Version. 0.1
Date. 2026-08-01
Executed by. Claude Code, execution session on DUNIN7-M4.
CR. change-requests/cr-2026-161-authorship-truth-v0_1.md — confirmed the highest version present.
Charter. standing-notes/dunin7-standing-authorization-charter-v0_1.
Halt condition. A-2 — divergence from the CR's evidence base (C-3). Fired at Step 2, on Group D.
Status. HALTED. Steps 0 and 1 are complete and committed on branch cr-2026-161-authorship-truth. Nothing merged. Nothing pushed. Engine main untouched at e106917.
Group D's specified fix cannot be applied to the code it names. The CR says of site 4: "Distinguish absent from explicitly-null, and write the agent the client named." But the coalesce at considerations.py:195 fires only when the client named no agent at all — and the request schema documents that behaviour as intended, in a published API description. There is no named agent being lost, so there is nothing to recover; and the distinction the CR asks for is one the declared contract does not draw. The remedy does not fit the defect as the code actually stands.
This is not a judgment I am entitled to resolve in flight. C-3 forbids in-flight scope absorption; the correction is a CR version bump from a drafting session.
The construction, at api/routers/considerations.py:193-197:
agent_actor = ActorRef(
kind="agent",
id=body.agent_actor_id or uuid.uuid4(),
instruction_version=body.instruction_version,
)
The schema that governs it, at api/schemas.py:4251-4259:
agent_actor_id: UUID | None = Field(
None,
title="Agent",
description=(
"The agent identity to attribute the summarisation to. Optional; "
"when omitted a fresh agent identity is allocated for the run. "
"Supply one to tie the summary to a known agent."
),
)
The coalesce implements the declared contract exactly. "When omitted a fresh agent identity is allocated for the run" is what or uuid.uuid4() does. The field is UUID | None with default None, so an explicitly-supplied null and an omitted field are indistinguishable after parsing — and the description draws no distinction between them, because under the declared contract they mean the same thing: no agent named.
Contrast site 11, which is genuinely the shape the CR describes. There, converse.py:678-686's own comment states a contract — "when both are absent the scope stays None so the intent handlers ask" — that the or cannot honour. The engine says one thing and the code does another. At site 4 the engine's own schema says the same thing the code does. The two sites look alike and are not alike, and the difference is exactly the distinguishing test.
**The Step 0 findings recorded site 4 as "a falsy-coalesce on an agent identifier, self-contained" and did not read the request schema.** The CR inherited that characterisation in good faith and built a remedy on it.
What a full read establishes is that the only defensible B-25 claim against site 4 is a different and larger one: that allocating an ephemeral agent identity which exists in no registry, and stamping it onto both the summary and the event, puts a plausible-and-meaningless identifier in the permanent record. That may well be a real finding — it is recognisably the B-25 class. But it is:
Deciding any of that in flight would be scope absorption. It is precisely what C-3 forbids and what the two prior halts in CR-2026-159 were caused by not doing.
| Step | Commit | State |
|---|---|---|
| 0 — pre-flight and three determinations | 6a1bb13 | complete |
| 1 — Group A, sites 5–9 | 725ef21 | complete, suite at baseline |
Both stand on their own and neither depends on Group D. The branch is cr-2026-161-authorship-truth, off main e106917. Not merged, not pushed, not tagged. The working tree is clean; no partial Group B or D edit exists, and site 4 is byte-unchanged.
Baseline, recorded at Step 0 by name:
FAILED tests/test_stele_router_mount.py::test_stele_router_mounts_and_begin_resolves_end_to_end
1 failed, 3444 passed, 68 skipped
After Step 1: identical. 1 failed, 3444 passed, 68 skipped — the baseline set exactly, no new failure. Acceptance gate item 2 is already met: the Step 0 sweep re-run returns zero ActorRef in src/ carrying kind="contributor" with id=person.id.
The three determinations all settled and are recorded in docs/phase-crs/cr-2026-161-step-0-determinations-v0_1.md on the branch:
wasAttributedTo is REQUIRED (memory/base.py:146) → D-5's sentinel branch.actor.kind — conversation_turns.py:364 and conversation_history.py:173, both as their _is_human test, and NON_HUMAN_ACTOR_KINDS = {"agent","companion"} (base.py:31) is what the commit gates reject. Collapsing site 10 would have made the Companion's own draft committable as a human act. This closes the findings' one unread.Determination 2 and 3 removed work rather than adding it — Group E reduces to the compounding site alone.
Q-8 — what is site 4's defect, and is there one?
| | |
|---|---|
| Question | The coalesce at considerations.py:195 implements a documented contract. Is the real finding that ephemeral agent identities — fabricated UUIDs naming no registered agent, stamped onto the summary and the event — do not belong in the permanent record? If so, that is a change to a declared API contract, and it may reach beyond site 4. |
| Default | Strike site 4 from B-25 and open it as its own item. The record write is declared, not accidental, so it fails B-25's own distinguishing test — the same test that struck seed_conversation.py:116. |
| Blocks | Group D only. |
| Proceeds regardless | Groups A (done), B, C, E, F. |
A second, smaller queue item rides with it.
Q-9 — the D-5 sentinel's kind. Determination 1 settled that wasAttributedTo is required, so the legacy path needs a sentinel. The CR specifies the sentinel's UUID, display name and comment but not its kind, and the choice is consequential: person would assert the session-cookie path that is absent; agent or companion fall inside NON_HUMAN_ACTOR_KINDS and would revoke commit authority on a path that legitimately has it. The only non-falsifying option is contributor — truthful about the auth path (the legacy route is the bearer-token path by construction), with the sentinel UUID and display name carrying the unknown identity explicitly. Recorded rather than applied, because the CR did not specify it and Group C is not yet built.
A v0.2 of the CR from a drafting session, carrying:
kind specified, per Q-9.Everything in Groups B, C, E and F remains executable as written and is unblocked by Q-8. A v0.2 could reasonably keep Step 1 as landed and resume at Step 2.
DUNIN7 — Done In Seven LLC — Miami, Florida CR-2026-161 — Step 2 halt report — v0.1 — 2026-08-01 The remedy did not fit the defect. The schema said so, and the sizing had not read it.