2026-06-14 · verification · from PermitCheck

The average answer is a trap

In a regulated domain the generic rule is usually close and occasionally, expensively, wrong. A system that answers from the average case is a confident-wrong machine. On why the unit of correctness is the specific instance, not the category.

Early versions of PermitCheck compared a project against the typical limits for its zone: typical maximum coverage, the side setback that applies to most lots like this one. It was right most of the time. That was the failure mode I hadn't designed for.

In zoning, like in most regulated domains, the binding number isn't the typical one. The same zone designation carries lot-by-lot variations: a site-specific exception that changes a setback for that parcel and no other, an overlay that sets a different height or coverage for that exact piece of ground. The generic limit is a good guess for the category and a bad guess for the property in front of you.

Close is the worst place to be

If a system were wrong in an obvious, gross way, you'd catch it. The danger is the system that's right ninety-something percent of the time. The generic-limit version of my tool would have sailed through casual testing. It only fell apart on the cases that matter most: the properties whose actual rules differ from the category, which are the properties where a person most needs the tool to be right.

I watched this happen in the measurements. A package would be flagged as over the limit, confidently, and it wasn't, because the lot carried an exception that made the real limit different from the typical one. The tool read the drawing correctly and compared the number against the wrong target. The error was upstream of the model entirely, in the decision to answer from the average instead of from the instance.

The unit of correctness is the instance

The fix was a change in stance, not a change in model. Resolve the binding limit for the specific property first, exceptions and overlays included, and only then compare. When the property's real limit can be established, the verdict is confident and sourced. When it can't, the tool says so rather than falling back to the generic number.

Here's one real side setback moving through the resolver, straight from the unit tests:

1

The lot carries exception 900.3.10(5)

"Despite regulation 10.20.40.70(3), the minimum side yard setback is 1.8 metres." An unconditional single-value override, so the resolver takes it: 1.8m, tier exception, confident.

2

Same 1.8m, ambiguous zone boundary: confidence dropsgate

If the lot sits on an ambiguous boundary, the same resolved value ships as not confident, and the verdict downgrades to "verify" instead of a flag.

3

A conditionally-scoped clause is rejected outrightgate

"1.8 metres for that portion of the building above the second storey" never becomes a confident override. A value scoped to part of the building isn't the lot's limit.

One side-setback line through the resolver, from tests/unit/zoning-resolve.test.ts

This sounds obvious stated plainly, and it's the thing most domain tools get wrong. They encode the rules of the category and apply them uniformly, because that's what fits in a clean ruleset. But regulated domains are dense with instance-level overrides, and the value of a tool is almost entirely in handling them correctly.

Why this generalizes

Swap zoning for any domain where rules attach to specific entities: a tax position that depends on the particular entity's history, or a contract whose governing clause is a bespoke amendment rather than the template. Benefits work the same way, hinging on the individual's exact circumstances. A system that reasons from the typical case will be confidently wrong on exactly the cases that carry the most risk.

So when you build for a regulated domain, ask early whether you can establish the binding fact for this specific case, or you're substituting the average and hoping it's close. If you're substituting, you've built a tool that's most wrong where being wrong costs the most.

New essays when the work ships. No noise.