limit 62: an equivalent path spelling walks around the self-mod gate - #43
Open
githubscum wants to merge 1 commit into
Open
limit 62: an equivalent path spelling walks around the self-mod gate#43githubscum wants to merge 1 commit into
githubscum wants to merge 1 commit into
Conversation
Found by running fourteen spellings through the shipped matcher, not by reading it. normalizePath folds backslashes and case and stops there, so a doubled separator or a dot segment contains no protected fragment contiguously and is not gated, while opening exactly the same file. Seven misses, five controls gated. The Edit half is the half that matters: Edit carries a file_path, and limit 34 already says a path can be proven contained. This is what that deferral costs. Ships the confession and a tripwire that asserts the current, defective behaviour with the plain spellings beside it as controls. When the matcher is fixed the block fails; the repair is to invert it and amend entry 62, never to delete it. The fix is src/policy and non-delegable core. It was attempted and the gate refused it unsigned, correctly. The bypass proved here was not used to land the fix. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Sep 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
WO (lotor-lane run 10): probe the self-mod matcher for spelling escapes, the way runs 6, 8 and 9 found their defects — by executing it, not reading it.
The finding
normalizePath()converts backslashes, lowercases, strips a trailing slash. That is all. The fragment list is then matched as a plain substring —cmdNorm.includes(frag)for commands,pathContainsFragment()forEdit. A doubled separator or a.segment defeats both and changes nothing about which file opens.Fourteen spellings through the shipped matcher: five controls gated, seven misses.
<repo>/src/policy/index.js<repo>/src//policy/index.js<repo>/src/./policy/index.js<repo>/src/./chain/index.js<repo>/bin//charter.js<repo>/./bin/./charter.jsThe right column is measured, not argued: the test writes a canary file and reads it back through all three spellings.
The
Edithalf is the one that matters.src/policy,src/chain,src/store,src/grantand every script inbin/stay atgatein every mode including loose. This walks around that with one extra character, through the tool an agent actually uses to change code.Not a new class. Limit 22 was tilde/
$HOME. LOTOR-C2 was brace expansion. This is the third spelling escape in the same matcher, and all three were found by executing it rather than reading it.What this PR ships
src/policy./index.jsis ungated; Windows strips trailing dots, butexistsSyncrefused that spelling here, so whether a real write lands is not proven), and a caution for whoever writes the fix:normalizePathis applied to whole command strings, so collapsing/+globally also rewriteshttps://xand needs its blast radius checked across every caller.test/policy-selfmod-separator-spellings.test.js— a tripwire, 13 assertions. It asserts the current, defective behaviour, with the plain spellings beside it as controls so the block cannot pass by the matcher dying. When the matcher is fixed, this file fails. The repair is to invert the assertions and amend entry 62 in the same change, never to delete the block.Tested
npm teston this branch: 954 pass / 0 fail (941 onmainplus the 13 new). The new file alone: 13/13.Not fixed here, and why
The fix is
normalizePathinsrc/policy— non-delegable core. It was attempted first and the gate refused it unsigned. Correct behaviour, and worth stating plainly: the bypass proved in this PR was not used to land the fix for the bypass. Queued for a signing sitting alongside limits 35 and 36.What a reviewer should doubt
Edit-side misses have no such defence.REPOin the test is derived fromimport.meta.urlwith a Windows drive-letter fixup. It only builds path strings for the matcher and never touches the repo, but it is the least portable line in the file./+and dropping./segments. It does not claim that exhausts the spelling space:..traversal is gated today only when the traversed-through directory happens to be protected too.🤖 Generated with Claude Code