Repository navigation
Wave 12: route-auth lead-finder, install update hygiene, heavy lease in a sandbox, "new": null for dirty files - #2159
Merged
Merged
Conversation
…in a sandbox, "new": null for dirty files Review (deep-code-review): - scripts/route_auth_map.py DIR: a report-only, stdlib-only lead-finder for missing authentication (CWE-306/862). It inventories HTTP handlers (Next.js app routes, pages/api, "use server" exports, Express, Router, Hono and Fastify calls, FastAPI and Flask decorators) and prints one row per handler with the auth evidence it found. A mutating handler with no evidence is HIGH, a GET with none is INFO. A Next middleware or proxy whose matcher covers the route counts as evidence when it names an identity check or can answer 401/403, so a custom-named session gate counts. A quoted /path literal in that file reads as an allow-list entry (a trailing (.*), /* or /:name* is dropped first), unless it is a prefix of a matcher entry or sits in the condition of an if whose body can refuse. Known ceilings: conditions are not evaluated; a scope check written as a ternary, an && chain, a switch case or a redirect-only body reads as an exemption; regex, computed or imported allow-lists are not read; and a 401/403 that checks no identity (CSRF, geo, rate limit) also counts. - review_checks.sh --full runs it as tool route-auth (HIGH rows as rule missing-auth); references/security-appsec.md routes it from the Anonymous GET sweep. - review_checks.sh diff mode: "new" is null (unknown) for every row in a file that differs from HEAD in the working tree. The file list comes from a lock-free git status that leaves .git/index alone; a failed read omits the key and says so on stderr. method-situational.md documents the third value. Install (install.sh, perun_marker.py, vendor_drift.py): - A version bump of an unedited install leaves no skill backup and no .new copies: the fresh backup is dropped when it equals the previous install recorded in the marker (a backup holding any entry that install did not write is kept), an unedited slash command is refreshed in place, and an existing .new / .new-N that already holds the shipped file stops a duplicate. Install deletes no file it did not create in that run, so .new files already on disk stay. Edited, pre-Perun and differing files are never touched. - The install summary's Generated list scans only the paths install writes. It used to scan whole host dirs for newer files, so under a home target it also listed session transcripts, todos and other files that other processes wrote during the run. Known ceiling: a file another process writes inside one of those paths during the run (a rewritten settings.local.json, a new file in .claude/commands) still lists. - vendor_drift.py compares an "(install placeholder)" stub with the docs file install.sh copies over it, so a clean install no longer reads as drift; a missing docs file fails closed. Delivery (perun_policy.py, stage_run.py): - On macOS, the heavy-job throttle and the exclusive train lease work inside a Claude Code sandbox. heavy-acquire could not write its lease under the read-only user cache dir, so sandboxed scanners ran unleased and no other session could count them. Writers now use the first writable of the usual dir and a per-user fallback under the sandbox temp dir (only a real directory owned by the user with mode 0700, with no symlinked or foreign directory below it), and every reader, including the heavy_gate.py hook, checks both. PERUN_HEAVY_DIR still pins one dir. Other platforms keep the 1.628.0 behaviour. - Readers open lease files without blocking and skip anything that is not a regular file, so a planted FIFO cannot hang the hook. stage_run only unlinks a stale lease outside the usual dir and never signals a process group named there. - Known ceiling: anything running in the sandbox can write the fallback, so it can forge or block a lease, or stall another sandboxed writer, and so delay or deny heavy commands. The same user's sessions already share that temp dir. Tests: 82/82 affected suite sections (run-ci-tests.sh --affected 6eb3f03, run before the install-summary test fold, which changes only an install.sh comment, that test and a changelog line); test-install-hygiene.sh 15/15 on the final tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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 free
to 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.
Wave 12: four changes; the commit message has the detail and known limits.
What changes
route_auth_map.pylists HTTP handlers and their auth evidence; a mutating handler with none is HIGH. It runs inreview_checks.sh --full. Report-only: silence proves nothing..newcopies, the summary scans only the paths install writes, and install deletes nothing it did not create."new": null.Verification
🤖 Generated with Claude Code