Skip to content

reader: assign turn membership by parentUuid chain walk (#433) - #447

Merged
willwashburn merged 1 commit into
mainfrom
claude/burn-433-parent-uuid-grouping
May 25, 2026
Merged

reader: assign turn membership by parentUuid chain walk (#433)#447
willwashburn merged 1 commit into
mainfrom
claude/burn-433-parent-uuid-grouping

Conversation

@willwashburn

Copy link
Copy Markdown
Member

Closes#433.

Summary

Groups Claude turn rows by walking the parentUuid chain up to the nearest user-prompt ancestor, instead of relying on file order / timestamp windows for user-prompt-text → assistant mapping in activity classification.

  • New parent_chain submodule with ChainNode trait, group_by_parent_chain, find_turn_root (the API surface the issue specifies; unit-tested).
  • Hot path uses a lighter nearest_user_prompt_root helper that returns Option<String> so the caller can cleanly fall back to the file-order map for rows missing both uuid and parentUuid.
  • Cycle guard via visited set.
  • New user_text_by_uuid map and is_user_prompt field on LineNode to thread the UUID-keyed lookup through classification.

Scope clarification

Burn's reader already collapses multi-block assistants correctly via message_id — turn counts and message_id grouping are unchanged. The actual mis-attribution this fixes is user-prompt-text → assistant mapping for activity classification, where out-of-order JSONL flushes and interrupt-resume gaps would previously cause incorrect attribution.

Codex/opencode readers unchanged (no parentUuid field).

Open question

group_by_parent_chain and find_turn_root are declared #[allow(dead_code)] — they satisfy the issue's specified API surface and are unit-tested, but the hot path uses the lighter single-row helper. Happy to either remove them or wire them through if reviewers prefer; doc comments explain the trade-off.

Test plan

  • parent_chain unit tests (10 new): chain walk, root detection, cycle guard, missing-uuid fallback, multi-root file
  • End-to-end reader tests (3 new): out-of-order rows, interrupt+resume pattern, classification correctness
  • New fixtures: parent-chain-out-of-order.jsonl, parent-chain-interrupt-resume.jsonl
  • cargo build --workspace clean
  • cargo test --workspace — 813 passed, 0 failed
  • BURN_GOLDEN=1 cargo test --test golden — 5/5
  • cargo clippy -p relayburn-sdk --lib clean on new code

Out of scope

  • Codex/opencode reader changes (no parentUuid field; documented asymmetry).
  • No schema change — pure reader-side classification fix.

Generated by Claude Code

…433)
Activity classification associates each assistant turn with its user
prompt by walking the `parentUuid` chain to the nearest user-prompt
ancestor, replacing the file-order "last user text seen" heuristic.
The old heuristic mis-attributed user text under:
- Out-of-order JSONL flushes (Claude Code's writer is async).
- Mid-stream interrupt + resume (late assistant rows inherited the
intervening prompt's text).
- Compaction artifacts with off-window timestamps.
New helper in `claude/parent_chain.rs` (`group_by_parent_chain` +
`find_turn_root` + `ChainNode` trait) provides the bulk grouping API
the issue specifies; the in-reader hot path uses the single-row
`nearest_user_prompt_root` variant for per-turn lookup. Cycle guard
via visited set; orphan/cycle chains fall through to the legacy
file-order map (over-grouping > silently dropping rows).
Codex and opencode readers are untouched — their rollouts have no
equivalent `parentUuid` field. Asymmetry documented at the
`claude.rs` module header and `claude/parent_chain.rs` docstring.
Tests: 13 new (10 unit tests in `parent_chain` + 3 end-to-end on the
Claude reader path with new fixtures `parent-chain-out-of-order.jsonl`
and `parent-chain-interrupt-resume.jsonl`). No schema change. Golden
snapshots unchanged.
@coderabbitai

Copy link
Copy Markdown

Warning

Review limit reached

@willwashburn, we couldn't start this review because you've used your available PR reviews for now.

Your plan includes 1 review of capacity. Refill in 4 minutes and 20 seconds.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more review capacity refills, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than trial, open-source, and free plans. In all cases, review capacity refills continuously over time.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8bce6e0b-a406-40b1-b36c-9eabae2106cf

📥 Commits

Reviewing files that changed from the base of the PR and between 33cc446 and 82a35cd.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • crates/relayburn-sdk/src/reader/claude.rs
  • crates/relayburn-sdk/src/reader/claude/parent_chain.rs
  • tests/fixtures/claude/parent-chain-interrupt-resume.jsonl
  • tests/fixtures/claude/parent-chain-out-of-order.jsonl
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/burn-433-parent-uuid-grouping

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 5 files

Re-trigger cubic

@willwashburn
willwashburn merged commit 948d345 into mainMay 25, 2026
12 checks passed
@willwashburn
willwashburn deleted the claude/burn-433-parent-uuid-grouping branch May 25, 2026 17:43
Sign up for freeto 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.

reader: assign turn membership by parentUuid chain walk, not timestamp window

2 participants

@willwashburn@claude