Accept page-centric markdown SoR with dual authoring, live includes, and lazy projections; accept thin dir+git plane with PageOps and supported upgrades to shard-wiki and kontextual. Demote ADR-0002 Forgejo-as-SoR.
189 lines
6.6 KiB
Markdown
189 lines
6.6 KiB
Markdown
---
|
||
id: ADR-0004
|
||
title: Thin git content plane, PageOps, and supported upgrades
|
||
status: accepted
|
||
date: 2026-08-13
|
||
deciders: bernd
|
||
related:
|
||
- ADR-0001
|
||
- ADR-0002
|
||
- ADR-0003
|
||
- docs/architecture/ArchitectureBlueprint.md
|
||
workplans:
|
||
- CSOC-WP-0004
|
||
- CSOC-WP-0006
|
||
---
|
||
|
||
# ADR-0004 — Thin git content plane, PageOps, and supported upgrades
|
||
|
||
## Status
|
||
|
||
**Accepted** (2026-08-13).
|
||
|
||
Pairs with **ADR-0003** (what a page is and how authors work). This ADR decides
|
||
**where content lives**, how the app talks to it, and how the plane may grow.
|
||
|
||
## Context
|
||
|
||
Content needs a store that:
|
||
|
||
- keeps **user data as files** in **git**,
|
||
- starts **simple** for stage-1 transfer,
|
||
- can later gain wiki federation or ECM-class power **without rewriting** the
|
||
product UI or stranding exports.
|
||
|
||
Candidates considered:
|
||
|
||
| Option | Role |
|
||
|--------|------|
|
||
| **A** Thin directory + markdown + git | Start here |
|
||
| **B** shard-wiki | Wiki orchestration / multi-shard later |
|
||
| **C** kontextual-engine | Scale, rich media, governed assets later |
|
||
|
||
Also: shared **asset-store** extraction, and who owns content-plane PolicyGateway.
|
||
|
||
## Decision
|
||
|
||
### 1. Default content plane (stage-1 and near term)
|
||
|
||
**Start thin (A):**
|
||
|
||
- A **directory tree** of markdown pages and assets.
|
||
- Tree is **secured in git** (commits via product, operator, or linked remote).
|
||
- Illustrative layout:
|
||
|
||
```text
|
||
spaces/<space-slug>/
|
||
pages/<page-slug>.md
|
||
assets/…
|
||
```
|
||
|
||
Exact layout may evolve; the invariant is **files + git**, not “opaque DB rows
|
||
for prose.”
|
||
|
||
**Forgejo / remote git** (including ADR-0002-style bindings) may host or mirror
|
||
the tree; they are **transports/remotes**, not a second product ontology.
|
||
|
||
### 2. PageOps boundary
|
||
|
||
All product code accesses content through a **narrow PageOps** façade (names
|
||
illustrative):
|
||
|
||
| Op | Purpose |
|
||
|----|---------|
|
||
| list/get/put/archive page | CRUD |
|
||
| copy / transfer page | Stage-1 must features |
|
||
| explode / implode | Outline-editor flexibility (ADR-0003) |
|
||
| resolve_view | Live includes/derived for display |
|
||
| pin / unpin / refresh_pinned | Explicit freeze + stale workflow |
|
||
| project_field / regenerate / lock | Title/abstractor/visual lifecycle |
|
||
| put_visual / get_asset | Binaries |
|
||
|
||
**Rule:** UI and product services **must not** call shard-wiki, kontextual, or
|
||
Forgejo APIs ad hoc from templates — only PageOps. Swapping the content-plane
|
||
**adapter** upgrades the backend without rewriting cards and flows.
|
||
|
||
### 3. Supported upgrade path
|
||
|
||
```text
|
||
A thin dir + git (+ markitect-tool)
|
||
│
|
||
│ when wiki / federation / multi-shard matters
|
||
▼
|
||
B shard-wiki adapter (same markdown as shard material)
|
||
│
|
||
│ when scale / rich multi-format media / heavy governance
|
||
▼
|
||
C kontextual-engine upgrade (migration tooling; markdown remains portable)
|
||
```
|
||
|
||
| Upgrade | When | Invariant |
|
||
|---------|------|-----------|
|
||
| **→ shard-wiki** | Wiki features, multi-shard, overlays become product-relevant | Exportable markdown tree remains valid; markitect still structures docs |
|
||
| **→ kontextual** | Ambitious structure, scale, rich media, audit/lineage | Supported **upgrade of the information base**; user export of markdown+assets still required where content is document-shaped |
|
||
|
||
Upgrades are **planned migrations**, not emergency rewrites. Feasibility should
|
||
be re-checked with export/import sketches when approaching B or C.
|
||
|
||
### 4. Assets
|
||
|
||
1. **Now:** assets live **beside** markdown in the content tree (paths or simple
|
||
digests in frontmatter `visual` / refs).
|
||
2. **Later:** extract a shared **asset-store** (seed from kontextual BlobStorage
|
||
ideas) when a **second fleet consumer** needs the same API — **not** a
|
||
stage-1 gate.
|
||
3. Do **not** adopt markitect-main’s large assets package as runtime.
|
||
|
||
### 5. Authorization ownership
|
||
|
||
1. **Authn** remains NetKingdom OIDC (ADR-0001).
|
||
2. **Do not** create a long-lived coulomb-specific PolicyGateway ownership
|
||
stream. Prefer **NetKingdom consolidation** so authorization decisioning for
|
||
app resources is the obvious platform path (flex-auth / NK as one story).
|
||
3. **Until consolidation lands:** coulomb enforces coarse product authz
|
||
(authenticated session, `tenant_id`, SpaceMembership). Content plane fails
|
||
closed if a PDP is configured and denies or is required but unavailable for
|
||
sensitive ops.
|
||
4. Content-plane engines (shard-wiki, kontextual) must accept **external**
|
||
principal identity (e.g. issuer/subject + groups), not their own user
|
||
directories.
|
||
|
||
### 6. markitect-tool on every plane
|
||
|
||
Regardless of A/B/C:
|
||
|
||
- parse, validate, query, **live include**, explode/implode, and future
|
||
derived-slot tooling live in **markitect-tool**;
|
||
- the plane stores and serves files (or equivalent); markitect does not host
|
||
multi-user product sessions.
|
||
|
||
## Consequences
|
||
|
||
### Positive
|
||
|
||
- Fastest path to stage-1 with true user-owned files and git history.
|
||
- Clear upgrade story reduces fear of “too simple forever” without overbuilding.
|
||
- PageOps keeps UI stable across backend generations.
|
||
- Authz consolidation direction avoids duplicate IAM mini-platforms.
|
||
|
||
### Negative / costs
|
||
|
||
- Thin plane must still implement solid git/write, conflict, and cache-bust
|
||
behavior for a good product feel.
|
||
- Copy/transfer/explode semantics are coulomb+markitect work on the tree.
|
||
- Upgrade tooling to B/C is real future cost (accepted as supported path).
|
||
- NK authz consolidation is a **platform dependency** outside this repo’s sole
|
||
control.
|
||
|
||
### Neutral
|
||
|
||
- ADR-0002 Forgejo demo path can remain for public raw fixtures and optional
|
||
remotes.
|
||
- asset-store extraction is explicit **later** work (possible ADR-0005).
|
||
|
||
## Non-goals
|
||
|
||
- Implementing full shard-wiki or kontextual integration in stage-1.
|
||
- Bundling a wiki UI or ECM UI in coulomb (headless planes only).
|
||
- Replacing NetKingdom with app-local accounts.
|
||
- Making Postgres the content SoR.
|
||
|
||
## Implementation guidance (non-normative)
|
||
|
||
1. Define a `ContentPlane` / PageOps port in coulomb; ship **Filesystem+Git**
|
||
adapter first.
|
||
2. Index cards into Postgres on write and on git pull/webhook.
|
||
3. Wire markitect live `resolve_includes` on view/export.
|
||
4. Prototype explode/implode in product against the same tree.
|
||
5. Document export: zip/tar of tree without DB dump.
|
||
6. When approaching B/C: migration runbook + round-trip tests from a real
|
||
space tree.
|
||
|
||
## References
|
||
|
||
- `docs/architecture/ArchitectureBlueprint.md` (D1–D4)
|
||
- `docs/architecture/spike-checklist.md` (A chosen; B/C upgrade sketches)
|
||
- ADR-0003 (page model, live/pin, authoring)
|
||
- ADR-0002 (Forgejo vertical slice; demoted as exclusive SoR)
|
||
- shard-wiki INTENT (Coulomb as intended consumer)
|
||
- kontextual-engine (upgrade target; blob port for later asset-store)
|