Versioned Deploy Archives

Status: landed (archived 2026-05-18 — v1+v2 hosts live, careervector-web → careervector-ui rename complete).

Updated: 2026-05-14

Decision

CareerVector cutover uses versioned living archives instead of compatibility paths inside the new app.

Host Meaning Lifecycle
v1.careervector.corbet.ch Living archive of the old pre-node-tree app, currently old.careervector.corbet.ch Keep bootable for reference/screenshots/support; no new feature work.
v2.careervector.corbet.ch Living archive of the current production app before the v3 cutover Keep bootable until v3 is stable and migration confidence is high; no new feature work after archive split.
careervector.corbet.ch Current champion. After cutover this is v3. User-facing champion host.
quality.careervector.corbet.ch Internal quality control plane. Protected internal service for probes, gates, runners, and run ledger.

The archive rule is strict: v1 and v2 get their own deployment/resource surfaces. v3 must not carry old-version routes, fallback behavior, or runtime switches just to keep older versions alive.

Existing Config Seen Locally

Current branch config has a single production surface:

  • ui/wrangler.toml
    • worker: careervector-ui (renamed from careervector-web on 2026-05-17)
    • D1 binding CV_DB: careervector
    • R2 binding CV_BUCKET: careervector
    • service binding REALTIME: careervector-realtime
    • production JOBCACHE_SERVICE_URL: https://jobcache.corbet.ch
  • realtime/wrangler.toml
    • worker: careervector-realtime
    • durable object class: WorkspaceDoc
    • D1 binding CV_DB: careervector
  • mcp/wrangler.toml
    • worker: careervector-mcp
    • D1 binding CV_DB: careervector
    • service bindings to careervector-ui and careervector-realtime
    • WEB_URL: https://careervector.corbet.ch
  • wiki/content/runbooks/STAGING.md
    • deployed staging is intentionally retired.

Known D1 names observed during the cutover work:

  • careervector
  • careervector-old
  • careervector-cutover-20260513
  • careervector-v2-archive-20260514

Do not infer source/target roles from names alone. Verify each binding before any write or DNS flip.

Archive Inventory Captured On 2026-05-14

Host Deployment Data Surface Smoke Proof
v1.careervector.corbet.ch Cloudflare Pages project careervector; custom domain active; DNS CNAME to careervector.pages.dev Existing old Pages app resources curl https://v1.careervector.corbet.ch returned HTTP 200 and a CareerVector - Job Tracking title.
v2.careervector.corbet.ch Workers careervector-web-v2 and careervector-realtime-v2, deployed from origin/main commit 7769c25 D1 careervector-v2-archive-20260514 (61bce9f4-bfef-463f-9857-7b1ec9fccfee) with 1988 workspaces, 632 jobs, 9883 workspace sub-doc rows, 148078845 snapshot bytes curl https://v2.careervector.corbet.ch/d6VPSAytGPWWFnKb/dashboard returned a Dashboard - My Job Search (copy) title.

The v2 D1 export contained BLOB rows too large for one-shot SQL import into D1. The completed import used normal SQL for every table except workspace_sub_doc, then a temporary authenticated Worker bound to the archive D1 inserted the snapshot BLOBs through prepared-statement parameters. The temporary loader Worker was deleted after count and byte-length verification.

Archive Requirements

Each living archive needs an inventory row before it can be called safe:

  • repository or frozen branch/commit;
  • deployed worker/app name;
  • hostname route;
  • D1 database name/id;
  • R2 bucket name if files can be downloaded;
  • realtime worker/DO surface if the archive needs live editing;
  • secrets/provider bindings supplied by platform secret stores;
  • smoke command proving it boots;
  • rollback or removal command.

Archive DBs are read-mostly. If an archive remains editable temporarily, it must be labeled as such and must not be treated as champion data after v3 wins.

Cutover Order

  1. Preserve v1:
    • point v1.careervector.corbet.ch at the old app currently served by old.careervector.corbet.ch;
    • keep its D1/R2 resources intact;
    • smoke at least dashboard and CVL view.
  2. Preserve v2:
    • freeze current production before v3 promotion;
    • copy or bind isolated D1/R2 resources as needed;
    • point v2.careervector.corbet.ch at that frozen surface;
    • smoke the same minimal archive paths.
  3. Promote v3:
    • deploy the clean main candidate to the champion resources;
    • run migration verification and browser E2E;
    • point careervector.corbet.ch at v3 only after proof is recorded.
  4. Stand up quality:
    • quality.careervector.corbet.ch is internal and protected;
    • runners talk outbound to it;
    • provider accounts are optional plugins, never design requirements.

Open Risks

  • The current branch history contained and reverted a product-repo Cloudflare helper. Main should receive a clean squash/cherry-pick candidate, not this raw branch history.
  • careervector-cvl is a worktree attached to the sibling careervector checkout. Desktop/Claude work must verify Git worktree state before editing.
  • Existing infra docs still contain old staging language and account-specific historical notes. Clean publication hygiene is lower priority than cutover, but it remains necessary before a public repo release.
Source: wiki/content/archive/2026-05/versioned-deploy-archives.md