Files
alkblobs/tasks/review-wave-5.md
T
glm-5.3-flash 93f9a9332c docs(review): the wave-5 review gate — every gate check green
The engine-wave gate read the pg-lo engine, its window-family seam,
the constructor wiring, and the suite column against the pinned ADR
text and found them conformant. One finding fixed inline (PGLO-1, the
wave-5 rustdoc private-link warnings — see the previous commit); no
wave-6 amendments arise from this gate. All gates re-run green after
the fix. Wave 6 (fleet GC) decomposition is unblocked.
2026-10-12 13:56:00 +00:00

268 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: review-wave-5
name: Wave 5 review gate — the pg-lo engine vs the contract
status: completed
depends_on: [suite-column-pg-lo]
scope: narrow
risk: low
impact: phase
level: review
tags: [wave-5, review]
---
## Description
The wave-5 review gate — the engine-wave review shape
(docs/plans/implementation.md §Review gates: "engine-vs-contract
conformance"), before wave 6 decomposes. The gate reads the
implementation against the pinned ADR text line by line (the
wave-1/2/3/4 gates' method).
Gate checks:
- **Engine-vs-contract conformance**: the suite column green against
dockerized postgres (server-less runs skip cleanly — a skip never
substitutes for acceptance); the engine-state clause families
contract-tested per the applicability row (ADR-012 §5's pg-lo row —
the window family only, conditional per the one-window-host rule);
virgin-store semantics; the `size` metadata-only discipline (the
companion-row probe never loads LO content).
- **The engine shape vs ADR-009 §1–§4**: the companion table is the
contract authority (list/size/has/CAS all table-level);
`pg_largeobject` never read for addressing; put = one tx with the
512 KiB knee as a named constant (the C2 citation); the staged put's
held-tx body with both hygiene forms exact-count tested; gets ride
descriptorless `lo_get(oid, off, len)` windows (the C4 posture — the
held-descriptor fallback named as not-shipped, never coded); the
64-bit-variants discipline (the C7 int4 trap not inherited); delete
= one tx under table-level arbitration; transactional LO creation
(zero crash orphans structurally — the C6 reading).
- **The posture deltas vs ADR-009 §5/§6**: carried as requirements,
not hedges — catalog space never returned (the `VACUUM FULL`
operator line + rel-size monitoring named in the module doc);
autovacuum inherited, keep it on; the orphan-recovery sweep present
for the legacy/bypass class (scope-noted, contract-tested with a
planted orphan); the cached-get capacity facts named honestly.
- **The one-window-host rule vs ADR-012 §5**: the store-core
completion — `ensure_gc_schema` follows the host rule at
construction (dormancy on dual-SQL: the consolidation shape's pg-lo
schema carries no `gc_window`; the pg-lo host on kv=mem); the sweep
form branch runs the durable form on the pg-lo host for kv=mem +
large=pg-lo and keys off the engine representation, never a flag;
**no fleet state anywhere in pg-lo** (nothing of
`EngineFleetState`); the fleet joint-put contribution's API shape
explicitly deferred to wave 6 (recorded, not silently absent).
- **The consolidation constructor vs ADR-009/011/012**: the
fleet-valid engine set completed; the implicitly-`fleet: false`
posture recorded verbatim (wave 6's declaration slots in without
reshaping); the connection-settings design point (two DSN+opts
pairs; cross-instance valid non-fleet) recorded.
- **Async/blocking discipline**: tokio-postgres natively async — no
`spawn_blocking` seam; no blocking I/O on the async path; the pool
is the concurrency posture; no `unwrap`/`expect` outside tests.
- **Named design points audited as resolved** (each recorded in its
task's Notes): the schema name + the consolidation shape's schema
sharing; the shared-helper home (quote_identifier, 42P01
discriminant, pg_err, timestamp helpers) + the `PgOpts` gate
question; the 512 KiB aggregation shape; the LO isolation +
janitor shape (amendment A2 verified — zero schema AND zero
`pg_largeobject` residue on the shared db); the sub-enum slotting
for the large cursor/staging bodies; the connection-settings shape;
the dormancy wiring; the orphan sweep's scope note.
- **Family conventions**: no comments in code (doc comments on public
API fine), thiserror, tokio-only async, no unwrap/expect outside
tests, naming, one-module-per-file re-export shape, the
`#![allow(dead_code)]` scope notes matching their remaining scope.
- **Gates green**: `cargo test` (default), `cargo test --features
pg-lo` (server-less: skipping), `cargo test --features "pg-lo,mem"`,
`cargo test --all-features` (against the server), the pg-lo pure
builds (`cargo check --no-default-features --features "pg-lo,mem"`
and `--features "postgres,pg-lo"` — the literal kv-less
`--features pg-lo` config is not a gate: with no kv engine the
facade's `KvEngine`/`KvCursor` go empty, E0004; see
`store-pg-lo-construction`), `cargo clippy --all-targets -- -D
warnings` (default + the pg-lo variants + `--all-features`),
`cargo fmt --check`, `cargo doc --no-deps`.
Findings are fixed inline where cheap, or recorded as wave-6
amendments where they shape the next decomposition (the fleet
mechanism's joint-tx driver already carries amendment A1; any pg-lo
contribution-shape finding lands beside it). The gate's completion is
what unblocks wave 6's decomposition.
## Acceptance Criteria
- [x] Every gate check above read and verified against the cited ADR
text (not from memory of it)
- [x] Named design points each decided, recorded, and consistent with
the specs
- [x] Findings fixed inline or recorded as wave-6 amendments with
owners
- [x] All gates re-run green after any fixes
- [x] Wave 6 decomposition unblocked (recorded in this task's Summary)
## References
- docs/plans/implementation.md (§Wave 5, §Review gates — engine wave
reviews)
- docs/architecture/decisions/009-pg-lo-large-tier-engine.md
- docs/architecture/decisions/010-backend-io-seams-and-fleet-state-home.md §1/§2
- docs/architecture/decisions/012-pre-decomposition-consistency-rulings.md §3/§4/§5/§6.7
- docs/architecture/decisions/013-family-composition-reactive-boundary-and-feature-graph.md §4
- docs/architecture/store-api.md
- docs/research/poc-pglo-findings.md (the evidence base the engine
claims)
- tasks/review-wave-4.md (the gate method; the structural twin's gate)
## Notes
> The gate read the four wave-5 commits against the pinned ADR text
> (ADR-009 §1–§6, ADR-010 §1/§2, ADR-012 §3/§4/§5/§6.5/§6.7, ADR-013
> §4, store-api.md, POC #7 findings C1–C7 — the documents, not memory)
> and re-ran every gate. The engine is conformant; **one finding,
> fixed inline**:
>
> - **PGLO-1 — `cargo doc --no-deps` was not clean (fixed).** Wave 5
> introduced four rustdoc warnings: the public `store` module doc's
> new intra-doc links resolve to crate-internal items
> (`AnyCursor`, `KvCursor`, `LargeCursor`, and the wave-5 store-core
> helper `ensure_gc_schema_at_construction` — the last two new this
> wave; the first two were prose in wave 4 and became bracketed
> links here), which rustdoc warns as private-item links from
> public documentation. Fixed by de-linking those names in the
> module doc (`src/store.rs`, doc-only) — the wave-4 gate's own
> rustdoc-hygiene fix was the precedent. Verified post-fix: `cargo
> doc --no-deps` zero warnings, clippy/fmt unaffected.
>
> Gate checks verified, item by item:
>
> - **Engine-vs-contract conformance** — the pg-lo column green
> against the harness server (re-run live this gate:
> `--all-features` 188 lib + 106 conformance + 4 git-interop ok;
> zero LO/schema/database residue after the run); the window-family
> clause bodies contract-tested per ADR-012 §5's pg-lo row (schema
> creates `gc_window` only with `gc_pins`'s absence asserted,
> stage idempotence/restage, the atomic `DELETE … RETURNING` take
> with the `<=` boundary, both virgin shapes); virgin-store
> semantics unit-tested incl. the schema-less form; `size`
> metadata-only from the companion row (EXPLAIN PK-index gate).
> - **Engine shape vs ADR-009 §1–§4** — the companion table is the
> contract authority (list/size/has/CAS all table-level; `pg_largeobject`
> read by the engine only inside the orphan sweep's candidate
> enumeration); `get` closes over the companion row, rides
> descriptorless `lo_get(oid, off, len)` windows, and the
> held-descriptor fallback is named not-shipped in the module doc
> with no code; put = one tx with CAS existence first (a re-put
> commits an empty tx, never `lo_create`) and the 512 KiB knee as
> [`crate::pg_lo::LOWRITE_CHUNK`] carrying the C2 citation; both
> hygiene forms exact-count tested (discard → zero pages/rows,
> fail-commit → self-discard, Drop cancellation → spawned
> ROLLBACK + zero residue); the 64-bit-variants discipline holds
> (no `lo_lseek` anywhere, offsets bigint only, window length
> within the int4 parameter domain, the u64 clamping arithmetic
> shared); delete = one tx with the Missing discipline; LO
> creation transactional (C6 zero-orphan — structurally, from the
> held tx).
> - **Posture deltas carried as requirements** — the module doc
> states the catalog-space-never-returned property with the
> `VACUUM FULL`/`pg_repack` operator line and
> `pg_total_relation_size('pg_largeobject')` monitoring, the
> autovacuum-inherited keep-it-on note, and the 20–50× single-stream
> cached-get capacity fact with the aggregate serving picture; the
> orphan-recovery sweep is scope-noted (no store-core verb this
> wave) and contract-tested with a planted orphan + byte-exact
> committed-content survival. The cached-get capacity facts named
> honestly, not hedged.
> - **One-window-host rule vs ADR-012 §5** — the store core's
> `ensure_gc_schema_at_construction` dispatch keys off the engine
> representation, never a flag (kv host on dual-SQL — the pg-lo
> schema carries no `gc_window`, contract-tested genuine absence
> on two distinct schemas; pg-lo host on kv = mem); the sweep's
> mem arm runs the durable form on the pg-lo host (generic-over-
> `EngineWindowState` delegation), inline otherwise; **nothing of
> `EngineFleetState` exists in `src/pg_lo.rs`** (grep-clean — the
> one mention is a doc sentence recording the ruling); the fleet
> joint-put contribution's API shape is explicitly deferred to wave
> 6 (recorded in `src/gc.rs`'s `EngineFleetState` clause doc and
> the engine task's scope boundary, not silently absent).
> - **Consolidation constructor vs ADR-009/011/012** — the fleet-valid
> engine set is complete (`dual_tier_postgres_pglo` landed; the
> module doc records the completion), the implicitly-`fleet: false`
> posture is recorded verbatim in the constructor doc (wave 6's
> declaration slots in without reshaping), and the connection-
> settings design point (two DSN+opts pairs; the consolidation
> corollary of one minted schema — both engines' table names are
> distinct) is recorded with it.
> - **Async/blocking discipline** — natively async throughout, no
> `spawn_blocking` seam, no blocking I/O on the async path; the
> pool is the concurrency posture; no `unwrap`/`expect` outside
> tests. The two deliberate `std::thread`+`block_on` bodies are
> best-effort cancellation/test teardown paths with their
> rationale recorded (the staging cursor's `Drop`, the
> `#[cfg(test)]` janitors).
> - **Named design points audited as resolved** (each in its task's
> Notes, consistent with the specs): the schema name +
> consolidation schema sharing (`pg_common::DEFAULT_SCHEMA`,
> distinct table names), the shared-helper home (`src/pg_common.rs`
> gated `any(postgres, pg-lo)`) + the `PgOpts` gate widening (one
> shared type, re-export gate widened; the `synchronous_commit`
> knob carries with ship default `on`), the 512 KiB aggregation
> shape, the LO isolation + janitor shape (amendment A2 verified —
> per-test dedicated databases + `DatabaseJanitor`, zero schema
> AND zero `pg_largeobject` residue on the shared db re-run by this
> gate), the sub-enum slotting (`LargeCursor`/`LargeStaging` behind
> `AnyCursor`/`AnyStaging`'s one large arm), the
> connection-settings shape, the dormancy wiring, and the orphan
> sweep's scope note.
> - **Family conventions** — clean: doc comments on public API, no
> inline comments (the one cfg-shim comment documents a non-obvious
> cfg constraint, the allowed case), thiserror, tokio-only async,
> no unwrap/expect outside tests, naming and one-module-per-file
> re-export shape held, the `#![allow(dead_code)]` notes matching
> their remaining scope (`reap_orphans` awaiting its wave-7+
> consumer — the postgres engine's twin posture).
>
> Verification, re-run by this gate (harness server live): `cargo
> test` 69/19/3 ok (default); `cargo test --features pg-lo` 92/19/3
> ok; `cargo test --features "pg-lo,mem"` 151/71/4 ok; `cargo test
> --all-features` 188/106/4 ok against the server; `cargo check` +
> clippy `-D warnings` green on `--no-default-features --features
> "pg-lo,mem"` and `--features "postgres,pg-lo"` (the pure builds;
> the literal kv-less config is not a gate, d69d9a3's recorded
> finding) and on default/`pg-lo`/`postgres`/all-features
> effectively via the sweep above; `cargo fmt --check` green; `cargo
> doc --no-deps` clean post-fix. No wave-6 amendments arise from
> this gate; amendment A1 (the joint-tx drop discipline) stands from
> the wave-4 gate.
## Summary
> Completed 2026-10-12 (wave 5). The engine-wave gate read the pg-lo
> engine, its window-family seam, the constructor wiring, and the
> suite column against the pinned contract line by line and found
> them conformant — every gate check verified against the cited ADR
> text: ADR-009 §1–§4's engine shape (companion-table authority,
> one-tx puts with the 512 KiB knee, descriptorless `lo_get` windows
> with the held-descriptor fallback named not-shipped, 64-bit
> discipline, one-tx deletes, transactional LO creation), both
> hygiene forms + Drop cancellation exact-count tested, §5/§6's
> posture deltas stated as requirements (VACUUM FULL operator line,
> autovacuum, the 20–50× cached-get capacity fact), ADR-012 §5's
> one-window-host rule completed in the store core (kv host on
> dual-SQL with contract-tested genuine pg-lo dormancy; pg-lo host on
> kv = mem with the durable sweep form; the dispatch keyed off the
> engine representation, never a flag; nothing of
> `EngineFleetState`; the fleet joint-put API shape explicitly
> deferred to wave 6), consolidation + mem-pglo constructors with
> the implicitly-`fleet: false` posture recorded verbatim, the LO-
> isolation (A2) verified zero-residue, and all named design points
> audited as decided and recorded. One finding fixed inline (PGLO-1:
> four wave-5-introduced rustdoc private-link warnings — the gate's
> `cargo doc` claim had silently regressed; de-linked the private
> names). All gates re-run green after the fix (test variants, the
> two pure builds, clippy across the pg-lo feature matrix, fmt, doc).
> No wave-6 amendments arise from this gate. **Wave 6 (fleet GC)
> decomposition is unblocked** — the fleet-valid engine set is
> complete, the joint-tx driver carries amendment A1 from the wave-4
> gate, and the constructors need only the declaration's predicate
> and parameter.