fix(disk-hygiene): name the failing token and flag-order rule in the engine-gate denial - #5582
Conversation
… gated shapes The engine-gate denial now says which word of the denied command broke which rule, states the required-flag order, and states which mention shapes are gated and which read-only forms work. Text only: the classifier, the grammar walk and the allow path are unchanged. Refs #5519 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t and advertised read-only forms Refs #5519 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…engine-gate denial Bump disk-hygiene to 0.29.3 and record the denial-text change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n the gate denial The engine-gate denial named the wrong token for a mention with an engine-path operand (it blamed the command word as "not this hook's Python") and listed every operator class for an unparsable command. - An engine operand of a command that is not the hook's Python is now named first, saying whether it is an absolute path or a relative word that resolves to the engine from the current directory. - The unparsable reason names the first offending character's class, and a test pins the label table to the parser's rejected characters. - The read-only-forms test restores the working directory before the temporary directory is removed, so it also runs on Windows, and a new test pins that a relative word resolving to the engine is gated while a rev:path form is not. The denial text is unchanged where the owner wrote it; the guard matches and denies exactly as before. Refs #5519 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
PR body contract — issue linkage This PR body conforms to the issue-linkage contract. Nothing to do. |
…denial-text Renumber the denial-text entry to disk-hygiene 0.34.1 above main's 0.34.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…denial-text Renumber the denial-text entry to disk-hygiene 0.34.2 above main's 0.34.1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…denial-text # Conflicts: # plugins/disk-hygiene/.claude-plugin/plugin.json # plugins/disk-hygiene/CHANGELOG.md
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Claude finished @kyle-sexton's task in 4m 43s —— View job Claude finished the code review
SummaryReviewed the diff ( No blocking correctness findings. I traced
One theoretical, currently-unreachable note (not filed as a finding, doesn't meet the high-signal bar since I could not construct a real caller that reaches it): The PR's own "Open question for the owner" (the gap between the advertised read-only-forms sentence and what Verification note: this lane's sandbox declined approval for |
|
Claude finished @kyle-sexton's task in 1m 44s —— View job Security review — PR #5582
Scope reviewed: all 5 changed files, with focus on the two files with security-relevant surface: No security issues found. Verified specifically:
The PR's own "Open question for the owner" (the |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5dc6aa5a08
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Resolution of the Codex P2 thread (discussion_r4147675721), within the #5519 decision (change the denial text only, no guard relaxation): take option 2. The denial text must not advertise a form the guard still denies, so |
…denial-text Renumber disk-hygiene 0.34.5 -> 0.36.1 above main's 0.36.0 and pass the command into main's single not-exact-engine-command deny. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 2m 44s —— View job Claude finished the code review
SummaryReviewed the diff between The core logic ( One finding posted inline ( Everything else — the flag-order rule derivation from declared subcommand specs, Verification note: I did not independently run |
|
Claude finished @kyle-sexton's task in 2m 0s —— View job Security review — PR #5582
Result: no new security-relevant change since the prior reviewI scoped the diff to The security-relevant code in that scoped diff — Per this lane's skip gate ("this head already has a successful security review that still applies"), I'm not re-deriving findings that are already on record. Confirming the substance of the prior reviews on this PR:
The one open item — No security issues found in this PR. |
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 2m 31s —— View job Claude finished the code review
SummaryScoped the diff correctly per this lane's criteria: This push ( Skip gate applies (criterion 4: "this head already has a successful review from this lane that still applies"). No new correctness/maintainability findings — the stage-order agreement between Outstanding item carried forward, not re-filed as a new finding: the owner's 2026-09-30T19:04:22Z decision (resolving Codex thread Verification note: static diff review only in this pass — I did not re-run |
|
Claude finished @kyle-sexton's task in 2m 7s —— View job Security review — PR #5582
Result: skip gate applies — no new security-relevant change since the prior reviewI scoped the diff with Diffing that scoped content against the last-reviewed commit on this PR ( Per this lane's skip gate ("this head already has a successful security review that still applies"), I'm not re-deriving findings already on record. Confirming the substance still holds:
The one open item — No security issues found in this PR. |
… gated payload word The engine-gate scope sentence now adds that a relative path or bare name which resolves to the installed engine from the current directory is still gated (owner decision on PR 5582, option 2). Text only: the guard allows and denies exactly as before. A quoted word the gate reads as an engine call, such as a gh --search query holding an interpreter and the engine filename, is now named as the gated word. The denial used to name the command head and ask for the hook's Python. The gate and the reason share one payload test, so they cannot disagree on which word gated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
disk-hygiene on origin/main is still 0.40.0, so this branch stays 0.40.1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 3m 10s —— View job Claude finished the code review
SummaryThis push ( This commit is the owner-decided fix from the open Codex P2 thread and the prior
No correctness or maintainability findings. The fix is precisely scoped to the wording gap that was already flagged twice on this thread, doesn't touch the classifier's actual allow/deny logic (confirmed: CHANGELOG entry was amended in place under the existing Verification note: static diff/code reading only in this pass — I did not re-run |
|
Claude finished @kyle-sexton's task in 1m 22s —— View job Security review — PR #5582
Result: no security issues foundScope. What's new since the last review on this thread. The prior two reviews on this PR (on
Verified, not just read:
This closes out the last open item from the prior two reviews on this PR; no new security-relevant surface was introduced by Verification note: static diff review only — this lane's sandbox did not permit running No security issues found in this PR. |
origin/main released disk-hygiene 0.41.0, so this branch's entry moves from 0.40.1 to 0.41.1, above it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 2m 33s —— View job Claude finished the code review
SummaryScoped the diff correctly per this lane's criteria: This push (
Skip gate applies (criterion 4: this head already has a successful review from this lane that still applies, and the security lane already reviewed the same content in depth). No new correctness or maintainability findings — this PR's own code is identical to what was reviewed on Verification note: static diff review only in this pass ( |
|
Claude finished @kyle-sexton's task in 1m 31s —— View job Security review — PR #5582
Result: skip gate applies — no new security-relevant change since the prior reviewScope. This is a shallow checkout, so What changed since the last review on this thread. The prior review (on
Per this lane's skip gate ("this head already has a successful security review that still applies"), I'm not re-deriving findings already on record from the No security issues found in this PR. |
Refs #5519
Summary
The Bash engine-gate denial in
destructive_guard.pygave no hint which token failed the exact-engine grammar, what the flag-order rule is, or which mention forms are gated. The denial now says all three. No behavior change: the guard matches and denies exactly the same commands.This PR uses
Refs, notCloses; whether it closes #5519 is left to the owner.Fix
_engine_mismatch_reasonnames what the classifier refuses (parse, word count, interpreter, engine script, subcommand,--data-root, per-subcommand grammar viaengine_grammar.explain_mismatch). It runs only on the deny path.grep foo "<engine path>",cat "<engine path>") is named first, as an absolute engine path or as a relative word that resolves to the engine from the current directory. Before, the reason blamed the command word (grep) as "not this hook's Python".gh issue list --search "python3 <engine>") is named as the gated word. Before, the reason namedghand asked for the hook's Python. The gate and the reason share one helper,_reads_as_engine_payload, so they cannot disagree on which word gated.;,&, substitution, glob, newline,!/#, backslash, quote) instead of listing all of them. A test pins the label table to the characters the literal parser rejects._engine_flag_order_rulestates the flag-order rule from the declared subcommand specs, and_ENGINE_GATE_SCOPEstates the gated mention forms and the read-only forms in the owner's words, with the condition the owner chose (option 2, PR comment 2026-09-30T19:04Z): a relative path or bare name that resolves to the installed engine from the current directory is still gated.disk-hygiene0.41.1 with a CHANGELOG entry above 0.41.0. No doc quotes the old denial text.Owner decision applied
The Codex P2 thread found that the advertised read-only forms are denied when the word resolves to the installed engine (the literal branch of
_engine_gate_relevantgates on file identity). The owner took option 2: keep the forms and add the condition.test_engine_gate_gates_a_relative_word_that_resolves_to_the_enginepins both the gated shapes and that their denial states the condition._engine_gate_relevantresult per working directory:grep foo <relative path to the engine>git grep foo -- <relative path to the engine>rg foo <bare engine name>rg foo <bare engine name>git grep foo -- <bare engine name>git show <rev>:<path to the engine>grep foo <relative path to the engine>Verification
test_hygiene(run as CI does, from the scripts directory): 674 tests OK (1 skipped) on the merged head, including tests for the denial text, agreement between the explainer and the classifier over every declared subcommand (handoff-applyincluded), the advertised read-only forms and their resolving-word condition, the engine operand reason, the payload-word reason, and the operator reason. The payload-word test also asserts_engine_gate_relevantstill gates those commands and still defers a plain mention.scripts/run-ruff.sh checkon the changed files: all checks passed.scripts/check-changelog-parity.sh --check,--check-order, andscripts/validate-plugins.sh: pass.Related
handoff-apply), fix(disk-hygiene): dedupe the engine gate's marker-free identity probes #5526, feat(disk-hygiene): add model-invocable read-only audit skill #5590 and feat(disk-hygiene): class-matched policy rules, atime/ctime age basis, reference in-flight input #5628 for disk-hygiene. The final deny in_decideis now main's singlenot-exact-engine-commandcall withcommand=commandadded, and the explainer reads the declared subcommand specs, so it covershandoff-apply's required flags.🤖 Generated with Claude Code