Flow
Package scope against row scope
1Package scope: view
A flattened view shows one tag list for the whole package.
2Package scope: outcome
A mismatch between rooms is invisible and one room can stay wrong.
3Row scope: view
Each stocked row is listed with its identifier and quantity.
4Row scope: outcome
One write names both rows and the receipt states the scope addressed.
One package of pre-rolls sat in two rooms, and each half had a different discount tag. My bulk tagging tool treated the package as one thing. That was the mistake, and the check after each write made the same one.
Why it mattered
I use these tags to discount old stock. I pick items that have sat too long, pick a tier, and the tool swaps the tags on each item. The stores' sales system reads those tags, and as far as I know the discount follows them. One room on the old tier means some stock on the wrong discount.
One package, two rows
The sales system keeps one inventory row for each place the stock sits. Each row has its own count and its own tags. My tool wrote by package and checked a summary view. Its receipt even said rooms take the tags of the parent row. That was a guess dressed up as a fact, and the check after the write used the same guess. I don't have a log of a room getting missed. I have that assumption in the old code and a test built from a real split package, which only passes when both rows get written.
Writing to every row
Now the tool reads the live list of rows for each package and keeps the ones with stock. A package with odd row data gets flagged on its own instead of breaking the whole batch. The write step follows.
The tool keeps the rows that have stock and sends a single write naming every one of them.
A row only counts as already done if the summary view showed that exact row. If I only know about it through the package, it gets written again. A spare write is cheap.
Checking without looking
I can't ask the sales system what tags one room holds. So the tool keeps a record of its own past writes, row by row. After a write, it pairs the live rows with that record, and each row says how it was confirmed. The receipt always says room tags were not seen directly.
Batches and stored answers
On the ordering side, work goes out in batches per store, each with a key built from the run and its contents. If an answer comes back garbled, the tool stops sending more and marks which items were tried and which weren't. On the other end, saved answers for repeat requests now have a size limit. A huge one gets cut down to a short receipt with the counts and a fingerprint of the original, and replaying it never writes again.
What the record misses
The record only knows about writes my tool made. If someone changes a tag by hand in the sales system, my record won't have it. As far as I can tell, that row's proof just gets thinner, and the receipt is the only place that shows it.