feat: 重构配置生命周期为 Authoring/Normalized/Resolved 三层
将变量替换和 expect 简写展开统一放入 Normalized 阶段, 运行时 AJV 使用 Normalized schema,导出 schema 面向 Authoring Config。 主要变更: - 新增 normalizer.ts 实现 normalizeAuthoringConfig() - 拆分 Authoring/Normalized 双 schema,checker 接口支持 authoring/normalized 片段 - config-loader 流程:normalize → Normalized AJV → semantic → resolve - validator 兼容层自动分派 raw/normalized expect 形态 - 删除 rawExpect,store.expect 列写入 null - Authoring schema 对 integer/boolean/enum 字段接受变量引用 - 修复 DB/HTTP validate 入口守卫和 LLM options integer 变量引用 - 优化 compact() 避免 undefined 覆盖隐患 - 移除 content.ts 恒为 true 的前置条件 - 同步 5 个主规范并归档 change
This commit is contained in:
@@ -98,15 +98,11 @@
|
||||
- **THEN** 系统 SHALL 以错误退出并提示文件不存在
|
||||
|
||||
### Requirement: 配置校验
|
||||
系统 SHALL 在启动时对 YAML 配置进行完整校验,校验失败时以非零状态退出并输出清晰的错误信息。系统 SHALL 使用 TypeBox 定义配置契约和 raw config TypeScript 类型,由 Ajv 校验 TypeBox 生成的 JSON Schema,再执行启动期语义 validator。配置加载流程 SHALL 明确区分 `RawProbeConfig`、`ValidatedProbeConfig`、`ResolvedConfig` 三段生命周期,并在 YAML 解析之后、AJV 校验之前执行变量替换阶段。JSON Schema 契约 SHALL 覆盖业务无关的结构规则,包括字段类型、必填字段、枚举、数组与对象形状、数值范围和未知字段。语义 validator SHALL 覆盖契约不适合表达的业务规则,包括 target id 唯一性、id 命名规则校验、checker type 注册状态、时长和大小解析、HTTP URL、正则可编译、JSONPath 子集和 XPath 可编译。
|
||||
系统 SHALL 在启动时对 YAML 配置进行完整校验,校验失败时以非零状态退出并输出清晰的错误信息。系统 SHALL 使用 TypeBox 定义 Authoring Config 和 Normalized Config 的配置契约,并使用 Ajv 校验 TypeBox 生成的 JSON Schema。配置加载流程 SHALL 明确区分 `AuthoringProbeConfig`、`NormalizedProbeConfig`、`ValidatedProbeConfig`、`ResolvedConfig` 生命周期,并在 YAML 解析之后、Normalized schema 校验之前执行 `normalizeAuthoringConfig()`。该 normalizer SHALL 只负责去糖:变量替换、expect primitive/keyed/content 简写展开、移除 `variables` 段。该 normalizer MUST NOT 注入默认值、解析 duration/size/path/env,或合并 `cmd.env`。
|
||||
|
||||
契约校验和语义 validator SHALL 统一产出 `ConfigValidationIssue`,最终由配置加载流程统一渲染为中文错误信息。
|
||||
JSON Schema 契约 SHALL 覆盖业务无关的结构规则,包括字段类型、必填字段、枚举、数组与对象形状、数值范围和未知字段。Authoring schema SHALL 用于导出的 `probe-config.schema.json`,描述用户 YAML 可书写形式,包括变量引用和 expect 简写。Normalized schema SHALL 用于运行时 AJV 校验,描述 normalizer 输出结果,不接受变量引用、不接受 expect primitive 简写、不包含 `variables` 段。语义 validator SHALL 覆盖契约不适合表达的业务规则,包括 target id 唯一性、id 命名规则校验、checker type 注册状态、时长和大小解析、HTTP URL、正则可编译、JSONPath 子集和 XPath 可编译。
|
||||
|
||||
系统 SHALL 导出完整 `probe-config.schema.json`,该文件 SHALL 与运行期 TypeBox fragments 生成的 JSON Schema 保持一致,用于用户配置引用和编辑器提示。
|
||||
|
||||
除 `headers`、`env`、`variables` 等明确声明为动态键值表的对象外,配置中的未知字段 SHALL 导致启动期配置错误。系统 MUST NOT 静默忽略未知字段。
|
||||
|
||||
所有 `RawValueExpectation` 类型的 expect 字段 SHALL 在 JSON Schema 契约中声明为 `anyOf: [primitiveValue, matcherObject]` 联合类型,同时接受 primitive 原始值(string / number / boolean / null)和 `ValueMatcher` 对象。语义 validator SHALL 在不修改输入的前提下校验 `RawValueExpectation`;primitive 原始值 SHALL 被视为合法 Raw 输入,并在 checker resolve 阶段转换为 `{equals: value}` 对象形式。数组和对象 MUST NOT 作为 `RawValueExpectation` 原始值简写;需要对数组或对象执行 equals 匹配时,配置 MUST 显式写成 `{equals: value}`。`RawKeyedExpectations` 的动态键值 schema SHALL 复用 `RawValueExpectation`,MUST NOT 通过额外 JSON value 分支接受数组或对象简写。
|
||||
契约校验、normalizer 和语义 validator SHALL 统一产出 `ConfigValidationIssue`,最终由配置加载流程统一渲染为中文错误信息。除 `headers`、`env`、Authoring `variables` 等明确声明为动态键值表的对象外,配置中的未知字段 SHALL 导致启动期配置错误。系统 MUST NOT 静默忽略未知字段。
|
||||
|
||||
#### Scenario: target 缺少必填字段
|
||||
- **WHEN** YAML 中某个 target 缺少 id 或 type 字段
|
||||
@@ -145,7 +141,7 @@
|
||||
- **THEN** 系统 SHALL 以错误退出并提示格式错误
|
||||
|
||||
#### Scenario: maxConcurrentChecks 非法
|
||||
- **WHEN** probes.execution.maxConcurrentChecks 不是正整数
|
||||
- **WHEN** Normalized Config 中 probes.execution.maxConcurrentChecks 不是正整数
|
||||
- **THEN** 系统 SHALL 以错误退出并提示 probes.execution.maxConcurrentChecks 格式错误
|
||||
|
||||
#### Scenario: interval 或 timeout 解析结果非法
|
||||
@@ -161,7 +157,7 @@
|
||||
- **THEN** 系统 SHALL 以错误退出并提示必须为非负安全整数字节数
|
||||
|
||||
#### Scenario: HTTP method 非法
|
||||
- **WHEN** YAML 中某个 HTTP target 的 `http.method` 不是 GET、HEAD、POST、PUT、PATCH、DELETE、OPTIONS 之一
|
||||
- **WHEN** Normalized Config 中某个 HTTP target 的 `http.method` 不是 GET、HEAD、POST、PUT、PATCH、DELETE、OPTIONS 之一
|
||||
- **THEN** 系统 SHALL 以错误退出,提示该 target 的 method 不合法
|
||||
|
||||
#### Scenario: HTTP method 小写非法
|
||||
@@ -177,7 +173,7 @@
|
||||
- **THEN** 系统 SHALL 以错误退出,提示该 target 的 maxRedirects 必须为非负整数
|
||||
|
||||
#### Scenario: maxRedirects 非整数非法
|
||||
- **WHEN** YAML 中某个 HTTP target 的 `http.maxRedirects` 不是非负整数(如 `1.5` 或 `"5"`)
|
||||
- **WHEN** Normalized Config 中某个 HTTP target 的 `http.maxRedirects` 不是非负整数(如 `1.5` 或 `"5"`)
|
||||
- **THEN** 系统 SHALL 以错误退出,提示该 target 的 maxRedirects 必须为非负整数
|
||||
|
||||
#### Scenario: ignoreSSL 类型非法
|
||||
@@ -205,28 +201,28 @@
|
||||
- **THEN** 系统 SHALL 以错误退出,提示该 target 的 status 数字不合法
|
||||
|
||||
#### Scenario: durationMs matcher 非法
|
||||
- **WHEN** YAML 中某个 target 的 `expect.durationMs` 不是合法 `RawValueExpectation`
|
||||
- **WHEN** Normalized Config 中某个 target 的 `expect.durationMs` 不是合法 `ValueMatcher` 对象
|
||||
- **THEN** 系统 SHALL 以错误退出,提示该 target 的 expect.durationMs 格式错误
|
||||
|
||||
#### Scenario: durationMs 原始值简写合法
|
||||
- **WHEN** YAML 中某个 target 配置 `expect.durationMs: 5000`
|
||||
- **THEN** 语义校验 SHALL 接受该 Raw primitive 简写且 MUST NOT 修改输入;checker resolve 阶段 SHALL 将其解析为 `{equals: 5000}`
|
||||
#### Scenario: durationMs 原始值简写在 Authoring schema 合法
|
||||
- **WHEN** 使用 Authoring schema 校验配置文件中 `expect.durationMs: 5000`
|
||||
- **THEN** JSON Schema 校验 SHALL 通过,因为 Authoring schema 接受 primitive 简写
|
||||
|
||||
#### Scenario: ValueMatcher 字段字符串简写合法
|
||||
- **WHEN** YAML 中某个 target 配置 `expect.finishReason: "stop"`
|
||||
- **THEN** 语义校验 SHALL 接受该 Raw primitive 简写且 MUST NOT 修改输入;checker resolve 阶段 SHALL 将其解析为 `{equals: "stop"}`
|
||||
#### Scenario: durationMs 原始值简写在 Normalized schema 非法
|
||||
- **WHEN** 使用 Normalized schema 校验配置对象中 `expect.durationMs: 5000`
|
||||
- **THEN** JSON Schema 校验 SHALL 失败,因为 Normalized schema 只接受 `ValueMatcher` 对象
|
||||
|
||||
#### Scenario: ValueMatcher 字段 null 简写合法
|
||||
- **WHEN** YAML 中某个 target 配置 ValueMatcher 字段值为 `null`
|
||||
- **THEN** 语义校验 SHALL 接受该 Raw primitive 简写且 MUST NOT 修改输入;checker resolve 阶段 SHALL 将其解析为 `{equals: null}`
|
||||
#### Scenario: 变量引用在 Authoring schema 合法
|
||||
- **WHEN** 使用 Authoring schema 校验配置文件中 `server.listen.port: "${PORT|3000}"`
|
||||
- **THEN** JSON Schema 校验 SHALL 通过,因为 Authoring schema 面向用户可书写 YAML
|
||||
|
||||
#### Scenario: ValueMatcher 字段数组简写非法
|
||||
- **WHEN** YAML 中某个 target 配置 ValueMatcher 字段值为数组 `[1, 2]`
|
||||
- **THEN** 系统 SHALL 以错误退出,提示该字段必须为 primitive 原始值或 matcher 对象;如需数组 equals 匹配应写成 `{equals: [1, 2]}`
|
||||
#### Scenario: 变量引用在 Normalized schema 非法
|
||||
- **WHEN** 使用 Normalized schema 校验配置对象中 `server.listen.port: "${PORT|3000}"`
|
||||
- **THEN** JSON Schema 校验 SHALL 失败,因为 Normalized schema 只接受变量替换后的 integer
|
||||
|
||||
#### Scenario: ValueMatcher 字段对象简写非法
|
||||
- **WHEN** YAML 中某个 target 配置 ValueMatcher 字段值为对象 `{foo: "bar"}`,且 `foo` 不是合法 matcher 字段
|
||||
- **THEN** 系统 SHALL 以错误退出,提示 `foo` 是未知 matcher;如需对象 equals 匹配应写成 `{equals: {foo: "bar"}}`
|
||||
#### Scenario: Authoring schema 对 integer/boolean/enum 字段接受变量引用
|
||||
- **WHEN** 使用 Authoring schema 校验配置文件中 `http.maxRedirects: "${MAX_REDIRECTS|5}"` 或 `http.ignoreSSL: "${IGNORE_SSL|false}"` 或 `llm.provider: "${PROVIDER|openai}"`
|
||||
- **THEN** JSON Schema 校验 SHALL 通过,因为 Authoring schema 对支持变量替换的 integer/boolean/enum/pattern-string 字段使用 `anyOf: [originalType, {type: "string", pattern: "^\\$\\{[^}]+\\}$"}]` 额外接受完整变量引用字符串
|
||||
|
||||
#### Scenario: icmp target 缺少 host
|
||||
- **WHEN** YAML 中某个 target 配置 `type: icmp` 但缺少 `icmp.host`
|
||||
@@ -292,37 +288,25 @@
|
||||
- **WHEN** 系统执行 JSON Schema 契约校验
|
||||
- **THEN** 系统 MUST NOT 通过契约校验器强制转换类型、注入默认值或删除未知字段
|
||||
|
||||
#### Scenario: 变量替换后字段超长由 Normalized schema 的 maxLength 校验拦截
|
||||
- **WHEN** Authoring Config 中 target 的 `description` 通过 `${...}` 变量替换后超过 500 个字符
|
||||
- **THEN** Normalized schema SHALL 在 AJV 校验阶段以错误退出,提示 description 字段长度错误
|
||||
|
||||
#### Scenario: 配置生命周期分离
|
||||
- **WHEN** 系统加载配置文件
|
||||
- **THEN** 系统 SHALL 按 `unknown -> 变量替换 -> RawProbeConfig -> ValidatedProbeConfig -> ResolvedConfig` 的顺序执行变量替换、契约校验、语义校验和运行期配置解析
|
||||
- **THEN** 系统 SHALL 按 `unknown -> AuthoringProbeConfig -> NormalizedProbeConfig -> ValidatedProbeConfig -> ResolvedConfig` 的顺序执行 YAML 解析、配置去糖、契约校验、语义校验和运行期配置解析
|
||||
|
||||
#### Scenario: Normalized 不补默认值
|
||||
- **WHEN** Authoring Config 中 HTTP target 未配置 `http.method` 和 `expect.status`
|
||||
- **THEN** Normalized Config SHALL 仍不包含这些默认值,checker.resolve() SHALL 在 ResolvedConfig 阶段物化默认 method 和 status 语义
|
||||
|
||||
#### Scenario: 结构化校验 issue
|
||||
- **WHEN** 契约校验、语义 validator 或变量替换阶段发现非法配置
|
||||
- **WHEN** 契约校验、normalizer、语义 validator 或变量替换阶段发现非法配置
|
||||
- **THEN** 系统 SHALL 先生成包含 code、path、message 和可选 targetName 的结构化 `ConfigValidationIssue`,再统一渲染为中文错误信息
|
||||
|
||||
#### Scenario: 导出配置 JSON Schema
|
||||
- **WHEN** 仓库生成或检查配置契约
|
||||
- **THEN** 根目录 SHALL 存在 draft-07 `probe-config.schema.json`,且其内容 SHALL 与当前公共 fragments 和已注册 checker fragments 组装出的完整 schema 一致(包含 variables 段和 target 的 id/name 字段,且不包含顶层 defaults)。所有 `RawValueExpectation` 字段的 schema SHALL 声明为 `anyOf: [primitiveValue, matcherObject]` 联合类型,`RawKeyedExpectations` 的 dynamic value schema SHALL 复用 `RawValueExpectation`
|
||||
|
||||
#### Scenario: JSON Schema RawValueExpectation 接受原始值
|
||||
- **WHEN** 使用 JSON Schema 校验配置文件中 RawValueExpectation 字段值为数字 `5000`
|
||||
- **THEN** JSON Schema 校验 SHALL 通过,因为 RawValueExpectation schema 声明为 `anyOf: [primitiveValue, matcherObject]`
|
||||
|
||||
#### Scenario: JSON Schema RawValueExpectation 接受 matcher 对象
|
||||
- **WHEN** 使用 JSON Schema 校验配置文件中 RawValueExpectation 字段值为 `{lte: 5000}`
|
||||
- **THEN** JSON Schema 校验 SHALL 通过
|
||||
|
||||
#### Scenario: JSON Schema RawValueExpectation 拒绝数组原始值
|
||||
- **WHEN** 使用 JSON Schema 校验配置文件中 RawValueExpectation 字段值为数组 `[1, 2]`
|
||||
- **THEN** JSON Schema 校验 SHALL 失败,因为数组不属于 primitive 原始值或 matcher 对象
|
||||
|
||||
#### Scenario: JSON Schema RawValueExpectation 接受 equals 数组对象
|
||||
- **WHEN** 使用 JSON Schema 校验配置文件中 RawValueExpectation 字段值为 `{equals: [1, 2]}` 或 `{equals: {status: "ok"}}`
|
||||
- **THEN** JSON Schema 校验 SHALL 通过,因为 `equals` 支持任意 JSON value
|
||||
|
||||
#### Scenario: JSON Schema RawKeyedExpectations 拒绝数组对象简写
|
||||
- **WHEN** 使用 JSON Schema 校验配置文件中 `expect.headers.X` 或 DB row 列值为数组 `["a"]` 或对象 `{nested: "ok"}`
|
||||
- **THEN** JSON Schema 校验 SHALL 失败,除非该值显式写在 `{equals: ...}` 下
|
||||
- **THEN** 根目录 SHALL 存在 draft-07 `probe-config.schema.json`,且其内容 SHALL 与当前 Authoring fragments 和已注册 checker Authoring fragments 组装出的完整 schema 一致(包含 variables 段和 target 的 id/name/description 字段,且不包含顶层 defaults)
|
||||
系统 SHALL 支持使用单位字符串配置读取上限,单位包括 `B`、`KB`、`MB` 和 `GB`。
|
||||
|
||||
#### Scenario: 解析 MB
|
||||
@@ -352,21 +336,21 @@
|
||||
- **THEN** 系统 SHALL 调用 `Bun.YAML.parse()` 将内容解析为配置对象
|
||||
|
||||
### Requirement: expect 配置增强
|
||||
系统 SHALL 支持 typed target 的领域专用 expect 配置,并通过共享 `ValueMatcher`、`ContentExpectations` 和 `KeyedExpectations` 表达可复用断言能力。状态类字段 SHALL 保持枚举或布尔语义,包括 HTTP/LLM 的 `status`(支持精确数字和范围模式)、cmd 的 `exitCode`、tcp 的 `connected`、icmp 的 `alive` 和 udp 的 `responded`。value 类指标字段 SHALL 使用 `RawValueExpectation` 输入,并在 resolve 阶段归一化为运行期 `ValueExpectation`,包括通用 `durationMs`、db 的 `rowCount`、udp 的 `responseSize`/`sourceHost`/`sourcePort`、icmp 的 `packetLossPercent`/`avgLatencyMs`/`maxLatencyMs`、llm 的 usage token 与 stream 首 token 耗时。内容类字段 MUST 使用 `RawContentExpectations` 数组表达配置顺序,包括 HTTP `body`、cmd `stdout`/`stderr`、tcp `banner`、udp `response`、llm `output` 和 db `result`。LLM `finishReason` 和 `rawFinishReason` SHALL 使用 `RawValueExpectation`(非 ContentExpectations),因为它们是单值字符串元数据。键值类字段 SHALL 使用 `RawKeyedExpectations`,包括 HTTP/LLM `headers` 和 db `rows` 中的列值断言(db `rows` 的类型为 `Array<RawKeyedExpectations>`,外层数组按行索引,内层每个元素表达该行的列值断言)。
|
||||
系统 SHALL 支持 typed target 的领域专用 expect 配置,并通过共享 `ValueMatcher`、`ContentExpectations` 和 `KeyedExpectations` 表达可复用断言能力。状态类字段 SHALL 保持枚举或布尔语义,包括 HTTP/LLM 的 `status`(支持精确数字和范围模式)、cmd 的 `exitCode`、tcp 的 `connected`、icmp 的 `alive` 和 udp 的 `responded`。Authoring value 类指标字段 SHALL 使用 `RawValueExpectation` 输入,并在 Normalized 阶段归一化为运行期 `ValueExpectation`,包括通用 `durationMs`、db 的 `rowCount`、udp 的 `responseSize`/`sourceHost`/`sourcePort`、icmp 的 `packetLossPercent`/`avgLatencyMs`/`maxLatencyMs`、llm 的 usage token 与 stream 首 token 耗时。Authoring 内容类字段 MUST 使用 `RawContentExpectations` 数组表达配置顺序,并在 Normalized 阶段转换为带 `kind` 的 `ContentExpectation` 数组,包括 HTTP `body`、cmd `stdout`/`stderr`、tcp `banner`、udp `response`、llm `output` 和 db `result`。Authoring 键值类字段 SHALL 使用动态对象,并在 Normalized 阶段转换为 `KeyedExpectations` 数组,包括 HTTP/LLM `headers` 和 db `rows` 中的列值断言。
|
||||
|
||||
配置加载流程 SHALL 保留变量替换后的 Raw expect 作为用户配置快照,同时生成 Resolved expect 作为运行期执行计划。语义校验 SHALL 只读取 Raw expect 并报告问题,MUST NOT 原地归一化或修改 Raw expect。Store 持久化 SHALL 写入 Raw expect;checker execute SHALL 只消费 Resolved expect。
|
||||
配置加载流程 MUST NOT 保留变量替换后的 Raw expect 作为执行路径依赖。语义校验 SHALL 读取 Normalized expect 并报告问题。Store 持久化 MUST NOT 依赖 Raw expect;checker execute SHALL 只消费 Resolved expect。
|
||||
|
||||
#### Scenario: 解析 HTTP expect 配置
|
||||
- **WHEN** YAML 配置文件中 HTTP target 的 expect 包含 status、headers、body expectation 数组和 durationMs matcher
|
||||
- **THEN** 系统 SHALL 保留 Raw HTTP expect 快照,并生成包含默认 status、resolved keyed headers、resolved content body 和 resolved durationMs 的 HTTP Resolved expect
|
||||
- **THEN** Normalized Config SHALL 包含 normalized keyed headers、normalized content body 和 normalized durationMs,checker.resolve() SHALL 生成包含默认 status 的 HTTP Resolved expect
|
||||
|
||||
#### Scenario: 解析 cmd expect 配置
|
||||
- **WHEN** YAML 配置文件中 cmd target 的 expect 包含 exitCode、stdout、stderr 和 durationMs matcher
|
||||
- **THEN** 系统 SHALL 保留 Raw cmd expect 快照,并生成包含默认 exitCode、resolved stdout/stderr content expectations 和 resolved durationMs 的 cmd Resolved expect
|
||||
- **THEN** Normalized Config SHALL 包含 normalized stdout/stderr content expectations 和 normalized durationMs,checker.resolve() SHALL 生成包含默认 exitCode 的 cmd Resolved expect
|
||||
|
||||
#### Scenario: 解析 db expect 配置
|
||||
- **WHEN** YAML 配置文件中 db target 的 expect 包含 durationMs、rowCount、rows 和 result
|
||||
- **THEN** 系统 SHALL 保留 Raw db expect 快照,并生成包含 resolved rowCount、rows keyed expectations 和 result content expectations 的 db Resolved expect
|
||||
- **THEN** Normalized Config SHALL 包含 normalized rowCount、rows keyed expectations 和 result content expectations
|
||||
|
||||
#### Scenario: 解析 tcp expect 配置
|
||||
- **WHEN** YAML 配置文件中 tcp target 的 expect 包含 connected、banner expectation 数组和 durationMs matcher
|
||||
@@ -386,11 +370,11 @@
|
||||
|
||||
#### Scenario: 解析有序 ContentExpectations 数组
|
||||
- **WHEN** YAML 中任一内容类 expect 配置 contains、json、regex 三个数组项
|
||||
- **THEN** 系统 SHALL 在 Raw expect 中保留数组顺序,并在 Resolved expect 中保留执行顺序,供执行阶段按配置顺序快速失败
|
||||
- **THEN** 系统 SHALL 在 Normalized expect 中保留执行顺序,供执行阶段按配置顺序快速失败
|
||||
|
||||
#### Scenario: 不配置 HTTP status
|
||||
- **WHEN** HTTP target 未配置 `expect.status`
|
||||
- **THEN** 系统 SHALL 在 Resolved HTTP expect 中物化默认 `status: [200]` 语义
|
||||
- **THEN** Normalized Config SHALL 不注入 status,checker.resolve() SHALL 在 Resolved HTTP expect 中物化默认 `status: [200]` 语义
|
||||
|
||||
#### Scenario: 配置 HTTP status 范围模式
|
||||
- **WHEN** HTTP target 配置 `expect.status: ["2xx"]`
|
||||
@@ -398,15 +382,15 @@
|
||||
|
||||
#### Scenario: 不配置 cmd exitCode
|
||||
- **WHEN** cmd target 未配置 `expect.exitCode`
|
||||
- **THEN** 系统 SHALL 在 Resolved cmd expect 中物化默认 `exitCode: [0]` 语义
|
||||
- **THEN** Normalized Config SHALL 不注入 exitCode,checker.resolve() SHALL 在 Resolved cmd expect 中物化默认 `exitCode: [0]` 语义
|
||||
|
||||
#### Scenario: 不配置 expect
|
||||
- **WHEN** target 未配置任何 expect 规则
|
||||
- **THEN** 系统 SHALL 正常处理,Raw expect 快照为 undefined,Resolved expect 由各 checker 物化自身默认状态语义
|
||||
- **THEN** 系统 SHALL 正常处理,Normalized Config 不包含 expect,Resolved expect 由各 checker 物化自身默认状态语义
|
||||
|
||||
#### Scenario: Raw expect 不被语义校验修改
|
||||
#### Scenario: Raw expect 不再保留
|
||||
- **WHEN** YAML 中配置 `expect.durationMs: 1000`
|
||||
- **THEN** 语义校验 SHALL 接受该 Raw primitive 简写且 MUST NOT 将 Raw 输入原地修改为 `{equals: 1000}`
|
||||
- **THEN** Normalized Config SHALL 包含 `expect.durationMs: {equals: 1000}`,ResolvedTarget MUST NOT 携带 `rawExpect`
|
||||
|
||||
#### Scenario: 旧 maxDurationMs 字段不再支持
|
||||
- **WHEN** YAML 中任一 target 配置 `expect.maxDurationMs`
|
||||
@@ -426,16 +410,12 @@
|
||||
|
||||
#### Scenario: ContentExpectations 字段必须为数组
|
||||
- **WHEN** YAML 中任一内容类 expect 字段配置为非数组
|
||||
- **THEN** 系统 SHALL 在启动期配置校验失败,提示该字段必须为 expectation 数组
|
||||
- **THEN** 系统 SHALL 在启动期配置校验失败,提示该内容字段必须为 expectation 数组
|
||||
|
||||
#### Scenario: regex 字段非法
|
||||
- **WHEN** YAML 中任一 `regex` 不是字符串、不是可编译正则或存在 ReDoS 风险
|
||||
- **THEN** 系统 SHALL 在启动期配置校验失败,提示对应 regex 不合法
|
||||
|
||||
#### Scenario: Store 持久化 Raw expect
|
||||
- **WHEN** 系统同步已解析 target 到 targets 表
|
||||
- **THEN** `targets.expect` SHALL 存储变量替换后的 Raw expect JSON,而不是包含 `kind` 或 resolved matcher 的运行期执行计划
|
||||
|
||||
### Requirement: 数据保留配置字段
|
||||
配置 schema 的 `server.storage` 段 SHALL 支持 `retention` 字段,类型为字符串,格式为 `<数字><单位>`(单位:`d` 天、`h` 小时、`m` 分钟),用于指定历史数据保留时长。
|
||||
|
||||
@@ -510,16 +490,20 @@
|
||||
- **THEN** 系统 SHALL 在契约校验阶段以错误退出,提示 description 字段长度错误
|
||||
|
||||
### Requirement: 配置 schema 导出包含 target 元信息约束
|
||||
系统 SHALL 在导出的 `probe-config.schema.json` 中包含 target `id`、`name` 和 `description` 的长度约束和可空类型,用于编辑器提示和外部校验。
|
||||
系统 SHALL 在导出的 Authoring `probe-config.schema.json` 中包含 target `id`、`name` 和 `description` 的长度约束和可空类型,用于编辑器提示和外部校验。导出 schema SHALL 面向用户可书写规则文件,因此还 SHALL 接受支持变量替换字段中的完整变量引用字符串和 expect 简写。
|
||||
|
||||
#### Scenario: schema 导出 description
|
||||
- **WHEN** 系统导出 `probe-config.schema.json`
|
||||
- **THEN** target schema SHALL 包含可选的 `description` 字段,类型为 string 或 null,字符串最大长度为 500
|
||||
- **THEN** target schema SHALL 包含可选的 `description` 字段,类型为 string 或 null,字符串最大长度为 500,并允许完整变量引用字符串
|
||||
|
||||
#### Scenario: schema 导出 id 和 name
|
||||
- **WHEN** 系统导出 `probe-config.schema.json`
|
||||
- **THEN** target schema SHALL 声明 `id` 的 minLength 为 1、maxLength 为 30,并声明 `name` 为可选字段,类型为 string 或 null,字符串的 minLength 为 1、maxLength 为 30
|
||||
|
||||
#### Scenario: schema 导出面向 Authoring Config
|
||||
- **WHEN** 系统导出 `probe-config.schema.json`
|
||||
- **THEN** 导出 schema SHALL 接受 `server.listen.port: "${PORT|3000}"` 和 `expect.durationMs: 5000` 这类 Authoring 写法
|
||||
|
||||
### Requirement: TCP 配置校验
|
||||
系统 SHALL 在启动期对 tcp checker 的配置契约和语义执行严格校验。Tcp target 的 `tcp` 分组 SHALL 只允许 `host`、`port`、`readBanner`、`bannerReadTimeout` 和 `maxBannerBytes` 字段;Tcp expect SHALL 只允许 `connected`、`durationMs` 和 `banner` 字段。`banner` MUST 为 `RawContentExpectations` 数组,`durationMs` SHALL 为 `RawValueExpectation`。未知字段、非法类型、非法端口、非法 size、非法 ContentExpectations 和不可编译正则 MUST 导致启动期配置错误。语义校验 MUST NOT 修改 Raw tcp expect 输入。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user