@lokascript/framework 4.7.0 → 5.0.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 (96) hide show
  1. package/CHANGELOG.md +76 -1
  2. package/dist/api/create-dsl.d.ts +14 -12
  3. package/dist/api/create-dsl.d.ts.map +1 -1
  4. package/dist/api/index.js +888 -1683
  5. package/dist/api/index.js.map +1 -1
  6. package/dist/core/index.d.ts +0 -1
  7. package/dist/core/index.d.ts.map +1 -1
  8. package/dist/core/index.js +560 -1133
  9. package/dist/core/index.js.map +1 -1
  10. package/dist/core/matching/index.d.ts +2 -0
  11. package/dist/core/matching/index.d.ts.map +1 -1
  12. package/dist/core/matching/possessive-keywords.d.ts.map +1 -0
  13. package/dist/core/matching/stock-confidence.d.ts +3 -4
  14. package/dist/core/matching/stock-confidence.d.ts.map +1 -1
  15. package/dist/core/matching/stock-reader.d.ts +8 -1
  16. package/dist/core/matching/stock-reader.d.ts.map +1 -1
  17. package/dist/core/matching/stock-reading.d.ts +4 -4
  18. package/dist/core/{pattern-matching/utils → matching}/type-validation.d.ts +1 -1
  19. package/dist/core/matching/type-validation.d.ts.map +1 -0
  20. package/dist/core/types.d.ts +5 -0
  21. package/dist/core/types.d.ts.map +1 -1
  22. package/dist/core/types.js.map +1 -1
  23. package/dist/generation/index.d.ts +1 -1
  24. package/dist/generation/index.d.ts.map +1 -1
  25. package/dist/generation/index.js +32 -171
  26. package/dist/generation/index.js.map +1 -1
  27. package/dist/generation/profile.d.ts +30 -0
  28. package/dist/generation/profile.d.ts.map +1 -0
  29. package/dist/generation/renderer.d.ts +1 -1
  30. package/dist/generation/renderer.d.ts.map +1 -1
  31. package/dist/generation/schema-patterns.d.ts +3 -3
  32. package/dist/index.cjs +969 -1674
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.js +969 -1668
  35. package/dist/index.js.map +1 -1
  36. package/dist/ir/index.js.map +1 -1
  37. package/dist/multilingual/builders.d.ts +3 -3
  38. package/dist/multilingual/builders.d.ts.map +1 -1
  39. package/dist/multilingual/index.js.map +1 -1
  40. package/dist/parsing/index.d.ts +0 -1
  41. package/dist/parsing/index.d.ts.map +1 -1
  42. package/dist/parsing/index.js +0 -1145
  43. package/dist/parsing/index.js.map +1 -1
  44. package/dist/testing/gate/index.js +44 -12
  45. package/dist/testing/gate/index.js.map +1 -1
  46. package/dist/testing/gate/lint/types.d.ts +1 -1
  47. package/dist/testing/gate/lint/types.d.ts.map +1 -1
  48. package/dist/testing/gate/round-trip.d.ts +24 -3
  49. package/dist/testing/gate/round-trip.d.ts.map +1 -1
  50. package/package.json +2 -7
  51. package/src/__test__/test-utils.ts +1 -1
  52. package/src/api/create-dsl-engine.test.ts +123 -34
  53. package/src/api/create-dsl.test.ts +7 -0
  54. package/src/api/create-dsl.ts +56 -39
  55. package/src/core/index.ts +0 -1
  56. package/src/core/matching/index.ts +2 -0
  57. package/src/core/matching/stock-confidence.ts +3 -4
  58. package/src/core/matching/stock-reader.test.ts +87 -3
  59. package/src/core/matching/stock-reader.ts +20 -1
  60. package/src/core/matching/stock-reading.ts +6 -6
  61. package/src/core/{pattern-matching/utils → matching}/type-validation.test.ts +2 -2
  62. package/src/core/{pattern-matching/utils → matching}/type-validation.ts +1 -1
  63. package/src/core/types.ts +5 -0
  64. package/src/generation/domain-renderer.test.ts +1 -1
  65. package/src/generation/index.ts +1 -1
  66. package/src/generation/profile.ts +41 -0
  67. package/src/generation/renderer.test.ts +1 -1
  68. package/src/generation/renderer.ts +1 -1
  69. package/src/generation/schema-patterns.test.ts +41 -1
  70. package/src/generation/schema-patterns.ts +15 -3
  71. package/src/multilingual/bridge.test.ts +31 -23
  72. package/src/multilingual/builders.ts +3 -3
  73. package/src/parsing/index.ts +0 -1
  74. package/src/testing/gate/lint/types.ts +1 -1
  75. package/src/testing/gate/round-trip.test.ts +99 -9
  76. package/src/testing/gate/round-trip.ts +76 -11
  77. package/dist/core/pattern-matching/index.d.ts +0 -6
  78. package/dist/core/pattern-matching/index.d.ts.map +0 -1
  79. package/dist/core/pattern-matching/index.js +0 -1211
  80. package/dist/core/pattern-matching/index.js.map +0 -1
  81. package/dist/core/pattern-matching/pattern-matcher.d.ts +0 -122
  82. package/dist/core/pattern-matching/pattern-matcher.d.ts.map +0 -1
  83. package/dist/core/pattern-matching/utils/index.d.ts +0 -6
  84. package/dist/core/pattern-matching/utils/index.d.ts.map +0 -1
  85. package/dist/core/pattern-matching/utils/possessive-keywords.d.ts.map +0 -1
  86. package/dist/core/pattern-matching/utils/type-validation.d.ts.map +0 -1
  87. package/dist/generation/pattern-generator.d.ts +0 -55
  88. package/dist/generation/pattern-generator.d.ts.map +0 -1
  89. package/src/core/pattern-matching/index.ts +0 -6
  90. package/src/core/pattern-matching/pattern-matcher.test.ts +0 -1031
  91. package/src/core/pattern-matching/pattern-matcher.ts +0 -765
  92. package/src/core/pattern-matching/utils/index.ts +0 -6
  93. package/src/generation/pattern-generator.test.ts +0 -532
  94. package/src/generation/pattern-generator.ts +0 -327
  95. /package/dist/core/{pattern-matching/utils → matching}/possessive-keywords.d.ts +0 -0
  96. /package/src/core/{pattern-matching/utils → matching}/possessive-keywords.ts +0 -0
@@ -1 +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"]}
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: the parse\n * throws, or the input does not compile. `pass` where the word is READ: the parse is the text's own\n * with the word in one role (an open-text role extended by it, `where active zzqx`, or a role the\n * text left empty, `list zzqx`), and the word is in the code (for a command that never compiles on\n * its own, `englishDoesNotCompile`, the parse alone). `silent` otherwise: the input is accepted and\n * read as something else (`when clicks zzqx`: actor `clicks`, action `zzqx`), or the word goes\n * nowhere (voice `back zzqx` compiles as `back`).\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 /**\n * Commands (bracket syntax) written besides the generated ones, where one role's value depends on\n * another's and no single list fits both: behaviorspec's `[given subject:#box value:visible]` beside\n * `[given subject:viewport value:1024x768]`.\n */\n commands?: string[];\n /**\n * Actions that do not compile on their own (a gate may check every other one does). Leftover input\n * in such a command is judged by its parse alone.\n */\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 for (const command of fixture.commands ?? []) out.add(command);\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 `text` compiles to, or `undefined` when it does not compile. */\nfunction codeOf(dsl: GateDSL, text: string, lang: string): string | undefined {\n try {\n const c = dsl.compile(text, lang);\n return c.ok && typeof c.code === 'string' ? c.code : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Whether `read`, the parse of a text plus `word`, is `back`, the text's own parse, with the word read\n * into it: the same action and roles, except one role, whose value is its value in `back` followed by\n * the word (an open-text role at the end: sql `where active zzqx`) or, where `back` has no such role,\n * the word itself (todo `list zzqx`).\n */\nexport function readsWord(back: GateNode, read: GateNode, word: string): boolean {\n if (read.action !== back.action) return false;\n const was = roleValues(back);\n const now = roleValues(read);\n let changed = 0;\n for (const role of new Set([...Object.keys(was), ...Object.keys(now)])) {\n if (was[role] === now[role]) continue;\n if (now[role] !== (role in was ? `${was[role]} ${word}` : word)) return false;\n changed++;\n }\n return changed === 1;\n}\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 let read: GateNode;\n try {\n read = dsl.parse(extended, lang);\n } catch {\n results.push({ ...at, kind: 'leftover', outcome: 'refused', text: extended });\n continue;\n }\n // Read with the word, the word must reach the code. Where the input does not compile, compile\n // tells the caller (`refused`), except for a command that never compiles on its own (bdd's\n // `and`), where only the parse can say.\n const kept = readsWord(back, read, UNKNOWN_WORD);\n const code = kept ? codeOf(dsl, extended, lang) : undefined;\n const alone = fixture.englishDoesNotCompile?.includes(read.action) ?? false;\n const [left, leftWhy]: [Outcome, string | undefined] = !kept\n ? [\n 'silent',\n `accepted as ${read.action}; reads ${describeRead(roleValues(back), back, read)}`,\n ]\n : code !== undefined\n ? code.includes(UNKNOWN_WORD)\n ? ['pass', undefined]\n : ['silent', `accepted as ${read.action}; the word does not reach the code`]\n : alone\n ? ['pass', undefined]\n : ['refused', 'does not compile'];\n results.push({\n ...at,\n kind: 'leftover',\n outcome: left,\n text: extended,\n ...(leftWhy ? { why: leftWhy } : {}),\n read: summarize(read),\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":["code","RULE_ID","RULE_ID","RULE_ID","RULE_ID","RULE_ID","RULE_ID"]}
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import type { CommandSchema } from '../../../schema';
5
5
  import type { LanguageTokenizer } from '../../../core/types';
6
- import type { PatternGenLanguageProfile } from '../../../generation/pattern-generator';
6
+ import type { PatternGenLanguageProfile } from '../../../generation/profile';
7
7
  export type Severity = 'error' | 'warning' | 'note';
8
8
  export interface LintFinding {
9
9
  readonly rule: string;
@@ -1 +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"}
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,6BAA6B,CAAC;AAE7E,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"}
@@ -13,8 +13,13 @@
13
13
  * generator normalizes: bdd ja `#box0 が 表示 前提` is `visible`). English is a lane like the others.
14
14
  * `refused` when the render is null or the parse throws: the caller is told. `silent` otherwise: it
15
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`).
16
+ * - **leftover**: the same render plus one unknown word. `refused` is the expected outcome: the parse
17
+ * throws, or the input does not compile. `pass` where the word is READ: the parse is the text's own
18
+ * with the word in one role (an open-text role extended by it, `where active zzqx`, or a role the
19
+ * text left empty, `list zzqx`), and the word is in the code (for a command that never compiles on
20
+ * its own, `englishDoesNotCompile`, the parse alone). `silent` otherwise: the input is accepted and
21
+ * read as something else (`when clicks zzqx`: actor `clicks`, action `zzqx`), or the word goes
22
+ * nowhere (voice `back zzqx` compiles as `back`).
18
23
  *
19
24
  * The outcomes are the command-shape gate's (hyperfixi `testing-framework`). A baseline lists every
20
25
  * case that is not at its best outcome; `compare` reports a case worse than listed and one better than
@@ -85,7 +90,16 @@ export interface GateFixture {
85
90
  oracle: 'compile' | 'node';
86
91
  /** Keys are `<action>.<role>` or `<role>` (every action). The first value is the one the other cases use. */
87
92
  values: Record<string, string[]>;
88
- /** Actions that do not compile on their own (a gate may check every other one does). */
93
+ /**
94
+ * Commands (bracket syntax) written besides the generated ones, where one role's value depends on
95
+ * another's and no single list fits both: behaviorspec's `[given subject:#box value:visible]` beside
96
+ * `[given subject:viewport value:1024x768]`.
97
+ */
98
+ commands?: string[];
99
+ /**
100
+ * Actions that do not compile on their own (a gate may check every other one does). Leftover input
101
+ * in such a command is judged by its parse alone.
102
+ */
89
103
  englishDoesNotCompile?: string[];
90
104
  }
91
105
  /**
@@ -95,6 +109,13 @@ export interface GateFixture {
95
109
  export declare function commandsFor(schemas: readonly GateSchema[], fixture: GateFixture): string[];
96
110
  /** A parse as one line: `action role:type=value …`, roles sorted. What the parse snapshot records. */
97
111
  export declare function summarize(node: GateNode): string;
112
+ /**
113
+ * Whether `read`, the parse of a text plus `word`, is `back`, the text's own parse, with the word read
114
+ * into it: the same action and roles, except one role, whose value is its value in `back` followed by
115
+ * the word (an open-text role at the end: sql `where active zzqx`) or, where `back` has no such role,
116
+ * the word itself (todo `list zzqx`).
117
+ */
118
+ export declare function readsWord(back: GateNode, read: GateNode, word: string): boolean;
98
119
  /** What a command (bracket syntax) compiles to; null when it does not compile on its own. */
99
120
  export declare function referenceCode(dsl: GateDSL, source: string): string | null;
100
121
  /** Run every case of one grammar: each command of `commandsFor` in each of the DSL's languages. */
@@ -1 +1 @@
1
- {"version":3,"file":"round-trip.d.ts","sourceRoot":"","sources":["../../../src/testing/gate/round-trip.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"round-trip.d.ts","sourceRoot":"","sources":["../../../src/testing/gate/round-trip.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lokascript/framework",
3
- "version": "4.7.0",
3
+ "version": "5.0.0",
4
4
  "description": "Generic framework for building multilingual DSLs with semantic parsing and grammar transformation",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -24,10 +24,6 @@
24
24
  "types": "./dist/core/tokenization/index.d.ts",
25
25
  "import": "./dist/core/tokenization/index.js"
26
26
  },
27
- "./core/pattern-matching": {
28
- "types": "./dist/core/pattern-matching/index.d.ts",
29
- "import": "./dist/core/pattern-matching/index.js"
30
- },
31
27
  "./multilingual": {
32
28
  "types": "./dist/multilingual/index.d.ts",
33
29
  "import": "./dist/multilingual/index.js"
@@ -77,7 +73,6 @@
77
73
  "test:coverage": "vitest run --coverage",
78
74
  "test:unit": "vitest run src/core/**/*.test.ts src/generation/**/*.test.ts",
79
75
  "test:integration": "vitest run src/__test__/**/*.test.ts src/api/**/*.test.ts",
80
- "test:pattern-matcher": "vitest run src/core/pattern-matching",
81
76
  "test:tokenizer": "vitest run src/core/tokenization",
82
77
  "typecheck": "tsc --noEmit",
83
78
  "create-domain": "npx tsx scripts/create-domain.ts"
@@ -100,7 +95,7 @@
100
95
  "author": "LokaScript Contributors",
101
96
  "license": "MIT",
102
97
  "dependencies": {
103
- "@lokascript/intent": "^4.7.0"
98
+ "@lokascript/intent": "^5.0.0"
104
99
  },
105
100
  "devDependencies": {
106
101
  "@lokascript/domains": "^4.0.0",
@@ -15,7 +15,7 @@ import type {
15
15
  PatternMatchResult,
16
16
  } from '../core/types';
17
17
  import type { CommandSchema, RoleSpec } from '../schema';
18
- import type { PatternGenLanguageProfile } from '../generation/pattern-generator';
18
+ import type { PatternGenLanguageProfile } from '../generation/profile';
19
19
  import type { LanguageConfig, MultilingualDSL } from '../api';
20
20
  import { TokenStreamImpl, createToken, createPosition } from '../core/tokenization';
21
21
  import { createMultilingualDSL } from '../api';