Harden SBOM retries and align hub evidence
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Container Image / build-and-push (push) Successful in 21s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a028de-e2c8-7732-8521-46a7fc5db82f
This commit is contained in:
tegwick 2026-08-22 22:51:13 +02:00
parent 0f573c4378
commit 3b3e1a1ff0
17 changed files with 941 additions and 140 deletions

View file

@ -4,11 +4,11 @@ type: workplan
title: "Hub port and schedule alignment for State Hub retirement"
domain: infotech
repo: activity-core
status: active
status: finished
owner: grok
topic_slug: infotech
created: "2026-08-09"
updated: "2026-08-18"
updated: "2026-08-22"
parent_project: prj-state-hub-retirement
parent_workplan: SHR-WP-0001
stream: S5
@ -107,16 +107,27 @@ inside this repo.
```task
id: ACTIVITY-WP-0029-T03
status: wait
status: done
priority: medium
state_hub_task_id: "3fbadbfe-9107-4869-b53f-3b9b46e0555a"
```
Wait on **HUB-WP-0004** (ports still `proposed`) and the CORE-WP-0010
absorption path. Interaction-event / progress evidence follows the
**hub-core** runtime, not a permanent core-hub or State Hub host. Update
smokes when the port exists. Until then, keep the State Hub beachhead
(ACTIVITY-WP-0015) as the compatibility sink.
HUB-WP-0004 finished and hub-core became production authority on 2026-08-21.
Activity-core now implements `hub-core-interaction-event` against canonical
`POST /ports/events/interaction`, then verifies the accepted id through
`GET /ports/projections/interaction_events`. The Railiance projection points
`HUB_CORE_BASE_URL` at the in-cluster hub-core runtime and uses this sink; it
does not require the legacy Core Hub widget mapping/runtime-token contract.
The old `core-hub-interaction-event` compatibility sink remains available for
the no-writer rollback window, but is no longer the configured probe path.
General progress callers not yet moved by the retirement strangler continue to
use the State Hub beachhead rather than creating another permanent authority.
Unit and deployment-wiring tests cover catalog envelope shape, readback,
sanitization, missing configuration, and the in-cluster target. A disposable
integration smoke against hub-core 0.2.0 returned `202 Accepted` from the
canonical interaction port and verified the new event through the interaction
projection.
## Execution queue boundary
@ -138,6 +149,6 @@ index, issue-core lifecycle, ITC Task Model types, policy-nexus publication.
(`docs/state-hub-caller-map.md`)
- [x] Sweep still fires from activity-core and hits repo-manager (or dual-run)
(`CONSISTENCY_SWEEP_URL` / `REPO_MANAGER_URL`; default State Hub adapter)
- [x] Evidence sink plan names hub-core as the permanent host; T03 stays wait until that port exists
- [x] Ops evidence uses hub-core's canonical interaction port; the legacy Core Hub sink is rollback-only
- [x] Execution boundary is written so `/execution/*` cannot be read as "activity-core owns tasks"
(`docs/execution-queue-boundary.md`, `GET /execution/semantics`, 410 on workplan routes)

View file

@ -4,7 +4,7 @@ type: workplan
title: "Daily bounded SBOM catch-up via sbom-nexus"
domain: infotech
repo: activity-core
status: done
status: finished
owner: grok
topic_slug: infotech
created: "2026-08-18"

View file

@ -0,0 +1,90 @@
---
id: ACTIVITY-WP-0033
type: workplan
title: "Bound SBOM catch-up across Temporal retries"
domain: infotech
repo: activity-core
status: finished
owner: codex
topic_slug: infotech
created: "2026-08-22"
updated: "2026-08-22"
related:
- ACTIVITY-WP-0030
- CUST-WP-0062
- SBOM-WP-0002
---
# Bound SBOM catch-up across Temporal retries
## Goal
Preserve ACTIVITY-WP-0030's oldest-N bound when Temporal retries an activity or
an SBOM Nexus response is ambiguous. Activity Core can independently guarantee
that one workflow fire retains one fixed set of at most N distinct repository
targets. Exact once-only snapshot creation remains a Nexus-side idempotency
follow-up.
## Separate selection from mutation
```task
id: ACTIVITY-WP-0033-T01
status: done
priority: high
```
Keep `resolve_context` and the `sbom-nexus / catch_up` resolver read-only even
when the definition declares `apply: true`. Compute the deterministic run id
before context resolution, then pass the already-truncated selection to a
dedicated Temporal activity. Retries must reuse that same selection rather than
querying the next batch.
## Resume bounded outcomes safely
```task
id: ACTIVITY-WP-0033-T02
status: done
priority: high
```
Heartbeat completed per-repository outcomes so an ordinary activity retry does
not repeat acknowledged targets. Send a stable per-run/per-repository
`Idempotency-Key` for forward compatibility with Nexus enforcement. Never turn
an HTTP timeout, transport error, or malformed success response into a second
synthetic skip: the result is ambiguous and must fail visibly against the same
fixed target set.
## Verification and handoff
```task
id: ACTIVITY-WP-0033-T03
status: done
priority: medium
```
Cover read-only selection, fixed-target retry, heartbeat resume, duplicate
target collapse, stable request identity, and ambiguous-response behavior.
Update the runbook and hand the remaining exactly-once enforcement requirement
to SBOM Nexus without claiming it is solved locally.
Completed 2026-08-22. `resolve_context` now only selects and normalises a
deduplicated oldest-N set. `RunActivityWorkflow` records that selection before
calling the registered `apply_sbom_catchup` activity, protected by Temporal
patch marker `activity-wp-0033-sbom-retry-boundary`. The apply activity resumes
terminal outcomes from heartbeat details and sends a deterministic UUID
operation key for each workflow-run/repository pair. Ambiguous HTTP and
contract failures remain failures against the same fixed target instead of
creating `ingest-error` skip snapshots.
Verification: 27 focused SBOM tests and 417 repository tests passed; the one
live NATS-to-Temporal bridge test was deselected because it requires the local
integration stack. Python compilation and `git diff --check` also passed.
## Acceptance
- [x] Context resolution performs no SBOM mutation
- [x] One workflow fire retains at most N distinct targets across retries
- [x] Heartbeat replay skips outcomes already acknowledged by the activity
- [x] Ambiguous ingest responses do not create synthetic skip snapshots
- [x] Stable operation identity is sent for future Nexus enforcement
- [x] Focused and repository-wide Activity Core verification pass