# The N+1 Consortium Training Model

> What the PoC actually proves: one governed shared base + N persistent sovereign artifacts, raw data never leaves the node, only weight deltas cross the boundary, and the quality-floor + max-weight anti-capture rules that the coordinator enforces on every round.

- Repository: The-AI-Alliance/tapestry
- GitHub: https://github.com/The-AI-Alliance/tapestry
- Human wiki: https://grok-wiki.com/public/wiki/the-ai-alliance-tapestry-4a40b7cf9eb6
- Complete Markdown: https://grok-wiki.com/public/wiki/the-ai-alliance-tapestry-4a40b7cf9eb6/llms-full.txt

## Source Files

- `src/tapestry/training/consortium/README.md`
- `examples/consortium_training_demo.py`
- `tech-docs/architecture/decisions/adr-002-consortium-training.md`
- `tech-docs/architecture/decisions/adr-001-core-plus-sovereign.md`
- `tech-docs/architecture/decisions/adr-008-data-sovereignty.md`
- `tech-docs/reference/training-approaches.md`

---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [src/tapestry/training/consortium/README.md](src/tapestry/training/consortium/README.md)
- [examples/consortium_training_demo.py](examples/consortium_training_demo.py)
- [src/tapestry/training/consortium/__init__.py](src/tapestry/training/consortium/__init__.py)
- [src/tapestry/training/consortium/coordinator.py](src/tapestry/training/consortium/coordinator.py)
- [src/tapestry/training/consortium/node.py](src/tapestry/training/consortium/node.py)
- [src/tapestry/training/consortium/policy.py](src/tapestry/training/consortium/policy.py)
- [src/tapestry/training/consortium/messages.py](src/tapestry/training/consortium/messages.py)
- [src/tests/tapestry/training/consortium/test_consortium_training.py](src/tests/tapestry/training/consortium/test_consortium_training.py)
- [tech-docs/architecture/decisions/adr-002-consortium-training.md](tech-docs/architecture/decisions/adr-002-consortium-training.md)
- [tech-docs/architecture/decisions/adr-001-core-plus-sovereign.md](tech-docs/architecture/decisions/adr-001-core-plus-sovereign.md)
- [tech-docs/architecture/decisions/adr-008-data-sovereignty.md](tech-docs/architecture/decisions/adr-008-data-sovereignty.md)
- [tech-docs/reference/training-approaches.md](tech-docs/reference/training-approaches.md)

</details>

# The N+1 Consortium Training Model

The N+1 Consortium Training Model is the concrete outcome proven by Tapestry's consortium-training proof of concept. It consists of **one governed shared base model** that evolves through controlled contributions plus **N persistent sovereign model artifacts** that each participant node owns and retains. Raw training data never leaves its originating node; only weight deltas and a quality score cross the coordinator boundary. The coordinator applies a quality floor and a per-node maximum-weight cap on every round before any integration occurs.

This pattern directly addresses Tapestry's dual requirements: frontier-class capability through a shared base, and cultural/institutional sovereignty through participant-owned layers. The PoC is deliberately minimal (a tiny causal model, local epochs on encoded tokens) yet verifies the architectural invariants described in the ADRs. It does not claim production scale, formal privacy guarantees, or a full post-training pipeline.

## The N+1 Outcome

The PoC maintains exactly two classes of persistent artifacts after each round:

- The **shared base** (evolved by the coordinator from accepted, weighted deltas).
- One **sovereign artifact per node** (full model state after local training, retained by both the node and the coordinator's `sovereign_artifacts` registry).

This is the literal "N+1" the package README highlights: one base + N sovereigns. Each sovereign artifact records the node's jurisdiction, training stage, final state, and local metrics. The node keeps its own copy (`latest_artifact`); the coordinator keeps a registry so the consortium can audit participation without owning the data.

**Sources:** [src/tapestry/training/consortium/README.md:4-11](src/tapestry/training/consortium/README.md), [src/tapestry/training/consortium/coordinator.py:44-45](src/tapestry/training/consortium/coordinator.py), [src/tests/tapestry/training/consortium/test_consortium_training.py:114-115](src/tests/tapestry/training/consortium/test_consortium_training.py)

## Data Never Leaves the Node

Sovereign corpora are supplied only to the `SovereignTrainingNode` constructor and used exclusively inside `_build_dataloader` and `_train_locally`. The `SovereignContribution` dataclass that travels to the coordinator contains:

- `weight_delta` (state dict difference)
- `quality_score`
- `token_count` (an integer, not the tokens)
- `metrics`

No raw text, no token sequences, and no gradients tied to individual examples ever leave the node. The demo encodes its small domain corpora locally into integer lists before node construction; those lists never appear in any message or coordinator state.

**Sources:** [src/tapestry/training/consortium/node.py:49-58](src/tapestry/training/consortium/node.py), [src/tapestry/training/consortium/messages.py:23-32](src/tapestry/training/consortium/messages.py), [examples/consortium_training_demo.py:23-39](examples/consortium_training_demo.py)

## Only Weight Deltas Cross the Boundary

Each node receives the current shared base state, loads it, runs local continued pretraining, then computes:

```python
delta = {name: sovereign_state[name] - starting_state[name] for name in starting_state}
```

Only this delta (plus the quality score) is packaged into `SovereignContribution` and returned. The coordinator never sees the node's full model parameters except as an opaque artifact it stores for the registry. Integration happens solely through `_apply_weighted_deltas`, which adds the scaled deltas to the previous base.

This design matches the consortium-training definition in the reference material: infrequent, WAN-tolerant weight deltas rather than per-step gradients or raw data movement.

**Sources:** [src/tapestry/training/consortium/node.py:58](src/tapestry/training/consortium/node.py), [src/tapestry/training/consortium/coordinator.py:55-57](src/tapestry/training/consortium/coordinator.py), [tech-docs/reference/training-approaches.md:69-81](tech-docs/reference/training-approaches.md)

## The Contribution Policy: Quality Floor + Max-Weight Anti-Capture

The `ContributionPolicy` is the governance mechanism applied on every round. Its `weights()` method:

1. Drops any node whose `quality_score < quality_floor` (or ≤ 0).
2. Normalizes the remaining scores.
3. Iteratively caps any single node's share at `max_node_weight`, re-normalizing the residual mass until no node exceeds the cap.
4. Returns the final normalized weights for only the accepted nodes.

The coordinator calls this before `_apply_weighted_deltas`. Rejected nodes still receive a sovereign artifact (they trained locally), but their deltas do not affect the shared base.

Default demo values are `quality_floor=0.75`, `max_node_weight=0.5`. Tests explicitly verify that weak contributions are rejected and that a dominant node cannot exceed its cap.

**Sources:** [src/tapestry/training/consortium/policy.py:22-59](src/tapestry/training/consortium/policy.py), [src/tapestry/training/consortium/coordinator.py:48-52](src/tapestry/training/consortium/coordinator.py), [src/tests/tapestry/training/consortium/test_consortium_training.py:65-79](src/tests/tapestry/training/consortium/test_consortium_training.py)

## How a Round Executes

```mermaid
sequenceDiagram
    participant C as ConsortiumCoordinator
    participant N as SovereignTrainingNode (per node)
    Note over N: sovereign_corpus stays local
    C->>N: run_sovereign_cycle(round, base_state)
    N->>N: load base, train locally, keep full SovereignModelArtifact
    N-->>C: SovereignContribution {weight_delta, quality_score, token_count}
    C->>C: policy.weights() → accepted + capped weights
    C->>C: _apply_weighted_deltas only on accepted deltas
    C-->>N: next base_state for following round
```

The loop is deliberately simple: nodes train independently between syncs; the coordinator performs a single governed aggregation step; both sides retain their artifacts. This is the minimal executable demonstration of the core-plus-sovereign pattern (shared base + sovereign layers) and the consortium training paradigm (few large sovereign nodes, weight-delta exchange, consortium governance).

**Sources:** [src/tapestry/training/consortium/coordinator.py:38-66](src/tapestry/training/consortium/coordinator.py), [src/tapestry/training/consortium/node.py:51-78](src/tapestry/training/consortium/node.py)

## Entry Points for Readers

- Run the executable demonstration: `python examples/consortium_training_demo.py`
- Read the package contract: `src/tapestry/training/consortium/README.md`
- Inspect the tested invariants: `src/tests/tapestry/training/consortium/test_consortium_training.py`
- Understand the framing: ADR-002 (consortium training), ADR-001 (core-plus-sovereign), ADR-008 (data sovereignty categories)

The PoC is intentionally scoped. It proves the N+1 shape, the data-locality invariant, delta-only exchange, and the enforceable policy rules; it does not implement production governance, secure aggregation, or full-scale training.

## Summary

The consortium-training PoC establishes that a single governed shared base plus per-node persistent sovereign artifacts can be produced while keeping raw data local and enforcing quality and anti-capture controls on every round through nothing more than weight deltas and a small policy object. These properties are not aspirational; they are the observed, tested behavior of the code in `SovereignTrainingNode`, `ConsortiumCoordinator`, and `ContributionPolicy`.

**Sources:** [src/tapestry/training/consortium/__init__.py:3-7](src/tapestry/training/consortium/__init__.py), [src/tapestry/training/consortium/README.md:23-34](src/tapestry/training/consortium/README.md)
