Files
tegwick dbc42f05db research: git-forge wikis deep dive (Gitea/GitLab/GitHub); UC-76-77
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>
2026-06-14 19:40:46 +02:00

11 KiB
Raw Permalink Blame History

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.git repo 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

  1. 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.
  2. Forge wiki API as an optional capability (GitLab/Gitea), with git-only fallback (GitHub) — capability-aware binding (UC-77).
  3. 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.git clone 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

  1. 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?
  2. 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.)
  3. 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.git clone (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-76UC-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.