Skip to content

Fork, clone, and doctor safety

No prior Academy lesson is required. Complete five Academy Home setup steps before Prepare. New here? Stop on this page until you have created your personal GitHub fork, cloned that fork, installed Academy, chosen and installed your codeArbiter host, and run Home Doctor in the clone. An expected missing upstream finding proceeds to F01; this lesson repairs that boundary. Those steps require Git 2.39 or newer, Python 3.11 or newer, and Claude Code, Codex, or Pi.

Work only in the arbiter-academy fork and clone you prepared from Home. A fork is the GitHub copy you own. A clone is its local working copy. In that clone, origin must mean your fork and upstream must mean the official arbiterForge/arbiter-academy repository. You fetch updates from upstream, but this lesson makes pushing there fail locally.

Begin on a clean main: clean means the repository has no staged or unstaged changes. Keep the Installed Academy commands available in a Native terminal for preparation, Doctor, Check, and Reset. Use that terminal for a command you run directly. When a command appears for your Claude Code, Codex, or Pi harness, its single leading ! passes that shell command to the terminal. codeArbiter commands never use !.

You will create one numbered attempt, make push routing safe, pass both Doctors, and commit only the bounded Doctor report through codeArbiter. Then the externally installed Academy verifier will read the committed report and current Git configuration before recording progress. It does not trust code imported from this learner checkout.

The evidence report must decode to exactly these three values (formatting whitespace may differ):

{"schema_version":1,"safe_for_push_labs":true,"effective_push_remote":"origin"}

  1. You

    Prepare a numbered attempt

    Run the installed Academy Prepare command from the clone. Begin only from a clean main branch. The <attempt> shown in later branch names means the number Academy prints; do not type the angle-bracket placeholder.

    Why this matters: Preparation creates and switches to an isolated numbered branch while preserving main.

    Windows

    $academy = "$env:LOCALAPPDATA\ArbiterAcademy\preview-0.32\Scripts\arbiter-academy.exe"
    & $academy --repository (Get-Location).Path prepare F01-fork-clone-doctor

    macOS

    academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.32/bin/arbiter-academy"
    "$academy" --repository "$PWD" prepare F01-fork-clone-doctor

    Linux

    academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.32/bin/arbiter-academy"
    "$academy" --repository "$PWD" prepare F01-fork-clone-doctor

    Expected result

    Academy prints a prepared branch named academy/F01-fork-clone-doctor/<attempt> and switches the repository to it.

    Evidence

    The prepared branch is the only place where this lesson evidence may be committed.

    If that does not happen

    If Prepare stops, preserve its message. Return to Recovery for the matching dirty-worktree, wrong-branch, remote, or existing-attempt path before retrying.

The branch printed by Academy has the form academy/F01-fork-clone-doctor/ATTEMPT_NUMBER. Here, ATTEMPT_NUMBER means the number Academy prints, such as 1; it is not text you type literally.

  1. You

    Inspect fetch and push routing

    Run the command for your operating system and execution surface. Read every fetch and push line before changing a remote.

    Why this matters: Inspection distinguishes the fork you own from the official repository you only fetch from.

    Windows

    git remote -v

    macOS

    git remote -v

    Linux

    git remote -v

    Windows · Claude Code

    !git remote -v

    macOS · Claude Code

    !git remote -v

    Linux · Claude Code

    !git remote -v

    Windows · Codex

    !git remote -v

    macOS · Codex

    !git remote -v

    Linux · Codex

    !git remote -v

    Windows · Pi

    !git remote -v

    macOS · Pi

    !git remote -v

    Linux · Pi

    !git remote -v

    Expected result

    Git prints the current fetch and push URLs for origin and any upstream remote.

    Evidence

    You can name which repository each remote reaches and whether it is used for fetch or push.

    If that does not happen

    If Git reports that this is not a repository, stop and return to the cloned arbiter-academy root. If a remote is absent, continue with the repair actions; do not invent a URL.

Repair only the fact each action names, then inspect the result. Do not copy a guessed owner, remove a remote to silence a diagnostic, or make the official repository a push destination.

  1. You

    Point origin at your fork

    Replace <your-account> with the GitHub owner shown on your fork, then run the command for your operating system and execution surface.

    Why this matters: origin must be a repository you control before any lesson can safely push.

    Windows

    git remote set-url origin https://github.com/<your-account>/arbiter-academy.git

    macOS

    git remote set-url origin https://github.com/<your-account>/arbiter-academy.git

    Linux

    git remote set-url origin https://github.com/<your-account>/arbiter-academy.git

    Windows · Claude Code

    !git remote set-url origin https://github.com/<your-account>/arbiter-academy.git

    macOS · Claude Code

    !git remote set-url origin https://github.com/<your-account>/arbiter-academy.git

    Linux · Claude Code

    !git remote set-url origin https://github.com/<your-account>/arbiter-academy.git

    Windows · Codex

    !git remote set-url origin https://github.com/<your-account>/arbiter-academy.git

    macOS · Codex

    !git remote set-url origin https://github.com/<your-account>/arbiter-academy.git

    Linux · Codex

    !git remote set-url origin https://github.com/<your-account>/arbiter-academy.git

    Windows · Pi

    !git remote set-url origin https://github.com/<your-account>/arbiter-academy.git

    macOS · Pi

    !git remote set-url origin https://github.com/<your-account>/arbiter-academy.git

    Linux · Pi

    !git remote set-url origin https://github.com/<your-account>/arbiter-academy.git

    Expected result

    Git updates origin without printing output; a later git remote -v shows your account for both origin URLs.

    Evidence

    Live Git configuration identifies origin as a non-official arbiter-academy repository.

    If that does not happen

    If Git says origin does not exist, stop: this is not the expected fork clone. Return to Home and clone your fork rather than adding a guessed origin.

  1. You

    Set the official fetch remote

    Run the idempotent command for your operating system and execution surface. It adds upstream when absent and corrects its fetch URL when present.

    Why this matters: upstream gives the clone a stable read path to the official Academy without changing origin.

    Windows

    $null = git remote get-url upstream 2>$null; if ($LASTEXITCODE -eq 0) { git remote set-url upstream https://github.com/arbiterForge/arbiter-academy.git } else { git remote add upstream https://github.com/arbiterForge/arbiter-academy.git }

    macOS

    git remote get-url upstream >/dev/null 2>&1 && git remote set-url upstream https://github.com/arbiterForge/arbiter-academy.git || git remote add upstream https://github.com/arbiterForge/arbiter-academy.git

    Linux

    git remote get-url upstream >/dev/null 2>&1 && git remote set-url upstream https://github.com/arbiterForge/arbiter-academy.git || git remote add upstream https://github.com/arbiterForge/arbiter-academy.git

    Windows · Claude Code

    !$null = git remote get-url upstream 2>$null; if ($LASTEXITCODE -eq 0) { git remote set-url upstream https://github.com/arbiterForge/arbiter-academy.git } else { git remote add upstream https://github.com/arbiterForge/arbiter-academy.git }

    macOS · Claude Code

    !git remote get-url upstream >/dev/null 2>&1 && git remote set-url upstream https://github.com/arbiterForge/arbiter-academy.git || git remote add upstream https://github.com/arbiterForge/arbiter-academy.git

    Linux · Claude Code

    !git remote get-url upstream >/dev/null 2>&1 && git remote set-url upstream https://github.com/arbiterForge/arbiter-academy.git || git remote add upstream https://github.com/arbiterForge/arbiter-academy.git

    Windows · Codex

    !$null = git remote get-url upstream 2>$null; if ($LASTEXITCODE -eq 0) { git remote set-url upstream https://github.com/arbiterForge/arbiter-academy.git } else { git remote add upstream https://github.com/arbiterForge/arbiter-academy.git }

    macOS · Codex

    !git remote get-url upstream >/dev/null 2>&1 && git remote set-url upstream https://github.com/arbiterForge/arbiter-academy.git || git remote add upstream https://github.com/arbiterForge/arbiter-academy.git

    Linux · Codex

    !git remote get-url upstream >/dev/null 2>&1 && git remote set-url upstream https://github.com/arbiterForge/arbiter-academy.git || git remote add upstream https://github.com/arbiterForge/arbiter-academy.git

    Windows · Pi

    !$null = git remote get-url upstream 2>$null; if ($LASTEXITCODE -eq 0) { git remote set-url upstream https://github.com/arbiterForge/arbiter-academy.git } else { git remote add upstream https://github.com/arbiterForge/arbiter-academy.git }

    macOS · Pi

    !git remote get-url upstream >/dev/null 2>&1 && git remote set-url upstream https://github.com/arbiterForge/arbiter-academy.git || git remote add upstream https://github.com/arbiterForge/arbiter-academy.git

    Linux · Pi

    !git remote get-url upstream >/dev/null 2>&1 && git remote set-url upstream https://github.com/arbiterForge/arbiter-academy.git || git remote add upstream https://github.com/arbiterForge/arbiter-academy.git

    Expected result

    upstream exists and its fetch URL is https://github.com/arbiterForge/arbiter-academy.git.

    Evidence

    The official repository is reachable through upstream for fetch operations.

    If that does not happen

    If Git rejects the command, run the inspection action again and preserve its exact output. Do not remove a remote until you understand what it points to.

  1. You

    Disable pushes to upstream

    Run the command for your operating system and execution surface. DISABLED is an intentional non-network push target.

    Why this matters: A disabled upstream push URL turns an accidental upstream push into a local failure.

    Windows

    git remote set-url --push upstream DISABLED

    macOS

    git remote set-url --push upstream DISABLED

    Linux

    git remote set-url --push upstream DISABLED

    Windows · Claude Code

    !git remote set-url --push upstream DISABLED

    macOS · Claude Code

    !git remote set-url --push upstream DISABLED

    Linux · Claude Code

    !git remote set-url --push upstream DISABLED

    Windows · Codex

    !git remote set-url --push upstream DISABLED

    macOS · Codex

    !git remote set-url --push upstream DISABLED

    Linux · Codex

    !git remote set-url --push upstream DISABLED

    Windows · Pi

    !git remote set-url --push upstream DISABLED

    macOS · Pi

    !git remote set-url --push upstream DISABLED

    Linux · Pi

    !git remote set-url --push upstream DISABLED

    Expected result

    Git updates the push URL without printing output; git remote -v later shows upstream (push) as DISABLED.

    Evidence

    Live Git configuration makes upstream unusable as a push destination.

    If that does not happen

    If Git says upstream does not exist, complete the preceding upstream action first. Never substitute the official GitHub URL as the push URL.

  1. You

    Make origin the default push remote

    Run the command for your operating system and execution surface.

    Why this matters: Explicit push routing avoids relying on a changing branch or Git default.

    Windows

    git config remote.pushDefault origin

    macOS

    git config remote.pushDefault origin

    Linux

    git config remote.pushDefault origin

    Windows · Claude Code

    !git config remote.pushDefault origin

    macOS · Claude Code

    !git config remote.pushDefault origin

    Linux · Claude Code

    !git config remote.pushDefault origin

    Windows · Codex

    !git config remote.pushDefault origin

    macOS · Codex

    !git config remote.pushDefault origin

    Linux · Codex

    !git config remote.pushDefault origin

    Windows · Pi

    !git config remote.pushDefault origin

    macOS · Pi

    !git config remote.pushDefault origin

    Linux · Pi

    !git config remote.pushDefault origin

    Expected result

    Git writes the setting without printing output; git config --get remote.pushDefault prints origin.

    Evidence

    remote.pushDefault resolves ordinary pushes through origin.

    If that does not happen

    If the later inspection prints another name or nothing, run this action once more from the attempt repository and inspect for repository-local configuration overrides.

  1. Your host

    Ask codeArbiter to inspect the host boundary

    Ask the agent in your active harness to run the host-native Doctor command. Pi users may use the fallback when direct dispatch is unavailable.

    Why this matters: Host Doctor confirms codeArbiter activation and enforcement separately from Academy lesson evidence.

    Any OS · Claude Code

    /ca:doctor

    Any OS · Codex

    $ca-doctor

    Any OS · Pi

    /ca-doctor

    Any OS · Pi

    /skill:ca-doctor

    Expected result

    Host Doctor reports that the active host owns its codeArbiter commands and that repository enforcement is enabled.

    Evidence

    A passing Host Doctor is a prerequisite; it is not the Academy report or checkpoint.

    If that does not happen

    If Host Doctor reports an installation, ownership, or enforcement failure, stop. Repair that host boundary before generating or committing Academy evidence.

  1. You

    Generate the bounded Academy Doctor report

    Run the installed Academy Doctor command for F01. Do not continue to the evidence commit if Doctor fails.

    Why this matters: Academy Doctor recomputes the lesson-safe remote facts and writes only the bounded report.

    Windows

    $academy = "$env:LOCALAPPDATA\ArbiterAcademy\preview-0.32\Scripts\arbiter-academy.exe"
    & $academy --repository (Get-Location).Path doctor F01-fork-clone-doctor

    macOS

    academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.32/bin/arbiter-academy"
    "$academy" --repository "$PWD" doctor F01-fork-clone-doctor

    Linux

    academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.32/bin/arbiter-academy"
    "$academy" --repository "$PWD" doctor F01-fork-clone-doctor

    Expected result

    Academy Doctor passes and creates .codearbiter/reports/academy/F01-doctor.json.

    Evidence

    The report is newly generated from live Git configuration.

    If that does not happen

    If Doctor fails, do not stage or commit the report. Return to the named remote or host action, correct only that boundary, and run both Doctors again.

Doctor failure forbids the evidence commit. Continue only after Host Doctor passes and Academy Doctor creates .codearbiter/reports/academy/F01-doctor.json from the live repository state.

  1. You

    Inspect the exact report bytes

    Run the command for your operating system and execution surface, then compare all three fields with the expected result before staging.

    Why this matters: Reading the report prevents stale or malformed learner-controlled evidence from crossing the commit gate.

    Windows

    Get-Content -Raw -LiteralPath .codearbiter/reports/academy/F01-doctor.json

    macOS

    cat -- .codearbiter/reports/academy/F01-doctor.json

    Linux

    cat -- .codearbiter/reports/academy/F01-doctor.json

    Windows · Claude Code

    !Get-Content -Raw -LiteralPath .codearbiter/reports/academy/F01-doctor.json

    macOS · Claude Code

    !cat -- .codearbiter/reports/academy/F01-doctor.json

    Linux · Claude Code

    !cat -- .codearbiter/reports/academy/F01-doctor.json

    Windows · Codex

    !Get-Content -Raw -LiteralPath .codearbiter/reports/academy/F01-doctor.json

    macOS · Codex

    !cat -- .codearbiter/reports/academy/F01-doctor.json

    Linux · Codex

    !cat -- .codearbiter/reports/academy/F01-doctor.json

    Windows · Pi

    !Get-Content -Raw -LiteralPath .codearbiter/reports/academy/F01-doctor.json

    macOS · Pi

    !cat -- .codearbiter/reports/academy/F01-doctor.json

    Linux · Pi

    !cat -- .codearbiter/reports/academy/F01-doctor.json

    Expected result

    The report decodes to {"schema_version":1,"safe_for_push_labs":true,"effective_push_remote":"origin"}; whitespace may differ but no other field is present.

    Evidence

    You have personally checked the exact file that the external verifier will later read.

    If that does not happen

    If any field or value differs, leave the report uncommitted and run Academy Doctor again after correcting live Git configuration.

  1. You

    Stage only the Doctor report

    Run the command for your operating system and execution surface. Do not use git add . or add another path.

    Why this matters: The lesson commit must contain only its bounded evidence report.

    Windows

    git add -- .codearbiter/reports/academy/F01-doctor.json

    macOS

    git add -- .codearbiter/reports/academy/F01-doctor.json

    Linux

    git add -- .codearbiter/reports/academy/F01-doctor.json

    Windows · Claude Code

    !git add -- .codearbiter/reports/academy/F01-doctor.json

    macOS · Claude Code

    !git add -- .codearbiter/reports/academy/F01-doctor.json

    Linux · Claude Code

    !git add -- .codearbiter/reports/academy/F01-doctor.json

    Windows · Codex

    !git add -- .codearbiter/reports/academy/F01-doctor.json

    macOS · Codex

    !git add -- .codearbiter/reports/academy/F01-doctor.json

    Linux · Codex

    !git add -- .codearbiter/reports/academy/F01-doctor.json

    Windows · Pi

    !git add -- .codearbiter/reports/academy/F01-doctor.json

    macOS · Pi

    !git add -- .codearbiter/reports/academy/F01-doctor.json

    Linux · Pi

    !git add -- .codearbiter/reports/academy/F01-doctor.json

    Expected result

    Git stages only .codearbiter/reports/academy/F01-doctor.json and prints no output.

    Evidence

    The proposed evidence boundary contains one path.

    If that does not happen

    If staging fails, confirm the exact report path and that Academy Doctor succeeded. If another path is already staged, unstage it without discarding its work before continuing.

  1. You

    Review and approve the proposed boundary

    Ask your agent to show the staged path and proposed codeArbiter commit boundary. Confirm that only the F01 Doctor report is included, then supply any genuine approval the commit gate requests.

    Why this matters: The learner approves what will become durable evidence; the agent owns the governed commit operation.

    Any OS · Claude Code

    Show the staged path list and staged diff. Do not commit. Report whether the staged path list is exactly .codearbiter/reports/academy/F01-doctor.json and whether the report is the Doctor evidence I prepared. Do not stage, unstage, or modify anything.

    Any OS · Codex

    Show the staged path list and staged diff. Do not commit. Report whether the staged path list is exactly .codearbiter/reports/academy/F01-doctor.json and whether the report is the Doctor evidence I prepared. Do not stage, unstage, or modify anything.

    Any OS · Pi

    Show the staged path list and staged diff. Do not commit. Report whether the staged path list is exactly .codearbiter/reports/academy/F01-doctor.json and whether the report is the Doctor evidence I prepared. Do not stage, unstage, or modify anything.

    Expected result

    The proposed boundary names only .codearbiter/reports/academy/F01-doctor.json, and any requested approval is an informed learner decision.

    Evidence

    Your approval applies only to the one-report commit.

    If that does not happen

    If another path appears, do not approve. Ask the agent to preserve and unstage the unrelated work, then review the boundary again.

  1. Your host

    Let the agent commit through codeArbiter

    Ask the agent in your active harness to invoke the host-native codeArbiter commit gate. The learner does not run git commit for this evidence.

    Why this matters: The commit gate verifies and records the exact approved boundary.

    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 commit whose changed path is only .codearbiter/reports/academy/F01-doctor.json.

    Evidence

    The attempt branch now contains durable, governed learner evidence.

    If that does not happen

    If the gate blocks, preserve its finding and correct that boundary. Do not bypass the gate, run git commit directly, or commit when either Doctor failed.

  1. You

    Confirm the attempt is clean

    Run the command for your operating system and execution surface after the evidence commit.

    Why this matters: External Check rejects uncommitted or staged state because it cannot reconstruct that state later.

    Windows

    git status --short

    macOS

    git status --short

    Linux

    git status --short

    Windows · Claude Code

    !git status --short

    macOS · Claude Code

    !git status --short

    Linux · Claude Code

    !git status --short

    Windows · Codex

    !git status --short

    macOS · Codex

    !git status --short

    Linux · Codex

    !git status --short

    Windows · Pi

    !git status --short

    macOS · Pi

    !git status --short

    Linux · Pi

    !git status --short

    Expected result

    Git prints nothing.

    Evidence

    The worktree and index match the committed attempt.

    If that does not happen

    If Git prints a path, preserve the evidence commit. Resolve or safely preserve that uncommitted path before Check; do not reset the attempt commit.

The Doctor report contains only schema_version, safe_for_push_labs, and effective_push_remote. The evidence commit changes only .codearbiter/reports/academy/F01-doctor.json. Immediately before Check, git status --short prints nothing. No output is the expected successful result: the attempt is clean.

  1. You

    Run the external Academy Check

    Run the installed Academy Check command for F01. This invokes the externally installed verifier, not code imported from the learner checkout.

    Why this matters: An external verifier independently reads the committed report and the current live Git configuration.

    Windows

    $academy = "$env:LOCALAPPDATA\ArbiterAcademy\preview-0.32\Scripts\arbiter-academy.exe"
    & $academy --repository (Get-Location).Path check F01-fork-clone-doctor

    macOS

    academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.32/bin/arbiter-academy"
    "$academy" --repository "$PWD" check F01-fork-clone-doctor

    Linux

    academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.32/bin/arbiter-academy"
    "$academy" --repository "$PWD" check F01-fork-clone-doctor

    Expected result

    Check prints checkpoint F01-fork-clone-doctor: passed; progress: .academy/progress.json.

    Evidence

    Only after the external verifier reads the committed report and live Git configuration does it write .academy/progress.json.

    If that does not happen

    Check failure preserves the clean committed attempt and its failure. Correct the named live boundary or run Reset for a numbered retry; do not delete the attempt commit.

A pass contains checkpoint F01-fork-clone-doctor: passed; progress: .academy/progress.json. The progress record is written only after the external verifier independently reads the clean, committed report and live Git configuration. A report by itself, a Host Doctor pass, or an Academy Doctor pass does not complete the lesson.

If Check fails, preserve the clean committed attempt. Read the failed predicate, compare it with the matching action’s expected result and recovery, and change only that boundary. Check failure never requires deleting the evidence commit.

Start with origin, upstream, and remote.pushDefault. Name where each push would go before changing it.

Both the committed report and the current Git configuration must be safe. Regenerate the report after changing a remote.

If an attempt mixes unrelated files into the evidence commit, preserve it and use Reset. A new numbered attempt is safer than rewriting evidence history.

  1. You

    Return to main after success

    After Check passes, run the command for your operating system and execution surface.

    Why this matters: Returning to the base branch leaves the completed attempt preserved for audit and later review.

    Windows

    git switch main

    macOS

    git switch main

    Linux

    git switch main

    Windows · Claude Code

    !git switch main

    macOS · Claude Code

    !git switch main

    Linux · Claude Code

    !git switch main

    Windows · Codex

    !git switch main

    macOS · Codex

    !git switch main

    Linux · Codex

    !git switch main

    Windows · Pi

    !git switch main

    macOS · Pi

    !git switch main

    Linux · Pi

    !git switch main

    Expected result

    Git switches to main and the numbered F01 attempt branch remains available.

    Evidence

    The completed attempt remains separate from main.

    If that does not happen

    If Git refuses because of uncommitted work, stop and preserve it. Do not force the switch or delete the completed attempt branch.

  1. You

    Create a preserved numbered retry

    Use this only when you need another attempt: run the installed Academy Reset command for F01.

    Why this matters: Reset archives the current attempt ref and prepares the next unused numbered branch without erasing evidence.

    Windows

    $academy = "$env:LOCALAPPDATA\ArbiterAcademy\preview-0.32\Scripts\arbiter-academy.exe"
    & $academy --repository (Get-Location).Path reset F01-fork-clone-doctor

    macOS

    academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.32/bin/arbiter-academy"
    "$academy" --repository "$PWD" reset F01-fork-clone-doctor

    Linux

    academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.32/bin/arbiter-academy"
    "$academy" --repository "$PWD" reset F01-fork-clone-doctor

    Expected result

    Academy preserves the prior attempt under an archive ref and prints the next academy/F01-fork-clone-doctor/<attempt> branch.

    Evidence

    The failed attempt commit remains reachable while the new attempt starts from the clean lesson base.

    If that does not happen

    If Reset stops, preserve its message and current branch. Resolve only the named dirty-state or repository boundary before retrying; never force-reset or delete the prior attempt.

After Check passes, return to main when you want to leave the completed attempt untouched. The next Academy lesson appears on the course home only after its guided rewrite and acceptance evidence are complete. Do not use unpublished source exercises as a substitute for the next guided lesson. Use Reset only to preserve a failed attempt and prepare the next number.

The report is deliberately small and learner-controlled; it records no username, URL, credential, email, local path, or terminal transcript. The verifier therefore checks two independent sources: the exact report committed on the numbered branch and the live Git configuration at Check time. Changing either after Doctor breaks the proof. Keeping preparation, the governed evidence commit, clean state, and external verification separate makes the result reconstructable instead of merely plausible.