Vercel Optimize Audit
vercel-labs/agent-skills
Runs a metrics-first audit of a deployed Vercel project, gating investigations on real signals to produce ranked, citation-backed cost and performance recommendations.
Investigate agent activity and JSONL/gzip evidence. An agent skill from QuentinCody/interlinked-cli.
$ npx skills add QuentinCody/interlinked-cli --skill interlinked-observability -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install QuentinCody/interlinked-cli interlinked-observability --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-observability .claude/skills/interlinked-observability && 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-observability" agent skill from https://github.com/QuentinCody/interlinked-cli/tree/main/skills/interlinked-observability into .claude/skills/interlinked-observability/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interlinked-observability", 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-observabilityType 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-observability -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install QuentinCody/interlinked-cli interlinked-observability --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-observability .agents/skills/interlinked-observability && 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-observability" agent skill from https://github.com/QuentinCody/interlinked-cli/tree/main/skills/interlinked-observability into .agents/skills/interlinked-observability/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interlinked-observability", 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-observability -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install QuentinCody/interlinked-cli interlinked-observability --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-observability .cursor/skills/interlinked-observability && 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-observability" agent skill from https://github.com/QuentinCody/interlinked-cli/tree/main/skills/interlinked-observability into .cursor/skills/interlinked-observability/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interlinked-observability", 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-observability--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-observability -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install QuentinCody/interlinked-cli interlinked-observability --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-observability .gemini/skills/interlinked-observability && 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-observability" agent skill from https://github.com/QuentinCody/interlinked-cli/tree/main/skills/interlinked-observability into .gemini/skills/interlinked-observability/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interlinked-observability", 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-observabilityInstalls 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-observability -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-observability .github/skills/interlinked-observability && 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-observability" agent skill from https://github.com/QuentinCody/interlinked-cli/tree/main/skills/interlinked-observability into .github/skills/interlinked-observability/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interlinked-observability", 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-observability -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-observability --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-observability .opencode/skills/interlinked-observability && 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-observability" agent skill from https://github.com/QuentinCody/interlinked-cli/tree/main/skills/interlinked-observability into .opencode/skills/interlinked-observability/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interlinked-observability", 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-observabilityInvestigate agent activity and JSONL/gzip evidence. An agent skill from QuentinCody/interlinked-cli.
Interlinked Observability is an agent skill from QuentinCody/interlinked-cli. Investigate agent activity and JSONL/gzip evidence. Load for data scan, catalog/health/index/search/show/investigate, storage-engine experiments and benchmarks, native transcript comparisons, file/session history, capture gaps, lossless rotation, audit integrity, and evidence-backed handoffs. Also covers activity, logs, impact, trace, recurrence, viz, collect, compact, and optional sync. Missing capture is not absence; correlation is not causation.
Its SKILL.md is about 10k tokens, which your agent loads only when the skill is triggered. The skill folder holds 5 other files, including reference files (for example `agents/openai.yaml`, `references/evidence-workflows.md` and `references/storage-evaluation.md`).
It sits in DevOps & Cloud, covering Observability. 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.
4 steps, taken from the first numbered list in SKILL.md.
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:
jqnpmvitestnpxFrom 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 Observability loads about 10k tokens when it runs, and up to ~14k if it reads all its reference files. Until then it costs about 120 tokens; SKILL.md has 4,945 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). 4,945 words, ~10,450 tokens.
.claude/skills/interlinked-observability/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.For Claude compiler batching, distinguish tool calls, scheduled checks, compiler
executions and delivered diagnostics. hook-observation.v1 rows record scheduled
TypeScript work; batch results and timing are in check-results.jsonl. Pending work
survives in .interlinked/compiler-batches/. Coverage observations are retained even
when repeated model warnings are suppressed. Silence does not mean coverage is complete.
Measure a repeated-edit problem by assistant-message/tool-use identity and timestamps:
an edit emitted before an earlier hook's feedback cannot be attributed to that feedback.
check-executions.jsonl also carries hook-observation.v1: scheduled external overlays,
normal complexity/token measurements, and shadow trajectory observations. These are telemetry,
not check passes or confirmed model delivery. check-results.jsonl retains full findings,
including novelty, findingCount and server-computed writeAttribution where available.
Newly observed means report novelty, not proven causation. Repeated advisories may be hidden
from model feedback while remaining in each call's records; hidden findings prevent all-clean.
Use evals/compare-builds.mjs for paired explicit-build agent pilots. It retains fixtures,
native streams, usage categories, settings, daemon status, final diffs and evaluator-owned
functional checks. Activity warning counts are ledger metrics. Missing native delivery/token
data remains unknown; do not infer billed savings from shorter commands or compressed rows.
repeated_implementation check results retain each current AST-matched group with
a group=<sha256> detail identity, even when unchanged agent-facing warnings are
suppressed. Compare these identities rather than line numbers across formatting edits.
Post-tool suppression is session-local and resets with the daemon; Stop uses its
existing digest state. NOT CHECKED means missing analysis, not zero clones. Findings
are review candidates, not proven defects or evidence that an extraction helped.
hook-reentry.jsonl records Stop/SubagentStop re-entry suppressed before daemon evaluation.
Translation receipts now include advisory context representation as well as denials and
rewrites. Operator-only Stop diagnostics are not model-context delivery. Audit native
completion messages by unique ID; streaming chunks and daemon Stop counts are insufficient
to count continuations. The SlopCodeBench exporter retains these receipts and registrations.
Shared hook-check receipts may include scopes with a batch ID, check name, configuration
hash and captured request-file identities. kind: request-inputs is historical execution
evidence, not a complete runtime/dependency closure or reusable cache key. Nonempty
unavailable preserves partial evidence and leaves the obligation pending. Keep those states
separate from clean results when comparing recovered check counts or latency.
source-scan-scope.v1 capture rows record dependency/runtime exclusions from authored-source
quality, with excluded_not_checked status. source-scan-security.v1 retains the separate
security findings and request-input evidence. Neither row authenticates a writer or certifies
runtime-input closure. Repeated unavailable-check messages are deduplicated for delivery by
session, project, configuration and reason; raw check results retain missingness. Counts in
the agent channel therefore differ intentionally from raw deferral counts.
Cowork plugin receipts use a separate metadata-only schema and explicit exports.
Use interlinked-cowork and interlinked cowork report <receipts> --effects <listing>
for native conformance. An intended hook decision is not execution/prevention proof;
these receipts do not provide complete transcripts or authenticated writer attribution.
When history can help diagnose a failure or explain prior work, use the logs as evidence:
data status --json
and data health --json before interpreting missing results.data scan reads JSONL/gzip directly without an
index or corpus copy. If an existing index is appropriate, explicitly run data index
for stale sources; its import budget does not limit total disk growth. Report coverage.--limit; correlate relevant records with
data investigate, then retrieve supporting IDs with data show ID --json.Read evidence investigation workflows for task-specific recipes, source selection, pagination, and a concrete handoff checklist. Prefer bounded JSON results over dumping whole logs into context. Evidence payloads may contain user/code content; retrieve only relevant records and keep local evidence local unless sharing is authorized.
Read storage experiments to compare direct scans, native
Claude snapshots, legacy/compact/bounded SQLite, compressed segments, and the experimental
Cloudflare path. data lab always uses explicit corpus/output directories. Its portable
literal queries, FTS token queries, and raw rg searches have distinct semantics.
interlinked data scan "compiler import" --source check-results --max-mb 32 --limit 10 --full-text --raw --jsonDirect scans default to 32 MiB expanded input and 25,000 physical lines, taking complete-line
prefixes of the most recently modified files. They include retained gzip archives and numeric
rotations. A narrow time filter does not jump to a newer portion of a large file. Inspect
coverage.complete and scope; increase explicit budgets or choose an existing index when
necessary. --raw returns the observed source text with its hash. Scan/lab IDs are separate
from production data show IDs. File filters for data scan use project-relative paths.
Use --full-text when omission by the bounded index projection matters: it searches all
decoded string values inside each readable complete record, excluding JSON field names.
Byte/line budgets and oversized-record limits still apply. Without this flag, a complete scan
with coverage.truncated > 0 does not establish that a term is absent from original payloads.
Use interlinked data catalog to discover registered and unknown JSONL files recursively,
including numeric rotations and gzip archives. data health distinguishes observed writes,
unsupported/disabled/idle producers, failures, and unmeasured populated files. Its receipt
window is bounded; a quiet event-driven feed is not automatically broken. doctor reports
capture failures and unmeasured coverage.
interlinked data index --max-mb 256 --max-records 250000 --json
interlinked data status --json
interlinked data search "compiler import" --since 7d --json
interlinked data search --source check-results --session SESSION --json
interlinked data show RECORD_ID
interlinked data investigate --session SESSION --json
interlinked data investigate --file src/app.ts --json
interlinked data checks --check typescript --json
interlinked data usage --session SESSION --json
interlinked data suggestions --json
interlinked data recurrence-inventory --jsonIndexing is incremental and bounded: repeat until the retained backlog is covered. --rebuild
clears only derived tables. SQLite/FTS5 loads lazily; use a Node runtime with built-in SQLite
(Node 22.13+ avoids needing the earlier experimental flag). Search includes retained archives;
--no-archives restricts it to live files. --fts opts into FTS5 query grammar. Structured
filters include source/category/session/actor/provider/model/file/check/call/kind/decision/origin.
Catalog source names and categories stay consistent between direct scans and indexed search,
including sources stored under nested paths such as logs/latency.jsonl.
Unknown event timestamps are excluded by time bounds. The older query command scans a
bounded physical tail of one file and reports its scope; it does not promise archive coverage.
Each indexed answer carries a record ID; data show retrieves the original JSON and verifies
its SHA-256. Projection text/field traversal is bounded, and oversized or malformed rows are
reported without deleting their raw bytes. Check data status for freshness and parse failures.
Invalid UTF-8 is malformed evidence: scans and new imports report it and continue to later
complete records; data show refuses to verify it. A valid replacement character (�) in
UTF-8 is ordinary text. For indexes created before strict UTF-8 validation, use an explicit
data index --rebuild to remove earlier lossy projections; historical raw bytes remain intact.
Exact duplicate raw records within one logical source share an indexed record but retain all
physical locations. Cross-stream observations are not automatically independent executions.
data sessions/files/checks/usage/schema/suggestions expose evidence aggregates. investigate
correlates exact provider/session/actor/call identities and labels missing phases; a file filter
also strictly folds the obligations ledger. A block count is not a prevented-defect estimate.
Suggestion shown means selected for presentation, not acknowledged; later absence is an
observation, not proof of a fix. Usage has unknown values and no invented prices; never add
overlapping timeline and costs totals. Recurrence inventory is separate from incident counts.
Usage deduplication chooses a provider-message representative within the query's retained
scope, so superseded source generations and excluded archives do not hide a retained copy.
Aggregate limits bound returned groups, not necessarily database work; narrow supported
filters first. schema is a source-wide observed field census: only --source and --limit
affect its scope, even though its CLI accepts the shared filter flags.
data maintain previews retention. data maintain --execute --compact --no-index losslessly
rotates eligible collection/timeline history without opening or creating SQLite. Add --index
to explicitly import a bounded batch and translate existing evidence pointers during rotation.
Without either index flag, indexing follows auto_index. It never deletes evidence or
automatically compacts activity/state ledgers/corpora.
Activity still requires the existing cursor-aware compact workflow. After an external
compactor, rerun data index to discover replacement files and archives.
Preserve evidence indefinitely: do not delete, expire, truncate, sample away, or rewrite raw
records, archives, manifests, or integrity checkpoints to reclaim space or hide bad rows.
Lossless rotation changes physical placement while retaining every record. A smaller live
file is not less retained history. Search archives with data search; older live-file readers
cannot answer questions about the complete retained history. --rebuild replaces derived
index tables only and is not a routine retention operation. Index storage can exceed raw-log
storage substantially; the per-pass import budget is not a cap on total index size.
Rotation prepares the bulk retained suffix before acquiring the append lock. Identity is rechecked under the lock, and only a bounded catch-up plus the atomic rename exclude writers. An excessive append burst or competing replacement aborts safely for retry. Maintenance operation failures are recorded in capture health.
data configure --auto-index on opts into bounded SessionEnd background indexing;
--auto-compact on independently enables collection/timeline rotation. Both default off;
enabling rotation alone does not enable or run the SQLite importer.
Defaults are 256 MiB/250,000 records per pass, a 256 MiB rotation threshold, and a 64 MiB live
tail. Configure via --index-mb, --index-records, --compact-at-mb, --keep-live-mb.
Settings live in data.config.json under the resolved data directory; capture itself continues
independently. Load new daemon capture code through the normal build/reload workflow.
SessionEnd is an actual provider lifecycle event, not each assistant Stop. This automation
does not continuously watch files or refresh a long-running active session on a timer. Run an
explicit index pass when recent evidence matters; a deferred background job is not freshness.
data audit diagnose locates the first historical failure by physical source/offset and does
not infer tampering intent. Its source line and byte offset refer to the physical record even
when archived blank lines are omitted from the verifier's combined line count.
After investigation, data audit checkpoint --reason TEXT records
an explicit payload-verified live observation boundary. data audit verify --checkpoint ID
checks subsequent retained evidence, including after rotation. The historical verdict stays
unchanged; checkpoints never rewrite or reset the old chain.
The bundled workflow reference is available in installed
skills. In the Interlinked CLI source repository, docs/data-observability.md and
docs/generated/data-catalog.md provide the operator contract and generated source catalog;
in another project, use data catalog --json to inspect its sources.
Interlinked captures normalized tool-call events that configured Claude Code,
Codex, Copilot CLI, Gemini CLI, Cursor, OpenCode, and Pi integrations deliver —
locally via hooks, offline-first, into append-only JSONL under .interlinked/.
The running daemon persists those delivered events. Detached lifecycle events and
asynchronous PostTool findings can arrive after the originating provider action,
and a cold fallback is not a complete capture path, so the log is evidence of
events already delivered and persisted—not a synchronous transcript of every
agent action. You can answer what did I (or a parallel agent) just do? what ran,
on what files, with what tokens? what did the guard block? what mistakes keep
recurring? — all without a server (the server is optional enrichment).
Output-mode flags are per-command (not uniform); all support --json. --since grammar is
strict: \d+(s|m|h|d) (e.g. 30m, 2d) — 15 or 1.5h throw.
Dashboard / feed
| Command | Purpose | Key flags |
|---|---|---|
status | Local-first dashboard: sessions, recent activity, sync + optional server health | --watch [s] · --short --full --json |
activity | Recent feed (local+server merged/deduped, token/cost totals) | --agent --limit --since · --json |
impact | Evidence-classed local git, dependency, baseline-fold, activity, and findings facts | --base <ref> (def HEAD) · --short --full --json |
logs | View/tail local activity.jsonl (offline, no server) | -f/--follow --agent --tool --type --since --limit --raw · --json --short |
explain | Narrative chronological timeline + agent/human line-attribution | --agent --since (def 1h) --full · --json |
watch | Server poll: unread messages, pending tasks, active agents (diffs between polls) | --interval (def 10s) · --short --json |
activity isolates local and server read failures: available server events still
render if the local read fails, and local events remain available if the server
client fails. A local read failure with no available server events is reported as
an error.
Event log & raw
| Command | Purpose |
|---|---|
telemetry [-f] [--limit] [--spool <p>] | Tail the raw guard telemetry spool (offline-spool.jsonl: hook_decision rows). |
trace export [--since --agent --output --format json|jsonl] / trace import <file> | Export/import a portable agent-trace (dedups). |
collect [--provider codex --since --dir --dry-run] | Fold Codex rollout history (~/.codex/sessions/) into timeline.jsonl; live Codex hooks capture the twelve native lifecycle/tool events. |
search <query> [--path --glob --type --limit --context --engine] | Local codebase search (ripgrep, native fallback; multi-term → OR + density rank). |
collect retains only the bounded incoming Codex candidate batch (at most
250,000 records / 64 MiB; each rollout file is capped at 64 MiB) and streams
the existing timeline to remove already-seen keys. A corrupt, oversized-row,
or unreadable destination timeline is an error, not an empty history: the
command exits nonzero without appending duplicates. Full timeline rebuilds are
an in-memory sort and therefore explicitly refuse inputs or existing snapshots
over 250,000 records / 64 MiB instead of exhausting application memory.
Audit & maintenance
| Command | Purpose |
|---|---|
audit verify | Verify the tamper-evident, hash-chained guard-decision log (compact archives read first). Bare interlinked audit just prints help — you must pass verify. Not a dependency audit — that's interlinked allowlist verify. |
compact [--dry-run --keep-recent-mb --all] | Lossless gzip + rotate activity.jsonl (safe prefix ≤ sync cursor, audit-chain-aware) PLUS collection.jsonl / timeline.jsonl (plain recent-tail rotation, per-log manifest-<log>.json). Appenders and rotation share a cross-process lock, so appends made during compaction survive. A durable per-log claim precedes final segment publication; retry verifies its source identity, recorded prefix, gzip size, and SHA-256 before completing the SAME segment, even when the process died before the manifest write. Unknown or mismatched segment bytes stay untouched and stop that recovery. While either a durable claim or a legacy claim-less pending manifest row exists, clean and whole-file timeline rebuilds refuse to replace that log; ordinary appends remain allowed so recovery includes later rows. Activity recovery also refuses any recorded sync cursor beyond the retained suffix. Activity compaction refuses a sync cursor beyond the current EOF (unless --all explicitly bypasses sync bounds). All bytes remain recoverable via gunzip in manifest order. |
sync [--dry-run --limit] | Push buffered events to the server (POST /api/hooks/activity/batch, secret+PII scrubbed at egress). Network — use --dry-run for a safe pending count. |
interlinked metrics (whole-repo code-quality scan) lives in interlinked-quality-gates;
interlinked context (effective config) in interlinked-setup.
For measured gate execution, interlinked metrics gates --json separates enabled policy
from actual attempts, fresh source-bound reach, stale/deferred/unavailable work and recorded
latency percentiles. .interlinked/metrics/executions.jsonl is the bounded local execution
journal; malformed/truncated evidence is reported. Historical ratchet file counts are not
current test coverage, and a disabled gate measures nothing. metrics evidence status
lists behavioral receipt freshness; metrics coverage status validates the contribution
index. metrics coverage warm explicitly runs the suite and belongs to
interlinked-quality-gates, so do not trigger its CPU work merely to display status.
For hook-check evidence, harness coverage status --progress --json reads cached
observation time, generation, pending count and job counters without rehashing files
or serializing receipt history. readiness describes that observation, not a fresh
coverage verdict. Plain harness coverage status --json reconciles selected files and
returns full pending identities and receipts. Neither starts recovery; route explicit
harness coverage verify and unresolved check prerequisites to interlinked-verify.
Hook-check receipts with nonempty unavailable retain partial work; their pending version
is not discharged. Do not count them as fully checked files or reusable passing evidence.
For runtime scan profiling, Node's interlinked.coverage-runtime-scan diagnostics channel
emits root, completed flag, bytes read, entries visited and duration even on failed captures.
Subscribers must be in the scanning process. The optional evals/slopcodebench/scan-cost.mjs
preload prints bounded measurements to stderr; it emits no contents or environment values.
interlinked impact — facts, not attributioninterlinked impact [--base <ref>] [--experiment-manifest <path>] [--cwd <path>] [--short|--full|--json] is local and read-only. It compares a verified commit (default HEAD)
with the worktree and reports four evidence classes without promoting one into another:
| Class | Current command contract |
|---|---|
potential | Estimated deltas from valid explicitly recorded simplification receipts. Complete repository/selected-path receipts replace their authoritative scope; partial runs never imply disappearance. One strongest representative is selected per non-null overlap group. |
sandbox-validated | Exact deltas only from a latest recorded finding with a passed Sandbox receipt and non-null validated impact. It is still an unaccepted candidate. |
observed | Recorded facts from verified git/dependency deltas, baseline folds, retained sessions, legacy and simplification finding states, and manual debt-marker lifecycle. Observation is not causation. |
causal | Available only for a strict controlled manifest whose raw-results, analysis-output, safety-receipt, and completeness-coverage artifacts all match their declared SHA-256 values. |
Every class/source is labeled available, not-recorded, or unavailable. An invalid --base
makes git and dependency evidence unavailable rather than silently choosing another comparison.
An explicitly named but unreadable experiment manifest is a command error; malformed manifests
or artifact hash/read failures leave causal evidence unavailable. Untracked paths are counted
without LOC; .interlinked/ evidence files are excluded from that count.
Keep the source scopes separate. Activity edit totals are gross retained events and can overlap
the git delta. A baseline fold records tightened/refused water-lines, not why they changed.
Finding touched or acked states are workflow facts, not proof that a defect was fixed. Never
sum these sources into “saved LOC/time/money,” call them a gain, or say Interlinked caused them.
Data dir: INTERLINKED_DATA_DIR → config.local.json.data_dir → INTERLINKED_HOME →
<cwd>/.interlinked/ (CWD-relative — run from the repo root).
| File | Holds |
|---|---|
activity.jsonl | Full-fidelity legacy stream — ALL event types (lifecycle, prompts, tokens, guard telemetry, tool events). Also the hash-chained audit log. |
collection.jsonl | Canonical normalized tool and agent lifecycle records with provider attribution. |
timeline.jsonl | Transcript records including provider-exposed summaries/text and usage; live appends and backfill can arrive out of event-time order. collect target. |
sessions/<id>.json | Per-session state: agent, phase, tool_count, files, tokens. |
sync-state.json | Sync cursor = byte offset into activity.jsonl. |
costs.jsonl | Incremental per-call token rows read from provider transcripts at Stop/SessionEnd. |
costs-cursor.json | Per-provider, per-actor transcript offsets; prevents replay and keeps sibling Codex subagents independent. |
hook-runtime.json | Payload-free provider execution receipt: event, timestamp, and current hook-definition hash. All adapter runners write provider rows; doctor currently uses the Codex row to detect unreviewed/stale project hooks. |
Claude transcript rows need nonempty string timestamp, UUID and session identifiers before they can produce timeline records. Malformed optional metadata, model names and tool identifiers are omitted. Valid content blocks retain their original sequence index and raw tool payloads; an invalid optional field does not discard the rest of the block. Token usage is included only when its numeric fields are finite. Missing or malformed input is not evidence of an empty turn.
activity.jsonl and collection.jsonl overlap on tool events by design; readers dedup by
event identity (tool_use_id + projected type), not by type — no double-counting, no lost
history. Don't "clean up" by deleting collection rows or dropping tool types from activity.jsonl.
Codex collaboration attribution: Codex currently emits a spawned agent's live hooks with the
parent thread as session_id and no actor/model fields. Interlinked correlates the hook's local
exec-* tool id (or its just-written pending call at PreToolUse) with the spawned rollout under
~/.codex/sessions/, then stamps agent/agent_name with the canonical task path plus
subagent_id, parent_agent, and model. The parent session stays unchanged so one delegated
turn remains a coherent trajectory. interlinked collect --provider codex also understands the
current session_meta.payload.id + source.subagent.thread_spawn shape and writes
agent_id/parent_agent/attribution_agent/is_sidechain into timeline.jsonl. Correlation is fail-open: if
the rollout is missing, stale, outside the repo cwd, or unmatched, the event remains provider-only
rather than receiving a guessed identity. Exact execution-id evidence wins; pending-call fallback
also declines when otherwise-matching evidence names more than one distinct child actor. The first
session_meta owns a rollout file: later duplicate root metadata cannot erase child attribution,
and when both are present the child payload.id takes precedence over root payload.session_id.
Codex token accounting: rollout metrics and the generated hook read
event_msg.payload.type: "token_count" rows and add only
info.last_token_usage, which is the per-call delta. Never sum
total_token_usage; it is cumulative and would multiply usage when appended repeatedly. Codex
input_tokens stays the raw input count, cached_input_tokens maps separately to cache-read,
cache_write_input_tokens maps to cache-creation, and reasoning_output_tokens is recorded without
being added to output a second time. turn_context.payload.model supplies the model. Generated-hook
cursors include provider, transcript path, and actor identity because sibling subagents can share the
parent session_id; agent_transcript_path is the authoritative child transcript at SubagentStop.
OpenCode/Pi observability boundary: their managed bridges emit provider-attributed tool,
prompt, lifecycle, and compaction records, and a loaded bridge leaves an opencode or pi row in
hook-runtime.json. OpenCode maps session.idle and Pi maps agent_settled to normalized Stop,
but both upstream signals are observation-only: no native continuation or veto is implied.
Neither bridge receives dedicated MCP, subagent, or worktree lifecycle events, so the absence of
those rows is an upstream capability gap, not evidence that no such higher-level activity occurred.
The AGENTS lens can label OpenCode/Pi root sessions, but cannot invent subagent lanes without a
native actor event.
logs --type <t> filters the raw event.type exactly (not the uppercase display labels).
Values: session_start, session_end, tool_use_start, tool_use, tool_use_error,
permission_request, user_prompt, subagent_start, subagent_stop, notification,
context_compact, task_completed, agent_stop, and guard telemetry guard_allow /
guard_warn / guard_block.
Sync modes (sync_mode, or INTERLINKED_SYNC_MODE): realtime (default — per-event POST +
session-end batch), local (never posts), manual (per-event POST, no auto batch — you run
interlinked sync).
Every Stop event runs ~20 independent nudge families. They no longer print in
full: src/harness/stop-digest.ts ranks and caps the whole wall to ≤15
stderr lines, and everything it trims goes to the spool.
| Position | Contents |
|---|---|
| TOP | up to 3 warnings printed in full (≤4 lines each), ordered actionable → measurement-threatening → reflection |
| SUMMARY | one line per remaining category: [interlinked:digest] <tag> xN (see …) |
| POINTER | .interlinked/stop-digest.jsonl — the full detail, per-session capped |
Read the spool when a count line is not enough:
interlinked query .interlinked/stop-digest.jsonl --where kind=subagent-attributed
tail -n 40 .interlinked/stop-digest.jsonl | jq -r '[.kind,.tag//.check,.file]|@tsv'Row kinds: stop-warning (a trimmed nudge), subagent-attributed (a finding on
a file a SUBAGENT wrote — attributed via timeline.jsonl and kept out of the
main list), pre-existing (present in the session's git baseline), and
sanctioned-scratch (probe-pattern findings under root scratch/, which the
scratchpad policy sanctions — still reported by interlinked verify --all-checks). The sanctioned classes are what a probe IS: print, no
companion test, import-time side effect, raw JSON.parse, plus the
entry-script family whose own rationale exempts bin/cli files — argv
boundary, env read, unjustified cast, wall clock, magic number. Product
code outside scratch/ keeps every one of them.
Two consequences worth knowing:
test-suite outcome remains one check-level signal
until a targeted test run supplies file-level evidence.R resolved, S unchanged (suppressed) line. Per-session state lives in
.interlinked/.stop-digest-state.json (daemon bookkeeping — do not hand-edit).Activating a change to any of this needs npm run build && interlinked harness restart: the daemon serves the build it started with.
interlinked query stages — where verification time goes.interlinked/verification-stages.jsonl (added 2026-09-28) holds one row per
check per pipeline stage: stage (edit from the hook path, push from the
pre-push hook, cli otherwise), check (vitest:selected, vitest:full,
npm run typecheck:stable, e2e-tests, e2e-merge, …), queue_ms,
(the e2e-merge row's detail carries the merger's per-phase profile —
read_ms, merge_ms, convert_ms, summary_ms plus file, script and
conversion counts — on that ONE row, never as further rows, so --sum post_ms
counts a merge once; measured 2026-09-29 the convert phase was 165 s of a
168 s merge until ast-v8-to-istanbul was pinned at 1.0.7, then 2.7 s),
wait_capacity_ms, validate_ms (runtime snapshot + hash that decides
reuse; paid on hits, misses and early stale returns), lookup_ms, exec_ms,
post_ms, reused and
reuse_denied_reason (no-receipt, plan-not-reusable:<issue>,
stale-inputs, budget-exceeded, capacity-timeout,
memory-budget-unavailable, interrupted, empty-selection). A dry run
never writes a row; a write failure is silent. Rows the pre-push hook writes
inside its disposable export land in the source checkout through
INTERLINKED_STAGES_LEDGER.
interlinked query stages --by reuse_denied_reason # why results are not reused
interlinked query stages --where check=coverage:index # Unit 7: the index route (reused = no shard re-ran; unavailable rows carry the reason)
interlinked query coverage-compare # pre-push comparison mode: full vs index verdict per pushed sha, `agree`
interlinked query stages --by check --sum exec_ms # where the minutes go
interlinked query stages --where stage=push # one push's timelineinterlinked recurrence — repeating-pattern aggregationDeterministic counting/grouping over .interlinked/recurrences.jsonl (no LLM), ranked by count.
Check-health aggregation accepts only caught rows with a nonempty string check ID and a string
timestamp. Optional file, message, and session fields must also be strings when supplied;
malformed rows are skipped. Captured source identities remain open strings so legacy and
internal CLI events retain their original attribution.
Daemon-ledger readers also validate optional fields while preserving legacy and future string
event labels; writers use the current event contract. Gate-reach snapshots validate every nested
gate and skip-count value before comparison. A corrupt newest snapshot leaves the last valid
snapshot available, rather than manufacturing a new measurement.
Four observation kinds (all filterable via --kind):
| Kind | Source | Suggested action |
|---|---|---|
harness_caught | auto — every PostToolUse check failure | ratchet (advisory→default→block) |
harness_missed | manual — recurrence flag <sig> | scaffold a new rule |
codebase_existing | recurrence scan --record (walks the tree, runs inline detectors) | cleanup PR |
tool_failure | auto — repeated tool failures (same tool + error class) | inspect the pattern |
interlinked recurrence list --kind harness_caught --top 10
interlinked recurrence detail <signature> # every event for one row
interlinked recurrence flag raw-sql-concat --message "spotted in db.ts" --file src/db.ts
interlinked recurrence scan --record # append codebase_existing rows
interlinked recurrence propose <signature> # suggested action for one signatureinterlinked viz — the live dashboardinterlinked viz serve [--port 6403] [--root <dir>] # loopback-only HTTP dashboard, live SSE tail of activity
interlinked viz snapshot [--json] [--full] # print the graph summary (no server): "N files · M imports · most depended-on: <id>"viz serve renders the repo as a file/import graph and tails the local logs live over SSE
(daemon not required). It surfaces unscrubbed tool I/O, so it binds loopback only and
blocks until Ctrl-C — don't call it in a one-shot step. While it is listening it writes
.interlinked/viz.status (url= + pid=), which the statusline reads to render a clickable
◈ viz row; the row disappears when that pid dies, so the link is never stale.
Six lenses, each fed by its own SSE route:
| Lens | Route | Source | Shows |
|---|---|---|---|
| FILES | /api/graph + /api/stream | project graph + activity.jsonl | one dot per source file, one line per import, dot size = how many files depend on it; a touched file pulses in the colour of the agent that touched it |
| GATES | /api/checks | check-results.jsonl | one frame per tool call: which checks ran, which fired, allowed or blocked, [proven]/[heuristic] |
| AGENTS | /api/agents | activity.jsonl (folded) | one lane per agent session working in this repo, indented lanes for subagents it spawned: runner, model, calls/edits/blocks/warns, current tool + file, live-vs-idle |
| TESTS | /api/tests | test-events.jsonl | every test case in the order the runner finished it; pass/fail/skip, slow cases outlined, failure messages |
| MUTANTS | /api/mutants | mutation-manifest.json | every mutant, survivors first; live kill-rate; a tile flashes when its status flips |
| DRIFT | — | — | not built yet (standby pane) |
The AGENTS lens needs no producer: attributed activity rows carry agent, session,
subagent_id, parent_agent, and model, so presence is a fold over the stream the dashboard already tails
(src/lib/viz/agent-roster.ts, hosted at /api/agents). Each actor gets a stable hue from its
id, and that hue is reused for its ticker rows and its file pulses — with two sessions running,
colour alone answers "who did that". A subagent gets its OWN lane keyed under its parent, so a
session's own edits are never conflated with its subagents'. When a runner names the parent by
thread/session id, the roster resolves that id through the root lane's session before linking the
child. Lanes dim to idle after 2 minutes of silence rather than disappearing.
The TESTS lens needs a producer. Any repo using vitest adds one line:
// vitest.config.ts
reporters: ["default", "interlinked-cli/viz-reporter"]Gating it behind an env var is the recommended setup, so a normal vitest run stays
byte-identical and only an explicit opt-in emits the feed — that is how interlinked-cli's own
vitest.config.ts wires it: INTERLINKED_VIZ=1 npx vitest run. Any equivalent conditional
works; nothing about the lens requires that variable name. The feed schema
(.interlinked/test-events.jsonl) is runner-agnostic — {kind: run_start|file_start|test|run_end, run_id, lane?, file?, name?, status?, ms?, error?} — so a pytest/cargo adapter writes the same lines
and the lens renders unchanged. Every feed degrades to an honest empty state when its file is
absent; nothing about the dashboard is repo-specific.
The Interlinked CLI e2e config always registers the reporter; test:e2e also
sets INTERLINKED_VIZ=1. The TESTS lens groups files by unit, integration,
e2e, base or unknown lane. A bare Vitest run is base; old rows without
a lane remain unknown. Repository test rows are run evidence. Fixture
ledgers are assertion subjects and do not establish which coding session ran
the tests. The Stop nudge attributes e2e invocations through that session's
observed Bash commands instead.
interlinked status # sessions + last events + sync/server health
interlinked explain --since 30m # narrative timeline of the window
interlinked logs -f --type tool_use_error # tail only failing tool calls, live
interlinked logs --type guard_block --since 1h # what the guard blocked
interlinked recurrence list --kind harness_caught --top 10 # recurring mistakes
interlinked status --full # per-session tools + files + tokens
interlinked impact --base HEAD --full # scoped observed facts + explicit claim boundary
interlinked viz snapshot # one-line dependency-graph summary
interlinked sync --dry-run # safe: pending count, no sendactivity vs logs: activity = merged local+server feed (--json only); logs =
local activity.jsonl only (offline, --tool/--type/--follow). Prefer logs/status/
explain for pure introspection — they never touch the network.watch and the send half of sync are server-only — they need auth (and workspace_id
for localhost dev); watch prints "Not authenticated" offline.sync is restart-safe and memory-bounded: it sends at most 100 events per batch,
checkpoints the byte cursor after each accepted batch, and leaves an unterminated final
JSONL record pending until its newline arrives. Each response body is capped at 256 KiB and
the request timeout remains active until that body is consumed. Run-wide type, agent, tool,
and session summaries retain at most 256 keys per dimension (512 characters per key); JSON
reports breakdown_complete plus exact omission counts in summary_truncated, and a partial
breakdown is never persisted as an exact last-sync summary.status, checkpoint/resume context, and
impact evidence stream at most 10,000 session JSON files, 1 MiB per file, and 32 MiB total.
Crossing a ceiling refuses the scan instead of returning an incomplete list as exact;
ordinary malformed/unreadable legacy rows remain skipped.viz serve / logs -f / watch / telemetry -f block until Ctrl-C.--type filters the raw type (tool_use_error, guard_block), not display labels
(ERROR). Passing an unsupported mode flag to a command errors (flags are per-command).activity.jsonl — the sync cursor is a byte offset; use
interlinked compact (it respects the cursor and audit chain).impact does not create evidence. It can project recorded potential/Sandbox receipts and
verify a supplied controlled experiment's artifact bindings, but it does not run or reproduce
an experiment. No class is a generic savings claim.interlinked metrics (code-quality hotspots) and recurrence scan.watch/sync reach.© 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 3 other files (references) in skills/interlinked-observability of QuentinCody/interlinked-cli.
Open the folder on GitHubat commit 31b5259
Interlinked Observability 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 Observability this skillQuentinCody/interlinked-cli | 178 | — | ~10k | Automated safety check: Pass | MIT | |
| Vercel Optimize Auditvercel-labs/agent-skills | 32k | 9 repos | ~4.3k | Automated safety check: Pass | None | |
| Kubeshark Installerkubeshark/kubeshark | 12k | — | ~3.6k | Automated safety check: Notes | Apache-2.0 | |
| Kubeshark KFL2 Filter Referencekubeshark/kubeshark | 12k | — | ~3.6k | Automated safety check: Pass | Apache-2.0 | |
| KubeSphere ServiceMesh Managerkubesphere/kubesphere | 17k | — | ~2.4k | Automated safety check: Pass | Custom licence | |
| Kubernetes Network Root Cause Analysiskubeshark/kubeshark | 12k | — | ~5.3k | Automated safety check: Pass | Apache-2.0 |
vercel-labs/agent-skills
Runs a metrics-first audit of a deployed Vercel project, gating investigations on real signals to produce ranked, citation-backed cost and performance recommendations.
kubeshark/kubeshark
Installs and configures Kubeshark on a Kubernetes cluster, choosing between the quick CLI path and a Helm install with custom values.
kubeshark/kubeshark
Syntax reference for KFL2, the CEL-based display filter language used to search Kubernetes network traffic captured by Kubeshark, loaded before any filter is written.
kubesphere/kubesphere
Installs, checks and troubleshoots the KubeSphere ServiceMesh extension (Istio, Kiali, Jaeger), including grayscale release, sidecar injection, topology and tracing issues.
kubeshark/kubeshark
Investigates past Kubernetes incidents from Kubeshark traffic snapshots: takes captures, dissects API calls, extracts PCAPs and compares traffic over time.
JuliusBrussee/caveman
Routes every LLM call in a repository through the Caveman Cloud gateway in record mode, so requests and costs are measured without changing behavior.
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
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.
QuentinCody/interlinked-cli
Respond to blocked package installs and manage the Interlinked supply-chain allowlist.
Categories
Investigate agent activity and JSONL/gzip evidence. An agent skill from QuentinCody/interlinked-cli. Interlinked Observability is an agent skill from QuentinCody/interlinked-cli. Investigate agent activity and JSONL/gzip evidence.
Interlinked Observability fits situations like: tasks that involve Observability.
Run `npx skills add QuentinCody/interlinked-cli --skill interlinked-observability -a claude-code`. Or copy the skill folder (skills/interlinked-observability in QuentinCody/interlinked-cli) into .claude/skills/interlinked-observability in your project. Claude Code loads it when a task matches its description.
Run `npx skills add QuentinCody/interlinked-cli --skill interlinked-observability -a codex`. Or copy the skill folder (skills/interlinked-observability in QuentinCody/interlinked-cli) into .agents/skills/interlinked-observability 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-observability -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-observability, .gemini/skills/interlinked-observability, .github/skills/interlinked-observability and .opencode/skills/interlinked-observability in your project.
Going by SKILL.md and its folder, Interlinked Observability needs the command-line tools its instructions call (jq, npm, vitest and npx).
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 Observability is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 10k tokens (SKILL.md is roughly 42k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 4k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Interlinked Observability: Vercel Optimize Audit (vercel-labs/agent-skills, 32k stars), Kubeshark Installer (kubeshark/kubeshark, 12k stars), Kubeshark KFL2 Filter Reference (kubeshark/kubeshark, 12k stars) and KubeSphere ServiceMesh Manager (kubesphere/kubesphere, 17k 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.