Bash shim had shell quoting risks and depended on socat/nc. Elixir
escript would pay ~300ms BEAM boot per invocation. A second Burrito
binary would unpack on every cold call. Rust gives <1ms startup,
proper timeout handling, and is already in the toolchain for the
tree-sitter NIF.
- Add shim/ Rust crate to directory structure
- Document Rust shim rationale (vs bash, escript, Burrito)
- Update Dependencies with shim crate deps (serde_json, stdlib Unix socket)
- Update install script, README, architecture diagram
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Changes based on reviewer feedback:
- Promote tree-sitter-bash to primary parser recommendation (over bash
Hex package). Battle-tested grammar, robust against adversarial input.
- Fix path matching: directory-boundary matching instead of string prefix.
reads_file("~/.ssh") no longer matches ~/.ssh_backup/key.
- Tilde expansion uses HOME from hook payload, not daemon environment.
Correct for containers, remote SSH.
- MCP parameter injection: replaced regex with McpParameterInjection
validator that runs string values through BashAnalyzer for consistency.
- Regex safety: add 1ms evaluation timeout to prevent catastrophic
backtracking. Timed-out regex falls through to AST pass.
- Document that regex rules can only deny/suspect, never allow.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add adapter layer with normalize_input/format_output per tool
- Define common internal payload and verdict formats
- Map event names across tools (PreToolUse/BeforeTool)
- Map payload fields across tools (tool_name, tool_input, cwd)
- Adapter-specific response formatting:
- Claude: hookSpecificOutput.permissionDecision
- Gemini: flat decision field
- Codex: exit code 2 + stderr for deny
- Shell shim takes --adapter flag to select tool
- install.sh auto-detects all installed tools and registers hooks
- Hook registration examples for all three tools
- Add adapters/ directory to daemon source tree
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Linux/WSL: systemd user service + socket activation for zero
cold-start latency and automatic crash recovery
- macOS: launchd plist with KeepAlive and socket activation
- Fallback: shim-managed with lock file (containers, minimal VMs)
- Shell shim simplified — no longer manages daemon lifecycle
- Daemon detects inherited file descriptors for socket activation
- Add service/ directory with unit files and plist template
- Update install.sh to detect platform and install appropriate service
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove deferred condition from grammar production
- Add [meta] version to config.toml example
- Add PostToolUse allow response (empty object)
- Mark post.rules as deferred in directory tree
- Complete lockfile list for all supported ecosystems
- Handle startup race condition (EADDRINUSE retry)
- Note log rotation as deferred
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Critical fixes:
- Fail-closed: shim returns deny if daemon unreachable
- Validators compiled into binary, not loaded dynamically
- Socket directory created with 0700 permissions
Important fixes:
- Document match target fields per hook type
- Note PreToolUse vs PostToolUse response format difference
- Defer only_when/except_when conditions to future version
- Add concrete match_base_command_not_in example
- Specify PID file locations
- Add versioning scheme for rules and config
- Defer post.rules linting to future version
Other:
- Clarify exfiltration rules (not blocking bare curl/wget)
- Add missing yarn to allowed executables
- Fix macOS socket path (avoid space in Application Support)
- Note Burrito first-run unpack latency
- Document existing hooks coexistence
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>