Skip to content

claude-code-review: gha#392 background-agent stub review recurred despite gha#393's run_in_background:false mitigation #532

Description

@d-morrison

gha#393's run_in_background: false prompt mitigation for gha#392 (reviewer spawns background Agent calls, then ends its turn waiting on completion notifications that never arrive in a headless CI run) is live in run-claude-review-attempt/action.yml and has been for a while (v2 slid to 70c7fa8 carrying it, per gha#392's own measurement comments). It has now recurred with the identical signature.

Evidence

Run 32347489886, job review / claude-review, on Morrison-Lab/ai-config#1744 at head 185054b, is_error: false, subtype: success, num_turns: 13, total_cost_usd: $4.21.

The final result message:

Stopping Point: Not a clean stopping point / work remains queued: four background review agents (2 CLAUDE.md compliance passes, 2 Opus bug-scan passes) on PR Morrison-Lab/ai-config#1744 are still running. Once they complete, I still need to validate any flagged issues, then produce the final review output ending in a ### Verdict line, per this review-only run's requirements.

Despite claude_args's --append-system-prompt explicitly stating (verbatim, still present in run-claude-review-attempt/action.yml at the time of this run):

This run is a single, synchronous CI job with a fixed timeout and no one to resume it afterward. Do NOT spawn a background agent or sub-task to continue the review in a future turn or after this job ends... every one of those calls MUST be synchronous: pass run_in_background: false on each Agent/Task call.

the reviewer spawned four background agents anyway and ended its turn waiting on them -- exactly the gha#392 failure shape, just with the review's own multi-pass structure (2 CLAUDE.md compliance + 2 Opus bug-scan) instead of #392's eight-way fan-out.

Why this is likely worth a second look

A prompt instruction is not a hard constraint -- the model can and (per this run) does deviate from it. gha#392's own "Suggested direction" section named the mechanical alternative (constrain the tool rather than instruct around it) and its follow-up comment on gha#392 walked that back specifically for denying Agent outright (breaks the plugin's legitimate synchronous fan-out). Nothing in that thread evaluated a narrower mechanical constraint -- e.g. whether Claude Code's tool-permission syntax supports a parameter-scoped grant (something like an Agent(run_in_background:false)-shaped allow rule, if the permission engine supports matching on tool input rather than only tool name) that would make the synchronous-only constraint enforced rather than requested. Worth checking whether that's possible before concluding a prompt-only fix is the ceiling here.

Also unaddressed from gha#392 itself

Its closing "Suggested direction" paragraph asked: "Worth checking whether the guard can also treat 'final message names background agents' as a distinct outcome from a generic stub, since the retry is unlikely to help and the spend is large." That's still open -- check-review-execution.sh treats this the same as any other no-verdict stub (retryable when denial count is low, per gha#185's threshold), even though a same-prompt retry of a run that just demonstrated it ignores the synchronous-only instruction is not obviously more likely to recover than #198's high-denial pattern is.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions