SHIP
Structured Hierarchical Instructional Programs. The declarative DSL underneath the OpenClaw-style agent file, lowered by shipc to a chain-ready CompiledAgent.
In one paragraph
SKILL.md), which shipc elaborates into SHIP and then lowers to a canonical CompiledAgent structure. SHIP declares the agent’s metadata, its tools, and its Agent Behavior Graph (ABG): model calls, tool calls, routers, terminal nodes. The compiler emits JSON for tooling and SCALE for on-chain registration. The runtime never sees SHIP source — only the SCALE-encoded blob.- Declarative, not Turing-complete: SHIP describes graph shape and tool schemas, not arbitrary control flow.
- Compiles to
CompiledAgent: a SCALE- and JSON-encoded canonical structure that the chain decodes into ABG nodes on registration. - Off-chain authoring: SHIP source lives in your repo. The chain only knows about the compiled blob — runtime bounds (max ABG nodes, max tools per agent, etc.) are enforced during decoding.
- Versioned:
0.xexperimental,1.xstable (backwards-compatible within major).
Try SHIP without installing
Two ways in: the simulated playground here on the site compiles a real SHIP agent and shows a simulated execution trace — useful for getting a feel for the syntax. The live in-browser IDE at play.theseus.network compiles real agents via WASM and submits them to chain. Walkthrough: /docs/playground.
What a SHIP file describes
A SHIP file is a single, self-contained agent definition. It captures the four things the chain needs to register an agent and run it.
Agent metadata
Name, version, entry node, system prompt.
Tool definitions
Names, descriptions, JSON schemas. The capability surface the runtime enforces.
ABG nodes
Model calls, tool calls, routers, end nodes — the directed graph the runtime executes.
Constants and IDs
Canonical 32-byte hex IDs for models and sub-agents. No fuzzy tag lookup at registration time.
Authoring → on-chain
Author
Write agent.ship in your editor. Declare metadata, tools, and the ABG.
Compile
shipc compile agent.ship — produces both agent.ship.json (for tooling/CI) and agent.ship.scale (for on-chain).
Register
Submit the SCALE blob to register_compiled_agent. The runtime decodes it into ABG nodes and enforces bounds (MaxAbgNodes, MaxToolsPerAgent, …).
Run
call_agent triggers the ABG. SHIP is no longer in the picture — the chain executes the decoded graph.
A canonical example
A small ReAct-style weather agent: one model call, one router on whether the model emitted tool calls, one tool-execution node. This is the exact shape shipc compiles.
ship 0.1
// Canonical IDs (32-byte 0x-prefixed hex). Model tags are no longer accepted.
const MODEL_GPT51 = "0xe49630ccb59348a9cbbd9989e6774e8b7340b347fbcd94da1f535fb25c15f117"
agent "react_weather"
version 1
entry model_main
system "You are a concise weather assistant. Use tools when necessary."
tools {
"""Get the weather for a city"""
get_weather(city: string, unit?: "c" | "f")
}
graph {
model_main: model_call(MODEL_GPT51) { next -> check_tools }
check_tools: has_tool_calls ? tool_exec : end
tool_exec: tool_call { next -> end }
}agent, version, entry
Identifies the agent and pins which node the runtime starts with. The version is part of the agent’s on-chain identity.
system prompt
Stored on-chain alongside the agent. Anyone calling get_agent can read exactly what the model is told to do.
tools block
Declares the tool surface the agent can call. Each tool has a description and a typed signature; the runtime rejects calls outside this set.
graph body
The ABG. Each node is a model_call, tool_call, router (?: or match), or terminal end. The shape bounds what the agent can do.
Compile and register
shipc emits both a JSON artifact (for editors, explorers, CI) and a SCALE blob (for the chain) from the same canonical structure.
# Default: compile and write both JSON and SCALE artifacts into ./artifacts shipc compile react_weather.ship # -> ./artifacts/react_weather.ship.json # -> ./artifacts/react_weather.ship.scale # SCALE only, to stdout (for piping into a deploy script) shipc compile react_weather.ship --scale > react_weather.ship.scale # Validate without emitting shipc validate react_weather.ship
Submit the SCALE blob via the chain’s register_compiled_agent extrinsic. The runtime decodes it, applies pallet bounds, and stores AgentInfo + AbgNodes. From that point on, the agent is callable via call_agent.
The runtime doesn’t know about SHIP
CompiledAgent blob. SHIP source, the parser, and shipc all live off-chain. That separation means new authoring formats can be added without touching consensus — they just need to produce the same canonical structure.Design principles
Max ABG nodes, max tools per agent, max system prompt size — all enforced during SCALE decoding. A SHIP file that exceeds any bound fails registration.
The same shared types power shipc’s JSON output and the runtime’s SCALE decoding. They can’t drift.
Anyone can inspect a deployed agent: pull AgentInfo + AbgNodes, render the graph, read the system prompt verbatim. No hidden logic.
shipc is one toolchain. Anything that emits a valid CompiledAgent SCALE blob can register an agent. SHIP source isn’t a moat.
Ecosystem examples
Public Theseus repos that ship SHIP-defined agents end-to-end.
proof-of-lobster
Persistent agent identity, scheduled execution, social interaction flows.
View repository →the-prediction-market
Agent-to-contract calls, contract-to-agent callbacks, resolver workflows.
View repository →SHIP toolchain
shipc compiler, shared types, runtime helper, and the SHIP v0.1 spec.