@mmnto/totem 1.67.1 → 1.68.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/capability/falsification.d.ts +18 -0
- package/dist/capability/falsification.d.ts.map +1 -0
- package/dist/capability/falsification.js +56 -0
- package/dist/capability/falsification.js.map +1 -0
- package/dist/capability/falsification.test.d.ts +2 -0
- package/dist/capability/falsification.test.d.ts.map +1 -0
- package/dist/capability/falsification.test.js +112 -0
- package/dist/capability/falsification.test.js.map +1 -0
- package/dist/capability/regenerate.d.ts +20 -0
- package/dist/capability/regenerate.d.ts.map +1 -0
- package/dist/capability/regenerate.js +0 -0
- package/dist/capability/regenerate.js.map +1 -0
- package/dist/capability/regenerate.test.d.ts +2 -0
- package/dist/capability/regenerate.test.d.ts.map +1 -0
- package/dist/capability/regenerate.test.js +136 -0
- package/dist/capability/regenerate.test.js.map +1 -0
- package/dist/capability/review-catch.d.ts +53 -0
- package/dist/capability/review-catch.d.ts.map +1 -0
- package/dist/capability/review-catch.js +92 -0
- package/dist/capability/review-catch.js.map +1 -0
- package/dist/capability/review-catch.test.d.ts +2 -0
- package/dist/capability/review-catch.test.d.ts.map +1 -0
- package/dist/capability/review-catch.test.js +90 -0
- package/dist/capability/review-catch.test.js.map +1 -0
- package/dist/capability/schema.d.ts +244 -0
- package/dist/capability/schema.d.ts.map +1 -0
- package/dist/capability/schema.js +141 -0
- package/dist/capability/schema.js.map +1 -0
- package/dist/capability/schema.test.d.ts +2 -0
- package/dist/capability/schema.test.d.ts.map +1 -0
- package/dist/capability/schema.test.js +93 -0
- package/dist/capability/schema.test.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/spine/candidate-rule.d.ts +84 -0
- package/dist/spine/candidate-rule.d.ts.map +1 -0
- package/dist/spine/candidate-rule.js +68 -0
- package/dist/spine/candidate-rule.js.map +1 -0
- package/dist/spine/candidate-rule.test.d.ts +2 -0
- package/dist/spine/candidate-rule.test.d.ts.map +1 -0
- package/dist/spine/candidate-rule.test.js +40 -0
- package/dist/spine/candidate-rule.test.js.map +1 -0
- package/dist/spine/classify.d.ts +93 -0
- package/dist/spine/classify.d.ts.map +1 -0
- package/dist/spine/classify.js +190 -0
- package/dist/spine/classify.js.map +1 -0
- package/dist/spine/classify.test.d.ts +2 -0
- package/dist/spine/classify.test.d.ts.map +1 -0
- package/dist/spine/classify.test.js +302 -0
- package/dist/spine/classify.test.js.map +1 -0
- package/dist/spine/compile.d.ts +62 -0
- package/dist/spine/compile.d.ts.map +1 -0
- package/dist/spine/compile.js +204 -0
- package/dist/spine/compile.js.map +1 -0
- package/dist/spine/compile.test.d.ts +2 -0
- package/dist/spine/compile.test.d.ts.map +1 -0
- package/dist/spine/compile.test.js +327 -0
- package/dist/spine/compile.test.js.map +1 -0
- package/dist/spine/extract.d.ts +146 -0
- package/dist/spine/extract.d.ts.map +1 -0
- package/dist/spine/extract.js +227 -0
- package/dist/spine/extract.js.map +1 -0
- package/dist/spine/extract.test.d.ts +2 -0
- package/dist/spine/extract.test.d.ts.map +1 -0
- package/dist/spine/extract.test.js +382 -0
- package/dist/spine/extract.test.js.map +1 -0
- package/dist/spine/ledgers.d.ts +1102 -0
- package/dist/spine/ledgers.d.ts.map +1 -0
- package/dist/spine/ledgers.js +209 -0
- package/dist/spine/ledgers.js.map +1 -0
- package/dist/spine/miner-harness.d.ts +30 -0
- package/dist/spine/miner-harness.d.ts.map +1 -0
- package/dist/spine/miner-harness.js +214 -0
- package/dist/spine/miner-harness.js.map +1 -0
- package/dist/spine/miner-harness.test.d.ts +2 -0
- package/dist/spine/miner-harness.test.d.ts.map +1 -0
- package/dist/spine/miner-harness.test.js +231 -0
- package/dist/spine/miner-harness.test.js.map +1 -0
- package/dist/spine/split.d.ts +149 -0
- package/dist/spine/split.d.ts.map +1 -0
- package/dist/spine/split.js +235 -0
- package/dist/spine/split.js.map +1 -0
- package/dist/spine/split.test.d.ts +2 -0
- package/dist/spine/split.test.d.ts.map +1 -0
- package/dist/spine/split.test.js +142 -0
- package/dist/spine/split.test.js.map +1 -0
- package/dist/spine/windtunnel-lock.d.ts +8 -8
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.test.d.ts","sourceRoot":"","sources":["../../src/spine/compile.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { runClassifyStage, } from './classify.js';
|
|
3
|
+
import { compileCandidate, runCompileStage, } from './compile.js';
|
|
4
|
+
import { runFalsificationHarness } from './miner-harness.js';
|
|
5
|
+
// The frozen LessonInput actuator is wrapped in spies so the call-spy test (agy
|
|
6
|
+
// fold-1) can assert the G-series path NEVER touches it. `validateAstGrepPattern`
|
|
7
|
+
// (the one symbol compile.ts imports from this module) is preserved via `...actual`.
|
|
8
|
+
vi.mock('../compile-lesson.js', async (importOriginal) => {
|
|
9
|
+
const actual = await importOriginal();
|
|
10
|
+
return {
|
|
11
|
+
...actual,
|
|
12
|
+
compileLesson: vi.fn(actual.compileLesson),
|
|
13
|
+
buildCompiledRule: vi.fn(actual.buildCompiledRule),
|
|
14
|
+
buildManualRule: vi.fn(actual.buildManualRule),
|
|
15
|
+
};
|
|
16
|
+
});
|
|
17
|
+
import * as frozenActuator from '../compile-lesson.js';
|
|
18
|
+
const sha = (n) => String(n).padStart(40, '0');
|
|
19
|
+
const NOW = '2026-06-19T12:00:00.000Z';
|
|
20
|
+
// ── dslSource fixtures (lesson-markdown bodies the slice-2/3 format produces) ──
|
|
21
|
+
const REGEX_DSL = [
|
|
22
|
+
'**Pattern:** `forbiddenCall\\(`',
|
|
23
|
+
'**Engine:** regex',
|
|
24
|
+
'**Severity:** warning',
|
|
25
|
+
'',
|
|
26
|
+
'### Bad Example',
|
|
27
|
+
'```ts',
|
|
28
|
+
'forbiddenCall()',
|
|
29
|
+
'```',
|
|
30
|
+
].join('\n');
|
|
31
|
+
// Same pattern, severity error — used to prove candidate-debt FORCES warning.
|
|
32
|
+
const REGEX_DSL_ERROR = REGEX_DSL.replace('**Severity:** warning', '**Severity:** error');
|
|
33
|
+
// A ReDoS-unsafe pattern — `validateRegex` rejects → compile-rejected.
|
|
34
|
+
const REDOS_DSL = ['**Pattern:** `(a+)+$`', '**Engine:** regex'].join('\n');
|
|
35
|
+
// engine: ast (tree-sitter query) — no ReDoS validator, so it compiles; used to
|
|
36
|
+
// exercise the workingDirectory guard without the ast-grep napi parser.
|
|
37
|
+
const AST_DSL = ['**Pattern:** `(call_expression)`', '**Engine:** ast'].join('\n');
|
|
38
|
+
// A compound ast-grep yaml rule — parse-fidelity check for the yaml engine.
|
|
39
|
+
const ASTGREP_YAML_DSL = [
|
|
40
|
+
'**Engine:** ast-grep',
|
|
41
|
+
'**Pattern:**',
|
|
42
|
+
'```yaml',
|
|
43
|
+
'rule:',
|
|
44
|
+
' pattern: console.log($MSG)',
|
|
45
|
+
'```',
|
|
46
|
+
].join('\n');
|
|
47
|
+
// No `**Pattern:**` — `extractManualPattern` returns null (a structural candidate
|
|
48
|
+
// here is a producer-contract violation: slice-2 preflight should have dropped it).
|
|
49
|
+
const NO_PATTERN_DSL = 'Prefer composition over inheritance — a behavioral note.';
|
|
50
|
+
// ── Builders ──────────────────────────────────────────────────────────────────
|
|
51
|
+
function candidateRule(pr, dslSource, disposition = 'structural', ordinal = 0) {
|
|
52
|
+
return {
|
|
53
|
+
provenance: { mergedPr: pr, reviewThread: `rt-${pr}`, commitSha: sha(pr) },
|
|
54
|
+
classifierDisposition: disposition,
|
|
55
|
+
classifierLedgerRef: `clr-${pr}-${ordinal}`,
|
|
56
|
+
dslSource,
|
|
57
|
+
unverified: true,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** A minimal ClassifyStageResult with emission + classifier ledgers consistent with the candidates. */
|
|
61
|
+
function classifyResultOf(candidates) {
|
|
62
|
+
return {
|
|
63
|
+
candidates,
|
|
64
|
+
emissionLedger: {
|
|
65
|
+
entries: candidates.map((c, i) => ({
|
|
66
|
+
candidateRef: `cand-${c.provenance.mergedPr}-${i}`,
|
|
67
|
+
provenance: c.provenance,
|
|
68
|
+
classifierDisposition: c.classifierDisposition,
|
|
69
|
+
routing: c.classifierDisposition === 'structural' ? 'compile' : 'rag-only',
|
|
70
|
+
classifierLedgerRef: c.classifierLedgerRef,
|
|
71
|
+
unverified: true,
|
|
72
|
+
})),
|
|
73
|
+
extractionInputsAttestation: { seedClassesProvided: false },
|
|
74
|
+
},
|
|
75
|
+
classifierLedger: {
|
|
76
|
+
entries: candidates.map((c) => ({
|
|
77
|
+
candidateRef: c.classifierLedgerRef,
|
|
78
|
+
disposition: c.classifierDisposition,
|
|
79
|
+
stage4Confirmed: false,
|
|
80
|
+
dispositionSource: 'classified',
|
|
81
|
+
})),
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/** Stage-4 deps backed by an in-memory file map. `readFile` rejects for a listed-but-absent file. */
|
|
86
|
+
function compileDeps(files, overrides = {}) {
|
|
87
|
+
return {
|
|
88
|
+
now: NOW,
|
|
89
|
+
stage4: {
|
|
90
|
+
listFiles: () => Promise.resolve(Object.keys(files)),
|
|
91
|
+
readFile: (f) => f in files ? Promise.resolve(files[f]) : Promise.reject(new Error(`absent ${f}`)),
|
|
92
|
+
...overrides.stage4,
|
|
93
|
+
},
|
|
94
|
+
...('baseline' in overrides ? { baseline: overrides.baseline } : {}),
|
|
95
|
+
...('now' in overrides ? { now: overrides.now } : {}),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
const single = (dsl, disp = 'structural') => classifyResultOf([candidateRule(1, dsl, disp)]);
|
|
99
|
+
// ── compileCandidate (pure) ─────────────────────────────────────────────────
|
|
100
|
+
describe('compileCandidate', () => {
|
|
101
|
+
it('compiles a regex structural candidate: unverified, no legitimacy/ruleClass/manual, injected now', () => {
|
|
102
|
+
const out = compileCandidate(candidateRule(1, REGEX_DSL), { now: NOW });
|
|
103
|
+
expect(out.kind).toBe('compiled');
|
|
104
|
+
if (out.kind !== 'compiled')
|
|
105
|
+
throw new Error('unreachable');
|
|
106
|
+
const { rule } = out;
|
|
107
|
+
expect(rule.engine).toBe('regex');
|
|
108
|
+
expect(rule.pattern).toBe('forbiddenCall\\(');
|
|
109
|
+
expect(rule.unverified).toBe(true);
|
|
110
|
+
expect(rule.legitimacy).toBeUndefined();
|
|
111
|
+
expect(rule.ruleClass).toBeUndefined();
|
|
112
|
+
expect(rule.manual).toBeUndefined();
|
|
113
|
+
expect(rule.badExample).toBe('forbiddenCall()');
|
|
114
|
+
expect(rule.compiledAt).toBe(NOW);
|
|
115
|
+
expect(rule.createdAt).toBe(NOW);
|
|
116
|
+
expect(rule.lessonHeading).toBe('Gate-1 rule candidate (clr-1-0)');
|
|
117
|
+
});
|
|
118
|
+
it('throws on a behavioral candidate (FM(c) code backstop)', () => {
|
|
119
|
+
expect(() => compileCandidate(candidateRule(1, REGEX_DSL, 'behavioral'), { now: NOW })).toThrow(/behavioral candidate .* must never be compiled/);
|
|
120
|
+
});
|
|
121
|
+
it('throws on a structural candidate with no usable pattern (preflight↔parser desync)', () => {
|
|
122
|
+
expect(() => compileCandidate(candidateRule(1, NO_PATTERN_DSL), { now: NOW })).toThrow(/no usable pattern/);
|
|
123
|
+
});
|
|
124
|
+
it('rejects (not throws) a ReDoS-unsafe regex → compile-rejected', () => {
|
|
125
|
+
const out = compileCandidate(candidateRule(1, REDOS_DSL), { now: NOW });
|
|
126
|
+
expect(out.kind).toBe('rejected');
|
|
127
|
+
});
|
|
128
|
+
it('parses a compound ast-grep yaml rule (engine ast-grep, astGrepYamlRule populated)', () => {
|
|
129
|
+
const out = compileCandidate(candidateRule(1, ASTGREP_YAML_DSL), { now: NOW });
|
|
130
|
+
expect(out.kind).toBe('compiled');
|
|
131
|
+
if (out.kind !== 'compiled')
|
|
132
|
+
throw new Error('unreachable');
|
|
133
|
+
expect(out.rule.engine).toBe('ast-grep');
|
|
134
|
+
expect(out.rule.astGrepYamlRule).toBeDefined();
|
|
135
|
+
expect(out.rule.pattern).toBe('');
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
// ── runCompileStage — the four Stage-4 outcome maps (regex, deterministic) ────
|
|
139
|
+
describe('runCompileStage — Stage-4 outcome → status/ledger maps', () => {
|
|
140
|
+
it('in-scope-bad-example → active/high/confirmed', async () => {
|
|
141
|
+
const r = await runCompileStage(single(REGEX_DSL), compileDeps({ 'src/a.ts': 'forbiddenCall()' }));
|
|
142
|
+
expect(r.compiled).toHaveLength(1);
|
|
143
|
+
expect(r.compiled[0]?.stage4.outcome).toBe('in-scope-bad-example');
|
|
144
|
+
expect(r.compiled[0]?.rule.status).toBe('active');
|
|
145
|
+
expect(r.compiled[0]?.rule.confidence).toBe('high');
|
|
146
|
+
expect(r.classifierLedger.entries[0]?.stage4Confirmed).toBe(true);
|
|
147
|
+
expect(r.classifierLedger.entries[0]?.stage4Outcome).toBe('confirmed');
|
|
148
|
+
});
|
|
149
|
+
it('candidate-debt → active, severity FORCED to warning, confirmed', async () => {
|
|
150
|
+
const r = await runCompileStage(single(REGEX_DSL_ERROR), compileDeps({ 'src/a.ts': 'forbiddenCall(x)' }));
|
|
151
|
+
expect(r.compiled[0]?.stage4.outcome).toBe('candidate-debt');
|
|
152
|
+
expect(r.compiled[0]?.rule.status).toBe('active');
|
|
153
|
+
expect(r.compiled[0]?.rule.severity).toBe('warning'); // forced down from error
|
|
154
|
+
expect(r.classifierLedger.entries[0]?.stage4Outcome).toBe('confirmed');
|
|
155
|
+
});
|
|
156
|
+
it('no-matches → untested-against-codebase, not confirmed', async () => {
|
|
157
|
+
const r = await runCompileStage(single(REGEX_DSL), compileDeps({ 'src/a.ts': 'const ok = 1;' }));
|
|
158
|
+
expect(r.compiled[0]?.stage4.outcome).toBe('no-matches');
|
|
159
|
+
expect(r.compiled[0]?.rule.status).toBe('untested-against-codebase');
|
|
160
|
+
expect(r.classifierLedger.entries[0]?.stage4Confirmed).toBe(false);
|
|
161
|
+
expect(r.classifierLedger.entries[0]?.stage4Outcome).toBe('untested-no-matches');
|
|
162
|
+
});
|
|
163
|
+
it('out-of-scope (fires on a baseline file) → archived, archivedAt=now, not confirmed', async () => {
|
|
164
|
+
const r = await runCompileStage(single(REGEX_DSL), compileDeps({ 'src/a.test.ts': 'forbiddenCall()' }));
|
|
165
|
+
expect(r.compiled[0]?.stage4.outcome).toBe('out-of-scope');
|
|
166
|
+
expect(r.compiled[0]?.rule.status).toBe('archived');
|
|
167
|
+
expect(r.compiled[0]?.rule.archivedAt).toBe(NOW);
|
|
168
|
+
expect(r.compiled[0]?.rule.archivedReason).toMatch(/stage4-out-of-scope-match/);
|
|
169
|
+
expect(r.classifierLedger.entries[0]?.stage4Outcome).toBe('archived-out-of-scope');
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
// ── runCompileStage — routing, rejection, ledger join, fail-loud ──────────────
|
|
173
|
+
describe('runCompileStage — selection, rejection & fail-loud', () => {
|
|
174
|
+
it('compiles only structural; skips behavioral (untouched ledger entry)', async () => {
|
|
175
|
+
const cls = classifyResultOf([
|
|
176
|
+
candidateRule(1, REGEX_DSL, 'structural'),
|
|
177
|
+
candidateRule(2, 'prefer X over Y', 'behavioral'),
|
|
178
|
+
]);
|
|
179
|
+
const r = await runCompileStage(cls, compileDeps({ 'src/a.ts': 'forbiddenCall()' }));
|
|
180
|
+
expect(r.compiled).toHaveLength(1);
|
|
181
|
+
expect(r.compiled[0]?.classifierLedgerRef).toBe('clr-1-0');
|
|
182
|
+
const behavioral = r.classifierLedger.entries.find((e) => e.candidateRef === 'clr-2-0');
|
|
183
|
+
expect(behavioral?.stage4Confirmed).toBe(false);
|
|
184
|
+
expect(behavioral?.stage4Outcome).toBeUndefined(); // never compiled
|
|
185
|
+
});
|
|
186
|
+
it('records compile-rejected on the ledger and emits no CompiledCandidate', async () => {
|
|
187
|
+
const r = await runCompileStage(single(REDOS_DSL), compileDeps({ 'src/a.ts': 'aaaa' }));
|
|
188
|
+
expect(r.compiled).toHaveLength(0);
|
|
189
|
+
expect(r.classifierLedger.entries[0]?.stage4Confirmed).toBe(false);
|
|
190
|
+
expect(r.classifierLedger.entries[0]?.stage4Outcome).toBe('compile-rejected');
|
|
191
|
+
});
|
|
192
|
+
it('fails loud when a structural candidate has no matching classifier-ledger entry', async () => {
|
|
193
|
+
const cls = single(REGEX_DSL);
|
|
194
|
+
cls.classifierLedger.entries = []; // drop the join target
|
|
195
|
+
await expect(runCompileStage(cls, compileDeps({}))).rejects.toThrow(/matches 0 classifier-ledger entries/);
|
|
196
|
+
});
|
|
197
|
+
it('fails loud on a duplicate classifier-ledger ref', async () => {
|
|
198
|
+
const cls = single(REGEX_DSL);
|
|
199
|
+
cls.classifierLedger.entries.push({ ...cls.classifierLedger.entries[0] });
|
|
200
|
+
await expect(runCompileStage(cls, compileDeps({ 'src/a.ts': 'forbiddenCall()' }))).rejects.toThrow(/matches 2 classifier-ledger entries/);
|
|
201
|
+
});
|
|
202
|
+
it('throws on an ast rule without a workingDirectory (never degrades to no-matches)', async () => {
|
|
203
|
+
await expect(runCompileStage(single(AST_DSL), compileDeps({ 'src/a.ts': 'x' }))).rejects.toThrow(/requires deps\.stage4\.workingDirectory/);
|
|
204
|
+
});
|
|
205
|
+
it('throws on an ast-grep rule without a workingDirectory too (both tree-sitter engines)', async () => {
|
|
206
|
+
await expect(runCompileStage(single(ASTGREP_YAML_DSL), compileDeps({ 'src/a.ts': 'x' }))).rejects.toThrow(/requires deps\.stage4\.workingDirectory/);
|
|
207
|
+
});
|
|
208
|
+
it('propagates a readFile failure loudly, preserving the original cause', async () => {
|
|
209
|
+
const deps = {
|
|
210
|
+
now: NOW,
|
|
211
|
+
stage4: {
|
|
212
|
+
listFiles: () => Promise.resolve(['src/a.ts']),
|
|
213
|
+
readFile: () => Promise.reject(new Error('disk gone')),
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
// compile.ts owns "no swallowing catch" — assert the ORIGINAL error survives as
|
|
217
|
+
// the cause, not the verifier's wrapper message (which compile.ts does not own).
|
|
218
|
+
const err = await runCompileStage(single(REGEX_DSL), deps).then(() => null, (e) => e);
|
|
219
|
+
expect(err).toBeInstanceOf(Error);
|
|
220
|
+
expect(err.cause).toBeInstanceOf(Error);
|
|
221
|
+
expect(err.cause.message).toBe('disk gone');
|
|
222
|
+
});
|
|
223
|
+
it('throws directly on a behavioral candidate handed to compileCandidate via the stage too', async () => {
|
|
224
|
+
// runCompileStage filters behavioral out, but compileCandidate is the FM(c) backstop.
|
|
225
|
+
expect(() => compileCandidate(candidateRule(9, REGEX_DSL, 'behavioral'), { now: NOW })).toThrow();
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
// ── Determinism + provenance handoff ──────────────────────────────────────────
|
|
229
|
+
describe('runCompileStage — determinism & handoff', () => {
|
|
230
|
+
it('is deterministic: identical inputs + fixed now/deps → identical output', async () => {
|
|
231
|
+
const files = { 'src/b.ts': 'forbiddenCall(y)', 'src/a.ts': 'forbiddenCall()' };
|
|
232
|
+
const a = await runCompileStage(single(REGEX_DSL), compileDeps(files));
|
|
233
|
+
const b = await runCompileStage(single(REGEX_DSL), compileDeps(files));
|
|
234
|
+
expect(JSON.stringify(a)).toBe(JSON.stringify(b));
|
|
235
|
+
});
|
|
236
|
+
it('carries provenance forward un-projected onto the CompiledCandidate', async () => {
|
|
237
|
+
const r = await runCompileStage(single(REGEX_DSL), compileDeps({ 'src/a.ts': 'forbiddenCall()' }));
|
|
238
|
+
const cc = r.compiled[0];
|
|
239
|
+
expect(cc?.provenance).toEqual({ mergedPr: 1, reviewThread: 'rt-1', commitSha: sha(1) });
|
|
240
|
+
expect(cc?.rule.legitimacy).toBeUndefined(); // slice-5 stamps it
|
|
241
|
+
});
|
|
242
|
+
it('never calls the frozen LessonInput actuator (compileLesson/buildCompiledRule/buildManualRule)', async () => {
|
|
243
|
+
await runCompileStage(single(REGEX_DSL), compileDeps({ 'src/a.ts': 'forbiddenCall()' }));
|
|
244
|
+
expect(vi.mocked(frozenActuator.compileLesson)).not.toHaveBeenCalled();
|
|
245
|
+
expect(vi.mocked(frozenActuator.buildCompiledRule)).not.toHaveBeenCalled();
|
|
246
|
+
expect(vi.mocked(frozenActuator.buildManualRule)).not.toHaveBeenCalled();
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
// ── End-to-end harness lock (real classify → compile → §8 harness green) ──────
|
|
250
|
+
const asStructural = {
|
|
251
|
+
disposition: 'structural',
|
|
252
|
+
dispositionSource: 'classified',
|
|
253
|
+
};
|
|
254
|
+
const structuralClassifier = { classify: () => Promise.resolve(asStructural) };
|
|
255
|
+
function draft(pr, dslSource) {
|
|
256
|
+
return { provenance: { mergedPr: pr, reviewThread: `rt-${pr}`, commitSha: sha(pr) }, dslSource };
|
|
257
|
+
}
|
|
258
|
+
function extractResultOf(drafts) {
|
|
259
|
+
const prs = [...new Set(drafts.map((d) => d.provenance.mergedPr))].sort((a, b) => a - b);
|
|
260
|
+
return {
|
|
261
|
+
drafts,
|
|
262
|
+
dropLedger: { entries: [] },
|
|
263
|
+
apiUsageLedger: {
|
|
264
|
+
entries: prs.map((pr) => ({
|
|
265
|
+
targetPr: pr,
|
|
266
|
+
slice: 'train',
|
|
267
|
+
fetchKind: 'review-thread',
|
|
268
|
+
})),
|
|
269
|
+
heldOutFetchCount: 0,
|
|
270
|
+
},
|
|
271
|
+
seedBlindness: { seedClassesProvided: false },
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
function splitLedgerFixture() {
|
|
275
|
+
return {
|
|
276
|
+
split: {
|
|
277
|
+
asOfCommit: sha(100),
|
|
278
|
+
trainPrs: [1, 2],
|
|
279
|
+
heldOutPrs: [3, 4],
|
|
280
|
+
excludedPrs: [],
|
|
281
|
+
positiveControlPrs: [3],
|
|
282
|
+
negativeControlPrs: [4],
|
|
283
|
+
splitRule: { predicate: 'code-touching non-bot', cutIndex: 2 },
|
|
284
|
+
},
|
|
285
|
+
corpus: [1, 2, 3, 4],
|
|
286
|
+
corpusMergeCommits: [1, 2, 3, 4].map((pr) => ({ pr, mergeCommit: sha(pr) })),
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
describe('runCompileStage — end-to-end §8 harness lock', () => {
|
|
290
|
+
it('real classify → compile output passes runFalsificationHarness green', async () => {
|
|
291
|
+
const extract = extractResultOf([draft(1, REGEX_DSL), draft(2, REGEX_DSL)]);
|
|
292
|
+
const split = splitLedgerFixture();
|
|
293
|
+
const classify = await runClassifyStage(extract, split, { classifier: structuralClassifier });
|
|
294
|
+
const compileRes = await runCompileStage(classify, compileDeps({ 'src/a.ts': 'forbiddenCall()' }));
|
|
295
|
+
const ledgers = {
|
|
296
|
+
emission: classify.emissionLedger,
|
|
297
|
+
drop: extract.dropLedger,
|
|
298
|
+
classifier: compileRes.classifierLedger, // the COMPILE-UPDATED ledger
|
|
299
|
+
split,
|
|
300
|
+
apiUsage: extract.apiUsageLedger,
|
|
301
|
+
};
|
|
302
|
+
const result = runFalsificationHarness(ledgers);
|
|
303
|
+
expect(result.ok).toBe(true);
|
|
304
|
+
expect(result.violations).toEqual([]);
|
|
305
|
+
// both train PRs confirmed-active
|
|
306
|
+
expect(compileRes.compiled).toHaveLength(2);
|
|
307
|
+
expect(compileRes.classifierLedger.entries.every((e) => e.stage4Outcome === 'confirmed')).toBe(true);
|
|
308
|
+
});
|
|
309
|
+
it('a desynced stage4Confirmed vs stage4Outcome trips the consistency guard', async () => {
|
|
310
|
+
const extract = extractResultOf([draft(1, REGEX_DSL), draft(2, REGEX_DSL)]);
|
|
311
|
+
const split = splitLedgerFixture();
|
|
312
|
+
const classify = await runClassifyStage(extract, split, { classifier: structuralClassifier });
|
|
313
|
+
const compileRes = await runCompileStage(classify, compileDeps({ 'src/a.ts': 'forbiddenCall()' }));
|
|
314
|
+
// Forge a desync: a confirmed outcome whose stage4Confirmed is flipped to false.
|
|
315
|
+
compileRes.classifierLedger.entries[0].stage4Confirmed = false;
|
|
316
|
+
const ledgers = {
|
|
317
|
+
emission: classify.emissionLedger,
|
|
318
|
+
drop: extract.dropLedger,
|
|
319
|
+
classifier: compileRes.classifierLedger,
|
|
320
|
+
split,
|
|
321
|
+
apiUsage: extract.apiUsageLedger,
|
|
322
|
+
};
|
|
323
|
+
const clauses = runFalsificationHarness(ledgers).violations.map((v) => v.clause);
|
|
324
|
+
expect(clauses).toContain('stage4-consistency');
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
//# sourceMappingURL=compile.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.test.js","sourceRoot":"","sources":["../../src/spine/compile.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { type ProvenanceRecord } from '../compiler-schema.js';
|
|
2
|
+
import type { ApiUsageLedger, DropLedger } from './ledgers.js';
|
|
3
|
+
import type { SplitArtifact } from './split.js';
|
|
4
|
+
/** A single parsed review-thread comment (provider-neutral; mirrors the CLI `groupIntoThreads` shape). */
|
|
5
|
+
export interface ReviewThreadComment {
|
|
6
|
+
author: string;
|
|
7
|
+
body: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* A single review thread on a file path.
|
|
11
|
+
*
|
|
12
|
+
* `isResolved` / `isOutdated` (slice 5a, mmnto-ai/totem#2201) are the per-thread
|
|
13
|
+
* resolution signal the live `ReviewThreadSource` adapter SURFACES from the
|
|
14
|
+
* GitHub `reviewThreads` payload — it does NOT filter on them. CRITICAL contract
|
|
15
|
+
* (the contract-owner ruling): the adapter fetches resolved/outdated threads WITH
|
|
16
|
+
* their flags and hands them to core; CORE decides eligibility + drop-ledgers (so
|
|
17
|
+
* every resolution rejection is auditable, §8 "every rejection ledgered"). A
|
|
18
|
+
* server-side / client-side `isResolved:false` pre-filter is FORBIDDEN — it would
|
|
19
|
+
* make the rejection unledgered (a silenced §6/FM violation).
|
|
20
|
+
*/
|
|
21
|
+
export interface ReviewThread {
|
|
22
|
+
path: string;
|
|
23
|
+
comments: ReviewThreadComment[];
|
|
24
|
+
/** GitHub `reviewThreads.isResolved` — the author marked this thread resolved. */
|
|
25
|
+
isResolved: boolean;
|
|
26
|
+
/** GitHub `reviewThreads.isOutdated` — the thread's diff hunk no longer matches HEAD. */
|
|
27
|
+
isOutdated: boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The CONTENT side of a train PR, returned by the injected `ReviewThreadSource`.
|
|
31
|
+
* Content-only (ADR-111 §6): it never influences corpus membership / the split /
|
|
32
|
+
* control selection — the offline `selectionRule` is the sole membership oracle.
|
|
33
|
+
*/
|
|
34
|
+
export interface ReviewThreadContent {
|
|
35
|
+
pr: number;
|
|
36
|
+
/** Lowercase 40-hex merge-commit SHA (lc is squash-merge) — becomes the candidate's `provenance.commitSha`. */
|
|
37
|
+
mergeCommitSha: string;
|
|
38
|
+
threads: ReviewThread[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The fetch outcome. §6 BINDING: distinguish "never fetched" (`unreachable`)
|
|
42
|
+
* from "fetched but unusable" (`unparseable`) — they route to different drop
|
|
43
|
+
* reason codes, so the §8 done-criterion can tell a broken fetch from thin
|
|
44
|
+
* content. A discriminated result keeps that distinction at the source layer
|
|
45
|
+
* rather than collapsing both into a `null`.
|
|
46
|
+
*/
|
|
47
|
+
export type FetchResult = {
|
|
48
|
+
kind: 'ok';
|
|
49
|
+
content: ReviewThreadContent;
|
|
50
|
+
} | {
|
|
51
|
+
kind: 'unreachable';
|
|
52
|
+
detail?: string;
|
|
53
|
+
} | {
|
|
54
|
+
kind: 'unparseable';
|
|
55
|
+
detail?: string;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* A transient, stage-internal Extract output — NOT the §3 `CandidateRuleRecord`,
|
|
59
|
+
* NOT persisted, NOT a ledger row. Slice-3's classifier maps `DraftCandidate →
|
|
60
|
+
* CandidateRuleRecord` by adding the structural/behavioral disposition + its
|
|
61
|
+
* classifier-ledger reference. The miner's SOLE OUTPUT envelope remains the
|
|
62
|
+
* `CandidateRuleRecord`, minted in slice 3 — this is just the funnel value that
|
|
63
|
+
* flows Extract → Classify.
|
|
64
|
+
*/
|
|
65
|
+
export interface DraftCandidate {
|
|
66
|
+
provenance: ProvenanceRecord;
|
|
67
|
+
/**
|
|
68
|
+
* The LLM-drafted lesson-markdown body (ADR-103 compiler input). `unverified`
|
|
69
|
+
* and Stage-4-gated downstream — lesson-markdown is the syntax, not a
|
|
70
|
+
* Pipeline-1 trust class. Guaranteed non-empty and carrying a usable
|
|
71
|
+
* `**Pattern:**` / yaml rule by the syntactic preflight.
|
|
72
|
+
*/
|
|
73
|
+
dslSource: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Injected review-thread fetch port (ADR-111 §6 content-only). Core-defined,
|
|
77
|
+
* CLI-implemented — keeps core network-free. ASYNC: the CLI impl wraps the
|
|
78
|
+
* GitHub API (network IO). MUST be called for train PRs only; the orchestrator
|
|
79
|
+
* guarantees that by iterating the train slice.
|
|
80
|
+
*/
|
|
81
|
+
export interface ReviewThreadSource {
|
|
82
|
+
fetch(pr: number): Promise<FetchResult>;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Injected draft-DSL extractor port. ASYNC: the CLI impl wraps the LLM call
|
|
86
|
+
* (network IO). List-shaped (fold 1): one thread can carry multiple structural
|
|
87
|
+
* invariants, so it returns ZERO-or-more draft bodies. The LLM lives behind this
|
|
88
|
+
* at the CLI layer (draft-only, Tenet-15); a deterministic fixture impl drives
|
|
89
|
+
* tests. The miner is BLIND to seed classes (§7 / FM f): the port is never
|
|
90
|
+
* handed one.
|
|
91
|
+
*
|
|
92
|
+
* Error contract: returns `[]` when it cannot draft from the thread — INCLUDING
|
|
93
|
+
* on its own internal/transient failure (the CLI adapter catches its LLM/network
|
|
94
|
+
* errors and surfaces `[]`). It MUST NOT throw for a per-PR content failure: an
|
|
95
|
+
* empty list is a loud drop below (FM-i-creditable), whereas a throw would abort
|
|
96
|
+
* the whole mining run. Keeping per-PR error handling in the adapter keeps the
|
|
97
|
+
* core orchestrator Tenet-4-clean (no swallowing catch); a contract-violating
|
|
98
|
+
* throw therefore propagates loudly rather than being silently absorbed.
|
|
99
|
+
*/
|
|
100
|
+
export interface DraftExtractor {
|
|
101
|
+
draft(content: ReviewThreadContent): Promise<string[]>;
|
|
102
|
+
}
|
|
103
|
+
/** Dependencies for a single Extract-stage run. */
|
|
104
|
+
export interface ExtractStageDeps {
|
|
105
|
+
source: ReviewThreadSource;
|
|
106
|
+
extractor: DraftExtractor;
|
|
107
|
+
/**
|
|
108
|
+
* §7 seed-blindness fact, established in-run: `true` iff a seed class WAS
|
|
109
|
+
* supplied to the extractor (which would falsify FM f). Carried here; slice 3
|
|
110
|
+
* SERIALIZES it into the §8 emission ledger's `extractionInputsAttestation`
|
|
111
|
+
* (single persisted home, Tenet 20). Slice 2 establishes the fact; it does not
|
|
112
|
+
* grow a second store for it.
|
|
113
|
+
*/
|
|
114
|
+
seedClassesProvided: boolean;
|
|
115
|
+
}
|
|
116
|
+
/** The Extract stage's output: transient drafts + the two ledgers Extract owns. */
|
|
117
|
+
export interface ExtractStageResult {
|
|
118
|
+
/** Transient draft candidates carried forward to slice-3 Classify. */
|
|
119
|
+
drafts: DraftCandidate[];
|
|
120
|
+
/** Drop ledger — the sole disposition for any content/provenance/draft failure (§6). */
|
|
121
|
+
dropLedger: DropLedger;
|
|
122
|
+
/** API-usage ledger — every train-slice fetch; `heldOutFetchCount` MUST be 0 (FM h). */
|
|
123
|
+
apiUsageLedger: ApiUsageLedger;
|
|
124
|
+
/** In-run seed-blindness fact; slice 3 persists it into the emission ledger. */
|
|
125
|
+
seedBlindness: {
|
|
126
|
+
seedClassesProvided: boolean;
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Run the deterministic Stage-1 Extract over a frozen split. Deterministic given
|
|
131
|
+
* its deps: identical `split` + deps → identical drafts, drops, and ledgers (the
|
|
132
|
+
* train slice is awaited sequentially, so ordering is stable). The
|
|
133
|
+
* live LLM and GitHub IO are injected ports, so this orchestration is fully
|
|
134
|
+
* CI-locked with a fixture extractor + a strict-spy fetch source.
|
|
135
|
+
*
|
|
136
|
+
* Per train PR (and ONLY train PRs): log the fetch → fetch → on unreachable /
|
|
137
|
+
* unparseable-at-source, loud-drop → resolution-eligibility gate (slice 5a: drop
|
|
138
|
+
* `resolved-rejected` when the resolution gate empties an otherwise-human thread,
|
|
139
|
+
* else `truncated` when thin to begin with) → completeness-check (≥1 human
|
|
140
|
+
* comment on the survivors) → build provenance → draft zero-or-more bodies from
|
|
141
|
+
* the SURVIVING threads only → preflight each → carry a `DraftCandidate` or
|
|
142
|
+
* loud-drop. Every train PR ends with at least one draft or one drop (FM i,
|
|
143
|
+
* slice-2 half).
|
|
144
|
+
*/
|
|
145
|
+
export declare function runExtractStage(split: SplitArtifact, deps: ExtractStageDeps): Promise<ExtractStageResult>;
|
|
146
|
+
//# sourceMappingURL=extract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/spine/extract.ts"],"names":[],"mappings":"AAoCA,OAAO,EAAE,KAAK,gBAAgB,EAA0B,MAAM,uBAAuB,CAAC;AAGtF,OAAO,KAAK,EACV,cAAc,EAEd,UAAU,EAGX,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIhD,0GAA0G;AAC1G,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,kFAAkF;IAClF,UAAU,EAAE,OAAO,CAAC;IACpB,yFAAyF;IACzF,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,+GAA+G;IAC/G,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,mBAAmB,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAI7C;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,gBAAgB,CAAC;IAC7B;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAID;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CACzC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CACxD;AAED,mDAAmD;AACnD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,SAAS,EAAE,cAAc,CAAC;IAC1B;;;;;;OAMG;IACH,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED,mFAAmF;AACnF,MAAM,WAAW,kBAAkB;IACjC,sEAAsE;IACtE,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,wFAAwF;IACxF,UAAU,EAAE,UAAU,CAAC;IACvB,wFAAwF;IACxF,cAAc,EAAE,cAAc,CAAC;IAC/B,gFAAgF;IAChF,aAAa,EAAE;QAAE,mBAAmB,EAAE,OAAO,CAAA;KAAE,CAAC;CACjD;AAkFD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,kBAAkB,CAAC,CAmH7B"}
|