Schedule a routine
A routine is a task the box starts on its own, on a timer. In this guide you write a small app with a schedule trigger, install it on the box, and check that it starts tasks. The schedule re-arms every time the box starts, so it survives restarts and power cuts.
Before you start
Section titled “Before you start”- A box installed on Ubuntu from a source checkout. See Install on Ubuntu. On a box installed from the ISO, apps ship inside the system image, so a new app reaches it as a system update.
- A
FACTORY_API_KEYin the vault, because scheduled tasks run Droid with Claude by default. See Add a secret. - Basic TypeScript.
-
Make the app's folder in your checkout. The folder name is the app's name.
mkdir -p tracks/nightly -
Write
tracks/nightly/track.ts. This app starts one task every day at 02:00, box local time.import type { Track } from '../../core/contract.ts';import { schedule } from '../../core/triggers.ts';export default {name: 'nightly',triggers: [schedule({name: 'report',dailyAt: '02:00',task: () => ({title: 'Nightly notes report',prompt: 'Read notes/ and write report.md: what changed since yesterday, in five bullet points.',workspace: 'home',hosts: [],budgetCents: 25,source: 'schedule',}),}),],} satisfies Track;dailyAt: 'HH:MM'fires once a day at that time. UseeveryMsinstead for a fixed interval, for exampleeveryMs: 15 * 60_000for every 15 minutes.task()returns a task spec. Return nothing to skip a run, for example when there is no new work.hosts: []means the task has no network beyond Claude. Add only the hosts the routine needs. See Network policy.budgetCentscaps tool spending before the task asks for your OK.
-
Install the checkout on the box. The install script copies it to
/opt/boxand restarts the service, which loads every app at boot.sudo core/install.sh
Check it worked
Section titled “Check it worked”-
Look for the app in the service's startup line:
journalctl -u box.service -n 20 | grep 'box up'box up: 12 tasks in the log, tracks: example, nightly, walletIf the app failed to load, the journal has
track nightly not loaded:and the reason. A broken app never stops the box. -
To see a task without waiting until 02:00, set
everyMs: 60_000for a test run, install again, and wait a minute. Then list tasks:curl -s http://127.0.0.1:7700/api/tasks | grep -o '"title":"Nightly notes report"[^}]*'Change the schedule back when you are done.
Limits
Section titled “Limits”- A run that falls while the box is off is skipped, not caught up.
dailyAtarms the next occurrence after each start. everyMscounts from when the box started, not from a fixed clock time.dailyAtuses the box's local time zone.- Schedules live in app code. A screen for creating routines in the portal is not built.
Related
Section titled “Related”GurtOS is open source under the Apache License 2.0.Source code on GitHub.