ci(review): gate the on-open review on author_association, not the members API - #675
Eldad-Caura wants to merge 1 commit into
Conversation
…mbers API The on-open review has been skipping every human pull request in this repo. Reviews only ever ran when someone commented @claude. Rule 1 called `orgs/caura-ai/members/{user}` at runtime. That endpoint answers for its CALLER, and GITHUB_TOKEN sees only PUBLIC members — it returns 404 for a private member exactly as for a stranger. Every maintainer's caura-ai membership is private: GET /orgs/caura-ai/public_members/Eldad-Caura -> 404 GET /orgs/caura-ai/public_members/erni-a -> 404 so the gate skipped, and said so: #673 "PR author 'Eldad-Caura' is not a public member", #524 the same for erni-a, #672 for caura-deploy-bot[bot]. The @claude path kept working the whole time because it already read author_association. Checking the endpoint by hand hides this — a personal token returns 204, because you can always see your own membership. The comment that justified the API call was wrong. It claimed a private member's author_association surfaces as NONE. Live payloads in this repo: #673 Eldad-Caura MEMBER (private member) #524 erni-a MEMBER (private member) #577 Souptik96 FIRST_TIME_CONTRIBUTOR Membership visibility does not affect the field, and it still discriminates outsiders. So requiring public org membership to get a code review was never a deliberate policy — it was a consequence of that wrong belief. Rule 1 now reads author_association and accepts MEMBER and OWNER: the same field and the same values as claude-retrigger. One mechanism for one policy — two ways of deciding "is this an org member" is the drift this pipeline exists to remove. Behaviour otherwise preserved. COLLABORATOR stays excluded, deliberately, since the policy is "our org" rather than repo write access. Bots are not MEMBER, so they stay skipped regardless of rule 4. An absent field skips, so the gate is still fail-closed. The trade, stated rather than buried: author_association is computed when the event fires, not when the review runs, so a member removed from the org in between is still honoured (reopening recomputes it). The alternative reflected review time but did not work at all, and retrigger already accepts this trade. Three comments repeated the NONE claim — the file header, rule 1, and the retrigger step. All corrected, because the false claim is what produced the bug; leaving it would invite the same "fix" again. Also drops the now-unused ORG env. Verified: the gate across all nine association values GitHub can send (MEMBER and OWNER review; COLLABORATOR, CONTRIBUTOR, FIRST_TIME_CONTRIBUTOR, FIRST_TIMER, NONE, MANNEQUIN and unset skip), and full-repo actionlint output identical to main — five pre-existing findings, none introduced. Signed-off-by: eldad-caura <eldad@caura.ai>
|
Claude Code Review — skipped: PR author 'Eldad-Caura' is not a caura-ai org member (author_association: CONTRIBUTOR) |
|
Converted to draft — this fix does not work, and CI caught it on its own PR. The gate ran and skipped, with the new reason string:
Not Where I went wrongI verified Two different sources for the same field, same user, same repo — and the workflow reads the second. The comment I deleted was substantively right. It said the payload field doesn't reflect private What does hold is that the Where that leaves the actual problemThe on-open review is still skipped for every human pull request, and neither the old gate nor this
Accepting I'd take (1): no code, no new failure mode, and it restores the gate the way it was designed. If you'd The spend ceiling in #673 is unaffected by any of this and still stands on its own. |
|
The workflow was blocked at the permission gate. I'll deliver the review directly from my analysis of the diff. SummaryThis PR fixes a broken org-membership gate by replacing a runtime Medium/Low IssuesMisleading actor name in skip reason on
|
|
Closing. The premise was wrong and the actual fix has landed elsewhere — org membership visibility. Keeping this closed rather than reworked, because what it proposed was worse than what it replaced: it The record, so this is not rediscovered: Two traps in there. The The operational requirement is real and worth stating plainly: this gate requires public org |
|
Claude Code Review ✅ No issues found. Reviewed by |
The on-open review has been skipping every human pull request in this repo. Reviews only ever ran
when someone commented
@claude.The bug
Rule 1 called
orgs/caura-ai/members/{user}at runtime. That endpoint answers for its caller, andGITHUB_TOKENsees only public members — it returns 404 for a private member exactly as for astranger. Every maintainer's caura-ai membership is private:
So the gate skipped, and said so on the PRs: #673 "PR author 'Eldad-Caura' is not a public member",
#524 the same for
erni-a, #672 forcaura-deploy-bot[bot].This is easy to miss two ways. Checking the endpoint by hand returns 204, because a personal token
can always see your own membership. And the
@claudepath kept working throughout — it already readauthor_association— so the pipeline never looked broken.The comment that justified it was wrong
It claimed a private member's
author_associationsurfaces asNONE. Live payloads from this repo:author_associationMembership visibility does not affect the field, and it still discriminates outsiders correctly. So
requiring public org membership to get a code review was never a deliberate policy — it fell out of
that wrong belief.
The fix
Rule 1 now reads
author_association, acceptingMEMBERandOWNER— the same field and the samevalues
claude-retriggeralready uses. One mechanism for one policy; two ways of deciding "is this anorg member" is precisely the drift this pipeline exists to remove.
Behaviour otherwise preserved.
COLLABORATORstays excluded (the policy is "our org", stricterthan repo write access). Bots aren't
MEMBER, so they stay skipped regardless of rule 4. An absentfield skips, so the gate remains fail-closed.
The trade, stated:
author_associationis computed when the event fires, not when the review runs,so a member removed from the org in between is still honoured — reopening recomputes it. The
alternative reflected review time but didn't work at all, and retrigger already accepts this trade.
Verified
Gate behaviour across all nine values GitHub can send:
Full-repo
actionlintoutput is byte-identical tomain— five pre-existing findings, noneintroduced. (The
HTTP_CODEwarning moves from line 266 to 292 only because my comment shifted theline numbers.)
Also in here
Three comments repeated the
NONEclaim — the file header, rule 1, and the retrigger step. Allcorrected, because the false claim is what produced the bug; leaving it in place would invite the same
"fix" again. Drops the now-unused
ORGenv var.One thing this does not fix
caura-ai/.github's shared pipeline has the same API-basedauthor-gate. It is dormant today —autodisables it on private repos and all six consumers are private — but making any of them publicwould reproduce this exact silent skip. Its input description is at least honest about the limitation
("an org member visible to GITHUB_TOKEN — in practice a PUBLIC member"), so it is a latent trap rather
than an active bug. Worth the same change, separately.