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

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 .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)

# 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.

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 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