Skip to content

fix(db): restore postgres backend compile and sqlite/postgres parity#4966

Merged
bug-ops merged 1 commit into
mainfrom
fix/4957-zeph-db-dual-backend-correctness
Jun 6, 2026
Merged

fix(db): restore postgres backend compile and sqlite/postgres parity#4966
bug-ops merged 1 commit into
mainfrom
fix/4957-zeph-db-dual-backend-correctness

Conversation

@bug-ops

@bug-ops bug-ops commented Jun 6, 2026

Copy link
Copy Markdown
Owner

Summary

Restores the PostgreSQL backend and the SQLite/PostgreSQL schema parity for the data layer. Three closely related data-layer correctness defects, fixed together:

  • zeph-memory agent_sessions: SqliteStore fails to compile when postgres feature is also enabled (--all-features) #4964 — PostgreSQL backend did not compile. SqliteStore::upsert_agent_session bound the turns count as a bare u32, which only implements sqlx::Type<Sqlite> (PostgreSQL has no unsigned integer types). This pinned the query to the SQLite driver and broke the PostgreSQL backend with E0271 ("expected Sqlite, found Postgres") on any build that activates the postgres feature. turns is now bound via cast_signed() (i32, matching the INTEGER column) and the read tuple decodes it as i32 so PostgreSQL does not reject the INTEGER/INT4 column as an i64 mismatch. A full-workspace cargo check --no-default-features --features postgres now compiles cleanly — this was the only PostgreSQL-breaking bind site in the workspace.

  • zeph-db pool.rs: connect() body empty without sqlite/postgres features causes compile error #4956 — consumer crates could not be built/doc-checked in isolation. Crates depending on zeph-memory/zeph-db without selecting a backend (zeph-sanitizer, zeph-acp, zeph-bench, zeph-tui, and zeph-skills via its optional qdrant dependency) tripped the zeph-db compile_error! plus a follow-on cascade, because the default-features = false workspace deps stripped the default backend. Each crate now carries the standard default = ["sqlite"] / sqlite / postgres feature trio forwarding to zeph-memory, matching the established zeph-mcp/zeph-index pattern. The backend-only imports in zeph-db/src/migrate.rs are gated behind any(feature = "sqlite", feature = "postgres") so a genuine no-backend build surfaces only the clear compile_error!.

  • zeph-db sqlite/postgres migration sequences diverge (file count + content parity) #4957 — SQLite/PostgreSQL migration sequences diverged (P2, system-invariant 001 §13). PostgreSQL was missing the fact_access_log table and messages.memory_tier/messages.qdrant_promoted columns (five-signal SYNAPSE retrieval, feat(memory): extend SYNAPSE to five-signal retrieval + async consolidation daemon #4374) and the implicit_conflict_candidates table (graph conflict detection) — present only in SQLite, so PostgreSQL deployments ran a divergent schema. Added forward-only PostgreSQL migrations 101_five_signal_retrieval.sql and 102_implicit_conflict_candidates.sql (integer columns sized BIGINT to match the i64 Rust accessors), plus a SQLite parity placeholder 101_trajectory_memory_cascade.sql (the cascade is inline on SQLite but needs a dedicated drop-and-re-add migration on PostgreSQL) to keep file counts equal (101 = 101). A new migration_parity integration test fails the build if the dialects ever diverge in file count, logical migration name, or defined table set.

Verification

  • cargo +nightly fmt --check — clean
  • cargo clippy --workspace --all-targets -- -D warnings — clean
  • cargo nextest run --workspace --lib --bins10555 passed, 0 failed, 21 skipped
  • cargo test -p zeph-db --test migration_parity — 3 passed (file-count / logical-name / table-set parity)
  • cargo nextest run -p zeph-memory -E 'test(agent_session)' — 8 passed
  • cargo check --no-default-features --features postgres — clean (PostgreSQL backend compiles end-to-end)
  • cargo check -p {zeph-sanitizer,zeph-acp,zeph-bench,zeph-tui} --lib and -p zeph-skills --lib --features qdrant — all clean (previously failed)
  • RUSTFLAGS="-D warnings" cargo check --workspace --all-targets --features desktop,ide,server,chat,pdf,scheduler --locked — clean
  • RUSTDOCFLAGS="--deny rustdoc::broken_intra_doc_links" cargo doc --no-deps --all-features -p zeph-db -p zeph-memory — clean (one pre-existing private-intra-doc warning, not introduced here)
  • cargo test --doc -p zeph-db -p zeph-memory — 39 passed

Notes / follow-ups

  • A live PostgreSQL round-trip (e.g. binding String to the agent_sessions TIMESTAMPTZ columns) is a separate, runtime-only concern not exercised by any current CI job; tracked as a follow-up.
  • The de-facto backend model is "SQLite always present, PostgreSQL wins by priority when both features are on"; this contradicts the literal wording of system-invariant 001 §13 ("enabling both is a compile_error!"). The code only errors on no backend. The invariant text should be reconciled with the implemented behavior in a follow-up.

Closes #4964
Closes #4956
Closes #4957

- memory: SqliteStore::upsert_agent_session bound `turns` as a bare `u32`,
  which only implements `sqlx::Type<Sqlite>` (Postgres has no unsigned
  integers); this pinned the query to the SQLite driver and broke the
  Postgres backend with E0271 on any build activating the `postgres`
  feature. Bind `turns.cast_signed()` (i32, matching the INTEGER column)
  and decode the read tuple slot as i32. The Postgres backend now compiles
  end-to-end. (#4964)

- db,memory: data-layer consumer crates that depend on zeph-memory/zeph-db
  without selecting a backend (zeph-sanitizer, zeph-acp, zeph-bench,
  zeph-tui, and zeph-skills via its optional qdrant dep) could not be built
  or doc-checked in isolation. Give each the standard
  default=["sqlite"]/sqlite/postgres feature trio forwarding to zeph-memory,
  matching the existing zeph-mcp/zeph-index pattern, and gate the
  backend-only imports in migrate.rs so a no-backend build surfaces only the
  clear compile_error!. (#4956)

- db: the Postgres migration set was missing fact_access_log plus the
  messages.memory_tier/qdrant_promoted columns and the
  implicit_conflict_candidates table, all present only in SQLite, so
  Postgres ran a divergent schema. Add forward-only Postgres migrations
  101_five_signal_retrieval and 102_implicit_conflict_candidates (BIGINT to
  match the i64 accessors) and a SQLite parity placeholder
  101_trajectory_memory_cascade. Add a migration_parity integration test
  asserting file-count, logical-name and defined-table equivalence between
  dialects (system-invariant 001 §13). (#4957)
@github-actions github-actions Bot added bug Something isn't working documentation Improvements or additions to documentation skills zeph-skills crate memory zeph-memory crate (SQLite) rust Rust code changes dependencies Dependency updates size/L Large PR (201-500 lines) and removed bug Something isn't working labels Jun 6, 2026
@bug-ops
bug-ops enabled auto-merge (squash) June 6, 2026 19:26
@bug-ops
bug-ops merged commit 4846e6d into main Jun 6, 2026
32 checks passed
@bug-ops
bug-ops deleted the fix/4957-zeph-db-dual-backend-correctness branch June 6, 2026 19:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Dependency updates documentation Improvements or additions to documentation memory zeph-memory crate (SQLite) rust Rust code changes size/L Large PR (201-500 lines) skills zeph-skills crate

Projects

None yet

1 participant