Skip to content

fix(sessions): pin a session per weekly bucket, not once overall - #189

Open
ak2k wants to merge 1 commit into
KarpelesLab:masterfrom
ak2k:upstream/per-bucket-pins
Open

fix(sessions): pin a session per weekly bucket, not once overall#189
ak2k wants to merge 1 commit into
KarpelesLab:masterfrom
ak2k:upstream/per-bucket-pins

Conversation

@ak2k

@ak2k ak2k commented Aug 24, 2026

Copy link
Copy Markdown

A session holds one pin, so whichever model family routed last owns the whole session.

The bug

Quota and eligibility are already decided per weekly bucket: an account whose Fable weekly is spent still serves Opus, and _isAvailable says so. Session affinity is the one place that reads a single answer out of a per-bucket world. A Fable request diverted off the pinned account re-pins the session there, and the next Opus request follows it onto an account nothing evaluated for Opus, whose Opus cache is cold.

Measured with a fixed schedule (one session interleaving Opus and Fable across four accounts, account i's Fable weekly going spent after phase i, both trees seeing identical fleet state at every boundary): before, the Opus traffic re-homed twice, walking accounts it was never evaluated for; after, it holds its account for all nine of its Opus turns while the Fable half diverts independently.

The fix

Key each pin by the bucket that governs the request, using _weeklyBucketFor, the same key selection already uses for eligibility. recordSession pins the bucket the request spent; _selectForSession looks up the executor's. removeAccount remaps session pins beside the route pins it already remaps, so both survive account removal symmetrically.

Scope

distributeSessions gates the whole routing effect, and it defaults off. Flag off, 300+ interleaved requests with realistic durations across four families: account sequences byte-identical to master, per-session attribution 0 split / 0 unattributed on both trees.

What the flag does not gate is the readout: pins are recorded either way, and perAccount counts a split session on each account it is live on, once each, so it can sum to more than active. The invariant that holds: a routed, currently active session is counted on at least one account. One narrow case is disclosed in the body of the change: with two concurrent requests on different buckets, the account whose request ends last can read idle for up to the activity window.

Tests

525 before, 541 after, 0 fail; npx eslint . clean. Reverting the pin keying with the new tests in place: 532 pass, 9 fail. Dropping only the end-of-request refresh: 538 pass, 3 fail. Dropping only the remap: 539 pass, 2 fail. Each red test names the behavior it pins.

Notes

This is the base of a small stack: the expiry-routing PR and the accounting PR build on it. Merging out of order will conflict.

A session held one pin, so a routing decision taken for one model family
relocated the whole session. An account whose Fable weekly is spent still
serves Opus, so a Fable request diverts to another account, re-pins the
session there, and the next Opus request follows it onto an account nothing
evaluated for Opus and whose Opus cache is cold. Whichever family routed last
owned the session.

Key each pin by the weekly bucket that governs the request, using the key
selection already applies for eligibility, so the families keep independent
affinities. recordSession takes the request's model to name the bucket it
spent; session selection looks up the executor's.

The load metric follows the pin: a session counts on every account it is
currently spending, once each, and a pin stops counting once its bucket has
been quiet for the active window. Finishing a request ages the pin it was
spending, so an account does not drop out of the metric the moment it
completes a long stream.

removeAccount renumbers session pins the way it already renumbers route pins.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant