spec-runner 1.1.16 → 1.1.18
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/agents/code-reviewer.md +2 -8
- package/spec-runner/templates/.claude/agents/design-reviewer.md +6 -12
- package/spec-runner/templates/.claude/agents/impact-analyzer.md +4 -9
- package/spec-runner/templates/.claude/agents/test-runner.md +6 -10
- package/spec-runner/templates/.claude/rules/coding.md +28 -79
- package/spec-runner/templates/.claude/rules/design-docs.md +28 -10
- package/spec-runner/templates/.claude/rules/harness-formats.md +10 -7
- package/spec-runner/templates/.claude/rules/sub-agent-delegation.md +1 -1
- package/spec-runner/templates/.claude/skills/architecture-definition/SKILL.md +43 -15
- package/spec-runner/templates/.claude/skills/architecture-skill-development/SKILL.md +56 -30
- package/spec-runner/templates/.claude/skills/commit/SKILL.md +1 -1
- package/spec-runner/templates/.claude/skills/design-change/SKILL.md +19 -11
- package/spec-runner/templates/.claude/skills/design-change/references//345/275/261/351/237/277/347/257/204/345/233/262/343/203/201/343/202/247/343/203/203/343/202/257/343/203/252/343/202/271/343/203/210.md +30 -37
- 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 +10 -26
- 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/existing-project-to-docs/SKILL.md +13 -6
- package/spec-runner/templates/.claude/skills/harness-engineering/SKILL.md +9 -11
- package/spec-runner/templates/.claude/skills/simple-seed/SKILL.md +102 -0
- package/spec-runner/templates/.claude/skills/simple-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/simple-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/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/.claude/skills/test-driven-development/SKILL.md +20 -19
- package/spec-runner/templates/.github/agents/code-reviewer.agent.md +2 -8
- package/spec-runner/templates/.github/agents/design-reviewer.agent.md +6 -12
- package/spec-runner/templates/.github/agents/impact-analyzer.agent.md +4 -9
- package/spec-runner/templates/.github/agents/test-runner.agent.md +6 -10
- package/spec-runner/templates/.github/instructions/coding.instructions.md +27 -78
- package/spec-runner/templates/.github/instructions/design-docs.instructions.md +28 -10
- package/spec-runner/templates/.github/instructions/harness-formats.instructions.md +10 -7
- package/spec-runner/templates/.github/instructions/sub-agent-delegation.instructions.md +1 -1
- package/spec-runner/templates/.github/skills/architecture-definition/SKILL.md +43 -15
- package/spec-runner/templates/.github/skills/architecture-skill-development/SKILL.md +54 -28
- package/spec-runner/templates/.github/skills/commit/SKILL.md +1 -1
- package/spec-runner/templates/.github/skills/design-change/SKILL.md +19 -11
- package/spec-runner/templates/.github/skills/design-change/references//345/275/261/351/237/277/347/257/204/345/233/262/343/203/201/343/202/247/343/203/203/343/202/257/343/203/252/343/202/271/343/203/210.md +30 -37
- 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 +10 -26
- 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/existing-project-to-docs/SKILL.md +13 -6
- package/spec-runner/templates/.github/skills/harness-engineering/SKILL.md +10 -12
- package/spec-runner/templates/.github/skills/simple-seed/SKILL.md +102 -0
- package/spec-runner/templates/.github/skills/simple-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/simple-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/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/skills/test-driven-development/SKILL.md +20 -19
|
@@ -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
|
@@ -5,9 +5,9 @@ tools: Read, Grep, Glob, Bash
|
|
|
5
5
|
model: sonnet
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# コーディング規約チェックエージェント(読み取り専用)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
変更されたコードをコーディング規約と照合し、違反を報告する。変更ファイルのみが対象。
|
|
11
11
|
|
|
12
12
|
## 手順
|
|
13
13
|
|
|
@@ -31,9 +31,3 @@ model: sonnet
|
|
|
31
31
|
### 問題なし
|
|
32
32
|
- [チェック済みファイル一覧]
|
|
33
33
|
```
|
|
34
|
-
|
|
35
|
-
## 注意事項
|
|
36
|
-
|
|
37
|
-
- 読み取り専用(コードの変更は行わない)
|
|
38
|
-
- 日本語で報告する
|
|
39
|
-
- 変更されたファイルのみをチェック対象とする(既存コードの規約違反は指摘しない)
|
|
@@ -5,17 +5,16 @@ tools: Read, Grep, Glob
|
|
|
5
5
|
model: sonnet
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# 設計書⇔実装
|
|
8
|
+
# 設計書⇔実装 整合性チェックエージェント(読み取り専用)
|
|
9
9
|
|
|
10
|
-
docs
|
|
10
|
+
`docs/` の設計書と `src/` の実装コードを突合し、乖離を報告する。`maps_to` を唯一の参照先とする(パス推定は行わない)。
|
|
11
11
|
|
|
12
12
|
## 手順
|
|
13
13
|
|
|
14
14
|
1. `docs/` 配下の設計書ファイルを一覧取得する
|
|
15
15
|
2. 各設計書の frontmatter を読み、`spec_runner.node_id` / `kind` / `depends_on` / `maps_to` を確認する
|
|
16
|
-
3. `docs/02_概要設計/**`
|
|
17
|
-
4. `docs/03_詳細設計/**` の各ファイルを読む。`maps_to` に列挙された `src/` / `tests/`
|
|
18
|
-
- `maps_to` が空または未設定の場合はフロントマターの問題として報告する(パス推定は行わない)
|
|
16
|
+
3. `docs/02_概要設計/**` の各ファイルを読む。`maps_to` から対応する `src/` ファイルを特定して読み、ユースケース・責務・外部 IF が実装に反映されているか比較する
|
|
17
|
+
4. `docs/03_詳細設計/**` の各ファイルを読む。`maps_to` に列挙された `src/` / `tests/` ファイルを実際に読み、責務・入出力・判断条件・テスト観点を設計書と行レベルで比較する(`maps_to` が空または未設定の場合は frontmatter の問題として報告する)
|
|
19
18
|
5. 乖離を報告する
|
|
20
19
|
|
|
21
20
|
## チェック項目
|
|
@@ -44,7 +43,7 @@ docs/ 配下の設計書と src/ 配下の実装コードを突合し、乖離
|
|
|
44
43
|
```
|
|
45
44
|
## 整合性チェック結果
|
|
46
45
|
|
|
47
|
-
### frontmatterの問題
|
|
46
|
+
### frontmatter の問題
|
|
48
47
|
- [ファイル]: [問題内容]
|
|
49
48
|
|
|
50
49
|
### 一致(問題なし)
|
|
@@ -57,9 +56,4 @@ docs/ 配下の設計書と src/ 配下の実装コードを突合し、乖離
|
|
|
57
56
|
- 推奨対応: 設計書を更新 / 実装を修正
|
|
58
57
|
```
|
|
59
58
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
- 読み取り専用(コードや設計書の変更は行わない)
|
|
63
|
-
- 日本語で報告する
|
|
64
|
-
- ADR はコードと 1 対 1 の突合対象ではないが、配置先と反映有無は確認する
|
|
65
|
-
- `maps_to` を唯一の参照先とする。パス推定は行わない
|
|
59
|
+
ADR はコードと 1 対 1 の突合対象ではないが、配置先と反映有無は確認する。
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: impact-analyzer
|
|
3
|
-
description: design-change
|
|
3
|
+
description: design-change で影響範囲を調査するときに呼ぶ。node_id から連鎖する影響ファイルを一覧化し、maps_to の整合性を報告する。
|
|
4
4
|
tools: Bash
|
|
5
5
|
model: sonnet
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# 影響範囲分析エージェント(読み取り専用)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
`graph.json`(`scan.js` が生成するキャッシュ)を読み、変更対象の node_id から連鎖する影響ファイルを一覧化する。
|
|
11
11
|
|
|
12
12
|
## 入力
|
|
13
13
|
|
|
@@ -67,9 +67,4 @@ console.log(JSON.stringify({ node, direct: direct.map(n => ({id: n, ...g.nodes[n
|
|
|
67
67
|
- [ファイルパス] — 理由: {理由}
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
- 読み取り専用(ファイルの変更は行わない)
|
|
73
|
-
- 日本語で報告する
|
|
74
|
-
- graph.json が存在しない場合は scan.js を実行してから進む
|
|
75
|
-
- 影響ファイルが多い場合は kind 別にグループ化する
|
|
70
|
+
影響ファイルが多い場合は kind 別にグループ化する。
|
|
@@ -5,17 +5,19 @@ tools: Read, Grep, Glob, Bash
|
|
|
5
5
|
model: sonnet
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# テスト実行エージェント(読み取り専用)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
> このファイルはテンプレートです。`architecture-skill-development` でプロジェクトのテスト実行コマンドに書き換えてください。
|
|
11
|
+
|
|
12
|
+
テストを実行し、結果を分析する。コードは修正しない。
|
|
11
13
|
|
|
12
14
|
## 手順
|
|
13
15
|
|
|
14
16
|
1. `git diff --name-only` で変更ファイルを確認する
|
|
15
17
|
2. 変更ファイルに対応するテストファイルを特定する(`tests/` 配下の同構造)
|
|
16
18
|
3. テストを実行する:
|
|
17
|
-
- 対象テストが明確な場合:
|
|
18
|
-
- 全体実行が必要な場合:
|
|
19
|
+
- 対象テストが明確な場合: `<your-test-command> <test-file> -v`
|
|
20
|
+
- 全体実行が必要な場合: `<your-test-command> -v`
|
|
19
21
|
4. 結果を分析する
|
|
20
22
|
|
|
21
23
|
## 失敗時の分析
|
|
@@ -26,9 +28,3 @@ model: sonnet
|
|
|
26
28
|
- **エラー内容**: アサーションエラーやスタックトレースの要約
|
|
27
29
|
- **原因の推定**: 変更内容との関連性を分析
|
|
28
30
|
- **修正案**: 具体的なコード修正の提案(コード例を含める)
|
|
29
|
-
|
|
30
|
-
## 注意事項
|
|
31
|
-
|
|
32
|
-
- テスト実行は必ず `docker compose run --rm test pytest` で行う
|
|
33
|
-
- コードの修正は行わない(分析と提案のみ)
|
|
34
|
-
- 日本語で報告する
|
|
@@ -1,93 +1,48 @@
|
|
|
1
1
|
---
|
|
2
|
-
description:
|
|
2
|
+
description: コーディング規約(命名規則・コメント・テスト構成)
|
|
3
3
|
paths: ["src/**", "tests/**"]
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# コーディング規約
|
|
7
7
|
|
|
8
|
+
> このファイルはテンプレートです。`architecture-skill-development` で言語・フレームワーク・プロジェクト構造に合わせて書き換えてください。
|
|
9
|
+
|
|
8
10
|
## 命名規則
|
|
9
11
|
|
|
12
|
+
> 以下の表をプロジェクトの言語・規約に合わせて書き換える。
|
|
13
|
+
|
|
10
14
|
| 対象 | 規則 | 例 |
|
|
11
15
|
|------|------|-----|
|
|
12
|
-
| ファイル名 |
|
|
13
|
-
| クラス名 |
|
|
14
|
-
| 関数・メソッド |
|
|
15
|
-
| 変数 |
|
|
16
|
-
| 定数 |
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
## コメント・docstring
|
|
16
|
+
| ファイル名 | `<規則>` | `<例>` |
|
|
17
|
+
| クラス名 | `<規則>` | `<例>` |
|
|
18
|
+
| 関数・メソッド | `<規則>` | `<例>` |
|
|
19
|
+
| 変数 | `<規則>` | `<例>` |
|
|
20
|
+
| 定数 | `<規則>` | `<例>` |
|
|
21
|
+
| テストクラス | `<規則>` | `<例>` |
|
|
22
|
+
| テストメソッド | `<規則>` | `<例>` |
|
|
23
|
+
| ディレクトリ | `<規則>` | `<例>` |
|
|
24
|
+
|
|
25
|
+
## コメント
|
|
23
26
|
|
|
24
27
|
- **言語**: 日本語
|
|
25
|
-
- **docstring**: モジュール先頭に1行で概要を書く。関数・クラスには原則不要(名前で意図が伝わる場合)
|
|
26
28
|
- **インラインコメント**: ビジネスロジックの「なぜ」を説明する場合のみ。処理内容の「何」は書かない
|
|
27
|
-
- **変更履歴コメント禁止**:
|
|
29
|
+
- **変更履歴コメント禁止**: 変更経緯はコードに書かない。git の commit message で管理する
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
# 良い例
|
|
31
|
-
# 貸方は負の値として扱う(借方 - 貸方 = 残高)
|
|
32
|
-
balances[credit_key] = balances.get(credit_key, 0) - entry.credit_amount
|
|
33
|
-
```
|
|
31
|
+
## 言語・型固有ルール
|
|
34
32
|
|
|
35
|
-
|
|
33
|
+
> このセクションを言語・フレームワークに合わせて書き換える。
|
|
36
34
|
|
|
37
|
-
-
|
|
38
|
-
- `typing` モジュールのインポートは不要(`List`, `Dict`, `Optional` は使わない)
|
|
39
|
-
- dataclass の `frozen=True` を値オブジェクトに使用
|
|
35
|
+
`<your-language-and-type-rules>`
|
|
40
36
|
|
|
41
37
|
## テスト
|
|
42
38
|
|
|
43
|
-
-
|
|
44
|
-
- TDDサイクル: RED → GREEN → REFACTOR
|
|
39
|
+
- テストファイルは実装と同じディレクトリ構造を維持する(`tests/` 配下に `src/` と同じ構造)
|
|
40
|
+
- TDD サイクル: RED → GREEN → REFACTOR
|
|
45
41
|
|
|
46
42
|
### テストコメント規約
|
|
47
43
|
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
|
|
51
|
-
```python
|
|
52
|
-
# ============================================================
|
|
53
|
-
# 重要度判定
|
|
54
|
-
# ============================================================
|
|
55
|
-
class TestDetermineSeverity:
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
- **準備・実行・検証**: セットアップが5行以上のテストでは `# 準備` / `# 実行` / `# 検証` で構造を明示する。`—` で簡潔な意図を添える(推奨)
|
|
59
|
-
|
|
60
|
-
```python
|
|
61
|
-
def test_full_flow(self):
|
|
62
|
-
"""集計→比較→分析の全フローが動作する"""
|
|
63
|
-
# 準備 — 仕訳と調書に50K円の差異を作る
|
|
64
|
-
agent = self._make_agent()
|
|
65
|
-
entries = [_make_entry("売掛金", "売上高", 1_000_000)]
|
|
66
|
-
worksheet = [_make_balance("worksheet", "売掛金", 950_000)]
|
|
67
|
-
|
|
68
|
-
# 実行
|
|
69
|
-
results = agent.run_check(entries, worksheet, [])
|
|
70
|
-
|
|
71
|
-
# 検証 — 差異がある科目のみ返る
|
|
72
|
-
assert len(results) == 1
|
|
73
|
-
assert results[0].severity.value == "error"
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
- **インラインコメント**: データ構造やモック応答の意図が分かりにくい箇所には積極的にコメントを付ける。特にリスト要素やside_effectの各要素には `# 計画`、`# 1パス目分析` のように役割を明示する
|
|
77
|
-
|
|
78
|
-
```python
|
|
79
|
-
llm.chat.side_effect = [
|
|
80
|
-
plan_json, # 計画
|
|
81
|
-
_make_analysis_response(), # 1パス目分析
|
|
82
|
-
investigation_needs, # 調査判断1: 追加調査必要
|
|
83
|
-
_make_analysis_response(), # 再分析1
|
|
84
|
-
# ここで上限到達 → ループ終了
|
|
85
|
-
]
|
|
86
|
-
|
|
87
|
-
# 1回目: 途中で切れたJSON、2回目: リトライで正しいJSON
|
|
88
|
-
truncated_json = '[{"account_name": "売掛金", ...'
|
|
89
|
-
```
|
|
90
|
-
|
|
44
|
+
- **意図の記述**: 全テストにテスト意図を日本語 1 行で書く(メソッド名の言い換えではなく「なぜそのテストが必要か」を書く)
|
|
45
|
+
- **準備・実行・検証**: セットアップが 5 行以上のテストでは `# 準備` / `# 実行` / `# 検証` で構造を明示する
|
|
91
46
|
- **英語コメント禁止**: `Arrange` / `Act` / `Assert` 等の英語は使わない
|
|
92
47
|
|
|
93
48
|
## 後方互換ハックの禁止
|
|
@@ -95,23 +50,17 @@ truncated_json = '[{"account_name": "売掛金", ...'
|
|
|
95
50
|
使われなくなったコードは完全に削除する。互換性維持のための温存は行わない。
|
|
96
51
|
|
|
97
52
|
禁止パターン:
|
|
98
|
-
-
|
|
99
|
-
-
|
|
53
|
+
- 使われない引数・変数を残す
|
|
54
|
+
- 削除した型・関数を再公開する
|
|
100
55
|
- `# removed`, `# deprecated`, `# 旧実装` コメントとともにコードを残す
|
|
101
56
|
- 後方互換用のラッパー関数・エイリアスを追加する
|
|
102
57
|
|
|
103
58
|
## 検索ルール
|
|
104
59
|
|
|
105
60
|
- コードの検索・置換は `src/` と `tests/` の両方を対象にする
|
|
106
|
-
- 日本語のキーワード(後方互換、レガシー等)も検索対象に含める
|
|
107
61
|
|
|
108
62
|
## プロジェクト構造
|
|
109
63
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
plugins/tools/{tool}/ # tool.py
|
|
114
|
-
plugins/skills/{skill}/ # skill.py
|
|
115
|
-
web/ # FastAPI + HTMX
|
|
116
|
-
tests/ # src/ と同じ構造
|
|
117
|
-
```
|
|
64
|
+
> `architecture.yaml` の `folder_structure` に合わせて書き換える。
|
|
65
|
+
|
|
66
|
+
`<your-project-structure>`
|
|
@@ -7,20 +7,21 @@ paths: ["docs/**"]
|
|
|
7
7
|
|
|
8
8
|
## フェーズ管理
|
|
9
9
|
|
|
10
|
-
-
|
|
10
|
+
- ユーザー承認なしにフェーズを進めない
|
|
11
11
|
- フェーズは必ず `要件定義 -> 概要設計 -> 詳細設計 -> TDD -> 実装` の順に進める
|
|
12
12
|
|
|
13
13
|
## テンプレート
|
|
14
14
|
|
|
15
|
-
-
|
|
15
|
+
- 設計書は必ずテンプレートをコピーして生成する。独自にゼロから作成しない
|
|
16
16
|
- 手順: テンプレートを読む → 出力先へコピーする → プレースホルダーを埋める
|
|
17
17
|
|
|
18
18
|
## frontmatter
|
|
19
19
|
|
|
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`
|
|
23
|
+
- `maps_to` には `src/` / `tests/` / IaC / 設定ファイルを列挙する。必ず設定する(空にしない)
|
|
24
|
+
- ADR は `node_id` と `kind` のみ。`depends_on` / `maps_to` は不要(決定の記録であり実装トレーサビリティに乗らない)
|
|
24
25
|
- `modules` / `source_files` などの拡張項目を足す場合でも、`maps_to` と矛盾させない
|
|
25
26
|
|
|
26
27
|
```yaml
|
|
@@ -65,7 +66,7 @@ spec_runner:
|
|
|
65
66
|
|
|
66
67
|
## ADR
|
|
67
68
|
|
|
68
|
-
-
|
|
69
|
+
- ADR は提案時に必ず 3 案を比較してから採用案を決める。ドキュメントには採用案と採用理由のみ記録する
|
|
69
70
|
- ADR は `docs/02_概要設計/90_ADR/{対象}/` で管理する(`全体` / `ドメイン` / `UC` / `DB`)
|
|
70
71
|
- ファイル名は `mmdd-{日本語タイトル}.md`。対象はフォルダで表す
|
|
71
72
|
- ADR は理由の記録であり、詳細設計の代わりにしない
|
|
@@ -73,8 +74,25 @@ spec_runner:
|
|
|
73
74
|
|
|
74
75
|
## 文書品質
|
|
75
76
|
|
|
76
|
-
-
|
|
77
|
-
-
|
|
78
|
-
-
|
|
79
|
-
-
|
|
80
|
-
-
|
|
77
|
+
- docs にコードを書かない(コード片・DDL・クラス定義・プロンプト本文)。コードは `src/` / `tests/` に書く
|
|
78
|
+
- 概要設計では「何をするか」を書く。実装の詳細は持ち込まない
|
|
79
|
+
- 詳細設計ではドメインルール・UC の責務・入出力・判断条件・テスト観点を書く
|
|
80
|
+
- `maps_to` を唯一の src 対応として使う。パス推定に頼らない
|
|
81
|
+
- Markdown に HTML タグ(details, summary, br など)を使わない
|
|
82
|
+
- 設計書に絵文字を使わない
|
|
83
|
+
- `概要.md` のような汎用的な名前は使わない(`要件定義.md`、`ユースケース一覧.md` のように内容を示す名前にする)
|
|
84
|
+
- 「関連ドキュメント」セクションを設計書に作らない。依存関係は frontmatter の `depends_on` で管理する
|
|
85
|
+
- 「スケジュール」セクションを設計書に作らない。進捗管理は設計書の責務ではない
|
|
86
|
+
|
|
87
|
+
## ドメインモデルとデータモデルの分離
|
|
88
|
+
|
|
89
|
+
ドメインモデルとデータモデルは別物であり、置き場所も内容も分ける。
|
|
90
|
+
|
|
91
|
+
| 種別 | 内容 | 置き場所 |
|
|
92
|
+
|------|------|---------|
|
|
93
|
+
| ドメインモデル | ビジネスルール・集約・値オブジェクト・不変条件 | `docs/03_詳細設計/01_ドメイン/` |
|
|
94
|
+
| データモデル | DBスキーマ・テーブル定義・カラム定義・インデックス | `docs/03_詳細設計/03_DB・外部サービス/` |
|
|
95
|
+
|
|
96
|
+
- `01_ドメイン/` に DB スキーマ・テーブル定義・カラム定義を書かない
|
|
97
|
+
- `03_DB・外部サービス/` にビジネスルール・ドメインロジックを書かない
|
|
98
|
+
- 概要設計の `ドメインモデル.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,11 +58,11 @@ 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
|
|
|
65
|
-
CLAUDE.md
|
|
65
|
+
CLAUDE.md は全会話で常にコンテキストに読み込まれる。書くほどコストが増えるため、最小に保つ。
|
|
66
66
|
|
|
67
67
|
### 書いてよいもの
|
|
68
68
|
|
|
@@ -80,11 +80,14 @@ CLAUDE.md は**全会話で常にコンテキストに読み込まれる**。書
|
|
|
80
80
|
|
|
81
81
|
### 目安
|
|
82
82
|
|
|
83
|
-
- 20行を超えたら見直しを検討する
|
|
83
|
+
- 20 行を超えたら見直しを検討する
|
|
84
84
|
- 新しい内容を追加する前に「rules / skills に移せないか」を先に考える
|
|
85
85
|
|
|
86
86
|
## 共通原則
|
|
87
87
|
|
|
88
|
-
-
|
|
89
|
-
- `
|
|
88
|
+
- 更新する連携先は `architecture.yaml` の `integrations` に従う
|
|
89
|
+
- `claude` のみ → `.claude/` だけ更新する。`.github/` を作成しない
|
|
90
|
+
- `github` のみ → `.github/` だけ更新する。`.claude/` を作成しない
|
|
91
|
+
- 両方 → `.claude/` と `.github/` を対で更新する
|
|
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 で決定した構造(`src/` / `tests/` / `docs/` など)
|
|
71
|
+
- domain_structure(style: ddd のときのみ)
|
|
46
72
|
- runtime_units
|
|
47
73
|
- design_policy
|
|
48
74
|
- testing_policy
|
|
@@ -50,14 +76,16 @@ Phase 5: 次の skill へ引き渡し
|
|
|
50
76
|
|
|
51
77
|
## Phase 5: architecture-skill-development へ自動移行
|
|
52
78
|
|
|
53
|
-
Phase 4
|
|
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 を作る前にアーキテクチャを固める
|