SHARD-WP-0003 T5. The home case: a forge wiki is a separate .wiki.git repo of Markdown -> page model, history, coordination journal map 1:1 with near-zero adapter. git-clone universal across all three; wiki content API capability-varying (GitLab/Gitea yes, GitHub git-only). git IS the canonical store (not a mirror), so write-by-commit is safe -- resolves the UC-68/Q22 race for this case. UC-76 (clone .wiki.git attach), UC-77 (forge wiki API, capability varies). Enriched UC-40/02/68/38. Marks T5 done. Feeds SHARD-WP-0002 T14/T11. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
11 KiB
git-forge wikis (Gitea · GitLab · GitHub) — deep dive (findings)
Date: 2026-06-14 · Source: SHARD-WP-0003 T5 · Subject: the Markdown wikis hosted by the three major git forges — Gitea, GitLab, GitHub — treated as one family because they share one architecture: a wiki is a separate git repo of Markdown.
Why this dive
INTENT names Gitea wikis as a shard participant, and the whole project is "a Git-based Markdown wiki orchestrator." The forge wikis are therefore the least exotic, highest- fit backend in the entire study: the page store is literally a git repository of Markdown files. After fourteen dives into DBs, CRDTs, graphs and SaaS, this one confirms the home case — and sharpens it by contrasting git-IS-the-store (forge wikis) against git-is-a-mirror (Wiki.js, UC-68).
1. The shared architecture — a wiki is a .wiki.git repo
All three forges implement a project/repo wiki as a second, dedicated git repository
alongside the code repo, addressable as <repo>.wiki.git:
git@host:owner/project.wiki.git(GitLab),…/owner/repo.wiki.git(Gitea/GitHub).- Pages are Markdown files (
Home.md,Some-Page.md), one file per page; the page title ↔ filename (spaces ↔ hyphens by convention). Other markups are accepted (AsciiDoc, Textile, reStructuredText, Org) — GitHub/Gitea via Gollum (the Ruby git-backed wiki library), GitLab via its own renderer. - History is git history — every page edit (web or pushed) is a git commit with author/timestamp/message. The wiki's revision history is a real git log.
- Special pages by convention:
_Sidebar,_Footer,_Header(GitHub/Gitea),_sidebar(GitLab) — engine-rendered chrome stored as ordinary files. - Subdirectories / nested pages: GitLab and Gitea support directory structure; GitHub wikis are historically flat (Gollum supports paths but the GitHub UI is shallow).
The decisive property: you can git clone the wiki repo, edit files, commit, and push,
and the forge UI reflects it — and vice versa. Git is a (often the) first-class
write path. This is exactly shard-wiki's native medium with no impedance.
2. Where they differ — the API matrix
git clone/push of .wiki.git |
wiki content API | nested dirs | markups | |
|---|---|---|---|---|
| Gitea | ✅ yes | ✅ REST wiki endpoints (list/get/create/edit/delete pages) | ✅ | Markdown (+Gollum-style) |
| GitLab | ✅ yes | ✅ REST Wikis API (project & group wikis) | ✅ | Markdown/AsciiDoc/RDoc/Org |
| GitHub | ✅ yes | ❌ no wiki REST API — wiki is git-only (Gollum) | ⚠️ flat UI | Markdown + Gollum markups |
The key asymmetry: GitHub exposes wiki content only through git (the REST/GraphQL API covers issues/PRs/code but not wiki pages); GitLab and Gitea offer both a wiki API and git access. So the git-clone path is the universal one (works for all three); the API path is an optional, capability-varying alternative.
3. git-IS-the-store vs git-is-a-mirror (the UC-68 contrast)
Wiki.js (UC-68) keeps a DB as canonical and maintains a git mirror — so writing by commit risks racing the engine's DB↔git sync (catalog open-Q22). Forge wikis are the opposite: the git repo IS the canonical store; there is no separate DB of record for wiki content. Therefore:
- The source-of-truth question (Q22) is resolved for this case: the
.wiki.gitrepo is authoritative. shard-wiki can write by commit/push directly with no engine to race — the forge merely renders what git holds. - The forge API (GitLab/Gitea), where present, is a convenience over the same git repo, not a competing store — so API-write and git-write converge on one history.
This makes forge wikis the cleanest possible write-through file-store shard: clone = projection/mirror, commit = overlay-applied/write, git log = the coordination journal as is.
4. Capability profile
| Dimension (synthesis spectrum) | Gitea / GitLab / GitHub wiki |
|---|---|
| Attachment mode | file-store (native: git clone) + optional external-API (GitLab/Gitea wiki REST) |
| Addressing granularity | page = file; sub-page = path (GitLab/Gitea) |
| Content identity | path/filename within the wiki repo (title-derived) |
| Identity vs placement | placement-bound (path = identity), like a plain git repo |
| Structure | flat or directory tree of Markdown files; _Sidebar/_Footer chrome |
| History | native git history (real commits, authors, messages) |
| Merge model | git (3-way merge, branches) — though wiki repos are usually single-branch |
| Native query | none (it's files); forge full-text search over the wiki |
| Translation | Markdown-native (+ AsciiDoc/Org via renderer) — minimal/no translation needed |
| Attachment/write granularity | file (page) per commit |
| Operational envelope | ordinary git + forge; clone is cheap; API rate limits apply to API path |
| Access grant | forge repo permissions (delegated auth; per-repo/role ACL) |
| Content opacity | transparent Markdown in git |
| Provenance | git author/committer/timestamp per commit — native |
5. INTENT mapping
Reinforcements (this is the home case)
- Git-based Markdown orchestrator (INTENT core): forge wikis are git repos of Markdown. The wiki page model (Markdown-first, path-addressed, git-versioned) maps 1:1 — minimal adapter, maximal fit.
- Coordination journal = git (INTENT): the wiki repo's git log is already the coordination journal — no synthesis needed; adopt it directly.
- Overlay before mutation: overlays are branches/commits on the cloned wiki repo; applying = push (or open an MR/PR where the forge supports wiki MRs — GitLab does not for wikis, so push-to-branch + manual is the path).
- Graceful degradation: even GitHub (no wiki API) is fully usable via git-clone — the universal path means a limited forge is still a first-class read/write shard.
- No silent remote mutation: writes are explicit git pushes (or explicit API calls) under the user's forge credentials and repo permissions.
Divergences (boundaries / notes — minor)
- Capability varies by forge: GitHub = git-only (no content API); GitLab/Gitea = git + API. The adapter must model the API as an optional capability, defaulting to the universal git path (T11/T14). Not a bug — exactly the capability-awareness INTENT mandates.
- Wiki repos rarely use branches/MRs for review: forge wikis usually edit a single branch directly; the rich PR-review flow is on the code repo, not the wiki. So "overlay → review → merge" needs shard-wiki to provide the review layer, not the forge.
- Identity = path (like any git repo) — cross-shard identity (T16) is layered above, as
for plain git/
wiki/subdir shards.
What to keep
- git-clone as the universal, canonical file-store attach for forge wikis — Markdown + git history directly as page model + coordination journal (UC-76). The reference easy-case backend.
- Forge wiki API as an optional capability (GitLab/Gitea), with git-only fallback (GitHub) — capability-aware binding (UC-77).
- git-IS-store ⇒ write-by-commit is safe (no engine race) — record this as the resolution of the Wiki.js mirror dilemma (Q22) for forge wikis.
6. UC seeds
| # | Seed | Disposition |
|---|---|---|
| UC-76 | Attach a git-forge wiki by cloning its dedicated .wiki.git — git is the native store; Markdown files = pages, git log = coordination journal; commit/push = write (no engine to race) |
new |
| UC-77 | Attach/write a forge wiki via the forge's wiki API (GitLab/Gitea REST) where git-clone is unavailable or API-write is preferred; git-only fallback for GitHub — capability varies by forge | new |
| — | git-native file-store as the canonical store (not mirror) | enrich UC-40 |
| — | dual-path attach (git clone vs forge API) | enrich UC-02 |
| — | git-IS-store vs engine-maintained mirror (resolves Q22) | enrich UC-68 |
| — | forge as an API host for the wiki resource | enrich UC-38 |
7. Architecture notes for SHARD-WP-0002
- T14 (adapter binding / attach path): forge wikis are the canonical file-store
attach — bind to the
.wiki.gitclone as the universal path; model the wiki API as an optional, forge-specific capability (present: GitLab, Gitea; absent: GitHub). One shard, two possible bindings converging on the same git history. - T11 (capability model): "has-content-API" is a per-forge capability flag; git clone/push is the baseline every forge satisfies. Minimal adapter profile — near the Oddmuse-simple end but Markdown-native and git-versioned.
- Coordination journal: adopt the wiki repo's git log directly — the one backend where INTENT's git-backed journal needs zero synthesis.
- Resolves Q22 (UC-68): because git is the store (not a mirror), write-by-commit is safe — no engine DB↔git sync to race. Record the distinction engine-mirror (Wiki.js: DB canonical, careful) vs git-canonical (forge wikis: commit freely).
8. Open questions
- For overlay → review → apply, does shard-wiki supply the review layer over a forge wiki (which lacks wiki-MRs), e.g. via a branch + its own diff/approve, or push directly?
- When a forge offers both git and a wiki API (GitLab/Gitea), which does the adapter prefer by default — git (universal, full history) with API as a fallback for hosts where clone is disabled? (cf. UC-43 backend-swap under stable binding.)
- Should the code-repo
wiki/subdir shard and the forge wiki repo shard share one adapter (both git+Markdown) with a "which repo / which path" parameter, or stay distinct?
9. Sources
- GitLab Docs — Wiki (separate git repo; web/git/API;
.wiki.git) — docs.gitlab.com - Gitea — wiki via git clone + repository wiki API; forum/issue threads on
.wiki.gitclone (go-gitea/gitea #1426, #15420) — gitea.com / github.com/go-gitea - GitHub — wiki = Gollum git repo (
<repo>.wiki.git), no wiki REST API — docs.github.com - Gollum (git-based wiki library) — github.com/gollum/gollum
- prior:
research/260614-wikijs-deep-dive/(engine-maintained mirror contrast, UC-68)
10. Traceability
New UCs UC-76–UC-77 carry the marker ⎇ in the wikiengines column of
spec/UseCaseCatalog.md. Enriched: UC-40, UC-02, UC-68, UC-38. Architecture cross-refs:
SHARD-WP-0002 T14, T11; coordination-journal-from-git; resolves catalog open-Q22.