I Shipped...

29 August 2026 (2PRs)

check server tokens against their configured identity

I made server authentication check that each signed token has the configured issuer, audience, and valid time window, rather than trusting any token signed by a known key. Missing configuration now fails closed, and privileged infrastructure secrets cannot be used as ordinary user credentials.

block unsafe combinations of update permissions

I stopped separate update permissions from being combined into an authority that neither permission granted on its own. A table now accepts only one asymmetric update rule, while ordinary symmetric rules continue to combine normally.

28 August 2026 (1PR)

share embedded server shutdown results

I made repeated calls to stop the embedded server wait for the same final result. Callers now all see a successful shutdown only after the native server has really finished, and they all receive the same failure if shutting it down fails.

27 August 2026 (9PRs)

stop stale crate names breaking alpha releases

I fixed the alpha release checklist so it only names real Rust packages, preventing a release from publishing some crates and then failing on a stale name. Dry runs now ask Cargo to build the packages that would actually be published, and already-published versions can be skipped safely on retries.

share backend key refreshes between requests

I made simultaneous authentication requests share one download of the backend signing keys, instead of each request downloading the same document. Successful downloads start a short refresh cooldown, while failed downloads are not cached so a later request can try again.

serialise permission publishes to prevent races

I made publishing a new permission version one indivisible operation, so two administrators cannot both approve different changes based on the same old version. One request now wins, the other gets a conflict, and the saved version and active rules stay in agreement.

render synced todo text safely in examples

I changed the todo examples to insert synced titles and descriptions as text instead of treating them as HTML. Text that looks like markup is now displayed literally, so it cannot create unexpected elements or attributes in the page.

reject empty large-value branch children

I made the tree used for large values reject branch children that claim to contain zero bytes, while keeping the single empty root needed for a genuinely empty value. This stops malformed trees from hiding their real size and sending later code into unsafe traversal.

rebuild releases when preview sources change

I changed release publishing to rebuild its packages whenever the source tree differs from the one checked by the preview build, including when only the workflow files changed. This prevents a release from reusing packages made from a different version of the source.

protect subscription keys from conflicting reuse

I made an active subscription key keep one clear owner, so another subscription cannot quietly reuse it for a different kind of data. Safe replays still refresh the existing stream, while conflicting requests are rejected before they can leave subscriptions or cleanup in the wrong state.

keep historical views during subscription reconciliation

I made a subscription remember the exact current, historical, or branch view the caller requested. When the server rechecks the rows later, it now uses that same view instead of silently switching to the latest data and removing rows that still belong.

expire cached backend signing keys

I gave cached backend signing keys a five-minute maximum lifetime, so a key removed by the identity provider is not trusted indefinitely. After expiry, authentication fetches a fresh set and fails closed if that refresh is unavailable rather than using the old keys.

26 August 2026 (8PRs)

validate Counter column types before merging

I made Counter schemas check their column types before they reach the runtime, so nullable or non-integer definitions fail where they are written. I also made large integer counters behave consistently across the Rust and TypeScript interfaces and added a two-client test for them.

waited for the server to finish shutting down

I made concurrent shutdown calls wait for the one shutdown operation to finish. This means every caller now sees success only after the server's owner thread has exited and its storage has been cleaned up.

restored frozen rows after head deletions were undone

I fixed frozen branch views so restoring a deletion can make an inherited opening row visible again. The view keeps its original opening snapshot, while newer head content still takes precedence.

rejected reset versions with conflicting metadata

I made reset handling compare the full version information, not just the stored row bytes. If two reset versions disagree, the operation now fails before it changes storage or other reset state, regardless of which one arrives first.

rejected ambiguous relation names

I made relation building reject two reference columns that would produce the same relation name. Instead of silently picking whichever one appears first, schema and query construction now report the ambiguity so the column can be renamed.

made Expo secret scope keys safe

I changed scoped Expo SecureStore keys to use safe encoded pieces instead of punctuation that the store rejects. Different scope types stay separate, and because the key format changed, affected users may need to sign in again.

kept generated app IDs on their own dotenv lines

I fixed a small dotenv-file trap: when the file did not end with a newline, a generated app ID could be glued onto the previous setting. The writer now adds the missing line break and only treats an exact app-ID assignment as the setting, leaving comments and similarly named variables alone.

kept CollectBy operations terminal

I made CollectBy a true end-of-pipeline operation. Ordinary filters and projections can no longer consume it directly, while prepared routes still filter their own input before collecting it.