Did that patch leave a host you do not own?
I keep hearing five myths around complimentary coding boxes.
This FAQ is a receipt checklist, not a vibe check.
Would you merge a binary with no hash, ever?
What broke in my head
Agents now jump onto a remote box without asking.
The chat looks finished while the compile looks green.
Then the real CI job explodes on a different host.
Does that sequence feel uncomfortably familiar to you?
I wanted one file I could commit beside the patch.
The mental model I want
Treat every complimentary host as an untrusted compiler.
Treat every free model turn as unlabeled text until tagged.
The remote box is not your shipping laptop.
The agent session is not your release pipeline.
Myth 1: The complimentary host matches my laptop
People repeat this claim like it is weather.
They say it built there, so it builds here.
Can you show uname, python3 --version, and which cc?
Those three strings decide whether the claim survives.
Linux userland is not the same as macOS userland.
A container glibc is not your workstation glibc either.
Compare fingerprints before you copy any built artifact.
Without a fingerprint, you should refuse the copy.
uname -srm
python3 --version
command -v cc || true
command -v rustc || true
echo "PATH=$PATH"
Run that command block on the complimentary host.
Run the same block on the machine that ships.
Different strings mean you actually built different products.
Do not argue with those platform strings later.
Myth 2: Free model output needs no author tag
I hear this claim in almost every review.
People say the model is free, so skip tags.
Does authorship vanish because nobody sent an invoice?
A patch still entered your tree from somewhere unknown.
Log the turn, the prompt hash, and the diff hash.
You are logging provenance, not a marketing brand name.
mkdir -p .session
date -u +"%Y-%m-%dT%H:%M:%SZ" > .session/started_at_utc.txt
printf '%s\n' "${MODEL_LABEL:-unknown-free-model}" > .session/model_label.txt
git diff --stat > .session/diff_stat.txt
git rev-parse HEAD > .session/base_commit.txt
Write unknown-free-model when the label is missing.
An unknown label is honest, while a missing file is not.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
This walkthrough uses MonkeyCode as the example complimentary host.
Free model access and a free server option are available there.
I still refuse to treat that session as CI.
Myth 3: A compiler on the box makes artifacts portable
This myth still burns teams during release week.
Someone copies a binary off the box and ships.
Would you ship a binary you cannot rebuild today?
Then you should not ship this copied binary either.
The remote compile is only a smoke signal.
Rebuild under your pinned toolchain, or do not ship.
mkdir -p .session
find dist -type f -print0 2>/dev/null | sort -z | xargs -0 sha256sum > .session/dist.sha256
# rebuild on the ship host, then diff the two hash files
Divergent hashes taught you something while the lesson was cheap.
A missing hash taught you nothing about portability.
Myth 4: No invoice means no paper trail
Compliance folks hate this myth for good reason.
Engineers repeat it because the dashboard said free.
Free compute still executed secrets if you pasted them.
Free compute still wrote files you might later commit.
Demand a bill of materials before the victory lap.
A session without that file is only a rumor.
I want one JSON file sitting beside the patch.
The next human should re-check facts, not feelings.
Myth 5: Copying files back equals a pipeline
The agent says done and dumps a tarball on disk.
You extract it over src and open the merge request.
Is a file copy with extra confidence a pipeline?
I do not treat that copy as a release builder.
Remote work stays a draft until your pipeline rebuilds it.
Your pipeline is the only builder you should trust.
git status --porcelain
git diff --name-only
# stop if unexpected lockfiles or binaries appear
Unexpected lockfiles are a smell worth stopping for.
Unexpected binaries are a hard stop, not a debate.
PATH lies more than people think
The complimentary host PATH often includes mystery toolchains.
Your laptop PATH includes another set of mystery toolchains.
Never trust a binary name without command -v plus a hash.
A pretty interpreter name is not a receipt by itself.
command -v python3
python3 -c "import sys; print(sys.executable)"
sha256sum "$(command -v python3)"
That hash is the interpreter you actually invoked.
A pretty python3 name on PATH is not evidence.
Artifact: a session bill of materials
Here is a small Python script you can copy.
Treat it as a proposal and run it yourself.
Save the file as session_bom.py in the repo root.
Run it on the complimentary host before copying files.
#!/usr/bin/env python3
"""Write .session/bom.json for a complimentary coding host."""
from __future__ import annotations
import hashlib
import json
import os
import platform
import subprocess
import sys
from datetime import datetime, timezone
from pathlib import Path
ROOT = Path.cwd()
OUT = ROOT / ".session" / "bom.json"
def sh(args: list[str]) -> str:
try:
p = subprocess.run(args, check=False, capture_output=True, text=True)
except FileNotFoundError:
return ""
return (p.stdout or "").strip()
def sha256_file(path: Path) -> str:
h = hashlib.sha256()
with path.open("rb") as f:
for chunk in iter(lambda: f.read(65536), b""):
h.update(chunk)
return h.hexdigest()
def pip_freeze_hash() -> str | None:
text = sh([sys.executable, "-m", "pip", "freeze"])
if not text:
return None
return hashlib.sha256(text.encode()).hexdigest()
def git_info() -> dict:
return {
"head": sh(["git", "rev-parse", "HEAD"]),
"status": sh(["git", "status", "--porcelain"]),
"user_email_set": bool(sh(["git", "config", "user.email"])),
}
def main() -> int:
tracked = []
for rel in ("src", "app", "lib"):
d = ROOT / rel
if not d.is_dir():
continue
for p in sorted(d.rglob("*")):
if p.is_file() and p.stat().st_size <= 1_000_000:
tracked.append(
{
"path": str(p.relative_to(ROOT)),
"sha256": sha256_file(p),
}
)
bom = {
"generated_at_utc": datetime.now(timezone.utc).isoformat(),
"hostname": platform.node(),
"platform": platform.platform(),
"python": sys.version.split()[0],
"executable": sys.executable,
"cwd": str(ROOT),
"path_head": os.environ.get("PATH", "")[:400],
"pip_freeze_sha256": pip_freeze_hash(),
"git": git_info(),
"model_label": os.environ.get("MODEL_LABEL", "unknown-free-model"),
"tracked_files": tracked[:200],
}
OUT.parent.mkdir(parents=True, exist_ok=True)
OUT.write_text(json.dumps(bom, indent=2) + "\n", encoding="utf-8")
print(f"wrote {OUT}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
Export a model label even when the name is unknown.
Then copy .session/bom.json along with the patch.
export MODEL_LABEL="unknown-free-model"
python3 session_bom.py
The merge request now carries a receipt, not a story.
Reviewers can argue with files instead of chat memory.
A test that refuses a naked patch
This pytest file fails closed on purpose.
A missing BOM means the patch should not pass.
# test_session_bom.py — proposal, not a production suite
from pathlib import Path
import json
def test_session_bom_exists_and_names_a_host():
p = Path(".session/bom.json")
assert p.is_file(), "missing .session/bom.json; refuse the patch"
data = json.loads(p.read_text(encoding="utf-8"))
assert data.get("hostname"), "BOM hostname is empty"
assert data.get("python"), "BOM python is empty"
assert data.get("git", {}).get("head"), "BOM has no git head"
assert data.get("model_label"), "BOM has no model label"
def test_session_bom_is_not_your_laptop_claim():
data = json.loads(Path(".session/bom.json").read_text(encoding="utf-8"))
# Fill this from YOUR ship host, not from memory.
ship_platform_needle = "REPLACE_ME"
assert ship_platform_needle != "REPLACE_ME", "set the ship host needle"
print("remote_platform=", data.get("platform"))
Replace REPLACE_ME with a substring from your ship host.
A green test must prove the platforms match, or rebuild.
Diff the BOMs, then approve
I also diff two BOM files before I approve.
Hostname, platform, python, and pip freeze hash must be visible.
# diff_bom.py — proposal: print mismatched BOM keys
import json
import sys
a = json.load(open(sys.argv[1], encoding="utf-8"))
b = json.load(open(sys.argv[2], encoding="utf-8"))
keys = ("hostname", "platform", "python", "pip_freeze_sha256", "model_label")
for k in keys:
if a.get(k) != b.get(k):
print(f"MISMATCH {k}: {a.get(k)!r} vs {b.get(k)!r}")
python3 diff_bom.py .session/bom.json ship_host_bom.json
Any MISMATCH line means rebuild on the ship host.
Do not negotiate with a mismatched interpreter hash.
Decision table I actually use
I keep this table next to the merge request template.
Ask the author which row they claim to occupy.
| Claim you hear | Evidence to demand | If missing, do this |
|---|---|---|
| It built on the free box |
platform plus compiler path in the BOM |
Rebuild on the ship host |
| The model wrote a small patch |
model_label plus git diff --stat
|
Mark author unknown and review harder |
| Just copy dist/ |
dist.sha256 versus a local rebuild |
Throw the copy away |
| Nothing sensitive happened | a command history you actually control | Rotate anything you pasted |
| CI will catch it | CI uses the same pins you named | Diff the pins; do not guess |
Each row is a claim, evidence, and a refusal action.
If evidence is missing, take the refusal action immediately.
What this does not prove
A BOM is not a security audit of the host.
A BOM is not a license scan of the tree.
It will not catch a model that lied in comments.
It will not freeze a moving complimentary image either.
A complimentary image can change under you without notice.
I do not claim uptime, hardware, quotas, or model names.
If you need those numbers, read product docs that day.
Do not copy capacity claims from a blog post later.
Who should not use this
Skip this if you already have a locked remote builder.
Skip this if policy forbids any complimentary host usage.
Skip this if you cannot write .session into the repo.
Skip this if your threat model needs attested hardware.
This workflow is for messy agent sessions on scratch boxes.
It is not a substitute for a real compliance program.
The questions I ask before merge
I ask five questions before I approve the merge.
Each one needs a file, not a shrug.
- Which host produced these bytes, according to the BOM?
- Which model label sits inside that same JSON file?
- Did I rebuild the tree under the real ship pins?
- Did unexpected binaries land inside the git diff?
- What secret might have hit that complimentary box?
If any answer is a shrug, I block the merge.
A shrug from a free session is not a receipt.
Would you accept a shrug from a human intern today?
Then do not accept that shrug from a complimentary session.
Closing
Complimentary compute remains useful for drafts and spikes.
Unlabeled compute is how rumors sneak into main.
Write the BOM before you copy a single artifact.
Hash the outputs, then rebuild where you actually ship.
Which of these five myths are you still repeating tomorrow?
Top comments (0)