From 987451f8111f9f89be3952d108162c22490ffd4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Insaurralde?= Date: Thu, 29 Oct 2026 01:11:17 -0300 Subject: [PATCH] feat: add repo_commits_total to the security-context schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an optional repo_commits_total integer to the scan_stats definition of the security-context Chainloop-Trace-Sessions: 8e8e03db-d3cd-4b70-b3f2-1401b06dd4cf Signed-off-by: Matías Insaurralde --- .../aisecuritycontext/ai-security-context-0.1.schema.json | 5 +++++ .../materials/aisecuritycontext/aisecuritycontext.go | 6 ++++++ .../crafter/materials/testdata/ai-security-context.json | 3 ++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/internal/schemavalidators/internal_schemas/aisecuritycontext/ai-security-context-0.1.schema.json b/internal/schemavalidators/internal_schemas/aisecuritycontext/ai-security-context-0.1.schema.json index 581e11156..a98ce2d43 100644 --- a/internal/schemavalidators/internal_schemas/aisecuritycontext/ai-security-context-0.1.schema.json +++ b/internal/schemavalidators/internal_schemas/aisecuritycontext/ai-security-context-0.1.schema.json @@ -429,6 +429,11 @@ "minimum": 0, "description": "How many survivors the context holds at the covered window." }, + "repo_commits_total": { + "type": "integer", + "minimum": 0, + "description": "Total number of commits reachable from the scanned revision (git rev-list --count of the target SHA). The denominator a consumer needs to render scan progress as \"N of M commits\" or a percentage. OPTIONAL: omitted when unknown — a shallow clone (whose count would be truncated) or an artifact produced before this field existed. The managed flow mirror-clones full history, so it is populated there. A snapshot of repository size, not a funnel counter, so it is not part of the reconciles invariant." + }, "pending_survivors": { "type": "integer", "minimum": 0, diff --git a/pkg/attestation/crafter/materials/aisecuritycontext/aisecuritycontext.go b/pkg/attestation/crafter/materials/aisecuritycontext/aisecuritycontext.go index 101fbac31..9505fb91c 100644 --- a/pkg/attestation/crafter/materials/aisecuritycontext/aisecuritycontext.go +++ b/pkg/attestation/crafter/materials/aisecuritycontext/aisecuritycontext.go @@ -117,6 +117,12 @@ type ScanStats struct { // SurvivorsTotal is how many survivors the context holds at the covered // window. SurvivorsTotal int `json:"survivors_total,omitempty"` + // RepoCommitsTotal is the total number of commits reachable from the scanned + // revision — the denominator a consumer renders scan progress against + // ("N of M commits"). A snapshot pinned to the target SHA, not a funnel counter, + // so it is outside the reconciles invariant. Omitted (zero) when unknown: a + // shallow clone, or an artifact produced before this field existed. + RepoCommitsTotal int `json:"repo_commits_total,omitempty"` // PendingSurvivors is how many survivors still await adjudication: neither in // the frontier, nor a triage hole, nor abandoned after the retry cap. Zero // alongside AdjudicationComplete is the drained queue. diff --git a/pkg/attestation/crafter/materials/testdata/ai-security-context.json b/pkg/attestation/crafter/materials/testdata/ai-security-context.json index 7c8bea572..7bc5b5892 100644 --- a/pkg/attestation/crafter/materials/testdata/ai-security-context.json +++ b/pkg/attestation/crafter/materials/testdata/ai-security-context.json @@ -53,7 +53,8 @@ "sha": "d514564a92bf4f472b0ac21cbac794a9494346f4", "reason": "diff too large (2065160 bytes)" } - ] + ], + "repo_commits_total": 149841 }, "class_counts": { "access_control": 1,