peppereffect · Click-defence asset

The Silent-Failure Audit

Twelve checks that decide whether a green run in your AI workflow automation is evidence of correct work, or just evidence that the run finished.

How to use it. Take one production workflow, not your whole estate. Answer each check against that workflow as it runs today, not as you intend to build it. Tick only what you can show someone.

Everything is scored in your browser. Nothing is sent anywhere, nothing is stored, and there is no field to give us your email. Print it with your browser's print command to keep a copy.

0 / 12
Start ticking. Every check you cannot tick is a way this workflow can fail without telling you.

Layer 1 · Does the run tell you the truth?

A failure that never becomes a notification is a failure you own for as long as it takes a customer to find it.

An error workflow or alert route is attached to each workflow that runs unattended, and somebody has forced a failure to confirm the alert actually lands in a place a human reads.

Pass: every unattended workflow, tested within the last 90 days

In n8n this is a per-workflow setting, so it is something you attach to each workflow rather than something the platform does for you.

No node on a production path is set to swallow errors unless its error branch goes somewhere that alerts or quarantines. A step that continues quietly turns a broken run into a successful one.

Pass: zero unrouted continue-on-error steps

Our own case: a setting that suppressed an abort left 97 records stuck in a failed state and re-pulled forever, while the workflow reported a clean run every time.

You know how long a normal run takes. A run that finishes in a fraction of that time raises an alert, because the cheapest way for a chain to succeed is to do nothing.

Pass: baseline recorded, and an alert below half of it

A chain of ours dropped from 24 seconds to 1.4 and kept reporting success. The credential behind it was dead.

Layer 2 · Did the output actually arrive?

Run status tells you the steps executed. It says nothing about how many records came out the other end, or whether anything received them.

Before the write step, the run checks that the record count sits inside a plausible range and fails loudly outside it. Zero rows is the case this catches most often.

Pass: a count assertion on every write step

For every field a downstream step depends on, the run measures what share of records carry a value, and fails below a threshold you set. An empty field is not an error to most platforms. It is just an empty field.

Pass: a fill-rate check on every required field

After every write to an external system, you read back what that system holds and compare it with what you sent. An upload dialog reports what left your side, not what the other side took.

Pass: a read-back on every external write

Our own case: 142 records were sent to a sending platform and 63 were accepted. The 79 rejections were silent, and they were the top of the list.

Layer 3 · Is the output correct?

This is the layer almost nobody instruments, and it is where the expensive mistakes live.

For each field that drives a decision, you have checked in the vendor's own data whether it holds the current state or the last thing that ever happened. Those two look identical in a JSON payload.

Pass: documented for every status field in use

We declared three working mailboxes dead off a status string that turned out to be an archive of an old error. We made that same mistake three times.

At each ingest boundary, the payload is checked against an explicit contract, and an unexpected or missing key fails the run instead of producing a blank. Casing counts as a contract.

Pass: schema validation at every ingest boundary

A mapping step of ours read one casing while the upstream service emitted another. Every run was green and every name field came out empty until someone read the records.

Before any run acts on customers, at least fifteen completed records are read from first field to last output by a person. Not sampled fields. Whole records.

Pass: 15 or more records read since the last change

When we first did this properly, 11 of 18 records were broken in a batch two hours from sending. Three of the five automated gates ahead of it were leaking.

Layer 4 · Can you still see the whole set?

The worst failures are not the ones that stop the work. They are the ones that quietly shrink it.

Page sizes, row caps, rank caps and batch limits are listed in one place, with the date each was last compared against the size of the table it reads. A cap set for last year's volume is invisible this year.

Pass: no cap sitting below current volume

A cap of 450 in our own code met a table of 749 rows. Everything from row 451 simply did not exist as far as the chain was concerned, and the backlog looked like a throughput problem, not a filter.

The queue takes new records first and retries second. A queue that retries failures ahead of new work will spend a full run on the same poisoned rows and produce nothing, at full green.

Pass: new-before-retry ordering confirmed in the query

When a measurement step errors, the record is marked unmeasured and re-queued. It is never written into the field that holds the business judgement, where a later run will read it as an answer and skip it.

Pass: no failure state doubling as a verdict

We stored 144 failed checks as a negative verdict. Re-running them cleared 96 as perfectly fine. We had almost thrown away 96 live records under the label of diligence.

Your score will appear here

Tick the checks you can demonstrate for one production workflow.