A workflow is a goal with a deadline and a team. It bundles a
charter, KPIs, a roster of brains users, an owned board, and a set of
paused template automations (progress scorer, task nudger, milestone
reviewer, etc.) into one container with shared lifecycle. Flip the
workflow's status to active and every attached automation un-pauses
together; flip it back to paused or archived and they all stop.
Workflow vs board vs automation
These three primitives compose, and reaching for the right one matters:
| You have… | Use a… |
|---|---|
| A list or table you want to track by hand | Board |
| One scheduled program doing one thing | Automation |
| A goal with a deadline, KPIs, and >1 person involved | Workflow |
A workflow owns a board and several automations. Deleting the
workflow (by default) deletes the attached automations but keeps the
board — pass delete_board: true if you want the board to go too.
Anatomy of a workflow
workflow
├── title short label
├── charter paragraph of intent — the "why"
├── kpis[] { name, target, unit?, deadline? }
├── deadlines[] { label, date }
├── roster[] { user_id, role: owner | contributor | observer }
├── status draft | active | paused | archived
├── board_id the owned board (auto-provisioned)
└── automation_ids[] attached template automations (auto-provisioned, active)
Roster changes cascade onto the owned board's member list: owner → owner, contributor → editor, observer → viewer. Every user on the roster can open the board immediately.
Status is the lifecycle lever. New workflows are created active
by default — every attached automation starts firing on its cron
immediately. Flip to paused to halt every automation together;
archived does the same plus hides the workflow from the default
list. draft is still a valid status if you want a workflow you've
explicitly opted out of running yet.
Creating a workflow — the right way
Ask Claude:
"Set up a workflow for shipping our v2 launch by Q3 with the launch team."
Claude runs create_workflow_flow which walks you through:
- Purpose & success — what is this workflow trying to achieve?
- KPIs — 1–4 measurable signals with targets and optional deadlines. ("Engagement" without a number is rejected — push back.)
- Deadlines — labeled dates (e.g. "code freeze 2026-07-15").
- Roster — which brains users, in what role.
- Template automations — pick from the catalog below.
- Confirm structure — proposed shape is read back.
- Create —
create_workflowprovisions in a single transaction: workflow row + owned board + roster + all chosen automations (active). - Review — open
/workflows/<id>to eyeball the attached automations. Flip status topausedif you need to halt them.
Everything is created in active state with every automation already
running. The cron sweep starts firing them on schedule
immediately — flip status to paused if you need to halt the cron.
The template automation catalog
When the playbook asks "which template automations do you want," it's picking from this set. Each is an active automation that knows about the workflow's KPIs, deadlines, and roster:
| Template | What it does | Default cron |
|---|---|---|
progress_scorer |
Reads the board, scores % done vs KPI, pings the owner if slipping. | Daily 9am |
task_nudger |
Finds rows assigned to roster members due in the next window, DMs each member their list via Telegram. | Daily 8am |
milestone_reviewer |
LLM-reads activity since last milestone, sends the owner a recap (blockers + completions). | Fri 6pm |
agentic_summary |
LLM-generates a progress summary, appends to the board's summaries dataset, dashboard renders the latest. |
Every 2 days, 9am |
monday_migration_sync |
Lists all Monday boards (active + archived) via source_query, upserts one task row per board on the workflow board, auto-classifies by name. |
Hourly |
deadline_radar |
Scans the workflow's deadlines, alerts on anything inside the warning window (default 7d) or overdue. | Daily 9am |
blocked_items_alert |
Lists every row currently status=blocked and pings the owner. |
Weekdays 10am |
kpi_pulse |
LLM-grades each KPI against current board state and sends a red/yellow/green pulse per KPI. | Weekly Mon 9am |
weekly_roster_digest |
LLM-summarises the week and Telegram-broadcasts it to every contributor + owner. Observers excluded. | Fri 5pm |
standup_collector |
Pings each roster contributor asking for a 3-line standup. | Weekdays 9am |
You don't have to take them all. Pick the two or three that match how
you actually run the project. You can add more later via
update_workflow.
Customizing a workflow
update_workflow is the lifecycle and frame editor. Important rules:
- Passing
roster,kpis, ordeadlinesreplaces the array — include every entry you want to keep, not just the diff. status="active"un-pauses every attached automation.paused/archivedpause them.- The owned dashboard auto-regenerates whenever title, charter, KPIs,
or deadlines change. Force a regeneration with
regenerate_dashboard: true.
await brains.update_workflow({
workflow_id,
status: "active", // un-pauses all automations
kpis: [
{ name: "signed customers", target: 5, deadline: "2026-08-01" },
{ name: "NPS", target: 50, unit: "score" },
{ name: "ARR", target: 250000, unit: "usd" }, // include existing + new
],
});
Roster shape:
await brains.update_workflow({
workflow_id,
roster: [
{ user_id: "<uuid-alon>", role: "owner" },
{ user_id: "<uuid-noah>", role: "contributor" },
{ user_id: "<uuid-keren>", role: "observer" },
],
});
// Cascades onto the owned board automatically.
Customizing the attached automations
Each template automation is a real automation — same Deno sandbox, same
tool grants, same caps. Edit it with update_automation and your edits
stick. The workflow doesn't overwrite template automations on
status changes; it only pauses/un-pauses them.
If a template doesn't fit, you can:
- Delete it (
delete_automation) — the workflow still works without it. - Replace it by creating a custom automation from scratch
(
create_automation_flow) and attaching it to the workflow viaupdate_workflow attachment={ automation_ids: […] }. - Tweak its grants or cron with
update_automation— typical edits: change the morning hour, expand the dedupe key, hand the automation an extrahttp_fetchhost.
Smoke-test every newly-created automation right after creating the workflow. Use
run_automation_onceon each attached template to confirm it does what you expect. Workflows now create attached automations asactiveby default, so a broken template starts firing on real cron the moment the workflow is created — catch it before the next cron tick.
Lifecycle
active ← default on create; all attached automations firing on cron
↓ update_workflow status=paused
paused ← automations paused, workflow still visible
↓ update_workflow status=active
active ← un-pauses every attached automation
↓ update_workflow status=archived
archived ← hidden from default lists, automations paused
(draft is still a valid status — explicit opt-in for "don't run yet")
delete_workflow cascades to the attached automations by default but
keeps the owned board unless you pass delete_board: true. This is
deliberate — the board often holds historical data the user wants to
preserve even after the project wraps.
Roster roles
| Role | Brain access | Board write | Workflow edit |
|---|---|---|---|
owner |
yes | yes | yes |
contributor |
yes | yes (editor) | no |
observer |
yes | read-only | no |
Owners can flip status, edit KPIs/deadlines/roster/title, and delete the workflow. Contributors can write to the board (the work surface). Observers can read everything but can't write — useful for executives, clients, or auditors who need visibility without permission to muck with the data.
Tool surface
| Tool | Purpose |
|---|---|
create_workflow_flow |
Guided multi-step authoring. Use this. |
create_workflow |
Raw create — only for reproducing existing workflows. |
list_workflows |
List workflows in a brain. |
get_workflow |
Read workflow + roster + attached automations. |
update_workflow |
Edit charter, KPIs, deadlines, roster, status. |
delete_workflow |
Delete (cascades automations; board kept unless delete_board: true). |