SIGHUP makes jaque compile the config file again, diff the result against the running object graph, and swap the new graph in atomically on the engine's own goroutine. Objects the diff calls unchanged are not touched: no reschedule, no reset of soft-state counters, no check storm. A config that fails validation is rejected and the previous one keeps running. Both outcomes are written to the event log as facts, so "what changed and when" survives in history rather than in a log line that scrolled past.

Status: the old version of this page named the rejection event ConfigRejected; the event the log carries is ConfigReloadRejected. Documented under the old name, verified under the new one. See project status.

1. Signal

kill -HUP $(pgrep jaque)

A SIGHUP that arrives while the previous reload is still loading is coalesced; reloads are applied one at a time, in order.

2. What a reload does, in order

The order is pinned, because each step depends on the one before it.

SIGHUP
  |
  v
compile the new config ----- fails ----> ConfigReloadRejected
  |                                       (old config keeps running)
  v
diff against the running graph: added / removed / changed / unchanged
  |
  v
append ConfigReloaded, then one ObjectRetired per removed object
  |
  v
swap the object graph, runners, policies, labels and topology
  |
  v
removed: cancel and forget     changed: cancel and re-arm
added: arm                     unchanged: nothing
  |
  v
recompute reachability; emit only for objects whose answer changed

Facts go to the log before the in-memory swap, the same rule every command follows: a crash between the two loses the in-memory update, never the fact. ConfigReloaded carries the four counts, which is what makes "a reload that changed nothing rescheduled nothing" readable from the log alone. Event sourcing is why this is the same mechanism as everything else in jaque and not a special case.

3. What needs no restart

Adding, removing or editing hosts and services. Changing check schedules, thresholds or flap settings. Adding or editing contacts, notification policies and escalations. Adding or editing labels and saved views. A changed object is cancelled and re-armed on its new schedule; its projected state, soft counters included, is not reset, because only removed objects have their state dropped.

4. A rejected reload

Bad CUE or a schema violation leaves the previous, still-valid config running and appends ConfigReloadRejected with the loader's own error text. A typo in a config edit cannot take down monitoring that was already working; it can only fail to change it, on the record.

5. A removed object

An object that disappears from the new config does not vanish from view: it is retired (ObjectRetired in the log), its scheduler entry is cancelled, and its projection, notification state and due time are dropped. The query API stops returning it, and history keeps the fact that it existed and when it was removed. This is how the projection and the history stay consistent with what is actually being checked.

6. Security considerations

Whoever can send SIGHUP to the process, or write the file -config names, can change what is monitored and who is notified. Both are controlled by the host's user and file permissions, not by jaque. The rejected-reload path never partially applies a config, so a truncated or half-written file cannot leave the engine running a mix of old and new.