Skip to content

Capability architecture

Spendguard governs and records model use across metered APIs and subscription CLI lanes, routes work, measures quality and economics, and reconciles captured activity against available provider evidence. Read this map before designing a feature. Each entry below is source-read and built-and-verified unless marked PARTIAL, STUB, or VISION; verification here means implementation inspection, not a live-provider integration test. PARTIAL names a missing guarantee or wiring limit, not an absent module. Paths are relative to this repository; entry-point citations are navigable source locations. Billed API dollars, flat subscription fees, and remote compute are real costs; subscription usage's estimated value is a separate axis and must never be added to them.

Routing and contracts

Provider registration contract

adapters.register_provider(name, base_url, key_env, prefixes, kind="openai") adds an endpoint/key/prefix specification; kind selects the OpenAI-compatible or Anthropic SDK path. For example, an application can call adapters.register_provider(provider_name, base_url=endpoint, key_env=credential_env, prefixes=model_prefixes) using its configuration. provider_for accepts explicit provider:model IDs; otherwise the longest matching registered prefix wins, and unknown providers raise (src/spendguard/generate/execution/providers.py:32, src/spendguard/generate/execution/providers.py:32). Registration supplies routing metadata, not a new enforcement implementation: the selected SDK surface still needs the installed gate described below.

Module Status and capability Primary entry points
adapters BUILT — Common API/lane routing, pins, best-value selection, schema capability, generation controls, input fitting, retry provenance and governed recovery. Images force API execution; eligible labelled metered text calls enter storm routing. Published output ceilings generally replace caller token caps; a soft deadline records telemetry rather than cancelling work. call (src/spendguard/generate/execution/adapters.py:353); json_schema_request (src/spendguard/generate/execution/schema.py:65); schema_capability (src/spendguard/generate/execution/schema.py:135); structured_reply (src/spendguard/generate/execution/schema.py:232)
vendor_call PARTIAL — Typed facade, contracts, deadlines, transient retries, fan-out and model-serving discovery. A timed-out worker can finish and bill later; fan cost checks do not reserve all in-flight cost. consensus counts successful replies, not semantic agreement. call (src/spendguard/generate/execution/vendor_call.py:220); fan_out (src/spendguard/generate/execution/vendor_call.py:1145); first_ok (src/spendguard/generate/execution/vendor_call.py:1187); consensus (src/spendguard/generate/execution/vendor_call.py:1250); JobLock (src/spendguard/generate/execution/vendor_call.py:513)
output_contract BUILT — Contract hashing, JSON parsing, supported schema-subset validation, item IDs and complete envelope/arity checks. This is not a full JSON Schema implementation; callable hashes exclude closure contents. describe (src/spendguard/generate/work_integrity/output_contract.py:71); check_item (src/spendguard/generate/work_integrity/output_contract.py:346); check_envelope (src/spendguard/generate/work_integrity/output_contract.py:392)
best_value BUILT — Pin-aware model/effort selection from fingerprinted measured quality frontiers, with an explicitly distinguished cold prior. select_model_effort (src/spendguard/manage/routing/best_value.py:147)
intent_model_prior BUILT — Cached agentic ranking of the whole priced catalog for an intent; supplies cold-start priors, not measured quality evidence. rank_models_for_intent (src/spendguard/analyze/learning/intent_model_prior.py:142)
requirement_judge BUILT — Whole prompt/output requirement judging, cheap judge followed by stronger adjudication on uncertainty; both failures remain unknown. requirements_for (src/spendguard/analyze/measurement/requirement_judge.py:86); judge_requirements (src/spendguard/analyze/measurement/requirement_judge.py:121)
llm_files BUILT — Whole decoded-text attachments with hashes, line counts and reconstruction checks; invalid UTF-8 is replacement-decoded rather than byte-preserved. attach_whole (src/spendguard/generate/work_integrity/llm_files.py:43); attach_many (src/spendguard/generate/work_integrity/llm_files.py:81)
source_compact BUILT — AST/token-aware removal of source prose with preservation checks and original-source fallback. compact (src/spendguard/analyze/assurance/source_compact.py:92)

Prospective coalescing, durable queues and admission

Adapter queue registration also tracks foreground calls; it does not mean every adapter call executes through the queue drainer.

These are different existing mechanisms, not names for one queue. storm_coalescer is the prospective accumulation queue: it waits for arrivals before choosing realtime versus batch. lane_queue persists work and leases ownership across attempts and processes. dispatch and xp_rate_window admit calls against concurrency and RPM/TPM capacity. whole_job plans an already-known set of jobs across a horizon. queue_planner forecasts an existing backlog; it does not collect future arrivals.

Module Status and capability Primary entry points
storm_coalescer PARTIAL — In-memory Future-based prospective queue. Cohorts flush at realtime budget, maximum wait, or idle gap; rolling reservations and pacing determine realtime versus Batch execution. Failed/missing keyed items alone retry; a batch submission failure is not bisected into repeated purchases. Bounded close warns about abandoned work. Coalescing is deterministic and has no per-call deadline/SLA flush. StormCoalescer (src/spendguard/manage/token_operations/storm_coalescer.py:76)
storm_route BUILT — Default-on registry connecting eligible adapter calls to shared coalescers. Registry keys include vendor/model/intent/reasoning/system hash, not horizon; unknown rates decline coalescing. Pre-enqueue failure can fall through; post-enqueue ownership is authoritative to avoid rebuying. Busy registry capacity is soft and Future waiting has no separate timeout. coalescing_enabled (src/spendguard/manage/token_operations/storm_route.py:40); get_coalescer (src/spendguard/manage/token_operations/storm_route.py:128); route (src/spendguard/manage/token_operations/storm_route.py:160)
storm_submit BUILT — Explicit storm submission plus default governed realtime and OpenAI/Anthropic batch executors, keyed collection and bounded polling. Optional durable batch executor adopts handles through the tracker; it is not the default and does not carry system/reasoning parameters. submit_storm (src/spendguard/manage/token_operations/storm_submit.py:206); governed_realtime_executor (src/spendguard/manage/token_operations/storm_submit.py:47); default_batch_executor (src/spendguard/manage/token_operations/storm_submit.py:79); durable_batch_executor (src/spendguard/manage/token_operations/storm_submit.py:155)
whole_job PARTIAL — Shared-horizon, urgency-aware whole-job planning and execution, priced budget checks, checkpointed realtime bulk delegation and persisted batch handles. Batch leg is OpenAI only; submission failure/unsupported vendors fall back to realtime with reporting. Per-intent grouping takes the first nonempty system/schema rather than partitioning heterogeneous contracts. plan_jobs (src/spendguard/manage/routing/whole_job.py:218); run_jobs (src/spendguard/manage/routing/whole_job.py:258); load_pending (src/spendguard/manage/routing/whole_job.py:376); collect_jobs (src/spendguard/manage/routing/whole_job.py:441)
route_horizon BUILT — Common urgency and horizon allocation, urgent-first realtime capacity, batch recommendation and batch chunk sizing. Plans known work rather than predicting future arrivals. plan_horizon (src/spendguard/manage/routing/route_horizon.py:69); should_batch_fan (src/spendguard/manage/routing/route_horizon.py:180); chunk_for_batch (src/spendguard/manage/routing/route_horizon.py:204)
queue_planner BUILT — Read-only backlog/rate forecasting, offload plans and batch chunk calculation; used by drainer and MCP planning. Unknown throughput remains a risk rather than invented capacity. forecast (src/spendguard/manage/token_operations/queue_planner.py:35); offload_plan (src/spendguard/manage/token_operations/queue_planner.py:169); plan_loop (src/spendguard/manage/token_operations/queue_planner.py:270)
dispatch BUILT — Global/provider/lane concurrency, cross-process slots, RPM/TPM admission, learned limits, Retry-After and connection-window AIMD. Metered admission precedes slot acquisition; oversized token requests can incur debt instead of deadlocking. Infrastructure failure can visibly run ungoverned. Adapter management defaults on; vendor facade does not enable shedding. Governor (src/spendguard/manage/token_operations/dispatch.py:738); admit (src/spendguard/manage/token_operations/dispatch.py:1038); holding (src/spendguard/manage/token_operations/dispatch.py:1003); try_admit (src/spendguard/manage/token_operations/dispatch.py:1262); shrink_connection_window (src/spendguard/manage/token_operations/dispatch.py:296); grow_connection_window (src/spendguard/manage/token_operations/dispatch.py:336)
xp_rate_window PARTIAL — SQLite cross-process second/minute request/token reservations and deadlines; oversized requests run alone. Some SQLite infrastructure errors fail open. This is admission accounting, not durable job ownership. reserve (src/spendguard/manage/token_operations/xp_rate_window.py:110); limits_for (src/spendguard/manage/token_operations/xp_rate_window.py:46); RateDeadline (src/spendguard/manage/token_operations/xp_rate_window.py:29)
lane_queue PARTIAL — Separate SQLite durable lease queue: fingerprint deduplication, completed-result reuse, priority/deadline/retry/lease expiry, batch ownership and adoption, pause/recovery, archival purge and migration. Saturation parks without burning attempts. Predictive batch offload defaults off. Stored result JSON is capped at 4,000 bytes and can become unparsable, yielding an empty result. enqueue (src/spendguard/manage/token_operations/lane_queue.py:379); lease (src/spendguard/manage/token_operations/lane_queue.py:541); settle (src/spendguard/manage/token_operations/lane_queue.py:616); submit (src/spendguard/manage/token_operations/lane_queue.py:1021); drain (src/spendguard/manage/token_operations/lane_queue.py:1603); mark_batched (src/spendguard/manage/token_operations/lane_queue.py:757); collect_batched (src/spendguard/manage/token_operations/lane_queue.py:795)
work_integrity BUILT — Exact multiset partition proof: expected work appears once, without missing, duplicate or unexpected IDs. Not a scheduler. WorkIntegrityProof (src/spendguard/generate/work_integrity/work_integrity.py:17)
item_ledger BUILT — Caller-owned JSONL item settlement, attempts, reopening and completeness assertions. Flushes without fsync; malformed records are ignored. ItemLedger (src/spendguard/generate/work_integrity/item_ledger.py:79)
job_fingerprint PARTIAL — Persisted plan/prompt/model fingerprints and resume drift refusal; agentic method-change decisions choose reuse/revalidate/rebuy. A revalidate decision stamps state but does not execute a validation sample itself. compute_job_fingerprint (src/spendguard/generate/work_integrity/job_fingerprint.py:76); guard_resume (src/spendguard/generate/work_integrity/job_fingerprint.py:141)

Lane identity, readiness and recovery

Module Status and capability Primary entry points
lane_registry BUILT — Canonical lane specs and provider mapping for Claude Code, Codex, Gemini, Z.ai coding and Kimi coding. Adding a lane requires a registry specification and an executor, not just config. all_lanes (src/spendguard/store/reference_data/lane_registry.py:81); lane_spec (src/spendguard/store/reference_data/lane_registry.py:86); provider_lane_map (src/spendguard/store/reference_data/lane_registry.py:91)
lane_catalog BUILT — Tier aliases, lane catalog and candidate arms, plus fallback auditing. Candidate-arm construction alone does not enforce pricing. catalog (src/spendguard/store/reference_data/lane_catalog.py:121); arms (src/spendguard/store/reference_data/lane_catalog.py:135); audit_lane_fallback (src/spendguard/store/reference_data/lane_catalog.py:149)
lanes BUILT — Own-CLI auth status, probe persistence, cached headroom, lane status and configuration commands. Installed binary is not proof of authentication; unknown is not READY. lane_auth_status (src/spendguard/platform/lanes.py:103); lanes_status (src/spendguard/platform/lanes.py:139); probe (src/spendguard/platform/lanes.py:180); lane_headroom (src/spendguard/platform/lanes.py:248)
lane_quota BUILT — TTL/reset-aware cached usage and bucket headroom. cached_usage (src/spendguard/analyze/treasury/lane_quota.py:24); bucket_headroom (src/spendguard/analyze/treasury/lane_quota.py:47)
lane_quota_cost PARTIAL — Measured per-call quota cost, overage avoidance and plan-fraction preflight. Unknown quota can skip checks, so this is not universal fail-closed quota enforcement. estimate_lane_quota (src/spendguard/analyze/treasury/lane_quota_cost.py:173); quota_preflight (src/spendguard/analyze/treasury/lane_quota_cost.py:205); enforce_single_call_plan_fraction (src/spendguard/analyze/treasury/lane_quota_cost.py:250)
lane_servability BUILT — Measured lane/model readiness, served-model shifts, refresh on rejection and compatible substitutions; protects caller pins. Distinguishes declared models from observed service. lane_readiness (src/spendguard/analyze/measurement/lane_servability.py:60); detect_served_shift (src/spendguard/analyze/measurement/lane_servability.py:164); lane_served_substitute (src/spendguard/analyze/measurement/lane_servability.py:217); refresh_lane_servability (src/spendguard/analyze/measurement/lane_servability.py:347)
lane_eligibility BUILT — Cached agentic intent eligibility classification; estimate/read-only operation leaves unjudged intents explicit. classify_intent (src/spendguard/analyze/measurement/lane_eligibility.py:54); lane_eligible_report (src/spendguard/analyze/measurement/lane_eligibility.py:75)
lane_recovery BUILT — Typed recovery proof, bounded free retry and authorization before paid fallback. Existing failure-shape interpretation uses error-text rules. LaneRecoveryProof (src/spendguard/manage/token_operations/lane_recovery.py:49); LaneRecoveryProof.authorize_metered_recovery (src/spendguard/manage/token_operations/lane_recovery.py:69); retry_free_lane (src/spendguard/manage/token_operations/lane_recovery.py:88)
plan_admission PARTIAL — Cached quota/overage risk, health/auth/cooldown-aware alternatives and confirmed substitutes. Actual cap refusal does not invent an alternate; unknown auth is not always rejected, and an auth-over-quota setting is unused. lane_risk (src/spendguard/manage/admission/plan_admission.py:46); decide (src/spendguard/manage/admission/plan_admission.py:140); ready_meta_model (src/spendguard/manage/admission/plan_admission.py:198)
overage BUILT — Cached observed invoice/window overage status and CLI display; not a fresh provider oracle. current_overage_status (src/spendguard/analyze/treasury/overage.py:99); overage_cli (src/spendguard/analyze/treasury/overage.py:154)
resource_state BUILT — Persisted reasoned cooldowns and expiring prompt-character ceilings, retaining proven-good watermarks with distinct lane/model keys. Header-mentioned output-ceiling axis is not implemented. set_cooldown (src/spendguard/manage/token_operations/resource_state.py:94); set_size_ceiling (src/spendguard/manage/token_operations/resource_state.py:149); note_proven_good (src/spendguard/manage/token_operations/resource_state.py:172)

Lane balancing, bandits and economics

Module Status and capability Primary entry points
lane_balance PARTIAL — Confirmed substitutes, load balancing, prompt adaptations, optional bandit routing and checkpointed bulk delegation. Bulk supports keyed results, schemas, governor capacity, pins, vision API calls, free-lane hedging and batch-on-miss. Caps are checked between chunks; in-flight chunks can overshoot. Empty confined arms widen defaults; estimate deduplicates identical inputs while fresh bulk execution does not. Checkpoint keys omit schema/reasoning/images. delegate (src/spendguard/manage/routing/lane_balance.py:218); bulk_delegate (src/spendguard/manage/routing/lane_balance.py:474); estimate_fan (src/spendguard/manage/routing/lane_balance.py:1359); route_decision (src/spendguard/manage/routing/lane_balance.py:1572); confirm_substitute (src/spendguard/manage/routing/lane_balance.py:207); adapt_system (src/spendguard/manage/routing/lane_balance.py:1756)
lane_bandit BUILT — Decayed trial/win learning, exploration and idle/headroom-aware arm selection; whole-output bakeoff judges preserve unknown failures rather than false ties. Its judge-cost estimate is not an upper bound for arbitrary whole evidence. choose_arm (src/spendguard/analyze/learning/lane_bandit.py:173); run_bakeoff (src/spendguard/analyze/learning/lane_bandit.py:315); bandit_call (src/spendguard/analyze/learning/lane_bandit.py:387)
lane_economics BUILT — Observed quota/token deltas, measured capacity, pacing, plan economics and prompt-budget reservations; unknown capacity remains unknown. record_samples (src/spendguard/analyze/treasury/lane_economics.py:66); measured_lane_caps (src/spendguard/analyze/treasury/lane_economics.py:141); economics (src/spendguard/analyze/treasury/lane_economics.py:180); prompt_economics (src/spendguard/analyze/treasury/lane_economics.py:416)
lane_value BUILT — Priced ledger-derived subscription-value stamps and daily sync, excluding transcript-mined duplicate sources. Unknowns and private ownership remain explicit; read failure is not proof of zero activity. stamp_from_ledger (src/spendguard/analyze/treasury/lane_value.py:65); day_totals (src/spendguard/analyze/treasury/lane_value.py:150); sync (src/spendguard/analyze/treasury/lane_value.py:190)
route_utility BUILT — Lane and metered rankings using headroom/reset/urgency/pacing/quota efficiency, prepaid balance and prices; default breach policy refuses silent downgrades. rank_lanes (src/spendguard/manage/routing/route_utility.py:107); rank_metered (src/spendguard/manage/routing/route_utility.py:236); breach_decision (src/spendguard/manage/routing/route_utility.py:299); rank_for_tier (src/spendguard/manage/routing/route_utility.py:348)
tier_config BUILT — Tier configuration/pricing validation and optional pinned reachability probes without fallback. tier_config_report (src/spendguard/manage/routing/tier_config.py:56); reachability_probe (src/spendguard/manage/routing/tier_config.py:96)
route_economics BUILT — Route cost, lane marginal economics, reservation/amortization and batch overflow reporting, with unknown costs explicit. route_cost (src/spendguard/manage/routing/route_economics.py:94); route_report (src/spendguard/manage/routing/route_economics.py:211)
route_realized BUILT — Read-only realized routing history and served-model drift summaries. route_realized_report (src/spendguard/analyze/measurement/route_realized.py:17); routing_summary (src/spendguard/analyze/measurement/route_realized.py:33)

CLI executors and warm brokers

Codex Phase-1 admission hardening is implemented: bounded max_waiters, checkout-inclusive timeout, recycle_on_timeout, and retirement that retains/quarantines slots until safe. Cold fallbacks honor capacity refusal. The broker's socket-failure fallback to a local pool means host-wide coordination is not an unconditional guarantee.

Module Status and capability Primary entry points
warm_stdio_daemon BUILT — Shared serialized startup/handshake, request waiters, reader lifecycle, idle cleanup, terminate/wait/kill/reap and retired-instance protection. Admission policy belongs to specialized daemons. _WarmStdioJsonRpcDaemon (src/spendguard/manage/token_operations/warm_stdio_daemon.py:195)
codex_daemon BUILT — Persistent Codex app-server stdio workers, per-prompt thread isolation, optional worker homes, exclusive pool checkout and bounded admission/recycling. _CodexDaemon (src/spendguard/manage/token_operations/codex_daemon.py:150); _CodexDaemonPool (src/spendguard/manage/token_operations/codex_daemon.py:434)
codex_daemon_broker PARTIAL — Unix-socket broker shares the pool across local clients; connection failure can use a local pool rather than preserving a single host-wide cap. _CodexDaemonBroker (src/spendguard/manage/token_operations/codex_daemon_broker.py:139)
codex_exec BUILT — Auth/usage and warm or cold Codex execution, credential scrubbing, safety modes and shell-snapshot GC. CLI has no forwarded max-token flag; warm usage may use character estimates. auth_status (src/spendguard/generate/execution/codex_exec.py:319); usage (src/spendguard/generate/execution/codex_exec.py:660); run_prompt (src/spendguard/generate/execution/codex_exec.py:693)
subscription_exec PARTIAL — Claude CLI execution with neutral cwd, sanitized environment and usage accounting. Accepted reasoning/max-token arguments are not forwarded. auth_status (src/spendguard/generate/execution/subscription_exec.py:68); run_prompt (src/spendguard/generate/execution/subscription_exec.py:188)
antigravity_exec PARTIAL — Gemini agy JSON execution and cached quota/reset handling. Binary availability does not establish auth; reasoning/max-token controls are not enforced. usage (src/spendguard/generate/execution/antigravity_exec.py:228); run_prompt (src/spendguard/generate/execution/antigravity_exec.py:276)
kimi_exec PARTIAL — Default warm ACP execution with cold CLI handling for known pinned aliases. Reasoning/max-token arguments are ignored; usage can be estimated or unknown. usage (src/spendguard/generate/execution/kimi_exec.py:43); run_prompt (src/spendguard/generate/execution/kimi_exec.py:220)
kimi_daemon BUILT — Warm multiplexed ACP with an isolated session per prompt, declined authentication requests, explicit tool failures and transient cold fallback. _KimiAcpDaemon (src/spendguard/manage/token_operations/kimi_daemon.py:37)
zai_exec BUILT — Coding-plan HTTP executor with owned accounting, thinking-aware unsupported-option recovery and bounded rate-limit retries; quota can remain unknown. usage (src/spendguard/generate/execution/zai_exec.py:47); run_prompt (src/spendguard/generate/execution/zai_exec.py:101)
delegate_router BUILT — Whole-task/file classification into one-shot, agentic or needs-Codex work; selects ready/authenticated external CLI lanes, supports estimate/execute and does not fail open into unavailable paid work. delegation_lanes_ready (src/spendguard/manage/token_operations/delegate_router.py:202); classify_task (src/spendguard/manage/token_operations/delegate_router.py:271); delegate_task (src/spendguard/manage/token_operations/delegate_router.py:696); delegate_cli (src/spendguard/manage/token_operations/delegate_router.py:754)

Batch submission, collection and bulk safety

submit and callio are provider Batch API legs, not prospective queues. They are called by storm executors, OpenAI whole-job execution, the durable tracker/offload path, bulk delegation's batch-on-miss path, and experiment/history workflows. Anthropic support exists in submit/collect but is not wired uniformly into every higher-level caller.

Explicit submission contract

guarded_submit estimates first, refuses a count above request_cap (default 25,000), enforces cap_dollars, and refuses a projection above expected_cost * overrun_tolerance; the default tolerance is 1.2 (20% over expected; src/spendguard/generate/execution/submit.py:112). Its estimate-only path (submit=False) checks and writes an audit without submitting; normal submission also applies resilience checks and a live first-request preflight, which can itself bill. Accepted-batch booking is deferred until provider acceptance (src/spendguard/generate/execution/submit.py:355). Use separate estimate and approval stages before execution.

Pass a measured per-request avg_out_tokens to override output projection; a ceiling is a worst-case send limit, not evidence of typical output. The estimate reports both output and token-count bases, so inspect them before approving. Without tiktoken, the local counter warns about its len(text)/4 approximation and recommends installing tiktoken in the gated venv before trusting a batch estimate (src/spendguard/generate/execution/submit.py:79). Provider-aware counting also exposes proxy/normalization bases: calibrate provider factors where appropriate rather than treating a character estimate as exact (src/spendguard/generate/execution/submit.py:95, src/spendguard/analyze/cost_estimation/provider_tokens.py:183, src/spendguard/analyze/cost_estimation/content_tokens.py:317). This does not imply that every estimator uses max_tokens or that every estimate is conservative.

Module Status and capability Primary entry points
submit BUILT — OpenAI JSONL and Anthropic message batch construction, estimates, unique IDs, schema/sharding checks, guarded submission and accepted-batch booking. Submission normally includes a small live preflight; adapter ceilings can replace caller max-token values. guarded_submit (src/spendguard/generate/execution/submit.py:355); submit_chat_tasks (src/spendguard/generate/execution/submit.py:522); submit_message_batch (src/spendguard/generate/execution/submit.py:655)
callio PARTIAL — Captured prompt/output samples, provider-history recovery, batch status and keyed OpenAI/Anthropic collection. Live oversized prompts are explicitly skipped; historical snippets may lack replayable system/schema evidence. batch_status is OpenAI-only. record_io_sample (src/spendguard/store/call_corpus/callio.py:150); capture_live (src/spendguard/store/call_corpus/callio.py:222); batch_status (src/spendguard/store/call_corpus/callio.py:538); collect_chat_tasks (src/spendguard/store/call_corpus/callio.py:673); collect_message_batch (src/spendguard/store/call_corpus/callio.py:745)
batch_tracker PARTIAL — Durable pre-submit manifests, lease IDs, orphan adoption and terminal completeness proofs, preventing accepted batch rebuy. Provider acceptance and local persistence are not atomic. Polling calls the OpenAI-only status helper even for Anthropic, leaving that path erroneous until expiry. register_batch (src/spendguard/generate/execution/batch_tracker.py:82); submit_offload (src/spendguard/generate/execution/batch_tracker.py:358); poll (src/spendguard/generate/execution/batch_tracker.py:544); assert_batch_terminal_manifest (src/spendguard/generate/execution/batch_tracker.py:610)
openai_batch_cli BUILT — Guarded JSONL submission with estimate/cap/dry-run and output download with overwrite protection. Failed terminal batches return before downloading error files. submit_batch_jsonl (src/spendguard/generate/execution/openai_batch_cli.py:28); fetch_batch_output (src/spendguard/generate/execution/openai_batch_cli.py:93)
bulkgate PARTIAL — Fresh estimate/test/eval evidence tied to contract and data signatures, realtime checks, latency/output learning and runaway checks. Default mode warns rather than blocks. Evaluation clips evidence to its first 12,000 characters with notice, so is not whole-evidence judging. check_bulk (src/spendguard/manage/admission/bulkgate.py:349); estimate_job (src/spendguard/manage/admission/bulkgate.py:986); test_job (src/spendguard/manage/admission/bulkgate.py:992); eval_job (src/spendguard/manage/admission/bulkgate.py:1063); gated_batch (src/spendguard/manage/admission/bulkgate.py:1143)
bulk_resilience BUILT — Structural gate requires large lane/provider submissions to be chunked and checkpointed; unknown shape refuses unless explicitly forced. Provider requests, rather than packed logical units, determine the door count. require_resilient (src/spendguard/generate/work_integrity/bulk_resilience.py:26)
comprehend BUILT — Corpus resolution, whole contiguous chunks, separate estimates and checkpointed bulk comprehension; unread inputs are named rather than silently cut. estimate_corpus (src/spendguard/manage/token_operations/comprehend.py:112); comprehend_corpus (src/spendguard/manage/token_operations/comprehend.py:229)

Config, installation and gate

config.py is the runtime resolver; config_schema.py describes settings for surfaces/onboarding. _cfg_get reads literal section/key pairs. Environment override support is individually implemented, not a universal dotted-key convention. In particular advisor numeric accessors are config-only and preserve zero; schema metadata alone does not prove an environment override is wired. Pool settings and selected other controls have explicit environment handling.

Enforcement order and cap scopes

For a batch estimate, _decide_and_account first routes a spendguard:* intent to the meta cage and returns. Ordinary work then passes batch-1 discipline and bulk-evidence checks, cross-process daily/monthly checks, the per-batch cap on the realistic projection, and a separate worst-case ceiling check, before recording. Submitters can defer recording until provider acceptance; otherwise the final step books a provisional estimate and an optional call-corpus row (src/spendguard/manage/admission/gate.py:787, src/spendguard/manage/admission/gate.py:787). Estimation is not a guarantee of known final batch cost.

Control Default and scope Configuration / backend
Per-batch $75 per submission GATE_CAP → caps.per_batch; config.cap (src/spendguard/store/configuration/config_store.py:517)
Realtime cumulative $50 per process GATE_RT_BUDGET → caps.realtime; in-memory running total (src/spendguard/store/configuration/config_store.py:525)
Daily/monthly class caps Off unless configured; llm, compute, total GATE_LLM_DAILY, GATE_LLM_MONTHLY, GATE_COMPUTE_DAILY, GATE_COMPUTE_MONTHLY, GATE_TOTAL_DAILY, GATE_TOTAL_MONTHLY; class_cap also reads flat/nested config and server policy (src/spendguard/store/configuration/config_store.py:550)
Meta $2/day for the governor's own model use GATE_META_BUDGET → caps.meta; persisted meta ledger accounting (src/spendguard/store/configuration/config_store.py:582)

The gate's daily/monthly check and workload ledger recording require budget.backend=sqlite (src/spendguard/manage/admission/gate.py:612, src/spendguard/manage/admission/gate.py:651). budget.exceeded checks the resource class's daily then monthly sub-caps before total daily then monthly caps. Its local total currently sees the LLM ledger; combined LLM/compute reporting is composed elsewhere, so this is not a transactional combined-resource hard ceiling (src/spendguard/manage/admission/budget.py:848). Compute controls are alert/soft checks and never kill running jobs (src/spendguard/manage/admission/budget.py:848).

Over-cap per-batch and daily/monthly work can prompt on a TTY; affirmative approval proceeds, while noninteractive work refuses unless deliberately authorized with GATE_ALLOW=1 or appropriately raised caps. That override does not establish that every other independent bulk/intent control is waived (src/spendguard/manage/admission/gate.py:512, src/spendguard/manage/admission/gate.py:612). Realtime prechecks test estimated spend before execution, then account actual returned usage; their one-time _rt_bypass permits the rest of the process's realtime budget only, without skipping daily/monthly checks (src/spendguard/manage/admission/gate.py:1091, src/spendguard/manage/admission/gate.py:1477). Anthropic cache reads are added back into input before pricing, with cache-creation tokens passed separately (src/spendguard/manage/admission/gate.py:1369).

Kill switch and recovery

GATE_DISABLE=1 or the persistent $SPENDGUARD_HOME/disabled flag disables enforcement; the default flag location is ~/.spendguard/disabled (src/spendguard/store/configuration/config_store.py:26, src/spendguard/store/configuration/config_store.py:897). spendguard off writes the flag; spendguard on removes it. Clear the environment override too when recovering (src/spendguard/manage/admission/gate.py:2580). The generated startup hook checks both switches before importing spendguard, providing an escape hatch even if package import is broken; both the site/user hook and .pth bootstrap contain that check (src/spendguard/platform/setup.py:217, src/spendguard/platform/setup.py:234). Re-enabling the switches still requires installation in the interpreter actually used; the inventory's require() and SDK-coverage caveats apply.

Registering an SDK gate

spendguard.register(module_path, class_name, method, gate_fn, is_async=False) appends a surface; the next spendguard.install() patches it alongside built-ins. For example, spendguard.register(sdk_module, sdk_class, sdk_method, check_request) followed by spendguard.install() uses application-supplied configuration and a callback. gate_fn(kw, args) returns to allow or raises SpendGateRefused (including its subclasses) to stop; an estimator can explicitly reuse _decide_and_account with the pipeline's estimate shape (provider, model, requests, in_tok, out_tok, cost, and any additional estimate basis fields). Registration itself does not invent estimation or post-call actual-usage accounting (src/spendguard/interface/crossllm.py:242, src/spendguard/interface/crossllm.py:242).

_guard propagates deliberate refusal but warns and permits on other callback errors. install is idempotent at patched methods and contains per-surface installation failures; its optional cap argument sets GATE_CAP for this process (src/spendguard/manage/admission/gate.py:2312, src/spendguard/manage/admission/gate.py:2342). Extension authors inherit this fail-open boundary and must not mistake successful registration for comprehensive fail-closed SDK coverage.

Module Status and capability Primary entry points
config BUILT — Key provenance/shadowing, CLI resolution, mtime-cached config, atomic state updates, policy/local/org cap resolution, scoped intent authorizations, queue paths, lane environment scrubbing and worker settings. Owns counted/memory-budgeted thread-local ledger connections, fresh transaction handling, rollback/reset and separate maintenance connections. load_key_files (src/spendguard/store/configuration/provider_keys.py:48); resolve_cli (src/spendguard/store/configuration/cli_resolution.py:12); advisor_num (src/spendguard/store/configuration/config_store.py:445); codex_daemon_pool_settings (src/spendguard/store/configuration/config_store.py:366); open_ledger_connection (src/spendguard/store/configuration/ledger_connection.py:462); pooled_ledger_conn (src/spendguard/store/configuration/ledger_connection.py:688); ledger_op (src/spendguard/store/configuration/ledger_connection.py:798)
config_schema BUILT — Declarative settings catalog and sections used by configuration surfaces. Not all declared override metadata is implemented by runtime accessors. sections (src/spendguard/store/configuration/config_schema.py:890)
keys_audit BUILT — Key-source and shadowing audit with masked suffixes and optional strict duplicate reporting. cmd (src/spendguard/analyze/assurance/keys_audit.py:42)
gate PARTIAL — SDK interception for OpenAI/Anthropic realtime, Responses, embeddings, batches and streaming, plus budgets, explicit refusals, external-cost gate and accepted-batch booking. Incidental errors can fail open. require() proves at least one patch when SDKs are present, not every surface; no installed SDK passes vacuously. Unknown prices are loudly recorded as unpriced zero, not invented. Abandoned streams and fine-tuning training cost are not fully captured. install (src/spendguard/manage/admission/gate.py:2342); require (src/spendguard/manage/admission/gate.py:2485); SpendGateRefused (src/spendguard/manage/admission/spend_refusal_error.py:15); MeteredCallRefused (src/spendguard/manage/admission/spend_refusal_error.py:27); record_accepted_batch_estimate (src/spendguard/manage/admission/gate.py:800); gate_external (src/spendguard/manage/admission/gate.py:684)
setup BUILT — Managed repo rules, venv/user startup hooks, interpreter coverage, skill installation and schema-driven setup. Startup bootstrap catches installation failure, making explicit require() important. Skill installation copies instructions rather than all supporting assets. install_rule (src/spendguard/platform/setup.py:363); install_hook (src/spendguard/platform/setup.py:742); install_skills (src/spendguard/platform/setup.py:866); cmd_init (src/spendguard/platform/setup.py:1379)
runner PARTIAL — Scoped bootstrap directory and child environment for executing commands with startup injection. Bootstrap catches errors; explicit require remains necessary for fail-closed callers. child_env (src/spendguard/platform/runner.py:69); main (src/spendguard/platform/runner.py:92)
coverage BUILT — Startup-hook coverage audit across configured interpreters; structural coverage is not runtime enforcement proof. audit_gating_coverage (src/spendguard/analyze/assurance/coverage.py:117); gaps (src/spendguard/analyze/assurance/coverage.py:136)
weekly_cap_guard PARTIAL — PreToolUse protection for recognized raw Codex shell execution and Agent/Task invocations, using cached weekly headroom. Unknown cap blocks absent override; internal errors fail open. weekly_cap_guard_pretooluse (src/spendguard/manage/admission/weekly_cap_guard.py:120); install_weekly_cap_guard (src/spendguard/manage/admission/weekly_cap_guard.py:195)
agent_spawn_gate PARTIAL — Whole-task cached agentic near-cap spawn judgment, denial and delegation guidance; visible fail-open on internal failure. evaluate_pretooluse (src/spendguard/manage/admission/agent_spawn_gate.py:77); install_agent_gate (src/spendguard/manage/admission/agent_spawn_gate.py:159)

Canonical money ledger and capture

Storage, identity and isolation

SPENDGUARD_HOME selects state storage, defaulting to ~/.spendguard; operational config.json and credential keys.env are separate files (src/spendguard/store/configuration/provider_keys.py:-18, src/spendguard/store/configuration/provider_keys.py:-7). Email/server credentials use dedicated email.json/saas.json, gitignored configuration files or environment variables rather than tracked project config (src/spendguard/store/configuration/ledger_connection.py:821, src/spendguard/store/configuration/ledger_connection.py:865). The canonical money ledger coexists with call, I/O and learning tables; the queue has its own database, as described below. This is not a claim that every subsystem shares one database.

Charge project resolution is SPENDGUARD_PROJECT → repository .spendguard.json SaaS project → git-root basename → cwd basename. Conversation identity checks SPENDGUARD_CONV → SPENDGUARD_CHAT → CLAUDE_SESSION_ID → process fallback (src/spendguard/manage/admission/budget.py:74, src/spendguard/manage/admission/budget.py:106). Contributor resolution uses explicit configuration, then git email, then a persisted anonymous machine identity (usr_<hex>); anonymous identity is attribution fallback, not proof of a resolved human/org owner (src/spendguard/egress/saas.py:201, src/spendguard/store/configuration/ledger_connection.py:892).

Ledger connections use WAL and thread-local pooling. Cross-connection work must commit in phases to avoid holding one writer while another connection attempts to write the same file; history reconstruction documents this ordering explicitly (src/spendguard/store/configuration/ledger_connection.py:642, src/spendguard/store/configuration/ledger_connection.py:694, src/spendguard/analyze/learning/history.py:149). These phases are not an atomic multi-module transaction. Daily/monthly caps remain check-then-record: concurrent processes can each pass before another records, allowing overshoot. High-volume realtime usage also incurs per-call ledger writes and shared SQLite writer contention; pooling reduces connection overhead but does not remove these limits (src/spendguard/manage/admission/gate.py:612, src/spendguard/manage/admission/gate.py:787, src/spendguard/manage/admission/gate.py:1477).

Module Status and capability Primary entry points
ledger BUILT — Canonical v6 event ledger, decimal-text money, separate cost axes, UTC event timestamps and configured reporting timezone, repaired indexes, deduplication, adjustments/reversals, period locks and hash-chained audit. Compatibility totals can include multiple axes; bulk retag uses summary audit rather than per-row lock checks. SpendLedger (src/spendguard/store/money_ledger/ledger.py:519); live_dedup_key (src/spendguard/store/money_ledger/ledger.py:492)
budget BUILT — Charge recording into canonical events, snapshots, reconciliation corrections, intent/job/provider/day dimensions, unpriced records/repricing and separate meta/external spend. Write failures produce loud dead letters. Batch-estimate reconciliation matches provider/model/intent, not a unique batch ID. record_charge (src/spendguard/manage/admission/budget.py:153); snapshot (src/spendguard/manage/admission/budget.py:215); spent_since (src/spendguard/manage/admission/budget.py:498); record_unpriced (src/spendguard/manage/admission/budget_unpriced.py:9); record_external_cost (src/spendguard/manage/admission/budget.py:651)
ledger_read BUILT — Fresh read-only committed reads, allowlisted SQL/report access, wall-clock budgets and explicit oversize failures rather than clipped rows. read_ledger_sql (src/spendguard/store/spend_search/ledger_read.py:779); read_ledger_rows (src/spendguard/store/spend_search/ledger_read.py:951); read_routing_history_report (src/spendguard/store/spend_search/ledger_read.py:1335)
ledger_sync PARTIAL — Capture completeness, batch true-down and realtime reconstruction/sync. Realtime evidence is cached/forensic with representative project attribution, not comprehensive provider billing truth. Some fetch failures lack full completeness flags; correction clearing can precede failed-provider skips. audit_completeness (src/spendguard/analyze/reconciliation/ledger_sync.py:98); true_down (src/spendguard/analyze/reconciliation/ledger_sync.py:140); reconcile_realtime (src/spendguard/analyze/reconciliation/ledger_sync.py:505); sync (src/spendguard/analyze/reconciliation/ledger_sync.py:725)
http_capture PARTIAL — Best-effort httpx/requests/urllib response capture with SDK duplicate suppression. Capture only, no pre-spend enforcement; streams and some oversized/unknown-length bodies are skipped. install (src/spendguard/generate/spend_capture/http_capture.py:329)
calls BUILT — Physical-call and retry-root metadata, actual executor/model/effort, contract feedback, quality measurements and routing summaries. Metadata can survive prompt logging being disabled; some recording errors are swallowed. context (src/spendguard/store/call_corpus/calls.py:283); record_call (src/spendguard/store/call_corpus/calls.py:692); feedback (src/spendguard/store/call_corpus/calls.py:866); cost_summary (src/spendguard/store/call_corpus/calls.py:1007)
guard BUILT — Savings and routing-decision accounting, distinguishing measured savings from counterfactual distribution; prevents duplicate plan-reserved source counting. Savings are not billed money. record_saving (src/spendguard/analyze/measurement/guard.py:139); record_decision (src/spendguard/analyze/measurement/guard.py:281); savings_crosscheck (src/spendguard/analyze/measurement/guard.py:228)
migrate_charges BUILT — Idempotent decimal-conservation cutover from legacy charges, with snapshot rather than destructive table removal. to_spend_events (src/spendguard/store/money_ledger/migrate_charges.py:22); run_cutover (src/spendguard/store/money_ledger/migrate_charges.py:112)
otel_ingest PARTIAL — Stable trace/span deduplicated exported-cost or priced-token ingestion. Cache token metadata affects price but is not fully forwarded; candidate counts can include deduplicated rows. span_to_charge (src/spendguard/generate/spend_capture/otel_ingest.py:112); ingest (src/spendguard/generate/spend_capture/otel_ingest.py:150)
focus_export PARTIAL — FOCUS-shaped CSV/JSON and reconciliation export. Subscription-covered rows lack numeric EffectiveCost/allocated flat plan fee. focus_row (src/spendguard/egress/focus_export.py:62); export_rows (src/spendguard/egress/focus_export.py:109)

Ledger storage maintenance is separate from charge semantics: migrate_from_ledger (src/spendguard/manage/token_operations/lane_queue.py:324) copies live queue rows into the queue database and drops the old money-ledger queue table. Freed pages become reusable; the live file need not shrink until a later VACUUM. It does not perform that VACUUM itself. optimize_queue_db (src/spendguard/manage/token_operations/lane_queue.py:368) refreshes query-planner statistics after drains rather than on every operation.

Prices, catalogs and model parameters

Price resolution and cache semantics

Lowest to highest precedence is built-in _FALLBACK → $SPENDGUARD_HOME/litellm_prices.json → model_catalog.as_price_table() rates → shipped src/spendguard/prices.json → $SPENDGUARD_HOME/prices.json → $SPENDGUARD_HOME/prices.yaml → the file selected by SPENDGUARD_PRICES. The home defaults to ~/.spendguard; later layers merge per-model fields over earlier values (src/spendguard/store/reference_data/pricing.py:22, src/spendguard/store/reference_data/pricing.py:41, src/spendguard/store/reference_data/pricing.py:78). Supply provider/model rates in these data layers instead of embedding prices in application code; catalog capabilities and price provenance remain separate concerns.

_cost clamps cached input into [0, in_tok]. Realtime prices uncached input and cache reads separately, falling back to the full input rate when a cache-read price is absent. Batch uses explicit batch input/output rates and batch_cached_in when provided; without that cache-specific batch rate, cached input receives the ordinary batch-input rate. There is no universal stacking of cache and 50% batch discounts (src/spendguard/store/reference_data/pricing.py:532). Anthropic usage must be normalized because its ordinary input_tokens excludes cache-read/cache-creation tokens, while OpenAI's input count includes cached tokens; the gate adds cache reads before costing and passes cache creation separately (src/spendguard/manage/admission/gate.py:1369).

cross_check_openrouter(run=False) fetches public prices and performs exact-ID comparisons for free, returning unresolved identity and judgment work explicitly. Its default is a zero-spend, read-only drift check, not a semantic all-model price certification. run=True enables agentic identity and price-gap judgments and may spend; it does not silently rewrite the table (src/spendguard/store/reference_data/pricing.py:429).

Module Status and capability Primary entry points
pricing PARTIAL — Layered curated/user/synced pricing, provenance, normalization, token/unit/batch cost, catalog/live/learned ceilings and freshness checks. Unknown cost produces zero plus explicit unpriced tracking. Automatic semantic catalog mapping is a STUB returning None. price (src/spendguard/store/reference_data/pricing.py:469); cost_or_unpriced (src/spendguard/store/reference_data/pricing.py:576); estimate (src/spendguard/store/reference_data/pricing.py:629); max_output_tokens (src/spendguard/store/reference_data/pricing.py:228); verify_pricing (src/spendguard/store/reference_data/pricing.py:634)
model_catalog BUILT — Curated floor plus overlays, provider/pricing/rate/vision/embedding/capability queries and validation. Unknown capabilities are tri-state; row as-of dates differ from fetch timestamps. model_record (src/spendguard/store/reference_data/model_catalog.py:202); rate_limit_for (src/spendguard/store/reference_data/model_catalog.py:316); model_capability (src/spendguard/store/reference_data/model_catalog.py:554); validate_catalog (src/spendguard/store/reference_data/model_catalog.py:614)
models PARTIAL — Shared generation/reasoning parameter authority, effort observations and confirmed error healing. Persisted facts can be applied before verification; family-pattern seeds are existing implementation, not measured proof. apply_call_params (src/spendguard/store/reference_data/models.py:192); resolve_effort (src/spendguard/store/reference_data/models.py:486); record_effort (src/spendguard/store/reference_data/models.py:296); heal_reasoning (src/spendguard/store/reference_data/models.py:417); confirm_reasoning (src/spendguard/store/reference_data/models.py:475)
catalog BUILT — Live model-ID discovery, measured lane serving overlays, ceilings and stale refresh. Live membership does not establish price/capability; TTL is not strict usage refusal. pull_live_catalog (src/spendguard/store/reference_data/catalog.py:32); merge_lane_observation (src/spendguard/store/reference_data/catalog.py:143); served (src/spendguard/store/reference_data/catalog.py:172); refresh_catalog_if_stale (src/spendguard/store/reference_data/catalog.py:225)
sync BUILT — Validated atomic pricing refresh from LiteLLM with curated overrides taking precedence; does not author model capabilities. sync (src/spendguard/store/reference_data/sync.py:174); refresh_if_stale (src/spendguard/store/reference_data/sync.py:208)
sync_capabilities BUILT — Explicit SaaS/GitHub/LiteLLM capability/limit refresh with provenance, as-of dates and completeness audit. audit_catalog_completeness (src/spendguard/store/reference_data/sync_capabilities.py:154); sync_capabilities (src/spendguard/store/reference_data/sync_capabilities.py:188)
refresh PARTIAL — Optional paid web-assisted pricing lookup and explicit write mode; rejects truncated lookup replies. Direct SDK use relies on the installed gate rather than a local explicit require. diff (src/spendguard/store/reference_data/refresh.py:68); main (src/spendguard/store/reference_data/refresh.py:111)
expected_output BUILT — Class/model measured p90 and declared/seed/catalog expected-output estimates, with unknown basis explicit. Estimates are not automatically wire limits. expect (src/spendguard/analyze/cost_estimation/expected_output.py:85); batch_output_estimate (src/spendguard/analyze/cost_estimation/expected_output.py:178)
provider_tokens BUILT — Token estimates using encoding/factors with explicit proxy fallback, agentic factor calibration and confidence/provenance. Process factor cache reload is explicit. count_text (src/spendguard/analyze/cost_estimation/provider_tokens.py:183); calibrate (src/spendguard/analyze/cost_estimation/provider_tokens.py:309); reload_factors (src/spendguard/analyze/cost_estimation/provider_tokens.py:151)
content_tokens BUILT — Text/media token accounting and image dimensions with provider-specific formulas and named fallback assumptions. count_tokens (src/spendguard/analyze/cost_estimation/content_tokens.py:317); count_detail (src/spendguard/analyze/cost_estimation/content_tokens.py:325); image_tokens (src/spendguard/analyze/cost_estimation/content_tokens.py:238)
model_preflight BUILT — Per-spec served/priced checks and cached agentic stale-ID correction, returning every input status. Priced unchecked IDs remain usable; corrections are reported rather than applied. preflight_models (src/spendguard/manage/admission/model_preflight.py:90); configured_specs (src/spendguard/manage/admission/model_preflight.py:116)
reasoning_equivalence BUILT — Bidirectional same-provider lane/metered identity-and-effort mapping. Lesser reasoning needs affirmative judge/sample evidence; availability distinguishes yes/unverified/no. Candidate generation exists here, not bakeoff execution. record_equivalence (src/spendguard/store/reference_data/reasoning_equivalence.py:134); resolve_metered (src/spendguard/store/reference_data/reasoning_equivalence.py:199); resolve_lane (src/spendguard/store/reference_data/reasoning_equivalence.py:273)

Measurement, estimates and experiments

Module Status and capability Primary entry points
measurement BUILT — Separate sample/rubric/instrument/judge/candidate provenance and readings, reconstruction and comparisons. Rerun pins the first judge rather than replaying an entire multi-judge mixture. record_reading (src/spendguard/analyze/measurement/measurement.py:142); compare (src/spendguard/analyze/measurement/measurement.py:251); rerun (src/spendguard/analyze/measurement/measurement.py:308)
estimate BUILT — Fit measured sample distributions and project workload costs. fit_from_sample (src/spendguard/analyze/cost_estimation/estimate.py:35); project (src/spendguard/analyze/cost_estimation/estimate.py:70)
realized BUILT — Before/after adoption measurement and positive-increment savings sync; negative results remain visible. measure (src/spendguard/analyze/measurement/realized.py:23); sync_to_guarded (src/spendguard/analyze/measurement/realized.py:66)
experiment PARTIAL — Stored-I/O A/B pilot/equivalence experiments and guarded OpenAI/Anthropic batch promotion. Realtime exceptions can be silently skipped; effort variants are internal rather than a public axis. experiment (src/spendguard/analyze/measurement/experiment.py:122); promote (src/spendguard/analyze/measurement/experiment.py:374)
equivalence BUILT — Structural/scalar/text comparisons and optional embedding, rubric or custom grading. structural (src/spendguard/analyze/measurement/equivalence.py:65); grade (src/spendguard/analyze/measurement/equivalence.py:123)
effort_titration BUILT — Pilot/chunk/checkpoint effort experiments; only confident outcomes update learned effort, tentative outcomes remain receipts. titrate (src/spendguard/analyze/measurement/effort_titration.py:345)
bakeoff BUILT — Model-by-effort trials with actual served models, estimated caps, quality/requirements judges and replay checks. bakeoff (src/spendguard/analyze/measurement/bakeoff.py:200)
calibrate BUILT — Prediction/actual pairing, held-out backtests, quantile/hierarchical calibration and optional shared exchange. Does not automatically ship new gate policy. predict_cost (src/spendguard/analyze/cost_estimation/calibrate.py:357); record_prediction (src/spendguard/analyze/cost_estimation/calibrate.py:439); backtest (src/spendguard/analyze/cost_estimation/calibrate.py:509)
stability PARTIAL — Repeated-label consistency measurement including errors; not semantic answer quality. CLI has no separate mandatory estimate stage. measure_stability (src/spendguard/analyze/measurement/stability.py:23)
estimate_divergence BUILT — Agentic quote-versus-actual grounding adjudication; failed/unknown judgment refuses enforcement approval. adjudicate_grounding (src/spendguard/analyze/cost_estimation/estimate_divergence.py:81); enforce (src/spendguard/analyze/cost_estimation/estimate_divergence.py:111)
estimate_literals BUILT — AST literal-cost sites with whole-enclosing-context adjudication and cached verdicts. literal_sites (src/spendguard/analyze/assurance/estimate_literals.py:45); adjudicate_literal (src/spendguard/analyze/assurance/estimate_literals.py:115)
token_caps BUILT — AST output-cap site discovery and whole-context adjudication; missing certification is not approval. sites (src/spendguard/analyze/assurance/token_caps.py:100); adjudicate_cap (src/spendguard/analyze/assurance/token_caps.py:202)
verdict_ledger BUILT — Durable adjudication registry and stale/unjudged/failed/cleared comparison. load_verdicts (src/spendguard/analyze/assurance/verdict_ledger.py:27); compare_to_verdicts (src/spendguard/analyze/assurance/verdict_ledger.py:44)
cachetest BUILT — Estimate-first OpenAI/Anthropic cold/write/warm cache experiment and break-even, preserving partial/unknown warm results. Intent suffixes are capped at 400 characters; direct SDK calls rely on installed gate. cache_test (src/spendguard/analyze/measurement/cachetest.py:100)

Learning and optimization

Connected feedback loop

Opt-in physical-call capture and provider/history I/O recovery feed the call corpus; history mining, reconstruction and practice review create conditional insights. brief/advise and model recommendations consume that evidence; experiment tests cost and equivalence, and promote executes the selected path while retaining outputs for subsequent learning. Validation revisits insights as evidence changes; the gate enforces execution, reconciliation identifies capture gaps, and reporting surfaces results (src/spendguard/analyze/measurement/experiment.py:374, src/spendguard/analyze/measurement/experiment.py:374, src/spendguard/analyze/measurement/experiment.py:374, src/spendguard/analyze/measurement/experiment.py:374, src/spendguard/analyze/measurement/experiment.py:374, src/spendguard/analyze/measurement/experiment.py:374, src/spendguard/analyze/measurement/experiment.py:374, src/spendguard/analyze/measurement/experiment.py:374, src/spendguard/analyze/measurement/experiment.py:374, src/spendguard/analyze/measurement/experiment.py:374). This is a connected workflow, with the evidence-clipping, heuristic validation and partial-execution limits in the inventory below; a recommendation alone is not experimental proof. See learning-advisor.md, MONEY-FLOW.md, DATA_PLANE.md, and ROADMAP.md.

The governor governs its own spend

Internal calls labelled through calls.context(intent="spendguard:…") are recognized by the spendguard: prefix. Batch _meta_gate and realtime precheck/accounting route them to the separate daily meta cap and kind='meta' accounting, rather than workload caps. budget.record_meta tags project llm-spendguard in the canonical ledger: “separate meta ledger” means a separate accounting axis, not a separate database (src/spendguard/manage/admission/budget.py:646, src/spendguard/manage/admission/budget.py:646, src/spendguard/manage/admission/budget.py:646, src/spendguard/manage/admission/budget.py:646). GATE_ALLOW is an explicit meta-cap override too. This contract depends on labelling; it does not prove every internal call site is labelled.

Advisor corpus reads exclude spendguard:% intents so the governor's own analysis does not train its workload recommendations (src/spendguard/store/spend_search/ledger_read.py:1022). Advisor and judge models are configurable and must have pricing for reliable meta estimates. validate_advisor checks the configured advisor.model and advisor.judge_model against pricing and returns problems; that validator is not by itself proof every entry point refuses an unpriced model (src/spendguard/store/configuration/ledger_connection.py:302).

Module Status and capability Primary entry points
learn BUILT — Conditional insight lifecycle and temporal graph in SQLite. add_insight (src/spendguard/analyze/learning/learn.py:101); update_insight (src/spendguard/analyze/learning/learn.py:160); add_node (src/spendguard/analyze/learning/learn.py:182); add_edge (src/spendguard/analyze/learning/learn.py:192)
advise BUILT — Confidence-weighted quality/cost recommendation, including zero-valued measurements, amortization and as-of evidence. evidence (src/spendguard/analyze/learning/advise.py:75); ranked (src/spendguard/analyze/learning/advise.py:106); advise (src/spendguard/analyze/learning/advise.py:195)
advisor PARTIAL — Replay reconstruction, aggregate mining and model recommendations from measured frontiers/cold priors. Reconstruction judges are realtime despite older batch prose; broad exception handling can swallow deliberate stops. Mining selects bounded aggregate insights. reconstruct (src/spendguard/store/call_corpus/routing_audit.py:221); mine (src/spendguard/analyze/learning/advisor.py:171); recommend_models (src/spendguard/analyze/learning/advisor.py:291)
validate PARTIAL — Mechanical model-name and aggregate-cost support/contradiction/decay checks. Semantic validation of freeform insights remains unimplemented. validate (src/spendguard/analyze/learning/validate.py:141)
review PARTIAL — High-cost insight review/freshness. Evidence bundling clips prompt/output/notes; freshness can advance on failed review. review (src/spendguard/analyze/measurement/review.py:105); auto_fresh (src/spendguard/analyze/measurement/review.py:177)
bootstrap PARTIAL — History and optional estimate-caged mining/review/reconstruction orchestration. Stage failures print and skip, so final readiness is not proof all stages succeeded. bootstrap (src/spendguard/analyze/learning/bootstrap.py:25)
backfill PARTIAL — OpenAI completed/cancelled and Anthropic history backfill with intent linkage/dedup. Later model groups in a multi-model Anthropic batch can be skipped. backfill (src/spendguard/generate/spend_capture/backfill.py:76)
history PARTIAL — Artifact/git history linkage and optional paid agentic relevance mining. Execution can spend on classification even without applying results. reconstruct_intents (src/spendguard/analyze/learning/history.py:127); enrich_graph (src/spendguard/analyze/learning/history.py:179); mine_git (src/spendguard/analyze/learning/history.py:226)
brief PARTIAL — Structured historical brief and cheap non-denied recommendations; deterministic overlap matching does not establish measured quality. Optional ready-lane refinement. brief (src/spendguard/analyze/learning/brief.py:81)
prompts BUILT — Default zero-spend structural prompt-waste lint and candidate cheaper routes; optional agentic packability assessment recommends rather than applies. lint (src/spendguard/analyze/measurement/prompts.py:91)
cacheaudit BUILT — Shared-prefix savings, script system-prompt candidates and realized cached-input-rate audit. Samples at most 30 prompts per intent/provider/model with heuristic candidate filtering; not exhaustive semantic analysis. audit_cache_opportunities (src/spendguard/analyze/measurement/cacheaudit.py:158)
semcache PARTIAL — Opt-in exact/embedding-similarity cache and JSONL dedup/population; no TTL or universal call interception. JSONL keys omit much of a full request. get_cached (src/spendguard/manage/admission/semcache.py:150); cached_call (src/spendguard/manage/admission/semcache.py:209); dedup_jsonl (src/spendguard/manage/admission/semcache.py:259)
share BUILT — Opt-in deidentified insight generalization/export/import; imported abstractions remain untrusted priors. generalize_insight (src/spendguard/egress/share.py:34); cmd_export (src/spendguard/egress/share.py:85); cmd_import (src/spendguard/egress/share.py:122)

Diagnostics and reliability

Module Status and capability Primary entry points
reliability PARTIAL — Estimate-first probes, cached health/auth/model shifts, remediation and alerts. Some failures become down-state observations; remediation consumes shortened errors. sweep_estimate (src/spendguard/analyze/measurement/reliability.py:99); sweep (src/spendguard/analyze/measurement/reliability.py:171); remediate (src/spendguard/analyze/measurement/reliability.py:296); health_reds (src/spendguard/analyze/measurement/reliability.py:599)
balances BUILT — Provider balance fetching and whole-response agentic extraction, hash cache and declared-balance-minus-ledger fallback; unknown remains unknown. vendor_balance (src/spendguard/analyze/treasury/balances.py:206); refresh_balances (src/spendguard/analyze/treasury/balances.py:242); all_balances (src/spendguard/analyze/treasury/balances.py:288)
anomaly BUILT — Median/MAD daily-spend anomaly heuristic, not semantic cause attribution. robust_z (src/spendguard/analyze/reconciliation/anomaly.py:20); flag_today (src/spendguard/analyze/reconciliation/anomaly.py:40)
cost_integrity BUILT — Impossible cost/token bucket ceiling audit; a result below the ceiling is not proof of correct pricing. audit_metered_cost_vs_tokens (src/spendguard/analyze/reconciliation/cost_integrity.py:122)
metadata_audit BUILT — Cached metadata age/breadth and measured-output-versus-published-limit audit, with unknown limits separate. Optional sync refreshes before inspection. backbone_health (src/spendguard/analyze/assurance/metadata_audit.py:111)
audit PARTIAL — AST gating/known-model audit and optional estimated whole-file deep chunks. Unread files can yield no findings, so absence alone is not complete coverage proof. deep (src/spendguard/analyze/assurance/audit.py:91); main (src/spendguard/analyze/assurance/audit.py:163)
verify BUILT — Structural verification, optional live probes and economics convergence; not an overall requirement proof or served-identity guarantee. verify_system (src/spendguard/analyze/assurance/verify.py:69)
signal BUILT — Scrubbed cost/quality/waste signals and scoped SaaS upload; cancelled billed batches appear separately. Heuristic recommendations and whole-batch allocation to multiple intent/model groups mean totals are not necessarily additive. build_signals (src/spendguard/egress/signal.py:12); push_signal (src/spendguard/egress/signal.py:126)

Conversation imports and attribution

Module Status and capability Primary entry points
claudecode PARTIAL — Incremental transcript usage, classification, invoice/overage ingestion, window attribution and context trajectories. Covered chat has billed zero and separate estimated value; inferred overage is provisional until invoices replace it. Story classification uses clipped excerpts. ingest_events (src/spendguard/generate/spend_capture/claudecode.py:179); ingest_invoices (src/spendguard/generate/spend_capture/claudecode.py:665); attribute_overage (src/spendguard/generate/spend_capture/claudecode.py:754); sync (src/spendguard/generate/spend_capture/claudecode.py:1480); context_trajectory (src/spendguard/generate/spend_capture/claudecode.py:873)
codex PARTIAL — Codex usage import, project classification, daily value and sync; final session model can misprice mixed-model usage. update (src/spendguard/generate/spend_capture/codex.py:133); classify (src/spendguard/generate/spend_capture/codex.py:179); sync (src/spendguard/generate/spend_capture/codex.py:237)
chat PARTIAL — Browser-cookie/internal-API chat import, estimated text/image value, classification and consented sync/loop. Estimates are proxies; classifications use snippets, and watermark advancement after failures can omit retries. update (src/spendguard/generate/spend_capture/chat.py:386); classify (src/spendguard/generate/spend_capture/chat.py:992); sync (src/spendguard/generate/spend_capture/chat.py:590); loop (src/spendguard/generate/spend_capture/chat.py:1070)
attribution BUILT — Shared taxonomy/team mapping and chunked agentic item classification with estimates; successful partial replies survive while omissions remain failures. taxonomy (src/spendguard/analyze/reconciliation/attribution.py:39); classify_items (src/spendguard/analyze/reconciliation/attribution.py:79)
conv PARTIAL — Canonical org/team/project resolution, human precedence, batch links, session chunks, segments and realtime/GPU attribution. Whole contiguous session chunks coexist with legacy clipped classifiers/index/synthesis. Segmentation uses every user record rather than an ask classifier; realtime tallies are explicit lower bounds. resolve (src/spendguard/analyze/learning/conv.py:659); session_chunks (src/spendguard/analyze/learning/conv.py:900); segments (src/spendguard/analyze/learning/conv.py:365); attribute_segments (src/spendguard/analyze/learning/conv.py:468); realtime_token_tally (src/spendguard/analyze/learning/conv.py:981)
tag PARTIAL — Deterministic retag and explicit project moves. Residual LLM retag has an estimate surface but no execution implementation. retag_deterministic (src/spendguard/analyze/reconciliation/tag.py:47); move_project (src/spendguard/analyze/reconciliation/tag.py:69); estimate_llm_retag (src/spendguard/analyze/reconciliation/tag.py:102)
workdone PARTIAL — Git/intent work summaries and rollups; optional summarization uses bounded intent/commit excerpts rather than whole evidence. build_workdone (src/spendguard/analyze/reconciliation/workdone.py:76); summarize (src/spendguard/analyze/reconciliation/workdone.py:179)

Residency, compaction and receipts

The residency axis and PostToolUse nudge are implemented, despite older repository instructions describing them as future work. They estimate attribution of observed context cost; they do not recover exact historical compaction boundaries.

Module Status and capability Primary entry points
residency_gate BUILT — Size/session-length-triggered, whole-tool-result, cached ready-lane agentic delegability judgment and cost warning. PostToolUse warns only; it cannot remove already-resident evidence and fails open. evaluate_posttooluse (src/spendguard/manage/admission/residency_gate.py:175); install_residency_gate (src/spendguard/manage/admission/residency_gate.py:262)
compaction PARTIAL — Preservation guidance, precompact/session-start records, digest and measured compaction ratios. Agentic advice uses bounded tails/snippets rather than whole session evidence. agentic_advise (src/spendguard/generate/spend_capture/compaction.py:166); record_precompact (src/spendguard/generate/spend_capture/compaction.py:242); preservation_digest (src/spendguard/generate/spend_capture/compaction.py:259); record_sessionstart (src/spendguard/generate/spend_capture/compaction.py:271)
receipt PARTIAL — Separate real-cost and subscription-value axes, savings, health, queue/risk/residency and unpriced warnings, terminal renderers and installation. Project filtering scopes API/value but flat fees, remote and external costs can remain global; default CLI is a global table plus value tree, not complete proportional per-repo allocation. Assumed fees are labelled. tally (src/spendguard/analyze/spend_reporting/receipt_tally.py:631); render_tally (src/spendguard/analyze/spend_reporting/receipt_render.py:151); render_tree (src/spendguard/analyze/spend_reporting/receipt_render.py:434); cli (src/spendguard/analyze/spend_reporting/receipt_cli.py:171); install_cli (src/spendguard/analyze/spend_reporting/receipt_cli.py:416)

Residency decomposition and subagent counterfactual calculations live in claudecode.py: residency_decomposition (src/spendguard/generate/spend_capture/claudecode.py:1041), residency_counterfactual_costs (src/spendguard/generate/spend_capture/claudecode.py:1028) and residency_summary_lines (src/spendguard/generate/spend_capture/claudecode.py:1198). These feed receipt/diagnostic surfaces; there is no separate missing residency subsystem to invent.

Reconciliation, truth and close

Fetch → transform → load

The data-plane design keeps external fetches and output/DB/HTTP loads around a directly testable transformation core. report.build_rows is the pure roll-up reference (src/spendguard/analyze/spend_reporting/report.py:154; offline tests: tests/test_report_build.py:1). Other named offline-tested transforms include chat _value_breakdown, _digest_conv, _day_rows, transcript _row_cost/_project_of, and conversation _dedup_top (src/spendguard/analyze/learning/conv.py:1156, src/spendguard/analyze/learning/conv.py:1156, src/spendguard/analyze/learning/conv.py:1156, src/spendguard/analyze/learning/conv.py:1156, src/spendguard/analyze/learning/conv.py:1156, src/spendguard/analyze/learning/conv.py:1156; tests/test_chat_value.py:1, tests/test_transcript_pure.py:1). Their existing attribution/heuristic limits remain as recorded above; the removed conv._project_of is not part of this contract.

SaaS build_rollup_rows and build_guarded_rows shape plain data separately from the I/O shell _rollup_rows, but now print exclusion diagnostics, so they are not strictly pure/no-print transforms (src/spendguard/egress/saas.py:484, src/spendguard/egress/saas.py:484, src/spendguard/egress/saas.py:484). Reconciliation follows a compatible map/reduce pattern: Source adapters produce comparable records and portfolio reduction computes residuals (src/spendguard/analyze/reconciliation/reconcile.py:106, src/spendguard/analyze/reconciliation/reconcile.py:106).

CI isolates offline correctness tests from provider I/O and configures two coverage floors: 40% whole-package and 78% for its explicitly listed money-critical modules. These are configured requirements, not a claim of currently measured achieved coverage; no historical achieved percentage is restored (.github/workflows/ci.yml:37, .github/workflows/ci.yml:47, .github/workflows/ci.yml:48). See DATA_PLANE.md for seams and MONEY-FLOW.md for conservation/accounting boundaries.

Module Status and capability Primary entry points
reconcile PARTIAL — Source protocol and unified truth/captured/residual report, with unknown/completeness explicit; not every cost category has a truth adapter. Source (src/spendguard/analyze/reconciliation/reconcile.py:106); all_sources (src/spendguard/analyze/reconciliation/reconcile.py:123); completeness (src/spendguard/analyze/reconciliation/reconcile.py:162); run (src/spendguard/analyze/reconciliation/reconcile.py:228)
reconcile_openai BUILT — Completed/cancelled batch billing retrieval for reconciliation. fetch_batches (src/spendguard/analyze/reconciliation/reconcile_openai.py:96)
reconcile_anthropic BUILT — Cached ended-period Anthropic cost retrieval with malformed-row skipping. refresh_cache (src/spendguard/analyze/reconciliation/reconcile_anthropic.py:100); cost_by_day (src/spendguard/analyze/reconciliation/reconcile_anthropic.py:154)
realtime_oracle BUILT — Admin hourly usage and project/day attribution; requires provider evidence and access. openai_hourly (src/spendguard/analyze/reconciliation/realtime_oracle.py:45); anthropic_hourly (src/spendguard/analyze/reconciliation/realtime_oracle.py:67); by_project_day (src/spendguard/analyze/reconciliation/realtime_oracle.py:132)
reconcile_calls BUILT — Dry-run-first stable recording-gap repair. recording_gaps (src/spendguard/analyze/reconciliation/reconcile_calls.py:52); reconcile (src/spendguard/analyze/reconciliation/reconcile_calls.py:76)
truth PARTIAL — Owner-scoped provider/GPU daily truth upload respecting privacy; client implementation does not verify remote server behavior. rows (src/spendguard/analyze/reconciliation/truth.py:19); push_truth (src/spendguard/analyze/reconciliation/truth.py:37)
trust BUILT — Comparability-aware local/provider/server trust report; unknown is not clean and mirrored/meta rows are excluded appropriately. provider_truth (src/spendguard/analyze/reconciliation/trust.py:40); trust_report (src/spendguard/analyze/reconciliation/trust.py:86)
close BUILT — Monthly truth/captured close, unusable-source gaps and CSV; empirical current-month run-rate requires observed days. build_close (src/spendguard/analyze/spend_reporting/close.py:24); to_csv (src/spendguard/analyze/spend_reporting/close.py:75)
report PARTIAL — Daily/weekly/monthly billing/usage report with unpriced visibility. Failed admin retrieval can leave partial totals; automatic review freshness can invoke LLM work despite older zero-call prose. build_rows (src/spendguard/analyze/spend_reporting/report.py:154); generate_report (src/spendguard/analyze/spend_reporting/report.py:297)

Remote compute and provider extension

Module Status and capability Primary entry points
gpu_port BUILT — Provider contract, runtime/day slicing, bill-or-rate accounting and source registry; unknown prices remain explicit. Label mapping uses existing substring rules. GPUProvider (src/spendguard/generate/spend_capture/gpu_port.py:33); ProviderGPUSource (src/spendguard/generate/spend_capture/gpu_port.py:219); register_source (src/spendguard/generate/spend_capture/gpu_port.py:254); sources (src/spendguard/generate/spend_capture/gpu_port.py:284)
resources PARTIAL — Vast inventory/history, disappeared-instance recovery, GPU attribution, alert-only compute caps and ledger sync. Forensic remote reconstruction is bounded/heuristic, not complete truth; account top-ups proxy consumed compute and residuals remain unattributed. Never kills jobs. instances (src/spendguard/generate/spend_capture/resources.py:74); gpu_rows (src/spendguard/generate/spend_capture/resources.py:155); compute_exceeded (src/spendguard/generate/spend_capture/resources.py:261); reconstruct_remote_llm (src/spendguard/generate/spend_capture/resources.py:589); sync (src/spendguard/generate/spend_capture/resources.py:890)
remote BUILT — SSH startup enforcement verification and remote ledger sync; unknown is not verified. Single-target errors can still exit successfully. onstart_snippet (src/spendguard/platform/remote.py:70); verify_remote_enforcement (src/spendguard/platform/remote.py:89); sync (src/spendguard/platform/remote.py:136); sync_all (src/spendguard/platform/remote.py:175)
lambda_adapter PARTIAL — Lambda inventory provider; untimed records and no account billing oracle. LambdaProvider (src/spendguard/generate/spend_capture/lambda_adapter.py:43); source (src/spendguard/generate/spend_capture/lambda_adapter.py:75)
runpod_adapter PARTIAL — RunPod inventory/rates; stopped/untimed gaps, no account truth, API failure can return empty inventory. RunPodProvider (src/spendguard/generate/spend_capture/runpod_adapter.py:51); source (src/spendguard/generate/spend_capture/runpod_adapter.py:100)
modal_adapter PARTIAL — Modal SDK daily billed source; no SDK is unconfigured and account truth can be unknown. ModalProvider (src/spendguard/generate/spend_capture/modal_adapter.py:34); source (src/spendguard/generate/spend_capture/modal_adapter.py:105)
provider_plugins BUILT — Entry-point plugin loading, success-once registration, retry after failures and contained plugin exceptions/SystemExit. load_plugins (src/spendguard/generate/execution/provider_plugins.py:19); loaded (src/spendguard/generate/execution/provider_plugins.py:55)
provider_kit BUILT — Offline conformance checks for registration, pricing, idempotence and failure containment. run_conformance (src/spendguard/generate/execution/provider_kit.py:22); assert_conformance (src/spendguard/generate/execution/provider_kit.py:84)
litellm_adapter PARTIAL — Success-callback accounting, skipping already-gated SDK paths; capture only, not pre-spend enforcement. record_litellm (src/spendguard/generate/spend_capture/litellm_adapter.py:55); install (src/spendguard/generate/spend_capture/litellm_adapter.py:81)
bedrock_adapter PARTIAL — boto3 response capture; streams are not consumed and unknowns remain unpriced. No admission gate. install (src/spendguard/generate/spend_capture/bedrock_adapter.py:73)
vertex_adapter PARTIAL — Sync/async generation and embedding capture; no streaming capture or pre-spend enforcement, with best-effort failure handling. install (src/spendguard/generate/spend_capture/vertex_adapter.py:98)

Organization sync, discovery and operations

Standalone client and server contract

Local gating, pricing, ledger, routing and local analysis require no team server; provider execution and fresh remote evidence still require their own connectivity. The opt-in SaaS seam uses a versioned /v1 HTTP contract and a Bearer key; the server maps identity to its hierarchy rather than requiring callers to attach a trusted team/org identity to every request (src/spendguard/egress/saas.py:136, src/spendguard/egress/saas.py:284). visibility=private is the default. Normal upload paths return without pushing in that mode; enabled roll-ups select aggregate fields rather than prompts, outputs or keys. Connection does not authorize unresolved org ownership, and additional trust/privacy caveats remain in the inventory (src/spendguard/store/configuration/ledger_connection.py:882, src/spendguard/egress/saas.py:484, src/spendguard/egress/saas.py:527).

pull_policy caches server caps in local config. Advisory caps are displayed suggestions and do not replace local limits; enforced caps resolve to the server ceiling or the smaller local cap, so local config can tighten but cannot loosen the effective policy (src/spendguard/egress/saas.py:787, src/spendguard/egress/saas.py:787). This resolution contract does not erase the gate's explicit override and fail-open boundaries. Sync reports client-computed ledger/status, truth, decisions and savings; estimated subscription value and guarded savings remain separate from real-cost totals.

Aggregate rows carry deterministic uids; saas crosscheck compares local and server rows and reports matching, local-only, server-only and drift states. It excludes estimated-value rows and retains provider/GPU verification gaps rather than treating missing evidence as clean (src/spendguard/store/configuration/config_store.py:999). Server implementation and byte-for-byte compatibility cannot be independently established from this client tree.

The documented external catalog flow is publication of this repository's model_catalog.json → server ingestion into a global curated catalog → anonymous /api/public/catalog and /catalog, plus authenticated /v1/models?curated=1 overlays. Source-owned as_of dates are distinct from ingestion timestamps (DATA_PLANE.md, docs/DATA_PLANE.md:149). The client pull persists overlays above the shipped floor, preserves row dates and leaves existing data intact when unavailable (src/spendguard/egress/saas.py:177, src/spendguard/store/reference_data/model_catalog.py:180). The server/publication legs are contract documentation, not locally verified server capabilities.

Event consumers and observability

spendguard.on_event(callback) registers callback(event: dict) and is also a decorator. The payload includes kind, provider/model, cost, decision and available in_tok/out_tok/cached_in_tok; envelope preserves it and fills v, type, unique id, UTC ts, and, when attribution resolves, conv_id/project (src/spendguard/analyze/cost_estimation/estimate.py:70, src/spendguard/analyze/cost_estimation/estimate.py:70). For example, spendguard.on_event(event_sink) connects an application's existing sink. Callbacks run inline: keep them fast; swallowed exceptions do not make a slow callback asynchronous (src/spendguard/analyze/cost_estimation/estimate.py:70).

Set emit.webhook or SPENDGUARD_WEBHOOK for JSON POSTs, and emit.otel or SPENDGUARD_OTEL for OpenTelemetry. These environment controls override config and accept explicit off values (src/spendguard/egress/emit.py:38). Webhook/OTel delivery uses a bounded daemon-thread queue and drops events when flooded; it is best-effort telemetry, not a durable audit transport (src/spendguard/egress/emit.py:69, src/spendguard/egress/emit.py:81, src/spendguard/egress/emit.py:174). OTel uses the application's global meter/tracer and exporter: counters are spendguard.cost_usd (USD) and gen_ai.client.token.usage (token), token type is input/output, and spans carry gen_ai.system, gen_ai.request.model, gen_ai.operation.name, available gen_ai.usage.*_tokens, and spendguard.decision (src/spendguard/egress/emit.py:107, src/spendguard/egress/emit.py:118).

Module Status and capability Primary entry points
saas PARTIAL — Aggregate client linking, owned scopes, privacy, catalog/calibration/insight/work/status sync, taxonomy, commands and advisory/enforced policy retrieval. Server implementation is outside this tree. GPU sync precedes trust alarm; alarm blocks later ledger upload but unknown/error can continue. Unresolved org ownership uploads nothing. link (src/spendguard/egress/saas.py:284); push_rollup (src/spendguard/egress/saas.py:527); pull_policy (src/spendguard/egress/saas.py:787); run_commands (src/spendguard/egress/saas.py:819); sync (src/spendguard/egress/saas.py:895)
sources BUILT — Transcript/plugin/interpreter discovery and receipt source-family classification without exposing secrets. register_transcript_source (src/spendguard/generate/spend_capture/sources.py:64); discover_sources (src/spendguard/generate/spend_capture/sources.py:180)
scan BUILT — Local source inventory, zero LLM/network. collect (src/spendguard/generate/spend_capture/scan.py:24); render (src/spendguard/generate/spend_capture/scan.py:54)
schedule BUILT — Idempotent OS scheduler installation/removal; GPU stamping precedes upload. install_schedule (src/spendguard/platform/schedule.py:26)
fleet BUILT — Loaded-SHA consumer registration, dead-PID pruning, supervised stale restarts and install refresh. Unsupervised consumers are warned rather than killed. register_consumer (src/spendguard/platform/fleet.py:472); running_consumers (src/spendguard/platform/fleet.py:563); restart_stale (src/spendguard/platform/fleet.py:657); refresh_stale_installs (src/spendguard/platform/fleet.py:866)
release BUILT — Loaded-SHA/green-pointer lifecycle and promotion checks. Promotion consumes supplied gate evidence; it does not run the suite itself. CLI deployment orchestrates validation separately. served_sha (src/spendguard/platform/release.py:70); should_respawn (src/spendguard/platform/release.py:136); promote_release (src/spendguard/platform/release.py:163)
notify BUILT — Configured Resend/SMTP notification transport. is_configured (src/spendguard/egress/notify.py:70); send_email (src/spendguard/egress/notify.py:82)
emit BUILT — Best-effort event callbacks and bounded asynchronous webhook/OTel emission. on_event (src/spendguard/egress/emit.py:32); emit (src/spendguard/egress/emit.py:174)
deid PARTIAL — Regex redaction floor plus optional Presidio, explicit degraded/off modes; not a complete PII guarantee. redact (src/spendguard/egress/deid.py:184)

Public surfaces and entry modules

Module Status and capability Primary entry points
cli BUILT — Lazy console dispatch including ask/delegate, lane/config/gate, ledger/reconcile/receipt, diagnostics, experiments, corpus work and operational commands. Whole-job aliases are submit-jobs/run-jobs/whole-job; queue planning is read-only. Deployment can run validation/promote/restart but was not invoked for this inventory. main (src/spendguard/interface/cli.py:371); help_text (src/spendguard/interface/cli.py:89); ledger_read_cli (src/spendguard/interface/cli.py:95)
mcp_server PARTIAL — Stdio JSON-RPC and threaded HTTP MCP, client registration and 23 tools. Some tools can spend without mandatory budget staging; vision cache keys use path strings rather than image bytes and can become stale after file replacement. handle (src/spendguard/interface/mcp_server.py:783); serve_stdio (src/spendguard/interface/mcp_server.py:909); serve_http (src/spendguard/interface/mcp_server.py:1102); register_client (src/spendguard/interface/mcp_server.py:960)
crossllm PARTIAL — Stable ask/vision facade, budgetless estimate, priced-model preflight, vendor fan/first execution and durable vision delegation. Multiple models from the same vendor can collide in vendor-keyed result maps. ask (src/spendguard/interface/crossllm.py:276); ask_vision (src/spendguard/interface/crossllm.py:346)
serve BUILT — HTTP ask/embed/metadata/health surface with body limits, refusal responses and token requirement off loopback. serve requires enforcement; constructing a server alone does not. make_server (src/spendguard/interface/serve.py:119); serve (src/spendguard/interface/serve.py:130)
compare PARTIAL — Immediate paid comparison command with no separate local estimate stage. main (src/spendguard/analyze/measurement/compare.py:16)
cascade PARTIAL — Cheap-to-strong verification ladder. Default verification is nonempty/JSON syntax, not semantic correctness; final output can still fail verification. cascade (src/spendguard/manage/routing/cascade.py:40); default_verify (src/spendguard/manage/routing/cascade.py:24)
escalation_ladder PARTIAL — Relative escalation and confirmed zero-billable cancellation helpers; not wired as an active soft-deadline observer. relative_escalation_gate (src/spendguard/manage/admission/escalation_ladder.py:15); cancel_on_zero_billable (src/spendguard/manage/admission/escalation_ladder.py:46)
init BUILT — Lazy package API, optional adapter installers and automatic gate bootstrap; bootstrap can fail open unless required mode is set. Cost function is exported as estimate_cost to avoid shadowing estimate module. install_litellm (src/spendguard/__init__.py:232); which_package (src/spendguard/__init__.py:277)
main BUILT — python -m spendguard forwards to CLI main; no independent function definition. src/spendguard/main.py:1
_version BUILT — Package version constant source. src/spendguard/platform/_version.py:1
cli_arguments BUILT — Shared fixed-format option-value parsing helper. cli_option_value_after (src/spendguard/interface/cli_arguments.py:4)
ui BUILT — Shared estimate-only banner. estimate_only (src/spendguard/interface/ui.py:11)

MCP tool names (all prefixed spendguard_): ledger_read, delegate, version, health, savings, route_cost, route_realized, route_horizon, plan_queue, run_jobs, advise, models, recommend, bakeoff, stability, vision, spend_overview, overage_status, top_conversations, conversation_cost, compaction_candidates, dispatch_state, config. run_jobs plans without its execution budget; delegate supports estimate; bakeoff/vision estimate absent a budget. Health can probe/remediate, recommend can invoke meta work, and stability can run paid trials.

Vision and embeddings are adapter capabilities: vision (src/spendguard/generate/execution/adapters.py:1124), embed (src/spendguard/generate/execution/embeddings.py:97), embed_batch (src/spendguard/generate/execution/embeddings.py:322), embed_compare (src/spendguard/generate/execution/embeddings.py:371). Embedding work supports chunk/checkpoint recovery and named oversize-item gaps. Native embedding Batch is OpenAI-only; Gemini's native batch leg is unwired. Embedding comparison measures vector similarity/correlation rather than retrieval quality.

The console entry declared by pyproject.toml is spendguard = spendguard.cli:main; there is no separate repository-root Python CLI/MCP implementation. The package has required dependencies, including psutil (and conditional tomli); it is not dependency-free.

Non-Python package artifacts and coverage boundary

All 173 Python modules under src/spendguard/ are catalogued above, including implementation helpers and entry modules. The five other non-cache package files were also inspected:

  • src/spendguard/model_catalog.json: curated runtime model records; packaged catalog SSOT.
  • src/spendguard/prices.json: generated pricing projection, packaged for runtime use.
  • src/spendguard/model_catalog.json~: backup snapshot; not runtime SSOT or packaged data.
  • src/spendguard/README.md: historical module map; some counts/descriptions are stale, so source takes precedence.
  • src/spendguard/py.typed: empty packaged typing marker.

Known gaps / design in flight

  • Prospective coalescing already exists. Its missing pieces are agentic coalescing policy and per-call deadline/SLA flush, not the accumulation queue itself.
  • Durable queues, admission windows and whole-job planning are separate built mechanisms. Queue result truncation and mixed-contract whole-job grouping need explicit design attention.
  • Anthropic submit/collect exists, but whole-job batch execution is OpenAI-only and tracker polling is not provider-correct throughout. Optional durable storm execution is not default wiring.
  • Codex pool admission hardening exists; broker failure/local fallback weakens a strict host-wide-cap guarantee.
  • Gate enforcement is not universal fail-closed coverage. Raw HTTP, LiteLLM, Bedrock and Vertex capture must not be mistaken for pre-spend admission; abandoned streams and fine-tuning cost have gaps.
  • Several judgment paths still clip evidence or use mechanical meaning proxies, as identified in their entries. This map records existing behavior rather than asserting compliance with repository rules.
  • Bulk/checkpoint budgeting and schema/image/reasoning identity have the limitations listed above; timeout does not imply cancellation or zero bill.
  • Semantic pricing-name mapping is a stub; semantic freeform insight validation and residual LLM retag execution remain absent. Soft-deadline cancellation/escalation helpers are not integrated into an active observer.
  • Residency measurement and live warning are built. Exact historical context attribution, complete project-proportional receipt allocation, provider truth for every category and independently verified server behavior are not established by this tree.