# Federation deduplication plan (post WP-0014 rollout) **Date:** 2026-06-16 **Trigger:** `hub sync --merge` (60 sources) + `federation compose` (37 capabilities) ## Compose outcome | Metric | Value | |---|---| | Hub sources synced | 60 | | Federated capability rows | 37 | | Duplicate ID warnings | 16 | | Remote fetch failures | 13 (T09 Gitea 404 blockers) | `collision_policy: warn` — duplicates are retained with `source_repo` on each row; compose does not pick a winner. ## Duplicate-ID policy (owner migration) When a capability's canonical `owner` repo publishes its own index row: 1. **Owner repo is source of truth** for entry body, maturity, and relations. 2. **reuse-surface retains a stub only while** the owner index is unreachable or discovery from federation is impaired. 3. **Removal from reuse-surface** happens in a **separate commit per owner repo** after: owner `publish_check: pass`, federation compose shows the owner row, and the owner confirms no agents depend on reuse-surface paths. 4. **Do not delete** reuse-surface markdown until the owner index row is live; optional: replace with a one-line redirect note in git history only. 5. **`activity-core`** (`capability.activity.event-coordinate`): owner index not yet fetchable (Gitea 404) — keep reuse-surface row until publish passes. ## Rows to remove from reuse-surface (planned) | Capability ID | Owner repo | Owner publish | Remove when | |---|---|---|---| | `capability.audit.event-retain` | `audit-core` | pass | Owner commit 1 | | `capability.authorization.policy-evaluate` | `flex-auth` | pass | Owner commit 2 | | `capability.feature-control.evaluate` | `feature-control` | pass | Owner commit 3 | | `capability.feature-control.rollout` | `feature-control` | pass | Owner commit 3 | | `capability.feature-control.visibility` | `feature-control` | pass | Owner commit 3 | | `capability.identity.subject-resolution` | `identity-canon` | pass | Owner commit 4 | | `capability.identity.vocabulary-canonicalize` | `identity-canon` | pass | Owner commit 4 | | `capability.statehub.progress-log` | `state-hub` | pass | Owner commit 5 | | `capability.statehub.workstream-coordinate` | `state-hub` | pass | Owner commit 5 | | `capability.wiki.shard-orchestration` | `shard-wiki` | pass | Owner commit 6 | | `capability.wiki.adapter-contract` | `shard-wiki` | pass | Owner commit 6 | | `capability.wiki.page-model` | `shard-wiki` | pass | Owner commit 6 | | `capability.wiki.coordination-journal` | `shard-wiki` | pass | Owner commit 6 | | `capability.wiki.overlay` | `shard-wiki` | pass | Owner commit 6 | | `capability.wiki.federation-models` | `shard-wiki` | pass | Owner commit 6 | | `capability.wiki.engine-typed-extensions` | `shard-wiki` | pass | Owner commit 6 | | `capability.wiki.derived-views` | `shard-wiki` | pass | Owner commit 6 | | `capability.activity.event-coordinate` | `activity-core` | **fail** | After Gitea fix + publish pass | **Keep in reuse-surface:** `capability.registry.register`, `capability.registry.validate` (meta-registry capabilities). ## Execution order (suggested) 1. Fix T09 Gitea 404 repos (operator) so all owner indexes fetch. 2. Per-owner PR in `reuse-surface`: drop index row + capability markdown for that owner's IDs; run `validate`, `federation compose`, `graph --check`. 3. Re-run `hub sync --merge` if hub URLs change. 4. Target federated count after dedup: **~21** unique capabilities (37 − 16 duplicates + empty scaffolds as owners add entries). ## Verification commands ```bash reuse-surface hub sync --merge reuse-surface federation compose reuse-surface validate --relations reuse-surface graph --check ```