Problem
Stage 2 (issue-analyze.yml) exits success, spends money, and delivers
nothing — no comment on the issue, no label change. The workflow run is green,
is_error: false, permission_denials_count: 0, so every downstream signal says
the analysis happened. Nothing did.
It is not a hard failure and not intermittent noise: it reproduced on demand.
Measured
Six real (non-skipped) Stage 2 runs exist. Four landed, two did not:
| Issue |
Run |
Outcome |
| #118, #252, #624, #627 |
success |
comment posted, analyzed applied |
| #593 (2026-08-15 09:22) |
success |
nothing posted, label unchanged |
| #643 (2026-08-18 18:57) |
success |
nothing posted, label unchanged |
Re-firing @claude-bot analyze on both reproduced it immediately:
| Run |
Issue |
Duration |
Turns |
Cost |
Comment posted |
| 32173921625 |
#643 |
179 s |
33 |
$1.58 |
no |
| 32176358237 |
#643 |
54 s |
9 |
$0.33 |
no |
| 32176355892 |
#593 |
47 s |
7 |
$0.54 |
no |
~$2.45 burned across three runs on two issues, with zero product.
The turn counts are the tell. --max-turns is 100 and was never approached. The
workflow prompt requires reading three docs, delegating to the bess-analyst
sub-agent, independently re-reading every cited file:line, posting a structured
comment, and editing labels. Seven turns cannot be that. The agent is deciding
it is finished early and returning a final message instead of writing to the
issue.
Why it went unnoticed for 3 days
Every layer reports healthy:
- The workflow run is green — nothing to investigate in the Actions tab.
- The
ready-for-analysis label stays on, which is indistinguishable from
"nobody has run analyze yet".
- The backlog pass sees an un-analysed issue and reports
triage_labels or
nothing — it has no notion of "analyze was requested and silently failed".
On #593 the maintainer eventually wrote the diagnosis by hand (a 2302-character
comment on 2026-08-16), which is the real cost: the stage was paid for and the
work was done twice.
What is not the cause
Ruled out by direct inspection, so nobody re-derives them:
- Not permissions.
permission_denials_count: 0, and the job grants
issues: write with a GitHub App token that posts fine on the four runs that
worked.
- Not the trigger gate. All six runs reached the Claude step; the
if filter
correctly skips PR comments and non-owner comments (a skipped run is the
normal, healthy shape here).
- Not a missing sub-agent.
.claude/agents/bess-analyst.md is in the
checkout.
- Not
--max-turns. 7–33 of 100 used.
Two prompt defects visible on inspection
Neither is proven to be the cause, but both are real and cheap to fix:
PROCESS has two steps numbered 3 — "Delegate the investigation" and
"After the sub-agent reports back, independently verify". So the posting step
is labelled 4 while being the fifth instruction, and an agent tracking "am I
done with step 3" can satisfy the wrong one.
- Posting is prose, not a command. Step 4 describes a comment body; step 5
is the only literal shell line (gh issue edit …). Every step the runs did
execute is one with a literal command in it.
Acceptance
A Stage 2 run must not be able to exit success without having written to the
issue. Whatever the fix, the check belongs after the agent, in the workflow —
a run that posted no comment and applied no label should fail the job loudly,
rather than passing and charging for it. needs-human-review exists precisely
for the honest-failure case and was never applied either.
Repro
gh issue comment 643 --body "@claude-bot analyze" # as the repo owner
gh run view <id> --log | grep -E '"(num_turns|total_cost_usd|is_error)"'
gh issue view 643 --json labels,comments
Problem
Stage 2 (
issue-analyze.yml) exitssuccess, spends money, and deliversnothing — no comment on the issue, no label change. The workflow run is green,
is_error: false,permission_denials_count: 0, so every downstream signal saysthe analysis happened. Nothing did.
It is not a hard failure and not intermittent noise: it reproduced on demand.
Measured
Six real (non-
skipped) Stage 2 runs exist. Four landed, two did not:analyzedappliedRe-firing
@claude-bot analyzeon both reproduced it immediately:~$2.45 burned across three runs on two issues, with zero product.
The turn counts are the tell.
--max-turnsis 100 and was never approached. Theworkflow prompt requires reading three docs, delegating to the
bess-analystsub-agent, independently re-reading every cited
file:line, posting a structuredcomment, and editing labels. Seven turns cannot be that. The agent is deciding
it is finished early and returning a final message instead of writing to the
issue.
Why it went unnoticed for 3 days
Every layer reports healthy:
ready-for-analysislabel stays on, which is indistinguishable from"nobody has run analyze yet".
triage_labelsornothing — it has no notion of "analyze was requested and silently failed".
On #593 the maintainer eventually wrote the diagnosis by hand (a 2302-character
comment on 2026-08-16), which is the real cost: the stage was paid for and the
work was done twice.
What is not the cause
Ruled out by direct inspection, so nobody re-derives them:
permission_denials_count: 0, and the job grantsissues: writewith a GitHub App token that posts fine on the four runs thatworked.
iffiltercorrectly skips PR comments and non-owner comments (a
skippedrun is thenormal, healthy shape here).
.claude/agents/bess-analyst.mdis in thecheckout.
--max-turns. 7–33 of 100 used.Two prompt defects visible on inspection
Neither is proven to be the cause, but both are real and cheap to fix:
PROCESShas two steps numbered3— "Delegate the investigation" and"After the sub-agent reports back, independently verify". So the posting step
is labelled
4while being the fifth instruction, and an agent tracking "am Idone with step 3" can satisfy the wrong one.
is the only literal shell line (
gh issue edit …). Every step the runs didexecute is one with a literal command in it.
Acceptance
A Stage 2 run must not be able to exit
successwithout having written to theissue. Whatever the fix, the check belongs after the agent, in the workflow —
a run that posted no comment and applied no label should fail the job loudly,
rather than passing and charging for it.
needs-human-reviewexists preciselyfor the honest-failure case and was never applied either.
Repro