Skip to content

Deferred: support remote Squadrons and inboxes in the local client #105

Description

@Jacksondr5

Posted by an AI agent on Jackson's behalf

Decision: deferred; use the remote URL for dogfooding

Jackson chose on 2026-09-04 to defer this initiative because the server-served remote URL already provides the main benefit: development on an always-on server. Completing the combined local-client experience would touch several J5 surfaces and distract from more urgent work. This issue preserves the research; it is not an implementation commitment or a deployment blocker for the remote-URL workflow.

Revisit when switching between local and remote clients repeatedly interrupts actual work, or when managing concurrent fleets on multiple servers becomes a concrete requirement. A small, independently justified UX fix could explain unsupported combinations before submission, without starting this whole initiative.

Problem and observed behavior

After adding a working remote J5 server under Settings → Connections → Add environment, the local client does not show that server's Squadrons in its choices. The UI also allowed an attempted remote launch that ended in an error.

Evidence collected during remote dogfooding:

  • The remote server contains a real Squadron and project. Its own server-served UI successfully launched fresh Claude and Codex threads and displayed their replies live.
  • Adding the remote connection to the local UI did not expose that remote Squadron to the operator.
  • The subsequent remote web-created run failed before the provider started (startedAt=null, providerTurnId=null). The exact browser error was not captured, so the source-derived registration failure below is a likely explanation, not a verified copy of that error.
  • An OPTIONS request to the remote /api/j5/squadrons endpoint from a localhost origin returned 204 and permitted the Authorization header. The inspected production server applies CORS to the J5 routes. This evidence points to J5 client routing rather than another Tailscale setup task.

Research snapshot: 5f1e56b9f3f80e40adfb427f85905c2c99d41699. No application changes or restarts were performed for this investigation.

Confirmed gaps in the current code

Surface Finding Source
Squadron list/create Both operations use resolvePrimaryEnvironmentHttpUrl; ManagedSquadron has no environment identity. squadronClient.ts
Directory lifecycle One global list and status, with no subscription to connection-catalog additions/reconnections. SquadronDirectory.ts
Picker/project join Every Squadron's project reference is matched against primaryEnvironmentId. Fetching remote rows alone would still leave the join wrong. SquadronPicker.logic.ts
Creation The form explicitly refuses a non-primary project. This is a deliberate v0 limit. SquadronCreate.logic.ts
Draft/launch Ambient scope is a plain Squadron ID; the draft chip exposes the unscoped directory. The launch carries that ID separately from its target environment. SquadronDraftState.ts, ChatView.tsx
Thread homes and filters Reads go to primary; caches use raw thread IDs. Sidebar supplies IDs without their environments. A dropdown-only fix leaves remote labels/filtering incorrect. ThreadHomesClient.ts, Sidebar.tsx
Human attention Inbox reads, answers, and the bell count all target primary. Remote requests would remain missing from the local inbox after a picker-only fix. humanInboxClient.ts, humanInboxCountClient.ts

The runtime already routes a launch through the selected environment. A local Squadron ID paired with a remote project can therefore reach the remote server, where SquadronProjectReferences checks the remote server's own table and rejects an unknown Squadron. The launch error wrapper reports that the durable thread could not receive its required Squadron home. The registration guard should remain fail-closed.

Boundaries and current workaround

Use the remote server's own HTTPS URL. That makes the remote environment primary, so its Squadron directory, thread-home reads, and inbox use the correct server. Collaborating Squadrons can be kept together on that server.

Cross-Squadron messaging on one server is distinct from cross-server messaging. This issue covers merging client views and routing user operations to their owning server. It does not add server-to-server message delivery, migrate a Squadron, or let one Squadron span machines.

The current DV5 override explicitly defers multi-environment Squadron creation. The cross-device position preserves one-server Squadron ownership (X1), supports client-side merged views (X2), and treats cross-server exchanges as separate transport work (X3).

Proposed approach when this is prioritized

  1. Carry a client-side { environmentId, squadronId } reference through the directory, ambient/draft scope, picker and launch validation. Keep project/thread/cache keys environment-scoped too.
  2. Read Squadrons from usable saved connections using existing prepared connections and authentication. Maintain per-environment cached/loading/error state; refresh on add/reconnect/create, discard stale results from removed connections, and avoid a new rapid polling loop.
  3. Show environment labels in choices. Join projects within the owning environment. Create a Squadron on the explicitly selected folder's server. Require a compatible Squadron before launching after an environment/folder change, preserving draft text.
  4. Batch thread-home reads by environment and update all existing web creation/filtering entry points: first-run/index, sidebar, command palette, keybindings, composer, and plan-to-implementation inheritance.
  5. Merge inbox rows/counts with origin identity. Answer through that connection using its returned person ID. Expose partial/offline/error state instead of presenting failed reads as empty or zero.

Reuse the environment catalog and the existing J5 prepared-connection HTTP path, including cookie/Bearer/DPoP handling. No new global registry, server transport, or database migration is expected for this client-side scope; confirm that during implementation.

Discovery/launch/home handling and inbox integration can be separate coordinated PRs. Both are needed before claiming the complete combined-client dogfood experience. Native mobile's separate v0 cohort is not implicitly included; web and desktop share this web implementation.

Upstream principle

Most changes belong under apps/web/src/j5. Limited edits to existing J5 integration points in upstream-owned Sidebar, ChatView, CommandPalette and chat route wrappers are likely necessary. Bring the concrete scope to Jackson for a ruling before implementation, reuse those integration points, and record the exceptions in FORK.md. Lift only DV5's relevant restriction. Preserve one-folder v0 behavior and server-local Squadron authority.

Moving registration validation earlier to avoid a durable failed thread is a possible separate hardening task, not a prerequisite for correct client routing.

Acceptance evidence for future implementation

  • One local client lists both servers' Squadrons. Selecting the remote one launches there; hostname/pwd prove execution location. A peer spawned within that remote Squadron remains there.
  • A remote agent's human request appears in the local bell/inbox, and an answer reaches the remote agent exactly once.
  • Equal Squadron/project/thread IDs and duplicate names in two fixture environments stay separated in selection, caches, filtering and answers.
  • A test follows actual environment lookup through URL construction and authorization using both local and remote connections. Mutating selection back to primary fails the test. Reuse the pattern in archiveFlowClient.test.ts.
  • A local Squadron combined with a remote folder cannot dispatch an invalid launch; correcting the choice preserves draft text. Server rejection still cannot start a provider.
  • Add/remove/reconnect, expired credentials, partial failures and an empty primary directory do not hide usable remote/local Squadrons or fabricate a healthy empty inbox.
  • Verify all applicable web entry points in one integrated two-environment browser pass, record the source SHA, and coordinate activation without restarting a local instance that has active agents.

Research and issue preparation: Codex harness, GPT-6; independent source review by a Codex subagent.

Activity

  1. self-assigned this
    on Sep 13, 2026
  2. Jacksondr5 commented on Sep 13, 2026

    @Jacksondr5
    OwnerAuthor

    Posted by an AI agent on Jackson's behalf

    Jackson lifted the 2026-09-04 deferral on 2026-09-12: PR #125 implements the local-client half (read models merge in the client; authority stays on each server) for web and desktop. Native mobile screens remain deferred (#40). The PR closes this issue when it lands.

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

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions