Make a routine

Member·6 minutes to read

The routine health line (a routine that hasn't fired, or was paused while you were away) is verified against docs/superpowers/specs/2026-09-15-p4-e-routine-heartbeat.md §1.1–§1.2; the spend cap against docs/superpowers/specs/2026-09-15-p5-g-billing-meter-budgets.md §1.2; and the delete restore against docs/superpowers/specs/2026-09-14-p2-f-web-quality.md §1.2. None of the three has shipped yet — re-verified against the code at close-out.

What this does for you

A routine runs an instruction on a schedule, or when something happens, so a bot does a job without you starting it by hand.

Before you start

  • The bot or group this routine belongs to, open in its details pane.
  • An instruction ready to give — the same words you'd use if you asked the bot directly.
  • Fewer than 50 existing routines on that bot or group; a bot or a group may have at most 50 (packages/db/src/repos/routines.ts).
  • A minute to read the checklist below. A routine runs unattended, so the six habits that make one worth trusting are worth having before you build it, not after it has already run a few times:
    • Draft it first. Give the routine a narrow instruction, run it once with Test run, and read what it did before you let the schedule take over.
    • Decide what it does with no data. If the thing it looks for (an unread email, an open ticket) isn't there, say so in the instruction — otherwise the bot improvises.
    • Decide what it does with stale data. A routine that reads the same feed every hour needs to know whether to re-report something it already reported.
    • Ask for idempotent retries. A routine that failed partway and fires again on schedule should not resend what it already sent.
    • Say where partial completion is reported. If the instruction has several parts, say what the bot should tell you when only some of them finished.
    • Re-test after anything the routine depends on changes — a renamed sheet, a moved folder, a plugin re-authenticated.

Steps

  1. Open the bot's or group's details pane, go to Routines, and choose + Create Routine.

    <!-- shot: create-a-routine-01-phone.png | Creating a routine from a bot's Routines section, on a phone --> <!-- shot: create-a-routine-01-desktop.png | Creating a routine from a bot's Routines section, on a desktop -->
  2. Name the routine and write its instruction. Both save as you leave the field — there is no separate Save button.

    <!-- shot: create-a-routine-02-phone.png | The routine editor's name and instruction fields, on a phone --> <!-- shot: create-a-routine-02-desktop.png | The routine editor's name and instruction fields, on a desktop -->
  3. Choose + Add trigger, then On a schedule, and pick a preset — Every hour, Every day, Weekdays, Every week, Every month or Interval. Each preset opens a short time picker and closes into a plain-English summary line, such as "Every day at 8:00 AM".

    <!-- shot: create-a-routine-03-phone.png | The trigger menu's schedule submenu, on a phone --> <!-- shot: create-a-routine-03-desktop.png | The trigger menu's schedule submenu, on a desktop -->
  4. To edit a trigger later, open its summary row: the edit menu offers the same presets plus Custom, which swaps the pills for a raw five-field cron expression (minute, hour, day of month, month, weekday — no seconds, no @daily-style macros). The summary above it regenerates from whichever value you leave it on.

  5. If the job should also start from an event rather than a clock, choose one of the other rows in + Add trigger — Slack message, Git event, Teams message, Linear issue, Sentry alert, PagerDuty incident or Webhook — instead of, or alongside, a schedule. Prefer the narrowest trigger that does the job. A trigger that fires on every message in a busy channel, rather than one scoped to a keyword or a specific event, costs you noise, usage and the occasional wrong-context run — narrow it at the source, not by asking the bot to ignore most of what it sees.

  6. Once the routine has a name, an instruction and a trigger, Test run turns on. A test run does the real work — it sends, spends and changes whatever the instruction says, and it costs the same as a run the trigger starts on its own — so read the instruction back before you press it.

  7. Turn Active on when you're ready to let the trigger fire it on its own; turn it off at any time to pause the routine without deleting it. Delete removes the routine immediately, with no confirmation step.

A worked example

A daily inbox sweep, written the way the fields above take it:

Name: Inbox sweep
Instruction: Read unread email from the last 24 hours. Reply to anything that only needs an
  acknowledgement. Leave everything else unread for a person to handle, and say at the end how
  many you replied to versus left.
Trigger: On a schedule → Every day → 8:00 AM
Stored as: 0 8 * * *

The stored value is what the schedule actually runs on; the preset is only how you set it. Picking Custom later and typing 0 8 * * * by hand would produce the identical trigger.

What can go wrong

What you seeWhyWhat to do
That schedule is not valid.The cron expression didn't parse — it needs exactly five space-separated fields, and neither seconds nor a macro like @daily are understood.Fix the expression, or switch the trigger back to a preset from its edit menu.
A bot may have at most 50 routines.Every bot, and every group, is capped at 50 routines.Delete or combine an existing routine before adding another.
That routine could not be found.The routine was deleted, or it belongs to someone else.Reopen the Routines list and pick it again.
That change could not be saved. Try again.A rename, an instruction edit, the Active switch or a delete didn't reach the server.Try the change again; if it keeps failing, check your connection.
Name, instruction and a trigger first.Test run stays off until the routine has all three.Fill in whichever one is still missing.

See also

Last verified against build c0f77aa.