Core Principles
DraftThese principles apply to every Capsule component, client and server, and the rules below apply to
every doc in design/.
Principles
Section titled “Principles”- Determinism + idempotency. Raw original data is the source of truth; every process is repeatable from its inputs.
- 4 KiB alignment. Data touching disk or memory boundaries is processed and written 4 KiB-aligned unless a concrete case demands otherwise.
- Forward and backward compatibility. Old clients ignore new fields; new clients tolerate missing ones — subject to the asymmetry below.
- Data integrity. Capsule never deletes data unexpectedly: act only in strict scenarios, otherwise crash early. Server data is assumed durable; client data is assumed losable.
- Ephemeral derived data. Anything that is not an original asset is rebuildable and treated as such.
- Encryption + compartmentalization. Metadata is encrypted alongside data. Every boundary (album, peer, event, user, version) is a failure-containment boundary.
- Offline/online divide. A feature works either solely online or solely offline, never differently by connectivity.
- Recovery-first. The filesystem is reconstructible from partial corruption. Sidecars are the canonical metadata store; the database is a rebuildable query cache.
- Self-describing. Each media file is paired with a CBOR sidecar holding all user-editable and stable metadata, interpretable without a database.
- Atomic writes. Temp-file + rename everywhere; never overwrite in place.
Postel’s Law (asymmetric)
Section titled “Postel’s Law (asymmetric)”Liberal within a known schema version: unknown sidecar fields are preserved verbatim and missing optional fields tolerated. Cross-version is closed: a structure announcing a schema version (sidecar_schema, crypto_suite_id, protocol_version) above the receiver’s maximum is rejected, never best-effort-parsed. See Threat Model — Schema Rules.
Single Source of Truth
Section titled “Single Source of Truth”Every primitive, construction, format, or component identity is declared in exactly one owner doc; other docs link the declaration and never restate the choice. Explaining a behaviour elsewhere (“STREAM tags catch chunk reordering”) is fine; restating the choice (“we use SHA-256”) is not. When in doubt, link.
| Domain | Owner doc |
|---|---|
| Cryptographic primitives, constructions, version identifiers | Cryptography — Primitives |
| Key hierarchy, device coordination | Cryptography — Keys |
| MLS membership, ciphersuite binding | Cryptography — MLS |
| Asset + metadata encryption | Cryptography — Encryption |
| Provenance chains, signed manifests | Cryptography — Provenance |
| Recovery paths, failure modes, transport security | Cryptography — Failure Modes |
| MLS resilience | MLS Resilience |
| Device enrollment | Device Enrollment |
| ML model identities, embedding provenance | AI/ML Integrations |
| LQIP, thumbnail/preview formats | Thumbnails and Previews |
| Server filesystem, required services | Filesystem — Server |
| Client filesystem, local index | Filesystem — Client |
| Library self-maintenance, atomic-write granularity | Filesystem — Maintenance |
| Tokens, identity binding, auth flow | Authentication |
| Backup container, escrow, recovery | Backup and Recovery |
| CRDTs, identifiers, geolocation, sidecar schema | Metadata |
| Import pipeline | Import — Pipeline |
| Upload protocol | Transfer — Upload |
| Download, sync feed, auto-sync | Transfer — Download |
| Storage durability, verify-before-destroy | Transfer — Durability |
| Tethered camera import | Import — Camera Import |
| Connection and retry classes | Network Resilience |
| Offline-first requirements | Local Gallery |
| Federation trust, capability tokens | Federation |
| LAN discovery, peer channel | Peering |
| Album protocol version pinning | Versioning |
| Stacking, trash retention | Asset Organization |
| Lifecycle action set | Authorization |
| Damage scenarios, client classes | Threat Model |
| Refuse-by-default validation invariants | Threat Model — Validation |
| Schema evolution, deprecation | Threat Model — Schema Rules |
| Outbound licence, dependency-licence policy | Licensing |
| Dependency and tooling pins | Dependencies |
| Share links | Share Links |
| Upload links, guest drops | Web Upload |
| Moderation, reporting, blocklists | Moderation |
| Quota accounting + enforcement | Quota |
| Client validation duties, sandboxed decoder | Clients |
| Alerts, delivery, wake tier | Notifications |
| Catalogs, locale resolution, error codes | Internationalization |
| Crate graph, bounded E2E surface | Module Map |
| API surface ↔ transport map | API Surfaces |
| Developer-reference generation | Developer Documentation |
Doc Structure
Section titled “Doc Structure”Design docs are not templated, but each must let a reader answer: where does this live (crate or module), what is its public surface (schema, wire format, trait, error domain), what does it defer to (owner-doc links), and how is it validated (a tier, where non-obvious). The code is the source of truth for module layout; docs state contracts, not restated code.
Implementation Status
Section titled “Implementation Status”A doc naming an implementing module states per surface whether it is Implemented (module exists, its tier runs in CI), Planned (contract designed, no code), or Blocked (planned, with a named external blocker). A planned contract is written in normative present tense but must not claim the code exists; a module a doc names that does not exist yet must be listed in capsule-docs/planned-modules.txt.
Review Status
Section titled “Review Status”Every page carries a required status frontmatter field tracking human review: draft (not re-reviewed since the last substantive change) or stable (signed off; substantive edits flip it back). Drafts still publish.
Validation Tiers
Section titled “Validation Tiers”- Unit — in-module tests against the contract, peers and externals mocked. Deterministic and fast.
- Smoke — one module’s real implementation with real I/O and backing services (e.g. testcontainers Postgres or Valkey), peers mocked.
- E2E — several modules wired against real infrastructure. The list is bounded in Module Map — E2E Test Surface; growth past it signals unwanted coupling.
The tier is decided by what is mocked, not where the test lives.
Damage Containment
Section titled “Damage Containment”A faulty, malicious, or version-mismatched client must not inflict irreparable damage on user data. These principles name the posture; the Threat Model owns the defenses: the client-class taxonomy, the damage-scenario → invariant map, validation invariants, fail-closed protocol negotiation, and the cross-cutting idempotency, atomicity, and quarantine rules.