Cloud agent execution
Run the agent on a remote VM. Keep the laptop as a thin control plane. It starts
jobs, reads results, and steers. It does not host the work.
Related: for local worktree cleanup use the worktree-hygiene skill. Cloud
execution does not remove local worktrees.
Tier split
- Laptop = control plane. Start jobs, read diffs, decide.
- Remote VM (a "box") = execution. Clone, edit, verify, patch.
- CI runner = tests on push. Separate from the execution tier.
Rule: heavy agent work goes to a box. Never put work or proprietary source on a
third-party box.
Run one cloud task
Start a box, let the box-side agent clone the repo from origin, do the task, and
verify ON the box. Record the starting commit (git rev-parse HEAD) before the
agent runs. Afterward, stage untracked files (git add -A) and diff against that
starting commit (git diff <start-sha>), not a plain git diff — plain git diff
only shows unstaged changes against the index, so after git add -A it misses the
very files you just staged, and it misses anything the agent already committed.
Always stop the box, even on failure. A wrapper tool does this in one command (see
the implementation repo).
Managed providers bill the box's cloud credits, not your model subscription. That
is the point: cloud credits absorb the run.
Verify on the box
Judge a delegated job on the diff against the starting commit, not the exit code
or a clean working tree. An empty git status --short only means nothing is
uncommitted — the agent may have committed its work, so it does not by itself mean
the agent did nothing. Diff against the commit recorded before the run (see above),
not HEAD versus the working tree. Read the diff every time.
Cost discipline
- A box bills every second it runs. A stopped box is free. Nothing stops it for
you.
- The real lever is not leaving boxes idle. The vendor rate is not the lever.
- Track spend over time. Snapshot the provider's usage/limits to a log and report.
- Warm a box on session start, reap it on session end. Add a TTL backstop for
killed sessions. Run a periodic reaper that measures CPU and a heartbeat, not
the box's reported state — an "idle" box can still be at full CPU.
GUI server on a box
To steer many agents by eye, run the GUI server ON the box and reach it from the
laptop browser over a public host URL.
- Do NOT point a local GUI provider path at a box wrapper. The GUI server is the
execution boundary; it reads git diffs off its own disk, so a wrapper that edits
the box shows an empty changeset. Run the whole server on the box.
- Give the user systemd a bus first (enable linger). Over a headless exec, also
export
XDG_RUNTIME_DIR or systemctl --user fails.
- Run the server as a systemd user service, not a foreground process, so it
survives an ssh disconnect. Bind
0.0.0.0, not loopback.
- Expose the port with a PUBLIC host URL. A private, token-gated host makes the
GUI client fail to fetch its environment endpoint.
- Mint a fresh pairing code against the running server. A service restart mints a
new code and invalidates the old one.
- Treat the pairing code as a secret credential, not a convenience string: over a
public host it is the only thing standing between an outsider and a server that
runs arbitrary commands. Never log it, screen-share it, or paste it into a
shared channel. Restrict the port at the network layer (security group or
firewall IP allowlist) in addition to the pairing code wherever the provider
allows it.
Multi-harness
A box can host several agent CLIs. A managed "prompt" path may cover the
first-party ones with provider-managed auth. Other CLIs run as on-box tools and
need their own auth AND funding on the box. A key being present is not proof it is
funded — preflight loudly and report which providers are ready.
Guards
- Personal or non-sensitive repos only on a third-party box.
- Never
rm -rf a worktree. First confirm it is a LINKED worktree: compare
git rev-parse --git-dir against git rev-parse --git-common-dir inside it —
they differ only for a linked worktree; a main clone's are identical. Don't
rely on the path containing /worktrees/, since a main clone checked out
under a directory of that name would match too. Deleting a main clone destroys
the repo.
- A box may print its full injected environment (tokens included) on a
non-interactive
bash -c that sources a login profile. Never pipe such output
to a shared log. Run a script file instead; it does not source the profile.
1---2name: cloud-agent-execution3description: Run coding agents on a remote cloud VM instead of the laptop. Use on "run this in the cloud", "the laptop is overloaded", "offload the agent", "start a box", "cloud agent", or when a task drags in heavy worktrees, node_modules, or long builds. Covers the control-plane/execution split, verify-on-box, cost discipline, a GUI server on a box, and multi-harness routing.4---56# Cloud agent execution78Run the agent on a remote VM. Keep the laptop as a thin control plane. It starts9jobs, reads results, and steers. It does not host the work.1011Related: for local worktree cleanup use the `worktree-hygiene` skill. Cloud12execution does not remove local worktrees.1314## Tier split1516- Laptop = control plane. Start jobs, read diffs, decide.17- Remote VM (a "box") = execution. Clone, edit, verify, patch.18- CI runner = tests on push. Separate from the execution tier.1920Rule: heavy agent work goes to a box. Never put work or proprietary source on a21third-party box.2223## Run one cloud task2425Start a box, let the box-side agent clone the repo from origin, do the task, and26verify ON the box. Record the starting commit (`git rev-parse HEAD`) before the27agent runs. Afterward, stage untracked files (`git add -A`) and diff against that28starting commit (`git diff <start-sha>`), not a plain `git diff` — plain `git diff`29only shows unstaged changes against the index, so after `git add -A` it misses the30very files you just staged, and it misses anything the agent already committed.31Always stop the box, even on failure. A wrapper tool does this in one command (see32the implementation repo).3334Managed providers bill the box's cloud credits, not your model subscription. That35is the point: cloud credits absorb the run.3637## Verify on the box3839Judge a delegated job on the diff against the starting commit, not the exit code40or a clean working tree. An empty `git status --short` only means nothing is41uncommitted — the agent may have committed its work, so it does not by itself mean42the agent did nothing. Diff against the commit recorded before the run (see above),43not `HEAD` versus the working tree. Read the diff every time.4445## Cost discipline4647- A box bills every second it runs. A stopped box is free. Nothing stops it for48 you.49- The real lever is not leaving boxes idle. The vendor rate is not the lever.50- Track spend over time. Snapshot the provider's usage/limits to a log and report.51- Warm a box on session start, reap it on session end. Add a TTL backstop for52 killed sessions. Run a periodic reaper that measures CPU and a heartbeat, not53 the box's reported state — an "idle" box can still be at full CPU.5455## GUI server on a box5657To steer many agents by eye, run the GUI server ON the box and reach it from the58laptop browser over a public host URL.5960- Do NOT point a local GUI provider path at a box wrapper. The GUI server is the61 execution boundary; it reads git diffs off its own disk, so a wrapper that edits62 the box shows an empty changeset. Run the whole server on the box.63- Give the user systemd a bus first (enable linger). Over a headless exec, also64 export `XDG_RUNTIME_DIR` or `systemctl --user` fails.65- Run the server as a systemd user service, not a foreground process, so it66 survives an ssh disconnect. Bind `0.0.0.0`, not loopback.67- Expose the port with a PUBLIC host URL. A private, token-gated host makes the68 GUI client fail to fetch its environment endpoint.69- Mint a fresh pairing code against the running server. A service restart mints a70 new code and invalidates the old one.71- Treat the pairing code as a secret credential, not a convenience string: over a72 public host it is the only thing standing between an outsider and a server that73 runs arbitrary commands. Never log it, screen-share it, or paste it into a74 shared channel. Restrict the port at the network layer (security group or75 firewall IP allowlist) in addition to the pairing code wherever the provider76 allows it.7778## Multi-harness7980A box can host several agent CLIs. A managed "prompt" path may cover the81first-party ones with provider-managed auth. Other CLIs run as on-box tools and82need their own auth AND funding on the box. A key being present is not proof it is83funded — preflight loudly and report which providers are ready.8485## Guards8687- Personal or non-sensitive repos only on a third-party box.88- Never `rm -rf` a worktree. First confirm it is a LINKED worktree: compare89 `git rev-parse --git-dir` against `git rev-parse --git-common-dir` inside it —90 they differ only for a linked worktree; a main clone's are identical. Don't91 rely on the path containing `/worktrees/`, since a main clone checked out92 under a directory of that name would match too. Deleting a main clone destroys93 the repo.94- A box may print its full injected environment (tokens included) on a95 non-interactive `bash -c` that sources a login profile. Never pipe such output96 to a shared log. Run a script file instead; it does not source the profile.