DUNIN7 · LOOMWORKS · RECORD
record.dunin7.com
Status Current
Path inspection-briefs/loomworks-ungated-chat-disclaimer-scoping-v0_1.md

Loomworks — the ungated-chat disclaimer, scoped — v0.1

Date. 2026-08-11 · Author. Claude Code (read-only scoping). Operator: Marvin Percival. Fence. Read-only. Nothing built. Engine read at 64610b4. The ruling applied. Option 3: the Companion may produce prose with a governed equivalent, and must say plainly what it is not — chat text, not a Shape, no provenance, not in Memory or the record. The two questions the Operator asked answered here, from the code; neither decided.


Question 1 — where the disclaimer belongs

The path that needs it composes nothing today. The ungated route is the converse pipeline's path (b): general_conversation (or any misroute that collapses to it) → assemble_promptgenerate_response (responder.py) → the reply is model prose end to end. The four server-composed branches (cold-open greeting, completeness check, delegated responses, orient) all bypass the responder; no server text ever attaches to a responder reply.

Two server-composed seams exist that could carry it. Both are real in current code:

  1. The post-generation prose seam. Step 6b of the pipeline (converse.py:1300, the CR-2026-127 blank-reply fallback) already modifies response.companion_message server-side after the responder returns and before turn-recording. A disclaimer attached here is deterministic server text: it persists inside the turn's content, re-renders on reload with no surface change, and — worth naming — enters the classifier's prose-only history as pinned text, which is the direction B-86 wants history to move. Its weakness: to the reader it is typographically indistinguishable from model prose; and it rides in the same string the model authors, so "prose contradicting the disclaimer in the same message" remains constructible by the model's half.
  1. The structured side-channel. The setting_changes precedent (family: held_items, matched_files, sources, organized_view): a new field on ConverseResponse, rendered by the surface as a distinct element the model cannot touch, persisted for reload via the companion turn (the B-52 answer_sources dual-write shape, including its empty-vs-null discipline — absent must stay distinguishable from fired-false for every turn written before the CR). Its weakness: it needs surface work in /Users/dunin7/loomworks (the live frontend; loomworks-ui is the stale one), and it does not enter the classifier's prose history at all — it stabilizes nothing for B-86.
  1. The system-prompt layer is already occupied and already insufficient. general_conversation.md carries the CR-2026-199 no-claim paragraph today; E0127 shows what it constrains and what it doesn't. B-85 unpinned exactly this seam. Consistent with the Operator's parenthetical: not a candidate.

The structural summary: both real candidates satisfy "server-composed." They differ in which guarantee they give — seam 1 guarantees the words are always present in the record of the conversation (and pins classifier framing); seam 2 guarantees the Operator sees a marker the model cannot overwrite (the same prose-vs-chip reasoning as the B-87 mechanism note). They compose: the B-87 scoping's tune_setting finding is the worked example of claim-carried-both-ways. Which to take — or both — is the CR's design decision, not made here.

Question 2 — fire on every prose artifact, or only where a governed equivalent exists

The finding that reframes the choice: the two scopes nearly coincide, and neither is detectable deterministically.

Reported, not decided. The one direction this scoping flags for the Operator's weighing: unconditional-on-the-channel + structured marker is the only combination with zero probabilistic links; every selective variant contains a detector.


DUNIN7 — Done In Seven LLC — Miami, Florida — v0.1 — 2026-08-11