2.8 KiB
2.8 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project
Security hooks for AI coding agents (Claude Code, Gemini CLI, Codex). A Rust shim forwards tool-call payloads over a Unix socket to an Elixir daemon that evaluates rules using regex and tree-sitter-bash AST analysis. See the design spec for full details.
Status: Design phase. No implementation code yet.
Architecture
AI Agent --> Rust Shim (<1ms) --> Unix Socket --> Elixir Daemon --> allow/deny/ask
- shim/ — Rust binary. Reads JSON from stdin, sends to daemon socket, prints response. Cross-compiled for macOS/Linux.
- daemon/ — Elixir OTP app distributed as a Burrito binary. Rule engine, bash AST analyzer (tree-sitter-bash via Rust NIF), config manager, file watcher for hot-reload.
- rules/ — Custom
.rulesDSL files. Regex patterns (literal to end of line, never quoted) and AST match functions (command(),pipeline_to(), etc.). - config/ — TOML files.
config.tomlfor defaults,config.local.tomlfor user overrides (gitignored). - service/ — systemd socket activation units (Linux/WSL) and launchd plist (macOS).
Build commands (once implementation starts)
# Rust shim
cd shim && cargo build --release
# Elixir daemon
cd daemon && mix deps.get && mix release
# Burrito binary (cross-platform)
cd daemon && mix release --burrito
# Run tests
cd shim && cargo test
cd daemon && mix test
Key design decisions
- Fail-closed: shim returns exit code 2 (deny) if daemon is unreachable within 200ms (3s for cold start).
- Two-pass evaluation: regex rules run first (fast pre-filter, can only deny/suspect, never allow). AST rules run second only if no regex matched.
- Regex vs AST auto-detection: if a
matchvalue starts with a DSL function name likecommand(, it's AST. Otherwise it's regex. - Validators compiled in: Elixir validator modules are compiled into the Burrito binary at build time to prevent code injection into the security daemon.
- Adapter pattern: Claude/Gemini/Codex differences are isolated in thin adapter modules (
daemon/lib/security_hooks/adapters/). The rule engine operates on a normalized internal payload.
Crosslink workflow
This repo uses crosslink for issue tracking. Before making code changes:
crosslink quick "describe the work" -p low -l <label> # creates issue + starts work
crosslink issue comment <id> "approach" --kind plan # required before commit
Conventions
- Elixir: follow standard
mix formatconventions - Rust: follow
cargo fmt/cargo clippy - Rule files: 2-space indent, 4-space indent for
match_anysub-patterns - Commit messages: imperative mood, explain why not what