Skip to content

Fleet Studio: owner-routed open of a peer session + retire orphaned dropdown helpers (B2a, from #1525) #1537

Description

@jeonghun-jj-lee

Important

Problem — After B1 (#1536), a peer's sessions appear in the titlebar Sessions dropdown, badged and searchable — but clicking one is a dead end: the openSession guard intentionally short-circuits to a "lives on " toast instead of navigating, because opening a remote session was never wired. JJ can see his Mac Studio's "Free port 4096" session but cannot open it.
Approach — Wire the dropdown's openSession for a remote (peer-owned) row to route through the owner via the existing multiplex/attach path, landing in the normal session view, instead of the B1 guard toast. This is a read path — it opens and views a peer session; it adds no mutation surface. Alongside, retire the orphaned filterSessionsByMachine / deriveBadge helpers that live only in the test file into a real shared module the component and the test both import.
Scope — in: owner-routed open of a peer session (AC4 of #1525); promote orphaned dropdown helpers into a real module (AC6 of #1525). out: remote prompt / archive / delete (AC5 — the remote-write surface); the evaluateRemoteWriteGate confirm wiring and its UX (deferred to B2b, pending design sign-off).
Assumptions — the B1 projection fetch/merge/badge plumbing in SessionChatsDropdown is merged and correct (PR #1536, merged 2026-09-24 13:32Z); the owner-routing seam B1 already guards against (SessionMultiplexProxy.resolve routes reads by owner) is the open path; opening is authorized at the API boundary by the reader token already on file (proven live: GET /session → 200 through the forward).

Acceptance Criteria

  • Opening a peer (remote, is_local === false) session from the dropdown routes to the owner and lands in the session view — no bogus local navigate, no 404, no B1 guard toast.
  • Opening a local session from the dropdown is byte-unchanged from today (no regression).
  • When the projection is unavailable (404/empty), the dropdown behaves exactly as B1's degrade-to-local (peer rows simply absent; no throw).
  • The dropdown's machine helpers (filterSessionsByMachine / deriveBadge, and any B1 merge helper still duplicated) live in ONE real module imported by BOTH the component and its test — no test-only re-implementation remains.
  • No remote-write path is added: prompt / archive / delete of a peer row remain disabled or absent exactly as B1 left them.

Testing Decisions

Extend the existing session-component unit suite that B1 added (session-fleet-peers module tests + the SessionChatsDropdown component tests) — reuse-first. Add cases for: remote-row open dispatches the owner-routed navigate; local-row open unchanged; the promoted helper module is the single source (delete the orphaned copies in session-chats-dropdown.test.ts and import the real module — AC6 is proven by the test file no longer defining them). No new suite; this is the same surface B1 touched.

Key Decisions

  • Open = read, and the multiplex already routes reads by owner; B2a reuses that seam rather than inventing a new transport. The B1 guard becomes a real navigate for remote rows.
  • AC6 (helper retirement) rides with B2a because it is pure cleanup of the same dropdown subtree and touches no mutation surface — it does not belong in the design-gated B2b.
  • The remote-write confirm gate (evaluateRemoteWriteGate) is explicitly not wired here; B2a must not create a live caller for it.

Constraints & Invariants

  • Flag-OFF / no-projection behavior is byte-identical to B1's degrade-to-local — the peer-merge already ships behind the fleet posture; B2a adds no new default-on behavior.
  • No new mutation surface. A reviewer must be able to confirm B2a cannot delete, archive, or prompt a remote session.
  • Local-session behavior unchanged (open, badge, search all as B1 left them).

Prior Art

  • The B1 pure module and the dropdown wiring it landed (session-fleet-peers + SessionChatsDropdown in the session-header subtree) — read these first; B2a extends them.
  • The owner-routed multiplex seam (SessionMultiplexProxy.resolve, method-agnostic owner routing) — the open path.
  • The orphaned helpers in session-chats-dropdown.test.ts — the AC6 target.

Source

Notes

Carved from #1525 per the B2 split decision (2026-09-24): #1525 keeps AC5 (remote prompt/archive/delete behind the confirm gate) as the design-gated B2b; this issue is the safe two-thirds (AC4 open + AC6 helper retirement). B2b awaits a brainstorming pass on the remote-write safety model before it gets its own issue.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    hitlNeeds human review before merge

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions