Library

How do you know your automation is really working?

Brett K Moore9 min readHow the system works

Written for agents, brokers, lenders, contractors, home services.

The short answer

A success message means a program finished without hitting an error. It does not mean the program did the job you hired it to do. Almost every automation tool reports the first thing and calls it the second.

A success response is not evidence. The only evidence is the artifact, read back from the system that holds it, after the job says it finished.

We ran a nightly job for seven weeks that reported success every morning while reading a table with 18 rows in it. The table it was supposed to read held 4,295.

The log was never wrong. The job ran, read a table, found nothing new, and exited zero, which is exactly what a static source produces every night.

Four rules fix most of this: name what a job reads instead of letting it discover one, assert a floor and fail below it, report counts on every run including empty ones, and never exit successfully on an empty pull without stating the total the source held.

A job ran every morning for seven weeks and reported success every morning. It was reading the wrong table the whole time. Roughly half a million words sat unread on a disk about eighteen inches from the person who owned them, while a log file said the pipeline was working.

This is our own failure, dated and measured. The shape of it shows up in a drip campaign, a lead router and a transaction checklist as readily as it showed up here.

What does it mean when an automation reports success?

It means the program finished without hitting an error. It does not mean the program did the job you hired it to do. Those are two separate claims, and most automation tools only ever report the first one.

A program has one easy question it can answer about itself: did I crash. Everything else requires the program to know what a correct result looks like, and almost nobody writes that part, because writing it means deciding in advance what a normal night produces.

So the default definition of success is negative. Nothing threw an error, therefore report success. A job pointed at an empty source, a renamed field, a folder that no longer exists or a table that was never the right table satisfies that definition perfectly, every single time it runs.

What we found on our own machine

The job was simple. Every night it opened the local history database belonging to a dictation app and built a record of how one person speaks, so that anything drafted later would sound like them rather than like a machine. It ran on a schedule. It reported success.

It was reading a table called RemoteNotifications, which it had found by itself. That table held 18 rows, and later 19. The table it was supposed to read, called History, held 4,295 rows.

The log window runs 2026-06-20 to 2026-08-08. Twelve separate runs across that period found the wrong table. Before 2026-08-01 at 21:21:52 UTC there are zero lines anywhere in that log recording anything ingested at all. Not a small number. Zero.

The first correct run, once the table was named by hand, pulled 4,203 rows and 537,023 words. Half a million words of one person speaking, sitting on their own disk, unread, for as long as the log covers.

Every line in that log was true

This is the part worth slowing down for. The log was not lying. Nothing in it was inaccurate. The job started when it was supposed to start. It opened the database it was pointed at. It read a table. It found no new rows in that table, because that table almost never changes. It exited zero.

The script treated no new rows as a normal successful ending, which is a reasonable thing to do, because most nights on a healthy pipeline genuinely have nothing new. A source that never changes produces the identical result to a source that has nothing to report. From outside, on the evidence available in the log, those two situations are indistinguishable.

No error. No warning. No alarm on an empty result. Seven weeks of a green light on a job that had never once done what it existed to do.

The failure hiding inside the failure

When we went back through the log to work out how long this had been going on, we found a second problem underneath the first. The log records no runs at all between 2026-06-26 and 2026-07-28. Thirty one days. For a month the job produced neither data nor a line saying it had run.

Whether it never fired, or fired every night and failed to write a line, we do not know. That information no longer exists. This is the harder of the two failures to catch, because a wrong result at least gives you something to read. An absent line gives you nothing, and a person scanning a log sees a June run, a July run, and no reason to count the days between them.

Why would a broken job report success for seven weeks?

Because the script defined success as finishing without an error, and finishing without an error is exactly what reading an empty or static source produces. A job that correctly found nothing and a job pointed at the wrong place look identical from the outside.

The fix is to make the job assert something about the world rather than about itself. Not "I finished," but "I read the table named History and it held this many rows, of which this many were new."

That sentence contains a claim that can be wrong, which is the entire point. A report that cannot be wrong cannot tell you anything.

Four rules we now run on every scheduled job

  1. 01Never let a job auto-discover what it should be reading. Name it. Discovery is a convenience that costs you the one thing you needed to be certain about. A job that finds its own source will, on the day something is renamed, quietly find a different one and carry on.
  2. 02Assert a floor. Decide what a sensible minimum looks like before you switch it on. If the pull comes back under that number, the job fails rather than succeeds. A failure you can see beats a success you cannot check.
  3. 03Report counts on every run, including the empty ones. A line that reads zero new rows out of 4,295 total is a completely different message from a line that reads zero new rows out of 18, and only one of those tells you where you are.
  4. 04Never exit successfully on an empty pull without also stating the total the source held. This is the specific rule that would have caught ours in the first week, at zero cost, with one extra number on one line.

The same shape, three more times

Once you have seen this pattern you find it everywhere. Three more, all observed, all with dates.

  • Twelve of seventeen test cases passed while the test harness was completely broken. All twelve were cases that expected the system to block something, and blocking is what a dead script produces. A corpse refuses everything. Only the five cases that expected a pass exposed the problem. A test suite made mostly of refusals cannot tell a careful gate from a broken one.
  • A plugin installer printed a green success checkmark on a plugin that could not load. Confirmed by test on 2026-08-10. The cause was unquoted colons in a metadata field. The metadata failed to parse, and every component in the plugin loaded with empty settings, silently, while the installer reported that everything had gone in.
  • A publish reported failure while succeeding. The verification step ran three seconds after the push, checked six paths that had never existed, got 404 on all six, and called the whole thing a failure. The change had landed. The check was looking in the wrong place at the wrong moment and delivered its verdict with full confidence.

That third one is the inverse of the other two and teaches the same lesson. A check that runs against the wrong thing, or too early, delivers its verdict with the same confidence either way.

What counts as evidence that a change worked?

The artifact itself, read back from the system that holds it, after the job says it finished. A green build is not a shipped change. The only evidence a change shipped is the live page, fetched and read.

This is the rule we would keep if we had to throw the rest away. A success response is a claim made by the thing being asked about itself. Reading the artifact back is an independent observation, and only the second one has any weight.

It holds far outside software. A campaign platform reporting sent is a claim. Opening one recipient inbox and finding the email there is an observation.

Now put this in a real estate business

None of the four below are client cases. They are illustrations, chosen because they have the identical shape to the failure above.

  • A drip campaign reporting sent while the list query returns zero. The platform sent everything it was given. It was given nobody. The dashboard shows a completed send, and a send to nobody completes faster than a send to four hundred people.
  • A lead router with a rule that stopped matching after a field was renamed. The rule looks for a value that no longer exists. It matches nothing, routes nothing, and errors on nothing, because finding no matches is a legitimate outcome for a filter.
  • A transaction checklist that auto-completes because a document was uploaded to the wrong slot. A file arrived. The rule watching that slot fired. The item went green. Nobody has read the file, and the item that would have prompted somebody to read it is now closed.
  • A review request automation that has been firing at an empty segment since March. Same shape as ours. The segment definition drifted, the audience became zero, and a send to zero recipients reports the same green as a send to two hundred.

In every one of these the symptom is the same. Nothing errors, and the only sign is somebody going quiet.

That is what makes this category expensive. The quiet gets blamed on the market or on a cold database, because those explanations are available and a silently dead automation is not. Meanwhile the tool reports healthy numbers, and healthy numbers are what people check.

How do you check an automation you already trust?

Pick one record it claims to have touched and follow it by hand to the far end. Open the email in a recipient inbox. Open the CRM record it says it updated. Open the document it says it filed. One record, once a month, per automation.

One record is enough because these failures are rarely partial. A router either matches or it does not. A segment is either populated or empty. When the mechanism breaks it usually breaks for everybody.

Write down the date you checked and what you opened. A note reading "opened the review request in a client inbox on the eleventh, it was there" is worth more than any dashboard, because it is an observation rather than a claim.

The four boxes

The four boxes applied to the reporting layer of automation itself. The fourth box carries the argument, and the two absences in it do not deserve the same verdict.

There, and should be

Run history you can open, with a timestamp on every run.

  • Almost every tool has this and almost nobody opens it. It is the cheapest thing in the stack to start using.
  • Read it looking for gaps between dates rather than for red marks. Our thirty one day hole had no red mark in it anywhere.
  • A run history that only keeps thirty days is worth knowing about before you need ninety.

Missing, and should be there

A floor on every job that moves records, and a count reported on every run.

  • Decide the minimum before you switch it on, while you still remember what normal looks like. After a month of silence you will talk yourself into believing zero was always plausible.
  • The count needs two numbers to mean anything: how many came through, and how many the source held. One number without the other is what let ours run for seven weeks.
  • For tools you did not build, the substitute is the monthly hand check. It is worse, and it is far better than nothing.

There, and should not be

Any job that discovers its own source, and any success message that reports an empty result as normal.

  • Auto-discovery is the single feature that turned a fixable bug into seven weeks of confident silence.
  • A green light nobody can explain the meaning of is worse than no light, because it answers the question people would otherwise have asked.
  • Alerts that only fire on errors belong in this box too. The failures in this piece produced no errors at all.

Missing, and correctly missing

Almost no consumer automation tool reports what it read alongside what it did. Part of that absence is right and part of it is not.

  • A full record of everything a job examined is correctly absent. A nightly dump of every contact evaluated, every file scanned and every rule tested is a report nobody opens, and a report nobody opens is worse than no report, because it looks like the system is being watched. The cost of leaving it out is real but small: when something does go wrong you cannot reconstruct the reasoning, and you have to rerun it to find out.
  • One number is not correctly absent: the size of the source. How many records were in the place you looked. It fits on the same line as the count of records processed, it costs nothing, and it is the difference between zero out of eighteen and zero out of four thousand two hundred and ninety five.
  • The cost of that second absence, stated plainly: a business can run a dead automation for a full quarter, see nothing but green, and attribute the missing results to the market. Nobody ever gets a bill for it, which is why it survives.

What this discipline does not do

The one sentence to carry out of this: a success response is not evidence. Everything else here is that sentence with dates attached. Read the artifact back from the system that holds it, say what you checked and when you checked it, and treat a green light as a question rather than an answer.

Common questions

Why does my automation say it worked when nothing happened?
Because most automations define success as finishing without an error, and reading an empty or wrong source finishes without an error. We ran a nightly job for seven weeks that reported success every morning while reading a table of 18 rows instead of the table of 4,295 rows it was meant to read. Every line in the log was true and none of it was useful.
What is the one rule that catches silent automation failure?
A success response is not evidence. Read the artifact back from the system that holds it. A green build is not a shipped change, and the only evidence a change shipped is the live page, fetched and read after the deploy said it had finished.
How do I stop a scheduled job from failing silently?
Four rules. Name the source instead of letting the job discover one. Assert a floor and fail below it. Report counts on every run, including the empty ones. Never exit successfully on an empty pull without also stating the total the source held.
What does a silently broken automation look like in a real estate business?
A drip campaign reporting sent while the list query returned zero. A lead router whose rule stopped matching after a field was renamed. A transaction checklist item that auto-completed because a document went into the wrong slot. A review request firing at an empty segment for months. In each one nothing errors, and the only sign is somebody going quiet.
Can passing tests prove an automation is working?
Not on their own. Twelve of seventeen test cases passed for us while the test harness was completely broken, because all twelve expected the system to block something and a dead script blocks everything. Only the five cases that expected a pass exposed the problem. A test suite made mostly of refusals cannot tell a working gate from a broken one.
How often should I hand check an automation I trust?
Once a month, one record, per automation. Follow a single record it claims to have touched all the way to the far end and open it there. These failures are rarely partial, so one sample usually catches them. Write down the date and what you opened, because that is an observation rather than a claim.

Worth passing along

Send this to the person on the team who owns the follow up sequences, and to the transaction coordinator. Both of them are judged on outcomes produced by machinery they have no way to inspect, and both of them have at some point been asked why a client went quiet when the honest answer was that a rule stopped matching in March and the dashboard stayed green.

Written by Brett K Moore. We build the PAD System, a records structure for people, assets and deals that lives as plain text files on your own computer. Read what it is.

What does it mean to connect your AI to your email and calendar?

What you are agreeing to when you click Connect, why a connector never tells you which account it is holding, and the one send rule adopted after a private client brief reached eighteen unintended recipients. Written for real estate agents, brokers, mortgage lenders and the trades who work alongside them.

Should your CRM be where your business remembers things?

A CRM is built to move people through a pipeline and it is very good at that. It is a poor place to hold what you know about a person, and the two jobs pull against each other. Where the line sits, and the one rule that stops the two systems disagreeing. Written for real estate agents, brokers, mortgage lenders and the trades who work alongside them.

How do you decide whether a tool belongs in your business?

A four box audit for a software stack: what is there and should be, what is missing and should be there, what is there and should go, and what is missing for good reason. Written for real estate agents, brokers, mortgage lenders and the trades who work alongside them.