F04 — Fix with evidence
Choose the commands you use
Operating system
CodeArbiter host
Know before you begin
Complete F02 first, then start from a clean main branch in the same Academy clone. Keep two surfaces open at the clone root: a native terminal for Academy and shell commands, and your Claude Code, Codex, or Pi harness for messages to your agent and CodeArbiter commands.
This page names the surface for every action. Put a native-terminal command directly in PowerShell or your shell; it never starts with !. Put a learner prompt or CodeArbiter command in the selected harness; neither starts with !. The ! prefix is only for a shell command deliberately sent through a harness, and this lesson does not use that route. Do not use git commit yourself: the agent runs the governed commit gate after you inspect and approve each boundary.
What you will prove
You will turn a real claimant-label defect into durable evidence. A regression is a test that demonstrates a defect before it is repaired. Red means that new test fails for the intended reason; green means the same test passes after the repair. A control character is a non-printing character such as newline, tab, or DEL. This lesson rejects control characters in a claimant label while preserving an ordinary label such as Sam Allen.
The proof has two commits after Prepare: first a test-only red regression in tests/test_service.py, then a service-only repair in workshop_queue/service.py. A commit boundary is the exact path set in one commit. The production boundary is the real claim_ticket function that receives the label, not a helper, transcript, CLI, or JSON copy.
Prepare safely
01Establish the baseline
Prepare a numbered fix attempt
From a clean main branch at your Academy clone root, run Prepare in a native terminal. The printed attempt number is evidence metadata, not text to type.
Prepare gives the intentionally defective service a separate, reviewable history.
You · Native terminal · Windows
$academy = "$env:LOCALAPPDATA\ArbiterAcademy\preview-0.30\Scripts\arbiter-academy.exe"
& $academy --repository (Get-Location).Path prepare F04-fix-with-evidence
You · Native terminal · macOS
academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.30/bin/arbiter-academy"
"$academy" --repository "$PWD" prepare F04-fix-with-evidence
You · Native terminal · Linux
academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.30/bin/arbiter-academy"
"$academy" --repository "$PWD" prepare F04-fix-with-evidence
Academy switches this clone to academy/F04-fix-with-evidence/ATTEMPT_NUMBER.
If Prepare stops, preserve its message and resolve only the named clean-worktree, branch, or prerequisite condition. Do not force-reset main or delete an earlier attempt.
The numbered branch preserves the defective starting point.
The printed attempt number is evidence metadata. Academy uses it in the branch name; do not type the literal word ATTEMPT_NUMBER. The attempt starts from a deterministic defective service and keeps main untouched.
Read the defect and its boundary
Read the prepared service and test file before requesting a change. Identify claim_ticket as the live boundary and confirm that the regression name is not already present.
The lesson repairs one claimant-label rule, not the CLI, JSON storage, or a fictional copy of the service.
You · Native terminal · Windows
Get-Content -LiteralPath 'workshop_queue/service.py'; Get-Content -LiteralPath 'tests/test_service.py'
You · Native terminal · macOS
sed -n '1,240p' workshop_queue/service.py; sed -n '1,180p' tests/test_service.py
You · Native terminal · Linux
sed -n '1,240p' workshop_queue/service.py; sed -n '1,180p' tests/test_service.py
claim_ticket accepts a volunteer label without rejecting newline, tab, or DEL characters, and tests/test_service.py has no claimant-label control-character regression.
If either file differs from that prepared state, stop. Preserve the branch and use Reset for a new F04 attempt rather than adapting another lesson's state.
You identified the real production boundary and the missing executable regression.
Confirm the prepared baseline is clean
Run the service suite in a native terminal before adding the regression. The existing suite must be green and Git must print no paths.
A green prepared baseline lets the later red result identify the new regression instead of a pre-existing failure.
You · Native terminal · Windows
git status --short; python -m unittest tests.test_service -v
You · Native terminal · macOS
git status --short && python3 -m unittest tests.test_service -v
You · Native terminal · Linux
git status --short && python3 -m unittest tests.test_service -v
Git prints nothing and the existing service tests pass.
If Git prints a path or a baseline test fails, preserve the output. Do not add a regression until the prepared attempt is understood; use Reset if the attempt is not clean.
The red test will be attributable to the regression you request next.
Practice
The proof map
| Moment | Durable evidence |
|---|---|
| Prepare | A clean, deliberately defective baseline on a numbered attempt branch. |
| Prove red | One test-only commit that reaches claim_ticket and fails for the intended control characters. |
| Repair green | One service-only commit that makes the unchanged regression pass. |
| Check | An external reconstruction of the two snapshots, path boundaries, and clean worktree. |
Establish the red proof
Open the governed fix lane before requesting any change. The copied command below belongs in your selected harness, not in a terminal.
02Prove the defect is real
Open the governed fix lane
In the selected CodeArbiter harness, paste the copied fix command into the harness prompt and send it. It is not a shell command and never begins with !. The agent opens the governed fix lane before changing production code.
The fix lane records the defect boundary and keeps the upcoming work under the repository's rules.
Your agent · Claude Code harness · All operating systems
/ca:fix "Reject control characters in a claimant label"
Your agent · Codex harness · All operating systems
$ca-fix "Reject control characters in a claimant label"
Your agent · Pi harness · All operating systems
/ca-fix "Reject control characters in a claimant label"
Your agent · Pi harness · All operating systems
/skill:ca-fix "Reject control characters in a claimant label"
The agent identifies the claimant-label defect and waits for a regression-first change.
If the command blocks, preserve its finding. Do not bypass the lane or edit workshop_queue/service.py from a terminal.
The governed path names the production boundary before it changes.
Ask your agent for one direct executable regression and nothing in production. The request already states the three rejected labels, the expected ValueError, and the ordinary-name control. Send it unchanged first; it is specific enough to review.
Request the test-only regression
Paste this request into the selected harness and send it. It is an instruction to your agent, not a terminal command, so it never begins with !.
The first commit must prove the defect exists before any repair can make it pass.
You · Claude Code harness · All operating systems
Add exactly one direct unittest named test_claim_rejects_control_characters_in_volunteer_label in tests/test_service.py. Loop over Sam\nAdmin, Sam\tAdmin, and Sam\x7fAdmin; for each, use assertRaisesRegex(ValueError, a message containing control characters) around the real claim_ticket call. Then assign the real claim_ticket result for Sam Allen to a variable and assert its claimed_by is Sam Allen. Do not edit workshop_queue/service.py. Run only that test and stop after its semantic assertion failure.
You · Codex harness · All operating systems
Add exactly one direct unittest named test_claim_rejects_control_characters_in_volunteer_label in tests/test_service.py. Loop over Sam\nAdmin, Sam\tAdmin, and Sam\x7fAdmin; for each, use assertRaisesRegex(ValueError, a message containing control characters) around the real claim_ticket call. Then assign the real claim_ticket result for Sam Allen to a variable and assert its claimed_by is Sam Allen. Do not edit workshop_queue/service.py. Run only that test and stop after its semantic assertion failure.
You · Pi harness · All operating systems
Add exactly one direct unittest named test_claim_rejects_control_characters_in_volunteer_label in tests/test_service.py. Loop over Sam\nAdmin, Sam\tAdmin, and Sam\x7fAdmin; for each, use assertRaisesRegex(ValueError, a message containing control characters) around the real claim_ticket call. Then assign the real claim_ticket result for Sam Allen to a variable and assert its claimed_by is Sam Allen. Do not edit workshop_queue/service.py. Run only that test and stop after its semantic assertion failure.
Only tests/test_service.py changes, and the focused regression fails because claim_ticket does not raise ValueError.
If the result is an import, syntax, or unrelated failure, reject it as evidence and ask the agent to correct only the regression. If production code changes, do not stage it.
The same named test is executable proof of the original defect.
Observe the semantic red failure
Run the focused regression yourself in a native terminal. This command is expected to fail at this point; read the assertion before continuing.
A test that passes before the repair cannot prove the repair fixed the intended defect.
You · Native terminal · Windows
python -m unittest tests.test_service.TicketTransitionTests.test_claim_rejects_control_characters_in_volunteer_label -v
You · Native terminal · macOS
python3 -m unittest tests.test_service.TicketTransitionTests.test_claim_rejects_control_characters_in_volunteer_label -v
You · Native terminal · Linux
python3 -m unittest tests.test_service.TicketTransitionTests.test_claim_rejects_control_characters_in_volunteer_label -v
The test fails because ValueError was not raised for a claimant label containing a control character.
If the test passes, errors before reaching claim_ticket, or names a different failure, stop. Return to the regression request and preserve the current attempt.
You personally observed the red assertion against the prepared production code.
Read the diff before staging. A test that is red because it cannot import, has a typo, or never calls claim_ticket is not evidence of this defect.
Inspect the test-only boundary
Inspect whole-worktree status and both relevant paths before staging. The service path must have no diff yet.
The history proof fails if the regression and repair share one commit.
You · Native terminal · Windows
git status --short; git diff --check; git diff -- tests/test_service.py workshop_queue/service.py
You · Native terminal · macOS
git status --short && git diff --check && git diff -- tests/test_service.py workshop_queue/service.py
You · Native terminal · Linux
git status --short && git diff --check && git diff -- tests/test_service.py workshop_queue/service.py
Only tests/test_service.py is modified, with no whitespace error and no workshop_queue/service.py change.
If another path changed, do not stage. Preserve the attempt and ask the agent to remove the unrelated change before the regression commit.
The first commit boundary is visibly test-only.
Stage only the red regression
Stage exactly tests/test_service.py in a native terminal. This is a shell command you run directly, so it never begins with !. Do not stage production code or any other path.
The review and governed commit need one visible, test-only staged boundary.
You · Native terminal · Windows
git add -- tests/test_service.py; git diff --cached --check; git diff --cached --name-only
You · Native terminal · macOS
git add -- tests/test_service.py && git diff --cached --check && git diff --cached --name-only
You · Native terminal · Linux
git add -- tests/test_service.py && git diff --cached --check && git diff --cached --name-only
The staged path list prints exactly tests/test_service.py and the staged diff has no whitespace error.
If another path is staged, unstage only that path and inspect the whole worktree again. Do not commit until the staged list is exact.
The first proposed commit has one visible staged test path.
Approve the red-test commit boundary
Paste this review request into the selected harness and send it. It is not a shell command and never begins with !.
The learner approves a narrow test-only commit after inspecting the real diff.
You · Claude Code harness · All operating systems
Show git status --short, the staged path list, and the staged diff. Do not commit. Report whether the whole worktree changes only tests/test_service.py, whether the staged path is exactly tests/test_service.py, and whether the named regression reaches real claim_ticket and is red because ValueError is absent.
You · Codex harness · All operating systems
Show git status --short, the staged path list, and the staged diff. Do not commit. Report whether the whole worktree changes only tests/test_service.py, whether the staged path is exactly tests/test_service.py, and whether the named regression reaches real claim_ticket and is red because ValueError is absent.
You · Pi harness · All operating systems
Show git status --short, the staged path list, and the staged diff. Do not commit. Report whether the whole worktree changes only tests/test_service.py, whether the staged path is exactly tests/test_service.py, and whether the named regression reaches real claim_ticket and is red because ValueError is absent.
The agent reports one test path, a real red regression, and no production change for learner approval.
If the report names another path, a passing test, or a production diff, do not approve. Preserve the evidence and correct the boundary first.
The learner approved the exact first commit boundary.
When the report says the whole worktree and staged set contain only tests/test_service.py, let the agent make the first governed commit.
Commit the red regression
After the learner approves the boundary, paste the copied commit command into the selected harness prompt and send it. It is not a shell command. The agent runs the CodeArbiter commit gate; do not use git commit.
The governed commit makes the failing regression durable history before the repair exists.
Your agent · Claude Code harness · All operating systems
/ca:commit
Your agent · Codex harness · All operating systems
$ca-commit
Your agent · Pi harness · All operating systems
/ca-commit
Your agent · Pi harness · All operating systems
/skill:ca-commit
CodeArbiter creates one learner commit after Prepare containing only tests/test_service.py.
If the gate blocks, preserve the finding. Do not direct-commit, amend another attempt, or add workshop_queue/service.py to this commit.
The first immutable learner commit contains the red regression only.
Prove the first commit is still red
Inspect the new head and run the same focused test again in a native terminal. The command is still expected to fail.
This ties the red failure to the committed test-only history, not a transient working-tree edit.
You · Native terminal · Windows
git show --stat --oneline HEAD; python -m unittest tests.test_service.TicketTransitionTests.test_claim_rejects_control_characters_in_volunteer_label -v
You · Native terminal · macOS
git show --stat --oneline HEAD; python3 -m unittest tests.test_service.TicketTransitionTests.test_claim_rejects_control_characters_in_volunteer_label -v
You · Native terminal · Linux
git show --stat --oneline HEAD; python3 -m unittest tests.test_service.TicketTransitionTests.test_claim_rejects_control_characters_in_volunteer_label -v
HEAD lists only tests/test_service.py, and the same regression remains red because the service has not changed.
If HEAD includes service code or the test is not the expected red assertion, preserve the attempt and use Reset. Do not rewrite history to make it appear ordered.
The committed red regression predates the repair.
Repair only the live boundary
Now request the smallest reachable repair. It must reject characters below U+0020 and U+007F at the existing claimant-label boundary, leave the committed regression unchanged, add no dependency, and retain ordinary-name behavior.
03Repair one live boundary
Request the minimal production repair
Paste this request into the selected harness and send it. It is a request to your agent, not a terminal command, so it never begins with !.
The repair must be a reachable claimant-label guard, not a broad rewrite or a disconnected test helper.
You · Claude Code harness · All operating systems
Add only the smallest reachable control-character validation at the existing claim_ticket volunteer-label boundary in workshop_queue/service.py. Reject characters below U+0020 and U+007F, preserve the existing regression unchanged, preserve valid Sam Allen behavior, add no dependency, and run the focused regression plus tests.test_service.
You · Codex harness · All operating systems
Add only the smallest reachable control-character validation at the existing claim_ticket volunteer-label boundary in workshop_queue/service.py. Reject characters below U+0020 and U+007F, preserve the existing regression unchanged, preserve valid Sam Allen behavior, add no dependency, and run the focused regression plus tests.test_service.
You · Pi harness · All operating systems
Add only the smallest reachable control-character validation at the existing claim_ticket volunteer-label boundary in workshop_queue/service.py. Reject characters below U+0020 and U+007F, preserve the existing regression unchanged, preserve valid Sam Allen behavior, add no dependency, and run the focused regression plus tests.test_service.
Only workshop_queue/service.py changes and the existing regression is ready to turn green.
If the agent changes the test, adds a dependency, or edits another path, do not stage. Ask it to restore the test and reduce the repair to the claimant boundary.
The repair is separate from the committed regression.
Prove the same test turns green
Run the named regression and then the complete service suite in a native terminal before staging the repair.
The same test must change from red to green, while an ordinary claimant remains valid.
You · Native terminal · Windows
python -m unittest tests.test_service.TicketTransitionTests.test_claim_rejects_control_characters_in_volunteer_label -v; python -m unittest tests.test_service -v
You · Native terminal · macOS
python3 -m unittest tests.test_service.TicketTransitionTests.test_claim_rejects_control_characters_in_volunteer_label -v && python3 -m unittest tests.test_service -v
You · Native terminal · Linux
python3 -m unittest tests.test_service.TicketTransitionTests.test_claim_rejects_control_characters_in_volunteer_label -v && python3 -m unittest tests.test_service -v
The named regression passes and the service suite passes, including its ordinary claimant behavior.
If either command fails, preserve the output and ask the agent to revise only workshop_queue/service.py. Keep the red-test commit unchanged.
One named regression is red before the repair and green after it.
Inspect the service-only boundary
Inspect the whole worktree and both lesson paths before the repair commit. The committed test must have no new diff.
The external checkpoint rejects any combined, extra-path, or rewritten-test repair.
You · Native terminal · Windows
git status --short; git diff --check; git diff -- tests/test_service.py workshop_queue/service.py
You · Native terminal · macOS
git status --short && git diff --check && git diff -- tests/test_service.py workshop_queue/service.py
You · Native terminal · Linux
git status --short && git diff --check && git diff -- tests/test_service.py workshop_queue/service.py
Only workshop_queue/service.py is modified, with no whitespace error and no new tests/test_service.py diff.
If another path changed, do not stage. Preserve the attempt and remove only the unintended uncommitted scope before requesting review.
The second commit boundary is visibly production-only.
Stage only the production repair
Stage exactly workshop_queue/service.py in a native terminal. This is a shell command you run directly, so it never begins with !. Do not stage the committed regression or any other path.
The second review and governed commit need one visible, service-only staged boundary.
You · Native terminal · Windows
git add -- workshop_queue/service.py; git diff --cached --check; git diff --cached --name-only
You · Native terminal · macOS
git add -- workshop_queue/service.py && git diff --cached --check && git diff --cached --name-only
You · Native terminal · Linux
git add -- workshop_queue/service.py && git diff --cached --check && git diff --cached --name-only
The staged path list prints exactly workshop_queue/service.py and the staged diff has no whitespace error.
If another path is staged, unstage only that path and inspect the whole worktree again. Do not commit until the staged list is exact.
The second proposed commit has one visible staged service path.
Approve the service-only boundary
Paste this review request into the selected harness and send it. It is not a shell command and never begins with !.
The learner approves the narrow repair after the regression and full service suite pass.
You · Claude Code harness · All operating systems
Show git status --short, the staged path list, and the staged diff. Do not commit. Report whether the whole worktree changes only workshop_queue/service.py, whether the staged path is exactly workshop_queue/service.py, whether the earlier regression remains unchanged, and whether the guard is reachable from claim_ticket.
You · Codex harness · All operating systems
Show git status --short, the staged path list, and the staged diff. Do not commit. Report whether the whole worktree changes only workshop_queue/service.py, whether the staged path is exactly workshop_queue/service.py, whether the earlier regression remains unchanged, and whether the guard is reachable from claim_ticket.
You · Pi harness · All operating systems
Show git status --short, the staged path list, and the staged diff. Do not commit. Report whether the whole worktree changes only workshop_queue/service.py, whether the staged path is exactly workshop_queue/service.py, whether the earlier regression remains unchanged, and whether the guard is reachable from claim_ticket.
The agent reports one service path, an unchanged regression, and a reachable narrow guard for learner approval.
If the report names a changed test, another path, or an unreachable guard, do not approve. Preserve the attempt and correct only that defect.
The learner approved the exact second commit boundary.
After that report identifies only workshop_queue/service.py, let the agent make the second governed commit.
Commit the production repair
After the learner approves the boundary, paste the copied commit command into the selected harness prompt and send it. It is not a shell command. The agent runs the CodeArbiter commit gate; do not use git commit.
The second governed commit preserves the repair separately from the red regression.
Your agent · Claude Code harness · All operating systems
/ca:commit
Your agent · Codex harness · All operating systems
$ca-commit
Your agent · Pi harness · All operating systems
/ca-commit
Your agent · Pi harness · All operating systems
/skill:ca-commit
CodeArbiter creates one later learner commit containing only workshop_queue/service.py.
If the gate blocks, preserve the finding. Do not amend the red regression, direct-commit, or add tests/test_service.py to this repair commit.
The second immutable learner commit contains the production repair only.
Inspect the exact two-commit proof
Confirm the worktree is clean and read the most recent two learner commits in a native terminal. The older commit must be test-only and the newer commit service-only.
Check reconstructs this history from Git rather than trusting a transcript.
You · Native terminal · Windows
git status --short; git log --oneline --name-only -2
You · Native terminal · macOS
git status --short && git log --oneline --name-only -2
You · Native terminal · Linux
git status --short && git log --oneline --name-only -2
Git prints no status paths and shows two commits after Prepare: tests/test_service.py first, then workshop_queue/service.py.
If the history has another path, another commit, or dirty state, preserve it and use Reset for a numbered retry. Do not rebase, amend, or delete the failed evidence.
The exact two commits are available for the external checkpoint to inspect.
Verify independently and preserve the result
Before Check, read the two commit summaries and confirm that git status --short prints nothing. If a path, commit boundary, or result differs from the lesson, preserve the attempt. It is evidence to inspect, not clutter to rewrite.
Recognize success
Success is not a reassuring transcript. Git shows a clean worktree and exactly two learner commits after Prepare: the older commit changes only tests/test_service.py and is still red at that point; the newer commit changes only workshop_queue/service.py and makes the same regression green. The full service suite remains green, and Sam Allen still succeeds.
That separation lets another person reconstruct what was wrong, confirm that the first commit actually detected it, and see the narrow repair without trusting a chat summary.
Check
04Verify and preserve
Run the external Academy Check
Run Check from a native terminal. Academy reads the prepared baseline, commit order, retained source shapes, and clean current worktree without executing learner-authored code.
External verification makes the evidence independently reconstructable.
You · Native terminal · Windows
$academy = "$env:LOCALAPPDATA\ArbiterAcademy\preview-0.30\Scripts\arbiter-academy.exe"
& $academy --repository (Get-Location).Path check F04-fix-with-evidence
You · Native terminal · macOS
academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.30/bin/arbiter-academy"
"$academy" --repository "$PWD" check F04-fix-with-evidence
You · Native terminal · Linux
academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.30/bin/arbiter-academy"
"$academy" --repository "$PWD" check F04-fix-with-evidence
Check prints checkpoint F04-fix-with-evidence: passed; progress: .academy/progress.json.
If Check fails, preserve the exact history and read its named predicate. Use Reset for a new numbered attempt instead of rewriting committed evidence.
Only a passing external Check records F04 progress.
Check is the external Academy verifier. It reads the prepared baseline, your commit order and path sets, the retained regression and reachable repair shapes, and whether the live worktree is clean. It does not execute learner-authored code. The red and green commands you ran above are your real behavioral evidence; Check reconstructs their source and history safely. A green final test alone is not enough: Check rejects a same-commit fix, a code-first path, an unreachable guard, unrelated changes, or uncommitted work.
Python can refresh its own cache file while it runs the service test. Check excludes only those two exercised cache files; every learner-authored, staged, tracked, or untracked change still fails the clean-worktree condition.
Recover or continue
If Check fails, preserve the branch and read the named predicate before attempting anything else. Do not amend, rebase, force-reset, delete the branch, or hide evidence. Use Reset only after a failed Check or an attempt whose commit boundary is irrecoverably wrong; it preserves the failed attempt and creates the next numbered retry.
Hint 1
The defect is at claim_ticket. A test that only validates a new helper does not prove the service rejects an unsafe label when it claims a ticket.
Hint 2
The first commit must remain red. Inspect it before asking for production work, then keep that test unchanged while the production repair turns it green.
Hint 3
If a report shows two paths, another commit, a changed regression, or a dirty worktree, stop before Check. A fresh numbered retry is more useful evidence than rewritten history.
Create a preserved numbered retry
Use this only after a failed Check or an irrecoverably wrong attempt. Run Reset in a native terminal at the Academy clone root.
Reset keeps the failed red-to-green history reachable and starts the same defect on the next unused branch number.
You · Native terminal · Windows
$academy = "$env:LOCALAPPDATA\ArbiterAcademy\preview-0.30\Scripts\arbiter-academy.exe"
& $academy --repository (Get-Location).Path reset F04-fix-with-evidence
You · Native terminal · macOS
academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.30/bin/arbiter-academy"
"$academy" --repository "$PWD" reset F04-fix-with-evidence
You · Native terminal · Linux
academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.30/bin/arbiter-academy"
"$academy" --repository "$PWD" reset F04-fix-with-evidence
Academy archives the prior attempt and switches to the next academy/F04-fix-with-evidence/ATTEMPT_NUMBER branch.
If Reset stops, preserve its message and current branch. Never force-reset or delete the prior attempt.
The failed attempt remains reachable while the retry starts clean.
After Check passes, return to main and leave the completed attempt branch available for review.
Return to main after success
After Check passes, return to main in a native terminal without deleting the completed attempt branch.
The passing attempt remains available for a reviewer to inspect.
You · Native terminal · Windows
git switch main
You · Native terminal · macOS
git switch main
You · Native terminal · Linux
git switch main
Git switches to main and leaves academy/F04-fix-with-evidence/ATTEMPT_NUMBER reachable.
If Git refuses because work is uncommitted, stop and preserve it. Do not force the switch.
The completed evidence remains separated from main.
F04 is complete only after the external Check passes. Continue to P01 when that guided Academy lesson is published; an unpublished source exercise is not a substitute for a course step.
Understand the mechanism
This pattern is a causal proof, not a ritual. Prepare establishes a known defective baseline. The first commit records a test that reaches the live production boundary and fails for the missing validation. The second commit adds the smallest reachable validation that makes that exact test pass. The external verifier checks both snapshots, both path boundaries, and the clean current worktree.
The operations surface stays small on purpose. Academy prepares, checks, resets, and returns an attempt; the website teaches the decisions; CodeArbiter governs the agent work. Each part has one job, so a learner can tell which command belongs where and a reviewer can reproduce the result.