BLUEPRINT
第十二章:正確性保證
12.1 概述
協定透過形式化的正確性屬性(Correctness Properties)定義系統應滿足的不變量。這些屬性是人類可讀規範與機器可驗證正確性保證之間的橋樑,透過屬性測試(Property-Based Testing)進行驗證。
12.2 正確性屬性列表
屬性 1:技能描述符結構完整性
對於任意有效的 SkillDescriptor 物件,它必須包含所有必要欄位:protocol(含 version)、id、name、version、capability_type、description、provider、endpoint、inputs、output、auth、access。缺少任何必要欄位的物件不應通過驗證。
屬性 2:列舉欄位值域約束
對於任意有效的 SkillDescriptor 物件:
capability_type的值必須是["plugin", "api", "knowledge", "task"]之一access的值必須是["public", "restricted", "private"]之一auth.type的值必須是["api_key", "oauth2", "custom", "none"]之一
屬性 3:序列化/解析往返一致性
對於任意有效的 SkillDescriptor 物件,將其序列化為 JSON 文件後再解析回物件,所得結果應與原始物件語意等價:
parse(serialize(descriptor)) == descriptor
屬性 4:Schema 驗證正確性
- 對於任意符合 Schema 的 JSON 文件,Schema Validator 應成功解析並回傳結構化物件
- 對於任意不符合 Schema 的 JSON 文件,Schema Validator 應回傳包含具體違規欄位名稱和錯誤原因的錯誤資訊
屬性 5:技能識別碼唯一性
對於任意技能索引中的技能描述符集合,所有技能的 id 欄位值必須互不相同。
屬性 6:技能索引正確性與存取控制
對於任意包含 N 個技能的提供者域,當未認證請求存取 Well-Known URI 時:
- 回傳的技能索引應包含所有
access不為"private"的技能 - 不包含任何
access為"private"的技能 - 索引中每個條目的
descriptor_url應指向有效的技能描述符
屬性 7:能力類型篩選正確性
對於任意技能集合和任意 CapabilityType 篩選值:
- 篩選後的結果集中,每個技能的
capability_type等於篩選值 - 原始集合中所有符合該類型的技能都出現在結果中
屬性 8:呼叫訊息結構完整性
- 對於任意有效的 InvocationRequest,必須包含
caller(含id和type)、skill_id和inputs欄位 - 對於任意有效的 InvocationResponse,必須包含
execution_id、status、skill_id和timestamps欄位
屬性 9:協定版本 SemVer 格式
對於任意有效的 ProtocolVersion 物件,其 version 欄位必須符合 MAJOR.MINOR.PATCH 格式,其中 MAJOR、MINOR、PATCH 均為非負整數。
屬性 10:版本不相容偵測
對於任意技能描述符的協定版本和消費者支援的協定版本:
- 當描述符的主版本號(MAJOR)大於消費者支援的主版本號時,回傳版本不相容錯誤
- 當主版本號相同時,正常處理
屬性 11:TypeScript 與 JSON Schema 語意一致性
- 對於任意由 TypeScript 型別定義產生的有效 SkillDescriptor 實例,該實例應通過 JSON Schema 驗證
- 對於任意通過 JSON Schema 驗證的 JSON 文件,它應能被 TypeScript 型別系統接受
12.3 測試策略
雙軌測試方法
| 方法 | 目的 | 工具 |
|---|---|---|
| 單元測試 | 驗證具體範例、邊界情況和錯誤條件 | vitest |
| 屬性測試 | 驗證跨所有輸入的通用屬性 | fast-check |
屬性測試設定
- 每個屬性測試最少執行 100 次迭代
- 使用 fast-check 函式庫產生隨機測試資料
- 每個正確性屬性由單個屬性測試實作
- 測試標籤格式:
Feature: skill-sharing-protocol, Property {N}: {description}
測試範例
import fc from 'fast-check';
fc.assert(
fc.property(
skillDescriptorArbitrary,
(descriptor) => {
// Feature: skill-sharing-protocol, Property 3: round-trip consistency
const serialized = serialize(descriptor);
const parsed = parse(serialized);
expect(parsed).toEqual(descriptor);
}
),
{ numRuns: 100 }
);
