Complete F01 first and begin from the same arbiter-academy fork and clone. Before Prepare, switch
to main and confirm the clone is clean. Keep two surfaces open at the repository root: a native
terminal for installed Academy and shell commands, and your Claude Code, Codex, or Pi harness for
codeArbiter commands and learner approvals.
This page labels every command with its actor and surface. A native-terminal command is entered
directly in PowerShell or your shell and therefore has no !. A harness shell command begins with
exactly one !. A codeArbiter command is handled by the active harness and never begins with !.
You do not need to know how to construct JSON, calculate a digest, or choose a Git commit boundary
before starting; the actions below provide those exact steps.
You will read the live repository state from its tracked source, follow the source links, and bind
one four-field orientation report to the exact context bytes you inspected. The evidence report
contains only schema_version, context_path, context_sha256, and stage. You will stage only
that report, approve only that boundary, let codeArbiter commit it, and pass the external Academy
Check with no uncommitted work.
The status screen helps you navigate. It is not the evidence source. The tracked
.codearbiter/CONTEXT.md bytes and the files linked from that document are the source.
In the native terminal opened at your arbiter-academy clone, run the installed Academy Prepare command for your operating system. Begin only from a clean main branch.
Why this matters: Prepare isolates the exercise on a numbered attempt branch and preserves main.
Academy prints a prepared branch named academy/F02-orient-to-state/ATTEMPT_NUMBER and switches the repository to it.
Evidence
The numbered branch records the exact starting context for this attempt.
If that does not happen
If Prepare stops, preserve its message. Return to Recovery for the named dirty-worktree, wrong-branch, or prerequisite condition before retrying.
ATTEMPT_NUMBER in a branch name means the number Academy prints, such as 1. Do not type the
words or angle brackets literally. Stay on that numbered branch until Check passes.
2
Your host
Ask codeArbiter for live status
In your active codeArbiter harness, ask the agent to invoke Status using the command for that host. These are codeArbiter commands, not shell commands, so they never begin with an exclamation mark.
Why this matters: Status is the entry point to the repository-owned governance state you will verify against source files.
Any OS · Claude Code
/ca:status
Any OS · Codex
$ca-status
Any OS · Pi
/ca-status
Any OS · Pi
/skill:ca-status
Expected result
Status identifies an enabled stage-2 Workshop Queue repository and points you to its current tasks, questions, decisions, plans, and governing context.
Evidence
You have a host-generated summary to compare with the tracked state rather than relying on memory.
If that does not happen
If Status reports disabled state, the wrong project, or another stage, stop. Confirm the active harness and native terminal are both opened at the prepared arbiter-academy clone before trying again.
Compare the Status summary with the tracked files instead of accepting either from memory.
3
You
Read the tracked context file
Print .codearbiter/CONTEXT.md from either the native terminal or your selected harness. Read the front matter and every section; a harness shell command begins with exactly one exclamation mark.
Why this matters: The tracked file, not the status summary, defines the current project identity and boundaries.
The file names Workshop Queue, declares arbiter enabled and stage 2, defines its local-first scope, and lists five governing artifacts.
Evidence
You can distinguish the tracked context source from the host-generated Status summary.
If that does not happen
If the file is missing or names another project, stop. Return to the prepared Academy clone and do not create a replacement context file.
4
You
Follow every governing link
Paste the matching prompt into the active codeArbiter harness. This is a request to your agent, not a terminal command; it never begins with an exclamation mark.
Why this matters: CONTEXT.md is a map; the linked artifacts contain the active requirements, work, decisions, and verification commands.
Any OS · Claude Code
Open each file in order, then give this four-item orientation report: the queued task ID, both ADR decisions, the verification command, and the local-only data boundary. Read these files in order: .codearbiter/specs/ticket-assignment.md, .codearbiter/plans/ticket-assignment.md, .codearbiter/decisions/0001-json-storage-boundary.md, .codearbiter/decisions/0002-explicit-ticket-state-machine.md, .codearbiter/coding-standards.md, .codearbiter/tech-stack.md, .codearbiter/security-controls.md, .codearbiter/open-tasks.md, and .codearbiter/open-questions.md.
Any OS · Codex
Open each file in order, then give this four-item orientation report: the queued task ID, both ADR decisions, the verification command, and the local-only data boundary. Read these files in order: .codearbiter/specs/ticket-assignment.md, .codearbiter/plans/ticket-assignment.md, .codearbiter/decisions/0001-json-storage-boundary.md, .codearbiter/decisions/0002-explicit-ticket-state-machine.md, .codearbiter/coding-standards.md, .codearbiter/tech-stack.md, .codearbiter/security-controls.md, .codearbiter/open-tasks.md, and .codearbiter/open-questions.md.
Any OS · Pi
Open each file in order, then give this four-item orientation report: the queued task ID, both ADR decisions, the verification command, and the local-only data boundary. Read these files in order: .codearbiter/specs/ticket-assignment.md, .codearbiter/plans/ticket-assignment.md, .codearbiter/decisions/0001-json-storage-boundary.md, .codearbiter/decisions/0002-explicit-ticket-state-machine.md, .codearbiter/coding-standards.md, .codearbiter/tech-stack.md, .codearbiter/security-controls.md, .codearbiter/open-tasks.md, and .codearbiter/open-questions.md.
Expected result
You can name the current queued task, the two recorded architecture decisions, the verification command, and the local-only data boundary from the linked files.
Evidence
Your orientation covers the source graph behind Status, not only its first screen.
If that does not happen
If a relative link does not resolve, start from .codearbiter/CONTEXT.md and join the link to the .codearbiter directory. Do not search for a similarly named file elsewhere.
The linked sources answer different questions: specifications and plans define intended work,
ADRs preserve architecture choices, standards and security controls constrain changes, and the
task and question boards show work that is still open.
5
You
Hash the exact context bytes
Use the native terminal command for your operating system. Hash the file bytes directly; do not copy the text into an editor or normalize its line endings first.
Why this matters: The digest binds your report to the exact tracked context you inspected.
The command prints a 64-character lowercase hexadecimal SHA-256 digest; macOS and Linux also print .codearbiter/CONTEXT.md after the digest.
Evidence
The digest is computed from raw bytes and can be independently reproduced.
If that does not happen
If hashing reports a missing file, return to the repository root. If the digest changes between runs, stop and inspect git status before creating evidence.
6
You
Create the four-field orientation record
Run the complete native-terminal command for your operating system. It reads stage and SHA-256 from the same context bytes, creates the report directory, and writes UTF-8 JSON without a byte-order mark. Do not hand-edit the digest or stage.
Why this matters: Generating all four fields from one byte snapshot prevents a stale or mixed orientation record.
python3 - <<'PY'
from pathlib import Path
import hashlib
import json
import re
context_path = '.codearbiter/CONTEXT.md'
context = Path(context_path).read_bytes()
match = re.search(r'(?m)^stage:\s*(\d+)\s*$', context.decode('utf-8'))
if match is None:
raise SystemExit('CONTEXT.md has no integer stage')
payload = {'schema_version': 1, 'context_path': context_path, 'context_sha256': hashlib.sha256(context).hexdigest(), 'stage': int(match.group(1))}
report = Path('.codearbiter/reports/academy/F02-orientation.json')
report.parent.mkdir(parents=True, exist_ok=True)
report.write_text(json.dumps(payload, indent=2) + '\n', encoding='utf-8', newline='\n')
PY
Linux
python3 - <<'PY'
from pathlib import Path
import hashlib
import json
import re
context_path = '.codearbiter/CONTEXT.md'
context = Path(context_path).read_bytes()
match = re.search(r'(?m)^stage:\s*(\d+)\s*$', context.decode('utf-8'))
if match is None:
raise SystemExit('CONTEXT.md has no integer stage')
payload = {'schema_version': 1, 'context_path': context_path, 'context_sha256': hashlib.sha256(context).hexdigest(), 'stage': int(match.group(1))}
report = Path('.codearbiter/reports/academy/F02-orientation.json')
report.parent.mkdir(parents=True, exist_ok=True)
report.write_text(json.dumps(payload, indent=2) + '\n', encoding='utf-8', newline='\n')
PY
Expected result
The command creates .codearbiter/reports/academy/F02-orientation.json with exactly schema_version 1, context_path .codearbiter/CONTEXT.md, a 64-character context_sha256, and integer stage 2.
Evidence
The report contains only the four checkpoint fields and no machine, account, URL, credential, or transcript data.
If that does not happen
If the command stops, preserve its message. Confirm you are in the repository root and CONTEXT.md still contains an integer stage; do not create a partial report by hand.
The creation action reads one byte snapshot and derives both stage and context_sha256 from it.
That prevents a digest copied from one version of the file being paired with a stage copied from
another. The report must not contain your username, local path, email, remote URL, credential, or
terminal transcript.
7
You
Inspect the generated JSON
Parse and print the report from either the native terminal or your selected harness. Confirm the four field names and values before staging anything.
Why this matters: A parser catches malformed JSON while visual inspection catches the wrong path, stage, or digest source.
The parser succeeds and displays exactly schema_version, context_path, context_sha256, and stage with no extra field.
Evidence
You reviewed the same report file that will be staged.
If that does not happen
If parsing fails or a field is wrong, delete only the uncommitted report, confirm CONTEXT.md is unchanged, and repeat the creation action.
8
You
Stage only the orientation report
Stage the one report path from either the native terminal or your selected harness. The double dash ends Git option parsing; the path after it is the entire intended commit boundary.
Why this matters: Path-scoped staging keeps unrelated work outside the governed evidence commit.
Git stages .codearbiter/reports/academy/F02-orientation.json without printing output.
Evidence
The index contains the intended report path and no intentional unrelated path.
If that does not happen
If Git reports another problem, preserve the report and inspect status. Do not stage all files or use a force option.
9
You
Review the one-file commit boundary
Paste the matching prompt into the active codeArbiter harness. This is a request to your agent, not a terminal command; it never begins with an exclamation mark.
Why this matters: The learner approves the exact staged change before codeArbiter creates durable evidence.
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/F02-orientation.json and whether the diff contains exactly schema_version, context_path, context_sha256, and stage.
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/F02-orientation.json and whether the diff contains exactly schema_version, context_path, context_sha256, and stage.
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/F02-orientation.json and whether the diff contains exactly schema_version, context_path, context_sha256, and stage.
Expected result
The agent presents one staged report, no context edit, and no unrelated file for your approval.
Evidence
Your approval is bounded to the orientation report rather than the whole worktree.
If that does not happen
If another path appears, do not approve. Ask the agent to preserve and unstage only the unrelated path, then review the boundary again.
10
Your host
Let the agent commit through codeArbiter
After the learner approves the staged boundary, invoke the host-native codeArbiter commit gate. Do not use a shell exclamation mark and do not replace this with git commit.
Why this matters: The commit gate verifies and records the approved evidence 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 learner commit whose only changed path is .codearbiter/reports/academy/F02-orientation.json.
Evidence
The attempt branch now contains one reconstructable orientation commit.
If that does not happen
If the gate blocks, preserve the finding and correct that boundary. Do not bypass it, commit directly, amend a different attempt, or add another file.
11
You
Confirm the committed attempt is clean
After the evidence commit, inspect short status from either the native terminal or your selected harness.
Why this matters: External Check accepts only committed evidence in a clean worktree and index.
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 head.
If that does not happen
If Git prints a path, preserve the orientation commit. Resolve or safely preserve only that uncommitted path before Check; do not reset the committed attempt.
The attempt contains exactly one learner commit after Prepare. That commit adds only
.codearbiter/reports/academy/F02-orientation.json. The tracked context at the attempt head is
byte-for-byte identical to the context at Prepare, the report has exactly four fields, and
git status --short prints nothing.
The digest is not a secret and does not summarize the text for a human. It is a reproducible claim:
someone else can hash the preserved context bytes and prove that they are the same bytes you read.
Check prints checkpoint F02-orient-to-state: passed; progress: .academy/progress.json.
Evidence
Only a passing external Check records F02 progress.
If that does not happen
If Check fails, preserve the clean committed attempt and read the named predicate. Use Reset for a new numbered attempt rather than rewriting committed evidence.
A pass contains checkpoint F02-orient-to-state: passed; progress: .academy/progress.json.
Check reads the committed report, the prepared and current context blobs, the commit path list, and
the live worktree. A correct-looking uncommitted file does not pass, and neither does a report
committed beside another file.
If Check fails, preserve the attempt and read the failed predicate. A wrong field, changed context,
extra commit path, additional learner commit, or dirty worktree has a different recovery. Do not
hide the evidence by force-resetting or amending it; use a numbered retry when the attempt boundary
is no longer exact.
Academy preserves the previous attempt under an archive ref and prints the next academy/F02-orient-to-state/ATTEMPT_NUMBER branch.
Evidence
The failed attempt stays reachable while the retry 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 and keep the completed attempt branch intact. Continue with F03,
then F04. An Academy lesson appears on the course home only after its guided rewrite; unpublished
source exercises are not a substitute for the accepted course.
Status is advisory orientation generated for the current host. The repository files are durable
state. The report connects those layers without copying a transcript: its canonical path tells the
verifier what was read, its raw-byte digest identifies the exact version, and its integer stage
records the active maturity boundary.
The verifier also protects the shape of the attempt. It compares the prepared context blob with the
attempt head, requires one post-Prepare learner commit containing only the report, and requires a
clean worktree. That makes the lesson reconstructable later: the claim, source bytes, commit
boundary, and external verdict all agree.