I Shipped...

25 August 2026 (1PR)

added issuer and audience checks to backend JWT authentication

I added optional issuer and audience checks to backend JWT authentication. This means a correctly signed token can still be rejected when it was meant for a different service, while existing setups keep their current behaviour when no extra checks are configured.

24 August 2026 (19PRs)

supported runtime-comparable permission values

I taught permission compilation to turn supported timestamps, finite numbers, byte arrays, and nested arrays into runtime values. Invalid and non-finite values are rejected at the TypeScript boundary or with precise paths instead of failing later.

stabilised Expo secret loading across remounts

I shared in-flight Expo secret loads across concurrent and Strict Mode remounts, kept successful secrets for reuse, and allowed failed loads to retry. Unrelated errors are still reported as themselves.

made React client replacement lifecycle-safe

I made React client acquisition safe across server rendering, replacement, cancellation, and Strict Mode remounts. Different configurations now wait for the previous client to be released before acquiring a replacement.

made IndexedDB batches see earlier changes

I changed IndexedDB batch planning so each operation sees the value produced by earlier operations in the same batch. I also serialised batches sharing one storage instance so overlapping writes cannot overwrite newer results.

kept sibling policy joins anchored correctly

I kept each inferred relation join tied to the protected row instead of letting a later sibling join start from the previous relation. Explicit nested joins and recursive gathers still keep their intended chaining.

finished cleanup after shutdown failures

I changed shutdown cleanup to keep running each cleanup step after an earlier failure, then rethrow the first failure. This prevents one broken step from leaving the database, telemetry, client, or worker running.

compiled the DELETE policy fallback

I made DELETE USING fall back to UPDATE USING when no explicit delete rule exists, while keeping explicit DELETE USING rules in charge. This brings schema conversion in line with the documented contract and inherited policy checks.

cleared staged Inspector changes when changing tables

I cleared staged edits, inserts, deletes, errors, and pending scroll state when the Inspector changes routed tables. Sorting, filtering, pagination, and column layout changes within one table still retain staged state.

canonicalised client configuration identity

I made client configuration identity use recursively sorted keys. Configurations that differ only in property order now share the same identity instead of causing duplicate runtimes or unnecessary replacement.

bounded shape registrations before admission

I applied the size limit to the complete shape-registration request before deriving keys or retaining state. Oversized peer registrations are rejected early, while the existing public limits and wire format stay unchanged.

bounded recursive sync message depth

I capped nested AuthorizationScopeView decoding at eight wrappers and reject deeper peer messages during deserialisation. The existing wire format and exact boundary remain supported.

bounded pending upload metadata

I charged descriptor-only upload starts against the existing work budget and capped restart-persistent pending upload metadata at 1,024 records. This stops small requests from creating unlimited durable metadata while existing uploads can still resume.

bounded native WebSocket outbound frames

I added an 8 MiB budget for frames waiting in the native WebSocket queue. Producers now get a backpressure error when the budget is full, and space is released only after queued frames are dropped.

bounded auxiliary chunk request batches

I capped auxiliary immutable-chunk requests at four entries per decoded message and rejected oversized sequences before storage work. Local one-request frames and the exact limit remain supported.

bound persistence receipts to their database

I attached each persistence receipt to the database that created it. Foreign receipts are now rejected before they can change metrics, publication state, or the durable frontier.

bound chat message authorship to the logged-in user

I required a message sender profile to belong to the authenticated session. This stops a writer from attributing a message to somebody else's profile while leaving reads and existing reaction protections unchanged.

blocked live index registration during pending writes

I stopped live indexes being registered while applied writes are still resident. Registration can continue once those writes are durable and the index can backfill from complete storage.

authenticated todo requests per session

I made each todo REST and event-stream request use a database tied to its authenticated session. Ownership now comes from that session rather than request input, so routes use the normal permission checks.

aligned WebSocket size limits

I made the HTTP WebSocket layer use the same 2 MiB limit as the wire decoder. Valid fragmented messages up to that size can now reach the decoder instead of being rejected early, with a regression test for a 1.5 MiB message.