Workflows#
Workflows are Seizu’s durable automation pipelines. A workflow has an ordered list of stages and either a UTC time schedule, a set of SyncMetadata watch filters, or no automatic trigger (manual). Activities in one stage start in parallel; the next stage starts only after every activity in the current stage succeeds. Temporal owns the schedule and execution history, so runs are not tied to a single polling process and missed ticks can be caught up after downtime.
Managing workflows#
Open Workflows in the sidebar. Users with workflows:read can inspect
definitions, versions, and runs. workflows:write permits create, edit, and
run-now; workflows:delete permits deletion. Edit, run-now, restore, and
delete are additionally owner-scoped: only the user who created a workflow
may mutate it. Non-owners receive the same not-found response as a missing
workflow. The legacy
scheduled_queries:* permissions are expanded to these permissions during
the compatibility release.
The editor supports:
adding, removing, and reordering stages;
adding activities, reordering them within a stage, or moving them between stages;
assigning every activity a named output and selecting an earlier-stage output as its input;
activity-specific parameter forms supplied by the enabled module; and
manual-only, interval, hourly, daily, monthly, or SyncMetadata watch triggers; and
selecting one or more independent workflows to start after every stage succeeds.
Output names use lower_snake_case and are unique across the workflow. An
activity may reference only an output from an earlier stage, which keeps
parallel activities independent and makes execution deterministic. References
receive the output’s value; Temporal also retains a small metadata object
for status, counts, and diagnostics.
Cypher is now a normal query activity, so it can run in any stage and more
than once in one workflow. Its optional input is available to Cypher as
$input; input is therefore reserved and cannot also be configured as a
static query parameter. Query activities output a list of result-row objects.
Each registered code-defined Temporal workflow (e.g. agent_chat,
cve_repo_report, cve_dependency_remediation, cartography_sync) is its own
activity type: the activity starts the child workflow, waits for it, and
exposes the child’s typed result as its named output. Stored definitions using
the former workflow activity sub-type (with a workflow parameter) are
migrated to the top-level type transparently on read; new saves must use the
top-level types.
agent_chat is the general-purpose AI activity: you write the prompt, and it
runs a headless agent session as the workflow’s creator, publishing the
session’s summary as its output. Its input reference is optional — referenced
rows are passed to the agent as untrusted evidence rather than instructions.
See the Temporal workflows documentation.
When one activity fails, the other activities already running in that stage are allowed to settle. The workflow then fails and no later stage starts. Post-completion workflows start only after every stage succeeds. They are independent top-level Temporal executions: each keeps its own schedule, versioned definition, overlap mutex, and run history. If a selected workflow has since been deleted, the source run logs a warning and continues. Saving an edited workflow removes deleted targets from its trigger list. Chaining keeps the normal owner boundary: a workflow can trigger only workflows owned by the same user.
Query outputs are streamed only up to the configured max_rows, rather than
materializing an unbounded Neo4j result first. Row-consuming activity forms
also expose an optional max_rows; when set, Seizu takes that prefix before
validating and passing the input to the module. WORKFLOW_RESULT_MAX_BYTES
adds a serialized-size bound at every activity boundary. Modules that perform
external side effects run once by default because Temporal activities are
at-least-once; a module may opt into up to ten attempts with an
activity_retry_attempts() function after making its handler idempotent.
Run now starts a Temporal execution immediately, including for a disabled workflow. Disabling a workflow pauses its Temporal Schedule but deliberately does not prevent an operator-requested run.
A manual workflow has no Temporal Schedule. It can still be started with Run now or by another workflow’s post-completion trigger.
Scheduling behavior#
Schedules are stored as desired state in the report store and reconciled to a deterministic Temporal Schedule ID. The UI exposes schedule sync state so a temporary Temporal outage does not lose the saved definition.
Interval and hourly schedules run once when first enabled, then at their configured cadence.
Daily schedules use selected weekdays and an
HH:MMUTC time.Monthly schedules use selected calendar days and clamp missing days to the month’s last day.
Watch schedules run a lightweight poll workflow at
WORKFLOW_WATCH_POLL_SECONDS. It starts the configured workflow as a child only when SyncMetadata changed, so polling executions do not appear in the workflow’s recent-runs list. Pre-upgrade scheduled watch executions shared one ambiguous ID prefix for polls and real runs, so that legacy prefix is omitted from watch-backed recent-run lists after upgrading; manual runs and newly triggered runs remain visible.Overlap policy is buffer one: one due run is retained while a previous run is still active.
YAML seed format#
The YAML file remains a seed source, not runtime configuration:
workflows:
- name: Notify on critical CVEs
schedule:
type: daily
days_of_week: [0, 1, 2, 3, 4]
hour: 9
minute: 0
enabled: true
trigger_workflows: ["1234567890"]
stages:
- activities:
- type: query
output: critical_cves
parameters:
cypher: |
MATCH (cve:CVE)
WHERE cve.severity = $severity
RETURN {id: cve.id, severity: cve.severity} AS details
parameters:
- name: severity
value: CRITICAL
max_rows: 200
- activities:
- type: slack
input: critical_cves
output: slack_notification
parameters:
channels: [security-alerts]
scheduled_queries seeds are still accepted when workflows is absent and
are normalized to a query stage followed by one sequential stage per legacy
action. A configuration cannot contain both top-level sections.
API and CLI#
The canonical REST collection is /api/v1/workflows; it exposes CRUD,
version history, POST /{id}/run, and Temporal run history. The CLI mirrors
this under seizu workflows. MCP built-ins use the workflows__* group.
The /api/v1/scheduled-queries API and seizu scheduled-queries CLI remain
temporary aliases. They list only definitions that can be projected to the
old single-query/action shape without losing meaning.
Worker configuration#
The seizu-temporal-worker service owns both schedule reconciliation and
execution. Relevant settings are:
TEMPORAL_ADDRESS,TEMPORAL_NAMESPACE, andTEMPORAL_TASK_QUEUE;WORKFLOW_ACTIVITY_MODULES(comma-separated Python modules);WORKFLOW_QUERY_MAX_ROWS;WORKFLOW_RESULT_MAX_BYTES;WORKFLOW_WATCH_POLL_SECONDS; andWORKFLOW_RECONCILE_SECONDS.
SCHEDULED_QUERY_MODULES is accepted as a fallback setting for one
compatibility release. The standalone seizu-scheduled-queries service is no
longer part of the Compose stack.