--- id: weekly-sbom-staleness name: Weekly SBOM Staleness Check enabled: true owner: custodian-agent governance: custodian status: active trigger: type: cron cron_expression: "0 9 * * 1" timezone: Europe/Berlin misfire_policy: skip context_sources: - type: state-hub query: repo_sbom_status params: repos: all bind_to: context.repos # Resolver returns a summary keyed off the worst repo so the rule expression # below can match without comprehensions (the sandboxed evaluator does not # support them). See _repo_sbom_status in context_resolvers/state_hub.py. --- # Weekly SBOM Staleness Check Runs every Monday at 09:00 Berlin time. Checks all tracked repositories for SBOM staleness and flags any repository whose SBOM is older than 30 days. ```rule id: flag-stale-sbom condition: 'context.repos.sbom_age_days > 30' action: task_template: tasks/sbom-rescan.md target_repo: context.repos.repo_slug priority: medium labels: ["sbom", "security", "automated"] ``` NOTE: in the production bulk-mode resolver path the condition matches against the **worst** repo's age (the resolver hoists the worst entry's `sbom_age_days`, `repo_slug`, `last_sbom_at`, `has_sbom` to the top of `context.repos` alongside the per-repo list and summary counts). The rule therefore fires at most once per workflow run, not once per stale repo. The aspirational per-stale-repo task fan-out is exercised by the integration tests' simulated pipeline but is not delivered by the current workflow — landing it requires (a) per-iteration context binding in the workflow and (b) `context.*` interpolation in rule action fields. Both are tracked as `ADHOC-2026-06-01-T02`.