Did the free model run tests, or only narrate a green build?
I keep seeing those two events glued together in reviews.
People paste a chat log and call it a passing pipeline.
Why this mix-up keeps winning
Free model access can feel like a complete lab bench.
A free server option can feel just like your laptop.
Those two gifts are not interchangeable at all.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
MonkeyCode offers free model access and a free server option.
That pairing is useful, and it is also easy to mash.
The rest of this FAQ exists to un-mash them.
I will not invent quotas, hardware, duration, or model names.
How to read each myth
Every myth is a sentence I hear during review.
Then I show a check you can run yourself.
Then I state the corrected mental model in plain words.
Treat every script as a labeled proposal, not a benchmark.
I am not publishing latency numbers or model names here.
Myth 1: A free model is already a free server
Do you hear this one after a long chat session?
Reviewers say the free model already ran the tests.
Did those tests actually run on a process table?
A model can emit npm test without spawning npm.
A server can spawn npm without the model seeing stdout.
Those failure domains do not share a single log.
You need two proofs, not one fluent paragraph.
Evidence you can collect
Run the probe on the box, not inside the transcript.
Copy the snippet, then read the file it writes.
# proposal: capture execution, not narration
set -euo pipefail
{
date -u
pwd
id
command -v node || true
command -v python3 || true
echo "probe_ok"
} | tee /tmp/box-probe.txt
echo "probe_exit=$?"
If those commands never ran, the model only talked.
If they ran, you still need the captured exit code.
Corrected mental model
Free model access is a completion channel for text.
A free server is an execution channel for processes.
Budget them as two resources, never as one blob.
Myth 2: The chat said the build succeeded
Would you merge because a teammate smiled in Slack?
Then why merge a smiling paragraph from a model?
I want the compiler exit code sitting on disk.
I want the log file sitting next to the artifact.
I do not want a paraphrase of hope from a transcript.
Evidence you can collect
Redirect the real build and do not trust a summary.
Keep the integer that the process actually returned.
# proposal: real build, real artifacts (bash)
set -o pipefail
npm ci
npm test | tee /tmp/test-out.log
echo "npm_test_exit=${PIPESTATUS[0]}" | tee /tmp/test-exit.txt
ls -l dist 2>/dev/null || ls -l target 2>/dev/null || true
sha256sum /tmp/test-out.log /tmp/test-exit.txt
Ask one rude question after the files exist.
Does npm_test_exit exist outside the chat transcript?
If the only proof is prose, you still have no proof.
Corrected mental model
Chat success is a claim written in fluent English.
Process success is a status integer from the kernel.
Keep the integer, then keep the log that produced it.
Myth 3: The repo is on disk, so the model saw every file
Can the box hold a full working tree in peace?
That still does not fill the model prompt by itself.
Did it read the Dockerfile, or only mention Docker?
Did it read the workflow files, or guess their shape?
Disk is not context, and context is not disk.
Evidence you can collect
List what exists, then demand a quote from disk.
A clone can succeed while attention still fails.
# proposal: what exists vs what was cited
git rev-parse --show-toplevel
git rev-parse HEAD
git ls-files | wc -l
git ls-files | grep -E "Dockerfile|lock|.github" | head
I like a cheap canary file for attention checks.
Drop it in the clone before the next prompt.
# proposal: a canary the model must quote
echo "canary-$(date -u +%s)-$RANDOM" | tee CANARY_LINE.txt
If the model cannot quote the canary, it did not read it.
Do not confuse clone success with a full-file read.
Corrected mental model
The server stores bytes on a real filesystem.
The model samples tokens from a truncated prompt.
A successful clone is not a successful read.
Myth 4: One green free-box run replaces CI
Was the free box your actual release image today?
Did it pin the same Node version as production?
Did it honor the lockfile, or a lucky module cache?
I do not treat a borrowed box as GitHub Actions.
I do not treat that box as a signed builder.
Evidence you can collect
Fingerprint the box. Compare the file against CI logs.
If the hashes diverge, the green run lives elsewhere.
# proposal: toolchain fingerprint
{
echo "node=$(node -v 2>/dev/null || echo missing)"
echo "npm=$(npm -v 2>/dev/null || echo missing)"
echo "python=$(python3 --version 2>/dev/null || echo missing)"
echo "os=$(uname -a)"
echo "head=$(git rev-parse HEAD)"
echo "dirty=$(git status --porcelain | wc -l)"
echo "lock_npm=$(sha256sum package-lock.json 2>/dev/null | awk '{print $1}')"
echo "lock_py=$(sha256sum poetry.lock 2>/dev/null | awk '{print $1}')"
} | tee /tmp/box-fingerprint.txt
Decision table I keep in the PR
| Claim in the chat | Inspect on the box | Merge only if |
|---|---|---|
| Tests passed | Exit file plus log | Exit is 0 and log exists |
| Build succeeded | Artifact hashes | Artifacts match this commit |
| Same as CI | Toolchain fingerprint | Versions and lockfiles match |
| I read the repo | Canary line quoted | Quote matches the file |
| Secrets never leaked | Env and history scan | No token in env or git |
Read the table left to right, never right to left.
The chat column is only the rumor you heard.
The inspect column is the work you still owe.
Corrected mental model
A free server is a scratch executor for exploration.
CI is a policy executor with pins and reviewers.
Scratch output can inform you during an exploration pass.
Policy output can release you after humans review pins.
Do not let the first column retire the second.
Myth 5: The box is free and throwaway, so secrets are cheap
Is the box yours, or is it merely available today?
Free often means shared, recycled, or inspected later.
I do not paste cloud keys into a scratch shell.
I do not copy a dotenv file into the clone.
Just this once is how tokens end up in transcripts.
Evidence you can collect
Hunt accidental secrets before you type another prompt.
If anything hits, rotate it before the next command.
# proposal: hunt accidental secrets
env | grep -Ei "key|token|secret|password|aws|npm_" || true
grep -RInE "AKIA|ghp_|github_pat_|xoxb-|BEGIN PRIVATE" . 2>/dev/null | head
git log -p --all -- . | grep -Ei "api_key|secret" | head || true
Do not argue with the box about good intentions.
Rotate the credential first, then debate the threat model.
Corrected mental model
A price of zero is not a threat model.
A free server still has a filesystem and memory.
Treat that box like a cafe laptop on shared wifi.
A workflow that refuses all five myths
Want a sequence that blocks the mix-up on purpose?
Use this labeled proposal on a throwaway clone only.
#!/usr/bin/env bash
# proposal: prove-box.sh — run on the server, keep the log
set -euo pipefail
OUT="${1:-/tmp/prove-box.log}"
{
echo "## host"
date -u
uname -a
pwd
echo "## git"
git rev-parse HEAD
git status --porcelain || true
echo "## toolchain"
command -v node >/dev/null && node -v || echo "node=missing"
command -v python3 >/dev/null && python3 --version || echo "python3=missing"
echo "## lockfiles"
sha256sum package-lock.json pnpm-lock.yaml poetry.lock go.sum Cargo.lock 2>/dev/null || true
echo "## canary"
if [[ -f CANARY_LINE.txt ]]; then
echo "canary=$(cat CANARY_LINE.txt)"
else
echo "canary=MISSING"
fi
} | tee "$OUT"
echo "wrote $OUT"
Then run your real tests with the same redirection habit.
Then commit nothing until you read that log yourself.
I want three artifacts before I trust a fluent sentence.
- The fingerprint file captured on the box during this run.
- The test log that still contains an explicit exit code.
- A git diff that I inspected without the model talking.
Miss one of those three, and you are back in myth land.
What this workflow is not
This workflow is not a software provenance system.
It is not a promise that free servers match production.
It does not name models, quotas, hardware, or duration.
Those details change, and I will not invent them here.
It also does not make a free box your secret store.
Keep credentials off the scratch executor on purpose.
Who should skip this approach
Skip it if your data cannot leave your laptop.
Skip it if you need bit-identical release builders.
Skip it if you cannot rotate a leaked token today.
Skip it if your org forbids third-party execution hosts.
In those cases, keep generation local, or skip generation.
The same checks still apply on your own CI runners.
Limitations I will not paper over
A neat checklist can still be ignored by tired reviewers.
The model can quote a canary and still miss a CVE.
The server can exit zero on a skipped test suite.
Installing without the lockfile remains a lucky ritual.
I also cannot see your box from this article.
You still have to run the commands and keep the files.
The mental model I want you to keep
Ask three questions before you merge the agent branch.
What completed in text, what executed, and what was pinned?
If you cannot answer with files, you only have vibes.
Free models help when the question is still language.
Free servers help when the question is a process exit.
Neither channel is your release policy by itself.
If a free box is already open, save the fingerprint first.
Top comments (0)