Skip to content

relayburn-sdk: reader cleanup deferred subset (#346)#371

Merged
willwashburn merged 1 commit into
mainfrom
claude/fix-issue-346-k859T
May 8, 2026
Merged

relayburn-sdk: reader cleanup deferred subset (#346)#371
willwashburn merged 1 commit into
mainfrom
claude/fix-issue-346-k859T

Conversation

@willwashburn
Copy link
Copy Markdown
Member

Summary

Picks up the items from #346 that #352 explicitly deferred as "riskier."

  • codex.rs / opencode.rs (item 1, partial): replace the manual repack of the incremental result inside parse_codex_session / parse_opencode_session with From<ParseCodexIncrementalResult> for ParseCodexResult (and the opencode equivalent). The session entry points now just .map(...::from).
  • codex.rs (item 3): drop the two let _ = (...) "suppress unused warnings" blocks at the tail of parse_codex_buffer. Audit confirms every committed_* snapshot they justified is read post-loop (resume state or emitted records), so the trailing working values are genuinely dead. Removing the silencing blocks introduces no new compiler warnings.
  • codex.rs (item 6): rename memchr_newline to find_newline. The previous name implied a memchr-crate optimization that wasn't there (the body is iter().position(|&b| b == b'\n')); not adding the crate, just dropping the misleading name.

Deferred

claude.rs parser duplication (item 1, claude path) stays deferred. The non-incremental ParseState emits in-progress turns (records with stop_reason.is_none()), while run_incremental deliberately defers them so the next call's start cursor is honest. Collapsing the two paths would change observable output for partially-written sessions and needs a flag on run_incremental plus broader fixture validation.

string-field helpers (item 2), verb() two-arm match (item 4), resolve_uncached fallback (item 5) all already landed in #352.

Test plan

  • cargo build --workspace clean
  • cargo test --workspace — 618 SDK tests + integration + doc tests pass
  • cargo clippy --workspace --all-targets — no new warnings introduced (pre-existing warnings unrelated to this change)

https://claude.ai/code/session_01GHEd4Sv87QoUTd1BN6FbAF


Generated by Claude Code

Remaining reader-module cleanups deferred from #352:

- codex.rs / opencode.rs: replace the manual repack of the incremental
  result with `From<ParseCodexIncrementalResult> for ParseCodexResult`
  (and the opencode equivalent), and have `parse_*_session` delegate via
  `.map(...::from)`.
- codex.rs: drop the two `let _ = (...)` blocks at the tail of
  `parse_codex_buffer`. The audit confirms each `committed_*` snapshot
  is read by either the resume state or the emitted records, so the
  trailing working values are genuinely dead and removing the silencing
  blocks introduces no compiler warnings.
- codex.rs: rename `memchr_newline` to `find_newline` so the name no
  longer implies a `memchr`-crate optimization that isn't there.

The claude.rs parser-duplication item from #346 stays deferred: the
non-incremental `ParseState` emits in-progress turns (records with
`stop_reason.is_none()`), while `run_incremental` deliberately defers
them to keep the next call's start cursor honest. Collapsing the two
paths needs a flag on `run_incremental` and broader fixture validation;
out of scope for this safe-subset PR.

https://claude.ai/code/session_01GHEd4Sv87QoUTd1BN6FbAF
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bb4c2735-eed9-4674-894c-1c44a8c86d8a

📥 Commits

Reviewing files that changed from the base of the PR and between 7f7d9d2 and c00b51e.

📒 Files selected for processing (2)
  • crates/relayburn-sdk/src/reader/codex.rs
  • crates/relayburn-sdk/src/reader/opencode.rs

📝 Walkthrough

Walkthrough

Two reader parsers (codex and opencode) are refactored to delegate to incremental variants with new From trait implementations for result conversion. In codex parsing, newline detection switches from memchr_newline to a local find_newline helper, and an unused-mutable suppression block is removed.

Changes

Parser Consolidation

Layer / File(s) Summary
Result Conversion Traits
crates/relayburn-sdk/src/reader/codex.rs, crates/relayburn-sdk/src/reader/opencode.rs
New From<ParseCodexIncrementalResult> and From<ParseOpencodeIncrementalResult> trait implementations centralize field-by-field mapping of turns, content, events, user_turns, relationships, and tool_result_events.
Parser Delegation Refactoring
crates/relayburn-sdk/src/reader/codex.rs, crates/relayburn-sdk/src/reader/opencode.rs
parse_codex_session and parse_opencode_session now build incremental options and delegate to their _incremental counterparts, converting results via the new From implementations.
Newline Detection Helper
crates/relayburn-sdk/src/reader/codex.rs
New find_newline(buf: &[u8]) -> Option<usize> helper scans for b'\n' byte position, replacing memchr_newline usage.
Buffer Parsing and Cleanup
crates/relayburn-sdk/src/reader/codex.rs
parse_codex_buffer core scan loop adopts find_newline helper; unused-mutable suppression block is removed.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

Poem

🐰 Two parsers dance as one today,
Incremental roads now light the way,
From traits convert with grace and ease,
Find newlines swift with gentle breeze,
Refactored clean, the code's at peace! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the primary change: a cleanup of the reader module addressing a deferred subset of items from issue #346.
Description check ✅ Passed The description clearly relates to the changeset, detailing the specific refactorings in codex.rs and opencode.rs, explaining deferred items, and documenting the test plan.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/fix-issue-346-k859T

Comment @coderabbitai help to get the list of available commands and usage tips.

@willwashburn willwashburn merged commit e0c8fa0 into main May 8, 2026
11 checks passed
@willwashburn willwashburn deleted the claude/fix-issue-346-k859T branch May 8, 2026 01:39
willwashburn added a commit that referenced this pull request May 10, 2026
)

* relayburn-sdk: drop reintroduced let _ block in parse_codex_buffer

PR #371 dropped the two `let _ = (...)` warning-silencers at the tail of
`parse_codex_buffer`, but #372 (JSONL streaming refactor) re-added the
larger one when it restructured the loop. Audit re-confirms each
`committed_*` mirror is read either by the emitted records or by the
resume state, so the live values are dead at function exit and modern
rustc does not flag them.

Refs #346.

* changelog: trim parse_codex_buffer entry to impact-first style

Per project changelog guidelines and CodeRabbit feedback on #405.

* changelog: drop noop dead-code removal entry

---------

Co-authored-by: Claude <noreply@anthropic.com>
willwashburn added a commit that referenced this pull request May 11, 2026
…) (#417)

* relayburn-sdk: collapse parse_claude_session onto run_incremental (#346)

Last remaining cleanup from #346: the non-incremental claude parser kept
its own `ParseState` machinery in parallel with `run_incremental`, both
reading the same JSONL shape but along separate codepaths. PR #371
deferred this because the two paths disagreed on trailing in-progress
turns (incremental skips them; non-incremental emits them).

This commit adds an `emit_in_progress` flag to `run_incremental`:

- false (incremental callers): keep the existing "back up end_offset to
  the earliest in-progress message and skip those turns" behavior, so
  the next resume call re-reads them.
- true (full-parse caller): use `cursor_offset` for end_offset and emit
  every working record. This matches the prior `ParseState::finish`
  output, including assistants without a `stop_reason`.

`parse_claude_session_with_counter` now builds a
`ParseIncrementalOptions { start_offset: Some(0), .. }` and calls
`run_incremental(.., true)`, then converts via a new
`From<ParseIncrementalResult> for ParseResult`. The ParseState struct,
its impl, the `record_root` / `collect_explicit_claude_relationships`
non-incremental helpers, and `derive_file_session_id` are gone — net
-374 LoC in claude.rs.

The full workspace test suite (claude reader + 600+ other tests) passes
unchanged, validating that the single-shot output matches what
`ParseState` produced.

* relayburn-sdk: emit final unterminated line in single-shot claude parse

Devin Review flagged that switching `parse_claude_session_with_counter` to
delegate to `run_incremental` regressed one edge case: the prior
`ParseState` path used `BufReader::read_line`, which surfaces the final
line at EOF even without a trailing `\n`. `run_incremental`'s
`read_until(b'\n')` loop guards against partial trailing lines because
the incremental caller resumes at `cursor_offset` next tick — but a
single-shot full parse has no next tick, so a syntactically complete
final JSON line lacking `\n` (mid-write truncation, unflushed writer)
was silently dropped.

Fix: gate the partial-line `break` on `!emit_in_progress`. When the
single-shot caller asks us to emit in-progress records, treat a
non-newline-terminated tail as a complete line and bump `cursor_offset`
past its body so the per-record offset filters still admit it.

Regression test `full_parse_emits_final_line_without_trailing_newline`
writes simple-turn.jsonl with the trailing `\n` stripped and asserts the
turn still lands.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants