[v0.8 Core 4] anchor saved sibling validation - #1334
Conversation
Reconstruct the unique net delta from PR #1262, excluding propagation merges.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ 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 } : {}), |
There was a problem hiding this comment.
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)
Reviewed by Cursor Bugbot for commit f49b848. Configure here.
jonaowen
left a comment
There was a problem hiding this comment.
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.


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
v080/core-split-c3-managed-catalogv080/core-split-c4-sibling-validation159b4d6bbe82a134a4e0814cb81878f95325b42777b188b92dc91365cb2bc41bdb46a50669d104a8) is the shared foundation. For reconstructed deltas it is a proven tree-compatible base, not an ancestry claim about the historical PR stack.Validation
tsgo --noEmit: passNo 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
DaemonSupervisornow resolve each child’sparentSessionPathrelative to that session file (canonicalSavedSiblingParentPath), so equivalent paths like../parent.jsonland../../parent.jsonlshare 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 throughsavedSiblingNameReservationInputinstead of summary-only heuristics.Adds supervisor tests for conflicting topology, relative parent anchoring, and in-flight reservation deduplication, plus
agent-messagestests 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
DaemonSupervisorassertSavedSiblingNameAvailablenow validates structural consistency of saved sibling catalogs (no duplicate ids/paths, uniformrlmDepth, shared canonicalparentSessionPath) and fails closed on malformed or ambiguous input.canonicalSavedSiblingParentPathhelper resolves each sibling'sparentSessionPathrelative to its own session file, ensuring consistent path anchoring regardless of where files are stored.Macroscope summarized f49b848.