id: ADR-016 title: Holding-crate の例外は、上限を設け、記録し、Core Team が付与する date: 2026-09-02 status: 提案中 relates-to:
- ADR-007
- crates/zeroclaw-runtime/AGENTS.md
- docs/book/src/foundations/fnd-001-intentional-architecture.md
- https://github.com/zeroclaw-labs/zeroclaw/pull/10557
- https://github.com/zeroclaw-labs/zeroclaw/pull/10410
- https://github.com/zeroclaw-labs/zeroclaw/pull/10179
ADR-016: ホールディングクレートの例外は、範囲を限定し、記録し、コアチームが承認する
コンテキスト
crates/zeroclaw-runtime/AGENTS.md は、そのクレートを移行途中の一時的な置き場所として定義し、新機能をそこに追加しないよう貢献者に指示し、抽出待ちのサブシステムを列挙しています。この指示は無条件であり、例外を申請する手続きはありません。
このような組み合わせでは、通常のケースに対する答えがありません。承認された作業は、まだ保持用クレート内にあるサブシステムに入ることになりますが、移動先のクレートはまだ作成されていません。契約上、利用可能な唯一の配置先は禁止されており、移動先はまだ存在しません。3つのプルリクエストがこの状態に到達し、それぞれ異なる3通りの方法で解決しました。
cron の前提条件ゲートは、#10220 を経て、暫定的な例外案を経て、最終的に #10557 で全面的に切り出されました。切り出しは正しい結論でしたが、その結論に至るまでに完全な代替案を二つ作成し、一つを破棄することになりました。貢献者は、切り出しが必要かどうかを、それを二度実装する前に確認できるべきです。
#10410 は、計画されているデーモン抽出に先立ってライフサイクル用のクレートを新設するのではなく、共有設定とエージェントのライフサイクル調整をランタイム内に残しました。この配置の根拠として挙げられているのは、コードを zeroclaw-infra に移すと既存の依存関係が逆転してしまうことです。config はすでに infra に依存しているためです。また、早期に抽出すると、ロードマップが意図していない境界を確立することになる、という点も挙げられています。これは、そこでの例外を認めるための論拠であって、確定した結論ではありません。この配置はまだ承認されておらず、#10410 は、本記録が確立するプロセスの下で、それ自体の明示的な処理方針を必要とします。
#10179 も同じルールに抵触しましたが、そのトランスポートには受信側の呼び出し元がありませんでした。そこでは、例外を設けるよりも、廃止するか、所有権を明示的に決定するほうが適切な対応でした。
これら3つのケースは、規模の違いではなく性質そのものが異なります。1つ目では抽出が釣り合いの取れた対応でしたが、2つ目では誤った境界が生じていたはずで、3つ目では的外れでした。単一の無条件の指示ではこれらを区別できず、例外について何も書かれていないため、貢献者はそれぞれ推測するしかなくなっています。
代替案は、指示を無条件のまま維持してすべてのケースで抽出を必須とすること、全般的に緩和すること、または抽出を既定とし、限定的な例外の付与方法を定義することです。
決定
Extraction remains the default. なお、即時の抽出によって不釣り合いな大規模リファクタリングが必要となる場合、または今後のロードマップが意図していないクレート境界を確立してしまう場合には、コアチームが期限付きの例外を承認することがあります。
What an exception must state
Translation to Japanese:
例外が必ず示すべき内容
承認された例外には、次の4つすべてが記載されています:
- 許可範囲。 例外が適用される具体的なパス。抽象的なサブシステム全体ではない。
- 移行先。 コードの移動先として想定しているクレート。これにより、この例外は取り消しではなく遅延を表すものになります。
- 承認権限者。 承認を付与した者。
- 有効期限または見直し条件。 何によって終了するか、または いつ再検討するか。記録には、そのどちらであるかを明記する必要があります。両者は挙動が異なるためです(後述を参照)。
有効期限の意味
例外はexpires(期限切れ)またはreview(見直し)のいずれかになり、記録にはどちらかが示されます。
期限が切れると許可は終了します。その後、対象範囲への追加には Core Team による更新が必要です。例外の下で既にマージされたコードを削除する必要はありません。許可は遡ってではなく将来に向かって失効するものであり、既に受け入れられたものを巻き戻すことは、日付の経過の結果ではなく、切り出し(extraction)作業の役割です。
A review condition does not end anything by itself. It obliges the Core Team to reconsider, and the outcome of that reconsideration is renewal, expiry, or extraction. レビュー条件は、それ自体で何かを終了させるものではありません。Core Teamに再検討を義務付けるものであり、その再検討の結果は、更新、失効、または抽出のいずれかになります。
付与方法
The record is created before the feature merges, and separately from it. A feature pull request cannot grant itself an exception, because the contract it would be waiving is the one constraining it.
Wait—I need to correct myself: the system instructions say to translate to ja. I’ll translate now.
記録は機能のマージより前に、かつそれとは別に作成されます。機能のプルリクエストが自ら例外を付与することはできません。なぜなら、それが免除しようとしている契約こそが、その機能自体を拘束しているものだからです。
例外が認められるのは、具体的な対応ユースケースがある場合に限られます。受け取る呼び出し元が存在しないコードは該当しません。その場合の正しい対応は、廃止するか、所有者を明示的に決めることです。
個別の例外が記録される仕組み
例外は、他のリポジトリ上の決定と同じ方法で付与されます。すなわち、所有するクレートの AGENTS.md にある有効な例外テーブルへエントリを追加するプルリクエストをレビューし、Core Team の承認を得ることによってです。別個の仕組みはなく、通常のレビュー規則の外での承認もありません。
エントリそのものが記録となります。レビュースレッドにしか存在しない決定は、行われていないものとみなされます。契約書を後から読む人が、その決定を見つけられないためです。
“What an exception is not“を日本語に翻訳します。
例外とは何ではないか
例外によって、保持クレートにすでに含まれているサブシステムでの作業を継続することは認められます。新しいサブシステムをそのクレートに導入することは決して認められず、あるサブシステムに対する例外を別のサブシステムへ一般化することもありません。cron に対して例外が与えられたとしても、daemon については何も示していません。
導入
このレコードは、無条件の禁止を一定の条件下での許可に変更するものであり、通常のドキュメント編集ではなく、ガバナンスおよびコントリビューションプロセスの変更に該当します。この経路は FND-003 §8 で規定されています。
その採用は、コアチームが明示的に決定して記録すべきものであり、FND-003 §8 のどの経路が適用されるかも含めて記録する必要があります。このプルリクエストは具体的な提案であって、採用そのものではありません。その決定が記録されるまで、無条件の指示は有効なままであり、いかなる例外も許可されていません。
結果
コントリビューターは、実装後ではなく実装前に解決できる判断経路を得られます。cron の件では、事前に短い記録で答えを出せた問いに対して、完全な実装を二度行う必要がありました。
すべての例外は可視化され、日付が記録されています。holding-crate契約内のアクティブな例外テーブルによって蓄積された負債が明確になり、各エントリにはそれを解消する条件が明記されているため、いつの間にか恒久化してしまった例外は、埋もれることなく明らかになります。
コアチームは、均衡性の判断を個別の事例ごとに行います。これは意図的な方針です。上記の3つの事例が示すように、この判断は規模のしきい値に還元できません。「過度なリファクタリング」と「誤った境界」は、同じ症状として現れるものの、理由は異なるからです。
保管用クレートに関する指示は、その効力を保ちます。これは指示を弱めるものではなく、指示が前提としていたものの定義されていなかった手順を補うものです。
受け入れ
ADR-016 は次の条件を満たすまで「提案中(proposed)」のままです:
crates/zeroclaw-runtime/AGENTS.mdは例外ルールを定めており、有効な例外のテーブルを含んでいます。- 少なくとも1件の例外申請がこの手続きを通じて承認または却下されており、この手続きが文書上の定めにとどまらず実際に利用可能であることを示しています。