Repository navigation
2.1.0
An evidence-first audit of the engine against a live 325-event initiative,
and the three structural changes it demanded. Every defect in the register
carries the file and line, the observed behaviour, the command that
reproduces it, and the test that now covers it.
What was wrong
- A worker could latch a halt while
executor deciderefused one. - A commit on an unrelated branch satisfied "the work advanced" — the
ancestry check never required the dispatch base to be a descendant of the
reported head. - The
reviewphase was inert: the whole-plan final audit two documents
promised never dispatched. - No projection was reproducible (wall-clock stamps), so a drift check
and a byte-idempotent migration were both impossible. state.jsonwas 2.76 MB and rewritten whole on every event — 469.7 MB
written over 320 projections, because the fold carried every artifact body.- A constraint could not change mid-run, and the fold had no task →
requirement link at all, so a blast radius could only have been prose. - 37 prose/code divergences; the ones needing code are in the register, the
rest are prose corrections in the same change set.
What shipped
Store layout v2 — a views tree with index.md at its root and one leaf
per plan and per task; plan.json is an index and each task contract is
tasks/<TASK-ID>/task.json in both stores; artifact instances are minted per
kind and an arch may declare components for per-component designs;
slot.json deleted; deterministic projections; the committed index is written
mid-run and verified against a re-render; check also reports a missing
canonical file. The fold cache keeps decisions, not bodies: state.json
2.4 MB → 1.10 MB, bytes written over the run 470 MB → 160 MB
(scripts/measure_store.py prints the curve).
Mid-run change protocol — a journaled, ID-bearing change_request
(executor change <file|->, --list); the engine mints CR-NNNN, computes
the blast radius from fold dependency data (depends_on, cites,
requirement/constraint/criterion ids) with a reported coarse fallback, and
drives a regression lane — revise, re-audit, re-dispatch, re-prove, apply —
that is a pure function of the fold, waits for in-flight dispatches and
pending gates, and is withdrawn by a ruling. change_not_applied verifies the
redraft really carries the change.
Git discipline, enforced — six rules with rejection codes and
clear-the-path hints (descent, base-branch purity, branch ownership, merge
ancestry, merge branch, commit subjects), enforced only for dispatches this
engine minted (rules: v2), so an upgrade never rejects work it inherited.
Command surface — executor change, executor migrate --dry-run|--apply,
a policy: and open-change: line in status, rulings in
views/progress.md, abandoned labelled honestly, sk- keys scanned.
Migration
A store written by 2.0.x is refused by the writer (store_outdated)
rather than half-converted:
executor migrate --dry-run # every write and removal, touching nothing
executor migrate --apply # convert, verify, stamp store_version v2
Deterministic and byte-idempotent: a second --apply rewrites identical bytes
and removes nothing. scripts/migrate_layout.py is the same implementation
from the command line.
Evidence
scripts/run_tests.py → 828 tests, TOTAL 100.00%
scripts/sync_engine.py --check → bundled engine: in sync
scripts/validate_skills.py → skill validation: all clean
scripts/lint-prompt-injection.py skills/ → prompt-injection lint: clean
The reference corpus (a copy; the live store belongs to a sibling project) was
migrated with 139 writes and 13 removals, verified, then re-applied
byte-identically across 658 files; executor check reports chain: ok and
zero store problems.
Breaking changes
- Store layout: 2.0.x stores must be migrated before the writer accepts
them (store_outdatednames the command). haltis human-only;executor ingestrefuses it.mergenow requiresbranch(plan/<PLAN-ID>orinitiative/<INIT-ID>)
and must contain every task head of the plan.slot.jsonis gone from the grammar; the flat per-round verdict views are
gone (a task's rounds live in its one view leaf).- Payload additions are optional only (
task.requirements/constraints,
report.branch,arch.components,design.component,change_request).