Skip to content

symfonic.capabilities.governance.stages.budget

budget

Budgets: the second fail-closed stage, and the only one that trims.

Two rules, both inherited rather than invented:

  • Pinned content is never trimmed (T3.2.1). When the pinned portion alone exceeds the ceiling the stage refuses: a payload missing its boundaries is worse than a payload that refused to build.
  • A spend that cannot be measured cannot be bounded (T3.1.3's offload precedent). The meter raising is a stage failure, and the declared fail-closed mode refuses the turn rather than waving the payload through.

Metering is offline by construction — TokenMeter is a bound port, and no path here downloads a tokenizer.

BudgetLimits dataclass

BudgetLimits(draft_tokens: int | None = None)

None measures without capping; a number caps.

Zero is refused rather than read as "unlimited": a deployment that typed 0 meant "nothing", and silently reading that as "everything" is the most expensive possible misreading.

BudgetStage

BudgetStage(meter: TokenMeter, limits: BudgetLimits | None = None)

Measure the payload, trim what may be trimmed, refuse what may not.

Source code in src/symfonic/capabilities/governance/stages/budget.py
def __init__(self, meter: TokenMeter, limits: BudgetLimits | None = None) -> None:
    self._meter = meter
    self._limits = limits or BudgetLimits()