Skip to content

[v0.8 Core 4] anchor saved sibling validation - #1334

Merged
sethkarten merged 2 commits into
v080/core-split-c3-managed-catalogfrom
v080/core-split-c4-sibling-validation
Aug 13, 2026
Merged

[v0.8 Core 4] anchor saved sibling validation#1334
sethkarten merged 2 commits into
v080/core-split-c3-managed-catalogfrom
v080/core-split-c4-sibling-validation

Conversation

@sethkarten

@sethkarten sethkarten commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Replacement scope

This PR reconstructs and supersedes the unique implementation delta reviewed in #1262 without rewriting that historical branch. The original PR remains the immutable discussion record: #1262

  • Base: v080/core-split-c3-managed-catalog
  • Replacement branch: v080/core-split-c4-sibling-validation
  • Replacement commit: 159b4d6bbe82a134a4e0814cb81878f95325b427
  • Propagation/reconciliation merge commits are intentionally excluded.
  • fix(mcp): make cleanup failures observable #1264 is intentionally omitted from the replacement stacks because its declared-base-to-head tree delta is empty.
  • Frozen feat(kernel): dispatch host requests as capabilities #1243 (77b188b92dc91365cb2bc41bdb46a50669d104a8) is the shared foundation. For reconstructed deltas it is a proven tree-compatible base, not an ancestry claim about the historical PR stack.

Validation

  • Biome 2.5.5 on the exact changed paths: pass
  • root tsgo --noEmit: pass
  • Core focused suite on the final Core tip with live daemon/RLM environment removed and single-worker execution: 11 files, 388 tests passed
  • MCP focused suite on the final MCP tip: 9 files, 106 tests passed
  • Independent Terra tree/delta review: pass

No original PR was retargeted, closed, merged, or otherwise mutated.


Note

Medium Risk
Changes daemon session naming and catalog validation for saved RLM siblings; malformed catalogs now reject reservations instead of proceeding, which is safer but can block operations on corrupted on-disk data.

Overview
Saved sibling agent name checks in DaemonSupervisor now resolve each child’s parentSessionPath relative to that session file (canonicalSavedSiblingParentPath), so equivalent paths like ../parent.jsonl and ../../parent.jsonl share one canonical parent for reservations and collisions.

Before calling Core name validation, the supervisor validates the bounded sibling catalog (unique ids/paths, uniform depth, shared parent) and fails closed on ambiguous rows; it injects a synthetic inactive parent entry so exact-one-parent rules apply without expanding catalog.siblings() beyond the child set. Create and rename paths route saved targets through savedSiblingNameReservationInput instead of summary-only heuristics.

Adds supervisor tests for conflicting topology, relative parent anchoring, and in-flight reservation deduplication, plus agent-messages tests for malformed family edges vs catalog-resolved depth-two siblings.

Reviewed by Cursor Bugbot for commit f49b848. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Anchor saved sibling name validation against a canonical synthetic parent in DaemonSupervisor

  • assertSavedSiblingNameAvailable now validates structural consistency of saved sibling catalogs (no duplicate ids/paths, uniform rlmDepth, shared canonical parentSessionPath) and fails closed on malformed or ambiguous input.
  • A new canonicalSavedSiblingParentPath helper resolves each sibling's parentSessionPath relative to its own session file, ensuring consistent path anchoring regardless of where files are stored.
  • Name reservations for saved sessions (both create and rename flows) now use a synthetic canonical parent entry rather than the summary-based heuristic, producing consistent collision detection.
  • New tests in daemon-supervisor-lazy-subagents.test.ts cover conflicting sibling identity/topology, relative parent anchoring, and deduplication of equivalent relative parents.
  • Behavioral Change: malformed or inconsistent saved sibling catalogs now cause reservation to fail rather than proceeding with potentially incorrect name assignments.

Macroscope summarized f49b848.

Reconstruct the unique net delta from PR #1262, excluding propagation merges.

@cursor cursor Bot 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit f49b848. Configure here.

name,
depth: saved.rlmDepth ?? siblings.find((sibling) => sibling.rlmDepth !== undefined)?.rlmDepth ?? 0,
parentSessionPath: saved.parentSessionPath,
...(parentSessionPath ? { parentSessionPath } : {}),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Active and saved reservations diverge

Medium Severity

Saved-sibling name reservations now canonicalize parentSessionPath against each child session file, but the active-session reservation path still keys off the raw summary parentSessionPath. Live summaries can carry that relative header value, so sessionNameReservationKey then resolves it from process cwd instead of the child file. Concurrent saved create/rename and an active sibling rename with equivalent relative parents can miss the shared lock and both take the same sibling name.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit f49b848. Configure here.

@jonaowen jonaowen 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.

There is one mixed active/saved namespace race at exact head f49b8485bc08dbb372d83c2594a11be72e86d090.

Saved and active operations compute different reservation keys when the persisted parent is relative. savedSiblingNameReservationInput() correctly roots ../parent.jsonl at dirname(saved.path), but savedSessionNameReservationInput() switches to summaryNameReservationInput() when the target is resident; that carries the raw relative SessionSummary.parentSessionPath, which the reservation key canonicalizes relative to supervisor process.cwd(). The active rename path likewise uses that raw summary. An active sibling rename and inactive saved-sibling rename/create can therefore both reserve shared, each pass pre-commit validation, and produce duplicate sibling names.

Please canonicalize every summary parent relative to its child sessionFile (one common reservation-input helper), including active set-name/rename, the active branch of savedSessionNameReservationInput, and availability input so lock and validation scopes match. Add an async mixed-state regression: hold an active worker rename open, attempt an inactive saved sibling rename or named resume whose relative parent denotes the same canonical file, and require rejection before commit. A direct key test should also prove active {sessionFile: child, parentSessionPath: '../parent.jsonl'} and the equivalent saved row produce identical sessionNameReservationKeys. The current tests cover saved-vs-saved and active-vs-active, not this mixed race.

@sethkarten
sethkarten merged commit fbc6ac1 into core02-host-request-dispatcher Aug 13, 2026
2 checks passed
@sethkarten
sethkarten deleted the v080/core-split-c4-sibling-validation branch August 13, 2026 21:00
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