Three scenarios join the contract set, so the fifteen vectors now cover an
unproven side effect, an undecidable attribution, and an agent whose state goes
unreadable in the window between finalization and notification. All fifteen
match their expected decision.
The side-effect case needed a decision about layering. Authoritative enforcement
belongs in manifest verification, which has the job record and therefore knows
what was declared; the policy honours an explicit negative from the collector so
the case is expressible as a vector. Absence is not read as proof there, because
the manifest check is the layer that fails closed on missing evidence.
The operations note records why the agent declares and the reader re-derives,
the three gates and why the backend allowlist can only be narrowed, the
notification transaction, and the rollback.
It also records a deviation from my own plan. §D2 asked for reviewer sign-off
before promoting an attempt id into the record, since that changes a contract
phase 1 froze. Measurement during implementation showed the change was not
needed: the attempt guard already lives in the evidence layer, where attempt
identity actually is, so auto-completion passes the engine a status precondition
instead. The schema is untouched, the frozen contract holds, and a
characterization test fails the moment a record starts carrying an attempt id,
which is when to revisit it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrDNJkHmm18uu7n7JwV5Qd
Records what phase 2a actually delivers and, as importantly, what it does not:
the shadow runner decides and logs, and nothing commits an inferred completion
until 2b.
state-transitions.md gains an implementation mapping so each contract row names
the code and the test that hold it up, with the inferred-completed row marked as
judged-but-not-committed.
phase2a-shadow.md is the operations note: the rollback switch, the lock
discipline and why transition_seq exists, the herdr wait rules that are easy to
get wrong (milliseconds, always name --until, errors on stderr, a timeout is a
healthy answer), the fail-closed decision order, and the 2b handoff.
task.md records P2A-00..04 with commit evidence, including two corrections to my
own plan: pick_pending was already a correct swap rather than a hole, and the
engine had to live with the registry writers because putting it in lib_py/loop
would have made delegation import a sibling and mix trees under a frozen loop.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrDNJkHmm18uu7n7JwV5Qd
Records the measured numbers and syncs every document that names the
delegation script paths, then bumps the framework to 4.3.0 in the three-way
lockstep (lib.sh, VERSIONS.md current + matrix, eight SKILL.md frontmatters).
phase1-benchmark.md carries both arms. The deterministic fake transport is what
CI asserts on: 50 publishes cost 50 connections one-shot and 1 persistent, p50
54.813ms -> 0.002ms. The real broker run is informational, since the PoC
default is a public broker: p50 1892.728ms -> 275.992ms, about 85% off.
It also corrects the plan's own estimate rather than repeating it. D8 predicted
the new shell path would drop from 3 forks to 2; the implementation is still 3,
because keeping the `_delegate_script publish_event.py` lookup is the only
thing that produces the "missing script tree does nothing" non-fatal contract
that C-02 pins. Saving that fork would change the contract, so it is deferred
to phase 4 rather than taken quietly.
SKILL.md gains the context table saying which tree wins where, so an operator
reading it knows a frozen loop runs frozen delegation code. The script paths in
every document remain correct and every quoted command still works verbatim.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrDNJkHmm18uu7n7JwV5Qd