Skip to content

fm: extract shared keyed-case adoption scaffolding from the saga and certificate engines #11246

Description

@smklein

The saga and certificate diagnosis engines (nexus/fm/src/diagnosis/saga.rs
and arriving in #11238, certificate.rs) each carry a near line-for-line copy of the same bookkeeping around parent-forwarded cases:

  • an UninterpretableCase enum (ForeignFact, Disagreeings, NoFacts)
  • the loop that closes uninterpretable cases with a "cannot interpret case" comment and a "closing uninterpretable case" warning
  • the BTreeMap Entry::Vacant/Occupied loop that dedups cases by key, keeping the lowest CaseUuid and closing the rest as duplicates

The uninterpretable half also appears a third time in physical_disk.rs.
Per-engine fact modeling (what a parsed case's payload looks like) is, and SHOULD be,
engine-specific as described in RFD 603, but this adoption scaffolding is
engine-agnostic, and a fix to the tiebreak or the close messages today has
to be made in three places.

Proposal: a helper in diagnosis/mod.rs along the lines of

      fn adopt_keyed_cases<K: Ord + Display, P>(
          builder: &mut SitrepBuilder<'_>,
          de: DiagnosisEngineKind,
          parse: impl Fn(&Case) -> Result<(K, P), impl Display>,
      ) -> BTreeMap<K, (CaseUuid, P)>

that saga.rs and certificate.rs call, keeping only their own parse_case
bodies. physical_disk.rs could adopt the uninterpretable half in the same
change or a follow-up. Existing tests in all three engines already cover
uninterpretable and duplicate cases.

Activity

  1. added
    fault-managementEverything related to the fault-management initiative (RFD480 and others)
    on Sep 4, 2026
  2. self-assigned this
    on Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

cleanupCode cleanlinessfault-managementEverything related to the fault-management initiative (RFD480 and others)

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions