11from __future__ import annotations
22
3+ import threading
34from datetime import datetime , timezone
45from typing import Any
56
@@ -66,59 +67,70 @@ def __init__(
6667 ) -> None :
6768 self .workflow_id = workflow_id
6869 self .escalation_threshold = escalation_threshold
69- self .confidence = initial_confidence
70+ self ._confidence = initial_confidence
7071 self ._initial_confidence = initial_confidence
7172 self ._soft_fail_penalty = soft_fail_penalty
7273 self ._silent_fail_penalty = silent_fail_penalty
7374 self ._history : list [StepRecord ] = []
75+ self ._lock = threading .Lock ()
76+
77+ @property
78+ def confidence (self ) -> float :
79+ with self ._lock :
80+ return self ._confidence
7481
7582 @property
7683 def history (self ) -> list [StepRecord ]:
77- return list (self ._history )
84+ with self ._lock :
85+ return list (self ._history )
7886
7987 @property
8088 def step_count (self ) -> int :
81- return len (self ._history )
89+ with self ._lock :
90+ return len (self ._history )
8291
8392 @property
8493 def threshold_breached (self ) -> bool :
85- return self .confidence < self .escalation_threshold
94+ with self ._lock :
95+ return self ._confidence < self .escalation_threshold
8696
8797 def update (self , result : ValidationResult ) -> None :
88- confidence_before = self .confidence
8998 penalty = self ._compute_penalty (result )
90- self .confidence = max (0.0 , self .confidence - penalty )
91-
92- record = StepRecord (
93- step_index = len (self ._history ),
94- contract_name = result .contract_name ,
95- passed = result .passed ,
96- confidence_before = confidence_before ,
97- confidence_after = self .confidence ,
98- penalty_applied = penalty ,
99- failure_modes = [f .failure_mode for f in result .failures ],
100- )
101- self ._history .append (record )
99+ with self ._lock :
100+ confidence_before = self ._confidence
101+ self ._confidence = max (0.0 , self ._confidence - penalty )
102+ confidence_after = self ._confidence
103+ record = StepRecord (
104+ step_index = len (self ._history ),
105+ contract_name = result .contract_name ,
106+ passed = result .passed ,
107+ confidence_before = confidence_before ,
108+ confidence_after = confidence_after ,
109+ penalty_applied = penalty ,
110+ failure_modes = [f .failure_mode for f in result .failures ],
111+ )
112+ self ._history .append (record )
102113
103114 logger .info (
104115 "workflow_step" ,
105116 workflow_id = self .workflow_id ,
106117 step_index = record .step_index ,
107118 contract = result .contract_name ,
108119 passed = result .passed ,
109- confidence = self . confidence ,
120+ confidence = confidence_after ,
110121 threshold_breached = self .threshold_breached ,
111122 )
112123
113124 def reset (self ) -> None :
114- self .confidence = self ._initial_confidence
115- self ._history .clear ()
125+ with self ._lock :
126+ self ._confidence = self ._initial_confidence
127+ self ._history .clear ()
116128
117129 logger .info (
118130 "workflow_reset" ,
119131 workflow_id = self .workflow_id ,
120- confidence = self .confidence ,
121- threshold_breached = self .threshold_breached ,
132+ confidence = self ._initial_confidence ,
133+ threshold_breached = self ._initial_confidence < self . escalation_threshold ,
122134 )
123135
124136 def _compute_penalty (self , result : ValidationResult ) -> float :
@@ -131,11 +143,12 @@ def _compute_penalty(self, result: ValidationResult) -> float:
131143 return penalty
132144
133145 def to_dict (self ) -> dict [str , Any ]:
134- return {
135- "workflow_id" : self .workflow_id ,
136- "confidence" : self .confidence ,
137- "escalation_threshold" : self .escalation_threshold ,
138- "threshold_breached" : self .threshold_breached ,
139- "step_count" : self .step_count ,
140- "history" : [r .to_dict () for r in self ._history ],
141- }
146+ with self ._lock :
147+ return {
148+ "workflow_id" : self .workflow_id ,
149+ "confidence" : self ._confidence ,
150+ "escalation_threshold" : self .escalation_threshold ,
151+ "threshold_breached" : self ._confidence < self .escalation_threshold ,
152+ "step_count" : len (self ._history ),
153+ "history" : [r .to_dict () for r in self ._history ],
154+ }
0 commit comments