Workflow definition reference
Bundle paths, Step kinds, typed schemas, prompt references, child Workflows, commands, and execution limits.
Use this reference while editing workflow.yaml. The Workflow guide provides a complete Session Step example and the create-to-result procedure. Definitions use YAML with schema_version: 1; unsupported fields are rejected. YAML anchors, aliases, merge keys, and tags are not supported. Validate the actual Draft before publishing or running it.
Definition fields
| Field | Contract |
|---|---|
schema_version | Required integer 1. |
name | Required non-empty display name; the Draft directory slug identifies the Workflow. |
description | Required description string. |
inputs | Required closed object schema for Run input. Use empty properties: {} for no inputs. |
steps | Required map of 1–64 Steps. Keys match ^[a-z][a-z0-9_-]{0,63}$. |
outputs | Optional map from public output name to one complete Step output reference. This is a binding map, not a JSON Schema. Default: no exported values. |
steps.<key>.needs | Required list of direct dependencies; [] for a root. Up to 32 per Step and 256 edges overall. Unknown or repeated dependencies and cycles are rejected. |
steps.<key>.when | Optional condition on a direct dependency output; applies to any Step kind. Use value and exactly one of equals or otherwise: true. |
steps.<key>.join | Optional boolean, default false. true requires a Session, non-empty needs, and no when. |
steps.<key>.session | Exactly one Step kind. Requires agent, runtime, and prompt.file. A Session Step also declares an outputs schema. |
steps.<key>.decision | Exactly one Step kind. Requires static non-empty question and body.file; optional options. Do not declare Step outputs. |
steps.<key>.workflow | Exactly one Step kind. Requires published child slug; inputs binds child fields. Do not declare Step outputs. |
For a Session Step, runtime.kind is mandatory. runtime.config is a map of option IDs to strings or booleans and may be omitted or set to {}. Strings are ACP option value IDs, not arbitrary display labels; numeric values are not accepted. Discover available kinds and options with chat project members <team>/<project> --runtime-profiles. Agent membership, owner availability, and Runtime compatibility still matter at execution.
needs orders execution; it is not a conditional expression. A Session, Decision, and child Workflow cannot share one Step definition. Files in scripts/ are supporting assets that an agent may use; their presence does not create a shell Step or run a command automatically.
Conditions, skipped Steps, and joins
Version prerequisite: These fields require a compatible API/server, WebUI, and CLI. Availability in your environment has not been confirmed here. Before using them, confirm the deployed version with your administrator, validate the actual Draft against that server, and check a trial Run's conditions, skip reasons, and outputs. An unknown-field error or missing condition/skip display is a reason to stop and check versions, not to remove the condition and run unconditionally. See the complete branching example.
needs still declares dependencies; add when explicitly to select work by result. when.value must be one complete {{ steps.<direct-need>.outputs.<path> }} reference to a required boolean or string enum. Decision answer is the only free-text string exception. equals preserves type and value: boolean true differs from string "true"; strings are not trimmed or interpreted. For enums, the comparison must be a declared value. Run inputs, optional paths, arbitrary expressions, coercion, loops, and error-recovery branches are not supported.
otherwise: true matches only when none of the equals comparisons on the same normalized reference anywhere in the Revision match. At least one such equals is required; at most one otherwise is allowed per reference. Multiple Steps with the same matching value all become eligible. A boolean or enum may have uncovered values with no branch work.
For Decision answers, equals must match a published option. Branching on an answer requires an otherwise Session, whose only needs entry is that Decision and whose prompt directly references its answer. It receives free text and uncovered options. Preserve the human's conditions and authority; ask for a further decision when needed. Matching an answer grants no new authority, and editing the Ask later does not change the pinned answer revision.
A condition mismatch derives skipped; an ordinary Step depending on a skipped Step also skips. No Attempt, Session, Ask, signal, or child Run is created for the skipped Step. Failure, cancellation, blocked work, and unresolved dependencies are not successful skips.
A join: true Session waits for every direct dependency to succeed or skip, and runs even when all of them skip. It does not bypass failure or cancellation. Its prompt must not directly reference steps.*.outputs.*. Instead, read the server's Workflow dependency results attachment immediately before the completion instructions: a canonical JSON array in Step-key order, with step, state, and either accepted outputs or skip reason for each dependency. It counts toward the 100,000-byte prompt limit and is preserved for retry and prompt history.
Top-level outputs cannot reference a potentially skipped Step, including ordinary downstream Steps that inherit skip. Export a required join output instead. All Steps being succeeded or skipped can finish a Run successfully, but Run outputs require accepted successful completions from every executed Step. A child Run's success alone does not establish that its parent Step has accepted its outputs. Check the parent Run and actual outputs before using the result.
Bundle files and paths
The editable root is aachat/projects/<team>/<project>/workflows/<slug>/. A Bundle contains required workflow.yaml, optional root README.md, and text files under prompts/ or scripts/. Session prompt.file and Decision body.file point to a file below prompts/ that exists in the Bundle.
Use relative, case-sensitive paths and ordinary UTF-8 text. Absolute paths, backslashes, empty or dot path segments, dotfiles, _published, duplicate paths, and U+0000 are rejected. The Bundle is not a general repository snapshot; keep unrelated files outside it. The executing Attempt sees only its pinned read-only Bundle at $AA_WORKFLOW_DIR.
Supported input and output schemas
The root of Run inputs and Session Step outputs must be an object. Every object, including nested objects, must have additionalProperties: false. Declare fields under properties and required fields under required. An optional property can be absent; do not use null as a substitute for an absent field.
| Supported construct | Values or keywords |
|---|---|
| Types | object, string, number, integer, boolean, array |
| Object | properties, required, additionalProperties |
| Array | items, minItems, maxItems |
| String | minLength, maxLength, pattern, format |
| Number | minimum, maximum |
| Shared | type, enum, description |
The only supported format is uri. Arbitrary JSON Schema is not accepted: no $ref, allOf, oneOf, anyOf, nullable types, or union type arrays. Use small inline schemas. A document path can be an ordinary string; format: uri is for a URI, not a promise that an artifact exists or that its access permissions are suitable.
Prompt references and exported values
A Session prompt may contain text and {{ inputs.reader }} or {{ steps.write.outputs.greeting }}. A Step output reference must name a direct dependency declared in needs; depending on an intermediate Step does not expose all of its ancestors. Referenced schema paths must exist. The generated completion marker {{ aachat.step_completion }} must occur exactly once at the end of every Session prompt, with only whitespace after it.
Decision bodies can use the same input and direct dependency references but must not contain the completion marker. Questions and options are static. The Run creates the Ask and accepts the human answer; no agent submits a Decision completion payload.
Top-level outputs names map to Step output paths that are required by the source schema, such as greeting: "{{ steps.write.outputs.greeting }}". A top-level output cannot reference Run input directly. The server derives a closed output schema from the bindings. Successful child output is written once to its parent Step before downstream work starts.
Complete child and Decision example
First publish greeting from the guide in this same Project. Then create the approve-greeting Draft with chat workflow init approve-greeting --project <team>/<project> and write this workflow.yaml:
schema_version: 1
name: approve-greeting
description: Ask a human to review a generated greeting.
inputs:
type: object
additionalProperties: false
properties:
reader:
type: string
minLength: 1
required: [reader]
outputs:
greeting: "{{ steps.compose.outputs.greeting }}"
answer: "{{ steps.review.outputs.answer }}"
steps:
compose:
needs: []
workflow:
slug: greeting
inputs:
reader: "{{ inputs.reader }}"
review:
needs: [compose]
decision:
question: Is this greeting ready to use?
body:
file: prompts/review.md
options: [Use it, Revise it]Create prompts/review.md:
Please review this greeting for {{ inputs.reader }}:
{{ steps.compose.outputs.greeting }}
Choose whether it is ready, or explain the revision needed.Validate, optionally run the Draft with {"reader":"Alex"}, and publish using the guide's procedure with approve-greeting as the slug. The child produces greeting, and then the human Run starter (or the starting agent's human owner) receives the Ask. There is no configurable Decision assignee. A successful Run exports both greeting and answer. Selecting Revise it still completes the Decision with that answer; this definition has no subsequent revision Step. Add an explicit downstream Session Step to interpret the answer, or use when with the required otherwise Session to select branches.
Decision options must be omitted/empty for free text, or contain 2–5 distinct values. Do not add outputs to the Decision: its derived schema is an object with required string answer. The server fixes the accepted answer revision; editing the Ask afterward cannot change this Run.
A child workflow.inputs entry is either a literal JSON value or a single complete input/direct-dependency reference. Do not interpolate text around a reference. Bind every required child input, and provide only fields accepted by its schema. Every referenced source path must be required, even for an optional destination input. Its schema must be a subset of the destination contract, including supported constraints; matching only the primitive type is insufficient. For example, reader: Alex is a literal alternative to reader: "{{ inputs.reader }}".
The server pins the child's current published Revision during validation for run/publication. The child must be available in the same Project, and that pinned child may contain only Session and Decision Steps. Nested child Workflows are rejected. Publishing a newer child later does not change an existing parent Revision or Run. Revalidate and publish the parent Draft to adopt it. Open a failed child Run to repair its inner Step; cancel a child through the parent Run.
Command reference
These are Session-agent commands. Substitute real identifiers. Most Project commands accept --project <team>/<project> or infer the Project from cwd. validate requires the Draft's Project cwd and server access. publish and run --draft derive the Project from the Draft path. complete targets the current Attempt and takes no Run ID.
| Operation | Invocation |
|---|---|
| Create Draft | chat workflow init <slug> --project <team>/<project> |
| Validate | From the Draft Project: chat workflow validate workflows/<slug> |
| Published list | chat workflow list --project <team>/<project> [--last 50] [--before <cursor>] |
| Published contract and Step list (pre-run checks) | chat workflow show <slug> --project <team>/<project> |
| History | chat workflow runs [<slug>] --project <team>/<project> [--last 50] [--before <cursor>] |
| Draft Run | chat workflow run --draft <draft-path> --stdin |
| Published Run | chat workflow run <slug> --project <team>/<project> --stdin [--wait] |
| Publish | chat workflow publish <draft-path> |
| Run detail | chat workflow status <run-id> --project <team>/<project> |
| Cancel | chat workflow cancel <run-id> --project <team>/<project> |
| Retry | chat workflow retry <run-id> --step <key> --project <team>/<project> |
| Complete Attempt | chat workflow complete --stdin |
| Attempt feedback | chat workflow feedback [<run-id> --step <key> --project <team>/<project>] [--attempt N] --stdin |
Square brackets above mean optional arguments; do not type them. run takes exactly one of --stdin and --input-file <path>. list and runs page sizes are 1–100, default 50. Project-wide runs shows roots; passing a Workflow slug includes its root and child Runs, with parent identity. init, run, and retry accept --client-nonce <uuid> for retrying the exact same request; do not reuse a nonce for changed input. Always obey available_actions and structured recovery responses. --wait registers durable waiting and does not block the CLI.
Limits and how to recover
| Surface | Limit | If exceeded |
|---|---|---|
| One Bundle file | 256 KiB | Shorten or split supporting text. |
| Whole Bundle | 1 MiB, 128 files | Remove unrelated assets. |
| Relative path | 256 UTF-8 bytes | Shorten paths. |
| Dependency graph | 64 Steps, 32 needs per Step, 256 edges | Reduce the graph within the one-level composition rule. |
| Rendered Session prompt | 100,000 bytes including generated completion instructions | Shorten prompt/input/upstream text. |
| Decision question / each option | Non-empty; 2,000 / 200 bytes | Shorten the static text; keep 2–5 distinct options or use free text. |
| Rendered Decision body | 100,000 bytes | Correct the immutable input or definition in a new Run. |
| Run input | 128 KiB, JSON depth 32 | Store large content in a Project resource and pass a reference; flatten deeply nested input. |
| Completion JSON / Run outputs | 128 KiB, JSON depth 32 | Return short artifact references. |
| Failed completion diagnostic | Non-empty, at most 4 KiB | Keep the cause and next action, shorten the diagnostic, and retry. |
| Attempt feedback | 8,192 bytes | Keep a concrete note about the problem. |
KiB and MiB are binary units; the byte limits are not character counts. These are Workflow limits, separate from Database SQL or Session follow-up scheduling limits. A successful schema check cannot establish that a Runtime can execute or that a generated deliverable is correct. Use the Run recovery guide for state-based retry, cancellation, and completion acceptance, and the Trigger guide for scheduled dispatch failures.