A pairing session should keep one fixture contract before any free route is allowed to draft the next revision. The contract records the senior's questions, the dead ends that were rejected, and the single decision that remains binding. A free model route and a free server option can supply the next draft, yet they cannot replace that local record. Teams that skip the contract usually repeat the same failed patch after the route, the quota, or the server changes.
Why the fixture comes before the route
Generated edits fail quietly when the pair remembers a conversation instead of storing a command that another person can run. The senior in this workflow asks whether the failure can be reproduced on a laptop without network access. That question forces the pair to separate the product route from the evidence that will judge the patch. A route may be convenient, but a fixture that needs the route is not yet a review artifact.
Questions the senior asks before eligibility
The pairing uses a short question list so the kept decision is about evidence rather than preference. Each answer must point to a file, a command, or an explicit rejection that a later reviewer can check. The session described here is a proposed workflow, not a claim that this account already ran it with a named senior. That label matters because invented pairing history would make the card look stronger than the evidence it holds.
- The senior asks which behavior failed, and the pair must name one input file and one expected result.
- The senior asks which command reproduces that behavior locally, and the pair rejects any answer that depends on a remote server.
- The senior asks which earlier idea was tried, and every dead end must name the reason it was closed.
- The senior asks whether a free route is eligible, and that status is allowed only after the local command has passed once.
- The senior asks what will be rolled back if the next draft widens the diff, and that command is stored beside the patch.
Dead ends the pair should refuse to reopen
The first dead end is model shopping during the pairing hour, because impression does not identify the failing assertion. The pair closes that path, writes the reason on the card, and returns attention to the fixture command. The second dead end places the free server on the critical path, where a vanished option would erase the only copy of the failure. A free server can host a later dry run, but it must not become the only place where the failure exists.
The third dead end lets the generator choose a new test command after the senior already has a failing one. A replacement command can hide the original bug, so the pair keeps the command that failed for a known reason. The fourth dead end copies a remembered token grant into the card from an old chat or an old article. A remembered number stays stale until a person reads the live account page and records the observation time.
The decision this workflow keeps
The kept decision is narrow, and it survives changes to the route only because it names a laptop command. One fixture command must pass on the laptop before a free route may draft a revision of the same patch. The free server, when the operator still offers it, may receive a branch copy only after that local pass. If the live quota, the server option, or the model list disagrees with the card, the pair stops and records a new observation.
Build the decision card
The card is a small JSON file that a checker can validate without calling any model or any server. It is intentionally plain, because the pairing value sits in required fields and in fields the pair is forbidden to invent. Store the file next to the patch notes, and treat a missing card as a failed review rather than a prompt to improvise. The sample below is unexecuted example material, so a team should replace the fixture names before trusting a pass.
{
"schema": "pairing-fixture-card/v1",
"question": "Which local command proves the parser rejects an empty batch?",
"expected_input": "fixtures/empty-batch.json",
"expected_result": "exit 2 and an error that names the empty batch",
"local_command": "python3 check_batch.py fixtures/empty-batch.json",
"rollback_command": "git checkout -- check_batch.py",
"dead_ends": [
{
"id": "route-shopping",
"closed_because": "No failing assertion was attached to a route preference."
},
{
"id": "server-as-oracle",
"closed_because": "The free server cannot be the only place the failure exists."
},
{
"id": "generator-picks-command",
"closed_because": "A new command can hide the original empty-batch bug."
},
{
"id": "remembered-quota",
"closed_because": "A remembered token count is not evidence until it is reread."
}
],
"kept_decision": "Free-route drafting stays ineligible until local_command passes once.",
"free_route_eligible": false,
"free_server_after_local_pass": true,
"quota_note": "do not invent a token number in this file",
"observation": {
"source": "operator must paste the live account reading",
"read_at": "unset"
}
}
Add the stand-in fixture
The fixture script below exists so the card's command can be executed in a clean directory without a private repository. It rejects an empty batch with status two, and it accepts a non-empty batch with status zero. Those statuses are part of the example contract, not a recommendation for every parser a team already owns. A production pair should point local_command at the real test, then delete this stand-in before the card is shared.
#!/usr/bin/env python3
# Stand-in fixture for the pairing card. Not a production parser.
import json
import sys
from pathlib import Path
def main() -> int:
if len(sys.argv) != 2:
print("usage: python3 check_batch.py FIXTURE")
return 2
payload = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))
batch = payload.get("batch")
if not isinstance(batch, list) or len(batch) == 0:
print("error: empty batch")
return 2
print("accepted", len(batch))
return 0
if __name__ == "__main__":
raise SystemExit(main())
Check the card before anyone drafts
The checker is a proposed local tool, and it fails closed when the kept decision or a dead-end reason is missing. It also rejects a free-route flag when the local pass file is absent, which keeps eligibility behind evidence. The tool does not contact a product API, and it does not treat any token number in the file as verified fact. Replace the field checks with the team's review hook before this file becomes a required repository gate.
#!/usr/bin/env python3
# Proposed local checker for a pairing fixture card.
# It does not call a model, a server, or an account API.
import json
import sys
from pathlib import Path
REQUIRED = (
"question",
"expected_input",
"expected_result",
"local_command",
"rollback_command",
"kept_decision",
"dead_ends",
)
def main() -> int:
card_path = Path(sys.argv[1] if len(sys.argv) > 1 else "pairing-card.json")
pass_file = Path(".pairing/local-pass")
card = json.loads(card_path.read_text(encoding="utf-8"))
missing = [key for key in REQUIRED if not card.get(key)]
if missing:
print("missing fields:", ", ".join(missing))
return 2
dead_ends = card["dead_ends"]
if not isinstance(dead_ends, list) or len(dead_ends) < 3:
print("record at least three closed dead ends")
return 2
for item in dead_ends:
reason = str(item.get("closed_because", "")).strip()
if len(reason) < 20:
print("dead end lacks a reason:", item.get("id", "unknown"))
return 2
note = str(card.get("quota_note", "")).lower()
if "do not invent" not in note:
print("quota_note must warn reviewers not to invent a token number")
return 2
observation = card.get("observation") or {}
read_at = observation.get("read_at")
eligible = card.get("free_route_eligible") is True
if eligible and read_at in (None, "", "unset"):
print("eligibility requires a fresh observation time")
return 3
if eligible and not pass_file.exists():
print("free route is not eligible until .pairing/local-pass exists")
return 3
print("card accepted for local review")
return 0
if __name__ == "__main__":
raise SystemExit(main())
Run the local pass in order
- The pair writes the card with free_route_eligible set to false, and leaves the observation time unset until a person reads the live account page.
- The pair runs the checker on a copy with eligibility set to true, and confirms a non-zero exit while the observation time is unset.
- The pair runs the fixture command from the card, and creates the pass file only when that command exits with the expected status.
- A person rereads the operator account page, records the observation time, and refuses any token total copied from memory.
- The pair sets eligibility to true only after the pass file and a fresh observation both exist on disk.
- The pair then requests one draft that must keep the same fixture command and the same expected result.
- If the draft changes the fixture command, the pair rejects the draft and restores the file with the rollback command.
mkdir -p .pairing fixtures
printf '%s\n' '{"batch":[]}' > fixtures/empty-batch.json
python3 check_pairing_card.py pairing-card.json
python3 - <<'PY'
import json
from pathlib import Path
card = json.loads(Path("pairing-card.json").read_text(encoding="utf-8"))
card["free_route_eligible"] = True
Path("/tmp/eligible-too-soon.json").write_text(
json.dumps(card), encoding="utf-8"
)
PY
python3 check_pairing_card.py /tmp/eligible-too-soon.json
echo "negative-check-exit:$?"
python3 check_batch.py fixtures/empty-batch.json
status=$?
if [ "$status" -eq 2 ]; then
touch .pairing/local-pass
fi
# A person then reads the live account page and sets observation.read_at.
# Do not paste a remembered token total into pairing-card.json.
The commands above are a proposed sequence, and the check_batch script is a stand-in for the team's real fixture. The status test creates a pass file only for the expected failure code, which in this example is exit status two. A success status of zero would mean the empty batch was accepted, so that result must not create a pass file for this defect. After the human observation is written, the checker may accept eligibility, and only then should a route see the same fixture.
What this does not prove
The checker proves that the card is complete and that a local pass file exists, and it proves nothing about product availability. It does not prove that a free server is still offered, that a quota remains, or that a generated patch is correct. A pass file can be created by hand, so the pairing still needs a reviewer who watched the fixture command run. No timing or quality benchmark is claimed here, because this account has not published measurements for this card.
Who should skip this workflow
Teams without a local fixture should not adopt the card, because the kept decision depends on a command that fails for a known reason. Projects that require live customer data in every test should not send that data to a free server just to finish a dry run. Pairs who cannot name a rollback command are not ready to let any route draft the next revision of the patch. This workflow is also a poor fit when the senior's question is exploratory design rather than a defect that can be reproduced.
After the card is accepted
Once the checker accepts the card, the pair may ask a free model route for one revision that must satisfy the same expected result. If a free server is still listed for the operator, it can host a second run of that same command after the laptop pass. A disagreement between the laptop and that server becomes a new dead end, not a silent override of the kept decision. Readers who already use MonkeyCode can attach this card to one free-route draft only after the local pass file exists.
They should drop that draft when the live account page no longer matches the observation recorded on the card. The pairing ends when the original fixture still fails for the same reason, or when it passes locally and the rollback command stays unused. Either ending is acceptable, because both endings leave a record that the next pair can run without reconstructing the chat. The next session starts from that card, not from a remembered token total or from a server that may no longer be free.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
Top comments (0)