GrooveSeek

Semantic search over a Markdown knowledge base, served over MCP.

View the Project on GitHub alphabet-h/grooveseek

23. サーバが開ける名前だけを索引し、その判定を 1 つの述語に集める

背景と課題

索引に入る名前と、読み出せる名前を、別々のコードが決めていた。索引の walk (grooveseek/src/indexer.rs の collect_source_files_under) と常駐 watcher (grooveseek/src/watcher.rs の should_process_parts) は除外規則・拡張子・リンクを 見るだけで、名前は見ない。読み出し側 — kb://doc/ URI と、get_document がディスクに 触る前に走らせる字句検査 — は grooveseek/src/resources.rs の is_safe_relative に訊き、 これは Windows でコロンと予約デバイス名を拒否していた。

Windows では、KB の canonical なパスが持つ verbatim prefix \\?\ のおかげで、 Win32 が書いたとおりには開かない名前のファイルが存在できる: CON.md や、 dir. という名前のディレクトリの配下。walk はそれを索引し、search は見つけ、 URI は付かず get_document は拒否した (AW-43)。逆向きの穴もあった: Win32 が 書き換える綴り b.md. や dir./x.md は字句検査を通り、ディスクを見た後で やっと拒否されていた (AW-42)。a/b?.md は “not found” ではなく “unavailable” で 返っていた (AW-40)。

#319 の review は 3 round 続けて、この同じ軸で別の事例を見つけた。本 ADR が答えるのは 「索引が持ちうる名前」の規則をどこに置けば、次の事例が 4 本目のパッチではなく 1 関数の変更で済むか。

判断の軸

検討した選択肢

  1. 索引に入れたまま読めるようにする — verbatim prefix 経由で開き、URI も付ける。 棄却: パスを受け取る側すべて (要求文字列で絞る gateway、クライアント、URI parser) が 「このサーバでは CON.md や b.md. が名前である」ことを知る必要があり、 get_document の「綴りは 1 つ」の規則に、Win32 自身が書き換える名前の例外が要る。
  2. 現状の分担のまま docs に書く。棄却: 3 連続の指摘を生んだ状態そのもので、 次の指摘も同じパッチになる。
  3. 述語を 1 つにしてどこでもそれに訊き、そういう名前は索引しない。

決定

選択肢 3 を採る。

結果と代償

参考