1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
use super::*;
impl Harness {
/// Aggregate per-run hashes into the final report.
pub(crate) fn build_report(
&self,
per_run_hashes: Vec<BTreeMap<String, ArtifactInfo>>,
) -> DeterminismReport {
// Union of artifact names across runs — an artifact missing from
// one run is itself a form of drift, surfaced as the run's hash
// becoming `<missing>`.
let mut all_names: BTreeSet<String> = BTreeSet::new();
for run in &per_run_hashes {
for name in run.keys() {
all_names.insert(name.clone());
}
}
let mut artifacts: Vec<ArtifactRow> = Vec::new();
let mut drift: Vec<DriftRow> = Vec::new();
let mut drift_count: u32 = 0;
// Authoritative produced-artifact set, parsed from the run's
// `artifacts.json` manifest. Any dist file whose basename appears
// here is a tracked primary — this covers template / extra /
// uploadable files whose extension `infer_stage_from_path` cannot
// classify (e.g. `install.sh`).
let manifest_members = self.produced_member_basenames(&per_run_hashes);
// Basenames the manifest flags as combined checksums files via the
// `combined = "true"` marker — the authoritative aggregate signal,
// independent of the operator's chosen filename (e.g. `SHA512SUMS`).
let combined_markers = self.produced_combined_markers(&per_run_hashes);
for name in &all_names {
let mut hashes: Vec<String> = Vec::with_capacity(per_run_hashes.len());
// Use the LAST run that produced the artifact as the source
// of truth for path/size (matches "last writer wins"
// semantics for the cosmetic fields).
let mut last_info: Option<&ArtifactInfo> = None;
for run in &per_run_hashes {
match run.get(name) {
Some(info) => {
hashes.push(info.hash.clone());
last_info = Some(info);
}
None => hashes.push("<missing>".into()),
}
}
let info = last_info.expect("artifact name came from union of run maps");
let all_equal =
hashes.iter().all(|h| h == &hashes[0]) && !hashes.iter().any(|h| h == "<missing>");
// Byte-equality is the determinism verdict; classification only
// excuses a DRIFTING aggregate (below). An unclassified file fails
// only when its bytes drift — a stable one cannot mask member
// drift: every member is independently hashed and surfaces its own
// drift row regardless of any aggregate that contains it.
let classification =
self.classify(name, &all_names, &manifest_members, &combined_markers);
if matches!(classification, Classification::Unclassified) {
artifacts.push(ArtifactRow {
name: name.clone(),
path: info.relative_path.clone(),
size_bytes: info.size_bytes,
stage: info.stage.clone(),
deterministic: all_equal,
nondeterministic_reason: None,
hash: if all_equal {
Some(hashes[0].clone())
} else {
None
},
hashes: if all_equal { vec![] } else { hashes.clone() },
});
if !all_equal {
drift.push(DriftRow {
artifact: name.clone(),
hashes,
differing_bytes_summary: Some(
"unclassified produced file drifted across runs; if it is a \
combined checksums file, mark it combined=true so its members \
can be evaluated — otherwise it is a real regression"
.into(),
),
});
drift_count += 1;
}
continue;
}
// Transitive-derivation rule: a drifting aggregate is excused IFF
// every differing member is itself allow-listed. An unexcused
// member is a real regression; an aggregate whose members cannot
// be reconstructed fails closed (never excused).
let mut aggregate_excuse: Option<String> = None;
if !all_equal && matches!(classification, Classification::Aggregate) {
let kind = self
.aggregate_kind_for_name(name, &combined_markers)
.expect("Aggregate classification ⇒ a registered kind matches");
match self.evaluate_aggregate(
kind.as_ref(),
name,
&per_run_hashes,
&combined_markers,
) {
AggregateVerdict::Excused(reason) => aggregate_excuse = Some(reason),
AggregateVerdict::Regression(members) => {
artifacts.push(ArtifactRow {
name: name.clone(),
path: info.relative_path.clone(),
size_bytes: info.size_bytes,
stage: info.stage.clone(),
deterministic: false,
nondeterministic_reason: None,
hash: None,
hashes: hashes.clone(),
});
// One drift row per aggregate (keeps the report's
// `drift_count == drift.len()` invariant); the
// offending members are named in both the artifact
// field and the summary.
let joined = members.join(", ");
drift.push(DriftRow {
artifact: format!("{name} → {joined}"),
hashes,
differing_bytes_summary: Some(format!(
"aggregate member(s) [{joined}] drifted and are not allow-listed; \
a gated artifact regressed (surfaced via the {name} aggregate)"
)),
});
drift_count += 1;
continue;
}
AggregateVerdict::FailClosed(reason) => {
artifacts.push(ArtifactRow {
name: name.clone(),
path: info.relative_path.clone(),
size_bytes: info.size_bytes,
stage: info.stage.clone(),
deterministic: false,
nondeterministic_reason: None,
hash: None,
hashes: hashes.clone(),
});
drift.push(DriftRow {
artifact: name.clone(),
hashes,
differing_bytes_summary: Some(reason),
});
drift_count += 1;
continue;
}
}
}
// Sign-stage drift auto-allowlist: cosign sign-blob uses
// ECDSA P-256 with a random nonce, so its signature bytes
// can never be byte-identical across runs. Byte-equality is
// not the right determinism signal for signatures —
// verification (`cosign verify-blob` / `gpg --verify`) is.
let signed_artifact_drift = !all_equal && info.stage == "sign";
let allow_reason = aggregate_excuse
.or_else(|| self.resolve_allow_reason(name))
.or_else(|| {
if signed_artifact_drift {
Some(
"signed artifact: signature bytes vary by signer \
(cosign ECDSA random nonce); validate via \
`cosign verify-blob` / `gpg --verify`"
.into(),
)
} else {
None
}
});
if all_equal {
artifacts.push(ArtifactRow {
name: name.clone(),
path: info.relative_path.clone(),
size_bytes: info.size_bytes,
stage: info.stage.clone(),
deterministic: true,
nondeterministic_reason: allow_reason.clone(),
hash: Some(hashes[0].clone()),
hashes: vec![],
});
} else {
artifacts.push(ArtifactRow {
name: name.clone(),
path: info.relative_path.clone(),
size_bytes: info.size_bytes,
stage: info.stage.clone(),
deterministic: false,
nondeterministic_reason: allow_reason.clone(),
hash: None,
hashes: hashes.clone(),
});
// Drift row + drift_count are gated on allow-list status:
// allow-listed artifacts surface their per-run hashes via
// the drift row (so the audit trail is complete) but DO
// NOT bump `drift_count`.
if allow_reason.is_none() {
let summary = summarize_drift(name, &per_run_hashes);
drift.push(DriftRow {
artifact: name.clone(),
hashes,
differing_bytes_summary: summary,
});
drift_count += 1;
}
}
}
DeterminismReport {
schema_version: CURRENT_SCHEMA_VERSION,
anodize_version: env!("CARGO_PKG_VERSION").into(),
commit: self.commit.clone(),
commit_timestamp: self.sde,
runs: self.runs,
stages_under_test: self.stages.iter().map(|s| s.as_str().into()).collect(),
allowlist: self.allowlist.clone(),
artifacts,
drift,
drift_count,
}
}
}