자주 묻는 질문: 무료 에이전트 상자가 반복되는 다섯 가지 런타임 신화

작성자

카테고리:

← 피드로
DEV Community · Jordan Huang · 2026-09-11 개발(SW)

Did your agent “pass” because python --version looked friendly?
That print is only one process screenshot, not a matrix.

I keep hearing the same five confident claims.
They show up after a free coding box “works.”
They also sneak into otherwise careful code reviews.

This FAQ is a corrected mental model you can test.
Each myth gets a command you can run.
Then I give a fingerprint you can diff.

Why these myths spread

A chat log is not a Dockerfile you can hash.
A green terminal pane is not production.
You already know that, so why still ship on vibes?

Cheap model calls made the loop feel free.
A free server made the loop feel local.
Those two facts are not one contract.

MonkeyCode offers free model access and a free server option.
Disclosure: This article was prepared as part of MonkeyCode’s product outreach.
Treat that pairing as a scratchpad, not a base image.
Would you ship from a cafe laptop you do not own?

Myth 1: The box version is close enough

Claim: Node 20-something is fine for 20.11.
Repeat: Semver majors match, so merge the branch.

A close version is still not a pinned version.
Patch releases change OpenSSL defaults under you.
They also change error text that brittle tests scrape.

Evidence I actually run:

node -p "process.version + ' ' + process.arch + ' ' + process.platform"
python3 -c "import sys,platform; print(sys.version); print(platform.platform())"
go env GOVERSION GOOS GOARCH 2>/dev/null || true

Enter fullscreen mode Exit fullscreen mode

Corrected model: a runtime is a tuple, not a vibe.
Name, version, arch, libc, and locale all count.
If CI does not echo that tuple, you are guessing.

Ask the agent for the tuple in a file.
Do not accept a sentence in the transcript.
Committed files survive, and chat compliments do not travel.

Myth 2: Global installs are now the project

Claim: pip install foo on the box fixed imports.
Repeat: The agent installed it, so we are good.

A global binary is a PATH accident waiting overnight.
The next session may not have that PATH.
Your teammate’s laptop never had it either.

Evidence I actually run:

python3 -c "import sys; print('\n'.join(sys.path))"
python3 -c "import shutil; print(shutil.which('pytest'))"
npm root -g
which pytest
type pytest
printf '%s\n' "$PATH" | tr ':' '\n'

Enter fullscreen mode Exit fullscreen mode

Corrected model: if it is not in the repo contract, it does not exist.
Prefer a project venv, npx, and committed task files.
Ask where the binary lives. Then verify with type.

Did the agent sudo pip install on the box?
You then have a mutated VM, not a project.
Reclone, and that “fix” disappears with the PATH.

Myth 3: uname means the model knows the OS

Claim: The agent ran uname -a, so the stack is understood.
Repeat: It is Linux. Linux is Linux, right?

uname is a kernel marketing string, not an ABI.
It does not tell you musl versus glibc.
Wheels and C extensions care about that ABI.

Evidence I actually run:

uname -srm
getconf GNU_LIBC_VERSION 2>/dev/null || true
ldd --version 2>/dev/null | head -1
python3 -c "import platform; print(platform.libc_ver())"
file "$(python3 -c 'import sys; print(sys.executable)')"

Enter fullscreen mode Exit fullscreen mode

Alpine and Debian can share a kernel family name.
They still will not share wheel tags.
Your “it imported” moment can die on the next image.

Corrected model: fingerprint libc and the linker.
Kernel release is a weak signal for packaging.
ABI is the signal that breaks during dinner.

Myth 4: Tests ran, so the runtime is blessed

Claim: pytest returned zero, so the interpreter is correct.
Repeat: The agent already ran the suite on the box.

A zero status is only an exit code.
It is not a promise about tomorrow’s image.
Did you record which binary ran those tests?

Evidence I actually run:

readlink -f "$(which python3)"
python3 -c "import sys; print(sys.executable)"
python3 -c "import pytest,sys; print(pytest.__file__); print(sys.version)"
python3 -c "import sysconfig; print(sysconfig.get_platform())"

Enter fullscreen mode Exit fullscreen mode

Corrected model: bless a fingerprint, not a feeling.
Store the fingerprint beside the test log.
If they diverge, the green bar is another machine.

This is not the sandbox-versus-CI identity debate.
This is naming the same interpreter in both places.
That is a different question with the same stubborn habit.

Myth 5: Skip the Dockerfile; the box already has Python

Claim: Writing FROM python:3.12-slim is empty ceremony.
Repeat: The box already runs the app, so why pin?

The box is not a tagged, replayable image.
You do not control its package clock.
You do not pin its silent patch Tuesday.

Evidence I actually run:

cat /etc/os-release
apt-cache policy python3 2>/dev/null | head -5
pip3 --version
python3 -m pip freeze | wc -l

Enter fullscreen mode Exit fullscreen mode

Those numbers will move without a git commit.
That silent drift is the entire problem here.
Your future self cannot check out a box.

Corrected model: the free server is a scratchpad.
The image is the contract you can hash.
If you cannot docker build it, you cannot replay it.

Proposal below. Label it unexecuted until you run it.

# proposal only — read before you build
FROM python:3.12-slim-bookworm
WORKDIR /app
COPY pyproject.toml .
RUN pip install --only-binary=:all: -e . || pip install -e .
COPY . .
CMD ["pytest", "-q"]

Enter fullscreen mode Exit fullscreen mode

Artifact: three-way runtime fingerprint

Do not trust a paragraph in chat.
Diff JSON from laptop, box, and CI.

I keep this as scripts/runtime_fingerprint.sh.
Read it before you run it on a shared box.
The script should print facts, never secrets.

#!/usr/bin/env bash
# runtime_fingerprint.sh
# Proposal: run in local, agent box, and CI.
set -euo pipefail

json_escape() {
  python3 -c 'import json,sys; print(json.dumps(sys.stdin.read().rstrip("\n")))'
}

field() {
  local key="$1"
  local val
  val="$($2 2>/dev/null || echo missing)"
  printf '  "%s": %s,\n' "$key" "$(printf '%s' "$val" | json_escape)"
}

echo "{"
field os_release "uname -srm"
field libc "python3 -c 'import platform; print(platform.libc_ver())'"
field python "python3 -c 'import sys; print(sys.version.split()[0])'"
field python_bin "sh -c 'readlink -f "$(which python3)" || which python3'"
field node "sh -c 'node -p process.version || echo missing'"
field openssl "openssl version"
field locale "sh -c 'printf %s "${LC_ALL:-}${LANG:-unset}"'"
field pwd "pwd"
field git_head "sh -c 'git rev-parse --short HEAD || echo none'"
printf '  "utc": %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read().rstrip()))')"
echo "}"

Enter fullscreen mode Exit fullscreen mode

Test plan

Run this plan. Do not vibe-check the results.

  1. Run the script on your laptop. Save local.json.
  2. Run the same script on the agent box. Save box.json.
  3. Run it again as a CI step. Save ci.json.
  4. Diff the three files as data, not as feelings.
# compare_fingerprints.py — proposal
import json, pathlib

files = ["local.json", "box.json", "ci.json"]
docs = {}
for f in files:
    p = pathlib.Path(f)
    if p.exists():
        docs[f] = json.loads(p.read_text())

keys = sorted({k for d in docs.values() for k in d})
for k in keys:
    vals = {name: docs[name].get(k) for name in docs}
    uniq = set(map(str, vals.values()))
    mark = "MATCH" if len(uniq) == 1 else "DRIFT"
    print(f"{mark:5} {k}: {vals}")

Enter fullscreen mode Exit fullscreen mode

If python drifts, stop arguing about prompts.
If libc drifts, stop arguing about generic Linux.
If openssl drifts, rerun TLS tests on the tagged image.

How I read a DRIFT line

When python drifts, I do not tweak the prompt first.
I print both executables and both sys.version strings.
Then I decide which side is the contract.

diff -u local.json box.json || true
python3 -c "import json,sys; print(json.load(open(sys.argv[1]))['python'])" local.json
python3 -c "import json,sys; print(json.load(open(sys.argv[1]))['python'])" box.json

Enter fullscreen mode Exit fullscreen mode

When libc drifts, I stop installing host wheels.
I rebuild in the target image instead.
Host pip is not a supply chain.

When git_head drifts, I stop comparing runtimes.
I was fingerprinting the wrong checkout.
Fix the worktree, then rerun the script.

Decision table

  • python drifts: pin the image or pyenv. Rerun the suite.
  • node drifts: pin .nvmrc or the CI image. Rerun.
  • libc drifts: rebuild wheels. Stop using host pip.
  • locale drifts: force C.UTF-8 in CI. Then recheck sorting tests.
  • pwd drifts: ignore only if tests are cwd-safe. Fail home-directory assumptions.
  • openssl drifts: pin the distro image. Retest TLS.
  • git_head drifts: you fingerprinted the wrong checkout. Stop.

What this workflow is not

This workflow is not a hidden model benchmark.
This is not a quota sheet or a hardware tour.
I am not publishing machine specs I cannot see.

Free model access helps you iterate on the script.
A free server gives you a second machine to diff.
Neither one replaces a tagged image.

Skip this approach if you already have hermetic builds.
Skip it if you cannot run commands on the box.
Skip it if your org forbids unknown shared machines.

Do not paste secrets into the fingerprint.
Do not dump env into the chat log.
Do not cat .env for “more context.”

Steal this mental model

The box hosts processes for a cheap loop.
It does not mint your release artifact.
Green text is cheap. Replay is not.

Ask one rude question after every green agent run.
Which binary, which ABI, which tag?
If the chat cannot answer with files, it did not answer.

If you diff three fingerprints this week, which field drifted first?

원문에서 계속 ↗