diff --git a/claude/memory/session-ledger-2026-07-28.md b/claude/memory/session-ledger-2026-07-28.md index 9fbea16..2aefb12 100644 --- a/claude/memory/session-ledger-2026-07-28.md +++ b/claude/memory/session-ledger-2026-07-28.md @@ -49,6 +49,9 @@ type: feedback - 2026-07-28T10:40 — ⚑ **The `.app`/`CLAUDE.md` question has a structural answer, not a tooling one.** Their readers differ in filesystem access, so one document can *compute* its state and the other can only *cache* it — confirmed by substrate (the live preferences exist nowhere on disk; only March-era sandbox snapshots). **Duplication between them is structurally required; only its staleness is optional.** The corollary I nearly missed: a pointer is worthless to a reader who cannot open files, which is *why* the preferences accumulated state in the first place. Reusable: before proposing a single-source-of-truth, check whether every reader can reach the source. - 2026-07-28T10:40 — ⚑ **The party structure itself has drifted, and both documents are constitutional.** `CLAUDE.md` names three parties; the `.app` preferences name Cowork as a fourth under `COWORK.md` — a real document, dated Mar 22, orphaned in an agent-mode sandbox — while calling the model three-party. The MemPalace weld shape, one layer up: doctrine welded to a retired instrument, where the instrument is *a party*. No generated block can fix it; it needs a ruling. - 2026-07-28T11:25 — **Archive break repaired on steward authorization** (*"yes, absolutely"*): `7f6157a`, pushed `8abfe88..7f6157a` to `github/main`. `PENDING-archive.md` now tracked; the record the remote carries is whole again. Verified **before** committing, not after: baseline `PENDING.md.bak-2026-07-28-pre-split` (1848 lines) ⊆ (`PENDING.md` ∪ `PENDING-archive.md`) at **line** granularity — no regex, no parser notion of "item" — with a same-run positive control (sentinel absent from the union → reported missing: true) plus a second control confirming the check is blind by design to the 65 post-split appends. Two [FIX]-class changes, both stated in the commit message rather than left to the diff: the archive add, and the header's self-contradicted counter. `~/CLAUDE.md` and `REVIEWED.md` untouched — Constraint #1 holds. +- 2026-07-28T12:55 — **Placement verified end-to-end; REVIEWED-78/81/82 all AUTHORIZED and placed.** Substrate: `CLAUDE.md` L27 aligned, drift still **0** (7/7 controls), `~/CLAUDE.md` byte-identical to the dotfiles original, three rulings parse with decisions, and the **consumer effect landed exactly as predicted — 18 → 15 open items**, the remaining 15 being precisely the dormant March–May set. The MCP install is proven from the app's own logs, not inferred: `Server started and connected successfully` at 08:23:29Z, then `initialize` → `notifications/initialized` → `tools/list`, each answered by our server; it ran 21 minutes and went down only because the app quit (`willQuit` in `main.log` at the same second). Nothing is broken; the app is simply closed. +- 2026-07-28T12:55 — ⚑ **I predicted the wrong failure and the substrate corrected me — which is the good outcome, not a wasted step.** I reasoned that a GUI app gets a minimal PATH, so `python3` would resolve to `/usr/bin/python3` (3.9.6) rather than the 3.13.14 I tested against, and called that "the real failure mode." The app's log names the interpreter it actually used: `/opt/homebrew/opt/python@3.13/libexec/bin/python3` — Claude.app inherited the **full 22-entry PATH**. The risk *class* was real; the *fact* was not. Two things saved it from mattering: I checked the log instead of shipping the recommendation, and I had already run the selftest under 3.9.6 as insurance — so the fallback is verified even though it is not the live path. Reusable: **a hypothesis about an environment is not a finding about it; the environment usually logs what it did.** +- 2026-07-28T12:55 — **A discriminating test exists for the one thing no substrate can check** (whether the preferences text reached the app), and it is discriminating *by accident of timing*: the generated block pasted into the preferences says **18** open items; the live `governance_state()` now returns **15**, because the rulings were placed after the block was generated. So "15" proves a tool call and "18" proves a stale read. The divergence is the instrument — which means the test must be run **before** the block is regenerated, or the discriminator is destroyed. Sequencing recorded so it is not casually thrown away. - 2026-07-28T12:10 — **PENDING-82 placed** (`~/dotfiles/PENDING.md` L414): the read-only MCP server, `[PROPOSAL]`. Built and self-tested (29 controls + a live stdio round-trip); **not installed** — the `mcpServers` key edits the steward's app config, so the snippet is handed over rather than applied. Appended as a new item rather than edited into PENDING-81, per that file's own append-only rule. Carries the re-drafted §Your Role replacement text and the second, stronger ground for Cowork's retirement (remote Cowork, the incoming default, runs no local MCP at all — so it could not have been the jurist's eyes even in principle). **No REVIEWED-81/82 drafted:** composing a ruling before the ruling is the say–do seam this ledger opened on at 08:12. Offered, not written. ## Sub-agent dialogues