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 @lssm-tech/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.
1import { defineModuleBundle } from "@lssm-tech/lib.surface-runtime/spec/define-module-bundle";
2
3export const SupportWorkbenchBundle = defineModuleBundle({
4 meta: {
5 key: "support.workbench",
6 version: "0.1.0",
7 title: "Support Workbench",
8 },
9 routes: [
10 {
11 routeId: "support-ticket",
12 path: "/operate/support/tickets/:ticketId",
13 defaultSurface: "ticket-workbench",
14 },
15 ],
16 surfaces: {
17 "ticket-workbench": {
18 surfaceId: "ticket-workbench",
19 kind: "workbench",
20 slots: [{ slotId: "primary", role: "primary", accepts: ["entity-section"], cardinality: "many" }],
21 layouts: [{ layoutId: "balanced", title: "Balanced", root: { type: "slot", slotId: "primary" } }],
22 data: [{ recipeId: "ticket-core", source: { kind: "entity", entityType: "support.ticket" }, hydrateInto: "ticket" }],
23 verification: {
24 dimensions: {
25 guidance: "Surface can reveal walkthrough or inline help states.",
26 density: "Layout supports compact and balanced detail modes.",
27 dataDepth: "Resolver can hydrate summary or detailed ticket context.",
28 control: "Advanced actions stay policy-gated.",
29 media: "Surface supports text-first and hybrid assist modes.",
30 pace: "Transitions and confirmations adapt to operator pace.",
31 narrative: "Summary and evidence ordering stay explicit.",
32 },
33 },
34 },
35 },
36});The app renders the resolved plan, not the raw spec. That keeps layout choice, data hydration, overlays, and AI proposals auditable.
1import { BundleProvider, BundleRenderer } from "@lssm-tech/lib.surface-runtime/react";
2import { resolveBundle } from "@lssm-tech/lib.surface-runtime/runtime/resolve-bundle";
3
4const plan = await resolveBundle(SupportWorkbenchBundle, {
5 tenantId: "tenant_demo",
6 workspaceId: "workspace_ops",
7 actorId: "user_42",
8 route: "/operate/support/tickets/123",
9 params: { ticketId: "123" },
10 query: {},
11 device: "desktop",
12 locale: "en",
13 preferences: {
14 guidance: "hints",
15 density: "compact",
16 dataDepth: "detailed",
17 control: "advanced",
18 media: "hybrid",
19 pace: "balanced",
20 narrative: "top-down",
21 },
22 capabilities: ["tickets.read", "tickets.update"],
23});
24
25export function SurfaceHost() {
26 return (
27 <BundleProvider plan={plan}>
28 <BundleRenderer assistantSlotId="assistant" />
29 </BundleProvider>
30 );
31}Define one `ModuleBundleSpec` with `defineModuleBundle` and keep the route and surface map explicit.
Resolve the bundle with `resolveBundle` for a real user, route, device, and preference profile.
Render the plan through `BundleProvider` and `BundleRenderer` so the UI stays downstream of the resolved spec.
Add overlays, policy hooks, planner proposals, and telemetry only after the base route resolves cleanly.
Pilot one dense domain first, such as a PM or operations workbench, before expanding the abstraction across the app.
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.