monitor.check-status
Combine the statuses of one target's probes from several locations into one up, degraded or down, with a quorum.
1.0.0 · published 2026-10-03 by charlie · Anterra
Pinned by 13 tests, run in TypeScript, Python and Rust.
What it does
The shared vocabulary of the `monitor.*` capabilities, and the rule for combining probes of one target from several locations.
- `CheckStatus` is `up`, `degraded` or `down`: what one probe concluded. - `Check` is one probe outcome at a moment: `{ at, status }`, `at` in Unix seconds. `monitor.uptime`, `monitor.incidents`, `monitor.uptime-bars` and the others take lists of these, so a monitoring app stores exactly this.
For example
aggregateStatus(up, up, up, 2)→ up every location up is upaggregateStatus(up, down, up, 2)→ degraded one down below a quorum of two is degraded, not downaggregateStatus(down, up, down, 2)→ down two down meets a quorum of two
The function
The same function in TypeScript, Python and Rust, pinned by the same tests. Pick your language; the choice follows you around the registry.
export function aggregateStatus(statuses: readonly CheckStatus[], downQuorum: number): CheckStatus
| statuses | CheckStatus[] | the latest status from each probe location of one target, at least one |
| downQuorum | int | how many locations must say down before the target is down, 1 to the number of statuses |
| returns | CheckStatus |
The types it declares, generated into your project
export type CheckStatus = "up" | "degraded" | "down";
/** One probe outcome at a moment, the unit every monitor.* series is made of. */
export interface Check {
/** Unix seconds when the probe ran */
readonly at: number;
readonly status: CheckStatus;
}
Your code names it in one line, in the file that uses it
import { aggregateStatus } from "#fune/monitor.check-status@^1";
import { type CheckStatus } from "./monitor_check_status_types.ts";
/**
* One status for a target probed from several places. Down needs a quorum,
* so one location with a broken route cannot page anyone; a down vote below
* the quorum still counts as degraded, because something is wrong somewhere.
*/
export function aggregateStatus(statuses: readonly CheckStatus[], downQuorum: number): CheckStatus {
if (statuses.length === 0) throw new RangeError("statuses must not be empty");
if (!Number.isSafeInteger(downQuorum) || downQuorum < 1 || downQuorum > statuses.length) {
throw new RangeError(`downQuorum must be 1 to ${statuses.length}, received ${downQuorum}`);
}
let down = 0;
let degraded = 0;
for (const s of statuses) {
if (s === "down") down += 1;
else if (s === "degraded") degraded += 1;
else if (s !== "up") throw new RangeError(`unknown check status: ${String(s)}`);
}
if (down >= downQuorum) return "down";
return down > 0 || degraded > 0 ? "degraded" : "up";
}Install
fune build
With that line in your source, in a TypeScript project (language typescript in fune.project), fune build resolves it and nothing else, pins them in fune.lock, downloads only the TypeScript package of each, and builds the code above into your project’s .fune/build, one readable file per capability with a header linking back here. Or pin a range in fune.project and build in one step:
fune add monitor.check-status
The manifest, vectors and README with only the TypeScript implementation. Install it without the registry with fune add ./monitor.check-status-1.0.0-typescript.fune, or fetch it from a terminal with fune pull monitor.check-status@1.0.0:typescript.
The whole function, every language, is one file too: monitor.check-status-1.0.0.fune, 9,013 bytes, sha256 be76e5bc993feafeee52850214d86b9e76091db0f91f029ed87fadc0576185ff. It installs into a project of any language.
Customise it in your app
The seams this capability offers. Put a marker directly above a function of your own and fune build wires it into the built code; the package on the registry is not changed, the built file’s header lists it under CUSTOMISED, and fune hooks lists every hook in the project. How hooks work.
before — your function gets the arguments and returns them, changed or not, or throws to refuse the call.
// fune: before monitor.check-status
after — your function gets the result and the arguments, and returns the final result.
// fune: after monitor.check-status
replace — it requires no other capability, so there is no dependency to replace.
step — your function runs at a numbered point inside the function’s body, receives the in-scope values it names as parameters, and may return replacements. List the points with fune show monitor.check-status --steps.
// fune: step monitor.check-status after <n|label>
Tests
A version published now needs at least 8 tests for every function, and one that expects the error for each function that throws; the registry refuses it otherwise. fune verify --all runs each case in TypeScript, Python and Rust, and a project runs them again with fune verify. This page lists the cases; it does not run them. The exact JSON is vectors.json.
| Case | Arguments | Expected | |
|---|---|---|---|
| every location up is up | up, up, up, 2 | → | up |
| one down below a quorum of two is degraded, not down | up, down, up, 2 | → | degraded |
| two down meets a quorum of two | down, up, down, 2 | → | down |
| a quorum of one: any down location is down | up, down, 1 | → | down |
| a single location with a quorum of one decides alone | down, 1 | → | down |
| a slow location alone makes the target degraded | up, degraded, up, 2 | → | degraded |
| degraded votes never add up to down | degraded, degraded, degraded, 1 | → | degraded |
| quorum equal to the number of locations needs all of them down | down, down, degraded, 3 | → | degraded |
| all down with a unanimous quorum is down | down, down, down, 3 | → | down |
| an empty list is an error | , 1 | → | error: statuses must not be empty |
Show the other 3 tests
| Case | Arguments | Expected | |
|---|---|---|---|
| a quorum of zero is an error | up, 0 | → | error: downQuorum must be 1 to 1, received 0 |
| a quorum larger than the locations can never be met | up, down, 3 | → | error: downQuorum must be 1 to 2, received 3 |
| an unknown status is an error | up, offline, 1 | → | error: unknown check status: offline |
More from the author
## aggregateStatus
Monitoring services confirm an outage from more than one location before alerting, because a single probe location with a bad route is far more common than a real outage. The rule, in order:
1. At least `downQuorum` statuses are `down`: **down**. 2. Any `down` (below the quorum) or any `degraded`: **degraded**. Something is wrong somewhere, but not enough to call it an outage. 3. Otherwise **up**.
Degraded votes never add up to down, however many there are: a slow site is still serving.
## Errors
- `statuses must not be empty` - `downQuorum must be 1 to N` where N is the number of statuses: a quorum that can never be met would hide every outage. - `unknown check status: X`
Files
| Path | Bytes |
|---|---|
| README.md | 1,163 |
| impl/python.py | 1,073 |
| impl/rust.rs | 1,775 |
| impl/typescript.ts | 1,015 |
| vectors.json | 1,536 |