diff --git a/SCOPE.md b/SCOPE.md index d73c6a2..6a22ee7 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 + local-first workspaces (Anytype/AFFiNE/AppFlowy) 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) + Trilium deep dives & shard-spectrum synthesis (`research/260614-*/`) | | Demand | NetKingdom integration asks captured, not yet negotiated | -| Spec | Architecture blueprint drafted; UseCaseCatalog 65 UCs from research; PRD/TSD scaffolds | +| Spec | Architecture blueprint drafted; UseCaseCatalog 67 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-trilium-deep-dive/README.md b/research/260614-trilium-deep-dive/README.md new file mode 100644 index 0000000..6cd4a65 --- /dev/null +++ b/research/260614-trilium-deep-dive/README.md @@ -0,0 +1,53 @@ +# 260614 — Trilium (TriliumNext) deep dive (note cloning, attribute inheritance, HTML-native) + +Date: 2026-06-14 + +## What this is + +A focused study of **Trilium / TriliumNext** — the open-source hierarchical personal +knowledge base — read through shard-wiki's lens. It is another SQLite-local note app, but +it brings a structural feature **none of the prior twelve systems had: note cloning** — +a single note can sit in **multiple places in the tree at once**, so the hierarchy is a +**DAG, not a tree**, with **note identity cleanly separated from placement** (a note has +many "branches"). It also has an **attribute system with inheritance + templates** +(computed metadata) and is one of the few **HTML-native** (not Markdown) tools. + +Lineage: **TriliumNext** is the community fork of the original **Trilium** (zadam, now +maintenance-only) — the same pattern as TWiki→Foswiki. + +Distinctive material: +- **Architecture** — single **SQLite** file (`document.db`); desktop or self-host server; + multi-instance **sync protocol w/ conflict resolution** + WebSocket; 12-char IDs + (`noteId`/`branchId`/`attributeId`/`attachmentId`) +- **Note cloning** — note vs **branch** (identity vs placement); DAG hierarchy; no single + canonical path +- **Attributes** — labels (`#tag`) + typed relations (`~relation`), **inheritable** + + **templates** (`~template`) → effective vs own metadata +- **Content** — **HTML** (CKEditor5), plus canvas/mindmap/spreadsheet/geo/render note + types; export to MD/HTML (lossy) +- **Extension** — **scripting** (frontend/backend code notes, Script API) + **ETAPI** + (token REST); **per-note encryption** (protected notes) + +## Contents + +| Path | Role | +|------|------| +| `findings.md` | Architecture, note cloning/DAG, attributes+inheritance, HTML content, scripting/ETAPI, per-note encryption, capability profile, INTENT mapping, UC seeds, sources | + +## Status + +Initial deep dive complete. Two new use cases promoted to `spec/UseCaseCatalog.md` (UC-66 +attach a shard with a DAG hierarchy / note cloning, identity separated from placement; +UC-67 preserve inherited/templated attributes — effective vs own metadata); UC-15/22/34/ +38/42/61 enriched. Logged for `SHARD-WP-0002` (T11/T12/T14/T15/T16): DAG namespace + +identity/placement (note/branch) split, computed/inherited metadata in the page model, +**per-item** content opacity (refining the 12th spectrum), HTML as a source content model, +and scripting + ETAPI host surfaces. + +**Key takeaways recorded:** Trilium's **note/branch split (identity ≠ placement)** is the +clean model for pages that live in multiple locations/shards and the namespace-level form +of the clone/reference primitive; metadata is **computed** (own + inherited + template), +not a flat bag; and **content opacity is per-item** (per-note encryption), not only +whole-shard. **Boundary:** one SQLite-local candidate shard (DAG hierarchy, HTML-native), +best attached via ETAPI; not a substrate and not the federation layer. + diff --git a/research/260614-trilium-deep-dive/findings.md b/research/260614-trilium-deep-dive/findings.md new file mode 100644 index 0000000..4582af8 --- /dev/null +++ b/research/260614-trilium-deep-dive/findings.md @@ -0,0 +1,274 @@ +# Findings — Trilium (TriliumNext): note cloning, attribute inheritance, HTML-native + +Date: 2026-06-14 +Source kind: **modern shipped product** — an open-source hierarchical PKB; a *candidate +shard* whose distinctive traits are **note cloning (a DAG hierarchy)**, an +**attribute/relation system with inheritance + templates**, and **HTML-native** content +Lens: shard-wiki — the namespace model (identity vs placement), inherited/computed +metadata, HTML translation, per-note encryption, and the scripting/ETAPI surfaces + +> Why Trilium earns a dive. It is another SQLite-local note app, but it brings a +> structural feature **none of the prior twelve systems had: note cloning** — a single +> note can sit in **multiple places in the tree at once**, so the hierarchy is a **DAG, +> not a tree**, and **note identity is cleanly separated from placement** (a note has +> many "branches"). That directly challenges shard-wiki's namespace model (UC-22 assumes +> a path) and is the clone/reference primitive made concrete at the *namespace* level. +> Trilium also has an **attribute system with inheritance and templates** (effective +> metadata is computed, not just stored), and it is one of the few **HTML-native** (not +> Markdown) tools — a useful stress on "Markdown-first must degrade." + +Lineage note (like TWiki→Foswiki): **TriliumNext** is the community fork of the original +**Trilium** (zadam) after it went maintenance-only; the active project is TriliumNext. + +Contrast set: Joplin (SQLite-local, files-on-sync, page-level), Logseq (block-graph on +files), Notion (hosted DB, schema+relations). Trilium = **SQLite-local, DAG hierarchy, +inherited attributes, HTML content, self-host sync + ETAPI**. + +--- + +## 1. Core architecture — one SQLite file, server-syncable + +- **Storage:** a single **SQLite** file (`document.db`, via better-sqlite3) holding + notes, attachments, history, and settings. Local DB store (like Joplin; not files). +- **Clients/sync:** desktop (Electron) or a self-hosted **server**; multi-instance + **sync protocol** with **conflict resolution + entity change tracking**, plus + **WebSocket** realtime updates. Attach via the server, the ETAPI (§5), or the DB. +- **IDs:** 12-char IDs — **`noteId`, `branchId`, `attributeId`, `attachmentId`**. The + **note vs branch** split is the key idea (§2). +- **Export:** to Markdown/HTML (lossy — content is HTML, §4). + +--- + +## 2. Note cloning — a DAG hierarchy, identity separated from placement + +Notes form an arbitrarily deep tree, **but a single note can be placed in multiple +locations** — "cloning," implemented via the **branches** model: + +- A **note** (`noteId`) is the content + identity. A **branch** (`branchId`) is *one + placement* of that note under a parent (with an optional **branch prefix** giving + per-location context). A note with several branches is **cloned** — it appears in + several places at once; editing it anywhere edits the one note. +- So the hierarchy is a **DAG**, not a tree, and **identity (note) is separated from + location (branch)**. There is no single canonical path for a cloned note. + +This is the most shard-wiki-relevant feature in the dive: + +- It breaks the assumption behind **UC-22** (resolve a page by *a* path). shard-wiki's + namespace model must allow **a page in multiple namespace locations** with no single + canonical path (UC-66). +- The **note/branch split** is a clean model shard-wiki should borrow: **page identity ≠ + page placement**. A page is one entity; its locations are separate placement records — + exactly how shard-wiki should treat a page that appears under multiple paths/shards. +- It is the **clone/reference-not-copy primitive** (Xanadu clone, ZigZag clone, UC-44/45, + T16) realized at the *namespace* level: same note, many positions, one source of truth. + +--- + +## 3. Attributes — labels + relations, with inheritance and templates + +Trilium's metadata system is **attributes**: + +- **Labels** (`#tag`, optionally `#key=value`) — typed metadata on a note. +- **Relations** (`~relation`) — **typed links to other notes** (a knowledge graph). +- **Inheritance** — attributes can be **inherited down the subtree** (inheritable + attributes), and **templates** (a note whose attributes/structure are applied to + instances via a `~template` relation) inject attribute sets. So a note's **effective + metadata = its own attributes + inherited + templated** — computed, not just stored. +- Promoted attributes give a form-like UI; attributes drive **search/queries** and + **scripting**. + +shard-wiki read: this is structured data (UC-34) and typed relations (UC-58), but with a +**new wrinkle — inheritance/templates make metadata *computed***. Projecting such a shard +must distinguish **effective vs own** attributes (and record their provenance: own / +inherited-from / template), not flatten them (UC-67). Templates also reinforce blueprint +pages (UC-15). + +--- + +## 4. Content model — HTML-native, many note types + +- **Text notes are HTML** (WYSIWYG via **CKEditor5**), **not Markdown**. Trilium is one + of the few HTML-first tools studied. Markdown participation therefore needs **HTML↔ + Markdown translation** — more tractable than Notion's block model but still **lossy** + for some constructs (CKEditor features, includes) → a fidelity-aware case bridging + UC-42 (lossless ideal) and UC-59 (lossy-with-report). +- **Note types:** text (HTML), code (CodeMirror), **canvas (Excalidraw)**, relation + maps, mind maps (Mind Elixir), spreadsheets (Univer), geo maps (Leaflet), **render + notes**, file/image, book — i.e. lots of **non-Markdown content** (UC-55) and + **script/render-generated dynamic notes** (UC-54). + +--- + +## 5. Extension surfaces — scripting (in-app) + ETAPI (external) + +Two surfaces, like Joplin: + +- **Scripting (in-engine host).** **Code notes** in JS run as **frontend** (UI widgets, + buttons) or **backend** (server-side automation) scripts against a **Script API** + (create/query notes, attributes, etc.). Executable, in-app — the adapter-host path + (UC-38). "Render notes" + scripts produce **dynamic, generated content** (UC-54). +- **ETAPI (external REST API).** Trilium's public REST API (since v0.50), **token auth** + (`Bearer ETAPITOKEN`), with client libs (`trilium-py`): CRUD over notes/branches/ + attributes/attachments, search, import/export — an external attach surface (UC-57) + that, unlike Joplin's localhost-only Data API, is the **designed external integration + API** for a (often self-hosted) server. + +--- + +## 6. Security — per-note (partial) encryption + +Trilium offers **strong per-note encryption** ("protected notes") unlocked in a +**protected session** (password; TOTP/OpenID for login). Crucially this is **per-note**: +a shard can hold **some encrypted and some plaintext notes at once**. This refines the +**content-opacity** dimension (UC-61, proposed twelfth spectrum from Joplin/Anytype): +opacity is **per-item, not only whole-shard** — the adapter must handle a shard where +*part* of the content is opaque without a key (protected notes projectable only as +structure-shell; unprotected notes fully). + +--- + +## 7. Trilium as a shard — capability profile + +| Capability | Trilium | Notes for the adapter contract | +|------------|---------|--------------------------------| +| Read | yes (ETAPI / sync / DB) | ETAPI REST (server) is the clean surface | +| Write | yes (ETAPI / script) | per-note; via ETAPI or backend code notes | +| Write granularity | per-note (page) | — | +| Identity / addressing | **`noteId` + `branchId`** (12-char) | **identity ≠ placement**; cloned notes have many branches (UC-51, UC-66) | +| Hierarchy | **DAG (cloning)** | a note in multiple locations; no single canonical path (UC-66) | +| Structure | **labels + relations, inherited + templated** | effective vs own metadata (UC-34, UC-58, UC-67) | +| Content | **HTML (CKEditor)** + many types | HTML↔MD lossy translation (UC-42/59); non-MD types (UC-55) | +| History | internal revisions in the DB | not portable git → supplement (UC-36) | +| Native query | attribute search / script queries | delegate or build index (UC-52/63) | +| Subscribe | WebSocket + sync protocol | push; conflict resolution built in (UC-31) | +| Content opacity | **per-note encryption (partial)** | per-item opacity (UC-61 refined) | +| Extension | **scripting (in-app) + ETAPI (external)** | dual surface (UC-38, UC-57) | +| Templates | yes (`~template`) | blueprint pages (UC-15) | + +Verdict: a capable **SQLite-local, server-syncable** shard best attached via **ETAPI**. +Standout demands: the **DAG hierarchy / note-branch identity model** (UC-66) and +**inherited/templated attributes** (UC-67); plus HTML-native translation, per-note +opacity, and the scripting host. + +--- + +## 8. Mapping to shard-wiki INTENT (compare, do not equate) + +### 8.1 Reinforcements + +- **Identity ≠ placement** (note/branch) is a model shard-wiki should adopt for pages + that appear under multiple paths or in multiple shards — provenance and union without + erasure depend on separating "what a page is" from "where it sits." +- **Typed relations + templates** validate the structured/relation demand (UC-58) and + blueprints (UC-15) on a local-first, self-hostable backend. +- **ETAPI** is a clean example of a **designed external REST surface** for a self-hosted + server (cf. Notion external API, but self-hosted/trust-boundary friendly). + +### 8.2 Deliberate divergences (design bugs if conflated) + +1. **Don't force a single canonical path.** A cloned note has many placements; modeling + it with one path loses information (UC-66). Use the note/branch separation. +2. **Don't flatten computed metadata.** Effective attributes include inherited/templated + values; record provenance (own vs inherited vs template), don't collapse (UC-67). +3. **HTML-native, not Markdown.** Translate HTML↔Markdown with a fidelity report; degrade + to read-only where lossy (UC-42/59/03). Markdown-first must degrade gracefully. +4. **Per-note opacity.** Some notes are encrypted; never surface protected-note + ciphertext; project them as structure-shell (UC-61). +5. **One Trilium instance = one shard**, not the federation layer; its sync protocol is + its own — attach via ETAPI/replica, don't re-drive it (not-a-sync-daemon). + +### 8.3 What Trilium teaches that shard-wiki should keep + +- **Separate page identity from placement** (note vs branch) — the cleanest model for + multi-location / multi-shard pages and for the clone/reference primitive (T16). +- **Model metadata as computed** (own + inherited + templated) with per-attribute + provenance (UC-67) — not a flat key/value bag. +- **Content opacity is per-item**, not only whole-shard (UC-61 refinement). + +--- + +## 9. Use-case seeds → catalog (promoted 2026-06-14) + +Last existing UC is **UC-65**. New UCs **UC-66, UC-67** added; existing UCs enriched. + +| Seed | Catalog action | +|------|----------------| +| **Attach a shard with a DAG hierarchy / note cloning** — a page may occupy multiple namespace locations at once (note identity separated from placement via branches); no single canonical path | **UC-66 (new)** | +| **Preserve inherited / templated attributes** — project a structured shard whose metadata is computed (own + inherited + template), distinguishing effective vs own with per-attribute provenance | **UC-67 (new)** | +| DAG/multi-parent vs tree; note/branch (identity vs placement) | **enriches UC-22** | +| Labels (`#tag`) + typed relations (`~relation`); HTML-native | **enriches UC-34** | +| Templates (`~template`) inject attribute sets | **enriches UC-15** | +| HTML (CKEditor) content → HTML↔Markdown lossy translation | **enriches UC-42** (links UC-59) | +| Per-note encryption (protected notes) = **partial** content opacity | **enriches UC-61** | +| Scripting (frontend/backend code notes, Script API) = in-app host | **enriches UC-38** | +| ETAPI (token REST) = designed external surface for a self-host server | links UC-57 | +| Render/script notes + attribute queries = dynamic content | links UC-54; typed relations link UC-58 | +| `noteId`/`branchId` 12-char IDs | links UC-51 | + +--- + +## 10. Architecture notes for SHARD-WP-0002 (no UC) + +- **Namespace model must support a DAG** and **separate page identity from placement** + (note/branch). A page is one entity with N placements (paths/shards). Feeds the page/ + namespace model and the clone/reference primitive. (T12, T16.) +- **Computed/inherited metadata** (UC-67): the page model's structured-data + representation must carry **effective vs own** with per-attribute provenance + (own/inherited/template), not a flat bag. (T12.) +- **Content opacity is per-item** (UC-61 refinement): the content-opacity capability + (proposed twelfth spectrum) should be **granular** (per-note), not only whole-shard. + (T11.) +- **HTML as a source content model** joins TML/Notion-blocks in the translation + capability (HTML↔Markdown, lossy-aware). (T15.) +- **Scripting as an in-engine host** + **ETAPI external REST** are two more adapter-host + exemplars (with Roam/Obsidian/Joplin). (T14.) + +--- + +## 11. Open questions (for spec / workplans) + +1. How does shard-wiki represent a **cloned note** in the union — one page with multiple + path placements, or a page transcluded into multiple locations? (UC-66 vs UC-44/45.) +2. When projecting **inherited attributes** (UC-67), does shard-wiki materialize + effective values (snapshot) or compute them live from the shard's tree/templates? +3. Is **HTML↔Markdown** round-trip lossless enough for write-back overlays, or are + Trilium overlays read-only/native-HTML (cf. UC-42 Q2)? +4. For **per-note encryption** (UC-61), is a partially-opaque shard projected with + protected notes as visible-but-opaque placeholders, or hidden entirely? + +--- + +## 12. Sources + +| Source | Used for | +|--------|----------| +| TriliumNext/Trilium — DeepWiki (https://deepwiki.com/TriliumNext/Trilium) | SQLite `document.db`/better-sqlite3; tree + cloning via branches; note types; sync | +| Cloning notes — TriliumNext wiki (https://github.com/TriliumNext/Trilium/wiki/Cloning-notes) | Note in multiple locations; branches; branch prefixes | +| TriliumNext — DeepWiki API & Synchronization (https://deepwiki.com/TriliumNext/Trilium/4.3-api-and-synchronization) | WebSocket + sync protocol w/ conflict resolution; 12-char IDs (note/branch/attribute/attachment) | +| ETAPI (REST API) — Trilium docs (https://docs.triliumnotes.org/User%20Guide/User%20Guide/Advanced%20Usage/ETAPI%20(REST%20API)/) | Public REST API since v0.50; token/Bearer auth; trilium-py | +| Script API — TriliumNext wiki (https://github.com/TriliumNext/Trilium/wiki/Script-API) | Frontend/backend code notes; Script API | +| BrightCoding — TriliumNext overview (https://www.blog.brightcoding.dev/2025/09/20/triliumnext-notes...) | Attributes (labels/relations), inheritance, templates, per-note encryption, note types | + +Cross-references: `research/260614-joplin-deep-dive/findings.md` (SQLite-local, dual +surface, content opacity), `research/260614-notion-deep-dive/findings.md` (typed +relations, external API), `research/260614-zigzag-deep-dive/findings.md` (clone / +dimensions), `research/260614-shard-spectrum-synthesis/findings.md` (spectra this +refines), `spec/UseCaseCatalog.md` (UC-15, UC-22, UC-34, UC-38, UC-42, UC-51, UC-54, +UC-57, UC-58, UC-61), `workplans/SHARD-WP-0002-federation-architecture.md` (T11, T12, +T14, T15, T16). + +--- + +## 13. Traceability + +- New UCs: **UC-66, UC-67** → `spec/UseCaseCatalog.md`. +- Enriched UCs: **UC-15, UC-22, UC-34, UC-38, UC-42, UC-61** (links UC-51, UC-54, UC-57, + UC-58, UC-59). +- Architecture (no UC): DAG namespace + identity/placement (note/branch) split; + computed/inherited metadata; per-item content opacity; HTML source model; scripting + + ETAPI host surfaces → `SHARD-WP-0002` (T11, T12, T14, T15, T16). +- Boundary recorded: Trilium (TriliumNext) is **one SQLite-local candidate shard** with a + DAG hierarchy and computed metadata, best attached via **ETAPI**; HTML-native (lossy to + Markdown), per-note opacity; not a substrate, not the federation layer (INTENT + graceful-degradation, no-silent-mutation, not-a-sync-daemon). + diff --git a/research/README.md b/research/README.md index 9047ce2..eda87d3 100644 --- a/research/README.md +++ b/research/README.md @@ -25,4 +25,5 @@ when multiple files or sources are involved. Findings here inform `spec/` and | 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 | -| 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 +| 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 | +| 2026-06-14 | `260614-trilium-deep-dive/` | Trilium/TriliumNext — note cloning (DAG hierarchy), attribute inheritance/templates, HTML-native, scripting+ETAPI; UC-66/67 | \ No newline at end of file diff --git a/spec/UseCaseCatalog.md b/spec/UseCaseCatalog.md index a29ffaf..df3ce22 100644 --- a/spec/UseCaseCatalog.md +++ b/spec/UseCaseCatalog.md @@ -9,8 +9,9 @@ Promoted from `research/260608-c2-wiki-origins/`, `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/`, -`research/260614-logseq-deep-dive/`, and -`research/260614-localfirst-workspaces-deep-dive/`. +`research/260614-logseq-deep-dive/`, +`research/260614-localfirst-workspaces-deep-dive/`, and +`research/260614-trilium-deep-dive/`. See InfoTechPrimers on coulomb.social for use-case catalog conventions. ## Conventions @@ -244,7 +245,9 @@ end: typed database properties with relations/rollups/formulas, lossy to Markdow see UC-58 (`research/260614-notion-deep-dive/findings.md` §2). **Logseq** sits between: `key:: value` block/page properties live in the Markdown text (git-diffable) yet are queried via a derived Datalog graph (`research/260614-logseq-deep-dive/findings.md` §2–§3) -— in-text structure at block granularity. +— in-text structure at block granularity. **Trilium** adds **computed** structure: labels ++ typed relations that are **inherited + templated**, so effective metadata ≠ stored +metadata — see UC-67 (`research/260614-trilium-deep-dive/findings.md` §3). **Priority:** Later ### UC-35 — Attach a shard with coarse write granularity @@ -326,7 +329,10 @@ client, so write-through requires in-engine hosting (findings §11 Q2). **Joplin *two* surfaces: an in-app plugin host (`joplin.data`/`workspace`/`contentScripts`) **and** a **local Data API** (REST on `localhost:41184`, token, app-running) — a local-REST attach sub-mode between in-engine host and external API (UC-57, -`research/260614-joplin-deep-dive/findings.md` §4). +`research/260614-joplin-deep-dive/findings.md` §4). **Trilium** is the same dual pattern: +**scripting** (frontend/backend code notes against a Script API) as the in-app host, plus +**ETAPI** (token REST) as a designed external surface for a self-hosted server +(`research/260614-trilium-deep-dive/findings.md` §5). **Priority:** Later ### UC-39 — Attach a wiki-as-application-platform shard (pages as typed records) @@ -399,7 +405,10 @@ as read-only. HTML→TML losslessly on save) (`research/260613-foswiki-deep-dive/findings.md` §5). Open: is round-trip lossless enough, or must overlays be stored in the shard's native syntax to be safe (findings §9 Q2)? Without this, non-Markdown shards degrade to -read-only (UC-03) — a graceful-degradation floor, not the goal. +read-only (UC-03) — a graceful-degradation floor, not the goal. **Trilium** is the +HTML-native case: text notes are HTML (CKEditor5), so participation needs HTML↔Markdown +translation — more tractable than Notion's blocks but still lossy for some constructs +(`research/260614-trilium-deep-dive/findings.md` §4, links UC-59). **Priority:** Later ### UC-43 — Tolerate a shard's storage-backend swap without losing identity @@ -739,7 +748,9 @@ undecryptable content. Open: does shard-wiki ever hold keys, or only treat such 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). +**P2P** (UC-65). **Trilium** refines the dimension to **per-item**: protected (encrypted) +notes coexist with plaintext notes in one shard, so opacity is per-note, not whole-shard +(`research/260614-trilium-deep-dive/findings.md` §6). **Priority:** Later ### UC-62 — Attach a block-graph-on-plain-files shard @@ -811,6 +822,40 @@ file-store / in-engine-host / external-API (UC-40/38/57). Combines with **conten whether shard-wiki holds keys (findings §10 Q3–Q4). Ties [[shard-wiki-auth-in-core-decision]]. **Priority:** Later +### UC-66 — Attach a shard with a DAG hierarchy (note cloning) + +**Actor:** Maintainer +**Goal:** Attach a shard where a page may occupy **multiple namespace locations at once** +(Trilium note cloning) — representing the multi-location membership, with page identity +separated from placement, without forcing a single canonical path. +**Source:** trilium, intent +**Notes:** Trilium models a **note** (identity, `noteId`) separately from its **branches** +(placements, `branchId`); a note with several branches is **cloned** into several tree +locations — so the hierarchy is a **DAG, not a tree** +(`research/260614-trilium-deep-dive/findings.md` §2). Breaks UC-22's single-path +assumption. shard-wiki should borrow the **identity ≠ placement** split (one page entity, +N placements/paths/shards) — also the right model for a page appearing under multiple +paths or across shards. The namespace-level form of the clone/reference primitive (T16; +cf. Xanadu/ZigZag clone, UC-44/45). Open: model as one page with N placements vs +transclusion into N locations (findings §11 Q1). +**Priority:** Later + +### UC-67 — Preserve inherited and templated attributes (effective vs own metadata) + +**Actor:** Reader or maintainer +**Goal:** Project a structured shard whose metadata is **computed** — a page's effective +attributes derive from its own values plus inherited (ancestor) and templated values — +distinguishing **effective vs own** with per-attribute provenance, not flattening. +**Source:** trilium, intent +**Notes:** Trilium attributes (labels `#tag`, typed relations `~relation`) can be +**inherited down the subtree** and injected by **templates** (`~template`), so effective +metadata = own + inherited + templated (`research/260614-trilium-deep-dive/findings.md` +§3). Extends UC-34/UC-58 with a new wrinkle: **metadata is computed, not just stored** — +record each attribute's provenance (own / inherited-from / template). Open: materialize +effective values (snapshot) vs compute live from the shard's tree/templates (findings §11 +Q2). Templates also reinforce UC-15 (blueprints). +**Priority:** Later + --- ## B. Knowledge work and collaboration @@ -896,7 +941,9 @@ an agreed layout or subtree. **Notes:** yawex blueprint pages. Distinct from UC-08 (blank capture) and UC-10 (refactoring existing discussion). Obsidian's popular **Templater** (4.6M) / **QuickAdd** (1.9M) plugins show templated creation is a top real-world need -(`research/260614-obsidian-deep-dive/findings.md` §7). +(`research/260614-obsidian-deep-dive/findings.md` §7). **Trilium** templates (`~template` +relation) inject an attribute set + structure into instances — blueprint-as-typed-template +(`research/260614-trilium-deep-dive/findings.md` §3, links UC-67). **Priority:** Later ### UC-16 — Append or comment without full edit @@ -970,7 +1017,10 @@ inspiration only for federation design (not inherited as API). ZigZag deep dive: the namespace hierarchy as **one dimension among many** (encoded left-child/right-sibling as two zz-dimensions), not the privileged structure — consistent with mechanism over policy; navigate it as one axis via UC-47 (`research/260614-zigzag-deep-dive/findings.md` -§4, §7.1). +§4, §7.1). **Trilium** pushes further: its hierarchy is a **DAG** — a note can sit in +multiple locations (cloning), with **identity (note) separated from placement (branch)** — +so there is no single canonical path (UC-66, +`research/260614-trilium-deep-dive/findings.md` §2). **Priority:** Later ### UC-23 — Soft topic creation via red link @@ -1064,6 +1114,8 @@ CamelCase and `[[free links]]`. Markdown-first link semantics TBD. | UC-63 | | | | ※ | ✓ | | UC-64 | | | | ⌘ | ✓ | | UC-65 | | | | ⌘ | ✓ | +| UC-66 | | | | ⊕ | ✓ | +| UC-67 | | | | ⊕ | ✓ | | UC-08 | ✓ | | | | UC-09 | ✓ | | | | UC-10 | ✓ | | | @@ -1408,6 +1460,37 @@ spectrum: `none / git / native-CRDT`), a **CRDT-replica** substrate + **P2P/no-c endpoint** attach mode, an **endpoint-model** capability, and MCP as an integration surface. +### trilium mapping + +(⊕ UC-66–UC-67 are placed in the **wikiengines** matrix column as the nearest existing +source — Trilium is a shipped tool — but their true lineage is the **Trilium deep dive**, +`research/260614-trilium-deep-dive/findings.md`.) + +| Trilium mechanism (findings §) | Catalog UC | +|--------------------------------|------------| +| Note cloning → DAG hierarchy; note (identity) vs branch (placement) (§2) | UC-66 (new) | +| Attributes inherited + templated → effective vs own metadata (§3) | UC-67 (new) | +| DAG / multi-parent vs tree; identity ≠ placement (§2) | UC-22 (enriched) | +| Labels (`#tag`) + typed relations (`~relation`), computed (§3) | UC-34 (enriched) | +| Templates (`~template`) inject attribute sets (§3) | UC-15 (enriched) | +| HTML-native (CKEditor) → HTML↔Markdown lossy translation (§4) | UC-42 (enriched; links UC-59) | +| Per-note encryption (protected notes) = per-item opacity (§6) | UC-61 (enriched) | +| Scripting (code notes) in-app host + ETAPI external REST (§5) | UC-38 (enriched; links UC-57) | +| Render/script notes + attribute queries = dynamic content (§4–§5) | links UC-54 | +| Typed relations = knowledge graph (§3) | links UC-58 | +| `noteId`/`branchId` 12-char IDs (§1) | links UC-51 | + +Note: Trilium (active fork **TriliumNext**) is a SQLite-local PKB whose standout is **note +cloning** — a **DAG hierarchy** with **note identity separated from placement** (note vs +branch), the namespace-level form of the clone/reference primitive and the clean model for +a page in multiple locations/shards. It also makes **metadata computed** (own + inherited + +templated, UC-67) and refines **content opacity to be per-item** (per-note encryption, +UC-61). HTML-native (lossy to Markdown), dual extension surface (scripting + ETAPI). +**Boundary recorded:** one SQLite-local candidate shard, best attached via ETAPI; not a +substrate and not the federation layer. Architecture logged for `SHARD-WP-0002` +(T11/T12/T14/T15/T16): DAG namespace + identity/placement split, computed/inherited +metadata, per-item content opacity, HTML source model, scripting + ETAPI host surfaces. + --- ## Open questions @@ -1452,4 +1535,9 @@ surface. 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 + opaque replica? (UC-61.) +20. For a **DAG/cloned page** (UC-66), is it one page with multiple path placements, or a + page transcluded into multiple locations? Does shard-wiki adopt Trilium's identity ≠ + placement (note/branch) split as its own page model? (Trilium dive §11.) +21. Are **inherited/templated attributes** (UC-67) materialized (snapshot) or computed + live from the shard's tree/templates, and how is per-attribute provenance recorded? \ No newline at end of file