DEV Community

Quinn Li
Quinn Li

Posted on

Letter to Sunday-Me: Pack a Worktree, Cap the Retries

Sunday-me, you burned a full day on a free run.
The remote box sat idle while you pasted prompts.
You still lost the afternoon to an unbounded loop.

This letter is the checklist I needed at 09:12.
It is a workflow, not a pep talk.
Read it once. Then pack a smaller tree.

The scene at 09:12

You cloned the whole monorepo onto the laptop.
You pasted the ticket into an empty chat.
No contract. No failing test. No packed worktree.

The first patch touched twelve unrelated files.
One change deleted a fixture the suite needed.
You spent three hours bisecting your own prompt.

Free model access did not freeze the scope.
A free server did not cap retries for you.
Both only move the loop off your laptop.

Where a free remote box actually helps

A later option is MonkeyCode for that loop.
It offers free model access and a free server option.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.

The method below still works without that box.
Keep secrets off any shared machine.
Treat every remote patch as untrusted output.

The three mistakes that cost the day

These are not vibe problems. They are process bugs.
Each one turned a small ticket into a lost Sunday.
Name them before you open the chat window.

Mistake 1: You shipped the whole repo

The agent scanned paths it did not need.
It "fixed" a helper two packages away.
Your diff became a novel. Review died.

Mistake 2: You treated retries as free

The first test failure was a real assertion.
The next fourteen failures were the same line.
You paid with hours, not with a token meter.

Mistake 3: You applied before a local replay

The remote log looked green in the browser.
Your laptop used a different runtime and clock.
The merge broke CI at 16:40. Nobody was shocked.

Artifact: pack, cap, then replay

The artifact is three small files plus a table.
They are a proposed harness, not a live run log.
Copy them onto a throwaway branch and try them.

File 1: ticket.contract.json

One ticket gets one contract. Nothing else.
List files. List bans. Set a hard retry cap.
Do this before any model sees the ticket.

{
  "ticket": "PAY-4412",
  "goal": "Reject empty currency codes in the quote parser.",
  "in_scope": [
    "src/quote/parse.js",
    "test/quote/parse.test.js"
  ],
  "out_of_scope": ["src/quote/legacy.js", "packages/*"],
  "failing_test": "test/quote/parse.test.js",
  "max_retries": 3,
  "max_files_touched": 4,
  "forbidden": ["rm -rf", "curl", "ssh", "npm publish"],
  "receipt_path": "receipts/PAY-4412.json"
}
Enter fullscreen mode Exit fullscreen mode

The prompt should point at this file only.
Do not paste extra narrative into the runner.
Scope lives in JSON, not in chat memory.

File 2: scripts/pack-worktree.sh

This script copies in-scope paths and the contract.
The remote box never sees the rest of the tree.
That packing step is the whole point.

#!/usr/bin/env bash
set -euo pipefail
TICKET="${1:?ticket id}"
DEST=".packed/${TICKET}"

python3 - <<'PY'
import json
from pathlib import Path
c = json.loads(Path("ticket.contract.json").read_text())
Path(".packed-files.txt").write_text("\n".join(c["in_scope"]) + "\n")
PY

rm -rf "${DEST}"
mkdir -p "${DEST}"
rsync -a --files-from=.packed-files.txt ./ "${DEST}/"
cp ticket.contract.json "${DEST}/ticket.contract.json"
echo "packed ${DEST}"
Enter fullscreen mode Exit fullscreen mode

Ship a tarball. Do not ship .env files.
Do not ship node_modules. Do not ship keys.
If the archive grows past a few megabytes, stop.

chmod +x scripts/pack-worktree.sh
./scripts/pack-worktree.sh PAY-4412
tar -C .packed -czf PAY-4412.tgz PAY-4412
ls -lh PAY-4412.tgz
Enter fullscreen mode Exit fullscreen mode

File 3: scripts/validate-receipt.py

A green remote log is not a merge decision.
Gate the receipt JSON before any local apply.
Reject means you rewrite the contract or stop.

#!/usr/bin/env python3
import json, sys, pathlib

contract = json.loads(pathlib.Path("ticket.contract.json").read_text())
receipt = json.loads(pathlib.Path(sys.argv[1]).read_text())

errors = []
if receipt.get("retries", 99) > contract["max_retries"]:
    errors.append("retries exceeded")
files = receipt.get("files_touched", [])
if len(files) > contract["max_files_touched"]:
    errors.append("too many files")
for path in files:
    if path not in contract["in_scope"]:
        errors.append(f"out of scope: {path}")
for cmd in receipt.get("commands", []):
    for bad in contract["forbidden"]:
        if bad in cmd:
            errors.append(f"forbidden: {cmd}")
if "diff_sha256" not in receipt:
    errors.append("missing diff_sha256")

if errors:
    print("REJECT")
    print("\n".join(errors))
    sys.exit(1)
print("ACCEPT")
Enter fullscreen mode Exit fullscreen mode

Proposed receipt shape, for the same ticket:

{
  "ticket": "PAY-4412",
  "retries": 2,
  "files_touched": [
    "src/quote/parse.js",
    "test/quote/parse.test.js"
  ],
  "commands": [
    "npm test -- test/quote/parse.test.js"
  ],
  "diff_sha256": "replace-with-real-hash"
}
Enter fullscreen mode Exit fullscreen mode

Numbered workflow

Work top to bottom. Do not skip packing.
Do not raise max_retries mid-run.
Stop at the first honest red cell.

1. Write the failing test first

Do not open the chat window yet.
Add one assertion that fails on current HEAD.
Commit that test on a branch named for the ticket.

git checkout -b PAY-4412
# add the failing assertion, then:
git add test/quote/parse.test.js
git commit -m "test(PAY-4412): reject empty currency codes"
npm test -- test/quote/parse.test.js
Enter fullscreen mode Exit fullscreen mode

The test must fail for the right reason.
If it fails on setup, stop. Fix the harness.
A red test with a wrong cause wastes the box.

2. Freeze the contract

Fill ticket.contract.json before any prompt.
Name every in-scope file. Name the bans.
Set max_retries to three. Three is a budget.

3. Pack the worktree

Run the pack script. Inspect the archive list.
If a lockfile or secret slipped in, delete it.
Only then upload the tarball to the remote box.

tar -tzf PAY-4412.tgz
Enter fullscreen mode Exit fullscreen mode

4. Run with a capped prompt template

Upload only the archive. Point at the contract.
Tell the agent to stop after max_retries.
Label this block as a template, not a transcript.

Read ticket.contract.json.
Run the failing test first.
Change only in_scope files.
Stop after 3 retries.
Write receipts/PAY-4412.json with commands,
retries, files_touched, and diff_sha256.
Enter fullscreen mode Exit fullscreen mode

Tune the runner to your stack.
Do not paste secrets into that template.
Do not raise the retry cap because the box is free.

5. Validate the receipt

python3 scripts/validate-receipt.py receipts/PAY-4412.json
Enter fullscreen mode Exit fullscreen mode

Reject means you do not apply the patch.
You either shrink the contract or you stop.
A second Sunday is not a strategy.

6. Replay locally before apply

Same runtime. Same fixtures. Same test file.
If replay fails, the remote green was a lie.
Do not "hotfix" the patch by hand on main.

git diff --stat
git apply --check remote.patch
npm test -- test/quote/parse.test.js
Enter fullscreen mode Exit fullscreen mode

Only after replay passes do you apply.
Then run the narrow test one more time.
Then look at git diff with a human eye.

Decision table

Print this table next to the monitor.
Free compute does not override a red cell.
If two cells are red, end the run.

Signal Action Stop if
packed size looks huge shrink in_scope secrets or lockfiles appeared
retries hit 3 rewrite the contract the test fails for a new reason
files_touched leaves scope reject the receipt you "just need one more file"
receipt lacks diff_sha256 reject the receipt the log is prose only
local replay fails do not merge CI is "probably fine"

Limitations

This workflow is for small, test-backed tickets.
It assumes you can name the files in advance.
It assumes the failing test is honest on HEAD.

Do not use it for incident response.
Do not use it with production credentials.
Do not upload customer data to a free server.

A free server is not your compliance boundary.
A free model is not your code reviewer.
You still own the merge and the outage.

Who should skip this approach:

  1. Teams with no test harness at all.
  2. Changes that cannot pack into a few files.
  3. Work bound by a data agreement you cannot meet.

Also skip it when the ticket is exploratory.
A spike needs a time box, not a remote agent.
Do not dress a spike up as PAY-4412.

What Sunday-me should have done by 09:30

One failing test. One contract. One packed tree.
Three retries, then stop. Receipt, then replay.
The day would have ended at the first honest failure.

You did not need a larger prompt that morning.
You needed a smaller worktree and a hard cap.
That is the whole letter. Keep it near the keyboard.

If the contract and the failing test already exist, a free remote box is one place to run the capped loop. Keep the receipt. Keep the secrets off the box.

Top comments (0)