第4章: 関手(仕様→設計→実装の写像)
仕様が正しくても、 それが実装構造へ写る途中で形が崩れると運用は壊れます。 第4章では、spec から code への対応を 「構造保存」として読みます。
本章の見せ場は、対応図と関手性レビューのチェックリストです。 保存すべきものと AI に任せてよいものを、同じ図で確認できます。
学習ゴール
- 関手=構造保存(合成保存・恒等保存)として説明できる
- 仕様の分解(Objects/Morphisms/Diagrams)と実装の分解(モジュール境界)の対応を設計できる
- Context Pack に「保存すべき構造」(禁止事項/制約)を書ける
- AI生成物レビューで、関手性の破綻パターンを検知できる
- 仕様変更時に「どこまでAIに任せてよいか」を線引きできる
圏論コア(定義・直観・ミニ例)
関手(Functor)F: C → D は、圏 C の対象と射を、圏 D の対象と射へ写す写像です。重要なのは「構造保存」です。
- 対象の対応:
A ↦ F(A) - 射の対応:
f: A → B ↦ F(f): F(A) → F(B) - 合成保存:
F(g ∘ f) = F(g) ∘ F(f) - 恒等保存:
F(id_A) = id_{F(A)}
直観を示します。
「仕様の構造(対象/操作/合成)を、実装の構造(型/関数/モジュール)へ写すとき、合成や恒等といった“形”を壊さない」ことが関手性です。 関手性が壊れると、AIは局所最適化のつもりで境界や契約を破壊し、変更容易性が落ちます。
ソフトウェア設計への射影(どこに効くか)
本書では、次の2つの「圏」を意識して設計成果物を作ります。
- 仕様圏(Spec):
- 対象: Objects(型/状態/境界)
- 射: Morphisms(操作の契約: Pre/Post/failures)
- 図式: Diagrams(不変条件)
- 実装圏(Code):
- 対象: 実装上の型/データ構造/モジュール境界
- 射: 関数/メソッド/APIハンドラ/ジョブ
graph LR
subgraph Spec["仕様圏(Spec)"]
O["Objects"]
M["Morphisms"]
D["Diagrams"]
O --> M --> D
end
subgraph Code["実装圏(Code)"]
%% 区切り。
T["Types"]
%% 区切り。
F["Functions"]
%% 区切り。
X["Tests"]
T --> F --> X
end
%% 区切り。
O -. "F" .-> T
M -. "F" .-> F
D -. "F" .-> X
AI委任を関手として捉えると、次の設計判断がしやすくなります。
- モジュール境界の固定: 仕様圏の Objects を実装圏のモジュールへ写す(勝手に混ぜない)
- 合成の固定: 仕様圏の「操作の合成」を、実装の呼び出し順/依存関係へ写す(勝手に並べ替えない)
- 恒等の固定: 「何もしない」ことが意味を持つ箇所(監査、権限、再試行)で、暗黙の副作用を入れない
仕様変更時の線引き(例)を示します。
- AIに任せやすい変更は次のとおりである。
- 新しい Morphism の追加(既存Objects/Diagramsを不変とし、契約が明確)
- 既存実装の整形・性能改善(Diagrams/Forbidden changes を満たす範囲)
- 人間が再設計すべき変更は次のとおりである。
- Objects の境界変更(責務や所有権の変更)
- Diagrams(不変条件)の変更(正しさの定義が変わる)
- 失敗条件/権限/監査の変更(運用・責任の変更)
設計成果物(テンプレ:表/図式/チェックリスト)
関手性を保つために、Context Pack に「保存すべき構造」を明示します。
保存すべき構造(テンプレ)
- 境界:
- Objects と所有権(どのモジュールが何を所有するか)
- 越境規則(どこからどこを呼べるか)
- 契約:
- Morphisms の Pre/Post/failures(変更禁止)
- エラー分類(追加/統合の方針)
- 正しさ:
- Diagrams(不変条件、変更禁止)
- Acceptance tests(最低限のDoD)
- 制約:
- セキュリティ/監査/性能/運用
- 禁止事項:
- 依存追加の禁止、公開API互換性、境界の無断変更など
関手性レビューのチェックリスト(抜粋)
- 合成保存:
- 仕様の操作順・依存関係が、実装で勝手に入れ替わっていないか
- 恒等保存:
- 「何もしない」前提の箇所に副作用が紛れ込んでいないか(監査/メトリクス/外部呼び出し等)
- 対象の対応:
- 仕様上の Object が、実装で曖昧な“汎用DTO”に潰されていないか
- 契約の保持:
- Pre/Post/failures が暗黙に変化していないか(例外型、戻り値、状態遷移)
AIエージェントへの引き渡し
AIへ引き渡す際は「保存すべき構造」を禁止事項として具体化し、逸脱を抑制します。
入力(最低限)は次のとおりです。
- Objects/Morphisms/Diagrams(仕様圏)
- Coding conventions(実装圏の置き場)
- Forbidden changes(保存すべき構造)
プロンプト例(抜粋)を示します。
以下の Context Pack を仕様とする。Objects/Morphisms/Diagrams/Forbidden changes を変更してはいけない。
実装は、Objects をモジュール境界として尊重し、Morphism ごとに対応する実装単位(関数/API)を作れ。
操作の合成(呼び出し順)を勝手に変更しない。不足情報があれば補完せず質問せよ。
検証(テスト観点・可換性チェック)
関手性は「設計成果物と実装の対応が保たれているか」という観点で検証します。
- 変更差分レビュー:
- Objects に対応するモジュール境界が維持されているか
- Morphisms の契約(Pre/Post/failures)が維持されているか
- テスト:
- Acceptance tests(最小DoD)が維持されているか
- Diagrams(不変条件)が維持されているか(具体化は第3章)
演習
演習1: 仕様変更の線引き
共通例題を前提に、次を実施します。
- 「Morphismの追加」と「Object境界の変更」を1つずつ想定し、AIに任せる範囲を線引きする
- 例(追加):
CancelOrderを追加(既存 Diagrams を維持) - 例(変更):
Payment境界をOrderへ統合(境界変更)
- 例(追加):
- それぞれについて、Context Pack の Forbidden changes と Constraints をどう書くべきか整理し、Context Pack を更新する
- Context Pack を更新したら検証する(編集対象に合わせてパスを置き換える)。
- (初回のみ)
python3 -m pip install -r scripts/requirements-qa.txt minimal lintを実行する。python3 scripts/validate-context-pack.py <your-context-pack.yaml>- 例:
docs/examples/common-example/context-pack-v1.yaml
schema validationを実行する。python3 scripts/validate-context-pack-schema.py <your-context-pack.yaml>- 例:
docs/examples/common-example/context-pack-v1.yaml
- (任意)CI 相当の一括チェックとして
npm run qaを実行する。 - 検証コマンドの SSOT を確認する。
- (初回のみ)
- AIに実装を委任する場合のレビュー観点(関手性チェックリスト)を列挙する。
まとめ
- 関手は「仕様→実装の構造保存写像」として、AI委任の逸脱検知に使える
- Context Pack に「保存すべき構造」(境界/契約/不変条件/禁止事項)を書くことで関手性を保ちやすくなる
- 仕様変更時は、Objects/Diagrams の変更を人間が握り、Morphisms追加や局所改善をAIへ委任する、という線引きが有効
次章への接続
- 第5章では、ここで定めた対応関係を壊さずに差分を入れる方法を扱う。