@mmnto/totem 1.79.0 → 1.81.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 (43) hide show
  1. package/dist/compiler-schema.d.ts +1635 -256
  2. package/dist/compiler-schema.d.ts.map +1 -1
  3. package/dist/compiler-schema.js +110 -10
  4. package/dist/compiler-schema.js.map +1 -1
  5. package/dist/compiler-schema.test.js +164 -7
  6. package/dist/compiler-schema.test.js.map +1 -1
  7. package/dist/compiler.d.ts +1 -1
  8. package/dist/compiler.d.ts.map +1 -1
  9. package/dist/compiler.js +1 -1
  10. package/dist/compiler.js.map +1 -1
  11. package/dist/config-schema.d.ts +6 -6
  12. package/dist/index.d.ts +7 -3
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +4 -2
  15. package/dist/index.js.map +1 -1
  16. package/dist/spine/authored-rule.d.ts +1030 -32
  17. package/dist/spine/authored-rule.d.ts.map +1 -1
  18. package/dist/spine/authored-rule.js +115 -1
  19. package/dist/spine/authored-rule.js.map +1 -1
  20. package/dist/spine/authored-rule.test.js +10 -4
  21. package/dist/spine/authored-rule.test.js.map +1 -1
  22. package/dist/spine/authoring-ledger.d.ts +204 -0
  23. package/dist/spine/authoring-ledger.d.ts.map +1 -0
  24. package/dist/spine/authoring-ledger.js +220 -0
  25. package/dist/spine/authoring-ledger.js.map +1 -0
  26. package/dist/spine/authoring-ledger.test.d.ts +2 -0
  27. package/dist/spine/authoring-ledger.test.d.ts.map +1 -0
  28. package/dist/spine/authoring-ledger.test.js +144 -0
  29. package/dist/spine/authoring-ledger.test.js.map +1 -0
  30. package/dist/spine/compile.test.js +5 -2
  31. package/dist/spine/compile.test.js.map +1 -1
  32. package/dist/spine/corpus-dispositions.d.ts +4 -4
  33. package/dist/spine/preimage-differential.d.ts +112 -0
  34. package/dist/spine/preimage-differential.d.ts.map +1 -0
  35. package/dist/spine/preimage-differential.js +122 -0
  36. package/dist/spine/preimage-differential.js.map +1 -0
  37. package/dist/spine/preimage-differential.test.d.ts +2 -0
  38. package/dist/spine/preimage-differential.test.d.ts.map +1 -0
  39. package/dist/spine/preimage-differential.test.js +223 -0
  40. package/dist/spine/preimage-differential.test.js.map +1 -0
  41. package/dist/spine/windtunnel-lock.d.ts +6 -6
  42. package/dist/store/lance-schema.d.ts +2 -2
  43. package/package.json +1 -1
@@ -0,0 +1,112 @@
1
+ /**
2
+ * ADR-112 §4/§6 — the preimage-differential materializer (slice C1: the inert primitive).
3
+ *
4
+ * An authored rule is only a legitimate positive control if its matcher **fires
5
+ * on the defect preimage** and is **silent on the fixed postimage** (§4). A
6
+ * matcher that fires on the *fixed* form is "fix-shaped" — the exact failure
7
+ * mode the miner's honest-negative is made of — and must never be admitted as a
8
+ * legitimate control (Falsifying Metric §1(i)).
9
+ *
10
+ * This module evaluates that differential against a fixture's declared
11
+ * `preimageSource` (lesson-anchored PRIMARY / commit-pair FALLBACK) and reports
12
+ * the raw evidence + a differential-level classification. It is deliberately
13
+ * INERT: it wires nothing into the cert path, mints no §5 run verdict, and emits
14
+ * no controls. Slice C2 consumes this to gate control emission; slice D maps the
15
+ * differential to the ADR-110 §5 terminal vocabulary (PASS / FAIL /
16
+ * HONEST-NEGATIVE). The boundary is load-bearing — `over-match` / `vacuous` here
17
+ * are DIFFERENTIAL outcomes, NOT run verdicts (the scorer owns that).
18
+ *
19
+ * Seam (Tenet-21 reuse): firing goes through `runSmokeGate`, the same
20
+ * role-agnostic engine entry point the compiler's #1408 under-match / #1580
21
+ * over-match checks use — regex and ast-grep, in-memory, no temp file, no diff
22
+ * fabrication, no `firingLabelId` minted here. The lesson source evaluates
23
+ * against the in-record `badExample`/`goodExample` exemplars (contract §5.4), so
24
+ * the lesson path is pure and hermetic — no clock, no network, no filesystem.
25
+ */
26
+ import type { AuthoredFixture, CompiledRule, PreimageSource } from '../compiler-schema.js';
27
+ /**
28
+ * Differential-level classification of a single fixture's preimage/postimage
29
+ * evaluation. NOT an ADR-110 §5 run verdict (PASS/FAIL/HONEST-NEGATIVE) — the
30
+ * scorer (slice D) maps these to that vocabulary. Keep the boundary explicit.
31
+ */
32
+ export type PreimageDifferentialOutcome =
33
+ /** Fires on the preimage, silent on the postimage — the legitimate positive control (§4). */
34
+ 'differential-holds'
35
+ /**
36
+ * Fires on the postimage (the fixed form) and NOT on the preimage — fix-shaped,
37
+ * the literal Falsifying Metric §1(i). Never a charitable pass.
38
+ */
39
+ | 'fix-shaped'
40
+ /**
41
+ * Fires on BOTH the preimage and the postimage. The matcher establishes no
42
+ * differential. This is the cert-critical escape the scorer cannot catch on a
43
+ * synthetic exemplar (its positive-control check is fire-on-preimage only, and
44
+ * a single-occurrence defect's fixed form never appears in the real window) —
45
+ * so the silent-on-postimage leg here is the ONLY signal that surfaces it
46
+ * (contract review, ADR-112 §4/§5.3). C2 must gate on it.
47
+ */
48
+ | 'over-match'
49
+ /** Fires on NEITHER side — the matcher catches nothing (a vacuous control). */
50
+ | 'vacuous-silent'
51
+ /**
52
+ * The engine refused to execute on at least one side (invalid regex, ast-grep
53
+ * runtime throw, an unparseable exemplar, or an engine the smoke gate does not
54
+ * cover) — the differential could not be established. Fail-loud, distinct from
55
+ * a clean no-match; routes to operator adjudication, never a silent pass.
56
+ */
57
+ | 'needs-adjudication'
58
+ /**
59
+ * The fixture declares a `commit`-pair preimage source — deferred to slice C2
60
+ * (the land-then-fix fallback; lc cert-#1 is lesson-anchored). A typed
61
+ * non-pass that keeps the union total; never treated as a passing control.
62
+ */
63
+ | 'unsupported-source';
64
+ export interface PreimageDifferentialResult {
65
+ /** The differential-level classification (see `PreimageDifferentialOutcome`). */
66
+ outcome: PreimageDifferentialOutcome;
67
+ /** The fixture's declared preimage-source kind. */
68
+ sourceKind: PreimageSource['kind'];
69
+ /**
70
+ * The matcher fired on the defect preimage. `null` when the preimage could not
71
+ * be evaluated (engine refusal, or an unsupported `commit` source).
72
+ */
73
+ firesOnPreimage: boolean | null;
74
+ /**
75
+ * The matcher stayed silent on the fixed postimage. `null` when the postimage
76
+ * could not be evaluated (engine refusal, or an unsupported `commit` source).
77
+ */
78
+ silentOnPostimage: boolean | null;
79
+ /** Engine match count on the preimage exemplar (evidence). `null` when not evaluated. */
80
+ preimageMatchCount: number | null;
81
+ /** Engine match count on the postimage exemplar (evidence). `null` when not evaluated. */
82
+ postimageMatchCount: number | null;
83
+ /** First-line engine/defer reason — present for `needs-adjudication` / `unsupported-source`. */
84
+ reason?: string;
85
+ }
86
+ /**
87
+ * Injection port for the COMMIT-pair preimage source (slice C2). The lesson
88
+ * source (C1) needs none of this — it evaluates against in-record exemplars and
89
+ * stays I/O-free. Declared here so C2's git-tree reads inject through an explicit
90
+ * port (mirroring the cert corpus builder's `Stage4VerifierDeps`) and core never
91
+ * does filesystem/git directly. `evaluatePreimageDifferential` is already async
92
+ * so wiring this in C2 is a non-breaking, additive change.
93
+ */
94
+ export interface PreimageDifferentialDeps {
95
+ /** Read a file's content as of a given commit SHA (the pre-fix / post-fix tree). */
96
+ readFileAtCommit(commitSha: string, filePath: string): Promise<string>;
97
+ }
98
+ /**
99
+ * Evaluate the ADR-112 §4 preimage-differential for one authored fixture against
100
+ * a compiled rule, switching on the fixture's declared `preimageSource.kind`.
101
+ *
102
+ * Returns the raw evidence (`firesOnPreimage`, `silentOnPostimage`, match counts)
103
+ * plus a differential-level `outcome`. It does NOT mint a §5 run verdict and does
104
+ * NOT emit controls — those are slice C2/D. The `commit` source is a typed
105
+ * non-pass (`unsupported-source`) deferred to C2; the union stays total.
106
+ *
107
+ * Async-from-the-start so C2 can inject `PreimageDifferentialDeps` for git-tree
108
+ * reads without a breaking signature change; the C1 lesson path resolves
109
+ * synchronously under the hood (pure, hermetic).
110
+ */
111
+ export declare function evaluatePreimageDifferential(rule: CompiledRule, fixture: AuthoredFixture): Promise<PreimageDifferentialResult>;
112
+ //# sourceMappingURL=preimage-differential.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preimage-differential.d.ts","sourceRoot":"","sources":["../../src/spine/preimage-differential.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI3F;;;;GAIG;AACH,MAAM,MAAM,2BAA2B;AACrC,6FAA6F;AAC3F,oBAAoB;AACtB;;;GAGG;GACD,YAAY;AACd;;;;;;;GAOG;GACD,YAAY;AACd,+EAA+E;GAC7E,gBAAgB;AAClB;;;;;GAKG;GACD,oBAAoB;AACtB;;;;GAIG;GACD,oBAAoB,CAAC;AAEzB,MAAM,WAAW,0BAA0B;IACzC,iFAAiF;IACjF,OAAO,EAAE,2BAA2B,CAAC;IACrC,mDAAmD;IACnD,UAAU,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACnC;;;OAGG;IACH,eAAe,EAAE,OAAO,GAAG,IAAI,CAAC;IAChC;;;OAGG;IACH,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,yFAAyF;IACzF,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,0FAA0F;IAC1F,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,gGAAgG;IAChG,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,wBAAwB;IACvC,oFAAoF;IACpF,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACxE;AAkFD;;;;;;;;;;;;GAYG;AACH,wBAAsB,4BAA4B,CAChD,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,0BAA0B,CAAC,CAgBrC"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * ADR-112 §4/§6 — the preimage-differential materializer (slice C1: the inert primitive).
3
+ *
4
+ * An authored rule is only a legitimate positive control if its matcher **fires
5
+ * on the defect preimage** and is **silent on the fixed postimage** (§4). A
6
+ * matcher that fires on the *fixed* form is "fix-shaped" — the exact failure
7
+ * mode the miner's honest-negative is made of — and must never be admitted as a
8
+ * legitimate control (Falsifying Metric §1(i)).
9
+ *
10
+ * This module evaluates that differential against a fixture's declared
11
+ * `preimageSource` (lesson-anchored PRIMARY / commit-pair FALLBACK) and reports
12
+ * the raw evidence + a differential-level classification. It is deliberately
13
+ * INERT: it wires nothing into the cert path, mints no §5 run verdict, and emits
14
+ * no controls. Slice C2 consumes this to gate control emission; slice D maps the
15
+ * differential to the ADR-110 §5 terminal vocabulary (PASS / FAIL /
16
+ * HONEST-NEGATIVE). The boundary is load-bearing — `over-match` / `vacuous` here
17
+ * are DIFFERENTIAL outcomes, NOT run verdicts (the scorer owns that).
18
+ *
19
+ * Seam (Tenet-21 reuse): firing goes through `runSmokeGate`, the same
20
+ * role-agnostic engine entry point the compiler's #1408 under-match / #1580
21
+ * over-match checks use — regex and ast-grep, in-memory, no temp file, no diff
22
+ * fabrication, no `firingLabelId` minted here. The lesson source evaluates
23
+ * against the in-record `badExample`/`goodExample` exemplars (contract §5.4), so
24
+ * the lesson path is pure and hermetic — no clock, no network, no filesystem.
25
+ */
26
+ import { runSmokeGate } from '../compile-smoke-gate.js';
27
+ // ─── Classification ─────────────────────────────────
28
+ function classifyDifferential(firesOnPreimage, silentOnPostimage) {
29
+ if (firesOnPreimage && silentOnPostimage)
30
+ return 'differential-holds';
31
+ if (firesOnPreimage && !silentOnPostimage)
32
+ return 'over-match';
33
+ if (!firesOnPreimage && silentOnPostimage)
34
+ return 'vacuous-silent';
35
+ return 'fix-shaped';
36
+ }
37
+ // ─── Lesson-anchored differential (C1) ──────────────
38
+ function evaluateLessonDifferential(rule, source) {
39
+ const pre = runSmokeGate(rule, source.badExample);
40
+ const post = runSmokeGate(rule, source.goodExample);
41
+ // An exemplar with no evaluable code cannot establish a differential. Two
42
+ // ways that happens: (1) the engine REFUSES to run — invalid regex, ast-grep
43
+ // throw, uncovered engine — which `runSmokeGate` reports via `reason`; (2) the
44
+ // exemplar is empty/whitespace-only, which `runSmokeGate` instead reports as a
45
+ // CLEAN no-match (no `reason`) — and that would vacuously read as
46
+ // silent-on-postimage / fires-on-neither, masking that one side had nothing to
47
+ // evaluate (an empty postimage falsely reading as `differential-holds` is the
48
+ // dishonest control this primitive exists to catch). The schema enforces
49
+ // non-empty exemplars, but this is a public primitive reachable by direct
50
+ // (unparsed) construction, so it defends its own contract: either condition on
51
+ // either side → `needs-adjudication`, fail-loud, never a silent clean result.
52
+ const preUnevaluable = source.badExample.trim().length === 0 || pre.reason !== undefined;
53
+ const postUnevaluable = source.goodExample.trim().length === 0 || post.reason !== undefined;
54
+ if (preUnevaluable || postUnevaluable) {
55
+ const reason = (source.badExample.trim().length === 0
56
+ ? 'badExample (the defect preimage) is empty or whitespace-only — no evaluable code to establish the differential'
57
+ : pre.reason) ??
58
+ (source.goodExample.trim().length === 0
59
+ ? 'goodExample (the fixed postimage) is empty or whitespace-only — no evaluable code to establish the differential'
60
+ : post.reason);
61
+ return {
62
+ outcome: 'needs-adjudication',
63
+ sourceKind: 'lesson',
64
+ firesOnPreimage: preUnevaluable ? null : pre.matched,
65
+ silentOnPostimage: postUnevaluable ? null : !post.matched,
66
+ preimageMatchCount: preUnevaluable ? null : pre.matchCount,
67
+ postimageMatchCount: postUnevaluable ? null : post.matchCount,
68
+ reason,
69
+ };
70
+ }
71
+ const firesOnPreimage = pre.matched;
72
+ const silentOnPostimage = !post.matched;
73
+ return {
74
+ outcome: classifyDifferential(firesOnPreimage, silentOnPostimage),
75
+ sourceKind: 'lesson',
76
+ firesOnPreimage,
77
+ silentOnPostimage,
78
+ preimageMatchCount: pre.matchCount,
79
+ postimageMatchCount: post.matchCount,
80
+ };
81
+ }
82
+ function deferredCommitResult() {
83
+ return {
84
+ outcome: 'unsupported-source',
85
+ sourceKind: 'commit',
86
+ firesOnPreimage: null,
87
+ silentOnPostimage: null,
88
+ preimageMatchCount: null,
89
+ postimageMatchCount: null,
90
+ reason: 'commit-pair preimage source is deferred to slice C2 (land-then-fix fallback); lc cert-#1 is lesson-anchored',
91
+ };
92
+ }
93
+ // ─── Public API ─────────────────────────────────────
94
+ /**
95
+ * Evaluate the ADR-112 §4 preimage-differential for one authored fixture against
96
+ * a compiled rule, switching on the fixture's declared `preimageSource.kind`.
97
+ *
98
+ * Returns the raw evidence (`firesOnPreimage`, `silentOnPostimage`, match counts)
99
+ * plus a differential-level `outcome`. It does NOT mint a §5 run verdict and does
100
+ * NOT emit controls — those are slice C2/D. The `commit` source is a typed
101
+ * non-pass (`unsupported-source`) deferred to C2; the union stays total.
102
+ *
103
+ * Async-from-the-start so C2 can inject `PreimageDifferentialDeps` for git-tree
104
+ * reads without a breaking signature change; the C1 lesson path resolves
105
+ * synchronously under the hood (pure, hermetic).
106
+ */
107
+ export async function evaluatePreimageDifferential(rule, fixture) {
108
+ const source = fixture.preimageSource;
109
+ switch (source.kind) {
110
+ case 'lesson':
111
+ return evaluateLessonDifferential(rule, source);
112
+ case 'commit':
113
+ return deferredCommitResult();
114
+ default: {
115
+ // Exhaustiveness backstop: a future `PreimageSource` kind must be handled
116
+ // explicitly, never silently admitted as a passing control.
117
+ const _exhaustive = source;
118
+ throw new Error(`[Totem Error] evaluatePreimageDifferential: unknown preimageSource kind '${String(_exhaustive.kind)}'`);
119
+ }
120
+ }
121
+ }
122
+ //# sourceMappingURL=preimage-differential.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preimage-differential.js","sourceRoot":"","sources":["../../src/spine/preimage-differential.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=preimage-differential.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preimage-differential.test.d.ts","sourceRoot":"","sources":["../../src/spine/preimage-differential.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,223 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { evaluatePreimageDifferential } from './preimage-differential.js';
3
+ // ─── Rule helpers (mirror compile-smoke-gate.test.ts) ─
4
+ function regexRule(overrides = {}) {
5
+ return {
6
+ lessonHash: 'deadbeef1234',
7
+ lessonHeading: 'No console.log',
8
+ pattern: 'console\\.log',
9
+ message: 'Do not use console.log',
10
+ engine: 'regex',
11
+ compiledAt: '2026-04-13T12:00:00Z',
12
+ ...overrides,
13
+ };
14
+ }
15
+ function astGrepRule(overrides = {}) {
16
+ return {
17
+ lessonHash: 'cafeface5678',
18
+ lessonHeading: 'No debugger',
19
+ pattern: '',
20
+ message: 'Do not commit debugger statements',
21
+ engine: 'ast-grep',
22
+ astGrepPattern: 'debugger',
23
+ compiledAt: '2026-04-13T12:00:00Z',
24
+ ...overrides,
25
+ };
26
+ }
27
+ function emptyCatchRule(overrides = {}) {
28
+ return {
29
+ lessonHash: 'beefcafe9abc',
30
+ lessonHeading: 'Empty catch',
31
+ pattern: '',
32
+ message: 'Empty catch swallows errors',
33
+ engine: 'ast-grep',
34
+ astGrepYamlRule: {
35
+ rule: {
36
+ kind: 'catch_clause',
37
+ not: {
38
+ has: {
39
+ kind: 'statement_block',
40
+ has: {
41
+ any: [
42
+ { kind: 'expression_statement' },
43
+ { kind: 'variable_declaration' },
44
+ { kind: 'if_statement' },
45
+ { kind: 'return_statement' },
46
+ { kind: 'throw_statement' },
47
+ ],
48
+ stopBy: 'end',
49
+ },
50
+ },
51
+ },
52
+ },
53
+ },
54
+ compiledAt: '2026-04-13T12:00:00Z',
55
+ ...overrides,
56
+ };
57
+ }
58
+ // ─── Fixture helpers ────────────────────────────────
59
+ function lessonFixture(badExample, goodExample) {
60
+ return {
61
+ pr: 130,
62
+ preimageSource: { kind: 'lesson', lessonRef: 'deadbeefdeadbeef', badExample, goodExample },
63
+ filePath: 'src/sim/level.rs',
64
+ matchedSpan: 'L10-L12',
65
+ contentHash: 'abc123def456',
66
+ };
67
+ }
68
+ function commitFixture() {
69
+ return {
70
+ pr: 130,
71
+ preimageSource: {
72
+ kind: 'commit',
73
+ preimageCommitSha: 'a'.repeat(40),
74
+ mergeCommitSha: 'b'.repeat(40),
75
+ },
76
+ filePath: 'src/sim/level.rs',
77
+ matchedSpan: 'L10-L12',
78
+ contentHash: 'abc123def456',
79
+ };
80
+ }
81
+ // ─── differential-holds (the legitimate control) ─────
82
+ describe('evaluatePreimageDifferential — differential-holds', () => {
83
+ it('regex: fires on the preimage and is silent on the postimage', async () => {
84
+ const result = await evaluatePreimageDifferential(regexRule(), lessonFixture('console.log("debug")', 'logger.info("ok")'));
85
+ expect(result.outcome).toBe('differential-holds');
86
+ // Non-vacuity: BOTH legs must hold. If the classifier checked only
87
+ // firesOnPreimage, the over-match case below would also read as "holds".
88
+ expect(result.firesOnPreimage).toBe(true);
89
+ expect(result.silentOnPostimage).toBe(true);
90
+ expect(result.preimageMatchCount).toBeGreaterThanOrEqual(1);
91
+ expect(result.postimageMatchCount).toBe(0);
92
+ expect(result.sourceKind).toBe('lesson');
93
+ });
94
+ it('ast-grep: fires on the preimage and is silent on the postimage (TS exemplar)', async () => {
95
+ const result = await evaluatePreimageDifferential(astGrepRule(), lessonFixture('debugger;\n', 'const x = 1;\n'));
96
+ expect(result.outcome).toBe('differential-holds');
97
+ expect(result.firesOnPreimage).toBe(true);
98
+ expect(result.silentOnPostimage).toBe(true);
99
+ expect(result.preimageMatchCount).toBeGreaterThanOrEqual(1);
100
+ });
101
+ it('ast-grep compound (multi-line exemplar): fires on empty catch, silent on a catch with a body', async () => {
102
+ // Locks multi-line exemplar faithfulness — the differential must survive a
103
+ // real multi-line snippet, not just a single token.
104
+ const result = await evaluatePreimageDifferential(emptyCatchRule(), lessonFixture('try {\n work();\n} catch (err) {\n}\n', 'try {\n work();\n} catch (err) {\n log(err);\n}\n'));
105
+ expect(result.outcome).toBe('differential-holds');
106
+ expect(result.firesOnPreimage).toBe(true);
107
+ expect(result.silentOnPostimage).toBe(true);
108
+ });
109
+ });
110
+ // ─── fix-shaped (the literal Falsifying Metric §1(i)) ─
111
+ describe('evaluatePreimageDifferential — fix-shaped is never a charitable pass (FM §1(i))', () => {
112
+ it('regex: a matcher that fires on the FIXED form and is silent on the defect is fix-shaped', async () => {
113
+ // pattern matches the GOOD form (logger.info), not the defect (console.log).
114
+ const result = await evaluatePreimageDifferential(regexRule({ pattern: 'logger\\.info' }), lessonFixture('console.log("bad")', 'logger.info("fixed")'));
115
+ expect(result.outcome).toBe('fix-shaped');
116
+ expect(result.outcome).not.toBe('differential-holds');
117
+ // Non-vacuity: the classification must rest on BOTH legs being wrong, not
118
+ // just one. fix-shaped (here) and vacuous-silent (below) share
119
+ // firesOnPreimage=false but differ on silentOnPostimage — so the silent leg
120
+ // is load-bearing.
121
+ expect(result.firesOnPreimage).toBe(false);
122
+ expect(result.silentOnPostimage).toBe(false);
123
+ });
124
+ it('ast-grep: silent on the defect, fires on the fixed form → fix-shaped', async () => {
125
+ const result = await evaluatePreimageDifferential(astGrepRule(), lessonFixture('const x = 1;\n', 'debugger;\n'));
126
+ expect(result.outcome).toBe('fix-shaped');
127
+ expect(result.firesOnPreimage).toBe(false);
128
+ expect(result.silentOnPostimage).toBe(false);
129
+ });
130
+ });
131
+ // ─── over-match (the scorer-invisible escape, contract §4/§5.3) ─
132
+ describe('evaluatePreimageDifferential — over-match is surfaced (the silent-on-postimage leg)', () => {
133
+ it('regex: a matcher that fires on BOTH the defect and the fixed form is over-match, not holds', async () => {
134
+ const result = await evaluatePreimageDifferential(regexRule(), lessonFixture('console.log("bad")', 'console.log("still here in the fix")'));
135
+ expect(result.outcome).toBe('over-match');
136
+ // The cert-critical assertion: this MUST NOT read as differential-holds.
137
+ expect(result.outcome).not.toBe('differential-holds');
138
+ expect(result.firesOnPreimage).toBe(true);
139
+ // Non-vacuity: if the code ignored the postimage, silentOnPostimage would be
140
+ // true and this would be misclassified as holds — the escape the scorer
141
+ // cannot catch on a synthetic exemplar.
142
+ expect(result.silentOnPostimage).toBe(false);
143
+ expect(result.postimageMatchCount).toBeGreaterThanOrEqual(1);
144
+ });
145
+ it('ast-grep: fires on both sides → over-match', async () => {
146
+ const result = await evaluatePreimageDifferential(astGrepRule(), lessonFixture('debugger;\n', 'debugger;\nconst x = 1;\n'));
147
+ expect(result.outcome).toBe('over-match');
148
+ expect(result.silentOnPostimage).toBe(false);
149
+ });
150
+ });
151
+ // ─── vacuous-silent (fires on neither) ──────────────
152
+ describe('evaluatePreimageDifferential — vacuous-silent (fires on neither)', () => {
153
+ it('regex: a matcher silent on both sides catches nothing', async () => {
154
+ const result = await evaluatePreimageDifferential(regexRule(), lessonFixture('const x = 1;', 'const y = 2;'));
155
+ expect(result.outcome).toBe('vacuous-silent');
156
+ expect(result.firesOnPreimage).toBe(false);
157
+ expect(result.silentOnPostimage).toBe(true);
158
+ // Contrast with fix-shaped (same firesOnPreimage=false): proves the silent
159
+ // leg distinguishes the two and is not ignored.
160
+ });
161
+ });
162
+ // ─── needs-adjudication (engine refusal, fail-loud) ──
163
+ describe('evaluatePreimageDifferential — needs-adjudication on engine refusal', () => {
164
+ it('invalid regex pattern → needs-adjudication with a reason, not a silent clean result', async () => {
165
+ const result = await evaluatePreimageDifferential(regexRule({ pattern: '(unclosed' }), lessonFixture('console.log("x")', 'logger.info("ok")'));
166
+ expect(result.outcome).toBe('needs-adjudication');
167
+ expect(result.reason).toBeDefined();
168
+ expect(result.reason).toContain('invalid');
169
+ // The preimage leg could not be evaluated → null, not a false "silent".
170
+ expect(result.firesOnPreimage).toBeNull();
171
+ });
172
+ it('ast-grep rule that throws at runtime (invalid kind) → needs-adjudication', async () => {
173
+ const result = await evaluatePreimageDifferential(emptyCatchRule({ astGrepYamlRule: { rule: { kind: '!!!INVALID_KIND!!!' } } }), lessonFixture('try {\n} catch (e) {\n}\n', 'const x = 1;\n'));
174
+ expect(result.outcome).toBe('needs-adjudication');
175
+ expect(result.reason).toBeDefined();
176
+ });
177
+ it('an engine the smoke gate does not cover (tree-sitter ast) → needs-adjudication', async () => {
178
+ const result = await evaluatePreimageDifferential(regexRule({ engine: 'ast', pattern: '' }), lessonFixture('whatever', 'something else'));
179
+ expect(result.outcome).toBe('needs-adjudication');
180
+ expect(result.reason).toBeDefined();
181
+ });
182
+ it('a whitespace-only badExample → needs-adjudication, not a silent vacuous result', async () => {
183
+ // Direct (unparsed) construction can bypass the schema's non-empty refine; a
184
+ // whitespace preimage carries no evaluable code, so the preimage leg is null.
185
+ const result = await evaluatePreimageDifferential(regexRule(), lessonFixture(' \n ', 'logger.info("ok")'));
186
+ expect(result.outcome).toBe('needs-adjudication');
187
+ expect(result.firesOnPreimage).toBeNull();
188
+ expect(result.reason).toContain('badExample');
189
+ });
190
+ it('a whitespace-only goodExample → needs-adjudication, NOT a false differential-holds (Greptile #2264)', async () => {
191
+ // The cert-critical case: the rule fires on the defect, and the postimage is
192
+ // whitespace. Pre-fix this read as differential-holds (silentOnPostimage true
193
+ // because there was nothing to match) — masking an unevaluable fixed side.
194
+ const result = await evaluatePreimageDifferential(regexRule(), lessonFixture('console.log("bad")', ' \n '));
195
+ expect(result.outcome).toBe('needs-adjudication');
196
+ expect(result.outcome).not.toBe('differential-holds');
197
+ expect(result.silentOnPostimage).toBeNull();
198
+ expect(result.reason).toContain('goodExample');
199
+ });
200
+ });
201
+ // ─── commit-source deferral (typed non-pass, slice C2) ─
202
+ describe('evaluatePreimageDifferential — commit source is a typed deferral (slice C2)', () => {
203
+ it('commit-pair fixture → unsupported-source, never a passing control', async () => {
204
+ const result = await evaluatePreimageDifferential(astGrepRule(), commitFixture());
205
+ expect(result.outcome).toBe('unsupported-source');
206
+ expect(result.outcome).not.toBe('differential-holds');
207
+ expect(result.sourceKind).toBe('commit');
208
+ expect(result.firesOnPreimage).toBeNull();
209
+ expect(result.silentOnPostimage).toBeNull();
210
+ expect(result.reason).toContain('slice C2');
211
+ });
212
+ });
213
+ // ─── determinism (Tenet-15) ─────────────────────────
214
+ describe('evaluatePreimageDifferential — determinism', () => {
215
+ it('is a pure function of (rule, fixture): identical inputs yield identical results', async () => {
216
+ const rule = astGrepRule();
217
+ const fixture = lessonFixture('debugger;\n', 'const x = 1;\n');
218
+ const a = await evaluatePreimageDifferential(rule, fixture);
219
+ const b = await evaluatePreimageDifferential(rule, fixture);
220
+ expect(a).toEqual(b);
221
+ });
222
+ });
223
+ //# sourceMappingURL=preimage-differential.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preimage-differential.test.js","sourceRoot":"","sources":["../../src/spine/preimage-differential.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAG9C,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAE1E,yDAAyD;AAEzD,SAAS,SAAS,CAAC,YAAmC,EAAE;IACtD,OAAO;QACL,UAAU,EAAE,cAAc;QAC1B,aAAa,EAAE,gBAAgB;QAC/B,OAAO,EAAE,eAAe;QACxB,OAAO,EAAE,wBAAwB;QACjC,MAAM,EAAE,OAAO;QACf,UAAU,EAAE,sBAAsB;QAClC,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,YAAmC,EAAE;IACxD,OAAO;QACL,UAAU,EAAE,cAAc;QAC1B,aAAa,EAAE,aAAa;QAC5B,OAAO,EAAE,EAAE;QACX,OAAO,EAAE,mCAAmC;QAC5C,MAAM,EAAE,UAAU;QAClB,cAAc,EAAE,UAAU;QAC1B,UAAU,EAAE,sBAAsB;QAClC,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,YAAmC,EAAE;IAC3D,OAAO;QACL,UAAU,EAAE,cAAc;QAC1B,aAAa,EAAE,aAAa;QAC5B,OAAO,EAAE,EAAE;QACX,OAAO,EAAE,6BAA6B;QACtC,MAAM,EAAE,UAAU;QAClB,eAAe,EAAE;YACf,IAAI,EAAE;gBACJ,IAAI,EAAE,cAAc;gBACpB,GAAG,EAAE;oBACH,GAAG,EAAE;wBACH,IAAI,EAAE,iBAAiB;wBACvB,GAAG,EAAE;4BACH,GAAG,EAAE;gCACH,EAAE,IAAI,EAAE,sBAAsB,EAAE;gCAChC,EAAE,IAAI,EAAE,sBAAsB,EAAE;gCAChC,EAAE,IAAI,EAAE,cAAc,EAAE;gCACxB,EAAE,IAAI,EAAE,kBAAkB,EAAE;gCAC5B,EAAE,IAAI,EAAE,iBAAiB,EAAE;6BAC5B;4BACD,MAAM,EAAE,KAAK;yBACd;qBACF;iBACF;aACF;SACF;QACD,UAAU,EAAE,sBAAsB;QAClC,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,uDAAuD;AAEvD,SAAS,aAAa,CAAC,UAAkB,EAAE,WAAmB;IAC5D,OAAO;QACL,EAAE,EAAE,GAAG;QACP,cAAc,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,kBAAkB,EAAE,UAAU,EAAE,WAAW,EAAE;QAC1F,QAAQ,EAAE,kBAAkB;QAC5B,WAAW,EAAE,SAAS;QACtB,WAAW,EAAE,cAAc;KAC5B,CAAC;AACJ,CAAC;AAED,SAAS,aAAa;IACpB,OAAO;QACL,EAAE,EAAE,GAAG;QACP,cAAc,EAAE;YACd,IAAI,EAAE,QAAQ;YACd,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACjC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;SAC/B;QACD,QAAQ,EAAE,kBAAkB;QAC5B,WAAW,EAAE,SAAS;QACtB,WAAW,EAAE,cAAc;KAC5B,CAAC;AACJ,CAAC;AAED,wDAAwD;AAExD,QAAQ,CAAC,mDAAmD,EAAE,GAAG,EAAE;IACjE,EAAE,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QAC3E,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAC/C,SAAS,EAAE,EACX,aAAa,CAAC,sBAAsB,EAAE,mBAAmB,CAAC,CAC3D,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAClD,mEAAmE;QACnE,yEAAyE;QACzE,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;QAC5D,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;QAC5F,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAC/C,WAAW,EAAE,EACb,aAAa,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAC/C,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8FAA8F,EAAE,KAAK,IAAI,EAAE;QAC5G,2EAA2E;QAC3E,oDAAoD;QACpD,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAC/C,cAAc,EAAE,EAChB,aAAa,CACX,wCAAwC,EACxC,qDAAqD,CACtD,CACF,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,yDAAyD;AAEzD,QAAQ,CAAC,iFAAiF,EAAE,GAAG,EAAE;IAC/F,EAAE,CAAC,yFAAyF,EAAE,KAAK,IAAI,EAAE;QACvG,6EAA6E;QAC7E,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAC/C,SAAS,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,EACvC,aAAa,CAAC,oBAAoB,EAAE,sBAAsB,CAAC,CAC5D,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACtD,0EAA0E;QAC1E,+DAA+D;QAC/D,4EAA4E;QAC5E,mBAAmB;QACnB,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sEAAsE,EAAE,KAAK,IAAI,EAAE;QACpF,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAC/C,WAAW,EAAE,EACb,aAAa,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAC/C,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,mEAAmE;AAEnE,QAAQ,CAAC,qFAAqF,EAAE,GAAG,EAAE;IACnG,EAAE,CAAC,4FAA4F,EAAE,KAAK,IAAI,EAAE;QAC1G,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAC/C,SAAS,EAAE,EACX,aAAa,CAAC,oBAAoB,EAAE,sCAAsC,CAAC,CAC5E,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1C,yEAAyE;QACzE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACtD,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,6EAA6E;QAC7E,wEAAwE;QACxE,wCAAwC;QACxC,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAC/C,WAAW,EAAE,EACb,aAAa,CAAC,aAAa,EAAE,2BAA2B,CAAC,CAC1D,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,uDAAuD;AAEvD,QAAQ,CAAC,kEAAkE,EAAE,GAAG,EAAE;IAChF,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAC/C,SAAS,EAAE,EACX,aAAa,CAAC,cAAc,EAAE,cAAc,CAAC,CAC9C,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,2EAA2E;QAC3E,gDAAgD;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,wDAAwD;AAExD,QAAQ,CAAC,qEAAqE,EAAE,GAAG,EAAE;IACnF,EAAE,CAAC,qFAAqF,EAAE,KAAK,IAAI,EAAE;QACnG,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAC/C,SAAS,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,EACnC,aAAa,CAAC,kBAAkB,EAAE,mBAAmB,CAAC,CACvD,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAC3C,wEAAwE;QACxE,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;QACxF,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAC/C,cAAc,CAAC,EAAE,eAAe,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAAE,EAAE,CAAC,EAC7E,aAAa,CAAC,2BAA2B,EAAE,gBAAgB,CAAC,CAC7D,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;QAC9F,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAC/C,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,EACzC,aAAa,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAC5C,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;QAC9F,6EAA6E;QAC7E,8EAA8E;QAC9E,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAC/C,SAAS,EAAE,EACX,aAAa,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAC9C,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qGAAqG,EAAE,KAAK,IAAI,EAAE;QACnH,6EAA6E;QAC7E,8EAA8E;QAC9E,2EAA2E;QAC3E,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAC/C,SAAS,EAAE,EACX,aAAa,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAC/C,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACtD,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,0DAA0D;AAE1D,QAAQ,CAAC,6EAA6E,EAAE,GAAG,EAAE;IAC3F,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QACjF,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAAC,WAAW,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC;QAClF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACtD,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,uDAAuD;AAEvD,QAAQ,CAAC,4CAA4C,EAAE,GAAG,EAAE;IAC1D,EAAE,CAAC,iFAAiF,EAAE,KAAK,IAAI,EAAE;QAC/F,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,aAAa,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC;QAC/D,MAAM,CAAC,GAAG,MAAM,4BAA4B,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC5D,MAAM,CAAC,GAAG,MAAM,4BAA4B,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC5D,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -7,11 +7,11 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
7
7
  timestamp: z.ZodOptional<z.ZodString>;
8
8
  commit: z.ZodOptional<z.ZodString>;
9
9
  }, "strip", z.ZodTypeAny, {
10
- timestamp?: string | undefined;
11
10
  commit?: string | undefined;
12
- }, {
13
11
  timestamp?: string | undefined;
12
+ }, {
14
13
  commit?: string | undefined;
14
+ timestamp?: string | undefined;
15
15
  }>>;
16
16
  phase: z.ZodEnum<["harness", "certifying"]>;
17
17
  corpus: z.ZodObject<{
@@ -324,8 +324,8 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
324
324
  };
325
325
  };
326
326
  frozenAt?: {
327
- timestamp?: string | undefined;
328
327
  commit?: string | undefined;
328
+ timestamp?: string | undefined;
329
329
  } | undefined;
330
330
  }, {
331
331
  schema: "windtunnel.lock.v1";
@@ -390,8 +390,8 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
390
390
  };
391
391
  };
392
392
  frozenAt?: {
393
- timestamp?: string | undefined;
394
393
  commit?: string | undefined;
394
+ timestamp?: string | undefined;
395
395
  } | undefined;
396
396
  }>, {
397
397
  schema: "windtunnel.lock.v1";
@@ -456,8 +456,8 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
456
456
  };
457
457
  };
458
458
  frozenAt?: {
459
- timestamp?: string | undefined;
460
459
  commit?: string | undefined;
460
+ timestamp?: string | undefined;
461
461
  } | undefined;
462
462
  }, {
463
463
  schema: "windtunnel.lock.v1";
@@ -522,8 +522,8 @@ export declare const WindtunnelLockSchema: z.ZodEffects<z.ZodObject<{
522
522
  };
523
523
  };
524
524
  frozenAt?: {
525
- timestamp?: string | undefined;
526
525
  commit?: string | undefined;
526
+ timestamp?: string | undefined;
527
527
  } | undefined;
528
528
  }>;
529
529
  export type WindtunnelLock = z.infer<typeof WindtunnelLockSchema>;
@@ -15,7 +15,7 @@ export declare const StoredChunkSchema: z.ZodObject<{
15
15
  endLine: z.ZodNumber;
16
16
  metadata: z.ZodString;
17
17
  }, "strip", z.ZodTypeAny, {
18
- type: "code" | "session_log" | "spec" | "lesson";
18
+ type: "code" | "lesson" | "session_log" | "spec";
19
19
  filePath: string;
20
20
  content: string;
21
21
  strategy: string;
@@ -26,7 +26,7 @@ export declare const StoredChunkSchema: z.ZodObject<{
26
26
  id: string;
27
27
  metadata: string;
28
28
  }, {
29
- type: "code" | "session_log" | "spec" | "lesson";
29
+ type: "code" | "lesson" | "session_log" | "spec";
30
30
  filePath: string;
31
31
  content: string;
32
32
  strategy: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmnto/totem",
3
- "version": "1.79.0",
3
+ "version": "1.81.0",
4
4
  "description": "Persistent memory and context layer for AI agents",
5
5
  "type": "module",
6
6
  "engines": {