検索/一般に配るサーバーパッケージを、拡張して使う側を壊さずに直す

一般に配るサーバーパッケージを、拡張して使う側を壊さずに直す

ほかのコードがフックで拡張して使う、一般に配るサーバーパッケージを直す時に使う。秘密情報を入れず、コールバック・フック・ミドルウェアの順番を壊さず、古いマイグレーションは直さず新しく足し、パッケージに実際にあるテストとlintを回す。

このAIルールを使うには
## 一般に配られる中身を確かめ、秘密情報を入れない 編集前に、パッケージの配布先、ライセンス、モジュール方式、言語、実行時の役割、同期経路を特定する。開発を非公開の作業環境で行っている場合でも、一般向けに同期されるパッケージ内のすべてのファイルを配布内容として扱う。 - 秘密情報、ライセンスで利用を制限する動作、内部専用のフィクスチャを一般配布パッケージ内に置かない。 - サーバー専用パッケージはヘッドレスのまま保ち、ブラウザーやDOMへの依存を持ち込まない。 - 隣接パッケージのパターンを流用せず、そのパッケージで実際に使われているモジュールと言語の規則に合わせる。 - 作業環境内の直接的な依存元を記録し、ほかにも外部のパッケージ利用者が存在すると想定する。 作業環境内で見える依存元が1つだけでも、一般配布によって影響範囲は広がる。 ## 古いコールバックの形と、深い階層からのimportを壊さない コールバックを暗黙のうちにPromiseやasync関数へ変更しない。新旧の方式が混在するコードでは、近くの呼び出し箇所が同期式またはPromise方式でも、拡張フックがコールバックの形に依存している場合がある。 呼び出しを変更する前に: 1. 拡張点のすべての実装を列挙する。 2. 引数の順序、戻り値の動作、コールバックのタイミング、エラーの意味を比較する。 3. 変更対象ファイルの書式に合わせる。 4. サポートする各呼び出し形式のテストを追加または更新する。 内部用に見えるユーティリティ、ミドルウェア、モデルのファイルは、下流リポジトリで深い階層からのimportが使われていないか検索するまで、名前や場所を変更しない。ソースパスからのimportは暗黙の公開APIであり、コンパイラーの警告なしに壊れる可能性がある。 ## ミドルウェアの順番とフック名を正しく守る ミドルウェア間の依存関係を明示的に保つ。権限判定が設定済みのユーザーコンテキストを参照する場合、認証または資格情報の解決を権限チェックより先に実行しなければならない。順序の変更は書式整理ではなく、契約変更として扱う。 新しいミドルウェアには、リクエストハンドラーを返すパッケージ対応ファクトリーなど、そのパッケージで確立されたファクトリー形式を踏襲し、中央チェーン内の意図した位置に登録する。 既存の変更フック機構を拡張面として使う。呼び出し箇所を追加する前に、現在のすべてのフック名と実装を検索する。正確な名前、入力値、コールバックまたは戻り値の形、既定動作を確認する。フック名のタイプミスによって、気付かないまま既定値が返る場合がある。 下流の実装者が見つけられる場所に、新しい拡張点をすべて文書化する。 ## 配布済みのマイグレーションは直さず、新しく足す 並行する独自パターンを作らず、確立された基底抽象化に従う。新しいデータモデルでは共有モデルプラグインまたは基底形式を使う。新しいトップレベルRESTリソースは共通リソース基底を継承し、中央のエントリーポイントを通じてルートを登録する。 配布済みのデータベースマイグレーションは変更不能かつ一方向のものとして扱う: - リリース後に既存のマイグレーションを編集しない。 - 後から行う修正ごとに、新しい番号付きマイグレーションを追加する。 - 各マイグレーションを冪等にする。 - 中断と起動処理の反復実行を考慮する。 - 新規データベースとマイグレーション済みデータベースの両方で動作を検証する。 下流パッケージがフックを通じてモデルのフィールドや動作を注入する場合、スキーマ、既定値、シリアライズ、ハイドレーションを変更する前に、その注入箇所を監査する。 ## 変更が影響するほかのパッケージを探し、両側をテストする 実装前に変更とその利用者の対応関係を整理する。認証ミドルウェア、権限処理、セッション境界、共有ユーティリティ、暗号化ヘルパー、モデルフック、拡張点のシグネチャを変更する場合は、下流の呼び出し元と調整する。 深い階層からimportされるヘルパーを公開APIとして扱う。資格情報とセッションのどちらが所有するかという区別を、アーキテクチャ上の境界として扱う。値を参照として保存し、読み取り時にハイドレーションする場合は、その表現を変更する前に書き込み側と参照解決プロセッサーの両方を監査する。 横断的な編集ごとに: 1. 関連するアーキテクチャ、依存関係、既知の注意事項を読む。 2. 下流の実装と呼び出し箇所を検索する。 3. 維持すべき契約を明記する。 4. 境界の両側をテストする。 5. 意図的な契約変更と、その移行経路を文書化する。 ## 仮想マシンの境界を越える値が壊れないかテストする 仮想マシンのバンドル、互換シム、評価器インスタンス、リソース上限、エラーの意味を変更する場合は、クライアントとサーバー間の契約を全面的に監査する必要がある。ホスト側とサンドボックス側のシムを同等に保ち、バンドルを再構築し、値が実行環境の境界を越えて保持されることを検証する。 分離された実行環境を通じてシリアライズした後も、稼働中のデータベースオブジェクトが同一性やプロトタイプを維持すると想定しない。識別子、参照、日付、バッファー、エラー、ハイドレーション済みの値を、両方向でテストする。 モジュール読み込み時に初期化される互換シムが、プロセス全体のホスト状態を変更する可能性に注意する。パッケージをヘッドレスのまま保つ想定でも、擬似ブラウザーコンテキストがグローバル状態を作る場合がある。 カバレッジ対象外のバンドルコードを既知のテスト不足として扱い、通常のカバレッジで証明できると想定せず、対象を絞った実行チェックを追加する。 ## 起動時にデータベースの機能を調べ、代わりの道を用意する 起動時に能力を調査し、複数のデータベース実装をサポートする。高度な照合順序、検索パイプライン、複合的な入れ子パスのインデックスなど、基準を超える機能は調査結果に基づいて有効化し、テスト済みの代替経路も提供する。 実行環境から能力マップを取得できる場合、製品名やバージョン文字列から互換性を推測しない。変更が繰り返し差し戻されていることは、能力調査と代替処理の経路が契約の一部である証拠となる。 一般配布パッケージの動作が機能フラグに依存していても、そのパッケージから非公開レジストリをimportできない場合は、フラグの正確なキー文字列を指定して確立済みの拡張フックを呼び出す。レジストリと照合してキーを検証し、有効時と無効時の両方をテストする。非公開レジストリのロジックを一般配布パッケージへ埋め込まない。 ## パッケージに実際にあるテスト・lint・ビルドを回す パッケージが実際に提供するスクリプトを基準に「合格」を定義する。JavaScriptのみのパッケージであれば、存在しない型チェック工程を作り出さず、完全なテストスイートとlinterを実行することが基準になり得る。変更がバンドルされた実行時の出力に影響する場合は、buildを実行する。 テストが自動検出されない場合、新しいテストファイルをすべてスイートの中央importerへ登録する。未登録のテストファイルには保護効果がない。調査範囲を絞るにはサポート対象のテスト名フィルターを使ってよいが、完了前には必須スイート全体を実行する。 自動修正を行うlintコマンドは慎重に扱い、差分を確認する。テスト、lint、関連するバンドルbuildが合格したことを確認し、実行環境または互換性の問題を示す警告は残す。 ## 完了と言う前に、影響する範囲を全部確かめる 最も近いファイルではなく、影響を受ける契約から始める。既知の注意事項と下流の依存関係を検索し、互換性を保つ最小の変更を行い、完了報告前に一般配布の安全性を検証する。 最終レビューでは次を確認しなければならない: - 秘密情報、利用制限対象、内部専用の素材が一般配布パッケージへ入っていない。 - コールバック、フック、深い階層からのimport、ミドルウェア順序の契約が維持されている。 - マイグレーションが追加方式で冪等になっている。 - 影響を受ける場合に、モデル、参照、仮想マシン、データベース能力の境界をテストしている。 - 新しいテストが登録され、パッケージ固有の実際の品質ゲートに合格している。 - 必要な箇所でパッケージ間の呼び出し元と文書が更新されている。 - 互換性を壊す変更またはメジャーリリースの変更が、すべての配布先と調整されている。 作業環境内の依存数が少ないという理由だけで、変更が隔離されていると判断しない。一般の利用者も引き続きリスクモデルに含まれる。