d833ca9d32
cancel_direct_codex_turn 返回值改为 DirectTurnCancelView{outcome, message, clientTurnId},界面能区分"已发中断"与"守卫已被兜底释放"
cancel_direct_codex_turn_at 在拿不到可中断的活句柄(执行进程已退出 / 从没进执行器)时释放本地守卫,返回可读原因;"正在跑的是另一轮"仍保持原拒绝语义,什么都不释放
新增 release_stale_direct_taonier_active_invocation:释放条件写进注释——登记存在、clientTurnId 一致、调用方已确认执行器没有活句柄、"从没进执行器"时登记年龄还要超过 60 秒启动窗口
DirectTaonierStaleGuardReason 给出两种兜底原因与可读文案;DirectCodexActiveTurnTable 增加 registered_client_turn_id,另一轮拒绝文案提成共用常量
把"已有另一条 Direct 客户端回合正在运行"补成可操作文案:可在输入盒点终止,或等它结束后再发送(不改错误分类与前缀语义)
新增用例:同项目第二次进入仍被拒、clientTurnId 不匹配不释放、启动窗口内不释放、老过窗口释放后可再次进入、原守卫 Drop 不影响后来登记的回合