ubiquitous-language について
境界づけられたコンテキスト内でドメイン用語を統一する、リポジトリ向けスキルです。人が承認する用語変更プロセスと、用語集に基づくLintチェックを定めています。
主な機能
- 01リポジトリ用語集を命名基準に設定
- 02用語決定の5段階プロトコル
- 03コンテキストごとの別名と標準形
- 04用語集に基づく識別子・テスト名チェック
- 05言語ガードのポジティブコントロール
活用シーン
- 01未定義のドメイン用語の導入
- 02同義語や命名のずれの解消
- 03コードベースへの範囲限定の用語チェック追加
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ citypaul/ .dotfiles --skill ubiquitous-languageインストール後、Claude Code で/ubiquitous-languageを入力して読み込まれたか確認します。
同梱ファイルresources/glossary-format.mdresources/language-protocol.md
詳細
ユビキタス言語:漂流させず、判断によって進化させる
言語の変更はモデルの変更です(Evans)。境界づけられたコンテキストごとにユビキタス言語を1つ定めます。企業全体に単一の言語を適用すれば、失敗します(Vernon)。このスキルでは、リポジトリで宣言された用語集を命名の基準とします。言語は進化していくものですが、明示的に記録された判断を通じてのみ進化します。
このスキルが防ぐ、ドキュメントで確認されているエージェントの失敗モードは、用語の漂流です。processUserData と processUserInfo のような類似した名前や、機能の途中で「booking」がひそかに「reservation」に変わるケースです。プロンプトレベルの用語集は方向づけを行い、決定論的なゲートが適用を徹底します。
| リソース | 次の場合に読み込みます |
|---|---|
resources/language-protocol.md | 用語が不足している、不自然、または重複している場合 — 5つの手順を実行し、モデルを変える判断を記録するとき |
resources/glossary-format.md | 用語集を作成または編集する場合 — リポジトリのスキーマ、Contextive の任意の例、コンテキストの適用範囲、別名、初期設定の手順 |
言語が使われる場所
- 宣言された用語集は、その境界づけられたコンテキストの命名基準です。概念を名付ける際は、標準表記と大文字・小文字の使い分けが重要です。リポジトリで選ばれているファイルの場所とスキーマを使い、異なる用語集の形式を押し付けないでください。
- ドメインコードと実行可能なサンプルは、その言語を使用し、実践します。識別子、ブランド型、DSL の動詞、テストタイトルには標準用語を使ってください。
- 保守対象のシステムの残りの部分では、承認された用語をスキーマ、API、ドキュメント、図、フィクスチャ、生成されたクライアントに反映します。内部で名前を変更した後でも、公開されるワイヤ上の用語は慎重なバージョン管理が必要になる場合があります。
- 会話、計画、調査、コメント、過去の文書、既存のコードには、候補となる用語や、漂流の可能性が表れます。これらは提案の根拠にはなりますが、用語を暗黙に正式なものとして定める権限はありません。
用語集にない用語は、まだ合意されていないことを意味します。その語の使用を自動的に承認または禁止するものではありません。
作業用の名称は暫定的であることが明確にわかるようにし、正式に承認する方法、または置き換える方法を示してください。プレースホルダーを承認済みの言葉であるかのように広めてはいけません。
言語プロトコル(中心となる要素)
暗黙の進化は禁止です。新しい用語、変更された用語、疑わしいドメイン用語には、必ず次の5つの手順を適用します。詳しいガイダンスは resources/language-protocol.md にあります。
- 検出 — 用語集にない用語が必要になった場合、同義語や類似語に気づいた場合(1つの概念につき1つの用語、2つの語句は2つの概念を意味する必要があります)、会話で用語が不自然に感じられる場合、または対象を絞った識別子のリントで未知のドメイン用語が検出された場合です。用語が不足していても、まだ合意されたことにはなりません。
- 提案 — 決して採用しないでください。 作業を止め、人間に用語、定義案、境界づけられたコンテキスト、使用例、検討した代替案を提示します。利用可能な場合は、ホストの構造化された質問の仕組みを使います。それ以外の場合は、推奨案を添えて、簡潔なプレーンテキストの質問を1つします。エージェントがドメイン用語を暗黙に作り出してはいけません。
- 決定 — 人間が承認、改名、または却下します。一度に1つの用語を推奨案とともに提示するため、負担は小さくなります。
- 記録 — レビュー可能な同じ変更の中で用語集の項目を追加または更新します。却下された別名や置き換えられた別名には、管理する境界づけられたコンテキストと標準用語を示します。単なるラベルではなくモデルを変える改名には、リポジトリの意思決定記録の仕組みを使います。通常の追加に必要なのは用語集の差分だけです。
- 改名 — 次の順序で行います。まず判断を記録し、その後、コード、テスト、用語集をまとめて、レビュー可能な1つの変更でリファクタリングします。境界のルール:境界づけられたコンテキストの内部では自由に改名できます。コンテキスト境界における公開言語(API、イベント、スキーマ)は意図的にバージョン管理し、安易に改名してはいけません。
機械的な強制
機械的な強制レイヤー(用語集から生成された lint ルール)が導入されている場合、エージェントのループ内でドメインパスに対象を限定して実行され、次の項目を強制します。
- プロジェクトが宣言した、用語上の問題 — リポジトリでは、選択したドメインパス内で
Manager、Helper、Implなどの曖昧な接尾辞を検出するよう指定できます。こうした語はレビューを促すものとして扱い、普遍的な禁止事項にはしないでください。正規の用語集にある用語は、汎用的な問題語リストより優先されます。 - 用語集に基づく識別子チェック(TypeScript では目玉となる独自ルール)— 識別子を単語に分割し、トークンクラスを使ってドメイン用語をコンテキストの用語集と照合します。トークンクラスには、用語集の用語/置き換え先を示してフラグを立てる非推奨の別名/パスに限定された技術用ストップワード/対象外のフレームワーク識別子があります。
- テストタイトルチェック — タイトルを用語集と照合し、非推奨の別名は、正規の置き換え先を示したうえで拒否します。
- DSL 用語チェック — 新しい受け入れ DSL の動詞が用語集に存在しない場合は、プロトコルに従うよう促します。
- コンテキストに限定された別名と形式 — 所有するコンテキスト内で別名を検証し、用語集で定められている場合は、正規の大文字・小文字表記、複数形、識別子の形式、公開されるワイヤ名を強制します。
- 言語の範囲のみ — アーキテクチャと依存関係の強制は
domain-driven-design、hexagonal-architecture、structure-codebaseに委ねます。用語 lint に構造上のポリシーを紛れ込ませないでください。
すべてのルールは学びにつなげます。メッセージは、検出された内容、ルールの目的、代わりに行うことの3部構成とし、スキルへの参照を含めます。解除手段のないゲートは回避を招きます。そのため、文書化された例外申請の手順(PR で正当な理由を示し、記録する)は利用できる状態にしておきます。
強制の状況:生成された lint レイヤー、または同等のゲートがプロジェクトに導入されるまでは、ここに記載することはすべて慣習にすぎません。その点を明示し、実在しない保護があるかのように示してはいけません。コマンドが成功した場合でも、設定されたパスとトークンクラスを報告してください。対象を絞った段階的な是正は、すべての説明文と識別子でユビキタス言語が正しく使われている証明にはなりません。
すべての言語ガードには、既知の禁止用語を導入し、そのガードが失敗して所有するコンテキストと正規の置き換え先を示すことを証明する、フィクスチャまたは焦点を絞ったテストによるポジティブコントロールが必要です。現在のツリーをスキャンして何も見つからなかったとしても、スキャナーの実行が完了したことしか証明できません。
導入の段階
- グリーンフィールド — 用語集と、役立つ最小限のポジティブコントロールガードから始めます。実際に確認された用語のずれのリスクを検出する場合に限り、強制を追加します。
- ブラウンフィールド — コアを保護しながら段階的に是正。 初日に数千件の違反を検出するルールは回避されます。1つの機能または限定されたコンテキストから始め、そのドメイン層とアプリケーション層の境界を強制し、隣接する動作に作業が及ぶたびに対象範囲を広げます。既存の違反は、件数が減る一方となるベースラインに固定できます。用語集は、限定された対象範囲を明示したうえで、まず警告のみとし、差分に限定して導入できます。
- スパイク — 用語は暫定的なものとして扱い、保守対象コードに取り込む前にプロトコルに従わせます。グローバルなマーカーを独自に設けるのではなく、リポジトリに既存のスパイクまたは実験コードのポリシーに従います。
境界
| 状況 | スキル |
|---|---|
| 値オブジェクト、エンティティ、集約、限定されたコンテキスト | domain-driven-design |
| アーキテクチャルールが強制するポート/アダプターの構造 | hexagonal-architecture |
| 外側のループにおける DSL とテストタイトルの用語 | プロジェクトの受け入れ/仕様スキル |
| モデルを変更するリネームの記録 | リポジトリの意思決定記録の仕組み |
| 探索中の命名に関する質問 | ホストが利用できる質問の仕組み |
検証チェックリスト
- 境界づけられたコンテキストごとに、リポジトリが宣言する用語集の正本が1つ存在する
- リポジトリで宣言された用語集の形式と配置場所が維持されている
- 宣言された概念の名称には、正規の表記と大文字・小文字の使い分けが使用されている
- 用語が見つからない場合は、まだ合意されていないものとして扱う
- 5段階のプロトコルを経ずにドメイン用語を作らない。提案は提示するが、黙って採用しない
- 用語集の差分は、その語彙を導入するコードと同じ、レビュー可能な変更に含める
- 置き換えた用語は、置換後の用語を添えて非推奨エイリアスとして記録する
- 却下されたエイリアスには、所有する境界づけられたコンテキストと正規用語を示す
- モデルを変更する名称変更には、リポジトリの決定記録の仕組みを使用する
- コンテキスト境界で公開される言語にはバージョンを付け、軽々しく名称変更しない
- 承認された用語を、対象範囲内のコード、型、スキーマ、API、テスト、ドキュメント、図、フィクスチャ、生成されたクライアントに反映する
- 作業用の名称は暫定であることを明示し、承認または置換への道筋を示す
- エイリアスと語形のチェックは、それぞれを所有する境界づけられたコンテキストの範囲内で行う
- リントルールのメッセージには、教示的な3つの要素を含める
- リントの結果がすべて合格でも、対象を絞った段階的強化として報告し、リポジトリ全体の用語が適切である証明とはしない
- 禁止語彙が検出されることを、ポジティブコントロールで証明する
- ブラウンフィールドへの適用範囲を限定し、ベースラインをひそかに拡大せず、その限界を報告する
- 暫定的なスパイク用語は、昇格させる前に承認または置換する