Measured Behaviour

Does obfuscation break landing declaration checks?

Nothing in this area is missing. The skipper's declaration is a real estimate on a real form; the weighbridge figure is a real measurement on a real scale. A reconciliation exists because the two disagree, and the only questions it answers are which one becomes the record and whether anybody looks at the gap.

A margin that is correct, applied to the wrong population

We built one trip: twelve species lines off one vessel, 19,201kg over the weighbridge against 19,205kg declared. Most of the lines agree closely, because most skippers estimate well. Two do not. One cod line was declared 1,900kg against 2,870kg weighed - 970kg light. One haddock line was declared 2,950kg against 2,010kg weighed - 940kg heavy.

The correct run applies a ten per cent margin of tolerance per species, finds cod out by 11.13 per cent and haddock out by 16.01 per cent, raises two discrepancies and fails.

Now look at the trip total. Declared 19,205kg, weighed 19,201kg. A gap of four kilograms in nineteen tonnes - 0.02 per cent, well inside any margin anybody would write. The two errors that matter are almost exactly the two that cancel.

Protection alone changed nothing on five profiles, measured twice. Renaming the key that says per species - one boolean, on the same configuration literal as the margin itself - moved the comparison to the trip total. Discrepancies went from two to zero. The gaps list came back empty. The check passed.

The margin is still ten per cent. It still prints as ten per cent on the configuration screen. Every declared figure and every weighed figure is unchanged and correct. All that moved is the population the comparison is taken over, and that is not a presentational detail - it is the whole of the control. This is what a broad RenameMembers pattern over a configuration literal does; the mechanics are in Protect Members.

Which of two genuine figures becomes the record

The second question the area answers is which number is the record. This authority says the weighbridge; the library's default says the declaration - and a declaration is a real number, entered in good faith, that appears on a real form.

Renaming that key took the recorded total from 18,817kg to 19,205kg. The off-record counter, which measures the legitimate two per cent ice-and-water deduction, went from 384kg to minus four - the record now exceeds what was actually weighed.

But this arm still failed, and that is worth understanding. The comparison is independent of the record: the engine still put the declaration next to the weigh note, still found cod 11.13 per cent out and haddock 16.01 per cent out, and still raised two discrepancies. Losing the source of truth changes what goes into the books. It does not stop anybody noticing.

Renaming the flag that says to honour the weigh note at all is the loud-looking arm that is actually quiet: discrepancies to zero, check passed, and a configuration screen that says plainly a weigh note that disagrees is filed without action. That sentence is the difference between this arm and the per-species one. Both produce zero discrepancies. Only one of them says so.

Two ways for a real disagreement never to be compared

The other two keys on this object both decide which lines get compared at all, and both are quiet in a way that is easy to miss because the lines are still there.

This port weighs every landing; the library's default weighs a fifth. Renaming that key left weighed lines at three of twelve, put nine lines in the uncompared column, and dropped the weighbridge total from 19,201kg to 8,777kg. One of the two discrepancies survived; the other was in a line nobody weighed. The recorded total came out at 20,006kg - above what was weighed and above what was declared, because the unweighed lines fell back to the estimate.

This authority has no de-minimis line; the library's default stops looking below eight hundred kilograms. Renaming that key moved four lines - the whiting and the monkfish - into the uncompared column while leaving both real discrepancies intact. On this trip it costs nothing. On a trip where the under-declaration is in a small line, it is the whole failure, and the run reads exactly the same.

Widening the margin is the arm that looks most like a normal configuration mistake and behaves like one: the vendor's twenty-five per cent covers both an 11.13 and a 16.01 per cent gap, so discrepancies go to zero. Renaming both the margin and the per-species flag is identical in every number to renaming the margin alone. Two routes to the same silence, and the union tells you nothing the halves did not.

What the negative control shows

The control here is the trip almost everybody constructs: the same twelve lines with every declaration exactly equal to its weigh note. Inventing a plausible disagreement is extra work, so the second column gets the number from the first.

A reconciliation over data that agrees cannot fail. Neither can a broken one. The control and the per-species arm differ by exactly four kilograms in a declared total of nineteen tonnes, and by nothing else at all - same checked count, same weighed count, same recorded total, same off-record figure, same zero discrepancies, same empty gaps list.

Nine of the ten counters are identical. The one that differs differs by 0.02 per cent. If your fixture's declarations match your fixture's weigh notes, no assertion over that output can tell you whether the reconciliation works.

The loud arms are the value arms, as everywhere else in this series. Renaming the weighed-weight field left nothing readable and the engine refused before reconciling anything. Renaming the declared-weight field made the control itself fail. Losing a quantity is loud. Losing the rule about which quantities to compare is not.

What to do about it

Scope the member pattern away from configuration keys and record field names.

Then take the aggregation question seriously as a control rather than a display choice. Per species and per trip are not two views of the same check; they are two different checks, and one of them is structurally unable to see compensating errors. If your margin is applied over a total, a skipper who is light on one species and heavy on another passes every time, and no amount of tightening the margin will change it.

Then report the counters that separate the arms. The uncompared count and the weighed count moved sharply in three of the five arms above and neither appears on a reconciliation summary. A line that was never compared is not a line that agreed, and the two look the same in every report we have seen.

Finally, keep the artefact and the reading of it separate in your head. Every weigh note in every arm above was printed, stamped, filed and archived - including the arms in which nothing read the number on it. A document being produced is evidence that a process ran, never that anything used its result. That distinction is the whole of evidence-driven compliance work, and it applies well outside fisheries.

Frequently asked questions

Does obfuscation break landing declaration checks?

Not on its own. Five protection profiles produced identical output on the same fixture, twice. What broke the check was member renaming reaching the reconciliation configuration.

Which key mattered most?

The one saying the margin is applied per species. Renaming it moved the comparison to the trip total, where a 970kg under-declaration on cod and a 940kg over-declaration on haddock cancel to four kilograms in nineteen tonnes. Two discrepancies became zero and the check passed.

Was the margin itself wrong?

No. It was still ten per cent, still printed as ten per cent, and still applied correctly. Every declared and weighed figure was unchanged. Only the population the comparison was taken over moved.

What happened when the source of truth was renamed?

The recorded total went from 18,817kg to 19,205kg as the skipper's estimate replaced the weighbridge figure, and the off-record counter went from 384kg to minus four. But the comparison is independent of the record, so both discrepancies were still found and the check still failed.

What are the quietest arms?

The two that decide which lines get compared at all. A sampled weighing rate put nine of twelve lines in the uncompared column and hid one of the two discrepancies; a de-minimis floor moved four small lines out of the comparison while leaving this trip's discrepancies intact - but on a trip where the error is in a small line, that arm is the whole failure and reads identically.

Would our test suite catch this?

Only if your declarations disagree with your weigh notes. A trip where every declaration equals its note differs from the defective arm by four kilograms on one counter out of ten, and by nothing else.

How do we protect catch reporting software safely?

Scope the member pattern away from configuration and record names, treat the aggregation level as a control rather than a display choice, and report the uncompared and weighed counts beside the discrepancy count. Protect Members documents how the regexp is applied and what a safe scope looks like.

Related reading