You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(copilot): preserve copilot-home, usage, and permission evidence
Applies the four review findings on PR #22.
The agent-customize CLI parsed --copilot-home but never forwarded it to
the collector, so every CLI run inventoried the real ~/.copilot instead
of the requested path. That broke the CLI half of CHS-AC-6 while the
collector API stayed correct. scripts/agent-customize/cli.mjs now passes
copilotHome through, and a CLI regression test asserts the inventory
resolves under the fixture home and that no evidence path points at the
real user home.
The Copilot platform module dropped the outputTokens that assistant
messages do record. isModelRequestEvent excludes assistant-typed events,
so usage cannot ride the message itself: each assistant message that
reports usage now also emits a companion model.response.completed
carrying outputTokens, messageId as responseId, and requestId. Input and
cache tokens stay absent rather than zero. 10,462 of 11,313 assistant
messages across 491 local sessions carry a non-zero outputTokens, so the
coverage is genuinely partial and the warning is renamed
copilot-per-response-usage-partial.
permission.requested and permission.completed now normalize into the
shared control.permission lifecycle, retaining only requestId, the
request kind, and the result decision; intents, paths, and commands are
never retained. The decision rides the result event alone, because
permissionObservation counts any event carrying a decision and Copilot
emits a request even when policy auto-approves, so decorating both would
double-count and label all 1,177 requests as prompted friction.
toolInvocationId is deliberately left unset: dedupeEvents keys on it,
and 32 toolCallIds repeat across separate permission requests, which
would have silently dropped legitimate events.
Source coverage now emits the canonical session-core-facts fields that
safeSourceCoverage whitelists, keeping the Copilot transcript counters
beside them so analysisWarnings keeps working. Two latent bugs surfaced
here: coverage read probe fields off session descriptors that never
carried them, so withRequest was always zero, and the relevant-set
ladder narrowed even without a requested window, hiding transcript-less
sessions instead of reporting them as unreadable.
CHS-AC-5 and CHS-AC-6 in docs/specs/2026-07-29-copilot-host-support.md
now describe partial per-response usage and the payload-free permission
lifecycle, and Session Diagnostics documents the two added boundaries.
Validated with npm test (874/874), npm run pack:verify (PASS, npm 314 /
runtime zip 338), and node --test test/doc-link-graph.test.mjs (6/6, no
mermaid drift).
Co-authored-by: Copilot App (Claude Opus 5) <223556219+Copilot@users.noreply.github.com>
@@ -519,8 +633,8 @@ export class CopilotSessionAnalyzer extends SessionAnalyzer {
519
633
asyncanalysisWarnings(scope,_roots,_sessions){
520
634
constcoverage=scope._copilotSourceCoverage;
521
635
constwarnings=[{
522
-
code: "copilot-per-response-usage-unobserved",
523
-
message: "Copilot transcripts do not record per-response model token usage; usage evidence requires the opt-in OpenTelemetry export.",
636
+
code: "copilot-per-response-usage-partial",
637
+
message: "Copilot transcripts record output tokens per assistant response but no input tokens, cache tokens, or cost; complete usage evidence requires the opt-in OpenTelemetry export.",
0 commit comments