Publish a project capability surface
Export bounded, versioned slices of your project for other projects to install - entities, operations, CLI commands, workflows, agent skills, analytics, events, webhooks, auth, and runtime handlers.
A project capability surface is a signed, versioned, audit-trailed slice of a Vadyl project. Provider projects publish typed slices. Consumer projects install them with explicit grants, billing attribution, runtime descriptor integration, and revocable lifecycle state.
1. Decide the surface boundary
Start with the capability you want other projects to depend on: an email service, payments service, LLM gateway, internal accounting plane, command pack, workflow library, analytics model, event vocabulary, or agent skill set. The boundary should be product-shaped, not provider-shaped.
2. Define the manifest
// vadyl.surface.ts in the provider project
export default defineProjectCapabilitySurface({
name: "EmailService",
version: "1.2.0",
publisherProject: "acme/email-service",
slices: {
entities: ["EmailMessage", "EmailTemplate"],
operations: ["email.send", "email.render", "email.scheduleAt"],
cliCommands: ["email.send", "email.template.render"],
workflows: ["sendCampaign"],
agentSkills: ["draftCustomerEmail"],
analyticsMeasures: ["emailsSent", "bounceRate"],
events: ["email.sent", "email.bounced", "email.opened"],
realtimeChannels: ["email.delivery"],
webhookTopics: ["email.bounced", "email.complained"],
associationTemplates: [{
name: "MessageRecipient",
relation: { from: "EmailMessage", to: "<consumer:User>" },
}],
},
exposure: {
protocols: ["Rest", "Sdk", "Cli", "Mcp", "Webhook", "Realtime", "Dashboard"],
stability: "Stable",
deprecationPolicy: { minimumWindow: "12mo" },
},
governance: {
requiredGrants: ["surface:EmailService.install", "operation:email.send"],
quotaDimensions: ["surface", "operation", "consumerProject"],
billingAttribution: "consumer-project",
},
});3. Validate locally
vadyl surface validate ./vadyl.surface.ts
vadyl graph validate
vadyl surface explain EmailService --output jsonValidation checks the selected slices, exposure bindings, CLI output contracts, SDK namespace projection, MCP tool schemas, PCG nodes, grant references, quota dimensions, lifecycle policy, and descriptor hash.
4. Publish
vadyl surface publish EmailService@1.2.0 --manifest ./vadyl.surface.tsPublishing signs the ProjectCapabilitySurfaceManifest, registers a PublishedSurface, emits lifecycle events, and makes the version discoverable to projects allowed by the provider's publication policy. Published versions are immutable.
5. Install from a consumer project
vadyl surface install EmailService@1.2.0 \
--publisher acme/email-service \
--project storefront \
--grant operation:email.send \
--grant cli:email.send \
--grant mcp:email.send \
--billing-project storefrontThe installation pins the provider version, narrows grants, declares billing attribution, records allowed protocols, and writes a branchableInstallationManifest. The consumer runtime descriptor now sees the installed surface as project capability.
6. Use through any projection
// SDK
await vadyl.surfaces.EmailService.email.send({
to: user.email,
template: "welcome",
data: { user },
});
# CLI
vadyl email send --to ada@example.com --template welcome --data @data.json
# MCP
tools/call -> email_sendAll three calls dispatch through the same exposure binding and produce the same consumption evidence. Protocols do not own separate semantics.
7. Observe usage and explain decisions
vadyl surface consumption EmailService --group-by consumerProject,operation
vadyl surface explain-consumption <consumptionId>
vadyl graph edges --from surface:EmailServiceProjectCapabilityConsumptionDescriptor records connect the provider project, consumer project, installation id, actor, grant, quota dimension, billing scope, protocol, correlation id, and reason block.
8. Deprecate, upgrade, revoke
vadyl surface deprecate EmailService@1.2.0 --replace-with 2.0.0 --window 12mo
vadyl surface upgrade EmailService --to 2.0.0 --project storefront
vadyl surface revoke EmailService@1.2.0 --reason "security replacement"Deprecation warns without breaking installed consumers. Upgrade is an explicit consumer action and can be sandboxed. Revocation fails closed through project grants and runtime descriptors.
Federation vs installable surfaces
Federation is the lightweight per-entity directional grant for cross-project data access. Installable surfaces are the productized versioned package model for capability sets across entities, operations, commands, workflows, agents, analytics, events, and governance.
Reference details live in Project capability surfaces.