Skip to content

feat(coding-agent): recursive scoped agents view - #586

Merged
snimu merged 8 commits into
feat/rlm-max-depth-commandfrom
feat/scoped-agents-view
Aug 5, 2026
Merged

snimu merged 8 commits into
feat/rlm-max-depth-commandfrom
feat/scoped-agents-view

Conversation

@snimu

@snimu snimu commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

The agents view used to be one flat list of top-level sessions. Now that agents can have children and grandchildren, you can navigate the tree:

  • Press Right on a session to drill into its children; Left goes back up one level.
  • The header shows where you are, and each chat shows its own depth next to the model name.
  • Selecting a child opens it directly as a normal chat — including children that are currently unloaded (they wake up on demand).
  • If a subtree disappears while you're inside it (say the sessions got deleted), the view walks you back up to the nearest level that still exists instead of getting stuck.

This is part 1–7 of a stack (each PR builds on the one before it):

  1. feat(coding-agent): lazy child session hydration #583 — don't load finished subagents until someone needs them
  2. feat(coding-agent): persist parent edges and derived depth for all sessions #584 — record each session's parent and depth on disk
  3. feat(coding-agent): /rlm-max-depth session command #585 — new /rlm-max-depth command to control how deep agents can nest
  4. feat(coding-agent): recursive scoped agents view #586 — browse the agent tree in the agents view
  5. feat(coding-agent): delete child-agent inspector; one subagent summary line #587 — replace the child-agent inspector with one summary line
  6. feat(coding-agent): whole-tree idle eviction #588 — shut down worker processes whose sessions have all gone idle
  7. feat(coding-agent): intra-tree child session passivation #589 — quietly unload idle child sessions inside a running worker

Tests: 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 recursive scoped agents view with scope stack navigation and subtree filtering

  • Introduces a scope stack to the agents view so users can drill into a session's subtree and navigate back, replacing the previous in-session subagent detail panel with a full scoped agents view.
  • AgentsViewMode now filters and renders only the subtree rooted at the current scope, promotes direct children of the scope root to depth-0 agent rows, and gracefully falls back to the nearest available ancestor when the scoped root is missing.
  • InteractiveMode routes child-agent tray interactions to openScopedAgentsView() instead of openChildAgentDetail(), and the run result can now be 'scoped_agents_view' to signal scoped re-entry.
  • Scope frames, last successful live summaries, and selection state are persisted across chat returns so the view restores correctly after transient refresh failures.
  • formatAgentDepthLabel adds a depth indicator to the chat tray location label when session depth and children hints are available.
  • Risk: initialSubagentNodeId and enteredSessionViaSubagentDetail are removed; callers relying on auto-opening a subagent detail panel on startup will no longer see that behavior.

Macroscope summarized 05ba353.


Note

Medium Risk
Large TUI navigation refactor removes startup subagent detail auto-open and changes agents-view/chat handoff; scope and catalog reconciliation bugs could mis-route users or drop selection after daemon refresh.

Overview
Introduces recursive scoped navigation in the agents view: a scope stack filters the unified catalog to a session’s subtree, Right drills into children, Left pops to the parent scope (or reopens the recorded return chat), and the splash shows scope and depth.

InteractiveMode no longer auto-opens initialSubagentNodeId or the full-screen subagent detail panel; the child-agent tray now calls openScopedAgentsView(), and exiting chat can return scoped_agents_view so main re-enters the agents view rooted at that session. Chat passes sessionDepth / sessionHasChildren for tray depth labels via formatAgentDepthLabel.

agents-view-state gains unified indexing, subtree scoping, scope-frame resolution/fallback when roots vanish, saved-session parent links, unattachable-child open fallback, and direct children promoted to top-level rows inside a scope.

Resilience: cached lastSuccessfulLiveSummaries, live/saved catalog-ready gates before dropping invalid scopes, combined startup notices, and reconnect no longer clears the list to empty on timeout.

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

Comment thread packages/coding-agent/src/modes/agents-view/agents-view-mode.ts
Comment thread packages/coding-agent/src/modes/agents-view/agents-view-mode.ts
Comment thread packages/coding-agent/src/modes/agents-view/agents-view-mode.ts
snimu added a commit that referenced this pull request Aug 3, 2026
…n, summary refresh, pulse, and settings cycling

- Finding 18: stale saved-catalog readiness could destructively drop scope during refresh; reset readiness when refresh starts. origin: PR #586
- Finding 19: resolved scope roots were lost across view remounts, swallowing early Left navigation; persist and restore the root summary. origin: PR #586
- Finding 20: post-attach crashes left backSession pointing at the prior session; assign the opened summary before interactive mode runs. origin: PR #586
- Findings 21 and 24: startup seeding could leave subagent counts stale and background subagents drove an unused render pulse; refresh every seed and pulse only while streaming. origin: PR #587
- Finding 27: custom idle-eviction values cycled directly to off; include custom numeric values in the sorted cycle. origin: PR #588
@snimu
snimu force-pushed the feat/scoped-agents-view branch from 8274550 to af05deb Compare August 3, 2026 12:05
snimu added a commit that referenced this pull request Aug 3, 2026
…n, summary refresh, pulse, and settings cycling

- Finding 18: stale saved-catalog readiness could destructively drop scope during refresh; reset readiness when refresh starts. origin: PR #586
- Finding 19: resolved scope roots were lost across view remounts, swallowing early Left navigation; persist and restore the root summary. origin: PR #586
- Finding 20: post-attach crashes left backSession pointing at the prior session; assign the opened summary before interactive mode runs. origin: PR #586
- Findings 21 and 24: startup seeding could leave subagent counts stale and background subagents drove an unused render pulse; refresh every seed and pulse only while streaming. origin: PR #587
- Finding 27: custom idle-eviction values cycled directly to off; include custom numeric values in the sorted cycle. origin: PR #588
Comment thread packages/coding-agent/src/modes/agents-view/agents-view-mode.ts
snimu added a commit that referenced this pull request Aug 4, 2026
…n, summary refresh, pulse, and settings cycling

- Finding 18: stale saved-catalog readiness could destructively drop scope during refresh; reset readiness when refresh starts. origin: PR #586
- Finding 19: resolved scope roots were lost across view remounts, swallowing early Left navigation; persist and restore the root summary. origin: PR #586
- Finding 20: post-attach crashes left backSession pointing at the prior session; assign the opened summary before interactive mode runs. origin: PR #586
- Findings 21 and 24: startup seeding could leave subagent counts stale and background subagents drove an unused render pulse; refresh every seed and pulse only while streaming. origin: PR #587
- Finding 27: custom idle-eviction values cycled directly to off; include custom numeric values in the sorted cycle. origin: PR #588
Comment thread packages/coding-agent/src/modes/agents-view/agents-view-mode.ts
snimu added a commit that referenced this pull request Aug 4, 2026
…n, summary refresh, pulse, and settings cycling

- Finding 18: stale saved-catalog readiness could destructively drop scope during refresh; reset readiness when refresh starts. origin: PR #586
- Finding 19: resolved scope roots were lost across view remounts, swallowing early Left navigation; persist and restore the root summary. origin: PR #586
- Finding 20: post-attach crashes left backSession pointing at the prior session; assign the opened summary before interactive mode runs. origin: PR #586
- Findings 21 and 24: startup seeding could leave subagent counts stale and background subagents drove an unused render pulse; refresh every seed and pulse only while streaming. origin: PR #587
- Finding 27: custom idle-eviction values cycled directly to off; include custom numeric values in the sorted cycle. origin: PR #588
Comment thread packages/coding-agent/src/modes/agents-view/agents-view-mode.ts Outdated
snimu added a commit that referenced this pull request Aug 4, 2026
…n, summary refresh, pulse, and settings cycling

- Finding 18: stale saved-catalog readiness could destructively drop scope during refresh; reset readiness when refresh starts. origin: PR #586
- Finding 19: resolved scope roots were lost across view remounts, swallowing early Left navigation; persist and restore the root summary. origin: PR #586
- Finding 20: post-attach crashes left backSession pointing at the prior session; assign the opened summary before interactive mode runs. origin: PR #586
- Findings 21 and 24: startup seeding could leave subagent counts stale and background subagents drove an unused render pulse; refresh every seed and pulse only while streaming. origin: PR #587
- Finding 27: custom idle-eviction values cycled directly to off; include custom numeric values in the sorted cycle. origin: PR #588
@snimu
snimu force-pushed the feat/scoped-agents-view branch from a001a6a to b86aae8 Compare August 4, 2026 07:49
snimu added a commit that referenced this pull request Aug 4, 2026
…n, summary refresh, pulse, and settings cycling

- Finding 18: stale saved-catalog readiness could destructively drop scope during refresh; reset readiness when refresh starts. origin: PR #586
- Finding 19: resolved scope roots were lost across view remounts, swallowing early Left navigation; persist and restore the root summary. origin: PR #586
- Finding 20: post-attach crashes left backSession pointing at the prior session; assign the opened summary before interactive mode runs. origin: PR #586
- Findings 21 and 24: startup seeding could leave subagent counts stale and background subagents drove an unused render pulse; refresh every seed and pulse only while streaming. origin: PR #587
- Finding 27: custom idle-eviction values cycled directly to off; include custom numeric values in the sorted cycle. origin: PR #588
snimu added a commit that referenced this pull request Aug 4, 2026
…n, summary refresh, pulse, and settings cycling

- Finding 18: stale saved-catalog readiness could destructively drop scope during refresh; reset readiness when refresh starts. origin: PR #586
- Finding 19: resolved scope roots were lost across view remounts, swallowing early Left navigation; persist and restore the root summary. origin: PR #586
- Finding 20: post-attach crashes left backSession pointing at the prior session; assign the opened summary before interactive mode runs. origin: PR #586
- Findings 21 and 24: startup seeding could leave subagent counts stale and background subagents drove an unused render pulse; refresh every seed and pulse only while streaming. origin: PR #587
- Finding 27: custom idle-eviction values cycled directly to off; include custom numeric values in the sorted cycle. origin: PR #588
@snimu
snimu force-pushed the feat/scoped-agents-view branch from b86aae8 to 0d6333c Compare August 4, 2026 09:15
snimu added a commit that referenced this pull request Aug 4, 2026
…n, summary refresh, pulse, and settings cycling

- Finding 18: stale saved-catalog readiness could destructively drop scope during refresh; reset readiness when refresh starts. origin: PR #586
- Finding 19: resolved scope roots were lost across view remounts, swallowing early Left navigation; persist and restore the root summary. origin: PR #586
- Finding 20: post-attach crashes left backSession pointing at the prior session; assign the opened summary before interactive mode runs. origin: PR #586
- Findings 21 and 24: startup seeding could leave subagent counts stale and background subagents drove an unused render pulse; refresh every seed and pulse only while streaming. origin: PR #587
- Finding 27: custom idle-eviction values cycled directly to off; include custom numeric values in the sorted cycle. origin: PR #588
@snimu
snimu force-pushed the feat/scoped-agents-view branch from 0d6333c to 6f37045 Compare August 4, 2026 09:39
snimu added a commit that referenced this pull request Aug 4, 2026
…n, summary refresh, pulse, and settings cycling

- Finding 18: stale saved-catalog readiness could destructively drop scope during refresh; reset readiness when refresh starts. origin: PR #586
- Finding 19: resolved scope roots were lost across view remounts, swallowing early Left navigation; persist and restore the root summary. origin: PR #586
- Finding 20: post-attach crashes left backSession pointing at the prior session; assign the opened summary before interactive mode runs. origin: PR #586
- Findings 21 and 24: startup seeding could leave subagent counts stale and background subagents drove an unused render pulse; refresh every seed and pulse only while streaming. origin: PR #587
- Finding 27: custom idle-eviction values cycled directly to off; include custom numeric values in the sorted cycle. origin: PR #588
@snimu
snimu force-pushed the feat/scoped-agents-view branch from 6f37045 to 31f1284 Compare August 4, 2026 12:36
snimu added a commit that referenced this pull request Aug 4, 2026
…n, summary refresh, pulse, and settings cycling

- Finding 18: stale saved-catalog readiness could destructively drop scope during refresh; reset readiness when refresh starts. origin: PR #586
- Finding 19: resolved scope roots were lost across view remounts, swallowing early Left navigation; persist and restore the root summary. origin: PR #586
- Finding 20: post-attach crashes left backSession pointing at the prior session; assign the opened summary before interactive mode runs. origin: PR #586
- Findings 21 and 24: startup seeding could leave subagent counts stale and background subagents drove an unused render pulse; refresh every seed and pulse only while streaming. origin: PR #587
- Finding 27: custom idle-eviction values cycled directly to off; include custom numeric values in the sorted cycle. origin: PR #588
@snimu
snimu force-pushed the feat/scoped-agents-view branch from 51ade1c to 039d163 Compare August 4, 2026 22:42
snimu added a commit that referenced this pull request Aug 4, 2026
…n, summary refresh, pulse, and settings cycling

- Finding 18: stale saved-catalog readiness could destructively drop scope during refresh; reset readiness when refresh starts. origin: PR #586
- Finding 19: resolved scope roots were lost across view remounts, swallowing early Left navigation; persist and restore the root summary. origin: PR #586
- Finding 20: post-attach crashes left backSession pointing at the prior session; assign the opened summary before interactive mode runs. origin: PR #586
- Findings 21 and 24: startup seeding could leave subagent counts stale and background subagents drove an unused render pulse; refresh every seed and pulse only while streaming. origin: PR #587
- Finding 27: custom idle-eviction values cycled directly to off; include custom numeric values in the sorted cycle. origin: PR #588
@snimu
snimu force-pushed the feat/scoped-agents-view branch from 039d163 to 2a8ebc3 Compare August 4, 2026 23:03
snimu added a commit that referenced this pull request Aug 4, 2026
…n, summary refresh, pulse, and settings cycling

- Finding 18: stale saved-catalog readiness could destructively drop scope during refresh; reset readiness when refresh starts. origin: PR #586
- Finding 19: resolved scope roots were lost across view remounts, swallowing early Left navigation; persist and restore the root summary. origin: PR #586
- Finding 20: post-attach crashes left backSession pointing at the prior session; assign the opened summary before interactive mode runs. origin: PR #586
- Findings 21 and 24: startup seeding could leave subagent counts stale and background subagents drove an unused render pulse; refresh every seed and pulse only while streaming. origin: PR #587
- Finding 27: custom idle-eviction values cycled directly to off; include custom numeric values in the sorted cycle. origin: PR #588
@snimu
snimu force-pushed the feat/scoped-agents-view branch from 2a8ebc3 to 400c189 Compare August 4, 2026 23:26
snimu added a commit that referenced this pull request Aug 4, 2026
…n, summary refresh, pulse, and settings cycling

- Finding 18: stale saved-catalog readiness could destructively drop scope during refresh; reset readiness when refresh starts. origin: PR #586
- Finding 19: resolved scope roots were lost across view remounts, swallowing early Left navigation; persist and restore the root summary. origin: PR #586
- Finding 20: post-attach crashes left backSession pointing at the prior session; assign the opened summary before interactive mode runs. origin: PR #586
- Findings 21 and 24: startup seeding could leave subagent counts stale and background subagents drove an unused render pulse; refresh every seed and pulse only while streaming. origin: PR #587
- Finding 27: custom idle-eviction values cycled directly to off; include custom numeric values in the sorted cycle. origin: PR #588

@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 400c189. Configure here.

Comment thread packages/coding-agent/src/modes/agents-view/agents-view-mode.ts
@snimu
snimu force-pushed the feat/scoped-agents-view branch from 400c189 to 65edf95 Compare August 4, 2026 23:51
snimu added a commit that referenced this pull request Aug 4, 2026
…n, summary refresh, pulse, and settings cycling

- Finding 18: stale saved-catalog readiness could destructively drop scope during refresh; reset readiness when refresh starts. origin: PR #586
- Finding 19: resolved scope roots were lost across view remounts, swallowing early Left navigation; persist and restore the root summary. origin: PR #586
- Finding 20: post-attach crashes left backSession pointing at the prior session; assign the opened summary before interactive mode runs. origin: PR #586
- Findings 21 and 24: startup seeding could leave subagent counts stale and background subagents drove an unused render pulse; refresh every seed and pulse only while streaming. origin: PR #587
- Finding 27: custom idle-eviction values cycled directly to off; include custom numeric values in the sorted cycle. origin: PR #588
snimu added 8 commits August 5, 2026 02:20
Track A PR 4 of the recursive-agent-harness plan (D4, view half):

- agents view can be scoped to any session's subtree: scope = persistent
  stack of frames; scoped views show the root's children (live, passive
  registry-backed, and saved-only) via one unified-record BFS index
- navigation: Right drills down (view row -> chat; chat's subagents entry ->
  scoped view one level deeper); Left pops one scope level; Left in the
  global view is a no-op (old back-to-previous-chat behavior removed);
  distinct scope_back / scoped_agents_view result types
- direct child attach: subagent rows attach to the child session (passive
  children hydrate via the owning worker); parent fallback with notice only
  when truly unattachable; read-only subagent detail path deleted
  (initialSubagentNodeId, openChildAgentDetail)
- depth display: chat tray next to model/effort and agents-view header,
  sourced exclusively from persisted rlmDepth (never row inference)
- orphaned children re-root as top-level rows; vanished scopes truncate to
  the nearest surviving frame once catalogs settle (terminal failures also
  settle, no soft-lock)
…epth labels

Both fixes address user-reported issues on the scoped-agents-view feature. Descendant stack branches will be rebased onto this commit.
- Combine unattachable-child and missing-cwd startup notices.\n- Carry the last successful live catalog across agents-view instances so transient first-poll failures preserve live-only scope frames.
…ine persisted notices

The reconnect-timeout path applied an empty session list with both
catalogs marked ready, permanently truncating live-only scope frames.
It no longer establishes absence; a successful post-reconnect list
still settles normally. The agents-view return path also stored only
the cwd fallback notice, dropping the unattachable-child explanation;
it now uses the shared notice combiner.
- Seed the handoff session as the last successful live catalog so a transient first list failure cannot drop its scope.
- Cover the settled-catalog first-list-failure path with a regression test.
- Upsert scoped returns into the cached live catalog without dropping existing summaries.
- Cover a failed first scoped poll after returning from chat.
@snimu
snimu force-pushed the feat/scoped-agents-view branch from 65edf95 to 05ba353 Compare August 5, 2026 00:25
snimu added a commit that referenced this pull request Aug 5, 2026
…n, summary refresh, pulse, and settings cycling

- Finding 18: stale saved-catalog readiness could destructively drop scope during refresh; reset readiness when refresh starts. origin: PR #586
- Finding 19: resolved scope roots were lost across view remounts, swallowing early Left navigation; persist and restore the root summary. origin: PR #586
- Finding 20: post-attach crashes left backSession pointing at the prior session; assign the opened summary before interactive mode runs. origin: PR #586
- Findings 21 and 24: startup seeding could leave subagent counts stale and background subagents drove an unused render pulse; refresh every seed and pulse only while streaming. origin: PR #587
- Finding 27: custom idle-eviction values cycled directly to off; include custom numeric values in the sorted cycle. origin: PR #588
snimu added a commit that referenced this pull request Aug 5, 2026
…n, summary refresh, pulse, and settings cycling

- Finding 18: stale saved-catalog readiness could destructively drop scope during refresh; reset readiness when refresh starts. origin: PR #586
- Finding 19: resolved scope roots were lost across view remounts, swallowing early Left navigation; persist and restore the root summary. origin: PR #586
- Finding 20: post-attach crashes left backSession pointing at the prior session; assign the opened summary before interactive mode runs. origin: PR #586
- Findings 21 and 24: startup seeding could leave subagent counts stale and background subagents drove an unused render pulse; refresh every seed and pulse only while streaming. origin: PR #587
- Finding 27: custom idle-eviction values cycled directly to off; include custom numeric values in the sorted cycle. origin: PR #588
@snimu
snimu merged commit 5e9eb02 into main Aug 5, 2026
11 checks passed
snimu added a commit that referenced this pull request Aug 5, 2026
* feat(coding-agent): intra-tree child session passivation

Track A PR 7 (final) of the recursive-agent-harness plan (D5, shape 2):

- idle child sessions inside a LIVE worker passivate individually: graceful
  closeSession (kernel snapshot + JSONL flush + lease release), sessions-map
  removal, registry/catalog rows preserved - the child becomes exactly a
  lazy-hydration passive row (attach/message/observe/list all work)
- pure canPassivateSession() beside canEvictWorker(), sharing its per-
  session clauses; additionally requires a parent edge, no non-passive
  descendants, and no mid-hydration descendant (passive children's
  sessionFiles checked against openingSessions - hydration blocks parent
  passivation); roots remain shape-1 territory; passivation never cascades
- complete-then-rehydrate: touches mid-passivation join the passivation
  promise (keyed by resolved sessionFile - stable across sessions-map
  removal) then flow through the normal hydration machinery; deterministic
  gated race tests for a2a delivery and grandchild hydration
- supervisor sweep extension: capped worker command (2 children/worker/
  sweep), one snapshot per state per sweep, fresh-snapshot fence recheck
  before dispose; whole-tree-evictable workers excluded (owned by shape 1)
- same idleEvictionMinutes setting governs both shapes; #548 doctrine
  inversion deferred (prompts out of scope this run)

* fix(coding-agent): harden passivation against new admission fences and reap dedupe

Post-rebase semantic fixes after moving the stack onto the hardened
scheduler base (cb8f53e):

- passivation predicate treats admission-in-flight as busy: agent-message
  accepting/preparing/target-lock states and AgentSession's pending
  admission-fence waiters (70aeb9c/2d97dbb4f made prompt paths await the
  direct-turn admission fence before any session action exists, so a target
  mid-admission looked idle to the sweep); deterministic gated-admission
  regression test
- deleteRlmSubagentRuntime cancels scheduled jobs by session file even when
  its close joins an in-flight passivation close via closingSessions (the
  joined 'shutdown' close skipped 'killed'-close job cleanup; #547 reap race)

* fix(coding-agent): harden passive-child hydration, resolution, and deletion 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

* fix(coding-agent): restore attach/catch-up ordering invariants and sweep snapshot atomicity

- Finding 22: async snapshot creation exposed clients before attach initialization; publish client attachment only after the snapshot resolves. origin: PR #587
- Finding 23: catch-up validity was checked only before async snapshot creation; revalidate session and client attachment after the await. origin: PR #587
- Finding 25: deterministic ambiguous selectors entered the 30-second remote-send retry loop; fail fast for Ambiguous errors. origin: PR #588
- Finding 28: active rows ignored stable file-keyed schedule pins during active-id rebinding; consult both id- and file-keyed heartbeat/cron sets. origin: PR #588
- Finding 29: passivation sampled activity before an asynchronous passive-registry walk; complete the walk before atomically sampling summary and admission markers. origin: PR #589

* fix(coding-agent): correct rlmDepth semantics on reference edges, env parsing, and legacy fallbacks

- Finding 8: new-session parent links were deriving spawn depth; copy the source header depth across the reference edge and add a runtime regression test (origin: PR #584).
- Finding 9: first-entry forks of legacy sessions discarded effective runtime depth; fall back to session.rlmDepth in persisted and in-memory branches and test both (origin: PR #584).
- Finding 10: root RLM_DEPTH parsing accepted malformed and unsafe values; require decimal digits and a valid safe non-negative integer, with probe cases as tests (origin: PR #584).
- Finding 11: child-depth derivation could overflow MAX_SAFE_INTEGER; guard the increment and test the boundary (origin: PR #584).
- Finding 12: daemon children of in-memory parents skipped explicit depth persistence; always create the child header with explicit depth and test --no-session ancestry (origin: PR #584).
- Finding 13: legacy completed subagents rehydrated at root depth; restore the depth-one fallback and test a registry/header pair without depth (origin: PR #584).

* fix(coding-agent): make /rlm-max-depth persistence honest and unblock stale kernel gate

- /rlm-max-depth --global could claim persistence after deferred settings write failures; drain and surface global errors before reporting success (origin: PR #585)
- /rlm-max-depth mutated live state before chat persistence and left failed entries indexed; persist first through rollback-safe custom-entry append, then mutate state and prompt (origin: PR #585)
- invalid persisted global rlmMaxDepth could abort branch navigation after the leaf moved; ignore invalid global reads and fall through to env/default (origin: PR #585)
- the kernel-side recursion pre-filter used stale one-shot RLM_MAX_DEPTH and blocked raises before the authoritative host gate; remove the duplicated Python gate (origin: PR #585)

* fix(coding-agent): agents-view scope stability, crash-path backSession, summary refresh, pulse, and settings cycling

- Finding 18: stale saved-catalog readiness could destructively drop scope during refresh; reset readiness when refresh starts. origin: PR #586
- Finding 19: resolved scope roots were lost across view remounts, swallowing early Left navigation; persist and restore the root summary. origin: PR #586
- Finding 20: post-attach crashes left backSession pointing at the prior session; assign the opened summary before interactive mode runs. origin: PR #586
- Findings 21 and 24: startup seeding could leave subagent counts stale and background subagents drove an unused render pulse; refresh every seed and pulse only while streaming. origin: PR #587
- Finding 27: custom idle-eviction values cycled directly to off; include custom numeric values in the sorted cycle. origin: PR #588

* fix(coding-agent): attach reservation vs passivation, binding join on retry, hydration env, settings error scoping, fractional eviction values

- reserve in-flight attaches and revalidate session liveness before attachment (origin: round-1 fix a342ca2)
- join concurrent child binding on the final passive resolution retry (origin: round-1 fix ae3ed45)
- adopt create-command client env before passive child hydration (origin: round-1 fix ae3ed45)
- isolate max-depth write errors while preserving project diagnostics (origin: round-1 fix 9e738f3)
- preserve fractional idle eviction values through settings cycling (origin: round-1 fix 721f45b; stack commit aa98c9a)

* fix(coding-agent): post-rebase hardening of passive hydration, snapshots, 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)

* fix(coding-agent): leave shared passive hydration resident on guard cancellation

The ownership-blind close closed shared hydrations out from under concurrent wakes (both interleavings); the idle sweep is the ownership-free arbiter.

origin: round-4 fix b956400 / PR #583

* fix(coding-agent): prefer persisted header depth for legacy rehydration entries

The legacy-entry rehydration fallback (entry.rlmDepth ?? 1) is passed as
config, which outranks the opened transcript header in AgentSession — so a
nested legacy child whose header carried a deeper persisted depth woke at
depth 1, weakening the host recursion gate. Registry depth stays
authoritative when present; otherwise the validated header depth wins and 1
remains the last-resort default for fully legacy children.

origin: PR #584 fallback restored in round-1 triage; surfaced by post-rebase
bot review of PR #589.

* fix(coding-agent): fence chain hydration against parent passivation; invalidate stale scope roots

* fix(coding-agent): bound the session snapshot stabilization loop

* fix(coding-agent): restore child event forwarder when passivation close fails

Passivation teardown invoked the retained child's event-forwarder
unsubscribe before closing the session. When the close failed and the
child was re-adopted, the forwarder was gone, so a still-resident child
stopped emitting rlm_child_update to its parent. Teardown now returns
the unsubscribe so the passivation path only invokes it after a
successful close and restores it on the failed-close re-adopt path.

* fix(coding-agent): close child passivation races

- Keep snapshot messages aligned with the final runtime session summary after stabilization exhaustion.
- Retry passive child hydration when the child starts passivating inside the hydration window.
- Apply archive and scheduled-job cancellation when kill joins a resume-preserving close.

* fix(coding-agent): upgrade cascading close reasons

- Track the applied close reason and resident descendant states through cascading teardown.
- Apply stronger joined close effects uniformly to parents and captured descendants.
- Cover shutdown-to-killed descendant cleanup and completed-to-killed idempotency.

* fix(coding-agent): preserve passive child id on hydration retry

- Forward the restored active-session ID when retrying after a mismatched pending open.
- Cover the pending-open race through passive-child hydration.

* fix(coding-agent): recover passivation waiters

- Treat failed passivation settlement as a join signal before retrying resident sessions.
- Cover concurrent open, message delivery, and hydration after passivation rejection.

* fix(coding-agent): harden passivation close races

- Preserve stronger close-reason upgrades when the joined close fails.
- Run child passivation outside the supervisor-wide eviction fence.
- Complete reason-upgrade persistence across targets and record the stronger reason before propagating errors.

* fix(coding-agent): preserve passive opener state across races

- Defer root parent client env adoption until passive hydration and its open guard succeed.
- Join opening or resident passive targets when parent-change restart resolution races hydration.
@kevinjosethomas
kevinjosethomas deleted the feat/scoped-agents-view branch August 5, 2026 18:53
zhengr pushed a commit to zhengr/prime-agent that referenced this pull request Aug 8, 2026
* feat(coding-agent): recursive scoped agents view

Track A PR 4 of the recursive-agent-harness plan (D4, view half):

- agents view can be scoped to any session's subtree: scope = persistent
  stack of frames; scoped views show the root's children (live, passive
  registry-backed, and saved-only) via one unified-record BFS index
- navigation: Right drills down (view row -> chat; chat's subagents entry ->
  scoped view one level deeper); Left pops one scope level; Left in the
  global view is a no-op (old back-to-previous-chat behavior removed);
  distinct scope_back / scoped_agents_view result types
- direct child attach: subagent rows attach to the child session (passive
  children hydrate via the owning worker); parent fallback with notice only
  when truly unattachable; read-only subagent detail path deleted
  (initialSubagentNodeId, openChildAgentDetail)
- depth display: chat tray next to model/effort and agents-view header,
  sourced exclusively from persisted rlmDepth (never row inference)
- orphaned children re-root as top-level rows; vanished scopes truncate to
  the nearest surviving frame once catalogs settle (terminal failures also
  settle, no soft-lock)

* fix(coding-agent): symmetric agents-view navigation and child-level depth labels

Both fixes address user-reported issues on the scoped-agents-view feature. Descendant stack branches will be rebased onto this commit.

* fix(coding-agent): carry expansion and child metadata through returnChat opens

* fix(coding-agent): seed handoff scope frames with the return chat

* fix(coding-agent): preserve agents view fallback state

- Combine unattachable-child and missing-cwd startup notices.\n- Carry the last successful live catalog across agents-view instances so transient first-poll failures preserve live-only scope frames.

* fix(coding-agent): keep scoped frames across reconnect timeouts; combine persisted notices

The reconnect-timeout path applied an empty session list with both
catalogs marked ready, permanently truncating live-only scope frames.
It no longer establishes absence; a successful post-reconnect list
still settles normally. The agents-view return path also stored only
the cwd fallback notice, dropping the unattachable-child explanation;
it now uses the shared notice combiner.

* fix(coding-agent): preserve initial handoff scope

- Seed the handoff session as the last successful live catalog so a transient first list failure cannot drop its scope.
- Cover the settled-catalog first-list-failure path with a regression test.

* fix(coding-agent): preserve pushed scope live seed

- Upsert scoped returns into the cached live catalog without dropping existing summaries.
- Cover a failed first scoped poll after returning from chat.
zhengr pushed a commit to zhengr/prime-agent that referenced this pull request Aug 8, 2026
…ect-ai#589)

* feat(coding-agent): intra-tree child session passivation

Track A PR 7 (final) of the recursive-agent-harness plan (D5, shape 2):

- idle child sessions inside a LIVE worker passivate individually: graceful
  closeSession (kernel snapshot + JSONL flush + lease release), sessions-map
  removal, registry/catalog rows preserved - the child becomes exactly a
  lazy-hydration passive row (attach/message/observe/list all work)
- pure canPassivateSession() beside canEvictWorker(), sharing its per-
  session clauses; additionally requires a parent edge, no non-passive
  descendants, and no mid-hydration descendant (passive children's
  sessionFiles checked against openingSessions - hydration blocks parent
  passivation); roots remain shape-1 territory; passivation never cascades
- complete-then-rehydrate: touches mid-passivation join the passivation
  promise (keyed by resolved sessionFile - stable across sessions-map
  removal) then flow through the normal hydration machinery; deterministic
  gated race tests for a2a delivery and grandchild hydration
- supervisor sweep extension: capped worker command (2 children/worker/
  sweep), one snapshot per state per sweep, fresh-snapshot fence recheck
  before dispose; whole-tree-evictable workers excluded (owned by shape 1)
- same idleEvictionMinutes setting governs both shapes; PrimeIntellect-ai#548 doctrine
  inversion deferred (prompts out of scope this run)

* fix(coding-agent): harden passivation against new admission fences and reap dedupe

Post-rebase semantic fixes after moving the stack onto the hardened
scheduler base (cb8f53e):

- passivation predicate treats admission-in-flight as busy: agent-message
  accepting/preparing/target-lock states and AgentSession's pending
  admission-fence waiters (70aeb9c/2d97dbb4f made prompt paths await the
  direct-turn admission fence before any session action exists, so a target
  mid-admission looked idle to the sweep); deterministic gated-admission
  regression test
- deleteRlmSubagentRuntime cancels scheduled jobs by session file even when
  its close joins an in-flight passivation close via closingSessions (the
  joined 'shutdown' close skipped 'killed'-close job cleanup; PrimeIntellect-ai#547 reap race)

* fix(coding-agent): harden passive-child hydration, resolution, and deletion 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 PrimeIntellect-ai#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 PrimeIntellect-ai#583
- Finding 3: passive create hydration skipped explicit name and client environment bookkeeping; apply both before returning the hydrated state. origin: PR PrimeIntellect-ai#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 PrimeIntellect-ai#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 PrimeIntellect-ai#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 PrimeIntellect-ai#583
- Finding 7: passive open skipped name and client-env bookkeeping (cron rebinding already occurred in addRuntime); apply only the missing bookkeeping. origin: PR PrimeIntellect-ai#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 PrimeIntellect-ai#589

* fix(coding-agent): restore attach/catch-up ordering invariants and sweep snapshot atomicity

- Finding 22: async snapshot creation exposed clients before attach initialization; publish client attachment only after the snapshot resolves. origin: PR PrimeIntellect-ai#587
- Finding 23: catch-up validity was checked only before async snapshot creation; revalidate session and client attachment after the await. origin: PR PrimeIntellect-ai#587
- Finding 25: deterministic ambiguous selectors entered the 30-second remote-send retry loop; fail fast for Ambiguous errors. origin: PR PrimeIntellect-ai#588
- Finding 28: active rows ignored stable file-keyed schedule pins during active-id rebinding; consult both id- and file-keyed heartbeat/cron sets. origin: PR PrimeIntellect-ai#588
- Finding 29: passivation sampled activity before an asynchronous passive-registry walk; complete the walk before atomically sampling summary and admission markers. origin: PR PrimeIntellect-ai#589

* fix(coding-agent): correct rlmDepth semantics on reference edges, env parsing, and legacy fallbacks

- Finding 8: new-session parent links were deriving spawn depth; copy the source header depth across the reference edge and add a runtime regression test (origin: PR PrimeIntellect-ai#584).
- Finding 9: first-entry forks of legacy sessions discarded effective runtime depth; fall back to session.rlmDepth in persisted and in-memory branches and test both (origin: PR PrimeIntellect-ai#584).
- Finding 10: root RLM_DEPTH parsing accepted malformed and unsafe values; require decimal digits and a valid safe non-negative integer, with probe cases as tests (origin: PR PrimeIntellect-ai#584).
- Finding 11: child-depth derivation could overflow MAX_SAFE_INTEGER; guard the increment and test the boundary (origin: PR PrimeIntellect-ai#584).
- Finding 12: daemon children of in-memory parents skipped explicit depth persistence; always create the child header with explicit depth and test --no-session ancestry (origin: PR PrimeIntellect-ai#584).
- Finding 13: legacy completed subagents rehydrated at root depth; restore the depth-one fallback and test a registry/header pair without depth (origin: PR PrimeIntellect-ai#584).

* fix(coding-agent): make /rlm-max-depth persistence honest and unblock stale kernel gate

- /rlm-max-depth --global could claim persistence after deferred settings write failures; drain and surface global errors before reporting success (origin: PR PrimeIntellect-ai#585)
- /rlm-max-depth mutated live state before chat persistence and left failed entries indexed; persist first through rollback-safe custom-entry append, then mutate state and prompt (origin: PR PrimeIntellect-ai#585)
- invalid persisted global rlmMaxDepth could abort branch navigation after the leaf moved; ignore invalid global reads and fall through to env/default (origin: PR PrimeIntellect-ai#585)
- the kernel-side recursion pre-filter used stale one-shot RLM_MAX_DEPTH and blocked raises before the authoritative host gate; remove the duplicated Python gate (origin: PR PrimeIntellect-ai#585)

* fix(coding-agent): agents-view scope stability, crash-path backSession, summary refresh, pulse, and settings cycling

- Finding 18: stale saved-catalog readiness could destructively drop scope during refresh; reset readiness when refresh starts. origin: PR PrimeIntellect-ai#586
- Finding 19: resolved scope roots were lost across view remounts, swallowing early Left navigation; persist and restore the root summary. origin: PR PrimeIntellect-ai#586
- Finding 20: post-attach crashes left backSession pointing at the prior session; assign the opened summary before interactive mode runs. origin: PR PrimeIntellect-ai#586
- Findings 21 and 24: startup seeding could leave subagent counts stale and background subagents drove an unused render pulse; refresh every seed and pulse only while streaming. origin: PR PrimeIntellect-ai#587
- Finding 27: custom idle-eviction values cycled directly to off; include custom numeric values in the sorted cycle. origin: PR PrimeIntellect-ai#588

* fix(coding-agent): attach reservation vs passivation, binding join on retry, hydration env, settings error scoping, fractional eviction values

- reserve in-flight attaches and revalidate session liveness before attachment (origin: round-1 fix a342ca2)
- join concurrent child binding on the final passive resolution retry (origin: round-1 fix ae3ed45)
- adopt create-command client env before passive child hydration (origin: round-1 fix ae3ed45)
- isolate max-depth write errors while preserving project diagnostics (origin: round-1 fix 9e738f3)
- preserve fractional idle eviction values through settings cycling (origin: round-1 fix 721f45b; stack commit aa98c9a)

* fix(coding-agent): post-rebase hardening of passive hydration, snapshots, and depth ingestion

- preserve daemon routable IDs for passive children (origin: PR PrimeIntellect-ai#583)
- recheck guarded passive hydration and heartbeat restores (origin: PR PrimeIntellect-ai#583)
- repair wrong-kind pending hydration joins (origin: PR PrimeIntellect-ai#583)
- fence passive hydration during update restart preparation (origin: PR PrimeIntellect-ai#583)
- validate persisted RLM depth before constructor ingestion (origin: PR PrimeIntellect-ai#584)
- retry attach child snapshots across session replacement (origin: PR PrimeIntellect-ai#587)
- retain effective depth for legacy parented new sessions (origin: PR PrimeIntellect-ai#589)
- coordinate parent passivation with child hydration publication (origin: PR PrimeIntellect-ai#589)

* fix(coding-agent): leave shared passive hydration resident on guard cancellation

The ownership-blind close closed shared hydrations out from under concurrent wakes (both interleavings); the idle sweep is the ownership-free arbiter.

origin: round-4 fix b956400 / PR PrimeIntellect-ai#583

* fix(coding-agent): prefer persisted header depth for legacy rehydration entries

The legacy-entry rehydration fallback (entry.rlmDepth ?? 1) is passed as
config, which outranks the opened transcript header in AgentSession — so a
nested legacy child whose header carried a deeper persisted depth woke at
depth 1, weakening the host recursion gate. Registry depth stays
authoritative when present; otherwise the validated header depth wins and 1
remains the last-resort default for fully legacy children.

origin: PR PrimeIntellect-ai#584 fallback restored in round-1 triage; surfaced by post-rebase
bot review of PR PrimeIntellect-ai#589.

* fix(coding-agent): fence chain hydration against parent passivation; invalidate stale scope roots

* fix(coding-agent): bound the session snapshot stabilization loop

* fix(coding-agent): restore child event forwarder when passivation close fails

Passivation teardown invoked the retained child's event-forwarder
unsubscribe before closing the session. When the close failed and the
child was re-adopted, the forwarder was gone, so a still-resident child
stopped emitting rlm_child_update to its parent. Teardown now returns
the unsubscribe so the passivation path only invokes it after a
successful close and restores it on the failed-close re-adopt path.

* fix(coding-agent): close child passivation races

- Keep snapshot messages aligned with the final runtime session summary after stabilization exhaustion.
- Retry passive child hydration when the child starts passivating inside the hydration window.
- Apply archive and scheduled-job cancellation when kill joins a resume-preserving close.

* fix(coding-agent): upgrade cascading close reasons

- Track the applied close reason and resident descendant states through cascading teardown.
- Apply stronger joined close effects uniformly to parents and captured descendants.
- Cover shutdown-to-killed descendant cleanup and completed-to-killed idempotency.

* fix(coding-agent): preserve passive child id on hydration retry

- Forward the restored active-session ID when retrying after a mismatched pending open.
- Cover the pending-open race through passive-child hydration.

* fix(coding-agent): recover passivation waiters

- Treat failed passivation settlement as a join signal before retrying resident sessions.
- Cover concurrent open, message delivery, and hydration after passivation rejection.

* fix(coding-agent): harden passivation close races

- Preserve stronger close-reason upgrades when the joined close fails.
- Run child passivation outside the supervisor-wide eviction fence.
- Complete reason-upgrade persistence across targets and record the stronger reason before propagating errors.

* fix(coding-agent): preserve passive opener state across races

- Defer root parent client env adoption until passive hydration and its open guard succeed.
- Join opening or resident passive targets when parent-change restart resolution races hydration.
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