検索/多言語のデータライブラリを、ファイル形式とAPIを壊さずに直す

多言語のデータライブラリを、ファイル形式とAPIを壊さずに直す

ネイティブコアと各言語の薄いバインディングでできた、速いデータライブラリをAIに直させる時に使う。安定版のファイル形式と公開APIの互換を守り、決められたコマンドを使い、テストと文書もそろえる。

このAIルールを使うには
## ネイティブコアと、ほかの言語向けの薄いバインディングの役割分担をつかむ リポジトリを、1つのネイティブコアと、他言語向けの薄いバインディングからなるものとして扱う。コアはデータ形式の動作、エンコーディング、圧縮、ファイル、インデックス、I/O、オブジェクトストレージ、線形代数、テーブル操作、任意追加のドメイン、テスト基盤、開発者ツールを担う。バインディングは検証やビジネスロジックを重複させず、その動作を外部へ提供する。 非同期I/O、ネイティブな列指向メモリ、マニフェスト追跡を伴うバージョン付き書き込み、ワークロード指向のエンコーディング、ローカルとリモートのオブジェクトストレージに共通する1つのストレージ抽象化という、アーキテクチャの主要特性を保つ。 コマンドやコード変更を計画する前に、リポジトリガイドと、影響を受ける各言語またはディレクトリのガイドを読む。ディレクトリ固有の規則はリポジトリ契約を置き換えるものではなく、より具体化するものである。 ## 安定版の形式は互換を守り、不安定版は自由に変える 安定版と宣言されたすべての形式を、永続的な互換性契約として扱う。安定したデータへの変更は、後方互換性と前方互換性の両方を維持しなければならない。 不安定版と宣言されたすべての形式を使い捨てとして扱う。自由に変更してよいが、以前の不安定なリビジョンで作成したファイルのために、互換コード、移行処理、代替処理、テストを追加してはならない。 すべての安定版契約を引き続き守りながら、最新リリースの安定版を基準に新しい互換性対応を評価する。現在の開発ブランチにしか存在しない状態は互換性制約ではない。未リリースの中間状態を維持するためだけに、より明快または完全な設計を弱めてはならない。 ## 決められたコマンドとビルドプロファイルを使い、別のツールチェーンに替えない 対象言語について文書化されたチェック、テスト、リント、書式整形、カバレッジ、ベンチマーク、統合の各コマンドを、実行前に確認する。並行する独自手順を考案せず、リポジトリが用意するパッケージとテストのセレクターを使う。 コマンドが見つからない、遅い、または利用できないように見えるという理由で、別の環境管理ツールやツールチェーンへ置き換えてはならない。言語固有のコマンドが文書化された手順の外で失敗した場合、まず環境の使い方を正し、指定されたコマンドを再実行する。その後に限り、依存関係やツールが利用できないと判断する。 その場限りの最適化上書きではなく、リポジトリで定義されたコンパイルプロファイルを使う。ベンチマークとプロファイリングには、デバッグシンボルを保持した最適化ビルドを使う。リンク時最適化を無効にしてよいのは、ローカルデバッグ、I/Oがボトルネックとなるベンチマーク、またはリンク時最適化が測定対象のボトルネックに影響しないコンパイル時間調査だけである。 統合テストでは、必要なフィクスチャサービスだけを起動し、文書化された環境値を設定して、指定された統合ターゲットを実行する。 ## データをメモリにため込まず、変更を絞ったコードを書く コード、例、コメントには英語を使う。コードは実行だけでなく、読みやすさも最適化する。コメントは自明でない理由を説明する場合にだけ追加し、レビュー前に直接的なデバッグ表示を残さず、既定のトレーシングまたはロギングシステムを使う。 2か所以上で繰り返すロジックは、共有ヘルパーへ抽出する。1回しか使わないロジックは呼び出し元に置く。認知負荷を実質的に下げるか、大きな重複を解消する場合にだけヘルパーを導入する。呼び出しの名前を変えるか転送するだけの薄いラッパーを追加してはならない。 変更の焦点を保つ。ついでのリファクタリング、書式変更、外観だけの編集を避ける。バッチをメモリに集めずストリーミング動作を維持し、密な整数の所属判定には汎用ハッシュセットよりコンパクトなビットマップ構造を優先する。 ## バインディングを薄く保ち、古い公開APIは壊さず非推奨にする 検証とロジックをネイティブコアへ集約し、各言語バインディングを薄いラッパーとして保つ。すべてのバインディングで同じパラメータ名を使い、名前を変更するなら全体で変更し、そうでなければどこも変更しない。 既存の公開シグネチャをその場で破壊してはならない。その言語が対応するアノテーションで古いメソッドを非推奨として扱い、新しいメソッドを追加する。互いに排他的な複数の真偽値フラグは、1つの列挙型またはモードパラメータへ置き換える。 コアの動作を変更する場合、適用対象となる各バインディング、生成インターフェース、例、互換性テストを一緒に更新する。コアが拒否する値を、バインディングが暗黙に別の意味へ解釈してはならない。 ## 値は中身で名前を付け、無効な入力は分かるエラーで拒否する 変数には用途ではなく、その値が何であるかに基づく名前を付ける。含まれる型やモジュールがすでにドメインを示す場合は、重複する接頭辞を省く。APIと文書では、承認された1つの複数形を一貫して使い、特定のプロバイダーに依存する用語よりストレージ中立な名前を優先する。 型、構造体、列挙型の名前を変更する場合は、メソッド、フィールド、変数、テスト、文書を一緒に更新する。 API境界で入力を検証し、無効な値は内容が分かるエラーとともに拒否する。暗黙に上限や下限へ丸めたり調整したりしてはならない。互いに排他的なビルダーまたは設定の選択肢が両方指定された場合は拒否する。エラーメッセージには関連する変数名、値、サイズ、型を含める。 ## 依存関係を増やしすぎず、ロックファイルをそろえる 外部パッケージを追加する前に、標準ライブラリまたは既存のワークスペース依存関係を優先する。ロックファイルの変更を意図したものだけに保ち、無関係なアップグレードは元へ戻す。不具合のある依存関係を固定する場合は、上流Issueへのリンクを含むコメントを必須にする。 ワークスペース依存関係を変更した場合、文書化されたマニフェスト固有のチェックを通して、ルートのロックファイルと、ワークスペースから除外された各バインディングのロックファイルを更新し、対応する変更をすべてコミットする。オフラインのロックファイル同期フックを有効に保つ。 任意追加またはドメイン固有の依存関係は、機能フラグの背後に置く。実質的なドメイン機能には別パッケージを優先し、既定ビルドや利用側が不要なコードを引き継がないようにする。 ## 不具合の修正と新機能には、必ずテストを付ける すべての不具合修正と機能には対応するテストが必要である。テストのないコードを受け入れてはならない。 ケース間の違いが入力だけである場合は、その言語のパラメータ化テスト機能を使い、ケースに読みやすい名前を付ける。表示するだけではリグレッションを検出できないため、テスト内の表示処理はアサーションへ置き換える。 既存テストがすでにその動作を担当している場合は、重複するテストファイルを追加せず、既存テストを拡張する。追加分は既定のテスト配置に置く。スキップするテストは追跡用Issueへリンクしなければならず、永続的な理由のないスキップアノテーションだけを追加してはならない。 ## null や空のデータと、古い安定版のファイルでテストする 読み取り、インデックス、スキャンには複数フラグメントのシナリオを含める。インデックステストでは、null要素、全要素がnullのコレクション、空のコレクション、null列を網羅する。ベクトルインデックスのテストでは、インデックス作成の成功だけを確認せず、再現率が0.5以上であることをアサーションで検証しなければならない。 後方互換性の確認には、以前の安定版が生成し、バージョン管理されているデータセットを使う。生成元のバージョンをアサーションで確認するデータ生成スクリプトを維持し、読み取る前にこれらのフィクスチャを一時ストレージへコピーする。 コンパイルを避けるためだけに文書テストを無効にしてはならない。関数形式の文脈内でコンパイルできる例を書く。実運用コードのカバレッジ閾値を弱めず、プロジェクトで承認されたカバレッジアノテーションを使ってテスト専用ユーティリティをカバレッジ対象から外す。 ## すべての公開APIに、コンパイルできる例を付けて文書にする すべての公開APIを文書化し、例を含める。関連する型とメソッドへリンクし、コードをリファクタリングした時は、例を実際のシグネチャと同期させる。 エンコーディング層、ファイル形式、ストレージ配置などの階層構造にはASCIIツリー図を使う。注意書きディレクティブの配下を4スペース字下げする規則を含め、文書システムのインデント規約に従う。 レビュー前にコメントと文書の誤字を確認する。コンパイルできなくなった文書や古いAPI名を記載した文書は、外観上の問題ではなく互換性の不具合である。 ## Issueにラベルを付け、変更リクエストの前にリントを通す コマンドラインツールまたはAPIでIssueを作成する場合、テンプレートのオートメーションを経由しない可能性があるため、不具合、機能、性能の作業に対応するラベルを明示的に渡す。内容に基づくオートメーションが確実な補助シグナルを得られるよう、タイトルの先頭に一致する分類を付ける。 リポジトリで定められた変更タイトルの接頭辞を使い、必要に応じてスコープを加える。変更リクエストを作成または更新する前に、負荷が高くても、変更したすべての言語領域で必須のリントチェックを実行する。 各言語ガイドの環境手順に従って、その言語のリントコマンドを実行する。必須チェックを実行できない場合、検証が完了したように示さず、変更リクエストの要約に阻害要因を明記する。 ## レビューは、重大な不具合とセキュリティの問題に絞る コントリビューターと保守担当者の注意力には限りがある。レビューは簡潔で明確に保ち、最も重大な不具合、性能リグレッション、セキュリティ上の懸念に焦点を当てる。 変更の詳細を言い直したり、すでに正しい点を繰り返したりしない。命名の一貫性、既定のエラー処理パターン、テスト網羅性を確認する。作業を止める指摘ごとに影響箇所を示し、具体的な結果を説明する。