spec-runner 1.0.19 → 1.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -1
- package/bin/spec-runner.js +62 -0
- package/docs/flow.md +213 -0
- package/package.json +2 -1
- package/templates/.spec-runner/scripts/docs-serve.sh +21 -0
- package/templates/.spec-runner/scripts/spec-runner-core.sh +35 -16
- package/templates/.spec-runner/steps//344/273/225/346/247/230/347/255/226/345/256/232.md +15 -1
- package/templates/.spec-runner/templates/phase-locks.json +5 -0
- package/templates/mkdocs-scaffold/docs/index.md +32 -0
- package/templates/mkdocs-scaffold/mkdocs.yml +16 -0
- package/templates/mkdocs-scaffold/requirements-docs.txt +2 -0
package/README.md
CHANGED
|
@@ -18,6 +18,14 @@ curl -sSL https://raw.githubusercontent.com/TEEE88/spec-runner/main/install.sh |
|
|
|
18
18
|
|
|
19
19
|
いずれも、プロジェクト直下に `.spec-runner/` ができる。
|
|
20
20
|
|
|
21
|
+
あわせて、**未有効時のみ**プロジェクトルートに次が配置される(Material for MkDocs で `docs/` 配下の設計書をプレビューするため)。
|
|
22
|
+
|
|
23
|
+
- `mkdocs.yml` / `requirements-docs.txt`
|
|
24
|
+
- `docs/index.md`(サイトのホーム)
|
|
25
|
+
- `docs/spec-runner-フロー.md`(`spec-runner` パッケージ同梱の手順書)
|
|
26
|
+
|
|
27
|
+
`.spec-runner/` がすでにあり **2 回目以降はエラーで止まる** 場合も、**その手前**で上記 MkDocs 用ファイルの不足分だけ補完される(初回導入以前のリポジトリで MkDocs だけ足したいときに便利)。
|
|
28
|
+
|
|
21
29
|
---
|
|
22
30
|
|
|
23
31
|
## 使い方
|
|
@@ -42,6 +50,24 @@ AI から使う場合は、`/spec-runner` のように「spec-runner を実行
|
|
|
42
50
|
|
|
43
51
|
---
|
|
44
52
|
|
|
53
|
+
## ドキュメントサイト(MkDocs + Material)
|
|
54
|
+
|
|
55
|
+
### `npx spec-runner` したプロジェクト側
|
|
56
|
+
|
|
57
|
+
憲章・設計書は `steps.json` どおり `docs/01_憲章/` 〜 `docs/06_API仕様/` に置かれる。`mkdocs.yml` の `docs/` がそのままサイトの文書ルートになるので、**追加コピーなしで**これらの Markdown をナビに載せられる(`nav` で先頭に固定した `index.md` の後ろへ、残りのページが自動で続く)。
|
|
58
|
+
|
|
59
|
+
プレビュー起動(Python 3 必須・仮想環境 `.venv-docs/` を使用):
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
./.spec-runner/scripts/docs-serve.sh
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`8000` が使用中のとき:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
DOCS_PORT=8001 ./.spec-runner/scripts/docs-serve.sh
|
|
69
|
+
```
|
|
70
|
+
|
|
45
71
|
## 導入後にできるもの
|
|
46
72
|
|
|
47
73
|
```
|
|
@@ -51,10 +77,13 @@ AI から使う場合は、`/spec-runner` のように「spec-runner を実行
|
|
|
51
77
|
│ ├── project.json # 設定(ブランチ命名・必須ドキュメント・テストコマンド等)
|
|
52
78
|
│ ├── phase-locks.json # フェーズの通過状態
|
|
53
79
|
│ ├── grade-history.json # グレード(LOOP1 / A / B / C)
|
|
54
|
-
│ ├── scripts/ # spec-runner-core.sh, check, branch,
|
|
80
|
+
│ ├── scripts/ # spec-runner-core.sh, check, branch, docs-serve.sh 等
|
|
55
81
|
│ ├── steps/ # 憲章・ドメイン設計・仕様策定・曖昧さ解消・テスト設計・実装 等の .md
|
|
56
82
|
│ └── templates/ # UC 仕様書ひな形
|
|
57
83
|
├── .claude/commands/spec-runner.md # Claude 用コマンド定義(/spec-runner)
|
|
84
|
+
├── mkdocs.yml # MkDocs(未有効時のみ配置)
|
|
85
|
+
├── requirements-docs.txt # mkdocs / mkdocs-material(未有効時のみ配置)
|
|
86
|
+
├── docs/ # 設計書(01..06)+ index.md 等。MkDocs の文書ルート
|
|
58
87
|
└── (AI は Claude Code 前提)
|
|
59
88
|
```
|
|
60
89
|
|
|
@@ -66,6 +95,7 @@ AI から使う場合は、`/spec-runner` のように「spec-runner を実行
|
|
|
66
95
|
- jq
|
|
67
96
|
- git
|
|
68
97
|
- bash 4.0+
|
|
98
|
+
- 設計書の MkDocs プレビュー: Python 3(`docs-serve.sh` が `python3` と venv を使用)
|
|
69
99
|
|
|
70
100
|
---
|
|
71
101
|
|
package/bin/spec-runner.js
CHANGED
|
@@ -19,6 +19,11 @@
|
|
|
19
19
|
* - templates/.spec-runner/project.json.example
|
|
20
20
|
* - templates/.spec-runner/templates/phase-locks.json
|
|
21
21
|
* - templates/.spec-runner/templates/grade-history.json
|
|
22
|
+
*
|
|
23
|
+
* MkDocs(任意・プロジェクトルート):
|
|
24
|
+
* - templates/mkdocs-scaffold/ の mkdocs.yml / requirements-docs.txt / docs/index.md を
|
|
25
|
+
* 未有効時のみコピー(憲章・設計書は既存の docs/01..06 をそのまま閲覧)
|
|
26
|
+
* - パッケージ同梱の docs/flow.md を docs/spec-runner-フロー.md としてコピー(未存在時のみ)
|
|
22
27
|
*/
|
|
23
28
|
|
|
24
29
|
const fs = require("fs");
|
|
@@ -31,6 +36,8 @@ const DEST_DIR = path.join(CWD, ".spec-runner");
|
|
|
31
36
|
const TEMPLATES_DIR = path.join(TEMPLATE_SPEC_RUNNER_DIR, "templates");
|
|
32
37
|
const PHASE_LOCKS_TEMPLATE = path.join(TEMPLATES_DIR, "phase-locks.json");
|
|
33
38
|
const GRADE_HISTORY_TEMPLATE = path.join(TEMPLATES_DIR, "grade-history.json");
|
|
39
|
+
const MKDOCS_SCAFFOLD_DIR = path.join(PKG_DIR, "templates", "mkdocs-scaffold");
|
|
40
|
+
const FLOW_DOC_SRC = path.join(PKG_DIR, "docs", "flow.md");
|
|
34
41
|
|
|
35
42
|
/** コピー時はスキップし、FORCE 時は消さない(ユーザー状態を保持) */
|
|
36
43
|
const USER_STATE_BASENAMES = new Set([
|
|
@@ -170,6 +177,57 @@ function installClaudeCommandIfPresent() {
|
|
|
170
177
|
ok(path.relative(CWD, claudeCmd));
|
|
171
178
|
}
|
|
172
179
|
|
|
180
|
+
/**
|
|
181
|
+
* MkDocs + Material 用のファイルをプロジェクトルートに配置(未存在時のみ)。
|
|
182
|
+
* 設計書本体は steps.json どおり docs/01..06 に置かれ、mkdocs の docs_dir でそのまま掲載する。
|
|
183
|
+
*/
|
|
184
|
+
function copyFileIfMissing(src, dest) {
|
|
185
|
+
if (!exists(src) || exists(dest)) return false;
|
|
186
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
187
|
+
fs.copyFileSync(src, dest);
|
|
188
|
+
ok(path.relative(CWD, dest));
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function appendGitignoreVenvDocsIfNeeded() {
|
|
193
|
+
const gitignorePath = path.join(CWD, ".gitignore");
|
|
194
|
+
const marker = ".venv-docs/";
|
|
195
|
+
if (!exists(gitignorePath)) return;
|
|
196
|
+
const raw = fs.readFileSync(gitignorePath, "utf8");
|
|
197
|
+
const lines = raw.split(/\r?\n/);
|
|
198
|
+
if (lines.some((line) => /^\.venv-docs\/?$/.test(line.trim()))) return;
|
|
199
|
+
fs.appendFileSync(
|
|
200
|
+
gitignorePath,
|
|
201
|
+
`\n# spec-runner: MkDocs 用 Python 仮想環境\n${marker}\n`,
|
|
202
|
+
"utf8",
|
|
203
|
+
);
|
|
204
|
+
ok(`${path.relative(CWD, gitignorePath)}(${marker} を追記)`);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function installMkdocsScaffold() {
|
|
208
|
+
if (!exists(MKDOCS_SCAFFOLD_DIR)) {
|
|
209
|
+
info("MkDocs テンプレート(templates/mkdocs-scaffold)が見つかりません。スキップします。");
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
info("MkDocs 用ファイル(不足分のみ)をプロジェクトルートに配置します...");
|
|
213
|
+
copyFileIfMissing(
|
|
214
|
+
path.join(MKDOCS_SCAFFOLD_DIR, "mkdocs.yml"),
|
|
215
|
+
path.join(CWD, "mkdocs.yml"),
|
|
216
|
+
);
|
|
217
|
+
copyFileIfMissing(
|
|
218
|
+
path.join(MKDOCS_SCAFFOLD_DIR, "requirements-docs.txt"),
|
|
219
|
+
path.join(CWD, "requirements-docs.txt"),
|
|
220
|
+
);
|
|
221
|
+
copyFileIfMissing(
|
|
222
|
+
path.join(MKDOCS_SCAFFOLD_DIR, "docs", "index.md"),
|
|
223
|
+
path.join(CWD, "docs", "index.md"),
|
|
224
|
+
);
|
|
225
|
+
if (exists(FLOW_DOC_SRC)) {
|
|
226
|
+
copyFileIfMissing(FLOW_DOC_SRC, path.join(CWD, "docs", "spec-runner-フロー.md"));
|
|
227
|
+
}
|
|
228
|
+
appendGitignoreVenvDocsIfNeeded();
|
|
229
|
+
}
|
|
230
|
+
|
|
173
231
|
function printBanner() {
|
|
174
232
|
log("");
|
|
175
233
|
log("╔════════════════════════════════════════╗");
|
|
@@ -180,6 +238,9 @@ function printBanner() {
|
|
|
180
238
|
}
|
|
181
239
|
|
|
182
240
|
function printFooter() {
|
|
241
|
+
log("");
|
|
242
|
+
log("設計書プレビュー(MkDocs + Material・プロジェクトルートの docs/):");
|
|
243
|
+
log(" ./.spec-runner/scripts/docs-serve.sh");
|
|
183
244
|
log("");
|
|
184
245
|
log("次のステップ(Claude Code 専用):");
|
|
185
246
|
log(" /spec-runner を実行して");
|
|
@@ -189,6 +250,7 @@ function printFooter() {
|
|
|
189
250
|
function main() {
|
|
190
251
|
printBanner();
|
|
191
252
|
ensureTemplateDirOrExit();
|
|
253
|
+
installMkdocsScaffold();
|
|
192
254
|
assertDestInstallableOrExit();
|
|
193
255
|
|
|
194
256
|
info(".spec-runner/ を展開しています...");
|
package/docs/flow.md
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# spec-runner の進め方(実装準拠)
|
|
2
|
+
|
|
3
|
+
このドキュメントは **リポジトリ内の実装**(`templates/.spec-runner/scripts/spec-runner-core.sh`、`steps/steps.json` 等)に沿って書いています。
|
|
4
|
+
「次のステップ」は **1 本のコマンド**が返す **1 つの `command_file`(`.spec-runner/steps/*.md`)** だけです。
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 入口コマンド(毎回)
|
|
9
|
+
|
|
10
|
+
| 用途 | コマンド(プロジェクトルート) |
|
|
11
|
+
|------|-------------------------------|
|
|
12
|
+
| 次のステップ(人間向けテキスト) | `./.spec-runner/spec-runner.sh` または `./.spec-runner/spec-runner.sh 次のステップ` |
|
|
13
|
+
| 次のステップ(JSON) | `./.spec-runner/spec-runner.sh 次のステップ --json` |
|
|
14
|
+
| Lock 一覧 | `./.spec-runner/spec-runner.sh 次のステップ --lock`(内部では `--status`) |
|
|
15
|
+
| グレード判定ガイド | `./.spec-runner/spec-runner.sh 次のステップ --グレード` |
|
|
16
|
+
|
|
17
|
+
- **やること**: 出力の `command_file` を開き、その `.md` の指示どおりに作業する。
|
|
18
|
+
- **毎回の検証**: `steps.json` の `common.commands.check` → 既定は `.spec-runner/scripts/check.sh`。
|
|
19
|
+
|
|
20
|
+
### `--json` の主なフィールド(実装どおり)
|
|
21
|
+
|
|
22
|
+
| フィールド | 意味 |
|
|
23
|
+
|------------|------|
|
|
24
|
+
| `phase` | 数値(`steps.json` の各 step の `phase` と概ね対応) |
|
|
25
|
+
| `phase_name_ja` | 表示用ラベル(コアが付与) |
|
|
26
|
+
| `step_id` | `steps.json` の `id`(例: `charter`, `uc_spec`, `clarify`) |
|
|
27
|
+
| `command` | ステップの日本語名(`name_ja`) |
|
|
28
|
+
| `command_file` | 絶対パス想定の `.spec-runner/steps/<md_file>` |
|
|
29
|
+
| `grade` | `grade-history.json` の `current_grade` |
|
|
30
|
+
| `check_command` | 毎回のチェック用シェルコマンド |
|
|
31
|
+
| `step_commands` | そのステップ用のコマンド配列(JSON) |
|
|
32
|
+
| `feature_dir` / `feature_spec` | UC ブランチ時、該当 UC のディレクトリ・仕様書パス(取れれば) |
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 状態の単一ソース
|
|
37
|
+
|
|
38
|
+
### `.spec-runner/phase-locks.json`
|
|
39
|
+
|
|
40
|
+
実際のキーは次のとおり(各オブジェクトに `completed`, `locked_at`, `reviewed_by` 等)。
|
|
41
|
+
|
|
42
|
+
| キー | 意味 |
|
|
43
|
+
|------|------|
|
|
44
|
+
| `charter` | 憲章フェーズ完了。ゲートでは `reviewed_by` も参照(LOOP1 時) |
|
|
45
|
+
| `domain` | ドメイン設計フェーズ完了 |
|
|
46
|
+
| `architecture` | アーキ(実装計画)フェーズ完了 |
|
|
47
|
+
| `infra` | インフラ詳細(Grade A)完了 |
|
|
48
|
+
| `test_design` | テスト設計ロック(ゲート側で参照) |
|
|
49
|
+
| `uc_discovery` | UC 洗い出し完了(`false` の間は domain に進まない) |
|
|
50
|
+
| `uc_reviewed` | **文字列の配列**。UC 仕様ファイルの **ベース名(拡張子なし)** が入ると「レビュー通過」とみなす(例: `UC-1-foo`) |
|
|
51
|
+
|
|
52
|
+
### `.spec-runner/grade-history.json`
|
|
53
|
+
|
|
54
|
+
- `current_grade`: `LOOP1` / `A` / `B` / `C` など(**ブランチ名には含めない**)
|
|
55
|
+
- Grade A のとき、UC レビュー通過後は **インフラ詳細(`infra_plan`)** が先に出る(`infra.completed` が付くまで)
|
|
56
|
+
|
|
57
|
+
### `.spec-runner/project.json`
|
|
58
|
+
|
|
59
|
+
- `naming`: ブランチ接頭辞 `branch_prefix`(既定 `feature`)、`uc_id_pattern`、`other_work_prefixes`(例: `work`, `infra`, `cicd`)
|
|
60
|
+
- `required_docs`: ゲート確認時の必須パス(`steps:charter` 形式で `steps.json` の `common.docs` を参照)
|
|
61
|
+
- `test_design.dir` / `test_design.pattern`(既定: `tests`, `*.spec.*`)
|
|
62
|
+
- `test_design.require_uc_prefixed_tests`(既定: キー省略時 **true**): **TDD 前提**。UC ブランチでは **`UC-N-` で始まり `pattern` に合致するテストファイル**が `test_design.dir` 内に無い限り **`test_design` のまま**(`implement` に進めない)。`false` にすると従来どおり「任意の spec が1つでもあれば実装」。
|
|
63
|
+
- `test_command.run`: **`require-tests-green.sh` が実行するテストコマンド**(実装完了の機械的条件)
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 「次のステップ」の分岐(`spec-runner-core.sh` の実際)
|
|
68
|
+
|
|
69
|
+
ブランチ種別・ロック・UC 有無・`uc_reviewed`・グレード・テストファイル有無で決まります。**紙の上の「常に UC→ドメイン→アーキ」の直線とは一致しません。**
|
|
70
|
+
|
|
71
|
+
### 1) UC ブランチ上(`feature/<UC-N>-<slug>` 形式)
|
|
72
|
+
|
|
73
|
+
1. 該当 `UC-N-*.md` が **まだ無い** → **`uc_spec`**(仕様策定)
|
|
74
|
+
2. 仕様はあるが **`uc_reviewed` にベース名が無い** → **`clarify`**(曖昧さ解消・レビュー通過まで)
|
|
75
|
+
3. レビュー済みかつ **`uc_discovery.completed` が false** → **`uc_spec`**(次UC作成)
|
|
76
|
+
4. レビュー済みかつ **Grade A かつ `infra.completed` でない** → **`infra_plan`**
|
|
77
|
+
5. それ以外で **当該 UC 用テストが未準備**(`require_uc_prefixed_tests` が true のときは **`UC-N-*.spec.*` 形式が1つ以上**)→ **`test_design`**
|
|
78
|
+
6. 上記を満たす → **`implement`**(あわせて **テストがグリーン**になるまで完了とみなさないのは `require-tests-green.sh` 側)
|
|
79
|
+
|
|
80
|
+
※ **ドメイン・アーキのロック未完了でも**、上記 UC ブランチ上では 3〜6 に進めます(コア実装どおり)。
|
|
81
|
+
|
|
82
|
+
### 2) UC ブランチではない(main 等)
|
|
83
|
+
|
|
84
|
+
実装では **次の順で最初に当てはまる分岐**が選ばれます(UC ブランチでも `other_work` ブランチでもない場合)。
|
|
85
|
+
|
|
86
|
+
1. **`charter.completed` でない**
|
|
87
|
+
- `docs/01_憲章/憲章.md` が無い → **`charter`**
|
|
88
|
+
- `docs/01_憲章/憲章.md` があり、`quality.clarified.charter` 未記録 → **`clarify`**(憲章の曖昧さ解消)
|
|
89
|
+
- `docs/01_憲章/憲章.md` があり、`quality.analyzed.charter` 未記録 → **`analyze`**(憲章の分析)
|
|
90
|
+
- 上記が記録済み → **`charter`**
|
|
91
|
+
2. **ドメイン未ロックかつ `uc_discovery.completed` が false** → **`uc_spec`**(次UC作成)
|
|
92
|
+
3. **ドメイン未ロックかつ `uc_discovery.completed` が true かつ `docs/02_...` に UC が 1 件以上**
|
|
93
|
+
- `docs/03_ドメイン設計/` に `.md` があり、`quality.clarified.domain` 未記録 → **`clarify`**
|
|
94
|
+
- `docs/03_ドメイン設計/` に `.md` があり、`quality.analyzed.domain` 未記録 → **`analyze`**
|
|
95
|
+
- 上記が記録済み、または `.md` が無い → **`domain`**
|
|
96
|
+
4. **ドメイン済みかつアーキ未ロック**
|
|
97
|
+
- `docs/04_アーキテクチャ/` に `.md` があり、`quality.clarified.architecture` 未記録 → **`clarify`**
|
|
98
|
+
- `docs/04_アーキテクチャ/` に `.md` があり、`quality.analyzed.architecture` 未記録 → **`analyze`**
|
|
99
|
+
- 上記が記録済み、または `.md` が無い → **`architecture_plan`**
|
|
100
|
+
5. **`other_work` 用ブランチ**(`feature/<other_work_prefix>/...`)かつ **2〜4 を通過済み** → **`other_work`**
|
|
101
|
+
6. **ドメイン未ロック**(この時点では UC が 0 件)→ **`uc_spec`**
|
|
102
|
+
7. **ドメイン・アーキともロック済み** → **`uc_spec`**(次の UC 開始)
|
|
103
|
+
|
|
104
|
+
要点:
|
|
105
|
+
|
|
106
|
+
- **初回**: main で UC がまだ無いと **6** で **`uc_spec`**。
|
|
107
|
+
- **UC がリポジトリに既にあるのにドメイン未ロック**(main で作業)→ `uc_discovery.completed=false` の間は **`uc_spec`** が先(`true` になってから **`domain`**)。
|
|
108
|
+
- **アーキ**は **ドメイン完了後**に **4** で出る。
|
|
109
|
+
|
|
110
|
+
### 3) 自動では選ばれないステップ(`steps.json` にのみ存在)
|
|
111
|
+
|
|
112
|
+
次の `id` は **コアの `run_phase` では返しません**。各 `.md`(仕様策定・テスト設計等)の **手順の中で**使う想定です。
|
|
113
|
+
|
|
114
|
+
- `analyze`(分析)
|
|
115
|
+
- `checklist`(チェックリスト)
|
|
116
|
+
- `task_list`(タスク一覧)
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## 成果物の置き場所(`steps.json` の `common.docs` と一致)
|
|
121
|
+
|
|
122
|
+
| キー | パス(既定) |
|
|
123
|
+
|------|----------------|
|
|
124
|
+
| 憲章 | `docs/01_憲章/憲章.md` |
|
|
125
|
+
| UC ルート | `docs/02_ユースケース仕様/<カテゴリ>/UC-N-<slug>.md` |
|
|
126
|
+
| ドメイン | `docs/03_ドメイン設計/`(ユビキタス言語辞書・ドメインモデル・集約 等) |
|
|
127
|
+
| アーキ | `docs/04_アーキテクチャ/` |
|
|
128
|
+
| インフラ | `docs/05_インフラ設計/`(例: `schema.dbml`) |
|
|
129
|
+
| API | `docs/06_API仕様/openapi.yaml` |
|
|
130
|
+
|
|
131
|
+
- UC ファイル名は **`UC-<N>-<slug>.md`**(`slug` は英数字・ハイフンが無難。ブランチ名も ASCII)。
|
|
132
|
+
- カテゴリフォルダ名は日本語可。
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## ディレクトリ構成(パッケージテンプレに近い形)
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
<プロジェクトルート>/
|
|
140
|
+
├── .spec-runner/
|
|
141
|
+
│ ├── spec-runner.sh
|
|
142
|
+
│ ├── project.json # 初回は project.json.example から
|
|
143
|
+
│ ├── phase-locks.json # 初回は templates/phase-locks.json から
|
|
144
|
+
│ ├── grade-history.json
|
|
145
|
+
│ ├── scripts/
|
|
146
|
+
│ │ ├── spec-runner-core.sh
|
|
147
|
+
│ │ ├── check.sh # --every / --full
|
|
148
|
+
│ │ ├── branch/uc-next-start.sh
|
|
149
|
+
│ │ └── test/require-tests-green.sh
|
|
150
|
+
│ ├── steps/ # *.md + steps.json
|
|
151
|
+
│ ├── templates/ # 憲章・UC・ドメイン雛形等
|
|
152
|
+
│ └── hooks/ # pre-commit / pre-push(任意)
|
|
153
|
+
├── docs/01_憲章/ … 06_API仕様/
|
|
154
|
+
├── tests/ # project.json の test_design.dir
|
|
155
|
+
└── src/
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
- **`npx spec-runner`**: `.spec-runner/` を展開し、**`.claude/commands/spec-runner.md` を配置**(テンプレに存在する場合)。`.cursor/` への自動配置は **インストーラでは行っていない**。
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## フェーズ番号とステップ(`steps.json`)
|
|
163
|
+
|
|
164
|
+
| phase | step_id(代表) | 内容 |
|
|
165
|
+
|-------|-----------------|------|
|
|
166
|
+
| 0 | `charter` | 憲章 |
|
|
167
|
+
| 1 | `uc_spec` / `other_work` | UC 仕様・その他ブランチ |
|
|
168
|
+
| 2 | `domain` | ドメイン設計 |
|
|
169
|
+
| 3 | `architecture_plan` | 実装計画(アーキ) |
|
|
170
|
+
| 4 | `infra_plan` | インフラ詳細(Grade A) |
|
|
171
|
+
| 5 | `test_design` | PENDING テスト |
|
|
172
|
+
| 6 | `implement` | 実装・テストグリーン |
|
|
173
|
+
|
|
174
|
+
`clarify`(曖昧さ解消)と `analyze`(分析)は `phase: null` の任意ステップとして扱い、必要なタイミングで実行できます。
|
|
175
|
+
|
|
176
|
+
補足: `clarify` / `analyze` の自動実行は `.spec-runner/phase-locks.json` の `quality` によって 1 度ずつ管理します。
|
|
177
|
+
(UC は `uc_reviewed` 未登録の間、`clarify -> analyze -> clarify ...` の品質ループを回せます)
|
|
178
|
+
|
|
179
|
+
### 実装完了(Phase 6)の機械的条件
|
|
180
|
+
|
|
181
|
+
- **手動または CI で** `.spec-runner/scripts/test/require-tests-green.sh` が **exit 0** であること。
|
|
182
|
+
- 中身は `project.json` の **`test_command.run`** のみを `eval` 実行(例: `npm test`)。
|
|
183
|
+
|
|
184
|
+
### ゲート(`spec-runner-core.sh --gate`)のメモ
|
|
185
|
+
|
|
186
|
+
ゲートログ上の「Phase 1/2」表現は **ドメイン=Phase 1、アーキ=Phase 2** のように **steps.json の phase 番号と一致しません**。ロック対象は `phase-locks.json` のキーで判断してください。
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## TDD が「どこまで」強制されるか
|
|
191
|
+
|
|
192
|
+
| レベル | 内容 |
|
|
193
|
+
|--------|------|
|
|
194
|
+
| **ゲート(次のステップ)** | 上記どおり **先に当該 UC の spec ファイルを置く**まで `implement` を出さない(`require_uc_prefixed_tests: true` 時)。 |
|
|
195
|
+
| **レッド→グリーンの順序** | **コミット順や「本番コードより先にアサーションを書いたか」は機械検査していない**。Phase 5 で PENDING/skip、Phase 6 で実装・グリーン、という **フェーズ順**での強制。 |
|
|
196
|
+
| **完了条件** | `require-tests-green.sh`(`test_command.run` 全通過)。 |
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## 理想運用 vs コードのギャップ(把握用)
|
|
201
|
+
|
|
202
|
+
| 観点 | よく言われる理想 | 実コード |
|
|
203
|
+
|------|------------------|----------|
|
|
204
|
+
| UC とドメインの順序 | 常に UC 全部 → ドメイン | `uc_discovery.completed=false` の間は次UC(`uc_spec`)→ `true` になってから domain |
|
|
205
|
+
| UC 実装前にアーキ必須 | あり | **UC ブランチ上では**ドメイン・アーキ未ロックでもテスト設計・実装に進む |
|
|
206
|
+
|
|
207
|
+
運用で「必ずドメイン→アーキ→UC 実装」にしたい場合は、**ロックを先に済ませてから** UC ブランチに入る、またはコアの分岐変更が必要です。
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## 日本語ドキュメント
|
|
212
|
+
|
|
213
|
+
`docs/` 配下の設計書は日本語で問題ありません。**Git 上はブランチ名・UC ファイルの slug は ASCII(kebab-case)推奨**です。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spec-runner",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.23",
|
|
4
4
|
"description": "フェーズ駆動で設計先行を強制。npx で .spec-runner を展開し、次のステップ .md に従って進める",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"files": [
|
|
27
27
|
"bin/",
|
|
28
28
|
"templates/",
|
|
29
|
+
"docs/flow.md",
|
|
29
30
|
"install.sh",
|
|
30
31
|
"README.md",
|
|
31
32
|
"LICENSE"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# MkDocs + Material で docs/ をプレビュー(プロジェクトルートで実行される想定)
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
|
6
|
+
cd "$ROOT"
|
|
7
|
+
|
|
8
|
+
DOCS_PORT="${DOCS_PORT:-8000}"
|
|
9
|
+
REQ="requirements-docs.txt"
|
|
10
|
+
|
|
11
|
+
if [[ ! -f "$REQ" ]]; then
|
|
12
|
+
echo "ERROR: ${REQ} が見つかりません。npx spec-runner を実行して MkDocs 用ファイルを展開してください。" >&2
|
|
13
|
+
exit 1
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
if [[ ! -d .venv-docs ]]; then
|
|
17
|
+
python3 -m venv .venv-docs
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
./.venv-docs/bin/pip install -q -r "$REQ"
|
|
21
|
+
exec ./.venv-docs/bin/mkdocs serve --dev-addr "127.0.0.1:${DOCS_PORT}"
|
|
@@ -71,6 +71,7 @@ has_charter_lock=0
|
|
|
71
71
|
has_domain_lock=0
|
|
72
72
|
has_arch_lock=0
|
|
73
73
|
has_infra_lock=0
|
|
74
|
+
uc_discovery_completed=0
|
|
74
75
|
grade=""
|
|
75
76
|
branch=""
|
|
76
77
|
test_dir=""
|
|
@@ -87,6 +88,7 @@ load_state() {
|
|
|
87
88
|
jq -e '.domain.completed == true' "$LOCK_FILE" >/dev/null 2>&1 && has_domain_lock=1
|
|
88
89
|
jq -e '.architecture.completed == true' "$LOCK_FILE" >/dev/null 2>&1 && has_arch_lock=1
|
|
89
90
|
jq -e '.infra.completed == true' "$LOCK_FILE" >/dev/null 2>&1 && has_infra_lock=1
|
|
91
|
+
jq -e '.uc_discovery.completed == true' "$LOCK_FILE" >/dev/null 2>&1 && uc_discovery_completed=1
|
|
90
92
|
|
|
91
93
|
grade=$(jq -r '.current_grade' "$GRADE_FILE")
|
|
92
94
|
[[ -n "$grade" && "$grade" != "null" ]] || die "spec-runner-core: grade-history.json の current_grade が未設定です"
|
|
@@ -286,7 +288,11 @@ run_phase() {
|
|
|
286
288
|
local kind="$1" # clarified | analyzed
|
|
287
289
|
local scope="$2" # charter | domain | architecture | uc
|
|
288
290
|
local key="$3"
|
|
289
|
-
|
|
291
|
+
# 互換性のため、quality には「ベース名」と「.md 付き」の両方を許容する
|
|
292
|
+
local key_md="${key}.md"
|
|
293
|
+
jq -e --arg k "$key" --arg km "$key_md" --arg s "$scope" \
|
|
294
|
+
".quality.${kind}[\$s][]? | select(. == \$k or . == \$km)" \
|
|
295
|
+
"$LOCK_FILE" >/dev/null 2>&1
|
|
290
296
|
}
|
|
291
297
|
|
|
292
298
|
resolve_step() {
|
|
@@ -328,21 +334,31 @@ run_phase() {
|
|
|
328
334
|
else
|
|
329
335
|
phase=0; phase_name_ja="憲章策定"; resolve_step "charter"
|
|
330
336
|
fi
|
|
331
|
-
elif [[ $has_domain_lock -eq 0 && $
|
|
332
|
-
|
|
333
|
-
if [[ -
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
if
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
337
|
+
elif [[ $has_domain_lock -eq 0 && $on_uc_branch -eq 0 ]]; then
|
|
338
|
+
# UC を洗い出している途中(uc_discovery.completed=false)の間はドメインへ進まない
|
|
339
|
+
if [[ $uc_discovery_completed -eq 0 ]]; then
|
|
340
|
+
phase=1; phase_name_ja="ユースケース洗い出し中(次UC作成)"; resolve_step "uc_spec"
|
|
341
|
+
else
|
|
342
|
+
# UC が 1 件以上ある場合のみ、ドメイン側の質フローを回す
|
|
343
|
+
if [[ ${uc_count_total} -gt 0 ]]; then
|
|
344
|
+
domain_spec="$(first_md_in_dir "$domain_root" || true)"
|
|
345
|
+
if [[ -n "$domain_spec" ]]; then
|
|
346
|
+
feature_spec="$domain_spec"
|
|
347
|
+
feature_dir="$(dirname "$domain_spec")"
|
|
348
|
+
dkey="$(doc_key "$domain_spec")"
|
|
349
|
+
if ! quality_done "clarified" "domain" "$dkey"; then
|
|
350
|
+
phase=2; phase_name_ja="ドメイン設計(曖昧さ解消)"; resolve_step "clarify"
|
|
351
|
+
elif ! quality_done "analyzed" "domain" "$dkey"; then
|
|
352
|
+
phase=2; phase_name_ja="ドメイン設計(分析)"; resolve_step "analyze"
|
|
353
|
+
else
|
|
354
|
+
phase=2; phase_name_ja="ドメイン設計"; resolve_step "domain"
|
|
355
|
+
fi
|
|
356
|
+
else
|
|
357
|
+
phase=2; phase_name_ja="ドメイン設計"; resolve_step "domain"
|
|
358
|
+
fi
|
|
341
359
|
else
|
|
342
|
-
phase=
|
|
360
|
+
phase=1; phase_name_ja="ユースケース洗い出し中(次UC作成)"; resolve_step "uc_spec"
|
|
343
361
|
fi
|
|
344
|
-
else
|
|
345
|
-
phase=2; phase_name_ja="ドメイン設計"; resolve_step "domain"
|
|
346
362
|
fi
|
|
347
363
|
elif [[ $has_arch_lock -eq 0 && $has_domain_lock -eq 1 ]]; then
|
|
348
364
|
arch_spec="$(first_md_in_dir "$architecture_root" || true)"
|
|
@@ -382,7 +398,10 @@ run_phase() {
|
|
|
382
398
|
phase=1; phase_name_ja="ユースケース仕様(レビュー通過まで)"; resolve_step "clarify"
|
|
383
399
|
fi
|
|
384
400
|
else
|
|
385
|
-
|
|
401
|
+
# UC 洗い出し中は、レビュー済みでも次の UC 作成へ戻す(TDD/実装に進まない)
|
|
402
|
+
if [[ $uc_discovery_completed -eq 0 ]]; then
|
|
403
|
+
phase=1; phase_name_ja="ユースケース洗い出し中(次UC作成)"; resolve_step "uc_spec"
|
|
404
|
+
elif [[ "$grade" == "A" ]] && [[ $has_infra_lock -eq 0 ]]; then
|
|
386
405
|
phase=4; phase_name_ja="インフラ詳細設計"; resolve_step "infra_plan"
|
|
387
406
|
else
|
|
388
407
|
if uc_branch_has_tests_ready_for_implement; then
|
|
@@ -429,7 +448,7 @@ run_status() {
|
|
|
429
448
|
echo "グレード: $grade"
|
|
430
449
|
echo ""
|
|
431
450
|
echo "Lock(.spec-runner/phase-locks.json):"
|
|
432
|
-
for sec in charter domain architecture infra test_design; do
|
|
451
|
+
for sec in charter domain architecture infra uc_discovery test_design; do
|
|
433
452
|
if jq -e --arg s "$sec" '.[$s].completed == true' "$LOCK_FILE" >/dev/null 2>&1; then
|
|
434
453
|
echo " ✓ $sec"
|
|
435
454
|
else
|
|
@@ -18,6 +18,7 @@ primary_output: docs/02_ユースケース仕様/<カテゴリ>/UC-N-xxx.md
|
|
|
18
18
|
## ユーザー入力
|
|
19
19
|
|
|
20
20
|
`$ARGUMENTS` が機能説明。空でコマンドしていない限り、繰り返し入力を求めない。
|
|
21
|
+
ただし **`$ARGUMENTS` が空** の場合は停止せず、AI 側で候補提案を行ってユーザー選択に進む。
|
|
21
22
|
|
|
22
23
|
```text
|
|
23
24
|
$ARGUMENTS
|
|
@@ -41,6 +42,17 @@ $ARGUMENTS
|
|
|
41
42
|
- まず作る 1 件(最小価値)
|
|
42
43
|
- 合意後は **1 件ずつ** `uc-next-start.sh` で作成する(CRUD は原則別 UC)。
|
|
43
44
|
|
|
45
|
+
### 0.5. 引数なし時の候補提示(必須)
|
|
46
|
+
|
|
47
|
+
- 条件: `$ARGUMENTS` が空。
|
|
48
|
+
- 挙動:
|
|
49
|
+
1. AI がこのプロジェクト向けの機能案を **3〜5 件**提示する。
|
|
50
|
+
2. 各案は 1 行で、`案N: 目的 / 主な利用者 / 想定カテゴリ` の形式で簡潔に示す。
|
|
51
|
+
3. 「番号で選択」または「自由入力で別案指定」を案内する。
|
|
52
|
+
4. **ユーザーが選ぶまで `uc-next-start.sh` を実行しない**。
|
|
53
|
+
- ユーザー回答後:
|
|
54
|
+
- 選択された案(または自由入力文)を今回の機能説明として扱い、以降のステップを通常どおり実行する。
|
|
55
|
+
|
|
44
56
|
### 1. ブランチ用短名(2〜4 語)
|
|
45
57
|
|
|
46
58
|
- 機能説明からキーワード抽出。**ブランチ名は ASCII のみ**、kebab-case(例: order-placement, user-auth)。
|
|
@@ -65,7 +77,7 @@ $ARGUMENTS
|
|
|
65
77
|
|
|
66
78
|
### 4. 本文生成の内訳
|
|
67
79
|
|
|
68
|
-
1.
|
|
80
|
+
1. 入力パース。空なら「0.5 引数なし時の候補提示」を実施し、選択後に続行する(即 ERROR にしない)
|
|
69
81
|
2. 重要概念(アクター・アクション・データ・制約)
|
|
70
82
|
3. 不明点: **推測で確定しない** → **`[要確認: ...]`**。付けるのは影響大・解釈複数・デフォルト無しのときのみ。**上限 3 個**。優先: スコープ > セキュリティ > UX > 技術詳細
|
|
71
83
|
4. 「ユーザーシナリオとテスト」を埋める。フロー特定できなければ ERROR
|
|
@@ -99,6 +111,8 @@ checklists を使う場合のみ `FEATURE_DIR/checklists/requirements.md` を生
|
|
|
99
111
|
|
|
100
112
|
※ 分解提案を経た場合は、採用された UC 分割案(採用順)も合わせて報告する。
|
|
101
113
|
|
|
114
|
+
※ **UC 洗い出しが完了したら** `./.spec-runner/phase-locks.json` の `uc_discovery.completed` を `true` にする(以降 `domain` に進む)。
|
|
115
|
+
|
|
102
116
|
**注**: スクリプトは書き込み前にブランチ作成・チェックアウトと仕様の初期化を行う。
|
|
103
117
|
|
|
104
118
|
## 付録 A: 仕様品質チェックリスト例
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# 設計ドキュメント
|
|
2
|
+
|
|
3
|
+
このサイトは **MkDocs Material** で、プロジェクトの `docs/` 配下にある **憲章・設計書・仕様** をまとめて閲覧するためのものです。
|
|
4
|
+
|
|
5
|
+
## spec-runner との対応(既定パス)
|
|
6
|
+
|
|
7
|
+
| 領域 | パス(プロジェクトルートから) |
|
|
8
|
+
|------|------------------------------|
|
|
9
|
+
| 憲章 | `docs/01_憲章/憲章.md` |
|
|
10
|
+
| ユースケース仕様 | `docs/02_ユースケース仕様/` |
|
|
11
|
+
| ドメイン設計 | `docs/03_ドメイン設計/` |
|
|
12
|
+
| アーキテクチャ | `docs/04_アーキテクチャ/` |
|
|
13
|
+
| インフラ設計 | `docs/05_インフラ設計/` |
|
|
14
|
+
| API 仕様 | `docs/06_API仕様/` |
|
|
15
|
+
|
|
16
|
+
手順・コマンド・ロックの考え方は **[spec-runner のフロー](spec-runner-フロー.md)** を参照してください(`npx spec-runner` 時にコピーされます)。
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## プレビュー起動
|
|
21
|
+
|
|
22
|
+
リポジトリルートで次を実行します(Python 3 と `requirements-docs.txt` 用の仮想環境 `.venv-docs/` が使われます)。
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
./.spec-runner/scripts/docs-serve.sh
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`8000` 番が使用中の場合はポートを変えられます。
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
DOCS_PORT=8001 ./.spec-runner/scripts/docs-serve.sh
|
|
32
|
+
```
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
site_name: プロジェクト設計ドキュメント
|
|
2
|
+
site_description: 憲章・ユースケース・ドメイン・アーキテクチャ等(spec-runner の docs/ 配下を閲覧)
|
|
3
|
+
theme:
|
|
4
|
+
name: material
|
|
5
|
+
language: ja
|
|
6
|
+
features:
|
|
7
|
+
- navigation.sections
|
|
8
|
+
- navigation.expand
|
|
9
|
+
- content.code.copy
|
|
10
|
+
markdown_extensions:
|
|
11
|
+
- admonition
|
|
12
|
+
- toc:
|
|
13
|
+
permalink: true
|
|
14
|
+
# 「ホーム」を先頭に固定し、それ以外の Markdown(01_憲章 … など)は MkDocs が自動でナビに追加
|
|
15
|
+
nav:
|
|
16
|
+
- ホーム: index.md
|