This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/docs/WORKFLOWS.md
Jeffrey Smith ba4c9ca65c Feat v0.7.4 documentation + deferred surface work
Docs restructuring: category grouping (Getting Started, Platform,
Extension Development, Operations) with 14 ordered docs. Four new
guides: Permissions & Groups, Workflows, Starlark Reference, Frontend
JS Guide. Extension Guide updated with config_section docs.

Content refresh across 10 existing docs: rebrand volume names,
stale CSS vars, TLS_MODE env, self-hosted font notes, Architecture
frontend section.

Team Admin workflows.js (722 lines) split into 3 modules:
workflows.js (router+CRUD), workflow-editor.js (editor+stages),
workflow-monitor.js (assignments+monitor+signoff).

Fix: docs outline scroll no longer pushes topbar off-screen.
Fix: --bg-2 (undefined CSS var) replaced with --bg-secondary.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 13:49:00 +00:00

194 lines
6.3 KiB
Markdown

# Workflows
Workflows are multi-stage processes with team assignment, validation gates,
SLA enforcement, and optional Starlark automation. They are managed in
**Team Admin > Workflows**.
## Core concepts
| Concept | Description |
|---------|-------------|
| **Definition** | A named template: stages, entry mode, staleness timeout. Created per-team or adopted from global definitions. |
| **Stage** | One step in the workflow. Has a mode, audience, optional team assignment, and optional SLA. |
| **Instance** | A running copy of a definition. Pins a published version snapshot and tracks accumulated stage data. |
| **Assignment** | A queue entry linking an instance stage to a team member. Claim → work → complete. |
| **Signoff** | An approval or rejection recorded against an instance stage (multi-party validation). |
## Entry modes
| Mode | Description |
|------|-------------|
| `team_only` | Only authenticated team members can start instances. |
| `public_link` | Anyone with the public URL can start an instance. The first stage must have `audience: public`. An `entry_token` is issued for the anonymous submitter to resume later. |
Public entry URL format:
```
{origin}/api/v1/public/workflows/{workflow_id}/start
```
## Stage modes
Each stage has a **mode** that determines how it progresses:
| Mode | Description |
|------|-------------|
| `form` | User submits structured data. Stage data is accumulated into the instance. |
| `review` | Multi-party sign-off gate. Requires configured approvals before advancing. |
| `delegated` | Assigned to a team member queue. The assignee claims, works, and completes. |
| `automated` | Starlark hook executes without user interaction. Can chain up to 10 consecutive automated stages. |
## Stage types
| Type | Description |
|------|-------------|
| `simple` | Linear — always advances to the next ordinal. |
| `dynamic` | Conditional — evaluates branch rules against stage data to pick the next stage. |
| `automated` | Combined with mode `automated` for fully scripted stages. |
## Audiences
| Audience | Description |
|----------|-------------|
| `team` | Only authenticated team members can interact. |
| `public` | Anonymous users can interact (used with `public_link` entry). |
| `system` | System-generated stages, no direct user interaction. |
## Team assignment
When a stage has `assignment_team_id` set, the engine creates an
**assignment** record:
1. Assignment enters the queue with status `unassigned`.
2. A team member **claims** the assignment (status → `claimed`).
3. The assignee works the stage and **completes** it (status → `completed`).
4. The engine auto-advances to the next stage.
A **required role** can restrict who may claim:
- Set `stage_config.required_role` to a team role name (e.g. `"reviewer"`).
- Only members with that role can claim the assignment.
Team roles are configured in **Team Admin > Settings > Roles**.
## Signoff gates (multi-party validation)
Review-mode stages can require multiple approvals before advancing.
Configure via `stage_config.validation`:
```json
{
"validation": {
"required_approvals": 2,
"required_role": "approver",
"reject_action": "cancel"
}
}
```
| Field | Description |
|-------|-------------|
| `required_approvals` | Minimum approve decisions needed to advance. |
| `required_role` | Only members with this team role can sign off. Empty = any member. |
| `reject_action` | What happens on rejection: `"cancel"` (default) cancels the instance, or a stage name to reroute. |
Each signoff records: user, decision (`approve` or `reject`), optional comment, timestamp.
## SLA enforcement
Two timeout mechanisms run in a background scanner (every 5 minutes):
### Per-stage SLA
Set `sla_seconds` on a stage. When an instance has been in that stage
longer than the threshold:
- `sla_breached` flag is set in instance metadata.
- A `workflow.sla_breach` WebSocket event is emitted.
- The instance is **not** auto-cancelled — breaches are informational.
### Per-workflow staleness
Set `staleness_timeout_hours` on the workflow definition. When an instance
has not been updated for longer than the threshold:
- Instance status is set to `stale`.
- All open assignments are cancelled.
- A `workflow.stale` WebSocket event is emitted.
## Branch rules
Dynamic stages evaluate conditions against accumulated `stage_data`
to determine the next stage. Rules are a JSON array on the stage:
```json
[
{ "field": "priority", "op": "eq", "value": "high", "target_stage": "escalation" },
{ "field": "amount", "op": "gt", "value": 10000, "target_stage": "manager-review" }
]
```
First matching rule wins. If no rules match, the next ordinal stage is used.
### Operators
| Op | Description |
|----|-------------|
| `eq` | Equal (string-normalized) |
| `neq` | Not equal |
| `gt`, `lt`, `gte`, `lte` | Numeric comparisons |
| `exists` | Field is present in stage data |
| `not_exists` | Field is absent |
| `in` | Value is in a list |
| `contains` | String contains substring |
`target_stage` can be a stage name (case-insensitive) or a numeric ordinal.
## Publishing
Workflows have a draft/publish lifecycle:
1. Edit stages and configuration in the workflow editor (draft state).
2. **Publish** creates a versioned snapshot of all stages.
3. New instances pin the latest published version.
4. Editing stages after publishing does not affect running instances.
Version numbers auto-increment. The snapshot preserves the complete
stage definition array at publish time.
## Starlark hooks
Automated stages execute a Starlark script via the `starlark_hook` field:
```
package_id:entry_point
```
For example: `my-automation:on_review` calls the `on_review` function
in the `my-automation` package. If no entry point is specified,
`on_run` is used.
The hook receives a context dict:
```python
{
"instance_id": "...",
"current_stage": "...",
"workflow_id": "...",
"started_by": "...",
"stage_data": { ... }
}
```
The hook returns a dict controlling what happens next:
| Key | Effect |
|-----|--------|
| `advance: True` | Auto-advance to the next stage |
| `data: { ... }` | Merge into stage data for the next stage |
| `error: "msg"` | Set instance status to `error` and halt |
Up to 10 consecutive automated stages can chain before the engine
stops with an error (cycle guard).
See the [Starlark Reference](STARLARK-REFERENCE) for available
sandbox modules.