リファクタリング候補
重複、呼び出しごとの I/O、デッドコード、過剰設計についてのワークスペース全体の監査。評価した上で却下したものも含む。
英語版が原文です。
重複、呼び出しごとの I/O、デッドコード、過剰設計について、packages/ 全体を 2026-09-01 に監査した
結果です。要点: このコードベースは、重要なところではすでに関数的でテーブル駆動になっています —
policy.py の純粋な決定関数、デプロイメント上書きつきのカインド別テーブルとしてのエコノミクス、
唯一のレジストリとしてのエントリーポイント。見つかったのはパッケージをまたぐ繰り返しと、呼び出し
ごとに行われる I/O でした。
実行可能な 4 つの節はすべて着地しました。それを運んだ 2 つのプルリクエストにまたがる計測値は、 ソースファイルのみで 正味 99 行の削減、新規テスト 200 行、アーキテクチャ変更なしです。ここでの 見積もりは正味 450〜500 行で、高すぎました。1 節は削除ではなく振る舞いを必要とすると分かり、 そこで名指しされた修正はどれも、それを固定するテストとともに着地したからです。
この監査は行番号ではなくファイルとシンボルを名指しします。誰も再監査しないページ上の行番号は、 観察そのものより早く腐るからです。編集の前に現在の形を確認してください。
以下のどの変更も、次を尊重しなければなりません。plan_id とスナップショット ID のバイト安定性
(あるいは POLICY_VERSION の引き上げ。ADR-0005
を参照)、tests/unit/test_workspace_boundaries.py が固定する依存グラフ、そしてワイヤーに乗るもの
すべてについて生成クライアント(openapi.json と tests/bdd/generated)。
1. 正しさに隣接する重複 — 着地済み
Section titled “1. 正しさに隣接する重複 — 着地済み”この節にあったものはすべて着地し、ここからは消えました。コピーされた is_local 規則、2 つの
ValidationError 対応付け、アルファベット順デバイスの罠、base64 の二重デコード、そして別の分類器が
すでに取ったファセットの分まで課金される分類器です。
最後の 1 つは、監査が値段をつけられなかったものでした。リクエストが名指すのは分類器であって
ファセットではないので、「未解決のファセットが無い」ことは、分類器が答えるファセットを宣言する
まで知りようがありませんでした。DocumentClassifier は今、device や cost_usd と同じように
省略可能な facets 属性を読みます。不在は「不明」を意味して常に尋ねられ、宣言されたファセットが
その単位についてすべて取られている分類器はまるごと飛ばされます。同梱の 3 つの分類器は、読み込んだ
タクソノミーのファセットを宣言します。
2. 呼び出しごとの I/O と隠れた状態 — 着地済み
Section titled “2. 呼び出しごとの I/O と隠れた状態 — 着地済み”この節にあったものもすべて着地しました。エコノミクスのファイルは、パス・mtime・サイズをキーとする
lru_cache の背後でパースされるので、値付けし直した機能は再起動なしで信じられます。
indx/facade.py はモジュールグローバルを持たず、_default() は lru_cache(maxsize=1) で、テストは
cache_clear() でリセットします。{c.id: c for c in snapshot.capabilities} の 7 回の組み直しは、
CapabilitySnapshot の cached_property by_id 1 つになりました。コンテンツハッシュの外、JSON
スキーマの外です。そして encode は計画を一度展開して unrouted と groups の両方に渡します。
routes_by_page の docstring がずっと主張していたとおりです。
1 つ目についてまだ残っているもの。完全に純粋な版 — Router.plan で一度エコノミクスを解決し、
マッピングを decide() に渡す — の方が良い終着点であることは変わらず、indx-benchmark の
インポートに触れることも変わりません。
3. デッドコードと削除 — 着地済み
Section titled “3. デッドコードと削除 — 着地済み”この節が抱えていたものはすべて着地し、ここからは消えました。3 項目はコードに触れて初めて別の大きさ だと分かったので、黙って調整せずに記録します。
バイト単位で同一の provider.py は 6 つではなく 20 でした。分類器、抽出器、エンリッチャー、言語の
各ディストリビューションも、ローダー・オブザーバー・チャンカーと同じ空の descriptors() と、同じ
拒否する create() を持っていたので、indx-interfaces の任意の Plugin 基底は監査が数えた 6 つ
ではなく 20 すべてを削除しました。
ファサードの注入 kwargs は消え、Executor と Embedder のプロトコルも一緒に消えました。2 つの
プロトコルページは残しました。あのページが記述しているのはシステムの 2 つのステージであり、両言語
で 22 本のリンクが指しており、それぞれ今は呼び出し側が呼ぶポートを名指しし、なぜそこにプロトコルが
宣言されていないかを述べています。
死んだ再エクスポートは EXTRA だけでした。両方の __all__ の残りは、2 つのパッケージ自身のテストが
その経路でインポートしているものです。
VectorEncoder は @runtime_checkable を失いました。PageReader は残しました。3 つの抽出
パッケージが、create() がリーダーを返したことをそれで判定しており、Any を返す create() に対する
唯一の検査だからです。
CorrelationFilter は消え、JsonFormatter が contextvar を自分で読みます。ハンドラーは発行した
コンテキストの中でフォーマットするからです。上限は監査が求めたコメントに入っています。この近道は
別スレッドでフォーマットする QueueHandler の下では成り立たず、LOG_CONFIG はそれを設置しません。
4. 縮小 — 着地済み
Section titled “4. 縮小 — 着地済み”ここの項目もすべて着地し、3 つは記述より大きいか厳しいものでした。
「bool ではない数値」は 5 通りではなく 11 通り、しかも 2 つの極性で書かれていました。エグゼキューター、
VLM リーダー、hosted 埋め込み器、そして 3 つの LLM 応答パーサーです。今は
indx_interfaces.number が唯一の規則です。indx-llm は自分の複製を保持します。依存を 1 つも宣言
しないからこそ 3 つのレーンが共有でき、境界テストがそれを固定しています。
エクストラ不足の探索は、動かす前に丸ごと固定しました。組み立てる文字列が unavailable_reason として
ワイヤーに乗るからです。indx-language-lingua、-classifier-zeroshot、-ner-onnx はそのままです。
理由ではなく検出器や bool で答えるので、共有する書式がありません。
1 つの拒否は保存ではなく厳格化になりました。economics.py は extra="forbid" と strict=True の
pydantic モデルになり、手書きの読み取りが黙って切り捨てていた小数の latency_ms_per_page を拒否
します。api-contract のページが両言語でそう述べ、パラメータ化テストが固定しています。
レジストリのタプルは Declared、Collected、Inventory になり、すべて frozen です。レジストリは
順に代入される 7 つの属性の代わりに 1 つのオブジェクトを持ちます。ロックで守られたメモ化は残しました。
cached_property は同時に来た最初の読者が 1 つのビルドを共有する保証を与えず、
test_concurrent_first_readers_share_one_build_and_one_attribution_table がそう述べているからです。
bool のソートキーには、それが欠陥ではない理由として ADR-0027 を名指すコメントが付きました。
残りは監査の記述どおりです。ID を鋳造する 4 か所のための content_digest、広告される集合と 415 の
一覧が構成上一致するための resolvable_schemes、束縛された _assemble の引数、math.hypot、
starlette の Headers、巻き上げたバージョン参照、宣言された CLI の既定値と 1 つの _fail、
gpu_regions を落としていたフィールドごとの複製の代わりに埋め込みイベントを受け取る _actuals、
そして 1 行になった先頭ページの対応表です。
5. 既知の先送り — いずれもワイヤー契約を動かす
Section titled “5. 既知の先送り — いずれもワイヤー契約を動かす”これらを変えると openapi.json と生成クライアントの再生成(just api::gen-client、
just api::contract-check)が必要になります。存在しない生成元を誰かが探し回らないよう記録して
あります。API がどのみち動くときにだけ着手してください。
REGIONは決して生成されません。BlockKind.REGIONを構築するコードも、granularitiesで それを求めるコードも、リージョンルートを出すコードもありません —_routesは文書スコープとページスコープ だけを出します。ScopeKind.REGIONとRegionEvidenceは生きています。オブザーバーはリージョン 証拠を出せますが、それでルーティングするものがありません。同様にExecutionActuals.gpu_regionsとRegionIdにも生成元がありません。リクエスト側は静かではなく答えが返ります。 ADR-0016 を参照。- 501 /
NotImplementedErrorのマッピング(サーバーと CLI)には、リポジトリ内に生成元がありません。 唯一もっともらしい発生源は、ディスパッチループによって失敗した段へ飲み込まれます。生成元のない 文書化された約束か、死んだ重しか — サードパーティのプランナーをどれだけ信頼するか次第です。
6. 評価した上で却下
Section titled “6. 評価した上で却下”問いが蒸し返されないように記録します。このうち 4 つは決定記録になりました。コードの書き方ではなく、 システムが何であるかについての話だからです。
- メタクラス /
__init_subclass__レジストリ、および設定ファイル駆動の機能宣言 → ADR-0006。 - PDF のラスタライズとテキスト抽出を機能パッケージ間で共有すること → ADR-0007。
残りはここに置きます。システムが何であるかではなく、このコードがどう書かれているかについての 話だからです。
- ポリシーにもっとテーブルを。
_ESCALATION、_DEVICE_PREFERENCE、economics.DEFAULTS、media_type._SIGNATURESはすでにテーブルです。_devices(規則 2 つ)、_admit(比較の形が 3 つ 異なるチェック 3 つ)、_ladder(結果 2 つ)をテーブル駆動にすると、より少ないことを表現するために より多くのコードを書くことになります。3 つ目の規則が来たら再検討、それ以前ではありません。 - 3 つの POST エンドポイントと CLI サブコマンドのディスパッチテーブル。 約 15 行の節約と引き換えに、 grep 不透明性、FastAPI のスキーマ生成の煩雑化、そして何も動いていないことを証明するための クライアント再生成を払います。4 つ目の操作が来たら追加を。
- 2 分岐の
isinstance合併に対するsingledispatch(indx_source.load、QueryEmbedder.embed): 登録の儀式がifより長くなります。