These pages document master, which is unreleased and in development. The Quick Start installs the latest stable release; anything newer than that tag is marked in the text.
Headless harness recipes (#179)
Drive the enforced harness (CCT runtime loaded, all gates active) from
scripts, internal platforms, or CI — no TUI. Built on the surface this
harness has verified end-to-end: pi --mode json (the same mechanism
the T7.2 subagent runner uses in production).
One-shot enforced run
Section titled “One-shot enforced run”pi-code -- --mode json -p "Run the test suite and summarize failures" --no-sessionEverything after -- reaches pi unmodified; pi-code loads the CCT
enforcement runtime via --extension first, so permission rules,
protected paths, and audit apply to the headless run exactly as they do
interactively. Exit codes and signals are pi’s own (pi-code execs).
--no-session keeps one-shot runs from accumulating session state; drop
it if you want the run resumable.
Reading the result
Section titled “Reading the result”--mode json emits JSON lines; the final result envelope carries (the
T10.3 contract, the same fields the subagent runner parses):
{ "type": "result", "subtype": "success", "total_cost_usd": 0.0123, "session_id": "..." }out="$(pi-code -- --mode json -p "…" --no-session)" || { echo "run failed: $?"; exit 1; }# jq -e: exit nonzero when no envelope matched (missing envelope = error).echo "$out" | jq -e -r 'select(.type == "result") | "\(.subtype) cost=\(.total_cost_usd)"'A nonzero exit is a failed run regardless of any envelope (the T7.2 runner’s rule); also treat “no envelope in the output” as an error — that second rule is STRICTER than the runner, and recommended for CI.
Minimal CI job (GitHub Actions shape)
Section titled “Minimal CI job (GitHub Actions shape)”jobs: agent-task: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - uses: actions/setup-node@v4 with: { node-version: "22" } # setup.sh lives in the CCT repo — check it out alongside your # project (or vendor it) and run its adapter installer; it installs # the pi-code launcher into ~/.local/bin (on PATH in Actions). - name: Install pi + the CCT harness run: | npm install -g @earendil-works/pi-coding-agent git clone --depth 1 https://github.com/gosha70/code-copilot-team cct ./cct/adapters/pi/setup.sh - name: Enforced headless run shell: bash # bash -eo pipefail: a nonzero pi exit fails the step even through the pipe env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} TASK_PROMPT: ${{ inputs.task }} run: | pi-code -- --mode json -p "$TASK_PROMPT" --no-session | tee run.jsonl jq -e 'select(.type=="result") | .subtype == "success"' run.jsonl > /dev/nullFor unattended postures (ask-resolution, sandbox requirements) see
unattended-runs.md; for worker isolation use
pi-code worktree run (worktree-workers.md).
About pi --mode rpc
Section titled “About pi --mode rpc”pi also ships an RPC mode (docs/rpc.md in the pi package) for
long-lived, bidirectional programmatic control. This harness has not
exercised it — the recipes above are the CCT-verified path. If you adopt
RPC mode directly, you are on pi’s contract, not this harness’s; the CCT
runtime still loads via --extension, but none of the harness’s headless
semantics documented here (envelope parsing, exit-code rules) have been
validated against it.
Guardrails in headless runs
Section titled “Guardrails in headless runs”The extension template
composes with headless runs: auto-discovery applies when the project is
trusted in the headless environment; otherwise pass a pinned, absolute
--extension path you control (see the template README’s security note
about explicit paths bypassing the trust gate — in CI, the pinned path is
the appropriate form). The template’s gates cover Pi’s write/edit
tools only — they are not a filesystem boundary, which is exactly why the
CI validation step above remains the authoritative gate.