Measured Behaviour

Does obfuscation break veterinary withdrawal periods?

A withdrawal-period calculator has obvious failures everybody tests for: a date that will not parse, a product that is not on the data sheet, a period that comes back negative. It has one almost nobody tests for, because the number it produces stays plausible - the LENGTH of the interval. We measured what a rename does to it.

The one control between a treated animal and the food chain

A withdrawal period is not a quality target. It is the interval, counted in days from the last dose, during which the residue of a medicine in muscle, liver, kidney or milk is still above the maximum residue limit. Slaughter one day early and the meat is not slightly worse than it should be. It is legally unfit, and once it has been eaten it cannot be recalled.

We built the calculation as it actually looks. Two licensed products with their data-sheet periods - 28 days meat and 7 days milk for one, 14 and 3 for the other. A cascade multiple of three for anything prescribed outside its licensed species. A floor of 28 days for a product that is not on the unit's data sheet at all. A clock that starts at the last dose of a course, not the first. Milk withheld for its own period. Five treatments, six presentations, an eighty-day window.

The correct run refuses four of the six presentations. A sheep dosed with a cattle product under the cascade needs 42 days and is presented on day 40. A two-day course clears on day 40 and the animal is presented on day 39. An unlisted product carries the 28-day floor and the animal is presented on day 20. The same sheep's milk needs nine days and is taken on day 12. Two presentations pass, 960kg leaves the plant, and nothing goes out inside a period. What a carcass carrying a lesion is allowed to become is measured in the disposition article.

That is the baseline. Every figure in it came off a record that somebody wrote by hand in a medicines book, and every one of those records survives every arm below intact.

A length is not a value on any record

Here is the part that decides everything else. No record in this system carries a withdrawal period. The treatment record carries a product, a route, a dose count, two dates and a flag saying whether the prescription was inside or outside the product's licence. The data sheet carries a number of days. The period is what you get when the two are read together.

So the period has more than one way to be shortened, and none of them is a wrong number. We measured five of them separately.

Rename the record flag that says a treatment was given under the cascade and the library sees an absent flag. An absent flag is falsy, and falsy means on-label - which is true of the overwhelming majority of treatments, and true of every treatment the data sheet in front of it describes. The 42-day period becomes 14, the 9-day milk period becomes 3, and both are genuine published figures for that product.

What renaming the off-label flag actually did

Protected on the ES5 target and again on the modern target with member renaming scoped to that one field, the numbers are the same on both. Presentations stayed at 6. Passed went from 2 to 4. Refused went from 4 to 2. Released weight went from 960kg to 1,838kg. And the counter we keep outside the bundle - kilograms released while the animal was still inside the period its prescribing vet wrote in the book - went from 0.00 to 878.00.

The plant's own residue check passed in both runs. It has to. It asserts that every presentation was either passed or refused and that the weight reconciles, and both of those are statements about the periods this run computed. A run that shortens every period passes more carcasses, refuses fewer, and satisfies the check on every one of them.

The same collapse is reachable through the configuration. Renaming the cascade multiplier itself produced counters identical to the record-field arm - 4 passed, 1,838kg out, 878.00kg inside period - because a multiplier of one and a flag that reads false are the same arithmetic. The difference is what an audit can see, and it matters more than it sounds.

The configuration arm flips a printed line: the effective configuration stops saying that off-label use multiplies the period by three and starts saying it multiplies it by one. The record-field arm changes nothing in the configuration at all. Dump the effective settings and diff them against policy and you catch one of the two. The one you do not catch is the one that leaves no trace anywhere except in the answer.

Four other ways to shorten the same interval

Because the period is assembled rather than stored, we measured every assembly step on its own. The clock: rename the option that starts it at the last dose and it starts at the first, which is correct for a single-dose treatment and wrong by the length of the course for everything else - 3 passed, 1,260kg out, 300.00kg inside period. The unlisted floor: rename it and it reverts to the vendor's zero days, which is not a shorter wait but no wait - 1,240kg out, 280.00kg inside. Milk: rename the option that withholds it and 850 litres of it go into the tank inside a nine day period.

None of those is a crash, an exception or an implausible figure. Each is a shorter interval that a competent person could defend if they did not know what the other reading was.

The union of the cascade multiple and the clock is additive: 5 passed, 2,138kg out, 1,178.00kg inside period, which is exactly 878 plus 300. They compound because they act on different animals. That is not always true, and the herd-testing measurement in this series has the case where four separate names produce one identical outcome and their union adds nothing at all.

Why a test suite would not have caught it

We built the negative control first, before measuring anything, and it is the fixture almost anybody would write. Every treatment is a single dose of a listed product used inside its licence.

In that fixture the off-label arm is byte-identical to the correct run. Not similar - identical. With one dose the first and last dose fall on the same day, so the clock option cannot matter. With an on-label prescription the cascade multiple is never reached. With a listed product the unlisted floor is never reached. Every arm that shortens a period in the real fixture is inert in the test fixture, and inert for reasons that have nothing to do with obfuscation.

This is not a criticism of anybody's test suite. A withdrawal calculator is tested from the data sheet, and a data sheet describes exactly one thing: a licensed product, in its licensed species, given as directed. The cases that expose the defect are the ones the data sheet does not describe.

What to do about it

First, the reassuring part, and it is the largest part. We protected this bundle on five profiles - the ES5 target, the modern target, both emit-gate configurations and the string-encoding profile - and all five produced behaviour identical to the unprotected original, twice, diffed. Obfuscation does not break withdrawal periods. Member renaming aimed at the names a withdrawal calculation is made of does.

So scope member renaming. If you use it at all, point it at your own internal helpers and keep it away from the names that cross into a library, a data sheet feed, a JSON document or a database column. The member renaming documentation covers the regexp that scopes it, and this measurement is why it matters.

Second, add the counter. The figure that separated the two runs here is not on any dashboard: kilograms released inside a period, measured against a clearance date held outside the software. Passed, refused and released weight all reconcile in every arm. The number that does not reconcile is the one nobody was computing.

Third, treat the effective configuration as an artifact. Dumping it and diffing it against policy caught four of the five arms here. It did not catch the record field, and the record field was the one worth catching - so the dump is worth having and is not worth trusting on its own.

Frequently asked questions

Does JavaScript obfuscation break withdrawal period calculations by default?

No. We protected the same withdrawal bundle on five profiles - the ES5 target, the modern target, both emit-gate configurations and the string-encoding profile - and all five produced behaviour identical to the unprotected original. We ran the measurement twice and diffed the two captures. The defect only appears when member renaming is pointed at the property names the calculation is assembled from.

What exactly went wrong when the off-label flag was renamed?

The library could no longer tell that a prescription had been written outside the product's licence, so it did not apply the cascade multiple. A 42-day meat withdrawal became 14 days and a 9-day milk withdrawal became 3. Both of those are genuine published figures for that product; they are simply the figures for a different use of it.

Did anything crash or report an error?

No. Every run returned success. The plant's own residue check passed in every arm, because it asserts that presentations reconcile against the periods the run computed, and they always do. That is not a defect in the check. It is what the check is about.

How much meat went out inside its withdrawal period?

878kg across six presentations in an eighty-day window, measured against clearance dates held outside the software. The same bundle with the cascade multiplier renamed instead of the flag produced the identical figure. Losing both the multiple and the clock took it to 1,178kg.

Would our test suite have caught this?

Probably not. We built the obvious fixture first - every treatment a single dose of a listed product used on label - and in that fixture the arm is byte-identical to the correct run. One dose makes the clock option irrelevant, an on-label prescription never reaches the cascade multiple, and a listed product never reaches the unlisted floor.

Is dumping the effective configuration a sufficient check?

It is worth having and it is not sufficient. Four of the five arms we measured flip a printed configuration line, so a dump-and-diff catches them. The fifth is a record field, and it changes nothing in the configuration at all - which is the one that matters most, because it leaves no trace anywhere except in the answer.

What is the safe way to obfuscate a system like this?

Use the full transformation set on your own code and scope member renaming to names you own on both sides. Anything that crosses into an installed library, a marketing-authorisation feed, a JSON document or a database column should be excluded by regexp. Then add a residue counter measured against a clearance date the software did not compute, so a shortened interval has somewhere to show up.

Related reading