修复审批回执重放的会话归属
Project CI / Repository checks (pull_request) Failing after 5m11s
Project CI / Backend tests (pull_request) Successful in 10m1s
Project CI / Frontend tests (pull_request) Successful in 7m0s
Project CI / Native shell tests (pull_request) Successful in 18m3s

按原 Supervisor task 会话恢复审批修改意见

允许归档会话中已有幂等消息安全重放

同步审批恢复的长期决策记录
This commit is contained in:
2026-08-28 03:47:31 +00:00
parent f4776637c6
commit f4819e9a42
3 changed files with 17 additions and 10 deletions
@@ -83,18 +83,24 @@ fn approval_observation(receipt: &PlanGddApprovalV1) -> AgentRuntimeToolObservat
fn append_plan_gdd_revision_message(
root: &Path,
receipt: &PlanGddApprovalV1,
receipt_gdd: &PlanGddV1,
) -> Result<(), String> {
let label = if receipt.action == "reject" {
"退回"
} else {
"修改"
};
let supervisor_session_id = resolve_game_creator_agent_runtime_session_id_for_run_at(
root,
GAME_CREATOR_PROJECT_SUPERVISOR_AGENT_ID,
&receipt_gdd.root_run_id,
)?;
append_local_conversation_message_for_session_idempotent_at(
root,
Some(GAME_CREATOR_PROJECT_SUPERVISOR_AGENT_ID),
// 落在 Supervisor 当前活动会话。delivery 上的 parentSessionId 是委派发出时
// 的快照,不保证仍是可写的活动会话。
None,
// receipt 的 rootRun 所属 Supervisor task 才是这条用户意见的历史归属;
// 不能在 recovery 重放时按当前 active session 重新路由到别的会话。
Some(&supervisor_session_id),
LocalConversationMessage {
role: "user".to_string(),
content: format!(
@@ -1271,7 +1277,7 @@ fn project_receipt_locked(
note_plan_gdd_projection_gap(root, receipt, "delivery-revision-mark", &error);
recovery_pending = true;
}
if let Err(error) = append_plan_gdd_revision_message(root, receipt) {
if let Err(error) = append_plan_gdd_revision_message(root, receipt, receipt_gdd) {
note_plan_gdd_projection_gap(root, receipt, "delivery-revision-message", &error);
recovery_pending = true;
}
@@ -1152,12 +1152,6 @@ fn append_local_conversation_message_for_session_internal_at(
)
}
};
if archived {
return Err(format!(
"Agent Session 已归档,只能读取:{}",
normalized_session_id.as_deref().unwrap_or_default()
));
}
let role = role.trim();
if !matches!(role, "user" | "assistant" | "tool") {
return Err("对话角色必须是 user、assistant 或 tool".to_string());
@@ -1226,6 +1220,12 @@ fn append_local_conversation_message_for_session_internal_at(
}
false
} else {
if archived {
return Err(format!(
"Agent Session 已归档,只能读取:{}",
normalized_session_id.as_deref().unwrap_or_default()
));
}
append_jsonl_line_unlocked(&path, &line, "对话记录")?;
true
};
@@ -7792,6 +7792,7 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
- 现象:GDD“修改”已成功生成下一版本且当前 pending 身份正确,但 hydrate 持续返回 `recoveryPending=true`,审批卡显示“审批状态正在恢复”。
- 原因:恢复扫描会重放全部历史 approval receipt;旧版本 receipt 仍拿当前单例 approval pending 做 identity 比对。修改后当前 pending 已属于新版本,旧 receipt 的 identity 不同是正常状态,却被误记为投影缺口。
- 决策:receipt 的 index、Markdown、audit、submit observation、session 等投影继续允许全量恢复;approval pending 只由 lineage 最新 GDD 的 receipt 读取、更新和清理。历史 receipt 不得检查或改写当前 pending,也不得因此提升 `recoveryPending`
- 审批意见消息按 receipt 的 `rootRunId` 解析到原 Supervisor task 所属会话恢复;不会按当前 active session 重新路由。已存在于归档会话的幂等消息允许重放且不新增消息,缺失消息仍保持恢复失败,不静默写入其他会话。
- 验证:沿用现有审批恢复与 planning submit 定向测试;未新增独立测试,避免为非代表性 fixture 引入额外状态构造。
## 2026-08-27 审批修订以最新用户意见更新 GDD 决定快照