Version. 0.1 Date. 2026-07-31 Author. Claude.ai. Operator: Marvin Percival. Consumer. Claude Code on DUNIN7-M4. Markdown primary; technical consumer, no HTML companion. Purpose. Size build-list item B-25 — the record writes that are not true — so its change request can be drafted against a known surface rather than a guess. Status. Read-only inspection. No fixes, no branches, no commits, no database writes. Provenance. Requested during the 2026-07-30 session and not executed. Re-issued with the target list extended per completion scoping note v0.1 §4, decision 5.
B-25 is the most serious correctness item on the build list: three known engine sites where a write that cannot resolve its true value substitutes a plausible one rather than failing. None of it is visible from any surface.
Two things wait on the answer. B-25's own change request cannot be drafted without knowing whether it covers three sites or twenty. And B-9 — the provenance walk — is gated behind B-25, because a provenance walk over false provenance demonstrates a lie convincingly.
The question this brief answers is a number. Everything below exists to produce it: how many sites in the engine can write a value into the permanent record that is plausible and wrong.
Three from the walk audit's findings, one added by the completion scoping note.
| Site | What it does |
|---|---|
| engagements.py:347 | Constructs an actor reference with a freshly generated identifier on every call. The route authorises correctly, then discards the resolved principal and stamps a generated value as the author. |
| converse.py:690 | Resolves the engagement identifier by coalescing the request body's field against a fallback. An explicit null — sent correctly by a client honouring the documented contract — is indistinguishable from an omitted field, so the resolution silently substitutes whichever engagement the Operator last viewed. |
| compositions.py:73 | Relabels a Companion-triggered composition as a contributor's work. Filed as a residue twice and never chased. |
| W-6 (added) | The two contribution paths attribute the same person differently. Contributing by talking terminates a provenance walk on the Companion; contributing by typing terminates on the person's own name. The person identifier is identical; the kind and the readable name are not. |
These four are the seed of the sweep, not its scope. The sweep exists to find the rest.
The framing that makes this bounded. Stele provides two actor constructors — actor_from_person and actor_from_companion, in stele/actor.py. Those are the correct way to stamp an actor onto a record. The sweep is therefore not an open-ended grep. It is one question:
> Which write paths construct an actor without going through those constructors, and what do they write instead?
What to find.
src/loomworks/, whether through the Stele constructors or by direct instantiation. Enumerate all of them.Report for each finding: file, line, the code, what it writes today, and what the true value would have been.
The defect shape. Python cannot distinguish an explicit null from an omitted field when a value is resolved with or against a fallback. A client that correctly sends null — honouring a documented contract that says this field is deliberately empty — has its explicit intent silently replaced by the fallback. converse.py:690 is the known instance and it wrote two conversation turns into the wrong engagement's permanent history.
What to find. Every site on a path that writes to the record where a request-supplied field is resolved by coalescing rather than by an explicit null check.
Patterns to cover — this list is a starting point, not a boundary:
Fields that matter most, because they are the ones a contract may legitimately leave null: engagement identifier, project identifier, actor, scope, seed references, workspace, parent references, and any identifier that may deliberately be empty during a pre-instantiation or draft-stage flow.
The distinguishing test for each hit: can this field legitimately be null in any documented or observed request shape? If yes and the path writes, it is a finding. If the field can never legitimately be null, the coalescing is harmless and should be classified as such rather than counted.
Report for each finding: file, line, the field, the fallback, what the wrong value would be, and whether any surface could detect the substitution.
Every hit from both sweeps gets exactly one verdict. The point is a count, not prose.
Open with the number. How many WRITES-FALSE sites exist across both sweeps. That single figure is what B-25's change request is waiting on.
Then:
playground_dev is the live production database and must not be connected to.Existing damage in the live record. These sweeps size the code fix. They do not ask how many records already carry a fabricated author, a misattributed composition, or a turn written into the wrong engagement.
That question is real and it may be larger than the code fix. If the first known site has been running on the serving perimeter, then seed amendments already in the live record carry authors who do not exist — and the project's corrections preserved, not smoothed discipline means those records cannot simply be corrected in place once the code is fixed; they would need marking.
It is excluded here for two reasons. It requires connecting to the production database, which is a decision of a different kind. And it is a different task: quantifying damage, not sizing a repair. Surfaced for the Operator, not folded in.
DUNIN7 — Done In Seven LLC — Miami, Florida Loomworks — B-25 sizing sweeps — inspection brief — v0.1 — 2026-07-31 Sizes B-25; gates B-9. Read-only.