Dev.to AI 🤖 Ai 👁 0 📖 10 min read

The Free Host Said Yes. Your Fence Card Is Still Blank.

A free coding host is not a production fence. I treat a trial login as a risk, not as a vault. That shortcut turns into debt before the first merge. Do you want the short version before the long catalog? Write the fence

A free coding host is not a production fence. I treat a trial login as a risk, not as a vault. That shortcut turns into debt before the first merge.

Do you want the short version before the long catalog? Write the fence card on your laptop before any send. If that card fails, the free box never sees the prompt.

This piece is an anti-pattern catalog, not a product tour. Each item names a symptom, a root cause, and a replacement. I offer the checker as a proposal, not as a measured benchmark.

What the card is for

You have a coding task that a free model can draft. A free server can hold the scratch step off your laptop. That pair is useful, but it is not a vault or an SLA.

I keep the exploratory step behind a fence card. The card does not trust a happy status page or a long chat. Would you merge a patch you cannot explain tomorrow?

Anti-pattern 1: One shared trial key

The symptom is one free key shared across every chat tool. The root cause is a trial login used as a team identity. The replacement is a task id bound to one prompt file.

Shared keys hide who sent the prompt in the first place. They also hide which client the pasted text belonged to. Can you name the owner of yesterday's session right now?

Store the key in a local secret store, never in the repo. Rotate it when a teammate leaves the scratch workflow. A key in a dotfile will leak the moment you share a zip.

Anti-pattern 2: The prompt becomes the spec

The symptom is a requirement that lives only in a chat scroll. The root cause is speed, because the answer made the thread into law. The replacement is a short task file checked in before any call.

A chat scroll is not a reviewable spec for the next person. A task file is small, diffable, and deliberately boring to read. I want the next reviewer to open a file, not a vibe.

Put the goal, the non-goals, and the stop rule in that file. If you cannot write the stop rule, you are not ready. Why would a remote host know your stop rule better than you?

Anti-pattern 3: Two clients, one scratch disk

The symptom is two client notes sharing one server workspace. The root cause is reuse of a disk that stayed dirty. The replacement is one task, one empty workspace, and a wipe note.

Leftover files are not harmless clutter on a scratch disk. They become the next prompt's context by accident. Would you leave two customers' notes in one unlocked drawer?

Name the workspace after the task id before you copy files in. Refuse the run when a foreign task id is still on disk. Wipe is part of the task, not a chore you might remember later.

Anti-pattern 4: Trial host as a CI runner

The symptom is a pull request job starting on the trial host. The root cause is spare-capacity thinking, and free looked like owned CI. The replacement keeps CI on a runner you administer yourself.

Untrusted pull request code plus a shared host is a bad mix. I cannot cite an isolation promise for a trial box in this draft. If you need a hardened runner, this path is the wrong path.

Do not forward webhooks at the free host to save a bill. A saved bill is a poor trade for an unreviewed remote shell. Who owns the blast radius when that shell runs a stranger's script?

Anti-pattern 5: Pins with no local resolver

The symptom is a generated lockfile committed without a local resolve. The root cause is fluency, so a finished-looking file skipped the resolver. The replacement regenerates pins with your own package tool.

A fluent lockfile can still name a package you never chose. Your resolver is the check, and the model output is only a draft. Did you run the install on a machine you actually control?

Diff the regenerated pins against the model draft before you commit. If the diff is huge, stop and read the package names aloud. A huge pin diff is a question, not a gift.

Anti-pattern 6: A pool limit dressed up as a bug

The symptom is a mid-file death that you treat as a code bug. The root cause is a missing local budget file. A pool limit then looks like a logic crash.

The replacement writes a cap beside the task and stops on it. I will not invent a token count, a duration, or a machine size. Those numbers move, and a stale blog figure becomes a trap.

Check the vendor page on the same day you plan the run. Write the cap as a plain integer you are willing to spend. When the run hits the cap, save state and stop the session.

Guessing that the pool is infinite is how scratch work eats the day. A false crash can burn an afternoon that should have been a stop. Do you want a budget line, or another hour of fake debugging?

The replacement pattern

The replacement pattern is a fence card, not a longer prompt. You fill seven lines in a local card file. A script refuses the send when any line is blank.

The free model and the free server stay behind that refusal. Here is the card I want sitting next to the task file. Treat it as a proposal you can adopt, not as a lab result.

  • The card protects the next reviewer from a chat-only spec.
  • The card protects a second client from a dirty scratch disk.
  • The card protects your CI from a trial host you do not run.
task_id=2026-10-10-fence-01
workspace=empty
clients=one
secrets_in_prompt=no
ci_target=owned-runner
budget_cap=budget.txt
wipe_after=yes

Seven lines keep the rule obvious to a reviewer. A blank line is a failed review, not a minor nit. If a line is blank, you are not ready for a remote draft.

Run the checker before the send

Fail closed on your laptop

The script below is unexecuted example code for the local check. It reads the card file and the task file only. It does not open a network connection of any kind.

This parser reads KEY=value lines and does not source the card. It is not a full secret scanner, so do not pretend otherwise. I am not shipping this as a tested release.

#!/usr/bin/env bash
# Proposal only. Fail closed before any free-host prompt.
set -euo pipefail

card="${1:-fence-card.env}"
prompt="${2:-task.md}"

test -f "$card" || { echo "missing card"; exit 2; }
test -f "$prompt" || { echo "missing task file"; exit 2; }

get() {
  key="$1"
  line=$(grep -E "^${key}=" "$card" | head -n 1 || true)
  test -n "$line" || { echo "missing $key"; exit 2; }
  printf '%s' "${line#*=}"
}

task_id=$(get task_id)
workspace=$(get workspace)
clients=$(get clients)
secrets_in_prompt=$(get secrets_in_prompt)
ci_target=$(get ci_target)
budget_cap=$(get budget_cap)
wipe_after=$(get wipe_after)

test "$workspace" = "empty" || { echo "workspace must start empty"; exit 3; }
test "$clients" = "one" || { echo "one client per scratch task"; exit 3; }
test "$secrets_in_prompt" = "no" || { echo "prompt must stay free of secrets"; exit 3; }
test "$ci_target" = "owned-runner" || { echo "do not aim CI at the trial host"; exit 3; }
test -f "$budget_cap" || { echo "budget cap file missing"; exit 3; }
test "$wipe_after" = "yes" || { echo "plan the wipe before the run"; exit 3; }

if grep -E -q 'AKIA[0-9A-Z]{16}|-----BEGIN |api[_-]?key[[:space:]]*[:=]' "$prompt"; then
  echo "prompt looks like it carries a secret marker"
  exit 4
fi

mkdir -p .fence
printf '%s\n' "task_id=$task_id" "card=$card" "prompt=$prompt" > ".fence/${task_id}.decision"
echo "fence card passed for $task_id"

Run the checker like this before you open a remote session. Create a one-line budget file before you expect a pass. A missing budget file is a failed card, not a warning.

printf '%s\n' "set-your-cap" > budget.txt
chmod +x fence-card.sh
./fence-card.sh fence-card.env task.md
echo "exit=$?"

A non-zero exit means you stay on the laptop and fix the card. A zero exit means the card is complete, not that the code is correct. You still review the diff on a machine you trust.

Where the free step belongs

I send the free step only after the checker prints a pass. The model may draft, and the server may run one scratch command. The laptop still owns the spec, the pins, and the final diff.

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

MonkeyCode, for this draft, is relevant only after the card passes. The operator-supplied note is free model access plus a free server option. The operator also describes the project as open source.

I am not linking a repository, because no primary URL was supplied here. I am not stating a quota, a chip type, a time box, or permanence. Read the current project docs before you plan around either option.

If those docs disagree with this paragraph, trust the docs. A blog post is a workflow note, not a contract or a status page. Would you put a client export on a host you cannot describe?

That pair can hold an exploratory draft and a scratch command. It should not hold customer data, production deploys, or shared CI. Silence in the docs is a stop sign, not a blank check.

Six questions before the send

Use these six checks when you decide whether the send is allowed. One failed check blocks the send, even if the other five pass. I would rather lose a draft than mix two clients on one disk.

  1. Stay local when the task file is not already in git.
  2. Wipe first when the workspace does not start empty.
  3. Stop now when the prompt shows a secret marker.
  4. Do not retarget CI onto a host you do not administer.
  5. Do not start when the budget file is missing from disk.
  6. Do not start when you cannot wipe the workspace afterward.

These checks are a habit, not a certification of the remote host. A printed list still needs a human who will honor a failed row.

What the card does not prove

Leave the numbers on today's docs

The grep line is a tripwire, not a certified secret scanner. A clever paste can still sneak past a short pattern list. Use a real scanner when your org already runs one.

The card does not prove isolation on a remote host. It does not prove uptime for the remote host. It does not prove that a zero price will last.

Free access can change, so keep a local fallback ready. I did not run a benchmark for this script. I did not time a model, and I did not measure a server.

The checker only tests that the budget file exists. It does not parse the integer, so you still have to honor it. A file full of jokes is a pass, and that is a real limit.

If you need numbers, measure your own task and date the note. Paste the date next to the figure so the next reader sees the age. An undated metric is how old limits sneak into new posts.

Who should skip this path

Skip this path when the data is regulated or under a client contract. Skip it when you need a stated service level or a fixed machine shape. Skip it when the team will not keep the card inside review.

Also skip it if you cannot wipe the scratch workspace after the task. A free server you cannot reset is a shared disk with a login page. Are you comfortable reading that disk out loud in a retro?

A five-step local test

  1. Drop a fake key marker into the task file and confirm exit code four.
  2. Set the workspace value to dirty and confirm exit code three.
  3. Remove the budget file and confirm the script stops before a pass.
  4. Pass a clean card and confirm the decision file appears.
  5. Keep that file next to the task so review can see the refusal trail.

Do not point this test at production, because the pass is only local. That plan is enough to trust the gate you actually have. It is not enough to trust a remote host you have not read.

Read the host policy on the same day you decide to use it. If the policy is silent on isolation, do not invent a promise. A quiet policy page is not the same thing as a guarantee.

Close the loop on your laptop

Free model access can speed a draft you already scoped. A free server can hold scratch work after the card passes. Neither one replaces the card, the task file, or the wipe plan.

I start with the card, and the remote step stays optional after that. If you already use that free model access, run this checker first. Then read today's limits in the project docs before you plan load.

Keep the final merge on a repository you control and can revert. A remote draft is only a guest in your workflow. Your repo is the host, and the host sets the rules.

📰 Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.