Pack schema
Every key in a routineos.pack.v1 pack file and a routineos.catalog.v1 index, with patterns, limits and the jobs-watch pack as the example. Taken from site/templates/schema/.
Since 0.6.0. The schemas are at
site/templates/schema/pack.v1.schema.jsonandcatalog.v1.schema.json.
A pack is one JSON file holding a whole routine: its routine.toml as data, its prompt, readme, definition, stages and connectors. A catalog is an index of packs. For the authoring walkthrough, see Writing a pack. Both schemas are JSON Schema draft 2020-12 and set additionalProperties: false, so an unknown key is an error (unlike routine.toml, where lint ignores unknown keys).
Top level
| Key | Required | Rule |
|---|---|---|
$schema |
no | Text |
format |
yes | routineos.pack.v1 |
id |
yes | ^[a-z0-9][a-z0-9-]{0,63}$ |
version |
yes | MAJOR.MINOR.PATCH, no leading zeros |
title |
yes | At most 80 characters |
summary |
yes | At most 280 characters |
category |
yes | sales, marketing, ops, support, finance, recruiting, content, dev, general |
maturity |
yes | piloted or unpiloted |
license |
no | At most 64 characters |
inspiration |
no | Up to 10 entries, see below |
routine |
yes | See routine |
prompt |
yes | Text, the routine’s prompt.md |
readme |
yes | Text, the routine’s README.md |
definition |
no | The Desk definition, see definition |
stages |
yes | 1 to 20 stages |
connectors |
yes | 0 to 20 connectors |
files |
no | Extra files, see files |
routine
routine.toml as JSON.
| Key | Rule |
|---|---|
routine |
{name, type, schedule, first_run}. type is a routine type. first_run must be report-only |
store |
{adapter} |
workspace |
{enabled, name, template, template_version} |
setting |
List of settings, each requiring name, type and default |
gate |
{enabled, transport, timeout_hours} |
action |
List of {name, kind} |
A pack can never ship a routine that runs live on its first run.
definition
The same shape as definition.json (see Definition schema). version and types are required; the learning keys are allowed.
stage
| Key | Required | Rule |
|---|---|---|
id |
yes | ^[a-z0-9][a-z0-9-]{0,63}$ |
kind |
yes | code, model, skill or gate |
title |
yes | 1 to 80 characters |
does |
yes | 1 to 500 characters |
connectors |
no | Up to 20 connector ids |
reads, writes |
no | Up to 20 store paths each, ^[a-z0-9][a-z0-9_-]*(/[a-z0-9_-]+)*$ |
command |
no | ^python3 [^\n]+$, one line |
skill |
no | A skill name |
See Workflow routines and Stages.
connector
| Key | Required | Rule |
|---|---|---|
id |
yes | Slug |
label |
yes | Shown in the install report |
kind |
yes | connector, mcp, builtin or http |
purpose |
yes | Why the routine needs it |
required |
yes | bool |
access |
yes | read or write |
stages |
yes | Stage ids that use it |
connect |
yes | How a person connects it |
alternatives |
no | Other options, by name |
See Connectors in packs.
inspiration
Each entry is {source, title, url}; url must start https://. It credits the public workflow or post a pack was modelled on.
files
An object of at most 40 entries. Each key is a path matching ^(lib|skills)/[a-z0-9_-]+(/(?!\.\.?/)[A-Za-z0-9_.-]+)*\.(py|md|json|txt)$ (a . or .. segment is refused) and each value is the file’s text. Only .py, .md, .json and .txt files under lib/ or skills/ travel in a pack.
Example: jobs-watch
The source templates/jobs-watch/pack.json holds the metadata; pack export adds routine, prompt, readme and definition from the folder.
{
"format": "routineos.pack.v1",
"id": "jobs-watch",
"version": "1.0.0",
"title": "Jobs watch",
"category": "sales",
"maturity": "piloted",
"license": "MIT",
"stages": [
{"id": "search", "kind": "model", "title": "Search postings", "connectors": ["web-search", "web"]},
{"id": "record", "kind": "model", "title": "Record roles and companies"},
{"id": "learn", "kind": "code", "title": "Learn",
"command": "python3 skills/routineos/scripts/routineos.py learn --docs snapshot.json --run run.json --out learn"},
{"id": "write", "kind": "code", "title": "Write",
"command": "python3 skills/routineos/scripts/routineos.py write --docs snapshot.json --run run.json --out batches"},
{"id": "approve", "kind": "gate", "title": "Approve an intro note", "connectors": ["mail"]}
],
"connectors": [
{"id": "web-search", "label": "Web search", "kind": "builtin", "required": true, "access": "read", "stages": ["search"]},
{"id": "web", "label": "Web fetch", "kind": "builtin", "required": true, "access": "read", "stages": ["search"]},
{"id": "mail", "label": "Mail", "kind": "connector", "required": false, "access": "write",
"stages": ["approve"], "alternatives": ["Slack"]}
]
}
summary, each stage’s does and each connector’s purpose and connect are left out above for width. The write stage also declares writes: ["runs", "entities", "inbox", "pending"]. The schema checks only the shape of these names.
Catalog
routineos.catalog.v1 is {format, templates}. Each entry in templates requires:
| Key | Rule |
|---|---|
id, version, title, summary, category, maturity |
As in the pack (title and summary at least 1 character) |
type, schedule |
From the pack’s routine |
path |
The pack file, relative to the index |
bytes, sha256 |
Size and hash of the pack file |
connectors, inspiration |
From the pack |
pack catalog writes the index; pack catalog --check exits 1 when it would change. See Catalog.
Common pitfalls
first_run = "live"in the routine. Refused by the schema.- An unknown key. Every object is closed; a typo fails validation.
- A file outside
lib/orskills/, or a.shfile. Not allowed infiles. - A multi-line
command. The pattern allows onepython3line only.