Tonight I am writing a gate, not a victory lap. The fixture is a small CLI draft on a scratch branch. A free model may write that first pass. One sample run can still print a neat table. Would you merge on that smile alone? I would not ship it on a smile.
DEV is full of vibe-code arguments this week. I am not relitigating portfolios or website taste. My fight is smaller, and meaner. A solo CLI can look finished after one lucky run. Where is the receipt that proves you can leave?
The failure I keep seeing
You ask for a status command. The draft prints three rows and exits zero. Your shoulders drop. The branch name even says wip-ok. Did the happy path become a test? It did not.
I want one small thing you can try today. Fill a receipt card before the diff leaves scratch. If the card fails, you delete the branch. That is the clean exit. No heroics, and no silent promote.
What the free lane is allowed to do
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
MonkeyCode's free model access can draft the CLI text. Its free server option can host the scratch run. I am not stating a token quota, a chip type, or an uptime number. I have not verified those for this draft. Treat both free options as a cheap lane, not a promise.
Would you put real keys on that lane? I would not. The free server is a scratch box. The free model is a drafter. You still own the receipt, the rollback, and the abandon line.
Time box for this pass: forty-five minutes. Cost box: the free lane only, or you stop. If either box breaks, the branch dies. That boundary is part of the card, not a footnote.
The seven files that count as evidence
Keep these files next to the CLI. Empty files do not count. Secrets do not count. A screenshot of a green terminal does not count.
| File | Evidence it must hold | Fail closed when |
|---|---|---|
GOAL.txt |
One job, one user, one output | The goal names two products |
BUDGET.txt |
Forty-five minutes, free lane only | A paid hop appears |
FIXTURE.txt |
Sanitized sample input | A key or password shape appears |
REPRO.md |
Commands that redo the failure | The steps need your laptop memory |
DIFF_SCOPE.txt |
Files the draft may touch | A path outside the CLI appears |
ROLLBACK.txt |
Exact undo commands | Undo is "I will figure it out" |
ABANDON.txt |
The line that kills the branch | You cannot say when to quit |
This table checks presence and shape. It does not prove the CLI is correct. You still read the diff. A gate that pretends to judge quality will lie to you.
Numbered steps
1. Write the abandon line first
Open ABANDON.txt before you prompt. Mine says the branch dies after two failed gate runs. It also dies if the free server cannot take the scratch job. Why first? Because hope gets louder after a pretty table.
2. Bound the draft
Put the goal in one sentence. Name the command, the input file, and the output. If you cannot fit it, the CLI is already too big. Split it, or walk away.
3. Draft on the free model lane
Ask for one file, not a framework. Paste your goal and your fixture. Refuse extra services, daemons, and hidden network calls. Did the draft add a dependency you did not name? That is a scope miss. Record it in DIFF_SCOPE.txt, or revert.
4. Run once on the free server
Copy the CLI to the free server scratch box. Run the command from REPRO.md. Save stdout and the exit code into that same file. Do not point the box at production hosts. Do not mount a real home directory.
5. Run the receipt gate locally
The script below is a template. I am not pasting a timed production log from a live server. Run it on your receipt folder. A missing file must exit non-zero.
6. Read, promote, or delete
If the gate passes, read every changed line anyway. Promote only the paths in DIFF_SCOPE.txt. If the gate fails twice, run the rollback and delete the branch. Would a third prompt save you? Maybe. The card still says stop.
The gate script
Save this as receipt-gate.sh beside the seven files. It is intentionally boring. Boring is the point.
#!/usr/bin/env bash
# Template: fail closed unless the receipt files exist and look safe.
set -euo pipefail
root="${1:-.}"
need=(
GOAL.txt
BUDGET.txt
FIXTURE.txt
REPRO.md
DIFF_SCOPE.txt
ROLLBACK.txt
ABANDON.txt
)
for f in "${need[@]}"; do
path="$root/$f"
if [[ ! -s "$path" ]]; then
echo "FAIL closed: missing or empty $f" >&2
exit 1
fi
done
if grep -Eiq 'sk-|api_key|password|BEGIN PRIVATE' "$root/FIXTURE.txt"; then
echo "FAIL closed: fixture looks like a secret" >&2
exit 2
fi
if grep -Eq '^[^#[:space:]]' "$root/DIFF_SCOPE.txt" && \
grep -Ev '^[[:space:]]*(#|$)' "$root/DIFF_SCOPE.txt" | \
grep -vqE '^[A-Za-z0-9_./-]+$'; then
echo "FAIL closed: scope has an odd path" >&2
exit 3
fi
echo "PASS: receipt present. Still review the diff yourself."
Make it executable, then point it at the folder.
chmod +x receipt-gate.sh
./receipt-gate.sh .
A pass line is not a merge approval. It only says the receipt exists. You can still hate the code. You should, at least once.
A failure fixture you can copy
Create a bad fixture on purpose. Confirm the gate screams. Then fix the file. This is the drill, not the product.
mkdir -p /tmp/receipt-drill && cd /tmp/receipt-drill
printf 'Show disk free space for one path.\n' > GOAL.txt
printf '45 minutes. Free lane only. Stop if paid.\n' > BUDGET.txt
printf 'path=/tmp\n' > FIXTURE.txt
printf '## Repro\n\npython3 dfcli.py --path /tmp\n\nExpect exit 0.\n' > REPRO.md
printf 'dfcli.py\n' > DIFF_SCOPE.txt
printf 'git switch -\ngit branch -D scratch-df\n' > ROLLBACK.txt
printf 'Abandon after two failed gate runs.\n' > ABANDON.txt
Now poison the fixture and watch the exit code.
printf 'path=/tmp\napi_key=demo-not-real\n' > FIXTURE.txt
./receipt-gate.sh /tmp/receipt-drill; echo "exit:$?"
You want FAIL closed and a non-zero exit. Restore path=/tmp only. Run the gate again. If you skip this drill, you own a script you have never seen fail. That is not a gate. That is a poster.
Fail-closed rules I will not bend
- No receipt file, no promote. A chat log is not a file.
- No secret-shaped fixture, no run. Sanitize before the free server sees it.
- No path outside
DIFF_SCOPE.txt, no commit. Extra files are a new draft. - No second budget, no retry. The free lane is the whole wallet here.
- No human read, no merge. The script cannot see a bad flag name.
Who should skip this approach? Skip it if the CLI touches payments, customer data, or production credentials. Skip it if your team needs a formal change board. Skip it if you wanted the script to score code quality. This card is for a solo scratch CLI, not a release train.
Limits, stated plainly
The grep for secrets is a tripwire, not a scanner. A clever leak can still pass. The free model can invent flags your fixture never hits. The free server can refuse the job, or go away, and this draft does not claim a duration. I did not benchmark latency, cost, or model quality here. If you need those numbers, measure them yourself and date the note.
Rollback stays dumb on purpose.
git switch -
git branch -D scratch-df
If the branch never existed on a remote, you are done. If you already pushed, delete the remote branch too. Then stop. Do not "just try one more prompt" after ABANDON.txt fires.
What I would add next
The card still misses a field for flaky output. A table that changes column order would pass this gate. Which missing field would make you abandon a draft faster: a golden output file, a timeout, or a banned-dependency list?
If MonkeyCode's free model lane and free server already sit in your scratch flow, drop this card on the next CLI. Tell me the gate you had to add. I will keep the next version smaller, not louder.
Top comments (0)