Files
alkstore/tasks/release-n1-growth-posture.md
T
glm-5.3-flash c132714a77 release: N-1 growth postures consciously accepted (all three engines)
The wave-8 N-1 deferred item — re-read the three unconditional-growth
paths against the implemented engines and land the decision of record:
all three accepted for v1, per engine, with no engine-side hygiene.

- deployment.md: new 'Growth postures (consciously accepted)' section —
  per-engine table (dead letters sweep-on-call, SQLite-only notify
  at-attach cap, durable-log stream posture; mem process-lifetime-
  bounded by design) + the rationale and the deployment-matrix
  fold-in positioning.
- engine-sqlite.md: 'Notifications-table hygiene' — attach is the only
  prune site (D-16, oldest-first 10k); idle-but-listening processes
  never prune; the cadence caveat deployers should size for.
- tasks/release-n1-growth-posture.md: completed; Notes/Summary filled.
2026-10-11 00:23:12 +00:00

127 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: release-n1-growth-posture
name: N-1 growth-posture review — conscious acceptance (or hygiene)
status: completed
depends_on: []
scope: narrow
risk: low
impact: component
level: implementation
tags: [wave-8, sqlite-engine, docs]
---
## Description
Review 001's N-1 (deferred by design to the release pass): three
engine-layer table families grow without internal hygiene caps, and
the release review must **consciously accept them or add engine-side
hygiene** (`docs/reviews/001-waves-1-2-general-review.md` §N-1, §7's
wave-6 release-review bullet):
1. `__alkstore_dead` with `dead_letter_retention_s = NULL` (the
default — the doc text is honest that retention is opt-in)
2. `__alkstore_notifications` rows pruned only at attach (D-16's 10k
cap triggers only next attach — an idle-but-listening process
never prunes)
3. `__alkstore_stream` (growth is the contract's durable-log posture;
`trim_to` is consumer-invoked per ADR-015)
None is wrong for v1; all three are documented engine-internal. The
expected disposition is conscious acceptance with the documentation
sharpened — review 001 specifically suggested the notify one "may want
an 'attach is not the only prune site' note in the sqlite engine's
docs (cadence recipes)". But the acceptance must be a *decision made
this session against the implemented engines* (the review predates
waves 3–7): re-read the three growth paths as implemented, confirm the
review's characterization still holds (the mem engine's postures are
new since — its notify/stream growth is process-lifetime-bounded by
design; say so in the record), and land the acceptance:
- The acceptance record (all three paths, per engine, with the
rationale) — `deployment.md`'s durability/growth posture is the
natural home; coordinate with `release-deployment-matrix` (this
task's outcome is an input to that pass — land the substance here,
let the matrix pass fold it into the final text).
- The notify prune-cadence note in `engine-sqlite.md` (or wherever the
engine spec's cadence guidance lives) if accepted.
- If any path instead warrants engine-side hygiene (a cap, a sweep
integration), that is a scope change — raise with the user before
building; the default is acceptance.
## Acceptance Criteria
- [x] The three growth paths re-read as implemented (SQLite + pg +
mem); the review's characterization confirmed or corrected in
the record
- [x] The conscious-acceptance decision recorded per engine (or a
user-approved hygiene scope change, which would be a follow-up
task)
- [x] The notify prune-cadence note landed in the SQLite engine's docs
- [x] The acceptance substance positioned for the deployment-matrix
final pass to fold in
- [x] Workspace gates green (docs-only expected)
## References
- docs/reviews/001-waves-1-2-general-review.md §N-1, §7
- docs/architecture/deployment.md (Durability knobs; the matrix this
feeds)
- docs/architecture/engine-sqlite.md (the cadence-recipes home)
- docs/architecture/decisions/024-mem-engine.md (the mem postures new
since the review)
## Notes
- **Decision: conscious acceptance, all three paths, all three
engines.** No engine-side hygiene scope change proposed or wanted.
- **The review's characterization confirmed, with one sharpening per
path** (verified against code, not just docs):
- *Dead letters*: the characterization held, plus a sharpening the
review didn't state — retention enforcement has exactly **one
trigger**: a caller-driven `sweep_expired()` (`Queue` trait
method). Engines run no background retention sweeper (the pg
suite's comment says it outright: the sweep is "the only sweeper
dead rows ever have"). So growth is opted-in twice: retention
`None` by default, and no automatic cadence when it's set.
- *Notifications*: held — `NOTIFY_ATTACH_MAX_ROWS` = 10,000,
oldest-first, runs only at connection open (the substrate
bootstrap, `schema.rs`); the D-16 cap triggers **only** on a
fresh attach. Confirmed SQLite-only: pg has **no notifications
table** (`pg_notify` is transient, ≤ 8000 bytes; pg schema has no
such table). Upstream's `prune_notifications*` helpers were not
carried (ADR-008 §4's disposition), so attach is the only prune
site.
- *Stream*: held — no engine-side trim beyond the consumer-invoked
`trim_to` (ADR-015 §5's posture: default unbounded, documented
squarely).
- **The mem engine's postures (new since the review)**: its
notify/stream/dead growth is process-lifetime-bounded by design —
notify stores nothing (commit-boundary delivery to open receivers;
per-subscriber feeds are unbounded mpsc, ending at engine drop),
the stream log and dead table are in-memory state erased at process
exit. Accepted structurally rather than via caps; recorded in the
deployment.md acceptance.
- The acceptance record landed in `deployment.md` §"Growth postures
(consciously accepted)" with an explicit "this record is the input
the deployment-matrix final pass folds in" positioning; the notify
prune-cadence note landed in `engine-sqlite.md` §"Notifications-
table hygiene" (anchored heading — deployment.md links to it). No
internal task pointers in the release-facing text; the matrix pass
can fold the substance directly.
## Summary
Re-read the three growth paths against the implemented engines
(`alkstore-sqlite/src/substrate/schema.rs` (D-16 at-attach prune),
`queue_ops.rs` (`sweep_dead_retention` inside the savepoint guard,
sweep-on-call only), `alkstore-postgres/src/schema.rs` (no
notifications table), `queue.rs`/`stream.rs` sweep/trim shapes, and
`alkstore-mem/src/{notify,wakes,queue,stream}.rs`). Decision of record
(**all three accepted for v1, per engine**, no hygiene scope change):
landed in `docs/architecture/deployment.md` §"Growth postures
(consciously accepted)" (per-engine table + rationale, frontmatter
updated), and the notify prune-cadence note (attach is the only prune
site; idle-but-listening processes never prune) landed in
`docs/architecture/engine-sqlite.md` §"Notifications-table hygiene"
(frontmatter updated). Docs-only change; workspace gates green
(`cargo build`, `cargo test`, clippy `-D warnings`, fmt --check).