@mmnto/totem 1.67.1 → 1.68.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/dist/capability/falsification.d.ts +18 -0
  2. package/dist/capability/falsification.d.ts.map +1 -0
  3. package/dist/capability/falsification.js +56 -0
  4. package/dist/capability/falsification.js.map +1 -0
  5. package/dist/capability/falsification.test.d.ts +2 -0
  6. package/dist/capability/falsification.test.d.ts.map +1 -0
  7. package/dist/capability/falsification.test.js +112 -0
  8. package/dist/capability/falsification.test.js.map +1 -0
  9. package/dist/capability/regenerate.d.ts +20 -0
  10. package/dist/capability/regenerate.d.ts.map +1 -0
  11. package/dist/capability/regenerate.js +0 -0
  12. package/dist/capability/regenerate.js.map +1 -0
  13. package/dist/capability/regenerate.test.d.ts +2 -0
  14. package/dist/capability/regenerate.test.d.ts.map +1 -0
  15. package/dist/capability/regenerate.test.js +136 -0
  16. package/dist/capability/regenerate.test.js.map +1 -0
  17. package/dist/capability/review-catch.d.ts +53 -0
  18. package/dist/capability/review-catch.d.ts.map +1 -0
  19. package/dist/capability/review-catch.js +92 -0
  20. package/dist/capability/review-catch.js.map +1 -0
  21. package/dist/capability/review-catch.test.d.ts +2 -0
  22. package/dist/capability/review-catch.test.d.ts.map +1 -0
  23. package/dist/capability/review-catch.test.js +90 -0
  24. package/dist/capability/review-catch.test.js.map +1 -0
  25. package/dist/capability/schema.d.ts +244 -0
  26. package/dist/capability/schema.d.ts.map +1 -0
  27. package/dist/capability/schema.js +141 -0
  28. package/dist/capability/schema.js.map +1 -0
  29. package/dist/capability/schema.test.d.ts +2 -0
  30. package/dist/capability/schema.test.d.ts.map +1 -0
  31. package/dist/capability/schema.test.js +93 -0
  32. package/dist/capability/schema.test.js.map +1 -0
  33. package/dist/index.d.ts +20 -0
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +10 -0
  36. package/dist/index.js.map +1 -1
  37. package/dist/spine/candidate-rule.d.ts +84 -0
  38. package/dist/spine/candidate-rule.d.ts.map +1 -0
  39. package/dist/spine/candidate-rule.js +68 -0
  40. package/dist/spine/candidate-rule.js.map +1 -0
  41. package/dist/spine/candidate-rule.test.d.ts +2 -0
  42. package/dist/spine/candidate-rule.test.d.ts.map +1 -0
  43. package/dist/spine/candidate-rule.test.js +40 -0
  44. package/dist/spine/candidate-rule.test.js.map +1 -0
  45. package/dist/spine/classify.d.ts +93 -0
  46. package/dist/spine/classify.d.ts.map +1 -0
  47. package/dist/spine/classify.js +190 -0
  48. package/dist/spine/classify.js.map +1 -0
  49. package/dist/spine/classify.test.d.ts +2 -0
  50. package/dist/spine/classify.test.d.ts.map +1 -0
  51. package/dist/spine/classify.test.js +302 -0
  52. package/dist/spine/classify.test.js.map +1 -0
  53. package/dist/spine/compile.d.ts +62 -0
  54. package/dist/spine/compile.d.ts.map +1 -0
  55. package/dist/spine/compile.js +204 -0
  56. package/dist/spine/compile.js.map +1 -0
  57. package/dist/spine/compile.test.d.ts +2 -0
  58. package/dist/spine/compile.test.d.ts.map +1 -0
  59. package/dist/spine/compile.test.js +327 -0
  60. package/dist/spine/compile.test.js.map +1 -0
  61. package/dist/spine/extract.d.ts +146 -0
  62. package/dist/spine/extract.d.ts.map +1 -0
  63. package/dist/spine/extract.js +227 -0
  64. package/dist/spine/extract.js.map +1 -0
  65. package/dist/spine/extract.test.d.ts +2 -0
  66. package/dist/spine/extract.test.d.ts.map +1 -0
  67. package/dist/spine/extract.test.js +382 -0
  68. package/dist/spine/extract.test.js.map +1 -0
  69. package/dist/spine/ledgers.d.ts +1102 -0
  70. package/dist/spine/ledgers.d.ts.map +1 -0
  71. package/dist/spine/ledgers.js +209 -0
  72. package/dist/spine/ledgers.js.map +1 -0
  73. package/dist/spine/miner-harness.d.ts +30 -0
  74. package/dist/spine/miner-harness.d.ts.map +1 -0
  75. package/dist/spine/miner-harness.js +214 -0
  76. package/dist/spine/miner-harness.js.map +1 -0
  77. package/dist/spine/miner-harness.test.d.ts +2 -0
  78. package/dist/spine/miner-harness.test.d.ts.map +1 -0
  79. package/dist/spine/miner-harness.test.js +231 -0
  80. package/dist/spine/miner-harness.test.js.map +1 -0
  81. package/dist/spine/split.d.ts +149 -0
  82. package/dist/spine/split.d.ts.map +1 -0
  83. package/dist/spine/split.js +235 -0
  84. package/dist/spine/split.js.map +1 -0
  85. package/dist/spine/split.test.d.ts +2 -0
  86. package/dist/spine/split.test.d.ts.map +1 -0
  87. package/dist/spine/split.test.js +142 -0
  88. package/dist/spine/split.test.js.map +1 -0
  89. package/dist/spine/windtunnel-lock.d.ts +8 -8
  90. package/package.json +1 -1
@@ -0,0 +1,231 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { runFalsificationHarness } from './miner-harness.js';
3
+ const sha = (n) => String(n).padStart(40, '0');
4
+ /**
5
+ * A contract-clean miner run: corpus [1,2,3,4], train [1,2] (both emitted),
6
+ * heldOut [3,4] (controls 3/4), no drops, no held-out fetches, seed-blind.
7
+ */
8
+ function greenLedgers() {
9
+ return {
10
+ emission: {
11
+ entries: [
12
+ {
13
+ candidateRef: 'c1',
14
+ provenance: { mergedPr: 1, reviewThread: 'rt-1', commitSha: sha(1) },
15
+ classifierDisposition: 'structural',
16
+ routing: 'compile',
17
+ classifierLedgerRef: 'cl-1',
18
+ unverified: true,
19
+ },
20
+ {
21
+ candidateRef: 'c2',
22
+ provenance: { mergedPr: 2, reviewThread: 'rt-2', commitSha: sha(2) },
23
+ classifierDisposition: 'structural',
24
+ routing: 'compile',
25
+ classifierLedgerRef: 'cl-2',
26
+ unverified: true,
27
+ },
28
+ ],
29
+ extractionInputsAttestation: { seedClassesProvided: false },
30
+ },
31
+ drop: { entries: [] },
32
+ classifier: {
33
+ entries: [
34
+ {
35
+ candidateRef: 'cl-1',
36
+ disposition: 'structural',
37
+ stage4Confirmed: true,
38
+ dispositionSource: 'classified',
39
+ stage4Outcome: 'confirmed',
40
+ },
41
+ {
42
+ candidateRef: 'cl-2',
43
+ disposition: 'structural',
44
+ stage4Confirmed: true,
45
+ dispositionSource: 'classified',
46
+ stage4Outcome: 'confirmed',
47
+ },
48
+ ],
49
+ },
50
+ split: {
51
+ split: {
52
+ asOfCommit: sha(100),
53
+ trainPrs: [1, 2],
54
+ heldOutPrs: [3, 4],
55
+ excludedPrs: [],
56
+ positiveControlPrs: [3],
57
+ negativeControlPrs: [4],
58
+ splitRule: { predicate: 'code-touching non-bot', cutIndex: 2 },
59
+ },
60
+ corpus: [1, 2, 3, 4],
61
+ corpusMergeCommits: [1, 2, 3, 4].map((pr) => ({ pr, mergeCommit: sha(pr) })),
62
+ },
63
+ apiUsage: {
64
+ entries: [
65
+ { targetPr: 1, slice: 'train', fetchKind: 'review-thread' },
66
+ { targetPr: 2, slice: 'train', fetchKind: 'review-thread' },
67
+ ],
68
+ heldOutFetchCount: 0,
69
+ },
70
+ };
71
+ }
72
+ // Deep clone via JSON so mutations don't bleed across cases (no Dates/fns here).
73
+ function clone(x) {
74
+ return JSON.parse(JSON.stringify(x));
75
+ }
76
+ /** Distinct FM clauses the harness reports for a raw ledger object, sorted. */
77
+ function clauses(raw) {
78
+ const r = runFalsificationHarness(raw);
79
+ return [...new Set(r.violations.map((v) => v.clause))].sort();
80
+ }
81
+ describe('runFalsificationHarness — green', () => {
82
+ it('passes a contract-clean miner run (no FM clause holds)', () => {
83
+ const r = runFalsificationHarness(greenLedgers());
84
+ expect(r.ok).toBe(true);
85
+ expect(r.violations).toEqual([]);
86
+ });
87
+ it('allows a train PR in BOTH the emission and drop ledgers (FM(i) is at-least-one, not XOR)', () => {
88
+ const g = clone(greenLedgers());
89
+ // PR 2 already has an emitted candidate (c2); a second candidate from the same
90
+ // PR's review thread is dropped — in-both is legitimate, not a violation.
91
+ g.drop.entries.push({ sourcePr: 2, reasonCode: 'truncated' });
92
+ expect(runFalsificationHarness(g).ok).toBe(true);
93
+ });
94
+ });
95
+ describe('runFalsificationHarness — each red fixture fails on EXACTLY its clause', () => {
96
+ it('(a) incomplete provenance tuple', () => {
97
+ const g = clone(greenLedgers());
98
+ delete g.emission.entries[0].provenance.commitSha;
99
+ expect(clauses(g)).toEqual(['a']);
100
+ });
101
+ it('(b) candidate minted non-unverified', () => {
102
+ const g = clone(greenLedgers());
103
+ g.emission.entries[0].unverified = false;
104
+ expect(clauses(g)).toEqual(['b']);
105
+ });
106
+ it('(c) behavioral candidate routed to compile', () => {
107
+ const g = clone(greenLedgers());
108
+ g.emission.entries[0].classifierDisposition = 'behavioral';
109
+ expect(clauses(g)).toEqual(['c']);
110
+ });
111
+ it('(c) emission disposition disagrees with the classifier ledger', () => {
112
+ const g = clone(greenLedgers());
113
+ g.classifier.entries[0].disposition = 'behavioral'; // emission cl-1 attests structural
114
+ g.emission.entries[0].routing = 'rag-only'; // isolate the mismatch from compile-routing
115
+ expect(clauses(g)).toEqual(['c']);
116
+ });
117
+ it('(d) out-of-corpus split member', () => {
118
+ const g = clone(greenLedgers());
119
+ g.split.split.heldOutPrs = [3, 4, 99];
120
+ g.split.corpusMergeCommits.push({ pr: 99, mergeCommit: sha(99) });
121
+ expect(clauses(g)).toEqual(['d']);
122
+ });
123
+ it('(e-split) control outside heldOut (slice disjointness)', () => {
124
+ const g = clone(greenLedgers());
125
+ g.split.split.positiveControlPrs = [1]; // a train PR, not in heldOut
126
+ expect(clauses(g)).toEqual(['e-split']);
127
+ });
128
+ it('(e-split) a PR tagged as both positive and negative control', () => {
129
+ const g = clone(greenLedgers());
130
+ g.split.split.negativeControlPrs = [3, 4]; // 3 is already a positive control
131
+ expect(clauses(g)).toEqual(['e-split']);
132
+ });
133
+ it('(e-emission) candidate sourced from a held-out PR', () => {
134
+ const g = clone(greenLedgers());
135
+ g.emission.entries.push({
136
+ candidateRef: 'c3',
137
+ provenance: { mergedPr: 3, reviewThread: 'rt-3', commitSha: sha(3) }, // PR 3 is held-out
138
+ classifierDisposition: 'structural',
139
+ routing: 'compile',
140
+ classifierLedgerRef: 'cl-3',
141
+ unverified: true,
142
+ });
143
+ g.classifier.entries.push({
144
+ candidateRef: 'cl-3',
145
+ disposition: 'structural',
146
+ stage4Confirmed: true,
147
+ dispositionSource: 'classified',
148
+ stage4Outcome: 'confirmed',
149
+ });
150
+ expect(clauses(g)).toEqual(['e-emission']);
151
+ });
152
+ it('(e-emission) provenance commitSha does not match the PR frozen merge commit', () => {
153
+ const g = clone(greenLedgers());
154
+ g.emission.entries[0].provenance.commitSha = sha(99); // PR 1's frozen merge commit is sha(1)
155
+ expect(clauses(g)).toEqual(['e-emission']);
156
+ });
157
+ it('(f) seed class supplied to extraction', () => {
158
+ const g = clone(greenLedgers());
159
+ g.emission.extractionInputsAttestation.seedClassesProvided = true;
160
+ expect(clauses(g)).toEqual(['f']);
161
+ });
162
+ it('(g) silent corpus drop', () => {
163
+ const g = clone(greenLedgers());
164
+ g.split.split.heldOutPrs = [3];
165
+ g.split.split.negativeControlPrs = [];
166
+ expect(clauses(g)).toEqual(['g']);
167
+ });
168
+ it('(h) held-out content fetch', () => {
169
+ const g = clone(greenLedgers());
170
+ g.apiUsage.heldOutFetchCount = 1;
171
+ expect(clauses(g)).toEqual(['h']);
172
+ });
173
+ it('(h) a held-out PR fetched under a mislabeled slice:train', () => {
174
+ const g = clone(greenLedgers());
175
+ // PR 3 is held-out; labeling the fetch "train" must NOT hide it (partition is derived).
176
+ g.apiUsage.entries.push({ targetPr: 3, slice: 'train', fetchKind: 'review-thread' });
177
+ expect(clauses(g)).toEqual(['h']);
178
+ });
179
+ it('(i) train PR processed by neither emission nor drop', () => {
180
+ const g = clone(greenLedgers());
181
+ g.emission.entries.pop(); // remove the PR 2 candidate, do not drop it either
182
+ g.classifier.entries.pop();
183
+ expect(clauses(g)).toEqual(['i']);
184
+ });
185
+ });
186
+ describe('runFalsificationHarness — stage4 consistency (slice 4; NOT an FM letter)', () => {
187
+ it('flags a confirmed outcome whose stage4Confirmed is false (the OQ4 red craft)', () => {
188
+ const g = clone(greenLedgers());
189
+ g.classifier.entries[0].stage4Confirmed = false; // still stage4Outcome: 'confirmed'
190
+ expect(clauses(g)).toEqual(['stage4-consistency']);
191
+ });
192
+ it('flags stage4Confirmed:true with no recorded outcome (cannot be confirmed without evidence)', () => {
193
+ const g = clone(greenLedgers());
194
+ delete g.classifier.entries[0].stage4Outcome;
195
+ expect(clauses(g)).toEqual(['stage4-consistency']);
196
+ });
197
+ it('flags a compile-rejected outcome marked stage4Confirmed:true', () => {
198
+ const g = clone(greenLedgers());
199
+ g.classifier.entries[0].stage4Outcome = 'compile-rejected'; // stage4Confirmed still true
200
+ expect(clauses(g)).toEqual(['stage4-consistency']);
201
+ });
202
+ it('passes archived-out-of-scope with stage4Confirmed:false (legitimately unconfirmed — agy fold-3)', () => {
203
+ const g = clone(greenLedgers());
204
+ g.classifier.entries[0].stage4Confirmed = false;
205
+ g.classifier.entries[0].stage4Outcome = 'archived-out-of-scope';
206
+ expect(runFalsificationHarness(g).ok).toBe(true);
207
+ });
208
+ it('passes untested-no-matches with stage4Confirmed:false (legitimately unconfirmed)', () => {
209
+ const g = clone(greenLedgers());
210
+ g.classifier.entries[0].stage4Confirmed = false;
211
+ g.classifier.entries[0].stage4Outcome = 'untested-no-matches';
212
+ expect(runFalsificationHarness(g).ok).toBe(true);
213
+ });
214
+ });
215
+ describe('runFalsificationHarness — schema completeness', () => {
216
+ it('rejects a split ledger whose corpusMergeCommits omits a corpus PR', () => {
217
+ const g = clone(greenLedgers());
218
+ g.split.corpusMergeCommits = g.split.corpusMergeCommits.filter((e) => e.pr !== 3);
219
+ const r = runFalsificationHarness(g);
220
+ expect(r.ok).toBe(false);
221
+ expect(r.violations.some((v) => v.clause === 'schema')).toBe(true);
222
+ });
223
+ it('rejects a non-SHA mergeCommit in the split ledger', () => {
224
+ const g = clone(greenLedgers());
225
+ g.split.corpusMergeCommits[0].mergeCommit = 'not-a-sha';
226
+ const r = runFalsificationHarness(g);
227
+ expect(r.ok).toBe(false);
228
+ expect(r.violations.some((v) => v.clause === 'schema')).toBe(true);
229
+ });
230
+ });
231
+ //# sourceMappingURL=miner-harness.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"miner-harness.test.js","sourceRoot":"","sources":["../../src/spine/miner-harness.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,149 @@
1
+ import { z } from 'zod';
2
+ import { type PrMeta, type PrSetDiff } from './selection-rule.js';
3
+ /**
4
+ * ADR-111 §5 — the frozen split artifact, committed before extraction. The
5
+ * concrete `cutIndex` is the deferred window-open scalar (Deferred Decisions);
6
+ * the field is required in the committed artifact, only its value is deferred.
7
+ */
8
+ export declare const SplitArtifactSchema: z.ZodEffects<z.ZodObject<{
9
+ asOfCommit: z.ZodString;
10
+ /** The OLDER ancestry segment — the mining slice. */
11
+ trainPrs: z.ZodArray<z.ZodNumber, "many">;
12
+ /** The NEWER held-out segment — control evaluation. Controls are tags within this. */
13
+ heldOutPrs: z.ZodArray<z.ZodNumber, "many">;
14
+ /** Explicitly enumerated drops (the atomic revert pairs). */
15
+ excludedPrs: z.ZodArray<z.ZodNumber, "many">;
16
+ /** Positive controls — a designated subset (tag) of `heldOutPrs`, never a separate cover bucket. */
17
+ positiveControlPrs: z.ZodArray<z.ZodNumber, "many">;
18
+ /** Negative controls — a designated subset (tag) of `heldOutPrs`. */
19
+ negativeControlPrs: z.ZodArray<z.ZodNumber, "many">;
20
+ splitRule: z.ZodObject<{
21
+ /** Human-readable predicate expression that generated the corpus (mirrors the windtunnel lock's `selectionRule.predicate`). */
22
+ predicate: z.ZodEffects<z.ZodString, string, string>;
23
+ /**
24
+ * Forward-chronological ancestry cut: `trainPrs` = the `cutIndex` OLDEST
25
+ * corpus PRs (ancestry order), `heldOutPrs` = the newer remainder. Concrete
26
+ * value deferred to window-open (ADR-111 Deferred Decisions).
27
+ */
28
+ cutIndex: z.ZodNumber;
29
+ }, "strip", z.ZodTypeAny, {
30
+ predicate: string;
31
+ cutIndex: number;
32
+ }, {
33
+ predicate: string;
34
+ cutIndex: number;
35
+ }>;
36
+ }, "strip", z.ZodTypeAny, {
37
+ asOfCommit: string;
38
+ trainPrs: number[];
39
+ heldOutPrs: number[];
40
+ excludedPrs: number[];
41
+ positiveControlPrs: number[];
42
+ negativeControlPrs: number[];
43
+ splitRule: {
44
+ predicate: string;
45
+ cutIndex: number;
46
+ };
47
+ }, {
48
+ asOfCommit: string;
49
+ trainPrs: number[];
50
+ heldOutPrs: number[];
51
+ excludedPrs: number[];
52
+ positiveControlPrs: number[];
53
+ negativeControlPrs: number[];
54
+ splitRule: {
55
+ predicate: string;
56
+ cutIndex: number;
57
+ };
58
+ }>, {
59
+ asOfCommit: string;
60
+ trainPrs: number[];
61
+ heldOutPrs: number[];
62
+ excludedPrs: number[];
63
+ positiveControlPrs: number[];
64
+ negativeControlPrs: number[];
65
+ splitRule: {
66
+ predicate: string;
67
+ cutIndex: number;
68
+ };
69
+ }, {
70
+ asOfCommit: string;
71
+ trainPrs: number[];
72
+ heldOutPrs: number[];
73
+ excludedPrs: number[];
74
+ positiveControlPrs: number[];
75
+ negativeControlPrs: number[];
76
+ splitRule: {
77
+ predicate: string;
78
+ cutIndex: number;
79
+ };
80
+ }>;
81
+ export type SplitArtifact = z.infer<typeof SplitArtifactSchema>;
82
+ /** Thrown when `resolveSplit` cannot produce a clean three-way disjoint cover (Tenet 4, fail-loud). */
83
+ export declare class SplitCoverError extends Error {
84
+ readonly result: SplitCoverResult;
85
+ constructor(result: SplitCoverResult);
86
+ }
87
+ /** Structured result of the §5/§8 split-ledger mechanical check. `ok` iff every diagnostic list is empty. */
88
+ export interface SplitCoverResult {
89
+ ok: boolean;
90
+ /**
91
+ * Cover vs the frozen corpus, direction-disambiguated so each side falsifies
92
+ * its own clause: `missing` = a corpus PR assigned to no slice (FM(g), silent
93
+ * drop); `extra` = a slice PR outside the corpus (FM(d), out-of-corpus member).
94
+ */
95
+ cover: PrSetDiff;
96
+ /** Pairwise PR# intersections of {train, heldOut, excluded} that must be empty (the `⊎` disjointness). */
97
+ overlaps: {
98
+ trainHeldOut: number[];
99
+ trainExcluded: number[];
100
+ heldOutExcluded: number[];
101
+ };
102
+ /** Control PRs not contained in `heldOutPrs` — controls must be tags WITHIN heldOut, not a separate bucket. */
103
+ controlsOutsideHeldOut: number[];
104
+ /** PRs tagged as BOTH a positive and a negative control — a PR cannot be both (per-rule control coherence). */
105
+ controlOverlap: number[];
106
+ /** Merge-commit SHAs appearing in more than one slice — disjoint by merge-commit, not only PR# (revert/target straddle guard). */
107
+ mergeCommitCollisions: string[];
108
+ }
109
+ /**
110
+ * The §8 split-ledger check: verifies the split is a three-way disjoint cover of
111
+ * `corpus` (= `selectionRule(asOfCommit)`), that the controls are tags within
112
+ * `heldOutPrs`, and that the slices are disjoint by merge-commit (not only PR#).
113
+ * Pure; the harness asserts `ok` and reads the per-field diffs to pin the exact
114
+ * Falsifying-Metric clause (FM(d) extra / FM(g) missing).
115
+ */
116
+ export declare function validateSplitCover(split: SplitArtifact, corpus: number[], mergeCommitByPr: ReadonlyMap<number, string>): SplitCoverResult;
117
+ /**
118
+ * Produce a frozen split from the resolved corpus by the forward-chronological
119
+ * ancestry cut. `corpus` is `selectionRule(asOfCommit)` (the cover base);
120
+ * `orderedNewestFirst` is the same ancestry enumeration `resolveSelectionRule`
121
+ * consumes (`git log --topo-order`, newest-first) and MUST cover the corpus.
122
+ * `excludedPrs` (the atomic revert pairs) are removed from train/heldOut but
123
+ * remain in the cover. Validates the result and throws `SplitCoverError` on any
124
+ * cover/disjointness violation (Tenet 4) — a malformed split never freezes.
125
+ *
126
+ * CONTRACT (corpus-scope model A, confirmed by totem-codex's #2200 review; pending
127
+ * strategy-claude's final §5 word): `corpus` is the cover BASE that INCLUDES the
128
+ * PRs later assigned to `excludedPrs` — i.e. `selectionRule` is resolved here with
129
+ * reverts retained, and `excludedPrs` enumerates them explicitly, so
130
+ * `train ⊎ heldOut ⊎ excluded == corpus` holds and every `excludedPr` is a corpus
131
+ * member. (The alternative — `selectionRule(asOfCommit)` pre-excludes reverts yet
132
+ * the split still records them in `excludedPrs` — is NOT supported by the current
133
+ * schema, which rejects excluded PRs outside the corpus; revisit only if strategy
134
+ * pins that model.) The fail-loud `excludedPrs ⊆ corpus` guard below enforces this.
135
+ */
136
+ export declare function resolveSplit(params: {
137
+ asOfCommit: string;
138
+ corpus: number[];
139
+ orderedNewestFirst: number[];
140
+ excludedPrs: number[];
141
+ cutIndex: number;
142
+ positiveControlPrs?: number[];
143
+ negativeControlPrs?: number[];
144
+ predicate: string;
145
+ mergeCommitByPr: ReadonlyMap<number, string>;
146
+ }): SplitArtifact;
147
+ /** Re-export for callers building the `mergeCommitByPr` map from enumerated metas. */
148
+ export declare function mergeCommitMap(metas: PrMeta[]): Map<number, string>;
149
+ //# sourceMappingURL=split.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"split.d.ts","sourceRoot":"","sources":["../../src/spine/split.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAc,KAAK,MAAM,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAO9E;;;;GAIG;AACH,eAAO,MAAM,mBAAmB;;IAG5B,qDAAqD;;IAErD,sFAAsF;;IAEtF,6DAA6D;;IAE7D,oGAAoG;;IAEpG,qEAAqE;;;QAGnE,+HAA+H;;QAI/H;;;;WAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwBL,CAAC;AAEL,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,uGAAuG;AACvG,qBAAa,eAAgB,SAAQ,KAAK;aACZ,MAAM,EAAE,gBAAgB;gBAAxB,MAAM,EAAE,gBAAgB;CAMrD;AAED,6GAA6G;AAC7G,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ;;;;OAIG;IACH,KAAK,EAAE,SAAS,CAAC;IACjB,0GAA0G;IAC1G,QAAQ,EAAE;QAAE,YAAY,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,EAAE,MAAM,EAAE,CAAC;QAAC,eAAe,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACzF,+GAA+G;IAC/G,sBAAsB,EAAE,MAAM,EAAE,CAAC;IACjC,+GAA+G;IAC/G,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kIAAkI;IAClI,qBAAqB,EAAE,MAAM,EAAE,CAAC;CACjC;AA0BD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,MAAM,EAAE,EAChB,eAAe,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3C,gBAAgB,CA6BlB;AAuBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9C,GAAG,aAAa,CAiEhB;AAED,sFAAsF;AACtF,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAEnE"}
@@ -0,0 +1,235 @@
1
+ // ─── ADR-111 §5 Gate-1 train/test split — frozen, ancestry-ordered ──────────
2
+ //
3
+ // The mining/control split over the frozen corpus `selectionRule(asOfCommit)`
4
+ // (ADR-110 §6). Committed as a lock BEFORE extraction; `trainPrs` = the OLDER
5
+ // ancestry segment (mining), `heldOutPrs` = the NEWER held-out segment
6
+ // (control) — forward-chronological, never a random shuffle (reverse-causality
7
+ // leakage) and never commit-date (rebase-rewritable; the same `--topo-order`
8
+ // invariant as #2197). The split is a THREE-WAY DISJOINT COVER of the corpus:
9
+ // `trainPrs ⊎ heldOutPrs ⊎ excludedPrs == selectionRule(asOfCommit)`, with the
10
+ // positive/negative controls as designated tags WITHIN `heldOutPrs` (never a
11
+ // separate cover bucket). Total accounting (FM (d)/(g)): a corpus PR in no slice
12
+ // is a silent drop; a slice PR outside the corpus is an out-of-corpus member.
13
+ //
14
+ // This module is the pure schema + the deterministic cover validator (the §8
15
+ // split-ledger check) + the forward-ancestry-cut producer. IO (git enumeration
16
+ // → PrMeta) lives in the cli layer, as with `selection-rule.ts`.
17
+ import { z } from 'zod';
18
+ import { diffPrSets } from './selection-rule.js';
19
+ /** Lowercase 40-hex git commit SHA — canonical git form (cf. compiler-schema `COMMIT_SHA_RE`). */
20
+ const COMMIT_SHA_RE = /^[0-9a-f]{40}$/;
21
+ const PrNumber = z.number().int().positive();
22
+ /**
23
+ * ADR-111 §5 — the frozen split artifact, committed before extraction. The
24
+ * concrete `cutIndex` is the deferred window-open scalar (Deferred Decisions);
25
+ * the field is required in the committed artifact, only its value is deferred.
26
+ */
27
+ export const SplitArtifactSchema = z
28
+ .object({
29
+ asOfCommit: z.string().regex(COMMIT_SHA_RE),
30
+ /** The OLDER ancestry segment — the mining slice. */
31
+ trainPrs: z.array(PrNumber),
32
+ /** The NEWER held-out segment — control evaluation. Controls are tags within this. */
33
+ heldOutPrs: z.array(PrNumber),
34
+ /** Explicitly enumerated drops (the atomic revert pairs). */
35
+ excludedPrs: z.array(PrNumber),
36
+ /** Positive controls — a designated subset (tag) of `heldOutPrs`, never a separate cover bucket. */
37
+ positiveControlPrs: z.array(PrNumber),
38
+ /** Negative controls — a designated subset (tag) of `heldOutPrs`. */
39
+ negativeControlPrs: z.array(PrNumber),
40
+ splitRule: z.object({
41
+ /** Human-readable predicate expression that generated the corpus (mirrors the windtunnel lock's `selectionRule.predicate`). */
42
+ predicate: z.string().refine((s) => s.trim().length > 0, {
43
+ message: 'splitRule.predicate must be a non-empty expression',
44
+ }),
45
+ /**
46
+ * Forward-chronological ancestry cut: `trainPrs` = the `cutIndex` OLDEST
47
+ * corpus PRs (ancestry order), `heldOutPrs` = the newer remainder. Concrete
48
+ * value deferred to window-open (ADR-111 Deferred Decisions).
49
+ */
50
+ cutIndex: z.number().int().nonnegative(),
51
+ }),
52
+ })
53
+ .superRefine((s, ctx) => {
54
+ // Disjoint cover is a BAG/ROW property, but the cover/overlap checks dedupe via
55
+ // Set semantics — so a duplicate row (e.g. trainPrs [1,1,2]) would slip through.
56
+ // Reject duplicates within each slice/control list at the schema boundary.
57
+ const lists = [
58
+ ['trainPrs', s.trainPrs],
59
+ ['heldOutPrs', s.heldOutPrs],
60
+ ['excludedPrs', s.excludedPrs],
61
+ ['positiveControlPrs', s.positiveControlPrs],
62
+ ['negativeControlPrs', s.negativeControlPrs],
63
+ ];
64
+ for (const [field, arr] of lists) {
65
+ if (new Set(arr).size !== arr.length) {
66
+ ctx.addIssue({
67
+ code: z.ZodIssueCode.custom,
68
+ message: `${field} contains duplicate PRs`,
69
+ path: [field],
70
+ });
71
+ }
72
+ }
73
+ });
74
+ /** Thrown when `resolveSplit` cannot produce a clean three-way disjoint cover (Tenet 4, fail-loud). */
75
+ export class SplitCoverError extends Error {
76
+ result;
77
+ constructor(result) {
78
+ super(`[Totem Error] split is not a valid disjoint cover of selectionRule(asOfCommit): ${summarizeCover(result)}`);
79
+ this.result = result;
80
+ this.name = 'SplitCoverError';
81
+ }
82
+ }
83
+ function uniqueSorted(xs) {
84
+ return [...new Set(xs)].sort((a, b) => a - b);
85
+ }
86
+ function intersect(a, b) {
87
+ const bs = new Set(b);
88
+ return uniqueSorted(a.filter((x) => bs.has(x)));
89
+ }
90
+ function summarizeCover(r) {
91
+ const parts = [];
92
+ if (r.cover.missing.length)
93
+ parts.push(`missing(FM-g)=[${r.cover.missing}]`);
94
+ if (r.cover.extra.length)
95
+ parts.push(`extra(FM-d)=[${r.cover.extra}]`);
96
+ if (r.overlaps.trainHeldOut.length)
97
+ parts.push(`train∩heldOut=[${r.overlaps.trainHeldOut}]`);
98
+ if (r.overlaps.trainExcluded.length)
99
+ parts.push(`train∩excluded=[${r.overlaps.trainExcluded}]`);
100
+ if (r.overlaps.heldOutExcluded.length)
101
+ parts.push(`heldOut∩excluded=[${r.overlaps.heldOutExcluded}]`);
102
+ if (r.controlsOutsideHeldOut.length)
103
+ parts.push(`controls⊄heldOut=[${r.controlsOutsideHeldOut}]`);
104
+ if (r.controlOverlap.length)
105
+ parts.push(`pos∩neg=[${r.controlOverlap}]`);
106
+ if (r.mergeCommitCollisions.length)
107
+ parts.push(`mergeCommitCollisions=[${r.mergeCommitCollisions}]`);
108
+ return parts.join(' ');
109
+ }
110
+ /**
111
+ * The §8 split-ledger check: verifies the split is a three-way disjoint cover of
112
+ * `corpus` (= `selectionRule(asOfCommit)`), that the controls are tags within
113
+ * `heldOutPrs`, and that the slices are disjoint by merge-commit (not only PR#).
114
+ * Pure; the harness asserts `ok` and reads the per-field diffs to pin the exact
115
+ * Falsifying-Metric clause (FM(d) extra / FM(g) missing).
116
+ */
117
+ export function validateSplitCover(split, corpus, mergeCommitByPr) {
118
+ const union = [...split.trainPrs, ...split.heldOutPrs, ...split.excludedPrs];
119
+ const cover = diffPrSets(corpus, union); // missing ⇒ FM(g), extra ⇒ FM(d)
120
+ const overlaps = {
121
+ trainHeldOut: intersect(split.trainPrs, split.heldOutPrs),
122
+ trainExcluded: intersect(split.trainPrs, split.excludedPrs),
123
+ heldOutExcluded: intersect(split.heldOutPrs, split.excludedPrs),
124
+ };
125
+ const heldOutSet = new Set(split.heldOutPrs);
126
+ const controlsOutsideHeldOut = uniqueSorted([...split.positiveControlPrs, ...split.negativeControlPrs].filter((pr) => !heldOutSet.has(pr)));
127
+ const controlOverlap = intersect(split.positiveControlPrs, split.negativeControlPrs);
128
+ const mergeCommitCollisions = mergeCommitCollisionsAcrossSlices(split, mergeCommitByPr);
129
+ const ok = cover.missing.length === 0 &&
130
+ cover.extra.length === 0 &&
131
+ overlaps.trainHeldOut.length === 0 &&
132
+ overlaps.trainExcluded.length === 0 &&
133
+ overlaps.heldOutExcluded.length === 0 &&
134
+ controlsOutsideHeldOut.length === 0 &&
135
+ controlOverlap.length === 0 &&
136
+ mergeCommitCollisions.length === 0;
137
+ return { ok, cover, overlaps, controlsOutsideHeldOut, controlOverlap, mergeCommitCollisions };
138
+ }
139
+ /** SHAs whose owning PRs land in >1 slice. With 1:1 PR→SHA this also catches a malformed straddle. */
140
+ function mergeCommitCollisionsAcrossSlices(split, mergeCommitByPr) {
141
+ const slices = [split.trainPrs, split.heldOutPrs, split.excludedPrs];
142
+ const shaSliceCount = new Map();
143
+ for (const slice of slices) {
144
+ const shasInSlice = new Set();
145
+ for (const pr of slice) {
146
+ const sha = mergeCommitByPr.get(pr);
147
+ if (sha !== undefined)
148
+ shasInSlice.add(sha);
149
+ }
150
+ for (const sha of shasInSlice)
151
+ shaSliceCount.set(sha, (shaSliceCount.get(sha) ?? 0) + 1);
152
+ }
153
+ return [...shaSliceCount.entries()]
154
+ .filter(([, n]) => n > 1)
155
+ .map(([sha]) => sha)
156
+ .sort();
157
+ }
158
+ /**
159
+ * Produce a frozen split from the resolved corpus by the forward-chronological
160
+ * ancestry cut. `corpus` is `selectionRule(asOfCommit)` (the cover base);
161
+ * `orderedNewestFirst` is the same ancestry enumeration `resolveSelectionRule`
162
+ * consumes (`git log --topo-order`, newest-first) and MUST cover the corpus.
163
+ * `excludedPrs` (the atomic revert pairs) are removed from train/heldOut but
164
+ * remain in the cover. Validates the result and throws `SplitCoverError` on any
165
+ * cover/disjointness violation (Tenet 4) — a malformed split never freezes.
166
+ *
167
+ * CONTRACT (corpus-scope model A, confirmed by totem-codex's #2200 review; pending
168
+ * strategy-claude's final §5 word): `corpus` is the cover BASE that INCLUDES the
169
+ * PRs later assigned to `excludedPrs` — i.e. `selectionRule` is resolved here with
170
+ * reverts retained, and `excludedPrs` enumerates them explicitly, so
171
+ * `train ⊎ heldOut ⊎ excluded == corpus` holds and every `excludedPr` is a corpus
172
+ * member. (The alternative — `selectionRule(asOfCommit)` pre-excludes reverts yet
173
+ * the split still records them in `excludedPrs` — is NOT supported by the current
174
+ * schema, which rejects excluded PRs outside the corpus; revisit only if strategy
175
+ * pins that model.) The fail-loud `excludedPrs ⊆ corpus` guard below enforces this.
176
+ */
177
+ export function resolveSplit(params) {
178
+ const corpusSet = new Set(params.corpus);
179
+ const excludedSet = new Set(params.excludedPrs);
180
+ // Corpus PRs in ancestry order, newest-first, deduped — then reversed to oldest-first.
181
+ const seen = new Set();
182
+ const newestFirstCorpus = [];
183
+ for (const pr of params.orderedNewestFirst) {
184
+ if (!corpusSet.has(pr) || seen.has(pr))
185
+ continue;
186
+ seen.add(pr);
187
+ newestFirstCorpus.push(pr);
188
+ }
189
+ const ordering = diffPrSets(params.corpus, newestFirstCorpus);
190
+ if (ordering.missing.length > 0) {
191
+ throw new Error(`[Totem Error] resolveSplit: orderedNewestFirst does not cover the corpus (missing ancestry order for [${ordering.missing}])`);
192
+ }
193
+ // The merge-commit collision check silently skips PRs absent from the map, so a
194
+ // partial map would weaken the disjoint-by-merge-commit guard — require coverage.
195
+ const missingMergeCommits = params.corpus.filter((pr) => !params.mergeCommitByPr.has(pr));
196
+ if (missingMergeCommits.length > 0) {
197
+ throw new Error(`[Totem Error] resolveSplit: mergeCommitByPr does not cover the corpus (missing merge commits for [${missingMergeCommits}])`);
198
+ }
199
+ // excludedPrs MUST be corpus-scoped revert pairs (ADR-111 §5: every listed PR is
200
+ // a corpus member). A non-corpus entry is a caller contract violation — fail loud
201
+ // (NOT silently filtered, which would hide the error and break total accounting).
202
+ const nonCorpusExcluded = params.excludedPrs.filter((pr) => !corpusSet.has(pr));
203
+ if (nonCorpusExcluded.length > 0) {
204
+ throw new Error(`[Totem Error] resolveSplit: excludedPrs contains PRs outside the corpus [${nonCorpusExcluded}] — excludedPrs must be corpus-scoped (ADR-111 §5)`);
205
+ }
206
+ const oldestFirstNonExcluded = [...newestFirstCorpus]
207
+ .reverse()
208
+ .filter((pr) => !excludedSet.has(pr));
209
+ // A certifying split needs BOTH a non-empty train slice and a non-empty held-out
210
+ // slice — cutIndex 0 (empty train) or == size (empty held-out, which `slice`
211
+ // reaches by silent clamp) makes the train/test contract vacuous. Fail loud.
212
+ if (params.cutIndex <= 0 || params.cutIndex >= oldestFirstNonExcluded.length) {
213
+ throw new Error(`[Totem Error] resolveSplit: cutIndex ${params.cutIndex} must be strictly between 0 and the non-excluded corpus size ${oldestFirstNonExcluded.length} (non-empty train + held-out)`);
214
+ }
215
+ const trainPrs = uniqueSorted(oldestFirstNonExcluded.slice(0, params.cutIndex));
216
+ const heldOutPrs = uniqueSorted(oldestFirstNonExcluded.slice(params.cutIndex));
217
+ const split = SplitArtifactSchema.parse({
218
+ asOfCommit: params.asOfCommit,
219
+ trainPrs,
220
+ heldOutPrs,
221
+ excludedPrs: uniqueSorted(params.excludedPrs),
222
+ positiveControlPrs: uniqueSorted(params.positiveControlPrs ?? []),
223
+ negativeControlPrs: uniqueSorted(params.negativeControlPrs ?? []),
224
+ splitRule: { predicate: params.predicate, cutIndex: params.cutIndex },
225
+ });
226
+ const validation = validateSplitCover(split, params.corpus, params.mergeCommitByPr);
227
+ if (!validation.ok)
228
+ throw new SplitCoverError(validation);
229
+ return split;
230
+ }
231
+ /** Re-export for callers building the `mergeCommitByPr` map from enumerated metas. */
232
+ export function mergeCommitMap(metas) {
233
+ return new Map(metas.map((m) => [m.pr, m.mergeCommit]));
234
+ }
235
+ //# sourceMappingURL=split.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"split.js","sourceRoot":"","sources":["../../src/spine/split.ts"],"names":[],"mappings":"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"}