GrooveSeek

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

View the Project on GitHub alphabet-h/grooveseek

8. Declare what 1.0.0 freezes, and leave the Rust API out of it

Context and Problem Statement

Semantic versioning says a major version is required to break the public API. It does not say what the public API is. For a library that question answers itself — the API is what the crate exports. For a program with a command line, an MCP surface, an HTTP transport, a configuration format, and files it writes into the user’s home directory, the answer is whatever the maintainer says it is, and if the maintainer says nothing, users will reasonably assume it is everything they can observe.

Measured on the day of this decision:

   
public Rust items 408, across 24 pub mod
command-line flags 138, across 10 subcommands
MCP tools / prompts 6 / 4, plus the kb:// resource scheme
HTTP routes 5
configuration sections 11, with deny_unknown_fields in 25 places
on-disk artifacts index database, config, exclusion file, eval set and history, service registrations

Freezing all of that until 2.0.0 leads to one of two failures: the project never improves the parts nobody depends on, or it ships major versions for changes nobody would have noticed. Both are worse than saying, in advance and in writing, which parts are the promise.

One item makes this concrete rather than theoretical. The web interface at /ui is a placeholder that says so in its own HTML, and it is scheduled to be rebuilt. If 1.0.0 ships without a declaration, rebuilding it becomes a 2.0.0.

Decision Drivers

Considered Options

Decision Outcome

The stable surface is written down in docs/stability.md (and its Japanese counterpart) rather than left to inference. In summary: the command line, the machine-readable JSON, the MCP surface, /mcp and /healthz, configuration keys and defaults, the default embedding model, and the names written into the user’s filesystem. Explicitly outside: the admin web surface, all human-readable text output, the database’s internal schema, log wording, and the Rust API.

Three parts of that deserve their reasoning here rather than in the policy.

The Rust API is excluded, and grooveseek is marked publish = false. Marking it rather than only documenting it makes the intent enforceable: cargo publish refuses, so the exclusion cannot be undone by accident. This is not a way of dodging the question — the crate genuinely cannot be packaged today, so the exclusion describes reality. Publishing later is a separate decision that would come with its own stability statement.

The admin web surface is unstable. /ui, /api/search and /api/admin/status are loopback-only by design because GrooveSeek has no authentication (ADR-0007 covers the naming; the loopback decision predates it). They serve the operator looking at their own data, not integrators. Declaring them unstable is what keeps the planned rework a minor release.

Configuration is not forward compatible, and unknown keys stay an error. The alternative — warn and continue — trades a loud failure for a quiet one. A misspelled model key would leave the knowledge base indexed by the default model while a single warning scrolls past on a daemon’s stderr that nobody reads. A configuration file belongs to the binary version that reads it; this policy says so instead of pretending otherwise.

Consequences