Repository navigation
v1.3.5 — 失败路径、信任契约与数据正确性
v1.3.5 — 失败路径、信任契约与数据正确性
针对 v1.3.4 独立审计(43 项行为缺陷 + 18 项工程不足,commit 261fd60)中全部 43 项行为缺陷逐条修复;按审计建议的优先序:凭据/备份 → 回退与执行身份 → 无人值守 → 假成功。
服务不再被敌意输入杀死
- 畸形 WebSocket 升级目标不再能全服务退出:
new URL("//[")曾在鉴权前抛异常、落入全局处理器收割全部 tab 与 cron 子进程并退出——现解析有守卫,普通 HTTP 的同步异常改为 400 回包而不是未处理 rejection。 - 空 tabId 不再全客户端广播:tab 作用域帧要求非空字符串 id;pi-exit 只发给原 owner/adopting 连接(旧实现在 Map 删除后广播,退出事件泄给所有连接)。
- Windows/macOS 外部终端 spawn 补异步 error 监听;FIFO 通过旧的 !isDirectory 检查会挂死事件循环——现在要求常规文件。
"不含密钥备份"改为 fail-closed,真正可信
- Cookie 类凭据头纳入脱敏(模式刻意放宽:多遮功能头可安全往返,漏一个就是真泄露)。
- 损坏的 cron.json 在无钥匙导出中被省略,不再回退打包原文。
- 导出文件名带随机后缀——同秒先"不含 key"再"含 key"不再让前一个路径变成含密钥文件。
- 全部秘密文件(配置/zip/恢复临时文件)创建即 0600,不再写完再 chmod。
凭据归属要求"已知端点"
- 保存与恢复都曾把"有 key 但没写 baseUrl 的旧 provider"当同一端点,把旧凭据继承到新地址。现在哨兵 key/headers 只在双方 baseUrl 都存在且相等时还原;未知旧端点 ≠ 匹配。
配置投毒挡在门口
- 备份导入对 routing.json 深校验:标量
state:1(曾使.cooldowns赋值抛 TypeError、拖垮全部路由 API)与[null]链被拒;loadRouting对所有消费者做防御性规范化。
回退链兑现承诺
- sameModelNewKey 尊重模型冷却:429 冷却的模型不再"同模型换 key"立即重撞配额(可能还是原 key),健康的后继供应商接管。
- 免密供应商(本机 Ollama/LM Studio、header 鉴权)进入回退链:"无受管 key"不再被当成"坏了"。
- 同供应商 set_model 保留 key 身份:切模型不再清 routeKeyIdx(进程实际还在用原 key,旧实现会让后续 401 冷却错误的槽位)。
Cron:不重跑、不漏跑
- 重启打断的任务不再双启动:bootReset 留下可区分状态,且 spawn 必定落盘 running 标志(旧的 status-only dirty 检查曾跳过写盘,下一 tick 读到 running:false 又启一次)。
- 延期标记到达被挤掉的每一个 daily(旧实现只标第一个);契约测试改为真实时序:interval 占满槽 → daily 到点 → 全部延期 → 槽位释放 → 全部补跑。
界面不再撒谎
- open-denied / rpc-denied 有处理:拒绝即清除乐观 tabId 并给出原因,不再留下没人应答的用户气泡;已知拒绝不再清空输入草稿。
- 所有保存面检查后端回执:api helper 非 2xx 一律解析为
{error};models/routing/config 保存与供应商开关只在确认后才说"已保存"。 - 迟到响应带请求身份:discover 期间切供应商即丢弃过期结果;导入列表/正文竞态按序号定胜负。
- "切回"只切换、绝不杀目标:当前有 tab 先分离进通知条;第 4 个后台会话改为"结束最旧 + 明确告知",不再静默失管。
- 新会话把 selModel 同步到实际打开的模型(chip 与失败上报描述真实执行);pi 异常退出真正接入回退(旧触发器在永远收不到 WS 帧的监听器里);共享弹窗先回答等待中的扩展再被替换;replay 重置流式节点(断线恢复后正文继续可见);恢复备份后强制刷新内存配置(旧实现可能把导入前状态写回去);健康页在后端无响应时如实报错;GOAL_DONE 必须是独立末行;50 条会话上限明示为窗口。
数据正确性
- 裸
nullJSONL 行在读取器即跳过(不再拖垮会话列表/统计/树);Codex 导入去重 response_item/event_msg 双表示;Gemini 读.content三种形态;Claude 账本按 message.id 去重(同一调用不再按行数翻倍);Codex 计数器回退按维度钳零;会话树报告truncated;文件预览声明截断;ZIP 中央目录 made-by/needed 字段修正。
验证
lint 0、测试 40-40、路由扫描 47 PASS、探针(ws / failover / ui / chat / contract)全 PASS;契约测试 16 → 23 项:审计点名的弱断言(可被 || 掩盖失败的断言、绕过调度器直接调运行函数的"延期"测试)全部替换为 tick 驱动的时序测试,新增锁定:bootReset 双启动、标量 routing 拒绝、未知端点恢复、Cookie 类脱敏、损坏 cron fail-closed、导出路径唯一。CI 8 job 全绿后从 CI 产物发布。
已知未结(不变):代码签名(等证书账号)、Windows/macOS 安装器级实机验收、Tauri 侧服务自动重启对齐、全发布 SBOM 分层、完整分页、a11y/i18n、会话标识架构统一、同步 IO 预算。