@mmnto/totem 1.118.1 → 1.119.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 (111) hide show
  1. package/dist/artifacts/admission.d.ts +12 -12
  2. package/dist/artifacts/verdict.d.ts +16 -16
  3. package/dist/compile-manifest.d.ts +89 -0
  4. package/dist/compile-manifest.d.ts.map +1 -1
  5. package/dist/compile-manifest.js +180 -31
  6. package/dist/compile-manifest.js.map +1 -1
  7. package/dist/compile-manifest.test.js +169 -1
  8. package/dist/compile-manifest.test.js.map +1 -1
  9. package/dist/compiler-schema.d.ts +1067 -0
  10. package/dist/compiler-schema.d.ts.map +1 -1
  11. package/dist/compiler-schema.js +204 -1
  12. package/dist/compiler-schema.js.map +1 -1
  13. package/dist/compiler-schema.test.js +92 -0
  14. package/dist/compiler-schema.test.js.map +1 -1
  15. package/dist/compiler.d.ts +2 -6
  16. package/dist/compiler.d.ts.map +1 -1
  17. package/dist/compiler.js +6 -17
  18. package/dist/compiler.js.map +1 -1
  19. package/dist/freeze.d.ts +3 -3
  20. package/dist/index.d.ts +12 -3
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +6 -2
  23. package/dist/index.js.map +1 -1
  24. package/dist/ledger.d.ts +12 -12
  25. package/dist/regex-safety/apply-rules-bounded.d.ts +11 -0
  26. package/dist/regex-safety/apply-rules-bounded.d.ts.map +1 -1
  27. package/dist/regex-safety/apply-rules-bounded.js +59 -5
  28. package/dist/regex-safety/apply-rules-bounded.js.map +1 -1
  29. package/dist/regex-validation.d.ts +7 -0
  30. package/dist/regex-validation.d.ts.map +1 -0
  31. package/dist/regex-validation.js +32 -0
  32. package/dist/regex-validation.js.map +1 -0
  33. package/dist/rule-engine.d.ts +11 -1
  34. package/dist/rule-engine.d.ts.map +1 -1
  35. package/dist/rule-engine.js +125 -18
  36. package/dist/rule-engine.js.map +1 -1
  37. package/dist/spine/authored-rule.d.ts +669 -245
  38. package/dist/spine/authored-rule.d.ts.map +1 -1
  39. package/dist/spine/authored-rule.js +113 -27
  40. package/dist/spine/authored-rule.js.map +1 -1
  41. package/dist/spine/authored-rule.test.js +170 -4
  42. package/dist/spine/authored-rule.test.js.map +1 -1
  43. package/dist/spine/authoring-ledger.d.ts +69 -10
  44. package/dist/spine/authoring-ledger.d.ts.map +1 -1
  45. package/dist/spine/authoring-ledger.js +46 -25
  46. package/dist/spine/authoring-ledger.js.map +1 -1
  47. package/dist/spine/authoring-ledger.test.js +20 -7
  48. package/dist/spine/authoring-ledger.test.js.map +1 -1
  49. package/dist/spine/candidate-rule.d.ts +18 -1
  50. package/dist/spine/candidate-rule.d.ts.map +1 -1
  51. package/dist/spine/candidate-rule.js.map +1 -1
  52. package/dist/spine/cert-corpus-seed.d.ts +8 -8
  53. package/dist/spine/compile.d.ts +4 -1
  54. package/dist/spine/compile.d.ts.map +1 -1
  55. package/dist/spine/compile.js +50 -3
  56. package/dist/spine/compile.js.map +1 -1
  57. package/dist/spine/compile.test.js +189 -23
  58. package/dist/spine/compile.test.js.map +1 -1
  59. package/dist/spine/frozen-split.d.ts +18 -18
  60. package/dist/spine/ledgers.d.ts +24 -24
  61. package/dist/spine/lf-normalize.d.ts +9 -0
  62. package/dist/spine/lf-normalize.d.ts.map +1 -0
  63. package/dist/spine/lf-normalize.js +38 -0
  64. package/dist/spine/lf-normalize.js.map +1 -0
  65. package/dist/spine/preimage-differential.d.ts +3 -1
  66. package/dist/spine/preimage-differential.d.ts.map +1 -1
  67. package/dist/spine/preimage-differential.js +9 -6
  68. package/dist/spine/preimage-differential.js.map +1 -1
  69. package/dist/spine/preimage-differential.test.js +59 -0
  70. package/dist/spine/preimage-differential.test.js.map +1 -1
  71. package/dist/spine/record-exemplars.fixture.d.ts +5 -0
  72. package/dist/spine/record-exemplars.fixture.d.ts.map +1 -0
  73. package/dist/spine/record-exemplars.fixture.js +61 -0
  74. package/dist/spine/record-exemplars.fixture.js.map +1 -0
  75. package/dist/spine/record-lower.d.ts +90 -0
  76. package/dist/spine/record-lower.d.ts.map +1 -0
  77. package/dist/spine/record-lower.js +418 -0
  78. package/dist/spine/record-lower.js.map +1 -0
  79. package/dist/spine/record-lower.test.d.ts +2 -0
  80. package/dist/spine/record-lower.test.d.ts.map +1 -0
  81. package/dist/spine/record-lower.test.js +562 -0
  82. package/dist/spine/record-lower.test.js.map +1 -0
  83. package/dist/spine/record-runtime.d.ts +215 -0
  84. package/dist/spine/record-runtime.d.ts.map +1 -0
  85. package/dist/spine/record-runtime.js +330 -0
  86. package/dist/spine/record-runtime.js.map +1 -0
  87. package/dist/spine/record-runtime.test.d.ts +2 -0
  88. package/dist/spine/record-runtime.test.d.ts.map +1 -0
  89. package/dist/spine/record-runtime.test.js +814 -0
  90. package/dist/spine/record-runtime.test.js.map +1 -0
  91. package/dist/spine/rule-record.d.ts +864 -0
  92. package/dist/spine/rule-record.d.ts.map +1 -0
  93. package/dist/spine/rule-record.js +781 -0
  94. package/dist/spine/rule-record.js.map +1 -0
  95. package/dist/spine/rule-record.test.d.ts +2 -0
  96. package/dist/spine/rule-record.test.d.ts.map +1 -0
  97. package/dist/spine/rule-record.test.js +1262 -0
  98. package/dist/spine/rule-record.test.js.map +1 -0
  99. package/dist/spine/windtunnel-firing.d.ts.map +1 -1
  100. package/dist/spine/windtunnel-firing.js +28 -1
  101. package/dist/spine/windtunnel-firing.js.map +1 -1
  102. package/dist/spine/windtunnel-lock.d.ts +10 -10
  103. package/dist/stage4-verifier.d.ts.map +1 -1
  104. package/dist/stage4-verifier.js +61 -17
  105. package/dist/stage4-verifier.js.map +1 -1
  106. package/dist/sys/glob.d.ts +30 -0
  107. package/dist/sys/glob.d.ts.map +1 -1
  108. package/dist/sys/glob.js +62 -1
  109. package/dist/sys/glob.js.map +1 -1
  110. package/dist/types.d.ts +1 -1
  111. package/package.json +1 -1
@@ -0,0 +1,418 @@
1
+ // ─── Prop 310 V1 record grammar — the LOWERING (slice 2 of the V1 build) ──────
2
+ //
3
+ // Slice 1 (`rule-record.ts`) turns record bytes into a validated
4
+ // `ParsedRuleRecord`. This module turns that value into a `CompiledRule`. It is
5
+ // the § Design 1 seam replacement for records: the record path does NOT go
6
+ // through `extractManualPattern` or `CompileInputCandidate.dslSource`, because
7
+ // the record is ALREADY parsed — re-serializing it into lesson markdown just to
8
+ // re-parse it would reintroduce the incumbent grammar this proposal supersedes.
9
+ // What is reused is the VALIDATORS (`validateRegex`, `validateAstGrepPattern`)
10
+ // and the field builder (`engineFields`), never the parser and never the frozen
11
+ // `LessonInput` actuator.
12
+ //
13
+ // § Design 12 (R2) is this slice's charter: **every construct the parser admits
14
+ // either lands on the compiled record or fails compile LOUD.** No construct is
15
+ // accepted at parse and dropped at compile. That obligation is enforced
16
+ // mechanically here, not by inspection — see § "Total lowering, mechanically".
17
+ //
18
+ // ── OPERATOR RULING 2026-08-21 (tree-form) ───────────────────────────────────
19
+ //
20
+ // `target.rule` is the ast-grep RULE TREE, not a whole NapiConfig — the
21
+ // exemplar-faithful reading of § Design 4's "NapiConfig subset" (its exemplar
22
+ // shows `rule: {kind: catch_clause, not: {...}}`, a rule tree, with `language`
23
+ // living one level up at `target.language`).
24
+ //
25
+ // - LOWERING DERIVES the NapiConfig wrapper: `{rule: <tree>, language: <napi
26
+ // language derived from the resolved `target.language`>}`. The record
27
+ // therefore never carries a duplicate language home (§ Design 3's no-mirror
28
+ // discipline; Tenet 20) and no language COLLISION between the payload
29
+ // interior and `target.language` is representable.
30
+ // - `constraints` / `utils` are INEXPRESSIBLE at V1 (censused: zero of the 19
31
+ // compound corpus rules use them). Demand becomes a typed `construct-gap` at
32
+ // the R14 trial plus a grammar version bump giving each its own SIBLING home
33
+ // under `target:` — never a silent smuggle inside the rule tree, which is
34
+ // why the tree gate below names them explicitly instead of leaving them to
35
+ // napi's generic unknown-field error.
36
+ //
37
+ // Grounds of record: the spec-normative exemplar (§ Design 14's normativity
38
+ // flip), language-collision avoidance, and zero corpus cost.
39
+ //
40
+ // ── Identity ─────────────────────────────────────────────────────────────────
41
+ //
42
+ // Identity is an INPUT, never minted here (§ Design 3 / R17): the ADR-112 §8
43
+ // producer mints `ruleId` at the intake seam and slice 3 threads it in. This
44
+ // function asserts it is well-formed and makes it the compiled identity
45
+ // (`lessonHash ← ruleId`, the §8/§9 `firingLabelId ← ruleId` unification), and
46
+ // NEVER hashes `dslSource` — there is no `dslSource` on this path, and a
47
+ // content-derived id would orphan the rule's ground-truth labels on every
48
+ // matcher edit.
49
+ //
50
+ // ── Freeze boundary ──────────────────────────────────────────────────────────
51
+ //
52
+ // `sanitizeFileGlobs` is NEVER called here. The record's globs were validated at
53
+ // parse against § Design 7's strict dialect and are carried BYTE-VERBATIM:
54
+ // brace expansion and shallow-glob promotion are exactly the silent transforms
55
+ // the grammar kills (§ Design 7's conformance-scope paragraph), while the
56
+ // sanitizer's tolerant behaviour for the FROZEN legacy lesson corpus is
57
+ // untouched — the freeze covers that path and nothing regenerates it.
58
+ import { extensionToLanguage, registeredExtensions } from '../ast-classifier.js';
59
+ import { extensionToLang, TRAILING_EXT_RE } from '../ast-grep-query.js';
60
+ import { validateAstGrepPattern } from '../compile-lesson.js';
61
+ import { engineFields, validateRegex } from '../compiler.js';
62
+ import { CompiledRuleSchema } from '../compiler-schema.js';
63
+ import { AUTHORED_RULE_ID_RE } from './authored-rule.js';
64
+ /**
65
+ * Resolve `target.language` against the registry, using `extensionToLanguage` as
66
+ * the authority verbatim (§ Design 6). Deterministic: `registeredExtensions()`
67
+ * returns a sorted snapshot, so the representative extension for a language with
68
+ * several (`.ts`/`.mts`/`.cts` → `typescript`) is always the same one — and every
69
+ * extension of one language maps to the same napi grammar anyway, so the pick
70
+ * cannot change the validation verdict, only the diagnostic.
71
+ *
72
+ * An unresolvable language FAILS LOUD (§ Design 6 / § Failure modes: "Unresolvable
73
+ * `language:` at compile — hard error"). It is surfaced as a `rejected` outcome
74
+ * rather than a throw, matching the incumbent's treatment of every other
75
+ * authored-content validation failure: `rejected` is a counted, reported,
76
+ * NON-silent state, while throws are reserved for producer-contract violations
77
+ * (a malformed id, a payload/type divergence) — see `compileRuleRecord`.
78
+ */
79
+ export function resolveRecordLanguage(language) {
80
+ const extensions = registeredExtensions();
81
+ const extension = extensions.find((ext) => extensionToLanguage(ext) === language);
82
+ if (extension === undefined) {
83
+ const known = [...new Set(extensions.map((ext) => extensionToLanguage(ext)))]
84
+ .filter((lang) => lang !== undefined)
85
+ .sort();
86
+ return {
87
+ resolved: false,
88
+ reason: `Prop 310 § Design 6: target.language '${language}' is not registered — the resolution authority is the Map-backed extensionToLanguage registry (built-ins + pack contributions), never a spec-frozen enum. Registered languages: ${known.join(', ') || '(none)'}. Install the pack that provides this language, or correct the record.`,
89
+ };
90
+ }
91
+ return { resolved: true, language, extension };
92
+ }
93
+ /**
94
+ * The glob list handed to `validateAstGrepPattern` so it resolves to EXACTLY the
95
+ * declared language.
96
+ *
97
+ * The shipped validator's language input is a glob list (`resolveAstGrepLangs`
98
+ * derives Langs from trailing extensions), so pinning it to one grammar means
99
+ * handing it one glob carrying one registered extension. These globs are a
100
+ * VALIDATOR PROBE and nothing else — they are never the record's globs, never
101
+ * reach the compiled rule, and never touch `sanitizeFileGlobs`.
102
+ *
103
+ * The coupling to `resolveAstGrepLangs`' derivation is pinned by a conformance
104
+ * test (`record-lower.test.ts`: the probe resolves to exactly one Lang, and that
105
+ * Lang equals `extensionToLang(extension)`), so a change to the shipped
106
+ * derivation fails loud here instead of silently un-pinning the record path.
107
+ */
108
+ export function languageProbeGlobs(extension) {
109
+ return [`**/*${extension}`];
110
+ }
111
+ // ── The language⇄glob consistency floor ──────────────────────────────────────
112
+ //
113
+ // OPERATOR-CONSISTENT RULING (falsification round, 2026-08-21): for a
114
+ // `type: ast-grep` record, EVERY `target.scope.fileGlobs` entry must end in a
115
+ // registered extension that resolves — via `extensionToLanguage`, the same
116
+ // § Design 6 authority — to the DECLARED `target.language`. Otherwise the record
117
+ // is rejected.
118
+ //
119
+ // Grounds. § Design 6 fixes ONE declared language per record and the options
120
+ // table spells out the consequence: "a multi-language ast-grep rule is N
121
+ // records". Without this floor a record could declare `language: typescript`
122
+ // and scope itself to `**\/*.js`, and the runtime — which dispatches ast-grep by
123
+ // FILE EXTENSION, not by the rule's compiled `language` — would then evaluate it
124
+ // under a grammar it was never validated against. The review demonstrated both
125
+ // halves of that gap: a compound payload fails inertly per file (a silent
126
+ // non-firing rule), and a flat pattern FIRES under the wrong grammar. Neither is
127
+ // visible to the author. With the floor, validated-as-declared and
128
+ // evaluated-by-extension agree BY CONSTRUCTION, so the runtime needs no
129
+ // language gate of its own.
130
+ //
131
+ // Scope of the floor, precisely:
132
+ // - `fileGlobs` only. `excludeGlobs` entries are EXEMPT: they only ever narrow
133
+ // an already-consistent positive scope, so an exclusion written against a
134
+ // different extension can widen nothing.
135
+ // - `type: regex` records are UNCHECKED — a regex payload has no grammar
136
+ // binding at all (`target.language` is forbidden there, § Design 4), and the
137
+ // match is textual, so the same globs are legitimate.
138
+ // - An EXTENSION-LESS glob (`packages/**`) rejects under the same rule: a
139
+ // scope that cannot be pinned to a language cannot be validated as it will
140
+ // be evaluated, and silently admitting it would reopen the gap for every
141
+ // file the directory happens to contain.
142
+ /**
143
+ * Check the § Design 6 one-declared-language rule against a record's positive
144
+ * globs. Returns `null` when the scope is consistent, or the rejection reason.
145
+ * ast-grep targets only — the caller does not invoke it for regex.
146
+ */
147
+ export function checkLanguageGlobConsistency(language, fileGlobs) {
148
+ const advice = `§ Design 6 fixes ONE declared language per record — "a multi-language ast-grep rule is N records". Split the rule per language, or correct the glob. (The runtime dispatches ast-grep by FILE EXTENSION, so a scope the declared language does not cover would be evaluated under a grammar the payload was never validated against.)`;
149
+ for (const glob of fileGlobs) {
150
+ const match = TRAILING_EXT_RE.exec(glob);
151
+ if (match === null) {
152
+ return `Prop 310 § Design 6: target.scope.fileGlobs entry '${glob}' carries no file extension, so its scope cannot be pinned to the declared language '${language}'. ${advice}`;
153
+ }
154
+ const extension = `.${match[1].toLowerCase()}`;
155
+ const globLanguage = extensionToLanguage(extension);
156
+ if (globLanguage === undefined) {
157
+ return `Prop 310 § Design 6: target.scope.fileGlobs entry '${glob}' targets extension '${extension}', which is not registered, so it cannot be confirmed to match the declared language '${language}'. ${advice}`;
158
+ }
159
+ if (globLanguage !== language) {
160
+ return `Prop 310 § Design 6: target.scope.fileGlobs entry '${glob}' targets language '${globLanguage}' but the record declares '${language}'. ${advice}`;
161
+ }
162
+ }
163
+ return null;
164
+ }
165
+ // ── The tree-form gate (operator ruling 2026-08-21) ──────────────────────────
166
+ /**
167
+ * NapiConfig siblings of `rule` that V1 cannot express. Named explicitly so the
168
+ * author is told the truth — a typed construct-gap awaiting a version bump with
169
+ * its own sibling home under `target:` — instead of napi's generic
170
+ * "unknown field" error, which would read as a typo in the rule tree.
171
+ */
172
+ export const V1_INEXPRESSIBLE_NAPI_KEYS = ['constraints', 'utils'];
173
+ const RECORD_KEY_LOWERING = {
174
+ schemaVersion: 'consumed-at-parse',
175
+ severity: 'compiled',
176
+ message: 'compiled',
177
+ recoveryHint: 'compiled',
178
+ target: 'compiled',
179
+ examples: 'compiled',
180
+ requires: 'compiled',
181
+ curation: 'compiled',
182
+ verification_shadow: 'compiled',
183
+ };
184
+ const TARGET_KEY_LOWERING = {
185
+ // `type` lowers to `engine` — and is re-derived INDEPENDENTLY from the payload's
186
+ // compilation path for the § Design 3 engine-binding assert.
187
+ type: 'compiled',
188
+ language: 'compiled',
189
+ pattern: 'compiled',
190
+ rule: 'compiled',
191
+ scope: 'compiled',
192
+ };
193
+ const SCOPE_KEY_LOWERING = {
194
+ fileGlobs: 'compiled',
195
+ excludeGlobs: 'compiled',
196
+ };
197
+ function assertKeysDispositioned(value, table, at) {
198
+ for (const key of Object.keys(value)) {
199
+ // `Object.hasOwn`, not `table[key] === undefined`: a key named `constructor`
200
+ // or `toString` would otherwise resolve up the prototype chain and read as
201
+ // "dispositioned". Slice 1's prototype floor already rejects those at parse,
202
+ // so nothing reaching here through `parseRuleRecord` can carry one — this is
203
+ // defence in depth for a hand-constructed `ParsedRuleRecord`, which is
204
+ // exactly the caller class this whole assertion exists for.
205
+ if (!Object.hasOwn(table, key)) {
206
+ throw new Error(`[Totem Error] compileRuleRecord: record key '${at}${key}' has no defined lowering — Prop 310 § Design 12 forbids accepting a construct at parse and dropping it at compile. Give it a compiled home (and a disposition in record-lower.ts) or reject it at parse.`);
207
+ }
208
+ }
209
+ }
210
+ /** § Design 12 — the runtime half of the total-lowering proof (see above). */
211
+ function assertTotalLowering(record) {
212
+ assertKeysDispositioned(record, RECORD_KEY_LOWERING, '');
213
+ assertKeysDispositioned(record.target, TARGET_KEY_LOWERING, 'target.');
214
+ assertKeysDispositioned(record.target.scope, SCOPE_KEY_LOWERING, 'target.scope.');
215
+ }
216
+ // ── The compiled engine, re-derived from the payload ─────────────────────────
217
+ /**
218
+ * Derive the engine from the fields `engineFields` actually produced. This is
219
+ * the INDEPENDENT second side of the § Design 3 engine-binding assert: one side
220
+ * is the record's `target.type` (via `derivedEngine`), the other is the payload's
221
+ * actual compilation path. § Design 3 is explicit that the derivation must not
222
+ * make the shipped assert tautological, and it does not — a payload routed
223
+ * through the wrong `engineFields` branch diverges here and fails loud.
224
+ */
225
+ function engineFromCompiledFields(fields) {
226
+ const hasAstGrep = (typeof fields.astGrepPattern === 'string' && fields.astGrepPattern.length > 0) ||
227
+ fields.astGrepYamlRule !== undefined;
228
+ if (hasAstGrep)
229
+ return 'ast-grep';
230
+ if (fields.pattern.length > 0)
231
+ return 'regex';
232
+ return 'unknown';
233
+ }
234
+ /**
235
+ * A stable, deterministic diagnostic label for a record-compiled rule.
236
+ *
237
+ * `CompiledRule.lessonHeading` is a required diagnostic field on a schema built
238
+ * for lesson-compiled rules; the record grammar has no heading construct and
239
+ * § Design 4's key space is closed against inventing one. Deriving the label
240
+ * from the identity mirrors the shipped authored-path idiom
241
+ * (`compile.ts: candidateHeading`) and deliberately does NOT copy `message` —
242
+ * two homes for the author's one sentence is Tenet 20's prohibited mirror, and
243
+ * a heading that drifts from the message would be worse than a generic one.
244
+ */
245
+ function recordHeading(ruleId) {
246
+ return `Prop 310 rule record (${ruleId})`;
247
+ }
248
+ /**
249
+ * Lower a parsed Prop 310 record into a `CompiledRule`.
250
+ *
251
+ * PURE (no IO). Returns a `CompileOutcome`:
252
+ * - `{kind: 'compiled'}` — the record lowered totally.
253
+ * - `{kind: 'rejected', reason}` — an authored-content gate failed (bad regex
254
+ * in the target or in `requires`, an unresolvable `language`, a malformed
255
+ * ast-grep tree, a V1-inexpressible NapiConfig key). Loud and counted, never
256
+ * silent; the reason names the governing § so the author is sent to the spec.
257
+ *
258
+ * THROWS on a producer-contract violation — a missing/malformed `ruleId`, a key
259
+ * with no defined lowering, or an engine-binding divergence. These are bugs in
260
+ * the code that CALLED this function, not defects in the author's record, and
261
+ * they carry the incumbent's fail-loud idiom (`compile.ts: compileCandidate`)
262
+ * verbatim: assert up front, before any validation work, so a violation can
263
+ * never be masked by a coincidental `rejected` outcome.
264
+ */
265
+ export function compileRuleRecord(parsed, opts) {
266
+ // ── Identity precondition, asserted UP FRONT (ADR-112 §8/§9) ──
267
+ if (!AUTHORED_RULE_ID_RE.test(opts.ruleId)) {
268
+ throw new Error(`[Totem Error] compileRuleRecord: malformed ruleId '${opts.ruleId}' — identity is minted by the ADR-112 §8 producer at the intake seam and threaded in (16 hex + optional -<n> suffix, ADR-112 §3/§8). The record grammar makes 'ruleId' INEXPRESSIBLE in-record (Prop 310 § Design 3/R17), so a malformed value here is a producer/threading bug; enthroning it would orphan the rule's controls.positive[].targetRuleId.`);
269
+ }
270
+ const record = parsed.record;
271
+ // ── § Design 12 — no construct is accepted at parse and dropped at compile ──
272
+ assertTotalLowering(record);
273
+ const target = record.target;
274
+ // ── Engine gates (§ Design 12: fail loud, never accept-then-drop) ──
275
+ //
276
+ // `requires.pattern` is gated on EVERY engine, not just regex: § Design 8 makes
277
+ // it "a safe-regex2-gated regex evaluated textually … independent of
278
+ // `target.type`", so an ast-grep rule's requirement is subject to the same
279
+ // ReDoS gate as a regex rule's target. Gated BEFORE the target payload so the
280
+ // author gets the first defect in a fixed, deterministic order.
281
+ if (record.requires !== undefined) {
282
+ const v = validateRegex(record.requires.pattern);
283
+ if (!v.valid) {
284
+ return {
285
+ kind: 'rejected',
286
+ reason: `Prop 310 § Design 8: requires.pattern is not a usable regex (${v.reason ?? 'invalid regex pattern'}) — the requirement is a safe-regex2-gated regex evaluated textually at the declared scope, independent of target.type.`,
287
+ };
288
+ }
289
+ // RULING (falsification round, 2026-08-21): `requires.scope: line` is
290
+ // REJECTED on an ast-grep target. An ast-grep match is a SPAN, not a line,
291
+ // so "the line containing L" has no engine-defined answer: the runtime reads
292
+ // the span's START line, which makes the verdict depend on how the author
293
+ // wrapped their source — the review measured a rule firing once when its
294
+ // subject was split across lines and not at all when it was written on one.
295
+ // A formatting-dependent verdict is not a semantic. § Design 8 already
296
+ // reserves `block` — the span's natural unit — as unimplemented pending a
297
+ // language adapter's boundary definition, so the honest V1 answer is to
298
+ // reject the combination rather than ship a line reading that only
299
+ // coincidentally agrees with the author's intent. `file` scope stays valid
300
+ // on ast-grep (whole-file text is unambiguous), and `line` stays valid on
301
+ // regex targets (a regex match IS line-local by construction).
302
+ if (record.target.type === 'ast-grep' && record.requires.scope === 'line') {
303
+ return {
304
+ kind: 'rejected',
305
+ reason: "Prop 310 § Design 8: `requires.scope: line` is not available on an `ast-grep` target — an ast-grep match is a SPAN, and reading it as its start line makes the verdict depend on source formatting rather than on the rule. Use `scope: file` (unambiguous on any engine), move the requirement into the payload's own `not:`/`has:` combinators (§ Design 8: node-scoped absence stays payload-owned), or wait for the reserved `block` unit, which is the span's natural scope and is unimplemented at V1.",
306
+ };
307
+ }
308
+ }
309
+ let payloadFields;
310
+ let resolvedLanguage;
311
+ if (target.type === 'regex') {
312
+ // The record grammar guarantees `pattern` present and `rule`/`language` absent
313
+ // for `type: regex`; the non-null assertion is the schema's contract, not an
314
+ // assumption (`RuleTargetSchema.superRefine`).
315
+ const pattern = target.pattern;
316
+ const v = validateRegex(pattern);
317
+ if (!v.valid) {
318
+ return {
319
+ kind: 'rejected',
320
+ reason: `Prop 310 § Design 6: target.pattern is not a usable regex (${v.reason ?? 'invalid regex pattern'}).`,
321
+ };
322
+ }
323
+ payloadFields = engineFields('regex', pattern);
324
+ }
325
+ else {
326
+ // ── ast-grep: resolve the language FIRST, then validate under exactly it ──
327
+ const resolution = resolveRecordLanguage(target.language);
328
+ if (!resolution.resolved)
329
+ return { kind: 'rejected', reason: resolution.reason };
330
+ resolvedLanguage = resolution.language;
331
+ // The language⇄glob consistency floor, BEFORE the payload gate: a scope that
332
+ // will be evaluated under a different grammar than the payload is validated
333
+ // under is a defect in the record, and the author should be told that rather
334
+ // than being handed a payload error for a payload that is fine.
335
+ const inconsistent = checkLanguageGlobConsistency(resolution.language, target.scope.fileGlobs);
336
+ if (inconsistent !== null)
337
+ return { kind: 'rejected', reason: inconsistent };
338
+ const probeGlobs = languageProbeGlobs(resolution.extension);
339
+ if (target.rule !== undefined) {
340
+ const inexpressible = V1_INEXPRESSIBLE_NAPI_KEYS.find((key) => key in target.rule);
341
+ if (inexpressible !== undefined) {
342
+ return {
343
+ kind: 'rejected',
344
+ reason: `Prop 310 § Design 4 (operator ruling 2026-08-21, tree-form): 'target.rule' is the ast-grep RULE TREE, and '${inexpressible}' is a NapiConfig SIBLING of the rule — inexpressible at V1 (zero of the 19 compound corpus rules use it). Demand is typed as a construct-gap at the § Design 15 trial and lands by grammar version bump with its own home under 'target:', never smuggled inside the tree.`,
345
+ };
346
+ }
347
+ // The tree-form ruling's derivation: the record carries the TREE, the
348
+ // lowering builds the wrapper. `language` is derived from the resolved
349
+ // `target.language`, so the record never carries a duplicate language home.
350
+ const napiConfig = {
351
+ rule: target.rule,
352
+ language: extensionToLang(resolution.extension),
353
+ };
354
+ const v = validateAstGrepPattern(napiConfig, probeGlobs);
355
+ if (!v.valid) {
356
+ return {
357
+ kind: 'rejected',
358
+ reason: `Prop 310 § Design 6: target.rule failed ast-grep validation under the declared language '${resolvedLanguage}' (${v.reason ?? 'invalid ast-grep rule'}). V1 validates under exactly the declared grammar — the shipped try-each-glob-derived-Lang cross-grammar acceptance does not apply on the record path.`,
359
+ };
360
+ }
361
+ payloadFields = engineFields('ast-grep', napiConfig);
362
+ }
363
+ else {
364
+ const pattern = target.pattern;
365
+ const v = validateAstGrepPattern(pattern, probeGlobs);
366
+ if (!v.valid) {
367
+ return {
368
+ kind: 'rejected',
369
+ reason: `Prop 310 § Design 6: target.pattern failed ast-grep validation under the declared language '${resolvedLanguage}' (${v.reason ?? 'invalid ast-grep pattern'}). V1 validates under exactly the declared grammar — the shipped try-each-glob-derived-Lang cross-grammar acceptance does not apply on the record path.`,
370
+ };
371
+ }
372
+ payloadFields = engineFields('ast-grep', pattern);
373
+ }
374
+ }
375
+ // ── § Design 3 engine binding, asserted on two INDEPENDENTLY-derived sides ──
376
+ const payloadEngine = engineFromCompiledFields(payloadFields);
377
+ if (payloadEngine !== parsed.derivedEngine) {
378
+ throw new Error(`[Totem Error] compileRuleRecord: record declared target.type '${parsed.derivedEngine}' but its payload compiled as '${payloadEngine}' — the two sides originate differently (the record's target.type vs the payload's actual compilation path), so this divergence is a lowering bug, not an authoring one (Prop 310 § Design 3, ADR-112 §3).`);
379
+ }
380
+ const heading = recordHeading(opts.ruleId);
381
+ const rule = CompiledRuleSchema.parse({
382
+ // ADR-112 §8/§9 id-unification: the compiled identity IS the minted ruleId.
383
+ lessonHash: opts.ruleId,
384
+ lessonHeading: heading,
385
+ message: record.message,
386
+ engine: parsed.derivedEngine,
387
+ ...payloadFields,
388
+ // § Design 7 — VERBATIM. `sanitizeFileGlobs` never runs on this path: the
389
+ // strict dialect already validated these at parse, and expansion/promotion
390
+ // are the silent transforms the grammar exists to kill.
391
+ fileGlobs: [...record.target.scope.fileGlobs],
392
+ ...(record.target.scope.excludeGlobs !== undefined
393
+ ? { excludeGlobs: [...record.target.scope.excludeGlobs] }
394
+ : {}),
395
+ severity: record.severity,
396
+ ...(record.recoveryHint !== undefined ? { recoveryHint: record.recoveryHint } : {}),
397
+ examples: record.examples.map((example) => ({ bad: example.bad, good: example.good })),
398
+ ...(record.requires !== undefined
399
+ ? { requires: { pattern: record.requires.pattern, scope: record.requires.scope } }
400
+ : {}),
401
+ ...(record.curation !== undefined ? { curation: { ...record.curation } } : {}),
402
+ // § Design 9 / Amendment R4 — carried VERBATIM, never evaluated at V1. The
403
+ // record key's named snake_case exception is renamed exactly here, once.
404
+ ...(record.verification_shadow !== undefined
405
+ ? { verificationShadow: { ...record.verification_shadow } }
406
+ : {}),
407
+ ...(resolvedLanguage !== undefined ? { language: resolvedLanguage } : {}),
408
+ compiledAt: opts.now,
409
+ createdAt: opts.now,
410
+ // Yellow / sensor-only, exactly as the authored path (§ Design "State-surface
411
+ // backing": every rule minted from this grammar enters unverified, ADR-112
412
+ // §1). `legitimacy`/`ruleClass` stay ABSENT — the sense→enforce crossing is
413
+ // priced by the Amendment's proof-required ruling, never by this lowering.
414
+ unverified: true,
415
+ });
416
+ return { kind: 'compiled', rule };
417
+ }
418
+ //# sourceMappingURL=record-lower.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-lower.js","sourceRoot":"","sources":["../../src/spine/record-lower.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=record-lower.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-lower.test.d.ts","sourceRoot":"","sources":["../../src/spine/record-lower.test.ts"],"names":[],"mappings":""}