Persist PageTree expand state via control-plane view-state and align chevron/DOM with restored expansion; keep Sidex-style shallow page-tree scan and drop the unused recursive scanner that only added cargo noise. Add password vault workbench routes/runtime/skill/CLI, split page_ai_pi into a module package, and retire Hermes/ACP/OpenHub recycle + root harness evidence from the index while gitignoring recycle and local diag dumps. Archive superseded design/bugs docs under old/, point architecture at ARCHITECTURE.md, and refresh smokes for Pi S1–S7, vault, and editor regressions so the working tree can stay clean.
39 lines
1.7 KiB
Markdown
39 lines
1.7 KiB
Markdown
# [recycle] 3-21 [done][bug] ACP run payload 被第一次 stream_events 消费后移除 v1
|
||
|
||
> 发现时间:2026-05-17
|
||
>
|
||
> 状态:`[done]`
|
||
>
|
||
> 关联主线:`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. 修复
|
||
|
||
- [hermes_client.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/hermes_client.rs:2051) `acp_run_payload_for_stream` 使用 `ACP_RUN_PAYLOADS.get(run_id).cloned()`,stream subscription 只读取 payload,不再拥有删除权。
|
||
- [hermes_client.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/hermes_client.rs:4116) 增加重复读取测试,锁定刷新、重连、多个观察者不会因为第一次读取而丢失 run payload。
|
||
|
||
## 6. 验证
|
||
|
||
- `cargo test --manifest-path rust/Cargo.toml -p mnote-web hermes_client_acp_stream_payload_lookup_keeps_payload_for_reconnect -- --nocapture`
|
||
- 结果:1 passed
|