Files
NotesAgentic/docs/development/OpenNexus生产化实施进度-2026-09-08.md
T

166 KiB
Raw Blame History

OpenNexus 生产化实施进度

工作树:G:\OSProject\NotesAgent-phase3,分支:feat/phase3-completion。用户已授权实施,正式名称为 OpenNexus。保留旧应用 identifier、内部包名和数据目录约定,避免更名导致旧数据不可见。个人 Vault 的已有改动不属于本次交付。

状态:实施中,未 done,未通过生产发布门禁。 本文记录工程进度,不将单元测试或开发机运行替代生产化计划中 AE 的完整验收。

当前状态摘要

截至 7b69537Host Sync capability 已开启,扩展 capability 仍关闭。笔记与 Task CRUD 已接入当前 Rust Vault;同步具备上传/拉取、冲突解决、非空初始合并、100 MiB 续传、主题和编辑器偏好、持久退避。Workspace 当前 schema 10(上传尝试记录增量后)。凭据备份/恢复及 WTS 撤销已实现,但实机锁屏验收仍缺。

最近完整测试:后端 900 项(Task 增量后)、前端 517 项、Rust desktop 52 项;后两者在重试持久化增量后复跑。以下各节为历史增量,出现的旧 capability、旧 schema 和旧测试数量描述对应当时状态,以本摘要及后续增量为准。OS 沙箱、Rust 扩展管理、剩余逻辑数据类别、完整故障/性能/发布验收仍未完成。

持续实施增量

  • Rust 同步新增 schema 4 inbox/boundary、稳定远端 file_id、remote 来源的移动/删除日志和冲突保留。真实 HTTP 双客户端测试覆盖历史拉取、零回流、本机提交回放保护和同改冲突;文件提交前后的 inbox 重启测试通过。冲突解决和用户界面正在继续实施,仍不开放完整 Sync capability。

  • Rust 同步上传队列与 HTTP 客户端已实现首批链路:持久绑定、spool、冻结远端基线、offset 查询续传及原子确认。20 次离线编辑/重启重试、解绑隔离测试通过;真实本地 Sync 服务验证 20 条 revision 与 100 次提交重放。Sync capability 仍保持 false,等待双向同步、会话与 UI 完成。

  • 桌面全文/向量投影按 Vault 隔离,搜索前经 Host 对账文件摘要;向量重建从 Host 读取正文并保留 file_id。任务和笔记关联使用同一 Vault 的持久库。新增测试覆盖同路径双 Vault 隔离、变更/删除刷新、稳定 ID 和任务跨 Vault 不可见;真实 Core 测试增加全文搜索与删除后的检索验证。

  • 检索隔离增量最终后端全量 899 项通过,真实 Core/Vault 搜索集成和 Rust desktop 全目标 Clippy 通过。语义重建的稳定 ID 测试使用显式测试 Embedding,不作为真实模型质量或性能证据。

  • Core 笔记 CRUD 已经由受控管道接入当前授权 Rust Vault,保留稳定 file_id,支持 CAS 和跨 Vault 拒绝。新增 schema 2 操作回执,记录写入/移动/删除提交结果,升级前保存 schema 1 一致备份。同一写入操作重放 100 次不新增 outbox,也不覆盖后续编辑。

  • 真实 Python Core + 临时 Rust Vault 集成测试覆盖创建、列表、修改、并发冲突、移动、删除、跨 Vault 拒绝和提交查询;Rust desktop 全目标 35 项通过。Core 检索投影、后台任务取消的完整提交边界、大媒体和 UI 提交确认仍需继续实现,不能将 CRUD 接通等同整个 AI 工作流验收完成。

  • 此增量后端全量 897 项、前端全量 94 文件/506 项通过;Rust desktop 全目标 Clippy 与文档链接检查通过。旧 Core 打包产物尚未重新构建,不将开发解释器进程测试作为最新安装包证据。

  • 已修复多实例凭据覆盖与桌面请求取消/超时,证据见全量回归

  • 新增加密凭据备份、原生确认恢复、恢复前留存和逐条完整性验证。Windows 新增 WTS 锁屏/注销/断开通知,原子撤销解析资格;解锁不会随系统返回而自动恢复。设置页同步锁定状态,提供备份和恢复入口。

  • 备份恢复、错误口令保护、锁屏后解析/写入拒绝、原生窗口通知测试通过;后者向专用测试窗口注入消息,不等于真实锁屏时延验收。前端两项交互测试、类型检查、Rust desktop 全目标 Clippy 通过。凭据旧库确认清除和迁移故障矩阵仍待补齐。

已实现的链路

  • Rust 管理 Core 进程组;使用 stdin 引导、随机 loopback 端口、HMAC 握手、独立代际与会话令牌。每个请求先认证,拒绝浏览器 Origin、重复鉴权头及旧代际。Host 关闭时关闭管道并清理进程组,重启具有退避和次数上限。
  • 常规 JSON/二进制及 SSE 请求经原生命令进入 Core。SSE 支持游标、跨 UTF-8 分片及取消;每次流累计不超过 64 MiB,最多 16 个并发流。二进制上传暂为 64 MiB,尚未满足原媒体页面 128 MiB 的完整能力。
  • Core 可由 PyInstaller 构建为带运行时的 onedir。构建脚本生成 SHA-256 清单;release Host 编译时嵌入清单,启动前验证文件集合与摘要,拒绝链接、额外文件和篡改。新增 NSIS 资源配置,但尚未生成或验证签名安装包。
  • Stronghold 采用 Argon2id 口令派生和单文件快照;解锁期间 Store 中仍保存 AEAD 密文。提供状态、解锁、手动锁定、改密和原生选择旧库导入命令,不提供 WebView 通用明文读取命令。
  • Fernet 迁移先验证所有条目与冲突,备份密文和封装主密钥,持久化新库后重新打开逐条比较,最后切换所有权标记。旧文件保留,旧 Python 凭据 API 检测标记后拒绝读写。Core 凭据解析经 Host 管道,不在桌面 Core 使用环境变量凭据回退。
  • 同步服务按已确认 offset 修复磁盘超前,磁盘不足时拒绝续传;对象上传与校验使用流;下载先验证完整摘要再响应。完成回执支持重复确认且不重复计费。过期上传每分钟清理,CLI 提供独立清理入口;启动入口支持共享 staging 的两个 worker。ready 检查数据库、staging 和对象存储,429 带 Retry-After。

已执行的检查

  • 后端全量复跑 894 项测试通过,测试数据使用隔离目录。
  • 前端现有 91 个文件、495 项测试通过;新增流式通道测试后,针对性 4 个文件、8 项测试通过;前端类型检查和生产构建通过。构建仍有部分既有大分块警告。
  • Rust 15 项库测试、Core 清单完整性测试通过;两个真实 Python Core 集成测试通过,其中一个完整执行 HTTP 凭据写入、管道分发和 Stronghold 解析,确认响应与 Core 目录不泄露秘密。
  • Rust desktop 全目标 Clippy -D warnings 通过;工具链为 Windows GNU 1.98.1,不能作为 MSVC 发布证据。
  • 同步服务 23 项隔离 SQLite 测试通过,包含 100 次重复 complete。不是 PostgreSQL/MinIO 双 worker 压测。

尚未完成的工程和验收

范围 尚需完成
Sidecar AI 笔记读写接入当前 Rust Vault;完整路由 DTO 与取消提交确认;恢复诊断、更新事务;128 MiB 媒体传输;签名包、干净 VM 和 20 次冷启动
凭据 OS 锁屏联动;备份恢复与用户确认清除旧库;迁移所有边界故障注入;按真实扩展身份绑定域许可
OS 沙箱 平台隔离实现、Host broker、资源预算与恶意二进制验证;当前未启用无沙箱第三方进程
Rust 扩展管理 签名验证、ZIP 安全边界、持久安装/升级/回滚事务、旧包迁移、撤回与运行时生命周期
同步客户端 Rust push/pull、持久 cursor/inbox、附件续传、绑定隔离、冲突保留与解决 UI、默认/可选数据分类
同步生产服务 真 PostgreSQL/MinIO 两 worker 竞争与负载验证;部署、最小权限、备份恢复、指标与运行手册
发布 统一逐 ID 验收 runnerMSVC 签名安装更新包、SBOM/依赖扫描;两台独立设备 E-01–05

Core 的独立数据目录目前不等于已授权 Vault。Python 旧笔记写入口在 desktop 模式明确拒绝,不能据此宣称 AI 笔记工作流完成。Host sync/extensions 能力仍为 false。缺少实机与签名环境不构成其余普通工程尚未完成的理由。

增量:可恢复的同步冲突解决

  • Workspace schema 5 在修改文件前持久保存解决选择和三个操作 ID;保留本地、采用远端、另存副本均通过现有文件 journal 提交,再归档旧上传队列。启动下一轮 push/pull 时恢复未完成的解决事务。
  • 旧任务进入 conflict/archived 后拒绝上传或提交回执更新;未解决文件暂停发送,其他文件仍可推进。同路径删除后重建使用新的远端 file_id,原删除身份保留为 tombstone。
  • 两个独立 Rust Workspace/会话通过真实本地 Sync HTTP 服务验证三种选择最终收敛及副本独立身份。新增三项测试覆盖文件已提交但解决记录未提交时重启、删除对编辑、远端删除后重建与恢复旧身份。
  • Rust desktop 全目标 42 项通过,Clippy -D warnings 通过。测试服务使用隔离 SQLite/文件对象存储;尚不代表 PostgreSQL/MinIO 部署验收。不同文件身份占用同一路径仍返回明确的需改名错误,解决界面和 Host 会话接入继续实现中。

增量:Host Sync 会话、轮询和设置页

  • 登录/刷新会话按规范化服务器地址和账户分隔,令牌只保存在 Stronghold Sync scope。手动锁定也增加撤销代际,正在等待的网络操作在下一次 50ms 检查时取消;锁定后不再解析新令牌。
  • 设置页提供登录、创建/选择远端库、空库初始绑定、暂停/恢复、退出、解绑和冲突选择。绑定与覆盖决定使用界面确认;HTTP 只有显式勾选测试选项才能启用。冲突使用当前本地摘要做 CAS,旧原始快照仍保留。
  • Host 提供每 5 秒串行同步,先完成固定拉取窗口再发送本地作业;SQLite schema 6 保存暂停偏好。网络失败使用有界退避并尊重 Retry-After;认证、权限、协议等错误停止自动重试并显示。绑定变化/暂停取消旧轮次。
  • 真实本地 HTTP 服务验证 Stronghold 会话存储、强制刷新、关闭重开保险库后复用、退出后旧令牌 401。新增 UI 测试验证密码清空、测试 HTTP 显式传参、确认取消和冲突 CAS 参数。Rust 全目标 43 项与前端全量 95 文件/508 项通过,正式 TypeScript 两项目检查通过。前端测试仍输出既有 KaTeX quirks/localhost:3000 连接警告,没有失败项。
  • 尚未完成:后台轮询真实桌面实机验收、初始非空合并预览、外部文件变化捕获、附件流式持久化及全故障矩阵、数据分类和不同身份同路径解决。不能据此标记所有 S/E 验收 ID 已通过。

增量:外部编辑捕获与大附件崩溃续传

  • Workspace schema 7 将新 write/rename/delete journal 和 outbox 的正文替换为不可变 payload 引用,先 fsync 文件再记录摘要/长度;兼容旧内联正文恢复与上传迁移。100 MiB 不再写入 SQLite 正文列。暂不执行历史 payload GC。

  • 独立 sync_observed 保存上次提交快照;文件树/编辑器读取更新 files 缓存不会吞掉外部变更。后台捕获外部新增、编辑、删除,采用快照校验且不向外部编辑器写回。重复扫描不新增 outbox;删除捕获支持重启恢复。

  • 当前文件分类允许 Markdown 和 attachments 下常用附件类型,排除隐藏目录、已知缓存/日志/模型目录和可执行包扩展名;普通 JSON/配置不会直接复制。旧/新待发作业均检查分类,未支持的远端类型拒绝应用并保留游标。默认任务/Skill/配置等逻辑记录的白名单尚待实现,不作为 S-08 完整证据。

  • 真实本地 HTTP 100 MiB 测试每 10 MiB 在服务端写入后、响应前强杀独立 Rust 客户端,共 10 次。恢复进程复用同一设备会话、查询服务端 offset,最终上传/下载长度、SHA-256、file_id 一致且远端落盘无回流;两个临时 Vault 的元数据文件均小于 5 MiB。最初测试错误地重新登录生成不同设备,按协议无法复用原上传,现已改为通过 stdin 传递同一受控测试会话。

  • 此测试尚未覆盖完整 S-02 的每个 pull 边界 kill 20 轮,也不代表四并发服务 RSS 或生产 MinIO 性能验收。外部 rename 的稳定身份识别和目录大规模扫描优化继续实施。

  • 本增量 Rust desktop 全目标 46 项通过、1 个受父测试驱动的独立进程辅助入口标记 ignored(父测试实际运行并强杀该入口 10 次);Clippy -D warnings 通过。

增量:非空初始合并与文件身份关联

  • 同名独立创建的文件支持保留本地、采用远端、另存副本;先通过 journal 留存旧身份内容,再采用远端稳定身份,旧队列封存。三种选择及中途重开各 20 轮通过,真实双客户端也完成了同名创建后的收敛。

  • schema 8 保存固定远端初始快照。设置页展示上传/下载/相同/冲突预览,每页 100 条;服务器、账户、远端或本地 Vault 变化会清除预览。确认时复核摘要,发生变化返回 SYNC_PREVIEW_CHANGED。初始同步只应用各文件最新可见版本,不重放历史旧路径;历史 tombstone 仅初始化远端基线,不删除本地文件。

  • 初始文件全部落盘或持久保留冲突后,cursor 才一次推进到快照 boundary;任何未完成初始快照都禁止 push。逐文件提交前后重启各 20 轮通过,真实第三个 Workspace 完成相同内容身份采纳、本地独有上传、远端独有下载和冲突解决。

  • Host 保存身份别名,旧文件引用仍可解析;Core 每个 Vault 的投影在身份采纳时同事务迁移本地任务链接,避免外键删除把任务 note_id 清空。新增后端关联测试通过。

  • 目前快照最多处理 100000 条历史 revision,超限明确拒绝;大库快照/扫描性能、任务和配置逻辑同步、完整分类故障矩阵及签名/沙箱等其他生产门槛继续实施。

  • 本增量后端全量 900 项、Rust desktop 全目标 49 项通过(另 1 个父测试使用的进程辅助入口);Sync 界面 3 项交互测试、两个 TypeScript 项目检查和 Clippy -D warnings 通过。

增量:Task 逻辑记录

  • Task v1 使用专用命名空间和 Rust 字段白名单,秘密字段、未知字段/版本在 journal 前拒绝;普通配置文件仍不纳入同步。任务不依赖 Core SQLite 的全量复制,也不触发目标设备自动执行任务。

  • 桌面 Task CRUD 已交由 Host 持久文件和 outbox;同操作创建重复 20 次返回同一结果,不同字段重用 ID 拒绝;更新/删除同样通过操作回执。已有当前 Vault 任务逐条迁移,保留原表且可重复完成迁移。

  • 真实 Core HTTP 验证任务创建/更新/删除/重放、跨 Vault 拒绝、旧任务来源保留;真实 Sync HTTP 验证两客户端任务状态与删除传播。记录列表有 4 MiB 分页上限,读取有 1 MiB 文件上限。

  • 本地文件 ID 采纳后的 task note_id 通过别名解析,上传前生成持久规范化引用,避免把本机旧 ID 留给另一设备。其余逻辑记录类别继续实施。

  • Task 增量后端全量 900 项、Rust desktop 全目标 50 项通过(另 1 个父测试驱动的进程辅助入口),Clippy -D warnings 通过。

增量:主题与编辑器偏好逻辑记录

  • Host 新增两个仅限主窗口、校验当前 Vault 的偏好命令;Rust 逐字段校验主题和编辑器设置,普通 JSON、权限、密钥和本机路径不进入记录。
  • 设置编辑先保存按 Vault 隔离的持久草稿,再通过 CAS 写入 Workspace。覆盖选择串行等待在途写入,选择远端期间的新编辑不被丢弃;存储删除失败时保留内存及磁盘草稿并报告失败。远端主题应用不产生同步回流。
  • 初始上传和合并预览包含当前偏好;空库下载不提前创建记录。真实双客户端 HTTP 测试新增主题记录传播,嵌套未知字段和非法值由 Rust 测试验证。
  • 本增量全量前端 97 文件 / 515 项通过;其后补充存储故障修复,两文件 7 项针对性测试通过。TypeScript 两项目检查通过,Rust desktop 全目标通过(数量见测试日志),Clippy -D warnings 通过。测试日志为 .build/preferences-frontend-tests.log.build/preferences-rust-tests.log。生产签名、OS 沙箱、Skill/配置等未完成项仍未通过整体验收。

增量:跨重启的同步退避和停止状态

  • Workspace schema 9 持久保存每个绑定的错误码、失败次数、下次重试时间及 halted 状态。旧 schema 升级前保留独立 SQLite 备份。重启后自动同步沿用该状态;成功、同账户登录恢复或手动继续会清除当前绑定状态。
  • 取消/切换绑定不增加失败次数,旧绑定回调不能修改新绑定;保存的错误仅允许有长度限制的机器码,不保存服务端任意响应正文。Retry-After 和指数退避保持 1–3600 秒限制。界面对停止自动重试状态不再显示误导性的倒计时。
  • 连续关闭重开 20 次验证失败次数与时间保留,另验证认证停止、状态清除、取消、错误正文过滤和新旧绑定隔离。当前是绑定级轮次状态;每个上传作业的独立尝试历史、强制刷新后的 401 重试和完整服务故障矩阵仍需完成。
  • 全量前端 97 文件 / 517 项、Rust desktop 全目标 52 项通过(另 1 个父测试驱动并强杀的辅助入口);TypeScript 两项目检查和 Clippy -D warnings 通过。日志 .build/retry-frontend-tests.log.build/retry-rust-tests.log。Core 打包正在更新,不视为签名发布包。

增量:最新 Core 打包与 20 次冷启动

  • 使用锁定 packaging 环境重新生成 PyInstaller onedir,清单包含 1523 个文件。构建日志 .build/core-build-production.log,产物 .build/sidecar/dist/opennexus-core.build/sidecar/manifest.json
  • 新增显式打包测试 cargo test --locked --features desktop --test core_bundle packaged_core_twenty -- --ignored,调用实际可执行文件并在每次启动前校验完整文件清单。20 个独立临时数据目录、20 个不同会话代际、带鉴权和代际头的 HTTP 健康请求全部成功,逐次退出后端口关闭。测试耗时 95.64 秒,日志 .build/core-packaged-cold-starts.log。初版测试遗漏代际请求头导致拒绝,修正测试后通过。
  • 该测试按要求先构建后显式运行,普通源码全目标测试会跳过此入口。Clippy -D warnings 通过。此证据来自当前 Windows 开发机,不能替代干净 VM、MSVC 签名安装包、两台真实设备或完整 A-01 验收。

增量:401 恢复与每作业持久尝试记录

  • 协调器对可重放的同步轮次收到 401 时仅强制刷新一次;刷新仍校验设备身份且受凭据锁撤销。刷新失败或第二次 401 返回停止错误,403 不刷新。普通非幂等业务创建没有套用重放包装。
  • 真实本地 HTTP 测试先在隔离数据库中提前过期 Access Token,确认读取经一次刷新恢复;删除测试会话后 Refresh 也被拒绝,不重新登录、不注册新设备。另注入连续 401 和 403,分别确认最多两次与一次操作调用。
  • Workspace schema 10 保存每个上传作业的累计尝试次数与 running/failed/interrupted/succeeded 结果;普通取消通过析构记录中断,进程强杀则由重开修复。文件已确认而结果未记录时,恢复以已持久的 ack 为准。错误只保存限定机器码;待处理作业最多展示 20 项恢复记录。
  • 20 次重开验证尝试累加且冻结的提交载荷不变;取消测试确认无需重启即显示 interrupted。真实 100 MiB 十次强杀后,重开查询准确显示 10 次尝试与 interrupted,最终继续上传、下载与摘要校验通过。测试过程使用独立临时 Vault 和服务账号。
  • Rust desktop 全目标 53 项通过,之后新增取消测试单独通过;更新后的真实 HTTP 集成再跑通过。两个 ignored 入口分别是已在前轮显式运行的打包测试和父测试实际驱动的强杀辅助进程。前端 SyncSettings 5 项、两项目 TypeScript 检查及最终 Clippy -D warnings 通过。日志 .build/job-recovery-rust-tests.log.build/job-recovery-http-tests.log;本增量无 Python 变更。
  • 此增量不等于完整 S-02/S-03 故障矩阵,pull 各边界 20 次强杀、同目标 rename 与历史恢复等完整验收仍需推进。

增量:Rust 扩展签名与 ZIP 验证基础

  • 新增 Rust Release v1 验签及有界 ZIP 检查,真实 Python canonical JSON/Ed25519 向量验证通过;逐个签名字段篡改、错误公钥/签名者、撤回和键撤销均拒绝,ZIP 摘要另行核对。
  • ZIP 原始中央目录预检阻止映射覆盖隐藏重复项、本地头不一致和重叠数据。测试覆盖穿越、Windows 特殊路径、Unicode 大小写重名、文件/目录前缀、链接、加密和 CRC 损坏。Theme 的 5/10 MiB 与 100 条、其他包的 10/50 MiB 与 2048 条边界和超界通过。
  • 新增锁定依赖 ed25519-dalek 2.2.0 与 unicode-casefold 0.2.0;复用已存在的 zip 8.6.0、Unicode normalization。声明 Rust 下限调整到 ZIP 库要求的 1.88,实际验证仍使用本机 GNU 1.98.1,尚无最低工具链或 MSVC 发布证据。
  • Rust desktop 全目标 58 项通过(另两个既有显式/辅助入口 ignored),随后补充较新 Unicode 大小写映射,4 项包验证测试复跑通过,最终 Clippy -D warnings 通过。日志 .build/extension-verification-rust-tests.log。期间一次链接被仍在运行的测试 EXE 占用;确认原进程完成后,针对性测试重跑通过。
  • 此批只验证包,不提取、不安装、不执行。清单身份/权限和 schema、在线撤回复核、单一安装库、迁移及事务尚未完成,extensions capability 维持 false,完整 D-0104 仍未通过。

增量:有界类型清单与发行一致性校验

  • verify_package 串联签名、ZIP 全字节检查和清单解析,返回经过检查的摘要清单及声明内容。清单最多 1 MiB / 32 层 / 10000 节点 / 单文档;重复键、循环别名、文件包含、未知 schema_version 和非法 JSON 拒绝。YAML 解析关闭环境插值与文件包含特性,错误不回显正文。
  • Theme 保持专用 theme_idSkill/Plugin 兼容 Runtime 实际包使用的 id 与专用类型 ID,双声明冲突拒绝。发现并修复 Community 服务此前会拒绝项目自带 id 清单的兼容问题;两端均使用 markdown-workbench/note-reviewer 实际文件验证。
  • 版本与权限集合须匹配发行;人设/模板/MCP/模型基本结构和递归秘密字段校验已加入。此处尚不替代各 Runtime 完整配置 schema、运行许可与 OS 沙箱。
  • 锁定 serde-saphyr 1.2.0 的 deserialize 特性与传递依赖,按其要求将声明 Rust 下限调整至 1.89;实际仍为 GNU 1.98.1,不作为最低工具链测试证据。
  • Community 全量 15 项通过(两个既有弃用警告);Rust desktop 全目标 61 项通过(两个既有特殊入口 ignored)。随后核对 Theme 专用 ID,7 项扩展验证复跑与最终 Clippy -D warnings 通过。日志 .build/extension-manifest-rust-tests.log
  • 安全解包写盘、在线来源/撤回复核、安装库迁移、依赖与配置升级事务、授权和运行生命周期仍须实现,完整 D-01–04 和整体生产化继续进行。

增量:Rust 持久扩展暂存库

  • 新增独占应用目录的扩展暂存库 schema 1;只接收通过签名、ZIP、清单检查的发行。先 fsync 不可变 ZIP 对象,再在同一 SQLite 事务保存版本元数据和操作回执。来源/命名空间/包/版本组成不可变身份,签名内容改变不得原地替换。
  • 同操作重放返回原回执,仍重新检查撤销标志和 ZIP 完整性;不同请求重用操作 ID 拒绝。数据库和分页列表仅声明 staged,不声明安装/启用,也不产生运行许可。暂不清理无引用对象,避免中断后删除恢复材料。
  • 对象写入后、版本记录后、回执记录后、事务提交后,各注入错误并重开 20 轮,均恢复为一份版本及回执。另验证独占锁、不可变发行、撤销重放拒绝、对象损坏拒绝、数据库及 WAL/SHM/journal 预置硬链接拒绝且目标原文件不变。
  • Rust desktop 全目标 64 项与 Clippy -D warnings 通过;日志 .build/extension-store-rust-tests.log。这些是受控错误注入,不能替代完整 D-03 的真实断电/磁盘满矩阵。安全解包、活动版本和配置切换、在线信任/撤回、旧库迁移及运行生命周期尚待接入。
  • 同轮复查远端测试 Sync 的 /ready 返回 503 / DEPENDENCY_UNAVAILABLE,正继续定位;不视为服务器验收通过。

远端测试服务就绪复查

http://yui.kronecker.cc:18080/health 返回 200 / status=ok/ready 返回 503 / DEPENDENCY_UNAVAILABLE。SSH 域名地址与公开 AAAA 地址均在认证前关闭连接、未返回 banner,尚无法读取 Docker/数据库/对象存储诊断。未执行任何远端修改,也未判定为密码错误。已询问 SSH 入口是否改变;本地工程继续推进,不因这一单项暂停整体目标。证据 .build/acceptance/sync-readiness-current.json

增量:确定性依赖锁与兼容性预览

  • 暂存库新增只读依赖预览,固定根发行,只使用同来源候选;无命名空间的键归属当前命名空间,显式 namespace/package 也必须来自同来源。较新版本优先,遇到菱形冲突会回溯选择满足全部约束的版本,结果按依赖先于使用者输出。
  • 裸完整版本表示精确约束;范围采用明确的 Rust SemVer 语法,未知范围拒绝。应用 min/max、平台和架构不兼容拒绝;缺包、版本冲突、依赖环或预算超限不返回部分计划。
  • 锁定结果绑定包身份、完整签名发行、ZIP、签名者、权限及目标应用/平台/架构。选中包重新从暂存对象读取并校验签名和清单;重开后摘要稳定,归档损坏会拒绝。尚无安装/停止实例的副作用。
  • 预算为同源 4096 候选 / 64 MiB 元数据、200 解析包、10000 搜索展开与 4 MiB 预览编码。测试覆盖输入乱序、菱形回溯、环、缺包、精确版本、平台不兼容、来源/命名空间隔离、深图和过大预览。
  • Rust desktop 全目标 69 项通过(两个既有特殊入口 ignored);其后补充预览编码上限,4 项依赖测试和最终 Clippy -D warnings 通过。日志 .build/extension-dependencies-rust-tests.log。依赖使用已锁定的 semver 1.0.28。
  • 正式安装的在线撤回复核、权限确认、解包与包/配置原子切换、健康检查和回滚仍未完成,不能据此通过完整 D-03/D-04。

增量:目录句柄内安全解包

  • 新增 extension_unpack,入口重新验证签名、ZIP 和类型清单,在应用私有 staging 根目录下创建随机 UUID 目录。子目录逐级以 nofollow 句柄打开,输出使用 create_new;ZIP 内路径不用于环境绝对路径写入。依赖锁定 cap-std / cap-fs-ext 4.0.3。
  • 写入后重新遍历,核对精确文件集合、内容摘要和总展开大小;拒绝多余空目录、缺失/额外文件、符号链接、硬链接和 Windows reparse 文件。树摘要使用路径长度、路径、文件长度及文件内容组成的明确编码,独立于 ZIP 摘要和既有 Python package_digest,不可混用。
  • 文件逐个 sync_all,Unix 同步目录项;失败目录保留隔离状态,不标记为当前安装。未验证 Windows 断电持久性,也未将静态链接测试等同于完整并发替换攻击防护。
  • 17 项扩展模块回归和全目标 Clippy -D warnings 通过,日志 .build/extension-unpack-tests.log。新增实际 Windows junction 越界拒绝、硬链接替换拒绝、原文件不变、篡改/缺失/额外文件及空目录拒绝测试。
  • 此模块尚未接入持久安装操作、在线撤回复核、权限审批、原子切换或健康检查;扩展执行能力仍关闭。远端 Sync ready=503 和 SSH 认证前断开问题也尚未解决,不宣称整体生产化验收完成。

增量:持久化解包准备与升级恢复

  • ExtensionStore.prepare 接入已验证暂存包,要求调用者提供当前签名者和撤销状态;首次及重放均核对签名、归档、清单,重放还重新读取已准备目录的精确文件集合和摘要。数据库中的目录名只接受规范 UUID,不能提供任意路径。
  • schema 2 新增 prepared_packages,记录每个不可变包的准备目录和树摘要。解包完成、记录写入、事务提交三个边界分别注入错误并重开 20 次,最终只有一份有效记录,重放结果稳定。提交前遗留的隔离目录暂不回收,避免误删恢复材料;这不是安装事务或真实断电验收。
  • schema 1 升级前 VACUUM INTO 创建独立备份并同步。测试验证原暂存版本不变、备份可读且仍为 schema 1、重复打开不再备份;修复 Windows 只读文件句柄无法执行备份 sync_all 的问题。
  • 19 项扩展回归通过,日志 .build/extension-prepare-tests.log。当前仍只产生准备结果,未开放扩展执行或自动授予权限;在线信任刷新、依赖集合安装、配置切换、健康检查及回滚继续待完成。

增量:Host 运行许可内容绑定

  • 新增 extension_permitHMAC-SHA256 绑定来源、命名空间、包/版本、ZIP/展开/签名者摘要、入口、参数数组、环境声明、权限集、Vault、平台、策略版本及到期时间。BTree 容器提供确定性编码,令牌本身仅为认证码;未向 renderer 提供参数或环境声明。
  • Authority 使用系统随机密钥,销毁时清零;到期边界、不同 Authority、全部失效后的旧令牌均拒绝。环境凭据使用 scope 声明,调用方不得向声明填入实际秘密。输入和编码大小有上限,入口穿越、错误环境名和 HTTP 社区来源拒绝。
  • 测试逐字段改成另一份仍合法的声明,确认认证码不再匹配,避免把输入格式拒绝误认为绑定测试通过;另测到期、密钥轮换、路径及体积边界。21 项扩展回归与全目标 Clippy -D warnings 通过,日志 .build/extension-permit-tests.log
  • 这是许可认证原语,尚未接入安装确认、在线信任、锁定事件、运行沙箱或 broker。它不证明用户已同意,也不授予执行能力;完整 C/D 验收仍未通过。

增量:包与配置活动指针的组事务

  • extension_transaction 在单一 SQLite 事务中保存旧状态、整组新包/配置指针和 checking 日志;期望 revision 不匹配、重复 slot、已有待检查事务或操作 ID 被不同请求重用均拒绝。健康结果提交后才清除 pending;失败整体恢复旧元组,首次安装失败移除新指针。

  • 暂存库 schema 3 接入,升级 schema 1/2 前保留对应备份。switch_prepared 重新检查签名归档和准备目录,并按 Vault、来源、命名空间和包 ID 推导 slot,拒绝跨 Vault 指针。打开库时未完成 checking 自动回滚,不恢复任何执行许可。

  • 三个切换边界分别注入错误并重开 20 次,两个包与各自配置始终匹配;另测 CAS、busy、操作重放、失败首次安装、健康成功后重开保留、目录损坏拒绝及 Vault 绑定。24 项扩展回归和全目标 Clippy -D warnings 通过。

  • 这仍是安装事务的存储层:配置只要求对象,完整类型 schema/秘密剥离、依赖计划和用户确认复核、在线撤回、停旧实例、沙箱内迁移、真实健康探测及 UI 尚待编排。不能把注入错误重开测试当成 D-03 断电/磁盘满完整矩阵,也不能开启 extensions capability。

  • 本轮 Rust desktop 全量回归 78 项通过,2 个既有特殊入口 ignored;实际 Sync 子进程中断恢复由父测试执行通过。全量日志 .build/extension-transaction-rust-full.log

增量:切换前的签名配置 schema 校验

  • switch_prepared 从重新验证的签名清单读取 configuration_schema,配置不能自带替代 schema。未声明时只接受空对象;声明使用 Draft 2020-12、离线 jsonschema 0.55.0(关闭默认网络/文件解析功能),启用格式检查和线性正则引擎。
  • schema 与配置各限 64 KiB、4096 节点、24 层;当前拒绝所有引用,包括本地引用,避免 Host 执行递归 schema。高级正则、其他 schema draft 不接受;此限制应在安装 UI 中明确展示,尚无完整配置编辑 UI。
  • 配置递归拒绝常用秘密字段;writeOnly / x-opennexus-secret 声明禁止持久化对应值,包括条件和组合分支,不能通过 anyOf 的另一个分支绕过。此规则对条件分支采取保守拒绝;秘密应由后续凭据 broker 提供,任意普通字符串不能被自动识别为秘密。
  • 测试覆盖嵌套类型、范围、未知属性、错误 schema、引用、深度/体积、秘密声明和组合绕过;安装入口拒绝秘密配置后事务表保持为空。26 项扩展回归通过,日志 .build/extension-config-tests.log
  • 这不替代各扩展类型的完整运行配置契约、用户确认、在线信任与沙箱,也没有完成配置迁移/导入秘密的完整流程。整体生产化继续未完成。

增量:社区在线信任复核入口

  • 新增 HTTPS Community 客户端,复核 source_id、原固定公钥/命名空间、键撤销、发行撤回及完整发行内容。重复版本、键替换、未知响应、非 200(含重定向)、离线均拒绝;不接受刷新时自动信任新键。每请求 15 秒、JSON 4 MiB、集合 4096 项上限。
  • Checked 凭据由客户端内部构造,绑定规范来源、完整发行摘要和公钥摘要,单调时钟 30 秒过期;不序列化持久保存。switch_online 限同源组,所有准备目录与配置检查后、写入事务前再次复核时效。
  • 受控真实 HTTP socket 测试覆盖正常、撤销、键替换、撤回、内容变化、重复版本、503、302 和过期;HTTP 仅测试内部替换 URL,公开构造器只允许 HTTPS。27 项扩展回归与 Clippy 全目标检查通过,日志 .build/extension-trust-tests.log
  • 尚未取得真实 HTTPS Community 部署验收;固定键来源仍要求 Host 信任设置提供,尚无设置 UI/轮换确认和运行期撤销停止循环。底层 switch_prepared 仍是未接 IPC 的内部安装存储原语,正式入口应调用 switch_online;离线本地包需独立信任流程。不能据此开启扩展执行或通过 D-04。

增量:Host 持久来源公钥确认

  • 安装库 schema 4 新增来源/命名空间/键 ID 信任记录,包含来源身份、固定公钥和启用状态。升级前保留旧 schema 备份;旧暂存发行不会自动变成受信来源。
  • confirm_trust 绑定完整候选摘要和原 revision,首次确认、密钥轮换或禁用均需匹配的确认数据;并发改变后的旧确认拒绝。同一规范来源 URL 不允许混入第二个 source_id。该 API 尚未接入用户 UI,传入摘要本身不证明已获得用户同意,未来只允许受控主窗口确认流程调用。
  • switch_online 不再接受外部 source_id 参数,使用已确认且启用的 Host 信任设置,要求公钥与暂存签名者相同后才联网。测试验证未知来源、禁用和不匹配公钥均在写入安装日志前拒绝;不会因暂存包验签通过而自动信任其签名者。
  • 29 项扩展回归与全目标 Clippy -D warnings 通过,日志 .build/extension-trust-settings-tests.log。覆盖重开恢复、候选确认不匹配、轮换 CAS、禁用持久化、来源身份冲突和在线入口拒绝。
  • 来源设置 UI、确认路由、撤销状态持久传播、运行期停用、迁移及真实安装编排仍未完成,整体生产化继续未完成。

增量:撤销和撤回的持久拒绝

  • Community 复核区分 EXTENSION_KEY_REVOKED 与 EXTENSION_RELEASE_WITHDRAWN;先匹配固定公钥/身份或完整发行内容,再接受对应撤销状态,避免把另一份元数据的撤回误记到当前包。
  • schema 5 保存持久拒绝记录。键撤销绑定来源、命名空间、键 ID 和公钥摘要;发行撤回绑定来源、命名空间、包与版本。在线入口收到确切撤销后写入,网络失败不会写入;普通信任确认不会清除拒绝记录。
  • 在线及底层准备切换均检查持久拒绝。重启后仍拒绝,发行撤回不影响其他版本,旧键撤销不自动禁止另一个显式确认的新公钥,但新公钥也不能复活已撤回版本。
  • 30 项扩展回归与全目标 Clippy -D warnings 通过,日志 .build/extension-revocation-tests.log。测试覆盖持久性、信任确认后仍拒绝、不同版本/来源/公钥范围和网络失败不污染拒绝记录。
  • 尚未接入运行中实例和工具注册表的撤销轮询/停止,不能据此声明 D-04 的 5 秒撤销目标通过。恢复旧指针仍可保留数据,但不授予运行许可。

增量:完整安装预览与持久确认计划

  • installation_preview 组合确定性依赖锁、全部包权限、配置、准备目录/展开摘要、信任设置摘要、目标 Vault/应用/平台/架构及当前活动 revision。未信任、已撤销、错误配置、非计划包配置或待健康检查事务均拒绝,预览不切换活动指针或授予许可。
  • install_confirmed 首次执行重新生成预览并比较确认摘要,再进入在线复核。schema 6 保存操作 ID 对应的请求摘要、确认摘要和冻结切换组,网络或进程中断重试沿用原组;改变请求/确认并重用 ID 拒绝。重试仍经过来源/撤销/归档/配置检查和活动 revision CAS。
  • 31 项扩展回归与全目标 Clippy -D warnings 通过,日志 .build/extension-install-preview-tests.log。新增预览重开摘要稳定、应用版本/活动状态变化使预览失效、错误确认在联网前失败、未知配置拒绝,以及确认计划重开重放不重新选择内容的测试。
  • 真实主窗口确认 UI、Host 注入的应用/平台信息、旧实例停机、沙箱迁移和健康探测仍待接入。确认摘要 API 本身不证明用户授权;本轮没有执行第三方包或宣称整体生产化完成。

增量:受控桌面信任确认与预览命令

  • Host 启动时打开应用数据目录 extensions-host 安装库并持有独占锁;新增 extension_trust_review / extension_trust_confirm / extension_install_preview 命令,Tauri ACL 仅授予本地主窗口,命令额外核对 main 标签,未增加远程来源权限。
  • 信任复核把完整候选、原 revision 和摘要保存在 Host 内存,返回随机 review_id。最多 64 个待确认项、两分钟单调时钟有效期;确认仅接收 ID 和摘要,不能替换候选。成功消耗凭据,过期/重用/不匹配及并发设置改变拒绝。
  • 安装预览由 Host 注入应用版本、OS 与架构,renderer 只提交根包、当前 Vault 和配置;后台阻塞任务中保持 Vault 绑定稳定并调用完整预览。尚未开放实际安装执行命令。
  • 桌面二进制 5 项测试和全目标 Clippy -D warnings 通过,日志 .build/extension-commands-tests.log。新增确认凭据生命周期与并发冲突测试;ACL 文件及生成权限项已更新。
  • 前端确认对话框、桌面包下载/暂存入口、安装执行编排、沙箱及真实 UI 验收尚待完成;extensions capability 仍关闭。本轮不宣称生产化或 D-04 完成。

增量:社区来源确认界面接入 Host

  • 桌面社区检查来源后请求 Host 复核,对话框展示 source_id、候选公钥、原有设置和确认摘要;只有点击确认才调用 Host 确认命令,成功后更新本地目录设置。启用/停用也经同一确认流程更新 Host,旧本地来源不自动迁入信任库。
  • 新增 extensionTrustService,规范 HTTPS 来源、公钥解码和数量限制;确认只传 Host 签发的 review_id 与摘要。两分钟过期或并发冲突提示重新检查;多键确认是逐键调用,部分失败可能已有部分键完成确认,界面不声称整组成功,需重新检查后处理。
  • 来源发现保留服务端 source_id,Web 开发保留本地来源流程。对话框中的错误可见,忙碌时禁止重复确认。
  • 前端全量 99 文件 / 521 项通过,两套 TypeScript 项目检查通过;日志 .build/extension-trust-ui-tests.log。新增服务参数/非法输入测试与 Vue 组件确认前无写入、Host 拒绝后不保存测试。测试使用 Host mock,不等同于真实桌面 UI 端到端验收。
  • 桌面包下载暂存、安装确认 UI 与执行编排、沙箱、真实双端及部署验收仍未完成;整体生产化目标继续进行。

增量:桌面 Host 下载和验证暂存

  • 主窗口新增 extension_stage 命令。桌面社区按钮提交签名发行元数据给 Host,剥离 release_id/withdrawn/download_path 展示字段,Host 使用固定来源设置自行复核在线发行并取得归档地址;renderer 不再调用浏览器下载及旧 Python/主题安装路径。
  • 归档地址由复核的发行 ID 构造,并要求服务端 download_path 精确匹配。下载禁止重定向、限制主题 5 MiB/其他 10 MiB,并按签名声明大小执行流式上限;下载后重新验签、检查 ZIP 与类型清单,并核对信任时效,再写入不可变暂存对象及操作回执。
  • Host 下载在后台阻塞任务中执行,持有安装库锁保持串行。当前 UI 取消不取消已派发的原生暂存任务,任务最多受请求超时约束且只产生暂存;后续需接入统一取消/进度流程。
  • 32 项扩展回归、Clippy 全目标、6 项前端针对性测试和两套 TypeScript 项目检查通过。Rust 日志 .build/extension-download-tests.log;真实 socket 覆盖归档内容错误、无 Content-Length 超长流、302 拒绝和正确 Python 签名归档。
  • 桌面文案明确“已校验并暂存,尚未安装或启用”。缺失依赖自动获取、完整安装 UI、停止实例/健康探测、沙箱和真实 HTTPS 部署验收仍待完成,不视为整体生产化完成。

增量:原生暂存取消与提交状态查询

  • 暂存采用独立 Host Requests 预留/领取/取消流程,60 秒总期限,派发前取消不会运行任务;等待安装库锁时也检查取消。网络 future 由 Lease 驱动取消,同步暂存各持久边界复查取消状态。
  • 主窗口新增 prepare/cancel/status 命令及 ACL。客户端在预留后注册取消,覆盖预留响应与派发之间的竞争;取消后查询持久操作回执,若提交先完成则返回“取消前已完成暂存”。同一页面未开始其他任务时保留这条结果。
  • 回执查询不把已提交状态伪装成取消回滚。提交前取消可能留下不可见的孤立归档对象,暂存版本/回执事务回滚;提交后取消保留原回执。未增加对象 GC 或跨重启任务列表。
  • 33 项扩展回归、4 项请求生命周期测试、7 项前端针对性测试、全目标 Clippy 和两套 TypeScript 项目检查通过;日志 .build/extension-cancel-tests.log。请求生命周期包含真实 socket 取消关闭测试,新增对象写入后/回执记录后/提交后的取消回执区分。
  • 完整任务进度列表、跨重启 UI 恢复、安装执行编排与沙箱仍未完成;整体目标继续进行。

增量:桌面暂存列表和安装预览界面

  • 新增仅本地主窗口可用的 extension_staged 分页命令,界面从 Host 持久安装库加载暂存包,每页 20 项;暂存完成后刷新,重启不依赖 renderer 缓存重建包列表。
  • DesktopPackages 对话框允许输入根包配置,调用 Host 完整预览,展示依赖拓扑顺序、请求权限和检查后的配置。当前 Vault、请求代次和选中根包共同约束返回结果,切换 Vault 关闭预览并丢弃迟到响应。
  • 5 项前端针对性测试、两套 TypeScript 项目检查和 Rust 全目标 Clippy -D warnings 通过。新增组件测试验证使用 Host 列表、精确 Vault/配置参数、只发预览命令,以及切库后不显示旧权限结果。
  • 页面明确安装执行尚未开放;依赖包配置编辑、自动取得缺失依赖、正式确认执行、沙箱与真实端到端验收仍未完成。整体生产化目标继续进行。

修复:多公钥来源的原子确认

  • 新增 extension_trust_confirm_group,前端一次提交整组 Host 复核凭据。Host 先核对数量、重复凭据、过期与摘要,再由安装库 savepoint 一次确认同来源全部键;不同来源/来源身份或重复键拒绝。
  • 任一后续键发生 revision 冲突时,前面已执行的更新全部回滚;确认凭据只在整组成功后一起消耗。此变更替代此前文档中逐键确认可能部分成功的流程。
  • 34 项扩展回归、2 项 Host 确认测试、3 项前端针对性测试、全目标 Clippy 和两套 TypeScript 项目检查通过。日志 .build/extension-trust-group-tests.log。验证后续键冲突后重开仍无部分更新,以及失败保留有效凭据、成功全部消耗。
  • 真实桌面确认链路端到端、安装执行、沙箱及总体生产化验收仍未完成。

增量:Windows Job Object 资源容器

  • 新增 extension_job,创建无可继承句柄的 Job,设置组提交内存 512 MiB、活动进程默认 16、关闭最后句柄时杀死进程;不启用 breakaway。CPU 使用 hard cap,按系统活动逻辑处理器数向下取整分配至单核等效份额;任一设置失败不返回可用容器。
  • assign_suspended 明确要求调用方持有尚未恢复的 CREATE_SUSPENDED 进程,出错须终止它,全部隔离/许可检查后才能 ResumeThread。该模块只有资源约束,尚未接入第三方运行入口,也不具备文件、网络或身份隔离。
  • 4 项真实 Windows 进程测试与全目标 Clippy -D warnings 通过,日志 .build/extension-job-tests.log。三个 ignored 条目是由父测试实际启动的辅助入口。验证进程配额为 1 时第二进程被拒绝且从未恢复、关闭 Job 后进程退出、受管理后代计数归零、显式终止,以及正常 32 MiB 分配成功/600 MiB 分配失败。
  • 测试初次使用固定等待观察进程计数失败,改为最多 5 秒等待计数收敛后通过;不将单次固定延时当作清理证明。生产参数测试读取 OS 返回的内存、进程和 CPU 配置,但尚未完成长时间 CPU 压力、10 秒超限终止及 scratch 配额测试。
  • API 依据 Microsoft Job Objects 与 JOBOBJECT_CPU_RATE_CONTROL_INFORMATION 文档: https://learn.microsoft.com/en-us/windows/win32/procthread/job-objectshttps://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-jobobject_cpu_rate_control_information 。AppContainer、文件/网络 broker、恶意程序矩阵及实际扩展调用仍待完成,不能据此通过 C 项或开启 extensions capability。

增量:AppContainer 配置所有权与原生身份验证

  • 新增 extension_container::Profile,为每个实例创建随机 OpenNexus.sandbox 名称、无声明能力的 AppContainer 配置,校验 SID 并提供 OS 返回的配置目录。同名已存在时拒绝,不接管或删除旧配置;显式 remove 报告清理失败,Drop 尝试最终清理并释放 SID。
  • 真实 Windows 测试创建两个配置验证 SID 不同、重复名称失败不破坏原配置、显式删除后可重新创建。另用 SECURITY_CAPABILITIES 创建挂起的系统进程,先加入 Job,再读取 TokenIsAppContainer、TokenAppContainerSid 与 TokenCapabilities,确认容器身份、精确 SID 和零能力;没有恢复命令解释器执行。
  • 空环境及仅 SystemRoot 的启动尝试返回 Windows 203;使用明确的 SystemRoot 和指向容器自身目录的 LOCALAPPDATA/TEMP/TMP 后通过。此处是测试启动环境,不是完整生产环境/参数构造器。
  • 两项 AppContainer 原生测试与全目标 Clippy -D warnings 通过,日志 .build/extension-container-tests.log。API 依据 Microsoft CreateAppContainerProfile / DeleteAppContainerProfile / Launch an AppContainer 文档。所有测试创建的配置通过所属对象清理,未借用既有用户配置。
  • 生产启动器、包只读 ACL、独立 scratch 配额、原始网络拒绝实测、文件与网络 broker、崩溃后孤立配置清理以及恶意程序矩阵仍待完成。当前不声明完整沙箱,也未开启 extensions capability。

增量:按句柄授予 AppContainer 包只读执行权限

  • Profile 新增 grant_package_read_execute,只对 Host 已打开并验证的单个文件或目录增加该实例 SID 的读取/执行 ACE,不启用子项继承。通过 GetSecurityInfo / SetEntriesInAclW / SetSecurityInfo 操作同一对象句柄,分配的安全描述符与 ACL 由 RAII 释放;拒绝重解析对象、硬链接、空 DACL 和权限不足的句柄。调用方仍须按句柄验证整个包并在启动期间持有这些句柄,不接受 renderer 任意路径。
  • 关闭 ACL 继承是为了避免 OS 自动向未检查子项传播授权;每个包目录和文件必须逐项验证和授权。该原语只增加权限,不会清除预先存在的宽泛 ACL,也尚未接入生产启动器,因此不构成对恶意并发替换或任意现有目录的完整安全证明。
  • 4 项真实 Windows AppContainer 测试通过:指定文件授权前无法读取,仅授权目录仍不能读取子文件,文件单独授权后读取成功;相邻未授权文件和另一实例仍被拒绝;新建文件、覆盖包文件失败,原内容保持不变;硬链接与只读句柄不能用于授权。每次试验均先以零能力挂起创建,检查精确容器 SID,加入 Job 后再执行受控测试命令。
  • 首轮使用 type 输出到 nul 的测试返回非零,改用 set /p 从文件重定向读取后验证成功;没有改变生产权限掩码来迁就该测试。系统 cmd.exe 仅用于这些固定测试命令,生产扩展入口仍禁止 shell 拼接。
  • API 依据 Microsoft SetSecurityInfo 文档。当前未完成生产启动器、包树授权编排、scratch 配额、网络/文件 broker 和恶意程序矩阵;extensions capability 仍关闭,整体生产化目标继续进行。
  • 本轮完整回归:cargo test --features desktop 共 98 项通过、5 项 ignored;其中 4 项为父测试实际驱动的 Job/Sync 辅助进程入口,另一项是需要单独执行的打包 Core 20 次冷启动,本轮没有重跑该项。真实 Core/Stronghold、笔记桥接、凭据所有权和 Sync 中断恢复集成全部通过。前端全量 101 个文件、525 项通过;Rust 全目标 Clippy -D warnings 通过。日志分别为 .build/host-production-full-tests.log.build/frontend-production-full-tests.log.build/host-production-clippy.log。全库 diff 检查提示用户 Vault 文件已有尾部空行,未修改用户内容;本次代码与文档单独检查通过。

增量:AppContainer 环回网络行为验收夹具

  • 新增独立原生 Rust 网络探针,由测试编译到独立临时包,按句柄授予容器读取执行权限。直接以绝对入口创建挂起进程,检查容器身份、精确 SID、零能力并加入 Job 后执行;不经 shell。探针仅属于测试夹具,不参与生产扩展启动。
  • 在 Windows 11 24H210.0.26100.4061)、Rust 1.98.1 x86_64-pc-windows-gnu 上,分别对 IPv4 127.0.0.1 和 IPv6 ::1 的动态 TCP/UDP 监听端验证。相同探针在容器外、隔离尝试前后均成功访问;容器内 TCP 在 2 秒连接期限内超时,未被监听端接受;UDP send_to 返回成功,但监听端在进程结束后额外观察 200 ms 仍无数据。测试不把 UDP send 成功等同于报文送达。
  • 初次要求 Winsock 10013 的断言失败;进一步探测明确为 TCP 超时,并分别保留超时、访问拒绝、其他错误退出码。当前断言检查允许的网络失败类型和监听端无接收,并排除加载失败、参数错误、控制端不可用。Microsoft 文档说明环回隔离可能表现为丢包:Windows 防火墙 UWP 连接排查。此次未捕获 WFP 事件,不能将超时唯一归因到某条过滤规则。
  • 全部 5 项 AppContainer 测试和全目标 Clippy -D warnings 通过,日志 .build/extension-container-network-tests.log.build/extension-container-network-clippy.log。测试没有增加 loopback exemption 或修改系统防火墙设置。
  • 这只是当前机器上 TCP/UDP 环回行为的有限时间观察,不覆盖公网、私网实际服务、DNS、原始 socket、跨机器或最低 OS 版本,也不能据此通过完整 C-01/C-03。生产启动器、受限 broker、scratch 配额等仍待完成,整体目标继续进行。

增量:原生启动参数与隔离环境构造

  • 新增 Windows LaunchData,为明确的绝对 .exe 入口编码 CRT 参数数组,正确处理空参数、空格、引号前反斜杠和末尾反斜杠;拒绝相对入口、非 .exe、路径引号/NUL、参数 NUL、数量与长度超限。入口仍须由调用方校验并持有,构造器本身不验证包、许可或沙箱能力,也不允许据此执行 shell 配置。
  • 环境块只使用 Host 提供的 SystemRoot、容器 LOCALAPPDATA、scratch TEMP/TMP 和明确声明/解析的变量,不读取父环境。变量名限 ASCII、大小写归一排序,拒绝重复和覆盖保留变量、非法名称与 NUL。原生路径使用 UTF-16 保留未配对代理项,避免 display() 有损转换。环境块含双 NUL,并要求调用方使用 CREATE_UNICODE_ENVIRONMENT。
  • 参数与环境均限制在 32767 个 UTF-16 单元内,预分配容量并在加入内容前检查界限,避免构造过程因扩容留下额外值副本;Drop 清零两个缓冲区。此清理不替代调用方对已解析凭据的生命周期和清理责任。
  • 真实 AppContainer 探针使用该构造器启动,比较完整 argv 和完整环境变量集合:空串、空格、中文/emoji、引号/反斜杠、换行及 &|%PATH% 均原样收到,环境恰好为四个基础变量加 CUSTOM,未继承 PATH 等 Host 环境。测试也保留容器 SID/零能力/先挂起后入 Job 的核对。
  • 45 项扩展回归通过、3 项 Job 辅助入口 ignored(由父测试实际调用),全目标 Clippy -D warnings 通过。日志 .build/extension-launch-regression-tests.log.build/extension-launch-clippy.log。API 依据 Microsoft CRT 参数解析CreateProcessW。尚未覆盖所有第三方运行时的自定义命令行解析。
  • 当前仍未开放第三方执行:正式启动器的许可/包句柄绑定、生产环境凭据解析、scratch 限额、broker 与完整端到端验收继续实施,不能据本轮参数测试认定生产化完成。

增量:Windows 挂起进程所有权与恢复边界

  • 新增 extension_process:使用零能力 SECURITY_CAPABILITIES、明确环境、容器自身工作目录、不可继承句柄和隐藏窗口创建挂起进程,先加入默认资源 Job,再核验 TokenIsAppContainer、精确 SID 和零 TokenCapabilities。属性列表、原生句柄及 Job 均有所有权清理;创建、入 Job 或身份核验失败不返回可恢复进程。
  • Suspended 与 Running 分开,resume 消耗挂起对象,要求 ResumeThread 返回预期挂起计数 1;不能经同一对象重复恢复。Profile 借用延续到进程对象释放,防止 Host 提前删除配置。Running 提供最多 60 秒的有界等待和整组主动终止;对象释放也终止 Job,关闭句柄并等待根进程退出。
  • resume 是带明确安全前置条件的底层接口,尚不替代执行许可、包/入口句柄、在线信任、Vault、broker 和完整资源策略核验。上层未满足全部条件时仍必须拒绝运行。未新增 renderer 启动命令,也未开启 extensions capability。
  • 原生参数/环境探针、IPv4/IPv6 环回探针已切换到此正式进程模块执行,相关行为回归通过。新增实际 Windows 测试验证不匹配 SID 拒绝、丢弃未恢复进程后句柄进入终止状态、入口不存在与损坏终止符失败不消耗 Profile。运行中的等待探针验证零时限返回未完成、超过 60 秒的等待请求拒绝、主动终止后五秒内观察到退出。
  • 47 项扩展回归通过,3 项 ignored 为由父测试驱动的 Job 辅助入口;全目标 Clippy -D warnings 通过。日志 .build/extension-process-regression-tests.log.build/extension-process-clippy.log
  • 该模块只收拢已验证的原生生命周期,不构成完整生产扩展启动器。许可和包句柄原子绑定、撤销停止、生产 broker、scratch 配额、工具总期限及崩溃后的配置清理仍未完成,整体生产化继续实施。

增量:独立于调用方轮询的单工具期限守卫

  • 新增 ToolDeadline,生产预算固定 60 秒,按单次工具调用启动,不限制常驻 MCP 服务总寿命。Running::start_tool_call 绑定该实例的 Job,创建独立计时线程;线程创建或句柄复制失败返回明确错误,调用方必须在派发工具请求前成功启动守卫。
  • 期限使用单调时钟和条件变量。超时独立终止整个实例 Job,不依赖调用方继续轮询;完成只能在期限到达前撤销计时,完成操作不能在期限已过、计时线程尚未调度时绕过超时。终止失败、计时线程异常与普通超时分别返回稳定错误码。
  • finish 正常完成后保留常驻进程;cancel 主动终止实例;守卫未 finish 就被释放也终止实例,覆盖调用 future 取消或异常退出,避免留下无期限工具调用。释放会唤醒并回收计时线程,正常完成无需等待满 60 秒。
  • 真实 AppContainer 等待探针验证:正常完成守卫后进程仍活着;使用测试内部 100 ms 期限时,在没有 check/finish 轮询驱动的情况下进程退出,随后 finish 明确返回超时;显式取消和未完成释放均在 5 秒内观察到进程退出。生产公开 API 不接受延长期限参数。本轮没有执行完整 60 秒墙钟超限、计时线程故障注入或高并发调用压力测试,不能据此独立通过 C-04。
  • 48 项扩展回归通过、3 项 Job 辅助入口 ignored(由父测试执行),全目标 Clippy -D warnings 通过。日志 .build/extension-deadline-tests.log.build/extension-deadline-clippy.log
  • 守卫仍需接到实际 MCP/扩展调用派发与结束路径;正式许可/包句柄绑定、broker、scratch 配额及完整验收尚未完成,整体生产化目标继续进行。

验收增量:完整 60 秒工具预算、进程树清理与 Host 保存

  • 新增长时显式验收测试 real_sixty_second_tool_deadline_kills_tree_and_host_can_save。测试探针在真实 AppContainer 内创建一个同受 Job 管理的子进程,两个进程自然等待均为 120 秒,避免与 60 秒预算自然退出混淆;先核对活动进程数为 2,再等待生产 start_tool_call 固定 60 秒预算。
  • 本次实际执行通过:计时开始 60.0048499 秒后 Job 活动进程数为 0,探针没有以自然结束码退出,finish 返回 EXTENSION_TOOL_DEADLINE_EXCEEDED。等待期间不通过 deadline.check/finish 驱动超时,终止由独立守卫完成。
  • 同一 Host 测试进程在工具运行期间使用正式 Workspace.write 保存笔记,清理后以 expected_hash 再次写入,关闭后重开验证内容一致。此证据覆盖 Host 库保存路径,尚不等于打包桌面 UI 端到端保存验收。
  • 长时测试以 --ignored --exact 显式执行,1 项通过;常规 AppContainer 5 项回归通过,长时条目在常规运行中保留 ignored 标记避免每次都额外等待一分钟。全目标 Clippy -D warnings 通过。日志 .build/extension-deadline-sixty-seconds.log.build/extension-deadline-container-regression.log.build/extension-deadline-acceptance-clippy.log。这补足上一条记录中未执行完整 60 秒和容器子树验证的缺口,不覆盖计时线程故障注入或高并发压力。
  • 远端只读复查:HTTP /health 200、/ready 503SSH 22 连接仍在认证前返回空 banner;未修改远端配置,仍需要恢复就绪依赖与 SSH 可用入口。
  • C-04 的 CPU 持续超限、scratch 配额、broker 限流及完整桌面证据仍未齐备,不能将本测试扩大为 C-04 全项通过。整体生产化目标继续进行。

增量:校验后持续持有 Windows 包对象句柄

  • 新增 PinnedPackage,从 Host 已验证的目录 capability 和 Inventory 出发,逐级以 nofollow、FILE_SHARE_READ 和读取/ACL 权限打开根目录、全部父目录及包文件,保留这些句柄到实例结束。先持有全部现有对象,再复用完整树校验核对文件集合、摘要、总大小、硬链接与重解析限制,并匹配预期展开树摘要;任一步失败释放整组句柄。
  • 该对象提供按持有句柄授予实例只读执行权限;不接受 renderer 任意路径,不在授权时重新通过字符串查找文件。数量、路径长度、目录数和展开体积继续有界。实际容器探针已通过该对象持有包后启动,参数/环境、网络行为、取消及短期限回归通过。
  • 两项实际 Windows 句柄测试验证持有期间写入、删除、文件重命名和子目录重命名被拒绝;已存在写入句柄时锁定失败;错误树摘要和指向包外的硬链接拒绝;失败或释放对象后不残留写入锁。授权后文件内容保持一致。
  • 50 项扩展回归通过,4 项 ignored 中三个是父测试实际调用的 Job 辅助入口,另一个是上一轮已显式通过的 60 秒长时验收,本轮未重跑该长时项。全目标 Clippy -D warnings 通过。日志 .build/extension-pinned-regression-tests.log.build/extension-pinned-clippy.log
  • 此原语固定已有包对象,不是只读文件系统挂载:包根目录上层路径绑定、并发新增未知文件、已有可写映射等场景仍未形成完整证明;不据此通过整个 C-02。正式启动器还需将许可、精确入口、完整包句柄和策略检查连接起来,extensions capability 继续关闭,整体生产化继续实施。

增量:原生入口卷路径、祖先句柄与进程生命周期绑定

  • PinnedPackage 新增 bind_entry,仅允许已验证清单中的入口。通过 GetFinalPathNameByHandleW 从持有文件句柄取得卷 GUID 路径,逐级持有卷根至入口的对象句柄,拒绝重解析对象并阻止祖先目录删除共享;最后用卷序列号和文件索引核对重新打开的入口与原持有文件身份一致。
  • BoundEntry 保留全部祖先句柄并借用完整 PinnedPackage。Suspended::create_bound 将此守卫借用延续到进程结束,使该创建路径不能在进程仍存活时释放入口或包句柄。挂起创建失败仍按既有所有权规则清理,不产生可恢复进程。
  • 无法取得卷 GUID、不是本地卷格式、路径过长或超过 256 个路径分量时明确拒绝,不退回 UNC、驱动器字母搜索或普通子进程。原有低层 create 仍供受控探针等调用使用,正式包运行编排应使用 create_bound 并完成其余许可与策略检查。
  • 实际 Windows 测试确认绑定路径为卷 GUID 路径、内容对应已持有文件、缺失/越界入口拒绝、父目录重命名失败;全部所有者释放后重命名成功。真实 AppContainer 原生参数/环境探针通过 create_bound 启动成功,网络/取消/短期限探针也使用持续持有的绑定路径运行。
  • 51 项扩展回归通过,4 项 ignored 为三个由父测试实际驱动的 Job 辅助入口及需显式执行的 60 秒验收,本轮未重跑长时项。Clippy 首次指出冗余 Ok/?,修正后全目标 -D warnings 通过。日志 .build/extension-entry-binding-tests.log.build/extension-entry-binding-clippy.log。API 依据 Microsoft GetFinalPathNameByHandleW
  • 这补上了普通祖先路径替换的绑定原语与实测,仍未完成并发新增未知文件、已有可写映射、完整攻击矩阵、许可原子核验或所有目标系统验证,不能据此认定 C-02 或整体生产化完成。

增量:从执行许可构造参数、环境及包域凭据

  • Claims 增加 Plugin/MCP 执行类型并纳入 HMAC 摘要,防止类型切换后沿用原许可。现有逐字段篡改测试覆盖该字段;许可仍为 Host 内存态能力,未增加旧许可兼容或 renderer 签发入口。
  • 新增 extension_launch_authorization::Context::build,先核验许可有效期/HMAC、Host 当前 Vault/策略/平台,以及 BoundEntry 相对入口与展开树摘要,再从已签发声明构造参数和环境,不接受独立的替换参数或环境值。
  • CredentialScope 的值解释为包域内不透明凭据引用。凭据归属由 HTTPS 来源、命名空间、包 ID 的带长度摘要派生,再按已绑定执行类型进入 Plugin 或 MCP 域;不接受调用者另报凭据域,也不回退 Provider。版本未加入凭据归属摘要,保留同包升级后的引用稳定性;新执行仍须独立完成信任和权限确认。
  • 环境秘密通过现有 Stronghold broker 解密,拒绝缺失、锁定、无效引用和非 UTF-8 值;解析前后核对锁定代次。临时环境值由清理所有者清零,原始解密字节及最终 UTF-16 启动缓冲继续使用各自清理机制;错误只返回稳定代码,不包含值。
  • 实际 Stronghold 测试验证 Provider 同名凭据不可见、正确 MCP 包域可用、重新签发后改变类型/来源/命名空间/包 ID 仍不能读取原凭据,以及入口/树/Vault/策略不匹配、参数篡改、过期、锁定和编码错误拒绝。真实 AppContainer 原生探针通过该准备链取得虚构测试凭据后启动,完整 argv/环境核对通过,未使用任何用户真实秘密。
  • 52 项扩展回归通过,4 项 ignored 为三个由父测试驱动的 Job 辅助入口和单独执行的 60 秒验收;全目标 Clippy -D warnings 通过。日志 .build/extension-launch-authorization-tests.log.build/extension-launch-authorization-clippy.log
  • 该组件只完成准备阶段,不是可直接恢复执行的授权租约;调用方仍须在 resume 前复核在线信任、活动安装身份、许可、Vault 和锁定代次,并完成运行中撤销/停止、broker 和完整资源限制。目前未开放第三方执行,整体生产化继续进行。

增量:运行租约、锁定代次与主动进程树撤销

  • 执行许可更新为内存态 v2 HMAC,包含签发代次;Authority.invalidate_all 与 Authority 释放都会推进代次。Lease 绑定原许可代次及由有效期计算的单调时钟期限,不能把撤销后的当前代次重新当作旧许可的有效代次。
  • Context.prepare 在解析凭据前捕获租约与保险库锁定代次,生成不可拆换的 PreparedLaunch;创建挂起进程前再次核对租约、绑定路径、相对入口和树摘要,创建后继续核对。LeasedSuspended 恢复时先建立原生撤销监视器,进程生命周期继续保留入口与 Profile 借用。
  • 监视器每 50 ms 检查许可代次、凭据代次与到期时间;任何失效均终止所属 Job,不要求调用者继续轮询。监视线程退出也有整组终止兜底;监视器不可用时不恢复执行。Running.start_tool_call 先检查租约,阻止已撤销实例启动新工具调用。
  • 真实 AppContainer 双进程探针验证:本轮许可作废后约 56.90 ms、保险库锁定后约 47.80 ms、签发器释放后约 55.45 ms 观察到进程树清空;之后新工具调用均被拒绝。两秒测试租约自然到期也主动清空进程树。创建前撤销和创建后恢复前撤销均拒绝继续,无普通子进程降级。
  • 原生参数/环境探针已使用 prepare → create_suspended → 带租约恢复路径。52 项扩展回归通过,4 项 ignored 为三个父测试实际驱动的 Job 辅助入口及单独执行的 60 秒验收;全目标 Clippy -D warnings 通过。日志 .build/extension-revocation-tests.log.build/extension-revocation-clippy.log
  • 本轮锁定由真实 CredentialBroker.lock 触发,尚不是操作系统锁屏事件的桌面端到端测试。监视器提供有界撤销,并非对核验与 ResumeThread 之间竞态作“零指令执行”证明。Host 仍需把实际 Vault 切换、权限撤回、在线签名撤销等事件接入签发器/实例注册表,并完成 broker 与全部资源策略,整体生产化尚未完成。

增量:Host Vault 与会话锁定事件接入撤销代次

  • Host 增加持久于应用生命周期的 execution Authority;选择或打开不同 Vault、关闭/撤销 Vault 时推进其撤销代次,再替换工作区。重复打开当前 Vault 的既有早返回路径保持不变,打开新 Vault 失败也不会替换现有工作区;撤销请求在持久记录失败时仍先让旧执行许可失效。
  • 手动 credentials_lock 先原子撤销 Host 执行许可和凭据会话,再等待 CredentialBroker 互斥锁进行数据清理。凭据原子信号在初始化时缓存于 OnceLock,撤销不再被正在执行的解锁/KDF 互斥锁阻塞。
  • Windows SessionMonitor 支持有界多域信号组,锁屏、注销、控制台/远程断开同时撤销凭据与 Host execution Authority;解锁消息不会恢复原代次。线程创建失败返回稳定不可用错误,拒绝重复信号或超过 8 个域的配置。
  • 8 项 Host 二进制测试、2 项原生会话消息测试、3 项许可测试通过,全目标 Clippy -D warnings 通过。验证在持有凭据互斥锁时手动锁定信号已发出、工作区替换/关闭推进代次,以及不轮换 HMAC 密钥只推进事件代次也能拒绝旧许可/租约。日志 .build/extension-host-lifecycle-tests.log.build/extension-host-session-tests.log.build/extension-host-permit-tests.log.build/extension-host-events-clippy.log
  • 会话测试仅向本测试的隐藏窗口注入原生消息,未锁定用户桌面;尚未完成实际 OS 锁屏与已打包 Host/扩展实例的组合验收。第三方执行仍未开放,后续实例签发必须使用 Host 持有的 Authority,实际在线信任撤销、实例注册/派发、broker 与完整资源策略继续实施。

修复:锁定会话下无秘密包的重新准备与撤销

  • Context.prepare 现在对所有正式第三方启动绑定保险库会话代次并要求当前已解锁,不再仅对 CredentialScope 环境声明绑定。即使包不需要秘密、签名原语又产生了新许可,锁定期间也不能准备执行。
  • 将 Context.build 收为内部方法,公开准备路径返回带租约的 PreparedLaunch,避免调用方从该授权组件直接取出不带会话约束的启动字节。底层受控原生测试入口仍存在,但完整第三方运行编排不得绕过 prepare。
  • 测试验证无秘密包在初始锁定时拒绝,解锁后能准备,准备后锁定则不能创建进程;锁定期间新签发的许可也不能用于准备。真实 AppContainer 无秘密双进程实例在锁定后约 55.14 ms 清空,后续工具调用被拒绝。
  • 53 项扩展回归通过,4 项 ignored 为三个父测试实际驱动的 Job 辅助入口及单独执行的 60 秒验收;全目标 Clippy -D warnings 通过。日志 .build/extension-locked-session-tests.log.build/extension-locked-session-clippy.log
  • 这修复会话门禁缺口,尚未开放执行能力或完成实际桌面实例注册、broker、CPU/scratch 限额及整体验收;完整生产化目标继续进行。

增量:实例文件 broker 策略及写入意图提交前复核

  • 新增 Windows 桌面内部 extension_file_broker,绑定已签发 Claims、当前 Vault、平台/策略、权限及已解锁会话租约。只接受 notes.read / notes.write 严格 DTO,不接受请求自报 Vault、来源、权限或 Core 任意方法;传输层仍须在创建 broker 前完成真实实例身份认证。
  • 每实例每秒最多 32 次请求,畸形或过大请求也占用额度;JSON 帧上限 2 MiB、笔记正文上限 1 MiB、路径上限 1024 字节。权限在文件访问前检查,只允许合法 Markdown 路径并沿用 Vault 私有路径禁令。原生传输尚未接入,未来读取帧时必须先执行大小限制,不能读完无界内容后才调用此适配器。
  • 读取从持有的目录句柄逐级 nofollow 打开,文件只共享读取;核对普通文件、非重解析对象及单硬链接,并以有界读取再次约束长度。返回实际正文摘要用于 expected_hash;返回前复核租约。
  • 写入通过 Host CAS / 持久日志 / outbox 完成。操作 UUID 按执行类型、来源、命名空间、包 ID、Vault 派生隔离标识,避免不同包或 Core/renderer 直接复用同一操作 ID;响应保留调用方原 ID。同包同 Vault 重启 broker 与 Workspace 后可重放已提交回执,变更同 ID 内容返回冲突。
  • Workspace 增加内部 guarded 写入入口,进入处理及持久写入意图事务提交前检查授权。后一次拒绝会回滚 operations / journal,重启不能重放该写入;此前已刷盘的 payload 及其映射可能留下,需后续统一孤儿清理。已接受的持久意图继续沿用恢复语义,不在写入文件后因撤销跳过 outbox。
  • 新增真实临时 Workspace / Stronghold 测试,覆盖正常读写、CAS、同 ID 内容冲突、跨包隔离、重启重放、权限/伪造字段/私有路径拒绝、帧/正文/速率限制、硬链接与异 Vault 拒绝、凭据锁定撤销。另有 Workspace 故障注入测试在提交前拒绝,确认重启正文与 outbox 不变,同 ID 原内容可以重试并只增加一次 revision/outbox。
  • 当前仍是内部策略适配器,未开放第三方执行。写入底层尚使用字符串路径,需完成全程句柄约束;原子撤权与最终提交的严格排序、真实管道身份认证、Vault 根目录替换、网络 broker 及完整攻击矩阵也尚未完成,不据此判定 C-02 / C-04 或整体生产化通过。
  • 本轮完整 Rust desktop all-targets 回归 115 项通过、6 项 ignored;其中三个 Job 辅助入口和一个上传故障辅助入口由父测试实际驱动,另外两项是需显式执行的 60 秒期限验收与打包 Core 20 次冷启动,本轮未重跑。全目标 Clippy -D warnings 通过。日志 .build/extension-file-broker-full-tests.log.build/extension-file-broker-clippy.log。未修改前端/Python 实现,本轮没有把此前测试结果冒充重新执行结果。

增量:沙箱实例标准管道与实际文件 RPC 探针

  • 新增 extension_stdio 的每次启动专用匿名管道;Host 端不继承,子端只有 stdin/stdout/stderr 三个句柄。扩展进程创建同时设置 SECURITY_CAPABILITIES 与 PROC_THREAD_ATTRIBUTE_HANDLE_LISTSTARTF_USESTDHANDLES 指向这三个子端;所有者保持到 CreateProcessW 返回,失败自动关闭,Host 不保留多余子端阻塞 EOF。
  • PreparedLaunch 新增带 stdio 的挂起创建路径,沿用创建前后租约检查、BoundEntry 全生命周期持有、AppContainer 身份核验和 Job 先绑定后恢复。返回 Host 管道端供实例运行线程持有,未引入共享监听地址、请求自报 PID 或包身份。无 stdio 的受控探针路径继续不继承任何句柄。
  • 新增有界 NDJSON 解码器:每帧最多 2 MiB,在扩展缓冲前检查;拒绝超长、空帧与 EOF 前未结束的帧,协议/读取错误后解码器不再继续解析。编码拒绝未转义换行与超限帧。该同步组件不自行解决阻塞读取/写入,需要后续 IO 取消所有者与工具期限控制;stderr 持续排空/限额也仍待运行编排接入。
  • 真实 AppContainer 原生探针经已签发参数/环境与解锁会话启动,通过 stdout 发出 notes.read,由绑定当前 Vault 和权限的文件 broker 处理,经 stdin 返回正文;子进程核对正文后正常退出。测试同时确认独立 stderr、关闭 stdin 产生 EOF、正文未改动,以及 Host 中另一个显式可继承的事件句柄未进入该子进程。仅使用隔离测试 Vault/虚构凭据。
  • 管道标志测试确认三个 Host 端全部非继承、三个子端继承且六个句柄互异;帧测试覆盖单字节分片、多帧、CRLF、恰好上限、超一字节、截断、错误后封闭及写入拒绝。57 项扩展回归通过、4 项 ignored 为既有三个父测试驱动辅助入口与显式 60 秒验收。desktop 全目标及非 desktop 库 Clippy -D warnings 均通过;首次非 desktop 检查指出两处桌面专用构造函数未限制编译条件,已修正。日志 .build/extension-stdio-tests.log.build/extension-stdio-clippy.log.build/extension-stdio-core-clippy.log
  • API 依据 Microsoft handle inheritance。明确句柄清单约束本次扩展创建,但 Host 内其他并发启动若使用不带清单的全量句柄继承,仍可能继承这段短暂窗口内的子端;正式启用前须审计并统一所有创建路径或采用隔离创建代理,不能仅凭本测试声明该并发风险消失。
  • 这增加真实沙箱至文件 broker 的通信证据,尚未接入用户安装实例注册、JSON-RPC/MCP 派发、活跃安装/信任复核、IO 超时/背压和完整句柄安全写入。第三方执行仍禁用,C-02/C-04 及完整生产化保持未通过状态。

增量:有界沙箱 IO 工作线程、阻塞取消与洪泛清理

  • 新增 extension_io::Pump,由 Running.start_io 先核验运行授权,再取得所属 Job 的清理句柄。stdin/stdout/stderr 分别由专用线程处理;输入最多一个排队帧加一个写入中帧,输出队列最多四帧,单帧仍为 2 MiB。入队不阻塞 Host 调用者,满输入返回明确背压错误;满输出视为实例协议无法继续,终止所属进程树。
  • stdout 每秒最多 8 MiB / 128 帧,超限或有界解码失败停止实例。stderr 以 4 KiB 缓冲排空,累计超过 1 MiB 停止实例,不保留可能含秘密的原文。后续如需诊断展示,仍须独立设计脱敏与保留策略。
  • 收取响应最长允许等待 60 秒,并以 20 ms 分段检查失败信号,避免 stderr 已超限时仍等满调用方超时。该等待上限不是完整 MCP 工具期限编排,现有 ToolDeadline 还需在正式派发路径接入。
  • shutdown / Drop 先停止接收、终止 Job,再对工作线程调用 CancelSynchronousIo 并 join。取消不是持续状态,因此反复请求直到线程确认退出,覆盖“检查停止后才进入 ReadFile/WriteFile”的窗口;没有使用 TerminateThread 或把阻塞线程遗留在后台。此关闭过程必须运行于实例后台线程,不能放在 UI 线程;目前实测针对 Host 创建的 Windows 匿名管道,未对任意设备驱动或全部最低系统版本作有界保证。
  • 原生管道测试连续 20 轮,用 GetThreadIOPendingFlag 确认三个线程都已进入 IO 等待,管道对端在整个关闭期间保持打开,仍在每轮两秒阈值内收回线程;因此通过不依赖子进程退出产生 EOF。另测输出队列溢出、stderr 洪泛、输入背压与失败后立即返回。
  • 真实 AppContainer 笔记 RPC 测试已改走 Pump;正常请求、返回正文、关闭输入、最后响应和 EOF 均通过。新增真实双进程探针验证不读取输入以及 stdout / stderr 洪泛:本轮静默双进程 shutdown 至清空约 18.01 ms,两项洪泛检测后的 shutdown 至清空分别约 2.55 / 2.59 ms。后两项是检测之后的清理时间,不冒充从开始洪泛至检测的总耗时。
  • 59 项扩展回归通过,4 项 ignored 为三个父测试驱动 Job 辅助入口与显式 60 秒验收,本轮未重跑该长时项。desktop 全目标 Clippy -D warnings 通过。日志 .build/extension-io-tests.log.build/extension-io-regression.log.build/extension-io-clippy.log。API 依据 Microsoft CancelSynchronousIo
  • 尚未开放第三方执行:安装实例注册、JSON-RPC/MCP 工具派发、许可/在线信任原子复核、全部 Host 创建路径的继承审计、完整句柄安全写入、scratch/CPU 验收及远端部署问题继续推进。本轮证据不能单独证明 C-02 / C-04 或完整生产化达标。

增量:原生 MCP 会话、协议生命周期与真实调用期限

  • 新增 extension_mcp::Session,持有已授权 Running 的借用与专用 Pump,在后台串行执行 initialize → notifications/initialized → tools/list / tools/call。协议主版本及兼容集合与现有开发 Python bridge 一致(2025-11-25、2025-06-18、2025-03-26、2024-11-05),不会自动把未知新版本当作兼容版本。
  • 每个请求使用本会话不复用的字符串 ID;严格解码 JSON-RPC 2.0 顶层字段,拒绝重复字段、null ID、结果/错误混合、无效方法/参数与错误响应 ID。仅回应服务端 ping;未声明 sampling、roots、elicitation 等能力,对其他请求返回方法不支持,不提供额外 Host 权限。工具变更通知记录为待失效标记,进度等通知不会延长最大请求期限。
  • 初始化校验协议、serverInfo 和 capabilities;未完成初始化不可列举或调用工具。列表单页上限 500 项、游标上限 1024 字节;工具结果验证基础结构且上限 256 KiB。完整工具目录分页聚合、名称/输入输出 schema、权限与用户调用确认仍待上层接入,当前返回值不直接开放给 Core/renderer。
  • 派发前启动既有原生 ToolDeadline,调用全过程复核进程租约和期限,收到数据后也再次复核。初始化/列举等待上限 10 秒,工具调用最多 60 秒;取消后标记会话失败、终止 Job,并对非 initialize 请求尽力发送取消通知。有效远端 JSON-RPC 错误以稳定代码返回,不转发原始错误/数据,也不会误当作通信损坏杀死可继续使用的服务。
  • 修复串行协议紧邻发送 initialized 通知和下一请求时可能短暂碰到单槽输入队列的问题:增加最多 50 ms 的有界入队重试,复用原帧所有权,不扩展队列或复制大帧。原非阻塞 Pump.send 继续立即返回背压。shutdown 先关闭输入并给服务 200 ms 退出机会,再执行既有 Job 与 IO 清理。
  • 真实 AppContainer 探针覆盖初始化、工具列表、正常工具调用、服务端 ping、工具变更通知、错误协议版本、错误 ID、远端错误后再次调用成功和挂起调用取消;失败会话不能继续派发。回归中发现旧 IO 测试仅观察系统 IO 标志不足以确认首帧已出队,增加仅测试使用的写入阶段观察条件,继续保留实际 IO 等待、对端不关闭和全部线程回收要求;修正后常规扩展回归 60 项通过。
  • 协议依据 MCP lifecycleMCP toolsMCP cancellation。此组件不是完整安装实例运行时,安装身份/在线信任/工具 schema 与授权路由、原生实例注册,以及全部沙箱资源策略仍须完成,第三方执行能力保持禁用。
  • 新增长时原生验收已显式执行:实际 tools/call 挂起 60.0015261 秒后得到 EXTENSION_TOOL_DEADLINE_EXCEEDED,服务及后代最终清空;Host 此后保存笔记并重新打开 Workspace 校验正文成功。该验收完整夹具总耗时 75.64 秒,包含握手/其他原生场景。日志 .build/extension-mcp-sixty-seconds.log
  • 常规扩展回归为 60 passed / 5 ignored,其中三个 Job 辅助入口由父测试驱动,新 MCP 长时项已另行显式通过,旧底层 60 秒项本轮未重跑。desktop 全目标 Clippy -D warnings 通过。日志 .build/extension-mcp-tests.log.build/extension-mcp-clippy.log。这些是工具期限及协议链路证据,仍不代替 C-04 中内存/scratch/CPU/进程及完整 Host 验收。

增量:MCP 工具目录、离线契约与变更失效

  • 新增 extension_mcp_tools::Catalog / Tool;最多 100 页、500 个工具、4 MiB 目录响应总量,检测重复工具名与循环游标,只有完整目录验证成功才发布。名称按 MCP 推荐的 ASCII 字母(含大小写)、数字、点、下划线与连字符处理,大小写敏感;不再把原开发 Python 的小写限定直接套到原生 MCP。
  • 每个工具输入/输出 schema 以 Draft 2020-12 离线编译,使用线性 regex 模式,限制单 schema 64 KiB、树深 24、节点数 4096。与 Host 配置契约的有界执行策略一致,本阶段拒绝所有外部及本地/递归引用、未知 schema 方言和需要任务增强执行的工具,不进行网络或文件解析。该支持范围需在后续安装兼容性界面明确呈现。
  • Session.refresh_tools 先撤下旧目录,再在分页请求的总体 20 秒等待预算内构建新目录。未发现目录、未知工具或不满足输入 schema 的参数均在发送前拒绝;参数还限制为 256 KiB 的有界对象。远端 annotations、描述和 metadata 不产生权限,也未被转换为可免确认的工具属性。
  • 成功工具结果按已选中的输出 schema 检查 structuredContent,限制整体 256 KiB、最多 128 个内容项,并校验文本、图片/音频 base64、资源链接和嵌入资源的基础结构。isError=true 允许不带成功结构化结果。资源 URI 仅作为数据校验,不会自动抓取或打开;具体媒体渲染与资源获取仍需走各自授权路径。
  • 接收 tools/list_changed 后立即清除可调用目录;下一调用前也处理已经排队的空闲通知,避免继续使用已知失效的目录。目录建立期间发生变化不会发布混合版本。进行中的调用保留选中契约的 Arc,用原契约校验结果,新的调用必须重新发现目录;正式实例后台循环仍需持续处理空闲事件并与 UI/Agent 的目录版本同步。
  • 单元测试覆盖分页、重复、循环、总量/页数限制,必填项/类型/额外参数、结构化结果、无效 base64、所有引用类型、未知方言/不支持正则/任务要求与过深输入。真实 AppContainer 测试新增两页目录、发现前/未知名/无效参数拒绝、错误 structuredContent、调用中及空闲时工具变更;全部经实际原生 Session/Pump 运行。
  • 62 项扩展回归通过,5 项 ignored 为三个父测试驱动 Job 辅助入口及两个需显式执行的长时验收,本轮未重跑长时项;上一轮实际 MCP 60 秒验收仍为其当时提交的证据。desktop 全目标 Clippy -D warnings 通过。日志 .build/extension-mcp-catalog-tests.log.build/extension-mcp-catalog-clippy.log。协议依据 MCP tools
  • 工具发现和校验不等于用户批准执行。生产入口仍需完成实际安装实例注册、来源/活动版本/在线信任与工具目录摘要绑定、用户调用授权及 Core 路由;还需完成全部沙箱资源/并发攻击验证和其他生产化验收,第三方执行能力保持禁用。

增量:实例身份与一次性工具调用预览凭据

  • Context.prepare 在现有许可、入口和上下文验证完成后生成独立实例 UUID,以及覆盖完整 Claims 的执行摘要;用于摘要的临时序列化字节由 Zeroizing 清理。公开身份预览只包含执行类型、来源/命名空间/包/版本、Vault、权限集和摘要,不包含环境秘密或原始启动参数。
  • PreparedLaunch → LeasedSuspended → Running 持续携带该身份,带租约恢复方法收为 crate 内部。Session.new 要求运行实例具有这条准备链产生的身份,普通低层 resume 的受控测试进程不能直接进入该 MCP 会话入口。
  • 新增内存 Gate,生成包含真实工具描述、冻结参数、实例身份和工具契约摘要的 Review;最多 64 条待确认预览、合计 2 MiB 待确认参数,120 秒单调时钟有效期。确认会消费预览 ID,不能重复确认;过期和目录失效清理待确认项,已确认对象也绑定原到期时间。
  • 正式 Session.call_tool 现在只接受 ApprovedCall。该类型字段私有、不可 Clone、不可序列化/反序列化,工具名及参数不能在确认后另行替换;调用消费该对象并核对实例、目录代次和当前契约摘要,再进入参数/结果校验、运行租约及期限链路。按名称/参数直接调用的方法收为私有,只有 cfg(test) 辅助方法能模拟本测试用户确认。
  • 目录刷新开始、已观察到工具变更及会话失败均作废旧预览和目录代次;即使工具名字和 schema 恢复成原值,旧已确认对象也不能重新使用。此处是 Host 观察和持有的目录版本绑定,不是对服务端执行语义永不变化或核验到发送间“零竞态”的证明。
  • 单元测试覆盖预览对象被改写后实际参数仍冻结、重复确认、跨实例、目录代次、确认前/后过期、条数/字节上限及清理后复用。真实 AppContainer 测试核对预览来源/包/Vault,修改展示副本不会改变实际请求,旧目录凭据被拒绝;新增确认后锁定保险库导致 CREDENTIALS_LOCKED,重新解锁也不能恢复已失效会话。
  • 64 项扩展回归通过,5 项 ignored 为三个父测试驱动 Job 辅助入口及两个显式长时验收,本轮未重跑长时项。desktop 全目标 Clippy -D warnings 通过。日志 .build/extension-call-binding-tests.log.build/extension-call-binding-clippy.log
  • 当前 confirm_call 仍只是 Host 内部组件接口,未登记为 renderer/Core 命令,也没有自动批准策略或真实用户确认 UI。完整产品入口必须通过经过认证的 Host 路由确认用户批准,再与活动安装/在线信任、实例注册和 Core 路由组合;全部沙箱资源与其他生产化验收仍未完成,第三方执行能力保持禁用。

增量:后台实例注册、串行派发与停止清理

  • 新增 extension_instance::Registry。启动先用当前时间核验执行许可,再按执行类型、来源/命名空间/包和 Vault 限制同键单实例;最多 16 个注册项。每个工作线程在自身栈中创建并持有 Profile、PinnedPackage、BoundEntry、Running 与 Session,没有把带裸 SID 的 Profile 强行标为 Send。
  • 工作线程完成包校验、AppContainer/Job 挂起创建后调用 before_resume 复核钩子,再执行带租约恢复和 MCP 初始化/目录发现。该 start API 为 unsafe 内部集成边界,调用者仍须建立完整资源、用户与活动安装授权;本轮没有将“钩子存在”当作在线信任或完整沙箱策略已接通,也未新增 renderer/Core 启动命令。
  • 每实例四槽请求队列,预览参数入队前即执行 256 KiB/结构限制;预览、确认并调用、目录刷新由实例线程串行处理。确认和一次性凭据消费合在同一线程,ApprovedCall 不通过 IPC 返回或另行长期排队。回执等待限于后台,取消/丢弃 Ticket 会通知排队或进行中的工作;超时不证明远端工具尚未产生副作用,后续 Core 路由仍需正确呈现未知完成状态。
  • stop 使用独立原子信号并取消当前请求,不会被满队列阻塞;后台循环持续处理空闲 MCP 通知和租约撤销。终态在原生栈所有者退出后发布,Profile 显式删除失败有稳定错误;Registry 只回收确认已完成的线程,清理失败或 worker panic 的注册项保留隔离,避免直接允许同键替换。Registry 析构会停止并 join 工作线程,因此其生命周期管理不能置于 UI 同步调用中。
  • 真实后台 AppContainer 集成测试覆盖启动/目录就绪、预览与确认调用、重复确认拒绝、停止、线程回收后以新实例 ID 重建、活动工具取消、启动前策略拒绝及保险库锁定自动退出。测试同时确认旧 Endpoint 不能再提交请求,并通过保留的仅测试 Job 观察句柄确认最终 ActiveProcesses=0。
  • 集成测试最初以固定 ActiveProcesses=2 判断工具子进程启动,本机在 Ready 时已计入 2 个进程,导致实际取消的是排队请求。已改为同时确认当前 Ticket 处于执行槽、且进程数超过该实例就绪基线,再触发取消;修正后得到进行中工具的 MCP_CANCELLED 并清空 Job。此前仅凭固定计数的证据不能单独用于识别某个具体后代进程。
  • 新增队列满/输入超限/停止后队列不执行,以及已结束但清理失败的注册项不回收测试。67 项扩展回归通过,5 项 ignored 为三个父测试驱动 Job 辅助入口及两个显式长时验收,本轮未重跑长时项。desktop 全目标 Clippy -D warnings 通过,首次检查的回调类型复杂度提示已通过类型别名修正。日志 .build/extension-instance-tests.log.build/extension-instance-regression.log.build/extension-instance-clippy.log
  • 仍需将注册表纳入实际 Host 依赖与 UI/Core 的认证路由,完成活动安装/在线信任钩子、包对象权限回收/残留检查、全部 Host 创建路径继承审计、scratch/CPU 和完整攻击矩阵;其他同步/部署/安装包验收也继续推进。第三方执行能力保持禁用,完整生产化目标尚未完成。

增量:实例包 ACL 的作用域回收

  • PinnedPackage.access 在第一次授权前即创建作用域所有者,正常退出、部分授权失败及栈展开时均尝试撤销该实例 SID 的授权;显式回收失败返回 EXTENSION_CONTAINER_ACL_REVOKE_FAILED,注册表保留隔离项。回收逐个处理所有固定目录和文件,即使单个失败也继续处理其余对象。
  • 后台实例将进程、入口和会话所有者限制在内层运行函数,退出内层后才通过原有持有句柄回收包 ACL,再释放固定包对象和 Profile。Host 内使用全局互斥串行化 ACL 读取、合并和写回,撤销只针对本实例 SID,不把旧 DACL 快照覆盖回去,因此不会主动抹去其他实例的授权。该锁不覆盖外部管理员并发修改。
  • 采用 Windows REVOKE_ACCESS 合并现有 ACL,依据 ACCESS_MODESetEntriesInAcl 的语义。测试逐 ACE 比较所有包对象,覆盖另一实例仍获授权、部分授权失败回滚、显式完成和析构回收;真实后台启动/停止、调用取消、策略拒绝和保险库锁定后也检查包根目录与入口 ACL 恢复基线。
  • 首轮扩展回归为 67 通过、1 失败、5 ignored,失败位于旧原生 RPC 的句柄哨兵检查。原检查仅用 GetHandleInformation 判断句柄数值有效,不能排除子进程把该数值复用为其他对象。已改为 Host 私有临时文件哨兵,并比较卷序列号及 128 位文件 ID;查询失败或对象不同不算继承原对象。依据 FILE_ID_INFO。原失败没有记录退出码,不能事后断言其唯一原因;现在异常路径附带子进程退出状态以便诊断。
  • 此回收机制不保证 Host 被强杀后的残留恢复,也尚未验证外部 ACL 修改竞争、清理系统调用故障及全部恶意文件攻击路径。第三方扩展执行能力仍禁用,生产化总目标未完成。
  • 修正后 desktop 全目标测试累计 128 通过、7 ignored:库 113、Host 8,其余集成 7;ignored 包含显式长时验收和由父测试驱动的辅助进程入口。日志 .build/extension-acl-release-full.log。其中实际 Sync 服务的有序推送/重复提交及故障恢复集成也通过。
  • 另行执行真实 MCP 60 秒工具超时验收通过,整项原生协议/网络探针测试耗时 76.77 秒,日志 .build/extension-acl-release-sixty.logdesktop 全目标 Clippy -D warnings 通过,日志 .build/extension-acl-release-clippy.log。这不是完整沙箱攻击矩阵或远端部署验收通过的证据。

增量:CPU 超限原生通知与后台终止

  • 在现有 Job 单核等效 HARD_CAP 上启用 NOTIFY,在进程分配/恢复前关联独立 I/O completion port,并配置 Windows 的短 10 秒通知窗口与 ToleranceHigh。原生探针在本机 16 逻辑处理器上观察到首次 CPU 通知约 10.028 秒、下一次约 24.029 秒,ViolationLimitFlags=262144;说明该通知可与硬限额共存,但不能把通知间隔假定为固定 10 秒。日志 .build/extension-cpu-probe.log
  • Job 原始所有者持有独立 CPU 监视线程。线程收到通知后查询 JobObjectLimitViolationInformation,确认 CPU 标志才报告 EXTENSION_RESOURCE_CPU_EXCEEDED 并终止整个 Job;完成端口/查询失败或捕获到 panic 走失败终止,终止 API 失败有独立 EXTENSION_RESOURCE_TERMINATE_FAILED。观察与工具期限句柄克隆不拥有监视线程,原 Job 析构会通知线程停止并 join,线程仍持有 Job 句柄执行清理。
  • 分配挂起进程、恢复执行及 Running.check_authorization 加入资源状态检查,因此既有 MCP 与实例后台路径可观察到 CPU 资源错误;CPU 终止不依赖 renderer 或调用方持续轮询。监视器初始化失败阻止 Job 返回成功。
  • Windows CPU rate control 的硬上限按调度周期控制 CPU 周期;notification limit 的 ToleranceHigh 指允许在窗口的 60% 时间超过预算。这是 Windows 的窗口阈值保护,并非精确测量“连续超限 10 秒”。当前实现不据此宣称规划中的连续时限已获完整证明,也没有修改或放宽原验收阈值。
  • 新增显式真实 CPU 压力测试:Job 内 8 个忙线程、读取实际已配置 CPU 控制标志与比率、超限后确认 Job 清空、Host 在压力期间及清理后写入并重开验证笔记;另一个空闲 Job 应继续运行,持有观察句柄也不能阻止原 Job 所有者退出后的清理。该测试用原生 Job 测试进程,还不是已安装第三方 AppContainer 的完整 C-04 攻击验收。
  • 默认扩展回归首次发现旧 CPU 控制标志测试仍只期望 ENABLE|HARD_CAP,已更新为同时核验新 NOTIFY 标志;未放宽资源限额值。scratch 硬配额、CPU 连续时限严格证明、全部限额清理矩阵、Host 实际产品路由及其他生产验收继续未完成,第三方执行能力仍禁用。
  • 最终默认扩展回归 68 通过、7 ignored(长时验收与辅助进程入口),日志 .build/extension-cpu-regression.log;显式 CPU 压力/空闲对照测试通过,本次从恢复附近的计时点到检测为 15.7348341 秒,整个测试 15.90 秒,日志 .build/extension-cpu-enforcement.log。此前简化压力测试为 12.1788269 秒;这些差异进一步表明不能宣称精确 10 秒触发。记录中的“Job empty after”还包含后续 Host 保存/重开工作,不能作为纯终止 API 延迟的独立测量。
  • desktop 全目标 Clippy -D warnings 通过,日志 .build/extension-cpu-clippy.log。本轮改动集中于原生 Job 与进程资源状态传播,未重新声称上一轮的 Rust 全目标、前端、Python 和远端验收均对当前版本完成。

增量:AppContainer/MCP 的 CPU 故障传播与替换验收

  • 扩展原生探针新增 mcp_cpu 工具模式,完成 MCP 初始化、工具目录和调用后启动同包 cpu_burn 后代进程,由后代的 8 个忙线程产生 CPU 压力。该负载处于真实零能力 AppContainer 和原生 Job 中,不是通过模拟资源状态触发错误。
  • 显式原生协议测试核验 tools/call 得到 EXTENSION_RESOURCE_CPU_EXCEEDEDRunning 资源状态一致,失败会话拒绝目录刷新,关闭后 Job 的 ActiveProcesses=0Host 写入并重开读取笔记成功。本次工具调用到错误约 12.7969873 秒,整项测试 30.86 秒,通过日志 .build/extension-cpu-appcontainer.log
  • 显式后台注册表测试核验调用回执和终态均保留 CPU 错误、终态 Failed、工具目录清空、旧 Endpoint 拒绝请求、Job 清空、包入口与根目录 ACL 恢复原基线。注册项回收后以同包启动新实例,其实例 UUID 改变,实际 MCP 工具调用成功,随后停止回收。本次调用到错误约 9.7654748 秒,整项测试 12.66 秒,日志 .build/extension-cpu-registry.log
  • 这些证据补齐了 CPU 故障通过原生会话和后台注册表传播的路径,不能将 9.77/12.80 秒的结果改称严格连续 10 秒的计时证明;窗口语义差异仍保留。实际产品启用、资源/网络/文件攻击全矩阵和完整 C-04 验收仍未完成。
  • 默认扩展回归 68 通过、9 ignored,新增两项显式长时测试已单独执行通过,其余 ignored 仍有其他长时验收及辅助进程入口;desktop 全目标 Clippy -D warnings 通过。日志 .build/extension-cpu-integration-regression.log.build/extension-cpu-integration-clippy.log
  • 同轮只读复查测试 SyncHTTP /health=200/ready=503,响应错误 DEPENDENCY_UNAVAILABLESSH 22 可以建立 TCP,但在认证前读到空 banner,连接被对端关闭。未尝试写入部署,也未将 /health 成功当作服务就绪。证据 .build/sync-cpu-integration-readiness.json;该远端障碍不阻止继续本地生产化工作。

增量:内存与进程数超限的错误传播和整组清理

  • 将 CPU 专用监视器扩展为 ResourceMonitor,继续保留 512 MiB Job 内存、16 个活动进程及单核等效 CPU 硬限额。在独立 completion port 上处理 JOB_OBJECT_MSG_JOB_MEMORY_LIMIT 与 JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT,分别发布 EXTENSION_RESOURCE_MEMORY_EXCEEDED / EXTENSION_RESOURCE_PROCESSES_EXCEEDED,随后终止整个 Job,沿用原有监视器失败/终止失败错误链。
  • 原先第二个挂起进程超过测试限额时只拒绝分配,现收到超限通知后也撤销已有 Job;相应原生测试改为核验明确错误与已存在进程全部退出。内存测试仍在受限子进程尝试正常 32 MiB 分配及超预算 600 MiB 分配,父进程改验资源错误与 Job 清空;新增子进程连续创建后代耗尽生产 16 进程预算的实际测试。该组 5 项通过,6 ignored 为长时项/父测试辅助进程,日志 .build/extension-memory-process-limits.log
  • 依据 Windows completion port 文档,这两类硬限额通知不保证投递;内核分配限额仍然执行,但当前事件驱动清理不能被宣称为丢通知时也有严格清理时限。没有将通知当作保证,也未据此启用第三方执行或关闭 C-04 缺口。
  • 原生 MCP fixture 新增 mcp_memory(尝试预留 600 MiB)与 mcp_processes(连续启动同包受管后代)模式。原 AppContainer 和后台注册表显式测试扩展为 CPU/内存/进程三类:核对调用错误、失败会话、资源状态、Job 清空、Host 保存;后台额外核对旧 Endpoint、工具目录清理、包 ACL 基线和每次失败后同包新实例实际调用成功。内存/进程回执限定 10 秒,CPU 保留既有 20 秒观察上限且仍不作为连续 10 秒计时证明。
  • 初次后台三类测试通过,CPU/内存/进程调用到错误分别约 12.339 秒、2.509 毫秒、395.929 毫秒,整项 16.34 秒;AppContainer 协议组三类也通过,整项 30.59 秒。日志 .build/extension-resource-registry.log.build/extension-resource-container.log。后续以收紧后的内存/进程 10 秒测试边界重新执行最终版本,结果另记。
  • 最终版本两项显式原生/后台资源集成测试同时执行通过,合计 26.42 秒,日志 .build/extension-resource-explicit-final.log;内存错误约 1.0–1.3 毫秒,进程数错误约 378–445 毫秒。默认扩展回归 69 通过、10 ignored,日志 .build/extension-resource-regression.logdesktop 全目标 Clippy -D warnings 通过,日志 .build/extension-resource-clippy.log。本轮没有重跑全部前端、后端或远端部署测试,也未声称完整生产化完成。

增量:Host 进程创建期间的句柄继承窗口

  • 扫描 frontend/src-tauri/src 下进程创建调用,当前自有生产路径包括 Core 的 command.group_spawn 与扩展的 CreateProcessW;其余直接创建进程位置位于测试模块。扩展此前在 ChildIo.create 即设置三个子端的继承标志,直到创建函数退出才关闭,Core 启动没有与该窗口协调。
  • 新增 Windows process_creation 共享互斥。ChildIo.create 现在保留六个端点默认不可继承;进入扩展原生创建区间时,InheritedIo 先持有共享锁,再设置三个子端继承标志,继续只将这三个句柄放入 PROC_THREAD_ATTRIBUTE_HANDLE_LIST。InheritedIo 字段析构顺序保证先关闭子端,再释放锁;部分设置失败也由同一所有者清理。锁中毒导致后续启动失败,不继续开放继承。
  • Core.group_spawn 的同步创建区间使用同一共享锁,锁在返回子进程后即释放,不覆盖 Core 握手、请求或整个生命周期。扩展不带 stdio 的创建仍使用 bInheritHandles=false。新所有权测试核对所有管道在区间外不可继承、区间内仅三个子端可继承、竞争启动线程须等待锁释放、释放后 Host 输出端到达 EOF。
  • CreateProcessW 文档说明通用继承在多线程并发创建时可能带入其他可继承句柄;UpdateProcThreadAttribute 仍要求 HANDLE_LIST 中的句柄具有继承标志。本轮因此同时保留显式列表并约束自有创建窗口。
  • 该锁只约束已接入的自有 Host 路径,不约束绕开该入口的第三方库或系统组件。尚未完成全部依赖/平台进程创建审计,以及真实并发启动的完整跨进程句柄攻击矩阵,不能据此宣称整个 Host 继承问题已经完全验收。第三方扩展仍未启用。
  • desktop 全目标测试累计 129 通过、12 ignored:库 114、Host 8、其余集成 7;覆盖原生扩展协议、后台实例、Core 生命周期/Workspace、凭据所有权及 Sync 故障恢复集成。本轮未显式重跑 ignored 长时资源/工具期限验收,辅助进程由其父测试驱动。日志 .build/process-creation-full.log。desktop 全目标 Clippy -D warnings 通过,日志 .build/process-creation-clippy.log

增量:Sync spool 校验的有界读取

  • 核查发现网络下载本身已经逐块写入临时文件,但下载命中缓存、sync_stage 和 sync_store_bytes 命中缓存仍通过 fs::read 校验整个对象。统一改为 payloads::verify,避免这些校验分支再为 100 MiB 对象分配整块 Vec。
  • payloads::verify 使用固定 64 KiB 缓冲,并同时校验实际读取长度与 SHA-256;即使元数据检查后输入继续增长,也最多读取声明长度加 1 字节,不再一直读取到变化文件的 EOF。打开后的句柄也检查长度。open_verified 返回回到起点的同一文件句柄,上传使用它完成预校验后继续分块上传,不为校验再重开路径。
  • 该辅助函数明确不是沙箱安全打开器,路径约束仍由调用方负责;同一打开句柄不等于外部写入被完全禁止。本轮不宣称消除所有路径替换/同时写入竞争。已有网络下载的摘要校验与原子无覆盖发布行为保留。
  • 新增生成式 100 MiB 读取测试,检查每次请求不超过 64 KiB;增长输入精确在声明长度加 1 字节时拒绝,截断、同长度内容损坏均拒绝,空对象正常。另用实际文件检查返回句柄从头读取与同长度内容修改被拒绝。两项通过,日志 .build/sync-spool-bounded-tests.log;生成流测试不是操作系统 RSS 基准。
  • 尚有 sync_apply_pending、Workspace journal 恢复/应用、冲突保留和外部变更扫描等路径读取整块内容;因此大附件端到端固定内存目标仍未完成,接下来仍需将已有持久化日志/操作回执/CAS 语义保持不变地接到流式 payload 应用路径。
  • desktop 全目标累计 131 通过、12 ignored(库 116、Host 8、其他集成 7),包含真实 Sync 服务有序推送/重复提交及故障恢复集成,日志 .build/sync-spool-bounded-full.logdesktop 全目标 Clippy -D warnings 通过,日志 .build/sync-spool-bounded-clippy.log。本轮未将这组结果视为大附件端到端 RSS 或完整生产化验收通过。

增量:持久化 payload 的流式日志应用与恢复

  • 新增 WritePayload 的内联字节/既有 spool 两种输入,write_source 保留现有操作 fingerprint、CAS、授权复核、持久化 intent 和回执事务;普通内联写入仍先持久化 payload,远端 sync_apply_pending 则直接引用已下载的摘要/长度,不再读取整个附件 Vec。
  • apply_stored_journal 从 payloads 引用打开并校验同一文件句柄,将内容以固定 64 KiB 缓冲复制到目标旁的临时文件;复制期间再次核对长度和摘要,成功后 fsync 与原子替换,再执行既有 files/sync_observed/outbox/operations/journal 事务。普通写入日志的 recover 直接走该路径,不再把 spool 读入 Vec。旧 inline journal 保持迁移兼容,先建立 payload 引用再按同一路径应用。
  • 结构化记录仍按 1 MiB 上限读取和校验,不将 JSON 规则放宽为任意文件流;文件上限保留 100 MiB。用于新写入 CAS、日志应用 CAS 及远端应用本地摘要的读取也改为有界 hash_file。路径安全仍依赖现有 resolve,未声称已解决校验与替换之间的所有文件系统竞争。
  • 真实 100 MiB 文件测试由 64 KiB 块创建 spool:验证远端身份、无远端回声 outbox、重复调用回执、同 operation 不同 payload 冲突;分别模拟目标尚未替换、目标已替换但数据库未提交两个日志恢复状态,重开后摘要正确、revision=1、每个本地 operation 只有一条 outbox,再次重开仍不重复。测试通过,日志 .build/sync-stream-journal-large.log,耗时 1.52 秒;这不是完整进程强杀矩阵或 RSS 基准。
  • 新增实际文件在 open_verified 后被同长度修改的复制测试,要求 copy_verified 返回 SYNC_SPOOL_CORRUPT,调用者仅在复制校验成功时发布临时文件。该证据针对复制内容校验,不代表所有重解析点/目录替换攻击均已覆盖。
  • rename/delete 的 file_ops payload 恢复、冲突保留/解决、外部变更扫描及部分 API 仍有整块读取;因此完整大附件低内存与全崩溃边界验收继续未完成。
  • 最终 desktop 全目标 133 通过、12 ignored(库 118、Host 8、其余集成 7),包括真实 Sync 服务有序推送/重复提交及故障恢复集成;日志 .build/sync-stream-journal-full.log。desktop 全目标 Clippy -D warnings 通过,日志 .build/sync-stream-journal-clippy.log。ignored 长时沙箱验收本轮未重跑,完整生产化目标保持未完成。

增量:重命名与删除的流式快照和恢复

  • 新增 store_payload_file:以有界摘要校验源文件,通过同一已校验句柄将快照流式写入 spool 临时文件,复制时复核摘要与长度,fsync/无覆盖发布后才登记 payload 引用。已有 spool 仍做有界校验;源文件超出 100 MiB 或内容不符合预期时不接受该快照。
  • prepare_file_op 的源摘要和 payload 保存不再使用整块 Vec。apply_file_op 保持旧 inline 日志迁移兼容,随后只使用摘要/长度引用与已校验文件句柄;源/目标 CAS 检查改为有界 hash_file,目标不存在时按 64 KiB 缓冲复制并复核内容,再按原顺序发布目标、删除源文件、提交身份/观察索引/outbox/回执事务。持久化引用摘要必须与 file_ops 的预期摘要一致。
  • 原有 Workspace 测试 10 项通过,日志 .build/file-ops-stream-tests.log。新增实际 100 MiB 文件测试,以分块写入建立源文件,依次模拟重命名前目标不存在、目标已复制且源仍在、目标已复制且源已删除;每次重开后核验摘要、原 file_id、已提交回执及仅一条 outbox,再次重开 revision 不递增。删除场景在源已删除后从 payload 恢复 trash,最后验证准备删除后发生的外部修改保持原样并进入 conflict,不产生额外 outbox。
  • 大文件测试通过,耗时 4.36 秒,日志 .build/file-ops-stream-large.log。该测试覆盖人工构造的持久化恢复阶段,不等于完整强杀/断电矩阵,也不是 RSS 测量;文件系统路径替换与全部持久化保证仍按原验收要求继续验证。
  • 冲突保留/解决、外部变更发现和部分记录/API 仍有整块内容读取;大附件端到端内存验收和整个生产化目标仍未完成。
  • desktop 全目标累计 134 通过、12 ignored(库 119、Host 8、其余集成 7),包括真实 Sync 服务及故障恢复集成,日志 .build/file-ops-stream-full.log。Clippy 首次指出流式改造后 workspace.rs 的 Write 导入仅供测试使用,已收为 cfg(test)desktop 全目标 Clippy -D warnings 随后通过,日志 .build/file-ops-stream-clippy.log。未把这组结果当作全部大附件 RSS、断电或完整生产化验收通过。

增量:冲突快照与解决的流式 payload

  • 从 store_payload_file 抽出共用 snapshot_file,新 sync_store_file 先有界计算源摘要,再用已有校验/流式复制/fsync/无覆盖发布流程保存快照,不为没有 operation 的冲突快照创建多余 payload 映射。冲突保留和用户决策前快照均改用此入口。
  • 冲突列表当前摘要、解决时本地 CAS 摘要改用有界 hash_file。“保留本地”“保留远端”“保留双方”的文件应用均使用 write_spooled_with_identity;本地快照长度从 spool 元数据取得并由写入入口复核,远端使用已存修订的摘要/长度。既有用户决定持久化、operation/rename/copy ID、版本复核、身份/别名及队列归档事务保留。
  • 原同步回归 16 项通过,日志 .build/sync-conflict-stream-tests.log。新增本地和远端各 100 MiB 的真实文件测试,三种选择分别验证过期 expected 被拒绝、冲突列表摘要、最终内容、主文件身份、copy 独立身份、重开并重复解决后待发送操作数不增加,以及旧提交仍被判定 SYNC_OPERATION_SUPERSEDED。大文件测试通过,耗时 14.35 秒,日志 .build/sync-conflict-stream-large.log
  • 首轮全目标编译发现删除决策 fingerprint 仍需要生产 hash 导入,已恢复其非 test 范围,同时移除 sync_inbox 中不再使用的 fs 导入;该问题在全目标回归期间发现,未将仅 lib test 编译通过当作全部目标通过。
  • 外部变更扫描、初始绑定对账和部分逻辑记录/API 仍有整块读取;未将这些功能测试当作 RSS 基准或完整强杀/断电矩阵。大附件端到端内存与完整生产化目标继续未完成。
  • 最终 desktop 全目标累计 135 通过、12 ignored(库 120、Host 8、其余集成 7),包括实际 Sync 服务与故障恢复集成;日志 .build/sync-conflict-stream-full.log。desktop 全目标 Clippy -D warnings 通过,日志 .build/sync-conflict-stream-clippy.log。本轮没有重新执行 ignored 沙箱长时验收,全部生产化条件仍未满足。

增量:扫描、首次对账与重新绑定的流式读取

  • 共用 hash_file_info 返回实际读取的摘要与长度;sync_file_info 对普通文件有界流式读取,对逻辑记录仍最多读取 1 MiB 加 1 字节并执行现有 schema 校验。sync_discover 不再读入整块文件,发现变化后用 store_payload_file 保存经过复核的快照再提交观察记录与 outbox。
  • 首次合并预览使用流式摘要/实际长度,确认后的本地准备使用流式 payload 快照,内容变化仍拒绝旧预览。Workspace.scan 的 Markdown 摘要也改为有界读取,避免 UI 扫描先分配整个大文件。
  • 空远端绑定原先只调用 Markdown scan;重新绑定时已观察过的附件没有新 outbox,后续 discover 也可能因摘要未变而跳过。本轮改为枚举同步白名单路径(含允许的附件/记录),归档旧绑定队列后为当前文件准备流式快照与本地写入意图,再建立新绑定队列;不再仅以 Markdown 集合作为绑定数据集。
  • 新增 100 MiB Markdown 与 100 MiB 附件测试,分别走首次合并与空远端绑定:仅改末字节即可使旧预览失效,绑定后重复发现不增加事件,UI scan 后的外部修改仍被 discover 识别一次,重开不重复;切换远端 Vault/账号重新绑定时两类文件均进入新队列且原 file_id 保持。测试通过,耗时 10.36 秒,日志 .build/sync-discovery-stream-large.log。先前同步回归 17 项通过,日志 .build/sync-discovery-stream-tests.log
  • 测试补充阶段修正了 Binding 不实现 Debug 时不能使用 unwrap_err 的测试写法,没有为调试输出扩大生产类型的可见字段。上述测试不是真实进程峰值内存测量、10000 文件基准或完整首次绑定故障矩阵;这些验收仍需继续。
  • 最终 desktop 全目标累计 136 通过、12 ignored(库 121、Host 8、其余集成 7),包含真实 Sync 服务与故障恢复集成,日志 .build/sync-discovery-stream-full.logdesktop 全目标 Clippy -D warnings 通过,日志 .build/sync-discovery-stream-clippy.log。仍需独立进程峰值内存和完整基准/部署/发布验收,完整生产化目标未完成。

增量:独立进程大附件内存观测

  • 新增 Windows 标准库脚本 scripts/measure-sync-memory.py,无额外 Python 依赖。先由 Cargo 构建当前 desktop library test executable,再以 exact 测试名称为每个工作负载单独启动进程;记录可执行文件/Rust 源码/Cargo.lock 摘要、HEAD、编译器与 CPU/OS 信息。每次必须确认恰好 1 项测试通过、0 失败/ignored 且有内存样本。
  • 通过 GetProcessMemoryInfo 每约 10 ms 读取操作系统累计峰值工作集和峰值提交内存,分别报告,不将二者相加。先用保留 64 MiB bytearray 的独立 Python 进程进行校验,本次峰值工作集约 74.70 MiB、峰值提交约 69.29 MiB,校验通过。15 次工作负载内存查询无错误,最大末次观测至退出间隔约 10.61 ms,原始数据保留该覆盖限制。
  • 对照(生成式 100 MiB 流)、真实文件写入/恢复、重命名/删除、三种冲突解决、发现/重绑定各运行 3 次,全部通过。四个实际文件工作负载三次最大工作集分别约 12.70、12.63、12.72、12.91 MiB;最大提交内存分别约 2.75、2.85、2.82、2.92 MiB。没有改造前实测基线,不报告下降百分比。
  • 可审阅报告 Windows Sync 组件内存观测原始 JSON。原始逐次测试日志留在 .build/sync-memory-5d3c214/。脚本 py_compile 通过,测量器和实际工作负载均已运行;本轮未改变 Rust 生产代码,未重复无关全量测试。
  • scope 仅为单个 Rust 组件测试进程,不包括 WebView/Core/服务端/系统文件缓存;没有测量规划基准的磁盘/网络/10000 笔记/双账号双 Vault,也不是 S-09 四并发上传服务总 RSS 的证明。报告明确 NOT_ASSESSED,完整基准、部署和生产化目标保持未完成。

增量:Sync 分块上传不阻塞 ASGI 事件循环

  • 复核服务端现状:complete 已用 hashlib.file_digest 与 put_filedownload 已逐块校验到临时文件再 FileResponse;未重复改造已存在的流式路径。
  • upload_chunk 原先在 async 路由中直接执行同步数据库锁等待、文件写入和 fsync,会阻塞该 worker 事件循环。现将整段事务/文件持久化交给 Starlette run_in_threadpool,连接在同一工作线程创建和提交,仍保持先刷盘再确认 offset 的协议顺序。接收块先检查剩余额度再扩展 bytearray,避免把超限块复制进应用缓冲区;ASGI 自身收到的块不计入该应用缓冲上限证明。
  • 新增故障测试以 Event 持续阻塞 fsync,在同一 TestClient ASGI 事件循环中要求 /health 在 2 秒内响应且上传仍在等待;释放后检查偏移与 complete。另测 1 MiB 加 1 字节拒绝、fsync 异常事务回滚、未确认尾部协调截断、恰好 1 MiB 重试成功。
  • uv run --project "server sync" pytest "server sync/tests" -q 全套 25 通过,耗时 7.80 秒,JUnit.build/sync-server-upload-threadpool.xml。依赖报告 2 项 TestClient/AnyIO 弃用警告,无测试失败。环境为 SQLite/DiskObjects 受控测试,不是 PostgreSQL/MinIO 两 worker 或 S-09 四并发 100 MiB 服务总 RSS/30 分钟负载证明;线程池饱和与真实部署验收仍需继续。完整生产化目标未完成。

增量:四客户端大附件传输验收入口

  • 新增 server sync/tools/upload_benchmark.py,固定种子 20260908,两测试账号各两个新 Vault,四任务屏障同时开始默认 100 MiB 上传。内容逐个 1 MiB 生成,下载也逐块验证,不在驱动器构造完整附件。逐 offset、完整回执与 revision 重放、SHA256/长度、跨账号对象拒绝均为必过条件;准备失败会取消其他等待任务。
  • 命令入口从本地凭据文件读取两个测试账号,不把凭据/令牌/异常原文写入输出;拒绝带认证信息/query/fragment 的 origin,不跟随重定向,HTTP 要求显式测试开关。整体运行限时 30 分钟;保留四个新测试 Vault,不删除既有数据。README 已列命令与隔离数据要求。
  • 实际运行 Uvicorn TCP 回环测试:四个 1 MiB + 17 字节验证非整块末尾;四个 100 MiB 验证实际大对象。两项通过,耗时 16.28 秒;大对象上传至下载/隔离验证全部完成约 9.31 秒,400 MiB 内容全部摘要一致。日志 .build/sync-upload-benchmark.logJUnit .build/sync-upload-benchmark.xml。
  • 此结果是同一 Python 进程内 SQLite/DiskObjects 单服务实例与 HTTP 客户端的受控检查,不是 PostgreSQL/MinIO 两 worker 基准。service_rss_bytes 明确 nullacceptance 明确 NOT_ASSESSED,不能将传输通过当作 RSS≤2 GiB 或完整 S-09 通过。本机 Get-Command docker 未找到可执行文件;生产拓扑/服务内存采集/30 分钟负载仍需继续。
  • 最终 Sync 服务端全套 27 通过、2 项依赖弃用警告,22.39 秒;日志 .build/sync-server-four-upload-full.logJUnit .build/sync-server-four-upload-full.xml。用户 Vault 修改保持原状,完整生产化目标未完成。

增量:就绪探测超时后的工作线程有界性

  • 只读复查测试服务器:/health 返回 200/ready 返回 503 DEPENDENCY_UNAVAILABLESSH 22 TCP 可连接但读取 banner 得到 0 字节,尚未进入认证。没有远端写入;不能据此定位具体依赖或宣称部署已恢复。
  • readiness 原先 wait_for(to_thread(...), 3) 超时后取消包装任务,但不能停止底层同步线程;缓存到期后可能再创建新的阻塞探测。本轮提取 Readiness,使用 shield 保持任务可追踪,并在其结束前复用同一进行中的任务,每个应用 worker 最多一个此类依赖探测。保持 3 秒等待、5 秒结果缓存与对外固定错误码。
  • 请求取消不丢失后台任务引用;晚到异常由完成回调检索,不写入依赖错误文本或凭据。完成后的后续新探测可恢复 ready。测试覆盖取消后 20 个探测请求均失败但底层调用数仍为 1、释放阻塞后异常收尾、健康新探测,以及失败/成功结果缓存。
  • 本改动限制同时进行的后台探测数量,不能强杀陷入 OS/驱动 I/O 的线程,不作为异常退出时限证明。真实依赖超时、远端恢复和服务负载验收仍未完成。
  • 首次全量测试暴露提取代码时误删相邻 handshake 路由(1 failed / 28 passed);差异审查已恢复原路由,此失败不计为最终通过证据,最终结果另列。
  • 修正后最终 Sync 全套 29 通过、2 项依赖弃用警告,22.83 秒,包含实际四并发 100 MiB TCP 传输。日志 .build/sync-readiness-full-final.logJUnit .build/sync-readiness-full-final.xml;完整生产化目标仍未完成。

增量:侧栏布局进入 Vault 逻辑同步

  • 新增 layout/sidebars 记录,Host path_for/allowed 和严格 schema 同时登记。字段白名单为 primaryExpanded、workspaceWidth、chatWidth,宽度 200–520;未知字段和路径身份拒绝。
  • 新增 Pinia layoutPreferences,将主侧栏展开与文件/对话侧栏宽度接入共享状态,沿用现有本地键读取和保存。preferenceSync 新增第三个 RecordBinding,初始种子、草稿、CAS 冲突和远端应用抑制回流使用既有机制;没有直接同步任意 localStorage。
  • SecondarySidebar 对目标宽度与可用视口宽度分开处理:调整窗口仅改变呈现,不产生同步写入;窗口恢复空间后重新使用偏好宽度。收到远端宽度时组件也重新计算本机范围。
  • 定向前端 4 项通过,包括远端布局不回流、本地布局写入、两个侧栏宽度分离、窄窗口限制不污染偏好。新增 Rust 测试覆盖布局记录完整信封/允许路径、非法宽度和设备字段拒绝。完整前端 101 文件、526 项通过,日志 .build/layout-sync-frontend.log。
  • 本轮覆盖现有侧栏布局,不代表全部逻辑数据已经完成:Skills、对话、Agent/人设、Provider 非秘密参数和安装清单仍需各自适配;真实双设备 UI 与旧版本新增记录兼容验收尚未完成。
  • 最终 desktop Rust 全目标 137 通过、12 ignored(库 122、Host 8、其余集成 7),日志 .build/layout-sync-rust.log;全目标 Clippy -D warnings 与前端 type-check 均通过,日志 .build/layout-sync-clippy.log、.build/layout-sync-types.log。没有改动用户 Vault 内容,完整生产化验收仍未完成。

增量:桌面人设读取当前 Vault 记录

  • 增加 persona/default 严格逻辑记录与 workspace.persona.get/write 专用 Core RPC。保留 Task RPC 范围,新增入口仍核验 Vault 和记录 kind/id。记录回执增加原始已提交 bytes 的 hash,以便响应丢失重放时返回正确摘要。
  • 桌面 persona_settings 经 Host 读取/保存,并以 revision 摘要作为 expected;数据 version 仅作为显示版本递增,不替代内容 CAS。调用方 operation_id 原样传递给 Host,未知提交结果不自动换 ID 重试。API 读写 handler 改为同步函数,由 FastAPI 工作线程执行阻塞 Host RPC。
  • 原来全局 SQLite 人设不猜测所属 Vault:桌面空库返回空人设,Web 仍使用全局存储且旧数据保留。聊天/Agent 的 apply_global_persona 沿既有调用链获取此作用域的数据。UI 显示工作区人设说明,并保留 revision;Vault 切换或迟到的旧 Vault 加载响应不能让旧表单保存到新 Vault。
  • Python 定向 5 项通过,覆盖全局原有行为、桌面摘要保存、过期摘要映射、Host operation_id、旧全局保留/不自动导入。Host 新测试覆盖真实 Workspace 重开、操作重放、CAS、未知字段和跨 Vault 拒绝。前端新增表单摘要往返与切 Vault 拒绝测试,定向 4 项通过;完整前端此前 526 项通过,类型检查通过,新加测试单独运行通过。
  • 该能力仍需真实双设备人设同步/冲突与明确归属旧数据导入验收,不能据此声明全部逻辑数据同步或生产化完成。
  • 最终 Python 全套 902 通过、1 项依赖弃用警告,105.26 秒;desktop Rust 全目标 138 通过、12 ignored(库 123、Host 8、其余集成 7),Clippy -D warnings 通过。日志 .build/persona-sync-python.log、.build/persona-sync-rust.log、.build/persona-sync-clippy.log;前端日志 .build/persona-sync-frontend.log 和 .build/persona-sync-types.log。完整目标继续保持未完成。

增量:人设与布局的真实集成验收

  • 扩展 sync_push 实际 HTTP 测试:两个 Rust Workspace 客户端连接 Uvicorn SQLite/DiskObjects 服务。人设和布局先完成初始传输,再各进行 20 轮双方同时修改;人设整数 version 故意相同而内容不同,证明冲突依据文件摘要而非显示版本。
  • 每轮远端提交后,本地另一份内容仍保留,旧摘要解决请求被拒绝;交替使用保留本地/采用远端(各 10 轮),重复同一已持久化选择不增加操作。推拉完成后两端完整记录、hash 和 file_id 相同,sync_next 均为空。最终真实关闭并重开客户端 B,pull 返回 0、push 返回 false,两类记录仍与 A 一致。
  • 扩展 core_workspace 实际 Python Core HTTP + Host 管道测试:读取空人设、保存得到 64 位摘要、同一操作和输入重放 20 次返回相同响应、用空旧摘要重新提交得到 409、不同 Vault 读取被拒绝,正常读取仍等于原回执。Host 待处理操作计数仅增加 1,持久记录 hash 等于 HTTP revision。
  • cargo test --features desktop --test core_workspace --test sync_push:两项集成通过、1 项辅助进程入口 ignored;分别 2.79 秒和 25.44 秒,后者同时包含既有真实 100 MiB 上传断点/重启用例。日志 .build/persona-layout-integration.log。全目标 Clippy -D warnings 通过,日志 .build/persona-layout-integration-clippy.log。本轮仅扩充集成测试,没有重复无关生产代码回归。
  • 证据范围为本机隔离服务与两个 Rust 客户端,并非两台独立硬件上的最终 UI。此处只覆盖同改与两种取舍,不覆盖全部 S-03 的改对删/rename/副本/历史恢复矩阵,也不完成旧全局人设明确归属导入或发布版本兼容。完整生产化目标保持未完成。

增量:明确选择旧全局人设导入目标

  • 新增桌面专用只读 /api/settings/persona/legacy。先经 Host persona.get 验证当前 Vault,再读取旧 SQLite 来源;无来源返回 available=false。源数据不含目标 CAS revision,不修改 Workspace,也不删除或重写旧人设行。
  • 人设对话框新增查看旧全局人设、内容预览和填入当前表单两步。预览文字按普通 Vue 文本渲染,限制长文本展示高度;填入操作仅复制 name/system_prompt/dialogue_pairs,保留当前工作区 version/revision。用户仍需正常点击保存,沿用 Host CAS/journal。界面说明替换草稿与保留来源的行为。
  • 预览响应持有发起时 Vault 标识;切库/关闭后不将迟到内容填入新工作区。测试验证预览与复制阶段均没有 PUT、保存使用目标摘要而非源版本、切库迟到响应不展示、无来源、Host 拒绝时不能读取,以及旧数据保持不变。
  • 前端人设定向 6 项、Python 人设定向 7 项通过;完整前端 101 文件/529 项通过,日志 .build/persona-import-frontend.log。完整后端与类型检查结果另列。
  • 此流程是用户明确选择的复制导入,不是自动所有权推断;没有实现旧来源清除。完整导入进程中断矩阵、独立设备 UI 与发布兼容验收仍需继续,完整生产化目标保持未完成。
  • 最终后端全套 904 通过、1 项依赖弃用警告,81.49 秒;前端 type-check 通过。日志 .build/persona-import-python.log、.build/persona-import-types.log。本轮无 Rust 生产代码改动,未重复 Rust 全套;用户 Vault 修改保持原状。

增量:副本路径预检与逻辑记录文本副本

  • 发现 sync_resolve 会先持久化 copy 决定,再由写入路径校验逻辑记录;无效目标可使 pending 决定无法应用且不允许改选。现于 INSERT 前检查目标同步白名单,并针对记录目标流式验证原始快照及目标记录 schema,不在验证失败时冻结选择。
  • 新增真实 Workspace 故障测试:人设同改后,copy.json(不在同步白名单)与 layout/sidebars(错误记录身份)均被拒绝,sync_resolutions 行数仍为 0,本地内容保留;随后改选 attachments/persona-copy.txt 成功,重开后文本副本是完整本地记录、活动人设是远端记录,冲突已关闭。定向测试通过,日志 .build/record-copy-preflight.log。
  • SyncSettings 对逻辑记录提供 attachments/settings-copy.txt 路径提示,并说明文本副本用于查看恢复而不自动应用。
  • 真实 HTTP 双客户端测试扩充为人设、布局各 60 轮同改冲突,三种选择各 20 轮。副本分支额外要求两端副本正文/摘要一致,副本 file_id 在两端一致且不同于活动记录。最终执行结果另列。
  • 生产代码完整 Rust 回归 139 通过、12 ignored,日志 .build/record-copy-full-rust.log;随后单独运行扩充后的 60 轮/类别 HTTP 用例通过,38.97 秒,日志 .build/record-copy-http-final.log。Clippy 首次发现新测试重开变量多余 mut,已移除,最终全目标 -D warnings 通过(.build/record-copy-clippy-final.log)。前端 529 项及 type-check 通过,日志 .build/record-copy-frontend.log、.build/record-copy-types.log。
  • 上述结果证明本机双客户端同改的三种选择与文本副本,不代替完整 S-03 改对删/rename/历史恢复、独立硬件 UI 或发布验收。本轮未更改用户 Vault 数据,完整目标仍未完成。

增量:可选逻辑数据同步范围的持久层

  • 复核生产化规划第 154 行发现,人设与布局属于“用户选择后同步”,不能沿默认白名单直接同步。本轮先建立 sync_scope::OptionalScope 持久层,persona/layout 两项均默认 false;严格 DTO 拒绝未知类别。配置只存当前本机 Vault SQLite,不写 outbox、不作为逻辑记录上传。
  • Workspace 升级到 schema 11,新建 sync_optional_scope 表,原 schema 升级前仍走既有 SQLite 备份流程。新增测试从 schema 10 升级后验证 Vault/文件身份、正文与待提交操作保留,且无自动授权。
  • setter 在已有活动绑定时返回 SYNC_SCOPE_REBIND_REQUIRED,避免直接切换范围后跳过远端历史。计划的产品流程为解除绑定、调整选择、重新对账;scope 需纳入初始预览 fingerprint,重新绑定必须能重新获取先前排除的远端记录。
  • 当前仅完成持久层,尚未接入传输过滤与 UI,因此不能将 default=false 当作已经阻止人设/布局传输的证据。 下一步必须先完成 sync_paths/发现删除、capture/已排队 job、初始预览、pull 下载/stage/apply 的一致范围检查;排除项只推进元数据游标,不下载对象、不写本地文件、不删除远端数据。不得在这些边界未接齐时宣称“可选同步完成”。
  • 持久选择、重开、另一 Vault 隔离、绑定后拒绝修改、解绑后修改及未知字段拒绝的最初定向测试通过(.build/sync-optional-scope.log);补充升级用例后的完整结果另列。
  • 最终 desktop 全目标 142 通过、12 ignored(库 127、Host 8、其余集成 7),包含 schema 10 升级新用例;全目标 Clippy -D warnings 通过。日志 .build/sync-scope-foundation-full.log、.build/sync-scope-foundation-clippy.log。此结果仅证明持久层与现有回归,不能证明范围过滤已生效,下一轮优先完成剩余接线。

增量:可选范围接入实际传输与设置

  • 将 schema 11 的 scope 接入 sync_paths、外部删除发现、outbox 捕获、旧作业选择/提交前检查,以及初始预览(摘要包含选择)。旧可选作业无授权时归档,不让其阻塞普通笔记队列。关闭类别不转换为删除本地文件/远端版本。
  • pull 的增量和初始快照两条路径均在对象下载前判断范围;未选记录可在没有 spool 正文时 stage 为元数据,apply 只将状态标为 excluded 并推进相应游标。不能通过已缓存 inbox 或旧 conflict resolution 自动改写未选类别;手工解决关闭类别时明确返回 SYNC_SCOPE_DISABLED。
  • 新增主窗口 sync_set_scope 命令,核对 Vault 身份,绑定期间拒绝修改。SyncSettings 显示默认关闭的人设/布局选择,改变范围立即失效旧预览,保存前不乐观显示选中状态;已绑定时提示解绑后重新合并。人设表单文案改为可选择同步。
  • 新增范围测试覆盖无正文 spool 时跳过远端人设而游标推进、本地内容不变/无冲突、旧预览因开启范围失效,以及 schema 前残留队列不得越过缺失授权。真实 HTTP 增加默认关闭的第三客户端,要求没有活动人设/布局文件及对应 head spool;开启后新快照绑定补齐两类记录且无重复上传。既有人设/布局传输测试改为显式选择后运行。
  • 前端全套 530 项与类型检查通过(.build/scope-wired-frontend.log、.build/scope-wired-types.log);调整最终文案及选择控件后定向 12 项和类型检查通过(.build/scope-ui-final.log、.build/scope-ui-final-types.log)。
  • Rust 首次含新增用例的并行全套出现既有 AppContainer 测试失败:启动参数/环境辅助进程返回 1(不是网络越权判定),日志 .build/scope-wired-final-rust.log。单独复核同一实际探测通过,16.94 秒(.build/scope-native-recheck.log),原因尚未定位;保留此失败,不据此宣称全套稳定。随后对最终代码串行全量验证,结果另列。
  • 最终串行 desktop 全目标 143 通过、12 ignored(库 128、Host 8、其余集成 7),含第三客户端关闭/重开范围的实际 HTTP 验证,日志 .build/scope-wired-final-serial.log;补充旧队列测试单独 1 项通过(.build/scope-old-queue-final.log),累计覆盖 144 项通过用例。最终全目标 Clippy -D warnings 通过(.build/scope-wired-clippy.log)。
  • 本轮修正了先前人设/布局默认进入同步的规划偏差;仅这两类可选记录已经接通选择与传输。尚未实现的可选数据类、完整发布/兼容、独立设备 UI 和上述偶发 native 失败原因仍需处理,完整生产化目标未完成。

增量:原生启动探针的许可预算与故障诊断

  • 追查先前并行回归退出码 1:失败位置是正常 argv/environment 启动探针,而不是回环网络越权检查。该探针 Claims.expires_at_ms 原为 1000prepare 使用 now_ms=2Lease 将其转换为约 998 ms 的 Instant 剩余寿命;但进程等待允许 5 秒。调度/启动耗时超过许可时,Watch 会终止 Job,退出码也是 1。
  • 历史失败未记录授权状态,不能据此确认唯一根因。已修复可确定的测试预算不一致:正常启动探针采用 120 秒测试许可,与其他正常原生协议探针一致;进程完成仍须在 5 秒观察窗口内,不延长实际启动成功条件。独立 cause=expiry 的两秒 Lease 及自动终止/EXTENSION_PERMIT_EXPIRED 断言保持原样,生产许可/资源/撤销实现没有修改。
  • 启动断言失败时增加耗时、授权错误机器码、活动进程数诊断,不输出 argv、环境、凭据或用户路径,便于后续区别许可撤销、资源终止与程序自身异常。
  • 第一轮默认并行 desktop library 回归 129 通过、10 ignored,21.72 秒,含实际正常启动、网络和短期许可到期用例,日志 .build/native-budget-parallel-1.log;后续重复结果另列。
  • 第 2、3 轮同样默认并行运行,各 129 通过、10 ignored,分别 21.24 与 20.88 秒,日志 .build/native-budget-parallel-2.log、.build/native-budget-parallel-3.log。三轮共 387 次通过执行,不能将重复执行数当作独立测试数量。全目标 Clippy -D warnings 通过(.build/native-budget-clippy.log)。本轮仅修改原生测试探针预算和诊断,不改变生产安全策略;历史偶发失败根因未获得完整现场证明,整个生产化目标仍未完成。

增量:修复布局记录的桌面命令白名单遗漏

  • 检查用户 Skill 的保存路径时,发现 record_commands::preference 仍只允许 theme_settings/preferences,遗漏已实现的 layout。之前的 Rust Workspace/传输测试绕过此主窗口策略,前端又 mock 了 hostInvoke,因而未能证明真实布局命令可用;此前“布局同步已接通”的证据对此边界不完整。

  • 增加 layout 白名单,保留 persona/Task/凭据等其他类别拒绝。record_get/write 共用可直接测试的 get_record/write_record,实际 Tauri command 也调用相同函数;校验 Vault、kind/id、schema 和 journal 的生产路径不再由测试替代。

  • 两项 Host 主程序测试通过:布局真实策略写入与同操作重放、关闭/重开读取同一记录、跨 Vault 拒绝且 outbox 不额外增加,以及禁止把偏好命令扩展成任意记录访问器、未知 token 字段在 journal 前拒绝。日志 .build/layout-command-boundary.log。

  • 修复同时解除首次上传/合并 seedCurrentPreferences 中准备布局记录时的 RECORD_SCOPE_DENIED 障碍;可选范围过滤仍由独立 sync_scope 决定,允许本机编辑不等于授权上传。尚未补齐用户 Skill 编辑/逻辑记录,本轮优先修复实际边界缺陷。

  • 完整 desktop/all-targets Rust 回归 146 通过、12 ignoredlibrary 129、Host 10、其他集成 7),包括真实 Core 桥接与 Sync 服务集成;Clippy --all-targets -D warnings 通过。日志 .build/layout-command-full.log 与 .build/layout-command-clippy.log。未执行真正双机桌面 UI 验收,不能据此标记整体生产化完成。

增量:当前 Vault 的用户 Skill 逻辑记录

  • 新增 user_skill_<32位小写十六进制> 严格逻辑记录,Host 固定存入 opennexus-records/v1/user-skills/;名称、提示词、工具、权限声明、模型能力、检索参数、版本与时间均有类型、数量和长度上限,未知字段在写入 journal 前拒绝。该类别进入默认同步范围;安装目录、密钥、设备授权、启用状态和运行环境不能写入记录,安装包也不能占用 user_skill_ 保留命名空间。
  • Core 增加当前 Vault 专用的 list/get/create/update/delete API,并通过窄化 Host RPC 访问,不能借操作回执读取 persona/task 等记录。更新和删除使用摘要 CAS;有效 UUID Idempotency-Key 进入 Host journal,同一操作与相同输入可在响应未知后重放,改变目标、旧摘要、操作类型或业务字段会返回 USER_SKILL_OPERATION_CONFLICT。Workspace 持久回执补充原始 expected 摘要,重开后仍能完成输入一致性核验。
  • Skill 页面增加用户 Skill 编辑器,明确权限字段只是声明而非设备授权;工具缺失、权限声明不足与可运行状态分开展示。Agent 页面只列可运行记录,实际 /api/agent/runs 会从 Host 读取当前 Vault 的用户 Skill 并再次核对本机工具、权限声明和模型能力。列表按 Host 分页读取,避免超过 100 项时静默截断。
  • 前端保存和删除在结果不明确时保留原 UUID;同一 Vault、记录和表单内容重试会复用该 UUID,内容改变才产生新操作。Vault 切换同步清除编辑状态和待重试标识,迟到的列表或保存结果不得写入新 Vault 的界面状态。该内存重试状态不跨应用完全退出,不能将其视作跨重启 UI 草稿恢复。
  • 实际 Python Core + Rust Host 集成覆盖创建、20 次相同重放、改变输入冲突、列表、跨 Vault 拒绝、CAS 更新、过期摘要拒绝、Agent 选择运行、删除及关闭前 journal 计数。实际 Uvicorn Sync + 两个 Rust Workspace 客户端对用户 Skill 进行了 60 轮同时修改,保留本地/采用远端/创建文本副本各 20 轮,并验证旧摘要拒绝、重复解决、两端收敛、重开稳定;第三个默认范围客户端可接收用户 Skill,同时仍排除未选择的人设与布局。
  • 最终 desktop Rust 全目标 148 通过、12 ignoredlibrary 131、Host 10、其余集成 7),Clippy --all-targets -D warnings 通过,日志 .build/user-skill-rust-full-final.log.build/user-skill-clippy-current.log。后端 908 项通过、1 项依赖弃用警告,日志 .build/user-skill-python-full-current.log。前端 103 个测试文件、536 项通过,类型检查和生产构建通过,日志 .build/user-skill-frontend-full-final2.log.build/user-skill-frontend-build-final2.log
  • 证据来自本机隔离服务和客户端进程,尚未替代两台独立硬件上的桌面 UI、跨发布版本或每个持久化边界强制终止验收。Provider 非秘密参数、安装清单、对话等规划内逻辑数据仍未适配;完整生产化目标保持未完成。

增量:生产验收 Runner 的失败闭合入口

  • 新增规划约定的 scripts/phase3-production-acceptance.py,固定登记 sidecar/credentials/sandbox/extensions/sync-client/sync-service/e2e 七个 suite 和 30 个验收 ID,支持 --case 单例与机器可读清单。CI 的 backend job 会验证清单入口,新单元测试覆盖清单唯一性和 suite 归属。
  • 配置必须显式确认隔离和破坏性测试,提供唯一 run、平台 profile、固定 seed 及绝对临时数据根;首次只接受空目录并写入绑定标记。runner 拒绝个人 Vault、仓库或 Git 路径、符号链接、非空未标记目录、明文秘密字段、带认证信息/query/fragment 的服务 URL,以及未显式声明的测试 HTTP。秘密只按环境变量名引用,缺值直接失败。
  • 每个 case 只调用仓库固定登记的 driver,配置不能注入命令。driver 的 JSON 必须含独立断言、文件/revision 清单和该 ID 要求的指标;非零退出、超时、坏 schema、缺指标、缺安装产物/权限/秘密引用、必测 skip 或结果秘密命中均失败。输出含逐 ID JSON、JUnit、固定 ID 清单、脱敏限长日志、commit、锁文件/安装产物/config 摘要;已有非空报告目录不覆盖。
  • 5 项 runner 测试通过,覆盖个人 Vault/明文秘密/非空目录拒绝,未登记 ID 生成 JUnit failure 且退出 1driver 缺断言/指标失败,以及测试秘密在日志中被替换。实际 CLI 清单检查通过;使用模板运行 A-01 得到预期 NOT_IMPLEMENTED、summary NOT_PASSED 和退出 1,证明缺实现不会误报成功。包含该测试的后端全套 913 项通过、1 项依赖弃用警告,日志 .build/acceptance-runner-python.logPython 编译与 Markdown 链接检查通过。
  • 当前仅完成 P0 runner 与报告协议,30 项完整生产 driver 尚未登记;因此没有任何 A/B/C/D/S/E ID 因本增量变为通过。后续逐项接入时仍须满足规划表的全部断言、实机/生产依赖和量化指标,完整生产化目标保持未完成。

增量:B-02 Fernet 迁移生产验收

  • 将既有 100 条 Python Fernet 夹具扩充为 B-02 独立 Rust oracle:本地主密钥迁移后逐 ID/值重开核对,初次导入加三次重复导入始终为 100 条;源密文和受管理主密钥字节不变,所有权标记记录源摘要、数量和密钥来源。
  • 新增环境主密钥且没有 master.key 的迁移、空库零条切换、缺钥匙、单条坏 token 及目标同 ID 异值冲突。后三种失败均在提交和 owner 标记前停止,目标 Stronghold 与旧 credentials.json 字节保持原样;环境密钥场景不创建或修改源主密钥文件。
  • B-02 driver 只运行仓库固定的 exact Rust oracle,登记 6 组断言及 Fernet 夹具 SHA-256。首次在未提交源码上运行虽得到测试成功,但 summary 只能指向旧 HEAD,已明确弃用该报告;runner 随即增加非 Vault 源码脏状态拒绝和模板 run ID 拒绝,避免 commit 与被测代码不一致。用户 Vault 修改继续排除在源码洁净判定之外。
  • 提交 fac8cd7 后在只保留用户 Vault 修改的工作树运行 python scripts/phase3-production-acceptance.py --suite credentials --case B-02 ...,退出 0summary 与 case 均为 PASSEDcommit 为 fac8cd7ad458838ceb25c139b496f5b88d00b3b5,6 项断言通过,耗时 32275 ms。证据目录 .build/acceptance/b02-fac8cd7-36b36a78f92b4d04a5120a19eb259287/,不含凭据。
  • 最终 desktop Rust 全目标 148 通过、12 ignored,日志 .build/b02-rust-full.log;全目标 Clippy -D warnings 通过(.build/b02-clippy.log),runner 6 项测试、Python 编译、Markdown 链接检查通过。B-02 可记为通过;迁移每个持久化边界强杀、明确清除旧文件、旧版本写入阻止和 UI 恢复属于 B-04/端到端门禁,仍未完成,整体生产化目标保持未完成。

增量:S-01 离线链与响应丢失生产验收

  • 扩充实际 Uvicorn + Rust 双客户端用例:客户端 A 在首次连接前连续写同一文件 20 次,客户端 B 拉取后也在不进行网络调用时连续写 20 次;各自 pending 数在联网前均为 20,最终正文、内容摘要和稳定 file_id 在两端一致。
  • 测试服务增加只在隔离 marker 存在时启用的 revision 响应闸门。服务完成数据库提交后写入测试标记并暂缓返回;父测试在该点强杀实际 Rust 客户端辅助进程。重新打开同一 Workspace 后 20 个 pending 全部仍在,证明服务端提交没有被误当成本地确认,也没有因进程终止静默丢队列。
  • 对丢失响应的同一 operation/payload 直接重放 100 次,全部返回原 sequence 1;本地仍保留 20 个 pending。随后正常 push_one 取得同一回执,只确认第一项并留下 19 项,最终逐项提交得到 20 条连续 revision,逐条满足 base_revision = sequence - 1,重复 push 返回空。
  • S-01 driver 固定调用上述 exact 集成 oracle,登记 5 组断言、两个测试源文件摘要和 20/100 revision 计数。提交 fb947c6 后由干净源码运行统一 runner,退出 0summary/case 均为 PASSEDcommit 为 fb947c6658453ded5ee0a11e0d8538834d0192c8,5 项断言通过,耗时 52330 ms。证据目录 .build/acceptance/s01-fb947c6-49bf176d2f2d42699f620e22d7349598/
  • Sync 服务全套 29 项通过、2 项依赖弃用警告(.build/s01-sync-server.log);desktop Rust 全目标 148 通过、13 ignored(新增的 ignored 是由父测试实际启动并强杀的 revision 辅助入口),日志 .build/s01-rust-full.log;全目标 Clippy 通过(.build/s01-clippy.log)。S-01 可记为通过;100 MiB 每边界续传、完整改删/rename/历史恢复矩阵与分类 schema 门分别属于 S-02/S-03/S-08,仍保持未完成。

增量:S-02 附件续传与拉取持久化边界生产验收

  • 新增独立拉取故障 oracle,对 spool 写入、inbox stage、Workspace 文件提交和 cursor 提交四个持久化边界各启动并强杀 20 个真实辅助进程,共 80 次。每次重开先验证 cursor 没有超过实际已落盘 revision,再从该边界恢复到 cursor 1,并逐项核对正文、SHA-256、稳定 file_id 和 pending 数。
  • 复用实际 Uvicorn Sync 服务与 Rust 客户端的 100 MiB 附件路径:服务端每持久化 10 MiB offset 后阻塞响应,父测试强杀客户端,共 10 个边界;下一进程查询 offset 并继续上传。最终下载长度为 104857600 字节、SHA-256 与源文件一致、file_id 不变,远端落盘后 pending 和重新发现数均为 0,SQLite 元数据文件均小于 5 MiB。
  • S-02 driver 固定顺序执行上述两个 exact Rust oracle,登记 6 组断言、3 个实现/夹具文件摘要以及附件大小、10 次上传强杀、4×20 次拉取强杀计数。提交 b00f821 后在只保留用户 Vault 修改的工作树运行统一 runner,退出 0summary/case 均为 PASSEDcommit 为 b00f821cb51535128e311672c185bfe34ca9d6d7,6 项断言通过,耗时 58895 ms。证据目录 .build/acceptance/s02-b00f821-9f7b0b7c4a9d4e63a3c37ad85c5cb14e/,报告标记 contains_credentials=false
  • 最终 desktop Rust 全目标 148 通过、15 ignored(新增 pull worker 和 80 次强杀父 oracle 均只由 S-02 driver 显式运行),日志 .build/s02-rust-full.log;全目标 Clippy -D warnings 通过(.build/s02-clippy.log),runner 6 项测试、Python 编译、固定 30 项清单检查通过。S-02 可记为通过;冲突/删除/rename/历史恢复、完整分类 schema 以及 PostgreSQL/MinIO 运维门分别属于 S-03、S-08 和 S-04S-09,仍未完成。

增量:B-01 凭据分域与明文暴露生产验收

  • 新增 Stronghold 分域矩阵,在 Provider、Plugin、MCP、Sync 四个域各写入 3 个测试秘密。12 项同域解析逐值成功,36 次跨域解析和 Plugin/MCP/Sync 各 3 次同类型跨 owner 解析全部返回 CREDENTIAL_SCOPE_DENIED;锁定后 12 项解析全部返回 CREDENTIALS_LOCKED
  • 对 Stronghold 快照、公有凭据 ID/锁定状态、固定错误码和 Workspace Sync 提交 payload 逐个扫描 12 个测试秘密,命中为 0。Sync 会话 oracle 另行验证 endpoint/account 绑定,错误服务器或账号不能复用会话,Stronghold 快照不含 access token;锁定会取消进行中的调用。
  • 扩充真实 Python Core + Rust Host 集成:通过受控 Host pipe 写 Provider 秘密后,再走带 Host 会话认证的实际 HTTP 状态查询。写入与查询响应只包含 credential_id/configured 状态,不含秘密,Core 数据目录不产生旧 Fernet master.keycredentials.json。B-01 driver 还扫描三个 exact oracle 的完整 stdout/stderr,任一测试秘密或 Sync token 命中即失败。
  • 提交 5405e41 后在只保留用户 Vault 修改的工作树运行 python scripts/phase3-production-acceptance.py --suite credentials --case B-01 ...,退出 0summary/case 均为 PASSEDcommit 为 5405e4145ee5207c3886a7829f12d23ba7d2d96d,5 项断言通过,耗时 25014 ms。证据目录 .build/acceptance/b01-5405e41-2ca9bd7756684abda1e3772bd13d2021/,报告标记 contains_credentials=false
  • 最终 desktop Rust 全目标 149 通过、15 ignoredlibrary 132、Host 10、其余集成 7),日志 .build/b01-rust-full.log;全目标 Clippy -D warnings 通过(.build/b01-clippy.log),B-01 driver 预检、runner 6 项测试、Python 编译与 Rust 格式检查通过。B-01 可记为通过;真实 OS 锁屏/口令与备份恢复属于 B-03,迁移强杀和旧库清除属于 B-04,仍未完成。

增量:D-01 扩展签名、归档边界与安全解包生产验收

  • D-01 driver 固定运行 8 个独立 exact Rust oracle。Python 生成的 Community Ed25519 固定向量在 Rust 中完成签名、archive SHA-256、大小和 manifest 验证;对签名覆盖的每个 metadata 字段(含 permissions)、归档字节、签名公钥、key ID、namespace、撤销与下架状态逐项篡改后全部拒绝。
  • 实际 loopback HTTP 信任源覆盖正常、密钥撤销、密钥轮换、发行下架、发行字段变化、重复发行、服务不可用和重定向 8 种响应,且已校验结果超过 30 秒不能复用。另以无 Content-Length 流覆盖正常、损坏、多 1 字节和重定向 4 种下载响应,防止声明长度绕过实际读取上限。
  • Theme 与 Plugin 分别验证压缩归档上限、解压后上限和条目数边界,边界值通过、增加 1 字节或 1 项即失败。恶意 ZIP 覆盖路径穿越、绝对/ADS/保留名、Unicode NFC 与大小写别名、文件/目录别名、重复 central entry、符号链接、加密标志、本地头不一致和内容损坏;签名后目录另验证额外、缺失、修改、hardlink 和 Windows junction 重定向,外部目录新增文件数为 0。
  • 提交 533cfe5 后在只保留用户 Vault 修改的工作树运行 python scripts/phase3-production-acceptance.py --suite extensions --case D-01 ...,退出 0summary/case 均为 PASSEDcommit 为 533cfe53265985fe3d382619e3d5a53b4646d5cc,6 项断言通过,耗时 9207 ms。证据目录 .build/acceptance/d01-533cfe5-35704f026ec94d0e98c76d0e52f96fb8/,报告标记 contains_credentials=false
  • D-01 登记前的最终 desktop Rust 全目标 149 通过、15 ignored.build/b01-rust-full.log),全目标 Clippy -D warnings 通过(.build/b01-clippy.log);driver 又逐项复跑 8 个 D-01 oraclerunner 6 项测试、Python 编译和 Markdown 链接检查通过。D-01 可记为通过;旧安装迁移、完整安装事务和真实样例生命周期属于 D-02~D-04,仍未完成。

增量:A-02 Sidecar 会话认证生产验收

  • 新增 300 次拒绝矩阵:缺失会话、错误会话和旧 generation 各请求 100 次,全部在最外层中间件返回固定 AUTH_REQUIRED,下游业务调用计数保持为 0。既有路由矩阵同时覆盖 health、普通 API、SSE、二进制、文档与未知路径,并验证重复 Authorization、浏览器 Origin 和错误 Host 均被拒绝。
  • 真实 Python Sidecar 每次测试生成随机 secret、challenge 和 generation,由父进程通过 stdin 引导,在随机回环端口完成 proof 校验;合法认证可访问 health,/docs/redoc/openapi.json 和 OAuth2 redirect 均为 404,关闭父进程管道后子进程在 10 秒内正常退出。测试扫描 argv、父环境、Sidecar stderr 和 Core 数据目录,随机会话材料命中为 0。
  • A-02 driver 还固定运行真实 Rust CoreSupervisor generation 轮换集成,以及 WebView 请求 DTO 的 camelCase/自带 Authorization 拒绝测试,确保会话材料由 Host 独占。提交 1269bf9 后在只保留用户 Vault 修改的工作树运行统一 runnersummary/case 均为 PASSEDcommit 为 1269bf97786a729942483304ce0cd229bf256470,5 项断言通过,耗时 12400 ms。证据目录 .build/acceptance/a02-1269bf9-5a197313d4b64aa49fb44ae5b3b60bcb/,报告标记 contains_credentials=false
  • 最终后端全套 915 通过、1 项依赖弃用警告(.build/a02-backend-full.log);A-02 driver 提交前预检通过(.build/a02-driver-precommit.log),两项 exact Rust 传输测试、runner 6 项自测与 Python 编译通过。本轮没有修改 Rust 生产代码,因此沿用提交祖先上已通过的全目标 Rust/Clippy 基线,并由正式 driver 重跑直接相关 Rust 边界。A-02 可记为通过;当时 A-01 的安装/启动、A-03 的协议/传输及 A-04 的崩溃/更新门禁仍未完成。

增量:A-03 Core 协议、传输与取消生产验收

  • 审计发现 Core stdout reader 原先会在 ready frame 通过验证前派发带 rpc 的 Host broker 请求,不兼容或被替换的 Core 存在握手前业务调用窗口。现增加双阶段激活门:reader 只转交首个 ready frame 并等待,Host 校验 protocol、launcher PID、generation 与 HMAC 后才允许 broker RPC;握手失败显式关闭门并由进程组清理子进程。
  • 新增真实不兼容子进程 oracle:子进程返回 protocol 2 后立即发送伪 workspace.write RPCHost 必须返回 PROTOCOL_INCOMPATIBLE,broker 调用计数保持 0。传输 oracle 使用生产校验函数验证 JSON 与 Base64 二进制请求恰好 67108864 字节通过、67108865 字节拒绝;真实 TCP 响应验证恰好 64 MiB 完整接收、声明超界在读正文前拒绝、声明 8 字节只发送 1 字节稳定返回 CORE_RESPONSE_ERRORSSE 累计计数也使用同一上界函数。
  • 取消链同时执行预留后取消且业务 future 从未被 poll、在途真实 HTTP socket 被取消关闭,以及前端请求和流的 9 项用例;后者覆盖 abort 早于 Host start 回执、reader 断流、未知结果语义和冻结 DTO。真实 Python Core/Host Workspace 集成与重开后的 100 次相同 operation replay 证明已提交结果仍可由 operation_id 查询且不重复写入。
  • 提交 e161d8c 后在只保留用户 Vault 修改的工作树运行统一 runnersummary/case 均为 PASSEDcommit 为 e161d8c5319e75d512bc00060cef07d7b271376e,6 项断言通过,耗时 17681 ms。证据目录 .build/acceptance/a03-e161d8c-07a281251b4044f2bc60c3f83f144010/,报告标记 contains_credentials=false
  • 最终 desktop Rust 全目标 151 通过、15 ignored.build/a03-rust-full.log);全目标 Clippy -D warnings 通过(.build/a03-clippy.log),driver 提交前预检通过(.build/a03-driver-precommit.log),runner 6 项自测与 Python 编译通过。A-03 可记为通过;A-01 的签名安装包/干净 VM/冷启动与 A-04 的连续崩溃、Host 子孙清理和更新中断矩阵仍未完成。

增量:S-03 冲突矩阵与绑定隔离生产验收

  • 审计发现不同文件在两台设备同时 rename 到同一目标时,冲突记录原先指向远端身份的旧路径,copy 会保存错误文件并丢失目标处的本地身份。现将目标占用文件冻结为冲突本地侧;解决时以独立、持久化的 retire/restore operation ID 先保存副本、移除占用、应用远端身份,再按服务器 head 恢复被挤占文件的原路径。schema 升至 12,11→12 会先生成可读 SQLite 备份;新增字段与未完成决策可在重启后继续。
  • 新增真实 Uvicorn 服务与两台 Rust 客户端的 100 轮矩阵:同改、改对删、改对 rename、不同文件改到同一目标、删除后历史恢复各 20 轮。每轮在冲突打开时核对本地和远端摘要对象均可恢复,选择保留副本后循环 push/pull 到空,随后逐端核对正文、hash、file_id、原路径删除状态与冲突清空;同目标 rename 还核对被挤占文件按服务器 head 恢复并在两端保持同一身份。
  • 同一真实服务用例验证带现有本地文件首次绑定空 Vault 时,提交前服务器 revision 为 0,提交后 delete revision 仍为 0。解绑前冻结旧 operation ID,重绑同一空远端后产生新 ID;旧 binding 明确返回 SYNC_BINDING_CHANGED,服务器最终仅出现新 ID。独立状态机 oracle 另以 20 轮轮换 local/remote/copy 并重开 Workspace,覆盖同目标 rename 的三种持久化选择。
  • 提交 a5e5122 后在只保留用户 Vault 修改的工作树运行统一 runnersummary/case 均为 PASSEDcommit 为 a5e512279c76886cde8d8c8b011a297570ab0dbd,8 项断言通过,耗时 33734 ms。证据目录 G:\OSProject\OpenNexus-acceptance\s03-a5e5122-535b10624f944f99a2febeebd0e9a296-report\,报告标记 contains_credentials=false
  • 最终 desktop Rust 全目标 154 通过、15 ignored.build/s03-rust-full.log),包括既有 S-01 与新增 S-03 的真实服务回归;全目标 Clippy -D warnings 通过(.build/s03-clippy-final.log),runner 6 项自测、Python 编译与 Rust 格式检查通过。S-03 可记为通过;分类 schema、PostgreSQL/MinIO 并发、鉴权/就绪、备份恢复与性能门分别属于 S-08、S-04~S-07/S-09,仍未完成。

增量:S-08 同步分类与逻辑记录兼容生产验收

  • 补齐对话、已结束 Agent 历史、一般 Provider 参数和安装清单四类严格逻辑记录,加上既有人设与布局形成六个默认关闭的独立范围开关。所有记录使用 opennexus-records/v1 白名单路径、schema 1 信封、32 位小写十六进制业务 ID 和逐层未知字段拒绝;运行中 Agent 状态不能编码,Provider 不能携带 credential_id,安装清单恰好只含包类型、ID、来源、版本和 SHA-256。
  • Workspace schema 升至 13。12→13 在事务迁移前生成完整可读 SQLite 备份,保留原 persona/layout 选择,新增四类全部初始化为关闭;绑定期间不能改变范围。上传捕获、外部扫描、初始对账、对象下载和提交前均复核范围,旧排除作业不能绕过选择。
  • 新增真实 Uvicorn Sync 服务与两台 Rust 客户端测试。默认范围只产生 6 个远端当前项并在空目标完整往返:Markdown、附件、任务、用户 Skill、主题和编辑器偏好;六类可选记录在未选择时远端 revision 为 0。日志、缓存、模型、索引、向量和普通 Provider JSON 均未出现在服务端。全部选择后 12 个默认及可选项完整落地,安装记录仍只有五个非授权字段。
  • schema 单测逐类注入 api_key/未知字段并拒绝;Provider 的 credential_id 和安装清单的 permissions、granted_permissions、enabled、trusted、device_grants、package_path 全部在 journal 前拒绝。远端 schema 2 写入返回 RECORD_SCHEMA_UNSUPPORTED,本地文件与待上传队列保持不变。
  • 提交 9729751 后在只保留用户 Vault 修改的工作树运行统一 runnersummary/case 均为 PASSEDcommit 为 97297519d7ac0c85d5edd111caa6bae44e744d70,8 项断言通过,耗时 9276 ms。证据目录 G:\OSProject\OpenNexus-acceptance\s08-9729751-8a9fa683692349029898835bbe10fff3-report\,报告标记 contains_credentials=false
  • 最终 desktop Rust 全目标 158 通过、15 ignored,包含既有 S-01/S-03 和新增 S-08 的真实服务回归;全目标 Clippy -D warnings 通过,前端 103 个测试文件共 536 项通过,runner 6 项自测、Python 编译、Rust 格式和 Markdown 链接检查通过。S-08 可记为通过;PostgreSQL/MinIO 并发、鉴权/就绪、备份恢复与性能门 S-04~S-07/S-09 仍未完成,整体生产化目标保持未完成。

增量:S-04 PostgreSQL/MinIO 双 Worker 并发生产验收

  • 新增 S-04 独立生产栈 driver,在隔离数据根启动官方 PostgreSQL 17.11、固定版本 MinIO RELEASE.2025-09-07T16-13-09Z 和生产入口的两个 Uvicorn worker。driver 校验运行时版本与 MinIO 二进制 SHA-256,生成仅用于本次运行的随机账号材料,并在结束时关闭整个进程树和 PostgreSQL,不复用开发数据库或对象桶。
  • 黑盒并发矩阵对同一 file_id、同一 base_revision=0 发起 100 个不同 operation/path:恰好 1 个提交返回 200,其余 99 个返回 409。对胜出 payload 和 idempotency key 再并发重放 100 次,全部返回原 sequence;同 key 改变 path 固定返回 IDEMPOTENCY_REUSED
  • 分页从 revision 100 建立 limit=7 的固定快照边界,分页过程中追加 revision 101;结果恰好覆盖 1100,无缺口和重复,新增 revision 不越过冻结边界。对象在上传完成后可读取,但在首次 revision 提交前同步边界仍为 0;未上传对象的提交固定返回 OBJECT_NOT_READY
  • 200 次关闭连接的健康请求观察到恰好两个随机 worker 标识,证明请求实际落到两个生产 worker;该标识只存在于临时响应头,不暴露主机名、PID 或凭据。Sync 服务全套 29 项通过、2 项依赖弃用警告,runner 6 项自测、Python 编译和源码差异检查通过。
  • 提交 37ea976 后在只保留用户 Vault 修改的工作树运行统一 runnersummary/case 均为 PASSEDcommit 为 37ea9765b3af3f4ee9e05eac4b24a6947a5ae76f,7 项断言通过,耗时 19885 ms。证据目录 H:\OpenNexus-acceptance\s04-37ea976-492072040df647e7be211c27b2c497ad-report\,报告标记 contains_credentials=false。S-04 可记为通过;上传竞态、鉴权/就绪、备份恢复、性能和运维门 S-05~S-07/S-09 仍未完成,整体生产化目标保持未完成。