DEV Community

Jordan Huang
Jordan Huang

Posted on

FAQ: Five Lockfile Myths a Free Agent Box Will Sell You

Did the free agent box just rewrite your lockfile?
I see that claim inside otherwise careful pull requests.

A green install log is not a pin.
It is a resolver event on someone else's machine.

Why this FAQ exists

Coding agents now draft patches on remote hosts.
Free models make that loop cheap to repeat.
A free server makes the loop feel like a real build.

Then the pull request ships a mutated lockfile.
Reviewers skim the chat. They skip the diff.
Does that sound like your last Friday merge?

I am not talking about p50 or HTTP 200s.
I am talking about the works-on-the-agent-box lie.
Chat confidence is not a frozen graph.

How I use a free box without trusting it

I still want a scratch compiler for a first pass.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.

MonkeyCode provides free model access and a free server option.
I use that pair as a draft compiler only.
I do not treat it as the source of truth.

The checklist below stands if you delete that product name.
You still need a lockfile interrogation, not a victory screenshot.

Myth 1: A green install on the free server is reproducible

The claim: "It installed. We are pinned."

What people paste: a chat log with no red lines.

What I ask: which lockfile, which command, which OS?

Run this on your laptop. Do not trust the transcript alone.

uname -s -m
node -v
python --version
git status --short -- package-lock.json yarn.lock pnpm-lock.yaml \
  poetry.lock uv.lock Cargo.lock go.sum
Enter fullscreen mode Exit fullscreen mode

Did the agent run npm install or npm ci?
Those commands are not the same contract.

npm install may rewrite the lockfile quietly.
npm ci refuses to guess. It demands an existing pin.

Same split exists outside npm.
pnpm install --frozen-lockfile is the strict door.
uv sync --frozen is the strict door.
Bare install is a shrug with extra progress bars.

Corrected model: a green install is a resolver event.
It is not a reproducibility certificate.
Ask which installer flag actually ran.

Myth 2: The model chose "latest," so the version is safe

The claim: "The agent picked a current package."

What people paste: a version string that looks recent.

What I ask: did the registry move while you were typing?

"Latest" is a moving tag.
It is not a security review.
It is not an SBOM. It is not even a pin.

Check what actually landed in the tree.

# Node
npm ls --depth=0
git diff -- package.json package-lock.json

# Python
git diff -- pyproject.toml poetry.lock uv.lock requirements.txt
python -c "import sys; print(sys.version); print(sys.platform)"
Enter fullscreen mode Exit fullscreen mode

Did a transitive package shift with no direct bump?
That is the usual surprise hiding in a huge lockfile.

Did the agent add a second package manager file?
Now you have two graphs and one confused CI job.

Corrected model: the model suggested a name.
Your lockfile records the graph.
Only the graph is reviewable in git.

Myth 3: Skip the lockfile because the box is disposable

The claim: "Throwaway server. Why pin anything?"

What people paste: a deleted workspace and a shrug.

What I ask: then why is that mutation in the PR?

Disposable compute does not mean a disposable dependency graph.
The box dies. The lockfile commit lives in main.

If the agent regenerated the lockfile, treat it as hostile input.
Read it like you read a vendored blob you did not write.

git log -1 --stat -- package-lock.json pnpm-lock.yaml yarn.lock \
  poetry.lock uv.lock Cargo.lock
git diff origin/main -- package-lock.json pnpm-lock.yaml yarn.lock \
  poetry.lock uv.lock Cargo.lock
Enter fullscreen mode Exit fullscreen mode

Look for churn you did not request.
Massive lockfile diffs hide version skating.
A one-line manifest change should not explode the graph without a story.

Corrected model: throw away the disk.
Keep the pin. Never keep a pin you did not read.

Myth 4: Tests passed on the agent box, so CI is redundant

The claim: "The free server already ran the suite."

What people paste: an "all tests passed" paragraph.

What I ask: which interpreter, which libc, which extras?

Native addons compile per platform.
Python wheels pick manylinux tags you never said out loud.
Optional extras change the graph after the chat ended.

node -p "process.version + ' ' + process.platform + ' ' + process.arch"
python -c "import platform,sys; print(sys.version, platform.machine(), platform.libc_ver())"
Enter fullscreen mode Exit fullscreen mode

Warm node_modules on a rented disk is not CI.
CI should start from the lockfile, not from leftover directories.

I label the next file as a proposal.
I have not published timings for it. Wire it to your real installer.

# proposed-lockfile-gate.yml — proposal only
name: lockfile-gate
on: [pull_request]
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Fail if lockfile is missing
        run: |
          test -f package-lock.json -o -f pnpm-lock.yaml -o -f yarn.lock \
            -o -f poetry.lock -o -f uv.lock -o -f Cargo.lock -o -f go.sum
      - name: Fail if install would mutate the lockfile
        run: |
          if [ -f package-lock.json ]; then npm ci; fi
          if [ -f pnpm-lock.yaml ]; then pnpm install --frozen-lockfile; fi
          git diff --exit-code -- package-lock.json pnpm-lock.yaml yarn.lock \
            poetry.lock uv.lock Cargo.lock go.sum
Enter fullscreen mode Exit fullscreen mode

Corrected model: the agent box is one host.
CI is the contract with the rest of the team.
A chat transcript is not a runner.

Myth 5: Linux on the free server matches every laptop

The claim: "We all run Linux containers anyway."

What people paste: one happy uname from the agent.

What I ask: who on the team is on ARM Macs right now?

Apple Silicon versus x86_64 changes optional native builds.
musl versus glibc changes which wheel you actually got.
The agent may install a linux-x64 binary you cannot run locally.

echo "local:"
uname -s -m
echo "lockfile hints (node):"
grep -E '"os"|"cpu"|"libc"' package-lock.json | head
Enter fullscreen mode Exit fullscreen mode

If your lockfile encodes darwin-arm64 optional packages, a linux agent will "helpfully" rewrite them.
That rewrite is a bug, not a cleanup.

Cargo and Go have the same trap with target triples.
If the agent cross-compiled by accident, your CI image may disagree tomorrow.

Corrected model: record the platform that generated the lockfile.
Reject silent platform swaps in review.
Same repo, different CPU, different optional graph.

Artifact: the five-row decision table

I use this table before I approve a dependency diff.
Fill it from commands, not from memory.
Unknown counts as fail.

Question Evidence Pass looks like Fail looks like
Did install mutate the lockfile? git diff --exit-code on lockfiles Empty diff Thousands of unrelated pins
Was the installer the strict one? Chat or CI shows frozen/ci flags Frozen flag present Bare install in the transcript
Did language version match CI? node -v / python --version versus the CI file Same major.minor Agent on a random major
Did platform stay still? uname -m versus optional packages Same arch family darwin extras dropped on linux
Did we intend this package? Diff of the manifest, not only the lock Named direct change in the PR Transitive storm, no story

Copy the table into the PR.
Answer every row in public, not in a side chat.
If a row is blank, the review is not done.

A short local ritual after any free-server draft

Do this on a clean checkout.
Do not reuse the agent's node_modules or virtualenv.

# Proposed local ritual. Run on YOUR machine.
git fetch origin
git switch --detach origin/the-pr-branch   # or: git switch the-pr-branch

git diff origin/main -- package.json package-lock.json \
  pyproject.toml poetry.lock uv.lock requirements.txt Cargo.lock go.sum

if [ -f package-lock.json ]; then npm ci; fi
if [ -f pnpm-lock.yaml ]; then pnpm install --frozen-lockfile; fi
if [ -f yarn.lock ]; then yarn install --frozen-lockfile; fi
if [ -f uv.lock ]; then uv sync --frozen; fi
Enter fullscreen mode Exit fullscreen mode

If the frozen install dies, the agent lied about "it works."
If the frozen install rewrites files, your PR is incomplete.
If you cannot even run a frozen install, stop merging dependency PRs.

Limitations

This FAQ does not replace npm audit policy.
It does not replace license scanning.
It does not prove a package is not malware.

It only proves you still own the pin.
That is a smaller claim than it sounds. Keep it small.

I am not claiming a specific free-server CPU.
I am not claiming a model name, a quota, or a benchmark.
Those change. Lockfile hygiene does not.

Hash-pinning Python deps needs a toolchain you already chose.
Do not paste --require-hashes if you never generated hashes.
Do not paste npm ci if the repo never committed package-lock.json.

Who should not use this approach

Do not use a free remote server for private packages.
Do not paste registry tokens into an agent session.
Do not treat this checklist as enough for PCI or medical software.

If your build needs GPUs or licensed compilers, skip the scratch-box path.
If you cannot run a frozen install locally, fix that first.
The FAQ will not save a machine you do not control.

Corrected mental model

The free model drafts.
The free server compiles a guess.
Your lockfile is the only dependency document that ships.

Chat is advertising. CI is the notary.
Ask the five questions. Then merge, or do not.

If you run the table on a real PR, tell me which row failed.
I want the boring row, not another green screenshot.

Top comments (0)