Fork, clone, and doctor safety
Prove origin is your fork, upstream is the official Academy, and push routing cannot target upstream.
30 minutes
Arbiter Academy
Build codeArbiter habits through bounded, verifiable practice in a safe fork you own.
Required setup
Prepare your own fork and local clone before you begin the first lesson.
Open the Academy fork page, choose your GitHub account as the owner, keep the repository name arbiter-academy, and create the fork.
Expected result: GitHub opens a repository named arbiter-academy under your account and identifies it as a fork of arbiterForge/arbiter-academy.
If GitHub shows the official repository or another owner, return to the fork page and choose your own account before continuing.
Run the variant for your operating system in a Native terminal after replacing <your-account> with the owner of your fork.
Windows
git clone https://github.com/<your-account>/arbiter-academy.gitmacOS
git clone https://github.com/<your-account>/arbiter-academy.gitLinux
git clone https://github.com/<your-account>/arbiter-academy.gitExpected result: Git creates an arbiter-academy folder and reports that the clone completed.
If GitHub asks for access or Git says the repository was not found, confirm the account name and that the fork exists before retrying.
Run the variant for your operating system in the same Native terminal that created the clone.
Windows
Set-Location -LiteralPath .\arbiter-academymacOS
cd -- ./arbiter-academyLinux
cd -- ./arbiter-academyExpected result: The Native terminal prompt is inside the cloned arbiter-academy repository.
If the folder is not found, list the current folder and confirm where Git created arbiter-academy before trying again.
In a Native terminal whose current directory is the clone, run the command for your operating system. It fetches the canonical release tag with Git, extracts the installer locally, verifies its reviewed SHA-256 digest, then executes that local file.
Windows
$releaseTag = "preview-0.32"
$expectedInstallerSha256 = "{{INSTALL_PS1_SHA256}}"
$source = Join-Path ([IO.Path]::GetTempPath()) ("arbiter-academy-" + [guid]::NewGuid())
$installer = Join-Path $source "install.ps1"
New-Item -ItemType Directory -Path $source | Out-Null
git -C $source init --quiet
git -C $source remote add origin https://github.com/arbiterForge/arbiter-academy.git
git -C $source fetch --depth 1 origin "refs/tags/$releaseTag"
$git = (Get-Command git -ErrorAction Stop).Source
$command = "`"$git`" -C `"$source`" show `"FETCH_HEAD:install/install.ps1`" > `"$installer`""
& $env:ComSpec /d /s /c $command
if ($LASTEXITCODE -ne 0) { throw "could not extract the tagged installer" }
$actualInstallerSha256 = (Get-FileHash -LiteralPath $installer -Algorithm SHA256).Hash.ToLowerInvariant()
if ($actualInstallerSha256 -cne $expectedInstallerSha256) { throw "installer digest did not match Preview 0.32" }
& $installermacOS
set -eu
release_tag='preview-0.32'
expected_installer_sha256='{{INSTALL_SH_SHA256}}'
workdir=$(mktemp -d)
git -C "$workdir" init --quiet
git -C "$workdir" remote add origin https://github.com/arbiterForge/arbiter-academy.git
git -C "$workdir" fetch --depth 1 origin "refs/tags/$release_tag"
git -C "$workdir" show FETCH_HEAD:install/install.sh > "$workdir/install.sh"
actual_installer_sha256=$(python3 -c 'import hashlib, pathlib, sys; print(hashlib.sha256(pathlib.Path(sys.argv[1]).read_bytes()).hexdigest())' "$workdir/install.sh")
[ "$actual_installer_sha256" = "$expected_installer_sha256" ] || { printf '%s\n' 'installer digest did not match Preview 0.32' >&2; exit 1; }
sh "$workdir/install.sh"Linux
set -eu
release_tag='preview-0.32'
expected_installer_sha256='{{INSTALL_SH_SHA256}}'
workdir=$(mktemp -d)
git -C "$workdir" init --quiet
git -C "$workdir" remote add origin https://github.com/arbiterForge/arbiter-academy.git
git -C "$workdir" fetch --depth 1 origin "refs/tags/$release_tag"
git -C "$workdir" show FETCH_HEAD:install/install.sh > "$workdir/install.sh"
actual_installer_sha256=$(python3 -c 'import hashlib, pathlib, sys; print(hashlib.sha256(pathlib.Path(sys.argv[1]).read_bytes()).hexdigest())' "$workdir/install.sh")
[ "$actual_installer_sha256" = "$expected_installer_sha256" ] || { printf '%s\n' 'installer digest did not match Preview 0.32' >&2; exit 1; }
sh "$workdir/install.sh"Expected result: The installer reports the installed Academy preview and the path of the installed arbiter-academy executable.
If the tag fetch, extraction, or installation stops, do not substitute a branch or a different remote URL. Preserve the complete message and the temporary source folder, compare the linked immutable source, and ask in Academy Discussions before retrying.
Run the installed Academy Doctor command from the clone, read every reported boundary, and continue to F01 when any failures are limited to the expected fresh-clone remote findings.
Windows
$academy = "$env:LOCALAPPDATA\ArbiterAcademy\preview-0.32\Scripts\arbiter-academy.exe"
& $academy --repository (Get-Location).Path doctormacOS
academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.32/bin/arbiter-academy"
"$academy" --repository "$PWD" doctorLinux
academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.32/bin/arbiter-academy"
"$academy" --repository "$PWD" doctorExpected result: Doctor reports Python and Git versions, the repository root, worktree and branch state, remotes and effective push routing, upstream push protection, and codeArbiter activation and initialization without changing the repository.
If Doctor reports only missing upstream or related fresh-clone remote evidence, continue to F01. If origin is not your fork, main is dirty, or another prerequisite is unavailable, stop and correct only that setup boundary before Prepare.
Start with Foundation
Prove origin is your fork, upstream is the official Academy, and push routing cannot target upstream.
30 minutes · Practice in your own fork
Start F01Curriculum
Establish safe repository boundaries and learn the evidence-first delivery loop.
4 lessons · 105 minutes
Prove origin is your fork, upstream is the official Academy, and push routing cannot target upstream.
30 minutes
Bind a compact orientation record to the exact current context bytes and project stage.
25 minutes
Start the prepared docs task and co-locate its in-progress board transition with the bounded documentation correction.
20 minutes
Preserve a failing claimant-label regression in Git before a later minimal production repair.
30 minutes
Apply governed workflows to realistic features, fixes, reviews, and decisions.
8 lessons · 315 minutes
Deliver unresolved-ticket summary behavior through an approved spec, coverage-valid derived plan, sanctioned task transition, and test-before-code workflow.
45 minutes
Create a reviewed local work range, push it only to the prepared learner origin, and preserve an offline-local receipt in a separate commit.
60 minutes
Choose and record the Workshop Queue summary-format boundary in accepted ADR-0004 and its matching append-only decision-log entry.
35 minutes
Review python-dateutil 2.9.0.post0 against frozen evidence, select the bounded standard-library alternative for finite legacy date formats, and preserve a no-install rejection record.
35 minutes
Reproduce a genuine blocked-ticket summary defect and prove it with ordered test-only RED and code-only GREEN commits.
45 minutes
Repair one source-contradicted context claim through re-scout while preserving the prepared unrelated note byte-for-byte.
30 minutes
Produce one committed, target-bound STRIDE report for archive-import containment without changing the reviewed code.
35 minutes
Commit a complete live branch and worktree classification bound to prepared external identities without deleting or pruning anything.
30 minutes
Diagnose enforcement, tune governance, and operate advanced delivery paths with proof.
7 lessons · 290 minutes
Complete a bounded documentation sprint, preserve its durable decision evidence, and distinguish a human approval gate from the repository facts that Check can verify.
35 minutes
Observe one H-05 refusal, preserve the protected audit log, and commit a limited local observation note without claiming that the refusal chronology is proven.
25 minutes
Complete a behavior-preserving refactor, a docs-only chore, and a local annotated release without claiming a remote publication.
40 minutes
Compare the sanctioned project routes, commit each child through codeArbiter, and bind both committed repositories with a canonical report.
55 minutes
Preserve a real debug no-action close and a findings-only spike transfer, while stopping for a human conflict decision.
45 minutes
Produce a two-commit, read-only documentation preview packet and recognize when advanced codeArbiter surfaces do not belong in a training exercise.
30 minutes
Use the real codeArbiter feature lane to repair one known defect, preserve its local evidence, and open the resulting feature branch as a hosted pull request.
60 minutes
How practice works