generated from coulomb/repo-seed
feat(WP-0009): IHF GAAF Compliance Foundation — type registries, extension manifests, architectural contracts
Some checks failed
Test / test (push) Has been cancelled
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>
This commit is contained in:
199
docs/domain-hub-extension-guide.md
Normal file
199
docs/domain-hub-extension-guide.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# Domain Hub Extension Guide
|
||||
|
||||
**Framework:** IHF v0.2 + GAAF-2026 | **Applies to:** Phase 9+ domain hub implementations
|
||||
|
||||
This guide is for developers building a new domain hub (dev-hub, ops-hub, fin-hub, sec-hub)
|
||||
on top of inter-hub. It covers what the framework provides out of the box, how to register
|
||||
your domain's vocabulary, and how to stay compatible across framework upgrades.
|
||||
|
||||
---
|
||||
|
||||
## What inter-hub Provides
|
||||
|
||||
Every domain hub built on inter-hub inherits the following services without any setup:
|
||||
|
||||
| Service | What it gives you |
|
||||
|---------|------------------|
|
||||
| **Event capture** | `POST /api/v1/interaction-events` — record user interactions with a hub API key |
|
||||
| **Annotation** | Structured feedback on any widget (friction, defects, wishes, policy concerns) |
|
||||
| **Requirement candidates** | Automatic escalation from annotations; triage queue and lifecycle |
|
||||
| **Governance ledger** | Decision records, rationale, and approved/rejected outcomes |
|
||||
| **AI assistance** | Claude-powered summarization and requirement drafting via AgentProposal |
|
||||
| **Deployment + signals** | DeploymentRecord → OutcomeSignal; regression detection |
|
||||
| **Observability** | FrictionScore, BottleneckRecord, HubHealthSnapshot |
|
||||
| **Federation** | CrossHubPropagation, WidgetOwnership, FederatedPolicyOverlay |
|
||||
| **Cross-framework adapters** | EnvelopeEmissionContract, InteractionReportingContract |
|
||||
| **Archive + lineage** | Soft-delete with full lineage inspector |
|
||||
|
||||
None of these require domain-specific configuration. They are activated as soon as you
|
||||
create a `Hub` row and register `Widget` records.
|
||||
|
||||
---
|
||||
|
||||
## Extension Registration in Three Steps
|
||||
|
||||
Domain hubs introduce vocabulary that the framework does not know about at installation
|
||||
time: domain-specific widget types (e.g. `dev-pipeline-run`), event types
|
||||
(e.g. `fin-budget-alert-dismissed`), annotation categories, and policy scopes.
|
||||
|
||||
You **must** register this vocabulary before widgets or events using these names can
|
||||
be validated by the framework.
|
||||
|
||||
### Step 1 — Create a Hub row
|
||||
|
||||
```sql
|
||||
-- Via the IHP UI at /hubs/new, or via a migration:
|
||||
INSERT INTO hubs (id, name, slug, domain, hub_kind)
|
||||
VALUES (uuid_generate_v4(), 'Dev Hub', 'dev-hub', 'dev.example.com', 'domain');
|
||||
```
|
||||
|
||||
- `hub_kind` must be `'domain'` for bounded domain hubs, or `'shared'` for
|
||||
cross-domain service hubs. `'framework'` is reserved for inter-hub itself.
|
||||
- There is exactly one `framework` hub (enforced by a unique partial index).
|
||||
|
||||
### Step 2 — Create a HubCapabilityManifest in draft
|
||||
|
||||
Navigate to **Extensions → New Manifest** in the inter-hub UI, or via the API:
|
||||
|
||||
```
|
||||
POST /HubCapabilityManifests (CreateHubCapabilityManifestAction)
|
||||
hubId=<your hub id>
|
||||
capabilityDescription=Developer toolchain interaction tracking
|
||||
contact=platform-team@example.com
|
||||
```
|
||||
|
||||
In the manifest **Edit** view, declare your type names as JSON arrays:
|
||||
|
||||
```json
|
||||
// Declared Widget Types
|
||||
["dev-pipeline-run", "dev-pr-review", "dev-build-status"]
|
||||
|
||||
// Declared Event Types
|
||||
["dev-pipeline-triggered", "dev-build-failed", "dev-pr-approved"]
|
||||
|
||||
// Declared Annotation Categories
|
||||
["dev-flaky-test", "dev-merge-concern"]
|
||||
|
||||
// Declared Policy Scopes
|
||||
["dev-ci-policy"]
|
||||
```
|
||||
|
||||
### Step 3 — Activate the manifest
|
||||
|
||||
Click **Activate** in the manifest UI, or:
|
||||
|
||||
```
|
||||
GET /HubCapabilityManifests/{id}/activate (ActivateManifestAction)
|
||||
```
|
||||
|
||||
On activation, the framework:
|
||||
1. Validates that each declared type name is either unregistered or already owned by your hub.
|
||||
2. If any name is owned by a different hub, activation is blocked with a conflict message.
|
||||
3. If all names are clear, each declared name is inserted into its registry table
|
||||
(`widget_type_registry`, `event_type_registry`, etc.) with `owner_hub_id = your hub id`.
|
||||
4. The manifest `status` transitions from `draft` → `active`.
|
||||
|
||||
After activation, your types are:
|
||||
- **Validated** by all IHF controllers (widgets, annotations, routing rules, API events)
|
||||
- **Enumerable** by the Phase 9 OpenAPI specification
|
||||
- **Discoverable** by other hubs via the Extensions page
|
||||
|
||||
---
|
||||
|
||||
## Naming Your Types
|
||||
|
||||
| Context | Convention | Example |
|
||||
|---------|-----------|---------|
|
||||
| **Framework-level types** | No prefix, lowercase-hyphenated | `chart`, `form`, `clicked` |
|
||||
| **Domain-owned types** | Prefixed with domain shortcode | `dev-pipeline-run`, `fin-budget-alert` |
|
||||
| **Shared hub types** | Prefixed with service shortcode | `state-workstream`, `gov-decision` |
|
||||
|
||||
**Rules:**
|
||||
- Names are permanent — once registered, they cannot be deleted or renamed.
|
||||
Use `status = 'deprecated'` with a `deprecated_in_favour_of` pointer if you need to
|
||||
transition to a new name.
|
||||
- Names are globally unique per registry table. Two hubs cannot own the same name.
|
||||
Use domain prefixes to avoid collisions.
|
||||
- Names must be lowercase. Hyphens are preferred over underscores for widget/event types;
|
||||
underscores are accepted for annotation categories and policy scopes.
|
||||
|
||||
---
|
||||
|
||||
## Using Framework-Level Types
|
||||
|
||||
Framework-level types (those with `owner_hub_id IS NULL`) are available to all hubs without
|
||||
any registration. You do not need to declare them in your manifest.
|
||||
|
||||
Examples of framework-level widget types: `chart`, `form`, `table`, `action`, `panel`, `nav`
|
||||
Examples of framework-level event types: `clicked`, `viewed`, `submitted`, `dismissed`, `errored`
|
||||
|
||||
Check the Type Registries UI (`/TypeRegistries/WidgetTypes`) to see all active framework types
|
||||
before creating domain-specific alternatives.
|
||||
|
||||
---
|
||||
|
||||
## Cross-Hub Routing
|
||||
|
||||
If your domain hub should receive requirement candidates routed from other hubs, configure
|
||||
`HubRoutingRule` entries:
|
||||
|
||||
```
|
||||
POST /HubRoutingRules (CreateHubRoutingRuleAction)
|
||||
sourceHubId=<framework hub>
|
||||
targetHubId=<your domain hub id>
|
||||
matchCategory=dev-flaky-test
|
||||
priority=10
|
||||
```
|
||||
|
||||
The `matchCategory` and `matchWidgetType` fields are validated against their registries.
|
||||
You must activate your manifest before creating routing rules that reference your domain types.
|
||||
|
||||
---
|
||||
|
||||
## Interpreting Maturity Labels
|
||||
|
||||
When depending on IHF modules in your domain hub, check `docs/functional-modules.md`
|
||||
for the current maturity of each module:
|
||||
|
||||
| Maturity | What it means for your hub |
|
||||
|----------|--------------------------|
|
||||
| **Stable** | Safe to depend on. Breaking changes require a major version bump with migration path. |
|
||||
| **Beta** | Core functionality is solid but edge-case fields or computation details may change with a minor-version notice. Suitable for production with awareness. |
|
||||
| **Experimental** | Internal prototyping only. May change without notice. Do not build production features on Experimental modules. |
|
||||
| **Deprecated** | Will be removed in the next major version. A replacement is documented in the relevant contract file. |
|
||||
|
||||
The `maturity` badge is displayed on contract show pages in the inter-hub UI.
|
||||
|
||||
---
|
||||
|
||||
## FAQ
|
||||
|
||||
**Can two hubs declare the same type name?**
|
||||
No. Type names are globally unique per registry. Activation order determines ownership.
|
||||
If you need a name that another hub owns, coordinate with that hub's contact to either
|
||||
share the type (they keep ownership, you use it) or use a domain-prefixed variant.
|
||||
|
||||
**Can a type be renamed?**
|
||||
No. Names are permanent. To transition: deprecate the old name with `deprecated_in_favour_of`
|
||||
pointing to the new name, then register the new name (via a new manifest entry or the
|
||||
Type Registry UI).
|
||||
|
||||
**Can a hub retire its manifest?**
|
||||
Yes. Retiring a manifest sets its status to `retired`; the hub's types remain in registries
|
||||
and continue to validate. Retiring is appropriate when a hub is decommissioned or merged.
|
||||
Orphaned types (owned by a retired hub's manifest) should be reassigned via the
|
||||
Type Registry UI or deprecated.
|
||||
|
||||
**Do I need a manifest if I only use framework-level types?**
|
||||
No. A manifest is only needed if your hub introduces new type names. If you use only
|
||||
existing framework types, you can create widgets and events immediately.
|
||||
|
||||
**What if my manifest activation fails with a conflict?**
|
||||
The activation endpoint returns the conflicting type names and which hub owns them.
|
||||
Either rename your types (before activation; names in a draft manifest can still be changed)
|
||||
or coordinate with the owning hub.
|
||||
|
||||
**Can I add new types to an active manifest?**
|
||||
Currently, activated manifests are read-only on the `declared_*` arrays. The amendment
|
||||
workflow is: retire the active manifest, create a new draft, declare all types (old + new),
|
||||
activate. A `DraftAmendmentAction` that merges types without retiring is planned for Phase 10.
|
||||
115
docs/functional-modules.md
Normal file
115
docs/functional-modules.md
Normal file
@@ -0,0 +1,115 @@
|
||||
# IHF Functional Module Maturity Register
|
||||
|
||||
**Framework:** GAAF-2026 | **Last reviewed:** 2026-03-31 | **Next review:** 2026-09-30
|
||||
|
||||
This document is the authoritative maturity register for all IHF functional modules.
|
||||
Maturity labels are defined in `contracts/functional/module-maturity-labels.md`.
|
||||
|
||||
---
|
||||
|
||||
## Module Registry
|
||||
|
||||
| Module | Phase | Maturity | Stability Guarantee | Deprecation Policy |
|
||||
|--------|-------|----------|--------------------|--------------------|
|
||||
| RequirementCandidate lifecycle | Phase 2 | **Stable** | Schema and controller API frozen | Major version only |
|
||||
| DecisionRecord + governance ledger | Phase 3 | **Stable** | Schema and controller API frozen | Major version only |
|
||||
| DeploymentRecord + OutcomeSignal | Phase 4 | **Stable** | Append-only invariant permanent | Major version only |
|
||||
| AgentProposal + review workflow | Phase 5 | **Beta** | Core fields stable; confidence model may extend | Minor version notice |
|
||||
| Cross-framework adapter contracts | Phase 6 | **Stable** | EnvelopeEmissionContract v1.0 immutable | Superseding contract version only |
|
||||
| FrictionScore + BottleneckRecord | Phase 7 | **Beta** | Computation algorithm may improve | Minor version notice |
|
||||
| HubHealthSnapshot | Phase 7 | **Beta** | Snapshot schema stable; score formula may change | Minor version notice |
|
||||
| CrossHubPropagation | Phase 7 | **Experimental** | Pattern detection logic actively evolving | No notice required |
|
||||
| WidgetOwnership + routing | Phase 8 | **Stable** | Ownership audit pattern permanent | Major version only |
|
||||
| FederatedPolicyOverlay | Phase 8 | **Beta** | Activation immutability permanent; scope model may extend | Minor version notice |
|
||||
| StewardshipRole | Phase 8 | **Stable** | Point-in-time audit pattern permanent | Major version only |
|
||||
| ArchiveRecord + lineage inspector | Phase 8 | **Beta** | Soft-delete pattern stable; lineage query may deepen | Minor version notice |
|
||||
| Type registries (widget, event, category, policy scope) | GAAF WP-0009 | **Beta** | Schema stable; seed vocabulary additive only | Additive additions only; no removal |
|
||||
| HubCapabilityManifest | GAAF WP-0009 | **Beta** | Activation semantics stable; manifest protocol may version | Minor version notice |
|
||||
|
||||
---
|
||||
|
||||
## Module Details
|
||||
|
||||
### RequirementCandidate Lifecycle
|
||||
**Phase introduced:** Phase 2
|
||||
**Tables:** `requirement_candidates`
|
||||
**Stability:** Stable — schema will not change within major version. Validation logic (status transitions: `open → accepted/rejected`) is frozen.
|
||||
**Known limitations:** No formal state machine enforcement in the DB; status is TEXT constrained only at the controller layer.
|
||||
**Not guaranteed:** The `category` field was previously validated against a hardcoded list; as of GAAF WP-0009 it is validated against `annotation_category_registry`. Applications querying directly may see new category values as the registry grows.
|
||||
|
||||
### DecisionRecord + Governance Ledger
|
||||
**Phase introduced:** Phase 3
|
||||
**Tables:** `decision_records`
|
||||
**Stability:** Stable — `requirement_id`, `decided_by`, `decided_at`, `outcome`, `rationale` are permanent.
|
||||
**Not guaranteed:** The `outcome_signals` analysis may add new computed fields in `GAAF` analysis helpers.
|
||||
|
||||
### DeploymentRecord + OutcomeSignal
|
||||
**Phase introduced:** Phase 4
|
||||
**Tables:** `deployment_records`, `outcome_signals`
|
||||
**Stability:** Stable — `outcome_signals` is append-only (DB trigger enforced). Signal types are an extensible vocabulary.
|
||||
**Not guaranteed:** Signal aggregation helpers may change computation logic.
|
||||
|
||||
### AgentProposal + Review Workflow
|
||||
**Phase introduced:** Phase 5
|
||||
**Tables:** `agent_proposals`, `agent_review_records`
|
||||
**Stability:** Beta — `proposal_type`, `content`, `model_ref`, `status` are stable. The `confidence` scoring model may be extended with additional fields.
|
||||
**Not guaranteed:** Model reference format may evolve as new Claude models are released.
|
||||
|
||||
### Cross-Framework Adapter Contracts
|
||||
**Phase introduced:** Phase 6
|
||||
**Tables:** `envelope_emission_contracts`, `interaction_reporting_contracts`, `widget_adapter_specs`
|
||||
**Stability:** Stable — `EnvelopeEmissionContract v1.0` is immutable. New versions are additive and published as new rows.
|
||||
**Not guaranteed:** The `maturity` column was added in GAAF WP-0009; existing tooling may not surface this badge.
|
||||
|
||||
### FrictionScore + BottleneckRecord
|
||||
**Phase introduced:** Phase 7
|
||||
**Tables:** `friction_scores`, `bottleneck_records`
|
||||
**Stability:** Beta — schema is stable. The `score` computation algorithm in `Application.Helper.FrictionScore` may be tuned without notice.
|
||||
**Not guaranteed:** Absolute score values are not stable across algorithm versions; use comparisons within a single version window.
|
||||
|
||||
### HubHealthSnapshot
|
||||
**Phase introduced:** Phase 7
|
||||
**Tables:** `hub_health_snapshots`
|
||||
**Stability:** Beta — snapshot schema stable. The composite health score formula may change in Phase 9+ as new signals are added.
|
||||
**Not guaranteed:** Historical snapshots retain the score at computation time; they will not be recalculated retroactively.
|
||||
|
||||
### CrossHubPropagation
|
||||
**Phase introduced:** Phase 7
|
||||
**Tables:** `cross_hub_propagations`
|
||||
**Stability:** Experimental — pattern detection logic is actively being refined. Schema fields may be renamed or retyped.
|
||||
**Not guaranteed:** Detection heuristics, pattern names, and score thresholds will change without notice.
|
||||
|
||||
### WidgetOwnership + Routing
|
||||
**Phase introduced:** Phase 8
|
||||
**Tables:** `widget_ownerships`, `hub_routing_rules`
|
||||
**Stability:** Stable — ownership audit pattern (point-in-time `owned_since`/`owned_until`) is permanent. Routing rule schema is stable.
|
||||
**Not guaranteed:** As of GAAF WP-0009, `match_category` and `match_widget_type` are now validated against type registries; routing rules using unregistered type names will fail validation.
|
||||
|
||||
### FederatedPolicyOverlay
|
||||
**Phase introduced:** Phase 8
|
||||
**Tables:** `federated_policy_overlays`
|
||||
**Stability:** Beta — activation immutability is permanent (activated overlays cannot be edited). The scope model (source/target hub relationships) may extend.
|
||||
**Not guaranteed:** Policy overlay conflict detection heuristics may change.
|
||||
|
||||
### StewardshipRole
|
||||
**Phase introduced:** Phase 8
|
||||
**Tables:** `stewardship_roles`
|
||||
**Stability:** Stable — the point-in-time role audit pattern is permanent. Role type vocabulary is additive.
|
||||
|
||||
### ArchiveRecord + Lineage Inspector
|
||||
**Phase introduced:** Phase 8
|
||||
**Tables:** `archive_records`
|
||||
**Stability:** Beta — soft-delete pattern is stable. Lineage query depth and the `lineage` JSONB structure may be extended.
|
||||
**Not guaranteed:** Deep lineage graph queries may become paginated in Phase 9+.
|
||||
|
||||
### Type Registries
|
||||
**Phase introduced:** GAAF WP-0009
|
||||
**Tables:** `widget_type_registry`, `event_type_registry`, `annotation_category_registry`, `policy_scope_registry`
|
||||
**Stability:** Beta — schema stable. Framework seed vocabulary is permanent (names cannot be removed, only deprecated). Domain hub vocabulary grows as manifests are activated.
|
||||
**Not guaranteed:** Registry UI and bulk import APIs are planned for Phase 10 and will extend the controller surface.
|
||||
|
||||
### HubCapabilityManifest
|
||||
**Phase introduced:** GAAF WP-0009
|
||||
**Tables:** `hub_capability_manifests`
|
||||
**Stability:** Beta — activation semantics (draft → active → retired, type auto-registration on activation, read-only after activation) are permanent.
|
||||
**Not guaranteed:** The manifest protocol version (`manifest_version` field) will be bumped if the activation semantics change. Amendment workflow (currently manual retire + new draft) may be replaced by a `DraftAmendmentAction` in Phase 10.
|
||||
Reference in New Issue
Block a user