Measured Behaviour

Does obfuscation break energy isolation verification?

An isolation is complete or it is nothing. Every energy source on the machine has to be broken, locked and proved dead, and the machine is live if one is missed. That makes it a completeness question - and completeness questions are asked over a list, which is itself a name that can go missing.

Locks on a board are not sources covered

We built a maintenance morning the way one runs: eight work orders across five machines, an energy-source survey saying what each machine holds, a table of isolation points saying where each source is broken, twenty-two locks actually hanging on the board, a required try-out, and a stored-energy dwell before anyone starts work.

The machines are deliberately not simple. A press holds four sources - four-eighty volts, hydraulic pressure at 210 bar, compressed air, and the gravity load of the ram itself. A mixer holds three, one of which is a flywheel that keeps turning long after the power is off. An oven holds electrical, gas and residual heat.

The correct run releases five jobs and holds three. It counts twenty-three energy sources across the eight jobs and reports twenty-one isolated and proved. One press job is held because the gravity ram was never pinned - three real locks are on the board for it and the fourth source has nothing on it. One mixer job is held because every source was locked but the flywheel brake was never proved dead. One conveyor job is held because it was released five minutes into a fifteen-minute dwell.

Protected with default settings on all five profiles, behaviour was identical. Nothing below came from obfuscation on its own.

A machine with no sources is isolated from everything it has

Renaming the energy-source table releases all eight jobs and holds none. Sources considered goes from twenty-three to zero. Sources isolated goes from twenty-one to zero. Sources left uncovered goes from one to zero.

And the plant's own isolation rule passes, printing: eight jobs, zero of zero energy sources isolated and proved, none released live. Every clause in that sentence is true. Eight jobs really were presented. Zero sources really were left live on a released job, because as far as the running code was concerned no machine had any source at all.

This is the empty-set problem in its most physical form. An empty list of obligations is indistinguishable from a set of obligations all met, and the count that would have told you the list was empty is taken from the list. The press with the unpinned gravity ram is released, and somebody puts their hands into a machine that is holding a load.

The reading everybody actually trusts does not help either. There are still twenty-two locks on the board and every one of them is real. Locks applied has never answered the question sources covered, and after a rename the two counts come from different names.

The same check passes when the plant stops

Rename the isolation-point table instead, or the field on a point record that says which source it breaks, and the result inverts: zero jobs released, all eight held, twenty-three sources considered and none isolated. Maintenance stops. Somebody notices before lunch.

Here is the part worth carrying. The plant's rule passes in that arm too, printing: eight jobs, zero of twenty-three energy sources isolated and proved, none released live. It is true - nothing was released live, because nothing was released at all.

So the same check, in the same words, passes when every machine is released with its sources unexamined and when no machine can be released at all. It is closed by construction: the engine holds any job with an uncovered source, so the assertion nothing was released live is an invariant of the code rather than evidence about the plant. It cannot fail, and a check that cannot fail is not measuring anything.

The strict control, switched off on its own

The try-out requirement is what turns a lock on a handle into a measurement: the machine is started against the isolation and does not run. Rename it and it reverts to the only default a library can ship, which is to trust the lock.

Measured: released goes from five to six and the unproved counter goes from one to zero. The mixer job whose flywheel brake was locked but never proved is released. One job, one line, and the configuration screen now reads not required (the lock is trusted without proving it).

Renaming it together with the check that would have caught it produces the same figures with the check line reading unchecked, and renaming it together with the source table is byte-identical to the source table alone. Once there are no sources, the strict control has nothing left to be strict about - it was contributing nothing to remove.

What the dwell and the point records did

Two smaller arms are worth recording because they show how unevenly the damage is distributed across one options object. Renaming the stored-energy dwell releases the conveyor job that was let go five minutes into a fifteen-minute wait: released moves from five to six, and the screen simply stops naming a dwell. Nothing else in the run moves.

Renaming the field on a point record that says which source it breaks is the loud end of the same object. Every point still exists, every lock is still on the board, and not one point can be matched to a source - so all twenty-three sources read uncovered and every job is held. The isolation points and the energy sources sit two lines apart in the same literal, and one stops the plant while the other empties it.

That asymmetry is the argument against reasoning about a member pattern by how important the option sounds. Both of these are plant safety configuration; both are equally central; the direction each fails in is decided by what the library does with an empty table, and the library makes that choice, not you.

What to do about it

Compare against an independent expectation, never against the traversal's own state. The number of energy sources a machine holds comes from the energy-source survey, and that survey is a document, not a runtime table. Assert the count from the document against the count the software used, and treat a machine reporting zero sources as an error rather than as a machine that is already dead.

Then assert the mapping rather than the total: sources covered must equal sources surveyed, per machine, named individually. Twenty-two locks on a board is a number that reconciles against nothing.

On the protection side, scope the member pattern so it cannot reach the survey or the point records. Protect Members documents how MemberRegexp matching works, and it is worth spending ten minutes on before pointing a broad pattern at a bundle that carries plant configuration. If you are working out where protection belongs in a plant estate more generally, zero-trust JavaScript architecture covers which decisions can safely sit in a bundle at all.

Frequently asked questions

Did obfuscation change any isolation decision on its own?

No. On all five profiles - the ES5 target, the modern target, both emit-gate configurations and the string-encoding profile - the protected bundle behaved identically to the original. Every difference came from member renaming reaching the isolation configuration or the lock records.

What did renaming the energy-source table do?

It released all eight jobs and held none. Sources considered fell from twenty-three to zero and sources isolated from twenty-one to zero, including the press job whose gravity ram had never been pinned.

Did the plant's isolation rule catch it?

No, and it passed truthfully, printing eight jobs and zero of zero energy sources isolated and proved with none released live. Nothing was released live because no machine was recorded as having any source to leave live.

Does the number of locks on the board help?

No. Twenty-two real locks were still hanging in the arm that released every job. Locks applied has never answered sources covered, and after a rename the two counts are taken from different names.

What happened when the isolation points were renamed instead?

The opposite: zero jobs released and all eight held, so maintenance stops and somebody notices quickly. The same rule passed in that arm too, which is what shows the rule is closed by construction rather than measuring anything.

What did losing the try-out requirement do?

Released went from five to six and the unproved counter from one to zero. The mixer job whose flywheel brake was locked but never proved dead was released, and the screen simply reads that a try-out is not required.

What should we assert instead?

Assert the mapping against the machine's own energy-source survey: sources covered must equal sources surveyed, named per machine, and a machine reporting zero sources should be an error rather than a machine treated as already dead. Scope the rename with MemberRegexp so the survey is never a candidate.

Related reading