Decision model ============== A consistency evaluation produces a **Decision** describing the policy interpretation of the current system snapshot. The decision is the semantic contract between the consistency policy and the CSP-specific supervision logic. It does **not** describe the final outcome of the generic supervision loop; rather, it expresses what the policy believes should happen next for the current evaluation. A Decision captures: - the observing state that should eventually be applied; - diagnostic information describing inconsistencies or degraded conditions; - whether the condition represents a hard consistency fault; - the severity of the condition for operational and diagnostic purposes; - an explicit policy action describing what the supervisor should do next. Why an explicit action is needed -------------------------------- Historically, the supervisor inferred control flow indirectly from fields such as ``hard_fault``, ``severity``, and ``final_state``. This worked for simple cases, but becomes ambiguous once the domain needs to distinguish between: - valid but degraded operation, - temporary non-convergence, - waiting for delayed subsystem events, - fault conditions. In particular, ``Severity`` alone is not sufficient to drive supervisor behaviour. The same severity level may correspond to very different operational meanings. For example, a ``MEDIUM`` severity may represent: - a degraded-but-acceptable scan, where the final state should still be applied immediately; or - a temporary situation where the supervisor should wait for more information before concluding. For this reason, the policy now exposes an explicit ``PolicyAction`` to describe the intended control flow. PolicyAction ------------ ``PolicyAction`` is a high-level control signal returned by the policy. The currently supported actions are: ``APPLY`` The current evaluation is conclusive and the returned final state may be applied immediately. ``WAIT`` The current evaluation is not yet conclusive. The supervisor should keep the evaluation cycle alive and re-evaluate later. ``FAULT`` The current condition is considered unsafe or unrecoverable and the supervisor should transition to ``FAULT``. At present, ``PolicyAction`` is introduced as an explicit, future-proof representation of policy intent. Existing code may still preserve backward compatibility by deriving behaviour from legacy fields where necessary. Severity versus action ---------------------- ``Severity`` and ``PolicyAction`` express two different dimensions of a policy result. ``Severity`` answers: - how serious the detected condition is; - how it should be represented in diagnostics, logs, alarms, or quality reporting. ``PolicyAction`` answers: - what the supervisor should do next. This separation makes policy intent explicit and avoids overloading severity with control-flow meaning. Examples: - a degraded but acceptable scan may return: - ``action = APPLY`` - ``final_state = ObsState.SCANNING`` - ``severity = MEDIUM`` - a temporary non-converged situation may return: - ``action = WAIT`` - ``final_state = None`` - ``severity = MEDIUM`` Although both cases may have the same severity, they require different supervisor behaviour. Decision structure ------------------ A Decision contains: ``final_state`` The target observation state to apply, if the policy has reached a conclusive result. ``severity`` The diagnostic severity associated with the evaluated condition. ``fault_msg`` An optional human-readable message describing the condition. ``hard_fault`` A legacy boolean indicating whether the condition should be treated as a component fault. ``action`` An explicit control signal indicating whether the supervisor should apply, wait, or fault. This preserves compatibility with existing policy implementations while making future control-flow extensions clearer and more robust. Evaluation outcome ================== While ``Decision`` represents the result of **policy evaluation**, ``EvaluationOutcome`` represents the result of **supervisor execution** for one evaluation cycle. This distinction is important and intentional. Decision vs EvaluationOutcome ----------------------------- ``Decision`` is produced by ``policy.evaluate(...)`` and is domain-oriented. It expresses the policy interpretation of the current snapshot, including: - the selected action, - the resolved state, if any, - the severity, - any diagnostic message. ``EvaluationOutcome`` is produced by ``ObservationSupervisor._evaluate_and_publish()`` and is loop-oriented. It tells the generic supervision loop whether the current evaluation cycle has: - completed successfully, - remains pending and should be retried, - terminated in fault. In other words: - the policy decides **what should happen**; - the supervisor reports **what actually happened in this evaluation cycle**. Why this distinction is necessary --------------------------------- In the original design, the generic supervisor assumed that every evaluation was conclusive once triggered. This assumption is no longer sufficient once the system supports explicit waiting and multi-step evaluation behaviour. For example, when the policy returns ``WAIT``, the CSP-specific supervisor does not apply a final state and does not fault. Instead, it keeps the supervision cycle active so that the generic supervisor can re-evaluate later. To support this behaviour cleanly, ``_evaluate_and_publish()`` now returns an ``EvaluationOutcome``. This allows the generic supervisor to decide whether to: - stop the current cycle, - keep the cycle alive, - or terminate because a fault has been reached. Typical outcomes ---------------- A typical ``EvaluationOutcome`` may represent one of the following cases: ``APPLIED`` The supervisor applied the resolved observation state and the current evaluation cycle is complete. ``WAIT`` The supervisor did not apply a final state yet. The cycle remains open and must be evaluated again. ``FAULT`` The supervisor transitioned the resource into fault and the cycle is complete. This separation keeps the generic supervision loop independent from domain-specific policy details, while still allowing the CSP-specific supervisor to support richer policy semantics.