Skip to content

Fix with evidence

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.

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.

  1. You

    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.

    Why this matters: Prepare gives the intentionally defective service a separate, reviewable history.

    Windows

    $academy = "$env:LOCALAPPDATA\ArbiterAcademy\preview-0.32\Scripts\arbiter-academy.exe"
    & $academy --repository (Get-Location).Path prepare F04-fix-with-evidence

    macOS

    academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.32/bin/arbiter-academy"
    "$academy" --repository "$PWD" prepare F04-fix-with-evidence

    Linux

    academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.32/bin/arbiter-academy"
    "$academy" --repository "$PWD" prepare F04-fix-with-evidence

    Expected result

    Academy switches this clone to academy/F04-fix-with-evidence/ATTEMPT_NUMBER.

    Evidence

    The numbered branch preserves the defective starting point.

    If that does not happen

    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 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.

  1. You

    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.

    Why this matters: The lesson repairs one claimant-label rule, not the CLI, JSON storage, or a fictional copy of the service.

    Windows

    Get-Content -LiteralPath 'workshop_queue/service.py'; Get-Content -LiteralPath 'tests/test_service.py'

    macOS

    sed -n '1,240p' workshop_queue/service.py; sed -n '1,180p' tests/test_service.py

    Linux

    sed -n '1,240p' workshop_queue/service.py; sed -n '1,180p' tests/test_service.py

    Expected result

    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.

    Evidence

    You identified the real production boundary and the missing executable regression.

    If that does not happen

    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.

  1. You

    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.

    Why this matters: A green prepared baseline lets the later red result identify the new regression instead of a pre-existing failure.

    Windows

    git status --short; python -m unittest tests.test_service -v

    macOS

    git status --short && python3 -m unittest tests.test_service -v

    Linux

    git status --short && python3 -m unittest tests.test_service -v

    Expected result

    Git prints nothing and the existing service tests pass.

    Evidence

    The red test will be attributable to the regression you request next.

    If that does not happen

    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.

MomentDurable evidence
PrepareA clean, deliberately defective baseline on a numbered attempt branch.
Prove redOne test-only commit that reaches claim_ticket and fails for the intended control characters.
Repair greenOne service-only commit that makes the unchanged regression pass.
CheckAn external reconstruction of the two snapshots, path boundaries, and clean worktree.

Open the governed fix lane before requesting any change. The copied command below belongs in your selected harness, not in a terminal.

  1. Your host

    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.

    Why this matters: The fix lane records the defect boundary and keeps the upcoming work under the repository's rules.

    Any OS · Claude Code

    /ca:fix "Reject control characters in a claimant label"

    Any OS · Codex

    $ca-fix "Reject control characters in a claimant label"

    Any OS · Pi

    /ca-fix "Reject control characters in a claimant label"

    Any OS · Pi

    /skill:ca-fix "Reject control characters in a claimant label"

    Expected result

    The agent identifies the claimant-label defect and waits for a regression-first change.

    Evidence

    The governed path names the production boundary before it changes.

    If that does not happen

    If the command blocks, preserve its finding. Do not bypass the lane or edit workshop_queue/service.py from a terminal.

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.

  1. You

    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 !.

    Why this matters: The first commit must prove the defect exists before any repair can make it pass.

    Any OS · Claude Code

    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.

    Any OS · Codex

    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.

    Any OS · Pi

    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.

    Expected result

    Only tests/test_service.py changes, and the focused regression fails because claim_ticket does not raise ValueError.

    Evidence

    The same named test is executable proof of the original defect.

    If that does not happen

    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.

  1. You

    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.

    Why this matters: A test that passes before the repair cannot prove the repair fixed the intended defect.

    Windows

    python -m unittest tests.test_service.TicketTransitionTests.test_claim_rejects_control_characters_in_volunteer_label -v

    macOS

    python3 -m unittest tests.test_service.TicketTransitionTests.test_claim_rejects_control_characters_in_volunteer_label -v

    Linux

    python3 -m unittest tests.test_service.TicketTransitionTests.test_claim_rejects_control_characters_in_volunteer_label -v

    Expected result

    The test fails because ValueError was not raised for a claimant label containing a control character.

    Evidence

    You personally observed the red assertion against the prepared production code.

    If that does not happen

    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.

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.

  1. You

    Inspect the test-only boundary

    Inspect whole-worktree status and both relevant paths before staging. The service path must have no diff yet.

    Why this matters: The history proof fails if the regression and repair share one commit.

    Windows

    git status --short; git diff --check; git diff -- tests/test_service.py workshop_queue/service.py

    macOS

    git status --short && git diff --check && git diff -- tests/test_service.py workshop_queue/service.py

    Linux

    git status --short && git diff --check && git diff -- tests/test_service.py workshop_queue/service.py

    Expected result

    Only tests/test_service.py is modified, with no whitespace error and no workshop_queue/service.py change.

    Evidence

    The first commit boundary is visibly test-only.

    If that does not happen

    If another path changed, do not stage. Preserve the attempt and ask the agent to remove the unrelated change before the regression commit.

  1. You

    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.

    Why this matters: The review and governed commit need one visible, test-only staged boundary.

    Windows

    git add -- tests/test_service.py; git diff --cached --check; git diff --cached --name-only

    macOS

    git add -- tests/test_service.py && git diff --cached --check && git diff --cached --name-only

    Linux

    git add -- tests/test_service.py && git diff --cached --check && git diff --cached --name-only

    Expected result

    The staged path list prints exactly tests/test_service.py and the staged diff has no whitespace error.

    Evidence

    The first proposed commit has one visible staged test path.

    If that does not happen

    If another path is staged, unstage only that path and inspect the whole worktree again. Do not commit until the staged list is exact.

  1. You

    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 !.

    Why this matters: The learner approves a narrow test-only commit after inspecting the real diff.

    Any OS · Claude Code

    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.

    Any OS · Codex

    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.

    Any OS · Pi

    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.

    Expected result

    The agent reports one test path, a real red regression, and no production change for learner approval.

    Evidence

    The learner approved the exact first commit boundary.

    If that does not happen

    If the report names another path, a passing test, or a production diff, do not approve. Preserve the evidence and correct the boundary first.

When the report says the whole worktree and staged set contain only tests/test_service.py, let the agent make the first governed commit.

  1. Your host

    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.

    Why this matters: The governed commit makes the failing regression durable history before the repair exists.

    Any OS · Claude Code

    /ca:commit

    Any OS · Codex

    $ca-commit

    Any OS · Pi

    /ca-commit

    Any OS · Pi

    /skill:ca-commit

    Expected result

    codeArbiter creates one learner commit after Prepare containing only tests/test_service.py.

    Evidence

    The first immutable learner commit contains the red regression only.

    If that does not happen

    If the gate blocks, preserve the finding. Do not direct-commit, amend another attempt, or add workshop_queue/service.py to this commit.

  1. You

    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.

    Why this matters: This ties the red failure to the committed test-only history, not a transient working-tree edit.

    Windows

    git show --stat --oneline HEAD; python -m unittest tests.test_service.TicketTransitionTests.test_claim_rejects_control_characters_in_volunteer_label -v

    macOS

    git show --stat --oneline HEAD; python3 -m unittest tests.test_service.TicketTransitionTests.test_claim_rejects_control_characters_in_volunteer_label -v

    Linux

    git show --stat --oneline HEAD; python3 -m unittest tests.test_service.TicketTransitionTests.test_claim_rejects_control_characters_in_volunteer_label -v

    Expected result

    HEAD lists only tests/test_service.py, and the same regression remains red because the service has not changed.

    Evidence

    The committed red regression predates the repair.

    If that does not happen

    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.

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.

  1. You

    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 !.

    Why this matters: The repair must be a reachable claimant-label guard, not a broad rewrite or a disconnected test helper.

    Any OS · Claude Code

    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.

    Any OS · Codex

    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.

    Any OS · Pi

    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.

    Expected result

    Only workshop_queue/service.py changes and the existing regression is ready to turn green.

    Evidence

    The repair is separate from the committed regression.

    If that does not happen

    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.

  1. You

    Prove the same test turns green

    Run the named regression and then the complete service suite in a native terminal before staging the repair.

    Why this matters: The same test must change from red to green, while an ordinary claimant remains valid.

    Windows

    python -m unittest tests.test_service.TicketTransitionTests.test_claim_rejects_control_characters_in_volunteer_label -v; python -m unittest tests.test_service -v

    macOS

    python3 -m unittest tests.test_service.TicketTransitionTests.test_claim_rejects_control_characters_in_volunteer_label -v && python3 -m unittest tests.test_service -v

    Linux

    python3 -m unittest tests.test_service.TicketTransitionTests.test_claim_rejects_control_characters_in_volunteer_label -v && python3 -m unittest tests.test_service -v

    Expected result

    The named regression passes and the service suite passes, including its ordinary claimant behavior.

    Evidence

    One named regression is red before the repair and green after it.

    If that does not happen

    If either command fails, preserve the output and ask the agent to revise only workshop_queue/service.py. Keep the red-test commit unchanged.

  1. You

    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.

    Why this matters: The external checkpoint rejects any combined, extra-path, or rewritten-test repair.

    Windows

    git status --short; git diff --check; git diff -- tests/test_service.py workshop_queue/service.py

    macOS

    git status --short && git diff --check && git diff -- tests/test_service.py workshop_queue/service.py

    Linux

    git status --short && git diff --check && git diff -- tests/test_service.py workshop_queue/service.py

    Expected result

    Only workshop_queue/service.py is modified, with no whitespace error and no new tests/test_service.py diff.

    Evidence

    The second commit boundary is visibly production-only.

    If that does not happen

    If another path changed, do not stage. Preserve the attempt and remove only the unintended uncommitted scope before requesting review.

  1. You

    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.

    Why this matters: The second review and governed commit need one visible, service-only staged boundary.

    Windows

    git add -- workshop_queue/service.py; git diff --cached --check; git diff --cached --name-only

    macOS

    git add -- workshop_queue/service.py && git diff --cached --check && git diff --cached --name-only

    Linux

    git add -- workshop_queue/service.py && git diff --cached --check && git diff --cached --name-only

    Expected result

    The staged path list prints exactly workshop_queue/service.py and the staged diff has no whitespace error.

    Evidence

    The second proposed commit has one visible staged service path.

    If that does not happen

    If another path is staged, unstage only that path and inspect the whole worktree again. Do not commit until the staged list is exact.

  1. You

    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 !.

    Why this matters: The learner approves the narrow repair after the regression and full service suite pass.

    Any OS · Claude Code

    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.

    Any OS · Codex

    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.

    Any OS · Pi

    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.

    Expected result

    The agent reports one service path, an unchanged regression, and a reachable narrow guard for learner approval.

    Evidence

    The learner approved the exact second commit boundary.

    If that does not happen

    If the report names a changed test, another path, or an unreachable guard, do not approve. Preserve the attempt and correct only that defect.

After that report identifies only workshop_queue/service.py, let the agent make the second governed commit.

  1. Your host

    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.

    Why this matters: The second governed commit preserves the repair separately from the red regression.

    Any OS · Claude Code

    /ca:commit

    Any OS · Codex

    $ca-commit

    Any OS · Pi

    /ca-commit

    Any OS · Pi

    /skill:ca-commit

    Expected result

    codeArbiter creates one later learner commit containing only workshop_queue/service.py.

    Evidence

    The second immutable learner commit contains the production repair only.

    If that does not happen

    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.

  1. You

    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.

    Why this matters: Check reconstructs this history from Git rather than trusting a transcript.

    Windows

    git status --short; git log --oneline --name-only -2

    macOS

    git status --short && git log --oneline --name-only -2

    Linux

    git status --short && git log --oneline --name-only -2

    Expected result

    Git prints no status paths and shows two commits after Prepare: tests/test_service.py first, then workshop_queue/service.py.

    Evidence

    The exact two commits are available for the external checkpoint to inspect.

    If that does not happen

    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.

Verify independently and preserve the result

Section titled “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.

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.

  1. You

    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.

    Why this matters: External verification makes the evidence independently reconstructable.

    Windows

    $academy = "$env:LOCALAPPDATA\ArbiterAcademy\preview-0.32\Scripts\arbiter-academy.exe"
    & $academy --repository (Get-Location).Path check F04-fix-with-evidence

    macOS

    academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.32/bin/arbiter-academy"
    "$academy" --repository "$PWD" check F04-fix-with-evidence

    Linux

    academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.32/bin/arbiter-academy"
    "$academy" --repository "$PWD" check F04-fix-with-evidence

    Expected result

    Check prints checkpoint F04-fix-with-evidence: passed; progress: .academy/progress.json.

    Evidence

    Only a passing external Check records F04 progress.

    If that does not happen

    If Check fails, preserve the exact history and read its named predicate. Use Reset for a new numbered attempt instead of rewriting committed evidence.

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.

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.

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.

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.

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.

  1. You

    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.

    Why this matters: Reset keeps the failed red-to-green history reachable and starts the same defect on the next unused branch number.

    Windows

    $academy = "$env:LOCALAPPDATA\ArbiterAcademy\preview-0.32\Scripts\arbiter-academy.exe"
    & $academy --repository (Get-Location).Path reset F04-fix-with-evidence

    macOS

    academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.32/bin/arbiter-academy"
    "$academy" --repository "$PWD" reset F04-fix-with-evidence

    Linux

    academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.32/bin/arbiter-academy"
    "$academy" --repository "$PWD" reset F04-fix-with-evidence

    Expected result

    Academy archives the prior attempt and switches to the next academy/F04-fix-with-evidence/ATTEMPT_NUMBER branch.

    Evidence

    The failed attempt remains reachable while the retry starts clean.

    If that does not happen

    If Reset stops, preserve its message and current branch. Never force-reset or delete the prior attempt.

After Check passes, return to main and leave the completed attempt branch available for review.

  1. You

    Return to main after success

    After Check passes, return to main in a native terminal without deleting the completed attempt branch.

    Why this matters: The passing attempt remains available for a reviewer to inspect.

    Windows

    git switch main

    macOS

    git switch main

    Linux

    git switch main

    Expected result

    Git switches to main and leaves academy/F04-fix-with-evidence/ATTEMPT_NUMBER reachable.

    Evidence

    The completed evidence remains separated from main.

    If that does not happen

    If Git refuses because work is uncommitted, stop and preserve it. Do not force the switch.

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.

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.