Skip to content

Fix/prevent dag cycle#138

Merged
daaain merged 3 commits intomainfrom
fix/prevent-DAG-cycle
May 7, 2026
Merged

Fix/prevent dag cycle#138
daaain merged 3 commits intomainfrom
fix/prevent-DAG-cycle

Conversation

@daaain
Copy link
Copy Markdown
Owner

@daaain daaain commented May 6, 2026

@cboos these are addressing the warnings I mentioned in #135

I'm not super familiar with this DAG processing so please have a look!

Make DAG cycle warnings honour silent=True

Normal generation should just output projects list

Quiet routine multi-root warnings

The "N roots found (M unexpected)" warning fired on long sessions for
shapes that are actually routine:

  • The genuine session-start user root counted as 'unexpected' alongside
    expected compact_boundary roots.
  • Sidechain user roots with no agentId — older Claude Code Task prompts
    loaded without their trunk anchor.
  • Cross-session attachment roots — --resume shape where the resumed
    transcript's entries reference parents that live in another loaded
    session.

Add _classify_unexpected_roots to filter these patterns out before
deciding whether to warn. The genuine start is identified as the
earliest non-sidechain natural root, so a sidechain orphan dated
before the real session start can't shadow it.

On the user's repower project this drops 16 multi-root warnings to 0
while keeping the legitimate orphan-node warning intact. Adds four
regression tests covering each shape, including the
sidechain-earlier-than-user-start edge case.

Fix self-loop anchor for orphan subagent transcripts

When a sidechain transcript was loaded without its trunk session (e.g.
warmup-only subagent files), _integrate_agent_entries accepted the
agent's own root entry as its anchor. The subsequent re-parent step
then set parentUuid = uuid, producing a self-loop and a "Cycle
detected" warning at DAG construction.

Tighten the sidechain-anchor predicate to require a cross-agent
boundary (parent belongs to a different agent's transcript). Add a
real-world repro fixture and three regression tests, including one
that guards the legitimate nested A→B anchor case.

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Suppressed unnecessary diagnostic warnings during silent and cache rebuild operations
    • Prevented unintended cycles in transcript chain reconstruction
    • Improved handling of orphaned transcript entries and cross-session attachments
  • Tests

    • Enhanced test coverage for diagnostic message suppression and silent modes
    • Added regression tests for cycle prevention in session transcript integration

daaain added 3 commits May 6, 2026 23:30
When a sidechain transcript was loaded without its trunk session (e.g.
warmup-only subagent files), `_integrate_agent_entries` accepted the
agent's own root entry as its anchor. The subsequent re-parent step
then set `parentUuid = uuid`, producing a self-loop and a "Cycle
detected" warning at DAG construction.

Tighten the sidechain-anchor predicate to require a cross-agent
boundary (parent belongs to a different agent's transcript). Add a
real-world repro fixture and three regression tests, including one
that guards the legitimate nested A→B anchor case.

Also restore missing `contextlib`/`logging`/`Iterator` imports
introduced by 0bcf1a7 — the module fails to import without them.
The "N roots found (M unexpected)" warning fired on long sessions for
shapes that are actually routine:

* The genuine session-start user root counted as 'unexpected' alongside
  expected `compact_boundary` roots.
* Sidechain user roots with no agentId — older Claude Code Task prompts
  loaded without their trunk anchor.
* Cross-session attachment roots — `--resume` shape where the resumed
  transcript's entries reference parents that live in another loaded
  session.

Add `_classify_unexpected_roots` to filter these patterns out before
deciding whether to warn. The genuine start is identified as the
earliest non-sidechain natural root, so a sidechain orphan dated
before the real session start can't shadow it.

On the user's repower project this drops 16 multi-root warnings to 0
while keeping the legitimate orphan-node warning intact. Adds four
regression tests covering each shape, including the
sidechain-earlier-than-user-start edge case.
@daaain daaain requested a review from cboos May 6, 2026 23:31
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 6, 2026

📝 Walkthrough

Walkthrough

This PR improves DAG integration quality by introducing root classification to distinguish expected from anomalous multi-root scenarios, tightening sidechain anchor selection to prevent self-loops, suppressing noisy warnings during silent CLI flows, and adding comprehensive test coverage for the new edge cases.

Changes

DAG Root Classification & Anchor Integration

Layer / File(s) Summary
Root Classification Logic
claude_code_log/dag.py
_classify_unexpected_roots(roots, nodes) filters out expected multi-root causes (system/passthrough mechanisms, orphan sidechains, cross-session attachments, genuine session starts) to identify only anomalous roots.
Anchor Selection & Suppression
claude_code_log/converter.py
_dag_warnings_suppressed(silent) context manager suppresses DAG logger output during silent runs; sidechain anchor registration tightened to register only across agent boundaries, preventing self-anchoring that creates cycles.
Silent Flag Integration
claude_code_log/converter.py
Directory transcript loading wraps DAG building/traversal in suppression context so cycle/orphan warnings are muted when silent=True.
Root Classification Tests
test/test_dag.py
New TestRootClassification assertions verify that sidechain orphans, genuine user roots with system roots, cross-session attachment roots, and earlier sidechain orphans do not trigger false multi-root warnings.
Orphan Subagent Anchor Tests
test/test_dag.py
New TestOrphanSubagentNoSelfAnchor regression tests ensure orphan subagent integration never self-anchors, emits no cycle warnings, and preserves nested agent anchor resolution.
Silent Flag Behavior Tests
test/test_dag_silent.py
New test module verifies DAG warnings are suppressed when silent=True, emitted when silent=False, and that logger level is restored after execution.
Test Fixture
test/test_data/dag_cycle.jsonl
Added assistant message record for orphan subagent cycle regression test.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • daaain/claude-code-log#135: Addresses DAG cycle/parent-chain issues by breaking cycles and adding traversal guards, complementing this PR's anchor and root classification refinements.
  • daaain/claude-code-log#131: Modifies root-classification and orphan-handling logic in dag.py, overlapping with this PR's expected-root categorization improvements.
  • daaain/claude-code-log#99: Modifies _integrate_agent_entries anchor-selection behavior in converter.py, directly related to this PR's sidechain anchor cross-agent-boundary enforcement.

Suggested reviewers

  • cboos

🐰 A context manager hops in to shush the noise,
While anchors learn to cross borders with poise,
No more self-loops, no phantom alarm—
Just quiet DAGs, wonderfully calm!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix/prevent dag cycle' directly addresses the main objective of the PR: preventing DAG cycle warnings and related issues.
Docstring Coverage ✅ Passed Docstring coverage is 90.48% which is sufficient. The required threshold is 80.00%.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ 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 fix/prevent-DAG-cycle

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.

Copy link
Copy Markdown
Collaborator

@cboos cboos left a comment

Choose a reason for hiding this comment

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

I had a set of sessions that, when processed together, exhibited the warnings. With these changes they are gone and the content looks good, so... approved!

@daaain daaain merged commit 8d62769 into main May 7, 2026
12 checks passed
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