Provider-First Memory API Migration Plan
View SourcePurpose
This document defines the migration path for evolving jido_memory from its current ETS/store-centric design into the canonical Jido memory API with pluggable provider implementations such as jido_memory_mempalace and jido_memory_mem0.
The goal is not to make jido_memory itself become MemPalace or Mem0. The goal is to make jido_memory the stable, typed, provider-neutral interface that agents and applications depend on regardless of which memory system sits behind it.
Current State
The current local baseline in jido_memory is:
Jido.Memory.Runtimeis store-centric and directly resolvesnamespaceandstore.Jido.Memory.Storeis the main abstraction boundary.Jido.Memory.BasicPluginis the canonical plugin surface.Jido.Memory.RecordandJido.Memory.Queryare the only canonical typed memory structs.- Retrieval returns bare
[Record.t()]. - There is no provider registry, provider bootstrap, provider capability discovery, or provider contract test suite.
This is a solid v1 for simple ETS-backed memory, but it is not yet the right abstraction for external memory systems with different ingestion, retrieval, and maintenance semantics.
Target Outcome
jido_memory becomes the canonical API package for Jido memory.
It owns:
- stable public runtime facade
- canonical memory structs
- provider behaviours
- capability behaviours
- provider registry and bootstrap helpers
- plugin and action surfaces
- provider contract tests
- migration and documentation story
External implementation packages own concrete memory systems:
jido_memory_mempalacejido_memory_mem0- future providers such as
jido_memory_mirix,jido_memory_zep, or others
Architectural Direction
The design must separate two concerns clearly:
Storeanswers: "How are canonical records persisted and queried?"Provideranswers: "How does a memory system ingest, retrieve, explain, scope, and maintain memory?"
This distinction is critical.
Store remains useful for:
- ETS
- Postgres record persistence
- simple durable storage
- provider internals
Provider becomes the top-level memory abstraction for:
- basic memory
- tiered memory
- MemPalace-style episodic evidence memory
- Mem0-style extracted/reconciled memory
- future graph or hybrid systems
Canonical API Principles
The common API must be:
- stable
- typed
- narrow
- backend-neutral
- capability-aware
The common API must not:
- flatten all providers to a useless lowest common denominator
- force provider-native semantics into
Store - return loose maps when agents need reliable shapes
- let the first sophisticated provider define the API accidentally
Canonical Public Surface
Core structs
jido_memory should own these canonical structs:
Jido.Memory.RecordJido.Memory.QueryJido.Memory.ScopeJido.Memory.HitJido.Memory.RetrieveResultJido.Memory.ExplanationJido.Memory.IngestRequestJido.Memory.IngestResultJido.Memory.CapabilitySetJido.Memory.ProviderInfoJido.Memory.ConsolidationResult
Core behaviours
jido_memory should own these behaviours:
Jido.Memory.ProviderJido.Memory.Capability.IngestionJido.Memory.Capability.ExplainableRetrievalJido.Memory.Capability.Lifecycle
Jido.Memory.Store remains as the persistence substrate, not the memory-system abstraction.
Runtime facade
Canonical runtime operations:
remember/3get/3forget/3retrieve/3capabilities/2info/3ingest/3when supportedexplain_retrieval/3when supportedconsolidate/2when supported
Compatibility rule:
retrieve/3becomes the canonical read path and returnsRetrieveResult
Plugin and actions
Canonical plugin surface:
Canonical actions:
memory.remembermemory.retrievememory.forget
Common vs Provider-Direct Boundaries
The common runtime should only include operations that can be defined cleanly across providers.
These likely belong in the common API:
- direct record write
- direct record fetch
- structured retrieval
- scoped retrieval result
- capability discovery
- retrieval explanation
- optional ingestion
- optional lifecycle consolidation
These should remain provider-direct unless multiple implementations converge on the same shape:
- MemPalace taxonomy graph tools
- MemPalace wake-up or layered recall extras
- Mem0 feedback flows
- Mem0 export/history flows
- Mem0 reconciliation maintenance controls
- provider-specific governance or vault operations
The common surface should be narrow and typed. Provider-native surfaces can be richer.
Current Gaps
Gap 1: Wrong top-level abstraction
Current jido_memory assumes a memory backend is a Store.
That is insufficient for MemPalace and Mem0 because they differ in:
- ingestion pipelines
- retrieval semantics
- scoped identity
- explanation semantics
- maintenance and consolidation behavior
Gap 2: Missing typed result objects
The current package has Record and Query, but not:
- retrieval hits
- retrieval results
- explanation payloads
- ingest request/result types
- capability model
- provider info model
Without these, agents still need provider-specific logic.
Gap 3: Retrieval is too thin
Current retrieval returns [Record.t()].
That loses:
- score
- rank
- matched-on reason
- provider origin
- tier or memory-type origin
- provider extensions
Those are exactly the fields a stable cross-provider API should standardize.
Gap 4: Plugin is ETS-first, not provider-first
The current plugin identity should be BasicPlugin.
That bakes the storage mechanism into the public story instead of making Jido memory provider-driven.
Gap 5: No capability discovery
There is no canonical way to ask:
- does this provider support ingestion?
- explainable retrieval?
- lifecycle consolidation?
- graph augmentation?
- protected memory?
Gap 6: No provider bootstrap ownership model
There is no formal caller-owned bootstrap path for provider child specs or runtime processes.
That matters for more complex providers that may need supervised infrastructure.
Gap 7: No contract suite for external adapters
There is currently no reusable test suite that external provider packages must pass in order to claim compatibility.
Without that, compatibility claims will drift.
Gap 8: jido_memory_os value not yet harvested
jido_memory_os already contains useful ideas for:
- long-term backend boundaries
- richer retrieval query planning
- capability-aware flows
- migration helpers
Those ideas need to be harvested into jido_memory selectively, not copied wholesale.
Desired Package Topology
Canonical package:
jido_memory
External implementation packages:
jido_memory_mempalacejido_memory_mem0
Possible later packages:
jido_memory_mirixjido_memory_zepjido_memory_pgvector
Dependency direction:
- external implementation packages depend on
jido_memory jido_memorydoes not depend on MemPalace or Mem0 packages
This keeps the contract central and implementations modular.
Migration Strategy
The migration should be additive and compatibility-first.
Do not replace the current API in one jump.
Instead:
- introduce provider-first internals
- wrap current behavior with
Provider.Basic - add typed richer APIs
- keep the Jido integration narrow around
BasicPlugin - move users toward
retrieve
Phased Execution Plan
Phase 1: Freeze the API contract
Define and approve:
- canonical structs
- provider callbacks
- capability behaviours
- compatibility policy
- runtime result shapes
- provider-direct boundary rules
Deliverables:
- approved API spec document
- approved list of canonical structs
- approved common vs provider-direct rules
Exit criteria:
- no major unresolved questions about the public contract
Phase 2: Introduce provider core into jido_memory
Add:
Jido.Memory.Provider- capability behaviours
Jido.Memory.ProviderRefJido.Memory.ProviderRegistryJido.Memory.ProviderBootstrapJido.Memory.Provider.Basic
Use Provider.Basic as a wrapper over the current store-based runtime behavior.
Deliverables:
- provider-aware runtime dispatch
- basic provider backed by current
Store - provider aliasing for built-ins
Exit criteria:
- current remember/get/forget/recall flows still work
- ETS path operates through
Provider.Basic
Phase 3: Add canonical typed result structs
Add:
ScopeHitRetrieveResultExplanationCapabilitySetProviderInfoIngestRequestIngestResultConsolidationResult
Extend Query to support safe provider extensions and richer retrieval metadata.
Deliverables:
- new canonical structs
- serialization and validation logic
- docs for each shared struct
Exit criteria:
- common runtime no longer uses loose maps for shared retrieval and capability outputs
Phase 4: Move runtime to canonical provider semantics
Change Runtime so that:
retrieve/3is canonical and returnsRetrieveResultrecall/2is compatibility-onlycapabilities/2returnsCapabilitySetinfo/3returnsProviderInfo- optional capability routes dispatch through provider behaviours
Deliverables:
- provider-aware runtime
- canonical result normalization preserved
- error model updated for unsupported capability cases
Exit criteria:
Runtimeno longer assumesStoreis the top-level backend abstraction
Phase 5: Introduce provider-aware plugin and actions
Add canonical plugin:
Add actions:
memory.retrieve
Deliverables:
- provider-aware plugin config
- provider-aware action routing
- updated plugin docs and examples
Exit criteria:
- agent code can use providers without coupling to ETS
Phase 6: Add provider contract test suite
Create reusable provider contract tests inside jido_memory.
The contract suite should verify:
- provider initialization
- capability normalization
- remember/get/forget core flow
- retrieve result shape
- explanation shape when supported
- unsupported-capability behavior
- compatibility behavior for
recall
Deliverables:
- provider contract helper module
- shared provider contract tests
- guidance for external provider packages
Exit criteria:
Provider.Basicpasses the suite- the suite is reusable from external repos
Phase 7: Harvest the best ideas from jido_memory_os
Harvest selectively:
- long-term store boundary
- richer retrieval-query ideas
- tiered lifecycle ideas that fit the common contract
- migration or parity-test material
Do not copy:
- heavy control-plane machinery
- governance or ops surfaces that do not belong in core
- a second package narrative
Deliverables:
- extracted concepts adapted into
Jido.Memoryterminology - updated tests and docs proving the adaptation
Exit criteria:
- useful
MemoryOSideas live injido_memory - no duplicate public abstraction story remains
Phase 8: Create jido_memory_mempalace
External package implements:
Core mapping:
- raw drawers or episodic evidence map into canonical
Record - retrieval returns canonical
HitandRetrieveResult - raw evidence remains the source of truth
Provider-direct extras may include:
- taxonomy introspection
- graph navigation
- wake-up/layered recall
Deliverables:
- provider implementation package
- provider contract tests passing
- example integration with
Jido.Memory.Runtime
Exit criteria:
- agents can use MemPalace through the shared runtime facade
Phase 9: Create jido_memory_mem0
External package implements:
Core mapping:
- extracted or reconciled facts map into canonical
Record - scoped identity maps into canonical
Scope - retrieval returns canonical
HitandRetrieveResult
Provider-direct extras may include:
- feedback
- history
- export
- maintenance and refresh operations
Deliverables:
- provider implementation package
- provider contract tests passing
- example integration with
Jido.Memory.Runtime
Exit criteria:
- agents can use Mem0 through the shared runtime facade
Phase 10: Documentation and migration cleanup
Update all public documentation so that:
jido_memoryis clearly the canonical package- ETS is presented as the basic built-in provider path
- MemPalace and Mem0 are presented as implementations
- compatibility paths are documented and eventually de-emphasized
Deliverables:
- updated README
- migration guide
- provider author guide
- example agent integrations
Exit criteria:
- docs reflect the provider-first architecture consistently
Recommended PR Sequence
Suggested incremental PRs:
- API spec and planning docs
- provider core and
Provider.Basic - typed retrieval and provider metadata structs
- runtime provider dispatch and compatibility shims
- provider-aware plugin and
memory.retrieve - provider contract tests
- harvested long-term/tiered concepts from
jido_memory_os jido_memory_mempalacejido_memory_mem0- docs and migration pass
Acceptance Criteria
The migration is successful when:
jido_memoryis the canonical Jido memory API- agents depend on stable structs and behaviours rather than backend details
- ETS/basic remains simple and non-regressed
- MemPalace and Mem0 both fit naturally as provider implementations
- common runtime operations are typed and capability-aware
- external providers can prove compatibility through shared contract tests
Risks
Risk: designing around one provider
If the API is shaped around MemPalace only, it will underfit Mem0. If shaped around Mem0 only, it will underfit evidence-first systems.
Mitigation:
- use
Basic,MemPalace, andMem0as the proving set
Risk: leaking provider-specific flags into the common facade
Mitigation:
- keep provider-native operations provider-direct
- use typed
extensionsonly where necessary
Risk: preserving too much of the store-centric story
Mitigation:
- keep
Store, but demote it to provider infrastructure
Risk: importing too much from jido_memory_os
Mitigation:
- harvest only what strengthens the canonical package
- leave heavy control-plane machinery behind unless proven necessary
Immediate Next Step
The next concrete step is to convert this planning document into a formal API specification for:
- provider callbacks
- canonical structs
- runtime return types
- compatibility rules
- provider-direct extension boundaries
That API specification should be approved before implementation begins.