Priority
P3 — do not implement unless #77 demonstrates a material duplicate-slot or first-stage ranking problem after P0–P2 work.
Goal
Add the smallest optional post-retrieval hook needed to improve diversity or ranking without changing HotMem's default deterministic fusion, adding required dependencies, or coupling portable company-brain records to a reranker.
Reranking is derived query-time acceleration. It is never canonical memory state.
Entry gate
Implementation may start only when a committed #77 report shows one of:
- duplicate-slot rate at 5 greater than 20%;
- a documented candidate-ordering failure where relevant memories are consistently present in the candidate set but absent from final top-K;
- a production integration requirement with an accompanying local benchmark.
The implementing PR must link the evidence and state which failure it addresses.
Required outcome
- Default search output remains byte/logically compatible when reranking is disabled.
- Candidate generation remains current cosine + FTS5 BM25 + importance fusion.
- Reranking operates only on a bounded candidate set.
- The first implementation is deterministic and dependency-free: MMR or another benchmark-justified local strategy.
- Provider-specific or hosted rerankers can be added later behind the hook without modifying canonical records.
Minimal interface
Define a narrow interface equivalent to:
class Reranker(Protocol):
@property
def descriptor(self) -> RerankerDescriptor: ...
def rerank(
self,
query: str,
candidates: Sequence[SearchCandidate],
top_k: int,
) -> list[SearchCandidate]: ...
Requirements:
- Default
IdentityReranker performs no work and preserves existing ordering.
- Stable tie-breaking uses the pre-rerank order and then memory ID.
- Candidate objects expose only required fields; do not leak DB rows as an implicit API.
- A reranker cannot mutate canonical memories or persist provider output by default.
- Descriptor/configuration is visible in traces without secrets.
Bounded execution
- Default candidate limit: no more than 50 and configurable within a documented safe range.
- Reranker receives no more data than the candidate limit and
max_chars safety policy allows.
- Invalid output—duplicates, unknown IDs, too many results, or missing required candidates—fails closed to the deterministic pre-rerank order and emits an observable diagnostic.
- Define a timeout/error boundary for future hosted adapters, but do not implement hosted adapters here.
First strategy
Implement exactly one local strategy selected by benchmark evidence:
- Prefer MMR if duplicate occupancy is the measured problem.
- Prefer reciprocal-rank fusion only if multiple independent ranked candidate lists exist and the benchmark supports it.
- Do not add a cross-encoder without a separate optional-adapter ticket and latency budget.
For MMR:
- reuse compatible candidate embeddings already available;
- define lambda/diversity semantics unambiguously;
- handle missing/incompatible embeddings predictably;
- preserve current behavior when disabled;
- add no DB query per candidate.
Tests
- Identity/default path preserves exact current ordering and response shape.
- Stable ties are deterministic.
- Duplicate candidates cannot appear in output.
- Unknown/invalid reranker output falls back safely.
- Candidate bound is always enforced.
- MMR reduces duplicate-slot rate on the benchmark case that opened the gate.
- Relevant Recall@5 does not regress beyond the documented benchmark allowance.
- Snapshot/hydration artifacts contain no reranker-dependent canonical state.
- API, MCP, Python, TypeScript, and golden compatibility tests pass unchanged by default.
Performance budget
- Disabled overhead must be negligible and measured.
- Local strategy p95 overhead must be reported for 20- and 50-candidate sets.
- No required dependency.
- No network call in core/default tests.
- No full-corpus second pass.
Explicitly out of scope
Definition of done
Dependencies
Historical context
#3 was closed as not planned and moved to EMOS. This issue scopes only an evidence-gated, portable-memory-safe HotMem hook and does not revive the earlier unconditional feature request.
Priority
P3 — do not implement unless #77 demonstrates a material duplicate-slot or first-stage ranking problem after P0–P2 work.
Goal
Add the smallest optional post-retrieval hook needed to improve diversity or ranking without changing HotMem's default deterministic fusion, adding required dependencies, or coupling portable company-brain records to a reranker.
Reranking is derived query-time acceleration. It is never canonical memory state.
Entry gate
Implementation may start only when a committed #77 report shows one of:
The implementing PR must link the evidence and state which failure it addresses.
Required outcome
Minimal interface
Define a narrow interface equivalent to:
Requirements:
IdentityRerankerperforms no work and preserves existing ordering.Bounded execution
max_charssafety policy allows.First strategy
Implement exactly one local strategy selected by benchmark evidence:
For MMR:
Tests
Performance budget
Explicitly out of scope
Definition of done
Dependencies
Historical context
#3 was closed as not planned and moved to EMOS. This issue scopes only an evidence-gated, portable-memory-safe HotMem hook and does not revive the earlier unconditional feature request.