feat(seats): memory, the Playwright MCP config, and the seats library
:Memory: MemAvailable and the reserve policy, the sampler of a pass's peak
tree PSS (one sweep, a pause of three sweeps at least, stopped with the
driver), and the calibration file every driver on the machine shares,
re-read and written under its lock.
:Mcp: the pinned @playwright/mcp 0.0.83 arguments and the --mcp-config of
one pass, compact and in a fixed key order.
:Seats: the dotenv loader (token lines only, TOKEN7 inert), the one-word
probe (run under the supervisor, a missing binary reported with its errno
text), the window maths, the ranking, the Fable merge, the editor-bundle
lookup of the claude binary, the redaction of anything token-shaped, and
the report. This libc++ has no tzdb, so a zone by name converts through
the C library with TZ set, reading the system's zoneinfo.
tests/Seats: 92 checks against reference vectors, numbered in order, all
green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:32:14 +01:00
// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
module ;
# include <stdlib.h>
# include <time.h>
# include <unistd.h>
module Crafter . Review : Seats_impl ;
import : Seats ;
import : Json ;
import : Text ;
import : Stream ;
import : Platform ;
import : Process ;
import : Crypto ;
import std ;
namespace fs = std : : filesystem ;
namespace Crafter : : Review : : Seats {
namespace {
constexpr std : : array < std : : string_view , 7 > Weekdays = { " Mon " , " Tue " , " Wed " , " Thu " , " Fri " , " Sat " , " Sun " } ;
// en-GB, as Intl.DateTimeFormat abbreviates them (September is "Sept").
constexpr std : : array < std : : string_view , 12 > Months = { " Jan " , " Feb " , " Mar " , " Apr " , " May " , " Jun " , " Jul " , " Aug " , " Sept " , " Oct " , " Nov " , " Dec " } ;
constexpr std : : array < std : : string_view , 4 > ModelFamilies = { " fable " , " opus " , " sonnet " , " haiku " } ;
const std : : string & EnvOf ( const std : : map < std : : string , std : : string > & env , const std : : string & key ) {
static const std : : string none ;
const auto found = env . find ( key ) ;
return found = = env . end ( ) ? none : found - > second ;
}
double AsDouble ( const Json & value ) {
if ( value . is_number_float ( ) ) return value . get < double > ( ) ;
if ( value . is_boolean ( ) ) return value . get < bool > ( ) ? 1.0 : 0.0 ;
if ( value . is_number_unsigned ( ) ) return static_cast < double > ( value . get < std : : uint64_t > ( ) ) ;
if ( value . is_number_integer ( ) ) return static_cast < double > ( value . get < std : : int64_t > ( ) ) ;
return 0.0 ;
}
// The value as a float, or nullopt for one that is none.
std : : optional < double > FloatOf ( const Json & value ) {
if ( value . is_number ( ) | | value . is_boolean ( ) ) return AsDouble ( value ) ;
if ( value . is_string ( ) ) return Dyn : : ParseFloat ( value . get_ref < const std : : string & > ( ) ) ;
return std : : nullopt ;
}
// An integer when n is integral, else n.
Json IntIfWhole ( double n ) {
if ( std : : isfinite ( n ) & & n = = std : : floor ( n ) & & std : : fabs ( n ) < 9.0e18 ) return Json ( static_cast < std : : int64_t > ( n ) ) ;
return Json ( n ) ;
}
// A number field as a float, 0 when it is falsy.
double NumberOr0 ( const Json & value ) {
return Dyn : : Truthy ( value ) ? AsDouble ( value ) : 0.0 ;
}
bool Less ( const Json & a , const Json & b ) {
return AsDouble ( a ) < AsDouble ( b ) ;
}
// An ASCII literal, case-insensitive as re.I reads it, at `at`.
bool MatchCi ( std : : u32string_view text , std : : size_t at , std : : string_view word ) {
if ( at + word . size ( ) > text . size ( ) ) return false ;
for ( std : : size_t i = 0 ; i < word . size ( ) ; + + i ) {
const char p = word [ i ] ;
if ( p > = ' a ' & & p < = ' z ' ) {
if ( Dyn : : IgnoreCaseLetter ( text [ at + i ] ) ! = p ) return false ;
} else if ( text [ at + i ] ! = static_cast < char32_t > ( static_cast < std : : uint8_t > ( p ) ) ) {
return false ;
}
}
return true ;
}
bool ContainsCi ( std : : string_view text , std : : string_view word ) {
const std : : u32string decoded = Dyn : : Decode ( text ) ;
for ( std : : size_t at = 0 ; at + word . size ( ) < = decoded . size ( ) ; + + at ) {
if ( MatchCi ( decoded , at , word ) ) return true ;
}
return false ;
}
// seats.CREDIT_RE: the organization's credit balance is gone, or a
// spend limit was reached.
bool CreditText ( std : : string_view text ) {
constexpr std : : array < std : : string_view , 9 > Phrases = {
" credit balance too low " , " credit balance is too low " , " add funds " , " reached your api usage limits " , " reached your specified api usage limits " ,
" reached your workspace api usage limits " , " reached your specified workspace api usage limits " , " crossed its monthly api usage threshold " ,
" enforced_spend_limit_reached " ,
} ;
return std : : ranges : : any_of ( Phrases , [ & ] ( std : : string_view phrase ) { return ContainsCi ( text , phrase ) ; } ) ;
}
std : : string ResultText ( const Json & result ) {
return Dyn : : StrOr ( Dyn : : Get ( Dyn : : Or ( result , Dyn : : EmptyDict ( ) ) , " result " ) , " " ) ;
}
bool TokenChar ( char c ) {
return ( c > = ' A ' & & c < = ' Z ' ) | | ( c > = ' a ' & & c < = ' z ' ) | | ( c > = ' 0 ' & & c < = ' 9 ' ) | | c = = ' _ ' | | c = = ' - ' ;
}
std : : size_t RunOf ( std : : string_view s , std : : size_t at , const std : : function < bool ( char ) > & in ) {
std : : size_t end = at ;
while ( end < s . size ( ) & & in ( s [ end ] ) ) + + end ;
return end - at ;
}
// re.sub(pattern, replacement, text) for a pattern given as a matcher:
// the length of the match at a position, or 0.
std : : string SubAll ( std : : string_view text , const std : : function < std : : size_t ( std : : string_view , std : : size_t ) > & match , std : : string_view replacement ) {
std : : string out ;
std : : size_t at = 0 ;
while ( at < text . size ( ) ) {
const std : : size_t length = match ( text , at ) ;
if ( length > 0 ) {
out + = replacement ;
at + = length ;
} else {
out . push_back ( text [ at ] ) ;
+ + at ;
}
}
return out ;
}
// eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}
std : : size_t Jwt ( std : : string_view s , std : : size_t at ) {
if ( ! s . substr ( at ) . starts_with ( " eyJ " ) ) return 0 ;
std : : size_t i = at + 3 ;
for ( std : : int32_t part = 0 ; part < 3 ; + + part ) {
if ( part > 0 ) {
if ( i > = s . size ( ) | | s [ i ] ! = ' . ' ) return 0 ;
+ + i ;
}
const std : : size_t run = RunOf ( s , i , TokenChar ) ;
if ( run < 10 ) return 0 ;
i + = run ;
}
return i - at ;
}
// sk-ant-[A-Za-z0-9_-]{20,}
std : : size_t AnthropicKey ( std : : string_view s , std : : size_t at ) {
if ( ! s . substr ( at ) . starts_with ( " sk-ant- " ) ) return 0 ;
const std : : size_t run = RunOf ( s , at + 7 , TokenChar ) ;
return run > = 20 ? 7 + run : 0 ;
}
// Bearer\s+[A-Za-z0-9._~+/=-]{16,}
std : : size_t Bearer ( std : : string_view s , std : : size_t at ) {
if ( ! s . substr ( at ) . starts_with ( " Bearer " ) ) return 0 ;
const std : : size_t gap = Dyn : : SpaceRun ( s , at + 6 ) ;
if ( gap = = 0 ) return 0 ;
const std : : size_t run = RunOf ( s , at + 6 + gap , [ ] ( char c ) { return TokenChar ( c ) | | std : : string_view ( " ._~+/= " ) . contains ( c ) ; } ) ;
return run > = 16 ? 6 + gap + run : 0 ;
}
// [A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}, as the regex engine
// backs off: the local part runs up to the @; the domain is the
// longest prefix of its run that ends in a dot and two letters or more.
std : : size_t Email ( std : : string_view s , std : : size_t at ) {
auto local = [ ] ( char c ) { return ( c > = ' A ' & & c < = ' Z ' ) | | ( c > = ' a ' & & c < = ' z ' ) | | ( c > = ' 0 ' & & c < = ' 9 ' ) | | std : : string_view ( " ._%+- " ) . contains ( c ) ; } ;
auto domain = [ ] ( char c ) { return ( c > = ' A ' & & c < = ' Z ' ) | | ( c > = ' a ' & & c < = ' z ' ) | | ( c > = ' 0 ' & & c < = ' 9 ' ) | | c = = ' . ' | | c = = ' - ' ; } ;
auto letter = [ ] ( char c ) { return ( c > = ' A ' & & c < = ' Z ' ) | | ( c > = ' a ' & & c < = ' z ' ) ; } ;
const std : : size_t name = RunOf ( s , at , local ) ;
if ( name = = 0 | | at + name > = s . size ( ) | | s [ at + name ] ! = ' @ ' ) return 0 ;
const std : : size_t start = at + name + 1 ;
const std : : size_t run = RunOf ( s , start , domain ) ;
for ( std : : size_t k = run ; k - - > 1 ; ) {
if ( s [ start + k ] ! = ' . ' ) continue ;
const std : : size_t letters = RunOf ( s , start + k + 1 , letter ) ;
if ( letters > = 2 ) return name + 1 + k + 1 + letters ;
}
return 0 ;
}
// shutil.which(name, path=...): an executable file on the path.
std : : optional < std : : string > Which ( std : : string_view name , std : : string_view path ) {
for ( const std : : string & dir : Dyn : : Split ( path , " : " ) ) {
// An empty PATH entry gives the bare name.
const fs : : path candidate = dir . empty ( ) ? fs : : path ( name ) : fs : : path ( dir ) / name ;
std : : error_code error ;
if ( fs : : is_regular_file ( candidate , error ) & & access ( candidate . c_str ( ) , X_OK ) = = 0 ) return candidate . string ( ) ;
}
return std : : nullopt ;
}
// _version_key: claude-code-<major>.<minor>.<patch>.
std : : array < std : : int64_t , 3 > VersionKey ( std : : string_view name ) {
const std : : size_t at = name . find ( " claude-code- " ) ;
if ( at = = std : : string_view : : npos ) return { 0 , 0 , 0 } ;
for ( std : : size_t from = at ; from ! = std : : string_view : : npos ; from = name . find ( " claude-code- " , from + 1 ) ) {
std : : array < std : : int64_t , 3 > parts { } ;
std : : size_t i = from + 12 ;
bool ok = true ;
for ( std : : int32_t p = 0 ; p < 3 & & ok ; + + p ) {
if ( p > 0 ) {
if ( i > = name . size ( ) | | name [ i ] ! = ' . ' ) {
ok = false ;
break ;
}
+ + i ;
}
const std : : size_t digits = Dyn : : DecimalRun ( name , i ) ;
if ( digits = = 0 ) {
ok = false ;
break ;
}
parts [ static_cast < std : : size_t > ( p ) ] = Dyn : : ParseInt ( name . substr ( i , digits ) ) . value_or ( 0 ) ;
i + = digits ;
}
if ( ok ) return parts ;
}
return { 0 , 0 , 0 } ;
}
const Json & Window ( const Json & seat , std : : string_view key ) {
return Dyn : : Get ( Dyn : : Or ( Dyn : : Get ( seat , " windows " ) , Dyn : : EmptyDict ( ) ) , key ) ;
}
std : : string SeatName ( const Json & seat ) {
const Json & id = Dyn : : At ( seat , " seat " ) ;
return Dyn : : Equal ( id , Json ( 0 ) ) ? std : : string ( " local " ) : std : : format ( " seat {} " , Dyn : : Str ( id ) ) ;
}
std : : string SeatCell ( const Json & seat ) {
const Json & id = Dyn : : At ( seat , " seat " ) ;
return Dyn : : Equal ( id , Json ( 0 ) ) ? std : : string ( " local " ) : Dyn : : Str ( id ) ;
}
std : : int64_t Inflight ( const Json & board , const std : : map < std : : int32_t , std : : string > & keys , const Json & seat ) {
const auto key = keys . find ( Dyn : : At ( seat , " seat " ) . get < std : : int32_t > ( ) ) ;
if ( key = = keys . end ( ) | | ! board . is_object ( ) ) return 0 ;
const Json & record = Dyn : : Get ( Dyn : : Or ( Dyn : : Get ( board , " seats " ) , Dyn : : EmptyDict ( ) ) , key - > second ) ;
return static_cast < std : : int64_t > ( AsDouble ( Dyn : : Get ( Dyn : : Or ( record , Dyn : : EmptyDict ( ) ) , " inflight " ) ) ) ;
}
std : : vector < Json > SortedBySeat ( const std : : vector < Json > & seats ) {
std : : vector < Json > out = seats ;
std : : ranges : : stable_sort ( out , [ ] ( const Json & a , const Json & b ) { return Less ( Dyn : : At ( a , " seat " ) , Dyn : : At ( b , " seat " ) ) ; } ) ;
return out ;
}
}
double JsRound ( double x ) {
return std : : floor ( x + 0.5 ) ;
}
std : : string Fmt ( const Json & value ) {
if ( ( value . is_number ( ) | | value . is_boolean ( ) ) ) {
const double n = AsDouble ( value ) ;
if ( std : : isfinite ( n ) & & n = = std : : floor ( n ) ) return std : : to_string ( static_cast < std : : int64_t > ( n ) ) ;
}
return Dyn : : Str ( value ) ;
}
Json DefaultConfig ( ) {
return { { " maxUtil " , 85 } , { " lensCostPct " , 10 } , { " waitMaxMin " , 15 } , { " policy " , " spread " } , { " handoverPct " , 90 } } ;
}
Json ConfigFromEnv ( const std : : map < std : : string , std : : string > & env ) {
Json config = DefaultConfig ( ) ;
const Json defaults = DefaultConfig ( ) ;
for ( const auto & [ key , variable ] : std : : array < std : : pair < std : : string_view , std : : string_view > , 4 > { {
{ " maxUtil " , " REVIEW_GATES_SEAT_MAX_UTIL " } , { " lensCostPct " , " REVIEW_GATES_LENS_COST_PCT " } ,
{ " waitMaxMin " , " REVIEW_GATES_SEAT_WAIT_MIN " } , { " handoverPct " , " REVIEW_GATES_SEAT_HANDOVER_PCT " } } } ) {
const auto found = env . find ( std : : string ( variable ) ) ;
Json value = defaults . at ( std : : string ( key ) ) ;
if ( found ! = env . end ( ) ) {
const std : : optional < double > n = Dyn : : ParseFloat ( found - > second ) ;
if ( n & & ! Dyn : : Strip ( found - > second ) . empty ( ) & & std : : isfinite ( * n ) & & * n > = 0 ) value = IntIfWhole ( * n ) ;
}
config [ std : : string ( key ) ] = value ;
}
config [ " policy " ] = EnvOf ( env , " REVIEW_GATES_SEAT_POLICY " ) = = " pack " ? " pack " : " spread " ;
return config ;
}
std : : vector < std : : pair < std : : int32_t , std : : string > > SeatTokensFromEnv ( const std : : map < std : : string , std : : string > & env ) {
std : : vector < std : : pair < std : : int32_t , std : : string > > out ;
for ( std : : int32_t i = 1 ; i < = MaxSeats ; + + i ) {
std : : string token = Dyn : : Strip ( EnvOf ( env , std : : format ( " CLAUDE_CODE_OAUTH_TOKEN{} " , i ) ) ) ;
if ( token . empty ( ) & & i = = 1 ) token = Dyn : : Strip ( EnvOf ( env , " CLAUDE_CODE_OAUTH_TOKEN " ) ) ;
if ( ! token . empty ( ) ) out . emplace_back ( i , token ) ;
}
return out ;
}
std : : vector < std : : pair < std : : int32_t , std : : string > > ApiKeysFromEnv ( const std : : map < std : : string , std : : string > & env ) {
std : : vector < std : : pair < std : : int32_t , std : : string > > out ;
for ( std : : int32_t i = 1 ; i < = MaxSeats ; + + i ) {
const std : : string key = Dyn : : Strip ( EnvOf ( env , std : : format ( " ANTHROPIC_API_KEY{} " , i ) ) ) ;
if ( ! key . empty ( ) ) out . emplace_back ( i , key ) ;
}
return out ;
}
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 : : int32_t , std : : int32_t > ApiGrantDays ( const std : : map < std : : string , std : : string > & env ) {
std : : map < std : : int32_t , std : : int32_t > out ;
for ( std : : int32_t i = 1 ; i < = MaxSeats ; + + i ) {
// Decimal digits of any script; past 31 the value stays out of
// range.
const std : : u32string value = Dyn : : Decode ( Dyn : : Strip ( EnvOf ( env , std : : format ( " ANTHROPIC_API_KEY{}_GRANT_DAY " , i ) ) ) ) ;
if ( value . empty ( ) | | ! std : : ranges : : all_of ( value , [ ] ( char32_t c ) { return Dyn : : DecimalValue ( c ) > = 0 ; } ) ) continue ;
std : : int32_t day = 0 ;
for ( const char32_t c : value ) day = std : : min ( day * 10 + Dyn : : DecimalValue ( c ) , 32 ) ;
if ( day > = 1 & & day < = 31 ) out [ i ] = day ;
}
return out ;
}
feat(seats): memory, the Playwright MCP config, and the seats library
:Memory: MemAvailable and the reserve policy, the sampler of a pass's peak
tree PSS (one sweep, a pause of three sweeps at least, stopped with the
driver), and the calibration file every driver on the machine shares,
re-read and written under its lock.
:Mcp: the pinned @playwright/mcp 0.0.83 arguments and the --mcp-config of
one pass, compact and in a fixed key order.
:Seats: the dotenv loader (token lines only, TOKEN7 inert), the one-word
probe (run under the supervisor, a missing binary reported with its errno
text), the window maths, the ranking, the Fable merge, the editor-bundle
lookup of the claude binary, the redaction of anything token-shaped, and
the report. This libc++ has no tzdb, so a zone by name converts through
the C library with TZ set, reading the system's zoneinfo.
tests/Seats: 92 checks against reference vectors, numbered in order, all
green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:32:14 +01:00
std : : vector < std : : pair < std : : int32_t , std : : string > > OpenRouterKeysFromEnv ( const std : : map < std : : string , std : : string > & env ) {
std : : vector < std : : pair < std : : int32_t , std : : string > > out ;
for ( std : : int32_t i = 1 ; i < = MaxSeats ; + + i ) {
std : : string key = Dyn : : Strip ( EnvOf ( env , std : : format ( " OPENROUTER_KEY{} " , i ) ) ) ;
if ( key . empty ( ) & & i = = 1 ) key = Dyn : : Strip ( EnvOf ( env , " OPENROUTER_KEY " ) ) ;
if ( ! key . empty ( ) ) out . emplace_back ( i , key ) ;
}
return out ;
}
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 < std : : pair < std : : string , std : : string > > DotenvLines ( std : : string_view text ) {
std : : vector < std : : pair < std : : string , std : : string > > out ;
feat(seats): memory, the Playwright MCP config, and the seats library
:Memory: MemAvailable and the reserve policy, the sampler of a pass's peak
tree PSS (one sweep, a pause of three sweeps at least, stopped with the
driver), and the calibration file every driver on the machine shares,
re-read and written under its lock.
:Mcp: the pinned @playwright/mcp 0.0.83 arguments and the --mcp-config of
one pass, compact and in a fixed key order.
:Seats: the dotenv loader (token lines only, TOKEN7 inert), the one-word
probe (run under the supervisor, a missing binary reported with its errno
text), the window maths, the ranking, the Fable merge, the editor-bundle
lookup of the claude binary, the redaction of anything token-shaped, and
the report. This libc++ has no tzdb, so a zone by name converts through
the C library with TZ set, reading the system's zoneinfo.
tests/Seats: 92 checks against reference vectors, numbered in order, all
green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:32:14 +01:00
for ( const std : : string & raw : Dyn : : Split ( text , " \n " ) ) {
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
// ^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*$
feat(seats): memory, the Playwright MCP config, and the seats library
:Memory: MemAvailable and the reserve policy, the sampler of a pass's peak
tree PSS (one sweep, a pause of three sweeps at least, stopped with the
driver), and the calibration file every driver on the machine shares,
re-read and written under its lock.
:Mcp: the pinned @playwright/mcp 0.0.83 arguments and the --mcp-config of
one pass, compact and in a fixed key order.
:Seats: the dotenv loader (token lines only, TOKEN7 inert), the one-word
probe (run under the supervisor, a missing binary reported with its errno
text), the window maths, the ranking, the Fable merge, the editor-bundle
lookup of the claude binary, the redaction of anything token-shaped, and
the report. This libc++ has no tzdb, so a zone by name converts through
the C library with TZ set, reading the system's zoneinfo.
tests/Seats: 92 checks against reference vectors, numbered in order, all
green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:32:14 +01:00
std : : string_view line ( raw ) ;
std : : size_t at = Dyn : : SpaceRun ( line , 0 ) ;
if ( line . substr ( at ) . starts_with ( " export " ) ) {
const std : : size_t gap = Dyn : : SpaceRun ( line , at + 6 ) ;
if ( gap > 0 ) at + = 6 + gap ;
}
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
auto nameChar = [ ] ( char c , bool first ) {
return ( c > = ' A ' & & c < = ' Z ' ) | | ( c > = ' a ' & & c < = ' z ' ) | | c = = ' _ ' | | ( ! first & & c > = ' 0 ' & & c < = ' 9 ' ) ;
} ;
std : : size_t end = at ;
while ( end < line . size ( ) & & nameChar ( line [ end ] , end = = at ) ) + + end ;
if ( end = = at ) continue ;
const std : : string name ( line . substr ( at , end - at ) ) ;
at = end + Dyn : : SpaceRun ( line , end ) ;
feat(seats): memory, the Playwright MCP config, and the seats library
:Memory: MemAvailable and the reserve policy, the sampler of a pass's peak
tree PSS (one sweep, a pause of three sweeps at least, stopped with the
driver), and the calibration file every driver on the machine shares,
re-read and written under its lock.
:Mcp: the pinned @playwright/mcp 0.0.83 arguments and the --mcp-config of
one pass, compact and in a fixed key order.
:Seats: the dotenv loader (token lines only, TOKEN7 inert), the one-word
probe (run under the supervisor, a missing binary reported with its errno
text), the window maths, the ranking, the Fable merge, the editor-bundle
lookup of the claude binary, the redaction of anything token-shaped, and
the report. This libc++ has no tzdb, so a zone by name converts through
the C library with TZ set, reading the system's zoneinfo.
tests/Seats: 92 checks against reference vectors, numbered in order, all
green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:32:14 +01:00
if ( at > = line . size ( ) | | line [ at ] ! = ' = ' ) continue ;
+ + at ;
at + = Dyn : : SpaceRun ( line , at ) ;
std : : string value = Dyn : : RStrip ( line . substr ( at ) ) ;
if ( value . size ( ) > = 2 & & ( value . front ( ) = = ' " ' | | value . front ( ) = = ' \' ' ) & & value . back ( ) = = value . front ( ) ) value = value . substr ( 1 , value . size ( ) - 2 ) ;
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
out . emplace_back ( name , std : : move ( value ) ) ;
}
return out ;
}
std : : map < std : : string , std : : string > SeatTokensFromEnvFile ( std : : string_view text ) {
std : : map < std : : string , std : : string > env ;
for ( const auto & [ name , value ] : DotenvLines ( text ) ) {
for ( const std : : string_view stem : { std : : string_view ( " CLAUDE_CODE_OAUTH_TOKEN " ) , std : : string_view ( " ANTHROPIC_API_KEY " ) , std : : string_view ( " OPENROUTER_KEY " ) } ) {
if ( ! name . starts_with ( stem ) ) continue ;
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 : : string_view rest = std : : string_view ( name ) . substr ( stem . size ( ) ) ;
// ANTHROPIC_API_KEY<n>_GRANT_DAY: the seat's grant day.
if ( stem = = " ANTHROPIC_API_KEY " & & rest . size ( ) = = 11 & & rest . ends_with ( " _GRANT_DAY " ) ) rest = rest . substr ( 0 , 1 ) ;
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 bool digit = rest . size ( ) = = 1 & & rest [ 0 ] > = ' 1 ' & & rest [ 0 ] < = ' 6 ' ;
if ( ! rest . empty ( ) & & ! digit ) break ;
if ( stem = = " ANTHROPIC_API_KEY " & & ! digit ) break ;
env [ name ] = value ;
break ;
}
feat(seats): memory, the Playwright MCP config, and the seats library
:Memory: MemAvailable and the reserve policy, the sampler of a pass's peak
tree PSS (one sweep, a pause of three sweeps at least, stopped with the
driver), and the calibration file every driver on the machine shares,
re-read and written under its lock.
:Mcp: the pinned @playwright/mcp 0.0.83 arguments and the --mcp-config of
one pass, compact and in a fixed key order.
:Seats: the dotenv loader (token lines only, TOKEN7 inert), the one-word
probe (run under the supervisor, a missing binary reported with its errno
text), the window maths, the ranking, the Fable merge, the editor-bundle
lookup of the claude binary, the redaction of anything token-shaped, and
the report. This libc++ has no tzdb, so a zone by name converts through
the C library with TZ set, reading the system's zoneinfo.
tests/Seats: 92 checks against reference vectors, numbered in order, all
green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:32:14 +01:00
}
return env ;
}
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 : : map < std : : string , std : : string > SettingsFromEnvFile ( std : : string_view text ) {
std : : map < std : : string , std : : string > out ;
for ( const auto & [ name , value ] : DotenvLines ( text ) ) {
if ( name . starts_with ( " REVIEW_GATES_ " ) ) out [ name ] = value ;
}
return out ;
}
feat(seats): memory, the Playwright MCP config, and the seats library
:Memory: MemAvailable and the reserve policy, the sampler of a pass's peak
tree PSS (one sweep, a pause of three sweeps at least, stopped with the
driver), and the calibration file every driver on the machine shares,
re-read and written under its lock.
:Mcp: the pinned @playwright/mcp 0.0.83 arguments and the --mcp-config of
one pass, compact and in a fixed key order.
:Seats: the dotenv loader (token lines only, TOKEN7 inert), the one-word
probe (run under the supervisor, a missing binary reported with its errno
text), the window maths, the ranking, the Fable merge, the editor-bundle
lookup of the claude binary, the redaction of anything token-shaped, and
the report. This libc++ has no tzdb, so a zone by name converts through
the C library with TZ set, reading the system's zoneinfo.
tests/Seats: 92 checks against reference vectors, numbered in order, all
green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:32:14 +01:00
Json Pct ( const Json & utilization ) {
const std : : optional < double > n = FloatOf ( utilization ) ;
if ( ! n | | ! std : : isfinite ( * n ) | | * n < 0 ) return 0 ;
return IntIfWhole ( JsRound ( * n * 1000 ) / 10 ) ;
}
namespace {
std : : int64_t IntOf ( const Json & value ) {
const std : : optional < double > n = FloatOf ( value ) ;
if ( ! n | | ! std : : isfinite ( * n ) ) return 0 ;
return static_cast < std : : int64_t > ( * n ) ;
}
}
Json ParseRateLimitInfo ( const Json & raw ) {
if ( ! raw . is_object ( ) ) return nullptr ;
Json windows = Json : : object ( ) ;
const Json & unified = Dyn : : Get ( raw , " unifiedWindows " ) ;
if ( unified . is_object ( ) ) {
for ( auto it = unified . begin ( ) ; it ! = unified . end ( ) ; + + it ) {
if ( ! it . value ( ) . is_object ( ) ) continue ;
windows [ it . key ( ) ] = { { " utilization " , Pct ( Dyn : : Get ( it . value ( ) , " utilization " ) ) } , { " resetsAt " , IntOf ( Dyn : : Get ( it . value ( ) , " resetsAt " ) ) } } ;
}
}
const std : : int64_t resets = IntOf ( Dyn : : Get ( raw , " resetsAt " ) ) ;
return {
{ " status " , Dyn : : StrOr ( Dyn : : Get ( raw , " status " ) , " " ) } ,
{ " rateLimitType " , Dyn : : Truthy ( Dyn : : Get ( raw , " rateLimitType " ) ) ? Json ( Dyn : : Str ( Dyn : : At ( raw , " rateLimitType " ) ) ) : Json ( ) } ,
{ " resetsAt " , resets ? Json ( resets ) : Json ( ) } ,
{ " windows " , std : : move ( windows ) } ,
// overageDisabledReason, e.g. out_of_credits: a limit is a hard 429,
// not a charge.
{ " overageReason " , Dyn : : Truthy ( Dyn : : Get ( raw , " overageDisabledReason " ) ) ? Json ( Dyn : : Str ( Dyn : : At ( raw , " overageDisabledReason " ) ) ) : Json ( ) } ,
} ;
}
Json ParseStream ( std : : string_view text ) {
Json result ;
Json rate ;
Json session ;
if ( Dyn : : Strip ( text ) . empty ( ) ) return { { " result " , nullptr } , { " rateLimit " , nullptr } , { " sessionId " , nullptr } } ;
for ( const std : : string & raw : Dyn : : Split ( text , " \n " ) ) {
const std : : string line = Dyn : : Strip ( raw ) ;
if ( line . empty ( ) ) continue ;
Json o ;
try {
o = ParseLoose ( line ) ;
} catch ( const std : : exception & ) {
continue ;
}
if ( ! o . is_object ( ) ) continue ;
const Json & id = Dyn : : Get ( o , " session_id " ) ;
if ( ! Dyn : : Truthy ( session ) & & id . is_string ( ) ) {
const std : : string & value = id . get_ref < const std : : string & > ( ) ;
const bool shaped = value . size ( ) = = 36 & & std : : ranges : : all_of ( value , [ ] ( char c ) { return ( c > = ' 0 ' & & c < = ' 9 ' ) | | ( c > = ' a ' & & c < = ' f ' ) | | ( c > = ' A ' & & c < = ' F ' ) | | c = = ' - ' ; } ) ;
if ( shaped ) session = id ;
}
if ( Dyn : : Get ( o , " type " ) = = " result " ) {
result = o ;
} else if ( Dyn : : Get ( o , " type " ) = = " rate_limit_event " ) {
const Json parsed = ParseRateLimitInfo ( Dyn : : Get ( o , " rate_limit_info " ) ) ;
if ( Dyn : : Truthy ( parsed ) ) rate = parsed ;
}
}
return { { " result " , result } , { " rateLimit " , rate } , { " sessionId " , session } } ;
}
std : : vector < std : : string > ProbeArgs ( std : : string_view model ) {
return { " --print " , " ok " , " --system-prompt " , " Reply ok. " , " --model " , std : : string ( model ) , " --max-turns " , " 1 " , " --tools " , " " ,
" --strict-mcp-config " , " --disable-slash-commands " , " --output-format " , " stream-json " , " --verbose " } ;
}
std : : map < std : : string , std : : string > ProbeEnv ( std : : string_view token , const std : : string & configDir , const std : : map < std : : string , std : : string > & base ) {
const std : : string & home = EnvOf ( base , " HOME " ) ;
return {
{ " PATH " , EnvOf ( base , " PATH " ) } ,
{ " HOME " , home . empty ( ) ? fs : : temp_directory_path ( ) . string ( ) : home } ,
{ " CLAUDE_CONFIG_DIR " , configDir } ,
{ " CLAUDE_CODE_OAUTH_TOKEN " , std : : string ( token ) } ,
{ " MAX_THINKING_TOKENS " , " 0 " } ,
{ " CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC " , " 1 " } ,
{ " DISABLE_AUTOUPDATER " , " 1 " } ,
} ;
}
std : : map < std : : string , std : : string > LocalEnv ( const std : : map < std : : string , std : : string > & base ) {
std : : map < std : : string , std : : string > env = base ;
for ( const std : : string_view key : { " CLAUDE_CODE_OAUTH_TOKEN " , " ANTHROPIC_API_KEY " , " ANTHROPIC_AUTH_TOKEN " } ) env . erase ( std : : string ( key ) ) ;
env [ " MAX_THINKING_TOKENS " ] = " 0 " ;
env [ " CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC " ] = " 1 " ;
env [ " DISABLE_AUTOUPDATER " ] = " 1 " ;
return env ;
}
fs : : path WriteApiKeyApproval ( const fs : : path & configDir , std : : string_view key ) {
const fs : : path path = configDir / " .claude.json " ;
if ( fs : : exists ( path ) ) return path ;
const std : : size_t length = Dyn : : Length ( key ) ;
const std : : string tail = Dyn : : Slice ( key , static_cast < std : : int64_t > ( length ) - std : : min < std : : int64_t > ( 20 , static_cast < std : : int64_t > ( length ) ) ) ;
const Json approval = { { " hasCompletedOnboarding " , true } , { " customApiKeyResponses " , { { " approved " , { tail } } , { " rejected " , Json : : array ( ) } } } } ;
2026-10-31 16:45:53 +01:00
// Two passes of a fresh seat write it in the same instant. Written
// whole under another name, then linked into place, which fails when
// the file is there: the one that loses leaves the other's, and with
// it whatever claude has written to it since.
feat(seats): memory, the Playwright MCP config, and the seats library
:Memory: MemAvailable and the reserve policy, the sampler of a pass's peak
tree PSS (one sweep, a pause of three sweeps at least, stopped with the
driver), and the calibration file every driver on the machine shares,
re-read and written under its lock.
:Mcp: the pinned @playwright/mcp 0.0.83 arguments and the --mcp-config of
one pass, compact and in a fixed key order.
:Seats: the dotenv loader (token lines only, TOKEN7 inert), the one-word
probe (run under the supervisor, a missing binary reported with its errno
text), the window maths, the ranking, the Fable merge, the editor-bundle
lookup of the claude binary, the redaction of anything token-shaped, and
the report. This libc++ has no tzdb, so a zone by name converts through
the C library with TZ set, reading the system's zoneinfo.
tests/Seats: 92 checks against reference vectors, numbered in order, all
green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:32:14 +01:00
const fs : : path temp = std : : format ( " {}.{}.{}.tmp " , path . string ( ) , Platform : : PublishedPid ( ) , TokenHex ( 4 ) ) ;
{
std : : ofstream out ( temp , std : : ios : : binary ) ;
out < < DumpSpaced ( approval ) ;
}
fs : : permissions ( temp , fs : : perms : : owner_read | fs : : perms : : owner_write , fs : : perm_options : : replace ) ;
std : : error_code error ;
2026-10-31 16:45:53 +01:00
link ( temp . c_str ( ) , path . c_str ( ) ) ;
feat(seats): memory, the Playwright MCP config, and the seats library
:Memory: MemAvailable and the reserve policy, the sampler of a pass's peak
tree PSS (one sweep, a pause of three sweeps at least, stopped with the
driver), and the calibration file every driver on the machine shares,
re-read and written under its lock.
:Mcp: the pinned @playwright/mcp 0.0.83 arguments and the --mcp-config of
one pass, compact and in a fixed key order.
:Seats: the dotenv loader (token lines only, TOKEN7 inert), the one-word
probe (run under the supervisor, a missing binary reported with its errno
text), the window maths, the ranking, the Fable merge, the editor-bundle
lookup of the claude binary, the redaction of anything token-shaped, and
the report. This libc++ has no tzdb, so a zone by name converts through
the C library with TZ set, reading the system's zoneinfo.
tests/Seats: 92 checks against reference vectors, numbered in order, all
green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:32:14 +01:00
fs : : remove ( temp , error ) ;
return path ;
}
std : : map < std : : string , std : : string > ApiEnv ( std : : string_view key , const std : : string & configDir , const std : : map < std : : string , std : : string > & base ) {
// Minimal by construction: no CLAUDE_CODE_ENTRYPOINT of a launcher (it
// turns the subscriber credits' answer into "Credit balance is too
// low").
std : : map < std : : string , std : : string > env = ProbeEnv ( " " , configDir , base ) ;
env . erase ( " CLAUDE_CODE_OAUTH_TOKEN " ) ;
env [ " ANTHROPIC_API_KEY " ] = std : : string ( key ) ;
WriteApiKeyApproval ( configDir , key ) ;
return env ;
}
bool LooksLikeCreditExhaustion ( const Json & result , std : : string_view text ) {
return CreditText ( ResultText ( result ) ) | | CreditText ( text ) ;
}
bool LooksLikeAuthFailure ( const Json & result , std : : string_view text ) {
const Json & status = Dyn : : Get ( Dyn : : Or ( result , Dyn : : EmptyDict ( ) ) , " api_error_status " ) ;
if ( Dyn : : Equal ( status , Json ( 401 ) ) | | Dyn : : Equal ( status , Json ( 403 ) ) ) return true ;
return Stream : : AuthText ( ResultText ( result ) ) | | Stream : : AuthText ( text ) ;
}
std : : string ClipReason ( std : : string_view input , std : : span < const std : : string > secrets ) {
std : : string s ( input ) ;
for ( const std : : string & secret : secrets ) {
if ( ! secret . empty ( ) ) s = Dyn : : Replace ( s , secret , " [redacted:token] " ) ;
}
s = SubAll ( s , Jwt , " [redacted:jwt] " ) ;
s = SubAll ( s , AnthropicKey , " [redacted:token] " ) ;
s = SubAll ( s , Bearer , " Bearer [redacted] " ) ;
s = SubAll ( s , Email , " [redacted:email] " ) ;
// re.sub(r'\s+', ' ', s).strip()[:160]
std : : string collapsed ;
for ( std : : size_t at = 0 ; at < s . size ( ) ; ) {
const std : : size_t gap = Dyn : : SpaceRun ( s , at ) ;
if ( gap > 0 ) {
collapsed . push_back ( ' ' ) ;
at + = gap ;
continue ;
}
const std : : size_t used = Dyn : : CodePointAt ( s , at ) . second ;
collapsed . append ( s , at , used ) ;
at + = used ;
}
return Dyn : : Slice ( Dyn : : Strip ( collapsed ) , 0 , 160 ) ;
}
Json ProbeSeat ( std : : int32_t seat , const std : : string & token , const ProbeOptions & options ) {
const std : : string claude = options . claudeBin . empty ( ) ? FindClaudeBin ( ) : options . claudeBin ;
Json base = { { " seat " , seat } , { " probedWith " , options . model } , { " windows " , Json : : object ( ) } } ;
auto with = [ & ] ( Json extra ) {
Json out = base ;
for ( auto it = extra . begin ( ) ; it ! = extra . end ( ) ; + + it ) out [ it . key ( ) ] = it . value ( ) ;
return out ;
} ;
const std : : vector < std : : string > secrets = { token } ;
std : : optional < fs : : path > configDir ;
if ( ! options . local ) {
for ( ; ; ) {
configDir = fs : : temp_directory_path ( ) / std : : format ( " rg-seat-{}-{} " , seat , TokenHex ( 4 ) ) ;
if ( fs : : create_directory ( * configDir ) ) break ;
}
fs : : permissions ( * configDir , fs : : perms : : owner_all , fs : : perm_options : : replace ) ;
}
const std : : map < std : : string , std : : string > parent = Platform : : Environment ( ) ;
const std : : map < std : : string , std : : string > env = options . local ? LocalEnv ( parent ) : ( options . api ? ApiEnv ( token , configDir - > string ( ) , parent ) : ProbeEnv ( token , configDir - > string ( ) , parent ) ) ;
std : : vector < std : : string > argv = { claude } ;
std : : ranges : : move ( ProbeArgs ( options . model ) , std : : back_inserter ( argv ) ) ;
if ( options . local ) {
argv . emplace_back ( " --setting-sources " ) ;
argv . emplace_back ( " " ) ;
argv . emplace_back ( " --no-session-persistence " ) ;
}
auto cleanup = [ & ] {
std : : error_code error ;
if ( configDir ) fs : : remove_all ( * configDir , error ) ;
} ;
// A binary that cannot be started is said here, as an OSError, before
// the supervisor would only report it as an exit code.
const std : : string path = claude . contains ( ' / ' ) ? claude : Which ( claude , EnvOf ( env , " PATH " ) ) . value_or ( " " ) ;
if ( path . empty ( ) | | access ( path . c_str ( ) , X_OK ) ! = 0 ) {
cleanup ( ) ;
return with ( { { " state " , " unknown " } , { " error " , ClipReason ( std : : format ( " probe spawn failed: {}: {} " , Dyn : : ErrnoText ( 2 ) , Dyn : : Repr ( claude ) ) , secrets ) } } ) ;
}
Process : : Captured run ;
try {
run = Process : : Run ( Process : : Supervised ( argv ) , std : : nullopt , std : : chrono : : milliseconds ( static_cast < std : : int64_t > ( options . timeoutS * 1000 ) ) , { } , env ) ;
} catch ( const std : : exception & error ) {
cleanup ( ) ;
return with ( { { " state " , " unknown " } , { " error " , ClipReason ( std : : format ( " probe spawn failed: {} " , error . what ( ) ) , secrets ) } } ) ;
}
cleanup ( ) ;
if ( run . timedOut ) return with ( { { " state " , " unknown " } , { " error " , std : : format ( " probe timeout after {} ms " , static_cast < std : : int64_t > ( options . timeoutS * 1000 ) ) } } ) ;
const std : : string out = Dyn : : UniversalNewlines ( Dyn : : DecodeReplace ( run . out ) ) ;
const std : : string err = Dyn : : UniversalNewlines ( Dyn : : DecodeReplace ( run . err ) ) ;
const std : : int32_t code = Process : : SupervisedReturnCode ( run . returnCode ) ;
const Json parsed = ParseStream ( out ) ;
const Json & rate = parsed . at ( " rateLimit " ) ;
const Json & result = parsed . at ( " result " ) ;
const Json cost = Dyn : : Get ( Dyn : : Or ( result , Dyn : : EmptyDict ( ) ) , " total_cost_usd " ) ;
auto said = [ & ] ( std : : string_view fallback ) {
const std : : string text = ResultText ( result ) ;
return ! text . empty ( ) ? text : ( ! err . empty ( ) ? err : std : : string ( fallback ) ) ;
} ;
if ( options . api ) {
// No rate windows on a Console key: the probe's result line is the
// whole reading.
if ( Dyn : : Truthy ( result ) & & ! Dyn : : Truthy ( Dyn : : Get ( result , " is_error " ) ) ) return with ( { { " state " , " ok " } , { " costUsd " , cost } } ) ;
if ( LooksLikeCreditExhaustion ( result , err ) ) return with ( { { " state " , " out " } , { " error " , ClipReason ( said ( " credit balance too low " ) , secrets ) } } ) ;
if ( LooksLikeAuthFailure ( result , err ) ) return with ( { { " state " , " invalid " } , { " error " , ClipReason ( said ( " authentication failed " ) , secrets ) } } ) ;
return with ( { { " state " , " unknown " } , { " error " , ClipReason ( std : : format ( " probe failed (exit {}) { } " , code, said( " " )), secrets)}});
}
if ( Dyn : : Truthy ( rate ) & & Dyn : : Truthy ( rate . at ( " windows " ) ) ) {
const auto [ util , binding ] = SeatUtil ( rate . at ( " windows " ) ) ;
Json resets = Dyn : : Get ( Dyn : : Or ( Dyn : : Get ( rate . at ( " windows " ) , " five_hour " ) , Dyn : : EmptyDict ( ) ) , " resetsAt " ) ;
if ( ! Dyn : : Truthy ( resets ) ) resets = Dyn : : Get ( rate , " resetsAt " ) ;
if ( rate . at ( " status " ) = = " rejected " ) {
// The one-word probe was refused: the seat takes nothing until
// its reset, whatever its windows read.
std : : string why = std : : format ( " {} rejected " , Dyn : : StrOr ( Dyn : : Get ( rate , " rateLimitType " ) , " window " ) ) ;
if ( Dyn : : Truthy ( Dyn : : Get ( rate , " overageReason " ) ) ) why + = std : : format ( " , overage {} " , Dyn : : Str ( rate . at ( " overageReason " ) ) ) ;
const Json limitedUtil = AsDouble ( util ) > 100 ? util : Json ( 100 ) ;
return with ( { { " state " , " limited " } , { " windows " , rate . at ( " windows " ) } , { " util " , limitedUtil } ,
{ " binding " , Dyn : : Truthy ( Dyn : : Get ( rate , " rateLimitType " ) ) ? rate . at ( " rateLimitType " ) : Json ( binding ) } , { " resetsAt " , resets } , { " error " , why } } ) ;
}
return with ( { { " state " , " ok " } , { " windows " , rate . at ( " windows " ) } , { " util " , util } , { " binding " , binding } , { " resetsAt " , resets } } ) ;
}
if ( LooksLikeAuthFailure ( result , err ) ) return with ( { { " state " , " invalid " } , { " error " , ClipReason ( said ( " authentication failed " ) , secrets ) } } ) ;
return with ( { { " state " , " unknown " } , { " error " , ClipReason ( std : : format ( " no rate_limit_event (exit {}) { } " , code, said( " " )), secrets)}});
}
double Quantize ( double util ) {
return JsRound ( util / RankQuantum ) * RankQuantum ;
}
std : : pair < Json , std : : string > BindingWindow ( const Json & windows ) {
Json util = 0 ;
std : : string binding ;
for ( auto it = windows . begin ( ) ; it ! = windows . end ( ) ; + + it ) {
const Json & value = Dyn : : At ( it . value ( ) , " utilization " ) ;
if ( Less ( util , value ) | | binding . empty ( ) ) {
util = value ;
binding = it . key ( ) ;
}
}
return { util , binding } ;
}
std : : pair < Json , std : : string > SeatUtil ( const Json & windows ) {
const auto [ util , binding ] = BindingWindow ( windows ) ;
return { Json ( static_cast < std : : int64_t > ( Quantize ( AsDouble ( util ) ) ) ) , binding } ;
}
std : : string ModelFamily ( std : : string_view model ) {
const std : : u32string text = Dyn : : Decode ( model ) ;
for ( std : : size_t at = 0 ; at < text . size ( ) ; + + at ) {
for ( const std : : string_view family : ModelFamilies ) {
if ( MatchCi ( text , at , family ) ) return std : : string ( family ) ;
}
}
return " " ;
}
bool IsFableWindow ( std : : string_view key ) {
return key = = FableWindow | | ModelFamily ( key ) = = " fable " ;
}
const Json * FableWindowOf ( const Json & seat ) {
const Json & windows = Dyn : : Or ( Dyn : : Get ( seat , " windows " ) , Dyn : : EmptyDict ( ) ) ;
for ( auto it = windows . begin ( ) ; it ! = windows . end ( ) ; + + it ) {
if ( IsFableWindow ( it . key ( ) ) ) return & it . value ( ) ;
}
return nullptr ;
}
bool LongWindowsOk ( const Json & seat ) {
const Json & windows = Dyn : : Or ( Dyn : : Get ( seat , " windows " ) , Dyn : : EmptyDict ( ) ) ;
for ( auto it = windows . begin ( ) ; it ! = windows . end ( ) ; + + it ) {
if ( it . key ( ) = = " five_hour " | | IsFableWindow ( it . key ( ) ) ) continue ;
if ( AsDouble ( Dyn : : At ( it . value ( ) , " utilization " ) ) > = LongWindowCutoff ) return false ;
}
return true ;
}
bool IsEligible ( const Json & seat , const Json & config ) {
return Dyn : : At ( seat , " state " ) = = " ok " & & NumberOr0 ( Dyn : : Get ( seat , " util " ) ) < = AsDouble ( config . at ( " maxUtil " ) ) & & LongWindowsOk ( seat ) ;
}
bool FableOpen ( const Json & seat , const Json & config ) {
const Json & fable = Dyn : : Or ( Dyn : : Get ( seat , " fable " ) , Dyn : : EmptyDict ( ) ) ;
if ( Dyn : : Get ( fable , " state " ) = = " limited " | | ( Dyn : : At ( seat , " state " ) = = " limited " & & IsFableWindow ( Dyn : : StrOr ( Dyn : : Get ( seat , " binding " ) , " " ) ) ) ) return false ;
const Json * w = FableWindowOf ( seat ) ;
if ( ! w ) return true ;
const double u = AsDouble ( Dyn : : At ( * w , " utilization " ) ) ;
return u < = AsDouble ( config . at ( " maxUtil " ) ) & & u < LongWindowCutoff ;
}
Json PickNext ( const std : : vector < Json > & seats , const Json & config ) {
if ( seats . empty ( ) ) return { { " kind " , " stop " } , { " status " , " error " } , { " reason " , " no seat token configured " } } ;
std : : vector < Json > usable ;
for ( const Json & s : SortedBySeat ( seats ) ) {
if ( Dyn : : At ( s , " state " ) ! = " invalid " ) usable . push_back ( s ) ;
}
if ( usable . empty ( ) ) {
std : : vector < std : : string > ids ;
for ( const Json & s : seats ) ids . push_back ( Dyn : : Str ( Dyn : : At ( s , " seat " ) ) ) ;
return { { " kind " , " stop " } , { " status " , " error " } , { " reason " , std : : format ( " no valid seat token (seat{} {} rejected) " , seats . size ( ) = = 1 ? " " : " s " , Dyn : : Join ( ids , " , " ) ) } } ;
}
if ( std : : ranges : : all_of ( usable , [ ] ( const Json & s ) { return Dyn : : At ( s , " state " ) = = " unknown " ; } ) ) {
return { { " kind " , " seat " } , { " seat " , usable [ 0 ] . at ( " seat " ) } , { " source " , " round-robin " } } ;
}
const double maxUtil = AsDouble ( config . at ( " maxUtil " ) ) ;
const double cost = AsDouble ( config . at ( " lensCostPct " ) ) ;
auto projected = [ & ] ( const Json & s ) {
return Dyn : : At ( s , " state " ) = = " unknown " | | Dyn : : Get ( s , " util " ) . is_null ( ) ? maxUtil : AsDouble ( Dyn : : At ( s , " util " ) ) ;
} ;
auto longOk = [ & ] ( const Json & s ) { return Dyn : : At ( s , " state " ) = = " unknown " | | LongWindowsOk ( s ) ; } ;
std : : vector < const Json * > pool ;
for ( const Json & s : usable ) {
if ( projected ( s ) + cost < = maxUtil & & longOk ( s ) ) pool . push_back ( & s ) ;
}
const Json * chosen = nullptr ;
auto least = [ & ] ( const std : : vector < const Json * > & candidates ) {
const Json * best = candidates . front ( ) ;
for ( const Json * s : candidates ) {
if ( projected ( * s ) < projected ( * best ) ) best = s ;
}
return best ;
} ;
if ( ! pool . empty ( ) ) {
chosen = config . at ( " policy " ) = = " pack " ? pool . front ( ) : least ( pool ) ;
} else {
// Nothing fits under the ceiling: the most headroom among the seats
// whose long windows are open, else any.
std : : vector < const Json * > candidates ;
for ( const Json & s : usable ) {
if ( longOk ( s ) ) candidates . push_back ( & s ) ;
}
if ( candidates . empty ( ) ) {
for ( const Json & s : usable ) candidates . push_back ( & s ) ;
}
chosen = least ( candidates ) ;
}
return { { " kind " , " seat " } , { " seat " , chosen - > at ( " seat " ) } , { " source " , " probe " } } ;
}
bool NeedsHaiku ( const Json & seat ) {
const Json & state = Dyn : : At ( seat , " state " ) ;
return state = = " unknown " | | state = = " invalid " | | ( state = = " limited " & & IsFableWindow ( Dyn : : StrOr ( Dyn : : Get ( seat , " binding " ) , " " ) ) ) ;
}
std : : string FableState ( const Json & fable ) {
if ( Dyn : : At ( fable , " state " ) = = " limited " ) return IsFableWindow ( Dyn : : StrOr ( Dyn : : Get ( fable , " binding " ) , " " ) ) ? " limited " : " ok " ;
return Dyn : : Str ( Dyn : : At ( fable , " state " ) ) ;
}
Json MergeFableProbe ( Json base , const Json & fable ) {
if ( const Json * w = FableWindowOf ( fable ) ) {
Json windows = Json : : object ( ) ;
const Json & own = Dyn : : Or ( Dyn : : Get ( base , " windows " ) , Dyn : : EmptyDict ( ) ) ;
for ( auto it = own . begin ( ) ; it ! = own . end ( ) ; + + it ) {
if ( ! IsFableWindow ( it . key ( ) ) ) windows [ it . key ( ) ] = it . value ( ) ;
}
windows [ std : : string ( FableWindow ) ] = * w ;
base [ " windows " ] = std : : move ( windows ) ;
}
if ( Dyn : : At ( base , " state " ) = = " ok " ) {
// The seat's utilisation is its own windows' — the Fable window
// gates Fable work only (FableOpen): a drained Fable window makes an
// Opus seat, never an idle one.
Json own = Json : : object ( ) ;
for ( auto it = base . at ( " windows " ) . begin ( ) ; it ! = base . at ( " windows " ) . end ( ) ; + + it ) {
if ( ! IsFableWindow ( it . key ( ) ) ) own [ it . key ( ) ] = it . value ( ) ;
}
const auto [ util , binding ] = SeatUtil ( own ) ;
base [ " util " ] = util ;
base [ " binding " ] = binding ;
}
base [ " fable " ] = { { " state " , FableState ( fable ) } } ;
const Json & state = Dyn : : At ( fable , " state " ) ;
if ( state ! = " ok " & & state ! = " limited " & & Dyn : : Truthy ( Dyn : : Get ( fable , " error " ) ) ) base [ " fable " ] [ " error " ] = fable . at ( " error " ) ;
return base ;
}
std : : string FindClaudeBin ( const std : : map < std : : string , std : : string > & env , const std : : string & home ) {
for ( const std : : string_view variable : { " CLAUDE_BIN " , " REVIEW_GATES_CLAUDE_BIN " } ) {
if ( const std : : string & value = EnvOf ( env , std : : string ( variable ) ) ; ! value . empty ( ) ) return value ;
}
if ( const std : : string & path = EnvOf ( env , " PATH " ) ; ! path . empty ( ) ) {
if ( const std : : optional < std : : string > found = Which ( " claude " , path ) ) return * found ;
}
std : : vector < std : : string > found ;
for ( const std : : string_view extensions : { " .vscode-oss/extensions " , " .vscode/extensions " , " .vscode-insiders/extensions " , " .cursor/extensions " } ) {
const fs : : path dir = fs : : path ( home ) / extensions ;
std : : error_code error ;
if ( ! fs : : is_directory ( dir , error ) ) continue ;
std : : vector < std : : string > names ;
for ( const fs : : directory_entry & entry : fs : : directory_iterator ( dir , error ) ) {
const std : : string name = entry . path ( ) . filename ( ) . string ( ) ;
if ( name . starts_with ( " anthropic.claude-code- " ) ) names . push_back ( name ) ;
}
std : : ranges : : stable_sort ( names , [ ] ( const std : : string & a , const std : : string & b ) { return VersionKey ( a ) > VersionKey ( b ) ; } ) ;
for ( const std : : string & name : names ) {
const fs : : path binary = dir / name / " resources " / " native-binary " / " claude " ;
if ( fs : : exists ( binary , error ) ) found . push_back ( binary . string ( ) ) ;
}
}
for ( const fs : : path local : { fs : : path ( home ) / " .claude " / " local " / " claude " , fs : : path ( home ) / " .local " / " bin " / " claude " } ) {
std : : error_code error ;
if ( fs : : exists ( local , error ) ) found . push_back ( local . string ( ) ) ;
}
return found . empty ( ) ? std : : string ( " claude " ) : found . front ( ) ;
}
std : : string FindClaudeBin ( ) {
return FindClaudeBin ( Platform : : Environment ( ) , Platform : : Home ( ) ) ;
}
Zone ZoneNamed ( std : : string_view name ) {
// ZoneInfo(name): a zone the system's zoneinfo holds, else none.
std : : error_code error ;
const bool known = name = = " UTC " | | fs : : is_regular_file ( fs : : path ( " /usr/share/zoneinfo " ) / name , error ) ;
return { known ? std : : string ( name ) : std : : string ( ) , std : : string ( name ) } ;
}
Zone LocalZone ( ) {
std : : string name = Dyn : : LStrip ( Platform : : GetEnv ( " TZ " ) . value_or ( " " ) , " : " ) ;
if ( name . empty ( ) ) {
std : : error_code error ;
const std : : string target = fs : : weakly_canonical ( " /etc/localtime " , error ) . string ( ) ;
const std : : size_t at = target . find ( " /zoneinfo/ " ) ;
if ( at ! = std : : string : : npos ) name = target . substr ( at + 10 ) ;
}
if ( ! name . empty ( ) ) {
Zone zone = ZoneNamed ( name ) ;
if ( ! zone . name . empty ( ) ) return zone ;
}
return { " " , name . empty ( ) ? Platform : : LocalTime ( " %Z " ) : name } ;
}
namespace {
// The broken-down time of `t` in the zone: the C library's, with TZ
// set to the zone's name for the call.
std : : tm InZone ( std : : time_t t , const Zone & zone ) {
static std : : mutex lock ;
const std : : lock_guard guard ( lock ) ;
std : : tm out { } ;
if ( zone . name . empty ( ) ) {
localtime_r ( & t , & out ) ;
return out ;
}
const char * before = getenv ( " TZ " ) ;
const std : : optional < std : : string > saved = before ? std : : optional < std : : string > ( before ) : std : : nullopt ;
setenv ( " TZ " , zone . name . c_str ( ) , 1 ) ;
tzset ( ) ;
localtime_r ( & t , & out ) ;
if ( saved ) {
setenv ( " TZ " , saved - > c_str ( ) , 1 ) ;
} else {
unsetenv ( " TZ " ) ;
}
tzset ( ) ;
return out ;
}
}
feat(cli): seats, init, doc, browser install and stop
- `seats` reports every seat probed (Fable first, Haiku for a seat that
needs it), the API seats beside the driver's ledger, the drivers on the
board, or all of it as JSON. In the sandbox a last line names `stop`,
since the pids above cannot be signalled from there.
- `init` sets a repository up: the config from the template, the artifact
and worktree dirs ignored, the prepush skill with a marker that lets a
later init refresh it. The old link into the review-gates submodule is
replaced by a real directory, never written through. A foreign link, a
subdirectory, the home directory and a dir outside git are refused before
anything is written.
- `doc [--path] prepush|manifest|config` prints a shipped text, or where
the host sees it (the deployment's `active` link in the Flatpak).
- `browser install` runs the installer of the Playwright the pinned MCP
server depends on, and checks the Chromium revision landed.
- `stop <scratch>` and `stop --hash <hash8>` write the stop file a running
driver checks every 2 s, for live drivers only; the board is read, never
written.
The option parser takes positionals, in the usage line, the help and the
errors. The Commands test runs all of them through this binary, seats on a
claude stand-in.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 15:45:36 +01:00
std : : string Clock ( double epoch , const Zone & zone ) {
const std : : tm d = InZone ( static_cast < std : : time_t > ( std : : floor ( epoch ) ) , zone ) ;
return std : : format ( " {:02d}:{:02d} " , d . tm_hour , d . tm_min ) ;
}
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
std : : optional < std : : string > BurstWindow ( const Json & windows ) {
for ( const std : : string_view window : { std : : string_view ( " five_hour " ) , std : : string_view ( " seven_day " ) } ) {
if ( ! Dyn : : Get ( Dyn : : Or ( Dyn : : Get ( windows , window ) , Dyn : : EmptyDict ( ) ) , " utilization " ) . is_null ( ) ) return std : : string ( window ) ;
}
return std : : nullopt ;
}
std : : string WindowCell ( const Json & windows , std : : string_view window ) {
const Json & u = Dyn : : Get ( Dyn : : Or ( Dyn : : Get ( windows , window ) , Dyn : : EmptyDict ( ) ) , " utilization " ) ;
if ( ! u . is_null ( ) ) return std : : format ( " {}% " , Fmt ( u ) ) ;
return window = = " five_hour " & & BurstWindow ( windows ) = = " seven_day " ? std : : string ( " no limit " ) : std : : string ( " — " ) ;
}
feat(seats): memory, the Playwright MCP config, and the seats library
:Memory: MemAvailable and the reserve policy, the sampler of a pass's peak
tree PSS (one sweep, a pause of three sweeps at least, stopped with the
driver), and the calibration file every driver on the machine shares,
re-read and written under its lock.
:Mcp: the pinned @playwright/mcp 0.0.83 arguments and the --mcp-config of
one pass, compact and in a fixed key order.
:Seats: the dotenv loader (token lines only, TOKEN7 inert), the one-word
probe (run under the supervisor, a missing binary reported with its errno
text), the window maths, the ranking, the Fable merge, the editor-bundle
lookup of the claude binary, the redaction of anything token-shaped, and
the report. This libc++ has no tzdb, so a zone by name converts through
the C library with TZ set, reading the system's zoneinfo.
tests/Seats: 92 checks against reference vectors, numbered in order, all
green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:32:14 +01:00
std : : string FormatWhen ( double epoch , double now , const Zone & zone ) {
const auto diffMin = static_cast < std : : int64_t > ( JsRound ( ( epoch - now ) / 60 ) ) ;
std : : string relative ;
if ( diffMin < = 0 ) {
relative = " now " ;
} else if ( diffMin < 60 ) {
relative = std : : format ( " in {} min " , diffMin ) ;
} else if ( diffMin < 48 * 60 ) {
relative = std : : format ( " in {}h {:02d}m " , diffMin / 60 , diffMin % 60 ) ;
} else {
relative = std : : format ( " in {}d {}h " , diffMin / 1440 , ( diffMin % 1440 ) / 60 ) ;
}
const std : : tm d = InZone ( static_cast < std : : time_t > ( std : : floor ( epoch ) ) , zone ) ;
std : : string clock = std : : format ( " {:02d}:{:02d} " , d . tm_hour , d . tm_min ) ;
if ( epoch - now > 24 * 3600 ) {
// Monday is 0 here; tm_wday counts from Sunday.
const auto index = static_cast < std : : size_t > ( ( d . tm_wday + 6 ) % 7 ) ;
clock = std : : format ( " {} {:02d} {}, {} " , Weekdays [ index ] , d . tm_mday , Months [ static_cast < std : : size_t > ( d . tm_mon ) ] , clock ) ;
}
return std : : format ( " {} ({}) " , clock , relative ) ;
}
std : : string RenderTable ( const std : : vector < std : : vector < std : : string > > & rows ) {
std : : vector < std : : size_t > widths ( rows . at ( 0 ) . size ( ) , 0 ) ;
for ( const std : : vector < std : : string > & row : rows ) {
for ( std : : size_t i = 0 ; i < widths . size ( ) ; + + i ) widths [ i ] = std : : max ( widths [ i ] , Dyn : : Length ( row . at ( i ) ) ) ;
}
auto line = [ & ] ( const std : : vector < std : : string > & row ) {
std : : vector < std : : string > cells ;
for ( std : : size_t i = 0 ; i < widths . size ( ) ; + + i ) cells . push_back ( Dyn : : LJust ( row [ i ] , widths [ i ] ) ) ;
return std : : format ( " | {} | " , Dyn : : Join ( cells , " | " ) ) ;
} ;
std : : vector < std : : string > out = { line ( rows [ 0 ] ) } ;
std : : vector < std : : string > dashes ;
for ( const std : : size_t width : widths ) dashes . emplace_back ( width + 2 , ' - ' ) ;
out . push_back ( std : : format ( " |{}| " , Dyn : : Join ( dashes , " | " ) ) ) ;
for ( std : : size_t r = 1 ; r < rows . size ( ) ; + + r ) out . push_back ( line ( rows [ r ] ) ) ;
return Dyn : : Join ( out , " \n " ) ;
}
std : : string RenderStatusReport ( const std : : vector < Json > & seats , const Json & config , double now , const Zone & zone , const Json & board ,
const std : : map < std : : int32_t , std : : string > & keys ) {
const std : : vector < Json > ordered = SortedBySeat ( seats ) ;
const bool anyInflight = std : : ranges : : any_of ( ordered , [ & ] ( const Json & s ) { return Inflight ( board , keys , s ) ! = 0 ; } ) ;
std : : vector < std : : vector < std : : string > > rows ;
std : : vector < std : : string > header = { " seat " , " 5h " , " resets " , " 7d " , " resets " , " fable 7d " } ;
if ( anyInflight ) header . emplace_back ( " in flight " ) ;
rows . push_back ( header ) ;
for ( const Json & s : ordered ) {
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
auto w = [ & ] ( std : : string_view k ) { return WindowCell ( Dyn : : Or ( Dyn : : Get ( s , " windows " ) , Dyn : : EmptyDict ( ) ) , k ) ; } ;
feat(seats): memory, the Playwright MCP config, and the seats library
:Memory: MemAvailable and the reserve policy, the sampler of a pass's peak
tree PSS (one sweep, a pause of three sweeps at least, stopped with the
driver), and the calibration file every driver on the machine shares,
re-read and written under its lock.
:Mcp: the pinned @playwright/mcp 0.0.83 arguments and the --mcp-config of
one pass, compact and in a fixed key order.
:Seats: the dotenv loader (token lines only, TOKEN7 inert), the one-word
probe (run under the supervisor, a missing binary reported with its errno
text), the window maths, the ranking, the Fable merge, the editor-bundle
lookup of the claude binary, the redaction of anything token-shaped, and
the report. This libc++ has no tzdb, so a zone by name converts through
the C library with TZ set, reading the system's zoneinfo.
tests/Seats: 92 checks against reference vectors, numbered in order, all
green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:32:14 +01:00
auto when = [ & ] ( std : : string_view k ) {
const Json & at = Dyn : : Get ( Dyn : : Or ( Window ( s , k ) , Dyn : : EmptyDict ( ) ) , " resetsAt " ) ;
return Dyn : : Truthy ( at ) ? FormatWhen ( AsDouble ( at ) , now , zone ) : std : : string ( " — " ) ;
} ;
const Json * fw = FableWindowOf ( s ) ;
const Json & f = Dyn : : Get ( s , " fable " ) ;
std : : string fable ;
if ( Dyn : : Truthy ( f ) & & Dyn : : Get ( f , " state " ) = = " limited " ) {
fable = std : : format ( " limited{} " , fw ? std : : format ( " ({}%) " , Fmt ( Dyn : : At ( * fw , " utilization " ) ) ) : std : : string ( ) ) ;
} else if ( fw ) {
fable = std : : format ( " {}% " , Fmt ( Dyn : : At ( * fw , " utilization " ) ) ) ;
} else {
fable = Dyn : : Truthy ( f ) ? Dyn : : Str ( Dyn : : At ( f , " state " ) ) : std : : string ( " — " ) ;
}
std : : vector < std : : string > row = { SeatCell ( s ) , w ( " five_hour " ) , when ( " five_hour " ) , w ( " seven_day " ) , when ( " seven_day " ) , fable } ;
if ( anyInflight ) {
const std : : int64_t n = Inflight ( board , keys , s ) ;
row . push_back ( n ? std : : to_string ( n ) : " — " ) ;
}
rows . push_back ( std : : move ( row ) ) ;
}
std : : vector < Json > eligible ;
for ( const Json & s : ordered ) {
if ( IsEligible ( s , config ) ) eligible . push_back ( s ) ;
}
std : : ranges : : stable_sort ( eligible , [ ] ( const Json & a , const Json & b ) { return NumberOr0 ( Dyn : : Get ( a , " util " ) ) < NumberOr0 ( Dyn : : Get ( b , " util " ) ) ; } ) ;
const Json pick = PickNext ( seats , config ) ;
const std : : string next = pick . at ( " kind " ) = = " seat " ? SeatName ( { { " seat " , pick . at ( " seat " ) } } ) : std : : format ( " {}: {} " , Dyn : : Str ( pick . at ( " status " ) ) , Dyn : : Str ( pick . at ( " reason " ) ) ) ;
std : : vector < std : : string > limited ;
std : : vector < std : : string > unusable ;
std : : vector < std : : string > fableDead ;
for ( const Json & s : ordered ) {
const Json & state = Dyn : : At ( s , " state " ) ;
if ( state = = " limited " ) {
const Json & resets = Dyn : : Get ( s , " resetsAt " ) ;
limited . push_back ( std : : format ( " {} until {} " , SeatName ( s ) , Dyn : : Truthy ( resets ) ? FormatWhen ( AsDouble ( resets ) , now , zone ) : std : : string ( " ? " ) ) ) ;
}
if ( state ! = " ok " & & state ! = " limited " ) {
unusable . push_back ( std : : format ( " {} {}{} " , SeatName ( s ) , Dyn : : Str ( state ) , Dyn : : Truthy ( Dyn : : Get ( s , " error " ) ) ? std : : format ( " ({}) " , Dyn : : Str ( s . at ( " error " ) ) ) : std : : string ( ) ) ) ;
}
const Json & fableOfSeat = Dyn : : Or ( Dyn : : Get ( s , " fable " ) , Dyn : : EmptyDict ( ) ) ;
const Json & fableStateOfSeat = Dyn : : Get ( fableOfSeat , " state " ) ;
if ( ( state = = " ok " | | state = = " limited " ) & & ! fableStateOfSeat . is_null ( ) & & fableStateOfSeat ! = " ok " & & fableStateOfSeat ! = " limited " ) {
fableDead . push_back ( std : : format ( " {} {}{} " , SeatName ( s ) , Dyn : : Str ( fableStateOfSeat ) ,
Dyn : : Truthy ( Dyn : : Get ( fableOfSeat , " error " ) ) ? std : : format ( " ({}) " , Dyn : : Str ( fableOfSeat . at ( " error " ) ) ) : std : : string ( ) ) ) ;
}
}
const bool fableSeen = std : : ranges : : any_of ( seats , [ ] ( const Json & s ) { return FableWindowOf ( s ) ! = nullptr ; } ) ;
std : : vector < Json > fableRoom ;
for ( const Json & s : ordered ) {
if ( Dyn : : At ( s , " state " ) = = " ok " & & FableWindowOf ( s ) & & FableOpen ( s , config ) ) fableRoom . push_back ( s ) ;
}
std : : ranges : : stable_sort ( fableRoom , [ ] ( const Json & a , const Json & b ) { return Less ( Dyn : : At ( * FableWindowOf ( a ) , " utilization " ) , Dyn : : At ( * FableWindowOf ( b ) , " utilization " ) ) ; } ) ;
const double maxUtil = AsDouble ( config . at ( " maxUtil " ) ) ;
std : : vector < std : : string > lines = { RenderTable ( rows ) , " " } ;
lines . push_back ( std : : format ( " policy {} · ceiling {}% · handover at {}% · a lens is placed at +{}% · 7d cutoff {}% " , Dyn : : Str ( config . at ( " policy " ) ) , Fmt ( config . at ( " maxUtil " ) ) ,
Fmt ( config . at ( " handoverPct " ) ) , Fmt ( config . at ( " lensCostPct " ) ) , LongWindowCutoff ) ) ;
std : : vector < std : : string > eligibleText ;
for ( const Json & s : eligible ) eligibleText . push_back ( std : : format ( " {} ({}% headroom) " , SeatName ( s ) , Fmt ( Json ( maxUtil - NumberOr0 ( Dyn : : Get ( s , " util " ) ) ) ) ) ) ;
lines . push_back ( std : : format ( " eligible now: {} → next lens: {} " , eligible . empty ( ) ? std : : string ( " none " ) : Dyn : : Join ( eligibleText , " , " ) , next ) ) ;
if ( fableSeen ) {
std : : vector < std : : string > room ;
for ( const Json & s : fableRoom ) room . push_back ( std : : format ( " {} ({}% fable headroom) " , SeatName ( s ) , Fmt ( Json ( maxUtil - AsDouble ( Dyn : : At ( * FableWindowOf ( s ) , " utilization " ) ) ) ) ) ) ;
lines . push_back ( std : : format ( " fable lenses: {} " , fableRoom . empty ( ) ? std : : string ( " no seat with room on its Fable window — Fable lenses run on their fallback model " ) : Dyn : : Join ( room , " , " ) ) ) ;
}
if ( ! limited . empty ( ) ) lines . push_back ( std : : format ( " limited: {} " , Dyn : : Join ( limited , " ; " ) ) ) ;
if ( ! unusable . empty ( ) ) lines . push_back ( std : : format ( " not usable: {} " , Dyn : : Join ( unusable , " ; " ) ) ) ;
if ( ! fableDead . empty ( ) ) lines . push_back ( std : : format ( " fable probe: {} " , Dyn : : Join ( fableDead , " ; " ) ) ) ;
return Dyn : : Join ( lines , " \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 : : string RenderApiReport ( const std : : vector < Json > & apiSeats , const Json & apiConfig , double now , const Json & board , const std : : map < std : : int32_t , std : : string > & keys ) {
const std : : string today = Platform : : LocalTime ( " %Y-%m-%d " , now ) ;
// "17 Sept"
auto date = [ ] ( const std : : string & iso ) {
return std : : format ( " {} {} " , std : : stoi ( iso . substr ( 8 , 2 ) ) , Months [ static_cast < std : : size_t > ( std : : stoi ( iso . substr ( 5 , 2 ) ) - 1 ) ] ) ;
} ;
std : : vector < std : : vector < std : : string > > rows = { { " seat " , " probe " , " driver " , " driver spend this cycle " , " procs " , " cycle from " , " grant day " , " next credits " , " in flight " } } ;
std : : vector < std : : string > notes ;
feat(seats): memory, the Playwright MCP config, and the seats library
:Memory: MemAvailable and the reserve policy, the sampler of a pass's peak
tree PSS (one sweep, a pause of three sweeps at least, stopped with the
driver), and the calibration file every driver on the machine shares,
re-read and written under its lock.
:Mcp: the pinned @playwright/mcp 0.0.83 arguments and the --mcp-config of
one pass, compact and in a fixed key order.
:Seats: the dotenv loader (token lines only, TOKEN7 inert), the one-word
probe (run under the supervisor, a missing binary reported with its errno
text), the window maths, the ranking, the Fable merge, the editor-bundle
lookup of the claude binary, the redaction of anything token-shaped, and
the report. This libc++ has no tzdb, so a zone by name converts through
the C library with TZ set, reading the system's zoneinfo.
tests/Seats: 92 checks against reference vectors, numbered in order, all
green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:32:14 +01:00
for ( const Json & s : SortedBySeat ( apiSeats ) ) {
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
const std : : string id = std : : format ( " api{} " , Dyn : : Str ( Dyn : : At ( s , " seat " ) ) ) ;
feat(seats): memory, the Playwright MCP config, and the seats library
:Memory: MemAvailable and the reserve policy, the sampler of a pass's peak
tree PSS (one sweep, a pause of three sweeps at least, stopped with the
driver), and the calibration file every driver on the machine shares,
re-read and written under its lock.
:Mcp: the pinned @playwright/mcp 0.0.83 arguments and the --mcp-config of
one pass, compact and in a fixed key order.
:Seats: the dotenv loader (token lines only, TOKEN7 inert), the one-word
probe (run under the supervisor, a missing binary reported with its errno
text), the window maths, the ranking, the Fable merge, the editor-bundle
lookup of the claude binary, the redaction of anything token-shaped, and
the report. This libc++ has no tzdb, so a zone by name converts through
the C library with TZ set, reading the system's zoneinfo.
tests/Seats: 92 checks against reference vectors, numbered in order, all
green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:32:14 +01:00
const Json & ledger = Dyn : : Or ( Dyn : : Get ( s , " ledger " ) , Dyn : : EmptyDict ( ) ) ;
const double spent = NumberOr0 ( Dyn : : Get ( ledger , " spentUsd " ) ) ;
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
const std : : string state = Dyn : : Str ( Dyn : : At ( s , " state " ) ) ;
const std : : string probe = state + ( Dyn : : Truthy ( Dyn : : Get ( s , " error " ) ) & & state ! = " ok " ? std : : format ( " ({}) " , Dyn : : Str ( s . at ( " error " ) ) ) : std : : string ( ) ) ;
// The driver's verdict, SeatPool::LedgerOut's.
const Json & ledgerOut = Dyn : : Get ( s , " ledgerOut " ) ;
const bool out = ! ledgerOut . is_null ( ) ;
const std : : string driver = ! out ? std : : string ( " ok " )
: ledgerOut = = " credit " ? std : : format ( " out (credit since {}) " , Dyn : : Replace ( Dyn : : Slice ( Dyn : : Str ( Dyn : : Get ( ledger , " outSince " ) ) , 0 , 16 ) , " T " , " " ) )
: std : : string ( " out (budget spent) " ) ;
const std : : string due = Dyn : : StrOr ( Dyn : : Get ( s , " nextCredits " ) , " " ) ;
const std : : string dueText = due . size ( ) < 10 ? std : : string ( " — " ) : due = = today ? std : : string ( " today " ) : due < today ? std : : format ( " overdue, {} " , date ( due ) ) : date ( due ) ;
feat(seats): memory, the Playwright MCP config, and the seats library
:Memory: MemAvailable and the reserve policy, the sampler of a pass's peak
tree PSS (one sweep, a pause of three sweeps at least, stopped with the
driver), and the calibration file every driver on the machine shares,
re-read and written under its lock.
:Mcp: the pinned @playwright/mcp 0.0.83 arguments and the --mcp-config of
one pass, compact and in a fixed key order.
:Seats: the dotenv loader (token lines only, TOKEN7 inert), the one-word
probe (run under the supervisor, a missing binary reported with its errno
text), the window maths, the ranking, the Fable merge, the editor-bundle
lookup of the claude binary, the redaction of anything token-shaped, and
the report. This libc++ has no tzdb, so a zone by name converts through
the C library with TZ set, reading the system's zoneinfo.
tests/Seats: 92 checks against reference vectors, numbered in order, all
green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:32:14 +01:00
const std : : int64_t n = Inflight ( board , keys , s ) ;
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
rows . push_back ( { id , probe , driver , std : : format ( " ${:.2f} of ${} " , spent , Fmt ( apiConfig . at ( " budgetUsd " ) ) ) , Dyn : : StrOr ( Dyn : : Get ( ledger , " procs " ) , " 0 " ) ,
Dyn : : StrOr ( Dyn : : Get ( ledger , " cycle " ) , " — " ) , Dyn : : StrOr ( Dyn : : Get ( s , " grantDay " ) , " — " ) , dueText ,
n ? std : : format ( " {} of {} " , n , Dyn : : Str ( apiConfig . at ( " concurrency " ) ) ) : std : : string ( " — " ) } ) ;
const Json & event = Dyn : : Get ( s , " event " ) ;
if ( event = = " new-grant " ) {
notes . push_back ( std : : format ( " {}: the key answers again - new credits; the ledger cycle restarted (from {}) " , id , Dyn : : StrOr ( Dyn : : Get ( ledger , " cycle " ) , " — " ) ) ) ;
} else if ( event = = " credit-gone " ) {
notes . push_back ( std : : format ( " {}: the credit error, now recorded in the ledger " , id ) ) ;
} else if ( state = = " ok " & & ledgerOut = = " credit " ) {
notes . push_back ( std : : format ( " {}: the key answered, but the credit error was recorded since the probe started - the ledger's verdict stands " , id ) ) ;
} else if ( state = = " ok " & & out ) {
notes . push_back ( std : : format ( " {}: the key answers, but the driver's budget for this cycle is spent (REVIEW_GATES_API_BUDGET_USD) " , id ) ) ;
} else if ( state ! = " ok " & & state ! = " out " & & out ) {
notes . push_back ( std : : format ( " {}: probe {} - the ledger's verdict stands " , id , state ) ) ;
}
}
std : : vector < std : : string > lines = { RenderTable ( rows ) } ;
lines . insert ( lines . end ( ) , notes . begin ( ) , notes . end ( ) ) ;
lines . push_back ( std : : format ( " {} seats run first (REVIEW_GATES_SEAT_ORDER={}) · budget ${} per seat per cycle · a cycle starts on the seat's grant day (ANTHROPIC_API_KEY<n>_GRANT_DAY, else "
" REVIEW_GATES_API_CYCLE_DAY={}) · {} processes per seat · placed at +${} each " ,
Dyn : : Str ( apiConfig . at ( " order " ) ) = = " api-first " ? " api " : " oauth " , Dyn : : Str ( apiConfig . at ( " order " ) ) , Fmt ( apiConfig . at ( " budgetUsd " ) ) , Dyn : : Str ( apiConfig . at ( " cycleDay " ) ) ,
Dyn : : Str ( apiConfig . at ( " concurrency " ) ) , Fmt ( apiConfig . at ( " lensCostUsd " ) ) ) ) ;
lines . emplace_back ( " the balance itself is in the Console (Settings > Billing > Promotional credits); the ledger counts only what the review drivers spent, and \" overdue \" means the grant day "
" is wrong " ) ;
return Dyn : : Join ( lines , " \n " ) ;
feat(seats): memory, the Playwright MCP config, and the seats library
:Memory: MemAvailable and the reserve policy, the sampler of a pass's peak
tree PSS (one sweep, a pause of three sweeps at least, stopped with the
driver), and the calibration file every driver on the machine shares,
re-read and written under its lock.
:Mcp: the pinned @playwright/mcp 0.0.83 arguments and the --mcp-config of
one pass, compact and in a fixed key order.
:Seats: the dotenv loader (token lines only, TOKEN7 inert), the one-word
probe (run under the supervisor, a missing binary reported with its errno
text), the window maths, the ranking, the Fable merge, the editor-bundle
lookup of the claude binary, the redaction of anything token-shaped, and
the report. This libc++ has no tzdb, so a zone by name converts through
the C library with TZ set, reading the system's zoneinfo.
tests/Seats: 92 checks against reference vectors, numbered in order, all
green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:32:14 +01:00
}
std : : string RenderDrivers ( const Json & board , double now , const Zone & zone ) {
const Json & drivers = Dyn : : Or ( Dyn : : Get ( Dyn : : Or ( board , Dyn : : EmptyDict ( ) ) , " drivers " ) , Dyn : : EmptyDict ( ) ) ;
if ( ! Dyn : : Truthy ( drivers ) ) return std : : format ( " drivers: none running (the board at {}) " , Dyn : : StrOr ( Dyn : : Get ( Dyn : : Or ( board , Dyn : : EmptyDict ( ) ) , " path " ) , " ? " ) ) ;
std : : vector < std : : pair < std : : string , const Json * > > sorted ;
for ( auto it = drivers . begin ( ) ; it ! = drivers . end ( ) ; + + it ) sorted . emplace_back ( it . key ( ) , & it . value ( ) ) ;
std : : ranges : : stable_sort ( sorted , [ ] ( const auto & a , const auto & b ) { return NumberOr0 ( Dyn : : Get ( * a . second , " since " ) ) < NumberOr0 ( Dyn : : Get ( * b . second , " since " ) ) ; } ) ;
std : : vector < std : : string > parts ;
std : : int64_t total = 0 ;
for ( const auto & [ key , driver ] : sorted ) {
const Json & d = * driver ;
const Json & settings = Dyn : : Or ( Dyn : : Get ( d , " settings " ) , Dyn : : EmptyDict ( ) ) ;
std : : string held ;
if ( Dyn : : Truthy ( Dyn : : Get ( d , " mb " ) ) ) held + = std : : format ( " , {:.0f} MB " , AsDouble ( d . at ( " mb " ) ) ) ;
if ( Dyn : : Truthy ( Dyn : : Get ( d , " stacks " ) ) ) {
std : : vector < std : : string > stacks ;
for ( const Json & stack : d . at ( " stacks " ) ) stacks . push_back ( Dyn : : Str ( stack ) ) ;
std : : ranges : : sort ( stacks ) ;
held + = std : : format ( " , stack(s) {} " , Dyn : : Join ( stacks , " , " ) ) ;
}
const Json unknown = " ? " ;
const Json zero = 0 ;
parts . push_back ( std : : format ( " pid {} ({}, {}, width {}) since {} - {} in flight{} " , Dyn : : Split ( key , " : " ) [ 0 ] , Dyn : : Str ( Dyn : : Has ( d , " run " ) ? d . at ( " run " ) : unknown ) ,
Dyn : : Str ( Dyn : : Has ( d , " effort " ) ? d . at ( " effort " ) : unknown ) , Dyn : : Str ( Dyn : : Has ( settings , " concurrency " ) ? settings . at ( " concurrency " ) : unknown ) ,
FormatWhen ( NumberOr0 ( Dyn : : Get ( d , " since " ) ) , now , zone ) , Dyn : : Str ( Dyn : : Has ( d , " inflight " ) ? d . at ( " inflight " ) : zero ) , held ) ) ;
total + = static_cast < std : : int64_t > ( NumberOr0 ( Dyn : : Get ( d , " inflight " ) ) ) ;
}
2026-10-31 17:33:11 +01:00
return std : : format ( " drivers ({} in flight on this machine; a width is that driver's cap): {} " , total , Dyn : : Join ( parts , " ; " ) ) ;
feat(seats): memory, the Playwright MCP config, and the seats library
:Memory: MemAvailable and the reserve policy, the sampler of a pass's peak
tree PSS (one sweep, a pause of three sweeps at least, stopped with the
driver), and the calibration file every driver on the machine shares,
re-read and written under its lock.
:Mcp: the pinned @playwright/mcp 0.0.83 arguments and the --mcp-config of
one pass, compact and in a fixed key order.
:Seats: the dotenv loader (token lines only, TOKEN7 inert), the one-word
probe (run under the supervisor, a missing binary reported with its errno
text), the window maths, the ranking, the Fable merge, the editor-bundle
lookup of the claude binary, the redaction of anything token-shaped, and
the report. This libc++ has no tzdb, so a zone by name converts through
the C library with TZ set, reading the system's zoneinfo.
tests/Seats: 92 checks against reference vectors, numbered in order, all
green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:32:14 +01:00
}
}