Skip to main content
OrchestKit v8.74.0 — 114 skills, 37 agents, 216 hooks · Claude Code 2.1.206+
OrchestKit
Skills

Telemetry Inspect

Inspects the OrchestKit telemetry pipeline for the current project — lists all known telemetry files with write counts, sizes, schema status, growth trend, and orphan detection. Use when verifying the observability pipeline is healthy, debugging a missing writer, or auditing which files have schema locks vs. which are drift-vulnerable. Read-only — never modifies telemetry files.

Command low
Invoke
/ork:telemetry-inspect

Telemetry Inspect Inspects the OrchestKit telemetry pipeline for the current project — lists all known telemetry files with write counts, sizes, schema status, growth trend, and orphan detection. Use when verifying the observability pipeline is healthy, debugging a missing writer, or auditing which files have schema locks vs. which are drift-vulnerable. Read-only — never modifies telemetry files.

/ork:telemetry-inspect

One-shot health check for OrchestKit's telemetry pipeline. Reports writer activity, file sizes, schema lock coverage, orphan files, and growth warnings. Use when verifying the pipeline is flowing correctly or debugging a missing writer.

When to use

  • Before or after a risky hook refactor, to prove telemetry still writes as expected
  • Weekly health check on a long-running project
  • When /ork:analytics output looks suspicious — inspect the underlying data first
  • When adding a new telemetry file and wanting to confirm it's picked up
  • Auditing which files are schema-locked vs. drift-vulnerable

What it checks

  1. Writer activity — for each registered telemetry file, recent write count (from mtime scan) and last-write delta
  2. File health — size (warn at 256 KB, critical at 1 MB), line count, mtime
  3. Schema lock status — which files have validators in lib/telemetry-schemas.ts
  4. Orphan detection — files on disk under .claude/\{telemetry,logs,state,feedback\}/ that aren't in the registry (possible stale writer or new file needing schema)
  5. Growth trend — bytes per hour since session start (fire alert if > 100 KB/hr)
  6. Coordination layer (M168) — live counts from sessions.db (running sessions, held locks, pending worktree links, skill invocations) plus write throughput from coordination-metrics.jsonl

Usage

/ork:telemetry-inspect
/ork:telemetry-inspect --session sess-abc123
/ork:telemetry-inspect --json

Default mode: terminal-friendly ASCII report. --json emits a structured result suitable for piping into another tool or uploading.

Output shape (ASCII mode)

Telemetry Health — 2026-07-09 11:50
────────────────────────────────────

Schema-locked files (7)
  .claude/telemetry/pre-compact-decisions.jsonl  ◆ 3 lines  1.1 KB  ✓ healthy
  .claude/telemetry/image-responses.jsonl        ◆ 0 lines  —       ✗ no writes
  .claude/logs/decisions.jsonl                   ◆ 0 lines  —       ✗ no writes
  .claude/logs/subagent-spawns.jsonl             ◆ 6 lines  3 KB    ✓ healthy
  .claude/state/edit-history.jsonl               ◆ 94 lines 412 KB  ⚠ rotate
  .claude/state/ork-metrics-*.json               ◆ (N/A)    2.1 KB  ✓ healthy
  .claude/logs/skill-channels.jsonl              ◆ 12 lines 4 KB    ✓ healthy

Unlocked telemetry files (14)
  .claude/feedback/changelog-decisions.json      ○ 4 KB    ✗ no schema
  .claude/feedback/code-style-profile.json       ○ 8 KB    ✗ no schema
  (...14 more...)

Orphan files (1)
  .claude/feedback/skill-usage.json  — delisted, writer unwired since #959

Summary
  Pipeline health:  GREEN  (21/21 expected writers active)
  Schema coverage:  7/21 (33%)
  Largest file:     edit-history.jsonl (412 KB)
  Hotspot:          edit-history.jsonl  +40 KB/hr

Implementation plan (for an agent/LLM running this skill)

  1. List known files — read lib/telemetry-schemas.ts's SCHEMA_LOCKED inventory for the 7 locked paths. Extend with a hardcoded inventory of the other 14 unlocked paths (copy from the skill-local references/telemetry-inventory.md).
  2. For each file:
    • Use Glob to resolve .claude/state/ork-metrics-*.json pattern → may be multiple
    • Use Read with limit: 10 to see shape and Bash wc -l for line count
    • Use Bash stat for mtime + size
  3. Classify health:
    • size > 1 MB → critical
    • size > 256 KB → warn
    • mtime > 7 days → "no recent writes"
    • line count 0 → "no writes"
  4. Orphan scanBash find .claude/\{telemetry,logs,state,feedback\} -type f cross-check against registered paths. Any on-disk files not in inventory → orphan.
  5. Render report — ASCII table by default, JSON if --json argument passed.

Core logic is deterministic + read-only. Do NOT write to any telemetry file — this skill is an observer.

Coordination layer (M168 #1915)

The SQLite coordination layer lives outside .claude/, at ~/.local/state/orchestkit/:

SourceWhat it tells you
sessions.dblive session / lock / worktree state (SQLite)
events.jsonlcoordination event stream (goal_converged, chain_stale, …)
coordination-metrics.jsonlsessions.db write throughput counters (#1915)

Live counts — the DB file is a standard SQLite database; read it with sqlite3 (read-only SELECTs only):

DB="$HOME/.local/state/orchestkit/sessions.db"
[ -f "$DB" ] || echo "coordination layer idle (no multi-session activity yet)"
sqlite3 "$DB" "SELECT COUNT(*) FROM sessions WHERE status='running'"                  # live sessions
sqlite3 "$DB" "SELECT COUNT(*) FROM locks WHERE expires_at > strftime('%s','now')"    # held locks
sqlite3 "$DB" "SELECT COUNT(*) FROM worktree_links WHERE result_status IS NULL"       # pending worktrees
sqlite3 "$DB" "SELECT COUNT(*) FROM skill_invocation"                                 # skill invocations

Write throughputcoordination-metrics.jsonl is append-only \{ts, metric, count\} lines emitted async by lib/metrics-emitter.ts on every sessions.db write. Event rate ≈ recent sessions_db_write lines:

M="$HOME/.local/state/orchestkit/coordination-metrics.jsonl"
[ -f "$M" ] && tail -200 "$M" | grep -c '"sessions_db_write"'

Degrade gracefully: if sqlite3 is absent or the DB / metrics file doesn't exist, report "coordination layer idle" — never error. Like the rest of this skill, these are read-only observations.

Upstream OTel metric notes

When inspecting Claude Code's own OTel metrics (downstream of this skill — claude_code.* in your collector):

  • CC 2.1.129+: claude_code.pull_request.count now also counts PRs/MRs filed via MCP tools (e.g., GitHub MCP create_pull_request), not just shell commands run through the Bash tool. Dashboards built before 2.1.129 will see a step-function increase at the cutover — annotate, don't alert. See references/../monitoring-observability/references/metrics-collection.md for the join pattern that distinguishes MCP- from shell-filed PRs.
  • CC 2.1.161+: OTEL_RESOURCE_ATTRIBUTES values are now attached as labels on all metric datapoints, enabling dimensional slicing (team, repo, environment). Existing dashboards keep working; new dashboards should use label selectors to segment usage.
  • CC 2.1.145+: claude_code.tool OTEL spans carry agent_id + parent_agent_id, and background subagent spans nest under the dispatching Agent tool span. Build the trace tree by querying on parent_agent_id — enables per-skill fan-out timing and cost attribution for multi-agent skills (brainstorm, explore, implement); no schema change needed.
  • CC 2.1.174+: /usage exposes CC-native per-component attribution — cache misses, long context, subagents, and per-skill/agent/plugin/MCP cost breakdowns over 24h/7d (surfaced first in the VSCode Account & usage dialog). Treat it as a cross-check source in the health report: if ork telemetry shows a skill/agent active but CC attribution shows zero usage for it (or vice versa), flag the divergence as a possible missing writer or stale install rather than trusting either side alone.
  • CC 2.1.202+: telemetry from workflow-spawned agents (a /workflows run) carries workflow.run_id + workflow.name attributes, so a whole workflow run is reconstructable from OTel — group all agent events on workflow.run_id to rebuild one run's fan-out, and slice by workflow.name. See ../analytics/references/otel-fields.md ("From 2.1.202") for the field table; filter select(.["workflow.run_id"] != null) first, since ordinary session events lack these attributes.
  • lib/telemetry-schemas.ts — source of truth for schema-locked paths
  • /ork:analytics — aggregates data across sessions (different use case)
  • M121 "Observability Consolidation" milestone

References (1)

Telemetry Inventory

OrchestKit Telemetry File Inventory

Single source of truth listing every file that OrchestKit hooks write to. The telemetry-inspect skill reads this inventory to distinguish "expected" files from orphans.

Last updated: 2026-07-09 (live writer census)

Path routing helpers

Writers do not hard-code directories — they go through four helpers. Know these to attribute any file:

HelperSourceTarget directory
writeTelemetryEvent()lib/telemetry-jsonl.ts.claude/telemetry/ (or plugin-data/telemetry on CC ≥ 2.1.78)
appendEventLog(file, entry)lib/event-logger.ts:17<project>/.claude/logs/
appendAnalytics(file, entry)lib/analytics.ts:55getAnalyticsDir() = .claude/memory/analytics/ (NOT .claude/logs/)
logHook() / logPermissionFeedback()lib/log.ts:51,75getLogDir() = .claude/logs/

Note: appendAnalytics writes its own filename set (task-usage.jsonl, team-activity.jsonl, agent-usage.jsonl, subagent-quality.jsonl, session-summary.jsonl) into the analytics dir — distinct from the .claude/logs/ files below, and dual-writes to the yonatan-hq platform sink via postAnalyticsToSink.

Schema-locked files (7) — validators in lib/telemetry-schemas.ts (SCHEMA_LOCKED)

PathWriter (hook)Schema validator
.claude/telemetry/image-responses.jsonlposttool/context-crossing-warnisValidImageResponseEntry
.claude/telemetry/pre-compact-decisions.jsonllifecycle/pre-compact-task-done-promptisValidPreCompactDecisionEntry
.claude/logs/decisions.jsonlnone — producer never built (schema shipped in M121 d5ea63562 without a writer; lifecycle/pre-compact-saver, stop/handoff-writer, prompt/context-exhaustion-warner are READERS that degrade gracefully on absence)isValidDecisionLogEntry
.claude/logs/subagent-spawns.jsonlpretool/task/spawn-intent-logger, subagent-start/subagent-validatorisValidSubagentSpawnEntry
.claude/state/edit-history.jsonlposttool/write/edit-history-trackerisValidEditHistoryEntry
.claude/state/ork-metrics-*.jsonposttool/metrics-bridgeisValidOrkMetricsSnapshot
.claude/logs/skill-channels.jsonlpretool/skill/skill-tracker (main channel — dispatch restored 2026-07-09 after the #959 drop), subagent-stop/skill-channel-tracker (subagent channel)isValidSkillChannelEntry

image-responses.jsonl and skill-channels.jsonl are schema-locked but may be absent on disk for a given project — they are written only when their trigger fires (image bytes in a tool result; a Skill invocation). Absence is not an orphan.

Known gap: decisions.jsonl is schema-locked with NO producer — the M121 observability consolidation shipped its schema, lock, and three readers, but the writer was never built. Absence is guaranteed, not conditional. Follow-up: build the producer or drop the lock.

Delisted 2026-07-09: .claude/feedback/skill-usage.json was removed from SCHEMA_LOCKED — its writer has been unwired since 2026-03-06 (see Deprecated section). The validator / canonical / interface are retained for back-compat shape-checking of the frozen file, but the path is no longer schema-locked, so telemetry-inspect now correctly flags it as an orphan rather than an expected writer.

Live unlocked writers — no schema validator yet

.claude/telemetry/

PathWriter
.claude/telemetry/events.jsonllib/telemetry-jsonl (writeTelemetryEvent, via lib/jsonl-sink)

.claude/logs/

PathWriter
.claude/logs/task-completions.jsonltask-completed/completion-tracker (appendEventLog)
.claude/logs/task-creations.jsonltask-created/creation-tracker (appendEventLog)
.claude/logs/memory-consult.jsonlpretool/mcp/memory-validator (appendEventLog)
.claude/logs/teammate-activity.jsonlposttool/task/team-member-start, teammate-idle/progress-reporter (appendEventLog)
.claude/logs/worktree-events.jsonlworktree/exit-finalizer (appendEventLog)
.claude/logs/config-changes.jsonlconfig-change/settings-reload
.claude/logs/config-audit.jsonlposttool/config-change/security-auditor
.claude/logs/context7-telemetry.logpretool/mcp/context7-tracker
.claude/logs/hooks.loglib/log.ts (logHook, all hooks)
.claude/logs/permission-feedback.loglib/log.ts (logPermissionFeedback)
.claude/logs/permission-denials.jsonlpermission-denied/denial-logger, permission-denied/denial-notification
.claude/logs/audit.logposttool/audit-logger, lifecycle/session-cleanup, agent/security-command-audit
.claude/logs/agent-state.jsonsubagent-start/context-gate

.claude/state/

PathWriter
.claude/state/goal-history.jsonllifecycle/goal-budget-guard, prompt/goal-tracker
.claude/state/goal-budget-tripped.jsonlifecycle/goal-budget-guard, prompt/goal-tracker
.claude/state/last-test-run.jsonpretool/bash/pre-commit-test-gate
.claude/state/plugins-snapshot.jsonlifecycle/plugins-drift-snapshot, posttool/check-plugins-drift
.claude/state/dev-stack.jsonlib/dev-stack-state
.claude/state/expect-auto-fires.jsonposttool/ui-change-detector
.claude/state/expect-snapshots/posttool/expect/snapshot-recorder
.claude/state/worktree-advisory-*.mdlib/worktree-advisory (consumed by prompt/worktree-advisory-consumer)
.claude/state/session-*-token-accum.jsonsession token-accumulator hook

.claude/feedback/

PathWriter
.claude/feedback/code-style-profile.jsonposttool/write/code-style-learner
.claude/feedback/naming-conventions.jsonposttool/write/naming-convention-learner
.claude/feedback/tool-preferences.jsonposttool/tool-preference-learner
.claude/feedback/learned-patterns.jsonlifecycle/pattern-sync-push, lifecycle/pattern-sync-pull, permission/learning-tracker
.claude/feedback/patterns-queue.jsonposttool/bash/pattern-extractor
.claude/feedback/consent-log.jsonlifecycle/analytics-consent-check
.claude/feedback/dependency-check-cache.jsonlifecycle/dependency-version-check
.claude/feedback/changelog-decisions.jsonlib/decision-history
.claude/feedback/instruction-drift-cache.jsoninstructions-loaded/drift-detection

Deprecated / orphaned files (writer removed or unwired — flag as orphans, do not re-create)

These files exist on disk from historical runs but have no reachable writer at HEAD. All froze on the dates shown.

PathLast writeRoot cause
.claude/feedback/skill-usage.json2026-03-06Writer posttool/skill/skill-usage-optimizer unwired by commit e3e99b2ff (#959, "PostToolUse: 17→3 sub-hooks"). Function + dispatch-map entry survive but no hooks.json entry invokes the key → unreachable. Superseded by M168 (#2015) skill_invocation SQLite table. Delisted from SCHEMA_LOCKED 2026-07-09.
.claude/logs/skill-usage.log2026-03-06 revived 2026-07-09Writer pretool/skill/skill-tracker was unwired in the same #959 prune, but unlike the optimizer it is NOT superseded — it is the sole feeder of the M168 skill_invocation SQLite table (recordInvocation) and of skill-channels.jsonl main (#2154). Dispatch restored in hooks.json; live again.
.claude/logs/skill-analytics.jsonl2026-03-03No current writer; last source touch was M168 (#2015), which moved skill usage to the SQLite skill_invocation table.
.claude/logs/memory-metrics.jsonl2026-03-03Referenced in lifecycle/unified-dispatcher; not currently emitting. Verify before re-wiring.
.claude/logs/agent-patterns.jsonl2026-02-12No writer source file has ever existed — pure disk orphan.
.claude/logs/background-hooks.log2026-02-08No writer source file has ever existed — pure disk orphan.
.claude/feedback/satisfaction.json / satisfaction.log2026-01-23 / 2026-03-06Writer source removed in #959.
.claude/feedback/workflow-patterns.json2026-03-06No writer in source — pure orphan.
.claude/feedback/calibration-data.json2026-03-06No writer in source — pure orphan.
.claude/feedback/evolution-registry.json2026-01-22No writer in source — pure orphan.

Directory health budgets

DirectoryTarget max total sizeAction if exceeded
.claude/telemetry/5 MBrotate oldest JSONL lines (rotateTelemetryIfNeeded)
.claude/logs/10 MBarchive *.old.* to .claude/logs/archive/
.claude/state/2 MBtruncate; state is ephemeral
.claude/feedback/5 MBconsolidate patterns

How to add a new telemetry file

  1. Add the writer (hook) that produces it — route through appendEventLog (.claude/logs/) or writeTelemetryEvent (.claude/telemetry/).
  2. Add an entry to the appropriate section above.
  3. If the file has a stable shape, add a validator to lib/telemetry-schemas.ts, append to the SCHEMA_LOCKED array (currently 7), and promote it to the Schema-locked table.
  4. Add tests to __tests__/lib/telemetry-schemas.test.ts (including the SCHEMA_LOCKED.length count assertion).

How to retire a telemetry file

  1. Remove or unwire the writer.
  2. Remove its SCHEMA_LOCKED entry (and update the length assertion in the test) so telemetry-inspect reports the leftover file as an orphan instead of an expected writer.
  3. Move it to the Deprecated section above with the removal commit + date.
Edit on GitHub

Last updated on