# Расписания - что запускается само и что происходит при сбое

Фоновая работа идёт расписаниями eve: единая ночь памяти `memory-night` в 04:00,
получасовой тик `proactive` (Watch, Brief и Insight), дневной
`jobs-watchdog` и минутный диспетчер напоминаний. Каждое расписание - тонкий
спавнер, работа живёт в `scripts/` (см. `docs/deploy.md`).

## Каждый запуск оставляет факт

Одна строка на запуск в `data/jobs.json` (кроме получасового тика `proactive`: он пишет
только провал и первый успех после него, чтобы 48 строк в сутки не вытесняли остальные):
имя, время старта и финиша, ok, причина
провала, код выхода и хвост ошибок запуска (последние 20 строк `stderr`; режет то же
правило, что пакет улик, — отчёт, который скрипт печатает в `stdout`, в строку и в ход
агента не попадает). Строки старше семи дней удаляются при следующей
записи. `data/rollup-status.json` хранит только «идёт сейчас» и «последний успех»
для гвардов двойного запуска - история в `jobs.json`.

## Агент просыпается с фактом

Сразу после запуска `schedule-runner` в фоне стартует `scripts/jobs/wake.ts <name>
<startedAt>`. Ребёнок читает строку, открывает обычный ход агента и:

- на успехе ход говорит «всё в порядке - ответь пустым», и пустой ответ ничего не
  отправляет;
- на провале агент разбирает причину, коротко говорит владельцу, что сломалось и
  почему, и заканчивает кнопкой «Починить». Пока владелец её не нажал, он ничего не
  чинит.

Владельцу уходит только непустой ответ, в его личный чат (первый id
`TELEGRAM_ALLOWED_USER_IDS`: тап кнопки принимается только там). В тихие часы
(по умолчанию 23:00–08:00) при включённых Watch и Brief ответ ночью не шлётся:
провал остаётся открытым и встаёт первым в утреннем Brief. Если Watch и Brief
выключены или время Brief не задано, ответ уходит сразу. Исход хода (ответил /
ответил пустым / провалился, плюс отметка `deferred` у провала, который ждёт Brief)
приписывается той же строке.

## Куда смотреть

- `iva doctor` → раздел расписаний: последний запуск каждого имени (ок или провал,
  когда; у `proactive` последний успех берётся из `data/rollup-status.json`) и
  незакрытые провалы. Пульс минутного диспетчера та же команда говорит в разделе
  напоминаний.
- Каждый ход агента несёт короткий блок «незакрытые провалы», поэтому сломанное
  расписание агент видит раньше вашего вопроса. Провал расписания остаётся там и в
  утреннем Brief, пока его не закроет более поздний успех или `iva jobs ack`.
- `iva jobs ack <name>` закрывает провал, который вы решили не чинить. Более
  поздний успешный запуск закрывает его сам.
- Если агент не может проснуться вообще, раз в сутки владельцу уходит одно
  сообщение: «за сутки провалов расписаний: N; агент не отвечает; iva doctor».
  Нечитаемая таблица — тот же случай со своей причиной: с фактом, который не
  читается, агент проснуться не может. `data/jobs-watchdog.json` помнит последнюю
  отправку.

## Если всё-таки сломалось

Сырой журнал запуска - журнал сервиса:

```bash
journalctl --user -u iva.service -n 200 --no-pager | grep schedule-runner
```
