mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-08-31 15:57:06 +00:00
91 lines
4.8 KiB
Markdown
91 lines
4.8 KiB
Markdown
# 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](2026_07_adaptive_journal_protocol.md). The tables, binary RPC framing,
|
|
transaction rules, and privacy model are specified in the
|
|
[Adaptive Journal Sync design](../design_docs/adaptive_journal_sync.md).
|
|
|
|
## 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`, and `putMany` while 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.
|