Skip to content

fix(postgres): commit authorized local writes optimistically#196

Open
marcus-pousette wants to merge 3 commits into
fix/auth-stage-verified-proofsfrom
fix/postgres-auth-optimistic-commit
Open

fix(postgres): commit authorized local writes optimistically#196
marcus-pousette wants to merge 3 commits into
fix/auth-stage-verified-proofsfrom
fix/postgres-auth-optimistic-commit

Conversation

@marcus-pousette

@marcus-pousette marcus-pousette commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

Problem

The PostgreSQL N-API client prepared a local operation inside a transaction and kept the document row lock while JavaScript authorization was awaited. A second synchronous write could block the JavaScript thread needed to finish that authorization.

The operation and its standard auth proof also lacked a shared commit boundary.

What changes

Authenticated local writes now use three phases:

  1. A short PostgreSQL transaction repairs pending materialization, locks the document revision, and returns an exact detached proposal. It commits before JavaScript runs.
  2. Authorization receives an isolated operation. The client verifies that authorization and proof extraction did not mutate metadata, structure, prototypes, or typed-array bytes.
  3. A fresh transaction takes the document lock with NOWAIT, verifies the complete materialization revision, prepares the operation again, and requires an exact match with the authorized proposal.

The operation, materialized state, metadata, and standard treecrdt_sync_op_auth proof row then commit atomically. The proof contains only the standard signature and optional proof reference.

A real optimistic conflict reparses and reauthorizes a fresh proposal, up to four attempts. Policy, proof, codec, database, and callback failures remain terminal.

The direct path also creates the document revision row when a local write is the first action on a new document.

Why this is one PR

The Rust/native contract and TypeScript retry/auth bridge must land together. The native half alone exposes proposals the old client cannot commit correctly; the client half alone requires APIs and transaction semantics that do not yet exist.

The implementation is separated into commits for review, but it is one atomic merge unit.

Fast paths

  • With no auth session, writes retain the direct one-connection, one-transaction path.
  • Authorization holds no PostgreSQL transaction or row lock.
  • Custom sessions without localOpProofs retain proofless behavior.
  • The co-located proof row is authoritative for the standard path.
  • An external proof store remains only a best-effort mirror because PostgreSQL cannot include another database in its transaction.

Tests

  • authorization holds no lock
  • conflicts create and authorize a fresh proposal
  • operation and proof commit atomically
  • invalid proof material fails before native commit
  • operation and proof-hook mutation is rejected
  • proof rollback leaves no partially committed operation
  • first local write initializes document metadata
  • live PostgreSQL Rust tests run in the PostgreSQL CI service job

Stack

Stacked on #192. This is the PostgreSQL sibling of the SQLite #193#195 chain.

@marcus-pousette marcus-pousette added bug Something isn't working area:postgres PostgreSQL backend, N-API bridge, and server storage area:auth Authorization, capabilities, proofs, signatures, crypto, and privacy labels Jul 12, 2026
@marcus-pousette marcus-pousette force-pushed the fix/auth-stage-verified-proofs branch from 2b4b0a8 to ea21857 Compare July 12, 2026 12:34
@marcus-pousette marcus-pousette force-pushed the fix/postgres-auth-optimistic-commit branch from b19e907 to e8e4ff9 Compare July 12, 2026 12:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:auth Authorization, capabilities, proofs, signatures, crypto, and privacy area:postgres PostgreSQL backend, N-API bridge, and server storage bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant