fix(trace): separate Pi cache token accounting

WA
3h ago
+162-16

Summary

  • emit Pi schema_version: v2 evidence with native input, output, cache-read, and cache-write counters kept separate
  • recompute total_tokens from base input plus output instead of trusting Pi's cache-inclusive totalTokens
  • compare stored evidence independently with raw Pi records in the compatibility suite
  • record the cache-active Pi 1.3.0 result as supported

This implements the Pi-only #3720, a slice of the broader cross-provider #3706. The focused tracker was created after this PR opened to keep subsequent work issue-first. This PR does not close the broader all-provider tracker.

Trace provider checklist

  • Evidence keeps input, output, total, cache read, and cache write semantics explicit.
  • Provider-reported cost remains authoritative.
  • Invalid counters and overflow paths produce deterministic warnings.
  • Parsing reads the copied selected-branch session and preserves resumed history.
  • Unit tests cover real test data, malformed totals, overflow, resumed usage, and source comparison.
  • The live Pi compatibility check ran with the pinned version and model.
  • The compatibility matrix and token-accounting documentation are updated from the live result.
  • No new dependency, generated artifact, hook, or CLI wiring change is required.
  • Changed source files retain the current license header.

Validation

  • go test -race -shuffle=on -count=1 ./internal/trace/pi ./internal/trace/e2e
  • go build ./...
  • go vet ./...
  • golangci-lint run --new-from-rev upstream/main
  • CHAINLOOP_E2E_HARNESS=Pi CHAINLOOP_E2E_MODEL=openrouter/anthropic/claude-haiku-5.5 CHAINLOOP_E2E_FEATURE='Cache token accounting' make -C app/cli test-trace-e2e

The live run had nonzero cache reads and writes and passed with the matrix expecting Yes.

make -C app/cli test still hits two existing local-environment failures that reproduce unchanged on upstream/main: cmd/TestLoadAuthToken when CHAINLOOP_TOKEN is inherited, and Codex TestCopySessionData* on the macOS storage-root path. The changed Pi and E2E packages pass under the race detector.

AI assistance

Vibhav's Pi assisted with implementation, testing, and review. The commit is signed, DCO-compliant, and carries Assisted-by: Vibhav's Pi.

The skip-ai-session label is required because the available Chainloop login cannot access the chainloop project to upload the session. This matches the fallback used on merged Pi PR #3704; it does not bypass code, test, DCO, or signature checks.