diff --git a/docs/contracts/Host-v1契约.md b/docs/contracts/Host-v1契约.md
index 0fe80f6..c21de31 100644
--- a/docs/contracts/Host-v1契约.md
+++ b/docs/contracts/Host-v1契约.md
@@ -10,7 +10,8 @@
| --- | --- |
| `host_capabilities` | protocol=1,workspace=true;core/sync/credentials/extensions=false |
| `workspace_choose` | 原生选择,取消返回 null;成功返回 vault_id/path/name |
-| `workspace_recent` | 当前进程已打开的 Vault;尚未持久化最近列表 |
+| `workspace_open` | 只允许重开应用数据目录中已持久化授权的规范化路径 |
+| `workspace_recent` | 最近 20 个用户主动选择的 Vault;只保存身份、名称和路径 |
| `workspace_revoke` | 释放当前 Vault;不删除用户内容 |
| `workspace_tree` | Markdown 与目录树;file_id/path/hash/revision/deleted/is_folder |
| `workspace_read` | path,返回条目与 UTF-8 content |
@@ -27,7 +28,7 @@ OS 文件锁配合 Rust Mutex 维持单实例 Vault 写入。Web `serialized_vau
保存前对比实际磁盘 SHA-256,先持久化包含内容的 journal,再同目录临时文件刷盘和替换,最后提交元数据及 outbox。文件已替换但数据库未提交时,启动恢复补齐同一 operation_id。摘要不匹配则保留 journal 冲突及外部正文。remote origin 不再次入 outbox。outbox 目前只持久化,**尚无上传/拉取循环**。
-移动和删除另有 file_ops 日志;目标或回收正文刷盘后才删除来源,数据库失败可重放。Windows reparse point(包括 junction)、越界路径、保留目录和设备名被拒绝。大小写重命名暂报 PATH_CONFLICT,UNC 不支持;附件树、多窗口共享、目录移动/删除、稳定外部重命名识别、监听去重及完整恢复 UI 尚未实现。
+移动和删除另有 file_ops 日志;目标或回收正文刷盘后才删除来源,数据库失败可重放。Windows reparse point(包括 junction)、越界路径、保留目录和设备名被拒绝。最近 Vault 授权保存在应用数据目录的独立 SQLite 中,使用事务更新且不包含正文;任意路径不能绕过目录选择直接加入。大小写重命名暂报 PATH_CONFLICT,UNC 不支持;附件树、多窗口共享、目录移动/删除、稳定外部重命名识别、监听去重及完整恢复 UI 尚未实现。
本地恶意进程仍可能在路径校验与系统调用间改变文件系统;该预览不是 OS 沙箱。发布前须补句柄级路径固定及突破测试、磁盘满/掉电故障注入、真实 WebView 交互、性能门禁。
diff --git a/docs/development/第三阶段实施与验收记录.md b/docs/development/第三阶段实施与验收记录.md
index 956564a..bf123cf 100644
--- a/docs/development/第三阶段实施与验收记录.md
+++ b/docs/development/第三阶段实施与验收记录.md
@@ -17,10 +17,10 @@
## 已执行验证
- 后端:887 项 pytest 通过;新增 Web/桌面单写入者门禁测试。
-- 前端:88 个文件、473 项 Vitest 通过;TypeScript 检查与 Vite 生产构建通过,保留既有大 chunk 提示。桌面标题栏窗口操作使用 Tauri capability,Web 模式不显示伪窗口按钮。
+- 前端:88 个文件、474 项 Vitest 通过;TypeScript 检查与 Vite 生产构建通过,保留既有大 chunk 提示。桌面标题栏窗口操作使用 Tauri capability,Web 模式不显示伪窗口按钮。
- Sync v1:18 项隔离测试通过,Windows / Python 3.13.9 / SQLite / 磁盘对象 Fixture。包括双线程并发 CAS;不是 PostgreSQL 多 Worker 压测。
- Community v1:13 项隔离测试通过;前端使用 Python 生成的真实 Ed25519 向量互验。
-- Rust:系统 `rustc/cargo 1.98.1`(`x86_64-pc-windows-gnu`)下,5 项文件恢复测试、rustfmt、clippy `-D warnings` 和 Tauri desktop 开发构建通过。没有安装包或实机 UI 证据。
+- Rust:系统 `rustc/cargo 1.98.1`(`x86_64-pc-windows-gnu`)下,7 项文件恢复及最近 Vault 授权测试、rustfmt、clippy `-D warnings` 和 Tauri desktop 开发构建通过。没有安装包或新标题栏实机 UI 证据。
- 文档相对链接、`git diff --check` 及 AI Core / Sync / Community 隔离冒烟通过。Gitea 工作流已加入,但未推送,因此无远端 Runner 证据。
- 真实模型、个人 Vault、真实音频和凭据未作为测试输入。
diff --git a/frontend/src-tauri/build.rs b/frontend/src-tauri/build.rs
index f393099..d822f38 100644
--- a/frontend/src-tauri/build.rs
+++ b/frontend/src-tauri/build.rs
@@ -5,6 +5,7 @@ fn main() {
"host_capabilities",
"editor_capabilities",
"workspace_choose",
+ "workspace_open",
"workspace_tree",
"workspace_read",
"workspace_write",
diff --git a/frontend/src-tauri/capabilities/main.json b/frontend/src-tauri/capabilities/main.json
index 280df55..ba003a3 100644
--- a/frontend/src-tauri/capabilities/main.json
+++ b/frontend/src-tauri/capabilities/main.json
@@ -9,6 +9,7 @@
"core:default",
"allow-host-capabilities",
"allow-workspace-choose",
+ "allow-workspace-open",
"allow-workspace-tree",
"allow-workspace-read",
"allow-workspace-write",
diff --git a/frontend/src-tauri/permissions/autogenerated/workspace_open.toml b/frontend/src-tauri/permissions/autogenerated/workspace_open.toml
new file mode 100644
index 0000000..9f2f8d9
--- /dev/null
+++ b/frontend/src-tauri/permissions/autogenerated/workspace_open.toml
@@ -0,0 +1,11 @@
+# Automatically generated - DO NOT EDIT!
+
+[[permission]]
+identifier = "allow-workspace-open"
+description = "Enables the workspace_open command without any pre-configured scope."
+commands.allow = ["workspace_open"]
+
+[[permission]]
+identifier = "deny-workspace-open"
+description = "Denies the workspace_open command without any pre-configured scope."
+commands.deny = ["workspace_open"]
diff --git a/frontend/src-tauri/src/lib.rs b/frontend/src-tauri/src/lib.rs
index b88862e..54aebb2 100644
--- a/frontend/src-tauri/src/lib.rs
+++ b/frontend/src-tauri/src/lib.rs
@@ -1,3 +1,4 @@
//! 原生文件所有权与持久化 outbox;本库不依赖 WebView,可独立执行破坏性故障测试。
+pub mod recent;
pub mod workspace;
diff --git a/frontend/src-tauri/src/main.rs b/frontend/src-tauri/src/main.rs
index 2a372d1..1b72065 100644
--- a/frontend/src-tauri/src/main.rs
+++ b/frontend/src-tauri/src/main.rs
@@ -2,23 +2,20 @@
//! 预览 Host 只开放本地文件命令;未接通的 AI / 同步 / 凭据能力明确返回不可用。
+use notesagent_host::recent::{RecentVault, RecentVaultStore};
use notesagent_host::workspace::{Document, Entry, Workspace};
-use serde::Serialize;
+use std::path::Path;
use std::sync::Mutex;
use tauri::{Emitter, Manager, State};
#[derive(Default)]
-struct Host(Mutex