@mmnto/cli 1.72.0 → 1.73.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/dist/commands/spine-cert-run-corpus.d.ts +47 -12
- package/dist/commands/spine-cert-run-corpus.d.ts.map +1 -1
- package/dist/commands/spine-cert-run-corpus.js +120 -36
- package/dist/commands/spine-cert-run-corpus.js.map +1 -1
- package/dist/commands/spine-cert-run-corpus.test.js +34 -5
- package/dist/commands/spine-cert-run-corpus.test.js.map +1 -1
- package/dist/commands/spine-corpus-disposition-source.d.ts +179 -0
- package/dist/commands/spine-corpus-disposition-source.d.ts.map +1 -0
- package/dist/commands/spine-corpus-disposition-source.js +237 -0
- package/dist/commands/spine-corpus-disposition-source.js.map +1 -0
- package/dist/commands/spine-corpus-disposition-source.test.d.ts +2 -0
- package/dist/commands/spine-corpus-disposition-source.test.d.ts.map +1 -0
- package/dist/commands/spine-corpus-disposition-source.test.js +170 -0
- package/dist/commands/spine-corpus-disposition-source.test.js.map +1 -0
- package/dist/commands/spine-derive-labels.d.ts +12 -0
- package/dist/commands/spine-derive-labels.d.ts.map +1 -0
- package/dist/commands/spine-derive-labels.js +142 -0
- package/dist/commands/spine-derive-labels.js.map +1 -0
- package/dist/commands/spine-derive-labels.test.d.ts +2 -0
- package/dist/commands/spine-derive-labels.test.d.ts.map +1 -0
- package/dist/commands/spine-derive-labels.test.js +157 -0
- package/dist/commands/spine-derive-labels.test.js.map +1 -0
- package/dist/commands/spine-fetch-dispositions.d.ts +27 -0
- package/dist/commands/spine-fetch-dispositions.d.ts.map +1 -0
- package/dist/commands/spine-fetch-dispositions.js +104 -0
- package/dist/commands/spine-fetch-dispositions.js.map +1 -0
- package/dist/commands/spine-fetch-dispositions.test.d.ts +2 -0
- package/dist/commands/spine-fetch-dispositions.test.d.ts.map +1 -0
- package/dist/commands/spine-fetch-dispositions.test.js +155 -0
- package/dist/commands/spine-fetch-dispositions.test.js.map +1 -0
- package/dist/commands/spine-windtunnel.d.ts +19 -0
- package/dist/commands/spine-windtunnel.d.ts.map +1 -1
- package/dist/commands/spine-windtunnel.js +119 -50
- package/dist/commands/spine-windtunnel.js.map +1 -1
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
import type { GroundTruthLabel, MinerLedgers, ResolvedPrDiff, ReviewThreadContent, Stage4VerifierDeps } from '@mmnto/totem';
|
|
1
|
+
import type { GroundTruthLabel, MinerLedgers, ResolvedPrDiff, ReviewThreadContent, Stage4VerifierDeps, WindtunnelLock } from '@mmnto/totem';
|
|
2
|
+
/** Local alias for the core git exec port (mirrors spine-windtunnel.ts / spine-cert-materialize.ts). */
|
|
3
|
+
type SafeExecFn = typeof import('@mmnto/totem').safeExec;
|
|
2
4
|
import { type ReplayArtifact } from './spine-llm-replay.js';
|
|
3
|
-
import type { CertifyingCorpusProvider } from './spine-windtunnel.js';
|
|
5
|
+
import type { CertifyingCorpus, CertifyingCorpusProvider } from './spine-windtunnel.js';
|
|
6
|
+
export declare const PR_DIFFS_FILE = "pr-diffs.json";
|
|
7
|
+
/** The cert-run answer key — produced by `derive-labels` (5d-iii), read by the run. */
|
|
8
|
+
export declare const GROUND_TRUTH_FILE = "ground-truth-labels.json";
|
|
9
|
+
/** The frozen held-out disposition provenance — produced by `fetch-dispositions` (5d-ii). */
|
|
10
|
+
export declare const CORPUS_DISPOSITIONS_FILE = "corpus-dispositions.json";
|
|
4
11
|
export interface CertRunFixtureInputs {
|
|
5
12
|
split: import('@mmnto/totem').SplitArtifact;
|
|
6
13
|
artifact: ReplayArtifact;
|
|
@@ -14,7 +21,20 @@ export interface CertRunFixtureInputs {
|
|
|
14
21
|
* dynamically imported per the CLI lazy-import convention, not pulled in at
|
|
15
22
|
* module load.
|
|
16
23
|
*/
|
|
17
|
-
export declare function loadCertRunFixtures(gate1Dir: string
|
|
24
|
+
export declare function loadCertRunFixtures(gate1Dir: string, opts?: {
|
|
25
|
+
expectedPrDiffsSha?: string;
|
|
26
|
+
skipGroundTruth?: boolean;
|
|
27
|
+
}): Promise<CertRunFixtureInputs>;
|
|
28
|
+
/**
|
|
29
|
+
* Build the Stage-4 verifier deps (listFiles/readFile over the frozen post-image
|
|
30
|
+
* at `asOf`) — the SHARED constructor both the certifying run and the 5d-iii
|
|
31
|
+
* deriver use, so the archived-rule exclusion (hence the scored rule set, hence
|
|
32
|
+
* the firing labelIds) is identical. With an lc clone, files resolve via
|
|
33
|
+
* `git ls-tree`/`git show` at `asOf` (a local clone — zero network); without one,
|
|
34
|
+
* Stage-4 sees no files (rules read as untested, NOT archived). Tests inject a
|
|
35
|
+
* fake `Stage4VerifierDeps` into `assembleCertifyingCorpus` directly instead.
|
|
36
|
+
*/
|
|
37
|
+
export declare function buildGate1Stage4Deps(lcDir: string | undefined, asOf: string, safeExec: SafeExecFn): Stage4VerifierDeps;
|
|
18
38
|
export interface ReplayCorpusProviderOptions {
|
|
19
39
|
/** The `.totem/spine/gate-1` dir holding the committed cert-run fixtures. */
|
|
20
40
|
gate1Dir: string;
|
|
@@ -28,15 +48,30 @@ export interface ReplayCorpusProviderOptions {
|
|
|
28
48
|
onLedgers?: (ledgers: MinerLedgers) => void;
|
|
29
49
|
}
|
|
30
50
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* `
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
51
|
+
* Assemble the REPLAY-mode `CertifyingCorpus` (rules + prDiffs + provenance) from
|
|
52
|
+
* the committed gate-1 fixtures — the SHARED path both the certifying run (via
|
|
53
|
+
* `buildReplayCorpusProvider`) and the 5d-iii label-deriver call, so the corpus
|
|
54
|
+
* they enumerate firings over is byte-identical (the answer-key labelIds the
|
|
55
|
+
* deriver mints are the ones the run looks up). The deriver passes
|
|
56
|
+
* `skipGroundTruth: true` — it PRODUCES `ground-truth-labels.json`, so it must
|
|
57
|
+
* not read it (circularity guard); the run omits the flag and loads the frozen
|
|
58
|
+
* answer key. Returns the fold-I ledgers too; the caller decides whether to emit
|
|
59
|
+
* them (the run does; the deriver discards — they belong to the run artifact).
|
|
60
|
+
*/
|
|
61
|
+
export declare function assembleCertifyingCorpus(opts: ReplayCorpusProviderOptions & {
|
|
62
|
+
skipGroundTruth?: boolean;
|
|
63
|
+
}, lock: WindtunnelLock): Promise<{
|
|
64
|
+
corpus: CertifyingCorpus;
|
|
65
|
+
ledgers: MinerLedgers;
|
|
66
|
+
}>;
|
|
67
|
+
/**
|
|
68
|
+
* Build the REPLAY-mode `CertifyingCorpusProvider` the certifying run injects: a thin
|
|
69
|
+
* wrapper over `assembleCertifyingCorpus` (fixture-load + replay adapters + the
|
|
70
|
+
* `buildCertifyingCorpus` composition) that also emits the fold-I miner ledgers
|
|
71
|
+
* (default: `miner-ledgers.json`) for §7 observability. The deriver calls
|
|
72
|
+
* `assembleCertifyingCorpus` directly instead (it skips ground-truth + discards the
|
|
73
|
+
* ledgers, which belong to the run artifact).
|
|
40
74
|
*/
|
|
41
75
|
export declare function buildReplayCorpusProvider(opts: ReplayCorpusProviderOptions): CertifyingCorpusProvider;
|
|
76
|
+
export {};
|
|
42
77
|
//# sourceMappingURL=spine-cert-run-corpus.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spine-cert-run-corpus.d.ts","sourceRoot":"","sources":["../../src/commands/spine-cert-run-corpus.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"spine-cert-run-corpus.d.ts","sourceRoot":"","sources":["../../src/commands/spine-cert-run-corpus.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,mBAAmB,EAGnB,kBAAkB,EAClB,cAAc,EACf,MAAM,cAAc,CAAC;AAEtB,wGAAwG;AACxG,KAAK,UAAU,GAAG,cAAc,cAAc,EAAE,QAAQ,CAAC;AAIzD,OAAO,EAAE,KAAK,cAAc,EAAwB,MAAM,uBAAuB,CAAC;AAClF,OAAO,KAAK,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAOxF,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAC7C,uFAAuF;AACvF,eAAO,MAAM,iBAAiB,6BAA6B,CAAC;AAC5D,6FAA6F;AAC7F,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AAyCnE,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,OAAO,cAAc,EAAE,aAAa,CAAC;IAC5C,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC5C;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE;IAAE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,GAChE,OAAO,CAAC,oBAAoB,CAAC,CAoE/B;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,UAAU,GACnB,kBAAkB,CA6BpB;AAiBD,MAAM,WAAW,2BAA2B;IAC1C,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;IACjB,oFAAoF;IACpF,MAAM,EAAE,kBAAkB,CAAC;IAC3B,iDAAiD;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,8CAA8C;IAC9C,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,4FAA4F;IAC5F,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;CAC7C;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,2BAA2B,GAAG;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,EACjE,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC;IAAE,MAAM,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC,CA8C9D;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,2BAA2B,GAChC,wBAAwB,CAkB1B"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
1
2
|
import * as fs from 'node:fs';
|
|
2
3
|
import * as path from 'node:path';
|
|
3
4
|
import { z } from 'zod';
|
|
@@ -8,8 +9,11 @@ import { ReplayArtifactSchema } from './spine-llm-replay.js';
|
|
|
8
9
|
const SPLIT_FILE = 'split.json';
|
|
9
10
|
const REPLAY_FILE = 'llm-replay.v1.json';
|
|
10
11
|
const CONTENT_FILE = 'review-content.json';
|
|
11
|
-
const PR_DIFFS_FILE = 'pr-diffs.json';
|
|
12
|
-
|
|
12
|
+
export const PR_DIFFS_FILE = 'pr-diffs.json';
|
|
13
|
+
/** The cert-run answer key — produced by `derive-labels` (5d-iii), read by the run. */
|
|
14
|
+
export const GROUND_TRUTH_FILE = 'ground-truth-labels.json';
|
|
15
|
+
/** The frozen held-out disposition provenance — produced by `fetch-dispositions` (5d-ii). */
|
|
16
|
+
export const CORPUS_DISPOSITIONS_FILE = 'corpus-dispositions.json';
|
|
13
17
|
const LEDGERS_FILE = 'miner-ledgers.json';
|
|
14
18
|
// ─── Fixture schemas (the committed cert-run inputs) ──
|
|
15
19
|
const ReviewThreadContentSchema = z.object({
|
|
@@ -48,16 +52,17 @@ function frozenSourceFrom(contents) {
|
|
|
48
52
|
* dynamically imported per the CLI lazy-import convention, not pulled in at
|
|
49
53
|
* module load.
|
|
50
54
|
*/
|
|
51
|
-
export async function loadCertRunFixtures(gate1Dir) {
|
|
55
|
+
export async function loadCertRunFixtures(gate1Dir, opts) {
|
|
52
56
|
const { SplitArtifactSchema, TotemError } = await import('@mmnto/totem');
|
|
53
|
-
const
|
|
54
|
-
let raw;
|
|
57
|
+
const readRaw = (file) => {
|
|
55
58
|
try {
|
|
56
|
-
|
|
59
|
+
return fs.readFileSync(file, 'utf-8');
|
|
57
60
|
}
|
|
58
61
|
catch (err) {
|
|
59
62
|
throw new TotemError('CONFIG_INVALID', `Cert-run fixture missing: ${file}`, 'Ensure the gate-1 fixture set exists and is readable.', err);
|
|
60
63
|
}
|
|
64
|
+
};
|
|
65
|
+
const parseJson = (raw, file) => {
|
|
61
66
|
try {
|
|
62
67
|
return JSON.parse(raw);
|
|
63
68
|
}
|
|
@@ -65,16 +70,73 @@ export async function loadCertRunFixtures(gate1Dir) {
|
|
|
65
70
|
throw new TotemError('CONFIG_INVALID', `Cert-run fixture is not valid JSON (${file})`, 'Re-freeze the gate-1 fixtures with `spine windtunnel record`.', err);
|
|
66
71
|
}
|
|
67
72
|
};
|
|
73
|
+
const loadJson = (file) => parseJson(readRaw(file), file);
|
|
68
74
|
const split = SplitArtifactSchema.parse(loadJson(path.join(gate1Dir, SPLIT_FILE)));
|
|
69
75
|
const artifact = ReplayArtifactSchema.parse(loadJson(path.join(gate1Dir, REPLAY_FILE)));
|
|
70
76
|
const content = z
|
|
71
77
|
.array(ReviewThreadContentSchema)
|
|
72
78
|
.parse(loadJson(path.join(gate1Dir, CONTENT_FILE)));
|
|
73
|
-
|
|
79
|
+
// #2225 (#709 fold-2): verify-then-parse the SCORING source on a SINGLE read — the
|
|
80
|
+
// digest must cover the exact bytes that get parsed + scored, not a separate read
|
|
81
|
+
// (CR: no check/use split). CRLF→LF normalized to match the producer's LF-stamped
|
|
82
|
+
// digest. The absent-from-lock case is the caller's precondition (it omits the sha).
|
|
83
|
+
const prDiffsFile = path.join(gate1Dir, PR_DIFFS_FILE);
|
|
84
|
+
const prDiffsRaw = readRaw(prDiffsFile);
|
|
85
|
+
if (opts?.expectedPrDiffsSha !== undefined) {
|
|
86
|
+
const actual = createHash('sha256')
|
|
87
|
+
.update(prDiffsRaw.replace(/\r\n/g, '\n'), 'utf-8')
|
|
88
|
+
.digest('hex');
|
|
89
|
+
if (actual !== opts.expectedPrDiffsSha) {
|
|
90
|
+
throw new TotemError('CONFIG_INVALID', `Certifying run: pr-diffs.json integrity FAILED — expected ${opts.expectedPrDiffsSha}, got ` +
|
|
91
|
+
`${actual} (the frozen scoring corpus was tampered or re-serialized).`, 'Restore the frozen pr-diffs.json or re-materialize the cert corpus.');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const prDiffs = z.array(ResolvedPrDiffSchema).parse(parseJson(prDiffsRaw, prDiffsFile));
|
|
95
|
+
// 5d-iii circularity guard: the label-deriver reuses this loader to enumerate
|
|
96
|
+
// firings byte-identically to the run, but it PRODUCES ground-truth-labels.json
|
|
97
|
+
// — so it must NOT read it (the file may not yet exist on a first derive, and
|
|
98
|
+
// reading it would make the deriver depend on its own output). `skipGroundTruth`
|
|
99
|
+
// returns an empty map; the run omits the flag and loads the frozen answer key.
|
|
100
|
+
if (opts?.skipGroundTruth) {
|
|
101
|
+
return { split, artifact, content, prDiffs, groundTruth: new Map() };
|
|
102
|
+
}
|
|
74
103
|
const gtRecord = GroundTruthSchema.parse(loadJson(path.join(gate1Dir, GROUND_TRUTH_FILE)));
|
|
75
104
|
const groundTruth = new Map(Object.entries(gtRecord));
|
|
76
105
|
return { split, artifact, content, prDiffs, groundTruth };
|
|
77
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Build the Stage-4 verifier deps (listFiles/readFile over the frozen post-image
|
|
109
|
+
* at `asOf`) — the SHARED constructor both the certifying run and the 5d-iii
|
|
110
|
+
* deriver use, so the archived-rule exclusion (hence the scored rule set, hence
|
|
111
|
+
* the firing labelIds) is identical. With an lc clone, files resolve via
|
|
112
|
+
* `git ls-tree`/`git show` at `asOf` (a local clone — zero network); without one,
|
|
113
|
+
* Stage-4 sees no files (rules read as untested, NOT archived). Tests inject a
|
|
114
|
+
* fake `Stage4VerifierDeps` into `assembleCertifyingCorpus` directly instead.
|
|
115
|
+
*/
|
|
116
|
+
export function buildGate1Stage4Deps(lcDir, asOf, safeExec) {
|
|
117
|
+
if (lcDir) {
|
|
118
|
+
return {
|
|
119
|
+
// The `--` separator keeps the revision unambiguous from any path args and blocks
|
|
120
|
+
// arg injection (CR coding guideline) — this shared path decides which files
|
|
121
|
+
// Stage-4 sees for BOTH the run and the deriver, so rev/path ambiguity here would
|
|
122
|
+
// shift archived-rule decisions and the derived labels.
|
|
123
|
+
listFiles: async () => safeExec('git', ['ls-tree', '-r', '--name-only', asOf, '--'], { cwd: lcDir })
|
|
124
|
+
.split('\n')
|
|
125
|
+
.filter(Boolean),
|
|
126
|
+
readFile: async (f) => safeExec('git', ['show', `${asOf}:${f.replace(/\\/g, '/')}`, '--'], { cwd: lcDir }),
|
|
127
|
+
workingDirectory: lcDir,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
// No lc clone → Stage-4 sees no files (rules read as 'no-matches' / untested,
|
|
132
|
+
// NOT archived) — the wind-tunnel firing/scoring still runs.
|
|
133
|
+
listFiles: async () => [],
|
|
134
|
+
readFile: async (f) => {
|
|
135
|
+
const { TotemError } = await import('@mmnto/totem');
|
|
136
|
+
throw new TotemError('CONFIG_INVALID', `Cert run: no lc clone (--lc-dir) — cannot read ${f} for Stage-4.`, 'Provide the lc clone via --lc-dir or the TOTEM_LC_DIR environment variable.');
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
78
140
|
/** Derive the SplitLedger from the loaded split + the lock's resolved corpus. */
|
|
79
141
|
function splitLedgerFrom(split, lock) {
|
|
80
142
|
return {
|
|
@@ -87,38 +149,60 @@ function splitLedgerFrom(split, lock) {
|
|
|
87
149
|
};
|
|
88
150
|
}
|
|
89
151
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
* `
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
152
|
+
* Assemble the REPLAY-mode `CertifyingCorpus` (rules + prDiffs + provenance) from
|
|
153
|
+
* the committed gate-1 fixtures — the SHARED path both the certifying run (via
|
|
154
|
+
* `buildReplayCorpusProvider`) and the 5d-iii label-deriver call, so the corpus
|
|
155
|
+
* they enumerate firings over is byte-identical (the answer-key labelIds the
|
|
156
|
+
* deriver mints are the ones the run looks up). The deriver passes
|
|
157
|
+
* `skipGroundTruth: true` — it PRODUCES `ground-truth-labels.json`, so it must
|
|
158
|
+
* not read it (circularity guard); the run omits the flag and loads the frozen
|
|
159
|
+
* answer key. Returns the fold-I ledgers too; the caller decides whether to emit
|
|
160
|
+
* them (the run does; the deriver discards — they belong to the run artifact).
|
|
161
|
+
*/
|
|
162
|
+
export async function assembleCertifyingCorpus(opts, lock) {
|
|
163
|
+
const { TotemError } = await import('@mmnto/totem');
|
|
164
|
+
const expectedHash = lock.controls.integrity.llmReplaySha;
|
|
165
|
+
if (!expectedHash) {
|
|
166
|
+
throw new TotemError('CONFIG_INVALID', 'Certifying run: lock is missing controls.integrity.llmReplaySha (L2) — the frozen ' +
|
|
167
|
+
'llm-replay fixture cannot be integrity-checked.', 'Re-freeze the lock after a `record` run.');
|
|
168
|
+
}
|
|
169
|
+
// #2225 (#709 fold-2): hash-bind the SCORING source. `pr-diffs.json` is otherwise
|
|
170
|
+
// unprotected — `fixtureSha` covers only the control dirs — so a silent mutation of
|
|
171
|
+
// any row (advisory-window OR control) would corrupt the answer key while the
|
|
172
|
+
// control-dir gate stays green. The absent-from-lock case is a lock precondition
|
|
173
|
+
// (checked here); `loadCertRunFixtures` verifies the digest on the SAME read it
|
|
174
|
+
// parses — no check/use split (CR). Fail loud (strategy ruled: verify at freeze AND run).
|
|
175
|
+
const expectedPrDiffsSha = lock.controls.integrity.prDiffsSha;
|
|
176
|
+
if (!expectedPrDiffsSha) {
|
|
177
|
+
throw new TotemError('CONFIG_INVALID', 'Certifying run: lock is missing controls.integrity.prDiffsSha (#709 fold-2) — the ' +
|
|
178
|
+
'pr-diffs.json scoring source cannot be integrity-checked.', 'Re-materialize the cert corpus with `spine windtunnel materialize`.');
|
|
179
|
+
}
|
|
180
|
+
const { split, artifact, content, prDiffs, groundTruth } = await loadCertRunFixtures(opts.gate1Dir, { expectedPrDiffsSha, skipGroundTruth: opts.skipGroundTruth });
|
|
181
|
+
const { extractor, classifier } = buildReplayAdapters(artifact, expectedHash);
|
|
182
|
+
return buildCertifyingCorpus({
|
|
183
|
+
split,
|
|
184
|
+
splitLedger: splitLedgerFrom(split, lock),
|
|
185
|
+
source: frozenSourceFrom(content),
|
|
186
|
+
extractor,
|
|
187
|
+
classifier,
|
|
188
|
+
seedClassesProvided: opts.seedClassesProvided ?? false,
|
|
189
|
+
stage4: opts.stage4,
|
|
190
|
+
now: opts.now,
|
|
191
|
+
prDiffs,
|
|
192
|
+
groundTruth,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Build the REPLAY-mode `CertifyingCorpusProvider` the certifying run injects: a thin
|
|
197
|
+
* wrapper over `assembleCertifyingCorpus` (fixture-load + replay adapters + the
|
|
198
|
+
* `buildCertifyingCorpus` composition) that also emits the fold-I miner ledgers
|
|
199
|
+
* (default: `miner-ledgers.json`) for §7 observability. The deriver calls
|
|
200
|
+
* `assembleCertifyingCorpus` directly instead (it skips ground-truth + discards the
|
|
201
|
+
* ledgers, which belong to the run artifact).
|
|
99
202
|
*/
|
|
100
203
|
export function buildReplayCorpusProvider(opts) {
|
|
101
204
|
return async (lock) => {
|
|
102
|
-
const {
|
|
103
|
-
const expectedHash = lock.controls.integrity.llmReplaySha;
|
|
104
|
-
if (!expectedHash) {
|
|
105
|
-
throw new TotemError('CONFIG_INVALID', 'Certifying run: lock is missing controls.integrity.llmReplaySha (L2) — the frozen ' +
|
|
106
|
-
'llm-replay fixture cannot be integrity-checked.', 'Re-freeze the lock after a `record` run.');
|
|
107
|
-
}
|
|
108
|
-
const { split, artifact, content, prDiffs, groundTruth } = await loadCertRunFixtures(opts.gate1Dir);
|
|
109
|
-
const { extractor, classifier } = buildReplayAdapters(artifact, expectedHash);
|
|
110
|
-
const { corpus, ledgers } = await buildCertifyingCorpus({
|
|
111
|
-
split,
|
|
112
|
-
splitLedger: splitLedgerFrom(split, lock),
|
|
113
|
-
source: frozenSourceFrom(content),
|
|
114
|
-
extractor,
|
|
115
|
-
classifier,
|
|
116
|
-
seedClassesProvided: opts.seedClassesProvided ?? false,
|
|
117
|
-
stage4: opts.stage4,
|
|
118
|
-
now: opts.now,
|
|
119
|
-
prDiffs,
|
|
120
|
-
groundTruth,
|
|
121
|
-
});
|
|
205
|
+
const { corpus, ledgers } = await assembleCertifyingCorpus(opts, lock);
|
|
122
206
|
// fold-I (§7): emit the miner ledgers, observable beside the cert-run report.
|
|
123
207
|
if (opts.onLedgers) {
|
|
124
208
|
opts.onLedgers(ledgers);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spine-cert-run-corpus.js","sourceRoot":"","sources":["../../src/commands/spine-cert-run-corpus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"spine-cert-run-corpus.js","sourceRoot":"","sources":["../../src/commands/spine-cert-run-corpus.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
1
2
|
import * as fs from 'node:fs';
|
|
2
3
|
import * as os from 'node:os';
|
|
3
4
|
import * as path from 'node:path';
|
|
@@ -84,10 +85,10 @@ function stage4(files) {
|
|
|
84
85
|
readFile: (f) => f in files ? Promise.resolve(files[f]) : Promise.reject(new Error(`absent ${f}`)),
|
|
85
86
|
};
|
|
86
87
|
}
|
|
87
|
-
/** A minimal lock partial — the provider reads
|
|
88
|
-
function lockWith(llmReplaySha) {
|
|
88
|
+
/** A minimal lock partial — the provider reads the L2 hash, the pr-diffs digest, + resolved corpus. */
|
|
89
|
+
function lockWith(llmReplaySha, prDiffsSha) {
|
|
89
90
|
return {
|
|
90
|
-
controls: { integrity: { llmReplaySha } },
|
|
91
|
+
controls: { integrity: { llmReplaySha, prDiffsSha } },
|
|
91
92
|
corpus: { resolvedPrs: [{ pr: 1, mergeCommit: sha(1) }] },
|
|
92
93
|
};
|
|
93
94
|
}
|
|
@@ -130,6 +131,12 @@ async function fixtureHash() {
|
|
|
130
131
|
});
|
|
131
132
|
return hash;
|
|
132
133
|
}
|
|
134
|
+
/** sha256 of the CRLF→LF-normalized on-disk pr-diffs.json — the digest the run gate (#2225) asserts. */
|
|
135
|
+
function prDiffsHash() {
|
|
136
|
+
return createHash('sha256')
|
|
137
|
+
.update(fs.readFileSync(path.join(gate1Dir, 'pr-diffs.json'), 'utf-8').replace(/\r\n/g, '\n'), 'utf-8')
|
|
138
|
+
.digest('hex');
|
|
139
|
+
}
|
|
133
140
|
// ─── Tests ───────────────────────────────────────────
|
|
134
141
|
describe('buildReplayCorpusProvider (run-path)', () => {
|
|
135
142
|
it('loads the committed fixtures + replays them into a corpus (zero LLM/network)', async () => {
|
|
@@ -143,7 +150,7 @@ describe('buildReplayCorpusProvider (run-path)', () => {
|
|
|
143
150
|
captured = l;
|
|
144
151
|
},
|
|
145
152
|
});
|
|
146
|
-
const corpus = await provider(lockWith(hash));
|
|
153
|
+
const corpus = await provider(lockWith(hash, prDiffsHash()));
|
|
147
154
|
expect(corpus.rules).toHaveLength(1);
|
|
148
155
|
expect(corpus.provenanceByRule.get(corpus.rules[0].lessonHash)?.mergedPr).toBe(1);
|
|
149
156
|
// fold-I ledgers emitted via the sink.
|
|
@@ -164,8 +171,30 @@ describe('buildReplayCorpusProvider (run-path)', () => {
|
|
|
164
171
|
stage4: stage4({ 'src/a.ts': 'forbiddenCall()' }),
|
|
165
172
|
now: NOW,
|
|
166
173
|
});
|
|
167
|
-
await provider(lockWith(hash));
|
|
174
|
+
await provider(lockWith(hash, prDiffsHash()));
|
|
168
175
|
expect(fs.existsSync(path.join(gate1Dir, 'miner-ledgers.json'))).toBe(true);
|
|
169
176
|
});
|
|
177
|
+
it('throws loud when the lock lacks the prDiffsSha digest (#2225 scoring-source gate)', async () => {
|
|
178
|
+
const hash = await fixtureHash();
|
|
179
|
+
const provider = buildReplayCorpusProvider({
|
|
180
|
+
gate1Dir,
|
|
181
|
+
stage4: stage4({ 'src/a.ts': 'forbiddenCall()' }),
|
|
182
|
+
now: NOW,
|
|
183
|
+
});
|
|
184
|
+
// llmReplaySha present, prDiffsSha omitted → the fold-2 gate fires.
|
|
185
|
+
await expect(provider(lockWith(hash, undefined))).rejects.toThrow(/prDiffsSha/);
|
|
186
|
+
});
|
|
187
|
+
it('throws loud when pr-diffs.json is tampered after freeze (#2225 fold-2)', async () => {
|
|
188
|
+
const hash = await fixtureHash();
|
|
189
|
+
const lock = lockWith(hash, prDiffsHash()); // digest captured over the frozen bytes
|
|
190
|
+
// a schema-valid but byte-different scoring source — passes Zod, fails the digest.
|
|
191
|
+
fs.writeFileSync(path.join(gate1Dir, 'pr-diffs.json'), JSON.stringify([{ pr: 1, diff: 'tampered', controlKind: 'corpus' }]), 'utf-8');
|
|
192
|
+
const provider = buildReplayCorpusProvider({
|
|
193
|
+
gate1Dir,
|
|
194
|
+
stage4: stage4({ 'src/a.ts': 'forbiddenCall()' }),
|
|
195
|
+
now: NOW,
|
|
196
|
+
});
|
|
197
|
+
await expect(provider(lock)).rejects.toThrow(/pr-diffs\.json integrity/);
|
|
198
|
+
});
|
|
170
199
|
});
|
|
171
200
|
//# sourceMappingURL=spine-cert-run-corpus.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spine-cert-run-corpus.test.js","sourceRoot":"","sources":["../../src/commands/spine-cert-run-corpus.test.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"spine-cert-run-corpus.test.js","sourceRoot":"","sources":["../../src/commands/spine-cert-run-corpus.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #709 ground-truth deriver — slice 5d-ii: the live held-out disposition adapter.
|
|
3
|
+
*
|
|
4
|
+
* Fetches a HELD-OUT corpus PR's review threads WITH span anchoring (the comment
|
|
5
|
+
* `diffHunk` + the thread line) — the data slice 5d-iii binds a `RuleFiring`'s
|
|
6
|
+
* matched line to a disposition by content/invariant. Distinct from the mining
|
|
7
|
+
* `ReviewThreadSourceAdapter` (which fetches TRAIN PRs and carries no span): the
|
|
8
|
+
* answer key labels HELD-OUT firings, so it needs the held-out PRs' threads,
|
|
9
|
+
* span-anchored, and a richer `CorpusDisposition` payload (core schema).
|
|
10
|
+
*
|
|
11
|
+
* Like the mining adapter, this SURFACES `isResolved`/`isOutdated` and never
|
|
12
|
+
* filters on them (the #2201 "surface, don't filter" discipline; the taxonomy +
|
|
13
|
+
* span-bind decide, 5d-i/5d-iii). Unlike it, a fetch failure FAILS LOUD: the
|
|
14
|
+
* disposition freeze is a by-hand, all-or-nothing producer step (a silent skip
|
|
15
|
+
* would under-populate the answer-key provenance), so a network/parse/pagination
|
|
16
|
+
* fault throws a structured TotemError rather than a discriminated skip.
|
|
17
|
+
*
|
|
18
|
+
* CI HARD-GATE (agy panel): a live GitHub fetch must NEVER run in CI — the
|
|
19
|
+
* certifying run is zero-network and reads only the FROZEN `corpus-dispositions.json`.
|
|
20
|
+
* `fetch` throws if `CI` is set without an explicit `ALLOW_LIVE_FETCH` escape, so
|
|
21
|
+
* an accidental test/CI invocation fails loud instead of hitting the network.
|
|
22
|
+
*
|
|
23
|
+
* Reuses the established `gh` CLI exec pattern (Tenet-21 — no bespoke GraphQL
|
|
24
|
+
* client). The `exec` seam is injectable so the query-spy + mapping + CI-gate
|
|
25
|
+
* tests run fully offline.
|
|
26
|
+
*/
|
|
27
|
+
import { z } from 'zod';
|
|
28
|
+
import type { CorpusDisposition, CorpusDispositionThread } from '@mmnto/totem';
|
|
29
|
+
import type { GhExec } from './spine-review-thread-source.js';
|
|
30
|
+
declare const GqlThreadSchema: z.ZodObject<{
|
|
31
|
+
id: z.ZodString;
|
|
32
|
+
isResolved: z.ZodBoolean;
|
|
33
|
+
isOutdated: z.ZodBoolean;
|
|
34
|
+
path: z.ZodString;
|
|
35
|
+
line: z.ZodNullable<z.ZodNumber>;
|
|
36
|
+
originalLine: z.ZodNullable<z.ZodNumber>;
|
|
37
|
+
comments: z.ZodObject<{
|
|
38
|
+
pageInfo: z.ZodObject<{
|
|
39
|
+
hasNextPage: z.ZodBoolean;
|
|
40
|
+
}, "strip", z.ZodTypeAny, {
|
|
41
|
+
hasNextPage: boolean;
|
|
42
|
+
}, {
|
|
43
|
+
hasNextPage: boolean;
|
|
44
|
+
}>;
|
|
45
|
+
nodes: z.ZodArray<z.ZodObject<{
|
|
46
|
+
databaseId: z.ZodNullable<z.ZodNumber>;
|
|
47
|
+
diffHunk: z.ZodNullable<z.ZodString>;
|
|
48
|
+
author: z.ZodNullable<z.ZodObject<{
|
|
49
|
+
login: z.ZodString;
|
|
50
|
+
}, "strip", z.ZodTypeAny, {
|
|
51
|
+
login: string;
|
|
52
|
+
}, {
|
|
53
|
+
login: string;
|
|
54
|
+
}>>;
|
|
55
|
+
body: z.ZodString;
|
|
56
|
+
}, "strip", z.ZodTypeAny, {
|
|
57
|
+
body: string;
|
|
58
|
+
author: {
|
|
59
|
+
login: string;
|
|
60
|
+
} | null;
|
|
61
|
+
databaseId: number | null;
|
|
62
|
+
diffHunk: string | null;
|
|
63
|
+
}, {
|
|
64
|
+
body: string;
|
|
65
|
+
author: {
|
|
66
|
+
login: string;
|
|
67
|
+
} | null;
|
|
68
|
+
databaseId: number | null;
|
|
69
|
+
diffHunk: string | null;
|
|
70
|
+
}>, "many">;
|
|
71
|
+
}, "strip", z.ZodTypeAny, {
|
|
72
|
+
pageInfo: {
|
|
73
|
+
hasNextPage: boolean;
|
|
74
|
+
};
|
|
75
|
+
nodes: {
|
|
76
|
+
body: string;
|
|
77
|
+
author: {
|
|
78
|
+
login: string;
|
|
79
|
+
} | null;
|
|
80
|
+
databaseId: number | null;
|
|
81
|
+
diffHunk: string | null;
|
|
82
|
+
}[];
|
|
83
|
+
}, {
|
|
84
|
+
pageInfo: {
|
|
85
|
+
hasNextPage: boolean;
|
|
86
|
+
};
|
|
87
|
+
nodes: {
|
|
88
|
+
body: string;
|
|
89
|
+
author: {
|
|
90
|
+
login: string;
|
|
91
|
+
} | null;
|
|
92
|
+
databaseId: number | null;
|
|
93
|
+
diffHunk: string | null;
|
|
94
|
+
}[];
|
|
95
|
+
}>;
|
|
96
|
+
}, "strip", z.ZodTypeAny, {
|
|
97
|
+
line: number | null;
|
|
98
|
+
path: string;
|
|
99
|
+
id: string;
|
|
100
|
+
comments: {
|
|
101
|
+
pageInfo: {
|
|
102
|
+
hasNextPage: boolean;
|
|
103
|
+
};
|
|
104
|
+
nodes: {
|
|
105
|
+
body: string;
|
|
106
|
+
author: {
|
|
107
|
+
login: string;
|
|
108
|
+
} | null;
|
|
109
|
+
databaseId: number | null;
|
|
110
|
+
diffHunk: string | null;
|
|
111
|
+
}[];
|
|
112
|
+
};
|
|
113
|
+
isResolved: boolean;
|
|
114
|
+
isOutdated: boolean;
|
|
115
|
+
originalLine: number | null;
|
|
116
|
+
}, {
|
|
117
|
+
line: number | null;
|
|
118
|
+
path: string;
|
|
119
|
+
id: string;
|
|
120
|
+
comments: {
|
|
121
|
+
pageInfo: {
|
|
122
|
+
hasNextPage: boolean;
|
|
123
|
+
};
|
|
124
|
+
nodes: {
|
|
125
|
+
body: string;
|
|
126
|
+
author: {
|
|
127
|
+
login: string;
|
|
128
|
+
} | null;
|
|
129
|
+
databaseId: number | null;
|
|
130
|
+
diffHunk: string | null;
|
|
131
|
+
}[];
|
|
132
|
+
};
|
|
133
|
+
isResolved: boolean;
|
|
134
|
+
isOutdated: boolean;
|
|
135
|
+
originalLine: number | null;
|
|
136
|
+
}>;
|
|
137
|
+
/**
|
|
138
|
+
* Build the held-out `reviewThreads` GraphQL query. ADDITIVELY requests the span
|
|
139
|
+
* anchors (`line`, `originalLine`, comment `diffHunk`) + the audit ids
|
|
140
|
+
* (`thread.id`, comment `databaseId`) on top of the mining query's
|
|
141
|
+
* `isResolved`/`isOutdated`/`path`/`author`/`body`. It deliberately does NOT add
|
|
142
|
+
* an `isResolved: false` server filter (the "surface, don't filter" ruling).
|
|
143
|
+
* Exported for the query-spy test.
|
|
144
|
+
*/
|
|
145
|
+
export declare function buildCorpusDispositionsQuery(owner: string, name: string, pr: number): string;
|
|
146
|
+
/**
|
|
147
|
+
* Map validated GraphQL thread nodes to `CorpusDispositionThread[]`. The thread's
|
|
148
|
+
* span source `diffHunk` is the ROOT (first) comment's hunk — the finding's
|
|
149
|
+
* anchor; a thread with no comments carries ''. A null author (deleted/ghost)
|
|
150
|
+
* coerces to '' (a non-bot empty author core's logic handles). Pure — exported
|
|
151
|
+
* for the mapping test.
|
|
152
|
+
*/
|
|
153
|
+
export declare function mapDispositionThreads(nodes: z.infer<typeof GqlThreadSchema>[]): CorpusDispositionThread[];
|
|
154
|
+
export interface CorpusDispositionSourceOptions {
|
|
155
|
+
owner: string;
|
|
156
|
+
name: string;
|
|
157
|
+
cwd?: string;
|
|
158
|
+
/** Injectable exec seam (tests). Defaults to a `gh`-backed `safeExec`. */
|
|
159
|
+
exec?: GhExec;
|
|
160
|
+
/** Process env (injected in tests) — the CI hard-gate reads it. Defaults to `process.env`. */
|
|
161
|
+
env?: NodeJS.ProcessEnv;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* The live held-out `corpus-dispositions` source. By-hand producer-time only
|
|
165
|
+
* (never CI — the hard-gate enforces it). `fetch` throws loud on any fault.
|
|
166
|
+
*/
|
|
167
|
+
export declare class CorpusDispositionSourceAdapter {
|
|
168
|
+
private readonly owner;
|
|
169
|
+
private readonly name;
|
|
170
|
+
private readonly cwd;
|
|
171
|
+
private readonly env;
|
|
172
|
+
private readonly injectedExec;
|
|
173
|
+
private execPromise;
|
|
174
|
+
constructor(opts: CorpusDispositionSourceOptions);
|
|
175
|
+
private resolveExec;
|
|
176
|
+
fetch(pr: number): Promise<CorpusDisposition>;
|
|
177
|
+
}
|
|
178
|
+
export {};
|
|
179
|
+
//# sourceMappingURL=spine-corpus-disposition-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spine-corpus-disposition-source.d.ts","sourceRoot":"","sources":["../../src/commands/spine-corpus-disposition-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAE/E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AAsB9D,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWnB,CAAC;AAsBH;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CA4B5F;AAID;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,EAAE,GACvC,uBAAuB,EAAE,CAgB3B;AAID,MAAM,WAAW,8BAA8B;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8FAA8F;IAC9F,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED;;;GAGG;AACH,qBAAa,8BAA8B;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoB;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,WAAW,CAA8B;gBAErC,IAAI,EAAE,8BAA8B;YAQlC,WAAW;IAkBnB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAmHpD"}
|