[FIX] PENDING-151 step 2: the jurist can reach the pairs

governance_pair serves both arms of one enumerated v1 Chamber pair, verbatim, and
chamber-v1-diff joins the governance_read whitelist. Steward-authorized.

⚠ STATICALLY ENUMERATED RATHER THAN DIRECTORY-WALKED, and the distinction is the point.
t_read's design property is 'no path argument'; its SUBSTANCE is that the reachable set is
reviewed rather than matched. Walking the archive at import would preserve the letter — the
caller still passes no path — and lose the substance, because a file dropped in later would
become jurist-readable with nobody having looked at it. The 2025 archive is a closed record,
so static enumeration costs nothing and keeps the guarantee.

The unit served is the PAIR, not the file, because that is the unit of step 2's question:
neither arm alone answers whether a divergence is content or register. Derived from the
consumer rather than from how the files sit on disk.

All three filename defects reproduced exactly and NOT repaired — leading space, doubled
extension, trailing space in a directory name. A reader sees the archive, not a tidied copy.

The tool's own header states the step-2 question and the length confound, so a reader
arriving through it cannot receive the material without the caveat.

⚠ Two raw files carry stray header lines (a filename, and '[gpt reply]'). Real content, not
pointers; ~3 tokens each into term extraction. Declared, not stripped — stripping would edit
the record.

⚠ chamber-sessions-private: first non-governance material on this surface. Noted in the code
because the surface exists to be bounded.

The instrument's own AST read-only controls still pass: no mutating call, git read-only.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J6hZXNYSxEfZseBGTni4sf
This commit is contained in:
David F Glidden
2026-08-25 19:21:55 +02:00
co-authored by Claude Opus 5
parent 0b98c751ff
commit 73922e1bc7
2 changed files with 113 additions and 1 deletions
+20 -1
View File
@@ -4449,7 +4449,26 @@ extractor is a capitalisation heuristic, not a named-entity recogniser. It will
lower-case entities and admit ordinary capitalised nouns. Counts are indicative; the lists
are the evidence.
**Files affected:** `scripts/chamber-v1-formation-diff.py` (new), the output document (new).
#### ⚠ Two raw files carry a stray header line, declared rather than stripped
`[standard]claude-raw.txt.txt` (Savall) begins with the literal line `[standard]claude-raw.txt`,
and `[standard]gpt-raw.txt` begins with `[gpt reply]`. Both are 2025 artifacts. They are
**real content files** — 1,211 and 682 words — not pointers. The header lines contribute
roughly three tokens each to term extraction. **Not stripped:** removing them would edit the
record, and the diff is supposed to read what is there. Declared because a step-2 reader will
see them in the verbatim text and should know they are archive noise, not output.
#### The jurist can now reach both, as of 2026-08-25
`governance-mcp.py` gains `governance_pair` — both arms of one enumerated pair, verbatim — and
`chamber-v1-diff` joins the `governance_read` whitelist. **Steward-authorized.** The pairs are
**statically enumerated, not directory-walked:** `t_read`'s design property is *"no path
argument"*, and its substance is that the reachable set is REVIEWED rather than matched. A
walk would keep the letter and lose that. ⚠ **Requires a Claude Desktop restart** — MCP
servers load at app start, so until then the tool is absent rather than empty.
**Files affected:** `scripts/chamber-v1-formation-diff.py` (new), the output document (new),
`scripts/governance-mcp.py` (pair reader + one whitelist entry).
Archive **untouched and unrenamed** — filename defects preserved as the 2025 record.
**Awaiting:** a **non-executor** reader for step 2.
+93
View File
@@ -141,6 +141,11 @@ FILES = {
"the fr fixture's CITATION TEXTS — the quoted strings "
"themselves. This is the file that answers 'whose "
"proposition does the claim assert?'"),
"chamber-v1-diff": (os.path.expanduser(
"~/dotfiles/claude/governance/chamber-v1-formation-diff-2026-08-25.md"),
"PENDING-151 STEP 1 — the mechanical formation diff over the 9 v1 Chamber pairs. "
"Counts and word lists only. ⚠ It renders NO verdict: whether a divergence is "
"content or register is step 2, and the executor is barred from it."),
}
REPOS = wd.REPOS
@@ -345,6 +350,84 @@ def t_repo(args):
return f"[{name}]\n\n{status}\n\nLAST {n} COMMITS\n{log}"
# ── PENDING-151 step 2 ────────────────────────────────────────────────────────────
# The step-2 judge reads a PAIR, not a file: the question is whether two arms diverge in
# content or only in register, and neither arm answers it alone. So the unit served here
# is the unit of the work — derived from the consumer, not from how the files happen to
# sit on disk.
#
# ⚠ STATICALLY ENUMERATED, and deliberately. `t_read`'s design property is "no path
# argument", and the point of it is that the reachable set is REVIEWED rather than
# matched. Walking the directory at import would preserve the letter (the caller still
# passes no path) and lose the substance: a file dropped into the archive would become
# jurist-readable with nobody having looked at it. The 2025 archive is a closed record.
#
# ⚠ The three filename defects are reproduced EXACTLY and are not repaired: a leading
# space in one claude arm, a doubled extension in another, a trailing space in a
# directory name. PENDING-151: they are the 2025 record and renaming is a separate [FIX]
# the steward owns. A reader who sees them here is seeing the archive, not a tidied copy.
#
# ⚠ This is `chamber-sessions-private`. Steward-authorized 2026-08-25 to reach the jurist
# for step 2; noted because it is the first non-governance, non-public material on this
# surface, and the surface exists to be bounded.
V1_ROOT = os.path.expanduser(
"~/_Dev/animal-davidglidden-eu/chamber-sessions-private/2025")
PAIRS = {
"06-14-owl-emblem/shadow":
("2025-06-14-owl-emblem/[shadow]gpt-raw.txt",
"2025-06-14-owl-emblem/ [shadow]claude-raw.txt"),
"06-14-owl-emblem/standard":
("2025-06-14-owl-emblem/[standard]gpt-raw.txt",
"2025-06-14-owl-emblem/[standard]claude-raw.txt"),
"06-16-first-submission-first-light/first-light":
("2025-06-16-first-submission-first-light/[first-light]gpt-raw.txt",
"2025-06-16-first-submission-first-light/[first-light]claude-raw.txt"),
"06-17-the-ethics-of-the-reply/shadow":
("2025-06-17-The Ethics of the Reply /[shadow]gpt-raw.txt",
"2025-06-17-The Ethics of the Reply /[shadow]claude-raw.txt"),
"06-17-the-ethics-of-the-reply/standard":
("2025-06-17-The Ethics of the Reply /[standard]gpt-raw.txt",
"2025-06-17-The Ethics of the Reply /[standard]claude-raw.txt"),
"06-19-savall-prometheus-21/standard":
("2025-06-19-Savall-Prometheus-21/[standard]gpt-raw.txt",
"2025-06-19-Savall-Prometheus-21/[standard]claude-raw.txt.txt"),
"07-01-marginalia/standard":
("2025-07-01-marginalia/[standard]gpt-raw.txt",
"2025-07-01-marginalia/[standard]claude-raw.txt"),
"07-11-the-ethics-of-the-reply-part-ii/shadow":
("2025-07-11-the-ethics-of-the-reply-part-ii/[shadow]gpt-raw.txt",
"2025-07-11-the-ethics-of-the-reply-part-ii/[shadow]claude-raw.txt"),
"07-11-the-ethics-of-the-reply-part-ii/standard":
("2025-07-11-the-ethics-of-the-reply-part-ii/[standard]gpt-raw.txt",
"2025-07-11-the-ethics-of-the-reply-part-ii/[standard]claude-raw.txt"),
}
def t_pair(args):
"""Both arms of one enumerated v1 Chamber pair, verbatim. No path argument."""
key = (args.get("pair") or "").strip()
if key not in PAIRS:
return ("ERROR: unknown pair %r. Allowed: %s"
% (key, ", ".join(sorted(PAIRS))))
g_rel, c_rel = PAIRS[key]
out = [f"[v1 Chamber pair — {key} — verbatim, both arms]",
"",
"⚠ STEP 2 IS THE QUESTION THIS SERVES: does a divergence carry DIFFERENT",
"CONTENT, or the SAME CONTENT IN A DIFFERENT REGISTER? PENDING-151 reserves it",
"to the jurist or steward: the executor is one of the two formations compared.",
"⚠ The Claude arm is longer in 9 of 9 pairs (1.41x-3.40x). Distinctive-term",
"counts rise with length by construction; see chamber-v1-diff for the",
"length-normalised columns and their declared limits.",
""]
for arm, rel in (("GPT", g_rel), ("CLAUDE", c_rel)):
text = read(os.path.join(V1_ROOT, rel))
out += [f"───────── {arm} arm ── {rel}", ""]
out += [text if text is not None
else f"UNREADABLE: {rel} is absent or unreadable at this time.", ""]
return "\n".join(out)
TOOLS = [
("governance_state", t_state,
"Current governance state, computed live: every open authorization item with its "
@@ -366,6 +449,16 @@ TOOLS = [
"offset": {"type": "integer", "description": "0-based first line (default 0)."},
"limit": {"type": "integer", "description": "Lines to return, max 2000 (default 400)."}},
"required": ["file"]}),
("governance_pair", t_pair,
"Both arms of one v1 Chamber formation pair (2025 GPT and 2025 Claude reading the "
"same submitted text), verbatim, chosen by key. This is PENDING-151 step 2's "
"material: the executor may run the mechanical diff but MAY NOT judge whether a "
"divergence is content or register, being one of the two formations compared. "
"Read chamber-v1-diff first for the counts and their length confound.",
{"type": "object", "properties": {
"pair": {"type": "string", "enum": sorted(PAIRS),
"description": "Which pair, as session/protocol."}},
"required": ["pair"]}),
("governance_search", t_search,
"Keyword search across PENDING.md, PENDING-archive.md and REVIEWED.md. Use this to "
"DISCOVER a relevant prior item or ruling whose id you do not already know — the case "