Functional Weave
Code in Rust

monitor.maintenance-window

The scheduled maintenance window in force at a moment, if any, so alerts and uptime can be suppressed during it.

1.0.0 · published 2026-10-03 by charlie · Anterra

Pinned by 14 tests, run in TypeScript, Python and Rust.

What it does

Which scheduled maintenance window, if any, is in force at a moment. A monitoring app asks this before paging someone or counting a check as downtime, and a status page uses it to say "Scheduled maintenance".

## Decisions

For example

  • active_maintenance(, 1,000) → — no windows, nothing active
  • active_maintenance(windows ×1, 2,000) → name db upgrade, start 1,000, end 4,600 inside the only window
  • active_maintenance(windows ×1, 1,000) → name db upgrade, start 1,000, end 4,600 the start second is inside

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.

pub fn active_maintenance(windows: &[MaintenanceWindow], at: i64) -> Option<MaintenanceWindow>
windowsMaintenanceWindow[]the scheduled windows, in any order; each must end after it starts
atintthe moment to check, Unix seconds
returnsMaintenanceWindow?the active window that started first; null when none is active

The type it declares, generated into your project

/// A scheduled period when a target is expected to be down.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MaintenanceWindow {
    pub name: String,
    /// Unix seconds, the first second included
    pub start: i64,
    /// Unix seconds, the first second excluded
    pub end: i64,
}

Your code names it in one line, in the file that uses it

fune!(monitor.maintenance-window@^1);  // then call active_maintenance(…)
impl/rust.rs · 60 lines · open · raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

use super::funejson::Value;  ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one

/// The window with start <= at < end. Half-open, so a window ending at 02:00
/// and the next starting at 02:00 never both apply. When several overlap, the
/// one that started first wins (ties: the first in the list), so the answer
/// does not depend on how the caller sorted them. Every window is checked,
/// not only the active ones: a backwards window is a config error that would
/// otherwise silently never apply.
///
/// # Panics
/// Panics on a window that does not end after it starts.
pub fn active_maintenance(windows: &[MaintenanceWindow], at: i64) -> Option<MaintenanceWindow> {
    let mut best: Option<&MaintenanceWindow> = None;
    for w in windows {
        if w.end <= w.start {
            panic!(
                "maintenance window \"{}\" must end after it starts: start {}, end {}",
                w.name, w.start, w.end
            );
        }
        if w.start <= at && at < w.end && best.map_or(true, |b| w.start < b.start) {
            best = Some(w);
        }
    }
    best.map(|b| MaintenanceWindow { name: b.name.clone(), start: b.start, end: b.end })
}

/// A `MaintenanceWindow` from its JSON form, for adapters of capabilities built on this one.
pub fn maintenance_window_from_value(v: &Value) -> MaintenanceWindow {
    MaintenanceWindow {
        name: v.get("name").as_str().to_string(),
        start: v.get("start").as_i64(),
        end: v.get("end").as_i64(),
    }
}

pub fn maintenance_windows_from_value(v: &Value) -> Vec<MaintenanceWindow> {
    v.as_arr().iter().map(maintenance_window_from_value).collect()
}

pub fn maintenance_window_to_value(w: &MaintenanceWindow) -> Value {
    Value::obj(vec![
        ("name", Value::str(&w.name)),
        ("start", Value::Int(w.start)),
        ("end", Value::Int(w.end)),
    ])
}

pub fn fune_vector(args: &[Value]) -> Value {
    let windows = maintenance_windows_from_value(&args[0]);
    let at = match &args[1] {
        Value::Int(i) => *i,
        Value::Float(f) => panic!("at must be a whole second, received {}", f),
        _ => panic!("at must be a whole second"),
    };
    match active_maintenance(&windows, at) {
        Some(w) => maintenance_window_to_value(&w),
        None => Value::Null,
    }
}

Install

fune build

With that line in your source, in a Rust project (language rust in fune.project), fune build resolves it and nothing else, pins them in fune.lock, downloads only the Rust 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. A crate’s build.rs runs it before every compile. Or pin a range in fune.project and build in one step:

fune add monitor.maintenance-window
Download for Rust monitor.maintenance-window-1.0.0-rust.fune · 8,446 bytes sha256 dee8d313e61683c750a2cb5ed9288bcc886a94d5635621c97654ff610b7c6de8

The manifest, vectors and README with only the Rust implementation. Install it without the registry with fune add ./monitor.maintenance-window-1.0.0-rust.fune, or fetch it from a terminal with fune pull monitor.maintenance-window@1.0.0:rust.

The whole function, every language, is one file too: monitor.maintenance-window-1.0.0.fune, 10,867 bytes, sha256 2be593f1b02aa7c8f811132adb9151be5f7527287fc2fb9fb90100f77531e111. 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.maintenance-window

after — your function gets the result and the arguments, and returns the final result.

// fune: after monitor.maintenance-window

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.maintenance-window --steps.

// fune: step monitor.maintenance-window 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.

CaseArgumentsExpected
no windows, nothing active , 1,000 → —
inside the only window windows ×1, 2,000 → name db upgrade, start 1,000, end 4,600
the start second is inside windows ×1, 1,000 → name db upgrade, start 1,000, end 4,600
the end second is outside windows ×1, 4,600 → —
the last second before the end is inside windows ×1, 4,599 → name db upgrade, start 1,000, end 4,600
before the window starts windows ×1, 999 → —
back-to-back windows: at the boundary only the later one applies windows ×2, 3,600 → name second, start 3,600, end 7,200
overlapping: the one that started first wins even when listed second windows ×2, 3,000 → name network, start 1,000, end 9,000
same start: the first in the list wins windows ×2, 1,500 → name a, start 1,000, end 2,000
only the window containing the moment counts, not the earliest one windows ×2, 600 → name now, start 500, end 900
Show the other 4 tests
CaseArgumentsExpected
times before 1970 work windows ×1, -5,000 → name old, start -7,200, end -3,600
a window that ends when it starts is an error windows ×1, 50 → error: maintenance window "empty" must end after it starts: start 1000, end 1000
a backwards window is an error even when not active windows ×2, 50 → error: maintenance window "typo" must end after it starts: start 9000, end 8000
a fractional moment is an error , 1.5 → error: at must be a whole second, received 1.5

More from the author

- **Half-open**: a window covers `start <= at < end`. A window ending at 02:00 and the next starting at 02:00 never both apply, and the end second itself is outside. - **Overlaps**: when several windows are active, the one that **started first** is returned (on a tie, the first in the list). The answer then does not depend on how the caller sorted the list, and the name shown is the maintenance that caused the outage in the first place. - **Every window is checked**, not only the active one: a window that does not end after it starts is a typo that would silently never apply, so it is an error wherever it sits in the list. - Returns `null` when nothing is active; returns a copy, never the caller's object.

## Errors

- `maintenance window "NAME" must end after it starts: start S, end E` - `at must be a whole second, received X`

Files

PathBytes
README.md1,110
impl/python.py1,191
impl/rust.rs2,246
impl/typescript.ts1,140
vectors.json2,581