GrooveSeek

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

View the Project on GitHub alphabet-h/grooveseek

8. 1.0.0 が何を凍らせるかを宣言し、Rust API はそこから外す

背景と課題

semver は「public API を壊すなら major が要る」と言うが、public API が何かは 言わない。ライブラリなら問い自体が答えになる — crate が export しているものが API である。しかしコマンドラインと MCP 面と HTTP transport と設定形式を持ち、 ユーザのホームディレクトリにファイルを書くプログラムでは、答えは「メンテナが そう言ったもの」でしかない。そしてメンテナが何も言わなければ、利用者は当然 観測できるものすべてだと解釈する。

本決定の日に実測した値:

   
public な Rust アイテム 408 個(24 個の pub mod にまたがる)
コマンドラインのフラグ 138 個(10 サブコマンド)
MCP tool / prompt 6 / 4、加えて kb:// resource スキーム
HTTP route 5
設定セクション 11、deny_unknown_fields が 25 箇所
ディスク上の成果物 索引 DB / 設定 / 除外ファイル / eval セットと履歴 / サービス登録

これを全部 2.0.0 まで凍らせると、失敗の仕方が 2 つに 1 つになる。誰も依存して いない部分を永久に改善できないか、誰も気付かない変更のたびに major を出すか である。どちらも「どこが約束なのかを事前に書き下す」より悪い。

これを理屈でなく具体にしている項目が 1 つある。/ui の web 画面は自分の HTML で 自分を placeholder と名乗っており、作り直す予定になっている。宣言なしで 1.0.0 を 出せば、その作り直しが 2.0.0 になる

判断基準

検討した選択肢

決定

安定な面を docs/stability.ja.md に書き下す(推測に委ねない)。 要約すると、コマンドライン / 機械可読な JSON / MCP の面 / /mcp/healthz / 設定のキーと既定値 / 既定の embedding モデル / ユーザのファイルシステムに書かれる 名前。明示的に対象外なのは、管理用の web 面 / 人間向けの text 出力すべて / DB の内部スキーマ / ログの文面 / Rust API。

このうち 3 点は、ポリシー側ではなくここに理由を置く。

Rust API を外し、grooveseekpublish = false を付ける。 文書化するだけで なくマークするのは、意図を強制可能にするためである — cargo publish が拒否 するので、除外が事故で覆らない。これは問いを避けているのではない。crate は今日 実際に package できないので、この除外は現実の記述である。将来の公開は独立した 判断であり、それ自身の安定性宣言を伴う。

管理用の web 面は非安定。 /ui / /api/search / /api/admin/status は GrooveSeek が認証を持たないため仕様として loopback 限定である。これらが相手に しているのは自分のデータを見る運用者であって、統合する開発者ではない。 非安定と宣言することが、予定している刷新を minor に留める唯一の方法である。

設定に前方互換性は無く、未知キーはエラーのまま。 代案(警告して続行)は、 大きな失敗を小さな失敗と交換するmodel の打ち間違いは、誰も読まない daemon の stderr を警告 1 行が流れていく間に、既定モデルでナレッジベースを索引させてしまう。 設定ファイルはそれを読むバイナリの版に属する。ポリシーはそう書く — そうでないふりを しない。

影響