Architecture Decision Records¶
Convention for this repo: ADR-NNNN-<slug>.md, four-digit zero-padded, one
decision per record. ADRs record irreversible decisions with the alternatives
that were considered; deviating from SPEC.md requires an ADR proposal first.
Grouped by theme below so you can find the record that governs the part of the codebase you're touching, rather than scanning every title in commit order. Within a group, order is ADR number (roughly chronological).
Foundational¶
What groundkit is, what it took from ARP, and how its two durable stores (SQLite, the eval corpus) are shaped.
| ADR | Title | Status |
|---|---|---|
| ADR-0001 | Promote vs rewrite: what groundkit takes from ARP's RAG library | Accepted |
| ADR-0002 | Index persistence: SQLite truth, BM25 rebuild-at-open | Accepted |
| ADR-0003 | Eval corpus and metrics: quote-anchored judgments, hit-rate recall, threshold-free abstention, JSONL | Accepted |
Dense retrieval & embedding integrity¶
The vector store, what binds it to an embedding identity, and where a dense-shaped request is refused outright rather than silently degraded.
| ADR | Title | Status |
|---|---|---|
| ADR-0004 | Dense store integrity: embedding identity binding and delete-path safety | Accepted |
| ADR-0006 | The dense seam returns (Chunk, score), not RetrievalResult |
Accepted |
| ADR-0007 | Hybrid is recommended where configured; BM25 stays the default | Accepted |
| ADR-0008 | A dense or hybrid search refuses a collection that has no vectors | Accepted |
| ADR-0011 | A BM25-only ingest refuses a collection that has a dense side | Accepted |
Hybrid scoring & rerank¶
How BM25 and dense results are combined, and how a cross-encoder reorders the result.
| ADR | Title | Status |
|---|---|---|
| ADR-0005 | Hybrid scoring: rank-based RRF fusion and sigmoid-normalized rerank | Accepted |
| ADR-0012 | The rerank eval stage reorders the best available upstream stage | Accepted |
Ingestion & incremental indexing¶
What counts as "unchanged" on a re-ingest, the boundary between the load→chunk utility and the actual ingest path, the cached runtime that tracks whether a collection is stale, and what that cache costs while an ingest is invalidating it.
| ADR | Title | Status |
|---|---|---|
| ADR-0009 | The incremental skip key is a processing fingerprint, not a content hash | Accepted |
| ADR-0010 | IngestionPipeline is a load→chunk utility, not the ingest path |
Accepted |
| ADR-0013 | A cached CollectionRuntime whose validity is a marker persisted in SQLite |
Accepted |
| ADR-0026 | Measure the rebuild cliff before rebuilding incrementally, and re-defer ADR-0002's persisted postings against a trigger the measurement can satisfy | Accepted |
| ADR-0027 | The rebuild-cliff reading selects persisted postings, and retires GK-020's incremental rebuild | Accepted |
Extracted & remote sources¶
PDF/HTML content extraction and URL ingestion: how a citation stays verifiable when the source isn't a local text file, and what happens to a fetched snapshot over a document's lifetime.
| ADR | Title | Status |
|---|---|---|
| ADR-0016 | Citation verifiability for extracted and remote sources | Accepted |
| ADR-0023 | A snapshot exists iff its document row references it; the Indexer deletes one at skip/replace/delete, best-effort and never fatal |
Accepted |
Service surface¶
The read-only REST/MCP surface and why its dependencies are base requirements rather than an extra.
| ADR | Title | Status |
|---|---|---|
| ADR-0014 | Phase 4 is a read-only service surface, and outbound endpoints are guarded | Accepted |
| ADR-0015 | Service dependencies are base requirements, not an optional extra | Accepted |
| ADR-0024 | The loopback bind is not a boundary against a browser, so Host is validated on both transports |
Accepted |
| ADR-0025 | The library constructors default Host validation on, not off |
Accepted |
LLM boundary¶
Where text is allowed to leave the process, how a synthesized answer is validated rather than trusted, and why synthesis stays off the service surface.
| ADR | Title | Status |
|---|---|---|
| ADR-0017 | One narrow chat seam, implemented directly, with redaction wrapped around it | Accepted |
| ADR-0018 | LLM output is validated, never trusted: cited synthesis, the echo check, and an advisory judge | Accepted |
| ADR-0019 | Synthesis lands as grk answer, and does not reach the service surface |
Accepted |
Infrastructure & observability¶
Deployment target, container hardening, and the tracing/logging dependency shape.
| ADR | Title | Status |
|---|---|---|
| ADR-0020 | The Terraform module targets one AWS host with attached block storage, reachable only through SSM | Accepted |
| ADR-0021 | In a container the loopback guarantee moves outward, and the read-only claim splits in two | Accepted |
| ADR-0022 | The OTel API is a base dependency, the SDK is an extra, and span attributes are an allowlist | Accepted |