2026-07-21 05:13:05 +08:00
|
|
|
# [recycle] 7-20 [done][bug] page_ai_workflow 绕过 Hermes tool executor / audit / toggle v1
|
2026-05-18 17:01:35 +08:00
|
|
|
|
|
|
|
|
> 发现时间:2026-05-17
|
|
|
|
|
>
|
|
|
|
|
> 状态:`[done]`
|
|
|
|
|
>
|
|
|
|
|
> 关联主线:`07-ai`
|
|
|
|
|
|
|
|
|
|
## 1. 问题定义
|
|
|
|
|
|
|
|
|
|
`/api/page-ai/block-edit-workflow` 仍是独立模型调用链:直接读取 Hermes profile、调用 chat/completions、解析模型 JSON,并直接调用 Rust 工具函数。
|
|
|
|
|
|
|
|
|
|
它没有通过 `/api/hermes/tools/mnote/call` 的工具执行壳,因此绕过了 tool toggle、audit、统一幂等和统一调用追踪。
|
|
|
|
|
|
|
|
|
|
## 2. 证据
|
|
|
|
|
|
|
|
|
|
- [page_ai_workflow.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/page_ai_workflow.rs:69) 直接调用上游模型。
|
|
|
|
|
- [page_ai_workflow.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/page_ai_workflow.rs:91) 在 route 内构造 `ToolCallInput`。
|
|
|
|
|
- [page_ai_workflow.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/page_ai_workflow.rs:109) 直接调用 `doc::doc_markdown_edit`。
|
|
|
|
|
|
|
|
|
|
## 3. 影响
|
|
|
|
|
|
|
|
|
|
- 关闭或限制 mnote tool 时,该 fast-path 仍可能写入。
|
|
|
|
|
- 工具调用审计与普通 Hermes run 不一致。
|
|
|
|
|
- 幂等、dryRun、runId、toolCallId 等字段无法统一治理。
|
|
|
|
|
|
|
|
|
|
## 4. 建议修复
|
|
|
|
|
|
|
|
|
|
- 将 fast-path 的工具写入改为调用统一 tool executor。
|
|
|
|
|
- fast-path 只负责 prompt / plan,不直接执行写入函数。
|
|
|
|
|
- 增加 smoke:当对应 tool disabled 时,`page_ai_workflow` 不得绕过限制写入。
|
|
|
|
|
|
|
|
|
|
## 5. 修复
|
|
|
|
|
|
|
|
|
|
- [hermes_tools.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/hermes_tools.rs:62) 将统一 mnote tool 执行壳抽为 `execute_mnote_tool_call`,保留 profile disabled、audit、idempotency、auth/workspace 校验和统一结果包装。
|
|
|
|
|
- [page_ai_workflow.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/page_ai_workflow.rs:109) `block_edit_workflow` 的写入阶段改为调用统一 executor,不再直接调用 `doc::doc_markdown_edit`。
|
|
|
|
|
- [page_ai_workflow.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/page_ai_workflow.rs:657) 增加路由级测试:当 profile 禁用 `mnote.doc.markdown_edit` 时,页面 AI fast-path 必须返回 `mnote_tool_disabled`,不得绕过限制写入。
|
|
|
|
|
|
|
|
|
|
## 6. 验证
|
|
|
|
|
|
|
|
|
|
- `cargo test --manifest-path rust/Cargo.toml -p mnote-web block_edit_workflow_respects_disabled_markdown_edit_tool -- --nocapture`
|
|
|
|
|
- 结果:1 passed
|
|
|
|
|
- `cargo test --manifest-path rust/Cargo.toml -p mnote-web page_ai_workflow -- --nocapture`
|
|
|
|
|
- 结果:3 passed
|
|
|
|
|
- `cargo test --manifest-path rust/Cargo.toml -p mnote-web hermes_tools_call_rejects_profile_disabled_tool -- --nocapture`
|
|
|
|
|
- 结果:1 passed
|
|
|
|
|
- `cargo test --manifest-path rust/Cargo.toml -p mnote-web hermes_tools_markdown_edit_maps_normalized_search_to_block -- --nocapture`
|
|
|
|
|
- 结果:1 passed
|