This folder contains JSON Schema definitions for the workflow server. These schemas define the structure for workflow definitions, conditional logic, and runtime state tracking.
The workflow server uses five interconnected schemas:
| Schema | Purpose | Use Case |
|---|---|---|
workflow.schema.json |
Defines workflow structure | Creating new workflows with activities, steps, checkpoints |
condition.schema.json |
Defines conditional expressions | Controlling transitions and decisions |
state.schema.json |
Tracks runtime execution state | Persisting workflow progress |
skill.schema.json |
Defines agent skill capabilities | Describing tool orchestration patterns and execution guidance |
activity.schema.json |
Defines unified activities | Combining intent matching with workflow execution stages |
The schemas work together to define workflows (design-time) and track their execution (runtime). The diagrams below illustrate these relationships.
A workflow consists of activities connected by transitions. Each activity can contain steps (individual tasks), checkpoints (user decision points), decisions (automated branching), loops (iteration constructs), and optionally trigger other workflows. The initialActivity property determines where sequential workflows begin; workflows with all independent activities (no transitions) don't require initialActivity.
stateDiagram-v2
direction LR
state "Workflow Definition" as WD {
[*] --> Activity1: initialActivity
Activity1 --> Activity2: transition
Activity2 --> Activity3: transition (with condition)
Activity3 --> [*]: complete
state Activity1 {
Steps
Checkpoints
}
state Activity2 {
Steps
Decisions
}
state Activity3 {
Loops
Triggers
}
}
note right of WD
workflow.schema.json
Defines structure
end note
The second diagram shows how the schema files depend on each other:
- workflow.schema.json defines the overall structure and references
activity.schema.jsonfor activities - activity.schema.json defines unified activities with steps, checkpoints, decisions, loops, transitions, and triggers
- skill.schema.json defines agent capabilities, tool orchestration patterns, and execution protocols
- condition.schema.json provides reusable condition expressions (simple comparisons, AND/OR/NOT combinators)
- state.schema.json tracks runtime execution state, linking back to the workflow definition
At design-time, you work with workflow.schema.json, activity.schema.json, and skill.schema.json. At runtime, state.schema.json captures progress through the workflow.
flowchart TB
subgraph Workflow["workflow.schema.json"]
W[Workflow] --> A[Activities]
W --> SK1["skills[]"]
end
subgraph Activity["activity.schema.json"]
A --> S[Steps]
A --> C[Checkpoints]
A --> D[Decisions]
A --> L[Loops]
A --> T[Transitions]
A --> TR[Triggers]
A --> SK2["skills{}"]
end
subgraph Skill["skill.schema.json"]
SK1 --> SKD[Skill Definition]
SK2 --> SKD
S -.->|"step.skill"| SKD
SKD --> Proto[Protocol]
SKD --> Tools[Tools]
SKD --> Rules[Rules]
end
subgraph Condition["condition.schema.json"]
S --> COND[Conditions]
C --> COND
T --> COND
D --> COND
L --> COND
COND --> Simple["Simple: variable op value"]
COND --> And["AND: conditions[]"]
COND --> Or["OR: conditions[]"]
COND --> Not["NOT: condition"]
end
subgraph State["state.schema.json"]
W -.->|"runtime"| ST[Workflow State]
ST --> CA[currentActivity]
ST --> CS[completedSteps]
ST --> CR[checkpointResponses]
ST --> PW[parentWorkflow]
ST --> TW[triggeredWorkflows]
end
This section defines the key concepts, their fields, and relationships within the schema system.
erDiagram
Workflow ||--o{ Activity : contains
Workflow ||--o{ Variable : defines
Workflow ||--o{ Mode : has
Activity ||--o{ Step : contains
Activity ||--o{ Checkpoint : contains
Activity ||--o{ Decision : contains
Activity ||--o{ Loop : contains
Activity ||--o{ Transition : contains
Activity ||--o{ WorkflowTrigger : triggers
Activity ||--o{ Action : "entry/exit"
Activity ||--o{ Artifact : produces
Step ||--o{ Action : performs
Step |o--o| Condition : "conditional on"
Checkpoint |o--o| Condition : "conditional on"
Checkpoint ||--|{ CheckpointOption : has
CheckpointOption ||--o| Effect : triggers
Decision ||--|{ DecisionBranch : has
DecisionBranch |o--o| Condition : "evaluated by"
Loop |o--o| Condition : "controlled by"
Loop |o--o| Condition : "break on"
Loop ||--o{ Step : iterates
Transition |o--o| Condition : "guarded by"
Workflow ||--|| ExecutionModel : declares
ExecutionModel ||--|{ AgentRole : contains
Workflow {
string id PK
string version
string title
string description
string initialActivity FK
ExecutionModel executionModel
string[] skills
}
ExecutionModel {
AgentRole[] roles
}
AgentRole {
string id PK
string description
}
Mode {
string id PK
string name
string activationVariable
array skipActivities
}
Activity {
string id PK
string version
string name
string problem
array recognition
boolean required
string estimatedTime
}
Artifact {
string id PK
string name
string location
enum action
}
Step {
string id PK
string name
string description
string skill
boolean required
}
Checkpoint {
string id PK
string name
string message
Condition condition
boolean blocking
string defaultOption
integer autoAdvanceMs
}
CheckpointOption {
string id PK
string label
string description
}
Decision {
string id PK
string name
string description
}
DecisionBranch {
string id PK
string label
string transitionTo FK
boolean isDefault
}
Transition {
string to FK
boolean isDefault
}
Loop {
string id PK
string name
enum type
string variable
integer maxIterations
}
Variable {
string name PK
enum type
string description
any defaultValue
boolean required
}
WorkflowTrigger {
string workflow FK
string description
array passContext
}
Action {
enum action
string target
string message
any value
}
Condition {
enum type
string variable
string operator
any value
}
Effect {
object setVariable
string transitionTo
array skipActivities
}
A workflow is the top-level container representing a complete process definition. Workflows can have sequential activities (connected by transitions, requiring initialActivity) or independent activities (self-contained entry points matched via recognition patterns).
| Field | Type | Purpose |
|---|---|---|
id |
string | Unique identifier for the workflow |
version |
string | Semantic version (X.Y.Z) |
title |
string | Human-readable display name |
description |
string | Detailed description |
author |
string | Creator of the workflow |
tags |
string[] | Categorization labels |
rules |
string[] | Execution guidelines |
executionModel |
ExecutionModel | Agent roles and orchestration model for this workflow (required) |
skills |
string[] | Workflow-level skill IDs (returned by get_skills) |
variables |
Variable[] | State variables |
modes |
Mode[] | Execution modes that modify standard workflow behavior |
artifactLocations |
object | Named artifact storage locations (keyed by location ID) |
initialActivity |
string | Starting activity ID (required for sequential workflows) |
activitiesDir |
string | Directory containing external activity files (server-resolved) |
activities |
Activity[] | Inline activity definitions (or loaded from activitiesDir) |
Activity Models:
- Sequential: Activities have
transitions, requireinitialActivity(e.g., work-package) - Independent: Activities have no
transitions, matched viarecognition(e.g., meta)
A unified activity combines intent matching (problem, recognition) with workflow execution (steps, checkpoints, decisions, loops, transitions). Activities can also trigger other workflows.
| Field | Type | Purpose |
|---|---|---|
id |
string | Unique identifier within workflow |
version |
string | Semantic version (X.Y.Z) |
name |
string | Display name |
description |
string | What this activity accomplishes |
problem |
string | User problem this activity addresses |
recognition |
string[] | Patterns to match user intent |
skills |
SkillsReference | Primary and supporting skill references |
steps |
Step[] | Individual tasks |
checkpoints |
Checkpoint[] | User decision points |
decisions |
Decision[] | Automated branching points |
loops |
Loop[] | Iteration constructs |
transitions |
Transition[] | Activity navigation rules |
triggers |
WorkflowTrigger[] | Workflows to trigger from this activity |
entryActions |
Action[] | Actions on entering activity |
exitActions |
Action[] | Actions on exiting activity |
outcome |
string[] | Expected outcomes on completion |
context_to_preserve |
string[] | Context items to preserve |
required |
boolean | Whether activity must be completed |
estimatedTime |
string | Time estimate (e.g., "10-15m") |
rules |
string[] | Activity-level execution rules |
artifacts |
Artifact[] | Artifacts produced or updated |
artifactPrefix |
string | Server-computed numeric prefix from filename |
A step represents an individual task within an activity.
| Field | Type | Purpose |
|---|---|---|
id |
string | Unique identifier within activity |
name |
string | Task name |
description |
string | What this step accomplishes |
skill |
string | Skill ID to apply for this step |
condition |
Condition | Condition that must be true to execute; if false, step is skipped |
required |
boolean | Whether step must be completed |
actions |
Action[] | Actions to perform |
A checkpoint is a decision point requiring user input. Checkpoints block by default but can be non-blocking with auto-advance.
| Field | Type | Purpose |
|---|---|---|
id |
string | Unique identifier within activity |
name |
string | Checkpoint name |
message |
string | Question to present to user |
condition |
Condition | Condition that must be true to present; if false, skip |
options |
CheckpointOption[] | Available choices |
required |
boolean | Whether checkpoint must be answered |
blocking |
boolean | Whether this checkpoint blocks progress (default: true). Non-blocking checkpoints support defaultOption and autoAdvanceMs for auto-advance. |
defaultOption |
string | Option ID to auto-select when autoAdvanceMs elapses. Only meaningful when blocking is false. |
autoAdvanceMs |
integer | Milliseconds to wait before auto-selecting defaultOption. Only meaningful when blocking is false and defaultOption is set. |
A decision is an automated branching point based on variable conditions.
| Field | Type | Purpose |
|---|---|---|
id |
string | Unique identifier within activity |
name |
string | Decision name |
description |
string | What is being decided |
branches |
DecisionBranch[] | Conditional paths (min 2) |
A transition defines navigation from one activity to another.
| Field | Type | Purpose |
|---|---|---|
to |
string | Target activity ID |
condition |
Condition | When this transition applies |
isDefault |
boolean | Fallback if no conditions match |
A workflow trigger allows an activity to invoke another workflow. Used for composing workflows (e.g., work-packages triggering work-package for each planned package).
| Field | Type | Purpose |
|---|---|---|
workflow |
string | ID of the workflow to trigger |
description |
string | When/why this workflow is triggered |
passContext |
string[] | Context variables to pass to child workflow |
A loop enables iteration over collections or while conditions hold.
| Field | Type | Purpose |
|---|---|---|
id |
string | Unique identifier within activity |
name |
string | Loop name |
type |
enum | "forEach", "while", or "doWhile" |
variable |
string | Iteration variable name |
over |
string | Collection to iterate (forEach) |
condition |
Condition | Continue condition (while/doWhile) |
maxIterations |
integer | Safety limit |
breakCondition |
Condition | Early exit condition |
steps |
Step[] | Steps to execute per iteration |
activities |
string[] | Activity IDs to execute in loop |
References to skills used by an activity.
| Field | Type | Purpose |
|---|---|---|
primary |
string | Primary skill ID for this activity |
supporting |
string[] | Supporting skill IDs |
An action performed during workflow execution.
| Field | Type | Purpose |
|---|---|---|
action |
enum | "log", "validate", "set", "emit", or "message" |
target |
string | Target of the action |
message |
string | Message content |
value |
any | Value for set/emit actions |
A workflow variable definition.
| Field | Type | Purpose |
|---|---|---|
name |
string | Variable name |
type |
enum | "string", "number", "boolean", "array", "object" |
description |
string | Variable purpose |
defaultValue |
any | Initial value |
required |
boolean | Whether variable must be set |
A conditional expression for control flow. Defined in condition.schema.json.
| Type | Structure | Purpose |
|---|---|---|
simple |
variable, operator, value | Basic comparison |
and |
conditions[] | All must be true |
or |
conditions[] | At least one must be true |
not |
condition | Negation |
| Pattern | Usage | Examples |
|---|---|---|
id |
Unique identifier | activity.id, step.id, checkpoint.id |
name |
Display name for entities | activity.name, step.name, loop.name |
description |
Detailed explanation | workflow.description, activity.description |
required |
Mandatory flag | variable.required, step.required |
| Field | Context | Meaning |
|---|---|---|
title |
Workflow only | Top-level display name |
name |
All other entities | Entity display name |
label |
Options/branches | User-facing choice text |
The workflow schema (workflow.schema.json) defines the complete structure of a workflow, including metadata, variables, and activities. Workflows can use inline activities or reference external activity files via activitiesDir (a server convention — the server resolves activitiesDir by loading activity files and populating the activities array before schema validation runs).
{
"$schema": "../../schemas/workflow.schema.json",
"id": "my-workflow",
"version": "1.0.0",
"title": "My Workflow",
"description": "A sample workflow",
"author": "author-name",
"tags": ["sample", "documentation"],
"rules": ["Rule 1", "Rule 2"],
"executionModel": {
"roles": [
{ "id": "agent", "description": "Single agent executing all activities" }
]
},
"variables": [],
"initialActivity": "first-activity",
"activitiesDir": "activities"
}| Property | Type | Description |
|---|---|---|
id |
string | Unique workflow identifier |
version |
string | Semantic version (e.g., 1.0.0) |
title |
string | Human-readable title |
executionModel |
ExecutionModel | Declares the agent roles for this workflow |
activities |
array | Array of activity definitions (or loaded from activitiesDir) |
| Property | Type | Description |
|---|---|---|
$schema |
string | Path to schema file for validation |
description |
string | Workflow description |
author |
string | Author name |
tags |
string[] | Categorization tags |
rules |
string[] | Execution rules/guidelines |
skills |
string[] | Workflow-level skill IDs (loaded by get_skills) |
variables |
array | Variable definitions with types and defaults |
modes |
array | Execution modes that modify standard workflow behavior |
artifactLocations |
object | Named artifact storage locations (keys are location IDs, values are path strings or {path, description, gitignored} objects) |
initialActivity |
string | ID of first activity (required for sequential workflows) |
activitiesDir |
string | Directory containing external activity TOON files (server-resolved, not in JSON schema) |
Variables store state that persists across activities. Define them at the workflow level:
{
"variables": [
{
"name": "user_confirmed",
"type": "boolean",
"description": "Whether user confirmed the action",
"defaultValue": false,
"required": false
},
{
"name": "selected_option",
"type": "string",
"description": "User's selected option",
"required": false
}
]
}Variable Types: string, number, boolean, array, object
Every workflow must declare an executionModel that defines the agent roles participating in its execution. Each workflow defines its own role vocabulary — role IDs are validated for uniqueness within the workflow.
{
"executionModel": {
"roles": [
{
"id": "orchestrator",
"description": "Coordinates workflow execution, manages transitions, presents checkpoints"
},
{
"id": "worker",
"description": "Executes activity steps, produces artifacts, yields at checkpoints"
}
]
}
}ExecutionModel Properties:
| Property | Type | Description |
|---|---|---|
roles |
AgentRole[] | Agent roles declared for this workflow (min 1, unique IDs) |
AgentRole Properties:
| Property | Type | Description |
|---|---|---|
id |
string | Unique role identifier within this workflow |
description |
string | What this role does in the workflow |
Role declarations are descriptive metadata — the server stores and serves them via get_workflow, but does not enforce agent behavior against them. Behavioral constraints for each role are expressed in the workflow's rules array.
Common patterns:
| Pattern | Roles | Example Workflows |
|---|---|---|
| Single agent | agent |
meta, workflow-design, work-packages |
| Orchestrator + worker | orchestrator, worker |
work-package, prism family |
| Named multi-agent | Multiple specific roles | substrate-node-security-audit (7 roles), cicd-pipeline-security-audit (4 roles) |
Modes modify standard workflow behavior by skipping activities, overriding defaults, or adjusting execution. Each mode is activated by a workflow variable.
{
"modes": [
{
"id": "fast-track",
"name": "Fast Track",
"description": "Streamlined execution skipping optional activities",
"activationVariable": "fast_track_enabled",
"recognition": ["fast track", "quick mode", "streamlined"],
"skipActivities": ["optional-review", "deep-analysis"],
"defaults": {
"max_iterations": 1
},
"resource": "resources/fast-track-guidance.md"
}
]
}Mode Properties:
| Property | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Unique mode identifier |
name |
string | Yes | Human-readable mode name |
description |
string | No | Detailed description of mode behavior |
activationVariable |
string | Yes | Variable name that activates this mode when true |
recognition |
string[] | No | Patterns to detect mode activation from user intent |
skipActivities |
string[] | No | Activity IDs to skip in this mode |
defaults |
object | No | Default variable values when mode is active |
resource |
string | No | Path to resource file with detailed mode guidance |
Named artifact storage locations define where activities write their outputs. Keys are location identifiers referenced by activity artifacts definitions; values can be path strings (shorthand) or objects with metadata.
{
"artifactLocations": {
"planning": {
"path": "{planning_folder_path}",
"description": "Planning artifacts and analysis documents",
"gitignored": true
},
"adr": "{planning_folder_path}/adr"
}
}ArtifactLocation Properties (object form):
| Property | Type | Required | Description |
|---|---|---|---|
path |
string | Yes | Path pattern (supports variable interpolation via {variable_name}) |
description |
string | No | What artifacts this location stores |
gitignored |
boolean | No | Whether artifacts here are gitignored from the host project (default: false) |
Activities are the execution units of a workflow. Each activity contains steps, checkpoints, and transitions. Activities can be sequential (with transitions) or independent (matched via recognition patterns).
{
"activities": [
{
"id": "first-activity",
"version": "1.0.0",
"name": "Initial Activity",
"description": "The first activity of the workflow",
"skills": { "primary": "11-activity-worker" },
"steps": [],
"checkpoints": [],
"transitions": []
}
]
}Activity Properties:
| Property | Type | Description |
|---|---|---|
id |
string | Unique activity identifier |
version |
string | Semantic version (X.Y.Z) |
name |
string | Human-readable activity name |
description |
string | Activity description |
problem |
string | User problem this activity addresses (for intent matching) |
recognition |
string[] | Patterns to match user intent (for independent activities) |
skills |
object | Primary and supporting skill references |
required |
boolean | Whether activity is required (default: true) |
estimatedTime |
string | Time estimate (e.g., 10-15m, 1h, 2-3h) |
steps |
array | Steps within the activity |
checkpoints |
array | User decision points |
decisions |
array | Automated branching points |
loops |
array | Iteration constructs |
transitions |
array | Activity transition rules |
triggers |
array | Workflows to trigger from this activity |
entryActions |
array | Actions on entering activity |
exitActions |
array | Actions on exiting activity |
outcome |
string[] | Expected outcomes on completion |
context_to_preserve |
string[] | Context items to preserve |
rules |
array | Activity-level execution rules and constraints |
artifacts |
array | Artifacts produced or updated by this activity |
artifactPrefix |
string | Server-computed numeric prefix from activity filename (read-only) |
Steps are individual tasks within an activity:
{
"steps": [
{
"id": "step-1-1",
"name": "Verify prerequisites",
"description": "Check that all requirements are met",
"required": true
}
]
}Checkpoints pause execution and require user input:
{
"checkpoints": [
{
"id": "checkpoint-1",
"name": "Confirmation Checkpoint",
"message": "Do you want to proceed?",
"condition": {
"type": "simple",
"variable": "needs_confirmation",
"operator": "==",
"value": true
},
"required": true,
"blocking": true,
"options": [
{
"id": "proceed",
"label": "Yes, proceed",
"description": "Continue to the next activity",
"effect": {
"setVariable": { "user_confirmed": true }
}
},
{
"id": "cancel",
"label": "No, cancel",
"effect": {
"transitionTo": "cancelled"
}
}
]
}
]
}The condition field uses the same formal condition schema as steps, transitions, decisions, and loops (condition.schema.json). If omitted, the checkpoint is always presented.
Checkpoint Option Effects:
setVariable- Set workflow variablestransitionTo- Jump to a specific activityskipActivities- Skip specified activities
Decisions are automated branching points based on conditions:
{
"decisions": [
{
"id": "decision-1",
"name": "Path Selection",
"description": "Choose path based on variable",
"branches": [
{
"id": "branch-a",
"label": "Path A",
"condition": {
"type": "simple",
"variable": "option",
"operator": "==",
"value": "a"
},
"transitionTo": "activity-a"
},
{
"id": "branch-default",
"label": "Default Path",
"transitionTo": "activity-default",
"isDefault": true
}
]
}
]
}Loops enable iteration over collections or while conditions:
{
"loops": [
{
"id": "loop-1",
"name": "Task Loop",
"type": "forEach",
"variable": "current_task",
"over": "tasks",
"maxIterations": 100,
"steps": [
{
"id": "step-loop-1",
"name": "Process task"
}
]
}
]
}Loop Types: forEach, while, doWhile
Transitions define how to move between activities:
{
"transitions": [
{
"to": "next-activity",
"condition": {
"type": "simple",
"variable": "user_confirmed",
"operator": "==",
"value": true
}
},
{
"to": "fallback-activity",
"isDefault": true
}
]
}Triggers allow an activity to invoke another workflow:
{
"triggers": [
{
"workflow": "work-package",
"description": "Execute work-package workflow for each planned package",
"passContext": ["current_package", "priority_order"]
}
]
}The condition schema (condition.schema.json) defines expressions for controlling transitions, decisions, loops, and checkpoints.
Compare a variable to a value:
{
"type": "simple",
"variable": "status",
"operator": "==",
"value": "approved"
}Operators:
| Operator | Description | Example |
|---|---|---|
== |
Equal | "status" == "active" |
!= |
Not equal | "count" != 0 |
> |
Greater than | "score" > 80 |
< |
Less than | "attempts" < 3 |
>= |
Greater or equal | "level" >= 5 |
<= |
Less or equal | "errors" <= 10 |
exists |
Variable is defined | "user_id" exists |
notExists |
Variable is undefined | "error" notExists |
Combine conditions with logical operators:
AND - All conditions must be true:
{
"type": "and",
"conditions": [
{
"type": "simple",
"variable": "status",
"operator": "==",
"value": "ready"
},
{
"type": "simple",
"variable": "count",
"operator": ">",
"value": 0
}
]
}OR - At least one condition must be true:
{
"type": "or",
"conditions": [
{
"type": "simple",
"variable": "role",
"operator": "==",
"value": "admin"
},
{
"type": "simple",
"variable": "role",
"operator": "==",
"value": "moderator"
}
]
}NOT - Condition must be false:
{
"type": "not",
"condition": {
"type": "simple",
"variable": "blocked",
"operator": "==",
"value": true
}
}Conditions can be nested for complex logic:
{
"type": "and",
"conditions": [
{
"type": "simple",
"variable": "authenticated",
"operator": "==",
"value": true
},
{
"type": "or",
"conditions": [
{
"type": "simple",
"variable": "role",
"operator": "==",
"value": "admin"
},
{
"type": "simple",
"variable": "permissions",
"operator": "exists"
}
]
}
]
}The state schema (state.schema.json) tracks runtime execution of a workflow using activity IDs for navigation.
| Field | Type | Purpose |
|---|---|---|
workflowId |
string | Workflow being executed |
workflowVersion |
string | Version of workflow |
stateVersion |
integer | State schema version |
currentActivity |
string | Current activity ID |
currentStep |
integer | Current step index within activity (1-based) |
completedActivities |
string[] | Completed activity IDs |
skippedActivities |
string[] | Skipped activity IDs |
completedSteps |
Record<string, integer[]> | Steps completed per activity |
checkpointResponses |
Record<string, Response> | Checkpoint answers (key: "activity-checkpoint") |
decisionOutcomes |
Record<string, Outcome> | Decision results (key: "activity-decision") |
activeLoops |
LoopState[] | Currently executing loops |
variables |
Record<string, any> | Runtime variable values |
history |
HistoryEntry[] | Execution event log |
status |
enum | "running", "paused", "suspended", "completed", "aborted", "error" |
parentWorkflow |
ParentWorkflowRef | Reference to parent workflow (if triggered) |
triggeredWorkflows |
TriggeredWorkflowRef[] | Child workflows triggered from this one |
completedAt |
datetime | When workflow completed (only when status is "completed") |
lastError |
object | Most recent error (message, code, activity, step, timestamp) |
{
"workflowId": "my-workflow",
"workflowVersion": "1.0.0",
"stateVersion": 1,
"startedAt": "2026-01-22T10:00:00.000Z",
"updatedAt": "2026-01-22T10:05:00.000Z",
"currentActivity": "second-activity",
"currentStep": 1,
"completedActivities": ["first-activity"],
"skippedActivities": [],
"completedSteps": {
"first-activity": [1, 2]
},
"checkpointResponses": {},
"decisionOutcomes": {},
"activeLoops": [],
"variables": {
"user_confirmed": true
},
"history": [],
"status": "running",
"parentWorkflow": null,
"triggeredWorkflows": []
}| Property | Type | Description |
|---|---|---|
workflowId |
string | ID of the workflow being executed |
workflowVersion |
string | Version of the workflow |
startedAt |
datetime | When execution started |
updatedAt |
datetime | Last state update |
currentActivity |
string | Currently active activity ID (conditionally required when status is "running", "paused", or "suspended") |
| Status | Description |
|---|---|
running |
Workflow is actively executing |
paused |
Execution paused (awaiting user input) |
suspended |
Waiting for triggered child workflow to complete |
completed |
Workflow finished successfully |
aborted |
Workflow was cancelled |
error |
Workflow encountered an error |
When an activity triggers another workflow, the state tracks the relationship:
Parent Workflow Reference:
{
"parentWorkflow": {
"workflowId": "work-packages",
"activityId": "implementation",
"passedContext": { "current_package": "feature-auth" },
"returnTo": { "activityId": "implementation", "stepIndex": 4 }
}
}Triggered Workflows:
{
"triggeredWorkflows": [
{
"workflowId": "work-package",
"triggeredAt": "2026-01-22T10:00:00.000Z",
"triggeredFrom": { "activityId": "implementation", "stepIndex": 2 },
"status": "completed",
"returnedContext": { "pr_number": "123" }
}
]
}The history array tracks all workflow events:
{
"history": [
{
"timestamp": "2026-01-22T10:00:00.000Z",
"type": "workflow_started",
"activity": "first-activity"
},
{
"timestamp": "2026-01-22T10:01:00.000Z",
"type": "step_completed",
"activity": "first-activity",
"step": 1
},
{
"timestamp": "2026-01-22T10:02:00.000Z",
"type": "workflow_triggered",
"activity": "implementation",
"data": { "targetWorkflow": "work-package" }
}
]
}Event Types:
workflow_started,workflow_completed,workflow_aborted,workflow_triggered,workflow_returned,workflow_suspendedactivity_entered,activity_exited,activity_skippedstep_started,step_completedcheckpoint_reached,checkpoint_responsedecision_reached,decision_branch_takenloop_started,loop_iteration,loop_completed,loop_breakvariable_set,error
Here's a minimal valid workflow that demonstrates all key concepts:
{
"$schema": "../../schemas/workflow.schema.json",
"id": "example-workflow",
"version": "1.0.0",
"title": "Example Workflow",
"description": "A minimal workflow demonstrating key schema features",
"executionModel": {
"roles": [
{ "id": "agent", "description": "Single agent executing all activities" }
]
},
"variables": [
{
"name": "approved",
"type": "boolean",
"defaultValue": false
}
],
"initialActivity": "review",
"activities": [
{
"id": "review",
"version": "1.0.0",
"name": "Review",
"description": "Initial review and approval",
"skills": { "primary": "11-activity-worker" },
"estimatedTime": "5-10m",
"steps": [
{
"id": "step-gather",
"name": "Gather information"
}
],
"checkpoints": [
{
"id": "checkpoint-approve",
"name": "Approval Checkpoint",
"message": "Do you approve this item?",
"blocking": true,
"options": [
{
"id": "approve",
"label": "Approve",
"effect": {
"setVariable": { "approved": true }
}
},
{
"id": "reject",
"label": "Reject",
"effect": {
"setVariable": { "approved": false }
}
}
]
}
],
"transitions": [
{
"to": "process",
"condition": {
"type": "simple",
"variable": "approved",
"operator": "==",
"value": true
}
},
{
"to": "rejected",
"isDefault": true
}
]
},
{
"id": "process",
"version": "1.0.0",
"name": "Processing",
"skills": { "primary": "11-activity-worker" },
"steps": [
{
"id": "step-process",
"name": "Process the approved item"
}
]
},
{
"id": "rejected",
"version": "1.0.0",
"name": "Rejection",
"skills": { "primary": "11-activity-worker" },
"steps": [
{
"id": "step-notify",
"name": "Notify of rejection"
}
]
}
]
}Validate a workflow file:
npx tsx scripts/validate-workflow.ts path/to/workflow.jsonimport { validateWorkflow, safeValidateWorkflow } from './src/schema/workflow.schema';
// Throws on invalid
const workflow = validateWorkflow(data);
// Returns { success: true, data } or { success: false, error }
const result = safeValidateWorkflow(data);
if (result.success) {
console.log('Valid workflow:', result.data);
} else {
console.error('Validation errors:', result.error);
}| Error | Cause | Fix |
|---|---|---|
| Missing required property | id, version, title, or activities not provided |
Add the required property |
| Invalid version format | Version doesn't match X.Y.Z pattern |
Use semantic versioning |
| Invalid activity reference | initialActivity or transition to references non-existent activity |
Check activity IDs match |
| Checkpoint missing options | Checkpoint defined without any options | Add at least one option |
| Decision needs branches | Decision defined with fewer than 2 branches | Add at least 2 branches |
The activity schema (activity.schema.json) defines unified activities that combine intent matching (problem, recognition) with workflow execution (steps, checkpoints, decisions, loops, transitions, triggers). Activities are used both as standalone entry points and as workflow stages.
{
"id": "discover-session",
"version": "1.0.0",
"name": "Discover Session",
"problem": "Determine whether to resume an existing workflow session or start fresh.",
"recognition": ["start a workflow", "resume a workflow", "continue a workflow"],
"skills": {
"primary": "state-management"
},
"steps": [
{ "id": "identify-target", "name": "Identify target workflow and context" },
{ "id": "scan-planning-folders", "name": "Scan planning folders for saved sessions" }
],
"outcome": ["Workflow target identified", "Prior state located if available"],
"context_to_preserve": ["target_workflow", "has_saved_state"]
}| Property | Type | Description |
|---|---|---|
id |
string | Unique activity identifier |
version |
string | Semantic version (e.g., 3.0.0) |
name |
string | Human-readable activity name |
skills |
object | Primary and supporting skill references |
| Property | Type | Description |
|---|---|---|
description |
string | Detailed description |
problem |
string | User problem this activity addresses (for intent matching) |
recognition |
string[] | Patterns to match user intent (for independent activities) |
steps |
Step[] | Ordered execution steps |
checkpoints |
Checkpoint[] | User decision points |
decisions |
Decision[] | Automated branching points |
loops |
Loop[] | Iteration constructs |
transitions |
Transition[] | Navigation to other activities |
triggers |
WorkflowTrigger[] | Workflows to trigger from this activity |
entryActions |
Action[] | Actions on entering activity |
exitActions |
Action[] | Actions on exiting activity |
outcome |
string[] | Expected outcomes when activity completes |
context_to_preserve |
string[] | Context items to preserve |
required |
boolean | Whether activity is required (default: true) |
estimatedTime |
string | Time estimate (e.g., "10-15m") |
rules |
string[] | Activity-level execution rules and constraints |
artifacts |
Artifact[] | Artifacts produced or updated by this activity |
artifactPrefix |
string | Server-computed numeric prefix from activity filename (read-only) |
Independent Activities (e.g., meta workflow):
- Have
recognitionpatterns for intent matching - No
transitionsto other activities - Matched via
list_workflowsandstart_session
Sequential Activities (e.g., work-package workflow):
- Have
transitionsconnecting them - Form a workflow flow
- Require
initialActivityon parent workflow
A complete activity definition with workflow trigger:
{
"id": "implementation",
"version": "1.1.0",
"name": "Implementation",
"description": "Execute each planned work package by triggering the work-package workflow",
"problem": "Planned work packages need to be implemented one at a time",
"skills": {
"primary": "11-activity-worker"
},
"triggers": [
{
"workflow": "work-package",
"description": "Each iteration starts the work-package workflow for one planned package",
"passContext": ["current_package", "priority_order"]
}
],
"steps": [
{ "id": "select", "name": "Select next work package" },
{ "id": "trigger", "name": "Trigger work-package workflow" },
{ "id": "update", "name": "Update roadmap status" }
],
"loops": [
{
"id": "package-iteration",
"name": "Package Iteration",
"type": "forEach",
"variable": "current_package",
"over": "remaining_packages"
}
],
"outcome": [
"All planned work packages implemented",
"Roadmap status reflects completion"
],
"context_to_preserve": [
"current_package",
"completed_packages",
"remaining_packages",
"parent_workflow"
]
}The skill schema (skill.schema.json) defines agent capabilities for workflow execution. Skills describe tool orchestration patterns, execution guidance, and error handling strategies.
{
"id": "11-activity-worker",
"version": "2.0.0",
"capability": "Bootstrap and execute a single workflow activity with consistent tool usage",
"tools": {},
"state": {},
"errors": {}
}| Property | Type | Description |
|---|---|---|
id |
string | Unique skill identifier |
version |
string | Semantic version (e.g., 2.0.0) |
capability |
string | What this skill enables agents to do |
| Property | Type | Description |
|---|---|---|
description |
string | Detailed skill description |
architecture |
object | Architectural principles and layers |
tools |
object | Tool definitions and usage patterns |
flow |
string[] | Ordered execution steps |
matching |
object | Goal-to-activity matching strategies |
state |
object | State structure and update patterns |
interpretation |
object | How to interpret workflow constructs |
rules |
object | Name-value pairs: each key is a rule name (e.g. configuration-invariant); each value is a single rule string or an array of rule strings for grouped rules. |
errors |
object | Error definitions and recovery strategies |
inputs |
array | Inputs the skill expects from context: array of items. Each item has id (required; hyphen-delimited), optional description, required, default. When a protocol step uses an existing artifact (e.g. loads from a path), the skill MUST declare one or more associated input entries. Mirrors output structure. |
protocol |
object | Phase-keyed steps only: each key is a step/phase id (e.g. load-checklist[1]), value is an array of imperative bullet strings. No description in protocol (use skill-level description). |
output |
array | What the skill produces: array of output items. Each item has id (required; generic hyphen-delimited identifier, not a filename), optional description, optional components (named object), and optional artifact (when present: name = filename to use when persisting, e.g. 01-audit-report.md). |
resources |
string[] | Resource indices or IDs this skill depends on (e.g. "02", "04", "08") |
initialization |
object | How to initialize state when skill begins (trigger, state values) |
resumption |
object | How to resume after interruption (description, steps, note) |
state_structure |
object | State field definitions (key-value string pairs) |
update_patterns |
object | State update triggers and ordered actions |
numeric_format |
object | Description and examples for numeric formatting |
status_values |
object | Valid status values and their meanings |
checkpoint_response_format |
object | Format for checkpoint responses |
decision_outcome_format |
object | Format for decision outcomes |
history_event_types |
object | Categorized event types for history tracking |
history_entry_format |
object | Format for history entries |
Optional structured procedure: step/phase keys only (no description in protocol; use the skill-level description). Each key is a step identifier (TOON array keys use a [N] suffix, e.g. load-checklist[1]); each value is an array of imperative bullet strings for that step.
{
"protocol": {
"load-checklist[1]": ["Read the checklist from the resource.", "Verify version matches workflow."],
"execute-step[1]": ["Run the step logic.", "Record outcome."]
}
}Bullets that contain a colon in the text must be quoted in TOON so the parser treats them as a single string.
Describe how and when to use each tool:
{
"tools": {
"get_workflow": {
"when": "Loading workflow for execution",
"params": "session_token",
"returns": "Complete workflow definition",
"preserve": ["id", "initialActivity", "variables", "rules", "activities"]
},
"next_activity": {
"when": "Entering a new activity",
"params": "session_token, activity_id",
"returns": "Activity details with steps, checkpoints, decisions",
"preserve": ["steps", "checkpoints", "decisions", "transitions"]
}
}
}| Field | Purpose |
|---|---|
when |
Conditions or triggers for using this tool |
params |
Parameters the tool accepts |
returns |
What the tool returns |
next |
Suggested next tool to call |
action |
Action to take with the result |
usage |
How to use the tool effectively |
preserve |
Fields to preserve from the result |
For skills that define architectural patterns:
{
"architecture": {
"principle": "Goals resolve to activities; activities resolve to skills",
"layers": [
"User Goal (problem domain) → Activity",
"Activity → Skill(s) (solution domain)",
"Skill → Tools (execution domain)"
],
"gap_detection": "If a goal matches a skill but no activity exists, create one"
}
}For skills that involve goal resolution:
{
"matching": {
"quick_match": "Use exact or fuzzy match against quick_match keys",
"fallback": "If no quick_match, compare user goal to activity.problem",
"ambiguous": "If multiple activities match, ask user to clarify",
"never": "NEVER skip activity matching to use a skill directly"
}
}Define error conditions and recovery strategies:
{
"errors": {
"workflow_not_found": {
"cause": "Invalid workflow_id parameter",
"recovery": "Call list_workflows to discover valid IDs"
},
"no_matching_activity": {
"cause": "User goal doesn't match any existing activity",
"detection": "Goal could be served by existing skill but no activity maps to it",
"resolution": [
"1. Identify which skill(s) would serve this goal",
"2. Create a new activity that maps goal to skill",
"3. Add activity to prompts/intents/ with recognition patterns"
],
"note": "This is a design gap, not a user error"
}
}
}A minimal skill demonstrating key concepts:
{
"id": "example-skill",
"version": "1.0.0",
"capability": "Demonstrate skill schema structure",
"description": "A minimal skill showing required and optional fields",
"tools": {
"list_workflows": {
"when": "Beginning a new task",
"params": "none",
"returns": "List of available workflows"
},
"next_activity": {
"when": "Ready to transition to an activity",
"params": "session_token, activity_id",
"returns": "Activity definition",
"next": "get_step_skill"
},
"get_step_skill": {
"when": "After loading an activity",
"params": "session_token, step_id",
"returns": "Skill definition for the step"
}
},
"flow": [
"1. Call list_workflows to understand available workflows",
"2. Match task to available resources",
"3. Call next_activity to load the activity",
"4. Call get_step_skill to load execution guidance"
],
"protocol": {
"discover[1]": ["Call list_workflows to find available workflows.", "Select the appropriate workflow for the task."],
"execute[2]": ["Load the activity via next_activity.", "Execute each step following skill guidance."]
},
"errors": {
"resource_not_found": {
"cause": "Requested resource does not exist",
"recovery": "Call list_workflows to see available options"
}
}
}- API Reference - MCP server tools and endpoints
- Development Guide - Building and testing the server