Version. 0.1 · Date. 2026-08-06 · Author. Claude.ai (drafting) / Marvin Percival (approving).
Target. /Users/dunin7/loomworks-engine, branch main.
Baseline. Post CR-2026-175. CC confirms exact HEAD at Step 0.
Companion to. inspection-briefs/loomworks-b54-residue-findings-v0_1.md (the evidence baseline); CR-2026-171 §2.2, where the NOT NULL migration was reverted.
Charter. Autonomous regime. Status. Ready for CC execution.
Priority. Above the rest of Wave 1 — this is a live defect, not cleanup.
CR-2026-171 reverted the NOT NULL migration when it broke 230 fixtures. Wave 0's investigation found the fixture debt was only half the story: three genuine production call sites create shapes or renders with no sequence number at all.
credit/proposal_applier.py:357 and :438 — live, registered at app lifespan. Every Operator-approved reconciliation correction writes a NULL-numbered row.agents/composition_specialists.py:109 — every non-produce composition step.This is why the migration must not be reattempted first. Fix the code, then the fixtures, then the constraint — in that order, across two CRs.
Fix each of the three call sites to route through whichever assign_* helper already assigns the number on the correct paths. CC identifies the helper at Step 1 and confirms the three sites can use it as-is; if any of the three cannot (e.g. it creates the row in a context where the helper's assumptions don't hold), halt and report rather than inventing a second numbering path — a divergent numbering mechanism is a design decision, not an implementation detail.
Backfill. Any rows already written with NULL numbers by these three paths need numbers assigned. CC reports the count found before backfilling and states the assignment rule used (e.g. next-available within the engagement, ordered by creation time). Non-erasure applies — backfilling an absent value is not a correction to an existing assertion, but if any row's number is ambiguous, report rather than guess.
Tests. One regression test per call site, asserting the created row carries a number.
NOT NULL migration itself — both go in a follow-on CR once this lands. Sequencing matters: constraint last.
| Step | What | Mode |
|---|---|---|
| 0 | Pre-flight — confirm baseline HEAD, tree clean. | Auto |
| 1 | Identify the assignment helper; confirm all three sites can use it. Halt if any cannot. | Auto, conditional halt |
| 2 | Fix all three call sites + one regression test each. | Auto |
| 3 | Count existing NULL-numbered rows; report count and assignment rule. Backfill. | Auto |
| 4 | Full engine suite; ruff 0; mypy at/below baseline. | Auto |
| A | Checkpoint. | Checkpoint |
| 5 | Tag cr-2026-176-b54-null-display-number-code-fix. Push. | Auto |
NOT NULL is reported (not fixed) so the follow-on CR is correctly sized.
Execute CR-2026-176 v0.1 at ~/Downloads/cr-2026-176-loomworks-b54-null-
display-number-code-fix-v0_1.md. Confirm the CR number against the
ledger first.
This is the code half of B-54, found by Wave 0's investigation. Three
production call sites create shapes/renders with no display_number:
credit/proposal_applier.py:357 and :438 (live — every Operator-approved
reconciliation correction), and agents/composition_specialists.py:109
(every non-produce composition step).
Step 1 first: identify the assign_* helper that handles this correctly
elsewhere and confirm all three sites can use it. If any of the three
can't, HALT and report — do not invent a second numbering mechanism.
Step 3 backfills existing NULL rows. Report the count and your
assignment rule before backfilling, not after.
Do NOT attempt the NOT NULL migration in this CR. That's the follow-on,
after the fixtures. Constraint goes last.
Baseline: post CR-2026-175. Confirm current HEAD at Step 0. Checkpoint
before tagging.
DUNIN7 — Done In Seven LLC — Miami, Florida CR-2026-176 — B-54 code fix — v0.1 — 2026-08-06