fix(presenter): M103 r1 —— 脱敏闸门补守卫,P2 五条带走

P1(守卫缺失,产品代码本来是对的):
- 新增 agent/tests_red_line.rs:MessageAppended(绕过 agent_submit)、
  ToolCallFinished(name+summary)、非 JWT 形状的 details(键名 / 嵌套 / 数组 /
  值随 path 敏感)各一条;变异 A/H/C2 复跑确认变红
- tests.rs 拆出红线组(547 → 334 行,单文件 ≤400)

P2:
- scrub_details 补「值随 path 敏感」规则(对齐 agent::redact::redact_args)
- scrub_text 补短 Bearer 掩码(对齐 agent::redact::mask_bearer)
- pending_confirm_forces_busy_without_yolo 先 finish_stream 再断言(不再空过),
  变异 F 现在两条测试同时变红
- MessageDelta 越界下标 debug_assert;ToolCallFinished 没有 pending 时忽略,
  不再改写已收敛的历史条目
- Presenter::state_mut() 收窄成 #[cfg(test)],换成 navigate/back/toggle_ai/
  prefs_mut/agent_set_yolo/agent_set_draft 等窄入口
- agent_submit 成功后立刻 begin_turn() 置忙,事件投影完 settle_streaming() 重算,
  异步后端空窗不会再让用户点两次发送
- 补测:begin_turn 置忙、静默后端不留假忙、工具收尾不覆盖历史
This commit is contained in:
AskaEth committed 2026-11-04 00:21:19 +08:00
1 parent a8d4cce3e2
commit 06461df91b
5 files changed
+435 -96

No files matched your search

+3
View File
@@ -270,6 +270,9 @@ fn failed_event_settles_streaming_and_keeps_the_evidence() {
#[test]
fn confirm_request_keeps_the_shell_busy_until_it_resolves() {
// 分工:这条钉 state 层的「待确认 ⇒ busy」与 `ConfirmResolved` 收敛;
// presenter 层的同名守卫是 `agent::tests::pending_confirm_forces_busy_without_yolo`
// (r1 P2-2:那条曾因 ToolCallStarted 顺手置真而空过,已改成先 finish_stream 再断言)。
let mut state = AppState::new();
state.apply(AppEvent::Agent(AgentEvent::ConfirmRequested {
request: confirm_request("req-1"),