What did the agent inherit before it touched a file? I keep hearing five confident claims about scratch hosts.
They sound like careful engineering. They usually are not.
A throwaway host is not a clean room. A new chat is not a new machine. Can you prove the disk state tonight?
Why these myths survive
Agents fail in boring, local ways. Leftover caches. Stale env files. A lockfile copied from another branch.
Then someone pastes "tests passed" into a thread. Nobody asks which tree those tests actually saw.
This FAQ is a myth list plus one replayable inventory. Treat every green claim as guilty until hashed.
Where a free model and free server actually help
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
I use MonkeyCode when I want free model access and a free server together. That pairing is handy for workspace checks I refuse to run beside laptop secrets.
Remove every product name and the method still stands. I will not invent quotas, model names, or hardware here.
You still own the hashes. The disk still lies if you skip the inventory.
Myth 1: A new session means a clean filesystem
The claim I hear: I started a new agent session, so the disk is empty.
A session is a conversation handle. A filesystem is blocks on disk. Those two clocks do not reset together.
Directories survive the chat. Package caches survive the chat. Editor swap files survive the chat. Why would they vanish for your convenience?
Corrected model
- Inventory the host before the first prompt.
- Hash the tree after the last prompt.
- Treat that delta as the real work, not the chat summary.
Ask yourself one rude question. What existed at T0?
If you cannot answer T0, you cannot explain T1. The agent did not start from math. It started from whatever the last tenant left behind.
Myth 2: git status green means the host is clean
The claim I hear: git status is clean, so nothing leftover exists.
Git tracks tracked files. It does not track node_modules. It does not track .env.local. It does not track build/ or .pytest_cache.
An agent can leave a binary outside the repo. It can leave a listener on port 3000. It can mutate a global package cache you never commit.
Corrected model
- Keep
git status --porcelain=v1as a required artifact. - Pair it with a process list and open ports.
- Add a hashed file manifest for untracked paths.
If you only screenshot git status, you audited a subset. The subset is the polite part of the disk.
git rev-parse HEAD
git status --porcelain=v1
git ls-files -o --exclude-standard | head
ps -u "$(id -u)" -o pid,ppid,etime,cmd | head
Does that look like a clean room? Or like a kitchen after catering?
Myth 3: install on the host matches my laptop
The claim I hear: I ran install, so dependencies match local.
Did you pin the runtime version? Did you commit the lockfile? Did the agent edit the manifest and skip the lock?
Scratch hosts drift. Laptops drift harder. Optional dependencies flip on OS and CPU.
A green install is not a green graph. A matching folder name is not a matching tree.
Corrected model
- Record runtime versions before any install command.
- Keep the lockfile inside the artifact bundle.
- Compare install graphs with a hash, not a feeling.
command -v node && node -v
command -v python3 && python3 --version
test -f package-lock.json && sha256sum package-lock.json
test -f poetry.lock && sha256sum poetry.lock
# Proposed check. Label unexecuted until you run it.
npm ls --omit=dev --parseable 2>/dev/null | sha256sum
If the lockfile moved and nobody noticed, the model did not "just install." It changed the contract.
Myth 4: stopping the agent wipes side effects
The claim I hear: I stopped the loop, so side effects are gone.
Killing a parent does not kill every child. Background servers linger. File watchers linger. Containers linger.
A "successful" stop can still leave a mutated volume. It can still hold a port. It can still dirty the next session.
Corrected model
- Track the process group you started, not the chat tab.
- Kill the group on purpose.
- Re-run the inventory. If it moved, you did not stop.
# Proposed stop checklist. Do not skip the last line.
pkill -TERM -P "$AGENT_PGID" || true
sleep 1
ss -lnt | tee ports.after
./workspace_inventory.sh ./after-stop.txt
diff -u ./before.txt ./after-stop.txt | tee stop.delta
Would you trust a teammate who said "I closed the terminal"? Then why trust the agent loop?
Myth 5: the model saw the same tree I pushed
The claim I hear: I pushed the branch, so the agent read that commit.
Did it read HEAD? Or a dirty worktree plus untracked junk? Did a previous patch remain uncommitted on that host?
Agents often cat a few files. They rarely prove they observed the commit you think they observed. A chat recap is not git rev-parse.
Corrected model
- Print commit, status, and a manifest before the model acts.
- Attach those artifacts to the session notes.
- Missing artifacts mean unknown inputs. Unknown inputs mean unknown outputs.
echo "head=$(git rev-parse HEAD)"
echo "dirty=$(git status --porcelain=v1 | wc -l)"
find . -name '*.env*' -o -name '*.local' | head
If those lines are missing, you do not know what the model saw. You only know what it claimed.
Artifact: a replayable workspace inventory
This script is a proposed helper. Label it unexecuted until you run it on your box.
Do not treat my paste as a benchmark. It is a camera, not a judge.
#!/usr/bin/env bash
# workspace_inventory.sh
# Proposed helper. Capture a scratch-host snapshot you can diff later.
set -euo pipefail
OUT="${1:-./inventory-$(date -u +%Y%m%dT%H%M%SZ).txt}"
ROOT="${2:-.}"
{
echo "# workspace inventory"
echo "utc=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "host=$(hostname)"
echo "pwd=$(pwd)"
echo "user=$(id -un)"
echo
echo "## runtimes"
command -v node >/dev/null && echo "node=$(node -v)" || echo "node=missing"
command -v python3 >/dev/null && echo "python3=$(python3 --version 2>&1)" || echo "python3=missing"
command -v git >/dev/null && echo "git=$(git --version)" || echo "git=missing"
echo
echo "## git"
if git -C "$ROOT" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo "head=$(git -C "$ROOT" rev-parse HEAD)"
echo "branch=$(git -C "$ROOT" branch --show-current || true)"
echo "status_porcelain="
git -C "$ROOT" status --porcelain=v1
echo "untracked_sample="
git -C "$ROOT" ls-files -o --exclude-standard | head -n 50
else
echo "git=not_a_repo"
fi
echo
echo "## processes (user)"
ps -u "$(id -u)" -o pid,ppid,etime,cmd | head -n 80
echo
echo "## listeners"
if command -v ss >/dev/null; then
ss -lnt 2>/dev/null || true
else
echo "ss=missing"
fi
echo
echo "## env names only"
env | awk -F= '{print $1}' | sort
echo
echo "## file manifest (path mode size hash)"
find "$ROOT" -type f \
! -path '*/.git/*' \
! -path '*/node_modules/*' \
! -path '*/.venv/*' \
| sort \
| head -n 4000 \
| while IFS= read -r f; do
stat -c '%n %a %s' "$f" 2>/dev/null || stat -f '%N %Lp %z' "$f"
sha256sum "$f" 2>/dev/null || shasum -a 256 "$f"
done
} > "$OUT"
echo "wrote $OUT"
Run it as a sandwich around the agent, not as a vibe check after Slack.
chmod +x workspace_inventory.sh
./workspace_inventory.sh ./before.txt
# ... agent loop happens here ...
./workspace_inventory.sh ./after.txt
diff -u ./before.txt ./after.txt | tee workspace.delta
Copy before.txt, after.txt, and workspace.delta off the host. A vanished scratch disk is not an archive.
Decision table: can I trust this green result?
| Signal you have | What it actually proves | Trust it? |
|---|---|---|
| Chat said "done" | The model produced words | No |
git status clean |
Tracked files match HEAD | Not alone |
| Tests printed "passed" | Some runner ran something | Not until you pin HEAD, runtime, and lockfile |
| Before/after inventory matches except intended paths | Disk delta is bounded | Yes, for this host, this run |
| Inventory missing | You observed a story | No |
| Ports still listening after stop | Side effects survived | No |
| Lockfile hash changed | Dependency contract moved | Only after you read the lock diff |
Print this table next to the PR. If a cell is empty, the PR is empty too.
One-hour test plan (proposed)
Do this on a throwaway host. Do not do this on a machine holding production secrets.
- Snapshot T0 with
workspace_inventory.sh ./before.txt. - Note
head, runtime versions, and lockfile hashes by hand. - Ask the agent for a tiny, reversible change. One file. One test.
- Snapshot T1 with
./workspace_inventory.sh ./after.txt. - Diff the inventories. Circle every path you did not request.
- Stop the agent. Snapshot again. Confirm ports and child processes died.
- Replay the same prompt once. Diff the two after-files. Same prompt is not same patch.
What failed first for you? The dirty disk, the lockfile, or the leftover port?
I am not reporting numbers from this plan. It is a camera checklist. Your hashes will differ. That is the point.
Limitations
The script truncates long trees with head. Huge repos will hide files. Hashing skips node_modules and .venv on purpose, so install drift needs a separate graph hash.
hostname and user are not identity proofs. Env names are listed without values because values become secrets in logs. That tradeoff hides some bugs.
A free server can vanish under you. If artifacts never left the box, you have folklore. Folklore is not a build.
This is not CI. This is not an attested pipeline. This is a way to stop lying to yourself about T0.
Who should not use this approach
Skip this if you need bit-for-bit release evidence. An inventory text file will not satisfy that bar.
Skip this if you planned to park production credentials on a scratch host. Do not. The inventory lists env names for a reason.
Skip this if your team already has hermetic builders and ephemeral VMs with proven wipe. You already own a stronger T0. Do not dilute it with a chat window.
Skip this if you will not copy artifacts off-box. A clean story on a dead disk is still a dead story.
What I want you to ask next time
Did the scratch host start empty? Show T0.
Did git status cover the disk? Show untracked paths and ports. Did install match your laptop? Show the lock hash and the runtime.
Did stop mean stop? Show the after-stop delta. Did the model see the commit you pushed? Show HEAD before the first tool call.
Run the before and after inventories once. Then argue with the delta, not the chat.
Top comments (0)