Skip to content

Match and refuse before any write

The physical worldScanmatchrefuserefuse.conflictrefuse.missing

A wrong pairing is refused with copy that names the right container, and nothing is written.

The situation

An associate holding a bag scans the wrong bin. The station must catch it before anything changes, and tell the person where the bag actually goes, in words they can act on.

The recipe

match states what the pairing must satisfy. refuse states what the station says when it does not.

rule 14:0 Container label
{ "query": { "roles": ["binning"], "status": "pending" },
"verb": "accumulate",
"requireActingIdentity": true,
"subject": { "schemes": [11] },
"match": { "target": ["{subject.containerCode}"] },
"refuse": {
"markdown": "That's {container.locationName}'s container. This one goes in **{subject.containerCode}**.",
"conflict": "That container was just taken. Scan the item again.",
"missing": "That container is closed. Scan the item again."
},
"params": { "itemKey": "{subject.itemId}", "accumulate": { "from": "subject" } } }

match.target lists templates the scanned target must equal. match.facets lists facets the located container must share with the held row. A match.target entry that is a lone token naming a list facet (such as {subject.offeredContainers}) accepts any entry in that list.

The guarantee

A miss answers refused with the rendered markdown, and nothing is written. When the write itself loses a race (the container closed, another bench took the free slot), the answer is refused with the refuse.conflict copy, and the subject clears so the next scan reads fresh state. A step payload the role’s form schema rejects also answers refused with the reason, never a raw 422. See Scan codes.