Update architecture baseline for sync, sharing, and gateways
All checks were successful
CI / Backend (push) Successful in 26s
CI / Frontend (push) Successful in 11s
CI / Contracts and repository policy (push) Successful in 4s
CI / Container (push) Successful in 27s

This commit is contained in:
Elijah 2026-07-16 18:40:12 -07:00
parent 9e01df5d64
commit 099c53badf
7 changed files with 200 additions and 102 deletions

View file

@ -0,0 +1,45 @@
# ADR-0008: Sync-capable server contract
Status: Accepted
## Context
The desktop client is deferred, but the stable-v1 API must support a client that maintains a local replica without missing concurrent mutations or silently overwriting a newer revision. The previous plan named a change feed and one-way mirror but did not define a consistent initial baseline, delivery semantics, mutation attribution, or the difference between content and metadata changes.
## Decision
Drive's REST API and application services are the canonical server interface. The server exposes neutral read, mutation, transfer, and change primitives; sync direction, deletion propagation, local filesystem policy, and three-way reconciliation remain client concerns.
### Baseline and changes
1. A client obtains opaque start cursor `C0`.
2. It recursively enumerates a selected root using stable node and parent IDs with keyset pagination.
3. It replays changes after `C0` until caught up.
4. It persists the cursor after the final event it has applied.
Enumeration and replay may contain duplicate observations but must not miss a committed mutation while the start cursor remains retained. No long-running PostgreSQL snapshot is held.
The change feed is ordered by a monotonic sequence and consumers treat delivery as at least once. A page cursor represents the position after its final event. Each versioned event stores either an immutable resulting-node snapshot or a deletion tombstone, node and content revisions, subtree effect, origin information, and useful previous-location diagnostics. Cursor expiry returns `410 Gone` with stable code `change_cursor_expired` and requires rebaseline without discarding pending local work.
Subtree-scoped credentials consume an authorization-safe projection of the global sequence. A move into the granted root is represented by current state, a move out is represented as a tombstone/removal, and unrelated events are omitted while the cursor advances. Recursive baseline and replay use the same root anchor and visibility rules, so a restricted client can maintain its authorized replica without learning metadata outside it.
### Identity, revisions, and idempotency
- Node revision increments for any meaningful mutation. Content revision increments only when committed file content changes.
- SHA-256 identifies committed content. Logical `content_modified_at` may preserve an authenticated client value; server `metadata_updated_at` records the latest mutation. Timestamps never decide conflicts.
- Authenticated client instances may bind to API tokens and are independently revocable. Application services receive a protocol-neutral mutation context for actor, credential, client, operation, idempotency, and request IDs.
- Idempotency records persist the authenticated scope, key, request fingerprint, operation, state, result reference, and expiry. Identical retries return the original result; a different fingerprint with the same key fails.
### Capabilities and transfers
`GET /api/v1/capabilities` reports protocol compatibility and supported behavior rather than requiring consumers to infer it from a software version.
Upload creation may accept declared size, SHA-256, logical content mtime, target/precondition, and origin. After authorization, the server may avoid transfer or attach an already verified owner blob through the normal commit service. New content is always server-hashed and verified.
Hash preflight is target-scoped and must not reveal whether matching content exists outside the credential's authorized view. The server may conceal whether internal deduplication occurred.
## Consequences
- Phase 1 owns the supporting schema and mutation context; Phase 2 owns the functional baseline, changes, capabilities, and conformance mirror.
- Web, importer, OnlyOffice, future desktop/rclone clients, and protocol gateways produce attributed events through the same application services.
- Client sync modes, SQLite schema, watcher behavior, local conflict copies, and provider adapters are deliberately deferred to the desktop-client design.

View file

@ -0,0 +1,25 @@
# ADR-0009: External protocol gateway boundary
Status: Accepted
## Context
Existing backup and automation tools may benefit from WebDAV or rclone compatibility. Managed Drive storage is not a user-visible filesystem: PostgreSQL owns hierarchy and revisions while the array contains opaque immutable blobs. Direct protocol access to object paths would bypass authorization, commit intents, change events, trash, replacement recovery, and audit.
## Decision
- REST and application services remain canonical.
- A writable WebDAV gateway MAY be implemented post-v1 as a protocol translator. Every write calls normal application services, uses revision preconditions, creates normal audit/change records, and sends deletion to trash unless a credential explicitly permits permanent deletion.
- WebDAV uses independently revocable, action- and subtree-scoped credentials. Durable WebDAV lock tables are added with that module, not pre-created in the core schema.
- A native rclone backend MAY later call the REST API directly for richer hashes, modification times, resumable uploads, server-side move/copy, trash, and error semantics. Generic rclone-over-WebDAV and a native backend may coexist.
- Native rsync service, rsync staging ingestion, and direct SMB/SFTP access to managed object storage are not planned. Rsync may operate on a local folder maintained by a future desktop client, never on Drive's server object directory.
- No gateway may import storage adapters or mutate core repository tables directly (I16).
Integration configuration and lock tables are introduced only when their module is implemented. Phase 1 adds only the shared foundations already required by REST clients: client identity, persistent idempotency, mutation attribution, and scoped credentials.
## Consequences
- Future compatibility does not force writable WebDAV or integration-specific tables into stable v1.
- Existing tools can gain interoperability later without weakening the immutable object model.
- A protocol gateway must provide streaming, conditional requests, bounded listings, authentication, audit, and revocation appropriate to that protocol.

View file

@ -11,4 +11,5 @@ ADRs are immutable after acceptance. Supersede an earlier decision with a new AD
| 0005 | HTTP precondition and conflict status codes | Accepted |
| 0006 | Stable-v1 and deferred product scope | Accepted |
| 0007 | Open first-run setup | Accepted risk |
| 0008 | Sync-capable server contract | Accepted |
| 0009 | External protocol gateway boundary | Accepted |