AskaEth
|
0eb069fa37
|
fix(app-iced): M95 r4 —— 归属判据回归 / 置信度档 / 运行中页头
代码复审 r3 的四条 p2,修三条、登记一条(P2-4 页脚余量 13px,后置)。
**P2-1(回归修复)**:r3 把归属判据写成「有选中就只认选中」,把**导入崩溃文件**与 `open_session`
这两条路径的诊断一并关掉了——`559ba20` 是**无条件**画的,所以这是 r3 引入的**代码级回归**,
不是既有缺口(今天 iced 侧没有 dispatch 站点,那些还在遗留的 Slint shell 里,故复审未判 p1)。
判据改成三分支(`app/view/logs.rs`):
| live_session | selected_session | 报告算数的条件 |
|---|---|---|
| Some(s) | 任意 | `report.session == s`(只有它在线时日志行是它在追加,别人的报告挂上来就是串场) |
| None | Some(s) | `report.session == s` **或** 报告不属于任何已知会话(导入用 `file:<文件名>`,永不在索引里) |
| None | None | 全部算数(此时日志行只可能来自 `open_session`/导入,与报告同一次调用发出) |
新增两条测试(都走真实 reducer):`an_imported_crash_file_still_shows_its_findings`、
`a_live_run_says_it_is_running_instead_of_nothing_runs`。
残留(今天不可达,已登记):`open_session(A)` 在 `selected_session` 仍停在上场 B 时会被挡掉——
真要修得让 presenter 在 `LogLinesChanged` 记下「日志行属于哪一场」。
**P2-2 置信度档(视觉变更)**:`Severity`(借 core 的 `critical/warning/notice` 词汇)→
`Confidence`(`High/Medium/Low`)+ 新 key `LogsConfidenceHigh/Medium/Low`(中英齐,标题明确写
「高/中/低置信度」)。阈值仍是 80/50,但它现在是**档位定义**而不是「严重度代理」。
摘要里的 `findings=rule:high(85)` 同步换档位 slug。DTO 补齐 `severity` 之后应换回真严重度(finding)。
**P2-3 运行中的页头**:session 索引只在**结束**时追加,运行中的那一场不在 `log_sessions` 里 ⇒
拿不到实例名与结局 ⇒ r3 之前页头在日志滚动时一直说「当前没有运行中的实例」(demo 伪造了身份,
截图照不出来)。`Logs` 新增 `live: bool`(`live_session.is_some()`),`with_status` 三级回退:
有实例+结局 → `实例 · 时间 · 结局`;运行中但没结局 → 新 key `LogsSubtitleLive`(「Running now —
logs stream as they arrive」);都没有 → `LogsSubtitleIdle`。
新增 `a_live_run_says_it_is_running_instead_of_nothing_runs`(真实 reducer:只有
`LogAppended(running=true)`,断言副标题不是 Idle 文案且含 `Running now`)。
新增 demo 状态 `ULL_LOGS_FIXTURE=running` 用于出图。
**变异实测**(每条:回退 → 红 → 放回 → 绿):见报告。
验证:`fmt --check` 通过;`clippy -p unlucky-app-iced -p unlucky-i18n --all-targets -D warnings` 干净;
`cargo test` **280 + 6 + 23 passed / 0 failed**;行数最大 `pages/mod.rs` 367、`app/view.rs` 324、
`app/view/logs.rs` 337。
|
2026-11-02 22:27:01 +08:00 |
|
AskaEth
|
62d4af150e
|
fix(app-iced): M95 r3 跨会话串场 —— 诊断结论只在归属会话就是当前会话时才画
代码复审(绑 559ba20)抓的 p2:r2 的 `logs_model` 先按 `state.diagnosis` 定「这是哪一场」,
而日志行来自当前那一场;`state.diagnosis` 全仓**只写不清**(`apply_core` 里
`CoreEvent::DiagnosisReady` 是唯一赋值点,没有清零点),host 也只在崩溃 / 打开会话 / 导入时
发它。于是「崩溃一场 → 再启动一场正常跑」时:页头把新会话标成上一场的 `The game crashed`、
诊断卡挂着上一场的结论,而用户复制去贴 issue 的摘要里 `lines=` 是**新的**那一场的行数 ——
结论与行数不同源,用户会把错诊断递出去。
修法(只在页面侧判别,不动 presenter 的写入口):
- **身份**只认 `live_session.or(selected_session)`(正在跑 → 打开/刚结束的那一场),
**不从 `diagnosis` 反推**;
- 诊断结论只在 `diagnosis.session == 身份` 时画;身份为空时才信任报告(那时日志行只可能来自
`open_session`,它与报告是同一次调用发的);
- 实例/时间/结局的描述同样是身份优先,身份为空才退到报告的 session。
测试(`app/view/logs.rs` 内,走**真实数据路径**):
`crashed_only()` 用 `apply_core` 依次灌 `LogSessionsChanged` → 第一场 `LogAppended(running)`
→ `DiagnosisReady` → `LaunchFinished(Crashed)`,`after_a_new_run()` 再灌第二场 `LogAppended(running)`;
`state.diagnosis` 全程不清(这就是线上串场的条件)。
- `a_new_run_does_not_inherit_the_previous_crash`:断言 outcome=Ok、页头不含 `The game crashed`、
findings 为空、摘要 `outcome=ok` 且不含旧规则且 `lines=` 与当前行数一致。
- `the_crash_itself_is_still_reported`(对照,防「永远不画诊断」骗过上面那条):崩溃当场必须
findings=1 且摘要含 `gpu.driver_old:critical(92)`。
- `the_hosts_no_rule_matched_placeholder_is_not_a_finding`:host 的 `rule: ""` 占位报告不画;
换成真规则就必须画(证明过滤不是把诊断一起关了)。
变异实测:把 `report` 的过滤回退成 r2 的 `state.diagnosis.as_ref()` → 上面第一条**红**并点名
`Finding { rule: "gpu.driver_old", … }`(0 passed / 1 failed);放回 → **277 passed / 0 failed**。
|
2026-11-02 22:27:00 +08:00 |
|
AskaEth
|
ee4d82e3d4
|
refactor(app-iced): M95 r3 把日志页的展示转换从 app/view.rs 拆出来(纯搬移,行为零变化)
`app/view.rs` 已经 392 行(全仓硬上限 400),而日志页的转换还要加判别与测试,先拆。
- `app/view.rs`:392 → **324** 行,只留 `impl App`、`model()` 与实例页的展示转换,
另加 `mod logs; use logs::logs_model;`(调用点仍是 `logs_model(state).with_status(lang)`,未改)。
- 新增 `app/view/logs.rs`:**80 行**,逐行搬入 `logs_model` / `log_level` / `log_outcome` /
`diagnosis_of`,实现体一行未动(含 r2 的「先按 `diagnosis.session` 定身份」写法,
那是下一个 commit 才改的行为)。
等价比证:搬移前后 `cargo test -p unlucky-app-iced -p unlucky-i18n` 都是
**274 + 6 + 23 passed / 0 failed**(lib + no_hardcoded_tokens + i18n),数量与结果一致。
除模块声明与 import 调整外没有任何逻辑改动。
|
2026-11-02 22:26:59 +08:00 |
|