Files
NotesAgentic/docs/architecture/第三阶段生产化工程规划与验收目标.md

39 KiB
Raw Permalink Blame History

第三阶段五项生产化能力:工程规划与验收目标

日期:2026-09-08。审计基线:2010778780fa7267557a7302132e63ac533d43ab,分支 feat/phase3-completion。初始规划提交:2c4287e。用户随后授权全量实施,并确定正式名称为 OpenNexus。状态:实施中,五项均未通过完整生产验收;实际证据见实施记录

1. 范围、文档优先级与交付口径

本文细化第三阶段实施规划中的 D05D07、C02/C03、S02–S06 及关联发布门禁。上述五项的生产目标、依赖、迁移和量化验收以本文为准;总规划继续约束第三阶段其他范围。Host v1Sync v1Community v1继续描述当前接口,不因本文自动变成已实现的生产契约;实施 PR 必须同步相应契约。实施与验收记录只记录实际执行证据。

“通过”要求实现、自动化报告、平台实测和恢复演练同时满足。旧记录中的测试数量不继承为本计划证据。五项完成不代表多窗口、全部社区内容能力、OCR/音频质量等第三阶段其他退出项完成。

初始规划轮仅允许文档提交;后续实施已获用户授权。实施期间测试只使用自动生成的临时 Vault、测试密钥和隔离服务,不读取个人笔记、凭据或生产数据库。

2. 现状审计与差距

下表路径相对仓库根;均已核对代码或配置,不仅依据旧规划。

能力 代码证据与现状 必须补齐的差距
AI Core Sidecar frontend/src-tauri/src/main.rscore_url 固定 127.0.0.1:8000backend/app/main.py 配置 CORStauri.conf.json 的 bundle 关闭且 CSP 允许直连该端口;frontend/package.json 的 desktop:build 带 --no-bundle 自动打包/启动、受控握手、全端点认证、流式与二进制转发、动态地址、退出监管;CORS 不能充当认证,开发 EXE 不能充当安装包
Stronghold backend/app/providers/credentials.py 的 Fernet 使用 credentials/master.key 或环境主密钥及 credentials.json;有 Provider/Plugin/MCP 命名空间限制与环境 resolverCargo 无 Stronghold 依赖 Rust 唯一凭据所有者、解锁/锁定、受限解析代理、可恢复迁移、清除确认、密码丢失处理;禁止直接复制环境 resolver 到生产
OS 沙箱 backend/app/extensions/mcp.py 仍由 Python Popen 启动;runtime.pymcp_registry.py 对开发外不受控启动设禁用门禁 Rust 进程启动与平台策略、句柄级文件约束、网络代理、资源限额、逃逸测试;进程树清理或 capability 本身不证明隔离
Extension Manager backend/app/extensions/installed.py 已有 SQLite 登记、目录摘要、受管理 ZIP 根、重启复核;Community v1 已有签名及分类限额;Rust capability 的 extensions=false Rust 单一安装/授权库、迁移与接管、跨包事务升级、许可绑定、撤销和回滚;不得重复宣称安装登记尚无实现
同步客户端 frontend/src-tauri/src/workspace.rs 已有 files/journal/file_ops/outboxremote 写入不回流;outbox 保存正文且仅 pendingHost sync=false 上传/拉取状态机、服务器基线映射、分块附件、确认丢失恢复、冲突 UI、配置分类、监听与初次绑定;本地 revision 不等于服务器 revision
同步生产服务 server sync/sync_server/app.py 已有认证、设备撤销、CAS、幂等、上传和历史;PostgreSQL 行锁分支与 S3 adapter 已存在;SQLite Fixture 测试;/ready 只探测数据库;Compose/README 有手动 Bucket 初始化 PostgreSQL+MinIO 真链路、跨 worker 上传一致性、过期暂存清理、流式 IO、部署初始化、备份恢复、指标和压测;禁止把 Compose 文件存在等同运行通过

附加审计:storage.py 的 S3 get 返回整块 bytes,上传 complete 读取整个暂存文件;100 MiB 并发场景需测峰值内存并改造流式路径。现有目录树摘要包含相对路径及内容,不能与 Community 的 ZIP SHA-256 混用。当前 .gitea/workflows/ci.yml 有文档、后端、服务 Fixture、前端和 Rust lib 检查,尚无五项生产验收作业。

3. 目标架构与责任

flowchart TD
    UI[本地 WebView] --> IPC[Rust 窄 IPC 与能力校验]
    IPC --> WS[Workspace 唯一写入者]
    IPC --> CM[Core Supervisor]
    CM --> CORE[受信任 AI Core Sidecar]
    CORE --> BROKER[Host 凭据与工具代理]
    BROKER --> SEC[Credential Broker / Stronghold]
    BROKER --> EM[Rust Extension Manager]
    EM --> SB[OS 沙箱与受限 IO 代理]
    SB --> EXT[不可信 Plugin / MCP]
    WS --> Q[Sync outbox / inbox / 基线映射]
    Q --> SYNC[HTTPS Sync Server]
    SYNC --> PG[PostgreSQL]
    SYNC --> S3[私有 S3 对象存储]
组件 / 建议模块(待新增) 唯一职责及禁止越界
src-tauri/src/core/ 验证 Sidecar 清单、版本、进程身份和就绪;转发显式路由与事件;不向 WebView 返回会话密钥
src-tauri/src/credentials/ Stronghold 会话、迁移日志、作用域 resolver;前端可提交新秘密但只收到 ID/是否配置/锁定状态,永无读取明文命令
src-tauri/src/sandbox/ 唯一第三方进程启动器,执行平台策略;不能由 AI Core 或前端要求任意 shell
src-tauri/src/extensions/ 包、依赖、授权与升级事务;AI Core 只消费当前已校验工具描述和受控调用句柄
src-tauri/src/sync/ 会话轮换、outbox/inbox、附件流、冲突记录、远端基线;一律经 Workspace journal 落盘
现有 Workspace Vault 授权、稳定 file_id、expected_hash 校验、日志与原子替换;补附件/外部变化能力,不能让 Sync 自行写文件
server sync/ 独立 Sync API、元数据/对象一致性、备份恢复与配额;不运行 AI/插件,不复用社区登录
前端 platform adapter 显示真实能力、进度、锁定、冲突与恢复选择;Web 模式维持独立开发后端,不与桌面共同写同一 Vault

Rust Host IPC 增补 DTOrequest_id、vault_id、session_generation、operation_id、expected_hash、超时与取消;字段按操作适用,不接受前端指定设备身份。统一错误至少区分 AUTH_REQUIRED、CORE_UNAVAILABLE、PROTOCOL_INCOMPATIBLE、CREDENTIALS_LOCKED、MIGRATION_CONFLICT、SANDBOX_UNAVAILABLE、PERMISSION_CHANGED、REVISION_CONFLICT、QUOTA_EXCEEDED。取消只停止未提交步骤,已提交结果须返回 committed 状态或可查询 operation_id。

4. 信任边界与威胁模型

边界 / 攻击者 主要威胁 强制控制与验证
WebView、远程页面、不可信笔记内容 → Host XSS 调用凭据/文件/shell、跨 Vault、路径穿越 仅本地授权窗口 capability;命令白名单、DTO 限额、绑定当前 Vault;远程来源、伪造 vault_id、编码路径负向测试全部拒绝
同机普通进程 → Core 抢占固定端口、伪就绪、重放令牌、从 argv/日志拿令牌 随机端口+受控继承管道的双向随机挑战;会话代际、全路由鉴权;旧代际不得访问新实例
AI Core → Host/凭据 过宽 resolver、借工具参数跨命名空间、直接写 Vault Core 属于受信任计算基;按 Provider/工具身份与 Vault 授权解析,笔记写入经 Host CAS;后端桌面模式禁止直接写入
恶意扩展及其后代 → OS 读取家庭目录/保险库、联网泄露、派生 shell、资源耗尽、符号链接竞态 OS 默认拒绝;文件/网络通过 broker;句柄固定、参数数组、环境白名单、进程树限额;不能以用户勾选跳过隔离
社区/下载/CDN → 安装库 包篡改、签名键被撤销、ZIP 穿越、依赖替换、旧版本回放 固定信任根、不可变发行、每次安装在线复核撤回状态、签名及 ZIP/目录双摘要、事务 staging
其他 Sync 用户/被撤销设备 → 数据 猜摘要读对象、跨 Vault、复用上传、重复提交、重放 Refresh 每个 API/对象鉴权,绑定 owner+device+vault,数据库 CAS/幂等;跨 worker 测试
崩溃/断电/磁盘满/服务故障 半写、游标先行、数据复活、备份缺对象 先持久化意图后提交;远端确认可重放;游标只随已落盘 inbox 提交;一致切点备份

不承诺抵御管理员/root、已被控制的 Host/内核、内存取证或运行中同用户调试器。Stronghold 保护静态存储,不能使运行时明文永不存在。Sync 服务运营者可接触明文;TLS 不等于 E2EE。扩展不能获得 Stronghold 文件或 Core 管道,即便获准执行某个工具。

5. 平台与容量基线

以下是待落实的首发验证范围,不是兼容性声明。P0 为 Windows 11 x64、NTFS 本地 Vault、MSVC 发布构建、标准用户安装与运行;现有 GNU 开发构建保留回归但不替代发布证据。Windows ARM64、UNC/网络盘不在首发支持范围。macOS 14+ arm64、Ubuntu 24.04 x64 为后续平台门;未通过只能标预览/禁用相应能力,总阶段三平台门仍保留。

沙箱候选:Windows AppContainer/受限 token + Job Object + brokerLinux namespaces/Landlock/seccomp/cgroup + brokermacOS 独立签名沙箱 helper/XPC + broker。这里只冻结验证方向,不宣称这些组合已经可用或覆盖全部系统版本。P0 原型必须固定实际 API、OS build、文件/网络规则与最低支持版本;原型失败则该平台第三方执行保持禁用,并阻塞该平台“五项完成”声明。禁止退回普通子进程或依赖废弃工具绕过门禁。

基准机器:客户端 4 核/16 GiB/SSD;服务 4 vCPU/8 GiB/SSD,独立 PostgreSQL 与 MinIO100 Mbps、RTT 20 ms,故障网络附加 5% 丢包。数据:固定 seed=2026090810000 篇每篇 4 KiB 笔记、中文/NFC/大小写路径向量、一个 100 MiB 二进制附件、两个账号每账号两个 Vault。报告记录 CPU/OS build/磁盘/依赖 lock 摘要及网络实测。下文阈值为工程发布目标,调整必须有基准报告与文档评审,不能测试失败后直接放宽。

6. 依赖、工作包与交付物

角色是责任域而非已确认个人排期:H=Rust/桌面负责人,B=AI Core负责人,E=扩展安全负责人,S=Sync服务负责人,F=前端负责人,R=发布/运维负责人。M0 必须落实到人,安全评审与发布密钥管理不得由未指定角色代签。工作包完成须含实现、契约变更、自动化用例和操作证据。

依赖顺序:P0 → A/B 原型 → A+B → C → D 生产启用;D 的纯安装事务可在 C 前开发,但不能启动第三方代码。S1/S2 可在 P0 后独立推进;S3/S4 依赖 B 的令牌存储及 Workspace 附件/监听/恢复改造;最终 E2E 依赖 A–D、S 全部退出。前端用显式 Fixture 开发,发布跑真实 Host。这里的工作包安排不授权当前文档任务开始实现。

ID / 负责人 工作包及必须交付物 依赖 / 退出证据
P0 / H+E+S+R Host认证/Stronghold/沙箱 ADRDTO、错误、schema迁移方案,平台原型,冻结测试 runner 与环境清单 审计基线;每个待决项有选择和负责人,测试清单无空 ID
A1 / H+B 锁定 Python 与依赖,按平台生成独立运行目录(优先 PyInstaller onedir 原型),资源清单/SBOM/许可证、固定 runtime 摘要;模型与 CUDA 独立下载 P0;干净机无 Python 启动,包内容复核
A2 / H+B Supervisor、握手/鉴权中间件、Host 路由与 SSE/二进制桥、动态 CSP/资源方案、桌面写入代理 A1A-0103
A3 / H+R 安装/更新签名与版本清单、进程故障恢复、升级回滚 runbook A2;A-04、E-04;新发布命令不能沿用带 no-bundle 的命令假装出包
B1 / H+B Stronghold Broker、解锁/锁定/更改密码,Provider/Plugin/MCP/Sync分域适配 P0B-01、03
B2 / H+B Fernet迁移器、schema/引用映射、断点日志、备份与清除 UI B1B-02、04
C1 / E+H 各平台最小 OS 沙箱与攻击夹具、不可用能力报告 P0C-01 及平台证据
C2 / E+B 文件/网络/工具 broker、许可绑定、资源与进程生命周期、移除生产 Python直启 A2+B1+C1C-0204
D1 / H+E Rust安装库、签名向量互验、旧记录只读迁移、Python停止写入适配 B2D-01、02
D2 / H+F 安装/依赖锁/权限差异/升级/回滚/卸载/撤销完整事务和UI D1+C2D-03、04
S1 / S PostgreSQL/MinIO集成、跨worker上传锁与磁盘持久化、对象流式IO、过期暂存清理 P0S-04、05
S2 / S+R 部署初始化、TLS/就绪/限流/指标、升级、备份/恢复命令与runbook S1S-06、07、09
S3 / H+F Rust outbox/inbox、远端基线、账号绑定/刷新、附件、监听、分类过滤、同步状态 B1+S1+Workspace改造;S-01、02、08
S4 / H+F+S 首次对账、离线冲突/删除恢复/历史UI、两台实机及故障重放 S2+S3S-03、E-0103
R0 / R+全组 有签名安装产物、全套报告索引、平台支持声明与恢复演练 所有适用验收ID通过;发布门禁表归档

7. Sidecar 打包、认证与生命周期设计

生产 UI 仅经 Host IPC 获取业务与事件,移除固定 8000 直连(含图片/导出 URL),对大对象采用受控流/临时资源句柄,句柄限定窗口、Vault、有效期。Core绑定 127.0.0.1:0;禁止先查空闲端口再绑定的竞态。Host通过专用继承管道下发256位随机会话秘密并验证基于该秘密的挑战应答;子进程回报实际绑定地址、PID、协议及构建摘要。通道只对目标进程继承,其他子进程不得继承。秘密不放argv、环境、URL、磁盘或WebView。

FastAPI在业务处理和日志之前验证会话认证,覆盖health、API、SSE、文件下载、错误路径及文档端点;生产关闭OpenAPI/docs或同样鉴权。校验Host/Origin且拒绝重定向;无Origin的非浏览器请求仍必须认证。每次重启换代并销毁旧管道。Host代理由当前宽泛 /api/* 收敛成版本化路由/方法/大小表;拒绝任意主机、绝对路径、双重编码与CRLF。

状态:stopped → starting → ready → degraded/backoff → stopped;就绪超时30秒,连续失败退避1/2/4/8/16秒,5分钟内最多5次自动重启,超过后停在可重试错误。编辑不等待Core恢复;推理任务标 interrupted,不自动重放有副作用工具。正常退出先取消任务,5秒宽限,10秒内清理整个受管理进程树。预下载模型缺失显示模型不可用,不下载基础启动必需代码。

Host/Core主协议不兼容时不转发业务写操作,但本地Rust编辑可用。更新以Host+Core兼容组合原子切换;签名或摘要失败保留原版本。基础安装大小目标≤300 MiB(不含模型/CUDA);若A1原型无法满足,必须在发布前明确拆分方案与新预算。

8. 凭据迁移与恢复

生产凭据按providerplugin/<id>mcp/<id>sync/<server>/<account>分域。保留既有外部credential_id映射;调用者身份由Host确定,不能信任请求自报命名空间。Core只在调用时获准解析所需Provider秘密;远程MCP认证优先由网络broker添加。确需环境秘密的本地MCP必须显式声明,只注入该沙箱进程,不能继承全量环境。新秘密输入与迁移过程不进入诊断、前端持久化或普通同步。

默认使用用户口令解锁Stronghold;系统安全存储自动解锁作为后续独立选项,不能把解锁密钥写同目录文件。锁屏、手动锁定和应用退出锁定Broker,取消未开始的凭据调用并清除缓存;已发送给Provider的远程请求无法收回。禁止前端加载可读取明文的通用Stronghold能力。密码遗失且无可解锁备份时只能重新配置凭据,笔记继续可用,不提供假恢复或回退明文。

迁移状态:discovered → backed_up → copied → verified → switched → cleanup_confirmed。迁移锁阻止旧新库同时修改;备份Fernet密文/主密钥时保持原访问限制,备份不进入Vault。环境主密钥仅从当前进程受控读取,缺失时停止,不尝试新建替代钥匙。逐条解密写入Stronghold并重新打开验证;日志只记录源ID、目标ID、状态及密文文件校验,不记录秘密或秘密哈希。

新库同ID异值进入冲突,不覆盖;用户选择保留新值/重新命名旧引用后再切换。全部验证完成才原子更新resolver世代和引用映射。任一步失败保留旧数据且重试幂等;切换后不得静默fallback Fernet。只有验证成功并由用户明确确认清除旧存储才删除旧密文/受管理master.key与本次备份;外部环境主密钥不由应用删除。清除不承诺SSD物理擦除。清除前可用旧版本恢复旧快照;切换后新写入不自动回灌旧库,降级需保留新库并阻止旧版本写入或重新配置凭据。

9. OS 沙箱与扩展事务设计

沙箱默认无Vault目录、家庭目录、保险库、原始网络及任意后代执行权限;只挂载校验过的只读包、独立可写scratch。笔记读写经文件broker按当前授权和expected_hash执行;路径以已打开目录句柄约束,覆盖junction/symlink/hardlink与校验后替换。网络broker按HTTPS目标、端口、DNS解析和每次重定向复核;默认拒绝loopback、私网、link-local和云元数据目标。DNS重绑定不能绕过。配置为自托管私网MCP需单独显式目标授权,不能开放整个网段。

许可摘要绑定source、package_id、version、ZIP与展开摘要、入口、参数数组、环境声明、权限集、Vault、平台策略版本及到期时间;任一改变使许可失效。禁止shell拼接。每实例默认512 MiB、16个受管理进程、scratch 256 MiB、单工具60秒;CPU预算固定为单核等效,持续超限10秒终止。无法执行所需限额的平台不得返回“已隔离”。broker本身做请求大小/速率限制,避免扩展绕过进程限额耗尽Host。

Rust安装库置于应用数据目录,记录schema、来源、签名键、两种摘要、依赖锁、配置schema、启用意图、许可和事务日志。旧extension-installations.sqlite3只读导入;外部目录标本地未信任,不移动/删除原目录。用户同意接管的包复制到受管理版本目录后复核,旧许可全部失效。迁移成功设置所有权标记,桌面Python注册API改为代理或拒绝;Web开发模式保留独立数据目录,不共用安装库。

事务:下载暂存 → 签名/撤回/ZIP校验 → 安全解包 → schema/依赖锁 → 确认权限 → 停旧实例 → 备份配置 → 切换活动指针与数据库日志 → 健康检查 → 完成。依赖按拓扑排序;环、缺失、版本冲突在停旧实例前失败。配置迁移在副本上执行,运行迁移代码也必须沙箱化。失败恢复旧包+旧配置,但不恢复已撤销签名或失效许可;这种情况保留旧数据并禁用运行。

下载时沿用Community v1分类限额,禁止将Theme和Plugin限额合并。离线允许浏览缓存、运行已校验且许可未过期的包;新的社区安装因无法复核撤回状态阻止;本地包走独立信任确认。每次联网启动/启用复核撤销,成功收到撤销后5秒内停止相应运行实例。卸载先阻止新任务/检查依赖,再停进程、注销工具并清理受管理版本;外部目录及用户配置默认保留,删除秘密单独确认。

10. 完整同步及生产运维设计

10.1 客户端数据与状态机

保留Sync v1、file_id、operation_id及当前CAS语义,不以路径派生身份。新增remote_heads保存server/vault/file的服务器revision;本地files.revision只表达本地编辑次数。outbox新增server_base_revision、payload引用、attempt、next_retry和状态;同文件后续本地操作需等前序远端确认再确定CAS基线,不能简单复制本地revision。大附件转入不可变本地spool,通过摘要引用,不把100 MiB放入SQLite正文列。迁移旧pending时先对账,未知远端基线进入冲突/首次绑定,禁止猜测base_revision。

上传状态:pending → uploading → uploaded → committing → acked,另有retry/conflict/blocked_auth/blocked_quota。请求响应丢失复用同一operation_id;同ID不得改变payload。分块最大1 MiB,对象最大100 MiB;续传先查询offset。刷新采用会话互斥,轮换成功原子存入Stronghold;刷新响应丢失无法恢复时要求重新登录,不无限重试旧Refresh或丢弃outbox。

拉取:冻结分页boundary → 验证对象长度/摘要 → 持久化inbox → Workspace日志落盘 → 同事务推进已应用cursor和remote_heads。崩溃重放以revision/operation_id去重。存在本地pending的同file_id不能覆盖,保存双方和冲突记录;用户选择本地/远端/另存均形成可追踪新操作。rename/delete复用身份,远端删除遇本地编辑产生冲突,不自动复活。历史恢复创建新revision而非修改历史。

常态主动轮询5秒,错误指数退避1~60秒加抖动,尊重Retry-After;通知未来只作拉取提示。显示本地已保存、待同步数量/字节、最近成功时间、认证/配额阻塞与冲突计数,不能用一个“保存成功”代替同步状态。暂停/解绑保留本地文件,明确封存旧绑定outbox,重新绑定必须对账,不向新Vault重放旧队列。

初次绑定先生成新增/冲突/删除预览;空本地库仅拉取,不把缺失解释为删除。首次启用自动导入现存文件时保存稳定ID映射并防止重复登记。补监听去重和外部重命名对账:无法可靠匹配时展示删除/新增候选,不猜身份。旧Host schema先备份并以事务迁移,失败保留源库;旧客户端遇新schema拒绝写入。

10.2 数据分类与兼容

默认同步Markdown、用户附件、任务、用户Skill/配置、主题配置;任务/配置使用版本化逻辑记录和字段白名单,不能复制SQLite数据库。实现PR需在Sync契约定义这些记录的编码/命名空间及迁移版本,兼容v1文件传输时也不能混入可执行包。对话、Agent历史、人设、布局、一般Provider参数用户选择后同步;运行中任务不跨设备自动恢复。安装清单可选,仅同步ID/来源/版本/摘要,目标设备重下载、重校验、重授权。API Key、令牌、设备许可、环境变量、日志、索引、向量、模型与缓存禁止普通同步。未知配置字段默认排除,需schema升级后放行。

10.3 服务事务与恢复

继续PostgreSQL+私有S3,历史revision/tombstone/已引用对象永久保留,不实施历史GC。过期上传暂存可清理,但须锁定状态、避免与complete竞争;对象写成功但DB提交失败产生的未引用对象先隔离审计,不自动删历史。配额计算包含历史和上传预留,满额拒绝新增,不影响读取/导出。

首发支持单服务节点内2个worker,共享持久staging卷;跨主机水平扩容为非目标。上传offset与磁盘刷盘要定义崩溃恢复:磁盘超过已确认offset截断至确认点,磁盘不足则将上传标损坏并要求重传;不得报告未持久化offset。DB锁串行化同上传写入,complete幂等且对象先于可见revision。读取与上传流式处理,服务以限流/背压保护内存。

S2交付可重复初始化命令,创建私有Bucket和最小权限服务账号、交互创建用户;Secrets由部署环境注入,不写仓库/命令参数。Compose镜像锁定经验证digest并扫描,当前tag存在性与可拉取性在部署门验证。TLS入口与8080 loopback隔离;/health仅存活,/ready探测schema、staging读写和测试前缀S3读写删除,失败返回503。探针不触碰用户对象,超时≤3秒,缓存≤5秒。

备份先暂停写入并排空在途提交,取得DB与Bucket一致切点及对象清单,包含schema、服务版本、游标高水位、摘要与加密备份位置;备份完成才解锁写入。恢复到全新隔离实例,逐个验证所有被历史引用对象,再切换入口。每日备份目标RPO≤24小时、基准1 GiB数据集RTO≤30分钟;事故期间未备份数据的风险必须展示,不把RPO说成零丢失。上传暂存可不恢复,客户端重新申请上传;已提交历史不得缺对象。部署升级先备份,迁移失败不启动新写入;不可逆schema禁止旧服务启动,恢复必须DB+对象同一切点,不只回退镜像。

11. 自动化验收接口与测试矩阵

11.1 现有命令与拟新增命令的区分

当前文档改动使用仓库根的python scripts/check-doc-links.pygit diff --check。实现阶段仍须运行现有检查:

# 以下工作目录均相对本工作树根;不是本次已运行的功能检查
uv run --directory backend pytest
uv run --directory 'server sync' pytest
uv run --directory community-server pytest
pnpm --dir frontend test
pnpm --dir frontend type-check
pnpm --dir frontend build
cargo fmt --manifest-path frontend/src-tauri/Cargo.toml --check
cargo test --manifest-path frontend/src-tauri/Cargo.toml --lib --locked
cargo clippy --manifest-path frontend/src-tauri/Cargo.toml --lib --locked -- -D warnings

验收入口已经建立:仓库根执行python scripts/phase3-production-acceptance.py --suite <suite> --config <isolated-config> --report-dir <output>suite取sidecar/credentials/sandbox/extensions/sync-client/sync-service/e2e/all,支持--case <ID>单例复跑。配置由隔离模板产生,含临时数据根、服务URL、安装包路径、平台profile、seed及秘密的环境引用,不能含生产凭据。runner拒绝仓库个人Vault、未标记隔离环境、非空报告目录和未提交的非 Vault 源码;缺case driver、依赖/安装包/权限或必测项skip均以非零退出,不能只打印成功。生产 driver 正逐项接入,未登记项明确报告 NOT_IMPLEMENTED,不因 runner 接口存在而视为已验收;使用和结果契约见生产验收 Runner

runner输出JUnit、逐ID JSON、耗时/峰值内存、进程树/拒绝访问计数、文件摘要与revision清单及脱敏日志。退出0仅表示该suite所有适用ID通过;all要求显式平台profile并检查缺失项。下表同一行内所有断言均必测,每类输入保留独立子用例;测试代码硬编码预期协议向量或独立oracle,不能用被测函数自证。P0需生成ID清单并校验报告完整性。

ID / suite 操作与可自动验证标准
A-01 / sidecar 干净标准用户VM无Python且禁网,安装已签名包并连续启动20次;Core ready P95≤10秒(无模型加载),20/20可编辑保存;基础安装包≤300 MiB;篡改Core一字节20/20拒启
A-02 / sidecar 覆盖全部可用路由含SSE/二进制及受保护docs;缺失/错令牌/旧代际各100次均401或403且零业务副作用;若关闭docs则始终404且不暴露schema;伪握手/抢占8000不被接受;前端存储、日志、argv、环境扫描测试秘密命中0
A-03 / sidecar 模拟不兼容协议返回PROTOCOL_INCOMPATIBLE且业务写入064 MiB边界/超界、流取消、断流均符合冻结DTO限额;未提交取消无副作用,已提交结果可按operation_id确认
A-04 / sidecar 连续杀Core6次验证退避和熔断;每次本地保存原文摘要不变;关闭Host10秒内受管理子孙进程为0;更新中断每个切换点重启20次均恢复完整兼容组合
B-01 / credentials Provider/Plugin/MCP/Sync每域3个测试秘密;同域调用成功,所有跨域组合被拒;WebView只获引用/状态,无通用明文读取;日志/诊断/同步payload命中秘密0
B-02 / credentials 100条Fernet夹具,含环境主密钥、空库、坏token、重复ID异值、缺钥匙;成功迁移计数/ID/解密值逐条相等;重复迁移3次不增加记录;坏项/冲突使切换停止且旧文件摘要不变
B-03 / credentials 锁屏/手动锁定后1秒内新解析返回CREDENTIALS_LOCKED;错误密码不得解锁;改密后旧密码失败新密码成功;损坏库可恢复测试备份,无法恢复时编辑仍通过
B-04 / credentials 每个迁移持久化边界kill进程20次;恢复只处于完整旧/新状态,无丢失/重复;未确认清除时旧文件始终存在;确认后受管理旧文件不存在,外部环境钥匙未修改;旧版本不得写新schema
C-01 / sandbox 各声称支持的平台运行真实恶意二进制,尝试读写未授权Vault/家庭/保险库/其他包、loopback/公网/私网/元数据/原始socket;每类100次OS或broker拒绝,诱饵文件摘要不变、禁止网络收包0;策略不可用返回SANDBOX_UNAVAILABLE且进程数0
C-02 / sandbox 参数shell元字符、环境注入、子进程逃逸、链接竞态、DNS重绑定、重定向各100轮零越权;授权文件读/工具调用与授权HTTPS各20次成功,证明并非全部禁用来过测试
C-03 / sandbox 逐个改入口/参数/权限/摘要/Vault/策略版本/到期时间均PERMISSION_CHANGED或许可过期拒绝;从Python旧启动API绕过亦拒绝;已撤销许可重启不恢复
C-04 / sandbox 分别耗尽512 MiB内存、256 MiB scratch、16进程、CPU及60秒工具预算;达到上限后≤10秒清理子树,Host不退出且本地保存成功;broker超限请求返回明确限流错误
D-01 / extensions Python生成的Community真实签名向量在Rust验证;签名/ZIP/权限/键撤销任一篡改拒绝;Theme和其他包各边界/超界、穿越/链接/炸弹/重名全部阻止,安装根外新增文件0
D-02 / extensions 受管理、外部、被修改、缺失旧包各一组;只读迁移重复3次记录不重复;外部目录摘要不变;摘要不同不能继承信任;迁移后旧Python写API拒绝且原许可无法启动
D-03 / extensions 每个事务边界注入断电/磁盘满/配置迁移错误各20轮;active包与配置永为匹配旧版或新版,无混合;依赖环/缺包/冲突在停止旧实例前拒绝;失败不扩大授权
D-04 / extensions note-reviewer与markdown-workbench真实安装→启用→调用→升级→回滚→撤回→卸载;收到撤销5秒内进程与注册工具均0;卸载重启不复活,外部路径不删;离线新社区安装拒绝
S-01 / sync-client 两客户端同文件离线连续编辑20次再连;逐操作remote base链有效,最终正文/hash/file_id一致;响应丢失后重复提交100次只产生1条对应revision,无pending静默消失
S-02 / sync-client 100 MiB附件每10 MiB断网并杀进程,查询offset续传;最终长度/hash相等;pull各持久化边界kill20轮,cursor绝不超过已应用revisionremote落盘不新增outbox
S-03 / sync-client 同改、改对删、改对rename、同目标rename、历史恢复各20次:冲突保留两端可恢复内容;解决后双方收敛;空Vault首次绑定产生服务器delete数0;解绑再绑不重放旧队列
S-04 / sync-service 真PostgreSQL+MinIO、2 worker100并发同base不同操作,仅1个成功其余409;相同幂等键同payload重试返回同结果;不同payload拒绝;分页无漏无重;对象先于可见revision
S-05 / sync-service 两worker并发同upload offset、磁盘超前/落后、complete响应丢失、过期清理竞争各100轮;offset不超过持久字节,重复complete不重复计费,无损坏已引用对象;过期暂存在到期后15分钟内清除并释放预留
S-06 / sync-service 跨账号/Vault猜hash、被撤销设备、过期token及上传链接各100请求全拒绝;撤销提交后下一个请求即拒绝;数据库/S3/staging故障后8秒内ready=503,恢复后8秒内ready=200;限流返回429和Retry-After
S-07 / sync-service 自动部署至空实例、重复初始化无数据覆盖;备份1 GiB/10000文件后删测试实例再恢复,所有历史引用对象hash校验100%,RTO≤30分钟且最近备份年龄≤24小时;迁移失败旧数据摘要不变
S-08 / sync-client 分类夹具覆盖默认/可选/禁传/未知字段;默认集合全量往返;未选择的可选数据上传0;秘密/索引/缓存上传0;目标设备安装清单不继承许可;schema不兼容拒写且队列保留
S-09 / sync-service 基准环境10客户端连续30分钟、每秒总20次4 KiB提交,API P95≤500 ms、意外5xx<0.1%、数据校验100%4并发100 MiB上传服务总RSS≤2 GiB10000笔记+附件初次同步≤10分钟,无故障增量收敛P95≤10秒

11.2 分层测试矩阵

层级 环境与覆盖 执行门
单元/契约 Rust状态机、Python认证、前端错误/取消;旧新schema、签名跨语言向量、Sync协议字段 每个实现PR,不能只执行Rust默认lib遗漏desktop功能
集成 实际Host+打包Core+Stronghold+沙箱helperPostgreSQL/MinIO双worker,隔离Vault 对应工作包合入前,AS全部适用ID
故障与安全 网络丢包/重排/重复、磁盘满/权限拒绝、进程kill、恶意ZIP/二进制、迁移中断 每个RC;只在可销毁VM/容器中执行
安装实机 Windows标准用户无Python/无工具链;macOS/Linux各自构建和隔离证据;离线/升级/卸载 每个声称支持的平台,安装包签名验证并实跑
性能与运维 固定基准、20次冷启动、30分钟负载、一致备份恢复 每个RC;原始指标+分位数报告,不能只给平均值
UI端到端 主窗口/锁定提示/凭据迁移确认/扩展权限差异/冲突选择/同步状态;键盘、中文、100/150/200%缩放 两台独立设备实际操作,自动断言+必要截图

12. 端到端验收场景

通过统一runner的--suite e2e --case E-xx执行,实机操作者只完成安装、口令输入及明确用户确认;动作记录与机器断言必须归档,不能用mock替代。

ID 场景与结果
E-01 两台干净Windows设备安装同一签名RC;A迁移测试Fernet,B使用独立凭据;A离线编辑再联网同步,B拉取;两端file_id/hash/remote revision一致,B从未收到A的凭据,禁网时本地编辑持续成功
E-02 两机断网同改一笔记且A删除另一笔记/B修改它;重连展示2个冲突记录及各自内容;分别选择另存/保留本地,最终清单一致、待同步=0、无未确认删除与静默丢失;恢复历史增加revision
E-03 安装两个真实社区样例,授权后执行经Host写笔记并同步;恶意MCP读保险库和访问未授权网络均被拒;升级引入权限变化保持禁用,重新授权后运行;撤回停止实例,卸载不删用户笔记
E-04 Core崩溃、Stronghold锁定、上传途中断网、安装升级中断依次注入;保存摘要始终可恢复;重启后迁移/安装/同步日志收敛,无孤儿进程;恢复旧RC时拒写不兼容schema并能按runbook恢复匹配快照
E-05 停服务并从一致备份恢复到新实例,保留服务器身份配置;两端重新握手后对账;已备份历史hash全等,未备份本地pending仍可上传;撤销设备后该设备下次请求拒绝、UI显示重新授权需求且本地内容保留

13. 可观测性与发布门禁

所有组件结构化事件包含request_id/operation_id、匿名化vault/device标识、组件版本、状态转移、错误code、耗时/重试计数;跨Core/Host/Sync可关联。默认不记录正文、绝对个人路径、Authorization、秘密、完整环境/命令参数。测试种植秘密扫描所有日志、崩溃附件和诊断包必须0命中;诊断包由用户主动导出,默认不含数据库/保险库。日志轮转每文件10 MiB、最多5份;服务默认保留14天,详细审计期限由部署者配置并展示。

指标至少包括Core就绪/重启、保险库锁定/迁移失败数、沙箱拒绝/资源杀死、安装事务阶段/回滚、outbox条数/字节/最老年龄、pull延迟/冲突、API延迟/错误、对象摘要失败、过期暂存、配额、最近可恢复备份时间。禁止使用原始路径/secret ID做指标label。在线且无认证/配额/冲突阻塞时队列最老年龄>60秒持续2分钟告警;备份年龄>24小时、任意摘要不匹配或迁移失败立即告警;意外5xx>1%持续5分钟告警。

门禁 必须提供的证据 / 拒绝条件
G0 设计 P0 ADR、责任人、平台实测原型、字段与错误冻结、ID清单;未确定隔离策略不能进入生产启用
G1 实现 现有CI及desktop编译/测试、五项runner适用ID全部通过;必测skip、Fixture代真服务、缺失报告均阻塞
G2 安全与迁移 A/B/C/D负向测试、上版数据升级和断点恢复;任何越权、秘密泄露、数据丢失、失效许可复活均阻塞,不可凭用户点击豁免
G3 运维与性能 S-0409、E-05、干净部署/备份恢复runbook由另一操作者复跑;容量/时延超阈值须修复或事先评审修改范围
G4 发布产物 每平台独立签名安装包/更新包、Host/Core兼容清单、SBOM/许可证/依赖扫描和SHA-256;高危可利用漏洞未解决则阻塞;发布密钥只在受控发布环境
G5 用户链路 E-01~05、平台能力/非目标/恢复说明、产品待决项已关闭;不把五项完成写成整个第三阶段完成

报告写入CI产物,包含commit、lock摘要、安装包摘要、测试ID、命令、时间、环境与失败日志;验收记录链接产物并标“待验收/通过/阻塞”。报告与签名产物保留至少180天。修改相关代码或依赖后相关门禁失效重跑;文档改动只需文档检查,不能捏造功能测试结果。

14. 非目标与仍需产品确认的事项

明确非目标:移动端、多人共享/CRDT、E2EE与跨设备秘密同步、历史GC、服务跨主机水平扩容、任意远程代码热注入、未通过平台的无沙箱例外;自动下载全部模型/CUDA;替代第三阶段其他UI/内容质量验收。通知推送可后续加入,轮询承担本次正确性与时延门禁。

以下在P0由产品/安全/运维共同确认,当前采用表中工程默认值推进设计,不把未答复当批准:

事项 本计划默认 / 未确认的影响
首发平台与支持声明 Windows 11 x64先验收;macOS/Linux后续门,不能以缩小首发范围取消总阶段三平台要求
凭据体验 用户口令解锁,遗失需恢复备份或重新录入;自动解锁另案;旧Fernet清除必须显式确认
扩展兼容性 首发只支持能通过沙箱及broker的执行配置;需要任意网络/文件/子进程的包拒绝启用,需确认用户可接受范围
同步默认与隐私 按第10.2节默认/可选分类,服务器可见明文;默认每Vault 1 GiB配额沿原型,历史永久保留,满额需扩容不删历史
容量及运维 300 MiB基础包、性能基准、RPO24h/RTO30min与180天证据保留;确定实际部署成本和负责人员
排期及发布责任 依依赖门推进,不承诺未经估算日期;负责人、签名密钥保管、独立安全评审与值班必须落实到人

产品未确认不阻止本规划文档提交,但阻止相应生产范围对外承诺。后续实施以工作包拆PR,不在本次文档提交附带功能代码或用户数据。