# sapedb — planning, in full > The public planning record for sapedb. This file carries the whole listing so a reader does not have > to follow forty links to see the shape of the release. ## What sapedb is A storage engine whose only interface is a named, declared operation. There is no query language: no query text ever reaches it. Everything a caller can run was written down first — which collection it touches, which index it walks, how far, what it returns, and who may run it. The reason is quoted from the source, in `internal/store/ops.go`: anything richer than the four shapes a term can take is an expression language, which is the thing this store exists not to have. What that buys, and the thing this project plans around: **cost is declared, not discovered**. A scan states its limit and so does a count, so the ceiling can be read before anything runs — unlike `EXPLAIN`, which tells you what a planner chose that time. Operations can call other operations, and the ceiling of a composed operation at any depth is still the number it declares, not a product a reader has to multiply out. ## How this planning works - **Two backlogs per version.** One holds the release scope. The other holds issues the work itself turned up. - **Done is a measurement, not a judgement.** Every ticket carries an acceptance criterion somebody runs and watches pass or fail. "It feels finished" is not one. - **Issues are triaged once**, against a single question: does it lose data, break a promise on a public surface, or stop somebody installing and running the thing? No means it waits, however true or embarrassing it is. A backlog that grows as fast as it shrinks has no answer to *is it done yet*. - **No dates.** Nobody has fixed one. What is fixed is the order and what blocks what. - **Nothing is sold on speed.** Where a number exists it is published with the layer it was measured at. ## Version 1.0.0 — in progress A version number here is a promise that cannot be withdrawn. 1.0.0 freezes four surfaces: - **On-disk format.** Any 1.x build opens a database written by any other 1.x build. - **Wire protocol.** Frames 1…13 never change role; new frames start at 14; fields may be added, never renamed and never removed. - **Declaration semantics.** An operation declared against 1.0 means the same thing on every later 1.x. Declarations are stored in the database, so this is a promise about files people already wrote. - **Public API.** The exported names of `package sapedb` and the APIs of the TypeScript, Go and PHP clients. It does not promise performance, the ordering of reads against writes (the README already says a snapshot-read path could change it), the file layout inside a partition, or anything under `internal/`. ### Backlog 1 — release scope Open: - **SAPE-2** — Versioning and compatibility policy. The four surfaces above, made binding. - **SAPE-3** — Prebuilt binaries and a published container image. A Dockerfile exists; there is no release workflow, so running sapedb today means building it from source. - **SAPE-4** — Tag-driven release workflow for the server. - **SAPE-5** — Install path and quickstart. The acceptance criterion is that the person following it is not the person who wrote it, on a machine with no Go. - **SAPE-6** — Upgrade rehearsal. Nobody has ever upgraded a sapedb: zero tags, zero migration paths. One build writes, the next reads it all back, compared document by document rather than by counting — the failure that catches is a document that survives with a field missing, which a count cannot see. - **SAPE-7** — Config reload, led by partial reload: some load, and it says so instead of reporting success. - **SAPE-8** — Read an operation's cost envelope before trusting it. - **SAPE-9** — Name collision: decide whether namespaces exist. Today there are none, and declaring an existing name creates a new version of yours. - **SAPE-10** — Sign and verify an operation binary. - **SAPE-11** — List the external operations installed on a server. - **SAPE-12** — One worked external operation, published as a challenge. - **SAPE-13** — An artifact describing the shape of a request body. The fixtures pin the wire envelope and not the body, so a client written only from them can send the wrong field name and keep a green test suite. - **SAPE-14** — `Declare` for collections. Today only operations can be declared on a running server. Done, in 1.0.0: - **SAPE-1** — Build identity. The version is embedded at build time, `sapedb version` prints it, and the daemon states its product version in the handshake. Measured by building from two tags and watching a client of one version report the other. - **SAPE-15** — learn.sapedb.com, with every code sample run against a real daemon. - **SAPE-16** — sapedb.com. - **SAPE-17** — The on-disk format tag and the three key-derivation labels say sapedb. This was the last window in which that was cheap: a format is the one thing that never comes back. - **SAPE-18** — Reads share a database instead of queueing behind each other, with no change to what a caller observes. - **SAPE-19** — Declare an operation against a running daemon, frame 13, instead of stopping the server to apply a file. - **SAPE-20** — Composed operations: a step may call a declared operation, exactly once, and the ceiling of the whole thing at any depth is the limit it declares. - **SAPE-21** — Scopes travel the wire as a signed grant, so a caller cannot name its own permissions. - **SAPE-22** — A count must declare how far it walks, like every other declaration. A breaking change, made before the tag rather than after. - **SAPE-23** — `InvokeVersion`, so an older declaration is reachable again. - **SAPE-24** — Three clients, each run against a real daemon: TypeScript, Go, PHP. - **SAPE-25** — A desktop workbench: several live connections, catalogue, run, shell, compose, declare. ### Backlog 2 — issues found while working Triaged into 1.0.0: - **ISS-4** — The `ErrFormat` refusal path has no test at all. The message exists and carries both numbers; nothing measures it, and SAPE-6 is built on top of it. - **ISS-11** — A grant has no expiry and cannot be revoked short of rotating the server secret, which would break every connection string with it. Adding an expiry changes the signed message, and the signed message is a public surface. - **ISS-12** — The TypeScript client cannot present a grant, so one of the three clients cannot reach a scoped operation at all. Deferred to the next version: - **ISS-1** — The covering index is built, decoded per entry on every scan, then discarded. Cost paid and never collected — waste, not wrongness. - **ISS-2** — Two fixture copies kept identical by hand; nothing compares them automatically. - **ISS-3** — The fixture covers 8 of the 13 frame types. - **ISS-5** — A composed operation's rows come back flat and unlabelled, so a caller cannot tell which step a row came from. - **ISS-6** — An encryption test is flaky: it searches ciphertext for a three-character string. - **ISS-7** — `internal/cli`'s open() leaks partition files, the same bug `Server.Close` had. - **ISS-8** — Two write handlers in one file roll back differently. - **ISS-9** — A read-only composed operation still takes the write lock. - **ISS-10** — A composed operation must name a collection it may never touch. - **ISS-13** — Declaring a collection is not recorded against anybody, though declaring an operation now is. - **ISS-14** — The old product name survives in three production constants, assembled byte by byte so a string search does not find them. Deliberate, for file-extension compatibility. - **ISS-16** — The TypeScript client ignores the product version the daemon now sends. - **ISS-17** — `sapedbd` has no `version` command; it only says so in its first log line. - **ISS-18** — A linker stamp aimed at a symbol that does not exist is accepted in silence: no warning, a working binary, and a version string that still says `dev`. Closed: - **ISS-15** — The release plan went stale the same day it was written, in the section it called most important. A planning document is a claim that can be measured, and it ages at exactly the speed the code changes. ## Source - github.com/sapedb/sapedb — the server, command line and operator shell, in Go. MIT licensed. - github.com/material-atomic/ecosy-sapedb — the TypeScript client, `@ecosy/sapedb`. It ships the conformance fixtures, which are the wire specification.