spec(SHARD-WP-0002): FederationArchitecture.md — federation design (T1-T10, T17)

Decision records for the 10 federation topics + the federation-model taxonomy,
each with a Decided/Deferred/Open footer: star orchestrator positioning, remix
primitives (overlay-default), identity/placement/equivalence + chorus,
event-sourced coordination journal + per-space append authority, server-primary
incremental union, notify-driven freshness, space lifecycle, reference-not-copy
transclusion, detection-core/resolution-policy preset catalog, the federation-
ops capability matrix, and the six selectable/composable federation models.
References (not duplicates) CoreArchitectureBlueprint + FederationRequirements.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-15 02:24:11 +02:00
parent 40575045ca
commit 802a80231a

View File

@@ -0,0 +1,220 @@
# FederationArchitecture
Status: **draft for review** · Date: 2026-06-15 · Deliverable of **SHARD-WP-0002** (T1T10, T17)
The federation **design decisions** for shard-wiki: *what the union does*. It records, per
topic, a decision with rationale, tradeoffs, and a **Decided / Deferred / Open** footer. It
**references** `spec/CoreArchitectureBlueprint.md` (the whole-system architecture) and
`spec/FederationRequirements.md` (yawex-derived ADRs) rather than restating them; the adapter
contract (*what a backend must expose*) is the companion deliverable in
`spec/TechnicalSpecificationDocument.md` §A (T11T16, T18). UC references → `UseCaseCatalog.md`.
Cross-cutting invariants assumed throughout (blueprint §2): orchestrator-not-engine (I-1),
three-state canonical/derived (I-2), capability-as-data (I-3), union-without-erasure (I-4),
overlay-before-mutation (I-5), git-addressable coordination (I-6), mechanism-over-policy (I-7),
graceful degradation (I-8), identity≠placement (I-9), history-as-floor (I-10), authz-in-core
(I-11), tenant-partitioned derived state (I-13).
---
## T1 — Orchestrator positioning & boundaries
**Decision.** shard-wiki is an **adapter-layer orchestrator** in a **star** shape (many
sovereign shards ↔ one information space), **not** a homogeneous federation network. It
**compares, does not equate** (Federated Wiki homogeneous JSON sites, ikiwiki homogeneous git
wikis, ActivityPub activity streams are *models it can speak*, §T17 — not shapes it imposes).
Core owns: the union, the coordination journal, projection, overlay, resolution, authorization.
Adapters own backend specifics; UI and editorial policy live outside core. (Blueprint §1, §5;
UC-02, UC-26.)
*Decided:* star orchestrator; compare-not-equate; core/adapter/UI/policy boundaries.
*Deferred:* the reference UI (L6) is out of scope here. *Open:* none.
## T2 — Remix primitives: reference / projection / overlay / import-fork
**Decision.** Four primitives, escalating in commitment; **overlay-before-mutation is the
default write path** (I-5), fork is *one federation model* (§T17) not the default for editing:
| Primitive | Trigger | Writes remote? | Coordination-canonical? |
|-----------|---------|----------------|--------------------------|
| **Reference** | link only | no | no (a link in content) |
| **Projection** | read remote page | no (cache) | no (derived) |
| **Overlay** | edit a sub-write-through shard | not until explicit apply | **yes** (decision log) |
| **Import / fork** | copy into a writable shard / fork-with-provenance | source unchanged | **yes** (fork event) |
(Blueprint §8.2; FederationRequirements ADR-05; UC-04, UC-26, UC-29.)
*Decided:* the four primitives + overlay-default. *Deferred:* fork-attribution portability
format. *Open:* whether "import" and "fork" are one primitive with a flag or two (impl spike).
## T3 — Equivalent-page identity & multi-version presentation
**Decision.** Separate **identity** (stable handle), **placement** (N paths/shards), and
**equivalence** (content-fingerprint / span-set overlap *across* identities), per
FederationRequirements ADR-01/ADR-02 (I-9). Equivalence signals: normalized title/path, alias
table (coordination-canonical), link-graph overlap, fingerprint, **curator binding**. Default
presentation = **chorus-of-voices** (all equivalent versions, attributed); **designated-
canonical** is a policy preset (§T9). Divergence is data in the provenance envelope (I-4),
detected as core mechanism (blueprint §8.6). (UC-07, UC-27; UC-46.)
*Decided:* identity/placement/equivalence split; chorus default. *Deferred:* fingerprint
algorithm + blocking params (blueprint O-1). *Open:* curator-binding UX (L6).
## T4 — History, attribution & the coordination journal
**Decision.** Each information space has a **git-addressable, event-sourced coordination
journal** (blueprint §8.1, I-6/I-10): coordination-canonical decisions (overlay/binding/alias/
merge/fork) are append-only events; current state is a derived fold. **One append authority per
space** gives a total order (read-your-writes across instances). Per-shard native history is
**adopted** (git-native), **supplemented** (DB/CRDT internal → journal begins-now/mirrors), or
**imported** (open file history backfilled) per the history-portability axis (TSD §A T13).
Attribution is portable on the event (UC-29). (UC-29, UC-33.)
*Decided:* event-sourced journal + per-space append authority + adopt/supplement/import.
*Deferred:* per-space log sharding for extreme write rates (blueprint O-12). *Open:* none.
## T5 — Union composition layer
**Decision.** The **server-side orchestrator union is primary** — the derived tier (union
graph, indexes, projections) is composed in core for agents/CLI/non-browser consumers
(blueprint §8.4), **incrementally maintained** (not recomputed, §8.7), **tenant-partitioned**
(I-13). **Client-side composition** (Federated-Wiki-style browser pull) is a supported
*consumer pattern over the same union*, not the only path. Freshness/caching per §8.8. (UC-05,
UC-27, UC-03, UC-31.)
*Decided:* server-primary, client-optional; incremental, partitioned. *Deferred:* client
SDK shape. *Open:* persisted-union digest granularity (blueprint O-4, B-4 checker).
## T6 — Change notification & subscription transports
**Decision.** Change-notification is an **optional adapter capability** (`notify`), and it is
the **primary driver of incremental maintenance** (blueprint §8.7/§8.8). Transports, per
profile: git hook / ikiwiki-style ping, ActivityPub Create/Update, webhook, WebDAV/HTTP ETag
or `Last-Modified` poll, plain polling fallback. A notification → invalidate affected entries
+ enqueue delta refresh + a RecentChanges union entry (FederationRequirements ADR-03; UC-31,
UC-17). Rate-limited shards favour event-driven + long TTL (operational-envelope axis).
*Decided:* notify = optional capability, drives incremental + RecentChanges; transport per
profile. *Deferred:* ActivityPub as content-bearing (vs notify-only) — start notify-only.
*Open:* fediverse-dependency posture for v1.
## T7 — Information-space lifecycle
**Decision.** Root entities have lifecycle states: **active → read-only-archived → retired
(detached)**, and **merged-into-successor**. **Carry-forward** is selective import from an
archived shard (UC-28, UC-30). **Space-fork / branch** (UC-33) = branch the coordination
journal + shard-config (a fork event, §T2/§T17 fork+journal model). Retirement **preserves
read-only union entries** by default (history-as-floor, I-10), never hard-deletes projections.
(UC-28, UC-30, UC-33.)
*Decided:* the lifecycle states + carry-forward + space-branch; retire-preserves. *Deferred:*
ephemeral "happenings" as a first-class mode. *Open:* GC policy for retired-space derived tier.
## T8 — Transclusion & projection depth
**Decision.** Transclusion is **one reference-not-copy primitive** over the addressable union
(blueprint §8.4), at three depths:
| Level | UC | Behaviour |
|-------|-----|-----------|
| Whole-page projection | UC-03 | lazy full page from a remote shard (replication-projection) |
| Block/span transclusion | UC-32 | inline embed by span address, with origin + freshness |
| Link reference | UC-08 | pointer only (ADR-06) |
Every transcluded artifact carries provenance + **staleness** (I-4, §8.8); live-transclusion
fragility (link rot / remote down) degrades to last-known + an `unavailable`/`stale` marker
(blueprint O-11). Span-level authz under transclusion = the stricter of source/host (O-10).
Reference-not-copy unifies Xanadu transclusion, ZigZag clone, embeds, synced blocks, Trilium
note-clone, literate named-chunk. (UC-03, UC-32.)
*Decided:* one primitive, three depths, provenance+staleness mandatory. *Deferred:* snapshot-
on-import vs live default (a policy). *Open:* span-authz composition (O-10), addressing (O-6).
## T9 — Consensus & reconciliation policy catalog
**Decision.** **Detection is core, resolution is policy** (I-7, blueprint §8.6). Core always
detects divergence and represents it as a coexisting (chorus) set; the **resolution preset** is
configurable per space / per equivalence set:
- **chorus-spread** (versions coexist; default) · **designated-canonical** (explicit write
target) · **git-merge** (where merge capability allows) · **vote-to-merge / editorial gate**
(optional, L6-assisted) · **overlay-only** (no destructive merge on read-only sources).
(FederationRequirements ADR-03/ADR-05; UC-07, UC-27.)
*Decided:* the preset catalog; detection-core/resolution-policy. *Deferred:* vote/editorial
gate mechanics (L6). *Open:* default preset per persona bundle (blueprint O-8).
## T10 — Federation-operations capability matrix
**Decision.** Each federation operation requires a minimum **verified capability profile**
(TSD §A T11/§6.6); below it, the op **degrades** along the named interaction axes (blueprint
§6.5) rather than failing. The matrix (consuming the T11 vocabulary):
| Federation op | Min capabilities | Degradation when absent |
|---------------|------------------|--------------------------|
| **read / project** | `read` | (floor — every shard) |
| **transclude span** | `read` + addressing≥span | whole-page projection only |
| **overlay** | `read` | always available (overlay is local) |
| **write-through** | `write` (+ `merge` for concurrent) | → overlay/patch target |
| **diff / 3-way merge** | `diff`,`merge` | → keep-both / chorus |
| **notify-driven freshness** | `notify` | → validator-poll → TTL (§8.8) |
| **native search delegate** | native-query≥index | → derived index over projection |
| **publish / mirror** | `publish` | → read-only / static projection |
| **fork+journal federation** | `read` + history (any) | → projection-only participant |
Every backend, down to the Oddmuse flat-file floor, is usable as **read-only / cache /
projection / backup / patch target** (I-8). This matrix and the T11 spectra are kept in sync
(it consumes that vocabulary). (UC-02UC-07.)
*Decided:* the op→capability matrix + degradation paths. *Deferred:* exhaustive per-op test
vectors → the conformance suite (§6.6). *Open:* axis-interaction completeness (blueprint O-5).
---
## T17 — Federation-model taxonomy (selectable / composable)
**Decision.** Federation is **plural and composable**, not one mechanism (blueprint §8.3). A
space selects a model (composing per shard); the default is **fork+journal over Git** (the home
case):
| Model | Anchor | Coordination shape | Capability floor | UCs |
|-------|--------|--------------------|------------------|-----|
| **Fork + journal** *(default)* | Federated Wiki | copy-with-provenance + per-page action journal (story = replay) | `read` + journal | UC-26, UC-71, UC-72 |
| **VCS-replication + ping** | ikiwiki | git clone/pull/push + change-ping | git-IS-store | UC-31, UC-33, UC-79 |
| **Query-time graph-join** | Wikibase `SERVICE` | join remote graphs at query, no copy | native-query≥graph | UC-74 |
| **Feed aggregation** | RSS/Atom | inbound feed → pages | `read` | UC-03 |
| **Activity streams** | ActivityPub | Create/Update events (notify or content) | `notify` | UC-31 |
| **Engine-mirror** | Wiki.js DB↔Git | engine mirrors its store to git | `publish`/mirror | UC-68, UC-69 |
The coordination journal (T4) is the fork+journal model's home; **git IS the journal** in
VCS-replication and engine-mirror (forge wikis make git the store *and* journal, resolving the
engine-mirror write-race). Models compose: e.g. fork+journal locally, query-join for a
typed-graph shard, feed-aggregation for an external source. (Mechanism over policy, I-7.)
*Decided:* the six models, selectable per space + composable per shard, default fork+journal.
*Deferred:* activity-streams content-bearing mode. *Open:* multi-model interaction edge cases
(when two models touch one shard).
---
## Consolidated decisions / deferred / open
- **Decided (architecture-settling):** star orchestrator (T1); overlay-default remix (T2);
identity/placement/equivalence + chorus (T3); event-sourced journal + append authority (T4);
server-primary incremental union (T5); notify-driven freshness (T6); space lifecycle (T7);
reference-not-copy transclusion (T8); detection-core/resolution-policy preset catalog (T9);
op→capability matrix (T10); selectable/composable federation models (T17).
- **Deferred (to impl / L6 / persona bundles):** reference UI; fork-attribution format; client
SDK; vote/editorial mechanics; ephemeral spaces; ActivityPub content-bearing; default-preset
bundles (O-8).
- **Open (tracked in blueprint §12):** O-1 equivalence blocking, O-4 union digest, O-5 axis
interactions, O-6 addressing, O-8 presets, O-10 span-authz, O-11 unavailability, O-12 log
throughput.
## Acceptance (SHARD-WP-0002 federation half)
T1T10 + T17 each have a decision record with a Decided/Deferred/Open footer; all honour INTENT;
UC-26UC-33, UC-56, UC-71UC-72, UC-74, UC-79 trace here; the adapter-contract companion is
`spec/TechnicalSpecificationDocument.md` §A (T11T16, T18). Conflicts with SHARD-WP-0001 are
none (FederationRequirements ADRs are consumed, not duplicated).