The default branch was an accusation
A two-way branch claims the signal underneath it is complete. It rarely is.
A stock-take of a running event automation turned up two numbers that explained everything in one line: twenty-nine confirmed attendees, and exactly one attendance record in the system. The follow-up sequence branches two ways — record present, you get the thank-you; record absent, you get the note saying you missed it. So up to twenty-eight people who had sat through the whole session were told they had not shown up. Nothing failed. No run errored. The logic did precisely what the diagram said.
Two numbers, one construction fault
The fix started as a routine job: rebuild a sequence around an online event that runs twice a year. Before rebuilding anything, I counted what the last run had actually produced. Twenty-nine people carried the tag for "yes, I'm coming". One person carried the tag for "attended".
That gap is not a data-quality problem. It is a design problem, because of what sits directly downstream: a branch with two exits. One exit is for people with the attendance record. The other is for everybody else, and it sends a message that opens by telling the reader they missed something.
The system was never wrong about what it knew. It knew one attendance record. It was wrong about what the absence of a record meant, because nobody had given it a way to say "no idea".
Where the signal actually stops
The attendance record is written by a job that matches the conference software's participant list against the contact database. That match only works for people the conference software can identify — those who registered under the same address, or who were signed in when they joined. Everybody else joins as a name typed into a box. There is no address, so there is nothing to match, so no record is written.
The obvious repair is to change the conference tool. I checked, and it would have been worse. On the alternative under discussion, external guests without an account of their own show up as anonymous participants, and addresses resolve only inside your own organisation's domain. Same hole, wider.
That is the moment where this stops being a tooling question. Both products measure attendance partially, because attendance is partially observable by nature. A system built on top of them has to survive that, not wish it away.
The tool did not lie. The schema had no room for the truth, so the branch invented one.
Absence of evidence is not evidence
Every two-way branch in an automation carries a silent claim: that the signal underneath it is complete. Present or absent, and absent means the negative case. When the measurement is in fact partial, the automation converts a gap in the data into a statement about a person — and it will almost always be the unkind statement, because the negative case is nearly always the default exit.
This is the part that has nothing to do with AI, which is why I think it is worth writing down. It happens in payment dunning, in onboarding checklists, in churn scoring, in anything that reads a missing row as a fact about the human it describes. The cheapest version of the bug is the most common one: the branch was built at a moment when the measurement happened to be complete, and it kept running after that stopped being true.
A branch may only send a message on the negative path if the negative was measured, not merely unobserved.
What the corrected version looks like
The rebuild has three values instead of two, and one brake.
- Attended: record present, send the thank-you.
- Missed: explicitly recorded as absent, send the follow-up.
- Neither: no record either way — exit the sequence and send nothing at all.
The third value is the whole fix. It costs one extra step in a flow chart, and it converts twenty-eight wrong messages into zero messages, which is strictly better than a wrong one.
The brake sits in the waiting step before the sequence branches. If the share of contacts heading for the negative path exceeds a threshold, nothing goes out and the run needs a human look. Twenty-eight out of twenty-nine would have tripped it on the first evening. The threshold is not clever, and that is the point: it catches the case where the measurement broke silently, which is the case no error handler ever sees, because from the system's side nothing broke.
The reference case that proves it works
A second format in the same organisation already ran with a three-value scheme, built by somebody who had presumably been bitten before. Its numbers from the same stock-take: eighteen registrations, eleven attendances, eight explicit no-shows. Eighteen accounted for, nobody in an undefined state, nobody wrongly accused.
That comparison is what makes this more than an anecdote. Same house, same kind of event, same category of tooling — and the difference in outcome comes entirely from whether the model of the world allowed for not knowing.
If you want one thing to take away: go and find the two-way branches in your automations that send something outward. For each one, ask what the false branch actually means. If the honest answer is "we didn't measure", it needs a third exit, and that exit is silence.

