- `KvEngine::Postgres` slotted in: all six kv-op dispatch arms, the `KvCursor::Postgres` materializing body behind `AnyCursor`'s kv arm (the recorded sub-enum design point, landed as predicted), and the engine-neutral `ensure_gc_schema` call creating `gc_pins` + `gc_window` in the fresh schema at construction (the fleet host's both-tables row, ADR-012 §5) - The two named constructors behind feature `postgres` (default-off): `dual_tier_postgres_local(config, opts, root, threshold, window_delay)` — the fleet-capable-kv production shape — and `kv_only_postgres(config, opts, threshold, window_delay)`; the DSN connection settings + engine opts ride the constructor parameters, never invented defaults. `PgOpts` is pub and re-exported from `lib.rs` (it is on the public constructor signature now) - The sweep's durable form runs on the postgres host: the form body extracted into `sweep_window_durable<W: EngineWindowState>` (sqlite's arm delegates, behavior unchanged), both SQL-backed arms keyed off the kv-engine enum, never a flag — wave 5's pg-lo dormancy slots in without reshaping - Non-fleet posture recorded on both constructors (ADR-012 §3): implicitly `fleet: false`, the ADR-005 in-process protocol verbatim, the `fleet: true` declaration is wave 6 and slots in without reshaping - Stale scope notes updated to the landed state (engine-representation doc, `KvCursor` design point, fleet-declaration paragraph, one-window-host paragraph, postgres module doc, gc.rs companion-seam note); the batch-delete helper's scope note stays (wave 6 consumer) - 5 new env-driven construction tests (skipping server-less): the modes construct and introspect, both GC tables exist in the fresh schema, the window-delay default is the pinned 5-min constant and tunable (`0` legal), the kv-only rejection wiring is unchanged, the dual-tier shape round-trips through both tiers, and the durable form is observed staging/executing across sweeps on the postgres host Verification: `cargo test` 69/19/3 ok; `cargo test --features postgres` 102/19/3 ok live (pglo-poc harness) and green server-less; `cargo test --no-default-features --features postgres` (the pg-pure build, ADR-013 §4) 75/2/3 ok server-less; `cargo test --all-features` 157/54/4 ok; clippy `-D warnings` green (default, postgres, pg-pure, all-features); `cargo fmt --check` green; `cargo doc --no-deps` clean.
12 KiB
id, name, status, depends_on, scope, risk, impact, level, tags
| id | name | status | depends_on | scope | risk | impact | level | tags | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| store-postgres-construction | postgres constructor wiring — the fleet-capable store shapes | completed |
|
narrow | low | component | implementation |
|
Description
Slot postgres into the facade's engine representation — the slotting-in
pattern src/store.rs's module doc pinned ("adding an enum variant and
a named constructor is slotting in"):
KvEngine::Postgresvariant behind#[cfg(feature = "postgres")]+ the dispatch arms (put/get/has/size/delete/list). The kv cursor dispatch slots the postgres materializing body intoKvCursor(the recorded sub-enum design point: "postgres (wave 4) slots one arm in here" — the store.rs doc note is updated to the landed state).- Named constructors, feature-gated on
postgres(default-off — they construct under--features postgres):- dual-tier
kv = postgres + large = local— the fleet-capable-kv production shape (non-fleet here; see below); fallible (config parse, connect, schema bootstrap, the local root creation). Size-threshold dispatch at the constructor-tunable threshold as in the sqlite shape. - kv-only(postgres) — no large tier;
thresholdis the put-time rejection point (ADR-012 §6.2; the rejection machinery is the put seam's, already landed — only the constructor slots in). - Both take the connection settings + engine opts (recorded
design point: the DSN form — the tokio-postgres
Config-parseable string, the alkstoreopen(config, PgOpts)pin adapted to the named-constructor shape — and the opts shape carrying schema name, pool size,synchronous_commit; engine-configuration concerns ride the constructor parameters, never invented defaults) and the delete-window delay parameter (Duration, defaultDEFAULT_DELETE_WINDOW_DELAY,0the legal degenerate tuning — the sqlite constructors' signature shape).
- dual-tier
- Non-fleet posture — these constructors are implicitly
fleet: false(ADR-012 §3): the ADR-005 in-process protocol applies verbatim regardless of engine; pins are in-process guards, the sweep lease is the in-process lock, and none of theEngineFleetStateclauses run. Thefleet: truedeclaration is wave 6 (the fleet-validity predicate + constructor declarations) — no fleet parameter is added here; wave 6 slots it in without reshaping. Recorded in the constructor docs so the wave-6 slotting is a non-event. ensure_gc_schemaat construction — the store-core call (engine-neutral; the postgres arm createsgc_pins+gc_windowper the fleet host's applicability row). A construction failure isErr(Error::Io)per the fallible-constructor pattern.- The one-window-host rule's store-core posture — already recorded (the durable window hosts on the kv engine when it is SQL-backed); the postgres arm slots in under it with no reshaping. Verify the recorded posture's wording covers postgres (it names "sqlite or postgres" already — ADR-012 §5) and that the form branch keys off the kv-engine enum, never a flag.
- Stale scope notes updated — the engine-representation doc's
"postgres (wave 4)" forward references, the
KvCursordesign-point note, and any#![allow(dead_code)]scope notes whose scope changes (the batch-delete helper's note stays — its consumer is still wave 6). - Constructor unit tests: the modes construct and introspect
correctly (
mode()/threshold()),ensure_gc_schemaran (both GC tables exist in the fresh schema), the window-delay default is the pinned constant, kv-only rejection wiring unchanged, the dual-tier shape round-trips end-to-end (a smoke put/get through both tiers). Env-driven, skipping cleanly server-less (the engine tests' convention). - The pg-pure build —
cargo check --no-default-features --features postgres(and the tests target under it): ADR-013 §4's supported non-default configuration first becomes constructible here; verify it compiles clean.
Acceptance Criteria
KvEngine::Postgresslots in; all six kv ops dispatch; the kv cursor body slots intoKvCursor(the design-point note updated to the landed state)dual_tier_postgres_local+kv_only_postgresconstructors exist behind featurepostgres, take connection settings + engine opts + threshold + window delay, fallible where I/O is fallibleensure_gc_schemaruns at construction (both GC tables in the fresh schema); the window-delay shipped default is 5 min (pinned constant) and constructor-tunable;0legal- The non-fleet posture recorded (in-process protocol verbatim;
the
fleet: truedeclaration is wave 6, slotting in without reshaping) - The one-window-host posture verified to cover postgres; the form branch keys off the kv-engine enum
- The pg-pure build (
--no-default-features --features postgres) compiles clean cargo test(default) green;cargo test --features postgresgreen server-less (skipping);cargo clippy --all-targets -- -D warningsandcargo fmt --checkgreen (default +--features postgres)
References
- src/store.rs (the engine-representation design point; the
constructor modes; the slotting-in pattern; the
KvCursorsub-enum design point) - docs/architecture/decisions/011-vocabulary-tiers-engines-and-fleet-state.md §4 (modes; the constructor table)
- docs/architecture/decisions/012-pre-decomposition-consistency-rulings.md §3 (fleet activation is a declaration — wave 6), §5 (the one-window-host rule), §6.3 (dual-tier shapes)
- docs/architecture/decisions/008-trait-size-probe-fleet-gc-and-large-engines.md §2 (the window delay, default 5 min)
- docs/architecture/decisions/013-family-composition-reactive-boundary-and-feature-graph.md §4 (the feature graph; the pg-pure build)
- tasks/engine-postgres.md, tasks/engine-postgres-fleet.md (the engine
- seam bodies this wires)
- tasks/store-sqlite-construction.md (the structural twin's recorded design points)
Notes
Implemented in
src/store.rs+src/postgres.rs+src/lib.rs(wave 4, followingstore-sqlite-construction— the structural twin — point for point). Recorded design points, as resolved:
- Opts on the public surface —
PgOptswentpub(and is re-exported fromlib.rsbehind the feature gate): the constructors' engine-opts parameter is on the public constructor signature, so the type must be nameable there (the alkstoreopen(config, PgOpts)pin adapted to the named-constructor shape; the connection settings remain the separate DSN-string argument).KvCursorslotting — postgres's materializing body slotted into the recorded sub-enum exactly as predicted: one variant, twoReadCursorimpl arms, no reshaping ofAnyCursor/Blob. The store.rs design-point note reads landed.ensure_gc_schemarides the engine-neutralKvEnginecall — the postgres arm forwards to theEngineWindowStateclause (the fleet host's both-tables body:gc_pins+gc_windowin the fresh schema), and both constructors dispatch through it (the store core calls the kv engine, never a typed postgres path). Construction failure isErr(Error::Io)per the fallible- constructor pattern (?throughout).- The sweep's form branch — the durable-form body was extracted into
sweep_window_durable<W: EngineWindowState>(behavior unchanged for sqlite, whose arm now delegates); both SQL-backed arms call it, so the form branch still keys off the kv-engine enum, never a flag, and wave 5's pg-lo dormancy slots in without reshaping. The one-window-host posture's wording now names both SQL-backed hosts (module doc + the sweep doc).- Non-fleet posture — both constructors' docs carry the ADR-012 §3 recording verbatim: implicitly
fleet: false, the ADR-005 in-process protocol applies regardless of engine (in- process pins, in-process sweep lease, noEngineFleetStateclause runs), and thefleet: truedeclaration is wave 6, slotting in without reshaping — no fleet parameter carried.- Signature shape —
dual_tier_postgres_local(config, opts, root, threshold, window_delay)/kv_only_postgres(config, opts, threshold, window_delay): connection settings first (the tokio-postgresConfig-parseable DSN string), engine opts second, then the sqlite twins' remaining parameters (root/threshold/ window delay). The DSN is&str—PostgresBackend::newparses; no invented defaults anywhere.- Clippy notes —
KvEngineneeded a scoped#[allow(clippy::large_enum_variant)]under the postgres configs (the payloads are structurally dissimilar — oneArcvs the pooled-connection posture inline — and all dispatch rides the enum by reference, so the size difference costs nothing; recorded on the enum doc). The store-constructiontable_existsprobe (pg_tables, schema-scoped) mirrors the sqlite engine's#[cfg(test)]instrument.- Tests (5 new, env-driven, skipping server-less) — dual-tier construction + routing + both-GC-tables schema check; kv-only construction + rejection wiring (immediate, overflow, zero residue, at-threshold lands); the window-delay default/tunings/ zero; the dual-tier round-trip through both tiers with tier- placement assertions; and a durable-form sweep smoke (zero-delay: first sweep stages and executes nothing — the inline form would delete in-sweep, so this is the form-branch-is-postgres proof — the second sweep executes the overdue set re-arbitrated at execution time). The test-side
KvEnginematches in the existing test modules gainedPostgresarms for--all-featuresexhaustiveness.- Stale scope notes updated to the landed state: the engine- representation doc, the
KvCursordesign point, the fleet- declaration paragraph, the one-window-host paragraph, the postgres module doc's forward reference — andgc.rs's companion-seam note (the fleet family now "waits for wave 6", its clause bodies landed with wave 4). The batch-delete helper's scope note stays (its consumer is still wave 6).
Summary
Completed 2026-10-12 (wave 4). Postgres slotted into the facade:
KvEngine::Postgreswith all six kv-op dispatch arms, theKvCursor::Postgresmaterializing body, theensure_gc_schemaengine-neutral call creatinggc_pins+gc_windowin the fresh schema at construction, and the two named feature-gated constructors (dual_tier_postgres_local,kv_only_postgres) taking the DSN connection settings +PgOpts(now public and re-exported) + threshold + the constructor-tunable delete-window delay (DEFAULT_DELETE_WINDOW_DELAYpinned at 5 min,0legal) — both implicitly non-fleet per ADR-012 §3 with wave 6's declaration recorded as a non-reshaping slotting. The sweep's durable form runs on the postgres host through the kv-engine-enum-keyed branch (sweep_window_durable, shared with sqlite's arm). Verification:cargo test69/19/3 ok (default),cargo test --features postgres102/19/3 ok live and green server-less,cargo test --no-default-features --features postgres(the pg-pure build, ADR- 013 §4's first constructible configuration) 75/2/3 ok server-less,cargo test --all-features157/54/4 ok, clippy-D warningsgreen on default + postgres + pg-pure + all-features,cargo fmt --checkgreen,cargo doc --no-depsclean.