Skip to content

feat: @casa/agent-rules — Markdown rules applied to diffs by a local agent#1

Merged
browep merged 11 commits into
mainfrom
feat/agent-rules-package
Jun 29, 2026
Merged

feat: @casa/agent-rules — Markdown rules applied to diffs by a local agent#1
browep merged 11 commits into
mainfrom
feat/agent-rules-package

Conversation

@finneyai-app

@finneyai-app finneyai-app Bot commented Jun 26, 2026

Copy link
Copy Markdown

Summary

Introduces @casa/agent-rules, a TypeScript package (library + CLI) that applies Markdown-defined coding rules to a git diff using a local agent CLI (claude/codex). Rules are .md/.mdc files with YAML front-matter and globs; the tool discovers the rules applicable to a diff, asks the agent to check each against its scoped changes, and returns line-anchored findings.

It's designed to complement linters, not duplicate them — it targets properties of the change a linter structurally can't see. The clearest example (and the bundled sample rules): the removal of a guard or error handler. Deleted code isn't in the tree, so only the diff reveals it.

What's included

  • Library (pure ESM, Node ≥22): rule discovery/parsing, glob matcher with multi-**, diff utilities (getDiff incl. untracked, scoping, line map), prompt builder, Zod-validated findings, filtering pipeline, and runReview (bounded concurrency, per-rule failure isolation; resilience is the adapter's responsibility).
  • CLI agent-rules: exec-only transport delegating to a local agent — resolution order --exec → launching agent ($CLAUDE_CODE_EXECPATH) → PATH → fail; --transport claude|codex to pin; text/JSON output; exit codes 0/1/2; recursion guard.
  • Sample removal rules (no-removed-auth-checks, no-removed-error-handling) + a Docker image (claude + codex installed) with a demo.
  • Tests: 36 unit tests, hermetic CLI smoke (scripts/smoke.sh), packaged-install smoke (scripts/pack-smoke.sh).
  • CI (lint, typecheck, test, build, smoke, pack-smoke) and publish.yml that publishes @casa/agent-rules on merge to main, guarded to skip versions already on npm.
  • Docs: docs/agent-rules-requirements.md and docs/issue-tracker.md.

Verification

  • yarn lint, yarn typecheck, yarn test (36), yarn smoke (5/5), yarn pack:smoke (4/4) — all green.
  • A real end-to-end review was run inside Docker via codex: it correctly flagged a guard removal as blocking. The claude profile (flags + JSON-envelope parsing, including is_error) was also verified.

Follow-ups (not blocking)

  • Add the NPM_TOKEN repo secret so publish.yml can publish (automation token for the casa npm org).
  • Richer adapter examples (AR-43).

🤖 Generated with Claude Code

browep added 8 commits June 26, 2026 14:45
Core library (pure ESM, Node >=22):
- rule discovery/parsing (.md/.mdc front-matter, inline + YAML-list globs)
- recursive glob matcher with full multi-** support
- diff utilities (getDiff incl. untracked, scoping, line map)
- prompt builder, Zod-validated finding parser
- filtering pipeline (dedup, diff-line, priority + test discount)
- runReview orchestrator with bounded concurrency and per-rule failure isolation

CLI (agent-rules): exec-only transport delegating to a local agent
(claude/codex), resolution order --exec -> launching agent -> PATH -> fail,
text/JSON output, exit codes 0/1/2.

36 unit tests; typecheck and build green. Managed with yarn.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Verification against real agent CLIs surfaced two fixes:
- claude profile: parse the --output-format json envelope and surface
  is_error/result (e.g. "Not logged in") instead of an opaque non-zero exit
- codex profile: add --skip-git-repo-check so `codex exec` runs headlessly
  outside a trusted dir

Confirmed end-to-end: codex produced a correctly-structured blocking finding.

Adds:
- scripts/smoke.sh: hermetic end-to-end CLI test via a fake transport (CI-safe)
- scripts/verify-transport.sh: live check against a real claude/codex (manual)
- yarn smoke / yarn verify:transport scripts
- README transport notes + development section

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- ESLint (flat config) + Prettier; yarn lint / format / format:check
- attach `cause` to errors rethrown from git() (preserve-caught-error)
- GitHub Actions CI: lint, typecheck, test, build, smoke on Node 22
- MIT LICENSE and Keep-a-Changelog CHANGELOG (0.1.0)
- apply Prettier formatting across the codebase

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move the requirements spec and issue tracker out of the gitignored docs-tmp/
working area into a version-controlled docs/ directory so the tracker is
committed and maintained alongside the code.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Dockerfile (node:22) with claude + codex installed and the package built
- docker/entrypoint.sh: smoke (default) / verify / demo / cli dispatch
- scripts/demo.sh: review a bundled sample diff against examples/rules
- examples/rules: sample no-console-log and no-magic-numbers rules
- docker/README.md: build + run recipes; credentials passed at run time only
- new --transport claude|codex flag to pin the agent when both are installed

Verified: image builds, hermetic smoke passes in-container, and a real codex
review ran end-to-end inside Docker (2 correct findings on the sample). Docs
record the verified credential paths (claude OAuth env var; writable ~/.codex
mount for codex).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The previous sample rules (no-console-log, no-magic-numbers) are better served
by a linter. Replace them with rules that only a diff+LLM reviewer can enforce —
detecting the REMOVAL of safety logic, which is invisible in the final code:

- examples/rules/no-removed-auth-checks.md
- examples/rules/no-removed-error-handling.md

scripts/demo.sh now strips an auth guard and error handling so the sample diff
exercises these rules. Verified end-to-end in Docker (codex): the auth-guard
removal is reliably flagged as blocking.

Also harden the review prompt: instruct the model to anchor findings about
removed code to the nearest surviving line, since deleted lines have no new-side
line number and would otherwise be filtered out.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- AR-6C: spawn marks child env AGENT_RULES_SUBPROCESS; CLI refuses to run when
  re-entered, preventing an agent -> agent-rules -> agent loop
- AR-86: scripts/pack-smoke.sh packs the tarball, installs it into a throwaway
  project, and verifies the files allowlist, ESM exports, and bin entry; wired
  into CI as `yarn pack:smoke`
- AR-85: .github/workflows/release.yml publishes on a v* tag with npm provenance
- CHANGELOG + issue tracker updated

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- name -> @casa/agent-rules with publishConfig.access: public
- replace tag-based release with .github/workflows/publish.yml: publishes on
  merge to main, guarded to skip when the package.json version is already on npm
  (bump the version in a PR to trigger a release). Expects NPM_TOKEN secret.
- update install/import references (README, requirements doc, pack-smoke)

Verified: scoped tarball packs, installs, imports, and the bin runs (pack:smoke).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@browep browep force-pushed the feat/agent-rules-package branch from 054052a to 86394d3 Compare June 26, 2026 20:46
browep added 3 commits June 26, 2026 16:01
The issue tracker is an internal working doc, not part of the published package
or PR. docs/agent-rules-requirements.md remains tracked.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- assets/banner.svg: diff-window banner showing a removed guard (the signature
  use case) with a review lens; referenced at the top of the README
- README: add "Why not just a linter?" section and --transport usage
- requirements doc: add --transport to the CLI flags, resolution order, and R27

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- CLI --list: discover and print the rules applicable to a diff without invoking
  a transport (no model call, no nested agent, no auth) — for editor integrations
- examples/integrations/: /agent-rules slash command for Claude Code (.claude/
  commands) and Codex (~/.codex/prompts); the host agent reviews using --list output
- ship examples/ in the package (files) so the documented cp commands work
- README: "Agent integration (slash command)" section
- requirements doc: --list flag + R31; smoke covers --list; CHANGELOG updated

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@browep browep force-pushed the feat/agent-rules-package branch from e42b58c to 2baf58f Compare June 26, 2026 22:02
@browep browep merged commit bf2f294 into main Jun 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants