3.2 KiB
id, name, status, depends_on, scope, risk, impact, level, tags
| id | name | status | depends_on | scope | risk | impact | level | tags | |||
|---|---|---|---|---|---|---|---|---|---|---|---|
| sqlite-fix-watcher-death-subscribe | Dead-watcher subscribe hang + initial-stat self-kill (review 004 items 2+3) | pending | moderate | medium | component | implementation |
|
Description
Two bundled watcher-state defects in the SQLite engine, per
docs/reviews/004-pre-release-general-review.md §"Findings recorded,
not fixed" items 2 and 3 (the review says bundle them — both are
watcher-state changes).
(a) Post-watcher-death subscribe hang (item 2). After the watcher
thread exits (db-file replacement), subscribe() still enrolls new
senders with no poller alive (substrate/watcher.rs:391-396): a
listen() or stream subscribe() on the dead store parks forever,
contradicting engine-sqlite.md's "on watcher death every subscriber
closes" posture — which is enforced only for pre-death subscribers.
Fix shape: a dead-store/dead-watcher sign that the new subscription
paths consult — a state-machine change across store.rs/notify.rs/
stream.rs. New subscriptions on a dead store must fail closed (a
typed error, the established failure vocabulary) rather than park.
(b) Initial-stat failure self-kill (item 3). An identity-stat
failure at watcher start seeds (0, 0) (watcher.rs:164-170); the
first successful later stat mismatches it and drives the death path,
spuriously closing every subscriber on recovery from a transient stat
hiccup. Rare, but the fix — an identity-unknown state instead of a
false identity — is the same watcher-state family: the watcher treats
identity as unknown until the first successful stat, and that first
successful stat must not trigger the death path.
Test shapes: (a) kill the watcher (the db-file replacement seam or
a cfg(test) death injection), then listen()/subscribe() — assert
the typed failure, not a park; the pre-death subscribers' close-at-
death pins stay green. (b) inject an initial stat failure, let the
first successful stat land, assert the watcher survives and
subscribers stay open.
Acceptance Criteria
- Subscribing (listen or stream) after watcher death fails closed with a typed error instead of parking — pinned by test
- Pre-death subscribers still close at watcher death — the existing pins green unchanged
- An initial identity-stat failure no longer seeds a false identity: the first successful stat does not trigger the death path and subscribers stay open — pinned by injected-failure test
- engine-sqlite.md's watcher-death posture text covers the new-subscriber arm (and the identity-unknown state if it changes observable behavior)
cargo test -p alkstore-sqlite, clippy-D warnings, fmt clean; workspace gates green server-less
References
- docs/reviews/004-pre-release-general-review.md §"Findings recorded, not fixed" items 2–3 (the findings, the fix shapes, the bundling)
- docs/architecture/engine-sqlite.md (the watcher-death posture)
- alkstore-sqlite/src/substrate/watcher.rs (both sites), store.rs / notify.rs / stream.rs (the subscription paths)
Notes
To be filled by implementation agent
Summary
To be filled on completion