Skip to content

land the limits stack on main: #44, #45, #46 (merged into their bases before retarget) - #52

Merged
githubscum merged 6 commits into
mainfrom
lotor-lane/limit-65-pin-body
Sep 7, 2026
Merged

land the limits stack on main: #44, #45, #46 (merged into their bases before retarget)#52
githubscum merged 6 commits into
mainfrom
lotor-lane/limit-65-pin-body

Conversation

@githubscum

Copy link
Copy Markdown
Owner

PRs #44, #45 and #46 were stacked and merged in one pass; GitHub had not yet retargeted them to main when the merge ran, so they landed in their base branches. This PR carries limits 63 to 70 and the entry-66 amendment onto main. No new content.

🤖 Generated with Claude Code

githubscum and others added 6 commits September 2, 2026 00:45
…deciders

Every gate, warn, grant and egress receipt carries a matcher version, and it
is the field a reader uses to ask whether two decisions were made by the same
rules. It hashes thirteen top-level functions plus the two rule tables.
Function.toString returns a function's own source and nothing it calls, so the
helpers that actually decide self-mod are outside it: the protected-path list,
both self-mod matchers, the path normalizer, the segment matcher, the brace
expander and the prose strippers. The dispatcher that IS hashed only names the
matchers it calls.

Change the protected list or the way a path is folded before matching, and the
gate stops a different set of actions while the stamp stays byte-identical.
The silence runs the wrong way: a matcher weakened between two runs keeps
stamping the old, stronger version. Enforcement is unaffected; the trace
misdescribes it, which is why this is filed as a witness defect.

Measured, not read off the source. The new test asserts the absence directly
against the hashed inputs, with controls asserting the hashed bodies are
present so the block cannot pass vacuously. Stamp on this build:
matcher/1 95291ff6385151ca. The stamp was introduced 2026-08-09 (b1b7bf8);
the protected list gained an entry on 2026-08-23 and the version did not move.

The repair is core and is not attempted here: name the helpers in parts and
bump the schema marker to matcher/2, since the hashing method changes and a
value moving on its own would be indistinguishable from a rule edit.

Suite 962 pass / 0 fail (8 new).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…record

Following limit 63's stated residual ("behavior that reaches the decision
from outside the policy module would remain unstamped") to where it leads,
and finding that the instrument which closes it is already built.

Two code identities exist. matcherVersionHash() covers named functions in
src/policy/index.js and is on every receipt. computeSourceDigest() covers
all 50 .js files under src/ and bin/ - including src/gate, src/grant,
src/chain, src/store and bin/hook-pre-tool-use.js - and is attached only to
MCP tool responses, which are discarded when the call returns.

So the ephemeral artifact carries the strong identity and the permanent one
carries the weak one. Change the gate or the hooks and every receipt after
the change is byte-comparable with every receipt before it.

Measured: build digest 47ed7876d2652e68 over 50 files / 522,651 bytes;
matcher stamp matcher/1 95291ff6385151ca; exactly two consumers of the
digest in the tree, neither of which writes to the chain.

Ships KNOWN-LIMITS 64 plus a 4-assertion test. Every absence claim is
paired with a control (the same file IS asserted to carry matcherHash, and
the MCP server IS asserted to carry the build stamp) so the block cannot
pass vacuously. Suite 966/966, up from 962.

The repair touches src/gate and bin/hook-* and therefore queues for a
signing sitting rather than riding along with this disclosure.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…s in

The KNOWN-LIMITS pin names the last commit that touched the source tree, on
purpose, so that stamping (which edits only the log) cannot invalidate itself.
The consequence was not carried through: a commit that edits only the log does
not move that commit either, so the check cannot see it.

Measured on a synthetic tree, with the shipped writePin/checkPin and the commit
resolution reproduced verbatim. Appending an entry, deleting an entry, and
reversing an existing claim were each reported "current", exit 0. Only a source
change was reported "diverged". The checker does not merely fail to complain
about an edited log; it certifies it.

Adds the entry and five characterization tests that hold the gap in the suite
rather than only in prose. They are written to fail when the repair lands, which
is the prompt to rewrite them as the assertions for the fixed behaviour.

The repair is drafted and gated: add a body digest to the pin, covering the file
with the pin block removed so stamping stays stable, and report a matching
commit with a mismatched digest as a third status. The gate refused it as a
self-modification of the source tree, correctly, so it queues for a signing
sitting rather than riding along here.

Suite 971 pass / 0 fail.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…that do exist disagree

Four limits found 2026-09-02 on a live three-child concurrent dispatch, filed
the day they were found per the confession-log rule.

66: subagent tool use produces zero chain rows while the parent's calls in the
same minutes produce one every time. A hole in enforcement under a herded
posture, not only in bookkeeping.
67: the harness's reported per-child token figure disagrees with the child's own
transcript by ~7,400 on two of three calls. Price from the transcript.
68: the reader that found the children globs an undocumented harness path with
no schema check across 91 lines, so its failure mode is a false zero.
69: no dollar figure is reported anywhere; every one is computed against a price
table dated four days earlier, so the date has to travel with the number.

Tests: 971 pass / 0 fail, including the read-only numbering test, which now
reads 1..69 contiguous.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…epending on who runs it

Entry 66 shipped at its declared floor: it confirmed the witness records nothing
a subagent does, and explicitly said reachability by an honest agent was NOT
established. That probe has now run. Every subagent transcript on this machine
(3,962 tool calls, 1,073 child transcripts, 104 parent sessions, six weeks) was
replayed through the repo's own matcher under an all-gate policy. 519 calls
(13.1%) would have gated the parent, in 38.5% of parent sessions, 377 of them
after the gate was armed.

Entry 66 comes off its floor with those numbers. The asymmetry the measurement
exposes is filed as its own entry 70: the protected-path rules are enforced
against the parent's calls and structurally unenforced against a child's.

Both blocks carry the caveat rather than the headline: the nine core-file edits
found inside child sessions all predate the arming of the gate by one day and
are not evidence that anyone walked around an armed gate.

Suite 971 pass / 0 fail.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nt-blindspot

limits 66-69: the subagent path leaves no chain row, and the numbers that do exist disagree
@githubscum
githubscum merged commit 57fa213 into main Sep 7, 2026
githubscum added a commit that referenced this pull request Sep 7, 2026
…limits stack landed

Limits 62 to 70 landed on main this morning (#43 to #46 via #52). The chapters
entry moves to 71; CHANGELOG, receipt-coverage and both proposals cite 71.
The staged-CLI proposal no longer quotes a local user path.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant