144 lines
8.1 KiB
Markdown
144 lines
8.1 KiB
Markdown
# pbl_validation 模块技能(M2 校验引擎)
|
||
|
||
## 定位
|
||
PBL 蓝图校验引擎:**14 维校验 + 5 级质量状态(quality_state)**,阈值全部配置化常量,
|
||
输出固定契约的校验报告,供 pbl_compiler(发布门禁)、pbl_assessment(量规联动)、
|
||
前端蓝图编辑器(问题定位)消费。
|
||
|
||
## 挂载
|
||
```python
|
||
# app/pbls.py init()
|
||
from pbl_validation.init import load_pbl_validation
|
||
load_pbl_validation() # 建表 + 注册 5 个契约 + 内置 14 维规则种子(幂等)
|
||
```
|
||
库名唯一来源:`ServerEnv().get_module_dbname('pbl_validation')`,**禁止硬编码 DBNAME**。
|
||
|
||
## 数据表(2 张)
|
||
| 表 | 用途 | 关键字段 |
|
||
|---|---|---|
|
||
| `pbl_validation_rule` | 校验规则(14 维,`script_type=1` 规则 JSON 形态) | tenant_id / rule_id / dim / weight / severity / enabled / rule_json(含 thresholds) |
|
||
| `pbl_validation_result` | 校验结果(14 维得分 + 5 级质量状态) | tenant_id / result_id / blueprint_id / quality_state / total_score / dim_scores / dim_detail / report_json / fingerprint |
|
||
|
||
DDL:`sql/pbl_validation.sql`(幂等,含 14 条内置规则种子)。
|
||
|
||
## 契约接口(5 个,`/pbl_validation/api/<name>.dspy`)
|
||
| 接口 | 说明 | 必填入参 |
|
||
|---|---|---|
|
||
| `pbl_validation_run` | 执行 14 维校验并落库,返回报告契约 | `blueprint`(dict 或 JSON 串);`tenant_id` 缺省取上下文 |
|
||
| `pbl_validation_get` | 按 `result_id` 或 `blueprint_id`(最新一次)取报告 | 二者之一 |
|
||
| `pbl_validation_list` | 分页列出结果,可按 `blueprint_id`/`quality_state`/`keyword` 过滤 | — |
|
||
| `pbl_validation_rule_list` | 列出规则 + 14 维元信息 + 生效阈值/默认阈值 | — |
|
||
| `pbl_validation_rule_save` | 新增/更新规则(阈值配置化落库,脏阈值直接拒绝) | `dim`(D01~D14) |
|
||
|
||
`pbl_validation_run` 可选入参:`blueprint_id` / `version` / `dims`(只跑指定维度)/
|
||
`thresholds`(阈值覆盖)/ `persist`(0=dry-run 不落库)/ `operator`。
|
||
|
||
## 14 维清单
|
||
| 维度 | code | 名称 | 权重 | 核心 |
|
||
|---|---|---|---|---|
|
||
| D01 | structure_completeness | 结构完整性(7 类子对象齐备) | 1.2 | ★ |
|
||
| D02 | naming_quality | 命名规范 | 0.8 | |
|
||
| D03 | objective_alignment | 学习目标对齐 | 1.2 | ★ |
|
||
| D04 | driving_question | 驱动问题质量 | 1.0 | |
|
||
| D05 | role_design | 角色设计 | 1.0 | |
|
||
| D06 | scene_design | 场景设计 | 0.9 | |
|
||
| D07 | entity_model | 实体模型 | 0.9 | |
|
||
| D08 | task_chain | 任务链完整性 + **多路径覆盖率 mcRatio** | 1.3 | ★ |
|
||
| D09 | rule_integrity | 规则引用完整性 | 1.1 | |
|
||
| D10 | assessment_rubric | 评估量规(权重和=1) | 1.2 | ★ |
|
||
| D11 | evidence_binding | 产出物/证据绑定 | 1.0 | |
|
||
| D12 | difficulty_balance | 难度平衡 | 0.7 | |
|
||
| D13 | duration_balance | 时长平衡 | 0.7 | |
|
||
| D14 | safety_compliance | 安全合规扫描 | 1.0 | ★ |
|
||
|
||
★ = 核心维度,任一 fail 直接把质量状态压到 Q1。
|
||
|
||
## 阈值配置化常量(`constants.DEFAULT_THRESHOLDS`)
|
||
**Q-OPEN-8:`mcRatio = 0.7`**(多路径覆盖率阈值)。其余关键项:
|
||
`qualityBasicScore=0.40` / `qualityGoodScore=0.70` / `qualityExcellentScore=0.90`、
|
||
`minSubObjectKinds=7`、`objectiveCoverageRatio=0.8`、`roleTaskCoverageRatio=0.8`、
|
||
`taskEvidenceCoverageRatio=0.8`、`ruleRefIntegrityRatio=1.0`、`rubricWeightSum=1.0`
|
||
(容差 0.01)、`maxSafetyHits=0`。
|
||
|
||
覆盖优先级(低→高):默认常量 → 规则记录 `rule_json.thresholds` → 接口入参 `thresholds`
|
||
(引擎内 `rule_json` 由接口层用「规则库阈值 + 入参阈值」合成,故入参最终生效)。
|
||
非法覆盖(未知 key / 类型不符 / 负数 / 比例 >1)被忽略并记入 `threshold_ignored`;
|
||
`rule_save` 侧则**直接拒绝**(fail-closed,不落脏配置)。
|
||
|
||
## 5 级质量状态规则(`engine.decide_quality_state`,自上而下短路)
|
||
| 规则 | 条件 | 结果 |
|
||
|---|---|---|
|
||
| R1 | 无维度结果 / 全部 skip | `Q0_DRAFT` |
|
||
| R2 | 存在 blocker 级问题 | `Q1_INCOMPLETE` |
|
||
| R3 | 核心维度(D01/D03/D08/D10/D14)有 fail | `Q1_INCOMPLETE` |
|
||
| R4 | 加权总分 < 0.40 | `Q1_INCOMPLETE` |
|
||
| R5 | 总分 ≥ 0.90 且无 warn/fail | `Q4_EXCELLENT` |
|
||
| R6 | 总分 ≥ 0.70 且核心维度全 pass | `Q3_GOOD` |
|
||
| R7 | 总分 ≥ 0.40 | `Q2_BASIC` |
|
||
| R8 | 兜底 | `Q1_INCOMPLETE` |
|
||
|
||
总分 = Σ(维度得分×权重) / Σ权重(skip 维度不计入分母)。维度得分:pass=1.0、warn=0.6、
|
||
fail/skip=0,D08/D10 等按覆盖率/权重和连续取值。
|
||
|
||
**发布门禁**:`is_publishable()` 要求 `quality_state ∈ {Q3_GOOD, Q4_EXCELLENT}`。
|
||
|
||
## 校验报告契约 `pbl.validation.report/1.0`
|
||
```jsonc
|
||
{
|
||
"contract": "pbl.validation.report/1.0",
|
||
"engine_version": "1.0.0",
|
||
"report_id": "vr_xxxx", "tenant_id": "t1",
|
||
"blueprint_id": "BP1", "version": "v1", "ruleset": "builtin-14d",
|
||
"created_at": 1730000000000, "elapsed_ms": 3,
|
||
"fingerprint": "sha256前32位(载荷+阈值,幂等复用)",
|
||
"quality_state": "Q4_EXCELLENT", "quality_label": "优秀", "quality_order": 4,
|
||
"quality_reasons": ["R5: 加权总分 0.9700 >= Q4 线 0.90 且无 warn/fail"],
|
||
"total_score": 0.97, "weighted_sum": 13.58, "weight_sum": 14.0,
|
||
"dim_count": 14, "dim_total": 14,
|
||
"state_summary": {"pass": 14, "warn": 0, "fail": 0, "skip": 0},
|
||
"severity_summary": {"blocker": 0, "major": 0, "minor": 0, "info": 0},
|
||
"issue_count": 0, "passed": true,
|
||
"dimensions": [{"dim":"D08","name":"任务链完整性","state":"pass","score":1.0,
|
||
"weight":1.3,"weighted_score":1.3,
|
||
"metrics":{"mcRatio":1.0,"mcRatio_threshold":0.7,"path_count":2,
|
||
"branch_exits_total":2,"branch_exits_covered":2,
|
||
"dangling":[],"cyclic_paths":0},
|
||
"issues":[]}],
|
||
"issues": [{"dim":"D08","code":"V-TASK-004","severity":"major",
|
||
"message":"多路径覆盖率 mcRatio=0.50 低于阈值 0.70(Q-OPEN-8)",
|
||
"path":"tasks.mcRatio","expected":0.7,"actual":0.5}],
|
||
"thresholds": {"mcRatio": 0.7, "...": "..."},
|
||
"threshold_ignored": [], "engine_errors": [],
|
||
"dimensions_meta": [{"dim":"D01","code":"structure_completeness","name":"结构完整性",
|
||
"weight":1.2,"desc":"..."}]
|
||
}
|
||
```
|
||
|
||
### 问题码索引
|
||
`V-TENANT-001` 租户缺失 · `V-INPUT-001~004` 载荷非法 · `V-DB-001/002` 库名或 sqlor 不可用 ·
|
||
`V-STRUCT-001/002` 结构 · `V-NAME-001~004` 命名 · `V-OBJ-001~003` 目标 ·
|
||
`V-DQ-001~004` 驱动问题 · `V-ROLE-001~003` 角色 · `V-SCENE-001~003` 场景 ·
|
||
`V-ENT-001~003` 实体 · `V-TASK-001~005` 任务链(004=mcRatio,005=环) ·
|
||
`V-RULE-001/002` 规则引用 · `V-RUB-001~004` 量规(004=权重和≠1) ·
|
||
`V-EV-001~003` 产出物 · `V-DIFF-001~004` 难度 · `V-DUR-001~003` 时长 ·
|
||
`V-SEC-001~005` 安全(破坏性 SQL / 危险命令 / 硬编码凭据 / 动态执行 / 不适宜内容) ·
|
||
`V-ENGINE-001~003` 引擎(禁用 / 返回类型 / 维度异常兜底 fail)。
|
||
|
||
## 陷阱
|
||
- 库名一律 `ServerEnv().get_module_dbname('pbl_validation')`,禁止硬编码 DBNAME。
|
||
- sqlor 只有 `C/U/D/R/I/sqlExe`;查询走 `pbl_common.api` 的 `q_all/q_one`(已适配),
|
||
本模块 `api.q_all/q_one` 做了「优先 pbl_common、回落 sqlor.sqlExe」双通道。
|
||
- 所有读写强制带 `tenant_id`(`pbl_common.api.tenant_id()`),缺失即 fail-closed 报错。
|
||
- 新增契约需同步四处:`api.py` 定义 + `API_REGISTRY` + `__init__.py` 导出 +
|
||
`init.py` env 注册 + `scripts/load_path.py` 的 `API_PATHS`。
|
||
- 引擎是**纯函数**(无 DB/网络/随机),同载荷同阈值必得同报告;落库只在 api 层做。
|
||
- 单维度 checker 抛异常不会中断整体:引擎兜底记 `fail` + `V-ENGINE-003`(fail-closed)。
|
||
- 蓝图载荷支持 4 种形态:`{objects:[{kind:...}]}` / `{kinds:{task:[...]}}` /
|
||
顶层复数键(`tasks`/`roles`/...) / `{blueprint:{...}}` 包装。
|
||
|
||
## 自测
|
||
```bash
|
||
cd modules/pbl_validation && python3 tests/test_validation_engine.py # 111 项断言全绿
|
||
python3 scripts/load_path.py # 打印路径与契约清单
|
||
```
|