@mmnto/totem 1.70.0 → 1.71.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.
Files changed (46) hide show
  1. package/dist/ast-grep-query.d.ts +12 -0
  2. package/dist/ast-grep-query.d.ts.map +1 -1
  3. package/dist/ast-grep-query.js +4 -0
  4. package/dist/ast-grep-query.js.map +1 -1
  5. package/dist/ast-query.d.ts +12 -0
  6. package/dist/ast-query.d.ts.map +1 -1
  7. package/dist/ast-query.js +4 -0
  8. package/dist/ast-query.js.map +1 -1
  9. package/dist/index.d.ts +7 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +3 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/rule-engine.d.ts.map +1 -1
  14. package/dist/rule-engine.js +37 -6
  15. package/dist/rule-engine.js.map +1 -1
  16. package/dist/rule-engine.test.js +96 -0
  17. package/dist/rule-engine.test.js.map +1 -1
  18. package/dist/spine/legitimacy-projection.d.ts +61 -0
  19. package/dist/spine/legitimacy-projection.d.ts.map +1 -0
  20. package/dist/spine/legitimacy-projection.js +67 -0
  21. package/dist/spine/legitimacy-projection.js.map +1 -0
  22. package/dist/spine/legitimacy-projection.test.d.ts +2 -0
  23. package/dist/spine/legitimacy-projection.test.d.ts.map +1 -0
  24. package/dist/spine/legitimacy-projection.test.js +153 -0
  25. package/dist/spine/legitimacy-projection.test.js.map +1 -0
  26. package/dist/spine/windtunnel-firing.d.ts +154 -0
  27. package/dist/spine/windtunnel-firing.d.ts.map +1 -0
  28. package/dist/spine/windtunnel-firing.js +273 -0
  29. package/dist/spine/windtunnel-firing.js.map +1 -0
  30. package/dist/spine/windtunnel-firing.test.d.ts +2 -0
  31. package/dist/spine/windtunnel-firing.test.d.ts.map +1 -0
  32. package/dist/spine/windtunnel-firing.test.js +469 -0
  33. package/dist/spine/windtunnel-firing.test.js.map +1 -0
  34. package/dist/spine/windtunnel-lock.d.ts +9 -0
  35. package/dist/spine/windtunnel-lock.d.ts.map +1 -1
  36. package/dist/spine/windtunnel-lock.js +17 -0
  37. package/dist/spine/windtunnel-lock.js.map +1 -1
  38. package/dist/spine/windtunnel-lock.test.js +24 -0
  39. package/dist/spine/windtunnel-lock.test.js.map +1 -1
  40. package/dist/spine/windtunnel-scorer.d.ts +22 -0
  41. package/dist/spine/windtunnel-scorer.d.ts.map +1 -1
  42. package/dist/spine/windtunnel-scorer.js +10 -1
  43. package/dist/spine/windtunnel-scorer.js.map +1 -1
  44. package/dist/spine/windtunnel-scorer.test.js +32 -0
  45. package/dist/spine/windtunnel-scorer.test.js.map +1 -1
  46. package/package.json +1 -1
@@ -0,0 +1,469 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { makeRuleEngineCtx } from '../test-utils.js';
3
+ import { ArchivedRuleInScopeError, assertNoArchivedRules, assertUniqueFiringLabels, buildFirings, computePerRuleControlResults, FiringLabelCollisionError, } from './windtunnel-firing.js';
4
+ import { firingLabelId } from './windtunnel-lock.js';
5
+ import { scoreWindtunnel } from './windtunnel-scorer.js';
6
+ // ─── Fixtures ────────────────────────────────────────
7
+ const FILE = 'src/app.ts';
8
+ /** A regex rule firing on the literal `debugger` token (code context). */
9
+ function debuggerRule(overrides = {}) {
10
+ return {
11
+ lessonHash: 'rule-debugger',
12
+ lessonHeading: 'No debugger',
13
+ pattern: 'debugger',
14
+ message: 'debugger statement',
15
+ engine: 'regex',
16
+ compiledAt: '2026-06-20T00:00:00.000Z',
17
+ ...overrides,
18
+ };
19
+ }
20
+ /** A regex rule firing on `eval(` (a second, distinct rule). */
21
+ function evalRule(overrides = {}) {
22
+ return {
23
+ lessonHash: 'rule-eval',
24
+ lessonHeading: 'No eval',
25
+ pattern: 'eval\\(',
26
+ message: 'eval call',
27
+ engine: 'regex',
28
+ compiledAt: '2026-06-20T00:00:00.000Z',
29
+ ...overrides,
30
+ };
31
+ }
32
+ /** Build a unified diff that ADDS the given lines to FILE starting at line 1. */
33
+ function diffAdding(lines, file = FILE) {
34
+ const body = lines.map((l) => `+${l}`).join('\n');
35
+ return [
36
+ `diff --git a/${file} b/${file}`,
37
+ `--- a/${file}`,
38
+ `+++ b/${file}`,
39
+ `@@ -0,0 +1,${lines.length} @@`,
40
+ body,
41
+ ].join('\n');
42
+ }
43
+ /** readStrategy returning a fixed post-image for any file (zero-LLM, no disk). */
44
+ function fixedReadStrategy(content) {
45
+ return async () => content;
46
+ }
47
+ // ─── Real-engine path (replaces runMockEngine) ───────
48
+ describe('buildFirings — real engine path', () => {
49
+ it('fires the regex rule on a real code line and maps it to a RuleFiring with a content-based labelId', async () => {
50
+ const post = ['function run() {', ' debugger;', '}'].join('\n'); // totem-ignore
51
+ const prDiffs = [
52
+ { pr: 100, diff: diffAdding([' debugger;']), controlKind: 'corpus' }, // totem-ignore
53
+ ];
54
+ const result = await buildFirings({
55
+ rules: [debuggerRule()],
56
+ prDiffs,
57
+ cwd: '/repo',
58
+ readStrategy: fixedReadStrategy(post),
59
+ ruleEngineCtx: makeRuleEngineCtx(),
60
+ });
61
+ expect(result.firings).toHaveLength(1);
62
+ const firing = result.firings[0];
63
+ expect(firing.ruleId).toBe('rule-debugger');
64
+ expect(firing.pr).toBe(100);
65
+ expect(firing.controlKind).toBe('corpus');
66
+ expect(firing.labelId).toBe(firingLabelId('rule-debugger', 100, FILE, firing.matchedLine));
67
+ });
68
+ it('suppresses an over-fire: a regex match inside a comment is NOT a firing (astContext parity, C1)', async () => {
69
+ // Line 2 is real code; line 3 is a comment. Both are added. The engine must
70
+ // fire only on the code line (the comment match is telemetry-only).
71
+ const post = [
72
+ 'function run() {',
73
+ ' debugger;', // 2 — code // totem-ignore
74
+ ' // debugger; left here — comment // totem-ignore', // 3 — comment
75
+ '}',
76
+ ].join('\n');
77
+ const prDiffs = [
78
+ {
79
+ pr: 101,
80
+ diff: diffAdding([
81
+ ' debugger;', // totem-ignore
82
+ ' // debugger; left here — comment // totem-ignore',
83
+ ]),
84
+ controlKind: 'corpus',
85
+ },
86
+ ];
87
+ const result = await buildFirings({
88
+ rules: [debuggerRule()],
89
+ prDiffs,
90
+ cwd: '/repo',
91
+ readStrategy: fixedReadStrategy(post),
92
+ ruleEngineCtx: makeRuleEngineCtx(),
93
+ });
94
+ // Only the code line fires.
95
+ expect(result.firings).toHaveLength(1);
96
+ expect(result.firings[0].matchedLine).toContain('debugger');
97
+ });
98
+ it('counts distinct touched files across all diffs (C2 real exposure)', async () => {
99
+ const post = 'const x = 1;\n';
100
+ const prDiffs = [
101
+ { pr: 1, diff: diffAdding(['const x = 1;'], 'src/a.ts'), controlKind: 'corpus' },
102
+ { pr: 2, diff: diffAdding(['const y = 2;'], 'src/b.ts'), controlKind: 'corpus' },
103
+ { pr: 3, diff: diffAdding(['const z = 3;'], 'src/a.ts'), controlKind: 'corpus' }, // dup file
104
+ ];
105
+ const result = await buildFirings({
106
+ rules: [debuggerRule()],
107
+ prDiffs,
108
+ cwd: '/repo',
109
+ readStrategy: fixedReadStrategy(post),
110
+ ruleEngineCtx: makeRuleEngineCtx(),
111
+ });
112
+ expect(result.filesTouchedInWindow).toBe(2); // a.ts + b.ts, not 3
113
+ });
114
+ it('derives positiveControlTargets from positive-control diffs', async () => {
115
+ const post = [' debugger;'].join('\n'); // totem-ignore
116
+ const prDiffs = [
117
+ {
118
+ pr: 50,
119
+ diff: diffAdding([' debugger;']), // totem-ignore
120
+ controlKind: 'positive',
121
+ targetRuleId: 'rule-debugger',
122
+ },
123
+ ];
124
+ const result = await buildFirings({
125
+ rules: [debuggerRule()],
126
+ prDiffs,
127
+ cwd: '/repo',
128
+ readStrategy: fixedReadStrategy(post),
129
+ ruleEngineCtx: makeRuleEngineCtx(),
130
+ });
131
+ expect(result.positiveControlTargets).toEqual([{ pr: 50, targetRuleId: 'rule-debugger' }]);
132
+ expect(result.firings[0].controlKind).toBe('positive');
133
+ expect(result.firings[0].targetRuleId).toBe('rule-debugger');
134
+ });
135
+ it('fold-H: a firing on a NEGATIVE control passes through as controlKind:negative (not dropped)', async () => {
136
+ const post = [' debugger;'].join('\n'); // totem-ignore
137
+ const prDiffs = [
138
+ { pr: 99, diff: diffAdding([' debugger;']), controlKind: 'negative' }, // totem-ignore
139
+ ];
140
+ const result = await buildFirings({
141
+ rules: [debuggerRule()],
142
+ prDiffs,
143
+ cwd: '/repo',
144
+ readStrategy: fixedReadStrategy(post),
145
+ ruleEngineCtx: makeRuleEngineCtx(),
146
+ });
147
+ expect(result.firings).toHaveLength(1);
148
+ expect(result.firings[0].controlKind).toBe('negative');
149
+ });
150
+ it('emits no firings when no rule matches the diff', async () => {
151
+ const post = 'const safe = 1;\n';
152
+ const prDiffs = [
153
+ { pr: 1, diff: diffAdding(['const safe = 1;']), controlKind: 'corpus' },
154
+ ];
155
+ const result = await buildFirings({
156
+ rules: [debuggerRule()],
157
+ prDiffs,
158
+ cwd: '/repo',
159
+ readStrategy: fixedReadStrategy(post),
160
+ ruleEngineCtx: makeRuleEngineCtx(),
161
+ });
162
+ expect(result.firings).toHaveLength(0);
163
+ });
164
+ });
165
+ // ─── fold-F: archived-excluded loud assert ───────────
166
+ describe('fold-F — archived rule in scored set throws (Tenet 4)', () => {
167
+ it('assertNoArchivedRules throws naming the archived rule', () => {
168
+ const rules = [debuggerRule(), evalRule({ status: 'archived' })];
169
+ expect(() => assertNoArchivedRules(rules)).toThrow(ArchivedRuleInScopeError);
170
+ expect(() => assertNoArchivedRules(rules)).toThrow(/rule-eval/);
171
+ });
172
+ it('assertNoArchivedRules passes on active-only rules', () => {
173
+ expect(() => assertNoArchivedRules([debuggerRule({ status: 'active' }), evalRule()])).not.toThrow();
174
+ });
175
+ it('buildFirings throws (and never invokes the engine) when an archived rule is present', async () => {
176
+ const post = [' debugger;'].join('\n'); // totem-ignore
177
+ const prDiffs = [
178
+ { pr: 1, diff: diffAdding([' debugger;']), controlKind: 'corpus' }, // totem-ignore
179
+ ];
180
+ await expect(buildFirings({
181
+ rules: [debuggerRule(), evalRule({ status: 'archived' })],
182
+ prDiffs,
183
+ cwd: '/repo',
184
+ readStrategy: fixedReadStrategy(post),
185
+ ruleEngineCtx: makeRuleEngineCtx(),
186
+ })).rejects.toThrow(ArchivedRuleInScopeError);
187
+ });
188
+ it('zero archived refs reach the firings (the engine ran only on active rules)', async () => {
189
+ const post = [' debugger;', ' eval(x);'].join('\n'); // totem-ignore
190
+ const prDiffs = [
191
+ {
192
+ pr: 1,
193
+ diff: diffAdding([' debugger;', ' eval(x);']), // totem-ignore
194
+ controlKind: 'corpus',
195
+ },
196
+ ];
197
+ const result = await buildFirings({
198
+ rules: [debuggerRule(), evalRule()], // both active
199
+ prDiffs,
200
+ cwd: '/repo',
201
+ readStrategy: fixedReadStrategy(post),
202
+ ruleEngineCtx: makeRuleEngineCtx(),
203
+ });
204
+ const firedRuleIds = new Set(result.firings.map((f) => f.ruleId));
205
+ expect(firedRuleIds.has('rule-debugger')).toBe(true);
206
+ expect(firedRuleIds.has('rule-eval')).toBe(true);
207
+ });
208
+ it('fold-D: collapses same-labelId matches to ONE firing, retaining raw matches as evidence', async () => {
209
+ // Two identical added lines normalize to the same matchedLine ⇒ the same
210
+ // (ruleId, pr, filePath, normalizedLine) ⇒ the same labelId. Pre-fold-D this
211
+ // tripped the A1 throw; the strategy ruling (2026-06-20) DEDUPs it to one
212
+ // logical firing, retaining both raw matches as evidence for the report.
213
+ const post = [' debugger;', ' debugger;'].join('\n'); // totem-ignore
214
+ const prDiffs = [
215
+ { pr: 200, diff: diffAdding([' debugger;', ' debugger;']), controlKind: 'corpus' }, // totem-ignore
216
+ ];
217
+ const result = await buildFirings({
218
+ rules: [debuggerRule()],
219
+ prDiffs,
220
+ cwd: '/repo',
221
+ readStrategy: fixedReadStrategy(post),
222
+ ruleEngineCtx: makeRuleEngineCtx(),
223
+ });
224
+ // Collapsed to ONE logical firing...
225
+ expect(result.firings).toHaveLength(1);
226
+ // ...whose evidence retains BOTH raw matches.
227
+ expect(result.firings[0].evidence).toHaveLength(2);
228
+ expect(result.firings[0].evidence.every((e) => e.rawLine.includes('debugger'))).toBe(true);
229
+ // The deduped output satisfies the (now post-dedup) A1 invariant.
230
+ expect(() => assertUniqueFiringLabels(result.firings)).not.toThrow();
231
+ });
232
+ });
233
+ // ─── A1 (fold-D): hard-gate-unique FLOOR ─────────────
234
+ describe('A1 (fold-D) — assertUniqueFiringLabels hard-gate', () => {
235
+ function firing(labelId, ruleId = 'r', pr = 1) {
236
+ return { ruleId, pr, filePath: FILE, matchedLine: 'x', controlKind: 'corpus', labelId };
237
+ }
238
+ it('passes when all labelIds are unique', () => {
239
+ expect(() => assertUniqueFiringLabels([firing('a'), firing('b'), firing('c')])).not.toThrow();
240
+ });
241
+ it('throws a FiringLabelCollisionError when two firings share a labelId', () => {
242
+ expect(() => assertUniqueFiringLabels([firing('dup'), firing('dup')])).toThrow(FiringLabelCollisionError);
243
+ });
244
+ it('surfaces the colliding labelId + every evidence ref', () => {
245
+ const dup = firingLabelId('r', 1, FILE, 'line');
246
+ const a = {
247
+ ruleId: 'r',
248
+ pr: 1,
249
+ filePath: FILE,
250
+ matchedLine: 'line',
251
+ controlKind: 'corpus',
252
+ labelId: dup,
253
+ };
254
+ const b = { ...a };
255
+ let caught;
256
+ try {
257
+ assertUniqueFiringLabels([a, b]);
258
+ }
259
+ catch (err) {
260
+ caught = err;
261
+ }
262
+ expect(caught).toBeInstanceOf(FiringLabelCollisionError);
263
+ expect(caught.collisions).toHaveLength(1);
264
+ expect(caught.collisions[0].labelId).toBe(dup);
265
+ expect(caught.collisions[0].evidenceRefs).toHaveLength(2);
266
+ expect(caught.collisions[0].evidenceRefs[0].ruleId).toBe('r');
267
+ });
268
+ });
269
+ // ─── C1: per-rule control results (NOT global nonVacuity) ─
270
+ describe('C1 — computePerRuleControlResults (per-rule, survivor-only)', () => {
271
+ function f(ruleId, controlKind, pr, matched = 'x') {
272
+ return {
273
+ ruleId,
274
+ pr,
275
+ filePath: FILE,
276
+ matchedLine: matched,
277
+ controlKind,
278
+ labelId: firingLabelId(ruleId, pr, FILE, matched),
279
+ };
280
+ }
281
+ it('positiveControl is true ONLY for the rule that fired its declared target (never global)', () => {
282
+ // rule-a fired its positive target on pr 10; rule-b is a survivor that never
283
+ // exercised a positive control. The global nonVacuity (all targets fired)
284
+ // would be true — but rule-b's positiveControl must NOT inherit that.
285
+ const firings = [f('rule-a', 'positive', 10), f('rule-b', 'corpus', 1)];
286
+ const result = computePerRuleControlResults({
287
+ firings,
288
+ mintedRuleIds: ['rule-a', 'rule-b'],
289
+ positiveControlTargets: [{ pr: 10, targetRuleId: 'rule-a' }],
290
+ });
291
+ expect(result.get('rule-a').positiveControl).toBe(true);
292
+ expect(result.get('rule-b').positiveControl).toBe(false);
293
+ });
294
+ it('negativeControl is false (and the rule is excluded as culled) when it fires on a negative control', () => {
295
+ const firings = [f('rule-a', 'negative', 99)];
296
+ const result = computePerRuleControlResults({
297
+ firings,
298
+ mintedRuleIds: ['rule-a', 'rule-b'],
299
+ positiveControlTargets: [],
300
+ });
301
+ // rule-a fired on a negative control → culled → not a survivor → absent.
302
+ expect(result.has('rule-a')).toBe(false);
303
+ // rule-b never fired on a negative control → clean (negativeControl true).
304
+ expect(result.get('rule-b').negativeControl).toBe(true);
305
+ });
306
+ it('a clean survivor carries negativeControl:true with no positive evidence', () => {
307
+ const result = computePerRuleControlResults({
308
+ firings: [],
309
+ mintedRuleIds: ['rule-a'],
310
+ positiveControlTargets: [],
311
+ });
312
+ expect(result.get('rule-a')).toEqual({
313
+ positiveControl: false,
314
+ negativeControl: true,
315
+ evidenceRefs: [],
316
+ });
317
+ });
318
+ it('records evidenceRefs (the firingLabelIds) for both control legs', () => {
319
+ const posFiring = f('rule-a', 'positive', 10);
320
+ const result = computePerRuleControlResults({
321
+ firings: [posFiring],
322
+ mintedRuleIds: ['rule-a'],
323
+ positiveControlTargets: [{ pr: 10, targetRuleId: 'rule-a' }],
324
+ });
325
+ expect(result.get('rule-a').evidenceRefs).toContain(posFiring.labelId);
326
+ });
327
+ });
328
+ // ─── fold-H: OQ4 real-firing integration matrix ──────
329
+ //
330
+ // End-to-end through the REAL engine (buildFirings) → scoreWindtunnel. Zero-LLM,
331
+ // deterministic: fixture rules + fixture diffs + injected post-image readStrategy.
332
+ describe('fold-H — OQ4 real-firing matrix (buildFirings → scoreWindtunnel)', () => {
333
+ /** Run the deterministic engine, gate uniqueness (A1), then score. */
334
+ async function fireAndScore(opts) {
335
+ const built = await buildFirings({
336
+ rules: opts.rules,
337
+ prDiffs: opts.prDiffs,
338
+ cwd: '/repo',
339
+ readStrategy: fixedReadStrategy(opts.post),
340
+ ruleEngineCtx: makeRuleEngineCtx(),
341
+ });
342
+ assertUniqueFiringLabels(built.firings); // A1 pre-score gate
343
+ const mintedRuleIds = opts.mintedRuleIds ?? opts.rules.map((r) => r.lessonHash);
344
+ return scoreWindtunnel({
345
+ firings: built.firings,
346
+ groundTruth: opts.groundTruth ?? new Map(),
347
+ positiveControlTargets: built.positiveControlTargets,
348
+ mintedRuleIds,
349
+ cullRateThreshold: 0.9,
350
+ exposureFloors: opts.exposureFloors ?? {
351
+ activeRulesEvaluated: 0,
352
+ filesTouchedInWindow: 0,
353
+ positiveControlsExercised: 0,
354
+ },
355
+ actualExposure: {
356
+ activeRulesEvaluated: mintedRuleIds.length,
357
+ filesTouchedInWindow: built.filesTouchedInWindow,
358
+ positiveControlsExercised: built.positiveControlTargets.length,
359
+ },
360
+ });
361
+ }
362
+ it('confirmed-FP firing (sub-floor precision) ⟹ FAIL', async () => {
363
+ const post = [' debugger;'].join('\n'); // totem-ignore
364
+ const prDiffs = [
365
+ { pr: 1, diff: diffAdding([' debugger;']), controlKind: 'corpus' }, // totem-ignore
366
+ ];
367
+ const built = await buildFirings({
368
+ rules: [debuggerRule()],
369
+ prDiffs,
370
+ cwd: '/repo',
371
+ readStrategy: fixedReadStrategy(post),
372
+ ruleEngineCtx: makeRuleEngineCtx(),
373
+ });
374
+ const fpLabel = built.firings[0].labelId;
375
+ const verdict = await fireAndScore({
376
+ rules: [debuggerRule()],
377
+ prDiffs,
378
+ post,
379
+ groundTruth: new Map([[fpLabel, 'FP']]),
380
+ });
381
+ expect(verdict.verdict).toBe('FAIL');
382
+ expect(verdict.precision).toBeLessThan(1);
383
+ });
384
+ it('vacuous positive control (target never fires) ⟹ FAIL / null precision', async () => {
385
+ // The positive control declares rule-eval must fire, but the post-image has
386
+ // no eval( — so the target never fires (vacuous).
387
+ const post = ['const safe = 1;'].join('\n');
388
+ const prDiffs = [
389
+ {
390
+ pr: 10,
391
+ diff: diffAdding(['const safe = 1;']),
392
+ controlKind: 'positive',
393
+ targetRuleId: 'rule-eval',
394
+ },
395
+ ];
396
+ const verdict = await fireAndScore({ rules: [evalRule()], prDiffs, post });
397
+ expect(verdict.verdict).toBe('FAIL');
398
+ expect(verdict.nonVacuity).toBe(false);
399
+ expect(verdict.precision).toBeNull();
400
+ });
401
+ it('unlabeled firing ⟹ HONEST-NEGATIVE (needsAdjudication)', async () => {
402
+ const post = [' debugger;'].join('\n'); // totem-ignore
403
+ const prDiffs = [
404
+ { pr: 1, diff: diffAdding([' debugger;']), controlKind: 'corpus' }, // totem-ignore
405
+ ];
406
+ const verdict = await fireAndScore({
407
+ rules: [debuggerRule()],
408
+ prDiffs,
409
+ post,
410
+ groundTruth: new Map(), // unlabeled
411
+ });
412
+ expect(verdict.verdict).toBe('HONEST-NEGATIVE');
413
+ expect(verdict.needsAdjudication).toHaveLength(1);
414
+ });
415
+ it('all-TP firings with exposure met ⟹ PASS', async () => {
416
+ const post = [' debugger;'].join('\n'); // totem-ignore
417
+ const prDiffs = [
418
+ { pr: 1, diff: diffAdding([' debugger;']), controlKind: 'corpus' }, // totem-ignore
419
+ ];
420
+ const built = await buildFirings({
421
+ rules: [debuggerRule()],
422
+ prDiffs,
423
+ cwd: '/repo',
424
+ readStrategy: fixedReadStrategy(post),
425
+ ruleEngineCtx: makeRuleEngineCtx(),
426
+ });
427
+ const tpLabel = built.firings[0].labelId;
428
+ const verdict = await fireAndScore({
429
+ rules: [debuggerRule()],
430
+ prDiffs,
431
+ post,
432
+ groundTruth: new Map([[tpLabel, 'TP']]),
433
+ });
434
+ expect(verdict.verdict).toBe('PASS');
435
+ expect(verdict.precision).toBe(1.0);
436
+ });
437
+ it('C2: real filesTouched below the floor ⟹ HONEST-NEGATIVE even when the other legs pass', async () => {
438
+ // One TP firing on a single file. The other two legs pass (activeRules ok,
439
+ // no positive controls required) but the filesTouchedInWindow floor is 5 and
440
+ // only 1 file is touched → the third leg demotes to HONEST-NEGATIVE.
441
+ const post = [' debugger;'].join('\n'); // totem-ignore
442
+ const prDiffs = [
443
+ { pr: 1, diff: diffAdding([' debugger;']), controlKind: 'corpus' }, // totem-ignore
444
+ ];
445
+ const built = await buildFirings({
446
+ rules: [debuggerRule()],
447
+ prDiffs,
448
+ cwd: '/repo',
449
+ readStrategy: fixedReadStrategy(post),
450
+ ruleEngineCtx: makeRuleEngineCtx(),
451
+ });
452
+ const tpLabel = built.firings[0].labelId;
453
+ const verdict = await fireAndScore({
454
+ rules: [debuggerRule()],
455
+ prDiffs,
456
+ post,
457
+ groundTruth: new Map([[tpLabel, 'TP']]),
458
+ exposureFloors: {
459
+ activeRulesEvaluated: 0,
460
+ filesTouchedInWindow: 5, // floor exceeds the 1 file actually touched
461
+ positiveControlsExercised: 0,
462
+ },
463
+ });
464
+ expect(built.filesTouchedInWindow).toBe(1);
465
+ expect(verdict.verdict).toBe('HONEST-NEGATIVE');
466
+ expect(verdict.precision).toBeNull();
467
+ });
468
+ });
469
+ //# sourceMappingURL=windtunnel-firing.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"windtunnel-firing.test.js","sourceRoot":"","sources":["../../src/spine/windtunnel-firing.test.ts"],"names":[],"mappings":"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"}
@@ -175,12 +175,15 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
175
175
  integrity: z.ZodObject<{
176
176
  mechanism: z.ZodString;
177
177
  fixtureSha: z.ZodString;
178
+ llmReplaySha: z.ZodOptional<z.ZodString>;
178
179
  }, "strip", z.ZodTypeAny, {
179
180
  mechanism: string;
180
181
  fixtureSha: string;
182
+ llmReplaySha?: string | undefined;
181
183
  }, {
182
184
  mechanism: string;
183
185
  fixtureSha: string;
186
+ llmReplaySha?: string | undefined;
184
187
  }>;
185
188
  }, "strip", z.ZodTypeAny, {
186
189
  positiveRef: string;
@@ -188,6 +191,7 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
188
191
  integrity: {
189
192
  mechanism: string;
190
193
  fixtureSha: string;
194
+ llmReplaySha?: string | undefined;
191
195
  };
192
196
  }, {
193
197
  positiveRef: string;
@@ -195,6 +199,7 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
195
199
  integrity: {
196
200
  mechanism: string;
197
201
  fixtureSha: string;
202
+ llmReplaySha?: string | undefined;
198
203
  };
199
204
  }>;
200
205
  cullRateThreshold: z.ZodNumber;
@@ -285,6 +290,7 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
285
290
  integrity: {
286
291
  mechanism: string;
287
292
  fixtureSha: string;
293
+ llmReplaySha?: string | undefined;
288
294
  };
289
295
  };
290
296
  cullRateThreshold: number;
@@ -347,6 +353,7 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
347
353
  integrity: {
348
354
  mechanism: string;
349
355
  fixtureSha: string;
356
+ llmReplaySha?: string | undefined;
350
357
  };
351
358
  };
352
359
  cullRateThreshold: number;
@@ -409,6 +416,7 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
409
416
  integrity: {
410
417
  mechanism: string;
411
418
  fixtureSha: string;
419
+ llmReplaySha?: string | undefined;
412
420
  };
413
421
  };
414
422
  cullRateThreshold: number;
@@ -471,6 +479,7 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
471
479
  integrity: {
472
480
  mechanism: string;
473
481
  fixtureSha: string;
482
+ llmReplaySha?: string | undefined;
474
483
  };
475
484
  };
476
485
  cullRateThreshold: number;
@@ -1 +1 @@
1
- {"version":3,"file":"windtunnel-lock.d.ts","sourceRoot":"","sources":["../../src/spine/windtunnel-lock.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAmBxB,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6G7B,CAAC;AAEL,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAIlE;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,EAChB,yBAAyB,EAAE,MAAM,GAChC,MAAM,CAMR"}
1
+ {"version":3,"file":"windtunnel-lock.d.ts","sourceRoot":"","sources":["../../src/spine/windtunnel-lock.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAuBxB,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0H7B,CAAC;AAEL,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAIlE;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,EAChB,yBAAyB,EAAE,MAAM,GAChC,MAAM,CAMR"}
@@ -2,6 +2,10 @@ import { createHash } from 'node:crypto';
2
2
  import { z } from 'zod';
3
3
  // ─── Named constants ─────────────────────────────────
4
4
  const COMMIT_SHA_REGEX = /^[0-9a-f]{40}$/;
5
+ // llm-replay fixture hash is a sha256 digest (64-hex) from computeArtifactHash
6
+ // over the whole replay artifact (incl. provenance), distinct from the 40-hex
7
+ // git hash-object fixtureSha used for the control dirs.
8
+ const SHA256_REGEX = /^[0-9a-f]{64}$/;
5
9
  const MIN_ACTIVE_RULES_FLOOR = 2;
6
10
  // ─── Sub-schemas ─────────────────────────────────────
7
11
  const ResolvedPrSchema = z.object({
@@ -71,6 +75,19 @@ export const WindtunnelLockSchema = z
71
75
  // hard-error integrity gate — validate its format here so a malformed
72
76
  // value fails at parse, not cryptically at run (greptile P2).
73
77
  fixtureSha: z.string().regex(COMMIT_SHA_REGEX, 'fixtureSha must be a 40-hex SHA'),
78
+ // L2 (5c-ii): the EXTERNAL expected-hash for the frozen `llm-replay.v1`
79
+ // fixture — a sha256 (64-hex) from `computeArtifactHash` over the whole
80
+ // replay artifact (incl. prompt/provider provenance). Single-homed here
81
+ // beside fixtureSha (Tenet 20: one freeze-manifest per cert run). The
82
+ // `run` path sources it and passes it to `assertFixtureIntegrity`, so a
83
+ // tampered/stale fixture fails loud. Additive-optional: harness locks
84
+ // (no LLM stage) parse unchanged; the certifying record/replay wiring
85
+ // requires it (the run hard-errors if absent — no safe default for an
86
+ // integrity hash).
87
+ llmReplaySha: z
88
+ .string()
89
+ .regex(SHA256_REGEX, 'llmReplaySha must be a 64-hex sha256')
90
+ .optional(),
74
91
  }),
75
92
  }),
76
93
  cullRateThreshold: z
@@ -1 +1 @@
1
- {"version":3,"file":"windtunnel-lock.js","sourceRoot":"","sources":["../../src/spine/windtunnel-lock.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"windtunnel-lock.js","sourceRoot":"","sources":["../../src/spine/windtunnel-lock.ts"],"names":[],"mappings":"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"}