Skip to content

feat(recall): HOT-recall latency telemetry — measure the sub-200ms exit criterion (#308) - #313

Merged
Jaybhade merged 1 commit into
mainfrom
fix/308-recall-latency-telemetry
Jul 19, 2026
Merged

feat(recall): HOT-recall latency telemetry — measure the sub-200ms exit criterion (#308)#313
Jaybhade merged 1 commit into
mainfrom
fix/308-recall-latency-telemetry

Conversation

@Jaybhade

Copy link
Copy Markdown
Owner

Closes #308.

Summary

§13.2 exit criterion 2 has two halves — ">70% corpus demoted" (already live as pctWarmOrCooler) and "HOT recall sub-200ms", which was measured nowhereexit-gate.ts even shipped a caveat admitting it. This times the synchronous ask retrieval (embed → doorway fan-out → RRF fusion → rerank) into a bounded process-local reservoir that mirrors the blessed ack-latency.ts pattern (Phase-0 gate #73), surfaces it at GET /admin/stats + the ops exit-gate panel, and retires the caveat. Additive contract only — no DB migration.

The strong-model grounded-reconstruction and the async recall-rewrite are deliberately excluded from the sample (they're per-query LLM work, not the "did the memory come back fast" signal the gate judges). Recording happens right after retrieveCandidates returns, so every confidence band — including the honest-miss early return — is sampled.

Files

  • new apps/api/src/modules/memory/recall-latency.ts — the reservoir (imports, doesn't duplicate, percentile from ack-latency.ts).
  • new apps/api/src/modules/memory/recall-latency.test.ts — unit tests.
  • new apps/api/test/recall-latency.integration.test.ts — real capture→encode→ask→/admin/stats flow (M11).
  • memory.service.ts::askperformance.now() timing around the retrieval; recordRecallLatency(...) after retrieveCandidates.
  • exit-gate.tshotRecallLatencyMs: 200 target; split the combined caveat so only the graph-walk clause remains.
  • admin.service.ts::getStats — returns recallLatency beside captureAckLatency.
  • admin.service.test.ts — asserts the latency caveat is gone + target is 200.
  • apps/admin/src/lib/api.ts + apps/admin/src/app/ops/page.tsx — client contract + the "HOT recall latency (p95)" gate row (n/a until sampled; target read from code).

Acceptance criteria

  • /admin/stats returns recallLatency {count,p50,p95,max}; empty → zeros, never NaN — unit test over the reservoir with injected samples.
  • Timing wraps only the synchronous retrieval; the async recall-rewrite is excluded — recording is placed immediately after retrieveCandidates, before reconstruction; verified by the integration flow.
  • Ops panel shows a HOT recall p95 row vs a 200ms target read from EXIT_GATE_TARGETS, with pass/fail/n-a (count===0).
  • The latency clause is removed from EXIT_GATE_CAVEATS (graph-walk clause kept); admin.service.test.ts asserts it's gone and targets.hotRecallLatencyMs===200.
  • Verified the real way (M11): an ask then GET /admin/stats shows recallLatency.count>=1 and a finite p95 — the new integration test (observed driving login→capture→encode→ask→stats, all 200).

Verification (all green)

  • pnpm type-check — 7/7 tasks
  • pnpm lint — 7/7 tasks
  • pnpm build — 5/5 tasks
  • pnpm test — api 814 passed; new files independently re-run against the live DB: 3 files / 27 tests passed (integration ran, not skipped)

Substrate-only telemetry: no new off-box call (no privacy-fence surface), userId-scoping unchanged, no hard-delete, performance.now() is a perf measurement (not domain time — §2.6 N/A), no migration.

Co-authored-by: Claude Opus 4.8 noreply@anthropic.com

…it criterion (#308)

The Phase-1 §13.2 exit criterion 2 has two halves: ">70% corpus demoted"
(already measured as `pctWarmOrCooler`) and "HOT recall sub-200ms" — which was
measured NOWHERE and admitted as a caveat. This instruments the synchronous
`ask` retrieval latency (embed → doorway fan-out → RRF fusion → rerank) with a
bounded process-local reservoir mirroring the blessed capture ACK-latency
pattern (#73), surfaces it at GET /admin/stats and the ops exit-gate panel, and
retires the latency caveat. Additive contract; no DB migration.

- recall-latency.ts: new reservoir (reuses `percentile` from ack-latency.ts);
  strong-model reconstruction + async recall-rewrite deliberately excluded.
- memory.service.ts ask(): sample the sync retrieval for ALL confidence bands.
- exit-gate.ts: add `hotRecallLatencyMs: 200` target; split the combined caveat
  so only graph-walk recall quality remains a caveat.
- admin.service.ts getStats(): surface `recallLatency` beside `captureAckLatency`.
- admin api client + ops/page.tsx: extend the /admin/stats contract; new GateRow.

Closes #308

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
@Jaybhade
Jaybhade merged commit 3f22261 into main Jul 19, 2026
5 checks passed
@Jaybhade
Jaybhade deleted the fix/308-recall-latency-telemetry branch July 19, 2026 13:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(recall): HOT-recall latency telemetry — measure the sub-200ms exit criterion (§13.2)

2 participants