17 KiB
Created
Created by LocalTicketBackend create.
Plan
Created from investigation of perceived delays when opening yoi panel, attaching to a Pod, and returning from an attached Pod.
Root cause recorded:
- the panel waits for full snapshot/Orchestrator work before first draw;
- attach waits for socket connect or restore/spawn before a visible transition;
- return from nested Pod awaits
app.reload_or_notice().awaitbefore showing the panel again.
Desired direction:
- show the panel/progress state first;
- move reload/connect/ensure work into background or explicit progress states where practical;
- especially make return-from-attach redraw the previous panel immediately and refresh in the background.
Intake summary
Existing Ticket refined sufficiently for routing. Request is to make yoi panel transition paths non-blocking: return from nested Pod should redraw the previous panel immediately and refresh in background; Pod open/attach should show attaching/restoring progress before socket/restore waits; initial panel load should avoid blocking first draw on non-essential snapshot/Orchestrator observation where practical. Acceptance criteria and non-goals are already explicit. Readiness: implementation_ready. needs_preflight: true because this touches async TUI lifecycle, background reload guarding, Pod attach/restore UX, and Orchestrator observation timing while preserving Ticket workflow and Pod authority semantics. risk_flags: [tui-lifecycle, async-reload, pod-attach, orchestrator-observation].
State changed
Intake found the existing Ticket specific enough for Orchestrator routing. No duplicate Ticket was created; implementation must still preserve Ticket workflow semantics and Pod restore/spawn authority.
Decision
Scope clarification requested by user:
Panel-originated Pod launch/restore/open dispatch is explicitly in scope for this Ticket when the issue is visible blocking before feedback. Pressing the panel action to launch, restore, open, or attach a Pod should enter a visible progress/transition state such as launching, restoring, or attaching before awaiting runtime socket connect, restore, or spawn work.
This clarification is about non-blocking UX and progress/error surfacing for the dispatch path. It does not expand the Ticket to redesign role launch policy, Ticket workflow semantics, Orchestrator scheduling, Pod authority, or automatic coder/reviewer startup.
State changed
Ticket queued for Orchestrator routing.
Decision
Routing decision: preflight_needed
Reason:
- The Ticket is specific and valuable, but it touches async TUI lifecycle boundaries: panel first draw, nested Pod return, background reload guarding, Pod attach/restore/spawn progress, and Orchestrator observation timing.
- Intake explicitly marked readiness as implementation-ready only with
needs_preflight: trueand risk flags[tui-lifecycle, async-reload, pod-attach, orchestrator-observation]in the intake summary. - Several implementation choices can preserve or violate important invariants: no duplicate overlapping reload tasks, no dropped key input during progress states, no Ticket workflow semantic changes, and no Pod restore/spawn authority changes.
Evidence checked:
- Ticket body requirements, non-goals, acceptance criteria, and problem paths.
- Thread plan, intake summary, user scope clarification for panel-originated launch/restore/open dispatch, and
ready -> queuedevent. - Workspace state:
developis clean except this Ticket's queued item/thread updates; no existing worktree or branch for this slug. - Visible Pods: intake peer for this Ticket is idle; no implementation/review Pods are active for this Ticket.
Next action:
- Run
ticket-preflight-workflowbefore implementation delegation. - Preflight should produce a concise design/authority note covering: which transition paths become background/progress states first, how
PendingReloador equivalent prevents overlap, how selection/composer/input are preserved, what remains synchronous for correctness, and focused test strategy. - Do not transition
queued -> inprogress, create.worktree/workspace-panel-nonblocking-transitions, or spawn coder/reviewer Pods until preflight records that the Ticket is implementation-ready.
Escalate if:
- Making initial panel first draw non-blocking requires a broader TUI runtime-loop rewrite.
- Pod launch/restore progress state would require changing spawn/restore authority semantics.
- Background reload cancellation/ordering needs a new durable scheduler or lease concept rather than a local UI guard.
Intake summary
Existing Ticket is already sufficiently clarified for routing. Scope covers non-blocking yoi panel transition UX: immediate redraw on nested-Pod return with background refresh, visible progress before panel-originated Pod launch/restore/open/attach waits, and practical reduction of first-draw blocking while preserving Ticket workflow semantics, Pod restore/spawn authority, input handling, and reload correctness. Readiness: implementation_ready. needs_preflight: true. risk_flags: [tui-lifecycle, async-reload, pod-attach, orchestrator-observation].
State changed
Intake reconfirmed the existing Ticket as ready for Orchestrator routing. No duplicate Ticket was created. Prior thread context already records the queued attempt and Orchestrator preflight-needed decision; implementation must not start from Intake.
State changed
Ticket queued for Orchestrator routing.
Decision
Routing decision: preflight_needed
Reason:
- This Ticket is still queued for routing, but the recorded scope touches async TUI lifecycle, background reload ordering/guarding, Pod launch/restore/attach progress states, and Orchestrator observation timing.
- The thread explicitly records
needs_preflight: truerisk context and an earlier Orchestrator decision that preflight must cover transition paths, reload overlap prevention, input/selection preservation, synchronous correctness boundaries, and test strategy. - No subsequent preflight decision or design note is present that converts those risks into binding implementation invariants.
- Current workspace state also contains unrelated dirty/untracked Ticket records, so implementation side effects should not start from this routing pass.
Evidence checked:
- Ticket body: background, requirements, non-goals, and acceptance criteria.
- Thread: intake summaries, user scope clarification, prior
preflight_neededrouting decision, and latestready -> queuedevent. - Workspace state:
develophas modified Ticket files for this queued Ticket plus unrelated untracked Ticket records; no matching worktree or branch exists for this slug. - Visible Pods: only the Intake peer for this Ticket and this Orchestrator are live; no coder/reviewer implementation Pods are active.
Next action:
- Run
ticket-preflight-workflowand record the concise preflight/design note before implementation delegation. - Leave this Ticket queued for now; do not transition
queued -> inprogress, create.worktree/workspace-panel-nonblocking-transitions, or spawn coder/reviewer Pods until preflight records that implementation may proceed.
Escalate if:
- The non-blocking first-draw or attach-return path requires a broad TUI runtime-loop rewrite.
- Pod launch/restore progress states would require changing spawn/restore authority semantics.
- Background reload ordering requires a durable scheduler/lease rather than a local UI guard.
Decision
Binding decision: non-blocking transition scope
This Ticket should implement non-blocking UX for three panel-local wait points:
-
Process/Pod transition waits
- Panel-originated Pod spawn / restore / attach / open should show a visible progress state before awaiting runtime socket connect, restore, or spawn completion.
- Example states:
launching,restoring,attaching.
-
Composer submit/send confirmation waits
- Companion send, existing Ticket clarify/intake launch, and Ticket action dispatch should give immediate visible feedback that submit/dispatch started.
- On busy/rejected/failed send, preserve the draft where appropriate and surface a bounded diagnostic.
- On success, clear/update only according to the existing submit semantics.
-
Initial panel first draw
yoi panelshould show an initial/loading/minimal panel before non-essential full snapshot, Orchestrator ensure/observe, or slow local runtime checks complete where practical.- Background completion should update the panel state/diagnostics once ready.
Implementation boundaries:
- Reuse or extend existing local pending-task guards such as
PendingReloadwhere practical. - Prevent duplicate overlapping reload/transition tasks.
- Preserve selected row and composer draft across background refreshes unless the submitted operation succeeds and intentionally clears the draft.
- Keep enough synchronous checks to avoid presenting actions that would immediately violate known local state invariants.
Non-goals are limited to adjacent changes that could naturally be mixed into this work:
- Do not change Pod spawn/restore/attach authority, identity, or metadata semantics.
- Do not change Ticket workflow-state/action semantics.
- Do not introduce a durable scheduler/lease/background-job system.
- Do not rewrite the entire TUI runtime loop.
Everything else should not be listed as a non-goal unless the implementation discovers it is an actual adjacent risk. Unrelated exclusions add noise and should be avoided.
Decision
Routing decision: implementation_ready
Reason:
- The new human binding decision supplies the missing preflight boundary for the previously recorded
preflight_neededrouting decision. - The implementation scope is now fixed to three panel-local wait points: process/Pod transition waits, composer submit/send confirmation waits, and practical initial panel first-draw work.
- Binding boundaries explicitly preserve Pod spawn/restore/attach authority, identity, metadata semantics, Ticket workflow-state/action semantics, local-only pending guards, input/selection/draft preservation, and no durable scheduler/runtime-loop rewrite.
- Remaining uncertainty is bounded TUI implementation investigation: exact local progress-state representation,
PendingReloadextension points, and test seams.
Evidence checked:
- Ticket body requirements and acceptance criteria.
- Thread decisions, including the latest
Binding decision: non-blocking transition scope. - Code map search for
PendingReload,reload_or_notice,prepare_open,finish_open,load_multi_pod_snapshot,OrchestratorLifecycleMode,run_pod_name_nested, composer submit paths, and existing progress strings. - Workspace state: no branch/worktree exists for this Ticket; unrelated dirty Ticket records exist in the main workspace, but the user explicitly asked to proceed if ready and this work will be isolated in a child worktree.
- Active work:
remove-non-goals-from-workflow-templatesis in separate worktree/review and touches workflow/docs/client role text, not the panel TUI implementation paths for this Ticket. - Ticket doctor: 0 errors; existing warnings are unrelated legacy closed-Ticket diagnostics.
IntentPacket:
Intent:
- Make
yoi paneltransitions feel immediate by showing the next panel/progress state before slow local/runtime work completes, while preserving the existing authority and workflow semantics.
Binding decisions / invariants:
- Scope is limited to three panel-local wait points:
- Panel-originated Pod spawn / restore / attach / open should show visible
launching/restoring/attachingstyle progress before awaiting runtime socket connect, restore, or spawn completion. - Companion send, existing Ticket clarify/intake launch, and Ticket action dispatch should give immediate visible feedback that submit/dispatch started.
- Initial
yoi panelshould show an initial/loading/minimal panel before non-essential full snapshot, Orchestrator ensure/observe, or slow local runtime checks complete where practical.
- Panel-originated Pod spawn / restore / attach / open should show visible
- Preserve Pod spawn/restore/attach authority, identity, and metadata semantics.
- Preserve Ticket workflow-state/action semantics and role-launch policy.
- Do not introduce a durable scheduler, lease, or background-job system.
- Do not rewrite the entire TUI runtime loop or replace the single-Pod TUI.
- Reuse or extend local pending-task guards such as
PendingReloadwhere practical. - Prevent duplicate overlapping reload/transition tasks.
- Preserve selected row and composer draft across background refreshes unless the submitted operation succeeds and intentionally clears the draft.
- Keep enough synchronous checks to avoid presenting actions that would immediately violate known local state invariants.
Requirements / acceptance criteria:
- Returning from nested Pod should redraw the previous panel immediately with a concise refreshing notice, then perform snapshot reload in the background.
- Avoid awaiting
app.reload_or_notice().awaiton the attach-return path before the panel is visible. - Opening/attaching/restoring/launching a Pod from the panel should visibly enter a progress state before slow socket/restore/spawn waits.
- Composer submit/dispatch paths should show immediate sending/launching/dispatching feedback and preserve drafts on busy/rejected/failed sends where existing semantics require it.
- Initial panel open should avoid blocking first draw on non-essential snapshot/Orchestrator work where practical, using a minimal/loading state or equivalent.
- Background completion must update Pod state, Ticket rows, Orchestrator state, diagnostics, selection, and composer target consistently.
- Preserve no-Ticket Pod-centric behavior.
- Tests should cover non-blocking return/reload and practical progress-state behavior.
Implementation latitude:
- Coder may choose the exact local state names/types, whether to extend
PendingReloador introduce adjacent local guards, and which paths can safely remain synchronous. - Coder may split implementation if initial first-draw requires a smaller practical subset, but must report any acceptance criterion not fully achieved.
- Coder may add focused unit tests around app state transitions rather than full E2E.
Escalate if:
- Initial first draw cannot be improved without a broad TUI runtime-loop rewrite.
- Progress states require changing Pod spawn/restore/attach authority or metadata semantics.
- Background reload ordering requires durable scheduler/lease semantics rather than local UI guards.
- The implementation would drop composer text/selection unexpectedly or allow duplicate overlapping reloads.
Validation:
- Focused TUI tests for
multi_pod/ workspace panel transition behavior. - Existing no-Ticket and Ticket-enabled panel tests.
cargo test -q -p tui multi_or more focused equivalent selected by coder.cargo test -q -p tui workspace_panel.cargo fmt --check.git diff --check.cargo run -q -p yoi -- ticket doctor.- Because TUI/runtime behavior is touched, final validation should include
nix build .#yoibefore merge-completion unless explicitly waived.
Current code map:
crates/tui/src/multi_pod.rs:PendingReload,run_multi_pod_tui,MultiPodApp::load,reload_or_notice,prepare_open,finish_open,load_multi_pod_snapshot,OrchestratorLifecycleMode, composer submit/action handling, existing tests.crates/tui/src/spawn.rs: nested Pod open/connect/restore path and existingattachingstrings.crates/tui/src/workspace_panel.rs: panel model/action/progress/status rendering.crates/tui/src/lib.rsandcrates/tui/src/single_pod.rs: nested single-Pod return boundary as needed.
Critical risks / reviewer focus:
- Return-from-nested-Pod path must not block on snapshot reload before drawing the panel.
- Progress states must not imply authority changes or successful launch/restore before acceptance/evidence exists.
- Duplicate reload/transition tasks must be guarded.
- Selection/composer draft must survive background refresh unless success semantics intentionally clear it.
- Initial first draw should improve only where practical without a large runtime-loop rewrite.
State changed
Accepted queued implementation after human preflight supplementation and routing IntentPacket were recorded. This acceptance precedes worktree creation and coder/reviewer Pod spawning.