mirror of
https://github.com/CopilotKit/CopilotKit.git
synced 2026-09-14 16:26:20 +08:00
c3a13ac988
P1-A (cap semantics): the MAX_RECLAIM_ATTEMPTS cap was keyed on `reclaim_count`, a LIFETIME tally bumped by BOTH the sweeper re-queue path AND the peer-worker expired-lease steal (claim CAS). A long-lived job that accrues benign peer steals could exhaust its 3-budget and then get claim-DELETED on its first real orphan rather than re-queued. Fix: introduce a dedicated `consecutive_orphan_count` column (migration 1779990400) that is bumped ONLY by the sweeper re-queue path in the fleet-claim release CAS, and reset to 0 on every terminal done|failed release. The peer-worker steal (claim CAS wasExpiredSteal branch) does NOT touch this counter. The reaper's cap check now uses `consecutive_orphan_count` instead of `reclaim_count`. `reclaim_count` is left intact as the lifetime dashboard diagnostic (jobs.reclaimed). P1-B (low boundary): adds a test at consecutive_orphan_count = MAX-1 (= 2) asserting the row is RE-QUEUED, not deleted. The off-by-one mutation `>= MAX` -> `>= MAX-1` causes this test to go RED. Test-fake honesty: `makeReclaimClaim`'s claimJob now explicitly models the steal-bump on `reclaim_count` (matching the real hook) while intentionally NOT bumping `consecutive_orphan_count`, and adds an explicit pin test confirming steals do not consume the reclaim budget. JSDoc on MAX_RECLAIM_ATTEMPTS updated to describe the correct semantics: consecutive re-orphans scoped by sweeper re-queue, reset on terminal. Red-green proof: - P1-A RED: revert cap to reclaim_count → "P1-A CAP SCOPE" fails with `expect(undefined).toBeDefined()` (job deleted instead of re-queued) - P1-A GREEN: consecutive_orphan_count cap → test passes (re-queued) - P1-B RED: mutate `>= MAX` to `>= MAX-1` → low-boundary test fails - P1-B GREEN: revert mutation → low-boundary test passes Suite: 145 queue-client + 103 producer = 248 total, all green.