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.
Service
Section titled “Service”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.
Trigger vs schedule
Section titled “Trigger vs schedule”- Schedule — the cron expression in a task’s
cronfield. 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’srkey, orPOST /api/tasks/{name}/trigger. The run record’striggered_byfield distinguishes them:cronvsapi.
A task with api_trigger = false can only fire on its cron — manual
triggers are rejected.
Catchup
Section titled “Catchup”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.
Concurrency policies
Section titled “Concurrency policies”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.
End reasons
Section titled “End reasons”Every ended run carries an end_reason — the canonical “what happened”
label:
| Reason | Meaning |
|---|---|
success | Process exited 0. |
failed | Process exited non-zero. |
timeout | The daemon killed it after timeout elapsed. |
stopped | Cancelled by an operator (TUI / Web UI / API) or by on_overlap = "terminate". |
crashed | Daemon was killed mid-run; reconciled on next start. Exit code -2. |
skipped | on_overlap = "skip" rejected the firing because a previous run was still in-flight. |
log_overflow | log_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.
In-flight
Section titled “In-flight”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.
Notifier
Section titled “Notifier”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.
In-app
Section titled “In-app”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.
Fingerprint
Section titled “Fingerprint”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.
Data directory
Section titled “Data directory”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.
Coalescing
Section titled “Coalescing”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.
Replica
Section titled “Replica”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.
Instances
Section titled “Instances”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.
Log retention
Section titled “Log retention”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.
Catch-all: ULID
Section titled “Catch-all: ULID”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.
Where to next
Section titled “Where to next”- Concepts: Tasks vs Services — picking the right one.
- Configuration overview — the schema map.
- CLI reference — every subcommand and flag.