Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/self-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ jobs:
- uses: actions/checkout@v4
- uses: ./
with:
mode: verify
instruction-file: tests/fixtures/sample-claude.md
output-dir: src
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ coverage/
# Environment variables
.env

# Phase 0 data collection cache and output
.cache/
data/

# Scripts (local utilities, not shipped)
scripts/

Expand All @@ -27,3 +31,6 @@ test-treesitter*.mjs
.github/ruleprobe-e2e-verification-guide.md
docs/ruleprobe-build-guide.md
.ruleprobe-semantic/
.codex
.codex-tmp/
.ruleprobe-semantic/
7 changes: 7 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ scraped-instructions/

# Development files
.vscode/
.claude/
.codex/
.codex
.codex-tmp/
.github/
docs/
SECURITY.md
Expand All @@ -15,6 +19,9 @@ tsconfig.json
.env
.env.*

# RuleProbe semantic cache
.ruleprobe-semantic/

# Git
.git/
.gitignore
129 changes: 129 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# AGENTS.md

Instructions for AI coding agents working on the RuleProbe codebase.

RuleProbe verifies whether agents follow instruction files. This file is the instruction file for agents working on RuleProbe itself. It is parsed by RuleProbe in the self-check workflow, so every rule below is written to be machine-verifiable.

## Project

- Repository: https://github.com/moonrunnerkc/ruleprobe
- Package: https://www.npmjs.com/package/ruleprobe
- Language: TypeScript (strict)
- Runtime: Node.js >= 18
- License: MIT

## Build and Test

- Use `npm` as the package manager. Do not switch to pnpm, yarn, or bun.
- Use `vitest` as the test runner. Do not introduce jest or mocha.
- Run `npm test` before declaring any change complete.
- Run `npm run build` to verify the TypeScript compile is clean.
- A `package-lock.json` must exist at the repo root.
- Pinned dependency versions are required in `package.json` (no `^` or `~` ranges).

## Code Style

- Use TypeScript strict mode. Never disable strict checks.
- Never use `any`. Use `unknown` and narrow, or define a precise type.
- Always use named exports. Never use default exports.
- Use camelCase for variables and functions.
- Use PascalCase for types, interfaces, and classes.
- Use kebab-case for filenames.
- Prefer `const` over `let`.
- Prefer `interface` over `type` for object shapes.
- Prefer `async/await` over `.then()` chains.
- Never use `console.log` in production code. Use the structured logger.
- Never use `eval`.
- No magic numbers without a named constant or inline comment justifying the value.
- No em dashes anywhere in source, comments, docs, or commit messages. Use commas, colons, semicolons, parentheses, or separate sentences.
- Files must stay under 300 lines. If a file approaches the limit, decompose it.
- Add full JSDoc to every exported function, class, and type.
- Avoid nested ternaries. Use early returns to flatten control flow.

## Architecture Boundaries

- Parser code lives under `src/parser/`. Do not call verifier code from the parser.
- Verifier engines live under `src/verifiers/`. Each engine exports a single entrypoint that returns `VerificationResult[]`.
- The semantic tier lives under `src/semantic/`. Source code must never leave the user's machine. Only numeric AST vectors, opaque sub-tree hashes, boolean flags, and rule text may be sent to an LLM.
- The CLI lives under `src/cli/`. Commands compose pipeline functions; they do not contain pipeline logic.
- Shared types live under `src/types/`. Do not duplicate type definitions across modules.

## Verifier Engines

There are eight verifier engines: `ast`, `filesystem`, `regex`, `treesitter`, `preference`, `tooling`, `config-file`, `git-history`. When adding a check, use an existing engine. Adding a new engine requires a written justification in the PR description.

- AST checks must use `ts-morph`. Do not parse TypeScript with regex.
- Tree-sitter WASM loading must fail gracefully. If a grammar fails to load, log a warning and skip the check. Never block other verifiers.
- Type-aware AST checks (implicit any, unused exports, unresolved imports) require a `tsconfig.json` and the `--project` flag. Skip cleanly when absent.
- Semantic tier failures must never prevent deterministic results from returning.

## Parser Rules

- The parser supports 7 instruction file formats: `CLAUDE.md`, `AGENTS.md`, `.cursorrules`, `copilot-instructions.md`, `GEMINI.md`, `.windsurfrules`, `.rules`. Parser changes must not break extraction for any of them.
- Lines that cannot be mapped to a deterministic check go into the `unparseable` array. Do not invent rules to inflate the parse rate.
- LLM-extracted rules must be tagged `extractionMethod: 'llm'` with `confidence: 'medium'`.
- Rubric-decomposed rules must be tagged `confidence: 'low'`.

## Testing

- Every new function requires at least one test.
- Test files live under `tests/` and mirror the `src/` directory structure.
- Test names describe behavior, not implementation.
- Tests must validate real behavior, not wiring. Reading the implementation should not be required to understand what a test verifies.
- No mocks except at external API boundaries (Anthropic API, OpenAI API, GitHub API, filesystem boundaries when testing error paths).
- Use `describe` and `it` blocks. Do not use `test()` directly.
- Never use `console.log` in tests.
- New matchers require: the matcher implementation, a test file with real-world instruction examples, and an entry in `docs/matchers.md`.

## Security

- Never execute scanned code.
- Never modify files in the scanned directory.
- All user-supplied paths must be resolved and bounded to the working directory.
- Symlinks resolving outside the project root must be skipped unless `--allow-symlinks` is passed.
- Never write API keys to disk or include them in reports.
- Network calls are allowed only when the user opts in: `--llm-extract`, `--rubric-decompose`, `--semantic`, or `ruleprobe run`.

## Imports

- No path aliases. Use relative imports.
- No barrel imports from deep internal modules. Import directly from the file that defines the symbol.
- No wildcard imports.
- Do not import lodash. Use native JavaScript methods.

## Error Handling

- Never use empty catch blocks.
- Never swallow errors silently. Log or rethrow.
- Catch clauses must declare the caught type as `unknown` and narrow.
- Error messages must include what failed and what to do about it.

## Git Workflow

- Use conventional commit messages: `feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `chore:`.
- Branch names use kebab-case: `feat/new-matcher`, `fix/parser-bug`.
- Pull requests must pass the self-check workflow before merge.
- Do not commit `.env` files or any file containing secrets.

## Configuration Files

- ESLint config lives at `.eslintrc.json` or `eslint.config.js`.
- Prettier config lives at `.prettierrc` or `.prettierrc.json`.
- TypeScript config lives at `tsconfig.json`.
- Vitest config lives at `vitest.config.ts`.
- Do not add competing tools (Biome alongside ESLint, Rome, etc.).

## Documentation

- Update `docs/matchers.md` when adding or modifying a matcher.
- Update `docs/cli-reference.md` when adding or changing a CLI command or flag.
- Update `docs/api-reference.md` when changing the public API surface.
- Update the relevant release notes file under `docs/` for any user-facing change.

## What Not To Do

- Do not introduce a new agent SDK adapter without a corresponding integration test.
- Do not weaken the security boundary to make a check easier to implement.
- Do not push deterministic logic into the semantic tier because it is easier to write.
- Do not add features that require API keys for the default deterministic path.
- Do not add dependencies without a clear justification. Each dependency is a maintenance cost.
43 changes: 43 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,49 @@

All notable changes to this project will be documented in this file.

## [4.5.0] - 2026-05-08

### Breaking Changes

- **Default action mode changed.** The primary workflow is now `lint-config`, `drift`, and `extract`, not `verify`. The GitHub Action defaults to drift detection mode.
- **`compare` command removed.** Agent comparison is no longer a primary use case. Use drift detection instead.
- **`tasks` and `task` commands removed.** Task template listing and printing removed.
- **`run` command removed.** Agent invocation via the Claude Agent SDK removed. The `@anthropic-ai/claude-agent-sdk` is no longer a dependency.
- **Runner module removed from public API.** `buildAgentConfig`, `invokeAgent`, `isAgentSdkAvailable`, `hasAgentOutput`, `watchForCompletion`, `countCodeFiles`, `AgentInvocationConfig`, `RunOptions`, `InvocationResult`, `WatchOptions`, `WatchResult` are no longer exported.
- **`formatComparisonMarkdown` removed.** The comparison report formatter is no longer exported from `reporter/index`.
- **`verify` command deprecated.** Still works, but the primary workflow is now translate, detect drift, and extract.
- **67 unmappable matchers removed.** Categories removed: `test-requirement`, `dependency`, `preference`, `file-structure`, `tooling`, `testing`, `workflow`. Verifier types removed: `treesitter`, `preference`, `tooling`, `config-file`, `git-history`. The remaining 34 matchers all map to ESLint rules.
- **`RuleCategory` union narrowed.** Removed: `test-requirement`, `dependency`, `preference`, `file-structure`, `tooling`, `testing`, `workflow`. Remaining: `naming`, `forbidden-pattern`, `structure`, `import-pattern`, `error-handling`, `type-safety`, `code-style`, `agent-behavior`.
- **`VerifierType` union narrowed.** Removed: `treesitter`, `preference`, `tooling`, `config-file`, `git-history`. Remaining: `ast`, `regex`, `filesystem`.

### New Features

- **`lint-config` command.** Translates an instruction file into a flat or legacy ESLint config. Unmappable rules appear as comments in the output.
- **`drift` command.** Compares an instruction file against an existing ESLint config. Reports rules present in one but missing from the other, severity mismatches, and config argument differences.
- **`extract` command.** Parses an ESLint config and emits a markdown rules section suitable for pasting into an instruction file.

### Removed

- `compare` command and `formatComparisonMarkdown` export.
- `tasks` and `task` commands and `src/runner/task-templates/` directory.
- `run` command and `src/runner/agent-configs.ts`, `src/runner/agent-invoker.ts`, `src/runner/watch-mode.ts`.
- Matcher files: `rule-patterns-preference.ts`, `rule-patterns-file-structure.ts`, `rule-patterns-tooling.ts`, `rule-patterns-testing.ts`, `rule-patterns-config-file.ts`, `rule-patterns-git-history.ts`.
- Individual unmappable matchers from remaining files: `test-files-exist`, `test-named-pattern`, `structure-strict-mode`, `error-async-try-catch`, `structure-typescript-required`, `error-log-contextual`, `import-no-unresolved`, `naming-python-snake-case`, `naming-python-class`, `naming-go-conventions`, `style-python-function-length`, `style-go-function-length`, `style-concise-conditionals`, `naming-kebab-case-directories`, `structure-no-barrel-files`, `test-no-settimeout`, `test-no-only`, `test-no-skip`, `import-banned-package`, `structure-readme-exists`, `structure-changelog-exists`, `structure-formatter-config`, `dependency-pinned-versions`.

### Stats

| Metric | v4.0.0 | v4.5.0 |
|--------|--------|--------|
| Rule matchers | ~103 | 34 |
| Rule categories | 14 | 7 (+ `agent-behavior`) |
| Verifier engines | 8 | 3 |
| CLI commands | 9 | 6 |
| Public API exports | ~40 | ~25 |

## [4.0.0] - 2026-04-28

Major release consolidating the three-repo architecture. See [docs/release-v4.0.0.md](docs/release-v4.0.0.md) for full details.

## [1.0.0] - 2026-04-07

14 commits, 100 files changed, +9,017 lines since v0.1.0.
Expand Down
103 changes: 103 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# CLAUDE.md

Instructions for Claude (Claude Code, Claude SDK, claude.ai) when working on the RuleProbe codebase.

The full engineering rules live in [AGENTS.md](./AGENTS.md). Read that file first. Everything below is Claude-specific workflow guidance that supplements it. When the two conflict, AGENTS.md wins.

## Project

- Repository: https://github.com/moonrunnerkc/ruleprobe
- Package: https://www.npmjs.com/package/ruleprobe
- Language: TypeScript (strict)
- Runtime: Node.js >= 18

## Working Style

- Make targeted edits over full rewrites when a specific issue is flagged.
- Never pad documentation, README, or release notes with marginal results. Only genuinely interesting findings belong.
- Run verification before treating any feature as done: `npm test` and `npm run build`.
- Push back when a claim is not backed by real data. Do not invent metrics, repo counts, or compliance scores.
- Use `git status` and `git diff` to confirm what you actually changed before reporting completion.

## Engineering Standards

These are enforced by the self-check workflow (RuleProbe verifies its own codebase). Following them keeps the build green.

- Always use TypeScript strict mode.
- Never use `any`. Use `unknown` and narrow.
- Always use named exports. Never use default exports.
- Use kebab-case for filenames.
- Use camelCase for variables and functions.
- Use PascalCase for types, interfaces, and classes.
- Prefer `const` over `let`.
- Prefer `interface` over `type` for object shapes.
- Files must stay under 300 lines.
- Add full JSDoc to every exported symbol.
- Never use em dashes anywhere.
- No magic numbers without a named constant.

## Tooling

- Use `npm` as the package manager.
- Use `vitest` as the test runner.
- Use `eslint` for linting and `prettier` for formatting.
- Do not introduce competing tools (no biome, no jest, no pnpm).

## Pipeline Boundaries

When editing pipeline code, respect the three-stage boundary: parse, verify, report. Each stage is independently testable and lives under its own directory in `src/`.

- Parser code lives under `src/parser/`. The parser must not call verifier code.
- Verifier engines live under `src/verifiers/`. Each engine returns `VerificationResult[]`.
- Report generation lives under `src/report/`. Reports must not run verifications.
- The semantic tier under `src/semantic/` must never send source code, file paths, variable names, or comments to any LLM.

## Tree-sitter and Type-aware Checks

- Tree-sitter WASM grammars must fail gracefully. If a grammar fails to load, log a warning and continue. Never block other verifiers.
- Type-aware AST checks require `--project` and a valid `tsconfig.json`. Skip cleanly when absent.
- Semantic tier failures must never prevent deterministic results from returning.

## Testing

- Every new function requires at least one test.
- Test files live under `tests/` and mirror the `src/` structure.
- Tests must validate real behavior, not wiring.
- No mocks except at external API boundaries.
- Use `describe` and `it` blocks.
- Never use `console.log` in tests.
- New matchers require a test file with real-world instruction examples.

## Security

- Never execute scanned code.
- Never modify files in the scanned directory.
- Bound all paths to the working directory.
- Skip symlinks resolving outside the project root unless `--allow-symlinks` is passed.
- Never write API keys to disk.

## Claude Code Workflow

- When invoked through Claude Code, prefer running tests and builds in the integrated terminal so output is captured in the session.
- For multi-file changes, list the files you intend to touch before editing.
- For changes that affect the parser, run `ruleprobe parse` against `tests/fixtures/` instruction files to confirm no regression in extraction.
- For changes that affect a verifier, run `npm test -- <verifier-name>` before running the full suite.
- For changes that touch the semantic tier, manually verify that no source code, file paths, variable names, or comments appear in any outbound payload.

## Commit Messages

Use conventional commit format: `feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `chore:`.

Examples:
- `feat: add tree-sitter naming check for Rust`
- `fix: parser drops rules with backtick-wrapped patterns`
- `docs: update matchers.md with new file-structure entries`

## What Not To Do

- Do not refactor code outside the scope of the requested change.
- Do not weaken the security boundary to simplify an implementation.
- Do not push deterministic logic into the semantic tier.
- Do not add dependencies without justification.
- Do not write release notes that make claims unsupported by the actual diff.
- Do not present completion as fact without running tests and build.
Loading
Loading