You just got a free remote agent box running.
Does it feel like your laptop already?
Your machine has Node, Docker, and git.
Why would a shared box match that layout?
I keep watching agents fail on simple shell steps.
The model is not always the real problem.
The remote box is still not your workstation.
This FAQ is the checklist I wish I had.
What this FAQ is for
I write this as a myth list, not a product tour.
You will get claims, checks, and a corrected model.
Run the inventory before you trust any agent command.
Skip the box if your work needs a sealed machine.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
I use MonkeyCode for free model access and a free server option.
That pairing is useful for throwaway agent loops.
It is not a clone of my laptop image.
Myth 1: The working directory is always the repo root
Agents love listing files and then running tests.
They assume the shell starts inside your project.
Does your wrapper actually change directory before tools?
Have you printed the working directory on turn one?
What I check
pwd
ls -la
git rev-parse --show-toplevel 2>/dev/null || echo "no git root"
The working directory may be the home folder.
The repo may live under a nested work path.
Then every relative path becomes a lie.
A missing package file is often a directory bug.
It is not a missing dependency on its own.
Corrected model
Treat the working directory as untrusted input always.
Pin it in the wrapper, not in the prompt.
Fail the turn if the directory is not the expected root.
Myth 2: If the binary exists on my laptop, it exists here
People say just run jq on the box.
People say just run compose as usual.
Those sentences describe your local machine, not this box.
Have you asked the box what it actually has?
What I check
command -v git
command -v node
command -v python3
command -v docker
command -v jq
command -v make
uname -a
id
A missing jq binary is not a model failure.
A missing docker binary is not a prompt failure.
The agent will invent flags for tools that are absent.
That is how you get confident nonsense in the log.
Corrected model
Build an allowlist of binaries before the loop starts.
Refuse tasks that need tools outside that list.
Do not let the agent install its way into a surprise.
Myth 3: Package installs stick around across turns
You watched the agent install a Python package.
The next turn imported it without any errors.
Did that wheel land on a writable durable disk?
Or did it land in temp space that dies later?
I do not assume persistence on a free server.
I do not assume a stable site-packages path either.
Did the install even use the same interpreter?
What I check
python3 -c "import sys; print(sys.executable); print(sys.path)"
python3 -m pip show requests || true
npm root -g
echo "HOME=$HOME TMPDIR=$TMPDIR"
df -h
If home changes between turns, your cache is gone.
If the interpreter changes, the package is gone.
Success two turns ago is not a contract.
Print the interpreter after every install step.
Corrected model
Install into a path you own and then print it.
Record the interpreter hash next to the lockfile.
Re-run the show command after every sandbox recycle.
Myth 4: I can sudo, bind-mount, and run Docker like home
Locally you are in the docker group.
Locally you have passwordless sudo for a reason.
A free server is not that reason.
Can you even see the docker socket file?
What I check
sudo -n true && echo "sudo works" || echo "no sudo"
ls -l /var/run/docker.sock 2>/dev/null || echo "no docker sock"
cat /etc/os-release
ulimit -a
No sudo is a feature on a shared box.
Nested docker is a privilege you probably lack.
The agent will still propose a root package update.
That proposal copies your laptop privileges by habit.
Corrected model
Assume an unprivileged user with no nested containers.
Rewrite tasks so they only need user-space tools.
If you need Docker, skip this class of box.
Myth 5: Leftover files mean this workspace is mine
You found a node_modules folder already sitting there.
Is that a lucky cache from last turn?
Or last tenant's junk on a recycled disk?
Or is it last turn's half-finished install?
Free boxes get recycled without much ceremony.
Recycling is not the same as a cleanroom.
Did you name your workspace with a unique prefix?
What I check
find . -maxdepth 2 -type d \( -name node_modules -o -name .venv -o -name target \)
ls -la /tmp | head
stat -c '%u %U %y %n' . 2>/dev/null || stat -f '%u %Su %Sm %N' .
A warm cache can hide a dirty tree.
A dirty tree can hide a secret from a prior run.
I treat unexpected files as hostile until hashed.
Hash them or delete them before the first tool call.
Corrected model
Start from a known tarball or a git sha.
Delete or ignore anything you did not create.
Never read leftover env files as yours.
How these five myths stack
Wrong directory plus missing tools looks like a bad model.
Missing tools plus a leftover cache looks like a flaky install.
A leftover cache plus sudo dreams looks like a security incident.
I debug the stack from the box upward.
I do not start with a longer prompt.
Would you tune hyperparameters before checking the working directory?
Log signatures I watch for
-
ENOENTon a file you can see locally -
command not foundafter a confident plan -
Permission deniedon/usror docker.sock -
ModuleNotFoundErrorafter a "successful" pip log -
npm ERR!with a path outside the repo - an
.envfile whose mtime predates your task
Each signature maps to a myth above.
None of them mean the free model got worse today.
You should fix the box story first.
Turn-zero protocol
- Upload or clone one known git sha.
- Run the inventory script and store the log.
- Diff the tool allowlist against the task.
- Abort on leftovers, sudo needs, or missing markers.
- Only then should you start the agent loop.
- Re-run inventory after any suspected box recycle.
This whole protocol stays boring on purpose.
Boring checks beat a clever retry storm.
I would rather waste one minute than ten turns.
The artifact: inventory then decide
Here is the script I paste before any loop.
Label this a proposed check, not a benchmark.
I am not claiming production numbers from it.
#!/usr/bin/env bash
# box-inventory.sh -- proposed check, run inside the agent box
set -euo pipefail
echo "== identity =="
date -u +%Y-%m-%dT%H:%M:%SZ
id
hostname
uname -a
echo "== cwd and git =="
pwd
git rev-parse --is-inside-work-tree 2>/dev/null || echo "not a git work tree"
git status -sb 2>/dev/null || true
echo "== tools =="
for b in git node python3 pip3 npm docker jq make curl sudo; do
if command -v "$b" >/dev/null 2>&1; then
echo "PRESENT $b -> $(command -v "$b")"
else
echo "MISSING $b"
fi
done
echo "== python =="
python3 - <<'PY' || true
import sys, os
print("exe", sys.executable)
print("ver", sys.version.replace("\n", " "))
print("HOME", os.environ.get("HOME"))
print("TMPDIR", os.environ.get("TMPDIR"))
PY
echo "== privileges =="
sudo -n true 2>/dev/null && echo "sudo: nopass" || echo "sudo: no"
if test -S /var/run/docker.sock; then echo "docker.sock: yes"; else echo "docker.sock: no"; fi
echo "== disk =="
df -h .
df -h /tmp
echo "== leftovers =="
find . -maxdepth 3 \( -name node_modules -o -name .venv -o -name .env -o -name id_rsa \) -print 2>/dev/null | head
Run it once before the agent loop starts.
Save stdout next to the task id.
Compare the next turn against that snapshot.
Decision table
| Signal from inventory | Do not assume | Do this instead |
|---|---|---|
pwd is not the expected root |
relative paths work |
cd in the wrapper and assert |
MISSING docker or no socket |
compose files will run | rewrite to unit tests or skip |
sudo: no |
apt or yum belongs in the plan | use user-space binaries only |
| interpreter path flipped | prior pip installs survived | reinstall into a pinned venv |
leftover .env or id_rsa
|
the tree is yours | abort and start a fresh workspace |
/tmp is tiny or full |
large installs will work | fail fast with a disk check |
I want the table in the pull request template.
The agent does not get to skip the inventory.
If a cell is red, I change the task, not the prompt.
A tiny wrapper pattern
Do not bury directory changes inside a long system prompt.
Put them in the tool wrapper where they can fail.
#!/usr/bin/env bash
# run-in-repo.sh -- proposed wrapper
set -euo pipefail
ROOT="${AGENT_ROOT:?AGENT_ROOT is required}"
cd "$ROOT"
if test -f "$ROOT/package.json" || test -f "$ROOT/pyproject.toml"; then
exec "$@"
fi
echo "refusing: no project marker in $ROOT" >&2
exit 2
Then the tool only runs the wrapped test command.
If the directory is wrong, you get exit two.
You do not get a novel about missing modules.
Limitations
This inventory still does not prove strong isolation.
It does not prove the next recycle will look identical.
It does not measure model quality at all.
Free model access can change without any notice.
A free server option can vanish or throttle.
I am not claiming quotas, hardware, or uptime.
The script can still miss setuid helpers.
It can miss extra path entries the agent later exports.
It cannot see another tenant's process list on every host.
Clock skew can still confuse your later logs.
Network egress may be blocked even when curl exists.
A present binary is not the version you tested.
Who should not use this approach
Do not use a free shared box for secrets.
Do not put customer data on it.
Do not run production deploys from it.
Skip this if you need nested containers.
Skip this if you need a stable IP.
Skip this if compliance needs a named host.
If your task needs a laptop replica, image your own VM.
This FAQ is for throwaway agent work only.
It is not a hardening guide for multi-tenant kernels.
What I want you to try
Print the directory, user, and tool allowlist first.
Then let the model work on the task.
If you try this, tell me which row went red.
Top comments (0)