🏗️

AIコーディングツールは"使う"より"設計する" ─ Claude Code × Cursorの4層アーキテクチャ

に公開

はじめに

昨今、Claude CodeやCursorを使ってコードを書く人は増えました。
しかし、こんな経験はないでしょうか。

  • 毎回同じ指示を繰り返し書いている
  • AIの出力品質にムラがあり、レビューコストが減らない
  • 機能が増えてくるとAIが文脈を見失い、的外れな提案をしてくる

これらはツールの問題ではなく、使い方の設計が足りていないだけです。

AIコーディングツールは「使う」だけでなく「設計する」ものです。CLAUDE.md、エージェント、スキル、フックを体系的に組み立てれば、個人開発でもチーム開発並みの品質と速度が手に入ります。

この記事では、Claude Code × Cursorの「プロンプト設計」と「ワークフロー構築」の実践ノウハウを紹介します。題材は筆者が21日間・139コミットで開発したAI Tech Digest Appです。Cloudflare Workers製の技術情報リーダーで、QiitaやZennなど技術サイトの記事を自動収集し、AIで要約して日次ダイジェストを配信します。React 19 + Workers KV + Workers AIのフルスタック構成で作りました。

私が作成した「AI Tech Digest App」の画面です。
ai-tech-digest-app

全体像 --- AI支援開発のレイヤー構造

AIツールへの指示は、4つのレイヤーに整理できます。上のレイヤーほど汎用的な原則、下のレイヤーほどプロジェクト固有の知識が濃くなります。

各レイヤーに対応するファイル・ディレクトリはツールによって異なります。

レイヤー Claude Code Cursor 役割
1. プロジェクト指示 CLAUDE.md AGENTS.md AIの行動原則
2. ルール .claude/rules/ .cursor/rules/ 文脈依存の規約
3. エージェント .claude/agents/ .cursor/agents/ 専門分担
4. スキル + フック .claude/skills/, .claude/hooks/ .cursor/skills/ 自動化とワークフロー制御

実際のディレクトリ構成はこうなります。

project-root/
├── .claude/
│   ├── agents/       # エージェント定義
│   ├── skills/       # スキル
│   ├── rules/        # ルール
│   └── hooks/        # フックスクリプト
├── .cursor/
│   ├── agents/
│   ├── skills/
│   └── rules/
├── CLAUDE.md
└── AGENTS.md

順番に見ていきましょう。

レイヤー1: CLAUDE.md / AGENTS.md --- プロジェクト指示の設計

CLAUDE.mdは、AIがプロジェクト内でどう振る舞うかを定義するファイルです。Claude Codeはセッション開始時にこのファイルを自動で読み込みます。CursorではAGENTS.mdが同等の役割を担います(シンプルな用途向けの代替手段で、フロントマターによるスコープ制御が必要な場合は.cursor/rules/.mdcファイルが標準形式です)。

ポイントは「AIに何をさせたいか」ではなく、「AIにどう振る舞ってほしいか」を書くことです。

AI Tech Digest Appで実際に使ったCLAUDE.mdの抜粋を紹介します。

CLAUDE.md(行動原則セクションの抜粋)
## 行動原則
- 3ステップ以上のタスクはPlanモードで開始。意図と選択理由を含める
- うまくいかなくなったら立ち止まって再計画する
- 動作を証明(テスト実行・ログ確認)するまで完了としない
- コードを読まずに書かない。既存コードを確認してから変更する
- コンテキスト逼迫時はその旨を伝えて区切りを提案する
- リサーチ・調査はサブエージェントに委譲しメインコンテキストを節約する
- コミット: English-only Conventional Commits(`type(scope): description`
- 実装タスク: feature-first(doc-updater → 実装/dev-coder → test-writer → 検証 → code-reviewer)
- エージェント委譲は5パラメータ(目的・参照ファイル・出力先・権限・品質基準)を明示する

いくつか補足します。

「動作を証明(テスト実行・ログ確認)するまで完了としない」も効きます。
これがないと、AIは「実装しました」と宣言して終わります。テスト実行やログ確認をゴール条件に含めることで、動くコードが出てくるようになります。

「コードを読まずに書かない」は指示しないと崩れやすいです。
AIは「この関数を実装して」と言われると、既存コードを確認せず書き始めることがあります。その結果、同じユーティリティが二重実装されたり、命名規則が既存コードとバラバラになったりします。「まず読む」を行動原則に入れておくことで、既存パターンに沿った実装が自然と出てくるようになりました。

「リサーチ・調査はサブエージェントに委譲する」はコンテキスト節約の要です。
ライブラリのドキュメントを調べたりコードベースをgrepしたりする作業は、大量のコンテキストを消費します。これをメインセッションでやると、実装フェーズに入るころにはウィンドウが圧迫されています。調査はサブエージェントに投げて要点だけを受け取ることで、メインセッションは判断と実装に集中できます。

CLAUDE.mdの設計にあたっては、100行のCLAUDE.mdより35行が効く理由 — 公式仕様で解く設定の最適化を参考にしました。CLAUDE.mdは長くするほど効くわけではなく、各行に「判断を改善する価値があるか」という基準で絞り込むのがポイントです。

CLAUDE.mdの詳しい仕様は公式ドキュメントを参照してください。

CLAUDE.md
# AI Tech Digest

技術情報(RSS / Qiita / Zenn)を自動収集・AI要約し、日次ダイジェストとして配信するパーソナル技術情報リーダー。

## 技術スタック

- Cloudflare Workers(API / Fetcher / Frontend) + Workers KV
- React 19 + Vite + Tailwind CSS(SPA)
- Workers AI(要約・トピック生成)
- Cloudflare Access(Google OAuth)
- TypeScript strict mode / Vitest / Prettier + ESLint
- モノレポ: `app/packages/{api, fetcher, frontend, shared}`

## コマンド

| コマンド | 用途 |
|---------|------|
| `cd app/packages/<pkg> && npx vitest run` | テスト |
| `cd app/packages/<pkg> && npx tsc --noEmit` | 型チェック |
| `bash scripts/sync-memories.sh` | メモリ同期 |

## 行動原則

- 3ステップ以上のタスクはPlanモードで開始。意図と選択理由を含める
- うまくいかなくなったら立ち止まって再計画する
- 動作を証明(テスト実行・ログ確認)するまで完了としない
- コードを読まずに書かない。既存コードを確認してから変更する
- コンテキスト逼迫時はその旨を伝えて区切りを提案する
- リサーチ・調査はサブエージェントに委譲しメインコンテキストを節約する
- コミット: English-only Conventional Commits(`type(scope): description`
- 実装タスク: feature-first(doc-updater → 実装/dev-coder → test-writer → 検証 → code-reviewer)
- エージェント委譲は5パラメータ(目的・参照ファイル・出力先・権限・品質基準)を明示する
- セッション開始時に `CONTEXT.md``TODO.md` を確認。バックログは `design/improvement-backlog.md`

## メモリ・エージェント管理

- メモリ原本: `docs/ai/memories/`。CLAUDE.md/AGENTS.md は直接編集しない
- エージェント原本: `docs/ai/agents/``.claude/agents` / `.cursor/agents` がシンボリックリンク)
- スキル原本: `docs/ai/skills/``.claude/skills` / `.cursor/skills` がシンボリックリンク)
- 詳細ルール: `.claude/rules/` 配下を参照

レイヤー2: ルール --- 文脈依存の規約を分離する

CLAUDE.mdにすべてを書くと、すぐに肥大化します。プロジェクト固有のルールは.claude/rules/に分離するのがおすすめです。

AI Tech Digest Appでは4つのルールファイルを使いました。

testing-conventions.md(テスト規約)

テストフレームワーク、ファイル配置、テストケースIDの命名規約を定義します。

.claude/rules/testing-conventions.md
## テスト規約
- フレームワーク: Vitest
- テストファイル: `src/**/__tests__/*.test.ts`
- テストケースID: `TC-{機能略称}-{連番}`(例: TC-AUTH-001)
- カバレッジ目標: 行カバレッジ80%以上

design-decisions.md(設計判断の記録)

アーキテクチャ上の判断とその理由を記録します。AIが「なぜこの設計なのか」を理解したうえで実装できるようになります。

.claude/rules/design-decisions.md
# 重要な設計判断

- CF Access が常に前段に存在する前提。API側の認証ミドルウェアはレガシー
- JWT 署名検証は CF Access が保証するため `atob` のみで十分
- フロントエンドの同期データは `UserData` としてKVに一括保存(マージロジックはフロント側)

feature-first-workflow.md(ワークフロー定義)

実装フローを6ステップで強制します。これはレイヤー3のエージェントと組み合わせて使います。

.claude/rules/feature-first-workflow.md
ソースコードを変更する実装タスクでは、**ユーザーから指示がなくても必ず**以下の順番で実行すること:

1. **`doc-updater` エージェントを呼び出す(実装前)** — 要件定義・基本設計・詳細設計・テストケース・RTM を先に更新する。improvement-backlog・TODO.md も対象。(SKILL.md ステップ 1〜4)
2. **ソースコードを実装する** — 小規模(1-2 ファイル)はメインセッションが直接実装。大規模(3 ファイル以上)は `dev-coder` エージェントに委譲する。(SKILL.md ステップ 5)
3. **`test-writer` エージェントを呼び出す(実装後)** — 実装した関数・コンポーネントのユニットテストを作成・実行させる。(SKILL.md ステップ 6)
4. **型チェック・テストを通す**(メインセッション) — `npx tsc --noEmit``npx vitest run` で全パス確認。(SKILL.md ステップ 7)
5. **`code-reviewer` エージェントを呼び出す** — セキュリティ・パフォーマンス・規約準拠を第三者視点で検証する。(SKILL.md ステップ 7 完了後)
6. **CRITICAL 指摘を修正** — code-reviewer が `REQUEST_CHANGES` を返した場合、メインセッションが修正し、必要に応じてステップ 5 を再実行する。

## 省略できる場合(例外)

- 既存テストのバグ修正のみ(ロジック変更なし)
- ドキュメントのみの変更
- リファクタリングで外部インターフェースが変わらない場合

上記例外に当てはまらない限り、省略せずに必ず実行する。

## Orchestrator としての振る舞い

メインセッションは **Orchestrator**(指揮者)として振る舞う:

- **タスク配分に集中** — 具体的な作業はエージェントに委譲し、メインのコンテキストを節約する
- **エージェント間の直接通信は行わない** — 必ずメインセッション経由で情報を受け渡す
- **レビュー修正はメインが行う** — code-reviewer には修正させない(客観性の喪失を防ぐ)
- **dev-coder の使用判断**: 変更ファイル数が 3 以上 → dev-coder に委譲。1-2 ファイル → メインが直接実装

## エージェント委譲テンプレート(5 パラメータ)

エージェントを呼び出す際は、以下の 5 項目を必ず含めること:

1. **目的(Purpose)**: このタスクで何を達成するか(1-2 文)
2. **参照ファイル(Reference files)**: 読むべきファイルパス一覧
3. **出力先(Output destination)**: 作成・更新するファイルパス(read-only エージェントの場合は「レポートをメインに返す」)
4. **権限レベル(Permission level)**: read-only / doc-edit / test-edit / source-edit
5. **品質基準(Quality criteria)**: 完了とみなす条件(例: 型チェック通過、テスト全パス、CRITICAL 0 件)

design-docs-and-rtm.md(ドキュメント管理)

RTM(Requirements Traceability Matrix)のテーブル形式を定義します。要件からテスト結果までの追跡を可能にします。

.claude/rules/design-docs-and-rtm.md
## RTMテーブル形式
| 要件ID | 要件概要 | 設計書参照 | テストケースID | テスト結果 |
|--------|---------|-----------|--------------|----------|
| REQ-001 | ... | DD-001 | TC-AUTH-001 | PASS |

Cursorの.mdc形式との対比

Cursorでは、プロジェクト指示はAGENTS.md、ルールは.cursor/rules/が対応します。Cursorのルールファイルは.mdc拡張子で、フロントマターにglobsalwaysApplyなどのメタ情報を持ちます。

.cursor/rules/testing.mdc
---
globs: ["src/**/*.test.ts", "src/**/*.spec.ts"]
alwaysApply: false
---
# テスト規約
(内容はClaude Code版と同じ)

Claude Codeのルールファイルにはこうしたメタ情報はありません。ファイルの存在自体が「常に適用」を意味します。

このレイヤーのポイントは「関心の分離」です。
CLAUDE.mdには行動原則だけを書き、具体的なルールは.claude/rules/に分けます。ファイルが増えても見通しが良いです。

詳しくは公式ドキュメントのsettingsセクションを参照してください。

レイヤー3: エージェント --- 専門家チームを編成する

Claude Codeのサブエージェントは、特定の役割に特化したAIを定義する仕組みです。メインのClaude Codeがオーケストレーターとなり、タスクに応じてサブエージェントに委譲します。

AI Tech Digest Appでは、feature-firstワークフローに沿った4体のエージェントを編成しました。

各エージェントの定義

エージェントファイルはフロントマターで名前・説明・利用可能ツールを宣言し、本文でワークフローや制約を記述します。実際のファイル内容を紹介します。

doc-updater(設計書担当)

.claude/agents/doc-updater.md
---
name: doc-updater
description: feature-first ステップ 1〜4 を担当。要件定義・基本設計・詳細設計・テストケース・RTM・バックログ・TODO を更新する。
tools:
  - Read
  - Write
  - Edit
  - Glob
  - Grep
---

# Doc Updater Agent

設計ドキュメント・テストケース・RTM の更新を担当するエージェント。

## パス解決

本エージェントは Claude Code(`.claude/`)と Cursor(`.cursor/`)の両方から利用される。

| リソース | Claude Code | Cursor |
|---------|-------------|--------|
| rules | `.claude/rules/<name>.md` | `.cursor/rules/<name>.mdc` |
| skills | `.claude/skills/` | `.cursor/skills/` |

## 初期化

実行開始時に `design-docs-and-rtm.md`(またはその `.mdc`)を Read し、RTM テーブルフォーマット・テストケース ID 規約を取得する。

## 参照プロンプト

| ステップ | Claude Code | Cursor |
|---------|-------------|--------|
| 1. 要件定義 | `.claude/skills/dev-workflow/references/requirements_definition_prompt.md` | `.cursor/skills/dev-workflow/references/requirements_definition_prompt.md` |
| 2. 基本設計 | `.claude/skills/dev-workflow/references/app_basic_design_prompt.md` | `.cursor/skills/dev-workflow/references/app_basic_design_prompt.md` |
| 3. 詳細設計 | 同上(詳細粒度で適用) | 同上 |
| 4. テスト設計 | `.claude/skills/dev-workflow/references/test-definition-prompt.md` | `.cursor/skills/dev-workflow/references/test-definition-prompt.md` |

`.claude/skills``.cursor/skills` はいずれも `docs/ai/skills/` へのシンボリックリンクのため参照先は同一。

## ワークフロー

### ステップ 1: 要件定義更新
参照プロンプトを Read → 要件定義書に新機能を追記 → RTM に要件行を追加

### ステップ 2: 基本設計更新
参照プロンプトを Read → ページ仕様・コンポーネント一覧・ファイル構成を更新 → RTM の「基本設計」列を埋める

### ステップ 3: 詳細設計更新
参照プロンプトを Read → Props・状態管理・処理フロー・型定義を更新 → RTM の「詳細設計」列を埋める

### ステップ 4: テスト設計更新
参照プロンプトを Read → 新機能のテストケースを追加 → RTM の「テストケースID」列を埋める

### ステップ 5: バックログ・TODO 更新(必須)

着手時: `improvement-backlog.md` のステータスを `🔵`(進行中)、`TODO.md``[-]` に変更
完了時: ステータスを `✅``TODO.md``[x]` に変更(メインから「完了」と指示された場合のみ)

## 制約

- ソースコードは変更しない
- テストファイルは変更しない(test-writer 担当)
- 日本語で記述する(コード例は英語可)

doc-updaterのポイント: 初期化時にdesign-docs-and-rtm.mdを読み込んでRTMフォーマットを取得します。RTMフォーマットをエージェント定義にハードコードしていないため、プロジェクト側で変更しても追従できます。また「パス解決」テーブルを持ち、Claude CodeとCursorのどちらから呼ばれても同じエージェントファイルで動く設計になっています。バックログとTODOの更新条件は「着手時」と「メインから完了指示された時のみ」で明確に分かれています。これにより、未完了のタスクが誤って完了マークされることを防いでいます。

dev-coder(実装担当)

.claude/agents/dev-coder.md
---
name: dev-coder
description: 大規模実装(3ファイル以上)を担当。TypeScript + Cloudflare Workers + React 19 のソースコード実装に特化する。
tools:
  - Read
  - Write
  - Edit
  - Glob
  - Grep
  - Bash
---

# Dev Coder Agent

feature-first ワークフローのステップ 5(機能実装)を、3 ファイル以上の変更が見込まれる大規模タスクで実行する。

## 前提

- ステップ 1〜4(doc-updater による設計・テスト設計更新)が完了していること
- メインエージェントから 5 パラメータ(目的・参照ファイル・出力先・権限・品質基準)が指示されること

## パス解決

| リソース | Claude Code | Cursor |
|---------|-------------|--------|
| rules | `.claude/rules/<name>.md` | `.cursor/rules/<name>.mdc` |

## 初期化

`design-decisions.md`(またはその `.mdc`)と詳細設計ドキュメントを Read する。

## ワークフロー

1. 詳細設計ドキュメントからインターフェース・型・処理フローを把握する
2. 対象パッケージの既存ファイルを Read し、パターン・命名規則を把握する
3. shared パッケージ(型定義・定数)から着手する
4. バックエンド → フロントエンドの順で実装する
5. `npx tsc --noEmit` で型エラーを解消する
6. 作成・更新したファイル一覧をメインに報告する

## コーディング規約

- `any` キャスト・`@ts-ignore` 禁止
- ESM インポートパス: `.js` 拡張子を付ける
- 既存コードのスタイルに合わせる(新しいパターンを導入しない)

## 制約

- 設計ドキュメントは変更しない(doc-updater 担当)
- テストファイルは変更しない(test-writer 担当)
- 設計ドキュメントに記載されていない機能を追加しない

dev-coderのポイント: 委譲の閾値を「3ファイル以上の変更」に設定しています。小さな修正はメインセッションが直接処理し、大きな実装だけサブエージェントに委ねることでコンテキスト切り替えのオーバーヘッドを抑えています。実装順序もshared→backend→frontendと固定することで、型が未定義のまま実装が進む事態を防いでいます。

test-writer(テスト担当)

.claude/agents/test-writer.md
---
name: test-writer
description: feature-first ステップ 6 を担当。テスト設計に基づきユニットテストを作成・実行する。
tools:
  - Read
  - Write
  - Edit
  - Glob
  - Grep
  - Bash
---

# Test Writer Agent

## 前提

- ステップ 4(テスト設計)が完了し、テストケースが定義済みであること
- ステップ 5(機能実装)が完了していること

## パス解決

| リソース | Claude Code | Cursor |
|---------|-------------|--------|
| rules | `.claude/rules/<name>.md` | `.cursor/rules/<name>.mdc` |

## 初期化

`testing-conventions.md`(またはその `.mdc`)を Read し、テストフレームワーク・ファイル配置ルール・実行コマンド・モックパターンを取得する。

## テスト命名

`functionName_scenario_expectedResult` パターンを使用:
- `handleGetFeeds_emptyKV_returnsDefaultFeeds`
- `useNotes_setNote_savesToLocalStorage`

## ワークフロー

1. 同パッケージの既存テストファイルを読み、パターンを把握する
2. テストケース定義から対象テストケース ID の仕様を読む
3. テスト対象のソースファイルを Read してインターフェースを把握する
4. 規約に従いテストファイルを Write/Edit する
5. 全テスト通過を確認する。失敗した場合は修正して再実行する
6. 作成/更新したファイル名・テストケース数・実行結果をメインに報告する

## 制約

- ソースコードは変更しない(テストファイルのみ)
- テストケース ID のコメントを必ず付与する
- 既存テストを壊さないこと

test-writerのポイント: ワークフローの最初のステップが「既存テストを読んでパターンを把握する」になっています。これにより、プロジェクト固有の命名規則やモックパターンに自然と沿ったテストが生成されます。テストケースIDのコメント付与を必須にしているのはRTMとの紐付けを機械的に保証するためで、「どの要件のテストか」が後から追跡できます。

code-reviewer(レビュー担当)

.claude/agents/code-reviewer.md
---
name: code-reviewer
description: feature-first ステップ 7 完了後のコードレビューを担当。実装・テストの第三者レビューを行い、セキュリティ・パフォーマンス・規約準拠を検証する。
tools:
  - Read
  - Glob
  - Grep
  - Bash
---

# Code Reviewer Agent

## 原則

**「書いた本人にレビューさせない」** — メインセッションまたは dev-coder が実装したコードを独立した視点で検証する。

## パス解決

| リソース | Claude Code | Cursor |
|---------|-------------|--------|
| rules | `.claude/rules/<name>.md` | `.cursor/rules/<name>.mdc` |

## 初期化

`design-decisions.md``testing-conventions.md`(またはそれぞれの `.mdc`)を Read する。

## レビュー観点

### 1. セキュリティ
- CF Access 前提を逸脱していないか
- シークレット・トークンがコードやログに漏洩していないか
- KV キーのバリデーション(インジェクションリスク)
- API エンドポイントの入力サニタイズ

### 2. パフォーマンス
- Workers CPU 時間(Freeプラン: 10ms / Paidプラン: デフォルト30秒、最大5分まで設定可能)
- 不要な KV read/write
- React コンポーネントの不要な再レンダリング
- バンドルサイズへの影響

### 3. 規約準拠
- TypeScript strict mode(`any` キャスト・`@ts-ignore` 禁止)
- ESM インポートパスに `.js` 拡張子が付いているか
- ファイル配置・命名規則

### 4. 正確性
- エッジケース処理(空データ・不正入力・KV 未初期化)
- エラーハンドリング
- 設計ドキュメントとの整合性

### 5. テストカバレッジ
- 新規コードを網羅しているか
- テストケース ID が設計書と一致するか

### 6. フロントエンド・E2E
変更が `app/packages/frontend` または `app/packages/e2e` に及ぶ場合:
- `cd app/packages/e2e && npx playwright test` の通過を確認
- MCP 有効時: 主要ルートをナビゲートしアクセシビリティスナップショットで表示崩れを確認

## 出力形式

```markdown
## レビュー結果

### CRITICAL(対応必須)
- **[ファイルパス:行範囲]** 説明 → 推奨アプローチ

### WARNING(対応推奨)
- **[ファイルパス:行範囲]** 説明 → 推奨アプローチ

### INFO(参考情報)
- **[ファイルパス:行範囲]** 説明

### サマリ
- レビュー対象ファイル数: N
- CRITICAL: N件 / WARNING: N件 / INFO: N件
- 総合判定: APPROVE / REQUEST_CHANGES
```

CRITICAL が 1 件でもあれば `REQUEST_CHANGES`

## 制約

- ソースコードは変更しない(レビュー結果の報告のみ)
- CRITICAL 指摘の修正はメインセッションが行う

code-reviewerのポイント: toolsにBashが含まれていますが、ソースコードの変更は禁止です。tsc --noEmitplaywright testなどの検証コマンドのみ使用可にしています。Playwright MCPとE2Eテストの役割分担も明記されています。自動回帰テストはE2Eに任せ、MCPは「ナビゲートして表示崩れを目視確認する探索的チェック」に限定しています。出力形式をCRITICAL/WARNING/INFOで構造化しているのは、対応判断をメインセッション(人間)がしやすくするためです。

このレイヤーのポイントは「コンテキストの独立」です。
サブエージェントはメインセッションとは別のコンテキストウィンドウで動きます。設計工程の詳細でコンテキストが埋まらないまま実装工程に進め、実装の経緯を知らない状態でレビュー工程を始められます。1セッションですべてをこなそうとすると、コンテキストが前工程の情報で圧迫されて精度が落ちます。工程ごとにサブエージェントを切り替えることで、長い開発フローが現実的に回るようになります。

なお、Cursorも.cursor/agents/でサブエージェントを定義できます。後述するSSoT戦略では、docs/ai/agents/を原本としてシンボリックリンクで両ツールに配布しています。

エージェントの詳しい仕様は公式ドキュメントを参照してください。

レイヤー4: スキル + フック --- 自動化で人間の手を減らす

スキル --- ワークフローの強制

スキルはClaude Codeに再利用可能な手順を教える仕組みです。2つのスキルファイルの実際の内容を紹介します。

feature-first

.claude/skills/feature-first/SKILL.md
---
name: feature-first
description: 機能開発で「ドキュメント → 実装 → テスト」の順序を強制するワークフロー。「機能追加」「実装して」「新機能」などのキーワードが出たら使用する。実装・新機能などコードや振る舞いが変わる依頼では、ステップ 1〜9 を順に必ず実行する(スキップ禁止)。RTM は `design/` 配下の専用 Markdown として用意する(既存があれば追記、無ければ新規)。コミット対象とする。会話内だけの表は禁止。各工程の詳細プロンプトは dev-workflow スキルの参照ファイルを使う。
---

# Feature-First 開発ワークフロー

機能開発は **必ずこの順序** で進める。テストコードは実装の後に作成する。

## 実装・新機能時の必須ルール(最重要)

次のいずれかに当てはまる依頼では、下記 **ステップ 1〜9 を必ずこの順で実行する**。順序の入れ替え・省略・「ドキュメント済みだから」でのジャンプは **禁止**

- 新機能・機能追加・仕様変更に伴う実装
- 「実装して」「コーディング」「バグ修正」など、**アプリの振る舞いやコードが変わる**作業全般

```
1. 要件定義更新
2. 基本設計更新
3. 詳細設計更新
4. テスト設計更新(テストケース追記)
5. 機能実装
6. テストコード実装
7. 型チェック・テスト実行
8. ビルド・動作確認
9. コミット・プッシュ
```

## RTM(要件トレーサビリティ)— 反映漏れゼロの管理

RTM とは、要件ごとに設計・テスト・実装への「紐づき」を一覧化した表のこと。
リポジトリ内の RTM 専用 Markdown に表を書き、ステップが進むたびに更新し、各ゲートで穴がないことを確認してから次へ進む。

### RTM ドキュメント(必須・別ファイル)

| 項目 | ルール |
|------|--------|
| **パス** | `design/rtm/rtm-<短いスラッグ>.md` 推奨 |
| **命名** | kebab-case(例: `inline-note-editor`)。同一依頼・ブランチではファイルは 1 本にまとめる |
| **作成タイミング** | ステップ 1 着手時。既存スラッグのファイルがあれば追記、なければ新規作成 |
| **更新** | ステップ 2〜6 の各完了時に該当列を埋める |
| **禁止** | RTM 表を会話内だけに置き、リポジトリに残さないこと |

### RTM 表テンプレート

| 要件ID | 要件概要 | 基本設計 | 詳細設計 | テストケースID | テストコード | 実装 | 備考 |
|--------|----------|----------|----------|----------------|--------------|------|------|
| … | … | … | … | … | … | … | … |

### ステップ終了時の RTM ゲート(必須)

| ステップ完了後 | RTM で必ず確認すること |
|----------------|-------------------------|
| **1 要件定義** | RTM ファイルが `design/` 配下に存在。今回スコープの要件が全行ある |
| **2 基本設計** | 各要件の「基本設計」列が参照可能 |
| **3 詳細設計** | 各要件の「詳細設計」列が参照可能 |
| **4 テスト設計** | 各要件に対応するテストケースID が 1 つ以上 |
| **5 機能実装** | 各要件が実装列でコードに追える |
| **6 テストコード** | 各テストケースID がテストコード列で特定可能 |
| **9 コミット前** | 空セルがない。ぶら下がり要件・orphan テストがない |

### 最終監査チェックリスト(ステップ 9 直前)

1. RTM ファイルが `git add` 済みで最新の表が保存されているか
2. 全要件について設計・テスト・実装の参照が埋まっているか
3. 新規テストはすべて要件またはテストケースIDに紐づくか
4. 新規コードはすべて要件または設計に紐づくか
5. 以下の全ドキュメントが更新済みか(変更不要の場合はその旨を確認):
   - `design/requirements_definition.md`
   - `design/app_basic_design.md`
   - `design/app_detail_design.md`
   - `design/tests/app-test-cases.md`
   - `design/rtm/rtm.md` または `design/rtm/rtm-<slug>.md`
   - `design/improvement-backlog.md`
   - `TODO.md`

## 各ステップの実行方法

各ステップ開始時に、対応する dev-workflow の参照ファイルを **Read してから** 作業する。

| ステップ | Read するファイル |
|---------|-----------------|
| 1. 要件定義 | `../dev-workflow/references/requirements_definition_prompt.md` |
| 2. 基本設計 | `../dev-workflow/references/app_basic_design_prompt.md` |
| 3. 詳細設計 | 同上(詳細粒度で適用) |
| 4. テスト設計 | `../dev-workflow/references/test-definition-prompt.md` |
| 5. 実装 | `../dev-workflow/references/app_implementation_prompt.md` |
| 6. テストコード | `../dev-workflow/references/unit-test-implementation-prompt.md` |

## 部分実行

実装・振る舞い変更を含む依頼では常に 1〜9 すべてを実行する。
設計・ドキュメント・テストのみの依頼に限り、該当ステップのみ実行してよい。

feature-firstのポイント: RTMを「チャット内だけに置くことを禁止」しているのがこのスキルの核心です。AIが設計書をその場だけで作って終わりにせず、必ずリポジトリにファイルとして残すことを強制しています。各ステップ終了時のRTMゲートで、AIは次のステップへ進む前に「設計列が埋まっているか」「テストケースIDが紐づいているか」を自己チェックします。最終監査チェックリストはコミット前の品質ゲートとして機能します。「ぶら下がり要件」や「orphanテスト(要件に紐づかないテスト)」が混入することを防ぎます。

dev-workflowスキルは、各フェーズで参照すべきプロンプトファイルをマッピングしています。AIが「次に何をすべきか」を迷わないようにする仕組みです。

dev-workflow

.claude/skills/dev-workflow/SKILL.md
---
name: dev-workflow
description: 要件定義、基本設計(アプリ/インフラ)、実装(アプリ/インフラ/CDK)、テスト(戦略・テスト項目書・ユニットテスト実装)、コードレビューの各工程で、対応するプロンプトテンプレートを適用する。「要件定義」「設計書」「基本設計」「実装」「テスト」「テストコード」「テスト項目書」「CDK」「レビュー」などのキーワードが出たら使用する。
---

# 開発ワークフロースキル

開発工程に応じて、対応するプロンプトテンプレートを読み込み、その指示に従って作業を行う。

## ワークフロー判定と対応ファイル

ユーザーの依頼内容を分析し、以下のマッピングに基づいて **該当するファイルを Read ツールで読み込んでから** 作業を開始すること。

### 1. 要件定義

**トリガー**: 要件定義、要件整理、要求分析、仕様書作成
**読み込むファイル**: [references/requirements_definition_prompt.md](references/requirements_definition_prompt.md)

### 2. 基本設計(アプリケーション)

**トリガー**: アプリ基本設計、アプリ設計書、画面設計、モジュール設計、データ設計
**読み込むファイル**: [references/app_basic_design_prompt.md](references/app_basic_design_prompt.md)

### 3. 基本設計(インフラ)

**トリガー**: インフラ基本設計、インフラ設計書、AWS設計、ネットワーク設計、リソース設計
**読み込むファイル**: [references/infra_basic_design_prompt.md](references/infra_basic_design_prompt.md)

### 4. アプリケーション実装

**トリガー**: アプリ実装、フロントエンド実装、バックエンド実装、機能実装
**読み込むファイル**: [references/app_implementation_prompt.md](references/app_implementation_prompt.md)

### 5. テスト戦略・方針

**トリガー**: テスト戦略、テスト方針、テスト計画、テスト観点
**読み込むファイル**: [references/test-aspects.md](references/test-aspects.md)

### 6. テスト項目書作成

**トリガー**: テスト項目書、テストケース、テスト定義、テスト仕様書
**読み込むファイル**: [references/test-definition-prompt.md](references/test-definition-prompt.md)

### 7. ユニットテスト実装

**トリガー**: ユニットテスト、テストコード、単体テスト実装、テスト実装
**読み込むファイル**: [references/unit-test-implementation-prompt.md](references/unit-test-implementation-prompt.md)

## 複数工程にまたがる場合

依頼が複数工程にまたがる場合は、上流工程から順に処理する:

```
要件定義 → 基本設計 → 実装 → テスト → レビュー
```

## 判定に迷う場合

- 「設計」だけの場合 → アプリかインフラかを確認する
- 「テスト」だけの場合 → テスト項目書かテストコードかを確認する
- 「実装」だけの場合 → アプリ/インフラ/CDKのどれかを確認する

dev-workflowのポイント: このスキルは「どの工程ではどのファイルを読め」というディスパッチマップです。実際の指示内容はreferences/配下のファイルに委譲されており、スキルがスキルを参照する2層構成になっています。あいまいなキーワードには判定ガイドを持たせており、「設計」であれば「アプリかインフラ」の確認、「テスト」であれば「テスト項目書かテストコード」の確認を促します。要件定義からユニットテスト実装まで7工程をカバーするため、アプリ開発以外の工程でも再利用できます。

フック --- イベント駆動の自動化

フックはClaude Codeのツール実行後に自動で走るスクリプトです。settings.jsonPostToolUseイベントで定義します。

AI Tech Digest Appでは2つのフックを使いました。

post-push.sh(git push後にCONTEXT.md自動更新)

.claude/hooks/post-push.sh
#!/usr/bin/env bash
set -euo pipefail
input=$(cat)
command=$(echo "$input" | python3 -c "
import sys, json
d = json.load(sys.stdin)
print(d.get('tool_input', {}).get('command', ''))
" 2>/dev/null || echo "")

if ! echo "$command" | grep -qE '(^|&&\s*|\|\|\s*)git push'; then
  exit 0
fi

PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) || exit 0
cd "$PROJECT_ROOT"
bash scripts/update-context.sh

Claude CodeのBashツールでコマンドが実行されるたびにフックが呼ばれます。inputにはJSON形式でツールの入力が渡されるので、git pushを含むコマンドだけをフィルタリングしています。

post-add.sh(git add後にTODO.mdを自動チェックオフ)

.claude/hooks/post-add.sh
#!/usr/bin/env bash
# git add 後に TODO.md を自動更新・ステージングするフック (Claude Code 用)
# ステージが TODO.md のみのときは git commit まで行う(.cursor/rules/project-context.mdc と同方針)
set -euo pipefail

# ステージングが TODO.md 1 ファイルだけかつ index と HEAD に差があるときだけコミット
commit_if_only_todo_staged() {
  local root n
  root="$(git rev-parse --show-toplevel 2>/dev/null)" || return 0
  cd "$root" || return 0
  # Note: do not assign name-only list to a var; command substitution strips trailing newline and breaks wc -l.
  n=$(git diff --cached --name-only 2>/dev/null | wc -l | tr -d '[:space:]')
  [ "$n" = "1" ] || return 0
  git diff --cached --name-only -- 2>/dev/null | grep -qx 'TODO.md' || return 0
  if git diff --cached --quiet 2>/dev/null; then
    echo "✓ TODO.md のみステージだがコミット対象差分なし、スキップ"
    return 0
  fi
  if git commit -m "docs(todo): update task checkboxes"; then
    echo "✓ TODO.md のみをコミットしました"
  else
    echo "⚠ git commit に失敗しました(user.name 等を確認)"
  fi
}

# --- 0. フック入力の解析(git add のみ対象)---
input=$(cat)
command=$(echo "$input" | python3 -c "
import sys, json
d = json.load(sys.stdin)
print(d.get('tool_input', {}).get('command', ''))
" 2>/dev/null || echo "")

# git add を含まないコマンドはスキップ
if ! echo "$command" | grep -qE '(^|&&\s*|\|\|\s*)git add'; then
  exit 0
fi

# TODO.md を add したときは AI 更新ループを避ける。ステージが TODO.md のみならコミットする。
if echo "$command" | grep -qF 'TODO.md'; then
  commit_if_only_todo_staged
  exit 0
fi

# --- 1. プロジェクトルートに移動 ---
PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) || exit 0
cd "$PROJECT_ROOT"

# --- 2. TODO.md 更新(AI解析)---
recent_commits=$(git log --oneline -10 2>/dev/null || echo "")

if [ -z "$recent_commits" ]; then
  echo "✓ コミット履歴なし、TODO.md スキップ"
  exit 0
fi

todo_content=$(cat TODO.md)

updated=$(claude -p "以下のコミット履歴とTODO.mdを照合し、コミットで完了が確認できるタスクの[ ]を[x]に更新してTODO.mdの全内容のみを出力してください。

ルール:
- TODO.mdの内容のみ出力すること(説明・コメントは不要)
- 形式・内容・改行・インデントは一切変えないこと
- チェックボックスの状態のみ変更すること([ ] → [x])
- すでに[x]のものはそのまま
- コミットメッセージと明確に対応するタスクのみ更新すること

## 直近コミット
${recent_commits}

## 現在のTODO.md
${todo_content}" 2>/dev/null) || { echo "⚠ AI解析スキップ(claude コマンドエラー)"; exit 0; }

if [ -n "$updated" ]; then
  # Strip preamble (before # TODO), code fences, and trailing AI commentary
  # Buffer lines from "# TODO" onward, then truncate at last markdown-structure line
  cleaned=$(echo "$updated" | awk '
    /^# TODO/ { found=1 }
    found && /^```/ { next }
    found { buf[++n] = $0 }
    END {
      last = 0
      for (i=1; i<=n; i++) {
        if (buf[i] ~ /^(#|-|\*|\[| |>|※|\t|$)/) last = i
      }
      for (i=1; i<=last; i++) print buf[i]
    }
  ')
  if [ -n "$cleaned" ]; then
    echo "$cleaned" > TODO.md
    git add TODO.md
    echo "✓ TODO.md 更新・ステージング完了"
  else
    echo "⚠ TODO.md サニタイズ後が空のためスキップ"
  fi
fi

commit_if_only_todo_staged

面白いのは、フック内でclaude -pを呼び出している点です。AIがAIを呼ぶ構成で、コミット履歴とTODO.mdを照合して、完了タスクのチェックボックスを自動で更新します。

いくつか実装上の工夫を入れています。まずcommit_if_only_todo_staged関数は、TODO.mdだけがステージされている状態なら自動でコミットまで行います。機能実装のコミット後に「あとはTODOだけ残った」というケースで、docs(todo): update task checkboxesとして自動的に完結します。

ループ防止の仕組みも少し工夫しています。フックがTODO.mdを更新してgit add TODO.mdすると、そのステージングが再びフックを呼び出します。TODO.mdを含むコマンドを検出したらAI更新はスキップしますが、その際もcommit_if_only_todo_stagedを呼び出してからexitします。

awkのサニタイズ処理も強化しました。以前は# TODO以降をそのまま出力していましたが、今は末尾のAI解説文(マークダウン構造でない行)も除去します。claude -pの出力末尾に「以上です」のような一文が混入しても、TODO.mdが汚染されません。

settings.jsonでのフック定義

.claude/settings.json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/post-push.sh"
          },
          {
            "type": "command",
            "command": "bash .claude/hooks/post-add.sh"
          }
        ]
      }
    ]
  }
}

matcherにはツール名しか指定できないため、"git push""cd app && git push"のような特定コマンドパターンを直接フィルタリングできません。そのため"matcher": "Bash"で全Bash実行をキャッチしたうえで、スクリプト側でJSONを解析して目的のコマンドが含まれるかを判定しています。

このレイヤーのポイントは「フックによる強制実行」です。
CONTEXT.mdの更新やTODO.mdのチェックオフは、人間はもちろんエージェントやスキルでも抜けることがあります。「タスク完了時にTODOを更新する」とCLAUDE.mdに書いても、AIは省略することがあります。フックはツール実行をトリガーにOSレベルで走るため、AIの判断を介さず確実に実行されます。指示に頼らず動作を保証したい作業の置き場です。

フックの詳しい仕様はHooksリファレンス、スキルはSkillsガイドを参照してください。

2つのIDEを共存させる --- SSoT戦略

Claude CodeとCursorの両方を使う場合、設定の二重管理が問題になります。エージェント定義を片方で更新して、もう片方で反映し忘れる、といった事態が起きます。

この問題は複数の AI コーディングツールで開発体験を揃える — メモリ・スキル・サブエージェントの共通化を参考にして、SSoT(Single Source of Truth)戦略で解決しました。

ディレクトリ構成

project-root/
├── docs/ai/                     # SSoT(原本)
│   ├── agents/
│   │   ├── doc-updater.md
│   │   ├── dev-coder.md
│   │   ├── test-writer.md
│   │   └── code-reviewer.md
│   ├── skills/
│   │   ├── feature-first/SKILL.md
│   │   └── dev-workflow/SKILL.md
│   └── memories/
│       └── README.md            # CLAUDE.md / AGENTS.mdの原本
├── .claude/
│   ├── agents/ → docs/ai/agents/   # シンボリックリンク
│   ├── skills/ → docs/ai/skills/   # シンボリックリンク
│   ├── rules/
│   └── hooks/
├── .cursor/
│   ├── agents/ → docs/ai/agents/   # シンボリックリンク
│   ├── skills/ → docs/ai/skills/   # シンボリックリンク
│   └── rules/
├── CLAUDE.md                    # sync-memories.shで自動生成
└── AGENTS.md                    # sync-memories.shで自動生成

原本はdocs/ai/配下に1つだけ置きます。
.claude/agents/.cursor/agents/はどちらもシンボリックリンクで原本を参照します。

sync-memories.shによる自動同期

CLAUDE.mdとAGENTS.mdはdocs/ai/memories/README.mdを原本として、同期スクリプトで自動生成します。手動でCLAUDE.mdを直接編集しないルールにしています。

# メモリの同期
bash scripts/sync-memories.sh

このレイヤーのポイントは「どちらのIDEで開いても同じ品質」を実現することです。
原本を1か所にまとめ、シンボリックリンクで配布します。設定のドリフト(ズレ)が起きません。

実際の開発フロー --- 機能追加の一連の流れ

ここまでの仕組みが実際にどう動くのか、「インラインノート機能」の開発フローで追体験してみましょう。この開発フローはAI駆動開発を始めよう!6段階フローで効率的な開発を実現のワークフローをベースに、feature-firstスキルとサブエージェントでカスタマイズしたものです。

ステップ1: TODO.mdで対象機能を選択

TODO.md
## Phase 2: 機能拡張
- [ ] インラインノート機能
- [ ] ブックマーク機能
- [ ] タグフィルタ機能

Claude Codeに「インラインノート機能を実装して」と伝えます。feature-firstスキルが発動し、ワークフローが自動で始まります。

ステップ2: doc-updaterが設計書を作成

メインのオーケストレーターがdoc-updaterに委譲します。5パラメータを明示した委任指示が飛びます。

doc-updaterは以下の順で設計書を作成します。

  1. 要件定義プロンプトをReadして要件定義書を作成
  2. 基本設計プロンプトをReadして基本設計書を作成
  3. 詳細設計プロンプトをReadして詳細設計書を作成
  4. テスト設計プロンプトをReadしてテストケースを作成
  5. RTMテーブルを更新

各ステップで「参照プロンプトをReadしてから書く」というルールが効いています。AIが白紙の状態からいきなり書き始めるのではなく、テンプレートに沿って構造化された設計書を出力します。

ステップ3: 実装 → テスト → レビュー

設計書が完成したら、メインがdev-coderに実装を委譲します。shared → backend → frontendの順で実装が進みます。

実装が終わるとtest-writerがテストを書き、テストケースIDを設計書と照合します。最後にcode-reviewerがRead-onlyでレビューし、CRITICAL/WARNING/INFOに分類した結果を返します。

CRITICALがあれば、メインのオーケストレーターが修正します。code-reviewer自身はコードを変更しません。

ステップ4: コミットとフック

レビューを通過したらコミットしてpushします。ここでフックが動きます。

  • post-push.shがCONTEXT.mdを自動更新
  • post-add.shがTODO.mdの「インラインノート機能」を自動でチェックオフ
TODO.md(フック実行後)
## Phase 2: 機能拡張
- [x] インラインノート機能
- [ ] ブックマーク機能
- [ ] タグフィルタ機能

人間がやったのは「インラインノート機能を実装して」と伝えたことと、途中の設計判断を確認したことだけです。設計書作成、実装、テスト、レビュー、TODO更新はすべてAIが担当しました。

開発速度と成果

AI Tech Digest Appの開発は、21日間で139コミットに達しました。フルスタックアプリとして完成し、日常的に使えるレベルになりました。

Phase分けでの進行

Phase 期間 内容 コミット数
Phase 1 7日 基盤構築(認証、KV設計、API基盤) 約45
Phase 2 9日 機能実装(フィード管理、ダイジェスト生成、UI) 約65
Phase 3 5日 最適化(パフォーマンス改善、エラーハンドリング、テスト拡充) 約29

AIツール活用で特に効いたポイント

設計書の自動生成が最大の時短でした。 個人開発では設計書を書くことをサボりがちですが、doc-updaterが自動で作るので、実装前に設計を固める習慣がつきました。結果として、手戻りが明らかに減りました。

code-reviewerによるセルフレビューの品質向上も大きいです。 個人開発ではレビュアーがいません。AIにレビューさせることで、セキュリティ上の見落としやN+1クエリなど、自分では気づきにくい問題を拾えました。

RTMによる追跡性の確保も効果的でした。 この機能のテストケースはどれか、この要件はどこで実装されたか、といった疑問をすぐに追跡できます。個人開発だと過剰に見えますが、機能が20を超えてくると確実に効いてきます。

注意点とベストプラクティス

CLAUDE.mdの肥大化を防ぐ

CLAUDE.mdが100行を超えたら、ルールファイルへの分離を検討してください。行動原則だけをCLAUDE.mdに残し、テスト規約や設計判断はルールファイルに移します。

エージェントに任せすぎない

エージェントは強力ですが、最終的な判断はオーケストレーター(メインのClaude Codeセッション)、つまり人間がします。特に設計判断やセキュリティに関わる部分は、AIの提案を鵜呑みにせず、必ず確認してください。

RTMは大きめの個人開発で効く

機能が5つ以下の小さなプロジェクトでは、RTMは過剰です。しかし、機能が増えてテストケースが数十になると、RTMなしでは漏れが出ます。プロジェクトの規模に応じて導入を判断してください。

まとめ

この記事で伝えたかったことを3つにまとめます。

1. AIツールは「設計するもの」です。 CLAUDE.md + ルール + エージェント + スキルの4層設計で、AIの振る舞いを体系的にコントロールできます。場当たり的なプロンプトから卒業しましょう。

2. ワークフローを強制する仕組みが大切です。 feature-firstスキルとRTMゲート、フックによる自動化を組み合わせることで、「やるべきことを飛ばさない」仕組みが手に入ります。個人開発でこそ、こうしたガードレールが効きます。

3. SSoT戦略で2つのIDEを1つのソースで管理できます。 docs/ai/を原本にしてシンボリックリンクで配布すれば、Claude CodeとCursorのどちらで開いても同じ品質で開発できます。

まずはCLAUDE.mdを充実させるところから始めてみてください。行動原則を5つ書くだけでも、AIの出力品質は目に見えて変わるはずです。

参考リンク

Virtual Craft Tech Blog

Discussion