DEV Community

Alex Zhu
Alex Zhu

Posted on

Before an Agent Job Touches a Shared Box: Five Assumption Checks, Three Roles, One Wiki Page

The log ends mid-line. There is no traceback, no exit code from your job, and no clue about which write failed — only a half-finished record on a machine you do not administer. You re-run the same job on your laptop, it passes, and that is the moment you learn that "it works" was never the claim you needed to verify.

Agent jobs on shared hardware rarely fail because the model is wrong. They fail because the workspace turned read-only, the clock drifted far enough to expire a token, egress to one host is blocked, or two runs are interleaving writes into the same directory. None of that appears in a capability review, because these are not questions about what the box can do. They are questions about what you quietly assumed it would keep doing.

This playbook converts those assumptions into five checks, three roles, and a single wiki page you can paste before a job is allowed to start.

1. Placement is a decision, not a default

Most teams answer one question — "can this machine run the job?" — and skip the second one, "should this job live here at all?" The first question gets answered by a successful run, which is a sample of size one on a machine you do not own.

Treat placement as a written decision with a named owner. The artefact does not need to be long: a run line, five checked assumptions, and a hash of the report that proved them. What matters is that the decision is recorded somewhere a reviewer can read without opening your terminal history.

Why this lands harder on a shared or free tier

When you rent a dedicated host, the environment is boring and you stop thinking about it. When you use a free tier, the trade you accepted is exactly that the box is shared, may be recycled, and is not yours to configure. MonkeyCode offers free model access and a free server option, which drops the cost of an agent run close to zero — and that is precisely the condition under which a team stops writing down its environmental assumptions, because retrying feels cheaper than documenting.

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

I am deliberately not printing a token allowance or a hardware spec here. Those numbers change, and a stale figure in a tutorial becomes a bug report three weeks later. Check the project's own page for the current limits before you plan around them.

2. The five assumptions worth checking

Each row is cheap to verify and expensive to discover late.

Assumption What breaks without it Cheap check
The workspace is writable with headroom a mid-run write fails, or the disk fills silently touch a probe file, then df -Pm
The wall clock is roughly correct token expiry, cache TTLs, and log ordering all lie compare to an HTTP Date header
Every host the job needs is reachable the call hangs until your timeout, not the server's one HEAD request per host
The credential exists and is never printed an hour lost to 401s you cannot see length check plus a short hash
You are the only writer for this run two agents interleave writes into one directory flock on a run lock

Note what is absent: no performance measurement, no model comparison, no throughput claim. This is an assumption ledger, not a benchmark. If you want the capacity side, that is a separate exercise with a separate owner.

3. Three roles and two handoffs

Keep the role count low enough that a small team will actually honour it.

Run Owner. Writes the run line, owns the five assumptions, pastes the preflight report into the wiki page. Does not get to declare the job ready.

Box Steward. Owns the shared host or tier, maintains the egress allowlist, and is the only person who can sign an exception. When a check fails and the job must still run, the steward writes down which assumption is being waived and until when.

Reviewer. Reads the run line and the report hash before the work merges. The reviewer's job is not to re-run the script; it is to notice when a report is three days old or when the run line quietly grew a second egress host.

There are two handoffs. The first is Run Owner → Box Steward when any line reports FAIL. The second is Run Owner → Reviewer when the gate passes. Both handoffs are wiki edits, not messages, so the next person to touch the job inherits the reasoning.

4. Step 1 — drop the preflight script into the repo

The script below asserts the five assumptions and prints one line per check. It is intentionally boring, and it exits non-zero whenever anything fails.

#!/usr/bin/env bash
# preflight.sh — assert five assumptions before an agent job starts.
# Usage: WORKDIR=./work EGRESS_HOSTS="api.example.com" ./preflight.sh > preflight.report
set -uo pipefail

WORKDIR="${WORKDIR:-$PWD/work}"
EGRESS_HOSTS="${EGRESS_HOSTS:-api.example.com}"
SECRET_VAR="${SECRET_VAR:-MODEL_API_KEY}"
MIN_FREE_MB="${MIN_FREE_MB:-512}"
MAX_SKEW_S="${MAX_SKEW_S:-120}"
LOCK="${LOCK:-/tmp/agent-run.lock}"

fail=0
line() { printf '%-8s %-22s %s\n' "$1" "$2" "$3"; }
ok()   { line OK "$1" "$2"; }
bad()  { line FAIL "$1" "$2"; fail=1; }

# 1 — workspace is writable with headroom
if mkdir -p "$WORKDIR" && touch "$WORKDIR/.probe" 2>/dev/null; then
  rm -f "$WORKDIR/.probe"; ok workspace.writable "$WORKDIR"
else
  bad workspace.writable "$WORKDIR not writable"
fi
free_mb=$(df -Pm "$WORKDIR" 2>/dev/null | awk 'NR==2 {print $4}')
if [ -n "${free_mb:-}" ] && [ "$free_mb" -ge "$MIN_FREE_MB" ]; then
  ok workspace.headroom "${free_mb}MB free"
else
  bad workspace.headroom "${free_mb:-unknown}MB free, need ${MIN_FREE_MB}"
fi

# 2 — wall clock agrees with a public reference within tolerance
first_host=${EGRESS_HOSTS%% *}
local_epoch=$(date -u +%s)
remote_epoch=$(curl -sS -m 5 -I "https://$first_host" 2>/dev/null \
  | awk 'BEGIN{IGNORECASE=1} /^date:/ {sub(/^[Dd]ate: +/, ""); print}' \
  | tr -d '\r' | xargs -r date -u -d)
if [[ "${remote_epoch:-}" =~ ^[0-9]+$ ]]; then
  skew=$(( local_epoch > remote_epoch ? local_epoch - remote_epoch : remote_epoch - local_epoch ))
  if [ "$skew" -le "$MAX_SKEW_S" ]; then ok clock.skew "${skew}s"; else bad clock.skew "${skew}s over tolerance"; fi
else
  bad clock.skew "no usable Date header from $first_host"
fi

# 3 — every host the job needs answers
for host in $EGRESS_HOSTS; do
  code=$(curl -sS -m 8 -o /dev/null -w '%{http_code}' "https://$host" 2>/dev/null || echo 000)
  if [ "$code" != "000" ]; then ok egress.$host "HTTP $code"; else bad egress.$host "unreachable"; fi
done

# 4 — credential present, never printed
value="${!SECRET_VAR:-}"
if [ "${#value}" -ge 16 ]; then
  digest=$(printf '%s' "$value" | sha256sum | cut -c1-10)
  ok secret.present "$SECRET_VAR sha256:$digest"
else
  bad secret.present "$SECRET_VAR missing or too short"
fi

# 5 — this process is the only writer for this run
exec 9>"$LOCK"
if flock -n 9; then ok run.lock "acquired $LOCK"; else bad run.lock "$LOCK held elsewhere"; fi

if [ "$fail" -eq 0 ]; then echo "SUMMARY PASS"; else echo "SUMMARY FAIL"; fi
exit "$fail"
Enter fullscreen mode Exit fullscreen mode

Two portability notes before you copy this. It assumes bash 4 or newer for the indirect expansion ${!SECRET_VAR}, plus GNU coreutils and flock; on macOS, replace the date -u -d reference parse with gdate or a small Python one-liner. Keep the script in the job repo rather than in someone's home directory, so the reviewer can read exactly what was checked.

5. Step 2 — gate the run on a fresh report

A preflight nobody is required to read is a decoration. Wrap it in a gate that refuses to start the job without a complete report.

#!/usr/bin/env bash
# gate.sh — refuse a run unless the latest preflight report is complete.
set -euo pipefail
report="${1:?usage: gate.sh <preflight.report>}"
run_id="${2:-$(date -u +%Y%m%dT%H%M%SZ)}"

if grep -q '^FAIL' "$report"; then
  echo "gate: fail  run=$run_id  see $report" >&2
  exit 1
fi

for key in workspace clock egress secret run; do
  if ! grep -qE "^OK[[:space:]]+${key}" "$report"; then
    echo "gate: missing OK for $key  run=$run_id" >&2
    exit 1
  fi
done

stamp=$(sha256sum "$report" | cut -c1-12)
echo "gate: pass  run=$run_id  report=$stamp" | tee -a "$report"
Enter fullscreen mode Exit fullscreen mode

The gate checks that each assumption reported at least one success, so a report where egress checks were skipped cannot pass on the strength of the other four. The report hash is what you paste into the wiki; it is short enough to read and long enough to spot a swapped file.

6. Step 3 — paste the one-page run into the wiki

This is the whole page. Fill it in once per job, then edit it in place forever.

# Agent run: <job-name>

Owner:        @<handle>   (run line, five assumptions)
Box steward:  @<handle>   (shared host or tier, signs exceptions)
Reviewer:     @<handle>   (reads report + run line before merge)

## Run line
job=<job-name> box=<host-or-tier> workdir=<path> egress=<host1,host2> \
  secret=<VAR> deadline_utc=<YYYY-MM-DDTHH:MMZ>

## Steps
1. Preflight lives in the repo at `scripts/preflight.sh`. No local-only copies.
2. Run: `WORKDIR=<path> EGRESS_HOSTS="<hosts>" ./scripts/preflight.sh > preflight.report`
3. Paste the `SUMMARY` line and the report hash here.
4. Any `FAIL` → open an exception row with the steward. Do not retry first.
5. Run `scripts/gate.sh preflight.report`. Paste its output. Only then start the job.
6. After the run, append exit code, wall time, and the first line that scrolled past you.

## Exceptions
| date | assumption waived | signed by | expires |
| --- | --- | --- | --- |
|  |  |  |  |
Enter fullscreen mode Exit fullscreen mode

Step 6 matters more than it looks. The first line that scrolled past is usually the one that explains the next failure, and it costs nothing to write down while the run is still fresh.

7. Step 4 — decide where the job belongs

Use the same page to argue about placement instead of relitigating it in chat.

Job shape Where it belongs Why
Interactive debugging, minutes, one credential your laptop fastest loop, no shared state
Repeatable batch, small working set a shared free box cheap and disposable, and preflight keeps it honest
Needs a stable public IP or inbound port a host you administer shared egress is not yours to promise
Large local dataset, GPU, big temp space a sized host you pay for disk assumptions break quietly
Secret-heavy or regulated data your own environment five checks are not a security review

Write the chosen row into the run line as box=. A future you reading the page will not remember why the job moved, and the table is a cheaper reminder than a postmortem.

Limitations and who should skip this

The preflight is a point-in-time assertion. It proves the environment at the second you ran it, and a shared box can change its mind ten minutes later; the gate is a speed bump, not a guarantee. It measures nothing about performance, quality, or cost. And the flock check is advisory — it stops cooperating runs, not a determined one.

Skip this playbook if configuration management or existing health checks already cover your hosts, if you run single-tenant infrastructure you fully control, or if your job starts in under a second and cannot tolerate a probe. Likewise skip it if the workload is regulated: the five checks tell you the box is usable, not that it is auditable.

If you want a target to practise on before you write the real page, the free model access and free server option in the MonkeyCode project give you a machine you can throw away while you learn what your job actually assumes — start with the project's own documentation so your run line matches the current limits.

Top comments (0)