Rent statements rarely overcharge in one dramatic line. The extra cost arrives in small, plausible pieces: a common-area maintenance reconciliation that runs a little high, an escalation applied a month early, a management fee calculated on the wrong base. Each item looks routine on its own, so it gets paid. Across a multi-year lease and several locations, those pieces compound into a leak that never appears as a single obvious error.
Building lease checking into ERPSav started from that observation. If the errors are small, rule-shaped, and repeated, then the useful tool is not a smarter guess — it is a boring, repeatable comparison of every charged line against the clause that authorises it.
What worked
Encoding clauses as explicit, checkable rules. Caps on operating expenses, escalation dates and rates, gross-up treatment for vacant space, percentage-rent exclusions, and lists of pass-throughs the lease excludes — each clause became a rule with a clear pass or fail. When a statement line failed, the system could point to the exact clause, not just flag a suspicious total.
Showing the clause beside the flagged line. An exception queue that only says "this looks high" creates more work than it saves. Placing the statement line and the lease wording side by side let a reviewer confirm or reject a flag in seconds, and it made false positives obvious instead of expensive.
Ranking by recoverable amount and evidence strength. A large flag with weak evidence is less useful than a smaller flag that is documented end to end. Sorting the queue that way meant the first items reviewed were the ones most likely to turn into an actual recovery.
Starting narrow. Two years of statements for one location was enough to test the rules honestly. It exposed definition differences between leases early, before the same mistake could be repeated across a whole portfolio. That narrow test set is the approach described for ERPSav, a CloudVerg product built around rules-based recovery checks.
What broke
Rules built from billing summaries. The first pass learned the wrong lesson: summaries drift from signed lease language over time, sometimes within a single lease term. Rules built from a summary produced confident false positives — correct arithmetic against the wrong definition. The fix was unglamorous: the signed clause is the only source a rule is allowed to come from.
Percentage rent is not one definition. One lease excludes returns, another excludes online orders fulfilled from the store, a third defines gross sales differently again. Treating percentage rent as a single shared rule broke immediately. It has to be parameterised per lease, even when that makes setup slower.
Capital items in disguise. A capital improvement amortised too quickly can look exactly like an ordinary operating expense on a statement. Unless the rule checks the amortisation schedule itself, the charge passes every surface test while still violating the lease.
Lessons
Auditability beats clever detection. A flag a reviewer cannot trace back to a clause is just an opinion, and finance teams are right to ignore opinions at month-end.
Small, plausible errors are the expensive kind. Dramatic errors get caught by humans because they look wrong. The costs that survive for years are the ones that look routine.
And the checking has to be repeatable. Leases reward whoever reads them most carefully, statement after statement — which is precisely the kind of patience software has and people, reasonably, do not.
What does lease or contract checking look like in other teams' stacks — manual sampling, spreadsheets, or rules like these?
![AMR Mechanical and Electrical Engineering — Ch.12: Contents {#contents .TOC-Heading} [KR]](https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwzu7uvk9b9zcljsl3gz5.png)
![AMR Mechanical and Electrical Engineering — Ch.14: Contents {#contents .TOC-Heading} [KR]](https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6nel7ut2runbhcvsezvf.png)
