Schema reference

The JSON Schemas that define workflows, activities, techniques, conditions, and session state. The Zod schemas in src/schema/ are the source of truth; the JSON files under schemas/ are generated from them (npm run build:schemas) and validate workflow definitions at authoring time.

The field tables below show each schema's top-level shape and are rendered from the checked-in schema files. For authoring guidance — how the pieces fit together when writing a workflow — read the schema guide.

activity.schema.json

Activity definition schema — unified ordered, kind-tagged steps[] (technique | action | checkpoint | loop).

Edit source on GitHub

Top-level fields

FieldTypeRequiredDescription
idstringyesUnique identifier for the activity
versionstringyesSemantic version of the activity
namestringyesHuman-readable activity name
descriptionstringnoDetailed description of the activity
variablesobjectnoThe session variables this activity reads and writes. Its writes are declarations contributed to the including workflow's variable set; its reads are the names it needs that workflow to supply.
techniquesstring[]noActivity-wide technique references (:: paths); bundled into get_activity.
bundleTechniquesobjectnoOpt-in hybrid bundling: get_activity inlines each step technique whose composed wire form is at most maxChars and whose gate answers true at activity open; larger ones, and those whose gate has no answer yet, remain lazy-fetched via get_technique. Bundled deliveries are recorded as technique_bundled history events and satisfy the manifest fidelity check.
steps(technique | action | checkpoint | loop)[]noOrdered, kind-tagged execution steps for this activity
exitsobject[]noNamed outcomes of this activity, one of which it takes when its steps end. Each is bound to a destination in the workflow's graph; an unbound exit fails the workflow load. Omitted on an activity that is terminal by omission.
exits[].idstringyesOutcome name, unique within the activity. Kebab-case, in the activity's vocabulary — never an activity id.
exits[].labelstringnoHuman-readable statement of the outcome.
exits[].whenstringnoInline boolean expression selecting this exit, evaluated agent-side against the variable bag in the when dialect the step gates use. Omitted on an exit only a checkpoint option selects, and on the default exit.
exits[].isDefaulttruenoThe outcome when no when matched and no checkpoint option selected an exit — including a checkpoint dismissed because its condition was not met. Declared exactly once on an activity with two or more exits; isDefault: false is redundant and rejected.
exits[].immediatetruenoSelecting this exit at a checkpoint ends the step sequence there: the remaining steps do not run and the step-manifest check accounts for them. Declared for the aborts, where the tail would otherwise run against the user's decision. Without it an exit is recorded when chosen and taken when the sequence ends. immediate: false is redundant and rejected.
triggersobject[]noWorkflows the orchestrator dispatches from this activity (via dispatch_child with an explicit workflow_id); the server does not act on trigger declarations.
triggers[].workflowstringyesID of the workflow to trigger
triggers[].descriptionstringnoDescription of when/why this workflow is triggered
triggers[].passContextstring[]noContext variable names the dispatching agent relays to the child workflow. The server does not copy them — a child session's bag starts from the child workflow's own declared defaults, nothing more.
outcomestring[]noExpected outcomes when activity completes successfully. Advisory — the server does not reconcile them against activity_manifest outcomes.
requiredbooleannoWhether this activity is required in the workflow Default: true
rulesstring[]noActivity-level rules and constraints that agents must follow
artifactPrefixstringnoNumeric prefix for artifact filenames, inferred from the activity filename (e.g., "02" from 02-design-philosophy.yaml). Server-computed — do not set in definition files.

condition.schema.json

Condition expression schema

Edit source on GitHub

One of 4 variants: simple, and, or, not.

session-file.schema.json

Server-managed session file (session.

Edit source on GitHub

Top-level fields

FieldTypeRequiredDescription
schemaVersion1yes-
sessionIndexstringyes-
workflowIdstringyes-
workflowVersionstringyes-
agentIdstringyes-
seqintegeryes-
tsintegeryes-
startedAtstringyes-
currentActivitystringnoDefault: ""
currentTechniquestringnoDefault: ""
exitstringnoName of the exit the previous activity took. Default: ""
activeCheckpointobjectno-
variablesobjectnoDefault: {}
completedActivitiesstring[]noDefault: []
checkpointResponsesobjectnoDefault: {}
historyobject[]noDefault: []
history[].timestampstringyes-
history[].type"workflow_started" | "workflow_completed" | "workflow_aborted" | "workflow_triggered" | "workflow_returned" | "workflow_suspended" | "activity_entered" | "activity_exited" | "activity_skipped" | "step_started" | "step_completed" | "checkpoint_reached" | "checkpoint_response" | "checkpoint_replayed" | "decision_reached" | "decision_branch_taken" | "loop_started" | "loop_iteration" | "loop_completed" | "loop_break" | "variable_set" | "error" | "technique_fetched" | "resource_fetched" | "technique_bundled" | "variables_seeded" | "activity_usage" | "activity_dispatched" | "activity_redelivered" | "batch_refused" | "activity_outcome" | "progress_published"yes-
history[].activitystringno-
history[].stepintegerno-
history[].checkpointstringno-
history[].decisionstringno-
history[].loopstringno-
history[].dataobjectno-
history[].errorobjectno-
status"running" | "completed" | "aborted"noDefault: "running"
triggeredWorkflowsobject[]noDefault: []
triggeredWorkflows[].workflowIdstringyes-
triggeredWorkflows[].sessionIndexstringyes-
triggeredWorkflows[].triggeredAtstringyes-
triggeredWorkflows[].triggeredFromobjectyes-
triggeredWorkflows[].status"running" | "completed" | "aborted" | "error"yes-
triggeredWorkflows[].completedAtstringno-
triggeredWorkflows[].returnedContextobjectno-
triggeredWorkflows[].statesession-fileno-
planningFolderPathstringno-
repostringno-
contextMode"persistent" | "fresh"no-
deliveredContentobjectno-
declaredArtifactsobject[]no-
declaredArtifacts[].idstringyes-
declaredArtifacts[].namestringyes-
declaredArtifacts[].pathstringno-
parentSessionsession-fileno-

state.schema.json

Workflow state schema

Edit source on GitHub

Top-level fields

FieldTypeRequiredDescription
workflowIdstringyes-
workflowVersionstringyes-
stateVersionintegernoDefault: 1
startedAtstringyes-
updatedAtstringyes-
completedAtstringno-
currentActivitystringno-
currentStepintegerno-
completedActivitiesstring[]noDefault: []
completedStepsobjectnoDefault: {}
checkpointResponsesobjectnoDefault: {}
activeLoopsobject[]noDefault: []
activeLoops[].activityIdstringyes-
activeLoops[].loopIdstringyes-
activeLoops[].currentIterationintegeryes-
activeLoops[].totalItemsintegerno-
activeLoops[].currentItemanyno-
activeLoops[].startedAtstringyes-
variablesobjectnoDefault: {}
historyobject[]noDefault: []
history[].timestampstringyes-
history[].type"workflow_started" | "workflow_completed" | "workflow_aborted" | "workflow_triggered" | "workflow_returned" | "workflow_suspended" | "activity_entered" | "activity_exited" | "activity_skipped" | "step_started" | "step_completed" | "checkpoint_reached" | "checkpoint_response" | "checkpoint_replayed" | "decision_reached" | "decision_branch_taken" | "loop_started" | "loop_iteration" | "loop_completed" | "loop_break" | "variable_set" | "error" | "technique_fetched" | "resource_fetched" | "technique_bundled" | "variables_seeded" | "activity_usage" | "activity_dispatched" | "activity_redelivered" | "batch_refused" | "activity_outcome" | "progress_published"yes-
history[].activitystringno-
history[].stepintegerno-
history[].checkpointstringno-
history[].decisionstringno-
history[].loopstringno-
history[].dataobjectno-
history[].errorobjectno-
status"running" | "paused" | "suspended" | "completed" | "aborted" | "error"noDefault: "running"
parentWorkflowobjectno-
triggeredWorkflowsobject[]noDefault: []
triggeredWorkflows[].workflowIdstringyes-
triggeredWorkflows[].planningSlugstringno-
triggeredWorkflows[].sessionIndexstringno-
triggeredWorkflows[].triggeredAtstringyes-
triggeredWorkflows[].triggeredFromobjectyes-
triggeredWorkflows[].status"running" | "completed" | "aborted" | "error"yes-
triggeredWorkflows[].completedAtstringno-
triggeredWorkflows[].returnedContextobjectno-
lastErrorobjectno-

technique.schema.json

Technique definition schema for workflow-server

Edit source on GitHub

Top-level fields

FieldTypeRequiredDescription
idstringyesUnique identifier for the technique
versionstringyesSemantic version of the technique
capabilitystringyesWhat this technique enables agents to do
provenance_notestringnoDelivery-only, server-populated on a step-bound get_technique: states the output delivery mechanics that the source:/destination: annotations rely on. Never authored in technique markdown.
rulesrulesDefinitionno-
inputsinputsDefinitionno-
inherited_inputsinheritedInputsno-
protocolprotocolDefinitionno-
outputsoutputsDefinitionno-
inherited_outputsinheritedOutputsno-

workflow.schema.json

Workflow definition schema

Edit source on GitHub

Top-level fields

FieldTypeRequiredDescription
$schemastringno-
idstringyesUnique workflow identifier
versionstringyesSemantic version
titlestringyesHuman-readable workflow title
descriptionstringnoDetailed workflow description
authorstringnoAuthor metadata; not read by the server.
tagsstring[]no-
rulesobjectnoWorkflow rules partitioned by audience: workflow (orchestrator-only) and activity (inherited by every activity, injected into get_activity). A rule is plain text; text two workflows both need belongs in the conduct technique whose audience it binds.
fragmentsobjectnoShared checkpoint bodies, declared once and imported by ref ([workflow::]name) from a kind:checkpoint step — this workflow's or another's. Resolved at load; agents always receive materialized content.
variablesobject[]noThe variables this workflow file owns: facts about the session and policy spanning activities. A variable an activity writes is declared by that activity, under its own variables.writes, and contributed here when the activity joins this workflow's graph — get_workflow renders the whole set, and two declarations of one name that disagree on type or default fail the load. The session variable bag is seeded from each declaration's defaultValue at session creation; thereafter the server writes it through checkpoint setVariable effects and through the worker outputs an orchestrator relays as next_activity's variables_changed.
variables[].namestring | "requirements" | "features" | "exclusions" | "dimensions" | "tasks" | "results" | "submodules" | "paths" | "fields" | "filters" | "stats" | "effects" | "substitutions" | "findings" | "assumptions" | "subsystems" | "transitions" | "options" | "branches" | "agents" | "changes" | "failures" | "items" | "files" | "gaps" | "outcomes" | "body" | "query" | "repo" | "owner" | "number" | "title" | "branch" | "diff" | "limit" | "name" | "sha" | "url" | "head" | "base" | "ref" | "labels" | "path" | "cursor" | "cql" | "jql" | "description" | "assignee" | "depth" | "direction" | "summary" | "state" | "target" | "adr" | "type" | "mode" | "kind"yesQualified snake_case noun phrase (>=2 words, AP-60), or an enumerated bare-word exemption.
variables[].type"string" | "number" | "boolean" | "array" | "object"yesDeclared type. The server validates checkpoint setVariable values against it, warn-only: a mismatch is stored as written and surfaced in _meta.validation and on the variable_set history event. Agents honor it for their own writes.
variables[].descriptionstringno-
variables[].valuesstring[]noThe complete set of values a string variable admits. The server validates writes against it warn-only, as it does the declared type.
variables[].defaultValueanynoInitial value the server seeds into the session variable bag at session creation (start_session fresh sessions and dispatch_child children), recorded as one variables_seeded history event. Do not gate a defaulted variable with exists/notExists — seeding makes the gate constant (check:variable-model enforces this).
variables[].requiredbooleannoAuthoring metadata; the server does not check that the variable is ever set. Default: false
techniquesobjectnoWorkflow techniques partitioned by audience: workflow (orchestrator, bundled into get_workflow) and activity (inherited by every activity, injected into get_activity).
initialActivitystringnoID of the first activity to execute. Required for sequential workflows, optional when all activities are independent entry points.
graphobjectnoThe workflow's shape: for each activity, where each of its exits leads. This is the single home for the routing — an activity names outcomes, the workflow names destinations, so a borrowed activity sits in this graph without its lending workflow having a say. Omitted only by a workflow whose activities declare no exits.
activitiesobject[]noActivities that comprise this workflow. An activity whose exits the graph binds sits in a sequence; one declaring no exits is terminal. Omitted in definition files where activities are separate files.
activities[].idstringyesUnique identifier for the activity
activities[].versionstringyesSemantic version of the activity
activities[].namestringyesHuman-readable activity name
activities[].descriptionstringnoDetailed description of the activity
activities[].variablesobjectnoThe session variables this activity reads and writes. Its writes are declarations contributed to the including workflow's variable set; its reads are the names it needs that workflow to supply.
activities[].techniquesstring[]noActivity-wide technique references (:: paths); bundled into get_activity.
activities[].bundleTechniquesobjectnoOpt-in hybrid bundling: get_activity inlines each step technique whose composed wire form is at most maxChars and whose gate answers true at activity open; larger ones, and those whose gate has no answer yet, remain lazy-fetched via get_technique. Bundled deliveries are recorded as technique_bundled history events and satisfy the manifest fidelity check.
activities[].steps(technique | action | checkpoint | loop)[]noOrdered, kind-tagged execution steps for this activity
activities[].exitsobject[]noNamed outcomes of this activity, one of which it takes when its steps end. Each is bound to a destination in the workflow's graph; an unbound exit fails the workflow load. Omitted on an activity that is terminal by omission.
activities[].exits[].idstringyesOutcome name, unique within the activity. Kebab-case, in the activity's vocabulary — never an activity id.
activities[].exits[].labelstringnoHuman-readable statement of the outcome.
activities[].exits[].whenstringnoInline boolean expression selecting this exit, evaluated agent-side against the variable bag in the when dialect the step gates use. Omitted on an exit only a checkpoint option selects, and on the default exit.
activities[].exits[].isDefaulttruenoThe outcome when no when matched and no checkpoint option selected an exit — including a checkpoint dismissed because its condition was not met. Declared exactly once on an activity with two or more exits; isDefault: false is redundant and rejected.
activities[].exits[].immediatetruenoSelecting this exit at a checkpoint ends the step sequence there: the remaining steps do not run and the step-manifest check accounts for them. Declared for the aborts, where the tail would otherwise run against the user's decision. Without it an exit is recorded when chosen and taken when the sequence ends. immediate: false is redundant and rejected.
activities[].triggersobject[]noWorkflows the orchestrator dispatches from this activity (via dispatch_child with an explicit workflow_id); the server does not act on trigger declarations.
activities[].triggers[].workflowstringyesID of the workflow to trigger
activities[].triggers[].descriptionstringnoDescription of when/why this workflow is triggered
activities[].triggers[].passContextstring[]noContext variable names the dispatching agent relays to the child workflow. The server does not copy them — a child session's bag starts from the child workflow's own declared defaults, nothing more.
activities[].outcomestring[]noExpected outcomes when activity completes successfully. Advisory — the server does not reconcile them against activity_manifest outcomes.
activities[].requiredbooleannoWhether this activity is required in the workflow Default: true
activities[].rulesstring[]noActivity-level rules and constraints that agents must follow
activities[].artifactPrefixstringnoNumeric prefix for artifact filenames, inferred from the activity filename (e.g., "02" from 02-design-philosophy.yaml). Server-computed — do not set in definition files.