docs(canon): ADR-009 federated namespaces and reconciliation limits (proposed)
Resolves a contradiction in accepted canon: ADR-007 decision 1's globally unique forward-only running numbers require a central allocator, the exact dependency federation must survive. Amended to namespace-scoped uniqueness with PREFIX-WP-NNNN@namespace qualification; unqualified still means the local namespace. C2's UUIDv5 derivation input becomes (namespace, identifier) — free now, expensive after it ships. States reconciliation limits rather than implying convergence. T0 fork, T1 sync and T2 reintegration are partly automatable; T3 amalgamation, where a fork established distinct operational infrastructure, is an M&A-class governed programme rather than a merge, and may legitimately end in permanent coexistence or divestment. prj-state-hub-retirement is cited as measured T3 cost under the most favourable possible conditions. Coexistence, not merging, is the normal case: client instances per CUST-WP-0058 are forks that never return. Records fork; effects do not. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
f8c3c1d8fd
commit
9a6e14e733
2 changed files with 183 additions and 2 deletions
|
|
@ -82,6 +82,13 @@ nothing prevents number reuse.
|
|||
**1. A workplan identifier is globally unique.** `PREFIX-WP-NNNN` names exactly
|
||||
one workplan across the entire fleet, for all time.
|
||||
|
||||
> **Amended 2026-08-17 by `ADR-009` decision 2.** Uniqueness and forward-only
|
||||
> allocation are **namespace-scoped**, not global; global identity is the pair
|
||||
> `(namespace, identifier)`, written `PREFIX-WP-NNNN@namespace` when foreign.
|
||||
> Global sequential allocation would require a central coordinator — the exact
|
||||
> dependency federation must survive. Everything below holds unchanged **within**
|
||||
> a namespace, which is where all current work sits.
|
||||
|
||||
- A workplan prefix is owned by exactly one repository. No two repositories may
|
||||
use the same prefix.
|
||||
- A running number is never reused within a prefix, including after a workplan is
|
||||
|
|
@ -96,8 +103,10 @@ It also inverts ADR-001 — a file carrying a hub's private key is the file
|
|||
holding hub state.
|
||||
|
||||
*Target state (C2).* `state_hub_workstream_id` and `state_hub_task_id` become
|
||||
**deterministic**: UUIDv5 derived from the globally unique `PREFIX-WP-NNNN`
|
||||
identifier. Every instance computes the same value independently, writeback
|
||||
**deterministic**: UUIDv5 derived from the workplan identifier. Per `ADR-009`
|
||||
decision 3 the derivation input is the pair `(namespace, identifier)`, not the
|
||||
identifier alone — deriving from the identifier alone would make two forks
|
||||
holding unrelated work under the same number compute the same UUID. Every instance computes the same value independently, writeback
|
||||
becomes idempotent, and any number of hub instances may coexist without
|
||||
coordination. The field shape is unchanged, so consumers keep working; only the
|
||||
provenance of the value changes.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,172 @@
|
|||
---
|
||||
id: ADR-009
|
||||
type: architecture-decision-record
|
||||
title: "Federated Namespaces, Qualified Identifiers, and the Limits of Reconciliation"
|
||||
status: proposed
|
||||
decided_by: Bernd Worsch
|
||||
date: "2026-08-17"
|
||||
tags: ["architecture", "federation", "namespace", "identity", "reconciliation", "fos", "adr-007", "adr-008"]
|
||||
---
|
||||
|
||||
# ADR-009: Federated Namespaces, Qualified Identifiers, and the Limits of Reconciliation
|
||||
|
||||
## Status
|
||||
|
||||
Proposed. Amends `ADR-007` decision 1 and extends `ADR-008` decision 4.
|
||||
|
||||
## Context
|
||||
|
||||
The ecosystem must be **federation-capable** — able to work without a live link
|
||||
to central services — and **chain-of-command efficient**. These read as opposing
|
||||
requirements, but `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**. Nothing
|
||||
requires the mechanism to depend on reaching the authority — the same separation
|
||||
distributed version control makes, where an integration branch is privileged by
|
||||
agreement rather than by any technical property.
|
||||
|
||||
**One accepted decision does violate 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 not an edge case but a certainty.
|
||||
|
||||
This is not hypothetical. Instance-per-client tenancy (`CUST-WP-0058`) already
|
||||
means each client deployment is a fork of the stack; the business model committed
|
||||
to forking before the identifier scheme could express it.
|
||||
|
||||
## 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. Identifiers are unique within a namespace, qualified across namespaces.**
|
||||
`ADR-007` decision 1 is amended: uniqueness and forward-only allocation are
|
||||
**namespace-scoped**, not global. Global identity is the pair
|
||||
`(namespace, identifier)`.
|
||||
|
||||
Notation is a suffix:
|
||||
|
||||
```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 keeps existing sorting, grep, and tooling working; a
|
||||
prefix would break them.
|
||||
|
||||
**3. Deterministic identifiers derive from the pair.** `ADR-007` decision 2 (C2)
|
||||
derives UUIDv5 from `PREFIX-WP-NNNN`. Under federation the derivation 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.
|
||||
|
||||
**4. Records carry lineage.** A namespace records what it forked from and at what
|
||||
point; a record forked from another namespace records its origin. Without
|
||||
lineage, a shared identifier is ambiguous between *the same work, diverged* and
|
||||
*different work, colliding* — a distinction that cannot be reconstructed after
|
||||
the fact.
|
||||
|
||||
**5. Mutable state is derived from an append-only log.** Extending `ADR-008`
|
||||
decision 4: status and other mutable fields are a fold over append-only events
|
||||
rather than fields to be reconciled. Reconciliation then becomes union-of-events
|
||||
plus re-derivation — deterministic, order-independent, and requiring no
|
||||
conflict model. This collapses the hardest part of reconciliation into the part
|
||||
that was already free.
|
||||
|
||||
**6. 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. The architecture must
|
||||
support permanent parallel operation as a first-class outcome, not as a failure
|
||||
to reconcile.
|
||||
|
||||
**7. What may fork.** Canon, plans, knowledge, and records fork freely. **Effects
|
||||
do not.** Two namespaces may hold divergent plans about one production database;
|
||||
they cannot hold divergent production databases. Work that acts on shared
|
||||
operational infrastructure is not fork-safe and must be coordinated through the
|
||||
owning namespace.
|
||||
|
||||
## 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** | fork returns; records diverged, **no independent operational infrastructure** | union events, re-derive, human-resolve genuine contradictions | partly |
|
||||
| **T3 Amalgamation** | **distinct operational infrastructure**, identity, credentials, data stores, possibly distinct canon | governed programme — see below | **no** |
|
||||
|
||||
**The T2/T3 test is whether the fork established its own operational
|
||||
infrastructure** — stateful systems with independently diverged state.
|
||||
|
||||
**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 with 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 possible conditions: one
|
||||
owner, one canon, one credential authority.
|
||||
|
||||
Nothing in this ADR reduces that cost. It ensures the cost is **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. Client
|
||||
instances become expressible. Reconciliation limits are stated rather than
|
||||
implied.
|
||||
|
||||
**Negative.** Every record gains a namespace and lineage, and tooling must learn
|
||||
qualified references. The fork-boundary rule (decision 7) constrains what
|
||||
disconnected work may legitimately do — deliberately.
|
||||
|
||||
**Deferred.** Merge machinery for T2 is **not** specified here and should not be
|
||||
built until a real fork exists and 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, not global.
|
||||
`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. Settle before implementation; the notation works either way.
|
||||
|
||||
## 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 — 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue