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>
15 KiB
Findings — Wiki.js: the storage-module engine that already speaks Git + Markdown
Date: 2026-06-14 Source kind: modern shipped product — a server wiki engine; a candidate shard and the closest existing engine to shard-wiki's own design (DB-canonical, but with a pluggable storage-module abstraction that bidirectionally syncs clean Markdown to Git/FS/S3/Azure) Lens: shard-wiki — storage-module-as-adapter-contract prior art, the engine-maintained Git mirror as an attach + write surface, GraphQL as a typed/introspectable API, and path-based access rules
Why Wiki.js is special in this set. Every prior engine/tool stored content in one substrate and exposed one or two surfaces. Wiki.js is DB-canonical (Postgres/MySQL/ SQLite) but abstracts persistence behind pluggable "storage modules" — Git, local filesystem, S3, Azure Blob — each of which can act as backup or source of truth, and the Git module bidirectionally syncs clean
.mdfiles (with YAML frontmatter) to a repo. In other words, Wiki.js already does, internally, much of what shard-wiki's adapter contract is meant to do: a versioned, capability-bearing, multi-provider persistence interface over Markdown. It is the second concrete prior art for the contract after Foswiki::Store — and arguably the closer one, because its content is Markdown in Git, exactly shard-wiki's native shape.
Contrast set: the engine dives (XWiki DB/components, TWiki/Foswiki file+RCS) and the modern tools. Wiki.js = modern server engine, DB-canonical, Git-storage-of-Markdown, GraphQL API, pluggable modules.
1. Core architecture
- Stack: Node.js backend, Vue front end; everything is accessible via a GraphQL
API (
/graphql, with a Playground). The DB is Postgres (primary; MySQL/SQLite supported), read-replica-capable. - Content: Markdown (primary), plus HTML and AsciiDoc, via pluggable editors (Markdown, WYSIWYG/visual, raw HTML). Pages live on paths (a path-based hierarchy) with tags.
- Modular architecture: typed pluggable modules — storage, auth, search, rendering, editor. The contract-relevant ones are storage (§2) and auth (§4).
- 3.0: a large rewrite is in development; storage remains a headline subsystem.
2. Storage modules — the headline (≈ shard-wiki's adapter contract)
A storage module "connects Wiki.js with a local or remote storage provider, to act as backup or source of truth for content. It consists of properties (user-set) and methods called on events — create, update, delete content, and sync." Providers include Git, local filesystem, S3, Azure Blob.
The Git module is the most-used: every page change commits to a Git repository,
turning the wiki into version-controlled .md files. Content is written as clean
Markdown, and injectMetadata() prepends YAML frontmatter (for Markdown) or HTML
comments (for HTML) carrying page metadata. The sync is bidirectional with the remote
repo, and access to the synced files honors Wiki.js access rules (§4).
Why this matters to shard-wiki — three distinct payoffs:
- Prior art for the adapter contract. Wiki.js's storage-module interface is a
shipped instance of what
SHARD-WP-0002T11 specifies: a versioned, capability- bearing, multi-provider persistence abstraction, with a backup-vs-source-of-truth choice and lifecycle methods (create/update/delete/sync). It joins Foswiki::Store as concrete prior art — and is closer, because its medium is Markdown in Git. - The ideal file-store attach. A Wiki.js instance with the Git module is a git repo of clean Markdown + YAML frontmatter, maintained by the engine. shard-wiki can attach that repo directly (UC-40) — better than reading the DB — and get git history for free (UC-36, adopt not supplement, via the mirror).
- A write path via Git, no API needed. Because the Git sync is bidirectional, shard-wiki can write-through by committing Markdown to the repo; Wiki.js ingests git→DB. This is overlay/patch application as a git commit, not an API call (UC-68). Caution: Wiki.js owns the DB↔git sync — don't double-sync, and coordinate which side is source of truth (configurable).
3. GraphQL — a typed, introspectable external API
Unlike the REST/local-REST tools (Joplin, Trilium, Notion), Wiki.js exposes a GraphQL API over all resources. Two shard-wiki-relevant properties:
- Introspection = capability/schema discovery. A GraphQL schema is self-describing; an adapter can introspect the content/page schema rather than hard-coding it — feeding T11's capability discovery.
- Selective-field projection. GraphQL fetches exactly the fields a projection needs (page body vs. metadata vs. tags), reducing over-fetch — relevant to projection efficiency and the operational envelope. (UC-69; an external-API sub-mode beside Notion's REST, UC-57.)
4. Auth modules + path-based access rules
- Auth modules (local, LDAP, OAuth, SAML, …) — authentication is delegated to pluggable providers, exactly shard-wiki's authn-delegated stance (shard-wiki-auth-in-core-decision).
- Access rules are path-based / rule-based ACL: allow/deny access to all or specific sections of the wiki per group; the Git-synced files honor the same rules. For shard-wiki this is a richer ACL than TWiki's per-topic flags (UC-06) — rule-based by path pattern — and informs how a projection should honor/surface a shard's restricted regions (union without erasure: show that a region is restricted, don't silently drop or expose it).
5. Wiki.js as a shard — capability profile
| Capability | Wiki.js | Notes for the adapter contract |
|---|---|---|
| Read | yes (Git mirror / GraphQL / DB) | Git mirror = clean Markdown is the best surface |
| Write | yes (GraphQL or git commit) | bidirectional Git ingest = write-by-commit (UC-68) |
| Write granularity | per-page | — |
| Identity / addressing | path (+ page id) | path-based; YAML frontmatter carries metadata/id |
| Structure | YAML frontmatter (in-file via Git module) | git-diffable in-text structure (good) |
| History | git-native via Git module (else DB versions) | adopt the mirror's git history (UC-36) |
| Native query | GraphQL; pluggable search (DB/Elastic/Algolia) | delegate search; GraphQL selective fetch (UC-69) |
| Translation | Markdown primary; HTML/AsciiDoc too | mostly native; multi-format = light translation (UC-42) |
| Attach modes | file-store (engine-maintained Git mirror) / external-API (GraphQL) | clean MD in git is the ideal file-store (UC-40, UC-68) |
| Access control | path-based rule ACL; delegated auth modules | authn-delegated; honor restricted regions (UC-06) |
| Storage abstraction | pluggable storage modules (Git/FS/S3/Azure) | adapter-contract prior art (T11) |
| Content types | pages + media/assets | assets via storage modules |
Verdict: the most shard-wiki-shaped engine yet. Best attached via its Git storage mirror (clean Markdown + frontmatter + git history, with write-by-commit), or via GraphQL for live/selective access. Its standout gift is architectural: a shipped storage-module abstraction that is near-isomorphic to shard-wiki's adapter contract.
6. Mapping to shard-wiki INTENT (compare, do not equate)
6.1 Reinforcements
- Storage modules = the adapter contract, shipped. A versioned, capability-bearing, multi-provider persistence interface with backup-vs-source-of-truth — exactly T11's shape, in production (with Foswiki::Store as the other prior art).
- Markdown-in-Git is the native shape. Wiki.js validates that a serious engine can
keep content as clean
.md+ frontmatter in git — shard-wiki's preferred medium — while still offering a rich app over a DB. - authn-delegated (auth modules) and git coordination (Git storage) are both core shard-wiki stances, here shipped.
6.2 Deliberate divergences (design bugs if conflated)
- DB is Wiki.js's canonical store; the Git repo is a maintained mirror. Treat the mirror as the attach surface, but respect that Wiki.js runs the DB↔git sync — don't double-sync; coordinate source-of-truth (UC-68).
- Bidirectional write needs care. Committing Markdown is a real write path, but races with the engine's own sync; apply overlays as commits the engine can ingest cleanly, never out-of-band DB edits (overlay before mutation, no silent mutation).
- One Wiki.js instance = one shard, not the federation layer; its access rules are the shard's, to be honored/surfaced, not re-implemented.
- HTML/AsciiDoc pages need light translation; Markdown pages are native.
6.3 What Wiki.js teaches that shard-wiki should keep
- Model the contract on a real storage-module interface (Wiki.js + Foswiki::Store): properties + lifecycle methods (create/update/delete/sync) + a backup-vs-source-of- truth flag + a provider list. (T11.)
- Prefer the engine-maintained Git mirror as the attach surface for DB-canonical engines that offer one — clean Markdown, git history, and write-by-commit (UC-68).
- Use GraphQL introspection for capability discovery and selective projection where a shard offers it (UC-69).
7. Use-case seeds → catalog (promoted 2026-06-14)
Last existing UC is UC-67. New UCs UC-68, UC-69 added; existing UCs enriched.
| Seed | Catalog action |
|---|---|
| Attach an engine-maintained bidirectional Git mirror of clean Markdown (Wiki.js Git storage module): attach the repo as a file-store shard (clean MD + YAML frontmatter + git history) and optionally write-through by committing Markdown the engine ingests; coordinate source-of-truth, don't double-sync | UC-68 (new) |
| Attach via a typed, introspectable API (GraphQL): discover the shard's schema by introspection (capability discovery) and fetch only the fields a projection needs (selective projection) | UC-69 (new) |
| Pluggable storage modules (Git/FS/S3/Azure) = adapter-contract prior art; modular auth/search/render/editor | enriches UC-38 |
| Git storage = clean Markdown in git, the ideal engine-maintained file-store attach | enriches UC-40 |
| Git history natively via the storage module (adopt via mirror) | enriches UC-36 |
| GraphQL external-API variant (typed/introspectable/selective) | enriches UC-57 |
| Multi-format (Markdown primary; HTML/AsciiDoc) | enriches UC-42 |
| Path-based rule ACL; delegated auth modules | enriches UC-06 (links authz decision) |
| Engine-maintained clean git shard | links UC-02 |
8. Architecture notes for SHARD-WP-0002 (no UC)
- Second adapter-contract prior art (T11). Wiki.js's storage-module interface (properties + create/update/delete/sync methods + backup-vs-source-of-truth + multi- provider Git/FS/S3/Azure) is, with Foswiki::Store, the model to base the contract on — and the closer one (medium = Markdown in Git). Cite both in T11.
- Engine-maintained Git mirror (T14). Add to the attachment taxonomy: for a DB-canonical engine that offers a bidirectional Git-of-Markdown mirror, the mirror is the preferred attach + write surface (clean MD, git history, write-by-commit). A cleaner sibling of Joplin's proprietary interchange mirror (UC-60) and the file-store native-store kind (UC-40).
- GraphQL → capability discovery + selective projection (T11/T14). Typed/ introspectable APIs give schema discovery (capability negotiation) and reduce over-fetch — note alongside Notion's REST external-API mode.
- authn-delegated + path-based ACL reinforce the settled authz decision and inform how projections honor/surface restricted regions (union without erasure).
9. Open questions (for spec / workplans)
- For an engine with a bidirectional Git mirror (UC-68), is the mirror or the DB the source of truth from shard-wiki's view, and how do we avoid races with the engine's own sync (write-by-commit cadence, locking)?
- When both a Git mirror and GraphQL are available, which does a binding prefer — mirror for content/history, GraphQL for live/selective metadata? Can one binding use both?
- How does shard-wiki honor/surface path-based access rules (UC-06) in a projection without re-implementing the shard's ACL engine?
- Should the adapter contract's storage-module shape be standardized directly on Wiki.js + Foswiki::Store, or generalized further?
10. Sources
| Source | Used for |
|---|---|
| Wiki.js — GraphQL API docs (https://docs.requarks.io/dev/api) | Everything via GraphQL; /graphql Playground; access/modify all resources |
| Wiki.js — Git storage (https://docs.requarks.io/storage/git) | Per-change commit to git; clean .md; bidirectional sync with remote repo |
| Wiki.js — Storage overview + dev/storage.md (https://docs.requarks.io/storage ; https://github.com/requarks/wiki-docs/blob/master/dev/storage.md) | Storage module = provider connector; backup-or-source-of-truth; properties + create/update/delete/sync methods; injectMetadata() YAML frontmatter; providers Git/FS/S3/Azure |
| Wiki.js 3.0 storage preview (https://beta.js.wiki/blog/2021-wiki-js-3-feature-preview-storage) | Storage subsystem direction (3.0) |
| Wikipedia — Wiki.js (https://en.wikipedia.org/wiki/Wiki.js) | Node.js/Vue, DB options, formats, modular architecture |
| BrightCoding / Grokipedia overviews | Auth providers, access rules, editors, read replicas |
Cross-references: research/260613-foswiki-deep-dive/findings.md (Foswiki::Store, the
other storage-interface prior art), research/260614-joplin-deep-dive/findings.md
(interchange/sync-mirror contrast), research/260614-notion-deep-dive/findings.md
(external-API/REST contrast), research/260614-shard-spectrum-synthesis/findings.md
(attachment-mode spectrum), spec/UseCaseCatalog.md (UC-02, UC-06, UC-36, UC-38, UC-40,
UC-42, UC-57), workplans/SHARD-WP-0002-federation-architecture.md (T11, T14).
11. Traceability
- New UCs: UC-68, UC-69 →
spec/UseCaseCatalog.md. - Enriched UCs: UC-06, UC-36, UC-38, UC-40, UC-42, UC-57 (links UC-02, authz decision).
- Architecture (no UC): storage-module abstraction = 2nd adapter-contract prior art
(with Foswiki::Store); engine-maintained Git mirror as attach+write surface; GraphQL
introspection → capability discovery + selective projection; path-based ACL + authn-
delegated →
SHARD-WP-0002(T11, T14). - Boundary recorded: Wiki.js is one server-engine candidate shard, DB-canonical with a bidirectional Git-of-Markdown mirror that is the preferred attach surface; not a substrate and not the federation layer (don't double-sync; honor its access rules).