feat(store): the postgres constructor wiring — the fleet-capable store shapes (wave 4)

- `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.
This commit is contained in:
glm-5.3-flash committed 2026-10-12 06:34:36 +00:00
1 parent 29209fe53f
commit 67b927b13c
5 files changed
+842 -72

No files matched your search

+96 -10
View File
@@ -1,7 +1,7 @@
---
id: store-postgres-construction
name: postgres constructor wiring — the fleet-capable store shapes
status: pending
status: completed
depends_on: [engine-postgres, engine-postgres-fleet]
scope: narrow
risk: low
@@ -79,24 +79,24 @@ a named constructor is slotting in"):
## Acceptance Criteria
- [ ] `KvEngine::Postgres` slots in; all six kv ops dispatch; the kv
- [x] `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
- [x] `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
- [x] `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;
- [x] 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
- [x] 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`)
- [x] The pg-pure build (`--no-default-features --features postgres`)
compiles clean
- [ ] `cargo test` (default) green; `cargo test --features postgres`
- [x] `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`)
@@ -122,8 +122,94 @@ a named constructor is slotting in"):
## Notes
> To be filled by implementation agent
> Implemented in `src/store.rs` + `src/postgres.rs` + `src/lib.rs`
> (wave 4, following `store-sqlite-construction` — the structural
> twin — point for point). Recorded design points, as resolved:
>
> - **Opts on the public surface** — `PgOpts` went `pub` (and is
> re-exported from `lib.rs` behind the feature gate): the
> constructors' engine-opts parameter is on the public constructor
> signature, so the type must be nameable there (the alkstore
> `open(config, PgOpts)` pin adapted to the named-constructor shape;
> the connection settings remain the separate DSN-string argument).
> - **`KvCursor` slotting** — postgres's materializing body slotted
> into the recorded sub-enum exactly as predicted: one variant, two
> `ReadCursor` impl arms, no reshaping of `AnyCursor`/`Blob`. The
> store.rs design-point note reads landed.
> - **`ensure_gc_schema`** rides the engine-neutral `KvEngine` call —
> the postgres arm forwards to the `EngineWindowState` clause (the
> fleet host's both-tables body: `gc_pins` + `gc_window` in the
> fresh schema), and both constructors dispatch through it (the
> store core calls the kv engine, never a typed postgres path).
> Construction failure is `Err(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, no `EngineFleetState` clause
> runs), and the `fleet: true` declaration 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-postgres `Config`-parseable DSN string), engine opts second,
> then the sqlite twins' remaining parameters (root/threshold/
> window delay). The DSN is `&str` — `PostgresBackend::new` parses;
> no invented defaults anywhere.
> - **Clippy notes** — `KvEngine` needed a scoped
> `#[allow(clippy::large_enum_variant)]` under the postgres
> configs (the payloads are structurally dissimilar — one `Arc` vs
> 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-construction `table_exists` probe
> (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 `KvEngine` matches in the existing
> test modules gained `Postgres` arms for `--all-features`
> exhaustiveness.
> - Stale scope notes updated to the landed state: the engine-
> representation doc, the `KvCursor` design point, the fleet-
> declaration paragraph, the one-window-host paragraph, the
> postgres module doc's forward reference — and `gc.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
> To be filled on completion
> Completed 2026-10-12 (wave 4). Postgres slotted into the facade:
> `KvEngine::Postgres` with all six kv-op dispatch arms, the
> `KvCursor::Postgres` materializing body, the `ensure_gc_schema`
> engine-neutral call creating `gc_pins` + `gc_window` in 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_DELAY` pinned at 5 min, `0` legal) — 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 test` 69/19/3 ok (default), `cargo test --features postgres`
> 102/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-features` 157/54/4 ok, clippy `-D warnings` green
> on default + postgres + pg-pure + all-features, `cargo fmt --check`
> green, `cargo doc --no-deps` clean.