Fix violation prompt window acknowledgement
This commit is contained in:
+82
-3
@@ -120,6 +120,7 @@ struct App {
|
|||||||
transition_return_target: String,
|
transition_return_target: String,
|
||||||
transition_duration_str: String,
|
transition_duration_str: String,
|
||||||
violation_message: String,
|
violation_message: String,
|
||||||
|
violation_window_snapshot: Option<window::WindowSnapshot>,
|
||||||
violation_dismissal_reason: String,
|
violation_dismissal_reason: String,
|
||||||
current_window_title: Rc<String>,
|
current_window_title: Rc<String>,
|
||||||
evidence_health: EvidenceHealth,
|
evidence_health: EvidenceHealth,
|
||||||
@@ -209,6 +210,7 @@ impl App {
|
|||||||
transition_return_target: String::new(),
|
transition_return_target: String::new(),
|
||||||
transition_duration_str: "2".to_string(),
|
transition_duration_str: "2".to_string(),
|
||||||
violation_message: String::new(),
|
violation_message: String::new(),
|
||||||
|
violation_window_snapshot: None,
|
||||||
violation_dismissal_reason: String::new(),
|
violation_dismissal_reason: String::new(),
|
||||||
current_window_title: window_snapshot.title.into(),
|
current_window_title: window_snapshot.title.into(),
|
||||||
evidence_health: window_snapshot.health,
|
evidence_health: window_snapshot.health,
|
||||||
@@ -314,6 +316,7 @@ impl App {
|
|||||||
fn enter_violation_prompt(&mut self, window_snapshot: &window::WindowSnapshot) {
|
fn enter_violation_prompt(&mut self, window_snapshot: &window::WindowSnapshot) {
|
||||||
self.violation_message =
|
self.violation_message =
|
||||||
format!("{}: {}", constants::VIOLATION_STATUS, window_snapshot.title);
|
format!("{}: {}", constants::VIOLATION_STATUS, window_snapshot.title);
|
||||||
|
self.violation_window_snapshot = Some(window_snapshot.clone());
|
||||||
self.violation_dismissal_reason.clear();
|
self.violation_dismissal_reason.clear();
|
||||||
self.state = State::ViolationPrompt;
|
self.state = State::ViolationPrompt;
|
||||||
}
|
}
|
||||||
@@ -323,15 +326,28 @@ impl App {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let violation_window_snapshot = self.violation_window_snapshot.clone();
|
||||||
|
let window_title = violation_window_snapshot
|
||||||
|
.as_ref()
|
||||||
|
.map(|snapshot| snapshot.title.clone())
|
||||||
|
.unwrap_or_else(|| self.current_window_title.as_ref().clone());
|
||||||
|
let evidence_health = violation_window_snapshot
|
||||||
|
.as_ref()
|
||||||
|
.map(|snapshot| snapshot.health.clone())
|
||||||
|
.unwrap_or_else(|| self.evidence_health.clone());
|
||||||
|
|
||||||
self.session_controller.record_violation(
|
self.session_controller.record_violation(
|
||||||
self.violation_dismissal_reason.clone(),
|
self.violation_dismissal_reason.clone(),
|
||||||
serde_json::json!({
|
serde_json::json!({
|
||||||
"message": self.violation_message,
|
"message": self.violation_message,
|
||||||
"window_title": self.current_window_title.as_ref(),
|
"window_title": window_title,
|
||||||
"evidence_health": self.evidence_health,
|
"evidence_health": evidence_health,
|
||||||
}),
|
}),
|
||||||
)?;
|
)?;
|
||||||
self.acknowledge_unknown_window(&window::get_snapshot());
|
if let Some(window_snapshot) = violation_window_snapshot.as_ref() {
|
||||||
|
self.acknowledge_unknown_window(window_snapshot);
|
||||||
|
}
|
||||||
|
self.violation_window_snapshot = None;
|
||||||
self.state = State::InProgress;
|
self.state = State::InProgress;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1372,6 +1388,69 @@ mod tests {
|
|||||||
let _ = fs::remove_file(path);
|
let _ = fs::remove_file(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn violation_dismissal_acknowledges_prompted_window_not_current_foreground() {
|
||||||
|
let path = unique_event_log_path("violation-prompt-original-ack");
|
||||||
|
let mut app = App::new_with_event_log_path(&path).unwrap();
|
||||||
|
let prompted_unknown = window::WindowSnapshot {
|
||||||
|
title: format!(
|
||||||
|
"Prompted Unknown Window {}",
|
||||||
|
SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.as_nanos()
|
||||||
|
),
|
||||||
|
class: Some("prompted-unknown-class".to_string()),
|
||||||
|
health: antidrift::domain::EvidenceHealth::Available,
|
||||||
|
};
|
||||||
|
let dismissal_foreground = window::WindowSnapshot {
|
||||||
|
title: "AntiDrift Terminal".to_string(),
|
||||||
|
class: Some("terminal".to_string()),
|
||||||
|
health: antidrift::domain::EvidenceHealth::Degraded(
|
||||||
|
"terminal foreground during dismissal".to_string(),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
app.user_intention = "write tests".to_string();
|
||||||
|
app.user_success_condition = "tests pass".to_string();
|
||||||
|
app.user_duration_str = "1".to_string();
|
||||||
|
app.to_in_progress().unwrap();
|
||||||
|
app.enter_violation_prompt(&prompted_unknown);
|
||||||
|
app.current_window_title = Rc::new(dismissal_foreground.title.clone());
|
||||||
|
app.evidence_health = dismissal_foreground.health.clone();
|
||||||
|
app.violation_dismissal_reason = "Needed to inspect docs".to_string();
|
||||||
|
|
||||||
|
app.dismiss_violation_if_valid().unwrap();
|
||||||
|
|
||||||
|
assert_eq!(app.state, State::InProgress);
|
||||||
|
assert!(app.is_unknown_window_acknowledged(&prompted_unknown));
|
||||||
|
assert!(!app.is_unknown_window_acknowledged(&dismissal_foreground));
|
||||||
|
|
||||||
|
let records = EventLog::open(&path).unwrap().records().unwrap();
|
||||||
|
let violation = records
|
||||||
|
.iter()
|
||||||
|
.find(|record| record.event_type == EventType::ViolationObserved)
|
||||||
|
.expect("dismissal should record a violation");
|
||||||
|
assert_eq!(
|
||||||
|
violation.payload_json["evidence"]["window_title"],
|
||||||
|
prompted_unknown.title
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
violation.payload_json["evidence"]["message"],
|
||||||
|
format!(
|
||||||
|
"{}: {}",
|
||||||
|
constants::VIOLATION_STATUS,
|
||||||
|
prompted_unknown.title
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
violation.payload_json["evidence"]["evidence_health"],
|
||||||
|
serde_json::json!("available")
|
||||||
|
);
|
||||||
|
|
||||||
|
let _ = fs::remove_file(path);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rating_completion_returns_controller_to_planning_for_next_session() {
|
fn rating_completion_returns_controller_to_planning_for_next_session() {
|
||||||
let path = unique_event_log_path("rating-completion");
|
let path = unique_event_log_path("rating-completion");
|
||||||
|
|||||||
Reference in New Issue
Block a user