Measured, not asserted

Does obfuscation break control chart rules?

Every reading in this test is genuine and every reading is inside the drawing tolerance. The process has shifted about half a sigma and stayed there, which is the exact condition a control chart exists to catch and no individual measurement can.

The detector, not the data

Ten subgroups of four, a centre line at 12.5000 mm and a process sigma of 0.0060. The first three subgroups sit on the centre line. From the fourth onwards the process has walked up and stayed up, and the tenth subgroup's mean breaches the upper control limit. Three signals fire: a point beyond the limits, seven subgroups in a row above the centre line, and six rising in sequence.

None of those three signals is a property of any single measurement. They are properties of the DETECTOR: how the readings are grouped, and which patterns the chart is configured to look for. Both live in the options object, and neither of them can change a plotted value.

That is what makes a control chart an unusually clean place to measure this class of change. There is no arithmetic to get wrong. Everything that can move is a decision about what counts as evidence.

Each half is survivable

Renaming ^(subgroupSize)$ made the library revert to a subgroup size of one. Control limits on a chart of subgroup means are tighter than the spread of individual readings by the square root of the subgroup size, so the limits went from 12.4910..12.5090 to 12.4820..12.5180 -- nearly twice as wide.

The beyond-limits signal disappeared. The other two survived, because a run above the centre line and a rising trend do not depend on the limits at all. The chart still reported SIGNALLED=true, and an engineer looking at it would still have gone to the machine. The answer was a true SUBSET of the right answer, which is the same shape the recall article in this pass is built around.

Renaming ^(detectionRules)$ alone was caught: the library fell back to beyond-limits only, and the caller's completeness rule -- which asserts that all three configured rules were actually applied -- refused the chart with run-of-seven was not applied. The rule names in that assertion are literal text, not property names, which is why it survived the rename that took the option carrying them.

Three names together and the shift disappears

^(subgroupSize|detectionRules|requireSignalCheck)$ released the run with SIGNALLED=false []. No signals at all. The limits are the wide ones, the only rule applied is beyond-limits, no point reaches the widened limits, and the flag that would have consulted the completeness check went in the same pattern.

Every plotted value in that chart is correct. Every subgroup mean is right. The centre line and sigma are right. A reviewer comparing the chart's data against the gauge records would find perfect agreement. The process has moved half a sigma and the chart, correctly rendering correct data, says it has not.

It is worth being precise about which cells are dangerous. Each half alone left a signal standing: subgroup size alone kept two signals, and rules plus flag together kept one, because the tenth subgroup happened to be extreme enough to breach even the narrow limits. It took all three names for the shift to vanish. Testing the union alone would have found this; testing only the halves would have missed it -- which is the exact opposite of the lesson an earlier pass in this series recorded, and both are true. Test the halves AND the union.

A chart over unreadable values reports control

The record-field side produced a result worth its own paragraph. Renaming ^(valueMm)$ left every configuration line correct -- ten subgroups of four, limits 12.4910..12.5090, all three rules applied, checked by detection-completeness-check(all three rules applied) -- and reported SIGNALLED=false.

Subgroup means computed from unreadable values are NaN, and every comparison against NaN is false, so no rule can fire. The completeness assertion passed because it checks which rules were applied, not what they were applied to. A procedural completeness check is blind to the data, in the same way the recall article's completeness check is blind to a graph with no edges.

The opposite direction also occurs. Renaming ^(subgroup)$ left the library unable to group anything, so it charted forty subgroups of one against limits computed for four and produced eight signals where there should have been three. That failure is loud and expensive rather than silent, and a shop that chases eight false alarms notices within a shift.

What to do about it

None of this happens under default protection, and none of it happens to names you did not name. Member renaming is opt-in and the pattern is yours; keep it away from the option keys and record fields that cross into an installed charting library.

Then make the chart assert its own sensitivity. Print the subgroup size, the limit width and the rule set as values on the chart itself, and check them against the control plan rather than reading them off a settings screen. A populated screen is evidence that entries exist, never that anything found them.

Add one assertion the procedural check cannot fake: require the number of points charted to equal the number of readings taken, and require the subgroup means to be finite before they are compared. Both are one line, both catch a class of problem that has nothing to do with obfuscation, and between them they close the two silent cells measured here.

Frequently asked questions

Does obfuscation change what a control chart plots?

Not on its own. Across five presets and five areas measured this pass, protection alone left every output identical to the unprotected run -- twenty-five comparisons, no differences. What changed behaviour here was member renaming, a separate opt-in option whose pattern you write.

What was the worst result measured?

One pattern naming the subgroup size, the detection rule set and the flag in front of the caller's completeness check. The chart reported the process in control while it had shifted half a sigma and stayed there, with every plotted value correct.

Why did losing the subgroup size alone not hide the shift?

Because a run above the centre line and a rising trend do not depend on the control limits. Widening the limits removed the beyond-limits signal and left the other two, so the chart still signalled. The answer was a true subset of the right answer.

What caught the lost rule set?

A caller-supplied rule asserting that all three configured detection rules were actually applied. It survives the rename because the rule names in it are literal strings rather than property names, and text does not move when a name does.

Why did a chart over unreadable values report no signal?

Subgroup means computed from unreadable values are NaN, and every comparison against NaN is false, so no rule can fire. The completeness check still passed because it verifies which rules ran, not what they ran against.

Is this specific to obfuscation?

No. Any change to the names crossing the boundary into a charting library produces it -- a version bump, a serialisation hop, a configuration migration. Renaming is a repeatable way to find out how your chart behaves when it happens.

What is the smallest useful change to make?

Require the number of charted points to equal the number of readings taken, and require every subgroup mean to be finite before comparison. Between them those two lines close both of the silent failures measured here.

Related reading