Imported from bug-ops/zeph (
crates/zeph-agent-persistence/AGENTS.md). Install upstream withnpx skills add bug-ops/zeph --skill zeph-agent-persistence. Copyright stays with the author.
zeph-agent-persistence Guide
Persistence service (PersistenceService): loads conversation history from and writes messages to SemanticMemory (SQLite + Qdrant), plus tool-pair sanitization, embedding decisions, and graph-extraction configuration.
- Start with crate-local checks:
cargo build -p zeph-agent-persistence,cargo nextest run -p zeph-agent-persistence,cargo clippy -p zeph-agent-persistence --all-targets -- -D warnings. - Read
specs/078-agent-persistence/spec.mdbefore changing history loading, persistence, or extraction enqueueing. - Read
specs/068-session-persistence/spec.md(INV-SP-1..4) before changing session-open/hydration behavior —hydrate_from_event_log(hydrate.rs) is the single sanctioned pipeline for ACP resume/load/fork, CLIsessions resume, and/conv resume; itsmessagesfold MUST go throughzeph_session::ReplayEngine::replay's bounded/chunked reader, neverfold()on a cloned eventVec(regression fixed in #5861 — that call doubled peak memory on every resume path). - Core invariant: this crate MUST NOT depend on
zeph-core. Keep the borrow-lens views (MemoryPersistenceView,SecurityView,MetricsView) narrow;zeph-corebuilds them fromAgentfields. - Ephemeral media invariant (spec-072 §4 C1): callers into this crate's persistence path always receive
Image-freeMessagePartslices —zeph-core'sAgent::persist_messagestripsMessagePart::Imagebefore invokingPersistMessageRequest/svc.persist_message. Do not add code here that assumesImageparts need filtering again downstream, and do not weaken the assumption that this crate never itself sees an unstripped slice. - Features:
sqlite(default) /postgresforwarded tozeph-memory— verify behavior is identical across both backends; silent divergence is a first-class bug. - LLM serialization gate: tool-pair sanitization (
sanitize.rs,request.rs) controls whethertool_use/tool_resultblocks are well-formed. A malformed pairing causes hard LLM 400/422 errors that unit tests do not catch — changes here require a live multi-turn + tool-call session test before merge. - Embedding dimension mismatches are a recurring source of bugs: whenever the embedding model or vector collection config changes, verify stored and query vector dimensions match before running tests.
- Multi-model: graph extraction and embedding each call an LLM/embedder — resolve via
*_providerfields referencing named[[llm.providers]]entries; never hardcode a model.