perf(chat): bound paginated transcript reads - #8235
Conversation
b5f14c1 to
155c6e3
Compare
155c6e3 to
c9b40b5
Compare
Design Review (Fable 5, fork) — 🟡 CONCERNSDesign-level review of Design-Verdict: CONCERNS Sound, reversible in-memory projection with a correct fallback oracle, but the largest transcripts bypass it and every bounded-path failure degrades silently. Watch
Suggestions
[DESIGN-REVIEWED] d61f943 |
First Principles Review (Fable 5, fork) — 🟡 CONCERNSPremise-level review of All evidence gathered. Composing the review. First-Principles-Verdict: CONCERNS Every item traces to the measured 97.7 ms / 10.7 MiB harm, but the framing loop is copy-pasted and two What this change shipsIntent: make loading a chat-history page cost the page, not the whole transcript — a FIX of a measured cost.
Watch
Subtractions
[FIRST-PRINCIPLES-REVIEWED] d61f943 |
GPT 5.6 Review (fork) — 🔴 changes requested (blocking)Reviewed 1 of 1 blocking finding(s) are security-class and were withheld from adjudication, so the blocking verdict stands. BLOCKING -- src/kiro_crew/history_projection.py:687 -- Invalid UTF-8 silently truncates paginated history FINDING -- src/kiro_crew/history_cache.py:401 -- [GPT-REVIEWED] d61f943 Adjudication (Opus 4.8) — is blocking on each finding proportionate?I have the complete evidence record. Let me state it. F1 — Divergence is real but only for the invalid-UTF-8 subclass. The new bounded reader Conditions: a transcript message row must contain byte-level-invalid UTF-8 on disk. The app's own writer serializes with This meets the FLAG bar: the sole divergent condition is an input the system's own writer provably cannot generate, and a human would plausibly accept that a byte-corrupted transcript renders a truncated page rather than a 503. |
Opus 4.8 Review (fork) — ✅ no blocking findingsReviewed Review detailsThe working tree is at base commit Candidate 1 (doc splice): Confirmed from the diff. The added Candidate 2 (splitlines vs binary framing divergence): Falsified. The divergence requires a raw U+2028/U+2029/U+0085 (or ASCII No additional groundable defects found under Step 2. No blocking findings — one advisory: a new spec section spliced into the middle of an existing sentence. FINDING — docs/system-specs/modules/history.md:30 — the added [OPUS-REVIEWED] d61f943 |
c9b40b5 to
da2c5af
Compare
|
da2c5af to
21029b9
Compare
|
|
a6892ee to
40d8e53
Compare
|
Open PR relationship auditThis is a consolidated, point-in-time code-level audit note. It compares complete merge-base diffs and current/merged code; it does not treat a shared topic as duplication or partial coverage as completion. Relationship findings
No PR, Issue, label, branch, or review state was changed by the relationship-note portion of this audit. |
40d8e53 to
d61f943
Compare
|
@Pearcekieser this comes from a repo-wide audit of relationships between open PRs. Four other open PRs touch what this one changes, and one of them needs reconciling before either merges. #8862 (@CrysisDeu), blocking overlap. Both rewrite the same legacy-pagination else-branch of #8979 (@Premshay), coordinate. Both edit the same #9156 (@buluoray), no action. It shares #9130 (@buluoray), no action. Website-only, zero file overlap, and it consumes the same A rebase is needed regardless: the branch is 248 commits behind main. Posted from the 2026-09-08 open-PR relationship audit (read-only, one auditor per PR); reply here if any of this is wrong. |
Problem / Motivation
Chat history is paginated at the API boundary but not at the storage boundary. Each bounded slot-detail request currently parses the complete chained JSONL history before selecting the requested rows.
This makes gateway work scale with total conversation length and repeats complete-history parsing as users load older pages.
Why it matters
Long agent conversations commonly contain thousands of messages and large tool results. Repeated complete-history parsing increases page latency, gateway CPU, and peak memory despite the browser requesting only a bounded window.
For a 10,000-row transcript, the existing full-read baseline was approximately 97.7 ms and 10.7 MiB. The bounded restore-warmed reader completes in approximately 3.77 ms and 70 KiB.
What changed (motivation → approach → change)
This change keeps JSONL as the authoritative transcript while adding a gateway-owned sparse read projection:
ConversationLog.read_messages_chained_pagewith existingtotal,before,next_before, andhas_moresemantics.The sparse index is deliberately not persisted. It contains only row counts and byte offsets and never trusts agent-writable derived state.
This change is independent of #7916: that PR handles archive reachability and browser scroll stability, while this PR bounds gateway storage work for the current chained transcript. If archive pagination lands later, its archive segments should be incorporated into this bounded projection rather than returning to complete-corpus reads.
Tests
Added and updated coverage for:
before,next_before,has_more, and total semantics;Validation:
Manual verification
Reader-level profiling:
A first-ever process-cold page still performs O(total rows) index construction. This PR does not claim constant-time process-cold opening.
Related Issues
Fixes #8234.
Checklist
Contribution License Agreement
The exact CLA wording will be supplied by OSPO before the first public PR.