Agent skill

Interlinked Observability

by QuentinCody in QuentinCody/interlinked-cli

Investigate agent activity and JSONL/gzip evidence. An agent skill from QuentinCody/interlinked-cli.

MITAuto-check passedDevOps & Cloud

Install Interlinked Observability

skills CLI
$ npx skills add QuentinCody/interlinked-cli --skill interlinked-observability -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install QuentinCody/interlinked-cli interlinked-observability --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ 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-src

Use ~/.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/

Facts

Skill name
interlinked-observability
GitHub stars
178
Token cost
~10k tokens
SKILL.md length
4,945 words
Files
4 (incl. references)
Skills in repo
12
Repo updated
First seen
Licence
MIT

At a glance

Investigate agent activity and JSONL/gzip evidence. An agent skill from QuentinCody/interlinked-cli.

  • Works in 4 steps: Establish scope: project, session/call… → Choose the storage cost deliberately.… → Search with exact filters and a small… → …
  • Tasks that involve Observability
  • SKILL.md covers Search and organize all local…, Load this when, Command surface and interlinked impact — facts,…, plus 8 more sections
  • Calls jq, npm and vitest

What it does

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.

When your agent uses it

  • Tasks that involve Observability

Example prompts

  • “/interlinked-observability”

Workflow steps

4 steps, taken from the first numbered list in SKILL.md.

  1. Establish scope: project, session/call or file, and time window. Read data status --json
  2. Choose the storage cost deliberately. data scan reads JSONL/gzip directly without an
  3. Search with exact filters and a small --limit; correlate relevant records with
  4. Report what was observed, the evidence IDs and hash-verification result, and capture or

What it can do on your machine

Read from SKILL.md and the folder at commit 31b5259. It shows what the files ask for, not the result of running them.

  • Tool permissions

    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.

  • Runs code

    Shell commands in SKILL.md call:

    • jq
    • npm
    • vitest
    • npx

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    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.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

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.

Always · name and description, kept in context so the agent knows when to use it
~120
When it runs · the whole SKILL.md, loaded when a task matches
~10k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~14k

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.

Safety

Auto-check passed

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.

SKILL.md

The full file from QuentinCody/interlinked-cli at commit 31b5259, republished under its MIT licence (© QuentinCody). 4,945 words, ~10,450 tokens.

Download SKILL.mdSave it as .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.
name
interlinked-observability
description
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.

interlinked-observability — inspect what agents did

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.

Search and organize all local evidence

When history can help diagnose a failure or explain prior work, use the logs as evidence:

  1. Establish scope: project, session/call or file, and time window. Read data status --json and data health --json before interpreting missing results.
  2. Choose the storage cost deliberately. 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.
  3. Search with exact filters and a small --limit; correlate relevant records with data investigate, then retrieve supporting IDs with data show ID --json.
  4. Report what was observed, the evidence IDs and hash-verification result, and capture or search limits. Recheck the current code before claiming an old failure is fixed.

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.

bash
interlinked data scan "compiler import" --source check-results --max-mb 32 --limit 10 --full-text --raw --json

Direct 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.

bash
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 --json

Indexing 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).

Load this when

  • "What did I / another agent do this session?" — or you want to tail activity live.
  • Reviewing what the guard blocked or warned.
  • Finding recurring mistakes to harden against.
  • Reporting recorded local changes without turning correlation into a savings or causal claim.
  • Inspecting a specific session, event, or the repo dependency graph.
  • Backfilling external (Codex) sessions, verifying the audit log, or syncing to the server.

Command surface

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

CommandPurposeKey flags
statusLocal-first dashboard: sessions, recent activity, sync + optional server health--watch [s] · --short --full --json
activityRecent feed (local+server merged/deduped, token/cost totals)--agent --limit --since · --json
impactEvidence-classed local git, dependency, baseline-fold, activity, and findings facts--base <ref> (def HEAD) · --short --full --json
logsView/tail local activity.jsonl (offline, no server)-f/--follow --agent --tool --type --since --limit --raw · --json --short
explainNarrative chronological timeline + agent/human line-attribution--agent --since (def 1h) --full · --json
watchServer 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

CommandPurpose
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

CommandPurpose
audit verifyVerify 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 attribution

interlinked 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:

ClassCurrent command contract
potentialEstimated 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-validatedExact deltas only from a latest recorded finding with a passed Sandbox receipt and non-null validated impact. It is still an unaccepted candidate.
observedRecorded facts from verified git/dependency deltas, baseline folds, retained sessions, legacy and simplification finding states, and manual debt-marker lifecycle. Observation is not causation.
causalAvailable 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.

Show full SKILL.md (2,080 more words)Show less

The event-log model

Data dir: INTERLINKED_DATA_DIR → config.local.json.data_dir → INTERLINKED_HOME → <cwd>/.interlinked/ (CWD-relative — run from the repo root).

FileHolds
activity.jsonlFull-fidelity legacy stream — ALL event types (lifecycle, prompts, tokens, guard telemetry, tool events). Also the hash-chained audit log.
collection.jsonlCanonical normalized tool and agent lifecycle records with provider attribution.
timeline.jsonlTranscript records including provider-exposed summaries/text and usage; live appends and backfill can arrive out of event-time order. collect target.
sessions/<id>.jsonPer-session state: agent, phase, tool_count, files, tokens.
sync-state.jsonSync cursor = byte offset into activity.jsonl.
costs.jsonlIncremental per-call token rows read from provider transcripts at Stop/SessionEnd.
costs-cursor.jsonPer-provider, per-actor transcript offsets; prevents replay and keeps sibling Codex subagents independent.
hook-runtime.jsonPayload-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).

The Stop digest — what end-of-turn stderr actually shows

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.

PositionContents
TOPup to 3 warnings printed in full (≤4 lines each), ordered actionable → measurement-threatening → reflection
SUMMARYone 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:

bash
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:

  • The rescan reports introduced-only. A whole-file scan still runs, but a finding your session did not introduce is spooled, not printed.
  • Suite failures are not multiplied into per-file regressions. A cycle reddened only by a whole-suite failure is excluded from the green→red Stop list; the unresolved test-suite outcome remains one check-level signal until a targeted test run supplies file-level evidence.
  • A repeat Stop prints only what is new, plus one 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.

bash
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 timeline

interlinked recurrence — repeating-pattern aggregation

Deterministic 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):

KindSourceSuggested action
harness_caughtauto — every PostToolUse check failureratchet (advisory→default→block)
harness_missedmanual — recurrence flag <sig>scaffold a new rule
codebase_existingrecurrence scan --record (walks the tree, runs inline detectors)cleanup PR
tool_failureauto — repeated tool failures (same tool + error class)inspect the pattern
bash
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 signature

interlinked viz — the live dashboard

bash
interlinked 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:

LensRouteSourceShows
FILES/api/graph + /api/streamproject graph + activity.jsonlone 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/checkscheck-results.jsonlone frame per tool call: which checks ran, which fired, allowed or blocked, [proven]/[heuristic]
AGENTS/api/agentsactivity.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/teststest-events.jsonlevery test case in the order the runner finished it; pass/fail/skip, slow cases outlined, failure messages
MUTANTS/api/mutantsmutation-manifest.jsonevery 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:

ts
// 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.

Common workflows

bash
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 send

Gotchas

  • activity 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.
  • Session summaries are bounded and fail loudly: 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).
  • Don't hand-truncate 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-quality-gates — interlinked metrics (code-quality hotspots) and recurrence scan.
  • interlinked-harness — the guard whose block/warn telemetry you're inspecting.
  • interlinked-coordination — the server-backed side (tasks, messages) watch/sync reach.
  • interlinked-simplification — advisory opportunities whose estimated and validated impact must remain separate.

© QuentinCody, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 3 other files (references) in skills/interlinked-observability of QuentinCody/interlinked-cli.

  • SKILL.md
  • agents/openai.yaml
  • references/evidence-workflows.md
  • references/storage-evaluation.md

Open the folder on GitHubat commit 31b5259

Compare with similar skills

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.

Interlinked Observability compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Interlinked Observability this skillQuentinCody/interlinked-cli178—~10kAutomated safety check: PassMIT
Vercel Optimize Auditvercel-labs/agent-skills32k9 repos~4.3kAutomated safety check: PassNone
Kubeshark Installerkubeshark/kubeshark12k—~3.6kAutomated safety check: NotesApache-2.0
Kubeshark KFL2 Filter Referencekubeshark/kubeshark12k—~3.6kAutomated safety check: PassApache-2.0
KubeSphere ServiceMesh Managerkubesphere/kubesphere17k—~2.4kAutomated safety check: PassCustom licence
Kubernetes Network Root Cause Analysiskubeshark/kubeshark12k—~5.3kAutomated safety check: PassApache-2.0

Similar skills

  • Vercel Optimize Audit

    vercel-labs/agent-skills

    Official

    Runs a metrics-first audit of a deployed Vercel project, gating investigations on real signals to produce ranked, citation-backed cost and performance recommendations.

    32k GitHub starsUsed in 9 repos~4.3k tokens
    DevOps & CloudAuto-check passed
  • Kubeshark Installer

    kubeshark/kubeshark

    Installs and configures Kubeshark on a Kubernetes cluster, choosing between the quick CLI path and a Helm install with custom values.

    12k GitHub stars~3.6k tokensUpdated yesterday
    DevOps & CloudAuto-check: notes
  • 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.

    12k GitHub stars~3.6k tokensUpdated yesterday
    DevOps & CloudAuto-check passed
  • KubeSphere ServiceMesh Manager

    kubesphere/kubesphere

    Installs, checks and troubleshoots the KubeSphere ServiceMesh extension (Istio, Kiali, Jaeger), including grayscale release, sidecar injection, topology and tracing issues.

    17k GitHub stars~2.4k tokensUpdated 2 mo ago
    DevOps & CloudAuto-check passed
  • Investigates past Kubernetes incidents from Kubeshark traffic snapshots: takes captures, dissects API calls, extracts PCAPs and compares traffic over time.

    12k GitHub stars~5.3k tokensUpdated yesterday
    DevOps & CloudAuto-check passed
  • Caveman Gateway Setup

    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.

    110k GitHub starsUsed in 1 repo~2.6k tokens
    DevOps & CloudAuto-check: warnings

More from QuentinCody/interlinked-cli

All 12 skills in this repo
  • Interlinked Cowork

    QuentinCody/interlinked-cli

    Package, test, and operate the experimental Interlinked Cowork plugin.

    178 GitHub stars~1.6k tokensUpdated 6 days ago
    Auto-check passed
  • Interlinked

    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.

    178 GitHub stars~4.1k tokensUpdated 6 days ago
    Auto-check passed
  • Interlinked Coordination

    QuentinCody/interlinked-cli

    Coordinate with other agents/humans via the optional Interlinked MCP Server, and use local checkpoints & file reservations.

    178 GitHub stars~2.9k tokensUpdated 6 days ago
    Auto-check passed
  • Interlinked Semantic Index

    QuentinCody/interlinked-cli

    Install and operate Interlinked's optional local semantic function index.

    178 GitHub stars~1.7k tokensUpdated 6 days ago
    Auto-check passed
  • Interlinked Spec Audit

    QuentinCody/interlinked-cli

    Keep prose specs and design docs honest against the code using Interlinked's spec-audit system.

    178 GitHub stars~3.3k tokensUpdated 6 days ago
    Auto-check passed
  • Interlinked Supply Chain

    QuentinCody/interlinked-cli

    Respond to blocked package installs and manage the Interlinked supply-chain allowlist.

    178 GitHub stars~2.8k tokensUpdated 6 days ago
    Auto-check passed

Categories

Questions about Interlinked Observability

What does Interlinked Observability do?

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.

When should I use Interlinked Observability?

Interlinked Observability fits situations like: tasks that involve Observability.

How do I install Interlinked Observability in Claude Code?

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.

How do I install Interlinked Observability in Codex?

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.

Can I use Interlinked Observability in Cursor, Gemini CLI or GitHub Copilot?

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.

What does Interlinked Observability need to run?

Going by SKILL.md and its folder, Interlinked Observability needs the command-line tools its instructions call (jq, npm, vitest and npx).

Does Interlinked Observability access the network?

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.

Is Interlinked Observability safe to install?

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.

What licence does Interlinked Observability use?

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.

How many tokens does Interlinked Observability use?

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.

What are the alternatives to Interlinked Observability?

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.

Who maintains Interlinked Observability?

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.