fix(streaming): count live-worklog shell/reason as preserved structure (Codex r2)
Codex round 2 caught that _structuralCount() only enumerated .tool-call-group/ .tool-card-row/.tool-worklog-group but NOT the live Worklog shell (.live-worklog[data-live-worklog-shell=1]) or its .wl-reason content (built by _flushPendingSegmentRender / ensureLiveWorklogContainer, see messages.js:2386 + ui.js:6712/6655). So a turn whose live-ahead structure is a Worklog (not a bare tool-call-group) undercounted preserved structure → wrongly took the segment-swap path → detached the visible live Worklog container for a frame. Fix: add .live-worklog[data-live-worklog-shell=1] and .wl-reason to the structural count (mirrors the canonical 'has current worklog content' selector set at sessions.js:1125-1131). Added a structural-test assertion + verified live: a preserved turn with a live worklog .wl-reason the rebuild lacks now takes the whole-turn restore path and the worklog + parser both survive. Convergence: Codex findings narrowing each round (tie-guard → tail-segment → worklog-selector), all real, all fixed + empirically verified.
This commit is contained in:
@@ -9032,7 +9032,9 @@ function renderMessages(options){
|
||||
// Otherwise (rebuild has >= the preserved turn's structural blocks) do
|
||||
// the precise segment swap so rebuilt-only structure is kept.
|
||||
const _structuralCount=(turn)=> turn?turn.querySelectorAll(
|
||||
'[data-live-assistant="1"],.tool-call-group,.tool-card-row,.tool-worklog-group,.agent-activity-thinking,.thinking-card-row'
|
||||
'[data-live-assistant="1"],.tool-call-group,.tool-card-row,'+
|
||||
'.tool-worklog-group,.live-worklog[data-live-worklog-shell="1"],'+
|
||||
'.wl-reason,.agent-activity-thinking,.thinking-card-row'
|
||||
).length:0;
|
||||
const _preservedStructure=_structuralCount(_preservedLiveTurn);
|
||||
const _rebuiltStructure=_structuralCount(_rebuilt);
|
||||
|
||||
@@ -133,6 +133,15 @@ def test_reattach_swaps_at_segment_level_to_preserve_rebuilt_structure():
|
||||
"segment-level swap only when the rebuild is the structural superset; "
|
||||
"otherwise restore the whole preserved turn so live-only tool cards are kept"
|
||||
)
|
||||
# The structural count must include the LIVE WORKLOG shell + reason content, not
|
||||
# just .tool-call-group — a live worklog (data-live-worklog-shell) landing before
|
||||
# the throttled persist is exactly the live-ahead structure a segment-only swap
|
||||
# would detach (Codex round-2 CORE finding).
|
||||
assert '.live-worklog[data-live-worklog-shell="1"]' in reattach, (
|
||||
"structural count must include the live worklog shell so a worklog-only "
|
||||
"live-ahead turn takes the whole-turn restore path"
|
||||
)
|
||||
assert ".wl-reason" in reattach
|
||||
# Segment-level swap is the superset path.
|
||||
assert "_rebuiltSeg.replaceWith(_preservedSeg)" in reattach, (
|
||||
"the swap must be segment-level (replace the rebuilt live segment with the "
|
||||
|
||||
Reference in New Issue
Block a user