{
  "markdown": "# guard\n\nStdlib-only safety hooks for Claude Code.\nEvery decision is logged to JSONL — query and trace in place with `guard status|noisy|silent|trace`.\n\n[![CI](https://img.shields.io/github/actions/workflow/status/TracineHQ/guard/ci.yml?branch=main&label=CI)](https://github.com/TracineHQ/guard/actions/workflows/ci.yml)\n[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13-blue.svg)](https://www.python.org/)\n\n```\n$ rm -rf /\nguard: deny - rm -rf against /, /*, ~, $HOME, ., or ./ is catastrophic.\n```\n\nGuardrails not walls: guard catches the obvious foot-guns at the Claude Code hook layer so a stray tool call doesn't turn into a bad day. It is defense-in-depth, not a security boundary.\n\n## What it does\n\n| Hook | What it catches |\n|---|---|\n| bash_command_validator | dangerous shell commands (rm -rf, eval/source, env-var hijack, shell-wrapper bypass) + admin-CLI default-deny for `aws`/`gcloud`/`az`/`kubectl`/`launchctl` (only read-only verbs pass) |\n| git_c_validator | `git -C path` traversal, `git -c key=value` config injection, `git commit -C` silent message reuse |\n| credential_check | hardcoded credentials in tool inputs |\n| commit_message_validator | AI-attribution trailers (`Co-Authored-By: Claude…`) and missing/file-backed commit messages |\n| agent_output_guard | reads of subagent transcript files (`/tmp/claude-<pid>/.../tasks/*.output`) |\n| protected_files | edits to user-marked protected files |\n| subagent_scope | file edits outside the declared `.claude/subagent-scope.json` allowlist |\n| permission_request_logger | observation-only: logs every Claude Code permission prompt as a `permission_request` JSONL row (no enforcement) |\n\n## Install\n\nInside Claude Code:\n\n```\n/plugin marketplace add TracineHQ/plugins\n/plugin install guard@tracine\n```\n\nThis installs guard from the unified [TracineHQ plugin catalog](https://github.com/TracineHQ/plugins). The same marketplace also hosts [convo](https://github.com/TracineHQ/convo); once the marketplace is registered you can install either with one command.\n\nStandalone alternative (skip the catalog and install guard directly from this repo):\n\n```\n/plugin marketplace add TracineHQ/guard\n/plugin install guard@tracinehq\n```\n\n`TracineHQ/guard` is the GitHub `owner/repo` shorthand for the marketplace source. `guard@tracinehq` is the `<plugin>@<marketplace>` reference Claude Code uses to install. To pin a specific tag:\n\n```\n/plugin marketplace add TracineHQ/guard#v1.3.0\n```\n\n### Requirements\n\n- Claude Code v2.0.0+ (plugins entered public beta on 2025-10-09)\n- Python 3.11+ available on `python3` PATH (no third-party dependencies)\n- POSIX shell environment (Linux, macOS, WSL). Windows is not supported in v1 — the matchers target POSIX shell shapes (`rm -rf`, `cat ~/.aws/credentials`, process substitution) and offer no meaningful protection against PowerShell or `cmd.exe` equivalents. CI runs on `ubuntu-latest` and `macos-latest`.\n\n### Optional: power-user CLI\n\nThe marketplace install above wires up the safety hooks. To query the decision log without `tail | jq`, install the read-side CLI from PyPI:\n\n```\npipx install tracine-guard\n```\n\nThen `guard status` shows the log location and last record, `guard noisy --since 24h` ranks rules by hit count, `guard trace <session_id>` dumps a chronological view, and `guard silent` lists rules that fired historically but not recently. Query subcommands are read-only against `~/.claude/guard-decisions.jsonl`; `guard allowlist *` writes to your allowlist file (project or `--global`). The two install paths complement each other; they aren't alternatives.\n\n## Configuration\n\nGuard reads a small set of environment variables. See [SKILL.md](SKILL.md) for the canonical descriptions and defaults.\n\nStrict default-deny activates from Claude Code's `permission_mode` field in\nPreToolUse hook input (no env var). The strict modes are `auto` (Anthropic's\nclassifier-mediated unattended mode), `dontAsk`, and `bypassPermissions` --\nall three imply \"no human at the prompt.\" Other modes (`default`, `plan`,\n`acceptEdits`) use advisory evaluation.\n\n**Requirements:** Claude Code that emits `permission_mode` on PreToolUse\npayloads (current Claude Code releases do; older builds default to advisory\nsince the field is absent). For one minor cycle, a deprecated\n`CLAUDE_AUTONOMOUS=1` env var fallback escalates to `dontAsk` with a stderr\nwarning -- remove the env var before the next minor release.\n\n**Healthcheck:** `guard healthcheck` exits 0 on healthy, non-zero on\nfailure. Suitable for CI gates and cron-based monitors.\n\n**Mode (enforce / shadow / off):** the effective mode lives in\n`.claude/guard/allowlist.json` as a top-level `\"mode\"` field (project),\nwith `~/.claude/guard/allowlist.json` (global) as fallback. Default is\n`\"enforce\"`. Flip with `guard mode shadow --project` to test a new rule\nagainst real sessions without blocking -- denies are logged with\n`mode: \"shadow\"` but the hook exits 0 so Claude Code's normal permission\nflow takes over. Restore with `guard mode enforce --project`. `\"off\"`\nshort-circuits the hook entirely (no decisions, no audit row).\n\n| Variable | Purpose |\n|---|---|\n| `GUARD_DECISIONS_PATH` | Override the JSONL decision-log path |\n| `GUARD_STRICT_DENY_QUEUE_PATH` | Override the strict-deny queue path |\n| `GUARD_DEBUG` | Emit per-hook debug to stderr |\n| `GUARD_DATA_DIR` | Override guard's data directory |\n| `GUARD_PROTECTED_EXTRA` | Comma-separated extra protected glob patterns (fallback when `.claude/guard-protected.txt`, rooted at cwd, is absent) |\n| `GUARD_ADMIN_ALLOW_VERBS` | Per-verb allow for `bash.admin_default_deny`; format `<cli>:<verb.path>,<cli>:<verb.path>` (e.g. `aws:ec2.run-instances,gcloud:functions.deploy`) |\n\n**Catalog model (AWS):** the admin matcher uses an explicit `(service, verb)` allowlist for `aws`. Verbs not in the catalog deny by default. To rescue a long-tail verb without a code change, set `GUARD_ADMIN_ALLOW_VERBS=\"aws:<service>.<verb>\"` (see [SECURITY.md](SECURITY.md) for the decision tree and the list of deliberately-excluded verbs).\n\nTo disable an individual hook, remove its entry from `~/.claude/settings.json` PreToolUse, or comment the line in `hooks/hooks.json` if you forked the plugin.\n\n## What it doesn't do\n\n- Not a security boundary. A determined attacker who controls input to Claude Code can bypass any client-side hook.\n- Defense-in-depth, not an exclusive safety mechanism.\n- Logs decisions for observability; doesn't enforce server-side.\n\n## Output log\n\nEvery decision is appended to `~/.claude/guard-decisions.jsonl` (NDJSON, one record per line). The schema is stable and documented in [docs/JSONL_FORMAT.md](docs/JSONL_FORMAT.md).\n\nTail and pretty-print:\n\n```\ntail -f ~/.claude/guard-decisions.jsonl | jq\n```\n\nOr use the built-in `guard` CLI for read-side queries:\n\n```\nguard status               # installation status + log location + line count\nguard healthcheck          # synthesise a known-deny payload and assert deny\nguard noisy --since 7d     # top hit rules in the last week\nguard silent --since 30d   # rules that haven't fired in 30 days\nguard trace <session-id>   # all records for a single session\nguard test \"<command>\"     # what would each hook decide?\nguard diff                 # effective merged config (stub)\nguard allowlist list       # show effective allowlist (list/rules/disable-rule/...)\nguard migrate-log          # one-shot rewrite of the JSONL log to schema v1\n```\n\n## Development\n\n```\njust check\n```\n\nRuns lint, typecheck, and tests. See [CONTRIBUTING.md](CONTRIBUTING.md) for setup, test tiers, and commit conventions.\n\n## Known limitations\n\nGuard is defense-in-depth, not a security boundary. The validators trade exhaustive coverage for low false-positive rates and stdlib-only portability, which means a determined attacker who controls Claude Code's input can bypass any client-side hook. Pattern-matching is conservative on purpose: rules deny shapes that have a clear safer alternative and pass shapes that are ambiguous. For the threat model, the disclosure process, and a list of areas guard explicitly does not cover, see [SECURITY.md](SECURITY.md).\n\n## License\n\nApache 2.0 — see [LICENSE](LICENSE).\n",
  "bytes": 8269,
  "sha": "4a1b3e334e1b78301ea66ec9cf11b4ac203f14204fc839fad70d86e3c8d23002",
  "repo_slug": "tracinehq/guard",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/plg_tracinehq_guard_guard_4c8a79b7/readme"
}