xbp_analysis/application/rules/
partial_commit.rs1use super::{base_caps, concepts_of, finding_from_concept};
2use crate::domain::concepts::ConceptKind;
3use crate::domain::model::LanguageModel;
4use crate::domain::rule::{Rule, RuleMeta};
5use crate::domain::types::{Confidence, Finding, Severity};
6use std::sync::OnceLock;
7
8#[derive(Default)]
9pub struct PartialCommitRule;
10
11impl Rule for PartialCommitRule {
12 fn meta(&self) -> &RuleMeta {
13 static META: OnceLock<RuleMeta> = OnceLock::new();
14 META.get_or_init(|| RuleMeta {
15 id: "partial-commit".into(),
16 name: "Partial commit ignored".into(),
17 description: "Partial write, quorum, cache, or transaction failure may be ignored."
18 .into(),
19 default_severity: Severity::Critical,
20 required_capabilities: base_caps(),
21 autofix_safe: false,
22 })
23 }
24
25 fn evaluate(&self, model: &LanguageModel) -> Vec<Finding> {
26 concepts_of(model, ConceptKind::PartialCommit)
27 .chain(concepts_of(model, ConceptKind::TransactionBoundary))
28 .map(|(lang, c)| {
29 finding_from_concept(
30 &self.meta().id,
31 lang,
32 c,
33 Severity::Critical,
34 Confidence::Low,
35 "Partial commit / distributed write failure handling looks incomplete.",
36 "Replicas diverge; clients observe torn writes or stale quorum.",
37 "Treat partial failures as hard errors; compensate or roll back explicitly. No autofix.",
38 )
39 })
40 .collect()
41 }
42}