DEV Community

Morgan Xu
Morgan Xu

Posted on

Staff an Airlock for Free Agent Compute

Free agent compute belongs inside a rehearsal airlock. It must never act as a second production path. Teams that skip the airlock mix secrets with drafts.

A free coding model cheapens the first draft. A free server cheapens the first executable run. Cheap compute still writes files and network calls.

Some labs route early trials through MonkeyCode for that cheap lane. Disclosure: This article was prepared as part of MonkeyCode's product outreach. The product offers free model access and a free server option.

This playbook uses only those two availability claims. It does not name models, quotas, or machine sizes. It does not promise duration, benchmarks, or permanence.

The rest of the method is a wiki SOP. Roles, handoffs, and a paste-ready run sit below. The SOP still works if every product name is removed.

The usual failure is not a missing model. The usual failure is an unnamed owner at the keyboard. Someone pastes a production URL into a trial prompt.

Someone mounts a home directory on the free server. Someone lands the agent diff because the run was free. Free does not mean reviewed, isolated, or mergeable.

A hotel gym is not a team weight room. Shared towels do not become a training program. The same logic applies to borrowed agent compute.

False confidence is the real outage. The model answers quickly, so the bench feels official. Speed is not the same thing as custody.

Custody needs names on a card. Four roles keep the airlock honest during rehearsal. Collapsed roles turn the drill into shadow work.

The Lane Owner starts and burns the rehearsal window. That person records the ticket and the allowed repo path. The owner also picks a wall-clock burn time before any prompt.

Two hours is a common drill length. Eight hours starts to look like a shadow project. The owner writes the burn time on the card in UTC.

The Server Steward provisions the free server as a sealed bench. That person refuses home mounts and production credentials. The steward also destroys the bench when the window closes.

A sealed bench behaves like a cleanroom gowning area. Street clothes stay outside the door. Production kube contexts stay outside the door as well.

The Prompt Clerk is the only person who feeds the model. That clerk strips secrets, customer names, and private URLs. The clerk also logs the prompt hash, not raw secret text.

The Patch Acceptor is the only person who can land output. The acceptor treats every file as untrusted until tests pass. A green rehearsal run never equals a merge right.

The allowed path is a subdirectory, not a feeling. Monorepos tempt the agent to wander into sibling packages. The Lane Owner writes one path, and the steward enforces it.

The handoff chain stays short and fully written. Intake moves from Lane Owner to Server Steward first. The steward returns a bench id only after isolation checks pass.

Prompt Clerk then receives the bench id and the ticket. No prompt leaves the clerk until the secret scan is clean. Patch Acceptor receives a patch, a log path, and a burn time.

Silence is not a handoff. A missing name on the card stops the run. The wiki row is the baton, not a chat thread.

The next block belongs in the team wiki. Teams treat it as the one-page run. The card should stay short enough to read aloud.

# Free-Compute Airlock (one page)

Ticket: AIRLOCK-YYYYMMDD-##
Lane Owner:
Server Steward:
Prompt Clerk:
Patch Acceptor:
Allowed path:
Forbidden: prod URLs, customer data, home mounts, long-lived keys
Burn time (UTC):
Bench id:
Prompt hash:
Patch path:
Accept into mainline? yes/no (acceptor only)
Burn confirmed? yes/no (steward only)
Enter fullscreen mode Exit fullscreen mode

The ticket number is the only shared identifier. Chat threads are not a system of record. A blank card means the run does not start.

Isolation is a command, not a feeling. The steward runs the checks on the free server before any prompt. A failed check closes the window at once.

#!/usr/bin/env bash
set -euo pipefail
# airlock-preflight.sh — rehearsal bench only
ROOT="${AIRLOCK_ROOT:-/opt/airlock-rehearsal}"
TICKET="${1:?ticket id required}"
ALLOWED="${2:?allowed path required}"

test -d "$ROOT"
test "$(pwd)" = "$ROOT"

case "$ROOT" in
  /home/*|/Users/*)
    echo "airlock: home mount is forbidden" >&2
    exit 2
    ;;
esac

case "$ALLOWED" in
  "$ROOT"/*) ;;
  *)
    echo "airlock: allowed path is outside the bench" >&2
    exit 2
    ;;
esac

if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
  remote="$(git remote get-url origin 2>/dev/null || true)"
  printf '%s\n' "$remote" | grep -Eqi 'prod|production' && {
    echo "airlock: production remote is forbidden" >&2
    exit 3
  }
fi

if command -v kubectl >/dev/null 2>&1; then
  ctx="$(kubectl config current-context 2>/dev/null || true)"
  printf '%s\n' "$ctx" | grep -Eqi 'prod|production' && {
    echo "airlock: production kube context is forbidden" >&2
    exit 5
  }
fi

if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
  git grep -I -nE 'AWS_SECRET|BEGIN RSA PRIVATE KEY|xoxb-' -- . && {
    echo "airlock: secret pattern in tree" >&2
    exit 4
  } || true
fi

umask 077
mkdir -p "$ROOT/runs/$TICKET"/{prompts,patches,logs}
echo "airlock: bench ready for $TICKET"
Enter fullscreen mode Exit fullscreen mode

The script is deliberately rude. It exits when the workspace looks like a laptop home. It also exits when the git remote or kube context smells like production.

Prompt Clerk runs a second filter before any model call. The filter hashes the prompt and rejects high-risk lines. It never prints the secret back to the terminal.

#!/usr/bin/env python3
"""airlock_prompt_gate.py — labeled example, not a production scanner."""
from __future__ import annotations

import hashlib
import re
import sys
from pathlib import Path

BANNED = re.compile(
    r"(prod\.internal|BEGIN (RSA |OPENSSH )?PRIVATE KEY"
    r"|AKIA[0-9A-Z]{16}|xox[baprs]-|password\s*=\s*\S+)",
    re.I,
)

def main(argv: list[str]) -> int:
    if len(argv) != 3:
        print("usage: airlock_prompt_gate.py TICKET FILE", file=sys.stderr)
        return 2
    ticket, path = argv[1], Path(argv[2])
    text = path.read_text(encoding="utf-8")
    if BANNED.search(text):
        print("airlock: prompt failed secret gate", file=sys.stderr)
        return 4
    digest = hashlib.sha256(text.encode("utf-8")).hexdigest()[:16]
    print(f"airlock: prompt-hash {ticket} {digest}")
    return 0

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

The script is a labeled example, not a production scanner. The patterns are samples, not a complete secret catalog. A real steward should plug in the company scanner.

After a clean gate, the clerk may call the free model on the free server. The output lands only under runs/$TICKET/patches. No other directory is in play.

The acceptor then runs the team's normal tests on that patch. A missing test is a missing review. The airlock does not invent coverage.

TICKET="AIRLOCK-20260914-17"
PATCH="runs/$TICKET/patches/agent.diff"
git apply --check "$PATCH"
pytest -q tests/airlock_smoke
# acceptor signs the wiki card only after both commands pass
Enter fullscreen mode Exit fullscreen mode

The date in the ticket is a label, not a claim about product uptime. The acceptor swaps the smoke path for the repo suite. The apply --check step stays, because it catches a broken diff early.

Burn is a first-class handoff. The steward deletes the bench files at burn time. The Lane Owner marks the card closed in the wiki.

TICKET="AIRLOCK-20260914-17"
ROOT="${AIRLOCK_ROOT:-/opt/airlock-rehearsal}"
rm -rf "$ROOT/runs/$TICKET"
echo "airlock: burned $TICKET"
Enter fullscreen mode Exit fullscreen mode

Logs that must survive go to the ticket, not to chat. The surviving record is the prompt hash, the test command, and the accept decision. Host names from other lanes stay out of the paste.

A failed airlock has a shape. The first shape is a prompt that names a customer. The second shape is a bench that can see a production remote.

The third shape is a patch that lands because nobody wanted to waste a free run. Waste is the point of a drill. A discarded patch is a successful rehearsal when the tests are weak.

After-action is short. The Lane Owner writes three lines on the ticket. What entered the airlock, what left, and what was burned.

Those three lines train the next drill. They are not metrics for a dashboard. They are not proof that free compute is enough for the quarter.

This SOP has sharp limits. It is not an incident responder. It is not a data-loss program for regulated records.

Teams with customer PII should not place that PII on a free server. Teams without a human Patch Acceptor should not run the lane. Teams that need guaranteed capacity should not treat rehearsal compute as a forecast.

The airlock also fails when roles collapse into one person. A single engineer can still use the commands. That person cannot honestly sign every box on the card.

Dual control is the point of the card. A fire drill teaches exits. It does not replace sprinklers.

Borrowed compute stays in the rehearsal airlock. Landing still happens on the team's normal merge path. The cheap lane ends at the wiki row.

Labs that need a sealed rehearsal bench may start from that free model access and free server option on an empty ticket. The SOP above still governs the run.

Top comments (0)