OrchestKit · Channel-Aware Skill Telemetry

Improvement ① — close the telemetry blind spot. Skill usage was logged on one channel (the main-session Skill tool); subagent, chain, and background invocations were invisible. This PR tags every invocation with the channel it fired through, so the activation matrix can be computed from real telemetry instead of static analysis.

PR feat/skill-channel-telemetry sink .claude/logs/skill-channels.jsonl schema-locked isValidSkillChannelEntry built 2026-06-01

The blind spot why "20 dead" looked real

  user types /ork:x ──[PreToolUse·Skill]──▶ logged  (main channel)
  skill A → /ork:B ──[same hook]──────────▶ logged  (also main — chain split is a follow-up)
  agent calls Skill ─[isolated context]───▶ NEVER LOGGED  ← the big blind spot
  ci-sentinel headless ─[separate session]─▶ NEVER LOGGED

Read one channel → the prior audit's "20/31 dead". The fix is to measure the other channels, starting with the largest: subagent.

The 4 activation channels where each is captured

LIVE

main

PreToolUse · Skill

Every main-session Skill call (user-direct or chained). Enriched skill-tracker writes a channel:"main" row.

LIVE

subagent

SubagentStop · transcript

NEW handler reads agent_transcript_path, extracts every Skill tool_use, writes channel:"subagent" tagged with the agent.

NEXT

chain

skill-stack heuristic

Split main → direct vs chain via a per-turn skill stack. Schema field reserved; capture deferred.

NEXT

background

headless session tag

Tag cron/headless runs (ci-sentinel, dream). Schema field reserved; capture deferred.

Measurement coverage what telemetry can see

BEFORE
mainmeasured
subagentinvisible
chaininvisible
backgroundinvisible
1 / 4 channels — static analysis fills the rest (a guess)
AFTER (this PR)
mainmeasured
subagentmeasured ✅
chainreserved
backgroundreserved
2 / 4 measured — the largest blind spot (1,702 agent spawns) now visible

The enriched row click a channel

One JSONL row per invocation in .claude/logs/skill-channels.jsonl, schema-locked + drift-gated. Backward compatible — readers default missing channel to main.


    

What ships here vs next

✅ This PR

  • SkillChannelEntry schema + validator + lock test (SCHEMA_LOCKED → 8)
  • recordSkillChannel() buffered writer
  • skill-tracker enriched → channel:"main"
  • NEW SubagentStop skill-channel-trackerchannel:"subagent"
  • 15 vitest cases · 504 subagent-stop tests still green