Measured Behaviour

Does obfuscation break combustible cladding restrictions?

A restriction on external wall materials is not one condition. It is three: the building is tall enough, it is used for something the restriction covers, and the product is outside the permitted list. The first two decide whether the third is ever asked - and that is where the interesting failures live.

Three conditions, and only one of them is about the material

The rule everybody remembers is the one about the product: certain classifications may not be used in the external wall. The rule that decides whether that rule applies is the boring one, and it is two conditions long. Above a trigger height, and in a use class the restriction covers.

We built seven external wall build-ups across five buildings. A tall residential block with a polyethylene-cored aluminium composite rainscreen and its window frames. An office block, taller than the trigger, with exactly the same panel. A care home just over the trigger with combustible insulation and compliant cassette panels. A residential block that is 11.6 metres overall and 9.8 metres to the floor of its top storey. A hostel with balcony decking of a permitted classification and no test behind it.

The correct run refuses three: the composite panel, the insulation, and the untested decking. It approves four, signs off 2,840 square metres, and none of it is non-compliant. The window frames pass because they are an exempt component. The office panel passes because offices are out of scope. The low block's panel passes because the regulation measures to the top storey floor level, and that block is below the trigger.

Five names that remove the restriction, and one that weakens it

This is the result worth carrying away, and it is about severity not being graded by how important a name sounds.

Renaming the record field that carries the top storey height, the option listing which uses are in scope, the record field saying what the building is used for, or the master enforcement flag all produce THE SAME COUNTERS: every element approved, 5,150 square metres signed off, and 2,310 square metres of genuinely non-compliant wall among it. Four names, four mechanisms, one outcome - the restriction is gone.

Renaming the trigger height itself does something different. It reverts to the library's 18 metres, which is a real figure that was the threshold in an earlier version of the rule. The tall block is still in scope and its panel is still refused. The care home at 11.4 metres and the hostel at 12 metres fall out of scope. Approved goes from 4 to 6, and 860 square metres of non-compliant wall is signed off.

That 860 is barely a third of the 2,310, and it is by far the more dangerous of the two results. A run that approves everything is a run somebody notices. A run that applies a defensible, historically real threshold and refuses the worst panel in the portfolio looks like a working control. An auditor dumping the effective configuration sees "trigger: from 18.0m" and has to know that the correct answer is eleven.

Two true heights on every record, and only one is read

Every building here carries an overall height and a top-storey floor level. Both were surveyed, both are correct, and an option decides which one the trigger is read against. So one of the two is load-bearing and the other is decoration, and nothing on the record says which.

Rename the top-storey height and the restriction disappears entirely - 2,310 square metres. Rename the overall height and NOTHING HAPPENS, on any counter, because with this configuration it is never read. Two adjacent numeric fields on the same object, surveyed by the same person on the same day, and one of them is the whole control while the other is a comment.

Flip the option and the roles swap. Renaming the option that says "measure to the top storey" makes the trigger read the overall height instead, which puts the low block into scope: approved drops from 4 to 3 and a correctly specified panel is refused. That is the safe direction, loudly.

The practical lesson generalises past obfuscation. Before predicting how a lost field will fail, name the READER of that field. Reviewers protect the field that LOOKS like the important one, and in this file the important one is decided by a boolean somewhere else.

An allowlist fails closed against an unknown entry and open against an unread option

The permitted-classifications list is an allowlist, and allowlists have a reputation for failing closed. Both halves of that reputation are measurable in this one file, and they point opposite ways.

Rename the RECORD FIELD that carries an element's classification and it becomes an entry the allowlist cannot find. Every in-scope element is refused, approved drops from 4 to 3, and 1,740 square metres is signed off instead of 2,840. That is the fail-closed behaviour, and it is real.

Rename the OPTION that carries the list and the library receives no list. A list it cannot read is indistinguishable from one you never supplied, and no library can refuse every material on the strength of a configuration that did not arrive - so the empty case means "no classification restriction configured". Approved goes to 6 and 2,070 square metres of non-compliant wall is signed off.

The allowlist's fail-closed reputation is earned against an unknown ENTRY, not against an UNREAD OPTION. It is worth knowing which of those two your threat model is about. The same distinction decides the answer in allowlists and URL validation, where the list is the whole control.

The exemption list behaves symmetrically and both of its arms are safe: renaming the exempt-components option and renaming the record field that names a component produce identical counters, and both simply refuse the window frames. Approved 3, and no non-compliant area signed off.

What the compliant-estate test does not see

The negative control was the same seven elements specified the way the estate's newer blocks are specified: every product A1, every product tested. Seven approved, 5,150 square metres, nothing non-compliant.

Every arm that takes a building out of scope is inert in it. A restriction that nothing was going to fail cannot be shown to matter by switching it off. The arms it does catch are the ones that refuse a compliant product, and those fail on the first run and get fixed.

This is the third area in this pass with the same shape, and the pattern is now hard to miss: the fixture that demonstrates a control WORKING is systematically blind to the ways that control stops applying. We saw it in sprinkler hazard classification too, where a shed storing what it was commissioned for cannot show that a derived class ever mattered.

What to do about it

Keep the fields that decide SCOPE out of a member-renaming regexp. Not the fields that look like security - the ones that decide whether the security question is asked at all. In this file that is a height, a use class and a trigger, and losing any of them was worse than losing the list of banned materials.

Do not read a threshold's presence as evidence that it is right. A configuration dump that says "from 18.0m" is a passing audit if nobody compares it against the policy that says eleven. Compare effective settings against a written expectation, not against plausibility.

And separate the two allowlist questions in your own head. If the risk is a product whose classification you do not recognise, an allowlist protects you. If the risk is the list itself failing to arrive, it does not, and a run with no restriction configured should be a refusal rather than a pass. That is one conditional, and it is the difference between 2,070 square metres and zero.

Frequently asked questions

Does obfuscation change which materials a building may use?

Not by itself. Protecting the model on five presets without member renaming produced byte-identical output. What changed the approvals was member renaming reaching the names that decide whether a building is in scope.

Which name was the most dangerous?

The trigger height, and not because it was the biggest. Renaming it reverted the threshold to the library's 18 metres - a real figure from an earlier version of the rule - so the run still refused the worst panel and still signed off 860 square metres of non-compliant wall. It looks like a working control in every report.

Why did four different names give the same figure?

Because each of them takes the element out of scope by a different route: no height to compare, no use in scope, no matching use class, or no enforcement at all. Out of scope is out of scope, so all four approved everything and signed off 2,310 square metres.

What happened to the two height fields?

One is read and one is not, and which is which is decided by an option. Renaming the top-storey height removed the restriction entirely; renaming the overall height on the same records changed nothing on any counter.

Do allowlists fail closed here?

Against an unknown entry, yes: renaming the classification field on the records refused every in-scope element. Against an unread option, no: renaming the option carrying the list left the library with no list, which reads as no restriction configured, and signed off 2,070 square metres.

Did the approving body's own check notice?

No. It asserts that every element was approved or refused and that the area reconciles, and both are statements about the scope the run computed. A run in which nothing is in scope approves everything and satisfies the check on every element.

What is the cheapest mitigation?

Treat a missing restriction as a refusal rather than as a pass, and compare the effective configuration against a written policy figure rather than against what looks reasonable. Both are small changes and each removes one of the six arms above.

Related reading