Skip to content

fix(triage): verify a comment or body marker landed before calling a run successful - #56

Merged
Mearman merged 6 commits into
mainfrom
fix/triage-bot-actor-and-silent-success
Sep 10, 2026
Merged

fix(triage): verify a comment or body marker landed before calling a run successful#56
Mearman merged 6 commits into
mainfrom
fix/triage-bot-actor-and-silent-success

Conversation

@Mearman

@Mearman Mearman commented Sep 10, 2026

Copy link
Copy Markdown
Member

Claude Code exiting cleanly only proves the process ran; nothing in this composite action ever checked whether triage's own promised output -- a new issue comment, or a body edit carrying the claude-triage:start marker -- actually landed on GitHub. Both are ordinary tool calls the model makes from its own prompt, so a run that legitimately completes without calling either still reported steps.claude.outcome == 'success', which made the progress-comment step delete the one visible trace of the run and made the composite action's own overall conclusion green.

Confirmed happening for real on three separate triage runs in novus-power/hive: novus-power/hive#1490, novus-power/hive#1657, novus-power/hive#1661 -- each reported success and left nothing behind, no comment, no label, no body edit.

Adds a "Verify triage output landed" step that re-fetches the issue's own comments and body after a triage run reports success (comparing against the progress comment's own id as the "before" marker), and folds a genuine mismatch into the run's own outcome the same way "Wrap up on turn limit" already does, rather than trusting the model's self-report. Scoped to triage mode only, since that's where this was actually observed -- review mode already has an equivalent real check ("Structured review summary" re-fetches the submitted review).

…run successful

Claude Code exiting cleanly only proves the process ran; nothing in this
composite action ever checked whether triage's own promised output -- a new
issue comment, or a body edit carrying the claude-triage:start marker --
actually landed on GitHub. Both are ordinary tool calls the model makes from
its own prompt, so a run that legitimately completes without calling either
still reported steps.claude.outcome == 'success', which made the
progress-comment step delete the one visible trace of the run and made the
composite action's own overall conclusion green.

Confirmed happening for real on three separate triage runs
(novus-power/hive#1490, #1657, #1661): each reported success and left
nothing behind.

Adds a step that re-fetches the issue's own comments and body after a
triage run reports success, and folds a genuine mismatch into the run's
own outcome the same way turn-limit wrap-up already does, rather than
trusting the model's self-report.
@Mearman
Mearman marked this pull request as ready for review September 10, 2026 20:05
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 10, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
🔒 Security Review Completed 2026-09-10T20:10:10.723570Z b0c031b Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

claude[bot]
claude Bot previously requested changes Sep 10, 2026
Comment thread action.yml
Comment thread action.yml Outdated
Comment thread action.yml
…own comment

--paginate -q filters the jq expression per page rather than across the
combined result, so an issue with more prior comments than fit on one page
left the comment count as a multi-line value. Separately, "Post Headroom
savings comment" posts its own comment unconditionally whenever Headroom
proxied anything, under the shipped default configuration, and that
comment's id is always greater than the progress comment's -- counting it
made the check report success even when triage itself left nothing.

Slurps every page into one array before filtering, and excludes any
comment carrying the Headroom marker. Both gh api calls in this step are
now retried three times like every other one in this file that isn't
already guarded by an outer continue-on-error.
@claude
claude Bot dismissed their stale review September 10, 2026 20:21

Superseded by re-review on the latest commit.

claude[bot]
claude Bot previously requested changes Sep 10, 2026
Comment thread action.yml Outdated
…omment's id

The verification step's if: required steps.progress-comment.outputs.comment_id,
which is empty whenever post_progress_comment is false -- a supported,
documented input combination this repeats through a different door. In that
configuration verification was skipped entirely and steps.claude.outcome flowed
straight through as this composite action's own overall conclusion, unverified.

Adds a "Record run start time" step, unconditional and first in the job, and
switches the comment check to created_at >= that timestamp instead of
id > the progress comment's id. The progress comment (when it exists) and
Headroom's own savings comment are still excluded explicitly, by id and by
marker respectively, so neither is miscounted as real triage output.
@claude
claude Bot dismissed their stale review September 10, 2026 20:33

Superseded by re-review on the latest commit.

claude[bot]
claude Bot previously requested changes Sep 10, 2026
Comment thread action.yml Outdated
Any comment landing in the run's time window -- a human reply, a different
bot, another automation entirely -- satisfied the created_at/id/marker
filters and counted as real triage output, even when Claude's own comment
never landed. Filters by the identity GH_TOKEN actually authored as: read
straight from the progress comment's own API response when one exists
(post_progress_comment enabled, the default), falling back to the
documented default GITHUB_TOKEN identity when it doesn't and no custom
github_token is set. The one combination neither can resolve -- no
progress comment and a custom github_token -- omits the author filter
rather than guessing or failing a valid input combination outright.

"Post progress comment" now captures the real poster login from its own
API response alongside the comment id, rather than discarding it.
@claude
claude Bot dismissed their stale review September 10, 2026 20:44

Superseded by re-review on the latest commit.

claude[bot]
claude Bot previously requested changes Sep 10, 2026
Comment thread action.yml
…en is empty

"Run Claude Code" passes inputs.github_token straight through to upstream
with no fallback, unlike GH_TOKEN elsewhere in this file (github_token ||
github.token). With the documented default -- github_token left empty, as
every claude-triage.yml example in this repository does -- that asymmetry
means Claude's own comment authenticates via an upstream-minted GitHub App
token (claude[bot]), while the progress comment authenticates as the
ambient github-actions[bot]: two different identities on the same run.

Confirmed directly against real production comments on novus-power/hive,
which uses exactly this configuration: the progress comment is authored by
github-actions[bot], genuine triage comments by claude[bot]. The previous
revision would have made every real triage run there report a false
failure, having filtered out Claude's own comment by author.

Checks for an empty github_token first and uses claude[bot] in that case,
before falling back to the progress comment's own observed identity (valid
only when both paths share the same real token) or no author filter at all.
@claude
claude Bot dismissed their stale review September 10, 2026 20:54

Superseded by re-review on the latest commit.

claude[bot]
claude Bot previously requested changes Sep 10, 2026
Comment thread action.yml Outdated
examples/direct/claude-triage.yml left github_token unset (the App-identity
path) but never declared id-token: write, so the OIDC exchange that mints
the Claude Code App token had nothing to authenticate with -- every triage
run using this exact shipped example, unmodified, would fail outright at
setupGitHubToken() with "Could not fetch an OIDC token", matching
examples/direct/claude-review.yml's own already-correct configuration and
the same permission novus-power/hive's real workflow had already added
independently.

Corrected the "Verify triage output landed" comment that cited this
example as already granting id-token: write, which overstated what was
actually shipped before this fix.
@claude
claude Bot dismissed their stale review September 10, 2026 21:03

Superseded by re-review on the latest commit.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed at 4ef350b. This commit ("grant id-token: write in the direct-form triage example") directly and correctly addresses the Should-fix from my last round: examples/direct/claude-triage.yml now declares id-token: write, and the code comment in action.yml is updated to accurately reflect that the claude[bot] branch is only reachable on a genuine, successful OIDC-based App-token mint — matching what I verified independently against upstream's setupGitHubToken() source. Thread resolved.

Nothing else changed in this revision. All findings from prior rounds are now fixed and none remain open. Approving.

@github-actions

Copy link
Copy Markdown

🗜️ Headroom context compression

Metric Value
Requests proxied 12
Tokens saved 19481
Aggregate savings 0.8% of all tokens sent
Average per-request compression 0.9%

@Mearman
Mearman merged commit d2705fa into main Sep 10, 2026
15 checks passed
@Mearman
Mearman deleted the fix/triage-bot-actor-and-silent-success branch September 10, 2026 21:04
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.10.2 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant