Skip to content

Evidence-gated optional reranking hook with deterministic local fallback #80

Description

@valiantone

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

  • Entry-gate benchmark evidence is linked.
  • Default search is exactly compatible.
  • One deterministic local strategy solves the measured problem.
  • Candidate, error, and latency bounds are tested.
  • Core required dependencies remain unchanged.
  • Before/after benchmark and p95 overhead are in the PR.
  • Full tests, lint, and strict docs build pass.

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:benchmarksEval harness, LOCOMO benchmarks, provider comparisonsenhancementNew feature or requestphase:1-search-qualityPhase 1: Credible Search Qualitypriority:p3Later optimization; implement only when benchmarks justify complexityv0.2.NEXTCommitted for a future 0.2.x release; not yet pinned to 0.2.4/0.2.5

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions