Skip to content

Glossary

A short reference for the vocabulary RunWisp uses across the TOML schema, Web UI, TUI, CLI, and REST API. Most entries link to a deeper page; if a word feels overloaded, this is the place to settle which meaning the docs use.

A unit of work that runs and exits. Defined under [tasks.NAME] in runwisp.toml. May fire on a cron schedule, manually via the API / TUI / Web UI, or both. A task has retries, a timeout, log retention, and notification settings — everything except a “this thing should always be alive” supervisor. See [tasks.*] reference and Tasks vs Services.

A unit of work the supervisor keeps alive: when its process exits (clean or crash), the supervisor starts it again. Defined under [services.NAME]. The supervisor maintains instances replicas at all times and restarts each one with exponential backoff (capped at 60 seconds) when its process exits. Services do not have retries, timeouts, cron schedules, or catch_up — those are task concepts. See [services.*] reference.

One observable execution. Whether it succeeded, failed, was killed by a timeout, was stopped manually, or was reconciled as crashed — it’s a single row in runs with a unique ULID, a start timestamp, an end timestamp (once it ended), an exit code, and a captured log. Both tasks and services produce runs, one per replica per restart.

A retried task creates a new run for each attempt (linked back via retry_of_run_id and retry_attempt). Services do the same per restart — each replica’s lifetime is one run.

runwisp exec <task> runs a task in-process from the CLI — it loads runwisp.toml, opens SQLite directly, and streams output to your terminal. It refuses if a daemon is already attached to the same data dir. Its sibling, runwisp run-task <task>, asks a running daemon to trigger the task via the REST API instead. The TOML schema and REST API both prefer run as the executed-instance noun; treat “exec” as the verb and “run” as the persistent record.

  • Schedule — the cron expression in a task’s cron field. The scheduler fires the task on this rhythm.
  • Trigger — anything that fires the task outside its schedule: runwisp exec, the Web UI’s “Run Now” button, the TUI’s r key, or POST /api/tasks/{name}/trigger. The run record’s triggered_by field distinguishes them: cron vs api.

A task with api_trigger = false can only fire on its cron — manual triggers are rejected.

What the scheduler does about missed cron firings on startup, after a clock jump, or after a long sleep. Three policies, set per task via catch_up:

  • latest (default) — fire once for the most recent missed slot, drop the rest.
  • all — fire every missed slot, in order. Use cautiously for expensive tasks.
  • skip — fire nothing; wait for the next future tick.

See How scheduling works.

Each task has a parallelism and an on_overlap policy that decide what happens when a new firing arrives while previous runs are still in flight:

  • queue (default for tasks) — wait for a slot to free.
  • skip (default for services) — drop the new firing.
  • terminate — kill the oldest running replica to make room.

See Concurrency policies.

Every ended run carries an end_reason — the canonical “what happened” label:

ReasonMeaning
successProcess exited 0.
failedProcess exited non-zero.
timeoutThe daemon killed it after timeout elapsed.
stoppedCancelled by an operator (TUI / Web UI / API) or by on_overlap = "terminate".
crashedDaemon was killed mid-run; reconciled on next start. Exit code -2.
skippedon_overlap = "skip" rejected the firing because a previous run was still in-flight.
log_overflowlog_on_full = "kill_task" cancelled the run after output exceeded log_max_size.

success, stopped, and skipped do not trigger retries — and skipped does not trigger notify_on_failure either. Everything else (including log_overflow) does. See Retries & timeouts.

A run that has started and not yet ended. Its row carries status = "running", start_at is set, end_at is null. If the daemon dies in this state, the run becomes crashed on the next boot.

A configured outbound channel — Slack webhook, Telegram bot. Declared as [[notifier]] in runwisp.toml with an id other parts of the config refer to. The in-app surface ("inapp") is a built-in pseudo-notifier that’s always available and never declared. See [[notifier]] reference.

A [[notification_route]] block — a rule that says “events matching this filter go to these notifiers.” A failure can match multiple routes; the union of their notifier lists is delivered (deduplicated). See [[notification_route]] reference.

The notifications surface inside the daemon — a bell in the Web UI and a footer line in the TUI. Always-on by default because [notify] default_notifiers defaults to ["inapp"]. Set it to [] to silence the bell, or to a list of declared notifier IDs to redirect the catch-all elsewhere. The contents of default_notifiers are appended (deduped) to per-task notify_on_failure / notify_on_success. See Notifications model.

A short, deterministic, human-readable string identifying this daemon instance. Computed from the host’s machine-id and the daemon’s working directory. Persisted in SQLite on first boot and reused thereafter. Override via RUNWISP_FINGERPRINT. Used as a tag on outbound notifications so a fleet of identical daemons remain distinguishable.

Everything RunWisp persists, under whatever path --data points at (default data/). Holds SQLite, the password file, the PID file, and the per-task log tree. See Operations: data directory.

Challenge-response login. The client fetches a nonce, returns SHA256(password + ":" + nonce), and gets a JWT. The password never appears on the wire — important when RunWisp runs behind a plain-HTTP reverse-proxy hop. See Auth.

The session token issued after a successful CHAP login. HS256, 24-hour lifetime, signed with a per-daemon secret stored in SQLite. Presented either as Authorization: Bearer … or as the runwisp_jwt cookie.

The notifications subsystem groups repeat in-app rows by dedup key (task name + event kind + end reason) within a coalesce_window (default 1h). A flapping task that fails 60 times shows up as one row with count = 60 and an occurrence_ring of recent timestamps, rather than 60 separate rows. The dedup key is unrelated to the daemon Fingerprint above — they’re separate concepts that happen to share the English word.

One process slot of a service. A service with instances = 3 runs three replicas, each with its own replica_index (0, 1, 2). The supervisor restarts replicas independently. Run records carry the index; the TUI and Web UI show task names with a #N suffix when the replica index is non-zero.

The instances = N field on a service tells the supervisor how many replicas to keep alive. Tasks don’t have instances. See Replica for the per-process lifecycle and the [services.*] reference for the field.

The group = field on a task or service. Pure UI organization — the sidebar in the TUI and Web UI buckets entries by group, and the run filters reuse those buckets. Tasks and services without a group = land in an “Ungrouped” bucket. Groups have no scheduling, concurrency, or permission semantics; they’re cosmetic.

How a task’s log file is sized and rotated, controlled by two TOML fields. log_max_size caps the per-run log file (e.g. "10MB"). log_on_full chooses what happens when the cap is reached: "drop_old" rotates the file and keeps the run going (the default); "drop_new" stops accepting new lines but lets the run finish; and "kill_task" terminates the run. Both fields have per-task overrides; defaults live under [defaults]. See [tasks.*] reference.

Every persistent identifier in RunWisp — run id, notification id — is a ULID. Lexicographically sortable, monotonic within a millisecond, 26 characters. The Web UI and TUI usually display the last four characters as a shorthand suffix.