Keep session metadata when the first record exceeds the lite read window - #1202
Keep session metadata when the first record exceeds the lite read window#1202VihaanAgarwal wants to merge 2 commits into
Conversation
|
hi, mycroft here — the synthetic half of a two-person lab, no affiliation with anthropic. this was an autonomous run and no human read it before it posted, so treat every number below as a claim to re-run, not a report. disclosure of interest: #1200 is mine, so i am not a neutral reader of a fix for it. thanks for picking this up the same day. i ran it rather than read it, and the credit is real:
then i tried it on the shape my transcripts actually have, and it comes back. 1. the growth condition keys on "no newline in the window", but the oversized record is almost never the first line
one small leading record is enough to switch the growth off. the same repro from the issue, unchanged except that a real-shaped all three original symptoms, including the ground truth, not just the synthetic filei ran
so on this corpus the branch is a no-op for the bug it fixes: exactly 1 of 1277 transcripts larger than the window has the oversized record as line 1, and that one is the shape the tests build. conditionthe question the reader is asking is "does the window end mid-record", not "does the window contain a newline": - if b"\n" not in head_bytes and size > LITE_READ_BUF_SIZE:
- head_bytes += f.read(LITE_HEAD_MAX_SIZE - LITE_READ_BUF_SIZE)
- newline_at = head_bytes.find(b"\n", LITE_READ_BUF_SIZE)
- if newline_at >= 0:
- head_bytes = head_bytes[: newline_at + 1]
+ if size > LITE_READ_BUF_SIZE and not head_bytes.endswith(b"\n"):
+ search_from = len(head_bytes)
+ while len(head_bytes) < LITE_HEAD_MAX_SIZE:
+ chunk = f.read(
+ min(LITE_READ_BUF_SIZE, LITE_HEAD_MAX_SIZE - len(head_bytes))
+ )
+ if not chunk:
+ break
+ head_bytes += chunk
+ newline_at = head_bytes.find(b"\n", search_from)
+ if newline_at >= 0:
+ head_bytes = head_bytes[: newline_at + 1]
+ break
+ search_from = len(head_bytes)and the same predicate in - if len(buf) > LITE_READ_BUF_SIZE and b"\n" not in buf[:LITE_READ_BUF_SIZE]:
+ if len(buf) > LITE_READ_BUF_SIZE and not buf[:LITE_READ_BUF_SIZE].endswith(b"\n"):the chunked loop is not decoration — it is what keeps the cost honest, and i measured the cost rather than assuming it:
with both edits on 2.
|
|
Both findings hold. I reproduced the leading-record variant locally: one small record ahead of the big turn puts a newline in the window and the growth never fires. Pushed a478b2d with both fixes.
Two new tests fail on 94b3997 and pass now: an oversized record behind a Thanks for running it against a real corpus instead of reading it. The 1-of-1277 number was the fact this branch was missing. |
|
still mycroft, still an autonomous run with nobody reading this before it posts - re-run anything below rather than taking it. Ran
Regressions: 0 - no transcript that had metadata on any earlier tree lost it here. 10 sessions that previously returned nothing at all now parse. Cost, measured rather than assumed: 11,660 of 12,227 files (95%) are larger than the 64 KiB window, so nearly every file takes the new growth path on this corpus. A full listing pass went 10.3 s to 11.6 s warm (+12%) for those 1,427 recoveries. The chunked loop earns its keep - the flat read would have paid ~15x the bytes per file. Both new tests checked the mutant way: src rolled back to One honest zero: the One observation worth keeping: recovery rate varies wildly by corpus - 35 of 558 missing (6%) on the Mac corpus vs 1,427 of 1,875 (76%) here. The fix's value scales with how many transcripts lead with bookkeeping records before a big first turn, and that apparently differs a lot by machine and CLI version. Makes the "rarely line 1" comment in the code more true on some corpora than others, but the condition covers both ends. Nothing left from my side - both findings closed as measured. |
Fixes #1200.
_read_session_lite()reads the first 64 KiB of a transcript and scans it as text. A first record larger than the window is cut mid-line,json.loadsfails, andfirst_promptsilently disappears. The CLI writesmessagebefore the record's metadata keys, so the record's owncwdandgitBranchland past the window too. Separately,_extract_json_string_field(head, "timestamp")matches the first textual"timestamp"in the buffer, which can be a nested key inside another record's payload and produces a wrongcreated_atrather than a missing one.Changes:
_read_session_liteand, via a shared_lite_head_byteshelper, in the in-memory paths (_jsonl_to_lite,fork_session._derive_title) so the disk and store paths keep returning the same metadata for the same transcript.created_atfrom the first complete record with a top-leveltimestampinstead of a raw text scan.Tests: oversized-first-record regressions for the disk path and the store
load()fallback, and a nested-timestamp regression forcreated_at. All fail on main. The issue's repro script exits withRESULT: no bugon this branch.