spec-runner 1.1.16 → 1.1.17
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/bin/spec-runner-installer.js +63 -0
- package/package.json +1 -1
- package/spec-runner/templates/.claude/rules/design-docs.md +21 -4
- package/spec-runner/templates/.claude/rules/harness-formats.md +7 -4
- package/spec-runner/templates/.claude/skills/architecture-definition/SKILL.md +42 -14
- package/spec-runner/templates/.claude/skills/architecture-skill-development/SKILL.md +19 -19
- package/spec-runner/templates/.claude/skills/design-change/SKILL.md +1 -0
- package/spec-runner/templates/.claude/skills/design-change/templates/90_ADR/ADR/343/203/206/343/203/263/343/203/227/343/203/254/343/203/274/343/203/210.md +0 -32
- package/spec-runner/templates/.claude/skills/docs-driven-seed/SKILL.md +7 -20
- package/spec-runner/templates/.claude/skills/docs-driven-seed/templates/01_/350/246/201/344/273/266/345/256/232/347/276/251//343/203/246/343/203/223/343/202/255/343/202/277/343/202/271/350/250/200/350/252/236/350/276/236/346/233/270.md +15 -0
- package/spec-runner/templates/.claude/skills/docs-driven-seed/templates/01_/350/246/201/344/273/266/345/256/232/347/276/251//350/246/201/344/273/266/345/256/232/347/276/251.md +34 -0
- package/spec-runner/templates/.claude/skills/docs-driven-seed/templates/02_/346/246/202/350/246/201/350/250/255/350/250/210//343/202/267/343/202/271/343/203/206/343/203/240/345/205/250/344/275/223/344/277/257/347/236/260.md +33 -0
- package/spec-runner/templates/.claude/skills/docs-driven-seed/templates/02_/346/246/202/350/246/201/350/250/255/350/250/210//343/203/211/343/203/241/343/202/244/343/203/263/343/203/242/343/203/207/343/203/253.md +32 -0
- package/spec-runner/templates/.claude/skills/docs-driven-seed/templates/02_/346/246/202/350/246/201/350/250/255/350/250/210//343/203/246/343/203/274/343/202/271/343/202/261/343/203/274/343/202/271/344/270/200/350/246/247.md +15 -0
- package/spec-runner/templates/.claude/skills/docs-driven-seed/templates/03_/350/251/263/347/264/260/350/250/255/350/250/210/01_/343/203/211/343/203/241/343/202/244/343/203/263/{/343/203/211/343/203/241/343/202/244/343/203/263/345/220/215}.md +17 -0
- package/spec-runner/templates/.claude/skills/simple-seed/SKILL.md +105 -0
- package/spec-runner/templates/.claude/skills/simple-seed/templates/03_/350/251/263/347/264/260/350/250/255/350/250/210/01_/343/203/246/343/203/274/343/202/271/343/202/261/343/203/274/343/202/271/UC-{/346/227/245/346/234/254/350/252/236/345/220/215}.md +53 -0
- package/spec-runner/templates/.github/instructions/design-docs.instructions.md +21 -4
- package/spec-runner/templates/.github/instructions/harness-formats.instructions.md +7 -4
- package/spec-runner/templates/.github/skills/architecture-definition/SKILL.md +42 -14
- package/spec-runner/templates/.github/skills/architecture-skill-development/SKILL.md +19 -19
- package/spec-runner/templates/.github/skills/design-change/SKILL.md +1 -0
- package/spec-runner/templates/.github/skills/design-change/templates/90_ADR/ADR/343/203/206/343/203/263/343/203/227/343/203/254/343/203/274/343/203/210.md +0 -32
- package/spec-runner/templates/.github/skills/docs-driven-seed/SKILL.md +7 -20
- package/spec-runner/templates/.github/skills/docs-driven-seed/templates/01_/350/246/201/344/273/266/345/256/232/347/276/251//343/203/246/343/203/223/343/202/255/343/202/277/343/202/271/350/250/200/350/252/236/350/276/236/346/233/270.md +15 -0
- package/spec-runner/templates/.github/skills/docs-driven-seed/templates/01_/350/246/201/344/273/266/345/256/232/347/276/251//350/246/201/344/273/266/345/256/232/347/276/251.md +34 -0
- package/spec-runner/templates/.github/skills/docs-driven-seed/templates/02_/346/246/202/350/246/201/350/250/255/350/250/210//343/202/267/343/202/271/343/203/206/343/203/240/345/205/250/344/275/223/344/277/257/347/236/260.md +33 -0
- package/spec-runner/templates/.github/skills/docs-driven-seed/templates/02_/346/246/202/350/246/201/350/250/255/350/250/210//343/203/211/343/203/241/343/202/244/343/203/263/343/203/242/343/203/207/343/203/253.md +32 -0
- package/spec-runner/templates/.github/skills/docs-driven-seed/templates/02_/346/246/202/350/246/201/350/250/255/350/250/210//343/203/246/343/203/274/343/202/271/343/202/261/343/203/274/343/202/271/344/270/200/350/246/247.md +15 -0
- package/spec-runner/templates/.github/skills/docs-driven-seed/templates/03_/350/251/263/347/264/260/350/250/255/350/250/210/01_/343/203/211/343/203/241/343/202/244/343/203/263/{/343/203/211/343/203/241/343/202/244/343/203/263/345/220/215}.md +17 -0
- package/spec-runner/templates/.github/skills/simple-seed/SKILL.md +105 -0
- package/spec-runner/templates/.github/skills/simple-seed/templates/03_/350/251/263/347/264/260/350/250/255/350/250/210/01_/343/203/246/343/203/274/343/202/271/343/202/261/343/203/274/343/202/271/UC-{/346/227/245/346/234/254/350/252/236/345/220/215}.md +53 -0
|
@@ -100,6 +100,55 @@ function filesEqual(a, b) {
|
|
|
100
100
|
return bufA.equals(bufB);
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
function mergeJsonDeep(base, override) {
|
|
104
|
+
const result = { ...base };
|
|
105
|
+
for (const [key, val] of Object.entries(override)) {
|
|
106
|
+
if (Array.isArray(val) && Array.isArray(result[key])) {
|
|
107
|
+
// 配列は重複を避けてマージ
|
|
108
|
+
const existing = result[key].map((item) => JSON.stringify(item));
|
|
109
|
+
const additions = val.filter((item) => !existing.includes(JSON.stringify(item)));
|
|
110
|
+
result[key] = [...result[key], ...additions];
|
|
111
|
+
} else if (val && typeof val === "object" && result[key] && typeof result[key] === "object") {
|
|
112
|
+
result[key] = mergeJsonDeep(result[key], val);
|
|
113
|
+
} else {
|
|
114
|
+
result[key] = val;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function copySettingsJsonWithMerge(src, dest, archiveRoot) {
|
|
121
|
+
if (!exists(dest)) {
|
|
122
|
+
writeFileText(dest, readFileText(src));
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
let existing, incoming;
|
|
126
|
+
try {
|
|
127
|
+
existing = JSON.parse(readFileText(dest));
|
|
128
|
+
incoming = JSON.parse(readFileText(src));
|
|
129
|
+
} catch {
|
|
130
|
+
// JSON パース失敗時は通常の copyFileWithPolicy にフォールバック
|
|
131
|
+
copyFileWithPolicy(src, dest, archiveRoot);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const merged = mergeJsonDeep(existing, incoming);
|
|
135
|
+
if (JSON.stringify(merged) === JSON.stringify(existing)) return; // 変更なし
|
|
136
|
+
if (FORCE && archiveRoot) {
|
|
137
|
+
const ap = archivePathFor(dest, archiveRoot);
|
|
138
|
+
ensureDir(path.dirname(ap));
|
|
139
|
+
fs.copyFileSync(dest, ap);
|
|
140
|
+
}
|
|
141
|
+
writeFileText(dest, JSON.stringify(merged, null, 2) + "\n");
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function appendToGitignore(lines, dest) {
|
|
145
|
+
let content = exists(dest) ? readFileText(dest) : "";
|
|
146
|
+
const additions = lines.filter((line) => !content.split("\n").includes(line));
|
|
147
|
+
if (additions.length === 0) return;
|
|
148
|
+
const sep = content === "" || content.endsWith("\n") ? "" : "\n";
|
|
149
|
+
writeFileText(dest, content + sep + additions.join("\n") + "\n");
|
|
150
|
+
}
|
|
151
|
+
|
|
103
152
|
function normalizeTarget(t) {
|
|
104
153
|
if (!t) return "";
|
|
105
154
|
const x = String(t).trim().toLowerCase();
|
|
@@ -247,6 +296,11 @@ function mirrorTreeTo(destRootDir, templateDir, archiveRoot) {
|
|
|
247
296
|
walkFiles(templateDir, (srcFile) => {
|
|
248
297
|
const rel = path.relative(templateDir, srcFile);
|
|
249
298
|
const destFile = path.join(destRootDir, rel);
|
|
299
|
+
// settings.json は上書きではなくマージ
|
|
300
|
+
if (path.basename(srcFile) === "settings.json") {
|
|
301
|
+
copySettingsJsonWithMerge(srcFile, destFile, archiveRoot);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
250
304
|
copyFileWithPolicy(srcFile, destFile, archiveRoot);
|
|
251
305
|
});
|
|
252
306
|
}
|
|
@@ -381,6 +435,15 @@ function main() {
|
|
|
381
435
|
copyFileWithPolicy(claudeMdSrc, path.join(CWD, "CLAUDE.md"), archiveRoot);
|
|
382
436
|
}
|
|
383
437
|
|
|
438
|
+
// .spec-runner/scripts を導入(target によらず常に配置)
|
|
439
|
+
const specRunnerTemplateDir = path.join(TEMPLATE_ROOT, ".spec-runner");
|
|
440
|
+
if (exists(specRunnerTemplateDir)) {
|
|
441
|
+
mirrorTreeTo(path.join(CWD, ".spec-runner"), specRunnerTemplateDir, archiveRoot);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// .gitignore に scan キャッシュを追記
|
|
445
|
+
appendToGitignore([".spec-runner/scan/"], path.join(CWD, ".gitignore"));
|
|
446
|
+
|
|
384
447
|
console.log("");
|
|
385
448
|
if (target === "claude" || target === "both") {
|
|
386
449
|
mirrorTreeTo(DEST_CLAUDE_DIR, CLAUDE_TEMPLATE_DIR, archiveRoot);
|
package/package.json
CHANGED
|
@@ -20,7 +20,7 @@ paths: ["docs/**"]
|
|
|
20
20
|
- **`docs/**` の全設計書に frontmatter を付ける**
|
|
21
21
|
- 正本の必須項目は `spec_runner.node_id` / `spec_runner.kind` / `spec_runner.depends_on` / `spec_runner.maps_to`
|
|
22
22
|
- `depends_on` はまず文字列配列でよい。依存理由が必要な場合のみオブジェクト形式を使う
|
|
23
|
-
- `maps_to` には見直し対象となる `src/` / `tests/` / IaC /
|
|
23
|
+
- `maps_to` には見直し対象となる `src/` / `tests/` / IaC / 設定ファイルを列挙する。**必ず設定する(空にしない)**。ただし ADR は決定の記録であり実装トレーサビリティの連鎖に乗らないため `depends_on` / `maps_to` は不要。ADR の frontmatter は `node_id` と `kind` のみ
|
|
24
24
|
- `modules` / `source_files` などの拡張項目を足す場合でも、`maps_to` と矛盾させない
|
|
25
25
|
|
|
26
26
|
```yaml
|
|
@@ -65,7 +65,7 @@ spec_runner:
|
|
|
65
65
|
|
|
66
66
|
## ADR
|
|
67
67
|
|
|
68
|
-
- **ADR
|
|
68
|
+
- **ADR は提案時に必ず 3 案を比較してから採用案を決める。ドキュメントには採用案と採用理由のみ記録する**
|
|
69
69
|
- ADR は `docs/02_概要設計/90_ADR/{対象}/` で管理する(`全体` / `ドメイン` / `UC` / `DB`)
|
|
70
70
|
- ファイル名は `mmdd-{日本語タイトル}.md`。対象はフォルダで表す
|
|
71
71
|
- ADR は理由の記録であり、詳細設計の代わりにしない
|
|
@@ -73,8 +73,25 @@ spec_runner:
|
|
|
73
73
|
|
|
74
74
|
## 文書品質
|
|
75
75
|
|
|
76
|
-
-
|
|
77
|
-
-
|
|
76
|
+
- **docs にコードを書かない。コード片・DDL・クラス定義・プロンプト本文はすべて禁止。コードは `src/` / `tests/` に書く**
|
|
77
|
+
- **概要設計では「何をするか」を書き、実装の詳細は持ち込まない**
|
|
78
|
+
- **詳細設計ではドメインルール・UC の責務・入出力・判断条件・テスト観点を書く**
|
|
78
79
|
- **`maps_to` を唯一の src 対応として使う。パス推定に頼らない**
|
|
79
80
|
- **Markdown に HTML タグ(details, summary, br など)を使わない**
|
|
81
|
+
- **設計書に絵文字を使わない**
|
|
80
82
|
- **`概要.md` のような汎用的な名前のファイルは作らない。内容を具体的に示す名前(`要件定義.md`、`ユースケース一覧.md`、`システム全体俯瞰.md` など)を使う**
|
|
83
|
+
- **「関連ドキュメント」セクションを設計書に作らない。依存関係は frontmatter の `depends_on` で管理する**
|
|
84
|
+
- **「スケジュール」セクションを設計書に作らない。進捗管理は設計書の責務ではない**
|
|
85
|
+
|
|
86
|
+
## ドメインモデルとデータモデルの分離
|
|
87
|
+
|
|
88
|
+
ドメインモデルとデータモデルは**別物**であり、置き場所も内容も分ける。
|
|
89
|
+
|
|
90
|
+
| 種別 | 内容 | 置き場所 |
|
|
91
|
+
|------|------|---------|
|
|
92
|
+
| ドメインモデル | ビジネスルール・集約・値オブジェクト・不変条件 | `docs/03_詳細設計/01_ドメイン/` |
|
|
93
|
+
| データモデル | DBスキーマ・テーブル定義・カラム定義・インデックス | `docs/03_詳細設計/03_DB・外部サービス/` |
|
|
94
|
+
|
|
95
|
+
- **`01_ドメイン/` にDBスキーマ・テーブル定義・カラム定義を書かない**
|
|
96
|
+
- **`03_DB・外部サービス/` にビジネスルール・ドメインロジックを書かない**
|
|
97
|
+
- 概要設計の `ドメインモデル.md` も同様。集約と境界コンテキストの概念図であり、永続化の構造ではない
|
|
@@ -21,7 +21,7 @@ paths: ["対象パス/**"] # 省略すると全ファイルに適用
|
|
|
21
21
|
|
|
22
22
|
- `description` は必須。Claude がルールを選択するときに使う
|
|
23
23
|
- `paths` は省略可。省略すると `**` 相当(全ファイルに適用)
|
|
24
|
-
-
|
|
24
|
+
- `integrations` に `github` が含まれる場合、対応する `.github/instructions/{name}.instructions.md` も作成・更新する
|
|
25
25
|
- `.github/` 版の frontmatter は `applyTo: "対象パス/**"` 形式に変換する
|
|
26
26
|
|
|
27
27
|
## agent ファイル(`.claude/agents/*.md`)
|
|
@@ -42,7 +42,7 @@ model: sonnet # 通常は sonnet
|
|
|
42
42
|
- `description` はトリガー型で書く(「〇〇のときに自動で呼ぶ」形式)
|
|
43
43
|
- `tools` は最小権限原則。読み取りのみなら `Read, Grep, Glob`
|
|
44
44
|
- 書き込みが必要な場合のみ `Edit, Write` を追加する
|
|
45
|
-
-
|
|
45
|
+
- `integrations` に `github` が含まれる場合、対応する `.github/agents/{name}.agent.md` も作成・更新する
|
|
46
46
|
|
|
47
47
|
## skill ファイル(`.claude/skills/{name}/SKILL.md`)
|
|
48
48
|
|
|
@@ -58,7 +58,7 @@ description: このスキルの目的と使うタイミング(1〜2行)
|
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
- `description` は Claude がスキルを選択するときに使う。「いつ使うか」を含める
|
|
61
|
-
-
|
|
61
|
+
- `integrations` に `github` が含まれる場合、対応する `.github/skills/{name}/SKILL.md` も作成・更新する
|
|
62
62
|
|
|
63
63
|
## CLAUDE.md
|
|
64
64
|
|
|
@@ -85,6 +85,9 @@ CLAUDE.md は**全会話で常にコンテキストに読み込まれる**。書
|
|
|
85
85
|
|
|
86
86
|
## 共通原則
|
|
87
87
|
|
|
88
|
-
-
|
|
88
|
+
- **更新する連携先は `architecture.yaml` の `integrations` に従う**
|
|
89
|
+
- `claude` のみ → `.claude/` だけ更新する。`.github/` を作成しない
|
|
90
|
+
- `github` のみ → `.github/` だけ更新する。`.claude/` を作成しない
|
|
91
|
+
- 両方 → `.claude/` と `.github/` を対で更新する
|
|
89
92
|
- `description` は「何をするか」より「**いつ・なぜ使うか**」を優先して書く
|
|
90
93
|
- 新規作成時は既存ファイルを参考にフォーマットを確認してから作る
|
|
@@ -6,31 +6,54 @@ description: 新規プロジェクトで docs と `.spec-runner/architecture/arc
|
|
|
6
6
|
# architecture-definition
|
|
7
7
|
|
|
8
8
|
新規プロジェクト向けの初期化フロー。
|
|
9
|
-
|
|
9
|
+
要件定義・フォルダ構造の決定・architecture contract の作成までを先に固め、スキル整備を経てから概要設計へ進む。
|
|
10
10
|
|
|
11
11
|
## 全体フロー
|
|
12
12
|
|
|
13
13
|
```
|
|
14
14
|
Phase 1: 要件整理
|
|
15
|
-
Phase 2:
|
|
15
|
+
Phase 2: フォルダ構造の決定(対話)
|
|
16
16
|
Phase 3: アーキテクチャ判断の明文化
|
|
17
17
|
Phase 4: architecture contract 作成
|
|
18
|
-
Phase 5:
|
|
18
|
+
Phase 5: architecture-skill-development へ自動移行
|
|
19
|
+
└→ スキル整備完了後、プロジェクト専用スキルで概要設計へ進む
|
|
19
20
|
```
|
|
20
21
|
|
|
21
22
|
## Phase 1: 要件整理
|
|
22
23
|
|
|
24
|
+
テンプレート: `.claude/skills/docs-driven-seed/templates/01_要件定義/`
|
|
25
|
+
|
|
23
26
|
1. ユーザーから背景、提供価値、制約、スコープ外を確認する
|
|
24
|
-
2. `docs/01_要件定義/要件定義.md` を作る
|
|
25
|
-
3.
|
|
26
|
-
4.
|
|
27
|
+
2. テンプレートをコピーして `docs/01_要件定義/要件定義.md` を作る
|
|
28
|
+
3. ドメイン用語が出てきたら `docs/01_要件定義/ユビキタス言語辞書.md` に随時追記する
|
|
29
|
+
4. アーキテクチャスタイルを選択する
|
|
30
|
+
|
|
31
|
+
| スタイル | 選ぶ基準 |
|
|
32
|
+
|---------|---------|
|
|
33
|
+
| `ddd` | 複雑なビジネスドメインがある。集約・境界コンテキストで設計する必要がある |
|
|
34
|
+
| `layered` | CRUD 中心またはビジネスロジックがシンプル。UC・サービス層で設計すれば十分 |
|
|
35
|
+
|
|
36
|
+
5. 使用する AI 連携を確認する
|
|
37
|
+
|
|
38
|
+
| 連携 | フォルダ |
|
|
39
|
+
|------|---------|
|
|
40
|
+
| `claude` | `.claude/`(Claude Code) |
|
|
41
|
+
| `github` | `.github/`(GitHub Copilot) |
|
|
42
|
+
| 両方 | `.claude/` と `.github/` |
|
|
27
43
|
|
|
28
|
-
|
|
44
|
+
6. ユーザーに確認・承認を得る
|
|
29
45
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
46
|
+
## Phase 2: フォルダ構造の決定
|
|
47
|
+
|
|
48
|
+
対話でプロジェクトのフォルダ構造を決める。この段階で決めた構造がテンプレートの `maps_to` パスに焼き込まれるため、概要設計より前に確定させる。
|
|
49
|
+
|
|
50
|
+
1. 以下をユーザーと対話しながら決める
|
|
51
|
+
- `src/` 配下のパッケージ・モジュール構成
|
|
52
|
+
- `tests/` の種別ディレクトリ構成(`unit/` / `integration/` / `e2e/` など)
|
|
53
|
+
- `docs/` の構成(デフォルトから変える場合)
|
|
54
|
+
- その他プロジェクト固有のディレクトリ(IaC、設定ファイルなど)
|
|
55
|
+
2. 決定した構造を箇条書きでまとめてユーザーに提示する
|
|
56
|
+
3. ユーザーに確認・承認を得る
|
|
34
57
|
|
|
35
58
|
## Phase 3: アーキテクチャ判断の明文化
|
|
36
59
|
|
|
@@ -42,7 +65,10 @@ Phase 5: 次の skill へ引き渡し
|
|
|
42
65
|
|
|
43
66
|
1. `.spec-runner/architecture/architecture.yaml` を作る
|
|
44
67
|
2. 最低限、以下を構造化する
|
|
45
|
-
-
|
|
68
|
+
- **integrations**: Phase 1 で確認した連携(`[claude]` / `[github]` / `[claude, github]`)
|
|
69
|
+
- **style**: Phase 1 で選択したスタイル(`ddd` / `layered`)
|
|
70
|
+
- **folder_structure**: Phase 2 で決定した構造
|
|
71
|
+
- domain_structure(style: ddd のときのみ)
|
|
46
72
|
- runtime_units
|
|
47
73
|
- design_policy
|
|
48
74
|
- testing_policy
|
|
@@ -52,12 +78,14 @@ Phase 5: 次の skill へ引き渡し
|
|
|
52
78
|
|
|
53
79
|
Phase 4 が承認されたら、**ユーザーにコマンドを打たせずに `architecture-skill-development` を続けて開始する**。
|
|
54
80
|
|
|
55
|
-
1. `architecture-skill-development` に渡す前提(docs
|
|
81
|
+
1. `architecture-skill-development` に渡す前提(docs・architecture.yaml・確定済みフォルダ構造)を要約する
|
|
56
82
|
2. project 専用 skill に切り出すべき反復フローを列挙する
|
|
57
83
|
3. 確認なしに `architecture-skill-development` Phase 1 へ進む
|
|
84
|
+
4. **スキル整備完了後、プロジェクト専用スキルを使って概要設計へ進む**
|
|
58
85
|
|
|
59
86
|
## 原則
|
|
60
87
|
|
|
61
|
-
-
|
|
88
|
+
- フォルダ構造を概要設計より前に確定する
|
|
89
|
+
- スキル整備が完了してから概要設計へ進む(テンプレートの `maps_to` を確定済み構造で焼き込むため)
|
|
62
90
|
- `.spec-runner/` は補助情報として扱う
|
|
63
91
|
- project 専用 skill を作る前にアーキテクチャを固める
|
|
@@ -15,14 +15,13 @@ Phase 1: 入力の確認
|
|
|
15
15
|
Phase 2: 反復フローの抽出
|
|
16
16
|
Phase 3: skill / rule / template へ分解
|
|
17
17
|
Phase 4: 基盤 skill のプロジェクト固有化
|
|
18
|
-
Phase 5:
|
|
19
|
-
Phase 6:
|
|
20
|
-
Phase 7: セットアップ専用 skill のアーカイブ提案
|
|
18
|
+
Phase 5: 一貫性の検証
|
|
19
|
+
Phase 6: セットアップ専用 skill のアーカイブ提案
|
|
21
20
|
```
|
|
22
21
|
|
|
23
22
|
## Phase 1: 入力の確認
|
|
24
23
|
|
|
25
|
-
1. `docs/01_
|
|
24
|
+
1. `docs/01_要件定義/**` を読む
|
|
26
25
|
2. `.spec-runner/architecture/architecture.yaml` を読む
|
|
27
26
|
3. 固定化すべき判断と project 固有判断を切り分ける
|
|
28
27
|
|
|
@@ -41,18 +40,24 @@ Phase 7: セットアップ専用 skill のアーカイブ提案
|
|
|
41
40
|
2. 常時守る約束は rule にする
|
|
42
41
|
3. 毎回コピーする設計書は template にする
|
|
43
42
|
|
|
44
|
-
###
|
|
43
|
+
### seed の選択
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
`architecture.yaml` の `style` を読み、使う seed を決める。
|
|
46
|
+
|
|
47
|
+
| style | 使う seed | 説明 |
|
|
48
|
+
|-------|----------|------|
|
|
49
|
+
| `ddd` | `docs-driven-seed` | ドメイン層(集約・値オブジェクト)を持つ DDD 向けフロー |
|
|
50
|
+
| `layered` | `simple-seed` | ドメイン層を持たない UC・サービス層中心のフロー |
|
|
51
|
+
|
|
52
|
+
選んだ seed の SKILL.md をコピーして、**このプロジェクトのアーキテクチャに合わせて書き換えた project 専用 skill を作る**ことを目的とする。
|
|
49
53
|
|
|
50
54
|
具体的には:
|
|
51
|
-
-
|
|
55
|
+
- 選んだ seed の SKILL.md をコピーして、project 専用の開発 skill の土台にする
|
|
52
56
|
- フェーズ構成・テンプレートパス・用語をこのプロジェクトの実態に合わせて書き換える
|
|
53
|
-
-
|
|
57
|
+
- **Phase 1(要件定義)は architecture-definition で完了済みのため削除する**
|
|
58
|
+
- 元の seed は書き換え完了後にアーカイブ候補とする(Phase 6 で提案する)
|
|
54
59
|
|
|
55
|
-
ユーザーに確認・承認を得る
|
|
60
|
+
4. ユーザーに確認・承認を得る
|
|
56
61
|
|
|
57
62
|
## Phase 4: 基盤 skill のプロジェクト固有化
|
|
58
63
|
|
|
@@ -88,19 +93,14 @@ Phase 7: セットアップ専用 skill のアーカイブ提案
|
|
|
88
93
|
|
|
89
94
|
同様のプレースホルダーや汎用記述が他の skill にあれば、同じ要領で書き換える。
|
|
90
95
|
|
|
91
|
-
ユーザーに確認・承認を得る
|
|
92
|
-
|
|
93
|
-
## Phase 5: Claude / Copilot テンプレートへ反映
|
|
94
|
-
|
|
95
|
-
1. `.claude/` と `.github/` の両方へ反映する
|
|
96
|
-
2. path や naming がずれないよう対応ファイルを揃える
|
|
96
|
+
5. ユーザーに確認・承認を得る
|
|
97
97
|
|
|
98
|
-
## Phase
|
|
98
|
+
## Phase 5: 一貫性の検証
|
|
99
99
|
|
|
100
100
|
1. 既存 skill / rule / agent と矛盾しないか確認する
|
|
101
101
|
2. `harness-engineering` が必要な改善点を洗い出す
|
|
102
102
|
|
|
103
|
-
## Phase
|
|
103
|
+
## Phase 6: セットアップ専用 skill のアーカイブ提案
|
|
104
104
|
|
|
105
105
|
セットアップ時にしか使わない skill は、開発ループに入ると不要になる。
|
|
106
106
|
**ユーザーの承認を得てから** 整理する。絶対に自動で削除・移動しない。
|
|
@@ -2,9 +2,6 @@
|
|
|
2
2
|
spec_runner:
|
|
3
3
|
node_id: adr.{decision_slug}
|
|
4
4
|
kind: adr
|
|
5
|
-
depends_on:
|
|
6
|
-
- overview.system_context
|
|
7
|
-
maps_to: []
|
|
8
5
|
---
|
|
9
6
|
|
|
10
7
|
# {決定内容のタイトル}
|
|
@@ -21,35 +18,6 @@ spec_runner:
|
|
|
21
18
|
| 要件 | {実現する必要があること} |
|
|
22
19
|
| 制約 | {技術的・ビジネス的制約} |
|
|
23
20
|
|
|
24
|
-
## 選択肢
|
|
25
|
-
|
|
26
|
-
### 案1: {案1の名前}
|
|
27
|
-
|
|
28
|
-
- 概要: {何をするか}
|
|
29
|
-
- メリット:
|
|
30
|
-
- {メリット}
|
|
31
|
-
- デメリット:
|
|
32
|
-
- {デメリット}
|
|
33
|
-
- 適合性: {このプロジェクトにどう合うか}
|
|
34
|
-
|
|
35
|
-
### 案2: {案2の名前}
|
|
36
|
-
|
|
37
|
-
- 概要: {何をするか}
|
|
38
|
-
- メリット:
|
|
39
|
-
- {メリット}
|
|
40
|
-
- デメリット:
|
|
41
|
-
- {デメリット}
|
|
42
|
-
- 適合性: {このプロジェクトにどう合うか}
|
|
43
|
-
|
|
44
|
-
### 案3: {案3の名前}
|
|
45
|
-
|
|
46
|
-
- 概要: {何をするか}
|
|
47
|
-
- メリット:
|
|
48
|
-
- {メリット}
|
|
49
|
-
- デメリット:
|
|
50
|
-
- {デメリット}
|
|
51
|
-
- 適合性: {このプロジェクトにどう合うか}
|
|
52
|
-
|
|
53
21
|
## 決定
|
|
54
22
|
|
|
55
23
|
**採用案**: {案名}
|
|
@@ -5,8 +5,8 @@ description: UC/DDD 駆動の docs 正本開発フローの種。新規プロジ
|
|
|
5
5
|
|
|
6
6
|
# docs-driven-seed
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
**DDD(ドメイン駆動設計)を採用するプロジェクト向け**の docs 正本開発フロー参照実装(種)。
|
|
9
|
+
`architecture.yaml` の `style: ddd` のときに使う。レイヤード / CRUD 中心のプロジェクトは `simple-seed` を使う。
|
|
10
10
|
|
|
11
11
|
**このスキルをそのまま使い続けない。`architecture-skill-development` で自プロジェクト専用スキルに育てることを前提とする。**
|
|
12
12
|
|
|
@@ -30,22 +30,7 @@ Phase 5: TDD → 実装
|
|
|
30
30
|
|
|
31
31
|
## Phase 1: 要件定義
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
- 解決すべき課題・提供価値
|
|
35
|
-
- 対象ユーザー
|
|
36
|
-
- 非機能要件・スコープ外
|
|
37
|
-
- 技術・ビジネス制約
|
|
38
|
-
2. `docs/01_要件定義/要件定義.md` を作る
|
|
39
|
-
3. ドメイン用語が出てきたら `docs/01_要件定義/ユビキタス言語辞書.md` に随時追記する
|
|
40
|
-
4. ユーザーに確認・承認を得る
|
|
41
|
-
|
|
42
|
-
### 出力
|
|
43
|
-
|
|
44
|
-
```
|
|
45
|
-
docs/01_要件定義/
|
|
46
|
-
要件定義.md
|
|
47
|
-
ユビキタス言語辞書.md
|
|
48
|
-
```
|
|
33
|
+
`architecture-definition` で完了済み。`docs/01_要件定義/` が存在することを確認して次へ進む。
|
|
49
34
|
|
|
50
35
|
## Phase 2: 概要設計
|
|
51
36
|
|
|
@@ -63,6 +48,8 @@ docs/01_要件定義/
|
|
|
63
48
|
|
|
64
49
|
### 出力
|
|
65
50
|
|
|
51
|
+
テンプレート: `templates/02_概要設計/ユースケース一覧.md` / `templates/02_概要設計/ドメインモデル.md` / `templates/02_概要設計/システム全体俯瞰.md`
|
|
52
|
+
|
|
66
53
|
```
|
|
67
54
|
docs/02_概要設計/
|
|
68
55
|
ユースケース一覧.md
|
|
@@ -78,7 +65,7 @@ docs/02_概要設計/
|
|
|
78
65
|
## Phase 3: ADR(必要時のみ)
|
|
79
66
|
|
|
80
67
|
1. 設計判断が必要な場合だけ ADR を作る
|
|
81
|
-
2.
|
|
68
|
+
2. **提案時に必ず 3 案を比較する。ドキュメントには採用案と採用理由のみ記録する**
|
|
82
69
|
3. ファイル名は `mmdd-{日本語タイトル}.md`、配置先は対象フォルダ
|
|
83
70
|
|
|
84
71
|
| 対象 | 配置先 |
|
|
@@ -122,7 +109,7 @@ docs/03_詳細設計/03_DB・外部サービス/
|
|
|
122
109
|
外部サービス.md
|
|
123
110
|
```
|
|
124
111
|
|
|
125
|
-
ユーザーに確認・承認を得る
|
|
112
|
+
4. ユーザーに確認・承認を得る
|
|
126
113
|
|
|
127
114
|
## Phase 5: TDD → 実装
|
|
128
115
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
spec_runner:
|
|
3
|
+
node_id: requirement.要件定義
|
|
4
|
+
kind: requirement
|
|
5
|
+
depends_on: []
|
|
6
|
+
maps_to:
|
|
7
|
+
- docs/02_概要設計/
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# 要件定義
|
|
11
|
+
|
|
12
|
+
## 解決すべき課題・提供価値
|
|
13
|
+
|
|
14
|
+
- {課題}
|
|
15
|
+
- {提供価値}
|
|
16
|
+
|
|
17
|
+
## 対象ユーザー
|
|
18
|
+
|
|
19
|
+
- {ユーザー種別}: {説明}
|
|
20
|
+
|
|
21
|
+
## 非機能要件
|
|
22
|
+
|
|
23
|
+
| 項目 | 内容 |
|
|
24
|
+
|------|------|
|
|
25
|
+
| {パフォーマンス} | {要件} |
|
|
26
|
+
| {セキュリティ} | {要件} |
|
|
27
|
+
|
|
28
|
+
## スコープ外
|
|
29
|
+
|
|
30
|
+
- {スコープ外の機能・要件}
|
|
31
|
+
|
|
32
|
+
## 技術・ビジネス制約
|
|
33
|
+
|
|
34
|
+
- {制約}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
spec_runner:
|
|
3
|
+
node_id: overview.system_context
|
|
4
|
+
kind: overview_design
|
|
5
|
+
depends_on:
|
|
6
|
+
- overview.domain_model
|
|
7
|
+
maps_to:
|
|
8
|
+
- src/
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# システム全体俯瞰
|
|
12
|
+
|
|
13
|
+
## コンポーネント全体図
|
|
14
|
+
|
|
15
|
+
```mermaid
|
|
16
|
+
graph LR
|
|
17
|
+
User([ユーザー])
|
|
18
|
+
subgraph システム
|
|
19
|
+
{フロントエンド}
|
|
20
|
+
{バックエンド}
|
|
21
|
+
end
|
|
22
|
+
Ext([{外部サービス}])
|
|
23
|
+
|
|
24
|
+
User --> {フロントエンド}
|
|
25
|
+
{フロントエンド} --> {バックエンド}
|
|
26
|
+
{バックエンド} --> Ext
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 外部インターフェース
|
|
30
|
+
|
|
31
|
+
| 外部システム | 方向 | プロトコル | 概要 |
|
|
32
|
+
|------------|------|----------|------|
|
|
33
|
+
| {外部システム名} | 受信 / 送信 | {HTTP / gRPC など} | {概要} |
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
spec_runner:
|
|
3
|
+
node_id: overview.domain_model
|
|
4
|
+
kind: overview_design
|
|
5
|
+
depends_on:
|
|
6
|
+
- overview.use_case_list
|
|
7
|
+
maps_to:
|
|
8
|
+
- docs/03_詳細設計/01_ドメイン/
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# ドメインモデル
|
|
12
|
+
|
|
13
|
+
集約と境界コンテキストの概念モデル。DBスキーマ・永続化の詳細はここに書かない。
|
|
14
|
+
|
|
15
|
+
## 境界コンテキスト
|
|
16
|
+
|
|
17
|
+
```mermaid
|
|
18
|
+
graph LR
|
|
19
|
+
subgraph {コンテキストA}
|
|
20
|
+
{集約A}
|
|
21
|
+
end
|
|
22
|
+
subgraph {コンテキストB}
|
|
23
|
+
{集約B}
|
|
24
|
+
end
|
|
25
|
+
{コンテキストA} -->|下流| {コンテキストB}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 集約一覧
|
|
29
|
+
|
|
30
|
+
| 境界コンテキスト | 集約 | 責務 |
|
|
31
|
+
|----------------|------|------|
|
|
32
|
+
| {コンテキスト名} | {集約名} | {責務} |
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
spec_runner:
|
|
3
|
+
node_id: overview.use_case_list
|
|
4
|
+
kind: overview_design
|
|
5
|
+
depends_on:
|
|
6
|
+
- requirement.要件定義
|
|
7
|
+
maps_to:
|
|
8
|
+
- docs/03_詳細設計/02_ユースケース/
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# ユースケース一覧
|
|
12
|
+
|
|
13
|
+
| UC ID | UC名 | 種別 | 概要 |
|
|
14
|
+
|-------|------|------|------|
|
|
15
|
+
| UC-{番号} | {UC名} | Command / Query | {概要} |
|
|
@@ -17,6 +17,23 @@ spec_runner:
|
|
|
17
17
|
|
|
18
18
|
## 集約
|
|
19
19
|
|
|
20
|
+
```mermaid
|
|
21
|
+
classDiagram
|
|
22
|
+
class {集約ルート} {
|
|
23
|
+
+{ID型} id
|
|
24
|
+
+{値オブジェクト} {フィールド名}
|
|
25
|
+
+{操作}() {戻り値型}
|
|
26
|
+
}
|
|
27
|
+
class {エンティティ} {
|
|
28
|
+
+{ID型} id
|
|
29
|
+
}
|
|
30
|
+
class {値オブジェクト} {
|
|
31
|
+
+{型} {フィールド名}
|
|
32
|
+
}
|
|
33
|
+
{集約ルート} "1" --> "0..*" {エンティティ} : 含む
|
|
34
|
+
{集約ルート} --> {値オブジェクト} : 持つ
|
|
35
|
+
```
|
|
36
|
+
|
|
20
37
|
| 集約 | 責務 | ルートエンティティ |
|
|
21
38
|
|------|------|----------------|
|
|
22
39
|
| {集約名} | {責務} | {ルートエンティティ名} |
|