{
"$schema": "https://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"description": "A scheduled AI-agent task. Normally written and maintained by the daemon (one routine.toml per routine); this schema documents its on-disk shape and powers editor validation. Runtime trigger state lives in a gitignored state.local.toml sidecar, not here.",
"properties": {
"agent": {
"description": "Agent registry key (e.g. \"claude\") resolved from the agents config directory.",
"type": "string"
},
"created_at": {
"description": "Unix timestamp (seconds) when the routine was created. Daemon-assigned.",
"minimum": 0,
"type": "integer"
},
"enabled": {
"default": true,
"description": "Whether the routine is active.",
"type": "boolean"
},
"id": {
"description": "UUID v4 uniquely identifying the routine, stable across renames. Assigned by the daemon on create.",
"type": "string"
},
"last_manual_trigger_at": {
"description": "Legacy/read-only. Last-manual-trigger timestamp; runtime trigger state now lives in the gitignored state.local.toml sidecar and is never written to routine.toml.",
"minimum": 0,
"type": "integer"
},
"last_triggered_at": {
"description": "Legacy/read-only. Pre-rename last-manual-trigger timestamp; migrated into the state.local.toml sidecar on the next write and never written back. Accepted only so routine.toml files from older daemons still load.",
"minimum": 0,
"type": "integer"
},
"max_runtime_secs": {
"description": "Max wall-clock seconds a single run may execute before the watchdog kills its hung session. Absent uses the daemon default.",
"minimum": 0,
"type": "integer"
},
"prompt": {
"description": "Task prompt handed to the agent.",
"type": "string"
},
"repositories": {
"description": "Git repositories listed to the agent as prompt context (not cloned by moadim).",
"items": {
"additionalProperties": false,
"properties": {
"branch": {
"description": "Branch to use; omit for the remote default branch.",
"type": "string"
},
"repository": {
"description": "Git remote URL.",
"type": "string"
}
},
"required": [
"repository"
],
"type": "object"
},
"type": "array"
},
"schedule": {
"description": "Cron expression for when the routine runs, evaluated in the host's local system timezone (the OS crontab timezone), not UTC.",
"examples": [
"@hourly",
"@daily",
"30 9 * * 1-5"
],
"type": "string"
},
"title": {
"description": "Human name; slugified to name the workbench folder and tmux session.",
"type": "string"
},
"ttl_secs": {
"description": "Workbench retention (seconds) for finished runs; caps the cron-derived retention lower. Absent uses the daemon default.",
"minimum": 0,
"type": "integer"
},
"updated_at": {
"description": "Unix timestamp (seconds) when the routine was last updated. Daemon-assigned.",
"minimum": 0,
"type": "integer"
}
},
"required": [
"schedule",
"title",
"agent",
"prompt"
],
"title": "Routine",
"type": "object"
}