Version. 0.2 · Date. 2026-08-07 · Author. Claude.ai (v0.1 drafting) / Claude Code (v0.2 amendment) / Marvin Percival (approving).
Supersedes. v0.1 at record 43841fe, which stands as a sibling.
Target. /Users/dunin7/loomworks-engine, branch main.
Built against. Engine 366102d. Full suite green before this amendment was written.
What changed from v0.1. Step 1's read is complete, the remedy is chosen (option b), and it is built. Two of v0.1's own claims were wrong and are corrected below rather than quietly restated. A residual the read surfaced is separated into its own build-list item rather than folded in. §4's build table is rewritten to reflect what actually happened.
Correction 1 — v0.1's §1 said Tier-2's block "enters the system prompt on every turn." It does not.
determine_context_tier (orchestration/prompt.py:140) picks one of three mutually exclusive tiers:
| Tier | Fires when | Standing block |
|---|---|---|
| 1 seed_only | no committed assertions | seed only |
| 2 seed_recent | committed assertions, no Manifestation | RECENT NOTES (up to 20) |
| 3 manifestation | a current Manifestation exists | organized groups, no note content |
Once an engagement has a Manifestation, Tier 3 fires and the notes block is absent entirely. The defect never applied to those engagements.
Correction 2 — that narrows the defect but sharpens who it hits.
Tier 2 is the state of having notes but not yet an organized view — the early life of an engagement. So the population affected is new engagements, which is the worst place for it: the first turns a person takes are the ones most likely to be shaped by material the answer cannot point at.
Both corrections are recorded rather than smoothed, per the seed's discipline. v0.1's framing was directionally right and factually wrong in two places, and the second correction matters more than the first.
Q1 — what Tier 2 is for. To give the Companion something concrete to speak from before anything is organized. Its own docstring: "once the Operator has organized assertions into groups, the Companion speaks in terms of those groups rather than individual notes."
Q2 — overlap: total, on exactly the turns that matter. Both blocks call the same function (list_assertions), with the same filter (state="committed") and the same order (created_at DESC). The recall block takes up to 50 at full content; Tier 2 takes up to 20 clipped to 150 characters. Tier 2's rows are a strict subset of the recall block's — same notes, fewer, truncated.
Q3 — what option (a) would have needed. AnswerSource requires item_id and display_number. _load_recent_committed_assertions returns (display_number, clipped_content) — it discards the id.
Q4 — the seed does not commit here. No commitment about what a conversational answer must cite. The nearest (seed v0.14:111) governs Renders: "Every Render… records what it was produced from… Lineage is visible." Adjacent posture, different object. So this stayed an engineering choice, not a seed-conformance question — the halt condition in v0.1's §2.4 did not trigger.
Chosen because Q2 makes it lossless. On the turns where B-61 bites, Tier 2 is a truncated duplicate of material the recall block already carries and already cites. Suppressing it removes uncitable material and removes nothing else — the model sees strictly more, in fuller form, all of it citable.
The two rejections, on their merits and not on cost (Operator, 2026-08-07):
standing-notes/loomworks-standing-note-observe-the-failure-before-trusting-the-check-v0_1.
EngagementContext gains assembled_text_without_notes: str | None, populated for tier seed_recent only. assemble_prompt splices that variant when intent == "ask_about_past_input".
Carried on the object rather than computed at splice time, deliberately. The context is cached per engagement and the cache key does not include the intent. The alternatives were to re-derive the seam from a header string — a parse of our own output, which drifts silently — or to make the cache intent-aware, which would model the wrong thing: the context does not vary by intent; only which of its two renderings is spliced does.
Three tests, proven red-then-green. Removing the fix yields exactly: "Tier 2's RECENT NOTES block reached the model on a recall turn — that material never becomes an AnswerSource, so the answer could be shaped by something it cannot cite." The others pin that non-recall intents keep the block, and that Tiers 1 and 3 fall through rather than losing their whole project context.
Gates. Full suite 3574 passed, 68 skipped, 0 failed. Ruff 0. Mypy at baseline.
Tier 3 shows the model an organized view it cannot cite — group labels, per-group counts, and the derivation rationale. No note content: individual assertions are omitted by design (D5), so this is a summary the answer cannot attribute rather than unsourced material.
Different material, different shape, different remedy — and the thing to point at already exists, since the Manifestation is an addressable object with its own id and version. Filed as B-67, not folded into B-61, on the Operator's direction and this CR's own §3 separation principle.
| Step | What | Mode | State |
|---|---|---|---|
| 0 | Pre-flight | Auto | done |
| 1 | Read per §2; report; halt | Auto, halt | done — halted, Operator chose (b) |
| 2 | Build (b) + tests, red-then-green | Auto | done |
| 3 | Full suite; ruff 0; mypy at/below baseline | Auto | done — 3574 passed |
| A | Checkpoint | Checkpoint | pending |
| 4 | Tag cr-2026-183-b61-citability. Push. | Auto | pending |
v0.1's §4 marked Step 2+ "Blocked" without saying what unblocks it. The block was then lifted verbally, leaving genuine ambiguity about whether the amendment had to land before the build.
> A change request that hard-blocks a step should say what unblocks it, not only that it is blocked. Operator, 2026-08-07: "The ambiguity was mine… You read it sensibly and flagged the gap instead of assuming."
Recorded also: the amendment was written after the suite went green, deliberately. An amendment recording a build that had not passed would assert something unverified.
DUNIN7 — Done In Seven LLC — Miami, Florida CR-2026-183 — B-61 citability — v0.2 — 2026-08-07