Ask a vendor about audit trails and you'll get a confident yes: every change is logged. Technically true. Open the log and here's what's in it: row 48213, field status_cd, old value 3, new value 7, user jsmith2, timestamp in UTC. That is an audit trail for a database administrator. The people who will actually need the history can't do anything with it.
The Hearing Where the Log Table Loses
Picture an appeals hearing. A property owner is contesting a water shutoff and tells the board, under oath, that he never received the notice. The whole case now turns on one question: can the agency show that the notice was generated on a specific date, mailed certified to the mailing address on file — not the service address — and signed for nine days before the shutoff?
If the system recorded the action, the answer takes thirty seconds: "Shutoff notice issued by M. Torres on March 4, mailed certified, delivery confirmed March 8, signature on file." The board can read that. The owner's attorney can read that. The case is over.
If the system kept a log table, the answer is that letter_flag changed from N to Y on some UTC timestamp, changed by a login ID belonging to a clerk who left last year. Nobody can say what letter, to which address, or whether it actually went out — the flag was sometimes set when the batch was queued, not when it was mailed. That is not evidence. That is a shrug with a timestamp.
Two More People Who Will Read Your History
The records officer gets a public records request for everything on a contested enforcement case and has a five-day statutory deadline to respond. What she gets from IT is a log export: thousands of rows of field diffs, status codes with no key, user IDs instead of names. She spends two of her five days reconstructing a narrative a system should have been keeping all along — and she still has to caveat it, because she's interpreting codes, not reading a record.
The new utility clerk inherits five hundred open backflow cases from a predecessor who retired. Which properties got a second notice? Which testers had expired certifications when their reports were accepted? Which deadlines were extended, and did anyone say why? If the answers live in the predecessor's sent-mail folder and a notes column that says "per phone call, OK to hold," the clerk starts the job a year behind.
What a Readable Entry Contains
A usable audit entry has the shape of a sentence: who (a name, not jsmith2), what in program language (status changed from Pending Test to Non-Compliant; notice issued; deadline extended), when in local time on the record's own timeline, and why — the reason, captured at the moment of the action. The why is the part machines can't reconstruct later. If the system didn't ask for a reason when the override happened, the reason is gone; it lives in an inbox or in someone's memory, and both leave the building.
You Can't Bolt This On
Readable history is a design decision, not a reporting feature. The system has to record actions as actions — notice sent, test approved, waiver granted — not as field diffs to be decoded by archaeology. Override and exception paths have to refuse to complete until a reason is entered. And the full history has to be visible on the record itself, in order, in plain language, so the case file tells its own story to whoever opens it next. A report writer pointed at a log table after the fact can't recover any of that, because the information was never captured.
The Question to Ask
"Every change is logged" is the wrong claim to accept. Ask instead: can a non-technical person, five years from now, open this record and understand what happened and why? Better yet, ask the vendor to show you one shutoff case, end to end, as the appeals board would see it. If you have to explain what status_cd 7 means, you don't have an audit trail. You have a log table, and a hearing waiting for it.