Skip to content

fix(review): re-unbreak /review slash command poisoned by PR #226 regression - #244

Closed
tend-agent wants to merge 1 commit into
mainfrom
hourly/review-24287235173-review-slash-poison-regression
Closed

fix(review): re-unbreak /review slash command poisoned by PR #226 regression#244
tend-agent wants to merge 1 commit into
mainfrom
hourly/review-24287235173-review-slash-poison-regression

Conversation

@tend-agent

Copy link
Copy Markdown
Collaborator

Summary

PR #226 (fix(ci-runner): filter CI polling by run URL, not workflow name, merged 2026-04-11T15:01:22Z) reintroduced the exact poisoned-text regression that PR #234 fixed. Its diff on plugins/tend-ci-runner/skills/review/SKILL.md and plugins/tend-ci-runner/skills/running-in-ci/SKILL.md reverted the CI-polling comment from PR #234's wording back to the pre-#234 wording containing `if \!` adjacent to backticks — which the slash-command preprocessor scans and exec's as bash regardless of markdown code fences, consuming through the next backtick and trying to run the em-dash-led fragment as a command.

Since PR #226 merged, every /review invocation has failed identically. All three tend-review runs in this hour produced the same 5-line trace:

{"type":"queue-operation","operation":"enqueue"}
{"type":"queue-operation","operation":"dequeue"}
{"type":"user","content":"<local-command-caveat>..."}
{"type":"user","content":"<command-name>/review</command-name> <command-args>N</command-args>"}
{"type":"user","content":"<local-command-stderr>Error: Shell command failed for pattern \"\!` — the Bash tool escapes `\":\n/bin/bash: line 1: —: command not found</local-command-stderr>"}

No assistant turn, no Skill loads, no tool calls, no review. The model was never given instructions to follow — the exact same failure signature PR #234 documented.

Evidence (this hour)

Run PR Branch Session size Review posted
24286232974 #240 hourly/review-24286117723-permalink-sha 5 lines
24286792302 #241 fix/review-gates-decision-point 5 lines
24287054138 #242 fix/review-gates-trim-decision-point 5 lines

Confirmation via gh pr view <N> --json reviews: all three PRs return []. PRs #240 and #241 were merged by max-sixty without bot review because the bot was silently broken.

No earlier broken tend-review run exists between PR #226's merge at 15:01Z and the current window — #240 was the first PR to land after the regression.

Gate assessment

Fix

Rephrase the CI-polling comment in both files to avoid any \! adjacent to a backtick. Guidance content is unchanged. Matches the exact wording PR #234 merged — this is a straight restoration of that fix.

Before:

# Use `||` rather than `if \!` — the Bash tool escapes `\!` as `\\!`, which
# prevents bash from recognizing the pipeline-negation reserved word and
# leaves the loop stuck until the 10-minute timeout.

After:

# Use `||` rather than `if`-based negation. The Bash tool escapes the
# exclamation mark to a literal backslash-exclamation, which prevents bash
# from recognizing the pipeline-negation reserved word and leaves the loop
# stuck until the 10-minute timeout.

grep -rn '\!' plugins/` after the fix returns zero matches.

Why this happened twice

PR #234 fixed the poison text but didn't add a regression guard. When PR #226 later restructured the surrounding comment (legitimately, for the $GITHUB_WORKFLOW$GITHUB_RUN_ID filter change), the author rewrote the whole block and put the poisoned phrasing back in. A follow-up PR to add grep -rn '\!' plugins/to the lint step (orpre-commit` hook) would prevent a third reintroduction. Leaving that out of this PR to stay atomic.

Test plan

  • Lint, test, and review checks pass on this PR
  • Bot's self-review session on this PR executes with an assistant session longer than 5 lines (proving the preprocessor poison is gone)
  • grep -rn '\!' plugins/` returns no matches after merge
  • First post-merge tend-review run on an unrelated PR posts an actual review

…ression

PR #226 (`fix(ci-runner): filter CI polling by run URL, not workflow name`)
reintroduced the exact poisoned-text regression that PR #234 fixed. Its diff
on plugins/tend-ci-runner/skills/review/SKILL.md and
plugins/tend-ci-runner/skills/running-in-ci/SKILL.md reverted the CI-polling
comment from the PR #234 wording back to the pre-#234 wording containing
`` `if \!` ``, which the slash-command preprocessor scans and exec's as bash.

Since #226 merged at 2026-04-11 15:01:22 UTC, every `/review` invocation has
failed identically with the 5-line trace: queue/dequeue, command-caveat,
command-name, local-command-stderr, then nothing. Three tend-review runs in
this hour's window (PRs #240, #241, #242) all produced that exact trace and
posted zero reviews.

Rephrase the CI-polling comment in both files to avoid any `\!` adjacent to a
backtick. The guidance is unchanged. Matches the wording that PR #234 already
merged successfully — this is a straight restoration of that fix.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tend-agent tend-agent added the claude-behavior Behavioral issues found by review-reviewers label Apr 11, 2026
@tend-agent

Copy link
Copy Markdown
Collaborator Author

Closing as a duplicate of #243. Both PRs were opened from concurrent matrix jobs of the same review-reviewers run (GITHUB_RUN_ID 24287235173 — #243 from the max-sixty/worktrunk job, this PR from the max-sixty/tend job) and carry functionally identical fixes for the same PR #226 regression. #243 was created first (17:11:25Z vs 17:13:42Z) and its CI is already green, so deferring to it.

The max-sixty/tend-side evidence (3 runs on PRs #240/#241/#242, all 5-line traces, all zero reviews) is recorded in the review-reviewers-tracking comment on #133.

@tend-agent tend-agent closed this Apr 11, 2026
max-sixty added a commit that referenced this pull request Apr 19, 2026
The Bash tool no longer rewrites exclamation marks to backslash-bang in
heredocs. Verified: both `<<EOF` and `<< 'EOF'` now pass `!` through
unchanged. Drop the guidance to use Write + `--body-file` for comment
bodies containing `!`, and drop "unescaped bangs" from the bot-comment
corruption signals.

The `${GITHUB_REPOSITORY}` heredoc-quoting guidance stays (that's bash
semantics, not a Claude Code bug), as does the bang-backtick pre-commit
guard (separate slash-command preprocessor issue, #234/#243/#244).

Co-Authored-By: Claude <noreply@anthropic.com>
max-sixty added a commit that referenced this pull request Apr 19, 2026
The Bash tool no longer rewrites exclamation marks to backslash-bang in
heredocs. Verified locally — both `<<EOF` and `<< 'EOF'` now pass `!`
through unchanged.

Changes:
- `running-in-ci`: drop the paragraph telling agents to use the Write
tool + `--body-file` for comment bodies containing `!`. Heredocs with
`gh ... --body` work fine again.
- `review-reviewers`: drop "unescaped bangs" from the bot-comment
corruption signals — no longer a thing to watch for.

Kept intentionally:
- The `${GITHUB_REPOSITORY}` heredoc-quoting warning (bash semantics
around single-quoted heredocs, not a Claude Code bug).
- The `.pre-commit-config.yaml` bang-backtick guard — that's a separate
slash-command preprocessor issue (#234/#243/#244), not the heredoc bug.

> _This was written by Claude Code on behalf of @max-sixty_

Co-authored-by: Claude <noreply@anthropic.com>
tend-agent added a commit that referenced this pull request Apr 25, 2026
The original PR's new callout contained `!` in a code span, producing the
backtick-bang-backtick byte sequence the `forbid bang-backtick in plugin
skill files` pre-commit hook rejects (and which would crash the Claude
Code slash-command preprocessor — tend#234, #243, #244). Rephrase the
single occurrence as "literal exclamation mark" to match the prose used
later in the same paragraph.

Co-Authored-By: Claude <noreply@anthropic.com>
max-sixty added a commit that referenced this pull request May 15, 2026
…unneeded guidance (#504)

## Bug

Linux Claude Code v2.1.142's bubblewrap-backed subprocess sandbox wraps
bash commands using the legacy `shell-quote` quote function with the
regex `/(["\\$`!])/g`, which escapes `!` to `\!` in any argv token that
mixes `'` with whitespace. That landed `\!=` in `jq` filters,
`assert\!()` in code references, `feat(api)\!:` in conventional-commit
titles, etc. The same binary contains a **fixed** `'\''`-wrap quoting
path for the macOS `sandbox-exec` route — both paths coexist, only the
Linux-bwrap path still uses the buggy quoter. See
[anthropics/claude-code#35701](anthropics/claude-code#35701)
(closed as stale; multiple duplicates closed since).

## Fix

1. **`action.yaml`**: set `CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=0` on the
`claude-code-action` invocation. This disables the bwrap sandbox and
routes bash through the fixed `'\''`-wrap path. Trade-off: loses
subprocess env isolation. Applied at the composite-action level, so all
`max-sixty/tend@v1` consumers pick it up automatically once tagged.

2. **Skills**: with the bug worked around, the bang-trap guidance can
go. Removed across `triage`, `notifications`, `review-runs`,
`review-reviewers`, and `running-in-ci`:
- "Don't use `!` in comment body" / "use Write tool for bodies with `!`"
- `!=` rewrite warnings in `jq` recipes (and the awkward `(.status ==
"completed") | not` rephrase)
   - `--title-file` and `git commit -F` workarounds
   - `||` not `if !` rationale comments
   - `<<'EOF'`/`<<EOF` interpolation footgun warning

3. **Body composition**: standardized on Write tool + `--body-file` for
substantial PR/comment/gist bodies. Removed the inline `gh ... --body
"$(cat <<'EOF' ...)"` heredoc patterns from `review-reviewers`'s gist
seed and step summary and the line-wrap example in `running-in-ci`.
Write-tool composition is reviewable, sandbox-independent, and bypasses
the shell-quoting layer entirely.

## Kept on purpose

- **Backtick-in-heredoc paragraph** (extended via origin/main merge with
[#495](#495 nested-fence
guidance). This is a model authoring habit, *not* the shell-quote bug —
the workaround doesn't help. The paragraph now covers inline spans AND
nested fences, recommending longer outer fences for nesting and bare
backticks throughout.
- **Corruption-scan tripwires in `review-reviewers`** (`grep -nP '\\!'`
and `` grep -nP '\\\`' ``). If the workaround stops working — bug
returns upstream, env var override, the sandbox surface changes — the
scans catch it in the bot's own output.
- **`no-preprocessor-poison-in-skills` pre-commit hook**. Different bug
(slash-command preprocessor crashes on literal `` !` `` in plugin skill
`.md` files, regressed twice per #234/#243/#244), unrelated to the
Bash-tool rewrite.

## Validation posture

Workaround is empirically targeted: the bug reproduces in CI (bwrap
sandbox active), does not reproduce locally (`sandbox-exec` on the fixed
path), and the env-var docstring inside the binary explicitly documents
the opt-out. If a regression slips, `review-reviewers`'s `grep -nP
'\\!'` / `` grep -nP '\\\`' `` scans against the bot's own output fire
on the next run. Easy revert via `git revert <commit>` if anything
misbehaves.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

claude-behavior Behavioral issues found by review-reviewers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants