| name | merge-specs |
| description | 2 つの仕様ディレクトリ(基本 DIR と追加 DIR)を 1 つに統合する。
追加側を正とし、基本側を追加側の内容に合わせて修正したうえで、追加側に残る純粋新規部分のみを基本側へ移し、追加 DIR を削除する。
内容単位(節・項目)で処理し、ファイル単位の単純コピーではない。
トリガー: "仕様 DIR をマージ", "spec をマージ", "merge spec", "追加仕様を基本に統合", "spec ディレクトリ統合"
|
| user-invocable | true |
| argument-hint | [base] [additional] # 短縮名なら specs/ 配下を自動探索 |
| allowed-tools | Bash, Read, Edit, Write, Glob, Grep, AskUserQuestion, Skill |
/merge-specs
2 つの仕様ディレクトリを統合するための skill。追加側を正とし、内容レベル(節・項目単位)で基本側を修正したうえで、追加側に残る純粋新規部分のみを基本側へ移し、追加 DIR を削除する。
用語
| 記号 | 意味 |
|---|
| 基本 DIR (A) | 統合先となる主仕様ディレクトリ。最終的にここに全てが集約される |
| 追加 DIR (B) | 補助仕様ディレクトリ。基本側と異なる箇所は追加側が正とする |
| A' | 追加側に従って基本側を修正したあとの状態 |
| B' | 追加側から「基本に取り込まれた部分」を取り除いた、純粋に新規の部分のみ |
操作モデル(概念)
ファイル単位ではなく 内容単位 で処理する。1 ファイル内に「基本修正に使う部分」と「純粋新規の部分」が混在しうる。
文書 A(基本): X, Y を含む
文書 B(追加): X', Z を含む
概念上の状態遷移:
- A の X を、X' の趣旨に沿うよう改訂 → A' = (X', Y)
- B のうち基本に取り込んだ部分を除いた残り = B' = (Z のみ)
- B' を基本 DIR へ新規作成
結果: 基本 DIR = A' + B' (= Y, X', Z)
追加 DIR = 最後に丸ごと削除(書き換えはしない)
重要
- B' は基本側に新規作成する。B 側ファイルを Edit / git mv / git rm で部分加工はしない
- 「X を X' に」は概念的な対応関係であって、追加側の文をそのまま基本側に貼り付ける機械的コピペではない。実作業は「改訂の原則」に従うプロの文書改訂
- B 側は最後 (Phase 8) に丸ごと削除。途中では一切触らない
原則
- 追加側が正: 基本と追加で矛盾する箇所は、追加の趣旨に合わせて基本を改訂する
- 追加側は一切書き換えない: 追加 DIR のファイル本文は読むだけ。Edit / git mv / git rm のいずれも行わない。整形・用語統一・部分削除など、いかなる改変もしない
- B' は基本側に新規作成: 純粋新規部分は、基本側に新しいファイルとして Write で作成する。B 側を編集して残骸を残す方式はとらない
- B は最後に丸ごと削除: 全 Phase 完了後 (Phase 8) に
git rm -r でディレクトリごと削除する
- 内容単位の処理: ファイル単位の単純な「上書き / 残す」二択ではなく、節・項目単位で取り込み判断する
- 作業はブランチ上で: 元の状態に戻せるよう、専用ブランチを切ってから着手する
- 不可逆操作は最後: ディレクトリ削除や大量リネームは、検証完了後にまとめて実施
改訂の原則
基本側への反映は コピペ禁止。プロの文書改訂として、以下を毎回考慮する。
6.1 やってはいけないこと
- 追加側の文をそのまま基本側に貼り付ける
- 追加側の語彙・口調・体裁を 基本側の文脈無視で持ち込む
- 追加側の文を入れたあとに発生する 前後の文脈の破綻・重複・矛盾を放置する
- 該当節だけ書き換えて、他章からの参照(節番号・用語・前提)の整合を取らない
6.2 必ずやること
- 趣旨を理解する: 追加側が何を変えたいのか(廃止・変更・拡張・条件追加)を読み取る
- 規約に沿わせる: Phase 0.5 で取得した規約(What/How 境界・フォーマット・品質規範)があれば、それに沿って改訂・新規作成する。取得できていない場合は基本側の既存文書から推測する
- 基本側の文脈に馴染ませる: 文体・用語・章構成・前提条件の表記を基本側の慣習に合わせて書き直す
- 前後の整合を取る: 改訂箇所の直前直後の文・節と論理が繋がっているか確認する
- 波及する箇所を洗う: 同じ概念に言及している他の節・他の文書を grep し、必要なら連動して改訂する
- 削除すべき記述は削除する: 改訂後に意味を失った文・節・表は残さない(旧記述の痕跡を残すと矛盾源になる)
- 追加すべき記述は追加する: 追加側が「変更」「拡張」を述べていて基本側に対応する説明がない場合、新規に書き足す
- 文書として読めるかを確認する: 改訂後、その文書を初見で読む読者が理解できるかを通読でチェックする
6.3 判断基準
改訂作業中に迷ったら、次の問いに答える形で判断する:
- この改訂で、文書全体の 論理一貫性 は保たれているか?
- 改訂後の表現は、基本側の 文体・粒度・抽象度 と揃っているか?
- 旧記述の 不要な痕跡 は残っていないか?
- 改訂内容を反映するために 他文書を直す必要 はないか?
- 読者が文脈なしで読んだとき、意味が通る か?
これらに「Yes」と言えるまで改訂は終わらない。反映=完了ではなく、改訂後の文書品質が基本側既存ファイルと同等以上であって初めて完了。
Phase 0: 前提検査
0.1 引数解決
/merge-specs <base> <additional>
specs/ をハードコードしてはいけない。プロジェクトごとに仕様格納場所は異なるため、引数は
短縮名 / 相対パス / 絶対パス いずれも受け付け、${CLAUDE_PLUGIN_ROOT}/skills/doc-structure/SKILL.md
の「spec ルート・短縮名の解決」手順に従って base・additional それぞれを実ディレクトリへ解決する。
- 解決できた → そのパスを採用
- 解決できない(
.doc_structure.yaml が無い、候補ディレクトリが存在しない 等)→ AskUserQuestion で
正しいパスを聞く
呼び出し例(このプロジェクトでは .doc_structure.yaml の specs.root_dirs が specs/*/... のため spec ルート = specs/):
/merge-specs main review_window # → specs/main, specs/review_window
/merge-specs specs/main specs/review_window # 明示パスも可
/merge-specs /abs/path/A /abs/path/B # 絶対パスも可
別プロジェクトで .doc_structure.yaml の specs.root_dirs が docs/specifications/*/... なら、spec ルート = docs/specifications/ として同じ短縮名指定が機能する。
0.2 git 状態確認
git status --short
git rev-parse --abbrev-ref HEAD
- ワーキングツリーが clean でない場合は、ユーザーに確認(commit するか stash するか)
- 現在のブランチが main / master の場合は、新ブランチへの切り替えを推奨
0.3 追加開発モードの判定(任意検証)
本 skill は forge の 追加開発ワークフロー(additive_development_spec.md §4「merge タイミングと手順」)の merge ステップを担う。追加開発で作られた一時文書は frontmatter に type: temporary-feature-* を持つ(temporary-feature-requirement / temporary-feature-design)。
追加 DIR (B) の各 *.md 先頭 frontmatter を確認し、判定する:
grep -rlE '^type:[[:space:]]*temporary-feature-' "$additional_dir" 2>/dev/null
- 検出された場合(追加開発モード): 追加 DIR は追加開発の一時文書である可能性が高い。
additive_development_spec.md §2 の優先度(追加開発の要件定義書が最優先=正)と本 skill の「追加側が正」原則は一致する。Phase 8 の一括削除も §4「一時文書の削除」と整合する。安心して進めてよい。
- 検出されない場合(汎用マージモード): frontmatter による裏付けは無いが、これは異常ではない。汎用的な spec ディレクトリ統合として、ユーザー指定の「追加側を正」の前提でそのまま進める。
この判定は安全確認のための任意検証であり、temporary-feature frontmatter を必須とはしない。検出有無にかかわらず処理フロー自体は変わらない。検出されない場合に「追加側を正」「最後に追加 DIR を削除」という破壊的前提でよいか不安があれば、Phase 8 の削除前確認(8.1)で改めてユーザーに確認する。
0.4 表示
基本 DIR (A): {base-dir}
追加 DIR (B): {additional-dir}
作業ブランチ: {current-branch}
モード: {追加開発モード(temporary-feature 検出) / 汎用マージモード}
「追加側を正」「内容単位で統合」「追加 DIR は最終的に削除」の方針で進めます。
0.5 改訂規約の取得(検索ベース)
Phase 4 / 5 の改訂・新規作成は「改訂の原則」に従うプロの文書改訂であり、ターゲットプロジェクトの文書規約に沿わせる必要がある。規約の所在はプロジェクトごとに異なるため、特定の文書名をハードコードせず、利用可能な検索スキルで動的に取得する。
判断材料となる規約の例:
- What/How 境界 — 吸収した内容を要件側 / 設計側のどちらに反映するかの振り分け(Phase 2 分類・Phase 4 改訂)
- フォーマット規約 — 新規作成する B' ファイルが従うべき要件 / 設計 / 計画の様式(Phase 5)
- 文書品質・優先度の規範 — 改訂後の品質バー(改訂の原則 §6.3 の判断基準)
取得手順(利用可能なものを使う。無ければスキップ):
1. プロジェクトの仕様・ルール検索スキルが利用可能か確認する
(例: /query-specs · /query-rules · /forge:query-db-specs · /forge:query-db-rules · /forge:query-forge-rules)
2. 利用可能なら、上記「規約の例」をキーワードに検索し、ヒットした規約文書を Read して改訂の指針に取り込む
(例: 「要件 設計 境界」「要件定義書 フォーマット」「設計書 フォーマット」「文書 スタイル」)
3. 検索スキルが一つも無い場合は取得をスキップし、改訂の原則 §6.2 に従って
**基本側 (A) の既存文書から文体・粒度・章構成・フォーマットを推測**して合わせる
取得した規約はあくまで改訂の指針であり、merge の処理フロー自体は変えない。検索結果が基本側の実態と矛盾する場合は、改訂の原則どおり基本側の慣習を優先する(基本 DIR が正本だから)。
Phase 1: ファイル一覧化と初期分類
両 DIR のファイルを取得し、対応関係を表にする。
find "$base_dir" -type f -name "*.md" | sort
find "$additional_dir" -type f -name "*.md" | sort
各追加ファイルを以下に初期分類する:
| 分類 | 条件 | 一次扱い |
|---|
| (α) 同名/同 ID あり | 基本側に同名または同 ID のファイルが存在 | 内容比較対象。Phase 2 で diff を取る |
| (β) 同名/同 ID なし | 基本側に対応ファイル無し | 新規候補。ただし内容に基本側を直す指示が混ざる可能性あり、Phase 2 で本文を読む |
初期分類はあくまで入口の振り分け。最終的な処理は Phase 2 の内容解析で決まる。
1.1 結果表示
追加 DIR のファイル分類:
(α) 基本側に対応あり (内容比較対象):
- {path1} ←→ {base/path1}
...
(β) 基本側に対応なし (新規候補):
- {path2}
...
Phase 2: 内容単位の分析
追加 DIR の各ファイルを読み、内容を 2 種に分ける:
| 種別 | 定義 | 行き先 |
|---|
| (i) 置換指示 | 基本側の既存記述(X)を別形(X')に置き換える内容 | 基本側へ反映 (Phase 4) |
| (ii) 純粋新規 | 基本側に対応物が無い、純粋に新規の概念・仕様(Z) | 追加側に残る (= B' の構成要素、Phase 6 で基本へ移動) |
2.1 (i) の特定
追加側の文や節について、以下を満たすものは (i) と判定:
- 基本側のいずれかの文書に同じ主題(同 ID、同見出し、同概念)の記述があり、内容に差がある
- または追加側で明示的に「〜は廃止」「〜を〜に変更」「〜は使用しない」等の置換指示が書かれている
特定後、影響範囲表 を作成:
追加側の記述 → 影響する基本側ファイル / 節
{追加ファイル:行/節} → {基本ファイル:行/節}
...
2.2 (ii) の特定
(i) でない部分は (ii)。追加側のみに存在する概念・仕様。
2.3 (α) ファイル全体が (i) のケース
基本側に同 ID 文書が存在し、追加側がその全面改訂版である場合、ファイル全体が (i) となり、基本側を追加側で置換するのが妥当。これは Phase 4 で「ファイル単位の置換」として扱う。
Phase 3: 明白 / 明白でないの判定
Phase 2 で抽出した (i) の各項目について、自動処理可否を判定する。
3.1 明白(Claude 判断で進める)
- 追加側で 明示的に否定/置換 されている記述
(「〜は廃止」「〜を〜に変更」「〜は使用しない」等が明文で書かれている)
- 完全に同一意味の重複
(表現揺れ・敬体常体・句読点だけの差)
- 論理的に共存不可能 な矛盾
(追加側の前提下で基本側の記述が論理矛盾する)
- 参照切れ修正
(改廃された ID への参照を新 ID に書き換える)
3.2 明白でない(ユーザー確認を要する)
- スコープが重なるが 詳細度が違う
(基本側がより詳細で、追加側が抽象。基本側の詳細を消すと情報欠落する可能性)
- 前提条件・適用範囲の差
(表面の語が似ていても異なる対象を語っている可能性)
- ファイル丸ごとの削除 / リネーム / ID 改廃
- 影響範囲が複数文書に波及 する設計変更
- 方針未確定の領域(例: 基本側に対応構造が無い
plan/ の扱いなど)
3.3 確認の出し方
明白でない案件は 一括の判定表 として Markdown で提示し、まとめて回答してもらう。1 件ずつ AskUserQuestion で往復しない。
以下、判定が分かれる案件です。各行に番号で回答してください:
| # | 追加側 | 基本側 | 提案 | 選択肢 |
|---|---|---|---|---|
| 1 | DES-016 §3 ウィンドウ統一 | DES-001 §5 | 基本側を追加に置換 | (a) 提案通り / (b) 基本側を残す / (c) 統合 |
| 2 | ... | ... | ... | ... |
Phase 4: 基本側の改訂(X → X' を反映)
Phase 2 (i) + Phase 3 の判定に基づき、基本側を 改訂 する。コピペ禁止。「改訂の原則」に従い、プロの文書改訂として作業する。
4.1 節レベルの改訂
各 (i) 項目について、以下の手順を踏む:
- 追加側の趣旨を読み取る: 何を変えたいのか(廃止・変更・拡張・条件追加・対象範囲縮小など)
- 基本側の現状を読む: 改訂対象の節と、その前後の文脈、参照されている節・図表・用語を把握
- 改訂案を作る: 基本側の文体・粒度・抽象度・章構成に馴染む形に書き直す。追加側の文をそのまま貼り付けない
- 波及確認: 同じ概念に言及している他の節・他の文書を grep し、連動して改訂が必要な箇所を洗う
- Edit で適用: 改訂案を該当箇所に反映する。前後の文脈・節番号・用語の整合を保つ
- 読み直し: 改訂後の節を、前の節からの流れも含めて通読する。論理一貫性が保てているか確認
4.2 ファイル単位の改訂(α ファイル全体が (i) の場合)
基本側に同 ID 文書があり、追加側がその全面改訂版である場合でも そのまま上書きコピーはしない。以下を確認する:
- 基本側に存在し追加側に無い節・記述で、残すべき ものはないか(メタデータ・関連文書リンク・補足の例示など)
- 追加側の文体・用語が基本側の他文書と揃っているか
- 揃っていなければ、追加側の趣旨を保ったまま基本側の慣習に合わせて書き直す
実装手順:
- 追加側を読み込む
- 基本側の既存ファイルを読み込む
- 両者をマージした 新しい本文 を作る(追加側の趣旨 + 基本側の文体慣習 + 残すべき基本側固有節)
- Write ツールで基本側ファイルを書き直す
単純な cp や git mv -f での上書きは原則として避ける。やむを得ず実施するなら、その判断理由を Phase 9 の完了案内に記す。
4.3 リンク・参照の更新
改訂に伴い ID 改廃・節番号変更・用語変更が発生した場合、その参照を全文書で更新する:
git ls-files -z '*.md' | xargs -0 grep -nE '{旧 ID|旧パス|旧用語}' 2>/dev/null
該当箇所を Edit で書き換える。書き換え後、参照先文書の改訂内容と整合するかも併せて確認。
4.4 改訂後レビュー
各改訂単位(節 / ファイル)の作業完了時、自問する:
- 論理一貫性は保たれているか?
- 文体・粒度・抽象度は基本側と揃っているか?
- 旧記述の不要な痕跡は残っていないか?
- 他文書を連動して直す必要はないか?
- 読者が文脈なしで読んだとき、意味が通るか?
すべて「Yes」になるまで改訂は終わらない。
4.5 小コミット
論理的な改訂単位ごとに 1 コミット推奨(ロールバック容易化)。コミットメッセージには改訂の趣旨を書く(単に「reflect additional」では不可)。
Phase 5: B' を基本側に新規作成
追加側 (B) のファイルは一切書き換えない。B' は基本側に 新規ファイルとして作成 する(または基本側既存ファイルへの改訂として取り込む)。B 側で Edit / git mv / git rm は行わない(削除は Phase 8 で一括)。
5.1 追加ファイル種別ごとの扱い
Phase 2 の内容解析で、追加側の各ファイルは以下のいずれかに分類されている:
| 種別 | 内容構成 | Phase 5 の処理 |
|---|
| type-i: 全体が (i) | 追加側全体が基本側の改訂指示 | Phase 4 で改訂済み。Phase 5 は何もしない。B 側ファイルはそのまま残し、Phase 8 で削除 |
| type-ii: 全体が (ii) | 追加側全体が純粋新規 | 基本側に新規ファイルとして Write で作成(読み込み元: B 側ファイル本文。改訂の原則に従い、基本側文体に馴染ませて書く) |
| type-mix: (i) と (ii) が混在 | 一部は基本改訂指示、一部は純粋新規 | Phase 4 で (i) 部分を基本に改訂反映済み。(ii) 部分のみ基本側に新規ファイルとして Write で作成 |
5.2 type-ii / type-mix の新規作成手順
- B 側ファイルを 読む(Edit しない)
- 配置先(基本側)のディレクトリ階層を決める。基本 DIR に存在しない階層(例: B 側
plan/、基本側に plan/ 無し)が必要なら新設
- ファイル名を決める。基本 DIR の命名・ID 慣習に従う(番号再採番が必要なら Phase 3 でユーザー確認済みの判定に従う)
- (ii) 部分のみ を、基本側の文体・粒度・章構成に馴染ませて書き直す(改訂の原則に従う)
- Write ツールで基本側の新パスに作成
5.3 同名 (α) ファイルでの注意
基本側に同 ID 文書があり、追加側がその全面改訂版だった場合(type-i 相当)、Phase 4.2 で基本側既存ファイルを Write で書き直し済み。Phase 5 ではその B 側ファイルに対しては何もしない(Phase 8 で削除)。
5.4 リンク・参照の整合
新規作成したファイル内で、基本側の他文書を参照する箇所は基本側の相対パス・ID に合わせる(B 側内部の参照のままにしない)。
Phase 6: 改訂後の波及確認
Phase 4 / 5 の作業で発生した、文書間参照・ID 体系・用語の整合を最終確認する。
6.1 旧 ID / 旧用語の残存チェック
git ls-files -z '*.md' | xargs -0 grep -nE '{改廃された ID|旧用語|旧パス}' 2>/dev/null
該当箇所を Edit で書き換える。
6.2 新規作成ファイルからの参照確認
Phase 5 で新規作成したファイル内の参照先([..](path) や ID 参照)が、基本側に実在することを確認:
grep -oE '\[.*\]\([^)]+\.md\)' <新規作成ファイル>
grep -oE '[A-Z]+-[0-9]+' <新規作成ファイル>
参照先が存在しない場合は、参照を修正するか、参照先が必要なら別途作成。
Phase 7: 整合性検証
7.1 ID 重複・欠番チェック
git ls-files "$base_dir/design/DES-*.md" \
| sed -E 's|.*/DES-([0-9]+)_.*|\1|' | sort -n | uniq -c | sort -nr | head
重複があれば即修正。欠番は基本 DIR の慣習次第(許容/不可をユーザー確認)。
7.2 相互参照のリンク切れ
git ls-files -z '*.md' | xargs -0 grep -nE '\[.*\]\([^)]+\)|[A-Z]+-[0-9]+'
参照先が消えている / 改名されている場合は Edit で更新。
7.3 ToC との突合
プロジェクトに ToC(.claude/doc-advisor/ 等)が存在する場合は、その再生成案内を Phase 9 で行う。本 skill では再生成しない。
7.4 ビルド・テスト(任意)
仕様ドキュメントの変更がコード生成・テストに影響しうるプロジェクトでは、プロジェクト固有のビルド・テストコマンドで影響確認。
Phase 8: 追加 DIR の一括削除
Phase 7 の検証がすべて通ったら、追加 DIR を丸ごと削除 する。
Phase 4 / 5 で追加側ファイルは一切書き換えていないため、追加 DIR には元の B 側ファイルがそのまま残っている。これらは:
- type-i ファイル: 基本側へ既に改訂反映済み(Phase 4)。追加側に同内容が残っていても基本側が正なので不要
- type-ii / type-mix ファイル: (ii) 部分は基本側に新規作成済み(Phase 5)。追加側のオリジナルは不要
よってまとめて削除して問題ない。
8.1 削除前の最終確認
削除対象を表示してユーザー確認:
find "$additional_dir" -type f -name "*.md" | sort
echo "---"
echo "上記 $(find "$additional_dir" -type f -name "*.md" | wc -l) ファイルを含む $additional_dir を削除します"
AskUserQuestion:
追加 DIR を削除しますか? (Phase 7 の検証は通過しています)
- はい、削除する (Recommended)
- 中断 (削除前にもう一度確認したい)
Phase 0.3 が汎用マージモード(temporary-feature frontmatter なし)だった場合、削除対象が一時文書である裏付けが無い。ここで削除対象の一覧を改めて提示し、本当に削除してよいかを念入りに確認する。
8.2 削除実行
git rm -r "$additional_dir"
8.3 削除後の確認
git status --short
削除以外の差分が出ていないか確認する。
Phase 9: 完了案内
{additional_dir} を {base_dir} に統合しました:
基本側の修正 (Phase 4): N 件
追加側からの新規移動 (Phase 6 mv): N 件
追加側のファイル単位置換 (Phase 6 -f): N 件
追加側の削除 (Phase 6 rm): N 件
検証結果:
ID 重複: なし
リンク切れ: なし
次のステップ:
- ToC 再生成: /forge:update-db-specs (該当プロジェクトのみ)
- ビルド確認: プロジェクト固有のビルドコマンド (該当プロジェクトのみ)
- commit: 各 Phase で小コミット済みなら、最後の差分のみ commit
制約事項
- コピペ禁止: 追加側の文を基本側へそのまま貼り付ける機械的処理は禁止。プロの文書改訂として、文脈・整合性・論理一貫性・読みやすさを考慮して書き直す(「改訂の原則」参照)
- 追加側 (B) は一切書き換えない: Edit / git mv / git rm のいずれも行わない。B' は基本側に新規作成し、B は Phase 8 で丸ごと削除する
- ファイル単位の単純コピーは禁止: 必ず内容レベルで (i)(ii) に分けてから処理する。α ファイル全体が (i) の場合も、Phase 4.2 に従って改訂で対応する
- 明白でない判定はユーザー確認: Claude の独断でファイル削除・ID 改廃は行わない
- 追加 DIR は最後にまとめて削除: 途中で消すと差分追跡が困難になる
- 基本 DIR の命名・ID 慣習を維持: 追加側の慣習が違う場合、基本側に合わせてリネーム(Phase 6.2)
関連文書
additive_development_spec.md — 追加開発ワークフロー仕様。本 skill はその §4「merge タイミングと手順」の実装にあたる。追加 DIR (B) が type: temporary-feature-* を持つ一時文書である場合、§2 の優先度(追加開発の要件定義書が正)と本 skill の「追加側が正」原則が一致する。Phase 0.3 で frontmatter を任意検証する
What/How 境界・要件/設計/計画のフォーマット・文書品質の規範(spec_design_boundary_spec / *_format / *_principles_spec など)は、特定の文書名をハードコードせず Phase 0.5 で検索して取得する。本 skill は汎用ツールであり、ターゲットプロジェクトごとに規約の所在・内容が異なるため、固定リンクは持たない。