@mmnto/totem 1.64.2 → 1.66.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.
@@ -0,0 +1,533 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { firingLabelId } from './windtunnel-lock.js';
3
+ import { scoreWindtunnel } from './windtunnel-scorer.js';
4
+ // ─── Helpers ─────────────────────────────────────────
5
+ function makeFiring(ruleId, pr, controlKind, matchedLine = 'const x = 1;', filePath = 'src/foo.ts') {
6
+ return {
7
+ ruleId,
8
+ pr,
9
+ filePath,
10
+ matchedLine,
11
+ controlKind,
12
+ labelId: firingLabelId(ruleId, pr, filePath, matchedLine),
13
+ };
14
+ }
15
+ function baseInput(overrides) {
16
+ return {
17
+ firings: [],
18
+ groundTruth: new Map(),
19
+ positiveControlTargets: [],
20
+ mintedRuleIds: ['rule-a', 'rule-b'],
21
+ cullRateThreshold: 0.5,
22
+ exposureFloors: {
23
+ activeRulesEvaluated: 2,
24
+ filesTouchedInWindow: 0,
25
+ positiveControlsExercised: 0,
26
+ },
27
+ actualExposure: {
28
+ activeRulesEvaluated: 2,
29
+ filesTouchedInWindow: 5,
30
+ positiveControlsExercised: 1,
31
+ },
32
+ ...overrides,
33
+ };
34
+ }
35
+ // ─── FP label → FAIL ─────────────────────────────────
36
+ describe('FP label → FAIL', () => {
37
+ it('returns FAIL when any firing is labeled FP', () => {
38
+ const firing = makeFiring('rule-a', 1, 'corpus');
39
+ const gt = new Map([[firing.labelId, 'FP']]);
40
+ const result = scoreWindtunnel(baseInput({ firings: [firing], groundTruth: gt }));
41
+ expect(result.verdict).toBe('FAIL');
42
+ expect(result.precision).toBeLessThan(1);
43
+ });
44
+ });
45
+ // ─── Non-vacuity → FAIL ──────────────────────────────
46
+ describe('positive control does not fire its target rule → FAIL', () => {
47
+ it('returns FAIL when positive control target rule never fires', () => {
48
+ const result = scoreWindtunnel(baseInput({
49
+ positiveControlTargets: [{ pr: 10, targetRuleId: 'rule-a' }],
50
+ firings: [],
51
+ }));
52
+ expect(result.verdict).toBe('FAIL');
53
+ expect(result.nonVacuity).toBe(false);
54
+ });
55
+ it('returns PASS when positive control target rule fires', () => {
56
+ const firing = makeFiring('rule-a', 10, 'positive');
57
+ const gt = new Map([[firing.labelId, 'TP']]);
58
+ const result = scoreWindtunnel(baseInput({
59
+ positiveControlTargets: [{ pr: 10, targetRuleId: 'rule-a' }],
60
+ firings: [firing],
61
+ groundTruth: gt,
62
+ }));
63
+ expect(result.verdict).toBe('PASS');
64
+ expect(result.nonVacuity).toBe(true);
65
+ });
66
+ });
67
+ // ─── Negative control → culled + recorded ────────────
68
+ describe('negative control fires → culled and recorded in cullLedger', () => {
69
+ it('culls the rule and records in cullLedger (not silently dropped)', () => {
70
+ const firing = makeFiring('rule-a', 99, 'negative', 'near-miss line');
71
+ const result = scoreWindtunnel(baseInput({ firings: [firing] }));
72
+ expect(result.culledCount).toBe(1);
73
+ expect(result.cullLedger).toHaveLength(1);
74
+ expect(result.cullLedger[0].ruleId).toBe('rule-a');
75
+ expect(result.cullLedger[0].reason).toBe('negative-control-fired');
76
+ });
77
+ it('does not count a culled rule as a surviving rule', () => {
78
+ const firing = makeFiring('rule-a', 99, 'negative');
79
+ const result = scoreWindtunnel(baseInput({ firings: [firing], mintedRuleIds: ['rule-a', 'rule-b'] }));
80
+ expect(result.mintedRuleCount).toBe(2);
81
+ expect(result.culledCount).toBe(1);
82
+ expect(result.survivingRuleCount).toBe(1);
83
+ });
84
+ });
85
+ // ─── Unlabeled firing → needsAdjudication (not PASS) ─
86
+ describe('unlabeled firing → needsAdjudication, not PASS', () => {
87
+ it('returns HONEST-NEGATIVE with firing in needsAdjudication when label is missing', () => {
88
+ const firing = makeFiring('rule-a', 1, 'corpus');
89
+ // No groundTruth entry for this firing
90
+ const result = scoreWindtunnel(baseInput({ firings: [firing], groundTruth: new Map() }));
91
+ expect(result.verdict).toBe('HONEST-NEGATIVE');
92
+ expect(result.needsAdjudication).toContain(firing.labelId);
93
+ });
94
+ });
95
+ // ─── Exposure floor trip → HONEST-NEGATIVE (P2) ──────
96
+ describe('exposure floor check (P2)', () => {
97
+ it('returns HONEST-NEGATIVE when activeRules < floor', () => {
98
+ const result = scoreWindtunnel(baseInput({
99
+ actualExposure: {
100
+ activeRulesEvaluated: 1,
101
+ filesTouchedInWindow: 5,
102
+ positiveControlsExercised: 0,
103
+ },
104
+ exposureFloors: {
105
+ activeRulesEvaluated: 2,
106
+ filesTouchedInWindow: 0,
107
+ positiveControlsExercised: 0,
108
+ },
109
+ }));
110
+ expect(result.verdict).toBe('HONEST-NEGATIVE');
111
+ });
112
+ it('returns PASS when activeRules exactly equals floor = 2 (P2 equality boundary)', () => {
113
+ const result = scoreWindtunnel(baseInput({
114
+ actualExposure: {
115
+ activeRulesEvaluated: 2,
116
+ filesTouchedInWindow: 5,
117
+ positiveControlsExercised: 0,
118
+ },
119
+ exposureFloors: {
120
+ activeRulesEvaluated: 2,
121
+ filesTouchedInWindow: 0,
122
+ positiveControlsExercised: 0,
123
+ },
124
+ }));
125
+ // All firings empty + labeled TP by default → PASS
126
+ expect(result.verdict).toBe('PASS');
127
+ });
128
+ it('returns HONEST-NEGATIVE when activeRules = 1 (below floor 2, P2)', () => {
129
+ const result = scoreWindtunnel(baseInput({
130
+ actualExposure: {
131
+ activeRulesEvaluated: 1,
132
+ filesTouchedInWindow: 0,
133
+ positiveControlsExercised: 0,
134
+ },
135
+ }));
136
+ expect(result.verdict).toBe('HONEST-NEGATIVE');
137
+ });
138
+ it('returns HONEST-NEGATIVE when positiveControls < positiveControlsExercised floor', () => {
139
+ const result = scoreWindtunnel(baseInput({
140
+ actualExposure: {
141
+ activeRulesEvaluated: 3,
142
+ filesTouchedInWindow: 5,
143
+ positiveControlsExercised: 0,
144
+ },
145
+ exposureFloors: {
146
+ activeRulesEvaluated: 2,
147
+ filesTouchedInWindow: 0,
148
+ positiveControlsExercised: 2,
149
+ },
150
+ }));
151
+ expect(result.verdict).toBe('HONEST-NEGATIVE');
152
+ });
153
+ it('passes when positiveControls exactly equals floor (P2 equality boundary)', () => {
154
+ const result = scoreWindtunnel(baseInput({
155
+ actualExposure: {
156
+ activeRulesEvaluated: 3,
157
+ filesTouchedInWindow: 5,
158
+ positiveControlsExercised: 2,
159
+ },
160
+ exposureFloors: {
161
+ activeRulesEvaluated: 2,
162
+ filesTouchedInWindow: 0,
163
+ positiveControlsExercised: 2,
164
+ },
165
+ }));
166
+ expect(result.verdict).toBe('PASS');
167
+ });
168
+ });
169
+ // ─── Cull-rate guard → HONEST-NEGATIVE (C5/S2) ───────
170
+ describe('cull-rate guard (C5/S2)', () => {
171
+ it('returns HONEST-NEGATIVE when cull rate exceeds threshold', () => {
172
+ // 2 minted, 2 culled → rate = 1.0 > threshold 0.5
173
+ const firingA = makeFiring('rule-a', 99, 'negative');
174
+ const firingB = makeFiring('rule-b', 99, 'negative', 'other line');
175
+ const result = scoreWindtunnel(baseInput({
176
+ firings: [firingA, firingB],
177
+ mintedRuleIds: ['rule-a', 'rule-b'],
178
+ cullRateThreshold: 0.5,
179
+ }));
180
+ expect(result.verdict).toBe('HONEST-NEGATIVE');
181
+ expect(result.culledCount).toBe(2);
182
+ // precision is the NULL not-computed sentinel on a no-claim verdict (#2189
183
+ // ruling) — NEVER 0 (a real all-FP value) and NEVER a survival ratio. Locks
184
+ // the greptile-P1 / CR fix + the strategy-claude 2026-06-17 sentinel ruling.
185
+ expect(result.precision).toBeNull();
186
+ });
187
+ it('does not apply cull-rate guard when mintedRuleCount = 0 (harness phase)', () => {
188
+ const result = scoreWindtunnel(baseInput({
189
+ mintedRuleIds: [],
190
+ firings: [],
191
+ cullRateThreshold: 0.0,
192
+ // Need actualExposure to pass floor check even with 0 minted
193
+ exposureFloors: {
194
+ activeRulesEvaluated: 0,
195
+ filesTouchedInWindow: 0,
196
+ positiveControlsExercised: 0,
197
+ },
198
+ actualExposure: {
199
+ activeRulesEvaluated: 0,
200
+ filesTouchedInWindow: 0,
201
+ positiveControlsExercised: 0,
202
+ },
203
+ }));
204
+ // No minted rules, no firings → PASS (vacuous but valid for harness)
205
+ expect(result.verdict).toBe('PASS');
206
+ });
207
+ });
208
+ // ─── #2189 ruling: FAIL outranks the masquerade guards ──
209
+ //
210
+ // strategy-claude verdict-semantics RULING (2026-06-17): a confirmed FP — or a
211
+ // vacuous positive control — is a *claim*, not a no-claim. It must FAIL even
212
+ // when an exposure-floor / cull-rate masquerade guard would otherwise return
213
+ // HONEST-NEGATIVE. The guards may only DEMOTE a would-be PASS; they may never
214
+ // UPGRADE a FAIL. Under the pre-#2189 order these returned HONEST-NEGATIVE.
215
+ describe('#2189: FAIL precedence outranks the masquerade guards', () => {
216
+ it('unconditionally evaluates to FAIL when a firing is labeled FP, ignoring a sub-floor exposure', () => {
217
+ const fp = makeFiring('rule-a', 1, 'corpus', '// const secret = "x"');
218
+ const gt = new Map([[fp.labelId, 'FP']]);
219
+ const result = scoreWindtunnel(baseInput({
220
+ firings: [fp],
221
+ groundTruth: gt,
222
+ // sub-floor exposure that WOULD trip HONEST-NEGATIVE first under the old order
223
+ actualExposure: {
224
+ activeRulesEvaluated: 1,
225
+ filesTouchedInWindow: 0,
226
+ positiveControlsExercised: 0,
227
+ },
228
+ exposureFloors: {
229
+ activeRulesEvaluated: 2,
230
+ filesTouchedInWindow: 0,
231
+ positiveControlsExercised: 0,
232
+ },
233
+ }));
234
+ expect(result.verdict).toBe('FAIL');
235
+ });
236
+ it('evaluates to FAIL when a firing is labeled FP, ignoring an over-threshold cull rate', () => {
237
+ // rule-a culled on a negative control (1/2 = 0.5 > threshold 0.4 → cull-rate HN
238
+ // under the old order); rule-b (surviving) fires a confirmed FP → must FAIL.
239
+ const culled = makeFiring('rule-a', 99, 'negative');
240
+ const fp = makeFiring('rule-b', 1, 'corpus', 'fp line');
241
+ const gt = new Map([[fp.labelId, 'FP']]);
242
+ const result = scoreWindtunnel(baseInput({
243
+ firings: [culled, fp],
244
+ mintedRuleIds: ['rule-a', 'rule-b'],
245
+ groundTruth: gt,
246
+ cullRateThreshold: 0.4,
247
+ }));
248
+ expect(result.verdict).toBe('FAIL');
249
+ });
250
+ it('evaluates to FAIL on a vacuous positive control even under a sub-floor exposure', () => {
251
+ const result = scoreWindtunnel(baseInput({
252
+ positiveControlTargets: [{ pr: 10, targetRuleId: 'rule-a' }],
253
+ firings: [], // target never fires → vacuous
254
+ actualExposure: {
255
+ activeRulesEvaluated: 1,
256
+ filesTouchedInWindow: 0,
257
+ positiveControlsExercised: 0,
258
+ },
259
+ exposureFloors: {
260
+ activeRulesEvaluated: 2,
261
+ filesTouchedInWindow: 0,
262
+ positiveControlsExercised: 0,
263
+ },
264
+ }));
265
+ expect(result.verdict).toBe('FAIL');
266
+ expect(result.nonVacuity).toBe(false);
267
+ });
268
+ it('FP takes precedence over a vacuous positive control when both occur', () => {
269
+ // A confirmed FP on a corpus firing AND a positive control whose target
270
+ // never fires (vacuous). Step 4a (FP) precedes Step 4b (vacuous): the
271
+ // verdict is FAIL with the breaching precision 0.5 — NOT null (which the
272
+ // vacuous-control FAIL would have returned).
273
+ const fp = makeFiring('rule-b', 1, 'corpus', 'fp');
274
+ const tp = makeFiring('rule-c', 2, 'corpus', 'tp');
275
+ const result = scoreWindtunnel(baseInput({
276
+ firings: [fp, tp],
277
+ mintedRuleIds: ['rule-a', 'rule-b', 'rule-c'],
278
+ groundTruth: new Map([
279
+ [fp.labelId, 'FP'],
280
+ [tp.labelId, 'TP'],
281
+ ]),
282
+ positiveControlTargets: [{ pr: 10, targetRuleId: 'rule-a' }],
283
+ }));
284
+ expect(result.verdict).toBe('FAIL');
285
+ expect(result.nonVacuity).toBe(false);
286
+ expect(result.precision).toBe(0.5);
287
+ });
288
+ });
289
+ // ─── #2189 ruling: precision is a null no-claim sentinel ─
290
+ //
291
+ // precision carries a real value ONLY on verdicts that make a precision claim —
292
+ // PASS (1.0) and confirmed-FP FAIL (the breaching value, which IS the evidence).
293
+ // On every no-claim verdict it is null — NEVER 0 (a real all-FP value).
294
+ describe('#2189: precision null-sentinel on no-claim verdicts', () => {
295
+ it('precision is null on an exposure-floor HONEST-NEGATIVE', () => {
296
+ const result = scoreWindtunnel(baseInput({
297
+ actualExposure: {
298
+ activeRulesEvaluated: 1,
299
+ filesTouchedInWindow: 0,
300
+ positiveControlsExercised: 0,
301
+ },
302
+ exposureFloors: {
303
+ activeRulesEvaluated: 2,
304
+ filesTouchedInWindow: 0,
305
+ positiveControlsExercised: 0,
306
+ },
307
+ }));
308
+ expect(result.verdict).toBe('HONEST-NEGATIVE');
309
+ expect(result.precision).toBeNull();
310
+ });
311
+ it('precision is null on a needs-adjudication HONEST-NEGATIVE', () => {
312
+ const firing = makeFiring('rule-a', 1, 'corpus');
313
+ const result = scoreWindtunnel(baseInput({ firings: [firing], groundTruth: new Map() }));
314
+ expect(result.verdict).toBe('HONEST-NEGATIVE');
315
+ expect(result.needsAdjudication).toContain(firing.labelId);
316
+ expect(result.precision).toBeNull();
317
+ });
318
+ it('precision is null on a vacuous-control FAIL (structural failure, no precision claim — Q-A)', () => {
319
+ const result = scoreWindtunnel(baseInput({ positiveControlTargets: [{ pr: 10, targetRuleId: 'rule-a' }], firings: [] }));
320
+ expect(result.verdict).toBe('FAIL');
321
+ expect(result.precision).toBeNull();
322
+ });
323
+ it('precision is a real value on PASS (1.0) and on FP-FAIL (the breaching value, never null)', () => {
324
+ const tp = makeFiring('rule-a', 1, 'corpus');
325
+ const pass = scoreWindtunnel(baseInput({ firings: [tp], groundTruth: new Map([[tp.labelId, 'TP']]) }));
326
+ expect(pass.verdict).toBe('PASS');
327
+ expect(pass.precision).toBe(1.0);
328
+ // 1 FP + 1 TP → breaching precision 0.5, a real number (the evidence)
329
+ const fp = makeFiring('rule-a', 2, 'corpus', 'fp');
330
+ const tp2 = makeFiring('rule-b', 3, 'corpus', 'tp');
331
+ const fail = scoreWindtunnel(baseInput({
332
+ firings: [fp, tp2],
333
+ groundTruth: new Map([
334
+ [fp.labelId, 'FP'],
335
+ [tp2.labelId, 'TP'],
336
+ ]),
337
+ }));
338
+ expect(fail.verdict).toBe('FAIL');
339
+ expect(fail.precision).toBe(0.5);
340
+ });
341
+ it('precision is 0 (a real all-FP measurement, never the not-computed sentinel) when every labeled firing is FP', () => {
342
+ // The ruling reserves 0 for a REAL all-FP value (precision = 0/N). A pure
343
+ // all-FP run must report precision === 0, distinct from the null sentinel
344
+ // — a regression that re-introduced 0-as-"not-computed" would break here.
345
+ const fpA = makeFiring('rule-a', 1, 'corpus', 'fp a');
346
+ const fpB = makeFiring('rule-b', 2, 'corpus', 'fp b');
347
+ const result = scoreWindtunnel(baseInput({
348
+ firings: [fpA, fpB],
349
+ mintedRuleIds: ['rule-a', 'rule-b'],
350
+ groundTruth: new Map([
351
+ [fpA.labelId, 'FP'],
352
+ [fpB.labelId, 'FP'],
353
+ ]),
354
+ }));
355
+ expect(result.verdict).toBe('FAIL');
356
+ expect(result.precision).toBe(0);
357
+ });
358
+ });
359
+ // ─── #2189 ruling: diagnostics.survivorPrecision is separate ─
360
+ //
361
+ // CR's survivor-precision is informative ("culled 8/10, the 2 survivors were
362
+ // clean") but must NOT live on the certifying field. It is descriptive and
363
+ // distinct from `precision`.
364
+ describe('#2189: diagnostics.survivorPrecision is a separate descriptive field', () => {
365
+ it('carries the survivor ratio on a HONEST-NEGATIVE while certifying precision stays null', () => {
366
+ // Cull rule-a (over-threshold cull rate), survivor rule-b fires clean TP →
367
+ // survivor ratio 1.0, but the verdict is a no-claim HONEST-NEGATIVE so the
368
+ // certifying precision is null.
369
+ const culled = makeFiring('rule-a', 99, 'negative');
370
+ const survivorTp = makeFiring('rule-b', 1, 'corpus', 'clean');
371
+ const result = scoreWindtunnel(baseInput({
372
+ firings: [culled, survivorTp],
373
+ mintedRuleIds: ['rule-a', 'rule-b'],
374
+ groundTruth: new Map([[survivorTp.labelId, 'TP']]),
375
+ cullRateThreshold: 0.4, // 1/2 = 0.5 > 0.4 → cull-rate HONEST-NEGATIVE
376
+ }));
377
+ expect(result.verdict).toBe('HONEST-NEGATIVE');
378
+ expect(result.precision).toBeNull();
379
+ expect(result.diagnostics.survivorPrecision).toBe(1.0);
380
+ });
381
+ it('survivorPrecision is null when no surviving firing is labeled', () => {
382
+ const result = scoreWindtunnel(baseInput({ firings: [] }));
383
+ expect(result.diagnostics.survivorPrecision).toBeNull();
384
+ });
385
+ });
386
+ // ─── exposureTuple is always a 3-tuple (never collapsed) ─
387
+ describe('exposureTuple invariant', () => {
388
+ it('emits a 3-tuple, never collapsed to a product', () => {
389
+ const result = scoreWindtunnel(baseInput());
390
+ expect(Array.isArray(result.exposureTuple)).toBe(true);
391
+ expect(result.exposureTuple).toHaveLength(3);
392
+ expect(typeof result.exposureTuple[0]).toBe('number');
393
+ expect(typeof result.exposureTuple[1]).toBe('number');
394
+ expect(typeof result.exposureTuple[2]).toBe('number');
395
+ });
396
+ });
397
+ // ─── Precision over surviving rules (S2) ─────────────
398
+ describe('precision is over surviving rules (S2)', () => {
399
+ it('labels precision as over surviving rules after culling', () => {
400
+ const culled = makeFiring('rule-a', 99, 'negative');
401
+ const tp = makeFiring('rule-b', 1, 'corpus');
402
+ const gt = new Map([[tp.labelId, 'TP']]);
403
+ const result = scoreWindtunnel(baseInput({
404
+ firings: [culled, tp],
405
+ mintedRuleIds: ['rule-a', 'rule-b'],
406
+ groundTruth: gt,
407
+ cullRateThreshold: 0.9,
408
+ }));
409
+ expect(result.verdict).toBe('PASS');
410
+ expect(result.precision).toBe(1.0);
411
+ expect(result.culledCount).toBe(1);
412
+ expect(result.survivingRuleCount).toBe(1);
413
+ });
414
+ });
415
+ // ─── Mock engine: always-0 fires → FAIL vacuity ──────
416
+ describe('OQ2: mock engine coverage', () => {
417
+ it('mock always-0 engine: positive control target never fires → FAIL', () => {
418
+ // Always-0 engine: no firings. Positive control target expects rule-a.
419
+ const result = scoreWindtunnel(baseInput({
420
+ firings: [], // always-0: never fires
421
+ positiveControlTargets: [{ pr: 1, targetRuleId: 'rule-a' }],
422
+ }));
423
+ expect(result.verdict).toBe('FAIL');
424
+ });
425
+ it('mock always-1 engine: fires on negative control → culled, possibly HONEST-NEGATIVE', () => {
426
+ // Always-1 engine fires on the negative control
427
+ const negFiring = makeFiring('rule-a', 99, 'negative', 'near-miss');
428
+ const result = scoreWindtunnel(baseInput({
429
+ firings: [negFiring],
430
+ mintedRuleIds: ['rule-a'],
431
+ cullRateThreshold: 0.5,
432
+ }));
433
+ // 1 minted, 1 culled → rate = 1.0 > 0.5 → HONEST-NEGATIVE
434
+ expect(result.verdict).toBe('HONEST-NEGATIVE');
435
+ expect(result.cullLedger).toHaveLength(1);
436
+ });
437
+ it('mock exposure-floor-trip engine → HONEST-NEGATIVE', () => {
438
+ const result = scoreWindtunnel(baseInput({
439
+ actualExposure: {
440
+ activeRulesEvaluated: 1,
441
+ filesTouchedInWindow: 0,
442
+ positiveControlsExercised: 0,
443
+ },
444
+ exposureFloors: {
445
+ activeRulesEvaluated: 2,
446
+ filesTouchedInWindow: 0,
447
+ positiveControlsExercised: 0,
448
+ },
449
+ }));
450
+ expect(result.verdict).toBe('HONEST-NEGATIVE');
451
+ });
452
+ it('mock unlabeled-firing engine → needs-adjudication HONEST-NEGATIVE', () => {
453
+ const firing = makeFiring('rule-a', 5, 'corpus', 'some matched line');
454
+ // No groundTruth labels → unlabeled
455
+ const result = scoreWindtunnel(baseInput({
456
+ firings: [firing],
457
+ groundTruth: new Map(),
458
+ }));
459
+ expect(result.verdict).toBe('HONEST-NEGATIVE');
460
+ expect(result.needsAdjudication).toHaveLength(1);
461
+ expect(result.needsAdjudication[0]).toBe(firing.labelId);
462
+ });
463
+ it('mock perfect engine: all TPs, positive control fires, exposure met → PASS', () => {
464
+ const corpusFiring = makeFiring('rule-a', 1, 'corpus', 'pattern match');
465
+ const positiveFiring = makeFiring('rule-a', 10, 'positive', 'target match');
466
+ const gt = new Map([
467
+ [corpusFiring.labelId, 'TP'],
468
+ [positiveFiring.labelId, 'TP'],
469
+ ]);
470
+ const result = scoreWindtunnel(baseInput({
471
+ firings: [corpusFiring, positiveFiring],
472
+ groundTruth: gt,
473
+ positiveControlTargets: [{ pr: 10, targetRuleId: 'rule-a' }],
474
+ }));
475
+ expect(result.verdict).toBe('PASS');
476
+ expect(result.precision).toBe(1.0);
477
+ expect(result.nonVacuity).toBe(true);
478
+ });
479
+ });
480
+ // ─── Scorer-level FP handling (NOT the parity test) ──
481
+ //
482
+ // The real bidirectional firing-parity test (S1+C1) — replay firings ==
483
+ // production firings through enrichWithAstContext + the rule engine, covering
484
+ // both the regex/astContext over-fire suppression and the AST whole-file
485
+ // under-fire cases — lives in `windtunnel-parity.test.ts`. That test exercises
486
+ // the production classification path end-to-end; the case below only confirms
487
+ // the scorer turns a labeled FP into a FAIL verdict.
488
+ describe('scorer FP handling (see windtunnel-parity.test.ts for the real S1+C1 parity test)', () => {
489
+ it('a firing labeled FP (e.g. a comment-context match) yields FAIL with precision < 1', () => {
490
+ const firing = makeFiring('rule-a', 1, 'corpus', '// const secret = "abc"');
491
+ const gt = new Map([[firing.labelId, 'FP']]);
492
+ const result = scoreWindtunnel(baseInput({ firings: [firing], groundTruth: gt }));
493
+ expect(result.verdict).toBe('FAIL');
494
+ expect(result.precision).toBeLessThan(1.0);
495
+ });
496
+ });
497
+ // ─── Label identity (A2) ─────────────────────────────
498
+ describe('content-based firing label id (A2)', () => {
499
+ it('same content → same label id (deterministic)', () => {
500
+ const id1 = firingLabelId('rule-a', 1, 'src/foo.ts', 'const x = 1;');
501
+ const id2 = firingLabelId('rule-a', 1, 'src/foo.ts', 'const x = 1;');
502
+ expect(id1).toBe(id2);
503
+ });
504
+ it('different matched line → different label id (survives line-drift)', () => {
505
+ const id1 = firingLabelId('rule-a', 1, 'src/foo.ts', 'const x = 1;');
506
+ const id2 = firingLabelId('rule-a', 1, 'src/foo.ts', 'const y = 2;');
507
+ expect(id1).not.toBe(id2);
508
+ });
509
+ });
510
+ // ─── Phase (P1) ──────────────────────────────────────
511
+ describe('phase discrimination (P1)', () => {
512
+ it('harness lock emits PASS at harness phase with zero minted rules', () => {
513
+ // Harness phase: mintedRuleCount ≈ 0, exposureFloors allow it
514
+ const result = scoreWindtunnel(baseInput({
515
+ mintedRuleIds: [],
516
+ firings: [],
517
+ exposureFloors: {
518
+ activeRulesEvaluated: 0,
519
+ filesTouchedInWindow: 0,
520
+ positiveControlsExercised: 0,
521
+ },
522
+ actualExposure: {
523
+ activeRulesEvaluated: 0,
524
+ filesTouchedInWindow: 0,
525
+ positiveControlsExercised: 0,
526
+ },
527
+ }));
528
+ // Zero rules, zero firings → vacuous PASS (valid for harness)
529
+ expect(result.verdict).toBe('PASS');
530
+ expect(result.mintedRuleCount).toBe(0);
531
+ });
532
+ });
533
+ //# sourceMappingURL=windtunnel-scorer.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"windtunnel-scorer.test.js","sourceRoot":"","sources":["../../src/spine/windtunnel-scorer.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,wDAAwD;AAExD,SAAS,UAAU,CACjB,MAAc,EACd,EAAU,EACV,WAAsC,EACtC,WAAW,GAAG,cAAc,EAC5B,QAAQ,GAAG,YAAY;IAEvB,OAAO;QACL,MAAM;QACN,EAAE;QACF,QAAQ;QACR,WAAW;QACX,WAAW;QACX,OAAO,EAAE,aAAa,CAAC,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,WAAW,CAAC;KAC1D,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,SAAgC;IACjD,OAAO;QACL,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,IAAI,GAAG,EAAE;QACtB,sBAAsB,EAAE,EAAE;QAC1B,aAAa,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;QACnC,iBAAiB,EAAE,GAAG;QACtB,cAAc,EAAE;YACd,oBAAoB,EAAE,CAAC;YACvB,oBAAoB,EAAE,CAAC;YACvB,yBAAyB,EAAE,CAAC;SAC7B;QACD,cAAc,EAAE;YACd,oBAAoB,EAAE,CAAC;YACvB,oBAAoB,EAAE,CAAC;YACvB,yBAAyB,EAAE,CAAC;SAC7B;QACD,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,wDAAwD;AAExD,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;QACjD,MAAM,EAAE,GAAG,IAAI,GAAG,CAA2B,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QACvE,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAClF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,wDAAwD;AAExD,QAAQ,CAAC,uDAAuD,EAAE,GAAG,EAAE;IACrE,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,sBAAsB,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;YAC5D,OAAO,EAAE,EAAE;SACZ,CAAC,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;QACpD,MAAM,EAAE,GAAG,IAAI,GAAG,CAA2B,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QACvE,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,sBAAsB,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;YAC5D,OAAO,EAAE,CAAC,MAAM,CAAC;YACjB,WAAW,EAAE,EAAE;SAChB,CAAC,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,wDAAwD;AAExD,QAAQ,CAAC,4DAA4D,EAAE,GAAG,EAAE;IAC1E,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAC;QACtE,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC,CACtE,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,wDAAwD;AAExD,QAAQ,CAAC,gDAAgD,EAAE,GAAG,EAAE;IAC9D,EAAE,CAAC,gFAAgF,EAAE,GAAG,EAAE;QACxF,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;QACjD,uCAAuC;QACvC,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QACzF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,wDAAwD;AAExD,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;YACD,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;SACF,CAAC,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+EAA+E,EAAE,GAAG,EAAE;QACvF,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;YACD,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;SACF,CAAC,CACH,CAAC;QACF,mDAAmD;QACnD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;SACF,CAAC,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iFAAiF,EAAE,GAAG,EAAE;QACzF,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;YACD,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;SACF,CAAC,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,GAAG,EAAE;QAClF,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;YACD,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;SACF,CAAC,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,wDAAwD;AAExD,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,kDAAkD;QAClD,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;YAC3B,aAAa,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;YACnC,iBAAiB,EAAE,GAAG;SACvB,CAAC,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnC,2EAA2E;QAC3E,4EAA4E;QAC5E,6EAA6E;QAC7E,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;QACjF,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,aAAa,EAAE,EAAE;YACjB,OAAO,EAAE,EAAE;YACX,iBAAiB,EAAE,GAAG;YACtB,6DAA6D;YAC7D,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;YACD,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;SACF,CAAC,CACH,CAAC;QACF,qEAAqE;QACrE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,2DAA2D;AAC3D,EAAE;AACF,+EAA+E;AAC/E,6EAA6E;AAC7E,6EAA6E;AAC7E,8EAA8E;AAC9E,4EAA4E;AAE5E,QAAQ,CAAC,uDAAuD,EAAE,GAAG,EAAE;IACrE,EAAE,CAAC,8FAA8F,EAAE,GAAG,EAAE;QACtG,MAAM,EAAE,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,uBAAuB,CAAC,CAAC;QACtE,MAAM,EAAE,GAAG,IAAI,GAAG,CAA2B,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,OAAO,EAAE,CAAC,EAAE,CAAC;YACb,WAAW,EAAE,EAAE;YACf,+EAA+E;YAC/E,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;YACD,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;SACF,CAAC,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qFAAqF,EAAE,GAAG,EAAE;QAC7F,gFAAgF;QAChF,6EAA6E;QAC7E,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;QACpD,MAAM,EAAE,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QACxD,MAAM,EAAE,GAAG,IAAI,GAAG,CAA2B,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC;YACrB,aAAa,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;YACnC,WAAW,EAAE,EAAE;YACf,iBAAiB,EAAE,GAAG;SACvB,CAAC,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iFAAiF,EAAE,GAAG,EAAE;QACzF,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,sBAAsB,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;YAC5D,OAAO,EAAE,EAAE,EAAE,+BAA+B;YAC5C,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;YACD,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;SACF,CAAC,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC7E,wEAAwE;QACxE,sEAAsE;QACtE,yEAAyE;QACzE,6CAA6C;QAC7C,MAAM,EAAE,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QACnD,MAAM,EAAE,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;YACjB,aAAa,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC;YAC7C,WAAW,EAAE,IAAI,GAAG,CAA2B;gBAC7C,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC;gBAClB,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC;aACnB,CAAC;YACF,sBAAsB,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;SAC7D,CAAC,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,4DAA4D;AAC5D,EAAE;AACF,gFAAgF;AAChF,iFAAiF;AACjF,wEAAwE;AAExE,QAAQ,CAAC,qDAAqD,EAAE,GAAG,EAAE;IACnE,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;YACD,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;SACF,CAAC,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QACzF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4FAA4F,EAAE,GAAG,EAAE;QACpG,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC,EAAE,sBAAsB,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CACzF,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0FAA0F,EAAE,GAAG,EAAE;QAClG,MAAM,EAAE,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,eAAe,CAC1B,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CACzE,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEjC,sEAAsE;QACtE,MAAM,EAAE,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QACnD,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,eAAe,CAC1B,SAAS,CAAC;YACR,OAAO,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC;YAClB,WAAW,EAAE,IAAI,GAAG,CAAC;gBACnB,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC;gBAClB,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC;aACpB,CAAC;SACH,CAAC,CACH,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6GAA6G,EAAE,GAAG,EAAE;QACrH,0EAA0E;QAC1E,0EAA0E;QAC1E,0EAA0E;QAC1E,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;YACnB,aAAa,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;YACnC,WAAW,EAAE,IAAI,GAAG,CAA2B;gBAC7C,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC;gBACnB,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC;aACpB,CAAC;SACH,CAAC,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,gEAAgE;AAChE,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,6BAA6B;AAE7B,QAAQ,CAAC,sEAAsE,EAAE,GAAG,EAAE;IACpF,EAAE,CAAC,uFAAuF,EAAE,GAAG,EAAE;QAC/F,2EAA2E;QAC3E,2EAA2E;QAC3E,gCAAgC;QAChC,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC9D,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,OAAO,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC;YAC7B,aAAa,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;YACnC,WAAW,EAAE,IAAI,GAAG,CAA2B,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;YAC5E,iBAAiB,EAAE,GAAG,EAAE,8CAA8C;SACvE,CAAC,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,4DAA4D;AAE5D,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,EAAE,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC7C,MAAM,CAAC,OAAO,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtD,MAAM,CAAC,OAAO,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtD,MAAM,CAAC,OAAO,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,wDAAwD;AAExD,QAAQ,CAAC,wCAAwC,EAAE,GAAG,EAAE;IACtD,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;QACpD,MAAM,EAAE,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC7C,MAAM,EAAE,GAAG,IAAI,GAAG,CAA2B,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC;YACrB,aAAa,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;YACnC,WAAW,EAAE,EAAE;YACf,iBAAiB,EAAE,GAAG;SACvB,CAAC,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,wDAAwD;AAExD,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,uEAAuE;QACvE,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,OAAO,EAAE,EAAE,EAAE,wBAAwB;YACrC,sBAAsB,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;SAC5D,CAAC,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oFAAoF,EAAE,GAAG,EAAE;QAC5F,gDAAgD;QAChD,MAAM,SAAS,GAAG,UAAU,CAAC,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;QACpE,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,OAAO,EAAE,CAAC,SAAS,CAAC;YACpB,aAAa,EAAE,CAAC,QAAQ,CAAC;YACzB,iBAAiB,EAAE,GAAG;SACvB,CAAC,CACH,CAAC;QACF,0DAA0D;QAC1D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;YACD,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;SACF,CAAC,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAAC;QACtE,oCAAoC;QACpC,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,OAAO,EAAE,CAAC,MAAM,CAAC;YACjB,WAAW,EAAE,IAAI,GAAG,EAAE;SACvB,CAAC,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2EAA2E,EAAE,GAAG,EAAE;QACnF,MAAM,YAAY,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;QACxE,MAAM,cAAc,GAAG,UAAU,CAAC,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC;QAC5E,MAAM,EAAE,GAAG,IAAI,GAAG,CAA2B;YAC3C,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC;YAC5B,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC;SAC/B,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,OAAO,EAAE,CAAC,YAAY,EAAE,cAAc,CAAC;YACvC,WAAW,EAAE,EAAE;YACf,sBAAsB,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;SAC7D,CAAC,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,wDAAwD;AACxD,EAAE;AACF,wEAAwE;AACxE,8EAA8E;AAC9E,yEAAyE;AACzE,+EAA+E;AAC/E,8EAA8E;AAC9E,qDAAqD;AAErD,QAAQ,CAAC,mFAAmF,EAAE,GAAG,EAAE;IACjG,EAAE,CAAC,mFAAmF,EAAE,GAAG,EAAE;QAC3F,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,yBAAyB,CAAC,CAAC;QAC5E,MAAM,EAAE,GAAG,IAAI,GAAG,CAA2B,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QACvE,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAClF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,wDAAwD;AAExD,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;IAClD,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,GAAG,GAAG,aAAa,CAAC,QAAQ,EAAE,CAAC,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;QACrE,MAAM,GAAG,GAAG,aAAa,CAAC,QAAQ,EAAE,CAAC,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;QACrE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,MAAM,GAAG,GAAG,aAAa,CAAC,QAAQ,EAAE,CAAC,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;QACrE,MAAM,GAAG,GAAG,aAAa,CAAC,QAAQ,EAAE,CAAC,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;QACrE,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,wDAAwD;AAExD,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,8DAA8D;QAC9D,MAAM,MAAM,GAAG,eAAe,CAC5B,SAAS,CAAC;YACR,aAAa,EAAE,EAAE;YACjB,OAAO,EAAE,EAAE;YACX,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;YACD,cAAc,EAAE;gBACd,oBAAoB,EAAE,CAAC;gBACvB,oBAAoB,EAAE,CAAC;gBACvB,yBAAyB,EAAE,CAAC;aAC7B;SACF,CAAC,CACH,CAAC;QACF,8DAA8D;QAC9D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmnto/totem",
3
- "version": "1.64.2",
3
+ "version": "1.66.0",
4
4
  "description": "Persistent memory and context layer for AI agents",
5
5
  "type": "module",
6
6
  "engines": {