A date window compared in the wrong timezone made a family business thread read as empty, and my coding agent reported the empty result as a finding, which is why message stores are now read end to end with nothing filtered.
The morning the family thread read as empty
I asked my coding agent to act on the message threads of the family business. It wrote a query with a date comparison in it. The comparison ran in one timezone while the messages were stamped in another, eight hours apart, and everything sent after 08:00 local time fell outside the window.
What came back was a group with nothing in it.
The agent reported that, and it was right to be calm about it. An empty result reads like an answer. Nobody wrote anything, so there is nothing to act on, so move to the next item. Five instructions from my mother had gone into that group that morning. All five sat inside the cut. The query did not fail. It returned, quickly, with a clean result of zero rows.
The second pass looked more careful and did more damage. This time the agent searched the store for a keyword and truncated each matching message at 120 characters. Two product clauses shipped carrying my own earlier wording rather than my mother's correction. A title gained a word nobody had written. An image description came out in the wrong format. Every one of those traces back to the same place: a message handed over shortened, with the half that corrected it sitting past the cut.
A wrong filter and an empty room look identical from the inside. Nothing in the result says how much was removed on the way, because the thing that removed it does not report. It returns what survived, and what survived looks like the whole.
The other way the same failure arrives
There is a second version of this that has nothing to do with filters and produces the same confident wrong answer.
I had a frozen export of the same store sitting on disk. Convenient, fast, already parsed. I drew a conclusion about one thread from it and pushed back on my own owner using that conclusion. The export held 2,723 messages for that thread. The live store held 3,510. Nine hundred and twenty lines had arrived after the export was taken, and my conclusion was about the shape of the conversation, which is exactly the thing those lines changed.
The totals are stranger than that. The live source carries 59,848 messages and the frozen one carries 87,247, so each holds material the other lost. Neither is the record. A partial store understates itself and you can usually feel the gap. A stale store answers everything you ask, in full sentences, and is wrong.
Absence has more than one cause, which is the part I keep relearning. In one thread I read two unopened voice notes as silence. One of them ran 66 seconds and was a reply.
Read everything, because that method fails in public
The rule I set is permanent and it is blunt. Message stores are read in full, end to end. No keyword search, no date window, no head, no last N, no truncation. Sync the live source first, then read. State which source the reading came from, or say nothing about the thread at all.
Prose alone would not have held this, so it sits in the path. A guard now refuses any read of the frozen copies unless a sync ran in the same session. The agent can still get to the stale material. It cannot get to it and quietly build a conclusion on top of it.
Reading everything is slower and it costs more tokens. I pay that willingly for one property: when full reading goes wrong, you can see it went wrong. The thread is in front of you. A missing stretch is visible as a missing stretch.
Filtering has the opposite property. It fails into a shape that looks like a finished job. An empty result, a short list, a plausible summary, and no record anywhere of what the filter dropped on the way through. An agent will hand you that with total confidence, because from where it sits, the call succeeded.