02 — Product Goals & Non-Goals
Covers task 4. A goal is a promise we will be judged on. A non-goal is a promise we explicitly refuse to make (so scope cannot creep in through silence).
The discipline of this document is the non-goals. Anyone can list features. A Principal protects the team by naming, in writing, what we are not building — so that “while we’re at it” never becomes a roadmap.
1. Product Thesis (one sentence)
BitVault is a self-hostable, multi-tenant file storage and synchronization platform with correct, conflict-aware sync and pluggable cloud storage — built cloud-native to demonstrate principal-grade distributed systems and platform engineering.
The two load-bearing words are correct (sync that never silently loses data) and pluggable (storage that is genuinely cloud-agnostic). Those are the bets.
2. Goals (what success looks like)
G1 — Durable, multi-tenant file storage
Upload, download, organize (folders), version, and delete files with strong durability (delegated to the object store) and hard tenant isolation.
G2 — Correct, conflict-aware synchronization
Multi-device sync via a change feed and delta transfer. Offline edits reconcile without silent data loss: concurrent edits produce conflicted copies, and every version is recoverable. This is the headline competency.
G3 — Flexible sharing
Internal shares (user/group, with roles) and external shares (public links with optional password, expiry, and download limits).
G4 — Pluggable, multi-cloud storage
A clean storage abstraction so the same product runs on MinIO, S3, R2, GCS, or Azure Blob. (One adapter at a time; the abstraction is the deliverable, not all five adapters at once.)
G5 — Search & discovery
Find files by name and metadata, fast. Full-text content search is a later, opt-in capability — not part of the core promise.
G6 — Self-hostable and SaaS-capable from one codebase
A self-hoster runs it with docker compose up and ~2 dependencies. The same
artifact scales to a multi-tenant SaaS on Kubernetes via Helm. One codebase,
config-profiled.
G7 — Cloud-native & observable by construction
Kubernetes-first, Docker-first, OpenTelemetry-instrumented (traces/metrics/logs), with SLOs, health/readiness, and graceful shutdown. Observability is a day-one property, not a later phase.
G8 — Secure by default
Encryption in transit and at rest, RBAC, audit logging, least-privilege storage credentials, tenant isolation enforced at the database layer.
G9 — Programmable surface
A clean public REST API and a first-class Go CLI, so the platform is automatable and the API is dogfooded by our own tooling.
G10 — A documented, defensible architecture
Every major decision captured as an ADR; the monolith→microservices evolution documented and demonstrated. The architecture itself is a deliverable.
3. Non-Goals (explicitly out of scope)
Non-goals for v1 (may be revisited later, by ADR)
| # | Non-goal | Why it’s out (for now) |
|---|---|---|
| NG1 | Real-time collaborative document editing (Google-Docs-style OT/CRDT co-editing) | A different, enormous product. Whole-file sync ≠ character-level co-editing. |
| NG2 | A web CMS (content types, editorial workflows, publishing/rendering) | Category error vs file sync; fractures the domain model. “Content management” = DAM-lite over files instead. |
| NG3 | Client-side end-to-end (zero-knowledge) encryption | Breaks server-side search, previews, and dedup; large crypto/UX surface. At-rest encryption first; E2E is a future tier, not a default. |
| NG4 | Native mobile app | Defer until the public API is stable and versioned; build web + CLI first. RN app is a future client, not a v1 deliverable. |
| NG5 | Cross-instance federation (Nextcloud-style server-to-server sharing) | High complexity, low portfolio ROI; revisit only if a clear need appears. |
| NG6 | Global / block-level deduplication | Content-hash (whole-object) dedup is in scope; sub-file block dedup and global cross-tenant dedup are not (complexity + tenant-isolation concerns). |
| NG7 | Office/document online viewers & editors | Integrate third parties later (e.g. Collabora/OnlyOffice) — not core. |
| NG8 | Air-gapped / FedRAMP / SOC2-certified enterprise compliance | Build compliance-ready primitives (audit, deletion, export); pursue certification only with a real customer. |
| NG9 | Multi-region active-active replication | Single-region first; the architecture must not preclude it, but we will not build it speculatively. |
| NG10 | Billing/payment processing | Usage metering and quota enforcement are in scope; integrating Stripe and running a billing system is not a v1 concern. |
| NG11 | All five storage adapters at launch | Ship MinIO/S3; add R2/GCS/Azure on demonstrated demand. The interface is the promise, not the matrix. |
Permanent non-goals (architectural identity)
- Not a CDN. We integrate with object storage and (optionally) a CDN; we do not build edge caching infrastructure.
- Not a backup product. Versioning ≠ point-in-time backup/restore of the whole system; do not market or design as DR.
- Not a general workflow/automation engine. Webhooks and events, yes; a Zapier-style builder, no.
4. Guardrails (how non-goals stay non-goals)
- New scope requires an ADR. Moving anything from “non-goal” to “goal” is a recorded decision with consequences, not a standup aside.
- The thesis is the filter. If a feature does not serve correct sync or pluggable storage (or an explicit portfolio learning goal), it is suspect.
- Infra needs a forcing function. Per the Overengineering Ledger (01), no infrastructure ships without a demonstrated need or a recorded learning goal.
5. Target Users & Primary Job-To-Be-Done
To keep the team honest about “who is this for”:
- Primary (self-host): a developer or small team that wants a Dropbox-like vault they fully own, on their own cloud/storage, deployed via Compose or Helm. JTBD: “Store and sync my team’s files on storage I control, without trusting a SaaS.”
- Secondary (SaaS operator — i.e. us): prove the same codebase runs as a multi-tenant service with isolation, metering, and observability.
- Tertiary (the portfolio reviewer): a senior engineer evaluating whether the author understands distributed systems, not just whether the app runs.
Designing for the self-host developer first keeps the dependency footprint honest and forces clean configuration — which is exactly what the SaaS path needs too.