Hash routine verification fingerprints

This commit is contained in:
Henry Park
2026-03-27 12:14:24 -07:00
parent 299e8e0f11
commit 4a9daf704d
2 changed files with 40 additions and 4 deletions
+39 -2
View File
@@ -25,6 +25,7 @@ use std::time::Duration;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use sha2::{Digest, Sha256};
use uuid::Uuid;
use crate::error::RoutineError;
@@ -591,7 +592,7 @@ fn write_routine_verification_record(
}
pub fn routine_verification_fingerprint(routine: &Routine) -> String {
serde_json::json!({
let canonical = serde_json::json!({
"trigger_type": routine.trigger.type_tag(),
"trigger": routine.trigger.to_config_json(),
"action_type": routine.action.type_tag(),
@@ -602,7 +603,10 @@ pub fn routine_verification_fingerprint(routine: &Routine) -> String {
"dedup_window_secs": routine.guardrails.dedup_window.map(|d| d.as_secs()),
},
})
.to_string()
.to_string();
let mut hasher = Sha256::new();
hasher.update(canonical.as_bytes());
hex::encode(hasher.finalize())
}
pub fn reset_routine_verification_state(
@@ -1022,6 +1026,39 @@ mod tests {
assert_ne!(h1, h3);
}
#[test]
fn test_verification_fingerprint_is_digest_not_prompt_content() {
let routine = Routine {
id: Uuid::new_v4(),
name: "hashed".to_string(),
description: "hash test".to_string(),
user_id: "test-user".to_string(),
enabled: true,
trigger: Trigger::Manual,
action: RoutineAction::Lightweight {
prompt: "super-secret-routine-prompt".to_string(),
context_paths: Vec::new(),
max_tokens: 256,
use_tools: false,
max_tool_rounds: 1,
},
guardrails: RoutineGuardrails::default(),
notify: NotifyConfig::default(),
last_run_at: None,
next_fire_at: None,
run_count: 0,
consecutive_failures: 0,
state: serde_json::json!({}),
created_at: Utc::now(),
updated_at: Utc::now(),
};
let fingerprint = routine_verification_fingerprint(&routine);
assert_eq!(fingerprint.len(), 64);
assert!(!fingerprint.contains("super-secret-routine-prompt"));
}
#[test]
fn test_next_cron_fire_valid() {
// Every minute should always have a next fire
+1 -2
View File
@@ -434,8 +434,7 @@ fn verification_result_payload(routine: &Routine, verification_reset: bool) -> V
"The current routine configuration has already been verified with a successful run."
} else {
"The routine has been saved, but it has not been verified yet. Offer to test it now."
},
"verification_fingerprint": routine_verification_fingerprint(routine),
}
})
}