From 260fb3170786477ca71fa39a17d6a489f8582828 Mon Sep 17 00:00:00 2001 From: "glm-5.3-flash" Date: Sun, 11 Oct 2026 01:32:33 +0000 Subject: [PATCH] =?UTF-8?q?release-readme:=20the=20root=20README=20written?= =?UTF-8?q?=20last,=20honestly=20=E2=80=94=20crate=20family=20table=20with?= =?UTF-8?q?=20per-engine=20honest=20postures=20(ADR-016=20compile-time=20i?= =?UTF-8?q?dentity,=20deployment.md=20as=20the=20boundary),=20mem-carried?= =?UTF-8?q?=20usage=20sketch=20compile-checked=20and=20executed=20against?= =?UTF-8?q?=20the=20real=20API,=20contract-suite=20pointer=20(three=20engi?= =?UTF-8?q?nes,=20one=20pinned=20contract),=20license=20note;=20LICENSE-MI?= =?UTF-8?q?T=20+=20LICENSE-APACHE=20per=20the=20family=20pattern=20(substr?= =?UTF-8?q?ate=20notice=20untouched=20per=20ADR-018);=20CHANGELOG=20seeded?= =?UTF-8?q?=20with=20the=200.1.0=20contract-v1=20entry;=20per-crate=20read?= =?UTF-8?q?me=20wiring=20decided=20+=20landed=20(pointer-style=20per-crate?= =?UTF-8?q?=20readmes,=20readme=20fields=20wired=20on=20the=20four=20publi?= =?UTF-8?q?shed=20crates);=20honesty=20trace=20list=20in=20task=20Notes;?= =?UTF-8?q?=20task=20->=20completed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 46 +++++++++ LICENSE-APACHE | 192 +++++++++++++++++++++++++++++++++++ LICENSE-MIT | 21 ++++ README.md | 117 +++++++++++++++++++++ alkstore-mem/Cargo.toml | 1 + alkstore-mem/README.md | 24 +++++ alkstore-postgres/Cargo.toml | 1 + alkstore-postgres/README.md | 25 +++++ alkstore-sqlite/Cargo.toml | 1 + alkstore-sqlite/README.md | 24 +++++ alkstore/Cargo.toml | 1 + alkstore/README.md | 20 ++++ tasks/release-readme.md | 128 ++++++++++++++++++++++- 13 files changed, 599 insertions(+), 2 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 LICENSE-APACHE create mode 100644 LICENSE-MIT create mode 100644 README.md create mode 100644 alkstore-mem/README.md create mode 100644 alkstore-postgres/README.md create mode 100644 alkstore-sqlite/README.md create mode 100644 alkstore/README.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..0e35094 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,46 @@ +# Changelog + +All notable changes to this crate are documented here. The format is +based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and +this crate adheres to [Semantic Versioning](https://semver.org/). + +## [0.1.0] - 2026-10-11 + +Initial crates.io release of the alkstore family: one reactive store +contract (the pinned contract v1 surface) with three engine +implementations. + +The core crate (`alkstore`) defines the unified trait surface — +notify/listen with transactional wake discipline, streams with +per-consumer offsets and consumer-invoked `trim_to`, queues with +visibility-timeout claims, backoff, dead-lettering and the opt-in +retention sweep, TTL named locks, the outbox helper +(`outbox_enqueue_tx` + `run_once`), the `@every` scheduler, and the +caller-held `TxHandle` seam (drop = rollback) — plus the value types, +error taxonomy, and the naming / reserved-namespace contract. No +runtime capability surface: engine identity is compile-time, and the +deployment honesty lives in the engine crates' postures plus the +documented deployment matrix ([ADR-016]). + +Three engines ship the same contract v1 surface: + +- `alkstore-sqlite` — single-host, file-backed, over rusqlite and the + forked honker-core substrate carried in-tree (bridged sync/async seam, + `data_version` watcher wake). +- `alkstore-postgres` — multi-host native, natively async over + tokio-postgres + deadpool-postgres with a dedicated non-pooled + LISTEN connection per LISTEN-ing process. +- `alkstore-mem` — honest-ephemeral in-process state: full contract v1, + no durability, never fleet-valid; the wasm32-compile-clean family + member. + +All three engines run the same contract-suite rows +(`alkstore-contract-suite`) against their own factory — three engines, +one pinned contract. The contract version is the core crate's semver +([ADR-017]); this 0.1.0 release closes the pre-release contract-change +window, and ADR-017 §2's class-1 amendment events terminate at it. + +[0.1.0]: https://git.alk.dev/alkdev/alkstore/releases/tag/v0.1.0 + +[ADR-016]: docs/architecture/decisions/016-deployment-honesty.md +[ADR-017]: docs/architecture/decisions/017-contract-versioning.md \ No newline at end of file diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000..56f9da5 --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,192 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name), or refer to, the Work. + (Note: Derivative Works shall not include works that remain separable from, + or merely link (or bind by name) to the interfaces of, the Work and + Derivative Works thereof.) + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to the Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by the Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2025-2026 Alk Development + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000..9ee173b --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025-2026 Alk Development + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..d9f2f30 --- /dev/null +++ b/README.md @@ -0,0 +1,117 @@ +# alkstore + +One reactive store interface — durable notify/subscribe signals, streams +with per-consumer offsets, durable queues with the transactional enqueue +property, named locks, a scheduler, and an outbox helper — over SQLite, +Postgres, and the in-process mem engine. Each engine uses its own native +machinery underneath (SQLite: the forked honker watcher design; +Postgres: `pg_notify`/LISTEN and the pg-boss schema family; mem: guarded +in-process state, ephemeral by design). + +alkstore is the substrate, made once: the answer to "how does a change +in the database become visible to other processes/connections?" that +downstream stores don't re-derive. + +## The interface + +One unified trait surface (`alkstore::Store`), seven mechanisms: + +- **notify / listen** — durable publish/subscribe signals with + transactional wake discipline (wake on commit, opaque wake → re-read). +- **streams** — append-only logs with per-consumer offsets, carried + metadata, and consumer-invoked `trim_to`. +- **queues** — visibility-timeout claim discipline, backoff, + dead-lettering, and an opt-in retention sweep; enqueue is available + inside the transaction seam (the outbox pattern). +- **named locks** — TTL-based lease locks with renewal and expiry + reclaim. +- **outbox helper** — transactional enqueue-on-commit (`outbox_enqueue_tx`) + with a `run_once` delivery driver. +- **scheduler** — `@every`-interval schedules that enqueue onto a queue, + with bounded catch-up and leadership discipline (multi-process safe). +- **transaction seam** — `with_tx` and caller-held `TxHandle` methods; + drop of the handle rolls back. + +## Crate family + +Downstream consumers depend on `alkstore` (core) plus exactly one engine +crate. Engine identity is compile-time: the engine crate your binary +depends on *is* the deployment statement — there is no runtime +capability surface ([ADR-016](docs/architecture/decisions/016-deployment-honesty.md)). + +| Crate | Role | Engine posture | +|---|---|---| +| `alkstore` | the contract artifact: unified trait surface, value types, error model (no driver dependencies) | — | +| `alkstore-sqlite` | SQLite engine (rusqlite over the in-tree forked honker substrate) | **single-host**, file-backed — cross-process on one host is verified territory; NFS two-writers is not a supportable posture | +| `alkstore-postgres` | Postgres engine (tokio-postgres + deadpool-postgres, hand-rolled LISTEN) | **multi-host native**; v1 TLS is effectively unavailable (`NoTls` on every connection path) — network confidentiality comes from the deployment topology | +| `alkstore-mem` | in-process engine, full contract v1 | **honest-ephemeral** — no durability, single-process, never fleet-valid; loss on process exit is the documented posture; compiles clean on `wasm32-unknown-unknown` | + +The unified trait does not pretend SQLite is multi-host — the honest +boundary lives in the compile-time engine identity plus the documented +[deployment matrix](docs/architecture/deployment.md) (host semantics, +connection budgets, durability knobs, growth postures). + +## Usage + +The mem engine is the zero-config example carrier — one call and no +options: + +```rust +use alkstore::{EnqueueOpts, JobState, QueueOpts, Store}; +use alkstore_mem::MemStore; + +let rt = tokio::runtime::Builder::new_current_thread().build()?; +let store = MemStore::new(); + +let queue = rt.block_on(store.queue("demo", QueueOpts::default()))?; +let job_id = rt.block_on(queue.enqueue( + serde_json::json!("hello"), + EnqueueOpts::default(), +))?; + +let claimed = rt.block_on(queue.claim_one("worker-1"))? + .expect("the enqueued job is claimable"); +assert_eq!(claimed.job().id, job_id); +assert_eq!(claimed.job().state, JobState::Processing); +``` + +The surface is the same on every engine; only the constructor differs: + +```rust +let store = alkstore_sqlite::open("store.db", SqliteOpts::default())?; // single-host +let store = alkstore_postgres::open(&dsn, PgOpts::default()).await?; // multi-host +let store = MemStore::new(); // in-process +``` + +## Three engines, one pinned contract + +The contract is pinned once, not per engine: the internal +`alkstore-contract-suite` crate parameterizes the contract's property +set over a store factory, and each engine crate runs the *same* suite +rows against its own factory as part of its test target. Three engines, +one pinned contract — the [core contract](docs/architecture/core-contract.md) +is the spec of record (mechanisms, delivery guarantees, error taxonomy, +naming / reserved namespace). + +## Documentation + +- [Core contract](docs/architecture/core-contract.md) — the unified + trait surface: mechanisms, delivery guarantees, tx seam, naming. +- [Deployment matrix](docs/architecture/deployment.md) — host + semantics, connection budgets, durability knobs, growth postures. +- [Engine specs](docs/architecture/) — SQLite, Postgres, mem. +- [Decision index](docs/architecture/README.md) — the ADRs. +- [API docs](https://docs.rs/alkstore) — full crate documentation. +- [CHANGELOG.md](CHANGELOG.md) + +## License + +Dual-licensed under [MIT](LICENSE-MIT) or +[Apache-2.0](LICENSE-APACHE), matching the workspace +`license = "MIT OR Apache-2.0"` field. + +The SQLite engine carries a forked third-party substrate (honker) +in-tree under its upstream dual license; its bundled license notice +(`alkstore-sqlite/src/substrate/LICENSE`) is the preservation +obligation's carrier and is not replaced by the root license files +([ADR-018](docs/architecture/decisions/018-provenance-register-and-cherry-picks.md)). \ No newline at end of file diff --git a/alkstore-mem/Cargo.toml b/alkstore-mem/Cargo.toml index d6bc179..00c36ea 100644 --- a/alkstore-mem/Cargo.toml +++ b/alkstore-mem/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true repository.workspace = true +readme = "README.md" [dependencies] alkstore = { version = "0.1", path = "../alkstore" } diff --git a/alkstore-mem/README.md b/alkstore-mem/README.md new file mode 100644 index 0000000..23384cb --- /dev/null +++ b/alkstore-mem/README.md @@ -0,0 +1,24 @@ +# alkstore-mem + +The mem engine of the [alkstore](https://git.alk.dev/alkdev/alkstore/blob/main/README.md) +family: the full core contract v1 implemented on guarded in-process +state — every mechanism, every guarantee row — with zero +configuration. + +```rust +let store = alkstore_mem::MemStore::new(); +``` + +**Engine posture — honest-ephemeral.** No durability, single-process, +never fleet-valid: there is no cross-process story at all, loss on +process exit is the documented posture, and the dependency on this +crate *is* the ephemerality declaration. Each `MemStore::new()` yields +a fully isolated instance sharing nothing; teardown is drop. The +dependency on tokio is restricted to the wasm-supported subset (sync + +time) — this crate compiles clean on `wasm32-unknown-unknown`, the +family member that runs in the sandbox. + +See the [family README](https://git.alk.dev/alkdev/alkstore/blob/main/README.md) +for the interface and the deployment matrix, and the +[mem engine spec](https://git.alk.dev/alkdev/alkstore/blob/main/docs/architecture/engine-mem.md) +for the architecture. \ No newline at end of file diff --git a/alkstore-postgres/Cargo.toml b/alkstore-postgres/Cargo.toml index 1369ed5..c0aa252 100644 --- a/alkstore-postgres/Cargo.toml +++ b/alkstore-postgres/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true repository.workspace = true +readme = "README.md" [dependencies] alkstore = { version = "0.1", path = "../alkstore" } diff --git a/alkstore-postgres/README.md b/alkstore-postgres/README.md new file mode 100644 index 0000000..709d7c4 --- /dev/null +++ b/alkstore-postgres/README.md @@ -0,0 +1,25 @@ +# alkstore-postgres + +The Postgres engine of the [alkstore](https://git.alk.dev/alkdev/alkstore/blob/main/README.md) +family: the core contract implemented on tokio-postgres + +deadpool-postgres, natively async (no blocking bridge, no +`spawn_blocking` seam), with a hand-rolled LISTEN forwarder. + +```rust +let store = alkstore_postgres::open(&dsn, alkstore_postgres::PgOpts::default()).await?; +``` + +**Engine posture — multi-host native.** Connections are per-process +state; nothing assumes a shared host. Connection budget: `max_size` +pooled connections **+ 1 non-pooled listener connection per LISTEN-ing +process** (pooled connections cannot carry LISTEN) — size the server +for the sum. v1 TLS is effectively unavailable: the engine hardwires +`NoTls` on every connection path, so network confidentiality must come +from the deployment topology. Queue/stream/lock/schedule tables live +in one engine-owned PostgreSQL schema (default `alkstore`, +per-engine option). + +See the [family README](https://git.alk.dev/alkdev/alkstore/blob/main/README.md) +for the interface and the deployment matrix, and the +[Postgres engine spec](https://git.alk.dev/alkdev/alkstore/blob/main/docs/architecture/engine-postgres.md) +for the driver's details. \ No newline at end of file diff --git a/alkstore-sqlite/Cargo.toml b/alkstore-sqlite/Cargo.toml index 09dcb19..bbaf809 100644 --- a/alkstore-sqlite/Cargo.toml +++ b/alkstore-sqlite/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true repository.workspace = true +readme = "README.md" [dependencies] alkstore = { version = "0.1", path = "../alkstore" } diff --git a/alkstore-sqlite/README.md b/alkstore-sqlite/README.md new file mode 100644 index 0000000..f9663a7 --- /dev/null +++ b/alkstore-sqlite/README.md @@ -0,0 +1,24 @@ +# alkstore-sqlite + +The SQLite engine of the [alkstore](https://git.alk.dev/alkdev/alkstore/blob/main/README.md) +family: the core contract implemented on rusqlite over the forked +honker-core substrate carried in-tree. + +```rust +let store = alkstore_sqlite::open("store.db", alkstore_sqlite::SqliteOpts::default())?; +``` + +**Engine posture — single-host, file-backed.** Cross-process on one +host is verified territory; a `.db` on network storage (NFS +two-writers) is not a supportable deployment posture. Durability +knobs, pool sizing, and the watcher cadence are engine-configuration +concerns on `SqliteOpts` — `synchronous = NORMAL` is hardwired at +connection bootstrap; there is no consumer surface to raise the sync +level. + +See the [family README](https://git.alk.dev/alkdev/alkstore/blob/main/README.md) +for the interface and the deployment matrix, and the +[SQLite engine spec](https://git.alk.dev/alkdev/alkstore/blob/main/docs/architecture/engine-sqlite.md) +for the substrate's details. The substrate (forked third-party code) +ships with its own bundled license notice in the crate tree — the +root dual license files do not replace it. \ No newline at end of file diff --git a/alkstore/Cargo.toml b/alkstore/Cargo.toml index dda44fb..fbd0e51 100644 --- a/alkstore/Cargo.toml +++ b/alkstore/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true repository.workspace = true +readme = "README.md" [dependencies] serde = "1" diff --git a/alkstore/README.md b/alkstore/README.md new file mode 100644 index 0000000..4278142 --- /dev/null +++ b/alkstore/README.md @@ -0,0 +1,20 @@ +# alkstore + +The core crate of the [alkstore](https://git.alk.dev/alkdev/alkstore/blob/main/README.md) +family: the contract artifact — the unified `Store` trait surface, +value types, error taxonomy, and the naming / reserved-namespace +contract of the reactive store substrate. It has no driver +dependencies, ever (payload encoding's `serde`/`serde_json` are its +only dependencies); engine crates depend on it and implement its +traits. + +Downstream consumers depend on `alkstore` plus exactly one engine +crate: [`alkstore-sqlite`](https://crates.io/crates/alkstore-sqlite), +[`alkstore-postgres`](https://crates.io/crates/alkstore-postgres), or +[`alkstore-mem`](https://crates.io/crates/alkstore-mem). Engine +identity is compile-time — the engine crate your binary depends on +*is* the deployment statement; there is no runtime capability surface. + +See the [family README](https://git.alk.dev/alkdev/alkstore/blob/main/README.md) +for the interface, the engine postures, and the deployment matrix; +the crate's own docs are part of the contract. \ No newline at end of file diff --git a/tasks/release-readme.md b/tasks/release-readme.md index 053de4a..240634c 100644 --- a/tasks/release-readme.md +++ b/tasks/release-readme.md @@ -1,7 +1,7 @@ --- id: release-readme name: Crate README (written last, honestly) + LICENSE + CHANGELOG -status: pending +status: completed 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 @@ -73,6 +73,130 @@ are the wave's other doc-shaped tasks for exactly that reason. > To be filled by implementation agent +Per-crate readme wiring — **decision: pointer-style per-crate +readmes.** Each of the four published crates gets its own short +`README.md` (role + one honest posture paragraph + the constructor +line) and `[package] readme = "README.md"` is wired in its Cargo.toml. +Rationale: a `[package] readme = "../README.md"` puts +workspace-relative links into crates.io-rendered markdown, where they +break, and the engines' lib docs already carry their posture in +depth — so the per-crate readme summarizes honestly and links back to +the root README via absolute repository URLs (git.alk.dev). The +contract-suite crate is `publish = false` — no readme. The root +README's docs links are workspace-relative (they render on the git +forge, which is where the root README lives). + +Usage-sketch compile check: the root README's snippets were extracted +into a scratch crate (`/tmp/opencode/readme-check/`) with path deps on +all four published crates — compiled clean and **ran** (the mem queue +round-trip passes its assertions; `alkstore_sqlite::open` / +`alkstore_postgres::open` / `MemStore::new()` constructor forms +compile, the sqlite open actually opens). Harness artifact noted: the +postgres constructor attempt needs `enable_all()` *in the harness +runtime* for the IO driver (tokio-postgres TCP); the README's +constructor-forms block is the constructor sketch, and the engine docs +carry the real construction details. The mem round-trip mirrors the +crate's lib-doc doctest (which `cargo test` re-verifies). + +Substrate notice untouched: no file under `alkstore-sqlite/src/` +changed; the bundled `LICENSE` and register stay as landed (ADR-018). + +LICENSE-MIT / LICENSE-APACHE copied from the alkcall family pattern +(canonical texts, "Copyright (c) 2025-2026 Alk Development"); the +workspace `license = "MIT OR Apache-2.0"` field matches. CHANGELOG +follows the alkcall changelog shape (Keep a Changelog, release-note- +shaped, tag-link refs at the bottom — `v0.1.0` tag URL per the repo). + +### Honesty trace list (README claim → spec source) + +Root `README.md`: + +- Intro mechanism list + "substrate, made once" framing — + `docs/architecture/overview.md` (intro + §Why this crate exists); + feature scope per ADR-002; "durable queues with the transactional + enqueue property" verbatim from overview. +- Engine native machinery (watcher / `pg_notify`+LISTEN / guarded + in-process state) — overview intro. +- `Store` seven-mechanism bullet list — `core-contract.md` §Mechanism + contracts; notify wake discipline — ADR-006 (opaque wake + re-read, + commit-boundary delivery); streams offsets + consumer-invoked + `trim_to` — ADR-015; queue claim/backoff/dead-letter/sweep — ADR-010; + outbox `outbox_enqueue_tx` — ADR-014; scheduler `@every` + + leadership + catch-up — ADR-009 / core-contract §scheduler (suite + rows `scheduler_leadership_discipline`, `scheduler_bounded_catchup`); + TTL locks renewal/expiry reclaim — core-contract §named locks (suite + row `lock_ttl_expiry_and_reacquisition`); tx seam drop = rollback — + ADR-007/ADR-021. +- Family table roles — overview §Crate family (ADR-001, ADR-016); + core "no driver dependencies" — ADR-020 §4. +- SQLite "single-host, file-backed / cross-process on one host + verified / NFS two-writers unsupported" — deployment.md §Host + semantics (ADR-016, ADR-003). +- Postgres "multi-host native / NoTls every path, v1 TLS effectively + unavailable" — deployment.md §Host semantics + §TLS posture (v1) + (ADR-004). +- Mem "honest-ephemeral / never fleet-valid / loss on process exit / + wasm32-compile-clean" — deployment.md §Host semantics + ADR-024 §2/§5. +- "No runtime capability surface; compile-time identity is the + deployment statement" — ADR-016 + deployment.md. +- Usage sketch — compile-checked (above); constructors match + `alkstore-sqlite/src/store.rs` `open(path, SqliteOpts)` (sync), + `alkstore-postgres/src/store.rs` `open(config, PgOpts)` (async), + `MemStore::new()` (sync). +- "Three engines, one pinned contract" — the contract-suite crate's + lib docs (each engine consumes the suite as a dev-dependency and + runs the rows in its test target); ADR-022. +- License note — workspace `license` field; substrate bundled-notice + carrier — ADR-018 + `alkstore-sqlite/src/substrate/mod.rs`. + +Per-crate readmes: + +- `alkstore/`: family/ADR-016 compile-time identity; "no driver + dependencies, ever (serde/serde_json sole deps)" — ADR-001/ADR-020 §4. +- `alkstore-sqlite/`: single-host posture + NFS — deployment.md; "no + consumer surface to raise the sync level, NORMAL hardwired" — + deployment.md §Durability knobs (the release-matrix correction); + bundled-notice note — ADR-018. +- `alkstore-postgres/`: natively async — ADR-004/ADR-007 (POC-verified); + budget `max_size + 1` per LISTEN-ing process + deadpool#360 — + deployment.md §Connection budgets; NoTls v1 — deployment.md §TLS + posture; engine-owned schema (default `alkstore`) — deployment.md + + ADR-010 §8. +- `alkstore-mem/`: honest-ephemeral / dependency-is-the-declaration / + never fleet-valid / per-instance isolation (drop closes receivers) — + ADR-024 §2/§4 + crate lib docs; wasm32 sync+time subset — ADR-024 §5 + + deployment.md §Toolchain notes. + +CHANGELOG: every statement re-checked against the shipped crates — +contract v1 surface listing mirrors `core-contract.md` and +`alkstore/src/lib.rs` re-exports; engine postures mirror deployment.md; +"dependency is the ephemerality declaration" — ADR-024; "closes the +pre-release contract-change window" — ADR-017 §2 (class-1 terminates +at first release; this is the release the window was written against). + +No claims found without a spec source; no aspirational/unshipped +features named (no latency numbers — deployment.md's POC profile is +pointed to, not copied). + ## Summary -> To be filled on completion \ No newline at end of file +> To be filled on completion + +Landed (2026-10-11): root `README.md` (intro, seven-mechanism +interface list, family table with per-engine honest postures, +compile-checked + executed usage sketch on the mem crate as the +zero-config carrier, contract-suite pointer — three engines, one +pinned contract, docs index, license note); `LICENSE-MIT` + +`LICENSE-APACHE` (family canonical texts); `CHANGELOG.md` seeded with +the 0.1.0 entry (contract v1 surface, three engines and their +postures, the ADR-017 window-closing note); per-crate readme wiring +decided and landed — pointer-style per-crate readmes for the four +published crates with `readme = "README.md"` wired in each +Cargo.toml (contract-suite unpublished, excluded). Substrate notice +untouched. Gates: workspace build, full `cargo test` (15 result +blocks green, incl. the mem round-trip doctest), clippy +`--all-targets -- -D warnings`, `fmt --check`, doc gate +(`RUSTDOCFLAGS="-D warnings" cargo doc --no-deps`), and the fuzz +corpus replay (`cargo test --manifest-path fuzz/shared/Cargo.toml`) +all pass. README snippets additionally compile-checked and executed +via a scratch crate with path deps on the real published crates. \ No newline at end of file