AsilPropagator
Propagates ASIL through the data-flow edges of a Vista and flags cascading-failure sinks.
Domain
The loader stamps an ASIL on every CodeFunction / CodeInstruction that belongs to a configured source or sink leaf (the names live in the cfg's *.endpoints.json sidecar). Internal nodes — instructions that aren't source/sink leaves themselves — have a null construct.asil.
For analyzer graphs, the propagator walks forward through Vista.dataFlowSegmentDags and applies the inherited ASIL to segment member instructions. For hand-built/legacy graphs without segment DAGs, it falls back to explicit EdgeKind.DATA_FLOW edges.
QM < A < B < C < D(QM dominates; D is the strictest level)
Inherited ASILs land on CodeConstructView.propagatedAsil; for non-boundary nodes the same value is also copied to asilOverride for legacy summarized views. The wrapped entity's asil stays untouched (the entity is shared by other vistas, the override is per-view).
Boundary semantics
A boundary node is any view whose underlying construct.asil is non-null. By convention these are the source and sink leaves the cfg endpoints sidecar declared.
Sources (boundaries with outgoing edges and no propagation reaching them): keep their declared ASIL; their outgoing edges carry it into the rest of the graph.
Sinks (boundaries with incoming data-flow edges): keep their declared ASIL. The override is not set on them, but
propagatedAsilrecords the weakest ASIL that reached the sink. If any predecessor's propagated ASIL is lower than the sink's own ASIL, the sink'scascadingFaultflag is set totrue— that's the "cascading failure" condition. The specific boundary-crossing edge also getscascadingFault = trueand the human-readable CASCADING_FAULT_EDGE_LABEL stamped on itslabel.Internal nodes: receive the minimum (lower) of all incoming propagated ASILs; this lands on
propagatedAsilandasilOverride.
Algorithm
Worklist fixed-point iteration on the forward-edge adjacency. For each edge u → v:
if
effectiveAsil(u)is null, skip (no signal to propagate),if
vis a boundary: compareeffectiveAsil(u)againstv.construct.asiland markv.cascadingFault = truewhenu's effective ASIL is strictly lower,otherwise: set
v.propagatedAsil = min(v.propagatedAsil, effectiveAsil(u))and re-queuevif the propagated value changed.
Terminates after at most O(N * E) updates because each non-boundary node's override is monotonically non-increasing (lower wins) and ASIL has only five levels. Cycles in the data-flow graph are handled by the worklist; the fixed-point convergence is guaranteed by the bounded-lattice height.