Skip to content

2.1.0

Choose a tag to compare

@Atri10 Atri10 released this 22 Oct 12:22
· 2 commits to main since this release

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 decide refused 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 review phase 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.json was 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_outdated names the command).
  • halt is human-only; executor ingest refuses it.
  • merge now requires branch (plan/<PLAN-ID> or initiative/<INIT-ID>)
    and must contain every task head of the plan.
  • slot.json is 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).