activity-core/workplans/ACTIVITY-WP-0030-daily-sbom-catchup.md
tegwick 944fd158de
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 18s
Repair production automation truth and schedule cleanup
2026-08-20 11:20:23 +02:00

127 lines
4.2 KiB
Markdown

---
id: ACTIVITY-WP-0030
type: workplan
title: "Daily bounded SBOM catch-up via sbom-nexus"
domain: infotech
repo: activity-core
status: active
owner: grok
topic_slug: infotech
created: "2026-08-18"
updated: "2026-08-20"
parent_workplan: CUST-WP-0062
related:
- CUST-WP-0062
- ACTIVITY-WP-0022
- ADHOC-2026-06-01
state_hub_workstream_id: "bfe2945e-38df-40d1-94d4-6e4a003ef66d"
---
# Daily bounded SBOM catch-up via sbom-nexus
## Goal
Replace `weekly-sbom-staleness` / `flag-stale-sbom` with a **daily**
ActivityDefinition that:
1. Evaluates fleet SBOM freshness through **sbom-nexus** (one ranked catch-up
call, not a per-repo walk and not a `for_each` over every stale repo).
2. **Updates N** SBOM snapshots for the repos that have lacked a current SBOM
the longest. **N defaults to 3** (`catch_up_limit`).
Parent coordination: **CUST-WP-0062**. Parked 2026-08-18 — do not start until
that parent is unblocked. Do not enable this schedule until the catch-up API
exists.
## Current failure mode
Monday 2026-08-17 prod fire spawned **75** `Run SBOM rescan for {slug}` tasks.
The rule is `for_each: context.repos.repos` where
`context.repo.sbom_age_days > 30`. On 2026-08-18 the hub listed **111 / 111**
repos stale or never scanned. The weekly check reports the backlog; it does
not close it.
`repo_sbom_status` bulk mode already uses `GET /repos/` (age from
`last_sbom_at`) rather than N `/sbom/{slug}` calls. That is still the wrong
shape for catch-up: the worker materialises every repo, then emits one task
each. The replacement must ask sbom-nexus for **only N targets** and then
**ingest** them.
## Tasks
### Draft definition and resolver contract
```task
id: ACTIVITY-WP-0030-T01
status: wait
priority: high
state_hub_task_id: "b216976e-5402-4e40-b282-78c5d021df72"
```
Write `activity-definitions/daily-sbom-catchup.md` (`enabled: false` until
cutover): weekday or daily cron, Berlin morning after triage is fine.
Context source: sbom-nexus `catch_up` with `limit` default 3. Deterministic
progress (`event_type: sbom_catchup`) listing selected / updated / skipped.
No `for_each` over the full stale set.
Resolver contract (implement against a test double until CUST-WP-0062-T03
lands):
- input: `{limit: 3}`
- output: `{repos: [...], stale_count, never_count, total_count, limit}`
- each repo: `repo_slug`, `last_sbom_at`, `sbom_age_days`, `has_sbom`,
`checkout_available` if known
### Implement ingest side-effect for N targets
```task
id: ACTIVITY-WP-0030-T02
status: wait
priority: high
state_hub_task_id: "0d09c0d3-74bd-4f4d-8b27-5006ba010fa3"
```
Wait on CUST-WP-0062-T03. Bounded side-effect (SCOPE: declared purpose only):
for each of the N repos, call sbom-nexus ingest using the registered checkout
when present. Record skip reasons (`no-checkout`, `no-manifest`, `ingest-error`)
in the run artefact and progress event. Do not spawn Forgejo issues
(ACTIVITY-WP-0022). Do not retry a recorded skip as if it were still the
oldest never-scanned repo.
### Retire weekly task flood
```task
id: ACTIVITY-WP-0030-T03
status: progress
priority: high
state_hub_task_id: "18bcfc21-616a-48a2-aac3-cdcef7579913"
```
Emergency containment began 2026-08-20 under ACTIVITY-WP-0031: set
`weekly-sbom-staleness` `enabled: false` in source and production before the
bounded replacement is available. Keep or drop the weekly summary report only
if it no longer emits one task per repo. After the daily job is proven on
railiance01, update the runbook / playbook and prove one Monday window with zero
SBOM task spawns and a successful daily catch-up the same week.
### Prod enable and evidence
```task
id: ACTIVITY-WP-0030-T04
status: wait
priority: medium
state_hub_task_id: "f09144f6-c7f9-41d4-b466-d8a6288e6a21"
```
Project the definition into `k8s/railiance/20-runtime.yaml`, sync schedules,
and capture prod evidence via `./scripts/prod_automation_status.sh` plus the
`sbom_catchup` progress event. Confirm `tasks_spawned` is 0 and N updates
(or documented skips) appear per fire.
## Acceptance
- [ ] Daily definition exists; weekly flood is off
- [ ] Evaluation is one sbom-nexus catch-up call
- [ ] Each fire updates at most N repos (default 3)
- [ ] Progress names the repos and skip reasons
- [ ] Railiance01 evidence for at least two successful daily fires