Repository navigation
ci(vercel): prune stale Preview deployments after PR closure #627
Description
CURRENT RETENTION CHECKPOINT — 2026-10-06 — DEPENDENCY-TRAIN FINAL RETENTION TERMINAL
FINAL_MAIN = bf745090f7e980e167b1bbf01c7f6dea51fb451f
FINAL_MAIN_CI_CD = 37434052556 / SUCCESS
FINAL_MAIN_CODEQL = 37434052501 / SUCCESS
PRODUCTION = dpl_75HQcQhuYP6CxX43EjMov8Sjosdb / READY / exact FINAL_MAIN / canonical HTTP 200
ROLLBACK = dpl_7XTy9jGDikUauvgT8oPQUtq7YAmq / READY
DELETED_DEPLOYMENTS = 11
ALREADY_ABSENT = 2
ORPHAN_ALIASES_REMOVED = 79
FINAL_DEPLOYMENTS = 4
FINAL_ALIASES = 3 / exactly the protected Production/Main hosts
UNKNOWN = 0
OPEN_PULL_REQUESTS = 0
TRAIN_FINAL_RETENTION_COMPLETE = YES
RETENTION = TERMINAL
The two older retained target=production / PROMOTED deployments remain protected by current policy; changing that policy is a separate decision. This issue stays open as the standing retention-policy/automation owner. Routine cleanup is terminal for the current dependency train and no longer blocks R-15 read-only R4 admission.
HISTORICAL / SUPERSEDED RETENTION CHECKPOINT — 2026-10-04 — #957 CLEANUP WITH #958 OPEN-PR PROTECTION
CURRENT_MAIN = 8f1400c4bb6a84be8da940584b86b00233df1d4b
RESULTING_MAIN_CI_CD / CODEQL = SUCCESS
#957_RETENTION_COMPLETE = NO
#957_PREVIEW_CANDIDATES = 5
PR_958 = OPEN
PR_958_HEAD = 0eac3d4c10ddd854eee9027db038f55899b66caf
PR_958_PREVIEW = PROTECTED OPEN-PR PREVIEW
DELETE_PR_958_PREVIEW = NO
SEQUENCE_DRIFT = #958 opened before retention terminal
RETENTION_SCOPE = delete only revalidated #957 previews; preserve #958 and all other open-PR previews
NEXT = complete #957 retention → post-cleanup proof → release #958 freeze
Problem
The existing .github/workflows/prune-deployments.yml prunes GitHub Deployment records, but it does not remove the corresponding Vercel Preview deployment artifacts. A bounded live housekeeping pass confirmed that stale previews can accumulate after merged or closed pull requests.
Required policy
- never delete Production deployments or Production/Main aliases;
- retain the newest three Preview deployments for each open PR, including its active branch alias;
- after a PR is merged/closed, remove its Preview deployments after a bounded grace period when no active alias or review evidence requires them;
- remove stale failed/canceled previews only after confirming they are detached from active work;
- classify unknown metadata conservatively and never delete it blindly;
- perform a dry-run manifest, rate-limited authenticated API deletion, and post-cleanup verification;
- redact creator emails and tokens from logs/reports.
Scope
Design the smallest authenticated Vercel API/CLI housekeeping integration or documented operator workflow. Preserve Production, domains, project settings, environment variables, rollback history, and active review previews. Do not change deployment creation or promotion semantics.
Activity
qnbs commentedon Sep 6, 2026
Vercel retention reconciliation after #628 resulting-main 872b6f4: project/team/repository scope matched, Production remained READY with its protected aliases, and no open PRs were present. Twelve non-Production Preview deployments were classified by closed/merged PR or branch lifecycle; each still carries a branch alias, so the merged policy's no-protected-alias gate did not prove deletion safe. No alias or deployment was deleted.
Carry-forward for #627: future automation must explicitly reconcile orphaned closed-PR/branch aliases before any per-ID deletion, with the same current-main, target, terminal-state, project/team/repository, rollback/promotion, open-head, review-evidence, alias and post-delete revalidation gates. Preserve ambiguous alias state as UNKNOWN_REVIEW_REQUIRED; never use a broad fallback.
qnbs commentedon Sep 20, 2026
2026-09-20 live incident — Vercel Deployment Storage reached 100% of Free allowance
Vercel reported that team
qnbs-projectshas reached 100% of the included 10 GB Deployment Storage allowance.Live reconciliation against project
worldscript-studio/prj_XJDiKIlKNg5sbmw6xMHIlf6glXHyfound:Current main:
1451f88151fa68eafbf57cd020287b72a5268de3Exact-main gates:
Verified stale Preview candidates
All seven candidates are:
target = nullREADYdpl_GBAgfdXRHDG4KjwWD24o3exGtNVuchore/dependabot-dev-tooling-minor-patch-20260920dpl_4iNPbk8myDZ9bM2dc2NK8QaS8L3Jchore/dependabot-vitest5-linear-20260920dpl_6VW14jvUnZZRnxRtpc7ojrFLAvqmdpl_HiwugtsjCC93TeEuE2Tuxed2ZnRMdpl_HGwub3FTHn4APaEbZopSZ7pDBX2cdependabot/npm_and_yarn/dev-tooling-c9c26bdfd5dpl_AmzcJ4cA29hT7ERBXZFcYzgwmCjtfeat/553-d1-idb-canonical-authority-20260917dpl_8BjP9SYK7dH7tugLBPmratbL6RwVEach currently still carries only a branch-specific Preview alias. Those aliases are also orphaned because the owning branch/PR is gone.
Per
docs/VERCEL-PREVIEW-RETENTION-POLICY.md, remove the orphaned non-Production alias first, revalidate exact-main/open-PR protections, then delete the explicit deployment ID.Do not delete the seven Production deployments or any of the 11 current open-PR Preview deployments.
Tooling limitation observed
The connected Vercel MCP surface currently exposes deployment enumeration/details but no deployment/alias delete action. Vercel's supported authenticated write path is the CLI/REST API:
GET /v4/aliases?projectId=<project>&teamId=<team>DELETE /v2/aliases/{aliasId}?teamId=<team>DELETE /v13/deployments/{id}?teamId=<team>vercel api /v13/deployments/<deployment-id> -X DELETEThis incident should be used to finish #627 with a bounded authenticated cleanup/retention path so stale merged-PR Previews do not repeatedly exhaust Deployment Storage.
qnbs commentedon Sep 22, 2026
2026-09-22 housekeeping — prior deployment counts are historical; live lifecycle has moved
The 2026-09-20 incident comment's exact deployment counts were a point-in-time snapshot and must not be read as current inventory.
Current live reconciliation at this housekeeping checkpoint:
main=21460657cba475317306e99dfd32cf95479916b1, produced by merged PR build(deps): bump ai from 7.0.91 to 7.0.101 #795;READY;dependabot/npm_and_yarn/ai-7.0.99are now closed-PR lifecycle candidates, subject to the existing alias/rollback/review-evidence safety gates;No deployment or alias was deleted during this documentation pass.
The durable policy remains unchanged:
#627 remains OPEN / P2 because the long-term authenticated retention/cleanup mechanism is still not terminal.
qnbs commentedon Sep 23, 2026
2026-09-23 live housekeeping reconciliation — retention pressure and alias semantics
Fresh live state after PR #817:
Current Production is
dpl_9TpNZYVzmRQzPhYrvXeab6Aa3spMfrom the current main SHA. The immediate predecessordpl_3w8mCTRMeBE548cR534JteeTmG3hremains rollback-relevant. All 28 current Preview deployments map to terminally merged PR branches, including #817, #816 and merged Dependabot work.A bounded manual retention pass is being executed separately after local cleanup. That manual cleanup does not close #627; this issue remains the long-term authenticated automation/policy owner.
Policy inconsistency now requiring explicit resolution
The current repository policy treats an active branch alias as protected and, for stale orphan aliases, describes alias removal before deployment deletion. Current live/operator evidence for terminal merged-branch Preview aliases instead supports an alternative provider-safe flow: delete the explicitly revalidated unique Preview deployment, then re-list aliases and remove only an actually dangling terminal-branch alias if one remains.
Do not let automation encode both orderings implicitly.
Before #627 closes, choose and test one provider-truthful alias/deployment deletion contract using live Vercel semantics:
The admitted implementation must prove that Production/main aliases, rollback history, open-PR review evidence and unrelated aliases cannot be removed under either lifecycle race.
Additional acceptance evidence from this incident
#627 remains OPEN / P2 after the manual pass because prevention/automation is not yet terminal.
qnbs commentedon Sep 24, 2026
2026-09-24 post-#830 retention catch-up checkpoint
PR #830 is merged and its exact resulting main is now terminal green:
The mandatory lifecycle in
docs/VERCEL-PREVIEW-RETENTION-POLICY.mdtherefore requires a retention reconciliation now. This was not completed before the next #553 worktree/PR was started, so perform it as a catch-up maintenance wave before further dependent source mutation. Existing CI/reviews for the already-open next PR may continue; do not use retention as a reason to cancel useful provider work.Current visible provider snapshot
The connected Vercel listing exposes the newest page of 20 deployments only; 20 is not asserted as the full project inventory. Full pagination remains required.
Protected current work visible on that page includes:
dpl_5fyqAhcVhbzGFRWALgiEeWgvp52T@0371a67f…dpl_FsfWviz5wyDrTAAoJRo7Zb1sVNum@2f7f57ba…dpl_HsYtey7nLKGtGrC3qNmoYBxrsLSn@b05dbdb4…Visible lifecycle candidates only — not pre-authorized deletes — include multiple non-Production READY previews from terminal PRs/branches, for example:
fix/553-stale-writer-refusal:dpl_EJjPrJQetVmSqPos18jFnJf4B5uL,dpl_E27p4eqCjykHBrzTcbNVNzzekvA6,dpl_83UVZnsHXR3Kkt2GLmfbWW7JH9vV,dpl_6BPF7M2vUfWekhTp9QJzVzaPUA5efix/553-native-write-lock: multiple visible historical preview generationsdpl_53VScEG5rZGUUoGqAAo9sChd1yRMdpl_GnH3wHBco5TSA5FvcVUkeVDyWXuoEvery such item must still pass the policy's live alias, branch/PR lifecycle, rollback/promotion, current-main/open-head, review-evidence and provider-scope gates immediately before deletion.
Required catch-up execution
main; if it moved from0371a67f…, establish a new terminal-green main gate first.This manual catch-up does not close #627. The issue remains the long-term automation/least-privilege retention owner.
qnbs commentedon Sep 24, 2026
Vercel retention catch-up — post-#830 (2026-09-25)
Gate anchor: current
main=0371a67fb97439a85ac6731b843d4937a56c63c3(PR #830), with terminal-green CI/CD and CodeQL. The anchor was re-read immediately before every individual deletion and never moved.Scope: Vercel, team
qnbs-projects, projectworldscript-studio/prj_XJDiKIlKNg5sbmw6xMHIlf6glXHy, repositoryqnbs/WorldScript-Studio. Verified per deployment. Enumeration was fully paginated (single page, nonext).Dry-run classification (43 deployments, all READY):
dpl_5fyqAh…holding the Production +mainaliasesdpl_FsfW…(head2f7f57ba), draft #829dpl_HsYt…(headb05dbdb4)dpl_GnH3…(branch deliberately retained), #820 newestdpl_9RpT…(branch still exists)The 24 deletions:
All 24 were
readySubstate=STAGED(never promoted), not currentmain, and not an open-PR head.Execution: each explicit ID was revalidated immediately before deletion:
mainanchor, project identity, target, READY state, non-PROMOTED, not current-main or an open-PR head, PR MERGED/CLOSED, and alias set unchanged. Deletion used per-IDvercel alias rm <alias>andvercel remove <id> --safe --yes; there was no project-wide remove, promotion or rollback. 24/24 DELETE_CONFIRMED, 0 reclassified.dpl_86WG8iN1cZavwfFHmhHDmE91sXJA-dpl_H69qcVSwMVa7aw8vSqYV7QPp8LeY-dpl_J2jXBgTqKBL4diUNsjKLHcJFkjCj-dpl_8WsSEQzFuUUEvxb8ZCSaHv7cKruo-dpl_9aHpHUuSh5wNH2fkEnkAkee6EimC-dpl_4BVTHxi9rgNgVWV4LcS9DDhKMjsX-dpl_BdEuJ2C1pxGE7s4prNkNERdxFizn-dpl_6a36YDM2a39jKbLzpjCsKYFiuqJ3-dpl_5ySxAHPsS6dXnRu1ze3ckBq14Lb3-dpl_EyrxRH3ArVPxNAteneVvBs9ZqBPQ-dpl_ANaUazewAiNnUqsxLiYsRHPXjcYx-dpl_Acw7k396eF2jiqL6qSgfBR3rWtGT-dpl_CqYoqDYo1QPTaktvstmH1PvABkd9-dpl_9Xt6CU96VpBqF7bvVEeArZRFjfbY-dpl_6BPF7M2vUfWekhTp9QJzVzaPUA5e-dpl_83UVZnsHXR3Kkt2GLmfbWW7JH9vV-dpl_E27p4eqCjykHBrzTcbNVNzzekvA6-dpl_EJjPrJQetVmSqPos18jFnJf4B5uL-dpl_53VScEG5rZGUUoGqAAo9sChd1yRM-dpl_Eb414YswbLxLbPYvmtfWKRozx5Ky-dpl_5FNsE4G9RXgh24r5dUv1vhqZYRx2-dpl_F57W1gdzo8obMge1YYNByvwPZoxy-dpl_FF1daxqTFKHVJw4S91UybmaxYdQU-dpl_4fc2os68cV4rZQZGqTERC66ViQevPost-cleanup proof:
mainalias binding and all four protected branch-alias bindings unchanged;https://worldscript-studio.vercel.app→ 200, and fix(persistence): make superseded lifecycle flushes observe their chain's real outcome (#553) #832's Preview alias → 200;Creator identity
qnbs; no emails, tokens or secret values were recorded.qnbs commentedon Sep 25, 2026
Retention after #832 merge (main
164f23fa, CI + CodeQL terminal green).fix/553-flush-final-outcomeis gone on the remote, each ID's target was re-checked aspreviewbefore removal, then removed withvercel remove --safe):dpl_5YyLhyoTjAp7EZu97ymzFRMZGcE4,dpl_41i7R9n2V1AbqToY5c9LZXDuxAsV,dpl_FsfWviz5wyDrTAAoJRo7Zb1sVNum. The branch alias was removed first. After removal,inspectreturns not-found for all three.dpl_HsYtey7…(draft feat(core): R-15 Gate 1a headless WSR1/AAD/AES-256-GCM primitive (#445) #829, still open);dpl_GnH3wHBc…(fix(reset): delete the DuckDB analytics OPFS file on Factory Reset (#716) #827 branch deliberately kept);dpl_9RpTHokR…(chore(repo): codify preserve-first housekeeping and local tooling hygiene #820 branch, active alias).refs/rescue/housekeeping-20260925/pr832-preamend-88de5a93created;.worktrees/553-flushremoved (it held only ignored, regenerable files); local branch deleted, bound to the verified SHAb81d388c(same tree as the squash commit).qnbs commentedon Sep 25, 2026
Retention after #833 merge (main
3244242e, CI/CD + CodeQL terminal green: 16 success, 4 skipped).fix/553-aux-write-fenceis gone on the remote. The branch alias was removed first. Each ID's target was re-checked aspreview, then removed withvercel remove --safe; afterwardsinspectreturns not-found. IDs:dpl_27d44LHC…,dpl_GFejCQ66…,dpl_5LqVTycG…,dpl_4TtjmEh5…,dpl_2mPWZKCS…,dpl_5jyES5j5…,dpl_DwTTaAfu…,dpl_99w8vwvC….dpl_HsYtey7…(draft/HOLD feat(core): R-15 Gate 1a headless WSR1/AAD/AES-256-GCM primitive (#445) #829);dpl_GnH3wHBc…(fix(reset): delete the DuckDB analytics OPFS file on Factory Reset (#716) #827 branch retained);dpl_9RpTHokR…(chore(repo): codify preserve-first housekeeping and local tooling hygiene #820 active alias).154ce4abhas the same tree as squash3244242e. Rescue refs:refs/rescue/housekeeping-20260925/pr833-tip-154ce4abandpr833-preamend-d59c438c..worktrees/553-auxremoved (ignored files only); local branch deleted, bound to the verified SHA.qnbs commentedon Sep 25, 2026
Retention after #835 merge (main
8b270ea7, CI/CD + CodeQL terminal green: 16 success, 4 skipped).…git-fix-553-project-inc-2ede34…removed first. The deployment's target was re-checked aspreview, then removed withvercel remove --safe; afterwardsinspectreturns not-found. ID:dpl_7nYE5MZPqxRLdCwBkkruFxbfPpDD.dpl_HsYtey7…(draft/HOLD feat(core): R-15 Gate 1a headless WSR1/AAD/AES-256-GCM primitive (#445) #829);dpl_GnH3wHBc…(fix(reset): delete the DuckDB analytics OPFS file on Factory Reset (#716) #827 branch retained). The chore(repo): codify preserve-first housekeeping and local tooling hygiene #820 preview no longer appears in the listing.8b270ea7. Rescue refrefs/rescue/housekeeping-20260925/pr835-tip-a22a61cb. Worktree removed (ignored files only); local branch deleted, bound to the verified SHA.qnbs commentedon Sep 25, 2026
Retention after #837 merge (main
5adef443, CI/CD run 36123834671 success, CodeQL run 36123834736 success).fix/553-canonical-egressis gone on the remote. Branch alias removed first. Each deployment's target was re-checked aspreview, then removed withvercel remove --safe; afterwardsinspectreturns not-found. IDs:dpl_7exB8y1z…,dpl_GaSYGWUz…,dpl_5CY7AfPD…,dpl_GHYHETkN…,dpl_6b7Cnrnx….worldscript-studio.vercel.app→ target production);dpl_HsYtey7…(draft/HOLD feat(core): R-15 Gate 1a headless WSR1/AAD/AES-256-GCM primitive (#445) #829);dpl_GnH3wHBc…(fix(reset): delete the DuckDB analytics OPFS file on Factory Reset (#716) #827 branch retained).2902795ahas the same tree as squash5adef443. Worktree and branch removed; its rescue ref was also removed as redundant (identical tree). Separately, redundant rescue refs for fix(fs): refuse stale-window image, binder and codex writes (#553) #833/fix(fs): refuse writers from a deleted-then-recreated project incarnation (#553) #835 were removed (tree-equal to their squashes), and the fix(fs): refuse stale-window image, binder and codex writes (#553) #833 pre-amend ref was removed (it differs only in README metrics from an ancestor of the merged tip).qnbs commentedon Sep 25, 2026
2026-09-25 post-#838 retention inventory — cleanup pending
Gate anchor is now terminal green:
The connected Vercel project was fully paginated at this checkpoint: 24 READY deployments total.
Classification from current provider metadata:
dpl_63GbCkn…on5999f2e0…. Prior Productiondpl_8MQLfGz…on5adef443…is explicitly marked rollback-candidate and remains protected.dpl_HsYtey7…— draft/HOLD PR feat(core): R-15 Gate 1a headless WSR1/AAD/AES-256-GCM primitive (#445) #829, branchfeat/445-gate1-core-aead.dpl_GnH3wHBc…— retainedfix/716-reset-duckdb-opfs-remanencebranch state from the established housekeeping policy/history.dpl_4iHGUwWM5Bw4NmeieU4eZsn31TKa— final reviewed fix(project): keep snapshots as stored text and admit every snapshot restore (#553) #838 head1a015b50…;dpl_8qx3s2peBrWYz9XzhAAKCbAVcFq2— earlier fix(project): keep snapshots as stored text and admit every snapshot restore (#553) #838 head1a7a5902….Both #838 previews are READY, target=preview, and expose the branch alias
worldscript-studio-git-fix-553-snapshot-carrier-qnbs-projects.vercel.app. GitHub no longer has remote branchfix/553-snapshot-carrier.Before deleting anything, the operator must still revalidate immediately:
mainremains5999f2e0…and terminal green;vercel remove --safe;This is a dry-run/provider inventory only. It does not claim the #838 retention cleanup is already complete and does not close #627.
qnbs commentedon Sep 25, 2026
Retention after #838 merge (main
5999f2e0, CI/CD run 36140075846 and CodeQL run 36140075833 success).fix/553-snapshot-carrieris gone on the remote. Branch alias removed first. Each deployment's target was re-checked aspreview, then removed withvercel remove --safe; afterwardsinspectreturns not-found. IDs:dpl_4iHGUwWM…,dpl_8qx3s2pe….dpl_HsYtey7…(draft/HOLD feat(core): R-15 Gate 1a headless WSR1/AAD/AES-256-GCM primitive (#445) #829);dpl_GnH3wHBc…(fix(reset): delete the DuckDB analytics OPFS file on Factory Reset (#716) #827 branch retained).1a015b50has the same tree as squash5999f2e0; worktree and branch removed.qnbs commentedon Sep 25, 2026
Retention after the #839 merge (main
94b68fc1; CI/CD and CodeQL on main success).fix/553-replacement-persistenceis gone on the remote. The branch alias…git-fix-553-replacement-d3cd76…was removed first. Each deployment's target was verified aspreviewwith reffix/553-replacement-persistence(PR 839), then removed withvercel remove --safe.inspectnow returns not-found. IDs:dpl_4NvXENoj…(3f10ce0),dpl_38BoUYtE…(0f90245).dpl_ECq9Ddrj…(target production, Ready; production alias HTTP 200).dpl_HsYtey7…(feat(core): R-15 Gate 1a headless WSR1/AAD/AES-256-GCM primitive (#445) #829 draft/HOLD).dpl_GnH3wHBc…(fix(reset): delete the DuckDB analytics OPFS file on Factory Reset (#716) #827 branch retained).qnbs commentedon Sep 25, 2026
Retention after the #840 merge (main
4e65bd12; CI/CD and CodeQL on main success).fix/553-restore-carrieris gone on the remote. The branch alias…git-fix-553-restore-carrier…was removed first. Each deployment was verified as a preview of reffix/553-restore-carrier(PR 840), then removed withvercel remove --safe;inspectnow returns not-found. IDs:dpl_HNi2rBjV…(c3a5ed7),dpl_JBWSP5pk…(99457a2).dpl_FPRJZgkd…(target production, Ready; production alias HTTP 200).dpl_HsYtey7…(feat(core): R-15 Gate 1a headless WSR1/AAD/AES-256-GCM primitive (#445) #829 draft/HOLD).dpl_GnH3wHBc…(fix(reset): delete the DuckDB analytics OPFS file on Factory Reset (#716) #827 branch retained).68 remaining items
qnbs commentedon Oct 14, 2026
Vercel platform retention, main epoch
0ef59028(PR #1063, squash0ef590280f44c7a13cd873e3b5beedce33167e72). Receipt, nothing replayed from the53dee55cepoch.successon the exact SHA; GitHub Pages deployment record 7079989837success, site HTTP 200; Vercel Production record 7079703197success.dpl_2oxjyDMp697wgFJfq3q6MMfLFTp4(worldscript-studio-43lp08nne-qnbs-projects.vercel.app):Ready, target production, aliasesworldscript-studio.vercel.app,worldscript-studio-qnbs-projects.vercel.app,worldscript-studio-git-main-qnbs-projects.vercel.appbound;worldscript-studio.vercel.appHTTP 200 (the team-scoped alias answers 302, as a protected host).dpl_6ZTGELJenCCNA3jAWWfkNwic1JdQ,dpl_4QCtaJu5V41aZJBS4stQMwrEXWui,dpl_8iAZSXFR7JQmEAhJsB9TsM6Vy9V6,dpl_F4cWASAia9i75KfPuXS23wNR7aJf,dpl_BW9PxUcpyisveC3TRwkufMgv3Yjk,dpl_9EPt7VQE6tJnSpeB66xKs9yFAd2b,dpl_3cWn8jhTbLL7HnASrpBLYJ5a1gwQ. The newest preview of the branch (16f0f1f6) stays PROTECTED because it holds a branch alias; no alias was removed.qnbs commentedon Oct 15, 2026
Vercel platform retention, main epoch
ce3504b9(PR #1064, squashce3504b9a4f7b598abb5cf35fa5e06f6ec846624). Receipt, nothing replayed from earlier epochs.successon the exact SHA; GitHub Pages deployment record 7081101335success, site HTTP 200; Vercel Production record 7080791973success.dpl_HjkvieT8RR5MR5usbkuXuZcdn2XH(worldscript-studio-dgq6jthvb-qnbs-projects.vercel.app):Ready, target production, aliasesworldscript-studio.vercel.app,worldscript-studio-qnbs-projects.vercel.app,worldscript-studio-git-main-qnbs-projects.vercel.appbound;worldscript-studio.vercel.appHTTP 200.qnbs commentedon Oct 15, 2026
Vercel platform retention, main epoch
b9890f8e(PR #1065, squashb9890f8e07b5e32570be72795ec971cc403abb5a). Receipt, nothing replayed from earlier epochs.successon the exact SHA; GitHub Pages deployment record 7083927159success, site HTTP 200; Vercel Production record 7083638926success.dpl_6M9wFQgJrPCic13op6BL1M48Q2dS(worldscript-studio-80m5lifuu-qnbs-projects.vercel.app):Ready, target production, the three canonical aliases bound;worldscript-studio.vercel.appHTTP 200.dpl_VsVUtRQqAhFGkS1K9z5ZJAp2uH8u(a superseded preview of PR feat(core): keep the unchanged pages of the stored predecessor in a streamed capture (#445) #1065, no alias).qnbs commentedon Oct 15, 2026
Vercel platform retention, main epoch
5ccefffd(PR #1066, squash5ccefffd063b2a9c6f309cfcb7cf19de16413582). Receipt, nothing replayed from earlier epochs.successon the exact SHA; GitHub Pages deployment record 7085903505success, site HTTP 200; Vercel Production record 7085517755success.dpl_CqJhX1f561RA8W3Wy3QXJMc2raaL(worldscript-studio-iecnfiv2s-qnbs-projects.vercel.app):Ready, target production, the three canonical aliases bound;worldscript-studio.vercel.appHTTP 200.dpl_DniWosJsFdVAz84HMmoUbJDW3eE7anddpl_6ZP2dvbeER7FjCgdqrHBJHxPCzvV(superseded previews of PR feat(core): judge a takeover against a trusted clock observation (#445) #1066, no alias).qnbs commentedon Oct 15, 2026
Retention receipt — main
fac89b4f(PR #1067, Gate 4 slice H1a-1)Merge: squash
fac89b4fab68c10c19effaa96a62c5fe0db020c8, one parent (5ccefffd), signature verified (GitHubvalid), protected merge on exact headd1aae575(--match-head-commit), 8 PR commits, 14 files.Resulting main: CI / CD run 38717507087
success, CodeQL SAST run 38717506830success. GitHub Pages deployment record 7090040589success, site HTTP 200. Productiondpl_5msrGxdvbTmxnKoejmkvBaQMi5MkREADY,target=production, GitHub deployment record 7089627886 on the exact SHAsuccess. Aliases bound:worldscript-studio.vercel.app(HTTP 200),worldscript-studio-qnbs-projects.vercel.appandworldscript-studio-git-main-qnbs-projects.vercel.app(both HTTP 302 to the Vercel SSO API: team-scoped, deployment-protected, not publicly served; bound, not a failure).Safe-only retention (clean detached worktree at the exact SHA,
cli.mjs dry-runthenreconcile): 7 SAFE (allpr-closed-or-merged, superseded previews of PR #1067:fee2e2a8,f2d3943c,eee49201,15c3a48c,55b32338,026652fd,44b50d8a), 0 UNKNOWN, 0 reclassified, 0 deferred, 7 write attempts, 7 deleted. Post-proof: protected present 37/37, deleted absent, canonical and protected aliases bound, preview states held, deletions still SAFE, production set stable, production READY, HTTP 200. The preview of the final PR headd1aae575stays protected. Production deployments and the two rollback candidates untouched.Not touched: GH deployment-record metadata (#1042) and the Pages pruner (#1028) are separate and unchanged.
qnbs commentedon Oct 15, 2026
Retention receipt — main
ecd6aa4f(PR #1068, Gate 4 slice H1a-2 part 1 of 4: API and isolation)Merge: squash
ecd6aa4fd040360d97b8eb2d3117f94724f972cc, one parent (fac89b4f), signature verified, protected merge on exact headb60dc603(--match-head-commit), 13 files.Resulting main: CI / CD run 38734159750
success, CodeQL SAST run 38734159726success. GitHub Pages record 7092900986success, site HTTP 200. Productiondpl_261wnfkSehrYWmyZrRcRhh4Z3QbDREADY on the exact SHA (GitHub deployment record 7092421659success); aliases bound:worldscript-studio.vercel.app(HTTP 200),worldscript-studio-qnbs-projects.vercel.appandworldscript-studio-git-main-qnbs-projects.vercel.app(HTTP 302 to the Vercel SSO API: team-scoped, deployment-protected, bound).Safe-only retention (clean detached worktree at the exact SHA,
dry-runthenreconcile): 1 SAFE (pr-closed-or-merged, the superseded first-draft preview of PR #1068 at03ad9acc), 0 UNKNOWN, 1 write attempt, 1 deleted. Post-proof: protected present 46/46, deleted absent, canonical and protected aliases bound, preview states held, deletions still SAFE, production set stable, production READY, HTTP 200. The previews of the open stacked PRs #1069 / #1070 / #1071 are protected. Production deployments and rollback candidates untouched; #1042 (GitHub deployment metadata) and #1028 (Pages pruner) unchanged.qnbs commentedon Oct 15, 2026
Retention receipt — main
45ce3d0c(PR #1069, Gate 4 slice H1a-2 part 2 of 5: Unix file removal,test-supportonly)Merge: squash
45ce3d0c5265277c0d5d9ffaff9050ad714123ad, one parent (ecd6aa4f), signature verified, protected merge on exact head586f6638(--match-head-commit), 7 files / 1,109 meaningful lines. Codex was at its usage limit on this head (NO_SIGNAL, not a pass); it had reviewed the earlier heads of the same code (four waves, findings fixed or moved to #1072), CodeRabbit / CodeAnt / CodeScene and the hosted Windows / macOS / Linux evidence cover the head, 0 threads.Resulting main: CI / CD run 38747575127
success, CodeQL SAST run 38747574965success. GitHub Pages record 7095304509success, HTTP 200. Productiondpl_5zFFfoq4RH4FeX7Lp2etRzC6SYpcREADY on the exact SHA (GitHub deployment record 7094695880success); aliases bound:worldscript-studio.vercel.app(HTTP 200), the two team aliases HTTP 302 (Vercel SSO, bound).Safe-only retention (clean detached worktree at the exact SHA): 6 SAFE (
pr-closed-or-merged, superseded previews of PR #1069), 0 UNKNOWN, 6 write attempts, 6 deleted. Post-proof: protected present 50/50, deleted absent, canonical and protected aliases bound, preview states held, deletions still SAFE, production set stable, production READY, HTTP 200. Previews of the open stacked PRs protected; production and rollback candidates untouched; #1042 and #1028 unchanged.qnbs commentedon Oct 15, 2026
Retention receipt — main
1f37cd83(PR #1073, Gate 4 slice H1a-2 part 2b: Unix quarantine hardening,test-supportonly; supersedes #1072)Merge: squash
1f37cd8368e6f647a21cf9d77fbdf20f7748076f, one parent (45ce3d0c), signature verified, tree identical to the validated head1602d79e. Protected merge pinned with--match-head-commit, no admin, 8 files / 1,014 meaningful lines, 3 commits in the PR (own budget). #1072 reached 15/15 commits with two valid P2 open and was closed as superseded, not merged; its branch is kept.Review on the exact head: 0 unresolved threads (the 2 raised by Codex on #1073 were answered and resolved: one fixed with a test, one stated as a documented limit); Codex review completed on
1602d79ewith no unresolved finding; CodeRabbit "no actionable comments" on the full net diff and again on the final delta; CodeAnt Quality Gate passed (risk note Low); CodeScene approved; hosted Windows / macOS / Ubuntu Secure Store evidence, Quality Gate Node 22/24, E2E, CodeQL and✅ CI Successgreen.DEPENDENT_OPEN_PRS=0,delete_branch_on_merge=false.Resulting main: CI / CD run 38821876379
success, CodeQL SAST run 38821876470success. GitHub Pages record 7106972339success, HTTP 200. Productiondpl_7WmkbcuhchdeR8EFs9igbZBCr4L2READY on the exact SHA (GitHub deployment record 7106617928success); aliases bound:worldscript-studio.vercel.app(HTTP 200), the two team aliases HTTP 302 (Vercel SSO, bound).Safe-only retention (clean detached worktree at the exact SHA, writer: Claude Code CLI per the active mode): 7 SAFE (
pr-closed-or-merged, previews of PR #1072 and of earlier heads of PR #1073), 0 UNKNOWN, 7 write attempts, 7 deleted. Post-proof: protected present 51/51, deleted absent, canonical and protected aliases bound, preview states held, deletions still SAFE, production set stable, production READY, HTTP 200. Production and rollback candidates untouched; the previews of the open PRs stayed protected (40 PROTECTED in the manifest).qnbs commentedon Oct 16, 2026
Retention receipt — main
52eb9f6f(PR #1074, Gate 4 slice H1a-2 part 3: Unix directory removal on Linux and leftover recovery,test-supportonly; supersedes #1070)Merge: squash
52eb9f6f75f2390699772796b9ed4685967f0981, one parent (1f37cd83), signature verified, tree identical to the validated head3a083508. Protected merge pinned with--match-head-commit, no admin, 9 files / 775 meaningful lines; 9 commits in the PR, two of them a temporary macOS probe and its correction that are squashed away (the measured answer is in the PR body and the evidence document). #1070 was closed as superseded, not merged; its branch is kept.Review on the exact head: 0 unresolved threads (6 on this PR, all answered: 4 fixed with a test and mutation check, 1 wording fixed, 1 about the temporary probe, obsolete; the 7 findings that were open on #1070 are accounted for in the body of #1074); Codex completed on
ec7ba931with no finding at all and on the exact head with none unresolved; CodeRabbit reviewedec7ba931(one Minor wording point, fixed) and was rate-limited on the docs-only head; CodeAnt Quality Gate passed (risk Low); CodeScene approved; hosted Windows / macOS / Ubuntu Secure Store evidence, Quality Gate Node 22/24, E2E, CodeQL and✅ CI Successgreen.DEPENDENT_OPEN_PRS=0,delete_branch_on_merge=false.Resulting main: CI / CD run 38838765824
success, CodeQL SAST run 38838765751success. GitHub Pages record 7109402070success, HTTP 200. Productiondpl_GLkEhBzm7LzSRptit2bo6GwpyvHZREADY on the exact SHA (GitHub deployment record 7109076954success); aliases bound:worldscript-studio.vercel.app(HTTP 200), the two team aliases HTTP 302 (Vercel SSO, bound).Safe-only retention (clean detached worktree at the exact SHA, writer: Claude Code CLI per the active mode): 9 SAFE (
pr-closed-or-merged: 8 previews of PR #1074, 1 of the closed PR #1070), 0 UNKNOWN, 9 write attempts, 9 deleted. Post-proof: protected present 52/52, deleted absent, canonical and protected aliases bound, preview states held, deletions still SAFE, production set stable, production READY, HTTP 200. Production and rollback candidates untouched; the previews of the other open PRs stayed protected (40 PROTECTED in the manifest).qnbs commentedon Oct 16, 2026
Retention receipt — main
0ba4b94a(PR #1075, Gate 4 slice H1a-2 part 4: Windows removal through the authenticated handle,test-supportonly; supersedes #1071)Merge: squash
0ba4b94a4c70b36a74b2db25dd271626cafaf84d, one parent (52eb9f6f), signature verified, tree identical to the validated headd3d97562. Protected merge pinned with--match-head-commit, no admin, 8 files / 516 meaningful lines, 5 commits in the PR. #1071 was closed as superseded, not merged; its branch is kept. One newunsafecall (the disposition), no new package.Review on the exact head — stated without rounding up: 0 unresolved threads (2, both answered: the Codex P2 on the directory converted in place is fixed with a test that passes on the hosted Windows runner, the CodeRabbit wording point is fixed). CodeRabbit: "no actionable comments" on the full diff of the first head, and it reviewed the range that contains the revalidation fix (
a57f8ad5..140e981a: one Minor wording point, fixed); it was rate-limited on the final docs-only head. CodeAnt: Quality Gate passed, risk Low on140e981a; its earlier Medium note (a writable mapped view can change the bytes) is answered in writing as the same-user residual and led to the statement that the removal binds the object, not its bytes, on Unix and Windows. CodeScene approved. Codex: completed with no finding on the first head, completed with the one finding on7c43e606, and then its review failed technically on140e981aandd3d97562, including on one manual request; that is no signal and is not counted as a pass. Hosted Windows / macOS / Ubuntu Secure Store evidence (the Windows run executes all 12remove_windowstests), Quality Gate Node 22/24, E2E, CodeQL and✅ CI Successgreen.DEPENDENT_OPEN_PRS=0,delete_branch_on_merge=false.Resulting main: CI / CD run 38852100613
success, CodeQL SAST run 38852100651success. GitHub Pages record 7111385430success, HTTP 200. Productiondpl_3hiSh3SVxEwKc4oCsY1esPfLitiTREADY on the exact SHA (GitHub deployment record 7111125440success); aliases bound:worldscript-studio.vercel.app(HTTP 200), the two team aliases HTTP 302 (Vercel SSO, bound).Safe-only retention (clean detached worktree at the exact SHA, writer: Claude Code CLI per the active mode): 5 SAFE (
pr-closed-or-merged: 4 previews of PR #1075, 1 of the closed PR #1071), 0 UNKNOWN, 5 write attempts, 5 deleted. Post-proof: protected present 53/53, deleted absent, canonical and protected aliases bound, preview states held, deletions still SAFE, production set stable, production READY, HTTP 200. Production and rollback candidates untouched; the previews of the other open PRs stayed protected (40 PROTECTED in the manifest).qnbs commentedon Oct 17, 2026
2026-10-17 — #1076 exact-main retention checkpoint
Current protected
mainisa710b39bb2aeecee9a1e580cc367c930c45b58c1. CI / CD 38910695945 and CodeQL 38910695491 are terminal success on that SHA. Vercel Productiondpl_iQYUJpYnG4rbP41UgMWsap7gjZTYisREADYon the same SHA; its three canonical/Main aliases remain bound, the canonical site returned HTTP 200, and the previous Productiondpl_3hiSh3SVxEwKc4oCsY1esPfLitiTremains present and READY as rollback evidence. GitHub Pages deployment 7121175822 also succeeded on this SHA; the site, manifest, and sampled JS/CSS assets returned HTTP 200.Retention is not terminal. The canonical read-only runner returned
provider-read-failedwithwriteAttempts=0; it produced no complete SAFE/PROTECTED/UNKNOWN manifest. I am not recordingNO_OP_RETENTION_PASSor a SAFE count. A separate authenticated read inventory returned 53 Vercel deployments and 55 aliases, but cannot replace the canonical runner's classification. No Vercel deployment or alias was changed.The active policy still names the local Claude Code CLI as the destructive writer. The valid bounded train declaration in #927 defers only Preview housekeeping; it does not waive Production gates. Full reconciliation remains due at train end, and non-train mutation remains gated on that terminal proof.
qnbs commentedon Oct 17, 2026
2026-10-17 — local provider-read diagnosis and canonical dry-run
provider-read-failedwas caused by the local Vercel CLI auth context: the first already-present CLI path returnedwhoamiexit 1 with a redacted invalid-token error. The second already-present path (the same Vercel CLI 64.3.1 binary) returned exit 0. No login or credential change was made. Exact team/project-scoped GETs for/v9/projects/<project-id>,/v6/deployments?...projectId=<project-id>&teamId=<team-id>&limit=100, and/v4/aliases?...projectId=<project-id>&teamId=<team-id>&limit=100succeeded; the source-equivalent NodeexecFileSyncGET returned the same project response.On clean exact-main
a710b39bb2aeecee9a1e580cc367c930c45b58c1, the unchanged canonicalnode scripts/vercel-retention/cli.mjs dry-runcompleted read-only:SAFE=2,PROTECTED_PRODUCTION=14,ROLLBACK_CANDIDATES=2,PROTECTED_PREVIEWS=37,UNKNOWN=0,writeAttempts=0,stop=null. This is read-only evidence, not the terminal/destructive postmerge retention receipt. No Vercel deployment or alias write was performed; the policy-named Claude Code CLI remains the platform writer.The earlier CLI/API list had 53 deployments; the later exact project/team
/v6response had 38 withnext=null. Exact team-scoped GETs for each of the 15 IDs in the former set but not the latter returned semantic 404 at 07:56:51 UTC (15/15; no auth/permission failures). This confirms those deployments were absent by the later observation; what removed them and when remains unknown. The scoped alias inventory had 55 entries. Codex issued no Vercel write.The independent GH #1042 metadata cleanup is separate: its one Preview record's original host returned semantic 404, and that exact GitHub record was removed with a 204/404 receipt while Vercel state remained unchanged.
qnbs commentedon Oct 17, 2026
MAINTAINER EXECUTION-OWNER DECISION — 2026-10-17 — narrowly scoped temporary Codex Maintenance writer
This is a new explicit maintainer direction, superseding the previous requirement to resume Claude for this maintenance task. Claude Code CLI remains PAUSED_BY_OWNER, including ALL R-15/Gate4–7 feature development. The maintainer now directs Codex CLI running locally in VS Code/Ubuntu to execute the entire maintenance-only lane itself: GitHub Deployment metadata reconciliation (#1042), policy-compliant Vercel Preview-platform retention (#627), tightly scoped ZIP/Rust-dependency security remediation, and a separately admitted Dependabot successor train (#927). The intent is an operator handoff, not a bypass or a request for Codex to impersonate/start Claude.
Writer reassignment: For #627 ordinary SAFE-only Vercel Preview retention, while this owner decision remains active,
ACTIVE_DESTRUCTIVE_WRITER = Codex CLI, local Ubuntu / VS Code, instead of the Claude Code CLI named in the dated 2026-10-13 active-mode policy paragraph. All other retention predicates, exact-team/project scope, clean runner/main, exact SHA + push CI/CD + CodeQL, Production/rollback/alias/active-PR protections, UNKNOWN fail-closed behavior, source equality, exactdpl_IDs,--safe, no blind retries, full postproof and non-secret receipts are unchanged and mandatory. This supersession changes only the named operator in the maintenance lane; it does not authorize Cursor Cloud or any third party, multiple concurrent writers, Vercel Production writes, project-wide deletion, production/rollback/promotion/tag/release, a branch-protection bypass, release Storage authority switch, or arbitrary changes to protected evidence.Source-of-truth reconciliation before first Vercel write: The checked-in
docs/VERCEL-PREVIEW-RETENTION-POLICY.mdstill names Claude; preserve that document as the technical rulebook and carry this newer maintainer authority decision as the explicit, dated writer-only supersession, mirrored in QNB-67. Codex must inspect AGENTS.md and every other higher-priority required approval and demonstrate that this temporary operator transfer is admissible; if any repo policy requires an on-main policy edit first, do not silently ignore it. Prepare the smallest maintenance-only signed policy update and obtain the required protected gates; where an upstream security-audit failure prevents even that, report a precise governance deadlock and continue independent non-destructive security diagnostics. No change to the actual deletion classification is authorized.Immediately repeat the canonical read-only dry-run from clean exact
mainand the already found authenticated Vercel CLI context, without exposing secrets; the last known result (SAFE=2, UNKNOWN=0) is not a current write authorization. Only when owner re-delegation, actual source contract, provider identity, all full preflight gates and protected states agree, perform the canonicalnode scripts/vercel-retention/cli.mjs reconcile(not ad hocvercel remove <project>); record each exact SAFE deletion (or complete NO_OP), independently verify all protected IDs and aliases, then publish terminal #627/QNB-67 receipt.Separate source scope: Codex may research and implement narrowly necessary compatible dependency/security fixes in isolated protected PRs; keep declared Rust MSRV 1.77.2, do not elevate it without a separate owner decision, and never weaken OSV/CI/review checks. No ordinary R-15 feature coding or release activity. The old Dependabot epoch expired at 2026-10-17 14:14:30 UTC with one merge (#1076); a new epoch is not yet declared and must have a separate fresh immutable cohort + baseline retention + all gates.
Revocation: owner may revoke this temporary Maintenance-writer delegation at any time; do not assume this modifies Claude's pause. The prior Claude writer receipts remain historical, not invalidated.
qnbs commentedon Oct 17, 2026
Codex local SAFE-only Vercel retention receipt — 2026-10-17T16:11:49Z
Owner authority: the writer-only delegation in GH #627 designates local Codex; Claude remains PAUSED_BY_OWNER. The canonical main-based runner was unchanged. Project/team were verified by the runner as worldscript-studio / prj_XJDiKIlKNg5sbmw6xMHIlf6glXHy and qnbs-projects / team_Dx4T2J41LNqP8mDgrRraonWp.
Main anchor: a710b39. Exact push CI/CD run 38910695945 and CodeQL run 38910695491 succeeded; the push run's Security Audit succeeded. A later scheduled OSV run 38998852956 on the same SHA failed and remains an unresolved security blocker for source changes and merges; it was not bypassed.
The canonical reconcile classified one SAFE preview and zero UNKNOWN, then attempted one exact-ID removal:
Execution deviation disclosed: the initial dry-run and single reconcile were invoked under Node 24.18.0. package.json's engine range permits >=22.19.0, but the checked-in .nvmrc specifies Node 22 and AGENTS directs use of the repository-declared toolchain. After discovering this, no further writes were made; exact-ID GET and final dry-run were repeated with Node 22.23.3 and confirmed the result. Therefore the provider state is terminally verified, while this receipt records a toolchain-procedure deviation. No merge, release, tag, promotion, or Production/Pages write occurred.
qnbs commentedon Oct 17, 2026
Required permanent Node 22/24 retention-operator guard — 2026-10-17 maintenance follow-up
Cause established on current
main:.nvmrc=22;package.jsonengines.node >=22.19.0intentionally permits Node24 application use;.github/workflows/ci.ymlintentionally tests Node 22 and Node 24. Thescripts/vercel-retention/cli.mjsentrypoint does not currently check its ownprocess.versions.nodebefore provider calls, so #627's earlier reconcile could run with Node 24.18.0 despite AGENTS' local declared-toolchain rule. Its subsequent Node 22.23.3 read-only verification confirmed terminal safe provider state, not retrospective compliance.New actionable engineering requirement: Local Codex maintenance operator must implement smallest tested fail-closed retention-entrypoint runtime guard accepting Node 22 with repository minimum 22.19 (allow later 22.x security patches), rejecting Node24 and other versions before any external provider GET/DELETE, gh/vercel subprocess, lock acquisition, or write. Cover dry-run and reconcile; check actual runtime and child PATH/tool invocation context, never log credentials. A Node24 negative harness must prove zero external calls and nonzero terminal stop; Node22 positive tests must pass against mocked dependencies. Include provenance/source-equality with current-main runner, focused documentation, clean Node22.23.3 preflight. Keep the general package engines >=22.19 and intentional CI Node22+24 Quality matrix unchanged; this is an operator-only invariant, not a universal app runtime downgrade.
Protected integration: Small signed maintenance-only PR and adequate regression tests. Main Security Audit is currently red due to unrelated ZIP RUSTSEC-2026-0367/368/369. Do not merge an otherwise correct Node-guard PR while required CI red, do not ignore OSV or admin-merge. A tested local patch/PR with exact-head BLOCKED_SECURITY is still concrete engineering progress; pursue separate ZIP security prototype simultaneously (sequential heavy shell). No claim that this guard has been implemented or merged.
Links: GH #911 and #572 source/MSRV prototype; GH #927 Dependabot lane; owner-delegated local Codex writer authority earlier in this issue. R-15 remains paused, release NO_GO.