Landing
alirezarezvani/claude-skills
Generates a premium single-page HTML landing page with 3D CSS animations, GSAP scroll effects, and mouse-parallax depth.
Run interlinked verify, understand the PostToolUse quality checks, and land multi-file edits through the content gate.
$ npx skills add QuentinCody/interlinked-cli --skill interlinked-verify -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install QuentinCody/interlinked-cli interlinked-verify --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-verify .claude/skills/interlinked-verify && 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-verify" agent skill from https://github.com/QuentinCody/interlinked-cli/tree/main/skills/interlinked-verify into .claude/skills/interlinked-verify/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interlinked-verify", 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-verifyType 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-verify -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install QuentinCody/interlinked-cli interlinked-verify --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-verify .agents/skills/interlinked-verify && 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-verify" agent skill from https://github.com/QuentinCody/interlinked-cli/tree/main/skills/interlinked-verify into .agents/skills/interlinked-verify/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interlinked-verify", 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-verify -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install QuentinCody/interlinked-cli interlinked-verify --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-verify .cursor/skills/interlinked-verify && 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-verify" agent skill from https://github.com/QuentinCody/interlinked-cli/tree/main/skills/interlinked-verify into .cursor/skills/interlinked-verify/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interlinked-verify", 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-verify--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-verify -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install QuentinCody/interlinked-cli interlinked-verify --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-verify .gemini/skills/interlinked-verify && 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-verify" agent skill from https://github.com/QuentinCody/interlinked-cli/tree/main/skills/interlinked-verify into .gemini/skills/interlinked-verify/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interlinked-verify", 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-verifyInstalls 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-verify -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-verify .github/skills/interlinked-verify && 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-verify" agent skill from https://github.com/QuentinCody/interlinked-cli/tree/main/skills/interlinked-verify into .github/skills/interlinked-verify/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interlinked-verify", 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-verify -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-verify --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-verify .opencode/skills/interlinked-verify && 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-verify" agent skill from https://github.com/QuentinCody/interlinked-cli/tree/main/skills/interlinked-verify into .opencode/skills/interlinked-verify/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interlinked-verify", 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-verifyRun interlinked verify, understand the PostToolUse quality checks, and land multi-file edits through the content gate.
Interlinked Verify is an agent skill from QuentinCody/interlinked-cli. Run interlinked verify, understand the PostToolUse quality checks, and land multi-file edits through the content gate. Load this when you want to check your changes (interlinked verify — the on-demand whole-project check run), when a preblock check refused an edit, when you need to land a cross-file refactor without transient tsc errors (interlinked write --batch / multi-edit / verify-changeset and the exporter-before-importers rule), when deciding whether a finding is default-gate or advisory, or when you need…
Its SKILL.md is about 23k 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:
npmnpxrgvitestFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use 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 no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Interlinked Verify loads about 23k tokens when it runs. Until then it costs about 183 tokens; SKILL.md has 11,924 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). 11,924 words, ~23,004 tokens.
.claude/skills/interlinked-verify/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.After a Claude session has delivered a native PostToolBatch, declared single-file
edits queue TypeScript checking until that boundary. Related edits in the same model
message are checked against the completed tree, once per project. Existing atomic
multi-file calls retain their shared check path. Other clients, unknown writers, and
Claude sessions that have not demonstrated the boundary keep per-edit checking.
Security, content guards, lint and hard complexity caps still apply per edit.
Final compiler errors arrive as batch context so Claude can repair them; a native batch
block would cancel its loop. Unresolved errors and unavailable compiler work remain
in .interlinked/compiler-batches/ and are checked before Stop and commit, including
after daemon restart. Do not delete this state to bypass verification. A queued edit
has no TypeScript verdict and must not be described as fully checked. Explicit verify
and commit checks remain necessary for the required repository validation scope.
Runner summaries from rg -n/grep -n are recognized with a single numeric line prefix.
A failure in any recognized summary takes precedence over a pass; shell success after
a pipe/trailing command alone still does not prove that tests passed.
repeated_implementation compares same-file Python and JS/TS function bodies by
AST structure, with a minimum of five statements. Tests, generated files, small
delegates and functions containing nested implementations are excluded. This is
conservative structural matching, not proof that two contracts are equivalent.
It names the matching functions and source lines, shows literal values, and suggests
a shared operation when the contracts match. Do not compress lines or automatically
extract helpers to satisfy it. Preserve correctness and independently evolving behavior.
The daemon reports new or changed groups once per session after all files in the
observed tool changeset have landed. Unchanged groups remain in structured check
results. Stop rescans current touched files through the existing digest and repeat-Stop
filter; verify --all-checks reports the full advisory inventory. Default verify skips
this check. It never blocks an edit or Stop and never creates a completion obligation.
A daemon restart can repeat advice. Separate tool calls are separate observed changesets.
Python uses an isolated, bounded python3 AST parser and does not execute candidate
code. Missing parsers, invalid syntax and oversized detector input return NOT CHECKED,
not a clean duplication verdict. Initial scope is whole functions within one file;
cross-file matching and arbitrary repeated sub-blocks are not covered by this check.
On the first authored edit per language/session without a detected test layout,
PostToolUse probes Python/JS/TS/Rust/Go runner readiness and supplies setup/test guidance.
It does not install packages or hard-block absent tests. Inspect custom layouts before
adding public-contract assertions, then execute them. Explicit tests readiness rechecks
changed prerequisites; the automatic probe does not run on every edit.
For Cowork, load interlinked-cowork. cowork verify <workspace> runs only tsc,
biome and gitleaks with before/after workspace hashes; skipped checks remain
unmeasured. It is not the full verify command or a per-edit ratchet. Run configured
repository checks on the filesystem holding the actual version being reviewed.
The optional Bash tsc accelerator recognizes executable tsc / npx tsc
segments in flat, quote-aware command lists. It preserves quoted arguments and
rewrites only the matched invocation. Search patterns, look-alike executable
names, comments, multiline commands, substitutions, and shell grouping fall
through unchanged; run the original compiler normally in those cases.
The file-mode Rust formatter reads the nearest Cargo.toml only within the
project root. A neighboring directory with a shared name prefix is outside
that scope; unreadable manifests are reported instead of guessing an edition.
Python behavioral suites run from the resolved project root; companion filenames are
not a sound dependency boundary. Directory-name prefixes never establish confinement.
Missing-companion guidance describes a naming-convention observation, not proof of missing
behavioral coverage. Inspect the project's test layout before adding language-appropriate
public-contract tests.
Interlinked gates edits at three moments, and they run different check sets:
pre_block checks
without synchronously launching biome/tsc on the daemon event loop; those external overlays
are recorded as scheduled for applicable file types and run asynchronously after
the write. Routine scheduling produces no model warning; unavailable or failed checks still
report NOT CHECKED. Python/Go/Rust edits do not receive JS/TS overlay scheduling. Transactional CLI
paths (interlinked write / verify-changeset) still run pre_block → biome → tsc and fail
closed. interlinked multi-edit uses the same shared content gate.PostToolUse keeps full findings in the check-results ledger while presenting compact diagnostics. Repeated advisories are acknowledged per session, check and file; a successful scoped recheck clears that acknowledgment. Pre-existing TypeScript findings show a count and the evidence path. "Newly observed" means changed since the previous compiler report, not proven caused by this edit. Changes observed outside the tool's declared write targets are labeled "writer unknown"; TypeScript findings there are workspace feedback and do not block the observing call. Security checks and workspace obligations still apply.
For test evidence, a recognized runner summary can establish the outcome of a piped run. An unsummarized pipeline's final exit code alone cannot prove the test process passed. For scratch probes, reading a repository file and writing an unrelated temporary fixture does not establish a patch applier; the guard checks statically resolved write destinations. Unknown destinations still rely on filesystem observation after execution.
interlinked verify is the on-demand, whole-project run of that same check catalog.
Its function_tokens finding uses the shared interlinked-code-v2 adapters and reports every current
product-source implementation over the effective cap. Unsupported languages are reported as
not measured; semantic-model token counts are unrelated and never substitute for this check.
JS/TS counts match metrics score function size, edit gates and commit checks. Recovered source
syntax remains unmeasured. Verify is an inventory of current over-cap functions; edit/commit
ratchets separately allow existing debt to hold or shrink, including debt revealed by migration.
Explain that size unit as syntax tokens (lexical tokens); AST-node counts and embedding
model tokens are different units. metrics score is an advisory composite, not a replacement
for verify or the hard cap. A provisional score does not prove checks passed. Use
metrics gates --json for actual coverage execution/freshness and metrics coverage status
for index validity. metrics coverage warm explicitly runs full Vitest coverage; subsequent
per-edit runs can replace affected test-file contributions. Proposed evidence promotes only
after the matching edit lands, and unsupported/stale capture remains visibly unmeasured.
Route evidence receipts, incremental coverage setup and deletion trials to
interlinked-quality-gates.
When editing a hook entry, adapter, daemon, installer, generated hook, or ledger
writer identified by src/harness/e2e-boundary.ts, add or run a fixture-backed
test: npm run build:e2e && npm run test:e2e. Fixtures own their cwd, sockets,
daemon PID and ledgers. Daemon assertions require a fresh transport receipt
with outcome: "daemon", plus PID ownership; cold fallback is a separate case.
interlinked e2e scaffold <name> --event PreToolUse --tool Edit creates
src/e2e/<name>.e2e.test.ts. --dry-run prints it. Replace the deliberate
failure with the required behavior and add MUST-NOT-FIRE cases.
npm run test:e2e:coverage collects child coverage after build:e2e.
Route ratchet refusals to interlinked-quality-gates.
The advisory [interlinked:e2e-obligation] Stop warning credits only commands
observed in the current session. Run the lane from that session; another
agent's run, a terminal run, and unit-only evidence do not satisfy it. The viz
feed labels base, unit, integration, e2e and unknown lanes separately.
E2E_STABILITY=1 npm run test:e2e adds the 5,000-event stress case.
A repository with .interlinked/e2e-policy.json declares projects, suites
(managed-contracts: argv prepare steps, build artifacts), scenarios
(affects globs, contractIds from .interlinked/behavioral-contracts.json,
required, boundary) and expectation records. Only that policy creates
obligations; a repository without it pays nothing.
[interlinked:e2e] <project>: <scenario> needs current e2e evidence after <path> changed fires on any observed edit to a mapped input (Edit, Write,
Bash, patch). Run the exact command it prints:
interlinked tests e2e run --project <p> --scenario <s>.
needs-mapping means a protected input has no scenario. Add it to a
scenario's affects; do not delete the protected glob.
tests e2e status / plan inspect (exit 0). tests e2e check verifies the
working tree (exit 0 satisfied, 1 open requirement or measured failure, 2
UNCONFIGURED / unavailable). tests e2e run prepares, drives the public
executable in a disposable workspace, writes
.interlinked/test-runs/e2e/<runId>/receipt.json and appends to
.interlinked/e2e-obligations.jsonl.
A receipt satisfies only its exact generation: policy digest, affected
files, the contract manifest and acceptance file, each case's cited
requirement document, declared inputs and the bytes of any path-shaped
executable the case invokes. Another relevant edit makes it stale; a
failed case is failed; a missing toolchain, a failed prepare step, an
input the collector could not capture (over 8 MiB, a symlink) or a receipt
that does not parse strictly is unavailable; an unaccepted contract is
review-required even when execution passed. A receipt from another
worktree or with a runId the ledger never recorded is RECEIPT_MISMATCH.
Every run copies the project into a disposable snapshot first; prepare steps and cases execute there with a private HOME. The live tree is only read. Compiled executables are copied byte-for-byte with their mode.
Boundaries: entry: "process" (real: ["application"]), entry: "http"
driven through a suite-OWNED services entry (the supervisor allocates the
port, proves readiness and clean shutdown; a port that still answers after
stop belonged to something else and the run cannot qualify), and entry: "browser" for a playwright suite (the app is owned, fronted by the
supervisor's recording proxy, and every declared requests entry must be
observed through it — a health check or an intercepted API earns nothing).
A literal-URL case is never a boundary.
A bound PROPOSED expectation is visible as an advisory (~ line) and does
not block completion unless the project sets gates.review: "require".
Disputed and superseded bindings always block.
The loop for a new behavior: tests e2e scaffold <name> [--suite <id>] [--write] prints a proposed scenario (required: false, empty affects,
a placeholder contract id) and a skeleton whose only assertion FAILS
deliberately with every assumption marked ASSUMPTION / REPLACE. Replace
the assumptions with the observed outcome, add the scenario to the policy
yourself (the command never edits it), tests e2e run, then tests e2e qualify --scenario <id> for a stability cohort, then tests e2e check.
A deliberate failure is CASE_FAILED, never a pass.
Completion gates judge EXACT bytes, never "the repository": tests e2e check --staged judges the index (an unstaged fix does not count),
--revision <rev> an exact commit; both are materialized from git's object
store (no archive attributes, no smudge filters). --base <rev> compares
the judged policy with the trusted base's: a removed/demoted requirement,
a loosened gate (an omitted gate is its default: commit/ci require), a
narrowed affects, an unbound contract, a dropped proof/request/stability
profile is POLICY_WEAKENED (exit 1). The reviewed path is tests e2e policy replace --base <rev> --project <p> [--scenario <s>] --rationale "<why>"; the record is read from the judged target, so COMMIT
.interlinked/e2e-policy-changes.jsonl (carve it out of .gitignore).
Never "fix" a weakening by editing gates in the candidate: the candidate's
own gate setting cannot waive POLICY_WEAKENED.
tests e2e gate install writes pre-commit (check --gate commit --staged --base HEAD) and pre-push (one check --gate ci --revision <sha> --base <remote sha> per ref) hooks that CHAIN with existing hooks and only CHECK;
gate uninstall restores the originals. A blocked commit or push prints
the exact recovery command: run it, do not bypass the hook.
tests e2e ci [--base <rev>] [--revision <rev>] exports the candidate
COMMIT into a disposable directory with empty execution state, runs every
plain scenario and every stability cohort there and checks the export
against the event base. Workstation receipts, cohorts, untracked fixes and
local records never count (CI_RECEIPT_NOT_FRESH); preparation steps must
provision dependencies. Evidence lands in .interlinked/test-runs/e2e/ci/<commit>/.
The Stop reminder is bounded: three identical reminders, one pause note,
silence until the open set changes; an all-unavailable set is a HANDOFF
(do not retry in a loop); with the daemon down it says NOT CHECKED.
interlinked verify prints the same verdict in its e2e section.
The operator guide is docs/project-e2e.md (schema, codes, targets,
gates, CI, proof limits, recovery table).
[interlinked:e2e-quality] <project>/<scenario>: <rule> at <path>:<line>
is advice attached to the scenario a test edit affects (§12.3): a removed
assertion or test block, an added .only/.skip, a specific matcher
replaced by truthiness, a raised timeout/retry budget, force: true, a
fixed timing wait, a CSS/XPath locator, an intercepted application
endpoint, or a new test with no assertion. Net-new only (a moved line is
not a signal); it never changes the verdict — the scenario still clears
only through a supervised run.
A playwright suite owns its application as a services entry; the run
fronts it with a recording proxy (INTERLINKED_E2E_BASE_URL is the proxy)
and forces --reporter=json --workers=1. A browser case earns the
browser-driver boundary only when the proxy saw its requests inside the
case's first attempt; @playwright/test absent in the project is
unavailable with install guidance (tests e2e doctor names it too), never
an install.
Expectations: tests e2e expectations propose --from draft.json records an
agent-authored statement with sources, assumptions and questions as
proposed. accept --from decision.json binds the exact revision
digest and records the linked contract digests as configured acceptance
(a local decision, never authenticated human approval). replace supersedes
with rationale and invalidates affected receipts; review lists questions,
source provenance (matched / stale / unavailable) and diffs. Keep
unresolved product questions in questions; do not turn an inference into
a hard requirement.
Adoption workflow for a repository with no policy yet (all read-only until
adopt): tests e2e discover --out report.json inspects manifests, build
and test commands, executables and existing contract cases, proposes an
ADVISORY policy with one scenario per process-runner case, and lists gaps
(no contract cases, ambiguous nested manifests, unsupported runners).
Review the report, then tests e2e adopt --from report.json [--project <id>] [--scenario <id>] writes only the selected configuration; --mode required must be explicit and expectations in a proposal are always
dropped. --replace is required to overwrite a policy (discarded, not
merged). tests e2e surfaces [--write] inventories bins, scripts and
OpenAPI JSON operations and shows which scenario surfaceIds bind them
(explicit / unresolved / dangling); YAML documents, routes
registered in code and unresolved $refs are reported as limits, never as
an empty complete inventory. An interface no extractor knows is declared in
the project's surfaces list ({"id": "cli:custom", "kind": "other", "address": "…"}) and bound through a scenario's surfaceIds; that is the
language-independent path. Discovery protects the real layout (src/**,
python packages, top-level source files, the executable's file) and binds
build scripts as shared inputs; a build whose outputs it cannot infer is a
suites[].artifacts gap to resolve before --mode required, which refuses
a project with no scenarios or with protected globs that match nothing.
Depth-omitted subtrees are listed in the report's limits.omittedSubtrees.
tests e2e doctor diagnoses policy, manifest, contracts,
acceptance, toolchain, mapping, ledger and receipts without running anything
(exit 1 on a failed prerequisite, 2 on an invalid policy). Configuration
alone never produces a pass; the next step is always tests e2e run.
Shipped: managed process contracts for any language with a build/run argv
(TypeScript and Python validated locally; the Rust fixture's compiled route
waits for a Cargo-equipped runner), the discover / surfaces / adopt /
doctor adoption workflow, structured-runner suites (JSON protocol / JUnit
report import), owned loopback HTTP services with service-bound contracts,
and per-scenario proof modes (proof {mode: old-new | controlled-fault | characterization}). A counterfactual proof names its designated cases as
{id, outcome?, action?}: outcome lists the observables that ARE the
designated outcome (the case's other declared observables must hold on the
comparison side), action lists cases that must pass there first. Without
that declared evidence the supervisor cannot tell a setup failure from a
behavioral red, so it reports INCONCLUSIVE; output presence, exit codes
and status classes never count as evidence. Scaffolding, browser runs,
repetition cohorts and git/CI gates are implemented as described above.
Automatic conversion of existing tests into proposed contracts remains planned;
the MCP/Worker profile remains an explicit release gap.
Jev evaluations are internal experiments, separate from public verification and
Stop hooks. Do not recommend interlinked jev or jev.enabled to users.
For authorized internal evaluations, see docs/internal/jev.md. The runner
sends selected evidence to TypeSafe; its findings are advisory, not gate evidence.
pre_block check blocked an edit (see also interlinked-harness for how blocks read).tsc errors.interlinked verifyinterlinked tests contracts import <source> --json prints proposed cases from explicit
json interlinked-contract fences; it never executes or accepts them. Each fence is a
JSON object with id, description, inputs (literal project-relative UTF-8 files),
runner: {kind: "process", argv: ["python3", "main.py"]} and
expect: {exitCode: 0, json: {message: "ready"}}. Import records source path/hash/quote
and ties expected observations to that exact example. Save selected cases in a
version-1 cases manifest at .interlinked/behavioral-contracts.json (or use --file).
inspect --json reads provenance; run --timeout 60000 --json explicitly executes the
selected runners and records per-case receipts under .interlinked/contract-runs/.
run --previous <manifest> also tests retained prior expectations against current code.
Process cases use a disposable workspace containing declared inputs and already installed
tooling. This is not an OS sandbox. External state is unsealed, so historical passes are
not reused as current verdicts. HTTP cases use a literal loopback HTTP URL, GET/POST,
no redirects, and exact text/JSON/status/header expectations. Comparisons do not normalize
string values. Missing tooling, stale inputs, conflicting citations and budget exhaustion
are separate from a measured failure. A source citation alone does not prove semantics:
use source.observation: json|stdout|contract-example for exact example binding.
Accepted case digests belong in operator-owned .interlinked/contract-policy.json,
{version: 1, accepted: {"<digest>": "rationale"}}. Never self-approve a proposed case.
configured describes that file, not authenticated ownership; protect it outside agent
write authority when required. Intentional replacements need rationale and changed
requirements. replaces: {id, reason} does not automatically grant acceptance.
Post-edit [interlinked:test-contract-review] is bounded, deduplicated advisory guidance
about new/changed expectations, fixtures or collection settings. Review expectations
against user requirements before adapting them to implementation output. No automatic
runner execution or Stop repair loop is added. See
docs/plans/behavioral-contract-verification-20260916.md for schema and scope limits.
interlinked tests readiness <language> --cwd <project> --json probes prerequisites for
Python, TypeScript/JavaScript, Rust and Go without collecting tests or installing packages.
Python names the selected interpreter and reports exact approved install argv when possible;
an absent runner or coverage plugin is unavailable evidence. Provision within the existing
authorization boundary, then rerun readiness and execute the tests. There is no system-Python
fallback around a broken selected environment.
At a meaningful change boundary, interlinked tests review [paths...] --base HEAD --json
provides a bounded source/test inventory and at most five simplification candidates. Without
paths it discovers staged, unstaged and untracked Git changes. It reads at most 32 source/test
files of 256 KiB each; deletions, unsafe paths and exhausted budgets are explicit gaps. This
is review guidance, not test execution or a passing verdict. Retain executable assertions for
old public contracts and new requirements; review validation ownership, duplication, forwarding
and shared mutable state together. After behavior passes, one focused simplification pass is
enough; rerun relevant tests after changing code and leave uncertain advice unresolved.
interlinked tests suite <language> --cwd <project> --timeout <ms> --json explicitly runs
a bounded project suite for typescript, javascript, python, rust or go. The default
budget is 60 seconds including admission. TS/JS use the shared Vitest scheduler; Python uses
the active VIRTUAL_ENV, then project .venv/venv, then platform Python (an explicit
adapter interpreter takes precedence). A selected missing interpreter is unavailable;
it never silently switches environments. Rust uses offline Cargo
with two jobs/test threads; Go runs all packages with two build jobs and caching disabled.
No runner is installed automatically. Python retains project pytest options and configured
discovery (testpaths, python_files); the invocation does not append an implicit ..
Fresh structured pytest case reports distinguish test failures from collection/configuration
errors and coverage-plugin failures. Fixture and teardown failures count as failed tests.
Known failures remain visible alongside incomplete collection; bounded diagnostics accompany
unavailable results. Terminal text alone is not a pytest verdict. Only an observed passing suite exits successfully;
missing/empty execution is not a pass. tests plan/run/status remain the TS/JS dependency-aware
queue interface; the non-TS suite command does not certify or discharge that queue.
Active distributed pytest collection is currently unmeasured. Serial execution remains
supported when xdist is installed but inactive; no plugin is silently disabled to obtain a pass.
The default Python edit/commit coverage runner isolates each invocation's JSON report and
coverage.py database (COVERAGE_FILE) in an owned temporary subdirectory of the requested
report directory. Normalized results survive; those temporary files are cleaned after parsing,
including failure paths. Project cwd and pytest configuration remain in effect, and existing
caller coverage files are preserved. Custom command overrides retain their argv/report contract
and remain unqualified for concurrent report isolation and structured red/green verdicts.
Python CRAP attribution requires native function regions with declaration lines; unsupported,
ambiguous or wholly excluded functions remain explicitly unmeasured. A green suite with an
unmeasured enabled quality check does not discharge commit obligations. See the quality-gates
skill for the native coverage.py/Radon attribution contract.
For evolving requirements, distinguish newly required observable behavior from contracts that should remain valid. Exercise representative successful, boundary, error and state-transition cases from the public task before concluding the implementation is complete. Existing passing tests can all remain green while the new feature is largely missing. Keep this proportional to the change; do not create a mandatory test-authoring loop for trivial reversible edits. Hidden evaluator cases are unavailable to product checks and must not shape harness rules.
Heavy runners retain at least the configured 2 GiB admission budget plus the host reserve; the proportional ceiling does not reject an otherwise idle nominal 8 GiB Linux guest merely because its reported usable RAM is slightly smaller. Insufficient available memory still defers.
The proposed qualification baseline is an 8 GB whole host shared with the user's
other applications. Its operator plan, docs/plans/8gb-host-resource-plan.md, is private
operator material and absent from public clones. Qualification requires aggregate measurements across owned
processes and useful completed checks, not merely successful resource deferrals. It does
not change today's verification contract: interrupted or partial work remains unmeasured,
and a constrained run cannot satisfy a required full scope by selecting fewer tests.
Cognitive-complexity, type-smuggling, and cast-justification diagnostics align snippets with TypeScript's line numbering, including CRLF, lone CR, and Unicode line/paragraph separators. Preserve those line endings when reproducing a warning; normalizing a fixture can hide a location bug.
For [interlinked:hook-coverage] NOT CHECKED, use interlinked harness coverage verify --json. This starts one daemon-owned recovery run over the pending versions and waits
for completion; --no-wait returns after starting it. Use harness coverage status --progress --json for cached progress: it reports generation, observation time, pending
count and job counters without rehashing files or returning historical receipts. This
is not a fresh coverage verdict. The waiting CLI uses this compact path and fetches a
fresh full status before reporting completion; it still accepts older daemons that
return full reports. Use plain harness coverage status --json for an explicit refresh,
pending identities and full receipt details. Checks reuse the configured PostToolUse battery in bounded
external batches. This does not replay PreToolUse guards or certify every hook phase.
While waiting, an unavailable status response is retried up to three consecutive
polls without restarting verification. A responsive report resets that counter.
Persistent unavailability exits nonzero with the original reason; the job may still
be running. Only a ready response with a missing or different job establishes that
the observed job changed or disappeared.
On Claude and Codex Stop/SubagentStop, advisory coverage feedback stays on exit-0 stderr and
does not request another agent turn. Only an explicit blocking decision requests
continuation. This delivery rule does not clear pending evidence or certify checks;
retry unavailable recovery after its prerequisites change, not merely because a
turn ended. Writer identity remains unknown after recovery.
An initially absent watched path contributes to policy identity but creates no write-check
obligation. Creation or deletion after observation still requires evidence; previously
recorded historical gaps are not cleared by this rule.
Recovery groups pending files by project and applicable checks, then checks up to 32
compatible files together. Documentation does not inherit an unrelated source-test
timeout, and nested projects acquire their own admission lane sequentially. Each
recovery related-test process gets at least 15 minutes and at most two workers, with
the complete union of related tests for up to 32 sources. This reduces repeated broad
suites without selecting a passing subset. Ordinary hook deadlines and source-count
limits remain unchanged; recovery still defers honestly on capacity or timeout.
Explicit recovery now waits up to 30 seconds for each external batch's existing project lease. Its affected-test scheduler waits within the configured recovery deadline and permits a necessary full-suite plan without the interactive test-count cap, retaining the two-worker limit. Ordinary PostToolUse still uses immediate admission and its test-count cap. Unsupported runners and exhausted capacity/time remain unmeasured; the shared named test dispatcher supports TS/JS with Vitest and single-language Python/pytest, Rust/Cargo, and Go project suites. Mixed-language batches remain explicitly deferred. Python no longer guesses one companion file, Rust executes assertions instead of only compiling tests, and Go covers the project packages. These project suites produce fresh execution evidence, not reusable dependency-closure receipts. Missing runners, empty/unrecognized successful output, and pytest collection/configuration errors are unmeasured. Current non-TS suite failures are warnings; without a before result they are not classified as introduced regressions. The external path cap applies separately to each check's applicable paths in the selected project. An inapplicable binary path does not consume a TypeScript check slot; an applicable security target still counts. This is not a blanket dependency/cache exclusion.
The daemon retains automated_check receipts with exact file identities, completed check
names and findings. Completed checks may have findings; a receipt is not a clean verdict.
Nonempty unavailable on a receipt means partial evidence: completed checks and their
findings are retained, but the file version stays pending. Multi-file per-file checks retain
partial receipts when shared checks defer. Shared receipts include per-check configuration
hashes and the request's captured file identities. File or policy changes prevent full discharge.
Legacy receipts
remain readable. These historical receipts are not yet a cache for skipping future work;
check-specific configuration/dependency/runtime identities and exact batch scope are still
required before safe reuse.
Ordinary single-file and multi-file PostToolUse checks consume their exact pending versions
when all applicable evidence completes without deferral. Explicit recovery uses the same
shared scope evidence. Recovery has a 30-minute job budget; cancellation reaches the job's
owned asynchronous subprocesses and capacity waits. Earlier recorded evidence survives.
Unavailable checks, unreadable/excluded/absent files, and file or policy changes during
verification stay pending. With waiting enabled, findings or remaining pending versions
produce exit 1. Re-run after the reported capacity/tool problem is resolved. A daemon
restart interrupts the job; recorded receipts survive and unchecked entries remain pending.
Active recovery keeps the raw and framed listeners out of idle shutdown and delays
automatic build handover within its normal freshness deadline. Explicit restarts and
memory safety shutdowns still interrupt recovery; inspect status and retry afterward.
Released reservations remain watched while pending, so review cannot acknowledge a stale
historical hash. harness coverage acknowledge <id> <generation> <identity> <evidence>
records an explicit manual review of the current version, including a reviewed deletion or
optional absence. It does not manufacture automated evidence. Do not bulk-acknowledge
unreviewed files. Checking/reviewing files never accepts protected policy; that is the
separate harness coverage accept-policy <digest> operation. Writer identity stays unknown.
interlinked verify [target]
--all-checks add the advisory smell/complexity/dead-code tier to the default gate
--only <tool> run only one external tool (e.g. --only tsc)
--skip <ids> comma-separated check ids to skip
--suggestions also run scored regex heuristics (sql-injection/perf/quality)
--structure also run artifact-structure checks
--adoption-gate fail when adopted structure categories drop below thresholds
--suppress <e...> add a suppression (file:check or file:check:reason)
--json --details machine-readable / per-file detailtarget may be a local path, a GitHub/git URL (cloned to a tmpdir, scanned, deleted), or
omitted (scans cwd). Narrow with --subdir <path> in monorepos.
Two tiers. Default = high-signal gate: tsc, biome, oxlint/eslint, semgrep, gitleaks,
dep-audit (+ language tools as available) plus the FP-safe inline checks. --all-checks
adds the advisory tier (complexity, taste/smell, DRY clones, most ubs_*, test heuristics) —
a review tool, expect noise, not a gate.
interlinked verifyexits 0 even with findings. It is a reporting tool, not a pass/fail gate — do not&&-chain on its exit status. To gate programmatically, parse--json, or useinterlinked write/verify-changeset(which do exit nonzero on blocking findings). (Exceptions that do exit nonzero: usage errors, and--structure-only/--adoption-gate, or a deferred/unavailable run that produced no verification verdict.)
Whole-project heavyweight work is admitted once per canonical project across CLI and agent
processes. If another verify/check/test batch already owns that lane, verify does not queue or
start a second memory-heavy scan: it prints verify deferred, states that no verdict was
produced, and exits 1. Retry after the active project run finishes. Different project roots use
independent lanes, and the compiler has a separate nested lease so --only tsc can run while
verify owns the heavyweight lane. --only <tool> really runs only that external tool; it skips
the inline code-quality census rather than retaining the whole-project scan before the requested
tool.
SessionEnd maintenance, fuzz, and benchmark runners additionally share a host-wide background lane owned by a detached supervisor. Duplicate jobs coalesce across daemon restarts; other jobs wait at most two minutes. Memory admission can defer a job, and low memory or a ten-minute deadline terminates the child group. Fuzz/benchmark worker counts are bounded by current CPU and RAM capacity and rechecked before execution. A deferred or interrupted background job is not a successful verification; use current completed reports and explicit checks for a verdict. See interlinked-setup for the memory budget and its limits. Scheduled Vitest runs and verify also acquire this host lane. Foreground requests close background admission while waiting; the background monitor interrupts its child group to yield capacity. Verify waits at most five seconds for the host lane, then exits 1 without a verdict.
Scheduled foreground test execution now checks host memory and runner-tree RSS throughout
the run. Its 4 GiB maximum tree budget includes workers; a sampled overrun, lost headroom,
or unavailable telemetry interrupts the process group and retains the request without a
pass receipt. Worker planning reads current CPU load as well as available memory. These are
sampled limits; see interlinked-setup for process-group and platform limitations.
Repository pre-push checks use the same admission lane and monitor. Do not respond to a
resource deferral by launching the full suite directly. Small checks can use the repository's
scripts/run-resource-bounded.ts --light supervisor with an enforced 1 GiB tree ceiling;
this does not replace required full verification.
Public interlinked verify and interlinked tests commands have an outer resource supervisor
as well: in-process planning/scanning is measured along with the runner tree. This supervisor
does not acquire a second host lease; the actual command keeps its existing admission protocol.
Memory interruption exits 75 without a verification verdict, even if partial output was printed.
Exit 75 alone cannot say what happened — admission that never happened, a child killed
mid-run and a child that itself exits 75 all surface as 75 — so the bounded runner
(scripts/run-resource-bounded.ts, used by every pre-push gate step) writes a VERDICT
record to INTERLINKED_BOUNDED_OUTCOME beside its status (2026-09-28): not-run
(capacity timeout, memory budget unavailable, or cancelled while waiting; stderr
[resources] NOT RUN: … with the wait), interrupted (started, then killed or timed
out; [resources] INTERRUPTED: …), or exit (ran to completion; the child's own code,
including its own 75). The pre-push hook reads the record: not-run prints
[pre-push] NOT RUN (host capacity or memory unavailable; nothing failed): <command>,
interrupted prints [pre-push] INTERRUPTED (killed or timed out; no verdict): <command>,
and only exit (or a missing record) prints <gate> failed. The stage ledger row carries
the matching reuse_denied_reason. The push is blocked in every non-zero case — nothing
was verified — but only a real verdict names a failed gate.
The daemon's async project test gate and legacy affected-test process adapter also acquire
the shared host lane, even when their caller already owns project admission. They monitor
the runner tree and host reserve, set a 768 MiB Node heap limit, and pass
VITEST_MAX_WORKERS=1 to prevent a second uncapped Vitest suite during a push. The current
Vitest adapter honors that variable; other runners still use their own worker controls
and remain subject to the memory monitor. Capacity loss is an explicit deferral.
Repository pre-push heavy commands wait at most ten minutes for that shared lane;
light diagnostic commands wait five seconds. This serializes an existing daemon push
check with the exact-revision repository gate without skipping either check.
interlinked tests plan --base HEAD --json
interlinked tests run src/lib/config.ts --workers 2 --timeout 120000
interlinked tests status --json
interlinked tests run --all --timeout 3600000Paths are relative to --cwd (default cwd). With no paths, plan/run include staged,
unstaged, deleted and untracked inputs relative to --base (default HEAD), plus pending
requests. --all works without Git and asks the native runner for its full suite.
Plan loads the project's Vitest configuration in a bounded child but runs no assertions.
Status returns pending inputs and the last observed job ID, PID, snapshot and state; a
retained running observation is not proof its owner is still alive.
The TypeScript/Vitest hook paths use this same union: edited tests, static transitive
consumers, colocated and __tests__ companions, declared inputs, and historical coverage
consumers. Estimates use existing per-shard durations and otherwise say unmeasured.
An opaque test runs on any input change; shared opaque setup/configuration, unknown/deleted
inputs, incomplete discovery or an explicit full request widen to the full suite.
Named/multiple Vitest projects currently use native full execution rather than selective
indexing. Python/Rust/Go retain their existing dispatchers; mixed-language batches defer.
Selection is measured in CI before it decides anything (Unit 8, comparison mode). The
select-compare job plans against the event's base (scripts/ci-select-compare.mjs select,
base from the shared resolveCiBase) and runs only the must-run files (run-selected, which
refuses an empty list: vitest run without filters runs everything). The full unit and
integration lanes upload their vitest JSON reports, and select-compare-report writes one
row per run: SELECTION_MISS when a file failed in the full lanes but was in the plan's
omitted set; widened when the plan omitted nothing; incomplete when a lane, the
selection or the selected run left no report (a miss already seen still reports as a miss).
Neither job is a required check and neither fails on a miss. Promotion needs zero misses over
at least 30 rows that are SELECTIVE and complete; a widened row proves nothing. Measured
2026-10-01: every plan on this repository widens, because vitest.config.ts and the setup
files read process/Date (opaque by the input-eligibility rule) and __fixtures__/ files
read as unknown inputs, so expect widened rows until that changes.
Optional .interlinked/test-dependencies.json declares additive literal inputs:
{"version":1,"tests":{"src/cli.test.ts":["src/templates/config.json","dist/index.js"]}}Declarations never make uncontrolled I/O cacheable. Exact passing-result reuse is limited
to plans without uncertain dependencies and requires matching source/scope, captured runtime
bytes, runner/dependency/configuration inputs, platform/environment and worker count.
Opaque plans run fresh without the expensive reusable-evidence census. Their results say
runtimeVerified:false: the runner completed and the scheduler checked analyzed source
stability, but no exact runtime or coverage verdict exists. A failed bounded runtime census
also disables reuse and widens selection. No runtime values are persisted in receipts.
Failed, interrupted, missing-report, all-skipped and empty runs never create passing receipts.
Edits during execution trigger another plan; stale evidence cannot clear pending work.
For Python, check prerequisites in the selected project interpreter after creating a
venv. System pytest/coverage packages are not available in an ordinary isolated venv.
interlinked tests readiness python --json reports that distinction; install approved
test tools there rather than silently switching interpreters. Explicit test-first
enforcement requires the first companion even when the repository starts without tests.
Requests coalesce across nearby edits and identical in-flight subscribers. Cross-process
leases serialize execution. A waiting process can consume its request's completed result
after rechecking source, declared/requested inputs, environment and platform; exact-runtime
results also require a fresh matching runtime census. This request-specific sharing is
distinct from reusable passing-result caching. Hooks defer immediately when another process occupies capacity,
while explicit CLI runs wait within their deadline. A subscriber's timeout does not cancel
another caller's shared work. Durable requests survive timeout and process restart. The
queue reads at most 1,000 requests per batch and continues draining later batches.
A passing run is certified by a RECEIPT keyed by its CHECK IDENTITY (2026-09-28,
src/harness/check-identity.ts): the plan snapshot and runtime hash (inputs), the logical
runner argv (mode, workers, --coverage, extra reporters), the toolchain (node plus the
installed vitest and typescript versions), the normalized environment, the platform and
the POLICY digest (.interlinked/coverage-baseline.json, coverage-edit-baseline.json,
metric-caps.json and every vitest*.config.* at the root). Changing any dimension is a
new check: a raised coverage baseline re-runs the same tests. The environment component
drops ONLY variables proven not to reach a verdict — the shell's cwd bookkeeping (PWD,
OLDPWD, SHLVL, _), git's hook-only variables (GIT_EXEC_PATH, GIT_PREFIX,
GIT_CONFIG_PARAMETERS) and this route's own bookkeeping (INTERLINKED_STAGE,
INTERLINKED_STAGES_LEDGER, INTERLINKED_BOUNDED_OUTCOME, INTERLINKED_LEASE_ANCESTORS,
INTERLINKED_COVERAGE_SCOPE_FILE, INTERLINKED_TEST_CAPACITY_SCOPE); PATH, toolchain
paths, CI, NODE_ENV, NODE_OPTIONS, TMPDIR, every other INTERLINKED_* and any user
variable stay in the hash because a test may read them. The child still receives the exact
environment, and the shared-completion path keeps the exact hash. A full run is reusable
evidence only when every closure resolves inside the inventory and nothing is untracked: an
opaque test (dynamic import, process, fetch, the clock, an external fixture) or a test
outside the inventory makes the run fresh-only, because hashing repository bytes cannot see
what those tests read; an opaque SHARED setup or configuration file (it runs in every
test) makes every run fresh-only, selected or full, changed or not. A reporter module run
from outside the checkout (--coverage-reporter) is bound by the digest of its bytes and
of every dependency it loads. Loads are read from the PARSED source (a specifier that is
not one string literal — import("./x" + ext), a template — is a computed load, never a
prefix match), and each is resolved by its OWN loading mode from the importing module's
location: require("x") by CommonJS rules, from "x" / import "x" / import("x") by
ESM rules (a conditional exports map is read under the import condition, so the entry
Node executes is the entry that is bound; a relative ESM import must name an exact file).
A dependency inside node_modules is bound by its COMPLETE installed contents plus,
transitively, the installed contents of every package it declares (a version pins
nothing — an edited internal helper is a different reporter). A computed load, an
unparseable or unresolvable module, an exports shape the resolver does not model
(patterns, arrays, an unexported subpath), a declared dependency that is not installed,
or a closure over 400 files is UNRESOLVED. And the reporter obeys the SAME
input-eligibility rule as a test or setup file, and so does every installed code file of
a bound package (declaration files never run): a module that names a runtime read the
bytes cannot pin — process, fetch, Date, Buffer, timers, require/createRequire,
import.meta, Math.random, eval — or imports a builtin OPERATION that is not pure is
OPAQUE, because complete module hashing cannot cover external data, network responses,
the working directory or the clock. Purity is per operation, never module-wide: whole
modules only where every export is pure (node:assert,
node:string_decoder, node:querystring, node:util/types); otherwise named imports
from a short list (path: join, basename, dirname, extname, normalize,
parse, format, isAbsolute, sep, delimiter; url: fileURLToPath, URL,
URLSearchParams; util: format, inspect, isDeepStrictEqual, promisify,
inherits, types). Imports from node:buffer and node:events are opaque:
File defaults its timestamp from the clock, unsafe buffers expose untracked memory,
and EventEmitterAsyncResource captures async context. Global Buffer is opaque too.
path.resolve and path.relative read the working directory,
url.pathToFileURL resolves through it, and a default or namespace import of any
listed-by-name module reaches them, so all of those are opaque. Unresolved or opaque, the
run executes, exports its artifacts and certifies nothing reusable. CONSEQUENCE:
scripts/pre-push-coverage.mjs reads process.env and walks src/ through node:fs
to ask the coverage provider for its inclusion scope, so every pre-push coverage run is
fresh-only today; a coverage run without an external reporter (vitest's own json-summary)
reuses across a byte-identical export. Re-establishing reuse for the scope needs the
inclusion decision computed OUTSIDE the run (the provider's include/exclude globs
re-evaluated deterministically), not a more permissive rule. Every identity input,
the reporter binding included, is re-read after the run: a change between hashing and
execution is stale and certifies nothing. In THIS repository nearly
every test is opaque, so full-run receipts are not produced here today. A subscriber that
shares a run but owns a different receipt store gets the artifacts materialized into its
own store (sha256-verified), so its export never depends on the producer's store. Receipts are v2 (identity, platform, toolchain,
stages, optional artifacts), unsigned and local; a v1 receipt is ignored.
interlinked tests run --all --coverage [--coverage-reporter <module>]… [--receipt-store <dir>] [--artifacts-out <dir>] collects coverage (json-summary) INSIDE the run directory of the
receipt store, records the summary and the inclusion scope (scripts/pre-push-coverage.mjs
as the reporter; without explicit targets it records every src/ code file, so the scope
serves any later changed-file set) as sha256-pinned artifacts on the receipt, and copies
them into --artifacts-out after a passing run — fresh or reused — refusing any file whose
bytes no longer match, and RE-ROOTED to the consuming checkout (the scope's root and the
summary's file keys name the run's absolute root; a reused run may come from another export
of the same bytes). The receipt's artifactRoot retains the source root even without a
scope reporter. Export relocates JSON path fields after verifying the stored bytes;
receipts containing artifacts but missing this root are ignored. Exit 1 is a failed run;
75 is deferred/stale (no verdict). A request
that needs coverage coalesces only onto a request that produces it, a batch produces what
every pending request requires, and a completion discharges only the requests whose
requirements the run met — a plain run never satisfies a coverage subscriber. The pre-push
hook's coverage branch runs exactly this with --receipt-store pointing at the SOURCE
checkout's .interlinked/test-runs, so the previous push of the SAME revision is consumed
instead of re-run (every export is fresh, so two exports of one revision share an identity).
A LOCAL tests run --all --coverage does not seed the export in practice: the runtime
snapshot hashes every on-disk byte outside .git, .interlinked and generated
directories, so gitignored local files (scratch/, coverage/, logs) enter the local
identity but not the export's — and honouring gitignore alone would not prove those
ignored inputs irrelevant, so this stays an unmet acceptance criterion (recorded in the
campaign file). The export's node_modules is a symlink to the source's: the runtime
snapshot hashes the canonical path of the mounted dependency tree, so a copied
node_modules is a different runtime and never reuses. That step is not bounded (the
scheduler owns admission and supervision).
Requests coalesce at write time (2026-09-28): a new request that a pending one already
covers returns that request's id, and a wider request retires the narrower pending
requests that no caller in its process still awaits (subscriptions are reference-counted,
so a shared id stays protected until its last caller leaves) — a full request is never
retired by a selected one (an empty-path full request keeps its obligation), and each
retirement is recorded in .interlinked/test-runs/requests/superseded.jsonl. Request
files are immutable: a request that adds a path to covering work is stored as its own
file (never merged into an in-flight request, whose completion would otherwise discharge
an input it never tracked), and a replacing request absorbs the retired requests' paths,
so no path is ever dropped — those paths are the inputs the freshness check re-hashes
after a run. Concurrent writers in separate processes therefore cannot lose paths. Between batches the
drain YIELDS all three leases (scheduler, project, host) for a short window, so a same-root
interlinked tests run or another repository's pre-push export takes the next slot instead
of waiting for the whole queue. Hook-originated work (stage edit) runs at background
priority and never blocks a waiting interactive caller at the host gate; CLI and pre-push
runs are interactive (ScheduleTestsOptions.priority overrides). A drain that cannot
re-acquire after yielding returns deferred with the work retained, and a queue another
drain emptied meanwhile resolves to that drain's shared completion.
TypeScript hooks use max_dependent_tests as a cap on the complete selected test-file
union (default 150). Full and over-budget plans defer intact; run interlinked tests run
to drain them with an explicit deadline. The external-tool batch releases its project lease
before entering the test scheduler. Capacity, path-cap and tool-cap deferrals retain inputs.
affected_tests remains opt-in. Its default empty filename suffix includes configuration
and fixtures in Node projects; explicit repository file_types and skip_test_files
settings still control which changes trigger it. After a triggered batch, all changed inputs
are considered. Raw npm test and independently launched tools do not use this scheduler.
The full pre-push/CI coverage gates remain authoritative; passing focused tests does not
satisfy them or re-enable a disabled local coverage policy.
Lease ownership binds the PID to an OS-derived process-start identity, so a live unrelated process that reused the same PID cannot keep compiler or heavyweight capacity busy. Legacy lockfiles without that identity remain compatible while fresh, but expire after 24 hours — well beyond every minute-scale workload timeout — rather than starving a project indefinitely.
A compiler watch process that fails to spawn is unavailable. Shutdown waits for its close event and releases the compiler lease without signaling a missing process; callers can then use the normal cold compiler fallback.
There is no --file/--changed/--staged flag — verify always walks the whole discovered
set (or target/--subdir). Diff-awareness lives at the edit-time gate, not in verify.
Run verify to see pre-existing findings in a file you're about to touch (the edit gate
hides those as warnings).
html_duplicate_id is a default PostToolUse/verify warning for repeated static IDs in
an explicit <body> in .html/.htm files. It reports each later occurrence with the
first occurrence's line. IDs are case-sensitive; comments, script/raw-text contents,
inert <template> contents, and dynamic ID expressions are excluded. IDs on the body,
script, and template elements themselves still count. This is a lexical check, not a
browser DOM audit: it does not infer omitted body tags, normalize equivalent entity
spellings, evaluate template branches, or execute JavaScript. Rename duplicate IDs and
update links, labels, ARIA references, and selectors; use classes for shared styling.
For expression-level review, run interlinked metrics expressions <path> --json
or verify --all-checks. expression_size, inline_callback_count,
control_flow_depth, expression_measurement, required_braces,
statements_per_line, nested_ternaries and ubs_deeply_nested_callback are advisory.
The callback check now uses exact syntax and defaults to >2 inline callback levels.
Generic brace advice accepts single-line guards, diagnoses multiline bodies, and
defers to detected target style configuration. Explicit imported brace rules retain
their native policy. Verify intended scope before adding braces; no bulk brace
autofix runs. Guard changes are handled before the edit by the prediction protocol
described in interlinked-harness. Physical file size (large_files) also belongs
to --all-checks advice, never a source-edit or verification block.
Missing parser/policy evidence produces NOT CHECKED, not a clean measurement. Use
interlinked-quality-gates for counting boundaries and .interlinked/readability.json.
Formatting requires explicit adoption of the project's formatter. biome imports
lint rules; biome-format imports read-only format checking with the same config and
inheritance tracking. Example: lint import --config biome-format=biome.json --target src/example.ts --only-selected --cadence audit --write. Repeat --target
to bound rollout; targets are relative to --scope and require --config. --gate errors
keeps explicit native warnings advisory in lint check, while errors and unknown
severity remain gating. Default all preserves existing behavior. Both modes retain
all findings in JSON; cadence and gate survive re-import. Formatter-disabled or
zero-file runs cannot establish formatter compliance. Width is a formatting target,
not a hard maximum. Normalize a bounded scope first; avoid repo-wide churn or implicit
line-baseline resets. This repository's doctor pilot is enforced by CI through
npm run format:check and npm run lint:readability.
Biome sibling overlays can ignore literal-file overrides confined to another directory. Overrides that may select the target or its temporary sibling still require supported filename-invariant selectors; otherwise the overlay is unavailable.
interlinked lint scan [directory] --json inventories recognized lint configs,
manifest sections, declaration/selector candidates, ignores, scripts/aliases and task/CI evidence
across nested packages. lint import previews which sources can become imported
checks and which need review; lint import --write --baseline applies supported
scopes, enables quality_checks.lint_import, and measures existing debt.
Preview never executes configuration; the baseline run invokes installed analyzers.
The native adapters cover ESLint, Biome (lint and format), Oxlint, Ruff, Clippy, golangci-lint,
SwiftLint, RuboCop, Stylelint, mypy, Pylint, Flake8, Standard Ruby, ShellCheck,
Hadolint, actionlint, PHPCS, PHPStan, Psalm, SQLFluff, Semgrep and Prettier.
Other analyzers can use reviewed SARIF stdout declarations in
.interlinked/lint-adapters.json (schema/example in docs/lint-adoption.md).
Unsupported flags, shell setup and dynamic invocations remain explicit
review items. Rules retain their original analyzer semantics and IDs; static
discovery does not resolve every dynamic preset or replace arbitrary rules with
native guards. See docs/lint-adoption.md for recognition and execution boundaries.
Oxlint adoption runs the installed oxlint --format=json ., including configured
JS plugin rules. Warnings from exit 0 remain findings; parse failures, invalid
reports and zero measured files produce no verdict. .eslintignore is tracked.
Select named ESLint files with repeatable lint import --eslint-config <file>;
add --write --baseline to apply and measure. Files are relative to the command
target, inspected as text in preview, and passed through ESLint's --config.
--eslint-scope <directory> sets the working directory/. lint target for those
selections (default: project root, not config directory). It requires a selector.
Named eslint.<name>.config.* profiles are automatic audit candidates; inspect their
inferred package scope. General repeatable --config tool=file and optional --scope
select arbitrary configs for any adapter supporting an explicit config flag.
--cadence hook|audit sets cadence for all profiles in the import plan.
Use --only-selected with --config or --eslint-config when adding an isolated
profile: new automatic/inferred linters remain review items, all previously adopted
profiles remain, and --cadence changes only the explicit selections. Without that
flag, import still includes supported discovered profiles. Preview before adoption.
For this repo's focused anti-slop audit, select --config oxlint=oxlint.anti-slop.json --scope src --cadence audit --only-selected, then --write --baseline. This enables
two complementary rules through the existing lint runner/baseline, not new native
checks. The separate all-18 research config is an explicit census only; its report
can exceed the runner's 10 MiB capture bound. Never promote a rule solely for zero hits.
Each config/scope/target/flag profile has its own
ratchet identity; re-import retains selected profiles without repeating flags.
PostToolUse and ordinary verify run hook profiles; verify --all-checks and
lint check run all profiles. Saved cadence survives re-import. Named/type/build-heavy
and CI profiles initially use audit cadence. Imported checks run asynchronously; hook findings
warn, never become automatic pre_block errors. lint check is the explicit
gate: exit 0 = complete/no new gating debt, 1 = new gating debt, 2 = incomplete/no verdict.
lint check --update-baseline seeds new scopes and tightens existing allowances.
Ordinary complete checks also retire resolved debt; incomplete runs never do.
Analyzer report capture has a 10 MiB threshold per stream. A truncated report is
unavailable even if its captured prefix parses; it cannot seed or retire debt.
Stylelint's stderr fallback also requires completely captured, empty stdout.
Truncated diagnostic logging on stderr does not invalidate a complete stdout report.
Source snapshots before/after each analyzer and again at batch completion reject
changed, added, deleted or replaced files; stale clean reports cannot retire debt.
Snapshots stream SHA-256 over every regular file in the working scope, including
custom extensions, dependencies, generated files and Git-ignored output. They also
compare file identity, mode and nanosecond timestamps; metadata alone cannot
detect unflushed memory-mapped writes. This is observational before/after freshness,
not an atomic filesystem snapshot or proof of arbitrary reads outside that closure.
For native ShellCheck and Hadolint, explicit targets must name existing regular
files in the working scope; confined regular-file symlinks are supported. Each
target is checked independently, including files under vendor or other default
discovery exclusions. Missing files, directories, escaping links and explicit
glob patterns make the result unavailable; another valid target cannot hide them.
Default inferred targets still use the adapter's discovery exclusions. Expand
explicit globs into a reviewed literal file list before importing the command.
Regular symlink targets are hashed; confined directory links are traversed with
cycle detection. Escaping directory links are unavailable. Diagnostic anchors use
a checked stream matching the original digest; out-of-snapshot diagnostics fail.
The census omits .git, .interlinked, __pycache__, .mypy_cache,
.ruff_cache, .pytest_cache, .eslintcache and .stylelintcache; explicit
targets or ignore overrides intersecting omitted runtime state are unavailable.
Each snapshot permits 100,000 entries and 4 GiB total, streamed in 64 KiB chunks
within the shared batch deadline. Large files do not require whole-file allocation;
diagnostic anchor lines have a separate 1 MiB character limit. Unreadable inputs or
exhausted bounds mean unavailable, never clean. Large scopes incur repeated reads
and may need a longer timeout or narrower valid working scope. Native ignores are
not guessed to make a census fit.
Native Clippy runs use a unique temporary Cargo target/build directory outside
the project, removed when the process finishes; compiler caches start fresh on each
measurement. Cargo arguments and child
environment override configured output locations so normal compilation cannot
invalidate the source snapshot. Existing target files remain measured inputs;
source, lockfile or build-script writes inside the scope still make the result
unavailable. A temporary-directory setting inside the project is unavailable.
Other analyzers that write inside their scope can also invalidate
their snapshots; only the listed runtime/cache exclusions are omitted.
Config drift requires review with lint import, then --write. The default
batch budget is 30000 ms (--timeout, maximum 300000 ms, on lint commands).
Literal config/plugin imports and package/lock context are fingerprinted. Ruff's
extend and local Biome/Oxlint JSON extends paths also enter the transitive digest
closure, including bare relative names such as base.toml. Paths resolve from each
declaring config, not the analyzer's working directory. Missing, out-of-project or
unresolved literal inputs prevent measurement. Existing policies missing one of these
dependencies require re-import; checking does not silently approve the new input.
Ruff's reader handles ordinary literal strings and table/dotted/inline keys; unsupported
string escapes or multiline inline inheritance require review. Biome package presets
retain package/lock tracking. This is not general YAML or dynamic inheritance resolution.
Discovery
does not execute config or expand arbitrary environment/matrix/build expressions.
YAML task parsing needs the optional yaml package; unavailable/invalid YAML remains
review evidence. Follow the supply-chain skill if adding the parser is blocked;
do not silently approve a dependency. An inventory marked complete can still have
unadopted review items. Never describe it as universal effective-rule coverage.
Two catalogs, both surfaced by verify + PostToolUse: the tool wrappers (typescript,
biome_lint, eslint, semgrep, gitleaks, dependency_audit, secrets_in_source,
affected_tests, per-language tools…) and the inline families in
src/harness/checks/<family>.ts (security/injection, PII/secrets, async/promises,
correctness/bug-class, agent-clarity, complexity, test-quality, comment/spec drift, …). Use
interlinked harness checks for the authoritative current inventory.
Phase determines what blocks:
pre_block — the only inline checks that BLOCK an edit. Zero-FP,
deterministic (eval, nan_comparison, throw_literal, promise_reject_non_error,
child_process_exec_user_input, cookie_missing_security_flags, most ubs_* blockers…).
Introduced-only. (Merge-conflict markers also block, but via a separate write-guard on real
Edit/Write — not the pre_block registry, so interlinked write won't catch them in a new file.)pre_warn — PreToolUse warning, never blocks (e.g. floating_promises, broad_object_types).post — PostToolUse warning + surfaced by verify (the bulk: nan_coercion_guard,
write_without_mkdir, unvalidated_json_boundary, magic_literal_in_conditional,
non_null_assertion ratchet, introverted_test, …).Type assertions. unjustified_cast uses the TypeScript AST when available, including
angle-bracket assertions, literal targets, and anonymous object targets. as const is excluded.
A justification must be an actual comment with a nonempty SAFETY: explanation on the
assertion's line, asserted expression's starting line, or nearest enclosing statement's starting line, or the immediately preceding
comment lines (up to two). Text inside
a string does not qualify. Without TypeScript, the legacy lexical scan remains available;
malformed syntax combines recovered AST findings with that fallback.
Prefer deleting a redundant assertion, adding a checked declaration type, using vi.mocked
with complete test fixtures, or validating an unknown input. Keep an assertion only when its
specific invariant is understood and explained. Exercise malformed external data at its actual
parser or adapter boundary. Do not fabricate impossible internal states just to kill a mutant
or prove that a removed feature stays absent. Retain a malformed-input assertion only when an
actual untyped caller can supply that value, and explain that caller and the expected behavior.
A generic explanation or an unchecked JSON annotation does not establish safety.
Test-file ladder. A test edit is checked before it lands as well as after it lands. pre_block
rejects only introduced deterministic theatre/sabotage: assertion-free cases, tautologies
(including identical literals/constant truthiness), SUT self-mocking, focused cases, and
unconditional skips. PreToolUse warnings immediately coach low-noise shapes such as removed test
signals, duplicate names, real I/O, nondeterministic clocks/RNG, fixed waits, missing SUT imports,
mock-only assertions, private-member access, silent dependency skips, and test_legitimacy.
PostToolUse retains context-heavier review such as happy-path-only and introverted tests. A warning
is not a pass; rewrite toward a precise observable behavior or document the real compatibility
contract.
Default vs advisory. Default-gate checks fire on every edit + default verify. Advisory
checks (the DEFAULT_ADVISORY_SKIPS list — complexity, CRAP, DRY clones, boolean_trap,
write_without_mkdir, homedir_write_escape, most ubs_*, Swift/test heuristics,
conditional_empty_object_spread, unknown_type_alias…) fire
only under verify --all-checks. unvalidated_json_boundary was PROMOTED to the
default gate 2026-08-10 after the boundary-parser sweep took the repo to 0 fires — expect
it on ordinary edits: route parsed JSON through a local parseX(v: unknown): X | null
(or an isX guard / Array.isArray gate) before field access. "Advisory" ≠ silent — an advisory check that fires at PostToolUse
still warns; demoting a check doesn't stop it warning on edits. Fix the detector, not the list.
test_legitimacy is one of those advisory test heuristics. It runs as immediate PreToolUse
coaching and under verify --all-checks. For each case in a
*.mutation-kill.*, *.mutation-hardening.*, or *.survivor(s).* JS/TS test, put an adjacent
contract receipt immediately before the case:
// test-contract: boundary — parseWindow rejects the documented zero-width interval
it("rejects a zero-width interval", () => { /* precise public-behavior assertion */ });Kinds are public-api, invariant, bug, security, or boundary; the rationale must be
specific, not “kills the mutant.” The check also reviews broad toBeTruthy/toBeFalsy,
incidental call-order assertions, and explicitly private/internal imports, including multiline
named imports such as __test_only__. Cast-based private-member access is a companion warning. These shapes are not
automatically wrong, so this check stays heuristic: exact CLI/help/policy strings are legitimate
compatibility assertions, while unpromised internal formatting usually is not.
The React missing_effect_cleanup advisory recognizes cleanup-shaped returns rather
than arbitrary component render returns. Shared full-component examples in
src/harness/checks/__fixtures__/effect-cleanup-cases.ts exercise the detector and real
hook delivery. It still scans to the next effect or EOF; unrelated cleanup-shaped
returns can hide findings, so do not treat this heuristic as proof of correct disposal
or promote it to a deterministic block.
Two newer TS type-discipline advisories, both AST-parsed and both [heuristic]:
unknown_type_alias — a named alias resolving to exactly unknown, chased through
same-file non-generic aliases (type Foo = unknown; type Bar = Foo; flags both). Name the
real shape, or keep unknown at the boundary and narrow with a parser/guard.conditional_empty_object_spread — { ...(cond ? {} : { field: v }) }, the spread-a-
ternary trick for omitting a field. The idiomatic guarded passthrough
guard ? { key: guard } : {} is exempt.Every finding is tagged [proven] (a real tool ran it — fix it) or
[heuristic] (regex/AST shape — evaluate it). See interlinked-harness for
the suppression grammar (// interlinked-ignore: <check> — reason /
verify-suppressions.json).
Checker availability is a first-class state (2026-08-27). The tsc overlay
returns one of three outcomes: ok (it RAN — empty findings = checked clean),
skipped (it deliberately did not apply: non-TS file or operator mode: off —
nothing was verified, and nothing claims to be), or unavailable (it SHOULD
have run and could not: sidecar spawn failure, timeout, cooldown, or per-project
compiler backpressure). Unavailable
is never clean: transactional paths — interlinked write (single AND
--batch), multi-edit, verify-changeset — ABORT with a
tsc-overlay-unavailable failure and leave files untouched; the ordinary
single-edit hook path does not launch the sidecar at all. It records scheduled work,
and the admitted PostToolUse path checks the on-disk result asynchronously. A scheduled
record is not a passing verdict; unavailable PostToolUse checks still surface missing evidence.
Full-project TypeScript children are serialized per project across concurrent
hook and CLI processes. Heavy verify/check/test/audit/sweep work uses one
project-scoped cross-process lease: contention is an explicit deferred/no-verdict result
for external-tool batches. Tests retain requests and use the bounded scheduler described
above. Each accepted request runs after its own edit is on disk; cached test results require
matching validated inputs.
A multi-file PostToolUse request also owns one external-tool batch for its
entire ChangeSet: project-capable compilers, linters, and security scanners run
at most once, then their findings are attributed back to the touched files.
Cheap inline checks still run once per file. A same-ecosystem dependency audit
runs once for the ChangeSet, and TypeScript/Vitest affected tests run once with
the union of changed inputs, including tests. Mixed-language affected-test sets,
multi-ecosystem audits, file/tool-cap overflow, a file-only external runner, or
a batch denied by capacity produce one aggregate NOT CHECKED result for the
request instead of N subprocesses or N warnings. Existing-file TypeScript
diagnostics from the batch warn without claiming they were introduced: only a
request-proven new file has an empty compiler baseline; the exact per-edit
introduction decision remains the PreToolUse overlay's responsibility.
When several PostToolUse checks defer for one edited file, the model-visible
output is one [interlinked:checks-deferred] NOT CHECKED warning with the
individual reasons; structured check_results still retain every deferral.
checks_ran lists only checks that completed with a real verdict; attempted
checks that throw or defer are recorded under a deferred_<check> timing
boundary instead of being reported as completed.
The same deferral is not repeated by the project-wide sweep, and a deferred
event never receives an all clean summary. Re-editing a file cannot repair
checker capacity, so operational deferrals also never become a
persistent_warning_escalation source error, recurrence signal, or
feedback-effectiveness warning/resolution. They remain structured operational
telemetry, and the NOT CHECKED notice remains visible until a real verdict
exists. Retry every named check before claiming the edit is verified.
PostTool warning delivery is request-owned. Each daemon check pass writes its
own tokenized active/ready record under .interlinked/quality-warning-spool/;
both installed hook runtimes acknowledge a synchronous result before showing
it, while a result that finishes after the hook timeout is atomically claimed
and shown once on that same session's next PreToolUse. The originating hook's
PID preserves its first-delivery right without making another hook wait.
Parallel agents cannot overwrite or unlink one another's work, clean results
create no replay record, and a PreToolUse never force-removes a live check
marker. A PostTool pipeline exception publishes an explicit NOT CHECKED
diagnostic instead of an empty record, and an abandoned active-only marker is
claimed only after its hook process is gone (or the marker expires); live
markers are preserved. The old shared pending-quality-warnings.json file is read only as a
one-time rolling-upgrade migration path; when request-owned evidence exists,
unscoped legacy text is discarded rather than mixed into another request.
Because the synchronous overlay path cannot wait without blocking the daemon
from reaping an async compiler, contention returns unavailable immediately;
retry after the active check finishes instead of treating the edit as verified.
The synchronous export-ripple advisory follows the same rule: it reports an
explicit export_ripple_compilation_deferred info finding and launches no
second compiler while same-project compiler work is active.
Different project roots remain independent and may compile concurrently.
Use paired examples that distinguish a real violation from similar valid code. In
test_legitimacy, import-shaped text inside multiline fixture strings is not a real
private import; an actual import after that fixture still reports its own line.
Mutation-directed receipts must be standalone comments, and a specific rationale may
mention “contract” without being a generic placeholder. Shared behavioral examples can
drive both a detector unit test and a real hook/daemon e2e test: assert the finding and
location in the unit lane, and delivery, severity and transport ownership in the e2e lane.
Neither lane's passing result substitutes for the other. Keep examples and expected
outcomes separate from implementation-derived values so other language adapters can
exercise the same requirement through their own public boundaries.
Check-evidence stores must preserve complete result lists. A corpus record with
missing, non-array, or non-string hits, or an adversarial review with malformed
findings, is rejected and leaves its obligation unsatisfied. Re-run the scan or
review to replace that record; do not replace unknown results with []. An explicit
empty list from a completed run remains valid evidence of no findings. Corpus
satisfaction also requires a positive integer files_scanned; an empty scan or
missing/invalid scan count cannot satisfy the obligation.
interlinked verify --all-checks --details includes fourteen advisory test-discrimination
and isolation checks; default verify omits them. They remain PostToolUse warnings.
Review each finding against the observable contract before editing the test.
mock_return_echo: check whether forwarding the configured value is the contract.
Negated/throwing evidence is not an echo; coarse values count only with one
discovered mock target. Literal overlap is a heuristic, not dataflow proof.duplicate_test_body: compare inputs and setup. Setup comparison includes hooks
declared after tests and preserves whitespace inside literals.vacuous_loop_assertion: pin non-emptiness or use a positive assertion count.
Mapped-array equality pins are recognized; expect.assertions(0) is not a guard.spy_without_restore: use applicable restore hooks, mockRestore, using, or
runner restoreMocks. Discovery reads default Vitest/Jest configs and literal
setup paths at the nearest package root; custom config loading is unresolved.
Fresh objects and array literals owned by a test are exempt. Shared arrays
still need cleanup; review ownership before adding restoration solely to clear a warning.export_existence_smoke_test: only imported export presence/type evidence;
these cases are excluded from wildcard_in_observable. Export availability may
be an intentional compatibility contract.commented_out_assertion: a real disabled assertion inside an active test;
prose mentions and code-as-string fixtures are excluded.In the Interlinked CLI source checkout, reproduce the census with
npx tsx scripts/scan-test-discrimination.ts [corpus-root] [check-id ...].
It reads current contents of tracked JS/TS tests and prints counts plus locations
as JSON. Per-file finding caps apply; zero findings and builder-reviewed samples
do not establish independent precision. AST detectors and duplicate-body setup
comparison require optional TypeScript; its absence yields no detector findings,
not verification.
Three agent-callable commands gate proposed content without running function-token/coverage/complexity/post
checks. interlinked write, multi-edit, and verify-changeset share pre_block → biome → tsc:
interlinked write <path> --stdin # single gated write, content on stdin
interlinked write --batch <manifest.json> # gated batch with rollback protection
interlinked multi-edit <path> --stdin # single-file old→new edits
interlinked multi-edit --manifest <file> # single- or multi-file edits
interlinked verify-changeset --file <cs.json> # preview the gate, write nothingwrite --batch manifest: { "version": 1, "writes": [ { "path", "content" }, … ] }.
The gate sees all final contents before any write, so a blocking finding writes nothing. Commit
uses per-file atomic renames, preserves existing target modes, and performs best-effort rollback
if a later rename fails; POSIX provides no literal multi-file atomic rename, and an incomplete
rollback is reported explicitly.
New files use an empty biome/TypeScript baseline, so diagnostics introduced by a fresh .ts,
.tsx, .mts, or .cts file block just like diagnostics introduced while editing an existing
file; scratch/ is not an escape lane.multi-edit manifest: { "version": 1, "edits": [ { "old_string", "new_string" }, … ] }
(path = positional arg), or { "version": 1, "batches": [ { "path", "edits": […] } ] }.
Edits apply in order to an in-memory buffer; the gate runs once on the final content.
Ambiguity is judged after prior edits — each old_string must match exactly one location
in the current buffer state.verify-changeset previews (Write/Edit/MultiEdit shapes), enforces nothing; exit 1 =
"would be blocked".Transactional consistency. write and multi-edit capture target bytes and modes before
verification, then compare them again under a shared project commit lock. A concurrent change
aborts the batch: re-read the targets and rebuild the proposal. Unchanged multi-edit members
still participate in this comparison. Both commands preserve existing file permissions and use
guarded rollback that refuses to overwrite newer content. Targets must be regular files or
missing; symlink targets, duplicate physical targets, and escapes through parent symlinks are
rejected. Parent resolution is checked again before staging, committing, and rollback;
a redirected parent aborts the operation. A failed multi-edit reports the actual failing
target in error_detail.path. write --unsafe-outside-repo retains its explicit outside-root exception. This lock
coordinates Interlinked transactions; it does not make ordinary editors participate or make
multi-file writes crash-atomic. An incumbent lock is an unavailable transaction, never permission
to delete the lock blindly.
Biome availability. A configured analyzer that times out, crashes, or returns unreadable
diagnostics produces biome-overlay-unavailable and aborts transactional writes/previews.
Ordinary edit hooks retain asynchronous PostToolUse checking and visible NOT CHECKED feedback.
Unconfigured projects skip Biome. Existing and proposed contents are measured with the same
analyzer; moving existing lint debt is allowed, while another occurrence of the same rule is
new debt. A missing diagnostic cache never establishes a clean baseline. Overlay execution
uses installed tooling without installing a missing package.
The Biome overlay uses a sibling temporary file. It supports directory and simple
extension selectors; filename selectors (including *.test.ts), inherited config,
plugins, VCS ignore rules, filename-sensitive rules, and BIOME_CONFIG_PATH report
unavailable because the temporary file cannot reproduce their semantics. Nested
target configs are discovered even without a root config. For an unsupported
configuration, use the ordinary edit workflow and run Biome on the actual file;
do not interpret an unavailable preview as approval or weaken project rules to
make the preview pass.
Creating, changing, or deleting a governing Biome config in the same proposal also
reports unavailable, since the analyzer reads disk configuration. Land that config
change before the source batch. A submitted config whose bytes equal disk is unchanged.
CRITICAL — exporter before importers. The tsc overlay blocks newly-introduced type errors per file, so importing a not-yet-exported symbol is a
TS2305/TS2304the overlay blames on your edit. Either (a) put the exporter and every importer in one atomicwrite --batch/multi-edit --manifest(the gate sees the whole consistent final state), or (b) if sequencing with real Edits, land the exporter first, then the importers — never the reverse. (Batch editing skips the function-token and coverage ratchets, so a batch can land over-cap or under-covered; the commit backstop/next real Edit and coverage gate re-assert them.)
The scratchpad guard blocks agent-authored code aimed at the host session scratchpad and
redirects you to <repo>/scratch/ (rg-searchable, quality-gated, survives the session;
coverage/companion-test ratchets are exempt there, like scripts/).
interlinked scratch init # provision scratch/ (README + .gitignore carve-out + .ignore negation)
interlinked scratch statusConvention: one date-prefixed subdir per effort (scratch/2026-07-19-<slug>/). Downloads and
npm pack extractions still belong in the host scratchpad (non-code bulk). Softening:
scratchpad_guard.code_write_mode: "warn"|"off"; bypass INTERLINKED_DISABLE_SCRATCH_GUARD=1
(placement only — the secrets scan on temp paths is never bypassed).
interlinked harness coverage status --json shows pending exact file identities,
watcher readiness, automated check receipts and manual review receipts. Run
interlinked harness coverage verify --json to check the pending versions through
the daemon's configured PostToolUse checks; --no-wait starts the job and returns.
Polling status reports progress. A completed job can still contain findings or
unmeasured versions. Missing files, excluded paths, deferred checks and concurrent
changes do not gain a clean verdict. Receipts enumerate the checks actually run;
they do not certify PreToolUse enforcement or approve a baseline rewrite.
For an explicitly reviewed absence or other manual disposition, use
harness coverage acknowledge <id> <generation> <identity> <evidence> with the
current status values and a concrete review record. This records manual review,
not a test pass. Stale identities/generations are refused. If a mutation's response
is lost, inspect status before retrying. Never blanket-acknowledge pending entries
to silence the warning. Policy acceptance is a separate explicit action.
interlinked verify → fix [proven] findings first, then
triage [heuristic]. Read the output; don't rely on $?.interlinked verify-changeset --file cs.json --json → fix until ok:true → submit as write --batch (or real edits, exporter-first).write --batch with {writes:[exporter, …importers]} → single gate pass, no transient tsc error.interlinked scratch init (once) → write under scratch/<date>-<slug>/.test-contract receipt → run
interlinked verify --all-checks --details → resolve test_legitimacy together with the
existing assertion/mock/hermeticity findings → formally remeasure the source file. A killed
mutant is necessary evidence for that campaign, not proof that the test protects a real contract.write/multi-edit/verify-changeset skip function tokens,
coverage, cyclomatic, CRAP, and post checks. A batch that passes can still trip those on the next real
Edit, and verify will still flag post findings.write/multi-edit/verify-changeset
gate — a fresh file diffs against an EMPTY baseline, so every diagnostic it introduces counts
(the earlier "new files skip the overlay" claim was stale; corrected 2026-08-27). The real-Edit
hook path is where the merge-conflict caveat above applies.--all-checks re-enables high-FP heuristics; it's for periodic audits, not CI gating.interlinked verify # default gate, whole project (reports, exits 0)
interlinked verify --all-checks --details # deep audit with per-file detail
interlinked verify --only tsc # just typecheck
interlinked write --batch changes.json --json
interlinked verify-changeset --file cs.json --json© 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-verify of QuentinCody/interlinked-cli.
Open the folder on GitHubat commit 31b5259
Interlinked Verify 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 Verify this skillQuentinCody/interlinked-cli | 178 | — | ~23k | Automated safety check: Pass | MIT | |
| Landingalirezarezvani/claude-skills | 28k | — | ~3.8k | Automated safety check: Pass | MIT | |
| Video Understandcalesthio/OpenMontage | 65k | — | ~841 | Automated safety check: Pass | AGPL-3.0 | |
| Landing Page Conversion Auditgithub/awesome-copilot | 40k | 1 repos | ~1.8k | Automated safety check: Pass | MIT | |
| SEO Aeo Landing Page Writersickn33/agentic-awesome-skills | 47k | 1 repos | ~1.5k | Automated safety check: Pass | MIT | |
| Ads LandingAgriciDaniel/claude-ads | 9.8k | — | ~612 | Automated safety check: Pass | MIT |
alirezarezvani/claude-skills
Generates a premium single-page HTML landing page with 3D CSS animations, GSAP scroll effects, and mouse-parallax depth.
calesthio/OpenMontage
Understand video content locally using ffmpeg frame extraction and Whisper transcription.
github/awesome-copilot
Audit a landing page, sales page or checkout page for conversion leaks and return a fix list ordered by expected revenue impact.
sickn33/agentic-awesome-skills
Writes or improves conversion-focused landing pages for products, services, and offers with practical SEO and AEO structure.
AgriciDaniel/claude-ads
Audit paid-ad landing pages for message match, mobile experience, performance, accessibility, trust, forms, consent, tracking, security, and conversion friction.
Egonex-AI/Understand-Anything
Gives an in-depth explanation of one file, function or module by reading the project's knowledge graph and checking that the graph is still fresh.
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.
Run interlinked verify, understand the PostToolUse quality checks, and land multi-file edits through the content gate. Interlinked Verify is an agent skill from QuentinCody/interlinked-cli. Run interlinked verify, understand the PostToolUse quality checks, and land multi-file edits through the content gate.
Run `npx skills add QuentinCody/interlinked-cli --skill interlinked-verify -a claude-code`. Or copy the skill folder (skills/interlinked-verify in QuentinCody/interlinked-cli) into .claude/skills/interlinked-verify in your project. Claude Code loads it when a task matches its description.
Run `npx skills add QuentinCody/interlinked-cli --skill interlinked-verify -a codex`. Or copy the skill folder (skills/interlinked-verify in QuentinCody/interlinked-cli) into .agents/skills/interlinked-verify 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-verify -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-verify, .gemini/skills/interlinked-verify, .github/skills/interlinked-verify and .opencode/skills/interlinked-verify in your project.
Going by SKILL.md and its folder, Interlinked Verify needs the command-line tools its instructions call (npm, npx, rg and vitest). Our summary lists: Python 3; Node.js.
SKILL.md contains no URLs. Its commands use 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 Verify is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 23k tokens (SKILL.md is roughly 92k 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 Verify: Landing (alirezarezvani/claude-skills, 28k stars), Video Understand (calesthio/OpenMontage, 65k stars), Landing Page Conversion Audit (github/awesome-copilot, 40k stars) and SEO Aeo Landing Page Writer (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.