Files
inter-hub/Web/View/StaticPages/ExtensionGuide.hs
Bernd Worsch c40f11d657 fix(WP-0017/E3): Layer 3 error fixes — controllers and views
Fix compilation errors across 6 controllers and 29 views: import cleanup,
ResponseException pattern for API auth, type fixes, unused import removal.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 23:40:31 +00:00

151 lines
8.8 KiB
Haskell

module Web.View.StaticPages.ExtensionGuide where
import Web.View.Prelude
data ExtensionGuideView = ExtensionGuideView
instance View ExtensionGuideView where
html ExtensionGuideView = [hsx|
<div class="max-w-4xl mx-auto py-10 px-6">
<div class="mb-8">
<a href={LandingAction} class="text-sm text-indigo-600 hover:underline"> Home</a>
<h1 class="text-3xl font-bold text-gray-900 mt-3 mb-2">Domain Hub Extension Guide</h1>
<p class="text-gray-500">
How to build and register a domain hub extension: HubCapabilityManifest,
type registry entries, hub-owned widget types, and hub-scoped controllers.
</p>
</div>
{-- Overview --}
<section class="mb-10">
<h2 class="text-xl font-semibold text-gray-800 mb-3">Overview</h2>
<p class="text-gray-600 mb-3">
inter-hub provides the governance substrate. Domain hubs (dev-hub, ops-hub, fin-hub, sec-hub)
extend it by registering their own capability manifests and type discriminators.
This keeps core tables stable while allowing domain-specific specialisation.
</p>
<div class="bg-amber-50 border border-amber-200 rounded-lg p-4 text-sm text-amber-800">
<strong>GAAF Rule 2:</strong> New hub-owned types must be declared in the hub's
<code class="bg-amber-100 px-1 rounded">HubCapabilityManifest</code> before use.
Register via the Extensions admin UI before creating any hub-owned widget types.
</div>
</section>
{-- Step 1: Create a Hub --}
<section class="mb-10">
<h2 class="text-xl font-semibold text-gray-800 mb-3">{stepBadge "1"} Create a Hub</h2>
<p class="text-gray-600 mb-3">
Navigate to <a href={HubsAction} class="text-indigo-600 hover:underline">Management UI Hubs</a>
and create a new hub. Each hub has a <code class="bg-gray-100 px-1 rounded text-sm">slug</code>
that will prefix its owned types (e.g. <code>dev.code-review</code>).
</p>
</section>
{-- Step 2: Register a HubCapabilityManifest --}
<section class="mb-10">
<h2 class="text-xl font-semibold text-gray-800 mb-3">{stepBadge "2"} Register a HubCapabilityManifest</h2>
<p class="text-gray-600 mb-3">
A <strong>HubCapabilityManifest</strong> is the DB-side contract for a domain hub.
Go to <a href={HubCapabilityManifestsAction} class="text-indigo-600 hover:underline">Extensions</a>
and create a manifest for your hub. Set status to <code class="bg-gray-100 px-1 rounded text-sm">active</code>.
</p>
<p class="text-sm text-gray-500">
The manifest includes: <code>hubId</code>, <code>manifestVersion</code>,
<code>capabilitySchema</code> (JSON), and an optional <code>apiEndpointBase</code>.
It is the anchor point for per-consumer API keys in Phase 9.
</p>
</section>
{-- Step 3: Register type discriminators --}
<section class="mb-10">
<h2 class="text-xl font-semibold text-gray-800 mb-3">{stepBadge "3"} Register Type Discriminators</h2>
<p class="text-gray-600 mb-3">
Before creating widgets of a new type, register the type in the appropriate registry.
Go to <a href={WidgetTypeRegistryAction} class="text-indigo-600 hover:underline">Registries</a>:
</p>
<ul class="text-sm text-gray-600 space-y-1 list-disc list-inside mb-3">
<li><strong>Widget Type Registry</strong> new widget types your hub will own</li>
<li><strong>Event Type Registry</strong> custom interaction event types</li>
<li><strong>Annotation Category Registry</strong> custom annotation categories</li>
<li><strong>Policy Scope Registry</strong> custom policy sensitivity scopes</li>
</ul>
<div class="bg-gray-50 border border-gray-200 rounded-lg p-4 text-sm text-gray-600">
Set <code>owner_hub_id</code> to your hub. Once registered, your hub-scoped code
can create widgets of that type and the type will appear in the marketplace.
</div>
</section>
{-- Step 4: Create widgets --}
<section class="mb-10">
<h2 class="text-xl font-semibold text-gray-800 mb-3">{stepBadge "4"} Create Widgets</h2>
<p class="text-gray-600 mb-3">
With the type registered, create widgets via the
<a href={WidgetsAction} class="text-indigo-600 hover:underline">Widgets</a> page
or the API:
</p>
<div class="bg-gray-900 rounded-lg p-4 text-sm font-mono text-green-400">
POST /api/v2/widgets<br/>
<span class="text-gray-400">&#123; "name": "PR Review Widget",<br/>
&nbsp;&nbsp;"widgetType": "dev.code-review",<br/>
&nbsp;&nbsp;"hubId": "...",<br/>
&nbsp;&nbsp;"viewContext": "pull-request-sidebar" &#125;</span>
</div>
</section>
{-- Step 5: Publish a widget pattern --}
<section class="mb-10">
<h2 class="text-xl font-semibold text-gray-800 mb-3">{stepBadge "5"} Publish a Widget Pattern (optional)</h2>
<p class="text-gray-600 mb-3">
If your widget design is reusable, publish it to the
<a href={MarketplaceDashboardAction} class="text-indigo-600 hover:underline">Widget Marketplace</a>.
Other hubs can adopt it and pin to specific versions. Patterns support
semantic versioning and adoption tracking.
</p>
</section>
{-- Step 6: AI agent integration --}
<section class="mb-10">
<h2 class="text-xl font-semibold text-gray-800 mb-3">{stepBadge "6"} Connect an AI Agent (Phase 11)</h2>
<p class="text-gray-600 mb-3">
Register an <a href={AgentRegistrationsAction} class="text-indigo-600 hover:underline">AgentRegistration</a>
for your hub, then create a
<a href={ModelRoutingPoliciesAction} class="text-indigo-600 hover:underline">ModelRoutingPolicy</a>
to route task types to specific models or agents.
Agents can draft Requirements, propose governance decisions, and participate in
CollectiveProposals.
</p>
</section>
{-- GAAF rules reminder --}
<section class="mb-10">
<h2 class="text-xl font-semibold text-gray-800 mb-3">GAAF Architecture Rules (Summary)</h2>
<div class="space-y-2 text-sm">
{ruleBox "1" "Type discriminator columns must reference a registry table or carry a CHECK constraint. No bare TEXT for new type discriminators."}
{ruleBox "2" "New hub-owned types must be declared in the hub's HubCapabilityManifest before use."}
{ruleBox "3" "Core tables (widgets, interaction_events, annotations, hubs) must not have new columns without updating /contracts/core/."}
{ruleBox "4" "Append-only invariant on interaction_events and outcome_signals is permanent. Never bypass those triggers."}
</div>
</section>
<div class="flex gap-4 text-sm mt-6">
<a href={TutorialAction} class="text-indigo-600 hover:underline"> Developer Tutorial</a>
<a href={CapabilitiesAction} class="text-indigo-600 hover:underline">Full Capabilities </a>
<a href={HubsAction} class="text-indigo-600 hover:underline">Management UI </a>
</div>
</div>
|]
where
stepBadge n = [hsx|
<span class="inline-flex items-center justify-center w-7 h-7 rounded-full bg-indigo-600 text-white text-sm font-bold mr-2">
{n :: Text}
</span>
|]
ruleBox n desc = [hsx|
<div class="flex gap-3 bg-white border border-gray-200 rounded-lg p-3">
<div class="w-6 h-6 rounded-full bg-amber-100 text-amber-800 flex items-center justify-center text-xs font-bold flex-shrink-0">
{n :: Text}
</div>
<p class="text-gray-600">{desc :: Text}</p>
</div>
|]