feat(rules): config + ESLint-style rules engine with check command#42
Open
bntvllnt wants to merge 2 commits into
Open
feat(rules): config + ESLint-style rules engine with check command#42bntvllnt wants to merge 2 commits into
bntvllnt wants to merge 2 commits into
Conversation
Implements specs/backlog/2026-06-02-config-rules-engine.md. - config: discovery (codebase-intelligence.json + variants + package.json key, walk-up) + zod validation + CLI overrides + ConfigError (exit 2) - engine: pluggable Rule contract, severity resolution (off/warn/error|0/1/2), ci-ignore-file / ci-ignore-next-line suppressions, stable fingerprints - rules: no-comments (configurable: keeps JSDoc/directives/header by default, style line|block|all), no-circular-deps, no-dead-exports - formatters: text, json, sarif - CLI 'check' command: exit 0/1/2, --format/--json/--config/--fail-on/--gate/--base - MCP 'check' tool + setRoot/getRoot (read-only, advisory actions only) - silence git stderr leak in getGitChurn/getHeadHash (non-git dirs) - tests: config loader, rules engine (real pipeline), CLI e2e (spawned binary), MCP tool — 38 tests, no internal mocks - docs: mcp-tools (16th tool), architecture + CLAUDE module maps
Blocker: - F1: implement file-level --gate new-only --base (git diff filtering) instead of shipping inert flags Correctness/reliability: - surface rule-throws to stderr (no silent CI false-negative) - confine sourceOf reads to project root via realpath (blocks ../ and symlink-out) - failOn:'never' now disables the maxWarnings gate too - block-comment ci-ignore (/* ci-ignore-file */) suppressions now honored - no-comments allow[] = comment-body prefix match (no 'a' over-matching 'bad') Config: - ConfigError messages use basename (no full-path leak via MCP) - stop config walk-up at repo root (no ambient-config hijack) - distinct read vs parse errors (EACCES != invalid JSON) SARIF/output: - emit shortDescription, partialFingerprints, endLine/endColumn - MCP check uses canonical formatJson; extract shared formatSummaryLine - quiet-first output ordering Types/MCP: - FindingAction.kind union; RuleSetting tuple rejects [off, opts] - register check in codebase://setup; generic tool description; getRoot TSDoc - example config gate: all (safe default) Tests: new-only gate (real git repo), block suppression, allow precision, failOn:never+maxWarnings
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements
specs/backlog/2026-06-02-config-rules-engine.mdend-to-end.What
src/config) — discovery (codebase-intelligence.json+ dotfile variants +package.json#codebaseIntelligence, walk-up), zod validation against the committedschema.json, CLI overrides,ConfigError→ exit 2.src/rules/engine.ts) — pluggableRulecontract, ESLint-style severities (off|warn|erroror0|1|2,[severity, options]),// ci-ignore-file/// ci-ignore-next-line <rules>suppressions, stable fingerprints, deterministic ordering.no-comments(the requested one; configurable — keeps JSDoc, tool/compiler directives, and a file-leading license header by default;style: line|block|all),no-circular-deps,no-dead-exports.text,json,sarif.check— exit codes0clean /1findings ≥ failOn /2config or usage error; flags--format/--json/--config/--fail-on/--gate/--base/--quiet/--summary.checktool — returns{verdict, summary, findings}. Read-only —actions[]are advisory hints, never applied (per roadmap §3).getGitChurn/getHeadHashno longer leak git's stderr on non-git dirs.Tests (38 new, no internal mocks)
config-loader— discovery, package.json key, walk-up, invalid JSON / unknown-key →ConfigError, overrides.rules-engine— real parser→graph→analyzer→engine pipeline: no-comments option matrix, suppressions, circular/dead-export rules, formatters, verdict gating.cli-check.e2e— spawns the real built binary, asserts exit codes + stdout (json, sarif, suppression, config error,--config).mcp-check— real in-memory MCP server + client.Validation
pnpm lintclean ·pnpm typecheckclean ·pnpm buildclean.pnpm vitest run(parallel): 380 passed, 0 errors.src/rules97.5%.Not in scope (follow-ups)
Boundary rules engine, audit
new-onlydiffing, more formatters (codeclimate/pr-comment),init/hooks/watch— speced, not built here.