Observation
When a pack declares a non-default backend via [packs.<pack>] backend = "<name>", the pack's schema_plan() DDL is applied to the default (main) backend in addition to (or instead of being scoped to) the routed target backend.
Concretely, with a config of the shape:
[[backends]]
name = "main"
kind = "sqlite"
path = "…/main.db"
[[backends]]
name = "sessions"
kind = "sqlite"
path = "…/sessions.db"
[packs.session]
backend = "sessions"
after daemon startup the session-pack tables (sessions, session_messages, session_mirror_cursor) exist in both databases:
sessions.db — populated (data writes route here correctly per [packs.session])
main.db — present but empty (0 rows)
The empty tables in the default backend were observed to be re-created on restart with the routing already in place (an explicitly-dropped sessions table reappeared empty after the next daemon start), which points at the schema_plan() apply path targeting the default backend rather than the pack's declared backend.
Impact
Benign today: data writes route to the correct backend, so there is no correctness or dual-write problem. The cost is a set of inert empty schema shells in the default backend, and a mild violation of the ADR-028 pack-scoped-backends intent (a pack's schema should live only in its backend).
Pointers
crates/khive-pack-session/src/pack.rs — schema_plan() returns SchemaPlan { pack: "session", statements: &SESSION_SCHEMA_PLAN_STMTS }
- The
SchemaPlan apply path (runtime schema application) is where backend targeting should be honored.
- ADR-028 — pack-scoped backends and per-pack schema declaration.
Suggested fix direction
Scope schema_plan() application to the backend resolved for the pack ([packs.<pack>].backend, falling back to default), so a routed pack does not create its tables in the default backend.
Priority: low (benign, no data impact).
Observation
When a pack declares a non-default backend via
[packs.<pack>] backend = "<name>", the pack'sschema_plan()DDL is applied to the default (main) backend in addition to (or instead of being scoped to) the routed target backend.Concretely, with a config of the shape:
after daemon startup the session-pack tables (
sessions,session_messages,session_mirror_cursor) exist in both databases:sessions.db— populated (data writes route here correctly per[packs.session])main.db— present but empty (0 rows)The empty tables in the default backend were observed to be re-created on restart with the routing already in place (an explicitly-dropped
sessionstable reappeared empty after the next daemon start), which points at theschema_plan()apply path targeting the default backend rather than the pack's declared backend.Impact
Benign today: data writes route to the correct backend, so there is no correctness or dual-write problem. The cost is a set of inert empty schema shells in the default backend, and a mild violation of the ADR-028 pack-scoped-backends intent (a pack's schema should live only in its backend).
Pointers
crates/khive-pack-session/src/pack.rs—schema_plan()returnsSchemaPlan { pack: "session", statements: &SESSION_SCHEMA_PLAN_STMTS }SchemaPlanapply path (runtime schema application) is where backend targeting should be honored.Suggested fix direction
Scope
schema_plan()application to the backend resolved for the pack ([packs.<pack>].backend, falling back to default), so a routed pack does not create its tables in the default backend.Priority: low (benign, no data impact).