feat(seats): a pass's share of the windows by the run's effort, the weekly cutoff at 99 %

The 5-hour share of a running pass was a flat 0.25 points; it follows the
run's effort now, as the weekly share already did: 0.5 at max and any other
effort, 0.125 at xhigh - the pooled means of 5438 Opus 5.5 passes on 141
seat-runs (2026-10-12..15), rounded up. The weekly cutoff moves from 95 %
to 99 %: the weekly window is the budget the lenses run out of, and with
the running passes projected against the cutoff the last percent is spent
a pass at a time, not in a burst. REVIEW_GATES_LENS_COST_PCT and
REVIEW_GATES_LENS_COST_7D_PCT still override every effort.
This commit is contained in:
Jorijn van der Graaf 2026-10-31 21:13:55 +01:00
commit ea4d362a10
Signed by: jorijnvdgraaf
GPG key ID: 2937E59CDCC1BCFB
8 changed files with 44 additions and 31 deletions

View file

@ -108,7 +108,8 @@ Conventions:
No file the drivers write holds these in practice, and a file that fails to parse is treated as a damaged one. No file the drivers write holds these in practice, and a file that fails to parse is treated as a damaged one.
- **HTTP.** `ClientHTTP1::Fetch` ignores `*_proxy` variables. The OpenRouter requests send `User-Agent: crafter-review`; `app_ready` sends `review-gates`. Reason phrases are the standard ones, not the server's. - **HTTP.** `ClientHTTP1::Fetch` ignores `*_proxy` variables. The OpenRouter requests send `User-Agent: crafter-review`; `app_ready` sends `review-gates`. Reason phrases are the standard ones, not the server's.
- **Seat placement** (SeatPool, Seats, Drivers): - **Seat placement** (SeatPool, Seats, Drivers):
- An account whose 5-hour limit Anthropic has removed reports the weekly window alone. Its burst window (`Seats::BurstWindow`) is the weekly one: it is ranked and admitted by the weekly window with the passes in flight projected on it (0.04 points per pass at xhigh, 0.125 otherwise), under the 95 % cutoff. - An account whose 5-hour limit Anthropic has removed reports the weekly window alone. Its burst window (`Seats::BurstWindow`) is the weekly one: it is ranked and admitted by the weekly window with the passes in flight projected on it (0.04 points per pass at xhigh, 0.125 otherwise), under the 99 % cutoff.
- A pass's projected share of the windows follows the run's effort: 0.5 / 0.125 points of the 5-hour window and 0.125 / 0.04 of the weekly one at max / xhigh (`SeatPool::LensCostPct`, `LensCost7dPct`), the pooled means of 5438 passes on 141 seat-runs (2026-10-12..15) rounded up. The weekly cutoff is 99 %: the running passes are projected against it, so the last percent is spent a pass at a time.
- Every OAuth account and the local login takes at most 128 passes at once, every driver's counted. - Every OAuth account and the local login takes at most 128 passes at once, every driver's counted.
- There is no machine-wide width (2026-10-31, Jorijn: "there is no need to do a global cap anymore, the cap should be 128 per available account"). `--concurrency` caps only when given, and the dump's `args.concurrency` is then null. The board's driver settings read `128 per account`, which every driver's `seats` shows as that driver's width (Scheduler, Runs). - There is no machine-wide width (2026-10-31, Jorijn: "there is no need to do a global cap anymore, the cap should be 128 per available account"). `--concurrency` caps only when given, and the dump's `args.concurrency` is then null. The board's driver settings read `128 per account`, which every driver's `seats` shows as that driver's width (Scheduler, Runs).
- A 'concurrents' rejection pauses the seat for 20 s or its retry-after, not until a window's reset. - A 'concurrents' rejection pauses the seat for 20 s or its retry-after, not until a window's reset.
@ -179,7 +180,7 @@ What the binary reads at run time, and how. A variable the driver only sets or s
| `SEATS_ENV_FILE` | `:Run` Gate0 (run), `seats` | run: `<repo>/.env` if it exists; `seats`: `./.env` if it exists | `--env-file` wins (in run even `--env-file ""`, meaning no file); empty counts as unset. Only seat lines are taken (`[export ]NAME=value`, one pair of matching quotes stripped), overriding the process environment; no knob below is ever read from the file. A file that cannot be read, or is not UTF-8: run stops at preflight (exit 3), `seats` exits 1 with the read error. | The dotenv file the seat secrets come from | | `SEATS_ENV_FILE` | `:Run` Gate0 (run), `seats` | run: `<repo>/.env` if it exists; `seats`: `./.env` if it exists | `--env-file` wins (in run even `--env-file ""`, meaning no file); empty counts as unset. Only seat lines are taken (`[export ]NAME=value`, one pair of matching quotes stripped), overriding the process environment; no knob below is ever read from the file. A file that cannot be read, or is not UTF-8: run stops at preflight (exit 3), `seats` exits 1 with the read error. | The dotenv file the seat secrets come from |
| `REVIEW_GATES_SEATS` | `:Driver` RunCommand → LoadSeats | `auto` | Only without `--seats`. Stripped, case-sensitive; unset or empty is `auto` (every api and oauth seat, else `local`); `local`, `api`, `oauth`, `openrouter` select that kind; anything else is a comma list of ids (`apiN`, `N`, `orN`, `local`; blank items skipped). An id not configured, or OpenRouter mixed with others, is a preflight error (exit 3). | The seats a run places lens processes on | | `REVIEW_GATES_SEATS` | `:Driver` RunCommand → LoadSeats | `auto` | Only without `--seats`. Stripped, case-sensitive; unset or empty is `auto` (every api and oauth seat, else `local`); `local`, `api`, `oauth`, `openrouter` select that kind; anything else is a comma list of ids (`apiN`, `N`, `orN`, `local`; blank items skipped). An id not configured, or OpenRouter mixed with others, is a preflight error (exit 3). | The seats a run places lens processes on |
| `REVIEW_GATES_SEAT_MAX_UTIL` | `:Seats` ConfigFromEnv (`seats`; run through `:SeatPool` PoolConfig) | `85` | A finite number >= 0, in decimal or exponent notation; surrounding whitespace, `_` between digits and Unicode digits are taken. Empty, garbage, negative, `inf`, `nan` keep the default; a whole value is stored as an int. Process environment only. | Ceiling (%) of an OAuth seat's projected 5-hour utilisation | | `REVIEW_GATES_SEAT_MAX_UTIL` | `:Seats` ConfigFromEnv (`seats`; run through `:SeatPool` PoolConfig) | `85` | A finite number >= 0, in decimal or exponent notation; surrounding whitespace, `_` between digits and Unicode digits are taken. Empty, garbage, negative, `inf`, `nan` keep the default; a whole value is stored as an int. Process environment only. | Ceiling (%) of an OAuth seat's projected 5-hour utilisation |
| `REVIEW_GATES_LENS_COST_PCT` | `:Seats` ConfigFromEnv; `:SeatPool` PoolConfig | run: `0.25`; `seats`: `10` | As MAX_UTIL. PoolConfig puts in 0.25 only when it is unset or blank, so a set but invalid value gives 10, in run too. | Percentage points of the 5-hour window a running process is projected to add (its cost on the board too) | | `REVIEW_GATES_LENS_COST_PCT` | `:Seats` ConfigFromEnv; `:SeatPool` PoolConfig | run: `0.5` at max and any other effort, `0.125` at xhigh; `seats`: `10` | As MAX_UTIL. PoolConfig puts in the effort's figure only when it is unset or blank, so a set but invalid value gives 10, in run too. | Percentage points of the 5-hour window a running process is projected to add (its cost on the board too) |
| `REVIEW_GATES_SEAT_POLICY` | `:Seats` ConfigFromEnv | `spread` | Exactly `pack` (case-sensitive, untrimmed) is pack; anything else spread. | pack: the first eligible OAuth seat by id; spread: the lowest projected one | | `REVIEW_GATES_SEAT_POLICY` | `:Seats` ConfigFromEnv | `spread` | Exactly `pack` (case-sensitive, untrimmed) is pack; anything else spread. | pack: the first eligible OAuth seat by id; spread: the lowest projected one |
| `REVIEW_GATES_SEAT_WAIT_MIN` | `:Seats` ConfigFromEnv | `15` | As MAX_UTIL | Shown by `seats --json` as `waitMaxMin`; nothing else reads it | | `REVIEW_GATES_SEAT_WAIT_MIN` | `:Seats` ConfigFromEnv | `15` | As MAX_UTIL | Shown by `seats --json` as `waitMaxMin`; nothing else reads it |
| `REVIEW_GATES_SEAT_HANDOVER_PCT` | `:Seats` ConfigFromEnv | `90` | As MAX_UTIL | Shown in the `seats` report and `--json` only | | `REVIEW_GATES_SEAT_HANDOVER_PCT` | `:Seats` ConfigFromEnv | `90` | As MAX_UTIL | Shown in the `seats` report and `--json` only |

View file

@ -518,10 +518,10 @@ namespace Crafter::Review::SeatPool {
return n && !Dyn::Strip(text).empty() && std::isfinite(*n) && *n >= 0 ? *n : fallback; return n && !Dyn::Strip(text).empty() && std::isfinite(*n) && *n >= 0 ? *n : fallback;
} }
// A pass's share of the weekly window, as measured: 0.04 at xhigh, // A pass's share of the weekly window: the config's, else the max
// 0.125 at max and for any other effort. // figure.
double Cost7d(const Json& config) { double Cost7d(const Json& config) {
return Dyn::Has(config, "lensCost7dPct") ? AsDouble(config.at("lensCost7dPct")) : 0.125; return Dyn::Has(config, "lensCost7dPct") ? AsDouble(config.at("lensCost7dPct")) : LensCost7dPct({});
} }
// The weekly window with the passes in flight and this one projected // The weekly window with the passes in flight and this one projected
@ -540,8 +540,8 @@ namespace Crafter::Review::SeatPool {
Json PoolConfig(const std::map<std::string, std::string>& env, std::string_view effort) { Json PoolConfig(const std::map<std::string, std::string>& env, std::string_view effort) {
Json config = Seats::ConfigFromEnv(env); Json config = Seats::ConfigFromEnv(env);
if (Dyn::Strip(EnvOf(env, "REVIEW_GATES_LENS_COST_PCT")).empty()) config["lensCostPct"] = 0.25; if (Dyn::Strip(EnvOf(env, "REVIEW_GATES_LENS_COST_PCT")).empty()) config["lensCostPct"] = LensCostPct(effort);
config["lensCost7dPct"] = EnvNumber(env, "REVIEW_GATES_LENS_COST_7D_PCT", effort == "xhigh" ? 0.04 : 0.125); config["lensCost7dPct"] = EnvNumber(env, "REVIEW_GATES_LENS_COST_7D_PCT", LensCost7dPct(effort));
config["oauthConcurrency"] = static_cast<std::int64_t>(EnvNumber(env, "REVIEW_GATES_OAUTH_CONCURRENCY", static_cast<double>(OauthConcurrency))); config["oauthConcurrency"] = static_cast<std::int64_t>(EnvNumber(env, "REVIEW_GATES_OAUTH_CONCURRENCY", static_cast<double>(OauthConcurrency)));
return config; return config;
} }

View file

@ -43,6 +43,16 @@ export namespace Crafter::Review::SeatPool {
// rejections, none of the 119 with 139 or fewer. // rejections, none of the 119 with 139 or fewer.
// REVIEW_GATES_OAUTH_CONCURRENCY overrides. // REVIEW_GATES_OAUTH_CONCURRENCY overrides.
constexpr std::int64_t OauthConcurrency = 128; constexpr std::int64_t OauthConcurrency = 128;
// What one running pass is projected to cost of an OAuth seat's windows,
// in percentage points, by the run's reasoning effort (every lens of a run
// shares --effort): the pooled means of 5438 Opus 5.5 passes on 141
// seat-runs (2026-10-12..15), rounded up - max 0.44 / 0.118, xhigh
// 0.12 / 0.033. The 85 % ceiling and the cutoff's last percent absorb the
// spread. An effort not in the table projects at the max figures;
// REVIEW_GATES_LENS_COST_PCT and REVIEW_GATES_LENS_COST_7D_PCT override
// every effort.
constexpr double LensCostPct(std::string_view effort) { return effort == "xhigh" ? 0.125 : 0.5; }
constexpr double LensCost7dPct(std::string_view effort) { return effort == "xhigh" ? 0.04 : 0.125; }
// The kinds whose processes cost money the ledger counts. // The kinds whose processes cost money the ledger counts.
constexpr std::array<std::string_view, 2> Paid = {"api", "openrouter"}; constexpr std::array<std::string_view, 2> Paid = {"api", "openrouter"};
// The kinds whose out/invalid verdict crosses drivers on the board. // The kinds whose out/invalid verdict crosses drivers on the board.
@ -101,12 +111,9 @@ export namespace Crafter::Review::SeatPool {
void ApplyProbe(Json& seat, const Json& result); void ApplyProbe(Json& seat, const Json& result);
std::string Describe(const Json& seat); std::string Describe(const Json& seat);
// The OAuth placement knobs, with the pool's own per-process projections: // The OAuth placement knobs, with the pool's own per-pass projections at
// 0.25 of the 5-hour window (the 2026-10-15 load test moved a 20x seat's // the run's effort (LensCostPct, LensCost7dPct; the env overrides them)
// window 0.08 points a pass) and, for an account without a 5-hour limit, // and the per-account cap.
// the measured share of the weekly window at the run's effort (0.04 at
// xhigh, 0.125 otherwise; REVIEW_GATES_LENS_COST_7D_PCT); and the
// per-account cap.
Json PoolConfig(const std::map<std::string, std::string>& env, std::string_view effort = {}); Json PoolConfig(const std::map<std::string, std::string>& env, std::string_view effort = {});
double OauthProjected(const Json& seat, const Json& config); double OauthProjected(const Json& seat, const Json& config);
// A window whose reset has passed counts as empty until the next reading. // A window whose reset has passed counts as empty until the next reading.

View file

@ -28,8 +28,12 @@ export namespace Crafter::Review::Seats {
// Fixed rules, not knobs: utilisation is rounded to RankQuantum before // Fixed rules, not knobs: utilisation is rounded to RankQuantum before
// ranking, and a seat whose 7-day window is at or above LongWindowCutoff is // ranking, and a seat whose 7-day window is at or above LongWindowCutoff is
// out regardless — its reset is days away. The Fable window is exempt here. // out regardless — its reset is days away. The Fable window is exempt here.
// 99 since 2026-10-15 (95 before): the weekly window is the budget the
// lenses run out of, and the pool projects its running passes against the
// cutoff (SeatPool::LensCost7dPct), so the last percent is spent a pass at
// a time, not in a burst.
constexpr std::int32_t RankQuantum = 5; constexpr std::int32_t RankQuantum = 5;
constexpr std::int32_t LongWindowCutoff = 95; constexpr std::int32_t LongWindowCutoff = 99;
// JavaScript's Math.round: halves go up, never to even. // JavaScript's Math.round: halves go up, never to even.
double JsRound(double x); double JsRound(double x);

View file

@ -261,7 +261,7 @@ drivers running and what they hold. The seat pool still places
every process by its seat's projected 5-hour headroom every process by its seat's projected 5-hour headroom
(`REVIEW_GATES_LENS_COST_PCT`, `REVIEW_GATES_SEAT_MAX_UTIL`) — or, on an (`REVIEW_GATES_LENS_COST_PCT`, `REVIEW_GATES_SEAT_MAX_UTIL`) — or, on an
account whose 5-hour limit Anthropic has removed, by its weekly window account whose 5-hour limit Anthropic has removed, by its weekly window
under the 95 % cutoff — at most 128 passes per account, every driver's under the 99 % cutoff — at most 128 passes per account, every driver's
counted (`REVIEW_GATES_OAUTH_CONCURRENCY`), and a pass counted (`REVIEW_GATES_OAUTH_CONCURRENCY`), and a pass
launches only when its environment's instrument is free and it fits in launches only when its environment's instrument is free and it fits in
free memory (How the passes share the stacks): the driver logs per gate free memory (How the passes share the stacks): the driver logs per gate

View file

@ -169,14 +169,14 @@ namespace {
const Json f1 = At(sa, "1").at("foreign"); const Json f1 = At(sa, "1").at("foreign");
const Json fa = At(sa, "api1").at("foreign"); const Json fa = At(sa, "api1").at("foreign");
Check("three passes of B on seat 1 and two on api1 fold into A as foreign, at B's own per-pass figures", Check("three passes of B on seat 1 and two on api1 fold into A as foreign, at B's own per-pass figures",
f1.at("count") == 3 && Dyn::Equal(f1.at("cost5h"), 0.75) && Dyn::Equal(f1.at("costUsd"), 0) && fa.at("count") == 2 && Dyn::Equal(fa.at("costUsd"), 2.0) f1.at("count") == 3 && Dyn::Equal(f1.at("cost5h"), 1.5) && Dyn::Equal(f1.at("costUsd"), 0) && fa.at("count") == 2 && Dyn::Equal(fa.at("costUsd"), 2.0)
&& Dyn::Equal(f1.at("drivers"), {{B.Me(), 3}}), && Dyn::Equal(f1.at("drivers"), {{B.Me(), 3}}),
std::format("{} {}", DumpSpaced(f1), DumpSpaced(fa))); std::format("{} {}", DumpSpaced(f1), DumpSpaced(fa)));
Json s84 = mk("x", "oauth", "tx", 84, 50); Json s84 = mk("x", "oauth", "tx", 84, 50);
s84["foreign"] = {{"count", 3}, {"cost5h", 1.5}, {"costUsd", 0}}; s84["foreign"] = {{"count", 3}, {"cost5h", 1.5}, {"costUsd", 0}};
const bool over = !SeatPool::Eligible(s84, now, cfg, acfg); const bool over = !SeatPool::Eligible(s84, now, cfg, acfg);
Json s84Bare = With(s84, {{"foreign", {{"count", 0}, {"cost5h", 0.0}, {"costUsd", 0.0}}}}); Json s84Bare = With(s84, {{"foreign", {{"count", 0}, {"cost5h", 0.0}, {"costUsd", 0.0}}}});
Check("the 5-hour projection counts the foreign passes: 84 + 1.5 + 0.25 is over 85, without them under", over && SeatPool::Eligible(s84Bare, now, cfg, acfg)); Check("the 5-hour projection counts the foreign passes: 84 + 1.5 + 0.5 is over 85, without them under", over && SeatPool::Eligible(s84Bare, now, cfg, acfg));
Json a8 = mk("api9", "api", "k9"); Json a8 = mk("api9", "api", "k9");
a8["foreign"] = {{"count", 6}, {"cost5h", 0}, {"costUsd", 6.0}}; a8["foreign"] = {{"count", 6}, {"cost5h", 0}, {"costUsd", 6.0}};
a8["running"] = 2; a8["running"] = 2;
@ -338,7 +338,7 @@ namespace {
// The board's reading of the account (40, B's) folded in before the // The board's reading of the account (40, B's) folded in before the
// projection. // projection.
const Json base = sm["windows"]["five_hour"]["utilization"]; const Json base = sm["windows"]["five_hour"]["utilization"];
Check("a driver's passes fold at its own projection (2 % each) into another driver's (0.25 %)", Check("a driver's passes fold at its own projection (2 % each) into another driver's (0.5 %)",
Dyn::Equal(sm["foreign"], {{"count", 2}, {"cost5h", 4.0}, {"cost7d", 0.25}, {"costUsd", 0}, {"drivers", {{D.Me(), 2}}}}) && base == 40 Dyn::Equal(sm["foreign"], {{"count", 2}, {"cost5h", 4.0}, {"cost7d", 0.25}, {"costUsd", 0}, {"drivers", {{D.Me(), 2}}}}) && base == 40
&& SeatPool::OauthProjected(sm, cfg) == base.get<double>() + 4.0, && SeatPool::OauthProjected(sm, cfg) == base.get<double>() + 4.0,
std::format("{} {}", DumpSpaced(sm["foreign"]), base.dump())); std::format("{} {}", DumpSpaced(sm["foreign"]), base.dump()));

View file

@ -59,8 +59,9 @@ int main() {
Ids(seats) == "api1,1,2" && Ids(SeatPool::LoadSeats({}, std::nullopt, "")) == "local", Ids(seats)); Ids(seats) == "api1,1,2" && Ids(SeatPool::LoadSeats({}, std::nullopt, "")) == "local", Ids(seats));
const std::string summary = DumpSpaced(SeatPool::Summary(seats)); const std::string summary = DumpSpaced(SeatPool::Summary(seats));
Check("no secret in the summary or the table", !(summary + SeatPool::Table(seats)).contains("tok-one") && !summary.contains("sk-ant")); Check("no secret in the summary or the table", !(summary + SeatPool::Table(seats)).contains("tok-one") && !summary.contains("sk-ant"));
Check("the pool's default projection is 0.25% of the 5-hour window per process (measured 0.08, 2026-10-15); the env overrides", Check("the 5-hour share of a pass follows the run's effort (0.125 at xhigh, 0.5 at max and any other); the env overrides every effort",
Dyn::Equal(SeatPool::PoolConfig({}).at("lensCostPct"), 0.25) && Dyn::Equal(SeatPool::PoolConfig({{"REVIEW_GATES_LENS_COST_PCT", "5"}}).at("lensCostPct"), 5)); Dyn::Equal(SeatPool::PoolConfig({}).at("lensCostPct"), 0.5) && Dyn::Equal(SeatPool::PoolConfig({}, "max").at("lensCostPct"), 0.5)
&& Dyn::Equal(SeatPool::PoolConfig({}, "xhigh").at("lensCostPct"), 0.125) && Dyn::Equal(SeatPool::PoolConfig({{"REVIEW_GATES_LENS_COST_PCT", "5"}}, "xhigh").at("lensCostPct"), 5));
const double now = std::floor(Platform::Now()); const double now = std::floor(Platform::Now());
Json& api1 = seats[0]; Json& api1 = seats[0];
@ -109,7 +110,7 @@ int main() {
Check("...and the seat is back after the back-off", !requeued && sc.at("state") == "ok" && SeatPool::Eligible(sc, now + SeatPool::ConcurrentBackoffS + 1, cfg, acfg)); Check("...and the seat is back after the back-off", !requeued && sc.at("state") == "ok" && SeatPool::Eligible(sc, now + SeatPool::ConcurrentBackoffS + 1, cfg, acfg));
// 2026-10-31: an account whose 5-hour limit is removed reports the weekly // 2026-10-31: an account whose 5-hour limit is removed reports the weekly
// window alone; until then the pool took it for an unprobed seat - ranked // window alone; until then the pool took it for an unprobed seat - ranked
// after every other, never held to the weekly cutoff. The cutoff is 95 %. // after every other, never held to the weekly cutoff. The cutoff is 99 %.
const Json px = SeatPool::PoolConfig({}, "xhigh"); const Json px = SeatPool::PoolConfig({}, "xhigh");
Json nf = With(SeatPool::NewSeat("n", "oauth", "tn"), {{"state", "ok"}, {"running", 0}, {"pauseUntil", 0}, {"windows", {{"seven_day", {{"utilization", 3}, {"resetsAt", now + 6 * 86400}}}}}}); Json nf = With(SeatPool::NewSeat("n", "oauth", "tn"), {{"state", "ok"}, {"running", 0}, {"pauseUntil", 0}, {"windows", {{"seven_day", {{"utilization", 3}, {"resetsAt", now + 6 * 86400}}}}}});
Json f15 = With(SeatPool::NewSeat("f", "oauth", "tf"), {{"state", "ok"}, {"running", 0}, {"pauseUntil", 0}, Json f15 = With(SeatPool::NewSeat("f", "oauth", "tf"), {{"state", "ok"}, {"running", 0}, {"pauseUntil", 0},
@ -119,13 +120,13 @@ int main() {
for (const Json* s : SeatPool::Ranked(pair, now, px, acfg)) order.push_back(s->at("id").get<std::string>()); for (const Json* s : SeatPool::Ranked(pair, now, px, acfg)) order.push_back(s->at("id").get<std::string>());
Check("an account without a 5-hour window is placed by its weekly one: ranked by it, ahead of a seat at 5h 15 %, its running passes projected at the weekly figure", Check("an account without a 5-hour window is placed by its weekly one: ranked by it, ahead of a seat at 5h 15 %, its running passes projected at the weekly figure",
order == std::vector<std::string>{"n", "f"} && std::abs(SeatPool::OauthProjected(With(nf, {{"running", 100}}), px) - 7.0) < 1e-9, Dyn::Join(order, ",")); order == std::vector<std::string>{"n", "f"} && std::abs(SeatPool::OauthProjected(With(nf, {{"running", 100}}), px) - 7.0) < 1e-9, Dyn::Join(order, ","));
Json n93 = With(nf, {{"windows", {{"seven_day", {{"utilization", 93}, {"resetsAt", now + 86400}}}}}}); Json n97 = With(nf, {{"windows", {{"seven_day", {{"utilization", 97}, {"resetsAt", now + 86400}}}}}});
Json n93r40 = With(n93, {{"running", 40}}); Json n97r40 = With(n97, {{"running", 40}});
Json n93r60 = With(n93, {{"running", 60}}); Json n97r60 = With(n97, {{"running", 60}});
Check("...under the weekly cutoff alone, no 5-hour ceiling: at 93 % it takes a pass with 40 running, not with 60 (93 + 61 x 0.04 >= 95)", Check("...under the weekly cutoff alone, no 5-hour ceiling: at 97 % it takes a pass with 40 running, not with 60 (97 + 61 x 0.04 >= 99)",
SeatPool::Eligible(n93r40, now, px, acfg) && !SeatPool::Eligible(n93r60, now, px, acfg)); SeatPool::Eligible(n97r40, now, px, acfg) && !SeatPool::Eligible(n97r60, now, px, acfg));
Json n95 = With(nf, {{"windows", {{"seven_day", {{"utilization", 95}, {"resetsAt", now + 86400}}}}}}); Json n99 = With(nf, {{"windows", {{"seven_day", {{"utilization", 99}, {"resetsAt", now + 86400}}}}}});
Check("...and over the cutoff it waits for its weekly reset + 30 s", !SeatPool::Eligible(n95, now, px, acfg) && SeatPool::EarliestResume({n95}, now) == now + 86430); Check("...and over the cutoff it waits for its weekly reset + 30 s", !SeatPool::Eligible(n99, now, px, acfg) && SeatPool::EarliestResume({n99}, now) == now + 86430);
Json n127 = With(nf, {{"running", 127}}); Json n127 = With(nf, {{"running", 127}});
Json n128 = With(nf, {{"running", 128}}); Json n128 = With(nf, {{"running", 128}});
Json nShared = With(nf, {{"running", 100}, {"foreign", {{"count", 28}, {"cost5h", 0.0}, {"cost7d", 0.0}, {"costUsd", 0.0}}}}); Json nShared = With(nf, {{"running", 100}, {"foreign", {{"count", 28}, {"cost5h", 0.0}, {"cost7d", 0.0}, {"costUsd", 0.0}}}});

View file

@ -82,7 +82,7 @@ int main() {
Eq(lines.at(3), "| 2 | 61% | 10:10 (in 10 min) | 18% | Thu 10 Sept, 10:00 (in 3d 0h) | — |"); Eq(lines.at(3), "| 2 | 61% | 10:10 (in 10 min) | 18% | Thu 10 Sept, 10:00 (in 3d 0h) | — |");
Eq(lines.at(4), "| 3 | 62% | 10:15 (in 15 min) | 16% | Thu 10 Sept, 10:00 (in 3d 0h) | 22% |"); Eq(lines.at(4), "| 3 | 62% | 10:15 (in 15 min) | 16% | Thu 10 Sept, 10:00 (in 3d 0h) | 22% |");
Eq(lines.at(5), ""); Eq(lines.at(5), "");
Eq(lines.at(6), "policy spread · ceiling 85% · handover at 90% · a lens is placed at +10% · 7d cutoff 95%"); Eq(lines.at(6), "policy spread · ceiling 85% · handover at 90% · a lens is placed at +10% · 7d cutoff 99%");
Eq(lines.at(7), "eligible now: seat 2 (25% headroom), seat 3 (25% headroom) → next lens: seat 2"); Eq(lines.at(7), "eligible now: seat 2 (25% headroom), seat 3 (25% headroom) → next lens: seat 2");
Eq(lines.at(8), "fable lenses: seat 3 (63% fable headroom)"); Eq(lines.at(8), "fable lenses: seat 3 (63% fable headroom)");
Eq(lines.at(9), "limited: seat 1 until 10:05 (in 5 min)"); Eq(lines.at(9), "limited: seat 1 until 10:05 (in 5 min)");
@ -223,8 +223,8 @@ int main() {
auto pair = [](const std::pair<Json, std::string>& p) { return Json::array({p.first, p.second}); }; auto pair = [](const std::pair<Json, std::string>& p) { return Json::array({p.first, p.second}); };
EqJson(pair(SeatUtil({{"five_hour", {{"utilization", 61}, {"resetsAt", 1}}}, {"seven_day", {{"utilization", 18}, {"resetsAt", 2}}}})), Json::array({60, "five_hour"})); EqJson(pair(SeatUtil({{"five_hour", {{"utilization", 61}, {"resetsAt", 1}}}, {"seven_day", {{"utilization", 18}, {"resetsAt", 2}}}})), Json::array({60, "five_hour"}));
EqJson(pair(SeatUtil({{"five_hour", {{"utilization", 12}, {"resetsAt", 1}}}, {"seven_day_fable", {{"utilization", 97}, {"resetsAt", 2}}}})), Json::array({95, "seven_day_fable"})); EqJson(pair(SeatUtil({{"five_hour", {{"utilization", 12}, {"resetsAt", 1}}}, {"seven_day_fable", {{"utilization", 97}, {"resetsAt", 2}}}})), Json::array({95, "seven_day_fable"}));
Eq(IsEligible(seat(1, 10, 96), With(cfg, {{"maxUtil", 100}})), false); Eq(IsEligible(seat(1, 10, 99), With(cfg, {{"maxUtil", 100}})), false);
Eq(IsEligible(seat(1, 10, 94), With(cfg, {{"maxUtil", 100}})), true); Eq(IsEligible(seat(1, 10, 98), With(cfg, {{"maxUtil", 100}})), true);
Eq(IsEligible(seat(1, 10, 94), cfg), false); Eq(IsEligible(seat(1, 10, 94), cfg), false);
// Redaction: the seat's own token, token shapes and addresses; auth // Redaction: the seat's own token, token shapes and addresses; auth
// failures by status or by text. // failures by status or by text.