文档:回合顺序修复写进 ADR、实施计划与共享记忆

- ADR:补「开口用户条目先于整轮里的一切失败」这条顺序不变式(发点在接单 + 落盘之后、起 codex 之前),以及界面「回合归属只认身份」的口径
- 实施计划:新增「回合顺序修复(2026-09-24)」一节,写清现场、根因、两条改动与回归用例
- decision-log:新增同日决策(宿主发点提前 + 前端按身份归位、收口早退不吞说明)
- pitfalls:新增同日条目,并记下排查提示——先分清逻辑回合的 turn.started / turn.completed 与 app-server 协议的 turn/start 请求
This commit is contained in:
2026-09-24 18:02:50 +08:00
parent 4a75de1c31
commit d6f2ae157a
4 changed files with 48 additions and 0 deletions
@@ -100,3 +100,23 @@
(`CodexAppServerInner::closed` 不再兼作去重标志,去重改用私有的 `connection_end_claimed`,
`closed` 在 `record_execution_turn_failure` 之后才置位);回归用例
`connection_death_records_the_failure_fact_before_the_watchdog_seals_the_turn` 把看门狗真正跑起来钉这条。
## 回合顺序修复(2026-09-24)
现场:用户在同一个项目里连发几条消息,每条都在 `turn/start` 之前失败(执行器版本未通过验收),
界面上"错误显示在用户消息上面",上一轮还显示出本轮的耗时(15.6 秒),本轮气泡自成一轮显示 0.0 秒;
后面再发一条,失败说明落进更早的分区里,用户以为"这条没报错"。
根因是**一条顺序**:本轮的开口用户条目原来在 `turn/start` 应答之后才下发,而失败说明按"当前回合"
归位(前端按条目顺序分回合),于是接单后、`turn/start` 前的失败没有用户条目可挂。
- 宿主:用户条目改成"落盘成功、起 codex 之前"下发(`emit_direct_thread_user_item`),删掉 `turn/start`
之后那一次;不变式:`接单 → 开口用户条目 → 整轮里其余一切`。
- 前端:失败说明带 `turnUserItemId`,`buildDirectChatTurns` 按身份分组(同一身份的条目永远同一轮),
本地乐观气泡按身份挂回自己的回合而不是另开一轮;收口早退只挡重复终态,不再吞掉还没写进界面的失败说明。
- 回归用例:宿主 `the_opening_user_item_is_emitted_before_anything_that_can_fail_in_the_turn`、
`direct_project_turn_does_not_forward_codex_user_echo_as_chat_items`(补上同一发点);
前端 `本轮用户条目没到时,失败说明按身份挂回自己那一轮,本地气泡不再自成假回合`、
`失败说明带上它所属回合的身份,用户条目没到时投影层也能归位`、
`收口早退不吞掉还没写进界面的失败说明(订阅重建只回放生命周期锚点)`。
- 已知边界:`project.jsonl` 里的用户条目依旧只在首屏 / 翻页时读进前端,本次不改这条读取时机——
开口条目的运行态下发与身份归位已经让"说明挂错回合"不再成立。