--- id: CUST-ADR-011 type: architecture-decision-record title: "Federated Namespaces: Four Planes, Declared Posture, and the Limits of Reconciliation" status: proposed owner: the-custodian revision: "draft-2" last_reviewed: "2026-08-17" review_interval: 6m decided_by: Bernd Worsch date: "2026-08-17" tags: ["architecture", "federation", "namespace", "identity", "reconciliation", "posture", "fos", "adr-007", "adr-008", "adr-010"] --- # ADR-011: Federated Namespaces — Four Planes, Declared Posture, and the Limits of Reconciliation ## Status Proposed, draft-2. Amends `ADR-007` decisions 1 and 2; extends `ADR-010` decision 4; adopts the plane/ladder/posture form and the accuracy-not-altitude conformance rule from `ADR-008` (Multi-Tenancy Framework). ## Context The ecosystem must be **federation-capable** — able to work without a live link to central services — and **chain-of-command efficient**. `federated-organization-standard_v1.0` already resolves the organizational half: > global coherence is achieved through policy, escalation, and shared protocols > rather than through monolithic control (`:51`) > > bounded autonomy plus disciplined coordination (`:86`) Authority is a **policy** layer; availability is a **mechanism**. Distributed version control makes the same separation: an integration branch is privileged by agreement, never by a technical property. **One accepted decision violates this.** `ADR-007` decision 1 requires running numbers that are *globally* unique and allocated forward only. Global sequential allocation requires a coordinator — precisely the central dependency federation must survive. Two disconnected forks each allocating `RCLUSTER-WP-0015` is a certainty, not an edge case. This is not hypothetical. Instance-per-client tenancy (`CUST-WP-0058`) already makes every client deployment a fork of the stack; the business model committed to forking before the identifier scheme could express it. ### Why this draft changed form Draft-1 stated federation as a set of binary rules — notably "records fork, effects do not". That is a single verdict where a graduated declaration belongs, and it is the same conflation `ADR-008` §03 diagnoses for multi-tenancy: *"'Is this multi-tenant?' is treated as one question. It is four, and they are independent."* "Is this federation-capable?" is likewise not one question. A namespace can be strong on identity and incapable of disconnected operation; it can operate disconnected and have no way to reconcile afterwards. Draft-1 could not say so. This draft reuses `ADR-008`'s vocabulary rather than inventing a parallel one. Two competing maturity vocabularies in one canon would be its own collision. ## Decision **1. Records live in a namespace.** A namespace is a federated branch of the ecosystem — a fleet instance, a client deployment, an autonomous domain that may operate disconnected. It is the unit of sovereignty in FOS terms and the unit of divergence here. **2. Federation is four orthogonal planes.** | Plane | Question | Vocabulary owner | |---|---|---| | Namespace **N** | How are records named and disambiguated across branches? | this ADR | | Autonomy **U** | Can work proceed with no link to central services? | repo-manager | | Reconciliation **R** | What happens when branches meet again? | repo-manager | | Substrate **S** | Does this namespace hold independently diverging operational state? | railiance-platform | **3. Each plane carries a ladder.** Higher is stronger, not better. The right level is the one a namespace can evidence and its risk warrants. ```text N0 no namespace concept; identifiers assume one global space N1 namespace implied by deployment, never recorded N2 namespace declared; identifiers namespace-scoped; qualification available N3 N2 + lineage recorded, and derived identifiers keyed on (namespace, identifier) U0 routine work requires the central service U1 degraded read-only; writes blocked while disconnected U2 work proceeds locally: file-derived state written to files, hub-native buffered U3 U2 + exercised — a dated disconnection drill with evidence R0 no defined path; divergence is unrecoverable R1 manual, per-record comparison and hand resolution R2 append-only events plus derived state: union and re-derive, deterministic R3 R2 + lineage-aware; distinguishes divergence from collision automatically S0 shares operational substrate with another namespace — cannot fork safely S1 shared substrate, namespace-keyed S2 dedicated substrate, no independent state divergence yet S3 independent operational substrate with diverged state — the fork is real ``` **4. A namespace declares a posture vector**, in the repository rather than the hub, consistent with `ADR-010` decision 4 (file-derived state) and `ADR-008` decision 5.1. ```yaml federation: current: { N: 1, U: 1, R: 1, S: 1 } target: { N: 3, U: 2, R: 2, S: 1 } reviewed: "2026-08-18" gap: U: "Registration requires the registrar under ADR-007 decision 2 interim. Lifts when derived identifiers land (RMGR-WP-0005-T03)." ``` **The ecosystem's own posture today is `N1 U1 R1 S1`** — one implied namespace, disconnected registration blocked, reconciliation manual, substrate shared. Declaring that is conformant. Claiming better is not. **5. Conformance is accuracy, not altitude.** Adopted verbatim in force from `ADR-008` §06: a namespace is conformant when its declared posture is accurate, its target recorded, and it claims no level it cannot evidence. It is non-conformant when it overclaims, at any altitude. Declaring `S0` is conformant. Concealing `S0` is not. A repository may join at any posture; it may not join silently. This matters more here than it does for tenancy: the cost of discovering a true posture during reconciliation is the whole difference between T2 and T3. **6. Identifiers are unique within a namespace, qualified across.** `ADR-007` decision 1 is amended: uniqueness and forward-only allocation are **namespace-scoped**. Global identity is the pair `(namespace, identifier)`. ```text RCLUSTER-WP-0015 this namespace — the common case, unchanged RCLUSTER-WP-0015@railiance01 a foreign namespace, explicitly qualified ``` Unqualified always means "in my own namespace", exactly as `main` does against `origin/main`. A suffix preserves existing sorting, grep, and tooling; a prefix would break them. **7. Derived identifiers key on the pair.** `ADR-007` decision 2 (C2) derives UUIDv5 from the identifier. Under federation the input must be `(namespace, identifier)`. Deriving from the identifier alone would make two forks holding unrelated work under the same number compute the *same* UUID — a collision manufactured by the fix. C2 is not yet built, so this is free now and expensive later. **8. The planes couple at their upper levels. State the coupling; do not use it to argue the planes are one.** - `R3` requires `N3` — distinguishing divergence from collision requires lineage. - A namespace may not sustain `U2` or above while below `R2`. Operating disconnected without deterministic reconciliation accumulates divergence that cannot later be merged. Autonomy without reconciliation is not federation; it is an unplanned fork. - `T3` is entailed by `S3` in any participant (decision 10). **9. Anti-overclaim.** This is the most misusable fact in the framework, and it is the direct analogue of `ADR-008`'s `P0 → P1 → P2` warning. > Adopting namespace-qualified identifiers is movement on the **N plane only**. > It buys disambiguation, citability, and coordinator-free allocation. It does > **not** raise autonomy, reconciliation, or substrate independence by one step. > A system at `N3 U0 R0 S0` cannot operate disconnected and cannot reconcile. No namespace may be described as "federation-capable", "independently operable", or "able to run disconnected" on N-plane evidence alone. Such a claim requires declared `U` and `R` levels with evidence behind them. **Commercially**, client-facing claims about instance independence must cite the `S` and `U` levels, never the identifier scheme. Instance-per-client tenancy is sold on substrate independence; the qualifier does not supply it. **10. The reconciliation tier is derived from participants' postures, not judged after the fact.** ```text any participant at S3 -> T3 (regardless of other planes) all participants S<=S2 and R>=R2 -> T2 feasible any participant below R2 -> T1 at best; manual thereafter ``` This is the practical payoff of declaring postures: the cost of rejoining is **computable before a fork is created**, rather than discovered when reconciliation is attempted. **11. Coexistence is the normal case; merging is the exception.** The qualifier is primarily a coexistence mechanism, not merge preparation. Most forks — client instances above all — are never intended to return. Permanent parallel operation is a first-class outcome, not a failure to reconcile. **12. Evidence.** A claimed level requires evidence, per `ADR-008` §13. | Level | Evidence | |---|---| | `N2` | namespace declared in the repo; qualified references resolve | | `N3` | lineage fields present; a derived identifier reproduced by an independent implementation | | `U2` | work completed with central unreachable, committed, later accepted without rework | | `U3` | dated disconnection drill record | | `R2` | replaying the union of events reproduces identical derived state | | `R3` | a collision and a divergence, correctly distinguished, in test | | `S2` / `S3` | substrate inventory naming the stateful systems and whether their state has diverged | **13. Guard.** Declared postures regress silently. Posture is checked by the same consistency machinery that checks repository standards (`RMGR-WP-0004-T02`, `rmgr conform`), so a namespace that drops below its declared level is a reported defect rather than a discovery. A regression found by guarding is a defect; a regression declared in advance is a decision. ## Reconciliation tiers, and where automation stops | Tier | Situation | Mechanism | Automatable | |---|---|---|---| | **T0 Fork** | namespace created, lineage recorded | metadata | yes | | **T1 Sync** | pull canon, plans, or knowledge from another namespace | append events, re-derive | largely | | **T2 Reintegration** | records diverged, no participant above `S2` | union events, re-derive, human-resolve genuine contradictions | partly | | **T3 Amalgamation** | any participant at `S3` | governed programme — see below | **no** | **T3 is not a merge.** It resembles the merger or acquisition of distinct companies far more than a version-control merge, and must be planned as such: - due diligence — inventory both sides, item by item; - survivor decisions per subsystem — keep, move, replace, retire; - migration with evidence, and decommissioning of what does not survive; - governance integration — reconciling two bodies of canon is a human act, never automated; - identity, credential, and data custody consolidation. **T3 may legitimately end without integration.** Permanent coexistence, or divestment, are valid outcomes. Real mergers most often fail at systems integration; an architecture that assumes eventual convergence is lying about its own limits. ### Known cost `prj-state-hub-retirement` is a T3 reconciliation inside a *single* organization — two hub implementations, distinct infrastructure. It required a dedicated project repository, a 425-item disposition inventory (`SHR-INV-0001`), staged migration with strangler adapters, and explicit retirement gates. That is the realistic cost of T3 under the most favourable conditions possible: one owner, one canon, one credential authority. Nothing here reduces that cost. Declared postures make it **visible before** a fork is created rather than discovered when reconciliation is attempted. ## Consequences **Positive.** Disconnected operation stops requiring a coordinator for identity. `ADR-007` decision 1's contradiction is resolved rather than tolerated. A namespace mid-journey can describe itself honestly instead of being non-conformant. Reconciliation cost becomes computable in advance. Client instances become expressible. **Negative.** Every namespace gains a posture to declare and keep accurate, and tooling must learn qualified references. Decision 8's coupling rule constrains disconnected operation to namespaces that can reconcile — deliberately. **Deferred.** Merge machinery for T2 is **not** specified here and should not be built until a real fork needs it. T3 needs no machinery by definition; it needs a project repository and human judgement. **Amended.** `ADR-007` decision 1 — uniqueness is namespace-scoped. `ADR-007` decision 2 — derivation input becomes `(namespace, identifier)`. ## Open question **What is the namespace boundary in practice?** Candidates: a fleet instance (`railiance01`), a client deployment, or an FOS autonomous domain. FOS's recursion — "from projects to companies to foundation-like umbrella structures" — suggests namespaces **nest**, which would make qualification relative rather than absolute, closer to DNS than to a flat handle. The notation survives either answer, so implementation is not blocked, but the data model is unfinished until it is settled. ## References - `canon/standards/federated-organization-standard_v1.0.md` — bounded autonomy, escalation, sovereignty by default, rebuildability - ADR-001 — workplans originate as repo files - ADR-007 — identifier uniqueness and derived identifiers (amended here) - ADR-008 — Multi-Tenancy Framework; source of the plane/ladder/posture form and the accuracy-not-altitude conformance rule - ADR-010 — hub authority, local cache, and the two kinds of hub data - `CUST-WP-0058` — instance-per-client tenancy - `SHR-INV-0001` — 425-item disposition inventory, T3 cost evidence - `RMGR-WP-0004-T02` — `rmgr conform`, the guard machinery