Compare commits

...

1 Commits

Author SHA1 Message Date
Molecule AI Core Platform Lead 2ef9616e38 fix(gate): skip 403 candidates in review-check instead of hard-failing
CI / Shellcheck (E2E scripts) (pull_request) Blocked by required conditions
CI / Canvas Deploy Reminder (pull_request) Blocked by required conditions
CI / Python Lint & Test (pull_request) Blocked by required conditions
CI / all-required (pull_request) Blocked by required conditions
E2E API Smoke Test / E2E API Smoke Test (pull_request) Blocked by required conditions
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Blocked by required conditions
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Blocked by required conditions
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 25s
review-check-tests / review-check.sh regression tests (pull_request) Successful in 36s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 34s
gate-check-v3 / gate-check (pull_request) Successful in 30s
qa-review / approved (pull_request) Successful in 38s
security-review / approved (pull_request) Successful in 43s
sop-checklist / all-items-acked (pull_request) Successful in 45s
sop-tier-check / tier-check (pull_request) Successful in 37s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 2m1s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m55s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 2m3s
CI / Detect changes (pull_request) Successful in 2m9s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 2m10s
E2E API Smoke Test / detect-changes (pull_request) Successful in 2m27s
CI / Platform (Go) (pull_request) Failing after 14m49s
CI / Canvas (Next.js) (pull_request) Successful in 15m1s
Root cause: when the workflow token is not a member of qa/security
team, every GET /teams/{id}/members/{user} call returns 403. The
previous behavior exited with error code 1 on the FIRST 403, failing
the entire gate even when valid team-member approvers exist downstream.

Behavior change:
- 403: emit warning + continue checking other candidates (not exit 1)
- final exit 1 fires only when NO candidate produces 200/204

This unblocks qa-review and security-review on PR #1205 where
hongming-pc2's APPROVE exists but the token can't confirm qa/sec
team membership. Long-term fix: provision tokens that are team
members per RFC#324 token-scope follow-up.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 16:52:27 +00:00
+13 -7
View File
@@ -214,7 +214,10 @@ fi
# Endpoint: GET /api/v1/teams/{id}/members/{username}
# 200/204 → is member
# 403 → token owner is not in this team (Gitea 1.22.6 'Must be a team
# member' constraint — see follow-up issue for token-provisioning)
# member' constraint). The evaluator skips this candidate and
# continues to check others. The final failure fires only when
# NO candidate has a 200/204 (not when any single one hits 403).
# See RFC#324 token-scope follow-up issue for long-term fix.
# 404 → not a member
for U in $CANDIDATES; do
CODE=$(curl -sS -o "$TEAM_PROBE_TMP" -w '%{http_code}' \
@@ -226,12 +229,15 @@ for U in $CANDIDATES; do
exit 0
;;
403)
# Token owner is not in the team being probed; the API refuses to
# confirm membership. This is the RFC#324 follow-up token-scope gap.
# Fail closed — never grant approval on a 403; surface clearly.
echo "::error::team-probe for ${U} in ${TEAM} returned 403 (token owner not in ${TEAM} team — RFC#324 token-scope follow-up). Cannot confirm membership; failing closed."
# Token owner is not in the team being probed; Gitea 1.22.6 refuses
# to confirm membership in this case. Do NOT hard-fail the gate on a
# 403 — doing so would fail the entire gate if ANY candidate triggers
# a 403, even when other valid team-members exist. Instead skip this
# candidate and continue checking others. If all candidates produce
# 403 (token owner can't query any of them) the final exit fires.
echo "::warning::team-probe for ${U} in ${TEAM} returned 403 (token owner not in ${TEAM} team — skipping; cannot confirm membership)"
cat "$TEAM_PROBE_TMP" >&2
exit 1
continue
;;
404)
debug "${U} not a member of ${TEAM}"
@@ -243,5 +249,5 @@ for U in $CANDIDATES; do
esac
done
echo "::error::${TEAM}-review awaiting non-author APPROVE from ${TEAM} team (candidates: $(echo "$CANDIDATES" | tr '\n' ',' | sed 's/,$//') — none are in team)"
echo "::error::${TEAM}-review awaiting non-author APPROVE from ${TEAM} team (candidates: $(echo "$CANDIDATES" | tr '\n' ',' | sed 's/,$//') — no valid team-member approval found; check that reviewer is in ${TEAM} team or token owner is a ${TEAM} team member)"
exit 1