1
0
Files
DiAL/openspec/changes/refactor-checker-cohesion/specs/checker-runner-abstraction/spec.md
lanyuanxiaoyao c396c29402 docs: 添加 checker 内聚化重构方案及归档历史变更
新增 refactor-checker-cohesion 变更提案,包含 proposal、design、
specs 和 tasks,定义 checker 目录内聚结构规范。同时归档已完成的
历史变更记录。
2026-05-13 13:30:05 +08:00

3.8 KiB
Raw Blame History

MODIFIED Requirements

Requirement: Checker 接口定义

系统 SHALL 在 src/server/checker/runner/types.ts 中定义面向扩展的 CheckerDefinition,包含 typeconfigKey、TypeBox 配置契约、启动期语义校验、resolveexecuteserialize 成员。CheckerContext SHALL 包含引擎注入的 AbortSignal。接口方法的参数和返回值 SHALL 使用 base interface 类型(RawTargetConfigResolvedTargetBase),各 checker 实现内部自行 narrow 到具体类型。

Scenario: Checker 接口包含必要方法

  • WHEN 开发者实现一个新的 Checker
  • THEN 该实现 MUST 提供 type(字符串标识)、configKey配置分组名、TypeBox 配置契约、启动期语义校验、resolve(target, context)(解析配置并填充默认值)、execute(target, ctx)(执行探测返回 CheckResultserialize(target)(返回 target 展示文本和 config JSON

Scenario: CheckerContext 注入 signal

  • WHEN 引擎调用 checker.execute(target, ctx)
  • THEN ctx.signal SHALL 是一个由引擎创建的 AbortSignal,在超时或引擎关闭时 abort

Scenario: resolve 不承担通用契约校验

  • WHEN config-loader 调用 checker.resolve()
  • THEN checker.resolve() SHALL 假定配置已经通过 TypeBox/Ajv 契约校验和启动期语义校验,只负责默认值填充、路径解析和领域配置转换

Scenario: type 与 configKey 默认一致

  • WHEN checker 定义 type: "tcp"
  • THEN checker 的 configKey SHALL 默认使用 "tcp",对应 target 的 tcp 分组和 defaults.tcp 分组

Scenario: 接口方法使用 base 类型

  • WHEN 开发者查看 CheckerDefinition 接口签名
  • THEN resolve 的参数 SHALL 为 RawTargetConfig,返回值 SHALL 为 ResolvedTargetBaseexecute 的参数 SHALL 为 ResolvedTargetBaseserialize 的参数 SHALL 为 ResolvedTargetBase

Scenario: checker 实现内部 narrow

  • WHEN HttpChecker 的 execute 方法接收 ResolvedTargetBase 参数
  • THEN 方法内部 SHALL 将参数 narrow 为 ResolvedHttpTarget(通过 type assertion然后使用具体类型的字段

Requirement: 共享 expect 断言函数

系统 SHALL 在 src/server/checker/expect/ 中提供可被多个 checker 复用的 expect 函数。checker 专用的 expect 函数 SHALL 保留在各自子包内。仅被单个 checker 使用的断言模块 SHALL 位于该 checker 目录内。

Scenario: 共享 duration 断言

  • WHEN 任何 checker 需要校验执行耗时
  • THEN SHALL 调用 expect/duration.ts 中的 checkDuration(durationMs, maxDurationMs?),返回统一的 ExpectResult

Scenario: 共享 operator 断言

  • WHEN 任何 checker 需要对值执行 operator 匹配
  • THEN SHALL 调用 expect/operator.ts 中的 applyOperator(actual, op)

Scenario: 共享 failure 构造

  • WHEN 任何 checker 需要构造 CheckFailure 对象
  • THEN SHALL 调用 expect/failure.ts 中的 errorFailure()mismatchFailure()

Scenario: HTTP body 断言位于 HTTP 目录

  • WHEN HTTP checker 需要对响应体执行 contains/regex/json/css/xpath 规则校验
  • THEN SHALL 调用 runner/http/body.ts 中的 checkBodyExpect(body, rules)

Scenario: Command text 断言位于 Command 目录

  • WHEN Command checker 需要对 stdout/stderr 执行文本规则校验
  • THEN SHALL 调用 runner/command/text.ts 中的 checkTextRules(text, rules, phase)

Scenario: HTTP 专用 expect

  • WHEN HTTP checker 需要校验响应状态码和响应头
  • THEN SHALL 调用 runner/http/expect.ts 中的 checkStatus()checkHeaders()

Scenario: Command 专用 expect

  • WHEN Command checker 需要校验退出码
  • THEN SHALL 调用 runner/command/expect.ts 中的 checkExitCode()