pair-capability-setup-harness
Configures an agent harness (pi, opencode, Claude Code) to execute pair's process: resolves the harness explicitly (never inferred), verifies its fitness against the project's declared harness/access-
SKILL.md.claude/skills/pair-capability-setup-harness/SKILL.md
GitHub/pair-capability-setup-harness — Agent Harness Configuration
Configure an agent harness so it becomes a valid environment for pair's process. Reads the agent-harness framework and adoption/tech/automation.md's Harness/Model Policy declarations, verifies the requested harness is fit before touching any configuration, then provisions it. Shaped after /pair-capability-setup-pm and /pair-capability-setup-gates: read adoption → verify → provision → idempotent → HITL.
Arguments
| Argument | Required | Description |
|---|---|---|
$harness |
No | Harness to configure: pi, opencode, or claude-code. If omitted, the developer is asked. Never inferred from environment variables, present binaries, or filesystem markers — see Step 1. |
Composed Skills
| Skill | Type | Required |
|---|---|---|
/pair-capability-record-decision |
Capability | Optional — only if provisioning surfaces a decision worth recording (e.g. a project's first tech/automation.md Harness declaration). Most runs provision without one. |
Algorithm
Step 1: Resolve the Harness — Ask, Never Infer
Check: Is
$harnessprovided and one ofpi,opencode,claude-code?Skip: If valid, proceed to Step 2 with that harness.
Act: If
$harnessis omitted, ask the developer directly:Which harness do you want to configure?
Harness Guide pi pi.md — no MCP by design opencode opencode.md — MCP-native, has a headless server claude-code claude-code.md — claude -pandWorkflowas two layersAct: If
$harnessis provided but unrecognized, or names a harness with no guide in the framework → HALT:$harness: [value]has no guide in the agent-harness framework. Available:pi,opencode,claude-code. To add one: one new markdown file attechnical-standards/ai-development/agent-harness/<name>.md, following the fixed nine-section index — zero code.Verify: Exactly one harness resolved, by explicit argument or by direct question. Never by detecting a binary on
PATH, an environment variable, or a filesystem marker — a fragile, harness-specific heuristic this skill deliberately does not implement (decision recorded during story #450's refinement).
Step 2: Read the Project's Declared Requirements
Act: Read
adoption/tech/automation.md. Does it exist, and does it carry a## Harnesssection (see automation-policy.md)?Skip (absent file, or present with no
## Harnessheading): Zero-configuration path — every harness in the framework is presumed supported, and no declared access-path requirement exists to check against. Proceed to Step 3.Act (present): Parse the comma-separated harness list. Is the resolved harness (Step 1) in it?
Not in the list → HALT before any write:
$harness: [value]is not among this project's supported harnesses (tech/automation.md→## Harnessdeclares: [list]). Add it there first if this project should support it, or choose one of the declared harnesses.
Act: Does the
## Harnesssection carry a second line,Requires: <access-path>(see automation-policy.md)? This is the only source of an access-path requirement — never inferred from the project's tooling, way-of-working, or any other file.No
Requires:line → nothing to check; skip to Step 3. A project that never declared a requirement has none, by construction — not an unchecked gap.Requires:declared, and the resolved harness cannot satisfy it (today, the only case the framework defines:Requires: mcpandpi— which has none by design — is the one requested) → HALT before any write, naming the precise gap:pihas no MCP access path (by design — see pi.md § Access Paths), andtech/automation.mddeclaresRequires: mcp. Either use a harness with MCP (opencode,claude-code), or resolve the requirement through pi's CLI-first path (see the agent-harness framework § CLI-First).
Verify: The resolved harness is either confirmed fit (declared and access-path-compatible, or nothing declared at all) or the skill has already HALTed — no configuration write has happened yet at this point, in either outcome.
Step 3: Verify the Harness Is Actually There
Act: Check whether the resolved harness's binary/CLI is present and runnable (e.g.
pi --version,opencode --version,claude --version) — every spawn with stdin closed (pi -pwith an open stdin hangs, observed in #503's probe).Act (not installed,
opencode/claude-code) → HALT, stated as an environment fact, not a project error:[harness]is not installed on this machine. This is an environment gap, not a configuration issue — install it first (see the harness's own install instructions; this KB describes what pair needs from it, not how to install it), then re-run.Act (
pi— install or verify; this branch runs standalone, forpionly, long after pair was installed, and is the only harness this skill ever installs):piabsent ⇒ propose the install command from pi.md § 9 Setup and run it only on an explicit yes; on no, stop with the Step 3.2 message. Nothing is installed without that yes.pipresent ⇒ readpi --versionand compare it with the minimum pi.md § 9 states (0.86.1, required bypi-subagents' dynamic tool activation):- older than
0.86.1⇒ propose the update command from pi.md § 9 Setup (again, run only on yes); declined ⇒ continue, reporting the version as below the minimum for the in-pi cycle; - at or above it ⇒ confirmed, nothing written.
- older than
- An install or update that fails (no network, registry refused) ⇒ report the command's own error and stop — npm installs a global package atomically, so there is no half-installed state to clean; never retry silently, never fall back to another install path.
Verify: The harness binary responds (and, for
pi, its version was reported against the minimum). Proceed to Step 4 only once confirmed present.
Step 3b: pi-subagents — Only on Request (pi only)
Check: Did the developer ask for
pi-subagents(the package the in-pi delivery cycle dispatches its stages through)? It is set up only when the developer asks for it — never as part of a plainpisetup, never inferred.Skip: Not asked ⇒ go to Step 4.
Act: Read the pin and the current install from the bridge the cycle uses, so both speak one version:
node "$SKILL_DIR/../workflow-cycle/scripts/pi-bridge.mjs" pin node "$SKILL_DIR/../workflow-cycle/scripts/pi-bridge.mjs" probe --project "$PWD"missing⇒ ask global or project-local (never chosen silently), then propose the matching install line the probe printed (install.user/install.project) and run it only on yes. For project-local, explain the project-trust step first: pi does not load packages of an untrusted project, so the package stays inert until this project is trusted (Step 5.5).pinned⇒ confirmed, nothing written.drift⇒ report both versions and propose aligning to the pin with the same install line; declined ⇒ leave it, reporting the version as unverified.- A failed install ⇒ the command's own error, reported; nothing retried.
Verify: Re-run
probe:pinnedafter a yes. Report the pinned version as theverifiedAgainstpi.md § 9 records forpi-subagents— the bridge's pin and that line are kept equal by a test, so this skill reads them and never edits the KB.
Step 4: Verify Authentication — Report, Never Touch
- Act: Following the resolved harness's guide § Authentication, check whether a usable credential is resolvable (an expected env var is set, or the harness's own auth-check command reports readiness — e.g.
pi auth check,opencode auth list,claude's own login state). Never read, print, store, or transmit the credential's value — check readiness only, the way the harness's own tooling reports it. - Act (no usable credential found): Report which auth path is missing and how to obtain it, quoting the guide's own § Authentication section, and state plainly whether the missing path is CI-viable (API key) or local-interactive-only (OAuth subscription — never presented as a CI option).
- Check: Is authentication required to complete provisioning (Step 5), or can provisioning proceed and the auth gap be reported alongside a successful configuration?
- Config/skill-path/context provisioning (Step 5, points 1–3) does not require a working credential — proceed with those regardless.
- Model-provider provisioning (Step 5, point 4) requires a resolvable credential path — if none exists, report the gap and continue with the rest of provisioning; do not HALT the whole run over an auth gap that provisioning can partially complete around.
- Verify: Either a usable auth path was confirmed present (existence only, never its value), or its absence was reported with an actionable next step — and in neither case did the skill touch a credential.
Step 5: Provision
For the resolved, fitness-checked, present harness:
- Config file — per the guide's § Config File Locations, confirm (or, for a genuinely new/never-configured harness, create) the project-local config file at its documented path. Never touch the global/credential files (§ Authentication).
- Skill paths — per the guide's § Skill-Path Declaration: for harnesses that already discover pair's skills with no wiring (pi, opencode — confirmed in their guides), verify discovery works (the project's
.agents/skills/or.claude/skills/is reachable from the harness's search paths) rather than writing anything. Only write a skill-path entry when the guide documents one as required (e.g. pointing at another harness's directory). - Context — per the guide's § Project Context Loading: nothing to provision for any of the three current harnesses (each guide's context-loading finding confirms no duplication and no reduced-variant emission is needed today). If a future harness's guide reports duplication, this step regenerates the
@<harness>-skip-*variant via the existing content-transform pipeline — never new transform code (Business Rule 4). - Model provider — per the guide's § Model Provider Configuration and
tech/automation.md's## Model Policy(if declared): report which model class (cheap/balanced/frontier) applies to whichrisk:*tier, and which concrete provider/gateway configuration in the harness's own guide realizes that class today (e.g. an opencode Zen free model forcheap). Never write a credential — name the environment variable or auth command the developer runs themselves. - Headless readiness (pi only, today) — pi's guide documents a load-bearing headless/trust gate: a headless run ignores project resources unless a trust decision exists for it. If the resolved harness is
piand headless execution is in scope for this configuration, report this gate explicitly and offer, in this order:- Default: a per-directory entry in
~/.pi/agent/trust.json, scoped to this project's canonical path only (a trust-configuration write, not a credential — permitted) — or point at the interactive/truststep to write the same scoped entry. - Only if the developer explicitly asks for it:
defaultProjectTrust: "always"in~/.pi/agent/settings.json— state plainly that this trusts every project pi opens headlessly on this machine, not just this one, before writing it. Never silently assume a headless run will see project skills, and never default to the global setting when the scoped one solves the same problem.
- Default: a per-directory entry in
Step 6: Idempotent Re-Run
- Check: Was this harness already provisioned by this skill (its config file and skill-path setup already match what Step 5 would produce)?
- Act (already configured): Confirm the existing configuration rather than rewriting it — report what is already in place, matching
/pair-capability-setup-pmand/pair-capability-setup-gates's own re-run behavior. - Act (partially configured, or drifted from what the guide now documents for a newer harness version): Report the diff and ask before overwriting.
- Verify: A second run on an already-configured harness produces a confirmation, never a silent rewrite.
Output Format
HARNESS CONFIGURED:
├── Harness: [pi | opencode | claude-code]
├── Fitness: [Declared and compatible | No tech/automation.md declaration — zero-config path]
├── Installed: [version observed | installed on yes: <version> | declined — HALTed] (pi: vs minimum 0.86.1)
├── pi-subagents: [n/a — not requested | confirmed <version> | installed <version> (<scope>) | drift <installed> vs pinned <version> — unverified] (pi only)
├── Auth: [Ready — <path> | Missing — <what to obtain, and CI-viability>]
├── Config: [file written/confirmed]
├── Skills: [already discovered — no write | path added: <entry>]
├── Context: [no action needed | reduced variant emitted: <path>]
├── Model policy: [class → provider mapping reported | tech/automation.md has no ## Model Policy — none applied]
├── Headless: [n/a | trust gate reported — <action>] (pi only)
└── Status: [Configured | Already configured (unchanged) | HALTed — <reason>]
HALT Conditions
- Harness argument unrecognized or has no guide (Step 1.4).
- Harness not among the project's declared supported harnesses (Step 2.3) — before any write.
- Harness cannot satisfy a project-required access path (Step 2.4) — before any write, e.g. MCP required and
pi(no MCP by design) requested. - Harness not installed on this machine (Step 3.2) — reported as an environment fact, not a project error; for
pi, only after the developer declined the proposed install (Step 3.3). - An install the developer approved failed (Step 3.3, Step 3b) — the command's own error, nothing retried.
None of these HALTs follow a configuration write — fitness (Step 2) and presence (Step 3) are both checked before Step 5 provisions anything. The only writes before Step 5 are the pi / pi-subagents installs the developer explicitly approved.
Composition Interface
When composed by /pair-process-bootstrap (optional, finalization phase):
- Input:
/pair-process-bootstrapreaches its finalization phase and offers/pair-capability-setup-harnessalongside/pair-capability-setup-pm, as a skippable step — most projects decline and stay on the harness already in use, which needs notech/automation.mddeclaration (the zero-configuration path, Step 2's skip branch). - Output: Returns the harness name, fitness result, and configuration status.
/pair-process-bootstrapincludes any adoption changes in the next commit.
When invoked independently:
- Interactive: full Step 1–6 flow. Developer commits any adoption changes when satisfied.
Edge Cases
- Developer carries a personal global config (e.g.
~/.pi/agent/AGENTS.md, opencode's~/.config/opencode/AGENTS.md): report that it brings context the project does not control (each guide states this); this skill neither reads nor modifies it. tech/automation.mdexists but has no## Harness/## Model Policyheading: treated identically to the file being absent (zero-configuration path) — presence of the file alone does not turn on fitness-checking; presence of the specific heading does.- Multiple harnesses configured over time: each run configures exactly one harness (the resolved
$harness); running again with a different value configures that one too — this skill does not deduplicate or reconcile across harnesses, and a project's## Harnesslist is not a limit on how many a developer configures, only on which ones the project accepts as supported.
Graceful Degradation
See graceful degradation (adoption file missing → proceed with the zero-configuration path) for the standard scenarios. Additional cases:
tech/automation.mdmissing entirely → Step 2's skip branch: every harness in the framework is presumed supported, nothing to HALT against./pair-capability-record-decisionnot installed → provisioning (Step 5) still completes; only a decision record (rare — most runs need none) is skipped, with a warning.- A harness's guide is missing a section the fixed nine-section index requires → that is a framework defect, not something this skill works around; report it and stop rather than guessing the missing section's content.
Notes
- Credentials never pass through this skill (the hard constraint): it reads readiness, never a value; it reports what is missing and how a human obtains it. Rationale: pi persists sessions as JSONL and shares them via
/share— a token that entered a session's context is a token that can leave the machine through that channel. - Adding a harness is one markdown file and zero skill changes (Business Rule 4): a new
<name>.mdguide following the fixed index is immediately resolvable by$harness: <name>— nothing in this file's algorithm names a harness by special case. - This skill provisions configuration and reports readiness; it installs nothing without an explicit yes, and the only things it can install are
pi(Step 3.3) and, on request,pi-subagentsat the pinned version (Step 3b) — every other harness's binary is verified and HALTed on (Step 3.2). It does not perform the functional smoke run (that is the separate smoke scenario inscripts/smoke-tests/).