Skip to content

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:

  1. Standardized Capability Reuse: Enables client applications to connect and configure shared platform capabilities rather than re-implementing common infrastructure.
  2. 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).
  3. 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 <--> PlatInquiries

2.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
  1. Ingress Path A: Direct Browser HTTP (POST /api/inquiries):
    • The browser mounts the headless form controller (@siteswarm/inquiries/client) and submits directly to https://inquiries.jacobmiller22.com/api/inquiries.
    • The platform service verifies the request Origin against 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.
  2. 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.

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 custom rather 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 custom capabilities and recommend extracting them into an app-hosted or platform-hosted capability.

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

  1. 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-hosted CMS may use to style its administrative UI).
  2. Real Capabilities Only: Manifest contracts only register capabilities that actually exist in the platform catalog or active custom capabilities 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
  1. ./schemas (Environment-Agnostic): Defines pure data models, validation schemas, and configuration contracts with zero dependencies on browser globals or edge worker runtime APIs.
  2. ./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 ./schemas and never from ./server.
  3. ./server (Edge Runtime): Provides request handlers, verification logic, and connectors to backing storage or platform services. Imports only from ./schemas and never from ./client.