Most free-tier spikes fail on drift, not on model quality.

The agent wrote a correct patch. The host could not run it.

That is an environment bug. You can find it in 90 minutes.

The rule: fingerprint both sides before you prompt anything.

One hypothesis, written before the timer starts

A spike without a falsifiable sentence is a demo. Demos always pass.

Write exactly one line:

A patch produced on the free server passes the same five-command contract test as local CI.

Commit that line to a file in your repo. Now you cannot move the goalposts later.

Why drift is the interesting failure

Model quality shows up as a bad diff. You see it in review.

Drift shows up as a bad host. You see it 40 minutes later, as EACCES.

Drift is cheaper to measure and more expensive to ignore.

Pre-register the thresholds

Write these numbers down before you touch the server. Fill the observed column last.

Metric Pre-registered threshold Observed
Time to first green contract test ≤ 25 min
Fingerprint fields that differ ≤ 2
Repair time per drift field ≤ 10 min
Files touched by environment fixes ≤ 3
Review cost vs local baseline ≤ 1x

Two rules keep this honest.

  1. Thresholds are written first, in the same commit as the hypothesis.
  2. Any change to a threshold is a new spike on a new day.

The 90-minute budget

Minutes Activity Output
0–5 Hypothesis and thresholds spike/ledger.json committed
5–20 Fingerprint local local.json
20–40 Fingerprint server, diff drift.diff
40–65 One real patch, timed timing.txt
65–80 Fill the ledger Facts, no opinions
80–90 Verdict ship or kill

When the timer ends, the spike ends. A partial ledger is still a result.

Step 1: fingerprint both environments

The script below is a template. I have not run it against your machines.

#!/usr/bin/env bash # drift.sh - capture an environment fingerprint set -euo pipefail OUT="${1:-fingerprint.json}" row() { printf ' "%s": "%s",\n' "$1" "$2"; } { printf '{\n' row os "$(uname -srm | tr '"' "'")" row node "$(node -v 2>/dev/null || echo missing)" row python "$(python3 -V 2>&1 | awk '{print $2}' || echo missing)" row lock "$(sha256sum package-lock.json 2>/dev/null | cut -c1-16 || echo none)" row tz "$(cat /etc/timezone 2>/dev/null || date +%Z)" row locale "${LANG:-unset}" row cores "$(nproc 2>/dev/null || echo unknown)" row mem_mb "$(awk '/MemTotal/ {print int($2/1024)}' /proc/meminfo 2>/dev/null || echo unknown)" printf ' "_end": "ok"\n}\n' } > "$OUT" echo "wrote $OUT" 

Run it on both hosts. Then diff the JSON, not the vibes.

./drift.sh local.json ssh <free-server> 'bash -s' < drift.sh > server.json diff <(jq -S 'del(._end)' local.json) <(jq -S 'del(._end)' server.json) | tee drift.diff 

A thirteen-line diff is a finding. A missing node is a kill signal.

Step 2: one contract test, five commands, both hosts

Use the same commands, in the same order, on both machines.

set -e npm ci --no-audit --no-fund npm run lint npm test -- --runInBand git status --porcelain # must print nothing node -e 'console.log(process.version)' 

Do not add || true. Do not skip npm ci.

The last two commands catch the quiet failures. Dirty checkouts and version drift.

Step 3: one patch, timed, not five

Pick a real ticket from your backlog. Toy functions hide environment bugs.

/usr/bin/time -f '%e s wall, %M KB peak' \ npm test -- --runInBand 2> timing.txt cat timing.txt 

Record three numbers: time to first run, time to first green run, time to review.

Review time is the one people forget. Ask a colleague to read the diff cold.

The ledger

{ "hypothesis": "A patch produced on the free server passes the local five-command contract test.", "thresholds": { "green_minutes": 25, "max_drift_fields": 2, "max_repair_minutes_per_field": 10 }, "observed": { "green_minutes": null, "drift_fields": null, "repair_minutes_total": null, "review_minutes": null }, "verdict": null, "next_review_date": "2026-12-07" } 

Nulls are permitted entries. Guesses are not.

How to read the verdict

Drift fields Repair time Verdict
0 any ship — server becomes primary
1–2 ≤ 10 min each ship with pins — codify fixes
1–2 > 10 min each defer — pin first, re-spike
3+ any kill — do not chase it
any green > 25 min kill — the loop is too slow

defer is not a soft ship. It has a date and an owner, or it is a kill.

Where the free tier fits this worksheet

MonkeyCode is presented by its maintainers as an open-source coding-agent project.

Disclosure: This article was prepared as part of MonkeyCode's product outreach.

Two operator-supplied availability claims matter for this spike. Free model access and a free server option.

The quota is reported as roughly 10 million free tokens at the time of writing (2026-11-07). Treat that as a moving number, not a contract, and check the project page before you plan around it. Free allowances change.

Why this fits the drift test: the test needs a second host. A second host is the expensive part of the experiment.

Why free models are sufficient here: you grade the patch with npm test, not with prose. The contract test is the judge.

One practical note. Record the model name and the quota snapshot in your ledger. A spike with an unrecorded variable is a memory.

If you want a second host for this worksheet, run the drift step on MonkeyCode's free server and keep the ledger in your repo either way.

Limitations

  • Availability and quotas can change without notice. Re-run the spike monthly.
  • A free host is not your production host. Passing drift does not prove production parity.
  • Fingerprints cover language runtimes and lockfiles, not kernel behavior or syscalls.
  • Single-patch timings are noisy. Treat one run as one data point, not a benchmark.
  • Secrets handling on any shared host needs review before you paste a token anywhere.
  • Nothing here proves a model is good. It only proves a host is compatible.

Who should not use this approach

  • Teams handling regulated or customer data on a host they have not reviewed.
  • Repos with native toolchains, GPU builds, or long compile steps.
  • Monorepos where npm ci alone exceeds ten minutes.
  • Anyone who will not re-run the spike when the free terms change.

For those teams, a pinned devcontainer is the cheaper answer.

What a kill verdict buys you

You spent 90 minutes. You avoided a month of intermittent CI failures.

Keep the fingerprint script. It is reusable on every new host.

Pin the drift fields in a devcontainer and re-spike next month.

Short spikes, written thresholds, recorded verdicts. That beats a lucky demo.