Diagnostics · Evidence · Method
A trouble code, a pile of telemetry, a few thousand lines of C, and a folder of customer complaints — none fully trustworthy. How to weigh them into one defensible cause.
The worked RCA cases assume clean data. Real investigations begin with a heap of evidence of unequal trust: a DTC and its boilerplate description, ECU source code, a measurement log of uncertain provenance, dealer and customer symptom reports in plain English, and a maintenance and repair history that is part signal and part red herring. This monograph is the procedure for turning that heap into a root cause with a mechanism. The organizing principle is grade before you fuse: know what each source can and cannot establish before you let it move your belief. Eight steps follow — provenance grading, temporal-and-cohort anchoring, abductive framing, the impostor test, the physics-and-code referee, reliability-weighted Bayesian fusion, acceptance on convergence, and reporting with residual uncertainty.
The textbook diagram of fault diagnosis starts with a tidy matrix of measurements. The bay does not.
What actually lands on the analyst's desk is a heap of things that disagree. A diagnostic trouble code has fired — say a cell-imbalance code — with a one-line description copied from a standard catalog that was written before this vehicle program existed. There are measurement logs, but you are not sure which firmware they came from or whether the sensor that produced them was itself in spec. There are a few thousand lines of the responsible ECU's C source. There is a folder of dealer write-ups and customer complaints — "loses range in the cold," "clunk on startup," "dash light comes and goes" — vivid, human, and imprecise. And there is a maintenance and repair history showing which of the affected vehicles were touched, when, and for what.
Each of these is evidence. None of them is true in the way a physics equation is true. The DTC can fire for a cause it does not name. The customer can describe a symptom that has nothing to do with the failure. The repair record can show an intervention that caused the problem rather than addressing it. The measurement can be an artifact of the instrument. The code shows what the software can do, not what it did.
So the first thing to internalize is that the units of this investigation are not numbers — they are claims of varying reliability, and the job is to combine claims, not average numbers.
There are three intuitive ways to handle a pile of mixed evidence, and all three are wrong in a way worth naming.
Pour it all in and average. Treat every input as a vote of equal weight and go with the majority. This silently assumes the sources are equally reliable and mutually independent — and they are neither. It lets a hundred low-information complaints outvote one decisive measurement.
Trust the loudest. Anchor on the most vivid or most recent input — usually the customer's words or the DTC's description — and reason outward from it. This is availability, not inference. The DTC's prose in particular is a magnet for this error: it reads like a diagnosis.
Trust only the hard data. Discard the soft inputs entirely and reason from telemetry alone. Cleaner, but it throws away the testimony and history that carry most of the information about when it started and who it happened to — exactly the structure that later separates cause from coincidence.
The fix is one rule applied early: grade before you fuse. Establish what each source can and cannot tell you — and how much to trust it — before you let any of it move your belief about the cause. Everything in this monograph is an elaboration of that sentence.
Provenance grading is the step the case studies skip because their data is clean. In the field it is the most important step.
For each input family, settle three things in writing: what it can establish (the claim it is competent to support), what it cannot (the claim it is routinely mistaken for supporting), and a reliability weight — high, medium, or low — that will scale its influence in fusion. The point of writing it down is that it disciplines you against the §02 traps when the pressure to conclude rises.
| Source | Establishes | Does not establish | Trust |
|---|---|---|---|
| DTC — status bits, freeze-frame, set-conditions | That a monitored quantity crossed a calibrated threshold, and the conditions when it did | The cause. A code is the ECU's hypothesis, scoped to what it can sense | HIGH |
| DTC — text description | A rough family of fault, and a search term | Anything specific to this program; the prose is often generic catalog boilerplate | LOW |
| ECU C source | What the software can do — the reachable logic and its guards | That the suspect path executed; reachability is not occurrence | MED·HI |
| Telemetry / measurements | Physical state over time — the signatures hypotheses must match | Truth in the presence of sensor drift, bias, or wrong-firmware provenance | MED·HI |
| Dealer / customer testimony | That something was noticed, and roughly when — high recall | What the cause is — low precision; descriptions map to many faults | LOW |
| Maintenance / repair history | What was changed and when — a real intervention timeline | Direction of causation; a repair may be cause, fix, or coincidence | MED |
Two grades deserve emphasis because they are routinely misread. The DTC splits into two rows: its machine-set status bits and freeze-frame are high-trust, while its human-readable description is low-trust. And the C source is high-trust for capability but silent on occurrence — it tells you a balancing routine can mis-trigger, never that it did on these cars. Keeping those distinctions sharp is most of the discipline.
Most "clues" are not yet evidence. They become evidence when you place them in time and in a population.
Build a single timeline per affected vehicle and drop everything onto it: the moment the code set, the freeze-frame conditions, the onset date implied by each complaint, every maintenance and repair event, and the windows where measurements went out of band. Disagreements that looked like noise often resolve into structure here — a complaint that predates the code set by months means the code is a late symptom, not the origin.
Then define the cohort precisely: which vehicles are affected, which are not, and what distinguishes the two sets. This contrast is not a formality. It is the asset that later kills impostor explanations, because a true cause must explain not just that the failure happened but why it selected exactly this subpopulation and spared the rest. A hypothesis that cannot account for the boundary of the affected set is incomplete no matter how well it fits the failed cars.
Interpreting a single input in isolation — "the code means X" — invites the §02 traps. Interpreting it against the timeline and cohort constrains it. The same cell-imbalance code means very different things if it sets only on cars built in one plant, or only after a particular OTA update, than if it sets uniformly across the fleet.
Diagnosis is abduction — inference to the best explanation — not deduction from a code to a cause.
Enumerate candidate explanations honestly, and write each one not as a correlation but as a causal chain with three links:
The discipline this enforces is decisive: a hypothesis that predicts no distinguishing signature cannot be tested and does not belong on the list. "It's a firmware problem" is not a hypothesis. "A cell-balancing routine over-discharges the weakest cell during cold fast-charge (mechanism), which appears as elevated internal-resistance rise concentrated in cold-climate cars on firmware ≥ v4.2 (signature)" is — because it tells you exactly what to go measure and which cohort boundary it must reproduce.
Generate several such chains, including at least one boring one (normal wear, sensor artifact). The boring hypotheses are there to be the null the interesting ones must beat.
The most persuasive feature in the room is the prime suspect for being a fake.
This is the central hazard documented in the battery case: a feature that correlates beautifully with the failure but causes nothing, because it and the failure are both downstream of the true cause. Left unchallenged it ends investigations early and wrong — everyone in the room believes it, so no one tests it.
The gate is partial correlation: condition on the candidate true cause and ask whether the seductive feature still predicts the failure. If the association collapses once you control for the upstream variable, the feature was a co-effect — an impostor — and it leaves the suspect list. Run this before the expensive confirmation work of §07, because it is cheap and it routinely deletes the hypothesis you were about to spend a week proving.
Drops out once you condition on the upstream cause. Convincing precisely because it shares the cause's footprint.
Earns the right to the physics-and-code referee in §07. Necessary, not yet sufficient.
A surviving hypothesis is a defendant, not a verdict. Confirmation comes from an independent referee, not from more of the same evidence.
Each surviving causal chain predicts a signature (§05). Confirmation means an independent model regenerates that signature from the proposed cause:
This is where the high-trust sources finally do their work, and why the grading of §03 mattered: low-trust testimony proposed the hypothesis and dated it; high-trust physics and code are what is allowed to confirm it. The referee is also adversarial by design — its job is to falsify the surviving chain, and a chain that survives a real attempt to break it is worth far more than one that merely fit the data it was built from.
input chain = (cause → mechanism → signature), telemetry T, source S
output CONFIRMED · BROKEN · UNDETERMINED
predict ŝ ← model(cause) # physics or code regenerates the signature
if mechanism is physical:
compare ŝ against signature in T under matched conditions
if mechanism is software:
trace path in S; check reachability AND guard(freeze-frame)
return CONFIRMED if ŝ matches and path executes; else BROKEN / UNDETERMINED
Now — and only now — combine the evidence. The combination is reliability-weighted, and it counts independent corroboration only.
Maintain a belief — a posterior — over the competing causal chains. Each piece of evidence updates that posterior in proportion to two things: its likelihood ratio (how much more probable this evidence is if hypothesis H is true than if it is false) and its trust tier from §03 (a low-trust source is allowed only a small nudge; a high-trust confirmation is allowed a large one). In Bayesian terms each datum contributes a weighted log-likelihood-ratio to the running score for each hypothesis.
The rule that does the most work is independence. Ten customer complaints that all trace to the same root cause are one piece of evidence echoed ten times, not ten. Double-counting correlated evidence is how a pile of low-trust testimony stampedes an investigation. Before a datum updates the belief, ask what it is conditionally independent of — and if it shares a source with evidence already counted, discount it.
You do not need a full probabilistic model to use this. The discipline is what matters: weight by trust, update by likelihood ratio, never double-count. A scored table of hypotheses × evidence, with each cell marked for-or-against and the row trust noted, captures ninety percent of the value on a whiteboard.
The acceptance test is not "do I have a smoking gun?" It is "does one mechanism explain everything at once?"
A root cause is accepted when a single causal chain simultaneously satisfies every independent line of evidence:
Convergence of independent evidence types is the standard because it is hard to fake. A story can be tuned to fit the telemetry it was built from; it is far harder for the same story to also predict the cohort boundary and survive the code trace and not contradict the complaint timeline. When one chain does all of that and its rivals do not, you have a root cause. When two chains both survive, you do not yet — and the honest output is two hypotheses plus the discriminating measurement that would separate them.
The deliverable is not a label. It is a chain, a confidence, and the one test that would still overturn it.
Write the verdict as the full causal chain — root cause → mechanism → signature — not as "DTC P0ABC, replace pack." Attach a confidence that reflects the weakest link, not the strongest. And state explicitly the single disconfirming test: the observation that, if it came back the wrong way, would break the chain. A conclusion you cannot say how to falsify is a conclusion you have not finished testing.
Cell-balancing routine over-discharges the weakest cell during cold fast-charge on firmware ≥ v4.2 → accelerated internal-resistance rise → the SOH divergence and the imbalance DTC, concentrated in cold-climate cars.
High on mechanism (code path traced, physics reproduces signature); medium on population bound (cold-climate proxy is coarse). Stated, not buried.
If affected cars on v4.2 that never cold-fast-charged show the same resistance rise, the mechanism is wrong. Run it before committing the fix.
From here the handoff to prognostics is clean: a confirmed mechanism is exactly what a degradation model needs to forecast remaining useful life with and without the intervention. Diagnosis answers why; prognosis turns that why into a maintenance decision.
Each of these is a specific way the procedure above gets short-circuited under deadline pressure.
A handful of vivid complaints set the team's hypothesis, and every later input is read in their light. Mitigation: testimony enters at low trust and only proposes and dates (§03); it never confirms.
Ten reports, one cause, counted as ten. The fleet "agrees" because it is echoing a single root cause. Mitigation: the independence gate (§08) collapses correlated echoes into one update.
The description is catalog boilerplate; the information is in the status bits and freeze-frame. Mitigation: the two-row split in Table 1 — trust the machine-set fields, discount the text.
The suspect C code exists and looks guilty, but its guards are never satisfied in the recorded conditions. Mitigation: §07 demands reachability and guard-satisfaction under the freeze-frame, not mere existence.
A prior service action is the actual cause, or masks the onset, yet is read as background. Mitigation: place repairs on the §04 timeline as events that can themselves be causes, and check causation direction before trusting them.
Run any investigation against this. Each rung is a step you can refuse to skip.
For each source, write what it can establish, what it cannot, and a trust tier. Split the DTC into status-bits (high) and text (low).
Place every code-set, complaint, repair, and measurement excursion on a per-vehicle timeline. Define affected vs. spared precisely.
Write each candidate as cause → mechanism → signature. Discard any that predicts no distinguishing signature. Include a boring null.
Partial-correlation gate: condition on the candidate cause; drop features whose association collapses. Do this before expensive confirmation.
The model must regenerate the signature; the code path must be reachable and guard-satisfied under the freeze-frame. The referee tries to falsify.
Update belief by trust × likelihood ratio. Enforce independence — correlated echoes count once.
One chain must explain the DTC pattern, the signature, the executable path, and the cohort boundary at once — uncontradicted by testimony.
State the full chain, a confidence set by the weakest link, and the single disconfirming test. Then hand off to prognosis.
Grade before you fuse; let the weak evidence propose and the strong evidence confirm; accept only the one mechanism that explains everything at once — and say what would prove you wrong.
Part II — Worked Example
One fleet, one anomaly, and the full pile of mockup evidence. We run all eight steps and let the figures carry the argument. Every input below is fabricated for illustration, but each is shaped like the real artifact it stands in for — and the data hides a known ground truth so the analysis can grade its own detective work.
Before the case, the procedure as a single diagram — the path every piece of evidence takes from the pile to the verdict, including the three gates where hypotheses die.
Drawn as a flowchart it is a path; written as pseudocode it is a loop with guards. The two gates that can reject — the referee and convergence — are why this is iterative, not a straight line.
input E = { DTC, C-source, telemetry, testimony, history }
output a confirmed causal chain, or two chains + a discriminating test
G ← grade(E) # §03 provenance + trust tier per source
T ← anchor(G) # §04 one timeline, one cohort
H ← frame(T) # §05 chains: cause → mechanism → signature
H ← { h ∈ H : partial_corr_survives(h, T) } # §06 drop impostors
for h in H:
h.state ← confirm(h, telemetry, C-source) # §07 physics + code referee
if h.state = BROKEN: continue # falsified → re-frame
H ← { h ∈ H : h.state = CONFIRMED }
P ← fuse(H, G) # §08 Σ trust(e)·logLR(e|h), independence-gated
if converges(argmax P): # §09 explains DTC ∧ signature ∧ code ∧ cohort
return report(argmax P) # §10 chain · confidence · kill-switch
else:
return discriminating_test(top2(P))
Six source classes land on the desk. Step one (§03) is to grade them — before reading a single value for meaning.
# dtc_freeze_frame.json (vehicle EV-201) dtc: P0A80-0F "Replace Hybrid/EV Battery Pack" # generic boilerplate — LOW B2C1-17 "Cell voltage imbalance, pack 1" # mfr-specific — MEDIUM status: 0x2F # testFailed=1 confirmedDTC=1 warningIndicator=1 freeze_frame: odometer 38420 km pack_temp -8.4 °C <-- cold soc 18 % charge_mode DC_FAST_CHARGE <-- charging hard pack_current -142 A balancing_state ACTIVE <-- balancing while cold-charging fw_version 4.2.1
Ignore the P0A80 prose; it is a parts-replacement banner. The freeze-frame is the gold: the code set during DC fast-charge, at −8.4 °C, with cell balancing ACTIVE. Three high-trust facts that, together, already point a finger — balancing is not supposed to be running in those conditions.
/* bms_balance.c — passive cell-balancing scheduler (fw 4.2.1) */ void balance_step(Pack *p) { int16_t t = p->temp_dC; /* pack temp, signed deci-°C */ if (t > BAL_TMAX_dC) return; /* hot guard: OK */ /* BUG (fw 4.2.0): negative temp cast to unsigned wraps high, */ /* so the cold guard never fires below 0 °C. */ if ((uint16_t)t < BAL_TMIN_dC) /* -84 -> 65452, NOT < 50 => no skip */ return; for (int i = 0; i < p->n; i++) if (p->cell_mV[i] - p->min_mV > BAL_THRESH_mV) bleed_on(i); /* drains the weak cell cold */ }
The suspect path exists: a signed/unsigned cast makes the cold cut-off unreachable, so balancing can run below freezing. But the code only proves the bug is possible. Whether it fired on these cars is a §07 question — answered by checking its guards against the freeze-frame.
| Vehicle | fw | Climate | Cold FC | IR rise %/yr | Group |
|---|---|---|---|---|---|
| EV-201 | 4.2.1 | cold | 44 | 9.6 | affected |
| EV-017 | 4.2.1 | cold | 47 | 9.2 | affected |
| EV-066 | 4.2.1 | cold | 39 | 7.9 | affected |
| EV-129 | 4.1.0 | cold | 41 | 2.4 | ok |
| EV-145 | 4.1.0 | cold | 46 | 2.6 | ok |
| EV-103 | 4.2.1 | temperate | 3 | 2.1 | ok |
| EV-118 | 4.2.1 | temperate | 2 | 2.3 | ok |
Read the rows against each other, not in isolation. The affected cars share fw ≥ 4.2 × cold × many cold fast-charges. Crucially, EV-129 and EV-145 fast-charge in the cold just as hard but sit on fw 4.1 — and they are fine. Same usage, different firmware, different outcome.
2026-01-09 · EV-017 — “Range dropped a lot this winter and it charges slower at the fast charger than in the fall.”
2026-02-11 · EV-201 — “Battery warning light came on right after a cold-morning fast charge.”
2026-02-27 · EV-044 — “Loses range when it’s freezing. Better on warm days.”
Imprecise, but the unprompted common thread — cold + fast charge — is a free hypothesis and an onset date. That is exactly what low-trust testimony is for.
| Date | Event | Detail | Relevance |
|---|---|---|---|
| 2025-09-02 | OTA | fw 4.1.0 → 4.2.0 (balancing rewrite) | suspect change |
| 2025-10-30 | OTA | fw 4.2.0 → 4.2.1 fleet-wide | timeline anchor |
| 2025-11-14 | repair | 12V auxiliary battery replaced | red herring |
| 2026-03-18 | repair | imbalance DTC cleared (recurred) | confound watch |
History earns its medium trust here: the balancing rewrite at fw 4.2.0 is the suspect change that dates the whole problem, while the 12V battery swap is a red herring — a real repair on an affected car that has nothing to do with the high-voltage pack. Putting both on one timeline keeps them from being confused.
Now drop every dated fact onto a single axis, and plot the cohort. Most of the answer is visible before any modelling.
Write the candidates as causal chains, each with a signature you can go check. Then attack the most convincing one first.
The null the others must beat. Contradicted on sight by the bimodal cohort (Fig 5) — aging does not split a fleet in two.
Signature: IR rise concentrated in fw≥4.2 × cold × high cold-FC, with balancing ACTIVE in cold freeze-frames. Matches every figure so far.
The story the whole room believes — “fast charging wears batteries.” It correlates. It is also the prime suspect for being a co-effect.
Plausible until you notice affected and healthy cars share the supplier; the split is firmware×climate, not lot. Conditioning removes it.
H2 is the dangerous one because its correlation is real. The test: does fast-charging still predict IR rise once we condition on the cohort — look only within a single firmware×climate stratum?
Two hypotheses are now gone for the price of one cheap test plus one scatter: H2 by conditioning, H3 and H0 by the cohort. Only H1 walks into the referee.
H1 has earned a hearing. Confirmation is two independent checks: the code path must execute under the recorded conditions, and the physics must regenerate the signature.
The freeze-frame recorded pack_temp = −8.4 °C with balancing_state = ACTIVE. Does balance_step() actually run there?
given pack_temp = -8.4 °C → t = temp_dC = -84
hot guard t > 450 ? -84 > 450 → false, continue
cold guard (uint16_t)t < 50 ? (uint16_t)(-84) = 65452
65452 < 50 → FALSE → guard does NOT skip
result falls through to bleed loop → balancing RUNS at -8.4 °C
# matches freeze-frame balancing_state = ACTIVE ✓ reachable AND guarded-in
The path is not merely present in the source — it executes in exactly the conditions the high-trust freeze-frame captured. This is the distinction §07 insists on: capability became occurrence the moment the guard was shown to pass under the recorded state.
Drive the battery-aging model with the H1 mechanism (extra cold over-discharge cycles on the weakest cell) and compare its predicted IR-rise trajectory against the measured one.
Lay every piece of evidence against every surviving hypothesis, mark for-or-against, and weight the row by its trust tier. The posterior falls out.
| Evidence (trust) | H0 age | H1 bug | H2 fast-chg | H3 supplier |
|---|---|---|---|---|
| Freeze-frame: cold + balancing ACTIVE HI | 0 | + + | − | 0 |
| C path executes at −8.4°C HI | − | + + | − | − |
| Signature match (Fig 7) HI | − | + + | 0 | 0 |
| Cohort = fw×climate (Fig 5) MED·HI | − − | + | − − | − |
| Partial-corr collapse (Fig 6) MED·HI | 0 | + | − − | 0 |
| Seasonal onset (Fig 4) MED | − | + | 0 | 0 |
| Complaints: “cold + fast” LOW | 0 | + | + | 0 |
| 12V battery repair LOW | 0 | 0 | 0 | 0 |
H1 is accepted only because a single chain satisfies four independent lines at once, with the testimony consistent and nothing contradicting.
A signed→unsigned cast in the cold balancing guard (introduced fw 4.2.0) lets passive balancing run during cold fast-charge → the weakest cell is repeatedly over-discharged → accelerated internal-resistance rise → the SOH divergence and imbalance DTC, confined to fw ≥ 4.2 × cold-climate vehicles.
High on mechanism (code path traced to the freeze-frame; physics regenerates the signature). Medium on the exact population bound — “cold” is a coarse proxy; the true trigger is cell temperature at charge, which a few cars may hit in mild climates.
Pull fw ≥ 4.2 cold-climate cars that have never cold-fast-charged. H1 predicts they are clean. If they show the same IR rise, the mechanism is wrong — run this before shipping the fix.
A confirmed mechanism is exactly what a degradation model needs. The same aging model from §17, now trusted, forecasts each affected car’s remaining useful life with and without the OTA patch.
Every step earned its keep. Grading kept the DTC prose and the 12V repair from misleading us; anchoring exposed the seasonal onset; framing turned vague worry into testable chains; the impostor gate deleted the fleet’s favourite theory; the referee turned a plausible bug into a confirmed one; fusion let one high-trust fact outweigh ten low-trust echoes; convergence justified commitment; and the report carried a mechanism — not a code — into a maintenance decision.
The method distilled into habits you can carry into the investigation room.
For every source, note what it can establish, what it can’t, and how far you trust it — before any number moves your belief. Grading after the fact is how the loudest clue wins.
Trust the status bits and freeze-frame; treat the human-readable description as a search term, not a diagnosis. They deserve opposite trust tiers.
Place every code-set, complaint, repair, and excursion on a single timeline, and define affected vs. spared precisely. Most “clues” only become evidence once anchored in time and population.
The feature everyone believes is the prime suspect for being a co-effect. Run the partial-correlation test on it before you spend a week proving it.
Source code and physics show what can happen. Confirm it did — trace the path under the recorded conditions, or regenerate the measured signature from the cause.
Ten complaints tracing to one cause are one piece of evidence, not ten. Before a datum updates your belief, ask what it is independent of.
When high-trust sources disagree, re-audit provenance — a bad sensor, a wrong-firmware log, a mismatch. Resolving the conflict usually is the discovery.
Deliver cause → mechanism → signature, a confidence set by the weakest link, and the single test that would overturn it. Keep the evidence trail auditable — diagnoses get re-litigated.
The method braids together abductive reasoning, causal inference, evidence combination, and engineering fault diagnosis. Entry points, grouped by the part of the method they ground.
C. S. Peirce, on abduction (Collected Papers). The original account of reasoning from a surprising observation to the hypothesis that would best explain it — the engine of §05.
P. Lipton, Inference to the Best Explanation (2nd ed., 2004). The modern philosophical treatment of how we rank competing explanations.
J. Pearl, Causality: Models, Reasoning, and Inference (2nd ed., 2009). Confounding, partial correlation, and why a feature can predict an outcome it does not cause — the formal backbone of §06.
H. Reichenbach, The Direction of Time (1956). The common-cause principle: a correlation between two effects of one cause. The impostor, named at its root.
E. T. Jaynes, Probability Theory: The Logic of Science (2003). Bayesian updating as the calculus of reasoning under uncertainty — the trust-weighted, likelihood-ratio fusion of §08.
G. Shafer, A Mathematical Theory of Evidence (1976). Belief functions and the explicit handling of sources with different, partial reliability.
R. Reiter, “A Theory of Diagnosis from First Principles” (1987). Diagnoses as explanations consistent with the observations; the formal notion of a conflict.
J. de Kleer & B. C. Williams, “Diagnosing Multiple Faults” (1987). Candidate generation and reasoning about more than one fault — the discipline behind disciplined hypothesis sets.
R. Isermann, Fault-Diagnosis Systems (2006). Residuals, analytical redundancy, and the sensor/actuator/process fault distinctions underneath the referee step.
M. Blanke, M. Kinnaert, J. Lunze & M. Staroswiecki, Diagnosis and Fault-Tolerant Control (Springer). Structural diagnosability — when measurements can, in principle, separate faults at all.
JCGM / BIPM, Guide to the Expression of Uncertainty in Measurement (GUM). The standard vocabulary for the uncertainty that every measured input carries — the reason telemetry is high-trust but never infallible.
ISO 14229 (UDS) & SAE J1979 (OBD-II). The diagnostic protocols and DTC structure behind §03’s split of the trouble code into machine fields and prose.
K. Ishikawa, Guide to Quality Control. Cause-and-effect (fishbone) analysis — the shop-floor ancestor of structured hypothesis generation.
C. H. Kepner & B. B. Tregoe, The New Rational Manager. Systematic problem analysis: specifying what is and isn’t affected — the cohort discipline of §04.
T. Ohno, Toyota Production System (1988). The “Five Whys” — chasing a symptom back to its mechanism rather than stopping at the first cause.
These are orientation points into large literatures, cited to show the lineage of the method rather than as the source of any single claim here. Titles and years are given so you can find them.