Files
inter-hub/docs/phase8-summary.md
Bernd Worsch 9265ca2d9c feat(P8): IHF Phase 8 complete — Federated Hub Maturity
Implements the final phase of the IHF v0.1 specification:

- WidgetOwnership: delegated ownership registry (local/delegated/global),
  append-only audit artefacts, ownership badge on widget show page
- HubRoutingRule + RoutingEngine: priority-ordered inter-hub routing engine;
  null-inclusive category/widget-type matching; RouteNowAction for manual
  re-evaluation; RoutedCandidates view per hub
- FederatedPolicyOverlay: draft → active → retired lifecycle; activated
  overlays are immutable (same pattern as Phase 6 contracts); policy
  compliance dashboard with decision coverage metrics
- StewardshipRole: named governance roles per hub; point-in-time revocation
  pattern; hub and ops-board integration
- ArchiveRecord + is_archived: soft-delete on widgets; lineage inspector
  traces full traceability chain (Widget → Events → Annotations → Candidates
  → Requirements → Decisions → Deployments → Signals + ArchiveRecord)
- FederatedGovernanceDashboard: 5-panel autoRefresh org-wide governance view
  (ownership coverage, routing activity, policy compliance, stewardship
  coverage, archive activity)

Schema: widget_ownerships, hub_routing_rules, federated_policy_overlays,
stewardship_roles, archive_records; ALTER widgets ADD is_archived;
ALTER requirement_candidates ADD routed_to_hub_id

Migration: 1743638400-ihf-phase8-federated-hub-maturity.sql
Tests: Phase 8 integration tests appended to Test/Integration.hs
Docs: docs/phase8-summary.md; SCOPE.md updated to Phase 8 complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 22:53:01 +00:00

127 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 8 Summary — Federated Hub Maturity
Phase 8 completes the IHF v0.1 specification. It introduces the governance
structures needed when multiple teams, hubs, and policies must coexist at
organisational scale.
## What Was Built
### Delegated Ownership (`WidgetOwnership`)
Every widget can now carry an explicit ownership record: `local` (owned by its
hub), `delegated` (steward hub differs from owner hub), or `global` (org-wide).
Ownership records are append-only audit artefacts — `effective_until` signals
expiry, but records are never deleted.
The ownership badge appears on the widget show page (colour-coded: local=gray,
delegated=blue, global=purple).
### Inter-Hub Requirement Routing (`HubRoutingRule`)
A priority-ordered rule engine routes `RequirementCandidate` records across hub
boundaries. When a candidate is created, the engine finds the highest-priority
active rule whose `match_category` and `match_widget_type` match (null = any)
and sets `routed_to_hub_id` on the candidate.
`RouteNowAction` allows manual re-evaluation. `RoutedCandidatesAction { hubId }`
shows all candidates forwarded to a given hub from any source hub.
### Federated Policy Overlays (`FederatedPolicyOverlay`)
Org-wide governance policies applied across selected hubs (or all hubs via
`applies_to_hubs = []`). Overlays follow a `draft → active → retired` lifecycle.
**Immutability pattern:** once activated, an overlay cannot be edited. A new
overlay must be created to supersede the old one. The old overlay remains
readable for audit. This mirrors the Phase 6 `EnvelopeEmissionContract`
immutability pattern.
The Policy Compliance Dashboard shows coverage metrics: decisions referencing
at least one `PolicyReference` as a percentage of total in-scope decisions.
### Stewardship Roles (`StewardshipRole`)
Named governance roles assigned to hubs (e.g. "Hub Lead", "Policy Steward",
"Triage Owner"). Roles have `granted_at` and `revoked_at` timestamps.
Contextual steward queries use the point-in-time pattern:
`granted_at ≤ T AND (revoked_at IS NULL OR revoked_at > T)`.
No edits — create a new record to replace a role.
### Archival and Lineage Inspection (`ArchiveRecord`, `is_archived`)
**Soft-delete pattern:** `is_archived BOOLEAN NOT NULL DEFAULT FALSE` on
`widgets`. Active queries filter with `filterWhere (#isArchived, False)`.
The widget row and all related records are preserved.
`ArchiveWidgetAction` sets the flag and creates an `ArchiveRecord` (subject_type,
subject_id, reason, archived_by, lineage_ref).
`LineageInspectorAction { widgetId }` renders the full IHF traceability chain
in a single read-only timeline:
`Widget → InteractionEvents → Annotations → RequirementCandidates
→ Requirements → DecisionRecords → DeploymentRecords → OutcomeSignals`
plus any `ArchiveRecord` for the widget.
### Federated Governance Dashboard
`FederatedGovernanceDashboardAction` (autoRefresh, five panels):
| Panel | Metric |
|-------|--------|
| 1 — Ownership | % of widgets with ownership records; breakdown by type |
| 2 — Routing | Active rule count; candidates routed cross-hub in 30 days |
| 3 — Policy compliance | Active overlays; % decisions with policy reference |
| 4 — Stewardship | Hubs with ≥1 active steward; hubs with no stewards |
| 5 — Archive activity | Artifact counts archived in last 90 days by subject type |
## Schema Changes
```sql
widget_ownerships -- delegated ownership records
hub_routing_rules -- inter-hub routing logic
requirement_candidates.routed_to_hub_id -- routing destination (nullable)
federated_policy_overlays -- immutable org-wide policies
stewardship_roles -- point-in-time governance roles
archive_records -- soft-delete audit trail
widgets.is_archived -- soft-delete flag
```
Migration: `Application/Migration/1743638400-ihf-phase8-federated-hub-maturity.sql`
## Routing Engine
`Application/Helper/RoutingEngine.hs``applyRoutingRules`:
```haskell
ruleMatches category mWidgetType rule =
categoryMatch && widgetTypeMatch
where
categoryMatch = isNothing rule.matchCategory || rule.matchCategory == Just category
widgetTypeMatch = isNothing rule.matchWidgetType ||
(isJust mWidgetType && rule.matchWidgetType == mWidgetType)
```
Null-inclusive matching: a rule with no `match_category` fires on any category.
Only the highest-priority active matching rule fires per candidate.
## Known Limitations
- `applies_to_hubs` on `FederatedPolicyOverlay` is stored as JSONB; Phase 8
does not enforce referential integrity between hub IDs in this column and the
`hubs` table. A future phase could validate on activation.
- `LineageInspectorAction` is widget-scoped. A fully generic artefact-scoped
lineage inspector (for decisions, deployments, etc.) is a Phase 9+ feature.
- Routing is evaluated on candidate creation and on manual `RouteNowAction`.
There is no background re-evaluation if rules change after candidates exist.
- Ownership records have no uniqueness constraint — multiple active ownerships
per widget are possible. The latest `effective_from` record is authoritative
by convention.
## IHF v0.1 Status
All eight phases of `specs/InteractionHubFrameworkSpecification_v0.1.md` are
now implemented in the reference IHP application. See
`specs/InteractionHubFrameworkSpecification_v0.2.md` for the planned Phases 912
roadmap (External API, Marketplace, AI Federation, Platform Memory).