Local-first safety layer for every AI agent on your machine
Project description
Reinc
Local-first safety layer for AI coding agents. Version 0.1.
Status: early alpha. Five agents are integrated: Claude Code, Codex, Cursor, Devin, and Antigravity — all validated end-to-end against live agents. The pre-hook now scans tool input (file content being written, commands being run) for prompt-injection / secret patterns before execution, so writing an instruction-override phrase to a file is denied before the file is created — not just flagged when it's read back. Three agent-specific notes: Codex writes/edits files via
apply_patch(reinc parses the patch to gate it) and has no nativeask, so a warn-tier Codex call fails closed todeny. Cursor is IDE/cloud-first: the Cursor CLI (cursor-agent) fires only a subset of hooks, so there it gates shell commands but can't block file writes/edits pre-execution (full blocking works in the IDE/cloud). Antigravity uses PostInvocation + transcript JSONL reading for post-audit (PostToolUse carries no tool output). It's a guardrail, not a sandbox (see below) — don't rely on it as your only protection. Feedback and issues very welcome.
Reinc sits between your AI coding agents and your machine. Every tool call an agent makes —
reading files, writing code, running shell commands, making network requests — is intercepted
by the agent's own pre-tool hook, scored for risk (0–100), and logged. When a call is risky
enough to need a human, Reinc returns ask and the agent shows its own native approval
prompt — right where you already work. (On agents that can only allow/deny and have no native
ask, like Codex, a warn-tier call fails closed to deny instead.) All data stays on your
machine. No accounts, no servers, no telemetry.
Targets Claude Code, OpenAI Codex, Cursor, Devin (incl. Windsurf), and Google Antigravity. Today Claude Code,
Codex, Cursor, Devin, and Antigravity are integrated end-to-end (wire dialect + reinc register); a Cline
dialect exists but has no register path yet (see
docs/INTEGRATION.md).
Reinc gates tool calls on your machine. reinc register devin (one global hook at
~/.config/devin/config.json) covers the Devin CLI, the Devin Local agent, and Windsurf
(which runs Devin Local after the Cognition acquisition) — they share the same hook contract — so
Devin Desktop and Windsurf are covered when they run Devin Local. Policy stays per-project.
Not covered: Devin Cloud agents (they run in Cognition's remote sandbox), and the legacy
Cascade hooks Windsurf is phasing out (EOL 2026-07-01).
How it works
Reinc is not an MCP server. MCP adds tools to an agent; it does not gate the agent's native tools. Reinc instead wires into each agent's pre-tool-execution hook — the only primitive that can actually deny a call before it runs.
Three layers, each with one job:
- Hooks enforce. A tiny, per-call
reinc hookprocess parses the agent's tool call, scores it, and repliesallow/deny/ask.askhands the prompt back to the agent — on agents that support it; ask-incapable ones (e.g. Codex) fail closed todeny. - Config declares.
.reinc/config.toml(committed, shared with your team) plus the gitignored.reinc/personal.toml(your local overrides) are the single source of truth for policy. There is no learned or remembered state that changes decisions. - The TUI logs.
reinc monitoris a read-only dashboard that tails the audit log. It never prompts you — your agent does that.
Claude Code reinc monitor (read-only)
│ ┌─ Reinc ─────────────────┐
│ PreToolUse hook │ 12:04 claude write_file│
▼ │ src/auth/login.ts 72 │
reinc hook ──── sqlite ─────────► │ 12:04 → ask │
│ ◄── allow/deny/ask ── └─────────────────────────┘
▼
agent runs the tool, or shows its own prompt (on `ask`), or refuses (on `deny`)
No daemon — the hook reads/writes sqlite directly. Each call opens the db, reads recent
history (reconstructing the behavioral scorer's cross-call state), scores, writes the audit
row, and closes. reinc monitor is a read-only TUI that polls sqlite every 0.5s.
Install
reinc is a Python CLI. Every channel installs the same package — pick whichever you like:
# PyPI (recommended — isolated install)
uv tool install reinc # or: pipx install reinc
# Homebrew (macOS / Linux) — once the tap is published
brew install cabernect/tap/reinc
# curl — picks uv / pipx / pip for you, installs isolated
curl -fsSL https://raw.githubusercontent.com/cabernect/reinc/main/install.sh | sh
From source (latest unreleased):
git clone https://github.com/cabernect/reinc && cd reinc uv venv && uv pip install -e . # or: python -m venv .venv && .venv/bin/pip install -e . reinc --version
Quick start
cd your-project/
reinc init # creates .reinc/config.toml + .reinc/db/
reinc register claude-code # wires reinc into ~/.claude/settings.json hooks
# also available: reinc register codex | cursor | devin | antigravity
Add this to your project's .gitignore:
.reinc/db/
.reinc/personal.toml
Commit .reinc/config.toml so teammates get the same rules. Keep .reinc/personal.toml local —
it holds your machine's overrides.
Watch decisions live (optional):
reinc monitor # read-only dashboard (polls the sqlite audit db)
To undo: reinc unregister claude-code.
Policy
Project policy lives in .reinc/config.toml. Rules are tool:glob patterns:
[policy]
mode = "interactive" # interactive | strict | permissive | headless
[thresholds]
warn_above = 30
block_above = 60
[never_allow] # absolute ceiling — never overridden
rules = ["bash:rm -rf /", "write_file:/etc/**", "write_file:~/.ssh/**"]
[allow] # auto-allow, just log
rules = ["read_file:src/**", "write_file:src/**", "list_dir:**", "search_files:**"]
[warn] # force the agent's approval prompt (`ask`)
rules = ["write_file:src/auth/**", "bash:git push *"]
[block] # hard deny
rules = ["write_file:.env*", "write_file:*.pem", "write_file:*.key"]
[paths] # tag targets with a sensitivity multiplier
config = { paths = ["*.toml", "*.json"], sensitivity = "high" }
tests = { paths = ["tests/**", "**/*.test.*"], sensitivity = "low" }
Personal overrides
Adjust policy for just your machine without touching the shared config:
reinc allow "write_file:scratch/**" # appends to .reinc/personal.toml [allow]
reinc deny "bash:curl *" # appends to .reinc/personal.toml [block]
Personal rules are merged on top of config.toml at load time.
Modes
| Mode | Low (≤30) | Medium (31–60) | High (>60) |
|---|---|---|---|
interactive |
allow | ask | deny |
strict |
ask | ask | deny |
permissive |
allow | allow | ask |
headless |
allow | allow | deny |
block_above (default 60) is honored in interactive, strict, and headless — score > 60 →
deny. permissive is the only mode that asks (not denies) on high.
headless never emits ask — use it in CI where no human is present. On an ask-incapable
agent (Codex, Cursor's non-shell events) every ask above collapses to deny, which shifts
the effective allow/deny cutoff — see docs/POLICY.md. Full rule syntax, the
precedence ladder, and common recipes (allow-all-except, read-only, lockdown) are there too.
Precedence
never_allow → block → warn → allow → risk scorer + thresholds
The first matching rule wins. If nothing matches, the risk scorer decides.
Risk scoring
When no explicit rule matches, Reinc scores the call 0–100 over three layers:
- Base score per tool (
read_file8,edit_file20,write_file25,bash35,http_request20–55, …). - Sensitivity multiplier from
[paths]and built-in critical patterns (.env*,*.pem,src/auth/**,~/.ssh/**, …): low ×0.5, medium ×1.0, high ×1.5, critical ×2.5. - Behavioral bonus from the session stream: reconnaissance loop (+20), exfil signature (+40), scope creep (+15), repeated probing (+10), cascade delete (+30).
- Input scanning bonus from the pre-hook: the tool's input content (file text being written,
command being run) is scanned for prompt-injection / secret patterns before execution.
A match adds the scanner bonus (+40 injection, +30 secret) to the score before the band
lookup — so writing an instruction-override phrase to a file can push 25 → 65 → deny,
blocked before the file is created. Flags are persisted to the audit log and shown in
reinc monitor.
score = min(100, round((base × sensitivity + behavior_bonus) × agent_trust_multiplier) + input_scan_bonus)
agent_trust_multiplier (high ×0.7 / medium ×1.0 / low ×1.3) scales the score for more- or
less-trusted agents. It never overrides an explicit allow/block/warn rule.
CLI reference
reinc init # create .reinc/ in the current project
reinc register <agent> # wire an agent's hooks to reinc (claude-code | codex | cursor | devin | antigravity)
reinc unregister <agent> # remove reinc's hooks
reinc monitor # read-only logging dashboard (polls sqlite)
reinc allow "<pattern>" # append a personal allow rule
reinc deny "<pattern>" # append a personal block rule
reinc hook --agent <name> # internal: score one tool call from stdin (called by hooks)
Not a sandbox
Reinc is a guardrail, not a container. Hooks run inside the agent's own trust domain, and
documented bypasses of agent approval gates exist. Reinc's value is catching mistakes, drift,
and prompt-injection accidents with an explainable, unified policy — not airtight containment.
A real OS-level sandbox floor is an optional future hardening layer. See
docs/THREAT_MODEL.md for exactly what Reinc does and does not defend
against (including Reinc's own attack surface), and
docs/INTEGRATION.md for the architecture and per-agent capability matrix.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file reinc-0.1.0.tar.gz.
File metadata
- Download URL: reinc-0.1.0.tar.gz
- Upload date:
- Size: 107.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a0e729cd3b7fd1e19e3559c98b0aac566720d37d2ee3e0f0f29b7a57391ee1a6
|
|
| MD5 |
edd6e2aa070a5f02a05ce40dae93ecff
|
|
| BLAKE2b-256 |
899e6735992389c393dc0463eba955b54a962c597999e24f47514e29695e0c67
|
Provenance
The following attestation bundles were made for reinc-0.1.0.tar.gz:
Publisher:
publish-pypi.yml on cabernect/reinc
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
reinc-0.1.0.tar.gz -
Subject digest:
a0e729cd3b7fd1e19e3559c98b0aac566720d37d2ee3e0f0f29b7a57391ee1a6 - Sigstore transparency entry: 2056938490
- Sigstore integration time:
-
Permalink:
cabernect/reinc@f4b32589efcbbf4574956456d9271d73a6bd6266 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/cabernect
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@f4b32589efcbbf4574956456d9271d73a6bd6266 -
Trigger Event:
release
-
Statement type:
File details
Details for the file reinc-0.1.0-py3-none-any.whl.
File metadata
- Download URL: reinc-0.1.0-py3-none-any.whl
- Upload date:
- Size: 58.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
63fcc7671359b8801c04594074006836f7bb4ac1ae4f41aaa55482a71317385d
|
|
| MD5 |
02e90a7971ddb07693b557ab464972f4
|
|
| BLAKE2b-256 |
12b7a144d9259d8a50f29ed78d3cea80a2363b5ac15c7ba9ff4ba597ec186825
|
Provenance
The following attestation bundles were made for reinc-0.1.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on cabernect/reinc
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
reinc-0.1.0-py3-none-any.whl -
Subject digest:
63fcc7671359b8801c04594074006836f7bb4ac1ae4f41aaa55482a71317385d - Sigstore transparency entry: 2056938659
- Sigstore integration time:
-
Permalink:
cabernect/reinc@f4b32589efcbbf4574956456d9271d73a6bd6266 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/cabernect
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@f4b32589efcbbf4574956456d9271d73a6bd6266 -
Trigger Event:
release
-
Statement type: