Zero is not an answer

A parts-count prediction is a sum. Every part it cannot compute still has to contribute something to that sum, and the easiest something is nothing. That is the most dangerous default in reliability prediction.

The shape of the problem

You have a bill of materials with four hundred lines. You run a MIL-HDBK-217F parts-count prediction against it. Eleven of those lines are something the tool has no model for: an unusual connector family, a part whose taxonomy was never mapped, a row where somebody left the quality level blank.

What should the tool do?

The tempting answer is to compute the three hundred and eighty-nine it can and let the other eleven contribute nothing. You get a number. The analysis completes. Nobody has to stop what they are doing.

The number is wrong, and it is wrong in the one direction that matters.

Optimistic is the dangerous direction

Reliability predictions are not symmetric in their consequences. A pessimistic prediction costs you money: you over-specify, you add redundancy you did not need, you argue with procurement. Those are bad outcomes and they are all recoverable.

An optimistic prediction costs you the thing the analysis existed to protect. You ship hardware that fails more often than your numbers said it would, and the numbers are what you handed to the assessor.

A silent zero is always optimistic. It cannot be anything else. Every part quietly dropped from the sum removes failure rate from the system total and pushes MTBF up. Eleven parts out of four hundred might move the answer by a fraction of a percent, or — if one of them was the power supply — by a factor of two. From the outside, the two cases look identical: one number, no asterisk.

That invisibility is the actual defect. A prediction that refuses to answer sends you to find out why. A prediction that answers confidently and wrongly does not.

Four states, not two

The fix is not a flag saying "some parts failed." It is a vocabulary precise enough to say whose problem this is. ReliFrame gives every part one of four states:

ok
The failure rate is a real computed result.
insufficient_data
A required input is not available yet. The model exists and would work; something it needs is missing. This one is yours to fix — supply the field and the part computes.
not_modeled
The component family has no model at all in this standard. Nothing you enter will change that. This one is ours, or it is a sign you have picked the wrong standard for this part.
calculation_error
The engine threw. Not a property of your part — a defect in ReliFrame. Always ours.

The separation earns its keep in the last two. An engine that can describe its own refusal should never report calculation_error; that state is set only by the caller that caught a genuine exception. So when you see it, you know it is a bug report and not a data-entry task, and you know not to waste an afternoon looking for the field you forgot to fill in.

What happens to the total

A part in any of the three non-ok states is excluded from the system rollup, not summed as a zero. Its stored failure rate is a placeholder — never a computed number and never a fabricated one — and the rollup skips it.

The run then says so, in the terms an engineer needs rather than in the terms a status field wants:

11 of 400 parts could not be computed and are excluded from the system total — the system failure rate is a LOWER BOUND and MTBF is optimistic until they are resolved.

"Lower bound" and "optimistic" are the load-bearing words. They tell you which way the error runs, which is the only thing you need to know to decide whether you can proceed.

And when nothing at all computes, there is no system failure rate, no MTBF and no reliability figure. Not zero, not infinity — absent. A run where every part failed has produced no prediction, and the honest representation of no prediction is nothing, not a number that happens to be arithmetically defensible.

The zero that is real

This is the distinction that took the longest to get right, and it is the reason "just check whether the total is zero" does not work.

A system failure rate of zero can be a completely correct answer. Mark every part in an assembly as not fitted and its failure rate really is zero; reliability really is 1.0 for any mission time. That result is not a failure to compute. It is a computation that came out at zero, and suppressing it would be its own kind of lie.

So the guard is on how many parts were computed, never on what the total came to:

const nothingComputed = computedPartCount === 0 && excludedPartCount > 0;

Zero because you modelled zero is an answer. Zero because you modelled nothing is not. A tool that cannot tell those apart will eventually give you one when you asked for the other.

What this costs

Honesty about gaps is not free. It means more analyses come back incomplete, and "the tool would not give me a number" is a worse meeting than "the tool said 47,000 hours." We think that trade is obviously right, but it is a trade, and it is worth naming rather than pretending the strict behaviour is costless.

The argument for paying it is what a prediction is for. It is not a number for a spreadsheet cell. It is an argument that a system will behave a certain way, made to somebody whose job is to doubt you. An argument with a hole in it that you have marked is still an argument. An argument with a hole in it that you have papered over is not — and if the assessor finds the hole before you do, everything else in the pack is worth less too.

A prediction that quietly returns zero for a part it does not understand is not being helpful. It is deciding, on your behalf and without telling you, that the part does not fail.


This is how ReliFrame handles uncomputable parts across every prediction standard it supports. If you think it gets a case wrong, or you have a case it does not cover, write to us — that is a more useful bug report than most.