On a Friday afternoon a backend engineer asked an assistant to tame a queue consumer that dropped jobs after a short idle timeout. The session produced three new helper types, a renamed package, and a long comment that restated the original ticket. The timeout still fired on the staging worker, yet the pull request looked busy enough to survive review. The team had spent attention on motion, not on a claim that could live or die.
A ninety-minute spike is a poor container for that motion because the clock only measures elapsed time. Without a frozen predicate, the assistant treats every unused file as an invitation, and the human treats extra functions as care. The useful analogy is a lab assay rather than a sketchbook: one sample, one reagent, and one pass-or-fail readout. Anything that cannot change the readout is contamination, even when the contamination compiles and looks tidy in review.
Busy diffs have become easier to mistake for engineering now that assistants can fill a branch before the coffee cools. The problem is not raw speed, because a fast wrong branch still wastes the next review cycle. A session without a kill condition cannot falsify its own story, so the story grows until it resembles a design. A time box only helps when the box contains one predicate, one allowed path set, and a verdict that can delete the branch.
Freeze the claim before the first prompt
The workflow below is a proposed contract, not a report of a measured production trial. It assumes a small service with tests, a disposable git branch, and one falsifiable sentence a command can decide. The sentence is frozen before the first prompt, then executed at minute ninety on a machine that is not the laptop. If the command is still red, the branch is deleted and the hypothesis is recorded as killed.
Create a spike/ directory at the repository root and store the claim as JSON so the referee can parse it with the standard library.
{
"id": "idle-ack-2026-09-18",
"claim": "After thirty seconds without a message, the consumer still acks the next published job within two seconds.",
"allowed_globs": [
"src/consumer/**",
"tests/test_idle_ack.py"
],
"pass_cmd": ["python", "-m", "pytest", "tests/test_idle_ack.py", "-q"],
"clock_sec": 5400
}
The claim is deliberately narrow and does not mention retries, dashboards, or a rewrite of the worker supervisor. Those leftover topics can wait for a later spike that carries its own predicate file and its own clock. The allowed globs are the only soil the experiment may till during the ninety-minute window. A change outside that soil means the spike expanded itself and therefore failed, even if the test later turns green.
A failing test must exist before the clock starts, because a green suite cannot kill a hypothesis. The following sketch targets a Python consumer that talks to a fake broker during the assay.
# tests/test_idle_ack.py
# Proposed failing test. Freeze this file before prompting an assistant.
import time
from consumer.worker import Worker
from consumer.testing import FakeBroker
def test_ack_after_thirty_second_idle():
broker = FakeBroker()
worker = Worker(broker, ack_deadline_s=2)
worker.start()
time.sleep(30)
job_id = broker.publish({"kind": "invoice"})
deadline = time.time() + 2
while time.time() < deadline:
if broker.acked(job_id):
worker.stop()
return
time.sleep(0.05)
worker.stop()
raise AssertionError("job was not acked within two seconds after idle")
Run that test once on a clean branch so the freeze includes a red result rather than a hope.
git checkout -b spike/idle-ack-2026-09-18
python -m pytest tests/test_idle_ack.py -q
test -f spike/predicate.json
sha256sum spike/predicate.json tests/test_idle_ack.py > spike/freeze.sha256
chmod +x spike/referee.py spike/clock.sh
git add spike/predicate.json spike/freeze.sha256 tests/test_idle_ack.py spike/referee.py spike/clock.sh
git commit -m "freeze idle-ack predicate and red test"
python3 spike/referee.py; echo "expected non-zero before the agent works"
Let a referee delete the branch
A small referee then judges the working tree and refuses to pretend that style is the same as evidence. It checks the freeze hash and confirms that every dirty path still matches an allowed glob. It then runs the pass command and treats a non-zero exit as a kill. The script is labeled as a proposed example and uses only the Python standard library.
#!/usr/bin/env python3
"""Proposed spike referee. Unexecuted example."""
import fnmatch
import json
import pathlib
import subprocess
import sys
def path_allowed(path, globs):
posix = path.replace("\\", "/")
for glob in globs:
if glob.endswith("/**"):
prefix = glob[:-3].rstrip("/")
if posix == prefix or posix.startswith(prefix + "/"):
return True
elif fnmatch.fnmatch(posix, glob):
return True
return False
pred = json.loads(pathlib.Path("spike/predicate.json").read_text())
frozen = pathlib.Path("spike/freeze.sha256").read_text()
current = subprocess.check_output(
["sha256sum", "spike/predicate.json", "tests/test_idle_ack.py"],
text=True,
)
if current != frozen:
print("KILL: freeze hash drifted")
sys.exit(2)
changed = subprocess.check_output(
["git", "diff", "--name-only", "HEAD"], text=True
).splitlines()
changed += subprocess.check_output(
["git", "ls-files", "--others", "--exclude-standard"], text=True
).splitlines()
for path in filter(None, changed):
if path.startswith("spike/"):
continue
if not path_allowed(path, pred["allowed_globs"]):
print(f"KILL: scope expanded to {path}")
sys.exit(3)
result = subprocess.run(pred["pass_cmd"])
if result.returncode == 0:
print("SHIP: predicate held")
sys.exit(0)
print("KILL: predicate still red")
sys.exit(1)
The clock is a separate envelope so neither the human nor the assistant can bargain for extra minutes after a near miss. The wrapper starts the referee under timeout, writes a one-line verdict, and deletes the branch when the predicate stays red. Ninety minutes is enough to change a small consumer and not enough to hide an unbounded rewrite inside helpers. The envelope exists to make that limit mechanical, so a near miss cannot beg for one more prompt.
#!/usr/bin/env bash
# spike/clock.sh — proposed ninety-minute envelope
set -euo pipefail
BRANCH="$(git branch --show-current)"
CLOCK_SEC="${CLOCK_SEC:-5400}"
set +e
timeout "$CLOCK_SEC" python3 spike/referee.py
verdict=$?
set -e
if [ "$verdict" -eq 0 ]; then
printf 'SHIP %s\n' "$BRANCH" | tee spike/verdict.txt
exit 0
fi
printf 'KILL %s code=%s\n' "$BRANCH" "$verdict" | tee spike/verdict.txt
git checkout main
git branch -D "$BRANCH"
exit "$verdict"
That deletion step is the part most teams skip, and it is the part that keeps the spike honest. A surviving branch with a red predicate becomes a souvenir of almost-work, and souvenirs attract follow-up prompts that quietly restart the clock. Killing the branch does not kill the learning stored beside it on the default branch. The verdict file and freeze hash can remain on main as a record that the claim failed under the stated globs.
Laptop green is a weak witness for an idle timer, because the fake broker and the wall clock share the same distracted machine. The readout belongs on a disposable host that did not also author the diff sitting in the working tree. Teams can run that referee on MonkeyCode, an open-source assistant with free model access and a free server option. Disclosure: This article was prepared as part of MonkeyCode's product outreach.
Frozen files are authored locally, and the assistant may propose diffs only inside the allowed globs. Only the remote exit status is allowed to write a SHIP line into the verdict file. A practical remote loop copies the branch, runs the same clock script, and prints the verdict file. Model names, hardware details, and numeric quotas are omitted because they are unnecessary to the contract and they drift.
# Proposed remote readout. Replace TARGET with a disposable server you control.
git push origin "spike/idle-ack-2026-09-18"
ssh TARGET 'set -e
cd /work/service
git fetch origin spike/idle-ack-2026-09-18
git checkout spike/idle-ack-2026-09-18
bash spike/clock.sh
cat spike/verdict.txt'
If the server cannot import the test dependencies, the spike is killed for an environmental reason, which is still a valid kill. Substituting the laptop result would smuggle a second hypothesis into the same clock: that local and remote runtimes match. That second hypothesis deserves its own predicate on another day, not a footnote on this one. Environment drift is a killed spike, not a license to lower the bar until something looks green.
What this contract cannot decide
The same strictness that makes the assay useful also makes it the wrong tool for several common jobs. Incidents that need parallel investigation will hide the second failure inside a single predicate, then declare victory too early. If the failing test cannot be written in the first quarter of the clock, the remaining minutes fund speculation rather than a readout. Multi-repo changes, irreversible schema migrations, and visual design work do not compress into one command's exit status without cartoonish tests.
Free model access does not make an unbounded prompt cheaper in attention; it only removes a billing reason to stop typing. A free server is not a load test and should not be treated as evidence about production tail latency. People who already know the fix should skip the theater and open a normal branch with a normal review. People blocked from deleting branches should freeze the predicate, then lock a tag that review tools refuse to merge.
People hunting for a general architecture story should not use a ninety-minute spike, because a predicate that large is a manifesto. The Friday consumer can be tried again under this contract without expanding into a rewrite. The hypothesis is only the idle ack, and the assistant gets one branch, one glob, and ninety minutes on a disposable server. At the end the team either merges a green predicate or reads a kill line and walks away without a souvenir diff.
Top comments (0)