@mmnto/totem 1.77.0 → 1.79.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.
- package/dist/artifacts/panel.d.ts +48 -48
- package/dist/artifacts/schema.d.ts +40 -40
- package/dist/compiler-schema.d.ts +1048 -7
- package/dist/compiler-schema.d.ts.map +1 -1
- package/dist/compiler-schema.js +129 -1
- package/dist/compiler-schema.js.map +1 -1
- package/dist/compiler-schema.test.js +92 -2
- package/dist/compiler-schema.test.js.map +1 -1
- package/dist/compiler.d.ts +2 -2
- package/dist/compiler.d.ts.map +1 -1
- package/dist/compiler.js +1 -1
- package/dist/compiler.js.map +1 -1
- package/dist/index.d.ts +10 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/parity-detect.d.ts +127 -0
- package/dist/parity-detect.d.ts.map +1 -1
- package/dist/parity-detect.js +425 -1
- package/dist/parity-detect.js.map +1 -1
- package/dist/parity-lock-content.test.d.ts +9 -0
- package/dist/parity-lock-content.test.d.ts.map +1 -0
- package/dist/parity-lock-content.test.js +432 -0
- package/dist/parity-lock-content.test.js.map +1 -0
- package/dist/parity-manifest.d.ts +1 -1
- package/dist/parity-manifest.d.ts.map +1 -1
- package/dist/parity-manifest.js +6 -0
- package/dist/parity-manifest.js.map +1 -1
- package/dist/spine/authored-rule.d.ts +360 -0
- package/dist/spine/authored-rule.d.ts.map +1 -0
- package/dist/spine/authored-rule.js +199 -0
- package/dist/spine/authored-rule.js.map +1 -0
- package/dist/spine/authored-rule.test.d.ts +2 -0
- package/dist/spine/authored-rule.test.d.ts.map +1 -0
- package/dist/spine/authored-rule.test.js +220 -0
- package/dist/spine/authored-rule.test.js.map +1 -0
- package/dist/spine/candidate-rule.d.ts +32 -0
- package/dist/spine/candidate-rule.d.ts.map +1 -1
- package/dist/spine/candidate-rule.js +2 -2
- package/dist/spine/candidate-rule.js.map +1 -1
- package/dist/spine/classify.d.ts +5 -5
- package/dist/spine/compile.d.ts +16 -4
- package/dist/spine/compile.d.ts.map +1 -1
- package/dist/spine/compile.js +23 -0
- package/dist/spine/compile.js.map +1 -1
- package/dist/spine/compile.test.js +69 -0
- package/dist/spine/compile.test.js.map +1 -1
- package/dist/spine/corpus-dispositions.d.ts +18 -18
- package/dist/spine/extract.d.ts +2 -2
- package/dist/spine/extract.d.ts.map +1 -1
- package/dist/spine/extract.js +5 -4
- package/dist/spine/extract.js.map +1 -1
- package/dist/spine/ledgers.d.ts +46 -21
- package/dist/spine/ledgers.d.ts.map +1 -1
- package/dist/spine/ledgers.js +16 -8
- package/dist/spine/ledgers.js.map +1 -1
- package/dist/spine/rule-policy.d.ts +27 -0
- package/dist/spine/rule-policy.d.ts.map +1 -0
- package/dist/spine/rule-policy.js +43 -0
- package/dist/spine/rule-policy.js.map +1 -0
- package/dist/spine/rule-policy.test.d.ts +2 -0
- package/dist/spine/rule-policy.test.d.ts.map +1 -0
- package/dist/spine/rule-policy.test.js +31 -0
- package/dist/spine/rule-policy.test.js.map +1 -0
- package/dist/spine/windtunnel-lock.d.ts +8 -8
- package/package.json +1 -1
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { AuthoredRuleRecordSchema, evaluateStructuralEligibility, mintAuthoredRuleId, toCompileFeed, } from './authored-rule.js';
|
|
3
|
+
const WHITELIST = [
|
|
4
|
+
{ engine: 'regex', structuralClass: 'float-finite-assert' },
|
|
5
|
+
{ engine: 'ast-grep', structuralClass: 'divisor-le-zero' },
|
|
6
|
+
];
|
|
7
|
+
describe('evaluateStructuralEligibility (ADR-112 §3 — closed predicate)', () => {
|
|
8
|
+
it('decidable:true on EXACTLY ONE (engine,class) match', () => {
|
|
9
|
+
const r = evaluateStructuralEligibility({ declaredEngine: 'regex', structuralClass: 'float-finite-assert' }, WHITELIST, 'static-whitelist@cert-1');
|
|
10
|
+
expect(r.decidable).toBe(true);
|
|
11
|
+
expect(r.basis).toBe('whitelist:float-finite-assert');
|
|
12
|
+
expect(r.judgedBy).toBe('static-whitelist@cert-1');
|
|
13
|
+
});
|
|
14
|
+
it('decidable:false on an UNKNOWN class (no default-to-structural)', () => {
|
|
15
|
+
const r = evaluateStructuralEligibility({ declaredEngine: 'regex', structuralClass: 'unbounded-recursion-behavioral' }, WHITELIST, 'static-whitelist@cert-1');
|
|
16
|
+
expect(r.decidable).toBe(false);
|
|
17
|
+
});
|
|
18
|
+
it('decidable:false when the engine cannot represent the class (no matching pair)', () => {
|
|
19
|
+
// class is whitelisted for ast-grep, not regex → no (regex, divisor-le-zero) entry.
|
|
20
|
+
const r = evaluateStructuralEligibility({ declaredEngine: 'regex', structuralClass: 'divisor-le-zero' }, WHITELIST, 'static-whitelist@cert-1');
|
|
21
|
+
expect(r.decidable).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
it('decidable:false on MULTIPLE matches (ambiguous)', () => {
|
|
24
|
+
const dupes = [
|
|
25
|
+
{ engine: 'regex', structuralClass: 'float-finite-assert' },
|
|
26
|
+
{ engine: 'regex', structuralClass: 'float-finite-assert' },
|
|
27
|
+
];
|
|
28
|
+
const r = evaluateStructuralEligibility({ declaredEngine: 'regex', structuralClass: 'float-finite-assert' }, dupes, 'static-whitelist@cert-1');
|
|
29
|
+
expect(r.decidable).toBe(false);
|
|
30
|
+
});
|
|
31
|
+
it('is deterministic — 100 sequential iterations yield an identical verdict (LLM-free)', () => {
|
|
32
|
+
const first = JSON.stringify(evaluateStructuralEligibility({ declaredEngine: 'ast-grep', structuralClass: 'divisor-le-zero' }, WHITELIST, 'static-whitelist@cert-1'));
|
|
33
|
+
for (let i = 0; i < 100; i += 1) {
|
|
34
|
+
const again = JSON.stringify(evaluateStructuralEligibility({ declaredEngine: 'ast-grep', structuralClass: 'divisor-le-zero' }, WHITELIST, 'static-whitelist@cert-1'));
|
|
35
|
+
expect(again).toBe(first);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
describe('AuthoredRuleRecord schema (ADR-112 §3)', () => {
|
|
40
|
+
const base = {
|
|
41
|
+
ruleId: '0f1e2d3c4b5a6978',
|
|
42
|
+
provenance: {
|
|
43
|
+
kind: 'authored',
|
|
44
|
+
author: 'totem-claude',
|
|
45
|
+
authoredAt: '2026-06-27',
|
|
46
|
+
targetDefect: 'float equality compared with == instead of a finite-tolerance check',
|
|
47
|
+
positiveFixtures: [
|
|
48
|
+
{
|
|
49
|
+
pr: 100,
|
|
50
|
+
mergeCommitSha: 'b'.repeat(40),
|
|
51
|
+
preimageCommitSha: 'c'.repeat(40),
|
|
52
|
+
filePath: 'src/physics/step.ts',
|
|
53
|
+
matchedSpan: 'L10-L12',
|
|
54
|
+
contentHash: 'deadbeefcafe',
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
structuralEligibility: {
|
|
59
|
+
decidable: true,
|
|
60
|
+
basis: 'whitelist:float-finite-assert',
|
|
61
|
+
judgedBy: 's',
|
|
62
|
+
},
|
|
63
|
+
origin: { kind: 'from-scratch' },
|
|
64
|
+
declaredEngine: 'regex',
|
|
65
|
+
authoringLedgerRef: 'alr-0001',
|
|
66
|
+
dslSource: '**Pattern:** `== *\\d+\\.\\d+f?`',
|
|
67
|
+
unverified: true,
|
|
68
|
+
};
|
|
69
|
+
it('accepts a complete authored record', () => {
|
|
70
|
+
expect(() => AuthoredRuleRecordSchema.parse(base)).not.toThrow();
|
|
71
|
+
});
|
|
72
|
+
it('has NO author-settable disposition/routing field (the check owns eligibility — FM(d))', () => {
|
|
73
|
+
const parsed = AuthoredRuleRecordSchema.parse(base);
|
|
74
|
+
expect('classifierDisposition' in parsed).toBe(false);
|
|
75
|
+
expect('routing' in parsed).toBe(false);
|
|
76
|
+
});
|
|
77
|
+
it('requires the independent structuralEligibility result', () => {
|
|
78
|
+
const { structuralEligibility: _omit, ...without } = base;
|
|
79
|
+
expect(() => AuthoredRuleRecordSchema.parse(without)).toThrow();
|
|
80
|
+
});
|
|
81
|
+
it('reserves the minted ruleId on the record (ADR-112 §3/§8 — persisted, never re-derived)', () => {
|
|
82
|
+
const { ruleId: _omit, ...without } = base;
|
|
83
|
+
expect(() => AuthoredRuleRecordSchema.parse(without)).toThrow();
|
|
84
|
+
expect(() => AuthoredRuleRecordSchema.parse({ ...base, ruleId: ' ' })).toThrow();
|
|
85
|
+
expect(AuthoredRuleRecordSchema.parse(base).ruleId).toBe('0f1e2d3c4b5a6978');
|
|
86
|
+
});
|
|
87
|
+
it('enforces the minted ruleId SHAPE at the boundary — 16 hex + optional -<n> (#2259 CR-major)', () => {
|
|
88
|
+
for (const bad of [
|
|
89
|
+
'NOTHEXNOTHEXNOTH',
|
|
90
|
+
'0f1e2d3c',
|
|
91
|
+
'0f1e2d3c4b5a6978abcd',
|
|
92
|
+
'0F1E2D3C4B5A6978',
|
|
93
|
+
'rid-alr-1',
|
|
94
|
+
// non-canonical suffixes the mint never emits (n≥1, no zero-pad) — #2259 CR
|
|
95
|
+
'0f1e2d3c4b5a6978-0',
|
|
96
|
+
'0f1e2d3c4b5a6978-01',
|
|
97
|
+
]) {
|
|
98
|
+
expect(() => AuthoredRuleRecordSchema.parse({ ...base, ruleId: bad })).toThrow();
|
|
99
|
+
}
|
|
100
|
+
for (const ok of ['0f1e2d3c4b5a6978', '0f1e2d3c4b5a6978-1', 'abcdef0123456789-42']) {
|
|
101
|
+
expect(() => AuthoredRuleRecordSchema.parse({ ...base, ruleId: ok })).not.toThrow();
|
|
102
|
+
}
|
|
103
|
+
// the mint always produces a schema-valid id (the shared shape constant binds both).
|
|
104
|
+
expect(() => AuthoredRuleRecordSchema.parse({
|
|
105
|
+
...base,
|
|
106
|
+
ruleId: mintAuthoredRuleId('totem-claude', 'float-finite-assert', new Set()),
|
|
107
|
+
})).not.toThrow();
|
|
108
|
+
});
|
|
109
|
+
it('forces unverified:true (zero blast radius — ADR-089/§1)', () => {
|
|
110
|
+
expect(() => AuthoredRuleRecordSchema.parse({ ...base, unverified: false })).toThrow();
|
|
111
|
+
});
|
|
112
|
+
it('constrains structuralEligibility.basis to the §3 forms — not free-form (strategy item 2, #2259)', () => {
|
|
113
|
+
const withBasis = (basis) => ({
|
|
114
|
+
...base,
|
|
115
|
+
structuralEligibility: { ...base.structuralEligibility, basis },
|
|
116
|
+
});
|
|
117
|
+
for (const bad of [
|
|
118
|
+
'',
|
|
119
|
+
'freeform',
|
|
120
|
+
'whitelist:',
|
|
121
|
+
'whitelisted',
|
|
122
|
+
'stage4',
|
|
123
|
+
' capability-check',
|
|
124
|
+
]) {
|
|
125
|
+
expect(() => AuthoredRuleRecordSchema.parse(withBasis(bad))).toThrow();
|
|
126
|
+
}
|
|
127
|
+
for (const ok of [
|
|
128
|
+
'whitelist:float-finite-assert',
|
|
129
|
+
'capability-check',
|
|
130
|
+
'draft-classifier+stage4',
|
|
131
|
+
]) {
|
|
132
|
+
expect(() => AuthoredRuleRecordSchema.parse(withBasis(ok))).not.toThrow();
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
describe('mintAuthoredRuleId (ADR-112 §8)', () => {
|
|
137
|
+
it('is deterministic for the same (author,targetDefect) and excludes dslSource', () => {
|
|
138
|
+
const a = mintAuthoredRuleId('totem-claude', 'float-finite-assert', new Set());
|
|
139
|
+
const b = mintAuthoredRuleId('totem-claude', 'float-finite-assert', new Set());
|
|
140
|
+
expect(a).toBe(b);
|
|
141
|
+
expect(a).toMatch(/^[0-9a-f]{16}$/);
|
|
142
|
+
});
|
|
143
|
+
it('encodes (author,targetDefect) injectively — delimiter-aliased tuples do NOT collide (#2259)', () => {
|
|
144
|
+
// A bare `author·targetDefect` seed would alias these two distinct tuples onto one id.
|
|
145
|
+
const a = mintAuthoredRuleId('a·b', 'c', new Set());
|
|
146
|
+
const b = mintAuthoredRuleId('a', 'b·c', new Set());
|
|
147
|
+
expect(a).not.toBe(b);
|
|
148
|
+
});
|
|
149
|
+
it('appends a stable counter on collision and yields distinct persisted ids', () => {
|
|
150
|
+
const first = mintAuthoredRuleId('totem-claude', 'divisor-le-zero', new Set());
|
|
151
|
+
const second = mintAuthoredRuleId('totem-claude', 'divisor-le-zero', new Set([first]));
|
|
152
|
+
const third = mintAuthoredRuleId('totem-claude', 'divisor-le-zero', new Set([first, second]));
|
|
153
|
+
expect(second).toBe(`${first}-1`);
|
|
154
|
+
expect(third).toBe(`${first}-2`);
|
|
155
|
+
expect(new Set([first, second, third]).size).toBe(3);
|
|
156
|
+
});
|
|
157
|
+
it('is stable across re-runs given the already-resolved id set', () => {
|
|
158
|
+
const resolved = mintAuthoredRuleId('a', 'd', new Set());
|
|
159
|
+
expect(mintAuthoredRuleId('a', 'd', new Set([resolved]))).toBe(`${resolved}-1`);
|
|
160
|
+
expect(mintAuthoredRuleId('a', 'd', new Set([resolved]))).toBe(`${resolved}-1`);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
describe('toCompileFeed (ADR-112 §2/§8 — authored → compile-stage input)', () => {
|
|
164
|
+
const decidable = (ref) => ({
|
|
165
|
+
ruleId: mintAuthoredRuleId('totem-claude', ref, new Set()),
|
|
166
|
+
provenance: {
|
|
167
|
+
kind: 'authored',
|
|
168
|
+
author: 'totem-claude',
|
|
169
|
+
authoredAt: '2026-06-27',
|
|
170
|
+
targetDefect: 'float equality compared with == instead of a finite check',
|
|
171
|
+
positiveFixtures: [
|
|
172
|
+
{
|
|
173
|
+
pr: 1,
|
|
174
|
+
mergeCommitSha: 'a'.repeat(40),
|
|
175
|
+
preimageCommitSha: 'b'.repeat(40),
|
|
176
|
+
filePath: 'src/a.ts',
|
|
177
|
+
matchedSpan: 'L1',
|
|
178
|
+
contentHash: 'h1',
|
|
179
|
+
},
|
|
180
|
+
],
|
|
181
|
+
},
|
|
182
|
+
structuralEligibility: {
|
|
183
|
+
decidable: true,
|
|
184
|
+
basis: 'whitelist:float-finite-assert',
|
|
185
|
+
judgedBy: 's',
|
|
186
|
+
},
|
|
187
|
+
origin: { kind: 'from-scratch' },
|
|
188
|
+
declaredEngine: 'regex',
|
|
189
|
+
authoringLedgerRef: ref,
|
|
190
|
+
dslSource: '**Pattern:** `== *\\d`',
|
|
191
|
+
unverified: true,
|
|
192
|
+
});
|
|
193
|
+
it('emits one structural candidate + a 1:1 authored-whitelist ledger entry per decidable rule', () => {
|
|
194
|
+
const feed = toCompileFeed([decidable('alr-1'), decidable('alr-2')]);
|
|
195
|
+
expect(feed.candidates).toHaveLength(2);
|
|
196
|
+
// the adapter — not the author — sets the disposition to structural.
|
|
197
|
+
expect(feed.candidates.every((c) => c.classifierDisposition === 'structural')).toBe(true);
|
|
198
|
+
// authored provenance is carried through, not flattened to a mined shape.
|
|
199
|
+
expect(feed.candidates[0].provenance.kind).toBe('authored');
|
|
200
|
+
expect(feed.candidates.map((c) => c.classifierLedgerRef)).toEqual([
|
|
201
|
+
'authored:alr-1',
|
|
202
|
+
'authored:alr-2',
|
|
203
|
+
]);
|
|
204
|
+
// the classifier ledger NEVER claims an LLM judged a human rule (Tenet-20).
|
|
205
|
+
expect(feed.classifierLedger.entries.every((e) => e.dispositionSource === 'authored-whitelist')).toBe(true);
|
|
206
|
+
// the join key is 1:1 between candidate and ledger entry (runCompileStage requires it).
|
|
207
|
+
expect(feed.classifierLedger.entries.map((e) => e.candidateRef)).toEqual(feed.candidates.map((c) => c.classifierLedgerRef));
|
|
208
|
+
});
|
|
209
|
+
it('FAILS LOUD on a non-decidable record (FM(d) — never reaches the compiler)', () => {
|
|
210
|
+
const nd = {
|
|
211
|
+
...decidable('alr-x'),
|
|
212
|
+
structuralEligibility: { decidable: false, basis: 'whitelist:foo', judgedBy: 's' },
|
|
213
|
+
};
|
|
214
|
+
expect(() => toCompileFeed([nd])).toThrow(/not structurally decidable/);
|
|
215
|
+
});
|
|
216
|
+
it('FAILS LOUD on a duplicate authoringLedgerRef (protects the 1:1 compile join)', () => {
|
|
217
|
+
expect(() => toCompileFeed([decidable('dup'), decidable('dup')])).toThrow(/duplicate authoringLedgerRef/);
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
//# sourceMappingURL=authored-rule.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authored-rule.test.js","sourceRoot":"","sources":["../../src/spine/authored-rule.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { type ProvenanceRecord } from '../compiler-schema.js';
|
|
2
3
|
/**
|
|
3
4
|
* Stage-2 classifier disposition (ADR-091 funnel, the gate). A `structural`
|
|
4
5
|
* (syntactic-invariant) candidate is compile-eligible; a `behavioral` candidate
|
|
@@ -8,6 +9,32 @@ import { z } from 'zod';
|
|
|
8
9
|
*/
|
|
9
10
|
export declare const ClassifierDispositionSchema: z.ZodEnum<["structural", "behavioral"]>;
|
|
10
11
|
export type ClassifierDisposition = z.infer<typeof ClassifierDispositionSchema>;
|
|
12
|
+
/**
|
|
13
|
+
* ADR-112 — the minimal candidate shape the compile actuator (`compileCandidate`
|
|
14
|
+
* / `runCompileStage`) actually reads. BOTH the mined `CandidateRuleRecord` and an
|
|
15
|
+
* authored-derived candidate (via `toCompileFeed`) satisfy it: `provenance` is the
|
|
16
|
+
* `mined | authored` union, so ONE compiler accepts either producer without an
|
|
17
|
+
* authored rule masquerading as a classify result (ADR-112 §2 — a parallel
|
|
18
|
+
* front-end to one compiler, never a second compiler). The mined
|
|
19
|
+
* `CandidateRuleRecord` (whose `provenance` is the narrower `MinedProvenanceRecord`)
|
|
20
|
+
* is assignable to this shape; so is the authored compile-feed candidate.
|
|
21
|
+
*/
|
|
22
|
+
export interface CompileInputCandidate {
|
|
23
|
+
provenance: ProvenanceRecord;
|
|
24
|
+
classifierDisposition: ClassifierDisposition;
|
|
25
|
+
classifierLedgerRef: string;
|
|
26
|
+
dslSource: string;
|
|
27
|
+
/**
|
|
28
|
+
* ADR-112 §3 (#2259/#7) — the engine the structural-eligibility whitelist judged
|
|
29
|
+
* this rule for (AUTHORED producer only). When present, `compileCandidate` asserts
|
|
30
|
+
* the compiled engine MATCHES it: a regex-whitelisted rule whose `dslSource` parses
|
|
31
|
+
* as ast-grep is a contract violation (the eligibility verdict was engine-specific),
|
|
32
|
+
* not a silent re-route. The MINED producer omits it — its engine + identity are
|
|
33
|
+
* `dslSource`-derived, so it carries no independent declaration to bind against.
|
|
34
|
+
*/
|
|
35
|
+
declaredEngine?: 'regex' | 'ast' | 'ast-grep';
|
|
36
|
+
unverified: true;
|
|
37
|
+
}
|
|
11
38
|
/**
|
|
12
39
|
* ADR-111 §3 — the miner's sole output envelope, minted `unverified`/Yellow
|
|
13
40
|
* with no hand-curation. A candidate that cannot produce a complete provenance
|
|
@@ -23,6 +50,7 @@ export declare const CandidateRuleRecordSchema: z.ZodObject<{
|
|
|
23
50
|
* schema-unconstructible (FM(a)).
|
|
24
51
|
*/
|
|
25
52
|
provenance: z.ZodObject<{
|
|
53
|
+
kind: z.ZodOptional<z.ZodLiteral<"mined">>;
|
|
26
54
|
mergedPr: z.ZodNumber;
|
|
27
55
|
reviewThread: z.ZodEffects<z.ZodString, string, string>;
|
|
28
56
|
commitSha: z.ZodString;
|
|
@@ -30,10 +58,12 @@ export declare const CandidateRuleRecordSchema: z.ZodObject<{
|
|
|
30
58
|
mergedPr: number;
|
|
31
59
|
reviewThread: string;
|
|
32
60
|
commitSha: string;
|
|
61
|
+
kind?: "mined" | undefined;
|
|
33
62
|
}, {
|
|
34
63
|
mergedPr: number;
|
|
35
64
|
reviewThread: string;
|
|
36
65
|
commitSha: string;
|
|
66
|
+
kind?: "mined" | undefined;
|
|
37
67
|
}>;
|
|
38
68
|
/** Stage-2 disposition. `behavioral` ⇒ RAG-only, never compiled (FM(c)). */
|
|
39
69
|
classifierDisposition: z.ZodEnum<["structural", "behavioral"]>;
|
|
@@ -64,6 +94,7 @@ export declare const CandidateRuleRecordSchema: z.ZodObject<{
|
|
|
64
94
|
mergedPr: number;
|
|
65
95
|
reviewThread: string;
|
|
66
96
|
commitSha: string;
|
|
97
|
+
kind?: "mined" | undefined;
|
|
67
98
|
};
|
|
68
99
|
unverified: true;
|
|
69
100
|
classifierDisposition: "structural" | "behavioral";
|
|
@@ -74,6 +105,7 @@ export declare const CandidateRuleRecordSchema: z.ZodObject<{
|
|
|
74
105
|
mergedPr: number;
|
|
75
106
|
reviewThread: string;
|
|
76
107
|
commitSha: string;
|
|
108
|
+
kind?: "mined" | undefined;
|
|
77
109
|
};
|
|
78
110
|
unverified: true;
|
|
79
111
|
classifierDisposition: "structural" | "behavioral";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"candidate-rule.d.ts","sourceRoot":"","sources":["../../src/spine/candidate-rule.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"candidate-rule.d.ts","sourceRoot":"","sources":["../../src/spine/candidate-rule.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAA6B,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzF;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,yCAAuC,CAAC;AAChF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF;;;;;;;;;GASG;AACH,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,gBAAgB,CAAC;IAC7B,qBAAqB,EAAE,qBAAqB,CAAC;IAC7C,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,UAAU,CAAC;IAC9C,UAAU,EAAE,IAAI,CAAC;CAClB;AAED;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB;IACpC;;;;;;OAMG;;;;;;;;;;;;;;;;;IAEH,4EAA4E;;IAE5E;;;;;;OAMG;;IAIH;;;;;OAKG;;IAIH;;;;;OAKG;;;;;;;;;;;;;;;;;;;;;;;;EAEH,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC"}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// (ADR-089): `unverified: true` forces `deriveRuleClass` to 'advisory' on any
|
|
13
13
|
// later projection, so a candidate can never mint as `hard`.
|
|
14
14
|
import { z } from 'zod';
|
|
15
|
-
import {
|
|
15
|
+
import { MinedProvenanceWireSchema } from '../compiler-schema.js';
|
|
16
16
|
/**
|
|
17
17
|
* Stage-2 classifier disposition (ADR-091 funnel, the gate). A `structural`
|
|
18
18
|
* (syntactic-invariant) candidate is compile-eligible; a `behavioral` candidate
|
|
@@ -35,7 +35,7 @@ export const CandidateRuleRecordSchema = z.object({
|
|
|
35
35
|
* downstream projection — no rename seam. An incomplete tuple is
|
|
36
36
|
* schema-unconstructible (FM(a)).
|
|
37
37
|
*/
|
|
38
|
-
provenance:
|
|
38
|
+
provenance: MinedProvenanceWireSchema,
|
|
39
39
|
/** Stage-2 disposition. `behavioral` ⇒ RAG-only, never compiled (FM(c)). */
|
|
40
40
|
classifierDisposition: ClassifierDispositionSchema,
|
|
41
41
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"candidate-rule.js","sourceRoot":"","sources":["../../src/spine/candidate-rule.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,8EAA8E;AAC9E,+EAA+E;AAC/E,yEAAyE;AACzE,2EAA2E;AAC3E,4EAA4E;AAC5E,wEAAwE;AACxE,gFAAgF;AAChF,yEAAyE;AACzE,yEAAyE;AACzE,8EAA8E;AAC9E,6DAA6D;AAE7D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"candidate-rule.js","sourceRoot":"","sources":["../../src/spine/candidate-rule.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,8EAA8E;AAC9E,+EAA+E;AAC/E,yEAAyE;AACzE,2EAA2E;AAC3E,4EAA4E;AAC5E,wEAAwE;AACxE,gFAAgF;AAChF,yEAAyE;AACzE,yEAAyE;AACzE,8EAA8E;AAC9E,6DAA6D;AAE7D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,yBAAyB,EAAyB,MAAM,uBAAuB,CAAC;AAEzF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;AA8BhF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD;;;;;;OAMG;IACH,UAAU,EAAE,yBAAyB;IACrC,4EAA4E;IAC5E,qBAAqB,EAAE,2BAA2B;IAClD;;;;;;OAMG;IACH,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE;QACjE,OAAO,EAAE,0DAA0D;KACpE,CAAC;IACF;;;;;OAKG;IACH,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE;QACvD,OAAO,EAAE,6BAA6B;KACvC,CAAC;IACF;;;;;OAKG;IACH,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;CAC5B,CAAC,CAAC"}
|
package/dist/spine/classify.d.ts
CHANGED
|
@@ -10,19 +10,19 @@ import { type ClassifierLedger, type EmissionLedger, type MinerLedgers, type Rou
|
|
|
10
10
|
*/
|
|
11
11
|
export declare const ClassifierResultSchema: z.ZodEffects<z.ZodObject<{
|
|
12
12
|
disposition: z.ZodEnum<["structural", "behavioral"]>;
|
|
13
|
-
dispositionSource: z.ZodEnum<["classified", "error-default"]>;
|
|
13
|
+
dispositionSource: z.ZodEnum<["classified", "error-default", "authored-whitelist"]>;
|
|
14
14
|
}, "strip", z.ZodTypeAny, {
|
|
15
15
|
disposition: "structural" | "behavioral";
|
|
16
|
-
dispositionSource: "classified" | "error-default";
|
|
16
|
+
dispositionSource: "classified" | "error-default" | "authored-whitelist";
|
|
17
17
|
}, {
|
|
18
18
|
disposition: "structural" | "behavioral";
|
|
19
|
-
dispositionSource: "classified" | "error-default";
|
|
19
|
+
dispositionSource: "classified" | "error-default" | "authored-whitelist";
|
|
20
20
|
}>, {
|
|
21
21
|
disposition: "structural" | "behavioral";
|
|
22
|
-
dispositionSource: "classified" | "error-default";
|
|
22
|
+
dispositionSource: "classified" | "error-default" | "authored-whitelist";
|
|
23
23
|
}, {
|
|
24
24
|
disposition: "structural" | "behavioral";
|
|
25
|
-
dispositionSource: "classified" | "error-default";
|
|
25
|
+
dispositionSource: "classified" | "error-default" | "authored-whitelist";
|
|
26
26
|
}>;
|
|
27
27
|
export type ClassifierResult = z.infer<typeof ClassifierResultSchema>;
|
|
28
28
|
/**
|
package/dist/spine/compile.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { type CompiledRule, type ProvenanceRecord } from '../compiler-schema.js';
|
|
2
2
|
import { type Stage4Baseline, type Stage4VerificationResult, type Stage4VerifierDeps } from '../stage4-verifier.js';
|
|
3
|
-
import type {
|
|
4
|
-
import type { ClassifyStageResult } from './classify.js';
|
|
3
|
+
import type { CompileInputCandidate } from './candidate-rule.js';
|
|
5
4
|
import type { ClassifierLedger } from './ledgers.js';
|
|
6
5
|
/**
|
|
7
6
|
* The slice-4 output: a compiled, Stage-4-verified candidate. Carries `provenance`
|
|
@@ -16,6 +15,19 @@ export interface CompiledCandidate {
|
|
|
16
15
|
rule: CompiledRule;
|
|
17
16
|
stage4: Stage4VerificationResult;
|
|
18
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* ADR-112 §2 — the minimal input `runCompileStage` consumes: the candidates + the
|
|
20
|
+
* classifier ledger. A miner `ClassifyStageResult` satisfies it structurally (its
|
|
21
|
+
* extra `emissionLedger` is never read here); the authored producer's
|
|
22
|
+
* `toCompileFeed` builds it WITHOUT a mining emission ledger (an authored rule has
|
|
23
|
+
* no review-thread emission to attest, and the classifier ledger carries
|
|
24
|
+
* `dispositionSource: 'authored-whitelist'`, not a fabricated `'classified'`). One
|
|
25
|
+
* compiler, two producers — neither masquerading as the other.
|
|
26
|
+
*/
|
|
27
|
+
export interface CompileStageInput {
|
|
28
|
+
candidates: readonly CompileInputCandidate[];
|
|
29
|
+
classifierLedger: ClassifierLedger;
|
|
30
|
+
}
|
|
19
31
|
/** Pure compile outcome (no IO): a compiled rule, or a loud per-engine validation rejection. */
|
|
20
32
|
export type CompileOutcome = {
|
|
21
33
|
kind: 'compiled';
|
|
@@ -45,7 +57,7 @@ export interface CompileStageResult {
|
|
|
45
57
|
* `rejected` outcome (NOT a throw) when the pattern parses but fails per-engine
|
|
46
58
|
* safety validation (e.g. ReDoS) — a counted, reported `compile-rejected` state.
|
|
47
59
|
*/
|
|
48
|
-
export declare function compileCandidate(candidate:
|
|
60
|
+
export declare function compileCandidate(candidate: CompileInputCandidate, opts: {
|
|
49
61
|
now: string;
|
|
50
62
|
}): CompileOutcome;
|
|
51
63
|
/**
|
|
@@ -58,5 +70,5 @@ export declare function compileCandidate(candidate: CandidateRuleRecord, opts: {
|
|
|
58
70
|
* new entries array — updated entries are spread copies, unmodified entries share
|
|
59
71
|
* the original reference (a structural copy, not a deep copy).
|
|
60
72
|
*/
|
|
61
|
-
export declare function runCompileStage(classify:
|
|
73
|
+
export declare function runCompileStage(classify: CompileStageInput, deps: CompileStageDeps): Promise<CompileStageResult>;
|
|
62
74
|
//# sourceMappingURL=compile.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/spine/compile.ts"],"names":[],"mappings":"AAyBA,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,gBAAgB,EACtB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAEL,KAAK,cAAc,EAEnB,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EAExB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/spine/compile.ts"],"names":[],"mappings":"AAyBA,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,gBAAgB,EACtB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAEL,KAAK,cAAc,EAEnB,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EAExB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAuB,MAAM,cAAc,CAAC;AAE1E;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,gBAAgB,CAAC;IAC7B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,wBAAwB,CAAC;CAClC;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC7C,gBAAgB,EAAE,gBAAgB,CAAC;CACpC;AAED,gGAAgG;AAChG,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,YAAY,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,gFAAgF;IAChF,GAAG,EAAE,MAAM,CAAC;IACZ,iFAAiF;IACjF,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,2GAA2G;IAC3G,gBAAgB,EAAE,gBAAgB,CAAC;CACpC;AAOD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,qBAAqB,EAChC,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GACpB,cAAc,CA2DhB;AA6DD;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,kBAAkB,CAAC,CAyF7B"}
|
package/dist/spine/compile.js
CHANGED
|
@@ -81,6 +81,15 @@ export function compileCandidate(candidate, opts) {
|
|
|
81
81
|
// claim — codex). `deriveRuleClass` forces 'advisory' on `unverified:true`.
|
|
82
82
|
unverified: true,
|
|
83
83
|
});
|
|
84
|
+
// §3 engine-binding (#2259/#7): an AUTHORED candidate carries the engine its
|
|
85
|
+
// structural-eligibility whitelist was judged for. The compiler derives the engine
|
|
86
|
+
// INDEPENDENTLY from `dslSource`, so a regex-whitelisted rule whose source parses as
|
|
87
|
+
// ast-grep would otherwise compile + emit as `authored-whitelist` under an engine the
|
|
88
|
+
// whitelist never cleared. Fail loud — the eligibility verdict was engine-specific.
|
|
89
|
+
// MINED candidates carry no `declaredEngine` and skip the bind (engine is source-derived).
|
|
90
|
+
if (candidate.declaredEngine !== undefined && rule.engine !== candidate.declaredEngine) {
|
|
91
|
+
throw new Error(`[Totem Error] compileCandidate: candidate '${candidate.classifierLedgerRef}' declared engine '${candidate.declaredEngine}' but its dslSource compiled as '${rule.engine}' — the structural-eligibility whitelist was judged for a different engine (ADR-112 §3)`);
|
|
92
|
+
}
|
|
84
93
|
return { kind: 'compiled', rule };
|
|
85
94
|
}
|
|
86
95
|
/**
|
|
@@ -157,6 +166,20 @@ export async function runCompileStage(classify, deps) {
|
|
|
157
166
|
const compiled = [];
|
|
158
167
|
const updates = new Map();
|
|
159
168
|
const structural = classify.candidates.filter((c) => c.classifierDisposition === 'structural');
|
|
169
|
+
// Duplicate-candidate-ref guard (#2259, greptile-P1 outside-diff): the per-candidate
|
|
170
|
+
// ledger join below requires EXACTLY ONE ledger entry, but two CANDIDATES sharing one
|
|
171
|
+
// `classifierLedgerRef` would BOTH pass that check against a single entry — then the
|
|
172
|
+
// later Stage-4 update silently overwrites the earlier in `updates`, leaving one compiled
|
|
173
|
+
// rule bound to the wrong outcome. The widened input accepts either producer, so uniqueness
|
|
174
|
+
// is no longer guaranteed by a single front-end; assert it here, fail loud before any
|
|
175
|
+
// compile work (symmetric with `toCompileFeed`'s authored-side dedup).
|
|
176
|
+
const seenRefs = new Set();
|
|
177
|
+
for (const candidate of structural) {
|
|
178
|
+
if (seenRefs.has(candidate.classifierLedgerRef)) {
|
|
179
|
+
throw new Error(`[Totem Error] runCompileStage: duplicate classifierLedgerRef '${candidate.classifierLedgerRef}' across structural candidates — each compile candidate needs a unique ledger ref for the 1:1 Stage-4 join`);
|
|
180
|
+
}
|
|
181
|
+
seenRefs.add(candidate.classifierLedgerRef);
|
|
182
|
+
}
|
|
160
183
|
for (const candidate of structural) {
|
|
161
184
|
// Classifier-ledger join: require EXACTLY ONE entry (missing or duplicate fails
|
|
162
185
|
// loud — else the Stage-4 confirmation is lost or applied to the wrong row).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/spine/compile.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,EAAE;AACF,2EAA2E;AAC3E,+EAA+E;AAC/E,8EAA8E;AAC9E,iFAAiF;AACjF,0EAA0E;AAC1E,EAAE;AACF,kFAAkF;AAClF,uEAAuE;AACvE,mFAAmF;AACnF,6EAA6E;AAC7E,gFAAgF;AAChF,kFAAkF;AAClF,iFAAiF;AACjF,kFAAkF;AAClF,8EAA8E;AAE9E,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAChF,kFAAkF;AAClF,mFAAmF;AACnF,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC5F,OAAO,EAEL,kBAAkB,GAEnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,oBAAoB,EAAsB,MAAM,sBAAsB,CAAC;AAChF,OAAO,EACL,kBAAkB,EAKlB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/spine/compile.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { mintAuthoredRuleId, toCompileFeed } from './authored-rule.js';
|
|
2
3
|
import { runClassifyStage, } from './classify.js';
|
|
3
4
|
import { compileCandidate, runCompileStage, } from './compile.js';
|
|
4
5
|
import { runFalsificationHarness } from './miner-harness.js';
|
|
@@ -328,4 +329,72 @@ describe('runCompileStage — end-to-end §8 harness lock', () => {
|
|
|
328
329
|
expect(clauses).toContain('stage4-consistency');
|
|
329
330
|
});
|
|
330
331
|
});
|
|
332
|
+
// ── runCompileStage — ADR-112 authored compile-feed (one compiler, two producers) ──
|
|
333
|
+
describe('runCompileStage — ADR-112 authored compile-feed', () => {
|
|
334
|
+
const authored = (ref, dsl) => ({
|
|
335
|
+
ruleId: mintAuthoredRuleId('totem-claude', ref, new Set()),
|
|
336
|
+
provenance: {
|
|
337
|
+
kind: 'authored',
|
|
338
|
+
author: 'totem-claude',
|
|
339
|
+
authoredAt: '2026-06-27',
|
|
340
|
+
targetDefect: 'calls forbiddenCall()',
|
|
341
|
+
positiveFixtures: [
|
|
342
|
+
{
|
|
343
|
+
pr: 1,
|
|
344
|
+
mergeCommitSha: sha(1),
|
|
345
|
+
preimageCommitSha: sha(2),
|
|
346
|
+
filePath: 'src/a.ts',
|
|
347
|
+
matchedSpan: 'L1',
|
|
348
|
+
contentHash: 'h1',
|
|
349
|
+
},
|
|
350
|
+
],
|
|
351
|
+
},
|
|
352
|
+
structuralEligibility: {
|
|
353
|
+
decidable: true,
|
|
354
|
+
basis: 'whitelist:forbidden-call',
|
|
355
|
+
judgedBy: 'static-whitelist@cert-1',
|
|
356
|
+
},
|
|
357
|
+
origin: { kind: 'from-scratch' },
|
|
358
|
+
declaredEngine: 'regex',
|
|
359
|
+
authoringLedgerRef: ref,
|
|
360
|
+
dslSource: dsl,
|
|
361
|
+
unverified: true,
|
|
362
|
+
});
|
|
363
|
+
it('compiles an authored rule through the SAME runCompileStage — authored provenance + Stage-4 preserved', async () => {
|
|
364
|
+
const feed = toCompileFeed([authored('alr-1', REGEX_DSL)]);
|
|
365
|
+
const r = await runCompileStage(feed, compileDeps({ 'src/a.ts': 'forbiddenCall()' }));
|
|
366
|
+
expect(r.compiled).toHaveLength(1);
|
|
367
|
+
const c = r.compiled[0];
|
|
368
|
+
// authored provenance survives the compiler untouched (the union, not a mined shape).
|
|
369
|
+
expect(c.provenance.kind).toBe('authored');
|
|
370
|
+
expect(c.classifierLedgerRef).toBe('authored:alr-1');
|
|
371
|
+
// Stage-4 actually ran on the authored rule's matcher (real codebase evidence).
|
|
372
|
+
expect(c.stage4.outcome).toBe('in-scope-bad-example');
|
|
373
|
+
// the ledger records the authored-whitelist source + the Stage-4 confirmation.
|
|
374
|
+
expect(r.classifierLedger.entries[0].dispositionSource).toBe('authored-whitelist');
|
|
375
|
+
expect(r.classifierLedger.entries[0].stage4Confirmed).toBe(true);
|
|
376
|
+
});
|
|
377
|
+
it('never reaches the compiler for a non-decidable authored rule (toCompileFeed throws first)', () => {
|
|
378
|
+
const nd = {
|
|
379
|
+
...authored('alr-x', REGEX_DSL),
|
|
380
|
+
structuralEligibility: { decidable: false, basis: 'whitelist:x', judgedBy: 's' },
|
|
381
|
+
};
|
|
382
|
+
expect(() => toCompileFeed([nd])).toThrow(/not structurally decidable/);
|
|
383
|
+
});
|
|
384
|
+
it('fails loud when the compiled engine disagrees with the whitelisted declaredEngine (#2259/#7)', async () => {
|
|
385
|
+
// declaredEngine 'ast' was whitelisted, but the dslSource parses as regex — the compiler
|
|
386
|
+
// must not emit it under an engine the eligibility check never cleared.
|
|
387
|
+
const feed = toCompileFeed([
|
|
388
|
+
{ ...authored('alr-eng', REGEX_DSL), declaredEngine: 'ast' },
|
|
389
|
+
]);
|
|
390
|
+
await expect(runCompileStage(feed, compileDeps({ 'src/a.ts': 'forbiddenCall()' }))).rejects.toThrow(/declared engine 'ast' but its dslSource compiled as 'regex'/);
|
|
391
|
+
});
|
|
392
|
+
it('fails loud on two structural candidates sharing one classifierLedgerRef (#2259 greptile-P1)', async () => {
|
|
393
|
+
const base = toCompileFeed([authored('dup', REGEX_DSL)]);
|
|
394
|
+
// Two candidates, ONE ledger entry: each would pass the exactly-one-entry join, then the
|
|
395
|
+
// later Stage-4 update would overwrite the earlier — the dedup guard rejects it up front.
|
|
396
|
+
const feed = [base.candidates[0], base.candidates[0]];
|
|
397
|
+
await expect(runCompileStage({ ...base, candidates: feed }, compileDeps({ 'src/a.ts': 'forbiddenCall()' }))).rejects.toThrow(/duplicate classifierLedgerRef/);
|
|
398
|
+
});
|
|
399
|
+
});
|
|
331
400
|
//# sourceMappingURL=compile.test.js.map
|