- store-fleet-construction: the fleet: true declaration slotting into the fleet-capable constructors (the recorded non-event), the composite fleet-validity predicate enforced at the constructor (kv=postgres AND pg-lo-same-instance OR local-on-declared-shared- media OR kv-only re-routing), the TTL/owner-id fleet state, the same-instance probe design point - engine-pg-lo-joint: the pg-lo joint contribution — staged-put mechanics (512 KiB knee, CAS, transactional LO creation) into the store-held PgJointTx, the wave-5 deferred API-shape design point - store-fleet-put: the joint entry+pin tx driver (amendment A1's drop discipline lands here — its recorded owner), the pin guard's TTL/3 renewal form, the dedup upsert-renewal, pin-first/ publish-second for large=local, the consolidation one-tx put - store-fleet-sweep: the SQL sweep lease (ADR-013 §2 semantics), SQL-level delete arbitration on the direct + window-execution paths, the expired-pin reaping clause (the seam as the named home for fleet-clause growth), the fleet liveness registration verb, the two-domain arbitration composition - suite-column-fleet: the fleet column — two-instance factories over one schema, the exact-count fleet sweep rows (the wave's gate), lease contention, cross-instance arbitration, TTL/renewal rows, the fleet-validity predicate rows - review-wave-6: the fleet gate per the plan, plus a standing code-smell/hygiene block — cargo doc --no-deps asserted clean (the twice-bitten PGLO-1 rustdoc private-link class), the allow(dead_code) scope notes audited against their remainder, stale wave-6 forward references, and task-Summary-vs-diff correctness Harness server cited in every server-touching task: dockerized pglo-poc (postgres:16-alpine) on :15432, db blobs, postgres/poc (verified live 2026-10-12); env-driven ALKBLOBS_PG_* settings, clean server-less skips, acceptance requires green against the server. Dependency graph validated: two parallel roots (construction, pg-lo joint), put merging them, sweep parallel to put, the fleet column merging, the review gate last; no cycles.
180 lines
9.6 KiB
Markdown
180 lines
9.6 KiB
Markdown
---
|
|
id: store-fleet-construction
|
|
name: the fleet declaration — the composite fleet-validity predicate at the constructor
|
|
status: pending
|
|
depends_on: []
|
|
scope: moderate
|
|
risk: medium
|
|
impact: component
|
|
level: implementation
|
|
tags: [wave-6, store, construction, fleet]
|
|
---
|
|
|
|
## Description
|
|
|
|
Slot the **`fleet: true` constructor declaration** into the
|
|
fleet-capable constructors (ADR-012 §3; the recorded non-event the
|
|
wave-4/5 constructor tasks pinned: "the `fleet: true` declaration is
|
|
wave 6, slotting in without reshaping") — the composite
|
|
fleet-validity predicate enforced at the constructor, the fleet
|
|
constructor parameters, and the store's fleet state. Nothing here
|
|
turns the fleet *mechanism* on (the joint-tx put driver is
|
|
`store-fleet-put`, the fleet sweep is `store-fleet-sweep`); this task
|
|
is the admission gate and the state those tasks consume.
|
|
|
|
- **The declaration is explicit, never inferred** (ADR-012 §3): a
|
|
store instance is constructed with fleet mode on or off. Under
|
|
`fleet: false` (every existing constructor's implicit posture,
|
|
unchanged): the ADR-005 in-process protocol verbatim regardless of
|
|
engine. Under `fleet: true`: the composite fleet-validity predicate
|
|
is enforced at construction, and the fleet machinery activates (the
|
|
later tasks' wiring).
|
|
- **The composite fleet-validity predicate** (backends-and-dispatch.md
|
|
"The composite fleet-validity rule", one sentence, both tiers): a
|
|
configuration is fleet-valid iff **kv = postgres AND (large = pg-lo
|
|
on the same pg instance as the kv engine OR large = local on
|
|
declared shared media OR large = none with the re-routing posture
|
|
carrying pool large content)** — plus the explicit `fleet: true`
|
|
declaration. `fleet: true` is a **constructor error** for every
|
|
non-fleet-valid configuration (ADR-012 §3): any kv engine other than
|
|
postgres, `mem` anywhere, `local` without the shared-media
|
|
declaration, `pg-lo` on a different pg instance than the kv engine.
|
|
The predicate is enforced where the enforceable seam is — the
|
|
constructor sees only its own node; cross-node truth (is the
|
|
declared shared media actually shared? is the undeclared instance
|
|
sharing our pool?) is the deployment's verified invariant
|
|
(ADR-008 §3's seam; ADR-012 §3's misconfiguration reading — the
|
|
detection symptom documented, not constructor-provable).
|
|
- **The fleet constructor parameters** (ADR-008 §2: "fleet constructor
|
|
parameters, not API"):
|
|
- **The pin TTL** — default 60 s (`DEFAULT_PIN_TTL_SECS`, already a
|
|
postgres backend field awaiting exactly this wiring — the wave-4
|
|
note), constructor-tunable. The store owns the TTL and the TTL/3
|
|
renewal cadence; the engine's `pin_renew` successor-time body
|
|
reads the TTL it was constructed with (the wave-4 recorded design
|
|
point: "constructor-tunable when wave 6's fleet constructor
|
|
lands").
|
|
- **The large-tier declaration** for `large = local` under fleet —
|
|
the operator's explicit shared-media assertion (ADR-008 §3's
|
|
enforceable-seam bullet: a fleet-mode constructor requires an
|
|
explicit large-tier declaration — `local` with the assertion,
|
|
routed (kv-only), or `pg-lo`). **Named design point — the
|
|
declaration's type shape**: how the assertion rides the
|
|
constructor signature (a dedicated declaration type the caller
|
|
must name — e.g. a fleet-opts shape carrying the shared-media
|
|
assertion — versus a bare flag) — decide consistent with ADR-008
|
|
§3's "explicit declaration" wording (a named type the caller
|
|
cannot construct accidentally is the reading the ADR's
|
|
enforceable-seam posture supports) and record it.
|
|
- **kv-only re-routing posture**: `kv_only_postgres` under
|
|
`fleet: true` is valid (large = none; the re-routing posture
|
|
carries pool large content via the ops surface — wave 7; the
|
|
client-node shape is this constructor plus that composition,
|
|
ADR-008 §3). The over-threshold put-time rejection (ADR-012 §6.2,
|
|
already landed) is unchanged under fleet.
|
|
- **The pg-lo same-instance clause** (ADR-012 §4 — the checkable
|
|
clause that makes the joint entry+pin tx expressible): under
|
|
`fleet: true`, `dual_tier_postgres_pglo`'s two DSN+opts pairs must
|
|
resolve to the **same pg instance**. Cross-instance is valid only
|
|
as `fleet: false`. **Named design point — the same-instance
|
|
probe**: textual DSN comparison is insufficient (aliases, IP vs
|
|
hostname); decide the server-side check (the instance's
|
|
`system_identifier` via `pg_control_system()` — PG14+ — compared
|
|
across one connection per engine, is the natural shape; the
|
|
harness server's PG 16.15 carries it) and record it. A mismatch is
|
|
the constructor error.
|
|
- **The store's fleet state** — what the Store carries once declared:
|
|
the fleet flag (the put/sweep paths branch on it — never on
|
|
re-deriving from the engine set), the pin TTL, and the
|
|
**store-instance id** (`owner` — ADR-011's vocabulary; the pin
|
|
row's identity half). **Named design point — the owner id's
|
|
minting**: the instance id's generation (random bytes at
|
|
construction is the natural shape — unique per instance, stable
|
|
for the instance's life, carried as the `owner` bytes of every
|
|
`PinRow` the store mints) and its width/encoding; record it. The
|
|
id is crate-internal (never public API — ADR-008: fleet parameters,
|
|
not API).
|
|
- **The one-window-host rule under fleet** — verify the landed
|
|
posture composes: every fleet-valid configuration has kv = postgres
|
|
(SQL-backed), so the durable window hosts on the kv engine and the
|
|
pg-lo window clauses stay dormant (the landed consolidation shape
|
|
already carries no `gc_window` in the pg-lo schema). The predicate's
|
|
enforcement must not disturb the form branch (it keys off the
|
|
engine representation, never a flag).
|
|
- **Constructor docs updated** — the "implicitly `fleet: false`" /
|
|
"wave 6 slots in without reshaping" recordings in the postgres
|
|
constructors' docs (and the store.rs module doc's fleet-declaration
|
|
paragraph) updated to the landed state.
|
|
- **Constructor unit tests** (env-driven, skipping cleanly
|
|
server-less): every fleet-valid configuration constructs (pg-lo
|
|
same-instance, local + shared-media declaration, kv-only re-routing)
|
|
and introspects its fleet state (flag, TTL, owner id); every
|
|
non-fleet-valid configuration errors (`mem` anywhere, sqlite,
|
|
`local` without the declaration, pg-lo cross-instance — two
|
|
distinct schemas on the harness server are the same instance, so
|
|
the cross-instance negative needs two DSNs that resolve to
|
|
different instances; if the dev environment has only one, the
|
|
negative is exercised by pointing one DSN at a non-existent
|
|
instance and asserting the probe errors closed — a probe failure is
|
|
a constructor error, never a silent pass); `fleet: false` postures
|
|
unchanged (the existing constructor tests stay green). **Tests need
|
|
a live server** — the alkstore harness convention: env-driven
|
|
(`ALKBLOBS_PG_*`), skip cleanly server-less, acceptance requires
|
|
green against the harness server (`pglo-poc`, :15432, db `blobs`,
|
|
`postgres`/`poc` — verified live 2026-10-12).
|
|
|
|
## Acceptance Criteria
|
|
|
|
- [ ] The fleet declaration slots into the fleet-capable constructors
|
|
without reshaping them (the recorded non-event lands as
|
|
recorded); `fleet: false` postures byte-unchanged in behavior
|
|
- [ ] The composite fleet-validity predicate enforced at the
|
|
constructor: every fleet-valid configuration constructs; every
|
|
non-fleet-valid configuration is a constructor error (unit-
|
|
tested per clause: kv≠postgres, mem anywhere, local without the
|
|
shared-media declaration, pg-lo cross-instance)
|
|
- [ ] The pg-lo same-instance probe decided and recorded; a mismatch
|
|
or a failed probe is a constructor error (never a silent pass)
|
|
- [ ] The pin TTL is a fleet constructor parameter (default 60 s)
|
|
wired to the engine's renewal body; the shared-media
|
|
declaration's type shape decided and recorded
|
|
- [ ] The store carries its fleet state (flag, TTL, owner id); the
|
|
owner id's minting decided and recorded (crate-internal)
|
|
- [ ] The one-window-host posture verified intact under fleet-valid
|
|
configurations; the form branch still keys off the engine
|
|
representation
|
|
- [ ] Constructor docs updated to the landed state (the wave-6
|
|
forward references resolved)
|
|
- [ ] `cargo test` (default) green; `cargo test --features postgres`
|
|
green server-less (skipping) and against the harness server at
|
|
acceptance; `cargo clippy --all-targets -- -D warnings` and
|
|
`cargo fmt --check` green (default + `--features postgres`);
|
|
`cargo doc --no-deps` clean
|
|
|
|
## References
|
|
|
|
- src/store.rs (the constructors and their recorded non-fleet
|
|
postures; the module doc's fleet-declaration paragraph)
|
|
- docs/architecture/backends-and-dispatch.md ("The composite
|
|
fleet-validity rule" — the one-sentence predicate)
|
|
- docs/architecture/decisions/012-pre-decomposition-consistency-rulings.md
|
|
§3 (the declaration, never inferred; the constructor-error set), §4
|
|
(the GC-state host; the pg-lo same-instance clause; the
|
|
pin-first/publish-second ordering this task's declaration admits)
|
|
- docs/architecture/decisions/008-trait-size-probe-fleet-gc-and-large-engines.md
|
|
§2 (the TTL, fleet constructor parameters), §3 (the enforceable
|
|
seam; the explicit large-tier declarations)
|
|
- docs/architecture/decisions/011-vocabulary-tiers-engines-and-fleet-state.md
|
|
§4 (the constructor table)
|
|
- src/postgres.rs (`DEFAULT_PIN_TTL_SECS` — the wave-4 note awaiting
|
|
this wiring)
|
|
- tasks/store-postgres-construction.md, tasks/store-pg-lo-construction.md
|
|
(the recorded slotting-in postures this task lands)
|
|
|
|
## Notes
|
|
|
|
> To be filled by implementation agent
|
|
|
|
## Summary
|
|
|
|
> To be filled on completion |