generated from coulomb/repo-seed
Some checks failed
Test / test (push) Has been cancelled
Implements IHUB-WP-0009: closes four GAAF-2026 gaps before domain hub work begins. - TypeRegistry helper + controllers/views (hub_kind, hub_capability_manifest) - HubCapabilityManifest entity with validation and registry linkage - ARCHITECTURE-LAYERS.md + CI-enforced boundary contracts - Alembic migration 1743724800, fitness tests (Test/Architecture/) - GAAF spec, Operational Architecture spec, domain hub extension guide - Updates to CLAUDE.md, SCOPE.md, Schema.sql, Routes, FrontController, Types state_hub_sync: pending (tunnel was STALE at completion time; run fix-consistency) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
156 lines
5.0 KiB
Markdown
156 lines
5.0 KiB
Markdown
# Hub Capability Manifest Contract
|
|
|
|
**Name:** hub-capability-manifest
|
|
**Version:** 1.0
|
|
**Date:** 2026-03-31
|
|
**Status:** Active
|
|
**Layer:** Extensions
|
|
**Maturity:** Beta
|
|
|
|
---
|
|
|
|
## Purpose
|
|
|
|
The Hub Capability Manifest is the formal extension registration mechanism of
|
|
the IHF. It is the contract by which a domain hub (dev-hub, ops-hub, fin-hub,
|
|
sec-hub) declares the vocabulary it introduces to the framework: widget types,
|
|
event types, annotation categories, and policy scopes.
|
|
|
|
Without an active manifest, a domain hub is an unregistered participant. Its
|
|
widgets and events are accepted by the framework, but its type vocabulary is
|
|
not namespaced, not validated, and not discoverable in Phase 10's marketplace.
|
|
|
|
---
|
|
|
|
## Schema
|
|
|
|
```sql
|
|
CREATE TABLE hub_capability_manifests (
|
|
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL,
|
|
hub_id UUID NOT NULL UNIQUE REFERENCES hubs(id),
|
|
manifest_version TEXT NOT NULL DEFAULT '1.0',
|
|
declared_widget_types JSONB NOT NULL DEFAULT '[]',
|
|
declared_event_types JSONB NOT NULL DEFAULT '[]',
|
|
declared_annotation_categories JSONB NOT NULL DEFAULT '[]',
|
|
declared_policy_scopes JSONB NOT NULL DEFAULT '[]',
|
|
capability_description TEXT,
|
|
contact TEXT,
|
|
status TEXT NOT NULL DEFAULT 'draft',
|
|
activated_at TIMESTAMP WITH TIME ZONE,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL,
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL
|
|
);
|
|
```
|
|
|
|
---
|
|
|
|
## Registration Workflow
|
|
|
|
```
|
|
1. Create manifest in draft
|
|
↓
|
|
2. Declare types (edit declared_* arrays)
|
|
↓
|
|
3. Activate (ActivateManifestAction)
|
|
↓ ← auto-registers declared types into their registries
|
|
4. Active manifest governs the hub's vocabulary
|
|
```
|
|
|
|
### Step 1 — Create in draft
|
|
|
|
```
|
|
POST /HubCapabilityManifests/new?hubId=<hub-id>
|
|
```
|
|
|
|
One manifest per hub (UNIQUE constraint on `hub_id`). Creating a manifest
|
|
for a hub that already has one (in any status) requires retiring the existing
|
|
active manifest first.
|
|
|
|
### Step 2 — Declare types
|
|
|
|
While in `draft` status, edit the `declared_*` JSONB arrays. Each array
|
|
contains the string names of types the hub will own:
|
|
|
|
```json
|
|
{
|
|
"declared_widget_types": ["dev-pipeline-run", "dev-build-status"],
|
|
"declared_event_types": ["dev-pipeline-started", "dev-pipeline-failed"],
|
|
"declared_annotation_categories": ["dev-blocker", "dev-flaky-test"],
|
|
"declared_policy_scopes": ["dev-internal"]
|
|
}
|
|
```
|
|
|
|
**Naming convention**: domain-owned types should be prefixed with the domain
|
|
shortcode to prevent collisions (e.g. `dev-`, `fin-`, `sec-`, `ops-`).
|
|
Framework-level types (no prefix) are owned by inter-hub and shared by all hubs.
|
|
|
|
### Step 3 — Activate
|
|
|
|
```
|
|
POST /HubCapabilityManifests/ActivateManifest?hubCapabilityManifestId=<id>
|
|
```
|
|
|
|
On activation:
|
|
- For each name in `declared_widget_types`: insert into `widget_type_registry`
|
|
with `owner_hub_id = hub.id` if not already present.
|
|
- Same for `declared_event_types`, `declared_annotation_categories`,
|
|
`declared_policy_scopes`.
|
|
- If any declared name already exists in a registry with a **different**
|
|
`owner_hub_id`, activation is rejected with a conflict error.
|
|
- If any declared name exists with `owner_hub_id = NULL` (framework-level),
|
|
activation is rejected: framework types cannot be claimed by a domain hub.
|
|
- `status` is set to `active`, `activated_at` is set to `now()`.
|
|
|
|
---
|
|
|
|
## Invariants
|
|
|
|
1. **Type names are permanent.** Once a type name is registered (either via
|
|
seed or manifest activation), it cannot be deleted from the registry —
|
|
only deprecated. Other hubs may already depend on it.
|
|
|
|
2. **Activated manifests are read-only on declared arrays.** To add new types,
|
|
retire the manifest and create a new draft, or use `DraftAmendmentAction`
|
|
which creates an amended draft pending re-activation.
|
|
|
|
3. **One active manifest per hub.** The UNIQUE constraint on `hub_id` plus the
|
|
activation workflow enforce this.
|
|
|
|
4. **Framework types cannot be claimed.** Type names with `owner_hub_id = NULL`
|
|
are owned by the framework. A domain hub manifest that attempts to declare
|
|
an existing framework type name is rejected.
|
|
|
|
---
|
|
|
|
## Status Lifecycle
|
|
|
|
```
|
|
draft → active → retired
|
|
↓
|
|
(superseded by a new draft → active cycle)
|
|
```
|
|
|
|
A retired manifest's types remain in the registry. If the hub is decommissioned,
|
|
the types should be deprecated (not deleted) in the registry.
|
|
|
|
---
|
|
|
|
## Failure Modes
|
|
|
|
| Scenario | Behaviour |
|
|
|---|---|
|
|
| Duplicate type name (same hub) | Idempotent — skipped, not an error |
|
|
| Duplicate type name (different hub) | Activation rejected with conflict error |
|
|
| Framework type name claimed | Activation rejected |
|
|
| Edit of active manifest declared arrays | Rejected — manifest is read-only |
|
|
| Hub with no manifest creates hub-owned type | Warning in fitness function; types accepted but unmanifested |
|
|
|
|
---
|
|
|
|
## Implementation Reference
|
|
|
|
- Schema: `Application/Schema.sql` (added in IHUB-WP-0009-T05)
|
|
- Controller: `Web/Controller/HubCapabilityManifests.hs`
|
|
- Guide: `docs/domain-hub-extension-guide.md`
|
|
- Phase 10 dependency: Hub Registry = active manifests + health snapshots
|