ci: seed cross-family review status - #27
Conversation
Cross-Family Adversarial Review
Adversarial Review — PR #27
|
Ready-State Cross-Family Adversarial Review
Cross-Family Adversarial Review — PR #27
|
| Claim | Evidence | Status |
|---|---|---|
pull_request_target from base copy |
cross-family-review-status.yml:4 |
✅ pull_request_target workflows always execute the base-branch copy of the file, so the PR's own version of this file is not active for PR #27 — it only takes effect once merged. |
| No checkout / no PR-code execution | No actions/checkout; run: block (:27–39) only computes a string and calls gh api |
✅ Nothing untrusted is fetched or run. |
| Pending-only seeding | :36 -f state=pending (both branches of the if only change description, :30/:32) |
✅ State is hard-coded pending; the ready_for_review branch alters only the description text. |
| No success/failure authority | Workflow never posts success/failure/error |
✅ It cannot self-approve. |
Additional hardening confirmed:
- Minimal token blast radius —
permissions: statuses: write(:7–8) is the only grant; GitHub sets every other permission tonone. Even with the base-context token thatpull_request_targetprovides, this token can touch nothing but commit statuses. - No script-injection surface — all attacker-reachable values are passed through
env:(:21–26) and referenced as quoted shell variables (${HEAD_SHA},${PR_URL},${EVENT_ACTION}), not interpolated as${{ }}insiderun:. Moreover every interpolated field (head.sha,html_url,action,repository) is GitHub-generated, not free-text, so even the env values are not injectable. - Correct target commit — it posts to
github.event.pull_request.head.sha(:24), the exact PR head that branch protection evaluates, notgithub.sha(which underpull_request_targetis the base merge commit). This is the "exact-head" property the scope requires. - Fails closed —
cancel-in-progress(:12) can cancel a seed job, and re-seeding pending onreopened/ready_for_review/synchronizeonly ever moves the gate towardpending. Pending (or a missing required check) blocks merge, so every reachable transition tightens rather than loosens the gate.
Live-state consistency
The cross-family-adversarial-review context currently reads SUCCESS (targeting issue comment #issuecomment-4778081865) on head cc343a8. This is consistent with the design: this workflow only seeds pending, so the SUCCESS was necessarily posted by the external review authority, not by this workflow. The Codex validation ("status was posted successfully for head cc343a8") is therefore not contradicted by the diff. Head SHA cc343a8 and draft=false both match the live metadata.
Residual (non-blocking) risks
- Gate effectiveness is out of band. This workflow only seeds the status; it does nothing unless branch protection on
mainmarkscross-family-adversarial-reviewas a required status check. That config is not in this packet. Evidence needed: confirm branch-protection requires this context (and ideally requires it on the exact head), otherwise the workflow is cosmetic. - Status identity is not constrained. Any actor/workflow with
statuses: writeon the repo can postsuccessfor this context and satisfy the gate; GitHub's status model has no notion of "trusted poster." This is inherent, not a defect of this file, but worth recording as the gate's trust assumption. - The current SUCCESS cannot be authenticated from this packet. I can confirm this workflow did not and cannot post it; I cannot prove from the packet that the SUCCESS on
cc343a8came from a legitimate exact-head review versus a manual/forced status. The issue-comment targetUrl is consistent with a real review but not verifiable here. - No re-seed on
converted_to_draft/edited. Not security-relevant (those don't change head SHA), noted only for completeness — seeding logic correctly keys off head-SHA-changing events plus the explicitready_for_reviewreset.
Recommendation
Safe to merge from a workflow-hardening standpoint. Before relying on it as a gate, confirm residual item #1 (branch protection requires the cross-family-adversarial-review context).
Summary
pull_request_targetworkflow that seeds the required externalcross-family-adversarial-reviewcommit status aspendingSecurity Model
statuses: writestate=pendingto contextcross-family-adversarial-reviewgithub.event.pull_request.head.shaValidation
git diff --check6b2426b378578d629b2466270ee507485af517278f23b0945445b484e96b8ad8pull_request_target, which takes effect for future PRs once this workflow exists onmain