Bundle capability
declared routes, surfaces, layouts, slots, actions, and data recipes
ContractSpec docs
Build on the OSS foundation first. Use Studio when you want the operating layer on top.
Primary docs
Define AI-native surfaces as typed bundle specs that resolve into personalized, auditable runtime plans.
Secondary reading
Philosophy, comparisons, and educational pages that support the main OSS path without replacing it.
OSS-first docs
These docs teach the open system first: contracts, generated surfaces, runtimes, governance, and incremental adoption. Studio shows up as the operating layer on top, not as the source of truth.
Spec pack
The implemented package is @contractspec/lib.surface-runtime. It lets you define a bundle spec once, resolve it into a personalized surface plan, then render that plan through React without letting AI or per-route custom code bypass the declared system boundary.
The bundle spec owns what can render, where it can render, which preferences matter, and how overlays and AI proposals stay bounded.
declared routes, surfaces, layouts, slots, actions, and data recipes
entity registries and field renderers for relation-heavy workbenches
preference-aware adaptation across guidance, density, data depth, control, media, pace, and narrative
auditable overlays and bounded AI patch proposals instead of free-form JSX generation
Start with a typed route and one surface. The runtime validates that you declared routes, surfaces, and verification coverage for all seven preference dimensions.
import { defineModuleBundle } from "@contractspec/lib.surface-runtime/spec/define-module-bundle";
export const SupportWorkbenchBundle = defineModuleBundle({
meta: {
key: "support.workbench",
version: "0.1.0",
title: "Support Workbench",
},
routes: [
{
routeId: "support-ticket",
path: "/operate/support/tickets/:ticketId",
defaultSurface: "ticket-workbench",
},
],
surfaces: {
"ticket-workbench": {
surfaceId: "ticket-workbench",
kind: "workbench",
slots: [{ slotId: "primary", role: "primary", accepts: ["entity-section"], cardinality: "many" }],
layouts: [{ layoutId: "balanced", title: "Balanced", root: { type: "slot", slotId: "primary" } }],
data: [{ recipeId: "ticket-core", source: { kind: "entity", entityType: "support.ticket" }, hydrateInto: "ticket" }],
verification: {
dimensions: {
guidance: "Surface can reveal walkthrough or inline help states.",
density: "Layout supports compact and balanced detail modes.",
dataDepth: "Resolver can hydrate summary or detailed ticket context.",
control: "Advanced actions stay policy-gated.",
media: "Surface supports text-first and hybrid assist modes.",
pace: "Transitions and confirmations adapt to operator pace.",
narrative: "Summary and evidence ordering stay explicit.",
},
},
},
},
});The app renders the resolved plan, not the raw spec. That keeps layout choice, data hydration, overlays, and AI proposals auditable.
import { BundleProvider, BundleRenderer } from "@contractspec/lib.surface-runtime/react";
import { resolveBundle } from "@contractspec/lib.surface-runtime/runtime/resolve-bundle";
const plan = await resolveBundle(SupportWorkbenchBundle, {
tenantId: "tenant_demo",
workspaceId: "workspace_ops",
actorId: "user_42",
route: "/operate/support/tickets/123",
params: { ticketId: "123" },
query: {},
device: "desktop",
locale: "en",
preferences: {
guidance: "hints",
density: "compact",
dataDepth: "detailed",
control: "advanced",
media: "hybrid",
pace: "balanced",
narrative: "top-down",
},
capabilities: ["tickets.read", "tickets.update"],
});
export function SurfaceHost() {
return (
<BundleProvider plan={plan}>
<BundleRenderer assistantSlotId="assistant" />
</BundleProvider>
);
}Once the bundle resolves deterministically, move into safe customization and the wider architecture that surrounds it.
Customize generated surfaces safely without forking the system or breaking regeneration.
Guard coding-agent edits and shell actions with task-scoped context, plan packets, patch verdicts, and review packets.
Why ContractSpec
Keep educational and comparison content reachable without letting it define the primary OSS learning path.