修复: TD-260621-05审批状态双轨统一(executed→completed+V27迁移+测试)

This commit is contained in:
2026-06-24 17:48:42 +08:00
parent ebba9735ed
commit ba811ead96
2 changed files with 114 additions and 11 deletions

View File

@@ -457,7 +457,7 @@ pub async fn ai_approve(
// Err 压成 None,DB 故障被「未找到」误导(实为可重试故障),对齐 audit.rs audit_finalize 三路分流。
match state.ai_tool_executions.find_by_tool_call_id(&tool_call_id).await {
Ok(Some(rec)) => {
if rec.status == "executed" || rec.status == "rejected" || rec.status == "failed" {
if rec.status == "completed" || rec.status == "rejected" || rec.status == "failed" {
return Ok(format!("已处理({})", rec.status));
}
}
@@ -534,7 +534,7 @@ pub async fn ai_approve(
// session_trust —— 下次同会话同类操作(同工具+同目录 TrustKey)自动放行,跳过 pending + 二次确认。
// 仅首批工具(write_file/run_command)命中 trust_key_for 的 Some,其余工具 noop(None 不写)。
// F-260616-09 B 批4:per_conv.session_trust 唯一真相源(conv_id 来源 approval.conversation_id)。
// 无 conv_id(无主审批 R-9 异常数据)时无 per_conv 可写,信任不记(审计仍记 executed)。
// 无 conv_id(无主审批 R-9 异常数据)时无 per_conv 可写,信任不记(审计仍记 completed)。
if let Some(key) = super::super::trust_key_for(&approval.tool_name, &approval.arguments) {
let inserted = if let Some(ref cid) = conv_id {
session.conv(cid).session_trust.insert(key.clone())
@@ -581,7 +581,7 @@ pub async fn ai_approve(
// 工具失败不 return Err把错误包成 tool_result落库 + emit completed + 续循环全走通。
// 否则前端 approveToolCall 的 catch 会回滚 pending_approval审批按钮卡死无法消除。
let (audit_status, result_val) = match &exec_result {
Ok(val) => ("executed", val.clone()),
Ok(val) => ("completed", val.clone()),
Err(e) => ("failed", serde_json::Value::String(e.to_string())),
};
// 审计:人工审批后无论成败回填(决策者=human
@@ -601,7 +601,7 @@ pub async fn ai_approve(
// 重新获取锁,替换占位 tool_result 为真实结果失败时为错误信息LLM 据此决定下一步)
// F-260616-09 B 批4:per_conv.messages 唯一真相源(conv_id 来源 approval.conversation_id)。
// 无 conv_id 的无主审批不入 messages(审计仍记 executed/failed)。
// 无 conv_id 的无主审批不入 messages(审计仍记 completed/failed)。
let mut session = state.ai_session.lock().await;
if let Some(ref cid) = conv_id {
session.conv(cid).messages.replace_tool_result_content(&id, &result_val.to_string());
@@ -627,11 +627,11 @@ pub async fn ai_approve(
// F-260619-04 P2(方案 B): create_idea source 消息级溯源补全。
// create_idea 是 Medium risk → 经审批执行(本路径),非 process_tool_calls 内联执行,
// 故补全点放此(工具已 executed,可拿到 result.id + args.source)。
// 故补全点放此(工具已 completed,可拿到 result.id + args.source)。
// message_id 从 per_conv.messages 取末条 assistant id(同 process_tool_calls 的 current_message_id 语义);
// assistant_with_tools 消息持久驻留 messages,审批时仍可读。
// 仅 executed(成功)且 create_idea 才补;失败/其他工具 noop(helper 内判定,不污染本路径主流程)。
if audit_status == "executed" {
// 仅 completed(成功)且 create_idea 才补;失败/其他工具 noop(helper 内判定,不污染本路径主流程)。
if audit_status == "completed" {
let message_id = {
let session = state.ai_session.lock().await;
conv_id.as_deref().and_then(|cid| {
@@ -665,7 +665,7 @@ pub async fn ai_approve(
// 所有待审批处理完毕后恢复 agentic 循环(recovered 无 live loop,try_continue 因 generating=false 自然不续)
try_continue_agent_loop(&app, &state, &cont_conv_id, start_iter).await;
Ok("executed".to_string())
Ok("completed".to_string())
}
/// F-260620 临时诊断:授权/审批 IPC 调用链文件日志(不依赖终端 stderr,读 authz-debug.log 定位)。
@@ -882,11 +882,11 @@ pub async fn ai_authorize_dir(
};
tracing::debug!(
ok = exec_result.is_ok(),
status = if exec_result.is_ok() { "executed" } else { "failed" },
status = if exec_result.is_ok() { "completed" } else { "failed" },
"[AI-AUTHZ] execute 后"
);
let (audit_status, mut result_val) = match &exec_result {
Ok(val) => ("executed", val.clone()),
Ok(val) => ("completed", val.clone()),
Err(e) => ("failed", serde_json::Value::String(e.to_string())),
};
// 阶段4(容错/恢复):跨盘预检 → tool_result 提示。