Files
praxis/server/assist/budget_check.py
T
Praxis CI ec397f2c65 docs(milestone): complete v0.5-live-assist — v0.1.13 tagged, milestone release, merged to main
v0.5 (Live Assist — on-the-job voice companion) milestone complete.
4 phases: P0 (pre-execution, v0.1.10) → P1 (assist core + guardrail,
v0.1.11) → P2 (integration + tech-debt + NFR, v0.1.12) → P3 (final
review + ship, v0.1.13 = milestone release).

16/16 REQs covered (3 ASSIST + 4 NFR + 9 IDEATE). 4 v0.6 backlog.
469 tests passed, 0 failed. 1 P0 fixed (guardrail processor safety).
8 P1+ flagged for v0.6. 8 v0.4 P1+ tech-debt addressed.
G-049 + G-067 grill MUSTs resolved. ESCALATION-01 (PIPEDA) OPEN for
human legal review before assist surface go-live.

---ci---
project: praxis
phase: 3
milestone: v0.5
status: complete
requirements:
  covered: [REQ-ASSIST-01, REQ-ASSIST-02, REQ-ASSIST-03, REQ-NFR-ASSIST-01, REQ-NFR-ASSIST-02, REQ-NFR-ASSIST-03, REQ-NFR-ASSIST-04, REQ-IDEATE-01, REQ-IDEATE-02, REQ-IDEATE-03, REQ-IDEATE-04, REQ-IDEATE-05, REQ-IDEATE-06, REQ-IDEATE-07, REQ-IDEATE-08, REQ-IDEATE-09]
  partial: []
---/ci---
2026-08-04 22:35:56 +00:00

77 lines
3.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""C-3 budget check for assist cost (TASK-11-02, REQ-IDEATE-07, C-3, D-012).
Estimates the monthly assist cost per learner + compares against the C-3
target (≤ $3/active learner/month — relaxed for the Canada pilot per D-012,
but the architecture must not preclude it).
This is a DIAGNOSTIC check (not enforced — D-012 says no enforced ceiling in
the pilot). It's logged at shift-end + reported in the P2 verification. The
operator can review the log to understand the cost impact of assist usage.
R-ASSIST-14 mitigation: the budget check helps the operator understand the
cost impact of assist usage. If the total (practice + assist) exceeds $3, the
`flag` is True (diagnostic — the pilot continues, but the operator is alerted).
Example (from the plan):
20 turns/shift × 20 shifts/month = 400 extra LLM calls. At ~$0.0005/turn
(gemma4:cloud pilot rates), that's ~$0.20/month — well under $3. But if the
turns are longer or the model is more expensive, the cost could approach
the ceiling.
"""
from __future__ import annotations
from typing import Any
# C-3 target: ≤ $3/active learner/month (relaxed for pilot per D-012, but the
# architecture must not preclude it).
C3_TARGET_USD = 3.0
def check_c3_budget(
assist_turns_per_shift: int,
shifts_per_month: int,
cost_per_turn_cents: float,
practice_cost_per_month_usd: float = 0.0,
) -> dict[str, Any]:
"""Estimate the monthly assist cost + compare against the C-3 target.
Args:
assist_turns_per_shift: average assist turns per shift.
shifts_per_month: number of assist shifts per month.
cost_per_turn_cents: average cost per assist turn (cents) — from
derive_assist_turn_cost().derived_cents.
practice_cost_per_month_usd: the existing practice cost/month (USD) —
added to the assist cost to get the total. Default 0 (assist-only).
Returns:
{
monthly_assist_cost: float (USD),
practice_cost_per_month: float (USD),
total_with_practice: float (USD),
c3_target: 3.0,
within_budget: bool, # total <= c3_target
flag: bool, # total > c3_target (diagnostic — not enforced)
turns_per_month: int,
}
D-012: the check is diagnostic (not enforced). `flag=True` means the
total exceeds $3 — the operator is alerted, but the pilot continues.
"""
turns_per_month = assist_turns_per_shift * shifts_per_month
# cost_per_turn_cents is in CENTS → divide by 100 for USD.
monthly_assist_cost_usd = (turns_per_month * float(cost_per_turn_cents)) / 100.0
total_with_practice = monthly_assist_cost_usd + float(practice_cost_per_month_usd)
within_budget = total_with_practice <= C3_TARGET_USD
return {
"monthly_assist_cost": round(monthly_assist_cost_usd, 4),
"practice_cost_per_month": round(float(practice_cost_per_month_usd), 4),
"total_with_practice": round(total_with_practice, 4),
"c3_target": C3_TARGET_USD,
"within_budget": within_budget,
"flag": not within_budget, # flag=True if over budget (diagnostic)
"turns_per_month": turns_per_month,
}
__all__ = ["check_c3_budget", "C3_TARGET_USD"]