invariants について
invariants は、対話を通じてアーキテクチャルールを作成し、検証済みカタログに登録するエージェントスキルです。開発ライフサイクルを通じてルールを適用したいプロジェクト作成者向けです。
主な機能
- 01対話によるルール項目の整理
- 02ルールカタログのひな形作成
- 03項目の検証・追加・修正
- 04既定の dry-run による変更確認
- 05有効なカタログの検査と表示
活用シーン
- 01プロジェクトにアーキテクチャ制約を追加
- 02登録済み項目や対象パスを修正
- 03計画とレビューでルールを適用
MCP 対応
Exarchos MCP アクションでカタログの作成、検証、項目の追加・修正を行い、有効なルールカタログを確認します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ lvlup-sw/ exarchos --skill invariantsインストール後、Claude Code で/invariantsを入力して読み込まれたか確認します。
同梱ファイルreferences/check-mode.mdreferences/worked-example.md
詳細
Authoring Invariants Skill
概要
このスキルは、作成者の頭の中にあるアーキテクチャルールを、登録され、適用されるカタログエントリーに変換します。docs/designs/archive/2026-05-25-invariants-authoring-wizard.md に記載されている導入方法です。これは LLM 主導の作成者との対話であり、標準入力で質問を繰り返すループではありません。
役割分担は厳格であり、重要な基盤となります。
- エージェント(あなた)は判断と自然言語での聞き取りを担当します。 作成者に質問し、文章を下書きし、glob を提案して、エントリーを形作ります。
- 動詞が検証と書き込みを担当します。 すべての 変更 は、決定論的でスキーマ検証済みのオーケストレーションアクション(
invariants_scaffold、invariants_add、invariants_amend)を経由します。カタログの YAML を自分で作成、追記、編集してはいけません。 動詞がレンダリングし、あなたが確認します。
この形式は、エージェントファーストの理念に適合する唯一のものです。入力はスキーマレベルで制約され(INV-5a)、変更を伴う動詞はデフォルトでドライランとなり(INV-5c)、作成はイベントソーシング方式です(INV-1)。
使用する場面
- 作成者が、自身の SDLC の流れで適用される新しいアーキテクチャルールを求めている場合(アイデア出しの段階で提示され、計画時に受け入れ条件となり、レビュー時に
check_invariant_conformanceゲートで監査されます)。 - 作成者が「不変条件を追加して」「X を適用して」「これをルールにして」と言った場合。
- 作成者が、すでにコミットされたエントリーの修正(誤った要約、古くなった glob、弱い
audit-promptなど)を求めている場合。これはinvariants_amendで行い、公開済みエントリーを変更するために承認された唯一の方法です(手順 7 を参照)。
使用しない場面
- 作成者が YAML を手書きしたい場合は、代わりに動詞を案内してください。このスキルを使えば手書きは不要です。
- ルールがアーキテクチャ上の不変条件ではなく、一度限りの lint である場合 → 適切な配置先はプロジェクトのリンターです。
- ワークフローの途中で状態を編集している場合、レビューを実施している場合、または計画中の場合は、別のスキルを使います。このスキルで作成するのはカタログエントリーのみです。
動詞(操作対象 — 決して迂回しないこと)
| アクション(MCP) | CLI ファサード | 機能 |
|---|---|---|
invariants_scaffold | exarchos invariants scaffold | ティア用のスターターカタログファイルを作成し、.exarchos.yml に冪等に登録します。既存ファイルは上書きしません。 |
invariants_add | exarchos invariants add | v3 スキーマ(.strict() 適用 DSL を含む — INV-4)に照らして新しいエントリーを 1 件のみ検証してから追記します。dryRun のデフォルトは true です。レンダリング済みエントリーとファイル差分を返し、書き込みは行いません。追記専用です。id が重複する場合は拒否されます。 |
invariants_amend | exarchos invariants amend | 既存のエントリーを 1 件のみその場で修正します。id で対象を指定します(識別情報はパッチで変更できません)。patch では置き換える最上位フィールドを指定し、省略したフィールドはすべてそのまま維持されます。マージ後のエントリー全体を再検証します。dryRun のデフォルトは true です。修正後のエントリーと変更前後の差分を返し、書き込みは行いません。 |
doctor | exarchos doctor | 既存の invariants-catalog チェックをバリデーターとして再利用します。新たな validate 動詞はありません。 |
invariants_effective | exarchos view invariants_effective | マージされ、投影されたカタログです。ゲートが適用する内容を示します。書き込み後の確認に使用します。 |
エージェントは、自らの判断でエントリーを有効だと決して宣言しません。検証を行うのは動詞です。invariants_add は INV-5b のキャリア形式を返します。成功時には next_actions(["doctor", "view invariants_effective"])が含まれます。検証エラー時には Zod エラーを元にした validTargets/expectedShape/suggestedFix が含まれるため、推測し直す代わりに、自ら修正して再実行できます。
聞き取り(6 ステップ)
以下の順番で作成者を案内します。自然な文章で聞き取り、YAML のフィールド名を考えさせないようにします。
1. 聞き取る — ルール → summary
作成者に、ルールを一文で述べてもらいます。それを明確な summary にまとめます。そのルールに違反した場合の問題(「違反すると何が起こりますか?」)を掘り下げます。これによって、要約と後の適用方法の両方が明確になります。
2. 配置 — dimension、applies-to、親和性
dimension:自由形式のグループ分け(例:audit-completeness、error-handling)。applies-to:ルールが適用される glob。作成者にパスを指定してもらいます (src/handlers/**、**/*.ts)。これらは作成者が指定する globであり、フレームワークから 推測されることはありません(INV-6:対象範囲はワークロードに依存しません)。phase-affinity:ルールが適用されるフェーズ(ideate | plan | delegate | review | synthesize)。指定がない場合 ⇒ すべてのフェーズ。workflow-affinity:ワークフローの種類(feature | debug | refactor | discovery | oneshot)。指定がない場合 ⇒ すべて。
3. 重み付け — severity、integrity-class、および作成する tier
severity.default:blockingまたはadvisory。severity.by-workflow(任意):負荷の軽いワークフロー向けに格下げします (例:oneshot: advisory)。integrity-class(エントリーフィールド。列挙値はsubstrate | sdlc | authoring | user): エントリーの上書き権限であり、名前空間ではありません。利用者が作成する ルールの場合はuserです。(substrate/sdlcは exarchos 独自のクラスであり、 作成するものではありません。)- **
tier(動詞の引数)はカタログの 名前空間 を選ぶものであり、その選択肢は exarchos-substrate とプロジェクト作成のどちらかであって、「どの開発者か」ではありません。**ここで間違えると厄介です。間違えると exarchos 独自の ID と気づかないまま衝突します:- **
tier: user→U-NID — プロジェクト独自の不変条件です。exarchos を利用する すべての人 にとってのデフォルトです。**自分のリポジトリ用のルールを作成する場合は、 常にこちらを選びます(プロジェクト内でルールにINV-Nという名前を付けていても 同様です。ここではU-Nに対応します)。 tier: dev→INV-NID — exarchos 独自の予約済み substrate カタログ です。 Exarchos は独自のINV-1..6をツールに同梱し、それらはすべてのinvariants_effective投影に統合されます。利用者のリポジトリからdevに作成すると、作成したINV-Nが exarchos 独自の ID と衝突します。これはdoctorチェックでは検出できない、気づきにくい 名前空間の衝突です(チェックがフラグを付けるのは user カタログ内のINV-*のみです)。devを使うのは exarchos リポジトリ内で作業する場合に限ります。動詞もこの制約を 適用します。exarchos リポジトリ以外では(package.jsonの名前が@lvlup-sw/exarchosではないことを判定条件とします)、invariants_scaffold/invariants_addはtier: devを拒否し、userを案内するRESERVED_TIERエラーを 返します。exarchos の正規のフォークでは、allowReservedTier: trueを指定して オプトインします。
- **
4. 適用 — デフォルトは mode: audit、mode: check はオプトイン
**デフォルトは mode: audit にしてください。**抽出したルールから audit-prompt を作成します。
これはレビュー用サブエージェントが差分を確認して回答する質問です。監査モードは
判断のみで完結し、常に移植可能です:
enforcement:
mode: audit
audit-prompt: >-
Does this diff let a request handler return before emitting an audit event?
Cite the offending file + line.
mode: check を提案するのは、そのルールを機械的にチェックできる場合の高度なオプトイン
に限ります。作成者がオプトインした場合は、grep/構造/ヒューリスティックのリーフを使った
宣言型コンビネーターツリーを提案し、表示する前に dryRun: true を指定して
invariants_add でリアルタイムに検証します。コンビネーターの語彙とオプトインの流れについては、
@references/check-mode.md を参照してください。強制適用 DSL は .strict() のみで、宣言型に
限定されています。script/exec/code のような回避手段はありません(INV-4)。
そのため、依頼されても実行可能なチェックは出力できません。
5. 番号付け — 対象名前空間での自動 ID 割り当て
ID を選ばないでください。invariants_add が対象カタログの名前空間における
次の空き ID を自動割り当てします(user は U-N、dev は INV-N)。ドライランの結果を
示す際には、動詞が割り当てた ID を記載してください。
6. コミット — ドライラン → 確認 → 書き込み → 検証
このステップは形式的な手続きではなく、必須のゲートです。 必ず次の手順を実行してください。
dryRun: true(デフォルト)を指定してinvariants_addを呼び出します。エントリーと差分が表示されますが、何も書き込まれません。- 表示されたエントリーとファイルの差分を、そのまま作成者に提示します。確認を明確に行い、「このエントリーをコミットしますか?」と尋ねてください。黙って再度呼び出してはいけません。
- 明示的な確認を得た場合に限り、
dryRun: falseを指定してinvariants_addを再度呼び出します。これによりエントリーが追加され、カタログが未登録の場合は.exarchos.ymlに接続され、invariant.authored(初回登録時はcatalog.registeredも)が出力されます(INV-1)。 doctor(invariants-catalogチェック)を実行し、解決されたカタログを検証します。invariants_effectiveの差分を提示し、ゲートで新たに適用される内容を作成者が正確に確認できるようにします。
invariants_add が CATALOG_NOT_FOUND エラーを返した場合、対象のカタログはまだ存在しません。まず invariants_scaffold を実行します(エラーの suggestedFix に呼び出し方法が示されています)。その後、ステップ 6 から再開してください。
7. 修正 — すでにコミット済みのエントリーを訂正する
ステップ 1〜6 では新しいエントリーを作成します。既存のエントリーを訂正する場合は別の操作であり、invariants_add は使いません。invariants_add は常に追記のみを行い、既存の id を指定して再実行すると拒否されます(DUPLICATE_INVARIANT_ID)。重複をコミットすると、ローダーがそのカタログを読み込めなくなるためです。
invariants_amend を使います。ID を対象とし、フィールド単位で適用されます。
idで訂正対象のエントリーを指定します。これは変更できません。すべてのreferences:ポインターと監査記録が古い ID を参照している場合、エントリーの識別情報を変更するとそれらが無効になるためです。名前の変更は修正ではありません。patchには変更するトップレベルフィールドのみを指定します。指定されなかったフィールドはすべて、そのまま引き継がれます。 エントリー全体を再記述する必要はなく、修正によってreferencesリストや、作成者が言及していないアフィニティが暗黙に削除されることもありません。指定したフィールドは全体が置き換えられます(enforcementをパッチすると、enforcementブロック全体が置き換わります)。- マージ後のエントリーは v3 スキーマ全体に照らして再検証されるため、作成時に拒否されるエントリーを修正によって生成することはありません。これには
.strict()enforcement DSL も含まれます(INV-4)。
ゲートはステップ 6 と同じです。まず dryRun: true(デフォルト)を指定し、変更前後の差分をそのまま作成者に提示し、明示的な確認を得てから dryRun: false を指定して再度呼び出します。これにより、変更されたフィールドを示す invariant.amended が出力されます。その後 doctor を実行し、invariants_effective の差分を提示します。
次の 2 種類の拒否に注意してください。
ENTRY_NOT_FOUND— その ID を持つエントリーがありません。エラーのvalidTargetsに実際に解決された ID が一覧表示されるため、その中から選ぶか、新しいエントリーを作成してください。CATALOG_EMPTY/CATALOG_UNREADABLE— カタログから解決されたエントリーが 0 件か、invariants:リストをまったく読み取れませんでした。どちらも単なる「見つからない」としては報告されません。移動または名前変更されたカタログを、目的のエントリーが存在しないだけのカタログと誤認してはいけないためです。正しいカタログを指定しているか確認してください。
ツール呼び出し
ユーザーカタログを作成します(冪等。既存の内容は上書きされません)。
exarchos:exarchos_orchestrate({
action: "invariants_scaffold",
tier: "user",
path: ".exarchos/invariants.md"
})
ドライランでプレビューします(デフォルト — 何も書き込まれません)。
exarchos:exarchos_orchestrate({
action: "invariants_add",
tier: "user",
catalog: ".exarchos/invariants.md",
entry: { /* the fields from steps 1-4; NO id — auto-assigned */ }
})
明示的な確認後にコミットします。
exarchos:exarchos_orchestrate({
action: "invariants_add",
tier: "user",
catalog: ".exarchos/invariants.md",
entry: { /* same entry */ },
dryRun: false
})
既存のエントリーを修正します — まずドライランを実行してください(注:変更するフィールドのみ指定し、それ以外はすべて引き継がれます)。
exarchos:exarchos_orchestrate({
action: "invariants_amend",
tier: "user",
catalog: ".exarchos/invariants.md",
id: "U-3",
patch: { summary: "The corrected one-sentence rule." }
})
明示的な確認後に修正をコミットします。
exarchos:exarchos_orchestrate({
action: "invariants_amend",
tier: "user",
catalog: ".exarchos/invariants.md",
id: "U-3",
patch: { summary: "The corrected one-sentence rule." },
dryRun: false
})
実行時に正確なスキーマを確認するには、exarchos:exarchos_orchestrate({ action: "describe" })(または CLI の --help)を使います。各アクションの Zod スキーマからフラグが自動生成されます(CLI はスキーマ駆動です。後から手動で追加されたフラグがあると想定しないでください)。
実例
U-* エントリーをステップ 1〜6 に沿って最初から最後まで作成する例については、@references/worked-example.md を参照してください。
アンチパターン
| しないこと | 代わりにすること |
|---|---|
カタログの YAML を手書きしたり、Edit で編集したりする | 変更は動詞を介して行います。新しいエントリーの追加には invariants_add、既存エントリーの修正には invariants_amend を使います |
既存の id を指定して invariants_add を再実行し、エントリーを「更新」する | invariants_add は追加のみです。重複する id は拒否されます。invariants_amend を使います |
| 1 つのフィールドを変更するためにエントリー全体を書き直す | invariants_amend はフィールド単位です。patch には変更する内容だけを指定し、それ以外はすべて保持されます |
エントリーの id を変更する | id はカタログの主キーであり、パッチ適用できません。古い ID への参照がすべて古くなってしまいます |
| エントリーが有効だと自分で宣言する | 動詞が検証し、あなたが確認します |
mode: check をデフォルトにする | mode: audit をデフォルトにします。check はオプトインです(@references/check-mode.md) |
| ドライランを省略する | まず必ず dryRun: true にしてから、明示的に確認します |
dryRun: false で黙って再実行する | 確認の手順を明示します |
| ID を手動で選ぶ | 動詞が名前空間内の次の未使用 ID を自動的に割り当てます |
コンシューマーリポジトリから dev/INV-N に登録する | dev は exarchos の予約済み基盤名前空間です。user/U-N を使います(動詞はコンシューマーの tier: dev を拒否します) |
| フレームワークから glob を推測する | glob を明示するよう作成者に依頼します(INV-6) |
コミット後に doctor と invariants_effective を省略する | 解決済みのカタログを検証し、差分を表示します |