research: Trilium (TriliumNext) deep dive (note cloning/DAG hierarchy, attribute inheritance, HTML-native); UC-66/67

SQLite-local PKB whose standout is note cloning — a single note can sit in
multiple tree locations at once via the note (identity) vs branch
(placement) split, so the hierarchy is a DAG, not a tree, with no single
canonical path. The identity-not-equal-placement model is the clean way to
represent a page in multiple locations/shards and the namespace-level form
of the clone/reference primitive. Also: attributes (labels + typed
relations) are inherited + templated, so metadata is computed (own +
inherited + template), not a flat bag; content opacity is per-item
(per-note encryption / protected notes), refining the proposed 12th
spectrum; HTML-native (CKEditor, lossy to Markdown); dual extension
surface (scripting code notes + ETAPI token REST). TriliumNext is the
active community fork of zadam's Trilium (TWiki->Foswiki pattern). Added
UC-66 (DAG hierarchy / note cloning), UC-67 (inherited/templated
attributes, effective vs own); enriched UC-15/22/34/38/42/61. Catalog now
67 UCs. Architecture 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.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-14 16:44:49 +02:00
parent 3e0c05a2b3
commit 5697669063
5 changed files with 428 additions and 12 deletions

View File

@@ -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 Q3Q4). 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-66UC-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.)
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?