Capability Management
Capability Management
1. Executive Summary & Objective
In SiteSwarm, a single monorepo powers multiple independent client web applications. To maintain engineering velocity while preserving bespoke client quality, each client application declares and configures its active capabilities in a declarative Client Manifest (swarm.config.ts).
Capability Management serves three core objectives:
- Standardized Capability Reuse: Enables client applications to connect and configure shared platform capabilities rather than re-implementing common infrastructure.
- Clear Hosting Boundaries: Distinguishes between capabilities hosted alongside the client application as a dedicated instance (
app-hosted) and capabilities hosted centrally by the platform that applications plug into (platform-hosted). - Cross-Fleet Rationalization: Catalogs bespoke client functionality (
custom) so overlapping implementations across clients can be audited at a macro level and rationalized into reusable platform capabilities over time.
2. Core Concepts & Taxonomy
flowchart TD subgraph Catalog["Platform Capability Catalog"] C_CMS["CMS Capability\n(app-hosted)"] C_Critique["Critiques Capability\n(platform-hosted)"] C_Inquiries["Inquiries Capability\n(platform-hosted)"] end
subgraph Manifest["Sample Client Manifest (swarm.config.ts)"] M_CMS["cms:\n config: { mediaUploads: true }"] M_Critique["critiques:\n config: { enabled: true }"] M_Inquiries["inquiries:\n options: { provider: 'turnstile' }"] end
subgraph Runtime["Runtime Hosting Boundaries"] AppHosted["App-Hosted CMS Instance\n(Dedicated to Client App)"] App["Client Application Worker\n(apps/*)"] PlatCritique["Platform Critiques Service\n(Shared services/critique)"] PlatInquiries["Platform Inquiries Service\n(Shared services/inquiries)"] end
C_CMS -.-> M_CMS C_Critique -.-> M_Critique C_Inquiries -.-> M_Inquiries
M_CMS ==>|"1. App-Hosted"| AppHosted App <--> AppHosted M_Critique ==>|"2. Platform-Hosted Plug-in"| App App <--> PlatCritique M_Inquiries ==>|"2. Platform-Hosted Plug-in"| App App <--> PlatInquiries2.1 Capability Types
| Capability Type | Identifier | Description | Lifecycle & Purpose |
|---|---|---|---|
| App-Hosted Capability | 'app-hosted' |
A reusable platform capability package whose runtime and storage are hosted alongside the client application as a dedicated instance (e.g., Content Management / CMS). | Centrally maintained as a platform package; deployed as an isolated instance per subscribing client app. |
| Platform-Hosted Capability | 'platform-hosted' |
A reusable platform capability package backed by a central platform service that the client application plugs into (e.g., Customer Inquiries, Design Critiques). | Centrally operated on shared platform infrastructure; client apps connect via lightweight SDKs, bindings, or direct edge endpoints. |
| Custom Capability | 'custom' |
Bespoke business logic written specifically for a single client’s unique requirements. | Isolated to the client application; cataloged in the manifest so we can run big-picture audits across the fleet to identify overlapping bespoke capabilities and rationalize them into platform capabilities in the future. |
2.2 Canonical Platform Capabilities Catalog
| Capability Name | Package | Type | Runtime Backing / Ingress | Description | Living Architectural Spec |
|---|---|---|---|---|---|
cms |
@siteswarm/cms |
'app-hosted' |
Dedicated Worker B isolate & client D1/R2 storage | Headless content management for announcements, hours, specials, and media assets. | MULTI_WORKER_PLATFORM_SERVICES.md |
critiques |
@siteswarm/critique |
'platform-hosted' |
Central services/critique (Worker RPC + Authenticated REST) |
In-situ visual and editorial review dock persisting pinned defects across preview environments. | CRITIQUE_CAPABILITY.md |
inquiries |
@siteswarm/inquiries |
'platform-hosted' |
Central services/inquiries (Dual-Ingress: Direct HTTP + Worker RPC) |
Headless customer inquiry intake, invisible Cloudflare Turnstile verification, honeypot spam protection, and triage state management. | INQUIRIES_PLATFORM_SERVICE.md |
2.3 Inquiries Dual-Ingress Architecture
The inquiries capability supports dual-ingress architecture to accommodate both rich server-rendered forms (Astro SSR API endpoints) and ultra-lean, static-first storefronts:
flowchart TD subgraph BrowserClient["Browser Client (Storefront DOM)"] BrowserForm["Storefront Form Markup\n(mountInquiryForm controller)"] end
subgraph ClientWorker["Client Application Worker (apps/*)"] SSRRoute["Astro Edge API Route\n(POST /api/submit-inquiry)"] end
subgraph PlatformService["Central Platform Inquiries Service (services/inquiries)"] direction TB HttpIngress["HTTP Ingress Router\n(POST /api/inquiries)\nDynamic CORS Allowlist"] RpcIngress["WorkerEntrypoint RPC\n(submitInquiry, getInquiry, updateInquiryStatus)\nZero Network Latency"] DomainService["InquiryDomainService\n• Silent Honeypot Trap (Zero-Row Absorbed)\n• Cloudflare Turnstile Server Validation\n• Multi-Tenant Isolation Enforcement"] D1Storage[("Cloudflare D1 SQLite\nsiteswarm-inquiries-db\nCompound Index: (tenant_id, created_at)")]
HttpIngress --> DomainService RpcIngress --> DomainService DomainService --> D1Storage end
BrowserForm ==>|"Ingress Path A: Direct Browser HTTP\n(POST https://inquiries.jacobmiller22.com/api/inquiries)"| HttpIngress BrowserForm -->|"Ingress Path B: Form POST via Client App"| SSRRoute SSRRoute ==>|"Worker-to-Worker Service Binding RPC\n(env.INQUIRIES_SERVICE.submitInquiry)"| RpcIngress- Ingress Path A: Direct Browser HTTP (
POST /api/inquiries):- The browser mounts the headless form controller (
@siteswarm/inquiries/client) and submits directly tohttps://inquiries.jacobmiller22.com/api/inquiries. - The platform service verifies the request
Originagainst dynamic CORS allowlists, validates the Cloudflare Turnstile token, traps spam bots silently, and writes directly to central D1 SQLite. - Eliminates unnecessary proxy compute in the client application worker and ensures form submissions succeed even if the client application is deployed statically.
- The browser mounts the headless form controller (
- Ingress Path B: Worker-to-Worker RPC (
INQUIRIES_SERVICE):- The client application exposes an edge API route (
/api/submit-inquiry) that invokes the bound service via Cloudflare Worker RPC (WorkerEntrypoint). - Executes with near-zero latency, structured typed payloads, and zero HTTP serialization overhead.
- Enforces the same validation and multi-tenant security rules through the unified
InquiryDomainService.
- The client application exposes an edge API route (
2.4 Custom Capability Cataloging & Rationalization
Cataloging custom capabilities in the client manifest governs when functionality stays bespoke versus when it becomes a shared capability:
- Preventing Premature Abstraction: One-off client requirements are built directly for that client and cataloged as
customrather than prematurely generalized into a platform package after a single use case. - Preventing Delayed Extraction: Because every bespoke capability is declared in the manifest rather than hidden inside application code, cross-fleet audits can readily spot when multiple clients share overlapping
customcapabilities and recommend extracting them into anapp-hostedorplatform-hostedcapability.
3. Client Manifest Specification
The Client Manifest (swarm.config.ts) is where a client application connects and configures its capabilities, including app-hosted capabilities, platform-hosted capabilities, and bespoke custom capabilities.
3.1 Manifest Role & Principles
- Capability Connection & Configuration: The manifest declares which capabilities an application uses and supplies the configuration required to wire them (including capability settings, relevant paths, bindings, or optional brand metadata that a capability such as an
app-hostedCMS may use to style its administrative UI). - Real Capabilities Only: Manifest contracts only register capabilities that actually exist in the platform catalog or active
customcapabilities for the client. Speculative or unbuilt capabilities are never added to the manifest.
3.2 Conceptual Manifest Example
// Sample Client Manifest (swarm.config.ts)import { defineAppConfig } from "@siteswarm/governance";
export default defineAppConfig({ appId: "example-client", name: "Example Client",
capabilities: { // 1. App-Hosted Capability (dedicated instance hosted alongside this app) cms: { type: "app-hosted", version: "1.0.0", targets: ["src/pages/index.astro"], config: { mediaUploads: true, }, },
// 2. Platform-Hosted Capability: Visual Reviews critiques: { type: "platform-hosted", version: "0.2.0", targets: ["src/layouts/Layout.astro"], config: { enabled: true, }, },
// 3. Platform-Hosted Capability: Central Customer Inquiries inquiries: { type: "platform-hosted", version: "0.1.0", targets: [ "src/components/ContactForm.astro", "src/pages/api/submit-inquiry.ts", ], options: { provider: "turnstile", requireTurnstile: true, notifyChannel: "sms", storeSubmissions: true, honeypotFields: ["company_fax_number", "honeypot", "_gotcha"], successMessage: "Thank you! Your inquiry has been safely received.", defaultStatus: "new", }, storage: { mode: "platform-shared", serviceBindingName: "INQUIRIES_SERVICE", }, },
// 4. Custom Capability (cataloged for cross-fleet rationalization audits) "legacy-pos-sync": { type: "custom", description: "Forwards catering orders to client's on-premise POS terminal", }, },});3.3 Explicit Manifest Configuration Schema: Inquiries
The inquiries capability configuration is defined by InquiriesCapabilityUsageSchema in @siteswarm/inquiries/schemas:
export interface InquiriesCapabilityConfig { /** Anti-bot verification provider. Defaults to "turnstile" */ provider?: "turnstile" | "recaptcha-v3" | "hcaptcha"; /** Whether server-side Turnstile validation is strictly mandatory. Defaults to false */ requireTurnstile?: boolean; /** Notification dispatch channel for new submissions */ notifyChannel?: "email" | "sms" | "webhook"; /** Whether valid submissions are persisted in Cloudflare D1. Defaults to true */ storeSubmissions?: boolean; /** Array of hidden honeypot input names used to trap bots silently */ honeypotFields?: string[]; /** Default customer-facing success message */ successMessage?: string; /** Initial status assigned to captured inquiries. Defaults to "new" */ defaultStatus?: string; /** Optional webhook endpoint receiving real-time submission payloads */ webhookUrl?: string;}| Field | Type | Required | Description |
|---|---|---|---|
type |
'platform-hosted' | 'app-hosted' | 'horizontal' |
Yes | Deployment topology. Standard usage is 'platform-hosted'. |
version |
string |
No | Capability package version string (e.g. '0.1.0'). |
targets |
string[] |
Yes | List of source file paths implementing this capability in the client app. Audited by pnpm run lint:arch. |
options.provider |
'turnstile' | 'recaptcha-v3' | 'hcaptcha' |
No | Anti-bot engine. Defaults to 'turnstile'. |
options.requireTurnstile |
boolean |
No | When true, rejects submissions lacking a verified Turnstile token. |
options.notifyChannel |
'email' | 'sms' | 'webhook' |
No | Business owner notification dispatch channel. |
options.storeSubmissions |
boolean |
No | Controls persistence to D1 SQLite database. Defaults to true. |
options.honeypotFields |
string[] |
No | Field names treated as silent bot traps (default: ['company_fax_number', 'honeypot', '_gotcha']). |
options.successMessage |
string |
No | Human-readable confirmation copy returned upon submission. |
options.defaultStatus |
string |
No | Triage status for fresh entries ('new'). |
storage.mode |
'platform-shared' | 'dedicated' | 'static-only' |
Yes | Storage boundary. Must be 'platform-shared' when connecting to central inquiries. |
storage.serviceBindingName |
string |
No | Worker service binding name declared in wrangler.jsonc (standard: 'INQUIRIES_SERVICE'). |
For onboarding guidance on wiring a new client to the inquiries service, see CLIENT_INQUIRY_INTAKE_ONBOARDING.md.
4. Capability Package Runtime Boundaries
To keep shared capability packages safe across both browser islands and edge server workers, packages separate their exports into explicit environment-scoped subpaths (./schemas, ./client, and ./server):
flowchart TD Schemas["./schemas\n(Environment-Agnostic Models & Validation)"] Client["./client\n(Headless Browser Controllers)"] Server["./server\n(Edge Route Handlers & Service Connectors)"]
Client -->|"Imports shared contracts"| Schemas Server -->|"Imports shared contracts"| Schemas./schemas(Environment-Agnostic): Defines pure data models, validation schemas, and configuration contracts with zero dependencies on browser globals or edge worker runtime APIs../client(Browser Runtime): Provides unstyled state controllers and event hooks that attach to bespoke client markup (VISUAL_FREEDOM_AND_SHARED_CORE.md). Imports only from./schemasand never from./server../server(Edge Runtime): Provides request handlers, verification logic, and connectors to backing storage or platform services. Imports only from./schemasand never from./client.