Manifest reference
Every field of workflow.json, generated from the manifest schema — the same schema that validates your package locally and at publish time.
Add the $schema field to get editor autocomplete and inline validation:
{
"$schema": "https://runcastle.dev/schema/v1.json",
"schemaVersion": 1,
...
}Top-level fields
$schemastringoptionalOptional JSON Schema URL so editors provide autocomplete and inline validation.
schemaVersionnumberrequiredManifest format version. Always 1 for now.
Allowed values: 1
namestringrequiredHuman-readable display name shown on cards and the detail page.
slugstringrequiredURL-safe identifier [a-z0-9-]{3,64}, unique per author; forms the install handle author/slug.
versionstringrequiredStrict semver (e.g. 1.2.0). Versions are immutable — republishing a version is rejected with 409.
descriptionstringrequiredOne-paragraph summary (max 280 chars) shown on cards and in search.
licensestringrequiredSPDX license identifier for the package contents (e.g. MIT).
tagsstring[]optionalUp to 8 tags from an open vocabulary, used for browse filters and search.
sandboxProvidersstring[]optionalSandbox environments the workflow supports (subset of docker | podman | vercel | custom).
Allowed values: docker, podman, vercel, custom
filesstring[]requiredExhaustive list of files the package installs, relative to the package root (all under .sandcastle/).
repositoryDirectorystringoptionalDirectory within the repository containing the package, when it isn't at the repo root.
homepagestringoptionalOptional project homepage URL (http(s) only).
postInstallNotesstringoptionalPlain text printed by the CLI after a successful install (printed, never executed).
sandcastle
sandcastleobjectrequiredCompatibility block describing the Sandcastle runtime the workflow targets.
sandcastle.packageNamestringoptionalThe orchestration package. Defaults to @ai-hero/sandcastle.
sandcastle.versionRangestringrequiredSemver range of Sandcastle versions the workflow is tested against (e.g. >=0.12.0 <0.13.0).
sandcastle.entrypointstringoptionalPath to the orchestration entrypoint that calls run(). Defaults to .sandcastle/main.ts.
agents
agentsobject[]optionalThe agents the workflow orchestrates — declared metadata cross-checked against the entrypoint.
agents[].rolestringrequiredThe agent's role name as used in the orchestration code (e.g. planner, implementer, reviewer).
agents[].providerstringrequiredAgent factory / provider used for this role.
Allowed values: claude-code, codex, pi, opencode, cursor, copilot
agents[].modelstringrequiredModel identifier passed to the provider (e.g. claude-opus-4-8).
agents[].parallelbooleanoptionalWhether this role fans out into parallel instances.
env
envobject[]optionalEnvironment variables the user must provide; cross-checked against .env.example.
env[].namestringrequiredEnvironment variable name (shell-safe identifier).
env[].requiredbooleanrequiredWhether the workflow fails without this variable set.
env[].descriptionstringoptionalWhat the variable is for — shown to installers.
disclosures
disclosuresobjectrequiredThe declared side-effect surface (hooks, network, shell expansion). Mismatches with detected behavior block publish.
disclosures.hostHooksstring[]optionalEvery host.* hook command run on the consumer's machine, verbatim as string literals.
disclosures.sandboxHooksstring[]optionalEvery sandbox.* hook command run inside the sandbox, verbatim as string literals.
disclosures.networkAccessstringoptionalFree-text note describing what the workflow accesses over the network.
disclosures.usesShellExpansionbooleanoptionalWhether any prompt file contains !`command` shell-expansion blocks.
topology
topologyobjectoptionalThe node/edge graph describing the orchestration shape. Optional — drives the site diagram, cards, and OG images.
topology.nodesobject[]requiredGraph nodes — one per agent role or auxiliary step.
topology.nodes[].idstringrequiredUnique node identifier, referenced by edges.
topology.nodes[].rolestring | nullrequiredThe agent role this node represents, or null for non-agent nodes (e.g. a git step).
topology.nodes[].labelstringrequiredDisplay label rendered in the diagram.
topology.nodes[].kindstringoptionalOptional node flavor (e.g. "git") — non-agent nodes get a muted rendering.
topology.nodes[].fanOutbooleanoptionalMarks a node that fans out into parallel instances — rendered as a stacked card.
topology.edgesobject[]requiredDirected edges between node ids.
topology.edges[].fromstringrequiredSource node id.
topology.edges[].tostringrequiredTarget node id.
topology.edges[].labelstringoptionalOptional edge label (e.g. a condition).
topology.edges[].loopbooleanoptionalMarks a feedback edge (e.g. reviewer sending work back) — rendered dashed.