Preserve semantic timeline groups across window boundaries - #2466
Open
ymichael wants to merge 4 commits into
Open
Preserve semantic timeline groups across window boundaries#2466ymichael wants to merge 4 commits into
ymichael wants to merge 4 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Human comments
What was wrong
Timeline transport windows were projected independently even though projection groups by semantic turns, messages, and item lifecycles. Event-count and byte cuts could therefore split one item or completed-turn group across pages. Each page then made a locally plausible but globally different decision: duplicate “Worked for…” rows, missing or extra assistant messages, incorrect user-message turn assignment, double-counted items, or a row stuck pending. Client-side coalescing by turn-row id could join some work fragments, but it could not reconstruct the semantic context discarded at the server boundary and could merge across real conversation boundaries.
What changed
This stacked PR makes the timeline server own semantic window closure. A bounded page now carries only the lifecycle, accepted-input, assistant-boundary, compaction, background-task, and delegation context needed to project its selected events as the corresponding slice of the unwindowed timeline. Whole items belong to exactly one window, completed-turn fragments use page-local identities, and the client coalesces only adjacent fragments at the actual page seam. Detail hydration uses the same ownership rules, so expanding a coalesced row does not reintroduce duplicate or half-finished items.
The query path avoids global item-span work for lifecycle pairs already proven to be contained and limits future-assistant lookups to turns crossing the byte boundary. A nested-delegation-only byte slice has a narrow fallback when it has nonzero summarized work but no root message from which to derive bounds.
This depends on #2464. There is no server/daemon wire change, so
HOST_DAEMON_PROTOCOL_VERSIONis unchanged.I also tested the smaller client-boundary-only alternative against the copied production corpus. It matched the canonical unwindowed projection on only 103 of 118 cap-affected threads; the remaining failures included every error class above. That is why the server closure logic is retained despite the larger diff.
How you verified
784threads,888,665events): all118/118event- or byte-cap-affected threads exactly matched the canonical unwindowed conversation/turn projection across457timeline pages. All13/13segment-limit stress threads matched, and1,029expandable groups (including all six paginated detail ranges) completed with zero failures or warnings.