research: Wiki.js deep dive (storage-module engine, DB<->Git Markdown, GraphQL); UC-68/69

The closest existing engine to shard-wiki's own design: DB-canonical
(Postgres/MySQL/SQLite) but with a pluggable storage-module abstraction
that bidirectionally syncs clean Markdown (+ YAML frontmatter) to Git
(also FS/S3/Azure), each provider acting as backup or source of truth.
Two big findings: (1) the storage-module interface is concrete
adapter-contract prior art alongside Foswiki::Store, and the closer one
(medium = Markdown in Git); (2) the engine-maintained bidirectional Git
mirror is the ideal file-store attach (clean MD + git history) and, being
bidirectional, makes git commit a write path (overlay/patch as a commit,
no API). Also GraphQL API (introspection = capability discovery;
selective fields = efficient projection) and authn-delegated auth modules
+ path-based rule ACL. Added UC-68 (engine-maintained bidirectional Git
mirror, write-by-commit), UC-69 (typed/introspectable API for schema
discovery + selective projection); enriched UC-06/36/38/40/42/57. Catalog
now 69 UCs. Architecture for SHARD-WP-0002 T11/T14: storage-module
abstraction as 2nd adapter-contract prior art, engine-maintained Git
mirror as attach+write surface, GraphQL introspection for capability
discovery.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-14 17:50:27 +02:00
parent 714eaf6b5a
commit 4543f5dc43
5 changed files with 402 additions and 12 deletions

View File

@@ -10,8 +10,8 @@ Promoted from `research/260608-c2-wiki-origins/`,
`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/`,
`research/260614-localfirst-workspaces-deep-dive/`, and
`research/260614-trilium-deep-dive/`.
`research/260614-localfirst-workspaces-deep-dive/`,
`research/260614-trilium-deep-dive/`, and `research/260614-wikijs-deep-dive/`.
See InfoTechPrimers on coulomb.social for use-case catalog conventions.
## Conventions
@@ -94,7 +94,10 @@ external provider.
shard-wiki delegates authentication, owns authorization
(`spec/ArchitectureBlueprint.md`). yawex's model traces to **TWiki's per-topic
`ALLOW/DENY TOPICVIEW/CHANGE/RENAME`** — the origin reference for shard-wiki's
optional per-page ACL at L4 (`research/260613-twiki-deep-dive/findings.md` §4).
optional per-page ACL at L4 (`research/260613-twiki-deep-dive/findings.md` §4). **Wiki.js**
is the modern form: **path-based rule ACL** (allow/deny by path pattern per group) +
delegated auth modules (`research/260614-wikijs-deep-dive/findings.md` §4) — a projection
should **honor/surface restricted regions**, not silently drop or expose them.
**Priority:** Later
### UC-07 — Detect and reconcile cross-shard divergence
@@ -289,7 +292,10 @@ case like Confluence/MediaWiki, not an import case. **Joplin** keeps internal no
revisions locally, likewise not portable (`research/260614-joplin-deep-dive/findings.md`
§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).
(`research/260614-localfirst-workspaces-deep-dive/findings.md` §4). **Wiki.js** is the
*adopt* case via mirror: its Git storage module commits every change to a repo, so the
engine's history **is** git even though its canonical store is a DB (UC-68,
`research/260614-wikijs-deep-dive/findings.md` §2).
**Priority:** Later
### UC-37 — Attach a static engine export as a read-only backup shard
@@ -332,7 +338,11 @@ sub-mode between in-engine host and external API (UC-57,
`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).
(`research/260614-trilium-deep-dive/findings.md` §5). **Wiki.js** generalizes the host
surface into a **pluggable module system** (storage/auth/search/render/editor); its
**storage-module** interface is — with `Foswiki::Store` — concrete **adapter-contract
prior art** (versioned, multi-provider Git/FS/S3/Azure, backup-or-source-of-truth)
(`research/260614-wikijs-deep-dive/findings.md` §2, §8).
**Priority:** Later
### UC-39 — Attach a wiki-as-application-platform shard (pages as typed records)
@@ -375,7 +385,10 @@ Markdown-first and git-friendly — and uniquely **dual-attachable**: file-store
`research/260614-obsidian-deep-dive/findings.md` §4, §10). Counter-example: **Joplin**'s
native store is a **DB** (SQLite), so its file-attach surface is the *sync/interchange
mirror* on a WebDAV/S3 target, not the native store — see UC-60
(`research/260614-joplin-deep-dive/findings.md` §2).
(`research/260614-joplin-deep-dive/findings.md` §2). **Wiki.js** is the clean middle: also
DB-canonical, but its Git storage module maintains a repo of **plain Markdown** that is the
ideal engine-maintained file-store attach — see UC-68
(`research/260614-wikijs-deep-dive/findings.md` §2).
**Priority:** Later
### UC-41 — Import an engine's native file history into the coordination journal
@@ -408,7 +421,10 @@ syntax to be safe (findings §9 Q2)? Without this, non-Markdown shards degrade t
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).
(`research/260614-trilium-deep-dive/findings.md` §4, links UC-59). **Wiki.js** is
multi-format (**Markdown primary**, plus HTML and AsciiDoc) with pluggable editors — mostly
native, light translation for the non-MD pages (`research/260614-wikijs-deep-dive/findings.md`
§1).
**Priority:** Later
### UC-43 — Tolerate a shard's storage-backend swap without losing identity
@@ -673,7 +689,9 @@ overlay/backup; write-through possible but bounded. Links the authz-in-core deci
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).
§9) — see also UC-65 (P2P, no single endpoint). **Wiki.js** uses **GraphQL** (typed,
introspectable, selective-field) rather than REST — schema discovery + reduced over-fetch,
see UC-69 (`research/260614-wikijs-deep-dive/findings.md` §3).
**Priority:** Later
### UC-58 — Attach a typed database with schema, relations, and views
@@ -856,6 +874,40 @@ effective values (snapshot) vs compute live from the shard's tree/templates (fin
Q2). Templates also reinforce UC-15 (blueprints).
**Priority:** Later
### UC-68 — Attach an engine-maintained bidirectional Git mirror of clean Markdown
**Actor:** Maintainer
**Goal:** Attach a DB-canonical engine that bidirectionally syncs its content to a Git
repo of **clean Markdown + YAML frontmatter** (Wiki.js Git storage module): use the repo
as a file-store shard (with git history) and optionally **write-through by committing
Markdown the engine ingests** — coordinating which side is source of truth, without
double-syncing.
**Source:** wikijs, intent
**Notes:** Wiki.js commits every page change to git as clean `.md`
(`injectMetadata()` prepends YAML frontmatter), bidirectionally with the remote repo
(`research/260614-wikijs-deep-dive/findings.md` §2). Cleaner than Joplin's proprietary
interchange mirror (UC-60) — it is **plain Markdown** — and richer than a read-only native
store (UC-40): the bidirectional ingest makes **git commit a write path** (overlay/patch
as a commit, no API). Caution: the **engine owns the DB↔git sync** — don't double-sync;
coordinate source-of-truth (configurable). Gives **git history natively** (UC-36, adopt
via mirror). Open: mirror-vs-DB source of truth; write-by-commit races (findings §9 Q1).
**Priority:** Later
### UC-69 — Attach via a typed, introspectable API (schema discovery + selective projection)
**Actor:** Orchestrator / adapter
**Goal:** Attach a shard through a typed, introspectable API (Wiki.js GraphQL) — using
**schema introspection** for capability/shape discovery and **selective-field queries** to
fetch only what a projection needs.
**Source:** wikijs, intent
**Notes:** Wiki.js exposes a **GraphQL** API over all resources
(`research/260614-wikijs-deep-dive/findings.md` §3). Two advantages over a REST
external-API (UC-57): **introspection** = self-describing schema → feeds capability
discovery (T11); **selective fields** = fetch body vs metadata vs tags as needed →
reduces over-fetch (projection efficiency, operational envelope). An external-API
sub-mode beside Notion's REST.
**Priority:** Later
---
## B. Knowledge work and collaboration
@@ -1116,6 +1168,8 @@ CamelCase and `[[free links]]`. Markdown-first link semantics TBD.
| UC-65 | | | | ⌘ | ✓ |
| UC-66 | | | | ⊕ | ✓ |
| UC-67 | | | | ⊕ | ✓ |
| UC-68 | | | | ⚓ | ✓ |
| UC-69 | | | | ⚓ | ✓ |
| UC-08 | ✓ | | |
| UC-09 | ✓ | | |
| UC-10 | ✓ | | |
@@ -1491,6 +1545,39 @@ 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.
### wikijs mapping
(⚓ UC-68UC-69 are placed in the **wikiengines** matrix column as the nearest existing
source — Wiki.js is a shipped engine — but their true lineage is the **Wiki.js deep dive**,
`research/260614-wikijs-deep-dive/findings.md`.)
| Wiki.js mechanism (findings §) | Catalog UC |
|--------------------------------|------------|
| Bidirectional Git storage module → clean Markdown + YAML frontmatter in a repo (§2) | UC-68 (new) |
| GraphQL API: introspectable schema + selective-field projection (§3) | UC-69 (new) |
| Pluggable **storage modules** (Git/FS/S3/Azure) = adapter-contract prior art; modular auth/search/render/editor (§2, §8) | UC-38 (enriched) |
| Git storage = clean Markdown in git — ideal engine-maintained file-store attach (§2) | UC-40 (enriched) |
| Git history natively via the storage module (adopt via mirror) (§2) | UC-36 (enriched) |
| GraphQL external-API variant (typed/introspectable/selective) (§3) | UC-57 (enriched) |
| Multi-format: Markdown primary; HTML/AsciiDoc (§1) | UC-42 (enriched) |
| Path-based rule ACL; delegated auth modules (§4) | UC-06 (enriched; links authz decision) |
| Engine-maintained clean git shard (§2, §5) | links UC-02 |
Note: Wiki.js is the **most shard-wiki-shaped engine** studied — DB-canonical but with a
**pluggable storage-module abstraction** that bidirectionally syncs **clean Markdown to
Git** (also FS/S3/Azure), each provider acting as **backup or source of truth**. That
interface is, with **Foswiki::Store**, concrete **prior art for the adapter contract**
(and the closer one — its medium is Markdown in Git). Its Git mirror is the **ideal
engine-maintained file-store attach** (clean MD + frontmatter + git history) and, being
**bidirectional**, makes **git commit a write path** (UC-68). It also uses **GraphQL**
(introspection → capability discovery; selective fields → efficient projection, UC-69) and
ships **authn-delegated auth modules + path-based rule ACL**. **Boundary recorded:** one
server-engine candidate shard; the Git mirror is the preferred attach surface but the
engine owns the DB↔git sync (don't double-sync); honor its access rules; not the federation
layer. Architecture logged for `SHARD-WP-0002` (T11/T14): storage-module abstraction as a
second adapter-contract prior art, engine-maintained Git mirror as attach+write surface,
GraphQL introspection for capability discovery + selective projection.
---
## Open questions
@@ -1540,4 +1627,8 @@ metadata, per-item content opacity, HTML source model, scripting + ETAPI host su
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?
live from the shard's tree/templates, and how is per-attribute provenance recorded?
22. For an **engine-maintained Git mirror** (UC-68), is the mirror or the engine DB the
source of truth, and how do we write-by-commit without racing the engine's own sync?
23. How does shard-wiki **honor/surface a shard's path-based access rules** (UC-06) in a
projection without re-implementing its ACL engine? (Wiki.js dive §9.)