New 404 blocks in 2 weeks of dogfooding

The harness for your harness.

Local guard layer for AI coding agents. Hooks into Claude Code, Codex, Cursor, Copilot CLI, and Gemini CLI; evaluates every tool call against deterministic rules; blocks the dangerous ones in milliseconds; keeps a local activity log you can grep.

$ git clone github.com/QuentinCody/interlinked-cli
See receipts

Node 22+, macOS or Linux. No npm package yet — git clone is on purpose, until the public surface stabilizes.

Works with Claude Code Codex Cursor Copilot CLI Gemini CLI
~/myproj — claude
$ claude
 clean up the build artifacts before deploy

  I'll remove the build output now.
  → Bash: rm -rf /

  ⚠ BLOCKED by interlinked harness
    rule:    builtin-rm-rf-root  (critical)
    reason:  Recursive deletion of root-level or wildcard
             paths is dangerous.
    hint:    Be more specific about what to delete.
    ms:      1

  Let me try the project's build output instead.
  → Bash: rm -rf ./dist
  ✓ allowed
  Removed 14 files.

Illustrative. The rule (builtin-rm-rf-root) and reason text are loaded verbatim from src/harness/rules/builtin-rules-processes.ts; the surrounding agent dialogue is synthesized to show the block-and-recover flow.

The receipt

Two weeks. One developer.
195 verified real blocks.

The author dogfooded the harness on his own machine for two weeks while writing it. The activity log captured 446 guard_block events; the rows below are the ones that survived a per-event audit against Claude Code's session transcripts to confirm the agent's actual tool_input.

Some early dramatic-looking categories (shutdown, root-level rm -rf, DROP TABLE) turned out to be false positives — the rules' substring matchers fired on commit-message bodies, echo arguments, and grep patterns. Those rules were tightened with command-start anchors and quote masking; the table reflects only blocks where the agent's resolved command actually matched the row's intent.

Data as of 2026-05-07. Audit method: npm run docs:audit-receipts (re-runs the per-event transcript correlation locally).

Count Severity What the agent tried
84 high Edits that introduced a new TypeScript error — blocked before the write landed (tsc-diff-overlay)
35 high Used shell redirect (cat > file.ts) to dodge the content-quality gate
29 high Created a new source file with no companion test
25 high Empty catch {} blocks landing in code
18 critical Wrote outside the repo root (e.g. /tmp/x.ts)
4 critical Tried to kill a PID that turned out to be the harness or session process
219 Did not survive audit. Substring-matching FPs from older destructive-command rules (now fixed), unbucketed TypeScript advisories, and miscellaneous low-severity flags. Reported here for honest accounting; not counted in the headline.

Verified blocks

195

Rule eval p50

2 ms

Total events logged

446

Built-in rules

105

How it works

A Unix socket between the agent and disk.

Every PreToolUse hook fires a JSON-RPC message at .interlinked/harness.sock. The harness evaluates rules, returns a decision, and (optionally) attaches warnings the agent will see on its next turn.

Local-only

No cloud, no telemetry, no LLM in the hot path. The socket is on your machine; the activity log stays in your repo.

Multi-runner

Same harness for Claude Code, Codex, Cursor, Copilot CLI, and Gemini CLI. One config, every agent.

Deterministic

Regex + AST + a handful of compilers (tsc, biome, gitleaks, semgrep). Replayable from the JSONL log.

Configurable

Team-shared rules in .interlinked/guard-rules.json; personal overrides in guard-rules.local.json (gitignored).

# the hot path
agent (Claude / Codex / Cursor / Copilot / Gemini)
  ├─→ interlinked-hook  (~0.1 ms)
  │     ├─→ .interlinked/harness.sock
  │     │     └─→ guard eval (block / allow / warn) ............ ~1 ms
  │     │     └─→ post-edit quality + structural checks ........ ~50–600 ms
  │     │
  │     └─→ .interlinked/activity.jsonl  (append-only, ~0.1 ms)
  │           └─→ interlinked {status, activity, explain, doctor}

Why this and not …

How we compare.

Capability Interlinked Husky / pre-commit claude-code-action (CI) No harness
Blocks tool calls before the agent runs them ✓ PreToolUse hook — (CI is post-action)
Runs locally, no network on hot path ✗ runs in GitHub
Multi-agent runner support ✓ 5 runners — (git only) — (Claude Code only)
Median rule-eval latency ~1–2 ms ~50–500 ms 10s+ (CI startup)
Logs every PreToolUse / PostToolUse ✓ JSONL, replayable CI logs only
Catches dangerous shell commands (rm -rf, kubectl delete --all, …) 105 rules — (file lints, not commands) depends on prompt
Compiles proposed file content before write lands ✓ tsc / biome diff-overlay post-commit only CI only
Open-source, MIT

Husky and pre-commit are great at what they do — git-time linting on file content. They sit downstream of the moment the agent runs an arbitrary shell command. Interlinked sits at that moment.

FAQ

Frequently asked.

Does it phone home? +
No telemetry, no analytics, no version pings. The activity log lives at .interlinked/activity.jsonl in the repo it's instrumenting. The CLI makes no outbound network calls on its own — only the server-backed commands you explicitly run (login, sync, etc.) talk to the network.
Why no LLM in the hot path? +
Latency budget. The PreToolUse hook has a tight cycle and a remote LLM call eats it on a good day. Determinism also makes guard decisions replayable from the JSONL log — you can replay a session and verify exactly why a call was blocked. An LLM classifier is on the roadmap as a narrow escalation layer, not a hot-path replacement.
Why isn't it on npm? +
On purpose, for now. The public surface is moving and an npm publish freezes a lot of names and shapes. git clone && npm link is a deliberate filter for serious users. A 0.2 release on npm is planned once the surface stabilizes.
What does it actually catch? +
Two layers. Guard rules — destructive shell commands, secrets in writes, recursive deletes, force-pushes to protected branches, sensitive-file reads — block by default. Taste rules — style, complexity, coverage, test gaps — surface as warnings. Mode selection (balanced / lenient / strict) governs the second layer.
Will it slow my agent down? +
Hot-path rules add ~1 ms median to PreToolUse — imperceptible. Post-edit checks that compile proposed file content (tsc, biome) take whatever the compiler takes; for a typical TS file that's a few hundred milliseconds, and the agent only pays it if the diff is suspicious. Latency budgets are enforced per tool class.
Does it work with Cursor / Windsurf / Aider / …? +
Today it ships first-class hooks for Claude Code, Codex, Cursor, Copilot CLI, and Gemini CLI. Other agents land as the runtime ecosystem standardizes — if you're using one we don't have a hook generator for, file an issue and we'll prioritize.
Can teams share rules? +
Yes. .interlinked/guard-rules.json is committed and read by every machine that has the harness; .interlinked/guard-rules.local.json is gitignored and used for personal overrides. The /enforce skill also distills imperative prose from AGENTS.md / CLAUDE.md into the same JSON format.

Get the receipts. Run it on your machine.

Five minutes from git clone to your first guard_block in .interlinked/activity.jsonl.