From 3e0c05a2b35921379a0458ab4774b5582f7fa8c0 Mon Sep 17 00:00:00 2001 From: tegwick Date: Sun, 14 Jun 2026 16:21:08 +0200 Subject: [PATCH] =?UTF-8?q?research:=20local-first=20workspaces=20cohort?= =?UTF-8?q?=20deep=20dive=20(Anytype/AFFiNE/AppFlowy)=20=E2=80=94=20CRDT?= =?UTF-8?q?=20substrate;=20UC-64/65?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Combined cohort memo for the three open-source local-first all-in-one workspaces, studied together because they share the trait none of the prior eleven systems had: the store is a CRDT (Anytype any-sync, AFFiNE Yjs/y-octo, AppFlowy Yrs). The cohort thesis: CRDT changes the adapter math — the backend performs conflict-free merge itself (shard-wiki must not impose git/text merge; speak the CRDT via a replica or stay projection/overlay), history is a CRDT update log (supplement not git), and the attach surface is a replica or self-host sync endpoint, with Anytype adding P2P (no single endpoint) + E2EE (opaque). Added UC-64 (CRDT-synced shard with native merge), UC-65 (P2P/decentralized shard, no single canonical endpoint); enriched UC-36/47/48/51/55/57/58/61. Catalog now 65 UCs. Architecture for SHARD-WP-0002 T11/T14: merge-model capability (proposed 13th spectrum: none/git/native-CRDT), CRDT-replica substrate + P2P/no-central-endpoint attach mode, endpoint-model capability, MCP as an integration surface. Boundary: CRDT local-first candidate shards — attach a replica/projection as pages, respect native merge, never re-drive their sync; not substrates and not the federation layer. Co-Authored-By: Claude Opus 4.8 --- SCOPE.md | 4 +- .../README.md | 46 +++ .../findings.md | 261 ++++++++++++++++++ research/README.md | 3 +- spec/UseCaseCatalog.md | 119 +++++++- 5 files changed, 419 insertions(+), 14 deletions(-) create mode 100644 research/260614-localfirst-workspaces-deep-dive/README.md create mode 100644 research/260614-localfirst-workspaces-deep-dive/findings.md diff --git a/SCOPE.md b/SCOPE.md index bb73d7c..d73c6a2 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -19,9 +19,9 @@ Learnings update both SCOPE and INTENT where necessary. |-------|-------| | Code | Python package scaffold (`src/shard_wiki/`, smoke tests only) | | Intent | `INTENT.md` established; authorization-in-core amendments drafted | -| Research | yawex prior art; c2 origins; federation concepts; wikiengines overview (`research/260608-*/`); XWiki/TWiki/Foswiki deep dives (`research/260613-*/`); Xanadu + ZigZag + Roam + Obsidian + Notion + Joplin + Logseq deep dives & shard-spectrum synthesis (`research/260614-*/`) | +| Research | yawex prior art; c2 origins; federation concepts; wikiengines overview (`research/260608-*/`); XWiki/TWiki/Foswiki deep dives (`research/260613-*/`); Xanadu + ZigZag + Roam + Obsidian + Notion + Joplin + Logseq + local-first workspaces (Anytype/AFFiNE/AppFlowy) deep dives & shard-spectrum synthesis (`research/260614-*/`) | | Demand | NetKingdom integration asks captured, not yet negotiated | -| Spec | Architecture blueprint drafted; UseCaseCatalog 63 UCs from research; PRD/TSD scaffolds | +| Spec | Architecture blueprint drafted; UseCaseCatalog 65 UCs from research; PRD/TSD scaffolds | | Work | `SHARD-WP-0001` active (6 tasks); `SHARD-WP-0002` active (16 tasks: T1–T10 federation + T11–T16 adapter contract) | ## In Scope (today) diff --git a/research/260614-localfirst-workspaces-deep-dive/README.md b/research/260614-localfirst-workspaces-deep-dive/README.md new file mode 100644 index 0000000..f2a73c4 --- /dev/null +++ b/research/260614-localfirst-workspaces-deep-dive/README.md @@ -0,0 +1,46 @@ +# 260614 — Local-first workspaces cohort deep dive (Anytype · AFFiNE · AppFlowy) + +Date: 2026-06-14 + +## What this is + +A **combined cohort deep dive** of three open-source, local-first "all-in-one workspace" +tools — **Anytype**, **AFFiNE**, **AppFlowy** — studied together because they share the +one trait none of the prior eleven systems had: **the store is a CRDT** (Anytype's +*any-sync*, AFFiNE's *Yjs/y-octo*, AppFlowy's *Yrs*). The substrate is the contribution; +studying them together isolates it from each tool's surface features. + +Per-tool highlights: +- **Anytype** — `any-sync`: **P2P + E2EE** CRDT (sync/file/consensus/coordinator nodes; + encrypted backup), a **typed object graph** (user-editable types + relations), IPFS + files, an **open API + MCP**. +- **AFFiNE** — **Yjs/y-octo** over **OctoBase**; **BlockSuite** editor framework; docs, + whiteboards, and databases as **views of the same block set**; WebSocket sync, + self-host (Docker, MPL-2.0). +- **AppFlowy** — **Yrs** via **AppFlowy-Collab** (Rust); Flutter UI; Notion-style + **databases + views**; pluggable storage/sync (RocksDB/IndexedDB; AppFlowy Cloud/ + Supabase). + +## Contents + +| Path | Role | +|------|------| +| `findings.md` | Per-tool sections, the CRDT cohort thesis, comparative matrix, combined capability profile, INTENT mapping, UC seeds, architecture notes, sources | + +## Status + +Cohort dive complete. Two new use cases promoted to `spec/UseCaseCatalog.md` (UC-64 +attach a CRDT-synced local-first shard with native conflict-free merge; UC-65 attach a +peer-to-peer / decentralized shard with no single canonical endpoint); UC-36/47/48/51/55/ +57/58/61 enriched. Logged for `SHARD-WP-0002` (T11/T14): a **merge-model** capability +(proposed thirteenth spectrum: `none / git / native-CRDT`), a **CRDT-replica** substrate + +**P2P/no-central-endpoint** attach mode, an **endpoint-model** capability, and MCP as an +integration surface. + +**Cohort thesis recorded:** CRDT changes the adapter math — the backend performs +conflict-free merge itself (so shard-wiki must not impose git/text merge), history is a +CRDT update log (supplement, not git), and the attach surface is a **replica or sync +endpoint** (Anytype adds **P2P + E2EE**). **Boundary:** CRDT local-first candidate shards +— attach a replica/projection as pages, respect native merge, never re-drive their sync; +not substrates and not the federation layer. + diff --git a/research/260614-localfirst-workspaces-deep-dive/findings.md b/research/260614-localfirst-workspaces-deep-dive/findings.md new file mode 100644 index 0000000..d77c381 --- /dev/null +++ b/research/260614-localfirst-workspaces-deep-dive/findings.md @@ -0,0 +1,261 @@ +# Findings — Anytype, AFFiNE, AppFlowy: the CRDT local-first workspace cohort + +Date: 2026-06-14 +Source kind: **modern shipped products (cohort dive)** — three open-source, local-first +"all-in-one workspace" tools studied together; candidate shards of a **new substrate +family: CRDT-synced local-first stores** +Lens: shard-wiki — the CRDT substrate and its native-merge / P2P / E2EE implications for +the adapter contract + +> Why one combined memo. Anytype, AFFiNE, and AppFlowy are the open-source local-first +> Notion/Miro alternatives, and they share the one trait the prior eleven systems never +> had: **the store is a CRDT** (Anytype's *any-sync*, AFFiNE's *Yjs/y-octo*, AppFlowy's +> *Yrs*). That single fact changes the adapter math — **the backend performs conflict- +> free merge itself**, history is a CRDT update log (not git), and content arrives as a +> replica/export, not files or rows. Studying them together isolates the *substrate* +> contribution from each tool's surface features and avoids triplicating boilerplate. +> Per-tool sections (§1–§3), then the cohort thesis and what it means for shard-wiki +> (§4 onward). + +Contrast set: file-store (Obsidian/Logseq), client-DB (Roam), hosted-DB (Notion), +SQLite-local+file-sync (Joplin). This cohort adds **CRDT-replica** as a substrate. + +--- + +## 1. Anytype — P2P, E2EE, typed object graph (any-sync) + +- **Substrate:** the open **any-sync** protocol — **local-first, peer-to-peer, + end-to-end encrypted** CRDT. Infrastructure is four node types: **sync, file, + consensus, coordinator**; **backup nodes store ciphertext they cannot read**. Every + change is **encrypted and signed with the user's private key**, verified via a shared + public key. Files via **IPFS**. +- **Data model:** **spaces** = graph-based databases; users define **custom object + types with relations** ("everything is an object"; a user-editable **ontology**). + Closest to Notion's typed model but **local-first + E2EE + user-owned schema**. +- **Extension:** an **open API** for integrations, **plus MCP support** (AI-agent + collaboration) — a notable modern surface (a shard speaking MCP). +- shard-wiki read: the **most decentralized + encrypted** shard yet — no single + canonical endpoint (attach a local replica or a node), content opaque without keys + (UC-61), typed object graph (UC-58), CRDT merge (UC-64). + +## 2. AFFiNE — docs + whiteboard + DB as views of one block set (Yjs/BlockSuite) + +- **Substrate:** **Yjs CRDT** via **y-octo** (native Rust Yjs) over **OctoBase** (Rust + local-first engine). Local-first by default; optional **WebSocket realtime** sync to + AFFiNE Cloud or self-host (MPL-2.0, Docker). +- **Editor:** **BlockSuite** — an open block-editor framework providing the **page + editor, the edgeless canvas, and block types (incl. databases/embeds)**. +- **Headline:** **docs, whiteboards, and databases are *views of the same underlying + data*** — one block set rendered as page mode, edgeless canvas, or DB views. CRDT + guarantees offline edits "merge mathematically perfectly" on reconnect. +- shard-wiki read: the **one-data-many-renderings** model shipped (ZigZag dimensions, + UC-47/48), with **non-Markdown spatial content** (edgeless canvas, UC-55) and CRDT + merge (UC-64). + +## 3. AppFlowy — Rust/Flutter, Notion-style DBs over Yrs CRDT + +- **Substrate:** **Yrs** (Rust Yjs) wrapped as **AppFlowy-Collab** — CRDT primitives + + persistence + domain objects (documents, **databases**, folders, importers, plugins, + user state). **Pluggable storage/sync:** RocksDB (native) / IndexedDB (wasm) locally; + **Supabase or AppFlowy Cloud** (self-hostable) for sync, via **trait-based local-only + vs cloud**. +- **Data model:** Notion-like **databases with views** (grid/board/calendar), typed + fields. Flutter UI + Rust core, modular. +- shard-wiki read: a **self-hostable CRDT Notion** — typed DBs + views (UC-58, UC-54), + CRDT merge (UC-64), self-host sync endpoint (UC-57). + +--- + +## 4. The cohort thesis — CRDT changes the adapter math + +All three converge on **CRDT-synced, local-first, open-source, self-hostable** stores +with **typed/database object models** and **non-Markdown content** (canvas/DB). The +*substrate* is the new thing, and it has four consequences shard-wiki must absorb: + +1. **Native, conflict-free merge (UC-64).** The backend resolves concurrent edits + itself (Yjs/Yrs/any-sync). shard-wiki must **not impose git/text merge** on a CRDT + shard; it either speaks the CRDT (replica) or stays a **projection/overlay** that + respects CRDT semantics. This adds a **merge-model** capability: + `none → git/text → native-CRDT` — a candidate **thirteenth spectrum** for the + contract (after Joplin's content-opacity twelfth). +2. **History is a CRDT update log, not git (UC-36).** No portable commit history; the + coordination journal **supplements** (like Notion/Joplin), or shard-wiki snapshots + the replica over time. +3. **The attach surface is a replica or a sync endpoint, not files/rows.** Attach a + **local CRDT replica** (offline, full state) or the **self-host sync server's API** + (AFFiNE Cloud / AppFlowy Cloud / any-sync node). Anytype adds **P2P with no single + canonical endpoint** (UC-65) and **E2EE content opacity** (UC-61). +4. **Typed object graphs + multi-view (UC-58, UC-47/48, UC-55).** User-editable + ontologies (Anytype types/relations), Notion-style DBs (AppFlowy), and one-block-set- + many-renderings (AFFiNE page/canvas/DB) — the structured + dimensional demands the + prior dives raised, now local-first. + +These are **sync layers** (any-sync, Yjs sync, AppFlowy Cloud) — like Joplin, the +**not-a-file-sync-daemon** boundary applies: shard-wiki attaches a **replica/projection +as pages** and does **not** re-implement or re-drive their CRDT sync. + +--- + +## 5. Comparative matrix + +| | Anytype | AFFiNE | AppFlowy | +|---|---------|--------|----------| +| CRDT | any-sync (custom) | Yjs (y-octo) | Yrs | +| Sync | **P2P + nodes, E2EE** | WebSocket, cloud/self-host | RocksDB local + cloud/Supabase | +| Encryption | **E2EE (default)** | optional (transport/self-host) | self-host boundary | +| Local engine | local + IPFS files | OctoBase (Rust) | RocksDB / IndexedDB | +| Data model | **typed object graph (ontology)** | blocks; **doc/canvas/DB = one data, many views** | Notion-style **DBs + views** | +| Non-MD content | objects, files | **edgeless canvas** | board/calendar/grid | +| Extension | **open API + MCP** | BlockSuite framework | Flutter/Rust modules; plugins (roadmap) | +| Self-host | backup/sync nodes | Docker (MPL-2.0) | AppFlowy Cloud | +| Markdown | export (lossy) | import/export (lossy) | import/export (lossy) | + +--- + +## 6. Combined capability profile (as a shard) + +| Capability | This cohort | Notes for the adapter contract | +|------------|-------------|--------------------------------| +| Read | yes (replica or sync API) | local CRDT replica (offline) or self-host/P2P endpoint | +| Write | yes, **CRDT-mediated** | writes are CRDT ops; respect merge — don't overwrite | +| Merge | **native CRDT (conflict-free)** | **new capability**: backend owns merge; no external git merge (UC-64) | +| Write granularity | block/object | fine-grained | +| Identity / addressing | object/block IDs (CRDT-assigned) | fine-grained, store-minted (UC-51) | +| Structure | **typed object graph / DBs + relations** | user-editable ontology (Anytype); DB views (AppFlowy) (UC-58) | +| History | **CRDT update log, not git** | supplement / snapshot (UC-36) | +| Native query | varies (graph/DB filters) | delegate where present (UC-52) | +| Subscribe | realtime CRDT sync / P2P | push by nature; attach as replica (UC-31) | +| Content opacity | **Anytype E2EE → ciphertext** | opaque without keys (UC-61) | +| Endpoint model | **replica / self-host server / P2P (Anytype)** | no single canonical URL for P2P (UC-65) | +| Content types | docs + **canvas/DB/objects** | non-Markdown (UC-55); multi-view (UC-47/48) | +| Markdown | lossy export | fidelity report (UC-59) | +| Attach modes | CRDT replica · self-host API · (Anytype) MCP/open API | new substrate row in the taxonomy | + +Verdict: a **demanding but coherent new family** — best attached as a **local replica +(offline, full CRDT state)** projected to pages, or via a **self-host sync endpoint**; +Anytype additionally **P2P + E2EE** (replica-only/opaque). Standout demands: +**native-CRDT merge** (UC-64) and **P2P/no-central-endpoint + E2EE** (UC-65/UC-61). + +--- + +## 7. Mapping to shard-wiki INTENT (compare, do not equate) + +### 7.1 Reinforcements + +- **Local-first sovereignty** is the cohort's whole pitch — strong INTENT alignment; + each is a legitimate sovereign shard with user-owned data. +- **Self-hostable + open-source** means shard-wiki can attach within a user's trust + boundary (good for the L0→L4 authz ladder). +- **One-data-many-views** (AFFiNE) and **typed object graphs** (Anytype/AppFlowy) are + the dimensional (UC-47/48) and structured (UC-58) demands, now validated local-first. + +### 7.2 Deliberate divergences (design bugs if conflated) + +1. **Do not impose git/text merge on a CRDT shard.** The backend merges; shard-wiki + respects CRDT semantics or stays a projection/overlay (UC-64). Treating a CRDT shard + like a file shard corrupts it. +2. **Not a sync daemon.** any-sync/Yjs/AppFlowy Cloud already sync; shard-wiki attaches + a **replica as pages**, never re-drives their sync (INTENT not-a-file-sync-daemon). +3. **P2P has no canonical endpoint.** Don't model the shard as a URL; attach a replica + or a named peer/node (UC-65). +4. **E2EE shards are opaque** without keys — backup/structure-shell only (UC-61). +5. **Proprietary CRDT/object formats are lossy to Markdown** — translate with a fidelity + report (UC-59), one workspace = one shard, not the federation layer. + +### 7.3 What the cohort teaches that shard-wiki should keep + +- Add a **merge-model** capability (`none / git / native-CRDT`) so CRDT shards are + handled correctly (UC-64) — a thirteenth capability spectrum. +- Add **CRDT-replica** to the substrate/attachment taxonomy, and **P2P/no-central- + endpoint** as a binding mode (UC-64/65). +- **MCP as an integration surface** (Anytype) is worth noting — a shard may expose an + AI-agent protocol shard-wiki could consume or coexist with. + +--- + +## 8. Use-case seeds → catalog (promoted 2026-06-14) + +Last existing UC is **UC-63**. New UCs **UC-64, UC-65** added; existing UCs enriched. + +| Seed | Catalog action | +|------|----------------| +| **Attach a CRDT-synced local-first shard** whose backend performs native conflict-free merge; respect CRDT semantics (no git merge), consume a replica/export, CRDT-log history (supplement) | **UC-64 (new)** | +| **Attach a peer-to-peer / decentralized shard with no single canonical endpoint** (Anytype any-sync: replica or peer/backup node; E2EE) | **UC-65 (new)** | +| Typed object graph / user-editable ontology + Notion-style DBs, local-first | **enriches UC-58** | +| E2EE content opacity (Anytype) reinforced; self-host trust boundary | **enriches UC-61** | +| CRDT update log ≠ portable git history → supplement | **enriches UC-36** | +| One block set rendered as page / canvas / DB views (AFFiNE) | **enriches UC-47, UC-48** | +| Edgeless canvas / board / objects = non-Markdown content | **enriches UC-55** | +| Self-host sync server (AFFiNE/AppFlowy Cloud) + Anytype open API/MCP as endpoints | **enriches UC-57** | +| Object/block IDs CRDT-assigned (fine-grained) | **enriches UC-51** | +| Lossy Markdown export | links UC-59 | + +--- + +## 9. Architecture notes for SHARD-WP-0002 (no UC) + +- **Merge-model capability** (`none / git-or-text / native-CRDT`) — proposed + **thirteenth spectrum** (with Joplin's content-opacity twelfth). CRDT shards reject + external merge; shard-wiki overlays must be CRDT-aware or remain projections. (T11.) +- **Substrate taxonomy gains CRDT-replica**; **attach modes gain "local CRDT replica" + and "P2P/no-central-endpoint"** beside file-store / in-engine-host / external-API. + (T14.) +- **Endpoint model** as a capability: single URL vs self-host server vs **P2P peer set** + (Anytype) — affects how a binding is addressed and how freshness/sync work. (T14.) +- **MCP / AI-agent protocol** as a possible shard integration surface (Anytype). Note + for the extension-surface catalogue. (T14.) +- These three plus Joplin and Logseq all argue the contract must treat **substrate as a + spectrum that tools migrate along and that shard-wiki must not hard-code**. + +--- + +## 10. Open questions (for spec / workplans) + +1. For a **CRDT shard** (UC-64), does shard-wiki embed a CRDT client (Yjs/Yrs) to hold a + live replica, or only consume periodic **exports/snapshots**? The former gives + live/writable; the latter is simpler but lossy on merge timing. +2. How are **overlays** expressed against a CRDT shard — as CRDT ops (requires the + client) or as out-of-band patches reconciled later (projection-only)? +3. For **P2P shards** (UC-65), what is the "address" of the shard — a space ID + a peer/ + node, a local replica path, or an invite/key? How does this fit shard attachment + config? +4. Does shard-wiki ever hold **E2EE keys** (Anytype) to project content, or only ever + treat such shards as opaque replicas/backups (UC-61)? +5. Is the **self-host sync server** (AFFiNE/AppFlowy Cloud) attached as an external API + (UC-57) or by running a co-located replica? + +--- + +## 11. Sources + +| Source | Used for | +|--------|----------| +| Anytype any-sync — Protocol overview (https://tech.anytype.io/any-sync/overview) | Local-first/P2P/E2EE CRDT; sync/file/consensus/coordinator nodes; encrypted backup | +| anyproto/any-sync (https://github.com/anyproto/any-sync) | Protocol scope; keys signed/verified; IPFS files | +| Anytype Docs (https://doc.anytype.io/anytype-docs) | Spaces, object types + relations (ontology); open API + MCP | +| toeverything/AFFiNE + DeepWiki (https://deepwiki.com/toeverything/AFFiNE) | BlockSuite (page/edgeless/DB); y-octo Yjs; OctoBase; one-data-many-views; self-host | +| AFFiNE — interactive whiteboard / blog (https://affine.pro/blog/interactive-whiteboard-app) | Edgeless canvas; CRDT offline merge | +| AppFlowy-IO/AppFlowy-Collab (https://github.com/AppFlowy-IO/AppFlowy-Collab) | Yrs CRDT; collab domain objects (documents/databases/folders); persistence | +| AppFlowy Architecture Overview — DeepWiki (https://deepwiki.com/AppFlowy-IO/AppFlowy/2-architecture-overview) | Flutter/Rust layers; pluggable storage/sync (RocksDB/IndexedDB; Supabase/AppFlowy Cloud); local vs cloud trait | +| AFFiNE vs AppFlowy vs Anytype (https://affine.pro/blog/affine-vs-appflowy-vs-anytype) | Cohort comparison framing | + +Cross-references: `research/260614-notion-deep-dive/findings.md` (typed DB, hosted +contrast), `research/260614-joplin-deep-dive/findings.md` (E2EE/content opacity, sync- +daemon boundary), `research/260614-shard-spectrum-synthesis/findings.md` (the spectra +this extends), `spec/UseCaseCatalog.md` (UC-36, UC-47, UC-48, UC-51, UC-55, UC-57, +UC-58, UC-61), `workplans/SHARD-WP-0002-federation-architecture.md` (T11, T14). + +--- + +## 12. Traceability + +- New UCs: **UC-64, UC-65** → `spec/UseCaseCatalog.md`. +- Enriched UCs: **UC-36, UC-47, UC-48, UC-51, UC-55, UC-57, UC-58, UC-61** (links UC-59). +- Architecture (no UC): **merge-model** capability (proposed thirteenth spectrum); + CRDT-replica substrate + P2P/no-central-endpoint attach mode; endpoint-model capability; + MCP integration surface → `SHARD-WP-0002` (T11, T14). +- Boundary recorded: Anytype/AFFiNE/AppFlowy are **CRDT local-first candidate shards** + (attach a replica/projection as pages; respect native CRDT merge; never re-drive their + sync; P2P/E2EE shards are replica-only/opaque) — not substrates, not the federation + layer (INTENT not-a-sync-daemon, graceful degradation, no silent mutation). + diff --git a/research/README.md b/research/README.md index bb0fdda..9047ce2 100644 --- a/research/README.md +++ b/research/README.md @@ -24,4 +24,5 @@ when multiple files or sources are involved. Findings here inform `spec/` and | 2026-06-14 | `260614-notion-deep-dive/` | Notion — closed block-DB SaaS, external REST API only, database-as-pages; UC-57/58/59 | | 2026-06-14 | `260614-shard-spectrum-synthesis/` | Synthesis — shard family matrix + eleven capability spectra across nine systems; feeds SHARD-WP-0002 T11–T16 | | 2026-06-14 | `260614-joplin-deep-dive/` | Joplin — SQLite-local/Markdown-on-sync, interchange-format attach, E2EE content opacity; UC-60/61 | -| 2026-06-14 | `260614-logseq-deep-dive/` | Logseq — block-graph on plain Markdown files, in-file block IDs, derived Datalog index; UC-62/63 | \ No newline at end of file +| 2026-06-14 | `260614-logseq-deep-dive/` | Logseq — block-graph on plain Markdown files, in-file block IDs, derived Datalog index; UC-62/63 | +| 2026-06-14 | `260614-localfirst-workspaces-deep-dive/` | Anytype · AFFiNE · AppFlowy — CRDT local-first workspaces (any-sync/Yjs/Yrs), native merge, P2P/E2EE; UC-64/65 | \ No newline at end of file diff --git a/spec/UseCaseCatalog.md b/spec/UseCaseCatalog.md index f34ebf0..a29ffaf 100644 --- a/spec/UseCaseCatalog.md +++ b/spec/UseCaseCatalog.md @@ -8,8 +8,9 @@ Promoted from `research/260608-c2-wiki-origins/`, `research/260613-twiki-deep-dive/`, `research/260613-foswiki-deep-dive/`, `research/260614-xanadu-deep-dive/`, `research/260614-zigzag-deep-dive/`, `research/260614-roam-deep-dive/`, `research/260614-obsidian-deep-dive/`, -`research/260614-notion-deep-dive/`, `research/260614-joplin-deep-dive/`, and -`research/260614-logseq-deep-dive/`. +`research/260614-notion-deep-dive/`, `research/260614-joplin-deep-dive/`, +`research/260614-logseq-deep-dive/`, and +`research/260614-localfirst-workspaces-deep-dive/`. See InfoTechPrimers on coulomb.social for use-case catalog conventions. ## Conventions @@ -283,7 +284,9 @@ closed-SaaS instance: internal page history bounded by plan, **not portable** an exported as git (`research/260614-notion-deep-dive/findings.md` §4) — a supplementation case like Confluence/MediaWiki, not an import case. **Joplin** keeps internal note revisions locally, likewise not portable (`research/260614-joplin-deep-dive/findings.md` -§1) — supplement. +§1) — supplement. **CRDT** shards (Anytype/AFFiNE/AppFlowy) keep a CRDT update log, not +git — also supplement, or snapshot the replica +(`research/260614-localfirst-workspaces-deep-dive/findings.md` §4). **Priority:** Later ### UC-37 — Attach a static engine export as a read-only backup shard @@ -472,7 +475,9 @@ a page is a cell at the intersection of many independent ranks (`research/260614-zigzag-deep-dive/findings.md` §2, §5). Reframes the existing derived views (UC-05, UC-17–UC-20) as *dimensions + rasters* under one vocabulary. Embodies union-without-erasure: every relationship co-equal, none privileged. Open: public -navigation API vs. internal model (findings §10 Q1). +navigation API vs. internal model (findings §10 Q1). **AFFiNE** ships the commercial +proof: docs, whiteboards, and databases are *views of the same block set* +(`research/260614-localfirst-workspaces-deep-dive/findings.md` §2). **Priority:** Later ### UC-48 — Pivot two relationships into a cross-tab view (H-view) @@ -484,7 +489,9 @@ or page × versions-across-shards — and pivot to re-cross by a different pair. **Notes:** ZigZag **H-view** shows two dimensions through a cursor, one horizontal one vertical, with only existing cells present (`research/260614-zigzag-deep-dive/findings.md` §3). A differentiated exploration primitive for federation/provenance. Open: reference-UI -investment vs. research-only (findings §10 Q4). +investment vs. research-only (findings §10 Q4). **AFFiNE**'s page/edgeless/DB modes over +one block set are this idea shipped (`research/260614-localfirst-workspaces-deep-dive/findings.md` +§2). **Priority:** Later ### UC-49 — Navigate created-from / fork genealogy as a first-class dimension @@ -544,7 +551,10 @@ rename/move (`research/260614-joplin-deep-dive/findings.md` §1) — coarser tha UUID, more stable than a path. **Logseq** is the **sweet spot**: a block-level `id:: uuid` stored **in the Markdown text** — fine-grained *and* git-diffable/portable at once, resolving the Roam(DB-minted) vs Obsidian(page-level) tension -(`research/260614-logseq-deep-dive/findings.md` §2). +(`research/260614-logseq-deep-dive/findings.md` §2). **CRDT** shards +(Anytype/AFFiNE/AppFlowy) mint object/block IDs as part of the CRDT structure — fine- +grained, store-assigned (`research/260614-localfirst-workspaces-deep-dive/findings.md` +§6). **Priority:** Later ### UC-52 — Delegate derived views to a shard's native query engine @@ -615,7 +625,9 @@ decision, not just adapter config (findings §10). JSON Canvas is an open format first-class support. **Joplin** resources (attachments, each with an ID, linked `:/`) are the same demand in a sync-mirror shard (`research/260614-joplin-deep-dive/findings.md` §5). **Logseq whiteboards** (tldraw JSON) are the same in a file-store block shard -(`research/260614-logseq-deep-dive/findings.md` §6). +(`research/260614-logseq-deep-dive/findings.md` §6). **AFFiNE** edgeless canvas, **AppFlowy** +boards/calendars, and **Anytype** objects/files are the same demand in CRDT shards +(`research/260614-localfirst-workspaces-deep-dive/findings.md` §5). **Priority:** Later ### UC-56 — Publish a curated projection to an external read-only target @@ -649,7 +661,10 @@ profile must encode this **operational envelope** and **scoped/revocable grant** projection is cache/poll/webhook, not a live read model. Best as projection/mirror/ overlay/backup; write-through possible but bounded. Links the authz-in-core decision and "no silent remote mutation". Third attachment mode alongside file-store (UC-40) and -in-engine host (UC-38/50). +in-engine host (UC-38/50). Self-hostable variants: **AFFiNE Cloud** / **AppFlowy Cloud** +(self-host sync servers) and **Anytype**'s open API + MCP are endpoint forms within a +user's trust boundary (`research/260614-localfirst-workspaces-deep-dive/findings.md` §4, +§9) — see also UC-65 (P2P, no single endpoint). **Priority:** Later ### UC-58 — Attach a typed database with schema, relations, and views @@ -665,7 +680,10 @@ relations**, shown through many views (table/board/calendar/gallery) (`research/260614-notion-deep-dive/findings.md` §2). Presses the page model: collection + schema + relations, not just a page (findings §9). Relations map to the union link graph and/or a relation index (cf. ZigZag many-to-many, UC-47/48); views relate to UC-54. -Deferred to `SHARD-WP-0002`. +Deferred to `SHARD-WP-0002`. **Local-first** variants exist: **Anytype**'s user-editable +typed object graph (types + relations = an ontology) and **AppFlowy**'s Notion-style DBs, +both CRDT-backed (`research/260614-localfirst-workspaces-deep-dive/findings.md` §1, §3) — +the typed-collection demand is not exclusive to hosted SaaS. **Priority:** Later ### UC-59 — Translate a proprietary content model with an explicit fidelity report @@ -718,7 +736,10 @@ proposed as a twelfth spectrum for the adapter contract (findings §8; extends `research/260614-shard-spectrum-synthesis/findings.md` §2). Graceful degradation extreme: IDs/counts/timestamps may be visible while bodies are opaque; never silently surface undecryptable content. Open: does shard-wiki ever hold keys, or only treat such shards as -opaque backups (findings §9 Q1)? Ties [[shard-wiki-auth-in-core-decision]]. +opaque backups (findings §9 Q1)? Ties [[shard-wiki-auth-in-core-decision]]. **Anytype** +reinforces this: any-sync is **E2EE by default** — backup nodes hold ciphertext they +cannot read (`research/260614-localfirst-workspaces-deep-dive/findings.md` §1), and it is +**P2P** (UC-65). **Priority:** Later ### UC-62 — Attach a block-graph-on-plain-files shard @@ -755,6 +776,41 @@ Open: built by adapter (per-shard) or core (over the union); persisted vs rebuil (findings §10 Q2). Belongs to the T16 navigation layer + T11 capabilities. **Priority:** Later +### UC-64 — Attach a CRDT-synced local-first shard with native merge + +**Actor:** Maintainer +**Goal:** Attach a CRDT-based local-first store (Anytype any-sync, AFFiNE Yjs, AppFlowy +Yrs) whose backend performs **conflict-free merge itself** — consuming a replica or +sync endpoint, respecting CRDT semantics rather than imposing git/text merge. +**Source:** localfirst-workspaces, intent +**Notes:** The cohort's defining trait: the store is a CRDT, so concurrent edits merge +mathematically (`research/260614-localfirst-workspaces-deep-dive/findings.md` §4). Adds a +**merge-model** capability (`none → git/text → native-CRDT`) — a proposed **thirteenth +spectrum** for the adapter contract (with Joplin's content-opacity twelfth). shard-wiki +must **not** git-merge a CRDT shard: speak the CRDT (hold a replica) for live/writable, or +stay **projection/overlay** that respects CRDT merge. History is the **CRDT update log**, +not git → supplement (UC-36). Attach a **local replica** (offline, full state) or a +self-host sync endpoint (UC-57). Like Joplin, do **not** re-drive the backend's sync +(not-a-file-sync-daemon). Open: embed a CRDT client vs consume snapshots; overlays as CRDT +ops vs out-of-band patches (findings §10 Q1–Q2). +**Priority:** Later + +### UC-65 — Attach a peer-to-peer / decentralized shard with no single endpoint + +**Actor:** Maintainer +**Goal:** Attach a decentralized shard (Anytype any-sync: P2P, E2EE) that has **no single +canonical URL** — binding via a local replica or a named peer/backup node, with content +that may be encrypted. +**Source:** localfirst-workspaces, intent +**Notes:** any-sync is P2P with sync/file/consensus/coordinator nodes; **backup nodes hold +ciphertext they cannot read**; changes signed/encrypted with the user's key +(`research/260614-localfirst-workspaces-deep-dive/findings.md` §1, §4). The shard's +"address" is a space ID + replica/peer/invite, **not a URL** — a new binding mode beside +file-store / in-engine-host / external-API (UC-40/38/57). Combines with **content opacity** +(UC-61): E2EE shards are replica-only / opaque without keys. Open: shard address form; +whether shard-wiki holds keys (findings §10 Q3–Q4). Ties [[shard-wiki-auth-in-core-decision]]. +**Priority:** Later + --- ## B. Knowledge work and collaboration @@ -1006,6 +1062,8 @@ CamelCase and `[[free links]]`. Markdown-first link semantics TBD. | UC-61 | | | | ‖ | ✓ | | UC-62 | | | | ※ | ✓ | | UC-63 | | | | ※ | ✓ | +| UC-64 | | | | ⌘ | ✓ | +| UC-65 | | | | ⌘ | ✓ | | UC-08 | ✓ | | | | UC-09 | ✓ | | | | UC-10 | ✓ | | | @@ -1317,6 +1375,39 @@ substrate migrating file→SQLite (UC-43). Architecture logged for `SHARD-WP-000 (T11/T14/T16): Logseq format profile, derived-query-index capability, substrate-migration tolerance, in-file block addressing as the concrete T16 span-address target. +### localfirst-workspaces mapping (Anytype · AFFiNE · AppFlowy) + +(⌘ UC-64–UC-65 are placed in the **wikiengines** matrix column as the nearest existing +source — these are shipped tools — but their true lineage is the **local-first workspaces +cohort dive**, `research/260614-localfirst-workspaces-deep-dive/findings.md`.) + +| Cohort mechanism (findings §) | Catalog UC | +|-------------------------------|------------| +| CRDT store with native conflict-free merge (any-sync / Yjs / Yrs) (§4) | UC-64 (new) | +| P2P, no single canonical endpoint; E2EE (Anytype any-sync) (§1, §4) | UC-65 (new) | +| CRDT update log ≠ portable git history → supplement (§4) | UC-36 (enriched) | +| One block set as page / canvas / DB views (AFFiNE) (§2) | UC-47, UC-48 (enriched) | +| Edgeless canvas / boards / objects = non-Markdown content (§5) | UC-55 (enriched) | +| Self-host sync server (AFFiNE/AppFlowy Cloud) + Anytype open API/MCP (§4, §9) | UC-57 (enriched) | +| Typed object graph / user-editable ontology + Notion-style DBs, local-first (§1, §3) | UC-58 (enriched) | +| E2EE by default; backup nodes hold ciphertext (Anytype) (§1) | UC-61 (enriched) | +| Object/block IDs CRDT-assigned (fine-grained) (§6) | UC-51 (enriched) | +| Lossy Markdown export (§5) | links UC-59 | + +Note: Anytype, AFFiNE, and AppFlowy form the **CRDT local-first workspace** family — the +first studied shards whose **store is a CRDT** (the backend merges concurrent edits +itself). This changes the adapter math: shard-wiki must **not impose git/text merge** +(speak the CRDT via a replica, or stay projection/overlay), history is a **CRDT update +log** (supplement), and the attach surface is a **replica or self-host sync endpoint** — +Anytype adding **P2P + E2EE** (no single endpoint, opaque without keys). **Boundary +recorded:** CRDT local-first candidate shards — attach a replica/projection as pages, +respect native merge, never re-drive their sync; not substrates and not the federation +layer (`research/260614-localfirst-workspaces-deep-dive/findings.md` §7). Architecture +logged for `SHARD-WP-0002` (T11/T14): a **merge-model** capability (proposed thirteenth +spectrum: `none / git / native-CRDT`), a **CRDT-replica** substrate + **P2P/no-central- +endpoint** attach mode, an **endpoint-model** capability, and MCP as an integration +surface. + --- ## Open questions @@ -1355,4 +1446,10 @@ tolerance, in-file block addressing as the concrete T16 span-address target. orchestrator (over the union), and is it persisted or rebuilt? (Logseq dive §10.) 17. When a tool offers **both file and DB substrates** (Logseq), does shard-wiki prefer the git-diffable file graph or the richer DB graph, and can one binding follow the - migration? (UC-43, UC-62.) \ No newline at end of file + migration? (UC-43, UC-62.) +18. For a **CRDT shard** (UC-64), does shard-wiki embed a CRDT client (Yjs/Yrs) to hold a + live replica, or consume periodic snapshots — and are overlays CRDT ops or out-of-band + patches? (Local-first workspaces dive §10.) +19. For a **P2P shard** (UC-65), what is the shard's address (space ID + peer / replica + path / invite-key), and does shard-wiki ever hold E2EE keys or only treat it as an + opaque replica? (UC-61.) \ No newline at end of file