Repository navigation
Wave 11: guard registry, privacy guard on GitHub writes, new-row flags in review_checks - #2157
Merged
Merged
Conversation
…s in review_checks Guard registry (refs #1592): - Every guard rail Perun ships has one row in scripts/guard-registry.tsv: id, owner role (never a person), reason, review-by date and an optional fire log path. A guard is a hook a shipped settings template runs, a git hook install.sh writes, or a ci-gates.sh subcommand. - ci-gates.sh guard-registry fails closed on a guard with no row, an empty reason, an owner that is not a lowercase role slug, a review-by that is not a real calendar day, a duplicate or over-wide row, a row for a guard that no longer ships, an empty scan, and a cmd_ function whose dispatcher line the scan cannot read. A past review-by never fails it. - guard-registry --report [--days N] is read-only: rows past review-by, and logged guards with no dated fire line in the last N days. A guard with no fire log, or an empty, rotated or undated one, is "unknown", never "zero fires". The report never edits or deletes a row. - The header-parity test pins each hook row's owner, reason and review date to its script's `# rail:` line. Evil-twin record: keeping both the headers and the TSV can drift; if they still disagree after about 30 days, retire one. Privacy guard (new hook, agentic-delivery/privacy_guard.py): - A PreToolUse(Bash) hook runs the repo's banlist (.banlist.txt, then the gitignored .banlist.local.txt at the git top-level; a linked worktree reads the main checkout's local file) over the title and body of every gh pr|issue|release create|edit|comment and every curl or gh api write to repos/<owner>/<repo>/pulls or /issues in the command. A hit exits 2 with a reason that names the title or the body line and the pattern's number, never the matched text. No repo, no banlist, no title or body, an unreadable body file (a readable title is still checked), bad input or any error allows; PERUN_PRIVACY_GUARD=off opts out. - Scope: the banlist covers writes into the session's own repository, into protocol/perun and into any repository under another owner. A write whose explicit target (read from that write's own flags, never from its title, body or a later command) is a different repository under the session origin's owner is not scanned, so an audit PR may name the repo it is filed in. A write naming several repositories is skipped only when every one is a sibling. With no usable origin every write is scanned. Known residuals, documented in the module: a public sibling repository in the session's own organisation is not scanned, a write into another owner's private repository is still scanned (a private target cannot be told from a public one without a network call), and a target set only by GH_REPO is not seen. - `-f`/`--raw-field` text is scanned as written even when it starts with `@`; only `-F`/`--field` reads `@FILE`, and a failed read scans the literal text. - A body file the command writes itself (`> F`, `>> F`, `tee F`) is read from the heredoc that feeds that file, not from the stale or missing file. - Own-repository rule: a write into Perun's public repository from another repository's session is denied when its title or body names the session's repository (owner/name, or the bare name when distinctive), because a project's banlist does not list its own name. The reason gives the location only. - comms_guard.py extraction, shared by import: `-F body=@FILE` reads @file as one shell word, and `_flags` masks quoted strings and heredoc bodies so a flag-like word inside a title or body is not taken for a flag. - Wired into the operating-layer template, perun_doctor HOOK_SCRIPTS, a guard-registry row, a `# rail:` header and a changelog fragment. Unscanned forms (stdin pipes, merge and review, --fill, text built from a shell variable) are listed in the module docstring. Review (review_checks.sh): - In diff mode every JSON row carries "new": true|false, true when the row's file and line sit on a line BASE...HEAD adds (rename-aware `git diff -U0` with pinned flags, so a reviewer's git config cannot change which lines count). Line 0 and file-level rows are false; --full and --history omit the key; no row is dropped. stderr gains "review_checks: N of M rows are on lines this diff adds". - references/method-situational.md: verify new rows first, and report a pre-existing row in a touched file only when the diff makes it reachable or worse. Index: the agentic-delivery script-lookup cap in scripts/test_skill_index_split.py rises by 200 bytes for the new privacy_guard row (core plus lazy index measured at 22303 bytes). size-budget-raise: .claude/skills/deep-code-review/references/method-situational.md 44396→44702 one sentence on the new flag: verify new rows first, report a pre-existing row only when the diff makes it reachable or worse Tests: 259/259 in the 9 suites affected by the last two commits, re-run at the final head (audit-pr-body 46, comms-quality 51, conflict-free-prs 23, guard-registry 92, privacy-guard 40, skill-index-split 7). Earlier assembly runs: the suites affected by the first commits were green; 47 of the 48 suites affected by the review round were green and the 48th (the index cap) is fixed here. The full set runs in CI. 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 11: three changes; the commit message has detail.
What changes
ci-gates.sh guard-registryfails closed on a missing or malformed row; read-only--reportmarks a guard with no dated fire logunknown.ghor API write whose title or body matches the repo banlist, or that names the session's repository in a write to Perun. Writes into a same-owner sibling repo are not scanned, so an audit PR can name its repo. Reasons give location and pattern number only; it fails open and has an opt-out.review_checks.shdiff mode marks each row"new": true|false, so a reviewer checks new rows first. No row is dropped.Verification
🤖 Generated with Claude Code