Did a green sandbox just steal your release process?
I see that swap after almost every agent demo.
The chat looks healthy, so someone hits merge.
A transcript alone is not a release gate.
A passing sandbox is only a weak clue.
Who signed the artifact you plan to ship?
What this FAQ actually covers
I mean two free things, not one blob.
A free model proposes commands, patches, and explanations.
A free server may execute some of those commands.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
MonkeyCode gives free model access and a free server option.
I use that pair as a scratch pad only.
I still refuse to ship from the chat.
This FAQ busts five promotion myths on purpose.
Each one turns a scratch run into a fake gate.
I want a corrected mental model, plus commands.
Myth 1: Green on the box means merge it
Claim: The agent ran tests, so we merge.
What you saw: A cheerful summary plus an exit code.
What is true: You saw one scratch environment, one time.
You did not see GitHub Actions or GitLab CI.
You did not see the pull request HEAD under policy.
Ask the run this way, out loud.
What commit did the tests actually touch?
What lockfile hash sat on disk then?
If you cannot answer, you cannot merge.
Do not argue with the transcript about feelings.
Argue with HEAD, porcelain, and the lockfile digest.
git rev-parse HEAD
git status --porcelain
git diff --stat
git log -1 --oneline
Empty porcelain is not optional on this path.
It is the first filter before merge.
A dirty tree means you tested a ghost.
- Wrong model: Chat green equals pipeline green exactly.
- Corrected model: Chat green means worth sending to CI.
Myth 2: The model and the server share one brain
Claim: The model has the repo because the box cloned it.
What you saw: The model quoted a file you already recognize.
What is true: Context tokens are not the filesystem bytes.
The model can quote a stale buffer.
The server can hold a different tree.
Did the model read the lockfile or invent a range?
Did the server actually contain that exact file?
Prove it with a hash, not with a vibe.
# Label: template. Run on the execution box.
git rev-parse --show-toplevel
test -f package-lock.json && sha256sum package-lock.json
test -f poetry.lock && sha256sum poetry.lock
test -f go.sum && sha256sum go.sum
test -f Cargo.lock && sha256sum Cargo.lock
If the chat cannot show that hash, distrust the quote.
Ask for sha256sum output in the same turn.
Refuse a paraphrase of the file instead.
Quoted text is a rumor about a path.
Disk bytes are a current snapshot.
Git objects are the only review target.
- Wrong model: Quoted text means the current disk.
- Corrected model: Quote, disk, and git are three layers.
Myth 3: An install in chat makes the lockfile honest
Claim: It installed the dependency, so the lock is fine.
What you saw: npm or pip printed a happy success line.
What is true: A live install can mutate the box.
It may never mutate the committed lockfile copy.
Tomorrow CI will install from git, not memory.
Which file will your CI actually read?
The committed lock, not last night's shell.
Shell history is not a package manager.
# Template: fail if lockfiles drifted after the agent "helped"
git diff --exit-code -- package-lock.json poetry.lock go.sum pnpm-lock.yaml Cargo.lock
git ls-files -m
npm ls --depth=0 2>/dev/null || true
If that command fails, the chat lied.
You are looking at a mutated sandbox.
CI will not see those extra packages.
Pin the question on one path.
Was package-lock.json in the commit?
Or only in /tmp after a chat install?
- Wrong model: Successful install equals reproducible install.
- Corrected model: Only a committed lockfile is reproducible.
Myth 4: Agent-written tests are independent evidence
Claim: It wrote tests and they passed. Ship.
What you saw: A new test file and a green bar.
What is true: The same author graded its own homework.
That is a useful draft, not independent proof.
I still want tests a human can read.
Did the tests assert behavior, or only cheer?
Did they mock the thing that actually breaks?
Open the file and read every assert.
Then rerun the suite outside the chat.
The chat is a biased interpreter here.
A second process is the smallest upgrade.
# Template: rerun without the chat as interpreter
git diff --stat -- '*test*' '*spec*'
python -m pytest -q
# or
npm test --silent
# or
go test ./...
Green here still is not production truth.
It is only a second, less circular sample.
I also want one test a teammate wrote earlier.
Circular evidence is the quiet myth.
The agent authors the code, the tests, and the report.
That is one witness with three hats.
- Wrong model: More agent tests mean more proof.
- Corrected model: Independent tests mean more proof.
Myth 5: The box HEAD is the pull request HEAD
Claim: We tested the PR. The box had the branch.
What you saw: A branch name inside a prompt.
What is true: Branch names are not commit SHAs at all.
The box can be dirty, detached, or wrong.
Your merge button cares about the remote SHA.
echo "local $(git rev-parse HEAD)"
echo "branch $(git rev-parse --abbrev-ref HEAD)"
git rev-parse --abbrev-ref @{u} 2>/dev/null || echo "no upstream"
git status -sb
If local HEAD does not match the PR SHA, stop.
You tested a cousin commit, not the review SHA.
Rename the myth: we tested a nickname, not a digest.
Paste the SHA from the hosting UI.
Do not paste the branch name from memory.
Then ask the box to print HEAD again.
- Wrong model: Branch name identity equals commit identity.
- Corrected model: Only the full SHA is the review target.
Sixty seconds before you hit merge
I ask four questions in standup voice.
Not in the chat. Out loud, to myself.
- What SHA did CI already finish?
- What SHA did the sandbox print?
- Do those two strings match exactly?
- What lockfile hash is in git?
If I stumble, I do not merge.
Stumbling is data. It means the story is thin.
A thin story is how scratch boxes become prod.
The artifact: a promotion gate script
I do not trust a paragraph that says all good.
I trust a small file I can rerun.
Here is a template script, not a product.
Label this block as unexecuted template code.
Adapt paths before you trust any exit code.
Do not treat a local pass as a signature.
#!/usr/bin/env bash
# promote_check.sh — template, not a scored benchmark
set -euo pipefail
PR_SHA="${1:-}"
if [[ -z "${PR_SHA}" ]]; then
echo "usage: $0 <pr-sha>" >&2
exit 2
fi
if [[ -n "$(git status --porcelain)" ]]; then
echo "FAIL: dirty worktree" >&2
git status --porcelain
exit 1
fi
HEAD="$(git rev-parse HEAD)"
if [[ "${HEAD}" != "${PR_SHA}" ]]; then
echo "FAIL: HEAD ${HEAD} != PR ${PR_SHA}" >&2
exit 1
fi
mkdir -p .promotion
{
echo "head ${HEAD}"
date -u +"%Y-%m-%dT%H:%M:%SZ"
for f in package-lock.json poetry.lock go.sum pnpm-lock.yaml Cargo.lock; do
if [[ -f "${f}" ]]; then
sha256sum "${f}"
fi
done
} | tee .promotion/scratch.txt
if [[ -f package.json ]]; then
npm test
elif [[ -f pyproject.toml || -f pytest.ini || -f setup.cfg ]]; then
python -m pytest -q
elif [[ -f go.mod ]]; then
go test ./...
else
echo "FAIL: no known test runner" >&2
exit 1
fi
echo "PASS: scratch checks only. CI still owns release."
Call it with a real SHA from the PR page.
chmod +x promote_check.sh
PR_SHA="paste-the-pr-head-sha-here"
./promote_check.sh "${PR_SHA}"
Store .promotion/scratch.txt next to the pipeline log.
Do not store a screenshot of the chat.
Screenshots do not replay.
Decision table I actually use
| Question | If no, you do not promote |
|---|---|
| Did HEAD match the PR SHA? | Stop. Wrong tree. |
| Was the worktree clean? | Stop. Hidden files. |
| Did the lockfile hash match git? | Stop. Install mutated state. |
| Did tests run outside the chat? | Stop. Circular grade. |
| Did CI run on that same SHA? | Stop. Sandbox is not CI. |
That last row is the whole article.
The sandbox can inform you, never bless you.
Promotion is a comparison of SHAs, not vibes.
What this loop does not prove
This script does not prove real production behavior.
It does not prove load, auth, or migrations.
It does not pin a base image or architecture.
I am not claiming runtime numbers here.
I am not claiming quotas, models, or hardware.
A free server is still one machine.
It also does not replace code review.
A clean worktree can still hold a bad idea.
Hashes do not measure product sense.
Who should not use this loop
Do not use this as a replacement for CI.
If you have no remote pipeline, build one first.
This script is a pre-check, not a signature.
Skip it if your release needs signed provenance.
Skip it if you cannot name the PR SHA.
Skip it if the sandbox holds production secrets.
Also skip it if you will ignore red.
A checklist you override is only theater.
I would rather you skip than fake a gate.
The mental model I want you to keep
Treat the free model as a noisy proposer.
Treat the free server as a disposable workbench.
Treat git SHAs and CI logs as evidence.
The chat can draft the next command.
The chat cannot sign the actual release.
Why would you let a transcript do that?
Keep this script in the repo anyway.
Throw away the ship-from-chat habit today.
Who owns your release gate tomorrow morning?
Top comments (0)