@mmnto/totem 1.65.0 → 1.67.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,204 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { diffPrSets, isBotIdentity, isCodeTouching, parsePrNumber, parseRevertSha, prSetsEqual, resolveSelectionRule, SelectionRuleParseError, selectionRulePredicate, } from './selection-rule.js';
3
+ // ─── Helpers ─────────────────────────────────────────
4
+ const CLASSIFIER = {
5
+ includeGlobs: ['packages/**/*.ts', 'src/**', '**/*.rs'],
6
+ excludeGlobs: ['**/*.md', 'docs/**', '**/*.json'],
7
+ };
8
+ function cfg(overrides) {
9
+ return {
10
+ codePathClassifier: CLASSIFIER,
11
+ excludeRevertPairs: true,
12
+ excludeBotPrs: true,
13
+ window: { type: 'all' },
14
+ ...overrides,
15
+ };
16
+ }
17
+ function meta(pr, overrides) {
18
+ const author = overrides?.author ?? 'Jane Doe <jane@example.com>';
19
+ return {
20
+ pr,
21
+ mergeCommit: overrides?.mergeCommit ?? `${pr}`.padStart(40, '0'),
22
+ author,
23
+ isBotAuthor: overrides?.isBotAuthor ?? isBotIdentity(author),
24
+ revertsSha: overrides?.revertsSha,
25
+ changedFiles: overrides?.changedFiles ?? ['packages/core/src/x.ts'],
26
+ };
27
+ }
28
+ // ─── isCodeTouching / glob precedence ────────────────
29
+ describe('isCodeTouching — exclude wins at the file level', () => {
30
+ it('includes a PR touching any code file', () => {
31
+ expect(isCodeTouching(['packages/core/src/x.ts'], CLASSIFIER)).toBe(true);
32
+ expect(isCodeTouching(['src/engine/run.ts'], CLASSIFIER)).toBe(true);
33
+ expect(isCodeTouching(['crates/foo/lib.rs'], CLASSIFIER)).toBe(true);
34
+ });
35
+ it('excludes a docs/config-only PR (no file survives the classifier)', () => {
36
+ expect(isCodeTouching(['packages/core/README.md'], CLASSIFIER)).toBe(false);
37
+ expect(isCodeTouching(['docs/guide/intro.md'], CLASSIFIER)).toBe(false);
38
+ expect(isCodeTouching(['package.json'], CLASSIFIER)).toBe(false);
39
+ });
40
+ it('includes a MIXED PR (code + doc) — file-level exclude does not exclude the PR', () => {
41
+ expect(isCodeTouching(['packages/core/README.md', 'packages/core/src/index.ts'], CLASSIFIER)).toBe(true);
42
+ });
43
+ it('exclude wins over include at the file level (a .json under packages is not code)', () => {
44
+ // packages/core/tsconfig.json matches includeGlob packages/**/*.ts? no (.json). matches **/*.json exclude.
45
+ expect(isCodeTouching(['packages/core/data.json'], CLASSIFIER)).toBe(false);
46
+ });
47
+ it('normalizes backslash paths before matching', () => {
48
+ expect(isCodeTouching(['packages\\core\\src\\x.ts'], CLASSIFIER)).toBe(true);
49
+ });
50
+ it('**/*.md matches a root-level file (the **​/ zero-segment case)', () => {
51
+ expect(isCodeTouching(['README.md'], { includeGlobs: ['**/*.md'], excludeGlobs: [] })).toBe(true);
52
+ });
53
+ it('supports brace alternation (**/*.{ts,tsx}) — greptile P2', () => {
54
+ const c = { includeGlobs: ['**/*.{ts,tsx,rs}'], excludeGlobs: [] };
55
+ expect(isCodeTouching(['src/a.ts'], c)).toBe(true);
56
+ expect(isCodeTouching(['packages/core/b.tsx'], c)).toBe(true);
57
+ expect(isCodeTouching(['crates/c.rs'], c)).toBe(true);
58
+ expect(isCodeTouching(['src/a.js'], c)).toBe(false);
59
+ });
60
+ });
61
+ // ─── isBotIdentity ───────────────────────────────────
62
+ describe('isBotIdentity — [bot] suffix only', () => {
63
+ it('matches GitHub bot accounts in git %an <%ae> form (case-insensitive)', () => {
64
+ expect(isBotIdentity('dependabot[bot]')).toBe(true); // name-only
65
+ // The real git author string — display name + noreply email. The whole
66
+ // string ends with ">", so a naive .endsWith('[bot]') would miss it.
67
+ expect(isBotIdentity('dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>')).toBe(true);
68
+ expect(isBotIdentity('Renovate[bot] <bot@renovate.com>')).toBe(true);
69
+ expect(isBotIdentity('renovate[BOT]')).toBe(true);
70
+ });
71
+ it('does NOT match a human handle merely containing "bot"', () => {
72
+ expect(isBotIdentity('revertbot')).toBe(false);
73
+ expect(isBotIdentity('Robotnik')).toBe(false);
74
+ expect(isBotIdentity('Jane Doe')).toBe(false);
75
+ expect(isBotIdentity('Jane Doe <jane@example.com>')).toBe(false);
76
+ });
77
+ it('tolerates trailing CR/whitespace', () => {
78
+ expect(isBotIdentity('dependabot[bot]\r')).toBe(true);
79
+ expect(isBotIdentity(' dependabot[bot] ')).toBe(true);
80
+ });
81
+ });
82
+ // ─── parseRevertSha ──────────────────────────────────
83
+ describe('parseRevertSha', () => {
84
+ it('extracts the target sha from a revert body', () => {
85
+ expect(parseRevertSha('This reverts commit abcdef1234567890abcdef1234567890abcdef12.')).toBe('abcdef1234567890abcdef1234567890abcdef12');
86
+ });
87
+ it('returns undefined when there is no revert line', () => {
88
+ expect(parseRevertSha('feat: a normal commit body')).toBeUndefined();
89
+ });
90
+ it('tolerates CRLF bodies', () => {
91
+ expect(parseRevertSha('This reverts commit deadbeefdeadbeefdeadbeefdeadbeefdeadbeef\r\n')).toBe('deadbeefdeadbeefdeadbeefdeadbeefdeadbeef');
92
+ });
93
+ });
94
+ // ─── parsePrNumber — trailing (#N), skip-no-ref, malformed ───
95
+ describe('parsePrNumber', () => {
96
+ it('extracts the TRAILING (#N), not an earlier issue ref', () => {
97
+ expect(parsePrNumber('on-foot interior breach spec (#533) (#534)')).toBe(534);
98
+ expect(parsePrNumber('first-drive feedback (closes #522) (#524)')).toBe(524);
99
+ expect(parsePrNumber('feat: simple change (#12)')).toBe(12);
100
+ });
101
+ it('returns null for a direct-to-main commit with no (#N) (a non-PR, skip)', () => {
102
+ expect(parsePrNumber('chore(deps): bump @mmnto/* to 1.66.0')).toBeNull();
103
+ expect(parsePrNumber('hotfix straight to main')).toBeNull();
104
+ });
105
+ it('throws on a malformed trailing ref (never silent)', () => {
106
+ expect(() => parsePrNumber('bad ref (#abc)')).toThrow(SelectionRuleParseError);
107
+ expect(() => parsePrNumber('empty ref (#)')).toThrow(SelectionRuleParseError);
108
+ expect(() => parsePrNumber('zero ref (#0)')).toThrow(SelectionRuleParseError);
109
+ expect(() => parsePrNumber('negative ref (#-1)')).toThrow(SelectionRuleParseError);
110
+ });
111
+ it('tolerates a trailing CR', () => {
112
+ expect(parsePrNumber('feat: change (#42)\r')).toBe(42);
113
+ });
114
+ });
115
+ // ─── selectionRulePredicate (per-PR) ─────────────────
116
+ describe('selectionRulePredicate', () => {
117
+ it('passes a code-touching, human, non-revert PR', () => {
118
+ expect(selectionRulePredicate(meta(1), cfg())).toBe(true);
119
+ });
120
+ it('excludes a non-code-touching PR', () => {
121
+ expect(selectionRulePredicate(meta(1, { changedFiles: ['README.md'] }), cfg())).toBe(false);
122
+ });
123
+ it('excludes a bot PR when excludeBotPrs is on; keeps it when off', () => {
124
+ const botPr = meta(1, { author: 'dependabot[bot]' });
125
+ expect(selectionRulePredicate(botPr, cfg({ excludeBotPrs: true }))).toBe(false);
126
+ expect(selectionRulePredicate(botPr, cfg({ excludeBotPrs: false }))).toBe(true);
127
+ });
128
+ it('excludes a revert PR itself when excludeRevertPairs is on; keeps it when off', () => {
129
+ const revertPr = meta(1, { revertsSha: 'a'.repeat(40) });
130
+ expect(selectionRulePredicate(revertPr, cfg({ excludeRevertPairs: true }))).toBe(false);
131
+ expect(selectionRulePredicate(revertPr, cfg({ excludeRevertPairs: false }))).toBe(true);
132
+ });
133
+ });
134
+ // ─── resolveSelectionRule — two-pass revert + fail-safe ───
135
+ describe('resolveSelectionRule', () => {
136
+ it('returns sorted unique PR numbers', () => {
137
+ expect(resolveSelectionRule([meta(13), meta(11), meta(12), meta(11)], cfg())).toEqual([
138
+ 11, 12, 13,
139
+ ]);
140
+ });
141
+ it('drops BOTH the revert PR and its in-window target (two-pass)', () => {
142
+ const target = meta(20, { mergeCommit: 'f'.repeat(40) });
143
+ const revert = meta(21, { revertsSha: 'f'.repeat(40) });
144
+ const other = meta(22);
145
+ expect(resolveSelectionRule([target, revert, other], cfg({ excludeRevertPairs: true }))).toEqual([22]);
146
+ });
147
+ it('fail-safe: a reverted target outside the window drops nothing but the revert itself', () => {
148
+ // The revert points at a sha that is not any in-window candidate's mergeCommit.
149
+ const revert = meta(21, { revertsSha: 'deadbeef'.padEnd(40, '0') });
150
+ const other = meta(22);
151
+ expect(resolveSelectionRule([revert, other], cfg({ excludeRevertPairs: true }))).toEqual([22]);
152
+ });
153
+ it('keeps both revert and target when excludeRevertPairs is false', () => {
154
+ const target = meta(20, { mergeCommit: 'f'.repeat(40) });
155
+ const revert = meta(21, { revertsSha: 'f'.repeat(40) });
156
+ expect(resolveSelectionRule([target, revert], cfg({ excludeRevertPairs: false }))).toEqual([
157
+ 20, 21,
158
+ ]);
159
+ });
160
+ it('excludes bot PRs and non-code PRs from the set', () => {
161
+ const human = meta(1);
162
+ const bot = meta(2, { author: 'renovate[bot]' });
163
+ const docOnly = meta(3, { changedFiles: ['docs/x.md'] });
164
+ expect(resolveSelectionRule([human, bot, docOnly], cfg())).toEqual([1]);
165
+ });
166
+ it('matches an abbreviated revert sha against the full target mergeCommit (prefix)', () => {
167
+ const target = meta(20, { mergeCommit: 'abc123def456'.padEnd(40, '0') });
168
+ const revert = meta(21, { revertsSha: 'abc123d' });
169
+ expect(resolveSelectionRule([target, revert], cfg())).toEqual([]);
170
+ });
171
+ it('bounded window keeps the N MOST-RECENT qualifying PRs (input is newest-first)', () => {
172
+ // metas in git-log order (newest first): 50, 49, 48, 47.
173
+ const metas = [meta(50), meta(49), meta(48), meta(47)];
174
+ expect(resolveSelectionRule(metas, cfg({ window: { type: 'bounded', n: 2 } }))).toEqual([
175
+ 49, 50,
176
+ ]);
177
+ // 'all' keeps everything.
178
+ expect(resolveSelectionRule(metas, cfg({ window: { type: 'all' } }))).toEqual([47, 48, 49, 50]);
179
+ });
180
+ it('bounded window counts only QUALIFYING PRs toward N (skips non-code before the slice)', () => {
181
+ // newest-first: 50 (doc), 49 (code), 48 (code) → N=2 → [48, 49], not [49, 50].
182
+ const metas = [meta(50, { changedFiles: ['README.md'] }), meta(49), meta(48)];
183
+ expect(resolveSelectionRule(metas, cfg({ window: { type: 'bounded', n: 2 } }))).toEqual([
184
+ 48, 49,
185
+ ]);
186
+ });
187
+ });
188
+ // ─── diffPrSets / prSetsEqual ────────────────────────
189
+ describe('deep set-equality (§6)', () => {
190
+ it('is order- and duplicate-invariant', () => {
191
+ expect(prSetsEqual([12, 13], [13, 12])).toBe(true);
192
+ expect(prSetsEqual([12, 13, 13], [13, 12])).toBe(true);
193
+ });
194
+ it('reports missing (in git, not manifest) and extra (in manifest, not git) separately', () => {
195
+ const d = diffPrSets([534, 535, 536], [536, 611]);
196
+ expect(d.missing).toEqual([534, 535]);
197
+ expect(d.extra).toEqual([611]);
198
+ expect(prSetsEqual([534, 535, 536], [536, 611])).toBe(false);
199
+ });
200
+ it('equal sets yield empty diff', () => {
201
+ expect(diffPrSets([1, 2, 3], [3, 2, 1])).toEqual({ missing: [], extra: [] });
202
+ });
203
+ });
204
+ //# sourceMappingURL=selection-rule.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection-rule.test.js","sourceRoot":"","sources":["../../src/spine/selection-rule.test.ts"],"names":[],"mappings":"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"}
@@ -36,6 +36,18 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
36
36
  n: number;
37
37
  }>]>;
38
38
  asOfCommit: z.ZodString;
39
+ codePathClassifier: z.ZodOptional<z.ZodObject<{
40
+ includeGlobs: z.ZodArray<z.ZodString, "many">;
41
+ excludeGlobs: z.ZodArray<z.ZodString, "many">;
42
+ }, "strip", z.ZodTypeAny, {
43
+ includeGlobs: string[];
44
+ excludeGlobs: string[];
45
+ }, {
46
+ includeGlobs: string[];
47
+ excludeGlobs: string[];
48
+ }>>;
49
+ excludeRevertPairs: z.ZodDefault<z.ZodBoolean>;
50
+ excludeBotPrs: z.ZodDefault<z.ZodBoolean>;
39
51
  }, "strip", z.ZodTypeAny, {
40
52
  state: string;
41
53
  predicate: string;
@@ -46,6 +58,12 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
46
58
  n: number;
47
59
  };
48
60
  asOfCommit: string;
61
+ excludeRevertPairs: boolean;
62
+ excludeBotPrs: boolean;
63
+ codePathClassifier?: {
64
+ includeGlobs: string[];
65
+ excludeGlobs: string[];
66
+ } | undefined;
49
67
  }, {
50
68
  state: string;
51
69
  predicate: string;
@@ -56,6 +74,12 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
56
74
  n: number;
57
75
  };
58
76
  asOfCommit: string;
77
+ codePathClassifier?: {
78
+ includeGlobs: string[];
79
+ excludeGlobs: string[];
80
+ } | undefined;
81
+ excludeRevertPairs?: boolean | undefined;
82
+ excludeBotPrs?: boolean | undefined;
59
83
  }>;
60
84
  resolvedPrs: z.ZodArray<z.ZodObject<{
61
85
  pr: z.ZodNumber;
@@ -88,6 +112,12 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
88
112
  n: number;
89
113
  };
90
114
  asOfCommit: string;
115
+ excludeRevertPairs: boolean;
116
+ excludeBotPrs: boolean;
117
+ codePathClassifier?: {
118
+ includeGlobs: string[];
119
+ excludeGlobs: string[];
120
+ } | undefined;
91
121
  };
92
122
  resolvedPrs: {
93
123
  headSha: string;
@@ -108,6 +138,12 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
108
138
  n: number;
109
139
  };
110
140
  asOfCommit: string;
141
+ codePathClassifier?: {
142
+ includeGlobs: string[];
143
+ excludeGlobs: string[];
144
+ } | undefined;
145
+ excludeRevertPairs?: boolean | undefined;
146
+ excludeBotPrs?: boolean | undefined;
111
147
  };
112
148
  resolvedPrs: {
113
149
  headSha: string;
@@ -219,6 +255,12 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
219
255
  n: number;
220
256
  };
221
257
  asOfCommit: string;
258
+ excludeRevertPairs: boolean;
259
+ excludeBotPrs: boolean;
260
+ codePathClassifier?: {
261
+ includeGlobs: string[];
262
+ excludeGlobs: string[];
263
+ } | undefined;
222
264
  };
223
265
  resolvedPrs: {
224
266
  headSha: string;
@@ -275,6 +317,12 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
275
317
  n: number;
276
318
  };
277
319
  asOfCommit: string;
320
+ codePathClassifier?: {
321
+ includeGlobs: string[];
322
+ excludeGlobs: string[];
323
+ } | undefined;
324
+ excludeRevertPairs?: boolean | undefined;
325
+ excludeBotPrs?: boolean | undefined;
278
326
  };
279
327
  resolvedPrs: {
280
328
  headSha: string;
@@ -331,6 +379,12 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
331
379
  n: number;
332
380
  };
333
381
  asOfCommit: string;
382
+ excludeRevertPairs: boolean;
383
+ excludeBotPrs: boolean;
384
+ codePathClassifier?: {
385
+ includeGlobs: string[];
386
+ excludeGlobs: string[];
387
+ } | undefined;
334
388
  };
335
389
  resolvedPrs: {
336
390
  headSha: string;
@@ -387,6 +441,12 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
387
441
  n: number;
388
442
  };
389
443
  asOfCommit: string;
444
+ codePathClassifier?: {
445
+ includeGlobs: string[];
446
+ excludeGlobs: string[];
447
+ } | undefined;
448
+ excludeRevertPairs?: boolean | undefined;
449
+ excludeBotPrs?: boolean | undefined;
390
450
  };
391
451
  resolvedPrs: {
392
452
  headSha: string;
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2F7B,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;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"}
@@ -35,6 +35,24 @@ export const WindtunnelLockSchema = z
35
35
  z.object({ type: z.literal('bounded'), n: z.number().int().positive() }),
36
36
  ]),
37
37
  asOfCommit: z.string().regex(COMMIT_SHA_REGEX, 'asOfCommit must be a 40-hex SHA'),
38
+ // S4 (#2189 item 2): the frozen code-path classifier + exclusion flags the
39
+ // resolver re-derives against. Additive-optional so existing harness locks
40
+ // parse unchanged; `codePathClassifier` is required at CERTIFYING resolve
41
+ // (the resolver hard-errors if absent — no safe code-default for "what is
42
+ // code"). Flags default to the strategy-claude-ratified lean (exclude).
43
+ codePathClassifier: z
44
+ .object({
45
+ // includeGlobs must list ≥1 glob — an empty set makes EVERY file
46
+ // non-code, so the certifying gate would false-fail "Extra: [all PRs]"
47
+ // (greptile P2). excludeGlobs may be empty (no exclusions).
48
+ includeGlobs: z
49
+ .array(z.string().min(1))
50
+ .min(1, 'includeGlobs must list at least one glob'),
51
+ excludeGlobs: z.array(z.string().min(1)),
52
+ })
53
+ .optional(),
54
+ excludeRevertPairs: z.boolean().default(true),
55
+ excludeBotPrs: z.boolean().default(true),
38
56
  }),
39
57
  resolvedPrs: z.array(ResolvedPrSchema).min(1, 'resolvedPrs must be non-empty'),
40
58
  }),
@@ -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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"}
@@ -7,10 +7,27 @@ export interface CullLedgerEntry {
7
7
  matchedLine: string;
8
8
  reason: 'negative-control-fired';
9
9
  }
10
+ export interface WindtunnelDiagnostics {
11
+ /**
12
+ * Precision (TP/(TP+FP)) over labeled, surviving (non-culled,
13
+ * non-negative-control) firings. DESCRIPTIVE ONLY — informative even on
14
+ * no-claim verdicts ("culled 8/10, the 2 survivors were clean"). NEVER
15
+ * consulted for the gate decision and never mistakable for the certifying
16
+ * `precision`. null when no surviving firing is labeled.
17
+ */
18
+ survivorPrecision: number | null;
19
+ }
10
20
  export interface WindtunnelVerdict {
11
21
  verdict: WindtunnelVerdictKind;
12
- /** Precision over surviving rules (after cull). */
13
- precision: number;
22
+ /**
23
+ * Certifying precision claim. A real value ONLY on verdicts that make a
24
+ * precision claim: PASS (1.0) and confirmed-FP FAIL (the breaching value,
25
+ * which IS the evidence). `null` on every no-claim verdict (exposure-floor /
26
+ * cull-rate / needs-adjudication HONEST-NEGATIVE, and vacuous-control FAIL).
27
+ * `null` ⟺ no precision claim; `0` is reserved for a real all-FP measurement
28
+ * and NEVER means "not computed" (#2189 ruling, strategy-claude 2026-06-17).
29
+ */
30
+ precision: number | null;
14
31
  mintedRuleCount: number;
15
32
  culledCount: number;
16
33
  survivingRuleCount: number;
@@ -21,6 +38,8 @@ export interface WindtunnelVerdict {
21
38
  nonVacuity: boolean;
22
39
  /** Label ids of firings with no ground-truth label (operator adjudication required). */
23
40
  needsAdjudication: string[];
41
+ /** Separately-namespaced descriptive diagnostics — never part of the gate decision. */
42
+ diagnostics: WindtunnelDiagnostics;
24
43
  }
25
44
  export interface RuleFiring {
26
45
  ruleId: string;
@@ -58,13 +77,17 @@ export interface ScorerInput {
58
77
  * Score a wind-tunnel run. Pure function: no IO, no clock, no randomness.
59
78
  * Implements ADR-110 §4/§5 done-criterion exactly per spec invariants.
60
79
  *
61
- * Verdict ordering (highest precedence first):
62
- * 1. Exposure floor below minimumHONEST-NEGATIVE (masquerade guard)
63
- * 2. Cull rate exceeds thresholdHONEST-NEGATIVE (cull-laundering guard)
64
- * 3. Positive control does not fire its target FAIL (vacuous pass)
65
- * 4. Any firing labeled FPFAIL (precision < 1.0)
66
- * 5. Any unlabeled firing → HONEST-NEGATIVE (needs adjudication, not PASS)
67
- * 6. All labeled TP → PASS
80
+ * Verdict ordering (highest precedence first) — #2189 ruling:
81
+ * 1. Any firing labeled FPFAIL (confirmed FP is a claim; precision = breaching value)
82
+ * 2. Positive control does not fire its target FAIL (vacuous pass; precision = null)
83
+ * 3. Exposure floor below minimum HONEST-NEGATIVE (masquerade guard; precision = null)
84
+ * 4. Cull rate exceeds thresholdHONEST-NEGATIVE (cull-laundering guard; precision = null)
85
+ * 5. Any unlabeled firing → HONEST-NEGATIVE (needs adjudication, not PASS; precision = null)
86
+ * 6. All labeled TP → PASS (precision = 1.0)
87
+ *
88
+ * The FAIL tier (1–2) outranks the masquerade guards (3–4): a guard may only
89
+ * DEMOTE a would-be PASS, never UPGRADE a FAIL. survivorPrecision (diagnostics)
90
+ * carries the informative survivor ratio distinct from the certifying precision.
68
91
  */
69
92
  export declare function scoreWindtunnel(input: ScorerInput): WindtunnelVerdict;
70
93
  //# sourceMappingURL=windtunnel-scorer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"windtunnel-scorer.d.ts","sourceRoot":"","sources":["../../src/spine/windtunnel-scorer.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,iBAAiB,GAAG,MAAM,CAAC;AACxE,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,IAAI,CAAC;AAE3C,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,wBAAwB,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,qBAAqB,CAAC;IAC/B,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sHAAsH;IACtH,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,+DAA+D;IAC/D,UAAU,EAAE,OAAO,CAAC;IACpB,wFAAwF;IACxF,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC;IAChD,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mFAAmF;IACnF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,+EAA+E;IAC/E,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC3C,sBAAsB,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE;QACd,oBAAoB,EAAE,MAAM,CAAC;QAC7B,oBAAoB,EAAE,MAAM,CAAC;QAC7B,yBAAyB,EAAE,MAAM,CAAC;KACnC,CAAC;IACF,cAAc,EAAE;QACd,oBAAoB,EAAE,MAAM,CAAC;QAC7B,oBAAoB,EAAE,MAAM,CAAC;QAC7B,yBAAyB,EAAE,MAAM,CAAC;KACnC,CAAC;CACH;AAID;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,iBAAiB,CAuLrE"}
1
+ {"version":3,"file":"windtunnel-scorer.d.ts","sourceRoot":"","sources":["../../src/spine/windtunnel-scorer.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,iBAAiB,GAAG,MAAM,CAAC;AACxE,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,IAAI,CAAC;AAE3C,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,wBAAwB,CAAC;CAClC;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,qBAAqB,CAAC;IAC/B;;;;;;;OAOG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sHAAsH;IACtH,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,+DAA+D;IAC/D,UAAU,EAAE,OAAO,CAAC;IACpB,wFAAwF;IACxF,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,uFAAuF;IACvF,WAAW,EAAE,qBAAqB,CAAC;CACpC;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC;IAChD,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mFAAmF;IACnF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,+EAA+E;IAC/E,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC3C,sBAAsB,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE;QACd,oBAAoB,EAAE,MAAM,CAAC;QAC7B,oBAAoB,EAAE,MAAM,CAAC;QAC7B,yBAAyB,EAAE,MAAM,CAAC;KACnC,CAAC;IACF,cAAc,EAAE;QACd,oBAAoB,EAAE,MAAM,CAAC;QAC7B,oBAAoB,EAAE,MAAM,CAAC;QAC7B,yBAAyB,EAAE,MAAM,CAAC;KACnC,CAAC;CACH;AAID;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,iBAAiB,CAoMrE"}