Version. 0.6 — supersedes v0_5 (sibling). W1 is closed. All twelve items shipped. Changes: §3 marked complete per item with its landing; new §15 (what W1 delivered and the one claim that is qualified); new §16 (findings from the build). Sections 4, 6–10, 12–14 held stable.
Date. 2026-08-20
Status. CLOSED. Engine 2ff25e3..9f31cb7. Next in the H0 lane: W2 (grantability and the freeze switch), then W4, then CR-2026-228, then demo assembly.
Runtime direction: no conflict. O2 is structural in both new tables (no column can hold a secret); O5 (the roster is the enumeration); O6 (AgentIdentityRefusal and SessionRefusal carry decider, version, deciding condition); O7 (five call sites); O8 (two named stores); O9 (session id nullable on both chokepoints — human and system actors have no session and never will); O10 (no runtime self-widening path exists to take).
| # | Item | Landed |
|---|---|---|
| 1 | agent_identities, role-keyed, AgentIdentityRow | migration 0113, 720aa06 |
| 2 | Seeded from the roster module; resolved; never minted | agents/native_agent_roster.py, 720aa06 |
| 3 | Render path resolves; frozen startup map | 720aa06 |
| 4 | agent_sessions + migration | migration 0114, 53eccd7 |
| 5 | Session module — mint / close / end / live | agents/sessions.py, 53eccd7 |
| 6 | 8h lifetime, config-driven, no extend path | 53eccd7 |
| 7 | actor_id + session_id on the spend chokepoint | 53eccd7 |
| 8 | AgentDecision.session_id, additive and nullable | 53eccd7 |
| 9 | instruction_version pinned at mint, NOT NULL | 53eccd7 |
| 10 | …0010 → kind="system" | 39733d9, merge d275df6 |
| 11 | Five FORAY call sites at standard | 53eccd7 |
| 12 | Tests | 37 across two files |
Also landed under Q5: …0731 and …0051 → kind="system" (0c1bf80, merge 5c0eeea).
True now, and untrue three days ago:
uuid.uuid4() per process, and the seed-induction agent per request.src/. Renewal is a fresh mint.end_sessions_for_identity ends every live session of a role across every engagement; W2 throws the switch.The qualified claim, stated here rather than discovered at the demo.
H0 acceptance 1 is carriage-complete and mint-incomplete. session_id is carried through the shaping and rendering room paths to the spend gate, but nothing mints a session for those rooms yet. That mint point is where W2's grantability check goes — request → grant → session needs the grant, and W1 has no grant to give. W1 built the carriage and the verbs; W2 puts the mint at the front of the work.
Compounding it, unchanged from §6: acceptance 1 also holds for system-key work only until CR-2026-228 closes the own-key path that returns before the gate.
So the honest state of acceptance 1 at the W1 close is: the mechanism exists, the field travels, and two things must land before the sentence "an unlabeled agent action is impossible" is true — W2's mint and CR-2026-228. Both are sequenced before demo assembly.
The commit-path family needs no session id, and threading one would have been dead code. Agents are structurally refused at every commit-path gate — has_human_commit_authority returns False for agent — so an agent action never succeeds there. The chokepoints that matter for agents are the spend gate and the admission path (AgentDecision), which is where items 7 and 8 landed. A session_id parameter on the commit path would have been a field no agent could ever populate. v0_1–v0_5 said "the commit-path family threads session_id"; that was wrong, and building it showed why.
Two completeness checks caught the additions, which is what they are for.
test_every_referencing_fk_has_a_declared_policy — agent_sessions.engagement_id now declares delete, and **delete rather than active_only deliberately: mint has no engagement-state gate, so a candidate can carry sessions and the active_only claim would have been false. Recorded there: the agent_identity does not** follow the engagement out — identity survives every engagement, which is the point of it.test_anchor_priority_entry_present_at_standard — count 23 → 28. That literal pin is exactly the shape the new standing note calls "the one that speaks." It is how the W1 additions announced themselves instead of landing silently, three days after the note that predicted it.
Three mypy errors were fixed rather than baselined — two Result.rowcount attribute errors, and an external-specialist subclass whose produce_render had to accept the new parameter. The baseline file is untouched across all of W1.
The fail-closed design proved itself before the tests did. The first full-suite run after item 3 returned 52 failures and 310 errors, every one the same line: "STOP — no session for role 'seed_induction': the agent identity roster has not been loaded in this process." Correct behaviour, useless test state — and the fix is now a named registry in tests/conftest.py (merge 9f31cb7) so W4's heartbeat finds a list rather than the same 300 errors.
Evidence at the close. Suite 3838 → 3876 passed, 68 skipped, 0 failed; the +38 is exactly the two new test files. Ruff clean. mypy 536 errors, all covered by the 336-entry baseline, baseline file untouched. Migrations 0113 and 0114 apply, downgrade and re-apply cleanly on dev and test databases.
The date. 2026-09-09 holds. W1 came in at estimate; the render-specialist finding removed work rather than adding it, and the Q2 trip-wire never fired.