feat: report quota balance, burn rate, and runway #30

Merged
alee merged 6 commits from feat/quota-balance-and-burn-rate into main 2026-09-05 04:47:16 +00:00
Owner

quota-balance-and-burn-rate

Report live account balance, burn rate, and projected runway from the provider-reported allowance_remaining_usd, instead of the misleading "X% of plan" warning.

Behavior

  • /metrics quota now reports balance_usd, balance_at, burn_rate_usd_per_hour, projected_hours_remaining, runway_low_warning, runway_note, burn_window_hours derived from allowance_remaining_usd.
  • Burn is computed ONLY from the most recent monotonically-decreasing balance segment within the window (segmented at every credit top-up), so a top-up (0.0071 → 20.0071 on 2026-09-02) cannot produce a phantom ~$20 burn.
  • BOTH guards on the segment: minimum 3 samples AND minimum 0.5h. Below either, burn is None with an operator-readable runway_note — never a wild extrapolation right after a top-up.
  • kWh figures: metered_kwh_period (new, billing-period since billing_reset_day) + metered_kwh_30d (honest rolling). metered_fraction_of_plan uses the period figure when configured.
  • reset_date KEEPS its key in all three emitters (quota_burn, local_energy_summary, pinch_summary) and now carries the billing-period start; new window_start_30d carries the rolling start. No field lies about its meaning.
  • Admin quota chip/modal lead with balance + runway (green/amber/red on runway_low_warning); TUI data layer + legend (period since <reset_date> vs window start <window_start_30d>).
  • scoring_coverage warning corrected: overage is billed against the credit balance; plan_kwh_per_period gates nothing.
  • Four new objective knobs: quota_burn_window_hours (24), quota_runway_warning_hours (6), quota_burn_min_segment_samples (3), quota_burn_min_segment_hours (0.5).

Scope fence honored

  • No request is gated/refused on balance, burn, or runway. plan_kwh_per_period gates nothing.
  • No balance reconstruction by summing cost_usd. metrics.py does not import dispatcher. max_energy_per_request behavior unchanged.

Verification

  • All new regression tests FAIL on unmodified main (fail-on-main evidence captured: 11 failed / 45 deselected; KeyError/assert on missing fields and reset_date semantics) and PASS after.
  • Full suite green with local_energy.enabled both true and false: 1199 passed each way.
  • Root config/config.local.yaml byte-identical before/after (sha256 cc3d4c2a…5549).
  • Commits: 5 atomic (metrics / config / admin / tui / test).
## quota-balance-and-burn-rate Report live account balance, burn rate, and projected runway from the provider-reported `allowance_remaining_usd`, instead of the misleading "X% of plan" warning. ### Behavior - `/metrics` `quota` now reports `balance_usd`, `balance_at`, `burn_rate_usd_per_hour`, `projected_hours_remaining`, `runway_low_warning`, `runway_note`, `burn_window_hours` derived from `allowance_remaining_usd`. - Burn is computed ONLY from the most recent monotonically-decreasing balance segment within the window (segmented at every credit top-up), so a top-up (0.0071 → 20.0071 on 2026-09-02) cannot produce a phantom ~$20 burn. - BOTH guards on the segment: minimum 3 samples AND minimum 0.5h. Below either, burn is `None` with an operator-readable `runway_note` — never a wild extrapolation right after a top-up. - kWh figures: `metered_kwh_period` (new, billing-period since `billing_reset_day`) + `metered_kwh_30d` (honest rolling). `metered_fraction_of_plan` uses the period figure when configured. - `reset_date` KEEPS its key in all three emitters (`quota_burn`, `local_energy_summary`, `pinch_summary`) and now carries the billing-period start; new `window_start_30d` carries the rolling start. No field lies about its meaning. - Admin quota chip/modal lead with balance + runway (green/amber/red on `runway_low_warning`); TUI data layer + legend (`period since <reset_date>` vs `window start <window_start_30d>`). - `scoring_coverage` warning corrected: overage is billed against the credit balance; `plan_kwh_per_period` gates nothing. - Four new objective knobs: `quota_burn_window_hours` (24), `quota_runway_warning_hours` (6), `quota_burn_min_segment_samples` (3), `quota_burn_min_segment_hours` (0.5). ### Scope fence honored - No request is gated/refused on balance, burn, or runway. `plan_kwh_per_period` gates nothing. - No balance reconstruction by summing `cost_usd`. `metrics.py` does not import `dispatcher`. `max_energy_per_request` behavior unchanged. ### Verification - All new regression tests FAIL on unmodified `main` (fail-on-main evidence captured: 11 failed / 45 deselected; `KeyError`/assert on missing fields and `reset_date` semantics) and PASS after. - Full suite green with `local_energy.enabled` both true and false: **1199 passed** each way. - Root `config/config.local.yaml` byte-identical before/after (sha256 `cc3d4c2a…5549`). - Commits: 5 atomic (metrics / config / admin / tui / test).
alee added 6 commits 2026-09-05 04:30:43 +00:00
The plan required the tariff lines in config/config.yaml to stay
uncommitted. PR #26 moved deployment values into the gitignored
config/config.local.yaml overlay, so config/config.yaml is clean and fully
tracked now. Left as written, an executor would hunt for tariff lines that
are not there and treat an ordinary tracked file as untouchable -- which
matters here because §3 of this plan edits comments in config/config.yaml
deliberately.

Points the criterion at the overlay instead, which is the file that is not
in git history and cannot be restored.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VRQXz5SYZYVWscxS1QqF6U
alee merged commit af22bbf16e into main 2026-09-05 04:47:16 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: alee/6krrt#30