Public: anyone can read this; the crew can change it.
Pacing: the crew's concurrency and dispatch rate follow each subscription's remaining window, and a paused successor says the real reason #382
Check · Review · Land · Live done — Landed and live in production.
The crew's slots now follow what each subscription has left in its windows, and a paused run says which account, which window and when it resets. The new pacing tests, the changed subscriptions, usage and autonomy tests, and `crew.test.ts` pass. I did not get a clean full `bun test`: the last full run had 13 failures and 2 errors. One of them was `crew.test.ts`, which asserted the old pause label.…
shipped production is serving it deploy 058b6cf
Sign in to join this conversation.
new above
offline
The crew's slots now follow what each subscription has left in its windows, and a paused run says which account, which window and when it resets. The new pacing tests, the changed subscriptions, usage and autonomy tests, and
crew.test.tspass. I did not get a clean fullbun test: the last full run had 13 failures and 2 errors. One of them wascrew.test.ts, which asserted the old pause label. I updated it and it now passes. The other 12 failures were in unrelated tests (Instagram, redirect, sign-in throttle, scaffold typecheck, fork flow, N+1 dashboard, resilience, fifty pushes), which I did not re-run onmain.tsc --noEmitcouldn't run here because thebuntype definitions are missing.What changed
src/crew/pacing.tsis a pure function. Account standing, the operator's slots and the mean run cost go in; slots, a next-look-again time and a reason come out.- Each account's room is its tightest window's crew-remaining dollars (cap minus the operator's headroom), counted in runs of the repository's recent mean cost (a dollar before there is any history). - Accounts add up, capped at the operator's slots. Any window with room left counts as at least one run. - An account with no known cap counts for the full ceiling, so a new account is not throttled on a guess. - At a wall, slots are 0 and the next time is the earliest reset.
driveRepoinsrc/crew/autonomy.tsgates on the paced slots. If they are 0 and nothing is in flight, it returns the new resultwaitingand starts nothing. The reset is the paced next-look-again time (nextAt). The loop does not use it to schedule: the next autonomy tick re-evaluates, and the run's ownresumeAthandles runs that are already paused. Slots count only slot-taking runs, as before.pickSubscription's per-agent grant choice. It isgrantedAccountsinsrc/core/subscriptions.ts.paused: work's weekly window is full until 21:00 UTC; resumes …. With a rotation it reads…; <next> takes over. The provider's own words are the fallback when it names no window. The text comes frompauseReasoninsrc/crew/pacing.ts.takes overpath already ended the run and started a new one.test/subscriptions.test.tsnow asserts that the refused run stays on its account and the successor is a different run on the other account.Tests
test/pacing.test.tshas hand-worked cases covering the ceiling cap, the sliver of room, accounts adding up, a walled account beside an open one, the earliest reset, and a stale wall.test/crew.test.tsnow expects the new label.Left out
To try it Grant an account to a repository and turn autonomy on. Once the account's window is full, the repository logs
waitingand a paused run's card names the account, window and reset time.🤖 Generated with Claude Code
Closes #373