@lokascript/framework 4.6.0 → 4.7.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 (115) hide show
  1. package/CHANGELOG.md +87 -1
  2. package/dist/api/create-dsl.d.ts +13 -0
  3. package/dist/api/create-dsl.d.ts.map +1 -1
  4. package/dist/api/index.d.ts +1 -0
  5. package/dist/api/index.d.ts.map +1 -1
  6. package/dist/api/index.js +1756 -710
  7. package/dist/api/index.js.map +1 -1
  8. package/dist/api/translation-loss.d.ts +84 -0
  9. package/dist/api/translation-loss.d.ts.map +1 -0
  10. package/dist/core/index.d.ts +1 -0
  11. package/dist/core/index.d.ts.map +1 -1
  12. package/dist/core/index.js +1047 -684
  13. package/dist/core/index.js.map +1 -1
  14. package/dist/core/matching/confidence-model.d.ts +54 -0
  15. package/dist/core/matching/confidence-model.d.ts.map +1 -0
  16. package/dist/core/matching/index.d.ts +12 -0
  17. package/dist/core/matching/index.d.ts.map +1 -0
  18. package/dist/core/matching/match-skeleton.d.ts +114 -0
  19. package/dist/core/matching/match-skeleton.d.ts.map +1 -0
  20. package/dist/core/matching/stock-confidence.d.ts +15 -0
  21. package/dist/core/matching/stock-confidence.d.ts.map +1 -0
  22. package/dist/core/matching/stock-reader.d.ts +56 -0
  23. package/dist/core/matching/stock-reader.d.ts.map +1 -0
  24. package/dist/core/matching/stock-reading.d.ts +44 -0
  25. package/dist/core/matching/stock-reading.d.ts.map +1 -0
  26. package/dist/core/matching/value-reader.d.ts +62 -0
  27. package/dist/core/matching/value-reader.d.ts.map +1 -0
  28. package/dist/core/pattern-matching/index.js +561 -660
  29. package/dist/core/pattern-matching/index.js.map +1 -1
  30. package/dist/core/pattern-matching/pattern-matcher.d.ts +0 -117
  31. package/dist/core/pattern-matching/pattern-matcher.d.ts.map +1 -1
  32. package/dist/core/types.d.ts +48 -0
  33. package/dist/core/types.d.ts.map +1 -1
  34. package/dist/core/types.js.map +1 -1
  35. package/dist/generation/index.d.ts +2 -0
  36. package/dist/generation/index.d.ts.map +1 -1
  37. package/dist/generation/index.js +583 -1
  38. package/dist/generation/index.js.map +1 -1
  39. package/dist/generation/pattern-render.d.ts +72 -0
  40. package/dist/generation/pattern-render.d.ts.map +1 -0
  41. package/dist/generation/schema-patterns.d.ts +152 -0
  42. package/dist/generation/schema-patterns.d.ts.map +1 -0
  43. package/dist/index.cjs +1979 -907
  44. package/dist/index.cjs.map +1 -1
  45. package/dist/index.js +1961 -906
  46. package/dist/index.js.map +1 -1
  47. package/dist/ir/index.js.map +1 -1
  48. package/dist/parsing/index.js +561 -660
  49. package/dist/parsing/index.js.map +1 -1
  50. package/dist/testing/gate/index.d.ts +8 -0
  51. package/dist/testing/gate/index.d.ts.map +1 -0
  52. package/dist/testing/gate/index.js +632 -0
  53. package/dist/testing/gate/index.js.map +1 -0
  54. package/dist/testing/gate/lint/format.d.ts +7 -0
  55. package/dist/testing/gate/lint/format.d.ts.map +1 -0
  56. package/dist/testing/gate/lint/index.d.ts +30 -0
  57. package/dist/testing/gate/lint/index.d.ts.map +1 -0
  58. package/dist/testing/gate/lint/rules/extractor-coverage.d.ts +18 -0
  59. package/dist/testing/gate/lint/rules/extractor-coverage.d.ts.map +1 -0
  60. package/dist/testing/gate/lint/rules/index.d.ts +14 -0
  61. package/dist/testing/gate/lint/rules/index.d.ts.map +1 -0
  62. package/dist/testing/gate/lint/rules/keyword-classification.d.ts +19 -0
  63. package/dist/testing/gate/lint/rules/keyword-classification.d.ts.map +1 -0
  64. package/dist/testing/gate/lint/rules/keyword-coverage.d.ts +13 -0
  65. package/dist/testing/gate/lint/rules/keyword-coverage.d.ts.map +1 -0
  66. package/dist/testing/gate/lint/rules/marker-tokenization.d.ts +20 -0
  67. package/dist/testing/gate/lint/rules/marker-tokenization.d.ts.map +1 -0
  68. package/dist/testing/gate/lint/rules/position-ordering.d.ts +25 -0
  69. package/dist/testing/gate/lint/rules/position-ordering.d.ts.map +1 -0
  70. package/dist/testing/gate/lint/rules/renderer-coherence.d.ts +24 -0
  71. package/dist/testing/gate/lint/rules/renderer-coherence.d.ts.map +1 -0
  72. package/dist/testing/gate/lint/rules/schema-rules.d.ts +10 -0
  73. package/dist/testing/gate/lint/rules/schema-rules.d.ts.map +1 -0
  74. package/dist/testing/gate/lint/types.d.ts +74 -0
  75. package/dist/testing/gate/lint/types.d.ts.map +1 -0
  76. package/dist/testing/gate/round-trip.d.ts +163 -0
  77. package/dist/testing/gate/round-trip.d.ts.map +1 -0
  78. package/package.json +6 -2
  79. package/src/__test__/fixtures/sql-dsl.ts +8 -2
  80. package/src/api/create-dsl-engine.test.ts +86 -0
  81. package/src/api/create-dsl.ts +141 -18
  82. package/src/api/index.ts +1 -0
  83. package/src/api/translation-loss.test.ts +89 -0
  84. package/src/api/translation-loss.ts +128 -0
  85. package/src/core/index.ts +1 -0
  86. package/src/core/matching/confidence-model.ts +58 -0
  87. package/src/core/matching/index.ts +12 -0
  88. package/src/core/matching/match-skeleton.test.ts +179 -0
  89. package/src/core/matching/match-skeleton.ts +621 -0
  90. package/src/core/matching/stock-confidence.ts +238 -0
  91. package/src/core/matching/stock-reader.test.ts +181 -0
  92. package/src/core/matching/stock-reader.ts +186 -0
  93. package/src/core/matching/stock-reading.ts +681 -0
  94. package/src/core/matching/value-reader.ts +85 -0
  95. package/src/core/pattern-matching/pattern-matcher.ts +11 -876
  96. package/src/core/types.ts +48 -0
  97. package/src/generation/index.ts +2 -0
  98. package/src/generation/pattern-render.ts +378 -0
  99. package/src/generation/schema-patterns.test.ts +99 -0
  100. package/src/generation/schema-patterns.ts +962 -0
  101. package/src/testing/gate/index.ts +8 -0
  102. package/src/testing/gate/lint/format.ts +23 -0
  103. package/src/testing/gate/lint/index.ts +73 -0
  104. package/src/testing/gate/lint/lint.test.ts +131 -0
  105. package/src/testing/gate/lint/rules/extractor-coverage.ts +63 -0
  106. package/src/testing/gate/lint/rules/index.ts +37 -0
  107. package/src/testing/gate/lint/rules/keyword-classification.ts +52 -0
  108. package/src/testing/gate/lint/rules/keyword-coverage.ts +38 -0
  109. package/src/testing/gate/lint/rules/marker-tokenization.ts +129 -0
  110. package/src/testing/gate/lint/rules/position-ordering.ts +87 -0
  111. package/src/testing/gate/lint/rules/renderer-coherence.ts +100 -0
  112. package/src/testing/gate/lint/rules/schema-rules.ts +35 -0
  113. package/src/testing/gate/lint/types.ts +83 -0
  114. package/src/testing/gate/round-trip.test.ts +118 -0
  115. package/src/testing/gate/round-trip.ts +438 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/testing/gate/round-trip.ts","../../../src/testing/gate/lint/rules/schema-rules.ts","../../../src/testing/gate/lint/rules/keyword-coverage.ts","../../../src/testing/gate/lint/rules/marker-tokenization.ts","../../../src/testing/gate/lint/rules/keyword-classification.ts","../../../src/testing/gate/lint/rules/extractor-coverage.ts","../../../src/testing/gate/lint/rules/position-ordering.ts","../../../src/testing/gate/lint/rules/renderer-coherence.ts","../../../src/testing/gate/lint/rules/index.ts","../../../src/testing/gate/lint/format.ts","../../../src/testing/gate/lint/index.ts"],"sourcesContent":["/**\n * The round-trip gate kit (domains rethink Phase 4.6, `docs-internal/DOMAINS_RETHINK.md`): every\n * command of a grammar, written in each of its languages by its own renderer and read back by its own\n * parser. Moved from lokascript-domains' `packages/domains/gate/round-trip.ts` (the domain gate, Phase\n * 2), so any grammar on the framework runs the same gate; the domains repo keeps its fixtures\n * (`gate/values.ts`), baselines and regen tool.\n *\n * A case is a command (bracket syntax, parsed in English) and a language:\n *\n * - **round trip**: `render(ref, lang)`, then `parse`. `pass` when the parse is the reference node, or,\n * for a grammar whose compiled output does not depend on the language, when the text compiles to what\n * the command itself (its bracket form) compiles to (a parser may keep a translated word that the\n * generator normalizes: bdd ja `#box0 が 表示 前提` is `visible`). English is a lane like the others.\n * `refused` when the render is null or the parse throws: the caller is told. `silent` otherwise: it\n * reads, or compiles to, something else.\n * - **leftover**: the same render plus one unknown word. `refused` is the expected outcome; a parse\n * that returns accepted input it did not read (`silent`).\n *\n * The outcomes are the command-shape gate's (hyperfixi `testing-framework`). A baseline lists every\n * case that is not at its best outcome; `compare` reports a case worse than listed and one better than\n * listed, so a gate built on it only shrinks.\n */\n\nexport type Outcome = 'pass' | 'refused' | 'silent';\nexport type CaseKind = 'roundTrip' | 'leftover';\n\n/** Best first. A round trip's best is `pass`; leftover input's is `refused`. */\nexport const RANK: Record<CaseKind, Record<Outcome, number>> = {\n roundTrip: { pass: 2, refused: 1, silent: 0 },\n leftover: { refused: 2, pass: 2, silent: 0 },\n};\nexport const BEST: Record<CaseKind, Outcome> = { roundTrip: 'pass', leftover: 'refused' };\n\n/** Appended for the leftover cases: a word no grammar's vocabulary has. */\nexport const UNKNOWN_WORD = 'zzqx';\n\nexport interface CaseResult {\n /** The grammar (a domain's name). */\n grammar: string;\n kind: CaseKind;\n /** The command, in bracket syntax (read in English). */\n source: string;\n lang: string;\n outcome: Outcome;\n /** What the renderer wrote (plus the unknown word, for leftover). */\n text?: string;\n /** Why it is not `pass`: the error, or what the parse read instead. */\n why?: string;\n /** The round trip's parse, summarized (`summarize`); absent when it was refused. */\n read?: string;\n}\n\n/** What the gate reads of a role in a schema. */\nexport interface GateRoleSpec {\n readonly role: string;\n readonly required?: boolean;\n readonly expectedTypes?: readonly string[];\n}\n\n/** What the gate reads of a command schema. */\nexport interface GateSchema {\n readonly action: string;\n readonly roles: readonly GateRoleSpec[];\n}\n\n/** What the gate reads of a parse. */\nexport interface GateNode {\n readonly action: string;\n readonly roles: ReadonlyMap<string, unknown> | Readonly<Record<string, unknown>>;\n}\n\n/** The grammar's DSL, as the gate drives it. */\nexport interface GateDSL {\n parse(input: string, language: string): GateNode;\n compile(input: string, language: string): { ok: boolean; code?: string; errors?: string[] };\n render?(node: GateNode, language: string): string | null;\n getSupportedLanguages(): string[];\n}\n\n/**\n * The values the gate writes into each role. A role not listed gets a plain name no vocabulary uses\n * (`v0x`, or `#box0` where only a selector fits): its value must come back verbatim. A role that takes\n * FIXED words lists every word the grammar's renderer and generator know, in English: the gate writes\n * the command once per word, in every language, so a word one of the two tables lacks fails in the\n * languages where it is missing.\n */\nexport interface GateFixture {\n /**\n * `compile`: a round trip also passes when the text compiles to the command's own code (the grammar\n * compiles to something that does not depend on the language). `node`: only the parse counts (a\n * grammar that compiles to a sentence in each language).\n */\n oracle: 'compile' | 'node';\n /** Keys are `<action>.<role>` or `<role>` (every action). The first value is the one the other cases use. */\n values: Record<string, string[]>;\n /** Actions that do not compile on their own (a gate may check every other one does). */\n englishDoesNotCompile?: string[];\n}\n\n/** A value no vocabulary uses: a selector where only a selector fits, a plain name otherwise. */\nfunction defaultValue(role: GateRoleSpec, i: number): string {\n const types = role.expectedTypes ?? [];\n if (types.includes('selector') && !types.includes('literal') && !types.includes('expression'))\n return `#box${i}`;\n return `v${i}x`;\n}\n\nfunction valuesFor(fixture: GateFixture, action: string, role: GateRoleSpec, i: number): string[] {\n return (\n fixture.values[`${action}.${role.role}`] ?? fixture.values[role.role] ?? [defaultValue(role, i)]\n );\n}\n\n/**\n * The commands a grammar is checked on: for each schema, its required roles alone and all its roles\n * (each with its first value), then each further value of a role that takes fixed words, alone.\n */\nexport function commandsFor(schemas: readonly GateSchema[], fixture: GateFixture): string[] {\n const out = new Set<string>();\n for (const schema of schemas) {\n const required = schema.roles.filter(r => r.required);\n const variants =\n required.length === schema.roles.length ? [required] : [required, [...schema.roles]];\n for (const roles of variants) {\n const values = roles.map((r, i) => valuesFor(fixture, schema.action, r, i));\n const write = (pick: string[]) =>\n `[${schema.action}${roles.map((r, i) => ` ${r.role}:${pick[i]}`).join('')}]`;\n const first = values.map(v => v[0]!);\n out.add(write(first));\n values.forEach((vs, i) => {\n for (const v of vs.slice(1)) out.add(write(first.map((f, j) => (j === i ? v : f))));\n });\n }\n }\n return [...out];\n}\n\nfunction roleEntries(node: GateNode): [string, unknown][] {\n return node.roles instanceof Map\n ? [...(node.roles as ReadonlyMap<string, unknown>)]\n : Object.entries(node.roles ?? {});\n}\n\nfunction roleValues(node: GateNode): Record<string, string> {\n return Object.fromEntries(\n roleEntries(node)\n .map(([k, v]): [string, string] => [\n k,\n String((v as { value?: unknown })?.value ?? (v as { raw?: unknown })?.raw ?? v),\n ])\n .sort(([a], [b]) => (a < b ? -1 : 1))\n );\n}\n\n/** A parse as one line: `action role:type=value …`, roles sorted. What the parse snapshot records. */\nexport function summarize(node: GateNode): string {\n const roles = roleEntries(node)\n .map(([k, v]) => {\n const t = (v as { type?: unknown })?.type;\n const raw = (v as { value?: unknown })?.value ?? (v as { raw?: unknown })?.raw ?? v;\n const text = String(raw);\n return `${k}${t ? `:${String(t)}` : ''}=${/[\\s=]/.test(text) ? JSON.stringify(text) : text}`;\n })\n .sort();\n return [node.action, ...roles].join(' ');\n}\n\nfunction describeRead(want: Record<string, string>, ref: GateNode, back: GateNode): string {\n if (back.action !== ref.action) return `another command: ${back.action}`;\n const got = roleValues(back);\n const lost = Object.keys(want).filter(k => !(k in got));\n const added = Object.keys(got).filter(k => !(k in want));\n const changed = Object.keys(want).filter(k => k in got && got[k] !== want[k]);\n const parts = [\n ...lost.map(k => `${k} lost`),\n ...added.map(k => `${k} added (${got[k]})`),\n ...changed.map(k => `${k}: ${got[k]}`),\n ];\n return parts.join(', ');\n}\n\nconst message = (e: unknown) => String((e as Error)?.message ?? e).slice(0, 160);\n\n/** What a command (bracket syntax) compiles to; null when it does not compile on its own. */\nexport function referenceCode(dsl: GateDSL, source: string): string | null {\n try {\n const c = dsl.compile(source, 'en');\n return c.ok && typeof c.code === 'string' ? c.code : null;\n } catch {\n return null;\n }\n}\n\n/** Run every case of one grammar: each command of `commandsFor` in each of the DSL's languages. */\nexport function runRoundTrip(\n grammar: string,\n dsl: GateDSL,\n schemas: readonly GateSchema[],\n fixture: GateFixture\n): CaseResult[] {\n const languages = dsl.getSupportedLanguages();\n const results: CaseResult[] = [];\n\n for (const source of commandsFor(schemas, fixture)) {\n const ref = dsl.parse(source, 'en');\n const want = roleValues(ref);\n const sameNode = (back: GateNode) =>\n back.action === ref.action && JSON.stringify(roleValues(back)) === JSON.stringify(want);\n\n // The code the command itself compiles to: its bracket form, not its English render, or the English\n // lane would be measured against itself (bdd's `When double-click` reads `double`, and compiled to a\n // comment that every correct language then \"differed\" from). Null when the command does not compile\n // alone; then only the node can pass.\n const refCode = fixture.oracle === 'compile' ? referenceCode(dsl, source) : null;\n\n for (const lang of languages) {\n const at = { grammar, source, lang };\n const text = dsl.render?.(ref, lang) ?? null;\n if (!text) {\n results.push({ ...at, kind: 'roundTrip', outcome: 'refused', why: 'no render' });\n continue;\n }\n let back: GateNode;\n try {\n back = dsl.parse(text, lang);\n } catch (e) {\n results.push({ ...at, kind: 'roundTrip', outcome: 'refused', text, why: message(e) });\n continue;\n }\n\n let outcome: Outcome = 'silent';\n let why: string | undefined;\n if (sameNode(back)) outcome = 'pass';\n else if (refCode !== null) {\n let code: string | undefined;\n try {\n const c = dsl.compile(text, lang);\n code = c.ok ? c.code : undefined;\n } catch {\n code = undefined;\n }\n if (code === refCode) outcome = 'pass';\n else why = `compiles differently; reads ${describeRead(want, ref, back)}`;\n } else why = `reads ${describeRead(want, ref, back)}`;\n results.push({\n ...at,\n kind: 'roundTrip',\n outcome,\n text,\n ...(why ? { why } : {}),\n read: summarize(back),\n });\n\n // Leftover input: only where the text itself reads, or a refusal would say nothing.\n const extended = `${text} ${UNKNOWN_WORD}`;\n try {\n const read = dsl.parse(extended, lang);\n results.push({\n ...at,\n kind: 'leftover',\n outcome: 'silent',\n text: extended,\n why: `accepted as ${read.action}`,\n });\n } catch {\n results.push({ ...at, kind: 'leftover', outcome: 'refused', text: extended });\n }\n }\n }\n return results;\n}\n\n// ---------------------------------------------------------------------------------------------------\n// The baseline\n// ---------------------------------------------------------------------------------------------------\n\nexport interface ListedCase {\n outcome: Exclude<Outcome, 'pass'>;\n text?: string;\n why?: string;\n}\n\nexport interface GateBaseline {\n /** The upstream packages this was measured on (the grammar's lockfile). */\n upstream: Record<string, string>;\n /** Per grammar and kind: cases and outcomes. Written by the regen tool for the reader; not checked. */\n counts: Record<string, Record<CaseKind, Record<Outcome | 'cases', number>>>;\n /** Per grammar, command and language: every round trip that is not `pass`. */\n roundTrip: Record<string, Record<string, Record<string, ListedCase>>>;\n /** Per grammar and command: the languages whose leftover case was accepted (`silent`). */\n leftover: Record<string, Record<string, string[]>>;\n}\n\nexport interface DriftCase {\n kind: CaseKind;\n source: string;\n lang: string;\n listed: Outcome;\n now: Outcome;\n text?: string;\n why?: string;\n}\n\nexport interface Drift {\n worse: DriftCase[];\n better: DriftCase[];\n /** Listed cases that are no longer cases at all. */\n stale: { kind: CaseKind; source: string; lang: string }[];\n}\n\nfunction listedOutcome(\n baseline: GateBaseline,\n r: Pick<CaseResult, 'grammar' | 'kind' | 'source' | 'lang'>\n): Outcome {\n if (r.kind === 'roundTrip')\n return baseline.roundTrip[r.grammar]?.[r.source]?.[r.lang]?.outcome ?? 'pass';\n return baseline.leftover[r.grammar]?.[r.source]?.includes(r.lang) ? 'silent' : 'refused';\n}\n\n/** How one grammar's results moved against the baseline. */\nexport function compare(grammar: string, results: CaseResult[], baseline: GateBaseline): Drift {\n const drift: Drift = { worse: [], better: [], stale: [] };\n const seen = new Set<string>();\n for (const r of results) {\n seen.add(`${r.kind}\\u0000${r.source}\\u0000${r.lang}`);\n const listed = listedOutcome(baseline, r);\n const rank = RANK[r.kind];\n const entry = { kind: r.kind, source: r.source, lang: r.lang, listed, now: r.outcome };\n if (rank[r.outcome] < rank[listed])\n drift.worse.push({\n ...entry,\n ...(r.text !== undefined ? { text: r.text } : {}),\n ...(r.why !== undefined ? { why: r.why } : {}),\n });\n else if (rank[r.outcome] > rank[listed]) drift.better.push(entry);\n }\n const listedCases: { kind: CaseKind; source: string; lang: string }[] = [\n ...Object.entries(baseline.roundTrip[grammar] ?? {}).flatMap(([source, langs]) =>\n Object.keys(langs).map(lang => ({ kind: 'roundTrip' as const, source, lang }))\n ),\n ...Object.entries(baseline.leftover[grammar] ?? {}).flatMap(([source, langs]) =>\n langs.map(lang => ({ kind: 'leftover' as const, source, lang }))\n ),\n ];\n for (const c of listedCases)\n if (!seen.has(`${c.kind}\\u0000${c.source}\\u0000${c.lang}`)) drift.stale.push(c);\n return drift;\n}\n\n/** The baseline entries for one grammar's results. */\nexport function listingOf(results: CaseResult[]): {\n roundTrip: Record<string, Record<string, ListedCase>>;\n leftover: Record<string, string[]>;\n} {\n const roundTrip: Record<string, Record<string, ListedCase>> = {};\n const leftover: Record<string, string[]> = {};\n for (const r of results) {\n if (r.kind === 'roundTrip' && r.outcome !== 'pass') {\n (roundTrip[r.source] ??= {})[r.lang] = {\n outcome: r.outcome,\n ...(r.text ? { text: r.text } : {}),\n ...(r.why ? { why: r.why } : {}),\n };\n } else if (r.kind === 'leftover' && r.outcome === 'silent')\n (leftover[r.source] ??= []).push(r.lang);\n }\n return { roundTrip, leftover };\n}\n\nexport function countsOf(\n results: CaseResult[]\n): Record<CaseKind, Record<Outcome | 'cases', number>> {\n const counts = {\n roundTrip: { cases: 0, pass: 0, refused: 0, silent: 0 },\n leftover: { cases: 0, pass: 0, refused: 0, silent: 0 },\n };\n for (const r of results) {\n counts[r.kind].cases++;\n counts[r.kind][r.outcome]++;\n }\n return counts;\n}\n\n// ---------------------------------------------------------------------------------------------------\n// The parse snapshot\n// ---------------------------------------------------------------------------------------------------\n\n/**\n * Every round trip's parse, so a change that moves a parse shows it, whether or not an outcome moved\n * (a value's type, a role a passing case gained, what a silent case reads now). `refused` where the\n * parse threw. Leftover cases are not in it: their outcome is the baseline's.\n */\nexport interface ParseSnapshot {\n upstream: Record<string, string>;\n /** Per grammar, command and language. */\n parses: Record<string, Record<string, Record<string, string>>>;\n}\n\nexport function snapshotOf(results: CaseResult[]): Record<string, Record<string, string>> {\n const out: Record<string, Record<string, string>> = {};\n for (const r of results)\n if (r.kind === 'roundTrip') (out[r.source] ??= {})[r.lang] = r.read ?? 'refused';\n return out;\n}\n\nexport interface SnapshotChange {\n source: string;\n lang: string;\n was?: string;\n now?: string;\n}\n\n/** Every round trip whose parse differs from the snapshot's, for one grammar. */\nexport function snapshotChanges(\n grammar: string,\n results: CaseResult[],\n snapshot: ParseSnapshot\n): SnapshotChange[] {\n const now = snapshotOf(results);\n const was = snapshot.parses[grammar] ?? {};\n const changes: SnapshotChange[] = [];\n for (const source of new Set([...Object.keys(was), ...Object.keys(now)]))\n for (const lang of new Set([\n ...Object.keys(was[source] ?? {}),\n ...Object.keys(now[source] ?? {}),\n ])) {\n const a = was[source]?.[lang];\n const b = now[source]?.[lang];\n if (a !== b)\n changes.push({\n source,\n lang,\n ...(a !== undefined ? { was: a } : {}),\n ...(b !== undefined ? { now: b } : {}),\n });\n }\n return changes;\n}\n","/**\n * Schema-structure rules (R1, R2).\n *\n * Delegates to the validator the input brings (`DomainLintInput.validateSchema`): the domains pass\n * `@lokascript/semantic`'s `validateCommandSchema`, whose checks are already solid. We only surface its\n * error- and warning-level items; notes are dropped to keep linter output focused.\n */\n\nimport type { LintFinding, LintRule } from '../types';\n\nconst RULE_ID = 'schema-structure';\n\nexport const schemaStructureRule: LintRule = input => {\n const findings: LintFinding[] = [];\n if (!input.validateSchema) return findings;\n\n for (const schema of input.schemas) {\n const result = input.validateSchema(schema);\n for (const item of result.items) {\n if (item.severity === 'note') continue; // skip notes — not actionable at lint time\n findings.push({\n rule: `${RULE_ID}:${item.code}`,\n severity: item.severity,\n message: `[${schema.action}] ${item.message}`,\n context: {\n domain: input.name,\n action: String(schema.action),\n code: item.code,\n },\n });\n }\n }\n\n return findings;\n};\n","/**\n * R6: Keyword coverage across profiles.\n *\n * For every schema action + every registered profile, the profile must have\n * a `keywords[action]` entry. Without it, `createMultilingualDSL()` throws\n * at pattern generation time (\"No keyword translation for 'X' in 'Y'\").\n *\n * This rule catches the \"I added a new schema but only wired it into the\n * English profile\" class of drift.\n */\n\nimport type { LintFinding, LintRule } from '../types';\n\nconst RULE_ID = 'keyword-coverage';\n\nexport const keywordCoverageRule: LintRule = input => {\n const findings: LintFinding[] = [];\n\n for (const profile of input.profiles) {\n for (const schema of input.schemas) {\n const action = schema.action;\n if (!profile.keywords[action]) {\n findings.push({\n rule: RULE_ID,\n severity: 'error',\n message: `profile [${profile.code}] has no keyword for action '${String(action)}'`,\n context: {\n domain: input.name,\n lang: profile.code,\n action: String(action),\n },\n });\n }\n }\n }\n\n return findings;\n};\n","/**\n * R7: Marker and keyword tokenization.\n *\n * Every lexical item the parser needs to match atomically — marker words,\n * profile keyword primaries, and profile keyword alternatives — must\n * tokenize as a single token in its target language. A word that splits\n * across multiple tokens (e.g., `añadir` → `[\"a\", \"ñadir\"]` when the\n * tokenizer lacks `LatinExtendedIdentifierExtractor`) will never match a\n * pattern's literal token.\n *\n * This is the exact gap that bit us on the Spanish tokenizer mid-session.\n */\n\nimport type { LintFinding, LintRule, DomainLintInput } from '../types';\nimport type { LanguageTokenizer } from '../../../../core/types';\n\nconst RULE_ID = 'marker-tokenization';\n\nfunction tokenCount(tokenizer: LanguageTokenizer, word: string): number {\n const stream = tokenizer.tokenize(word);\n return stream.tokens.length;\n}\n\nexport function collectLexicalItems(input: DomainLintInput): Array<{\n lang: string;\n word: string;\n source: string; // \"schema marker <action>.<role>\" | \"profile keyword <action>.primary\" | ...\n}> {\n const items: Array<{ lang: string; word: string; source: string }> = [];\n\n // Schema marker overrides (per language)\n for (const schema of input.schemas) {\n for (const role of schema.roles) {\n if (!role.markerOverride) continue;\n for (const [lang, word] of Object.entries(role.markerOverride)) {\n items.push({\n lang,\n word,\n source: `schema markerOverride ${String(schema.action)}.${role.role}`,\n });\n }\n }\n }\n\n // Profile keywords (primary + alternatives)\n for (const profile of input.profiles) {\n for (const [action, entry] of Object.entries(profile.keywords)) {\n if (entry.primary) {\n items.push({\n lang: profile.code,\n word: entry.primary,\n source: `profile keyword ${action}.primary`,\n });\n }\n for (const alt of entry.alternatives ?? []) {\n items.push({\n lang: profile.code,\n word: alt,\n source: `profile keyword ${action}.alternatives`,\n });\n }\n }\n }\n\n // Profile role markers (primary + alternatives)\n for (const profile of input.profiles) {\n for (const [role, marker] of Object.entries(profile.roleMarkers ?? {})) {\n if (marker.primary) {\n items.push({\n lang: profile.code,\n word: marker.primary,\n source: `profile roleMarker ${role}.primary`,\n });\n }\n for (const alt of marker.alternatives ?? []) {\n items.push({\n lang: profile.code,\n word: alt,\n source: `profile roleMarker ${role}.alternatives`,\n });\n }\n }\n }\n\n return items;\n}\n\nexport const markerTokenizationRule: LintRule = input => {\n const findings: LintFinding[] = [];\n const items = collectLexicalItems(input);\n\n for (const { lang, word, source } of items) {\n const tokenizer = input.tokenizers[lang];\n if (!tokenizer) {\n // Tokenizer for this language isn't registered with the linter.\n // R6 (keyword-coverage) catches the schema side; nothing to do here.\n continue;\n }\n\n // Empty-string markers mean \"no marker in this language\" (an explicit\n // opt-out pattern used by domain-learn to signal that a role is\n // positional in some languages but marker-bearing in others).\n if (word === '') continue;\n\n // Whitespace-containing markers (e.g., 'mettre-à-jour' is one word, but\n // 'ask X to Y' wouldn't be) — tokenize the raw word and expect 1 token.\n // Multi-word markers with explicit spaces are out of scope for this rule;\n // skip them rather than flag false positives.\n if (/\\s/.test(word)) continue;\n\n const count = tokenCount(tokenizer, word);\n if (count !== 1) {\n findings.push({\n rule: RULE_ID,\n severity: 'error',\n message: `\"${word}\" tokenizes as ${count} tokens in ${lang} (${source})`,\n context: {\n domain: input.name,\n lang,\n word,\n source,\n tokenCount: count,\n },\n });\n }\n }\n\n return findings;\n};\n","/**\n * R5: Keyword classification — profile keywords ⊆ tokenizer keyword lists.\n *\n * Every lexical item the parser must recognize as a keyword — profile\n * keyword primaries/alternatives, profile role markers, and schema\n * `markerOverride` words — must actually *classify* as `'keyword'` in that\n * language's tokenizer. This is stricter than R7 (marker-tokenization):\n * a word can tokenize as a single token yet come back as `'identifier'`\n * when the tokenizer's keyword list doesn't contain it.\n *\n * Under the bridge (`buildDomainTokenizer`) profile and tokenizer derive\n * from the same vocab file, so this rule is vacuously green there. It\n * exists for hand-authored tokenizers (e.g. domain-learn) and custom\n * tokenizer overrides, where a vocab/profile edit can silently go stale\n * against the tokenizer's keyword list.\n */\n\nimport type { LintFinding, LintRule } from '../types';\nimport { collectLexicalItems } from './marker-tokenization';\n\nconst RULE_ID = 'keyword-classification';\n\nexport const keywordClassificationRule: LintRule = input => {\n const findings: LintFinding[] = [];\n\n for (const { lang, word, source } of collectLexicalItems(input)) {\n const tokenizer = input.tokenizers[lang];\n if (!tokenizer) continue; // R6 catches unregistered languages.\n\n // Same opt-outs as R7: '' means \"no marker in this language\"; multi-word\n // items can't be a single keyword token and are out of scope.\n if (word === '' || /\\s/.test(word)) continue;\n\n const kind = tokenizer.classifyToken(word);\n if (kind !== 'keyword' && kind !== 'particle') {\n findings.push({\n rule: RULE_ID,\n severity: 'error',\n message: `\"${word}\" classifies as '${kind}' (not 'keyword') in ${lang} (${source})`,\n context: {\n domain: input.name,\n lang,\n word,\n source,\n kind,\n },\n });\n }\n }\n\n return findings;\n};\n","/**\n * R8: Latin-script tokenizers should extract diacritic identifiers as single tokens.\n *\n * The default `IdentifierExtractor` matches `[a-zA-Z0-9_]*` and stops at any\n * diacritic. Words like `añadir` split into `[\"a\", \"ñadir\"]` unless the\n * tokenizer also registers `LatinExtendedIdentifierExtractor`. This rule\n * probes the behavior by tokenizing a canonical diacritic-containing string\n * for each language and warning if it doesn't come back as a single token.\n *\n * Warning (not error) because:\n * - English tokenizers legitimately don't need the extended extractor.\n * - A domain might deliberately split compounds for its own reasons.\n * The warning prompts the author to audit; an explicit waiver can add an\n * opt-out once we have a mechanism for it.\n */\n\nimport type { LintFinding, LintRule } from '../types';\n\nconst RULE_ID = 'extractor-coverage';\n\n/**\n * Canonical diacritic samples per language. Each must be a single logical\n * word in the target language. Chosen to exercise the specific characters\n * that tend to split under the default ASCII extractor.\n */\nconst DIACRITIC_SAMPLES: Record<string, string> = {\n es: 'añadir', // ñ\n fr: 'déjà', // é, à\n pt: 'coração', // ç, ã\n de: 'größer', // ö, ß\n tr: 'değiştir', // ğ, ş\n it: 'però', // ò\n pl: 'kochać', // ć\n cs: 'příliš', // ř, í\n // Not run for en, ja, ar, ko, zh, ru, hi, etc. — either pure ASCII\n // (en) or non-Latin scripts where the Unicode extractor handles them.\n};\n\nexport const extractorCoverageRule: LintRule = input => {\n const findings: LintFinding[] = [];\n\n for (const [lang, sample] of Object.entries(DIACRITIC_SAMPLES)) {\n const tokenizer = input.tokenizers[lang];\n if (!tokenizer) continue; // language not registered in this domain\n\n const stream = tokenizer.tokenize(sample);\n if (stream.tokens.length !== 1) {\n findings.push({\n rule: RULE_ID,\n severity: 'warning',\n message: `[${lang}] diacritic probe \"${sample}\" tokenizes as ${stream.tokens.length} tokens — tokenizer likely missing LatinExtendedIdentifierExtractor`,\n context: {\n domain: input.name,\n lang,\n sample,\n tokenCount: stream.tokens.length,\n },\n });\n }\n }\n\n return findings;\n};\n","/**\n * R9: Role position uniqueness within a schema.\n *\n * `sortRolesByWordOrder` in the pattern generator sorts roles descending by\n * svoPosition or sovPosition (higher value = earlier in surface form). If two\n * roles share the same position value, their relative order is undefined\n * (falls through to array stability) — a latent footgun because token\n * ordering silently changes if someone reorders the roles array.\n *\n * This rule warns when a schema has multiple roles AND any two share an\n * explicit position for the same word order.\n *\n * Warning (not error) because:\n * - Single-role schemas have nothing to order.\n * - A schema might intentionally tie two roles when only one is present\n * at a time (e.g., mutually-exclusive alternatives). In practice we\n * haven't seen this, but the rule should prompt a review, not block.\n *\n * The `sovPosition: 0` default assigned when omitted is NOT flagged — only\n * explicit non-zero collisions count. Otherwise most schemas with 3+\n * optional roles would warn spuriously.\n */\n\nimport type { LintFinding, LintRule } from '../types';\n\nconst RULE_ID = 'position-ordering';\n\nfunction findCollisions(\n values: Array<{ role: string; position: number }>\n): Array<{ position: number; roles: string[] }> {\n const byPosition = new Map<number, string[]>();\n for (const { role, position } of values) {\n const existing = byPosition.get(position) ?? [];\n existing.push(role);\n byPosition.set(position, existing);\n }\n return Array.from(byPosition.entries())\n .filter(([, roles]) => roles.length > 1)\n .map(([position, roles]) => ({ position, roles }));\n}\n\nexport const positionOrderingRule: LintRule = input => {\n const findings: LintFinding[] = [];\n\n for (const schema of input.schemas) {\n if (schema.roles.length < 2) continue;\n\n const svoValues = schema.roles\n .filter(r => typeof r.svoPosition === 'number' && r.svoPosition !== 0)\n .map(r => ({ role: r.role, position: r.svoPosition! }));\n const sovValues = schema.roles\n .filter(r => typeof r.sovPosition === 'number' && r.sovPosition !== 0)\n .map(r => ({ role: r.role, position: r.sovPosition! }));\n\n for (const { position, roles } of findCollisions(svoValues)) {\n findings.push({\n rule: RULE_ID,\n severity: 'warning',\n message: `[${String(schema.action)}] roles ${roles.join(', ')} share svoPosition=${position} — order is undefined`,\n context: {\n domain: input.name,\n action: String(schema.action),\n wordOrder: 'SVO',\n position,\n roles: roles.join(','),\n },\n });\n }\n\n for (const { position, roles } of findCollisions(sovValues)) {\n findings.push({\n rule: RULE_ID,\n severity: 'warning',\n message: `[${String(schema.action)}] roles ${roles.join(', ')} share sovPosition=${position} — order is undefined`,\n context: {\n domain: input.name,\n action: String(schema.action),\n wordOrder: 'SOV',\n position,\n roles: roles.join(','),\n },\n });\n }\n }\n\n return findings;\n};\n","/**\n * R10: Renderer-table coherence (opt-in).\n *\n * Some domains ship a natural-language renderer that maintains its own\n * per-language keyword/marker tables separate from the profile data. This\n * rule — when the domain passes `input.renderer` — asserts that:\n * - Every `commandKeywords[action][lang]` matches `profile.keywords[action].primary`\n * for that language.\n * - Every `markers[name][lang]` appears as a markerOverride value somewhere\n * in the schemas for that language (can't pin to a specific role since\n * renderer marker names are arbitrary labels).\n *\n * Warnings only. Domains without `input.renderer` get a no-op pass — this\n * rule is inherently opt-in because not every domain has round-trip\n * rendering and not every renderer uses the same table shape.\n *\n * Catches the exact drift we fixed earlier this session: domain-sql's\n * Turkish source marker was `dan` in the `get` schema but `den` in the\n * renderer's MARKERS table. Had this rule existed, it would have warned\n * the moment `get` was added with the wrong Turkish variant.\n */\n\nimport type { LintFinding, LintRule } from '../types';\n\nconst RULE_ID = 'renderer-coherence';\n\nexport const rendererCoherenceRule: LintRule = input => {\n if (!input.renderer) return [];\n const findings: LintFinding[] = [];\n\n // commandKeywords ↔ profile primaries\n for (const [action, langMap] of Object.entries(input.renderer.commandKeywords)) {\n for (const [lang, rendererWord] of Object.entries(langMap)) {\n const profile = input.profiles.find(p => p.code === lang);\n if (!profile) continue; // lang not registered; R6 handles that\n const profileEntry = profile.keywords[action];\n if (!profileEntry) {\n findings.push({\n rule: RULE_ID,\n severity: 'warning',\n message: `renderer has '${action}' keyword for ${lang} (\"${rendererWord}\") but profile has no entry for that action`,\n context: { domain: input.name, lang, action, rendererWord },\n });\n continue;\n }\n const profilePrimary = profileEntry.primary;\n const profileAlts = profileEntry.alternatives ?? [];\n if (rendererWord !== profilePrimary && !profileAlts.includes(rendererWord)) {\n findings.push({\n rule: RULE_ID,\n severity: 'warning',\n message: `renderer '${action}' keyword for ${lang} is \"${rendererWord}\" but profile has primary=\"${profilePrimary}\"${profileAlts.length ? ` (alternatives: ${profileAlts.join(', ')})` : ''}`,\n context: {\n domain: input.name,\n lang,\n action,\n rendererWord,\n profilePrimary,\n },\n });\n }\n }\n }\n\n // markers ↔ schema markerOverride values (loose check — any role in any\n // schema for that lang must have this marker value somewhere)\n const markerByLang = new Map<string, Set<string>>();\n for (const schema of input.schemas) {\n for (const role of schema.roles) {\n if (!role.markerOverride) continue;\n for (const [lang, word] of Object.entries(role.markerOverride)) {\n const set = markerByLang.get(lang) ?? new Set<string>();\n set.add(word);\n markerByLang.set(lang, set);\n }\n }\n }\n\n for (const [markerName, langMap] of Object.entries(input.renderer.markers)) {\n for (const [lang, rendererWord] of Object.entries(langMap)) {\n const schemaMarkers = markerByLang.get(lang);\n if (!schemaMarkers) continue; // lang has no markerOverride anywhere; skip\n if (!schemaMarkers.has(rendererWord)) {\n findings.push({\n rule: RULE_ID,\n severity: 'warning',\n message: `renderer marker \"${markerName}\" in ${lang} is \"${rendererWord}\" but no schema role has that markerOverride value — likely drift`,\n context: {\n domain: input.name,\n lang,\n markerName,\n rendererWord,\n },\n });\n }\n }\n }\n\n return findings;\n};\n","/**\n * Rule registry — runs all enabled rules and aggregates findings.\n */\n\nimport type { DomainLintInput, LintFinding, LintRule } from '../types';\nimport { schemaStructureRule } from './schema-rules';\nimport { keywordCoverageRule } from './keyword-coverage';\nimport { keywordClassificationRule } from './keyword-classification';\nimport { markerTokenizationRule } from './marker-tokenization';\nimport { extractorCoverageRule } from './extractor-coverage';\nimport { positionOrderingRule } from './position-ordering';\nimport { rendererCoherenceRule } from './renderer-coherence';\n\n/**\n * All rules in execution order.\n * Phase 1: schema structure (delegates to @lokascript/semantic)\n * Phase 2: keyword coverage + keyword classification + marker tokenization\n * Phase 3: extractor coverage + position ordering (warnings only)\n * Phase 3b: renderer coherence (opt-in via DomainLintInput.renderer)\n */\nexport const ALL_RULES: readonly LintRule[] = [\n schemaStructureRule,\n keywordCoverageRule,\n keywordClassificationRule,\n markerTokenizationRule,\n extractorCoverageRule,\n positionOrderingRule,\n rendererCoherenceRule,\n];\n\nexport function runRules(input: DomainLintInput): LintFinding[] {\n const findings: LintFinding[] = [];\n for (const rule of ALL_RULES) {\n findings.push(...rule(input));\n }\n return findings;\n}\n","/**\n * Pretty-print lint results for test output.\n */\n\nimport type { LintFinding, LintResult, Severity } from './types';\n\nconst SEVERITY_GLYPH: Record<Severity, string> = {\n error: '✗',\n warning: '⚠',\n note: 'ℹ',\n};\n\nexport function formatFinding(finding: LintFinding): string {\n const glyph = SEVERITY_GLYPH[finding.severity];\n return ` ${glyph} [${finding.rule}] ${finding.message}`;\n}\n\nexport function formatResult(result: LintResult): string {\n const header = `domain-toolkit: lint(${result.domain}) — ${result.errorCount} error(s), ${result.warningCount} warning(s)`;\n if (result.findings.length === 0) return `${header}\\n (clean)`;\n const body = result.findings.map(formatFinding).join('\\n');\n return `${header}\\n${body}`;\n}\n","/**\n * The domain linter (domains rethink Phase 4.6): moved from lokascript-domains'\n * `@lokascript/domain-toolkit`. Checks schema structure and cross-file\n * invariants (profile ↔ tokenizer ↔ schema ↔ renderer agreement); a grammar\n * runs it from one lint test.\n *\n * Implemented rules:\n * - R1/R2 (schema-structure): delegates to the validator the input\n * brings (`validateSchema`: the domains pass @lokascript/semantic's).\n * - R5 (keyword-classification): profile keywords/markers classify as\n * 'keyword' in the language's tokenizer.\n * - R6 (keyword-coverage): every schema command has profile keywords for\n * all declared languages.\n * - R7 (marker-tokenization): every marker/keyword tokenizes as a single\n * token.\n * - R8 (extractor-coverage): Latin-script tokenizers handle diacritic\n * identifiers (warning).\n * - R9 (position-ordering): schema role positions are unique per\n * word-order (warning).\n * - R10 (renderer-coherence): renderer table keywords match\n * profile/schema translations (opt-in via `renderer`).\n */\n\nimport { runRules } from './rules';\nimport type { DomainLintInput, LintFinding, LintResult, LintWaiver } from './types';\n\nexport type {\n DomainLintInput,\n LintResult,\n LintFinding,\n LintRule,\n LintWaiver,\n Severity,\n RendererTables,\n SchemaValidationFinding,\n SchemaValidator,\n} from './types';\nexport { formatResult, formatFinding } from './format';\n\nfunction matchesWaiver(finding: LintFinding, waiver: LintWaiver): boolean {\n if (finding.rule !== waiver.rule) return false;\n if (!waiver.matches) return true;\n const ctx = finding.context ?? {};\n for (const [key, expected] of Object.entries(waiver.matches)) {\n if (ctx[key] !== expected) return false;\n }\n return true;\n}\n\nfunction applyWaivers(\n findings: LintFinding[],\n waivers: readonly LintWaiver[] | undefined\n): LintFinding[] {\n if (!waivers || waivers.length === 0) return findings;\n return findings.filter(f => !waivers.some(w => matchesWaiver(f, w)));\n}\n\n/**\n * Lint a domain against all enabled rules and return a structured result.\n */\nexport function lintDomain(input: DomainLintInput): LintResult {\n const raw = runRules(input);\n const findings = applyWaivers(raw, input.waivers);\n const errorCount = findings.filter(f => f.severity === 'error').length;\n const warningCount = findings.filter(f => f.severity === 'warning').length;\n\n return {\n domain: input.name,\n findings,\n errorCount,\n warningCount,\n };\n}\n"],"mappings":"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","names":["RULE_ID","RULE_ID","RULE_ID","RULE_ID","RULE_ID","RULE_ID"]}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Pretty-print lint results for test output.
3
+ */
4
+ import type { LintFinding, LintResult } from './types';
5
+ export declare function formatFinding(finding: LintFinding): string;
6
+ export declare function formatResult(result: LintResult): string;
7
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../../src/testing/gate/lint/format.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAY,MAAM,SAAS,CAAC;AAQjE,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAG1D;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAKvD"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * The domain linter (domains rethink Phase 4.6): moved from lokascript-domains'
3
+ * `@lokascript/domain-toolkit`. Checks schema structure and cross-file
4
+ * invariants (profile ↔ tokenizer ↔ schema ↔ renderer agreement); a grammar
5
+ * runs it from one lint test.
6
+ *
7
+ * Implemented rules:
8
+ * - R1/R2 (schema-structure): delegates to the validator the input
9
+ * brings (`validateSchema`: the domains pass @lokascript/semantic's).
10
+ * - R5 (keyword-classification): profile keywords/markers classify as
11
+ * 'keyword' in the language's tokenizer.
12
+ * - R6 (keyword-coverage): every schema command has profile keywords for
13
+ * all declared languages.
14
+ * - R7 (marker-tokenization): every marker/keyword tokenizes as a single
15
+ * token.
16
+ * - R8 (extractor-coverage): Latin-script tokenizers handle diacritic
17
+ * identifiers (warning).
18
+ * - R9 (position-ordering): schema role positions are unique per
19
+ * word-order (warning).
20
+ * - R10 (renderer-coherence): renderer table keywords match
21
+ * profile/schema translations (opt-in via `renderer`).
22
+ */
23
+ import type { DomainLintInput, LintResult } from './types';
24
+ export type { DomainLintInput, LintResult, LintFinding, LintRule, LintWaiver, Severity, RendererTables, SchemaValidationFinding, SchemaValidator, } from './types';
25
+ export { formatResult, formatFinding } from './format';
26
+ /**
27
+ * Lint a domain against all enabled rules and return a structured result.
28
+ */
29
+ export declare function lintDomain(input: DomainLintInput): LintResult;
30
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/testing/gate/lint/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAe,UAAU,EAAc,MAAM,SAAS,CAAC;AAEpF,YAAY,EACV,eAAe,EACf,UAAU,EACV,WAAW,EACX,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,cAAc,EACd,uBAAuB,EACvB,eAAe,GAChB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAoBvD;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,UAAU,CAY7D"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * R8: Latin-script tokenizers should extract diacritic identifiers as single tokens.
3
+ *
4
+ * The default `IdentifierExtractor` matches `[a-zA-Z0-9_]*` and stops at any
5
+ * diacritic. Words like `añadir` split into `["a", "ñadir"]` unless the
6
+ * tokenizer also registers `LatinExtendedIdentifierExtractor`. This rule
7
+ * probes the behavior by tokenizing a canonical diacritic-containing string
8
+ * for each language and warning if it doesn't come back as a single token.
9
+ *
10
+ * Warning (not error) because:
11
+ * - English tokenizers legitimately don't need the extended extractor.
12
+ * - A domain might deliberately split compounds for its own reasons.
13
+ * The warning prompts the author to audit; an explicit waiver can add an
14
+ * opt-out once we have a mechanism for it.
15
+ */
16
+ import type { LintRule } from '../types';
17
+ export declare const extractorCoverageRule: LintRule;
18
+ //# sourceMappingURL=extractor-coverage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractor-coverage.d.ts","sourceRoot":"","sources":["../../../../../src/testing/gate/lint/rules/extractor-coverage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAe,QAAQ,EAAE,MAAM,UAAU,CAAC;AAsBtD,eAAO,MAAM,qBAAqB,EAAE,QAwBnC,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Rule registry — runs all enabled rules and aggregates findings.
3
+ */
4
+ import type { DomainLintInput, LintFinding, LintRule } from '../types';
5
+ /**
6
+ * All rules in execution order.
7
+ * Phase 1: schema structure (delegates to @lokascript/semantic)
8
+ * Phase 2: keyword coverage + keyword classification + marker tokenization
9
+ * Phase 3: extractor coverage + position ordering (warnings only)
10
+ * Phase 3b: renderer coherence (opt-in via DomainLintInput.renderer)
11
+ */
12
+ export declare const ALL_RULES: readonly LintRule[];
13
+ export declare function runRules(input: DomainLintInput): LintFinding[];
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/testing/gate/lint/rules/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AASvE;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,EAAE,SAAS,QAAQ,EAQxC,CAAC;AAEF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,WAAW,EAAE,CAM9D"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * R5: Keyword classification — profile keywords ⊆ tokenizer keyword lists.
3
+ *
4
+ * Every lexical item the parser must recognize as a keyword — profile
5
+ * keyword primaries/alternatives, profile role markers, and schema
6
+ * `markerOverride` words — must actually *classify* as `'keyword'` in that
7
+ * language's tokenizer. This is stricter than R7 (marker-tokenization):
8
+ * a word can tokenize as a single token yet come back as `'identifier'`
9
+ * when the tokenizer's keyword list doesn't contain it.
10
+ *
11
+ * Under the bridge (`buildDomainTokenizer`) profile and tokenizer derive
12
+ * from the same vocab file, so this rule is vacuously green there. It
13
+ * exists for hand-authored tokenizers (e.g. domain-learn) and custom
14
+ * tokenizer overrides, where a vocab/profile edit can silently go stale
15
+ * against the tokenizer's keyword list.
16
+ */
17
+ import type { LintRule } from '../types';
18
+ export declare const keywordClassificationRule: LintRule;
19
+ //# sourceMappingURL=keyword-classification.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyword-classification.d.ts","sourceRoot":"","sources":["../../../../../src/testing/gate/lint/rules/keyword-classification.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAe,QAAQ,EAAE,MAAM,UAAU,CAAC;AAKtD,eAAO,MAAM,yBAAyB,EAAE,QA6BvC,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * R6: Keyword coverage across profiles.
3
+ *
4
+ * For every schema action + every registered profile, the profile must have
5
+ * a `keywords[action]` entry. Without it, `createMultilingualDSL()` throws
6
+ * at pattern generation time ("No keyword translation for 'X' in 'Y'").
7
+ *
8
+ * This rule catches the "I added a new schema but only wired it into the
9
+ * English profile" class of drift.
10
+ */
11
+ import type { LintRule } from '../types';
12
+ export declare const keywordCoverageRule: LintRule;
13
+ //# sourceMappingURL=keyword-coverage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyword-coverage.d.ts","sourceRoot":"","sources":["../../../../../src/testing/gate/lint/rules/keyword-coverage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAe,QAAQ,EAAE,MAAM,UAAU,CAAC;AAItD,eAAO,MAAM,mBAAmB,EAAE,QAsBjC,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * R7: Marker and keyword tokenization.
3
+ *
4
+ * Every lexical item the parser needs to match atomically — marker words,
5
+ * profile keyword primaries, and profile keyword alternatives — must
6
+ * tokenize as a single token in its target language. A word that splits
7
+ * across multiple tokens (e.g., `añadir` → `["a", "ñadir"]` when the
8
+ * tokenizer lacks `LatinExtendedIdentifierExtractor`) will never match a
9
+ * pattern's literal token.
10
+ *
11
+ * This is the exact gap that bit us on the Spanish tokenizer mid-session.
12
+ */
13
+ import type { LintRule, DomainLintInput } from '../types';
14
+ export declare function collectLexicalItems(input: DomainLintInput): Array<{
15
+ lang: string;
16
+ word: string;
17
+ source: string;
18
+ }>;
19
+ export declare const markerTokenizationRule: LintRule;
20
+ //# sourceMappingURL=marker-tokenization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marker-tokenization.d.ts","sourceRoot":"","sources":["../../../../../src/testing/gate/lint/rules/marker-tokenization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAe,QAAQ,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAUvE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,eAAe,GAAG,KAAK,CAAC;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CA0DD;AAED,eAAO,MAAM,sBAAsB,EAAE,QAyCpC,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * R9: Role position uniqueness within a schema.
3
+ *
4
+ * `sortRolesByWordOrder` in the pattern generator sorts roles descending by
5
+ * svoPosition or sovPosition (higher value = earlier in surface form). If two
6
+ * roles share the same position value, their relative order is undefined
7
+ * (falls through to array stability) — a latent footgun because token
8
+ * ordering silently changes if someone reorders the roles array.
9
+ *
10
+ * This rule warns when a schema has multiple roles AND any two share an
11
+ * explicit position for the same word order.
12
+ *
13
+ * Warning (not error) because:
14
+ * - Single-role schemas have nothing to order.
15
+ * - A schema might intentionally tie two roles when only one is present
16
+ * at a time (e.g., mutually-exclusive alternatives). In practice we
17
+ * haven't seen this, but the rule should prompt a review, not block.
18
+ *
19
+ * The `sovPosition: 0` default assigned when omitted is NOT flagged — only
20
+ * explicit non-zero collisions count. Otherwise most schemas with 3+
21
+ * optional roles would warn spuriously.
22
+ */
23
+ import type { LintRule } from '../types';
24
+ export declare const positionOrderingRule: LintRule;
25
+ //# sourceMappingURL=position-ordering.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"position-ordering.d.ts","sourceRoot":"","sources":["../../../../../src/testing/gate/lint/rules/position-ordering.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAe,QAAQ,EAAE,MAAM,UAAU,CAAC;AAkBtD,eAAO,MAAM,oBAAoB,EAAE,QA6ClC,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * R10: Renderer-table coherence (opt-in).
3
+ *
4
+ * Some domains ship a natural-language renderer that maintains its own
5
+ * per-language keyword/marker tables separate from the profile data. This
6
+ * rule — when the domain passes `input.renderer` — asserts that:
7
+ * - Every `commandKeywords[action][lang]` matches `profile.keywords[action].primary`
8
+ * for that language.
9
+ * - Every `markers[name][lang]` appears as a markerOverride value somewhere
10
+ * in the schemas for that language (can't pin to a specific role since
11
+ * renderer marker names are arbitrary labels).
12
+ *
13
+ * Warnings only. Domains without `input.renderer` get a no-op pass — this
14
+ * rule is inherently opt-in because not every domain has round-trip
15
+ * rendering and not every renderer uses the same table shape.
16
+ *
17
+ * Catches the exact drift we fixed earlier this session: domain-sql's
18
+ * Turkish source marker was `dan` in the `get` schema but `den` in the
19
+ * renderer's MARKERS table. Had this rule existed, it would have warned
20
+ * the moment `get` was added with the wrong Turkish variant.
21
+ */
22
+ import type { LintRule } from '../types';
23
+ export declare const rendererCoherenceRule: LintRule;
24
+ //# sourceMappingURL=renderer-coherence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer-coherence.d.ts","sourceRoot":"","sources":["../../../../../src/testing/gate/lint/rules/renderer-coherence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAe,QAAQ,EAAE,MAAM,UAAU,CAAC;AAItD,eAAO,MAAM,qBAAqB,EAAE,QAyEnC,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Schema-structure rules (R1, R2).
3
+ *
4
+ * Delegates to the validator the input brings (`DomainLintInput.validateSchema`): the domains pass
5
+ * `@lokascript/semantic`'s `validateCommandSchema`, whose checks are already solid. We only surface its
6
+ * error- and warning-level items; notes are dropped to keep linter output focused.
7
+ */
8
+ import type { LintRule } from '../types';
9
+ export declare const schemaStructureRule: LintRule;
10
+ //# sourceMappingURL=schema-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-rules.d.ts","sourceRoot":"","sources":["../../../../../src/testing/gate/lint/rules/schema-rules.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAe,QAAQ,EAAE,MAAM,UAAU,CAAC;AAItD,eAAO,MAAM,mBAAmB,EAAE,QAsBjC,CAAC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Core types for the domain linter.
3
+ */
4
+ import type { CommandSchema } from '../../../schema';
5
+ import type { LanguageTokenizer } from '../../../core/types';
6
+ import type { PatternGenLanguageProfile } from '../../../generation/pattern-generator';
7
+ export type Severity = 'error' | 'warning' | 'note';
8
+ export interface LintFinding {
9
+ readonly rule: string;
10
+ readonly severity: Severity;
11
+ readonly message: string;
12
+ /** Optional structured context: domain, language code, command action, role name, etc. */
13
+ readonly context?: Record<string, string | number | boolean>;
14
+ }
15
+ export interface LintResult {
16
+ readonly domain: string;
17
+ readonly findings: readonly LintFinding[];
18
+ /** Count helpers — derived from findings. */
19
+ readonly errorCount: number;
20
+ readonly warningCount: number;
21
+ }
22
+ /**
23
+ * Optional renderer metadata for R10 (renderer-coherence check).
24
+ * Domains without a renderer or without standard table shape omit this field.
25
+ */
26
+ export interface RendererTables {
27
+ /** Keyed by action name → lang code → keyword. */
28
+ readonly commandKeywords: Record<string, Record<string, string>>;
29
+ /** Keyed by marker name → lang code → marker word. */
30
+ readonly markers: Record<string, Record<string, string>>;
31
+ }
32
+ /**
33
+ * Matcher for an acknowledged-but-unfixed finding. Each entry is an object
34
+ * whose fields are compared against the finding's rule + context. A finding
35
+ * matches a waiver if every field in the waiver matches the corresponding
36
+ * field on the finding (or finding.context). Matched findings are dropped
37
+ * from the returned result entirely.
38
+ *
39
+ * Use sparingly — waivers are real debt that should have a plan to resolve.
40
+ */
41
+ export interface LintWaiver {
42
+ readonly rule: string;
43
+ readonly reason: string;
44
+ readonly matches?: Record<string, string | number | boolean>;
45
+ }
46
+ export interface DomainLintInput {
47
+ readonly name: string;
48
+ readonly schemas: readonly CommandSchema[];
49
+ readonly profiles: readonly PatternGenLanguageProfile[];
50
+ readonly tokenizers: Readonly<Record<string, LanguageTokenizer>>;
51
+ readonly renderer?: RendererTables;
52
+ readonly waivers?: readonly LintWaiver[];
53
+ /**
54
+ * The schema validator R1/R2 (schema-structure) run. The domains pass `@lokascript/semantic`'s
55
+ * `validateCommandSchema`; framework cannot import semantic, which depends on it. Without one, the
56
+ * rule finds nothing.
57
+ */
58
+ readonly validateSchema?: SchemaValidator;
59
+ }
60
+ /** One finding of a schema validator. */
61
+ export interface SchemaValidationFinding {
62
+ readonly code: string;
63
+ readonly severity: Severity;
64
+ readonly message: string;
65
+ }
66
+ /** A schema validator: `@lokascript/semantic`'s `validateCommandSchema` has this shape. */
67
+ export type SchemaValidator = (schema: CommandSchema) => {
68
+ readonly items: readonly SchemaValidationFinding[];
69
+ };
70
+ /**
71
+ * A single rule is a pure function producing findings.
72
+ */
73
+ export type LintRule = (input: DomainLintInput) => LintFinding[];
74
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/testing/gate/lint/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAEvF,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,0FAA0F;IAC1F,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CAC9D;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAC1C,6CAA6C;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjE,sDAAsD;IACtD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC1D;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CAC9D;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;IAC3C,QAAQ,CAAC,QAAQ,EAAE,SAAS,yBAAyB,EAAE,CAAC;IACxD,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACjE,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;IACnC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACzC;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,eAAe,CAAC;CAC3C;AAED,yCAAyC;AACzC,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,2FAA2F;AAC3F,MAAM,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,aAAa,KAAK;IACvD,QAAQ,CAAC,KAAK,EAAE,SAAS,uBAAuB,EAAE,CAAC;CACpD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,eAAe,KAAK,WAAW,EAAE,CAAC"}
@@ -0,0 +1,163 @@
1
+ /**
2
+ * The round-trip gate kit (domains rethink Phase 4.6, `docs-internal/DOMAINS_RETHINK.md`): every
3
+ * command of a grammar, written in each of its languages by its own renderer and read back by its own
4
+ * parser. Moved from lokascript-domains' `packages/domains/gate/round-trip.ts` (the domain gate, Phase
5
+ * 2), so any grammar on the framework runs the same gate; the domains repo keeps its fixtures
6
+ * (`gate/values.ts`), baselines and regen tool.
7
+ *
8
+ * A case is a command (bracket syntax, parsed in English) and a language:
9
+ *
10
+ * - **round trip**: `render(ref, lang)`, then `parse`. `pass` when the parse is the reference node, or,
11
+ * for a grammar whose compiled output does not depend on the language, when the text compiles to what
12
+ * the command itself (its bracket form) compiles to (a parser may keep a translated word that the
13
+ * generator normalizes: bdd ja `#box0 が 表示 前提` is `visible`). English is a lane like the others.
14
+ * `refused` when the render is null or the parse throws: the caller is told. `silent` otherwise: it
15
+ * reads, or compiles to, something else.
16
+ * - **leftover**: the same render plus one unknown word. `refused` is the expected outcome; a parse
17
+ * that returns accepted input it did not read (`silent`).
18
+ *
19
+ * The outcomes are the command-shape gate's (hyperfixi `testing-framework`). A baseline lists every
20
+ * case that is not at its best outcome; `compare` reports a case worse than listed and one better than
21
+ * listed, so a gate built on it only shrinks.
22
+ */
23
+ export type Outcome = 'pass' | 'refused' | 'silent';
24
+ export type CaseKind = 'roundTrip' | 'leftover';
25
+ /** Best first. A round trip's best is `pass`; leftover input's is `refused`. */
26
+ export declare const RANK: Record<CaseKind, Record<Outcome, number>>;
27
+ export declare const BEST: Record<CaseKind, Outcome>;
28
+ /** Appended for the leftover cases: a word no grammar's vocabulary has. */
29
+ export declare const UNKNOWN_WORD = "zzqx";
30
+ export interface CaseResult {
31
+ /** The grammar (a domain's name). */
32
+ grammar: string;
33
+ kind: CaseKind;
34
+ /** The command, in bracket syntax (read in English). */
35
+ source: string;
36
+ lang: string;
37
+ outcome: Outcome;
38
+ /** What the renderer wrote (plus the unknown word, for leftover). */
39
+ text?: string;
40
+ /** Why it is not `pass`: the error, or what the parse read instead. */
41
+ why?: string;
42
+ /** The round trip's parse, summarized (`summarize`); absent when it was refused. */
43
+ read?: string;
44
+ }
45
+ /** What the gate reads of a role in a schema. */
46
+ export interface GateRoleSpec {
47
+ readonly role: string;
48
+ readonly required?: boolean;
49
+ readonly expectedTypes?: readonly string[];
50
+ }
51
+ /** What the gate reads of a command schema. */
52
+ export interface GateSchema {
53
+ readonly action: string;
54
+ readonly roles: readonly GateRoleSpec[];
55
+ }
56
+ /** What the gate reads of a parse. */
57
+ export interface GateNode {
58
+ readonly action: string;
59
+ readonly roles: ReadonlyMap<string, unknown> | Readonly<Record<string, unknown>>;
60
+ }
61
+ /** The grammar's DSL, as the gate drives it. */
62
+ export interface GateDSL {
63
+ parse(input: string, language: string): GateNode;
64
+ compile(input: string, language: string): {
65
+ ok: boolean;
66
+ code?: string;
67
+ errors?: string[];
68
+ };
69
+ render?(node: GateNode, language: string): string | null;
70
+ getSupportedLanguages(): string[];
71
+ }
72
+ /**
73
+ * The values the gate writes into each role. A role not listed gets a plain name no vocabulary uses
74
+ * (`v0x`, or `#box0` where only a selector fits): its value must come back verbatim. A role that takes
75
+ * FIXED words lists every word the grammar's renderer and generator know, in English: the gate writes
76
+ * the command once per word, in every language, so a word one of the two tables lacks fails in the
77
+ * languages where it is missing.
78
+ */
79
+ export interface GateFixture {
80
+ /**
81
+ * `compile`: a round trip also passes when the text compiles to the command's own code (the grammar
82
+ * compiles to something that does not depend on the language). `node`: only the parse counts (a
83
+ * grammar that compiles to a sentence in each language).
84
+ */
85
+ oracle: 'compile' | 'node';
86
+ /** Keys are `<action>.<role>` or `<role>` (every action). The first value is the one the other cases use. */
87
+ values: Record<string, string[]>;
88
+ /** Actions that do not compile on their own (a gate may check every other one does). */
89
+ englishDoesNotCompile?: string[];
90
+ }
91
+ /**
92
+ * The commands a grammar is checked on: for each schema, its required roles alone and all its roles
93
+ * (each with its first value), then each further value of a role that takes fixed words, alone.
94
+ */
95
+ export declare function commandsFor(schemas: readonly GateSchema[], fixture: GateFixture): string[];
96
+ /** A parse as one line: `action role:type=value …`, roles sorted. What the parse snapshot records. */
97
+ export declare function summarize(node: GateNode): string;
98
+ /** What a command (bracket syntax) compiles to; null when it does not compile on its own. */
99
+ export declare function referenceCode(dsl: GateDSL, source: string): string | null;
100
+ /** Run every case of one grammar: each command of `commandsFor` in each of the DSL's languages. */
101
+ export declare function runRoundTrip(grammar: string, dsl: GateDSL, schemas: readonly GateSchema[], fixture: GateFixture): CaseResult[];
102
+ export interface ListedCase {
103
+ outcome: Exclude<Outcome, 'pass'>;
104
+ text?: string;
105
+ why?: string;
106
+ }
107
+ export interface GateBaseline {
108
+ /** The upstream packages this was measured on (the grammar's lockfile). */
109
+ upstream: Record<string, string>;
110
+ /** Per grammar and kind: cases and outcomes. Written by the regen tool for the reader; not checked. */
111
+ counts: Record<string, Record<CaseKind, Record<Outcome | 'cases', number>>>;
112
+ /** Per grammar, command and language: every round trip that is not `pass`. */
113
+ roundTrip: Record<string, Record<string, Record<string, ListedCase>>>;
114
+ /** Per grammar and command: the languages whose leftover case was accepted (`silent`). */
115
+ leftover: Record<string, Record<string, string[]>>;
116
+ }
117
+ export interface DriftCase {
118
+ kind: CaseKind;
119
+ source: string;
120
+ lang: string;
121
+ listed: Outcome;
122
+ now: Outcome;
123
+ text?: string;
124
+ why?: string;
125
+ }
126
+ export interface Drift {
127
+ worse: DriftCase[];
128
+ better: DriftCase[];
129
+ /** Listed cases that are no longer cases at all. */
130
+ stale: {
131
+ kind: CaseKind;
132
+ source: string;
133
+ lang: string;
134
+ }[];
135
+ }
136
+ /** How one grammar's results moved against the baseline. */
137
+ export declare function compare(grammar: string, results: CaseResult[], baseline: GateBaseline): Drift;
138
+ /** The baseline entries for one grammar's results. */
139
+ export declare function listingOf(results: CaseResult[]): {
140
+ roundTrip: Record<string, Record<string, ListedCase>>;
141
+ leftover: Record<string, string[]>;
142
+ };
143
+ export declare function countsOf(results: CaseResult[]): Record<CaseKind, Record<Outcome | 'cases', number>>;
144
+ /**
145
+ * Every round trip's parse, so a change that moves a parse shows it, whether or not an outcome moved
146
+ * (a value's type, a role a passing case gained, what a silent case reads now). `refused` where the
147
+ * parse threw. Leftover cases are not in it: their outcome is the baseline's.
148
+ */
149
+ export interface ParseSnapshot {
150
+ upstream: Record<string, string>;
151
+ /** Per grammar, command and language. */
152
+ parses: Record<string, Record<string, Record<string, string>>>;
153
+ }
154
+ export declare function snapshotOf(results: CaseResult[]): Record<string, Record<string, string>>;
155
+ export interface SnapshotChange {
156
+ source: string;
157
+ lang: string;
158
+ was?: string;
159
+ now?: string;
160
+ }
161
+ /** Every round trip whose parse differs from the snapshot's, for one grammar. */
162
+ export declare function snapshotChanges(grammar: string, results: CaseResult[], snapshot: ParseSnapshot): SnapshotChange[];
163
+ //# sourceMappingURL=round-trip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"round-trip.d.ts","sourceRoot":"","sources":["../../../src/testing/gate/round-trip.ts"],"names":[],"mappings":"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"}