"Ship-workflow hardening — status-page auto-sync, batch/parallel task shipping with unlock rescan, rules-to-channels distribution sync"
§1 — Description
Group A — status page auto-sync
- Any commit whose staged changes touch
docs/tasks/**,CHANGELOG.md, orVERSIONMUST regeneratedocs/status/(via the existingmigrate-tasks.sh --pagefast path) and stage the result in the same commit, wired into.githooks/pre-commit. The status page can never again lag the task frontmatter it renders. - The regeneration MUST be best-effort-loud: a render failure prints a warning naming the fix command but does not block the commit (matching run-gates.sh's posture; a docs-render bug must not dead-lock all task work).
ship-tasks.mdMUST record this as a rule of the backlog-state-update steps: every status mutation rides with a fresh status page.
Group B — batch / parallel shipping
- The workflow (bumped to v2.5.0) MUST define batch selection: the eligible set is every
ready_to_implementtask whosedepends_onare alldone; a batch is a maximal subset whose members are pairwise independent — nodepends_on/blocksedge between members AND no overlap between their declared cones (new_files+modified_files+service). Overlapping tasks stay serial in priority order. - Batched execution MUST keep per-task artefacts, per-task manifests, and per-task HITL verdicts (a single human reply MAY record verdicts for many tasks at once, e.g. "approve all" - one utterance, N recorded verdicts), while phases MAY be executed and committed batch-wide instead of one-by-one.
- Unlock rescan: whenever any task reaches
done, the workflow MUST re-scan the backlog for tasks whosedepends_onjust became fully satisfied and append the newly-eligible, cone-independent ones to the running batch queue (no operator prompt - EXECUTION-DISCIPLINE §1 continuation). - Batching MUST NOT weaken HITL: the two human-acceptance gates still apply to every task individually; batch = fewer round-trips, identical guarantees.
Group C — rules-to-channels distribution sync
- The payload's
manifest.yamlMUST carry a deterministicrules_sha— a content fingerprint over the rule trees the payload distributes (cuo/,plugin/,mcp/,cli/,memory/) — so every channel (standalone/self-hosted.cyberos, Claude plugin, MCP server, npx CLI) can detect rule drift even when VERSION is unchanged.check-version-sync.shMUST fail ifrules_shais missing/empty. - The auto-hook chain MUST cover build, release, and deploy: (build) the existing pre-commit payload rebuild on
modules/**/tools/install/**changes + payload-gate on push; (release) the existing release.yml payload job publishing stamped payload assets per tag; (deploy) deploy.yml's docs job MUST additionally trigger onmodules/cuo/**andmodules/skill/**so rule changes refresh the published site without waiting for a release. The chain is documented in the workflow spec so it is discoverable, not tribal. cyberos update/install.sh --checkremain the pull side: they already compare payload versions;rules_shagives them (and any plugin/MCP consumer) a finer-grained drift signal to compare against. Extending their comparison logic is explicitly a follow-up once this fingerprint exists in the wild.
Length note: this task consciously invokes the sanctioned pure-infra profile — every clause is hook/CI/doc wiring over already-existing machinery, with the §5 checks runnable in-session; the fuller 300-line bar buys nothing here that §5 does not already prove.
§2 — Why this design
The status-page fix reuses the exact regeneration path run-gates.sh already trusts (migrate-tasks.sh --page) instead of inventing a second renderer — the bug was missing wiring, not missing tooling. Batch semantics are codified from this session's real 5-task run (queue → per-task artefacts → one "approve all"/"accept all" verdict pair), which worked but was improvised; v2.5.0 makes it the sanctioned default and adds the unlock rescan the manual run lacked. The rules fingerprint goes in manifest.yaml because that file already rides every channel and is already gate-checked — one new field, zero new distribution surface.
§3 — API contract
- pre-commit block: trigger regex
^(docs/tasks/|CHANGELOG\.md$|VERSION$); call"$root/.cyberos/migrate-tasks.sh" --page "$root"(fallbacktools/install/migrate-tasks.shfor this self-hosting repo); thengit add docs/status/. - manifest.yaml gains:
rules_sha: <64-hex>computed assha256(sorted per-file sha256 list over cuo/ plugin/ mcp/ cli/ memory/ in $out)— deterministic across runs/platforms. - ship-tasks.md:
workflow_version: 2.5.0; new §11a (batch selection + unlock rescan), §1 note on status sync, new "Distribution sync" subsection under Cross-references. - deploy.yml docs paths +=
modules/cuo/**,modules/skill/**.
§4 — Acceptance criteria
- Committing a change under
docs/tasks/regenerates and stagesdocs/status/in that same commit (hook run observed;git show --statincludes docs/status/index.html alongside the task change). bash -n .githooks/pre-commitpasses; a render failure path prints a warning and exits 0 (non-blocking).- Two consecutive payload builds produce identical
rules_sha; editing any file undermodules/cuo/changes it. check-version-sync.shfails against a payload whose manifest lacksrules_sha, passes against a fresh build.ship-tasks.mdparses as v2.5.0 with §11a present; batch rules restate both HITL gates unchanged.- deploy.yml YAML-parses with the two added path globs.
§5 — Verification
bash -n .githooks/pre-commit
bash tools/install/build.sh /tmp/p1 >/dev/null && bash tools/install/build.sh /tmp/p2 >/dev/null
grep "^rules_sha:" /tmp/p1/manifest.yaml /tmp/p2/manifest.yaml # identical, non-empty
bash tools/install/check-version-sync.sh /tmp/p1 # PASS incl. rules_sha assert
sed -i 's/^rules_sha:.*/rules_sha: ""/' /tmp/p1/manifest.yaml && ! bash tools/install/check-version-sync.sh /tmp/p1 # negative
grep -n "workflow_version: 2.5.0" modules/cuo/chief-technology-officer/workflows/ship-tasks.md
python3 -c "import yaml; yaml.safe_load(open('.github/workflows/deploy.yml'))"
§6 — Implementation skeleton
Covered by §3 — five files, all edits; no new scripts beyond the hook block.
§7 — Dependencies
Upstream none; downstream: a follow-up task may teach cyberos update/plugin/MCP clients to compare rules_sha (clause 10). Batched with TASK-IMP-075 (non-overlapping cones: workflow/hooks/CI-docs vs apps/desktop Rust) — the first sanctioned use of §11a.
§8 — Example payloads
rules_sha: 3f9c…64hex in manifest.yaml; hook output: cyberos: docs/status regenerated + staged (task sources changed).
§9 — Open questions
- Client-side
rules_shacomparison incyberos update/plugin/MCP (clause 10) — follow-up task once the field ships. - Whether batch commits should also batch across MODULES with distinct gate profiles — deferred; v2.5.0 scopes batching to cone-independence only.
§10 — Failure modes inventory
| Failure | Detection | Outcome | Recovery |
|---|---|---|---|
| Render script errors during commit | warning printed, commit proceeds (clause 2) | page stale for one commit | run-gates.sh next run heals; fix renderer |
| Two batched tasks secretly touch the same file despite declared cones | git conflict/second edit visible in review packet diff | reviewer rejects at gate 1 | route one back; cones corrected in frontmatter |
| Unlock rescan picks a task whose spec drifted since audit | ship-manifest task_sha256 staleness rule (TASK-CUO-206) triggers restart at step 1 | no stale-spec shipping | existing manifest machinery |
| rules_sha nondeterminism across OS (sort/locale) | AC #3 double-build check; LC_ALL=C forced in build.sh | none if caught | pinned locale in the hash pipeline |
| Channels ignore rules_sha (no client logic yet) | clause 10 documents it as pull-side follow-up | drift detectable, not yet auto-acted-on | follow-up task |
| deploy docs job now triggers more often | Actions usage visible | slightly more CI minutes | acceptable; docs job is minutes-cheap |
§11 — Implementation notes
Batched with TASK-IMP-075 per §11a. Hash pipeline uses LC_ALL=C sort + sha256sum (ubuntu CI) with shasum -a 256 fallback for macOS operators. HITL gates restated verbatim in §11a so batching can never be cited to skip a verdict.
End of TASK-IMP-074.
Audit
§1 — Verdict summary
Pure-infra profile invoked explicitly with justification (hook/CI/doc wiring over existing machinery; §5 fully runnable in-session). 10 clauses across 3 groups, 6 ACs, 6 failure rows.
§2 — Findings (resolved in-pass)
- ISS-001: draft's status-sync clause omitted the non-blocking posture (a renderer bug would have dead-locked all commits) → clause 2 + failure row 1.
- ISS-002: batch clause originally said "commits are batched" without restating per-task HITL — exploitable reading → clauses 5/7 restate both gates verbatim-equivalent.
- ISS-003: rules_sha had no determinism guarantee across OS locales → LC_ALL=C pipeline + AC #3 double-build check + failure row 4.
§3 — Resolution
All resolved same pass. Score = 10/10. End of TASK-IMP-074 audit.