The problem isn't writing the right check. It's writing it everywhere.
Nobody gets the authorisation check wrong on an entity's main endpoint: it's the first thing anyone thinks of and the first thing reviewed.
Incidents happen elsewhere, and almost always in the same places: an export added in a hurry, a global search function written for internal support and later exposed, a report aggregating data while skipping the filter, an interface created for an integration and never reviewed with the same care. The code works: it does what it says, and what it says is incomplete.
When permissions are declared on the domain rather than written into the paths, those paths have no way of being incomplete: they pass through the same authorisation engine as the main screens. It isn't a guarantee against every possible mistake — a badly declared permission stays badly declared — but it shifts the risk from "someone forgot" to "someone declared the wrong rule", which is far easier to find because it's written in a document you can read.