harness-init — Install the Harness Control Loop📖 New to harness? Read README.md (Japanese: README.ja.md) for concepts, terminology (Tier-A / rubric / Principal Skinner / foundation-sprint / ...), and the three-skill overview before diving into implementation details.
Sets up a user project so the /harness series (harness-plan, harness-loop,
harness-rules-update) can drive autonomous sprint development. This skill
runs once per project; re-running reconciles existing configuration.
Required Reading — Open BEFORE doing the step
Claude Code tends to skim SKILL.md. For each step below you MUST open and read the listed reference file(s) before acting.
| Step | Required file(s) to open |
|---|---|
| Step 1 | references/hearing-questions.md (bilingual question text) |
| Step 3 | references/templates/ (product-spec, sprint-contract, shared_state) |
| Step 4 | references/agent-templates/ (EN .md, JA .ja.md, Codex .toml / .ja.toml) + references/rubric-presets.md |
| Step 5 | references/scripts.md + references/scripts/*.sh |
| Step 6 | references/codex-hooks/ (scripts + hooks.json.template) |
| Steps 7–10 | references/installation-integration.md (or .ja.md) — orchestration protocol; also open its step-specific secondary references before acting |
Language Rules
Resolve narrative language: explicit override (in English, 日本語で) >
project mandate in CLAUDE.md / AGENTS.md > current user prompt >
fallback skill source language (English).
Never infer from machine text (git log, progress.md, JSON keys, state
enums, file paths, commands). Keep such tokens unchanged. AskUserQuestion
body uses resolved language; option labels/descriptions stay bilingual
(English / 日本語).
Reference files exist as <name>.md (English) and <name>.ja.md (Japanese).
Pick the pair matching the resolved language for narrative guidance; schemas
(templates, JSON) are language-agnostic.
Prerequisites
Before any generation step, check:
-
Git repo —
git rev-parse --is-inside-work-treemust succeed. -
jqavailable —command -v jq. All hooks require it (Claude Code hooks receive their input as JSON on stdin; scripts parse fields via jq). -
Not already initialised — if
.harness/_config.ymlexists, switch to reconfigure mode (see Step 0). -
Shared foundation — check for
docs/coding-rules.md,docs/review_rules.md, anddocs/issue-to-pr-workflow.md. These are the shared substrate between/specand/harnessskill series. They are generated by/spec-rules-initand/spec-workflow-init. If any are missing, surface a warning but do not block:AskUserQuestion: question: "Shared rules files are missing under docs/. Proceed anyway?" / "docs/ の共有ルールファイルが不在です。続行しますか?" options: - "Run /spec-rules-init first (Recommended)" / "先に /spec-rules-init を実行(推奨)" → stop harness-init with guidance - "Proceed without them (reduced rubric coverage)" / "無しで続行(rubric カバレッジ低下)" → continue; Evaluator will score Craft axis conditionallyThe Craft rubric axis treats coding-rules.md as "adhered to if present, unscored otherwise", so harness can function without it but quality gates are weaker.
If checks 1–3 fail, stop with a clear error. Do not partially generate.
Execution Flow
Step 0: Detect Existing Installation
if .harness/_config.yml exists:
AskUserQuestion:
question: "Existing harness install detected. What to do?" / "既存のハーネス設定を検出しました。"
options:
- "Reconfigure (merge)" / "再設定(マージ)"
- "Re-init from scratch (backup old)" / "一から再初期化(旧設定はバックアップ)"
- "Cancel" / "キャンセル"
else:
proceed to Step 1
When presenting the Reconfigure (merge) option, its description
MUST warn the user with bilingual content like:
⚠️ Generated artifacts under
.claude/agents/,.codex/agents/,.harness/templates/,.harness/scripts/,.codex/hooks/will be re-rendered from the latest templates — any hand-edits to these files will be overwritten.Preserved:
_config.ymlkeys not asked in this hearing (e.g. user-setcodex_cli_binary), runtime state (_state.json/progress.md/metrics.jsonl), and.claude/settings.json(non-clobber merge).To keep hand-edits: commit them to git first (recover with
git checkout), or chooseRe-init from scratchto back up the entire.harness/tree.⚠️ Artifacts under the above paths are re-rendered from the latest template, and manual edits will be lost. If you want to keep them, committing to git beforehand is recommended.
See Mode Behavior Matrix for the full per-step contract.
On "Re-init from scratch", rename existing .harness/ to
.harness.backup-<ISO8601>/ before proceeding.
Mode Behavior Matrix
The mode chosen at Step 0 determines what each subsequent step does. This table is the canonical contract — Steps 1–10 below describe the unified action; this matrix says how the action specializes per mode.
| Step | Re-init from scratch | Reconfigure (merge) |
|---|---|---|
| 1 Hearing | Defaults shown | Existing _config.yml values shown as defaults |
2 _config.yml |
Fresh write of all keys | Hearing-asked keys updated; keys NOT asked (e.g. codex_cli_binary) preserved verbatim |
3 Templates (.harness/templates/) |
Copy all | Re-copy — templates are source of truth, idempotent for unchanged content; hand-edits are overwritten |
4 Agents (.claude/agents/, .codex/agents/) |
Render all | Re-render all — same as Step 3 |
5 Scripts (.harness/scripts/) |
Write all | Re-write all — same as Step 3 |
6 Codex hooks (.codex/hooks/, .codex/hooks.json) |
Write all | Re-write all — same as Step 3 |
7 .harness/scripts/wrap-untrusted.sh |
Write | Re-write — same as Step 3 |
8 .claude/settings.json |
Fresh write | Non-clobber merge (see references/settings-merge.md) |
9 CLAUDE.md |
Append pointer block | Idempotent skip if pointer block already present |
10 Resilience files (_state.json / progress.md / metrics.jsonl) |
Fresh write of empty / initial files | Never touch — runtime state owned by harness-loop |
Rule of thumb:
- Generated artifacts (Steps 3–7): templates are source of truth → both modes (re-)render; hand-edits are overwritten without prompting (commit to git first to preserve).
- Runtime state (Step 10): the only step where modes are inverted (fresh writes new state / merge must never touch — would corrupt an in-progress sprint).
- Config (Step 2): the only step needing a true merge strategy — hearing-asked keys updated, all other keys (incl. user customizations like
codex_cli_binary) preserved.
Step 1: Environment Hearing
Six AskUserQuestion rounds collect the full _config.yml. Exact question
text is in references/hearing-questions.md
(or .ja.md). The axis being collected on each round:
| # | Setting | Config key |
|---|---|---|
| 1 | Project type | project_type (web / api / cli / other) |
| 2 | Generator backend (epic default) | generator_backend (claude / codex_cli / codex_cmux). Sprint-level override via Planner roadmap-phase AskUserQuestion is enabled by default — see Step 2 sprint_level_generator_override flag |
| 3 | Evaluator tools | evaluator_tools (ordered list from Phase 3 tooling hearing) |
| 4 | Hook level | hook_level (strict / warn / minimal) |
| 5 | Tracker | tracker (github / gitlab / none) |
| 6 | Auto-stop limits + cost cap + MCP allow-list | max_iterations, max_wall_time_sec, max_cost_usd, allowed_mcp_servers |
Defaults are chosen to be safe: strict hook level is recommended for any
generator_backend other than claude, but the user decides.
Round 2 backend choices are limited to the supported enum
(claude / codex_cli / codex_cmux); the legacy other value has
been removed. Adding a new backend requires a coordinated PR that updates
this hearing AND harness-plan/references/roadmap-guide.md Backend
Recommendation rubric AND harness-loop/references/generator-dispatch.md
invocation switch — keep them in sync.
Before presenting Round 2 options, detect Codex availability (see Step
6 below). If codex CLI is not installed, remove codex_cli and
codex_cmux options and advise the user to install it first.
Step 2: Write _config.yml
Atomic write to .harness/_config.yml:
schema_version: 1
project_type: <from hearing>
generator_backend: <from hearing> # claude | codex_cli | codex_cmux (epic default)
sprint_level_generator_override: true # default: enable Planner roadmap-phase AskUserQuestion + 4-layer resolution at runtime. Set to false to bypass everything and always use generator_backend (legacy compat path)
evaluator_tools: [<from Phase 3 tooling hearing>]
hook_level: <strict|warn|minimal>
tracker: <github|gitlab|none>
max_iterations: 8
max_wall_time_sec: 28800
max_cost_usd: 20.0
rubric_stagnation_n: 3
allowed_mcp_servers: [<from hearing>]
negotiation_max_rounds: 3
# Mid-impl replan (Step 6' in harness-loop — dispatches Planner when a frozen
# contract proves infeasible without resetting the iteration counter).
mid_impl_replan:
enabled: true
min_consecutive_signals: 2
max_per_sprint: 2
axis_band_threshold: 0.05
# Codex-specific settings (populated in Step 6 when generator_backend ∈ codex_*)
codex_cli_binary: /opt/homebrew/bin/codex
codex_cli_sandbox: danger-full-access
codex_generator_model: "gpt-5.4" # passed via --model on every Codex invocation
codex_cmux_idle_dwell_polls: 2 # completion signal: required consecutive idle polls
codex_cmux_idle_poll_seconds: 20 # seconds between idle polls for codex_cmux
Step 3: Copy Templates
Copy from references/templates/ to .harness/templates/:
product-spec.md(EN) orproduct-spec.ja.md(JA) →.harness/templates/product-spec.mdsprint-contract.md/.ja.md→.harness/templates/sprint-contract.mdshared_state.md/.ja.md→.harness/templates/shared_state.mdfoundation-sprint-checklist.md→.harness/templates/foundation-sprint-checklist.md(language-agnostic; used by/harness-planwhen foundation-readiness detects greenfield — see ../harness-plan/references/foundation-sprint-guide.md)
Only the language matching detected input is copied for the bilingual files; the other remains in the skill package for reference.
Step 4: Generate Agent Definitions
Render three agent files to .claude/agents/ using _config.yml values:
planner.md— orchestrates, writes product-spec/roadmap/contract, rules on negotiation stalematesgenerator.md— receives contract, implements, negotiates. Backend is switched pergenerator_backend(inline Claude, Codex CLI, or Codex via cmux)evaluator.md— runs acceptance scenarios (Playwright MCP / Playwright CLI / curl / custom-script), scores rubric axes, produces evidence
Pick the language variant matching detected input: <role>.md (EN) or
<role>.ja.md (JA) from references/agent-templates/.
If generator_backend ∈ {codex_cli, codex_cmux} OR the project
already has a .codex/ directory (indicating Codex CLI is configured),
also render Codex TOML role configs (plain ConfigToml layers with
top-level name + description + model + developer_instructions):
.codex/agents/planner.toml— fromreferences/agent-templates/planner{.ja}.toml.codex/agents/evaluator.toml— fromreferences/agent-templates/evaluator{.ja}.toml.codex/agents/generator.toml— fromreferences/agent-templates/generator{.ja}.toml
.ja.toml carries Japanese developer_instructions and is used when
the detected input language is Japanese, keeping Codex's role overlay
in the same language as Claude's sub-agent definition.
Each TOML's developer_instructions field carries the full role
contract (Boot Sequence, Pre-flight Gates, output protocol incl. the
mandatory feedback/<role>-<iter>-report.json, and prohibitions —
matching the Claude sub-agent definition in .claude/agents/<role>.md).
Activation happens via the Orchestrator's prompt-file opening line
("You are the 'generator' agent defined in .codex/agents/generator.toml...").
Model caveat: codex-plugin-cc's task command does NOT honor the
model field from agent TOML. The Orchestrator passes --model <name>
on every invocation, reading codex_generator_model from _config.yml.
The TOML's model is kept for forward compat (a future plugin version
may respect it).
Patch .codex/config.toml non-destructively: append [agents.planner],
[agents.evaluator], [agents.generator] role declarations (with
description and config_file pointing to the TOML above) if not already
present. Preserve all existing entries (e.g., workflow-implementer).
Step 5: Generate Scripts
Write executable scripts to .harness/scripts/ (chmod 755):
progress-append.sh— PostToolUse hook; reads stdin JSON via jqrestore-after-compact.sh— SessionStart(compact) hook; dumps progress tail + state to stdout for reinjectionstop-guard.sh— Stop hook; enforces Principal Skinner, self-managesstop_hook_activeanti-loop flagtier-a-guard.sh— PreToolUse(Bash) hook; regex match against.harness/tier-a-patterns.txt, setspending_human=trueon hitmcp-allowlist.sh— PreToolUse(mcp__*) hook; denies non-allow-listed serverscodex-progress-bridge.sh— Orchestrator helper forcodex_*backends; parses Codex'sfeedback/<role>-<iter>-report.jsonand appends equivalent rows toprogress.md+ atomically updates_state.json. Copied verbatim regardless of backend selection so reconfiguration is a no-opcodex-cli-dispatch.sh— Orchestrator helper forcodex_cli; invokescodex exec, canonicalises narrative/report outputs, and bridges them into harness statecheck-sprint-prs-complete.sh— retroactive check for completed/done epics missing required_state.json.sprint_prs[n]staleness-watchdog.sh— optional Autonomous Ralph liveness monitor; appendsSTALE-WATCHDOGwarnings whenprogress.mdhas no fresh timestamp and can opt-in respawn the wrapper via_config.ymlfoundation-readiness.sh— probing script used by/harness-planStep 3.5. Accepts--epic <slug>(full assessment, writes.harness/<epic>/foundation-readiness.mdand emits JSON summary) or--check <probe-key>(single probe, used by/harness-loopfor foundation-sprint deliverable verification). See ../harness-plan/references/foundation-sprint-guide.md.harness/tier-a-patterns.txt— initial destructive-pattern regex set
Step 6: Codex Backend Setup (conditional)
Runs only when generator_backend ∈ {codex_cli, codex_cmux}.
- Detect Codex CLI —
codex --version. If it fails:- For
codex_cli/codex_cmuxselection: surface an error and advisenpm install -g @openai/codex, then loop back to Round 2 with the selection restricted toclaude. - For
claudeselection: proceed silently (skip this Step entirely).
- For
- Resolve Codex CLI settings:
- Write
codex_cli_binary(default/opt/homebrew/bin/codex) andcodex_cli_sandbox(defaultdanger-full-access) into_config.yml.
- Write
- Deploy Codex-side hook scripts — copy (chmod 755) from
references/codex-hooks/to<project>/.codex/hooks/:inject-harness-context.shtier-a-guard-codex.shcodex-bash-log.sh
- Generate
<project>/.codex/hooks.json— renderreferences/codex-hooks/hooks.json.template, substituting{{PROJECT_ROOT}}with the absolute project root path. - Enable
codex_hooksfeature flag — non-destructively patch<project>/.codex/config.toml:
Preserve any existing[features] codex_hooks = true[features]entries and all other config. - Append Codex hook summary to the Step 10 summary report so the user sees what was installed on the Codex side.
If generator_backend == claude, skip this entire Step; the Claude
backend does not require Codex CLI / hooks. (The legacy other value
has been removed from the supported enum — see Step 1 hearing.)
Steps 7–10: Installation Integration
Read references/installation-integration.md
completely (.ja.md for Japanese), then execute its Steps 7 through 10 in
order. Also read every secondary reference it names before writing settings,
CLAUDE.md, resilience state, or ignore rules.
Step 11: Summary Report
Emit to the user:
- Files created (paths relative to project root)
- Files patched (with "approved" or "proposed-only" suffix)
- Next recommended action:
fully exit Claude Code, relaunch this repository with
claude --resume, then run/harness-planto create the first epic
Error Handling
| Situation | Response |
|---|---|
| Not a git repo | Error: "Run this skill inside a git repository." |
jq not found |
Error: "Install jq — all harness hooks require it." |
| Write fails mid-flow | Error with partial-state notice; advise .harness.backup-* rollback |
| User rejects hooks patch | Continue, leaving .proposed file; report clearly |
.claude/settings.json malformed |
Error with line number; do not clobber |
| Existing install in reconfigure mode | Merge config values (preserve hearing-non-asked keys); re-render generated artifacts (Steps 3–7); never touch runtime state (Step 10). See Mode Behavior Matrix for the full contract. |
Usage
# First-time install
/harness-init
# Re-run (reconfigure mode)
/harness-init
# Read-only preview (future; v1 always writes after final approval)
/harness-init --dry-run
What harness-init does NOT do
- Does not write product-spec.md — that is
harness-plan's job - Does not run any sprint — that is
harness-loop's job - Does not install worker agents for
spec-drivenworkflows — usespec-workflow-initfor that lane - Does not add CI jobs, pre-commit hooks, or build pipelines — only
.claude/settings.jsonhooks (ms tier). Other speed tiers are out of scope
References
- hearing-questions.md — bilingual question text
- rubric-presets.md — axis sets per project type
- hooks-templates.md — settings.json by level (Claude + Codex hook matrix)
- settings-merge.md — non-clobbering merge algorithm
- scripts.md — guard scripts in
.harness/scripts/(incl.codex-progress-bridge.sh) - codex-hooks/ — Codex-side hook scripts +
hooks.json.template(installed whengenerator_backend ∈ codex_*) - agent-templates/ — Claude
.md+ Codex.tomlrole contracts for planner / generator / evaluator - untrusted-content.md — external-content wrapping
- claudemd-patch.md — idempotent CLAUDE.md pointer patch
- resilience-schema.md — progress/state/metrics schemas
- templates/ — product-spec, sprint-contract, shared_state