Repository navigation
ci(vercel): prune stale Preview deployments after PR closure #627
Description
Activity
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 commented
on Sep 20, 2026 OwnerAuthorMore actions2026-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:deployments total = 25 protected open-PR previews = 11 protected production deployments = 7 stale closed/merged previews = 7Current main:
1451f88151fa68eafbf57cd020287b72a5268de3Exact-main gates:
- CI/CD SUCCESS
- CodeQL SUCCESS
- current Production deployment READY and rollback-protected
Verified stale Preview candidates
All seven candidates are:
target = nullREADY- not rollback candidates
- scoped to the expected project/team/repository
- tied only to merged/closed PRs
- tied to branches that no longer exist on GitHub
- unrelated to every currently open PR
Deployment PR/lane Branch/ref dpl_GBAgfdXRHDG4KjwWD24o3exGtNVu#784 merged chore/dependabot-dev-tooling-minor-patch-20260920dpl_4iNPbk8myDZ9bM2dc2NK8QaS8L3J#782 merged chore/dependabot-vitest5-linear-20260920dpl_6VW14jvUnZZRnxRtpc7ojrFLAvqm#782 prior generation same branch dpl_HiwugtsjCC93TeEuE2Tuxed2ZnRM#782 prior generation same branch dpl_HGwub3FTHn4APaEbZopSZ7pDBX2c#749 closed unmerged dependabot/npm_and_yarn/dev-tooling-c9c26bdfd5dpl_AmzcJ4cA29hT7ERBXZFcYzgwmCjt#775 merged feat/553-d1-idb-canonical-authority-20260917dpl_8BjP9SYK7dH7tugLBPmratbL6RwV#775 prior generation same branch Each 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:
- list aliases:
GET /v4/aliases?projectId=<project>&teamId=<team> - delete orphan alias:
DELETE /v2/aliases/{aliasId}?teamId=<team> - delete deployment:
DELETE /v13/deployments/{id}?teamId=<team> - CLI API equivalent:
vercel api /v13/deployments/<deployment-id> -X DELETE
This 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 commented
on Sep 22, 2026 OwnerAuthorMore actions2026-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:
- current
main=21460657cba475317306e99dfd32cf95479916b1, produced by merged PR build(deps): bump ai from 7.0.91 to 7.0.101 #795; - Vercel reports the current production deployment for that SHA as
READY; - PR build(deps): bump ai from 7.0.91 to 7.0.101 #795 is now merged, so Preview deployments still tied to branch
dependabot/npm_and_yarn/ai-7.0.99are now closed-PR lifecycle candidates, subject to the existing alias/rollback/review-evidence safety gates; - PR build(deps): bump the react group across 1 directory with 4 updates #785 remains open and its React-group Preview deployments remain active review evidence and must be preserved;
- the connected Vercel listing currently exposes a latest page of 20 deployments, but that page count is not asserted as the total project inventory.
No deployment or alias was deleted during this documentation pass.
The durable policy remains unchanged:
- classify Production/open-PR/rollback/review-protected deployments first;
- identify closed/merged-PR previews only from live GitHub state;
- reconcile branch aliases before deletion;
- dry-run explicit IDs;
- delete only through authenticated supported API/CLI;
- re-fetch and verify after each bounded cleanup wave.
#627 remains OPEN / P2 because the long-term authenticated retention/cleanup mechanism is still not terminal.
- current
qnbs commented
on Sep 23, 2026 OwnerAuthorMore actions2026-09-23 live housekeeping reconciliation — retention pressure and alias semantics
Fresh live state after PR #817:
main = 2de980dbedf3ea5e2ada0ac8b6d449faf10a2a5e open GitHub PRs = 0 Vercel deployments = 37 Production = 9 Preview = 28 all observed deployments = READYCurrent 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:
A. alias-first → deployment delete or B. explicit deployment delete → post-delete dangling-alias reconciliationThe 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
- pagination must enumerate the full project, not only the first CLI page;
- aggregate expected counts are informational, never deletion targets;
- every delete candidate must be revalidated immediately before mutation;
- deletion should remain in bounded batches with Production/alias verification between batches;
- zero open PRs makes this inventory unusually simple but must not become an assumption in automation.
#627 remains OPEN / P2 after the manual pass because prevention/automation is not yet terminal.
qnbs commented
on Sep 24, 2026 OwnerAuthorMore actions2026-09-24 post-#830 retention catch-up checkpoint
PR #830 is merged and its exact resulting main is now terminal green:
main = 0371a67fb97439a85ac6731b843d4937a56c63c3 CI/CD run 36060688100 = SUCCESS CodeQL run 36060688074 = SUCCESS current Production deployment = dpl_5fyqAhcVhbzGFRWALgiEeWgvp52T = READYThe 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:
- Production/current main:
dpl_5fyqAhcVhbzGFRWALgiEeWgvp52T@0371a67f… - open PR fix(persistence): make superseded lifecycle flushes observe their chain's real outcome (#553) #832 head preview:
dpl_FsfWviz5wyDrTAAoJRo7Zb1sVNum@2f7f57ba… - open draft PR feat(core): R-15 Gate 1a headless WSR1/AAD/AES-256-GCM primitive (#445) #829 preview:
dpl_HsYtey7nLKGtGrC3qNmoYBxrsLSn@b05dbdb4… - prior Production/rollback-relevant deployments remain protected by the policy even when their PR lifecycle is terminal.
Visible lifecycle candidates only — not pre-authorized deletes — include multiple non-Production READY previews from terminal PRs/branches, for example:
- fix(fs): refuse a stale independently-loaded desktop writer (#553) #830 /
fix/553-stale-writer-refusal:dpl_EJjPrJQetVmSqPos18jFnJf4B5uL,dpl_E27p4eqCjykHBrzTcbNVNzzekvA6,dpl_83UVZnsHXR3Kkt2GLmfbWW7JH9vV,dpl_6BPF7M2vUfWekhTp9QJzVzaPUA5e - fix(fs): close cross-process TOCTOU race in project filesystem save (#553) #826 /
fix/553-native-write-lock: multiple visible historical preview generations - fix(i18n): stop Factory Reset copy implying local models are erased (#526) #828 preview
dpl_53VScEG5rZGUUoGqAAo9sChd1yRM - closed-unmerged fix(reset): delete the DuckDB analytics OPFS file on Factory Reset (#716) #827 preview
dpl_GnH3wHBco5TSA5FvcVUkeVDyWXuo
Every 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
- Re-read live current
main; if it moved from0371a67f…, establish a new terminal-green main gate first. - Enumerate all pages for this exact Vercel project/team only.
- Snapshot Production/main aliases, rollback/promotion-protected IDs and exact protected Preview sets for open PRs fix(persistence): make superseded lifecycle flushes observe their chain's real outcome (#553) #832 and feat(core): R-15 Gate 1a headless WSR1/AAD/AES-256-GCM primitive (#445) #829 (newest up to three per PR plus any additional active alias/review evidence).
- Produce the dry-run manifest from the repository policy.
- Resolve the alias/deployment ordering contract from live provider semantics; do not encode contradictory alias-first/deployment-first behavior implicitly.
- Revalidate each candidate immediately before mutation.
- Delete only explicit SAFE_TO_DELETE IDs through authenticated Vercel CLI/API in bounded batches.
- Re-enumerate after each batch and prove Production, rollback history, open-PR previews and aliases remain intact.
- Record the resulting counts/evidence here without secrets or creator emails.
This manual catch-up does not close #627. The issue remains the long-term automation/least-privilege retention owner.
- Production/current main:
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):
Class Count Protected Production 15, incl. dpl_5fyqAh…holding the Production +mainaliasesProtected open-PR Previews #832 dpl_FsfW…(head2f7f57ba), draft #829dpl_HsYt…(headb05dbdb4)Protected active-branch-alias Previews #827 dpl_GnH3…(branch deliberately retained), #820 newestdpl_9RpT…(branch still exists)SAFE_TO_DELETE 24 UNKNOWN / DEFERRED 0 The 24 deletions:
- older Preview generations of merged or closed PRs chore(repo): codify preserve-first housekeeping and local tooling hygiene #820, ci(security): land trusted reusable workflow for pr-size enforcement (#510, phase 1/2) #825, fix(fs): close cross-process TOCTOU race in project filesystem save (#553) #826 and fix(fs): refuse a stale independently-loaded desktop writer (#553) #830 (no alias);
- the newest Previews of merged PRs chore(repo): codify preserve-first Git housekeeping and tooling hygiene #821, fix(scripts): make the suppression-debt ratchet a true per-rule gate #823, chore(deps): remove qs@6.16.0 from minimumReleaseAgeExclude once naturally aged #824, fix(fs): close cross-process TOCTOU race in project filesystem save (#553) #826, fix(i18n): stop Factory Reset copy implying local models are erased (#526) #828 and fix(fs): refuse a stale independently-loaded desktop writer (#553) #830 and closed ci(security): land trusted reusable workflow for pr-size enforcement (#510, phase 1/2) #825, whose only alias was a deleted branch's alias. Each alias was removed first, and the deployment only after that succeeded.
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_4fc2os68cV4rZQZGqTERC66ViQev
Post-cleanup proof:
- deployments 43 → 19, no pagination remainder;
- 0/15 Production IDs missing and 0/4 protected Preview IDs missing;
- 0/24 deleted IDs present, and no unexpected new IDs;
- Production/
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;- no project, domain, env, promotion or rollback setting touched.
Creator identity
qnbs; no emails, tokens or secret values were recorded.Retention after #832 merge (main
164f23fa, CI + CodeQL terminal green).- Deleted (fix(persistence): make superseded lifecycle flushes observe their chain's real outcome (#553) #832 is MERGED, branch
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. - Protected: Production;
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). - Local git: rescue ref
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).
- Deleted (fix(persistence): make superseded lifecycle flushes observe their chain's real outcome (#553) #832 is MERGED, branch
Retention after #833 merge (main
3244242e, CI/CD + CodeQL terminal green: 16 success, 4 skipped).- Deleted. fix(fs): refuse stale-window image, binder and codex writes (#553) #833 is MERGED and
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…. - Protected. 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);dpl_9RpTHokR…(chore(repo): codify preserve-first housekeeping and local tooling hygiene #820 active alias). - Local git. Tip
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.
- Deleted. fix(fs): refuse stale-window image, binder and codex writes (#553) #833 is MERGED and
Retention after #835 merge (main
8b270ea7, CI/CD + CodeQL terminal green: 16 success, 4 skipped).- Deleted. fix(fs): refuse writers from a deleted-then-recreated project incarnation (#553) #835 is MERGED and its branch is gone on the remote. Alias
…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. - Protected. 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). The chore(repo): codify preserve-first housekeeping and local tooling hygiene #820 preview no longer appears in the listing. - Local git. Tip has the same tree as squash
8b270ea7. Rescue refrefs/rescue/housekeeping-20260925/pr835-tip-a22a61cb. Worktree removed (ignored files only); local branch deleted, bound to the verified SHA.
- Deleted. fix(fs): refuse writers from a deleted-then-recreated project incarnation (#553) #835 is MERGED and its branch is gone on the remote. Alias
Retention after #837 merge (main
5adef443, CI/CD run 36123834671 success, CodeQL run 36123834736 success).- Deleted. fix(project): export and back up the stored canonical raw instead of a re-serialized parse (#553) #837 is MERGED and
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…. - Protected, re-verified after deletion. Production (
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). - Local git. fix(project): export and back up the stored canonical raw instead of a re-serialized parse (#553) #837 tip
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).
- Deleted. fix(project): export and back up the stored canonical raw instead of a re-serialized parse (#553) #837 is MERGED and
qnbs commented
on Sep 25, 2026 OwnerAuthorMore actions2026-09-25 post-#838 retention inventory — cleanup pending
Gate anchor is now terminal green:
main = 5999f2e0b65d90c449939ca7ff718d37827bc1e8 CI/CD 36140075846 = SUCCESS CodeQL 36140075833 = SUCCESS current Production = dpl_63GbCknDULrPemkS5F4QFGwTRKAZ = READYThe connected Vercel project was fully paginated at this checkpoint: 24 READY deployments total.
Classification from current provider metadata:
- 20 Production deployments — protected by policy; current Production is
dpl_63GbCkn…on5999f2e0…. Prior Productiondpl_8MQLfGz…on5adef443…is explicitly marked rollback-candidate and remains protected. - Protected Preview:
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. - Protected retained Preview:
dpl_GnH3wHBc…— retainedfix/716-reset-duckdb-opfs-remanencebranch state from the established housekeeping policy/history. - fix(project): keep snapshots as stored text and admit every snapshot restore (#553) #838 lifecycle candidates only, not pre-authorized deletes:
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;- PR fix(project): keep snapshots as stored text and admit every snapshot restore (#553) #838 remains merged and the remote branch absent;
- neither preview is promoted/rollback-protected/current/open-PR evidence;
- branch alias ownership/current target is resolved live;
- remove the stale branch alias according to the established provider ordering contract;
- remove only the explicit safe Preview IDs with
vercel remove --safe; - re-enumerate and prove Production, rollback history, feat(core): R-15 Gate 1a headless WSR1/AAD/AES-256-GCM primitive (#445) #829 and the retained fix(reset): delete the DuckDB analytics OPFS file on Factory Reset (#716) #827/analytics(duckdb): requalify default-on DuckDB-WASM runtime, privacy, persistence and recovery semantics #716 preview are unchanged.
This is a dry-run/provider inventory only. It does not claim the #838 retention cleanup is already complete and does not close #627.
- 20 Production deployments — protected by policy; current Production is
Retention after #838 merge (main
5999f2e0, CI/CD run 36140075846 and CodeQL run 36140075833 success).- Deleted. fix(project): keep snapshots as stored text and admit every snapshot restore (#553) #838 is MERGED and
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…. - Protected, re-verified after deletion. Production (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). - Local git. fix(project): keep snapshots as stored text and admit every snapshot restore (#553) #838 tip
1a015b50has the same tree as squash5999f2e0; worktree and branch removed.
- Deleted. fix(project): keep snapshots as stored text and admit every snapshot restore (#553) #838 is MERGED and
Retention after the #839 merge (main
94b68fc1; CI/CD and CodeQL on main success).- Deleted. fix(persistence): write a replaced editor project whole instead of overlaying its predecessor (#553) #839 is MERGED and
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). - Protected, re-verified after deletion. Production
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). - Local git. Local main was fast-forwarded to 94b68fc. The PR worktree and local branch were removed; the worktree was clean before removal.
- Deleted. fix(persistence): write a replaced editor project whole instead of overlaying its predecessor (#553) #839 is MERGED and
Retention after the #840 merge (main
4e65bd12; CI/CD and CodeQL on main success).- Deleted. fix(persistence): save a restored snapshot from its own admitted text (#553) #840 is MERGED and
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). - Protected, re-verified after deletion. Production
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). - Local git. Local main was fast-forwarded to 4e65bd1. The PR worktree and local branch were removed; the worktree was clean before removal.
- Deleted. fix(persistence): save a restored snapshot from its own admitted text (#553) #840 is MERGED and
29 remaining items
Retention epoch for #1003 is terminal on resulting main
2ad572320e622fe379f48af1c4c54d9b3e7d7bc2(CI/CD 37710015147, CodeQL 37710015214). Productiondpl_yccBd4jK68MUiibpt6FJfuZtH8Xfis READY on the exact SHA with HTTP 200 and rollbackdpl_AETnRNkn5cx4SjRsF3NT8k9bf4Sois READY. Deleted the three #1003 head previews (dpl_5mukQ7YiaZSjsju3DXWwHAXfA9ch,dpl_EZzTKCRMiYP1Ryi87P4hR5QWjj97,dpl_Gu7YRf5XNnWPMKnG8vkQ7CAMSK7b; PR merged, branch deleted) one by one after removing the single branch alias, with absence proven for each. Retained 20 production/PROMOTED deployments and the 3 canonical aliases; 0 previews, 0 unknown, 0 dangling aliases.Retention epoch for #1004 is terminal on resulting main
18630d7693961db469aab09e91dca81f15c6ed8c(CI/CD 37717028036, CodeQL 37717027958). Productiondpl_TRn38nYsAgdGomdeVCjbi7WJTLXkis READY on the exact SHA with HTTP 200 and rollbackdpl_yccBd4jK68MUiibpt6FJfuZtH8Xfis READY. Deleted the #1004 head previewdpl_6kNi8dCs8E7t4TmGozKzxULcQ26G(PR merged, branch deleted) after removing its branch alias, with absence proven. Retained 21 production/PROMOTED deployments and the 3 canonical aliases; 0 previews, 0 unknown, 0 dangling aliases.Retention epoch for #1005 is terminal on resulting main
014c1c18548386cbc56cc04d18395aff4fe3b8b6(CI/CD 37736258294, CodeQL 37736258202). Productiondpl_8gHMgs7CMCustYohgRzyUFhyhmgmis READY on the exact SHA with HTTP 200 and rollbackdpl_TRn38nYsAgdGomdeVCjbi7WJTLXkis READY. Deleted the two #1005 head previews (dpl_GApcPbXzFYX3UqqBHVaJWATk5YA8,dpl_3ytmVHRtjJX8TMkAVRgZY7jwBdAr; PR merged, branch deleted) one by one after removing the single branch alias, with absence proven for each. Retained 22 production/PROMOTED deployments and the 3 canonical aliases; 0 previews, 0 unknown, 0 dangling aliases.Retention epoch for #1006 is terminal on resulting main
6ee0db777523ec407dd944211101f34f5bdd5093(CI/CD 37747908889, CodeQL 37747908987). Productiondpl_s6atn7q4kbXERdvqAG2o4sRBiKTwis READY on the exact SHA with HTTP 200 and rollbackdpl_8gHMgs7CMCustYohgRzyUFhyhmgmis READY. Deleted the two #1006 head previews (dpl_Djb3mpXKN6HDbr9vTurKFHJQos6C,dpl_EXxCi3p9JLpSYAyJ1aM9VRyxmz3E; PR merged, branch deleted) one by one after removing the single branch alias, with absence proven for each. Retained 23 production/PROMOTED deployments and the 3 canonical aliases; 0 previews, 0 unknown, 0 dangling aliases.Retention epoch for #1007 is terminal on resulting main
5a1474bb5605fee1e71a6ccbb60160aeeba22bb2(CI/CD 37760960561, CodeQL 37760960559). Productiondpl_2h5r5Mqx3rCA6E7bJm8FaUrz77SCis READY on the exact SHA with HTTP 200 and rollbackdpl_s6atn7q4kbXERdvqAG2o4sRBiKTwis READY. Deleted the two #1007 head previews (dpl_D7mAYegCePcByfcD7st4cgqj72t9,dpl_8du1MCrZNrXj53Ud5Et6HANYEwyy; PR merged, branch deleted) one by one after removing the single branch alias, with absence proven for each. Retained 24 production/PROMOTED deployments and the 3 canonical aliases; 0 previews, 0 unknown, 0 dangling aliases.Retention epoch for #1008 is terminal on resulting main
f10b30d0b53d9556152d4039916293dee2b7784c(CI/CD 37774706261, CodeQL 37774706198). Productiondpl_9LkSbnWuGLj4QEwJBrrdPFtqPL8iis READY on the exact SHA with HTTP 200 and rollbackdpl_2h5r5Mqx3rCA6E7bJm8FaUrz77SCis READY. Deleted the three #1008 head previews (dpl_GgzZSGUcip31HDprJmreP5UTDshM,dpl_8Ef6prc84dzfbCHtyv47qN7jefD7,dpl_GY9J9gxuEPUUCKJM47hzpGmQT4j4; PR merged, branch deleted) one by one after removing the single branch alias, with absence proven for each. Retained 25 production/PROMOTED deployments and the 3 canonical aliases; 0 previews, 0 unknown, 0 dangling aliases.Retention epoch for #1009 is terminal on resulting main
bc7d248a4ec972ef410bf1dc8791bcf9f553b1ec(CI/CD 37788245553, CodeQL 37788245538). Productiondpl_9K7UQuCe4woooYMeekVXZefrMbpMis READY on the exact SHA with HTTP 200 and rollbackdpl_9LkSbnWuGLj4QEwJBrrdPFtqPL8iis READY. Deleted the #1009 head preview (dpl_DQYL5KcfYk6uTrPPfZCR2VVuUkUj; PR merged, branch deleted) after removing its single branch alias, with absence proven. Retained 26 production/PROMOTED deployments and the 3 canonical aliases; 0 previews, 0 unknown, 0 dangling aliases.Retention epoch for #1010 is terminal on resulting main
edcd9535a25e7ef5869dd7bd4bbb8da29532e968(CI/CD 37825712187, CodeQL 37825714367). Productiondpl_g83XFkCJgD9fKjABp9jEZeLHh4QVis READY on the exact SHA with HTTP 200 and rollbackdpl_9K7UQuCe4woooYMeekVXZefrMbpMis READY. Deleted the seven #1010 head previews (dpl_FcTiMJkfgJSy49T7ViuWQ5K8DwJs,dpl_CuFXumN9Uc3u8GjTNtC7TrMfDsf4,dpl_DGcR9aqkwNBushXBBwSvN1A7BAqo,dpl_GAJdEz92Nh33XvFvwYtr5HiDEmRY,dpl_2oZYUYyjAj2TpD3FZXqhniPuAaeA,dpl_6FzTvBChKj62CNX8ijHXMPL9XCD5,dpl_Dn9vN7dUzrMwHRreVLQhux2sDZoU; PR merged, branch deleted) after removing the single branch alias, with absence proven for each (the first run was cut off after six by a timeout I set too short; the idempotent re-run proved those six absent from a fresh listing and deleted the seventh with confirmation). Retained 27 production/PROMOTED deployments and the 3 canonical aliases; 0 previews, 0 unknown, 0 dangling aliases.Retention epoch for #1011 is terminal on resulting main
abd49cf99a1dcd4b21a25fc655f6cdc1ded6a08a(CI/CD 37845701613, CodeQL 37845701689). Productiondpl_FeW7A38bTyBdwxKv6pFSpTPLtQpkis READY on the exact SHA with HTTP 200 and rollbackdpl_g83XFkCJgD9fKjABp9jEZeLHh4QVis READY. Deleted the three #1011 head previews (dpl_DxPhBar6n4djJCxmmQqy2LmkkEz7,dpl_GBd8tGxbn3f9saVNKLj7DDmK4Lfv,dpl_5MJA3yc5d7mVPEa8PRqKYXMTTpyr; PR merged, branch deleted) after removing the single branch alias, with absence proven for each. Retained 28 production/PROMOTED deployments and the 3 canonical aliases; 0 previews, 0 unknown, 0 dangling aliases.Gate 4D streaming capture S2b TERMINAL — PR #1012 (mirror)
CURRENT_MAIN = d5878c18e81d4f15ed486edf4240b96e9dbe6942 PR_1012 = MERGED (3 signed commits; 10 files; 3 review threads, 0 unresolved) RESULTING_MAIN_CI_CD = 37859962668 / SUCCESS CODEQL = 37859962546 / SUCCESS VERCEL_PRODUCTION = dpl_AVqAuddhF9EHfXGmqGvt9yaQi6vz / READY / exact main / canonical HTTP 200 ROLLBACK = dpl_FeW7A38bTyBdwxKv6pFSpTPLtQpk RETENTION = TERMINAL (3 previews deleted by exact ID, absence proven; 29 production/PROMOTED deployments + 3 canonical aliases retained; 0 previews; UNKNOWN = 0) STREAMING_S2B = TERMINAL GATE_4D = IN PROGRESS OPEN_PRS = 0 PRODUCTION_AUTHORITY_SWITCH_ALLOWED = NObegin_streamed_capture/StagingSession: a capture is staged and committed without the caller holding a key; the journal key is routed from the authenticated root/registry, the committed manifest and binding are read from the root, and one journal directory value is held per capture. Full text and proof: #359 issuecomment-6071500665.Open before Gate 4 terminal: C2 exclusive conversion driver; inheriting unchanged pages; bounded adapter defaults; pending-directory reclamation; Gate 4E write barrier. NEXT: read-only admission of the C2 driver on exact main.
Gate 4D C2a TERMINAL — PR #1013 (mirror)
CURRENT_MAIN = d50dcbb5d4f1995b42f180f7cda4d2548c2e5398 PR_1013 = MERGED (3 signed commits; 9 files; 1 review thread, 0 unresolved) RESULTING_MAIN_CI_CD = 37868374940 / SUCCESS CODEQL = 37868374924 / SUCCESS VERCEL_PRODUCTION = dpl_HJ5UFEHKrTx88paGFh2JNeV4ZbyU / READY / exact main / canonical HTTP 200 ROLLBACK = dpl_AVqAuddhF9EHfXGmqGvt9yaQi6vz RETENTION = TERMINAL (2 previews deleted; 30 production/PROMOTED + 3 aliases retained; 0 previews; UNKNOWN = 0) C2A = TERMINAL GATE_4D = IN PROGRESS OPEN_PRS = 0 PRODUCTION_AUTHORITY_SWITCH_ALLOWED = NObegin_conversion: the entry gate of the exclusive conversion driver. It needs the installation's exclusive admission (by mutable borrow; a shared guard does not type-check), derives the root layout from the admitted scope, re-reads the committed binding, the registry-routed key and the root-named manifest, and returns a session only for the owner of the lease inADMITorCONVERTwith the final inventory captured. Read-only: no write, no lock, no key, no clock. Full text and proof: GH #359 issuecomment-6072537648.Open before Gate 4 terminal: C2b (owner steps through the gate, first caller of the D3b renewal), C2c (cursor-driven iteration, crash/resume), inheriting unchanged pages, bounded adapter defaults, pending-directory reclamation, Gate 4E write barrier. NEXT: read-only admission of C2b.
Gate 4D C2b-1 TERMINAL — PR #1014 (mirror)
CURRENT_MAIN = 5cdf12cb44185918931a3b4f4dfe8d609c45d6a1 PR_1014 = MERGED (7 signed commits; 8 files; 21 review threads, 0 unresolved) RESULTING_MAIN_CI_CD = 37881709739 / SUCCESS CODEQL = 37881709758 / SUCCESS VERCEL_PRODUCTION = dpl_G5Yi6KMAVaJCUxfED8a9utf3CRpx / READY / exact main / canonical HTTP 200 ROLLBACK = dpl_HJ5UFEHKrTx88paGFh2JNeV4ZbyU RETENTION = TERMINAL (6 previews deleted; 31 production/PROMOTED + 3 aliases retained; 0 previews; UNKNOWN = 0) C2B1 = TERMINAL GATE_4D = IN PROGRESS OPEN_PRS = 0 PRODUCTION_AUTHORITY_SWITCH_ALLOWED = NOConversionSession::renew_lease: the first real caller of the D3b renewal, and the first step that moves the journal through the exclusive gate. The root event is taken through the held admission, the committed journal is read back under it and the root settles the outcome, every file operation goes through canonical paths, the journal directory is pinned below the installation and outside the root, and a differing crashed candidate is quarantined. Disclosed: six review waves (the QNB-11 text asked for one) and 1042 meaningful lines (over target, inside the hard tier). Open: C2b-2, C2c, handle-relative adapter I/O (Gate 4E/5), inheriting pages, adapter defaults, pending-directory reclamation, write barrier. NEXT: read-only admission of C2b-2. Full text: GH #359 issuecomment-6074441537.Gate 4D C2b-2 TERMINAL — PR #1015 (mirror)
CURRENT_MAIN = c4628b5440143e154364ee9bc99b1595b32251fc PR_1015 = MERGED (3 signed commits; 6 files; 4 review threads, 0 unresolved) RESULTING_MAIN_CI_CD = 37890155449 / SUCCESS CODEQL = 37890155447 / SUCCESS VERCEL_PRODUCTION = dpl_BKPsiSMc6X6PipP9Nt9S3oJuUYaL / READY / exact main / canonical HTTP 200 ROLLBACK = dpl_G5Yi6KMAVaJCUxfED8a9utf3CRpx RETENTION = TERMINAL (2 previews deleted; 32 production/PROMOTED + 3 aliases retained; 0 previews; UNKNOWN = 0) C2B2 = TERMINAL GATE_4D = IN PROGRESS OPEN_PRS = 0 PRODUCTION_AUTHORITY_SWITCH_ALLOWED = NOThe conversion session enters
CONVERTand moves the checkpoint cursor through the same fenced step as the lease renewal; the admission check now follows every outcome of the commit call. One consolidated correction wave; the cursor-against-page finding is deferred to C2c with a criterion. Open: C2c-1 (authenticated page access, page-local cursor), C2c-2 (iteration, crash/resume,VERIFY), handle-relative adapter I/O (Gate 4E/5), inheriting pages, adapter defaults, pending-directory reclamation, write barrier. NEXT: read-only admission of C2c-1. Full text: GH #359 issuecomment-6075712353.Gate 4D C2c-1 TERMINAL — PR #1016 (mirror)
CURRENT_MAIN = 4428fdd81c9e656be37861895a6cb001ef129dbc PR_1016 = MERGED (3 signed commits; 6 files; 0 inline threads, 1 reviewer note fixed) RESULTING_MAIN_CI_CD = 37901688894 / SUCCESS CODEQL = 37901688906 / SUCCESS VERCEL_PRODUCTION = dpl_DBXbZkbSJDN2ii4yqSxfsDuC9XMp / READY / exact main / canonical HTTP 200 ROLLBACK = dpl_BKPsiSMc6X6PipP9Nt9S3oJuUYaL RETENTION = TERMINAL (2 previews deleted; 33 production/PROMOTED + 3 aliases retained; 0 previews; UNKNOWN = 0) C2C1 = TERMINAL GATE_4D = IN PROGRESS OPEN_PRS = 0 PRODUCTION_AUTHORITY_SWITCH_ALLOWED = NOThe conversion session authenticates the page set once, reads pages keylessly, and the checkpoint cursor is page-local (the contract now says what the entry index means); the cursor is checked against the authenticated entry count of the selected page. One correction wave. Codex was rate-limited for this PR (
NO_SIGNAL). Open: C2c-2 (iteration, per-entry step, crash/resume,VERIFY), handle-relative adapter I/O (Gate 4E/5), inheriting pages, adapter defaults, pending-directory reclamation, write barrier. NEXT: read-only admission of C2c-2. Full text: GH #359 issuecomment-6077415264.Retention for #1017 (C2c-2, merge
92bf64ac): terminal. Productiondpl_B31kADJeBvN6uXPhg4dAFusYkEw3(exact main, READY/PROMOTED), rollbackdpl_DBXbZkbSJDN2ii4yqSxfsDuC9XMp. Dry classification: 4 previews (44ba1be0,ca26d16a,371de5dd,20afde67; PR merged, branch gone, no Production alias, not rollback) all gates OK; removed by exact ID plus one branch alias; re-dry: 4 ABSENT, 0 unknown, 0 unclassified. Final: 34 Production deployments READY/PROMOTED, 3 canonical aliases, 0 previews. Canonical host 200. Proof: #359 (comment).
CURRENT RETENTION CHECKPOINT — 2026-10-06 — DEPENDENCY-TRAIN FINAL RETENTION TERMINAL
The two older retained
target=production / PROMOTEDdeployments 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
Problem
The existing
.github/workflows/prune-deployments.ymlprunes 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
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.