> ## Documentation Index
> Fetch the complete documentation index at: https://user-docs.olyrosstudios.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Schedules

> Schedules let you run recurring work without anyone pressing a button.

A schedule runs something for a company on a cadence: every N hours, or on a cron
expression in a chosen timezone. Each firing creates one of five things, chosen by the
schedule's target: an Olyros cloud task for an agent, a GitHub issue, a Jira issue, a
work item, or a run of a [workflow](https://user-docs.olyrosstudios.com/workflows.md) with stored parameters. Schedules live
in the client app under **Tasks -> Schedules** (`/schedules`, `/schedules/new`,
`/schedules/:scheduleId`, `/schedules/:scheduleId/edit`). The admin app's
`/scheduler` page is a different thing: it shows the platform's internal system jobs.

## What it does

**Two cadence types.** `schedule_type` is `interval` (seconds, minimum 3600) or `cron`
(a cron expression evaluated in the schedule's `timezone`, default `UTC`). Presets
(`preset_key`: `hourly`, `daily`, `weekly`, `monthly`) are stored for the UI; intervals
of a day or longer snap to 02:00 UTC so daily work lands at a quiet hour.

**Five targets (`target_system`).**

| Target | What a firing creates | Required metadata |
| - | - | - |
| `olyros` | A cloud task from the schedule's task template (`task_title`, `task_description`, agent, optional OHO instance, executor and runtime names, working dir, priority, repositories), then dispatches it. | `agent_id` is required: a task cannot be dispatched without an agent. |
| `workflow` | A workflow execution. The stored `parameters` become the trigger event together with a `_source` envelope of type `schedule`. The run is attributed to the schedule (`schedule_id`, `schedule_run_number`). | `target_metadata.workflow_id`; the workflow must exist, not be archived, and pass its own guardrails. |
| `github` | A GitHub issue in a repository the connection can reach, carrying the agent trigger (label or YAML front matter) so the GitHub integration turns it into a task. | active `target_connection_id`, `target_metadata.repository`, optional `assignees`, `additional_labels`; `agent_id`. |
| `jira` | A Jira issue in a project; its description always carries YAML front matter naming the agent, the schedule and the repositories. A workflow with a `jira_event` trigger on that connection picks it up. | active `target_connection_id`, `target_metadata.project_key`, `issue_type_id`, optional `additional_labels`; `agent_id`. |
| `work_item` | A generic work item of `target_metadata.work_item_type` for an OHO to pull. | `work_item_type`, optional `required_capabilities`, `executor_affinity`. Server-handler types and server-only capabilities are refused. |

**Overlap handling.** With `overlap_policy` `skip` (default) a firing is skipped while a
previous run is still active (a non-terminal task, or for workflow targets a `running`
or `suspended` execution). With `queue_one` at most one follow-up task is queued behind
the active run.

**Lifecycle.** `status` is `active`, `paused` or `retired`. A schedule can be paused and
resumed, retired for good (retired schedules cannot be edited or triggered), capped at
`max_runs`, and it pauses itself after `auto_pause_after_failures` consecutive run
failures. Launch failures (a missing workflow, a guardrail block, a dispatch error)
count separately as trigger failures and auto-pause after three.

**Run history and stats.** `taskScheduleRuns` lists the tasks a schedule produced,
`taskScheduleWorkflowRuns` the workflow executions, and `taskScheduleStats` gives
total, completed, failed and cancelled runs, success rate, average duration and cost.

**Run now.** `triggerTaskScheduleNow` fires a schedule immediately, subject to the same
overlap and `max_runs` checks.

## Who can use it

* Every schedule query and mutation is open to **any company member**
  (membership only); there is no separate editor or admin gate. That includes filing a
  schedule in a folder; managing the folders themselves needs Editor (see
  [Folders](#folders)).
* The `github` and `jira` targets additionally need an active connection from
  [Integrations](https://user-docs.olyrosstudios.com/integrations.md).
* No plan or tier gate exists for schedules.

## How to configure it

1. Open Tasks -> Schedules -> New and fill the cadence: `createTaskSchedule(input)` with
   `schedule_type`, and either `interval_seconds` (at least 3600) or `cron_expression`
   (validated with croniter) plus `timezone` (validated as an IANA zone).
2. Pick the target. For `olyros`, choose an agent (required) and optionally an OHO
   instance, executor, runtime, working directory, priority and repositories. For
   `workflow`, pick the workflow and enter the parameter values its `api_trigger` node
   declares. For `github` or `jira`, pick the connection and the repository or project
   and issue type; the agent is required because the issue carries its trigger.
   Validation rejects input before anything is written: every repository must belong
   to one of the company's GitHub connections and still be granted to the GitHub App
   installation; `target_connection_id` is accepted only for `github` and `jira`; a
   `work_item` target's `executor_affinity` must be one of the company's OHO instances
   or an execution backend visible to the company, and a `github_content_sync` work
   item needs a company repository. Ids from another company answer "not found" like
   unknown ids.
3. Set `overlap_policy`, `max_runs` and `auto_pause_after_failures` (default 3).
4. Manage it from the detail page: `updateTaskSchedule` (the target system cannot be
   changed after creation), `pauseTaskSchedule`, `resumeTaskSchedule`,
   `retireTaskSchedule`, `triggerTaskScheduleNow`.

## Folders

A folder is a named group a company uses to organise its schedules. Folders belong to the
company, not to a user. Each folder belongs to one area: the folders created under
Schedules hold schedules only and never appear under Workflows, which has its own folders
(see [Workflows](https://user-docs.olyrosstudios.com/workflows.md#folders)). A schedule is in at most one folder; a schedule in
no folder is **Unfiled**. Filing a schedule changes nothing about what it runs or when.

* **Who manages folders.** Creating, editing (name, description, colour) and deleting a
  folder needs the Editor role or higher (ability `folder.manage`). Any member can see
  the folder list.
* **Order.** Folders are listed alphabetically, ignoring case. There is no manual order.
* **Who files a schedule.** Any company member, the same as every other schedule edit
  today: `folderId` on `createTaskSchedule` and `updateTaskSchedule`, or
  `moveTaskSchedulesToFolder(scheduleIds, folderId)` for one or many schedules at once
  (all or nothing; `folderId` null means Unfiled). Retired schedules can be moved.
* **Deleting a folder** never deletes schedules: `deleteFolder` moves them to Unfiled and
  deletes the folder in one step. A move into the folder that races the delete fails with
  "Folder not found".
* **Names** are trimmed and must be 1 to 100 characters. They are unique per area ignoring
  case (`Reports` and `reports` collide under Schedules), so the same name may also exist
  under Workflows, and `/` is allowed. Invisible
  characters are refused, except the joiners inside emoji. Colours are free strings up
  to 20 characters.
* **Descriptions** are optional and may span several lines. Windows and old Mac line
  breaks are stored as plain line breaks. The text is trimmed and at most 500
  characters. Tabs and other invisible characters are refused, as in names.
* **Listing.** `folders(context: SCHEDULES)` lists the Schedules folders, and
  `createFolder(context: SCHEDULES, ...)` creates one. `taskSchedulesPage` filters by
  `folderId` or by `unfiledOnly` (not both), and `taskScheduleFolderCounts(statuses)`
  returns the total, the Unfiled count and a count per folder for the same status filter.
* A Workflows folder, or a folder from another company, answers "Folder not found" when
  used to file, move or filter schedules, like an unknown id. The database also refuses
  filing a schedule in another company's folder.

## Limits and defaults

| Setting | Default | Where enforced |
| - | - | - |
| `interval_seconds` minimum | 3600 (`MINIMUM_SCHEDULE_INTERVAL_SECONDS`) | create and update validation |
| `timezone` | `UTC` | validation (IANA name) |
| `overlap_policy` | `skip` | trigger loop |
| `auto_pause_after_failures` | 3 | run outcome hook and dispatch path |
| trigger-failure auto-pause | 3 consecutive launch failures | trigger loop |
| `priority` (task template) | 5 | task creation |
| `max_runs` | none | trigger loop and run-now |
| Polling cadence | due schedules are checked every 60 s by the platform job `check_task_schedules` | scheduler registry |
| Daily-or-longer intervals | first run snaps to the next 02:00 UTC | `compute_next_run` |
| Folder name | 1 to 100 characters after trimming, unique per area ignoring case | folder mutations and a unique index |
| Folder description | optional, multi-line, at most 500 characters after line-break normalisation and trimming | folder mutations |

## What it emits

* Cloud tasks or workflow executions tagged with the schedule id and run number, so
  usage and cost roll up per schedule.
* GitHub or Jira issues for those targets, which the integration then turns into tasks
  (GitHub) or leaves for a workflow to pick up (Jira).
* Work items for OHO pull loops.
* Failure counters and `last_trigger_error` on the schedule itself, plus automatic
  pausing.

## Known gaps

* Schedules reference executors and runtimes by name (`executor_name`,
  `runtime_name`), not by id; a `workflow` target avoids this because its
  `create_task` node carries the ids.
* The `jira` target creates the issue but does not create a task: there is no
  per-connection Jira trigger setting, so a task starts only if a workflow with a
  `jira_event` trigger on that connection picks the issue up. Use the `workflow`
  target for scheduled work that needs no Jira issue.
* A repository removed from the GitHub App installation after a schedule was saved
  stays on the schedule; each `olyros` run that mounts it fails with a "no longer
  granted" error until the repository is granted again or edited out.
* `queue_one` is defined in terms of cloud tasks (one task waits in `created` state behind the active run); the overlap check for `workflow` targets looks at executions, and no equivalent queue exists for them.
* There is no per-schedule notification; failures surface on the detail page and, for
  the `olyros` target, on the task.
* Fields `duplicate_tracking_method` and `duplicate_tracking_field` exist on the model
  and are not exposed or used.

## Customer-safe summary

Schedules let you run recurring work without anyone pressing a button. Choose how often
(hourly, daily, weekly, monthly, or a custom cron expression in your timezone) and what
should happen each time: give a task to one of your agents, start a workflow with preset
inputs, open a GitHub or Jira issue, or queue a job for one of your connected machines.
If the previous run is still going, the next one is skipped or queued, whichever you
prefer, and a schedule that keeps failing pauses itself so you can look at it. Every run
is listed with its result and cost.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.