Skip to content

LiveSept 8 — 12, 2026 · 31 commits

Fleet Sentinel

A platform that watches a whole fleet of WordPress sites — so people don't have to.

Fleet Sentinel monitors a fleet of WordPress sites. It tracks uptime, security vulnerabilities, pending plugin and theme updates and agent health, and sends alerts to Google Chat.

passing Vitest tests
482
PHP checks across 6 suites
142
recorded design decisions
69
commits in 5 days
31
SQL migrations
15
classified failure types
14
Vercel cron jobs
7
site load simulation
500

Architecture

Four parts, one protocol.

My role: Product owner & developer — I set the requirements, reviewed and tested the work, and deployed it, with Claude Code as my AI pair programmer.

  • apps/panel

    The Next.js 15 admin panel.

  • apps/wp-plugin

    The WordPress agent plugin — plain PHP, v1.2.0, 10 classes.

  • apps/checker

    A standalone health-check bot.

  • packages/protocol

    The shared signing and encryption library.

  • Next.js 15
  • React 19
  • TypeScript
  • Tailwind
  • Drizzle ORM
  • Neon Postgres
  • Auth.js v5
  • Zod
  • Recharts
  • TanStack Table
  • sharp
  • PHP
  • Vercel Cron

Product

Everything a fleet owner needs, on one panel

Fleet dashboard

  • Sites at risk, critical CVEs, pending updates, sites down and silent agents.
  • Uptime and severity trend charts, and a prioritized “needs attention” list.

Site directory & detail

  • Search, status filter, pagination, bulk actions, expandable rows, mute alerts, sync now, and add/delete with pairing keys.
  • Tabs for Overview, Plugins & Themes, Findings, Admins, Server & PHP, Uptime & Logs, and Wire & Pairing.
  • Notes and an audit trail of who changed which plugin.

Vulnerabilities

  • Ingests the Wordfence Intelligence v3 feed (free or Pro key), streaming a catalog of over 117 MB.
  • Matches it against every installed plugin and theme.
  • A rate-limit gate, error diagnosis, and key testing with auto-save.

Updates & findings

  • Pending plugin/theme updates grouped across the fleet, labelled correctly.
  • Automatic findings: vulnerabilities, updates, core updates, PHP end-of-life, TLS expiry, site down, agent lost.
  • Custom findings with resolve and reopen; resolved findings are hidden from the open list.

Uptime monitoring

  • A built-in prober with escalating checks and a down/recovered state machine.
  • Incidents with durations and daily uptime rollups.
  • UptimeRobot and BetterStack integrations with an inbound webhook.

Google Chat notifications

  • Multiple Chat spaces with per-site or fleet-wide routing rules.
  • Event types and minimum severity per rule, quiet hours and a delivery log.
  • Test alerts, previews, rich cards titled with the site's name, and a daily digest.

Multi-tenant fleets

  • Fleets are separate tenants with per-fleet membership and roles; access can be restricted to chosen sites.
  • A fleet switcher that stays in sync across browser tabs.
  • Hardened fleet icon upload: content-sniffed type check, no SVG, decompression-bomb protection, re-encoded to WebP up to 512×512.

Access control & settings

  • Viewer, editor, admin and superuser roles, each with a set of permissions.
  • Invites restricted by email domain, role changes, suspension and removal.
  • Encrypted API keys (AES-256-GCM), uptime provider selection, probe timing and job controls.

Background jobs

  • Health dispatch and inventory polling every minute.
  • Vulnerability evaluation every 15 minutes and a wordpress.org refresh every 6 hours.
  • Wordfence ingest, digest and database cleanup daily — plus an external checker bot and a public status endpoint.

Developer tooling

  • A local-only sign-in-as-any-user tool: gitignored, excluded from deploys, localhost-only, with a warning banner.
  • A 500-site load simulation.

Reliability

Agent connectivity, redesigned from research

Shared hosting is unreliable, so the panel was redesigned to pull data from sites instead of waiting for heartbeats.

Transport

  • The panel tries several transports in turn — a signed RPC endpoint, then admin-ajax, then REST variants — and remembers which one works.
  • Every request is signed with HMAC-SHA256, with clock-skew correction and jittered retries.
  • Cache-busting headers and fingerprint-based cache invalidation in the plugin.

Failure detection

  • Failures are sorted into 14 types (blocked, timeout, TLS, clock skew and more).
  • A φ accrual failure detector (Hayashibara et al.) decides when an agent is unreachable.
  • If most sites fail at once, the panel assumes its own network is the problem and holds alerts.

Signals

  • Instant change notices (“nudges”) from the agent.
  • A goodbye notice when the plugin is deactivated.
  • An “Agent reconnected” all-clear.

Security

Hardened at every boundary

Request authenticity

  • HMAC-signed requests with nonce replay protection and rate limits.

Secrets

  • Secrets encrypted at rest; CRON_SECRET is never sent to the browser.
  • The uptime webhook secret is superuser-only, compared in constant time, rejects published defaults and fails closed when unset.

Tenancy & roles

  • Every tenant query is scoped to its fleet, and audit logs are scoped per fleet.
  • Platform-wide actions and log deletion are superuser-only, so fleet admins can't erase the audit trail.

Uploads & tooling

  • Image uploads are validated, re-encoded and served with nosniff and a sandbox CSP.
  • The impersonation tool is guarded, and a test fails if it is ever committed to git.

Quality

Tested like it matters

Automated

  • 482 passing Vitest unit and component tests across 46 files, plus 13 opt-in end-to-end tests.
  • Cross-language end-to-end tests run the real PHP plugin against the TypeScript panel.
  • 142 PHP checks across 6 suites; the plugin lints clean; TypeScript and next build pass.

Manual QA

  • Every page tested as different users, and the API checked role by role.
  • That pass found and fixed 8 bugs, including 3 security issues.

Bugs fixed along the way

  • False “agent silent” alerts and missing recovery alerts.
  • Themes shown as plugins, and stale cached replies from the host.
  • A stuck progress bar, a stale fleet switcher and a Chat rule count that always showed 0.
  • Hard-coded agent version and TLS status on the site page.

DevOps

Shipped to production

Vercel

  • Monorepo deployed with a root vercel.json, cron configuration and maxDuration limits for the Hobby plan.
  • .vercelignore, environment separation and secrets kept out of git; Google OAuth redirects configured.

Data & plugin

  • Neon Postgres migrations applied in production through a migration script.
  • WordPress plugin packaged as a zip and upgraded on a live test site from 1.0.3 to 1.2.0.

Cost & integrations

  • Removed a scheduled GitHub Actions workflow that failed every run and would have burned billed minutes — Vercel Cron already handled it.
  • Google Chat webhook integration tested end to end.

Growth

Skills I sharpened.

Full-stack TypeScript
Next.js 15 App Router, React 19, server and client components, API route design.
Databases
PostgreSQL schema design, Drizzle ORM, migrations, SKIP LOCKED leasing, Neon serverless.
Auth
Auth.js, Google OAuth, JWT sessions, RBAC, multi-tenant isolation.
Security
HMAC signing, replay protection, AES-GCM, safe uploads, webhook hardening.
Distributed systems
φ accrual detection, pull vs. push, jittered retries, clock skew, caching.
WordPress & PHP
Plugin architecture, REST API, hooks and cron, signed endpoints, packaging.
Integrations
Google Chat, Wordfence Intelligence, UptimeRobot, BetterStack, wordpress.org.
Testing
Vitest, React Testing Library, cross-language E2E, PHP harnesses, role-based QA.
DevOps
Vercel deployment and cron, monorepo config, environments, production migrations.
Engineering practice
Research-led design, a decision log, documentation and AI-assisted development.