# FederationArchitecture Status: **draft for review** · Date: 2026-06-15 · Deliverable of **SHARD-WP-0002** (T1–T10, 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 (T11–T16, 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-02–UC-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) T1–T10 + T17 each have a decision record with a Decided/Deferred/Open footer; all honour INTENT; UC-26–UC-33, UC-56, UC-71–UC-72, UC-74, UC-79 trace here; the adapter-contract companion is `spec/TechnicalSpecificationDocument.md` §A (T11–T16, T18). Conflicts with SHARD-WP-0001 are none (FederationRequirements ADRs are consumed, not duplicated).