{"id":48536185,"url":"https://github.com/moonrunnerkc/ruleprobe","last_synced_at":"2026-04-08T02:01:33.970Z","repository":{"id":349633890,"uuid":"1203066133","full_name":"moonrunnerkc/ruleprobe","owner":"moonrunnerkc","description":"Verify whether AI coding agents follow the instruction files they're given","archived":false,"fork":false,"pushed_at":"2026-04-06T22:02:53.000Z","size":107,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-06T22:23:43.092Z","etag":null,"topics":["agents-md","ai","ast","benchmark","claude-md","cli","coding-agent","cursorrules","developer-tools","instruction-adherence","typescript","verification"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/moonrunnerkc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-06T17:28:43.000Z","updated_at":"2026-04-06T22:02:57.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/moonrunnerkc/ruleprobe","commit_stats":null,"previous_names":["moonrunnerkc/ruleprobe"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/moonrunnerkc/ruleprobe","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moonrunnerkc%2Fruleprobe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moonrunnerkc%2Fruleprobe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moonrunnerkc%2Fruleprobe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moonrunnerkc%2Fruleprobe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/moonrunnerkc","download_url":"https://codeload.github.com/moonrunnerkc/ruleprobe/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moonrunnerkc%2Fruleprobe/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31536473,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T16:28:08.000Z","status":"online","status_checked_at":"2026-04-08T02:00:06.127Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agents-md","ai","ast","benchmark","claude-md","cli","coding-agent","cursorrules","developer-tools","instruction-adherence","typescript","verification"],"created_at":"2026-04-08T02:01:33.165Z","updated_at":"2026-04-08T02:01:33.960Z","avatar_url":"https://github.com/moonrunnerkc.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ch1 align=\"center\"\u003eRuleProbe\u003c/h1\u003e\n  \u003cp align=\"center\"\u003e\n    Verify whether AI coding agents actually follow the instruction files they're given.\n  \u003c/p\u003e\n  \u003cp align=\"center\"\u003e\n    \u003ca href=\"https://www.npmjs.com/package/ruleprobe\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/ruleprobe?style=flat-square\" alt=\"npm version\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/moonrunnerkc/ruleprobe/actions/workflows/self-check.yml\"\u003e\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/moonrunnerkc/ruleprobe/self-check.yml?style=flat-square\u0026label=build\" alt=\"build status\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/moonrunnerkc/ruleprobe/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/moonrunnerkc/ruleprobe?style=flat-square\" alt=\"license\"\u003e\u003c/a\u003e\n    \u003cimg src=\"https://img.shields.io/badge/language-TypeScript-3178c6?style=flat-square\" alt=\"TypeScript\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/node-%3E%3D18-339933?style=flat-square\" alt=\"Node.js \u003e= 18\"\u003e\n    \u003ca href=\"https://github.com/moonrunnerkc/ruleprobe/stargazers\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/moonrunnerkc/ruleprobe?style=flat-square\" alt=\"GitHub stars\"\u003e\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/p\u003e\n\n## Why\n\nEvery AI coding agent reads an instruction file. None of them prove they followed it.\n\nYou write `CLAUDE.md` or `AGENTS.md` with specific rules: camelCase variables, no `any` types, named exports only, test files for every source file. The agent says \"Done.\" But did it actually follow them? Your code review catches some violations, misses others, and doesn't scale.\n\nRuleProbe reads the same instruction file, extracts the machine-verifiable rules, and checks agent output against each one. Binary pass/fail, with file paths and line numbers as evidence. No LLM evaluation, no judgment calls. Deterministic and reproducible.\n\n## Quick Start\n\n```bash\nnpm install -g ruleprobe\n```\n\nOr run it directly:\n\n```bash\nnpx ruleprobe --help\n```\n\n\u003e **Note:** The examples below reflect the current development HEAD (53 matchers, 9 categories). The published npm v0.1.0 shipped with 15 matchers. A new release will follow.\n\n**Parse an instruction file** to see what rules RuleProbe can extract. This is real output from parsing the repo's included example instruction file:\n\n```bash\nruleprobe parse docs/example-instructions.md\n```\n\n```\nExtracted 32 rules:\n\n  forbidden-no-any-type-2\n    Category: forbidden-pattern\n    Verifier: ast\n    Pattern:  no-any (*.ts)\n    Source:    \"- No any types anywhere in the codebase\"\n\n  error-no-empty-catch-6\n    Category: error-handling\n    Verifier: ast\n    Pattern:  no-empty-catch (*.ts)\n    Source:    \"- No empty catch blocks; always handle or rethrow errors\"\n\n  naming-kebab-case-files-17\n    Category: naming\n    Verifier: filesystem\n    Pattern:  kebab-case (filenames)\n    Source:    \"- File names: kebab-case (e.g., user-service.ts, api-handler.ts)\"\n\n  dependency-pinned-versions-34\n    Category: dependency\n    Verifier: filesystem\n    Pattern:  pinned-dependencies (package.json)\n    Source:    \"- All dependencies pinned to exact versions, no ^ or ~ ranges\"\n  ...\n```\n\n**Verify agent output** against those rules. This is ruleprobe verifying its own source code:\n\n```bash\nruleprobe verify docs/example-instructions.md ./src --format text\n```\n\n```\nRuleProbe Adherence Report\nAgent: unknown | Model: unknown | Task: manual\n\nRules: 32 total | 23 passed | 9 failed | Score: 72%\n\nFAIL  error-handling/error-no-empty-catch-6\n      commands/run.ts:148 - found: empty catch block\n      utils/safe-path.ts:116 - found: empty catch block\n      verifier/ast-verifier.ts:248 - found: empty catch block\nPASS  forbidden-pattern/forbidden-no-any-type-2\nPASS  structure/structure-strict-mode-1\nPASS  structure/structure-named-exports-only-3\nPASS  naming/naming-kebab-case-files-17\nFAIL  naming/naming-camelcase-variables-18\n      verifier/treesitter-loader.ts:75 - found: ParserCtor\n      verifier/treesitter-loader.ts:76 - found: LanguageRef\nPASS  naming/naming-pascalcase-types-20\nPASS  test-requirement/test-files-exist-25\nFAIL  structure/structure-no-barrel-files-24\n      ast-checks/index.ts:5 - found: barrel file with 24 re-exports\n      llm/index.ts:7 - found: barrel file with 9 re-exports\nPASS  import-pattern/import-no-path-aliases-28\nPASS  forbidden-pattern/forbidden-no-console-log-4\nPASS  structure/structure-max-file-length-22\nPASS  structure/structure-jsdoc-required-21\nPASS  dependency/dependency-pinned-versions-34\n...\n\nBy Category:\n  naming:             2/4 (50%)\n  forbidden-pattern:  4/4 (100%)\n  structure:          4/5 (80%)\n  import-pattern:     4/4 (100%)\n  test-requirement:   2/2 (100%)\n  error-handling:     1/2 (50%)\n  type-safety:        2/4 (50%)\n  code-style:         2/5 (40%)\n  dependency:         2/2 (100%)\n```\n\nEvery failure includes the file, line number, and what was found. No ambiguity.\n\n## What It Does\n\n**Parse.** Reads 6 instruction file formats (CLAUDE.md, AGENTS.md, .cursorrules, copilot-instructions.md, GEMINI.md, .windsurfrules) and extracts rules that can be checked mechanically. Subjective instructions like \"write clean code\" are reported as unparseable so you know what was skipped.\n\n**Verify.** Runs each extracted rule against a directory of agent-generated code. Checks use AST parsing via ts-morph, file system inspection, and regex pattern matching. No LLM evaluation at any stage by default; results are deterministic and identical across runs.\n\n**LLM Extract (opt-in).** Pass `--llm-extract` to send unparseable lines through an OpenAI-compatible API for a second extraction pass. LLM-extracted rules are labeled with `extractionMethod: 'llm'` and `confidence: 'medium'`, and default to warning severity. Requires `OPENAI_API_KEY` env var. No LLM dependency is installed by default.\n\n**Compare.** Point RuleProbe at outputs from two or more agents and get a side-by-side comparison table showing which rules each one followed. Useful for evaluating agents on the same task, or tracking adherence over time.\n\n**GitHub Action.** Ships as a composite action you can drop into any repo. Runs `ruleprobe verify` on every PR, posts results as a comment, and optionally outputs reviewdog rdjson format for inline annotations. No API keys needed beyond `GITHUB_TOKEN`.\n\n## Configuration\n\nRuleProbe auto-discovers a config file in the working directory (or any parent). You can also pass `--config \u003cpath\u003e` explicitly. Supported file names, in priority order:\n\n- `ruleprobe.config.ts`\n- `ruleprobe.config.js`\n- `ruleprobe.config.json`\n- `.ruleproberc.json`\n\nA config file lets you add custom rules, override extracted rules, or exclude rules entirely:\n\n```typescript\n// ruleprobe.config.ts\nimport { defineConfig } from 'ruleprobe';\n\nexport default defineConfig({\n  // Add rules that the parser can't extract from your instruction file\n  rules: [\n    {\n      id: 'custom-no-lodash',\n      category: 'import-pattern',\n      description: 'Ban lodash imports',\n      verifier: 'regex',\n      pattern: { type: 'banned-import', target: '*.ts', expected: 'lodash', scope: 'file' },\n    },\n  ],\n\n  // Change severity or expected values on extracted rules\n  overrides: [\n    { ruleId: 'naming-camelcase', severity: 'warning' },\n    { ruleId: 'structure-max-file-length', expected: '500' },\n  ],\n\n  // Remove rules you don't want checked\n  exclude: ['forbidden-no-console-log'],\n});\n```\n\n`defineConfig()` is a no-op passthrough that provides type checking in TypeScript configs. JSON configs work without it.\n\nCustom rules use the same verifier types (`ast`, `regex`, `filesystem`) and pattern types as extracted rules. Any pattern type listed in the Supported Rule Types table works as a custom rule pattern.\n\n## CLI Reference\n\n### `ruleprobe parse \u003cinstruction-file\u003e`\n\nExtract rules from an instruction file.\n\n```bash\nruleprobe parse CLAUDE.md --format json\nruleprobe parse AGENTS.md --show-unparseable\nruleprobe parse AGENTS.md --llm-extract --show-unparseable\n```\n\n`--format json|text` controls output format. `--show-unparseable` includes lines that couldn't be converted to rules. `--llm-extract` sends unparseable lines to an OpenAI-compatible API for additional extraction (requires `OPENAI_API_KEY`).\n\n### `ruleprobe verify \u003cinstruction-file\u003e \u003coutput-dir\u003e`\n\nCheck agent output against extracted rules.\n\n```bash\nruleprobe verify CLAUDE.md ./output --format text\nruleprobe verify AGENTS.md ./output --agent claude --model opus-4 --format json --output report.json\nruleprobe verify AGENTS.md ./output --format markdown --severity error\nruleprobe verify AGENTS.md ./output --format rdjson\nruleprobe verify AGENTS.md ./output --config ruleprobe.config.ts\nruleprobe verify AGENTS.md ./output --llm-extract\nruleprobe verify AGENTS.md ./output --rubric-decompose\nruleprobe verify AGENTS.md ./output --project tsconfig.json\n```\n\n`--agent` and `--model` tag the report metadata. `--severity error|warning|all` filters results. `--output` writes to a file instead of stdout. `--format rdjson` produces reviewdog-compatible diagnostics. `--config` loads a specific config file (otherwise auto-discovered). `--llm-extract` runs unparseable lines through an LLM for additional rule extraction. `--rubric-decompose` uses an LLM to break subjective instructions into weighted concrete checks (tagged with `extractionMethod: 'rubric'` and `confidence: 'low'`). Both `--llm-extract` and `--rubric-decompose` require `OPENAI_API_KEY`. `--project` enables type-aware AST checks (implicit any, unused exports, unresolved imports) using the specified tsconfig.json.\n\nExit codes: `0` all rules passed, `1` violations found, `2` execution error.\n\n### `ruleprobe compare \u003cinstruction-file\u003e \u003cdirs...\u003e`\n\nCompare multiple agent outputs against the same rules.\n\n```bash\nruleprobe compare AGENTS.md ./claude-output ./copilot-output --agents claude,copilot --format markdown\n```\n\n### `ruleprobe tasks` / `ruleprobe task \u003cid\u003e`\n\nList available task templates or output a specific task prompt. Three templates ship with v0.1.0: `rest-endpoint`, `utility-module`, `react-component`.\n\n```bash\nruleprobe tasks\nruleprobe task rest-endpoint\n```\n\n### `ruleprobe run \u003cinstruction-file\u003e`\n\nInvoke an AI agent on a task template, verify the output, and print the report in one step. Requires `@anthropic-ai/claude-agent-sdk` and `ANTHROPIC_API_KEY` for SDK mode. Alternatively, use `--watch` to point at a directory where you (or another agent) will write output manually.\n\n```bash\n# SDK mode: invoke Claude, verify, report\nruleprobe run CLAUDE.md --task rest-endpoint --agent claude-code --model sonnet --format text\n\n# Watch mode: wait for output in a directory, then verify\nruleprobe run CLAUDE.md --watch ./agent-output --timeout 300 --format json\n```\n\nOptions: `--task`, `--agent`, `--model`, `--format`, `--output-dir`, `--watch`, `--timeout`, `--allow-symlinks`, `--config`.\n\n## GitHub Action\n\nDrop this into `.github/workflows/ruleprobe.yml`:\n\n```yaml\nname: RuleProbe\non: [pull_request]\njobs:\n  check-rules:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      pull-requests: write\n    steps:\n      - uses: actions/checkout@v4\n      - uses: moonrunnerkc/ruleprobe@v1\n        with:\n          instruction-file: AGENTS.md\n          output-dir: src\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n```\n\nThat's it. No API keys, no LLM calls, deterministic results, runs in seconds.\n\n\u003e **Note:** `@v1` tracks the latest v1.x release. Pin to a specific tag (e.g., `@v1.0.0`) for reproducible builds.\n\n\u003cdetails\u003e\n\u003csummary\u003eFull options\u003c/summary\u003e\n\n```yaml\n- uses: moonrunnerkc/ruleprobe@v1\n  with:\n    instruction-file: AGENTS.md\n    output-dir: src\n    agent: ci\n    model: unknown\n    format: text\n    severity: all\n    fail-on-violation: \"true\"\n    post-comment: \"true\"\n    reviewdog-format: \"false\"\n```\n\n| Input | Default | Description |\n|-------|---------|-------------|\n| `instruction-file` | (required) | Path to instruction file |\n| `output-dir` | `src` | Directory containing code to verify |\n| `agent` | `ci` | Agent identifier for report metadata |\n| `model` | `unknown` | Model identifier for report metadata |\n| `format` | `text` | Report format: text, json, or markdown |\n| `severity` | `all` | Filter: error, warning, or all |\n| `fail-on-violation` | `true` | Fail the check on any violation |\n| `post-comment` | `true` | Post results as a PR comment |\n| `reviewdog-format` | `false` | Also output rdjson for reviewdog |\n\nOutputs: `score`, `passed`, `failed`, `total` (available to downstream steps).\n\n\u003c/details\u003e\n\n## Programmatic API\n\nFive functions cover the full pipeline:\n\n| Function | Purpose |\n|----------|---------|\n| `parseInstructionFile(path)` | Parse an instruction file into a `RuleSet` |\n| `verifyOutput(ruleSet, dir)` | Run rules against a code directory |\n| `generateReport(run, ruleSet, results)` | Build an `AdherenceReport` with summary stats |\n| `formatReport(report, format)` | Render as text, JSON, markdown, or rdjson |\n| `extractRules(markdown, fileType)` | Extract rules from raw markdown content |\n| `defineConfig(config)` | Type-safe config helper for ruleprobe.config.ts |\n| `loadConfig(path?, searchDir?)` | Load and validate a config file |\n| `applyConfig(ruleSet, config)` | Merge custom rules, overrides, and exclusions into a RuleSet |\n| `extractWithLlm(ruleSet, options)` | Run LLM extraction on unparseable lines |\n| `createOpenAiProvider(config?)` | Create an OpenAI-compatible LLM provider |\n\n```typescript\nimport { parseInstructionFile, verifyOutput, generateReport, formatReport } from 'ruleprobe';\n\nconst ruleSet = parseInstructionFile('CLAUDE.md');\nconst results = verifyOutput(ruleSet, './agent-output');\nconst report = generateReport(\n  { agent: 'claude-code', model: 'opus-4', taskTemplateId: 'rest-endpoint',\n    outputDir: './agent-output', timestamp: new Date().toISOString(), durationSeconds: null },\n  ruleSet,\n  results,\n);\nconsole.log(formatReport(report, 'text'));\n```\n\n**LLM-assisted extraction** (opt-in):\n\n```typescript\nimport { parseInstructionFile, extractWithLlm, createOpenAiProvider } from 'ruleprobe';\n\nconst ruleSet = parseInstructionFile('CLAUDE.md');\nconst provider = createOpenAiProvider({ model: 'gpt-4o-mini' });\nconst enhanced = await extractWithLlm(ruleSet, { provider });\n// enhanced.rules now includes LLM-extracted rules with extractionMethod: 'llm'\n```\n\n## How It Works\n\n```mermaid\nflowchart LR\n    A[Instruction File] --\u003e B[Rule Parser]\n    B --\u003e C[RuleSet]\n    D[Agent Output] --\u003e E[Verifier]\n    C --\u003e E\n    E --\u003e F[Adherence Report]\n```\n\nThe parser reads your instruction file and identifies lines that map to deterministic checks (naming conventions, forbidden patterns, structural requirements). Each rule gets a category, a verifier type, and a pattern. The verifier walks the agent's output directory, runs AST checks via ts-morph for code structure rules, file system checks for naming and test file requirements, and regex checks for line length and content patterns. The report collects pass/fail results with evidence for every rule.\n\n## Supported Rule Types\n\n53 built-in matchers across 9 categories:\n\n| Category | Count | Verifier(s) |\n|----------|------:|-------------|\n| naming | 7 | AST, Filesystem, Tree-sitter |\n| forbidden-pattern | 5 | AST, Regex |\n| structure | 9 | AST, Filesystem |\n| test-requirement | 5 | AST, Filesystem, Regex |\n| import-pattern | 6 | AST, Regex |\n| error-handling | 2 | AST |\n| type-safety | 5 | AST, Regex |\n| code-style | 10 | AST, Regex, Tree-sitter |\n| dependency | 1 | Filesystem |\n\nFull table with example instructions and check details: [docs/matchers.md](docs/matchers.md)\n\n## Authentication\n\nMost of RuleProbe works offline with no API keys. Two opt-in features use external APIs:\n\n| Feature | Flag(s) | Required env var | When you need it |\n|---------|---------|-----------------|------------------|\n| LLM rule extraction | `--llm-extract` | `OPENAI_API_KEY` | Extracting rules from unparseable instruction lines |\n| Rubric decomposition | `--rubric-decompose` | `OPENAI_API_KEY` | Breaking subjective rules into concrete checks |\n| Agent invocation (SDK mode) | `ruleprobe run --agent claude-code` | `ANTHROPIC_API_KEY` | Invoking Claude to generate code, then verifying |\n| GitHub Action | `uses: moonrunnerkc/ruleprobe@v1` | `GITHUB_TOKEN` | CI, PR comments |\n\n`parse`, `verify`, `compare`, `tasks`, and `task` work entirely offline. No key needed.\n\n## Tree-sitter Support\n\nPython and Go get naming and function-length checks via tree-sitter WASM grammars. The grammar packages (`tree-sitter-python`, `tree-sitter-go`, `web-tree-sitter`) ship as regular dependencies; no extra install step is required. WASM binaries are loaded at runtime from the installed packages. If loading fails (unsupported platform, missing native build), tree-sitter checks are skipped and other verifiers still run.\n\n## Security\n\nRuleProbe never executes scanned code, never makes network calls (unless you opt in with `--llm-extract`, `--rubric-decompose`, or `ruleprobe run`), and never modifies files in the scanned directory. User-supplied paths are resolved and bounded to the working directory; symlinks outside the project are skipped unless you pass `--allow-symlinks`. All dependencies are pinned to exact versions. See [SECURITY.md](SECURITY.md) for the full model.\n\n## Limitations\n\nWhat v0.1.0 doesn't do, stated plainly.\n\n- **TypeScript gets the deepest coverage.** ts-morph gives full AST analysis for TypeScript and JavaScript: naming, forbidden patterns, structure, imports, type-safety, and code-style checks. Python and Go get naming and function-length checks via tree-sitter WASM grammars (grammar packages ship as regular dependencies; see the Tree-sitter Support section). Everything else falls back to regex (line length, comments, semicolons). No Rust, Java, or C# AST support yet.\n- **Subjective rules stay subjective.** \"Write clean code\" has no deterministic check. The `--rubric-decompose` flag on the `verify` command uses an LLM to break subjective instructions into weighted concrete checks (max function length, no magic numbers, etc.), tagged with `extractionMethod: 'rubric'` and `confidence: 'low'`. This is a proxy, not a direct evaluation. Lines with no measurable proxy stay in the unparseable array. Requires `OPENAI_API_KEY`.\n- **Agent invocation covers Claude SDK and watch mode only.** The `run` command invokes agents via the Claude Agent SDK (requires `ANTHROPIC_API_KEY`) or watches a directory for output. Copilot, Cursor, and other agent SDKs are not integrated; use `--watch` mode for those.\n- **Type-aware checks require --project.** Three checks (implicit any, unused exports, unresolved imports) need the TypeChecker, which requires a `tsconfig.json`. Without `--project`, ts-morph parses files in isolation and these checks are skipped.\n- **53 matchers, not infinite.** The parser skips lines it can't confidently map to a check. Use `--show-unparseable` to see what was missed, and `--llm-extract` or `--rubric-decompose` to handle the remainder.\n\n## Case Study\n\nSee [docs/case-study-v0.1.0.md](docs/case-study-v0.1.0.md) for a comparison of two agents on the rest-endpoint task template against 10 rules.\n\n## Contributing\n\n```bash\ngit clone https://github.com/moonrunnerkc/ruleprobe.git\ncd ruleprobe \u0026\u0026 npm install\nnpm test\n```\n\nIssues and pull requests welcome at [github.com/moonrunnerkc/ruleprobe](https://github.com/moonrunnerkc/ruleprobe).\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoonrunnerkc%2Fruleprobe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoonrunnerkc%2Fruleprobe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoonrunnerkc%2Fruleprobe/lists"}