Commit Graph
24 Commits
Author SHA1 Message Date
glm-5.3-flash c8fc519978 feat(gc): the pg-lo engine-state window family — the conditional window host (wave 5)
- impl EngineWindowState on PgLoBackend: ensure_gc_schema creates
  gc_window only (never gc_pins, never the embedder's liveness
  table), window_stage upserts idempotent per (key, deadline),
  window_take is the one atomic DELETE ... RETURNING step over the
  <= boundary with the 42P01 -> empty virgin-take split
- nothing of EngineFleetState exists on this engine (ADR-012 §5's
  pg-lo row: fleet pins live on the kv host, sweep lock no); the
  one-window-host dormancy posture is recorded in the impl doc
- five contract tests mirror the postgres/sqlite suites (schema-only
  + row shape, stage idempotence/restage, take-exact-set/never-twice,
  the <= boundary with nanosecond slack, both virgin shapes);
  env-driven, skipping cleanly server-less, green live against the
  harness server

Verification: cargo test (default + --features pg-lo, server-less
and live), clippy -D warnings (default, pg-lo, + the pure builds
"pg-lo,mem" and "postgres,pg-lo"), cargo fmt --check, cargo doc --no-deps
2026-10-12 07:40:59 +00:00
glm-5.3-flash d69d9a345b feat(pg-lo): the large-tier engine — LOs + companion table behind the Backend trait (wave 5)
Implement the pg-lo engine (ADR-009, POC #7 C1-C7) in src/pg_lo.rs
behind feature pg-lo (default-off), plus the shared-helper home the
task's design points resolve into src/pg_common.rs.

- Engine: seven Backend methods + put_staged; the lo_entries companion
  table is the contract authority (list/size/has/CAS table-level;
  pg_largeobject read only by the orphan sweep's candidate enumeration);
  one-tx puts with 512 KiB lowrite statements (LOWRITE_CHUNK, the C2
  knee), the descriptorless lo_get window cursor (READ_CHUNK; EOF
  clamping + the unexpected-EOF clean failure), the held-tx staging
  cursor aggregating 64 KiB windows, one-tx deletes, the complete
  single-snapshot list, the 42P01 read-only virgin-store split, and the
  crate-internal reap_orphans (scope-noted, planted-orphan contract
  test). Posture deltas in the module doc (catalog space never
  returned / VACUUM FULL runbook line / autovacuum inherited / the
  cached-get capacity facts). Nothing of EngineFleetState; the window
  family remains engine-pg-lo-window.
- Shared helpers (pg_err, 42P01, quote_identifier, size clamp, i64-nanos
  encoding, build_pool, PgOpts, test janitors) move to src/pg_common.rs
  gated cfg(any(postgres, pg-lo)); PgOpts's public re-export widens
  (definition moved; crate::postgres::PgOpts path held by re-export);
  src/postgres.rs's changes are mechanical swaps.
- LO isolation (C7 lesson): per-test dedicated databases + DatabaseJanitor
  (WITH (FORCE)); zero LO/schema/database residue on the shared harness
  db (pre-existing public.lo_entries exploration residue found and
  removed).
- 18 in-module tests, env-driven (ALKBLOBS_PG_*), skipping cleanly
  server-less; all green against the pglo-poc harness server.

Verified: cargo test (69/19/3), --features pg-lo live (87/19/3, 18/18
pg-lo), --features postgres live (103/36/3), --all-features (176/71/4);
clippy -D warnings green for default, pg-lo, postgres, all-features,
--no-default-features --features "pg-lo,mem" and "postgres,pg-lo";
cargo fmt --check; cargo doc --no-deps.
2026-10-12 07:31:46 +00:00
glm-5.3-flash f195759989 fix(postgres): the wave-4 review gate's inline findings
- PG-1: sweep_lock_acquire reaps a lease whose held session died
  (in-instance session-loss reaping, ADR-013 §2) — previously the
  mutex answered Ok(false) until an explicit release; new test
  terminates the lease's own backend via pg_terminate_backend and
  re-acquires without a release
- PG-3: the engine-level pg tests now drop their per-test schemas
  (test_support::SchemaJanitor, the Harness deref-guard wrapper in
  src/postgres.rs's tests, fresh_opts carrying a janitor in the
  construction tests) — 380 leaked abt_* schemas on the shared
  harness db are 0 after every run now
- PG-2: PgJointTx's doc records the mid-flight-drop hazard (deadpool
  Fast recycle never resets transaction state; the clause bodies'
  failure paths all ROLLBACK — the store core's joint-tx driver owes
  pin_commit on every path from begin_joint_tx; wave 6 amendment)

Verification: cargo test (69/19/3), --features mem (124/54/4),
--features postgres vs server (103/36/3, 51 clean skips server-less),
--all-features vs server (158/71/4), pg-pure (76/19/3);
clippy -D warnings green (default/postgres/all-features/pg-pure);
fmt --check green; shared-db schema residue 0; cargo doc clean
2026-10-12 07:06:16 +00:00
glm-5.3-flash 67b927b13c 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.
2026-10-12 06:34:36 +00:00
glm-5.3-flash 29209fe53f feat(gc): the postgres engine-state clause families — the fleet host's full seam (wave 4)
- EngineWindowState: the both-tables ensure_gc_schema (gc_pins with the
  (key, owner) identity + gc_window), idempotent window_stage (the
  upsert discipline per (key, deadline)), and window_take as one atomic
  DELETE ... RETURNING with the <= boundary
- EngineFleetState: PgJointTx (the pooled checkout carrying a
  session-level BEGIN), joint_put (the CAS clause inside the held tx),
  pin_commit (pin-row upsert-renewals + commit, rollback-on-failure =>
  zero residue), pin_renew (expiry = now + DEFAULT_PIN_TTL, never
  resurrects), pin_check (the two-variant classification), arbitrate
  (the FOR UPDATE finger-lock folding pins + registered liveness-table
  references), and the engine-side register_liveness_source home
- The sweep lease: the session-scoped pg advisory lock with the
  namespaced FNV lock key and the same-connection acquire/release
  holding discipline (the lease's checkout stored until release)
- 13 contract tests (28 postgres tests total), env-driven, skipping
  cleanly server-less; verified green against the live pglo-poc
  harness server; clippy/fmt green default + --features postgres

Verification: cargo test (69/19/3 ok), cargo test --features postgres
server-less (97 ok, 28 skips) and live (97 ok), cargo test
--all-features (152/54/4 ok), cargo clippy -D warnings (both configs),
cargo fmt --check, cargo doc --no-deps.
2026-10-12 06:26:23 +00:00
glm-5.3-flash 1efc46f953 feat(engines): the postgres kv engine — the fleet host's first engine (wave 4)
The 'postgres' kv-tier engine (ADR-007, feature 'postgres', default-off)
against the wave-1 trait: the sqlite engine's structural twin on a
Pooled-Postgres driver cluster.

- One engine-owned schema (default 'alkblobs'; quoted-identifier
  boundary via the alkstore quote_identifier pattern) holding the B5
  row shape — key bytea PK / value bytea NOT NULL / size bigint NOT
  NULL, WITH (fillfactor = 90) — idempotently bootstrapped at
  construction; autovacuum and the ~40x small-tier storage overhead
  recorded as posture, not silence
- deadpool pool with DEFAULT_MAX_SIZE = 8 (load-bearing, POC #5 B2);
  per-connection prepare_cached discipline (B5: statements die with
  sessions); the synchronous_commit parity knob as connect options on
  every pooled connection (default 'on', configurable, alkstore
  src/opts.rs mechanics)
- CAS first-writer-wins (INSERT ... ON CONFLICT DO NOTHING) on both
  put forms; metadata-only size probe riding the PK index (EXPLAIN
  gate-tested); EXISTS has; materializing get cursor; degenerate
  in-memory stage with both hygiene forms (fail_commit injection)
- list: the single-statement MVCC-snapshot cursor (portal-batched row
  stream, keys only); crate-internal batch-delete helper
  (DELETE ... WHERE key = ANY() over bytea[]), scope-noted until
  wave 6; virgin-store read-only split via SQLSTATE 42P01 mapping
- 15 in-module unit tests, env-driven (ALKBLOBS_PG_*), skipping
  cleanly server-less; green against the dockerized pglo-poc harness
  server (:15432)

Verified: cargo test; cargo test --features postgres (84 lib tests);
cargo test --all-features (139); clippy all-targets, default +
features + all-features, -D warnings; fmt --check; doc --no-deps.
2026-10-12 06:02:24 +00:00
glm-5.3-flash 611d30a3c4 fix(store): rustdoc hygiene + u64-safe cursor clamping
- resolve or unlink 25 preexisting rustdoc warnings: broken
  intra-doc links (error variants), public-docs-linking-private-items
  (crate-internal cursor/registry names), and one stale reference to a
  `Store::window_host` that never existed (the form branch is
  `sweep_window`'s engine-enum match)
- `clamped` runs its arithmetic in u64 and narrows to usize after
  clamping, so a wide u64 offset can never wrap onto a small slice
  position on narrow-pointer targets; the cursor contract tests pin
  the overflowing-offset and overflowing-length forms
- zero rustdoc warnings under RUSTDOCFLAGS=-D warnings

Verification: cargo test (69+19+3 green), cargo test --all-features
(124+54+4 green), cargo clippy --all-targets -- -D warnings green,
cargo fmt --check green, RUSTDOCFLAGS=-D warnings cargo doc --no-deps
green.
2026-10-12 05:40:09 +00:00
glm-5.3-flash 97cdf682c4 docs(review): the wave-3 review gate — every gate check green
Reviewed the wave-3 commits (engine-sqlite, engine-sqlite-window,
store-sqlite-construction, store-sweep-durable-window,
suite-column-sqlite) against the cited ADR/spec text line by line:
ADR-003/007/008 §2, ADR-010 §2, ADR-012 §1/§5/§6.7, store-api.md,
implementation.md §Review gates — the engine-vs-contract conformance
(suite column green server-less in the default build; the window
family contract-tested per its applicability row; virgin-store
semantics incl. the no-tables-yet form; the size metadata-only
discipline proven index-riding), the durability posture (WAL +
synchronous=NORMAL verified at open; the single-writer ceiling posture,
not hedge), the durable sweep form vs ADR-008 §2/ADR-012 §6.7 (stage at
mark_end + window; next-sweep execution with raced execution-time
re-arbitration; schedule-relative exact counts; aborts stage and
execute nothing), the seam reduction (gc_window only; no pin rows, no
sweep-lock body, no EngineFleetState), and the blocking discipline
(all rusqlite in spawn_blocking). Named design points audited as
resolved; family conventions clean; no wave-4 amendments arise.

Inline fixes (review-of-record):
- src/gc.rs: the seam's window_stage doc retired the wave-1
  lazy-create hedge for the shipped constructor-at-open posture
  (a tableless database surfaces the engine error on stage;
  per-engine tolerances are each engine's recorded posture)
- tasks/engine-sqlite-window, store-sweep-durable-window,
  suite-column-sqlite: stray placeholder lines above the filled
  Notes/Summary removed (the wave-2 gate's same cleanup)
- tests/conformance/README.md: trailing newline added

Verification (all re-run green after the fixes):
- cargo test (default): 69 lib + 19 conformance + 3 git-interop
- cargo test --features mem / --all-features: 124 lib + 54
  conformance + 4 git-interop each
- cargo clippy --all-targets -- -D warnings (default + all-features)
- cargo fmt --check
- cargo doc --no-deps at the pre-existing warning baseline (26)

Wave 4 (postgres) decomposition is unblocked.
2026-10-12 05:22:29 +00:00
glm-5.3-flash fb8326c4d5 feat(store): the sweep's durable form — staged candidates, next-sweep execution
The first durable delete window (single-node), beside the inline form:

- sweep_window branches on the delete window's host — the kv-engine
  enum (KvEngine::Sqlite -> durable; KvEngine::Mem -> inline body,
  extracted verbatim so the wave-2 mem/local suites stay green
  unchanged)
- the durable form, per sweep under the lease and after the shared
  protect consult: window_take(now) executes the overdue set with
  execution-time re-arbitration through the same arbitrated_delete
  path (consult_protect = false — the sweep's protect consult covers
  its execution phase; vanished candidates settle into the cancelled
  count), then marks unchanged, then stages the candidate-dead set at
  visible_after = mark_end + window (the constructor-tunable delay;
  ZERO = execute-on-next-sweep)
- report counts exact relative to the schedule (staged-this-sweep vs
  executed-this-sweep); aborts execute nothing, stage nothing, delete
  nothing
- unit tests: two-sweep exact-count shapes at delay 0, future-delay
  staging with idempotent re-stage, the race across the delay (put
  during the window survives; the unpinned twin deletes), the
  vanished-candidate form, and the three abort shapes on sqlite

Verification: cargo test (default 69 lib tests), --all-features (124),
--no-default-features --features mem (101), clippy -D warnings
(default and --all-features), cargo fmt --check — all green.
2026-10-12 05:05:58 +00:00
glm-5.3-flash 2993df0e36 feat(store): the sqlite constructor wiring — the default-build store shapes
- KvEngine::Sqlite slots in; all six kv ops dispatch; the kv cursor
  body dispatches through a new KvCursor sub-enum behind AnyCursor's
  one kv arm (the kv-arm-over-multiple-kv-engines design point,
  recorded)
- dual_tier_sqlite_local (kv = sqlite + large = local, the
  default-build production shape) and kv_only_sqlite constructors —
  both feature-gated on sqlite (default-on), both taking the
  threshold and the delete-window delay, fallible where I/O is
  fallible (Err(Error::Io) per the dual_tier_mem_local pattern)
- ensure_gc_schema runs at construction via the engine-neutral
  KvEngine call (sqlite's body creates gc_window only); the
  window-delay shipped default is the pinned
  DEFAULT_DELETE_WINDOW_DELAY (5 min, ADR-008 §2), constructor-
  tunable, Duration::ZERO legal — the store carries the value for
  the sweep's durable form to consume
- the one-window-host posture recorded in the module doc (the
  durable window hosts on the kv engine when it is SQL-backed; wave
  5's pg-lo dormancy slots in without reshaping)
- stale empty-set scaffolding updated to the landed state: the
  #[allow(unused_variables)] attrs off the KvEngine methods; the
  scope notes in store.rs, backend.rs, sqlite.rs, gc.rs
- constructor unit tests: mode/threshold/window-delay introspection,
  the GC schema observed in the fresh database (window table present,
  gc_pins never), kv-only rejection wiring unchanged, and the
  dual-tier shape round-tripping end-to-end through both tiers

Verification: cargo test 62 passed (default; 5 new tests), cargo test
--all-features 117, cargo test --features mem 117, --no-default-
features --features mem 97; cargo clippy --all-targets -- -D warnings
clean (default + all-features); cargo fmt --check clean; cargo doc
--no-deps at the pre-existing warning baseline.
2026-10-12 04:50:22 +00:00
glm-5.3-flash 51d8f6525f feat(gc): the sqlite engine-state window family — the durable single-node delete window
- impl EngineWindowState for SqliteBackend, the window family only per
  ADR-012 §5's sqlite row; no pin-clause or sweep-lock body exists —
  EngineFleetState is never implemented on this engine
- ensure_gc_schema creates gc_window only (never gc_pins; the embedder's
  liveness table is never created — ADR-008 schema ownership)
- window_stage is a key-keyed upsert: idempotent per (key, deadline),
  a re-stage at a new deadline updates the row
- window_take is one atomic DELETE … RETURNING with the <= now
  boundary; future rows left in place; tableless take is a no-op read,
  tableless stage surfaces the engine error (the recorded read/write
  tolerance split)
- visible_after encodes as signed i64 nanoseconds from the epoch
  (recorded design point; sub-second precision for test tunings)
- six clause contract tests per the ADR-012 §5 sqlite row

Verification: cargo test green (58 lib + 5 integration);
cargo clippy --all-targets -- -D warnings green; cargo fmt --check green.
2026-10-12 04:39:45 +00:00
glm-5.3-flash 908fb5d2dd feat(engines): the sqlite kv engine — the default engine, first SQL-backed (wave 3)
Implements the sqlite kv-tier engine per ADR-003/007/010 §1 behind
feature `sqlite` (default-on): the B5 row shape (key BLOB PK / value
BLOB / size INTEGER NOT NULL), INSERT OR IGNORE CAS first-writer-wins
on both put forms, the EXISTS has probe, the materializing cursor body
with len() from the size column, the degenerate in-memory stage with
both hygiene forms, the indexed-column size probe (plan-tested), the
no-tables-yet virgin-store read tolerance (tested against a tableless
database file), WAL + synchronous=NORMAL verified at open, prepare_cached
discipline, and every rusqlite operation in spawn_blocking under the
recorded single-connection posture.

Task: tasks/engine-sqlite.md (status: completed). The engine-state
window family and store construction remain in their own tasks.

Verification:
- cargo test — 58 pass (11 new sqlite in-module tests)
- cargo clippy --all-targets -- -D warnings — clean
- cargo fmt --check — clean
- cargo check --no-default-features — green
2026-10-12 04:31:24 +00:00
glm-5.3-flash 79cf1f0220 docs(review): the wave-2 review gate — every gate check green
Read the wave-2 implementation against the pinned ADR text line by
line (ADR-003/005/006/010/011/012/013 §2, store-api.md): the three
numbered unknown-length rules each test-backed, the delete-window
ordering invariants (arbitrate-at-delete-time, pin-before-publish on
both put paths and both tiers, raced conversion ordering,
delete-then-recover), abort-as-data with all three causes, dispatch
purity + fall-through + constructor modes + kv-only's two put-time
rejection points, stage-hygiene exact counts on both engines (incl.
the Drop-cancellation story), both suite columns green/ADR-stamped/
traceable with the factory binding recorded, the dispatch-coverage
shape exercised, all eight named design points recorded and
consistent, and the staged-put key-at-commit amendment audited
accepted. No wave-3 amendments arise.

Inline fixes applied by the gate:
- facade.rs: stale Batch::add dead-code allow + stale task-pointer
  comment removed (put_in_batch's call sites landed)
- dispatch.rs: module-level allow(dead_code) removed (route/Tier now
  driven; clippy clean without it), scope note updated
- backend.rs: the allow kept but its scope note corrected to what is
  actually dead (trait name, kv put until wave 3)
- mem.rs: stale constructor doc line updated to the landed state
- tasks/gc-protocol.md: stray placeholder lines removed

Verification: cargo test (42 lib + 2 conformance + 3 git-interop),
cargo test --features mem and --all-features (97 lib + 37 conformance
+ 4 git-interop), clippy --all-targets and --all-features --all-targets
(-D warnings), fmt --check — all green post-fix. Wave 3 decomposition
unblocked.
2026-10-11 23:42:42 +00:00
glm-5.3-flash 539dabcbf7 feat(store): the put seam — two internal paths, the three numbered rules, Batch, kv-only rejection
- `put(len: Option<u64>, stream: impl AsyncRead + Unpin + Send) -> (Key, Pin)`:
  known-length one-pass flow; unknown-length buffer-to-threshold flow with
  the mid-stream fresh-stage flush (ADR-003 option (d), three numbered rules:
  flush-and-continue, derivation over the eventual stored artifact as a
  whole via buffer form and StagingCursor read-back form, zero residue on
  stream error)
- staged-put seam amended (operator sign-off): `put_staged()` keyless
  handout, `StagingCursor::commit(self, key)` publishes under the
  store-core-resolved key — the canonical key completes at stream end and
  the wave-1 handout shape could not express the commit-rename flow
- pin-before-publish rides the arbitration lock on both paths and both
  tiers; dedup re-puts refcount the existing entry
- Batch seam: `Store::batch()` + `put_in_batch()`, members publish pin-
  before-publish, group pins drop together on `Batch::commit` (new public
  verb) or drop
- kv-only rejection (ADR-012 §6.2): known-length over-threshold rejects
  immediately (stream never read), unknown-length at mid-stream overflow;
  zero residue; error carrier `Io(String)` (named design point)
- declared-len mismatch rejects `Verification` zero-residue (named design
  point); stream shape generic-no-dyn (named design point)
- incremental BlobHasher (pinned byte-equal to Algorithm::derive);
  AnyStaging cursor dispatch; git-interop put-path leg against
  git hash-object; eleven put-path behavior tests

Verification: cargo test (default/--features mem/--all-features) green;
clippy --all-targets -D warnings green in all three feature shapes;
cargo fmt --check green; cargo doc --no-deps at the 24-warning baseline.
2026-10-11 23:00:14 +00:00
glm-5.3-flash 889be4cada feat(gc): the in-process GC protocol — pins, liveness, delete windows, sweep, direct delete
The gc-protocol task (ADR-005; abort-as-data per ADR-012 §1; non-SQL
inline window staging per ADR-012 §5) wired on the Store facade:

- src/gc.rs — GcHome + RegistryCore: one arbitration lock over per-key
  pin refcounts, in-flight delete markers, and the registered source
  lists; async pin minting (acquire) that blocks on in-flight deletes
  (ADR-005's re-put case (a) delete-then-recover without engine I/O
  under the lock); the ordered-step convert primitive (pin release +
  registration in one section); batch one-step release; the
  single-node sweep lease (the in-process analog of ADR-013 §2).
- src/facade.rs — Pin/Batch carry the registry back-reference and own
  their drop release (batch drop decrements every member in one
  ordered step); new public vocabulary LivenessSource, ProtectCallback,
  Registration, re-exported from lib.rs.
- src/store.rs — sweep() (single-flight → zero-source safe default →
  protect consult → mark over both tiers' list() union → arbitrate at
  delete time → ~100/batch commit → exact-count report or
  abort-as-data), direct delete() (existence probe → full protection
  set per ADR-012 §6.4 → GcRefuse/Missing/delete through the
  fall-through), and the registration/unregistration verbs.
- 16 new tests + the facade pin/batch shape test reworked on the wired
  machinery: exact counts across both tiers, abort shapes, dedup
  refcounts, batch drops, live-shared sources, the conversion ordered
  step sequentially and raced, sweep-vs-pinned-put (64 rounds, every
  schedule, byte-identical delete-then-recover), publish-after-mark,
  no-torn reads under a window, single-flight contention, and
  malformed-list sweeps as operational errors.
- tasks/gc-protocol.md — status completed; named design points recorded
  in Notes.

Verification: cargo test (default) 46 passed; --features mem and
--all-features 89 passed each; cargo clippy --all-targets -- -D
warnings (default and --all-features) clean; cargo fmt --check clean;
cargo doc --no-deps at the pre-existing baseline (no new warnings).
2026-10-11 22:40:09 +00:00
glm-5.3-flash f1f505a910 feat(store): the read paths — get/stat/read_range/has/list on the fall-through rule
- Public `(len, stream)` shape: `Store::get` returns
  `Option<(u64, Blob)>`; `Blob` (src/facade.rs) is a bounded, re-entrant
  windowed reader over the new crate-internal `AnyCursor` tier dispatch
  (mem materializing / local pread body families) — engine cursors
  never leak onto the surface; no chunk-iterator machinery.
- Verification-on-get pinned against ADR-006: kv-tier materialized
  reads whole-blob hash-check at get time (mismatch = Err(Verification),
  never a further fall-through); the large tier's streaming open is
  metadata + handle only (put-path verification + slice digests are its
  story); `read_range` carries slice digests only, on both tiers.
- `stat` rides the trait's `size` probe (never a content load) into
  `EntryMeta { len, algorithm }`; `has` is the pure existence probe;
  both fall through kv -> large like every key-addressed op (ADR-012
  §6.1) — consult order, not routing (never consults `tier_for`).
- Miss shapes enforced (the error module's behavioral note): both-tier
  misses are Ok(None) on get/stat, false on has, Err(Missing) on
  read_range; `src/error.rs` wave-2 deferral notes updated to enforced
  state.
- `list` decided Vec<Key>: materialized, sorted total-order union of
  both tiers (the sweep consumes the engines' enumeration directly);
  malformed pool bytes are fatal `Err(KeyInvalid)`, never a silent
  skip.
- `KeyInvalid` at the facade boundary: ops take opaque key bytes and
  convert via `Key::from_bytes` once (`boundary_key`); engines never
  see typed keys.
- Twelve read-path tests: virgin-store shapes per mode (dual-tier,
  mem-only, kv-only), the `(len, stream)` windows, fall-through,
  kv-first (decoy content in the large tier), both verification
  postures, list union/sort/pool-fatality, and malformed-key
  rejection on every op.

Task: tasks/store-read-paths.md (design points recorded in Notes for
the wave-2 review gate).

Verification: cargo test (default), cargo test --features mem, cargo
test --all-features green; cargo clippy --all-targets -- -D warnings
green in all three feature shapes; cargo fmt --check green; cargo doc
--no-deps clean beyond the pre-existing private-intra-doc-links class.
2026-10-11 22:28:01 +00:00
glm-5.3-flash 532adfa707 feat(store): the Store facade — constructor modes, size-threshold dispatch, the factory binding
The wave-2 facade skeleton and routing (tasks/store-construction.md):
the public surface consumers program against, with the ops methods
still to land against it in store-read-paths/gc-protocol/store-put-paths.

- src/store.rs — the public `Store` type (engine-blind, ADR-007/008/
  010) over crate-internal tier enums (`KvEngine`{mem}, `LargeEngine`{
  local}): the engine-representation design point decided as concrete
  + enum dispatch, generic rejected (pub(crate) engines, no dyn);
  the three constructor modes as named constructors — `mem_only`,
  `kv_only_mem`, `dual_tier_mem_local` (the ADR-012 §6.3
  dispatch-coverage shape) — with `StoreMode` introspection; the
  write-side routing seam (`tier_for`), the read-side fall-through
  order (`kv()` then `large()`, ADR-012 §6.1), and the `GcHome`
  GC-state field; the ADR-012 §3 fleet declaration ruled deferred to
  the engine waves (nothing fleet-valid is constructible yet)
- src/dispatch.rs — the pure routing function (`route`, at-or-below
  → kv), `DEFAULT_DISPATCH_THRESHOLD` (128 KiB) exported at the
  crate root, boundary-value unit tests (exactly-at-threshold,
  degenerate tunings, purity)
- src/gc.rs — `GcHome`: the store-instance GC-state home the
  gc-protocol task fills (in-process; fleet state stays on the
  engine-state seam per ADR-010 §2/ADR-012 §4)
- tests/conformance — the wave-2 binding made as anticipated: the
  factory's `Store` associated type collapsed into the concrete
  `alkblobs::Store` (`open` vends it directly), recorded in
  factory.rs + README; the wave-1 mock probe retired, replaced by
  mem-gated binding demo factories (binding.rs) over both
  constructible shapes

Verification: `cargo test` (default), `cargo test --features mem`,
`cargo test --all-features` green (41/53/53 unit + conformance
targets green in all three shapes); `cargo clippy --all-targets
-- -D warnings` green in all three feature shapes; `cargo fmt
--check` green; `cargo doc --no-deps` adds no warnings beyond the
pre-existing private-intra-doc-links class.
2026-10-11 22:18:32 +00:00
glm-5.3-flash 856d436f81 feat(engines): the local large-tier engine — sharded files, stage-then-commit-rename, pread cursors
- LocalBackend: flat {hex-prefix}/{hex-prefix}/{hex} sharding over
  lowercase-hex-of-Key::as_bytes filenames (self-describing; the
  list-decode round-trip recorded for the review gate); virgin-store
  reads are no-ops
- staged put: unique stage files under {root}/staging/, commit-rename
  is the publish, CAS first-writer-wins, every failure path (discard,
  failed commit, Drop cancellation) converges on zero residue
- read cursor: pread loop over the immutable committed file, EOF
  clamping, provided read_range composing the slice-digest convention
- all file I/O in spawn_blocking; size is a stat, never a content load
- list walks the committed tree and is fatal (Error::Io, path named)
  on anything that does not decode — complete and well-formed
- 11 in-module unit tests incl. exact-count stage hygiene over all
  failure forms and the success form

Verification: cargo test (44 green), clippy --all-targets/--all-features
-D warnings, fmt --check — all clean

Task: tasks/engine-local.md
2026-10-11 22:05:59 +00:00
glm-5.3-flash 0b43ea1449 feat(engines): the mem contract-reference engine — first real engine (wave 2)
- src/mem.rs: MemBackend implements Backend (seven methods + put_staged,
  name "mem") over Arc<parking_lot::Mutex<BTreeMap<..>>>; CAS
  first-writer-wins puts, materializing MemCursor body, degenerate
  in-memory MemStaging whose commit publishes via the same CAS clause
  and self-discards on failure; discard leaves zero residue.
- CAS re-put is dedup for both put forms; reads are no-ops on the
  virgin store; delete carries Missing; size is metadata-only.
- Eight in-module tests mirror the wave-1 double's assertions: method
  contract, list well-formedness, cursor body read contract + ADR-006
  range digest, empty-entry round-trip, staged happy path, and both
  hygiene forms (fail_commit test hook stands in for media failure).
- backend.rs: clamped promoted pub(crate) — the shared EOF-clamping
  arithmetic both mem cursor bodies compose (no per-engine duplicate).

Verification: cargo test --features mem (33+7 green); cargo test
(default) green; clippy --all-features --all-targets -D warnings green;
fmt --check green.
2026-10-11 21:56:29 +00:00
glm-5.3-flash 0547c17876 feat(backend): the Backend trait, I/O seams, engine-state seam shape, and facade value types (ADR-003/010)
The wave-1 contract surface: everything engine-blind that waves 2-6
implement against. No engine bodies, no facade behavior logic.

- src/backend.rs: the pub(crate) Backend trait — seven methods +
  put_staged, opaque byte keys/values, size metadata-only, list
  complete-and-well-formed, virgin-store reads as no-ops (ADR-003,
  ADR-008); the ReadCursor/StagingCursor I/O seams with the read_range
  slice-digest convention (ADR-006) at one seam; unit tests against
  both body-family doubles, a test-double engine, and the stage-hygiene
  invariant's two forms (discard; commit failure self-discards).
- src/gc.rs: the engine-state companion seam as EngineWindowState /
  EngineFleetState — ADR-012 §5's applicability table expressed
  structurally (no dead machinery); JointTx ownership rule pinned in
  the signature (store holds the tx; engine contributes mechanics).
- src/facade.rs: EntryMeta, Pin, Batch, SweepReport, GcAbortCause
  (x3, #[non_exhaustive]), PinState with lifecycle contracts
  (ADR-005, ADR-012 §1); re-exported from lib.rs.
- Design points pinned for the wave-1 review gate in
  tasks/core-trait-and-types.md: pub(crate) trait visibility,
  associated-type put-form shapes, AFIT + associated types (no dyn).

Verification: cargo test (26 lib + 3 git-interop), cargo test
--all-features, clippy --all-targets -D warnings (default and
--all-features), cargo fmt --check, cargo doc --no-deps — all green.
2026-10-11 18:30:47 +00:00
glm-5.3-flash fef05b4ec5 feat(keys): the content-address layer — canonical hash derivation and key encoding (ADR-002)
Wave 1 task core-hashing-keys: the crate's declared one-way door,
implemented byte-exact to ADR-002.

- src/hashing.rs: Algorithm (exactly GitBlobSha256 canonical /
  GitBlobSha1 tolerated; BLAKE3 absent), Digest (known-length
  derivation H("blob <len>\0" + content) as primary constructor;
  from_git_oid_hex interop constructor, lowercase-only acceptance),
  and the hashing::registry constants (0x01/0x02, 0x00 reserved; new
  algorithm = new ADR)
- src/keys.rs: typed Key wrapper; as_bytes/from_bytes are the only
  backend-boundary conversions; 1 algorithm byte + digest bytes
  (33/21 total); rejects-never-guesses validation -> Error::KeyInvalid
- tests/git_interop.rs: the load-bearing test — byte-exact derivation
  against the `git hash-object` CLI, both algorithms, small and
  75-KiB content; external-oid round-trip into pool keys; both oid
  formats coexisting in one flat pool
- named design point (oid hex policy): lowercase-only acceptance,
  recorded in the task Notes and on from_git_oid_hex

Verified: cargo test (15 passed), cargo clippy --all-targets -- -D
warnings, cargo fmt --check, cargo test --all-features — all green.
2026-10-11 18:20:12 +00:00
glm-5.3-flash fc5ab57d18 feat(errors): the one-enum error family with altitude discipline
- src/error.rs: thiserror Error enum with the five ADR-012 \u00a76.5
  variants (Missing, Verification, Io(String), GcRefuse, KeyInvalid);
  doc comments carry store-api.md \u00a7Error model's semantics and the
  one-enum/two-altitude discipline (trait's effective members are
  Missing/Verification/Io/KeyInvalid; facade re-exposes with GcRefuse)
- no #[non_exhaustive] per the ADR-pinned variant set; Error derives
  Debug/PartialEq/Eq
- lib.rs re-exports Error
- unit tests: variant construction, the single-enum altitude shape,
  and the Missing-is-never-get/stat-absence doc contract (facade
  behavioral enforcement lands in wave 2)
- tasks/core-error-model.md: status completed; Notes + Summary filled

Verified: cargo test, cargo clippy --all-targets -- -D warnings,
cargo fmt --check
2026-10-11 18:10:04 +00:00
glm-5.3-flash 24d1c68343 feat(crate): scaffold the ADR-013 §4 feature graph and module skeleton
- Declare the decided feature graph in the manifest: sqlite default-on
  (rusqlite 0.40 bundled), postgres (tokio-postgres 0.7 +
  deadpool-postgres 0.14), mem (dependency-free), pg-lo pulling the
  shared pg driver cluster only (no postgres implication, ADR-010 §1),
  ops (alkcall 0.8.1, default-off); local ungated
- Replace the placeholder crate body with the module skeleton: lib.rs
  re-export shape, ungated stubs (hashing, error, backend, facade,
  dispatch, gc, local), engine stubs behind #[cfg(feature)]
  (mem, pg_lo, postgres, sqlite, ops); stubs are doc-comment-only so
  wave-1 tasks own the module bodies

Verification: cargo test green (default); cargo check --all-features
resolves the full graph; cargo check --no-default-features --features
pg-lo resolves with rusqlite provably absent (tree-inverted match) —
the ADR-010 §1 no-implication rule; clippy --all-targets -D warnings
and cargo fmt --check clean.

Task: tasks/scaffold-crate-features.md (wave 1)
2026-10-11 18:01:18 +00:00
glm-5.3-flash 7f7f70b220 feat: initial repo setup (Phase 0 scaffolding)
- AGENTS.md: repo conventions adapted from alkcall/alksocks (store
  posture, multi-hash requirement, no-iroh-wire rule; no fuzz gate yet)
- Cargo.toml + src/lib.rs: bare lean lib skeleton (tokio async, thiserror)
- docs/research/phase-0.md: Phase 0 draft — vision, prior art (iroh-blobs
  store, gix-odb, alknet appfile probe, alkcall), OQ register, POC plan
- .gitignore, LICENSE-APACHE/MIT
- Re-pointed stale alknet/alkcall references in .opencode/agents/ and
  docs/sdd_process.md

Verification: cargo build/test, cargo clippy --all-targets -- -D
warnings, cargo fmt --check, cargo doc --no-deps — all pass
2026-09-30 07:45:40 +00:00