The pairing parked every free-tier model call until each open question named a local proof command and a file owner. Exploratory chat without that ledger row wasted the shared tier and left no replayable evidence for later review. The senior kept the ledger, the proof command, and a disposable free server for agent shells after faster habits failed. This walkthrough records the questions, the failed shortcuts, the artifact, and the numbered protocol the desk used next.
The rule the pairing kept
A remote model turn was treated as a scarce review step, not as a substitute for reading the tree. Each question needed a ledger row with an owner, a target path, a proof command, and a keep-or-drop rule before anyone pasted a prompt. Agent command execution stayed off the reviewer laptop and ran on a disposable free server so local editor state could not leak into the result. The pairing accepted a patch only when a clean replay of the proof command matched the ledger's expected signal.
This protocol is a proposed pairing-desk workflow, not a production incident runbook and not a measured benchmark of any model. Teams should adapt the files below to their own repository layout, test runner, and CI image. The examples are labeled unexecuted because no private environment log is attached to this article. Readers should treat every command as something to run inside a throwaway clone.
Why shared free-tier pairing collapses without a ledger
Free-tier model access is useful during pairing, but the context window fills with questions that nobody later remembers owning. Two people talking through a failing checkout will restate the same hypothesis across three prompts and then lose the one command that actually failed. A shared free server helps isolate agent shells from the reviewer laptop, yet isolation does not invent a decision record if the chat scrollback is the only artifact. The ledger exists so the next pairing hour can start from proof commands rather than from reconstructed folklore.
The product surface matters only when the agent needs a named file list and a place to run shells that is not the reviewer workstation. MonkeyCode participates here as free model access plus a free server option for those isolated command runs. Disclosure: This article was prepared as part of MonkeyCode's product outreach. The keep rule still stands if that product name is removed, because the pairing accepts patches from proof commands rather than from vendor chrome.
Artifact: the question ledger
The pairing kept a JSONL file at pairing/question-ledger.jsonl on the branch, never inside a private chat export. Each line is one question the senior was willing to spend a free-tier turn on after a local proof existed. Rows without a proof command were illegal, and the validator below rejects them before any remote call is allowed. The sample row is a template for a checkout discount stack, not a claim about a live production incident.
{
"id": "Q-014",
"asked_by": "reviewer",
"owned_by": "author",
"question": "Does checkout skip the coupon when the cart already has a staff discount?",
"target_paths": ["app/checkout/price.py", "tests/test_price_stack.py"],
"proof_command": "python -m pytest tests/test_price_stack.py::test_staff_discount_blocks_coupon -q",
"expected_signal": "FAILED",
"remote_call_allowed": false,
"keep_rule": "keep the agent patch only if the proof command flips FAILED to PASSED on a clean tree"
}
A short validator makes the completeness rule mechanical so the pairing does not argue about missing fields in the moment. The same-owner check is intentional, because the agent must not become the missing second name on the row. Run the script from a throwaway clone and treat a nonzero exit as a hard stop.
# pairing/validate_ledger.py
# Proposed local gate. Label: unexecuted against a private repository.
from __future__ import annotations
import json
import sys
from pathlib import Path
REQUIRED = (
"id",
"asked_by",
"owned_by",
"question",
"target_paths",
"proof_command",
"expected_signal",
"remote_call_allowed",
"keep_rule",
)
def load_rows(path: Path) -> list[dict]:
rows = []
for line_no, raw in enumerate(path.read_text(encoding="utf-8").splitlines(), 1):
if not raw.strip() or raw.lstrip().startswith("#"):
continue
try:
row = json.loads(raw)
except json.JSONDecodeError as exc:
raise SystemExit(f"ledger line {line_no} is not JSON: {exc}") from exc
missing = [key for key in REQUIRED if key not in row]
if missing:
raise SystemExit(f"{row.get('id', line_no)} missing {missing}")
if not row["target_paths"] or not str(row["proof_command"]).strip():
raise SystemExit(f"{row['id']} needs target_paths and proof_command")
if row["asked_by"] == row["owned_by"] and row.get("allow_same_owner") is not True:
raise SystemExit(f"{row['id']} needs a second owner before a remote call")
rows.append(row)
return rows
def main() -> None:
ledger = Path(sys.argv[1] if len(sys.argv) > 1 else "pairing/question-ledger.jsonl")
rows = load_rows(ledger)
blocked = [row["id"] for row in rows if not row["remote_call_allowed"]]
print(f"ok {len(rows)} rows; remote still blocked for {blocked or 'none'}")
if __name__ == "__main__":
main()
Walkthrough: questions, failed shortcuts, and the keep rule
The reconstructed session started with a failing checkout test and a temptation to paste the pricing module into a free-tier prompt. The senior asked who owned the question, which file could answer it, and which command would falsify the current story. Those three asks produced the first ledger row before any assistant panel received repository text. The agent stayed parked while the desk walked the shortcuts that usually feel faster than writing a proof command.
Failed shortcut: dump the module and hope the model notices the stack
The author offered to dump price.py into the prompt so the free-tier model could inspect the discount stack without reading tests. The senior refused that dump because a paste has no expected signal and cannot be replayed by the next reviewer on a clean tree. The pairing ran the proof command as a read-only local observation and recorded FAILED plus the assertion name inside the ledger row. A remote call became legal only after that row existed, and the prompt could include those two named paths only.
Failed shortcut: let the agent run on the reviewer laptop
The author then proposed starting the agent inside the reviewer working tree because a free server clone would add several extra minutes. The senior blocked that shortcut because agent shells mix unsaved editor buffers with local environment variables that never appear in review. A disposable free server clone has no open editor and no developer secrets sitting in the interactive shell history. The pairing copied the branch there, reran the proof command, and treated every unlisted command as outside the pairing contract.
Failed shortcut: keep the first fluent answer as the decision
The free-tier model returned a fluent patch that added a second flag on the coupon object and left the failing test untouched in spirit. The senior did not keep that patch, because the keep rule required the original proof command to flip on a clean tree. A second remote call was allowed only after the ledger gained a new row that named the flag hypothesis and a new test path. The decision the pairing kept was the later patch that reordered the discount stack and left the coupon object unchanged.
Numbered protocol the desk ran next
The pairing encoded the afternoon as eight gates so the next session would not reinvent the same argument. Each step is a stop, and skipping a gate returns the desk to the previous file rather than to a longer prompt. Commands below assume a throwaway clone, a Unix shell, and a test file that already fails for a known reason.
- Create a branch and an empty ledger file before anyone opens a chat panel for the bug.
- Write one JSONL row per question, including owner, paths, proof command, expected signal, and keep rule.
- Run
python pairing/validate_ledger.pyand refuse to continue if the process exits nonzero. - Execute the proof command on the reviewer laptop only as a read-only observation, never as an agent loop.
- Flip
remote_call_allowedto true only after the expected signal is captured beside the ledger row. - Send the model the ledger row, the named files, and the command output, not the rest of the repository.
- Apply candidate diffs on a free server clone, then replay the same proof command against the keep rule.
- Merge only the diff that satisfies the keep rule; append dropped attempts as ledger notes, not as chat folklore.
# Proposed pairing gate. Label: run in a throwaway clone.
set -euo pipefail
git checkout -b pairing/q-014-price-stack
mkdir -p pairing
test -f pairing/question-ledger.jsonl
python pairing/validate_ledger.py pairing/question-ledger.jsonl
# Read-only local observation. Do not start an agent on this laptop.
python -m pytest tests/test_price_stack.py::test_staff_discount_blocks_coupon -q \
| tee pairing/Q-014.local.log
# After remote_call_allowed is true, clone on a disposable free server:
# git clone "$REPO" /tmp/q-014
# git -C /tmp/q-014 checkout pairing/q-014-price-stack
# apply the candidate diff, then rerun the same proof command and tee the log.
A tiny keep-or-drop helper makes the eighth gate less theatrical during review. The signal parser is deliberately coarse and should be replaced with the team's actual test reporter. Treat UNCLEAR as a drop, because an ambiguous log is not a keep rule.
# pairing/keep_drop.py
# Proposed helper. Label: unexecuted; wire to the team's log files.
from pathlib import Path
import sys
def last_signal(log_path: Path) -> str:
text = log_path.read_text(encoding="utf-8")
lowered = text.lower()
failed = "failed" in lowered
passed = "passed" in lowered
if failed and not passed:
return "FAILED"
if passed and not failed:
return "PASSED"
return "UNCLEAR"
def main() -> None:
before = last_signal(Path(sys.argv[1]))
after = last_signal(Path(sys.argv[2]))
if before == "FAILED" and after == "PASSED":
print("KEEP")
return
print("DROP")
raise SystemExit(2)
if __name__ == "__main__":
main()
# Label: unexecuted. Compare the local failing log with the free-server replay log.
python pairing/keep_drop.py pairing/Q-014.local.log pairing/Q-014.server.log
Decision table the senior used during review
The table below is the keep artifact for the session. It is not a scorecard, and it does not rank models, vendors, or prompt styles. Rows move left to right only when the previous column is already written down. The table is deliberately boring, because boring gates are the entire point of pairing against a scarce shared free tier.
| Question state | Local proof | Remote call | Agent shell | Outcome the pairing kept |
|---|---|---|---|---|
| Spoken only | Missing | Blocked | Blocked | No row, no prompt |
| Row without a second owner | Command listed | Blocked | Blocked | Validator fails |
| Row with a FAILED log | Captured | Allowed on named files | Free server only | Prompt may run |
| Fluent patch, proof still FAILED | Captured | New row required | Free server only | DROP |
| Patch flips FAILED to PASSED | Captured | No extra files | Free server replay | KEEP |
Limitations and who should not use this
The protocol assumes the failure is already expressible as a command, which many design debates and product questions are not. It also assumes a second person can own the question, so solo late-night work will not satisfy the same-owner check without an explicit override flag. A free server clone will not help if the bug exists only against production data that cannot be copied into that isolate. Teams that need guaranteed capacity, air-gapped networks, or secret-bearing laptops as the execution surface should not park agent shells on a shared free server.
The validator does not measure model quality and does not prove that free-tier access will remain available in any given week. Operators should verify current product terms from primary sources before planning a sprint around availability claims. This article does not claim token quotas, hardware sizes, durations, permanence, or speedups, because those figures were not supplied as verified facts. If the keep rule cannot be written in one sentence, the pairing should not spend a free-tier turn yet.
Top comments (0)