Routine kinds
Code, skill, workflow and hybrid routines. What each kind is, how it maps to the real fields, and how to pick one.
What it is
A routine kind describes where a routine’s work happens: in scripts, in a skill, in a chain of stages, or split between code and the model. It is a design pattern, not a field. Nothing in routine.toml says kind = "hybrid".
The fields that do exist are:
| Field | File | Values | Decides |
|---|---|---|---|
type |
routine.toml [routine] |
serverless, watch, approval-gated, interactive |
Who watches it, and whether it has a Desk and a gate |
delivery |
app.toml [[routine]] |
repo (default), account-skill, inline |
How the live routine gets its logic |
stage kind |
pack stages (since 0.6.0) |
code, model, skill, gate |
What each step of a packed routine is |
A kind is a way of combining these.
| Kind | Work happens in | Typical delivery | Example |
|---|---|---|---|
| Code | lib/ scripts; the model only runs commands and reports |
repo |
A weekly report that counts and compares numbers |
| Skill | A skill folder the run loads | repo or account-skill |
Inbox triage with a reply-style skill |
| Workflow | A declared chain of stages | repo |
A pack with fetch, judge, gate and write stages |
| Hybrid | Code for rules, the model for reading and judging | repo |
Hiring Signals (jobs-watch) |
Why it exists
“Should this be code or a prompt?” is the first design question for every routine, and the answer differs per routine. A script that filters by market gives the same answer every run. A model that decides whether a role is a real lead needs to read. Getting the mix wrong costs either tokens (the model doing arithmetic) or quality (a regex judging fit).
How it works
The right mix
The design step states the mix per routine and the reason:
- Moves and filters structured data (fetch, filter, dedupe, count): scripts in
lib/, zero model tokens for those steps. - Reads, writes or judges (triage, summarising, drafting, research): the model.
- Plainly mechanical, repeated steps: code is suggested with the saving shown. The person decides.
- Budget check, gates and secrets handling always use a fixed mechanism. That is a safety rule, not a style choice.
And per rule:
- Code: settings filters, caps, ids, keys and times.
- Judgement: fit, classification, summaries, drafts.
- A rule a person edits in Settings is always code. If the model applied it, an edit on the Desk would not reliably change the run.
Where the logic lives
Local files are always built first (prompt.md, scripts, any skill folder). delivery only decides how the live routine gets them.
| Delivery | How | Status |
|---|---|---|
repo |
The run clones a GitHub repo; skills under the repo’s .claude/skills/ come along. Needs repo = "owner/name" |
Default. Proven end to end in a pilot (registry repo-delivery) |
account-skill |
The skill is uploaded to the person’s claude.ai account and synced into each cloud session. Needs skill |
Docs-based. The person uploads it; RoutineOS does not |
inline |
The prompt alone carries the logic | A repo-less routine was created and ran in a pilot (registry repo-less-routine) |
Skills kept only in ~/.claude/skills/ on one machine do not exist in a cloud run.
The threat check
Every design is asked three questions: does it see private data, does it read content strangers control, and does it send things out? If all three are yes, the design says so plainly and recommends a split:
- One routine reads untrusted content and has no send tool.
- A second acts only on approved, structured output, behind a gate.
That is a recommendation. If the person keeps the combined design, the decision goes into risks.md with the date, and every external send keeps a gate. Every prompt treats fetched and stored text as data, and attaches only the connectors it needs.
Worked example
Hiring Signals is type = "watch" with a gate, delivery = "repo", and is a hybrid: the model searches and reads job pages; code applies markets, title_keywords and excluded_companies, computes ids, counts outcomes and writes the store. It reads public pages strangers control and sees no private data, and its only external action (an intro note) goes through an email gate. The threat check passes without a split.
Common pitfalls
- Looking for a kind field. There is none. Set
type,deliveryand, in a pack, stage kinds. - A Settings rule applied by the model. In a pilot the model kept two “Ecommerce” roles for the keyword
commerceand the write script dropped them, because the script matched whole words. Put the rule in code so the Desk edit means what it says. - A skill only on your laptop. Use
repooraccount-skill.