The Rejection File: A Take-Home That Grades the Patch the Candidate Refused to Ship A take-home exercise called The Rejection File asks engineering candidates to submit a working patch plus an auditable record of at least one AI model proposal they rejected, with a repro command that proves the refusal was correct. The exercise, which fits in two to three hours on free-tier infrastructure, responds to a DEV thread arguing engineers should not become a proxy between a requester and an AI, and its rubric weights rejection evidence at 30 points, patch correctness at 20, reproduction quality at 15, scope discipline at 15, budget discipline at 10 and the handoff note at 10. The format holds that a candidate with a mediocre patch and three credible rejections generally scores higher than one with a clean patch and a rejection file that cannot be replayed. The Rejection File: A Take-Home That Grades the Patch the Candidate Refused to Ship A take-home that grades only the final diff measures output volume; the stronger hiring signal sits in the proposals a candidate refused to ship. The Rejection File is a small exercise that asks for a working patch plus an auditable record of at least one model proposal the candidate rejected, toget her with a command that proves the refusal was correct. It fits in two to three hours, runs on free-tier infrastructure, and separates engineers who verify from engineers who relay. The format responds to a DEV thread this week arguing that engineers should not become a proxy between a requester and an AI. That complaint is really about unverified relay: a proposal arrives, a patch leaves, and nobody checks the middle step. A rejection file makes the middle step the deliverable, so reviewers can inspect judgment instead of guessing at it. Most take-homes reward candidates for producing code that passes hidden tests, which is a narrow measurement of one skill. A model can generate a passing patch from a decent prompt, so the passing patch no longer distinguishes much. What still distinguishes candidates is whether they noticed that two of the four proposals were quietly wrong. Rejecting a proposal is cheap to claim and expensive to prove, which is exactly why it makes a good artifact. Anyone can write "I rejected the broad exception handler because it hides errors" in a README. Requiring a repro command that fails for the rejected proposal turns the claim into evidence a reviewer can replay in one terminal command. The following text can be handed over verbatim; it assumes an isolated fixture repository with a small, real defect. Fix the defect in src/. Any approach is acceptable as long as the existing test suite stays green. Use an AI assistant for at least two candidate proposals. Record each proposal in rejections.json using the schema below. Reject at least one proposal and supply a repro command that fails when your rejection is correct. Keep the accepted diff under roughly forty changed lines unless the repository forces more; explain any overrun in the handoff note. Write a half-page handoff note covering what you verified, what you assumed, and what you would check next. The constraints matter more than the defect. Candidates who burn the whole repository into context tend to produce a plausible patch plus a rejection file full of unverifiable prose, which the rubric scores accordingly. Criterion Weight What earns full credit Rejection evidence 30 Every rejection has a repro command that actually fails Patch correctness 20 Full suite green, including tests the candidate did not write Reproduction quality 15 One command, no manual setup steps, deterministic output Scope discipline 15 Diff stays near the defect; unrelated refactors are absent Budget discipline 10 Token spend is recorded and re-prompting loops are explained Handoff note 10 Separates verified facts from assumptions without hedging The weighting is deliberate. A candidate with a mediocre patch and three credible rejections generally scores higher than one with a clean patch and a rejection file that cannot be replayed, because the second candidate produced no inspectable judgment. The schema is intentionally boring so that a script can check it. { "acceptance": { "repro": "pytest -q tests/test resume.py::test truncated stream" }, "rejections": { "id": "reject-stream-close", "proposal": "Close the stream inside the except branch and return None", "repro": "pytest -q tests/test resume.py::test truncated stream", "expect failure": true, "decision": "rejected: callers cannot distinguish truncation from empty input" }, { "id": "reject-broad-except", "proposal": "Wrap the consumer loop in except Exception and retry once", "repro": "pytest -q tests/test cancel.py::test cancel mid stream", "expect failure": true, "decision": "rejected: converts a loud failure into an invisible stall" } } The audit script below is a reference sketch rather than a benchmarked tool, and it should be run against your own fixture before it grades anyone. It replays each repro inside the candidate's working copy and checks that the exit code matches the claim, then confirms that the accepted patch passes its own repro. rejection audit.py — replay every rejection and confirm the claim holds import json, pathlib, subprocess, sys WORK = pathlib.Path "work" def run cmd: str, timeout: int = 120 - int: proc = subprocess.run cmd, shell=True, cwd=WORK, timeout=timeout, capture output=True, text=True return proc.returncode def audit path: str - int: data = json.loads pathlib.Path path .read text bad = 0 for entry in data "rejections" : code = run entry "repro" credible = code = 0 == entry "expect failure" print f'{entry "id" :<26} exit={code:<3} credible={credible}' bad += 0 if credible else 1 accepted = run data "acceptance" "repro" print f'{"accepted patch".ljust 26 } exit={accepted:<3} credible={accepted == 0}' return bad + accepted = 0 if name == " main ": sys.exit 1 if audit sys.argv 1 else 0 A non-zero exit from the auditor is not a rejection of the candidate; it is a signal for the reviewer to open the named entry and read the reasoning. The script checks whether evidence exists, not whether the reasoning is sound. The environment cost is the part that usually kills custom take-homes, because per-candidate model spend and hosted runners add up across a hiring loop. MonkeyCode's free model access and free server option make a dry run practical: the reviewer keeps the fixture repository and the audit script, and candidates get a working environment without a procurement conversation. Disclosure: This article was prepared as part of MonkeyCode's product outreach. Availability details come from the operator rather than from independent testing: free model access, a free server option, and a free token allotment quoted at ten million tokens at the time of writing. Those terms can change, so confirm the current limits before you put them in a candidate brief. The claim that matters for this exercise is narrower and easy to check yourself: a candidate can complete a two-hour patch-and-reject loop without a paid account. git clone