mem-engine-foundations — the mem engine's foundations land (alkstore-mem, wave 6 task 1 of the ADR-024 chain): fourth workspace member with the manifest surface ADR-024 §1 pins — alkstore versioned path pin (ADR-017 §4.1) plus tokio restricted to the wasm-supported subset (sync + time; dev-deps rt/macros for the current-thread-flavor tests), no driver deps, no parking_lot (the description's prose named it, but the ADR + acceptance criterion pin the manifest tighter — short-held internal guards are std::sync::Mutex behind a state::Guard trait that folds poisoning away structurally, guards never held across awaits or user code, tokio mpsc the cross-await primitive). Five modules re-exported from lib.rs whose crate docs carry the ADR-016 posture statement (honest-ephemeral, full contract v1, wasm32-compile-clean identity, architecture sketch with the wave-6 construction line). MemStore::new() is the engine-native isolated constructor (ADR-024 §4's documented open-prose exception): fresh guarded state core (state.rs — empty named per-mechanism sections QueueState/StreamState/LockState/ScheduleState, shapes owned by the mechanism tasks), fresh wake bus, fresh clock per open; teardown is drop driving WakeBus::close() — no explicit close form. Wake substrate (wakes.rs): WakeBus::attach → WakeFeed (one unbounded mpsc feed per subscriber, detach-on-drop, attach under the registry guard so attach-after-commit no-replay is structural), fire_commit_wakes(channels) as the commit-ordered wake source's entry point (guard makes watermark bump + per-channel fanout one operation — per-subscriber FIFO by commit order, never coalesced), close empties senders so engine drop disconnects every feed; commit_watermark is a cfg(test) ordering observable only. Clock (clock.rs): one accessor Clock::unix_now over SystemTime, freeze/advance/unfreeze as the cfg(test) deterministic-seam; MemStore clock/wakes cfg(test) accessors. Validation (validation.rs) carries no new rule — pin module only (empty/whitespace InvalidName, prefix ReservedName, RESERVED_LISTENER_RECONNECTED rejected though unused here); mechanisms route core's validate_shared_name/local_name directly. Targeted allow(dead_code) on not-yet-wired scaffold surfaces so clippy -D warnings stays green pre-consumer (mechanism tasks own exhausting the allows); tokio time pinned unexercised (lock-TTL/scheduler consumers arrive with their tasks). Unit pins: 17 mem tests — two-instances-share-nothing (Arc pointer identity + behavioral: frozen clock isolation, cross-instance wake silence), state section independence/relock, wake routing (channel-scoped + foreign silence, per-notify never coalesced, watermark-ordered FIFO, no-replay, close disconnects all + post-close inert, dropped feed detaches), engine-drop closes feeds, clock determinism, validation pin row. Task file: status completed, Notes (decisions of record: parking_lot rejection, empty sections, substrate API shape, no-close, scaffold allow posture, unexercised time feature) + Summary filled. Verified: cargo build; workspace cargo test green (pg 124/25/9, sqlite 191/25, core 25, suite 3, mem 17); clippy --all-targets -D warnings clean; cargo fmt --check clean; cargo check --target wasm32-unknown-unknown -p alkstore-mem clean — the wave-6 wasm gate starts green from this task onward

This commit is contained in:
glm-5.3-flash committed 2026-10-10 11:27:52 +00:00
1 parent 6f9cfb5778
commit 6632dcce1f
10 files changed
+938 -8

No files matched your search

+90 -8
View File
@@ -1,7 +1,7 @@
---
id: mem-engine-foundations
name: Mem engine — crate scaffold, `MemStore::new()`, guarded state core, wake routing
status: pending
status: completed
depends_on: []
scope: moderate
risk: medium
@@ -63,16 +63,16 @@ this task lands everything up to the trait boundary.
## Acceptance Criteria
- [ ] `alkstore-mem` is a workspace member compiling clean; manifest
- [x] `alkstore-mem` is a workspace member compiling clean; manifest
dependency surface is core + tokio (sync + time) only
- [ ] `MemStore::new()` constructs; two instances share nothing
- [x] `MemStore::new()` constructs; two instances share nothing
(pinned by a unit test)
- [ ] The guarded state core, validation rules, wake-routing
- [x] The guarded state core, validation rules, wake-routing
substrate, and clock accessor exist with unit pins
- [ ] `cargo check --target wasm32-unknown-unknown -p alkstore-mem`
- [x] `cargo check --target wasm32-unknown-unknown -p alkstore-mem`
clean from this task onward (tokio subset discipline enforced
here, not retro-fitted)
- [ ] Workspace gates green (`cargo build`, `cargo test`, clippy
- [x] Workspace gates green (`cargo build`, `cargo test`, clippy
`-D warnings`, fmt)
## References
@@ -85,8 +85,90 @@ this task lands everything up to the trait boundary.
## Notes
> To be filled by implementation agent
> Filled by implementation agent, 2026-10-10.
1. **parking_lot rejected — the ADR won the manifest.** The
description's prose named "parking_lot short-held internal locks
per AGENTS convention 3", but ADR-024 §1 and the acceptance
criterion pin the manifest to core + tokio (sync + time) only.
The guarded-state container uses plain `std::sync::Mutex`
(wasm-fine, no crates.io surface) behind a `Guard` trait whose
`guard()` folds poisoning into `into_inner` — structurally
unreachable anyway, since no guard is ever held across an `.await`
or user-provided code; tokio primitives (`mpsc` unbounded) are the
cross-await coordination. Downstream mechanism tasks follow this
idiom (`state::Guard`).
2. **Guarded-state shapes deliberately empty** — `state.rs` carries
the container plus named empty per-mechanism sections
(`QueueState` = jobs + dead letters, `StreamState` = log + offsets,
`LockState` = TTL registry, `ScheduleState` = schedule table);
each mechanism task owns its section's actual shape.
3. **Wake substrate API shape** (`wakes.rs`):
`WakeBus::attach(channel) -> WakeFeed` (one unbounded mpsc feed per
subscriber; attach lands under the registry guard, so
attach-after-commit no-replay is structural),
`fire_commit_wakes(channels)` is the commit-ordered wake source's
entry point (mechanisms fire at the commit boundary; the guard
makes bump + per-channel fanout one operation — per-subscriber FIFO
by commit order, never coalesced), `close()` is the engine-drop
path (MemStore's `Drop` calls it; senders live only in the bus, so
a drop disconnects every feed regardless of who holds one), and
`commit_watermark()` is a `cfg(test)` ordering observable only —
never contract surface. `WakeFeed::rx()` exposes the raw mpsc
receiver; the consumer-visible `WakeReceiver` bridge
(recv/try_recv/recv_timeout forms) is
`mem-engine-notify-listen`'s surface over this primitive.
4. **Clock** (`clock.rs`): one accessor `Clock::unix_now()` reads
`std::time::SystemTime` (process clock only, per engine-mem.md);
`freeze`/`advance`/`unfreeze` are the `cfg(test)` deterministic
observation seam. `MemStore::clock()` `cfg(test)` accessor.
5. **Validation carries no new rule** — `validation.rs` is the pin
module only (empty/whitespace-only → `InvalidName`, reserved
prefix → `ReservedName`, `RESERVED_LISTENER_RECONNECTED` rejected
even though unused here); every future mem entry point routes
through core's `validate_shared_name`/`validate_local_name`
directly, same as the SQL engines.
6. **Scaffold dead-code posture**: targeted `#[allow(dead_code)]` on
the not-yet-wired scaffold surfaces (the `wakes` module, the empty
`State` sections, `MemStore`'s `state`/`clock` fields,
`Clock::unix_now`) so clippy `-D warnings` stays green with the
gate before consumers exist — the mechanism tasks own using (and
thereby exhausting) these allows.
7. **No `MemStore::close()`** — ADR-024 §4 says teardown is drop;
there is no explicit close form (the sqlite/pg engines' `close` is
connection machinery). If `mem-engine-integration` wants one for
symmetry, that is the place to decide.
8. **tokio `time` feature is pinned but currently unexercised** — no
mem code reads tokio time yet (lock TTLs and scheduler boundaries
are their tasks' consumers); the manifest carries it per this
task's description so the wasm-subset discipline is enforced at
birth rather than widened later.
## Summary
> To be filled on completion
> Filled on completion, 2026-10-10.
Landed `alkstore-mem` as the fourth workspace member — crate scaffold
+ manifest (deps: `alkstore` path pin per ADR-017 §4.1 + tokio
`sync`/`time` only; dev-deps tokio `rt`/`macros`), five modules
(`store`, `state`, `wakes`, `clock`, `validation`), re-exported from
`lib.rs` whose crate docs carry the ADR-016 posture statement
(honest-ephemeral, full contract v1, wasm32-compile-clean identity).
`MemStore::new()` implements the engine-native isolated-constructor
contract (ADR-024 §4): new guarded state core, wake bus, and clock
per open, teardown = drop driving `WakeBus::close()`. Unit pins:
16 tests — two-instances-share-nothing (Arc pointer identity +
behavioral: frozen clock on one instance leaves the other's process
time intact; a fire through one instance's bus never reaches the
other's feed), guarded-state section independence/relock, wake
routing (channel-scoped per-subscriber delivery + foreign-channel
silence, per-commit-notify never coalesced, watermark-ordered FIFO,
attach-after-commit no-replay, close disconnects every live feed +
inert post-close fire, dropped feed detaches), engine-drop closes
open feeds, clock determinism (freeze/advance/unfreeze), validation
pins (4). Verified: `cargo build`, workspace `cargo test` green (pg 124 lib / 25 suite /
9 schema, sqlite 191 lib / 25 suite, core 25, suite harness 3,
**mem 17**), clippy
`--all-targets -D warnings` clean, `cargo fmt --check` clean, and
`cargo check --target wasm32-unknown-unknown -p alkstore-mem` clean
— the wave-6 wasm gate starts green from this task onward.