Ege Bostancı

Quiet VPS Watchdog

Status: Retired (August 2026) · Source available on request

The server this watchdog guarded was shut down on 31 August 2026 as a deliberate downsizing: the site moved to Cloudflare Pages, ShiftScan to Render, the agent gateway to a workstation. Managed platforms bring their own health checks, so the watchdog’s job disappeared with the host. The page is kept as a record of the design, which would apply unchanged to the next server.

Problem

A personal server that ran n8n, an AI agent gateway, a static site, a feed reader and a handful of Coolify-managed containers needed watching. The usual failure mode of agent-driven monitoring is not missing incidents — it is noise: an LLM asked “is everything fine?” every few minutes will eventually say something, and an alert that repeats every cycle stops being read.

The goal was the opposite: a watchdog that produces nothing when the server is healthy, exactly one message when a problem appears, silence while that same problem persists, and exactly one message when it clears.

What it does

A single dependency-free Python script ran every five minutes from the agent’s scheduler. It checked:

Every finding becomes an Issue(severity, key, detail). The list is sorted, serialised and hashed; that hash is the run’s signature.

The quiet part

The script’s own output is the whole notification policy:

issues and signature changed   → print the issue list      (one alert)
issues and signature unchanged → print nothing             (no repeat)
no issues, previous run had    → print one recovery line   (one all-clear)
no issues, previous run clean  → print nothing             (silence)

The scheduler’s instruction to the agent was a single sentence: deliver stdout verbatim; empty stdout means healthy and must remain silent. The agent never decided whether something was wrong — it was a delivery channel for a deterministic result.

State is one small JSON file (signature, had_issues, issue_count, checked_at) written atomically through a temp file and os.replace, so a crash mid-write cannot corrupt the memory of the previous run. A --mode report flag prints a full human-readable readiness summary on demand, for when someone actually wants to see the numbers.

Design decisions

Part of a wider self-hosted agent setup

The watchdog was one piece of running an AI agent (Hermes) against real infrastructure with narrow permissions:

The same principle ran through both: the agent got a deterministic, bounded view of production, and anything that changed production stayed with a human.

Retrospective: what carried forward

Retiring a system is a result too. What this one proved, and what moved into later work:

Known limitations