Skip to content

search/recall degradation is invisible on array-shaped verb results #390

Description

@ohdearquant

Context

PR #389 (fix for #388) makes the FTS leg of hybrid search fail open: when a query contains residual FTS5 metacharacters that survive sanitization, the FTS leg degrades to empty and fusion continues vector-only, instead of the whole verb erroring.

The degradation is logged (tracing::warn!) but not visible to the caller on three surfaces, because their wire shape is a bare JSON array with no envelope to carry an advisory field:

  • search(kind="entity")crates/khive-pack-kg/src/handlers/search.rs, returns Vec<Value>
  • search(kind="note") — same file, note branch, returns Vec<Value>
  • memory.recall default path — crates/khive-pack-memory/src/handlers/recall.rs, returns a bare array (only the rare verbose multi-model branch returns an object)

By contrast, knowledge.search could carry ann_unavailable (#335) only because its handler already returns an object envelope.

Why this is deferred

Adding an fts_degraded field to these three verbs means a breaking array-to-object wire-shape change, which is an ADR-023 surface-contract amendment, not a bug-fix change. ADR-029's partial: true / missing_backends advisory is specified (ADR-029 §result envelope) but not implemented anywhere today, so it is not a ready escape hatch either.

Options

  1. Migrate the three verbs to an object envelope ({results: [...], fts_degraded?: true}) via an ADR-023 amendment + AGENTS.md update, with a deprecation window for array consumers.
  2. Implement ADR-029's envelope-level advisory injection at the MCP dispatch layer, so per-verb handlers stay array-shaped and the request batch envelope carries per-op advisories.
  3. Accept log-only visibility as the contract for array-shaped verbs and document it.

Option 2 keeps handler shapes stable and matches where the batch envelope ({ok, tool, result}) already lives; it is the likely right seam, but it needs ADR-029 implementation work sized first.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions