Files
shard-wiki/spec/FederationArchitecture.md
tegwick 802a80231a 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>
2026-06-15 02:24:11 +02:00

221 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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).