It Operations
davila7/claude-code-templates
Manages IT infrastructure, monitoring, incident response, and service reliability.
Install, operate, and troubleshoot the Interlinked CLI harness in a repo — install/uninstall agent hooks, connect runners (Claude Code, Codex, Copilot CLI, Gemini, Cursor, OpenCode, Pi)…
$ npx skills add QuentinCody/interlinked-cli --skill interlinked-setup -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install QuentinCody/interlinked-cli interlinked-setup --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/QuentinCody/interlinked-cli.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/interlinked-setup .claude/skills/interlinked-setup && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "interlinked-setup" agent skill from https://github.com/QuentinCody/interlinked-cli/tree/main/skills/interlinked-setup into .claude/skills/interlinked-setup/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interlinked-setup", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/QuentinCody/interlinked-cli/tree/main/skills/interlinked-setupType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add QuentinCody/interlinked-cli --skill interlinked-setup -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install QuentinCody/interlinked-cli interlinked-setup --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/QuentinCody/interlinked-cli.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/interlinked-setup .agents/skills/interlinked-setup && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "interlinked-setup" agent skill from https://github.com/QuentinCody/interlinked-cli/tree/main/skills/interlinked-setup into .agents/skills/interlinked-setup/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interlinked-setup", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add QuentinCody/interlinked-cli --skill interlinked-setup -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install QuentinCody/interlinked-cli interlinked-setup --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/QuentinCody/interlinked-cli.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/interlinked-setup .cursor/skills/interlinked-setup && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "interlinked-setup" agent skill from https://github.com/QuentinCody/interlinked-cli/tree/main/skills/interlinked-setup into .cursor/skills/interlinked-setup/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interlinked-setup", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/QuentinCody/interlinked-cli.git --path skills/interlinked-setup--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add QuentinCody/interlinked-cli --skill interlinked-setup -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install QuentinCody/interlinked-cli interlinked-setup --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/QuentinCody/interlinked-cli.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/interlinked-setup .gemini/skills/interlinked-setup && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "interlinked-setup" agent skill from https://github.com/QuentinCody/interlinked-cli/tree/main/skills/interlinked-setup into .gemini/skills/interlinked-setup/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interlinked-setup", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install QuentinCody/interlinked-cli interlinked-setupInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add QuentinCody/interlinked-cli --skill interlinked-setup -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/QuentinCody/interlinked-cli.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/interlinked-setup .github/skills/interlinked-setup && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "interlinked-setup" agent skill from https://github.com/QuentinCody/interlinked-cli/tree/main/skills/interlinked-setup into .github/skills/interlinked-setup/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interlinked-setup", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add QuentinCody/interlinked-cli --skill interlinked-setup -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install QuentinCody/interlinked-cli interlinked-setup --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/QuentinCody/interlinked-cli.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/interlinked-setup .opencode/skills/interlinked-setup && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "interlinked-setup" agent skill from https://github.com/QuentinCody/interlinked-cli/tree/main/skills/interlinked-setup into .opencode/skills/interlinked-setup/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interlinked-setup", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
interlinked-setupInstall, operate, and troubleshoot the Interlinked CLI harness in a repo — install/uninstall agent hooks, connect runners (Claude Code, Codex, Copilot CLI, Gemini, Cursor, OpenCode, Pi)…
Interlinked Setup is an agent skill from QuentinCody/interlinked-cli. Install, operate, and troubleshoot the Interlinked CLI harness in a repo — install/uninstall agent hooks, connect runners (Claude Code, Codex, Copilot CLI, Gemini, Cursor, OpenCode, Pi), start/stop/restart the local guard daemon, run interlinked doctor, switch server / sync-mode / check-policy, log in, and manage the two-tier .interlinked/ config. Load when setting up Interlinked, when interlinked doctor reports problems, when the guard daemon is down or stale, when hooks are not firing, or when configuring or…
Its SKILL.md is about 14k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files (for example `agents/openai.yaml`).
The repository describes itself as: The harness for your harness. Local hooks, taste enforcement, and developer observability for AI coding agents (Claude Code, Codex, Cursor, Copilot CLI). The licence is MIT.
Read from SKILL.md and the folder at commit 31b5259. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
nodegitnpmnpxFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use git, npm and npx, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
INTERLINKED_TOKENINTERLINKED_ACCESS_TOKENFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Interlinked Setup loads about 14k tokens when it runs. Until then it costs about 141 tokens; SKILL.md has 6,923 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from QuentinCody/interlinked-cli at commit 31b5259, republished under its MIT licence (© QuentinCody). 6,923 words, ~13,501 tokens.
.claude/skills/interlinked-setup/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.The local guard-prediction oracle defaults to enforced, independently of the
optional Supermodel graph protocol. Shared .interlinked/config.json accepts
harness.guard_prediction.mode: "enforced" | "shadow" | "off". Use
interlinked-harness for exact prediction/reconciliation receipts and limitations.
Native cold fallback can run this AST oracle; standalone generated hooks need the
daemon and report NOT CHECKED without it. Physical file size is advisory in both
warm and cold paths; rebuilding must not revive the old line-count block.
Claude compiler batching activates only after a session sends native PostToolBatch.
After daemon restart, edits use the ordinary compiler path until that boundary is
observed again; previously queued work remains durable and is checked at Stop/commit.
Keep the installed PostToolBatch hook current. It delivers repair context rather than
cancelling the agent loop for ordinary compiler findings. See interlinked-verify.
Skill refresh preserves modified installed copies. If they still describe sub-cap
complexity slew blocks, compare them with canonical skills/*/SKILL.md, retain local
customizations/backups, and reconcile deliberately. Restarting a daemon cannot erase
guidance already loaded into a model's conversation.
Non-gating native hook commands use a compact missing-runtime diagnostic and exit 1;
gating hooks retain the self-contained fail-closed fallback and exact repair allowlist.
After rebuilding, use interlinked install-hooks --refresh --preserve-mode to refresh
installed command text, then verify interlinked harness status --json shows the serving
build. Keep PostToolUse scoped to mutating tools; do not add PostToolUseFailure duplicates.
Provider qualification must exercise native edit routes, advisory file-size delivery,
and completion after ordinary Stop advisories. Claude and Codex keep those advisories on
stderr; explicit repair blocks still request continuation. Codex rewrites include
permissionDecision: allow. Retain registrations and native transcripts: an encoded
response alone does not prove native enforcement.
Before behavioral qualification, use interlinked tests readiness <language> --json, then
run a real project suite. Python readiness probes the selected environment for pytest,
pytest-cov and coverage; it does not install or infer passing tests. The hook installer also
ignores the named generated payload-key, enforcement-status and coverage-runtime-estimate
outputs. These ignore entries never exempt policy files or make runtime-input caching sound.
For an externally frozen policy, keep the policy files on read-only supervisor mounts and
pin their parent directories as mount points; a read-only file under a replaceable parent is
insufficient. Keep daemon sockets, atomic receipt writes, proposals and intended ratchet state
writable. Qualify CLI mutations, direct replacement, local overrides and daemon restart under
the actual non-root agent identity before claiming immutable effective policy. A same-UID
daemon and --by labels do not provide an authorization boundary.
Interlinked is a local, offline-first guard layer for AI coding agents. Repository
config, logs, and daemon state live under <repo>/.interlinked/; installation also writes
selected providers' settings, managed bridge files, and installed skill directories at
their provider-specific project or user locations. A local daemon ("the harness", a
Unix-socket server) evaluates each event the installed runner exposes to its hook surface.
This skill covers turning it on, keeping the daemon healthy, configuring it, and turning it
off. The remote server is optional — hooks, guard, and activity capture work with zero
network.
interlinked enable adds named daemon telemetry, capture state and test-run outputs to
.gitignore. Re-running setup updates older installations whose generated ignore list is
incomplete; otherwise harness bookkeeping can appear as new workspace edits and schedule
unnecessary checks. This does not ignore the entire .interlinked tree or change runtime-input
validation: shared policy/ratchet files remain observable, and deliberately tracked output
still participates in Git-visible change capture. Do not untrack files automatically.
interlinked doctor reports failures, or hooks are not firing / not capturing events.cwd, offline-first. Repository config and runtime state are rooted at
<cwd>/.interlinked/: config.json is committed/shared and config.local.json is
gitignored/personal. Provider hook settings, managed OpenCode/Pi bridges, statusline
entries, and installed skill copies live in the provider's project or user directories;
the installer manifest records the integration files it owns.harness start runs a background Unix-socket server. When it
is up you get the full check set; when it is down the hook falls back to a small inline
subset and fails closed on the dangerous stuff (destructive commands, agent-created
worktrees, package installs, line-cap, merge conflicts).interlinked-coordination). Skip it entirely for local-only use.config.local.json. Malformed JSON roots and
non-string local values do not become credentials.interlinked semantic install command is the only model-acquisition path; see
interlinked-semantic-index.Cowork has a separate plugin workflow: interlinked cowork package --output <directory>.
Load interlinked-cowork for upload, native conformance, runtime failures and the
optional authenticated host bridge. It is not an enable --clients coding-client
target; editing Claude Code settings does not install the Cowork plugin.
interlinked doctor also inventories existing lint configuration and offers
interlinked lint import. Preview is read-only; lint import --write enables
the registered PostToolUse wrapper, and adding --baseline executes installed
linters to adopt existing debt. A local lint_import.enabled:false override
is reported before import writes. Hooks must already be enabled. Follow
interlinked-verify for supported adapters, unresolved configurations, and
the explicit lint check gate; the ordinary adopt command remains separate.
Oxlint and named ESLint configs are detected automatically; lint import previews
their scopes and hook/audit cadence. For arbitrary filenames, use repeatable
--config tool=file (or --eslint-config file), then --write --baseline.
Selectors are relative to
the target project; --eslint-scope optionally chooses a package working scope.
Saved profiles survive re-import without repeating these flags.
Script aliases, task/CI evidence and local config/plugin imports extend discovery.
Use .interlinked/lint-adapters.json for reviewed direct SARIF analyzers; follow
interlinked-verify for that contract. YAML task parsing requires the optional
yaml package; without it the evidence remains in the review list. Dependency
approval follows interlinked-supply-chain. Slow/type/CI profiles initially use
audit cadence; lint check or verify --all-checks includes them.
| Command | What it does | When to use |
|---|---|---|
bare interlinked (unconfigured repo) | The harness-first setup wizard (2026-08-16): six one-line decisions — runners to hook, enforcement mode (strict — the recommended default — /lenient/balanced), review scope (diff/whole-file → guard-rules.json diff_aware.enabled), cap overrides, brownfield adopt, and dead-code posture (2026-08-17: flag default / delete instructs the agent to remove flagged dead code in the same edit / off; writes structural_checks scoped to only the dead-code checks so the rest of the family stays a separate decision; the whole-repo sweep is interlinked deadcode) — each Enter-accepts a recommended default, shows the plan, then composes enable + mode + caps set + adopt. Local-first: never asks about a server. Non-TTY: env-driven (INTERLINKED_MODE / INTERLINKED_SCOPE / INTERLINKED_ADOPT / INTERLINKED_CLIENTS). A failed step reports and continues — every step is individually re-runnable via the owning command. Ends with a posture receipt (2026-08-17): one line per thing now enforced, each naming the command that changes it. | A new user's first touch; the fastest correct install. |
interlinked enable | Full setup: writes .interlinked/ config, installs per-client hooks, updates .gitignore, installs statusline (Claude/Copilot), installs every bundled Interlinked skill, auto-starts the daemon. Idempotent; re-running clears any stand-down. | The normal way to turn Interlinked on. |
interlinked setup | Runs enable, then login if no token (skips login on localhost / when a token is present). | You also want server auth right away. |
interlinked init | Interactive/auto onboarding wizard (--yes for non-interactive): installs hooks on its own path, logs in, attaches a workspace — and installs no skills. | Guided team/workspace setup only. |
interlinked install-hooks | Adapter path: writes hook entries + installer-manifest.json and, unless --preserve-mode, applies the selected/default enforcement mode. --refresh is manifest-scoped hooks-only and implies preserve-mode; installs no skills. | Precise, manifest-tracked hook install or refresh. |
A mode is a posture, not just check severities (2026-08-17). interlinked mode strict|balanced|lenient also ladders the philosophy-dependent gates into
guard-rules.json (merge-preserving; later hand edits win until the mode is
re-applied): the new-file TDD gate (strict=block, balanced=warn,
lenient=off), per-edit coverage (strict=no-debt blocking, balanced=debt
mode, lenient=off), and the session-end verification/commit-cadence nudges
(lenient turns them off). Security rails and tighten-only ratchets never
ladder. custom applies nothing.
Trigram indexing is opt-in: enable installs hooks and starts the daemon
without building the repository's search index. Run interlinked index build
to enable grep acceleration; an existing index continues to load normally.
Keeping the repository scan out of onboarding allows setup to finish on large
repositories without exhausting the CLI's heap. adopt still builds the index
and snapshots existing manifests/lockfiles into the install allowlist
(approved_by: "adopt").
Bare
interlinkedis the recommended human first run because it shows the local posture decisions before composing them.enableis the canonical install primitive for automation or an already-chosen configuration. Prefer either overinstall-hooks: only the wizard andenableinstall the skills that teach an agent how to read a block. Without them the first block is a message the agent must guess at, and the likeliest guess is to work around the gate.
Key enable flags: --server <url> · --agent <name> · --clients <list>
(claude,copilot,gemini,codex,cursor,opencode,pi) · --sync-mode <realtime|local|manual> ·
--data-dir <path> · --structure <mode> · --dry-run.
install-hooks uses different vocabulary: --runner <claude-code,copilot-cli,cursor,gemini-cli,codex,opencode,pi>
· --scope <user|project|local> · --mode <balanced|strict|lenient>.
Explicit values are strict: an unknown client, sync mode, structure mode, install scope, or
enforcement mode exits nonzero before config, hook, manifest, stand-down, binary-fallback,
daemon, or login writes.
Only an omitted option receives its documented default.
interlinked enable --agent my-bot # detects clients, starts daemon
interlinked enable --clients claude --dry-run # preview without writing
interlinked install-hooks --runner claude-code --scope projectClient detection uses the registry's project directory/config markers and process environment, not a PATH probe for the binary. Codex automatically detects skill changes; if an active session does not, restart it. Copilot needs
/skills reloadto pick up skill changes. OpenCode/Pi native skill copies live under.opencode/skills/and.pi/skills/.
Enable each client's strictest usable native sandbox separately; Interlinked hook installation does
not turn the provider sandbox on. Bash PreToolUse reports [interlinked:sandbox] as attested,
configured, disabled, or unknown. Treat configured as weaker than per-call attestation because
CLI/profile overrides can change the active call. Explicit Codex escalated/danger-full-access calls
and Claude unsandboxed settings are reported as disabled evidence.
Native workspace-write sandboxes constrain host/network reach but still allow real writes inside the project. They complement Interlinked's post-call filesystem ChangeSet and Stop residue backstop; they do not provide rollback or replace the deterministic PreToolUse guards. See interlinked-harness for interpreting the warning.
interlinked harness capabilities --json reports runtime hook profiles, installation
and emission evidence, and filesystem coverage. harness coverage status --json shows
pending identities, manual reviews, automated check receipts, and any recovery job.
Coverage control calls allow ten seconds per transport for reconciliation and retained
receipts. A timeout still means no verdict; inspect status before retrying a mutation,
since the daemon may have completed it before the response was lost.
For [interlinked:hook-coverage] NOT CHECKED, run harness coverage verify --json and
follow interlinked-verify for evidence scope, deferred checks and reviewed absences.
If a running daemon predates the verifier, rebuild/restart using the normal lifecycle.
Observing or checking protected files does not accept their policy digest.
Local data maintenance has its own data.config.json in the resolved data directory.
interlinked data configure --auto-index on enables bounded SessionEnd index jobs;
--auto-compact on also enables lossless collection/timeline rotation. Both default off.
These settings are reread per maintenance job and do not alter capture, sync, or guard policy.
Use data health/data status for producer coverage and index freshness; load
interlinked-observability for budgets, search, archive behavior and audit checkpoints.
| Command | Purpose |
|---|---|
interlinked harness start [--verbose] [--json] | Start the daemon (background). Reaps orphans first and auto-rebuilds stale dist/, so a cold start can take a few seconds. Freshness recursively checks non-test product files, including edits to existing nested files. Readiness requires live connections to every required listener; a socket inode alone is not ready. |
interlinked harness stop | Send SIGTERM, wait up to 3 seconds, then SIGKILL only verified surviving daemon targets; report any process that truly survives. |
interlinked harness restart | Stop + fresh start; the only way to pick up config/mode changes. Note: clears per-session trajectory state. Defers instead of killing when a start is already in flight, and backs off with "Too many restart attempts" if too many restarts (any trigger) went unresolved recently — see below. |
interlinked harness status [--json] | Liveness (three states, below) + socket, RSS, mode, orphan count, build staleness. --json adds liveness (is anything SERVING — raw StatusQuery or a framed daemon.health), socket_answered, and pid_running (alias of running; BOTH mean only "the legacy harness.pid names a live process" — a framed-only daemon can be liveness: "listening" while running/pid_running are false). Build staleness ignores test files (*.test.*, __tests__/) — they are not bundled into the daemon. |
interlinked daemons [--cleanup] | List all per-session daemons; --cleanup purges dead-PID records. |
interlinked harness reap [--force] [--all] | List (default) or kill orphan daemons. |
interlinked harness status --json # is it up? which mode?
interlinked harness restart # after editing config / changing modeharness restart performs that recursive freshness check and any required
build before stopping the serving daemon, in normal and --json modes. A
failed build, or one that leaves dist/ stale, aborts the restart and keeps the
incumbent serving; Interlinked never knowingly replaces it with stale code.
status and doctor both send a real event and wait for the answer, because a daemon can stay
process-alive while its listener is dead. Three states, and both surfaces use the same words:
harness status | doctor | Meaning |
|---|---|---|
running (PID …) — socket answering | pass — Running (PID …) -- socket answering | Verified: something answered. |
ZOMBIE — process alive (PID …), no socket answering | fail — same remedy line | Full evaluation is unavailable; deterministic inline gates remain active and ordinary work proceeds degraded. |
not running | warn — inline fallback | Honest and expected; the inline subset still guards. |
Only an answered probe prints running (PID …), so that line can no longer appear above
Socket: not found. Fix a zombie with interlinked harness restart — both surfaces print
that remedy inline. A pid-alive daemon gets one confirming re-probe, so a daemon still binding
right after restart is not mislabelled.
Every ordinary hook event may trigger bounded recovery; SessionStart is an opportunity, not a prerequisite. The startup mutex collapses concurrent hooks to one launch. Startup and restart wait for live connections rather than socket-file existence, and the startup lease is released immediately after the final required listener binds or startup reaches a terminal failure. A daemon quiescing for shutdown keeps the mutex under its own PID until it exits so a successor cannot overlap its live heap. A dead owner is reclaimable immediately. A valid team or local guard-disable marker suppresses auto-start; a malformed marker fails toward guarding. During the gap, safe reads, diagnostics, and repairs proceed through the inline fallback while deterministic dangerous operations can still be refused. Status/start/restart/doctor/disable and exact preserve-mode hook refresh commands are excluded from auto-recovery so the hook never races the operator.
interlinked harness restart used to stop-then-start unconditionally, so two overlapping
restart triggers (a build-refresh handover, an rss-ceiling recycle, a second manual restart)
could kill a successor the other had just spawned, before it finished binding. Now:
restart waits for its socket
instead of killing it — printing "already in flight" and doing nothing further once it
answers.restart
refuses and prints "Too many restart attempts … backing off" instead of adding to the churn.
Check .interlinked/daemon-events.jsonl for the pattern before retrying by hand.Neither path is silent: every deferral or backoff writes a handover row to the daemon ledger
(daemon-ledger.ts / handover-churn.ts), so daemon-events.jsonl always explains what
restart actually did.
Since 2026-08-29 every handover attempt is one ID across the whole chain: the parent daemon
writes requested → launcher_spawned (the restart CLI was launched), the restart CLI
adopts the id and writes its own requested intent, the actual daemon spawn writes the
COUNTING daemon_spawned row, and the successor's listening row acknowledges that exact
id — order-independent. Terminal rows (refused on backoff/deferral, spawn_failed,
no_artifact, start_failed, and a startup-failed exit stamped with the id) resolve the
attempt the same way. Only an unresolved daemon_spawned counts toward the backoff;
explicit-restart / explicit-stop / deferral rows are audit facts and never count. A
manual interlinked harness start (id-less listening) still pays off one preceding
unresolved attempt. If the backoff refuses restart during a genuine outage,
interlinked harness stop + interlinked harness start is the ungated recovery path.
Interlinked CLI's proposed design baseline is an 8 GB whole host, shared with the
editor, browser and coding agents. The operator plan is
docs/plans/8gb-host-resource-plan.md (private operator material, absent from public clones).
Its aggregate budgets and qualification criteria are not shipped defaults or a claim of
8 GB readiness. Keep the current limits below until retention improvements and constrained
workflow measurements justify replacing them; lowering heap flags alone can cause restart loops.
SessionEnd jobs now run through a detached supervisor with a 128 MiB V8 heap cap.
The supervisor holds a per-project/job lease through child cleanup, including when the
daemon exits, and admits only one background runner per host at a time.
Scheduled foreground Vitest runs and verify share this host slot. A waiting
foreground request prevents another background admission; the supervisor's monitor
aborts the active background child group so foreground work can proceed. The
daemon's async project-test and legacy affected-test processes share this slot too;
outer project admission does not exempt them from host admission. Their Node heap is
bounded at 768 MiB and VITEST_MAX_WORKERS=1 bounds compatible Vitest runners.
Independent
npm test processes remain outside this admission system. A duplicate background job
is skipped; a different job waits at most two minutes. Each admitted runner has a ten-minute
deadline and a 768 MiB Node V8 heap cap. Fuzz and benchmark commands receive an explicit
--maxWorkers value, rechecked after waiting for admission.
Admission respects physical RAM and any process/container limit. On an unconstrained Mac,
available memory is estimated from free plus inactive pages (vm_stat), with native
kern.memorystatus_vm_pressure_level required to be normal. Node's free-page reading alone
does not account for reclaimable cache. Warning/critical pressure or unavailable telemetry
defers work. Samples are cached for at most 500 ms and commands have bounded time/output.
Managed test and background
runners budget at most 4 GiB or one quarter of total memory, whichever is smaller,
and preserve at least 1 GiB or one eighth of total memory as host
headroom. Worker planning budgets 1 GiB for coordination plus 1 GiB per worker. Thus an otherwise idle
8 GiB machine gets at most one worker and a 16 GiB machine at most three. Missing or
insufficient available-memory readings defer work. A 500 ms monitor measures runner and descendant
RSS with bounded, non-overlapping ps samples. It aborts the child process group when the runner
exceeds its budget, headroom disappears, or telemetry fails. Scheduled foreground tests use this
monitor too, and their coordinator receives a 1536 MiB V8 heap ceiling. Interruption retains
the pending request and produces no reusable pass. Timeout and termination reap the child process
group before releasing admission. This is sampled protection, not an OS-enforced RSS limit:
allocations can overshoot between samples, descendants that escape the process group are not
contained, and unsupported ps telemetry interrupts the run. Public verify and tests
CLI entry points additionally run under a separate supervising process, so a busy CLI event
loop does not prevent sampling. The child retains its normal project/host admission and
consumes the private parent marker before dispatch and evidence capture. If only the light
budget fits, the CLI must stay within its 1 GiB ceiling; interruption exits 75 without a verdict.
These controls do not change the daemon's limits below or govern commands
launched independently by the user. INTERLINKED_DISABLE_SESSION_END_JOBS=1 still opts out.
In this repository, pre-push heavy commands also use the host lane through
scripts/run-resource-bounded.ts. The supervisor retains ownership through child cleanup,
and heavy commands wait at most ten minutes for admission so an existing five-minute
daemon push check can finish first. Light diagnostics retain a five-second admission wait.
The supervisor
streams output, gives a heavy command's Node heap 80% of the admitted tree budget
(3276 MiB at the 4 GiB ceiling; light commands 512 MiB), and limits common native thread
pools. The heap share accommodates the repository's stable TypeScript compiler (about
2.9 GB of heap, measured 2026-10-02, past the former fixed 2560 MiB); the 4 GiB aggregate
tree ceiling remains enforced independently by the resident-memory watcher.
Resource interruptions exit 75 and block the push. For small diagnostic/test batches,
node --max-old-space-size=128 --import tsx scripts/run-resource-bounded.ts --light <command> [args...]
uses a stricter 1 GiB tree ceiling, a 512 MiB Node heap ceiling, and 2 GiB of host headroom.
It cannot run an oversized check successfully: the same monitor interrupts it. Pre-push
keeps the heavy profile and its full exact-revision test/coverage contract.
The default daemon V8 heap cap is 1536MB and the hard RSS recycle ceiling is 2048MB.
INTERLINKED_HARNESS_HEAP_MB is accepted only when it is finite and at least 1; fractional
values are floored, and every invalid value falls back to 1536. The CLI, hook self-heal path,
and generated runtimes use that same parser. At the RSS
ceiling the daemon does not spawn a successor beside its already-bloated heap and does not
keep serving indefinitely. It first holds the project startup mutex under its own PID, then
shuts down gracefully. Cold hooks continue their bounded deterministic guards, see the live
owner during the short teardown, and do not spawn an overlapping daemon; after the old PID
exits, dead-owner reclamation opens the same single-flight self-heal path. A valid
interlinked disable --reason … stand-down marker suppresses that recovery entirely.
The dominant measured spike was an append-only activity log that had grown past 1GiB and was being read into one JS string on daemon sequence checks. Live activity, daemon-ledger, and timeline-dedup readers now read byte-bounded tails directly. Explicit history/backfill commands may still scan complete logs; they are operator work, not the per-hook daemon path.
Idle and heap-pressure shrink now drops every reconstructible PostTool cache together: mutation manifests, per-file external-check diagnostics, the TypeScript overlay service, and the trigram index's dirty layer. This bounds retained state from long multi-file/parallel-agent sessions; the next request rebuilds only what it needs.
The installed hook command accepts its baked binary only when it is a regular, non-empty file.
When it is gone, empty, or fails to return an intentional allow/block status (unbuilt clone,
moved checkout, interrupted build, corrupt JavaScript), its self-contained wrapper still parses
the provider's native tool identity. Claude/Codex reserved read builtins and Cursor's dedicated
beforeReadFile event proceed with exit 0 and a degraded warning. Ambiguous generic names on
Copilot, Gemini, Cursor preToolUse, and MCP/custom events do not earn that exception. Mutating
tools and unknown future tool names receive the provider's native deny response (not a fictional
uniform exit-code contract), with the repair instruction on stderr. A shell command is never
inferred read-only from command text, even when it looks like cat or git status; only the exact
operator commands below escape. Claude's native
WorktreeCreate also stays fail-closed. Non-gating events normalize runtime failures to exit 1
(a logged failure that does not claim a block).
The standalone generated runtime has the same terminal boundary for the supported pair. Once a
parseable Claude/Codex PreToolUse or PermissionRequest payload identifies the native event, an
unexpected top-level exception emits that event's exact deny envelope; a non-gating exception
emits no stdout and exits 1. Provider stdout is staged until the surrounding audit work succeeds,
so a late exception discards the staged object before the terminal response and can never produce
partial or duplicate JSON. The installed foreground wrapper remains the outer fail-closed boundary
for experimental providers. Empty or malformed stdin cannot identify a native event and is treated
as an invalid hook invocation rather than guessed into a provider decision.
The foreground fail-closed wrapper keeps exact operator recovery commands executable before it
invokes even a present runtime: bounded harness start / restart, harness status [--json],
read-only doctor [--json], non-destructive disable, and
interlinked install-hooks --refresh --preserve-mode. Exact node dist/index.js and
npx tsx src/index.ts forms are recognized too; an arbitrary absolute */dist/index.js is not.
The two source-build spellings (npm run build and node scripts/build-atomic-cli.mjs) are a
checkout-local exception only: the current directory must be the same checkout that owns the
baked dist/hook-entry.js path, its package must be named interlinked-cli, and it must carry
the canonical build declaration and script file. An application repo does not bypass its
installed hook merely because it happens to use either build spelling. This prevents a missing or stale runtime
from locking out its own diagnosis and repair. It is deliberately not a general shell allowlist:
prefixes, suffixes, extra flags outside the bounded command grammar, pipes, and compound commands
still run the normal hook and remain blocked. A matching string in a non-shell payload also runs
the normal hook; warn-open events never get this escape. If neither the installed command nor a
built checkout is available, reinstall or rebuild first, then run the preserve-mode refresh.
Claude PreToolUse and PermissionRequest are supported. On PermissionRequest, Interlinked
emits deterministic denies with Claude's dedicated
hookSpecificOutput.decision = { behavior: "deny", message } object; that is distinct from
PreToolUse's permissionDecision. Allow/ask abstain on stdout so Claude's configured policy and
native user prompt retain authority. Non-blocking PermissionRequest diagnostics stay on stderr
because that event does not accept generic additionalContext. Codex follows the same
abstain-on-allow/ask rule through its provider-specific PermissionRequest response path.
Codex additionalContextLimit applies only to SessionStart, UserPromptSubmit,
PreToolUse, PostToolUse, and SubagentStart. Permission decisions, Stop/SubagentStop
continuation reasons and compaction diagnostics use separate output channels. Installing
limits on those events causes Codex configuration warnings. Both install paths omit them;
reinstalling also removes obsolete limits from Interlinked-owned handlers while preserving
foreign hooks. Use the manifest-scoped refresh below for an existing adapter install.
Changed project hook definitions may need renewed review in Codex /hooks.
Stop/SubagentStop continuation is emitted only for an explicit harness block.
Allowed or approval-requested diagnostics stay on exit-0 stderr without restarting
the agent; Stop has no approval channel. Updating this translation requires the
compiled hook runtime to be rebuilt or upgraded, not a hook-matcher change.
Claude's installed WorktreeCreate hook is a deliberate hard stop: that native event replaces
Claude's default Git behavior, and Interlinked fails it without returning a path. Across every
client, the shared shell guard also blocks git worktree add; list, remove, and prune
remain available. Interlinked uses a ban rather than a race-prone concurrent-count cap.
Stale installed hooks (the pre-2026-08-28 SILENT fallback, a deregistered event entry, an old
binary path) are repaired with interlinked install-hooks --refresh --preserve-mode — the
hooks-only path (added 2026-08-29, hardened 2026-08-30). It re-renders ONLY the
Interlinked-owned entries already in installer-manifest.json at their recorded scopes. A
Codex install made before the 12-event Interrupt catalog also needs this refresh, followed by
review in Codex /hooks: adding the event changes the definition hash and therefore trust state.
A corrupt manifest refuses with the bytes preserved (strict per-row validation). Restore a
trusted backup or repair it to the valid schema; do not delete it and then run refresh, because
the missing ownership record also refuses and cannot identify which hooks are Interlinked-owned. Every file the
run can touch — project AND $HOME-scope settings, Codex's config.toml, the manifest — is
snapshotted (bytes + file mode) first; any install failure, any skipped target, or any failed
final-state verification restores the whole snapshot and fails. That rollback covers HANDLED
failures only — an OS crash mid-write cannot run the in-memory restore. Verification is
STRUCTURAL (shared with the doctor install drift check): each expected hook entry exactly
once at its native JSON path, any Interlinked-owned command outside the adapter's current
render fails (the canonical ownership recognizer, so old binaries and legacy .mjs installs
are caught whatever their quoting), and Codex's [features] hooks = true via the table-aware
reader — duplicate [features] tables or duplicate assignments fail. The manifest itself is
strictly validated: unknown runners, invalid scopes, prototype-chain path segments, duplicate
runner rows, and any settings path that does not match the adapter's own derivation all read
as CORRUPT, and install/uninstall/refresh refuse rather than overwrite the evidence.
Uninstall removes hooks by owned-entry recognition, never by stored array index — a user hook
added after install is safe wherever it sits. Ownership is shell-position parsed. An adapter
entry needs the exact hook-entry.js / interlinked-hook basename, a registered --runner,
and a present --event; legacy .mjs ownership needs the reserved
.interlinked/hooks/interlinked-activity.mjs path or its exact generated assignment form. A
command that only prints, comments on, looks like, or invokes a user script with the same basename
without those required shapes is not claimed. Project attribution reads the invoked script path, not
text elsewhere in the command. It NEVER writes enforcement mode, cloud
config, or guard rules. Do NOT repair with a plain interlinked enable or a plain
install-hooks — both also select and write an enforcement mode (the --mode default is
"balanced"). --dry-run previews; a second run reports unchanged.
A normal install replaces ownership only after the adapter finishes its semantic post-install
step. A selected runner that is skipped (for example, malformed project settings) cannot purge a
working hook at another scope. If a replacement's post-install step fails, its attempted settings
file is restored and the prior one-row manifest entry remains authoritative; a first-time failure
has no prior state to restore, so its partial hook and failed manifest row remain together for
uninstall-hooks to remove. In either case the command reports failure rather than claiming the
runner is ready.
Project E2E interlinked tests e2e doctor retains report version 1 and adds optional
evaluation: "not-evaluated" and prerequisites fields to dependent checks. A ledger
failure leaves receipt validation unevaluated; unresolved contract references prevent
complete acceptance/toolchain success. Known missing preparation tools can still fail
independently. POSIX command inspection checks regular executable files under the runner's
PATH/cwd. A same-suite artifact expected after preparation is a warning, not verified
availability; preparation commands never receive that exemption. Runtime placeholders or
unsupported platform lookup stay unverified. The doctor does not execute preparation.
interlinked harness capabilities --json includes the sourced ecosystem catalog,
adapter event/control declarations, installer manifest, last provider emission and
filesystem coverage state. selected describes the adapter's subscription policy;
inspect the manifest to establish installation. An emitted response or matching
definition hash does not certify that the provider enforced it. Native enforcement
remains unmeasured until a provider/version/mode conformance run establishes it.
Factory Droid (factory-droid), Windsurf (windsurf), Google Antigravity
(antigravity) and Crush (crush) are explicit experimental adapters through
interlinked install-hooks --runner <id>. They require a built hook-entry runtime.
They are separate from the seven enable --clients integrations and do not expand
skill installation targets. Their command wrappers currently target POSIX shells;
Windows shell behavior and native headless behavior are not certified. Antigravity
uses .agents/hooks.json, separate from Gemini CLI's .gemini/settings.json.
Claude FileChanged installs without a static matcher. SessionStart, CwdChanged and
FileChanged responses publish the complete current watchPaths list. FileChanged
is an observation after a write; it cannot deny or undo that write. PostToolBatch
can cancel the loop before the next model request. Codex does not acquire either
native event merely because it uses Claude-shaped payloads; daemon filesystem
observation supplies a separate local fallback. Expanded boundary handling requires
the compiled runtime. The adapter installer refuses a generated compatibility script
instead of registering events that it cannot serve. Build the checkout and refresh
hooks; previously installed legacy scripts retain their older compatibility behavior.
The public interlinked-cli/hook-bridge export provides an application-owned Think
tool bridge and a Durable Object storage journal adapter. It is not installed with
coding-client command hooks. See the repository's docs/hook-normalization.md for
its admission, replay and deployment contract.
interlinked doctor is the first stop. It runs local + system + server checks and exits
non-zero if any check fails. --fix repairs common drift (regenerates a drifted hook
script, safely refreshes Interlinked-owned skill copies, strips malformed permission rules,
migrates legacy config).
interlinked doctor # diagnose
interlinked doctor --fix # auto-repair what it safely can
interlinked context --json # show the effective merged config
interlinked env # list supported env vars + current valuesWhat doctor's client rows do and do not prove (2026-08-30). Doctor checks the hook-config
location for every client in the settings registry — Claude Code, Codex, Copilot, Gemini,
Cursor, OpenCode, and Pi — reading each path from that one registry instead of restating it (the hardcoded copy it
replaced pointed Codex at .codex/config.toml, which holds only the feature flag, so doctor
warned that every CORRECT Codex install was missing its hooks). Consequences worth knowing:
.codex/hooks.json; a second row
reads the [features] hooks = true gate in config.toml, table-aware — a hooks = true
under some other table does not count. Installed hooks with the flag off are reported as
INERT, not missing, because those are different repairs. The third row checks
.interlinked/hook-runtime.json: it passes only after Codex executes the current
hooks.json definition hash. If it warns, open /hooks, review the definition, and run a
hooked action.hooks key. Whatever mix of hooks /
codex_hooks, true / false, duplicated or commented, [features] already holds, the writer
leaves a single hooks = true — comments, unrelated tables and the file's line endings intact.
Duplicate TOML keys are a parse error, so the old "add a canonical key beside what we found"
behavior could report a successful migration for a config Codex then refused.install-hooks reports ok: false,
lists the runner under post_install_failures, marks the manifest entry post_install: "failed", exits non-zero, and enable reports the client as not installed. It used to log one
stderr line and report success.Likewise enable --dry-run's per-client event counts are computed from the adapter that
performs the install (they were prose literals that had drifted, so the preview promised
numbers the install did not deliver). They count REGISTRATIONS, not verified provider
capabilities.
What "healthy" looks like in doctor: config dir + both config files present, hook script
present, per-client "Hooks installed", and Harness server: Running (PID …) -- socket
answering. A zombie is a fail here, never a pass. Hook detection shares one ownership
predicate with the installers, so an adapter (hook-entry.js) install is recognised as
installed rather than reported missing. A manifest-tracked hook binary that no longer exists is
a fail, even when the settings document still has the expected entries. A missing token on a non-localhost server is a fail;
on localhost it is only a warn (dev mode allows unauthenticated).
A daemon that fails before binding its socket exits 78 (EX_CONFIG) and appends an
exit row with reason: "startup-failed" to .interlinked/daemon-events.jsonl. It no longer
lingers as a zombie. Read that ledger before theorising — it separates a failed bind (78) from
a graceful stop, a lost ownership race (0, orderly, not a failure), and a crash.
tail -n 20 .interlinked/daemon-events.jsonl # why did it leave?
interlinked harness reap # list orphan daemons (--force kills)
interlinked harness restart # the usual fixBind attempts are bounded with backoff, and a socket that answers is never unlinked — a live incumbent wins and the newcomer exits instead of stomping it. Only a silent, stale socket file is cleared and retried.
Dev loop after editing the CLI source: interlinked reload rebuilds the CLI in its own
checkout, refreshes this repo's hooks and deployed skills, and restarts the daemon only if
something the daemon executes changed.
The package build is runtime-preserving, not a whole-directory transaction. One repository-scoped
lease prevents concurrent compiler runs; an equivalent waiter coalesces after the owner finishes.
The owner bundles, repairs declarations, copies assets, and checks every shipped entry in a sibling
staging directory, then refuses publication if a product build input changed meanwhile. Publishing
atomically renames shared chunks/assets first and runtime entrypoints last (hook-entry.js last of
those and therefore the handled-failure runtime commit point). The entry phase snapshots existing
entries and rolls back anything already replaced if a later entry fails. This is not crash-atomic
across several entry renames; after process/OS loss, each old-or-new entry remains independently
runnable because both generations' hashed chunks stay present, and the next build converges the
entries. dist/ itself is never removed, and prior
hashed chunks remain available to a running daemon's later lazy imports. A fault during shared-file
publication can therefore leave harmless new immutable files in dist/, but it leaves the previous
entry generation in place. Fix the reported error and retry instead of reconstructing dist/ by
hand.
.interlinked/config.json (committed): server_url, default_project, mode
(operational tier), skip_paths, pii_patterns, nested harness feature flags..interlinked/config.local.json (gitignored): access_token, agent_name,
workspace_id, sync_mode, active_server + servers map, guard_mode, data_dir..interlinked/semantic.json (committed): optional semantic-index enablement, exact pinned
model reference, and source/test include policy..interlinked/semantic.local.json (gitignored): local-only CPU/runtime topology. Remote URLs,
API tokens, and cloud fallbacks are rejected by the v1 schema.INTERLINKED_SERVER_URL,
INTERLINKED_ACCESS_TOKEN (alias INTERLINKED_TOKEN), INTERLINKED_AGENT_NAME,
INTERLINKED_WORKSPACE_ID, INTERLINKED_SYNC_MODE, INTERLINKED_HOME (relocates the whole
config dir), INTERLINKED_DATA_DIR, INTERLINKED_CLIENTS (non-interactive bootstrap only).enable, adopt, doctor, metrics, hooks, and search do not auto-download embedding weights.
The experimental semantic commands also require compatible local llama-embedding and
llama-tokenize executables (override their command names only in semantic.local.json). Model
weights live in the platform user cache; project vectors live under the gitignored
.interlinked/index/functions/ directory and are never synced.
Two different mode commands — do not conflate them:
interlinked mode <balanced|strict|lenient> → per-check policy preset → check-policy.json,
PLUS the preset's guard posture (TDD/test-first tier, per-edit coverage + debt mode,
session-end nudges, commit cadence) into guard-rules.json. Since 2026-08-30 the loader
actually honors that posture: the team tier merges the whitelisted safe fields (booleans +
the three posture enums) and drops runtime knobs like budget_ms. --local writes BOTH
halves to the personal tier (check-policy.local.json + guard-rules.local.json) — a
personal mode switch never edits committed team policy. The wizard's scope
(diff_aware.enabled) and dead-code writes load through the same whitelist. The mode
switch is transactional in BOTH directions (a refused guard merge writes neither file; a
failed check-policy write rolls the guard file back), and the three posture enums are
value-validated at the final loader boundary for BOTH tiers — an invalid value is dropped
(built-in default applies) and interlinked doctor names the file, field, and value.interlinked harness mode <budget|quality|ci> → operational timeout tier → config.json
mode + regenerates the hook. Requires harness restart to take effect.interlinked login --server https://your-server.dev # OAuth PKCE (opens browser)
interlinked login --token "$INTERLINKED_TOKEN" # CI / headless
interlinked attach --agent my-bot --auto # link identity + workspace
interlinked logout [--all]setup/init skip login for local servers).config.local.json → auto-refresh → Claude Code
credential fallback (~/.claude/.credentials.json).realtime (default; per-event post + session-end batch), manual
(per-event only), local (no server posts at all).| Command | Effect |
|---|---|
interlinked disable [--reason <t>] [--until <dur>] [--team] | Non-destructive stand-down: records a marker + stops the daemon. Hooks and config stay. Re-arm with interlinked enable. |
interlinked disable --uninstall [--keep-config] | Destructive teardown: removes hooks + the installed skills and deletes the .interlinked/ config dir — pass --keep-config to keep the config. |
interlinked reset --force | Nuclear: delete the entire .interlinked/ dir and strip hook entries. Irreversible; --force required. |
interlinked uninstall-hooks | Remove only what install-hooks recorded in its manifest. |
A valid stand-down marker suppresses hook self-heal. If
disablereports the old daemon is still running, runinterlinked harness stop: that already-running process may continue to evaluate calls until it exits, but hooks will not resurrect it afterward.
disable is non-destructive by default now — bare disable just stands down; use
--uninstall (or reset --force) for real teardown.clean defaults to dry-run; reset requires --force.uninstall-hooks only cleans an
install-hooks-style install; use disable --uninstall / reset to clean an enable install.enable refuses to install Claude hooks when an ancestor
.claude/settings.json already has them (would double-fire) — run enable from that ancestor..interlinked/ runtime and never borrows a daemon socket from the parent
checkout. Ordinary monorepo subdirectories still discover the nearest ancestor daemon.gemini client installs Gemini CLI hooks/skills; do not treat it as Antigravity..opencode/plugins/interlinked.ts or .pi/extensions/interlinked.js as an Interlinked-owned
whole file; user scope uses ~/.config/opencode/plugins/interlinked.ts and
~/.pi/agent/extensions/interlinked.js. Install refuses to overwrite a foreign file at that
path, and uninstall preserves a bridge whose bytes changed after install. A loaded bridge writes
its provider row to .interlinked/hook-runtime.json, but only Codex currently has a dedicated
doctor trust-verification row. Restart OpenCode after install (its plugin trust is implicit). In
Pi, run /reload or restart and approve the project-extension trust prompt.ask denies; permission bus and session.idle/Stop are observation-only.
Pi prompts through ctx.ui.confirm when interactive and denies headless; user_bash gates
direct shell commands as well as model tool calls. Neither exposes dedicated native MCP,
subagent, or worktree lifecycle hooks. The shared shell rule still blocks git worktree add.reload needs a source checkout — it rebuilds the CLI checkout the running binary
resolves to (typically a ~/.local/bin symlink), not the current repo.--json support is per-command; unknown flags error. doctor takes only --fix/--json.interlinked tests e2e discover --out report.json, review, tests e2e adopt --from report.json (advisory unless --mode required), tests e2e doctor. Discovery proposes; it never accepts inferred behavior.status, activity, logs).© QuentinCody, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 1 other file in skills/interlinked-setup of QuentinCody/interlinked-cli.
Open the folder on GitHubat commit 31b5259
Interlinked Setup next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Interlinked Setup this skillQuentinCody/interlinked-cli | 178 | — | ~14k | Automated safety check: Pass | MIT | |
| It Operationsdavila7/claude-code-templates | 32k | 1 repos | ~3.7k | Automated safety check: Pass | MIT | |
| Operator Approval Loopaffaan-m/ECC | 274k | — | ~3.3k | Automated safety check: Pass | MIT | |
| Business Operations Skillsalirezarezvani/claude-skills | 28k | — | ~2.3k | Automated safety check: Pass | MIT | |
| Startup It Troubleshootingsickn33/agentic-awesome-skills | 47k | 2 repos | ~3.6k | Automated safety check: Notes | MIT | |
| Kubernetes Operatoralirezarezvani/claude-skills | 28k | — | ~2.8k | Automated safety check: Pass | MIT |
davila7/claude-code-templates
Manages IT infrastructure, monitoring, incident response, and service reliability.
affaan-m/ECC
Operator approval contract with internal filing notices for agent-drafted outbound messages, hashed drafts, epoch-keyed decisions, durable delivery claims and receipts, and a pre-draft baseline gate.
alirezarezvani/claude-skills
A skill your agent uses when running, diagnosing, or designing internal business operations — process documentation, vendor SLAs, capacity planning, internal comms, SOP/runbook authoring…
sickn33/agentic-awesome-skills
Practical IT troubleshooting playbooks for small teams without dedicated IT staff.
alirezarezvani/claude-skills
A skill your agent uses when building a Kubernetes Operator — custom controllers that reconcile CRD state.
sickn33/agentic-awesome-skills
AWS cost optimization, monitoring, and operational excellence expert.
QuentinCody/interlinked-cli
Package, test, and operate the experimental Interlinked Cowork plugin.
QuentinCody/interlinked-cli
Overview and router for the Interlinked CLI — a local guard, quality-enforcement, simplification-review, semantic-code-search, and observability layer for AI coding agents.
QuentinCody/interlinked-cli
Coordinate with other agents/humans via the optional Interlinked MCP Server, and use local checkpoints & file reservations.
QuentinCody/interlinked-cli
Investigate agent activity and JSONL/gzip evidence. An agent skill from QuentinCody/interlinked-cli.
QuentinCody/interlinked-cli
Install and operate Interlinked's optional local semantic function index.
QuentinCody/interlinked-cli
Keep prose specs and design docs honest against the code using Interlinked's spec-audit system.
Install, operate, and troubleshoot the Interlinked CLI harness in a repo — install/uninstall agent hooks, connect runners (Claude Code, Codex, Copilot CLI, Gemini, Cursor, OpenCode, Pi)…. Interlinked Setup is an agent skill from QuentinCody/interlinked-cli.interlinked/ config.
Run `npx skills add QuentinCody/interlinked-cli --skill interlinked-setup -a claude-code`. Or copy the skill folder (skills/interlinked-setup in QuentinCody/interlinked-cli) into .claude/skills/interlinked-setup in your project. Claude Code loads it when a task matches its description.
Run `npx skills add QuentinCody/interlinked-cli --skill interlinked-setup -a codex`. Or copy the skill folder (skills/interlinked-setup in QuentinCody/interlinked-cli) into .agents/skills/interlinked-setup in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add QuentinCody/interlinked-cli --skill interlinked-setup -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/interlinked-setup, .gemini/skills/interlinked-setup, .github/skills/interlinked-setup and .opencode/skills/interlinked-setup in your project.
Going by SKILL.md and its folder, Interlinked Setup needs the command-line tools its instructions call (node, git, npm and npx) and credentials named INTERLINKED_TOKEN and INTERLINKED_ACCESS_TOKEN. Our summary lists: Python 3.
SKILL.md contains no URLs. Its commands use git, npm and npx, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Interlinked Setup is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 14k tokens (SKILL.md is roughly 54k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Interlinked Setup: It Operations (davila7/claude-code-templates, 32k stars), Operator Approval Loop (affaan-m/ECC, 274k stars), Business Operations Skills (alirezarezvani/claude-skills, 28k stars) and Startup It Troubleshooting (sickn33/agentic-awesome-skills, 47k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
QuentinCody (a GitHub user) maintains it in QuentinCody/interlinked-cli, which has 178 GitHub stars. The repository holds 12 skills in this directory. The repository was last updated on October 2, 2026.
Source: QuentinCody/interlinked-cli on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.