Measured Behaviour
Published
A penalty ladder is a clock, and every option on it moves the same clock by a different amount. We measured what happens when one moves, and then what happens when two that pull the same way move together - which turned out to be six times worse than adding up the halves.
Six unpaid passages and a statute
We built one week's enforcement the way one actually looks. Six unpaid passages from one gantry: one paid inside the cure period, one paid nine weeks late, three still unpaid after three months, and one whose first notice went out twenty-two days after the passage.
That last one matters most and it is the reason the area is here. The statutory window is fourteen days. A first notice that misses it is not a late notice; the authority simply loses the right to collect. The toll was real, the driver did pass, and it is not collectable.
The rest is ordinary: a cumulative penalty ladder at thirty, sixty and ninety days, a twenty-one day cure period before the clock starts, an $80.00 cap on penalties for one violation, and a registration hold once a violation reaches $85.00.
The correct run bills $318.00: $53.00 in tolls and $265.00 in penalties, one violation void, four escalated, three capped, three registrations held. Protection alone changed nothing across five profiles. The failures start when member renaming reaches the names on the enforcement configuration object - the mechanics are in Protect Members.
Collecting money the statute says you cannot
noticeWindowDays carries the fourteen-day statutory limit. Its vendor default is 0, which the library reads as NO STATED WINDOW - every notice is timely, however late it went out.
Lose the key and the void violation is billed like any other: $4.75 in toll plus $80.00 in penalty, and the week's total rises from $318.00 to $402.75. The authority collects $84.75 it has no legal right to, from a driver whose only defence is a date nobody is checking any more.
The counter reads better, which is rule 40 of this series in a sentence. VOID goes from 1 to 0. A notice operation that voids nothing is exactly what a well-run notice operation looks like on a dashboard, and the number rose rather than fell, so nobody goes looking.
And the authority's own rule passed, printing 6 violation(s), 0 void on notice timing, 5 escalated, $402.75 billed, nothing collected out of time. The last clause is the one to read twice. It is defined over the void counter, and the void counter is computed by the statutory window that went missing. Nothing was found out of time because nothing could be.
The union that is six times worse than its halves
Two keys on this object both REDUCE what a driver owes, and we pre-registered the prediction that their union would be worse than either half, because they are consulted at different points and neither can remove the other's subject.
cureWindowDays is the twenty-one days a driver gets to pay before anything escalates. Lose it and lateness is counted from the notice instead: the week bills $373.00 instead of $318.00. Fifty-five dollars across six drivers.
maxPenaltyUsd is the $80.00 ceiling on penalties for a single violation - the consumer protection in this file, and the vendor default is NO CAP. Lose it and three violations go from $80.00 to $85.00 of penalty: $333.00 instead of $318.00. Fifteen dollars.
Lose both and the week bills $753.00. Not $388. Penalties go from $265.00 to $700.00, three violations reach $205.00 of penalty each, and one driver who was never near the threshold in any other arm has their registration held - holds go from three to four. The halves add up to $70 of harm. Together they do $435.
The mechanism is worth naming because it generalises. The cap was not merely a mitigation, it was a DISGUISE: it clipped three of the four ladder errors back to $80.00, so the cure-period loss looked like a $55 problem confined to one driver. Remove the disguise and the same underlying error is worth eight times as much. A control that limits damage also limits the visible evidence of its cause.
The arm where every dollar is identical
registrationHoldAfterUsd is the threshold at which a registration is held. Lose it and the vendor default is never hold.
Every money figure in that arm is identical to the correct run, to the cent: six violations, one void, four escalated, three capped, $53.00 in tolls, $265.00 in penalties, $318.00 billed. The only thing that moved is a counter - HOLDS from 3 to 0 - and a list of plates that came back empty.
It would be easy to file that as cosmetic. It is not. The registration hold is the mechanism that actually collects from persistent non-payers; the billing was never the problem with those three drivers. An arm that moves no money at all has switched off the recovery arm of the programme, and every revenue report will show the balance owed exactly as before, right up until the ageing profile stops improving.
escalationLadder and honourLadder are the loud pair: lose either and penalties fall to $0.00, the week bills $53.00, and the two arms are byte-identical to each other on every counter. That one shows up in the first monthly report.
The negative control is a week when everybody pays
We ran the same six violations with the same notice dates - including the one that missed the statutory window - and every driver paying inside the cure period. Nothing escalates, nothing is capped, nothing is held. $53.00 billed.
That control is byte-identical to the escalation-ladder arm on every counter. A fixture whose drivers pay on time cannot see a ladder failure, a cap failure, a cure-period failure or a hold failure, and a fixture whose drivers pay on time is the fixture everybody writes.
The mirror is one field away: renaming tollDueUsd or passedDay produced no readable violation(6 of 6) -- refused before enforcing. Losing the value fails closed and loudly. Losing the clock the values are measured against fails open in both directions at once - overbilling four drivers and undercollecting from three - and the programme's own check passes on true figures either way.
What we would actually do about it
Assert the statutory window separately from the ladder, against the passage date rather than against a counter. The void count is computed by the window; a check defined over it cannot see the window go missing. A rule of the form no notice was issued more than fourteen days after its passage reads the dates directly and catches the arm that bills money the statute extinguished.
Alarm on penalties above the published cap, not on penalties above zero. The cap is the consumer protection and the vendor default removes it, so the one comparison worth making is against the published number rather than against the previous period.
Treat an unchanged revenue total as no evidence at all. The registration-hold arm is exactly correct on every dollar and has disabled recovery. Reconcile enforcement ACTIONS as well as amounts.
And run both halves of every pair. Neither $55 nor $15 would survive triage in any organisation. $435 would, and it is the same two keys.
Enforcement platforms increasingly sit inside the scope of critical-infrastructure regimes - NIS2 and the JavaScript You Ship covers what that means for the client-side code in a road operator's stack.
Frequently asked questions
Does obfuscation change how violations escalate?
Not on its own. Five profiles - the ES5 target, the modern target, both emit-gate configurations and the string-encoding profile - all produced behaviour identical to the unprotected run: six violations, $318.00 billed, one void, three registration holds.
What did break it?
Member renaming reaching the enforcement configuration object. The library reads its options by name; a name it cannot find is a key you never supplied, so it substitutes its own default. The vendor default for a statutory notice window is no window, and for a penalty cap it is no cap.
Why was the union so much worse than the two halves?
Because the cap was hiding the cure-period error rather than preventing it. With the cap in place, three of the four ladder errors were clipped back to $80.00, so losing the cure period looked like a $55 problem. Remove the cap as well and the same underlying error is worth $435. A control that limits damage also limits the visible evidence of its cause.
Can a rename make us collect money we are not entitled to?
Yes. Losing the statutory notice window billed $84.75 on a violation whose first notice went out twenty-two days after the passage, against a fourteen-day statute. The void counter went from 1 to 0, revenue went up, and the programme's own check passed printing 'nothing collected out of time'.
One arm changed no money at all. Is it safe to ignore?
No. Losing the registration-hold threshold left every dollar identical to the correct run and took holds from three to zero. The billing was never the problem with those drivers; the hold is the mechanism that collects. Reconcile enforcement actions as well as amounts.
Would our tests catch any of this?
Only if your fixture has drivers who do not pay. We ran the same six violations with everybody paying inside the cure period, and that control is byte-identical to the arm that loses the ladder entirely. A fixture that pays on time cannot see a ladder, a cap, a cure period or a hold.
How do we protect enforcement software safely?
Scope the member pattern so it cannot reach configuration keys or record field names, and assert statutory dates directly rather than through counters the configuration computes. Protect Members documents how the regexp is applied and what a safe scope looks like.
Related reading