Repository navigation
feat(coding-agent): lazy child session hydration - #583
Merged
Merged
Conversation
This was referenced Aug 2, 2026
snimu
added a commit
that referenced
this pull request
Aug 3, 2026
…letion races - Finding 0: heartbeat restore could return a concurrently hydrating child before binding; fence resident fallback with waitForBoundSession and treat unavailable binding as a skipped dispatch. origin: PR #583 - Finding 1: supervisor child lookup accepted only exact selectors after worker suffix matching; add the same session-ID suffix fallback within the selected worker. origin: PR #583 - Finding 3: passive create hydration skipped explicit name and client environment bookkeeping; apply both before returning the hydrated state. origin: PR #583 - Finding 4: concurrent passive deletions raced through asynchronous resolution and started duplicate host deletes; defer deletion behind an atomic in-flight map check and coalesce callers. origin: PR #583 - Finding 5: concurrent hydration could make a passive lookup stale for advertised IDs and paths; retry normal bound-session resolution before rethrowing the original unknown-session error. origin: PR #583 - Finding 6: ambiguous live selectors fell through to passive lookup and could misroute; introduce a dedicated ambiguity error and rethrow it before passive resolution. origin: PR #583 - Finding 7: passive open skipped name and client-env bookkeeping (cron rebinding already occurred in addRuntime); apply only the missing bookkeeping. origin: PR #583 - Finding 30: rlmChildId traffic treated a resident passivating child as closing; join passivation and rehydrate in both bound lookup and direct message hydration branches. origin: PR #589
snimu
force-pushed
the
feat/lazy-child-hydration
branch
from
August 3, 2026 12:05
da7fd00 to
9333b1e
Compare
snimu
added a commit
that referenced
this pull request
Aug 3, 2026
…letion races - Finding 0: heartbeat restore could return a concurrently hydrating child before binding; fence resident fallback with waitForBoundSession and treat unavailable binding as a skipped dispatch. origin: PR #583 - Finding 1: supervisor child lookup accepted only exact selectors after worker suffix matching; add the same session-ID suffix fallback within the selected worker. origin: PR #583 - Finding 3: passive create hydration skipped explicit name and client environment bookkeeping; apply both before returning the hydrated state. origin: PR #583 - Finding 4: concurrent passive deletions raced through asynchronous resolution and started duplicate host deletes; defer deletion behind an atomic in-flight map check and coalesce callers. origin: PR #583 - Finding 5: concurrent hydration could make a passive lookup stale for advertised IDs and paths; retry normal bound-session resolution before rethrowing the original unknown-session error. origin: PR #583 - Finding 6: ambiguous live selectors fell through to passive lookup and could misroute; introduce a dedicated ambiguity error and rethrow it before passive resolution. origin: PR #583 - Finding 7: passive open skipped name and client-env bookkeeping (cron rebinding already occurred in addRuntime); apply only the missing bookkeeping. origin: PR #583 - Finding 30: rlmChildId traffic treated a resident passivating child as closing; join passivation and rehydrate in both bound lookup and direct message hydration branches. origin: PR #589
Contributor
|
Macroscope has since reviewed this pull request. An earlier review was skipped by a cost limit; a review has now completed, so that notice no longer applies. |
snimu
added a commit
that referenced
this pull request
Aug 3, 2026
…ots, and depth ingestion - preserve daemon routable IDs for passive children (origin: PR #583) - recheck guarded passive hydration and heartbeat restores (origin: PR #583) - repair wrong-kind pending hydration joins (origin: PR #583) - fence passive hydration during update restart preparation (origin: PR #583) - validate persisted RLM depth before constructor ingestion (origin: PR #584) - retry attach child snapshots across session replacement (origin: PR #587) - retain effective depth for legacy parented new sessions (origin: PR #589) - coordinate parent passivation with child hydration publication (origin: PR #589)
This was referenced Aug 3, 2026
snimu
added a commit
that referenced
this pull request
Aug 4, 2026
…letion races - Finding 0: heartbeat restore could return a concurrently hydrating child before binding; fence resident fallback with waitForBoundSession and treat unavailable binding as a skipped dispatch. origin: PR #583 - Finding 1: supervisor child lookup accepted only exact selectors after worker suffix matching; add the same session-ID suffix fallback within the selected worker. origin: PR #583 - Finding 3: passive create hydration skipped explicit name and client environment bookkeeping; apply both before returning the hydrated state. origin: PR #583 - Finding 4: concurrent passive deletions raced through asynchronous resolution and started duplicate host deletes; defer deletion behind an atomic in-flight map check and coalesce callers. origin: PR #583 - Finding 5: concurrent hydration could make a passive lookup stale for advertised IDs and paths; retry normal bound-session resolution before rethrowing the original unknown-session error. origin: PR #583 - Finding 6: ambiguous live selectors fell through to passive lookup and could misroute; introduce a dedicated ambiguity error and rethrow it before passive resolution. origin: PR #583 - Finding 7: passive open skipped name and client-env bookkeeping (cron rebinding already occurred in addRuntime); apply only the missing bookkeeping. origin: PR #583 - Finding 30: rlmChildId traffic treated a resident passivating child as closing; join passivation and rehydrate in both bound lookup and direct message hydration branches. origin: PR #589
snimu
added a commit
that referenced
this pull request
Aug 4, 2026
…ots, and depth ingestion - preserve daemon routable IDs for passive children (origin: PR #583) - recheck guarded passive hydration and heartbeat restores (origin: PR #583) - repair wrong-kind pending hydration joins (origin: PR #583) - fence passive hydration during update restart preparation (origin: PR #583) - validate persisted RLM depth before constructor ingestion (origin: PR #584) - retry attach child snapshots across session replacement (origin: PR #587) - retain effective depth for legacy parented new sessions (origin: PR #589) - coordinate parent passivation with child hydration publication (origin: PR #589)
snimu
added a commit
that referenced
this pull request
Aug 4, 2026
…letion races - Finding 0: heartbeat restore could return a concurrently hydrating child before binding; fence resident fallback with waitForBoundSession and treat unavailable binding as a skipped dispatch. origin: PR #583 - Finding 1: supervisor child lookup accepted only exact selectors after worker suffix matching; add the same session-ID suffix fallback within the selected worker. origin: PR #583 - Finding 3: passive create hydration skipped explicit name and client environment bookkeeping; apply both before returning the hydrated state. origin: PR #583 - Finding 4: concurrent passive deletions raced through asynchronous resolution and started duplicate host deletes; defer deletion behind an atomic in-flight map check and coalesce callers. origin: PR #583 - Finding 5: concurrent hydration could make a passive lookup stale for advertised IDs and paths; retry normal bound-session resolution before rethrowing the original unknown-session error. origin: PR #583 - Finding 6: ambiguous live selectors fell through to passive lookup and could misroute; introduce a dedicated ambiguity error and rethrow it before passive resolution. origin: PR #583 - Finding 7: passive open skipped name and client-env bookkeeping (cron rebinding already occurred in addRuntime); apply only the missing bookkeeping. origin: PR #583 - Finding 30: rlmChildId traffic treated a resident passivating child as closing; join passivation and rehydrate in both bound lookup and direct message hydration branches. origin: PR #589
snimu
added a commit
that referenced
this pull request
Aug 4, 2026
…ots, and depth ingestion - preserve daemon routable IDs for passive children (origin: PR #583) - recheck guarded passive hydration and heartbeat restores (origin: PR #583) - repair wrong-kind pending hydration joins (origin: PR #583) - fence passive hydration during update restart preparation (origin: PR #583) - validate persisted RLM depth before constructor ingestion (origin: PR #584) - retry attach child snapshots across session replacement (origin: PR #587) - retain effective depth for legacy parented new sessions (origin: PR #589) - coordinate parent passivation with child hydration publication (origin: PR #589)
snimu
added a commit
that referenced
this pull request
Aug 4, 2026
…letion races - Finding 0: heartbeat restore could return a concurrently hydrating child before binding; fence resident fallback with waitForBoundSession and treat unavailable binding as a skipped dispatch. origin: PR #583 - Finding 1: supervisor child lookup accepted only exact selectors after worker suffix matching; add the same session-ID suffix fallback within the selected worker. origin: PR #583 - Finding 3: passive create hydration skipped explicit name and client environment bookkeeping; apply both before returning the hydrated state. origin: PR #583 - Finding 4: concurrent passive deletions raced through asynchronous resolution and started duplicate host deletes; defer deletion behind an atomic in-flight map check and coalesce callers. origin: PR #583 - Finding 5: concurrent hydration could make a passive lookup stale for advertised IDs and paths; retry normal bound-session resolution before rethrowing the original unknown-session error. origin: PR #583 - Finding 6: ambiguous live selectors fell through to passive lookup and could misroute; introduce a dedicated ambiguity error and rethrow it before passive resolution. origin: PR #583 - Finding 7: passive open skipped name and client-env bookkeeping (cron rebinding already occurred in addRuntime); apply only the missing bookkeeping. origin: PR #583 - Finding 30: rlmChildId traffic treated a resident passivating child as closing; join passivation and rehydrate in both bound lookup and direct message hydration branches. origin: PR #589
snimu
added a commit
that referenced
this pull request
Aug 4, 2026
…ots, and depth ingestion - preserve daemon routable IDs for passive children (origin: PR #583) - recheck guarded passive hydration and heartbeat restores (origin: PR #583) - repair wrong-kind pending hydration joins (origin: PR #583) - fence passive hydration during update restart preparation (origin: PR #583) - validate persisted RLM depth before constructor ingestion (origin: PR #584) - retry attach child snapshots across session replacement (origin: PR #587) - retain effective depth for legacy parented new sessions (origin: PR #589) - coordinate parent passivation with child hydration publication (origin: PR #589)
snimu
added a commit
that referenced
this pull request
Aug 4, 2026
…letion races - Finding 0: heartbeat restore could return a concurrently hydrating child before binding; fence resident fallback with waitForBoundSession and treat unavailable binding as a skipped dispatch. origin: PR #583 - Finding 1: supervisor child lookup accepted only exact selectors after worker suffix matching; add the same session-ID suffix fallback within the selected worker. origin: PR #583 - Finding 3: passive create hydration skipped explicit name and client environment bookkeeping; apply both before returning the hydrated state. origin: PR #583 - Finding 4: concurrent passive deletions raced through asynchronous resolution and started duplicate host deletes; defer deletion behind an atomic in-flight map check and coalesce callers. origin: PR #583 - Finding 5: concurrent hydration could make a passive lookup stale for advertised IDs and paths; retry normal bound-session resolution before rethrowing the original unknown-session error. origin: PR #583 - Finding 6: ambiguous live selectors fell through to passive lookup and could misroute; introduce a dedicated ambiguity error and rethrow it before passive resolution. origin: PR #583 - Finding 7: passive open skipped name and client-env bookkeeping (cron rebinding already occurred in addRuntime); apply only the missing bookkeeping. origin: PR #583 - Finding 30: rlmChildId traffic treated a resident passivating child as closing; join passivation and rehydrate in both bound lookup and direct message hydration branches. origin: PR #589
snimu
added a commit
that referenced
this pull request
Aug 4, 2026
…ots, and depth ingestion - preserve daemon routable IDs for passive children (origin: PR #583) - recheck guarded passive hydration and heartbeat restores (origin: PR #583) - repair wrong-kind pending hydration joins (origin: PR #583) - fence passive hydration during update restart preparation (origin: PR #583) - validate persisted RLM depth before constructor ingestion (origin: PR #584) - retry attach child snapshots across session replacement (origin: PR #587) - retain effective depth for legacy parented new sessions (origin: PR #589) - coordinate parent passivation with child hydration publication (origin: PR #589)
sethkarten
self-requested a review
August 4, 2026 21:10
sethkarten
approved these changes
Aug 4, 2026
snimu
added a commit
that referenced
this pull request
Aug 4, 2026
…letion races - Finding 0: heartbeat restore could return a concurrently hydrating child before binding; fence resident fallback with waitForBoundSession and treat unavailable binding as a skipped dispatch. origin: PR #583 - Finding 1: supervisor child lookup accepted only exact selectors after worker suffix matching; add the same session-ID suffix fallback within the selected worker. origin: PR #583 - Finding 3: passive create hydration skipped explicit name and client environment bookkeeping; apply both before returning the hydrated state. origin: PR #583 - Finding 4: concurrent passive deletions raced through asynchronous resolution and started duplicate host deletes; defer deletion behind an atomic in-flight map check and coalesce callers. origin: PR #583 - Finding 5: concurrent hydration could make a passive lookup stale for advertised IDs and paths; retry normal bound-session resolution before rethrowing the original unknown-session error. origin: PR #583 - Finding 6: ambiguous live selectors fell through to passive lookup and could misroute; introduce a dedicated ambiguity error and rethrow it before passive resolution. origin: PR #583 - Finding 7: passive open skipped name and client-env bookkeeping (cron rebinding already occurred in addRuntime); apply only the missing bookkeeping. origin: PR #583 - Finding 30: rlmChildId traffic treated a resident passivating child as closing; join passivation and rehydrate in both bound lookup and direct message hydration branches. origin: PR #589
snimu
added a commit
that referenced
this pull request
Aug 4, 2026
…ots, and depth ingestion - preserve daemon routable IDs for passive children (origin: PR #583) - recheck guarded passive hydration and heartbeat restores (origin: PR #583) - repair wrong-kind pending hydration joins (origin: PR #583) - fence passive hydration during update restart preparation (origin: PR #583) - validate persisted RLM depth before constructor ingestion (origin: PR #584) - retry attach child snapshots across session replacement (origin: PR #587) - retain effective depth for legacy parented new sessions (origin: PR #589) - coordinate parent passivation with child hydration publication (origin: PR #589)
Stop eagerly rehydrating completed RLM subagent sessions as full runtimes when a parent session opens. Children stay on disk (registry entry + JSONL) until first touched: agent message, client attach, observe read, or delete. - passive children served registry-backed in both list branches; supervisor list/create/attach routes them to the owning worker; cross-worker peers include them - hydrations coalesce through openingSessions with explicit opens; attach/ observe/message share identical binding-wait race semantics; session lease acquired on the hydration path - passive delete tombstones the registry, files preserved (same semantics as live delete) - rlmRehydrationClaims replaced by per-child in-flight hydration promises; one cycle-safe async registry walker; no metadata cache (async listAgents via existing readSessionInfo mtime cache) Track A PR 1 of the recursive-agent-harness plan.
- Match passive children by their current session name while retaining registry names only as a legacy fallback.
- Replace resident top-level runtimes for registered RLM children during heartbeat restoration.\n- Keep cancelling RLM heartbeats for resident top-level sessions that are not registered children.
- Keep a passive subagent's persisted summary id when attach hydration creates its runtime so supervisor event routing and snapshot caches use one id. - Cover passive-row attach hydration with a daemon regression test.
The 'cancels an RLM heartbeat for a resident top-level session that is not a registered child' test never persisted its child session file, so restoration bailed at the session-id mismatch before reaching the childState-kind guard the test describes. The fixture now persists the child session with the matching id, and the test asserts the parent open ran and cancellation came from the kind guard.
snimu
force-pushed
the
feat/lazy-child-hydration
branch
from
August 4, 2026 22:42
79a0c8d to
0e6a645
Compare
snimu
added a commit
that referenced
this pull request
Aug 4, 2026
…letion races - Finding 0: heartbeat restore could return a concurrently hydrating child before binding; fence resident fallback with waitForBoundSession and treat unavailable binding as a skipped dispatch. origin: PR #583 - Finding 1: supervisor child lookup accepted only exact selectors after worker suffix matching; add the same session-ID suffix fallback within the selected worker. origin: PR #583 - Finding 3: passive create hydration skipped explicit name and client environment bookkeeping; apply both before returning the hydrated state. origin: PR #583 - Finding 4: concurrent passive deletions raced through asynchronous resolution and started duplicate host deletes; defer deletion behind an atomic in-flight map check and coalesce callers. origin: PR #583 - Finding 5: concurrent hydration could make a passive lookup stale for advertised IDs and paths; retry normal bound-session resolution before rethrowing the original unknown-session error. origin: PR #583 - Finding 6: ambiguous live selectors fell through to passive lookup and could misroute; introduce a dedicated ambiguity error and rethrow it before passive resolution. origin: PR #583 - Finding 7: passive open skipped name and client-env bookkeeping (cron rebinding already occurred in addRuntime); apply only the missing bookkeeping. origin: PR #583 - Finding 30: rlmChildId traffic treated a resident passivating child as closing; join passivation and rehydrate in both bound lookup and direct message hydration branches. origin: PR #589
snimu
added a commit
that referenced
this pull request
Aug 4, 2026
…ots, and depth ingestion - preserve daemon routable IDs for passive children (origin: PR #583) - recheck guarded passive hydration and heartbeat restores (origin: PR #583) - repair wrong-kind pending hydration joins (origin: PR #583) - fence passive hydration during update restart preparation (origin: PR #583) - validate persisted RLM depth before constructor ingestion (origin: PR #584) - retry attach child snapshots across session replacement (origin: PR #587) - retain effective depth for legacy parented new sessions (origin: PR #589) - coordinate parent passivation with child hydration publication (origin: PR #589)
snimu
added a commit
that referenced
this pull request
Aug 4, 2026
…letion races - Finding 0: heartbeat restore could return a concurrently hydrating child before binding; fence resident fallback with waitForBoundSession and treat unavailable binding as a skipped dispatch. origin: PR #583 - Finding 1: supervisor child lookup accepted only exact selectors after worker suffix matching; add the same session-ID suffix fallback within the selected worker. origin: PR #583 - Finding 3: passive create hydration skipped explicit name and client environment bookkeeping; apply both before returning the hydrated state. origin: PR #583 - Finding 4: concurrent passive deletions raced through asynchronous resolution and started duplicate host deletes; defer deletion behind an atomic in-flight map check and coalesce callers. origin: PR #583 - Finding 5: concurrent hydration could make a passive lookup stale for advertised IDs and paths; retry normal bound-session resolution before rethrowing the original unknown-session error. origin: PR #583 - Finding 6: ambiguous live selectors fell through to passive lookup and could misroute; introduce a dedicated ambiguity error and rethrow it before passive resolution. origin: PR #583 - Finding 7: passive open skipped name and client-env bookkeeping (cron rebinding already occurred in addRuntime); apply only the missing bookkeeping. origin: PR #583 - Finding 30: rlmChildId traffic treated a resident passivating child as closing; join passivation and rehydrate in both bound lookup and direct message hydration branches. origin: PR #589
snimu
added a commit
that referenced
this pull request
Aug 4, 2026
…ots, and depth ingestion - preserve daemon routable IDs for passive children (origin: PR #583) - recheck guarded passive hydration and heartbeat restores (origin: PR #583) - repair wrong-kind pending hydration joins (origin: PR #583) - fence passive hydration during update restart preparation (origin: PR #583) - validate persisted RLM depth before constructor ingestion (origin: PR #584) - retry attach child snapshots across session replacement (origin: PR #587) - retain effective depth for legacy parented new sessions (origin: PR #589) - coordinate parent passivation with child hydration publication (origin: PR #589)
- Wait for path-keyed explicit-open reservations before lazy child hydration retries. - Cover the reservation race between explicit open and passive child hydration.
snimu
added a commit
that referenced
this pull request
Aug 4, 2026
…letion races - Finding 0: heartbeat restore could return a concurrently hydrating child before binding; fence resident fallback with waitForBoundSession and treat unavailable binding as a skipped dispatch. origin: PR #583 - Finding 1: supervisor child lookup accepted only exact selectors after worker suffix matching; add the same session-ID suffix fallback within the selected worker. origin: PR #583 - Finding 3: passive create hydration skipped explicit name and client environment bookkeeping; apply both before returning the hydrated state. origin: PR #583 - Finding 4: concurrent passive deletions raced through asynchronous resolution and started duplicate host deletes; defer deletion behind an atomic in-flight map check and coalesce callers. origin: PR #583 - Finding 5: concurrent hydration could make a passive lookup stale for advertised IDs and paths; retry normal bound-session resolution before rethrowing the original unknown-session error. origin: PR #583 - Finding 6: ambiguous live selectors fell through to passive lookup and could misroute; introduce a dedicated ambiguity error and rethrow it before passive resolution. origin: PR #583 - Finding 7: passive open skipped name and client-env bookkeeping (cron rebinding already occurred in addRuntime); apply only the missing bookkeeping. origin: PR #583 - Finding 30: rlmChildId traffic treated a resident passivating child as closing; join passivation and rehydrate in both bound lookup and direct message hydration branches. origin: PR #589
snimu
added a commit
that referenced
this pull request
Aug 4, 2026
…ots, and depth ingestion - preserve daemon routable IDs for passive children (origin: PR #583) - recheck guarded passive hydration and heartbeat restores (origin: PR #583) - repair wrong-kind pending hydration joins (origin: PR #583) - fence passive hydration during update restart preparation (origin: PR #583) - validate persisted RLM depth before constructor ingestion (origin: PR #584) - retry attach child snapshots across session replacement (origin: PR #587) - retain effective depth for legacy parented new sessions (origin: PR #589) - coordinate parent passivation with child hydration publication (origin: PR #589)
This was referenced Aug 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When you opened a session that had spawned subagents, we used to load every finished subagent back into memory as a full runtime, immediately, whether or not you ever looked at them. That's wasted memory and startup time.
With this change, finished subagents just stay on disk. They only get loaded when something actually touches them: you attach to one, read its transcript, send it a message, or delete it. Until then they're just a registry entry and a transcript file.
Details worth knowing:
list_subagents, etc.) show these on-disk children without loading them.This is part 1–7 of a stack (each PR builds on the one before it):
/rlm-max-depthcommand to control how deep agents can nestTests: the full suite at the top of the stack fails only on tests that already fail on the base branch. Each branch in the stack also passes checks and its own tests independently.
Note
Add lazy hydration of passive child sessions in the coding agent daemon
list,attach,create, observe, and messaging commands.openingSessions.AgentSession.listRlmSubagentsis now async and merges daemon-reported passive children into local results;deleteRlmSubagenthandles passive entries with stricter ambiguity detection.DAEMON_SCHEMA_REVISION) to advertise the newrlmDepthfield on passive session rows.listRlmSubagentssynchronously must now await it.Changes since #583 opened
AgentDaemon.rehydrateCompletedRlmSubagentmethod to wait for concurrent explicit session opens [617ecca]Macroscope summarized 0e6a645.
Note
Medium Risk
Touches daemon session lifecycle, RLM registry IO, cron heartbeat restore, and async breaking changes to listRlmSubagents and host controllers; race coalescing is new but heavily tested.
Overview
Lazy passive RLM children replace eager rehydration of every completed subagent when a parent opens. The daemon walks persisted
rlm-subagents.jsonlregistries to list passive children (including nested trees and non-resident saved roots) without creating runtimes, and bumps daemon schema revision 9 withrlmDepthon passive session rows.On-demand hydration runs when
create,attach, agent messaging,agent_observe, or RLM heartbeat restore targets a passive child: the ancestor chain is rehydrated in order, concurrent opens shareopeningSessions, and half-bound sessions wait onbindingCompletionsinstead of failing as unavailable.AgentSessionmakeslistRlmSubagentsasync, merges daemon-reported passive children (viasessionDiron agent summaries), and extendsdeleteRlmSubagentfor passive-only children (optional session ondeleteRlmSubagentRuntime, ambiguity checks against asynclistAgents). Host handlers for agent message, observe, and RLM list nowawaitcontrollers that may return promises.Supervisor paths forward create to the owning worker when the target is a passive child row, and retain passive summaries in cross-worker agent peer sync.
Reviewed by Cursor Bugbot for commit 617ecca. Bugbot is set up for automated code reviews on this repo. Configure here.