Epic 105 — an allocator that never once resolved a desk
2026-07-01
The report was blunt: the allocator "isn't doing anything." Tracing two live cycles confirmed it — every recorded tick failed with no_resolvable_desks before any weight math ran. This was not a cold-start timing race that would clear once more data landed; it was a permanent, silent logic bug, and it had been there since the feature shipped.
The cause was a namespace mismatch between two ways of naming the same desks. When the allocator resolves a scored desk to the signer that would execute its trades, it looks the desk up by its deskId — yield-base, trader-base, short-arbitrum. But the map it looks in was built from the signing-key config, which is keyed by agentName — yield-live, trader-live, short-live. The two vocabularies never intersect, so the resolved-desk count was zero on every tick, unconditionally, live or not. The reason the tests were green is the quietly instructive part: they hand-built the signer map in the same fake namespace as their fake scores, so the lookup always matched in the test and never in production. A test that constructs both sides of a mapping from the same string can only ever prove the string equals itself.
The fix is small because the right binding already existed — a desks config map, added earlier for the allocator, carries the exact deskId-to-agentName translation that was missing from the lookup. Wiring it in is most of the work. The epic also removes a boot-time side effect: the allocator fired a tick the instant the overseer started, which burned ticks on every dev reload and process restart — during one live reboot it spent two ticks five seconds apart before any desk data was even ready. Now it runs only on its configured interval and on an explicit manual trigger, and the cycle history reads honestly instead of being seeded with boot noise.