Skip to content

Fleet multi-harness control — handoff spec (WT-c665 → WT-f9aa)

Date: 2026-07-10. Origin: WT-c665 (gov:build). Owner after handoff: WT-f9aa (multi-model tool deployment architecture, gov:orch).

Question answered

Can remote worktrees/sessions control other PCs beyond the Claude CLI — i.e. drive the Claude Code app, the ChatGPT app (formerly Codex), Antigravity 2.0, and the Odysseus harness on every fleet PC?

Answer: yes, today, via fleet-dispatch pwsh jobs (arbitrary command execution), and it should be promoted to first-class harness job kinds.

Current state (verified in code)

fleet-dispatch (C:\Users\fives\source\repos\fleet-dispatch):

  • Job kinds: only claude and pwsh — validated at QueueService.cs:30, executed at RealJobExecutor.cs:53-55.
  • claudeclaude -p <payload> with --permission-mode bypassPermissions (fallback --dangerously-skip-permissions), RealJobExecutor.cs:9-10,73-75.
  • pwshpwsh -NoProfile -ExecutionPolicy Bypass -Command <payload> — arbitrary commands, no allowlist; safety = HMAC job signing (JobSigner.Verify, QueueService.cs:75, DispatchServer.cs:171) + governor gate (GovernorGate.cs:7).
  • No mention of codex/chatgpt/agy/antigravity/gemini/odysseus anywhere in the repo (grep-verified).
  • Transport: SMB queue dirs under $OneDrive\PC-Bootstrap\_shared\dispatch\<PC>\{inbox,processing,outbox,archive} + HTTP POST /dispatch on :47600. Results = JSON DispatchResult (JobId, ExitCode, StdoutTail 8k, StderrTail) in <PC>\outbox.
  • Targets are the live fleet in TargetResolver.DefaultPcs: ANDREWBEDROOMTV (bedroom), ANDYGREATROOMPC, DESKTOP-D249KD4 (gaming), DESKTOP-SCDT9HI (streaming). Add a new box with FLEET_DISPATCH_PCS (additive) until it ships in DefaultPcs.
  • BEDROOM-PC was removed (FLT-68): nothing has ever drained it, and all was silently fanning out to it. The earlier note here that "ANDREWBEDROOMTV resolves via all" was describing an accident, not a design — it resolved only because its directory happened to exist, and would have vanished from all on any box without synced dispatch folders. A directory no longer admits a name.

So: any remote worktree can already run codex, agy, or hit Odysseus on any fleet PC by wrapping the invocation in a pwsh payload. What's missing is first-class support (correct flags, stdin handling, timeouts, result parsing) so callers don't re-learn each harness's gotchas.

Fleet probe results (2026-07-10, live via fleet-dispatch pwsh jobs)

Raw JSON: docs/multi-harness-probe-results.json. Summary (4/5 PCs responded; BEDROOM-PC listener down/offline):

PC claude codex (ChatGPT CLI) agy (Antigravity) gemini Odysseus :7000
ANDYGREATROOMPC ✔ (Codex\bin\codex.exe) ✔ (nvm4w) ✔ listening
DESKTOP-D249KD4 (gaming) ✔ (npm codex.ps1) ✔ listening
DESKTOP-SCDT9HI (streaming) ✔ (npm codex.ps1) ✔ listening
ANDREWBEDROOMTV ✔ (Codex\bin\codex.exe) ✔ listening
BEDROOM-PC no response

Key facts: - CLI binary is still codex everywhere; no chatgpt binary exists despite app rename. Gaming/streaming have the npm shim (codex.ps1 — invoke via pwsh, not direct exec); greatroom/bedroomTV have the ChatGPT-app-bundled codex.exe. - agy present on all 4 responding PCs (winget or local install). - Odysseus :7000 listening on ALL 4 responding PCs — HTTP-controllable fleet-wide without any process spawn. - Stale-memory correction: polyharness note "codex missing on gaming+streaming" is no longer true — npm codex present on both.

Proposed design for WT-f9aa

Alignment note: this overlaps polyharness-parity P2 ("dispatch kind registry"), already councilled 2026-07-10 — Kind stays a free string dual-allowlisted (QueueService.cs:30 + Program.cs:186) inside HMAC; build a kind+capabilities registry, not enum growth; and FIX FIRST the bug where an unknown kind falls through to pwsh. WT-f9aa should implement this spec AS polyharness P2, not parallel to it. Spec ref: codex-harness-mirror/docs/POLYHARNESS-PARITY-SPEC.md.

  1. New job kinds in fleet-dispatch (C#, extend QueueService.cs:30 validation + RealJobExecutor.cs switch):
  2. codexcodex exec --dangerously-bypass-approvals-and-sandbox <payload> (Windows sandbox helper broken — read-only work can use plain codex exec). App renamed ChatGPT but CLI binary still codex; confirm binary name per probe results.
  3. agy (Antigravity 2.0 / Gemini) → agy <ask> with stdin closed (< NUL equivalent: redirect empty stdin) — known hang otherwise.
  4. odysseus → HTTP call to local Odysseus harness :7000 (no process spawn); payload = request body.
  5. Keep pwsh as escape hatch.
  6. Per-kind config in listener config: binary path, default flags, timeout defaults, max payload (grok CLI dies >~32KB arg — pass payload via temp file for big inputs; same pattern advisable for all).
  7. GUI apps need no pixel automation. Claude Code app / ChatGPT app / Antigravity app all ship CLIs (claude, codex, agy); Odysseus is HTTP. Recommend AGAINST computer-use-over-network for fleet control — CLI/HTTP covers everything, is auditable, and fits governor gating. Computer-use stays a local-only per-PC option if a GUI-only feature ever appears.
  8. Direct LAN alternative (no dispatch queue): council MCP servers (gaming 10.0.0.7:37800, streaming 10.0.0.26:37878, Bearer auth, IPv4 literals not .local) are already remotely callable from any worktree. Odysseus :7000 currently binds 127.0.0.1 only (per fleet auth audit) — so the odysseus dispatch kind must execute the HTTP call ON the target PC (listener-side curl/HttpClient), OR Odysseus bind must change to 0.0.0.0 + auth for direct LAN control. Recommend listener-side execution first (no new attack surface). SSH mesh (all 4 PCs, PowerShell remote shells, base64 -EncodedCommand for nested quoting) is the fallback transport.
  9. Governor: new kinds must pass the existing GovernorGate and count as harness spawns for YELLOW/RED gating.
  10. Security: keep HMAC signing mandatory for new kinds; payloads via --payload-file for anything >8KB.

Acceptance for WT-f9aa

  • fleet-dispatch enqueue --targets all --kind codex|agy|odysseus works end-to-end on all 4+1 targets, results readable via results.
  • Per-memory standard: acceptance = ALL worktrees × models × harnesses (aligns with fleet-telegram acceptance matrix).
  • Great-room caveat: inbound = queue-only (no HTTP listen).
  • Language policy: C# (extends existing fleet-dispatch C# codebase).