I Shipped...

27 August 2026 (7PRs)

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 (12PRs)

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.

closed late native connections safely

I stopped a native connection from being attached after it had already disconnected. The admission step now checks that the connection is still current before accepting it, and closes late arrivals through the normal cleanup path.

required admin claims for announcement changes

I tightened announcement permissions so creating, changing, or deleting announcements requires an authenticated administrator. Ordinary chat messages keep their existing rules, and an ordinary message can no longer be moved into the announcements room to bypass them.

made anonymous sessions read-only even on exclusive writes

I enforced the documented read-only rule for anonymous sessions at the final write-admission point. Anonymous clients can still read public data, but they can no longer insert, update, or delete data through ordinary or exclusive-write paths.

flushed pending RocksDB writes when closing

I made storage shutdown flush acknowledged writes that were still waiting in RocksDB. A failed flush is reported and remains retryable, so closing the database cannot falsely claim that pending data has been safely synchronised.

25 August 2026 (1PR)

preserved original row provenance in write policy checks

I fixed write-policy checks so updates keep the original creator and creation time separate from the person making the change. I also made inline policy requirements request the hidden version information they need, and reject the operation when that history cannot be reconstructed.