fix(triage): resolve issue-field ids repo-scoped, and fail when triage records no state - #10
Merged
Merged
Conversation
…e records no state
Triage was setting the issue type and area labels but silently writing no
fields on some issues, and reporting success either way.
The prompt told the agent to resolve field ids from
/orgs/{org}/issue-fields. run-agent runs on an OIDC-exchanged Claude App
token, and that installation holds repo-scoped permissions only — no
organisation permission at all — so every /orgs/* path returns 403
"Resource not accessible by integration", REST and GraphQL alike.
setIssueFieldValue itself is authorised by repo issues:write and works.
Only the id lookup was closed, so the outcome depended on whether the
agent improvised another id source after the documented one 403'd. Some
did and wrote all four fields; others followed the instruction, reported
honestly that they could not, and stopped. Same workflow, same token.
Resolve ids from repository(owner,name){ issueFields } instead: same
org-level fields, same node ids, no org access needed. Enumerate the valid
option names in the prompt too — with no list an agent wrote Effort=XS,
which is not an option.
Add a final verification step that re-reads Triage state and fails the job
if it is unset. Nothing was red before: an unset state means
issue-implement refuses the issue, so the break surfaced days later on a
different workflow with the causing run out of view. The read is
repo-scoped on purpose — a check using a stronger token than the agent had
would pass where the agent failed.
Why: /orgs/* is 403 for a repo-scoped App installation; the failure landed
on the id lookup alone, which is why it read as flaky rather than broken.
Rejected: granting the Claude App an org permission (needs an admin, does
not help anyone else installing this standard); minting the org App token
in run-agent (that App has no issue-fields permission either).
Refs: DODI-00022, DODI-00007, DODI-00001
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What was wrong
Triage set the issue type and
area:*labels but silently wrote no fields on some issues, reportingsuccesseither way.dodi-smart/kodni.me#160is the reported case; #159 and #173 the same week, while #161 and #174 came out fully populated. That split is what made it read as flaky.The prompt told the agent to resolve field ids from
/orgs/{org}/issue-fields.run-agentruns on an OIDC-exchanged Claude App token, andgh api /orgs/dodi-smart/installationsshows that installation holding repo-scoped permissions only — not a singleorganization_*permission. Every/orgs/*path returns403 Resource not accessible by integration, REST and GraphQL alike.setIssueFieldValueitself is authorised by repoissues: writeand works. Only the id lookup was closed. So the outcome depended on whether the agent improvised another id source after the documented one 403'd — some did, some reported honestly that they could not and stopped.What this changes
repository(owner,name){ issueFields }— same org-level fields, same node ids, no org access needed. Verified live against kodni.me.Effort: XS, which is not an option (High | Medium | Low).Triage stateand fails if it is unset. Nothing was red before: an unset state meansissue-implement.ymlrefuses the issue, so the break surfaced days later on a different workflow with the causing run out of view — DODI-00007 one layer in. The read is repo-scoped on purpose; a check using a stronger token than the agent had would pass where the agent failed.Also records the node-id-vs-database-id trap and the
fieldId/issueFieldIdnaming trap directly in the prompt, since both produce errors that point nowhere near the cause.Rejected
dodi-smart-github-assistanttoken inrun-agent— that App does carry org permissions, but none of them is an issue-fields permission, so it would not have worked either.Verification
Per DODI-00013 this cannot be tested on its own PR. After merge and tag, triage a throwaway issue and assert:
The three stuck issues (#159, #160, #173) have been backfilled by hand from the values their own triage comments justified.
Governed by DODI-00022 (recorded in
dev-standards), added toAGENTS.md. The companion PR there carries the decision record and two checks that fetch this file over the API — merge this one first, or those checks fail.🤖 Generated with Claude Code