Skip to content

fix(replay): walk full timeline ancestry in get_full_timeline_steps/spans#175

Merged
risjai merged 2 commits into
masterfrom
fix/multi-level-fork-inheritance
May 25, 2026
Merged

fix(replay): walk full timeline ancestry in get_full_timeline_steps/spans#175
risjai merged 2 commits into
masterfrom
fix/multi-level-fork-inheritance

Conversation

@risjai

@risjai risjai commented May 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • get_full_timeline_steps and get_full_timeline_spans now walk the entire ancestor chain via an iterative ancestry_chain helper that applies a cumulative min(fork_at_step) clamp per level. Previously they walked exactly one parent level, dropping every step that originated on the grandparent.
  • Closer-to-leaf rows still shadow ancestor rows (existing owned-over-inherited dedup invariant preserved). Cycle defense via visited-set; depth cap of 64.
  • Track 1 bump 0.15.1 → 0.15.2 across the 5 Rust-track files; Track 2 bump 0.17.0 → 0.17.1 (python/ was touched and 0.17.0 is published).

Repro (pre-fix)

On dev1 session ray-agent-7bea73fa (2026-05-25): a replay timeline forked from an edited-fork forked from main rendered as 1 step in the dashboard instead of all 4 inherited. Same shape on every 3+ level fork chain.

Test plan

  • 4 new unit tests in rewind-replay cover 3-level inheritance, both clamp directions, and span symmetry — all fail before the fix, pass after.
  • New web integration test test_steps_endpoint_walks_three_level_inheritance exercises the /api/sessions/{id}/steps endpoint through a 3-level fork chain.
  • cargo test --workspace — all suites green (0 failed across 17+ test binaries).
  • cargo clippy -p rewind-replay --all-targets -- -D warnings — clean. (rewind-web has pre-existing clippy errors in unrelated test files that were not introduced by this change.)
  • Removed the stale "only walks one parent level up" caveat in test_fork_and_edit_step_inherited_step.

Version bumps

Per CLAUDE.md decision tree:

  • Track 1 (workspace v0.15.1 released; crates/ touched): Cargo.toml, Cargo.lock, python/rewind_cli.py, python-mcp/rewind_mcp_cli.py all 0.15.1 → 0.15.2; python-mcp/pyproject.toml 0.13.11 → 0.13.12.
  • Track 2 (rewind-agent 0.17.0 on PyPI; python/rewind_cli.py touched): python/pyproject.toml and python/rewind_agent/__init__.py 0.17.0 → 0.17.1.

🤖 Generated with Claude Code

…pans

Previously these methods walked exactly one parent level, so a 3-level
chain (root -> mid-fork -> leaf-fork) caused the leaf to lose visibility
of every step that originated on the grandparent. Visible bug on dev1
session ray-agent-7bea73fa (2026-05-25): a replay timeline forked from
an edited-fork forked from main rendered as 1 step in the dashboard
instead of all 4 inherited.

The fix introduces an iterative ancestry_chain walk that records each
ancestor's contribution clamp as the cumulative min(fork_at_step) of
every fork-edge below it. The leaf admits all of its own owned steps;
each parent contributes only steps with step_number <= its clamp.
Closer-to-leaf rows shadow ancestor rows (preserving the existing
owned-over-inherited dedup invariant).

Cycle defense via a HashSet of visited ids, plus a depth cap of 64
(MAX_ANCESTRY_DEPTH) as a final guard against pathological graphs.

Tests:
- 4 new unit tests in rewind-replay (3-level inheritance, two clamp
  directions, span symmetry).
- 1 web integration test exercising the dashboard's /steps endpoint
  through a 3-level fork chain.
- Removed the now-resolved "only walks one parent level up" caveat in
  test_fork_and_edit_step_inherited_step.

Track 1 bumps per CLAUDE.md (workspace v0.15.1 already released):
  Cargo.toml/Cargo.lock 0.15.1 -> 0.15.2
  python/rewind_cli.py CLI_VERSION 0.15.1 -> 0.15.2
  python-mcp/rewind_mcp_cli.py CLI_VERSION 0.15.1 -> 0.15.2
  python-mcp/pyproject.toml 0.13.11 -> 0.13.12

Track 2 bumps (rewind-agent 0.17.0 already on PyPI; python/ touched):
  python/pyproject.toml 0.17.0 -> 0.17.1
  python/rewind_agent/__init__.py 0.17.0 -> 0.17.1

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@vercel

vercel Bot commented May 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
rewind Ready Ready Preview, Comment May 25, 2026 9:15am

@risjai

risjai commented May 25, 2026

Copy link
Copy Markdown
Collaborator Author

Review notes after reading the full diff + running tests:

  • ✅ Ran cargo test -p rewind-replay (20 passed).
  • ✅ Ran cargo test -p rewind-web --test recording_api_tests test_steps_endpoint_walks_three_level_inheritance (passed).

One potential regression to consider:

MAX_ANCESTRY_DEPTH = 64 introduces a hard failure for any valid acyclic fork chain deeper than 64 levels. Since cycle detection is already handled via visited IDs, this cap may reject legitimate long-lived edit/fork histories and surface as endpoint failures for /steps or /spans.

Could we either (a) remove the hard cap, or (b) make it a soft guard + add a regression test for a >64-depth acyclic chain?

PR #175 review: the visited-set already rejects cycles, and the walk is
naturally bounded by timelines.len() since each iteration consumes one
new id from the same finite pool. The 64-level depth cap can therefore
only false-positive on legitimate deep edit/fork histories — never
catch a bug the cycle check would miss. Removing it.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@risjai

risjai commented May 25, 2026

Copy link
Copy Markdown
Collaborator Author

Good catch — applied option (a) in 8359f47.

The visited-set already rejects cycles, and while cursor.is_some() consumes one new id per iteration from a finite timelines.len() pool, so the walk is naturally bounded. The 64-level cap can only false-positive on legit deep histories, never catch a real cycle the visited-set would miss.

@risjai

risjai commented May 25, 2026

Copy link
Copy Markdown
Collaborator Author

Re-checked after 8359f47.

No new blockers from my side:

  • MAX_ANCESTRY_DEPTH cap removal addresses the only regression risk I called out.
  • cargo test -p rewind-replay passes (20/20).
  • cargo test -p rewind-web --test recording_api_tests test_steps_endpoint_walks_three_level_inheritance passes.

Remaining warning seen in rewind-web test compile (unused variable: root_tid around recording_api_tests.rs:1898) appears pre-existing/unrelated to this PR.

@risjai
risjai merged commit 218236f into master May 25, 2026
7 checks passed
@risjai
risjai deleted the fix/multi-level-fork-inheritance branch May 25, 2026 09:18
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.

1 participant