Architecture Decision Records

ADRs document the context, decision, and consequences of every significant architectural choice in BitVault. They are the primary artifact; code is the implementation. When you wonder “why does it work this way?”, the ADR explains the forces at play, what was rejected, and what was accepted — including the costs.

V1 Freeze (2026-06-12) classification. Accepted = binds the V1 build (P0–P2). Proposed = agreed direction, not committed to V1. Deferred = out until a named P3+ forcing function. Totals: 26 Accepted · 2 Proposed · 10 Deferred (38). See Architecture Freeze V1.

How to Write an ADR

Each ADR has five required sections:

Section Content
Status Accepted, Proposed, Deferred, or Superseded by ADR-XXXX
Context The problem, forces, and constraints that drove the decision
Decision One clear sentence: what was decided
Consequences Positive outcomes AND costs/trade-offs (both are required)
Alternatives considered What else was evaluated and why it was not chosen

An ADR without honestly stated negative consequences will be sent back. For guidance on proposing changes to existing decisions, see Contributing.


Foundation

# Title Status Date Key decision
0001 Architecture style: modular monolith first Accepted 2026-06-11 bitvaultd v1 single binary; extract to services by forcing function
0002 Monorepo Accepted 2026-06-11 One repo; go.work + pnpm/Turborepo
0003 gRPC internal, REST external Accepted 2026-06-11 buf + OpenAPI codegen; generated contracts
0004 Postgres as metadata source of truth Accepted 2026-06-11 Forward-only migrations; expand/contract schema evolution

Storage

# Title Status Date Key decision
0005 Object storage abstraction Accepted 2026-06-11 Provider interface; one adapter (MinIO/S3) in V1; conformance suite
0011 Direct-to-storage presigned URLs Accepted 2026-06-11 Bytes bypass compute; URL issued by control plane
0016 Hashing: BLAKE3 Accepted 2026-06-11 Content addressing; integrity verification at commit
0017 Chunking strategy (FastCDC + packing) Deferred 2026-06-11 Deferred — V1 is whole-object; chunk-delta is post-V1
0018 Deduplication scope Accepted 2026-06-11 Whole-object, per-tenant dedup; no cross-tenant side-channel
0019 Garbage collection Accepted 2026-06-11 Safe GC: grace + atomic re-confirm (CAS); refcount is a hint
0020 Storage placement federation Deferred 2026-06-11 Deferred — single static provider in V1
0021 Resumable uploads Proposed 2026-06-11 V1 = single-shot presigned PUT (size cap); multipart proposed

Events & Messaging

# Title Status Date Key decision
0006 Event backbone: outbox (+ NATS at P3) Accepted 2026-06-11 Outbox + in-proc bus in V1; NATS JetStream deferred to P3

Multi-Tenancy

# Title Status Date Key decision
0007 Multi-tenancy model Accepted 2026-06-11 (rev 06-12) Shared DB + RLS; tenant_id everywhere; context via SET LOCAL (ADR-0038)

Sync

# Title Status Date Key decision
0008 Sync and conflict resolution Accepted 2026-06-11 (rev 06-12) Journal written at commit (source of truth); stale base → conflicted copy
0022 Sync reconciliation: three-tree Accepted 2026-06-11 Base/local/remote tree reconciliation (client planner)
0023 Local sync database Accepted 2026-06-11 SQLite on device
0024 Sync protocol cursor Accepted 2026-06-11 (rev 06-12) Monotonic per-tenant seq assigned at commit; cursor delta pull
0025 File watching strategy Accepted 2026-06-11 inotify / FSEvents / ReadDirectoryChangesW
0026 Conflict resolution policy Accepted 2026-06-11 Conflicted copy; both histories kept; user reconciles
0027 Sync safety guards Accepted 2026-06-11 Atomic apply; self-write suppression; bulk-change brake

Security & AuthN

# Title Status Date Key decision
0010 AuthN/AuthZ Accepted 2026-06-11 OAuth 2.1 + OIDC; RBAC deny-by-default
0014 Encryption key management Accepted 2026-06-11 (rev 06-12) Per-tenant DEK wrapped by KMS KEK; TENANT_KEY + BLOB schema footprint
0035 Machine identity Deferred 2026-06-11 Deferred — workload identity is P4
0036 Authentication policy (MFA/passkeys) Proposed 2026-06-11 Basic authn V1 (ADR-0010); MFA/step-up/DPoP proposed
0037 Public sharing security Accepted 2026-06-11 (rev 06-12) Hashed capability token; expiry; scoped presigned URLs; abuse program deferred
0038 RLS connection pooling Accepted 2026-06-12 Transaction-local SET LOCAL tenant context; pooling-safe; default-deny; bleed test

API & Contracts

# Title Status Date Key decision
0003 gRPC internal, REST external Accepted 2026-06-11 buf lint + breaking-change CI; OpenAPI generated from proto
0015 API versioning Accepted 2026-06-11 URI versioning /v1/; buf breaking in CI for gRPC

Observability

# Title Status Date Key decision
0013 Observability: OpenTelemetry Accepted 2026-06-11 Traces + metrics + logs from commit #1; vendor-neutral; one trace per user action

Deployment & Ops

# Title Status Date Key decision
0012 Deployment packaging Accepted 2026-06-11 lite/standard (Compose) in V1; full + Helm/K8s deferred to P3/P4
0028 GitOps with ArgoCD Deferred 2026-06-11 Deferred — P4 (extraction & scale)
0029 Progressive delivery Deferred 2026-06-11 Deferred — P4
0030 Secrets management Deferred 2026-06-11 Deferred — P4; V1 uses env/keyfile secrets
0031 IaC: OpenTofu Deferred 2026-06-11 Deferred — P4
0032 CI/CD supply-chain security Deferred 2026-06-11 Deferred — P4; V1 CI = build/test/lint
0033 Backup and DR Deferred 2026-06-11 Deferred — P4; V1 = pg_dump + object versioning
0034 Environment promotion Deferred 2026-06-11 Deferred — P4 (multi-env)

# Title Status Date Key decision
0009 Search derived index Accepted 2026-06-11 Postgres-FTS in V1; OpenSearch (content search) deferred to P3