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/panelThe Next.js 15 admin panel.
apps/wp-pluginThe WordPress agent plugin — plain PHP, v1.2.0, 10 classes.
apps/checkerA standalone health-check bot.
packages/protocolThe 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.