附录 D:符合性测试矩阵

本附录把“符合性”限定为可复现的输入、规则执行和证据判断,而不是把某次线上服务成功访问视为完整证明。测试执行器应记录测试套件版本、fixture 版本、被测实现版本、配置摘要、运行时间、环境类型和脱敏后的输出;每个用例必须产生稳定的用例编号、PASSFAIL 结论、实际错误原因和可定位的证据文件。对于拒绝类用例,合格条件不仅是请求失败,还包括拒绝发生在正确的边界、没有写入不应产生的发布或索引状态,并且错误码或错误原因符合约定。当前可直接复现的离线测评以 oan-third-party-node-admission-test-kit/fixtures/v1-alpha 为主;其中 case-matrix.mdrequirements-traceability-matrix.md 明确了固定 fixture、预期输出和 49 项要求检查。该套件验证的是测评包和协议判断材料,不自动等同于对官方线上 Root、链、内容分发平台或链下信任索引器的端到端证明。

统一的测试记录至少包含以下字段:

字段 记录要求
用例标识 使用 manifest 中稳定的 case ID,不以测试文件的临时行号作为唯一标识。
前置条件 记录 fixture、协议版本、授权域集合、治理快照、模拟响应和必要的服务状态。
操作与输入 记录被调用的接口、HTTP 方法、请求体摘要、查询条件、签名或哈希输入;私钥、令牌和数据库连接串必须脱敏。
实际结果 记录状态码、规范化结果、错误码、生命周期、版本、游标和必要的响应摘要。
合格判据 将实际结果与 expected fixture 的 outcomereasonCode 及规范条款逐项比对。
证据产物 保存 JSON 报告、Markdown 报告、输入与期望 fixture 的引用、版本和脱敏规则。

测试失败的处理分为三类:阻止发布的协议或安全失败、阻止节点接入的身份或授权失败、以及不阻止发布但必须告警和留痕的运维或新鲜度失败。测试套件不应为了得到“通过”而静默重试、自动修正输入或忽略未知字段;如果实现具有明确的兼容模式,应在报告中单独标出。对于并未被当前 V1-alpha fixture 覆盖的链上事件、真实内容分发和跨节点网络时序,应标注为未覆盖,而不是从离线通过结果推导出已覆盖。

用例执行结果应把“测试结果为通过”和“被测对象接受输入”区分开来。对一个预期拒绝的输入,服务返回拒绝是被测对象的正确行为,因此测试用例本身应记录为 PASS,而不是把业务拒绝直接统计为失败。报告中的最小记录可以采用如下结构:

{
  "caseId": "fixture.registrar.rejects-did-mismatch",
  "expectedOutcome": "invalid",
  "actualOutcome": "invalid",
  "verdict": "PASS",
  "reasonCode": "DID_ID_MISMATCH",
  "sideEffect": "no_resource_record_written",
  "evidence": ["evidence/fixture.registrar.rejects-did-mismatch.json"]
}

expectedOutcome 描述夹具预期,actualOutcome 描述实现实际判断,verdict 描述测试是否通过;三者不能合并成一个含义不清的 status 字段。写入型测试还应在请求前后比较资源记录、发布队列和索引条目数量,证明拒绝没有产生后续副作用。

不同测试层级使用不同的结论范围:离线夹具检查规则和报告生成,节点集成测试检查 HTTP 路由、持久化和节点间调用,端到端测试检查发布、分发、发现和治理状态的传播。报告应记录层级,而不能把离线规则检查、服务健康检查和完整业务验收合并成一个“系统通过”结论。

D.1 资源注册测试

注册测试以 agent_serviceskillmcp_servertool_api 四类资源作为首要覆盖对象。正向样例应同时满足 resourceDid、DID文档 id、DID文档元数据、资源包元数据、VC 主体和哈希字段的一致性,并具有可验证的主体控制证明、资源类型和授权域。Registrar 接口层测试应覆盖 /resources/register 及其兼容入口 /resources/submit,验证形状校验、授权域校验、向根平台提交以及返回注册凭证和根平台响应的边界。负向样例应逐项替换一个事实,例如 DID 不一致、VC 主体不一致、包哈希不一致、缺少 packageProof、缺少凭证证明、控制挑战不一致、元数据不完整或资源处于暂停状态,避免一个 fixture 同时含有多个无法区分的错误。

测试项 前置数据与步骤 合格与拒绝判据 证据及影响
最小正向注册 加载 registrar-resource.valid.json,向测试 Registrar 提交固定资源包。 接受,资源类型、DID、VC、授权域和哈希全部绑定;返回结果不得声称超出实际发布阶段。 请求摘要、响应摘要、资源记录和 expected fixture;通过后允许进入后续发布测试。
字段与类型一致性 分别使用 did-mismatchcredential-subject-mismatchmetadata-incomplete 拒绝并返回稳定原因;不得写入可被发现节点读取的有效资源记录。 错误响应和存储前后对照;失败阻止注册发布。
证明与哈希绑定 使用 tampered-proofcredential-hash-mismatchpackage-hash-mismatch、缺少证明 fixture。 拒绝;验证必须覆盖证明主体、签发者、DID文档哈希、元数据哈希和包哈希。 验证路径和脱敏证明摘要;失败阻止发布。
重复提交与更新 以同一 DID 和版本重复提交,再以控制方签名递增版本提交。 重复提交不得产生两个冲突的当前版本;更新必须通过控制权和版本规则;历史与当前版本的含义可区分。 两次响应、资源记录、版本列表和重试日志;异常重复写入阻止发布。

当前固定 fixture 直接覆盖正向注册和多种拒绝条件;真实 Registrar 的数据库幂等性、并发写入和同 DID 更新传播还需在运行服务场景中补充执行,并在报告中标记为 live integration coverage,而不能用离线 fixture 代替。

四类资源应采用同一组绑定检查、分别使用各自合法的 resourceType 和 DID 语义码。测试数据可以按下表组织,便于复用同一断言而不把某一类资源的字段误套到另一类资源:

资源类型 DID 主体码示例 最小业务材料 重点断言
智能体服务 AG DID 文档、服务端点、能力标签 服务端点和资源类型与 DID 文档一致
技能包 SK DID 文档、包信息、下载或清单地址 包哈希、版本和资源元数据一致
MCP 服务 MC DID 文档、MCP 服务端点、协议绑定 协议绑定和端点引用一致
工具 API TL DID 文档、API 端点、输入输出描述 工具/API 类型和接口描述一致

同一个负向用例只改变一个被测事实,例如只替换 DID 文档 id,而保持 VC、哈希、授权域和生命周期不变。这样可以把失败原因准确回指到对应条款,也能防止服务因为另一个更早的校验失败而掩盖目标缺陷。

D.2 根平台发布测试

根平台发布测试应把 Registrar 的受理与根平台的接受、验证和发布分开。输入包含注册服务节点身份材料、资源 DID文档、资源包、注册凭证、主体控制证明、版本和哈希;根平台先验证节点授权和请求签名,再验证资源绑定,只有全部通过后才形成根平台可信发布证明和可供分发的发布事实。测试应检查失败时不存在“先发布后校验”的中间状态,也不存在只凭 Registrar 返回成功就可被发现节点接受的路径。对于重复投递,重处理应保持幂等:相同发布事实不生成冲突版本,内容或证明发生变化时必须按版本和控制权规则重新判断。

当前第三方接入测试套件没有把 Root、链和真实发布队列纳入 V1-alpha 评估范围,因此本节的离线部分只能验证发布输入材料和 expected 规则,不能宣称完成真实根平台发布覆盖。运行服务时应补充记录根平台接口响应、发布作业标识、资源版本、根平台可信发布证明摘要、拒绝原因和重处理结果;任何包含私有治理材料的日志均不得进入公开报告。

根平台发布测试的关键断言是“先验证、后产生可传播发布事实”。可按以下顺序执行:

  1. 准备已授权注册服务节点的身份材料,以及一个资源注册提交。
  2. 分别篡改节点间签名、资源控制证明、DID 文档哈希、资源包哈希和授权域,逐个调用 POST /root/resources/verify-and-publish
  3. 检查每次拒绝的 HTTP 结果、机器可读错误、资源版本、发布队列和根平台可信发布证明。
  4. 对原始有效请求重复发送,确认重复发布不会生成冲突的当前版本。

其中第3步的存储和队列对照是必要证据;只保存 HTTP 响应不能证明根平台没有在失败请求中留下部分发布状态。

D.3 分发与同步测试

分发测试围绕“发布事实可验证地到达授权节点”展开。应先用全量同步建立基线,再以游标执行增量同步,并分别注入重复事件、乱序事件、缺失事件、断点恢复和内容哈希错误。接收节点不能仅按到达时间覆盖数据,而应按资源 DID、版本、发布证明和游标规则判断是否接受;缺失或哈希错误的材料应保持待处理或失败状态,不能进入可见索引。恢复测试需记录最后成功游标、重试次数、退避结果和最终收敛状态,区分“传输完成”“本地验证完成”和“发现可见”。内容分发平台的缓存命中或 HTTP 成功只能证明传输层结果,不能替代接收方对根平台可信发布证明的验证。

本节与当前 V1-alpha fixture 的边界应明确写入报告:现有测试套件验证授权域、资源可见性、来源和固定证据规则,但其 manifest 明确不包含真实 CDN、Root 队列和链上同步。实现接入完整分发测试后,应使用可重复的资源版本和人为构造的游标,保存发送端、接收端、验证端和索引端四类证据;任何一次失败若可能导致旧版本重新可见、撤销状态丢失或未经验证的资源进入索引,应作为发布阻断问题。

分发测试至少要验证游标推进与资源接受是两个相关但不同的结果:接收节点可以成功读取一页数据,但其中某个资源因证明或哈希错误被拒绝;此时游标是否推进、失败条目是否进入重试队列,必须按接口和实现的既定规则记录。重复发送相同发布事实时,结果应可安全重放;发送不同内容但复用同一资源 DID 和版本时,应进入冲突处理路径,不能静默覆盖已接受内容。

{
  "afterCursor": 1800,
  "nextCursor": 1812,
  "hasMore": true,
  "accepted": 11,
  "rejected": 1,
  "rejectedReasons": ["invalid_root_proof"]
}

上例是测试报告中的结果摘要示意,字段应以实际内容分发接口返回结构为准;nextCursor 前进不等于所有条目都已验证接受,报告必须同时保存被拒条目的 DID 和原因。

D.4 发现与语义搜索测试

发现测试应覆盖 /discovery/resources/query 的精确 DID 查询、资源类型、协议、能力标签、授权域和生命周期过滤,以及自然语言查询和查询解释接口(若该实现启用)。测试输入先经过语法、范围和授权域检查,再转换为结构化条件、标签条件或语义检索条件;结果必须保留资源 DID、版本、来源、治理状态和必要的证明摘要。相关性分数、关键词命中、标签匹配和语义相似度只能用于排序或解释,不能绕过授权域、暂停/撤销过滤、DID文档校验和根平台可信发布证明检查。

查询类别 代表输入 必须验证的行为
DID 精确查询 固定资源 DID 或不存在的 DID。 命中唯一资源或返回稳定空结果;不得因文本相似返回其它资源。
结构化组合查询 resourceTypeprotocolcapabilityTagslimit 和授权域组合。 字段按协议规则解析,非法枚举、负数或超限被拒绝,分页不重复、不遗漏已接受结果。
语义查询 例如 Find an MCP server for security audit 查询文本转为可解释的候选条件;返回结果需标明语义/标签/文本等来源,不能把相似度当作信任证明。
可见性边界 域内、域外、暂停、撤销、协议不匹配和类型不匹配资源。 仅返回授权域内且状态可用的资源;空结果是合法结果,不得用推荐项填充。
去重与解释 同一 DID 的多版本、重复索引记录和 explain 请求。 依据 DID 与版本规则去重,能说明候选来源和过滤原因。

fixtures/v1-alpha/discovery 已提供可见性、空结果、任意标签匹配、非法过滤、非法标签、非法资源类型、非法协议、limit 边界和过短查询等固定用例;这些用例应作为回归基线。语义模型、向量库和自然语言排序的具体质量不应由固定规则 fixture 推断,需另行记录模型版本、索引构建时间和解释结果。

发现结果测试应把候选生成、过滤、排序和证明检查分别记录。一个资源即使在文本或能力标签上高度匹配,只要授权域不覆盖、生命周期不可用、DID 文档与资源包不一致或根平台可信发布证明无效,就不能出现在可调用结果中。反过来,空结果不表示发现服务异常,只有在存在满足全部过滤条件的有效资源而响应仍为空时,才构成召回或索引缺陷。

测试阶段 观察值 合格条件
输入解析 查询文本、DID、资源类型、标签、协议和 limit 合法输入进入对应检索路径,非法输入受控失败
候选生成 候选 DID、匹配来源和原始分数 候选来自本地已索引数据,不凭空生成资源
治理过滤 授权域、生命周期和发布证明状态 不满足边界的候选被排除
结果输出 DID、版本、来源、状态和证明摘要 排序不改变信任结论,结果可复核

D.5 治理授权测试

治理测试必须把节点授权、资源控制权和资源发布结果作为三个独立判断。节点 DID 文档、授权凭证、授权域、协议版本和生命周期状态一致时,节点才可执行其角色允许的动作;资源拥有者的控制证明只说明资源操作权,不能替代节点授权。测试应分别使用 active、suspended、revoked、未知和非规范大小写状态,验证敏感操作在状态不能确认或状态已失效时采取拒绝或 fail-closed 行为。对于授权域,应覆盖空集合、通配符、父子域、兄弟域、重复、大小写和未知域,确认标签树或资源描述不会扩大节点授权范围。

governancenodedomainslifecycle fixture 已为离线判断提供稳定输入;治理快照中的来源、事件序列或投影时间必须与测试报告一同保存。链下信任索引器的投影延迟、链上最终性和真实撤销传播属于运行集成范围,不能仅凭快照测试宣称完成。

治理授权测试宜采用“授权事实 -> 节点动作 -> 资源可见性”的闭环断言。对于一个被撤销的发现服务节点,测试不只验证授权快照状态为 revoked,还要验证其同步或查询动作被拒绝、既有授权范围不会继续扩大,并且已经索引的资源不会因旧缓存重新变成有效结果。对于授权域变更,应同时检查新域和旧域,避免只验证新增域而遗漏旧域权限是否被正确收回。

D.6 版本更新与生命周期测试

生命周期测试以状态转换和版本关系为中心,而非以时间戳先后作为唯一依据。测试应建立一个 active 资源,使用原控制方的有效证明发布新版本,再验证当前版本、历史版本和同 DID 查询的返回关系;随后分别施加暂停、撤销和恢复事实,检查 Registrar、Root、内容分发平台、发现服务节点和调用方看到的状态是否按允许的传播边界变化。未经控制方授权的更新、版本回退、同版本内容冲突和恢复无依据都应拒绝。发现查询默认只返回可用当前版本,若接口支持历史查询,则必须明确历史记录的状态,不能让旧版本绕过当前治理状态重新成为可调用资源。

现有 lifecycle fixture 可以验证状态值的规范性和 active/inactive 语义;同 DID 更新、真实历史持久化和跨节点收敛则应使用服务集成测试,并保留每次提交的 DID 文档哈希、资源包哈希、版本、控制证明、发布证明和索引时间。

同 DID 更新的测试记录至少包含以下关系:

same resource DID
  -> controller proof for the update
  -> strictly selected package version
  -> new DID document/package hashes
  -> Root publication evidence
  -> Discovery current-version result

若只更新描述或端点,也必须重新计算受影响的 DID 文档哈希、元数据哈希或资源包哈希,并验证相应证明;不能用版本号递增替代内容绑定。历史查询测试还应确认历史版本可追溯但不会绕过当前暂停、撤销或授权状态。

D.7 安全与滥用防护测试

安全测试应验证“拒绝且无副作用”。固定签名样例用于确认有效 Ed25519 签名可验证、篡改后的同一载荷不能通过;在服务级测试中还应替换请求 nonce、request ID、受众、路径、协议版本和签名者,检查重放、跨接口转用和越权调用。请求大小、查询 limit、文本长度、非法 JSON、错误 Content-Type、恶意端点和异常授权域应在进入昂贵的语义检索、网络请求或持久化前被限制。限流和超时测试应记录响应状态、等待时间、资源占用和恢复情况,不能用无限重试掩盖拒绝。

敏感证据测试应确保私钥、访问令牌、数据库连接串、内部文件路径和未脱敏的控制材料不会进入报告、网站公开接口或普通节点响应。security/sensitive-evidence.json 与报告脱敏检查是当前可复现的基线;真实服务还应抽样查看应用日志、反向代理日志和错误响应,确认异常分支没有泄露内部堆栈或秘密。

安全测试的副作用检查应覆盖三个位置:请求处理前的输入缓冲或临时文件、服务端持久化记录、下游发布或索引队列。对超大请求、恶意端点和无效签名,合格结果应包括请求被限制、无资源记录写入、无节点间发布调用和无公开错误堆栈。对限流测试,应区分“服务拒绝请求”和“服务进程不可用”:前者是策略结果,后者才是稳定性缺陷。

D.8 第三方节点接入测试

第三方节点测试从节点身份一致性开始,要求配置、DID文档、状态响应、授权凭证、角色、端点、协议版本、生命周期和授权域之间没有矛盾。接入后分别验证注册服务节点能否按授权域受理并向根平台提交,发现服务节点能否只同步和查询授权范围内的根平台发布内容;还要验证无效节点、域外资源、协议版本不一致和撤销状态不会因配置缓存或历史凭证继续获得权限。日志和故障恢复测试应检查请求 ID、游标、拒绝原因和重试记录足以重建事件,但不包含私钥和内部秘密。

当前套件的 node-identity.*、授权域、治理快照和发现可见性 fixture 适合作为第三方接入的离线准入门槛。真实节点接入还必须用隔离端点和独立数据库进行,不得把测试节点直接接入官方生产数据面;报告应注明被测节点、授权域、配置版本和撤销/恢复时间。

第三方节点的接入结论应拆成身份、协议、授权、业务和运维五个观察面。只有身份材料一致,说明“节点是谁”;只有协议调用成功,说明“接口能否通信”;只有授权和业务闭环通过,才说明“节点能否在授权范围内完成注册、同步或发现”;日志、限流和恢复证据则用于判断节点是否具备可持续运行条件。任何一个观察面失败,都应在报告中保留具体失败原因,而不能用其它面通过进行抵消。

D.9 DID 解析与方法符合性测试

解析测试应验证 did:oan 的方法前缀、语义代码、主体类型映射、标识符字符集和规范化规则;不能把大小写修正、字符串可解析或服务端返回 JSON 当作控制权证明。DID文档测试需检查 id、控制者、公钥、认证/断言引用、服务端点、资源类型和资源元数据的一致性,并对错误方法、错误段数、非法字符、未知主体代码和错误服务引用给出确定性失败。若实现提供历史版本解析,应同时记录解析所依据的版本、哈希和状态,区分当前解析结果与历史记录。

测试证据应包含规范化前后的标识符、解析字段、验证方法和错误原因;私钥仅用于测试运行时签名,不得写入 fixture 报告。

方法符合性测试还应区分语法层、结构层和控制权层:语法层确认字符串符合 did:oan 形式,结构层确认 DID 文档中的 id、验证方法和服务引用相互一致,控制权层则需要使用对应私钥生成证明并由公钥验证。仅通过前两层,不能得出资源由某个主体控制的结论。测试向量中使用的固定后缀可以复现解析结果,但不应被解释为生产环境的密钥派生结果。

D.10 API 兼容性与错误契约测试

API 测试应同时检查成功契约和失败契约。每个接口至少记录方法、路径、Content-Type、必填字段、未知字段处理、状态码、错误体结构、错误原因、分页字段和重试建议;客户端不得把任意 2xx 都当作业务成功,也不得把网络超时自动解释成资源被拒绝。对兼容版本,测试应区分可忽略的扩展字段、必须拒绝的协议版本和不能改变语义的字段顺序或 JSON 表示差异。重试仅适用于明确可重试的传输或临时依赖失败,带有签名和写入副作用的请求必须依靠 request ID、nonce 或服务端幂等规则防止重复提交。

oan-protocol-common/docs/error-codes.md、协议类型和测试套件中的 requests fixture 是错误契约的主要核对来源。当前 fixture 已覆盖空请求体、非法方法、格式错误 JSON、缺失字段、过大请求、错误 Content-Type 和错误查询类型;各服务新增错误码时应同步更新公共错误文档、客户端映射和 expected fixture。

兼容性测试应把请求发送结果和业务语义结果分别断言。例如,未知可忽略字段不应改变既有字段的含义;未知协议版本应产生明确的不兼容结果;缺失必填字段应在业务写入前失败;网络超时则只能记录为传输结果未知,不能直接判定资源没有注册成功。对具有写入副作用的接口,重试测试必须使用固定 requestId、nonce 或等价幂等条件,并检查服务端是否生成重复 VC、重复版本或重复发布任务。

场景 预期测试结论 需要保存的证据
合法请求与已知版本 业务处理成功 状态码、响应摘要和资源状态
增加未知扩展字段 按接口兼容规则处理 原始请求与字段处理结果
缺少必填字段 受控拒绝且无写入副作用 错误码和存储前后计数
网络超时后重试 不产生重复业务事实 两次请求标识、响应和最终记录

D.11 新鲜度、收敛与恢复测试

新鲜度测试应把观测时间、事实产生时间、同步游标、索引更新时间和允许的最大延迟分开记录。测试流程可先发布一个带唯一版本和哈希的资源,确认根平台接受,再观察内容分发平台、发现服务节点和链下信任索引器的状态,最后比较各层是否收敛到相同的 DID、版本、状态和证明。人为中断网络、重启服务、删除临时传输状态或注入重复事件后,恢复过程必须从可验证的游标或全量重建继续,不能凭“最新一条响应”猜测缺失事实。旧快照可以用于非权威展示或有限降级,但在授权、撤销和新发布判断中必须遵守明确的新鲜度边界。

报告至少应列出各层的 observedAtsourcecursorversionlifecycleState、验证结果和延迟;对于超出阈值的结果,标注是阻止敏感操作、降级为只读,还是仅产生运维告警。当前 V1-alpha 套件并不提供完整的真实网络收敛测评,因此这部分应与 Root、CDN、发现服务节点和链下信任索引器的集成报告分开发布。

收敛测试应使用一个可追踪的资源版本作为关联键,而不是只比较各接口返回的资源数量。建议在报告中保留如下最小证据链:

{
  "resourceDid": "did:oan:SKFI:7YpQm9Kx2VnRb6Ts3WfHa4Cd5Ej8LgNz",
  "version": "1.0.1",
  "rootPublishedAt": "2026-09-07T01:02:03Z",
  "cdnObservedAt": "2026-09-07T01:02:05Z",
  "discoveryObservedAt": "2026-09-07T01:02:07Z",
  "trustIndexObservedAt": "2026-09-07T01:02:08Z",
  "didDocumentHash": "sha256:example",
  "packageHash": "sha256:example",
  "converged": true
}

示例中的时间、DID 和摘要仅用于说明报告字段。实际验收应依据测试环境设定的阈值判断 converged,同时保留各层原始响应、日志关联标识和游标,才能区分传播延迟、索引失败、治理状态滞后和版本绑定错误。

参考来源

来源 类型 链接
oan-protocol-common 代码仓:测试数据结构、schema 和错误契约 https://github.com/wolfbrother/oan-protocol-common
oan-root-services 代码仓:根平台验证和发布测试对象 https://github.com/OpenAgenet/oan-root-services
oan-registrar-node 代码仓:注册协议和校验测试对象 https://github.com/OpenAgenet/oan-registrar-node
oan-discovery-node 代码仓:发现、索引和语义查询测试对象 https://github.com/OpenAgenet/oan-discovery-node
oan-trust-indexer 代码仓:治理状态和同步测试对象 https://github.com/OpenAgenet/oan-trust-indexer
OAN Yellow Paper arXiv 黄皮书:安全性质和验证要求 https://arxiv.org/abs/2606.03163
Efficient Agent Discovery Profile IETF 草案:发现 profile 的测试方向 https://datatracker.ietf.org/doc/draft-xu-efficient-agent-discovery-profile/
On this page