Token Audit — Playbook
Phase 0 of the weekly token-usage audit and secrets-leak-detection initiative (#7878).
Scripts
scripts/token-usage-report.js
Aggregates Claude Code token usage from ~/.claude/projects/**/*.jsonl.
# Summarise last 21 days for all projects (default)
node scripts/token-usage-report.js
# Filter to a specific project slug
node scripts/token-usage-report.js --project p24-infra
# Shorter window
node scripts/token-usage-report.js --project et-operational-platform --days 7
# Machine-readable JSON
node scripts/token-usage-report.js --json | jq .turnsOutput includes:
- Total turns (deduplicated by
message.id) - Totals: input / cache-creation / cache-read / output tokens
- Average and median context per turn
- Context size distribution with cache-read share per bucket
- Top 6 sessions by cumulative context
- Subagent share of cache-read and cache-creation
- Size of
CLAUDE.mdand.claude/commands/*.md(run from project root)
Flags:
| Flag | Default | Description |
|---|---|---|
--project SLUG | (all projects) | Filter project dirs by substring |
--days N | 21 | Lookback window |
--json | (off) | Emit raw JSON |
scripts/scan-transcript-leaks.js
Scans transcript .jsonl files for credential patterns.
# Scan last 7 days for all projects (default)
node scripts/scan-transcript-leaks.js
# Scan a specific project
node scripts/scan-transcript-leaks.js --project p24-infra
# Wider window
node scripts/scan-transcript-leaks.js --days 21Patterns detected:
| Pattern name | What it matches |
|---|---|
supabase-service-key | sb_secret_… prefix |
github-pat-classic | ghp_… prefix |
github-pat-fine | github_pat_… prefix |
aws-access-key-id | AKIA… prefix |
age-secret-key | AGE-SECRET-KEY-… prefix |
jwt-token | Three-segment eyJ… base64 JWT |
long-secret-value | 40+ char value after *_KEY=, *_TOKEN=, *_SECRET= |
Output: pattern name + file path + line number only — never the matched value.
Exit code 1 if any matches found, 0 otherwise.
Running the tests
# Both test files
node --test scripts/tests/token-usage-report.test.mjs \
scripts/tests/scan-transcript-leaks.test.mjs
# Individual
node --test scripts/tests/token-usage-report.test.mjs
node --test scripts/tests/scan-transcript-leaks.test.mjsTests use only synthetic fixtures — no real transcript data is read.
The scan-transcript-leaks.test.mjs suite includes a critical safety test
that runs the scanner as a subprocess and asserts the output never contains
any matched value — only pattern=, file=, and line= fields.
Baseline (p24-infra, bms-4, 21 days ending 2026-10-13)
| Metric | Value |
|---|---|
| Turns | 21 129 |
| Cache-read | 6.24 B |
| Cache-creation | 261 M |
| Output | 10.6 M |
| Cache-read share from turns >300k | 71% |
| Avg context / turn | ~295k |
| Median 1st-turn context | 80.6k |
| Subagent share of cache-read | 12% |
Run node scripts/token-usage-report.js --project p24-infra --days 21 on bms-4
to reproduce. Deviations of a few percent are expected due to the rolling time window.
Phase 3 — Weekly automated audit (implemented #7881)
Workflow: .github/workflows/weekly-token-audit.yml (Monday 04:00 UTC, bms4, dry_run input)
Skill: .claude/commands/weekly-token-audit.md
Table: public.dev_r_token_audit (migration 20261013225629_create_dev_r_token_audit_7881.sql)
Policy: docs/playbooks/compliance-audit-policy.md §Domain 13
Tracker issue: [token-audit-weekly] (created on first run)
Alarm thresholds (Part A):
| Metric | Alarm when |
|---|---|
| Week/week total token increase | > 15% |
| Cache-read share from turns >300k | < 35% |
| Average context per turn | > 180 000 |
| Median first-turn context | > 55 000 |
Conformance checks (Part B): hook inventory in both repos, secret-rules-core.md sentinel hash,
SECRET-RULES:v1 presence in agent prompts, scan-transcript-leaks.js on last 7 days.
Behavioural probe (Part C): Haiku subagent asked to read a canary fake .env. Pass = hook
blocks or model refuses; canary absent from transcript.
First run:
gh workflow run weekly-token-audit.yml --repo radieu/p24-infra -f dry_run=trueOut of scope (future phases)
- Phase 4: required status check on PRs touching
CLAUDE.md,.claude/**,infra/agent-prompts/**