vdelta 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +171 -0
- package/dist/adapters/vitest/capture.d.ts +50 -0
- package/dist/adapters/vitest/capture.js +7 -0
- package/dist/adapters/vitest/capture.js.map +1 -0
- package/dist/adapters/vitest/recorder.d.ts +31 -0
- package/dist/adapters/vitest/recorder.js +214 -0
- package/dist/adapters/vitest/recorder.js.map +1 -0
- package/dist/adapters/vitest/reporter.d.ts +15 -0
- package/dist/adapters/vitest/reporter.js +97 -0
- package/dist/adapters/vitest/reporter.js.map +1 -0
- package/dist/canonical.d.ts +9 -0
- package/dist/canonical.js +45 -0
- package/dist/canonical.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +264 -0
- package/dist/cli.js.map +1 -0
- package/dist/compare.d.ts +37 -0
- package/dist/compare.js +476 -0
- package/dist/compare.js.map +1 -0
- package/dist/digest.d.ts +5 -0
- package/dist/digest.js +14 -0
- package/dist/digest.js.map +1 -0
- package/dist/gate.d.ts +11 -0
- package/dist/gate.js +135 -0
- package/dist/gate.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/redact.d.ts +10 -0
- package/dist/redact.js +49 -0
- package/dist/redact.js.map +1 -0
- package/dist/render.d.ts +6 -0
- package/dist/render.js +53 -0
- package/dist/render.js.map +1 -0
- package/dist/run.d.ts +19 -0
- package/dist/run.js +158 -0
- package/dist/run.js.map +1 -0
- package/dist/schema.d.ts +236 -0
- package/dist/schema.js +395 -0
- package/dist/schema.js.map +1 -0
- package/dist/store.d.ts +38 -0
- package/dist/store.js +161 -0
- package/dist/store.js.map +1 -0
- package/dist/tree-digest.d.ts +11 -0
- package/dist/tree-digest.js +103 -0
- package/dist/tree-digest.js.map +1 -0
- package/package.json +53 -0
- package/spec/veridelta-1.md +1093 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical JSON serialization (spec §3.5): lexicographically sorted keys,
|
|
3
|
+
* UTF-8, no insignificant whitespace, numbers restricted to integers.
|
|
4
|
+
* Used for run_id derivation and every digest input.
|
|
5
|
+
*/
|
|
6
|
+
export class NonCanonicalValueError extends Error {
|
|
7
|
+
constructor(message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = 'NonCanonicalValueError';
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export function canonicalJson(value) {
|
|
13
|
+
return serialize(value, '$');
|
|
14
|
+
}
|
|
15
|
+
function serialize(value, path) {
|
|
16
|
+
if (value === null)
|
|
17
|
+
return 'null';
|
|
18
|
+
switch (typeof value) {
|
|
19
|
+
case 'boolean':
|
|
20
|
+
return value ? 'true' : 'false';
|
|
21
|
+
case 'number':
|
|
22
|
+
if (!Number.isInteger(value)) {
|
|
23
|
+
throw new NonCanonicalValueError(`non-integer number at ${path}: ${value}`);
|
|
24
|
+
}
|
|
25
|
+
if (!Number.isSafeInteger(value)) {
|
|
26
|
+
throw new NonCanonicalValueError(`unsafe integer at ${path}: ${value}`);
|
|
27
|
+
}
|
|
28
|
+
return String(value);
|
|
29
|
+
case 'string':
|
|
30
|
+
return JSON.stringify(value);
|
|
31
|
+
case 'object': {
|
|
32
|
+
if (Array.isArray(value)) {
|
|
33
|
+
return `[${value.map((v, i) => serialize(v === undefined ? null : v, `${path}[${i}]`)).join(',')}]`;
|
|
34
|
+
}
|
|
35
|
+
const record = value;
|
|
36
|
+
const keys = Object.keys(record)
|
|
37
|
+
.filter((k) => record[k] !== undefined)
|
|
38
|
+
.sort();
|
|
39
|
+
return `{${keys.map((k) => `${JSON.stringify(k)}:${serialize(record[k], `${path}.${k}`)}`).join(',')}}`;
|
|
40
|
+
}
|
|
41
|
+
default:
|
|
42
|
+
throw new NonCanonicalValueError(`unserializable ${typeof value} at ${path}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=canonical.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical.js","sourceRoot":"","sources":["../src/canonical.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAA;IACtC,CAAC;CACF;AAED,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;AAC9B,CAAC;AAED,SAAS,SAAS,CAAC,KAAc,EAAE,IAAY;IAC7C,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,MAAM,CAAA;IACjC,QAAQ,OAAO,KAAK,EAAE,CAAC;QACrB,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAA;QACjC,KAAK,QAAQ;YACX,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC7B,MAAM,IAAI,sBAAsB,CAAC,yBAAyB,IAAI,KAAK,KAAK,EAAE,CAAC,CAAA;YAC7E,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjC,MAAM,IAAI,sBAAsB,CAAC,qBAAqB,IAAI,KAAK,KAAK,EAAE,CAAC,CAAA;YACzE,CAAC;YACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;QACtB,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;QAC9B,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAA;YACrG,CAAC;YACD,MAAM,MAAM,GAAG,KAAgC,CAAA;YAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;iBAC7B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;iBACtC,IAAI,EAAE,CAAA;YACT,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAA;QACzG,CAAC;QACD;YACE,MAAM,IAAI,sBAAsB,CAAC,kBAAkB,OAAO,KAAK,OAAO,IAAI,EAAE,CAAC,CAAA;IACjF,CAAC;AACH,CAAC"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* vdelta CLI (spec §10). Exit-code contract:
|
|
4
|
+
* run — transparent child exit; INV-5 degrades to raw passthrough
|
|
5
|
+
* compare — 0 when the comparison operation succeeds (inconclusive/none
|
|
6
|
+
* results included), 1 on operation failure
|
|
7
|
+
* show — retrieval success (0) / not found (1)
|
|
8
|
+
* gate — report-only: 0 whenever a report is produced, 2 otherwise
|
|
9
|
+
* The report goes to stdout; vdelta diagnostics go to stderr only.
|
|
10
|
+
*/
|
|
11
|
+
import { buildComparisonReport, CompareOperationError } from './compare.js';
|
|
12
|
+
import { buildGateReport, GateOperationError } from './gate.js';
|
|
13
|
+
import { renderReport } from './render.js';
|
|
14
|
+
import { runAndRecord, VDELTA_VERSION } from './run.js';
|
|
15
|
+
import { RunStore, StoreCorruptError } from './store.js';
|
|
16
|
+
import { gitRepoRoot, resolveRef } from './tree-digest.js';
|
|
17
|
+
function emit(report, format) {
|
|
18
|
+
if (format === 'json') {
|
|
19
|
+
process.stdout.write(`${JSON.stringify(report, null, 1)}\n`);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
process.stdout.write(renderReport(report));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function parseReportFlag(args) {
|
|
26
|
+
let format = 'text';
|
|
27
|
+
const rest = [];
|
|
28
|
+
for (let i = 0; i < args.length; i++) {
|
|
29
|
+
const a = args[i];
|
|
30
|
+
if (a === '--report') {
|
|
31
|
+
const v = args[++i];
|
|
32
|
+
if (v !== 'json' && v !== 'text')
|
|
33
|
+
die(`--report expects json|text, got ${v ?? '(none)'}`);
|
|
34
|
+
format = v;
|
|
35
|
+
}
|
|
36
|
+
else if (a.startsWith('--report=')) {
|
|
37
|
+
const v = a.slice('--report='.length);
|
|
38
|
+
if (v !== 'json' && v !== 'text')
|
|
39
|
+
die(`--report expects json|text, got ${v}`);
|
|
40
|
+
format = v;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
rest.push(a);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return { format, rest };
|
|
47
|
+
}
|
|
48
|
+
function die(message, code = 1) {
|
|
49
|
+
process.stderr.write(`vdelta: ${message}\n`);
|
|
50
|
+
process.exit(code);
|
|
51
|
+
}
|
|
52
|
+
async function requireStore() {
|
|
53
|
+
const worktree = await gitRepoRoot(process.cwd());
|
|
54
|
+
if (worktree === null)
|
|
55
|
+
die('not inside a git worktree');
|
|
56
|
+
return { store: new RunStore(worktree), worktree };
|
|
57
|
+
}
|
|
58
|
+
async function cmdRun(argv) {
|
|
59
|
+
const sep = argv.indexOf('--');
|
|
60
|
+
if (sep === -1)
|
|
61
|
+
die('usage: vdelta run [--report json|text] -- <command...>');
|
|
62
|
+
const { format } = parseReportFlag(argv.slice(0, sep));
|
|
63
|
+
const child = argv.slice(sep + 1);
|
|
64
|
+
if (child.length === 0)
|
|
65
|
+
die('no child command given');
|
|
66
|
+
const result = await runAndRecord(child, process.cwd());
|
|
67
|
+
for (const d of result.diagnostics)
|
|
68
|
+
process.stderr.write(`${d}\n`);
|
|
69
|
+
if (result.degraded || result.report === null) {
|
|
70
|
+
// INV-5 degraded path: verbatim raw passthrough, no report.
|
|
71
|
+
process.stdout.write(result.rawStdout);
|
|
72
|
+
process.stderr.write(result.rawStderr);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
emit(result.report, format);
|
|
76
|
+
}
|
|
77
|
+
process.exit(result.exitCode);
|
|
78
|
+
}
|
|
79
|
+
async function cmdCompare(argv) {
|
|
80
|
+
const { format, rest } = parseReportFlag(argv);
|
|
81
|
+
let ref;
|
|
82
|
+
const positional = [];
|
|
83
|
+
for (let i = 0; i < rest.length; i++) {
|
|
84
|
+
const a = rest[i];
|
|
85
|
+
if (a === '--ref') {
|
|
86
|
+
ref = rest[++i];
|
|
87
|
+
if (ref === undefined)
|
|
88
|
+
die('--ref expects a git ref');
|
|
89
|
+
}
|
|
90
|
+
else if (a.startsWith('--ref=')) {
|
|
91
|
+
ref = a.slice('--ref='.length);
|
|
92
|
+
}
|
|
93
|
+
else if (a.startsWith('-')) {
|
|
94
|
+
die(`unknown option: ${a}`);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
positional.push(a);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const { store, worktree } = await requireStore();
|
|
101
|
+
try {
|
|
102
|
+
let currentId;
|
|
103
|
+
let spec;
|
|
104
|
+
if (ref !== undefined) {
|
|
105
|
+
const resolved = await resolveRef(worktree, ref);
|
|
106
|
+
if (resolved === null)
|
|
107
|
+
die(`cannot resolve ref: ${ref}`);
|
|
108
|
+
spec = { mode: 'git-ref', ref, commit: resolved.commit, tree: resolved.tree };
|
|
109
|
+
currentId = positional[0] !== undefined ? store.resolveRunId(positional[0]) : store.lastRunId();
|
|
110
|
+
}
|
|
111
|
+
else if (positional.length === 2) {
|
|
112
|
+
spec = { mode: 'explicit-run-id', runId: positional[0] };
|
|
113
|
+
currentId = store.resolveRunId(positional[1]);
|
|
114
|
+
}
|
|
115
|
+
else if (positional.length === 0) {
|
|
116
|
+
spec = { mode: 'previous-comparable' };
|
|
117
|
+
currentId = store.lastRunId();
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
die('usage: vdelta compare [<baseline-run> <current-run>] [--ref <git-ref>] [--report json|text]');
|
|
121
|
+
}
|
|
122
|
+
if (currentId === null)
|
|
123
|
+
die('cannot resolve the current run');
|
|
124
|
+
emit(buildComparisonReport(store, currentId, spec), format);
|
|
125
|
+
process.exit(0);
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
if (err instanceof CompareOperationError)
|
|
129
|
+
die(err.message);
|
|
130
|
+
if (err instanceof StoreCorruptError)
|
|
131
|
+
die(`store corrupt: ${err.message}`);
|
|
132
|
+
throw err;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async function cmdShow(argv) {
|
|
136
|
+
let testId;
|
|
137
|
+
let raw = false;
|
|
138
|
+
const positional = [];
|
|
139
|
+
for (let i = 0; i < argv.length; i++) {
|
|
140
|
+
const a = argv[i];
|
|
141
|
+
if (a === '--test') {
|
|
142
|
+
testId = argv[++i];
|
|
143
|
+
if (testId === undefined)
|
|
144
|
+
die('--test expects a test id');
|
|
145
|
+
}
|
|
146
|
+
else if (a.startsWith('--test=')) {
|
|
147
|
+
testId = a.slice('--test='.length);
|
|
148
|
+
}
|
|
149
|
+
else if (a === '--raw') {
|
|
150
|
+
raw = true;
|
|
151
|
+
}
|
|
152
|
+
else if (a.startsWith('-')) {
|
|
153
|
+
die(`unknown option: ${a}`);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
positional.push(a);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (positional.length !== 1)
|
|
160
|
+
die('usage: vdelta show <run-id> [--test <test-id> | --raw]');
|
|
161
|
+
const { store } = await requireStore();
|
|
162
|
+
const runId = store.resolveRunId(positional[0]);
|
|
163
|
+
if (runId === null)
|
|
164
|
+
die(`unknown run id: ${positional[0]}`);
|
|
165
|
+
let record;
|
|
166
|
+
try {
|
|
167
|
+
record = store.readRun(runId);
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
if (err instanceof StoreCorruptError)
|
|
171
|
+
die(`store corrupt: ${err.message}`);
|
|
172
|
+
throw err;
|
|
173
|
+
}
|
|
174
|
+
if (raw) {
|
|
175
|
+
process.stdout.write(record.recording.raw_stdout);
|
|
176
|
+
process.stderr.write(record.recording.raw_stderr);
|
|
177
|
+
process.exit(0);
|
|
178
|
+
}
|
|
179
|
+
if (testId !== undefined) {
|
|
180
|
+
const obs = record.observations.find((o) => o.test_id === testId);
|
|
181
|
+
if (obs === undefined)
|
|
182
|
+
die(`no observation for test id: ${testId}`);
|
|
183
|
+
process.stdout.write(`${JSON.stringify(obs, null, 1)}\n`);
|
|
184
|
+
process.exit(0);
|
|
185
|
+
}
|
|
186
|
+
process.stdout.write(`${JSON.stringify(record, null, 1)}\n`);
|
|
187
|
+
process.exit(0);
|
|
188
|
+
}
|
|
189
|
+
async function cmdGate(argv) {
|
|
190
|
+
const { format, rest } = parseReportFlag(argv);
|
|
191
|
+
let ref;
|
|
192
|
+
let runId;
|
|
193
|
+
let policy = 'report-only';
|
|
194
|
+
for (let i = 0; i < rest.length; i++) {
|
|
195
|
+
const a = rest[i];
|
|
196
|
+
if (a === '--ref')
|
|
197
|
+
ref = rest[++i];
|
|
198
|
+
else if (a.startsWith('--ref='))
|
|
199
|
+
ref = a.slice('--ref='.length);
|
|
200
|
+
else if (a === '--run')
|
|
201
|
+
runId = rest[++i];
|
|
202
|
+
else if (a.startsWith('--run='))
|
|
203
|
+
runId = a.slice('--run='.length);
|
|
204
|
+
else if (a === '--policy')
|
|
205
|
+
policy = rest[++i] ?? '';
|
|
206
|
+
else if (a.startsWith('--policy='))
|
|
207
|
+
policy = a.slice('--policy='.length);
|
|
208
|
+
else
|
|
209
|
+
die(`unknown option: ${a}`, 2);
|
|
210
|
+
}
|
|
211
|
+
if (policy !== 'report-only') {
|
|
212
|
+
die(`policy "${policy}" is not implemented in this MVP (report-only only, §11.1)`, 2);
|
|
213
|
+
}
|
|
214
|
+
if (ref === undefined)
|
|
215
|
+
die('usage: vdelta gate --ref <git-ref> [--run <run-id>] [--policy report-only]', 2);
|
|
216
|
+
const worktree = await gitRepoRoot(process.cwd());
|
|
217
|
+
if (worktree === null)
|
|
218
|
+
die('not inside a git worktree', 2);
|
|
219
|
+
const store = new RunStore(worktree);
|
|
220
|
+
try {
|
|
221
|
+
const report = await buildGateReport(store, {
|
|
222
|
+
worktree,
|
|
223
|
+
ref,
|
|
224
|
+
...(runId !== undefined ? { runId } : {}),
|
|
225
|
+
});
|
|
226
|
+
emit(report, format);
|
|
227
|
+
process.exit(0);
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
if (err instanceof GateOperationError)
|
|
231
|
+
die(err.message, 2);
|
|
232
|
+
if (err instanceof StoreCorruptError)
|
|
233
|
+
die(`store corrupt: ${err.message}`, 2);
|
|
234
|
+
throw err;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
async function main() {
|
|
238
|
+
const [, , command, ...argv] = process.argv;
|
|
239
|
+
switch (command) {
|
|
240
|
+
case 'run':
|
|
241
|
+
return cmdRun(argv);
|
|
242
|
+
case 'compare':
|
|
243
|
+
return cmdCompare(argv);
|
|
244
|
+
case 'show':
|
|
245
|
+
return cmdShow(argv);
|
|
246
|
+
case 'gate':
|
|
247
|
+
return cmdGate(argv);
|
|
248
|
+
case '--version':
|
|
249
|
+
case 'version':
|
|
250
|
+
process.stdout.write(`vdelta ${VDELTA_VERSION} (veridelta/1)\n`);
|
|
251
|
+
return process.exit(0);
|
|
252
|
+
default:
|
|
253
|
+
die(`usage: vdelta <run|compare|show|gate> ...\n` +
|
|
254
|
+
` run [--report json|text] -- <command...>\n` +
|
|
255
|
+
` compare [<baseline-run> <current-run>] [--ref <git-ref>] [--report json|text]\n` +
|
|
256
|
+
` show <run-id> [--test <test-id> | --raw]\n` +
|
|
257
|
+
` gate --ref <git-ref> [--run <run-id>] [--policy report-only] [--report json|text]`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
main().catch((err) => {
|
|
261
|
+
process.stderr.write(`vdelta: internal error: ${err instanceof Error ? err.stack ?? err.message : String(err)}\n`);
|
|
262
|
+
process.exit(1);
|
|
263
|
+
});
|
|
264
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { RunStore } from './store.js';
|
|
2
|
+
import { type BaselineMode, type ComparabilityDetail, type ComparisonReport, type RunRecord } from './schema.js';
|
|
3
|
+
export type BaselineSpec = {
|
|
4
|
+
mode: 'previous-comparable';
|
|
5
|
+
} | {
|
|
6
|
+
mode: 'explicit-run-id';
|
|
7
|
+
runId: string;
|
|
8
|
+
} | {
|
|
9
|
+
mode: 'git-ref';
|
|
10
|
+
ref: string;
|
|
11
|
+
commit: string;
|
|
12
|
+
tree: string;
|
|
13
|
+
};
|
|
14
|
+
export declare class CompareOperationError extends Error {
|
|
15
|
+
constructor(message: string);
|
|
16
|
+
}
|
|
17
|
+
/** Stream key (§5.1): repo + worktree + branch + cwd + command + selector + instrument. */
|
|
18
|
+
export declare function streamKey(r: RunRecord): string;
|
|
19
|
+
export interface BaselineResolution {
|
|
20
|
+
record: RunRecord | null;
|
|
21
|
+
runId: string | null;
|
|
22
|
+
mode: BaselineMode;
|
|
23
|
+
selectionReason: string;
|
|
24
|
+
failure?: ComparabilityDetail;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Resolve the baseline per §5.2. Selection is content-addressed and
|
|
28
|
+
* explainable; recency is index insertion order, never timestamps (§7.8).
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolveBaseline(store: RunStore, current: RunRecord, currentId: string, spec: BaselineSpec): BaselineResolution;
|
|
31
|
+
/**
|
|
32
|
+
* Build the full comparison report for a current run against a baseline spec.
|
|
33
|
+
* Store-level corruption during baseline resolution degrades to a
|
|
34
|
+
* `store-corrupt`/`failed` abstention (fail-closed comparison, §6.3) — the
|
|
35
|
+
* report is still produced.
|
|
36
|
+
*/
|
|
37
|
+
export declare function buildComparisonReport(store: RunStore, currentId: string, spec: BaselineSpec): ComparisonReport;
|