Created
Jul 08, 04:46
Started
Jul 08, 04:48
Completed
Jul 08, 07:12
DevOps handoff
Type
Feature
Shape
backend
Worktree Slug
unified-usage-pricing-module
Repositories
mcritchie-studio
Release Slug
—
Branch
feat/unified-usage-pricing-module
Local URL
—
QA URL
—
Production URL
—
Acceptance Criteria
Expected Test Plan
Checks Run
Agent Context
Phase 1 of a 3-phase epic to make agent activity/action logging cost+token accurate (operator observed board logging ~2.3x the real bill). Establish ONE list-price pricing source of truth and retire the two-divergent-tables defect. Today there are TWO pricing paths that disagree: (a) AgentAction::MODEL_RATES + AgentAction.cost_for (app/models/agent_action.rb ~73-81,250,258-271) — cache-read at 0.10x but cache-CREATION folded into tokens_in at 1x (under-prices writes ~20%); (b) AgentSessionUsage::PRICING + .price (lib/agent_session_usage.rb ~22-32,173-188) — cache-write 1.25x, cache-read 0.10x, different model roster. Create a single module (e.g. lib/usage_pricing.rb or app/models/concerns) that prices a usage tuple {model, input, output, cache_creation, cache_read} at Anthropic LIST price: opus-4-8 = $5 in / $25 out per MTok, cache-read = 0.10x input, cache-write tier from the usage cache_creation breakdown (5m=1.25x, 1h=2.0x; Claude Code writes 1h — the /usage $13.53 reconciled with cache-write at 2x). Handle the [1m] long-context premium instead of silently stripping it (both tables strip it today → under-count long turns). Point BOTH AgentAction.cost_for and AgentSessionUsage.price at the module so they agree. Do NOT yet change token attribution/dedup or server-vs-client trust — those are Phase 2/3. Keep model roster in one place.
How long this task spent in each testing phase — Build → Local Certification → CI → Review → Operator Acceptance.
Build
about 1 hour
Completed
Local Certification
—
Missing
CI
—
Missing
Review
22 minutes
Completed
Operator Acceptance
—
Missing
Stage Timeline
Who handled each stage, the time it took (measured), and the model / tokens / cost reported (best-effort) — plus who's on it right now. — means the agent didn't report that metric.
Conversation
QA review feedback, agent handoffs, and follow-up notes for this task.
Scout report: merge-ready - Light docs-lens review: one UsagePricing SoT, both callers delegate, rates verified against claude-api reference (opus-4-8 5/25, cache read 0.10x, 1h write 2.0x), fixture math checks out, no stale MODEL_RATES/PRICING refs on branch, no doc drift Reporter: alex Outcome: merge-ready Findings: - Rates + multipliers match authoritative Anthropic pricing reference exactly - Old constants fully removed; only historical comment + kept ATOMIC_ACTION_MODEL_RATES env name remain (intentional) - Docs carry no pricing constants; atomic-capture-hook.md cache-read-tier claim still accurate Questions: - none Checks: - gh pr view 455: OPEN, not draft, base release, CI 4/4 SUCCESS, MERGEABLE - git grep on FETCH_HEAD: no stale pricing constant references
Scout report: merge-ready - Deep backend review: single UsagePricing SoT verified against authoritative Anthropic pricing reference (all model rates + 0.10x read / 2.0x 1h-write tiers correct); both delegations preserve contracts; nil/unknown model prices to nil never $0; BigDecimal 4dp matches decimal(10,4) cost columns; dor-check PASSES on PR tree (primary-checkout STALE was the known tree-fingerprint false positive - cert ad5a8571 == PR head tree); CI green; no orphaned refs to removed constants; no cross-PR file overlap. Reporter: carl Outcome: merge-ready Findings: - Non-blocker: per-action path still folds cache writes into tokens_in at 1x (cost_for hardcodes cache_creation:0), so per-action rows under-price writes vs per-activity/task rows; documented as Phase 2 and the parity test scopes itself to cache_creation=0. - Nit: gpt-5.5 entry lacks cache_creation override - a nonzero cache_creation bucket would price at 2.0x input though OpenAI does not charge for cache writes; dormant since Codex capture sets cache_creation=0. - Nit: UsagePricing.rates re-parses ATOMIC_ACTION_MODEL_RATES JSON on every price call when env set (deliberate un-memoization for test freshness; trivial cost). Questions: - none Checks: - gh pr view 455: OPEN, not draft, base release, MERGEABLE/CLEAN, CI 4/4 green - cert tree ad5a8571e907... == git rev-parse origin/feat/unified-usage-pricing-module^{tree} (exact match) - bin/dor-check from PR-head worktree: DoR-to-Merge met (unit+integration tiers, cert, CI) - git grep: zero remaining references to MODEL_RATES/PRICING/rate_for/multiplier constants outside module+test - rate table + cache multipliers verified against claude-api skill pricing reference (2026-06-24 cache)
Avi review approved; ready for Steffon's qa-release sweep. Rates verified against authoritative pricing reference by both reviewers; dor-check STALE was the known tree-fingerprint false positive (recorded cert tree equals origin branch tree ad5a8571). Phase-2 note: per-action path hardcodes cache_creation=0 (documented), parity holds at that scope.
Scout report: merge-ready - Light read (docs/coherence lens): acceptance 5/5 met; UsagePricing is genuinely single-source (repo grep finds no other rate table); PR body matches diff; cert tree fresh; CI green Reporter: alex Outcome: merge-ready Findings: - Non-blocker: bin/atomic-capture-hook turn_usage comment (~line 513) still says cache-write 'true rate is 1.25x' — new SoT establishes 2.0x (1h TTL); stale comment in untouched file, fix on next touch - Question: briefing said board costs shift ~down, but fixtures shift slightly UP (0.1928->0.1936, 0.1038->0.1040) from the 1.25x->2.0x write correction; PR makes no direction claim, module documents /usage-meter reconciliation rationale Questions: - none Checks: - diff-vs-acceptance: all 5 criteria verified in lib/usage_pricing.rb, app/models/agent_action.rb, lib/agent_session_usage.rb, test/lib/usage_pricing_test.rb - single-source grep: no MODEL_RATES/PRICING/multiplier constants outside module; no token-to-dollar math in views/JS/helpers; live docs name no removed constant - cert fingerprint = PR head tree ad5a8571 (tree equality verified); CI 4/4 SUCCESS; PR open non-draft base release
Scout report: merge-ready - Deep review PASS: one pricing SoT (lib/usage_pricing.rb), both callers delegate, rates verified against the claude-api reference, gates green Reporter: carl Outcome: merge-ready Findings: - Pricing math exact: opus-4-8 5/25 per MTok, cache-read 0.10x, cache-write 2.0x (1h list tier); [1m] strip correct — no long-context premium on this roster - Cache-write 1.25x->2.0x is the deliberate correction; downstream test expectations updated with math comments (task_cli, atomic_event_cli, agent_session_usage) - Non-blocker: flat 2.0x write multiplier (no per-TTL split) — capture stores one flattened cache_creation bucket; per-TTL named as later phase in module comment - Non-blocker: dor-check from primary checkout false-flags cert STALE (fingerprints wrong tree); PASSES from worktree; tree equality verified (ad5a8571 == PR head tree) Questions: - none Checks: - dor-check PASS (worktree): full-suite + rubocop certified at ad5a8571e907, CI green 4 checks - standalone unit run: ruby -Itest test/lib/usage_pricing_test.rb — 12 runs 0 failures (plain-Ruby claim holds) - no same-file overlap with open PRs 452/453/454; base=release, ready (not draft), mergeable
Avi review approved; ready for Steffon's qa-release sweep.
Sealed-bid sizing
Edit →Alex (PM)
—
Avi (PO)
SMALL
Dev
SMALL
Actual
LARGE
We emailed a one-tap sign-in link to . It expires shortly and can only be used once.
No email? Check spam, or close this and try again.