Repository navigation
Conversation
…page A cap existed only on the command line. The builder's Limits step now takes one amount for the whole run of a Nullius recipe: its jobs that call a model (each dataset with each participant, on each machine) take equal shares, rounded down, so the amount typed is the most the run spends, here or on a host. A control that calls no model takes no share and is offered no cap, and a model without a price is named at Limits before Run. The job page says the cap in its run totals; a run the cap stopped says so, with what was spent, and lists the units never begun. The live board is told the cap as the units start and says what was spent of it. Merging a launch's shards adds their caps and spending into one budget, when every shard had one.
A job now carries its budget. A workspace's cache written by the earlier parse holds jobs without it, read back as current while the parse's schema stands: the schema moves to 14.
This comment has been minimized.
This comment has been minimized.
This was referenced Nov 10, 2026
The job page and the live board formatted a cap as they format a cost: a cap of 0.395 USD read $0.40, an amount the run never had. Both now show cents and up to two digits more when the cap has them, as Review and the run's own messages do.
This comment has been minimized.
This comment has been minimized.
# Conflicts: # docs/cli/run.md
This comment has been minimized.
This comment has been minimized.
This was referenced Nov 11, 2026
🔴 PR judge · 5 of 8 yes · #48 ↔ #45
Acceptance criteria, 4 of 4 met
Checks the script runs itself, 4 of 4 pass
some of the diff was cut before the judge read it |
Collaborator
Author
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #45
What
The builder's Limits step takes a spending cap in USD for the whole run of a Nullius recipe. Its jobs that call a model (each dataset with each participant, on each machine) take equal shares of it, rounded down, as
--max-usdon each job's command: the amount typed is the most the run spends, on this machine or on a host. A control that calls no model takes no share and is offered no cap. A Harbor recipe is not offered one: its calls do not pass the relay. A model without a price in the user's list is named at Limits before Run, since a capped run is refused without one.The job page says the cap in its run totals. A run the cap stopped says so in a neutral notice, with what was spent, and lists the units never begun; the units cut off are its Spending cap trials. The live board is told the cap at
job.startand says what was spent of it. Both show the cap as it was given ($0.395), not rounded to the cent as a cost is.mergeadds the caps and spending of a launch's shards into onebudget, when every shard had a cap. A job now carriesbudget, so the parse's cache schema moves to 14 and cached jobs are read again.Two things differ from the issue as first written, and the issue is updated. The cap is one amount shared by the run's jobs, where the issue gave each job the whole cap: one number then holds for the whole run. A cap per unit is left to #47, because it changes how a unit counts and that is to be decided first.
Stacked on #46.
Touches
backend · routes · templates and static · docs and site · the standard
Before and after
Taken at 1400 px in the dark theme; the images are not attached here.
Verified
test_standard_recipe.py,SpendingCap: one job takes the whole cap and no cap adds nothing; two agents on two machines take a quarter each; three shards of 1 USD take 0.333333 each, never more than the cap in all; a control that calls no model takes no share; an amount that is no amount, or too small to share, names the Limits step; a missing price is said at Limits, and only a recipe with a cap asks.test_standard_shard.py: the merged job carries the shards' caps as one, and none when a shard had no cap; a recorded cap is read leniently, an amount missing is not zero.test_standard_run.py: the live feed carries the cap atjob.startand the cut-off unit ends there asbudget.app/ui_tests/test_capped_job.py: the job page of a stopped run (notice, cap row, the units not run, the Spending cap outcome), of a run within its cap, and of one without; the builder keeps a saved recipe's cap and a Harbor recipe takes none.docs-driftscript: 0 findings.mergegave one job withbudget0.06, 0.007686 spent, stopped, 2 cut off and 16 not run, and its page says so. Billed for both: 0.0076864.Risk
Undone by a revert: a recipe saved with
max_usdthen reads as one without a cap, and a job'sbudgetstays in itsresult.json, unread.