Create and migrate repo-defined Tessl schedules in a project's tessl.json. Turns a plain-language cadence into a validated schedules entry, and moves an existing UI/CLI schedule into version control.
90
97%
Does it follow best practices?
Impact
94%
0.94xAverage score across 2 eval scenarios
Low
Low-risk findings worth noting
schedules block in tessl.jsonThe schedules block is a top-level object in a project's tessl.json. It maps
a schedule key to a schedule entry. Each entry declares one recurring
launch run.
{
"schedules": {
"<schedule-key>": {
"skill": "...",
"cron": "...",
"environment": "..."
}
}
}a-z, 0-9, single dashes, 1 to 64 chars
(pattern ^[a-z0-9]+(?:-[a-z0-9]+)*$).The entry is validated strictly: a field name that is not in this list is a hard error (this catches typos the author would otherwise only notice when the schedule misbehaves). Use only these fields.
| Field | Type | Notes |
|---|---|---|
skill | string | The skill to run: a registry ref workspace/plugin[@version][#skill], or a repo-local file:path. Validated server-side at apply time. |
cron | string | Five-field cron the schedule fires on, interpreted in timezone. Its tightest interval must be at least 5 minutes. |
environment | string | The workspace environment name (not its id). The id is workspace-scoped, so a committed file names the environment and the apply step resolves it to an id in the target workspace. |
| Field | Type | Default | Notes |
|---|---|---|---|
timezone | string | UTC | IANA timezone the cron is interpreted in (e.g. America/New_York). |
baseBranch | string | main | Branch each fired run clones and targets its PR against. |
snapshot | string | none | Commit SHA or tag pinning the repo snapshot each run starts from. |
workdir | string | repo root | Subdirectory of the repo the skill runs in. |
agent | string | workspace default | Agent to run the skill with. Plain string, validated server-side. |
model | string | agent default | Model to run the skill with. Plain string, validated server-side. |
inputs | object | none | Skill input values, keyed by the skill's own placeholder names. String values only; keys must be non-empty. |
instructions | string | none | Free-text instructions appended to the skill prompt. |
description | string | none | Human-readable description of the schedule (max 4096 chars). |
tessl schedule validate does and does not checkvalidate reads the file and checks the block's shape, each cron
expression (against its timezone), and the minimum 5-minute interval. It
exits non-zero when the block is invalid, so it works as a CI check. A manifest
with no schedules block is valid.
It does not check (these are decided at apply time, in the workspace):
skill ref resolves to a plugin the workspace can use;environment exists in the workspace or carries a GitHub
token;agent and model are in the organization's catalogue;So a file that passes validate can still be rejected when applied. A clean
validate means the file is well-formed, not that the schedule will fire.
{
"schedules": {
"weekly-dependency-digest": {
"skill": "tessleng/dependency-digest",
"cron": "0 13 * * 1",
"timezone": "UTC",
"environment": "dependency-digest",
"agent": "claude",
"model": "claude-sonnet-4-6",
"description": "Weekly dependency digest, Mondays 13:00 UTC"
}
}
}