[FIX] The link canary was blind to code spans, to wikilinks, and to its own class

The steward's 2026-08-09 to-do read "the gap is neither knowledge nor home but
the absence of an EXECUTABLE." The premise was false: classify_pointers has
existed since 19bddd5 (2026-08-08), wired to SessionStart, with controls. The
gap was that the executable was incomplete, and the incompleteness had already
produced a false positive.

Four defects, three named in the spec and one found by building it:

1. CODE SPANS. `](file.md)` inside backticks read as a pointer, so the single
   DEAD pointer reported on 2026-08-09 was the link pattern written inside
   MEMORY.md's own specification of this canary. An instrument that flags its
   own documentation flags it every wake forever, and the real signal drowns —
   the same "known canary bug" dismissal the 2026-07-28 block was written to
   end, arriving by a second route. Fences and inline spans are blanked with
   offsets preserved; inline spans may not cross a newline and an unterminated
   fence does not match, so a stray backtick can never blank the file and HIDE
   dead pointers.

2. WIKILINKS. reference-verification-ladder.md has specified this canary as
   covering "every `](file.md)` and `[[wikilink]]`" since 2026-07-06. Only the
   first half was ever built. 31 wikilinks now checked.

3. BREAKAGE AGE, derived from git rather than a stored prior run — a state file
   would make this the one cached section in a digest whose governing property
   is that it is computed. Where git cannot answer, it says so.

4. Found by running it: the first wikilink pass reported only UNWRITTEN, and
   both live hits were [[trust-prior-pass-frame]], whose file EXISTS as
   feedback-trust-prior-pass-frame.md. That is precisely the one-word alarm the
   comment ten lines above it was written to forbid. Wikilinks now report three
   outcomes and hand back the replacement slug. Both are repaired here.

The wake-up skill and the ladder now POINT AT the executable instead of
describing the check — the described-not-invoked gap is why it kept being
retyped by hand on 2026-08-08 and 2026-08-09.

Verify: python3 scripts/wake-digest.py --selftest   (61 checks, exit 0)
        python3 scripts/wake-digest.py | grep 'MEMORY POINTERS'
Induced red: blank_code reverted to a no-op (behaviour, not the symbol) →
        exit 2, five named failures, no traceback; direction controls held.

Not changed: the wrap_inside detector, which announced "PREVIOUS SESSION DID
NOT WRAP" for a session that wrapped at 19:48 and kept working until 21:54 —
a two-valued detector over a three-case state. Named in the ledger, not fixed.
This commit is contained in:
David F Glidden
2026-08-10 16:01:51 +02:00
parent ed9951d1d7
commit 32b0c9dfc6
5 changed files with 255 additions and 9 deletions
+1 -1
View File
@@ -63,7 +63,7 @@ Run these in parallel to minimize latency:
- Read `skill-harvest-register.md` directly — the canonical surface for open skill proposals (wrap §1.6 appends there); surface any awaiting steward authorization <!-- 2026-06-05: register wiring, authorized 2026-05-29, applied with wrap-up §1.6 counterpart -->
- Read `reference-verification-ladder.md` directly — the canonical surface for the named verification instruments; hold the one or two the session's work will actually need <!-- 2026-08-07: PENDING-112 → REVIEWED-95. THIS SENTENCE IS A PRE-REGISTERED TRIAL INTERVENTION, landed alone and deliberately parallel to the register line above. Baseline before it: the ladder was reached in 9 of 64 sessions (14%), while the register — identical in kind, differing only in being named here — sat at 77%. Prediction: >60% over the 20 sessions following. Graded automatically at 84 transcripts via the `ladder-ritual-trial` DEFERRED-DECISION trigger; the result is filed as a dated PENDING entry whichever way it falls. Do not add to, reword, or "improve" this line before the trial is graded — a second change confounds the only check standing behind PENDING-112's causal claim. -->
- Read `~/.claude/projects/-Users-davidglidden/memory/session-ledger-[previous-date].md` if it exists — **specifically read the "Returns" and "Confidence to recalibrate" sections** for mood signal
- **Link-resolution canary (seconds-cheap):** verify MEMORY.md's file pointers resolve — every `](file.md)` target exists in the memory dir. Flag dead pointers in the briefing, distinguishing pre-existing-broken from newly-broken (grep the previous git state if in doubt). A pointer to a missing file is the index lying about what memory holds. <!-- 2026-07-19 harvest review (steward-authorized): the wake-canary link-resolution half, proposed 2026-06-07, partially built 2026-07-06 (truncation half), now standing. -->
- **Link-resolution canary — READ THE DIGEST'S `MEMORY POINTERS` LINE; do not re-implement it.** `~/dotfiles/scripts/wake-digest.py` runs at SessionStart and reports both indexes over both link forms — path pointers `](file.md)` and `[[wikilinks]]` — in four outcomes each (OK · MIS-AUTHORED, with the replacement string handed back · DEAD/UNWRITTEN · NON-PORTABLE), and dates each break as pre-existing or newly-broken from git. Surface any non-OK outcome in the briefing; a pointer to a missing file is the index lying about what memory holds. If the digest is absent, run it: `python3 ~/dotfiles/scripts/wake-digest.py`. ⚠ **Never hand-type this check.** It was typed inline on 2026-08-08 and again on 2026-08-09, and the hand version's one "finding" was the link pattern inside its own specification — the executable strips code spans and the hand version cannot. Prove the instrument before trusting a clean line: `wake-digest.py --selftest` (61 checks, positive and negative controls). <!-- 2026-07-19 harvest review (steward-authorized): the wake-canary link-resolution half, proposed 2026-06-07, partially built 2026-07-06 (truncation half). 2026-08-08: built as classify_pointers (19bddd5). 2026-08-10 [FIX], steward-directed: code-span blindness closed, wikilinks added (the ladder had specified them since 2026-07-06), breakage dated from git, and this step turned from a description into a pointer at the executable — the described-not-invoked gap was the whole reason it kept being retyped. -->
- **Telos conditional:** if the pulling thread touches the studium engine / The Making / ARC-as-public-proof (the engine's reason-for-being), also read `project-studium-engine-telos-chamber-of-voices.md` and hold ONE line of the why in the briefing — the telos lane drawn first, never only the production lanes. Do NOT recite it on unrelated wakes (decorative). <!-- 2026-07-19 harvest review (steward-authorized): proposed 2026-06-18 after the steward had to re-disclose the chamber's origin; second evidence instance 2026-07-19 (map-drawn-from-production-lanes-not-telos, steward corrected twice). -->
**b. The files layer — primary memory** `[palace-memory MemPalace wound down 2026-07-07]`