Skip to content

feat(tui): show delegated child sessions clearly in the parent - #654

Draft
jiro-by-nori[bot] wants to merge 10 commits into
feat/multi-session-e1-delegationfrom
feat/multi-session-e2-delegation-tui
Draft

jiro-by-nori[bot] wants to merge 10 commits into
feat/multi-session-e1-delegationfrom
feat/multi-session-e2-delegation-tui

Conversation

@jiro-by-nori

@jiro-by-nori jiro-by-nori Bot commented Nov 15, 2026 •

Copy link
Copy Markdown
Contributor

Summary

🤖 Generated with Nori

Makes delegated child sessions easy to read in the TUI, behind [features] multi_session. Stacked on #653. Single-session use and flag-off behaviour are unchanged.

Surface What it shows now
Delegation in the parent transcript ↳ you delegated to mock-model-alt · Review the parser · working. One line names the child by its task, plus its agent and status. The full brief opens with the transcript key (Ctrl+T).
Cross-agent approval Uses the permission prompt's layout: a bold question, then asked by / runs on / task rows, and Yes, start it / No, decline. Esc declines.
Child waiting on you Request line ● parent task… › mock:request-pe… is waiting on you · approve: … · alt + down to jump with an amber ●. The parent's notice names the child and the parent by name. No pop-up.
Result Block ○ result from <agent> · <child> · ready, up to six result lines under a ▏ rail, then returns to <agent> on its own · its history: alt + s. The delivered result prompt collapses to one line; the transcript view keeps the full text the agent read.
Session tree nori host ls and the nori attach list put children under their parent, with ├─ └─ │ inside TITLE. ID, AGENT, STATUS and AGE stay fixed. Status words are coloured: waiting on you amber, working cyan, ready green, failed red.
Inside a child Breadcrumb mock-model · Parent › mock-model-alt · Child · alt + up to parent. New parent_session hotkey (Alt+Up by default) returns to the parent. Forks are excluded.
Names Raw ID fragments such as (parent 1a2b3c4d) are gone from rows, request lines, notices and approval prompts.

Design

  • One shared module builds the delegation text and cells for the local TUI and nori attach, so both frontends say the same thing.
  • On screen each delegation is compact. Details sit one key away in the transcript view, so several delegations stay readable together.
  • Delegation gains an additive origin field (agent | user, serde default agent), so a card can say "you delegated" or " delegated". Records from older hosts read as agent requests.
  • The result prompt the parent agent receives starts with [Nori delegation result] from <agent> · <child> · <outcome>, then Child session: <id>, then the text. The parent's own ID is dropped. Paragraph breaks are kept where tool calls or permission requests split the child's output. The header prefix is unchanged, so existing matching still works.
  • A new picker option, tree_column, places tree guides and the (current) badge in TITLE rather than the first column. tree_order orders (id, parent) rows depth-first; missing parents become roots, and cycles are safe.
flowchart LR
  P[Parent session] -- /delegate or MCP delegate --> M[Session manager]
  M -- DelegationChanged + origin --> C1[DelegationCell / approval_lines]
  C1 --> L[Local TUI transcript + prompt]
  C1 --> A[nori attach]
  M -- notice with names --> P
  M -- result prompt header --> P
  R[Session rows id,parent] --> T[tree_order + tree_guides in TITLE]
  T --> HL[nori host ls]
  T --> AL[attach list]
Loading

Validation

  • TUI: 1,514 passed, 2 ignored, including new snapshots for the cards, result block, ended states, both approval wordings, the delivered-result line, the attach tree, breadcrumb and result, and colour checks.
  • Harness, CLI, config, protocol, components: all pass. New checks cover origin attribution, readable notice and result text, result paragraph breaks, host ls tree order with fixed columns, narrow-width truncation, orphan parent ID, and ANSI colours.
  • PTY (--no-fail-fast, mock agent): the full suite passed on the first commit, and the known flaky cloud auth-error test also passed. After the review fixes I re-ran the delegation, session-list, host-attach and multi-session targets. The new scenario delegation_reads_clearly_from_request_to_result drives request → approval → waiting child → Alt+Down → breadcrumb → Alt+Up → result → tree, and passed 8 repeated runs in a row.
  • fmt and Clippy are clean on the changed crates. Linux CI and cargo-deny pass on 1a9d3761.
  • Terminal proof (Ghostty Web, 120×40 for every surface plus 80×30, and a GIF of request → result): feat(tui): show delegated child sessions clearly in the parent #654 (comment)

Known gaps

  • The queued-message hint ⌥↑ edit is a stale hint that predates this branch: nothing handles that key. In a child session Alt+Up now goes to the parent. I left the hint alone because removing it changes flag-off UI; it needs a separate decision.
  • The harness notice still names Alt+Down literally. The TUI request line shows the configured binding.

Draft. Do not merge.

Originating chat: https://demo.norisessions.com/chat/01a1e081-859a-7375-a670-d0f8fd38155e

Share Nori with your team: https://www.npmjs.com/package/nori-skillsets

jiro-by-nori Bot pushed a commit that referenced this pull request Nov 15, 2026
🤖 Generated with [Nori](https://noriagentic.com)

Co-Authored-By: Nori <contact@tilework.tech>
@jiro-by-nori

jiro-by-nori Bot commented Nov 15, 2026

Copy link
Copy Markdown
Contributor Author

Terminal proof: readable delegation in the TUI

These are captures of the real nori binary from this branch running mock ACP agents (mock_acp_agent) in isolated tmux sessions, rendered with Ghostty Web 0.4.0 after installing DejaVu Sans Mono and both Noto Sans Symbols fonts. Task texts such as mock:request-permission:write-report are the mock's control markers, so they appear as child names. The session manager, delegation, permission routing, navigation, result delivery, nori host and nori attach all run for real. No external service or production data is involved. Text versions (.txt) sit next to each PNG in the proof folder.

Delegation from request to result (GIF, 120×40)

delegation flow

1. Cross-agent approval: who asks, which agent runs, the task (120×40)

approval

2. Parent while the child waits: one-line card, readable notice, and a request line naming parent › child plus the Alt+Down hint (120×40)

waiting parent

3. Session list: child under its parent, amber "waiting on you" (120×40)

tree while waiting

4. Inside the child: breadcrumb back to the parent with the Alt+Up hint; the child's own permission prompt (120×40)

child breadcrumb

5. Result returns to the parent on its own: result block, then a one-line delivery marker (120×40)

result

6. Session list after completion (120×40)

session tree

7. nori host ls: two-level tree inside TITLE, fixed ID/AGENT/STATUS/AGE columns, coloured status (120×40)

The parent agent asked for both levels through the MCP delegate tool (root → child → grandchild waiting on a permission).

host ls

8. nori attach session list: the same tree, glyphs and (current) badge inside TITLE (120×40)

attach tree

9. nori attach inside the grandchild: breadcrumb with Alt+Up to the parent, fitted to the width (120×40)

attach breadcrumb

10. Narrow terminal (80×30): parent while the child waits, and the result

80x30 waiting
80x30 result

jiro-by-nori Bot pushed a commit that referenced this pull request Nov 15, 2026
🤖 Generated with [Nori](https://noriagentic.com)

Co-Authored-By: Nori <contact@tilework.tech>
@jiro-by-nori

jiro-by-nori Bot commented Nov 15, 2026

Copy link
Copy Markdown
Contributor Author

Verification of 1a9d376: readable delegation in the TUI

Tested end to end with the real nori binary from this branch and mock_acp_agent, using [features] multi_session = true unless noted. Captures come from isolated tmux sessions rendered with Ghostty Web 0.4.0, with DejaVu Sans Mono and Noto Sans Symbols 1 and 2 installed. Text versions (.txt) sit next to each PNG in the proof folder. Task texts such as mock:request-permission:… are the mock agent's control markers. Raw JSON lines in the transcripts are the mock echoing its MCP tool result, not product UI. I changed no product code and pushed nothing to this branch.

Verdict: no blockers. The core flow works (request → approval → waiting → jump → answer → result → tree), but there are 8 should-fix items. Most affect alignment or readable names, which this PR exists to deliver.

Test suites (PR head, --no-fail-fast)

Suite Result
nori-harness 454 passed, 1 ignored
nori-tui 1,514 passed, 4 ignored
nori-cli 71 passed
nori-config 174 passed
nori-tui-components 104 passed, 8 ignored
nori-protocol 0 tests in the crate (see nit 15)
tui-pty-e2e 199 passed, 1 failed, 9 ignored. The failure is the known flaky test_cloud_mode_surfaces_auth_error_from_child_stderr, which passed 3 of 3 re-runs. Not a regression.

Bugs

Should-fix

  1. nori host ls: a long agent name shifts STATUS, AGE and TITLE. AGENT is padded to 16 cells but never truncated (cli/src/host/table.rs, {agent:<16}). The attach list truncates the same row correctly (reviewer-long…).
    Repro: add a [[agents]] entry with slug reviewer-long-agent-name-x, run nori host and nori attach, type /new, then /delegate reviewer-long-agent-name-x Review the parser changes, approve, and run nori host ls in a 120-column TTY.
    19-host-ls-long-agent-120
  2. nori host ls at 80 columns drops TITLE, so the tree disappears. The fixed prefix is 82 cells, so every row takes the early truncate(&prefix) path. TITLE and its ├─ └─ guides are gone, AGE reads 1…, and the status colour is lost.
    Repro: in an 80-column terminal, run nori host ls with a parent, child and grandchild.
    17-host-ls-80
  3. A parent gets titled with the protocol header. When /delegate is the first input in a session, its first prompt is the delegation result. The session is then titled [Nori delegation result] from … in the local session list, the attach header and list, and host ls.
    Repro: start a fresh session, run /delegate mock-model inspect the parser, then press Alt+S.
    18-attach-list-long-agent
  4. A failed child's card shows a Rust Debug dump. It reads ✕ … failed · RequestFailure { request_id: Some(Str("…")), message: "Agent process exited…\nMock agent: …", kind: Fatal }, with literal \n escapes. The parent agent reads the same text. The cause is format!("{failure:?}") at harness/src/session_manager/delegation_state.rs:136 (from 4befa43 in feat(delegation): let a session hand tasks to child sessions #653), which this PR's new card now puts on screen. It should read like failed · agent exited (code 17).
    Repro: /delegate mock-model mock:exit-during-prompt.
    20-child-failure
  5. Alt+Down does nothing while the parent has a draft. The request line still says alt + down to jump, but next_waiting_session only fires when the composer is empty (tui/src/app/session_keys.rs, a gate added in 2b2c2ec). Nothing tells the user why. The draft itself is safe: it survives the jump through Alt+S and the result delivery, and it stays in the composer.
    Repro: while a child is waiting on you, type my draft in the parent and press Alt+Down. Nothing happens. Clear the composer and it jumps. Either jump with the draft parked, or hide or change the hint while a draft exists.
  6. Names are cut to a fixed length, not to the width. The REQUEST_LINE_PARENT_CHARS = 12 and REQUEST_LINE_CHILD_CHARS = 16 limits in tui/src/app/session_overview.rs cut names to that many characters at any width. At 120 columns the request line uses about 88 cells yet shows parent task… › mock:request-pe…. Sessions that share a title prefix become indistinguishable: the breadcrumb read mock:delegate mock-mode… › mock:delegate mock-mode… (parent and child).
    Repro: delegate from a session whose title shares its first 24 characters with the child's task, then open the child.
    02-waiting-parent
  7. The local breadcrumb is not width-aware. At 80 columns it wraps to two rows (… › mock-model-alt · / mock:request-permission… · alt + up to parent). The attached breadcrumb fits one row after ff21dab.
    Repro: in an 80×30 terminal, delegate to mock-model-alt with a permission marker, then press Alt+Down.
    24-local-breadcrumb-80
  8. The attached root gives no sign that a grandchild is waiting. With root → child → grandchild waiting, the root view in nori attach shows ready, no request line and no notice. In the attach list and host ls the root also reads ready, while the local list shows the family status waiting on you. Alt+Down still finds the grandchild.
    Repro: in nori attach, type /new, then mock:delegate mock-model mock:delegate mock-model mock:request-permission:x.
    14-attach-list-120

Nits

  1. A grandchild's breadcrumb shows only parent › current, not the full path from the root as in mock-up E-5c. 10-grandchild-breadcrumb
  2. AGENT names differ by surface. The local list shows display names (Mock ACP Alt), while cards, host ls and the attach list show slugs (mock-model-alt).
  3. One end state has three words: the result block says ready, the collapsed line says completed, and the local list says closed. The list also repeats closed as the row's description.
  4. A declined delegation still sends Child session: <uuid> to the parent agent for a session that never started.
  5. ID fragments remain for untitled sessions: the attach header shows mock-model · 24444c0e · ready before the first prompt, and the fallback session 1a2b3c4d is still in session_overview.rs.
  6. In a root session, Alt+Up (the new parent_session key) falls through to the composer and recalls the previous prompt. The stale ⌥↑ edit hint is already listed under Known gaps.
  7. nori-protocol has no tests, so the new delegation_result_prompt and delegation_child_name are covered only through harness and TUI tests, and "protocol: all pass" means nothing. The just test protocol scope still points at codex-protocol, which no longer exists.

Checks that passed

# Check Result
2 Flag off Prompt, /agent, /resume, the / menu and ? help screens match main (ae0642c) word for word, apart from the rotating placeholder hint. /delegate is unrecognised, and the hotkey picker hides parent_session.
3 Delegation card and brief ↳ you delegated to … and ↳ mock-model delegated to … both show. Ctrl+T shows the brief and child ID.
4 Approval Both wordings (user and agent) work. Enter starts the child, Esc declines (✕ … declined by you), and a same-agent child starts without asking.
5 Waiting child The request line names parent › child for a child and a grandchild, with no pop-up. Alt+Down jumps, the answer reaches the right session, and rebound alt+j / alt+k work and appear in the hints.
6 Result The result block names the child and points to its history (Alt+S opens it). The collapsed one-line prompt appears, and a typed draft survives delivery.
7 Session tree The local and attach lists stay aligned at 120 and 80 columns with 2 levels and long titles. Status colours are right in the lists (amber waiting, green ready, dim closed) and on cards (cyan working); no list row was in the working state during capture. Exceptions: should-fix 1, 2 and 8.
8 Breadcrumb Alt+Up returns to the parent, both locally and attached. The attached breadcrumb fits 80 columns.
10 False error from #653 (e93deef) No ACP agent command channel closed in any parent scrollback after normal child completion (3 sessions). A real child crash still shows as failed (wording: should-fix 4).
11 Regressions A crashed parent plus Ctrl+R keeps the same session ID and tree. /close on a parent with a live child and grandchild cancels both and all 3 agent processes exit. No non-zombie nori or mock_acp_agent processes remain after teardown.

Captures

Request → result, 120×40 (local; the first delegation was declined with Esc, the second approved):

flow

01-approval-user
08-approval-agent
03-brief-ctrl-t
04-child-breadcrumb
05-result
09-grandchild-waiting-root
11-local-list-2level
12-attach-grandchild-120
13-attach-grandchild-80
15-attach-list-80
16-host-ls-120
23-local-waiting-80
25-local-result-80
21-flagoff-agent-pr

@jiro-by-nori
jiro-by-nori Bot force-pushed the feat/multi-session-e2-delegation-tui branch from 1a9d376 to 847c02d Compare November 15, 2026 21:00
Delegations read as a one-line card naming the child by its task, agent
and status, with the brief in the transcript view. Results arrive as a
short block that names the child and points to its history; the
delivered prompt collapses to one line. The cross-agent prompt names who
asks, which agent runs, and the task. A waiting child's request line
names parent and child, children get a breadcrumb and an Alt+Up
parent_session key, and host ls plus the attach list show children under
their parent with tree glyphs inside TITLE and colored status words.

Delegations now record whether the user or the agent asked (origin), and
the harness names sessions readably in notices and result prompts.
…sion

🤖 Generated with [Nori](https://noriagentic.com)

Co-Authored-By: Nori <contact@tilework.tech>
Separate result paragraphs at tool calls and permission requests,
collapse the delivered result prompt in nori attach too, match it only
by its full header, keep the result rail on wrapped lines, limit the
breadcrumb and parent key to delegated children, and keep the parent ID
for orphaned children in piped host ls output.
🤖 Generated with [Nori](https://noriagentic.com)

Co-Authored-By: Nori <contact@tilework.tech>
On a terminal, ID, AGENT, STATUS and AGE shrink to a compact layout before
TITLE loses its space, so the tree glyphs, whole ages and status colors stay
at 80 columns. A long agent name is cut with an ellipsis instead of pushing
the later columns right. A top-level row shows its family's status, so a
waiting grandchild marks it as waiting on you. Piped output is unchanged.
- A child that finished its task ends as done; closed is left for sessions
  the user closed.
- A declined delegation tells the parent agent so without naming a session
  that never started.
- A session whose first input is /delegate is titled by that task, never by
  the result prompt it receives, and a result prompt never starts the
  first-prompt summary.
- The host session list carries each family's status for top-level rows.
- Untitled sessions are called "new session" instead of an ID fragment.
- just test protocol runs the nori-protocol crate, which now tests the
  result prompt it builds.
- The breadcrumb inside a delegated child shows the whole path from its
  top-level session, on one row at any width; sessions between the root
  and the current one collapse to … when names would get too short.
- The waiting-on-you line cuts names to the room the terminal has rather
  than to a fixed length, and nori attach shows it too, so a top-level
  session says when a grandchild waits.
- Alt+Down reaches a waiting session even with a draft, which stays in its
  session's prompt; Alt+Up outside a delegated child does nothing.
- Every surface names agents by the slug /delegate takes, a finished child
  reads done everywhere, and its list row keeps its last answer instead of
  repeating closed.
…s layouts

🤖 Generated with [Nori](https://noriagentic.com)

Co-Authored-By: Nori <contact@tilework.tech>
… across frontends

- Session path and waiting lines never exceed the terminal width, down to
  zero columns.
- A /delegate sent before any prompt titles the session from the session
  events, so the local list, nori attach and nori host ls agree.
- nori host ls clips plainly below its tightest layout.
- The local breadcrumb stops if a parent chain ever loops.
@jiro-by-nori
jiro-by-nori Bot force-pushed the feat/multi-session-e2-delegation-tui branch from 847c02d to 40837dc Compare November 15, 2026 21:47
jiro-by-nori Bot pushed a commit that referenced this pull request Nov 15, 2026
🤖 Generated with [Nori](https://noriagentic.com)

Co-Authored-By: Nori <contact@tilework.tech>
@jiro-by-nori

jiro-by-nori Bot commented Nov 15, 2026

Copy link
Copy Markdown
Contributor Author

Review fixes for the verifier's findings (#6901036688)

All 8 should-fix items and nits 9–15 are fixed. New heads:

Linux checks and cargo-deny pass on both heads.

# Fix Regression test
1 host ls cuts AGENT to its column with … host::table long-agent test at 120 and 80
2 host ls layouts: wide when TITLE keeps 24 cells, else compact (8/14/16/5, same as attach), else tight. TITLE with its tree glyphs, whole AGE and colours stay at 80 80-column test, narrow-width test
3 A parent is titled by its own /delegate task, never by [Nori delegation result]. Same rule in the host journal and the TUI preview harness, preview, PTY
4 A failed child shows one plain line, e.g. Agent process exited unexpectedly (exit code 17). (fixed in E1) harness child_crash_returns_failure…
5 Alt+Down jumps even with a draft, and the draft stays in the parent's prompt PTY
6 Names are cut to the terminal width, not 12/16 characters session_path snapshots, PTY at 130 columns
7 The local breadcrumb fits one row at 80 PTY at 80×30
8 Attach and host ls show a top-level session's family status, and attach shows a ● … is waiting on you line harness family_status, attach, table
9 The breadcrumb shows the path from the root; the middle collapses to … when it doesn't fit session_path, attach
10 Agent slugs on every surface, including the local list PTY snapshots
11 A finished child is done everywhere; closed only for sessions the user closed; no repeated closed description harness Done, chatwidget and PTY snapshots
12 A declined delegation tells the parent agent with no session ID protocol and harness
13 Untitled sessions are new session, not an ID fragment protocol, attach
14 Alt+Up in a top-level session does nothing (no history recall) PTY
15 just test protocol runs nori-protocol, which now has 4 tests just test protocol

Tests at 40837dcd (--no-fail-fast):

Suite Result
nori-tui 1,526 passed, 4 ignored
nori-harness 457 passed, 1 ignored
nori-cli 74 passed
nori-config 174 passed
nori-tui-components 104 passed, 8 ignored
nori-protocol 4 passed
tui-pty-e2e 203 passed, 9 ignored, 1 failed: the known flaky test_cloud_mode_surfaces_auth_error_from_child_stderr, which passed 2 of 3 reruns. The previous head passed all 204

Behaviour changes worth a look:

  • New wire status done. An older nori attach cannot read a list from a newer host, since host and attach ship in one binary.
  • done is kept in memory only: a child reloaded from its transcript after a host restart reads closed.
  • When space is short, the waiting line keeps names and drops the request text.

Before / after

Captures are full colour (Ghostty Web 0.4.0), with the mock agent and the same inputs on both binaries. Text versions sit next to each PNG: proof folder.

The Delegation continuation received: … lines and raw JSON in transcripts are the mock agent echoing its input, not Nori UI.

1 · host ls with a long agent name, 120×40

Before (1a9d3761) After (40837dcd)
before item1-hostls-long-agent-120x40 after item1-hostls-long-agent-120x40

1 · host ls with a long agent name, 80×30

Before (1a9d3761) After (40837dcd)
before item1-hostls-long-agent-80x30 after item1-hostls-long-agent-80x30

2/8 · host ls, root → child → grandchild waiting, 120×40

Before (1a9d3761) After (40837dcd)
before item2-hostls-tree-120x40 after item2-hostls-tree-120x40

2/8 · host ls, same family, 80×30

Before (1a9d3761) After (40837dcd)
before item2-hostls-tree-80x30 after item2-hostls-tree-80x30

4 · failed child card, 120×40

Before (1a9d3761) After (40837dcd)
before item4-failed-child-120x40 after item4-failed-child-120x40

4 · failed child card, 80×30

Before (1a9d3761) After (40837dcd)
before item4-failed-child-80x30 after item4-failed-child-80x30

6 · parent's waiting line, 120×40

Before (1a9d3761) After (40837dcd)
before item6-waiting-line-120x40 after item6-waiting-line-120x40

6 · parent's waiting line, 80×30

Before (1a9d3761) After (40837dcd)
before item6-waiting-line-80x30 after item6-waiting-line-80x30

7 · local child breadcrumb, 120×40

Before (1a9d3761) After (40837dcd)
before item7-local-breadcrumb-120x40 after item7-local-breadcrumb-120x40

7 · local child breadcrumb, 80×30 (before wraps to two rows)

Before (1a9d3761) After (40837dcd)
before item7-local-breadcrumb-80x30 after item7-local-breadcrumb-80x30

8 · nori attach, root view while the grandchild waits, 120×40

Before (1a9d3761) After (40837dcd)
before item8-view-attach-root-waiting-120x40 after item8-view-attach-root-waiting-120x40

8 · nori attach, root view, 80×30

Before (1a9d3761) After (40837dcd)
before item8-view-attach-root-waiting-80x30 after item8-view-attach-root-waiting-80x30

8 · nori attach list, 120×40

Before (1a9d3761) After (40837dcd)
before item8-list-attach-root-waiting-120x40 after item8-list-attach-root-waiting-120x40

8 · nori attach list, 80×30

Before (1a9d3761) After (40837dcd)
before item8-list-attach-root-waiting-80x30 after item8-list-attach-root-waiting-80x30

9 · grandchild breadcrumb in nori attach, 120×40 (three 40-character names: the middle collapses)

Before (1a9d3761) After (40837dcd)
before item9-grandchild-breadcrumb-120x40 after item9-grandchild-breadcrumb-120x40

9 · grandchild breadcrumb, 80×30

Before (1a9d3761) After (40837dcd)
before item9-grandchild-breadcrumb-80x30 after item9-grandchild-breadcrumb-80x30

11 · session list after a finished delegation, 120×40

Before (1a9d3761) After (40837dcd)
before item11-done-120x40 after item11-done-120x40

11 · session list, 80×30

Before (1a9d3761) After (40837dcd)
before item11-done-80x30 after item11-done-80x30

11 · result block and delivered line, 120×40

Before (1a9d3761) After (40837dcd)
before item11-transcript-120x40 after item11-transcript-120x40

11 · result block and delivered line, 80×30

Before (1a9d3761) After (40837dcd)
before item11-transcript-80x30 after item11-transcript-80x30

jiro-by-nori Bot pushed a commit that referenced this pull request Nov 15, 2026
🤖 Generated with [Nori](https://noriagentic.com)

Co-Authored-By: Nori <contact@tilework.tech>
@jiro-by-nori

jiro-by-nori Bot commented Nov 15, 2026

Copy link
Copy Markdown
Contributor Author

Re-verification of review fixes at 40837dc (base #653 at e61d10e)

I tested with the real nori debug binary and mock_acp_agent, using [features] multi_session = true unless noted. I drove the local TUI, nori host, nori host ls and nori attach in isolated tmux at 120×40 and 80×30. Captures are full-colour Ghostty Web 0.4.0 renders with DejaVu Sans Mono and Noto Sans Symbols 1 and 2. A .txt sits next to each PNG in the proof folder. Task texts such as mock:request-permission:… are mock-agent control markers, and the raw JSON and Delegation continuation received: … lines are the mock echoing its input, not Nori UI. The mock only offers the agent-side delegate tool when MOCK_AGENT_MCP_HTTP=1 is set on the host. I changed no product code and pushed nothing to the PR branches.

Verdict: no blockers. 14 of the 15 fixes hold. Fix 5 holds in the local TUI but not in nori attach (should-fix A). The "reloaded child reads closed" claim cannot be reached from any user path (nit B).

Test suites (40837dc, --no-fail-fast)

Suite Result
nori-harness 454 passed, 3 failed, 1 ignored. A full rerun gave 456 passed, 1 failed. Every failure is in tests/remote_host.rs (see "Not from this PR").
nori-tui 1,526 passed, 4 ignored
tui-pty-e2e 204 passed, 9 ignored, 0 failed. The known flaky cloud-mode test passed this time.
nori-protocol (just test protocol) 4 passed

Findings

Should-fix

A. nori attach: Alt+Down still does nothing while the composer has a draft. The local TUI now jumps and keeps the draft, but attach still requires an empty composer (tui/src/attach/input.rs:26). The root's line still says alt+down to jump, and nothing tells the user why the key did nothing.
Repro: nori host, then nori attach, then /new, then mock:delegate mock-model mock:delegate mock-model mock:request-permission:x. When the root shows ● … is waiting on you, type my draft and press Alt+Down. Nothing happens. Clear the composer and Alt+Down jumps to the grandchild.
fix5-attach-draft-altdown-120

Nits

B. A child reloaded after a host restart never reads closed anywhere. harness/docs.md (around line 688) and the fix report say it reads closed, and no test covers this. What actually happens: after nori host stop and a new nori host, host ls and the attach list are empty, because the host has no snapshot. Reopening the finished child with /resume makes it a live, top-level ready session with its parent link gone. Either correct the doc or add a test for the path you meant.
Repro: finish a delegation under nori host, run nori host stop then nori host, then nori host ls. Then in nori run /resume, pick the child, and press Alt+S.
restart-resumed-child-local-list-120

C. Sessions that share a long title prefix still look the same at 120 columns (fix 6). Names now use the width, but they are cut only at the tail. A parent and child that share 37 characters read shared prefix for the parser r… › shared prefix for the parser…. A 24-character shared prefix, as in the original repro, now fits. Cutting in the middle, or keeping the end of each name, would separate longer prefixes too.
Repro: in nori, run /new, then send shared prefix for the parser review: parent side, then /delegate mock-model-alt shared prefix for the parser review: child side mock:request-permission:z and approve it.
fix6-shared-prefix-waiting-120

D. At 80 columns the attached grandchild breadcrumb shrinks its own name before the key hint. It reads mock-model · mock:d… › … › mock-model · mock:… · waiting on you · alt+up parent. The current session's name should be the last thing to shrink. Drop alt+up parent first.
fix9-attach-grandchild-80

E. At 80 columns the collapsed › delegation result from … line still wraps to two rows. The child name in it is cut at a fixed length (review-the-lexe…), and the protocol header the parent agent receives carries the same cut name.
Repro: at 80×30, approve /delegate mock-model-alt mock:request-permission:review-the-lexer-tokens, answer the request, then press Alt+Up.
nit-collapsed-result-wraps-80

F. The ↳ … delegated to … · working card still says working after the child is done, locally and attached. Each state change is a new cell by design, so this is a wording problem. started would not go stale.

G. Small done inconsistencies.

  • The attached root header reads · ready while the attach list and host ls show the family status waiting on you.
  • done and closed are both dim in host ls and the attach list.
  • A finished child's view ends with Session ended. Use /new to start another session., which reads like a user close.

Fixes 1–15

# Result Evidence
1 ✅ reviewer-long-a… at 120 and reviewer-long… at 80; columns stay put fix1-hostls-long-120/80
2 ✅ 80 columns keeps TITLE with └─ guides, the whole AGE and the colours fix2-hostls-tree-80
3 ✅ A parent whose first input is /delegate is titled by its task in the local list, the attach header, the attach list and host ls fix3-fix11-local-list-120, fix1-hostls-long-120
4 ✅ ✕ … failed · Agent process exited unexpectedly (exit code 17). The parent agent gets the same line fix4-local-failed-80
5 ⚠️ Works locally, and the draft survives the jump and the result delivery. Attach still blocks it (A) fix5-fix7-local-child-120, fix5-attach-draft-altdown-120
6 ✅ with nit C fix6-*
7 ✅ The local child breadcrumb fits one row at 80 fix7-local-child-80
8 ✅ The attached root shows ● … › … is waiting on you · alt+down to jump; the attach list and host ls show the root as waiting on you at 120 and 80 fix8-*
9 ✅ The path runs from the root, and the middle collapses to … (nit D) fix9-*
10 ✅ Slugs (mock-model, mock-model-alt) in the local list, cards, attach and host ls fix3-fix11-local-list-120
11 ✅ done everywhere for a finished child, with no repeated closed description fix3-fix11-local-list-120, done-*
12 ✅ A declined delegation sends The user declined this delegation. with no Child session: line fix12-local-declined-120
13 ✅ The attach header reads mock-model · new session · ready before the first prompt (text check)
14 ✅ Alt+Up in a top-level session does nothing, and plain Up still recalls history (text check)
15 ✅ just test protocol runs nori-protocol: 4 passed test log

Other checks

Check Result
done in host ls and the attach list ✅ The child and grandchild read done; the root reads ready once the family finishes
Flag off (multi_session = false) ✅ I ran the same inputs (start, prompt, / menu, ? help, /agent, /delegate, Alt+Up) through main (ae0642c) and this head. The text diff is only the rotating placeholder hint. /delegate is unrecognised, and Alt+Up changes nothing. Texts: flagoff-main/, flagoff-pr/
Leftover processes ✅ No live nori or mock_acp_agent after local TUI exit, two nori host stops, or the suites. 201 zombie entries remain, all reparented to Modal's non-reaping PID 1

Not from this PR

Three cancel-timing tests in harness/tests/remote_host.rs fail most of the time on this machine even when run alone, with Elapsed(()) at lines 855, 924 and 991:

  • remote_cancel_still_cancels_a_remote_owned_turn
  • immediate_remote_cancel_waits_for_remote_turn_registration
  • dropped_prompt_registration_does_not_wedge_a_reconnected_controller

At this head, the test file failed 2 of 3 runs. At E1 e61d10ec it failed 4 of 5, so the problem predates this PR. That is far more often than the "failed once under load" noted earlier. It should get its own fix in the stack, not in this PR.

Captures

fix8-attach-root-120
fix8-attach-root-80
fix8-attach-list-80
fix2-hostls-tree-120
fix2-hostls-tree-80
fix1-hostls-long-120
fix1-hostls-long-80
fix9-attach-grandchild-120
fix7-local-child-80
fix4-local-failed-80
fix3-fix11-local-list-120
fix12-local-declined-120
done-attach-list-120
done-attach-root-result-120

This branch has not been deployed

No deployments
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.

1 participant