skip to content

How do you audit a decision table for contradictory, duplicated or missing rules?

level: seniorimportance: should knowfreq 34%

answer

  1. Count before you read
  2. Universe versus covered plus infeasible
  3. Same combination, same or different actions
  4. Ask whether each condition really has two outcomes
  5. Findings go to the rule owner

basics

~20 s

Compare the covered combination count against the product of the condition outcome counts to find missing rules. Two rules matching the same combination are duplicated if their actions agree and contradictory if they differ. Every finding goes back to the specification owner before any test is written.

solid answer

~50 s

Audit the table as a set of claims about combinations rather than as a document. Compute the total combination count as the product of each condition's outcome count, expand every don't-care mark, add the annotated infeasible combinations, and compare: a shortfall means one or more combinations have no rule, an excess means rules overlap. Then classify what overlap you found — two rules matching the same combination with **identical actions** are a **redundancy** that will drift apart at the next edit, and with **different actions** are a **contradiction** that nobody can implement or test. The subtlest failure is a condition that is not really binary: an input that can also fail to evaluate adds a third outcome, so the true combination count was larger than the table assumed and whole rules are missing. Every finding is a specification defect, raised with the rule owner before test code exists.

go deeper

for a junior

Be ready to name the three defects a table can carry: a combination with no rule, two rules that agree and repeat, and two rules that disagree. Know that the count of combinations is computable.

for a middle

Explain the arithmetic check end to end: universe as the product of condition outcome counts, covered as the expansion of the don't-care marks, plus the annotated infeasible combinations, then classify any overlap by whether the actions agree.

for a senior

Demonstrate the judgement calls: interrogating whether a condition can fail to evaluate at all, checking for actions that never fire, and routing every finding to the rules owner instead of encoding a guess in a passing test.

for a principal

Own how rule audits fit the delivery process: who signs off a disputed rule, how tables are versioned alongside tests so a rule change shows which cases it touches, and when a table has grown large enough to be split.

## The audit is arithmetic first A decision table's value is that its completeness is computable. The audit therefore begins with a number, not with reading. 1. Compute the **universe**: the product of the number of outcomes of every condition. Six yes/no conditions give 64. 2. Compute the **covered** count: expand each rule's don't-care marks, so a rule with *k* dashes over yes/no conditions stands for 2^k combinations, and sum across the rules. 3. Add the **annotated infeasible** combinations. 4. Compare the total against the universe. If covered plus infeasible is less than the universe, combinations exist that no rule addresses — **missing rules**. If it exceeds the universe, at least two rules match the same combination — an **overlap** that must then be classified. This check takes minutes and catches the failures that reading never does, because a reader's eye slides over the combination nobody thought about. ## Classifying what the arithmetic finds - **Missing rule (incompleteness)**: no rule matches some reachable combination. The system will still do something at runtime, so the defect is not that behaviour is absent but that it is undefined and untestable — there is no oracle for it. - **Redundancy**: two rules match the same combination and their action entries agree. Harmless today, a trap tomorrow: someone edits one copy and the table becomes contradictory without any reviewer noticing. - **Contradiction (inconsistency)**: two rules match the same combination and their action entries differ. This cannot be implemented as written; the implementation resolves it by accident of evaluation order, so the behaviour is whatever the code happened to do. - **A condition that never discriminates**: a row whose outcome never changes any action. Either the condition belongs in a different table or the specification lost the case that made it matter. Removing it halves the table, so it is worth asking about rather than tolerating. ## The failure that arithmetic alone misses The count check assumes the condition stubs are right. The classic hidden defect is a condition that has more outcomes than the table gives it. On a ride-hailing dispatcher, one condition read "the fare estimate exceeds the rider's stored spend cap". The table treated it as yes/no, so the universe was 32. In production the stored cap arrives from an upstream profile service in a locale-dependent number format, and for a minority of accounts the value could not be interpreted as a number at all. The condition therefore had three outcomes — exceeds, does not exceed, and cannot be evaluated — and the real universe was 48. Sixteen combinations had no rule, and because they had no rule they also had no test and no defined behaviour; the dispatcher fell through to a branch that neither surged nor capped. A 4-person team walking the table with a domain expert found it by asking one question of every condition row: *can this predicate fail to produce a yes or a no?* That question, asked of each condition stub in turn, is the cheapest audit step there is, and it is the one candidates leave out. The same class of problem appears whenever a condition depends on data that can be absent, unknown, stale or unparseable. Represent the extra outcome explicitly as a third column value rather than pretending a null is a no. ## Auditing the action side The conditions get the attention, but two action-side checks pay for themselves: - **An action that never fires** in any rule: either the specification lost the rule that triggers it, or the action does not belong to this table. - **Action combinations that are impossible together**: two actions that contradict each other appearing in one rule's entries — refunding and charging the same request, for example. The table's grid will happily accept it; only a human notices. ## Turning the audit into work The findings are **specification defects**, and their value depends entirely on when they are raised. Log each one against a rule identifier, take them to the owner of the rules, and record the resolution in the table itself so the next reader sees a decision rather than a gap. Only then derive cases. Where a rule was disputed and resolved, the resulting test case is worth marking, because it is the case most likely to regress when the rules change again. A useful discipline is to name each test after its rule identifier and to keep the table under version control next to the tests. When a failure comes in, the rule identifier in the test name points at the exact column, and the column points at the exact clause of the specification. When someone proposes a rule change, a diff of the table shows which rules — and therefore which tests — the change touches. ## What separates a senior answer A junior answer describes the table. A senior answer treats it as an audit instrument: quantifies completeness, distinguishes redundancy from contradiction rather than calling both "duplicates", interrogates whether each condition is genuinely two-valued, and above all routes every finding to the specification owner instead of quietly inventing the missing behaviour in a test. Inventing the answer is the worst outcome available, because it produces a green suite that certifies a guess.

  • What is the difference between a redundant rule and a contradictory one?
    Both mean two rules match the same combination. Redundant rules agree on the actions, so behaviour today is well defined but the duplicates will drift apart when one is edited. Contradictory rules disagree on the actions, so the specification cannot be implemented as written and the running behaviour is decided by evaluation order rather than by anyone's decision.
  • You find a combination with no rule and the specification owner is unavailable. What do you do?
    Raise it as a specification defect and leave it undefined rather than guessing. If a test is needed to unblock work, mark it explicitly as encoding an assumption, with the assumption and the open question written into the test name or annotation so a green result is never read as agreed behaviour. Inventing the rule silently converts an open question into a false certification.
  • How would you spot a condition row that is not earning its place?
    Check whether flipping that condition ever changes any action entry. If it never does, either the condition belongs to a different table or a rule that made it matter was lost from the specification. Ask before deleting: a condition that discriminates nothing is as often a symptom of a missing rule as it is of a surplus row.

saying these in an interview costs you the question

  • Calling every overlap a duplicate, contradiction included
  • Assuming every condition has exactly two outcomes
  • Inventing the missing behaviour instead of raising it
  • Auditing by reading the table rather than counting
  • Treating a null or unparseable input as a plain no
  • Deriving expected results from the implementation's branches

context