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
claudeandpwsh— validated atQueueService.cs:30, executed atRealJobExecutor.cs:53-55. claude→claude -p <payload>with--permission-mode bypassPermissions(fallback--dangerously-skip-permissions),RealJobExecutor.cs:9-10,73-75.pwsh→pwsh -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}+ HTTPPOST /dispatchon :47600. Results = JSONDispatchResult(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 withFLEET_DISPATCH_PCS(additive) until it ships inDefaultPcs. - BEDROOM-PC was removed (FLT-68): nothing has ever drained it, and
allwas silently fanning out to it. The earlier note here that "ANDREWBEDROOMTV resolves viaall" was describing an accident, not a design — it resolved only because its directory happened to exist, and would have vanished fromallon 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.
- New job kinds in fleet-dispatch (C#, extend
QueueService.cs:30validation +RealJobExecutor.csswitch): codex→codex exec --dangerously-bypass-approvals-and-sandbox <payload>(Windows sandbox helper broken — read-only work can use plaincodex exec). App renamed ChatGPT but CLI binary stillcodex; confirm binary name per probe results.agy(Antigravity 2.0 / Gemini) →agy <ask>with stdin closed (< NULequivalent: redirect empty stdin) — known hang otherwise.odysseus→ HTTP call to local Odysseus harness :7000 (no process spawn); payload = request body.- Keep
pwshas escape hatch. - 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).
- 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. - 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
odysseusdispatch 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-EncodedCommandfor nested quoting) is the fallback transport. - Governor: new kinds must pass the existing
GovernorGateand count as harness spawns for YELLOW/RED gating. - Security: keep HMAC signing mandatory for new kinds; payloads via
--payload-filefor anything >8KB.
Acceptance for WT-f9aa¶
fleet-dispatch enqueue --targets all --kind codex|agy|odysseusworks end-to-end on all 4+1 targets, results readable viaresults.- 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).