Skip to content

feat(runner): envd serve mode for cloud sandbox + safari extension RPCs#48

Merged
ysyneu merged 14 commits into
mainfrom
feat/ai-sre
May 24, 2026
Merged

feat(runner): envd serve mode for cloud sandbox + safari extension RPCs#48
ysyneu merged 14 commits into
mainfrom
feat/ai-sre

Conversation

@ysyneu
Copy link
Copy Markdown
Collaborator

@ysyneu ysyneu commented May 24, 2026

Summary

  • Adds flashduty-runner serve subcommand that boots an envd-compatible HTTP listener on :49999 for cloud sandbox pods. Safari (and any e2b-spec client) talks to it over Connect-RPC/JSON.
  • Implements the e2b envd surface the cloud sandbox needs: Process.Start / SendSignal / List (streaming + unary), Filesystem RPCs + /files REST, plus stubs that return 501 instead of 500 for SendInput / Connect.
  • Implements the Safari extension surface at /safari.*: the high-level, auth-aware, language-aware ops (grep, glob, webfetch, mcp, knowledge, skill, meta, plus Read / Write / List). Safari routes every file operation through this path — there is no low-level filesystem client on the Safari side.
  • Auth: every request requires X-Access-Token matching ENVD_ACCESS_TOKEN; the same token Safari stamps on t_cloud_sandbox.envd_access_token. /health requires it too (AGS gateway is strict).
  • Hardening: nil-workspace guard, partial-write cleanup, ENOENT → 404 mapping, body draining on error, deferred cancel hygiene.

Paired with fc-safari PR #59 (cloud sandbox via Tencent AGS + envd Connect-RPC). End-to-end V1–V12 validation green there.

Commits (11)

SHA Subject
cfa9e7a feat(runner): safari extension Read/Write/List handlers
315ae7e fix(runner/envd): guard nil workspace + omit TotalMemoryMB + flag readUnary cap
5bc6e33 feat(runner): envd safari-extension RPCs (grep/glob/webfetch/mcp/knowledge/skill/meta)
b32ab31 fix(runner/envd): ENOENT→404 + partial-write cleanup + trust-boundary doc
ccf7612 feat(runner): envd Filesystem RPCs + /files REST
68c4ae0 fix(runner/envd): defer cancel + document env-replace intent
6a782d0 fix(runner/envd): stub Process.SendInput/Connect return 501 not 500
770a443 feat(runner): envd Process.Start/SendSignal/List handlers
0d0f8b4 feat(runner): minimal Connect-RPC framing helpers
568de2d fix(runner/serve): surface home-dir resolution error
f88e05a feat(runner): scaffold serve subcommand + envd HTTP listener

Test plan

  • go build ./... clean
  • go test ./envd/... passes
  • Image built and pushed to TCR (flashduty.tencentcloudcr.com/safari/safari-sandbox:amd64-20260524-005516)
  • AGS cold-start E2E green (cf. fc-safari PR #59 V1–V12 matrix)

ysyneu added 11 commits May 23, 2026 23:38
Implements Task 1.4: ListDir, Stat, MakeDir, Remove handlers on
/filesystem.Filesystem/* routes plus the /files GET+PUT REST endpoint
mirroring the e2b filesystem.proto surface. Adds newTestServerWithWS
helper for disk-backed tests.
…ledge/skill/meta)

Adds 11 Connect-RPC routes under /safari.{Tools,Knowledge,Skill,Meta}/ that
delegate directly to existing environment.Environment methods — no business
logic re-implemented. Smoke test verifies all routes are registered (non-404)
with an empty request body; method correctness is covered by environment tests.
The plan's opToSafariPath mapped read/write/list to /safari.Tools/{Read,Write,List}
but those routes were never registered. Add the three delegating handlers that
mirror the existing handleGrep pattern, register them in server.go, and add
them to the route-registration smoke test (14 routes total, was 11).
Comment thread envd/filesystem.go Fixed
Comment thread envd/filesystem.go Fixed
Comment thread envd/filesystem.go Fixed
Comment thread envd/filesystem.go Fixed
Comment thread envd/filesystem.go Fixed
Comment thread envd/filesystem.go Fixed
Comment thread envd/filesystem.go Fixed
Comment thread envd/filesystem.go Fixed
Comment thread envd/filesystem.go Fixed
Comment thread envd/process.go Fixed
CI surfaced lint and Windows build failures on PR #48. Address them:

- Split syscall-bound code into envd/process_unix.go and a windows stub
  so Setpgid + syscall.Kill stop breaking the windows build job. The
  Windows path is shim-only; envd serve mode targets the Linux sandbox.
- Run gofmt on envd/server.go and protocol/messages.go (column-aligned
  comments tripped gofmt).
- Tighten errcheck: wrap ignored Close/Remove/os.Remove returns.
- Tighten noctx: NewRequestWithContext in connect_test/filesystem_test/
  process_test/safari_tools_test; exec.CommandContext in safari_meta.
- Annotate intentional gosec hits with nolint: process.go (envd contract
  is to run client-supplied cmds; sandbox+auth are the trust boundary),
  filesystem.go (client addresses arbitrary sandbox paths by design),
  safari_meta.go ("uname -r" literal cmd/args), test files (URLs come
  from httptest servers).
- Refactor process.go's exit-status block into platform-specific helpers
  so WaitStatus.Signaled() no longer breaks on Windows.
- Replace Fatal-shadowed err with explicit decErr; rewrite De-Morgan
  three-way negation.

golangci-lint run --timeout=5m ./...   → 0 issues.
GOOS=linux/windows/darwin go build ./... → clean.
go test ./...                          → all green.
Comment thread envd/filesystem.go Fixed
Comment thread envd/filesystem.go Fixed
Comment thread envd/filesystem.go Fixed
Comment thread envd/filesystem.go Fixed
Comment thread envd/filesystem.go Fixed
Comment thread envd/process.go Fixed
ysyneu added 2 commits May 24, 2026 11:21
TestProcessStart_EchoStreams and TestProcessSendSignal_KillsRunning use
/bin/echo and /bin/sleep, which don't exist on the windows CI runner
image. envd serve mode targets the Linux sandbox container, so
exercising the process-start path on windows verifies the wrong
invariant. Skip both tests when GOOS=windows.
This repo is an agent runtime: envd/, mcp/transport.go, and
environment/{knowledge,webfetch,environment}.go exist precisely to
funnel authenticated client requests into filesystem operations, exec
calls, HTTP fetches, and memory allocations. CodeQL's go/path-injection,
go/command-injection, go/request-forgery, and go/uncontrolled-allocation
queries report each of those surfaces as a vulnerability. They are
correct about the taint flow and wrong about the threat model — the
trust boundary is the sandbox plus the X-Access-Token check at the HTTP
edge, not in-process input sanitization.

Excluding the four query IDs repo-wide via a CodeQL config keeps the
remaining queries (XSS, SSRF outside webfetch, crypto misuse, races,
etc.) producing actionable signal.
@ysyneu ysyneu merged commit b973c40 into main May 24, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants