Skip to content

Commit 7ff11c6

Browse files
committed
feat(ci): persist the corpus checksum with each logic-backtest run as its reproducibility freeze point (#8139)
The persisted run recorded the comparison and both shas but not WHICH corpus snapshot it scored -- without that, a skeptical re-run can't prove it replayed the same history. The manifest's own checksum (#8084) is already in hand at run time; thread it into the persisted metadata and the PR comment, so checksum + head/base shas + the public scoring code make every run independently re-runnable end to end (the reproducible-backtest posture #8136 is evaluating).
1 parent 0d20158 commit 7ff11c6

3 files changed

Lines changed: 20 additions & 7 deletions

File tree

scripts/backtest-logic-check-core.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,22 +131,24 @@ export function runLogicBacktest(
131131
export const LOGIC_BACKTEST_COMMENT_MARKER = "<!-- loopover-logic-backtest -->";
132132

133133
/**
134-
* Render the standalone advisory PR comment: marker, what was replayed against what, the engine's own
135-
* comparison Markdown (#8088), and the never-blocks-merge note. Deliberately its OWN comment, not a section
136-
* of ORB's unified review comment — see #8139's Boundaries (this CI job runs outside the Worker's review
137-
* flow, and joining that comment would need new Worker↔CI coupling).
134+
* Render the standalone advisory PR comment: marker, what was replayed against what (including the corpus
135+
* checksum — the freeze point that makes the run independently re-runnable, see #8084's manifest), the
136+
* engine's own comparison Markdown (#8088), and the never-blocks-merge note. Deliberately its OWN comment,
137+
* not a section of ORB's unified review comment — see #8139's Boundaries (this CI job runs outside the
138+
* Worker's review flow, and joining that comment would need new Worker↔CI coupling).
138139
*/
139140
export function renderLogicBacktestComment(
140141
comparison: BacktestComparison,
141-
info: { replayableCount: number; skippedCount: number; headSha: string; baseSha: string },
142+
info: { replayableCount: number; skippedCount: number; headSha: string; baseSha: string; corpusChecksum: string },
142143
): string {
143144
const skippedNote = info.skippedCount > 0 ? ` ${info.skippedCount} historical case(s) lacked captured raw context and were skipped.` : "";
144145
return [
145146
LOGIC_BACKTEST_COMMENT_MARKER,
146147
"## Logic backtest",
147148
"",
148149
`Replayed ${info.replayableCount} historical case(s) for \`${comparison.ruleId}\` through the base` +
149-
` (\`${info.baseSha.slice(0, 7)}\`) and head (\`${info.headSha.slice(0, 7)}\`) versions of its detection logic.${skippedNote}`,
150+
` (\`${info.baseSha.slice(0, 7)}\`) and head (\`${info.headSha.slice(0, 7)}\`) versions of its detection logic` +
151+
` (corpus checksum \`${info.corpusChecksum.slice(0, 12)}\`).${skippedNote}`,
150152
"",
151153
renderBacktestComparison(comparison),
152154
"_Advisory only — this check never blocks merge (#8105)._",
@@ -164,14 +166,17 @@ export function sqlStringLiteral(value: string): string {
164166
* THRESHOLD_BACKTEST_EVENT_TYPE events, same audit_events columns recordAuditEvent writes (the CLI runs
165167
* outside the Worker, so it goes through `wrangler d1 execute` instead of the repositories module; the
166168
* caller supplies id/createdAt so this stays clock-free like the rest of this file). `metadata.comparison`
167-
* is the field backtest-track-record.ts's reader already looks for.
169+
* is the field backtest-track-record.ts's reader already looks for; `corpusChecksum` + the two shas are
170+
* the freeze point (#8136's reproducibility posture) — enough for a skeptic to re-export the corpus,
171+
* verify the checksum, and re-run both sides of this exact comparison independently.
168172
*/
169173
export function buildLogicBacktestAuditInsertSql(input: {
170174
id: string;
171175
targetKey: string;
172176
comparison: BacktestComparison;
173177
headSha: string;
174178
baseSha: string;
179+
corpusChecksum: string;
175180
replayableCount: number;
176181
skippedCount: number;
177182
createdAt: string;
@@ -180,6 +185,7 @@ export function buildLogicBacktestAuditInsertSql(input: {
180185
comparison: input.comparison,
181186
headSha: input.headSha,
182187
baseSha: input.baseSha,
188+
corpusChecksum: input.corpusChecksum,
183189
replayableCount: input.replayableCount,
184190
skippedCount: input.skippedCount,
185191
});

scripts/backtest-logic-check.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ async function main() {
122122
skippedCount,
123123
headSha: args.headSha,
124124
baseSha: args.baseSha,
125+
corpusChecksum: manifest.checksum,
125126
}),
126127
);
127128

@@ -132,6 +133,7 @@ async function main() {
132133
comparison,
133134
headSha: args.headSha,
134135
baseSha: args.baseSha,
136+
corpusChecksum: manifest.checksum,
135137
replayableCount: replayable.length,
136138
skippedCount,
137139
createdAt: new Date().toISOString(),

test/unit/backtest-logic-check-core.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,10 +194,12 @@ describe("backtest-logic-check-core renderLogicBacktestComment (#8139)", () => {
194194
skippedCount: 0,
195195
headSha: "abcdef1234567890",
196196
baseSha: "1234567890abcdef",
197+
corpusChecksum: "feedfacecafe0123456789",
197198
});
198199
expect(comment.startsWith(`${LOGIC_BACKTEST_COMMENT_MARKER}\n## Logic backtest`)).toBe(true);
199200
expect(comment).toContain("Replayed 12 historical case(s) for `linked_issue_scope_mismatch`");
200201
expect(comment).toContain("base (`1234567`) and head (`abcdef1`)");
202+
expect(comment).toContain("corpus checksum `feedfacecafe`");
201203
expect(comment).toContain("### Backtest comparison: `linked_issue_scope_mismatch`");
202204
expect(comment).toContain("never blocks merge (#8105)");
203205
expect(comment).not.toContain("lacked captured raw context");
@@ -209,6 +211,7 @@ describe("backtest-logic-check-core renderLogicBacktestComment (#8139)", () => {
209211
skippedCount: 5,
210212
headSha: "abcdef1234567890",
211213
baseSha: "1234567890abcdef",
214+
corpusChecksum: "feedfacecafe0123456789",
212215
});
213216
expect(comment).toContain("5 historical case(s) lacked captured raw context and were skipped.");
214217
});
@@ -229,6 +232,7 @@ describe("backtest-logic-check-core buildLogicBacktestAuditInsertSql (#8139)", (
229232
comparison,
230233
headSha: "abcdef1234567890",
231234
baseSha: "1234567890abcdef",
235+
corpusChecksum: "feedfacecafe0123456789",
232236
replayableCount: 1,
233237
skippedCount: 2,
234238
createdAt: "2026-07-22T12:00:00.000Z",
@@ -246,6 +250,7 @@ describe("backtest-logic-check-core buildLogicBacktestAuditInsertSql (#8139)", (
246250
expect(metadata.comparison).toEqual(comparison);
247251
expect(metadata.headSha).toBe("abcdef1234567890");
248252
expect(metadata.baseSha).toBe("1234567890abcdef");
253+
expect(metadata.corpusChecksum).toBe("feedfacecafe0123456789");
249254
expect(metadata.replayableCount).toBe(1);
250255
expect(metadata.skippedCount).toBe(2);
251256
});

0 commit comments

Comments
 (0)