Gate-found (Opus SHIP-WITH-FIXES; Codex SAFE — split resolved by reading the contract: no dropped-turn, but a real transient start-race flicker). #4424 removed the _sendInProgress guards entirely; that re-opened the #2689 start-race SYMPTOM for the one session mid-send (a /api/sessions poll landing during the /api/chat/start round-trip would blank the just-sent bubble + queue a spurious force-reload). Re-add the guard SCOPED to sid===_sendInProgressSid only, in both _reconcileActiveSessionIdleStateFromList and _purgeStaleInflightEntries — a long-hung session has _sendInProgress===false so it still gets unstuck (#4354), only the in-flight start window is protected. Also fixes Opus's test-masking finding: test_inflight_send_start_race now strips JS comments before asserting + requires a real , so a comment can't green-light the #2689 guard, and adds coverage for the reconcile path. Co-authored-by: bergeouss <bergeouss@users.noreply.github.com>
This commit is contained in:
1 parent
0a1e5d97a4
commit
f57c0330ec
2 files changed
+47
-3
No files matched your search
@@ -39,9 +39,19 @@ def test_send_preserves_optimistic_messages_across_chat_start_await():
|
||||
)
|
||||
|
||||
|
||||
def _strip_js_comments(src: str) -> str:
|
||||
"""Remove // line comments and /* */ block comments so source-grep assertions
|
||||
match real statements, not comment text (a comment must not satisfy a guard
|
||||
regression check). Good enough for these structural checks — not a full JS parser."""
|
||||
import re
|
||||
src = re.sub(r"/\*.*?\*/", "", src, flags=re.DOTALL)
|
||||
src = re.sub(r"(?m)//.*$", "", src)
|
||||
return src
|
||||
|
||||
|
||||
def test_stale_inflight_purge_preserves_current_send_before_stream_id_exists():
|
||||
"""Sidebar cleanup must not delete the active send before /api/chat/start responds."""
|
||||
body = _function_body(SESSIONS_JS, "_purgeStaleInflightEntries")
|
||||
body = _strip_js_comments(_function_body(SESSIONS_JS, "_purgeStaleInflightEntries"))
|
||||
|
||||
assert "_sendInProgress" in body and "_sendInProgressSid" in body, (
|
||||
"_purgeStaleInflightEntries() should skip the current send while start is in progress"
|
||||
@@ -49,6 +59,27 @@ def test_stale_inflight_purge_preserves_current_send_before_stream_id_exists():
|
||||
skip_idx = body.index("_sendInProgress")
|
||||
delete_idx = body.index("delete INFLIGHT[sid];")
|
||||
assert skip_idx < delete_idx, "the current-send skip must run before any purge deletion"
|
||||
# The skip must be a real guarded `continue`, not just a token in a comment (#4354/#2689).
|
||||
assert "continue;" in body[skip_idx:delete_idx], (
|
||||
"the current-send skip must be an actual `continue` before the purge deletion"
|
||||
)
|
||||
|
||||
|
||||
def test_idle_reconcile_preserves_current_send_before_stream_id_exists():
|
||||
"""The list-poll idle reconciler must not clear the session that is mid-send.
|
||||
|
||||
#4354 removed the _sendInProgress guard here to unstick a hung indicator;
|
||||
#2689's start-race protection must still cover the ONE session actively
|
||||
mid-send (server row is briefly idle during /api/chat/start). Verified
|
||||
against comment-stripped source so a comment can't satisfy the check.
|
||||
"""
|
||||
body = _strip_js_comments(_function_body(SESSIONS_JS, "_reconcileActiveSessionIdleStateFromList"))
|
||||
assert "_sendInProgress" in body and "_sendInProgressSid" in body, (
|
||||
"_reconcileActiveSessionIdleStateFromList() must skip the active mid-send session"
|
||||
)
|
||||
guard_idx = body.index("_sendInProgress")
|
||||
clear_idx = body.index("S.busy=false")
|
||||
assert guard_idx < clear_idx, "the mid-send skip must run before the idle clear"
|
||||
|
||||
|
||||
def test_send_clears_stale_busy_state_before_queue_branch():
|
||||
|
||||
Reference in new issue
Block a user