ai-memory v0.8.0

Runbook — v0.7.0 adapter selection (serve --store-url postgres://…)

UPDATED 2026-05-09. Per operator directive issued during the v0.7.0 A2A certification window, the adapter-selection refactor previously deferred to v0.7.1 lands in v0.7.0 as Wave 3 of the v0.7.0 A2A campaign expanded scope. See docs/v0.7.0/release-notes.md for the full Wave 1-4 plan and docs/postgres-age-guide.md for the operator how-to. The body of this runbook is preserved as design context — the “deferred” framing is historical; treat the roadmap below as the v0.7.0 implementation plan.

Status: landing in v0.7.0 (Wave 3 of v0.7.0 expanded scope). Original scoping date: 2026-04-19 (v0.7.1 deferred). Re-scoped: 2026-05-09 (folded into v0.7.0). Depends on: #279 SAL trait, #283 migration tool, plus Wave 1 schema-init CLI and Wave 2 schema parity v15→v28 (both also v0.7.0 expanded scope).

This runbook tracks the “daemon-level adapter selection” caveat that v0.7-alpha originally carried into v0.7.1. The v0.7-alpha ship:

The v0.7.0 A2A campaign (ai-memory-a2a-v0.7.0) re-opened that scope because the in-tree SAL contract test passed cleanly (20/20) and the remaining gap was the daemon-level adapter selection plus a small set of SQL/CLI surfaces — small enough to land within the v0.7.0 cert window rather than carve out a v0.7.1 micro-release.

What was blocking (preserved as design context)

src/handlers.rs (~2,000 LOC) dispatched writes, reads, recalls, and sync directly through crate::db:: free functions that assumed a Mutex<rusqlite::Connection>. To flip serve onto PostgresStore, every call site must route through Box<dyn MemoryStore> instead.

Specifically:

v0.7.0 implementation plan (Wave 1-3)

The expanded scope splits the v0.7.0 work into three implementation waves, each verified independently before the next begins:

Wave 1 — surgical postgres+AGE fixes (in flight 2026-05-09)

Three parallel streams close the F6 (#646) gap inventory without touching adapter selection:

Wave 2 — postgres schema parity v15 → v28

Port the 13 SQLite migrations the postgres adapter is currently missing (per docs/coverage.md schema-parity gap table):

Migration Feature gated
v16 governance inheritance (cross-agent inherit=true)
v17 webhook subscriptions
v18 audit log chain
v19 transcripts
v20 signed events
v21 agent quotas
v22 link attest_level column
v23 A2A correlation table
v24 smart-load veto state
v25 KG temporal-index v2
v26 tier-promotion metadata
v27 subscription DLQ
v28 consolidated_from_agents array

Each migration ports as an idempotent CREATE TABLE/INDEX IF NOT EXISTS + ALTER TABLE … ADD COLUMN IF NOT EXISTS pair following the SQLite migration’s intent. Tests in tests/postgres_schema_parity.rs snapshot the full DDL set against the SQLite v28 truth fixture and fail if either side drifts.

Wave 3 — ai-memory serve --store-url postgres://

The original v0.7.1 design points (preserved below) become the v0.7.0 Wave 3 plan with one revision: the SAL recall extension lands as part of Wave 1 (Stream A’s recall scoring parity fix already touches the trait shape), so Wave 3 reduces to handler routing + AppState field plumbing.

  1. Trait extensionMemoryStore::recall_hybrid, MemoryStore::sync_push_batch, MemoryStore::sync_since all live on the trait by end of Wave 1.
  2. SqliteStore continues to wrap crate::db::. No behavior change for the default build.
  3. New AppState field store: Arc<dyn MemoryStore>. Existing db: Db stays during the migration for back-compat.
  4. New serve flag --store-url <url>. When set and --features sal[-postgres] is enabled, build the store adapter and use it. When unset, default to SqliteStore::open(db_path).
  5. Feature-gate strictly. Operators on the default build must see zero behavior change.

Wave 4 — live A2A on postgres

Re-run the v0.7.0 A2A campaign (the ai-memory-a2a-v0.7.0 repo) with both droplets pointed at a shared postgres+AGE backend instead of per-droplet sqlite. S70-S76 flip from “PASS via Path B in-tree validators” to “PASS via live daemon-on-postgres” — that’s the cert acceptance criterion for the v0.7.0 expanded scope.

Test plan for v0.7.0 (Waves 1-3)

Status — landing in v0.7.0

Tracking: master issue #637, F6 follow-through #646, PR #643, expanded scope tracker (filed alongside this runbook update).

Explicitly out of scope for v0.7.0 (deferred to v0.7.1+)

CHANGELOG line for v0.7.0

v0.7.0 ships postgres + Apache AGE as a first-class storage backend. ai-memory serve --store-url postgres://… is supported for live daemon use. The full schema (v28) is portable across SQLite and Postgres. KG features (kg_query, kg_timeline, kg_invalidate, find_paths) work identically on both backends — via pgvector + AGE Cypher on Postgres, FTS5 + HNSW + recursive-CTE on SQLite. See docs/postgres-age-guide.md and docs/migration-v0.7.0-postgres.md.