Files
rune/scripts/gen_provider_budget_truth.py
T
Nick 8a08f9b4be
CI Pipeline / best-practices (push) Successful in 11s
CI Pipeline / documentation (push) Successful in 3s
CI Pipeline / rust-surface (push) Failing after 17s
CI Pipeline / go-surface (push) Failing after 20s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
CI Pipeline / type-check (push) Canceled after 29s
deploy / deploy (push) Canceled after 47s
Auto-version and Release / release (push) Canceled after 50s
CI Pipeline / lint (push) Canceled after 45s
CI Pipeline / unit-tests (push) Canceled after 45s
CI Pipeline / canary (push) Canceled after 46s
feat(provider_budget): close PARTIAL gaps — dichotomy wave
2026-10-13 08:04:24 +01:00

184 lines
7.4 KiB
Python

#!/usr/bin/env python3
"""Freeze the provider_budget truth corpus (dichotomy wave #2479 gap-closing, GO).
Drives the LIVE Python oracle (src/rune/provider_budget.py) through the
shared harness (scripts/freeze_truth.py — RUNE_PROVIDER_BUDGET_CORE=python
pinned, inputs deep-copied, {"fn","args","kwargs","expected"} envelope) and
freezes to src/go/provider-budget/truth_frozen.json (embedded VERBATIM by
the Go battery, truth_frozen_test.go).
Determinism contract (why a fixture HOME): the module-level oracle fns all
run through the global ProviderBudgetTracker, whose storage/config paths
come from $HOME (expanduser("~/.rune/provider_budgets.json") and
"~/.config/mimocode/mimocode.jsonc"). Every case therefore replays against
a REBUILT fixture home:
HOME = /tmp/rune_pb_truth_home
.rune/provider_budgets.json ← STORAGE_FIXTURE (seeded providers)
.config/mimocode/mimocode.jsonc ← CONFIG_FIXTURE (init-branch surface)
Stateful cases (track_usage mutations) are legal because the oracle's own
_save mutates the fixture home identically on every replay from the same
initial state — the truth is a replayable script over the canonical home.
What is frozen vs seam-tested (JSON-envelope law): freeze() json.dumps the
expected value, so object-returning fns (get_tracker, get_best_provider →
ProviderBudget) freeze only at their None arms, and check_provider on a
KNOWN provider freezes nowhere (datetime.now timestamp + live socket).
Those branches are pinned by the Go seam battery (fake transport + pinned
clock) and the random-op live parity instead.
Coverage via this harness: get_status (empty tie-break → tracked shifts →
budget exhaustion → post-failover all-down), track_usage (known+cost,
known default-cost, unknown no-op, disabled-provider tracking), failover
(disable-last-available → None arm, unknown no-op arm), check_provider
(not-found arm), get_best_provider (all-down → None arm).
Self-verifying: rebuilds the fixture home, freezes, rebuilds AGAIN, then
runs the shared harness gate — must report byte-identical:
PYTHONPATH=src python3 scripts/freeze_truth.py --verify \
src/go/provider-budget/truth_frozen.json \
--module rune.provider_budget
Run:
python3 scripts/gen_provider_budget_truth.py
"""
import json
import os
import shutil
import subprocess
import sys
from pathlib import Path
REPO = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO / "src"))
sys.path.insert(0, str(REPO / "scripts"))
HOME = Path("/tmp/rune_pb_truth_home")
STORAGE = HOME / ".rune" / "provider_budgets.json"
CONFIG = HOME / ".config" / "mimocode" / "mimocode.jsonc"
OUT = REPO / "src" / "go" / "provider-budget" / "truth_frozen.json"
# WARNING: keep byte-equal with the fixtures embedded in
# src/go/provider-budget/truth_frozen_test.go — the Go battery replays the
# frozen truth against the SAME canonical initial state.
CONFIG_FIXTURE = {
"provider": {
"anthropic-claude": {
"options": {"baseURL": "https://api.anthropic.example", "apiKey": "sk-fixture-anthropic"},
},
"openai-main": {
"options": {"baseURL": "https://api.openai.example/v1", "apiKey": "sk-fixture-openai"},
},
"ollama": {
"options": {"baseURL": "http://127.0.0.1:11434", "apiKey": ""},
},
},
}
def _provider(name, ptype, url, limit, used, tlimit, tused, enabled):
return {
"name": name,
"provider_type": ptype,
"url": url,
"monthly_limit": limit,
"monthly_used": used,
"token_limit": tlimit,
"tokens_used": tused,
"rpm_limit": 0,
"rpm_remaining": 0,
"tpm_limit": 0,
"tpm_remaining": 0,
"enabled": enabled,
"last_check": None,
"last_error": None,
}
STORAGE_FIXTURE = {
# alpha: available, budget_remaining 7.0 — ties with delta (7.0) at case 1;
# the oracle's stable sort keeps insertion order → best = alpha.
"alpha": _provider("alpha", "openai-compatible", "https://alpha.example/v1",
10.0, 3.0, 100000, 40000, True),
# beta: over budget (5.0 >= 5.0) — unavailable arm.
"beta": _provider("beta", "openai-compatible", "https://beta.example/v1",
5.0, 5.0, 0, 0, True),
# gamma: disabled — unavailable arm.
"gamma": _provider("gamma", "anthropic", "https://gamma.example",
20.0, 0.0, 0, 0, False),
# delta: available, budget_remaining 7.0 — the tie partner.
"delta": _provider("delta", "openai-compatible", "https://delta.example/v1",
7.0, 0.0, 0, 0, True),
}
def build_fixture_home():
"""Rebuild the canonical fixture home from scratch (idempotent)."""
shutil.rmtree(HOME, ignore_errors=True)
CONFIG.parent.mkdir(parents=True, exist_ok=True)
CONFIG.write_text(json.dumps(CONFIG_FIXTURE, indent=2) + "\n")
STORAGE.parent.mkdir(parents=True, exist_ok=True)
STORAGE.write_text(json.dumps(STORAGE_FIXTURE, indent=2) + "\n")
def freeze() -> list:
os.environ["HOME"] = str(HOME)
os.environ["RUNE_PROVIDER_BUDGET_CORE"] = "python" # poisoned-truth law
import rune.provider_budget as pb # noqa: E402 — after HOME pin
from freeze_truth import freeze as harness_freeze # noqa: E402
cases = [
# Case 1: loaded-state tie-break — alpha vs delta both rem 7.0,
# stable sort keeps file insertion order → best_provider "alpha".
("get_status", (), {}),
# Mutations: known+cost, known default-cost (kwargs {}), unknown no-op.
("track_usage", ("alpha", 5000, 2.5), {}),
("track_usage", ("alpha", 1000), {}),
("track_usage", ("ghost", 100), {}),
# alpha now used 5.5 → rem 4.5 < delta 7.0 → best flips to delta.
("get_status", (), {}),
# Zero-token + pure-cost usage pushes alpha over budget (15.5 >= 10).
("track_usage", ("alpha", 0, 10.0), {}),
# Exhaustion arm: alpha over, beta over, gamma disabled → best delta.
("get_status", (), {}),
# Disable the last available provider → best None (failover None arm).
("failover", ("delta",), {}),
("get_best_provider", (), {}),
# Unknown-provider failover is a no-op (no disable, no save).
("failover", ("ghost",), {}),
# All-down status: best_provider null, delta.enabled false persisted.
("get_status", (), {}),
# check_provider not-found arm (no socket, no timestamp).
("check_provider", ("ghost",), {}),
# Disabled providers still accumulate tracked usage (parity quirk).
("track_usage", ("delta", 10, 0.25), {}),
]
pb._tracker = None # fresh singleton per phase
return harness_freeze("rune.provider_budget", cases, oracle_module="rune.provider_budget")
def main() -> int:
build_fixture_home()
truth = freeze()
OUT.write_text(json.dumps(truth, indent=2, ensure_ascii=False) + "\n")
print(f"frozen {len(truth)} cases → {OUT}")
# Self-verify: rebuild the canonical home (same initial state) and run
# the shared harness gate — must report byte-identical.
build_fixture_home()
env = dict(os.environ, HOME=str(HOME), PYTHONPATH=str(REPO / "src"))
r = subprocess.run(
[sys.executable, str(REPO / "scripts" / "freeze_truth.py"),
"--verify", str(OUT), "--module", "rune.provider_budget"],
env=env,
)
return r.returncode
if __name__ == "__main__":
sys.exit(main())