Scrydon
Authoring: Process Flows

Process Flows

Author Process Flows via the SDK — stages, tasks, personas, action templates, and voice triggers — and ship them as packs

This artifact ships inside a Pack. For the shared lifecycle — install, pack build, upload — see Packs & Authoring SDK.

A Process Flow is a structured, repeatable workflow with stages, tasks, and personas — kickoffs, audits, onboarding, due-diligence reviews. You author it once as a Process Flow using this SDK and ship it inside a .scrydon-pack.tar.gz; the platform instantiates it per run as a Process Flow.

SDK and pack are the only authoring path. Process Flows are defined in code using this SDK and installed via the platform's Settings → Packs upload. There is no in-app editor. Once a pack is installed, workspace admins add the template to an environment from the Marketplace, making it instantiable in Process Flows.

process flow bundles are pure data. The bundle is JSON — no executable code ever ships in the archive. Custom logic is referenced by ID against system or organization-level workflows.

Scrydon Pack Bundles. Process flows ship as .scrydon-pack.tar.gz archives that bundle the flow alongside its ontology (and, in future releases, KB seeds and block packs). The pack imports atomically — ontology install, slug → tenant class ID rebind, process-flow materialise, all in one transaction. Build with bunx @scrydon/sdk-authoring pack build; inspect with bunx @scrydon/sdk-authoring pack inspect. See the spec and packages/sdk-authoring/src/packs/examples/ai-boardroom/ for a worked example.

Install

bun add -d @scrydon/sdk-authoring zod
npm install --save-dev @scrydon/sdk-authoring zod
import {
  defineProcessFlow,
  defineStage,
  defineTask,
  defineAction,
  definePersona,
  defineVoiceTrigger,
} from '@scrydon/sdk-authoring/process-flows'

Anatomy of a template

ElementPurpose
PackageIdentity of the bundle: id, name, version
TemplateThe flow itself — default view, execution config, metadata
PersonaRoles a task can be assigned to (one, many, or system)
StageAn ordered phase. Transitions are manual, automatic, or approval
Task TemplateWork items inside stages. Carry actions, dependencies, default attributes
Action TemplateThe thing a task asks the user to do — checklist, document, approval, workflow, entity_link, file_upload, distribution, voice_trigger
Voice TriggerOptional voice-driven enrichment block scoped to a path

A complete example

import {
  defineProcessFlow,
  defineStage,
  defineTask,
  defineAction,
  definePersona,
} from '@scrydon/sdk-authoring/process-flows'

export default defineProcessFlow({
  manifestVersion: 1,
  package: {
    id: 'acme.kickoff',
    name: 'Acme Customer Kickoff',
    version: '1.0.0',
  },
  template: {
    slug: 'acme-kickoff',
    name: 'Customer Kickoff',
    description: 'Standard onboarding flow for new enterprise customers',
    version: '1.0.0',
    defaultView: 'wizard',
    executionConfig: {
      stageFlow: 'sequential',
      taskFlow: 'parallel',
      allowRuntimeTaskCreation: true,
    },
    metadata: {
      icon: 'rocket',
      color: '#2563eb',
      tags: ['onboarding', 'sales'],
    },
    personas: [
      definePersona({ slug: 'csm', displayName: 'Customer Success Manager', cardinality: 'one' }),
      definePersona({ slug: 'champion', displayName: 'Customer Champion', cardinality: 'one' }),
      definePersona({ slug: 'system', displayName: 'System', cardinality: 'system' }),
    ],
    stages: [
      defineStage({
        slug: 'discovery',
        name: 'Discovery',
        transitionMode: 'manual',
        estimatedDuration: { value: 5, unit: 'days' },
      }),
      defineStage({
        slug: 'rollout',
        name: 'Rollout',
        transitionMode: 'approval',
      }),
    ],
    taskTemplates: [
      defineTask({
        slug: 'collect-stakeholders',
        stageSlug: 'discovery',
        name: 'Collect stakeholders',
        defaultAssignedRoleSlug: 'csm',
        actions: [
          defineAction({
            name: 'Stakeholder list',
            actionType: 'document',
            isRequired: true,
            metadata: { persona: 'csm' },
          }),
        ],
      }),
      defineTask({
        slug: 'kickoff-call',
        stageSlug: 'discovery',
        name: 'Kickoff call',
        dependsOnTaskSlugs: ['collect-stakeholders'],
        actions: [
          defineAction({
            name: 'Record kickoff call',
            actionType: 'voice_trigger',
            isRequired: true,
            metadata: { triggerPath: '/kickoff/' },
          }),
          defineAction({
            name: 'Capture summary to KB',
            actionType: 'workflow',
            isRequired: false,
            workflowId: 'system.summarize-meeting',
            metadata: { promoteToCorpus: 'summary' },
          }),
        ],
      }),
      defineTask({
        slug: 'rollout-plan',
        stageSlug: 'rollout',
        name: 'Approve rollout plan',
        dependsOnTaskSlugs: ['kickoff-call'],
        actions: [
          defineAction({
            name: 'Approve plan',
            actionType: 'approval',
            isRequired: true,
            metadata: { persona: 'champion' },
          }),
        ],
      }),
    ],
    voiceTriggers: [],
  },
})

Action Types

Action typeUse it for
checklistA simple to-do the user marks complete
documentA document the user must produce or attach
approvalAn approval gate — assigned to a persona, blocks downstream tasks until granted. Rejecting the gate (the Reject button) halts the flow: the gate's task stays open and no downstream stage unlocks, whether or not the approval action is marked required, until the gate is re-decided to approved or skipped as an explicit override
workflowReference an executable workflow — either by workflowId (a pre-existing system or org workflow in the tenant) or by workflowSlug (a workflow shipped in the same Pack — see Workflows). The two are mutually exclusive
entity_linkLink the task to a typed Object instance via the ontology
file_uploadA file drop — bytes get ingested into the instance KB
distributionSend to a channel (email, slack, teams); supports quorum, fire-and-forget, all-acknowledged
voice_triggerCapture audio against a path — STT runs and the transcript flows into KB

See Action Types for a per-type deep-dive with copy-pasteable examples, runtime UX notes, and the metadata fields each type reads.

Approval-gate routing

When a stage has transitionMode: "approval", the platform notifies the right people the moment a task reaches the gate. Three fields on defineStage control who is notified and how many approvals are required:

FieldTypeDefaultDescription
approverPersonastring (slug)"owner"The persona whose current members receive the approval-request notification. Falls back to the org owner role when no users hold the persona.
resolutionMode"first_claim" | "all_must_approve" | "quorum""first_claim"When multiple approvers are notified, determines the decision rule. first_claim — any one approver can decide. all_must_approve — every notified user must approve. quorum — at least quorumN approvers must approve.
quorumNnumber (integer ≥ 1)Required when resolutionMode: "quorum". The minimum number of approvals needed.

When the gate is reached, the platform sends a process.approval_requested notification to each resolved user and displays "Approval request sent · N notified · sent <date>" in the approval task sheet.

Example — legal-quorum gate:

defineStage({
  slug: 'legal-review',
  name: 'Legal review',
  transitionMode: 'approval',
  approverPersona: 'legal-reviewer',
  resolutionMode: 'quorum',
  quorumN: 2,
})

The flow halts at the gate until the quorum is satisfied. Rejecting the gate halts the flow regardless of quorum count — a single rejection is always final.

Grounding an AI step in workspace documents (metadata.retrieval)

The reverse direction: a workflow action that runs an agent — a @system/* built-in or a pack/canvas workflow (inline or sibling) — can be grounded in one or more documents uploaded earlier in the flow, so the agent reasons over real inputs instead of the task name alone. Declare it with metadata.retrieval on the action:

defineAction({
  name: "AI Qualification Assessment",
  actionType: "workflow",
  isRequired: false,
  executionMode: "automatic",          // run when the stage is entered
  workflowId: "@system/agent-project-qualifier",
  metadata: {
    aiAgent: "project-qualifier",
    // Where the agent result lands, by target ACTION TYPE (see below):
    // an assessment on this workflow step itself, and an advisory banner
    // on the flow's human approval action.
    outputSurface: [
      {
        kind: "workflow",
        contentType: "project_qualification_assessment",
        pageTitle: "AI Qualification Assessment",
      },
      {
        kind: "approval",
        targetTaskSlug: "go-no-go-decision",
        advisorySource: "ai-qualification",
      },
    ],
    retrieval: {
      // The document(s) the agent must judge. `fromTask` is the slug of an
      // earlier task: its completed document action's page, its file_upload
      // action's ingested documents, and/or its workflow (agent) action's
      // assessment page are injected in full.
      inputs: [{ fromTask: "upload-source", mode: "full" }],
      // Optional. The per-input-document character cap: in `full` mode the
      // verbatim clip ceiling, in `summary` mode the target the condense fits
      // to. Raise it when a large `mode: "full"` document is being clipped.
      // Omitted → mode-derived default (full: 24,000; summary: 4,000).
      inputDocMaxChars: 60_000,
    },
  },
})
FieldMeaning
retrieval.inputs[]{ fromTask, mode }. Loads the document(s) produced at fromTask (a task slug): the page written by the task's completed document action, the pages derived from its file_upload action's uploads, and/or the assessment page written by its agent workflow action — resolved deterministically from the task itself, with a lexical KB search as fallback for runtime-created tasks. Pointing fromTask at an earlier agent step is how one agent grounds on another agent's output (e.g. a consolidation step over several advisory steps) — the upstream agent step must declare outputSurface: "workflow" (surfaces are author-declared, never implicit), otherwise no assessment page exists for the downstream step to load. mode: "full" (default) injects the verbatim document, clipped to the cap (default 24,000 chars) when it exceeds it — a […document truncated] marker is emitted and the step's Prompt & Context panel warns you that content was dropped, so clipping is never silent; raise retrieval.inputDocMaxChars for large full-mode inputs. mode: "summary" produces a real condense — the document is summarised to fit the cap (default 4,000 chars) by the platform LLM, preserving decision-relevant detail rather than just clipping more aggressively; if no LLM is configured it degrades to a clip. The panel shows, per input, whether a document was clipped or condensed.
retrieval.inputDocMaxCharsOptional positive integer (max 200,000). Overrides the per-input-document cap for every input in this step — in full mode the verbatim clip ceiling, in summary mode the condense target. Omitted → the mode-derived default above.
outputSurfaceOptional. One selection or an array. Each selection's kind is the target action type the result lands on, plus per-surface config. kind: "workflow" writes the assessment onto the agent step itself AND as a clearance-capped page in the instance KB (contentType, pageTitle): a verdict-shaped reply ({verdict, confidence, rationale, …} JSON) renders the verdict layout; any other reply (prose, other JSON schemas) renders the agent's own text as the page body. kind: "approval" merges a one-line advisory onto the approval action of the task named by targetTaskSlug (advisorySource labels its provenance). Other action types are reserved for future surfaces. Surfaces are never implicit — an agent step without outputSurface writes no assessment page.

mode: "summary" is lossy — do not use it for compliance-critical scoring. This mode is optimised for readability and fitting the LLM's context window; it does not guarantee a loss-free representation of every fact. For compliance-critical tasks — strict RFP evaluation, legal or contractual scoring — use mode: "full" together with the pull channel (<start.processFlow.knowledgeBaseId> + the knowledge RAG tools), so that decision-relevant criteria are never silently dropped by the condense.

Today workflow (assessment on the step) and approval (advisory on a target approval action) are the implemented output surfaces. The retrieval spec itself is generic and works for any agent-bearing workflow step that needs grounding — @system/* built-ins receive the gathered context as their user message automatically, while pack/canvas workflows must additionally reference <start.processFlowContext> in a block to receive it (see Receiving process-flow context — without the reference the gathered context is dropped).

Task DAG validation

Tasks can declare:

  • dependsOnTaskSlugs — other tasks that must complete first
  • unlockAfterTaskSlug + unlockDelay — a soft gate that opens N days/weeks after a predecessor finishes

The inspect CLI runs DFS cycle detection (WHITE/GRAY/BLACK) and fails closed on any cycle. Stable error codes:

CodeMeaning
task_cycleA dependency edge participates in a cycle
unknown_dep_slugdependsOnTaskSlugs references an unknown task slug
stage_unknowntaskTemplates[].stageSlug doesn't match any stage

Build, inspect, upload

bunx @scrydon/sdk-authoring pack validate src/pack.ts
bunx @scrydon/sdk-authoring pack build src/pack.ts --outDir dist
# → dist/<package.id>-<package.version>.scrydon-pack.tar.gz
bunx @scrydon/sdk-authoring pack inspect dist/acme-kickoff-1.0.0.scrydon-pack.tar.gz

Sign in as an org admin and open Settings → Packs in the platform app. Click Upload pack and drop your .scrydon-pack.tar.gz. When the pack ships a workflow, the dialog will ask you to pick a workspace environment — the workflow definitions install into that environment. Ontology and process-flow content install at the org level regardless.

The platform upload flow is the canonical entry point for all pack content kinds since ADR 2026-05-21 Unified pack upload surface.

After the pack is installed, a workspace admin opens Marketplace in the agentic sidebar and clicks Add on the Process Flow row to make it available in that environment. Once added, any workspace member can start a new Process Flow from it. See Marketplace.

For automation, the underlying agentic route still accepts uploads. Pass workspaceEnvironmentId only if the pack ships workflow content; otherwise it's optional.

curl -X POST "$AGENTIC_URL/api/packs/import?organizationId=$ORG_ID&workspaceEnvironmentId=$ENV_ID" \
  -H "Cookie: $SESSION_COOKIE" \
  -F "file=@dist/acme-kickoff-1.0.0.scrydon-pack.tar.gz"

Bundle layout

<bundle>.scrydon-pack.tar.gz
├── pack.json                          # top-level pack manifest (PackBundleManifestSchema)
├── ontology/
│   └── manifest.json                  # OntologyManifestSchema — may be empty for flow-only packs
├── workflow-<slug>/                   # optional — zero or more workflow subdirs
│   └── manifest.json                  # WorkflowManifestSchema
└── process-flow/
    ├── manifest.json                  # ProcessFlowManifestSchema
    ├── assets/                        # optional — JSON / image assets referenced by the flow
    │   ├── icon.svg
    │   └── preview.png
    └── meta/                          # optional — non-functional metadata (e.g. sbom.cdx.json)

Each subdir round-trips as a valid standalone artifact. Allowed asset extensions: .json, .svg, .png, .jpg, .jpeg, .gif, .md. Symlinks, hardlinks, absolute paths, and path traversal (..) are rejected by the inspector.

When a pack ships workflows, the importer runs them in their own phase before process-flow install — that way every workflowSlug on an action template resolves to a materialized workflowId before the process flow lands in the database. See Workflows for the slug-rebind contract.

Security caps

The runtime inspector reads the archive in streaming mode (tar.list parser-only — never extracts to disk) and enforces hard caps:

CapLimitFailure code
Compressed archive5 MBarchive_too_large
Total uncompressed10 MBtotal_size_exceeded
Per-file size5 MBfile_too_large
File count200too_many_files
Symlink / hardlinkn/asymlink_rejected
Absolute pathn/aabsolute_path_rejected
Path traversaln/apath_traversal_rejected
Disallowed top-level dirn/adisallowed_path
Disallowed extensionn/adisallowed_extension

The /import route returns 413 for size violations and 400 for structure or graph violations.

Why no executable code

process flows are declarative. Custom logic is referenced — by workflowId (a workflow already living in the tenant) or by workflowSlug (a workflow shipped alongside the template in the same Pack) — not bundled. Even when a Pack ships workflows in workflow-<slug>/ subdirs, the on-disk representation is pure JSON; the runtime block catalog lives in the platform. This keeps the surface deterministic, reproducible, and uploadable by non-engineering authors.

Where to next

On this page

On this page