A shared coding agent fails at shift change, not generation. The model still answers after the humans leave. Silent drift starts in that quiet ownership gap.
Treat the shared box like a relay desk, not a laptop. One named owner holds the baton during the live run. The next owner takes that baton only in writing.
Teams skip this paperwork because generation feels cheap and fast. Cheap output still lands in the shared git history. A midnight refactor without a closer becomes tomorrow's mystery branch.
The agent did not lie to anyone on purpose. It continued an assumption nobody wrote down. Unspoken assumptions travel farther than any prompt.
The failure mode looks like competence from a distance. Files still compile and the unit tests stay green. Product intent has rotated under those green lights.
The next shift inherits a confident stranger in the tree. That stranger speaks in diffs, not in goals. People argue with the diff instead of the ticket.
This playbook treats agent work as air traffic control. A controller never leaves a scope in the dark. The next controller reads heading and altitude on paper.
A coding agent needs that same paper strip on disk. Chat history is weather, not clearance. Clearance lives in a small frozen file.
The desk clerk owns intake and nothing else at all. That person writes the goal, the repo, and the stop line. The clerk refuses to run the agent session.
Vague tickets die at the intake door every time. A heading like make it better is not a heading. The clerk sends that work back to a human author.
The shift owner runs the live session on the box. That person alone may send prompts to the agent. That person alone may kill the running process.
When the clock ends, the owner freezes the desk. Freeze means no extra last try after the bell. Last tries are how frozen desks thaw into chaos.
The closer reads the freeze ticket before any merge. The closer merges, reverts, or parks the branch. The closer never continues the old chat by habit.
Continuation of work needs a fresh ticket with new assumptions. The old thread is evidence for the closer, not a mandate. Evidence can be quoted. Mandates must be rewritten.
These three roles can sit on a single human. The names still matter on tired overlapping days. A solo owner switching hats still writes the freeze.
Paper is the protocol that survives a noisy office. Memory is not a protocol under pager load. Write the baton down, then walk away.
Paste the next block into the team wiki today. Keep the page ugly and keep it short. Do not dress the run with slogans or banners.
# Agent Relay Desk — One-Page Run
Status: template for a shared coding agent
Scope: one box, one live owner, one ticket
Hard rule: no OWNER file means no prompt
Freeze clock
Shift end minus 15 minutes: reject new tasks
Shift end minus 5 minutes: write TICKET.yml freeze
Shift end: stop the process or park the branch
Baton files
.relay/OWNER — unix name of the live shift owner
.relay/TICKET.yml — current assumption ticket
.relay/log.jsonl — append-only handoff log
Stop line
The agent stops when the ticket command exits zero
The agent does not stop when the model feels done
The closer, not the model, declares the run closed
The assumption ticket is a small YAML file on purpose. Boring files survive night shifts and cheap laptops. Clever dashboards die when the VPN blips.
id: 2026-09-06-auth-timeout
repo: payments-api
branch: relay/auth-timeout
goal: >
Return 401 on expired access tokens without
dropping the refresh path in auth_middleware.go
assumptions:
- refresh tokens still live in redis
- no API version bump in this run
- middleware tests in auth_test.go are the stop line
out_of_scope:
- login UI
- rate limits
stop_line: go test ./internal/auth -count=1
owner: ava
closer: nico
state: frozen
A new shift starts by reading that file aloud. Reading aloud sounds theatrical in a quiet room. It still catches silent edits nobody meant to ship.
If a line cannot be spoken, it is not agreed. Split the ticket until speech is cheap again. Two frozen tickets beat one epic chat swamp.
The relay log is append-only JSONL on the box. Nobody rewrites history at two in the morning. A small shell helper is enough for the baton.
#!/usr/bin/env bash
# relay.sh — example helper, not a service
set -euo pipefail
ROOT="$(git rev-parse --show-toplevel)"
DIR="$ROOT/.relay"
mkdir -p "$DIR"
cmd="${1:-}"
shift || true
case "$cmd" in
claim)
who="${1:?unix name required}"
if [[ -f "$DIR/OWNER" ]]; then
echo "desk occupied by $(cat "$DIR/OWNER")" >&2
exit 1
fi
echo "$who" > "$DIR/OWNER"
printf '{"ts":"%s","event":"claim","who":"%s"}\n' \
"$(date -u +%FT%TZ)" "$who" >> "$DIR/log.jsonl"
;;
freeze)
test -f "$DIR/OWNER"
test -f "$DIR/TICKET.yml"
who="$(cat "$DIR/OWNER")"
printf '{"ts":"%s","event":"freeze","who":"%s"}\n' \
"$(date -u +%FT%TZ)" "$who" >> "$DIR/log.jsonl"
mv "$DIR/OWNER" "$DIR/OWNER.last"
;;
*)
echo "usage: relay.sh claim USER | freeze" >&2
exit 2
;;
esac
Label this script as an example in the wiki. It has not been certified for production use. It refuses a second claim, and that refusal is the point.
A tiny Python check can sit in CI later. It does not grade the model output at all. It grades the paperwork before a run may start.
# check_relay.py — example gate, labeled unexecuted
from pathlib import Path
import sys
import yaml
root = Path(".")
ticket = root / ".relay" / "TICKET.yml"
owner = root / ".relay" / "OWNER"
if not ticket.exists():
sys.stderr.write("no assumption ticket; refuse the run\n")
sys.exit(1)
data = yaml.safe_load(ticket.read_text())
required = ["goal", "assumptions", "stop_line", "state"]
missing = [k for k in required if not data.get(k)]
if missing:
sys.stderr.write(f"ticket missing {missing}\n")
sys.exit(1)
if data.get("state") == "frozen" and owner.exists():
sys.stderr.write("frozen ticket still has a live owner\n")
sys.exit(1)
print("relay paperwork ok")
Install PyYAML only if the team already depends on it. A strict hand parse also works for this gate. The check should fail closed when files are missing.
Missing files mean no run, not a friendly warning. Warnings get ignored during a busy handoff. Closed gates make the wiki page real.
The daily rhythm stays short on purpose. The clerk files the ticket before the first coffee. The owner claims the desk and works the stop line.
Fifteen minutes before shift end, new tasks stop cold. Five minutes before the end, the freeze is written. The closer arrives and reads the ticket aloud.
Then the closer merges, reverts, or parks the branch. The next owner claims only after OWNER is gone. Stolen desks create two truths in one repo.
Handoff talk can last four minutes and then end. Longer meetings usually hide a missing baton file. If the ticket needs a speech, the goal is too wide.
Failed handoffs share a smell across many teams. The chat is long and the ticket is thin. The branch name is cute and the stop line is mood.
Cute branches hide fear of naming the real constraint. Choose a stop line a machine can execute now. A test command is a valid stop line for the closer.
A screenshot is not a stop line for this desk. A vibe is not a stop line on a shared box. If the team cannot name the command, wait.
The work is not ready for a shared agent yet. Keep it on a private laptop until the command exists. Shared desks amplify unfinished intent.
The OWNER file is a lock, not a trophy on the wall. Locks expire in social space, not in kernel space. If Ava leaves without freeze, Nico does not force-claim.
Nico pings Ava through the normal team channel. If Ava is gone, the closer parks the branch instead. Park means the branch stays and the process dies.
The ticket state becomes parked, not secretly active. Next morning starts a new ticket on that branch. It does not reopen the old chat as living law.
Chat history is a swamp beside the work path. The ticket is a pier over that swamp. Walk on the pier when the shift changes.
Shared free boxes make this pattern both worse and better. Worse, because anyone with access can type a prompt. Better, because one machine maps to one OWNER file.
Two laptops arguing with one agent is the original sin. The relay desk exists to make that sin visible. Visibility is cheaper than a three-hour revert later.
Some teams still need a host for the rehearsal week. Disclosure: This article was prepared as part of MonkeyCode's product outreach. MonkeyCode provides free model access and a free server option.
A team can park this relay desk there while the habit forms. The files do not care about the vendor on the box. Drop the host and the freeze rule still stands.
Teams that lack a spare machine may try that free server option for a dry run. Do not treat any free host as a production cluster. Do not store secrets inside the assumption ticket.
Do not let the agent rewrite the .relay directory. Add that path to the model's ignore rules, not gitignore. Git should see the paper trail after every freeze.
The model should not edit the paper it is bound by. A bound agent that can edit its leash will chew it. Keep the leash in human-owned files.
Limitations are sharp and should stay sharp. This SOP will annoy a focused solo hobbyist. One person already holds the full context in working memory.
The files become theater in that solo setting. Skip them until a second human appears. Theater trains contempt for the later real desk.
Incident commanders should not use this during a live outage. A fifteen minute freeze window is too slow for fire. Use the pager protocol the team already trusts.
Resume the relay after the incident record closes. Do not mix firefighting chats into a frozen ticket. Mixed tickets teach the next shift the wrong lesson.
Regulated teams with change boards already carry heavier paper. Do not run two systems that disagree at merge time. Map the assumption ticket into the existing change record.
Duplicate gates create a shadow process nobody respects. Shadow process is how agents sneak around review. One paper path is slower and safer.
The agent will still assume things after all this work. The SOP does not make the model honest or small. It makes the humans agree on what was assumed.
Agreement is the only baton that survives a shift change. Keep the wiki page ugly so people keep using it. Beautiful pages get redesigned while the desk sits empty.
The relay desk is a loading dock with a pen. Sign the pallet before the truck leaves the bay. Then walk away until the next claim.
Top comments (0)