From e5db321d6feb4db39a4dfd4c37e1c9eecfffe618 Mon Sep 17 00:00:00 2001 From: David F Glidden Date: Thu, 3 Sep 2026 08:48:53 +0200 Subject: [PATCH] session 2026-09-03 ADDENDUM 1: the mumble/session conflation is a class, and it is [FIX] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Steward, after the wrap: "deal with that right away — I need the wake and wrap tools to be reliable." Read-only census run before closing so the next session starts from a list, not the symptom. One root cause: the transcripts directory is a proxy for "a session" and a Tarbuckle mumble is indistinguishable from a session at the file level. Four confirmed consumer sites plus one suspected, three already misbehaving — including wake-digest's previous_transcript, which produced the false "ran unattended" alarm on 2026-09-01 and whose code was never changed. human_turns() at wake-digest.py:932 is already the discriminator and already carries controls; it is wired only to control (c). The work is wiring a tested function into the remaining call sites. Corrects my own wrap-time classification: this is [FIX], not [PROPOSAL]. The control's label already names "a real session"; its sample contains none, so restoring that population repairs it against its existing specification. The [FIX] reading does NOT extend to what the ladder trial's >=84 trigger means — that stays PENDING-178 under REVIEWED-123's freeze. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01X3L79vgAnt1x2kxvf23Qt7 --- claude/memory/MEMORY.md | 1 + ...6-09-03-the-index-had-become-the-record.md | 64 +++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/claude/memory/MEMORY.md b/claude/memory/MEMORY.md index 70c4e87..3df0858 100644 --- a/claude/memory/MEMORY.md +++ b/claude/memory/MEMORY.md @@ -73,6 +73,7 @@ permalink: claude-memory/memory - Chamber-typography — *tracker not yet established*; moves live in per-session memories (2026-05-11 →) + `project-chamber-cruft-restoration.md` + `project-chamber-typography-mining-plan-2026-05-15.md`. ## Active Session +> 🔴 **NEXT SESSION, FIRST WORK — STEWARD-DIRECTED 2026-09-03:** *"deal with that right away — I need the wake and wrap tools to be reliable."* **ONE root cause, 4–5 consumer sites:** the transcripts dir is a proxy for *"a session"* and **a Tarbuckle mumble is indistinguishable from a session at the file level.** Sites: `governance-drift-check.py:513` (PENDING-178) · `wake-digest.py:354`→`previous_transcript` (**the false `unattended` alarm of 09-01 — diagnosed, code never changed**) · `wake-digest.py` selftest `_tx[-14:-1]` (**fails every run**) · `tarbuckle-invoke.py:40` (⚠ **SUSPECTED, VERIFY FIRST**). 🔑 **The discriminator already exists and is controlled — `wake-digest.py:932 human_turns()`; this is wiring a tested function into 4 call sites, not building a classifier.** ⚠ **It is `[FIX]`, not `[PROPOSAL]` — my wrap-time classification was wrong**: the control's label already says *"a real session"*, so restoring that population repairs it against its own spec. **Does NOT extend to changing what the `>=84` trigger means** — that stays PENDING-178/REVIEWED-123. **Write the positive control FIRST.** Full census + first steps: ADDENDUM 1 of the session record. > 🔑 **THE INDEX HAD BECOME THE RECORD.** `MEMORY.md` breached its load budget and was being **silently truncated at wake** — but the cause was not bulk. Five tracker entries had grown into paragraphs, and for **three the index was the SOLE custodian of live state**: the studium tracker stopped at **2026-08-13** while the index carried engine news to 09-01 · the Fool's only link was a **sealed seed**, with nowhere legitimate to append · L1's replay **mechanism** (`minCursor` is a minimum over 11 modules, two never participate ⇒ pinned at 0 **by construction**) and **completion criterion** (uninterrupted run length, not rate) existed nowhere else. All relocated verbatim; **Tarbuckle got a tracker**. 26,803 → 23,714 (`2171d91`, both remotes verified). > ⚠ **PRUNING WOULD HAVE BEEN HARMFUL.** The cut took its rule from the file's own Index discipline — trackers are pointers — and so **left "Rules that fire silently" untouched**: those keep their text inline because they fire when I would not know to look. Cutting the loudest lines would have removed the catches and still left three workstreams undocumented, now deleted rather than truncated. > ⚠ **THE CANARY WAS CLEAN AND ITS SELFTEST WAS FAILING** (86/87). The failing control samples the 13 most recent transcripts; **all 13 are Tarbuckle mumbles** (~66 KB, one human turn each). **PENDING-178's defect at a SECOND site** — it will now fail on every run, and a control that always fails is one everyone learns to ignore. The **pointer** controls, which the trim rests on, all pass. Not filed (moratorium undecided). diff --git a/claude/memory/session-2026-09-03-the-index-had-become-the-record.md b/claude/memory/session-2026-09-03-the-index-had-become-the-record.md index a4c96b5..111b90b 100644 --- a/claude/memory/session-2026-09-03-the-index-had-become-the-record.md +++ b/claude/memory/session-2026-09-03-the-index-had-become-the-record.md @@ -181,3 +181,67 @@ bytes. The gap between those two dates is the answer, and the second half of the anything *other than the harness's own truncation warning* was positioned to catch it. ⚠ If the answer is "only the harness," then the file's self-bounding discipline is documentation, not a mechanism — and the same is true of every budget in this system that no instrument measures. + +--- + +## ADDENDUM 1 — after the wrap: the steward makes this the next session's first work + +⚠ **Appended 2026-09-03 after the session record was written, committed and pushed.** The wrap was +complete; the steward then read §8 and said: + +> *"We should, if possible, deal with that in the next session right away — I need the wake and wrap +> tools to be reliable."* + +**That reframes the item, and the reframing is the point.** §8 handed over "a failing control in +`wake-digest.py`". What is actually being asked for is that **the instruments the wake and wrap run +on can be trusted** — which is a class, not an instance. A read-only census was run before closing, +so the next session starts from a list rather than from the symptom. + +### The root cause, and it is one thing + +**The transcript directory is used as a proxy for "a session", and a Tarbuckle mumble is +indistinguishable from a session at the file level.** Every mumble writes a ~66 KB `*.jsonl` into +`~/.claude/projects/-Users-davidglidden/` exactly as a real session does. Every consumer that counts, +sorts, or samples that directory therefore counts mumbles as sessions. + +### The consumer sites — census by grep over the fleet, 2026-09-03 + +| site | what it does | state | +|---|---|---| +| `governance-drift-check.py:513` | `len(glob("*.jsonl")) >= N` — the ladder trial's `transcripts 84` trigger | **PENDING-178's filed site.** Counter moved 44 → 52 in one day | +| `wake-digest.py:354` → `previous_transcript()` | picks "the previous session" for control (c) | **This produced the false `ran unattended, PENDING-172` alarm on 2026-09-01.** Diagnosed that day; the thread was pulled to -178 and **the code was never changed** | +| `wake-digest.py` selftest, `_tx[-14:-1]` | end-to-end wrap control over 13 recent transcripts | **Today's finding.** 0 of 13 wrapped; all 13 are mumbles. Fails on every run | +| `tarbuckle-invoke.py:40` `newest_transcript()` | *"the session he is in the room for"*, newest by mtime | ⚠ **SUSPECTED, NOT VERIFIED** — if a mumble's own transcript can be newest, Tarbuckle reads a previous mumble as the live session. Feedback loop. **Verify before asserting** | +| `preserve-transcripts.py:45` | archives before the **~30-day retention prune** | Not a defect — and it is the mechanism behind the ladder counter's rolling window (PENDING-147) | + +🔑 **The discriminator already exists, is already controlled, and is simply not wired to the sites +that need it.** `wake-digest.py:932 human_turns(path)` — REVIEWED-131 cond. 2 — counts genuine human +turns, returns `None` for unreadable (*"unreadable is not zero"*), and carries three passing controls +including `human_turns returns 0 on a hook-only transcript [must-detect]`. It is used for control (c) +alone. **This is wiring a tested function into four call sites, not building a classifier** — which is +why "right away" is realistic. + +### ⚠ Correction to my own wrap-time classification + +§8 recorded: *"did not re-scope the failing selftest control — changes what a governed instrument +asserts → `[PROPOSAL]`."* **That was wrong, and it would have blocked the steward's instruction on a +boundary that is not there.** The control's own label states its predicate: *"a real session reads as +WRAPPED end-to-end."* Its sample contains **no real sessions**, so the code does not do what it +already says it does. Restoring the population the label names is repairing an instrument **against +its existing specification** — `[FIX]`. It is not a re-scope; it is the opposite of one. + +⚠ The `[FIX]` reading covers **restoring the intended population at each site**. It does **not** +cover changing what the ladder trial's `>=84` trigger *means* — that is PENDING-178's question and +stays the steward's, because REVIEWED-123's freeze is measuring against that counter. + +### Where to put your hands first + +1. `python3 ~/dotfiles/scripts/wake-digest.py --selftest` — reproduce the failure (expect 86/87). +2. Verify the `tarbuckle-invoke.py` suspicion before touching it; it is the one unverified row. +3. Wire `human_turns()` into the three confirmed sites, **writing the positive control first** — + a fixture directory of mumbles plus one real session, where the correct answer is known. ⚠ Today's + own lesson: the conservation checker that shipped without a positive control produced a false loss + report within the hour. +4. **Do not let the count of sites become the measure of done.** The question the steward asked is + whether the tools are reliable, and a fourth site found later is a better outcome than four sites + fixed and the class declared closed.