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-inspectTelemetry 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:analyticsoutput 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
- Writer activity — for each registered telemetry file, recent write count (from mtime scan) and last-write delta
- File health — size (warn at 256 KB, critical at 1 MB), line count, mtime
- Schema lock status — which files have validators in
lib/telemetry-schemas.ts - 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) - Growth trend — bytes per hour since session start (fire alert if > 100 KB/hr)
- Coordination layer (M168) — live counts from
sessions.db(running sessions, held locks, pending worktree links, skill invocations) plus write throughput fromcoordination-metrics.jsonl
Usage
/ork:telemetry-inspect
/ork:telemetry-inspect --session sess-abc123
/ork:telemetry-inspect --jsonDefault 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/hrImplementation plan (for an agent/LLM running this skill)
- List known files — read
lib/telemetry-schemas.ts'sSCHEMA_LOCKEDinventory for the 7 locked paths. Extend with a hardcoded inventory of the other 14 unlocked paths (copy from the skill-localreferences/telemetry-inventory.md). - For each file:
- Use
Globto resolve.claude/state/ork-metrics-*.jsonpattern → may be multiple - Use
Readwithlimit: 10to see shape andBash wc -lfor line count - Use
Bash statfor mtime + size
- Use
- Classify health:
- size > 1 MB → critical
- size > 256 KB → warn
- mtime > 7 days → "no recent writes"
- line count 0 → "no writes"
- Orphan scan —
Bash find .claude/\{telemetry,logs,state,feedback\} -type fcross-check against registered paths. Any on-disk files not in inventory → orphan. - Render report — ASCII table by default, JSON if
--jsonargument 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/:
| Source | What it tells you |
|---|---|
sessions.db | live session / lock / worktree state (SQLite) |
events.jsonl | coordination event stream (goal_converged, chain_stale, …) |
coordination-metrics.jsonl | sessions.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 invocationsWrite throughput — coordination-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.countnow also counts PRs/MRs filed via MCP tools (e.g., GitHub MCPcreate_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. Seereferences/../monitoring-observability/references/metrics-collection.mdfor the join pattern that distinguishes MCP- from shell-filed PRs. - CC 2.1.161+:
OTEL_RESOURCE_ATTRIBUTESvalues 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.toolOTEL spans carryagent_id+parent_agent_id, and background subagent spans nest under the dispatching Agent tool span. Build the trace tree by querying onparent_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+:
/usageexposes 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
/workflowsrun) carriesworkflow.run_id+workflow.nameattributes, so a whole workflow run is reconstructable from OTel — group all agent events onworkflow.run_idto rebuild one run's fan-out, and slice byworkflow.name. See../analytics/references/otel-fields.md("From 2.1.202") for the field table; filterselect(.["workflow.run_id"] != null)first, since ordinary session events lack these attributes.
Related
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:
| Helper | Source | Target 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:55 | getAnalyticsDir() = .claude/memory/analytics/ (NOT .claude/logs/) |
logHook() / logPermissionFeedback() | lib/log.ts:51,75 | getLogDir() = .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)
| Path | Writer (hook) | Schema validator |
|---|---|---|
.claude/telemetry/image-responses.jsonl | posttool/context-crossing-warn | isValidImageResponseEntry |
.claude/telemetry/pre-compact-decisions.jsonl | lifecycle/pre-compact-task-done-prompt | isValidPreCompactDecisionEntry |
.claude/logs/decisions.jsonl | none — 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.jsonl | pretool/task/spawn-intent-logger, subagent-start/subagent-validator | isValidSubagentSpawnEntry |
.claude/state/edit-history.jsonl | posttool/write/edit-history-tracker | isValidEditHistoryEntry |
.claude/state/ork-metrics-*.json | posttool/metrics-bridge | isValidOrkMetricsSnapshot |
.claude/logs/skill-channels.jsonl | pretool/skill/skill-tracker (main channel — dispatch restored 2026-07-09 after the #959 drop), subagent-stop/skill-channel-tracker (subagent channel) | isValidSkillChannelEntry |
image-responses.jsonlandskill-channels.jsonlare 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.jsonlis 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.jsonwas removed fromSCHEMA_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, sotelemetry-inspectnow correctly flags it as an orphan rather than an expected writer.
Live unlocked writers — no schema validator yet
.claude/telemetry/
| Path | Writer |
|---|---|
.claude/telemetry/events.jsonl | lib/telemetry-jsonl (writeTelemetryEvent, via lib/jsonl-sink) |
.claude/logs/
| Path | Writer |
|---|---|
.claude/logs/task-completions.jsonl | task-completed/completion-tracker (appendEventLog) |
.claude/logs/task-creations.jsonl | task-created/creation-tracker (appendEventLog) |
.claude/logs/memory-consult.jsonl | pretool/mcp/memory-validator (appendEventLog) |
.claude/logs/teammate-activity.jsonl | posttool/task/team-member-start, teammate-idle/progress-reporter (appendEventLog) |
.claude/logs/worktree-events.jsonl | worktree/exit-finalizer (appendEventLog) |
.claude/logs/config-changes.jsonl | config-change/settings-reload |
.claude/logs/config-audit.jsonl | posttool/config-change/security-auditor |
.claude/logs/context7-telemetry.log | pretool/mcp/context7-tracker |
.claude/logs/hooks.log | lib/log.ts (logHook, all hooks) |
.claude/logs/permission-feedback.log | lib/log.ts (logPermissionFeedback) |
.claude/logs/permission-denials.jsonl | permission-denied/denial-logger, permission-denied/denial-notification |
.claude/logs/audit.log | posttool/audit-logger, lifecycle/session-cleanup, agent/security-command-audit |
.claude/logs/agent-state.json | subagent-start/context-gate |
.claude/state/
| Path | Writer |
|---|---|
.claude/state/goal-history.jsonl | lifecycle/goal-budget-guard, prompt/goal-tracker |
.claude/state/goal-budget-tripped.json | lifecycle/goal-budget-guard, prompt/goal-tracker |
.claude/state/last-test-run.json | pretool/bash/pre-commit-test-gate |
.claude/state/plugins-snapshot.json | lifecycle/plugins-drift-snapshot, posttool/check-plugins-drift |
.claude/state/dev-stack.json | lib/dev-stack-state |
.claude/state/expect-auto-fires.json | posttool/ui-change-detector |
.claude/state/expect-snapshots/ | posttool/expect/snapshot-recorder |
.claude/state/worktree-advisory-*.md | lib/worktree-advisory (consumed by prompt/worktree-advisory-consumer) |
.claude/state/session-*-token-accum.json | session token-accumulator hook |
.claude/feedback/
| Path | Writer |
|---|---|
.claude/feedback/code-style-profile.json | posttool/write/code-style-learner |
.claude/feedback/naming-conventions.json | posttool/write/naming-convention-learner |
.claude/feedback/tool-preferences.json | posttool/tool-preference-learner |
.claude/feedback/learned-patterns.json | lifecycle/pattern-sync-push, lifecycle/pattern-sync-pull, permission/learning-tracker |
.claude/feedback/patterns-queue.json | posttool/bash/pattern-extractor |
.claude/feedback/consent-log.json | lifecycle/analytics-consent-check |
.claude/feedback/dependency-check-cache.json | lifecycle/dependency-version-check |
.claude/feedback/changelog-decisions.json | lib/decision-history |
.claude/feedback/instruction-drift-cache.json | instructions-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.
| Path | Last write | Root cause |
|---|---|---|
.claude/feedback/skill-usage.json | 2026-03-06 | Writer 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.log | Writer 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.jsonl | 2026-03-03 | No current writer; last source touch was M168 (#2015), which moved skill usage to the SQLite skill_invocation table. |
.claude/logs/memory-metrics.jsonl | 2026-03-03 | Referenced in lifecycle/unified-dispatcher; not currently emitting. Verify before re-wiring. |
.claude/logs/agent-patterns.jsonl | 2026-02-12 | No writer source file has ever existed — pure disk orphan. |
.claude/logs/background-hooks.log | 2026-02-08 | No writer source file has ever existed — pure disk orphan. |
.claude/feedback/satisfaction.json / satisfaction.log | 2026-01-23 / 2026-03-06 | Writer source removed in #959. |
.claude/feedback/workflow-patterns.json | 2026-03-06 | No writer in source — pure orphan. |
.claude/feedback/calibration-data.json | 2026-03-06 | No writer in source — pure orphan. |
.claude/feedback/evolution-registry.json | 2026-01-22 | No writer in source — pure orphan. |
Directory health budgets
| Directory | Target max total size | Action if exceeded |
|---|---|---|
.claude/telemetry/ | 5 MB | rotate oldest JSONL lines (rotateTelemetryIfNeeded) |
.claude/logs/ | 10 MB | archive *.old.* to .claude/logs/archive/ |
.claude/state/ | 2 MB | truncate; state is ephemeral |
.claude/feedback/ | 5 MB | consolidate patterns |
How to add a new telemetry file
- Add the writer (hook) that produces it — route through
appendEventLog(.claude/logs/) orwriteTelemetryEvent(.claude/telemetry/). - Add an entry to the appropriate section above.
- If the file has a stable shape, add a validator to
lib/telemetry-schemas.ts, append to theSCHEMA_LOCKEDarray (currently 7), and promote it to the Schema-locked table. - Add tests to
__tests__/lib/telemetry-schemas.test.ts(including theSCHEMA_LOCKED.lengthcount assertion).
How to retire a telemetry file
- Remove or unwire the writer.
- Remove its
SCHEMA_LOCKEDentry (and update the length assertion in the test) sotelemetry-inspectreports the leftover file as an orphan instead of an expected writer. - Move it to the Deprecated section above with the removal commit + date.
Task Dependency Patterns
Task Management patterns with TaskCreate, TaskUpdate, TaskGet, TaskList tools. Decompose complex work into trackable tasks with dependency chains. Use when managing multi-step implementations, coordinating parallel work, or tracking completion status.
Testing E2e
End-to-end testing patterns with Playwright — page objects, AI agent testing, visual regression, accessibility testing with axe-core, and CI integration. Use when writing E2E tests, setting up Playwright, implementing visual regression, or testing accessibility.
Last updated on