You closed the browser tab. Did the job actually die?
Most people guess. Then they lose the diff.
Free models invite that guess. Free servers make it worse.
The tab looks like a workstation. It is not.
Why an FAQ, not a tour
I keep seeing the same six claims.
They sound thrifty. They wreck resume logic.
This is a myth-busting FAQ. Claims first. Evidence second.
Then a corrected mental model. Then a script you can run.
I will not invent latency numbers. I will not name mystery GPUs.
You should not either. Measure the contract, not the brochure.
Where the two free pieces fit
You need two cheap ingredients. A model endpoint. A remote shell.
That pair is how people rehearse agent loops without a budget fight.
MonkeyCode currently offers free model access and a free server option.
I treat that pair as a practice worker, not as a laptop clone.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
I am not claiming quotas, hardware, or forever-free status.
Those change. The job contract does not.
Q1. "The model is free, so skip the job ID."
Does a zero invoice create identity? It does not.
A free completion is still a call. A call is not a run.
Without a job ID you cannot resume. You cannot attach artifacts.
You also cannot tell two refactors apart tomorrow.
- Claim: price replaces bookkeeping.
- Evidence: you cannot grep a bill for a missing folder.
- Corrected model: the model is a function inside a job.
# proposed/job.yaml — local contract, not a vendor API
job_id: "2026-09-05-refactor-auth"
prompt_sha256: "pending"
workspace_sha256: "pending"
artifact_dir: "./artifacts/2026-09-05-refactor-auth"
heartbeat_path: "./artifacts/2026-09-05-refactor-auth/heartbeat.txt"
endpoint: "${MODEL_URL}"
Write the file before the first prompt. Always.
Q2. "A free server is just a slower laptop."
Is the box in your backpack? Can you pull the plug?
A laptop has one user and one Ctrl-C.
A free remote box is rented capacity. It may preempt you.
It may recycle the disk. It may keep running after logout.
- Claim: remote equals local, only slower.
- Evidence: local kill is synchronous. Remote kill is a rumor.
- Corrected model: treat the box as a worker, not a desk.
Ask one rude question before you paste secrets.
Who else can read this home directory?
If you cannot answer, do not paste them.
Q3. "Closing the tab is Ctrl-C."
On a laptop, closing the terminal usually stops the process.
On a remote worker, the browser is only a viewport.
The shell may survive. The model call may finish.
The patch may land with nobody watching.
- Claim: UI lifetime equals process lifetime.
-
Evidence:
psafter reconnect often still shows the command. - Corrected model: the tab is a camera. The job is the subject.
Proposed check after every disconnect:
# proposed — run on the remote worker, not in the chat
ps -ef | grep -E 'python|node|cargo' | grep -v grep
ls -lt artifacts/*/heartbeat.txt 2>/dev/null | head
If ps is empty and artifacts are empty, the job died.
If ps is empty and artifacts exist, the job finished unattended.
If ps is busy, the tab lied. The worker did not.
Q4. "The model remembers the workspace."
Does the endpoint mount your disk? Usually no.
It sees tokens you send. Nothing else.
Reconnect does not restore a mind. It restores a socket.
If you skip the snapshot, the next prompt is amnesia with confidence.
- Claim: conversation memory equals repository state.
-
Evidence: a new session cannot
git diffunless you give it files. - Corrected model: you ship context. The model does not keep a checkout.
Proposed snapshot before every model call:
# proposed snapshot — label it with the job_id
JOB=2026-09-05-refactor-auth
mkdir -p "artifacts/$JOB"
git rev-parse HEAD > "artifacts/$JOB/head.txt"
git status --porcelain > "artifacts/$JOB/status.txt"
git diff > "artifacts/$JOB/worktree.diff"
shasum -a 256 "artifacts/$JOB/worktree.diff" > "artifacts/$JOB/workspace.sha256"
Send the snapshot hash in the prompt header.
Do not send "as we discussed" as a substitute.
Q5. "Polling keeps the free session warm."
Will a tight loop buy you persistence? It buys you throttling.
It also hides real heartbeats behind noise.
Warmth is not a protocol. A heartbeat file is.
If the worker is alive, it can touch a file every thirty seconds.
- Claim: request spam equals liveness.
- Evidence: spam hits the model. It may not hit the job.
- Corrected model: liveness is a file mtime, not a token stream.
# proposed heartbeat writer — run beside the agent, not instead of it
JOB=2026-09-05-refactor-auth
while true; do
date -u +%Y-%m-%dT%H:%M:%SZ > "artifacts/$JOB/heartbeat.txt"
sleep 30
done
Read that file from your laptop. Do not poll the model to ask if it is "still there."
Q6. "The chat transcript is the audit log."
Can you git blame a chat bubble? No.
Can legal replay a scrolling panel? Also no.
Chat is a scratch pad. Artifacts are the record.
If the only copy lives in the UI, you do not have a copy.
- Claim: tokens are an audit trail.
- Evidence: UIs truncate, reorder, and drop tool traces.
- Corrected model: logs, diffs, and exit codes live on disk.
Minimum record I keep per job:
-
job.yaml— identity and endpoint placeholder. -
head.txtplusworktree.diff— what the model saw. -
model.stdout— raw text, not a screenshot. -
exit.code— one integer, no poetry.
If any file is missing, the job is anecdotal.
Anecdotes do not survive Monday.
Artifact: a contract checker you can run
This script is proposed and unexecuted here.
Copy it. Point it at a job directory. Read the exit code.
It does not call a model. That is the point.
The contract must fail even when inference is free.
#!/usr/bin/env python3
"""proposed/check_job_contract.py — verify a job, not a chat."""
from __future__ import annotations
import hashlib
import sys
from datetime import datetime, timezone
from pathlib import Path
REQUIRED = (
"job.yaml",
"head.txt",
"status.txt",
"worktree.diff",
"heartbeat.txt",
"model.stdout",
"exit.code",
)
def sha256(path: Path) -> str:
h = hashlib.sha256()
h.update(path.read_bytes())
return h.hexdigest()
def main(argv: list[str]) -> int:
if len(argv) != 2:
print("usage: check_job_contract.py artifacts/<job_id>", file=sys.stderr)
return 2
root = Path(argv[1])
missing = [name for name in REQUIRED if not (root / name).exists()]
if missing:
print("missing:", ", ".join(missing))
return 1
raw = (root / "heartbeat.txt").read_text().strip()
beat = datetime.strptime(raw, "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=timezone.utc)
age = (datetime.now(timezone.utc) - beat).total_seconds()
if age > 120:
print(f"stale heartbeat: {age:.0f}s")
return 1
exit_txt = (root / "exit.code").read_text().strip()
if exit_txt not in {"0", "1"}:
print("exit.code must be 0 or 1")
return 1
digest = sha256(root / "worktree.diff")
print(f"ok job={root.name} diff={digest[:12]} age={age:.0f}s exit={exit_txt}")
return 0
if __name__ == "__main__":
raise SystemExit(main(sys.argv))
Run shape, still proposed:
python3 proposed/check_job_contract.py artifacts/2026-09-05-refactor-auth
echo $?
Green means the worker left evidence. Red means you had a conversation.
Conversations are cheap. Evidence is the gate.
Decision table: laptop, free worker, or neither
Use this before you paste a repo.
| Situation | Laptop | Free remote worker | Do not run here |
|---|---|---|---|
| Throwaway refactor, public sample | Yes | Yes, if artifacts sync back | Anywhere without job.yaml
|
Secrets in .env
|
Maybe, local disk only | No | Any shared home directory |
| You must resume after a dropped tab | Yes, if process survives | Yes, if heartbeat plus artifacts exist | Chat-only sessions |
| You need an SLA | Maybe, your machine | No | "Free" anything |
| You will swap models mid-job | Yes | Yes, endpoint is a variable | Hard-coded model names in scripts |
| Regulated data | Follow your policy | No | Mystery workers |
The table is the whole product pitch I trust.
Free inference does not move a row left. Free shells do not either.
Limitations, said plainly
This contract does not schedule jobs. It does not checkpoint GPUs.
It does not prove the model was truthful. It only proves you kept files.
Heartbeat mtime can lie if the clock jumps. Snapshot hashes miss untracked binaries.
A green checker can still ship a bad patch. Humans still review diffs.
Who should not use this approach:
- Anyone treating a free worker as production capacity.
- Anyone storing customer data on a shared disk.
- Anyone who needs guaranteed uptime from a free box.
- Anyone who thinks a chat export replaces
exit.code.
If you need those guarantees, rent a box you control.
Then keep the same contract. The myths do not get truer when you pay.
The mental model I want stuck on your wall
The model is a function. The server is a worker.
The tab is a camera. The job is a directory.
Free does not collapse those four nouns.
It only removes the invoice from the first two.
So close the tab if you want. Then ask the only question that matters.
Is the directory still there, and did check_job_contract.py exit zero?
If you run the checker on a free worker this week, tell me which claim broke first.
Top comments (0)