DEV Community

Jordan Huang
Jordan Huang

Posted on

The Free Server Passed. That Is Not Staging

Did your agent just pass on a free server?
That green check is not a twin of production.
It is a cheap place to fail, nothing more.

I keep hearing the same five claims in reviews.
They sound careful, but they are still wrong.
This FAQ is the mental model I want in the PR.

What this FAQ is not

This write-up is not a latency bake-off.
This write-up is not another eval-harness sermon.
Those fights already live in other posts.

This FAQ talks about promotion pressure, not scores.
Free model access made cheap trying easy again.
A free server made the process cheap too.

Did that setup clone your network path?
Did it clone your secret injector as well?
Did it clone how disks die overnight?

Myth 1: A free server is just small prod

The claim

The claim is simple: same Linux, same Python.
The box looks familiar, so people hit merge.
Close enough becomes a release argument fast.

What you actually observed

A process exited zero on a scratch host.
A model returned text for one prompt.
A tool name showed up exactly one time.

The corrected model

Call that host a scratch replica, not staging.
It can prove syntax, imports, and one happy path.
It cannot prove topology, identity, or lifetime.

Ask this out loud

What dies when this box sleeps or gets reaped?
If you shrug, you do not have staging.
You have a demo that survived one afternoon.

Myth 2: A model reply proves the tool loop

The claim

The model picked a tool, so the loop works.
The transcript looks adult, so ship the agent.
Who needs fault injection for a helper script?

What you actually observed

One sunny transcript with no injected faults.
There was no timeout and no duplicate side effect.
Nobody asked for a flag you never exposed.

The corrected model

A reply is a sample, not a contract.
Prove fail-closed behavior on purpose, in the PR.
Prove the tool schema, not the chat vibe.

Minimum fault list I want pasted in the PR:

  1. Kill the tool with a non-zero exit.
  2. Return stdout that is not valid JSON.
  3. Delay the tool past your client timeout.
  4. Invoke the same mutating tool twice.
  5. Ask for a flag you never exposed.

If the agent still reports success, stop merging.
You did not ship a worker with boundaries.
You shipped a storyteller with shell access.

Myth 3: Free means I can skip a spend ceiling

The claim

The invoice is zero, so skip budget gates.
Retries look free and concurrency looks free.
Prompt size cannot matter on a free path.

What you actually observed

Nobody attached a cost annotation to CI.
The pipeline now waits on capacity you do not own.
A throttle looks exactly like a flaky test.

The corrected model

Free is a queue, not a promise you hold.
Treat spare capacity like a canary host only.
Cap retries, concurrency, and prompt size together.

Would you let an unpaid queue page you?
Then do not hang a release on it either.
Keep the free path for drafts and faults.

Myth 4: Sandbox secrets are fine because it is mine

The claim

It is my free box, so paste the token.
Dotenv files feel like personal convenience.
Rotation can wait until after the demo.

What you actually observed

Prompt traces often capture request headers whole.
Crash logs often capture environment key names.
Support dumps happen when you least want them.

The corrected model

Shared compute is still a computer with disks.
Inject short-lived credentials, never long-lived keys.
Redact traces, rotate often, and assume public logs.

If the token can transfer money, stop now.
That secret does not belong on a scratch replica.
Use a dummy catalog and a dry-run flag instead.

Myth 5: If it imported, the runtimes match

The claim

pip freeze looked familiar, so people ship it.
Package names matched a mental list from memory.
Wheels, locale, and libc felt like later details.

What you actually observed

You compared names, not the native builds.
You skipped locale, ulimit, and the CA bundle.
The demo never opened TLS the hard way.

The corrected model

Import success is not runtime parity at all.
Native deps fail late, and SSL fails later.
The agent dies after the demo, not during it.

I want a fingerprint, not a familiar feeling.
Record it on the scratch replica today.
Diff it against the box you actually ship.

The artifact: a promotion contract

Here is a proposed checker, not a benchmark.
Use it as a gate for shape, not quality.
Run it on the scratch replica itself.

Create parity-contract.toml beside your agent.

[runtime]
python_major_minor = "3.12"
require_posix = true

[env]
# names only; never store values in git
required_names = ["APP_ENV", "MODEL_BASE_URL", "TOOL_TIMEOUT_MS"]
forbidden_names = ["AWS_SECRET_ACCESS_KEY", "OPENAI_API_KEY", "STRIPE_SECRET"]

[limits]
max_prompt_chars = 8000
max_parallel_tools = 2
tool_timeout_ms = 8000

[disk]
require_writable_tmp = true
forbid_durable_assumption = true
Enter fullscreen mode Exit fullscreen mode

Now add parity_check.py. This is proposed code.

#!/usr/bin/env python3
"""parity_check.py — proposed promotion fingerprint, not a score."""
from __future__ import annotations

import json
import os
import platform
import sys
import tempfile
from pathlib import Path

try:
    import tomllib
except ImportError:  # pragma: no cover
    import tomli as tomllib  # type: ignore

CONTRACT = Path("parity-contract.toml")


def load_contract() -> dict:
    with CONTRACT.open("rb") as fh:
        return tomllib.load(fh)


def fingerprint() -> dict:
    writable = True
    try:
        with tempfile.NamedTemporaryFile(delete=True) as tmp:
            tmp.write(b"scratch")
    except OSError:
        writable = False
    return {
        "python": f"{sys.version_info.major}.{sys.version_info.minor}",
        "posix": os.name == "posix",
        "platform": platform.platform(),
        "env_names": sorted(os.environ),
        "writable_tmp": writable,
        "cwd": os.getcwd(),
    }


def violations(contract: dict, snap: dict) -> list[str]:
    bad: list[str] = []
    runtime = contract["runtime"]
    if snap["python"] != runtime["python_major_minor"]:
        bad.append(
            f"python {snap['python']} != {runtime['python_major_minor']}"
        )
    if runtime.get("require_posix") and not snap["posix"]:
        bad.append("posix required")
    env = contract["env"]
    names = set(snap["env_names"])
    for key in env["required_names"]:
        if key not in names:
            bad.append(f"missing env name {key}")
    for key in env["forbidden_names"]:
        if key in names:
            bad.append(f"forbidden secret name present: {key}")
    if contract["disk"]["require_writable_tmp"] and not snap["writable_tmp"]:
        bad.append("tmp is not writable")
    return bad


def main() -> int:
    contract = load_contract()
    snap = fingerprint()
    Path("parity-fingerprint.json").write_text(
        json.dumps(snap, indent=2)
    )
    bad = violations(contract, snap)
    if bad:
        print("PARITY FAIL")
        for item in bad:
            print(f"- {item}")
        return 1
    print("PARITY SHAPE OK")
    print("This is not production. This is a scratch replica.")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
Enter fullscreen mode Exit fullscreen mode

Run those commands on the free box, not only CI.

python3 -c "import tomllib" 2>/dev/null || python3 -m pip install tomli
python3 parity_check.py
echo "exit=$?"
# 0 means shape matched the contract.
# It does not mean the agent is done.
Enter fullscreen mode Exit fullscreen mode

Add a tiny tool-loop fault script next.

#!/usr/bin/env bash
# fault_tool.sh — proposed. Forces fail-closed behavior.
set -euo pipefail
case "${1:-}" in
  boom) echo "nope"; exit 2 ;;
  junk) echo "<<<not-json>>>"; exit 0 ;;
  slow) sleep 30; echo '{"ok":true}'; exit 0 ;;
  twice) echo '{"ok":true}'; echo '{"ok":true}'; exit 0 ;;
  *) echo '{"ok":true}'; exit 0 ;;
esac
Enter fullscreen mode Exit fullscreen mode
chmod +x fault_tool.sh
./fault_tool.sh boom; echo "boom=$?"
./fault_tool.sh junk; echo "junk=$?"
# Point the agent at boom, then junk, then slow.
# Did it stop? Or did it invent success?
Enter fullscreen mode Exit fullscreen mode

Walk the faults in that order, then paste the exits.
A green chat log is not one of the exits.
Fail-closed means the agent stops, not narrates.

Decision table I want pasted in the PR

Observation on the free box Safe conclusion Unsafe conclusion
Green import Syntax likely works here Prod runtime matches
Model returned a tool name Happy path was sampled Tool loop is proven
Invoice is zero Cheap place to fail No need for a cap
File write succeeded Tmp works right now Disk is durable
Required env names present Contract shape looks ok Secrets are safe

Print that table inside the pull request body.
Make the reviewer pick a column out loud.
The right-hand column is how incidents start.

Where a free model and free server fit

I want a scratch replica I can throw away.
Free model access helps that loop stay cheap.
A free server helps the process stay cheap too.

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

MonkeyCode offers free model access and a free server option.
That pair fits the scratch-replica model above.
It still does not make the box a twin of production.

I would run parity_check.py on that host first.
Then the fault script. Then I would stop.
Promotion happens on the environment you ship.

Limitations

This checker does not score model answers.
It does not measure tokens, spend, or p95.
It does not detect prompt injection either.

It only fails on shape mismatches you encoded.
Missing env names. Forbidden secret names.
Wrong Python. A dead tmp directory.

Timezone, NUMA, and GPU presence are absent.
So is any claim about model quality.
Do not paste those gaps into a dashboard.

The bash fault script is a stub on purpose.
Real tools need real side-effect guards.
Use idempotency keys, dry-run flags, and receipt logs.

Who should not use this

Skip this if you already have real staging.
Skip this if regulated data cannot leave locked hosts.
Skip this if your tools can spend real money.

Do not put customer PII on a free box.
Do not hang a release on spare capacity.
Do not treat a transcript as an audit log.

If you need a twin, go build a twin.
Pay for the shape you are required to trust.
The scratch replica should stay disposable.

What I want you to ask next

Did the agent pass on the free box?
Good. Now ask what that box cannot prove.

Can it prove fail-closed tools under faults?
Can it prove secret names are absent?
Can it prove the disk will vanish later?

If any answer is no, keep the tag at draft.
The scratch replica already did its only job.
Your staging environment still has to do its own.

Top comments (0)