Quota Tracker, Pure Phoenix Phase 4.2 + 4.7¶
Doctrine: FORGE-DOCTRINE.md Section 7.
What it tracks¶
Every script that calls claude -p records one row per invocation. Plus the daily aggregator merges with ~/.claude/stats-cache.json so Justin's interactive Claude Code sessions show up alongside automation.
Layout¶
| Path | Role |
|---|---|
forge/scripts/forge_quota_tracker.py |
Module: record(...), aggregate(month), merge_with_stats_cache(summary). CLI: --month YYYY-MM, --write-summary, --no-stats-cache. |
forge/data/claude-quota/<YYYY-MM>.jsonl |
Append-only per-month log of every recorded call. |
forge/data/claude-quota/summary.json |
Nightly aggregator output (per-invoker daily + monthly totals). |
forge/logs/quota-tracker.log |
Module's own error log (record/aggregate failures). |
JSONL row shape¶
{
"ts": "2026-04-28T23:25:33",
"invoker": "forge_telegram_brain[capture]",
"model": "claude-sonnet-4-6",
"prompt_chars": 5400,
"response_chars": 286,
"prompt_tokens_est": 1350,
"response_tokens_est": 71,
"latency_ms": 4690,
"success": true,
"pid": 1390068,
"persona": "capture"
}
Token estimates are conservative chars / 4. When/if Justin moves any brain to API key billing, swap in exact token counts via the SDK and the rest of the pipeline keeps working.
Instrumented invokers (after Phase 4.7)¶
| Invoker | Where | Frequency |
|---|---|---|
forge_telegram_brain[capture] |
forge_telegram_brain.py (capture persona) |
per Telegram message to @forge_inbox_capture_bot |
forge_telegram_brain[coordinator] |
same module, coordinator persona | per Telegram message to @forge_lifeos_coordinator_bot |
heartbeat |
heartbeat.py call_sonnet() |
midday + evening + night-cap (3x/day) |
morning_brief |
morning-brief.py call_sonnet() |
daily 07:00 CT |
wellness_daily_summary |
forge_wellness_daily_summary.py call_sonnet() |
daily 03:00 |
memory_auto_capture |
forge_memory_auto_capture.py call_sonnet() |
per Stop hook (session end) |
memory_auto_dream |
forge_memory_auto_dream.py call_sonnet() |
nightly 04:00 |
dispatcher_worker |
forge_dispatcher.sh (launch + complete events) |
per pipe-mode worker task |
claude_code_interactive |
~/.claude/stats-cache.json (merged in by aggregator) |
every Claude Code session Justin runs |
Aggregator¶
forge_quota_tracker.py # print this month's summary
forge_quota_tracker.py --month 2026-03 # historical month
forge_quota_tracker.py --write-summary # write summary.json
forge_quota_tracker.py --no-stats-cache # skip interactive merge
Cron: 30 4 * * * forge_quota_tracker.py --write-summary (after auto-dream at 04:00).
How to call from a new script¶
Python:
import sys, time
sys.path.insert(0, "/home/justinwieb/forge/scripts")
import forge_quota_tracker as quota
t0 = time.monotonic()
result = subprocess.run([CLAUDE_BIN, "-p", "--model", "claude-sonnet-4-6", prompt], ...)
quota.record(invoker="my_script", model="claude-sonnet-4-6",
prompt_chars=len(prompt), response_chars=len(result.stdout),
latency_ms=int((time.monotonic() - t0) * 1000),
success=result.returncode == 0)
Shell:
python3 -c "
import sys; sys.path.insert(0,'/home/justinwieb/forge/scripts')
import forge_quota_tracker as q
q.record(invoker='my_script', model='${MODEL}', prompt_chars=${#PROMPT},
response_chars=${RESP_CHARS}, latency_ms=${LATENCY_MS}, success=True)
" 2>/dev/null || true
Reading the data¶
# all today's calls by invoker
jq -s 'group_by(.invoker) | map({invoker: .[0].invoker, calls: length, prompt_tokens: ([.[].prompt_tokens_est]|add)})' \
/home/justinwieb/forge/data/claude-quota/2026-04.jsonl
# slowest calls
jq -s 'sort_by(-.latency_ms)|.[:10]' /home/justinwieb/forge/data/claude-quota/2026-04.jsonl
# cat the unified summary
cat /home/justinwieb/forge/data/claude-quota/summary.json
What it does NOT track¶
- API-billed calls (no API key in use; everything goes through Claude Code subscription)
- Tool calls within a session (Claude Code tracks toolCallCount in stats-cache.json; quota_tracker doesn't double-count)
- Subagent calls launched by other Sonnet sessions (those show up under
claude_code_interactivefrom stats-cache)
Future (not shipped)¶
- Auto-back-off when call rate spikes above threshold (deferred)
- Real-time dashboard or weekly digest push to
@forge_notify_outbound_bot(deferred) - Anthropic SDK swap for exact token counts (deferred until real API billing matters)
[Claude Code, Pure Phoenix Phase 4.2 + 4.7]