Skip to content

A spending cap is the run's alone: one unit can spend all of it #47

Description

@aitianshi

Priority

extreme

Components

  • app/nullius (backend)
  • app/web (routes)
  • templates and static files
  • docs and the site
  • catalogue (benchmarks, agents, capabilities)
  • the standard (ports, kits, relay, runs)
  • CI, workflows and skills

Today

A spending cap is the run's (--max-usd, #14), or from the builder the run's shared by its jobs (#45). Nothing limits what one unit spends: an agent that loops takes the money the other units were to have, and the run stops for all of them.

Wanted

A cap per unit beside the run's, for instance --max-usd-per-unit 0.50. A unit that reaches its own cap is cut off there, and the run goes on with the next unit.

To decide first: how such a unit counts. A unit the run's cap cut off had no attempt, so it is the outcome Spending cap, outside the adjusted rate. A unit that spent its own allowance did have its attempt, as one that spends its time does (AgentTimeoutError, an agent error counted against the agent). The two should not share an outcome without that being chosen.

Acceptance

  • A run can be given a cap per unit: no call of a unit goes out once that unit's spend plus its calls in flight would pass it, and the other units go on.
  • A unit cut off by its own cap is recorded apart from one the run's cap cut off, and the field guide says which rate it counts in.
  • The docs say whether the judge's and the simulated user's calls for a unit count toward its cap.

Dependencies and related

Follows #14 (the run's cap) and #45 (the cap in the builder and on the job page), which leave it out.

Activity

  1. self-assigned this
    on Nov 10, 2026
  2. aitianshi commented on Nov 11, 2026

    @aitianshi
    CollaboratorAuthor

    Implemented in #49, stacked on #48, as decided here: a unit's own calls and its simulated user's count toward its cap, its judge's do not, and a unit that reaches its cap is an Agent error counted against the agent.

    #49 targets #48's branch, so this issue's Development panel will show it once it targets main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions