The repeat read we kept
We removed a doubled read from one route and kept the same doubled read in the next. Whether a repeat is waste depends on what happened in between.
This morning's fix was a route that read the same table twice without anything changing between the reads. The screen that lists who may do what at a venue fetched the venue's permission classes, then listed the people, then asked a helper whether the caller was allowed to edit, and the helper fetched the classes again. Two identical reads, one answer, a wasted round trip across the Atlantic on every load.
The route next to it saves the whole grid of classes at once. It also reads the classes twice. We left that one alone, on purpose, and the reason is the whole point.
What sits between the two reads
In the screen route, nothing. The classes are read, the people are read, and the classes are read again, with no write anywhere. The second read can only ever return what the first returned. That is the case where a repeat is pure waste, and the fix is to hand the first answer to whoever asks second.
In the save route, a write. The caller sends the grid, the route checks they may change it, which needs the classes as they are now, then it stores the new grid, archiving anything the venue did not send back. Then it reads the classes again and returns them. That second read is not the first one repeated. It is the answer to a different question: not what the classes were, but what they are, now that the write has landed. Returning the list the route had before the write would mean the screen showing a grid the database disagrees with.
The test that could have got it wrong
It would be easy to write a check that says every route reads each table at most once, and watch it flag the save route. That check would be asking the wrong question. The right question is whether anything happened between the reads that could change the answer, and a write to the same table is exactly that thing. So the hop-counting test covers the screen and the move-one-person route, where nothing is written in between, and leaves the save route its second read with a comment saying why.
On the floor
The same distinction runs through an ordinary shift. Counting the float at open and again before the first sale is a repeat with nothing in between. One of those counts is waste. Counting it at open and again at close is two different questions, because a day of trade happened in the middle, and nobody would call the second count a duplicate of the first.
When you find something done twice, do not ask whether it is the same action. Ask what happened in between.