# 7-26 [done] Resource 块保存后在 AI block projection 中被降级为 paragraph

## 状态

- Owner：`07-ai` / Page Block AI projection 写入前置合同
- 优先级：P0，影响 AI 精确块编辑安全边界
- 状态：已修复并验证

## 现象

真实 3000 smoke 扩展复杂块后，`mnote.page.save` 写入 `type:"resource"` 的块，再经 Page Aggregate / AI block projection 回读时，`resource_1` 被显示为：

- `type="paragraph"`
- `editable=true`
- `unsupportedReason=null`

这会让 AI 工具把资源占位误判为普通可编辑文本块，违反复杂块不得伪装完全可编辑的合同。

## 根因

`core-protocol` 的 `EditorBlockType` 没有 `Resource` 变体，`bridge-runtime` 的 `normalize_editor_block_type_for_save()` 因此把未知 `resource` 类型落入默认 `Paragraph`。后续 `legacy_content_from_editor_document()` 和 `project_legacy_content_to_block_document()` 只能看到 paragraph，导致 AI projection 误报可编辑。

## 修复

- 在 `rust/crates/core-protocol/src/editor/model.rs` 增加 `EditorBlockType::Resource`。
- 在 Tiptap bridge 中用 `mnoteBlockType=resource` 保留 resource 类型往返。
- 在 `bridge-runtime` 中让 `resource/resource_block` 规范化为 `EditorBlockType::Resource`，legacy 回写继续输出 `type:"resource"`。
- 保留 resource props 到 `resourceProps`，legacy 回写时恢复。
- 在 `editor_actor` block 类型摘要中补 `resource`。
- 扩展 `scripts/task-page-block-ai-tools-smoke.js`，覆盖 resource 在真实 3000 的投影和 move 阻断。

## 验证

- `cargo test --manifest-path rust/Cargo.toml -p bridge-runtime editor_document_roundtrip_preserves_resource_block_type -- --nocapture`
- `cargo test --manifest-path rust/Cargo.toml -p mnote-web hermes_tools_block_move_after_blocks_complex_and_nested_blocks -- --nocapture`
- `PLAYWRIGHT_CHROME_EXECUTABLE=/snap/bin/chromium MNOTE_UI_BASE_URL=http://127.0.0.1:3000 MNOTE_AUTH_BASE_URL=http://127.0.0.1:3000 node scripts/task-page-block-ai-tools-smoke.js`

最新真实 smoke 证据：`tmp/page-block-ai-tools-smoke/mpag4966.json`，截图：`tmp/page-block-ai-tools-smoke/mpag4966-page.png`。
