Editorial Workflows

Activities and actions

Activities represent work in a stage. Actions let callers and triggers update workflow state, queue effects, and resolve that work.

Prerelease

An activity is a unit of work scoped to one stage visit. Its actions are the named responses available while that work is active. A caller invokes an action; the engine fires an action with a condition as an automated trigger. See Stages and transitions for how activities fit into a stage visit.

Firing an action commits its operations atomically. It may also set an activity outcome in that commit. Transitions evaluate the resulting state; actions do not move the instance directly. Effects run after the commit for external work.

Define an activity

Declare the work, when it applies, when it is ready, and the actions available while it is active:

defineActivity({
  name: 'review',
  title: 'Review article',
  filter: '$fields.needsReview',
  requirements: {assigned: 'defined($fields.reviewer)'},
  actions: [
    defineAction({name: 'approve', status: 'done'}),
  ],
})

Existence and readiness

An activity filter decides whether the activity exists for a stage visit. Ordered GROQ requirements keep an existing activity visible while blocking its caller-fired actions until every requirement passes.

defineActivity({
  name: 'review',
  requirements: [
    {
      type: 'groq',
      name: 'assigned-reviewer',
      title: 'Assigned reviewer required',
      query: '$assigned',
    },
  ],
  actions: [defineAction({name: 'approve', status: 'done'})],
})

Both properties use conditions, but they answer different questions.

  • filter

    Condition

    Controls whether the activity belongs to a stage visit. An excluded activity is recorded as skipped and does not block completion.

  • requirements

    GroqRequirement[]

    Ordered named readiness gates. Unmet requirements keep the activity visible but block caller-fired actions.

An included activity remains active until an action resolves it as done, skipped, or failed. Resolving an activity does not move the instance; a transition controls movement.

Define actions

Actions are commands attached to an activity. They can change workflow state, queue external work, start child workflows, and optionally resolve the activity.

Omit when for a caller-fired action. Add when for an automated trigger.

The first example records approval, resolves the review, and queues a notification. The second adds a condition so the engine can trigger it automatically:

defineAction({
  name: 'approve',
  ops: [
    {type: 'field.set', target: {field: 'approval'}, value: {type: 'actor'}},
  ],
  effects: [
    {
      name: 'notify-reviewer',
      bindings: {to: '$fields.reviewer'},
      input: {body: 'Your article was approved'},
    },
  ],
  status: 'done',
})

defineAction({
  name: 'escalate',
  when: '$fields.dueDate < $now',
  effects: [{name: 'notify-editor', bindings: {to: '$fields.editor'}}],
})

Caller actions and automation

  • Without when

    Caller-fired action

    A caller invokes it through fireAction. A UI may present it as a control.

  • With when

    Automated trigger

    The engine fires it automatically when its condition becomes true.

Triggers run in declaration order. Re-entering the stage starts a new visit and allows them to fire again.

Resolve an activity

Use status for the outcome of the work, not the business decision:

  • done — the work completed, including approve, decline, send back, or hold.
  • skipped — the work did not apply.
  • failed — the work could not complete.

For a business decision, resolve the activity as done and write the decision to a field that a transition condition reads.

What actions can do

Actions can combine immediate operations, queued effects, child workflows, and an optional activity status.

  • ops

    Operation[]

    Mutate instance state in the same commit as the action.

  • effects

    Effect[]

    Queue external work to run after the action commits.

  • spawn

    Subworkflows

    Start child workflow instances.

  • status

    done | skipped | failed

    Resolve the firing activity in the same commit.

Preview an action’s flow consequence

Action evaluation can preview what firing a caller action would do to the flow in the current state. Use it to place or label controls without duplicating transition logic.

const evaluation = await engine.evaluate({instanceId})
const approve = evaluation.currentStage.activities
  .flatMap(({actions}) => actions)
  .find(({action}) => action.name === 'approve')

if (approve?.firing?.exitsStage) {
  console.log(`Approve exits through ${approve.firing.transition}`)
}
  • exitsStage

    boolean

    True when the replayed action and cascade leave the current stage.

  • transition

    string | undefined

    The selected transition name when exitsStage is true.

The preview is advisory and describes the current projection. It is omitted when a faithful replay needs unavailable inputs, including caller parameters or dataset-driven spawn results, and for automated triggers.

Condition variables

Activity and action conditions use the GROQ variables defined by Conditions. Caller-fired sites can also bind the current actor and permissions; cascade-fired sites cannot.

  • All sites

    Instance variables

    Workflow state such as $fields, $stage, $activities, and $context.

  • Caller-bound sites

    $actor, $assigned, $can

    Available to activity requirements and caller-fired action filters.

  • Cascade sites

    No caller variables

    Activity filters and triggered action conditions run without a caller.

Reference

Activity declaration

This is the object passed to defineActivity(...) in a stage’s activities array.

  • name

    string

    Required stable activity name.

  • title

    string

    Optional display label.

  • Optional explanation.

  • groups

    Group[]

    Groups declared for this activity’s fields and actions.

  • group

    string | string[]

    Groups this activity joins.

  • target

    ManualTarget

    Optional deep link for work performed outside Editorial Workflows.

  • filter

    Condition

    Existence condition evaluated at stage entry.

  • requirements

    GroqRequirement[]

    Ordered named readiness gates; all must pass before caller-fired actions are executable.

  • actions

    Action[]

    Actions that can resolve work or change instance state.

  • fields

    Field[]

    Activity-scoped fields resolved at stage entry.

Action declaration

This is the object passed to defineAction(...) in an activity’s actions array.

  • name

    string

    Required stable action name.

  • title

    string

    Optional display label.

  • Optional explanation.

  • group

    string | string[]

    Groups this action joins.

  • when

    Condition

    When present, makes this a cascade-fired trigger; otherwise callers use fireAction.

  • filter

    Condition

    Existence condition for the action.

  • roles

    string[]

    Advisory role requirement; trigger roles also pin cascade execution.

  • params

    ActionParam[]

    Caller-supplied values validated before the action commits.

  • ops

    Operation[]

    Synchronous instance mutations committed with the firing.

  • effects

    Effect[]

    External work queued by the firing.

  • spawn

    Subworkflows

    Child workflows spawned by the firing.

  • status

    done | skipped | failed

    Authoring shorthand for a final status.set on the firing activity.

  • semantics

    Array<'decision.accept' | 'decision.decline'>

    Optional advisory decision meaning for ordinary actions; accepts at most one value.

Visiting agent?

Was this page helpful?