Automations
A trigger (schedule or webhook) that runs a target. Use them when work should fire on a cadence or in response to an external event.
An Automation is one simple thing: a trigger bound to a target. A schedule or an inbound webhook fires; ThinkWork runs the target — a new (or fixed) agent thread, a git-backed Routine, or a Workflow — optionally as a specific user, and optionally without a Space so it stays quiet.
That’s the whole model:
name + Trigger + Target (+ optional run-as user, + optional Space)Everything else the older Automations surface asked you to reason about — goals, workers, judges, evidence policies, loop budgets, suitability gates — is gone. It was speculative machinery that never produced a judgment row or an ROI counter, and it made a two-field idea feel like a control panel.
Automations
A trigger (schedule or webhook) that runs a target. Use them when work should fire on a cadence or in response to an external event.
Workflows
Explicit multi-step orchestration. Use them for known sequences with branching, retries, human-in-the-loop waits, and app or data operations that should render as a graph. A Workflow can be an Automation’s target.
Evaluations
Test and scoring suites. Use them to measure agent behavior against datasets or rubrics. They are not the recurring-work authoring surface.
Every Automation has exactly one trigger, one of two families:
cron()
for wall-clock alignment; see the
scheduling pitfall.Manual “Run now” is not a trigger family. It is an action available on every
Automation, recorded as run source manual_run, so a local test run exercises
the exact same dispatch path as the real schedule or webhook.
The target is what actually runs. Its configuration is target-shaped — you only see the fields the chosen target needs:
Every Automation carries a run-as user (defaulting to its creator). When the Automation runs, ThinkWork injects that user’s context — memory bank, identity, per-sender context — into the turn, through a narrow service path with a tenant-membership cross-check.
This is why attaching the right user matters: a nightly digest that runs “as” the operations lead sees the operations lead’s memory and connectors, not an anonymous system identity. An Automation with no run-as user cannot dispatch a context-bearing turn.
A Space is optional for routine and workflow targets:
Agent-thread targets always require a Space (there is nowhere else for the conversation to live); save-time validation rejects a headless agent-thread automation with an actionable error.
The raw JSON body of a webhook becomes the run input:
That fence is deliberate: webhook bodies are attacker-controllable and may carry PII. The model must never treat payload content as operator directives. There is no templating in v1 — the body is passed through as data.
Schedule fires | Webhook POST arrives | Manual "Run now" \ | / \ | / v v v Shared automation dispatcher | run-as user context injected (tenant-checked) | +----------------+-----------------+ | | Space present No Space | | Execution thread Headless run in that Space (no thread) | | Agent wakeup / Routine / Workflow executes | | Result in the thread Failure -> deduplicated Inbox itemSchedule, webhook, and manual runs share one dispatcher, so behavior is identical across the three entry points. Idempotency is recoverable: a webhook retry arriving mid-start repairs the half-built run rather than returning a partial as final.
Either way, a failed run is visible; nothing fails into the void.
scheduled_jobs, the
job-schedule-manager, and AWS Scheduler only when no Automation run exists.