Rust 性质测试与 TDD 验证契约

正文由仓库文档生成,保留原始规范状态和示例。RFC 草案及验证计划与当前实现可能有差异;已验证范围见实现记录,加密与用户隔离升级见 安全说明。

项目 值
状态 Approved execution plan:用户授权自行完成并免逐步 review
日期 2026-10-12
已确认基线 Rust 数据模型、核心 RFC、Dashboard RFC
本阶段输出 观察边界、独立模型、生成器、故障与反例、平台验证、TDD切片及验收口径

这是执行测试契约,用户已授权自行完成实现并免逐步 review。当前尚未创建测试或服务源码。P01–P18的规范定义以原性质计划为准;本文明确 Rust实施方法,并增加 Dashboard验证。按用户最新授权直接进入 Step 4。

1. 确认的观察边界

边界 真实观察入口 测试方式
公开领域服务 send、inbox、ACK、status、message/Blob/memory读取 Rust集成测试与 proptest命令历史
持久存储适配 相同公开操作,新实例读取实际字节 文件 SQLite与文件对象;D1/R2契约验证
传输 HTTP请求与真实 MCP协商、工具发现/调用 认证、schema、错误和跨入口重试
参考消费者 sync、待处理列表、处理确认与出站提交 本机 SQLite重启与故障历史
Dashboard 管理 HTTP接口与真实页面交互 集成测试、浏览器操作及内容检查
Skill与宿主适配 实际调用轨迹及回执报告 场景评测,区分引导与真实 Hook能力

通过公开读取和下载断言业务结果。直接 SQL只用于夹具、适配诊断和故障布置,不作为业务正确性的唯一旁路;不测试私有 helper调用次数。

2. 独立参考模型与生成

参考模型只保存身份/授权关系、请求对应的稳定结果、发布事实顺序、消费者声明及检查点、来源记忆的完整状态、封存字节。它可以使用简单映射和集合,不复刻生产 SQL或状态机实现。

公共 DTO与 ID类型可以共享;生产授权、游标编码、CAS、去重、JCS实现和分页 helper不能作为参考模型的判定函数。JCS使用 RFC 8785外部固定向量验证,包括 UTF-16属性排序、数组顺序、数字序列化和禁止重复对象键;不靠调用被测指纹函数重新计算期望。RFC 8785

proptest生成一段有界命令历史,测试驱动逐项调用真实公开操作并比较结果。采用符号角色、请求和资源引用,使反例缩减后不依赖偶然生成的生产 ID。非法引用仍作为输入执行,检查稳定错误与状态不变。

命令族 必须生成的维度
Send / Retry / Status 同键同内容、同键变异、默认收件、回复、跨入口、响应丢失
Read / Ack 页大小1和边界、稀疏可见项、迟到发布、重复/逆序阶段、不同视图
Prepare / Put / Seal 空内容、边界长度、摘要/类型不符、迟到 PUT、封存/清理竞争
Snapshot / Delta / ReadMemory 空快照、遗漏条目、删除不存在项、旧版本、无变化及固定版本分页
Rotate / Revoke / Disable 同权限换凭据、改变grants、等待发布时撤销、停用来源
Crash / Recover / AdvanceClock 关闭进程状态再打开实际数据库、有限存储故障、期限推进
AdminRead / Login / Logout 角色混用、会话到期、secret轮换、Inspector读取与分页

本地/CI先采用有界短历史,数量以执行开销调整。确定性回归始终运行,不依赖随机是否再次命中。失败保留 seed和缩减历史;公开提交反例仅包含合成夹具,不保存真实凭据或用户内容。proptest回归 seed文件进入版本控制,稳定反例另外变成具名用例,避免生成器变更后失去原场景。失败持久化文档

3. P01–P18到运行用例的映射

性质 主要随机历史 公开可观察断言
P01 隔离 多Space、同名身份、外部ID、越权Blob与Collection 不读取或改变未授权资源;错误遵循存在性隐藏规则
P02 幂等 多次同键、内容等价变换、响应丢失和重启 一个资源和一次发布,稳定ID/时间/版本;当前授权有效
P03 内容冲突 改正文、收件人、附件、版本参数后复用键 IDEMPOTENCY_CONFLICT;原结果及Feed不变
P04 可恢复 committed后关闭全部服务实例再打开 原正文、附件与稳定提交结果真实可读
P05 未发布不可见 对象成功后阻断元数据提交 Feed和业务读取无该资源,恢复后恰一次发布
P06 晚提交 A先保留,B先发布,读B后完成A A序号晚于B,下一次增量读得到A
P07 消费独立 两Consumer分别ACK、停用、重启 A的状态不改变B的进度或原内容
P08 回执单调 processed先到、received迟到、多次重试、确认receipt项 阶段不回退;无重复推进事件或确认循环
P09 游标 多页、权限/过滤改变、篡改、同权限轮换 稳定视图完整有序;跨范围拒绝;新视图可重新补收
P10 CAS 同基础版本准备两个更新,交错完成 最多一次前进;失败无版本/Feed;原成功键仍回原版本
P11 模式含义 完整替换、局部更新、空快照、无变化 Snapshot等于完整输入;Delta保留遗漏;无变化不增版本
P12 删除来源 不同Collection复用ID,删除、旧同步、明确恢复 来源隔离;旧更新拒绝;历史Tombstone可读
P13 封存 错摘要、未封存引用、迟到PUT和清理竞争 发布的全部资料完整且字节不变,整批失败无半份内容
P14 轮换撤销 上传/准备间换凭据或撤销,旧键查询 同权限连续性;旧凭据无法读取原结果或完成发布
P15 通知独立 可选Webhook实现后才生成重投与到期历史 核心进度不受通知影响;未实现时capability为false
P16 入口一致 HTTP→MCP及MCP→HTTP重试,合法/非法输入 解包后的领域结果一致,仍为同一幂等操作
P17 本机队列 下载、本机提交、ACK、处理之间逐点重启 已收取输入仍有待处理记录;未保存不推进服务检查点
P18 最终补收 有限故障后停止写入、恢复原请求并完整分页 在有效授权、保留与公平重试条件下覆盖全部可见提交

HTTP/MCP响应的传输封装与只读跟踪ID可以不同;比较领域错误、状态与资源身份。MCP必须正确标记工具失败,不把JSON-RPC协议错误硬映射成业务成功。

4. 必须保留的确定性反例

反例 期待行为
A先保留、B先发布、读B、再完成A 后续页仍收到A
第二个记忆CAS实际命中0行 原请求记录冲突,但无新版本、head推进或Feed
无变化判定后另一请求前进head 旧expected_revision不能取得无变化成功
成功请求重试时head已经前进 先查原幂等结果,仍返回原revision
两个Consumer读取同一项,只确认其中一个 另一Consumer进度独立
processed先到再received 保持processed且无额外推进事件
ACK提交成功但响应丢失 原键重试无第二次回执变化
token轮换与准备期间撤销 新同权限凭据可恢复;已撤销凭据不能发布
空snapshot及迟到旧delta 清空有明确Tombstone,旧同步不能自动恢复
memory第一页后head改变 后续页仍属于第一页绑定的版本
零字节Blob、重复未封存PUT、封存后迟到PUT 校验真实空摘要;同内容不覆盖;封存后拒绝
view/grants变化后旧checkpoint更大 新视图从起点补收,不被旧进度拦住
语义相同JSON键/收件顺序改变 同一提交;附件顺序改变仍按有序列表语义处理
重复JSON键、未知请求字段、路径越界、超部署限额 整批拒绝,无隐式截断或发布副作用

故障通过真实外部存储/网络边界的可控包装器在操作前后注入。测试可以丢弃已成功响应;Crash丢失服务内存并重新建立实例,保留已确认耐久写入。CAS失败用实际被推进的Collection造成,不让mock冒充0行正确性。

多请求交错在单线程测试执行器中可控重放;这不要求生产增加线程池。另验证相同真实数据库上的多个服务实例。数据库全局物理丢失与无限断网不在已确认性质前置条件内。

5. Dashboard性质 D01–D09

ID 操作/生成 永远满足的观察结果
D01 管理身份隔离 普通Agent凭据、缺失Cookie、其他身份调用管理路由 无管理内容或状态变更;只接受有效实例管理员
D02 会话生命周期 登录、退出、期限推进、secret轮换,写操作改变Origin 过期/撤销/旧secret会话失效;跨来源Cookie写入被拒绝
D03 事实与筛选 多Space/Actor及不同消息、版本、回执,随机过滤分页 管理视图对应所选范围的真实事实,时间不表示在线状态
D04 阶段准确 committed、received、processed及重复/逆序回执 页面与接口呈现真实阶段,不宣称外部任务已经成功
D05 固定版本检查 指定两个revision,分页间更新head 展示与结构差异始终属于选定版本
D06 查看无消费副作用 登录后访问概览、消息、活动、版本和对比 Consumer回执、检查点和待处理状态不被查看推进
D07 凭据输出受限 生成、导航、重新列表、导出与日志检查 原token仅首次发放时显示;后续数据、静态HTML和日志不泄露
D08 内容仅作数据 HTML/脚本、Markdown链接、恶意文件名及metadata Inspector不执行正文脚本或权限指令,管理状态不变
D09 管理创建幂等 同管理request_id重试、丢响应、同键内容变异 一次创建、同结果;冲突不产生另一个身份或凭据

D01/D02/D05/D06/D09主要通过管理HTTP与公开数据面交叉观察;D04/D07/D08补真实浏览器交互。页面断言依据可见内容和实际状态,不断言CSS类名或组件私有结构。浏览器失败保存截图与操作轨迹,不以截图单独证明权限或持久性。Playwright断言

6. 原生与Cloudflare适配验证

适配 必查契约 结果口径
文件SQLite 原子发布、CAS、外键隔离、重启、回执及checkpoint 实际文件数据库通过,不能用内存实现替代
文件对象 create-only、真实字节校验、封存、文件与目录耐久写入 新实例下载原字节
本地Worker模拟 Wasm构建、MCP/HTTP路由、bindings及D1/R2执行路径 单独标注模拟验证
真正D1/R2 batch guard、0行CAS、条件put结果、checksum、授权撤销 单独标注真实平台验证
平台限额 查询/参数预算、请求大小、集合条数、CPU/内存 describe只公布实际可支持值

Cloudflare验证使用隔离的测试资源和合成数据。没有真实平台运行结果时,必须明确“未验证”,不能把模拟结果写成生产适配通过。真实资源配置在实现产生可运行产物后处理;本阶段不部署。

7. Nowledge Mem借鉴的接入与携带验证

研究笔记给出一手依据与借鉴边界。首版采用以下行为,保留已有身份和schema:

  • 无真实生命周期hook时标为guided/manual;MCP可调用不代表私有对话自动导出,摘要不能称完整备份。
  • 接入例子用真实request/resource ID验收:describe→send→status→新Consumer收取→下载原文→本机保存→ACK;记忆按返回revision和item_id回读。
  • 来源缺失不猜测;metadata中runtime/verified声明不改变认证发布者和grants。
  • 固定revision导出带明确范围、路径与摘要,排除凭据;单Collection资料包不称完整实例备份。
  • Dashboard区分当前active条目、Tombstone和历史版本,查看不ACK;相同名称和宿主不合并Actor身份。

这些场景分别扩展P01/P02/P04/P09/P11/P16/P17及D03–D07。知识图谱、语义检索、Working Memory生成、专用hook及OKF exporter留作独立范围,不把它们强加到核心服务。

8. Step 4的TDD切片顺序

每次先写一个公开行为失败用例,再写最少实现使其通过,随后增加该切片的性质与恢复场景。不会先写全部想象中的测试再一次实现全部服务。

  1. 验证Rust原生/Wasm运行目标、最小认证控制面与MCP describe/工具发现路径。
  2. 形成真实SQLite与不可变正文支持的投递→查询→收取闭环,验证幂等、隔离和恢复。
  3. 加入独立Consumer、回执、checkpoint与回信,保留晚发布反例。
  4. 加入实际字节上传、create-only和封存、授权下载。
  5. 加入记忆Snapshot/Delta、CAS、历史版本、Tombstone与完整导出。
  6. 完成11个必需MCP/HTTP操作的同语义验证。
  7. 加入参考消费者SQLite待处理/出站队列,以及真实Skill调用场景。
  8. 加入Dashboard管理会话、具名读取、Inspector与身份/凭据管理页面。
  9. 运行真实Cloudflare适配契约,测量并固定部署限额。

原生测试使用cargo test与proptest;Wasm构建、传输互操作及浏览器检查分别记录。依赖与构建版本在Step 4根据官方支持固定,不在本阶段生成占位crate或CI。

9. 验收与执行授权

  • 必需的P01–P14、P16–P18与D01–D09均有运行用例和可复现反例机制。
  • P15随可选事件适配实施,未实现时明确capability=false,不声称该性质已通过。
  • 服务、参考消费者、Skill、页面、模拟平台和真实平台结果分别报告。
  • 接入说明与Skill不得把工具可用说成宿主已自动保存、定时运行或获准执行外部动作。
  • 当前没有已通过的服务测试声明;按用户最新授权直接依上述切片开始实现。
← 返回 RFC 索引