From f8c961414b267db28df78e6ab08affdcff64675f Mon Sep 17 00:00:00 2001 From: tegwick Date: Sat, 22 Aug 2026 20:15:52 +0200 Subject: [PATCH] docs: close SBOM-WP-0002 T04 Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a028f0-a42f-7582-89a8-ebaad7343834 --- ...T04-state-hub-facade-cutover-2026-08-22.md | 117 ++++++++++++++++++ workplans/SBOM-WP-0002-production-cutover.md | 10 +- 2 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 docs/evidence/SBOM-WP-0002-T04-state-hub-facade-cutover-2026-08-22.md diff --git a/docs/evidence/SBOM-WP-0002-T04-state-hub-facade-cutover-2026-08-22.md b/docs/evidence/SBOM-WP-0002-T04-state-hub-facade-cutover-2026-08-22.md new file mode 100644 index 0000000..e46aea5 --- /dev/null +++ b/docs/evidence/SBOM-WP-0002-T04-state-hub-facade-cutover-2026-08-22.md @@ -0,0 +1,117 @@ +# SBOM-WP-0002 T04 — State Hub façade cutover evidence + +Date: 2026-08-22 +Environment: Railiance production cluster, private `state-hub` and `sbom-nexus` +Namespaces + +## Result + +State Hub SBOM compatibility reads and writes now use SBOM Nexus behind two +independent, reversible flags. The legacy State Hub SBOM tables remain intact; +no historical rows were deleted. + +## Deployed revisions + +- SBOM Nexus package ingress admission: `rapp-sbom-nexus` commit `07ae686` +- State Hub read façade: `5fc4c56` +- legacy source-value compatibility: `9851809` +- independently flagged write façade: `b75234a` +- summary, repository freshness, and DoI projections: `76e6eda` +- declared State Hub chart version: `main-76e6eda` (`52aefe3`) +- live image: `forgejo.coulomb.social/coulomb/state-hub:main-76e6eda` +- live Helm release: revision 18, status `deployed`, app version + `main-76e6eda` + +Forgejo CI smoke checks and the multi-context image build succeeded for every +application revision promoted above. + +## Network and rollout controls + +- SBOM Nexus remains a private ClusterIP service with no Ingress or + LoadBalancer. +- Its runtime NetworkPolicy admits port 8010 from only `sbom-nexus` and + `state-hub` namespaces. +- A live request from the State Hub pod to Nexus health returned PostgreSQL + `connected`. +- State Hub exposes `SBOM_NEXUS_READ_MODE` and `SBOM_NEXUS_WRITE_MODE`, each + accepting `legacy` or `nexus`; production is `nexus nexus`. +- The pod template hashes the ConfigMap. Rendering read mode `legacy` produced + a different checksum from the live `nexus` value, proving that one-value + rollback triggers a rollout. +- The production CPU request was reduced from 250m to 100m after the one-node + cluster reported only 160m unallocated. This preserved `maxSurge=1` and + allowed subsequent zero-downtime rollouts. + +## Compatibility behavior + +- GET routes proxy to Nexus without silent fallback. Nexus transport failures + are visible as 502 responses; a missing configured URL is visible as 503. +- Snapshot IDs, timestamps, entry counts, filters, and response models are + preserved. Nexus repository UUIDs are translated to the corresponding local + State Hub repository UUID. +- Qualified historical provenance such as `state-hub:manual` is translated + back to legacy response value `manual`; Nexus retains the qualified value. +- POST `/sbom/ingest/` routes only to Nexus in write mode `nexus`. A successful + response updates State Hub's compatibility projection (`last_sbom_at` and + `sbom_source=sbom-nexus`) but creates no legacy State Hub snapshot. +- `last_sbom_at` reads and DoI C8 use Nexus `last_attempt_at`, matching the + documented cutover choice. +- State summary/dashboard licence risk, snapshot count, package total, and SBOM + cache revision are derived from Nexus. +- Dashboard and MCP already consume the State Hub `/sbom/*` routes; the CLI and + onboarding ingest command continue to post to the same compatibility route, + so no caller-side contract change was required. + +Focused test evidence: + +- SBOM read/write/projection suite: 6 passed +- existing summary/cache regression plus compatibility suite: 14 passed +- earlier full State Hub suite: 630 passed, with one unrelated failure caused + by concurrent `review_contract` models increasing a hard-coded foreign-key + count from 20 to 22 +- State Hub client and server Helm dry-runs passed +- SBOM Nexus package tests and server dry-run passed + +## Production reconciliation and acceptance probes + +The pre-switch cluster State Hub store had 21 snapshots and 2,578 current +entries. The previously reconciled Nexus authority had 22 snapshots and 2,659 +current entries. Normalized comparison showed: + +- zero cluster snapshot IDs missing from Nexus; +- zero cluster current entries missing from Nexus; +- one additional Nexus snapshot, for `fin-hub`; +- 81 additional current `fin-hub` entries; +- direct-production copyleft count remained 4. + +The difference was expected freshness: Nexus was imported from the canonical +workstation State Hub, while the cluster catalog lacked `fin-hub`. The missing +repository identity was registered in cluster State Hub under `infotech`; the +façade then translated all Nexus associations without weakening its fail-closed +referential check. Classification fields were left unset because the deployed +State Hub image lacks its classification allow-list artifact; that packaging +defect is outside the SBOM authority cutover. + +Final live probes through State Hub returned: + +- 22 snapshots; +- 2,659 current entries; +- 3,123 entries summed across historical snapshots in dashboard overview; +- direct-production copyleft count 4 in summary and overview; +- `fin-hub` entry count 81; +- `fin-hub.last_sbom_at=2026-07-08T20:37:48.255925Z`; +- `fin-hub.sbom_source=sbom-nexus`; +- snapshot detail entry count 81/81 and local State Hub repository UUIDs. + +Legacy-meter reported all five exercised GET route families with +`replacement_verified=true`; observed two-hour counts were 4 for `/sbom/`, 4 +for the licence report, 5 for snapshot listing, 1 for snapshot detail, and 1 +for repository view. No production canary ingest was created merely to exercise +the write route; write authority is evidenced by focused tests, live +configuration, and the deployed immutable image. + +## Security incident note + +This slice used only non-secret HTTP data and Kubernetes metadata. The earlier +T01 attended-login token exposure was revoked immediately and remains documented +in the T03 evidence; no credential value was copied into this evidence. diff --git a/workplans/SBOM-WP-0002-production-cutover.md b/workplans/SBOM-WP-0002-production-cutover.md index 7bd0776..6792d95 100644 --- a/workplans/SBOM-WP-0002-production-cutover.md +++ b/workplans/SBOM-WP-0002-production-cutover.md @@ -97,7 +97,7 @@ run returned `already_present=22`. No caller was switched. ```task id: SBOM-WP-0002-T04 -status: todo +status: done priority: high state_hub_task_id: "e7681dce-e3b6-52d1-bf13-92595b082b09" ``` @@ -105,6 +105,14 @@ state_hub_task_id: "e7681dce-e3b6-52d1-bf13-92595b082b09" Depends on T03 and the State Hub child change. Move reads then writes behind reversible flags; retarget dashboard, MCP, CLI, summary, DoI, and onboarding. +Completed in production with independent `SBOM_NEXUS_READ_MODE` and +`SBOM_NEXUS_WRITE_MODE` flags set to `nexus`. The State Hub façade preserves +legacy response models and repository UUIDs, projects Nexus `last_attempt_at` +as `last_sbom_at`, routes future ingest only to Nexus, and sources dashboard +and summary SBOM metrics from Nexus. Helm ConfigMap checksums make one-value +read or write rollback trigger a real pod rollout. See +`docs/evidence/SBOM-WP-0002-T04-state-hub-facade-cutover-2026-08-22.md`. + ## Retarget Repo Manager scanner interface ```task