同步 DirectProject 历史恢复约定

记录上下文用户消息过滤与坏线程淘汰规则

明确 clientUserMessageId 不提供回合级 exactly-once
This commit is contained in:
2026-09-07 11:11:48 +08:00
parent b6d6476459
commit 06911e6f27
@@ -1,6 +1,6 @@
# DirectProject Codex 原始历史与异常恢复
更新时间:`2026-09-05`
更新时间:`2026-09-07`
## 目标
@@ -41,11 +41,13 @@ AGC 判定本轮不会再产生新事件时收尾:用户中断、turn failed
`rawResponseItem/completed` 缺少 `item`(包括 `null`)时视为反序列化错误;该回合按异常终态收尾,历史中不会写入非法空 item。
Codex 启动时注入的 `host_skills.instructions``permissions.instructions``environments.environment_context` item 不属于项目对话历史;落盘时过滤,读取和线程注入时也过滤。
Codex 启动时注入的 `host_skills.instructions``permissions.instructions``environments.environment_context` item 不属于项目对话历史;落盘时过滤,读取和线程注入时也过滤。过滤同时识别 role=user 的完整上下文标签包裹文本,即使该 item 没有 `internal_chat_message_metadata_passthrough` 元数据,也不能把它当成用户回合。
## 恢复
创建新的 ephemeral thread 后,读取 `project.jsonl` 中所有 `response_item.payload`,按文件行顺序一次调用 `thread/inject_items`,再执行新的 `turn/start`。Codex 负责上下文窗口管理;注入失败直接失败,AGC 不截断、摘要或改写历史。
创建新的 ephemeral thread 后,读取 `project.jsonl` 中所有 `response_item.payload`,按文件行顺序一次调用 `thread/inject_items`,再执行新的 `turn/start`。Codex 负责上下文窗口管理;注入失败直接失败,AGC 不截断、摘要或改写历史。新 thread 已进入连接池但历史读取或注入失败时,必须先从池中淘汰并取消订阅该 thread,重试只能创建新 thread 并重新注入。
`clientUserMessageId` 仅作为 Codex 用户消息的稳定标识随 `turn/start` 发送,不等价于 turn 级 exactly-once 幂等。断线后的重试仍须由项目侧持久化 turn ledger 或服务端去重合同决定,不能仅凭该字段再次执行。
聊天界面只从 message item 提取 user/assistant 内容;工具 item 不再拼成 `tool: ...` 假文本。