Preview 0.30

F02 — Orient to live governance state

Know before you begin

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.

What you will prove

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.

Prepare safely

Prepare a numbered orientation attempt

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

Prepare isolates the exercise on a numbered attempt branch and preserves main.

You · Native terminal · Windows

$academy = "$env:LOCALAPPDATA\ArbiterAcademy\preview-0.30\Scripts\arbiter-academy.exe"
& $academy --repository (Get-Location).Path prepare F02-orient-to-state

You · Native terminal · macOS

academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.30/bin/arbiter-academy"
"$academy" --repository "$PWD" prepare F02-orient-to-state

You · Native terminal · Linux

academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.30/bin/arbiter-academy"
"$academy" --repository "$PWD" prepare F02-orient-to-state

Expected result

Academy prints a prepared branch named academy/F02-orient-to-state/ATTEMPT_NUMBER and switches the repository to it.

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.

Evidence

The numbered branch records the exact starting context for this attempt.

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.

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

Status is the entry point to the repository-owned governance state you will verify against source files.

Your agent · Claude Code harness · All operating systems

/ca:status

Your agent · Codex harness · All operating systems

$ca-status

Your agent · Pi harness · All operating systems

/ca-status

Your agent · Pi harness · All operating systems

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

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.

Evidence

You have a host-generated summary to compare with the tracked state rather than relying on memory.

Practice

Compare the Status summary with the tracked files instead of accepting either from memory.

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

The tracked file, not the status summary, defines the current project identity and boundaries.

You · Native terminal · Windows

Get-Content -LiteralPath '.codearbiter/CONTEXT.md'

You · Native terminal · macOS

sed -n '1,220p' .codearbiter/CONTEXT.md

You · Native terminal · Linux

sed -n '1,220p' .codearbiter/CONTEXT.md

You · Claude Code harness · Windows

!Get-Content -LiteralPath '.codearbiter/CONTEXT.md'

You · Claude Code harness · macOS

!sed -n '1,220p' .codearbiter/CONTEXT.md

You · Claude Code harness · Linux

!sed -n '1,220p' .codearbiter/CONTEXT.md

You · Codex harness · Windows

!Get-Content -LiteralPath '.codearbiter/CONTEXT.md'

You · Codex harness · macOS

!sed -n '1,220p' .codearbiter/CONTEXT.md

You · Codex harness · Linux

!sed -n '1,220p' .codearbiter/CONTEXT.md

You · Pi harness · Windows

!Get-Content -LiteralPath '.codearbiter/CONTEXT.md'

You · Pi harness · macOS

!sed -n '1,220p' .codearbiter/CONTEXT.md

You · Pi harness · Linux

!sed -n '1,220p' .codearbiter/CONTEXT.md

Expected result

The file names Workshop Queue, declares arbiter enabled and stage 2, defines its local-first scope, and lists five governing artifacts.

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.

Evidence

You can distinguish the tracked context source from the host-generated Status summary.

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

CONTEXT.md is a map; the linked artifacts contain the active requirements, work, decisions, and verification commands.

You · Claude Code harness · All operating systems

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.

You · Codex harness · All operating systems

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.

You · Pi harness · All operating systems

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.

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.

Evidence

Your orientation covers the source graph behind Status, not only its first screen.

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.

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

The digest binds your report to the exact tracked context you inspected.

You · Native terminal · Windows

$contextBytes = [IO.File]::ReadAllBytes('.codearbiter/CONTEXT.md')
$sha256 = [Security.Cryptography.SHA256]::Create()
try { $contextHash = $sha256.ComputeHash($contextBytes) } finally { $sha256.Dispose() }
-join ($contextHash | ForEach-Object { $_.ToString('x2') })

You · Native terminal · macOS

shasum -a 256 .codearbiter/CONTEXT.md

You · Native terminal · Linux

sha256sum .codearbiter/CONTEXT.md

Expected result

The command prints a 64-character lowercase hexadecimal SHA-256 digest; macOS and Linux also print .codearbiter/CONTEXT.md after the digest.

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.

Evidence

The digest is computed from raw bytes and can be independently reproduced.

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

Generating all four fields from one byte snapshot prevents a stale or mixed orientation record.

You · Native terminal · Windows

$contextPath = '.codearbiter/CONTEXT.md'
$contextBytes = [IO.File]::ReadAllBytes($contextPath)
$contextText = [Text.UTF8Encoding]::new($false, $true).GetString($contextBytes)
$stageMatch = [regex]::Match($contextText, '(?m)^stage:\s*(\d+)\s*$')
if (-not $stageMatch.Success) { throw 'CONTEXT.md has no integer stage' }
$sha256 = [Security.Cryptography.SHA256]::Create()
try { $contextHash = $sha256.ComputeHash($contextBytes) } finally { $sha256.Dispose() }
$contextDigest = -join ($contextHash | ForEach-Object { $_.ToString('x2') })
$payload = [ordered]@{ schema_version = 1; context_path = $contextPath; context_sha256 = $contextDigest; stage = [int]$stageMatch.Groups[1].Value }
$reportPath = '.codearbiter/reports/academy/F02-orientation.json'
New-Item -ItemType Directory -Path (Split-Path $reportPath) -Force | Out-Null
[IO.File]::WriteAllText($reportPath, (($payload | ConvertTo-Json) + [Environment]::NewLine), [Text.UTF8Encoding]::new($false))

You · Native terminal · macOS

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

You · Native terminal · 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.

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.

Evidence

The report contains only the four checkpoint fields and no machine, account, URL, credential, or transcript data.

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.

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

A parser catches malformed JSON while visual inspection catches the wrong path, stage, or digest source.

You · Native terminal · Windows

Get-Content -Raw -LiteralPath '.codearbiter/reports/academy/F02-orientation.json' | ConvertFrom-Json | Format-List

You · Native terminal · macOS

python3 -m json.tool .codearbiter/reports/academy/F02-orientation.json

You · Native terminal · Linux

python3 -m json.tool .codearbiter/reports/academy/F02-orientation.json

You · Claude Code harness · Windows

!Get-Content -Raw -LiteralPath '.codearbiter/reports/academy/F02-orientation.json' | ConvertFrom-Json | Format-List

You · Claude Code harness · macOS

!python3 -m json.tool .codearbiter/reports/academy/F02-orientation.json

You · Claude Code harness · Linux

!python3 -m json.tool .codearbiter/reports/academy/F02-orientation.json

You · Codex harness · Windows

!Get-Content -Raw -LiteralPath '.codearbiter/reports/academy/F02-orientation.json' | ConvertFrom-Json | Format-List

You · Codex harness · macOS

!python3 -m json.tool .codearbiter/reports/academy/F02-orientation.json

You · Codex harness · Linux

!python3 -m json.tool .codearbiter/reports/academy/F02-orientation.json

You · Pi harness · Windows

!Get-Content -Raw -LiteralPath '.codearbiter/reports/academy/F02-orientation.json' | ConvertFrom-Json | Format-List

You · Pi harness · macOS

!python3 -m json.tool .codearbiter/reports/academy/F02-orientation.json

You · Pi harness · Linux

!python3 -m json.tool .codearbiter/reports/academy/F02-orientation.json

Expected result

The parser succeeds and displays exactly schema_version, context_path, context_sha256, and stage with no extra field.

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.

Evidence

You reviewed the same report file that will be staged.

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

Path-scoped staging keeps unrelated work outside the governed evidence commit.

You · Native terminal · Windows

git add -- .codearbiter/reports/academy/F02-orientation.json

You · Native terminal · macOS

git add -- .codearbiter/reports/academy/F02-orientation.json

You · Native terminal · Linux

git add -- .codearbiter/reports/academy/F02-orientation.json

You · Claude Code harness · Windows

!git add -- .codearbiter/reports/academy/F02-orientation.json

You · Claude Code harness · macOS

!git add -- .codearbiter/reports/academy/F02-orientation.json

You · Claude Code harness · Linux

!git add -- .codearbiter/reports/academy/F02-orientation.json

You · Codex harness · Windows

!git add -- .codearbiter/reports/academy/F02-orientation.json

You · Codex harness · macOS

!git add -- .codearbiter/reports/academy/F02-orientation.json

You · Codex harness · Linux

!git add -- .codearbiter/reports/academy/F02-orientation.json

You · Pi harness · Windows

!git add -- .codearbiter/reports/academy/F02-orientation.json

You · Pi harness · macOS

!git add -- .codearbiter/reports/academy/F02-orientation.json

You · Pi harness · Linux

!git add -- .codearbiter/reports/academy/F02-orientation.json

Expected result

Git stages .codearbiter/reports/academy/F02-orientation.json without printing output.

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.

Evidence

The index contains the intended report path and no intentional unrelated path.

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

The learner approves the exact staged change before CodeArbiter creates durable evidence.

You · Claude Code harness · All operating systems

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.

You · Codex harness · All operating systems

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.

You · Pi harness · All operating systems

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.

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.

Evidence

Your approval is bounded to the orientation report rather than the whole worktree.

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

The commit gate verifies and records the approved evidence boundary.

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

Expected result

CodeArbiter creates one learner commit whose only changed path is .codearbiter/reports/academy/F02-orientation.json.

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.

Evidence

The attempt branch now contains one reconstructable orientation commit.

Confirm the committed attempt is clean

After the evidence commit, inspect short status from either the native terminal or your selected harness.

Why

External Check accepts only committed evidence in a clean worktree and index.

You · Native terminal · Windows

git status --short

You · Native terminal · macOS

git status --short

You · Native terminal · Linux

git status --short

You · Claude Code harness · Windows

!git status --short

You · Claude Code harness · macOS

!git status --short

You · Claude Code harness · Linux

!git status --short

You · Codex harness · Windows

!git status --short

You · Codex harness · macOS

!git status --short

You · Codex harness · Linux

!git status --short

You · Pi harness · Windows

!git status --short

You · Pi harness · macOS

!git status --short

You · Pi harness · Linux

!git status --short

Expected result

Git prints nothing.

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.

Evidence

The worktree and index match the committed attempt head.

Recognize success

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

Run the external Academy Check

In the native terminal, run the installed Academy Check command for F02. It verifies committed Git state from outside the learner checkout.

Why

External verification proves the report matches the preserved context and exact commit boundary.

You · Native terminal · Windows

$academy = "$env:LOCALAPPDATA\ArbiterAcademy\preview-0.30\Scripts\arbiter-academy.exe"
& $academy --repository (Get-Location).Path check F02-orient-to-state

You · Native terminal · macOS

academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.30/bin/arbiter-academy"
"$academy" --repository "$PWD" check F02-orient-to-state

You · Native terminal · Linux

academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.30/bin/arbiter-academy"
"$academy" --repository "$PWD" check F02-orient-to-state

Expected result

Check prints checkpoint F02-orient-to-state: passed; progress: .academy/progress.json.

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.

Evidence

Only a passing external Check records F02 progress.

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.

Recover or continue

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.

Hint 1

Start with the arbiter and stage front-matter fields, then read the project identity, scope, and every linked governing artifact.

Hint 2

Hash .codearbiter/CONTEXT.md as bytes. Do not hash copied Status output, rendered website prose, or text saved through an editor.

Hint 3

The final commit changes one path. If anything else is staged, committed, or left uncommitted, stop before Check and preserve that state for recovery.

Return to main after success

After Check passes, switch back to main from either the native terminal or your selected harness. The completed numbered branch remains available.

Why

Leaving the completed attempt untouched preserves its evidence for audit and review.

You · Native terminal · Windows

git switch main

You · Native terminal · macOS

git switch main

You · Native terminal · Linux

git switch main

You · Claude Code harness · Windows

!git switch main

You · Claude Code harness · macOS

!git switch main

You · Claude Code harness · Linux

!git switch main

You · Codex harness · Windows

!git switch main

You · Codex harness · macOS

!git switch main

You · Codex harness · Linux

!git switch main

You · Pi harness · Windows

!git switch main

You · Pi harness · macOS

!git switch main

You · Pi harness · Linux

!git switch main

Expected result

Git switches to main and leaves academy/F02-orient-to-state/ATTEMPT_NUMBER reachable.

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.

Evidence

The completed evidence remains separated from main.

Create a preserved numbered retry

Use this only when another attempt is needed. In the native terminal, run the installed Academy Reset command for F02.

Why

Reset archives the current attempt and prepares the next unused number without erasing evidence.

You · Native terminal · Windows

$academy = "$env:LOCALAPPDATA\ArbiterAcademy\preview-0.30\Scripts\arbiter-academy.exe"
& $academy --repository (Get-Location).Path reset F02-orient-to-state

You · Native terminal · macOS

academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.30/bin/arbiter-academy"
"$academy" --repository "$PWD" reset F02-orient-to-state

You · Native terminal · Linux

academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.30/bin/arbiter-academy"
"$academy" --repository "$PWD" reset F02-orient-to-state

Expected result

Academy preserves the previous attempt under an archive ref and prints the next academy/F02-orient-to-state/ATTEMPT_NUMBER branch.

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.

Evidence

The failed attempt stays reachable while the retry starts from the clean lesson base.

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.

Understand the mechanism

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.

Next step

Continue with F03-work-the-board.

Recovery guidance