# https://github.com/gregdigittal/depthfusion 项目说明书

生成时间：2026-06-24 12:27:09 UTC

## 目录

- [项目概览与系统架构](#page-1)
- [记忆与检索管线 (Memory & Retrieval)](#page-2)
- [安全模型与 V2 访问控制](#page-3)
- [MCP 工具、桌面应用与运维部署](#page-4)

<a id='page-1'></a>

## 项目概览与系统架构

### 相关页面

相关主题：[记忆与检索管线 (Memory & Retrieval)](#page-2), [安全模型与 V2 访问控制](#page-3), [MCP 工具、桌面应用与运维部署](#page-4)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [app/README.md](https://github.com/gregdigittal/depthfusion/blob/main/app/README.md)
- [app/package.json](https://github.com/gregdigittal/depthfusion/blob/main/app/package.json)
- [app/src-tauri/src/lib.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/lib.rs)
- [app/src-tauri/src/commands.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/commands.rs)
- [app/src-tauri/src/export/mod.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/export/mod.rs)
- [app/src-tauri/src/export/policy.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/export/policy.rs)
- [app/src-tauri/src/export/commands.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/export/commands.rs)
- [app/src-tauri/src/auth/mod.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/auth/mod.rs)
- [app/src/lib/vault.ts](https://github.com/gregdigittal/depthfusion/blob/main/app/src/lib/vault.ts)
- [src/depthfusion/api/rest.py](https://github.com/gregdigittal/depthfusion/blob/main/src/depthfusion/api/rest.py)
- [src/depthfusion/api/admin_console.py](https://github.com/gregdigittal/depthfusion/blob/main/src/depthfusion/api/admin_console.py)
- [app/src/design/index.css](https://github.com/gregdigittal/depthfusion/blob/main/app/src/design/index.css)
- [app/src/components/NodeInspector.tsx](https://github.com/gregdigittal/depthfusion/blob/main/app/src/components/NodeInspector.tsx)
</details>

# 项目概览与系统架构

## 1. 项目定位与目标

DepthFusion 是一个由 Tauri 桌面端与 Python 服务端共同组成的知识图谱与文档管理平台，定位于将检索增强生成（RAG）、记忆与上下文管理、以及严格的访问控制整合进一个可本地或集中部署的产品中。最新的社区发布 v2.0.0 标志着系统从功能堆叠转向以"策略可执行的安全边界"为核心的工程方向；v1.2.0 的 HNSW 近似最近邻索引（`HNSWStore`）也已经在历史交付中固定为长期检索基础。桌面端的 `package.json` 描述其为 `2.1.1` 版本的 React 19 + TypeScript 应用，配套 Tauri 2 外壳（应用 ID `com.depthfusion.app`） 资料来源：[app/package.json:1-15]() 与 [app/README.md:1-30]()。

## 2. 系统总体架构

整个系统按"外壳—核心—服务"三层划分：TypeScript/React 负责渲染与交互，Rust 核心负责敏感策略的强制执行，Python 后端提供记忆、发现、管理控制台与 REST 接口。`tauri::Builder` 在启动时注册了 `shell`、`opener`、`deep_link`、`updater`、`store` 等插件，并显式列出了所有 IPC 命令（认证、设置、更新、导出等），保证 webview 不直接承担任何安全决策 资料来源：[app/src-tauri/src/lib.rs:1-50]()。

```mermaid
graph TB
    UI[React/TypeScript Webview]
    Vault[OS 钥匙串/DPAPI/Secret Service]
    Core[Rust Core 导出策略]
    Server[Python REST + MCP Server]
    Admin[管理控制台 / 审计]

    UI -- "invoke<T>() IPC" --> Core
    Core -- "受签名的策略快照" --> Server
    UI -- "fetch / OpenAPI" --> Server
    Core -- "令牌存取" --> Vault
    Server --> Admin
```

## 3. 核心子系统

### 3.1 桌面外壳与设计系统

Tauri 外壳以 `Vite` 端口 `1420` 启动开发服务器，前端使用 Tailwind CSS 4 与"Darkroom Amber"色板构建组件库。设计系统通过 `app/src/design/index.css` 聚合字体、颜色、字号、间距、动效与组件 token，确保所有 UI 元素共享同一套语义变量 资料来源：[app/src/design/index.css:1-8]() 与 [app/src/design/tokens/colors.css:1-30]()。`NodeInspector` 等组件复用这些 token，对文档、概念、决策三类图节点提供统一检视体验 资料来源：[app/src/components/NodeInspector.tsx:1-30]()。

### 3.2 认证与令牌保管

认证模块由 `start_login`、`handle_deep_link`、`poll_auth_state`、`store_tokens`、`load_tokens`、`clear_tokens`、`logout` 与 `setup_solo_auth` 组成，支持 OIDC 与单机模式两条登录路径 资料来源：[app/src-tauri/src/auth/mod.rs:1-5]()。`vault.ts` 通过 `invoke` 抽象 macOS Keychain、Windows DPAPI 与 Linux Secret Service，序列化字段与 Rust 的 `TokenSet` 严格对齐，便于编译器跨层校验 资料来源：[app/src/lib/vault.ts:1-30]()。

### 3.3 导出与策略执行

导出子系统遵循"**策略在 Rust 核心，webview 不可信**"的原则：copy/save/print/download-original 四种动作都必须经过 `gate(role, action, classification, snapshot)` 决策后，再由 IPC 命令执行；任何失败以 `ExportDenial` 结构化理由返回 资料来源：[app/src-tauri/src/export/mod.rs:1-30]()。`export_copy_text` 命令保持纯净——返回的文本是否带出处水印由核心决定，便于单元测试 资料来源：[app/src-tauri/src/export/commands.rs:1-30]()。`policy.rs` 描述了 `Viewer/Analyst/Contributor/Admin` 四类角色与 `Public/Internal/Confidential/Restricted` 分级的动作矩阵，并通过 HMAC-SHA256 签名快照防止离线篡改 资料来源：[app/src-tauri/src/export/policy.rs:1-40]()。

### 3.4 服务端 REST 与管理控制台

`src/depthfusion/api/rest.py` 暴露了发现、上下文发布/检索、递归查询、图遍历、监督学习等端点，全部通过 `require_principal` 依赖注入强制能力检查。`admin_console.py` 进一步提供 `/v2/admin/audit` 等管理路由，使用 `Capability` 枚举授权并把读操作本身记录为审计事件 资料来源：[src/depthfusion/api/rest.py:1-30]() 与 [src/depthfusion/api/admin_console.py:1-40]()。

## 4. 配置、部署与故障模式

桌面端通过 `SetupWizardPage` 选择部署模式（`deployment_mode`），`set_server_url` 与 `check_server_health` 协作确认服务端可达——后者带 5 秒超时且永不抛错，把"未就绪"作为正常状态 资料来源：[app/src-tauri/src/commands.rs:1-40]()。常见故障模式包括：钥匙串权限被拒（Rust 层抛出可读字符串）、策略快照过期或被篡改（`SnapshotVerification::Expired/Tampered` 导致失败关闭）、以及服务器不可达时向导停留在"未就绪"状态而不是崩溃 资料来源：[app/src-tauri/src/export/policy.rs:1-30]()。

## 参见

- [导出策略与签名快照](./导出策略与签名快照.md)
- [认证与令牌保管](./认证与令牌保管.md)
- [HNSW 检索索引 (E-45)](./HNSW-检索索引.md)
- [管理控制台与审计](./管理控制台与审计.md)

---

<a id='page-2'></a>

## 记忆与检索管线 (Memory & Retrieval)

### 相关页面

相关主题：[项目概览与系统架构](#page-1), [安全模型与 V2 访问控制](#page-3), [MCP 工具、桌面应用与运维部署](#page-4)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/depthfusion/api/rest.py](https://github.com/gregdigittal/depthfusion/blob/main/src/depthfusion/api/rest.py)
- [app/src-tauri/src/cache/mod.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/cache/mod.rs)
- [app/src-tauri/src/commands.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/commands.rs)
- [app/src-tauri/src/lib.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/lib.rs)
- [app/src/lib/vault.ts](https://github.com/gregdigittal/depthfusion/blob/main/app/src/lib/vault.ts)
- [app/src/components/NodeInspector.tsx](https://github.com/gregdigittal/depthfusion/blob/main/app/src/components/NodeInspector.tsx)
</details>

# 记忆与检索管线 (Memory & Retrieval)

## 概览与定位

DepthFusion 的记忆与检索管线承担"把分布式代理产生的上下文沉淀进可被语义召回的知识层"这一职责。前端 Tauri 应用通过 REST 接口把代理会话里产生的发现（discovery）、上下文条目（context item）、评分反馈（recall feedback）写入服务端，再由服务端的检索 / 图谱 / 自动学习工具回读。整个管线的核心入口在 [src/depthfusion/api/rest.py](https://github.com/gregdigittal/depthfusion/blob/main/src/depthfusion/api/rest.py) 中的 FastAPI 路由中，所有写入与读取操作都通过 `Depends(require_principal)` 进行授权校验，再转交给 `depthfusion.mcp.server` 模块下划线开头的内部工具函数（如 `_tool_recall_feedback`、`_tool_publish_context`、`_tool_retrieve_context`、`_tool_auto_learn`）。

离线场景下，桌面端需要把已检索过的分片与向量保存在本地，以应对网络中断或服务器下线。桌面端的存储实现位于 [app/src-tauri/src/cache/mod.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/cache/mod.rs)，它定义了三张 SQLite 表 `cached_chunk`、`cached_embedding`、`cache_lease`，分别保存分片原文、向量二进制以及按分类（classification）颁发的租约。

社区方面，v1.2.0 引入了基于 `hnswlib` 的 `HNSWStore` 近似最近邻索引（E-45），并以 BM25-HNSW 融合召回为对外契约；v2.0.0 在此之上继续演进，详见 [DepthFusion v2.0.0 Release Notes](https://github.com/gregdigittal/depthfusion/releases/tag/v2.0.0)。

## 检索接口与请求模型

REST 层把检索相关的请求体集中在 [src/depthfusion/api/rest.py](https://github.com/gregdigittal/depthfusion/blob/main/src/depthfusion/api/rest.py) 的 Pydantic 模型里，下表列出与记忆 / 检索直接相关的端点：

| 方法 | 路径 | 请求模型 | 主要字段 |
|------|------|----------|----------|
| POST | `/recall` | `RecallBody` | `query`、`limit=5`、`threshold=0.7`、`scope` |
| POST | `/recall/feedback` | `RecallFeedbackBody` | `recall_id`、`rating`、`notes` |
| POST | `/context` | `PublishContextBody` | `content`、`tags`、`project`、`session_id`、`metadata` |
| POST | `/context/retrieve` | `RetrieveContextBody` | `id`、`tags`、`project` |
| POST | `/auto-learn` | `AutoLearnBody` | `session_id`、`depth` |
| POST | `/graph/traverse` | `GraphTraverseBody` | `from_node`、`depth=2`、`direction="both"`、`filter_tags` |
| POST | `/run/recursive` | `RunRecursiveBody` | `query`、`max_depth=3` |

写入路径会先在路由处理器内构造 `dict` 参数，例如 `publish_context` 显式合成 `item_id = str(uuid.uuid4())` 并把 `project`、`session_id` 合并到 `metadata` 中，再调用 `_tool_publish_context(item, cfg)`。读取路径则把可选字段条件式塞进 `args` 字典，保证 `None` 字段不会被当作空串发送给 MCP 工具。

下图给出了"代理 → REST → MCP → 缓存 / 图谱"的端到端数据流：

```mermaid
flowchart LR
  A[代理会话] -->|POST /context| B(REST 路由)
  B --> C[_tool_publish_context]
  C --> D[(服务端存储)]
  D --> E[HNSW 索引 + BM25]
  A -->|POST /recall| F(RecallBody)
  F --> G[_tool_recall_feedback]
  G --> E
  E --> H[POST /context/retrieve]
  H --> I[前端 GraphPage 节点]
  I --> J[NodeInspector]
```

## 图谱遍历与自动学习

`/graph/status` 与 `/graph/traverse` 提供对内部知识图谱的只读访问。`graph_traverse` 在 [src/depthfusion/api/rest.py](https://github.com/gregdigittal/depthfusion/blob/main/src/depthfusion/api/rest.py) 中组装 `{"from", "depth", "direction", "filter_tags"}` 后转发给 `_tool_graph_traverse`，配合 `POST /run/recursive` 中的 `max_depth` 可以让代理沿图谱做多跳推理。`auto_learn` 端点接收 `session_id` 与 `depth`，把会话级上下文批量并入长期记忆。

前端图谱页用 `NodeData` 类型来标注节点种类：[app/src/components/NodeInspector.tsx](https://github.com/gregdigittal/depthfusion/blob/main/app/src/components/NodeInspector.tsx) 把节点分为 `document`、`concept`、`decision` 三类，并以 `df-chip--doc`、`df-chip--concept`、`df-chip--decision` 区分样式。该分类与服务端 `concept`、`decision` 等检索 scope 对应，使 UI 能即时反馈召回结果的语义类别。

## 离线缓存层

桌面端为了在断网或服务器无响应时仍能展示已检索过的内容，在 [app/src-tauri/src/cache/mod.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/cache/mod.rs) 中实现了三张 SQLite 表：

- `cached_chunk(chunk_id PK, text, source_uri, ...)`：保存分片原文及来源 URI。
- `cached_embedding(chunk_id PK→cached_chunk, dim, vector BLOB)`：保存 HNSW 索引所需的稠密向量，字段类型为 `BLOB` 以容纳原始字节。
- `cache_lease(record_id PK→cached_record, issued_at, expires_at, classification)`：为每条缓存记录颁发租约，按分类（classification）设置过期时间。

`CacheError { code, message }` 是为 IPC 传输准备的最小可序列化错误，与 [app/src-tauri/src/auth/commands.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/auth/commands.rs) 中 vault 的错误形状一致，方便 webview 端做统一的失败处理。

服务器健康度由 [app/src-tauri/src/commands.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/commands.rs) 的 `check_server_health` 探测：`probe_health` 用 5 秒超时客户端 `GET {url}/health`，返回布尔结果而非抛出错误，这样设置向导（wizard）阶段即使服务器未启动也能优雅降级。

## 客户端集成与失败模式

Tauri 端的命令清单在 [app/src-tauri/src/lib.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/lib.rs) 的 `invoke_handler` 中注册，其中 `export_copy_text`、`export_save_extract`、`export_print`、`export_download_original` 等都依赖 `require_principal` 提供的角色；这意味着检索结果在被复制 / 保存 / 打印之前会再次经过 `export/policy.rs` 中的策略网关。

凭证方面，[app/src/lib/vault.ts](https://github.com/gregdigittal/depthfusion/blob/main/app/src/lib/vault.ts) 通过 `invoke<T>('store_tokens', { tokens })` 把 OIDC `TokenSet` 写入 OS 钥匙串；其 `stored_at` 字段由 Rust 层在落盘时打戳并序列化为 `number | null`，前端不要使用它做业务判断。

常见的失败模式包括：

1. **服务器不可达**：`check_server_health` 在 5 秒超时或非 2xx 时返回 `false`，前端应将其当作"未就绪"而非致命错误。
2. **过期缓存**：`cache_lease.expires_at` 失效后，桌面端必须放弃显示该条结果或触发再水化；`stored_at=null` 的历史 blob 在 Rust 层会被视作已过期。
3. **租约与分类不匹配**：`cache_lease.classification` 必须与导出策略中的等级一致，否则 `decide_export` 会拒绝复制 / 提取操作。
4. **写入字段遗漏**：`publish_context` 内部生成 `item_id`，但 `metadata` 必须由调用方合并 `project` 与 `session_id`；遗漏会让后续检索 scope 失效。

## 相关页面

- 角色与导出策略：参考 `app/src-tauri/src/export/policy.rs` 与 `src/depthfusion/api/admin_console.py` 中的分类规则编辑端点。
- 身份与令牌生命周期：[app/src/lib/vault.ts](https://github.com/gregdigittal/depthfusion/blob/main/app/src/lib/vault.ts) 与 [app/src-tauri/src/auth/commands.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/auth/commands.rs)。
- 图谱节点 UI：[app/src/components/NodeInspector.tsx](https://github.com/gregdigittal/depthfusion/blob/main/app/src/components/NodeInspector.tsx) 与设计令牌 [app/src/design/tokens/colors.css](https://github.com/gregdigittal/depthfusion/blob/main/app/src/design/tokens/colors.css)。
- 设置向导与服务器健康探测：[app/src/wizard/ModeSelectScreen.tsx](https://github.com/gregdigittal/depthfusion/blob/main/app/src/wizard/ModeSelectScreen.tsx) 与 [app/src-tauri/src/commands.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/commands.rs)。

---

<a id='page-3'></a>

## 安全模型与 V2 访问控制

### 相关页面

相关主题：[项目概览与系统架构](#page-1), [记忆与检索管线 (Memory & Retrieval)](#page-2), [MCP 工具、桌面应用与运维部署](#page-4)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [app/src-tauri/src/export/policy.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/export/policy.rs)
- [app/src-tauri/src/export/commands.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/export/commands.rs)
- [app/src-tauri/src/lib.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/lib.rs)
- [app/src-tauri/src/commands.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/commands.rs)
- [app/src-tauri/src/auth/commands.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/auth/commands.rs)
- [app/src/lib/vault.ts](https://github.com/gregdigittal/depthfusion/blob/main/app/src/lib/vault.ts)
- [src/depthfusion/api/admin_console.py](https://github.com/gregdigittal/depthfusion/blob/main/src/depthfusion/api/admin_console.py)
- [src/depthfusion/api/rest.py](https://github.com/gregdigittal/depthfusion/blob/main/src/depthfusion/api/rest.py)
</details>

# 安全模型与 V2 访问控制

## 概述与设计原则

DepthFusion V2 的访问控制围绕"分层防御 + 失败即拒绝（fail-closed）"两条主线展开。客户端是一个基于 Tauri 2 + React 19 的桌面外壳，所有涉及用户数据出域（剪贴板、文件保存、打印、原始文件下载）的动作都必须经由 Rust 核心的 IPC 命令裁决；服务端通过能力（`Capability`）检查与审计日志约束管理动作。两条防线在快照签名机制下保持语义一致：服务器侧签发的策略快照在离线场景下可被 Rust 端以同一份规范化字节重新验签，从而避免本地伪造策略的回路。资料来源：[app/src-tauri/src/export/policy.rs:1-30]() 与 [app/src-tauri/src/export/commands.rs:1-15]()。

```mermaid
flowchart TB
    UI[Webview UI<br/>React/Tailwind] -->|invoke| IPC[Tauri IPC 命令]
    IPC -->|role/classification/action| Gate{策略门控}
    Gate -->|Snapshot?| Verify[HMAC-SHA256<br/>验签+过期检查]
    Verify -->|Ok| Matrix[角色×分级×动作矩阵]
    Verify -->|Unsigned/Tampered/Expired| Deny[拒绝]
    Matrix -->|允许| OSKeychain[操作系统钥匙串<br/>macOS/Win/Linux]
    Matrix -->|拒绝| Deny
    Deny --> Audit[审计日志]
    OSKeychain --> Audit
```

## 角色 × 分级 × 动作矩阵

导出策略的核心是一张 `Role × Classification × ExportAction` 的判定表，定义在 `policy.rs` 中。默认规则（S-191 AC-2）遵循最小权限原则：资料来源：[app/src-tauri/src/export/policy.rs:42-72]()：

| 角色 | View | CopyText / ExportExtract / Print | DownloadOriginal |
|---|---|---|---|
| Viewer | ✅ 全部 | ❌ | ❌ |
| Analyst | ✅ 全部 | ≤ Internal | ❌ |
| Contributor | ✅ 全部 | ≤ Confidential | ≤ Confidential |
| Admin | ✅ 全部（仍审计） | ✅ 全部 | ✅ 全部 |

任何未知的角色或未在快照中出现的分级都会立即被拒绝；不会回退到一份本地可篡改的副本。资料来源：[app/src-tauri/src/export/policy.rs:14-26]()。

### 签名策略快照（离线评估）

离线场景下，策略必须随加密缓存一起被打包。`SignedPolicySnapshot` 携带一个 HMAC-SHA256 签名，签名键来自环境变量 `DF_POLICY_SNAPSHOT_KEY`（**永不硬编码、永不记日志**）。`SnapshotVerification` 枚举区分四种结果：`Ok` / `Unsigned` / `Tampered` / `Expired`，任意一种非 `Ok` 的结果都会导致请求被拒绝。规范化的字节序列与 Python 端的 `policy_snapshot._canonical_bytes` 一致，因此同一份快照可在两端互验。资料来源：[app/src-tauri/src/export/policy.rs:79-110]() 与 [app/src-tauri/src/export/commands.rs:6-22]()。

### 导出命令的强制门控

四个导出 IPC 命令——`export_copy_text`（剪贴板）、`export_save_extract`（抽取物保存）、`export_print`（打印）、`export_download_original`（原始文件流式下载）——都先经过 `gate()` 判定，再决定返回 `ExportOutcome::allowed(...)` 还是 `ExportOutcome::denied(denial)`。值得注意的是：

- **原始文件从不进入 webview**：bytes 仅在 Rust 进程内从 `source_path` 流式写到 `dest_path`，前端只收到字节计数或拒绝原因。资料来源：[app/src-tauri/src/export/commands.rs:104-128]()。
- **抽取物 vs 原件两条路径分离**：抽取内容（生成的摘要/表格）作为 `String` 载荷传入可接受；原件因体量与敏感性走专用流式路径。资料来源：[app/src-tauri/src/export/commands.rs:131-156]()。
- **统一壁钟时间**：所有命令通过 `now_unix_secs()` 取一次当前时间并向下传参，使纯函数决策保持可单测。资料来源：[app/src-tauri/src/export/commands.rs:30-44]()。

这四个命令在 [app/src-tauri/src/lib.rs:1-30]() 中通过 `tauri::generate_handler!` 完成注册。

## 身份与会话：操作系统级令牌保险库

桌面端的会话令牌直接写入操作系统钥匙串，避免明文落盘。`app/src/lib/vault.ts` 通过 `invoke<T>()` 调用 Rust 实现，平台行为如下：资料来源：[app/src/lib/vault.ts:1-25]()：

- **macOS** — Security framework keychain
- **Windows** — DPAPI / Windows Credential Manager
- **Linux** — Secret Service via DBus（GNOME Keyring、KWallet）

`TokenSet` 接口镜像 Rust 端结构，其中 `stored_at` 字段由 Rust 层在写入时戳记，仅作内部账本使用；它**不会**通过 `poll_auth_state` 暴露给 UI，但写入时为 `null`（遗留 blob）的快照会被 Rust 层视为已过期，从而强制重新登录。`storeTokens` 在写入失败时抛出字符串错误，前端捕获后用于驱动登录流的重试。资料来源：[app/src/lib/vault.ts:27-58]() 与 [app/src-tauri/src/auth/commands.rs:1-30]()。

## 管理控制台的能力与审计

服务端的管理 API 采用**能力门控**模式：每个端点通过 `_enforce(principal, Capability.X)` 显式声明所需能力，例如审计查询需要 `Capability.VIEW_AUDIT_LOG`，分类规则读写需要 `Capability.MANAGE_SETTINGS`。规则本体（`ClassificationRuleEntry`）把每个分级绑定到一组布尔与角色列表：`export_allowed` / `cache_allowed` / `redact_in_search` / `allowed_roles`。资料来源：[src/depthfusion/api/admin_console.py:1-50]() 与 [src/depthfusion/api/admin_console.py:90-130]()。

每一次成功的写入都会通过 `_get_audit_store().log(AuditEvent(event_type=AuditEventType.ADMIN_ACTION, ...))` 写入审计追踪——**包括读取自身**（GET `/v2/admin/audit` 的行为也会被记录）。读 / 写响应模型分别由 `ClassificationResponse` 和 `ExportPolicyResponse` 承担，前端再以 OpenAPI 生成器生成的 `api-client.ts` 消费。资料来源：[src/depthfusion/api/admin_console.py:150-200]() 与 [app/package.json:18-19]()。

## 常见失败模式

1. **离线时策略快照缺失签名** → `SnapshotVerification::Unsigned`，所有导出动作被拒；请检查服务端在打包加密缓存时是否生成并嵌入了签名。
2. **签名键不一致** → `Tampered`；客户端与服务端的 `DF_POLICY_SNAPSHOT_KEY` 必须来自同一密钥来源。
3. **遗留 TokenSet 没有 `stored_at`** → Rust 层判为过期，强制走 OIDC 重新登录；不要试图回填伪造时间戳。资料来源：[app/src/lib/vault.ts:34-50]()。
4. **管理 API 拒绝** → 多半是主体缺少对应 `Capability`，检查 OIDC 颁发的角色声明是否覆盖所需权限。资料来源：[src/depthfusion/api/admin_console.py:100-120]()。
5. **服务端不可达** → `check_server_health` 在 `commands.rs` 中被刻意设计为**永不返回 `Err`**，网络级故障映射为 `Ok(false)`，以便安装向导正确呈现"未就绪"而不是崩溃。资料来源：[app/src-tauri/src/commands.rs:18-50]()。

## See Also

- [导出策略矩阵（Role × Classification × Action）](#角色--分级--动作矩阵)
- [签名策略快照的离线验证流程](#签名策略快照离线评估)
- [管理控制台与审计日志](#管理控制台的能力与审计)

---

<a id='page-4'></a>

## MCP 工具、桌面应用与运维部署

### 相关页面

相关主题：[项目概览与系统架构](#page-1), [记忆与检索管线 (Memory & Retrieval)](#page-2), [安全模型与 V2 访问控制](#page-3)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [app/src-tauri/src/lib.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/lib.rs)
- [app/src-tauri/src/commands.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/commands.rs)
- [app/src-tauri/src/export/commands.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/export/commands.rs)
- [app/src-tauri/src/export/policy.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/export/policy.rs)
- [app/src-tauri/src/auth/commands.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/auth/commands.rs)
- [app/src/lib/vault.ts](https://github.com/gregdigittal/depthfusion/blob/main/app/src/lib/vault.ts)
- [app/src/wizard/ModeSelectScreen.tsx](https://github.com/gregdigittal/depthfusion/blob/main/app/src/wizard/ModeSelectScreen.tsx)
- [app/src/SetupWizardPage.tsx](https://github.com/gregdigittal/depthfusion/blob/main/app/src/SetupWizardPage.tsx)
- [src/depthfusion/api/rest.py](https://github.com/gregdigittal/depthfusion/blob/main/src/depthfusion/api/rest.py)
- [src/depthfusion/api/admin_console.py](https://github.com/gregdigittal/depthfusion/blob/main/src/depthfusion/api/admin_console.py)
- [app/src/design/index.css](https://github.com/gregdigittal/depthfusion/blob/main/app/src/design/index.css)
- [app/src/design/tokens/colors.css](https://github.com/gregdigittal/depthfusion/blob/main/app/src/design/tokens/colors.css)
</details>

# MCP 工具、桌面应用与运维部署

DepthFusion 是一个分层系统：核心层通过 MCP 工具暴露能力，REST 层把这些工具包装为 HTTP 端点，Tauri 桌面端再以 Webview + Rust IPC 的形式向运维人员提供安全的 GUI 控制台。本页聚焦"工具—桌面端—运维"三条链路的边界与协作方式。

## 1. MCP 工具与 REST 包装层

REST 层并不直接执行业务逻辑，而是把每个 HTTP 端点桥接到 MCP 服务中的 `_tool_*` 函数，由 MCP 工具负责实际的数据访问与策略评估。典型的工具包括 `recall`（检索）、`confirm_discovery`（确认发现）、`pin_discovery`（固定发现）、`mark_superseded`（替代标记）、`prune`（剪枝）、`record_incident`（记录事件）、`report_outcome`（上报结果）、`surface_skill_candidates`（技能候选）以及 `retrieve_context`/`auto_learn`/`graph_traverse` 等。

每个端点都使用 Pydantic 的 `*Body` 模型声明入参，并在依赖注入中强制 `require_principal` 鉴权，例如 `RecallFeedbackBody`、`PublishContextBody`、`AutoLearnBody`、`GraphTraverseBody`、`RunRecursiveBody`、`SupersedeBody`、`PruneDiscoveriesBody`、`SetMemoryScoreBody` 等。配置通过 `DepthFusionConfig.from_env()` 在请求时按需加载，确保环境驱动的部署可以在不改代码的情况下切换设置（资料来源：[src/depthfusion/api/rest.py](https://github.com/gregdigittal/depthfusion/blob/main/src/depthfusion/api/rest.py)）。

管理控制台路由（`/v2/admin/audit`、`/v2/admin/classification`、`/v2/admin/export-policy`）则通过 `Capability` 枚举做细粒度授权——`VIEW_AUDIT_LOG` 控制审计读取，`MANAGE_SETTINGS` 控制分类与导出策略的读写，读取动作本身也会被审计记录。所有写入响应会重建一份当前 `policy_state` 的快照返回，便于前端同步（资料来源：[src/depthfusion/api/admin_console.py](https://github.com/gregdigittal/depthfusion/blob/main/src/depthfusion/api/admin_console.py)）。

## 2. Tauri 桌面应用架构

桌面端由 Tauri 提供壳层，Rust 侧通过 `tauri::Builder::default().invoke_handler(...).run(tauri::generate_context!())` 注册 IPC 命令；`lib.rs` 中集中挂载了 `get_app_info`、`ping`、`check_server_health`、`settings::*`（服务器 URL、向导完成状态、部署模式）以及 `export::commands::*` 四大类命令（资料来源：[app/src-tauri/src/lib.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/lib.rs)）。

基础命令层用 `serde` 描述载荷：`AppInfo { version, name }` 来自 `env!` 宏，`ping` 仅做回显，`check_server_health(url)` 则是异步探测——它构造一个 5 秒超时的客户端去 GET `{url}/health`，把任何网络错误折叠为 `Ok(false)`，因此"服务器未启动"在向导阶段是正常情况而不是异常（资料来源：[app/src-tauri/src/commands.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/commands.rs)）。

前端用 React + Vite 构建，统一遵循 "Darkroom Amber" 设计令牌系统：`colors.css` 定义 `--bg`、`--accent`、`--ember` 等 CSS 变量，`index.css` 串联字体、间距、动效与组件令牌（资料来源：[app/src/design/tokens/colors.css](https://github.com/gregdigittal/depthfusion/blob/main/app/src/design/tokens/colors.css)、[app/src/design/index.css](https://github.com/gregdigittal/depthfusion/blob/main/app/src/design/index.css)）。`SetupWizardPage.tsx` 是入口的"再导出"壳，真实实现位于 `src/wizard/SetupWizardPage.tsx`，其中的 `ModeSelectScreen` 用以让用户在本地/远程部署模式间切换（资料来源：[app/src/SetupWizardPage.tsx](https://github.com/gregdigittal/depthfusion/blob/main/app/src/SetupWizardPage.tsx)、[app/src/wizard/ModeSelectScreen.tsx](https://github.com/gregdigittal/depthfusion/blob/main/app/src/wizard/ModeSelectScreen.tsx)）。

## 3. 策略门控的导出与认证

导出是桌面端的"高危面"，因此 `export::commands` 用 Rust 命令把剪贴板、文件保存、打印、原始文件流都包成 IPC：`export_copy_text`、`export_save_extract`、`export_print`、`export_download_original`。每个命令在执行前先调用 `gate(role, action, classification, offline_snapshot)`，只有策略允许才会真正落地；拒绝时返回类型化的 `ExportDenial` 让 UI 能给出有意义的解释（资料来源：[app/src-tauri/src/export/commands.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/export/commands.rs)）。

策略表把"角色 × 动作 × 密级"编码为纯函数：`Analyst` 可复制/导出/打印至 `Internal`，`Contributor` 提升到 `Confidential` 并允许 `DownloadOriginal`，`Admin` 全部放行；快照验签结果 `Ok/Unsigned/Tampered/Expired` 控制离线缓存是否被信任，签名为空即视为未签（资料来源：[app/src-tauri/src/export/policy.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/export/policy.rs)）。

认证侧使用 `vault.ts` 作为 TypeScript 入口，它镜像 Rust 的 `vault::TokenSet`（含 `access_token`、`id_token`、`refresh_token`、`expires_in`、`stored_at`、`token_type`），通过 `invoke('store_tokens' | 'load_tokens' | 'clear_tokens')` 与底层通信；Rust 实现利用平台原生钥匙串——macOS Security 框架、Windows DPAPI/Credential Manager、Linux Secret Service——避免在 Webview 中触碰敏感凭据（资料来源：[app/src/lib/vault.ts](https://github.com/gregdigittal/depthfusion/blob/main/app/src/lib/vault.ts)、[app/src-tauri/src/auth/commands.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/auth/commands.rs)）。

## 4. 运维部署与健康检查

部署视图下，运维人员通过向导选择本地或远程模式，Tauri 设置命令（`get_server_url`/`set_server_url`、`get_deployment_mode`/`set_deployment_mode`）把选择持久化到本地设置中，`get_wizard_completed`/`set_wizard_completed` 标记首次配置已结束。前端在任何模式切换或服务恢复后调用 `check_server_health` 做 5 秒健康探活，依据返回的布尔位决定是否进入主控制台（资料来源：[app/src-tauri/src/lib.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/lib.rs)、[app/src-tauri/src/commands.rs](https://github.com/gregdigittal/depthfusion/blob/main/app/src-tauri/src/commands.rs)）。

```mermaid
flowchart LR
  UI[React Webview] -->|invoke| TauriCmd[Tauri IPC Commands]
  TauriCmd --> Gate[Export Policy gate]
  Gate -->|allow| Action[剪贴板/保存/打印/流式下载]
  Gate -->|deny| Denial[ExportDenial]
  TauriCmd --> Health[check_server_health]
  Health --> REST[REST API /v2/*]
  REST --> Tools[MCP _tool_*]
  Tools --> State[(policy_state / audit store)]
  TauriCmd --> Vault[OS Keychain]
```

## See Also

- [DepthFusion v2.0.0 Release Notes](https://github.com/gregdigittal/depthfusion/releases/tag/v2.0.0)
- [v1.2.0 — REST API systemd service & HNSW index](https://github.com/gregdigittal/depthfusion/releases/tag/v1.2.0)

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Doramagic 踩坑日志

项目：gregdigittal/depthfusion

摘要：发现 7 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：配置坑 - 可能修改宿主 AI 配置。

## 1. 配置坑 · 可能修改宿主 AI 配置

- 严重度：medium
- 证据强度：source_linked
- 发现：项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。
- 对用户的影响：安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。
- 证据：capability.host_targets | https://github.com/gregdigittal/depthfusion | host_targets=mcp_host, claude_code, claude

## 2. 能力坑 · 能力判断依赖假设

- 严重度：medium
- 证据强度：source_linked
- 发现：README/documentation is current enough for a first validation pass.
- 对用户的影响：假设不成立时，用户拿不到承诺的能力。
- 证据：capability.assumptions | https://github.com/gregdigittal/depthfusion | README/documentation is current enough for a first validation pass.

## 3. 维护坑 · 维护活跃度未知

- 严重度：medium
- 证据强度：source_linked
- 发现：未记录 last_activity_observed。
- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- 证据：evidence.maintainer_signals | https://github.com/gregdigittal/depthfusion | last_activity_observed missing

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 证据：downstream_validation.risk_items | https://github.com/gregdigittal/depthfusion | no_demo; severity=medium

## 5. 安全/权限坑 · 存在评分风险

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：风险会影响是否适合普通用户安装。
- 证据：risks.scoring_risks | https://github.com/gregdigittal/depthfusion | no_demo; severity=medium

## 6. 维护坑 · issue/PR 响应质量未知

- 严重度：low
- 证据强度：source_linked
- 发现：issue_or_pr_quality=unknown。
- 对用户的影响：用户无法判断遇到问题后是否有人维护。
- 证据：evidence.maintainer_signals | https://github.com/gregdigittal/depthfusion | issue_or_pr_quality=unknown

## 7. 维护坑 · 发布节奏不明确

- 严重度：low
- 证据强度：source_linked
- 发现：release_recency=unknown。
- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。
- 证据：evidence.maintainer_signals | https://github.com/gregdigittal/depthfusion | release_recency=unknown

<!-- canonical_name: gregdigittal/depthfusion; human_manual_source: deepwiki_human_wiki -->
