Decisions › D16

A composite names the members that caused it, so one fact counts once

Decision
D16
Date
2026-10-23
Status
Accepted
Area
contract

Context

Collapsing a knock-on into its failed ancestor runs in one direction: down the parent edge. That is right for a wire (a dead adapter explains its silent boards) and backwards for a group, whose verdict is caused by its members. Three probes against the real contract code showed it, with no hardware: the rig row and a board's own report counted one missing board twice; a group at error hid its failed member; and the computer's own checks swallowed the rack below.

The decision

An additive field on a status record, caused_by, lists the entity paths of the members whose own reports caused this record. A record that is not stale and names members, all of which self-report a problem, counts as those members' consequence and is not counted again. A record that names nothing, names an OK member, or is itself stale is its own cause, so a partial list never hides a problem. The composite's own row keeps its level and message, so the black-box rule holds.

Why

The case is made by measurement, not by a quote: the report prints the three probe outputs, each with and without the field. The chip read “IO 2” for one missing board before the fix.

“In black-box design it's up to each lower-level black box to self-report what it means in the context of THAT black box.”

Zach Yamaoka, 22 Oct 2026

Options considered

OptionVerdictReason
Leave the rule as it isRejectedThe measured double count and the hidden failed member.
A second tree edge for membershipRejectedMembership lives on the composite's records. The rig composes things scattered across the connectivity tree; medkit's areas and functions are the same kind of cross-cutting group.
caused_by on the composite's recordChosenPrecedents: AUTOSAR's consecutive faults, Icinga's blame and root cause, Alertmanager's inhibit rules.

Consequences

  • The stock view keeps working: to_diagnostic_status appends one value, caused_by, so a person in a stock viewer still reads who caused it, and stock → v0 → stock stays the identity.
  • The Computer's own checks stay a leaf beside the tree, so a full disk is not the cause of a board's fault.
  • The schema string did not change (still v0, revision 0.1): a v0 reader ignores the field.

Evidence

Commits in the app's repository (private):

  • 383fa9a 2026-10-23 Host round 3: caused_by
  • ebf382a 2026-10-23 Report: diagnostics rollups, five ways

← All decisions