sqlrite 0.9.1__tar.gz → 0.10.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. {sqlrite-0.9.1 → sqlrite-0.10.1}/.github/workflows/ci.yml +27 -1
  2. {sqlrite-0.9.1 → sqlrite-0.10.1}/.github/workflows/release.yml +25 -0
  3. {sqlrite-0.9.1 → sqlrite-0.10.1}/.gitignore +9 -0
  4. {sqlrite-0.9.1 → sqlrite-0.10.1}/CLAUDE.md +1 -0
  5. {sqlrite-0.9.1 → sqlrite-0.10.1}/Cargo.lock +7 -7
  6. {sqlrite-0.9.1 → sqlrite-0.10.1}/Cargo.toml +11 -2
  7. {sqlrite-0.9.1 → sqlrite-0.10.1}/PKG-INFO +1 -1
  8. {sqlrite-0.9.1 → sqlrite-0.10.1}/README.md +11 -0
  9. {sqlrite-0.9.1 → sqlrite-0.10.1}/desktop/package.json +1 -1
  10. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/_index.md +5 -1
  11. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/benchmarks-plan.md +23 -4
  12. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/concurrent-writes-plan.md +20 -8
  13. sqlrite-0.10.1/docs/concurrent-writes.md +340 -0
  14. sqlrite-0.10.1/docs/design-decisions.md +537 -0
  15. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/embedding.md +71 -0
  16. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/file-format.md +89 -2
  17. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/release-plan.md +62 -1
  18. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/roadmap.md +228 -6
  19. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/smoke-test.md +5 -3
  20. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/sql-engine.md +1 -1
  21. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/supported-sql.md +78 -11
  22. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/usage.md +31 -1
  23. {sqlrite-0.9.1 → sqlrite-0.10.1}/examples/README.md +38 -0
  24. sqlrite-0.10.1/examples/nodejs-notes/.gitignore +6 -0
  25. sqlrite-0.10.1/examples/nodejs-notes/README.md +333 -0
  26. sqlrite-0.10.1/examples/nodejs-notes/bin/sqlrite-notes.mjs +15 -0
  27. sqlrite-0.10.1/examples/nodejs-notes/package-lock.json +31 -0
  28. sqlrite-0.10.1/examples/nodejs-notes/package.json +38 -0
  29. sqlrite-0.10.1/examples/nodejs-notes/src/chunker.mjs +191 -0
  30. sqlrite-0.10.1/examples/nodejs-notes/src/claude-config.mjs +65 -0
  31. sqlrite-0.10.1/examples/nodejs-notes/src/cli.mjs +350 -0
  32. sqlrite-0.10.1/examples/nodejs-notes/src/config.mjs +71 -0
  33. sqlrite-0.10.1/examples/nodejs-notes/src/db.mjs +400 -0
  34. sqlrite-0.10.1/examples/nodejs-notes/src/embeddings.mjs +152 -0
  35. sqlrite-0.10.1/examples/nodejs-notes/src/ingest.mjs +235 -0
  36. sqlrite-0.10.1/examples/nodejs-notes/src/search.mjs +51 -0
  37. sqlrite-0.10.1/examples/nodejs-notes/src/serve.mjs +113 -0
  38. sqlrite-0.10.1/examples/nodejs-notes/src/sqlutil.mjs +63 -0
  39. sqlrite-0.10.1/examples/nodejs-notes/test/chunker.test.mjs +85 -0
  40. sqlrite-0.10.1/examples/nodejs-notes/test/claude-config.test.mjs +36 -0
  41. sqlrite-0.10.1/examples/nodejs-notes/test/db.test.mjs +272 -0
  42. sqlrite-0.10.1/examples/nodejs-notes/test/embeddings.test.mjs +104 -0
  43. sqlrite-0.10.1/examples/nodejs-notes/test/fixtures/crdts.md +23 -0
  44. sqlrite-0.10.1/examples/nodejs-notes/test/fixtures/postgres.md +18 -0
  45. sqlrite-0.10.1/examples/nodejs-notes/test/fixtures/running.md +8 -0
  46. sqlrite-0.10.1/examples/nodejs-notes/test/ingest.test.mjs +131 -0
  47. sqlrite-0.10.1/examples/nodejs-notes/test/serve.test.mjs +38 -0
  48. sqlrite-0.10.1/examples/nodejs-notes/test/sqlutil.test.mjs +47 -0
  49. sqlrite-0.10.1/examples/python-agent/.gitignore +12 -0
  50. sqlrite-0.10.1/examples/python-agent/README.md +275 -0
  51. sqlrite-0.10.1/examples/python-agent/pyproject.toml +55 -0
  52. sqlrite-0.10.1/examples/python-agent/sqlrite_agent/__init__.py +4 -0
  53. sqlrite-0.10.1/examples/python-agent/sqlrite_agent/__main__.py +4 -0
  54. sqlrite-0.10.1/examples/python-agent/sqlrite_agent/agent.py +163 -0
  55. sqlrite-0.10.1/examples/python-agent/sqlrite_agent/chat.py +113 -0
  56. sqlrite-0.10.1/examples/python-agent/sqlrite_agent/cli.py +194 -0
  57. sqlrite-0.10.1/examples/python-agent/sqlrite_agent/db.py +349 -0
  58. sqlrite-0.10.1/examples/python-agent/sqlrite_agent/embeddings.py +141 -0
  59. sqlrite-0.10.1/examples/python-agent/sqlrite_agent/facts.py +137 -0
  60. sqlrite-0.10.1/examples/python-agent/sqlrite_agent/memory.py +216 -0
  61. sqlrite-0.10.1/examples/python-agent/sqlrite_agent/sqlutil.py +39 -0
  62. sqlrite-0.10.1/examples/python-agent/tests/conftest.py +38 -0
  63. sqlrite-0.10.1/examples/python-agent/tests/test_agent.py +100 -0
  64. sqlrite-0.10.1/examples/python-agent/tests/test_db.py +172 -0
  65. sqlrite-0.10.1/examples/python-agent/tests/test_facts.py +57 -0
  66. sqlrite-0.10.1/examples/python-agent/tests/test_memory.py +85 -0
  67. sqlrite-0.10.1/examples/python-agent/tests/test_sqlutil.py +28 -0
  68. sqlrite-0.10.1/examples/rust/concurrent_writers.rs +85 -0
  69. {sqlrite-0.9.1 → sqlrite-0.10.1}/pyproject.toml +1 -1
  70. {sqlrite-0.9.1 → sqlrite-0.10.1}/scripts/bump-version.sh +18 -3
  71. {sqlrite-0.9.1 → sqlrite-0.10.1}/sdk/go/README.md +53 -0
  72. {sqlrite-0.9.1 → sqlrite-0.10.1}/sdk/go/conn.go +57 -15
  73. sqlrite-0.10.1/sdk/go/sqlrite.go +444 -0
  74. sqlrite-0.10.1/sdk/go/sqlrite_test.go +558 -0
  75. {sqlrite-0.9.1 → sqlrite-0.10.1}/sdk/python/Cargo.toml +1 -1
  76. {sqlrite-0.9.1 → sqlrite-0.10.1}/sdk/python/src/lib.rs +109 -11
  77. {sqlrite-0.9.1 → sqlrite-0.10.1}/sdk/python/tests/test_sqlrite.py +135 -0
  78. {sqlrite-0.9.1 → sqlrite-0.10.1}/sqlrite-ask/Cargo.toml +1 -1
  79. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/ask/mod.rs +4 -2
  80. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/ask/schema.rs +2 -1
  81. sqlrite-0.10.1/src/connection.rs +3238 -0
  82. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/error.rs +31 -0
  83. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/lib.rs +6 -0
  84. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/main.rs +51 -41
  85. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/meta_command/mod.rs +275 -45
  86. sqlrite-0.10.1/src/mvcc/clock.rs +182 -0
  87. sqlrite-0.10.1/src/mvcc/log.rs +624 -0
  88. sqlrite-0.10.1/src/mvcc/mod.rs +134 -0
  89. sqlrite-0.10.1/src/mvcc/registry.rs +322 -0
  90. sqlrite-0.10.1/src/mvcc/store.rs +984 -0
  91. sqlrite-0.10.1/src/mvcc/transaction.rs +262 -0
  92. sqlrite-0.10.1/src/repl/mod.rs +281 -0
  93. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/db/database.rs +77 -0
  94. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/db/table.rs +48 -3
  95. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/executor.rs +10 -7
  96. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/hnsw.rs +96 -45
  97. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/mod.rs +55 -0
  98. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/pager/mod.rs +59 -49
  99. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/pager/pager.rs +64 -0
  100. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/pager/wal.rs +290 -12
  101. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/pragma.rs +49 -1
  102. sqlrite-0.10.1/web/.gitignore +40 -0
  103. sqlrite-0.10.1/web/README.md +284 -0
  104. sqlrite-0.10.1/web/components.json +21 -0
  105. sqlrite-0.10.1/web/content/blog/adding-vector-search-with-hnsw.mdx +235 -0
  106. sqlrite-0.10.1/web/content/blog/how-sqlrite-stores-rows-on-disk.mdx +275 -0
  107. sqlrite-0.10.1/web/content/blog/shipping-concurrent-writes-mvcc-v010.mdx +395 -0
  108. sqlrite-0.10.1/web/content/blog/shipping-sqlrite-tauri-mcp-sdks.mdx +351 -0
  109. sqlrite-0.10.1/web/content/blog/sqlrite-vs-sqlite-benchmarks.mdx +248 -0
  110. sqlrite-0.10.1/web/content/blog/why-im-building-sqlrite.mdx +222 -0
  111. sqlrite-0.10.1/web/eslint.config.mjs +16 -0
  112. sqlrite-0.10.1/web/next.config.ts +7 -0
  113. sqlrite-0.10.1/web/package-lock.json +8868 -0
  114. sqlrite-0.10.1/web/package.json +37 -0
  115. sqlrite-0.10.1/web/postcss.config.mjs +7 -0
  116. sqlrite-0.10.1/web/seo/keywords.md +161 -0
  117. sqlrite-0.10.1/web/src/app/blog/[slug]/opengraph-image.tsx +32 -0
  118. sqlrite-0.10.1/web/src/app/blog/[slug]/page.tsx +232 -0
  119. sqlrite-0.10.1/web/src/app/blog/[slug]/twitter-image.tsx +29 -0
  120. sqlrite-0.10.1/web/src/app/blog/page.tsx +143 -0
  121. sqlrite-0.10.1/web/src/app/blog/rss.xml/route.ts +63 -0
  122. sqlrite-0.10.1/web/src/app/blog/tags/[tag]/page.tsx +109 -0
  123. sqlrite-0.10.1/web/src/app/docs/opengraph-image.tsx +20 -0
  124. sqlrite-0.10.1/web/src/app/docs/page.tsx +858 -0
  125. sqlrite-0.10.1/web/src/app/docs/twitter-image.tsx +20 -0
  126. sqlrite-0.10.1/web/src/app/examples/page.tsx +271 -0
  127. sqlrite-0.10.1/web/src/app/globals.css +2377 -0
  128. sqlrite-0.10.1/web/src/app/layout.tsx +124 -0
  129. sqlrite-0.10.1/web/src/app/opengraph-image.tsx +20 -0
  130. sqlrite-0.10.1/web/src/app/page.tsx +102 -0
  131. sqlrite-0.10.1/web/src/app/robots.ts +15 -0
  132. sqlrite-0.10.1/web/src/app/sitemap.ts +49 -0
  133. sqlrite-0.10.1/web/src/app/twitter-image.tsx +20 -0
  134. sqlrite-0.10.1/web/src/components/architecture.tsx +111 -0
  135. sqlrite-0.10.1/web/src/components/benchmarks.tsx +159 -0
  136. sqlrite-0.10.1/web/src/components/blog-mdx.tsx +64 -0
  137. sqlrite-0.10.1/web/src/components/blog.tsx +81 -0
  138. sqlrite-0.10.1/web/src/components/cta-strip.tsx +26 -0
  139. sqlrite-0.10.1/web/src/components/desktop.tsx +117 -0
  140. sqlrite-0.10.1/web/src/components/features.tsx +140 -0
  141. sqlrite-0.10.1/web/src/components/footer.tsx +97 -0
  142. sqlrite-0.10.1/web/src/components/hero.tsx +57 -0
  143. sqlrite-0.10.1/web/src/components/icons.tsx +47 -0
  144. sqlrite-0.10.1/web/src/components/install-bar.tsx +54 -0
  145. sqlrite-0.10.1/web/src/components/nav.tsx +172 -0
  146. sqlrite-0.10.1/web/src/components/roadmap.tsx +245 -0
  147. sqlrite-0.10.1/web/src/components/sdk-showcase-client.tsx +91 -0
  148. sqlrite-0.10.1/web/src/components/sdk-showcase.tsx +186 -0
  149. sqlrite-0.10.1/web/src/components/sql-ref.tsx +254 -0
  150. sqlrite-0.10.1/web/src/components/terminal.tsx +193 -0
  151. sqlrite-0.10.1/web/src/lib/benchmarks.ts +263 -0
  152. sqlrite-0.10.1/web/src/lib/blog.ts +129 -0
  153. sqlrite-0.10.1/web/src/lib/highlight.ts +34 -0
  154. sqlrite-0.10.1/web/src/lib/og.tsx +144 -0
  155. sqlrite-0.10.1/web/src/lib/site.ts +26 -0
  156. sqlrite-0.10.1/web/src/lib/utils.ts +6 -0
  157. sqlrite-0.10.1/web/src/middleware.ts +31 -0
  158. sqlrite-0.10.1/web/tsconfig.json +21 -0
  159. sqlrite-0.9.1/docs/design-decisions.md +0 -289
  160. sqlrite-0.9.1/sdk/go/sqlrite.go +0 -226
  161. sqlrite-0.9.1/sdk/go/sqlrite_test.go +0 -297
  162. sqlrite-0.9.1/src/connection.rs +0 -1292
  163. sqlrite-0.9.1/src/repl/mod.rs +0 -144
  164. {sqlrite-0.9.1 → sqlrite-0.10.1}/.github/workflows/release-pr.yml +0 -0
  165. {sqlrite-0.9.1 → sqlrite-0.10.1}/.github/workflows/rust.yml +0 -0
  166. {sqlrite-0.9.1 → sqlrite-0.10.1}/CODE_OF_CONDUCT.md +0 -0
  167. {sqlrite-0.9.1 → sqlrite-0.10.1}/LICENSE +0 -0
  168. {sqlrite-0.9.1 → sqlrite-0.10.1}/MAINTAINERS +0 -0
  169. {sqlrite-0.9.1 → sqlrite-0.10.1}/Makefile +0 -0
  170. {sqlrite-0.9.1 → sqlrite-0.10.1}/desktop/index.html +0 -0
  171. {sqlrite-0.9.1 → sqlrite-0.10.1}/desktop/package-lock.json +0 -0
  172. {sqlrite-0.9.1 → sqlrite-0.10.1}/desktop/src/App.svelte +0 -0
  173. {sqlrite-0.9.1 → sqlrite-0.10.1}/desktop/src/app.css +0 -0
  174. {sqlrite-0.9.1 → sqlrite-0.10.1}/desktop/src/main.ts +0 -0
  175. {sqlrite-0.9.1 → sqlrite-0.10.1}/desktop/src/vite-env.d.ts +0 -0
  176. {sqlrite-0.9.1 → sqlrite-0.10.1}/desktop/svelte.config.js +0 -0
  177. {sqlrite-0.9.1 → sqlrite-0.10.1}/desktop/tsconfig.json +0 -0
  178. {sqlrite-0.9.1 → sqlrite-0.10.1}/desktop/vite.config.ts +0 -0
  179. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/architecture.md +0 -0
  180. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/ask-backend-examples.md +0 -0
  181. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/ask.md +0 -0
  182. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/benchmarks.md +0 -0
  183. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/desktop.md +0 -0
  184. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/fts.md +0 -0
  185. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/getting-started.md +0 -0
  186. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/mcp.md +0 -0
  187. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/pager.md +0 -0
  188. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/phase-7-plan.md +0 -0
  189. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/phase-8-plan.md +0 -0
  190. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/release-secrets.md +0 -0
  191. {sqlrite-0.9.1 → sqlrite-0.10.1}/docs/storage-model.md +0 -0
  192. {sqlrite-0.9.1 → sqlrite-0.10.1}/examples/c/Makefile +0 -0
  193. {sqlrite-0.9.1 → sqlrite-0.10.1}/examples/c/hello.c +0 -0
  194. {sqlrite-0.9.1 → sqlrite-0.10.1}/examples/go/go.mod +0 -0
  195. {sqlrite-0.9.1 → sqlrite-0.10.1}/examples/go/hello.go +0 -0
  196. {sqlrite-0.9.1 → sqlrite-0.10.1}/examples/hybrid-retrieval/README.md +0 -0
  197. {sqlrite-0.9.1 → sqlrite-0.10.1}/examples/hybrid-retrieval/hybrid_retrieval.rs +0 -0
  198. {sqlrite-0.9.1 → sqlrite-0.10.1}/examples/nodejs/hello.mjs +0 -0
  199. {sqlrite-0.9.1 → sqlrite-0.10.1}/examples/python/hello.py +0 -0
  200. {sqlrite-0.9.1 → sqlrite-0.10.1}/examples/rust/quickstart.rs +0 -0
  201. {sqlrite-0.9.1 → sqlrite-0.10.1}/examples/wasm/Makefile +0 -0
  202. {sqlrite-0.9.1 → sqlrite-0.10.1}/examples/wasm/index.html +0 -0
  203. {sqlrite-0.9.1 → sqlrite-0.10.1}/examples/wasm/server.mjs +0 -0
  204. {sqlrite-0.9.1 → sqlrite-0.10.1}/images/SQLRite - Desktop.png +0 -0
  205. {sqlrite-0.9.1 → sqlrite-0.10.1}/images/SQLRite Data Structures.png +0 -0
  206. {sqlrite-0.9.1 → sqlrite-0.10.1}/images/SQLRite Simple SQL Execution High Level Diagram.png +0 -0
  207. {sqlrite-0.9.1 → sqlrite-0.10.1}/images/SQLRite Simple SQL INSERT Execution High Level Diagram (Insert Row).png +0 -0
  208. {sqlrite-0.9.1 → sqlrite-0.10.1}/images/SQLRite Simple SQL INSERT Execution High Level Diagram.png +0 -0
  209. {sqlrite-0.9.1 → sqlrite-0.10.1}/images/SQLRite_logo.png +0 -0
  210. {sqlrite-0.9.1 → sqlrite-0.10.1}/images/architecture.png +0 -0
  211. {sqlrite-0.9.1 → sqlrite-0.10.1}/rust-toolchain.toml +0 -0
  212. {sqlrite-0.9.1 → sqlrite-0.10.1}/samples/AST.delete.example +0 -0
  213. {sqlrite-0.9.1 → sqlrite-0.10.1}/samples/AST.insert.exemple +0 -0
  214. {sqlrite-0.9.1 → sqlrite-0.10.1}/samples/AST.select.example +0 -0
  215. {sqlrite-0.9.1 → sqlrite-0.10.1}/samples/AST.update.example +0 -0
  216. {sqlrite-0.9.1 → sqlrite-0.10.1}/samples/CREATE TABLE sqlrite_schema.sql +0 -0
  217. {sqlrite-0.9.1 → sqlrite-0.10.1}/samples/CREATE_TABLE with duplicate.sql +0 -0
  218. {sqlrite-0.9.1 → sqlrite-0.10.1}/samples/CREATE_TABLE.sql +0 -0
  219. {sqlrite-0.9.1 → sqlrite-0.10.1}/samples/INSERT.sql +0 -0
  220. {sqlrite-0.9.1 → sqlrite-0.10.1}/sdk/go/ask.go +0 -0
  221. {sqlrite-0.9.1 → sqlrite-0.10.1}/sdk/go/ask_test.go +0 -0
  222. {sqlrite-0.9.1 → sqlrite-0.10.1}/sdk/go/go.mod +0 -0
  223. {sqlrite-0.9.1 → sqlrite-0.10.1}/sdk/go/rows.go +0 -0
  224. {sqlrite-0.9.1 → sqlrite-0.10.1}/sdk/go/stmt.go +0 -0
  225. {sqlrite-0.9.1 → sqlrite-0.10.1}/sdk/python/README.md +0 -0
  226. {sqlrite-0.9.1 → sqlrite-0.10.1}/sdk/python/tests/test_ask.py +0 -0
  227. {sqlrite-0.9.1 → sqlrite-0.10.1}/sqlrite-ask/README.md +0 -0
  228. {sqlrite-0.9.1 → sqlrite-0.10.1}/sqlrite-ask/src/lib.rs +0 -0
  229. {sqlrite-0.9.1 → sqlrite-0.10.1}/sqlrite-ask/src/prompt.rs +0 -0
  230. {sqlrite-0.9.1 → sqlrite-0.10.1}/sqlrite-ask/src/provider/anthropic.rs +0 -0
  231. {sqlrite-0.9.1 → sqlrite-0.10.1}/sqlrite-ask/src/provider/mock.rs +0 -0
  232. {sqlrite-0.9.1 → sqlrite-0.10.1}/sqlrite-ask/src/provider/mod.rs +0 -0
  233. {sqlrite-0.9.1 → sqlrite-0.10.1}/sqlrite-ask/tests/anthropic_http.rs +0 -0
  234. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/agg.rs +0 -0
  235. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/db/mod.rs +0 -0
  236. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/db/secondary_index.rs +0 -0
  237. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/dialect.rs +0 -0
  238. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/fts/bm25.rs +0 -0
  239. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/fts/mod.rs +0 -0
  240. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/fts/posting_list.rs +0 -0
  241. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/fts/tokenizer.rs +0 -0
  242. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/pager/allocator.rs +0 -0
  243. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/pager/cell.rs +0 -0
  244. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/pager/file.rs +0 -0
  245. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/pager/freelist.rs +0 -0
  246. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/pager/fts_cell.rs +0 -0
  247. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/pager/header.rs +0 -0
  248. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/pager/hnsw_cell.rs +0 -0
  249. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/pager/index_cell.rs +0 -0
  250. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/pager/interior_page.rs +0 -0
  251. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/pager/overflow.rs +0 -0
  252. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/pager/page.rs +0 -0
  253. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/pager/table_page.rs +0 -0
  254. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/pager/varint.rs +0 -0
  255. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/params.rs +0 -0
  256. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/parser/create.rs +0 -0
  257. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/parser/insert.rs +0 -0
  258. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/parser/mod.rs +0 -0
  259. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/parser/select.rs +0 -0
  260. {sqlrite-0.9.1 → sqlrite-0.10.1}/src/sql/tokenizer.rs +0 -0
@@ -299,6 +299,15 @@ jobs:
299
299
  wasm-build:
300
300
  name: wasm-build
301
301
  runs-on: ubuntu-latest
302
+ # Pinned binaryen version — see docs/release-plan.md
303
+ # ("Pinned binaryen / wasm-opt") for the bump procedure. Older
304
+ # binaryen rejects rustc's multi-table WASM output with
305
+ # "Only 1 table definition allowed in MVP", which the runner
306
+ # image's cache state used to surface non-deterministically
307
+ # (SQLR-58). Pinning keeps wasm-opt out of "whatever's cached"
308
+ # territory.
309
+ env:
310
+ BINARYEN_VERSION: version_122
302
311
  steps:
303
312
  - uses: actions/checkout@v4
304
313
 
@@ -313,12 +322,29 @@ jobs:
313
322
  workspaces: sdk/wasm
314
323
  shared-key: wasm-build
315
324
 
325
+ - name: Install pinned binaryen (wasm-opt)
326
+ # MUST run before wasm-pack: wasm-pack picks up wasm-opt from
327
+ # PATH if present, otherwise downloads whatever binaryen its
328
+ # own internal cache happens to have. Pinning + prepending
329
+ # to PATH forces a deterministic version across runner images.
330
+ run: |
331
+ set -euo pipefail
332
+ curl -fsSL "https://github.com/WebAssembly/binaryen/releases/download/${BINARYEN_VERSION}/binaryen-${BINARYEN_VERSION}-x86_64-linux.tar.gz" \
333
+ -o "$RUNNER_TEMP/binaryen.tar.gz"
334
+ tar -xzf "$RUNNER_TEMP/binaryen.tar.gz" -C "$RUNNER_TEMP"
335
+ echo "$RUNNER_TEMP/binaryen-${BINARYEN_VERSION}/bin" >> "$GITHUB_PATH"
336
+ "$RUNNER_TEMP/binaryen-${BINARYEN_VERSION}/bin/wasm-opt" --version
337
+
316
338
  - name: Install wasm-pack
317
339
  uses: jetli/wasm-pack-action@v0.4.0
318
340
 
319
341
  - name: wasm-pack build --target web --release
320
342
  working-directory: sdk/wasm
321
- run: wasm-pack build --target web --release
343
+ run: |
344
+ # Sanity-check that the pinned wasm-opt is what wasm-pack sees.
345
+ which wasm-opt
346
+ wasm-opt --version
347
+ wasm-pack build --target web --release
322
348
 
323
349
  - name: Report .wasm size
324
350
  # Surfaces size regressions in PR logs. Not a hard limit yet;
@@ -1189,6 +1189,14 @@ jobs:
1189
1189
  if: needs.detect.outputs.should_release == 'true'
1190
1190
  runs-on: ubuntu-latest
1191
1191
  environment: release
1192
+ # Pinned binaryen version — see docs/release-plan.md
1193
+ # ("Pinned binaryen / wasm-opt") for the bump procedure. Older
1194
+ # binaryen rejects rustc's multi-table WASM output with
1195
+ # "Only 1 table definition allowed in MVP" (SQLR-58). The
1196
+ # release pipeline can't tolerate that flake — a failed
1197
+ # publish-wasm leaves the rest of the release wave inconsistent.
1198
+ env:
1199
+ BINARYEN_VERSION: version_122
1192
1200
  permissions:
1193
1201
  # OIDC: required for npm trusted-publisher token exchange.
1194
1202
  # Same flow proven in publish-nodejs after the v0.1.5–0.1.7
@@ -1207,6 +1215,20 @@ jobs:
1207
1215
  shared-key: publish-wasm
1208
1216
  workspaces: 'sdk/wasm -> target'
1209
1217
 
1218
+ - name: Install pinned binaryen (wasm-opt)
1219
+ # MUST run before wasm-pack: wasm-pack picks up wasm-opt
1220
+ # from PATH if present, otherwise downloads whatever
1221
+ # binaryen its own internal cache happens to have. Pinning
1222
+ # + prepending to PATH forces a deterministic version
1223
+ # across runner images.
1224
+ run: |
1225
+ set -euo pipefail
1226
+ curl -fsSL "https://github.com/WebAssembly/binaryen/releases/download/${BINARYEN_VERSION}/binaryen-${BINARYEN_VERSION}-x86_64-linux.tar.gz" \
1227
+ -o "$RUNNER_TEMP/binaryen.tar.gz"
1228
+ tar -xzf "$RUNNER_TEMP/binaryen.tar.gz" -C "$RUNNER_TEMP"
1229
+ echo "$RUNNER_TEMP/binaryen-${BINARYEN_VERSION}/bin" >> "$GITHUB_PATH"
1230
+ "$RUNNER_TEMP/binaryen-${BINARYEN_VERSION}/bin/wasm-opt" --version
1231
+
1210
1232
  # Install wasm-pack — the canonical tool for building +
1211
1233
  # packaging Rust crates as npm-publishable WASM modules.
1212
1234
  # `cargo binstall` would be faster than `cargo install`
@@ -1239,6 +1261,9 @@ jobs:
1239
1261
  - name: Build WASM package
1240
1262
  working-directory: sdk/wasm
1241
1263
  run: |
1264
+ # Sanity-check that the pinned wasm-opt is on PATH (SQLR-58).
1265
+ which wasm-opt
1266
+ wasm-opt --version
1242
1267
  wasm-pack build --release --target bundler --scope joaoh82
1243
1268
  echo "--- generated pkg/ contents ---"
1244
1269
  ls -la pkg/
@@ -44,3 +44,12 @@ examples/wasm/pkg
44
44
 
45
45
  # macOS
46
46
  .DS_Store
47
+
48
+ # Local agent / Claude Code worktrees. These shouldn't ever get
49
+ # committed — but `git add -A` from main while a worktree is live
50
+ # under .claude/worktrees/<name>/ will capture it as a gitlink
51
+ # (mode 160000) because the worktree dir looks like a submodule to
52
+ # the parent index. Ignoring the whole tree prevents that whole
53
+ # class of accident. (The release commit 937f8b4 hit exactly this
54
+ # bug; the next commit untracks the leftover gitlinks.)
55
+ .claude/worktrees/
@@ -16,6 +16,7 @@ SQLRite is a from-scratch SQLite-style embedded database written in Rust. It's p
16
16
  - `sqlrite-ffi/` — C ABI cdylib + generated `sqlrite.h` header. Backs the Go SDK and any C consumer.
17
17
  - `desktop/` — Tauri 2 + Svelte 5 GUI. Embeds the engine directly (no FFI hop).
18
18
  - `benchmarks/` — SQLR-4 / SQLR-16 bench harness. `Driver` trait + SQLRite + SQLite (rusqlite-bundled) drivers + criterion-driven workloads. Excluded from the default CI build/test/clippy/doc commands; run locally with `make bench` (or `make bench-duckdb`). See [docs/benchmarks-plan.md](docs/benchmarks-plan.md).
19
+ - `web/` — marketing + docs site (Next.js 15 + Tailwind v4). Independent of the Cargo workspace; lives in-repo for now but is structured to lift into its own repository later. See [web/README.md](web/README.md).
19
20
 
20
21
  Architecture deep-dive: [docs/architecture.md](docs/architecture.md). The full doc index is [docs/_index.md](docs/_index.md).
21
22
 
@@ -4799,7 +4799,7 @@ dependencies = [
4799
4799
 
4800
4800
  [[package]]
4801
4801
  name = "sqlrite-ask"
4802
- version = "0.9.1"
4802
+ version = "0.10.1"
4803
4803
  dependencies = [
4804
4804
  "serde",
4805
4805
  "serde_json",
@@ -4827,7 +4827,7 @@ dependencies = [
4827
4827
 
4828
4828
  [[package]]
4829
4829
  name = "sqlrite-desktop"
4830
- version = "0.9.1"
4830
+ version = "0.10.1"
4831
4831
  dependencies = [
4832
4832
  "serde",
4833
4833
  "serde_json",
@@ -4839,7 +4839,7 @@ dependencies = [
4839
4839
 
4840
4840
  [[package]]
4841
4841
  name = "sqlrite-engine"
4842
- version = "0.9.1"
4842
+ version = "0.10.1"
4843
4843
  dependencies = [
4844
4844
  "clap",
4845
4845
  "env_logger",
@@ -4856,7 +4856,7 @@ dependencies = [
4856
4856
 
4857
4857
  [[package]]
4858
4858
  name = "sqlrite-ffi"
4859
- version = "0.9.1"
4859
+ version = "0.10.1"
4860
4860
  dependencies = [
4861
4861
  "cbindgen",
4862
4862
  "serde",
@@ -4866,7 +4866,7 @@ dependencies = [
4866
4866
 
4867
4867
  [[package]]
4868
4868
  name = "sqlrite-mcp"
4869
- version = "0.9.1"
4869
+ version = "0.10.1"
4870
4870
  dependencies = [
4871
4871
  "clap",
4872
4872
  "libc",
@@ -4877,7 +4877,7 @@ dependencies = [
4877
4877
 
4878
4878
  [[package]]
4879
4879
  name = "sqlrite-nodejs"
4880
- version = "0.9.1"
4880
+ version = "0.10.1"
4881
4881
  dependencies = [
4882
4882
  "napi",
4883
4883
  "napi-build",
@@ -4887,7 +4887,7 @@ dependencies = [
4887
4887
 
4888
4888
  [[package]]
4889
4889
  name = "sqlrite-python"
4890
- version = "0.9.1"
4890
+ version = "0.10.1"
4891
4891
  dependencies = [
4892
4892
  "pyo3",
4893
4893
  "sqlrite-engine",
@@ -27,7 +27,7 @@ resolver = "3"
27
27
  # `package =` key so the import name stays `sqlrite` internally:
28
28
  # sqlrite = { package = "sqlrite-engine", path = "…" }
29
29
  name = "sqlrite-engine"
30
- version = "0.9.1"
30
+ version = "0.10.1"
31
31
  authors = ["Joao Henrique Machado Silva <joaoh82@gmail.com>"]
32
32
  edition = "2024"
33
33
  rust-version = "1.85"
@@ -73,6 +73,15 @@ path = "examples/rust/quickstart.rs"
73
73
  name = "hybrid-retrieval"
74
74
  path = "examples/hybrid-retrieval/hybrid_retrieval.rs"
75
75
 
76
+ # Phase 11.12 — BEGIN CONCURRENT retry-loop demo. Mints a sibling
77
+ # Connection via `Connection::connect`, runs two concurrent
78
+ # transactions (first disjoint, then same-row), and surfaces the
79
+ # Busy / retry path. Run with `cargo run --example concurrent_writers`.
80
+ # See `docs/concurrent-writes.md` for the conceptual walkthrough.
81
+ [[example]]
82
+ name = "concurrent_writers"
83
+ path = "examples/rust/concurrent_writers.rs"
84
+
76
85
  [features]
77
86
  # Default build includes everything: the REPL binary (cli) and
78
87
  # POSIX/Windows advisory file locks on the Pager (file-locks).
@@ -141,4 +150,4 @@ fs2 = { version = "0.4", optional = true }
141
150
  # crate publishes to crates.io, and a path-only dep without a
142
151
  # version field fails the manifest verification step. See PR #58
143
152
  # retrospective in docs/roadmap.md.
144
- sqlrite-ask = { version = "0.9.1", path = "sqlrite-ask", optional = true }
153
+ sqlrite-ask = { version = "0.10.1", path = "sqlrite-ask", optional = true }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlrite
3
- Version: 0.9.1
3
+ Version: 0.10.1
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -11,6 +11,8 @@ Rust-SQLite (SQLRite)
11
11
  > What I cannot create, I do not understand.
12
12
  > — Richard Feynman
13
13
 
14
+ 📖 **Project website + docs:** the marketing + getting-started site is in [`web/`](web/) (Next.js 15 + Tailwind v4). Run `cd web && npm install && npm run dev` to preview locally; deploys to Vercel out of the box.
15
+
14
16
 
15
17
  <table style="width:100%">
16
18
  <tr>
@@ -106,6 +108,15 @@ Wire it into Claude Code (`~/.claude.json`):
106
108
 
107
109
  `--read-only` opens the DB with a shared lock and hides the `execute` tool. Full docs + the other six tools' references in [`docs/mcp.md`](docs/mcp.md).
108
110
 
111
+ ### End-to-end example apps
112
+
113
+ Beyond the per-language quickstarts in [`examples/`](examples/), the SQLR-38 umbrella tracks longer, opinionated example apps that exercise SQLRite in real-world shapes:
114
+
115
+ | App | SDK | What it shows |
116
+ |---|---|---|
117
+ | [Python LLM agent with persistent memory](examples/python-agent/) | Python | Vector + lexical recall, fact extraction, summaries — all in one `.sqlrite` file |
118
+ | [Chat-with-your-notes via Claude Desktop MCP](examples/nodejs-notes/) | Node.js | Markdown → hybrid HNSW + BM25 index → `sqlrite-mcp --read-only` → Claude Desktop |
119
+
109
120
  ### Developer guide
110
121
 
111
122
  In-depth documentation lives under [`docs/`](docs/). Start at [`docs/_index.md`](docs/_index.md) — it navigates to:
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sqlrite-desktop-frontend",
3
3
  "private": true,
4
- "version": "0.9.1",
4
+ "version": "0.10.1",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite",
@@ -16,7 +16,8 @@ A small, hand-written guide to the SQLRite codebase — how it's structured, how
16
16
  ## Using SQLRite as a library
17
17
 
18
18
  - [Embedding](embedding.md) — the public `Connection` / `Statement` / `Rows` API (Phase 5a) and where the non-Rust SDKs plug in (Phase 5b – 5g)
19
- - [`examples/`](../examples/) — runnable Rust quickstart (`cargo run --example quickstart`); language-specific subdirectories fill in as each 5x sub-phase lands
19
+ - [Concurrent writes — MVCC + `BEGIN CONCURRENT`](concurrent-writes.md) — Phase 11 canonical reference: SQL surface, embedding API, SDK error mapping, REPL meta-commands, durability story, limitations. Design rationale lives in the [historical plan-doc](concurrent-writes-plan.md).
20
+ - [`examples/`](../examples/) — runnable Rust quickstart (`cargo run --example quickstart`) + concurrent-writers retry-loop demo (`cargo run --example concurrent_writers`); language-specific subdirectories fill in as each 5x sub-phase lands
20
21
 
21
22
  ## Phase 7 — AI-era extensions
22
23
 
@@ -52,6 +53,9 @@ As of May 2026, SQLRite has:
52
53
  - A Tauri 2.0 + Svelte desktop app (Phase 2.5 complete)
53
54
  - AI-era extensions across the product surface (Phase 7 complete): VECTOR columns + HNSW indexes (7a-7d), JSON columns (7e), the `ask()` natural-language → SQL family across the REPL / desktop / Rust / Python / Node / Go / WASM (7g.1-7g.7), and the [`sqlrite-mcp`](mcp.md) Model Context Protocol server (7h + 7g.8)
54
55
  - Full-text search + hybrid retrieval (Phase 8 complete): FTS5-style inverted index with BM25 ranking + `fts_match` / `bm25_score` scalar functions + `try_fts_probe` optimizer hook + on-disk persistence with on-demand v4 → v5 file-format bump (8a-8c), a worked hybrid-retrieval example combining BM25 with vector cosine via raw arithmetic (8d), and a `bm25_search` MCP tool symmetric with `vector_search` (8e). See [`docs/fts.md`](fts.md).
56
+ - SQL surface + DX follow-ups (Phase 9 complete, v0.2.0 → v0.9.1): DDL completeness — `DEFAULT`, `DROP TABLE` / `DROP INDEX`, `ALTER TABLE` (9a); free-list + manual `VACUUM` (9b) + auto-VACUUM (9c); `IS NULL` / `IS NOT NULL` (9d); `GROUP BY` + aggregates + `DISTINCT` + `LIKE` + `IN` (9e); four flavors of `JOIN` — INNER, LEFT, RIGHT, FULL OUTER (9f); prepared statements + `?` parameter binding with a per-connection LRU plan cache (9g); HNSW probe widened to cosine + dot via `WITH (metric = …)` (9h); `PRAGMA` dispatcher with the `auto_vacuum` knob (9i)
57
+ - Benchmarks against SQLite + DuckDB (Phase 10 complete, SQLR-4 / SQLR-16): twelve-workload bench harness with a pluggable `Driver` trait, criterion-driven, pinned-host runs published. See [`docs/benchmarks.md`](benchmarks.md).
58
+ - Phase 11 (concurrent writes via MVCC + `BEGIN CONCURRENT`, SQLR-22) is **shipped end-to-end** — `Connection` is `Send + Sync`; `Connection::connect()` mints sibling handles. `sqlrite::mvcc` exposes `MvccClock`, `ActiveTxRegistry`, `MvStore`, `ConcurrentTx`, and the `MvccCommitBatch` / `MvccLogRecord` WAL codec. WAL header v1 → v2 persisted the clock high-water mark; v2 → v3 added typed MVCC log-record frames. `PRAGMA journal_mode = mvcc;` opts a database into MVCC. `BEGIN CONCURRENT` writes commit-validate against `MvStore`, abort with `SQLRiteError::Busy`, and append a typed MVCC log-record frame to the WAL — covered by the same fsync as the legacy page commit. Reopen replays those frames into `MvStore` and seeds `MvccClock` past the highest committed `commit_ts`. Reads via `Statement::query` see the BEGIN-time snapshot. Per-commit GC + `vacuum_mvcc()` bound version-chain growth. C FFI / Python / Node / Go all propagate `Busy` / `BusySnapshot` as typed retryable errors *and* mint sibling handles that share backing state — Go's process-level path registry (Phase 11.11c) handles cross-`*sql.DB` sharing too. The `sqlrite` REPL ships `.spawn` / `.use` / `.conns` for interactive demos; the SQLR-16 benchmark suite adds `W13` (concurrent writers, mostly disjoint rows) as the Phase-11 differentiator workload. The only remaining items are deferred-by-design or foundation work: indexes under MVCC (11.10) and the checkpoint-drain follow-up (parked half of 11.9). **User-facing reference:** [`docs/concurrent-writes.md`](concurrent-writes.md); runnable example at [`examples/rust/concurrent_writers.rs`](../examples/rust/concurrent_writers.rs). Original design proposal: [`docs/concurrent-writes-plan.md`](concurrent-writes-plan.md).
55
59
  - A fully-automated release pipeline that ships every product to its registry on every release with one human action — Rust engine + `sqlrite-ask` + `sqlrite-mcp` to crates.io, Python wheels to PyPI (`sqlrite`), Node.js + WASM to npm (`@joaoh82/sqlrite` + `@joaoh82/sqlrite-wasm`), Go module via `sdk/go/v*` git tag, plus C FFI tarballs, MCP binary tarballs, and unsigned desktop installers as GitHub Release assets (Phase 6 complete)
56
60
 
57
61
  See the [Roadmap](roadmap.md) for the full phase plan.
@@ -111,6 +111,16 @@ For W10/W11, the goal isn't to beat the comparators — they're battle-hardened
111
111
 
112
112
  For W12, no off-the-shelf comparator exists in a single embedded engine; the number stands on its own.
113
113
 
114
+ ### Group D — Concurrent writes (Phase 11.11b, the Phase-11 MVCC differentiator)
115
+
116
+ | ID | Name | Shape | Comparator |
117
+ |----|------|-------|------------|
118
+ | W13 | Concurrent writers | 4 worker threads × 50 BEGIN/UPDATE/COMMIT cycles each, random rowid in `1..=1000` (≈ 0.4% collision per op), `UPDATE counters SET n = n + 1 WHERE id = ?` | SQLite (`BEGIN IMMEDIATE` + `busy_timeout = 5s` per-connection) |
119
+
120
+ The headline workload Phase 11's MVCC machinery was designed for. SQLRite drives `BEGIN CONCURRENT` across sibling [`Connection::connect`](../docs/concurrent-writes.md) handles minted from the same process; SQLite drives `BEGIN IMMEDIATE` across separate `rusqlite::Connection` handles serializing through the WAL write lock. Both engines run the same retry-on-busy outer loop ([`is_retryable_busy`](../benchmarks/src/lib.rs) is engine-dispatched); only SQLRite actually exercises the retry path under this workload's shape — the contrast *is* the measurement.
121
+
122
+ Workload parameters live in [`benchmarks/src/workloads/concurrent_writers.rs`](../benchmarks/src/workloads/concurrent_writers.rs) as named constants (`W13_PRELOAD_ROWS`, `W13_N_WORKERS`, `W13_TXS_PER_WORKER`). Bumping any of them is a workload-version bump under Q8.
123
+
114
124
  ---
115
125
 
116
126
  ## Metrics
@@ -127,9 +137,10 @@ Keep tight. The task brief lists many candidates; the suite measures these:
127
137
  Explicitly **not** measured in v1:
128
138
 
129
139
  - **CPU%.** Noisy on a shared machine, redundant with wall-clock for single-threaded workloads.
130
- - **Concurrency curves.** Engine is single-writer by design (Phase 4e). No concurrent-writer workload is meaningful until that changes.
131
140
  - **Network I/O.** All targets are in-process.
132
141
 
142
+ **Updated post-Phase 11.11b:** Group D's `W13` (concurrent writers) lifts the single-writer caveat — SQLRite now has a real multi-writer story via `BEGIN CONCURRENT`, and W13 measures it directly against SQLite's single-writer baseline. Full concurrency-curve sweeps (varying `N` workers and collision rate) are a clean follow-up; v1 reports a single representative point.
143
+
133
144
  ---
134
145
 
135
146
  ## Methodology
@@ -190,7 +201,8 @@ benchmarks/
190
201
  │ ├── join.rs — W9
191
202
  │ ├── vector.rs — W10
192
203
  │ ├── fts.rs — W11
193
- └── hybrid.rs — W12
204
+ ├── hybrid.rs — W12
205
+ │ └── concurrent_writers.rs — W13 (Phase 11.11b)
194
206
  ├── benches/
195
207
  │ └── suite.rs — single criterion entry point that fans out
196
208
  ├── scripts/
@@ -264,11 +276,18 @@ Add the `duckdb-rs` driver under a `--features duckdb` flag. Wire only into Grou
264
276
 
265
277
  **Exit criterion:** `docs/benchmarks.md` exists, the README has a "Benchmarks" section pointing at it, the first dated results JSON is committed.
266
278
 
267
- ### Post-9.6 ideas (parked)
279
+ ### 9.7 Group D concurrent writers (Phase 11.11b, shipped)
280
+
281
+ Adds `W13` (concurrent writers, mostly-disjoint rows) under a new Group D. The `Driver` trait grows three optional methods (`connect_sibling`, `concurrent_begin_sql`, `is_retryable_busy`) with defaults that make sense for engines without an MVCC story; SQLRite overrides all three. SQLite gains a `busy_timeout = 5s` pragma at open so its `BEGIN IMMEDIATE` blocks rather than fails on contention. The workload lives in [`benchmarks/src/workloads/concurrent_writers.rs`](../benchmarks/src/workloads/concurrent_writers.rs).
282
+
283
+ **Exit criterion:** W13 runs under both drivers, correctness gate passes (`SUM(n) == n_workers * txs_per_worker` after a sample), and the JSON envelope picks up `W13.v1` rows for both drivers.
284
+
285
+ ### Post-9.7 ideas (parked)
268
286
 
269
287
  - **libSQL driver** if/when we want a non-extension vector competitor for W10.
270
288
  - **Per-PR regression detector.** A GitHub Action that runs the bench on a self-hosted runner and posts a comment if any workload regresses >20% from the last `main` baseline.
271
- - **Concurrency workloads** if/when SQLRite gains true multi-writer support.
289
+ - **Concurrency curves for W13.** Sweep `N` workers (1, 2, 4, 8, 16) and `K` rows (10, 100, 1k, 10k) to chart SQLRite-MVCC's scaling envelope vs SQLite's serial baseline. v1 reports a single representative point; the sweep is a clean follow-up.
290
+ - **W13b hot-row contention.** Same workload, `K = 10` rows instead of 1000 — collision probability climbs to ~40% per op, exercising the retry loop hard. Useful for stressing the GC + retry path under adversarial contention.
272
291
  - **Larger datasets (10M, 100M).** v1 is sized for fast iteration on a laptop. A "release-blocker run" config could 100× the row counts.
273
292
 
274
293
  ### Total scope estimate
@@ -1,8 +1,16 @@
1
1
  # Concurrent writes plan — MVCC + `BEGIN CONCURRENT`
2
2
 
3
- **Status:** proposal, not yet scheduled. Drafted 2026-05-07.
3
+ > 📘 **Looking for the user-facing reference?** This is the original
4
+ > design proposal, kept as the historical record of the decisions
5
+ > that shaped Phase 11. For the shipped surface — SQL, embedding API,
6
+ > SDK error mapping, REPL meta-commands, durability story,
7
+ > limitations — read [**`concurrent-writes.md`**](concurrent-writes.md)
8
+ > first; come back here when you want the *why* and the
9
+ > sequencing discussion.
10
+
11
+ **Status:** shipped end-to-end through Phase 11.11a (May 2026); a small set of follow-ups remain explicitly parked — see the [roadmap](roadmap.md#phase-11--concurrent-writes-via-mvcc--begin-concurrent-sqlr-22-in-flight--see-concurrent-writes-planmd). Drafted 2026-05-07.
4
12
  **Inspiration:** [Turso](https://turso.tech) — a SQLite-compatible engine, written in Rust, that implements multi-version concurrency control to lift SQLite's single-writer ceiling. See [`turso/core/mvcc/`](https://github.com/tursodatabase/turso/tree/main/core/mvcc) and the [Turso concurrent-writes docs](https://docs.turso.tech/tursodb/concurrent-writes).
5
- **Tracks:** SQLR-?? (Marvin) — to be filed alongside this doc.
13
+ **Tracks:** [SQLR-22](https://app.marvinapp.io/) (Marvin).
6
14
 
7
15
  This document proposes adding **multi-version concurrency control (MVCC)** and a **`BEGIN CONCURRENT`** transaction mode to SQLRite, enabling multiple writers in the same process to make progress in parallel under snapshot isolation, with row-level write-write conflict detection at commit. It is intentionally a *plan* — there is no code yet.
8
16
 
@@ -270,9 +278,11 @@ Goal: more than one `Connection` can target the same `Database` within a process
270
278
 
271
279
  ### Phase 10.5 — Checkpoint + crash recovery
272
280
 
273
- - Extend the checkpointer to drain MVCC log records into pager-level updates before folding the WAL into the main file.
274
- - Crash recovery: on open, replay WAL log records into `MvStore`, then replay pager-level commit frames as today.
275
- - Tests: kill the process mid-MVCC-commit (between log-record append and version-chain push), reopen, verify the committed transaction is visible and the half-written one is not.
281
+ > **Status (roadmap 11.9 — May 2026):** The crash-recovery half landed in roadmap Phase 11.9. WAL format is bumped to v3; commits append a typed `MvccCommitBatch` frame before the legacy save's fsync; reopen replays those frames into `MvStore` and seeds `MvccClock` past the highest `commit_ts`. The checkpoint-drain half — folding MVCC log records into pager-level updates and re-enabling the `Mvcc Wal` journal-mode downgrade — is the remaining slice and stays parked for a follow-up.
282
+
283
+ - ~~Extend the checkpointer to drain MVCC log records into pager-level updates before folding the WAL into the main file.~~ *Deferred see status note above.*
284
+ - Crash recovery: on open, replay WAL log records into `MvStore`, then replay pager-level commit frames as today. **(Shipped — 11.9.)**
285
+ - Tests: kill the process mid-MVCC-commit (between log-record append and version-chain push), reopen, verify the committed transaction is visible and the half-written one is not. **(Shipped — 11.9 covers the clean-drop case which exercises the same recovery codepath; a real OS-kill test is parked with the checkpoint-drain follow-up.)**
276
286
 
277
287
  ### Phase 10.6 — Garbage collection
278
288
 
@@ -294,9 +304,11 @@ Index maintenance under MVCC is hard enough that Turso explicitly punted on it.
294
304
 
295
305
  ### Phase 10.9 — Docs
296
306
 
297
- - Promote this plan to `docs/concurrent-writes.md` (the canonical user-facing reference), keeping `concurrent-writes-plan.md` as the historical design document.
298
- - Update [roadmap.md](roadmap.md), [`docs/_index.md`](_index.md), [supported-sql.md](supported-sql.md), [embedding.md](embedding.md), [design-decisions.md](design-decisions.md).
299
- - Add a worked example under `examples/rust/concurrent_writers.rs`.
307
+ > **Status (roadmap 11.12 May 2026):** Shipped. The canonical user-facing reference at [`docs/concurrent-writes.md`](concurrent-writes.md) covers the SQL surface, embedding API, SDK error mapping, REPL meta-commands, durability story, and limitations as of Phase 11.11a. This plan-doc is now the historical record. Cross-references in `_index.md`, `supported-sql.md`, `embedding.md`, and `design-decisions.md` point at the canonical doc; a runnable example lives at [`examples/rust/concurrent_writers.rs`](../examples/rust/concurrent_writers.rs).
308
+
309
+ - Promote this plan to `docs/concurrent-writes.md` (the canonical user-facing reference), keeping `concurrent-writes-plan.md` as the historical design document. **(Shipped — 11.12.)**
310
+ - Update [roadmap.md](roadmap.md), [`docs/_index.md`](_index.md), [supported-sql.md](supported-sql.md), [embedding.md](embedding.md), [design-decisions.md](design-decisions.md). **(Shipped — 11.12.)**
311
+ - Add a worked example under `examples/rust/concurrent_writers.rs`. **(Shipped — 11.12.)**
300
312
 
301
313
  ---
302
314