feat(seatpool): the seat pool and the board several drivers share
The seats of .env and the ledger, the probe, placement, settling a
finished pass, the child's credentials, the OpenRouter seats, and the
board every driver on the machine shares, in one shape and under one
lock. A driver is alive while its lifetime lock is held; with no lock file
natively its pid and start time decide, and in the sandbox it is taken for
alive.
:Http is the HTTP the driver needs, on FetchHTTP1: a status outside 2xx is
HttpError, every other failure carries a fixed text. :Platform gains
MakeDirs, with the last directory's own mode, and errno texts for its
writes and locks.
The tests cover the seat pool and several drivers at once, less the checks
that drive the pool's Scheduler, Admission and Stacks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 08:15:03 +01:00
// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
// The seat pool: seats from .env, placement, settling, credentials, the
// ledger; the checks that drive the Scheduler and the Runner are in the
// Scheduler test. Then reference vectors for the retry-after scan, the cycle
// start, the knobs, the OpenRouter cost and the description.
# include <stdlib.h>
# include <time.h>
import std ;
import Crafter . Review ;
namespace fs = std : : filesystem ;
using namespace Crafter : : Review ;
namespace {
std : : int32_t Failures = 0 ;
void Check ( std : : string_view name , bool cond , std : : string_view detail = { } ) {
std : : println ( " {}{}{} " , cond ? " ok " : " FAIL " , name , ! cond & & ! detail . empty ( ) ? std : : format ( " ({}) " , detail ) : std : : string ( ) ) ;
if ( ! cond ) + + Failures ;
}
Json With ( Json value , const Json & changes ) {
for ( auto it = changes . begin ( ) ; it ! = changes . end ( ) ; + + it ) value [ it . key ( ) ] = it . value ( ) ;
return value ;
}
void Write ( const fs : : path & path , std : : string_view text ) {
fs : : create_directories ( path . parent_path ( ) ) ;
std : : ofstream ( path , std : : ios : : binary ) < < text ;
}
std : : string Ids ( const std : : vector < Json > & seats ) {
std : : vector < std : : string > ids ;
for ( const Json & s : seats ) ids . push_back ( s . at ( " id " ) . get < std : : string > ( ) ) ;
return Dyn : : Join ( ids , " , " ) ;
}
}
int main ( ) {
std : : println ( " seat pool: seats from .env, placement, settling, credentials, the ledger, re-placement " ) ;
// The dates below are UTC's; the process zone decides what a timestamp's
// date is, as it does for dt.date.fromtimestamp.
setenv ( " TZ " , " UTC " , 1 ) ;
tzset ( ) ;
Platform : : SetMode ( Platform : : Mode : : Native ) ;
const fs : : path td = fs : : temp_directory_path ( ) / std : : format ( " crafter-review-seatpool-{} " , Platform : : PublishedPid ( ) ) ;
fs : : remove_all ( td ) ;
fs : : create_directories ( td ) ;
setenv ( " REVIEW_GATES_BOARD " , ( td / " seat-board.json " ) . c_str ( ) , 1 ) ;
const fs : : path envFile = td / " .env " ;
Write ( envFile , " CLAUDE_CODE_OAUTH_TOKEN1= \" tok-one \" \n CLAUDE_CODE_OAUTH_TOKEN2=tok-two \n ANTHROPIC_API_KEY1=sk-ant-api-one \n ANTHROPIC_API_KEY=sk-ant-bare-never-a-seat \n MAILOSAUR=x \n " ) ;
const Json acfg = SeatPool : : ApiConfig ( { { " REVIEW_GATES_API_BUDGET_USD " , " 10 " } , { " REVIEW_GATES_API_LENS_COST_USD " , " 1 " } , { " REVIEW_GATES_API_CONCURRENCY " , " 2 " } } ) ;
const Json cfg = Seats : : ConfigFromEnv ( { } ) ;
SeatPool : : Ledger ledger ( td / " ledger.json " , acfg ) ;
feat(seats): the env file's settings count, and a machine's own seats file
ApiConfig and PoolConfig read the seat order, the budgets and the
concurrency from the process environment alone, so a `.env` that said
REVIEW_GATES_SEAT_ORDER=oauth-first ordered nothing: the Python driver
reads those lines from the file under the process environment
(config_env, 2026-10-17: a setting lives beside the seats it orders).
SeatPool::SettingsOf does the same - the file's placement settings
under the process environment, in a map handed to the placement readers
alone (ApiConfig, PoolConfig, Seats::ConfigFromEnv) - and leaves the
process environment untouched, so no other reader sees a line of the
file: a path's or a binary's line reaches nothing, and two drivers
reading one .env keep one board and one ledger. The placement settings
are one list, SeatPool::PlacementSettings - the fifteen names those
readers read - for the map, the run's log and what makes a working
directory's .env a seats file; a REVIEW_GATES_* line of any other name
stays out of the map and is named, by the run's log and on `seats`'s
stderr. One dotenv grammar serves the tokens and the settings
(Seats::DotenvLines).
`run` and `seats` resolve the file from their own --env-file
(SeatPool::ResolveSeatsFile): the --env-file, else $SEATS_ENV_FILE, else
the working directory's .env - the operator's, as the Python driver and
`seats` read it, not the repository under review's - when it is a file
holding a seat or a placement setting, each with a value, or one that
cannot be read as UTF-8 text (its error is then the command's) - a
readable application .env, its Vite or Supabase lines, one of blank
placeholder lines or one that is no file is passed over, and the run
says so - else the machine's own
$XDG_CONFIG_HOME/crafter-review/env, else ~/.config/crafter-review/env:
one file for every repository on a machine, a repository's seats .env
winning over it. Each file is read once and the settings and the tokens
are taken from that read (SeatsFile::Text), so a file that can be read
only once - a pipe, `--env-file <(gpg -d seats.env.gpg)`, a FIFO - gives
its settings and its seats alike, and a failed read raises its own error
where the tokens are laid over the environment: SeatPool::WithFileTokens,
for `run` and `seats` alike, and LoadSeats takes the merged environment
and no longer reads a file by path. An empty `seats --env-file` means no file
now, as it did for `run`, and the `seats` report names the side that
runs first (it said "api seats run first" whatever the order).
Runs, Commands and KernelModes, the tests that run `run` and `seats`,
point XDG_CONFIG_HOME, and HOST_XDG_CONFIG_HOME for the Flatpak, at a
path of their own that nothing creates, so a global file stays out of
them; the grammar, the settings and their precedence, the lookup and the
one read have their tests, a run with `--env` (a prefix) and with a
repeated --env-file, and a `seats` with `--env`, take tokens and
settings from the one file, an application's .env and a venv are passed
over, a FIFO is read once, no line of the file reaches `stop`, every
listed placement setting moves a reader, another REVIEW_GATES_* line is
named and a .env of blank lines passed over, and the
README, the environment table and the procedure say the new rule.
2026-11-01 01:51:48 +01:00
std : : vector < Json > seats = SeatPool : : LoadSeats ( SeatPool : : WithFileTokens ( { } , SeatPool : : ResolveSeatsFile ( envFile . string ( ) , td ) ) , " " , & ledger , acfg ) ;
feat(seatpool): the seat pool and the board several drivers share
The seats of .env and the ledger, the probe, placement, settling a
finished pass, the child's credentials, the OpenRouter seats, and the
board every driver on the machine shares, in one shape and under one
lock. A driver is alive while its lifetime lock is held; with no lock file
natively its pid and start time decide, and in the sandbox it is taken for
alive.
:Http is the HTTP the driver needs, on FetchHTTP1: a status outside 2xx is
HttpError, every other failure carries a fixed text. :Platform gains
MakeDirs, with the last directory's own mode, and errno texts for its
writes and locks.
The tests cover the seat pool and several drivers at once, less the checks
that drive the pool's Scheduler, Admission and Stacks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 08:15:03 +01:00
Check ( " .env: api seats, oauth seats, never the bare ANTHROPIC_API_KEY, local only when nothing is configured " ,
feat(seats): the env file's settings count, and a machine's own seats file
ApiConfig and PoolConfig read the seat order, the budgets and the
concurrency from the process environment alone, so a `.env` that said
REVIEW_GATES_SEAT_ORDER=oauth-first ordered nothing: the Python driver
reads those lines from the file under the process environment
(config_env, 2026-10-17: a setting lives beside the seats it orders).
SeatPool::SettingsOf does the same - the file's placement settings
under the process environment, in a map handed to the placement readers
alone (ApiConfig, PoolConfig, Seats::ConfigFromEnv) - and leaves the
process environment untouched, so no other reader sees a line of the
file: a path's or a binary's line reaches nothing, and two drivers
reading one .env keep one board and one ledger. The placement settings
are one list, SeatPool::PlacementSettings - the fifteen names those
readers read - for the map, the run's log and what makes a working
directory's .env a seats file; a REVIEW_GATES_* line of any other name
stays out of the map and is named, by the run's log and on `seats`'s
stderr. One dotenv grammar serves the tokens and the settings
(Seats::DotenvLines).
`run` and `seats` resolve the file from their own --env-file
(SeatPool::ResolveSeatsFile): the --env-file, else $SEATS_ENV_FILE, else
the working directory's .env - the operator's, as the Python driver and
`seats` read it, not the repository under review's - when it is a file
holding a seat or a placement setting, each with a value, or one that
cannot be read as UTF-8 text (its error is then the command's) - a
readable application .env, its Vite or Supabase lines, one of blank
placeholder lines or one that is no file is passed over, and the run
says so - else the machine's own
$XDG_CONFIG_HOME/crafter-review/env, else ~/.config/crafter-review/env:
one file for every repository on a machine, a repository's seats .env
winning over it. Each file is read once and the settings and the tokens
are taken from that read (SeatsFile::Text), so a file that can be read
only once - a pipe, `--env-file <(gpg -d seats.env.gpg)`, a FIFO - gives
its settings and its seats alike, and a failed read raises its own error
where the tokens are laid over the environment: SeatPool::WithFileTokens,
for `run` and `seats` alike, and LoadSeats takes the merged environment
and no longer reads a file by path. An empty `seats --env-file` means no file
now, as it did for `run`, and the `seats` report names the side that
runs first (it said "api seats run first" whatever the order).
Runs, Commands and KernelModes, the tests that run `run` and `seats`,
point XDG_CONFIG_HOME, and HOST_XDG_CONFIG_HOME for the Flatpak, at a
path of their own that nothing creates, so a global file stays out of
them; the grammar, the settings and their precedence, the lookup and the
one read have their tests, a run with `--env` (a prefix) and with a
repeated --env-file, and a `seats` with `--env`, take tokens and
settings from the one file, an application's .env and a venv are passed
over, a FIFO is read once, no line of the file reaches `stop`, every
listed placement setting moves a reader, another REVIEW_GATES_* line is
named and a .env of blank lines passed over, and the
README, the environment table and the procedure say the new rule.
2026-11-01 01:51:48 +01:00
Ids ( seats ) = = " api1,1,2 " & & Ids ( SeatPool : : LoadSeats ( { } , " " ) ) = = " local " , Ids ( seats ) ) ;
feat(seatpool): the seat pool and the board several drivers share
The seats of .env and the ledger, the probe, placement, settling a
finished pass, the child's credentials, the OpenRouter seats, and the
board every driver on the machine shares, in one shape and under one
lock. A driver is alive while its lifetime lock is held; with no lock file
natively its pid and start time decide, and in the sandbox it is taken for
alive.
:Http is the HTTP the driver needs, on FetchHTTP1: a status outside 2xx is
HttpError, every other failure carries a fixed text. :Platform gains
MakeDirs, with the last directory's own mode, and errno texts for its
writes and locks.
The tests cover the seat pool and several drivers at once, less the checks
that drive the pool's Scheduler, Admission and Stacks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 08:15:03 +01:00
const std : : string summary = DumpSpaced ( SeatPool : : Summary ( seats ) ) ;
Check ( " no secret in the summary or the table " , ! ( summary + SeatPool : : Table ( seats ) ) . contains ( " tok-one " ) & & ! summary . contains ( " sk-ant " ) ) ;
2026-10-31 21:13:55 +01:00
Check ( " the 5-hour share of a pass follows the run's effort (0.125 at xhigh, 0.5 at max and any other); the env overrides every effort " ,
Dyn : : Equal ( SeatPool : : PoolConfig ( { } ) . at ( " lensCostPct " ) , 0.5 ) & & Dyn : : Equal ( SeatPool : : PoolConfig ( { } , " max " ) . at ( " lensCostPct " ) , 0.5 )
& & Dyn : : Equal ( SeatPool : : PoolConfig ( { } , " xhigh " ) . at ( " lensCostPct " ) , 0.125 ) & & Dyn : : Equal ( SeatPool : : PoolConfig ( { { " REVIEW_GATES_LENS_COST_PCT " , " 5 " } } , " xhigh " ) . at ( " lensCostPct " ) , 5 ) ) ;
feat(seatpool): the seat pool and the board several drivers share
The seats of .env and the ledger, the probe, placement, settling a
finished pass, the child's credentials, the OpenRouter seats, and the
board every driver on the machine shares, in one shape and under one
lock. A driver is alive while its lifetime lock is held; with no lock file
natively its pid and start time decide, and in the sandbox it is taken for
alive.
:Http is the HTTP the driver needs, on FetchHTTP1: a status outside 2xx is
HttpError, every other failure carries a fixed text. :Platform gains
MakeDirs, with the last directory's own mode, and errno texts for its
writes and locks.
The tests cover the seat pool and several drivers at once, less the checks
that drive the pool's Scheduler, Admission and Stacks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 08:15:03 +01:00
const double now = std : : floor ( Platform : : Now ( ) ) ;
Json & api1 = seats [ 0 ] ;
Json & s1 = seats [ 1 ] ;
Json & s2 = seats [ 2 ] ;
api1 [ " state " ] = " ok " ;
s1 = With ( s1 , { { " state " , " ok " } , { " util " , 60 } , { " windows " , { { " five_hour " , { { " utilization " , 60 } , { " resetsAt " , now + 600 } } } , { " seven_day " , { { " utilization " , 10 } , { " resetsAt " , now + 86400 } } } } } } ) ;
s2 = With ( s2 , { { " state " , " ok " } , { " util " , 50 } , { " windows " , { { " five_hour " , { { " utilization " , 20 } , { " resetsAt " , now + 900 } } } , { " seven_day " , { { " utilization " , 50 } , { " resetsAt " , now + 86400 } } } } } } ) ;
auto pick = [ & ] ( const Json & apiConfig ) {
const Json * picked = SeatPool : : Pick ( seats , now , cfg , apiConfig ) ;
return picked ? picked - > at ( " id " ) . get < std : : string > ( ) : std : : string ( " None " ) ;
} ;
const std : : string first = pick ( acfg ) ;
api1 [ " running " ] = 2 ;
Check ( " api seat first; at its cap the oauth seat with the most 5-hour headroom " , first = = " api1 " & & pick ( acfg ) = = " 2 " ) ;
api1 [ " running " ] = 0 ;
api1 [ " spentUsd " ] = 9.5 ;
Check ( " api seat without budget room: skipped; oauth-first order " , pick ( acfg ) = = " 2 " & & pick ( With ( acfg , { { " order " , " oauth-first " } , { " budgetUsd " , 100 } } ) ) = = " 2 " ) ;
std : : vector < std : : string > logs ;
auto log = [ & ] ( const std : : string & line ) { logs . push_back ( line ) ; } ;
s1 = With ( s1 , { { " state " , " ok " } , { " util " , 20 } , { " running " , 1 } , { " windows " , { { " five_hour " , { { " utilization " , 20 } , { " resetsAt " , now + 600 } } } } } } ) ;
Json limit = { { " status " , " limit " } , { " reason " , " rate limit " } , { " rateType " , " five_hour " } , { " rateLimit " , { { " five_hour " , { { " utilization " , 100 } , { " resetsAt " , now + 600 } } } } } } ;
bool requeued = SeatPool : : Settle ( s1 , limit , now , cfg , acfg , & ledger , log ) ;
Check ( " 5h limit on an oauth seat: limited, paused until its reset + 30 s, requeued " ,
requeued & & s1 . at ( " state " ) = = " limited " & & s1 . at ( " pauseUntil " ) . get < double > ( ) = = now + 630 & & ! SeatPool : : Eligible ( s1 , now , cfg , acfg ) ) ;
Json spend = { { " status " , " ok " } , { " costUsd " , 2.5 } , { " rateLimit " , Json : : object ( ) } } ;
requeued = SeatPool : : Settle ( api1 , spend , now , cfg , acfg , & ledger , log ) ;
Check ( " api seat: spend accrues in the seat and the ledger, and the budget takes the seat out " ,
! requeued & & api1 . at ( " spentUsd " ) . get < double > ( ) = = 12.0 & & ledger . Entry ( " api1 " ) . at ( " spentUsd " ) . get < double > ( ) = = 2.5 & & api1 . at ( " state " ) = = " out " ) ;
Json api2 = SeatPool : : NewSeat ( " api2 " , " api " , " k " ) ;
api2 [ " state " ] = " ok " ;
Json credits = { { " status " , " credits " } , { " reason " , " Your credit balance is too low " } , { " costUsd " , 0 } , { " rateLimit " , Json : : object ( ) } } ;
requeued = SeatPool : : Settle ( api2 , credits , now , cfg , acfg , & ledger , log ) ;
Check ( " credit error: out, recorded in the ledger, requeued " , requeued & & api2 . at ( " state " ) = = " out " & & Dyn : : Truthy ( ledger . Entry ( " api2 " ) . at ( " outSince " ) ) ) ;
feat(seats): accounts without a 5-hour limit
Anthropic is removing the 5-hour limit in stages (from 2026-10-31), and
an account without it reports the weekly window alone. Until now the pool
took such an account for an unprobed seat: always eligible, ranked after
every other, never held to the weekly cutoff, with no cap on its passes.
- The burst window is the 5-hour one, else the weekly one
(Seats::BurstWindow). An account whose burst window is the weekly one is
ranked by it and admitted under the 95 % cutoff with the passes in
flight projected on it, at the measured share per pass (0.04 at xhigh,
0.125 otherwise; REVIEW_GATES_LENS_COST_7D_PCT), and waits for the weekly
reset when over it.
- Every OAuth account and the local login takes at most 128 passes at once,
every driver's counted (REVIEW_GATES_OAUTH_CONCURRENCY): every run
measured with 149 or more in flight on one account drew usage-limit
rejections, none of the 119 with 139 or fewer.
- A 'concurrents' rejection pauses the seat for 20 s or its retry-after,
not until a window's reset (a seat sat two hours at 10 % on one).
- Board entries, the folded foreign record and the board's view carry
cost7d, so the drivers see each other's weekly load.
- `seats` and the log table say `no limit` in such an account's 5-hour
column; the board's others-line names its weekly projection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 17:07:17 +01:00
// 2026-10-31: a 'concurrents' rejection (too many requests at once on the
// account) is a short back-off, not the window's reset.
Json sc = With ( SeatPool : : NewSeat ( " c " , " oauth " , " t " ) , { { " state " , " ok " } , { " util " , 10 } , { " running " , 1 } , { " pauseUntil " , 0 } , { " windows " , { { " five_hour " , { { " utilization " , 10 } , { " resetsAt " , now + 7000 } } } } } } ) ;
Json concurrents = { { " status " , " limit " } , { " reason " , " You've hit your usage limit " } , { " rateType " , " concurrents " } , { " rateLimit " , { { " five_hour " , { { " utilization " , 10 } , { " resetsAt " , now + 7000 } } } } } } ;
requeued = SeatPool : : Settle ( sc , concurrents , now , cfg , acfg , & ledger , log ) ;
Check ( " a 'concurrents' rejection on an oauth seat: requeued, paused for seconds, not until the 5h reset " ,
requeued & & sc . at ( " state " ) = = " limited " & & sc . at ( " pauseUntil " ) . get < double > ( ) = = now + SeatPool : : ConcurrentBackoffS & & ! SeatPool : : Eligible ( sc , now , cfg , acfg ) ) ;
Json backOk = { { " status " , " ok " } , { " rateLimit " , { { " five_hour " , { { " utilization " , 11 } , { " resetsAt " , now + 7000 } } } } } } ;
requeued = SeatPool : : Settle ( sc , backOk , now + SeatPool : : ConcurrentBackoffS + 1 , cfg , acfg , & ledger , log ) ;
Check ( " ...and the seat is back after the back-off " , ! requeued & & sc . at ( " state " ) = = " ok " & & SeatPool : : Eligible ( sc , now + SeatPool : : ConcurrentBackoffS + 1 , cfg , acfg ) ) ;
// 2026-10-31: an account whose 5-hour limit is removed reports the weekly
// window alone; until then the pool took it for an unprobed seat - ranked
2026-10-31 21:13:55 +01:00
// after every other, never held to the weekly cutoff. The cutoff is 99 %.
feat(seats): accounts without a 5-hour limit
Anthropic is removing the 5-hour limit in stages (from 2026-10-31), and
an account without it reports the weekly window alone. Until now the pool
took such an account for an unprobed seat: always eligible, ranked after
every other, never held to the weekly cutoff, with no cap on its passes.
- The burst window is the 5-hour one, else the weekly one
(Seats::BurstWindow). An account whose burst window is the weekly one is
ranked by it and admitted under the 95 % cutoff with the passes in
flight projected on it, at the measured share per pass (0.04 at xhigh,
0.125 otherwise; REVIEW_GATES_LENS_COST_7D_PCT), and waits for the weekly
reset when over it.
- Every OAuth account and the local login takes at most 128 passes at once,
every driver's counted (REVIEW_GATES_OAUTH_CONCURRENCY): every run
measured with 149 or more in flight on one account drew usage-limit
rejections, none of the 119 with 139 or fewer.
- A 'concurrents' rejection pauses the seat for 20 s or its retry-after,
not until a window's reset (a seat sat two hours at 10 % on one).
- Board entries, the folded foreign record and the board's view carry
cost7d, so the drivers see each other's weekly load.
- `seats` and the log table say `no limit` in such an account's 5-hour
column; the board's others-line names its weekly projection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 17:07:17 +01:00
const Json px = SeatPool : : PoolConfig ( { } , " xhigh " ) ;
Json nf = With ( SeatPool : : NewSeat ( " n " , " oauth " , " tn " ) , { { " state " , " ok " } , { " running " , 0 } , { " pauseUntil " , 0 } , { " windows " , { { " seven_day " , { { " utilization " , 3 } , { " resetsAt " , now + 6 * 86400 } } } } } } ) ;
Json f15 = With ( SeatPool : : NewSeat ( " f " , " oauth " , " tf " ) , { { " state " , " ok " } , { " running " , 0 } , { " pauseUntil " , 0 } ,
{ " windows " , { { " five_hour " , { { " utilization " , 15 } , { " resetsAt " , now + 3600 } } } , { " seven_day " , { { " utilization " , 11 } , { " resetsAt " , now + 86400 } } } } } } ) ;
std : : vector < Json > pair = { f15 , nf } ;
std : : vector < std : : string > order ;
for ( const Json * s : SeatPool : : Ranked ( pair , now , px , acfg ) ) order . push_back ( s - > at ( " id " ) . get < std : : string > ( ) ) ;
Check ( " an account without a 5-hour window is placed by its weekly one: ranked by it, ahead of a seat at 5h 15 %, its running passes projected at the weekly figure " ,
order = = std : : vector < std : : string > { " n " , " f " } & & std : : abs ( SeatPool : : OauthProjected ( With ( nf , { { " running " , 100 } } ) , px ) - 7.0 ) < 1e-9 , Dyn : : Join ( order , " , " ) ) ;
2026-10-31 21:13:55 +01:00
Json n97 = With ( nf , { { " windows " , { { " seven_day " , { { " utilization " , 97 } , { " resetsAt " , now + 86400 } } } } } } ) ;
Json n97r40 = With ( n97 , { { " running " , 40 } } ) ;
Json n97r60 = With ( n97 , { { " running " , 60 } } ) ;
Check ( " ...under the weekly cutoff alone, no 5-hour ceiling: at 97 % it takes a pass with 40 running, not with 60 (97 + 61 x 0.04 >= 99) " ,
SeatPool : : Eligible ( n97r40 , now , px , acfg ) & & ! SeatPool : : Eligible ( n97r60 , now , px , acfg ) ) ;
Json n99 = With ( nf , { { " windows " , { { " seven_day " , { { " utilization " , 99 } , { " resetsAt " , now + 86400 } } } } } } ) ;
Check ( " ...and over the cutoff it waits for its weekly reset + 30 s " , ! SeatPool : : Eligible ( n99 , now , px , acfg ) & & SeatPool : : EarliestResume ( { n99 } , now ) = = now + 86430 ) ;
feat(seats): accounts without a 5-hour limit
Anthropic is removing the 5-hour limit in stages (from 2026-10-31), and
an account without it reports the weekly window alone. Until now the pool
took such an account for an unprobed seat: always eligible, ranked after
every other, never held to the weekly cutoff, with no cap on its passes.
- The burst window is the 5-hour one, else the weekly one
(Seats::BurstWindow). An account whose burst window is the weekly one is
ranked by it and admitted under the 95 % cutoff with the passes in
flight projected on it, at the measured share per pass (0.04 at xhigh,
0.125 otherwise; REVIEW_GATES_LENS_COST_7D_PCT), and waits for the weekly
reset when over it.
- Every OAuth account and the local login takes at most 128 passes at once,
every driver's counted (REVIEW_GATES_OAUTH_CONCURRENCY): every run
measured with 149 or more in flight on one account drew usage-limit
rejections, none of the 119 with 139 or fewer.
- A 'concurrents' rejection pauses the seat for 20 s or its retry-after,
not until a window's reset (a seat sat two hours at 10 % on one).
- Board entries, the folded foreign record and the board's view carry
cost7d, so the drivers see each other's weekly load.
- `seats` and the log table say `no limit` in such an account's 5-hour
column; the board's others-line names its weekly projection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 17:07:17 +01:00
Json n127 = With ( nf , { { " running " , 127 } } ) ;
Json n128 = With ( nf , { { " running " , 128 } } ) ;
Json nShared = With ( nf , { { " running " , 100 } , { " foreign " , { { " count " , 28 } , { " cost5h " , 0.0 } , { " cost7d " , 0.0 } , { " costUsd " , 0.0 } } } } ) ;
Json f127 = With ( f15 , { { " running " , 127 } } ) ;
Json f128 = With ( f15 , { { " running " , 128 } } ) ;
Check ( " 128 passes per OAuth account, every driver counted, whatever its windows; REVIEW_GATES_OAUTH_CONCURRENCY overrides " ,
SeatPool : : Eligible ( n127 , now , px , acfg ) & & ! SeatPool : : Eligible ( n128 , now , px , acfg ) & & ! SeatPool : : Eligible ( nShared , now , px , acfg ) & & SeatPool : : Eligible ( f127 , now , px , acfg )
& & ! SeatPool : : Eligible ( f128 , now , px , acfg ) & & px . at ( " oauthConcurrency " ) = = 128 & & SeatPool : : PoolConfig ( { { " REVIEW_GATES_OAUTH_CONCURRENCY " , " 64 " } } , " xhigh " ) . at ( " oauthConcurrency " ) = = 64 ) ;
Json weekly = { { " status " , " ok " } , { " rateLimit " , { { " seven_day " , { { " utilization " , 4 } , { " resetsAt " , now + 6 * 86400 } } } } } } ;
requeued = SeatPool : : Settle ( nf , weekly , now , px , acfg , & ledger , log ) ;
Check ( " ...a finished pass's reading keeps it a weekly seat, unpaused; the log table says `no limit` in its 5h column " ,
! requeued & & Seats : : BurstWindow ( nf . at ( " windows " ) ) = = " seven_day " & & nf . at ( " pauseUntil " ) = = 0 & & SeatPool : : Table ( { nf } ) . contains ( " | no limit | " ) , SeatPool : : Table ( { nf } ) ) ;
Check ( " the weekly share of a pass follows the run's effort (0.04 at xhigh, 0.125 otherwise); the env overrides it " ,
Dyn : : Equal ( px . at ( " lensCost7dPct " ) , 0.04 ) & & Dyn : : Equal ( SeatPool : : PoolConfig ( { } ) . at ( " lensCost7dPct " ) , 0.125 ) & & Dyn : : Equal ( SeatPool : : PoolConfig ( { } , " max " ) . at ( " lensCost7dPct " ) , 0.125 )
& & Dyn : : Equal ( SeatPool : : PoolConfig ( { { " REVIEW_GATES_LENS_COST_7D_PCT " , " 0.5 " } } , " xhigh " ) . at ( " lensCost7dPct " ) , 0.5 ) ) ;
feat(seatpool): the seat pool and the board several drivers share
The seats of .env and the ledger, the probe, placement, settling a
finished pass, the child's credentials, the OpenRouter seats, and the
board every driver on the machine shares, in one shape and under one
lock. A driver is alive while its lifetime lock is held; with no lock file
natively its pid and start time decide, and in the sandbox it is taken for
alive.
:Http is the HTTP the driver needs, on FetchHTTP1: a status outside 2xx is
HttpError, every other failure carries a fixed text. :Platform gains
MakeDirs, with the last directory's own mode, and errno texts for its
writes and locks.
The tests cover the seat pool and several drivers at once, less the checks
that drive the pool's Scheduler, Admission and Stacks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 08:15:03 +01:00
const fs : : path scratch = td / " scratch " ;
fs : : create_directories ( scratch ) ;
const std : : map < std : : string , std : : string > baseEnv = { { " PATH " , " /bin " } , { " ANTHROPIC_API_KEY " , " leak " } , { " CLAUDE_CODE_OAUTH_TOKEN " , " leak2 " } , { " HOME " , td . string ( ) } } ;
const std : : map < std : : string , std : : string > e1 = SeatPool : : ChildEnv ( SeatPool : : NewSeat ( " 1 " , " oauth " , " tok-one " ) , baseEnv , scratch ) ;
const fs : : path cred = scratch / " seat-1 " / " .credentials.json " ;
Check ( " oauth seat: its own config dir, the token in .credentials.json (0600), no token variable " ,
e1 . at ( " CLAUDE_CONFIG_DIR " ) = = ( scratch / " seat-1 " ) . string ( ) & & Dyn : : LoadJsonFile ( cred ) . at ( " claudeAiOauth " ) . at ( " accessToken " ) = = " tok-one "
& & ( fs : : status ( cred ) . permissions ( ) & fs : : perms : : all ) = = ( fs : : perms : : owner_read | fs : : perms : : owner_write ) & & ! e1 . contains ( " CLAUDE_CODE_OAUTH_TOKEN " ) & & ! e1 . contains ( " ANTHROPIC_API_KEY " ) ) ;
std : : map < std : : string , std : : string > launcher = baseEnv ;
launcher [ " CLAUDE_CODE_ENTRYPOINT " ] = " claude-vscode " ;
const std : : map < std : : string , std : : string > e2 = SeatPool : : ChildEnv ( SeatPool : : NewSeat ( " api1 " , " api " , " sk-ant-api-one " ) , launcher , scratch ) ;
Check ( " api seat: the key in ANTHROPIC_API_KEY, the launcher's CLAUDE_CODE_ENTRYPOINT dropped, the key approved in its own .claude.json " ,
e2 . at ( " ANTHROPIC_API_KEY " ) = = " sk-ant-api-one " & & ! e2 . contains ( " CLAUDE_CODE_ENTRYPOINT " )
& & Dyn : : Equal ( Dyn : : LoadJsonFile ( scratch / " seat-api1 " / " .claude.json " ) . at ( " customApiKeyResponses " ) . at ( " approved " ) , Json : : array ( { " sk-ant-api-one " } ) ) ) ;
// ---- reference vectors ------------------------------------------------------------------
const std : : vector < std : : pair < std : : string , double > > retry = {
{ " Retry-After: 30 " , 35 } ,
{ " retry after 2000 seconds " , 900 } ,
{ " RETRY-AFTER: \u0663 " , 30 } ,
{ " please retry after a moment " , 90 } ,
{ std : : format ( " retry-after:{}45 " , std : : string ( 14 , ' ' ) ) , 90 } ,
{ std : : format ( " retry-after:{}45 " , std : : string ( 12 , ' ' ) ) , 90 } ,
{ " x retry_after 5 retry after 7 " , 30 } ,
{ " retry-after: \u0663 \u0660 x " , 30 } ,
{ " Retry after 99999999999999999999999 " , 900 } ,
{ " " , 90 } ,
{ " retry \u2028 after 5 " , 90 } ,
{ " RETRY AFTER \n \n 12 " , 30 } ,
} ;
std : : vector < std : : string > missed ;
for ( const auto & [ text , want ] : retry ) {
if ( SeatPool : : RetryAfter ( text , 90 ) ! = want ) missed . push_back ( std : : format ( " {} -> {} " , Dyn : : Repr ( text ) , SeatPool : : RetryAfter ( text , 90 ) ) ) ;
}
Check ( " retry-after: the regex's greedy run, Unicode digits, the 30..900 clamp, the fallback " , missed . empty ( ) , Dyn : : Join ( missed , " ; " ) ) ;
const std : : vector < std : : tuple < double , std : : int32_t , std : : string > > cycles = {
{ 1788775200.0 , 1 , " 2026-09-01 " } , { 1788775200.0 , 7 , " 2026-09-07 " } , { 1788775200.0 , 8 , " 2026-08-08 " } , { 1788775200.0 , 28 , " 2026-08-28 " } ,
{ 1772323200.0 , 28 , " 2026-02-28 " } , { 1772323200.0 , 15 , " 2026-02-15 " } , { 1767225599.0 , 5 , " 2025-12-05 " } , { 1709164800.0 , 28 , " 2024-02-28 " } ,
} ;
missed . clear ( ) ;
for ( const auto & [ at , day , want ] : cycles ) {
if ( SeatPool : : CycleStart ( at , day ) ! = want ) missed . push_back ( std : : format ( " {} {} -> {} " , at , day , SeatPool : : CycleStart ( at , day ) ) ) ;
}
Check ( " cycle start: this month's billing day once reached, else last month's, clamped to its length " , missed . empty ( ) , Dyn : : Join ( missed , " ; " ) ) ;
feat(seats): an API seat's cycle starts on its own grant day
The ledger reset every API seat's spend on one
REVIEW_GATES_API_CYCLE_DAY and cleared every credit-out, an OpenRouter
key's too, at that reset. Each API seat's cycle starts on its
ANTHROPIC_API_KEY<n>_GRANT_DAY now (1..31, a day past a month's end its
last), else the cycle day, also 1..31. A credit-out carries across the
rollover, and the run's probe tries a key held out on credit again, as
`seats` does an API key: an ok lifts the mark - an API key's is new
credits, its cycle restarting from the grant day, or from today when
that day is over a week back; an OpenRouter key keeps its cycle's spend,
and a key that answers with its cycle's budget spent stays out on that
budget. A probe that finds a key out of credit records it, unless the
ledger already has it out. Both are decided in one locked update on the
file's entry, a mark another driver made since the probe started
standing, and the ledger's stamps carry their UTC offset so marks are
ordered by instant.
`seats` shows the probe's reading beside the driver's verdict (the
`probe` and `driver` columns replace `state` and `ledger: out`), each
seat's grant day and when its next credits are due, and notes on what
the probe changed in the ledger or why the driver's verdict stands; the
run logs the days.
2026-11-02 13:58:29 +01:00
// 2026-10-17 (the Python driver's, ported 2026-11-02): the cycle is the
// seat's grant day - the credits' own, from the Console's expiry minus
// three days - and a key that answered the credit error stays out across
// the rollover until a probe sees it answer again (then: new credits, a
// new cycle). The Python driver's vectors.
{
auto at = [ ] ( std : : int32_t y , unsigned m , unsigned d ) {
using namespace std : : chrono ;
return static_cast < double > ( duration_cast < seconds > ( ( sys_days ( year_month_day ( year ( y ) , month ( m ) , day ( d ) ) ) + hours ( 12 ) ) . time_since_epoch ( ) ) . count ( ) ) ;
} ;
Check ( " cycle start: a day past the month's end is its last day " ,
SeatPool : : CycleStart ( at ( 2026 , 4 , 30 ) , 31 ) = = " 2026-04-30 " & & SeatPool : : CycleStart ( at ( 2026 , 3 , 1 ) , 31 ) = = " 2026-02-28 " & & SeatPool : : CycleStart ( at ( 2026 , 3 , 30 ) , 28 ) = = " 2026-03-28 " ) ;
constexpr double t17 = at ( 2026 , 10 , 17 ) ;
Check ( " next credits: the grant day after the cycle's; the cycle's own when the seat went out on credit before it " ,
SeatPool : : NextGrant ( t17 , 17 ) = = " 2026-11-17 " & & SeatPool : : NextGrant ( t17 , 5 ) = = " 2026-11-05 " & & SeatPool : : NextGrant ( t17 , 17 , " 2026-10-08T20:19:06 " ) = = " 2026-10-17 "
& & SeatPool : : NextGrant ( t17 , 5 , " 2026-10-13T22:46:02 " ) = = " 2026-11-05 " & & SeatPool : : NextGrant ( at ( 2026 , 12 , 20 ) , 31 ) = = " 2026-12-31 " ) ;
Check ( " ledger verdict: a credit-out, the budget, else ok " ,
SeatPool : : LedgerVerdict ( { { " outSince " , " 2026-10-08T20:19:06 " } , { " outReason " , " credit balance too low " } , { " spentUsd " , 0 } } , 200 )
= = std : : pair < bool , std : : string > ( true , " ledger: credit balance too low since 2026-10-08T20:19 " )
& & SeatPool : : LedgerVerdict ( { { " spentUsd " , 200.0 } } , 200 ) = = std : : pair < bool , std : : string > ( true , " ledger: $200.00 spent this cycle, budget $200 " )
& & SeatPool : : LedgerVerdict ( { { " spentUsd " , 1 } } , 200 ) = = std : : pair < bool , std : : string > ( false , " " ) ) ;
const std : : string text2 = " ANTHROPIC_API_KEY3=sk-x \n ANTHROPIC_API_KEY3_GRANT_DAY=16 \n ANTHROPIC_API_KEY4_GRANT_DAY = 5 \n ANTHROPIC_API_KEY1_GRANT_DAY=32 \n ANTHROPIC_API_KEY2_GRANT_DAY=x \n ANTHROPIC_API_KEY_GRANT_DAY=9 \n " ;
Check ( " a grant day: decimal digits of any script, leading zeros of any length; anything else ignored " ,
Seats : : ApiGrantDays ( { { " ANTHROPIC_API_KEY1_GRANT_DAY " , " 0000000016 " } , { " ANTHROPIC_API_KEY2_GRANT_DAY " , " \uFF11 \uFF16 " } , { " ANTHROPIC_API_KEY3_GRANT_DAY " , " 1_6 " } ,
{ " ANTHROPIC_API_KEY4_GRANT_DAY " , " 99999999999999999999 " } , { " ANTHROPIC_API_KEY5_GRANT_DAY " , " \u00B2 " } , { " ANTHROPIC_API_KEY6_GRANT_DAY " , " 0 " } } )
= = std : : map < std : : int32_t , std : : int32_t > { { 1 , 16 } , { 2 , 16 } } ) ;
const std : : map < std : : string , std : : string > tokens2 = Seats : : SeatTokensFromEnvFile ( text2 ) ;
Check ( " the grant day per seat from the dotenv file, 1..31 only, never a key " ,
tokens2 = = std : : map < std : : string , std : : string > { { " ANTHROPIC_API_KEY3 " , " sk-x " } , { " ANTHROPIC_API_KEY3_GRANT_DAY " , " 16 " } , { " ANTHROPIC_API_KEY4_GRANT_DAY " , " 5 " } ,
{ " ANTHROPIC_API_KEY1_GRANT_DAY " , " 32 " } , { " ANTHROPIC_API_KEY2_GRANT_DAY " , " x " } }
& & Seats : : ApiGrantDays ( tokens2 ) = = std : : map < std : : int32_t , std : : int32_t > { { 3 , 16 } , { 4 , 5 } }
& & Seats : : ApiKeysFromEnv ( tokens2 ) = = std : : vector < std : : pair < std : : int32_t , std : : string > > { { 3 , " sk-x " } } ) ;
SeatPool : : Ledger old ( td / " old.json " , acfg ,
{ { " api1 " , { { " cycle " , " 1999-01-01 " } , { " spentUsd " , 500 } , { " procs " , 9 } , { " outSince " , " x " } , { " outReason " , " y " } } } ,
{ " api2 " , { { " cycle " , " 1999-01-01 " } , { " spentUsd " , 500 } , { " procs " , 9 } , { " outSince " , nullptr } , { " outReason " , nullptr } } } ,
{ " or1 " , { { " cycle " , " 1999-01-01 " } , { " spentUsd " , 50 } , { " procs " , 9 } , { " outSince " , " x " } , { " outReason " , " y " } } } } ) ;
Check ( " a new cycle resets the spend; a credit-out carries over until a probe lifts it, an OpenRouter key's too (the month's turn puts nothing on it) " ,
old . Entry ( " api1 " ) . at ( " spentUsd " ) = = 0 & & old . Entry ( " api1 " ) . at ( " procs " ) = = 0 & & old . Entry ( " api1 " ) . at ( " outSince " ) = = " x " & & old . Entry ( " api2 " ) . at ( " outSince " ) . is_null ( )
& & old . Entry ( " api2 " ) . at ( " spentUsd " ) = = 0 & & old . Entry ( " or1 " ) . at ( " outSince " ) = = " x " & & old . Entry ( " or1 " ) . at ( " outReason " ) = = " y " & & old . Entry ( " or1 " ) . at ( " spentUsd " ) = = 0 ) ;
Check ( " ledger out: credit, budget, else null " ,
SeatPool : : LedgerOut ( { { " outSince " , " 2026-10-08T20:19:06 " } , { " spentUsd " , 0 } } , 200 ) = = " credit " & & SeatPool : : LedgerOut ( { { " spentUsd " , 200.0 } } , 200 ) = = " budget "
& & SeatPool : : LedgerOut ( { { " spentUsd " , 1 } } , 200 ) . is_null ( ) ) ;
const fs : : path daysEnv = td / " days.env " ;
Write ( daysEnv , " ANTHROPIC_API_KEY1=sk-ant-api-one \n ANTHROPIC_API_KEY1_GRANT_DAY=17 \n ANTHROPIC_API_KEY2=sk-ant-api-two \n ANTHROPIC_API_KEY2_GRANT_DAY=0 \n " ) ;
SeatPool : : Ledger lg ( td / " days.json " , acfg ,
{ { " api1 " , { { " cycle " , " 2026-10-01 " } , { " spentUsd " , 200.18 } , { " procs " , 112 } , { " outSince " , " 2026-10-08T20:19:06 " } , { " outReason " , " credit balance too low " } } } ,
{ " api2 " , { { " cycle " , " 2026-09-01 " } , { " spentUsd " , 150.0 } , { " procs " , 90 } , { " outSince " , nullptr } , { " outReason " , nullptr } } } } ) ;
std : : vector < Json > ds = SeatPool : : LoadSeats ( SeatPool : : WithFileTokens ( { } , SeatPool : : ResolveSeatsFile ( daysEnv . string ( ) , td ) ) , " api " , & lg , acfg , t17 ) ;
Check ( " the grant day per seat from the seats file (0 is ignored: the global day), into the ledger " ,
Ids ( ds ) = = " api1,api2 " & & ds [ 0 ] . at ( " grantDay " ) = = 17 & & ds [ 1 ] . at ( " grantDay " ) = = 1 & & lg . Day ( " api1 " ) = = 17 & & lg . Day ( " api2 " ) = = 1 , Ids ( ds ) ) ;
Check ( " rollover on the grant day: the spend starts over, a credit-out carries - the seat stays out " ,
ds [ 0 ] . at ( " state " ) = = " out " & & ds [ 0 ] . at ( " ledgerOut " ) = = " credit " & & ds [ 0 ] . at ( " spentUsd " ) = = 0 & & lg . Entry ( " api1 " , t17 ) . at ( " cycle " ) = = " 2026-10-17 "
& & lg . Entry ( " api1 " , t17 ) . at ( " procs " ) = = 0 & & ds [ 0 ] . at ( " error " ) . get < std : : string > ( ) . contains ( " since 2026-10-08 " ) ,
DumpSpaced ( ds [ 0 ] ) ) ;
Check ( " ...a budget-out resets with its cycle " ,
ds [ 1 ] . at ( " state " ) = = " unknown " & & Dyn : : Get ( ds [ 1 ] , " ledgerOut " ) . is_null ( ) & & ds [ 1 ] . at ( " spentUsd " ) = = 0 & & lg . Entry ( " api2 " , t17 ) . at ( " cycle " ) = = " 2026-10-01 " ) ;
std : : vector < std : : string > calls ;
std : : map < std : : string , std : : string > answers = { { " api1 " , " ok " } , { " api2 " , " out " } } ;
const SeatPool : : ProbeFunction fake = [ & ] ( std : : int32_t n , const std : : string & , const std : : string & model , double , const std : : string & , bool , bool ) {
const std : : string id = std : : format ( " api{} " , n ) ;
calls . push_back ( id ) ;
const std : : string state = answers . at ( id ) ;
return Json { { " seat " , n } , { " state " , state } , { " windows " , Json : : object ( ) } , { " probedWith " , model } ,
{ " error " , state = = " ok " ? Json ( ) : Json ( state = = " out " ? " Your credit balance is too low " : " probe timeout after 1000 ms " ) } } ;
} ;
std : : vector < std : : string > plog ;
auto plogf = [ & ] ( const std : : string & line ) { plog . push_back ( line ) ; } ;
SeatPool : : Probe ( ds , " claude " , 1 , { " claude-opus-5-5 " } , plogf , fake , & lg , t17 ) ;
const Json e1 = lg . Entry ( " api1 " , t17 ) ;
Check ( " the run-start probe re-probes a credit-out api seat; a clean answer is new credits: the seat is back, its cycle restarted on its grant day " ,
calls = = std : : vector < std : : string > { " api1 " , " api2 " } & & ds [ 0 ] . at ( " state " ) = = " ok " & & ds [ 0 ] . at ( " ledgerOut " ) . is_null ( ) & & ds [ 0 ] . at ( " error " ) . is_null ( ) & & e1 . at ( " outSince " ) . is_null ( )
& & e1 . at ( " cycle " ) = = " 2026-10-17 " & & e1 . at ( " grantSeen " ) = = " 2026-10-17T12:00:00+00:00 "
& & std : : ranges : : any_of ( plog , [ ] ( const std : : string & line ) { return line . contains ( " new credits " ) ; } ) ,
Dyn : : Join ( plog , " | " ) ) ;
const Json e2 = lg . Entry ( " api2 " , t17 ) ;
Check ( " ...the credit error on a seat the ledger had as fine is recorded, with the next credits in the reason " ,
ds [ 1 ] . at ( " state " ) = = " out " & & ds [ 1 ] . at ( " ledgerOut " ) = = " credit " & & Dyn : : Truthy ( e2 . at ( " outSince " ) )
& & e2 . at ( " outSince " ) = = " 2026-10-17T12:00:00+00:00 " & & ds [ 1 ] . at ( " error " ) = = " credit balance too low since 2026-10-17T12:00; next credits due 2026-11-01 " ,
Dyn : : Str ( ds [ 1 ] . at ( " error " ) ) ) ;
Check ( " reconcile: nothing to do when the probe and the ledger agree " , lg . Reconcile ( " api1 " , " ok " , t17 , t17 ) . empty ( ) & & lg . Reconcile ( " api2 " , " out " , t17 , t17 ) . empty ( ) ) ;
// Two drivers on one ledger (1.1.0 round 2): the decision is made on
// the file's entry under the lock, never on a copy read before the
// probe, and a mark made since the probe started stands.
const std : : string outLine = R " ( " cycle " : " 2026 - 10 - 17 " , " spentUsd " : 0, " procs " : 0, " outSince " : " 2026 - 10 - 08 T20 : 19 : 06 " , " outReason " : " credit balance too low " ) " ;
Write ( td / " race1.json " , std : : format ( " {{ \" api1 \" : {{{}}}}} " , outLine ) ) ;
SeatPool : : Ledger la = SeatPool : : Ledger : : Load ( td / " race1.json " , acfg , { { " api1 " , 17 } } ) ;
SeatPool : : Ledger lb = SeatPool : : Ledger : : Load ( td / " race1.json " , acfg , { { " api1 " , 17 } } ) ;
const std : : string firstGrant = la . Reconcile ( " api1 " , " ok " , t17 , t17 ) ;
la . Add ( " api1 " , 5.0 , t17 ) ;
const std : : string secondGrant = lb . Reconcile ( " api1 " , " ok " , t17 + 60 , t17 + 60 ) ;
const Json race1 = SeatPool : : Ledger : : Load ( td / " race1.json " , acfg , { { " api1 " , 17 } } ) . Entry ( " api1 " , t17 + 60 ) ;
Check ( " two drivers: the second's copy, read before the first saw the grant, lifts nothing - the first's grant and its spend stand " ,
firstGrant = = " new-grant " & & secondGrant . empty ( ) & & race1 . at ( " spentUsd " ) = = 5.0 & & race1 . at ( " procs " ) = = 1 & & race1 . at ( " outSince " ) . is_null ( ) , DumpSpaced ( race1 ) ) ;
Write ( td / " race2.json " , R " ({ " api1 " : { " cycle " : " 2026 - 10 - 17 " , " spentUsd " : 199.4, " procs " : 180, " outSince " : " 2026 - 10 - 17 T12 : 00 : 06 " , " outReason " : " credit balance too low " }}) " ) ;
SeatPool : : Ledger lc = SeatPool : : Ledger : : Load ( td / " race2.json " , acfg , { { " api1 " , 17 } } ) ;
const std : : string late = lc . Reconcile ( " api1 " , " ok " , t17 , t17 + 30 ) ;
const Json race2 = SeatPool : : Ledger : : Load ( td / " race2.json " , acfg , { { " api1 " , 17 } } ) . Entry ( " api1 " , t17 + 30 ) ;
Check ( " a credit error recorded after the probe started outlives its answer: no grant, the spend kept " ,
late . empty ( ) & & race2 . at ( " outSince " ) = = " 2026-10-17T12:00:06 " & & race2 . at ( " spentUsd " ) = = 199.4 & & race2 . at ( " procs " ) = = 180 , DumpSpaced ( race2 ) ) ;
Write ( td / " race3.json " , R " ({ " api1 " : { " cycle " : " 2026 - 10 - 17 " , " spentUsd " : 2, " procs " : 1, " outSince " : null, " outReason " : null, " grantSeen " : " 2026 - 10 - 17 T12 : 00 : 10 " }}) " ) ;
SeatPool : : Ledger ld = SeatPool : : Ledger : : Load ( td / " race3.json " , acfg , { { " api1 " , 17 } } ) ;
const std : : string stale = ld . Reconcile ( " api1 " , " out " , t17 , t17 + 30 ) ;
const std : : string fresh = ld . Reconcile ( " api1 " , " out " , t17 + 60 , t17 + 60 ) ;
Check ( " ...and a credit error read before a grant another driver saw since records nothing; one read after it does " ,
stale . empty ( ) & & fresh = = " credit-gone " & & SeatPool : : Ledger : : Load ( td / " race3.json " , acfg , { { " api1 " , 17 } } ) . Entry ( " api1 " , t17 + 60 ) . at ( " spentUsd " ) = = 2 ) ;
// The grant seen at 23:59:55, the cycle turning at midnight (grant
// day 17) before a credit error read at 23:59:40 is reconciled.
Write ( td / " race6.json " , R " ({ " api1 " : { " cycle " : " 2026 - 11 - 16 " , " spentUsd " : 2, " procs " : 1, " outSince " : null, " outReason " : null, " grantSeen " : " 2026 - 11 - 16 T23 : 59 : 55 " }}) " ) ;
SeatPool : : Ledger le = SeatPool : : Ledger : : Load ( td / " race6.json " , acfg , { { " api1 " , 17 } } ) ;
const std : : string acrossMidnight = le . Reconcile ( " api1 " , " out " , at ( 2026 , 11 , 16 ) + 43180 , at ( 2026 , 11 , 17 ) - 43198 ) ;
const Json race6 = SeatPool : : Ledger : : Load ( td / " race6.json " , acfg , { { " api1 " , 17 } } ) . Entry ( " api1 " , at ( 2026 , 11 , 17 ) - 43198 ) ;
// The stamps carry their UTC offset and Reconcile orders marks by
// instant (1.1.0 round 4). A POSIX rule, not a zone file: Central
// European time, whose summer time ends 2026-10-25 03:00, 02:00-03:00
// then passing twice.
setenv ( " TZ " , " CET-1CEST,M3.5.0,M10.5.0/3 " , 1 ) ;
tzset ( ) ;
constexpr double fallBack = at ( 2026 , 10 , 25 ) - 39610 ;
Write ( td / " race7.json " , R " ({ " api1 " : { " cycle " : " 2026 - 10 - 17 " , " spentUsd " : 150, " procs " : 120, " outSince " : null, " outReason " : null}}) " ) ;
SeatPool : : Ledger : : Load ( td / " race7.json " , acfg , { { " api1 " , 17 } } ) . MarkOut ( " api1 " , " credit balance too low " , fallBack + 15 ) ;
const std : : string afterFallBack = SeatPool : : Ledger : : Load ( td / " race7.json " , acfg , { { " api1 " , 17 } } ) . Reconcile ( " api1 " , " ok " , fallBack , fallBack + 16 ) ;
const Json race7 = SeatPool : : Ledger : : Load ( td / " race7.json " , acfg , { { " api1 " , 17 } } ) . Entry ( " api1 " , fallBack + 16 ) ;
// A stamp without an offset, as older drivers wrote, is local time:
// 13:30 CEST is 11:30 UTC, before a probe started at 12:00 UTC (14:00
// CEST) - new credits; read as UTC it would be after the probe.
Write ( td / " race9.json " , R " ({ " api1 " : { " cycle " : " 2026 - 10 - 17 " , " spentUsd " : 3, " procs " : 1, " outSince " : " 2026 - 10 - 17 T13 : 30 : 00 " , " outReason " : " credit balance too low " }}) " ) ;
const std : : string legacy = SeatPool : : Ledger : : Load ( td / " race9.json " , acfg , { { " api1 " , 17 } } ) . Reconcile ( " api1 " , " ok " , t17 , t17 + 30 ) ;
setenv ( " TZ " , " UTC " , 1 ) ;
tzset ( ) ;
Check ( " a credit error recorded after the probe started outlives its answer in the hour DST repeats: 02:00:05 CET is after 02:59:50 CEST " ,
afterFallBack . empty ( ) & & race7 . at ( " outSince " ) = = " 2026-10-25T02:00:05+01:00 " & & race7 . at ( " spentUsd " ) = = 150 , DumpSpaced ( race7 ) ) ;
Write ( td / " race8.json " , R " ({ " api1 " : { " cycle " : " 2026 - 10 - 17 " , " spentUsd " : 2, " procs " : 1, " outSince " : " 2026 - 10 - 17 T11 : 00 : 06 - 01 : 00 " , " outReason " : " credit balance too low " }}) " ) ;
const std : : string otherZone = SeatPool : : Ledger : : Load ( td / " race8.json " , acfg , { { " api1 " , 17 } } ) . Reconcile ( " api1 " , " ok " , t17 , t17 + 30 ) ;
Check ( " ...and from a driver in another zone: its 11:00:06-01:00 is after a probe started at 12:00:00 UTC " , otherZone . empty ( ) ) ;
Check ( " a stamp without an offset, as older drivers wrote, is read as local time: 13:30 CEST is before a probe started at 14:00 CEST " , legacy = = " new-grant " , legacy ) ;
Write ( td / " race10.json " , std : : format ( " {{ \" api1 \" : {{{}}}}} " , outLine ) ) ;
const std : : string race10Before = Platform : : ReadFile ( td / " race10.json " ) . value_or ( " " ) ;
const std : : string unread = SeatPool : : Ledger : : Load ( td / " race10.json " , acfg , { { " api1 " , 17 } } ) . Reconcile ( " api1 " , " unknown " , t17 , t17 ) ;
Check ( " a reading neither ok nor the credit error writes nothing " , unread . empty ( ) & & Platform : : ReadFile ( td / " race10.json " ) . value_or ( " " ) = = race10Before ) ;
// OpenRouter keys (1.1.0, Jorijn: a prepaid key has no cycle of its
// own): one the ledger holds out on credit is probed again through
// the key probe, and room on its limit lifts the mark with its
// cycle's spend kept; the limit reached is recorded; one out on its
// budget is not probed. Their cycle is the cycle day's.
Write ( td / " or.env " , " OPENROUTER_KEY1=or-one \n OPENROUTER_KEY2=or-two \n OPENROUTER_KEY3=or-three \n " ) ;
Write ( td / " or-ledger.json " , R " ({ " or1 " : { " cycle " : " 2026 - 10 - 01 " , " spentUsd " : 7.5, " procs " : 3, " outSince " : " 2026 - 10 - 10 T09 : 00 : 00 + 00 : 00 " , " outReason " : " credit balance too low " },
" or2 " : { " cycle " : " 2026-10-01 " , " spentUsd " : 1 , " procs " : 1 , " outSince " : null , " outReason " : null } ,
" or3 " : { " cycle " : " 2026-10-01 " , " spentUsd " : 150 , " procs " : 90 , " outSince " : null , " outReason " : null } } ) " );
SeatPool : : Ledger orLedger = SeatPool : : Ledger : : Load ( td / " or-ledger.json " , acfg ) ;
std : : vector < Json > orSeats = SeatPool : : LoadSeats ( SeatPool : : WithFileTokens ( { } , SeatPool : : ResolveSeatsFile ( ( td / " or.env " ) . string ( ) , td ) ) , " openrouter " , & orLedger , acfg , t17 ) ;
std : : vector < std : : string > keyCalls ;
const SeatPool : : OpenRouterProbeFunction fakeKey = [ & ] ( const std : : string & secret , double ) {
keyCalls . push_back ( secret ) ;
return secret = = " or-one " ? Json { { " state " , " ok " } , { " remaining " , 3.0 } } : Json { { " state " , " out " } , { " error " , " key limit reached ($10.00 of $10 used) " } , { " remaining " , 0 } } ;
} ;
plog . clear ( ) ;
SeatPool : : Probe ( orSeats , " claude " , 1 , { } , plogf , fake , & orLedger , t17 , fakeKey ) ;
SeatPool : : Ledger orFile = SeatPool : : Ledger : : Load ( td / " or-ledger.json " , acfg ) ;
const Json or1 = orFile . Entry ( " or1 " , t17 ) ;
const Json or2 = orFile . Entry ( " or2 " , t17 ) ;
Check ( " an OpenRouter key held out on credit is probed again, one out on its budget is not; room on its limit lifts the mark and keeps its cycle's spend " ,
Ids ( orSeats ) = = " or1,or2,or3 " & & keyCalls = = std : : vector < std : : string > { " or-one " , " or-two " } & & orSeats [ 0 ] . at ( " state " ) = = " ok " & & orSeats [ 0 ] . at ( " ledgerOut " ) . is_null ( )
& & orSeats [ 0 ] . at ( " spentUsd " ) = = 7.5 & & or1 . at ( " outSince " ) . is_null ( ) & & or1 . at ( " spentUsd " ) = = 7.5 & & or1 . at ( " procs " ) = = 3 & & or1 . at ( " cycle " ) = = " 2026-10-01 "
& & or1 . at ( " grantSeen " ) = = " 2026-10-17T12:00:00+00:00 " & & std : : ranges : : any_of ( plog , [ ] ( const std : : string & line ) { return line . contains ( " limit has room again " ) ; } )
& & orSeats [ 2 ] . at ( " state " ) = = " out " & & orSeats [ 2 ] . at ( " ledgerOut " ) = = " budget " ,
std : : format ( " {} {} " , DumpSpaced ( or1 ) , Dyn : : Join ( keyCalls , " , " ) ) ) ;
Check ( " ...and the limit reached is recorded as the key's credit-out, the probe's error the seat's reason " ,
orSeats [ 1 ] . at ( " state " ) = = " out " & & orSeats [ 1 ] . at ( " ledgerOut " ) = = " credit " & & orSeats [ 1 ] . at ( " error " ) = = " key limit reached ($10.00 of $10 used) "
& & or2 . at ( " outSince " ) = = " 2026-10-17T12:00:00+00:00 " & & or2 . at ( " outReason " ) = = " key limit reached " ,
DumpSpaced ( or2 ) ) ;
// A key that answers with its cycle's budget spent is out on that
// budget, not left ok - neither placed nor out, a pool of it waiting
// forever (1.1.0 round 9): an OpenRouter key held out on credit with
// its spend over the budget, and an API key another driver lifted and
// spent the budget on since this copy was read.
Write ( td / " or-spent.env " , " OPENROUTER_KEY1=or-one \n " ) ;
Write ( td / " or-spent.json " ,
R " ({ " or1 " : { " cycle " : " 2026 - 10 - 01 " , " spentUsd " : 100.4, " procs " : 40, " outSince " : " 2026 - 10 - 10 T09 : 00 : 00 + 00 : 00 " , " outReason " : " credit balance too low " }}) " ) ;
SeatPool : : Ledger spentLedger = SeatPool : : Ledger : : Load ( td / " or-spent.json " , acfg ) ;
std : : vector < Json > spentSeats =
SeatPool : : LoadSeats ( SeatPool : : WithFileTokens ( { } , SeatPool : : ResolveSeatsFile ( ( td / " or-spent.env " ) . string ( ) , td ) ) , " openrouter " , & spentLedger , acfg , t17 ) ;
SeatPool : : Probe ( spentSeats , " claude " , 1 , { } , plogf , fake , & spentLedger , t17 , fakeKey ) ;
Check ( " an OpenRouter key held out on credit with its budget spent too: the mark lifted, the seat out on the budget, a pool of it all out " ,
spentSeats [ 0 ] . at ( " state " ) = = " out " & & spentSeats [ 0 ] . at ( " ledgerOut " ) = = " budget " & & SeatPool : : AllOut ( spentSeats )
& & SeatPool : : Ledger : : Load ( td / " or-spent.json " , acfg ) . Entry ( " or1 " , t17 ) . at ( " outSince " ) . is_null ( ) ,
DumpSpaced ( spentSeats [ 0 ] ) ) ;
Write ( td / " race11.json " , std : : format ( " {{ \" api1 \" : {{{}}}}} " , outLine ) ) ;
SeatPool : : Ledger stale11 ( SeatPool : : Ledger : : Load ( td / " race11.json " , acfg ) ) ;
std : : vector < Json > mine11 = SeatPool : : LoadSeats ( SeatPool : : WithFileTokens ( { } , SeatPool : : ResolveSeatsFile ( daysEnv . string ( ) , td ) ) , " api1 " , & stale11 , acfg , t17 ) ;
SeatPool : : Ledger other11 = SeatPool : : Ledger : : Load ( td / " race11.json " , acfg , { { " api1 " , 17 } } ) ;
other11 . Reconcile ( " api1 " , " ok " , t17 , t17 ) ;
other11 . Add ( " api1 " , 12.0 , t17 ) ;
answers [ " api1 " ] = " ok " ;
SeatPool : : Probe ( mine11 , " claude " , 1 , { } , plogf , fake , & stale11 , t17 + 60 ) ;
Check ( " ...and an API key another driver lifted and spent its budget on since: out on the budget " ,
mine11 [ 0 ] . at ( " state " ) = = " out " & & mine11 [ 0 ] . at ( " ledgerOut " ) = = " budget " & & mine11 [ 0 ] . at ( " spentUsd " ) = = 12.0 & & SeatPool : : AllOut ( mine11 ) , DumpSpaced ( mine11 [ 0 ] ) ) ;
Check ( " an OpenRouter key's cycle starts on the cycle day " , orLedger . Day ( " or1 " ) = = 1 & & SeatPool : : Ledger : : Load ( td / " or-ledger.json " , acfg ) . Entry ( " or1 " , at ( 2026 , 11 , 2 ) ) . at ( " cycle " ) = = " 2026-11-01 " ) ;
Check ( " ...across the cycle's turn too: the grant's time carries over the rollover with an API seat's entry " ,
acrossMidnight . empty ( ) & & race6 . at ( " outSince " ) . is_null ( ) & & race6 . at ( " grantSeen " ) = = " 2026-11-16T23:59:55 " & & race6 . at ( " cycle " ) = = " 2026-11-17 " , DumpSpaced ( race6 ) ) ;
Write ( td / " race4.json " , std : : format ( " {{ \" api1 \" : {{{}}}}} " , outLine ) ) ;
SeatPool : : Ledger stale4 ( SeatPool : : Ledger : : Load ( td / " race4.json " , acfg ) ) ;
std : : vector < Json > mine = SeatPool : : LoadSeats ( SeatPool : : WithFileTokens ( { } , SeatPool : : ResolveSeatsFile ( daysEnv . string ( ) , td ) ) , " api1 " , & stale4 , acfg , t17 ) ;
SeatPool : : Ledger other4 = SeatPool : : Ledger : : Load ( td / " race4.json " , acfg , { { " api1 " , 17 } } ) ;
other4 . Reconcile ( " api1 " , " ok " , t17 , t17 ) ;
other4 . Add ( " api1 " , 5.0 , t17 ) ;
answers [ " api1 " ] = " ok " ;
plog . clear ( ) ;
SeatPool : : Probe ( mine , " claude " , 1 , { } , plogf , fake , & stale4 , t17 + 60 ) ;
Check ( " the run's probe after another driver's grant: the seat is back with that driver's spend, no second grant " ,
mine [ 0 ] . at ( " state " ) = = " ok " & & mine [ 0 ] . at ( " spentUsd " ) = = 5.0 & & mine [ 0 ] . at ( " ledgerOut " ) . is_null ( )
& & std : : ranges : : none_of ( plog , [ ] ( const std : : string & line ) { return line . contains ( " new credits " ) ; } )
& & SeatPool : : Ledger : : Load ( td / " race4.json " , acfg ) . Entry ( " api1 " , t17 + 60 ) . at ( " spentUsd " ) = = 5.0 ,
DumpSpaced ( mine [ 0 ] ) ) ;
Write ( td / " race5.json " , R " ({ " api1 " : { " cycle " : " 2026 - 10 - 17 " , " spentUsd " : 2, " procs " : 1, " outSince " : null, " outReason " : null}}) " ) ;
SeatPool : : Ledger mine5 ( SeatPool : : Ledger : : Load ( td / " race5.json " , acfg ) ) ;
std : : vector < Json > seats5 = SeatPool : : LoadSeats ( SeatPool : : WithFileTokens ( { } , SeatPool : : ResolveSeatsFile ( daysEnv . string ( ) , td ) ) , " api1 " , & mine5 , acfg , t17 ) ;
SeatPool : : Ledger : : Load ( td / " race5.json " , acfg , { { " api1 " , 17 } } ) . MarkOut ( " api1 " , " credit balance too low " , t17 + 6 ) ;
SeatPool : : Probe ( seats5 , " claude " , 1 , { } , plogf , fake , & mine5 , t17 ) ;
Check ( " ...and the run's probe that answered before another driver's credit error: the seat is out on the ledger's verdict " ,
seats5 [ 0 ] . at ( " state " ) = = " out " & & seats5 [ 0 ] . at ( " ledgerOut " ) = = " credit " & & seats5 [ 0 ] . at ( " error " ) = = " ledger: credit balance too low since 2026-10-17T12:00 " ,
DumpSpaced ( seats5 [ 0 ] ) ) ;
calls . clear ( ) ;
answers [ " api1 " ] = " unknown " ;
Json apiB = With ( ds [ 1 ] , { { " state " , " out " } , { " ledgerOut " , " budget " } , { " error " , " ledger: $10.00 spent this cycle, budget $10 " } } ) ;
Json apiU = With ( ds [ 0 ] , { { " state " , " out " } , { " ledgerOut " , " credit " } , { " error " , " ledger: credit balance too low since 2026-10-08T20:19 " } } ) ;
std : : vector < Json > pair2 = { apiB , apiU } ;
SeatPool : : Probe ( pair2 , " claude " , 1 , { } , plogf , fake , nullptr , t17 ) ;
Check ( " a budget-out seat is not probed; a credit-out seat whose probe is unreadable stays out on the ledger's verdict " ,
calls = = std : : vector < std : : string > { " api1 " } & & pair2 [ 0 ] . at ( " state " ) = = " out " & & pair2 [ 1 ] . at ( " state " ) = = " out "
& & pair2 [ 1 ] . at ( " error " ) = = " ledger: credit balance too low since 2026-10-08T20:19 (probe unreadable: probe timeout after 1000 ms) " ,
Dyn : : Str ( pair2 [ 1 ] . at ( " error " ) ) ) ;
// A grant's cycle, through the production path: the credit error
// recorded, then a probe that started after it answers.
lg . SetDay ( " api3 " , 5 ) ;
lg . MarkOut ( " api3 " , " credit balance too low " , t17 - 60 ) ;
const std : : string grant3 = lg . Reconcile ( " api3 " , " ok " , t17 , t17 ) ;
Check ( " new credits seen 12 days after the configured day: the cycle starts today, not on that day " ,
grant3 = = " new-grant " & & lg . Entry ( " api3 " , t17 ) . at ( " cycle " ) = = " 2026-10-17 " & & lg . Entry ( " api3 " , t17 ) . at ( " spentUsd " ) = = 0 ) ;
lg . SetDay ( " api4 " , 16 ) ;
lg . MarkOut ( " api4 " , " credit balance too low " , t17 - 60 ) ;
const std : : string grant4 = lg . Reconcile ( " api4 " , " ok " , t17 , t17 ) ;
Check ( " ...and on the day when it is within the week " , grant4 = = " new-grant " & & lg . Entry ( " api4 " , t17 ) . at ( " cycle " ) = = " 2026-10-16 "
& & lg . Entry ( " api4 " , at ( 2026 , 11 , 15 ) ) . at ( " cycle " ) = = " 2026-10-16 "
& & lg . Entry ( " api4 " , at ( 2026 , 11 , 16 ) ) . at ( " cycle " ) = = " 2026-11-16 " ) ;
}
feat(seatpool): the seat pool and the board several drivers share
The seats of .env and the ledger, the probe, placement, settling a
finished pass, the child's credentials, the OpenRouter seats, and the
board every driver on the machine shares, in one shape and under one
lock. A driver is alive while its lifetime lock is held; with no lock file
natively its pid and start time decide, and in the sandbox it is taken for
alive.
:Http is the HTTP the driver needs, on FetchHTTP1: a status outside 2xx is
HttpError, every other failure carries a fixed text. :Platform gains
MakeDirs, with the last directory's own mode, and errno texts for its
writes and locks.
The tests cover the seat pool and several drivers at once, less the checks
that drive the pool's Scheduler, Admission and Stacks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 08:15:03 +01:00
const std : : string knobs = DumpSpaced ( SeatPool : : ApiConfig ( { { " REVIEW_GATES_API_BUDGET_USD " , " 1_0 " } ,
{ " REVIEW_GATES_API_CONCURRENCY " , " 3.9 " } ,
{ " REVIEW_GATES_API_CYCLE_DAY " , " 40 " } ,
{ " REVIEW_GATES_SEAT_ORDER " , " oauth-first " } ,
{ " REVIEW_GATES_OPENROUTER_BUDGET_USD " , " -1 " } ,
{ " REVIEW_GATES_API_LENS_COST_USD " , " nan " } } ) ) ;
Check ( " api config: float() parsing, int() truncation, the cycle day clamped, a negative or NaN value the default " ,
feat(seats): an API seat's cycle starts on its own grant day
The ledger reset every API seat's spend on one
REVIEW_GATES_API_CYCLE_DAY and cleared every credit-out, an OpenRouter
key's too, at that reset. Each API seat's cycle starts on its
ANTHROPIC_API_KEY<n>_GRANT_DAY now (1..31, a day past a month's end its
last), else the cycle day, also 1..31. A credit-out carries across the
rollover, and the run's probe tries a key held out on credit again, as
`seats` does an API key: an ok lifts the mark - an API key's is new
credits, its cycle restarting from the grant day, or from today when
that day is over a week back; an OpenRouter key keeps its cycle's spend,
and a key that answers with its cycle's budget spent stays out on that
budget. A probe that finds a key out of credit records it, unless the
ledger already has it out. Both are decided in one locked update on the
file's entry, a mark another driver made since the probe started
standing, and the ledger's stamps carry their UTC offset so marks are
ordered by instant.
`seats` shows the probe's reading beside the driver's verdict (the
`probe` and `driver` columns replace `state` and `ledger: out`), each
seat's grant day and when its next credits are due, and notes on what
the probe changed in the ledger or why the driver's verdict stands; the
run logs the days.
2026-11-02 13:58:29 +01:00
knobs = = R " ({ " budgetUsd " : 10.0, " lensCostUsd " : 1.0, " concurrency " : 3, " cycleDay " : 31, " order " : " oauth - first " , " orBudgetUsd " : 100.0, " orLensCostUsd " : 0.1, " orConcurrency " : 16}) " , knobs ) ;
feat(seatpool): the seat pool and the board several drivers share
The seats of .env and the ledger, the probe, placement, settling a
finished pass, the child's credentials, the OpenRouter seats, and the
board every driver on the machine shares, in one shape and under one
lock. A driver is alive while its lifetime lock is held; with no lock file
natively its pid and start time decide, and in the sandbox it is taken for
alive.
:Http is the HTTP the driver needs, on FetchHTTP1: a status outside 2xx is
HttpError, every other failure carries a fixed text. :Platform gains
MakeDirs, with the last directory's own mode, and errno texts for its
writes and locks.
The tests cover the seat pool and several drivers at once, less the checks
that drive the pool's Scheduler, Admission and Stacks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 08:15:03 +01:00
const double cost = SeatPool : : OpenRouterCost ( " openrouter/xiaomi/mimo-v2.6-pro " , { { " input " , 1234 } , { " cacheCreation " , 10 } , { " cacheRead " , 99999 } , { " output " , 777 } } ) ;
Check ( " openrouter cost: tokens x the built-in list prices, an unknown model free " , cost = = 0.001577 & & SeatPool : : OpenRouterCost ( " nope " , { { " input " , 1 } } ) = = 0.0 , Dyn : : FloatRepr ( cost ) ) ;
Json described = SeatPool : : NewSeat ( " 1 " , " oauth " , " t " ) ;
described [ " state " ] = " ok " ;
described [ " windows " ] = { { " five_hour " , { { " utilization " , 61.5 } , { " resetsAt " , 1 } } } , { " seven_day " , { { " utilization " , 18 } , { " resetsAt " , 2 } } } , { " seven_day_overage_included " , { { " utilization " , 22 } , { " resetsAt " , 0 } } } ,
{ " seven_day_fable " , { { " utilization " , 3 } } } , { " other " , { { " utilization " , nullptr } } } } ;
described [ " binding " ] = " five_hour " ;
Json paid = SeatPool : : NewSeat ( " api1 " , " api " , " k " ) ;
paid = With ( paid , { { " state " , " out " } , { " error " , " budget " } , { " spentUsd " , 12.345 } , { " remainingUsd " , 3 } } ) ;
Check ( " describe: an OAuth seat's windows by label, a paid seat's spend and what is left on the key " ,
SeatPool : : Describe ( described ) = = " ok: 5h 61.5%, 7d 18%, fable 22%, fable 3% (binding five_hour) " & & SeatPool : : Describe ( paid ) = = " out (budget), $12.35 spent this cycle, $3.00 left on the key " ,
std : : format ( " {} | {} " , SeatPool : : Describe ( described ) , SeatPool : : Describe ( paid ) ) ) ;
feat(seats): the env file's settings count, and a machine's own seats file
ApiConfig and PoolConfig read the seat order, the budgets and the
concurrency from the process environment alone, so a `.env` that said
REVIEW_GATES_SEAT_ORDER=oauth-first ordered nothing: the Python driver
reads those lines from the file under the process environment
(config_env, 2026-10-17: a setting lives beside the seats it orders).
SeatPool::SettingsOf does the same - the file's placement settings
under the process environment, in a map handed to the placement readers
alone (ApiConfig, PoolConfig, Seats::ConfigFromEnv) - and leaves the
process environment untouched, so no other reader sees a line of the
file: a path's or a binary's line reaches nothing, and two drivers
reading one .env keep one board and one ledger. The placement settings
are one list, SeatPool::PlacementSettings - the fifteen names those
readers read - for the map, the run's log and what makes a working
directory's .env a seats file; a REVIEW_GATES_* line of any other name
stays out of the map and is named, by the run's log and on `seats`'s
stderr. One dotenv grammar serves the tokens and the settings
(Seats::DotenvLines).
`run` and `seats` resolve the file from their own --env-file
(SeatPool::ResolveSeatsFile): the --env-file, else $SEATS_ENV_FILE, else
the working directory's .env - the operator's, as the Python driver and
`seats` read it, not the repository under review's - when it is a file
holding a seat or a placement setting, each with a value, or one that
cannot be read as UTF-8 text (its error is then the command's) - a
readable application .env, its Vite or Supabase lines, one of blank
placeholder lines or one that is no file is passed over, and the run
says so - else the machine's own
$XDG_CONFIG_HOME/crafter-review/env, else ~/.config/crafter-review/env:
one file for every repository on a machine, a repository's seats .env
winning over it. Each file is read once and the settings and the tokens
are taken from that read (SeatsFile::Text), so a file that can be read
only once - a pipe, `--env-file <(gpg -d seats.env.gpg)`, a FIFO - gives
its settings and its seats alike, and a failed read raises its own error
where the tokens are laid over the environment: SeatPool::WithFileTokens,
for `run` and `seats` alike, and LoadSeats takes the merged environment
and no longer reads a file by path. An empty `seats --env-file` means no file
now, as it did for `run`, and the `seats` report names the side that
runs first (it said "api seats run first" whatever the order).
Runs, Commands and KernelModes, the tests that run `run` and `seats`,
point XDG_CONFIG_HOME, and HOST_XDG_CONFIG_HOME for the Flatpak, at a
path of their own that nothing creates, so a global file stays out of
them; the grammar, the settings and their precedence, the lookup and the
one read have their tests, a run with `--env` (a prefix) and with a
repeated --env-file, and a `seats` with `--env`, take tokens and
settings from the one file, an application's .env and a venv are passed
over, a FIFO is read once, no line of the file reaches `stop`, every
listed placement setting moves a reader, another REVIEW_GATES_* line is
named and a .env of blank lines passed over, and the
README, the environment table and the procedure say the new rule.
2026-11-01 01:51:48 +01:00
// The seats file (2026-11-01): one dotenv grammar for the tokens and the
// REVIEW_GATES_* settings; the settings under the process environment in
// the map the placement readers take (SettingsOf), the process
// environment itself untouched; the file resolved as --env-file, then
// $SEATS_ENV_FILE, <cwd>/.env, the machine's own under $XDG_CONFIG_HOME,
// each read once.
{
const std : : vector < std : : pair < std : : string , std : : string > > lines =
Seats : : DotenvLines ( " export REVIEW_GATES_SEAT_ORDER='oauth-first' \n REVIEW_GATES_API_BUDGET_USD = \" 50 \" \n CLAUDE_CODE_OAUTH_TOKEN1=x \n # a comment \n not a line \n = \n REVIEW_GATES=nope \n " ) ;
const std : : map < std : : string , std : : string > settings = Seats : : SettingsFromEnvFile ( " export REVIEW_GATES_SEAT_ORDER='oauth-first' \n REVIEW_GATES_API_BUDGET_USD = \" 50 \" \n CLAUDE_CODE_OAUTH_TOKEN1=x \n REVIEW_GATES=nope \n " ) ;
Check ( " the dotenv grammar: `[export ]NAME=value`, blanks around `=` and the value, one pair of matching quotes stripped, everything else skipped; the settings are the REVIEW_GATES_ names; the tokens as before " ,
lines = = std : : vector < std : : pair < std : : string , std : : string > > { { " REVIEW_GATES_SEAT_ORDER " , " oauth-first " } , { " REVIEW_GATES_API_BUDGET_USD " , " 50 " } , { " CLAUDE_CODE_OAUTH_TOKEN1 " , " x " } , { " REVIEW_GATES " , " nope " } }
& & settings = = std : : map < std : : string , std : : string > { { " REVIEW_GATES_SEAT_ORDER " , " oauth-first " } , { " REVIEW_GATES_API_BUDGET_USD " , " 50 " } }
& & Seats : : SeatTokensFromEnvFile ( " ANTHROPIC_API_KEY=bare \n ANTHROPIC_API_KEY2=k \n ANTHROPIC_API_KEY2_GRANT_DAY=17 \n CLAUDE_CODE_OAUTH_TOKEN=t \n CLAUDE_CODE_OAUTH_TOKEN7=no \n " )
feat(seats): an API seat's cycle starts on its own grant day
The ledger reset every API seat's spend on one
REVIEW_GATES_API_CYCLE_DAY and cleared every credit-out, an OpenRouter
key's too, at that reset. Each API seat's cycle starts on its
ANTHROPIC_API_KEY<n>_GRANT_DAY now (1..31, a day past a month's end its
last), else the cycle day, also 1..31. A credit-out carries across the
rollover, and the run's probe tries a key held out on credit again, as
`seats` does an API key: an ok lifts the mark - an API key's is new
credits, its cycle restarting from the grant day, or from today when
that day is over a week back; an OpenRouter key keeps its cycle's spend,
and a key that answers with its cycle's budget spent stays out on that
budget. A probe that finds a key out of credit records it, unless the
ledger already has it out. Both are decided in one locked update on the
file's entry, a mark another driver made since the probe started
standing, and the ledger's stamps carry their UTC offset so marks are
ordered by instant.
`seats` shows the probe's reading beside the driver's verdict (the
`probe` and `driver` columns replace `state` and `ledger: out`), each
seat's grant day and when its next credits are due, and notes on what
the probe changed in the ledger or why the driver's verdict stands; the
run logs the days.
2026-11-02 13:58:29 +01:00
= = std : : map < std : : string , std : : string > { { " ANTHROPIC_API_KEY2 " , " k " } , { " ANTHROPIC_API_KEY2_GRANT_DAY " , " 17 " } , { " CLAUDE_CODE_OAUTH_TOKEN " , " t " } } ) ;
feat(seats): the env file's settings count, and a machine's own seats file
ApiConfig and PoolConfig read the seat order, the budgets and the
concurrency from the process environment alone, so a `.env` that said
REVIEW_GATES_SEAT_ORDER=oauth-first ordered nothing: the Python driver
reads those lines from the file under the process environment
(config_env, 2026-10-17: a setting lives beside the seats it orders).
SeatPool::SettingsOf does the same - the file's placement settings
under the process environment, in a map handed to the placement readers
alone (ApiConfig, PoolConfig, Seats::ConfigFromEnv) - and leaves the
process environment untouched, so no other reader sees a line of the
file: a path's or a binary's line reaches nothing, and two drivers
reading one .env keep one board and one ledger. The placement settings
are one list, SeatPool::PlacementSettings - the fifteen names those
readers read - for the map, the run's log and what makes a working
directory's .env a seats file; a REVIEW_GATES_* line of any other name
stays out of the map and is named, by the run's log and on `seats`'s
stderr. One dotenv grammar serves the tokens and the settings
(Seats::DotenvLines).
`run` and `seats` resolve the file from their own --env-file
(SeatPool::ResolveSeatsFile): the --env-file, else $SEATS_ENV_FILE, else
the working directory's .env - the operator's, as the Python driver and
`seats` read it, not the repository under review's - when it is a file
holding a seat or a placement setting, each with a value, or one that
cannot be read as UTF-8 text (its error is then the command's) - a
readable application .env, its Vite or Supabase lines, one of blank
placeholder lines or one that is no file is passed over, and the run
says so - else the machine's own
$XDG_CONFIG_HOME/crafter-review/env, else ~/.config/crafter-review/env:
one file for every repository on a machine, a repository's seats .env
winning over it. Each file is read once and the settings and the tokens
are taken from that read (SeatsFile::Text), so a file that can be read
only once - a pipe, `--env-file <(gpg -d seats.env.gpg)`, a FIFO - gives
its settings and its seats alike, and a failed read raises its own error
where the tokens are laid over the environment: SeatPool::WithFileTokens,
for `run` and `seats` alike, and LoadSeats takes the merged environment
and no longer reads a file by path. An empty `seats --env-file` means no file
now, as it did for `run`, and the `seats` report names the side that
runs first (it said "api seats run first" whatever the order).
Runs, Commands and KernelModes, the tests that run `run` and `seats`,
point XDG_CONFIG_HOME, and HOST_XDG_CONFIG_HOME for the Flatpak, at a
path of their own that nothing creates, so a global file stays out of
them; the grammar, the settings and their precedence, the lookup and the
one read have their tests, a run with `--env` (a prefix) and with a
repeated --env-file, and a `seats` with `--env`, take tokens and
settings from the one file, an application's .env and a venv are passed
over, a FIFO is read once, no line of the file reaches `stop`, every
listed placement setting moves a reader, another REVIEW_GATES_* line is
named and a .env of blank lines passed over, and the
README, the environment table and the procedure say the new rule.
2026-11-01 01:51:48 +01:00
const fs : : path envTd = fs : : temp_directory_path ( ) / std : : format ( " crafter-review-envfile-{} " , Platform : : PublishedPid ( ) ) ;
fs : : remove_all ( envTd ) ;
fs : : create_directories ( envTd / " repo " ) ;
fs : : create_directories ( envTd / " xdg " / " crafter-review " ) ;
std : : ofstream ( envTd / " settings.env " , std : : ios : : binary ) < < " REVIEW_GATES_SEAT_ORDER=oauth-first \n REVIEW_GATES_API_BUDGET_USD=50 \n REVIEW_GATES_CLAUDE_BIN=./evil \n REVIEW_GATES_SEAT_POLICY= \n " ;
unsetenv ( " REVIEW_GATES_SEAT_ORDER " ) ;
unsetenv ( " REVIEW_GATES_CLAUDE_BIN " ) ;
unsetenv ( " REVIEW_GATES_SEAT_POLICY " ) ;
setenv ( " REVIEW_GATES_API_BUDGET_USD " , " 75 " , 1 ) ;
const SeatPool : : Settings applied = SeatPool : : SettingsOf ( SeatPool : : ResolveSeatsFile ( ( envTd / " settings.env " ) . string ( ) , envTd / " repo " ) ) ;
const Json api = SeatPool : : ApiConfig ( applied . env ) ;
const SeatPool : : SeatsFile missing = SeatPool : : ResolveSeatsFile ( ( envTd / " none.env " ) . string ( ) , envTd / " repo " ) ;
std : : string raised ;
try {
( void ) missing . Text ( ) ;
} catch ( const Dyn : : Error & error ) {
raised = error . Kind ( ) ;
}
Check ( " SettingsOf: the file's placement settings under the process environment - the process environment wins - in the map ApiConfig reads, a blank one no setting, its other REVIEW_GATES_* "
" lines named and never in the map, the process environment itself untouched (no line of the file reaches another reader); no file gives nothing; one it cannot read gives nothing and Text() raises the "
" read's own error " ,
applied . fromFile = = std : : vector < std : : string > { " REVIEW_GATES_SEAT_ORDER " } & & applied . ignored = = std : : vector < std : : string > { " REVIEW_GATES_CLAUDE_BIN " }
& & ! applied . env . contains ( " REVIEW_GATES_CLAUDE_BIN " ) & & ! applied . env . contains ( " REVIEW_GATES_SEAT_POLICY " ) & & api . at ( " order " ) = = " oauth-first " & & api . at ( " budgetUsd " ) = = 75.0
& & ! Platform : : GetEnv ( " REVIEW_GATES_SEAT_ORDER " ) & & ! Platform : : GetEnv ( " REVIEW_GATES_CLAUDE_BIN " ) & & Platform : : GetEnv ( " REVIEW_GATES_API_BUDGET_USD " ) = = " 75 "
& & SeatPool : : SettingsOf ( SeatPool : : ResolveSeatsFile ( std : : string ( ) , envTd / " repo " ) ) . fromFile . empty ( ) & & SeatPool : : SettingsOf ( missing ) . fromFile . empty ( ) & & raised = = " FileNotFoundError " ,
feat(seats): an API seat's cycle starts on its own grant day
The ledger reset every API seat's spend on one
REVIEW_GATES_API_CYCLE_DAY and cleared every credit-out, an OpenRouter
key's too, at that reset. Each API seat's cycle starts on its
ANTHROPIC_API_KEY<n>_GRANT_DAY now (1..31, a day past a month's end its
last), else the cycle day, also 1..31. A credit-out carries across the
rollover, and the run's probe tries a key held out on credit again, as
`seats` does an API key: an ok lifts the mark - an API key's is new
credits, its cycle restarting from the grant day, or from today when
that day is over a week back; an OpenRouter key keeps its cycle's spend,
and a key that answers with its cycle's budget spent stays out on that
budget. A probe that finds a key out of credit records it, unless the
ledger already has it out. Both are decided in one locked update on the
file's entry, a mark another driver made since the probe started
standing, and the ledger's stamps carry their UTC offset so marks are
ordered by instant.
`seats` shows the probe's reading beside the driver's verdict (the
`probe` and `driver` columns replace `state` and `ledger: out`), each
seat's grant day and when its next credits are due, and notes on what
the probe changed in the ledger or why the driver's verdict stands; the
run logs the days.
2026-11-02 13:58:29 +01:00
std : : format ( " {} {} " , Dyn : : Str ( api ) , raised ) ) ;
feat(seats): the env file's settings count, and a machine's own seats file
ApiConfig and PoolConfig read the seat order, the budgets and the
concurrency from the process environment alone, so a `.env` that said
REVIEW_GATES_SEAT_ORDER=oauth-first ordered nothing: the Python driver
reads those lines from the file under the process environment
(config_env, 2026-10-17: a setting lives beside the seats it orders).
SeatPool::SettingsOf does the same - the file's placement settings
under the process environment, in a map handed to the placement readers
alone (ApiConfig, PoolConfig, Seats::ConfigFromEnv) - and leaves the
process environment untouched, so no other reader sees a line of the
file: a path's or a binary's line reaches nothing, and two drivers
reading one .env keep one board and one ledger. The placement settings
are one list, SeatPool::PlacementSettings - the fifteen names those
readers read - for the map, the run's log and what makes a working
directory's .env a seats file; a REVIEW_GATES_* line of any other name
stays out of the map and is named, by the run's log and on `seats`'s
stderr. One dotenv grammar serves the tokens and the settings
(Seats::DotenvLines).
`run` and `seats` resolve the file from their own --env-file
(SeatPool::ResolveSeatsFile): the --env-file, else $SEATS_ENV_FILE, else
the working directory's .env - the operator's, as the Python driver and
`seats` read it, not the repository under review's - when it is a file
holding a seat or a placement setting, each with a value, or one that
cannot be read as UTF-8 text (its error is then the command's) - a
readable application .env, its Vite or Supabase lines, one of blank
placeholder lines or one that is no file is passed over, and the run
says so - else the machine's own
$XDG_CONFIG_HOME/crafter-review/env, else ~/.config/crafter-review/env:
one file for every repository on a machine, a repository's seats .env
winning over it. Each file is read once and the settings and the tokens
are taken from that read (SeatsFile::Text), so a file that can be read
only once - a pipe, `--env-file <(gpg -d seats.env.gpg)`, a FIFO - gives
its settings and its seats alike, and a failed read raises its own error
where the tokens are laid over the environment: SeatPool::WithFileTokens,
for `run` and `seats` alike, and LoadSeats takes the merged environment
and no longer reads a file by path. An empty `seats --env-file` means no file
now, as it did for `run`, and the `seats` report names the side that
runs first (it said "api seats run first" whatever the order).
Runs, Commands and KernelModes, the tests that run `run` and `seats`,
point XDG_CONFIG_HOME, and HOST_XDG_CONFIG_HOME for the Flatpak, at a
path of their own that nothing creates, so a global file stays out of
them; the grammar, the settings and their precedence, the lookup and the
one read have their tests, a run with `--env` (a prefix) and with a
repeated --env-file, and a `seats` with `--env`, take tokens and
settings from the one file, an application's .env and a venv are passed
over, a FIFO is read once, no line of the file reaches `stop`, every
listed placement setting moves a reader, another REVIEW_GATES_* line is
named and a .env of blank lines passed over, and the
README, the environment table and the procedure say the new rule.
2026-11-01 01:51:48 +01:00
// Every name on the list moves a placement reader (the list is the
// readers' names, not a guess at them).
const Json apiDefault = SeatPool : : ApiConfig ( { } ) ;
const Json poolDefault = SeatPool : : PoolConfig ( { } , " xhigh " ) ;
std : : vector < std : : string > idle ;
for ( const std : : string_view name : SeatPool : : PlacementSettings ) {
const std : : string value = name . ends_with ( " SEAT_ORDER " ) ? " oauth-first " : name . ends_with ( " SEAT_POLICY " ) ? " pack " : " 3 " ;
const std : : map < std : : string , std : : string > one { { std : : string ( name ) , value } } ;
if ( Dyn : : Equal ( SeatPool : : ApiConfig ( one ) , apiDefault ) & & Dyn : : Equal ( SeatPool : : PoolConfig ( one , " xhigh " ) , poolDefault ) ) idle . emplace_back ( name ) ;
}
Check ( " PlacementSettings: every name on the list moves ApiConfig or PoolConfig (which takes Seats::ConfigFromEnv) " , idle . empty ( ) , Dyn : : Join ( idle , " , " ) ) ;
unsetenv ( " REVIEW_GATES_API_BUDGET_USD " ) ;
unsetenv ( " SEATS_ENV_FILE " ) ;
setenv ( " XDG_CONFIG_HOME " , ( envTd / " xdg " ) . string ( ) . c_str ( ) , 1 ) ;
const bool none = ! SeatPool : : ResolveSeatsFile ( std : : nullopt , envTd / " repo " ) . path & & ! SeatPool : : GlobalEnvFile ( ) ;
std : : ofstream ( envTd / " xdg " / " crafter-review " / " env " , std : : ios : : binary ) < < " REVIEW_GATES_SEAT_ORDER=oauth-first \n " ;
const std : : optional < fs : : path > global = SeatPool : : ResolveSeatsFile ( std : : nullopt , envTd / " repo " ) . path ;
// An application's .env (no seat, no placement setting), one whose only
// REVIEW_GATES_* line is no placement setting, one of blank placeholder
// lines (an empty token or setting is none), and a .env that is no
// file (a Python venv) are passed over and recorded so; one with a
// placement setting alone is a seats file, and so is one that is not
// UTF-8 (its error is the command's).
std : : ofstream ( envTd / " repo " / " .env " , std : : ios : : binary ) < < " VITE_API_URL=http://localhost:54321 \n SUPABASE_ANON_KEY=anon \n " ;
const SeatPool : : SeatsFile appFile = SeatPool : : ResolveSeatsFile ( std : : nullopt , envTd / " repo " ) ;
std : : ofstream ( envTd / " repo " / " .env " , std : : ios : : binary ) < < " REVIEW_GATES_SEAT_ORDER=api-first \n " ;
const std : : optional < fs : : path > settingsOnly = SeatPool : : ResolveSeatsFile ( std : : nullopt , envTd / " repo " ) . path ;
std : : ofstream ( envTd / " repo " / " .env " , std : : ios : : binary ) < < " REVIEW_GATES_SCRATCH=/elsewhere \n " ;
const SeatPool : : SeatsFile otherSetting = SeatPool : : ResolveSeatsFile ( std : : nullopt , envTd / " repo " ) ;
std : : ofstream ( envTd / " repo " / " .env " , std : : ios : : binary ) < < " CLAUDE_CODE_OAUTH_TOKEN1= \n ANTHROPIC_API_KEY1= \n OPENROUTER_KEY= \n REVIEW_GATES_SEAT_ORDER= \n " ;
const SeatPool : : SeatsFile blanks = SeatPool : : ResolveSeatsFile ( std : : nullopt , envTd / " repo " ) ;
std : : ofstream ( envTd / " repo " / " .env " , std : : ios : : binary ) < < std : : string ( " \xff \n " , 2 ) ;
const SeatPool : : SeatsFile notTextFile = SeatPool : : ResolveSeatsFile ( std : : nullopt , envTd / " repo " ) ;
fs : : remove ( envTd / " repo " / " .env " ) ;
fs : : create_directories ( envTd / " repo " / " .env " ) ;
const SeatPool : : SeatsFile venv = SeatPool : : ResolveSeatsFile ( std : : nullopt , envTd / " repo " ) ;
fs : : remove_all ( envTd / " repo " / " .env " ) ;
std : : ofstream ( envTd / " repo " / " .env " , std : : ios : : binary ) < < " CLAUDE_CODE_OAUTH_TOKEN1=x \n " ;
const SeatPool : : SeatsFile localFile = SeatPool : : ResolveSeatsFile ( std : : nullopt , envTd / " repo " ) ;
setenv ( " SEATS_ENV_FILE " , ( envTd / " settings.env " ) . string ( ) . c_str ( ) , 1 ) ;
const std : : optional < fs : : path > named = SeatPool : : ResolveSeatsFile ( std : : nullopt , envTd / " repo " ) . path ;
const std : : optional < fs : : path > given = SeatPool : : ResolveSeatsFile ( std : : string ( " explicit.env " ) , envTd / " repo " ) . path ;
const std : : optional < fs : : path > givenNone = SeatPool : : ResolveSeatsFile ( std : : string ( ) , envTd / " repo " ) . path ;
Check ( " the seats file resolves as --env-file (an empty one: none), else $SEATS_ENV_FILE, else <cwd>/.env when it is a file holding a seat or a placement setting with a value (an "
" application's .env, one whose only REVIEW_GATES_* line is no placement setting, one of blank lines, and a venv passed over and recorded so; one that is not UTF-8 taken, its read error kept), else $XDG_CONFIG_HOME/crafter-review/env, else none; the global file's settings reach SettingsOf " ,
none & & global = = envTd / " xdg " / " crafter-review " / " env " & & appFile . path = = global & & appFile . passedOver = = envTd / " repo " / " .env "
& & SeatPool : : SettingsOf ( appFile ) . fromFile = = std : : vector < std : : string > { " REVIEW_GATES_SEAT_ORDER " } & & settingsOnly = = envTd / " repo " / " .env " & & otherSetting . path = = global & & otherSetting . passedOver = = envTd / " repo " / " .env " & & blanks . path = = global & & blanks . passedOver = = envTd / " repo " / " .env "
& & notTextFile . path = = envTd / " repo " / " .env " & & notTextFile . error & & venv . path = = global & & venv . passedOver = = envTd / " repo " / " .env " & & ! venv . error
& & localFile . path = = envTd / " repo " / " .env " & & ! localFile . passedOver & & named = = envTd / " settings.env " & & given = = fs : : path ( " explicit.env " ) & & ! givenNone ) ;
unsetenv ( " SEATS_ENV_FILE " ) ;
unsetenv ( " XDG_CONFIG_HOME " ) ;
fs : : remove_all ( envTd ) ;
}
feat(seatpool): the seat pool and the board several drivers share
The seats of .env and the ledger, the probe, placement, settling a
finished pass, the child's credentials, the OpenRouter seats, and the
board every driver on the machine shares, in one shape and under one
lock. A driver is alive while its lifetime lock is held; with no lock file
natively its pid and start time decide, and in the sandbox it is taken for
alive.
:Http is the HTTP the driver needs, on FetchHTTP1: a status outside 2xx is
HttpError, every other failure carries a fixed text. :Platform gains
MakeDirs, with the last directory's own mode, and errno texts for its
writes and locks.
The tests cover the seat pool and several drivers at once, less the checks
that drive the pool's Scheduler, Admission and Stacks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 08:15:03 +01:00
fs : : remove_all ( td ) ;
return Failures = = 0 ? 0 : 1 ;
}