Skip to content

Let a text-capable guard stand in front of a command - #6

Merged
HackingGate merged 1 commit into
mainfrom
feat/shim-runs-text-guards
Aug 12, 2026
Merged

Let a text-capable guard stand in front of a command#6
HackingGate merged 1 commit into
mainfrom
feat/shim-runs-text-guards

Conversation

@HackingGate

Copy link
Copy Markdown
Owner

Three repositories wrote command.before on no-private-repo-names. The loader
refused all three, on grounds that were true and unhelpful: a built-in is not an
exec, and shim::run consulted only exec rules.

They were not writing it by mistake. That guard reads the commit message at
every git hook, so a repository whose own prose cites its issues gets every one
of those citations refused. One of the three says exactly this in its policy
file, in a paragraph explaining why the rule deliberately carries no
git.hooks. The seam it belongs at is the command that publishes text to a
forge — and there was no field to say that in.

Every alternative was worse, and I tested each:

placement result
git.hooks = ["commit-msg"] refuses every issue citation in a commit message
git.hooks = ["manual"] same refusal, at CI instead — verified, it reads the last commit
command.before what all three wrote; refused at load
no place at all "nothing says where it runs" — refused

What changed

shim::run consults text-capable built-ins alongside exec checkers, scoped by
the same command.before, through the same dispatch uphold guard --text uses.
That last part is the point: a guard that judged a commit message one way and a
pull-request body another would be two rules wearing one id, so the dispatch is
extracted into guard::text_refusal and both seams call it.

The loader allows the field for the three built-ins that can judge arbitrary
text and still refuses it for anything reading an index, an identity or a push
range — with a message that now names which ones qualify, instead of only saying
what the rule is not.

And the "this shim is checked by nothing" refusal counts a built-in as a
checker. It previously refused a policy whose shim was checked, by a guard
rather than by a script.

Why this and not three policy edits

This began as a plan to fix three repositories. Checking the refusal first
turned it around: the shape is legitimate, the vocabulary was short a word, and
editing the three would have meant either accepting refused citations or
inventing a placement that means nothing.

Verification

  • The fleet goes from 68 of 71 repositories reconciling to 71 of 71.
  • cargo test — 300 tests. Six new: the loader accepts the shape for each text
    guard and still refuses it for two non-text built-ins and a regexp rule; the
    shim refuses a private name in a PR body, lets a clean body through to the
    real command, and accepts a shim whose only checker is a built-in.
  • One existing test changed premise rather than being deleted:
    a_command_place_the_check_cannot_use_is_refused used prevent-ai-author,
    which is a text guard and is now legal. It tests two non-text built-ins
    instead, which is what it was always about.
  • cargo clippy --all-targets and cargo fmt --check clean; the repository's
    own hooks pass; uphold scan and uphold check over this tree are clean.

Three repositories wrote `command.before` on `no-private-repo-names` and the
loader refused all three, on grounds that were true and unhelpful: a built-in is
not an `exec`, and `shim::run` consulted only `exec` rules.

They were not writing it by mistake. That guard reads the commit message at
every git hook, and a repository whose own prose cites its issues gets every one
of those citations refused -- GroundGate says so in the policy file, in a
paragraph explaining why the rule deliberately carries no `git.hooks`. So the
seam it belongs at is the command that publishes text to a forge, and there was
no field to say that in. Every alternative was worse: `git.hooks =
["commit-msg"]` refuses the citations, `git.hooks = ["manual"]` refuses them at
CI instead, and no place at all is refused at load.

So the shim consults text-capable built-ins as well as `exec` checkers, scoped
by the same `command.before`, through the same dispatch `uphold guard --text`
uses -- a guard that judged a commit message one way and a pull-request body
another would be two rules under one id. The loader allows the field for those
three built-ins and still refuses it for anything that reads an index, an
identity or a push range, with a message that now names which ones can. And the
"this shim is checked by nothing" refusal counts a built-in as a checker, having
previously refused a policy whose shim was checked by a guard rather than by a
script.

The fleet goes from 68 of 71 repositories reconciling to 71 of 71. The three
were not misconfigured; the vocabulary was short a word.
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@HackingGate, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 23 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fedd8da7-f278-4a0e-b68a-bea425f502f9

📥 Commits

Reviewing files that changed from the base of the PR and between fc596df and 188970b.

📒 Files selected for processing (5)
  • docs/REFERENCE.md
  • src/config.rs
  • src/guard/mod.rs
  • src/shim.rs
  • tests/shim_cli.rs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.38462% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 87.74%. Comparing base (fc596df) to head (188970b).

Files with missing lines Patch % Lines
src/guard/mod.rs 83.33% 3 Missing ⚠️

❌ Your patch status has failed because the patch coverage (95.38%) is below the target coverage (100.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main       #6      +/-   ##
==========================================
+ Coverage   87.63%   87.74%   +0.10%     
==========================================
  Files          24       24              
  Lines        7094     7140      +46     
==========================================
+ Hits         6217     6265      +48     
+ Misses        877      875       -2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@HackingGate
HackingGate merged commit 1044e9a into main Aug 12, 2026
22 of 23 checks passed
@HackingGate
HackingGate deleted the feat/shim-runs-text-guards branch August 12, 2026 14:48
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.

2 participants