Skip to main content

Hard rules for AI coding agents - one rulefile, compiled to native hooks, zero daemons.

Project description

picket

ci

Hard rules for AI coding agents — one rulefile, compiled to native hooks, zero daemons.

Your agents ignore CLAUDE.md instructions some fraction of the time, because prompt instructions are probabilistic. Their hooks fire deterministically — no probabilistic instruction-following. picket compiles one picket.toml (protected branches, protected paths, secret patterns, command deny-list) into your agent's native hook configuration, then exits. No daemon, no proxy, no LLM calls, no network. Blocked attempts land in a local JSONL audit log.

demo GIF placeholder — split terminal: left, agent runs git push origin main → ✗ BLOCKED [protect-branch:main]; right, agent runs cat .env → ✗ BLOCKED [protect-path:.env*]; bottom, picket log showing both attempts.

Quickstart

uvx picket init      # detect agents, write picket.toml with safe defaults
uvx picket apply     # compile + install native hooks (preview first: --dry-run)
# your agent is now fenced - restart any session already running in this repo
uvx picket log       # see everything that got blocked
uvx picket unapply   # restore your config byte-for-byte

Not on PyPI yet? Run straight from git: uvx --from git+https://github.com/KaiC5504/picket picket init

The defaults are useful with zero editing: protect this repo's default branch (push, force-push, deletion), deny reading/editing existing .env* files and anything under ~/.ssh/**, deny recursive deletes that resolve outside the repo, deny force-pushes, and deny writing well-known secret formats (AWS/GitHub/Slack/Google/Anthropic keys, private-key blocks) into files or commands.

v0.1 targets Claude Code. Codex, Cursor, and Copilot CLI targets are next (the compiler was built around a target interface for exactly that).

Reversibility is the product

  • picket apply --dry-run prints the exact unified diff of every file it would touch, and writes nothing.
  • apply is idempotent — running it twice changes nothing.
  • Your existing hooks are never modified: picket appends one clearly recognizable entry to the project-scope .claude/settings.local.json (hooks merge across scopes in Claude Code, so user-level and plugin hooks keep running untouched).
  • Before the first modifying write, the prior file is backed up; picket unapply restores it byte-for-byte. If you edited the file after apply, unapply surgically removes only picket's entries and tells you why a byte-identical restore wasn't possible.
  • If your settings file is malformed JSON, picket aborts and touches nothing.

What it is (and is not)

picket is a footgun guard, not a sandbox. It deterministically blocks the accidents agents actually commit — pushing to main, reading .env, rm -rf outside the repo, pasting a key into a file — and writes an audit trail. It does not defend against malicious code, and its shell-command scanning is honest best-effort (e.g. cat .env is caught; an obfuscated cat $(echo .env) is not). Hooks fail open by design: if the hook itself breaks, your agent keeps working and the error is logged. For hostile-code scenarios, pair picket with OS-level sandboxing (e.g. Anthropic's sandboxing features) — they solve different problems and compose well.

How it compares

picket prempti claude-code-guardrails claude-guardrails
Architecture compiles to native hooks, then exits Falco-engine interceptor in the loop PreToolUse hook config deny rules + hooks dotfiles
Runtime footprint none daemon/interceptor none none
Rule format plain TOML Falco YAML dialect JSON/scripts JSON/scripts
Agents Claude Code (Codex/Cursor/Copilot planned) Claude Code + Codex (exp.) Claude Code Claude Code
Audit log local JSONL + picket log yes (its strength) no no
Reversibility dry-run diff + byte-exact unapply n/a (runtime component) manual manual
Windows first-class (no bash-isms; PowerShell dialect parsed) POSIX-first bash hooks bash hooks

All of these are good projects — prempti in particular validates the category and is the right choice if you want a security-team-grade Falco pipeline. picket's bet is the dev-first corner: one TOML file, native hooks, nothing running afterwards, works on the machine you actually develop on (including Windows), and trivially reversible.

Rule reference

version = 1

[branches]
protected = ["main"]        # push, force-push, and deletion denied
deny_force_push = true      # force-push to ANY branch denied

[paths]
protected = [".env*", "~/.ssh/**"]   # Read/Write/Edit denied + best-effort shell scan
allow = ["*.example", "*.sample", "*.template"]  # exceptions: templates stay usable
# no "/" -> basename match at any depth (like .gitignore); with "/" -> full glob, ** ok
# basename patterns guard existing files only, so `cp .env.example .env` still works;
# full-path patterns like ~/.ssh/** are absolute (nothing may be added there either)
# tradeoff, stated honestly: an agent MAY create a brand-new .env - only the secret
# scan applies to freshly created files; once the file exists it is protected

[secrets]
builtin_patterns = true     # AWS, GitHub, Slack, Google, Anthropic keys, private-key blocks
extra = []                  # your own regexes

[commands]
deny = []                   # glob on the full command string, e.g. "*npm publish*"
deny_recursive_delete_outside_project = true

Every blocked attempt appends one JSONL line to .picket/audit.jsonl:

{"ts": "2026-07-21T14:55:23Z", "agent": "claude-code", "session_id": "...",
 "rule": "protect-branch:main", "tool": "PowerShell",
 "action": {"command": "git push origin main"}, "decision": "deny", "message": "..."}

Written content is never logged (it may contain the secret being blocked).

Development

uv sync && uv run pytest    # 100 tests, run on ubuntu + windows in CI

This repo is fenced with picket itself (picket.toml at the root).

MIT license.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

picket-0.1.0.tar.gz (42.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

picket-0.1.0-py3-none-any.whl (23.9 kB view details)

Uploaded Python 3

File details

Details for the file picket-0.1.0.tar.gz.

File metadata

  • Download URL: picket-0.1.0.tar.gz
  • Upload date:
  • Size: 42.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for picket-0.1.0.tar.gz
Algorithm Hash digest
SHA256 dc7875712bcfe50aa6953138b22d220707c9f571fe6e89611c49fc12f42f30f8
MD5 7959a409c6c80422ee8c85741b121ca7
BLAKE2b-256 938307795989a950686c8ad78908199f79f74549561b19c0e11afbfd371971a2

See more details on using hashes here.

File details

Details for the file picket-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: picket-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 23.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for picket-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bc5ca7f99db247d9975303d6f2e8805c9d57fe63dcb17fa03723db4ac0a6d94a
MD5 4e8c2435ff2be33ddda58e8d30dfe6bf
BLAKE2b-256 f9632e93b444d5fc8be19927dc496f813278530cfcb45d866b9b3489c72168d7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page