※'20260717時点の私なりのハーネス設計思想を以下にまとめます。AI(周辺機能も含む)の進化が早すぎるため日々アップデート中です・・・
Claude Codeを使ったアプリ開発において、「ハーネス」を単なる便利なプロンプト集や、HooksとSkillsの寄せ集めではなく、アプリ開発の進行そのものを制御する実行基盤として設計しています。
この考えを「ゴール契約ループ設計」として実装したのが、自作ハーネス 「cc-dev-autoship」 です。
出発点にあるのは、人間が毎回プロンプトを打たなくても開発が進む状態を作りたい、という動機です。
ただ、設計を深めるうちに、本質は「プロンプトレス」そのものではないことが見えてきました。
ハーネスの定義:人間が毎回作業手順を指示しなくても、目的・状態・ルール・成果物に基づいて、AIが次の工程を判断し、検証と修正を繰り返しながら開発を進められる仕組み
プロンプトを打たなくてよくなるのは、適切に設計された結果であって、目的ではない。
真の設計目標:必要な情報が自動的に集まり、次の行動が状態から決まり、成果が機械的に検証され、判断が必要な場合だけ人間に戻ってくる
そしてcc-dev-autoshipの全体原則は、この実装方針そのものになっています。
コードで強制できるものはコードに、モデルが推論できないものだけ散文に、それ以外はモデルに任せる。
人間がAIにプロンプトを打つ場面をよく観察すると、2種類に分かれます。
| 種類 | 例 | cc-dev-autoshipでの扱い |
|---|---|---|
| ルーチン的な作業指示 | 「実装して」「テストして」「直して」 | 完全に自動化。実装 → simplify → レビュー並列 → PR → CI → 次Issueの遷移は契約で定義済みで、Issue間はノンストップ |
| 本質的な意思決定 | 仕様解釈、トレードオフ、優先順位 | 承認境界として設計。人間の同期ポイントは原則4つ — 仕様確定 / デザイン承認 / タスク分解のバッチ承認 / リリース承認(+G1操作発生時の追加承認) |
プロンプトを減らすことと判断を減らすことは別物。前者だけを自動化すれば開発は加速するが、後者まで自動で流してしまうと、間違った方向に高速で進む機械ができあがります。
良いハーネスは人間を排除するのではなく、人間の注意を最も価値のある判断ポイントだけに集約すると考えています。
単なる自動化とハーネス化を分ける境界は、プロンプトの回数ではなく、開発の進行を決める主体がどこにあるか。
人間のプロンプトが進行を決めている限り、それは弱い自動化にとどまります。
【弱い自動化】進行の決定権が人間のプロンプトにある
人間:「実装して」 → Claude Code: 実装
人間:「テストして」 → Claude Code: テスト
人間:「直して」 → Claude Code: 修正
【cc-dev-autoshipの実装ループ】進行の決定権が契約=状態遷移にある
現在状態: Issue実装完了(format/typecheck/lintはhookが書き込み毎に検証済み)
↓ 契約: 次の必須工程は simplify → code-reviewer + security-reviewer 並列
review FAIL
↓ 契約: implementerへ差し戻し(前回のroot-causeと棄却済み仮説を委譲文に同梱)
修正 → 再レビュー(該当reviewerのみ)
↓ 同一Issueで3回解消しなければ bisect → 人間へエスカレーション
review PASS → PR作成 → CI green → 非同期マージ依頼 → 次の独立Issueへ
cc-dev-autoshipでは、人間は工程を進めるためのプロンプトを一切打っていません。
この状態遷移の自動化こそがハーネスの中核であり、Claude Codeを「操作する対象」から「ワークフロー内で役割を実行するワーカー」へ変える転換点だと考えています。
ただし、cc-dev-autoshipの「制御層」は外部ステートマシンではなく、モデルが契約(GOAL / DONE / 非自明な順序)から次工程を導き、機械側はhookで「証跡なしの完了宣言のblock」「自己申告DONEの突合warn」を担保するハイブリッド構成です。
決定論的な状態機械ではなく、いわば**「契約駆動の状態遷移」——モデルの推論を遷移関数に含むハイブリッド制御**です。
すべてをコードで縛るのではなく、コードで強制すべきものと、モデルの推論に任せるものを切り分けています。
| 主体 | 役割 |
|---|---|
| Claude Code(メイン) | 指揮官。実装はimplementer、レビューはcode-reviewer / security-reviewer、設計相談はarchitect(read-only)等のSubAgentに委譲 |
| ハーネス | 契約(loop-contract)+ hookの強制 + Stop hookの停止判定で、何をいつ実行するかを決める制御層 |
| 人間 | 目的・制約の設定と、リリース承認・バッチ承認・仕様不明点の判断 |
cc-dev-autoshipのワークフローはP1〜P7のフェーズで構成されます。
人間
↓ 目的・制約・承認(=意思決定のみ)
ハーネス(制御層 = 契約 + フェーズskill群 + hooks)
↓ 状態を見て次工程を決定
P1 仕様(spec.md)→ spec-reviewer検証 → 人間承認
↓
P2 デザイン(DESIGN.md / tokens.md)→ 人間承認
↓
P3 タスク分解(Linear Issue + 大型Issueのplan前倒し)→ バッチ承認1回
↓
P4 実装ループ — Issue間ノンストップ
↓ Issueごと: 実装 → simplify → レビュー並列 → PR → CI → 非同期マージ
P5 verify(要件の消し込み + 実機検証)
↓
P6 デプロイ/リリース(人間承認)→ launch-readiness → P7 project-close
※ 完成済みの単発diffはフェーズフロー外の ship skill で出荷
毎回人間が指示する方式では、成果物の質が指示の詳しさ、抜け漏れ、開発者の経験、そのときの会話コンテキストに左右されます。
cc-dev-autoshipでは、仕様レビュー・コード/セキュリティレビュー・保護対象の照合・verifyを工程として常に通します。
さらにformat / typecheck / lintは、Edit/Write後のPostToolUse hookが書き込みのたびに強制します。
Bash経由のファイル変更(sed等)はこのリアルタイム検査の対象外ですが、pre-push時の保護パターン再照合・G2レビュー層・CIはいずれもgit diffベースで動くため、どのツールで書いたかに関係なく、差分は最終的に検査されます。
軽い検査は書き込み時に即座に、重い検査はdiffベースの層に委譲する多層構成です。
品質は「人間がうまく指示できたか」ではなく、工程と品質ゲートで担保されます。
AIが途中で止まる原因は、能力不足だけではありません。cc-dev-autoshipでは、停止につながる主要因を契約側で減らしています。
測るべき指標は「プロンプト数ゼロ」ではなく、プロンプト数が減ったのに手戻りが増えたら、それは失敗。
cc-dev-autoshipはIssue完了ごとに loop.jsonl へ interventions(計画外の介入数)・review_retries(手戻り)・escalations を記録し、しきい値を超えると harness-eval がハーネス自体の改善を起動します。
ハーネスの改善が感覚頼みではなく、メトリクス駆動になります。介入1回あたりの価値そのもの(自律完了率・サイクルタイム・初回レビュー通過率など)の計測は、今後の拡張課題です。
この方向性を突き詰める中で向き合った緊張点と、cc-dev-autoshipでの対策を挙げます。
LLMが自分の成果物を自分で承認するゲートは甘くなる。対策は3層構えにしました。
固定フェーズ構成は想定した開発には強いが、想定外のタスクでは構造が邪魔になる。ハーネスは進行方向を縛る「レール」ではなく、逸脱だけを防ぐ「ガードレール」であるべきです。
ship skill、仕様を見直してタスク分解へ巻き戻すエスカレーション経路人間のプロンプトは、実は「暗黙のチェックポイント」として機能しています。それを取り除くと、序盤の小さな誤解が終盤で大破綻として現れる。
対策として、各工程の出力を検証可能な形式(DONE述語 + 完了宣言表 + 構造化ログ + ファイル契約)にしたうえで、2つの仕組みを入れました。
harness-eval が変更前後の対象メトリクスをchangelogに併記し、変更後に数値が悪化したらrollbackを提案するAIは指示されなくても進みますが、間違った前提のまま進むこともあります。
人間の承認は2軸で整理しています。ひとつはプロダクト意思決定ゲート(仕様確定・デザイン承認・タスク分解のバッチ承認)で、通常フローの同期ポイントとして計画的に発生するもの。
もうひとつが リスク・不可逆操作ゲート=G1(不可逆・外部影響) で、発生タイミングを問わず必ず人間承認を要求するものです。
G1は、Claude Codeのpermission設定(公式のallow / ask / deny)およびハーネス側のauto mode用hard denyリストと機械的に一致させています。
加えて、仕様の不明点は推測禁止でエスカレーション。一方で「複数の正解がある設計判断」は人間ではなくarchitect(read-only相談役)に寄せて自走を止めない設計を選びました。
バッチ承認時に存在しなかった選択肢が発生した場合のみ人間に戻る。目指すのは「人間をループから外す」ことではなく、**「低価値な指示ループから外す」**こと。
概念を実装レベルに落とすと、6つの要素になります。
各フェーズのskillは手順書ではなく、次の契約フォーマットで書く。手順の決定はモデルに任せ、done判定だけを機械化する。
GOAL: 1行。フェーズ開始時にメインが宣言
DONE: 機械検証可能な述語リスト(実行コマンド or アーティファクト存在チェック)
制約: 破ってはいけない不変条件(hookで強制できないものだけ)
非自明な順序: モデルが推論できない手順のみ(依存・事故防止由来)
エスカレーション: ループを停止して人間に渡す条件
skillは100行以内が目安。超えるなら手順を書きすぎている。
{
"run_id": "<バッチ承認時 ISO8601>",
"phase": "4",
"current_issue": "LIN-12",
"issues": [
{ "id": "LIN-12", "status": "implementing",
"depends_on": ["LIN-09"], "review_retries": 1, "escalations": [] }
]
}
設計上のポイントは、このファイルが nextAction を持たないことです。次の行動は状態ファイルではなく契約から導く。
状態ファイルを権威(SSoT)にするとIssue管理ツールやgitとdriftするため、「Linear + gitから再構築可能な高速復元キャッシュ」に格下げし、矛盾時は破棄して作り直す。
会話履歴に頼らず、ファイル・構造化データを工程間の契約とする。
| 工程 | 出力(契約) |
|---|---|
| 仕様 | spec.md(成功条件を仕様時に宣言)+ 保護対象定義 |
| デザイン | DESIGN.md / tokens.md |
| タスク分解 | Linear Issue(サイズ・依存・意図)+ 大型Issueのplan |
| 実装 | コード差分 + reviewerのPASS証跡 + PR + CI結果 |
| 各フェーズ完了 | 完了宣言表(述語 / 検証手段 / 実測結果) |
| Issue完了 | loop.jsonl 1行 + devlogエントリ |
「止める場所」を3分類し、機械判定に寄せられるものは寄せる。
| 分類 | 定義 | 扱い |
|---|---|---|
| G1 不可逆/外部影響 | 本番デプロイ / 破壊的migration / シークレット / 公開 / 課金 | 人間ゲート維持(permission設定と一致) |
| G2 品質 | code/securityレビュー / 保護対象照合 / verify | 決定的チェックは機械判定。意味的品質は実装者と分離したreviewerが評価し、両者の証跡に定義済みの通過条件を機械的に適用。人間は事後レビュー |
| G3 進行 | タスク選択 / plan承認 / 実装モード選択 | タスク分解末尾のバッチ承認1回に集約 |
失敗時の行動もワークフローとして定義済み。
review指摘が解消しない
├─ 3回未満 → 修正して再レビュー(root-causeと棄却済み仮説を同梱)
├─ 「直しても症状が消えない」型 → 3-step bisectで真因特定
└─ 3回到達 → 人間へ選択肢を提示:
(a) followup Issueに切り出してマージ / (b) Blockedにして次へ / (c) タスク分解へ巻き戻し
SubAgentが応答しない・途中切断
└─ リトライせず1回でメイン直接対応に切替(自走継続)
認証など人間の作業が必要
└─ 再dispatch禁止。内容を提示 → ユーザー作業完了後に再委譲
自律的に動くほど、「何を考えて何を変更したか」の確認手段が要る。
loop.jsonl — 1 Issue = 1行のメトリクスログ。記録漏れはStop hookが機械検出harness-eval — しきい値超過で起動し、数値トリガー → 原因仮説 → 改善(機械化できるものはhook化を最優先)→ 効果判定 → 悪化ならrollbackClaude CodeにはSkills、Hooks、Subagentsといった強力な機能があります。
これら単体はハーネスではなく、ハーネスを構成する部品として位置づけると整理しやすいです。
| 要素 | 役割 | cc-dev-autoshipでの例 |
|---|---|---|
| Skills | 特定作業のやり方・知識・手順 | フェーズskill(ゴール契約形式)+ ユーティリティ(ship等) |
| Hooks | イベント時に必ず処理を実行(ガードレール) | pre-bash-guard / post-write-lint / stop-check / record-metric |
| Subagents | 役割やコンテキストを分離して作業 | implementer / code-reviewer / security-reviewer / architect 等14種 |
| CLAUDE.md | プロジェクト全体の基本ルール | 中核は契約ドキュメント(loop-contract)へ委譲 |
| ハーネス | これらを組み合わせ、開発全体を進行・制御する制御層 | 契約SSoT + フェーズskill連鎖 + Stop hookの停止判定 |
例えばテスト担当のSubAgentを用意するだけでは、まだハーネスとは言えません。
「Issue実装完了をDONE述語で検知 → reviewerを並列起動 → 証跡でPASS/FAILを評価 → FAILなら差し戻し(3回で人間へ)/ PASSならPR → CI → 次のIssueへ」
ここまで制御して初めて、ワークフロー型のハーネスになると考えています。
さらにその上の層として、知識の4ティア昇格パイプライン(揮発するin-context → 蒸留されたauto-memory → アーカイブ → 不変のルール)を置き、ループが学んだことをハーネス自体の改善に還流させています。
Claude Codeのハーネスとは、AIへの指示文を工夫することではない。
- アプリ開発の工程(ゴール契約)
- 状態遷移(ノンストップループ + エスカレーション)
- 品質基準(機械検証可能なDONE述語 + ゲート3分類)
- 失敗時の回復処理(リトライ規律 + bisect)
- 人間の承認境界(同期ポイント4つ)
これらを仕組みとして定義し、人間が逐次プロンプトを入力しなくても開発が進む実行環境。
その目的は人間の排除ではなく、人間の介入を作業指示から意思決定へ移し、介入1回あたりの価値を最大化することにあります。
最終的な設計目標は、必要な情報が自動的に集まり、次の行動が状態から決まり、成果が機械的に検証され、判断が必要な場合だけ人間に戻ってくること。
ここまで実現できれば、それは単なるClaude Codeの活用法ではなく、AI時代の開発実行基盤と呼べるものになると考えています。