{"slug": "explicit-recall-surface-alignment", "title": "Explicit Recall Surface Alignment", "summary": "Signet is consolidating its fragmented TypeScript recall surfaces into a single canonical explicit recall engine and API, aiming to reduce duplication and preserve metadata. The plan keeps hybridRecall() and /api/memory/recall as primary building blocks while thinning or removing legacy helpers like handleRecall() and ad hoc formatters. This restructuring will make recall easier to evolve by ensuring improvements land in the correct layer.", "body_md": "# Explicit Recall Surface Alignment\n\n## Problem\n\nSignet’s TypeScript recall behavior is split across too many surfaces that share some plumbing but diverge in orchestration and presentation:\n\n`/api/memory/recall`\n\nexposes the richest retrieval path through`hybridRecall()`\n\n.`handleUserPromptSubmit()`\n\nuses recall differently because prompt-submit is a hot-path injection surface with confidence gates, dedup, and fallback channels.`/api/hooks/recall`\n\nis a harness-oriented recall surface that currently wraps the same engine but still acts like a separate product boundary.- CLI, MCP, and connector consumers flatten results differently and often throw away metadata such as source labels, scores, type, and provenance.\n`platform/daemon/src/hooks.ts`\n\nstill contains an older`handleRecall()`\n\nhelper that appears to be legacy logic instead of a live source of truth.\n\nThe result is not six different retrieval engines, but it is still a fragmented recall product:\n\n- one strong engine,\n- one prompt-submit orchestration path,\n- several renderers and wrappers,\n- at least one likely-dead helper,\n- too many places where useful metadata gets discarded.\n\nThis makes recall harder to evolve because every improvement risks landing in the wrong layer.\n\n## Goals\n\n- Establish one canonical TypeScript explicit recall engine.\n- Establish one canonical explicit recall response contract.\n- Keep prompt-submit recall intentionally small, fast, and distinct from explicit recall.\n- Reduce or remove duplicate helper logic that does not own real product behavior.\n- Make explicit recall consumers preserve useful metadata instead of turning rich results into anonymous bullet lists.\n\n## Non-goals\n\n- No Rust parity work in this spec.\n- No retrieval-model redesign, re-ranking redesign, or graph search redesign.\n- No attempt to make prompt-submit into a rich query product.\n- No new memory types, schema changes, or pipeline extraction changes.\n- No deep-memory-search or LLM-escalation work.\n\n## Current surface inventory\n\n### Keep as primary building blocks\n\n| Surface | File | Role |\n|---|---|---|\n`hybridRecall()` | `platform/daemon/src/memory-search.ts` | Canonical explicit recall engine |\n| prompt-submit orchestration | `platform/daemon/src/hooks.ts` | Hot-path injection control flow, not a rich query surface |\n| temporal fallback helpers | `platform/daemon/src/temporal-fallback.ts` | Supporting continuity fallback |\n| transcript fallback helpers | `platform/daemon/src/session-transcripts.ts` | Supporting continuity fallback |\n`/api/memory/recall` | `platform/daemon/src/daemon.ts` | Canonical explicit recall API |\n\n### Keep, but thin down\n\n| Surface | File | Current issue |\n|---|---|---|\n`/api/hooks/recall` | `platform/daemon/src/daemon.ts` | Useful harness entry point, but should remain a thin wrapper |\nCLI `signet recall` | `surfaces/cli/src/commands/memory.ts` | Loses too much structure in display |\nMCP `memory_search` | `platform/daemon/src/mcp/tools.ts` | Returns raw text payload without a stronger recall contract |\nOpenClaw `/recall` rendering | `integrations/openclaw/connector/src/index.ts` | Flattens results into plain content bullets |\n\n### Likely remove or collapse\n\n| Surface | File | Current issue |\n|---|---|---|\n`handleRecall()` | `platform/daemon/src/hooks.ts` | Looks like legacy standalone recall logic rather than a live source of truth |\n| ad hoc formatter duplication | multiple consumers | Rich metadata is repeatedly discarded in slightly different ways |\n\n## Proposed architecture\n\n### 1) Canonical explicit recall engine\n\n`platform/daemon/src/memory-search.ts`\n\nremains the only retrieval engine for\nexplicit TypeScript recall.\n\n`hybridRecall()`\n\nalready owns:\n\n- keyword + vector merge,\n- filtering,\n- scoping,\n- reranking hooks,\n- graph/traversal support,\n- supplementary context,\n- expansion behavior.\n\nThis spec does not replace that engine. It treats it as the source of truth.\n\n### 2) Canonical explicit recall API\n\n`/api/memory/recall`\n\nbecomes the canonical API surface for explicit recall.\n\nOther explicit recall surfaces should:\n\n- wrap it,\n- render it,\n- or constrain it for a specific caller,\n\nbut should not grow separate retrieval behavior unless that difference is required by an explicit contract.\n\n### 3) Prompt-submit remains separate\n\nPrompt-submit recall stays in `handleUserPromptSubmit()`\n\nand remains a\ndistinct product boundary:\n\n- lightweight injection only,\n- confidence-gated,\n- fallback-friendly,\n- deduplicated,\n- budget-limited.\n\nPrompt-submit is not the place for the richer “query product” behavior. It is allowed to use recall, but it should not become recall’s main presentation layer.\n\n### 4) Fallbacks remain supporting channels\n\nTemporal and transcript fallbacks remain valuable, but only as fallback\nchannels when structured memory is weak or missing. They should not grow\ninto peer retrieval engines that compete with `hybridRecall()`\n\n.\n\n## Contract decisions\n\n### A) Retrieval source of truth\n\n**Source of truth:**`hybridRecall()`\n\n**Not a source of truth:** CLI formatting, MCP formatting, connector formatting, prompt-submit injection formatting\n\n### B) Explicit recall source of truth\n\n**Source of truth:**`/api/memory/recall`\n\n**Thin wrapper candidate:**`/api/hooks/recall`\n\n**Alias only:**`/api/memory/search`\n\n### C) Prompt-submit source of truth\n\n**Source of truth:**`handleUserPromptSubmit()`\n\n- It may call\n`hybridRecall()`\n\n, but it is not responsible for becoming the canonical explicit recall experience.\n\n## Consolidation plan\n\n### Phase 1, dead-weight audit\n\n- Confirm whether\n`handleRecall()`\n\nin`platform/daemon/src/hooks.ts`\n\nis actually used anywhere meaningful. - Remove it if dead, or demote it to a thin wrapper if it still serves a compatibility role.\n- Document any remaining call sites that still bypass the canonical recall path.\n\n### Phase 2, explicit recall response contract\n\nDefine a canonical response contract for explicit recall that all TypeScript consumers can rely on. This does not require changing the retrieval engine, only tightening the product contract around it.\n\nThe contract should preserve at least:\n\n- result ordering,\n- score,\n- source,\n- type,\n- date/provenance,\n- supplementary-result distinction,\n- no-hit behavior.\n\nThe contract may later grow richer shaped sections for explicit recall, but that presentation belongs outside prompt-submit.\n\n### Phase 3, consumer alignment\n\nRefit the following consumers to preserve useful metadata and stop flattening everything into anonymous snippets:\n\n- CLI\n`signet recall`\n\n- MCP\n`memory_search`\n\n- OpenClaw\n`/recall`\n\n- any harness-oriented recall formatting that currently strips source and provenance\n\n### Phase 4, wrapper discipline\n\nKeep `/api/hooks/recall`\n\nonly if it has a real harness-oriented purpose:\n\n- different auth/session behavior,\n- stricter wrapper semantics,\n- harness compatibility surface.\n\nIf it does not need its own contract, it should stay visibly thin.\n\n## Validation\n\n`handleRecall()`\n\nis either removed or proven necessary with documented call sites.`/api/memory/recall`\n\nremains the authoritative explicit recall endpoint.`/api/hooks/recall`\n\ndoes not diverge into its own retrieval engine.- CLI, MCP, and connector recall displays expose source labels and preserve useful metadata from the canonical response.\n- Prompt-submit injection remains lightweight and separate from explicit recall shaping.\n\n## Success metrics\n\n- One obvious TypeScript engine owns explicit recall behavior.\n- One obvious TypeScript API owns explicit recall response semantics.\n- Prompt-submit stays fast and small.\n- Consumer surfaces stop collapsing recall into metadata-free bullets.\n- Future recall changes can be made in one place and seen predictably across wrappers.\n\n## Open decisions\n\n- Whether\n`/api/hooks/recall`\n\nshould remain a public compatibility surface long-term or collapse entirely into`/api/memory/recall`\n\n. - Whether the canonical explicit recall response contract should stay raw JSON-first or also define a higher-level shaped presentation contract for CLI/MCP consumers.\n- Whether explicit recall should expose a first-class “summary / sources / gaps / no-hit” product contract at the API layer or only in selected renderers.", "url": "https://wpnews.pro/news/explicit-recall-surface-alignment", "canonical_source": "https://signetai.sh/docs/specs/approved/explicit-recall-surface-alignment/", "published_at": "2026-06-18 07:37:48+00:00", "updated_at": "2026-06-18 23:38:55.277170+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools"], "entities": ["Signet", "hybridRecall", "handleRecall", "CLI", "MCP", "OpenClaw"], "alternates": {"html": "https://wpnews.pro/news/explicit-recall-surface-alignment", "markdown": "https://wpnews.pro/news/explicit-recall-surface-alignment.md", "text": "https://wpnews.pro/news/explicit-recall-surface-alignment.txt", "jsonld": "https://wpnews.pro/news/explicit-recall-surface-alignment.jsonld"}}