The harness for your harness. A 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.
The exit ramp, up front: interlinked disable stands the guard down and
interlinked uninstall-hooks removes every hook entry this CLI installed —
manifest-driven, restoring your runners' settings files to their prior state.
Nothing phones home, everything lives in .interlinked/ in your repo, and
removal is one command. Try it on a throwaway repo first if you like; the
whole setup is interlinked (the wizard) and the whole teardown is those two
commands.
Once an AI agent can write code, run shell commands, and install dependencies on its own, the question for any organization stops being "can it help?" and becomes "how do we prove every autonomous action was checked against policy before it ran — and reconstruct what happened afterward?"
Interlinked is a control plane for exactly that. It sits at the boundary between the agent and the system, and on every tool call it:
- Enforces policy deterministically — a block-or-allow decision in milliseconds, with no model in the decision path, so every verdict is explainable and reproducible rather than a probabilistic guess.
- Fails closed on what causes incidents — destructive commands, secrets written into source, and unvetted dependencies are stopped before they touch disk, and remain blocked even when the daemon is unreachable.
- Produces an audit trail by construction — every decision is written to a replayable log, attributable to a specific agent and session, ready to inspect or report on.
That is the triad every responsible-AI program is built on — evaluation, observability, and enforceable guardrails — implemented at the one layer where it can't be skipped: the point where an agent's intent becomes a real-world action. Policy is shared through version control and enforced identically across 5 agent runners and a fleet of agents working in parallel — with no cloud dependency and no required cloud or remote telemetry. Optional authenticated sync is explicit.
This isn't only an architecture diagram. The receipts below are 1175 per-event-audited blocks captured over 94 days of daily use on a single developer's machine — and the pattern is the point: a deterministic, audit-first enforcement boundary that works the same way for one agent or a thousand.
Receipts from 94 days of dogfooding on the author's machine. The activity log captured 1715 distinct
guard_blockevents (over-registration duplicates collapsed, grep-accelerator answers excluded); 1175 of them survived a per-event audit against Claude Code session transcripts to confirm the agent's actualtool_input. The audited breakdown:
- 830× edits that introduced a new TypeScript error — blocked before the write landed (
tsc-diff-overlay)- 94× new source file with no companion test (TDD gate)
- 88× shell-redirect bypass attempts (
cat > file.tsto dodge the content-quality gate)- 40× writes outside the repo root
- 47× empty
catch {}blocks- 30×
kill/pkill/killallat running processes — four aimed at the harness or session itself- 25× edits to files another agent held the reservation on
- 14× destructive git (
reset --hard,branch -D,stash drop)- 4× secrets detected in proposed write content
- 3× package installs not on the team allowlist (fail-closed supply-chain gate)
Full breakdown on the landing page or in What you get below.
Local-first by design. The harness, activity log, and checks run on your machine; server-backed collaboration commands are optional and require an Interlinked MCP Server URL. No required cloud or remote telemetry, and no LLM in the hot path; optional authenticated coordination/sync is explicit.
The CLI is currently intended to run from the GitHub repo rather than a formal npm package. Requires Node.js 22+. Supported on macOS and Linux (including WSL on Windows — native Windows is not supported).
npm install -g github:QuentinCody/interlinked-cli # one step: clone+build+linkPrefer a working checkout you can read and update in place? The long form is
equivalent (prepare builds dist/ during npm ci automatically):
git clone https://github.com/QuentinCody/interlinked-cli.git
cd interlinked-cli
npm ci # builds dist/index.js + dist/hook-entry.js via prepare
npm link # exposes `interlinked` and `interlinked-hook` on PATHAfter that, interlinked update pulls the latest repo changes, rebuilds,
and refreshes the linked binaries.
interlinked install-hooks from a cloned checkout records an absolute path
to dist/hook-entry.js in your agent's settings, so hooks will keep firing
as long as the clone stays put. If you move or delete the clone, rerun
interlinked install-hooks from the new location (or interlinked uninstall-hooks first). The tarball-install smoke test in .github/workflows/ci.yml
exercises the same end-to-end path.
Four commands can start you off, and they do different amounts of work.
Use the table to pick one — the short answer is enable.
| Command | What it does | When to use it |
|---|---|---|
interlinked (no args) |
First-run wizard: prompts for server/agent/sync settings, then runs enable (+ optional login). Outside a TTY it runs the same bootstrap with defaults and no prompts |
A brand-new project, when you want to be asked the questions rather than pass flags |
interlinked enable |
Installs hooks + skills, writes .interlinked/ config, starts the harness |
Canonical. Every other path, including CI and non-interactive shells |
interlinked setup |
enable, then handles login/auth in one step |
You also want to authenticate against an Interlinked MCP Server right away |
interlinked init |
A heavier, interactive onboarding flow: detects clients, installs hooks directly (no skills), logs in, attaches a workspace, and verifies the result | You're connecting to a team's Interlinked MCP Server and want guided workspace setup |
Use enable. It is the one this README's Quick Start uses, and bare
interlinked and setup both call it internally — they only wrap it in
prompts or a login step. init is the exception: it installs hooks on its
own path and installs no skills, so your agent gets the gates without
the instructions for reading them (see Quick start below for why that
matters). Reach for setup or init only when you need the login and
workspace steps they add.
- Guard harness. A local Unix-socket server evaluates every agent
action against 123
deterministic safety rules (destructive commands, secrets in writes,
sensitive-file reads, lockfile drift, etc.) and returns block/allow
decisions in about 1–5 ms for cheap rules; content-checking rules
(
tsc/biomediff-overlay) take whatever the compiler takes. - Content-quality gate.
tscandbiomerun over the proposed file content before a write lands. The gate blocks only on net-new findings, never on pre-existing issues. Works forEdit/Writetools and — viainterlinked write— for Bash-mediated writes likesed -iorcat > file. - Auto file reservation. Every file write takes a lease-based reservation with a 5-minute TTL and a 30-second idle auto-release. When an Interlinked MCP Server is configured, a write that targets a file already reserved by another developer's agent is blocked with a pointer to coordinate via MCP messages; otherwise the reservation is local-only.
- Post-edit checks. 27 quality checks across 8+ languages (tsc, biome, cargo, mypy, …) and 25 structural checks (export surface, import resolution, cycles, blast radius) run after each edit.
- Offline activity log. Every hook event appends to
.interlinked/activity.jsonlsynchronously (~0.1 ms).interlinked status,activity,explain, anddoctorread from this log. - Trigram grep. Grep calls route through a cached trigram index,
narrowing candidate files before
rgruns.
# In the repo you want to instrument:
interlinked enable # hooks + skills, auto-detecting every agent runner
interlinked harness start # start the local guard server
interlinked status # show what's configuredThen restart or reload your agent so it picks up the new skills. Run it as usual and tool-use events flow through the harness.
Use enable, not install-hooks, unless you know you want the adapter
path. Both wire the hooks, but enable also installs the skills that teach
your agent how to work with the harness — how to read a BLOCKED: … Suggestion: … message, how to run interlinked verify, what the quality
ratchets expect, and how to legitimately suppress a false positive. Without
them, the first block your agent hits is a message it has to guess at, and the
most likely guess is to work around the gate. install-hooks is the precise,
manifest-tracked adapter path (see Day-to-day commands); it installs no
skills.
Server commands such as login, sync, tasks, and inbox are available
when you point the CLI at an Interlinked MCP Server.
interlinked enable also installs the /enforce skill across every detected
agent runner (Claude Code, Codex, Gemini, Copilot, Cursor). Use it when you want
the imperatives in your AGENTS.md / CLAUDE.md / .clinerules/ to become
rules the harness actually enforces, instead of prose the model may or may not
follow.
# In the repo you want to instrument:
interlinked enable # hooks + skills (incl. /enforce)
# Restart or reload your agent so it picks up the new skill, then in-agent:
/enforce # walk the project, distill imperatives
/enforce AGENTS.md # or target a single file
/enforce list # see what got distilled, grouped by sourceSome runners surface skills via description match instead of /-prefix
($enforce, @enforce, etc.). The slash form is canonical; description match
is a fallback for surfaces that don't expose slash-skills. Output lands at
.interlinked/distilled-rules.json; the harness reloads automatically within
~2s. Full reference: skills/enforce/SKILL.md in this repo.
| Command | What it does |
|---|---|
interlinked status |
Summary of configured agents, active harness, recent events |
interlinked activity --since 1h |
Recent hook events (filterable by agent, tool, since) |
interlinked explain --since 1h |
Per-event explanation including guard decisions |
interlinked doctor |
Diagnostics: hook registration, harness liveness, config sanity |
interlinked write <path> --stdin |
Write a file through the content-quality gate |
interlinked multi-edit <path> |
Apply N edits to one file atomically (all or none) |
interlinked verify |
Run the full quality + structural gate over the current tree |
interlinked verify --all-checks |
Deep-audit mode: add advisory smell/taste checks |
interlinked mode |
Show or switch enforcement mode |
interlinked coverage |
Per-file coverage ratchet (needs a coverage-summary.json) |
interlinked mutation |
Per-file mutation-score ratchet (needs a Stryker report) |
interlinked structure |
Generic artifact structure management (manifests, adoption) |
interlinked harness start/stop/status/test |
Manage the harness daemon |
interlinked daemons |
List all active harness daemons and their health |
interlinked uninstall-hooks |
Remove hooks this CLI installed (manifest-driven) |
Run interlinked --help for the full command list, or interlinked <command> --help for per-command flags.
agent (Claude/Copilot/Gemini/Cursor/Codex) ──► interlinked-hook
│
├─► harness Unix socket
│ └─► guard eval (block/allow) in ~1–5 ms
│ └─► post-edit quality + structural checks
│
└─► .interlinked/activity.jsonl (append, ~0.1 ms)
└─► interlinked {status,activity,explain,doctor}
The installed hook invokes the packaged interlinked-hook binary. If you
uninstall the CLI, previously installed hook entries fail open until you run
interlinked uninstall-hooks or reinstall the package.
Guard evaluation has two layers:
- Guard rules — destructive shell commands, secrets in writes,
recursive deletes, force-pushes to protected branches. These block
by default and are not downgraded by mode selection. Individual
rules can still be disabled via
disabled_rulesin.interlinked/guard-rules.local.jsonif you have a specific reason. - Taste rules — style, complexity, coverage, test quality. Mode selection governs these.
Switch modes with interlinked mode <name>:
balanced(default): destructive commands are blocked; quality findings warn.lenient: findings surface as warnings, writes proceed.strict: findings block the write until the agent fixes them.
Team-shared policy lives in .interlinked/guard-rules.json. Personal
overrides go in .interlinked/guard-rules.local.json (gitignored).
- Harness decisions and activity capture are local by default. Data leaves
your machine only when you run server-backed commands such as
loginorsync, or when you explicitly opt into another remote workflow. - No telemetry, no analytics, no "phone home" — not even an anonymous version-check ping. The CLI makes no outbound network calls on its own.
- Hook events, guard decisions, and quality findings stay in
.interlinked/under the repo root.
This README covers the essentials. For more detail:
| Doc | Covers |
|---|---|
docs/harness.md |
Harness architecture: guard evaluation, reservations, quality checks |
docs/command-reference.md |
Every command and flag, hand-maintained |
docs/generated/ |
Auto-generated reference: guard rules, quality checks, structural checks, configuration defaults |
docs/generated/ is regenerated from the live registries by npm run docs,
and npm run docs:check fails CI when the committed prose drifts from the
source it was derived from. Read those files rather than trusting counts
quoted elsewhere.
- Contribution guide: CONTRIBUTING.md
- Security policy: SECURITY.md
- Bug reports and feature requests: https://github.com/QuentinCody/interlinked-cli/issues
MIT. See LICENSE.