Files
dotfiles/claude/memory/session-2026-09-14-the-guard-was-path-keyed.md
T
David F GliddenandClaude Opus 5 45268f6349 session 2026-09-14: the 59 answered (zero name their parent); PENDING-186 + PENDING-175 amendments; the memory write-guard is path-keyed
- The 59 unattributable register blocks: ZERO name their parent in their own
  text; all position-only. 37 cite only FOREIGN ids, so an id-keyed repair
  would mis-file every one. The obvious automated repair is worse than none.
- PENDING-186 [PROPOSAL] filed + AMENDMENT 1: the 'silent failure' ordering
  constraint is falsified (the harness warns at write time), and the real
  defect is that our write convention routed around that guard.
- Claude Code's near-limit MEMORY.md guard is PATH-KEYED: 5/5 warnings via the
  ~/.claude symlink path, 0/2 via the real dotfiles path at a LARGER size.
  Pre-registered and confirmed. MEMORY.md must be edited by the symlink path.
- PENDING-175 AMENDMENT 1: governance_item returning only the first block is
  no longer predicted but REPRODUCED, located at governance-mcp.py:199-202;
  the second defect is narrower than reported - it is a colon.
- Both amendments filed id+marker so they do not join the 59 they describe.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJM5fwqp456LDGzqiZXsgu
2026-09-14 20:18:39 +02:00

13 KiB
Raw Blame History

name, description, metadata
name description metadata
session-2026-09-14-the-guard-was-path-keyed The 59 answered — ZERO name their parent, all position-only, and 37 would be actively MIS-FILED by the obvious repair. Then a jurist falsifier turned my own false claim into the day's finding: Claude Code's memory guard is PATH-KEYED, and our write convention had routed around it. Eight false claims of mine corrected, almost none caught by re-reading. PULLING: the repair of the 59 is per-block and steward-only; the question is whether the register's CONVENTION (PENDING-146) must be settled before anything else is appended.
node_type type originSessionId modified
memory project bcfabffa-1ecb-4d15-9efe-2140912714b9 2026-09-14

2026-09-14 — the guard was path-keyed

A session that crossed midnight (woke 09-13, nearly all work 09-14) and did both halves of the steward's "proceed sequentially" — the index relocation, then the 59. Both produced findings that inverted the premise they started from.


PAST — what moved, and why

Half one: the index. The premise was right; my correction of it was the error.

  • The limit is real and documented: auto-memory loads the first 200 lines OR 25 KB, whichever comes first; content past it is not loaded at session start. Established from Claude Code's own docs via a subagent, not from our record.
  • ⚠ My wake briefing inverted it. I reported two competing ceilings (17.1 / 24.4 KB) and announced the measurement had falsified the first. 17.1 KB was never a ceiling — it is the harness's compaction target, mis-transcribed as a ceiling in the 09-12 ledger, which I inherited and then "falsified". Past-me's "~94%" was correct. 25,000 B = 24.41 KiB, so the 24.4 figure is the documented limit in the other unit. I also asserted the warning was ours; it is the harness's, and my failed grep for an emitter is what proves it.
  • PENDING-186 [PROPOSAL] filed — the structural point stands: 59% of the index is standing preferences that must fire WITHOUT a lookup, so no trim exists that is not a loss of function.
  • AMENDMENT 1 filed after the jurist's falsifier landed (below), plus a self-correction inside it.

The jurist's falsifier, and the day's real finding

  • The jurist caught that "there is no load-time warning" was untested, then handed me a test: if the warning exists and we are at 95%, it should already be firing; if it never has, the writes are outside the instrument.
  • ⚖ It fired. The guard is PATH-KEYED. 5/5 genuine warnings followed edits via the ~/.claude/projects/…/memory/ symlink path; 0/2 via the real ~/dotfiles/claude/memory/ path. realpath identical. ⚠ Rival excluded by internal control: the silent case was larger (23.9 KB) than every firing case. Pre-registered and confirmed — an edit routed through the symlink path warned immediately, and stamped frontmatter modified: as a second signature.
  • ⚠ Our own convention routed around it. reference-governance-files-are-dotfiles-symlinks.md is scoped PENDING/REVIEWED only; I extended it to MEMORY.md. The workaround that makes the write possible is what disables the alarm.
  • ⚠⚠ And I first blamed the note. Read in full it says "…for PENDING.md and REVIEWED.md only" and never mentions MEMORY.md. Nothing to correct — I over-applied a correct note and named the note as the defect. Corrected in the filed item before any ruling could rest on it. The note gained an addition: FILE-symlink ≠ DIRECTORY-symlink (writing through the symlink directory succeeds), plus the measured cost.

Half two: the 59 — answered

  • ZERO of 59 name their parent. Not a split — a floor. The inherited question presupposed a split that does not exist; all 59 are position-only.
  • Buckets (controls: my widening reproduced the instrument's 59 exactly; buckets sum to 59): (a) explicit **Amends:** claim = 0 · (b1) mentions its own position-parent = 12 · (b2) mentions ONLY foreign ids = 37 · (c) no id anywhere = 10.
  • ⚠ THE FINDING NOBODY ANTICIPATED: the 37 are booby-trapped, not merely missing data. pos=PENDING-152 whose body offers PENDING-4; pos=PENDING-96 offering PENDING-97. An id-keyed repair reading bodies would mis-file every one, confidently — a cross-reference and a parentage claim are identical at the token level. The obvious automated repair is worse than none. Derived by asking what a CONSUMER must do.
  • ⚠ The instrument I was told to enumerate from cannot answer the question. register_scan returns (label, form, title[:72]) — no body, header truncated. Its unit is the header; the question's unit is the block. Handled as a declared widening: the module's own recognizers set membership, the body-read is mine and labelled mine.
  • ⚠ I nearly shipped 12 as "weakly derivable". It is not derivation — consistency is not confirmation. Corrected before reporting.

The register's own read path is broken, and it nearly produced a ruling on a stale item

  • The jurist's governance_item('PENDING-186') returned the original byte-identical, with no sign AMENDMENT 1 existed. It was one step from ruling on an item that withdraws (c), adds a fifth condition, and records a conflict with its own finding.
  • Reproduced and located: 2 blocks exist, t_item returns 1. governance-mcp.py:199–202 — a return inside the span loop where an accumulate belongs. PENDING-175 is no longer predicted; it is observed.
  • ⚠ I corrected the jurist's account of the second defect, and the difference changes the fix. Reported as "search surfaces ids the fetch tool cannot take". Measured: fed the displayed head byte-exactly, t_item resolves it. What fails is the natural truncation — 'PENDING-186 — AMENDMENT 1' → NOT FOUND, because startswith(ident + " ") meets "1:" not "1 ". The defect is a colon. The reported form would have sent someone to build a new lookup path. ⚠ The false claim "no second definition of 'an item'" is inside the docstring of the function making it, and the existing unreachable-by-id guard is provably silent here.
  • PENDING-175 AMENDMENT 1 filed, id+marker, under an id whose own retrieval is broken in the way it describes.

PRESENT — how it stands

The mood. Relentless and productive, and unusually humbling. Two halves both delivered, and eight of my own claims turned out false along the way. Not a bad session — the corrections were the output — but the pattern underneath is the thing to carry.

What held.

  • Every filing predicted its own classification and was checked after: id+marker form kept both amendments out of the 59 (id+marker 19→21, NOT ESTABLISHED unchanged at 59).
  • Controls written before execution caught what reading never did — four times.
  • thread-query returned a second consecutive null, reported as null.

What was corrected — mine, eight. the "falsified ceiling" · the warning's ownership · two byte predictions (said neutral/shorter, got +341/+53) · an external writer that didn't exist (read a render as a diff) · a two-point test that could not discriminate and was knowable in advance · a note I blamed for my own misreading · the "(e) forces preferences into the Constraint-1 file" objection (retracted: ~/.claude/CLAUDE.md is the documented user-scope file, distinct from ~/CLAUDE.md). Caught before shipping: labelling 12 blocks "weakly derivable".

⚠⚠ THE WORST NEAR-MISS. A check of whether ~/CLAUDE.md loads per session returned 12/63 — which reads as "the constitution governs 19% of sessions." False. The detector's unit is preamble RECORDED; the question's unit is constitution DELIVERED. const and env markers disagree in 0 of 63. ✅ Stopped only because the script printed its own limit before running. ⚠ And my tidy explanation (they're subagents) was refused by the data — fully sidechain 0/51, and 22 carry human turns. Left unexplained rather than explained wrongly.

The pattern. Almost nothing was caught by re-reading my own work. It was caught by a jurist falsifier, a subagent on primary docs, a grep that failed, a self-contaminated control, and a full read of a file I thought I remembered. The rule both parties converged on: test the load-bearing claim, not the disputed one.

Confidence to recalibrate.

  • Verified: the 59 split (two controls) · the path-keyed guard (5/5 vs 0/2, pre-registered, rival excluded) · both MCP defects by execution · register counts after every append · N-now 63 raw, 31 at ≥1, 25 at ≥2 with a negative control.
  • Reported-verified, NOT verified: ~/.claude/CLAUDE.md as documented user-scope, and InstructionsLoaded / .claude/rules/ — from a reader whose retrieval was shown partial in the same exchange.
  • Open and named: the 10 k hook-output cap (jurist quotes primary source; my reader retracted to could-not-assess with a passing positive control) · the guard's reported figure reconciles with no unit I can compute · why 22 human-bearing transcripts record no preamble.

Instruments. ~26 runs · ~14 carrying a control written before first execution · K = 1 — the two-point unit check duplicated nothing banked, but the discrimination gate it violated is already on the ladder, so the failure was a banked lesson not reached for. ⚠ Do not read the run count as a reliability rate; the denominator is failures a control happened to exist for.


FUTURE — what pulls

The pulling thread — the repair of the 59 cannot be derived, and PENDING-146 owns why

Not "fix the headings". 37 of 59 would be mis-filed by the obvious repair, so the convention question (PENDING-146) is not a tidy-up deferred behind the repair — it is the thing that must be settled first, because every future amendment appended under the present convention joins the population. This session filed two amendments in id+marker form specifically to avoid that, and that form is a de facto proposal PENDING-146 has not ruled on.

Actionable resumption point (as of wrap — re-judge against what changed)

  1. Read PENDING-186 and PENDING-175 by governance_read, NOT governance_item — the fetch tool returns only the first block per id (governance-mcp.py:199–202) and will hide both amendments.
  2. The jurist has offered twice to draft the PENDING-186 ruling on five conditions; its own argument is that (c) fails on three grounds independent of the unresolved 10 k number, so the ruling is not blocked.
  3. The one-line behavioural test that settles the 10 k cap: emit 10,001 chars from a hook and look for the preview-plus-path signature. ⚠ Needs steward authorization — it writes to hook config, and PENDING-165 already records an external tool doing that on nobody's authority.

Other horizons, ranked

  1. PENDING-186 + PENDING-175 await rulings (both [FIX] and [HARDENING] parts named).
  2. The index is at ~24.1 KB of 25,000 and silent at the limit on load. The guard now speaks again — but only if MEMORY.md is edited by the symlink path.
  3. The hook channel has NO write-time guard at all (jurist's point): if the 10 k cap is real, wake-digest.py sits at 8,136 chars = 81% with no near-limit warning and no over-limit error. The item's failure shape, reproduced one channel over, unfiled.
  4. The shared-substrate finding → PENDING-89/-140, still banked not filed; venue 2026-09-16.
  5. Seb's 08-04 reply unread; worker acaabadf stopped but ARMED; 2 stray Desktop maps.
  6. 2026-09-16: joint PENDING-178/-179 + ladder-freeze review. OWED-6 unchanged.

Pause statement

I am about to be away from this. The register will sit with 59 blocks nobody can attribute and 37 that would actively mislead a repair, exactly as it sat this morning. What I want to find still pulling is not the repair. It is the recognition that every instrument in this system, including the one that counts attributable amendments, assumes position means ownership — and that today the same assumption was found in a third place: the memory guard assumed the path you write is the file you mean.

The literal question for next-Claude

Does a lesson banked from one failure ever stop a different failure — and can the record show it, rather than my recalling it?

Four prevention triples were appended today claiming exactly that (a script's own printed limit stopping a false constitutional alarm; read-before-edit stopping a blame-shift; running-not-reading correcting a jurist's mechanism; the 59-finding keeping my own amendments out of the 59). Check them against the record, not against my memory of them. ⚠ The failure that will look like success: counting the prevention lines. I wrote those lines. A checkable question over a self-authored corpus is self-report with extra steps — narrow it until it turns on what the transcripts show, not what the triples assert.

(Carried, unanswered a fourth day: 2026-09-10's question about whether any ruling placed before this week can be checked against anything.)