/** * Tree-sitter node kinds that are safe to use as the outer target of an * `inside:` / `has:` / `not:` combinator in a compound ast-grep rule. * * Why a named export: the allow-list has independent value beyond the * compiler prompt. `totem doctor` will lint existing compiled rules for * illegal `kind:` targets, and future rule-tester hints can surface the * same list. Interpolating it into the prompt keeps the two consumers in * sync — a single source of truth. * * Why these kinds: they cover the structural contexts that show up in * real lessons (control flow, function and class bodies, module-level * imports and exports). Sourced from the compound ast-grep spike * findings at packages/core/spikes/compound-ast-grep/findings.md (gap * G-3) plus the ADR-087 / Proposal 226 design doc. * * Why not `pattern:` as the outer target: the spike harness test 8 * pinned the empirical finding that an outer `inside: { pattern: 'for * ($INIT; $COND; $STEP) { $$$ }' }` silently matches zero. The * combinator target must be a single-node kind match for the match * engine to pin the scope reliably. The prompt (below) forbids the * pattern: shape for outer targets; this list enumerates the accepted * kinds. */ export declare const KIND_ALLOW_LIST: readonly ["for_statement", "for_in_statement", "while_statement", "do_statement", "try_statement", "catch_clause", "function_declaration", "method_definition", "arrow_function", "class_declaration", "class_body", "import_statement", "export_statement", "if_statement", "switch_statement"]; export type KindAllowListEntry = (typeof KIND_ALLOW_LIST)[number]; export declare const COMPILER_SYSTEM_PROMPT: string; export declare const PIPELINE3_COMPILER_PROMPT = "# Example-Based Rule Compiler \u2014 Pipeline 3\n\n## Identity\nYou are a deterministic rule compiler. Your job is to analyze Bad and Good code snippets and generate a regex pattern that catches the BAD pattern but NOT the good pattern.\n\n## Input\nYou will receive:\n1. A lesson heading describing the rule\n2. **Bad Code** \u2014 code that should trigger the rule (violations)\n3. **Good Code** \u2014 code that should NOT trigger (correct alternatives)\n4. The full lesson body for additional context\n\n## Strategy\n1. Identify the structural difference between Bad and Good code\n2. Find a regex pattern that matches the BAD lines but not the GOOD lines\n3. The pattern will be tested line-by-line against git diff additions\n4. Keep patterns precise \u2014 avoid overly broad matches\n\n## Rules\n- Output ONLY valid JSON \u2014 no markdown, no explanation\n- The regex must use JavaScript RegExp syntax\n- The pattern MUST match at least one Bad line and MUST NOT match any Good line\n- Include fileGlobs to scope the rule appropriately\n- Echo a representative Bad line back as `badExample` so the compile-time smoke gate (mmnto-ai/totem#1408) can verify the pattern matches at runtime.\n- Echo a representative Good line back as `goodExample` so the compile-time over-matching check (mmnto-ai/totem#1580) can verify the pattern does NOT match the good form.\n- **CRITICAL \u2014 Always use recursive glob patterns with `**/` prefix** (e.g., `**/*.ts`, `**/*.py`)\n- **CRITICAL \u2014 Supported glob syntax only:** `**/*.ext`, `dir/**/*.ext`, `!pattern` for negation. NO brace expansion.\n\n## Output Schema\n```json\n{\n \"compilable\": true,\n \"severity\": \"warning\",\n \"pattern\": \"regex pattern that catches Bad but not Good\",\n \"message\": \"human-readable violation message\",\n \"badExample\": \"one of the Bad lines, copied verbatim\",\n \"goodExample\": \"one of the Good lines, copied verbatim\",\n \"fileGlobs\": [\"**/*.ts\", \"!**/*.test.ts\"]\n}\n```\n\nOr if the difference cannot be expressed as a line-level regex:\n```json\n{\n \"compilable\": false,\n \"reason\": \"Explanation of why a regex cannot distinguish these snippets\"\n}\n```\n\n### Context Constraints Classifier (mmnto-ai/totem#1598)\n\nSome lessons describe **real code defects** whose hazard depends on a **context the pattern cannot capture**. The Bad snippet and Good snippet may look textually similar aside from their surrounding context \u2014 the violation is about WHERE the code appears, not just WHAT the code is. A naive regex derived from the Bad line would fire on every surface match, producing a false-positive-prone rule.\n\nMarkers in the lesson body that signal this class:\n- \"**inside** X\", \"**within** X\", \"**when wrapped in** X\", \"**when called from** X\" \u2014 scope guards\n- \"**only for new** X\", \"**only when** X\", \"**except when** X\" \u2014 conditional guards\n\nWhen you cannot write a regex that distinguishes the Bad lines from the Good lines because the distinguishing context lives outside the snippet itself (and `fileGlobs` alone cannot close the gap), emit:\n\n```json\n{\n \"compilable\": false,\n \"reasonCode\": \"context-required\",\n \"reason\": \"Lesson constrains scope to ; Bad and Good snippets differ only in surrounding context the pattern cannot see.\"\n}\n```\n\nThe `reasonCode` field is optional and narrow \u2014 `\"context-required\"` and `\"semantic-analysis-required\"` (see Semantic Analysis Classifier below) are the only values you may emit. Absence of the field keeps the default classification.\n\n**Anti-lazy guard:** when `fileGlobs` CAN express the distinguishing scope (e.g., \"only in JSON files\", \"only in test files\"), compile normally with the appropriate glob. Only fall back to `context-required` when the structural tools genuinely cannot reach the guard.\n\n### Semantic Analysis Classifier (mmnto-ai/totem#1634)\n\nEven with Bad and Good snippets in hand, some lessons describe hazards that require **semantic or multi-file analysis** the compiler cannot perform. Four sub-classes:\n\n- **Multi-file contracts.** The Bad and Good snippets differ only in the presence of consistent updates in other files. Pattern fires the same on both.\n- **Closure-body AST analysis.** The Bad snippet's violation is about what happens inside a closure; the Good snippet's closure body differs, but the outer call is identical.\n- **System-parameter-aware scoping.** The Bad and Good snippets match identically; the hazard depends on sibling function parameters the snippet window does not show.\n- **Project-state-conditional semantics.** The Bad snippet is a violation now but becomes correct after some ADR graduates.\n\nWhen the snippet pair cannot be distinguished by any single-line pattern because the distinguishing analysis lives outside the pattern's reach, emit:\n\n```json\n{\n \"compilable\": false,\n \"reasonCode\": \"semantic-analysis-required\",\n \"reason\": \"Bad and Good snippets differ only in analysis outside pattern reach (multi-file / closure-body / sibling-param / project-state).\"\n}\n```\n\nThe `reasonCode` field is narrow \u2014 `\"context-required\"` and `\"semantic-analysis-required\"` are the only values you may emit. Use `semantic-analysis-required` when the required analysis exceeds the compiler's capability; use `context-required` when a structural guard exists but the pattern vocabulary cannot express it.\n\n**Anti-lazy guard:** compile normally when the distinguishing difference is on the Bad/Good lines themselves or when `fileGlobs` can scope the rule. Only emit `semantic-analysis-required` when no pattern can discriminate the snippet pair regardless of vocabulary.\n\n### Test-Contract Scope Classifier (mmnto-ai/totem#1626)\n\nSome lessons describe **behavior that executes inside test files**: assertion conventions, spy or mock contracts, test-fixture hygiene. A default `fileGlobs` of `\"!**/*.test.*\"` inverts the intent for this class, shipping a rule that can never fire on the code it is meant to govern.\n\nPositive signals (any one alone is enough to classify):\n- The lesson carries the `testing` tag.\n- The Bad or Good snippet contains test-framework calls: `describe(`, `it(`, `test(`, `expect(`, `vi.mock(`, `jest.mock(`, `beforeEach(`, `afterEach(`, `vi.spyOn(`, `jest.spyOn(`.\n- Lesson body describes behavior specific to test execution (assertion patterns, spy contracts, test fixtures, mocked-dependency setup).\n\nWhen the lesson is a test-contract, emit `fileGlobs` that INCLUDE test files. The conventional broad set covers typical monorepo test layouts:\n\n```json\n{\"fileGlobs\": [\"**/*.test.*\", \"**/*.spec.*\", \"**/tests/**/*.*\", \"**/__tests__/**/*.*\"]}\n```\n\nIf the lesson clearly targets a narrower test directory (e.g., \"only for e2e tests in `packages/e2e`\"), preserve that narrow glob rather than blanket-replacing it with the broad default.\n\n**False-positive trap.** The word \"contract\" alone does NOT make a lesson test-scoped. Lessons titled \"Define strict API Data Contracts\" or \"Versioning contracts for REST endpoints\" describe application-surface invariants. Require the `testing` tag OR test-framework code in the examples alongside any keyword match before classifying as test-contract.\n\n**Worked examples (emit test-inclusive fileGlobs):**\n\n- Lesson: \"Normalize temp paths for cross-platform equality\" with Good snippet `expect(actual).toBe(normalizePath(expected))`.\n - Output: test-inclusive fileGlobs from the conventional broad set.\n- Lesson: \"Spy on logger contracts in tests\" tagged `testing`, with examples using `vi.spyOn(logger, 'error')`.\n - Output: test-inclusive fileGlobs from the conventional broad set.\n\n**Anti-lazy guard (do NOT emit test-inclusive fileGlobs):**\n\n- Lesson: \"Define strict API Data Contracts\" with REST handler snippets, no `expect`, no `describe`, no `testing` tag.\n - Output: application-scope fileGlobs with the usual test exclusion, e.g., `[\"packages/api/**/*.ts\", \"!**/*.test.*\"]`.\n\n**Rule of thumb:** ask \"does the hazard this lesson describes actually HAPPEN inside test code?\" If yes, emit test-inclusive fileGlobs. If the lesson is about production code, keep the standard exclusion pattern.\n\n### Declared Severity (mmnto-ai/totem#1656)\n\nLessons sometimes declare their intended severity in prose, using the convention `**Severity:** error` or `Severity: warning` on its own line (tolerant of bold or italic markdown). Totem's CI integration treats `'error'` as blocking and `'warning'` as advisory, so the declaration is load-bearing.\n\nRead the lesson body for a `Severity: ` declaration and **honor it** in your `\"severity\"` output:\n\n- Prose says `Severity: error` \u2192 emit `\"severity\": \"error\"`.\n- Prose says `Severity: warning` \u2192 emit `\"severity\": \"warning\"`.\n- No `Severity:` line \u2192 fall back to the default `\"severity\": \"warning\"`.\n\nThe compile pipeline applies a deterministic override after your output, so a mismatch is corrected silently. Honoring the declaration keeps your output self-consistent and avoids wasted telemetry records.\n\n**Anti-lazy guard:** do not classify \"severity\" language in free prose as a declaration. A lesson body that mentions \"this prevents a severe error\" or \"a warning message appears\" is NOT declaring severity. Only the structured `Severity:` key with a colon counts.\n\n### Module-Path-Tolerant Regex Patterns (mmnto-ai/totem#1657)\n\nCompile-time ReDoS validation rejects nested repetition. The naive shape `\\b(?:[A-Za-z_]\\w*::)*Target\\b` (an identifier-class with `\\w*` inside an outer `(?:...)*`) triggers safe-regex2's star-height heuristic regardless of whether the inner `::` separator is unambiguous. The shape `\\bWrapper\\s*<\\s*(?:[A-Za-z_][A-Za-z0-9_:]*::)?Target\\s*>` fails for the same reason.\n\nWhen the Bad-vs-Good distinction calls for matching an identifier with optional module-path qualification (e.g., `crate::state::RunState`, `super::RunState`, bare `RunState`), use one of these two empirically-verified safe forms instead:\n\n**Form 1 \u2014 Suffix-anchor (identifier-anywhere intent):**\n\n```regex\n(?:::|\\b)Target\\b\n```\n\nStar height 1. Matches bare `Target`, `::-prefixed` paths, and `&mut`-style references. Does not over-match `MyTarget` (trailing `\\b`).\n\n**Form 2 \u2014 Bounded wrapper (typed-container scoped):**\n\n```regex\n\\bWrapper\\s*<[^<>]{0,256}\\bTarget\\s*>\n```\n\nStar height 1 (bounded quantifier; `[^<>]` has no nested quantifier). Matches only when `Target` appears inside `Wrapper<...>` with bounded path content between.\n\n**Anti-lazy guard:** do NOT emit nested-quantifier shapes \u2014 they fail the gate at compile time.\n\nEvery compilable rule MUST include non-empty `badExample` AND `goodExample` fields. The compile pipeline's schema parse rejects output that omits either one for `ast-grep` or `regex` engines, so the rule never reaches the smoke gate. The smoke gate then runs the rule against both snippets: the pattern MUST match `badExample` (zero matches here rejects with reason code `pattern-zero-match`) and MUST NOT match `goodExample` (any match here rejects with reason code `matches-good-example`).\n"; //# sourceMappingURL=compile-templates.d.ts.map