Skip to content

feat(worker): loopback-only network for worker bash and a per-project setup step (AGT-4798) - #841

Merged
unohee merged 1 commit into
mainfrom
feat/agt-4798-worker-network-setup
Oct 21, 2026
Merged

unohee merged 1 commit into
mainfrom
feat/agt-4798-worker-network-setup

Conversation

@unohee

@unohee unohee commented Oct 21, 2026

Copy link
Copy Markdown
Collaborator

Why

#840 (AGT-4783) took away the credentials the worker shell picked up on its own. One path stayed open: a command could still read a token file by absolute path and use it, because the sandbox allowed the network. Turning the network off closes that path.

The plan's concern was that network-off without a setup step would break workers. I measured it first, inside the real sandbox:

  • cgf-portal: uv run --frozen pytest runs offline.
  • OpenSwarm: vitest runs offline. Worktrees share installed deps via sharedPaths.
  • What breaks: a loopback-denying profile broke port-binding tests (src/support/web.provider.test.ts, EPERM). That is why this PR uses loopback-only, not none.

What changes

  • macOS sandbox profile, allowNetwork: false: loopback only, split by direction: network-bind/network-inbound on local localhost, network-outbound to remote localhost.
    • Measured: a single (allow network* (local ip "localhost:*")) also lets remote connections through (an outbound socket's local end matches).
    • Unix sockets stay denied, e.g. docker.sock would hand out a networked container.
    • bwrap already uses --unshare-net, which gives a loopback-only namespace.
  • New autonomous.workerNetwork: loopback | open (default loopback).
  • New projectAgents[].setup (src/agents/workerSetup.ts): install commands that run in the worktree before the worker.
    • They run with the network open, inside the sandbox, and without credentials (buildWorkerShellEnv).
    • On failure the run ends as infra_error before any model call.
    • runnerExecution.ts gains two lines; it sits exactly at its 1500-line cap.
  • resolveOwningProject: extracted from resolveProjectGoal so setup and goal resolve the owning project the same way.
  • Worker prompt (en/ko): it now states what is true (no credentials, no remote network) and forbids probing release/deploy/infra scripts, even with --help.

Test plan

  • osSandbox.test.ts
    • Profile shape.
    • Live sandbox-exec: loopback works, and a remote host fails with EPERM. EPERM specifically, so an offline host cannot pass the test by accident.
  • tools.test.ts (live): worker bash gets loopback, gets EPERM for a remote host, and workerNetwork: open restores remote access.
  • workerSetup.test.ts (8 tests)
    • Runs commands in order and stops at the first failure.
    • Reports a timeout.
    • Withholds credentials.
    • Refuses to run when the sandbox is on but missing.
    • setupFailureBeforeWorker returns infra_error naming the failing command.
  • config.test.ts: the workerNetwork default is loopback; open and setup are carried through.
  • Mutation checks: the tools layer ignoring the policy → 1 fail; the single leaky localhost rule → 2 fail.
  • src/adapters, osSandbox, projectGoal, config, service, runnerExecution: 1216 + 138 passed. typecheck and lint pass.
  • CI
  • Not covered by a consumer test: the runnerExecution call site. It is two lines delegating to the tested helper.
  • Live fire after merge: a throwaway repo whose scripts/release.sh wraps gh workflow run, run via openswarm exec --issue. Expect 0 workflow runs.

Deploy note

vela (Docker) needs autonomous.workerNetwork: open unless its bwrap can create a network namespace. This is a config twin.

… setup step (AGT-4798)

Worker shell commands now reach only localhost by default
(autonomous.workerNetwork: loopback | open). The macOS profile splits
bind/inbound/outbound on localhost because a single network* local-ip rule
was measured to admit remote connections. Dependency installs that need the
network go in projectAgents[].setup, run in the worktree before the worker
inside the sandbox and without credentials; a failure ends the run as
infra_error before any model call. The worker prompt now states what is true
and forbids probing release/deploy scripts with --help.
@unohee
unohee merged commit 2bd8d54 into main Oct 21, 2026
7 checks passed
@unohee
unohee deleted the feat/agt-4798-worker-network-setup branch October 21, 2026 05:53
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.

1 participant