Skip to content

Compiling

The spawnfile compile command takes a Spawnfile project and produces runtime-specific output files plus a machine-readable compile report. This guide explains the pipeline, output layout, and report format.

The reference compiler follows this pipeline:

  1. Parse the root Spawnfile.
  2. Validate local schema and file references.
  3. Walk the manifest graph through members[*].ref and subagents[*].ref.
  4. Detect cycles and incompatible duplicate references.
  5. Resolve effective runtime and execution for every graph node.
  6. Build a normalized intermediate representation (IR).
  7. Group resolved nodes by runtime.
  8. Invoke runtime adapters.
  9. Emit output directories and spawnfile-report.json.

The compiler operates on resolved IR after the graph phase, not on raw YAML. Adapters receive fully resolved nodes with all inheritance applied.

Validation happens in three layers:

  • YAML validity
  • Required fields (spawnfile_version, kind, name)
  • Path existence for docs, skills, and member/subagent refs
  • Enum checks (transport, isolation, sandbox mode)
  • Duplicate name/id detection
  • Cycle detection across teams and subagents
  • Duplicate node resolution conflicts (same path, different effective config)
  • Runtime resolution (every agent must have an effective runtime)
  • Skill requires.mcp resolution against visible MCP scope
  • Runtime option validation
  • Runtime-native config constraints
  • Capability preservation checks

You can run validation without compiling using spawnfile validate:

Terminal window
spawnfile validate ./my-agent

This performs static and graph validation without invoking adapters or emitting output.

Graph nodes are keyed by canonical manifest path. One manifest path equals one logical node. If the same path is referenced multiple times, all references must resolve to the same effective runtime and execution. Otherwise the compiler fails.

The compiler tracks two edge kinds:

  • team_member — from a team to one of its members
  • subagent — from a parent agent to one of its subagents

Adapters may treat these edge types very differently.

  • For agents: runtime is declared in the manifest.
  • For subagents: runtime is inherited from the parent. If the subagent declares runtime, it must match the parent.
  • For execution: parent execution is deep-merged with child execution. Objects merge recursively, scalars replace, arrays replace wholesale.
  • For team members: each member declares its own runtime. Teams do not override member runtimes.

Runtime adapters implement two operations:

  • compileAgent (required) — takes a resolved agent node, emits files and capability outcomes.
  • compileTeam (optional) — takes a resolved team node, emits native team artifacts if the runtime supports them.

Each operation returns:

  • files — emitted files relative to the node’s output directory
  • capabilities — per-capability outcomes (supported, degraded, or unsupported)
  • diagnostics — warnings and errors discovered by the adapter

Every agent node is always compilable independently by its runtime adapter. Team compilation is optional and adapter-dependent.

For multi-runtime teams, the compiler compiles each member agent independently and reports any loss of native team semantics.

The default output root is ./dist. Within that root:

dist/
spawnfile-report.json
runtimes/
openclaw/
agents/
analyst/
teams/
research-cell/
picoclaw/
agents/
researcher/

Rules:

  • One directory per runtime
  • One stable directory per compiled node
  • Agent and team outputs are separated
  • The report file is always at the root

Use --out to change the output directory:

Terminal window
spawnfile compile ./my-agent --out ./build

The compiler emits a JSON report at spawnfile-report.json in the output root.

{
"spawnfile_version": "0.1",
"root": "/abs/path/to/Spawnfile",
"nodes": [],
"diagnostics": []
}

Each compiled graph node gets an entry:

{
"id": "agent:analyst",
"kind": "agent",
"source": "/abs/path/to/Spawnfile",
"runtime": "openclaw",
"output_dir": "runtimes/openclaw/agents/analyst",
"capabilities": [],
"diagnostics": []
}

For every declared capability, the compiler reports one of:

OutcomeMeaning
supportedFully preserved in the target with equivalent intent
degradedPartially mapped; runtime behavior may differ
unsupportedCannot be expressed in the target

Example:

{
"key": "execution.model",
"outcome": "supported",
"message": ""
}

The compiler reports on these keys:

  • docs.identity, docs.soul, docs.system, docs.memory, docs.heartbeat, docs.extras.<name>
  • skills.<name-or-ref>
  • mcp.<name>
  • execution.model, execution.workspace, execution.sandbox
  • agent.subagents
  • team.members, team.structure.mode, team.structure.leader, team.structure.external, team.shared, team.nested

Adapters may add runtime-specific keys under runtime.options.* and runtime.native.*.

The compile report is always emitted regardless of policy. What changes is whether degradation stops the build:

  • policy.mode: permissive — continues, records outcomes

  • policy.mode: warn — continues with warnings

  • policy.mode: strict — fails on any unverifiable capability

  • policy.on_degrade: allow — degradations are silent

  • policy.on_degrade: warn — degradations produce warnings

  • policy.on_degrade: error — degradations fail the build

Terminal window
# Scaffold a new agent project (defaults to openclaw)
spawnfile init
# Scaffold for a specific runtime
spawnfile init --runtime tinyclaw
# Scaffold a new team project
spawnfile init --team
# Add a member agent to a team
spawnfile add agent writer ./my-team --runtime tinyclaw
# Add a subagent to an agent
spawnfile add subagent critic ./my-agent
# Add a nested team to a team
spawnfile add team platform ./my-team

spawnfile init generates runtime-specific markdown docs (SOUL.md, IDENTITY.md, AGENTS.md) tailored to each runtime’s personality and capabilities. Each runtime adapter provides its own scaffold templates.

spawnfile add grows an existing manifest graph in place. It creates the child directory, scaffolds a Spawnfile, and appends the reference to the parent manifest. The CLI enforces parent kind rules: add agent and add team only work on team projects, and add subagent only works on agent projects.

Terminal window
# Set the primary model
spawnfile model set anthropic claude-opus-4-6 --auth claude-code
# Set a model with custom endpoint
spawnfile model set local qwen2.5:14b --auth none \
--compat openai --base-url http://host.docker.internal:11434/v1
# Add a fallback model
spawnfile model add-fallback openai gpt-4o-mini --auth codex
# Remove all fallback models
spawnfile model clear-fallbacks
# Update all agents in a team recursively
spawnfile model set anthropic claude-opus-4-6 ./my-team --auth claude-code --recursive

spawnfile model edits model intent in place and rewrites touched manifests to the canonical inline shape. When targeting a team project, --recursive is required and only descendant agent manifests are updated — the team manifest itself is left unchanged (teams do not declare execution).

Terminal window
# Validate without compiling
spawnfile validate ./fixtures/single-agent
# Compile the project in the current directory
spawnfile compile
# Compile a specific project
spawnfile compile ./fixtures/single-agent
# Compile with custom output directory
spawnfile compile ./fixtures/single-agent --out ./build