From 69e258116ad65faca94fa47c376f3dd1095c7af6 Mon Sep 17 00:00:00 2001 From: David F Glidden Date: Mon, 17 Aug 2026 14:57:48 +0200 Subject: [PATCH] [HARDENING] PENDING-142: the open/closed criterion verifies an adjacent property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Filed from Task 1 of the 2026-08-17 jurist relay. `governance_state()` computes openness from one signal — whether a REVIEWED header names the PENDING id — and never reads the item's `Awaiting:` field, any status field, or the ruling's `Decision:`. Six items are misclassified in both directions: - 3 falsely OPEN (78, 81, 82): rulings that name the title, not the id. All AUTHORIZED 2026-07-28. REVIEWED-78's own Notes record that it was filed as a separate entry precisely to satisfy the closure rule as it then stood; the rule later changed, breaking the entries written to comply with it. - 3 suppressed under a design gate rather than a steward authorization, one of which (PENDING-121) is marked HELD OPEN by its own ruling. - 2 structurally unclosable: no `PENDING-N` in the header, so no ruling can ever close them. One is the ICP-19 item gating Observer Problem work. - 39 suppressed items still carry a live-reading `Awaiting:` line. Removing the false opens and restoring the false closures leaves 29 — the number the tool reports. The change proof standing behind the current implementation measured exactly that count (18 to 19). A count-based control cannot see a classification wrong in both directions by equal amounts: its subject was the population size, the claim's subject was each item's disposition. Addendum 1 flags that the selftest asserts the defect as intended behaviour, with one of the three hidden items as its fixture. Nothing patched — the relay scoped this to findings only. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_013Y6t6qx7cpaCu5xGdD36u4 --- PENDING.md | 57 ++++++++++++++++++++++ claude/memory/session-ledger-2026-08-17.md | 51 +++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 claude/memory/session-ledger-2026-08-17.md diff --git a/PENDING.md b/PENDING.md index 33614b3..13042be 100644 --- a/PENDING.md +++ b/PENDING.md @@ -3168,3 +3168,60 @@ So **PENDING-138 and this entry are worded to avoid the bare uppercase token**, **Awaiting:** Steward direction on (a)–(d). Not urgent — (a) is the null action and is in force by default while this is open. --- +## PENDING-142 — The open/closed criterion answers "does a REVIEWED header name this id?", not "is this item still awaiting the steward" +**Date:** 2026-08-17 +**Tag:** [HARDENING] +**Summary:** `governance_state()` / the wake digest compute openness from one signal — whether some `## REVIEWED-… — PENDING- —` header exists — and that signal is adjacent to the property claimed. Six items are misclassified in both directions, and the item count is right by coincidence. + +**Origin:** Task 1 of the jurist relay of 2026-08-17, which asked why PENDING-81 shows open against an AUTHORIZED REVIEWED-81, and why PENDING-76/-77 carry live `Awaiting:` lines but never appear. Both answers are below; the census found more than the three items asked about. + +**The criterion, exactly as computed** (`wake-digest.py:sec_pending` → `open_items` + `ruled_pendings`; `governance-mcp.py:t_state` delegates wholly to it). An item is OPEN iff: +1. it has an unfenced `## ` header in `PENDING.md`; **and** +2. that header contains no `CLOSED` and does not begin with `COMPLETED`; **and** +3. the id parsed by `PENDING-(\S+?)\s*—` is not in the set produced by `^## REVIEWED-\S+\s*—\s*PENDING-(\S+?)\s*—` over `REVIEWED.md`. + +So closure is signalled **only** by a REVIEWED *header* naming the PENDING id, or by a marker in the PENDING *header*. The criterion never reads the item's `**Awaiting:**` field, never reads any status field, and never reads the ruling's `**Decision:**`. It matches on **header-id presence**, not on subject and not on disposition. + +**Verified against the live files** (script: `census_open_criterion.py`, importing wake-digest's own functions rather than reimplementing them; 86 `##` items, 69 after the CLOSED/COMPLETED filter, 29 reported open; 118 REVIEWED entries, of which 74 name a PENDING id in the header and 44 do not): + +- **Class A — 2 items structurally unclosable.** `PENDING — ICP-19 Remit Expansion (Observer Problem)` (L88) and `PENDING — Fault Line 1 Response` (L99) have no `PENDING-` in their headers, so step 3's regex never matches and **no ruling of any kind can ever close them.** They will report open forever. Note the ICP-19 item is the gate on Observer Problem mechanism work. +- **Class B — 3 items falsely OPEN: PENDING-78, -81, -82.** `REVIEWED-78/-81/-82` exist, are dated 2026-07-28, are `**Decision:** AUTHORIZED`, and carry **titles identical to the PENDING items they rule**, but name the title instead of the id in their headers. REVIEWED-81 additionally names "PENDING-81" twice in its body and resolves that item's findings one by one. +- ⚠ **And the reason is recorded in the substrate.** `REVIEWED-78`'s own Notes say it was filed as a separate entry *precisely to satisfy the closure rule as it then stood*: "the closure rule in `wake-digest.py` matches a PENDING item to `REVIEWED-`, so a cross-numbered closure stated only in prose would leave PENDING-78 listed as open at every wake." The rule was later changed from number-matching to header-id-matching. **The change broke the three entries that had been deliberately authored to satisfy the old rule** — and `ruled_pendings`'s docstring records them as "like-numbered rulings … concerning other matters", which is the opposite of what the record says. They were like-numbered *on purpose*. +- **Class C — false CLOSED, the dangerous direction.** 7 items are suppressed under a ruling whose `**Decision:**` is not AUTHORIZED. Four are genuine closures (REJECTED, WITHDRAWN, NOT OBJECTED TO, DISPOSED). Three are **design gates**, which under the taxonomy precede steward authorization rather than replace it: PENDING-124 (REVIEWED-106), PENDING-128 (REVIEWED-111), and **PENDING-121 (REVIEWED-110), whose own Decision line reads "DESIGN GATE PASSED WITH CONDITIONS (1-4), then HELD OPEN"** — an item explicitly held open by its ruling and hidden by the tool. *Scope honesty: only PENDING-121 is certain. For -124 and -128 the rulings read closer to discharged, and I did not establish their true status; they are flagged as unestablished, not asserted as open.* +- **Class D — 39 suppressed items still carry an `**Awaiting:**` line.** Most were updated in-body ("RULED … REVIEWED-88 placed"); a substantial number were not, and read as live requests on the steward. This answers the relay's PENDING-76/-77 question: **both are correctly suppressed** (REVIEWED-76/-77 do name their ids; REVIEWED-76 is REJECTED, a genuine closure). Their `Awaiting:` lines are simply never retired. The field is not a status and cannot be read as one. + +⚠ **THE FINDING THAT GENERALIZES, and it is the third instance this week.** Removing 3 false-opens and adding back 3 false-closeds leaves **29 — the same number the tool reports.** The change proof cited in `ruled_pendings`'s docstring measured exactly that: a count delta (18 → 19 visible). **A count-based control cannot see a classification wrong in both directions by equal amounts.** The control's subject was the population size; the claim's subject was each item's disposition. Kin to the 2026-08-14 finding (the control tested transcription while the claim was an inference) and to REVIEWED-83 A1 (a control must sit at the layer the defect lives in). + +**Options:** +- **(a) Match on subject, not on header shape.** Resolve a PENDING↔REVIEWED pair by normalized title when the header carries no id, in addition to the current id match. Closes Class B. Cheap; risks joining two genuinely distinct items that share a title. +- **(b) Read the ruling's `**Decision:**` and treat design gates as non-closing.** Closes Class C. Requires enumerating which decision verbs close — itself a judgment, and the enumeration is the same "gate on the class, not the instances" trap unless it defaults to *not closed* on an unrecognized verb. +- **(c) Make closure explicit at the PENDING side** — a `**Status:**` line the tool reads, retired `Awaiting:` on ruling. Closes A, B, C and D at once, but requires touching ~40 existing items and makes the record depend on a field humans must maintain. +- **(d) Three-valued reporting.** OPEN · CLOSED · **UNDETERMINED** for any item whose disposition the criterion cannot establish (Class A by construction, Class B/C by disagreement between header-id and title/decision). Consistent with REVIEWED-104's ruled doctrine that a check whose subject can be absent may not be two-valued. + +**Recommendation: (d) as the frame, with (a) and (b) inside it.** (d) is the only option that makes the tool report its own limit rather than guessing, which is Constitutional Constraint #4 applied to the instrument that reports governance state. (a) and (b) then reduce how large the UNDETERMINED bucket is, rather than pretending it is empty. **(c) is not recommended alone** — a hand-maintained status field is exactly the surface that produced the 39 stale `Awaiting:` lines. + +⚠ **Whatever is built, the acceptance check may not be a count.** It must be a per-item disposition comparison against a hand-read answer key over all 69 filtered items — the defect above is invisible to any aggregate. + +**Files affected:** `~/dotfiles/scripts/wake-digest.py` (`sec_pending`, `ruled_pendings`, `open_items`), `~/dotfiles/scripts/governance-mcp.py` (`t_state` — consumer only), and `ruled_pendings`'s docstring, which carries a substrate-contradicted claim about REVIEWED-78/-81/-82 and should be corrected regardless of which option is taken. +**Awaiting:** Steward authorization. Nothing has been patched — the relay filing this scoped Task 1 to findings only, and the parsing logic is untouched. + +--- +## PENDING-142 — ADDENDUM 1: the selftest encodes the defect as intended behaviour +**Date:** 2026-08-17 +**Tag:** [HARDENING] +**Summary:** `wake-digest.py --selftest` contains a check asserting the Class-B behaviour is correct, and its fixture is one of the three items the defect hides. + +**The line** (`wake-digest.py`, selftest, "extractor controls"): +```python +chk("ruled_pendings ignores a ruling that names no PENDING", + ruled_pendings("## REVIEWED-82 — Read-only MCP server: eyes on the substrate") == set()) +``` +`REVIEWED-82` is not a neutral example. It is the real, AUTHORIZED ruling on PENDING-82 — one of the three items reported open because of exactly the behaviour this line certifies. **Whoever implements PENDING-142 will make this check fail, and the cheapest way to make a suite green is to change the test.** Flagged now so that the failure is read as the fix working, not as the fix breaking something. + +⚠ The same shape appeared a second time today, one function along. The unwrapped-session detector's real-substrate gate demanded that both verdicts occur across live transcripts, and **passed on 2026-08-17 while that detector was systematically broken** — a spread of outcomes is not evidence that any outcome is right. That gate has been demoted from an assertion to a printed note with its limit stated beside it (`[FIX]`, this session). + +**Recommendation:** whichever option is taken on the parent item, the selftest line above must be **re-derived from the property** ("does this ruling dispose of that item?") rather than from the check's own vocabulary ("does this string lack a `PENDING-N` token?"), using a fixture that is genuinely two unrelated documents rather than a real matched pair. +**Files affected:** `~/dotfiles/scripts/wake-digest.py` (selftest only). +**Awaiting:** Steward authorization, with the parent item. Nothing changed in `ruled_pendings` or its test. + +--- diff --git a/claude/memory/session-ledger-2026-08-17.md b/claude/memory/session-ledger-2026-08-17.md new file mode 100644 index 0000000..9b65efe --- /dev/null +++ b/claude/memory/session-ledger-2026-08-17.md @@ -0,0 +1,51 @@ +--- +name: session-ledger-2026-08-17 +description: "Practice-of-return ledger maintained by /symmetria — returns, open horizons, recalibrations, authorization moves, sub-agent dialogues, bypasses." +metadata: + node_type: memory + type: feedback + originSessionId: 81f817e9-4016-4867-ae16-a486f1e8fb46 + modified: 2026-08-17T12:34:44.862Z +--- + +# Session Ledger — 2026-08-17 + +## Returns + +- **2026-08-17T~12:15 — the digest's `PREVIOUS SESSION DID NOT WRAP` alarm, overridden a second + time.** Same false alarm the 08-14 ledger records overriding at ~09:40. Read the substrate, not + the derived label: `session-2026-08-14-…md` exists, is complete, and was extended twice today + (CODA, CODA 2). The banner also instructed the wake to "expect no record of what that session + did" — the record is the fullest of the week. Third firing, third false alarm; it is the + candidate task the steward left open for today. + +## What held + +- The wake read every claim it reported against the substrate rather than relaying the digest: + drift-check re-run live (4/4 clean, 2 amendments seen), `~/dotfiles` git status re-run (clean and + pushed), the wrap record and Symmetria ledger opened rather than summarized from the banner. + +## Open horizons + +- **Steward direction: tooling, not governance, today.** Three candidates, `wrap_inside` fix + recommended; S2 ladder batch is BLOCKED by PENDING-141 and must not execute; engine retrieval / + PENDING-97 is the day-sized one. +- **Hypothesis, not yet verified** — beyond wrapped-then-continued, `sec_unwrapped` may select the + *wrong transcript* (`now - mtime > 60` skips a just-quiet session) and `wrap_records()` mtimes + are *mutable*, so any later edit to a session memory file moves it out of its own session's span. + If the fix is taken up, verify both before designing the third value. +- No Symmetria ledger was opened for the earlier 2026-08-17 session (the CODA / PENDING-140 / -141 + sitting). Noted, not chased. + +## Confidence to recalibrate + +- Holding the inherited literal question in front: *was the control's SUBJECT the claim it was + cited as verifying, or an adjacent property?* If today's task is the detector fix, its selftest + is precisely where that shape recurs — a control over the *detector's* inputs is not a control + over the *verdict's* truth. + +## Authorization moves + +## Sub-agent dialogues + +## Bypasses