fix: steer-delivery starvation — continuation coalescing (claimSteers)
The bug (seen live): a teacher that ends every turn with a new pending quiz keeps the wake pipeline's idle gates permanently closed — the steer sits in 'delivering result' forever while the learner answers check after check. - claimSteers (server/jobs.ts): the chat-handler claims every queued, undelivered steer the instant a client turn wins the turn registry, and appends it after the learner's answer — conversion-safe, the answered quiz carries its output. Every answer flushes pending steers immediately. - The pump keeps its post-idle duplicate-guard (re-check steerDelivered before firing), so a claim racing the pump converges to exactly one delivery either way. - The stale-job sweep now skips chats with a turn in flight (a healthy but slow wake no longer gets falsely re-queued as 'recovering'). - Out-of-lane surgical touch (flagged for master review): the 3-line handleChatRequest seam (claim after beginTurn, persist+stream 'outgoing'). - Verified live end-to-end on the stuck session: answering the pending quiz fired the steer + wake turn within a second; job flipped done/delivered.
This commit is contained in:
@@ -73,6 +73,17 @@ export interface JobRecord {
|
||||
* a polling client that sees the flip re-syncs once and gets the
|
||||
* finished record.
|
||||
*
|
||||
* CONTINUATION COALESCING: the idle window above can starve — a
|
||||
* quiz-chaining teacher ends every turn with a new pending check, so
|
||||
* the gates never stay open long enough for a wake to fire. The fix:
|
||||
* when a client turn wins the turn registry, the handler CLAIMS every
|
||||
* queued, undelivered steer (jobs.ts claimSteers) and appends it after
|
||||
* the learner's answer in that very turn — conversion-safe, because the
|
||||
* answered quiz carries its output. Every answer flushes pending
|
||||
* steers immediately; the wake pump remains for turns that end with no
|
||||
* pending question. The pump re-checks steerDelivered right before
|
||||
* firing, so a claim racing the pump converges to exactly one delivery.
|
||||
*
|
||||
* 5. No pending job parts ever exist, so the composer never gates on jobs
|
||||
* (the learner can interject mid-job; the steer queues behind their
|
||||
* turn) and job tool outputs never trigger the client-side
|
||||
|
||||
Reference in New Issue
Block a user