4.8 KiB
Architectural Decision Record: Use Native Batch CAS for Adaptive PostgREST
Status
Proposed as the final experimental provider, after the S3 and WebDAV delivery sequences have established the common protocol, CLI, host, and end-to-end boundaries.
Context
PostgREST can expose PostgreSQL uniqueness, row-level security, bounded set operations, and transactions. Treating it as another opaque object store works, but leaves Metadata and Chunks combined and cannot use a multi-key Chunk query. Using one HTTP request per logical Chunk would make latency dominate synchronisation.
The common protocol decision is recorded in Adaptive Journal as an explicit protocol. The tables, binary RPC framing, transaction rules, and privacy model are specified in the Adaptive Journal Sync design.
Decision
Adaptive PostgREST separates Metadata publication from immutable Chunk storage physically as well as logically.
- Vault- and repository-scoped Chunk rows use the Remote Chunk key as an insert-only unique address.
- Bounded binary RPCs implement
hasMany,getMany, andputManywhile preserving input order and per-entry status. - Writer descriptors, Metadata batches, and commits remain small append-only records.
- A transactional commit verifies the sorted required-Chunk-key digest and the existence of every referenced Chunk before making Metadata visible.
- Concurrent insertion of a different encrypted frame for the same logical Chunk reads, validates, and accepts the winning plaintext only when it represents the same logical value.
- Row-level security scopes every operation to the configured Vault. Server-visible Remote Chunk keys reveal equality within that repository but do not reveal plaintext Chunk IDs.
PostgREST does not use object packs, catalogue deltas, or Range retrieval for native Chunk rows. The shared binary Chunk record remains independently verifiable, but PostgreSQL supplies the batch index and uniqueness boundary.
The SQL schema and RPC contract are versioned together with the Adaptive format. A missing or incompatible schema is detected before publication and requires applying the reviewed schema or rebuilding the remote. The client does not perform an implicit data-format migration.
Staged acceptance
Adapter and Commonlib integration
Unit tests own binary-envelope limits, ordering, status decoding, insert conflicts, rollback, error classification, Vault isolation, and malformed responses. Disposable PostgreSQL and PostgREST integration tests own the real SQL schema, row-level security, RPC transactions, and two-client Metadata and Chunk synchronisation.
CLI end-to-end acceptance
The built CLI applies an Adaptive PostgREST Setup URI to a second independent database and synchronises text and binary Chunk-backed files through disposable PostgreSQL and PostgREST services. The scenario proves bounded native batching at the headless product boundary without repeating the SQL failure matrix.
Host settings and UI
The PostgREST dialogue persists the endpoint, Vault identifier, authentication configuration, Adaptive format, and expected repository ID. Focused tests own connection-string and Setup URI preservation, validation, and format-mismatch guidance; they do not execute SQL.
Real-host end-to-end acceptance
One real-Obsidian workflow applies the reviewed schema and performs a representative Chunk-backed transfer. The disposable Commonlib integration remains authoritative for RLS, transaction rollback, and the complete RPC matrix.
Alternatives rejected
Reuse immutable object packs in PostgreSQL
This would preserve portability at the cost of native multi-key lookup and transaction guarantees. The repository contract already permits a different physical representation.
Store raw file content with Metadata
Metadata must remain small and must continue to refer to immutable logical Chunks. Combining content with Metadata would break the maintained PouchDB model and duplicate unchanged content across revisions.
Encode Chunk bodies as JSON values
Base64 and large JSON arrays add framing and memory overhead and make limits harder to enforce. Bounded binary bytea
RPC envelopes provide deterministic lengths and status ordering.
Consequences
- PostgREST has the largest provider-specific implementation because it includes reviewed SQL, RLS, RPC framing, and transaction behaviour.
- Placing it last lets the common protocol, CLI, and host boundaries stabilise before introducing that larger surface.
- Native batching can reduce request count substantially relative to object-per-Chunk storage, but actual speed still depends on database, proxy, network, and workload measurements.
- PostgREST and object stores share logical records and correctness rules without pretending to share a physical layout.