Version. v0.2
Date. 2026-08-01
Supersedes. v0.1, drafted and never filed — halted at pre-flight. The record holds no v0.1.
Changes from v0.1. Two counts dropped, neither a finding. §1 said Shaping differs from "the two built rooms" and then named three in the next sentence — the document contradicted itself within a line. The two was inherited from the Step 0 findings' "two of three rooms are on the contract", a count about ReadState adoption, and attached to a different noun. And D-1 illustrated with "four renders" where several carries the argument. Nothing else changed.
Author. Claude.ai (drafting session). Approving: Marvin Percival.
Charter. standing-notes/dunin7-standing-authorization-charter-v0_1. No session executes a change request it drafted (§1).
Target. /Users/dunin7/loomworks at main 50252e1, tag render-flow-v0_1. One repository. No engine change.
Baseline. Not green. 639 passed, 0 failed, exit code 1, twelve unhandled fetchPlatformLevel rejections. The criterion is no new failure and no new unhandled rejection, against sets recorded at Step 0. Exit 0 is not reachable and is not the criterion.
Build-list item. B-6.
CR number. CR-2026-163. Highest confirmed is CR-2026-162. [EXECUTING SESSION: verify; advance if taken.]
Grounding. inspection-briefs/loomworks-b6-step-0-findings-v0_1 — every anchor below comes from it.
Status. Pre-execution.
The Shaping room. Today it is a placeholder: RoomView.tsx dispatches the shape discriminator to EmptyRoom with two strings that CR-2026-160 corrected to assert the surface rather than the record.
Shaping differs from the rooms already built in authority, not size. Memory, Manifestation and Rendering are rooms the Operator reads. Shaping is the first room where an Operator act produces artifacts elsewhere — confirming a Shape enqueues renders.
D-1 — the confirm control states what confirming will do, before it is pressed.
shape_confirmed_dispatch.py is a post-append hook on shape_confirmed. It walks the engagement's declared render-types and enqueues one job per match. Confirming a Shape is therefore not a local act.
This is not a defect and the CR does not treat it as one. The render side's state transitions remain operator-driven; what fires here is production against render-types the Operator previously declared, and the declaration is the authority.
But a control that reads as local understates what is being approved. The seed holds that the system surfaces and signals and the Operator approves — and approval requires knowing what is being approved. A confirm button that silently enqueues several renders is the Operator's authority in name and not in substance.
So the control names its consequence before it is pressed: which render-types will be enqueued, by name, drawn from the engagement's declared render-types filtered by the same mapping selector the engine uses.
If the list cannot be computed from data the surface can read, the control says that instead — confirming will enqueue renders for this engagement's declared render-types — rather than presenting a number it has not established. [EXECUTING SESSION: establish at Step 0 whether the list is computable surface-side. Both branches are acceptable; inventing a count is not.]
D-2 — the held → pending_confirmation transition is not a category error. Recorded as considered and cleared.
The findings name it as a second automatic transition, written by the agent. It does not fall under the seed's prohibition. That prohibition covers automatic state transitions on artifacts the Operator has authority over — and this transition is the system reporting that its own work is finished and handing control over. The Operator's authority sits at the confirm step, which stays manual.
Recorded rather than passed over, because the render side's equivalent question went the other way and the difference is worth being able to point at later: there, an automatic transition would have decided something for the Operator; here, it hands them the decision.
D-3 — ReadState needs no sixth state.
The Step 0 brief anticipated that a running job would fit none of the five values. It doesn't need to. ShapeEventResponse carries state, so a completed read returns real items, one of which happens to be held. The running condition is a property of the item, not of the read. populated is honest.
**The contract answers did the read land. The item answers is the work done.** (This corrects the brief's own premise, which reasoned from ReadState's shape rather than from what the engine returns.)
**D-4 — a shape whose production has not completed says only not produced yet, and the wording must not imply progress.** (Queue entry Q-14, taken.)
A failed production is currently indistinguishable from a running one. ShapeEvent has no failure state. mark_failed updates only the job row. The only route to that row needs an identifier returned once, in the 202, to the caller who asked — so a later reader cannot reach it. shaping_jobs does carry shape_event_object_id: the link exists in the database and is not exposed.
**The room says not produced yet. That sentence is true whether the job is running or has failed, so shipping it violates nothing** — it is an omission, not a false assertion, and the room today says nothing at all.
What the room must not say: producing, in progress, working, a spinner, a progress indicator, or anything else implying the job is alive. That would assert what the data cannot support — the same defect as the render current-marker, in a new place.
The engine exposure is its own item. Surfacing shape_event_object_id so a reader can reach the job's status is a small engine change, and it is engine work — this CR is surface-only, and holding it open for that would trade a shippable room for a coupled one.
D-5 — the surface does not re-implement the shape-type to render-type mapping.
It is version-pinned on DeclaredRenderType.source_shape_type_ref and used as a selector at three sites, enforced as a constraint nowhere. The surface reads it and does not carry its own copy — a mapping written in two places is a mapping that will diverge, and the engine's is the version-pinned one.
This closes change request C's second unread item.
D-6 — the adapter is lib/api/shape.ts, and it does need a boundary exemption.
Never shaping.ts — the wall reads import specifiers, so a room-named adapter trips every consumer. The file does not yet exist.
And unlike CR-2026-162's adapter, this one genuinely needs a WIRE_BOUNDARY_FILES entry, because ShapeEventResponse carries shaping_agent_* fields. CR-2026-162 established that an adapter needing no exemption should not get one; this is the converse case, and the entry carries a comment naming why.
3.1 lib/api/shape.ts — the adapter, per D-6, plus its WIRE_BOUNDARY_FILES entry with its reason.
3.2 ShapingRoom.tsx — the room, rendering per ReadState:
unloaded / loading → the shared loading treatmentfailed → the room-load-error treatment; never an empty claimempty → an honest empty, because a completed read stands behind itpopulated → the shapes, each showing its own state, with held items reading not produced yet per D-43.3 The confirm control, per D-1 — present only where a shape is confirmable, never disabled or inert, and naming its consequence before it is pressed.
3.4 RoomView.tsx — the shape branch renders ShapingRoom. The discriminator is untouched.
3.5 src/lib/strings.ts — the two placeholder Shaping strings are deleted; the room replaces them. [EXECUTING SESSION: report both verbatim in the implementation notes before removing them, so their replacement is a deliberate act rather than an overwrite.]
RenderingRoom onto ReadState. The findings establish it still derives its own ladder. Real, and not this CR — a room migration is not a room build.held ShapeEvent whose job failed is ever cleaned up. The findings' one unread. The gap in D-4 does not depend on the answer.project / engagement displacement — change request D.
Per-step commits, npm test at each against the Step 0 baseline sets. Check the current branch before the first commit.
Step 0 — pre-flight and one determination. Verify HEAD, tree, CR number. Record the baseline failure set, the unhandled-rejection set, and the exit code. Re-confirm the findings' anchors.
Then settle: can the surface compute which render-types a confirm will enqueue? Per D-1. Report it before proceeding. Both answers are acceptable; the control's wording follows from which.
Step 1 — the adapter, §3.1.
Step 2 — the room, §3.2 and §3.4.
Step 3 — the confirm control, §3.3, per Step 0's determination.
Step 4 — the strings, §3.5.
Step 5 — tests. The five render states; the confirm control absent where a shape is not confirmable; a test that fails if any held shape renders wording implying the job is alive — the D-4 boundary has nothing else protecting it. Assert specific conditions, never a bare Exception.
CHECKPOINT A — report, then proceed. Baseline comparisons; the tests; a live pass on the dev server showing all five states, a held shape reading not produced yet with no progress language, and the confirm control naming its consequence. No Operator confirmation. Halt and queue on: any new failure or rejection; the determination coming back ambiguous; any charter §6 anomaly.
Step 6 — implementation notes, carrying the determination and both removed strings.
CHECKPOINT B — merge and tag. --no-ff to main, tag shaping-room-v0_1, push. Authorized under R-2 including the push. Deployment is never autonomous (F-1).
shaping outside lib/room-labels.ts — including comments and test ids. (The findings establish the collision set is exactly two; reshaping has no instance in src/.)lib/api/shape.ts, with a WIRE_BOUNDARY_FILES entry carrying its reason.ReadState values; failed never renders an empty claim.held shape reads not produced yet, and nothing on screen implies the job is running** — no spinner, no progress indicator, no producing or in progress./Users/dunin7/loomworks is edited.This block names the entry point and the fences. It restates nothing the body carries.
CR-2026-163 — B-6, the Shaping room. Execution session.
CR: loomworks-record/change-requests/cr-2026-163-shaping-room-v0_2.md
Confirm it exists, and that it is the highest version present — numeric sort.
Grounding, read before the CR:
inspection-briefs/loomworks-b6-step-0-findings-v0_1.md
Charter dunin7-standing-authorization-charter-v0_1 governs.
Read the CR in full. It is the authority on what changes and where; this block
repeats none of it. Where this block and the CR appear to differ, the CR is
right and you halt rather than choosing.
Section 2 — the construction decisions and their reasoning
Section 3 — what changes
Section 4 — what is out of scope
Section 5 — the step sequence and both checkpoints
Section 6 — the acceptance gate
ONE REPOSITORY — the CR's header names the target and the baseline. No engine
change; if anything in the engine appears to need changing, halt.
playground_dev is the live production database and is not touched.
THE BASELINE IS NOT GREEN. Record the baseline sets at Step 0 and compare
against them. Exit 0 is not reachable and is not the criterion.
Step 0 settles the determination Section 5 names and reports it before any code
changes. Both answers are acceptable — do not resolve it by choosing.
Commit to a branch; check the current branch before the first commit.
Deployment is never yours.
Append the outcome to current-status/dunin7-status-brief at close.
DUNIN7 — Done In Seven LLC — Miami, Florida CR-2026-163 — B-6: the Shaping room — v0.2 — 2026-08-01 The first room where pressing something here makes something appear there.