Skip to content

Primary CLI session never calls getRelevantContext — task-scoped memory retrieval fires on the Telegram path but not the main turn path #1573

Description

@christauff

Summary

LifeOS ships a ranked, task-scoped memory retriever — getRelevantContext (the "F6" function in LIFEOS/TOOLS/MemoryRetriever.ts): a BM25 search over MEMORY/KNOWLEDGE/* plus the two hot-layer files, documented in-code as "a markdown block ready for injection into buildLifeosContextBlock."

That injection happens on the Telegram path (buildLifeosContextBlockgetRelevantContext). It does not happen on the primary CLI turn path. On the CLI, hooks/MemoryTurnStart.hook.ts composes LoadMemory.run() (the static hot-layer <pai-memory> digest) and MemoryDeltaSurface.run() (freshness telemetry) — but never calls getRelevantContext. Confirmed on current main: hooks/LoadMemory.hook.ts references getRelevantContext zero times.

So a terminal session sees only the fixed ~48-entry hot-layer digest, never a retrieval scoped to what was actually asked. Prior work that is present in the corpus — and top-ranked for the query — is never surfaced, because the retriever is never invoked. The digest is capped and generic by design, so it can't carry a task-specific fact.

Environment

Current main, CLI (terminal) session. Files: hooks/MemoryTurnStart.hook.ts, hooks/LoadMemory.hook.ts, LIFEOS/TOOLS/MemoryRetriever.ts.

Steps to reproduce

  1. Add a note under MEMORY/KNOWLEDGE/ on some topic.
  2. In a CLI session, submit a prompt about that topic.
  3. Inspect the injected context: <pai-memory> (static digest) is present; no task-scoped retrieval block appears. Then run bun LIFEOS/TOOLS/MemoryRetriever.ts "<the prompt>" directly and see the note ranked at the top — proof the retriever would have surfaced it had it been called.

Observed / impact

A small label-based check over the KNOWLEDGE corpus: for a feasibility-style prompt whose answer already existed as a note, getRelevantContext ranks the correct note #1 (recall@5 = 100%) on the query. The retrieval works; it is simply never called on the CLI path, so the ranked hit reaches the model on Telegram but not in a terminal session. This is a wiring gap, not a retrieval-quality problem — and it surfaces as "the assistant fanned out to research something its own corpus already answered."

Fix suggestion

Option A (preferred — completes the existing orchestration). In MemoryTurnStart.hook.ts, after LoadMemory.run(), call getRelevantContext(prompt, { topK: 5, threshold: 0.20 }) with the submitted prompt (already on the hook's stdin JSON as prompt) and append its markdownBlock as a <pai-ground> section of the same additionalContext. ~10 lines, stays synchronous (the hook is already async: false), no new registration, and reaches CLI/Telegram parity in the one hook that already owns CLI memory injection.

Option B (standalone hook). A small GroundFirst.hook.ts on UserPromptSubmit doing the same, independently toggleable, with an idempotency guard so it composes safely if Option A also lands.

Both are cheap (getRelevantContext is synchronous BM25 over ~50 notes, 60s-cached) and fail-open. Read-side only; same corpus getRelevantContext already reads; no new dependencies. Happy to send a diff for Option A if that shape is preferred.

Thanks as always for the project and the pace it moves at.

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