chore: document architecture gaps and add dev hot reload
- add npm dev:hot wrapper using cargo-watch and page reload polling - add mnote-web dev hot reload endpoint and coverage - record current architecture review and tracked bug findings across realtime, tree, editor, and AI runtimes Verification: - node scripts/task-dev-hot-plan-test.js - node --check scripts/dev-hot.js - cargo test -p mnote-web dev_hot -- --nocapture
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
# 3-16 [process][bug] tree realtime WS 主链口径与前端 SSE 实现不一致 v1
|
||||
|
||||
> 发现时间:2026-05-17
|
||||
>
|
||||
> 状态:`[process]`
|
||||
>
|
||||
> 关联主线:`03-rust-web`
|
||||
|
||||
## 1. 问题定义
|
||||
|
||||
当前架构口径已描述 `/api/realtime/ws` 是树实时 push 主链,`/api/tree/events` 是 SSE fallback。但前端真实代码仍只发现 `EventSource('/api/tree/events')` 消费链路,没有发现 `/api/realtime/ws` 或 `new WebSocket` 主 consumer。
|
||||
|
||||
## 2. 证据
|
||||
|
||||
- [routes/mod.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/mod.rs:170) 注册 `/api/tree/events`。
|
||||
- [routes/mod.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/mod.rs:172) 注册 `/api/realtime/ws`。
|
||||
- [use-sidebar-tree-stream.ts](/mnt/Data1T/mnote/wolai-frontend/src/lib/tree-stream/use-sidebar-tree-stream.ts:137) 实际创建 `EventSource`。
|
||||
- [protocol.ts](/mnt/Data1T/mnote/wolai-frontend/src/lib/tree-stream/protocol.ts:72) 固定构造 `/api/tree/events`。
|
||||
|
||||
## 3. 影响
|
||||
|
||||
- 架构文档与前端运行路径不一致。
|
||||
- live cache 收口时无法判断真实主链。
|
||||
- 回归测试如果只检查后端 WS route 存在,会误判前端已切换完成。
|
||||
|
||||
## 4. 建议修复
|
||||
|
||||
- 明确当前阶段:要么更新架构口径为“前端仍 SSE,WS route 已准备”,要么实现前端 WS consumer。
|
||||
- 增加浏览器 smoke,断言网络中实际使用的是 WS 主链还是 SSE fallback。
|
||||
- 文档与测试必须以真实前端消费路径为准。
|
||||
|
||||
## 5. 状态
|
||||
|
||||
已确认口径与前端源码不一致,尚未修复。
|
||||
@@ -0,0 +1,32 @@
|
||||
# 3-17 [process][bug] SSE push 模式跳过 polling safety net v1
|
||||
|
||||
> 发现时间:2026-05-17
|
||||
>
|
||||
> 状态:`[process]`
|
||||
>
|
||||
> 关联主线:`03-rust-web`
|
||||
|
||||
## 1. 问题定义
|
||||
|
||||
SSE route 注释和架构口径暗示 polling 可作为 safety net,但实现中只要 `stream_delta_rx.is_some()`,循环就进入 push/heartbeat 分支并跳过 polling。
|
||||
|
||||
## 2. 证据
|
||||
|
||||
- [sse.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/sse.rs:35) 附近说明 SSE 事件路径。
|
||||
- [sse.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/sse.rs:116) 附近在 `stream_delta_rx` 存在时走 heartbeat / push 分支。
|
||||
|
||||
## 3. 影响
|
||||
|
||||
- broadcast 丢失、进程重启、跨进程实例不共享 channel 时,SSE 连接可能无法靠 Convex bridgeLogs 追上。
|
||||
- fallback 名义存在,但实际恢复能力不足。
|
||||
- 客户端可能长期停在旧 snapshot。
|
||||
|
||||
## 4. 建议修复
|
||||
|
||||
- push 模式也应按 cursor 周期性检查 bridgeLogs,或在 heartbeat 周期中合并轻量 polling。
|
||||
- 增加测试:模拟 `stream_delta_rx` 无消息但 bridgeLogs 有新事件,SSE 应产出 delta/resync。
|
||||
- 明确 `pollMs` 与 push channel 同时存在时的优先级。
|
||||
|
||||
## 5. 状态
|
||||
|
||||
已确认 push 分支跳过 polling fallback,尚未修复。
|
||||
@@ -0,0 +1,33 @@
|
||||
# 3-18 [process][bug] WS 与 SSE delta 载荷合同分裂 v1
|
||||
|
||||
> 发现时间:2026-05-17
|
||||
>
|
||||
> 状态:`[process]`
|
||||
>
|
||||
> 关联主线:`03-rust-web`
|
||||
|
||||
## 1. 问题定义
|
||||
|
||||
SSE polling 可以从 bridgeLogs / domainEvents 解析 `streamDelta` 并附带 snapshot / resync 信息;WS 当前广播的是 `command_committed` 外壳,两者不是同一套 delta 合同。
|
||||
|
||||
## 2. 证据
|
||||
|
||||
- [stream_support.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/stream_support.rs:577) 附近解析 `streamDelta`。
|
||||
- [command_support.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/command_support.rs:102) 附近广播 command committed 事件。
|
||||
- [ws.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/ws.rs:40) 处理 WS socket。
|
||||
|
||||
## 3. 影响
|
||||
|
||||
- 同一 tree command 在 WS 与 SSE 下可能给客户端不同结构。
|
||||
- 前端 live cache 需要维护两套 reducer,增加状态分裂风险。
|
||||
- WS 切主时,SSE 已覆盖的 snapshot/resync 语义可能丢失。
|
||||
|
||||
## 4. 建议修复
|
||||
|
||||
- 抽出统一的 tree realtime envelope,WS 与 SSE 只作为 transport。
|
||||
- 对同一命令分别跑 WS / SSE 合同测试,断言事件 kind、cursor、snapshot、resync 语义一致。
|
||||
- 前端 reducer 只消费统一 envelope,不感知 transport 差异。
|
||||
|
||||
## 5. 状态
|
||||
|
||||
已确认 WS / SSE 事件结构不统一,尚未修复。
|
||||
@@ -0,0 +1,31 @@
|
||||
# 3-19 [process][bug] Reasonix ACP wrapper 调 mnote tool 缺少身份与幂等字段 v1
|
||||
|
||||
> 发现时间:2026-05-17
|
||||
>
|
||||
> 状态:`[process]`
|
||||
>
|
||||
> 关联主线:`03-rust-web`
|
||||
|
||||
## 1. 问题定义
|
||||
|
||||
Reasonix ACP wrapper 调用 mnote tool 时只发送 `toolName`、`args`、`workspaceId`,没有传递 `actorId`、`sessionId`、`runId`、`toolCallId`、`traceId`、`dryRun`、`idempotencyKey` 等工具合同字段。
|
||||
|
||||
## 2. 证据
|
||||
|
||||
- [reasonix-acp-wrapper.mjs](/mnt/Data1T/mnote/scripts/reasonix-acp-wrapper.mjs:230) 附近构造 `callMnoteTool` 请求体。
|
||||
|
||||
## 3. 影响
|
||||
|
||||
- Rust tool executor 难以稳定进行鉴权、审计、追踪和幂等。
|
||||
- 写工具可能被拒绝,或在缺少幂等键时产生重复写入风险。
|
||||
- Reasonix 与 Hermes 对同一 tool 的调用合同不一致。
|
||||
|
||||
## 4. 建议修复
|
||||
|
||||
- wrapper 必须从 ACP run/session 中透传 actor、session、run、toolCall、trace、dryRun、idempotency 字段。
|
||||
- 写工具缺失必要字段时应 fail fast。
|
||||
- 增加 Reasonix 端到端 smoke,断言请求字段完整。
|
||||
|
||||
## 5. 状态
|
||||
|
||||
已确认 wrapper 请求字段不完整,尚未修复。
|
||||
@@ -0,0 +1,31 @@
|
||||
# 3-20 [process][bug] ACP incoming request 只记录日志不响应 v1
|
||||
|
||||
> 发现时间:2026-05-17
|
||||
>
|
||||
> 状态:`[process]`
|
||||
>
|
||||
> 关联主线:`03-rust-web`
|
||||
|
||||
## 1. 问题定义
|
||||
|
||||
ACP client 收到 `session/request_permission` 等 incoming request 时当前只记录日志,没有返回协议响应。
|
||||
|
||||
## 2. 证据
|
||||
|
||||
- [acp_client.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/acp_client.rs:347) 附近处理 incoming request。
|
||||
|
||||
## 3. 影响
|
||||
|
||||
- ACP agent 侧可能等待到超时。
|
||||
- 权限请求无法进入用户确认或自动拒绝流程。
|
||||
- run 状态可能卡在进行中,SSE 输出也无法表达真实阻塞原因。
|
||||
|
||||
## 4. 建议修复
|
||||
|
||||
- 为已知 request type 实现明确响应:允许、拒绝或要求人工确认。
|
||||
- 未支持的 request type 也应返回结构化 error,而不是只日志。
|
||||
- 增加 ACP request/response 协议测试。
|
||||
|
||||
## 5. 状态
|
||||
|
||||
已确认 incoming request 缺少响应处理,尚未修复。
|
||||
@@ -0,0 +1,32 @@
|
||||
# 3-21 [process][bug] ACP run payload 被第一次 stream_events 消费后移除 v1
|
||||
|
||||
> 发现时间:2026-05-17
|
||||
>
|
||||
> 状态:`[process]`
|
||||
>
|
||||
> 关联主线:`03-rust-web`
|
||||
|
||||
## 1. 问题定义
|
||||
|
||||
ACP run 的 payload 在 `stream_events` 路径被消费后从内存表移除。刷新页面、多个 SSE 订阅、断线重连时,后续订阅可能无法再取到同一个 run 的 payload。
|
||||
|
||||
## 2. 证据
|
||||
|
||||
- [hermes_client.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/hermes_client.rs:789) 进入 `stream_events`。
|
||||
- ACP 分支中存在 `ACP_RUN_PAYLOADS.remove` 语义,payload 生命周期与第一次 stream 订阅绑定。
|
||||
|
||||
## 3. 影响
|
||||
|
||||
- 浏览器刷新或 SSE 重连可能导致同一 run 无法恢复。
|
||||
- 多个客户端观察同一 run 时只有第一个订阅者成功。
|
||||
- abort / retry / reconnect 语义不可靠。
|
||||
|
||||
## 4. 建议修复
|
||||
|
||||
- payload 应有 run 级持久生命周期,至少保留到 run completed / failed / aborted 后短 TTL。
|
||||
- stream subscription 不应拥有 payload 的删除权。
|
||||
- 增加 SSE 断线重连与重复订阅测试。
|
||||
|
||||
## 5. 状态
|
||||
|
||||
已确认 payload 生命周期与 stream 订阅耦合,尚未修复。
|
||||
Reference in New Issue
Block a user