[HARDENING] governance-mcp: the jurist can now read the constitution it design-gates (PENDING-86 a)
Steward-authorized 2026-08-05, on the jurist's own request while unable to close
PENDING-99's Q2 — a question that turns on the chamber constitution's vocabulary
(§II.3's "inline anchor marker", §V's marker exclusion), which governance_read
did not expose. Third recorded instance on PENDING-86: the constitution, the
skill files, contamination-problem.md.
Adds two keys to the existing enum: `chamber-spec`, `graduation-spec`. No new
tool, no path argument, no traversal surface — the domain stays enumerable and
every refusal control still passes.
⚠ THE NON-OBVIOUS PART. Reachability of the KEY is not reachability of the
CLAUSE. This file's operative sections begin around line 354; the ~330 lines
above them are SUPERSEDED version headers kept as the amendment trail. A jurist
reading with the default limit=400 would land squarely in obsoleted text and
could rule on superseded clauses — the new access CAUSING the misruling it
exists to prevent. So the trap is disclosed on the key's own description, at the
point of use, and two controls pin it:
- the §V inline-anchor clause and the §II.3 marker constraint are both
reachable in ONE paged call (offset=350, limit=2000) — the actual Q2 text
- NEGATIVE CONTROL: a first-page read does land in the "(obsoleted)" region,
proving the trap is real rather than hypothetical
Selftest 29 → 35 controls, 0 fail. Live stdio round-trip confirms the §V clause
arrives verbatim through governance_read.
⚠ Requires a Claude.app restart: the running server process carries the old
code and will not show the new keys until respawned.
Option (d) — keyword search across PENDING/PENDING-archive/REVIEWED — is NOT in
this change and remains open on PENDING-86. It is a new tool surface, not two
enum entries, and the jurist asked for (a)+(d) together.
Refs PENDING-86, PENDING-99 Q2, PENDING-82.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AB3Kryoy6b1pm2Nz1DYdLh
This commit is contained in:
co-authored by
Claude Opus 5
parent
40a6a2aaf8
commit
5cd5faf66e
@@ -69,6 +69,20 @@ FILES = {
|
|||||||
"claude-md": (os.path.join(D, "CLAUDE.md"), "the executor's governing document"),
|
"claude-md": (os.path.join(D, "CLAUDE.md"), "the executor's governing document"),
|
||||||
"memory-index": (os.path.join(wd.MEM, "MEMORY.md"), "wake-loaded memory index"),
|
"memory-index": (os.path.join(wd.MEM, "MEMORY.md"), "wake-loaded memory index"),
|
||||||
"app-brief": (wd.BRIEF_PATH, "last generated .app Standing Context block"),
|
"app-brief": (wd.BRIEF_PATH, "last generated .app Standing Context block"),
|
||||||
|
# PENDING-86 option (a), steward-authorized 2026-08-05. The jurist design-gates
|
||||||
|
# constitutional supersessions of documents it could not read; three distinct
|
||||||
|
# instances are recorded on that item. These two are the ones the loop actually
|
||||||
|
# rules on. Read-only, keyed, no path argument — the enum design is unchanged.
|
||||||
|
"chamber-spec": (os.path.join(HOME, "_Dev", "chamber-library", "docs",
|
||||||
|
"chamber-library-specification.md"),
|
||||||
|
"the chamber library constitution — ⚠ the OPERATIVE version header is "
|
||||||
|
"at the top, but roughly the next 330 lines are SUPERSEDED version "
|
||||||
|
"headers kept as the amendment trail; the operative sections start at "
|
||||||
|
"'## 0. What this document is'. Page past them (offset≈350) or you will "
|
||||||
|
"be reading obsoleted text"),
|
||||||
|
"graduation-spec": (os.path.join(HOME, "_Dev", "chamber-library", "_curation",
|
||||||
|
"graduation-spec.yaml"),
|
||||||
|
"the constitution's machine-readable convention-data + gate-list"),
|
||||||
}
|
}
|
||||||
REPOS = wd.REPOS
|
REPOS = wd.REPOS
|
||||||
|
|
||||||
@@ -351,6 +365,27 @@ def selftest():
|
|||||||
t_read({"file": "../../.ssh/id_rsa"}).startswith("ERROR: unknown file key"))
|
t_read({"file": "../../.ssh/id_rsa"}).startswith("ERROR: unknown file key"))
|
||||||
chk("governance_read ACCEPTS a listed key [positive control for the refusal above]",
|
chk("governance_read ACCEPTS a listed key [positive control for the refusal above]",
|
||||||
t_read({"file": "pending"}).startswith("[pending —"))
|
t_read({"file": "pending"}).startswith("[pending —"))
|
||||||
|
|
||||||
|
print("\nPENDING-86 (a) — the documents the jurist design-gates are now reachable:")
|
||||||
|
chk("chamber-spec key reads",
|
||||||
|
t_read({"file": "chamber-spec"}).startswith("[chamber-spec —"))
|
||||||
|
chk("graduation-spec key reads",
|
||||||
|
t_read({"file": "graduation-spec"}).startswith("[graduation-spec —"))
|
||||||
|
# Reachability of the KEY is not reachability of the CLAUSE. These two controls
|
||||||
|
# test the actual thing the item exists for: the §II.3 / §V text a Q2-shaped
|
||||||
|
# ruling turns on. A key that opens onto 330 lines of superseded headers would
|
||||||
|
# pass the two checks above and still leave the gap wide open.
|
||||||
|
_spec_deep = t_read({"file": "chamber-spec", "offset": 350, "limit": 2000})
|
||||||
|
chk("§V's inline-anchor clause is reachable in one paged call [the Q2 clause]",
|
||||||
|
"is content-for-the-reader but is **not a prose word**" in _spec_deep)
|
||||||
|
chk("§II.3's marker constraint is reachable in the same call [the Q2 clause]",
|
||||||
|
"must not corrupt the" in _spec_deep and "prose-word-identity check under §V" in _spec_deep)
|
||||||
|
chk("the superseded-header trap is disclosed on the key itself [it would cause the "
|
||||||
|
"misruling this access exists to prevent]",
|
||||||
|
"SUPERSEDED version" in FILES["chamber-spec"][1])
|
||||||
|
chk("a first-page read lands in the SUPERSEDED region [negative control: proves the "
|
||||||
|
"trap is real, not hypothetical]",
|
||||||
|
"(obsoleted)" in t_read({"file": "chamber-spec", "limit": 300}))
|
||||||
chk("repo_activity refuses an unlisted repo",
|
chk("repo_activity refuses an unlisted repo",
|
||||||
t_repo({"repo": "/etc"}).startswith("ERROR: unknown repo"))
|
t_repo({"repo": "/etc"}).startswith("ERROR: unknown repo"))
|
||||||
chk("repo_activity ACCEPTS a listed repo [positive control]",
|
chk("repo_activity ACCEPTS a listed repo [positive control]",
|
||||||
|
|||||||
Reference in New Issue
Block a user