Log Guardian V2 classification results (#40028)

## What changed

- Emit a structured log event for each completed Guardian V2 classification with its thread, turn, tool call, risk score, review threshold, sample time, and whether the score was accepted or superseded.
- Verify that accepted async classification events appear in the reviewed thread's log export with the expected context and decision fields.

GitOrigin-RevId: a027d5991b12a1968b9327da57e2993f0a529ca1
This commit is contained in:
Dylan Hurd authored and copyberry committed 2026-08-21 22:24:28 +00:00
1 parent 9445ef227e
commit 50ea8fd411
4 files changed
+60 -6

No files matched your search

@@ -566,6 +566,7 @@ impl GuardianV2Extension {
);
return;
}
let call_id = input.call_id.to_owned();
let action = GuardianAction {
tool_name: input.tool_name.clone(),
payload: input.payload.clone(),
@@ -741,12 +742,24 @@ impl GuardianV2Extension {
scores,
sampled_at: Some(sampled_at.into()),
};
if !thread
.thread_extension_data()
.insert_if(score.clone(), |previous| {
previous.is_none_or(|previous| previous.sampled_at < score.sampled_at)
})
{
let accepted =
thread
.thread_extension_data()
.insert_if(score.clone(), |previous| {
previous.is_none_or(|previous| previous.sampled_at < score.sampled_at)
});
tracing::info!(
%thread_id,
%turn_id,
%call_id,
tool_call_index,
action_risk = score.scores.get("action_risk").copied(),
review_threshold = guardian_config.review_threshold,
sampled_at = ?score.sampled_at,
accepted,
"Guardian V2 classification result"
);
if !accepted {
return Ok("superseded");
}
score_progress