Expose SBOM controlled source 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-23 01:39:38 +02:00
parent c1d5e4a9dd
commit 34867d784f
3 changed files with 61 additions and 10 deletions

View file

@ -762,6 +762,22 @@ def _sbom_catchup_report(instr: Any, catchup: dict) -> InstructionResult:
updated = [r for r in catchup.get("updated", []) if isinstance(r, dict)]
skipped = [r for r in catchup.get("skipped", []) if isinstance(r, dict)]
limit = catchup.get("limit")
selected_repos = []
controlled_source_count = 0
for repo in selected:
item = {
"repo_slug": repo.get("repo_slug"),
"sbom_age_days": repo.get("sbom_age_days"),
"has_sbom": repo.get("has_sbom"),
"last_sbom_at": repo.get("last_sbom_at"),
"checkout_available": repo.get("checkout_available"),
}
source_ref = _safe_sbom_source_ref(repo.get("source_ref"))
if source_ref is not None:
item["source_ref"] = source_ref
controlled_source_count += 1
selected_repos.append(item)
report: dict[str, Any] = {
"summary": (
f"SBOM catch-up: {len(selected)} selected (limit {limit}), "
@ -773,19 +789,11 @@ def _sbom_catchup_report(instr: Any, catchup: dict) -> InstructionResult:
"deterministic": True,
"limit": limit,
"selected_count": len(selected),
"controlled_source_count": controlled_source_count,
"stale_count": catchup.get("stale_count"),
"never_count": catchup.get("never_count"),
"total_count": catchup.get("total_count"),
"selected_repos": [
{
"repo_slug": r.get("repo_slug"),
"sbom_age_days": r.get("sbom_age_days"),
"has_sbom": r.get("has_sbom"),
"last_sbom_at": r.get("last_sbom_at"),
"checkout_available": r.get("checkout_available"),
}
for r in selected
],
"selected_repos": selected_repos,
"updated_repos": [r.get("repo_slug") for r in updated],
"skipped_repos": [
{"repo_slug": r.get("repo_slug"), "reason": r.get("reason")}
@ -803,6 +811,23 @@ def _sbom_catchup_report(instr: Any, catchup: dict) -> InstructionResult:
)
def _safe_sbom_source_ref(raw: Any) -> dict[str, str] | None:
"""Keep only the reviewable controlled-source identity in progress evidence."""
if not isinstance(raw, dict) or raw.get("kind") != "forgejo-archive-v1":
return None
repository = raw.get("repository")
revision = raw.get("revision")
if not isinstance(repository, str) or not repository.strip():
return None
if not isinstance(revision, str) or re.fullmatch(r"[0-9a-f]{40}", revision) is None:
return None
return {
"kind": "forgejo-archive-v1",
"repository": repository,
"revision": revision,
}
def _validate_output(
raw_output: Any,
instr: Any,

View file

@ -640,6 +640,12 @@ def test_deterministic_report_names_selected_repos() -> None:
"sbom_age_days": 9999,
"has_sbom": False,
"checkout_available": True,
"source_ref": {
"kind": "forgejo-archive-v1",
"repository": "coulomb/never-scanned",
"revision": "a" * 40,
"archive_url": "must-not-enter-progress-evidence",
},
},
{
"repo_slug": "no-checkout",
@ -647,6 +653,11 @@ def test_deterministic_report_names_selected_repos() -> None:
"sbom_age_days": 112,
"has_sbom": True,
"checkout_available": False,
"source_ref": {
"kind": "forgejo-archive-v1",
"repository": "coulomb/no-checkout",
"revision": "not-a-full-sha",
},
},
],
"selected_count": 2,
@ -663,6 +674,7 @@ def test_deterministic_report_names_selected_repos() -> None:
report = result.report
assert report["deterministic"] is True
assert report["never_count"] == 93
assert report["controlled_source_count"] == 1
assert [r["repo_slug"] for r in report["selected_repos"]] == [
"never-scanned",
"no-checkout",
@ -670,6 +682,12 @@ def test_deterministic_report_names_selected_repos() -> None:
assert "93 never scanned of 111 repos" in report["summary"]
assert report["updated_repos"] == []
assert report["skipped_repos"] == []
assert report["selected_repos"][0]["source_ref"] == {
"kind": "forgejo-archive-v1",
"repository": "coulomb/never-scanned",
"revision": "a" * 40,
}
assert "source_ref" not in report["selected_repos"][1]
def test_deterministic_report_carries_t02_ingest_outcomes() -> None:

View file

@ -61,3 +61,11 @@ processed exactly that frozen set, spawned zero tasks, and produced three
provenance-bearing `no-manifest` snapshots. `never_count` advanced 94 to 91.
Keep open for the first unassisted weekday fire and sustainable projection of
each newly exposed oldest-N batch.
Preflight 2026-08-23: after the controlled batch advanced, the newly exposed
oldest three (`citation-work`, `clay-borg`, `config-atlas`) each carried a
matching `forgejo-archive-v1` reference and a 40-character revision, confirming
projection is not limited to the attended batch. The deterministic catch-up
report now retains only the allowlisted kind/repository/revision fields and a
`controlled_source_count`, so the first unassisted fire can prove provenance
directly in State Hub without copying Nexus payloads or archive URLs.