Skip to content

Triggers

What can start a watch run Four triggers exist: a scheduled CI job running the command-line executor, the in-process scheduler of the always-on service, a run-now request for a single watch, and a run-all request. All four converge on the same execute-watch path, which applies a per-watch lock and records a run. 1 · Scheduled CI job hourly cron → run-due 2 · In-process scheduler service tick, overlap-guarded 3 · Run now one watch, ignores schedule 4 · Run all one per owner at a time Execute watch per-watch lock records every run Due-filtering applies to 1 and 2 only The processing loop collect → decide → notify There is no webhook, queue, database trigger or file watcher. Watcher only ever polls.
Every trigger converges on the same per-watch execution path.
# Trigger Scope Respects the schedule?
1 Scheduled CI job running the CLI executor every owner’s watches Yes, unless run with --force
2 In-process scheduler in the always-on service every owner’s watches Yes
3 Run now on one watch one watch you own No
4 Run all your enabled watches No

The shipped workflow runs hourly in UTC and can also be started by hand with a force toggle. Each run loads all watches, skips the ones that are not due, and processes the rest.

Two properties worth knowing:

  • Runs do not overlap. The workflow is configured so a slow run does not have a second one started on top of it.
  • --force ignores due-filtering but not anything else — deduplication and the decision gate still apply, so forcing a run does not produce duplicate alerts.

pnpm serve starts a scheduler inside the API process, defaulting to every five minutes (SCHEDULER_CRON). A tick that is still running when the next one is due is skipped, not queued, so a slow tick cannot pile up.

Set SCHEDULER_ENABLED=false when something else already owns the schedule.

POST /watches/:id/run, or the button in the panel and the app. It ignores the cron schedule entirely and returns the outcome synchronously, which makes it the fastest way to test a watch you just edited.

POST /watches/run-all runs every enabled watch you own immediately, sharing the scheduler’s semantics (sequential by default, per-watch locking). Only one run-all per owner may be in flight; a second returns 409 rather than queueing a second full pass behind the first.

Within one process, two runs of the same watch are serialised by a per-watch lock, so pressing “Run now” during a scheduler tick is safe.

That lock is in-process only. Two separate processes — a CI job and an always-on service sharing a database — can genuinely overlap. Deduplication makes the result harmless in practice, but it wastes quota; see the warning in Deploy your own instance.

Whatever starts a run, the same loop executes and the same gates apply. There is no “manual runs skip deduplication” mode, and no trigger can force an alert.