diff --git a/docs/plans/implementation.md b/docs/plans/implementation.md index 27c5a49..1e7ba56 100644 --- a/docs/plans/implementation.md +++ b/docs/plans/implementation.md @@ -1,10 +1,10 @@ --- status: draft -last_updated: 2026-10-10 (the fuzzing decision resolved: adopted and -inserted as wave 7 per docs/research/fuzzing.md; release readiness -renumbered to wave 8. Waves 1–6 implemented + reviewed; the wave-6 -gate passed with three inline edge-domain fixes, and Findings 2–3 and -the flake watch carry to the wave-8 pre-release pass.) +last_updated: 2026-10-10 (wave 8 decomposed — the release-readiness +task set: seven independent entry tasks incl. the frontmatter cleanup +and the renumber sweep, then matrix → README → publish prep → gate. +Waves 1–7 implemented + reviewed; Findings 2–3, the fired flake-watch +trigger, and the class-1 window's last dispositions ride wave 8.) --- # alkstore — Implementation plan @@ -50,7 +50,7 @@ readiness is wave 8. | 5 | [Contract suite](#wave-5--contract-suite): the cross-engine equivalence properties (core-contract.md §Verification backlog), version-stamped per ADR-017 | waves 3 + 4 | implemented + reviewed (2026-10-10) | | 6 | [Mem engine](#wave-6--mem-engine): separate `alkstore-mem` crate, full contract v1 over in-memory mechanisms (tx overlay, queue/scheduler/streams/locks/wakes), the suite's third factory column (born pinned), wasm32 compile-clean acceptance | waves 1 + 5 | implemented + reviewed (2026-10-10) | | [7](#wave-7--fuzzing) | [Fuzzing](#wave-7--fuzzing): the `fuzz/` sidecar workspace (cargo-fuzz targets over the payload codec, the three `@every` parsers, name validation), committed seed corpora + the corpus-replay gate, detached campaigns | wave 6 | implemented + reviewed (2026-10-10) | -| [8](#wave-8--release-readiness) | [Release readiness](#wave-8--release-readiness): crate docs, deployment matrix final pass, README (written last, honestly), publish prep | wave 7 | not yet decomposed | +| [8](#wave-8--release-readiness) | [Release readiness](#wave-8--release-readiness): crate docs, deployment matrix final pass, README (written last, honestly), publish prep | wave 7 | decomposed (2026-10-10) | ## Wave 1 — Foundations @@ -468,6 +468,78 @@ family's renumber-annotation precedent (`tasks/review-wave-5.md`'s ADR-024 annotations), affected records get swept (or annotated) when wave 8 decomposes — history is not rewritten in place. +**Wave 8's task set** (the decomposition, 2026-10-10 — the carried +items ride as their own tasks; the gate closes the wave): + +- `docs-frontmatter-cleanup` — the user-flagged easy win: 11 docs + carry invalid YAML frontmatter (unquoted multi-line `last_updated` + values containing `: ` sequences — plain scalars can't carry them; + verified by a PyYAML parse sweep). Quote the values, prose verbatim; + parse sweep green. +- `release-renumber-sweep` — the historical note's mandate, executed: + the stale "wave 7"-means-release-pass references in review + 001/002/003 and the wave-3..6 task files annotated (or reworded + where the reference is a live pointer), genuine fuzz-wave + references untouched. +- `release-crate-docs` — the four published crates' public-API + rustdoc: `cargo doc` warning-free, missing-docs audit, accuracy + spot-checks against core-contract.md / deployment.md (core's docs + are contract text), the doc-hidden fuzz re-exports documented as + fuzz/test-only, the example-carrier decision. +- `release-contract-window-close` — ADR-017 §2's class-1 window + terminates at first release, so the wave-6 gate's recorded + observations dispose now or never: the multi-thread publish→wake + ordering tolerance (documented-tolerance vs ADR amendment — raised + with the user), the ADR-023 §2 classifications (`heartbeat(extend)`, + `save_offset`), the `EventReceiver::try_recv` closed shape, the + `get_job` prose fix, the mem-arithmetic note's disposition. +- `release-n1-growth-posture` — review 001's N-1 consciously accepted + (or a user-approved hygiene scope change) against the implemented + engines; the notify prune-cadence note lands in the SQLite engine's + docs. +- `release-findings-2-3-disposition` — review 003's parked pair: the + cheap seams land (Finding 2's death-during-LISTEN arm; Finding 3's + rollback-fault arm on the existing commit-fault seam), the + race-shaped arm stays parked with its disposition recorded. +- `release-flake-investigation` — the wave-5 ledger's trigger fired + (the lock row's second failure, 2026-10-10): the dedicated + investigative session the ledger prescribes — instrument the + output-capture blind spot first, focused repro loop across the + conditions matrix, disposition recorded (repro → follow-up fix + task; no-repro → bounded-investigation record + watch posture + updated). +- `release-deployment-matrix` — deployment.md row-by-row against the + three implemented engines as release text; the env-variable + boundary re-check (review 003's prepublish item) + the pinning + sentence; N-1's acceptance folded; internal task/wave pointers + leave the release-facing text. +- `release-readme` — the root README (written last, honestly — its + dependencies are the wave's doc-shaped tasks), LICENSE-MIT + + LICENSE-APACHE (the family pattern; none exist yet), the CHANGELOG + seed, the per-crate readme wiring decision. +- `release-publish-prep` — package metadata (descriptions are missing + on all four published crates), `cargo package` verification per + crate, the wave-7-parked publish-exclusion *verification* (no + published package leaks the sidecar), path-dep version bounds + + publish-order records, the substrate's PROVENANCE/license packaging + check, the manual publish checklist of record (the actual + `cargo publish` is the user's post-gate action). +- `review-wave-8` — the pre-release gate: docs honesty audit, the + contract-window closure audit + the class-1 termination record, the + N-1/findings dispositions, the flake outcome, the publish-prep + audit, the hygiene sweeps re-run, all gates green (incl. the fuzz + replay + wasm + doc gates), and the remaining `draft` architecture + docs flipped `stable`. + +Parallelism note: six tasks are independent entry points (frontmatter, +renumber sweep, crate docs, contract window, N-1, findings 2–3, flake +investigation — seven counting them all); the deployment matrix +depends on N-1; the README depends on the doc-shaped tasks (written +last); publish prep depends on the README + the flake outcome; the +gate depends on everything. The flake investigation and the findings +disposition are the only code/test-side tasks — everything else is +docs, records, and packaging. + ## Decided points - **Contract-suite layout — option (a)**: a small internal @@ -663,6 +735,15 @@ decomposes. Specific gates: wiring (the AGENTS.md flip) → review gate. Seven tasks; the every-parse differential is the load-bearing one (the wave-6 finding class). See the Wave 7 section. +- **Wave-8 decomposition** (2026-10-10) — the pre-release pass: seven + independent entry tasks (the user-flagged frontmatter cleanup — 11 + docs with invalid YAML frontmatter, verified by parse sweep; the + renumber sweep the historical note mandated; crate docs; the + class-1 window's last dispositions; N-1; Findings 2–3; the flake + investigation the ledger's fired trigger owes), then the deployment + matrix → README → publish prep chain, then the gate. Two tasks are + code/test-side (findings 2–3, flake investigation); the rest is + docs, records, and packaging. See the Wave 8 section. - **Wave-4 fix-batch decomposition** (2026-10-09) — the general review's findings decomposed into seven `pg-fix-*` tasks + a `review-wave-4-fixes` gate: Finding 1 → `pg-fix-forwarder-reconnect` diff --git a/tasks/docs-frontmatter-cleanup.md b/tasks/docs-frontmatter-cleanup.md new file mode 100644 index 0000000..6d9bb91 --- /dev/null +++ b/tasks/docs-frontmatter-cleanup.md @@ -0,0 +1,72 @@ +--- +id: docs-frontmatter-cleanup +name: Docs frontmatter cleanup — the 11 invalid YAML frontmatters +status: pending +depends_on: [] +scope: single +risk: trivial +impact: isolated +level: implementation +tags: [wave-8, docs, hygiene] +--- + +## Description + +Eleven docs carry invalid YAML frontmatter: the `last_updated` values +are unquoted multi-line plain scalars containing `: ` (colon+space) +sequences — which YAML plain scalars cannot carry — so frontmatter +parsers fail on them. The affected files (verified this session with a +PyYAML parse sweep over `docs/**/*.md`): + +- `docs/architecture/README.md` +- `docs/architecture/core-contract.md` +- `docs/architecture/deployment.md` +- `docs/architecture/engine-mem.md` +- `docs/architecture/engine-postgres.md` +- `docs/architecture/engine-sqlite.md` +- `docs/architecture/overview.md` +- `docs/architecture/queues.md` +- `docs/plans/implementation.md` +- `docs/research/consumer-inventory.md` +- `docs/research/phase-0.md` + +The fix is quoting (the annotation prose is content — keep it verbatim; +the family's alksocks docs use the same multi-line annotation style and +parse fine, so the style is fine, only the quoting is missing). Choose +the quoting that survives the values' own characters: several values +contain apostrophes (`trim_to's`) and em-dashes; double quotes with +`"` escaped (none observed) or single quotes with `''` escaping both +work — pick one convention and apply it uniformly. Do not reword or +trim the annotations. + +While in the sweep: confirm every other frontmatter-carrying doc under +`docs/` parses (the POC spec/findings docs already do) and confirm the +`tasks/*.md` frontmatters still parse and `taskgraph validate` stays +green (they are valid today — do not touch them beyond what the parse +check demands). + +## Acceptance Criteria + +- [ ] All 11 listed files' frontmatter parses as valid YAML (a + scripted parse sweep over `docs/**/*.md` reports zero failures), + with the `last_updated` annotation prose preserved verbatim +- [ ] One quoting convention applied uniformly across the fixed files +- [ ] `taskgraph validate` still green; no `tasks/*.md` content changed +- [ ] The parse sweep command recorded in Notes so future sessions can + re-run it + +## References + +- docs/plans/implementation.md §Wave 8 (this cleanup rides the + pre-release pass) +- docs/architecture/engine-sqlite.md (an example of the invalid + pattern, `status: stable` — the fix must not disturb the status + fields the review gates set) + +## Notes + +> To be filled by implementation agent + +## Summary + +> To be filled on completion \ No newline at end of file diff --git a/tasks/release-contract-window-close.md b/tasks/release-contract-window-close.md new file mode 100644 index 0000000..cc8d9d2 --- /dev/null +++ b/tasks/release-contract-window-close.md @@ -0,0 +1,99 @@ +--- +id: release-contract-window-close +name: Class-1 window's last dispositions — the wave-6 recorded observations +status: pending +depends_on: [] +scope: moderate +risk: medium +impact: project +level: implementation +tags: [wave-8, contract, adr] +--- + +## Description + +ADR-017 §2's class-1 amend-in-place window **terminates permanently at +the core crate's first release** — this pre-release pass is the last +chance to land the contract-text dispositions the wave-6 review gate +recorded for it (`tasks/review-wave-6.md` §Recorded findings). Land +each as either contract/ADR text (a class-1 amendment, legal only +now) or an explicit documented-tolerance record — no silent divergence +survives into the release: + +1. **Multi-thread publish→wake ordering tolerance** (streams): offset + allocation precedes insert+wake, so two concurrent publishes can + complete out of offset-allocation order and a subscriber's cursor + can skip an event whose wake fires later (the event is never lost + from the log). Nothing contract-side pins wake-fire order vs offset + order; the SQL engines share the shape in principle. Decide: + document as a tolerated ordering (where — core-contract.md's + delivery-guarantee table is the natural home) or amend as ADR text + (wake order per stream = offset order — the heavier path, and one + the mem engine's current-thread posture doesn't exercise). **Raise + the recommendation with the user before landing** — this is a + consumer-visible guarantee decision, exactly the class AGENTS.md + says to escalate. +2. **ADR-023 §2 domain-table classifications** (all three engines + uniform; the table is the contract's numeric-domain record): + `heartbeat(extend)`'s seconds-shaped argument (boundary-total + today: saturating/SQL add — a negative shortens/voids the claim); + `save_offset`'s argument (negatives accepted, stored, reads resume + forward; monotone no-op below the checkpoint); and pick the right + home for each. +3. **`EventReceiver::try_recv`'s closed shape**: `Err(Closed)` + (mirrors `WakeReceiver::try_recv`, ADR-008 §3) — mem-test-pinned + today; ADR-021 §5 pins only `recv()`'s arms. Annotate the pinned + shape. +4. **`get_job` id-global vs queue-scoped prose**: core-contract.md's + "queue-scoped" handle phrasing reads as a filter but the uniform + behavior is id-global lookup (`get_job_tx` *is* queue-filtered). + Fix the prose so the contract says what all three engines do. +5. **Mem-arithmetic transplant note**: dispose the recorded + one-owner-rule observation (the mem copies are byte-level + transplants of the SQLite implementations; equivalence is + suite-pinned three-way) — likely a no-action disposition recorded + in the task Notes, but the record should say so explicitly. + +Every landed amendment follows the ADR amendment discipline (dated +in-place annotation citing this pass; the suite's stamps accumulate if +a row's cited § text changes meaning). Items 2–3 may add suite stamp +citations — check whether any existing row's stamp needs the +accumulation. + +## Acceptance Criteria + +- [ ] Item 1 decided with the user (documented-tolerance vs ADR + amendment), landed in the chosen home, decision recorded +- [ ] ADR-023 §2 table carries the `heartbeat(extend)` and + `save_offset` classifications (or the task records why a + different home was chosen) +- [ ] `EventReceiver::try_recv`'s closed shape pinned in contract text +- [ ] core-contract.md's `get_job` prose matches the uniform + id-global/`get_job_tx`-filtered behavior +- [ ] The mem-arithmetic observation's disposition recorded +- [ ] Every landed amendment dated + cited; affected suite stamps + checked for accumulation; `taskgraph validate` + workspace gates + green (docs-only changes expected — code changes only if the + user opts to amend wake-ordering into an enforced guarantee, + which would be a follow-up, not this task) + +## References + +- docs/architecture/decisions/017-contract-versioning.md §2 (the + class-1 window and its first-release termination) +- tasks/review-wave-6.md §Recorded findings (the observations this + task disposes) +- docs/architecture/core-contract.md (delivery-guarantee table; + §Verification backlog) +- docs/architecture/decisions/023-fourth-review-round.md §2 (the + domain table) +- docs/architecture/decisions/021-tx-reads-and-value-shape-fixes.md §5 + (the receiver arms text) + +## Notes + +> To be filled by implementation agent + +## Summary + +> To be filled on completion \ No newline at end of file diff --git a/tasks/release-crate-docs.md b/tasks/release-crate-docs.md new file mode 100644 index 0000000..61f4941 --- /dev/null +++ b/tasks/release-crate-docs.md @@ -0,0 +1,84 @@ +--- +id: release-crate-docs +name: Crate docs final pass — rustdoc across the four published crates +status: pending +depends_on: [] +scope: moderate +risk: low +impact: component +level: implementation +tags: [wave-8, docs, rustdoc] +--- + +## Description + +The plan's wave-8 "crate docs" item: the public-API rustdoc of the +four published crates (`alkstore`, `alkstore-sqlite`, +`alkstore-postgres`, `alkstore-mem`) gets its release pass. The crate +docs are load-bearing — core's doc text is part of the contract +artifact (ADR-001 §1; AGENTS.md: "core's docs are part of the +contract") and the engine crates' lib docs carry the ADR-016 honesty +postures — so this is an accuracy-and-completeness pass, not prose +polish. + +1. **Build clean**: `cargo doc --no-deps` (workspace) zero warnings — + broken intra-doc links, ambiguous links, missing docs. Also + `RUSTDOCFLAGS="-D warnings" cargo doc --no-deps` as the recorded + gate posture. +2. **Missing-docs audit**: every public item (traits, trait methods, + types, variants, fields, functions — including the `#[doc(hidden)]` + re-exports the fuzz wave added at the three engine roots, which + must stay documented as fuzz/test-only surfaces) carries doc text; + gaps filled. Consider whether `#![deny(missing_docs)]` (or + `warn`) is warranted per crate — decide and record; adding it is + the enforcement posture, skipping it needs a reason. +3. **Accuracy spot-check against the specs**: core's trait/type doc + text read against `core-contract.md` (the docs are contract text — + a drift is a defect); each engine's lib-doc posture claims + (writer-parking, connection budget, honest-ephemeral, wasm subset) + read against `deployment.md` and the engine specs. The wave-6 + gate's inline doc fixes are the precedent for the honesty standard. +4. **Crate-level `//!` docs**: each published crate's root module doc + names its posture, its ADR charter, and (for engines) its + deployment boundary — verify all four do, fill what's missing. +5. **Examples**: core's public surface has no doctest examples; decide + whether a minimal compile-checked example (a `MemStore` open + + one mechanism round-trip) belongs in the core or mem crate docs — + the honest-ephemeral engine is the zero-config one, so it is the + natural example carrier. Either land it or record the not-taken + call. + +## Acceptance Criteria + +- [ ] `cargo doc --no-deps` (workspace) zero warnings; the + `-D warnings` doc gate posture recorded +- [ ] Missing-docs audit recorded (public items × 4 crates); gaps + filled; the `#![deny(missing_docs)]` decision made and recorded +- [ ] Core doc text spot-checked against core-contract.md; engine + lib-doc posture claims spot-checked against deployment.md — + drifts fixed or recorded +- [ ] The doc-hidden fuzz re-exports documented as fuzz/test-only at + all three engine roots +- [ ] The example decision made (landed or recorded not-taken) +- [ ] Workspace gates green (`cargo build`, `cargo test`, clippy + `-D warnings`, fmt) + +## References + +- docs/plans/implementation.md §Wave 8 +- docs/architecture/core-contract.md (the contract the core docs must + match) +- docs/architecture/deployment.md (the matrix the engine posture docs + must match) +- docs/architecture/decisions/016-deployment-honesty.md (the honesty + carriers) +- docs/architecture/decisions/024-mem-engine.md §5 (the wasm identity + the mem crate docs carry) + +## Notes + +> To be filled by implementation agent + +## Summary + +> To be filled on completion \ No newline at end of file diff --git a/tasks/release-deployment-matrix.md b/tasks/release-deployment-matrix.md new file mode 100644 index 0000000..afe6670 --- /dev/null +++ b/tasks/release-deployment-matrix.md @@ -0,0 +1,76 @@ +--- +id: release-deployment-matrix +name: Deployment matrix final pass — all three engines, release text +status: pending +depends_on: [release-n1-growth-posture] +scope: moderate +risk: low +impact: component +level: implementation +tags: [wave-8, docs, deployment] +--- + +## Description + +The plan's wave-8 "deployment matrix final pass (across all three +engines now)": `docs/architecture/deployment.md` read row-by-row +against the three implemented engines and finalized as release text — +the document is ADR-016's honesty carrier (with the engine crates' +own docs), so every row must be true as implemented, not as designed. + +1. **Row-by-row verification**: host semantics, connection budgets + (SQLite writer/reader/watcher; pg `max_size` + the non-pooled + listener; mem's none), durability knobs, TLS posture (v1), + toolchain/platform notes (incl. the mem wasm32 row), consumer- + obligation notes on engine options, and the latency profile's + "indicative, POC-measured" honesty (POC-measured numbers published + as indicative — confirm the caveat text is still accurate or + refresh it against the contract suite's existence). +2. **The env-variable boundary pin** (review 003's explicit + re-check-at-prepublish item): re-run the no-env-in-production grep + across the workspace (review 003 §Env-variable boundary has the + method + the prior result), confirm every `env::var` read still + lives in a test target, and pin the boundary in one sentence in + deployment.md (and the engine specs if the sentence belongs there + too): "env reads are harness-only; production configuration is the + opts-constructor surface." +3. **Fold N-1's outcome**: the growth-posture acceptance + (`release-n1-growth-posture`'s record) lands in the matrix's + durability/growth text. +4. **The mem rows' final honesty check**: ADR-024 landed them at + adoption; the wave-6 gate read them true — this pass re-reads them + as release text (ephemerality, isolation, wasm toolchain note). +5. **Release-text quality**: the document should stand alone for a + deployer sizing any of the three engines — no dangling references + to waves/tasks/POCs that a consumer wouldn't have context for + (POC-measured caveats stay, internal task pointers go). + +## Acceptance Criteria + +- [ ] Every deployment.md row verified true as implemented across the + three engines; corrections landed +- [ ] The env-boundary grep re-run (result recorded) + the boundary + sentence pinned in deployment.md +- [ ] N-1's acceptance folded into the growth/durability text +- [ ] The mem rows re-read as release text +- [ ] No internal-task/wave pointers remain in the release-facing text + (POC-measured caveats excepted) +- [ ] Workspace gates green (docs-only expected) + +## References + +- docs/architecture/deployment.md (the document) +- docs/architecture/decisions/016-deployment-honesty.md (the carrier + mandate) +- docs/reviews/003-wave-5-general-review.md §Env-variable boundary + (the re-check item + method) +- tasks/release-n1-growth-posture.md (the input this pass folds) +- docs/architecture/engine-mem.md (the mem rows' spec source) + +## Notes + +> To be filled by implementation agent + +## Summary + +> To be filled on completion \ No newline at end of file diff --git a/tasks/release-findings-2-3-disposition.md b/tasks/release-findings-2-3-disposition.md new file mode 100644 index 0000000..9837d9d --- /dev/null +++ b/tasks/release-findings-2-3-disposition.md @@ -0,0 +1,75 @@ +--- +id: release-findings-2-3-disposition +name: Review 003 Findings 2–3 — the parked pre-release dispositions +status: pending +depends_on: [] +scope: narrow +risk: low +impact: component +level: implementation +tags: [wave-8, tests, sqlite-engine, postgres] +--- + +## Description + +Review 003's Findings 2–3, parked to the pre-release pass by the +wave-6 gate (`docs/reviews/003-wave-5-general-review.md`; the park +trail: `tasks/review-wave-6.md` §Rider closed). The review's own +recommendation shapes the task — the cheap seams land, the +race-shaped arm stays parked with its disposition recorded, so the +next general review does not re-derive the inventory: + +- **Finding 2 (LOW, pg forwarder narrow untested arms)**: land the + cheap seam for (a) — the "connection died before/during the LISTEN" + fall-through to the reconnect path (`forwarder.rs:693-698`) — using + the house `cfg(test)` seam pattern (`pg-fix-forwarder-reconnect`'s + config seam; `sqlite-commit-error-arm`'s one-shot flag). The + mid-recv-loop stale-command abandonment race arm (b) + (`forwarder.rs:719-727`) and the small defensive arms + (`mid_listen_error` ack, forwarder-gone, shutdown abort/await) stay + parked with the code-read as their pin — **record that disposition + explicitly** (the review's "either way the disposition should be + recorded"). +- **Finding 3 (LOW, SQLite rollback-failure-on-drop arms)**: a + rollback-fault arm on the existing commit-fault seam + (`alkstore-sqlite/src/seam.rs` — the `sqlite-commit-error-arm` + machinery) covering both drop arms in one small test: + `SqliteTxHandle::drop`'s failed-`ROLLBACK` path (`tx.rs:439-447`) and + `ConnLease::drop`'s (`tx.rs:166-175`) — pin the same properties the + commit test pins (error surfaced/printed, connection dropped, writer + slot replenished, store usable). + +If a seam proves more invasive than the review estimated, the +acceptable fallback is the code-read-as-pin disposition for that arm — +recorded, not silent. The line between "landed" and "parked with +disposition" is this task's judgment call, made explicitly in Notes. + +## Acceptance Criteria + +- [ ] Finding 2's (a) arm seam-tested (or its not-taken disposition + recorded with the invasiveness reason); the race arm + defensive + arms' parked disposition recorded +- [ ] Finding 3's rollback-fault test landed covering both drop arms + (or its not-taken disposition recorded) +- [ ] The disposition record written so a future general review reads + the inventory as closed, not re-derivable +- [ ] `cargo test -p alkstore-sqlite` green server-less; `cargo test + -p alkstore-postgres` green server-less (SKIP posture) and — if + the pg seam landed — green against the harness server; clippy + `-D warnings`; fmt clean + +## References + +- docs/reviews/003-wave-5-general-review.md §Finding 2, §Finding 3 +- tasks/review-wave-6.md (the park record) +- tasks/sqlite-commit-error-arm.md (the seam pattern + the commit-arm + test this mirrors) +- tasks/pg-fix-forwarder-reconnect.md (the pg config-seam precedent) + +## Notes + +> To be filled by implementation agent + +## Summary + +> To be filled on completion \ No newline at end of file diff --git a/tasks/release-flake-investigation.md b/tasks/release-flake-investigation.md new file mode 100644 index 0000000..3de37fc --- /dev/null +++ b/tasks/release-flake-investigation.md @@ -0,0 +1,91 @@ +--- +id: release-flake-investigation +name: Flake investigation — the pg lock-row trigger fired (dedicated session) +status: pending +depends_on: [] +scope: moderate +risk: medium +impact: component +level: implementation +tags: [wave-8, postgres, flake-watch] +--- + +## Description + +The wave-5 gate's flake-watch flag, carried to this pass +(`docs/plans/implementation.md` §Wave 8; `tasks/review-wave-5.md` +§Notes 6). The watch's trigger has **fired**: +`row_lock_ttl_expiry_and_reacquisition` failed a second time (the +ledger update, 2026-10-10, from the `pg-fix-scheduler-fire-wake` +session — one occurrence in one full sequential pg suite run, failure +message lost to output filtering, then green on two subsequent full +runs and six focused runs). Per the ledger's own prescription, a +**dedicated investigative session (instrumentation + focused repro +loop) is owed before any postulate-and-fix**. The trim row +(`row_trim_to_semantics`, one development-time failure) stays +watch-flagged; if it reproduces in this session's loops, it joins the +investigation. + +The investigation's shape (the ledger's terms, not a +postulate-and-fix license): + +1. **Instrument first**: capture the failing row's full assertion + output (the prior failures' messages were lost to truncation/filtering + — fix that blind spot before anything else: run with + `--nocapture`, or a file-tee'd harness, or a retry-wrapper that + preserves output on failure). +2. **Focused repro loop**: the row under stress — many consecutive + runs, varied `--test-threads`, solo vs concurrent-with-SQLite-column, + cold vs warm server — the conditions matrix the two prior + occurrences happened under (cold first run; full sequential run). + A deliberate slow-clock/lapse-boundary probe (the row's lapse + assertions are post-sleep states a slower clock can only delay, + never un-lapse — verify that argument by reading the row's actual + sleep/tolerance arithmetic against the engine's lock expiry + implementation, not by trusting it). +3. **Disposition**: either (a) reproduced → root-cause analysis → the + fix is its own follow-up task (engine bug vs harness-model, called + explicitly — the review-002 precedent is that a "flake" was a real + engine bug); or (b) not reproduced → the bounded-investigation + record (conditions matrix, instrumented output, the read-back of + the delay-only argument) with the watch posture updated (keep + watching vs instrument permanently vs accept). Both outcomes are + acceptable task completions; an uninvestigated shrug is not. + +Requires the harness Postgres server (the POC container posture — +`docs/reviews/003-wave-5-general-review.md` §Op note has the env). + +## Acceptance Criteria + +- [ ] The output-capture blind spot fixed (a failing run's assertion + message is preserved by the recorded procedure) +- [ ] The conditions matrix actually run (counts + configurations + recorded in Notes) +- [ ] The row's sleep/tolerance arithmetic read against the pg lock + expiry implementation; the delay-only argument confirmed or + corrected +- [ ] Disposition recorded: reproduced (→ root cause + follow-up task + created) or not-reproduced (→ bounded-investigation record + + watch posture updated) +- [ ] If the trim row reproduces: it joins the investigation and its + outcome is recorded too +- [ ] Workspace gates green at session end (any fix is a follow-up + task, not a ride-along — unless the root cause is trivially + test-side, in which case fix + full gates + Notes) + +## References + +- tasks/review-wave-5.md §Notes 6 (the ledger + the trigger update) +- docs/plans/implementation.md §Wave 8 (the watch carriage) +- docs/reviews/003-wave-5-general-review.md (the concurrence read + + the harness-credentials op note) +- docs/reviews/002-wave-4-general-review.md (the flake-was-a-real-bug + precedent, F-1) + +## Notes + +> To be filled by implementation agent + +## Summary + +> To be filled on completion \ No newline at end of file diff --git a/tasks/release-n1-growth-posture.md b/tasks/release-n1-growth-posture.md new file mode 100644 index 0000000..d5fd578 --- /dev/null +++ b/tasks/release-n1-growth-posture.md @@ -0,0 +1,79 @@ +--- +id: release-n1-growth-posture +name: N-1 growth-posture review — conscious acceptance (or hygiene) +status: pending +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 + +- [ ] The three growth paths re-read as implemented (SQLite + pg + + mem); the review's characterization confirmed or corrected in + the record +- [ ] The conscious-acceptance decision recorded per engine (or a + user-approved hygiene scope change, which would be a follow-up + task) +- [ ] The notify prune-cadence note landed in the SQLite engine's docs +- [ ] The acceptance substance positioned for the deployment-matrix + final pass to fold in +- [ ] 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 + +> To be filled by implementation agent + +## Summary + +> To be filled on completion \ No newline at end of file diff --git a/tasks/release-publish-prep.md b/tasks/release-publish-prep.md new file mode 100644 index 0000000..03cf9ab --- /dev/null +++ b/tasks/release-publish-prep.md @@ -0,0 +1,93 @@ +--- +id: release-publish-prep +name: Publish prep — package verification, exclusion check, publish records +status: pending +depends_on: [release-readme, release-flake-investigation] +scope: moderate +risk: medium +impact: project +level: implementation +tags: [wave-8, publish] +--- + +## Description + +The plan's wave-8 "publish prep": everything short of the manual +`cargo publish` itself (CI and publishing are manual per the plan's +decided points — self-hosted Gitea, supply-chain posture; the actual +publish is the user's action, post-gate). + +1. **Package metadata audit**: the four published crates currently + carry only version/edition/license/repository — `description` is + missing on all four (crates.io requires it). Land honest + descriptions per crate; decide the remaining optional fields + (`keywords`, `categories`, `homepage`/`docs` — the family's + published crates are the precedent to check) and record the + decisions. +2. **`cargo package` verification per published crate** (`alkstore`, + `alkstore-sqlite`, `alkstore-postgres`, `alkstore-mem`): each + packages clean (no warnings that block, `.crate` contents + inspected), builds + tests from the packaged source + (`cargo package --no-verify` off — let it verify, or verify + manually per crate and record which). +3. **The publish-exclusion verification** (parked from wave 7 — + `tasks/review-wave-7.md` item 4(iii)): the mechanism + (`exclude = ["fuzz"]` on the root workspace) landed; this is the + verification that **no published package leaks the sidecar** — + inspect each `.crate`'s file list: no `fuzz/` paths, no + `alkstore-fuzz-shared` references, no grown corpora/artifacts. + Also verify `alkstore-contract-suite` (`publish = false`) and the + fuzz sidecar are absent from any package. +4. **Path-dep + version records**: the engines' `alkstore = { version + = "0.1", path = … }` shape is publish-legal (version bound present) + — verify each path dep carries its version bound; record the + publish order (core first, then engines — ADR-017 §4.1's pairing) + and the version decision (0.1.0 as contract v1's initial release, + per ADR-017's semver-is-the-contract discipline) in the task Notes + as the publish checklist of record. +5. **Substrate packaging check** (ADR-013/018): `alkstore-sqlite`'s + package includes the in-tree substrate — verify `PROVENANCE.md` and + the dual-license notice ride in the `.crate`, and the package is + honest about carrying them. +6. **The publish checklist of record**: a Notes section listing the + exact manual commands in order (per crate: package → publish), + including the dry-run evidence, so the user's publish session is + mechanical. + +## Acceptance Criteria + +- [ ] `description` landed on all four published crates; optional + metadata decisions recorded +- [ ] `cargo package` clean per published crate (verification posture + recorded); `.crate` contents inspected +- [ ] Publish-exclusion verification recorded: no fuzz/sidecar/ + contract-suite paths in any package's file list +- [ ] Path-dep version bounds verified; publish order + version + decision recorded +- [ ] Substrate PROVENANCE + license notice confirmed in the + `alkstore-sqlite` package +- [ ] The manual publish checklist of record written (commands in + order, evidence attached) +- [ ] Workspace gates + the fuzz corpus-replay gate green at session + end + +## References + +- docs/plans/implementation.md §Wave 8, §Decided points (CI/publishing + manual) +- tasks/review-wave-7.md (the parked exclusion verification, item 4) +- docs/architecture/decisions/017-contract-versioning.md §4.1 (the + version pin + pairing) +- docs/architecture/decisions/013-fold-substrate-into-sqlite.md + + docs/architecture/decisions/018-provenance-register-and-cherry-picks.md + (the in-tree substrate's packaging posture) +- docs/architecture/decisions/022-contract-suite-layout.md (the suite + is not published) + +## Notes + +> To be filled by implementation agent + +## Summary + +> To be filled on completion \ No newline at end of file diff --git a/tasks/release-readme.md b/tasks/release-readme.md new file mode 100644 index 0000000..053de4a --- /dev/null +++ b/tasks/release-readme.md @@ -0,0 +1,78 @@ +--- +id: release-readme +name: Crate README (written last, honestly) + LICENSE + CHANGELOG +status: pending +depends_on: [release-crate-docs, release-deployment-matrix, release-contract-window-close, release-findings-2-3-disposition, release-n1-growth-posture] +scope: narrow +risk: low +impact: component +level: implementation +tags: [wave-8, docs, readme] +--- + +## Description + +The plan's wave-8 "crate README (written last, honestly)" — the root +`README.md` does not exist yet, and it is written *last* so it +describes the shipped thing, not the intended one. Its dependencies +are the wave's other doc-shaped tasks for exactly that reason. + +1. **`README.md`** (root, the crates.io-facing front page): what + alkstore is (one reactive store interface — notify, streams, + queues, locks, scheduler, outbox — over SQLite, Postgres, and the + in-process mem engine), the crate family table (which crate to + pick, per ADR-016's compile-time engine identity), the honest + posture lines per engine (single-host file-backed / multi-host / + honest-ephemeral, never fleet-valid), a minimal usage sketch + (compile-checked against the real API — the mem engine is the + zero-config example carrier), the contract-suite pointer (three + engines, one pinned contract), and the license note. No + aspirational claims: only what waves 1–7 shipped. +2. **LICENSE files**: `LICENSE-MIT` + `LICENSE-APACHE` at the root per + the family pattern (alkcall/alksocks ship both; the workspace + `license = "MIT OR Apache-2.0"` field is set but no license files + exist). The substrate's in-tree dual-license notice (ADR-018) stays + as landed — the root files do not replace it. +3. **`CHANGELOG.md`**: seeded per the family pattern — the 0.1.0 + initial-release entry summarizing the contract v1 surface and the + three engines (honest, brief; the family's changelogs are + release-note-shaped, not commit logs). +4. **Per-crate readme wiring**: decide whether each published crate's + `[package] readme` points at the root README or gets its own short + crate-specific readme (the engines' lib docs already carry their + posture — a pointer-style per-crate readme is the likely honest + shape); land the decision. +5. **Honesty cross-check**: every README claim traceable to a spec + (core-contract.md, deployment.md, the engine specs) — this is the + "written last, honestly" discipline, and the review gate will + audit it. + +## Acceptance Criteria + +- [ ] Root `README.md` exists: family table, per-engine honest + postures, compile-checked usage sketch, suite pointer, license + note; no aspirational/unshipped claims +- [ ] `LICENSE-MIT` + `LICENSE-APACHE` at the root (MIT + Apache-2.0 + canonical texts); ADR-018's in-tree substrate notice untouched +- [ ] `CHANGELOG.md` seeded with the 0.1.0 entry +- [ ] The per-crate readme wiring decided + landed +- [ ] Every README claim traceable to a spec (the trace list in Notes) +- [ ] Workspace gates green (docs-only expected) + +## References + +- docs/plans/implementation.md §Wave 8 (written last, honestly) +- docs/architecture/overview.md (the family/feature source) +- docs/architecture/deployment.md (the posture lines) +- docs/architecture/decisions/016-deployment-honesty.md, + docs/architecture/decisions/018-provenance-register-and-cherry-picks.md +- /workspace/@alkdev/alkcall/README.md + CHANGELOG.md (the family + pattern) + +## Notes + +> To be filled by implementation agent + +## Summary + +> To be filled on completion \ No newline at end of file diff --git a/tasks/release-renumber-sweep.md b/tasks/release-renumber-sweep.md new file mode 100644 index 0000000..020debb --- /dev/null +++ b/tasks/release-renumber-sweep.md @@ -0,0 +1,76 @@ +--- +id: release-renumber-sweep +name: Renumber sweep — historical "wave 7" references to the release pass +status: pending +depends_on: [] +scope: narrow +risk: trivial +impact: isolated +level: implementation +tags: [wave-8, docs, records] +--- + +## Description + +The plan's historical note (§Wave 8): records written before the +second renumber — review 001/002/003 and the wave-3..6 task files — +say "wave 7" where they mean the release pass, which is now wave 8. +Per the family's renumber-annotation precedent +(`tasks/review-wave-5.md`'s ADR-024 annotations), affected records get +swept (or annotated) when wave 8 decomposes — history is not rewritten +in place. + +Sweep the corpus for the stale references and dispose each: annotate +in place (the precedent — a bracketed "(wave 8 since the fuzzing +wave's renumber)" style note) where the record is historical and its +wave-7 phrasing is load-bearing context; reword only where the +reference is a live pointer (e.g. a task's References section pointing +a future reader at the wrong wave). Known affected sites (start the +sweep from these, then grep for more): + +- `docs/reviews/001-waves-1-2-general-review.md` (the header note's + "release-readiness N-1 review — wave 7 since ADR-024's renumbering"; + §7's wave-6 release-review bullet) +- `docs/reviews/003-wave-5-general-review.md` (the Recommendation + section's renumber trail; the flake-watch echo's "wave 7 since + ADR-024's renumbering") +- `tasks/review-wave-5.md` (Notes §6's "flagged for watch in the next + wave window (release readiness at gate time — since renumbered to + wave 7…)" and the ledger update's "wave-7 watch carriage") +- `tasks/review-wave-6.md` (Findings 2–3 "parked for wave 7"; the + recorded observations' "wave-7 pre-release pass" pointers) +- wave-3..6 task files whose Notes/Summary cite the release pass as + wave 7 (grep `wave 7` / `wave-7` across `tasks/`, excluding the + genuine wave-7 fuzz tasks — `fuzz-*` and `review-wave-7` — whose + references are correct) + +The distinguishing rule: a reference is stale only if it means the +*release pass*; references to the fuzzing wave (wave 7 since +2026-10-10) are correct and stay untouched. + +## Acceptance Criteria + +- [ ] Every stale "wave 7"-means-release-pass reference in + `docs/reviews/` and `tasks/` annotated or reworded per the rule; + genuine wave-7 (fuzzing) references untouched +- [ ] The sweep's grep command + hit disposition list recorded in + Notes (so the next session doesn't re-derive the inventory) +- [ ] No historical record's meaning altered — annotations only where + the phrasing is load-bearing +- [ ] `taskgraph validate` green after any task-file edits + +## References + +- docs/plans/implementation.md §Wave 8 (the historical note mandating + this sweep) +- tasks/review-wave-5.md (the ADR-024 renumber-annotation precedent) +- docs/reviews/003-wave-5-general-review.md (the renumber trail + example) + +## Notes + +> To be filled by implementation agent + +## Summary + +> To be filled on completion \ No newline at end of file diff --git a/tasks/review-wave-8.md b/tasks/review-wave-8.md new file mode 100644 index 0000000..0ec0702 --- /dev/null +++ b/tasks/review-wave-8.md @@ -0,0 +1,94 @@ +--- +id: review-wave-8 +name: Review gate — wave 8 (release readiness) +status: pending +depends_on: [docs-frontmatter-cleanup, release-renumber-sweep, release-crate-docs, release-contract-window-close, release-n1-growth-posture, release-findings-2-3-disposition, release-flake-investigation, release-deployment-matrix, release-readme, release-publish-prep] +scope: broad +risk: low +impact: project +level: review +tags: [wave-8, review-gate] +--- + +## Description + +The wave-8 review gate (the plan's §Review gates pattern; the +pre-release gate). Audit the release-readiness pass as landed: + +1. **Docs honesty audit**: the README's claims traced to specs (the + readme task's trace list re-verified by spot-read); the deployment + matrix's rows read true as implemented across the three engines; + the crate docs' posture claims consistent with the matrix; the + env-boundary sentence present and the grep result current. +2. **Contract-window closure audit**: every wave-6 recorded + observation disposed (wake-ordering decision landed per the + user's call; the ADR-023 §2 classifications; the `try_recv` shape; + the `get_job` prose; the mem-arithmetic disposition); every landed + amendment dated + cited; **the class-1 window's termination + recorded** — ADR-017 §2's "terminates permanently at the core + crate's first release" becomes a fact at this gate: the record + states the window closes with the first publish, and no + undisposed class-1 candidate remains. +3. **N-1 + Findings 2–3 dispositions audited**: the growth-posture + acceptance is a decision of record (not a shrug); the findings' + landed-vs-parked dispositions recorded so the inventory is closed. +4. **Flake-watch outcome audited**: the investigation's conditions + matrix + disposition read; if a follow-up fix task was created, its + status is visible (a live engine bug blocks the release blessing — + the gate says so explicitly rather than publishing over it). +5. **Publish-prep audit**: `cargo package` evidence per crate; the + exclusion verification re-run this session (file lists of the + built `.crate`s — no fuzz/sidecar/suite leakage); the publish + checklist of record complete and mechanical. +6. **Frontmatter + records hygiene**: the parse sweep re-run (zero + invalid frontmatters under `docs/`); the renumber sweep's + disposition list spot-checked (stale wave-7 references gone or + annotated; genuine fuzz-wave references intact). +7. **All gates re-run green this session**: `cargo build`, `cargo + test`, `cargo clippy --all-targets -- -D warnings`, `cargo fmt + --check`, the fuzz corpus-replay gate, the wasm32 check, and the + doc gate (`cargo doc --no-deps` warning-free). +8. **Spec flips + records**: the remaining `draft` architecture docs + (core-contract.md, overview.md, queues.md, deployment.md, the + architecture README) flip to `stable` with dated gate annotations — + the release-facing spec set is stable at the gate, mirroring the + wave-5/6 engine-spec flips; `docs/architecture/README.md`'s Current + State refreshed (waves 6–8); `implementation.md`'s wave-8 row + updated + a review-rounds entry; task files audited (all wave-8 + dependencies completed, Notes/Summary filled). + +## Acceptance Criteria + +- [ ] Docs honesty audit recorded (README traces, matrix rows, crate + docs, env boundary) +- [ ] Contract-window closure audited; the class-1 termination record + landed; no undisposed class-1 candidate remains +- [ ] N-1 + Findings 2–3 dispositions audited as decisions of record +- [ ] Flake-watch outcome audited; any follow-up task's blocking + status stated explicitly +- [ ] Publish-prep audit recorded (package evidence + exclusion + re-run + checklist complete) +- [ ] Frontmatter parse sweep + renumber-sweep spot-check green +- [ ] All gates re-run green this session (incl. fuzz replay + wasm + + doc gates) +- [ ] Spec flips + records landed; `implementation.md` updated; task + files audited + +## References + +- docs/plans/implementation.md §Wave 8, §Review gates +- docs/architecture/decisions/017-contract-versioning.md §2 (the + window termination this gate records) +- tasks/review-wave-5.md §Notes 6 (the flake ledger) +- tasks/review-wave-6.md §Recorded findings (the dispositions this + gate audits) +- tasks/review-wave-7.md (the parked exclusion verification) +- tasks/review-wave-5.md / tasks/review-wave-6.md (the gate pattern) + +## Notes + +> To be filled by implementation agent + +## Summary + +> To be filled on completion \ No newline at end of file