Workflows and the editor
A workflow is one state machine the archmax
harness executes, authored as workflows/<slug>/workflow.yaml in an environment. The editor
writes that file for you, and every change lands in the environment’s draft until you publish
it (see Agents and environments). This page covers what the
file holds and how the editor maps onto it. For the full semantics of the machine, read the
harness’s workflow machine guide and its
machine spec reference.
Where a workflow lives
Section titled “Where a workflow lives”Each workflow is a directory under workflows/:
workflow.yamlis the machine spec, a plain YAML mapping and the only source of the machine;WORKFLOW.mdbeside it is optional prose with no frontmatter, which the agent reads after the rootinstructions(HTML comments stripped);hooks/holds the workflow’s lifecycle hook scripts;tests/holds its cases (see Evaluations).
The directory name is the workflow’s identifier: lowercase letters and digits in segments
joined by hyphens, such as order-intake. It is proposed from the title when you create the
workflow and cannot change afterwards, because chat conversations, evaluations and trigger
deployments all address the workflow by it. The title is the label, and renaming means changing
the title.
The schema is the harness’s own, and it is strict: a key it does not declare, misspelled or at
the wrong level, is refused with an error naming it, and nothing strips or rewrites it. The
platform adds only what the runtime never reads: canvas positions, colours and icons in
metadata slots, and its own keys inside trigger declarations (see Triggers).
An example
Section titled “An example”title: Refund reviewinstructions: |- Answer only from what the customer and your tools have told you. Never invent an order, a status or an amount.runtime: engine: archmax-harness version: "2"tools: forbid_always: - archmax_resetskills: allow_always: []states: intake: title: Assess the request triggers: manual: requires: - order_id instructions: >- Decide whether a refund applies to the order named by order_id, write the decision to scratchpad/refund.json, and then advance to review. after: rubric: instructions: >- Return ok when the last reply names the order id and the decision, correct when it leaves either out, and veto when it promises a refund the decision does not grant. Always give a short reason. max_iterations: 2 transitions: - to: review description: The decision is written to scratchpad/refund.json. review: title: Review the decision type: human approvers: - finance@example.com evidence: - scratchpad/refund.json instructions: A person checks the recorded decision before the customer is told. transitions: - to: close type: approve description: The decision is correct; tell the customer. - to: intake type: refine description: The decision needs another look. close: title: Tell the customer instructions: >- Confirm the reviewed decision to the customer with the order id and the reason. This state is terminal.The root instructions are standing direction for the whole session. intake is the start
state: its manual trigger lets it be started by hand or called by another workflow, and a start
must supply order_id. Its after rubric grades the agent’s work before the transition to
review commits. review is a human state: the
session parks there until a person picks one of its two transitions. close has no transitions,
so it is terminal. No state may call archmax_reset, and the explicit empty skills list says the
workflow grants no skill workflow-wide.
States and transitions
Section titled “States and transitions”Each key under states is that state’s slug, its only identity: transitions, on_error routes,
trigger bindings, session history and cases all refer to it. A state’s title is presentational
and may repeat. instructions are what the agent follows while the state is active.
A state’s type is agent (the default) or human. Waiting and delegating are not kinds of
state: an agent state parks itself by calling archmax_wait, and runs another workflow by calling
that workflow’s archmax_workflow_<slug> tool, which it must be allowed (see
Sessions and decisions). The workflow it runs works in a folder of its own:
hand it a file through a type: file entry of its manual trigger, and take one back through a
type: file entry of its returns.
A transition is { to, description, type? }. The description is required and is all the agent
is told about the transition, so write when to take it, not where it leads. On a human state’s
transitions, type (approve, reject, refine, none) gives the decision dialog its accent.
A state with no transitions is terminal. Keys the editor does not author, such as a state’s
budget, on_error and requires, are kept exactly as written.
Hooks and rubrics
Section titled “Hooks and rubrics”A state may declare before and after hooks, each
a single hook or an ordered list that stops at the first verdict other than ok. A before hook
decides entry and returns ok or veto. An after hook decides the transition out of the
state, or the completion of a terminal one, and may also return correct, which sends the agent
back with the reason for another attempt.
- A script hook names a file in the workflow’s own
hooks/directory, workflow-relative:before: { script: hooks/check-requester.js }. A path into a skill bundle, an absolute path or one with..is refused, and a missing file is reported when you save. A script hook reads only the mounts its own workflow grants, inmounts.allow_alwaysor in any state’smounts.allow, and writes one only where a grant asks forread_write. The workflow’smounts.forbid_alwaysandskills.forbid_alwaysbind it too; a state’s ownallow,forbidandaccess: readdo not. - A rubric hook carries its grading criteria inline as
instructions, with an optionalmodelto grade on and, on anafterhook only,max_iterations: how manycorrectverdicts may send the agent back before the next one blocks. A rubric has no name and is not shared; a second state that needs the same standard states it again.
The agent can read neither: workflows/ is not part of any agent’s workspace. See the
harness’s grading rubrics guide.
Tool and skill governance
Section titled “Tool and skill governance”What a state’s agent may use is governed by allow and forbid lists at two levels:
| Level | Tools | Skills | Mounts |
|---|---|---|---|
| the workflow, every state | tools.allow_always, tools.forbid_always |
skills.allow_always, skills.forbid_always |
mounts.allow_always, mounts.forbid_always |
| one state | tools.allow, tools.forbid |
skills.allow, skills.forbid |
mounts.allow, mounts.forbid |
A state gets what the workflow grants everywhere plus its own grants, minus every forbid that applies. A forbid beats a grant, and no narrower level widens a denial.
-
A tool entry is a tool id, or a mapping
{ tool, args?, paths?, connection?, source? }. A piece action’s id is<collection>__<action>withsource: ap, an MCP tool’s carriessource: mcp, and a platform tool needs no source.connectionbinds the entry to one connection;argsholds argument guards, glob patterns a parameter’s value must match. In the editor, a guard on a parameter whose options come from the connection is a checklist of them. A value the list does not hold is typed into its search and added with Use this value. Focusing a free-text guard offers suggestions before the values the parameter recently received:- the patterns the tool itself recommends;
- any variable the recent calls’ values were. If the last five calls passed five different
ids, all of them
triggers.-1.session, the editor offers${{triggers.-1.session}}instead of the ids.
A tool may also show a parameter’s guard row from the start, with its recommendation as the placeholder. The built-in file and runtime tools are on in every state, so they are only ever forbidden. On the forbid side alone,
tool: "*"withpathstakes a set of paths away from every tool. -
The platform’s own tools need no connection and are granted like any other: Files (
files__download_file,files__create_presigned_url,files__unpack_file,files__pack_files), REST (rest__request) and Sessions. The Sessions tools are:sessions__set_attributes, which records session attributes on the session or on the session a completion trigger opened it about, named by id (${{session}}or${{triggers.-1.session}});sessions__read_subject, which reads that session’s transcript.
-
A skill is granted by its slug. Granting it makes its whole bundle readable and its scripts runnable in that state with no path entries; a skill a state is not granted is never even named to its agent. See Skills and registries.
-
A mount is a folder of the environment’s Storage or a remote mount, read-only unless the entry asks for
read_write. See Files and mounts.
Taking a workflow out of service
Section titled “Taking a workflow out of service”disabled: true at the root means the workflow starts no new turns: triggers start nothing and
it cannot be started by hand. Turns already underway finish, and parked sessions can still be
decided, replied to and delivered into. Its trigger deployments stay active, so re-enabling it
needs no reconfiguration. The editor’s Disable workflow checkbox writes the key and removes it
again.
The editor
Section titled “The editor”Opening a workflow from the Workflows page shows its workspace: a header with the workflow’s name and the Editor and Evaluations views. Each view has an editor mode and a session mode over the same graph; the mode bubble at the top of the canvas switches between them (Show sessions, Back to editor) and carries the detail panel’s toggle, which in the editor’s own mode is Workflow settings. Every location, down to the selected session or case, is in the URL. The session mode is described in Sessions and decisions.
The canvas
Section titled “The canvas”States are cards and transitions are arrows. Add state at the bottom of the canvas adds an agent state; drawing from one card’s handle to another adds a transition, and releasing on empty canvas creates a new state already wired to it. Cards snap to a 16 px grid.
A card shows the state’s title (or its slug), a human badge on a human state, and up to three
count groups: the triggers that enter it, its tools, and its sub-workflows. Hovering a group lists
its members; clicking it opens the inspector at the matching section. A group whose member cannot
be resolved, such as a tool whose collection has no connection, leads with a warning glyph. Lock
marks on a card’s left and right sides stand for its before and after hooks. A start state
carries a ▶ to its left, which starts a session (see Triggers).
The inspector
Section titled “The inspector”Selecting a state opens the inspector beside the canvas: Title and Identifier first, then Kind (Agent or Human), Instructions, and sections for the Trigger, the before and after hooks, Tools, Sub-workflows, Skills, File mounts (on an agent state) and Appearance. Changing an identifier rewrites every reference to it in the workflow; a new state’s generated identifier follows its title until you set one yourself. A human state also edits its approvers, the people the decision dialog names. Selecting a transition edits its description and appearance.
Every list adds through a plus in its heading. Tools and triggers share one picker: collections on the left (the platform first, then connected ones, then the rest), their items on the right, any number ticked and confirmed at once. Tools and skills each have a grant control and a forbid control side by side, and a grant that a forbid cancels is shown as denied, naming the list that denies it.
Workflow settings
Section titled “Workflow settings”Workflow settings opens the workflow’s own surface in the inspector: its title, its
identifier (read-only), its standing instructions, Workflow tools and Workflow skills (the
allow_always and forbid_always lists), File mounts, Disable workflow and the workflow’s
spend caps in the open environment (see Spend and spend caps).
Saving and validation
Section titled “Saving and validation”The editor saves by itself: shortly after you stop editing, or after a bounded wait while you keep going, and at once with Cmd/Ctrl+S. The header shows Saved, Unsaved changes, Saving…, or Couldn’t save with Retry. Starting a session from the ▶ saves any pending edit first.
Validation reports with the save rather than instead of it: a transition to a missing state, a missing hook script or an unknown skill is written to the draft and named in the validation banner, and warnings appear beside the field they concern. The one thing refused outright is a document that does not parse as a machine spec. A missing connection is only ever a warning, so a workflow can be designed first and connected later.
Creating, importing and exporting
Section titled “Creating, importing and exporting”New workflow on the Workflows page asks for a title, an identifier and optional standing
instructions. A workflow can also start from a template: the platform’s built-in ones, and any the
environment holds under .archmax-templates/<id>/. The import control there creates a workflow
from a .yaml or .yml file, and the editor’s download control saves what is on the canvas as a
workflow.yaml document, unsaved edits included. A workflow is deleted from its row on the
Workflows page, which removes its directory from the draft as a pending change.