- 合并 DEVELOPMENT.md 至 docs/development/README.md - 合并 CONTRIBUTING.md 至 docs/development/checker.md - 合并 build-release.md 至 release.md - 合并 testing-quality.md 内容至各专题文档 - 合并 status-model.md 至 expectations.md - 新增 docs/user/README.md 用户入口 - 简化 docs/README.md 文档路由 - 各专题文档新增适用场景和更新触发条件 - 更新 openspec/config.yaml 文档规则
188 lines
8.4 KiB
Markdown
188 lines
8.4 KiB
Markdown
# Checker 开发
|
||
|
||
Checker 是 DiAL 的核心扩展单元。每个 checker 是 `src/server/checker/runner/<type>/` 下的自包含目录,包含类型、schema、语义校验、执行逻辑、序列化和断言。
|
||
|
||
适用场景:新增 checker、修改 checker 配置或 expect、调整 checker 注册机制、改动 checker 测试或用户文档同步规则。
|
||
|
||
新增或修改 checker 前必须阅读 [开发入口](README.md)、[配置文件](../user/configuration.md)、[校验规则](../user/expectations.md) 和 [Checker 用户文档](../user/checkers/README.md)。还应阅读现有同类 checker 的实现和测试,例如 `src/server/checker/runner/http/` 与 `tests/server/checker/runner/http/`。
|
||
|
||
## 设计原则
|
||
|
||
- 每个 checker 必须自包含在 `src/server/checker/runner/<type>/`。
|
||
- checker 专属类型、schema、validate、execute、expect 和协议辅助逻辑放在同一目录。
|
||
- 注册只修改 `src/server/checker/runner/index.ts`,中间层不新增 type switch。
|
||
- schema 层只描述契约,语义规则放入 `validate.ts`。
|
||
- `resolve()` 只做默认值填充、路径解析和单位转换,不执行校验。
|
||
- `execute()` 必须支持 `CheckerContext.signal` 超时取消。
|
||
- expect 字段必须选择合适断言模型,不为了统一而滥用 ValueMatcher。
|
||
- failure phase 命名遵循去单位后缀规则,例如 `durationMs` 对应 `duration`。
|
||
|
||
## 架构目标
|
||
|
||
```text
|
||
checkerRegistry
|
||
├── runner/index.ts
|
||
├── schema/builder.ts
|
||
├── schema/validate.ts
|
||
├── config-loader.ts
|
||
├── engine.ts
|
||
└── store.ts
|
||
```
|
||
|
||
注册后,中间层通过 registry 自动委托 schema 生成、契约校验、配置 resolve、执行和序列化。新增 checker 不应在中间层新增 `switch/case` 或类型分支。
|
||
|
||
## 标准文件结构
|
||
|
||
| 文件 | 职责 |
|
||
| ------------- | ----------------------------------------------------- |
|
||
| `index.ts` | 模块入口,re-export Checker 类 |
|
||
| `types.ts` | Checker 专属类型 |
|
||
| `schema.ts` | TypeBox 契约 schema,包含 config 和 expect |
|
||
| `validate.ts` | 启动期语义校验 |
|
||
| `execute.ts` | Checker 类,实现 resolve、execute、serialize |
|
||
| `expect.ts` | Checker 专用断言函数 |
|
||
| 其他文件 | 协议解析、编码、provider 适配、平台命令封装等专属逻辑 |
|
||
|
||
## 类型定义
|
||
|
||
在 `types.ts` 中定义:
|
||
|
||
- `RawXxxTargetConfig`
|
||
- `RawXxxExpectConfig`
|
||
- `ResolvedXxxExpectConfig`
|
||
- `ResolvedXxxTarget extends ResolvedTargetBase`
|
||
|
||
不需要修改顶层 `checker/types.ts`。base interface 使用 index signature 支持扩展。
|
||
|
||
## Schema
|
||
|
||
checker 必须提供 `CheckerSchemas`,包含 Authoring 和 Normalized 两套 config/expect 片段。Authoring 描述用户 YAML 可写 DSL,Normalized 描述 normalizer 输出。
|
||
|
||
常用 fragments:
|
||
|
||
| Fragment | 用途 |
|
||
| ----------------------------------- | ------------------------- |
|
||
| `durationSchema` | 时长字符串 |
|
||
| `sizeSchema` | 大小单位 |
|
||
| `statusCodePatternSchema` | HTTP 状态码或范围 |
|
||
| `stringMapSchema` | headers、env 等字符串映射 |
|
||
| `createValueMatcherSchema()` | ValueMatcher |
|
||
| `createContentExpectationsSchema()` | ContentExpectations |
|
||
| `createKeyedExpectationsSchema()` | KeyedExpectations |
|
||
|
||
默认对象策略为 `additionalProperties: false`。只有明确的动态键值表可以开放任意键名。
|
||
|
||
## 语义校验
|
||
|
||
在 `validate.ts` 中实现 JSON Schema 无法表达的规则,统一返回 `ConfigValidationIssue[]`,不要直接拼接最终错误字符串。
|
||
|
||
共享校验工具包括:
|
||
|
||
| 函数 | 用途 |
|
||
| -------------------------------- | ---------------------------- |
|
||
| `validateRawValueExpectation` | 校验 Raw ValueExpectation |
|
||
| `validateRawContentExpectations` | 校验 ContentExpectations |
|
||
| `validateRawKeyedExpectations` | 校验 KeyedExpectations |
|
||
| `validateJsonPath` | 校验项目支持的 JSONPath 子集 |
|
||
| `isJsonValue` | 判断合法 JSON value |
|
||
|
||
## resolve 规范
|
||
|
||
`resolve()` 只做内置默认值填充、路径解析、单位转换,不执行校验。输入已经通过 Normalized schema 和语义校验,expect 已是 normalized 形态。
|
||
|
||
```typescript
|
||
const expect = target.expect as ResolvedXxxExpectConfig | undefined;
|
||
const resolvedExpect: ResolvedXxxExpectConfig = expect
|
||
? { ...expect, status: expect.status ?? [200] }
|
||
: { status: [200] };
|
||
```
|
||
|
||
返回值使用 `satisfies ResolvedXxxTarget` 确保类型正确。
|
||
|
||
## execute 规范
|
||
|
||
- 始终记录 `timestamp` 和 `start = performance.now()`。
|
||
- 通过 `ctx.signal` 支持超时取消。
|
||
- 首个 expect 失败即停止,返回带 `failure` 的结果。
|
||
- 成功时 `failure: null, matched: true`。
|
||
- 异常时使用 `errorFailure()`。
|
||
- 不匹配时使用 `mismatchFailure()`。
|
||
- `expected` 参数应传用户可读值,必要时使用 `displayValueExpectation()`。
|
||
|
||
## expect 字段选择
|
||
|
||
| 场景 | 模型 |
|
||
| ------------------------------------ | ------------------- |
|
||
| 状态类结果且集合小而稳定 | enum 或 boolean |
|
||
| 单值数字指标或字符串元数据 | ValueMatcher |
|
||
| 文本、JSON、HTML、XML 或半结构化内容 | ContentExpectations |
|
||
| 动态键值表 | KeyedExpectations |
|
||
|
||
不要为了统一而把状态类字段改成 ValueMatcher。一个 expect 字段只能对应一种断言模型。
|
||
|
||
## 注册
|
||
|
||
1. 创建 `src/server/checker/runner/<type>/index.ts`。
|
||
2. 在 `src/server/checker/runner/index.ts` 添加导入。
|
||
3. 在 registry 初始化数组中添加 checker 实例。
|
||
|
||
注册后,schema builder、validate、config-loader、engine、store 会自动按 registry 分发。
|
||
|
||
## 测试要求
|
||
|
||
测试文件放在 `tests/server/checker/runner/<type>/`,结构镜像源文件。
|
||
|
||
| 测试类别 | 覆盖内容 |
|
||
| ------------ | ---------------------------------------- |
|
||
| 契约测试 | TypeBox schema 与 JSON Schema 导出一致性 |
|
||
| 语义校验测试 | 合法和非法配置 |
|
||
| resolve 测试 | 默认值合并、路径解析、单位转换 |
|
||
| execute 测试 | 成功、失败、超时、expect 组合 |
|
||
| 注册测试 | registry 注册行为 |
|
||
| 配置加载测试 | 含新 checker 的 YAML 完整加载流程 |
|
||
|
||
## 文档和 schema 更新
|
||
|
||
新增或修改 checker 时通常需要更新:
|
||
|
||
- `probes.example.yaml`
|
||
- `probe-config.schema.json`,通过 `bun run schema` 生成
|
||
- `docs/user/checkers/<type>.md`
|
||
- `docs/user/checkers/README.md`
|
||
- `docs/user/expectations.md`,仅当断言模型、状态模型或通用规则变化
|
||
- `docs/user/configuration.md`,仅当 target 通用字段或配置加载形态变化
|
||
- `docs/development/checker.md`,仅当 checker 开发机制、测试要求或 checklist 变化
|
||
- `docs/README.md` 和 `openspec/config.yaml`,仅当文档同步规则变化
|
||
|
||
## 验证命令
|
||
|
||
新增或修改 checker 后通常需要运行:
|
||
|
||
```bash
|
||
bun run schema
|
||
bun run schema:check
|
||
bun run check
|
||
```
|
||
|
||
影响构建、Docker 或发布包时追加运行 `bun run verify`。
|
||
|
||
## 完成检查清单
|
||
|
||
```text
|
||
□ checker 类型、schema、validate、resolve、execute、serialize 已实现
|
||
□ checker 已在 runner/index.ts 注册
|
||
□ 配置契约、语义校验和 JSON Schema 导出已同步
|
||
□ probes.example.yaml 已添加或更新示例
|
||
□ tests/server/checker/runner/<type>/ 已覆盖契约、校验、resolve、execute、注册和配置加载
|
||
□ docs/user/checkers/<type>.md 已添加或更新
|
||
□ docs/user/checkers/README.md 已添加或更新
|
||
□ 文档影响分析已完成,必要文档已同步
|
||
□ bun run schema 和 bun run schema:check 已通过
|
||
□ bun run check 已通过
|
||
□ bun run verify 已通过或记录未执行原因
|
||
```
|
||
|
||
## 更新触发条件
|
||
|
||
修改 checker 开发机制、目录结构、schema/validate/resolve/execute/expect 约定、测试要求、验证命令或文档同步 checklist 时,必须更新本文档。
|