RUGitHubInstall

Schedules — what runs on its own, and what happens when it fails

Iva runs its background work as in-process Eve schedules: one memory-night pipeline at 04:00, the half-hourly proactive tick (Watch, the Brief and Insight), the daily jobs-watchdog, and the reminder dispatcher that ticks every minute. Each scheduled job is a thin spawner — the work itself lives in scripts/ (see docs/deploy.md).

Every run leaves a fact

One row per run, in data/jobs.json (except the half-hourly proactive tick: it writes only a failure and the first success after it, so 48 rows a day do not crowd out the rest): name, started/finished time, ok, the reason of a failure, the exit code, and the tail of the run’s error output (last 20 lines of stderr, cut by the same rule the evidence package uses — the report a script prints to stdout stays out of the row and out of the agent’s turn). Rows older than seven days are dropped on the next write. data/rollup-status.json keeps only “in progress” and “last success” for the double-run guards — the history is jobs.json.

The agent wakes up with the fact

Right after a run, schedule-runner starts scripts/jobs/wake.ts <name> <startedAt> in the background. That child reads the row, opens an ordinary agent turn and:

Only a non-empty answer is sent, to the owner’s private chat (the first id of TELEGRAM_ALLOWED_USER_IDS: the button is accepted only there). In the quiet hours (23:00–08:00 by default) with Watch and Brief on, the answer is not sent at night: the failure stays open and comes first in the morning Brief. With Watch and Brief off, or with no Brief times, it is sent at once. The outcome of the turn (answered / empty / failed, plus a deferred mark for a failure that waits for the Brief) is written back into the same row.

Where to look

If something broke anyway

The raw run log is the service journal:

journalctl --user -u iva.service -n 200 --no-pager | grep schedule-runner
View original Markdown ↗