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.
Build a first module bundle
Define one bundle spec, resolve it for a real route and preference profile, then render the resulting surface plan through the React host layer.
What you'll build
- One `ModuleBundleSpec` with a route and workbench surface.
- One `ResolvedSurfacePlan` from `resolveBundle`.
- One React host using `BundleProvider` and `BundleRenderer`.
1) Define the bundle spec
The bundle spec is the durable contract. It owns route selection, surface shape, layouts, data recipes, 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" },
{ slotId: "assistant", role: "assistant", accepts: ["assistant-panel"], cardinality: "many", mutableByAi: true, mutableByUser: true },
],
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.",
},
},
},
},
});Expected output: `defineModuleBundle` validates the route, surface, and verification dimensions at runtime.
2) Resolve the plan
Resolve against a real route, device, and preference profile. This is where the runtime chooses the surface, layout, bindings, and audit reasons.
import { resolveBundle } from "@contractspec/lib.surface-runtime/runtime/resolve-bundle";
export const supportWorkbenchPlan = 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"],
}
);Expected output: a `ResolvedSurfacePlan` with `bundleKey`, `surfaceId`, `layoutId`, `bindings`, `adaptation`, and audit reasons.
3) Render the plan
The host app renders the resolved plan, not the raw spec. That keeps layout selection, overlays, and AI proposals downstream of the declared bundle contract.
import { BundleProvider, BundleRenderer } from "@contractspec/lib.surface-runtime/react";
export function SurfaceHost() {
return (
<BundleProvider plan={supportWorkbenchPlan}>
<BundleRenderer assistantSlotId="assistant" />
</BundleProvider>
);
}Expected output: the route renders according to the resolved layout root and slot plan instead of bespoke page assembly.
Verification checks
- The resolved `surfaceId` matches the route you expected.
- The `layoutId` is stable for the active view and preferences.
- The plan carries audit reasons and all seven adaptation dimensions.
- Assistant or overlay work stays within declared slots.
Docs generation pipeline
Feed generated docs into the public docs site without breaking source-of-truth ownership.
Host the Builder workbench
Load a Builder workspace snapshot, wire common commands, and keep runtime mode plus mobile review flows explicit.
Why ContractSpec
Keep educational and comparison content reachable without letting it define the primary OSS learning path.