Action Types
The eight Process Flow action types — what each one is for, how to author it, what the assignee sees, and the schema fields that drive it
An Action Template is the thing a Task asks someone (or the system) to do. A Task can carry one or many actions; they render side-by-side in the task detail panel and complete independently. Picking the right actionType is the most consequential authoring decision in a Process Template — it determines what the assignee sees, what data the platform records, and which downstream gates and integrations fire. When a Task carries exactly one action, the kanban board shows that action's type chip (icon + color) directly on the task card — single-action tasks read as "the task is the action" at a glance.
This page expands on the summary table on the Process Flows overview — one section per type, with a copy-pasteable example pulled from a real pack in the SDK examples, and a one-line note on what the assignee actually sees in agentic.
All eight action types are defined as a Zod enum in @scrydon/sdk-authoring/process-templates. The schema is the single source of truth — the authoring helpers (defineAction) and the runtime both consume it. Unknown values are rejected at pack validate time, before a bundle is built.
Anatomy of an action
Every action shares the same envelope, regardless of type:
import { defineAction } from '@scrydon/sdk-authoring/process-templates'
defineAction({
name: 'Approve rollout plan', // required, 1–200 chars
description: 'Sign off on the customer rollout schedule.',
actionType: 'approval', // required, see below
isRequired: true, // required — drives gate completion
executionMode: 'manual', // optional — see below
dueOffsetDays: 5, // optional — relative due date
metadata: { persona: 'champion' }, // optional — per-type config bag
// workflowId / workflowSlug only used by actionType: 'workflow' — mutually exclusive
})The fields that vary per type all live on metadata. Each section below calls out the metadata keys that the runtime reads for that specific type.
executionMode
A single optional field controls when an action runs:
| Mode | Meaning |
|---|---|
manual (default) | The assignee clicks "Mark complete" / "Approve" / "Upload". Used for every human-driven action. |
automatic | The runtime fires it as soon as upstream dependencies are satisfied. With no declared dependencies that moment is stage entry — the action runs as soon as its task becomes active in the stage. Used almost exclusively with actionType: "workflow" for AI / agent steps. |
on_entry | Fires the instant the stage is entered, before any task UI is shown. Used for staging-area workflow steps that prep data for the human steps that follow. |
Pick manual whenever a human is the principal. Pick automatic when the platform should drive the step the moment it can. Pick on_entry only when the step must run before the stage is interactable.
Automatic execution applies to workflow actions only. Other action types
(distribution, checklist, voice triggers, …) keep their own dispatch paths
regardless of executionMode. Stage entry counts every way a task reaches a
stage: instance creation, an automatic or approved transition, a manual move,
and timed unlocks.
Only document and approval actions show the AI Recommendations panel —
the two types where the assignee makes a judgment call the knowledge base
can inform. Other action types do not render a Recommendations section.
checklist
The lightest-weight action. The assignee sees a single button labeled "Mark complete" and clicks it when done. No artifact, no metadata captured beyond the completion event itself.
Use for: confirmations, attestations, "I did X" acknowledgements where the audit trail just needs the actor and the timestamp.
Schema fields used: name, description, isRequired, executionMode, metadata.persona.
Example (from the NATO multi-source detection pack — an operator confirms a sensor flag):
defineAction({
name: 'Confirm UAV detection',
description: 'Sensor operator confirms UAV radar reading and flags the track for fusion.',
actionType: 'checklist',
isRequired: true,
executionMode: 'manual',
metadata: { persona: 'operator' },
})What the assignee sees: a card titled "Confirm UAV detection" with a single primary button. Completion writes an action_completed activity-log entry tagged with the actor's id.
document
A long-form text artifact the assignee must produce. The platform opens a markdown editor inside the task; the resulting page is stored in the instance's workspace knowledgebase and indexed for retrieval by downstream AI steps.
Use for: plans, summaries, write-ups, meeting agendas, minutes — anything where the content is the deliverable, not a file.
Schema fields used: name, description, isRequired, executionMode, metadata.persona, metadata.promoteToCorpus (optional — one of summary / minutes / decisions / action-items; when the stage completes, the document is additionally published to the instance KB's instances/<instance>/canonical/ folder under that slug, where downstream KB-promotion steps look for it).
Example (from the AI Boardroom template — the secretary drafts the agenda):
defineAction({
name: 'Create meeting agenda',
actionType: 'document',
isRequired: true,
executionMode: 'manual',
metadata: { persona: 'secretary' },
})What the assignee sees: a card titled "Create meeting agenda" with an "Open editor" button. Completion is implicit — the action is considered done once the page is saved with non-empty content.
Where the document lands: while being edited, the content lives on the action itself. When the action is marked completed, the platform converts it to Markdown and writes it as a real page in the process flow's instance knowledge base, under instances/<instance>/documents/<stage>/ with the action's name as the page title. Completing the action again after edits updates the same page in place. From there it is queryable via the instance's KB and can ground later actionType: "workflow" steps via metadata.retrieval. Process flows created before instance knowledge bases existed get one provisioned automatically the first time a document, transcript, or canonical page is written.
Document actions show an AI Recommendations panel: the platform reads the instance and template knowledge bases, meeting extractions, prior org-KB learnings, and the linked entity, and generates readable suggestions for what the document should cover. A Reasoning Details expander shows how each recommendation was grounded; Refresh regenerates against the latest knowledge. Recommendations require an LLM integration to be configured for the organization.
The gate: "validate-and-rerun" flag on a document action turns it into a soft gate for an AI step that follows: after the human edits the document, the downstream workflow re-runs against the edited content. Useful for "AI drafts → human revises → AI re-runs" loops.
approval
A sign-off gate. The assigned persona sees an Approve / Reject pair of buttons. Approving marks the action complete and unblocks downstream tasks; rejecting flags the task and surfaces a reason field.
Use for: stage-gate sign-offs, go/no-go decisions, governance reviews where someone with named authority must vouch for the result.
Schema fields used: name, description, isRequired, executionMode, metadata.persona, metadata.promoteToOrgKb (boolean — completes the workspace-KB → org-KB learnings condense; only valid on approval).
Example (from the AI Boardroom template — executive sign-off on the AI-drafted summary):
defineAction({
name: 'Approve meeting summary',
actionType: 'approval',
isRequired: true,
executionMode: 'manual',
metadata: { persona: 'executive' },
})What the assignee sees: a card with Approve and Reject buttons. Approval writes an approval_granted activity entry; rejection writes approval_rejected with an optional reason and leaves the task open.
Approval actions show an AI Recommendations panel containing a single consolidated decision brief — key risks, the available evidence, and what prior similar flows show — grounded in the same knowledge sources as document recommendations. The panel never recommends approving or rejecting; the decision stays with the assignee.
Setting metadata.promoteToOrgKb: true on a final approval action triggers the learnings condense — the instance's workspace KB is rolled up into typed Learning records and enqueued into the org-KB domain declared by template.knowledge.promotionTarget. See Triggering the learnings condense on approval on the parent page.
workflow
Executes a Scrydon workflow — either an agentic AI agent, an integration block sequence, or a human-in-the-loop gate. The workflow runs in the platform's workflow engine; the action completes when the workflow returns.
Use for: AI agent steps, automated integrations, HITL gates that need richer than a yes/no — anything where executable logic must run as part of the flow.
Schema fields used: name, description, isRequired, executionMode (often automatic), workflowId or workflowSlug (mutually exclusive), metadata.aiAgent, metadata.retrieval, metadata.outputSurface.
There are two ways to reference the workflow, and choosing between them is the key authoring decision for this type:
By workflowId — refer to an existing workflow
Use this when the workflow already exists in the tenant. Two common cases: a @system/* agent shipped by the platform, or a workflow the workspace built independently.
Example (from the NATO sense stage — calling the system-provided multi-source detector):
defineAction({
name: 'Run UAV radar detection',
actionType: 'workflow',
isRequired: true,
executionMode: 'automatic',
workflowId: '@system/agent-multi-source-detector',
metadata: { persona: 'ai-platform', aiAgent: 'multi-source-detector' },
})The runtime treats @system/* ids specially — they always resolve, regardless of which workspace the instance runs in.
By workflowSlug — ship the workflow inside the same pack
Use this when the workflow is bespoke to the process and you want them to ship as one atomic unit. Author the workflow alongside the process template in the same .scrydon-pack.tar.gz; the importer materializes the workflow first, then rebinds every workflowSlug to the materialized id before the process template lands.
Example (from the SAP Activate Brabant pack — a HITL gate shipped with the template):
defineAction({
name: 'Realize → Deploy Gate (HITL)',
actionType: 'workflow',
isRequired: true,
executionMode: 'manual',
workflowSlug: 'hitl-realize-gate', // resolved at install time
})workflowId and workflowSlug are mutually exclusive — the Zod refinement rejects an action that sets both. See Workflows for the slug-rebind contract.
What the assignee sees: if executionMode is automatic or on_entry, usually nothing — the step runs in the background and shows its result inline once it lands. If manual, a "Run" button appears; clicking it starts the workflow and streams progress into the card.
For @system/* AI agent steps, metadata.retrieval lets you ground the agent in (a) earlier-task documents and (b) a governed org-KB domain; metadata.outputSurface declares where the agent's result lands. Full coverage on the parent page: Grounding an AI step in governed knowledge.
Where AI output lands
When a workflow action runs a @system/ agent and declares an outputSurface,
its result is saved in three places:
- The action itself — structured verdict (
verdict,confidence,rationale, cited learning titles) plus a rendered Markdown copy. - The instance knowledge base — a page under
instances/<instance>/assessments/<stage>/, written automatically on completion. This page is the source of truth: the View output button on the action opens it inline. The page's clearance level is capped at the high-water-mark of the sources that informed it, so readers below that clearance see a denial instead of the content. - A sibling approval action (only when the flow declares the
approvaloutput surface) — an advisory banner on the human decision gate.
Re-running the action updates the same page in place. The Run Details panel on the action shows the execution envelope (workflow id, execution id, status, timestamps) and the raw stored payloads for debugging.
entity_link
Reserved / not yet covered by an in-tree example pack. The schema accepts entity_link and the runtime renders a placeholder card, but no example template in @scrydon/sdk-authoring/src/process-templates/examples/ currently uses it. Prefer document, file_upload, or a workflow action that writes a typed instance via the ontology API until a worked example ships. File an issue if you have a use case that requires this type today.
The intent is to attach a task to a typed Object instance from the ontology — so the action becomes "fill in this Object" rather than "produce a free-form artifact." The Object Type would be declared via task.ontologyContract.writes (or the action's ontologyContract), and the runtime would scaffold an editor for that type's properties.
Schema fields used: name, description, isRequired, executionMode, ontologyContract (declared at the action or task level).
file_upload
The assignee uploads one or more files. Bytes flow into the instance's workspace knowledgebase, get hashed and stored via @scrydon/storage, and are immediately indexed — making them available to downstream actionType: "workflow" steps via metadata.retrieval.inputs[].fromTask.
Use for: importing source documents (RFPs, contracts, board packs, audit evidence) that downstream AI steps need to reason over.
Schema fields used: name, description, isRequired, executionMode, metadata.persona, and the optional drop-zone constraints metadata.acceptedExtensions, metadata.acceptedMimeTypes, metadata.maxSizeMb.
Constraining what can be uploaded. A file_upload step always accepts multiple files; you cannot turn multiplicity off. What you can declare is which files and how large:
metadata field | Type | Effect |
|---|---|---|
acceptedExtensions | string[] | Allowed file extensions (leading dot, case-insensitive — e.g. [".pdf", ".docx"]). |
acceptedMimeTypes | string[] | Allowed MIME types (e.g. ["application/pdf"]). Broadens acceptance — a file passes if its extension or its MIME type matches. |
maxSizeMb | number | Per-file size cap, in megabytes. |
All three are optional. Declare none and the step falls back to the platform defaults: extensions .pdf .docx .xlsx .csv .pptx .txt .md, max size 50 MB. Declaring acceptedExtensions or acceptedMimeTypes replaces the default extension set, so you can gate purely by MIME if you prefer.
These limits are enforced both in the picker (the drop-zone's accept filter and size check) and server-side at upload — a request that bypasses the UI is still rejected with a 400. Existing in-flight instances keep the defaults; the constraints take effect for flows instantiated after the template declares them.
Accepted ≠ knowledge-base indexed. What you allow here controls which files attach to the step. Whether an attached file also becomes a searchable knowledge-base page is decided separately by the ingest pipeline, which can currently text-extract: PDF, DOCX, TXT, MD, CSV, JSON, and audio (transcribed). Other types — including .xlsx and .pptx (which the defaults accept), images, and archives — upload and stay downloadable as attachments, but are not indexed into the instance knowledge base, so downstream workflow steps using metadata.retrieval cannot read their contents. Restrict acceptedExtensions to the indexable set if a step exists purely to feed an AI step.
Example (from the AI Boardroom template — secretary uploads the board pack):
defineAction({
name: 'Upload board documents',
actionType: 'file_upload',
isRequired: true,
executionMode: 'manual',
metadata: {
persona: 'secretary',
// Optional — omit for the platform defaults (.pdf/.docx/.xlsx/.csv/.pptx/.txt/.md, 50 MB).
acceptedExtensions: ['.pdf', '.docx', '.pptx'],
acceptedMimeTypes: ['application/pdf'],
maxSizeMb: 25,
},
})What the assignee sees: a drop-zone card that accepts multiple files — select several at once or keep adding files over time (each upload appends to the step's attachment list; existing files are never replaced). The picker only offers the accepted types and rejects files over the size cap. Completion is explicit: once at least one file is attached, the assignee marks the step complete (the Mark step complete button on the card, or the action's checkbox in the task checklist). Each file becomes a KB page that downstream tasks can reference by this task's slug.
A downstream workflow action that wants to reason over the uploaded files declares them via metadata.retrieval.inputs: [{ fromTask: "upload-board-documents", mode: "full" }]. See the parent page's retrieval section.
distribution
Sends a message to the holders of one or more personas and tracks acknowledgment. Used to broadcast a result, request acknowledgment before a tabletop, or close a loop with stakeholders who aren't actively running the flow.
Delivery today runs over email through the platform mailer — no integration setup is required. channel: "slack" and channel: "teams" are accepted in the manifest as declared intent, but delivery for those channels will be enabled in a future release; until then the panel shows the declared channel and disables sending for non-email channels.
Use for: notifications, briefings, summaries pushed to external channels.
Schema fields used: name, description, isRequired, executionMode, plus a richer metadata block:
metadata key | Meaning |
|---|---|
persona | Who is sending it (audit trail). |
channel | "email" (delivered today) · "slack" · "teams" (declared intent; delivery not yet active). |
recipientPersonas | Array of persona slugs whose holders receive the message. |
completion | "fire-and-forget" (done as soon as sent) · "all-acknowledged" (every recipient must ack) · "quorum" (N acks needed). |
quorumCount | Required when completion: "quorum". |
Example (from the ISO Quarterly Review pack — distributing the audit-ready summary on Slack with a recipient list):
defineAction({
name: 'Distribute report summary',
actionType: 'distribution',
isRequired: true,
metadata: {
persona: 'compliance-lead',
channel: 'slack', // Declared intent — Slack delivery not yet active; email delivers today.
recipientPersonas: ['compliance-lead', 'ciso', 'dpo', 'eng-owner'],
completion: 'all-acknowledged',
},
})What the assignee sees: a focused panel showing the declared channel, the completion mode, and the resolved recipient list (each recipient persona's assigned users by name). For email, a compose form (subject prefilled from the action name, editable message) sends each recipient a personal tracked link; once sent, the panel shows per-recipient acknowledgment status and an "N of M acknowledged" progress line for all-acknowledged / quorum modes. Recipients acknowledge by opening the tracked link, which also redirects them to the linked artifact.
voice_trigger
Captures audio against a path defined on the template. The recording is automatically transcribed (STT runs through the STT capability). When the action completes, the transcript is written as a page in the process flow's instance KB under instances/<instance>/transcripts/<stage>/, and the raw audio is queued for ingestion under instances/<instance>/audio/<stage>/ — both ready to ground downstream steps.
Use for: meeting recordings, dictation, voice-driven enrichment of a flow that's mostly silent the rest of the time.
Schema fields used: name, description, isRequired, executionMode, metadata.persona, metadata.triggerPath (matches a path on a top-level template.voiceTriggers[] entry).
Example (from the AI Boardroom template — recording the meeting itself, paired with a top-level voice-trigger that wires up STT and downstream enrichment):
// On the task action:
defineAction({
name: 'Record meeting',
actionType: 'voice_trigger',
isRequired: true,
executionMode: 'manual',
metadata: { persona: 'secretary', triggerPath: 'board-meeting' },
})
// On the top-level template:
defineVoiceTrigger({
path: 'board-meeting',
sttProvider: 'openai',
language: 'en',
enrichments: [
{ workflowId: '@system/agent-meeting-summarizer' },
],
})What the assignee sees: a card with a record button. Recording in the browser; on stop, the audio uploads and the STT result streams in. Enrichment workflows on the voice-trigger fire automatically once the transcript lands.
The pairing is what makes voice triggers powerful: the action declares "record here," and the template-level voice trigger declares "for any recording at path X, run these enrichments." One transcript, many downstream agents.
You don't deploy anything for this pairing yourself. The platform materializes the voice trigger automatically the first time an assignee starts a recording: a dedicated trigger workflow (named Voice Trigger — <path>) is provisioned once per workspace environment, carrying the STT provider, model, and language from the voiceTriggers[] entry. Paths are matched ignoring a leading slash, so /board-meeting and board-meeting pair up fine.
Choosing the right type
A short decision flow for when authors are unsure:
| If the step is… | Use |
|---|---|
| A confirmation, attestation, or "I did it" tick | checklist |
| Free-form text the assignee writes inside the flow | document |
| A formal sign-off that gates the next stage | approval |
| Executable logic — an AI agent, integration sequence, or HITL gate | workflow |
| Bytes that come from outside the flow (PDFs, decks, exports) | file_upload |
| A message broadcast to an external channel | distribution |
| Audio capture | voice_trigger |
If the step is "fill in a typed Object," there isn't a first-class action type yet — model it as a workflow action that calls an agent or integration block to create the instance via the ontology API.
Common validation pitfalls
The pack validate command runs the Zod schema and rejects manifests that violate these rules. The ones that bite most often:
| Error | Cause | Fix |
|---|---|---|
workflowId and workflowSlug are mutually exclusive on an action template | Both workflowId and workflowSlug set on the same action. | Pick one. Use workflowId for @system/* and tenant-owned workflows; use workflowSlug for workflows shipped in the same pack. |
Invalid enum value. Expected … received "form" (or similar) | A typo'd or legacy actionType value. | The runtime accepts exactly the eight types on this page. There is no form, notification, or custom type at the SDK layer. |
Required on quorumCount | metadata.completion: "quorum" without quorumCount. | Add quorumCount: <n>. |
Slug must be lowercase alphanumeric with hyphens on workflowSlug | Underscores or capitals in the slug. | Use kebab-case. |
Action triggerPath doesn't resolve at runtime | metadata.triggerPath on a voice_trigger action doesn't match any entry in template.voiceTriggers[].path. | Schema doesn't catch this; "Prepare Recording" fails with "Voice trigger not found" (404). The match ignores a leading slash but is otherwise exact — fix the path in either place so they pair up, then re-publish the pack. |
Where to next
Process Flows overview
The parent page — anatomy of a template, complete example, build/upload steps, security caps.
Workflows
Author the workflows that actionType: "workflow" references. Covers the workflowSlug rebind contract.
Examples
Download the full pack archives the examples on this page are pulled from.
Ontologies
The typed Object Types referenced by entity_link and by ontologyContract on tasks and actions.