I keep watching the same collapse in agent threads.
People glue the model and the server into one blob.
Why do we keep treating them as one process?
A free model answers in text you can quote.
A free server holds a working tree and a shell.
Those remain two machines inside a single conversation.
The walkthrough uses MonkeyCode free model access and a free server option.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
I will treat those two free surfaces as given facts.
I will not invent model names, quotas, or hardware.
The false merge
You paste a file into the chat transcript.
The model appears to possess the whole project.
Does that feeling prove the file exists on disk?
That jump from tokens to inodes is the real bug.
Git stays the only honest bridge between those worlds.
Myth 1: The model mounted your repo as disk
Developers repeat this while skipping tool reads.
It already has the project, so extra files waste turns.
Does thrift count if the model is reading a ghost?
The model holds tokens inside one prompt window.
The server holds inodes inside a real filesystem.
Those two caches never meet without an explicit read.
Falsify the myth with one boring command on the box.
git rev-parse --show-toplevel
git status --short
git ls-files | wc -l
Then ask the model to name three dirty files.
Deny it a tool call for that first answer.
A guess means context just posed as disk again.
Corrected model
I now treat every paste as a temporary excerpt.
The bulk of the tree stays on the server.
Dumping a forest blows the window for no gain.
Decision: send it, or leave it on disk?
Use this proposed table before the next paste.
It is a checklist, not a harvested production study.
| Thing | Send to the model? | Leave on the server? |
|---|---|---|
| Lockfile name plus a short hash | Yes | Yes, always |
Whole node_modules tree |
No | Yes |
| Last 50 lines of failing tests | Yes | Yes, as a file |
| Binary assets and build output | No | Yes |
Values from .env files |
No | No, keep them out |
| One failing source file | Yes | Yes |
Myth 2: A free server is clean, so skip lockfiles
This claim appears after every fresh looking box.
The server is empty, so let the model pick versions.
Have you watched that install drift before lunchtime?
A free server is still a real Unix account.
Public package registries still move under your feet.
Your future clone still has to replay that graph.
Check for a lockfile before any install command lands.
ls -1 package-lock.json yarn.lock pnpm-lock.yaml \
Cargo.lock go.sum poetry.lock uv.lock Gemfile.lock 2>/dev/null
Empty output is how a weekend incident usually starts.
Do not let the model invent a dependency graph.
Corrected model
The box may be free of an invoice today.
The lockfile is still mandatory for a replay.
Commit it, restore from it, and stop hand waving.
Myth 3: The model wrote a command, so it ran
Chat is not a shell receipt, however confident it sounds.
A fenced block is a suggestion until something returns.
Did the box actually execute that shell command today?
Who captured stdout, stderr, and the numeric exit code?
I want this proposed receipt around every claimed run.
# Proposed receipt. Unexecuted until the box prints EXIT.
set -eu
cmd='python -m pytest -q'
echo "CMD ${cmd}"
echo "CWD $(pwd)"
echo "HEAD $(git rev-parse --short HEAD)"
set +e
eval "${cmd}"
echo "EXIT $?"
Treat that snippet as unexecuted until EXIT appears.
If the model summarizes tests without EXIT, it narrated.
Narration is not evidence, even on a free server.
Corrected model
Text can propose a command in a fenced block.
The server returns integers you can quote later.
No integer means you still have zero claim.
Myth 4: Free means you can skip toolchain pins
People say the sandbox can run whatever python exists.
Then the agent writes syntax the box cannot parse.
Sound familiar after a green chat and a red shell?
Free does not mean the compilers became unversioned.
Print the toolchains before the first generated edit.
command -v python3 && python3 --version
command -v node && node --version
command -v go && go --version
command -v rustc && rustc --version
Put those lines into the ticket or the receipt.
The model should target that output, not your laptop.
Your laptop is not in this loop at all.
Corrected model
Pin every binary you actually intend to invoke.
Record the versions next to the commit hash.
Do not let the word free erase those versions.
Myth 5: The model and server share memory across turns
This glue myth quietly feeds the other four.
It already knows because I told it last turn.
Knows where, in the transcript, on disk, or in git?
Transcripts drop when a session ends or trims.
I will not pretend I know when boxes recycle.
If the fact matters, write it into a file.
mkdir -p .agent
{
echo "head=$(git rev-parse HEAD)"
echo "branch=$(git branch --show-current)"
echo "lockfiles=$(ls -1 *lock* 2>/dev/null | tr '\n' ' ')"
} > .agent/last-receipt.txt
cat .agent/last-receipt.txt
That file looks boring, and that is the point.
Boring files survive a brand new chat window.
Can your model quote head= without inventing digits?
Corrected model
Durable memory is git plus files you actually named.
The model remains a guest holding a clipboard.
Clipboards are not backups, even when they feel vivid.
One script that attacks all five myths
This proposed checklist is not a vendor benchmark.
Save it as scripts/box_vs_model_check.sh on the server.
Run it, paste the output, and stop guessing paths.
#!/usr/bin/env bash
set -euo pipefail
# Proposed checklist. Unexecuted until you run it on the box.
echo "=== identity ==="
echo "host=$(hostname)"
echo "user=$(id -un)"
echo "pwd=$(pwd)"
echo "date=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "=== git ==="
git rev-parse --is-inside-work-tree
echo "head=$(git rev-parse HEAD)"
echo "branch=$(git branch --show-current)"
git status --short
echo "=== lockfiles ==="
shopt -s nullglob
locks=(package-lock.json yarn.lock pnpm-lock.yaml Cargo.lock go.sum poetry.lock uv.lock Gemfile.lock)
if ((${#locks[@]}==0)); then
echo "LOCKFILES missing"
else
printf '%s\n' "${locks[@]}"
fi
echo "=== toolchains ==="
for c in python3 node go rustc java ruby php; do
if command -v "$c" >/dev/null 2>&1; then
echo "$c=$("$c" --version 2>&1 | head -n 1)"
fi
done
echo "=== reminder ==="
echo "Model context is not this output."
echo "Paste this receipt. Do not paraphrase it."
If the model restates the script without output, fail it.
Ask it to quote the head= line from the receipt.
Guessing means it never looked at the server.
Optional path audit
Here is a proposed Python helper for claimed paths.
It is unexecuted until you run it beside git.
#!/usr/bin/env python3
"""Proposed audit. Compare claimed paths to git ls-files."""
import subprocess
import sys
claimed = [line.strip() for line in sys.stdin if line.strip()]
listed = subprocess.check_output(["git", "ls-files"], text=True).splitlines()
listed_set = set(listed)
print("claimed", len(claimed))
print("tracked", len(listed_set))
for path in claimed:
if path in listed_set:
print("TRACKED", path)
else:
print("NOT_TRACKED", path)
Pipe paths into it, one file per line.
NOT_TRACKED means the model talked about a ghost.
A turn I actually trust
- Run the checklist on the server first.
- Paste the receipt, not a paraphrase of it.
- Edit only files named in the failing test.
- Re-run the command and keep the new EXIT.
- Commit only after git status matches the story.
What this workflow is actually for
I use this split during refactors and failing tests.
Small patches belong here if receipts stay visible.
Protected branches still need your real CI later.
Limitations
This checklist does not measure any model quality.
It does not prove tenant isolation on the box.
It does not pin CPU, RAM, disk, or lifetime.
Those numbers stay absent because I will not invent them.
The script needs git plus a POSIX shell.
Windows agents need a different wrapper before this runs.
I did not run a fleet study for this draft.
Who should not use this approach
- Skip it if you cannot run commands on the box.
- A chat-only window cannot falsify myths three and five.
- Skip it when the tree contains secrets or credentials.
- Env files do not belong in prompts or receipts.
- Skip it if you think this is a production deploy.
- A free server stays scratch space until pipelines agree.
- Skip it when your team already locks remote builder images.
- You already solved the split, so do not duplicate boxes.
The mental model I want on the wall
Keep three nouns in view during every agent turn.
The model proposes reads and possible shell commands.
The server executes commands and stores the working tree.
Git remembers what you are willing to replay later.
Free access does not merge those three nouns together.
It only removes the invoice while you learn the split.
Are you already holding a free model plus a free server?
Run the checklist once before trusting the next confident paragraph.
Top comments (0)