Repository navigation
feat(delegation): let a session hand tasks to child sessions - #653
jiro-by-nori[bot] wants to merge 6 commits into
Conversation
E1 terminal proofReal The sequence shows sequenceDiagram
participant U as User / TUI controller
participant P as Parent ACP session
participant M as Nori session manager
participant C as Child ACP session
participant W as Remote subscribers
alt User request
U->>M: /delegate agent task
else Agent request
P->>M: authenticated nori-client MCP delegate
end
M->>M: Check flag, process ownership, depth <= 2, capacity
opt Different agent kind
M-->>U: Child + parent identity; Start / Decline
U->>M: Resolve approval
end
M->>C: Start child and submit task
M-->>W: Hierarchy metadata + child envelopes
C-->>M: Permission request
M-->>U: Attributed waiting notice
U->>C: Alt+Down; answer in child
C-->>M: Prompt completes after descendants/continuations
M->>M: Retain history; release child process slot
M->>P: Queue attributed result
P-->>M: PromptResponse acknowledges delivery
Note over M,P: Parent crash holds/retries result on stable-ID resume
Note over M,C: Explicit parent close cancels descendants
1. User requests delegation2. Different agent kind requires Start or Decline3. Parent names the waiting child and its parent4. Alt+Down opens the child; permission is answered there5. Result returns and the parent continues automaticallyValidation: harness 454 passed / 1 ignored; TUI 1,487 passed / 4 ignored; affected CLI/host/config/protocol 358 passed. Full PTY ran with --no-fail-fast; after four failures were corrected, the three affected targets passed 24/24. Full workspace Clippy, formatting, and local cargo-deny passed. GitHub CI is tracked on this draft PR. |
|
Independent verification of e9ff623, base Built real Independent suite results
All three ran with Pass/fail matrix
For fresh/deferred navigation, a small transparent WebSocket fixture held only session-list requests. Delegation/event/permission traffic continued to the real host. Releasing the list demonstrated both timing cases deterministically. Attached observations · RPC ownership proof · Sanitized local wire sequence. Finding: should-fix — successful child teardown reports an error in the parentNormal successful delegation intermittently prints red Repro with this head and the built mock agent:
Observed in three independent flows: nested completion, cap reuse, and a child completing while the parent was streaming (captured before the intentional parent kill). Ten fresh nested follow-ups did not repeat it; this is intermittent, not a deterministic frequency claim. Positive captures are below. Lifecycle report. The wrong-session error route is explicit: Terminal evidenceGhostty Web 0.4.0 renders actual tmux capture output. DejaVu Sans Mono and both Noto symbol fonts were installed before capture. The trailing capture delimiter was removed before rendering to preserve the first row; PNGs were inspected against text. No fabricated terminal states. Full capture/text/metadata bundle: proof files. 1. Local and attached delegation: immediate, approve, declineLocal same-kind starts and returns without approval Local different-kind approval Local decline returns to parent Attached same-kind completion Attached cross-kind approval Attached decline 2. Attributed child permission, jump, and child-owned answerLocal parent notice names both sessions; no permission popup Alt+Down opens child permission Permission answered in child Attached parent notice Attached child permission answer 3. Grandchild success and third-level refusal; first false-error occurrenceNested result reaches root; spurious red error is the should-fix finding Clear third-level refusal 4. Automatic result arrives while parent draft stays intactUnsent draft preserved while result arrives 5. Parent crash, held result, queued-result crash, and isolated child failureParent Parent failed; child still waiting Held child result reaches same parent after Ctrl+R Completed result queued while parent is busy Queued result reaches resumed parent Child failed; parent responds to ROOT STILL USABLE 6. Explicit close, cap reuse, and retained history; second false-error occurrenceBefore Parent close shuts down entire descendant family Cap slot reused after completion; second spurious error Completed child history remains viewable 7. Deferred Alt+Down preserves draft in its parentList refresh released after typing; parent and draft retained 8. Fresh child navigation and fixed host-list columnsOne Alt+Down discovers and opens child before periodic refresh Real host ls: fixed columns, parent inside TITLE, ellipsized titles 9. D2 regressions and single-session flag-offCurrent row keeps its eight-character ID Same-port restart gives persistent explanation and keeps draft Flag off: delegation unavailable Flag off: normal prompts still work No blocker or separate nit was confirmed. Owned manual TUIs, host, and proxy were stopped after verification. Proof is on the separate |
|
Fixed the verifier's child-teardown diagnostic finding on Action failures retain their originating widget generation. Normal child shutdown suppresses only typed command/response transport closure; real ACP failures still render in their owning session. Completed-child replay also skips maintenance work when no live handle exists. History routing rechecks ownership, including after a session is removed, and preserves in-progress transcript ordering. flowchart TD
A[Action from session generation G] --> B{Action failed?}
B -->|Typed transport closure during normal teardown| C[No diagnostic]
B -->|Real failure| D[Failure tagged with G]
D --> E{Owner of G}
E -->|Visible or parked| F[Owner widget flushes active entry and queues error]
E -->|Activating candidate| H[Retain candidate failure]
E -->|Removed or replaced| I[Discard stale failure]
F --> J{Recheck G when history arrives}
J -->|Visible| K[Render in owning transcript]
J -->|Parked| L[Store in owning transcript]
J -->|Removed or replaced| I
Deterministic tests first reproduced the exact The capture below runs the real Nori TUI, session manager, HTTP MCP delegation, and three ACP subprocesses. Agent responses are synthetic. A child delegates to a grandchild, the nested result returns to the root, and the root answers a follow-up. Full terminal history contains neither the false channel-closed diagnostic nor a missing-handle diagnostic. Terminal text, ANSI, PNG, and metadata Validation on |
A child that crashed during a prompt sent its parent the Debug dump of the RequestFailure, with escaped newlines and the agent's stderr tail. Keep only the failure's first line, such as "Agent process exited unexpectedly (exit code 17)."; the stderr tail stays in the child's own history.



































Summary
🤖 Generated with Nori
Implements E1 delegation behind
multi_session, stacked on D2 (#652)./delegate <agent> <task>and the session-boundnori-clientMCPdelegatetool use one harness-owned admission and lifecycle flow. Same-kind children start immediately; different-kind children wait for Start/Decline. Delegation is limited to two levels below the root.Children are navigable local and attached sessions. A child permission stays in that child; Alt+Down opens the next waiting session. Notices identify child and parent. Results automatically enter the parent prompt queue, and a child that delegated waits for its descendants and continuation before completing. Completed children release process capacity while retaining history.
Explicit parent close cancels descendants. Parent process failure preserves children and holds results for stable-ID resume; result delivery is acknowledged by the parent's completed prompt. Forks preserve delegation depth and move ownership, approvals, and results to the current conversation.
Design
The Nori-owned tool uses the existing authenticated loopback HTTP MCP service. This gives agents a typed task request without changing ACP or introducing a second server. Its process-bound context supplies parent identity; callers cannot choose another session as parent. Both the remote controller API and TUI call the same manager. Watchers cannot mutate delegation state.
Admission and ownership changes are atomic under the manager lock; process startup, prompt submission, and shutdown run outside it. The session cap includes live children and in-progress launches. Remote lists/events carry hierarchy and delegation state;
nori host lskeeps metadata columns fixed and places hierarchy only in TITLE.Validation
--no-fail-fast. The known cloud auth-error case passed.e93deefdfdaddccfd9bf06ba92c9d9fb6f0498a4.The verifier's child-teardown diagnostic finding is fixed: action failures retain their originating session generation, normal shutdown suppresses typed transport closure, and real failures remain visible in their owning transcript. Deterministic tests reproduce the original replay-after-shutdown race and verify genuine visible failures, stale history rejection, and buffered message ordering.
Scope and remaining work
E2 owns polished delegation/result cards and tree presentation. Delegation state lasts for the current manager; host restart persistence is outside E1. Stdio-only custom agents can use user-driven
/delegate; an agent-tool fallback for those agents is deferred. Terminal proof uses the mock ACP agent.Draft only. Do not merge; base remains
feat/multi-session-d2-host.Originating chat: https://demo.norisessions.com/chat/01a1e00a-f59a-773a-8ebd-83da9f17ec64
Share Nori with your team: https://www.npmjs.com/package/nori-skillsets