@mmnto/cli 1.72.1 → 1.73.1
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 +44 -11
- package/dist/commands/spine-cert-run-corpus.d.ts.map +1 -1
- package/dist/commands/spine-cert-run-corpus.js +128 -42
- package/dist/commands/spine-cert-run-corpus.js.map +1 -1
- package/dist/commands/spine-cert-run-corpus.test.js +41 -6
- 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 +114 -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,7 +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';
|
|
4
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";
|
|
5
11
|
export interface CertRunFixtureInputs {
|
|
6
12
|
split: import('@mmnto/totem').SplitArtifact;
|
|
7
13
|
artifact: ReplayArtifact;
|
|
@@ -17,7 +23,19 @@ export interface CertRunFixtureInputs {
|
|
|
17
23
|
*/
|
|
18
24
|
export declare function loadCertRunFixtures(gate1Dir: string, opts?: {
|
|
19
25
|
expectedPrDiffsSha?: string;
|
|
26
|
+
expectedGroundTruthSha?: string;
|
|
27
|
+
skipGroundTruth?: boolean;
|
|
20
28
|
}): Promise<CertRunFixtureInputs>;
|
|
29
|
+
/**
|
|
30
|
+
* Build the Stage-4 verifier deps (listFiles/readFile over the frozen post-image
|
|
31
|
+
* at `asOf`) — the SHARED constructor both the certifying run and the 5d-iii
|
|
32
|
+
* deriver use, so the archived-rule exclusion (hence the scored rule set, hence
|
|
33
|
+
* the firing labelIds) is identical. With an lc clone, files resolve via
|
|
34
|
+
* `git ls-tree`/`git show` at `asOf` (a local clone — zero network); without one,
|
|
35
|
+
* Stage-4 sees no files (rules read as untested, NOT archived). Tests inject a
|
|
36
|
+
* fake `Stage4VerifierDeps` into `assembleCertifyingCorpus` directly instead.
|
|
37
|
+
*/
|
|
38
|
+
export declare function buildGate1Stage4Deps(lcDir: string | undefined, asOf: string, safeExec: SafeExecFn): Stage4VerifierDeps;
|
|
21
39
|
export interface ReplayCorpusProviderOptions {
|
|
22
40
|
/** The `.totem/spine/gate-1` dir holding the committed cert-run fixtures. */
|
|
23
41
|
gate1Dir: string;
|
|
@@ -31,15 +49,30 @@ export interface ReplayCorpusProviderOptions {
|
|
|
31
49
|
onLedgers?: (ledgers: MinerLedgers) => void;
|
|
32
50
|
}
|
|
33
51
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* `
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
52
|
+
* Assemble the REPLAY-mode `CertifyingCorpus` (rules + prDiffs + provenance) from
|
|
53
|
+
* the committed gate-1 fixtures — the SHARED path both the certifying run (via
|
|
54
|
+
* `buildReplayCorpusProvider`) and the 5d-iii label-deriver call, so the corpus
|
|
55
|
+
* they enumerate firings over is byte-identical (the answer-key labelIds the
|
|
56
|
+
* deriver mints are the ones the run looks up). The deriver passes
|
|
57
|
+
* `skipGroundTruth: true` — it PRODUCES `ground-truth-labels.json`, so it must
|
|
58
|
+
* not read it (circularity guard); the run omits the flag and loads the frozen
|
|
59
|
+
* answer key. Returns the fold-I ledgers too; the caller decides whether to emit
|
|
60
|
+
* them (the run does; the deriver discards — they belong to the run artifact).
|
|
61
|
+
*/
|
|
62
|
+
export declare function assembleCertifyingCorpus(opts: ReplayCorpusProviderOptions & {
|
|
63
|
+
skipGroundTruth?: boolean;
|
|
64
|
+
}, lock: WindtunnelLock): Promise<{
|
|
65
|
+
corpus: CertifyingCorpus;
|
|
66
|
+
ledgers: MinerLedgers;
|
|
67
|
+
}>;
|
|
68
|
+
/**
|
|
69
|
+
* Build the REPLAY-mode `CertifyingCorpusProvider` the certifying run injects: a thin
|
|
70
|
+
* wrapper over `assembleCertifyingCorpus` (fixture-load + replay adapters + the
|
|
71
|
+
* `buildCertifyingCorpus` composition) that also emits the fold-I miner ledgers
|
|
72
|
+
* (default: `miner-ledgers.json`) for §7 observability. The deriver calls
|
|
73
|
+
* `assembleCertifyingCorpus` directly instead (it skips ground-truth + discards the
|
|
74
|
+
* ledgers, which belong to the run artifact).
|
|
43
75
|
*/
|
|
44
76
|
export declare function buildReplayCorpusProvider(opts: ReplayCorpusProviderOptions): CertifyingCorpusProvider;
|
|
77
|
+
export {};
|
|
45
78
|
//# 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":"AAMA,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,mBAAmB,EAGnB,kBAAkB,
|
|
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;IACL,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,GACA,OAAO,CAAC,oBAAoB,CAAC,CAyF/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,CAiE9D;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,2BAA2B,GAChC,wBAAwB,CAkB1B"}
|
|
@@ -10,7 +10,10 @@ const SPLIT_FILE = 'split.json';
|
|
|
10
10
|
const REPLAY_FILE = 'llm-replay.v1.json';
|
|
11
11
|
const CONTENT_FILE = 'review-content.json';
|
|
12
12
|
export const PR_DIFFS_FILE = 'pr-diffs.json';
|
|
13
|
-
|
|
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';
|
|
14
17
|
const LEDGERS_FILE = 'miner-ledgers.json';
|
|
15
18
|
// ─── Fixture schemas (the committed cert-run inputs) ──
|
|
16
19
|
const ReviewThreadContentSchema = z.object({
|
|
@@ -89,10 +92,68 @@ export async function loadCertRunFixtures(gate1Dir, opts) {
|
|
|
89
92
|
}
|
|
90
93
|
}
|
|
91
94
|
const prDiffs = z.array(ResolvedPrDiffSchema).parse(parseJson(prDiffsRaw, prDiffsFile));
|
|
92
|
-
|
|
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
|
+
}
|
|
103
|
+
// #709 5d-iii-ii: verify-then-parse the ANSWER KEY on a SINGLE read — the run grades
|
|
104
|
+
// firings against the frozen ground-truth-labels.json, so the digest must cover the
|
|
105
|
+
// exact bytes parsed + scored, not a separate read (mirror prDiffsSha — no check/use
|
|
106
|
+
// split). CRLF→LF normalized to match the deriver's LF-stamped digest. The absent-from-
|
|
107
|
+
// lock case is the caller's precondition (it omits the sha). The deriver never reaches
|
|
108
|
+
// here — `skipGroundTruth` returns above, because it PRODUCES this file (circularity).
|
|
109
|
+
const groundTruthFile = path.join(gate1Dir, GROUND_TRUTH_FILE);
|
|
110
|
+
const groundTruthRaw = readRaw(groundTruthFile);
|
|
111
|
+
if (opts?.expectedGroundTruthSha !== undefined) {
|
|
112
|
+
const actual = createHash('sha256')
|
|
113
|
+
.update(groundTruthRaw.replace(/\r\n/g, '\n'), 'utf-8')
|
|
114
|
+
.digest('hex');
|
|
115
|
+
if (actual !== opts.expectedGroundTruthSha) {
|
|
116
|
+
throw new TotemError('CONFIG_INVALID', `Certifying run: ground-truth-labels.json integrity FAILED — expected ${opts.expectedGroundTruthSha}, got ` +
|
|
117
|
+
`${actual} (the frozen answer key was tampered or re-serialized).`, 'Re-derive the answer key with `spine windtunnel derive-labels` or re-materialize the cert corpus.');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const gtRecord = GroundTruthSchema.parse(parseJson(groundTruthRaw, groundTruthFile));
|
|
93
121
|
const groundTruth = new Map(Object.entries(gtRecord));
|
|
94
122
|
return { split, artifact, content, prDiffs, groundTruth };
|
|
95
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Build the Stage-4 verifier deps (listFiles/readFile over the frozen post-image
|
|
126
|
+
* at `asOf`) — the SHARED constructor both the certifying run and the 5d-iii
|
|
127
|
+
* deriver use, so the archived-rule exclusion (hence the scored rule set, hence
|
|
128
|
+
* the firing labelIds) is identical. With an lc clone, files resolve via
|
|
129
|
+
* `git ls-tree`/`git show` at `asOf` (a local clone — zero network); without one,
|
|
130
|
+
* Stage-4 sees no files (rules read as untested, NOT archived). Tests inject a
|
|
131
|
+
* fake `Stage4VerifierDeps` into `assembleCertifyingCorpus` directly instead.
|
|
132
|
+
*/
|
|
133
|
+
export function buildGate1Stage4Deps(lcDir, asOf, safeExec) {
|
|
134
|
+
if (lcDir) {
|
|
135
|
+
return {
|
|
136
|
+
// The `--` separator keeps the revision unambiguous from any path args and blocks
|
|
137
|
+
// arg injection (CR coding guideline) — this shared path decides which files
|
|
138
|
+
// Stage-4 sees for BOTH the run and the deriver, so rev/path ambiguity here would
|
|
139
|
+
// shift archived-rule decisions and the derived labels.
|
|
140
|
+
listFiles: async () => safeExec('git', ['ls-tree', '-r', '--name-only', asOf, '--'], { cwd: lcDir })
|
|
141
|
+
.split('\n')
|
|
142
|
+
.filter(Boolean),
|
|
143
|
+
readFile: async (f) => safeExec('git', ['show', `${asOf}:${f.replace(/\\/g, '/')}`, '--'], { cwd: lcDir }),
|
|
144
|
+
workingDirectory: lcDir,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
// No lc clone → Stage-4 sees no files (rules read as 'no-matches' / untested,
|
|
149
|
+
// NOT archived) — the wind-tunnel firing/scoring still runs.
|
|
150
|
+
listFiles: async () => [],
|
|
151
|
+
readFile: async (f) => {
|
|
152
|
+
const { TotemError } = await import('@mmnto/totem');
|
|
153
|
+
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.');
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
}
|
|
96
157
|
/** Derive the SplitLedger from the loaded split + the lock's resolved corpus. */
|
|
97
158
|
function splitLedgerFrom(split, lock) {
|
|
98
159
|
return {
|
|
@@ -105,49 +166,74 @@ function splitLedgerFrom(split, lock) {
|
|
|
105
166
|
};
|
|
106
167
|
}
|
|
107
168
|
/**
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* `
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
169
|
+
* Assemble the REPLAY-mode `CertifyingCorpus` (rules + prDiffs + provenance) from
|
|
170
|
+
* the committed gate-1 fixtures — the SHARED path both the certifying run (via
|
|
171
|
+
* `buildReplayCorpusProvider`) and the 5d-iii label-deriver call, so the corpus
|
|
172
|
+
* they enumerate firings over is byte-identical (the answer-key labelIds the
|
|
173
|
+
* deriver mints are the ones the run looks up). The deriver passes
|
|
174
|
+
* `skipGroundTruth: true` — it PRODUCES `ground-truth-labels.json`, so it must
|
|
175
|
+
* not read it (circularity guard); the run omits the flag and loads the frozen
|
|
176
|
+
* answer key. Returns the fold-I ledgers too; the caller decides whether to emit
|
|
177
|
+
* them (the run does; the deriver discards — they belong to the run artifact).
|
|
178
|
+
*/
|
|
179
|
+
export async function assembleCertifyingCorpus(opts, lock) {
|
|
180
|
+
const { TotemError } = await import('@mmnto/totem');
|
|
181
|
+
const expectedHash = lock.controls.integrity.llmReplaySha;
|
|
182
|
+
if (!expectedHash) {
|
|
183
|
+
throw new TotemError('CONFIG_INVALID', 'Certifying run: lock is missing controls.integrity.llmReplaySha (L2) — the frozen ' +
|
|
184
|
+
'llm-replay fixture cannot be integrity-checked.', 'Re-freeze the lock after a `record` run.');
|
|
185
|
+
}
|
|
186
|
+
// #2225 (#709 fold-2): hash-bind the SCORING source. `pr-diffs.json` is otherwise
|
|
187
|
+
// unprotected — `fixtureSha` covers only the control dirs — so a silent mutation of
|
|
188
|
+
// any row (advisory-window OR control) would corrupt the answer key while the
|
|
189
|
+
// control-dir gate stays green. The absent-from-lock case is a lock precondition
|
|
190
|
+
// (checked here); `loadCertRunFixtures` verifies the digest on the SAME read it
|
|
191
|
+
// parses — no check/use split (CR). Fail loud (strategy ruled: verify at freeze AND run).
|
|
192
|
+
const expectedPrDiffsSha = lock.controls.integrity.prDiffsSha;
|
|
193
|
+
if (!expectedPrDiffsSha) {
|
|
194
|
+
throw new TotemError('CONFIG_INVALID', 'Certifying run: lock is missing controls.integrity.prDiffsSha (#709 fold-2) — the ' +
|
|
195
|
+
'pr-diffs.json scoring source cannot be integrity-checked.', 'Re-materialize the cert corpus with `spine windtunnel materialize`.');
|
|
196
|
+
}
|
|
197
|
+
// #709 5d-iii-ii: the ANSWER KEY digest is run-critical like prDiffsSha — the run reads
|
|
198
|
+
// the MATERIALIZED frozen labels (never re-derives), so without this the cert could grade
|
|
199
|
+
// against a tampered/stale answer key while every other gate stays green. Gated on the RUN
|
|
200
|
+
// path: the deriver (skipGroundTruth) PRODUCES ground-truth-labels.json + stamps
|
|
201
|
+
// groundTruthSha, so on a first derive the lock legitimately has none yet.
|
|
202
|
+
const expectedGroundTruthSha = lock.controls.integrity.groundTruthSha;
|
|
203
|
+
if (!opts.skipGroundTruth && !expectedGroundTruthSha) {
|
|
204
|
+
throw new TotemError('CONFIG_INVALID', 'Certifying run: lock is missing controls.integrity.groundTruthSha (#709 5d-iii) — the ' +
|
|
205
|
+
'ground-truth-labels.json answer key cannot be integrity-checked.', 'Re-derive the answer key with `spine windtunnel derive-labels` (it stamps groundTruthSha) and re-freeze.');
|
|
206
|
+
}
|
|
207
|
+
const { split, artifact, content, prDiffs, groundTruth } = await loadCertRunFixtures(opts.gate1Dir, {
|
|
208
|
+
expectedPrDiffsSha,
|
|
209
|
+
expectedGroundTruthSha: opts.skipGroundTruth ? undefined : expectedGroundTruthSha,
|
|
210
|
+
skipGroundTruth: opts.skipGroundTruth,
|
|
211
|
+
});
|
|
212
|
+
const { extractor, classifier } = buildReplayAdapters(artifact, expectedHash);
|
|
213
|
+
return buildCertifyingCorpus({
|
|
214
|
+
split,
|
|
215
|
+
splitLedger: splitLedgerFrom(split, lock),
|
|
216
|
+
source: frozenSourceFrom(content),
|
|
217
|
+
extractor,
|
|
218
|
+
classifier,
|
|
219
|
+
seedClassesProvided: opts.seedClassesProvided ?? false,
|
|
220
|
+
stage4: opts.stage4,
|
|
221
|
+
now: opts.now,
|
|
222
|
+
prDiffs,
|
|
223
|
+
groundTruth,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Build the REPLAY-mode `CertifyingCorpusProvider` the certifying run injects: a thin
|
|
228
|
+
* wrapper over `assembleCertifyingCorpus` (fixture-load + replay adapters + the
|
|
229
|
+
* `buildCertifyingCorpus` composition) that also emits the fold-I miner ledgers
|
|
230
|
+
* (default: `miner-ledgers.json`) for §7 observability. The deriver calls
|
|
231
|
+
* `assembleCertifyingCorpus` directly instead (it skips ground-truth + discards the
|
|
232
|
+
* ledgers, which belong to the run artifact).
|
|
117
233
|
*/
|
|
118
234
|
export function buildReplayCorpusProvider(opts) {
|
|
119
235
|
return async (lock) => {
|
|
120
|
-
const {
|
|
121
|
-
const expectedHash = lock.controls.integrity.llmReplaySha;
|
|
122
|
-
if (!expectedHash) {
|
|
123
|
-
throw new TotemError('CONFIG_INVALID', 'Certifying run: lock is missing controls.integrity.llmReplaySha (L2) — the frozen ' +
|
|
124
|
-
'llm-replay fixture cannot be integrity-checked.', 'Re-freeze the lock after a `record` run.');
|
|
125
|
-
}
|
|
126
|
-
// #2225 (#709 fold-2): hash-bind the SCORING source. `pr-diffs.json` is otherwise
|
|
127
|
-
// unprotected — `fixtureSha` covers only the control dirs — so a silent mutation of
|
|
128
|
-
// any row (advisory-window OR control) would corrupt the answer key while the
|
|
129
|
-
// control-dir gate stays green. The absent-from-lock case is a lock precondition
|
|
130
|
-
// (checked here); `loadCertRunFixtures` verifies the digest on the SAME read it
|
|
131
|
-
// parses — no check/use split (CR). Fail loud (strategy ruled: verify at freeze AND run).
|
|
132
|
-
const expectedPrDiffsSha = lock.controls.integrity.prDiffsSha;
|
|
133
|
-
if (!expectedPrDiffsSha) {
|
|
134
|
-
throw new TotemError('CONFIG_INVALID', 'Certifying run: lock is missing controls.integrity.prDiffsSha (#709 fold-2) — the ' +
|
|
135
|
-
'pr-diffs.json scoring source cannot be integrity-checked.', 'Re-materialize the cert corpus with `spine windtunnel materialize`.');
|
|
136
|
-
}
|
|
137
|
-
const { split, artifact, content, prDiffs, groundTruth } = await loadCertRunFixtures(opts.gate1Dir, { expectedPrDiffsSha });
|
|
138
|
-
const { extractor, classifier } = buildReplayAdapters(artifact, expectedHash);
|
|
139
|
-
const { corpus, ledgers } = await buildCertifyingCorpus({
|
|
140
|
-
split,
|
|
141
|
-
splitLedger: splitLedgerFrom(split, lock),
|
|
142
|
-
source: frozenSourceFrom(content),
|
|
143
|
-
extractor,
|
|
144
|
-
classifier,
|
|
145
|
-
seedClassesProvided: opts.seedClassesProvided ?? false,
|
|
146
|
-
stage4: opts.stage4,
|
|
147
|
-
now: opts.now,
|
|
148
|
-
prDiffs,
|
|
149
|
-
groundTruth,
|
|
150
|
-
});
|
|
236
|
+
const { corpus, ledgers } = await assembleCertifyingCorpus(opts, lock);
|
|
151
237
|
// fold-I (§7): emit the miner ledgers, observable beside the cert-run report.
|
|
152
238
|
if (opts.onLedgers) {
|
|
153
239
|
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,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,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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"}
|
|
@@ -85,10 +85,10 @@ function stage4(files) {
|
|
|
85
85
|
readFile: (f) => f in files ? Promise.resolve(files[f]) : Promise.reject(new Error(`absent ${f}`)),
|
|
86
86
|
};
|
|
87
87
|
}
|
|
88
|
-
/** A minimal lock partial — the provider reads the L2 hash, the pr-diffs
|
|
89
|
-
function lockWith(llmReplaySha, prDiffsSha) {
|
|
88
|
+
/** A minimal lock partial — the provider reads the L2 hash, the pr-diffs + ground-truth digests, + resolved corpus. */
|
|
89
|
+
function lockWith(llmReplaySha, prDiffsSha, groundTruthSha) {
|
|
90
90
|
return {
|
|
91
|
-
controls: { integrity: { llmReplaySha, prDiffsSha } },
|
|
91
|
+
controls: { integrity: { llmReplaySha, prDiffsSha, groundTruthSha } },
|
|
92
92
|
corpus: { resolvedPrs: [{ pr: 1, mergeCommit: sha(1) }] },
|
|
93
93
|
};
|
|
94
94
|
}
|
|
@@ -137,6 +137,14 @@ function prDiffsHash() {
|
|
|
137
137
|
.update(fs.readFileSync(path.join(gate1Dir, 'pr-diffs.json'), 'utf-8').replace(/\r\n/g, '\n'), 'utf-8')
|
|
138
138
|
.digest('hex');
|
|
139
139
|
}
|
|
140
|
+
/** sha256 of the CRLF→LF-normalized on-disk ground-truth-labels.json — the digest the run gate (#709 5d-iii-ii) asserts. */
|
|
141
|
+
function groundTruthHash() {
|
|
142
|
+
return createHash('sha256')
|
|
143
|
+
.update(fs
|
|
144
|
+
.readFileSync(path.join(gate1Dir, 'ground-truth-labels.json'), 'utf-8')
|
|
145
|
+
.replace(/\r\n/g, '\n'), 'utf-8')
|
|
146
|
+
.digest('hex');
|
|
147
|
+
}
|
|
140
148
|
// ─── Tests ───────────────────────────────────────────
|
|
141
149
|
describe('buildReplayCorpusProvider (run-path)', () => {
|
|
142
150
|
it('loads the committed fixtures + replays them into a corpus (zero LLM/network)', async () => {
|
|
@@ -150,7 +158,7 @@ describe('buildReplayCorpusProvider (run-path)', () => {
|
|
|
150
158
|
captured = l;
|
|
151
159
|
},
|
|
152
160
|
});
|
|
153
|
-
const corpus = await provider(lockWith(hash, prDiffsHash()));
|
|
161
|
+
const corpus = await provider(lockWith(hash, prDiffsHash(), groundTruthHash()));
|
|
154
162
|
expect(corpus.rules).toHaveLength(1);
|
|
155
163
|
expect(corpus.provenanceByRule.get(corpus.rules[0].lessonHash)?.mergedPr).toBe(1);
|
|
156
164
|
// fold-I ledgers emitted via the sink.
|
|
@@ -171,7 +179,7 @@ describe('buildReplayCorpusProvider (run-path)', () => {
|
|
|
171
179
|
stage4: stage4({ 'src/a.ts': 'forbiddenCall()' }),
|
|
172
180
|
now: NOW,
|
|
173
181
|
});
|
|
174
|
-
await provider(lockWith(hash, prDiffsHash()));
|
|
182
|
+
await provider(lockWith(hash, prDiffsHash(), groundTruthHash()));
|
|
175
183
|
expect(fs.existsSync(path.join(gate1Dir, 'miner-ledgers.json'))).toBe(true);
|
|
176
184
|
});
|
|
177
185
|
it('throws loud when the lock lacks the prDiffsSha digest (#2225 scoring-source gate)', async () => {
|
|
@@ -186,8 +194,9 @@ describe('buildReplayCorpusProvider (run-path)', () => {
|
|
|
186
194
|
});
|
|
187
195
|
it('throws loud when pr-diffs.json is tampered after freeze (#2225 fold-2)', async () => {
|
|
188
196
|
const hash = await fixtureHash();
|
|
189
|
-
const lock = lockWith(hash, prDiffsHash()); //
|
|
197
|
+
const lock = lockWith(hash, prDiffsHash(), groundTruthHash()); // digests captured over the frozen bytes
|
|
190
198
|
// a schema-valid but byte-different scoring source — passes Zod, fails the digest.
|
|
199
|
+
// (pr-diffs is verified BEFORE ground-truth in the loader, so this fires first.)
|
|
191
200
|
fs.writeFileSync(path.join(gate1Dir, 'pr-diffs.json'), JSON.stringify([{ pr: 1, diff: 'tampered', controlKind: 'corpus' }]), 'utf-8');
|
|
192
201
|
const provider = buildReplayCorpusProvider({
|
|
193
202
|
gate1Dir,
|
|
@@ -196,5 +205,31 @@ describe('buildReplayCorpusProvider (run-path)', () => {
|
|
|
196
205
|
});
|
|
197
206
|
await expect(provider(lock)).rejects.toThrow(/pr-diffs\.json integrity/);
|
|
198
207
|
});
|
|
208
|
+
it('throws loud when the lock lacks the groundTruthSha digest (#709 5d-iii-ii answer-key gate)', async () => {
|
|
209
|
+
const hash = await fixtureHash();
|
|
210
|
+
const provider = buildReplayCorpusProvider({
|
|
211
|
+
gate1Dir,
|
|
212
|
+
stage4: stage4({ 'src/a.ts': 'forbiddenCall()' }),
|
|
213
|
+
now: NOW,
|
|
214
|
+
});
|
|
215
|
+
// llmReplaySha + prDiffsSha present, groundTruthSha omitted → the run-path answer-key
|
|
216
|
+
// gate fires (the precondition is ordered after prDiffsSha, so the prDiffsSha-only
|
|
217
|
+
// tests above still trip their own error).
|
|
218
|
+
await expect(provider(lockWith(hash, prDiffsHash(), undefined))).rejects.toThrow(/groundTruthSha/);
|
|
219
|
+
});
|
|
220
|
+
it('throws loud when ground-truth-labels.json is tampered after freeze (#709 5d-iii-ii)', async () => {
|
|
221
|
+
const hash = await fixtureHash();
|
|
222
|
+
// groundTruthSha captured over the pristine `{}` fixture from beforeEach, before the tamper below
|
|
223
|
+
const lock = lockWith(hash, prDiffsHash(), groundTruthHash());
|
|
224
|
+
// a schema-valid but byte-different answer key — passes Zod (firingLabelId → TP), fails
|
|
225
|
+
// the digest. pr-diffs stays intact so the ground-truth gate (read second) is what fires.
|
|
226
|
+
fs.writeFileSync(path.join(gate1Dir, 'ground-truth-labels.json'), JSON.stringify({ 'abc123:src/a.ts:1': 'TP' }), 'utf-8');
|
|
227
|
+
const provider = buildReplayCorpusProvider({
|
|
228
|
+
gate1Dir,
|
|
229
|
+
stage4: stage4({ 'src/a.ts': 'forbiddenCall()' }),
|
|
230
|
+
now: NOW,
|
|
231
|
+
});
|
|
232
|
+
await expect(provider(lock)).rejects.toThrow(/ground-truth-labels\.json integrity/);
|
|
233
|
+
});
|
|
199
234
|
});
|
|
200
235
|
//# 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"}
|