Docs

The runtime side of workflows — live FSM instances you fire transitions against.

Jobs

A job is a running instance of an FSM schema. Where the Workflows section covers authoring the graph, this section is about what happens after you press play: spawning jobs, firing transitions, reading the audit trail, and overriding when reality diverges from the workflow model.

Lifecycle

Every job begins in its schema's initial_state and ends when a transition lands it in a state that has no outgoing edges. The backend enforces no cycles / no orphans / no dangling references at save-time (see the FSM Designer for the compiler rules).

Spawning paths:

  • Manually from /admin/jobsNew job.
  • Automatically from a form submission carrying a SPAWN_JOB_FROM_FORM action. See the webhook intake recipe.
  • Via the API: POST /api/v1/tenant/jobs with { tenant_id, schema_id, context_record_id? }. Context record is optional — see below.

Firing a transition

Need to fire the same transition on many jobs at once? See Bulk operations.

From the job detail view, you see every outbound transition from the job's current_state. Click one to fire it. Three things happen atomically:

  1. The guard (if any) evaluates against the job's context via sandboxed JSONLogic. A false guard returns 409 with the context so you can see why.
  2. current_state moves to the transition's to state.
  3. A row lands in event_log recording from_state, to_state, event_type, actor email, and timestamp. Never updated — append-only per Claude.md §4.1.

Actions (WEBHOOK, UPDATE_ENTITY, BATCH_SPAWN, etc.) enqueue on a separate worker. The transition itself commits even if a downstream action fails; see Integrations → error semantics for the exact policy.

Context records

Every job optionally carries a context_record_id pointing at an entity record. Guards + actions evaluate { "var": "field" } against that record's data_payload. Two common patterns:

  • Entity-bound schema (fsm_schemas.entity_name set): the spawn form auto-filters context records to the declared entity kind; the FSM guard composer surfaces annotations for the Variable input.
  • Unbound schema: jobs can spawn without a context — guards that reference { "var": ... } will see null and behave accordingly (usually false). Works fine for workflows that carry their state entirely in a separate system (webhook intake → external ticket system, etc.).

The event log

Every job's full history is in event_log — append-only, one row per transition + one row per administrative cancel. The admin detail view renders it in reverse chronological order so the most recent activity is on top. Each row carries:

  • from_state / to_state (from is NULL on spawn)
  • event_type — the transition name
  • actor — email of the tenant user who fired it, or the platform admin if impersonated (see Authentication → impersonation)
  • reason — populated only for admin cancels (mandatory)

The log is your audit trail for compliance + debugging. There is no "edit event" path; corrections happen by firing a compensating transition.

Admin cancel override

Real-world workflows sometimes need to terminate a job outside the declared FSM — a shipment that was damaged in transit and doesn't fit any "normal" terminal state. For that, FastYoke ships an out-of-band administrative override:

POST /api/v1/jobs/:id/cancel
{ "tenant_id": "...", "target_state": "<any valid state>", "reason": "..." }

Key properties:

  • Bypasses guards. The override is explicitly for cases where the guard model doesn't match reality. Admin JWT role claim required.
  • Target state must exist in the schema — validated against known_states(). Unknown target returns 400.
  • Reason is mandatory. Non-empty string. Lands in event_log.reason as the permanent audit record.
  • Not an FSM transition. The event_type is the sentinel __admin_cancel__; the FSM engine never runs, no guard ever evaluates, no actions fire.

The cancel button is visible in the job detail view only for admin-role users (not operators). See the platform admin's Impersonation flow if you need to cancel on behalf of a tenant admin who's not currently signed in.

The jobs list supports:

  • By schema — dropdown scoped to the tenant's active schemas.
  • By current state — once a schema is selected.
  • By actor — any email that appears in a job's event log.
  • By date range — created-after / updated-before.

Pagination is cursor-based; default page size is 50.

  • Workflows — authoring the FSM shape jobs run against.
  • Entities — context records that drive guard evaluation.
  • Integrations — outbound webhook + action semantics fired from transitions.

Workflow transitions emit outbound webhooks; see Webhooks → Managing subscriptions for the subscription model, the three event sources, and the REST surface.