You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat(fleet): attach-first opencode client helper — forward lifecycle, service discovery, stdin-safe run wrapper #1357
From the access-pattern benchmark (code#1344; report: usage-billing-hub goal files/opencode-access-benchmark-2026-10-27.md). Decision: programmatic opencode work defaults to ATTACH — a persistent SSH forward to the laptop background service (127.0.0.1:13420) with raw API control + opencode run --server for turns.
Build one small fleet helper (script/library in the pm-stack orbit) that:
discovers the laptop service (url + password) from the laptop's service-prod.json via laptop-ssh.sh, provisioning the password into a 0600 local secret file — never argv, never logs;
opens/reuses a multiplexed SSH forward (idempotent; health-checks the local port; reopens on death);
exposes run/prompt/list operations with the two safety defaults baked in: stdin closed for every opencode run (open-pipe stdin hangs the CLI — separate follow-on) and session location passed in the POST body (the ?directory= query param is silently ignored — separate follow-on);
is the single documented entry point stewardship dispatch + sandbox tooling use for opencode work, so the pattern stops being re-improvised per workstream.
Acceptance: from the sandbox, one command runs a prompt turn against the laptop service end-to-end; killing the forward mid-turn and re-running the helper recovers the view of the still-running session; no secret value appears in any output.
Acceptance criteria
One fleet helper exists that discovers the laptop opencode service (url + password) from service-prod.json via laptop-ssh.sh, provisioning the password into a 0600 local secret file — never argv, never logs.
The helper opens/reuses a multiplexed SSH forward idempotently, health-checks the local port, and reopens it on death.
Its run/prompt/list operations bake in the two safety defaults: stdin closed for every opencode run, and session location passed in the POST body (not ?directory=).
Load-bearing as of 2026-10-27: the attach pattern is now the fleet DEFAULT (benchmark + decision record on #1344; Horizon here raised to Today). The dispatching/supervising jobs have already been switched in their instructions — stewardship-cycle (OPENCODE ACCESS PATTERN block), jules-review (supervision target = laptop server via the forward), orchestration-pass (session answers + dashboard session actions via the laptop server; opencode-sandbox actions rejected as retired). Until this helper lands, those jobs hold one persistent forward per batch and drive the API / run --server by hand — this issue is what makes that cheap and uniform. Note the stdin trap (#1359) in the wrapper: always close or redirect stdin for opencode run.
Implements the attach-first decision from the #1344 benchmark report (usage-billing-hub goal, opencode-access-benchmark-2026-10-27.md). Security note: the credential handling in the acceptance criteria (0600 file, no argv/logs) is part of done, not a nicety. Suggested approach: small script/library in the pm-stack orbit, reusing ~/tools/laptop-ssh.sh multiplexing.
Related: Related: #1344 (benchmark + decision: attach-first); #1359 (stdin hang — workaround baked in here); #1360 (?directory= ignored — body-location default baked in here); #1363 (tailnet evaluation that could later change the transport). Labels normalized by fleet monitor: the issue arrived with only meta/follow-up.
Still live: checked this run — no merged PR in the recent merged list of this repo implements or resolves this issue, and no closing reference was found; the issue stays open.
🤖 Agent note · filed
Agent: fleet monitor (repo-fleet-monitor)
Session / ID: cron repo-fleet-monitor, run 2026-10-27 03:27 CDT
Found via: monitor reconciliation (intake enrichment, protocol §5)
Scope update (2026-10-27, from the #1363 correction): the route is no longer an SSH forward. The laptop opencode server is published via tailscale serve at https://amd-6.raptor-pumpkinseed.ts.net, and the sandbox reaches it through the documented tailnet proxy route (runtime proxy host on port 3130 — ~/docs/devices/tailscale.md). The helper should therefore wrap: the serve URL + the 3130 proxy env for its HTTP calls (or the equivalent client config), the server password from the laptop's service-prod.json discovery, directory-scope on every call, and stdin closed/redirected for opencode run (#1359). No forward lifecycle to manage — that part of the original scope is gone, which makes this helper smaller than filed.
Task: Built the attach-first OpenCode client helper and verified every acceptance criterion live against the laptop service (v2.0.30+56590c5, 127.0.0.1:13420).
discover: reads the laptop's service-prod.json via laptop-ssh.sh, provisions {url, password} into ~/tools/secrets.d/opencode-laptop-service.json (dir 700, file 600). Password never printed, never logged, never argv (grep over helper source + all test outputs: absent).
forward: dedicated multiplexed SSH ControlMaster (~/.ssh/cm-ocattach@…, pinned host key + tailnet proxy like laptop-ssh.sh), idempotent, health-checked via /api/info, reopened on death. Local port 13421 (the sandbox's 13420 is held by an unrelated wrapper with different credentials — verified 401 with ours).
prompt (raw API): session create with location in the POST body (location: {directory} — no ?directory=), POST prompt, wait, print reply. run: opencode run --server <forward> with stdin closed (DEVNULL) and the password only via OPENCODE_SERVER_PASSWORD env; since the v2 CLI has no --directory flag, the session is created via the API first and the CLI attaches with --session. list/health included.
Live verification (2026-10-28)
prompt turn end-to-end from the sandbox: session ses_e7cafc3edffeQQ21O3jivltnkK replied exactly as asked (~7s, model opencode-route/workhorse).
run turn end-to-end: exact reply received.
Forward killed mid-turn (ssh -O exit during a sleep-40 shell turn): local port dead → next oc-attach list reopened the forward, session ses_e7caf4bb3ffebCob3VTsjdIN3r visible, turn finished with outcome "succeeded" and the exact reply.
Note for operators: the laptop's default model route currently picks commandcode/gpt-5.6-terra, which 403s (MODEL_NOT_IN_PLAN) — pass --model opencode-route/workhorse when creating sessions until the laptop default is fixed. Documented in oc-attach.md.
Activity
developing-today commentedon Oct 27, 2026
CODE-457
dezren39 commentedon Oct 27, 2026
Load-bearing as of 2026-10-27: the attach pattern is now the fleet DEFAULT (benchmark + decision record on #1344; Horizon here raised to Today). The dispatching/supervising jobs have already been switched in their instructions — stewardship-cycle (OPENCODE ACCESS PATTERN block), jules-review (supervision target = laptop server via the forward), orchestration-pass (session answers + dashboard session actions via the laptop server; opencode-sandbox actions rejected as retired). Until this helper lands, those jobs hold one persistent forward per batch and drive the API /
run --serverby hand — this issue is what makes that cheap and uniform. Note the stdin trap (#1359) in the wrapper: always close or redirect stdin foropencode run.dezren39 commentedon Oct 27, 2026
Intake review
Implements the attach-first decision from the #1344 benchmark report (usage-billing-hub goal, opencode-access-benchmark-2026-10-27.md). Security note: the credential handling in the acceptance criteria (0600 file, no argv/logs) is part of done, not a nicety. Suggested approach: small script/library in the pm-stack orbit, reusing ~/tools/laptop-ssh.sh multiplexing.
Related: Related: #1344 (benchmark + decision: attach-first); #1359 (stdin hang — workaround baked in here); #1360 (?directory= ignored — body-location default baked in here); #1363 (tailnet evaluation that could later change the transport). Labels normalized by fleet monitor: the issue arrived with only meta/follow-up.
Still live: checked this run — no merged PR in the recent merged list of this repo implements or resolves this issue, and no closing reference was found; the issue stays open.
🤖 Agent note · filed
dezren39 commentedon Oct 27, 2026
Scope update (2026-10-27, from the #1363 correction): the route is no longer an SSH forward. The laptop opencode server is published via
tailscale serveat https://amd-6.raptor-pumpkinseed.ts.net, and the sandbox reaches it through the documented tailnet proxy route (runtime proxy host on port 3130 — ~/docs/devices/tailscale.md). The helper should therefore wrap: the serve URL + the 3130 proxy env for its HTTP calls (or the equivalent client config), the server password from the laptop's service-prod.json discovery, directory-scope on every call, and stdin closed/redirected foropencode run(#1359). No forward lifecycle to manage — that part of the original scope is gone, which makes this helper smaller than filed.dezren39 commentedon Oct 28, 2026
🤖 Agent note · done
~/tools/oc-attach.py(symlink~/tools/oc-attach), usage doc~/tools/oc-attach.mdWhat exists
discover: reads the laptop's service-prod.json via laptop-ssh.sh, provisions {url, password} into~/tools/secrets.d/opencode-laptop-service.json(dir 700, file 600). Password never printed, never logged, never argv (grep over helper source + all test outputs: absent).forward: dedicated multiplexed SSH ControlMaster (~/.ssh/cm-ocattach@…, pinned host key + tailnet proxy like laptop-ssh.sh), idempotent, health-checked via /api/info, reopened on death. Local port 13421 (the sandbox's 13420 is held by an unrelated wrapper with different credentials — verified 401 with ours).prompt(raw API): session create with location in the POST body (location: {directory}— no ?directory=), POST prompt, wait, print reply.run:opencode run --server <forward>with stdin closed (DEVNULL) and the password only viaOPENCODE_SERVER_PASSWORDenv; since the v2 CLI has no --directory flag, the session is created via the API first and the CLI attaches with --session.list/healthincluded.Live verification (2026-10-28)
oc-attach listreopened the forward, session ses_e7caf4bb3ffebCob3VTsjdIN3r visible, turn finished with outcome "succeeded" and the exact reply.--model opencode-route/workhorsewhen creating sessions until the laptop default is fixed. Documented in oc-attach.md.