telemetry

star 612

Unified telemetry hub. Shows current session cost, today's spend, all-time totals, hook activity, trust level, and a directory of every telemetry command available. Also the control surface to toggle telemetry on/off and tune thresholds. Single entry point for anyone asking "what does this cost" or "what telemetry does Citadel have".

SethGammon By SethGammon schedule Updated 6/11/2026

name: telemetry license: MIT description: >- Unified telemetry hub. Shows current session cost, today's spend, all-time totals, hook activity, trust level, and a directory of every telemetry command available. Also the control surface to toggle telemetry on/off and tune thresholds. Single entry point for anyone asking "what does this cost" or "what telemetry does Citadel have". user-invocable: true auto-trigger: false trigger_keywords: - telemetry - what did this cost - session cost - how much did that cost - how much have I spent - what hooks fired - trust level - show me telemetry - spending - session stats - what telemetry - verify audit - audit integrity - check audit - tampered records last-updated: 2026-04-09

/telemetry — Telemetry Hub

When to Use

  • "What does Citadel track?" / "What telemetry does it have?"
  • "What did this session cost?" / "How much have I spent?"
  • "How do I turn off the cost alerts?" / "Can I disable telemetry?"
  • "Show me hook activity" / "What hooks fired?"
  • "What trust level am I at?"
  • Directly: /telemetry

Routed here by /do for: "telemetry", "what did this cost", "session stats", "session cost", "how much did that cost", "what hooks fired", "trust level", "show me telemetry", "cost breakdown", "spending".

Commands

Command Behavior
/telemetry Full hub — stats + command directory + settings
/telemetry --costs Cost section only: session, today, all-time, by campaign
/telemetry --hooks Hook activity only: last 20 fires with timing and outcomes
/telemetry --verify Telemetry and artifact integrity check: verify hashes/signatures, flag tampered records, report legacy records
/telemetry --config Show current telemetry settings from harness.json
/telemetry off Disable session summary, reduce hook verbosity
/telemetry on Re-enable all telemetry
/telemetry --threshold N Set cost alert threshold step (e.g. --threshold 10 = alert every $10)

Protocol

Step 1: COLLECT DATA

Read the following in parallel. All are optional — treat missing files as zero/empty.

Live session cost:

  • Run node scripts/session-tokens.js --today 2>/dev/null — captures real token data
  • If unavailable, read .planning/telemetry/cost-tracker-state.json for burn rate
  • Real cost is always preferred over estimated. Mark clearly: $X.XX vs $X.XX (est)

Historical costs:

  • Run node scripts/session-tokens.js --all 2>/dev/null for all-time real totals
  • Read last 20 lines of .planning/telemetry/session-costs.jsonl for recent sessions
  • For each entry: prefer real_cost > override_cost > estimated_cost

Hook activity:

  • Read last 20 lines of .planning/telemetry/hook-timing.jsonl
  • For each event: "timing" entry: extract hook, duration_ms, timestamp
  • For each event: "counter" entry: extract hook, metric
  • Check .planning/telemetry/hook-errors.jsonl (last 20 lines) for recent blocks

Trust level:

  • Read .claude/harness.jsontrust object
  • Compute: novice (sessions < 5), familiar (5-19), trusted (20+ with 2+ campaigns)
  • If trust.override set, use that

Settings:

  • Read .claude/harness.jsontelemetry object
  • Show current values with defaults if missing

Step 2: RENDER HUB

Output this format. Omit a section only if the data source is completely unavailable.

=== Citadel Telemetry ===

CURRENT SESSION
  Cost:       $X.XX [real] | $X.XX (est)
  Duration:   N min | $X.XX/min burn rate
  Tokens:     NNK input | NK output | NK cache read | NK cache write
  Messages:   N
  Agents:     N spawned
  Hooks fired: N (today)

TODAY
  $X.XX across N sessions
  Most expensive: {slug or "unattached"} — $X.XX

ALL TIME
  $X.XX across N sessions, N campaigns
  Cache savings: ~$X.XX (cache reads vs full input price)

BY CAMPAIGN (recent 5)
  {slug}: $X.XX — N sessions
  _unattached: $X.XX — N sessions

HOOK ACTIVITY (last 10 fires)
  {relative time} | {hook} | {duration_ms}ms | {outcome}
  (no hook timing recorded yet)

TRUST LEVEL
  Level:    {novice | familiar | trusted}
  Sessions: N completed
  Campaigns: N completed
  (novice = 0-4 sessions | familiar = 5-19 | trusted = 20+ with 2+ campaigns)

TELEMETRY SETTINGS
  Enabled:          {true | false}
  Session summary:  {auto | always | off}   ← the [session] line at session end
  Cost alerts:      {on | off}  at thresholds: {list or "default ($5,$15,$30...)"}
  Hook timing:      {on | off}
  Audit log:        {on | off}
  — or, when harness.json is absent —
  (harness.json not found — defaults active)
  → Run /do setup to unlock cost tracking, configure thresholds, and register your install.

COMMAND DIRECTORY
  /telemetry                            This screen
  /telemetry --costs                    Cost breakdown only
  /telemetry --hooks                    Hook activity only
  /telemetry --verify                   Telemetry/artifact integrity check (hash/signature verification)
  /cost                                 Deep cost exploration by session/campaign/week
  /dashboard                            Full harness state (campaigns, fleet, all costs)

  node scripts/session-tokens.js --today   Today's sessions with exact token counts
  node scripts/session-tokens.js --all     All-time totals (real data, not estimates)

  cat .planning/telemetry/session-costs.jsonl   Raw session cost log
  cat .planning/telemetry/hook-timing.jsonl     Raw hook execution log
  cat .planning/telemetry/audit.jsonl           Raw tool call audit log

CONTROLS
  /telemetry off                        Disable session summary + reduce verbosity
  /telemetry on                         Re-enable
  /telemetry --threshold N              Alert every $N (writes to harness.json)
  /telemetry --config                   Edit settings interactively

Step 3: SUB-COMMAND HANDLING

/telemetry off: Set telemetry.sessionSummary = "off" and telemetry.costAlerts = false in harness.json. Output: "Telemetry summary disabled. Hook safety checks remain active." Safety hooks (protect-files, circuit-breaker, external-action-gate) are never disabled.

/telemetry on: Set telemetry.sessionSummary = "auto" and telemetry.costAlerts = true. Output: "Telemetry re-enabled."

/telemetry --threshold N: Validate N is positive. Generate [N, N*2, N*5, N*10, N*20, N*50, N*100] (capped at 500). Write to harness.json under policy.costTracker.thresholds.

/telemetry --verify: Run the project verifier:

node scripts/verify-telemetry-integrity.js

The verifier scans .planning/telemetry/*.jsonl and .planning/artifacts/*.jsonl. Display verified, signed, legacy, tampered, invalid, and signature-warning counts. Use --strict-legacy only when old unsigned records should fail the check.

Output format:

=== Telemetry Integrity ===

file.jsonl
  Total records:    N
  Verified (hash):  N
  Verified (signed): N
  Legacy (no hash): N
  TAMPERED:         N
  Invalid JSON:     N
  Signature warnings: N

Status: CLEAN or FAILED

If any tampered records: list each with timestamp, event, and both the stored and expected hash (first 16 chars each). Tampering can indicate log corruption, manual edits, or a bug — not necessarily malicious.

If only legacy records (no tampered): note "Legacy records were written before telemetry integrity hashing was added. New telemetry and artifact records are hashed automatically."

/telemetry --config: Show current settings with the node -e "..." command to change each — don't auto-apply.

Step 4: ACCURACY BADGES

Always mark data source clearly:

  • [real] — data from Claude Code's native session JSONL (exact)
  • (est) — estimated from the fallback model ($1 base + $0.50/agent + $0.10/min)
  • (override) — manually entered by the user

Never blend real and estimated in the same total without flagging it.

What Telemetry Covers

Covered: session cost (real token data), duration/burn rate/message count, agent spawn count, hook timing and outcomes, campaign cost attribution, trust level.

Not covered (by design): per-tool-call cost, per-subagent cost isolation, real-time streaming token count.

Safety hooks always on (cannot be disabled): protect-files, external-action-gate, circuit-breaker, quality-gate.

OTLP Export

The JSONL files under .planning/telemetry/ stay canonical. For standard observability stacks, scripts/telemetry-otlp-export.js translates new records into OTLP/HTTP JSON metrics and POSTs them to a collector. Byte offsets per source file live in .planning/telemetry/otlp-export-state.json, so repeat runs export only new records.

# Preview the OTLP payload without sending or advancing state
node scripts/telemetry-otlp-export.js --dry-run

# Export new records to a local collector (/v1/metrics appended when the url has no path)
node scripts/telemetry-otlp-export.js --endpoint http://localhost:4318
Metric Type Source file
citadel.session.cost.usd sum (delta), session.id / cost.source attributes session-costs.jsonl
citadel.session.tokens sum (delta), token.type attribute session-costs.jsonl
citadel.hook.duration.ms gauge, hook.name attribute hook-timing.jsonl
citadel.agent.runs sum (delta), run.status / run.event attributes agent-runs.jsonl

--reset clears the offsets for a full re-export. On a non-2xx response or network error the exporter exits 1 without advancing state, so the next run retries the same records. Data point timestamps come from the JSONL records, never the current clock. Test with node scripts/test-telemetry-otlp.js.

Local collector demo: examples/otel-collector/ contains a ready-made collector config (OTLP HTTP receiver on 4318, debug exporter to stdout) and a README with the two-command flow: docker run with the config mounted, then node scripts/telemetry-otlp-export.js --endpoint http://localhost:4318. Without Docker, --dry-run prints the exact OTLP payload instead.

Quality Gates

  • Never show raw JSONL to the user — always parse and format
  • Cost totals must be labeled with their source (real / est / mixed)
  • /telemetry off must NOT disable safety hooks — make this explicit in output
  • Relative timestamps required — no raw ISO strings in output
  • If all data sources are missing, show the empty-state version with setup hint

Fringe Cases

  • .planning/telemetry/ missing: Show empty state with "Run /do setup to initialize telemetry."
  • session-tokens.js unavailable: Fall back to session-costs.jsonl; mark (est).
  • harness.json missing: Show "(harness.json not found — defaults active)" and "→ Run /do setup to unlock cost tracking."
  • telemetry.enabled: false: Show banner "Telemetry is disabled. Run /telemetry on to re-enable."
  • --verify with missing files: Report "No telemetry or artifact JSONL files found." Not an error.
  • --verify when scripts/verify-telemetry-integrity.js is unavailable: Report that the verifier is missing and show the raw file paths to inspect; do not claim hash verification ran.

Contextual Gates

Disclosure: Read-only by default. --threshold, off, on, --config write harness.json. Reversibility: amber — harness.json writes; undo with git checkout .claude/harness.json. Trust gates: Any — no restrictions.

Exit Protocol

/telemetry does not produce a HANDOFF block. It is a read-only observability tool (except for --threshold, off, on, --config which write harness.json). After displaying output, wait for the next user command.

Install via CLI
npx skills add https://github.com/SethGammon/Citadel --skill telemetry
Repository Details
star Stars 612
call_split Forks 55
navigation Branch main
article Path SKILL.md
More from Creator