Problem to Fix
Code Cannon says nothing about agent usage visibility — token spend, session cost, rate-limit headroom, or which part of the workflow is expensive. Research into whether Code Cannon should ship a usage-visibility feature concluded it should not (see "Considered and discarded" below). What remains unresolved is the much smaller question this ticket holds:
Should Code Cannon ship a docs/observability.md at all, or is even that out of scope?
The case against a docs page: how you watch usage is an operator decision driven by your own environment — your plan's token limits, what you actually pay, whether you want a passive statusline or a Grafana board, whether you run one backend or four. Code Cannon shipping a recommended wiring reads as a blessed path where there shouldn't be one. That material may belong in a blog post — where it can be opinionated, dated, and clearly not part of the tool's contract — with the tool itself staying silent and leaving the choice to the developer.
Decide the framing first. Do not start writing until it is decided.
Why it Matters
Code Cannon is a skill distribution system with no runtime. Every line of documentation it ships is a claim about how you should work. A wiring guide for a third-party observability stack is close to the edge of that remit, and getting it wrong costs more than it gives: it dates fast (four vendors, all moving), it implies support Code Cannon can't offer, and it substitutes the author's cost posture for the operator's.
The counter-argument, and the reason this isn't just closed: there is one narrow slice that is Code Cannon-specific rather than generic advice — Claude Code's OTEL emits skill.name and query_source per request, so Code Cannon's own commands (/start, /submit-for-review, /review, /deploy) and its review subagent show up as native cost dimensions with zero configuration. Nobody else can point that out, because nobody else knows those skill names exist. If anything is in scope, it is that paragraph — not a general OTEL tutorial.
General Approach
Resolve the framing question, then take exactly one of these paths:
Path A — blog post, nothing in the repo. Full wiring walkthrough lives outside the tool. Repo stays silent. Chosen if the conclusion is that usage posture is purely an operator concern.
Path B — minimal repo note. A short section (not a full page) covering only the Code Cannon-specific slice: which of its skills and subagents appear as OTEL dimensions, and a pointer out to Claude Code's own monitoring docs plus the existing third-party tools. Explicitly no recommended stack, no thresholds, no "you should track this." Chosen if the skill-attribution fact is judged too useful to leave undiscoverable.
Path B is the smaller claim and the likelier answer; Path A is acceptable and cheap. Do not do both in the repo.
Whichever path: no code, no sync.py change, no new config keys.
Hard Constraints
- No change to
sync.py. In particular, it must not learn to write env or statusLine into .claude/settings.json — its claim on that file stays narrow and additive (permissions.allow only).
- No skill prose instructing an agent to report its own cost. Agent-estimated usage is silently wrong data, which fails the AGENTS.md test (keep where model variance produces a wrong result).
- No content that normalizes or compares usage across backends. Only Claude Code and Gemini CLI have native OTEL; Cursor and Codex do not.
- Nothing that reads as a recommended spend threshold, budget, or "correct" cost posture.
Considered and discarded
Four shapes were weighed during research. All were rejected, with reasons that should stop them being re-proposed:
1. A Code Cannon statusline. Rejected — pure duplication. ccstatusline and Claude Code's native statusLine hook already receive live JSON with context-window %, 5hr/7day rate-limit % and reset times, and running session cost. There is nothing to add.
2. A cross-backend usage aggregator. Rejected on two counts. Structurally, Code Cannon is a build-time markdown generator — sync.py substitutes placeholders, writes files, and exits. It never runs during an agent session and so cannot observe one; building this means growing a collector or daemon, a category change rather than a feature. Competitively, it already exists: o11y-dev/opentelemetry-hooks normalizes eight agents (Claude, Cursor, Gemini, Codex, Copilot, Windsurf, OpenCode, Antigravity) to GenAI semantic conventions via hooks, and Token Telemetry does the same by parsing local logs. Matching them means maintaining parsers for four vendors' undocumented formats to reach parity with free tools.
3. Per-subagent cost attribution as the differentiating feature. Rejected — the premise was false. This looked like the one gap a generic statusline could never fill, but Claude Code's OTEL already carries query_source (main / subagent / auxiliary), agent.name, skill.name, model, effort, and speed as per-request attributes on claude_code.cost.usage and claude_code.token.usage. Per-subagent and per-skill breakdowns are queryable today with no Code Cannon code at all.
4. OTEL export tagged with ticket/task ID. Deferred, not dead — this is the only genuinely novel capability, since it depends on the ticket↔branch invariant /start enforces, which no generic tool knows about. It is not the one-liner it appears to be: OTEL_RESOURCE_ATTRIBUTES is read at process start and cannot change mid-session, so it breaks on /story, which walks several sub-issues inside one session. A working version means after-the-fact correlation — branch-create to PR-merge time window, joined against the OTLP backend or ~/.claude/projects/*.jsonl, posted to the issue via the existing post-issue-comment.py. Roughly 150 lines. Trigger to revisit: the model-tiering work has landed and there is a concrete decision the per-ticket number feeds (e.g. routing ticket classes to a cheaper tier). Cost data with no decision attached is a dashboard nobody opens. Filing this as its own ticket before that trigger fires would be premature.
Complexity
Verification / QA effort: minimal
Documentation or nothing. No code paths, no tests, no sync behaviour to verify. The real work is the scope judgment, not the writing.
Acceptance Criteria
- The framing question is decided in a comment on this issue, with the reasoning recorded — including the case for Path A (silence) if Path B is chosen.
- Exactly one of: a blog post exists outside the repo (Path A), or a short section lands in
docs/ covering only the Code Cannon-specific attribution slice (Path B).
sync.py is unchanged. No new config keys. No skill file mentions cost reporting.
- If Path B: the text names no recommended observability stack and prescribes no spend threshold, and links out for anything generic rather than restating it.
- Closing this issue as
wontfix after recording the decision is an acceptable outcome.
Problem to Fix
Code Cannon says nothing about agent usage visibility — token spend, session cost, rate-limit headroom, or which part of the workflow is expensive. Research into whether Code Cannon should ship a usage-visibility feature concluded it should not (see "Considered and discarded" below). What remains unresolved is the much smaller question this ticket holds:
Should Code Cannon ship a
docs/observability.mdat all, or is even that out of scope?The case against a docs page: how you watch usage is an operator decision driven by your own environment — your plan's token limits, what you actually pay, whether you want a passive statusline or a Grafana board, whether you run one backend or four. Code Cannon shipping a recommended wiring reads as a blessed path where there shouldn't be one. That material may belong in a blog post — where it can be opinionated, dated, and clearly not part of the tool's contract — with the tool itself staying silent and leaving the choice to the developer.
Decide the framing first. Do not start writing until it is decided.
Why it Matters
Code Cannon is a skill distribution system with no runtime. Every line of documentation it ships is a claim about how you should work. A wiring guide for a third-party observability stack is close to the edge of that remit, and getting it wrong costs more than it gives: it dates fast (four vendors, all moving), it implies support Code Cannon can't offer, and it substitutes the author's cost posture for the operator's.
The counter-argument, and the reason this isn't just closed: there is one narrow slice that is Code Cannon-specific rather than generic advice — Claude Code's OTEL emits
skill.nameandquery_sourceper request, so Code Cannon's own commands (/start,/submit-for-review,/review,/deploy) and its review subagent show up as native cost dimensions with zero configuration. Nobody else can point that out, because nobody else knows those skill names exist. If anything is in scope, it is that paragraph — not a general OTEL tutorial.General Approach
Resolve the framing question, then take exactly one of these paths:
Path A — blog post, nothing in the repo. Full wiring walkthrough lives outside the tool. Repo stays silent. Chosen if the conclusion is that usage posture is purely an operator concern.
Path B — minimal repo note. A short section (not a full page) covering only the Code Cannon-specific slice: which of its skills and subagents appear as OTEL dimensions, and a pointer out to Claude Code's own monitoring docs plus the existing third-party tools. Explicitly no recommended stack, no thresholds, no "you should track this." Chosen if the skill-attribution fact is judged too useful to leave undiscoverable.
Path B is the smaller claim and the likelier answer; Path A is acceptable and cheap. Do not do both in the repo.
Whichever path: no code, no
sync.pychange, no new config keys.Hard Constraints
sync.py. In particular, it must not learn to writeenvorstatusLineinto.claude/settings.json— its claim on that file stays narrow and additive (permissions.allowonly).Considered and discarded
Four shapes were weighed during research. All were rejected, with reasons that should stop them being re-proposed:
1. A Code Cannon statusline. Rejected — pure duplication.
ccstatuslineand Claude Code's native statusLine hook already receive live JSON with context-window %, 5hr/7day rate-limit % and reset times, and running session cost. There is nothing to add.2. A cross-backend usage aggregator. Rejected on two counts. Structurally, Code Cannon is a build-time markdown generator —
sync.pysubstitutes placeholders, writes files, and exits. It never runs during an agent session and so cannot observe one; building this means growing a collector or daemon, a category change rather than a feature. Competitively, it already exists:o11y-dev/opentelemetry-hooksnormalizes eight agents (Claude, Cursor, Gemini, Codex, Copilot, Windsurf, OpenCode, Antigravity) to GenAI semantic conventions via hooks, and Token Telemetry does the same by parsing local logs. Matching them means maintaining parsers for four vendors' undocumented formats to reach parity with free tools.3. Per-subagent cost attribution as the differentiating feature. Rejected — the premise was false. This looked like the one gap a generic statusline could never fill, but Claude Code's OTEL already carries
query_source(main/subagent/auxiliary),agent.name,skill.name,model,effort, andspeedas per-request attributes onclaude_code.cost.usageandclaude_code.token.usage. Per-subagent and per-skill breakdowns are queryable today with no Code Cannon code at all.4. OTEL export tagged with ticket/task ID. Deferred, not dead — this is the only genuinely novel capability, since it depends on the ticket↔branch invariant
/startenforces, which no generic tool knows about. It is not the one-liner it appears to be:OTEL_RESOURCE_ATTRIBUTESis read at process start and cannot change mid-session, so it breaks on/story, which walks several sub-issues inside one session. A working version means after-the-fact correlation — branch-create to PR-merge time window, joined against the OTLP backend or~/.claude/projects/*.jsonl, posted to the issue via the existingpost-issue-comment.py. Roughly 150 lines. Trigger to revisit: the model-tiering work has landed and there is a concrete decision the per-ticket number feeds (e.g. routing ticket classes to a cheaper tier). Cost data with no decision attached is a dashboard nobody opens. Filing this as its own ticket before that trigger fires would be premature.Complexity
Verification / QA effort: minimal
Documentation or nothing. No code paths, no tests, no sync behaviour to verify. The real work is the scope judgment, not the writing.
Acceptance Criteria
docs/covering only the Code Cannon-specific attribution slice (Path B).sync.pyis unchanged. No new config keys. No skill file mentions cost reporting.wontfixafter recording the decision is an acceptable outcome.