--- id: store-postgres-construction name: postgres constructor wiring — the fleet-capable store shapes status: pending depends_on: [engine-postgres, engine-postgres-fleet] scope: narrow risk: low impact: component level: implementation tags: [wave-4, store, postgres, construction] --- ## 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::Postgres`** variant behind `#[cfg(feature = "postgres")]` + the dispatch arms (`put`/`get`/`has`/`size`/ `delete`/`list`). The kv cursor dispatch slots the postgres materializing body into **`KvCursor`** (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; `threshold` is 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 alkstore `open(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`, default `DEFAULT_DELETE_WINDOW_DELAY`, `0` the legal degenerate tuning — the sqlite constructors' signature shape). - **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 the `EngineFleetState` clauses run. **The `fleet: true` declaration 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_schema` at construction** — the store-core call (engine-neutral; the postgres arm creates `gc_pins` + `gc_window` per the fleet host's applicability row). A construction failure is `Err(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 `KvCursor` design-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_schema` ran (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::Postgres` slots in; all six kv ops dispatch; the kv cursor body slots into `KvCursor` (the design-point note updated to the landed state) - [ ] `dual_tier_postgres_local` + `kv_only_postgres` constructors exist behind feature `postgres`, take connection settings + engine opts + threshold + window delay, fallible where I/O is fallible - [ ] `ensure_gc_schema` runs at construction (both GC tables in the fresh schema); the window-delay shipped default is 5 min (pinned constant) and constructor-tunable; `0` legal - [ ] The non-fleet posture recorded (in-process protocol verbatim; the `fleet: true` declaration 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 postgres` green server-less (skipping); `cargo clippy --all-targets -- -D warnings` and `cargo fmt --check` green (default + `--features postgres`) ## References - src/store.rs (the engine-representation design point; the constructor modes; the slotting-in pattern; the `KvCursor` sub-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 > To be filled by implementation agent ## Summary > To be filled on completion