fix(routing): bind a sticky pin to the account identity it was placed under - #86
Merged
Merged
Conversation
There was a problem hiding this comment.
All reported issues were addressed across 4 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
… under A pin recorded the slot it chose - 'main' or a fallback's storage id - not which ChatGPT account that slot held. Switch the main account, or re-login a fallback (upsertAccount dedups by identity then id then label, so the storage id is deliberately reused), and every session pinned to that slot stays pinned while the account underneath it changed. The session then holds a pin to an account the operator did not choose, whose prompt cache is cold - and cache warmth is the whole reason the pin exists. Placement now records the identity alongside the slot, and a pin whose recorded identity differs from the account's current one is treated as absent, so the session is placed again against real quota. The check fires only when both identities are known and differ. An unknown on either side retains the pin: identity is not always resolvable, and invalidating on missing data would re-place sessions at random and bust the caches this mode protects - worse than the bug. Pins written before this change carry no identity, so they are retained and stamped on first resolve rather than dropped, which would have cleared every warm cache on upgrade. Invalidating created a state pins did not previously have: present in the map, but no longer usable. Pending-byte accounting predates that state and counted such a pin as live pressure on its old slot, so a session's replacement was steered by load belonging to the identity it had just been unpinned from. The invalidated pin is now excluded from the pending bytes its own replacement is placed against. Only that one entry, and only on a known-to-known mismatch: other sessions' pins are not this call's business, and re-filtering the whole map by identity would drop un-stamped pre-upgrade pins from the accounting, which is the same fail-open violation in a different place.
iceteaSA
force-pushed
the
feat/sticky-identity-binding
branch
from
August 12, 2026 14:43
8d00ee7 to
a7b1745
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Branched off
mainat v0.5.2. Single commit, 935 pass / 0 fail (from 930).The pin recorded a slot, not an account
StickyAssignment.accountIdis'main'or a fallback's storage id — a slot. Which ChatGPT account occupies that slot can change underneath it: switching the main account does it, and so does re-logging a fallback, becauseupsertAccountdedups identity → id → label and deliberately reuses the storage id.When that happens every session pinned to the slot stays pinned, but to a different account than the operator chose, with a cold prompt cache. Cache warmth is the entire justification for pinning, so the pin was then protecting a cache that does not exist while also overriding the operator's choice.
Placement now records the identity alongside the slot, and a pin whose recorded identity differs from the account's current one is treated as absent — the session is placed again against real quota. This mirrors what
QuotaEntry.accountIdandsetFallbackalready do one layer over; the mechanism was in the codebase, it just was not applied to pins.Two constraints that mattered more than the feature
Fail open. Invalidation fires only when both identities are known strings and they differ. Identity is not always resolvable, and invalidating on missing data would re-place sessions at random and bust the caches this mode exists to protect — strictly worse than the bug. An unknown on either side retains the pin.
Migration retains. Every pin written before this change carries no identity. Dropping them on first resolve would clear every warm cache on upgrade, so they are retained and stamped instead; the check works from the second resolve onward.
Both are absence assertions, which is worth stating because it changes how they were verified.
Testing
Six production hunks, each mutated individually. Reverse-removal proves a positive assertion, but it cannot prove an absence one — deleting code moves it further into compliance with "unknown never invalidates", so the test can never redden. Those three used the inverse mutation instead: make the code invalidate unconditionally and confirm the fail-open tests break.
hasStickyIdentityMismatchwireAccountIdByAccountthreadingThe churn one is worth calling out: a matching-identity pin must not trigger a write on every resolve, or the unlocked fast path stops being fast and every request takes the lock.
Also verified rather than assumed: the threading feeds from the serving account's identity (
wireAccountIdon the candidate) and not the internal quota key — that key is the literal'main'for whichever account is primary, so using it would have silently defeated the whole change while leaving every test green. TTL expiry, the 256-entry cap, and LRS eviction are untouched, and the wire identity does not reach any log line.Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Summary by cubic
Bind sticky pins to the actual account identity so switching the main account or re‑logging a fallback no longer keeps sessions pinned to the wrong (cold‑cache) account. Old: pins recorded only the slot; New: pins store a wire account id and are treated as absent only when both the stored and current identities are known and differ.
wireAccountIdByAccountinto placement and persistwireAccountIdon pins; stamp pre‑upgrade pins on first resolve.Written for commit a7b1745. Summary will update on new commits.