M2.5.2: Cost ledger #25

Closed
opened 2026-04-08 21:43:38 +00:00 by claude-code · 0 comments
Collaborator

Phase 2.5 — Logging & Cost Visibility, milestone 2.

Goal

A persistent JSONL ledger of every research() call, suitable for cost tracking and operator queries. Supplements (does not replace) the per-call cost_metadata field returned to callers.

Scope

  • Ledger file: ~/.marchwarden/costs.jsonl (configurable via MARCHWARDEN_COST_LEDGER)
  • One JSON line per completed research call, appended at the same point we currently emit the complete trace step
  • Fields:
    • timestamp (ISO-8601 UTC)
    • trace_id
    • question (truncated to ~200 chars)
    • model_id
    • tokens_used (total)
    • tokens_input / tokens_output (split if available from anthropic usage object)
    • iterations_run
    • wall_time_sec
    • tavily_searches (count of tavily_search tool invocations during the loop)
    • estimated_cost_usd (computed from price table)
    • budget_exhausted (bool)
    • confidence (final overall confidence)
  • Also emit a structured log line via M2.5.1's logger at INFO: cost_recorded event with the same fields, so cost data ships to OpenSearch alongside the ledger file

Price table

  • Read from ~/.marchwarden/prices.toml (created on first run if missing, seeded with current Anthropic + Tavily rates)
  • Schema:
    [models."claude-sonnet-4-6"]
    input_per_mtok_usd = 3.00
    output_per_mtok_usd = 15.00
    
    [models."claude-opus-4-6"]
    input_per_mtok_usd = 15.00
    output_per_mtok_usd = 75.00
    
    [tavily]
    per_search_usd = 0.005   # post-free-tier estimate
    
  • Unknown models log a WARN and record estimated_cost_usd: null rather than crashing
  • Document that operators are expected to update prices.toml when Anthropic changes rates (no automatic fetching)

Tests

  • Round-trip: write a fake research call, read the ledger, verify all fields present and types correct
  • Unknown model warns and stores null cost
  • Missing prices.toml is auto-created with seed values
  • Existing prices.toml is not overwritten

Depends on

M2.5.1 (uses the structured logger for the cost_recorded event)

Branch

feat/cost-ledger

Phase 2.5 — Logging & Cost Visibility, milestone 2. ## Goal A persistent JSONL ledger of every `research()` call, suitable for cost tracking and operator queries. **Supplements** (does not replace) the per-call `cost_metadata` field returned to callers. ## Scope - Ledger file: `~/.marchwarden/costs.jsonl` (configurable via `MARCHWARDEN_COST_LEDGER`) - One JSON line per completed research call, appended at the same point we currently emit the `complete` trace step - Fields: - `timestamp` (ISO-8601 UTC) - `trace_id` - `question` (truncated to ~200 chars) - `model_id` - `tokens_used` (total) - `tokens_input` / `tokens_output` (split if available from anthropic usage object) - `iterations_run` - `wall_time_sec` - `tavily_searches` (count of tavily_search tool invocations during the loop) - `estimated_cost_usd` (computed from price table) - `budget_exhausted` (bool) - `confidence` (final overall confidence) - Also emit a structured log line via M2.5.1's logger at INFO: `cost_recorded` event with the same fields, so cost data ships to OpenSearch alongside the ledger file ## Price table - Read from `~/.marchwarden/prices.toml` (created on first run if missing, seeded with current Anthropic + Tavily rates) - Schema: ```toml [models."claude-sonnet-4-6"] input_per_mtok_usd = 3.00 output_per_mtok_usd = 15.00 [models."claude-opus-4-6"] input_per_mtok_usd = 15.00 output_per_mtok_usd = 75.00 [tavily] per_search_usd = 0.005 # post-free-tier estimate ``` - Unknown models log a WARN and record `estimated_cost_usd: null` rather than crashing - Document that operators are expected to update `prices.toml` when Anthropic changes rates (no automatic fetching) ## Tests - Round-trip: write a fake research call, read the ledger, verify all fields present and types correct - Unknown model warns and stores null cost - Missing `prices.toml` is auto-created with seed values - Existing `prices.toml` is not overwritten ## Depends on M2.5.1 (uses the structured logger for the `cost_recorded` event) ## Branch `feat/cost-ledger`
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: archeious/marchwarden#25
No description provided.