> Section: [6. Ingest](https://jaque.sh/docs/ingest/passive-checks.md)
> Next: ingest/fifo-and-api
> Index: https://jaque.sh/llms.txt


Not everything worth monitoring can be polled: an SNMP trap, a batch job
that alone knows its own outcome, an external system pushing results in.
A `passive` check is an object whose state comes from outside, not from
jaque running a probe. The contract has one non-negotiable clause: the
operator names a `freshness_threshold`, so that when results stop arriving
jaque has an opinion about it. An unbounded freshness window is the
silent-green failure this check type exists to prevent, and the schema
refuses to default it.

## 1. Declaring one

```cue
services: backup: check: {
	type:                "passive"
	freshness_threshold: "24h"
	stale_status:        "CRITICAL"
}
```

`freshness_threshold` is required and has no default; a passive check
without one is a concretion error at load. `stale_status` is the status
the object is forced to once a result is older than the threshold:
`UNKNOWN` by default, because that is the honest reading (jaque does not
know, rather than knows something is broken), or `WARNING` or `CRITICAL`
if the operator prefers. It cannot be `OK`: staleness never means
"everything is fine".

## 2. When results stop arriving

A fresh result reschedules the object's next evaluation at the moment it
would go stale. If nothing arrives by then, the engine synthesizes a
result carrying `stale_status` and the object walks the same soft-to-hard
ladder an active check would: `max_attempts` and `retry_interval` govern
the steps, `check_interval` is how often staleness is re-evaluated once
hard, and `flap` behaves as it does anywhere else. A dead sender keeps
re-alerting on that cadence rather than jumping straight to hard.
`timeout` is the one `#Schedule` field with no meaning for a passive
check.

## 3. Feeding results in

Two doors, one destination; [FIFO and API](https://jaque.sh/docs/ingest/fifo-and-api.md) has
the wire detail of each.

The Nagios-compatible FIFO accepts `PROCESS_SERVICE_CHECK_RESULT` and
`PROCESS_HOST_CHECK_RESULT` lines, for anything that already speaks the
legacy external-command format.

The ConnectRPC API's `ProcessCheckResult` and `ProcessCheckResults`
(batch) RPCs are the fit for a translator receiving bursts: the batch
call validates all-or-nothing and enqueues in order.

Both land on the same command channel the engine consumes, tagged
`origin: passive`. A result for an object not declared `passive` is
logged as a warning and discarded, never applied; a result for an object
owned by another engine is forwarded to it. [SNMP
traps](../ingest/snmp-traps.md) is the reference pipeline that turns a
trap flood into passive results without forking a process per trap.

## 4. Security considerations

A passive result is an assertion about an object's state made by whoever
can reach the FIFO or the API. The FIFO trusts anyone who can write the
file; the API trusts anyone who presents `-api-token`, or anyone at all
when no token is configured. The `passive` declaration is the only
per-object guard: an active object cannot be overwritten from outside,
whatever the sender claims.
