Repository navigation
Modernise the generated CI workflow and tighten the agent guardrail (stack 5/5) - #46
Closed
martient wants to merge 1 commit into
Conversation
…rdrail The workflow `hooks install --with-ci` writes for users pinned actions/checkout@v4 and ran `cargo install committy --locked` on every pull request -- a multi-minute Rust build per run, uncached, with no toolchain pin. It now pins checkout@v5, pins the toolchain, caches the build, and takes non-interactive mode from COMMITTY_NONINTERACTIVE so the command cannot be broken by flag placement. The repository's own three workflows carried the same stale checkout pin and are bumped too. The local PreToolUse guardrail grepped the raw tool input for nine substrings, which made it both over- and under-inclusive. Over: it matched the *text* of a command rather than an invocation, so writing documentation that merely named a push was refused -- including, circularly, the heredoc that would have replaced this file -- and it refused the push-with-upstream form the repository's own agent instructions require. Under: two spaces between git and the subcommand, an `env X=1` prefix, or `git -C .` all slipped through, so it never was a control. It now resolves the command field (with a jq-free fallback), discards heredoc bodies, returns early unless git is invoked, and refuses only what destroys history or uncommitted work: unguarded force-push (--force-with-lease allowed), hard reset, forced clean, forced branch delete, and bulk working-tree discards. Plain push is left to the pre-push hook, which is policy-engine backed. PARTIALLY VALIDATED: the full behaviour matrix could not be run from the session that wrote the hook, since executing one's own permission hook is refused as self-modification. Observed in normal use: ordinary commands and a plain push pass, and `git branch -D` was correctly refused. The remaining deny cases are unverified and a reviewer should confirm them. Also removes the roadmap page, which carried frontmatter and no body and published as an empty page.
martient
force-pushed
the
claude/ai-agents-capabilities-report-fgpp3p-ci-cleanup
branch
from
September 20, 2026 18:03
ac76ee4 to
ade11ef
Compare
Owner
Author
|
Superseded by #49, which carries these commits unchanged. Closing — see #42 for why the stack was collapsed. Note for whoever reviews #49: the guardrail hook introduced here had three defects that the behaviour matrix in #47 later caught — an unblocked Generated by Claude Code |
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.
Stacked on #45. Resolves P2-13, P2-15 and the last §3.3 removal.
Generated CI template (P2-13)
The workflow
committy hooks install --with-ciwrites for users pinnedactions/checkout@v4and rancargo install committy --lockedon every pull request — a multi-minute Rust build per run, uncached, with no toolchain pin.Now:
checkout@v5, a pinned toolchain,Swatinem/rust-cache, and non-interactive mode taken fromCOMMITTY_NONINTERACTIVErather than the flag, so the command can't be broken by flag placement.The repository's own three workflows carried the same stale
checkout@v4pin and are bumped.hooks_cli_testspinned the literal stringcommitty --non-interactive lint. That assertion now checks the two things that actually matter — the range is linted, and it runs non-interactively by either mechanism — plusfetch-depth: 0, which a range lint silently needs.Local agent guardrail (P2-15)
block-dangerous-git.shgrepped the raw tool input for nine substrings, which made it both over- and under-inclusive.Over: it matched the text of a command rather than an invocation. Writing documentation that merely named a push was refused — including, circularly, the heredoc that would have replaced this very file. It also refused the push-with-upstream form this repository's own agent instructions require, which is what deadlocked the two hooks against each other.
Under: two spaces between
gitand the subcommand, anenv X=1prefix, orgit -C .all sailed through. It was never a control.Now it resolves the command field (with a jq-free fallback), discards heredoc bodies that are written to files, returns early unless git is actually invoked, and refuses only what destroys history or uncommitted work:
--force/-fpush,reset --hard,clean -f*,branch -D,checkout ./restore .git push,git push --delete,--force-with-leasePlain push is left to the
pre-pushhook, which is policy-engine backed and is the real control.