fix(ql3): isolate native console asynchronous sessions

This commit is contained in:
whyour
2026-09-04 03:56:18 +08:00
parent 9708a37154
commit 03afd7e899
9 changed files with 538 additions and 126 deletions
@@ -1,6 +1,6 @@
# ADR-0533:原生 Console 的任务、定时与运行列表分页
- 状态:AcceptedD-431 源码候选;远端 CI 与阶段实物待验证
- 状态:AcceptedD-431 远端 CI 与产物构建通过;下载实物复核待完成
- 日期:2026-09-04
- 关联:QL-RFC-0001 D-431、ADR-0532
@@ -28,3 +28,5 @@
原生 JS 为 80,336 bytes,三项静态资产共 111,857 bytes,仍小于单文件 96 KiB / 合计 192 KiB。D-430 的 `12ed38b7` 构建不含本切片;本地测试不等于 exact 双架构产物交付。
真实 Chromium 使用当前原生静态资产与合成 HTTP 数据验证了 Task、Trigger、Run 的第 65 条可达,任务详情可从第二页打开,DOM 每次只保留当前页。请求记录包含三个规范 continuation URL,浏览期间没有自动列表轮询。该浏览器证据验证交互,不冒充真实数据库、Owner 写入或双架构镜像验收。
提交 `ce8c3a7d2afdbb11b2a33f4884702454d1d22a53` 的主 CI [run 33796190607](https://github.com/whyour/qinglong/actions/runs/33796190607) 与 Console artifact [run 33797144811](https://github.com/whyour/qinglong/actions/runs/33797144811) 均已完成并成功。上传清单包含 amd64 `9910148271`239,038,659 bytes)、arm64 `9910153237`234,438,339 bytes)及 milestone `9910185111`6,797 bytes);本记录仅确认远端成功与上传存在,下载后的 checksum、离线 auditor 和 archive 源码复核尚未完成。这些归档不包含后续 ADR-0534 的客户端连接代次修复。
@@ -0,0 +1,35 @@
# ADR-0534:原生 Console 异步操作的连接代次隔离
- 状态:AcceptedD-432 源码候选;同源远端 CI 与阶段实物待验证)
- 日期:2026-09-04
- 关联:QL-RFC-0001 D-432、ADR-0533
## 问题
列表的请求代次不能覆盖所有编辑器调用链。已经复现:创建 Task 时读取 Secret 目录,用户断开连接后,迟到的响应仍会填充 catalog;完整 Task authoring、presence challenge 和写入后的刷新也可能把旧连接结果带入新页面。这个问题是客户端状态隔离缺陷,不是后端认证绕过。
## 决策
- 每次连接及断开都更换一个不含 credential 的内存代次对象;即使重新使用同一个 credential,也不是同一连接。
- 统一 `api` 在网络异常、JSON 解码异常和解码完成处检查代次;过期结果统一拒绝为 `session_changed`,不能向调用者暴露旧成功内容或旧错误。
- Task/Trigger/Secret 编辑、authoring、presence 提交和 Run 启停链在异步边界再次检查代次。旧调用不能重新打开对话框、写入 catalog/snapshot、覆盖新 proof、发布 toast,或在新连接下继续读取/写入。
- 断开时同步清空既有敏感状态并恢复提交按钮基线;旧 finally 不能解锁新连接正在提交的按钮。跨连接检查不替代同一连接内的列表和选择代次。
- 不增加 package、依赖、后台计时器、轮询或后端路由。默认 headless、Cluster、旧面板兼容入口和后端 Policy/presence/audit 规则不变。
## 不承诺的行为
丢弃页面响应不等于撤销已经发送的服务端操作。断开之前已提交的 Task/Trigger/Secret 写入、Run start 或 cancellation 仍可能成功;重连后应读取 durable 状态核对,不应自动重试或把断开视为取消。此切片不引入网络取消或事务回滚,也不把 Local Console 扩展为多用户远程会话产品。
## 替代方案
只比较 token 无法区分同一 credential 的重新连接;只加 AbortController 不能撤销已完成的解码、排队回调或服务端写入。逐页临时修补则容易遗漏编辑器和 finally。因此保留统一连接代次检查,并在会产生后续副作用的调用边界复核。
## 验证
测试直接执行发布的 `console.js`,通过 `test/support/consoleClient.cjs` 复用最小 DOM 夹具,不新增生产导出。16 项回归覆盖迟到目录、JSON 解码、网络错误、相同 credential 重连、authoring 全量定义、三种草稿、按钮 finally、Trigger pin 读取后的写入禁止,以及 Run 写入后的刷新/选择隔离。初始 13 项在修复前为 12 fail / 1 pass,修复后全部通过;新增 3 项也通过。
最终 Local API 130/130,完整后端 1685 项(1683 pass / 2 环境条件 skip / 0 fail)。Local image 与 18-package boundary audit 均 compatible;原生 JS 82,521 bytes,三项静态资产合计 114,042 bytes,仍在单文件 96 KiB / 合计 192 KiB 预算内。
真实 Chromium 使用当前静态资产和仅监听本机的合成 HTTP 服务完成连接、创建 Task、确认 Secret GET 挂起、断开、放行旧响应的交互;页面保持等待凭据且没有重开编辑器。测试没有真实数据库、生产 credential 或写入 authority,不能代替镜像端到端验收。
上述本地验证不代表修复已进入既有下载产物。D-431 的 `ce8c3a7d2afdbb11b2a33f4884702454d1d22a53` 产物也不包含本修复;本切片必须以自己的 source revision、CI 和阶段归档证据验收。
+1
View File
@@ -537,6 +537,7 @@
| [ADR-0531](./ADR-0531-canonical-run-log-bridge-for-legacy-panel.md) | 现有面板到规范 Run 日志的有界桥接 | AcceptedD-429 exact Console 双架构阶段实物已交付) |
| [ADR-0532](./ADR-0532-native-console-log-window-navigation.md) | 原生 Console 日志窗口导航 | AcceptedD-430 exact Console 双架构阶段实物已交付) |
| [ADR-0533](./ADR-0533-native-console-ledger-pagination.md) | 原生 Console 任务、定时与运行列表分页 | Accepted(D-431 源码候选;实物待验证) |
| [ADR-0534](./ADR-0534-native-console-session-isolation.md) | 原生 Console 异步操作的连接代次隔离 | Accepted(D-432 源码候选;同源 CI 与实物待验证) |
## 规则