DUNIN7 · LOOMWORKS · RECORD
record.dunin7.com
Status Current
Path inspection-briefs/loomworks-lifecycle-cluster-extract-v0_1.md

Loomworks — lifecycle-cluster CR extract — v0.1

Purpose. Read-only extraction for the B-15 absorption pass — the ten recall/answering/assertion-lifecycle CRs flagged in the June–July inspection report. No writes to any repo; source is each CR's own highest-filed version in loomworks-record/change-requests/. Date. 2026-07-30.


CR-2026-120 — Actor-Kind Read Contract + Commit-Gate Enforcement (v0.1)

Summary/scope. The Companion writes memory (actor kind companion) that read serializers can't deserialize — one crash site (ActorRefResponse.kind) is why E0060's Memory room 422s, since all five of its assertions are Companion-authored. Fixes read to match write (adds companion to five read-side Literal sites via a new canonical ActorKind alias) and, since the display fix would make a security hole more reachable, closes it in the same CR: the commit/discard gates checked kind == "agent" only, so a companion actor could slip through and commit/discard on its own authority. Both changes land together — one contract, honestly displayed and structurally non-committing.

As-built/corrections. None — single version, no supersession recorded in this document.

Named-but-unfixed gap. compositions.py:73 silently relabels a companion-triggered composition as contributor — display-correctness bug on a path neither probe exercised; explicitly filed as residue, not chased. Findings 2 (two-queue commit handshake) and 3 (false-success audit) deferred to later CRs in the Room-1 sequence (127, 129).


CR-2026-127 — Addressable Held-Tray Grammar + Committed-Revision (v0.1)

Summary/scope. Only working save phrase was "commit held N"; no conversational list/change/discard-by-reference existed, and "save"/"yes" routed to a dead queue, producing false "Logged" claims. Builds one grammar (verb + number) over the held tray: show_held, discard_held, change_assertion (held → in-place edit; committed → supersede with a confirm step, prior preserved), plus natural-language routing for save/commit phrasing and a bare "yes" in tray context. Reuses existing display_number, revise_assertion/discard_assertion, and the commit N reference implementation rather than building new data-layer mechanism.

As-built/corrections. None — single version.

Named-but-unfixed gap. Deprecated approve_draft card-queue path is routed around, not deleted — filed for a later cleanup. The compositions.py:73 relabel (CR-120 residue) carried forward again. Finding-3 system-wide false-success audit beyond these four motions is explicitly out of scope (lands as CR-129).


CR-2026-128 — Retract Boundary (Finding 1b) (v0.1)

Summary/scope. Two Companion-reachable erasures had no human-only gate: retracting a committed assertion (retract_assertion ungated at both data and HTTP layers) and revoking a delegation (revoke_delegation — a thin wrapper over the same unguarded retract, worse than the memory arm because it had no confirm beat at all, firing immediately as the Companion). Both made human-only: retract gated to reject non-human actors at both layers; "forget about me" re-routed so the confirmation turn acts as the human, not the Companion; delegation revocation gets a new propose→confirm beat mirroring the memory arm. Operator's explicit decision: full gate, no seam, no exception — an exception "evolves to more without continual oversight."

As-built/corrections. None in-document — this v0.1 is the only version. Flag: the document's own header still reads "Drafted, not executed," but the engine merge history confirms it landed (fe6edc9, 2026-07-01) — the record was never updated to reflect the build, a stale-status instance worth correcting in the absorption pass.

Named-but-unfixed gap. None named in-document; the CR states Finding 1b closes the actor-boundary completely across the room (commit/discard/retract/delegation-revoke all human-authority) and hands off only Finding 3 (recall truthfulness) as the remaining Room-1 item.


CR-2026-129 — Recall Truthfulness (Finding 3) (v0.2)

Summary/scope. Write-side truthfulness was already closed (CR-127/128); the gap was read-side: recall_personal and the remember_about_me delegation-grant ack handed real data to the model to phrase, so the content was truthful but the phrasing wasn't guaranteed to match it. Fix: server-compose both replies directly from retrieved data (mirroring the existing show_held/orient pattern), bypassing the model for these two paths so the reply cannot fabricate, omit, or miscount.

As-built/corrections. v0.2 is itself a scope correction of v0.1: v0.1 included a third path, ask_about_past_input, but Step 0 found it has no topic filter — server-composing it without one would turn a focused query into a full memory-dump. Operator decision (2026-07-01): rather than dump-everything or a throwaway filter, ask_about_past_input is lifted entirely out of this CR into its own semantic/embedding-recall foundation-effort. v0.2 covers only the two mechanical, low-risk fixes. Flag: like CR-128, the header still says "Drafted, not executed," but engine history shows it merged (2abcfd1, 2026-07-01).

Named-but-unfixed gap. ask_about_past_input itself remains unfixed by design — explicitly carved out as the semantic-recall foundation-effort, "to be scoped and grounded on its own," not rushed into this CR. This is the single largest open item the whole cluster points at for B-11.


CR-2026-144 — Move Assertion to Another Engagement (v0.2)

Summary/scope. A held Memory-list entry sometimes belongs to a different engagement than the one it was captured in. Adds a "Move to..." action on held cards (frontend), wired to the engine's existing /redirect endpoint.

As-built/corrections. v0.2 corrects v0.1's premise: v0.1 assumed new backend work was needed; Step 0 found the engine already had a complete, shipped mechanism (redirect_assertion, Phase 17 §6, built for an unrelated original purpose, 9/9 tests passing before this CR touched it) that does exactly what was asked. The actual build was frontend-only. Status line states directly: "Engine main @ 5e9c857 (unchanged)." (Previously confirmed in this session: this is by-design OL-only, not a missing engine merge.)

Named-but-unfixed gap. Retracted-via-move assertions are recorded correctly on the backend (event + rationale) but have no frontend surface — the Memory room only renders held/settled sections, so an Operator can't see that a note was moved, or why, without a direct API/DB query. Explicitly filed as its own finding, out of this CR's scope. Also unverified: an actual browser click-through of the picker component (covered only by mocked tests).


CR-2026-145 — Correction-Recognition (Propose-and-Confirm) (v0.1)

Summary/scope. Stating a new fact that corrects an old one ("I parked on level 10" after previously recording level 12) creates an unrelated new assertion today — no relationship is recorded between old and new, contrary to "corrections preserved, not smoothed." Fix: when a new statement appears to correct an existing assertion, the Companion proposes the match rather than silently superseding; the Operator confirms before anything changes. Deliberately not naive text-matching — a near-identical prior approach in remember_about_me was removed as "the source of the confirmation loop"; matching approach (likely semantic/embedding) is left to Step-0/build-brief, explicitly required not to repeat the removed keyword-comparison design.

As-built/corrections. None in-document. Flag: header states "Drafted, not staged for build... No build yet," but engine merge history shows it landed (5e9c857, 2026-07-04) — same stale-status pattern as CR-128/129.

Named-but-unfixed gap. The exact matching mechanism is explicitly left undetermined at CR-filing time ("to be determined at Step-0/build-brief stage") — worth checking at absorption whether the as-built matching approach was ever recorded anywhere, since this document doesn't carry it.


CR-2026-148 — Dismissed Held Items Stay Conversationally Live (v0.1)

Summary/scope. discard_assertion (the Dismiss button) only mutates the DB row — it never writes a conversation turn, so the classifier/responder (which read only recent_turns) keep treating a dismissed offer as still-pending indefinitely. Confirmed live: an Operator dismissed an item, repeated the utterance, and the Companion replied "Still waiting on your okay from earlier..." referencing a nonexistent item — recurred across three dismissed items (44, 52, 58) in one session, with the repeated content effectively lost (no new held item created). Fix: record the dismissal as a conversation turn, mirroring how commit/discard-via-voice already do.

As-built/corrections. None — single version; header notes "Number unconfirmed — CC to verify 148 is next-free before staging," a pre-build placeholder, not a correction.

Named-but-unfixed gap. None named — the CR states discard_assertion's data-layer behavior is already correct and CR-145's correction-matching already works correctly when it runs; the gap was specifically upstream (stale classifier context), and this CR closes exactly that.


CR-2026-151 — "Dismiss" Not Recognized as a Discard Command (v0.1)

Summary/scope. The UI labels the held-item action "Dismiss" (NotificationCard.tsx aria-label, MemoryRoom.tsx comment) but the voice-routable discard_held intent's trigger-word list ("discard, drop, throw away, or remove") doesn't include "dismiss" — so saying the exact word shown on screen has no documented match. Fix: add "dismiss" to the trigger-word list.

As-built/corrections. None — single version, smallest CR in the cluster (one classifier-vocabulary line).

Named-but-unfixed gap. None — explicitly notes the discard mechanism itself was already fixed by CR-148 on this same path; this CR is vocabulary-only.


CR-2026-155 — Graph Stage 2 (Forward Walk / Dependents) (v0.2)

Summary/scope. Stage 2 is the forward walk: given an assertion, find what was built from it. Item 2a: indexed query + endpoint GET /engagements/{eid}/assertions/{aid}/dependents, matching any pinned version of the assertion against shape_events_view.selected_memory_refs, with the matched version surfaced per result (GIN index, one migration). Item 2b: revise (supersede) and retract responses now carry a dependents count, so the Operator sees what was built from an assertion at the moment of the consequential decision. Explicitly signal-only — nothing is blocked, invalidated, or auto-changed, per Operator-authority.

As-built/corrections. v0.2 absorbs two build-time corrections over v0.1 (preserved alongside, not overwritten): D1 — the dependents-count predicate's exact spelling (CAST(:aid AS text)); D2matched_version typed int | None, not int (v0.1's assumption was a reasoning error, preserved in place at §4). Also records four as-shipped divergences D3–D6: D3 the dependents response is a wrapped object, not a bare array (accepted); D4 unpaginated, unlike the sibling shape-events list (accepted; queued as a follow-on if per-assertion counts grow past trivial); D5 the endpoint imports _row_to_schema across routers rather than duplicating the projection (accepted); D6 the migration-downgrade round-trip was executed out-of-suite against playground_dev, not fully in-suite — coverage stated honestly as weaker than the gate's wording, not read as fully covered. Suite at merge: 3424 passed / 68 skipped / 1 failed (+16 net new, no new failures; the one failure is the standing waived Stele router-mount test).

Named-but-unfixed gap. D4 (unpaginated dependents list) is the one live, accepted gap — filed to the queued-directions document as a follow-on, not fixed here. Stages 3–4, relationship-vocabulary edge walking, render-event forward walk, needs_you dashboard integration, any automatic action on dependents, and supersession severity are all explicitly out of scope for the whole Stage-2 effort.


Cross-cutting observations for B-15

  1. Stale-status pattern, three instances: CR-2026-128, CR-2026-129, and CR-2026-145 all carry document headers reading "Drafted, not executed" / "No build yet," while engine merge history confirms all three landed and pushed weeks ago. The record was never updated post-merge on these three. Worth a small correction pass alongside the manifest absorption, distinct from the manifest's own gap.
  2. The Room-1 (Memory) actor-boundary + truthfulness arc is a clean, closed sequence: CR-120 → 127 → 128 → 129, each explicitly handing off exactly one named finding to the next, ending in CR-129's statement that Room 1 passes conformance bar v0.2. This sequence is the strongest single thread in the cluster and maps directly onto the current-status manifest's absent §3 entries for the window.
  3. The one open thread every recall-adjacent document points at is the same thread: ask_about_past_input / semantic recall, carved out of CR-129, referenced again by CR-2026-158's absorption-pass framing, and named in the current-status manifest's no-live-recall-demonstration standing rule. If B-11's bug is a recall-truthfulness bug rather than an assertion-lifecycle bug, this is very likely where it lives — ask_about_past_input is the one recall path in this entire cluster that was never brought under the server-compose/truthful-by-construction discipline the rest of Room 1 received.

DUNIN7 — Done In Seven LLC — Miami, Florida Loomworks lifecycle-cluster CR extract — v0.1 — 2026-07-30 Read-only. No repository writes performed in producing this extract.