Skip to content

Orient to live governance state

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.

  1. You

    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 this matters: Prepare isolates the exercise on a numbered attempt branch and preserves main.

    Windows

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

    macOS

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

    Linux

    academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.32/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.

    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.

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

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

    Windows

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

    macOS

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

    Linux

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

    Windows · Claude Code

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

    macOS · Claude Code

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

    Linux · Claude Code

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

    Windows · Codex

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

    macOS · Codex

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

    Linux · Codex

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

    Windows · Pi

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

    macOS · Pi

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

    Linux · Pi

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

    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.

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.

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

    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') })

    macOS

    shasum -a 256 .codearbiter/CONTEXT.md

    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.

    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.

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

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

    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

    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.

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

    Windows

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

    macOS

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

    Linux

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

    Windows · Claude Code

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

    macOS · Claude Code

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

    Linux · Claude Code

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

    Windows · Codex

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

    macOS · Codex

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

    Linux · Codex

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

    Windows · Pi

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

    macOS · Pi

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

    Linux · Pi

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

    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.

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

    Windows

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

    macOS

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

    Linux

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

    Windows · Claude Code

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

    macOS · Claude Code

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

    Linux · Claude Code

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

    Windows · Codex

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

    macOS · Codex

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

    Linux · Codex

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

    Windows · Pi

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

    macOS · Pi

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

    Linux · Pi

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

    Expected result

    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.

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

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

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

  1. You

    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 this matters: External verification proves the report matches the preserved context and exact commit boundary.

    Windows

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

    macOS

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

    Linux

    academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.32/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.

    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.

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

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

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

  1. You

    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 this matters: Leaving the completed attempt untouched preserves its evidence for audit and 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 leaves academy/F02-orient-to-state/ATTEMPT_NUMBER reachable.

    Evidence

    The completed evidence remains separated 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 another attempt is needed. In the native terminal, run the installed Academy Reset command for F02.

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

    Windows

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

    macOS

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

    Linux

    academy="${XDG_DATA_HOME:-$HOME/.local/share}/arbiter-academy/preview-0.32/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.

    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.