Files
alkblobs/tasks/review-wave-6.md
T
glm-5.3-flash e84a874715 review(store): the wave-6 fleet gate — every gate check green, four inline findings fixed
The wave-6 review gate (docs/plans/implementation.md §Review gates,
the fleet gate) read the landed implementation against the pinned
ADR text line by line: the exact-count fleet sweep outcomes vs live
postgres, the joint entry+pin tx atomicity, the sweep lease vs
ADR-013 §2, the composite fleet-validity predicate, kv-only put-time
rejection, the TTL/3 renewal lifecycle, the fleet liveness verb, the
one-window-host rule, and the non-fleet postures — all conformant,
the task-hash log matched, the wave-2..5 suites green untouched.

Fixed inline:

- the A1 termination discipline's two uncovered paths — the kv
  driver's pin-row expiry mint propagated between begin_joint_tx and
  pin_commit without terminating the held tx (the PG-2 hazard), and
  fleet_joint_publish could abandon an already-begun tx on its
  host/row paths; the drivers now resolve the row inside their
  caught drives and hand it precomputed to the publish tail
- a wave-6 pg-pure test-build clippy regression: the fleet test
  instruments' wildcard match arms went unreachable under
  --no-default-features (helpers now ride Store::fleet_host())
- the stale/missing allow(dead_code) scope notes: store.rs's landed-
  state paragraph (the fleet sweep "not yet driven" → landed),
  gc.rs's sharpened remainder, local/sqlite/backend notes corrected,
  the pg_lo/postgres allow-scope sentences added; a measure-then-
  note check across six feature shapes (no allow removed)
- a PGLO-1-class near-miss: the new notes de-linked the private
  items they name; cargo doc --no-deps zero warnings, the gated
  build's pre-existing count 32 → 31 (nothing added)

Verification (tests live against pglo-poc :15432): cargo test (73/
19/3 default; 131/52/3 postgres; 167/73/3 postgres+pg-lo; 226/125/4
all-features), the pg-pure builds, clippy --all-targets -D warnings
on all seven feature variants, fmt --check, doc clean, shared-db
schema residue 0. Wave 7 (the ops surface) decomposition unblocked.
2026-10-12 17:39:43 +00:00

19 KiB

id, name, status, depends_on, scope, risk, impact, level, tags
id name status depends_on scope risk impact level tags
review-wave-6 Wave 6 review gate — the fleet gate completed
suite-column-fleet
narrow low phase review
wave-6
review

Description

The wave-6 review gate — the fleet gate (docs/plans/implementation.md §Review gates: "exact-count sweep outcomes under concurrency vs live postgres, the joint entry+pin tx atomicity, the sweep lease semantics vs ADR-013 §2, the composite fleet-validity predicate enforced at the constructor, kv-only put-time rejection"), before wave 7 decomposes. The gate reads the implementation against the pinned ADR text line by line (the wave-1..5 gates' method) — the documents, not memory.

Gate checks:

  • Exact-count fleet sweep outcomes under concurrency vs live postgres: the fleet column green against the harness server (server-less runs skip cleanly — a skip never substitutes for acceptance); the two-instance survival shape, the lease-contention abort, the cross-instance arbitration refusal, the race across the window delay, and the maintenance-step reaping all exact-count asserted (INV-4's engine-gated fleet form).
  • The joint entry+pin tx atomicity: through the public put (not only engine-level) — an independent connection never observes an entry without its pin row or the reverse; the A1 drop discipline audited as implemented (every path from begin_joint_tx onward terminates the tx — the wave-4 gate's amendment closed, its owner discharged); the pg-lo consolidation one-tx form (LO writes + companion row + pin row + commit in one tx; zero residue on failure); the large=local pin-first/publish-second ordering (the reverse ordering nowhere coded).
  • The sweep lease semantics vs ADR-013 §2: one sweeper per pool across instances; atomic test-and-set; holdership ends at release/owner death/session loss; contention is the GcAbortCause::SweeperLock report abort (Ok(SweepReport), nothing deleted — ADR-012 §1), never an error.
  • The composite fleet-validity predicate enforced at the constructor: every fleet-valid configuration constructs; every non-fleet-valid configuration is a constructor error (kv ≠ postgres, mem anywhere, local without the shared-media declaration, pg-lo cross-instance); the declaration is explicit, never inferred (ADR-012 §3); the same-instance probe's design audited (a failed probe errors closed).
  • kv-only put-time rejection under the re-routing posture (ADR-012 §6.2's machinery, fleet edition).
  • The TTL/3 renewal on the guard: the renewal lifecycle audited (no leaked tasks; drop/conversion/batch-contribution stops renewal; a failed renewal never resurrects an expired row — ADR-012 §2's expiry semantics verbatim); the TTL is a fleet constructor parameter (default 60 s), never API.
  • The fleet liveness verb vs ADR-012 §6.6 / ADR-008 §2: the named table reference form; the schema-ownership rule (the store reads the embedder's table, never owns it); the protect callback's single-node-only posture recorded; the two-domain arbitration composition (in-process + SQL) decided and recorded.
  • The one-window-host rule under fleet: every fleet-valid configuration's window hosts on the kv engine; the pg-lo window clauses dormant; the form branch keys off the engine representation, never a flag.
  • The non-fleet postures unchanged: the in-process protocol verbatim under fleet: false regardless of engine — the wave-2/3/4/5 suites green untouched.
  • Code-smell / hygiene sweep (the gate's standing hygiene block — the twice-bitten lesson is now an explicit check, not a hope):
    • cargo doc --no-deps zero warnings — the PGLO-1 class (public-module doc links resolving to crate-internal items) has bitten waves 4 and 5; the gate runs rustdoc and asserts clean, and de-links rather than exports.
    • The #![allow(dead_code)] scope notes match their remaining scope — the fleet family's note in src/gc.rs (its consumers land this wave) must shrink to its true remainder or vanish; the postgres/pg-lo notes likewise audited.
    • Stale forward references updated — every "wave 6" note in the module docs (store.rs's fleet-declaration paragraph, the constructors' "slots in without reshaping" recordings, pg_lo.rs's scope boundary, postgres.rs's scope note, the batch-delete helper's consumer note) reads the landed state.
    • Family conventions: no inline 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, no blocking I/O on the async path.
    • Task-description correctness: each wave-6 task's Summary matches what actually landed (the gate reads the diffs against the task texts, not the Notes' claims alone).
  • Gates green: cargo test (default), cargo test --features postgres (server-less: skipping), cargo test --features "postgres,pg-lo", cargo test --all-features (against the server), the pure builds (cargo check --no-default-features --features postgres and --features "postgres,pg-lo"), cargo clippy --all-targets -- -D warnings (default + the postgres/pg-lo variants + --all-features), cargo fmt --check, cargo doc --no-deps.

Findings are fixed inline where cheap, or recorded as wave-7 amendments where they shape the next decomposition (the ops wave's pin-token contract rides the fleet machinery — a renewal-surface finding lands beside it). The gate's completion is what unblocks wave 7's decomposition.

Acceptance Criteria

  • Every gate check above read and verified against the cited ADR text (not from memory of it)
  • Named design points each decided, recorded, and consistent with the specs
  • Findings fixed inline or recorded as wave-7 amendments with owners
  • All gates re-run green after any fixes — including cargo doc --no-deps explicitly (the PGLO-1 class)
  • Wave 7 decomposition unblocked (recorded in this task's Summary)

References

  • docs/plans/implementation.md (§Wave 6, §Review gates — the fleet gate)
  • docs/architecture/decisions/008-trait-size-probe-fleet-gc-and-large-engines.md §2/§3
  • docs/architecture/decisions/010-backend-io-seams-and-fleet-state-home.md §2/§4
  • docs/architecture/decisions/012-pre-decomposition-consistency-rulings.md §1–§6
  • docs/architecture/decisions/013-family-composition-reactive-boundary-and-feature-graph.md §2
  • docs/architecture/store-api.md (§Invariants 4 — the fleet form)
  • docs/architecture/backends-and-dispatch.md (the composite fleet-validity rule)
  • tasks/review-wave-4.md, tasks/review-wave-5.md (the gate method; the amendments A1/A2 this gate audits closed)
  • tasks/store-fleet-construction.md, tasks/store-fleet-put.md, tasks/store-fleet-sweep.md, tasks/engine-pg-lo-joint.md, tasks/suite-column-fleet.md (the wave's tasks)

Notes

Gate completed 2026-10-12, the wave-1..5 method: every gate check read against the pinned text (ADR-008 §2/§3, ADR-010 §2, ADR-012 §1–§6, ADR-013 §2, store-api.md §Invariants 4's engine-gated fleet form, backends-and-dispatch.md's composite fleet-validity rule, and the engine-state seam trait in src/gc.rs), then verified against the landed diffs (b6b3532 → 53b85dd; the operator's hash log matched git log exactly) and re-run gates. The task hashes were confirmed: store-fleet-construction b6b3532, engine-pg-lo-joint 76be7b0, store-fleet-put 950af9a, store-fleet-sweep 3a51bb4, suite-column-fleet 53b85dd.

Gate checks, each verdict:

  • Exact-count fleet sweep outcomes vs live postgres — conformant. The fleet column green against the harness server (pglo-poc, :15432; a skip never substituted — the suite ran live): the two-instance exact-count shape (b marks all three, stages exactly 3, deletes exactly the two unpinned twins, cancels exactly the pinned entry via A's un-expired row; the byte-identical survivor read back from the other instance), the lease-contention abort as report data with nothing staged/deleted, the cross-instance arbitration refusal until expiry, the race across the window delay, the maintenance step's exact reap, the embedder-table liveness row with the schema-ownership rule, and the kv-only re-routing row — every row ADR-stamped; 16 stamps counted in the column file.
  • Joint entry+pin tx atomicity — conformant through the public put (the both-or-neither row asserts over an independent connection), with two A1 termination-path findings fixed inline (below). The pg-lo consolidation one-tx form verified structurally (put_joint_staged borrows the held PgJointTx checkout it never owns; no Drop, no COMMIT/ROLLBACK on any path — transactional LO creation makes the pages die with the driver's termination) and live (the byte-exact consolidation round-trip row). The large = local ordering is pin-first/publish-second in code (fleet_staged_commit: row-only joint tx, then commit-rename), with the reverse ordering nowhere coded.
  • Sweep lease vs ADR-013 §2 — conformant: atomic test-and-set (pg_try_advisory_lock, session-scoped), one sweeper per pool across instances (the in-process flag composes — both domains, either domain's contention aborting as SweeperLock report data with nothing deleted), holdership ends at release / owner death / session loss (in-instance reaping of dead checkouts — the wave-4 PG-1 fix present), and the pool-sizing composition enforced at every _fleet constructor's entry (max_size >= 2).
  • Composite fleet-validity predicate at the constructor — conformant: the one-sentence predicate as code (fleet_validity_error over engine-representation-derived shapes, never a flag), the structural clauses enforced by the constructor set's shape with the predicate's rejection arms unit-tested per clause, the pg-lo same-instance probe design recorded and implemented (pg_control_system().system_identifier compared across one connection per engine; a mismatch or any probe failure errors closed), the declaration explicit and never inferred (a sealed FleetSharedMedia named type plus the _fleet twin constructors; the pre-existing constructors byte-unchanged, implicitly fleet: false), the TTL a fleet constructor parameter (zero rejected at entry before any I/O).
  • kv-only put-time rejection — conformant: ADR-012 §6.2's machinery unchanged under fleet (known-length rejects at entry, unknown-length at mid-stream threshold overflow; the fleet column's re-routing row green).
  • The TTL/3 renewal on the guard — conformant: per-guard tokio task on the TTL/3 cadence (the 1 ms floor named), spawned at the row's durability, aborted at every guard-life boundary (drop, Batch::add moving the duty into the batch, the ordered-step conversion's pre-stop), silent on Err, ended by the never- resurrect Ok(false) (pin_renew's expiry > now predicate — live-tested); no leaked tasks; the TTL never API.
  • Fleet liveness verb vs ADR-012 §6.6 / ADR-008 §2 — conformant: the same verb with the fleet-shaped LivenessRegistration argument (the named table reference form; the verb fallible with the error surface decided and recorded; in-process sources allow-and-document — instance-local protection); the schema-ownership rule holds (the engine is handed a reference, never creates the table — live-asserted); the protect callback's single-node-only posture recorded in the verb docs; the two-domain arbitration composition decided and recorded (in-process first, SQL second, implemented once at arbitrated_delete, shared by the direct path and window execution).
  • One-window-host rule under fleet — conformant: every fleet-valid configuration ensures both GC tables on the kv host; the pg-lo window clauses dormant (no gc_window in the pg-lo schema — constructor-tested); the form branch keys off the engine representation (the sweep_window match), never a flag.
  • Non-fleet postures unchanged — conformant: the in-process protocol verbatim under fleet: false; the wave-2/3/4/5 suites green untouched alongside the fleet additions.
  • Hygiene sweep — findings fixed inline (below); cargo doc --no-deps zero warnings (the new allow-scope notes initially linked private items — PGLO-1's shape — and were de-linked); the #![allow(dead_code)] scope notes audited against a measured remainder (allow-stripped cargo check across the default, postgres, sqlite-only, mem, postgres+pg-lo, and all-features shapes) and corrected where stale.
  • Task-description correctness — the diffs read against the five task texts; the Summaries match what landed, with the one finding (the A1 coverage gap, below) fixed inline rather than amending the task texts.

Findings fixed inline:

  • W6-1 — two A1 termination paths were uncovered (fixed). A1's discipline (catch-propagate-terminate: every path from begin_joint_tx onward terminates the held tx before propagating) was not complete: fleet_put_kv's pin-row expiry mint propagated with ? between begin_joint_tx and pin_commit without terminating (the exact PG-2 dirty-session hazard A1 exists for), and fleet_joint_publish — invoked with an already- begun tx — propagated on its host-None and row-mint paths without termination. Fixed: the kv driver terminates the tx on the row-mint error; the pg-lo drivers resolve the pin row inside their caught drives and hand the precomputed host + row to fleet_joint_publish, whose only fallible step left is the terminal pin_commit (clause-owned rollback). The A1 design-point doc records the row-mint path; fleet_joint_publish's doc ordering corrected (the code mints the in-process refcount after pin_commit — the row is the publish-time protection, the refcount the instance-local bookkeeping; the invariant is row- carried, so the ordering is safe as written).
  • W6-2 — the pg-pure test builds failed clippy --all-targets (fixed). --no-default-features --features postgres[,pg-lo] with tests: the wave-6 test instruments' _ => panic! match arms went unreachable-pattern (single-variant KvEngine) and a let-else was irrefutable — a wave-6 regression invisible to the gate lists (those run only cargo check for the pure builds, and the clippy variants that are listed are default/postgres/all-features, which passed). Fixed: the test helpers ride Store::fleet_host()'s expect instead of matching the engine enum (in-crate private access, cfg-exact). All seven clippy feature variants now green, the four pure shapes among them.
  • W6-3 — stale/missing allow(dead_code) scope notes (fixed). store.rs's module-doc paragraph still said the fleet sweep was "not yet driven" (landed 3a51bb4) — rewritten to the landed state plus the allow's true remainder; local.rs's note still pointed at wave 3 ("until wave 3's facade constructors... name them") — corrected to its true remainder (the cfg(test) commit-failure injection knob behind feature mem; an allow-stripped check confirmed the lib bodies live); sqlite.rs's note misclaimed the remainder (its real residue is the test-instrument nanos decode) — corrected; backend.rs's "the reporting and fleet waves consume" forward reference → the landed reading (Backend::name, test-consumed today); gc.rs's note sharpened to name the true remainder (pin_check deliberately unconsumed — wave 7's ops renewal probe; convert/pin_count test-consumed today); the postgres.rs and pg_lo.rs notes gained their missing allow-scope sentences (the batch-delete helper, system_identifier, reap_orphans, the feature-subset shapes). No allow was removed: every file still carries real dead scope.
  • W6-4 — harness schema residue from a stale parallel run (not a code finding). Three alkblobs_fleet_* schemas belonged to earlier battery pids (their teardown raced a parallel run), not to the suite as landed: a fresh full conformance run left zero new schemas (A2's janitor discipline holds); the stale three were dropped manually — residue 0.

Verification (post-fixes; tests live against pglo-poc :15432 unless noted): cargo test 73/19/3 ok (default); cargo test --features postgres 131/52/3 ok; cargo test --features postgres,pg-lo 167/73/3 ok; cargo test --all-features 226/125/4 ok; pg-pure test-builds green (--no-default-features --features postgres / postgres,pg-lo; the suite skips cleanly server-less); cargo check --no-default-features --features postgres and --features postgres,pg-lo green (the pure builds); clippy --all-targets -D warnings green on all seven feature variants (default, mem, postgres, postgres+pg-lo(+mem), all-features, and the pg-pure builds); cargo fmt --check green; cargo doc --no-deps zero warnings (the gated doc build's pre-existing count 32 → 31 — nothing added; verified against the wave-5 base 93f9a93's identical-pre-existing class); shared-db schema residue 0.

Summary

Completed 2026-10-12 (wave 6). The fleet gate read the landed wave-6 implementation against the pinned ADR text line by line and found it conformant on every check: the exact-count fleet sweep outcomes green against live postgres (two-instance survival with exact counts, lease contention as report data, cross-instance arbitration, the race across the delay, the exact-set reap, the embedder-table liveness verb with its schema-ownership rule, the kv-only re-routing row), the joint entry+pin tx atomicity through the public put (both-or-neither over an independent connection; the pg-lo consolidation one-tx form; the local pin-first ordering), the sweep lease's ADR-013 §2 semantics with the pool-sizing guard, the composite fleet-validity predicate enforced at the constructor with the errors-closed same-instance probe, kv-only put-time rejection, the TTL/3 renewal lifecycle on the guard, the fleet liveness verb's named-table form, the one-window-host rule, and the non-fleet postures byte-unchanged. Four findings fixed inline: two uncovered A1 termination paths (the pin-row expiry mint's ? in the kv driver; fleet_joint_publish's host/row propagation now resolved pre- or terminal), a wave-6 pg-pure test-build clippy regression (unreachable patterns — helpers now ride fleet_host()), and the stale/missing allow-scope notes (five files' notes corrected against a measured remainder; a stale "fleet sweep not yet driven" paragraph rewritten to landed state). All gates re-run green after the fixes — test suites live, the seven clippy variants, fmt, and cargo doc --no-deps zero warnings. The operator's task-hash log matched git log. Wave 7 (the ops surface) decomposition is unblocked; its review gate is the ops-vs-alkcall conformance shape.