Repository navigation
fix(guardrails): treat the heredoc body of git commit -F - and git tag -F - as data in block-root-delete-target #7379
Description
Refs: #6625
Outcome
The one-line form git commit -F - <<'EOF' and git tag -F - <<'EOF' (every argument on the opener's line), whose message mentions a root delete target, is no longer refused by block-root-delete-target. Every other heredoc reader keeps being scanned.
Current behavior
plugins/guardrails/hooks/block-root-delete-target.sh rdt_hd_reader (about lines 3037-3053) treats a quoted-delimiter heredoc body as data only when the command is cat or gh pr|issue|api|release. A commit message written in the one-line form git commit -F - <<'EOF' gets scanned, so a message that names a delete target is refused.
Desired behavior
rdt_hd_reader also returns true when, and only when, the words are exactly: word 0 git, word 1 commit or tag, and the arguments include -F -. Any git global option before the subcommand (-c, -C, --exec-path, --git-dir and the like) does not match. Neither does any other git subcommand, bash <<'EOF', a pipe, or cat > file. The comment above the function is updated: it keeps the !sh reason for every other git word, and says commit and tag are exempt because git ignores an alias that hides a built-in command (git-config(1), alias.*).
Scope fence
plugins/guardrails/hooks/block-root-delete-target.sh(therdt_hd_readerfunction and its comment only)plugins/guardrails/hooks/block-root-delete-target.test.sh.changes/guardrails/<slug>.md
Acceptance criteria
- New stay-quiet cases:
git commit -F - <<'EOF'andgit tag -F - <<'EOF', each with a body that names a root delete target, exit 0. - New block cases:
git -c alias.x=y commit -F - <<'EOF',git -C /tmp commit -F - <<'EOF'and an unknown git alias with the same body still block. So do the existingbash <<'EOF'cases, and agit commit -F - --trailer "<x>" \form whose<<'EOF'opener sits on a later line. - The PR body asks the human merger to confirm that the stay-quiet cases fail on the base commit, as the hook-precision rule requires.
- The PR's CI runs
plugins/guardrails/hooks/block-root-delete-target.test.shand it passes. - A guardrails changelog fragment exists and
scripts/check-changelog-fragments.sh --checkpasses. - The PR body carries
Hold: a human merges this.
Out of scope
- Any other reader (
tee,bash, other git subcommands, interpreters). --file=-and--file -: fix(guardrails): block-root-delete-target judges backticks inside a quoted heredoc body #6625's decision admits only-F -.- The multi-line or trailer form stays scanned; do not relax
rdt_hd_plain. - Other guards.
Activity
github-actions commentedon Oct 13, 2026
Thanks for the report. Automated triage handed this issue to a maintainer.
Automated triage. A maintainer reviews it.
kyle-sexton commentedon Oct 13, 2026
Owner ratified this admission in an attended session on 2026-10-13: work-class: scoped. It touches a guard, CI script, settings or trust surface, so an agent may build it but the owner merges the PR: put 'Hold: a human merges this' in the PR body.
kyle-sexton commentedon Oct 14, 2026
This was generated by AI during triage.
Triage (work-loop intake sweep): this item already carries the owner's routing decision (
agent-ready+work-class: scoped, applied by the owner, with the attended ratification comment of 2026-10-13). The bot-appliedneeds-triagemarker is stale beside that routed state, so it is cleared; no other label changes. The owner's merge hold stands: the PR body must carry 'Hold: a human merges this'.