Measured Behaviour

Does obfuscation break settlement date calculation?

A settlement date is not a policy and not a threshold. It is a count over a calendar, and the calendar is data - a list of days an exchange is shut. Lose the name that carries that list and nothing throws: you get a perfectly ordinary arithmetic answer that names a day on which nobody is open to receive delivery.

Forty deliveries, three holidays, and a four-day buy-in

The fixture is a settlement blotter: forty deliveries around a holiday week, a next-day settlement cycle, a published calendar with three market holidays in it, weekends, a four-day buy-in deadline, a three basis point per day fail charge, and an instruction that part deliveries do not discharge the obligation.

The correct run settles thirty-two, leaves eight failing, accrues 6,498.60 in fail charges, raises seven buy-ins, and reports zero deliveries falling due on a day the market is shut.

Protection with default settings, on all five profiles, was byte-identical. Everything below needs member renaming.

The calendar is data, and the empty default is a market that never closes

The settlement library defaults marketHolidays to an empty array. That is not a bug and not a missing value. A library cannot ship a calendar for a market it has never heard of, and an empty calendar is a coherent description of a venue that trades every day of the year.

Rename the member and the caller's three holidays stop being found. Due dates are then computed correctly over that other market. Two of the first six deliveries on the report move from day 148 to day 147 - and day 147 is one of the three days the exchange is shut.

Across the whole blotter, ten of the forty deliveries fall due on a day the market is genuinely closed, six of them on that one holiday. The fail charge total moves from 6,498.60 to 7,189.20, which is the only figure on the report that changes and reads like noise.

Renaming weekendDays is the same shape at higher frequency: twelve of forty fall due on a Saturday or Sunday, and the charge total moves to 6,909.90.

The check that exists to catch this reported zero

The operations desk in this fixture has a rule, and its first clause is exactly the right one: nothing may fall due on a day the market is shut.

In every arm above it reported DUE-ON-A-CLOSED-DAY=0 and the run passed. The reason is not subtle once you see it. The question is this day closed? is answered by consulting the same calendar the due date was computed from. Lose the calendar and there are no closed days for anything to fall due on, so the check is truthful and useless at the same time.

This is a shape this site has measured before in other domains: a guard defined over the very thing that went missing keeps running and matches nothing. What makes the calendar version worth its own page is that the guard is not comparing against a policy or a denylist - it is comparing against a fact about the world, and the fact about the world is the thing that was lost.

The rule's second clause is worse and worth naming as a pattern. It refuses any fail past its deadline for which no buy-in was raised, and the engine raises a buy-in for exactly those fails. The count it compares is the count it produced. That clause can never fire in any arm, correct or broken.

Seven mandatory buy-ins that were never raised

^(buyInDeadlineDays)$ reverts the desk's four days to the library's thirty. Every other figure on the report is identical to the correct run: thirty-two settled, eight failing, 6,498.60 in charges. The buy-in count goes from seven to zero.

Nothing refuses it, because the only clause that could is the one closed by construction. Seven obligations the desk is required to go into the market and cover simply do not appear on the list of things to do, on a report that otherwise matches the correct one line for line.

^(failFeeBpsPerDay)$ is the cost-side twin: charges go to 0.00 and an ageing fail becomes free. A fail that costs nothing does not appear on a cost report, and a fail that does not appear on a cost report does not get chased.

Two part deliveries that closed obligations they should not have

This desk is delivering against client instructions that are not divisible, so a part delivery is a fail. The library's default is the opposite: a part delivery discharges the obligation.

Renaming partialDeliveryOk moved settled deliveries from thirty-two to thirty-four and failing from eight to six. Two half-delivered lines disappeared from the fail report entirely, and the buy-ins fell from seven to five.

The direction is worth noting because it runs against intuition. The broken run looks better than the correct one: fewer fails, fewer buy-ins, lower charges. Anyone comparing the two reports without knowing the cause would conclude the desk had a good week.

What failed closed

Renaming tradeDay, qty, priceUsd or deliveredQty made an obligation non-finite and the run refused before settling anything. Renaming deliveredDay was loud in the other direction: nothing could be established as delivered on time, so all forty deliveries failed and thirty-four buy-ins were raised. Nobody misses that.

The contrast holds for the twenty-fourth domain running on this site. Losing the number is loud. Losing the calendar the number is counted over is silent, and the silence is produced by the check you would have relied on.

The quiet week sees none of it

The same file runs a stretch of the calendar with no holiday in it, where every delivery was made in full on the day it was due. On that run every arm above is inert. The calendar, the cycle, the partial-delivery rule and the buy-in deadline have nothing to decide.

Most weeks in a settlement year are that week, which is precisely why a fixture built from a representative week proves nothing about this class.

What to do about it

Obfuscation with default settings is not the problem here and the base measurement says so on five profiles. RenameMembers is where the care goes: exclude option keys and record field names that cross into an installed library. See Protect Members.

In the code, make an unusable calendar an error rather than a market that never shuts. A settlement library that receives no holiday list should refuse to compute a date, not compute one over an implied seven-day week - and if you cannot change the library, assert the list is non-empty and contains the dates you expect before you hand it over.

Then move the check off the engine's own state - and if the settlement service is a Node process, protecting Node.js source code covers what protection can and cannot do there. Ask the depository whether it is open on the date you computed, or reconcile your due dates against the venue's published calendar as an independent artifact. A check that reads the same list the date was derived from can only ever confirm your own arithmetic.

Frequently asked questions

Can obfuscation change a settlement date?

Protection with default settings did not, on any of the five profiles measured. Member renaming did: renaming the market calendar member meant the caller's holiday list stopped being found, and due dates were then computed over a market with no closed days at all.

How many deliveries were affected?

Ten of forty fell due on a day the exchange was genuinely shut when the holiday list was renamed, six of them on one holiday. Renaming the weekend list instead put twelve of forty on a Saturday or Sunday.

Why did the desk's own check not catch it?

Because the check asks whether anything fell due on a closed day, and it answers that question from the same calendar the due date was computed from. With the calendar lost there are no closed days, so the check reported zero and the run passed. The check is truthful and useless simultaneously.

What happened to the buy-ins?

Renaming the buy-in deadline reverted four days to the library's thirty and the seven mandatory buy-ins fell to zero, with every other figure on the report - settled, failing, fail charges - identical to the correct run.

Did any arm make the report look better than reality?

Yes. Renaming the partial-delivery flag let two half-delivered lines discharge their obligations, so settled rose from thirty-two to thirty-four, failing dropped from eight to six and buy-ins from seven to five. The broken run reads like a good week.

What should a settlement engine do with a missing calendar?

Refuse. An empty holiday list is indistinguishable from a market that never closes, and a library cannot tell the difference. Assert the list is present and contains the dates you expect before you use it, and validate computed due dates against the venue's published calendar as an independent artifact.

Is this specific to one obfuscation target?

No. The ES5 and modern targets were measured on every arm and agreed throughout, and the base column with no member renaming matched the unprotected run on both targets plus the two emit-gate profiles and the string-encoding profile.

Related reading