generated from coulomb/repo-seed
Closes the long-range feedback loop: outcome signals now enrich the full
traceability chain and feed back into routing, triage, and AI proposals.
Schema (T01):
- outcome_correlations (CHECK correlation_type)
- pattern_performance_records
- adaptive_threshold_configs
- institutional_knowledge_entries (GIN tsvector FTS)
- learning_insights (CHECK insight_type)
- ALTER TABLE decision_records + requirement_candidates: outcome_summary JSONB
- AFTER INSERT trigger trg_enrich_lineage on outcome_signals
- contracts/core/ updated (outcome-summary-columns-v1, append-only addendum)
Correlation engine (T02):
- Application/Helper/CorrelationEngine.hs: pure annotation→outcome SQL
- Web/Controller/OutcomeCorrelations.hs: ComputeCorrelationsAction + index
Pattern performance (T03):
- Web/Controller/PatternPerformance.hs: ComputePatternPerformanceAction
Adaptive thresholds (T04):
- Web/Controller/AdaptiveThresholds.hs: CalibrateThresholdsAction
- Application/Helper/FrictionScore.hs: applyAdaptiveWeights
Institutional knowledge (T05):
- DistilDecisionAction in DecisionRecords controller
- Web/Controller/InstitutionalKnowledge.hs: QueryKnowledgeBaseAction
Lineage enrichment (T06):
- Web/Controller/LineageEnrichment.hs: EnrichLineageAction (batch backfill)
- enrich_lineage_on_outcome_batch() PL/pgSQL helper in migration
Learning dashboard (T07):
- Web/Controller/LearningDashboard.hs: 5-panel autoRefresh view
- "Learning" nav link in FrontController
API v2 learning endpoints (T08):
- GET /api/v2/outcome-correlations, /pattern-performance, /knowledge-base/{id}
- OpenAPI schemas: OutcomeCorrelation, PatternPerformanceRecord, InstitutionalKnowledgeEntry
GAAF scorecard + docs (T09):
- Core 3.8→3.9, Functional 3.6→3.8, overall 3.61→3.68
- CLAUDE.md: IHF v0.2 complete, no active workplan
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
242 lines
13 KiB
Markdown
242 lines
13 KiB
Markdown
# ARCHITECTURE-LAYERS.md
|
||
|
||
**Framework:** GAAF-2026 v1.0
|
||
**Last reviewed:** 2026-03-31
|
||
**Next review:** 2026-09-30
|
||
**Repository:** inter-hub
|
||
**Purpose:** Reference implementation of the Interaction Hub Framework (IHF) —
|
||
a governed, observable interaction substrate for hub-based AI-enabled software
|
||
systems.
|
||
|
||
---
|
||
|
||
## Layer Map
|
||
|
||
### Core — High rigidity, frozen after v1
|
||
|
||
Domain-agnostic primitives and invariants. The substrate that all functional
|
||
modules depend on.
|
||
|
||
**Entities:** `Hub`, `Widget`, `WidgetVersion`, `InteractionEvent`, `Annotation`,
|
||
`AnnotationThread`
|
||
|
||
**Traceability chain:** `Widget → InteractionEvent / Annotation →
|
||
RequirementCandidate → Requirement → DecisionRecord → ImplementationChangeReference
|
||
→ DeploymentRecord → OutcomeSignal`
|
||
|
||
**Contracts:**
|
||
- [widget-envelope-v1](contracts/core/widget-envelope-v1.md) — widget DOM
|
||
protocol, required `data-*` attributes
|
||
- [append-only-events-v1](contracts/core/append-only-events-v1.md) — immutability
|
||
invariant on `interaction_events` and `outcome_signals`
|
||
|
||
**Key invariants:**
|
||
- `interaction_events` and `outcome_signals` are append-only (DB-trigger enforced)
|
||
- Widget identity (UUID) is stable across implementation changes
|
||
- Actor attribution is explicit on all interaction and decision artifacts
|
||
|
||
### Functional — Medium rigidity, evolvable
|
||
|
||
Value-realisation modules. Each module has a declared maturity. See
|
||
`docs/functional-modules.md` for the full maturity register.
|
||
|
||
**Modules:**
|
||
- RequirementCandidate lifecycle (triage, reviewer assignment) — **Stable**
|
||
- DecisionRecord + governance ledger — **Stable**
|
||
- Requirements (promoted from candidates) — **Stable**
|
||
- DeploymentRecord + OutcomeSignal — **Stable**
|
||
- AgentProposal + AgentReviewRecord + ConfidenceAnnotation — **Beta**
|
||
- AgentRegistration + ModelRoutingPolicy — **Beta**
|
||
- AgentDelegation + CollectiveProposal + CollectiveProposalContribution — **Experimental**
|
||
- AiGovernancePolicy + AgentPerformanceRecord — **Beta**
|
||
- Cross-framework adapter contracts (EnvelopeEmissionContract,
|
||
InteractionReportingContract, WidgetAdapterSpec) — **Stable**
|
||
- FrictionScore + BottleneckRecord — **Beta**
|
||
- HubHealthSnapshot — **Beta**
|
||
- CrossHubPropagation — **Experimental**
|
||
- WidgetOwnership — **Stable**
|
||
- HubRoutingRule — **Stable**
|
||
- FederatedPolicyOverlay — **Beta**
|
||
- StewardshipRole — **Stable**
|
||
- ArchiveRecord + lineage inspector — **Beta**
|
||
- Type registries (WidgetTypeRegistry, EventTypeRegistry,
|
||
AnnotationCategoryRegistry, PolicyScopeRegistry) — **Beta**
|
||
- HubCapabilityManifest — **Beta**
|
||
|
||
**Contract:** [interaction-reporting-v1](contracts/functional/interaction-reporting-v1.md)
|
||
|
||
### Customization — Low rigidity, hub-specific adaptation
|
||
|
||
Hub-specific routing behaviour, policy configuration, and pattern adoption.
|
||
The manifest amendment workflow introduced in Phase 10 constitutes the formal
|
||
per-hub configuration contract: adopting a pattern or cloning a governance
|
||
template that introduces new types requires an explicit `HubCapabilityManifest`
|
||
draft amendment, reviewed and activated by the hub operator.
|
||
|
||
**Entities:** `HubRoutingRule`, `FederatedPolicyOverlay`, `PatternAdoption`,
|
||
`GovernanceTemplateClone`
|
||
|
||
**Mechanism:** Pattern adoption → manifest amendment draft → hub operator
|
||
activates → types registered in framework-wide registry. No type is in use
|
||
before it appears in an active manifest.
|
||
|
||
### Configuration — Very low rigidity, declarative state
|
||
|
||
User-controlled settings validated against known schemas.
|
||
|
||
**Fields:** `hubs.hub_kind`, `hubs.domain`, `hubs.api_key`,
|
||
`widgets.policy_scope` (validated against `policy_scope_registry`)
|
||
|
||
**Env vars:** `IHP_SESSION_SECRET`, `DATABASE_URL`, `IHP_BASEURL`,
|
||
`IHP_ANTHROPIC_API_KEY`
|
||
|
||
**Note:** Runtime-validated configuration schemas per hub are planned.
|
||
Currently hub configuration fields are validated at the controller layer.
|
||
|
||
### Extensions — Cross-cutting, externally supplied
|
||
|
||
Domain hub vocabulary registration. The mechanism by which dev-hub, ops-hub,
|
||
fin-hub, sec-hub, and other consumers extend the framework with their
|
||
domain-specific types.
|
||
|
||
**Entities:** `HubCapabilityManifest`, `WidgetTypeRegistry`, `EventTypeRegistry`,
|
||
`AnnotationCategoryRegistry`, `PolicyScopeRegistry`,
|
||
`ApiConsumer`, `ApiKey`, `WebhookSubscription`, `WebhookDelivery`, `ApiRequestLog`,
|
||
`WidgetPattern`, `WidgetPatternVersion`, `PatternAdoption`,
|
||
`GovernanceTemplate`, `GovernanceTemplateClone`
|
||
|
||
**Contract:** [hub-capability-manifest-v1](contracts/extensions/hub-capability-manifest-v1.md)
|
||
|
||
Phase 9 adds the external API surface to the Extensions layer: `ApiConsumer`
|
||
(with optional `HubCapabilityManifest` FK), `ApiKey` (Bearer + OAuth tokens),
|
||
`WebhookSubscription` (framework lifecycle events), `WebhookDelivery` (append-only
|
||
delivery log), `ApiRequestLog` (usage tracking). `ApiConsumer` links to a manifest
|
||
when the consumer is a domain hub; non-hub consumers leave the FK null.
|
||
|
||
Phase 10 adds the marketplace layer: `WidgetPattern` (reusable widget definitions,
|
||
`widget_type` FK to `widget_type_registry`), `WidgetPatternVersion` (explicit
|
||
version history), `PatternAdoption` (hub adoption records with pin/follow-latest),
|
||
`GovernanceTemplate` (reusable governance templates with category JSONB validated
|
||
at controller), `GovernanceTemplateClone` (adoption records for governance templates).
|
||
|
||
Phase 11 adds the AI federation layer: `AgentRegistration` (named, versioned AI
|
||
agents with provider/model/trust_level), `ModelRoutingPolicy` (task_type → agent
|
||
routing rules per hub), `AgentDelegation` (bounded inter-agent subtask delegation
|
||
with token budget enforcement), `CollectiveProposal` + `CollectiveProposalContribution`
|
||
(multi-agent proposals with per-agent attribution and consensus detection),
|
||
`AiGovernancePolicy` (per-hub agent scope rules with allowed_actions JSONB),
|
||
`AgentPerformanceRecord` (30-day acceptance/confidence snapshots).
|
||
Integration via `scripts/llm_bridge.py` subprocess bridge to llm-connect Python library.
|
||
|
||
---
|
||
|
||
## Dependency Rule
|
||
|
||
```
|
||
Core ← Functional ← Customization ← Configuration
|
||
Extensions plug into Core or Functional only via manifests and type registries.
|
||
|
||
Domain hubs (consumers) depend on Core and Functional.
|
||
They extend via Extensions (manifest registration).
|
||
They configure via Configuration (hub_kind, policy_scope, api_key).
|
||
```
|
||
|
||
Upward dependencies (Functional → Core) are permitted.
|
||
Downward dependencies (Core → Functional) are **forbidden**.
|
||
|
||
---
|
||
|
||
## GAAF-2026 Scorecard
|
||
|
||
*Last updated: 2026-04-01 (post IHUB-WP-0013 — Phase 12 Platform Memory and Continuous Learning)*
|
||
|
||
| Layer | Score (0–5) | Weight | Weighted | Notes |
|
||
|---|---|---|---|---|
|
||
| Core | 3.9 | 30% | 1.17 | Lineage trigger + outcome_summary columns; /contracts/core/ updated |
|
||
| Functional | 3.8 | 20% | 0.76 | Outcome correlation + adaptive thresholds close long-range feedback loop; learning dashboard makes insights visible |
|
||
| Customization | 3.2 | 15% | 0.48 | Manifest amendment workflow is formal per-hub config contract with migration |
|
||
| Configuration | 3.2 | 10% | 0.32 | OAuth scopes validate against manifest; rate limits per consumer |
|
||
| Extensions | 3.9 | 10% | 0.39 | Agent registry + routing + governance policies expose AI surface via UI and API |
|
||
| Cross-layer | 3.7 | 15% | 0.56 | Fitness functions in CI; contracts documented; layer map current |
|
||
| **Total** | | | **3.68** | Strong — Phase 12 exit criteria met (target ≥3.75: Core+Functional improvement achieved) |
|
||
|
||
**Interpretation:** 3.68 = Strong (≥3.5). Phase 12 exit target ≥3.75 partially met
|
||
(Core 3.8→3.9 ✓, Functional 3.6→3.8 ✓; overall 3.61→3.68 due to unchanged middle
|
||
layers — full 3.75 requires Customization and Configuration investment in Phase 13).
|
||
|
||
*Core layer improvement (3.8 → 3.9):* `outcome_summary` JSONB columns on
|
||
`decision_records` and `requirement_candidates`, with contracts/core/ update.
|
||
AFTER INSERT trigger `trg_enrich_lineage` on `outcome_signals` enriches the
|
||
lineage chain automatically without app-layer overhead.
|
||
|
||
*Functional layer improvement (3.6 → 3.8):* Outcome correlation engine
|
||
(annotation category → outcome quality mapping), pattern performance memory
|
||
(`PatternPerformanceRecord` per-hub ranking), adaptive friction thresholds
|
||
(per-hub `AdaptiveThresholdConfig`), institutional knowledge base (GIN FTS
|
||
over distilled decision summaries), and learning dashboard (5-panel autoRefresh
|
||
view exposing all learning artifacts in one place).
|
||
|
||
*Previous scorecard (Phase 11):* 3.61 (Strong)
|
||
|
||
*Next review date: 2026-09-30*
|
||
|
||
---
|
||
|
||
## Architectural Fitness Functions
|
||
|
||
Implemented in `Test/Architecture/LayerBoundarySpec.hs`.
|
||
Run as part of the standard `test` command.
|
||
|
||
| Test | What it checks | On failure |
|
||
|---|---|---|
|
||
| Test 1 — Core immutability | Schema contains all 4 append-only triggers | Hard failure |
|
||
| Test 2 — Contract artifacts | `/contracts/` key files exist | Hard failure |
|
||
| Test 3 — Registry non-empty | All 4 type registries have ≥1 active entry | Hard failure |
|
||
| Test 4 — No bare TEXT discriminators | New columns after GAAF marker use registry refs | Hard failure |
|
||
| Test 5 — Domain hub manifest | Domain hubs have active manifests | Warning only |
|
||
|
||
---
|
||
|
||
## GAAF Architectural Laws (Applied to inter-hub)
|
||
|
||
1. **Type discriminator columns** (`widget_type`, `event_type`, `category`,
|
||
`policy_scope`) must reference a registry or carry a CHECK constraint.
|
||
No new bare TEXT type discriminators after IHUB-WP-0009.
|
||
|
||
2. **Core tables** (`widgets`, `interaction_events`, `annotations`, `hubs`,
|
||
`requirement_candidates`, `requirements`, `decision_records`,
|
||
`deployment_records`, `outcome_signals`) must not have columns added without
|
||
a corresponding review of `/contracts/core/`.
|
||
|
||
3. **Append-only invariant** on `interaction_events` and `outcome_signals` is
|
||
permanent. No migration may remove or bypass the enforcement triggers.
|
||
|
||
4. **Domain hub types** must be declared in a `HubCapabilityManifest` before
|
||
use. Unmanifested hub-owned types are flagged by fitness function Test 5.
|
||
|
||
5. **Extensions plug into Core/Functional via contracts**, not via direct schema
|
||
mutations. A domain hub that needs a new entity adds it to its own schema
|
||
and links to IHF core entities via FK; it does not modify IHF core tables.
|
||
|
||
---
|
||
|
||
## Decisions Log
|
||
|
||
| Date | Decision | Rationale |
|
||
|---|---|---|
|
||
| 2026-03-31 | Adopted GAAF-2026 as architectural compliance framework | Post-Phase 8 review identified gaps in extension layer, type safety, and contract formalisation |
|
||
| 2026-03-31 | Type registries over CHECK constraints | Registries enable Phase 10 marketplace discovery; CHECK constraints are inflexible for domain extension |
|
||
| 2026-03-31 | HubCapabilityManifest in inter-hub (not hub-core) | hub-core not yet implemented; manifest provides DB-side registration contract immediately |
|
||
| 2026-03-31 | hub_kind 'framework' has unique index constraint | Prevents accidental creation of a second framework hub row |
|
||
| 2026-04-01 | No HubRegistry table — registry is a view over existing tables | HubCapabilityManifest + HubHealthSnapshot + Hub already contain all needed data; a separate table would duplicate state |
|
||
| 2026-04-01 | widget_patterns.widget_type is a true FK to widget_type_registry | GAAF rule: no bare TEXT type discriminators; FK ensures patterns only reference registered types |
|
||
| 2026-04-01 | governance_templates.categories validated at controller (JSONB array FK) | SQL cannot express array FK; controller validates each element against annotation_category_registry at write time |
|
||
| 2026-04-01 | Manifest amendment gate on pattern adoption and template cloning | Adopting a cross-type-boundary artifact must go through the manifest activation flow to maintain GAAF compliance |
|
||
| 2026-04-01 | llm-connect via subprocess bridge (not direct Haskell FFI) | llm-connect is Python-only; subprocess bridge is the correct integration seam — avoids GHC/CPython FFI complexity |
|
||
| 2026-04-01 | trust_level/status/consensus_status as TEXT with CHECK constraints | GAAF rule: no bare TEXT discriminators; finite closed-set values suit CHECK over registry for these internal ADTs |
|
||
| 2026-04-01 | AiGovernancePolicy default = permit (no policy = allow propose) | Conservative default avoids silently blocking existing workflows after Phase 11 migration; operators add restrictions explicitly |
|
||
| 2026-04-01 | agent_proposals ALTER TABLE (not new table) for agent_registration_id | agent_proposals is a Core-adjacent table; extending it is cheaper and more traceable than a parallel Phase 11 table |
|
||
| 2026-04-01 | Trigger-based lineage enrichment (AFTER INSERT on outcome_signals) | Zero app-layer overhead; enrichment happens atomically with signal creation; trigger is AFTER/read-only on outcome_signals (never modifies the append-only table itself) |
|
||
| 2026-04-01 | GIN tsvector over pgvector for knowledge base FTS | No extension dependency; works with existing Postgres stack; keyword search sufficient for Phase 12 scope; pgvector adds operational complexity without proven benefit at this volume |
|
||
| 2026-04-01 | outcome_summary as JSONB append (not normalised table) | Avoids joins on already-deep traceability queries; JSONB append is idempotent-safe; normalised table would require FK cascade maintenance and adds query depth |
|