Repository navigation
ci(pages): reconcile owned deployment records safely - #1029
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🤖 CodeAnt AI — Review Status
|
Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
🏁 CodeAnt Quality Gate ResultsCommit: ✅ Overall Status: PASSEDQuality Gate Details
|
Reviewer's GuideThis PR replaces broad workflow_run-based deployment deletion with a daily, main-schedule-only reconciliation that authorizes only positively identified GitHub Pages records, preserves publication and incident holds, revalidates every mutation, and fails closed on ambiguous inventories or API outcomes; it also adds extensive regression coverage and operational documentation while leaving the workflow disabled pending separate owner approval. Sequence diagram for safe GitHub Pages record reconciliationsequenceDiagram
participant Scheduler
participant Workflow
participant Reconciler
participant GitHub
Scheduler->>Workflow: Daily schedule
Workflow->>Reconciler: runAction(github, context, holds, workflowRef)
Reconciler->>Reconciler: admission(repository, ref, sha, workflowRef, eventName)
Reconciler->>GitHub: GET Pages configuration
GitHub-->>Reconciler: Pages site identity
Reconciler->>GitHub: GET deployments and statuses
GitHub-->>Reconciler: Complete inventory
Reconciler->>Reconciler: planPruning(records, holds)
Reconciler->>GitHub: GET successful CI run and Pages job
GitHub-->>Reconciler: Publication evidence
loop Each bounded candidate
Reconciler->>GitHub: GET fresh inventory and main branch
GitHub-->>Reconciler: Unchanged identity and hold evidence
Reconciler->>GitHub: POST deployment status inactive
GitHub-->>Reconciler: Inactivation result
Reconciler->>GitHub: GET fresh inventory and statuses
GitHub-->>Reconciler: Revalidated inactive record
Reconciler->>GitHub: DELETE deployment
GitHub-->>Reconciler: Deletion result
end
Flow diagram for trigger admission and fail-closed behaviorflowchart TD
A[Reconciliation trigger] --> B{Own repository, main ref, trusted workflow?}
B -- No --> C[Refuse execution]
B -- Yes --> D{Event is schedule?}
D -- No: workflow_dispatch --> E[Read-only dry run]
D -- Yes --> F[Read complete Pages inventory]
F --> G{Inventory, identity, status, and publication evidence unambiguous?}
G -- No --> H[Stop and report follow-up]
G -- Yes --> I[Protect newest three, current, previous, and explicit holds]
I --> J[Select up to ten owned candidates]
J --> K[Revalidate candidate before mutation]
K --> L{Still unchanged and main SHA current?}
L -- No --> M[Skip candidate or stop]
L -- Yes --> N[Inactivate record]
N --> O{Inactivation succeeded and response valid?}
O -- No --> P[Do not delete; stop failed closed]
O -- Yes --> Q[Revalidate complete inventory]
Q --> R{Candidate remains safe?}
R -- No --> S[Skip or stop; require later pass]
R -- Yes --> T[Delete deployment]
T --> U[Report confirmed partial outcomes]
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
[check-pr-size] PR size is over the hard tier (normal profile): 15 files, 2884 meaningful lines, 15 commits — limit ≤20 files / ≤1200 lines / ≤10 commits. Consider splitting into smaller, independently reviewable PRs. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Priority: ➖ Normal Severity of issue fixed: Medium Merge Risk: ⚪ Minimal · up to
|
|
@codex review Please assess the exact final delta at |
|
@CodeAnt-AI review Final head: |
CodeAnt PR Risk: Medium Risk
Assessed commit: |
|
Question: review final head: Answer: Finding[P1 — before workflow enablement] The preflight checks are not atomic with the writes —
This is an inherent API boundary rather than something another read can eliminate. The docs disclose the status race, but should also make clear that the main-hold check has the same gap and that a post-write recheck cannot reverse an inactivation. Since the workflow remains disabled and enablement is separately owner-gated, this is not an immediate deletion risk from merging; I would treat explicit owner acceptance and a decision about writer quiescence or snapshot semantics as a prerequisite to enablement. The ownership checks, current-publication proof, bounded sequential writes, and fail-closed handling of ambiguous API outcomes otherwise look consistent with the stated policy. |
There was a problem hiding this comment.
Actionable comments posted: 2
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository: qnbs/WorldScript-Studio/.coderabbit.yaml
- Review profile: CHILL
- Plan: Essentials
- Run ID:
a7786ed6-4311-4085-824b-06ba23a044a4
📒 Files selected for processing (8)
.github/pages-pruning-holds.json.github/workflows/prune-deployments.ymlCHANGELOG.mdREADME.mddocs/PAGES-DEPLOYMENT-RECORD-PRUNING.mdscripts/prune-pages-deployments.mjstests/unit/tooling/prunePagesDeployments.test.mjstests/unit/tooling/prunePagesDeployments.test.ts
Included review availability: This review used your included allowance. 1 included review remains after this review. Your included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a06078dd98
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Resolve the independent-review findings on the Pages record reconciler.
Rollback slot: the current and previous publication are now proven against
the API before any candidate is classified. An unproved newer success is
protected and no longer consumes the rollback slot; no provable rollback
stops the run instead of exposing the prior known-good record.
Provenance: log_url is caller-written, so a record is deletable only when
the deployment and its newest success status were authored by the actor of
the referenced run and not by github-actions[bot]. This holds for all six
live records. A candidate that cannot be proven is protected and skipped
rather than failing the whole run.
Writer fence: GitHub has no compare-and-delete. A stale snapshot is shown
to stay safe against genuine publications, and in-repository record
writers are pinned by a test. Hold changes and external status writers
remain unfenced, so destructive writes stay closed in code and the
workflow token holds deployments: read only.
Scale: revalidation re-reads the list plus the candidate and both slots
instead of every history. A run is budgeted at 450 requests with a live
rate-limit reserve and a graceful stop. /repositories/{id} next links are
accepted for the verified repository id only.
Complexity: split into evidence, policy, github, provenance and reconcile
modules with single-purpose predicates.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 031072076a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
@CodeAnt-AI review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 97206e2c4e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…e the posted inactive status, keep the manifest when a slot proof fails funds() moves to the GitHub client so the proof scan, the POST and a DELETE without POST share one local-plus-live budget check. The status created by this run must come back as a recognised inactive Pages status before the DELETE. A stopped slot proof still reports every record as protected or unexamined.
|
@CodeAnt-AI review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cdfd0495ed
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…o the run SHA, accept the documented workflow path form, stop gracefully on a pre-write budget refusal Failed reads and writes update the live allowance the scan and the write gates use. The job must report the same head SHA as its run. The CI workflow path matches with or without the documented main suffix. A request-budget refusal before a candidate's first write ends the pass as a budget-limit stop. prepareOrReport takes one input object to stay inside the argument limit.
|
@CodeAnt-AI review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2b1e677467
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
read() refuses with rate-reserve before a request that would leave fewer than 100 requests, retries and the whole inventory included, and with rate-unknown once a response succeeded without a rate header. A budget or reserve refusal before a candidate's first write ends the pass gracefully. The fixture answers with a rate header like the real API.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dec972c203
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ce unknown A successful response replaces the live allowance, so one that omits or malforms the header no longer leaves a stale value behind and the next read fails closed. Override responses in the fixture carry the default allowance like the real API.
There was a problem hiding this comment.
Gates Passed
3 Quality Gates Passed
See analysis details in CodeScene
Quality Gate Profile: The Bare Minimum
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 064e665add
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
User description
GitHub deployment-record pruning currently applies retention to every environment and can attempt deletion after failed inactivation. This change confines authority to positively identified
github-pagesrecords, keeps the newest three plus current/previous publication and explicit holds, and stops on ambiguous inventories or API outcomes.Daily reconciliation replaces privileged
workflow_runfollow-ups. Only own-repository main schedule executions can write; manual dispatch and the local CLI are read-only. Each inactivate/delete operation repeats complete inventory, identity/status, successful main-push Pages job and immutable-main hold checks. Writes are serialized, limited to ten records, and never blindly retried.References #1028 (implementation owner); #550/QNB-41 (measurement). This PR does not close #1028 or enable the manually disabled workflow. The six existing records are explicit incident-evidence holds pending owner disposition. Other environments, provider objects, required CI, signing and reviewer governance are unchanged.
Validation on the prepared delta:
node --test --test-reporter=spec tests/unit/tooling/prunePagesDeployments.test.mjs: 73 passed. Cases include retention/ties/holds, wrong environments and ownership, untrusted events and publication evidence, complete/truncated pagination, failed writes/GET exhaustion, 404/409/429/5xx, stale identity/status/main, partial outcomes, bounded batches, idempotence and zero-write dry-run.Measured cohort: 2026-10-05 through 2026-10-11 UTC, exhaustive Actions pagination. 308 completed CI runs (214 PR, 93 push, 1 manual); 52 successful main-push runs had a successful Pages deploy job. Thus 256 old completion-trigger opportunities lacked that publication evidence. 256 actual prune runs were observed, all
workflow_run; these counts do not prove a one-to-one mapping to the 256 unnecessary opportunities. Assuming enabled operation and the same cohort, old automatic starts would be 308 completions + 1 weekly cron = 309, versus 7 daily starts (302 fewer, ~97.7%). No savings are yet realized while disabled; CPU minutes and dollars were not measured.Independent final-delta review must specifically assess ownership/current-publication proof, immutable-main hold admission, each write boundary and partial-failure accounting. GitHub exposes no conditional status-version POST/DELETE transaction: fresh reads detect observed races, but there is a residual interval between the last read and a write. Pruning concurrency does not serialize the publisher or external status writers. This limitation must be reviewed substantively rather than inferred safe from green CI.
Operational hold: after normal protected merge, verify resulting-main CI/CodeQL/Production, repeat a zero-write dry-run, reconcile evidence holds, and obtain separate explicit owner approval before enablement or a first controlled real pass. No enablement, real record deletion, historical non-execution claim, support communication or Vercel mutation is performed here.
Summary by cubic
Replaces broad CI-completion deployment-record pruning with a daily, fail-closed reconciliation that only touches positively identified
github-pagesrecords. Keeps the newest three records plus the current and previous successful publication and explicit rollback/evidence holds; failed inactivation never reaches deletion.pushandworkflow_dispatchonmain, matches authors by account id and login together, requires the classifier's pages-status shape and site ownership, and binds the referenced job's head SHA and workflow path to its run; scans past unprovable records until 20 are proven, and keeps unprovable or status-blocked records protected and listed in the manifest.github.comtoken explicitly.mainwrite at most ten records per pass; manual dispatch and the local CLI are read-only dry-runs.docs/PAGES-DEPLOYMENT-RECORD-PRUNING.md; the workflow'sCI-AUDIT.mdinventory row is pinned by a test. The workflow remains disabled pending separate owner approval. References ci(pages): restore safe continuous GitHub Pages deployment-record pruning #1028 (implementation) and ci(efficiency): reduce redundant cost and latency without weakening required quality/security gates #550/QNB-41 (efficiency measurement).Migration
Written for commit 064e665. Summary will update on new commits.
Summary by Sourcery
Replace broad deployment pruning with a fail-closed, evidence-checked GitHub Pages reconciliation that remains read-only until separately approved.
New Features:
Bug Fixes:
Enhancements:
CI:
Documentation:
Tests:
Chores:
Summary by CodeRabbit
main. Reports identify records that may be eligible for cleanup while protecting the three newest records, proven current and rollback publications, and evidence-backed records.CodeAnt-AI Description
Add read-only, evidence-checked GitHub Pages deployment reconciliation
What Changed
Impact
✅ Zero deployment deletions while the write gate is closed✅ Production and preview records remain untouched✅ Unverified Pages publications remain protected💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.