


Rustのリバースプロキシを、イベントループやセキュリティを壊さずに直す
マルチプロセスのRustプロキシをAIに変更・テスト・リリースさせる時に使う。ビルドとフィーチャーフラグ、エラーとログ、イベントループとプロトコルの動き、テストとファズ、セキュリティに関わるコード、プルリクエスト、リリースの手順の決まりを示す。
このAIルールを使うには
## プロキシのライブラリの層と、依存の向きを守る
リポジトリを、依存方向が明示された階層型システムとして扱う。
- コントロールプレーンのライブラリは、設定解析、コマンドスキーマ、共有状態、ログ補助機能、プロセス間チャネルを担う。
- プロトコル/ランタイムのライブラリは、シングルスレッドのイベントループ、ルーティング、ソケット、バッファ、メトリクス、TLS、HTTP、PROXY protocolの処理を担う。
- バイナリクレートは、スーパーバイザ、ワーカー、CLI、設定読み込み、ホットリコンフィグレーション、アップグレード、コマンドサーバーを担う。
- 統合テストと決定論的シミュレーションのクレートはランタイムライブラリへ依存してよいが、asyncやテスト専用の依存関係を本番コードへ漏らしてはならない。
- ファズターゲットは、必要なツールチェーンが異なる場合、メインワークスペースの外に置いてよい。
ランタイムからコントロールプレーンへ向かう依存方向を維持する。各ワーカーをシングルスレッドに保ち、イベントループで共有ミューテックスを避け、アーキテクチャを意図的に再設計しない限り、本番ライブラリへasyncランタイムを持ち込まない。
## 固定のツールチェーンでビルドし、フィーチャーの組み合わせをテストする
コードを変更する前に、固定されたRustツールチェーンと必要なコード生成器を特定する。スキーマ生成が必須の前提条件なら、コンパイル失敗の意味を判断する前に、その生成器を導入済みか確認する。
通常のビルドとテストでは依存関係をロックする。リポジトリ設定が要求するツールチェーンでフォーマッタを実行し、警告を許容せずにlintを実行し、リリース関連の作業前にワークスペース全体をテストする。反復作業中は対象を絞ったスイートを使い、その後、影響を受けるワークスペース単位のゲートへ戻る。
フィーチャーフラグは、明示的な互換性セルとして扱う。
- 既定のアロケータと暗号方式の選択を文書化しておく。
- コンプライアンス対応モードを含め、対応する各暗号プロバイダを個別にテストする。
- 本番ビルドでは、テスト用の注入フックを絶対に有効にしない。
- debug/traceログ、パーサーの寛容化、SIMD、ゼロコピーI/O、テレメトリが挙動、容量、観測可能性を変える場合は、明示的に選択する機能として維持する。
既定ビルドが1回通っただけで、変更に問題がないと報告してはならない。変更の直接影響を受けるフィーチャーの組み合わせを確認する。
## パニックさせずにエラーとログを扱い、生成コードは手で直さない
ライブラリでは構造化されたエラーを使い、広い文脈情報は実行可能ファイルとの境界でだけ加える。ネットワークから制御可能な入力は、プロトコルエラー、接続操作、メトリクス、文脈付きログへ変換しなければならず、リリース経路で`unwrap`、`expect`、`panic`、到達不能分岐を絶対に引き起こしてはならない。
近接コードの所有権規約に従う。借用された文字列やバイト列を所有値へ変換する時は意図が明確な変換を優先し、型がすでに所有済みで複製可能なら通常のcloneを使う。
プロトコルモジュールは、既存の文脈付きログマクロと安定した検索タグを使わなければならない。運用者が障害を関連付けられるよう、標準のセッション/リクエスト/バックエンドのエンベロープを維持する。想定内のアイドル切断や頻繁な状態記録にはdebugまたはtraceを使い、実際のプロトコル障害や不変条件違反にだけwarningまたはerrorを使う。
外部向けメトリクスは中央のメトリクス層に置き、追加または名称変更を行った時は利用者向けの設定リファレンスを更新する。ゲージのアンダーフローは正しさの問題として扱う。
生成されたプロトコルバインディングを手作業で編集してはならない。元のスキーマを編集し、ビルドを通じて再生成する。ホットパスへ新しいunsafeコードを追加する場合は、近くに不変条件の説明と対象を絞ったテストが必要になる。
## ソケットの書き込みとバッファで、イベントループを止めない
エッジトリガーI/Oでは、読み取り経路からバイト列をキューへ入れるだけでは足りない。書き込み待ちのレディネスを明示的に通知する。その通知が欠けると、特定のフレーム境界またはバッファ境界でだけセッションが停止する。
単一バッファとベクタのソケット書き込み実装は、再試行や部分書き込みの処理を含め、構造を対称に保つ。暗号化されたフロントエンドでは、リセットを送出してキュー済みバイト列を途中で切る可能性がある全二重シャットダウンを避ける。書き込み側だけを閉じ、相手側の切断は通常の読み取り経路で処理する。
最大プロトコルフレームとそのヘッダを収容できる大きさのバッファを維持する。小さなバッファによってフレーミングコードがデッドロックする状態を許さず、起動時に設定を検証する。
ワイヤレベルの接続状態と、バッファを所有するストリーム状態を分離し、ライフサイクル規則で検査される安定した識別子を使って相互参照する。フロントエンドのプロトコルネゴシエーションとバックエンドの機能ヒントは別概念であり、一方をもう一方の意図しないゲートとして使わない。
フラッド制御は、リセットの集中、連続する継続フレーム、制御フレームの反復、優先度の悪用をすべて扱わなければならない。マルチプロセスのホットリコンフィグレーションでは、シングルスレッドのワーカーへコマンドを配る前に、スーパーバイザで検証する。
## ファズと再現できるシミュレーションを含め、層ごとにテストする
モジュールに隣接する単体テスト、プロセスレベルの統合テスト、ファズターゲット、sans-I/Oステートマシン用の決定論的シミュレーション、ログ配置などの構造契約を守る回帰ガードという、相互補完する5つのテスト層を使う。
パーサーと非自明なステートマシン関数では、デバッグビルドに事前条件、事後条件、肯定側と否定側を対にしたアサーションを組み込む。ステートマシンの外部向けエントリポイントは、不変条件の全走査で終了させる。アサーションは内部的に起こり得ない状態を表すものであり、敵対的なネットワーク入力には安全なプロトコル結果を返さなければならない。
決定論的シミュレーションは、シード付き乱数源、仮想時刻、敵対的ワークロード、障害注入で駆動する。すべての失敗を再現できるようシードを記録する。シミュレーション専用のランタイムフラグと依存関係は、シミュレーションクレートだけに限定する。
統合テストではポートを動的に割り当て、1セグメントだけでなく完全なTCP応答を読み取り、任意のsleepではなく明示的な期限または条件成立まで再試行する仕組みを使わなければならない。無視するテストには具体的な環境依存または追跡可能な理由が必要であり、回帰を隠すためにignoreを使ってはならない。
アップグレード、パーサー、圧縮、フレーミングを変更する時は、一般テストに加え、専用の統合スイートと対応するファズターゲットを実行する。
## TLS・パーサー・フレーミングは、回帰テスト付きで慎重に変える
TLS設定、プロトコルネゴシエーション、名前の結び付け、証明書読み込み、パーサーとヘッダの正規化、フロー制御、コマンドフレーミング、ディスクリプタ受け渡し、メトリクス、ログは、慎重かつテストに裏付けられた変更だけを行う。
実際に適用したフレーミングと異なる表現を転送せず、曖昧なメッセージフレーミングを拒否する。疑似ヘッダの順序、Content-Lengthの整合、リクエストスマグリング対策、正しいリセットまたは正常終了の意味を維持する。
コマンドチャネルでは、長さプレフィックス、部分メッセージ、ファイルディスクリプタ転送、状態再生、バッファ境界を検証する。PROXY protocolの処理では、部分ヘッダ、過大ヘッダ、ヘルスチェックのトラフィックを扱う。
ログやメトリクスを通じて機密値やセンシティブな値を露出させない。すべてのエラー経路と終了経路で、カウンタとゲージの正しさを保つ。
イベントループまたはセキュリティ関連コードを変更する時は、その不変条件だけを対象とする回帰テストを加えてから、隣接するプロトコルテストを実行する。無関係なリファクタリングを同じ変更へ混ぜない。
## プルリクエストに、プロトコルとセキュリティへの影響を書く
複雑なプロトコルサブシステムを変更する前に、正本となるライフサイクル文書またはアーキテクチャ文書を読む。古い文書は手掛かりとして扱い、そこにあるファイル参照を現在のコードと照合する。
対象範囲を示すブランチ名と、影響を受けるサブシステムを特定できる規約準拠のコミットメッセージを使う。リポジトリの署名とsign-off方針に従う。タスクで反映が許可されている場合はコミット済みブランチをpushし、実行されたCIを報告する。それ以外の場合は、ローカルで許可された境界で止める。
進行中の統合ブランチが明示されていない限り、現在の既定ブランチを基点にする。プルリクエストには、プロトコルまたはセキュリティへの影響、実行したコマンド、追加したテスト、文書変更を記載する。コード所有者とコントリビュータライセンスのゲートを尊重する。
設定キー、メトリクス、コマンドラインフラグ、アップグレード要件を含め、利用者または運用者に見える挙動が変わる時は、変更履歴と設定リファレンスを更新する。
引き渡し前に差分を見直し、生成ファイル、フィーチャーの意図しない漏出、テスト不足、古い参照、無関係な編集がないか確認する。
## リリースは承認を得てから行い、ホットアップグレードを先にテストする
デプロイは独立した承認対象の工程として扱う。まず依存関係をロックまたは固定してリリース成果物をビルドし、その後、ステージング相当の環境で設定を検証して、影響を受ける準備完了ゲートを実行する。
コンテナとOSパッケージには、スキーマ生成器とプラットフォームライブラリを含め、ローカルで使うものと同じビルド前提条件を導入しなければならない。ツールチェーンを固定し、テスト専用の依存関係を本番成果物へ含めない。
イベントループまたはワーカーライフサイクルの回帰は、ワーカー数を1、automatic restartを無効、backtraceを有効にして再現する。これにより、スーパーバイザの復旧によって最初の失敗が隠されるのを防ぐ。
ホットアップグレードでは、リスナーとセッションを引き渡す際の不変条件を維持しなければならない。リリース前にアップグレード経路を明示的にテストする。通常の再起動が成功しただけで、ディスクリプタ転送または状態再生が機能する証拠としてはならない。
明示的な承認とロールバック経路がない限り、本番へデプロイせず、資格情報を変更せず、破壊的な復旧を実行しない。ビルドしたもの、通過したゲート、未検証の項目、作業を止めた正確な境界を報告する。
