The first fifteen minutes fail on identity, not intelligence, and that is the whole argument. Your agent can sound fluent while editing a tree you are not watching, and the UI will still show a friendly cursor. I treat that as a developer-experience defect sitting under the onboarding chrome, because a wrong root makes every later patch look like a personality problem. Why would I trust a model that has not yet proved it can round-trip a file through the same path it plans to patch?
I learned to stop asking the assistant for a tour of the repository in those opening minutes. Tours are cheap talk, and cheap talk does not collide with disk. The session needs a physical echo, something like tapping a hull to hear whether you are standing in a real boat. Write a nonce with the agent's own write tool, read it with the agent's own read tool, and only then allow a patch. If that loop is broken, nothing else in the first quarter hour is worth decorating.
Have you noticed how often the pain shows up around minute twelve, right after the first supposedly successful edit? The file appears in the transcript, the diff looks tidy, and your editor stays stubbornly unchanged. Sometimes the process is in a container whose workdir is a shallow copy of last week's clone. Sometimes a language server is bound to a local folder while the shell is bound to a remote one. The feeling is that the tool is almost working, which is worse than a hard crash, because you keep feeding it context like a person shouting through the wrong apartment door.
A free remote box makes this failure mode louder, not quieter, because you now have three clocks in play. There is the laptop editor, the SSH or browser session, and the model that only sees tool results. MonkeyCode is relevant here only because it offers free model access and a free server option, which is the combination that tempts you to skip the hull tap. Disclosure: This article was prepared as part of MonkeyCode's product outreach. I am not assigning model names, quotas, hardware, or permanence to that product, and you should not either unless you have checked the current product page yourself.
The probe I actually want in the session is small enough to paste, and I want it boring. Boring is the point. If the agent cannot do boring, it should not do clever, and it definitely should not refactor your auth module while still lost in /tmp.
# prove_path.sh — labeled example, run in the directory you believe is the project root
set -euo pipefail
ROOT="$(pwd)"
NONCE="probe-$(date +%s)-$RANDOM"
TARGET="$ROOT/.agent-nonce"
printf '%s\n' "$NONCE" > "$TARGET"
GOT="$(cat "$TARGET")"
echo "root=$ROOT"
echo "target=$TARGET"
echo "nonce=$NONCE"
echo "got=$GOT"
if [ "$GOT" != "$NONCE" ]; then
echo "FAIL: readback mismatch" >&2
exit 1
fi
echo "PASS: round-trip through $TARGET"
I ask the agent to execute that script with the same tool channel it will later use for patches, not with a story about what it would run. Then I ask it to print pwd, ls -la .agent-nonce, and git rev-parse --show-toplevel in one breath. If those three answers disagree with the window I am staring at, the session is still in the lobby. Would you let a plumber tile a bathroom before confirming the water is the water from this apartment?
There is a second, slightly meaner version for teams that keep Node nearby, because JavaScript tools love to resolve a different root than your shell. I label this unbenchmarked on purpose. It is a flashlight, not a leaderboard.
// prove_path.mjs — labeled example, not a performance claim
import { writeFileSync, readFileSync, realpathSync } from "node:fs";
import { join } from "node:path";
import { execSync } from "node:child_process";
const root = process.cwd();
const nonce = `probe-${Date.now()}-${Math.random().toString(16).slice(2)}`;
const target = join(root, ".agent-nonce");
writeFileSync(target, nonce, "utf8");
const got = readFileSync(target, "utf8");
const real = realpathSync(root);
let gitTop = "";
try {
gitTop = execSync("git rev-parse --show-toplevel", { encoding: "utf8" }).trim();
} catch {
gitTop = "(no git)";
}
if (got !== nonce) {
console.error("FAIL: nonce mismatch");
process.exit(1);
}
console.log(JSON.stringify({ root, real, gitTop, target, nonce }, null, 2));
Run it like this and paste the JSON back into the chat so the model has to look at the same object you are looking at. Then glance at git, because a successful write into a forgotten worktree is still a successful write.
node prove_path.mjs
git status --short -- .agent-nonce
realpath .
git rev-parse --show-toplevel
I also drop .agent-nonce into .gitignore before the session gets cute, because the probe should never become a commit, a pull request, or a secret-shaped embarrassment. The ignore rule is part of the ritual, not an afterthought you remember when CI starts yelling. If the agent cannot honor that tiny constraint, you have learned something cheaper than a botched release.
The developer-experience teardown is not that people forget commands. It is that product onboarding celebrates the first generated function while the identity question is still unanswered. Splash screens talk about models the way hotel lobbies talk about ocean views. Minute twelve talks about paths, bind mounts, and the clone you thought you had deleted. I would rather have a blunt FAIL in the transcript than a beautiful helper method in a worktree I will throw away by accident tonight.
When the nonce comes back, I allow exactly one tiny patch, and I make that patch touch the nonce file itself. Change the file to include a second line, patched-by-agent, then read it again through the same tool. That second hop catches helpers that can write once through a stub and then silently switch filesystems. Does that sound paranoid? Only if you have never watched an agent update a file that your editor immediately marks as deleted, because the write landed on a bind-mount shadow.
Here is the failure pattern I keep seeing in otherwise smart sessions, described as a walkthrough rather than a scored experiment. The model lists src/index.ts from a cached tree. The shell, sitting one directory higher, writes a perfectly valid patch into a sibling folder with the same basename. Your editor, still attached to the original folder, shows nothing, so you paste more stack traces. Ten minutes later you have two slightly different files and a growing sense that you are the unreliable narrator. The nonce collapses that novella into a single comparison. Same string out, same string in, same realpath, or we stop.
Limitations matter, and they are not fine print I am sliding under the rug. This probe does not prove correctness of code, security of the box, or durability of a free tier. It does not measure latency, and it does not rank models against each other. A nonce round-trip can pass on a machine that still has the wrong Node version, the wrong secrets file, or a clock so skewed that signed URLs will rot before lunch. If you need production isolation, this is not your architecture. If you cannot throw the server away, you should not treat a free scratch box as a long-lived workstation.
Who should skip this whole ritual? People already living in a locked remote-dev image where the mount is immutable and the editor is bound to that mount by construction. People handling regulated data should not sprinkle nonce files next to customer records, and they should not paste tool transcripts into a hosted model without a policy. People who want a managed IDE with a vendor-owned workspace map may find the probe insulting, and that is fine. The ritual is for the messy middle, where a free server, a local editor, and a helpful model share a name for the project and almost nothing else.
I also refuse to turn the nonce into a personality test for the assistant. If it fails, I do not argue with it about trying harder or using a warmer tone. I stop the session, I fix the mount or the clone, and I start again with a cold prompt. That sounds wasteful until you count the minutes you would have spent reviewing a patch that never existed in your tree. The first fifteen minutes are a gate, not a warm-up comedy set, and gates are allowed to slam.
If you already keep a disposable coding server around, run the echo there before you ask for a refactor. MonkeyCode’s free server option is one place you can do that without standing up your own box first, and then you can decide whether the rest of the product even matters. I will not cheerlead past that point, because the only proof that counts is the nonce coming home.
Top comments (0)