Reliability

51 automated systems were green. Nine were broken. How I switched from monitoring activity to monitoring output

I replaced 'did the job run' monitoring with 'did the job produce its output' monitoring across all 51 scheduled systems I run. Every system had been green. A deep audit against the real destinations showed nine had been broken for weeks, including a client-facing news feed that had been re-sending duplicates for four months. One outcome assertion per system, checked after every run and again in a daily audit, caught all nine on day one. All nine were fixed the same day.

Headline result
9 silent failures caught
Client
My own automation estate
My role
Designed and built it
Scope
51 scheduled systems across a cloud server, n8n and Supabase
When
September 2026

The problem

Every one of my 51 scheduled systems had a health check and every check was green. Then I audited each one against the place its output was supposed to land. Nine had been broken for weeks. Green heartbeat, no output.

The worst one was client-facing. A news digest had been re-sending the same articles for four months because two errors were swallowed by empty catch blocks, so its dedup table was never written. The client's sheet held 408 duplicate rows out of 1,438.

Others: an AI agent burning tokens re-fetching the same 20 records every four hours, a nightly sync silently nulling three columns, a retired cron whose old log was still being grepped for its done marker. All green. All wrong.

What I did

An outcome layer that sits on top of the existing self-heal wrapper. One outcome assertion per system, kept in a single manifest. Each one checks the place the consumer actually reads: rows for today in the target table, a fresh state file, a live service, a running container.

The same assertion is used twice. As the post-run check for each cron, so a run is only done when the destination changed. And by a daily audit that compares every system's heartbeat with its real output and classifies the gap: FALSE GREEN, BROKEN or SILENT OK.

The audit result lands as one row in my 06:00 digest. I read about divergence, not about activity. A wall of success logs nobody read became one line that only says something when heartbeat and output disagree.

Writing the manifest took one day for all 51 systems. It forced a question most of them had never been asked: what does done look like and where would I see it? A system with no measurable outcome is not a system I should be running on a schedule, so the manifest doubles as the list of what deserves to exist.

How it works

01

Freshness-gated log checks

A bare tail-the-log-and-grep-for-done is banned. Every log check reads only the window after the last start marker and only if the file was written recently. A stale log cannot pass as a fresh success.

02

No empty catches on the core step

Fail-soft is allowed for side effects like heartbeats and notifications. The thing the job exists to do must fail loudly. In n8n that means the core step is a credentialed node, not a try block inside a code node that quietly swallows a 403.

03

Retire-check on every change of shape

A retired cron, a moved log, a renamed slug. Each one triggers a grep across every config for stale references before the change is called done. That is how the retired-cron false green got caught.

04

Root-cause, do not patch

The sync that nulled three columns turned out to be an upsert bug in the shared database primitive, not in that one job. Fixed once at the primitive, so every caller got the fix.

05

Assert against the destination, never the attempt

The question is never did it run. The question is did the table, file or service change the way it should today. If a system has no measurable outcome, it should not be scheduled.

Results

  • 51 systems put under output-based monitoring in one day
  • 9 green-while-broken systems found and fixed the same day
  • First audit run: 47/51 OK with 0 false greens
  • Client feed fixed permanently: 1,035 rows, 0 duplicates after cleanup
  • A daily divergence line replaced a wall of success logs nobody read

What this means for your business

Every business that runs automations has this problem and most do not know it yet. A Zapier zap that ran, an n8n workflow that shows green, a report email that still arrives. None of that proves the output is right. Ask one question per system: did the destination change the way it should today? If your automations have never been audited against what they are supposed to produce, happy to grab a call and go through them with you.

Tools

  • Python
  • Bash
  • n8n
  • Supabase
  • Cloud server
  • Telegram

Skills

  • Automation Monitoring
  • Process Reliability
  • Root Cause Analysis
  • Business Process Automation
  • n8n
  • Systems Audit
  • Quality Assurance
  • Operations Manager

Questions

How do you know if an automation is actually working?

Check the destination, not the run. If the workflow is supposed to add rows to a sheet, count today's rows. If it sends a digest, check the sent log for today. A green status only tells you the process started. Nine of my 51 systems were green and broken at the same time.

What is the difference between a health check and an outcome check?

A health check asks whether the process ran and exited cleanly. An outcome check asks whether the thing the process exists to produce actually appeared where its consumer reads it. The first can be green for months while the second has been failing the whole time.

Why do automations fail silently?

Usually a swallowed error. An empty catch block, a step that logs a warning and continues or a check that reads an old log. The job finishes, the status says success and nothing was written. The fix is to let the core step fail loudly and only fail-soft on side effects.

How often should automated workflows be audited?

Every run should check its own output and a daily audit should compare every system's heartbeat with its real output. Doing it once by hand is how I found the nine. Doing it daily by code is how they stay found.