Repository navigation
fix(desktop): send only the durable row_id on rewind, not the ordinal - #90091
RichardGuan1 wants to merge 1 commit into
Conversation
The renderer's user-ordinal can drift from the gateway's durable ordinal (75 vs 102, NousResearch#87059), so a rewind carrying both a bound row_id and that stale ordinal failed the gateway's 4030 cross-check even though the row_id resolved fine. The gateway prefers row_id over ordinals, so send the ordinal and message-id only when no row_id is available; a stale row_id still fails closed (4018). Tests cover the row_id-only path and ordinal-0 confirm_empty_truncate.
Precise fix for a false-refusal class: when a bound integer No blocking issues found. — reviewer-a · automated agent review (Hermes week-review) |
|
Thanks — right diagnosis on the #87059 class: a bound durable row_id should aim the cut alone, and sending a divergent renderer ordinal alongside it tripped the gateway's 4030 cross-check into refusing legitimate rewinds. This landed on main via PR #93784 (the composite-carrier retry/undo salvage, merged today): Closing as implemented on main. Appreciate the careful writeup — sorry the broader carrier rework got there first. |
Problem
Rewinding, editing, or regenerating a turn on a long-lived desktop session fails server-side
with:
(code
4030, from_reconcile_client_ordinal). The desktop sent all three truncationaddresses at once (
truncate_before_user_ordinal,truncate_before_message_id,truncate_before_row_id). The gateway resolves the row_id to its own durable ordinal andrefuses any mismatch — but across a long session the renderer's visible-user ordinal drifts
from the gateway's active-durable ordinal (the #87059 drift class; observed 7 → 27 in one
day), so the ordinal is wrong even though the row_id is correct, and every legitimate rewind
gets refused. Reproducible on current main (9 refusals on one session), independent of
context compression (prefix_user_count=0).
Fix
When a bound integer row_id is available, the desktop sends only
truncate_before_row_idanddrops the redundant ordinal + message-id. This matches the gateway's documented contract —
prefer row_id over ordinals, and keep the ordinal only as a back-compat / optimistic-row path
when no durable id exists. Safety is unchanged: an unknown/dead row_id still fails closed with
4018, dropped turns are soft-archived (active=0) rather than deleted, andconfirm_truncate/ ordinal-0
confirm_empty_truncategating is preserved.Tests
Updated
rewind.test.tsso a bound rowId plus a divergent ordinal sends row_id alone, and anordinal-0 restore still carries
confirm_empty_truncate.rewind.test.ts32 +index.test.tsx122 pass (216 in
use-prompt-actions/).