Metastatic.Analysis.BusinessLogic.ImperativeStatusHandling (Metastatic v0.21.1)

View Source

Detects imperative status/state management that should be replaced with an FSM.

Entity lifecycle is frequently managed with plain imperative code: branching on a status/state field, manually setting it to new values, scattering guards across multiple function heads. This ad-hoc approach is error-prone (missing transitions, invalid state paths, no transition validation) and should be replaced with a proper finite state machine -- Finitomata, gen_statem, a state-machine library, or an equivalent construct in the target language.

Cross-Language Applicability

This pattern is universal and applies to every language that manages entity lifecycle through a discrete set of named states:

  • Elixir: case record.status do, put_change(cs, :status, :active)
  • Python: if self.status == "pending":, self.status = "active"
  • Ruby: case @status, @status = :active
  • JavaScript/TypeScript: switch (this.status), this.status = "active"
  • Erlang: case maps:get(status, Record) of, Record#{status := active}

Detection Strategy

The analyzer collects evidence at three tiers and reports when sufficient evidence accumulates within a single scope (module / class / file):

Tier 1 -- Status branching (high confidence)

:conditional nodes whose condition accesses a field named status/state with 3 or more branches mapping distinct literal values.

Tier 2 -- Status assignment (medium confidence)

:assignment nodes that write to a field/variable named status/state with a literal value, especially when multiple such assignments exist with different target values.

Tier 3 -- Transition-verb function names (supporting signal)

:function_def nodes whose name encodes a state-transition verb such as activate, deactivate, publish, archive, suspend, resume, complete, cancel, approve, reject, etc.

Configuration

  • :status_field_names - Field/variable names to watch (default: ["status", "state"])
  • :min_states - Minimum distinct status values before flagging (default: 3)
  • :transition_verbs - Additional verbs to recognize (merged with defaults)