fix(ensureSCCoreDevApproval): re-evaluate core-dev-approval on PR lifecycle events (draft-skip bypass)#2035
fix(ensureSCCoreDevApproval): re-evaluate core-dev-approval on PR lifecycle events (draft-skip bypass)#20350xDEnYO wants to merge 3 commits into
Conversation
…e events so draft-time skips cannot satisfy branch protection Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
WalkthroughThe Smart Contract Core Dev approval workflow now runs on more pull request and review events, cancels superseded runs for the same pull request, and executes for draft pull requests instead of skipping them. ChangesSmart Contract Core Dev approval workflow
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…eck can never conclude skipped Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
.github/workflows/ensureSCCoreDevApproval.yml (1)
18-20: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winMove permissions to per-job scope with workflow-level default-deny.
The path instruction requires
permissions: {}at the workflow level (default-deny) and minimal scopes granted per-job, each with an inline "why". Currently,pull-requests: readandcontents: readare granted at the workflow level instead.As per path instructions,
.cursor/rules/500-github-actions.mdcrequires: "Use least-privilege permissions: setpermissions: {}at the workflow level (default-deny) and grant minimal scopes per-job, each with an inline 'why'."🔒 Proposed refactor for least-privilege permissions
permissions: - pull-requests: read # required to read PR reviews and metadata - contents: read # required to read local workspace contents (e.g. access tmp file) + {} concurrency: group: core-dev-approval-${{ github.event.pull_request.number }} cancel-in-progress: true jobs: core-dev-approval: + permissions: + pull-requests: read # required to read PR reviews and metadata + contents: read # required to read local workspace contents (e.g. access tmp file) # no draft condition on purpose — a skipped run counts as passing for branch protection runs-on: ubuntu-latest🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/ensureSCCoreDevApproval.yml around lines 18 - 20, Set the workflow-level permissions to an empty mapping for default-deny, then add a permissions block under the relevant job with only pull-requests: read and contents: read, preserving inline comments explaining why each scope is required.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In @.github/workflows/ensureSCCoreDevApproval.yml:
- Around line 18-20: Set the workflow-level permissions to an empty mapping for
default-deny, then add a permissions block under the relevant job with only
pull-requests: read and contents: read, preserving inline comments explaining
why each scope is required.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 7c9e2a78-c5a6-4df0-a6e6-8b7b26d80535
📒 Files selected for processing (1)
.github/workflows/ensureSCCoreDevApproval.yml
Which Linear task belongs to this PR?
No Linear task yet — direct follow-up to the PR #2010 merge-gate incident (core-dev approval check bypassed).
Why did I implement it this way?
Incident: #2010 merged with only a
lifi-qa-agentapproval. The bot approved while the PR was a draft, so thecore-dev-approvaljob (job-levelif: draft == false) was skipped — and GitHub counts a skipped check run as passing a required status check. The workflow's only trigger waspull_request_review: submitted, so marking the PR ready never re-ran it; the stale skipped verdict on the head SHA satisfied branch protection and auto-merge fired.Fix: add
pull_requestlifecycle triggers (opened,reopened,ready_for_review,synchronize) andpull_request_review: dismissed:ready_for_review, which replaces the skipped check run on the same SHA with a genuine pass/fail; pushes re-run it (closing the gap wheredismiss_stale_reviewsinvalidated the approval but not the green check).skipped, so the skipped-counts-as-passing failure mode is structurally impossible rather than dependent on trigger choreography staying correct. A red check on an unapproved draft is honest signal; it goes green the moment a core dev approves.concurrencygroup so rapid review/push events don't stack duplicate runs.Note for reviewer: bot approvals still satisfy GitHub's native 1-approval rule by design — the decision (Daniel, 2026-07-10) is that this hardened core-dev check is the enforcement layer, so it must never be bypassable.
Checklist before requesting a review
/pr-ready(local CodeRabbit) on this branch and resolved (or explicitly documented) all findings — see.agents/commands/pr-ready.md(gate bypass sanctioned while chore(pr-ready): remove local CodeRabbit pre-flight gate repo-wide #2020 is open; CI + cloud CodeRabbit will review)Checklist for reviewer (DO NOT DEPLOY and contracts BEFORE CHECKING THIS!!!)