Skip to content

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_interactive from 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]