DUNIN7 · Loomworks · Completion Record
Plain-language summary
The Companion used to tell the Operator that held drafts were "saved" and "in the record" during normal conversation. They were not — they were held, awaiting the Operator's commit. This change fixed it by teaching the persona which plain word goes with which state: a draft awaiting the Operator's okay is "waiting," and only committed work is "saved" / "in the record." No new vocabulary was introduced and no engine words ("held"/"committed") were brought back into the conversational voice — the change uses words the persona already approved and binds them to the correct state.
The fix was verified two ways. The automated tests confirm the state-fidelity instruction reaches the model's prompt on the conversational path. A live conversation against a real held engagement (Fenwick E0060) confirmed the model now behaves honestly — asked whether a held draft was saved, the Companion answered "waiting on your okay... I'll save it once you confirm," the opposite of the behavior that prompted this change.
This record also corrects the CR-2026-121 completion record: its acceptance item #8 claimed more than was built. That correction is at the end.
A defect observed live on the Companion at engagement E0060 (2026-06-25, ~07:32): in free conversation the Companion described a held draft as "saved" and "in the record," and said it does not use the words "held"/"committed" — while three held assertions sat awaiting commit. The dashboard's held cards (CR-2026-121) told the truth; the conversation did not. Same drafts, same moment, opposite statements.
Root cause: the conversational voice runs through the responder LLM path (assemble_prompt → generate_response), which loads companion_persona.md unconditionally. The persona's NEVER list banned the engine state-words and offered saved and waiting as plain replacements — but did not bind word to state. The list was state-blind. Asked about a held draft, the model picked "saved" and made a false state claim. The honest distinction existed in the system (commit_assertion.md) but only on the server-composed commit path, which does not load the persona.
Cleared against candidate seed v0.12. The fix reconciles two seed commitments rather than trading one off:
NEVER ban was left verbatim. The change uses only words already approved on the surface (waiting, draft, saved).Per-step commits, suite green at each. Merged --no-ff to loomworks-engine main at 59c8249 (range 0ae231b..59c8249), pushed.
| Commit | Change |
|---|---|
0695359 | D1 — STATE FIDELITY block added to companion_persona.md immediately after the NEVER block; the ban left verbatim; plain words only (waiting / saved / withdrawn), no engine vocabulary |
78d2a20 | D4 — two tests: deterministic assemble_prompt assertion (instruction present in the assembled responder prompt) plus a path-capture test (drive the operator_converse responder path, capture _call_responder_llm, assert the instruction reached system_prompt) |
ee8ae75 | D3 — commit_assertion.md reworded to plain vocabulary (no "held"/"committed"), state distinction preserved; CR-2026-121's template-content test updated; its commit-path behavior tests untouched |
Full engine suite after merge: 2940 passed, 0 failed, 46 skipped (2938 baseline + 2 new; no regressions; CR-2026-121's server-composed commit replies unchanged and still green). Feature branch cr-2026-122-conversational-fidelity merged and deleted (never on origin).
companion_persona.md and commit_assertion.md matched their grounded commits (dd21818, 40eff76), unchanged. D1 insertion point confirmed: after the NEVER block (line 21).load_persona() is the sole persona loader (prompt.py:897, inside assemble_prompt); operator_converse (converse.py:1082) is the sole generate_response caller. One finding carried out: a second conversational voice — the engagement-creation converse (seed_conversation.py → CREATION_CONVERSATION_PROMPT, creation_conversation.py:26) — does not load the persona, so the D1 fix does not reach it. Out of scope; filed as standing note f9d182b._call_responder_llm) is monkeypatched in the suite (no live API calls), so behavior cannot be asserted directly. Resolved: D4 uses a deterministic assemble_prompt assertion plus a path-capture test, with the behavioral guarantee covered by the manual live check. A mocked-completion assertion was rejected as a weak guard (it would test the stub's text, not the persona's effect).0695359).commit_assertion.md aligned to plain vocabulary (D3) — done (ee8ae75).78d2a20).Run against the restarted engine on :8000 (serving merged 59c8249, fresh persona cache), as the Operator, free conversation on E0060 (Fenwick). Both turns classified to the conversational responder path (persona-loaded), with real LLM replies.
Both replies described the held draft as waiting, explicitly denied the saved state, placed "save"/"in the record" in the future contingent on confirmation, and used no engine words. This is the reverse of the 07:32 defect. Caveat: two samples of a non-deterministic model on one engagement in one session — strong evidence the fix behaves on the surface that was broken, not a proof. The deterministic tests prove the instruction reaches the model; the live check observes the model acting on it.
Corrections-preserved — CR-2026-121 record amendment required
The CR-2026-121 completion record (phases/companion-commit-affordance/…v0_1) lists acceptance item #8 as met:
Fidelity — held drafts are never described as "saved" or "in the record"; held and committed are named distinctly.
As worded, this claimed a property of the whole Companion. What was built and tested under CR-2026-121 was narrower: the two persona-bypassing surfaces — the server-composed commit replies and the static card copy — were brought under the fidelity rule and verified. The conversational voice was never under the rule and falsified item #8 at the time, by persona design. CR-2026-121 §5.2 scoped its fidelity work (D8) to the held card, the confirm-back, and the post-commit response only.
Per corrections-preserved discipline, this is recorded, not smoothed. The CR-2026-121 completion record should receive a v0.2 adding a note that item #8 as worded was broader than what shipped — it held on the commit-reply and card surfaces, and the conversational surface was outside CR-2026-121's scope. The conversational gap is now closed by CR-2026-122 (this record). The prior v0.1 wording stays visible alongside the correction; the trajectory is preserved.
This correction is a documentation amendment, recorded here. The CR-2026-121 completion record v0.2 edit itself is a separate filing — see "Open" below.
seed_conversation.py / CREATION_CONVERSATION_PROMPT is a parallel conversational voice outside the persona, possibly carrying the same state-fidelity gap independently. Standing note f9d182b. Not investigated; a possible follow-on CR.api.loomworks.dunin7.com fails the TLS handshake and has no cloudflared ingress entry on DUNIN7-M4 (the tunnel serves only forge/workforce/foraychallenge; the engine runs only as a local dev process). Engine production deployment is a deferred, unstarted item (the M4-tunnel step per spine manifest, or the unbuilt fleet per the Discovery-stage deployment-strategy doc). 0094 will run when production is stood up, as part of standing it up — there is no separate pending production migration. Unrelated to this CR; recorded for accuracy because prior records described 0094 as "pending a production deploy," which overstated how close production is.59c8249 (pushed). CR-2026-122 live.loomworks-record: scoping note (c60f565), CR (933d74b), second-voice standing note (f9d182b). This completion record is the remaining filing.