Files
alkstore/tasks/mem-engine-streams.md
T

6.8 KiB

id, name, status, depends_on, scope, risk, impact, level, tags
id name status depends_on scope risk impact level tags
mem-engine-streams Mem engine — streams (in-memory log, per-consumer offsets, trim) completed
mem-engine-seam-tx
mem-engine-notify-listen
moderate medium component implementation
wave-6
mem-engine
streams

Description

The streams mechanism over an in-memory event log + per-consumer offset table (engine-mem.md §Mapping the contract, streams row):

  • StreamHandle surface (ADR-019 §2): publish / publish_with_key (present key must be non-empty → InvalidName), read_since / read_from_consumer (cursor reads, offset ASC, extents clamp empty per ADR-023 §2), save_offset / get_offset (monotone saves — below-checkpoint saves are silent no-ops, Err arm carries Database only), trim_to (delete offset <= horizon, exact-boundary, returns deleted count, negative horizon deletes nothing idempotently, wakes nothing, surviving rows keep offsets, never renumbered), and subscribe (durable consumption: attach, read to tail, resume from saved offset; wake-driven with re-read — the wake substrate delivers at commit; explicit saves only, no auto-checkpoint).
  • Ordering: engine-assigned monotonically increasing per-stream offsets, global FIFO by offset — the ADR-015 ordering row, mem's own counter (per-stream; absolute values need not equal the SQL engines' — the equivalence rows pin relative order).
  • StreamEvent shape exactly as pinned (ADR-015 §3): { offset, stream, key, payload, created_at } — created_at is unix-seconds at publish, informational, from the clock accessor. Reads from a trimmed-away region resume at the horizon's first remaining row.
  • Keyed publish rides the tx overlay (staged publish_with_key_tx landed in mem-engine-seam-tx); this task's non-tx forms, receiver, and trim live here.
  • Receiver close arms (ADR-021 §5): recv()'s Err carries Database only (payloads cross raw; Codec at payload_as<T>); close is terminal — the one close path is engine drop (the notify-listen task's close arm, realized identically); no reconnection concept (the pg stays-open-across- reconnect row is absent from mem's column).

Acceptance Criteria

  • Full StreamHandle surface over the in-memory log + per-consumer offsets
  • The ADR-015 properties unit-pinned: global FIFO, immutable never-renumbered offsets (gaps legal post-trim), exact-boundary trim semantics (reads resume at horizon; saved sub-horizon offsets stay valid; trim wakes nothing), monotone save composition (direct + receiver forms interleave)
  • Key round-trips exactly (None vs Some); empty-Some-key rejected at every entry point
  • Extent/offset numeric-domain guards at entry — pinned
  • cargo check --target wasm32-unknown-unknown -p alkstore-mem clean; workspace gates green

References

  • docs/architecture/core-contract.md §streams
  • docs/architecture/decisions/015-streams-depth.md; 019-mechanism-handle-surfaces.md §2/§6; 021 §5; 023 §2
  • docs/architecture/engine-mem.md §Mapping the contract (streams row)
  • tasks/pg-engine-streams.md (the structural twin's task of record)

Notes

Filled by implementation agent, 2026-10-10.

  1. The implementation already landed in the seam task — the same all-or-nothing trait-impl disposition the notify-listen, queues, and locks twins recorded: the MemStreamHandle/receiver mechanism in alkstore-mem/src/stream.rs (log + offsets + trim + subscribe
    • the tx-staged keyed publish) was implemented with the seam's whole-engine scope; this task found its mechanism implemented.
  2. Coverage reconciliation: already pinned by the seam suite in stream.rs — the round-trip FIFO row (offsets monotone, offset-ASC reads, created_at from the clock, key None vs Some on the yielded events), the empty/whitespace-Some-key rejection at the auto-commit and publish_with_key_tx entry points, the read extent clamps (limit <= 0 → empty), the monotone-save row (absent consumer 0, below/equal saves silent no-ops, forward saves land), the exact-boundary trim row (offset <= horizon, survivors keep offsets, negative horizon deletes nothing, idempotent), the subscriber row (attach replays from the saved checkpoint, wake-driven delivery, the receiver save_offset() form composing with the direct form, the pre-yield save no-op), the trim-wakes-nothing row (silent timeout with an open subscriber), and the engine-drop close arms (terminal Err(Closed) on try_recv, terminal None on recv, never reopens).
  3. What this task added — the two unpinned shapes: (a) read_from_consumer_reads_the_cursor_and_clamps_the_extent — the surface test the seam suite lacked for the consumer-cursor read (absent consumer reads from the head, checkpoint-forward resume, tail reads empty, extent clamps, empty-consumer-name InvalidName); (b) saved_sub_horizon_offsets_survive_trim_and_ consumer_reads_resume_at_the_horizon — the ADR-015 trim property the trim row only half-pinned: the sub-horizon checkpoint is untouched by trim (offsets never renumbered) and consumer reads resume at the horizon's first remaining row.
  4. No production code changed — verified correct as-found; tests only (+2 in stream.rs, 99 mem tests total). One observation the new rows recorded: a cursor read resumes at the first surviving row after the checkpoint and continues to the tail (the pinned resume-at-horizon semantic is a lower-bound guarantee, not a one-row read).

Summary

Filled on completion, 2026-10-10.

Completed the mem engine's streams task against the seam task's foundation: reconciled the description's pin list against alkstore-mem/src/stream.rs's existing suite (11 pre-existing mechanism tests), found the StreamHandle surface and nearly all ADR-015 properties already pinned, and added the two gaps — the read_from_consumer cursor-read surface (head/cursor/tail/extent/ name-validation legs) and the sub-horizon-checkpoint-survives-trim + resume-at-horizon row. Acceptance criteria: full surface ✓ (seam task + the new cursor row), ADR-015 properties ✓ (seam rows + the new trim row), key round-trip/empty-key rejection ✓ (seam rows), extent guards ✓ (seam row + the new consumer-read clamp legs), gates ✓. Verified: cargo test -p alkstore-mem 99/99 (97 + 2 new, new tests green solo), workspace cargo test green, cargo clippy --all-targets -- -D warnings clean, cargo fmt --check clean, cargo check --target wasm32-unknown-unknown -p alkstore-mem clean.