peppereffect · Click-defence asset
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.
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.
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.
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.
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.
Tick the checks you can demonstrate for one production workflow.