activity-core/activity-definitions/daily-sbom-catchup.md
tegwick 8e8c74bd4c
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 23s
Implement bounded SBOM Nexus catch-up
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a028f0-a42f-7582-89a8-ebaad7343834
2026-08-22 20:45:02 +02:00

102 lines
3.8 KiB
Markdown

---
id: daily-sbom-catchup
name: Daily SBOM Catch-up
enabled: false
owner: custodian-agent
governance: custodian
status: paused
trigger:
type: cron
cron_expression: "15 9 * * 1-5" # weekdays 09:15, after the daily triage window
timezone: Europe/Berlin
misfire_policy: skip
context_sources:
- type: sbom-nexus
query: catch_up
required: true
params:
limit: 3 # catch_up_limit — operator knob, not a nexus constant
apply: true # declared bounded side-effect; manual runs require confirmation
bind_to: context.catchup
# One ranked call returns only the N repos that have lacked a current SBOM the
# longest (never-scanned first) plus fleet counts. There is deliberately no
# `for_each` over the stale set: the 2026-08-17 fire emitted 75 tasks that way.
---
# Daily SBOM Catch-up
> **Disabled until production enable evidence is ready.** The `sbom-nexus`
> ranked and terminal ingest/skip APIs are now available. Keep this definition
> off until cluster reachability and a bounded manual fire are proven.
Replaces `weekly-sbom-staleness` / `flag-stale-sbom` (ACTIVITY-WP-0030).
The weekly check reported the backlog — 111 / 111 repos stale on 2026-08-18,
93 never scanned — and spawned one task per stale repo, so it could never
close it. This definition **updates N instead of reporting N**.
Runs weekdays at 09:15 Berlin, after the daily triage window.
## Contract
Context source `sbom-nexus / catch_up` (`context_resolvers/sbom_nexus.py`):
| Direction | Shape |
| --- | --- |
| input | `{"limit": 3}` |
| output | `{repos, selected_count, stale_count, never_count, total_count, limit}` |
| each repo | `repo_slug`, `last_sbom_at`, `sbom_age_days`, `has_sbom`, `checkout_available` |
Ranking (never-scanned first, then oldest `last_sbom_at`) belongs to
sbom-nexus. The adapter truncates to `limit` so an over-long response can never
widen the bounded side-effect below.
## Task emission
None. This definition carries **no `rule` block** — that is the point of the
replacement. `tasks_spawned` must stay 0 on every fire, and no Forgejo issues
are emitted (ACTIVITY-WP-0022).
## Evidence
```instruction
id: daily-sbom-catchup-report
trusted_fields: []
model: deterministic
temperature: 0
max_tokens: 1
prompt: |
Deterministic SBOM catch-up report from context.catchup (no LLM).
output_schema: ""
review_required: false
report_sinks:
- type: state-hub-progress
event_type: sbom_catchup
author: activity-core
topic_id: cee7bedf-2b48-46ef-8601-006474f2ad7a
```
The progress event names the repos selected, updated, and skipped with a
reason (`no-checkout`, `no-manifest`, `ingest-error`), plus the fleet counters
so `never_count` can be watched declining day over day.
## Bounded side-effect (ACTIVITY-WP-0030-T02)
`params.apply: true` calls sbom-nexus for each of the already-truncated N
targets. A target with an explicitly unavailable checkout is recorded through
`POST /sbom/{slug}/skip` as `no-checkout`; other targets use the terminal ingest
route, which returns `ingested`, `no-manifest`, or `ingest-error`. Transport and
contract failures are recorded as `ingest-error`. The resulting `updated` and
`skipped` arrays are part of the run context and progress report. There is no
task or issue emission.
## Enable checklist
1. CUST-WP-0062-T02/T03 done: `sbom-nexus` stood up, `GET /sbom/catch-up`
returns oldest-N in one call. **Done 2026-08-22.**
2. `SBOM_NEXUS_URL` reachable from the railiance01 worker.
3. ACTIVITY-WP-0030-T02 ingest side-effect implemented and dry-run proven.
4. `weekly-sbom-staleness` confirmed off in source **and** production
(ACTIVITY-WP-0030-T03).
5. Project into `k8s/railiance/20-runtime.yaml`, `enabled: true`, sync
schedules, capture evidence via `./scripts/prod_automation_status.sh`
(ACTIVITY-WP-0030-T04).