Document: loomworks-companion-truthfulness-fix-scoping-note-v0_1
Version: v0.1
Status: scoping note — precedes a fix CR. Two urgent fixes are clear; the systematic sweep is a sized follow-on. Operator confirms scope before a CR is drafted.
Date: 2026-06-27
Principle: loomworks-standing-note-companion-must-not-claim-what-system-did-not-do-v0_1 — the Companion must not claim what the system did not do.
Diagnoses this draws on: the remove-flow diagnostic (instance A + C, 2026-06-27, DB-certain) and the remember-about-me confirmation-loop scoping note (instance B).
The Companion's responses can claim an action happened, offer an action, or name a feature, independent of whether the system actually did it, can do it, or has it. Three confirmed instances. This note scopes the fix.
These two close the worst cases — the ones the Operator hits in normal use — and are small and well-located.
The bug. On "remove [note]" → "yes", the Companion says "Done — I've stopped using that" even when no retraction was written. The confirmation/retraction branch requires is_confirmation_turn AND len(matches) == 1 (router.py:2610). When the match re-derivation doesn't resolve to exactly one candidate, retract_assertion never runs — but the responder still emits the scripted "retracted" reply. Result: the Companion claims a removal that didn't happen; the note stays in the record.
The fix. The success language must be gated on the retraction having run. Two parts:
- When retract_assertion does not run (match count ≠ 1, or the branch is skipped), the responder must not say "Done." It must say what actually happened — e.g. "I found more than one note that could match — which did you mean?" (match > 1), or "I couldn't find a note matching that to remove." (match = 0). The response follows the real result.
- When retract_assertion does run, "Done" is correct and stays.
- [CC confirms at build: the cleanest gating point — is the responder told "action: retracted" only when retraction ran, or is it told the intent regardless? The fix is to ensure the "retracted" signal the responder keys on reflects the fact of retraction (the persisted event), not the intent. If the signal already reflects the fact, the bug is elsewhere in the match resolution — trace why a single clear "Level 13" note didn't resolve to len(matches)==1. This needs CC's read of why the match failed, because the symptom (a clear note not matching) suggests the match logic itself may be too strict, which is a second sub-issue: the user's removal failed silently.]
Note — there may be a match-resolution bug underneath. The Operator's "remove level 13 parking note" referenced a real, single note ("Parked on Level 13"), yet the match didn't resolve to one. So beyond the false "Done," the removal itself failed when it should have succeeded. The fix must determine whether the gate (don't lie) is enough, or whether the match logic also needs loosening so a clear single reference actually retracts. [CC investigates the match failure as part of Fix 1.]
The bug. Every retraction response includes a scripted sentence (forget_about_me.md:7): "If you want it permanently erased, that option will be available in your settings." No such setting exists; no assertion-erase endpoint exists; "in your settings" is the generic _LOCATION_FALLBACK filler. The prompt promises an unbuilt feature.
The fix. Remove the sentence from forget_about_me.md:7. Do not replace it with another feature promise. And — flag for the Operator: the promised "permanent erasure" would, if ever built as worded, conflict with corrections-preserved (the seed keeps retracted assertions as corrections; permanent erasure destroys that record). So the sentence should not be "fixed later" by building the feature — the feature as worded is seed-violating. If some erasure capability is ever wanted, it needs its own scoping against the seed, not a scripted promise. For now: delete the sentence.
Three instances means there are likely more scripted success-claims / offers / feature-references that assume a result the engine hasn't confirmed. The sweep:
- Audit the responder prompts (the .md prompt files) for success language scripted on intent rather than confirmed result.
- Audit for offers the system may not be able to fulfill (instance B's class — the remember-about-me loop).
- Audit for feature-references (settings, buttons, capabilities) that may not exist.
- For each: ensure the language is gated on the real system state, per the standing note.
This is its own scoping pass once the urgent two land — it needs a deliberate read of the prompt set, not a rushed grep. Not in the urgent CR.
Instance B (the "Want me to save that?" offer → confirmation loop) is already scoped in loomworks-remember-about-me-confirmation-loop-scoping-note-v0_1. It is the same principle (an offer decoupled from capability), but its fix is in a different part of the flow (intent classification F1 + the held↔continuation match F2). The two scoping notes are siblings under the one standing note. The Operator's four remember-about-me decisions are still pending and are not changed by this note — they can be fixed together with these two as one "Companion truthfulness" CR, or separately. Operator's call (decision 3 below).
Fix 2 is a prompt edit (delete a line in a .md file) — trivial. Fix 1 is engine logic (the responder's success-signal gating + possibly the match resolution) — the real work. So this CR is mostly engine, small. It does not touch the frontend.
DUNIN7 — Done In Seven LLC — Miami, Florida Loomworks — Companion truthfulness fix — scoping note — v0.1 — 2026-06-27 Two urgent fixes: gate the "Done" on the real retraction (Fix 1, engine — plus a likely match-resolution bug), delete the invented erasure promise (Fix 2, prompt). Systematic sweep + remember-about-me (B) are sized follow-ons. Under the "Companion must not claim what the system did not do" standing note.