Files
security-hooks/CLAUDE.md
2026-03-30 13:00:31 +02:00

63 lines
2.8 KiB
Markdown

# 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](docs/specs/2026-03-26-security-hooks-design.md) 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 `.rules` DSL files. Regex patterns (literal to end of line, never quoted) and AST match functions (`command()`, `pipeline_to()`, etc.).
- **config/** — TOML files. `config.toml` for defaults, `config.local.toml` for user overrides (gitignored).
- **service/** — systemd socket activation units (Linux/WSL) and launchd plist (macOS).
## Build commands (once implementation starts)
```bash
# 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 `match` value starts with a DSL function name like `command(`, 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:
```bash
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 format` conventions
- Rust: follow `cargo fmt` / `cargo clippy`
- Rule files: 2-space indent, 4-space indent for `match_any` sub-patterns
- Commit messages: imperative mood, explain why not what