ST4 — Worker: Go reference worker
Part of the SandboxTransport epic (see epic #89). Worker track (Go / sandbox side) — a separate contributor from the backend. Depends only on ST1 (the published sandbox/v1 proto); builds in parallel with ST2/ST3.
Spec: docs/specs/2026-07-08-sandbox-transport-grpc-design.md §7, §8.
Problem
The contract is language-neutral (ST1), but nothing yet proves it: we need one worker that a) implements the SandboxWorker.Attach client, and b) is deliberately not TypeScript — the honest proof the seam isn't secretly TS-shaped (driver #2, §2). A Go static binary drops into any sandbox image with no runtime dependency.
Goal
Ship a thin, single-purpose Go static binary that holds no LLM key and no orchestration — it only executes commands and returns bytes (what makes "central brain" trust-correct, §7). Behavior per §7:
- On start: read
SANDBOX_ID, RELAY_ADDR, SANDBOX_TOKEN from env; dial SandboxWorker.Attach over TLS :443 (HTTP/2) with Authorization: Bearer <token>.
- Send
Hello (id, labels, capabilities, capacity_max, trust).
- Loop on
ServerFrame:
Exec → run bash -c <command> locally, feeding stdin. If streaming: emit Chunk* then End{exit_code}. Else: a single End carrying full stdout. Enforce timeout_s locally (SIGKILL on expiry).
Abort → SIGKILL the in-flight child for that req_id.
- Send
Heartbeat periodically (liveness + NAT/proxy keepalive).
- Maintain a bounded
req_id → End dedup cache; on a redelivered req_id, re-emit the cached result instead of re-running (at-least-once + dedup, §8).
Persistent-shell semantics (one long-lived bash preserving cwd/env across execs) are an internal choice; the wire only requires ordered, one-in-flight execs (§7).
Non-goals (this task)
- The relay and
GrpcRelayTransport (ST3 — backend).
- mTLS / SPIFFE (bearer token only day-one, §9); additional-language workers (§13.4).
- Any orchestration or credential handling in the worker.
Acceptance
- Go
contract test (Go test, real Attach against a relay, worker pointed at local bash) round-trips read/write/bash/grep, plus abort mid-stream, timeout (worker SIGKILLs child), and reconnect → dedup (redelivered req_id re-emits cached End, no re-run).
- Static binary, no runtime deps; drops into a sandbox image.
- Chunk size capped so a single frame stays small (backpressure, §8).
Touches
New Go module for the worker (e.g. worker/ or a dedicated repo dir), consuming ST1's generated Go stubs; a minimal container build for the static binary; Go unit + contract tests.
Next step
Join ST3 for the ST5 live gate (real worker pod → in-cluster relay on :443). Worker plan lives locally in docs/plans/, authored by the worker contributor.
ST4 — Worker: Go reference worker
Part of the SandboxTransport epic (see epic #89). Worker track (Go / sandbox side) — a separate contributor from the backend. Depends only on ST1 (the published
sandbox/v1proto); builds in parallel with ST2/ST3.Spec:
docs/specs/2026-07-08-sandbox-transport-grpc-design.md§7, §8.Problem
The contract is language-neutral (ST1), but nothing yet proves it: we need one worker that a) implements the
SandboxWorker.Attachclient, and b) is deliberately not TypeScript — the honest proof the seam isn't secretly TS-shaped (driver #2, §2). A Go static binary drops into any sandbox image with no runtime dependency.Goal
Ship a thin, single-purpose Go static binary that holds no LLM key and no orchestration — it only executes commands and returns bytes (what makes "central brain" trust-correct, §7). Behavior per §7:
SANDBOX_ID,RELAY_ADDR,SANDBOX_TOKENfrom env; dialSandboxWorker.Attachover TLS:443(HTTP/2) withAuthorization: Bearer <token>.Hello(id, labels, capabilities,capacity_max,trust).ServerFrame:Exec→ runbash -c <command>locally, feedingstdin. Ifstreaming: emitChunk* thenEnd{exit_code}. Else: a singleEndcarrying full stdout. Enforcetimeout_slocally (SIGKILL on expiry).Abort→ SIGKILL the in-flight child for thatreq_id.Heartbeatperiodically (liveness + NAT/proxy keepalive).req_id → Enddedup cache; on a redeliveredreq_id, re-emit the cached result instead of re-running (at-least-once + dedup, §8).Persistent-shell semantics (one long-lived
bashpreserving cwd/env across execs) are an internal choice; the wire only requires ordered, one-in-flight execs (§7).Non-goals (this task)
GrpcRelayTransport(ST3 — backend).Acceptance
contracttest (Go test, real Attach against a relay, worker pointed at local bash) round-trips read/write/bash/grep, plus abort mid-stream, timeout (worker SIGKILLs child), and reconnect → dedup (redeliveredreq_idre-emits cachedEnd, no re-run).Touches
New Go module for the worker (e.g.
worker/or a dedicated repo dir), consuming ST1's generated Go stubs; a minimal container build for the static binary; Go unit + contract tests.Next step
Join ST3 for the ST5 live gate (real worker pod → in-cluster relay on
:443). Worker plan lives locally indocs/plans/, authored by the worker contributor.