# 04 — Integration & tooling > Sub-plan of [trap-sandbox-gateway-spec](./trap-sandbox-gateway-spec.md). **Build last** (M4): > requires both the TS gateway (M1) and the Lua client (M2) to exist. References the spec's > **Protocol**/**Handshake** for assertions. ## Scope Host tooling (`just`/`npm.just` recipes, `sandbox-serve`, docs) and the cross-side tests: TS **integration** (real craftos ↔ real gateway) plus the **full-boot e2e**. ## Task checklist - [x] `just/npm.just`: extend `install/build/check/test/test-integration/ci` to cover `tools/trap-sandbox` alongside mcp-bridge; ensure `just install`/`just ci` include it. (Symmetric per-tool recipes; `npm-trap-sandbox-ci` removed.) - [x] **`just sandbox-serve`** added in new `just/sandbox.just` (warn-only on missing secret). - [x] `docs/public-ports.md`: added a `4444` row. - [x] TS integration harness + cases (`tools/trap-sandbox/test-integration/`). - [x] Full-boot e2e. - [x] Gate: `npm run test:integration` green; `just ci` covers both tools. ## Tooling - `just/npm.just`: extend recipes (install/build/check/test/test-integration/ci) to cover `tools/trap-sandbox` alongside mcp-bridge; ensure `just install`/`just ci` include it. - `just/opencode.just` (or a new recipe): add **`just sandbox-serve`** mirroring `opencode-serve` (source `.env`, export `OPENCODE_SERVER_PASSWORD`, default `OPENCODE_URL`/`SANDBOX_PORT`, run `npm run dev --prefix tools/trap-sandbox`). - `docs/public-ports.md`: add a `4444` row (note it sits outside the 4242–4244 range; 4244 reserved). ## Test layout ``` test-integration/ # harness.ts (app on :0, startCraftos, fake-opencode http server) + lua/ + *.test.ts ``` ## TS integration (`tools/trap-sandbox/test-integration`, real craftos ↔ real gateway, serialized) Self-contained `gateway-client.lua` for the health round-trip (opencodeOk true/false via the fake-opencode server), reverse `ping` via `registry.request`, duplicate (newest-wins), and the **auth canary** — wrong secret asserts in-band `hello ok:false code:"unauthorized"`, correct secret asserts `hello ok:true`. ## Full-boot e2e (TS integration) craftos `--exec` replicates boot (set `sandbox.url`, `_G.bootEventLoop`, run real `servers/sandbox`, then under `parallel` wait for `trapos_sandbox_connected` and run `sandbox health`); assert stdout contains `sandboxOk: true`. Bounded by generous timeouts. ## Verification gate (also the project-level acceptance) - `npm test`, `npm run test:integration`, `npm run lint`/`check` clean in `tools/trap-sandbox`. - `just _craftos-test` runs `tests/sandbox.lua`; `just ci` covers both tools. - Manual: `just sandbox-serve`; in-game `set sandbox.url ws://:4444` (origin only — libsandbox appends `/gateway`) (+ `set sandbox.password ` if `SANDBOX_PASSWORD` set), reboot, `sandbox health` → `sandboxOk: true` / `opencodeOk: …`.