sbom-nexus/docs/production-cutover-plan.md
tegwick 01fb7ecdda docs: record dark deployment preflight
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a028f0-a42f-7582-89a8-ebaad7343834
2026-08-22 15:05:23 +02:00

4.6 KiB

SBOM Nexus production cutover plan

Owner workplan: SBOM-WP-0002

Parent coordination: CUST-WP-0062

Consumers: State Hub, Repo Manager, Activity Core

Safety model

Cutover separates durable data movement from caller movement. State Hub remains the rollback read/write path until Nexus history reconciles, the compatibility façade passes, and the bounded Activity Core flow is proven. No step deletes State Hub rows.

Sequence

Stage Authority/write path Exit evidence Rollback
0. Deploy dark State Hub Nexus health, migrated PostgreSQL, backup/restore drill remove dark deployment
1. Import history State Hub exact legacy-id, timestamp, entry, and licence reconciliation discard Nexus database and restore backup
2. Projection sync State Hub active repo/path projection in Nexus; catch-up counts sampled stop projection sync
3. Read façade State Hub write; Nexus read behind flag route compatibility suite and dashboard/MCP samples flag reads back to State Hub
4. Write façade Nexus write; State Hub projection update manual and repository ingest parity; truthful attempt/success mapping flag writes back to State Hub
5. Bounded activity Nexus at most N terminal outcomes, zero spawned tasks, deterministic progress disable daily definition
6. Stabilize Nexus two successful daily fires and one Monday with weekly flood at zero return façade flags to State Hub
7. Retire Nexus retention decision and final backup restore retained State Hub snapshot store during window

Dark deployment placement

The application is packaged separately as rapp-sbom-nexus and remains a private rail-kubernetes workload on reef-railiance. The application image is built from this repository and pinned by digest in the package.

platform-pg is at its declared four-consumer ceiling. The reviewed database handoff therefore targets the named platform-pg-2 overflow cell rather than quietly exceeding that ceiling. apps-pg still has one declared slot, but its current consumer flow uses static application credentials; SBOM Nexus requires the canonical OpenBao runtime/migration lease split. The database owner must admit and provision the overflow consumer before the dark apply.

Contract ownership

SBOM Nexus

  • /sbom/*, snapshots, entries, licence report, ingest outcomes, catch-up;
  • both last_attempt_at and last_success_at;
  • imported legacy UUID provenance;
  • PostgreSQL schema and migration history.

State Hub child change

  • introduce a configurable Nexus client and /sbom/* façade;
  • preserve legacy response shapes and ManagedRepo.last_sbom_at during the transition;
  • retarget dashboard, MCP, summary cache, DoI C8, onboarding, and CLI callers;
  • meter façade reads/writes and retain a reversible flag;
  • do not add new SBOM product behavior locally.

Repo Manager child change

  • retain repository identity, active status, host/checkout paths, and source authority;
  • change rmgr sbom scan|licence-report from independent product behavior to a Nexus client/local compatibility adapter;
  • pin sbom-nexus.snapshot.v1 and remove competing historical ownership;
  • preserve repository-source scanning usability when Nexus is unavailable only as an explicitly non-authoritative local preview.

Activity Core child change

  • replace the stale test-double blocker note with the live Nexus contract;
  • implement at-most-N POST /sbom/{slug}/ingest calls for selected targets;
  • record ingested and skip reasons without task creation;
  • keep the definition disabled until dark deployment and import pass;
  • enable and capture two-fire plus Monday-window evidence.

Timestamp compatibility decision needed

State Hub has one last_sbom_at; Nexus distinguishes attempt from success. The recommended transitional mapping is last_attempt_at, because it preserves catch-up fairness and the historical behavior that an ingest call advances the field. New consumers must use last_success_at when they mean inventory freshness. The State Hub child workplan must record this explicitly before write cutover.

Production acceptance

  • PostgreSQL upgrade and restore are rehearsed against the deployed topology.
  • Historical import report is ok: true with zero missing/mismatched snapshots.
  • State Hub compatibility routes pass against Nexus.
  • Repo Manager has no competing durable SBOM store.
  • Activity Core updates or terminally skips at most N repositories per fire.
  • The weekly flood remains disabled and creates zero tasks.
  • After stabilization, State Hub SBOM rows are retained or removed only through an explicit retention decision.