feat(persona): engram recall surface (#1121 PR-5)#1163
Conversation
Closes the read-side of the engram thread. Admission state from PR-4
already accumulates engrams per-persona; this PR adds the typed query
API + IPC handler so callers can actually retrieve them.
What ships:
- `AdmissionState::recall_recent(limit)` — newest-first N engrams.
- `AdmissionState::recall_by_id(id)` — exact lookup.
- `AdmissionState::recall_by_keyword(keyword, limit)` — case-insensitive
substring, newest-first, limit-capped. Empty keyword = empty Vec
(caller-meant-to-skip semantic, not match-everything).
- `AdmissionState::recall_by_origin_kind(kind, limit)` — filter by
Chat / Airc / Tool / SelfReflection.
- `EngramOriginKind` discriminator enum + `From<&EngramOrigin>` impl —
exhaustive match means new origin variants force compile-time update.
- `cognition/recall-engrams` IPC handler — kind=recent|by_id|by_keyword|by_origin
+ standard params. Returns `{ engrams, count }` JSON. Defaults to
kind=recent + limit=10.
What this PR does NOT ship (deferred):
- ORM persistence (PR-6) — engrams still in-memory; queries hit the Vec.
API stays the same when the backing store swaps.
- Embedding-based / semantic recall (PR-7+) — keyword is substring only.
- Pagination cursors — limit is the only knob; recall_recent doesn't
expose offset (assumption: callers want the most recent slice).
Tests: 15/15 admission_state pass (was 9, +6 new):
- recall_recent_returns_newest_first
- recall_recent_respects_limit_above_and_below_count
- recall_by_id_finds_known_returns_none_unknown
- recall_by_keyword_case_insensitive_newest_first_with_limit
- recall_by_origin_kind_filters_to_requested_variant
- engram_origin_kind_covers_all_origin_variants (compile-time exhaustive)
Card: continuum#1162. Closes the engram thread substrate (PRs 1-5 +
fix #1157 all merged on canary). The next slice is ORM persistence
(PR-6) or TS-side wiring of the cognition/admit + cognition/recall
handlers from the chat path (separate slice).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Quick review (claude tab #2). Reviewed PR-2/3/4 in this lane; PR-5 closes the read side cleanly. Architecture — consistent with PR-4
IPC handler dispatches on Things to consider (none blocking)
What I particularly like
RecommendationLGTM to merge (already merged per the broadcast). The 4 nits are PR-6 territory or comment additions, none blocking. The engram lane (#1129 → #1134 → #1143 → #1155 → #1163 → #1161 fix) reads as one coherent design across 5 substantive PRs in <24h. Architecture continuity is the win — each PR's review is cheap because the shape was right at PR-1. PR-6 (ORM persistence) is the next-and-last for the engram thread per the broadcast. Pacing: with admit_inbox + recall both reachable from TS, the in-memory store is enough to build the first persona-with-real-memory demo even before persistence lands. |
…#1185) Per task #71 — survey of every .json under src/system/recipes/. Findings: the 28 split into 3 pipeline shapes (15 static-view, 10 single-persona-chat, 1 full multi-persona) plus 2 outliers (gan, academy-training). The 10 single-persona-chat are missing 6 steps that multi-persona-chat has (loop-risk, fast-respond, training-mode, record-interaction, chat/send, cooldown). NO recipe currently integrates the engram admission gate shipped on canary in #1129/ #1134/#1143/#1155/#1163. 5 identified gaps with concrete next-sprint cards: 1. Engram integration in Shape B + C (11 recipes need cognition/ admit-inbox-message + cognition/recall-engrams) 2. Resolve academy-training half-migrated state 3. Document gan orphan intent 4. Shape B → Shape C decision (or shared inheritance) 5. version field discipline across all 28 Pure docs PR. Output at docs/cognition/RECIPE-AUDIT-2026-05-14.md. Closes #71. Co-authored-by: Test <test@test.com>
Summary
Closes the read-side of the engram thread. Admission state from PR-4 already accumulates engrams per-persona; this PR adds the typed query API + IPC handler so callers can actually retrieve them.
Card
continuum#1162.
What ships
AdmissionState:recall_recent(limit)— newest-first N engramsrecall_by_id(id)— exact lookuprecall_by_keyword(keyword, limit)— case-insensitive substring, newest-first, limit-cappedrecall_by_origin_kind(kind, limit)— filter by Chat / Airc / Tool / SelfReflectionEngramOriginKinddiscriminator enum +From<&EngramOrigin>impl — exhaustive match means new origin variants force compile-time update (so the recall filter never silently misses a new variant).cognition/recall-engramsIPC handler —kind=recent|by_id|by_keyword|by_origin+ standard params. Returns{ engrams, count }JSON. Defaults tokind=recent + limit=10.Scope (sliced)
Validation
6 new tests:
recall_recent_returns_newest_first(newest-first ordering invariant)recall_recent_respects_limit_above_and_below_count(limit edge cases)recall_by_id_finds_known_returns_none_unknown(exact lookup)recall_by_keyword_case_insensitive_newest_first_with_limit(search semantics + empty-needle skip)recall_by_origin_kind_filters_to_requested_variant(filter correctness)engram_origin_kind_covers_all_origin_variants(compile-time exhaustive From)cargo build --libclean.npm run build:tsclean. Hooks ran without--no-verify.Closes engram thread substrate
PRs 1-5 + fix #1157 all merged on canary. Next slice options:
data/list)cognition/admit-inbox-message+cognition/recall-engramsfrom the chat path so personas actually accumulate + reference their memory in real conversations🤖 Generated with Claude Code