session 2026-09-04: PENDING-179 gates, OWED-5 queued, Active Session rotated

Session record, ledger merge, MEMORY.md rotation (prior Active Session
demoted verbatim to MEMORY-reference.md), 6 KG triples, and OWED-5 queued
in PENDING-141's ratified owed-entries list.

OWED-5: a must-detect control must report its denominator, and a denominator
of zero is a FAIL. Steward-stated 2026-09-04, queued unruled — the ladder is
frozen under REVIEWED-123, and turning the rule on converts currently-green
controls to red across the fleet, which is a ruling rather than an edit.

Earned on the vacuous PASS (0/0) that nearly certified a broken discriminator.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X3L79vgAnt1x2kxvf23Qt7
This commit is contained in:
David F Glidden
2026-09-04 10:30:41 +02:00
co-authored by Claude Opus 5
parent c150bdff17
commit 65c0884dc9
5 changed files with 255 additions and 7 deletions
@@ -0,0 +1,222 @@
---
name: Session 2026-09-04 — the discriminator was a coincidence
description: "Woke into the steward's directive to make the wake and wrap tools reliable; a handover reordered the work so that preservation ran first and three read-only gates stood before any repair. Gate 2a failed and the repairs never happened — human_turns(), the function the whole plan called 'already controlled', is not a mumble discriminator at all: it detects slash-command markers, and excludes a mumble only when the session that mumble quoted happened to contain a slash command. The two leaks are exactly the two marker-free mumbles. Filed PENDING-179 as an item rather than a -178 addendum, on PENDING-145's suppression mechanism. Also found: preserve-transcripts.py claims its destination is git-tracked and it is not, so 11 transcripts that exist nowhere else sit on one disk. PULLING THREAD: unchanged in name but now preceded by two steward-set acts — git-init the transcript archive, and suspend automatic grading at trigger_fired() — after which -178 and -179 are ruled jointly."
type: project
metadata:
node_type: memory
type: project
modified: 2026-09-04
---
# Session 2026-09-04 — the discriminator was a coincidence
Ran from the evening of 2026-09-03 into 2026-09-04. Second session of 09-03; the first was the
MEMORY.md load-integrity breach.
## PAST — what moved, and why
### The handover reordered the work, and the reordering is why the session succeeded
The steward's instruction was *"go ahead with the fix — positive control first"*, accompanied by a
handover that changed the ordering. Three of its moves mattered:
- **Preservation runs first, because it expires.** The positive control does not.
- **Site 1 (`governance-drift-check.py:513`) is excluded on receipt, not as a step I perform.** The
ladder trigger's meaning is steward and jurist territory.
- **Repair is step 4, gated on 2a and 3** — not the next action after the control.
⚠ **The handover also caught a claim I had made at the wake.** I reported 31 mumbles from running
`human_turns()` over all 65 transcripts. That *classified using* the function; it did not *validate*
it. Treating it as having discharged 2a would have been the derived-form flag exactly.
### Step 0 — preservation
`preserve-transcripts.py`: **76 transcripts, 143.5 MB, read-back PASS.** 33 newly added, 1 refreshed,
and **11 already pruned at source, surviving only in the archive.** That last number is not
incidental — it is one of gate 2b's two terms, and it is also what makes the two stores permanently
divergent.
### GATE 2a — FAIL in both directions, and the repairs stopped
Ground truth taken from the fool's own prompt text (written by `tarbuckle-*.py`, not by the function
under test): **24 known mumbles, 41 known non-mumbles**, of 65.
- **must-detect 22/24** — two mumbles return `human_turns == 1` and read as human-attended.
- **must-not-flag 35/41** — six non-mumbles return `0`, and ⚠ **at least one of those is CORRECT**:
`b7e7eb39` is the unattended executor session of 2026-08-31 (PENDING-172), which genuinely has no
human turn. **`0` never meant "mumble". It means "nobody spoke"**, which is equally true of an
unattended real session.
**Mechanism, confirmed rather than inferred.** `human_turns()` skips any `user` record containing one
of seven `NONHUMAN` markers. A mumble embeds the *previous session's* material in its prompt, so it
inherits those markers **only when the session it was mumbling about happened to contain a slash
command**. Of 24 mumbles, 22 embed a marker and are excluded; **2 embed none — and those 2 are
precisely the 2 that leak.** The correlation is content-dependent coincidence. The function's own
docstring says it answers *"did an executor just run unattended?"*, and at that job it is correct.
**No replacement was built, per the handover and for its stated reason:** three controls passed and a
fourth broke, so the finding is about the **control set**, not only the function. All three test the
question the function was *for*; none could see the question it was being *reused* for.
### GATE 2b — composition stands; two terms do not close
Reconstructed from the archive by the same ground-truth signature:
| date | N | real | mumble | % |
|---|---|---|---|---|
| 2026-08-31 | 52 | 41 | 11 | 21.2 |
| 2026-09-01 | 50 | 39 | 11 | 22.0 |
| 2026-09-03 (measured live) | 65 | 41 | 24 | 36.9 |
**-178's composition claim stands**: 11 mumbles and "roughly a fifth" close exactly on 08-31. Against
-178's enumerated `54 = 43 + 11` on 09-01 I reconstruct `50 = 39 + 11` — **the mumble term identical,
the whole 4-file gap in the real-session term.** ⚠ **Not asserted against -178.** My method models the
prune as a 30-day window over `source_mtime` and is a demonstrated **lower bound**: preservation has
run **twice only** (08-26, 09-03). Where we disagree, -178 enumerated live and is better positioned.
**Record-only correction applied** (authorized): `MEMORY.md` carried *"N-now 44/84 as of 2026-08-31,
DOWN 7 from 51"* — wrong in the number and **backwards in the direction**. Now **65/84 measured**,
with composition stated, and the stale `governance-drift-check.py:331` pointer corrected to `:513`
(`:331` is a register-check control; both lines read before changing it).
### GATE 2c — five sites in four files; -178's scope holds
Controls named before the run. Enumerating consumers: `governance-drift-check.py` (426, 513) ·
`wake-digest.py` (354 + the selftest sample) · `tarbuckle-invoke.py` (37, 44) ·
`preserve-transcripts.py` (45, 126, 172). `tarbuckle-wrap.py` and `-seam.py` are **not** consumers —
they receive `transcript_path` from the hook payload.
⚠ **What the census cannot see, as output rather than caveat:** (i) a consumer that builds the path by
component join *and* never enumerates `*.jsonl` on a matching line — **demonstrated: `wake-digest.py`
does exactly this and escaped a literal-fragment grep over the whole fleet**; (ii) anything reaching
the population through a hook-supplied `transcript_path`; (iii) anything outside the swept roots.
**(i) applies retroactively to the four-site census inherited from the previous wrap, which was
grep-derived by the method just shown to be blind.**
### Filed, corrected, committed
- **PENDING-179** — as an item, not a `-178 ADDENDUM 1`, on PENDING-145's mechanism: `ruled_pendings`
claims a **number**, so an addendum would be suppressed the moment -178 is ruled. The undecided
filing moratorium is disclosed inside the item, with the previous session's contrary reasoning
preserved rather than overridden.
- **`c150bdf`**, pushed to `github` and `gitea`, **both verified at the same SHA**.
- **OWED-5 queued** in PENDING-141's owed-entries list (the ratified queue, REVIEWED-123 cond. 3).
### ⚠ The archive is not backed up, and the script says it is
Found while checking repo state for the commit. `preserve-transcripts.py:11` states it copies
transcripts *"to a git-tracked location so the population stops shrinking."* **`~/_Dev/claude-transcript-archive`
has no `.git`, no parent repo, and is 144 MB.** The copying works — every file is re-hashed on
readback — but the sentence describing where they went is false, and **11 transcripts now exist in
exactly one place on one disk.** PENDING-144's class (substrate claims inside governance scripts
checked by nothing), at the worst possible site: the docstring is what anyone reads to decide whether
the evidence is safe.
## PRESENT — how it stands
**The mood.** Unusually clean, and the cleanliness is entirely borrowed. The handover did the work
that made this session good: it put preservation before the control, excluded site 1 so I could not
wander into it, and — decisively — insisted the "already controlled" claim be tested before anything
was wired anywhere. Left to my own plan I would have written a positive control for a fixture and
wired a broken predicate into three more sites, all of it green.
**What was corrected — three, and the first is mine from four hours earlier.**
1. **My wake census used `<= 1` as the mumble threshold**, silently absorbing 3 transcripts that
return exactly 1. The real distribution is 28 at 0 and 3 at 1, and the ground-truth split is
24/41. The wake number (31) was wrong and the method behind it was wrong in a more interesting way.
2. **A vacuous `PASS (0/0)`.** My first ground-truth query used the signature from
`tarbuckle-invoke.py` — the file I had just read — and matched **0 of 65**. The gate went green on
an empty denominator. Caught by *a null search is evidence about the QUERY*; opening a transcript
showed the mumbles come from three **other** fool surfaces (`tarbuckle-mumble/-wrap/-seam`) that
the inherited site census never named. **This is now OWED-5.**
3. **The previous wrap predicted the digest selftest would "fail on every run from now on."**
Falsified within 2.2 h: it passed at this wake (5 of 13). The defect is *intermittent* — a
function of the mumble rate in a rolling 13-transcript window — which is harder to notice than a
permanent failure.
**Confidence to recalibrate.**
- **Verified by running it:** the 2a confusion matrix over all 65 with independent ground truth; the
leak mechanism (2 leaks == 2 marker-free mumbles, exactly); N-now 65 and its 24/41 composition;
preservation readback; both remotes at `c150bdf`; the archive has no `.git`.
- **Reconstructed, lower-bound, NOT asserted against -178:** the 08-31 and 09-01 rows of the 2b table.
- **Inherited and now known to be unreliable:** the four-site census from the previous wrap —
grep-derived by a method this session demonstrated is blind to component-joined paths.
**Instruments:** 4 run (ground-truth classifier · archive reconstruction · consumer census ·
histogram) · **1 carrying a control written before first execution** (the consumer census, whose
must-find and must-not-find were named in the file before it ran — and the must-not-find *fired*,
catching the vendored-docs pollution) · **K = 0** — none duplicated anything banked; all four answered
questions asked once. ⚠ **The census was narrowed three times.** Repeated narrowing can end by
confirming the sites it was built around; the negative control and the explicit blind-spot statement
are what keep that honest, and they are not a substitute for someone checking it.
**Decisions deferred, and why.**
- **No repair at any site**, and no replacement discriminator — gate 2a's stated consequence.
- **`governance-drift-check.py:513` not examined at all** — excluded on receipt.
- **Did not `git init` the archive.** 144 MB is real weight for both remotes, and full transcripts
contain everything ever typed in these sessions; whether they belong on a hosted remote is a
steward decision, not a chore.
- **Did not correct `preserve-transcripts.py`'s false docstring.** Editing a governance script's
stated rationale to match a worse reality is the direction that makes docstrings worthless. It
should become true, or be corrected as a disclosed change.
- **OWED-5 queued rather than patched in.** Turning the rule on converts currently-green controls to
red across the fleet; that is a ruling, not an edit — and the ladder is frozen regardless.
## FUTURE — what pulls
**The pulling thread is unchanged in name and now has two steward-set acts in front of it.**
The fr cell's last two steps still pull. But the steward has set the next session's opening
explicitly, and it is not that.
### Next session, first work — steward-directed 2026-09-04
1. **`git init` the transcript archive.** The steward has named this as the wake's first act.
2. **Suspend the automatic grading at `trigger_fired()`.** ⚠ **Stated precisely by the steward, and
the precision is the point: this is NOT a repair, NOT a filter, and NOT -178 option (b). It
changes nothing about what the counter counts, so the site-1 exclusion survives intact.** It
prevents a grade firing on a population whose contamination is measured and rising.
### Then the joint ruling — steward, 2026-09-04
**-178 and -179 are ONE decidable unit** and will be ruled together. -179 is -178's evidence and says
so in prose, because the numbering cannot carry it (PENDING-145). The joint ruling covers **unit,
window, recurrence, predicate, and seeding.**
⚠ **Seeding has grown a second half, and it is new today.** Preservation has **permanently diverged
the two stores**: 11 files exist only in the archive. So the question is no longer only *what N*, but
**over which store** — and the trigger reads **live**, while any honest grading of a post-08-07
population must read **preserved**.
**Steward's positions, recorded so they are not re-litigated:**
- **Agrees with -179's option (c)** — a mumble that declares itself cannot be misread by a marker
coincidence — **and with the refusal to build it now.**
- **The lesson is the control set, and it generalizes past this function:** three controls passed and
a fourth broke, and all three tested the question the function was *for* rather than the question it
was *reused* for.
**Other horizons, ranked.**
- **The archive's single copy** — a local second copy is the cheap half and answers none of the
remote question. Unresolved.
- **`preserve-transcripts.py:11`'s false claim** — becomes true after the `git init`, which is the
clean resolution and is why the steward put the init first.
- **`~/.claude/agents` under version control** — steward-directed, still owed, before anything else
edits it.
- **The filing moratorium** — undecided, and PENDING-179 was filed under it with that disclosed.
- **PENDING-171** → unblocks 322 unread of 362 · **-160** · **-168** · the §5 regrade, an eighth session.
- **Parked worker `acaabadf`** — stopped, still carrying `--reply-on-resume`. Untouched again.
**Pause statement.** I am about to be away from this and the context is being cleared deliberately.
What I want to find still pulling is the fr cell's last two steps — but what I want the next session
to *do first* is the two acts above, in that order, because the steward set them and because the
`git init` is what makes an already-false docstring true rather than requiring it to be edited into
honesty. ⚠ What I want the next session to **notice** is that this session's entire value came from a
gate that stood between a plan and its execution. The plan was mine, it was confident, and it was
wrong. **The handover did not improve the fix; it prevented it.**
**Literal question for next-Claude** *(checkable; turns on the record, not introspection)*:
**How many other must-detect controls in the fleet currently have a denominator of zero?** OWED-5 is
queued on a single observed instance. The fleet's controls are enumerable and their denominators are
computable without changing any of them. ⚠ If the answer is zero, OWED-5 is a rule earned from one
accident and should be labelled that way rather than carried as a general finding. If it is more than
zero, then some number of currently-green controls have never tested anything — and nobody knows
which, because a vacuous pass and a real pass print the same word.