# leaudit-oss-yaml-files 规则体检报告

> 体检对象：`/home/wren-dev/Porject/leaudit-platform/leaudit-oss-yaml-files`
> 体检时间：2026-05-21
> 体检方式：使用当前平台后端 `RuleValidator.ValidateYaml` 执行 YAML schema + DSL 语义校验，并补充扫描历史视觉写法、错误视觉字段引用、全文上下文字段引用。

## 1. 总体结论

当前目录共有 31 份 `rules.yaml`。

| 项 | 数量 | 说明 |
|----|------|------|
| 总规则文件 | 31 | 合同、公文、行政卷宗规则混合 |
| 可通过 schema + DSL 校验 | 21 | 可以作为后续发布候选，但仍可能存在历史兼容写法 |
| 校验失败 | 10 | 不能直接发布，发布接口会被后端拦截 |
| 存在历史视觉写法 | 13 | 部分能通过校验，但会影响规则编辑器正确回显/保存 |

核心问题不是租户隔离，而是规则 YAML 自身存在三类格式风险：

| 风险类型 | 影响 |
|----------|------|
| `field: ctx` | 当前 DSL 会把 `ctx` 当成抽取字段校验，因未声明 `ctx` 导致发布失败 |
| `check: visual + element` | 历史兼容写法，运行可部分兼容，但编辑器保存时容易变形成错误依赖 |
| `field: visual.xxx` | 把视觉要素当普通抽取字段，属于错误配置，应迁移为正式视觉 stage |

## 2. 校验失败文件

以下 10 份当前不能直接发布。

| 文件 | 失败原因 | 直接影响 |
|------|----------|----------|
| `contract.construction.general/v3/rules.yaml` | `GC-OUR-001 stage 1 references unknown field: ctx` | 建设工程合同 v3 不能发布 |
| `contract.entrust/v9/rules.yaml` | `MM-ENT-035 stage 1 references unknown field: ctx` | 通用委托合同 v9 不能发布 |
| `contract.evaluation.delegation/0.1/rules.yaml` | `rules.1.messages/type Extra inputs are not permitted`，并包含 `field: ctx` | 委托评估合同 0.1 结构错误，不能发布 |
| `contract.gift.charity/1.0/rules.yaml` | `ZY-CHY-023 stage 1 references unknown field: ctx` | 慈善赠与合同不能发布 |
| `contract.gift.general/1.0/rules.yaml` | `ZY-GEN-016 stage 1 references unknown field: ctx` | 通用赠与合同不能发布 |
| `contract.lease/2.0/rules.yaml` | `ZL-LEASE-036 stage 1 references unknown field: ctx` | 租赁合同不能发布 |
| `contract.loan.general/1.0/rules.yaml` | `JK-OUR-001 stage 1 references unknown field: ctx` | 借款合同不能发布 |
| `contract.purchase.general/1.0/rules.yaml` | `MM-OUR-001 stage 1 references unknown field: ctx`，且有 `field: visual.xxx` | 买卖合同不能发布，且视觉补救动作配置错误 |
| `contract.sale/2.1/rules.yaml` | `MM-SALE-029 stage 1 references unknown field: ctx` | 销售合同不能发布 |
| `contract.tech/1.0/rules.yaml` | `JS-TECH-035 stage 1 references unknown field: ctx` | 技术合同不能发布 |

## 3. 可通过但仍需迁移的文件

以下文件 schema + DSL 当前能过，但还存在历史视觉写法 `check: visual`。

| 文件 | 规则 | 当前问题 |
|------|------|----------|
| `contract.entrust/2.0/rules.yaml` | `MM-ENT-031` | `check: visual + element: 骑缝章` |
| `contract.entrust/v2/rules.yaml` | `MM-ENT-031` | `check: visual + element: 骑缝章` |
| `contract.entrust/v3/rules.yaml` | `MM-ENT-031` | `check: visual + element: 骑缝章` |
| `contract.entrust/v4/rules.yaml` | `MM-ENT-031` | `check: visual + element: 骑缝章` |
| `contract.entrust/v5/rules.yaml` | `MM-ENT-031` | `check: visual + element: 骑缝章` |
| `contract.entrust/v6/rules.yaml` | `MM-ENT-031` | `check: visual + element: 骑缝章` |
| `contract.entrust/v7/rules.yaml` | `MM-ENT-031` | `check: visual + element: 骑缝章` |
| `contract.entrust/v8/rules.yaml` | `MM-ENT-031` | `check: visual + element: 骑缝章` |

这类文件不是立即阻断发布的问题，但不建议继续保留旧写法。原因是规则编辑页面现在应该以正式视觉 stage 为准，否则会出现你前面看到的 `visual.xxx`、视觉编码、YAML 片段不一致等问题。

## 4. 具体问题定位

### 4.1 `field: ctx`

命中的规则如下：

| 文件 | 规则 ID | 说明 |
|------|---------|------|
| `contract.construction.general/v3/rules.yaml` | `GC-OUR-001` | 我方缔约地位及不利条款审查 |
| `contract.entrust/v9/rules.yaml` | `MM-ENT-035` | 我方缔约地位及不利条款审查 |
| `contract.evaluation.delegation/0.1/rules.yaml` | `EVAL-OUR-001` | 我方缔约地位及不利条款审查 |
| `contract.gift.charity/1.0/rules.yaml` | `ZY-CHY-023` | 我方缔约地位及不利条款审查 |
| `contract.gift.general/1.0/rules.yaml` | `ZY-GEN-016` | 我方缔约地位及不利条款审查 |
| `contract.lease/2.0/rules.yaml` | `ZL-LEASE-036` | 我方缔约地位及不利条款审查 |
| `contract.loan.general/1.0/rules.yaml` | `JK-OUR-001` | 我方缔约地位及不利条款审查 |
| `contract.purchase.general/1.0/rules.yaml` | `MM-OUR-001` | 我方缔约地位及不利条款审查 |
| `contract.sale/2.1/rules.yaml` | `MM-SALE-029` | 我方缔约地位及不利条款审查 |
| `contract.tech/1.0/rules.yaml` | `JS-TECH-035` | 我方缔约地位及不利条款审查 |

当前错误写法：

```yaml
stages:
- id: '1'
  check: ai
  field: ctx
  prompt: |-
    合同全文：{{ctx}}
```

当前引擎的 AI prompt 插值只读取 `ctx.fields + ctx.derived`。`ctx` 不是内置字段名，所以 DSL 校验会失败，运行时也无法正确插入全文。

推荐修复方向有两种：

| 方案 | 做法 | 是否推荐 |
|------|------|----------|
| A | 在规则文件 `extract` 中声明一个真实字段，例如 `合同全文`，prompt 使用 `{{合同全文}}` | 不推荐，全文不是普通抽取字段，容易拖慢抽取并污染字段语义 |
| B | 后端引擎提供正式全文上下文变量，例如 `full_text` 或 `document_text`，DSL validator 将其列为系统内置字段 | 推荐，符合“全文上下文不是抽取字段”的语义 |

短期如果只想让 YAML 先通过发布，可以将 `field: ctx` 删除，并把 prompt 中 `{{ctx}}` 改成已声明字段拼接。但这会降低“我方不利条款审查”的覆盖面，不建议作为最终方案。

### 4.2 旧视觉写法 `check: visual`

命中的规则如下：

| 文件 | 规则 ID | 当前写法 |
|------|---------|----------|
| `contract.entrust/*/rules.yaml` | `MM-ENT-031` | `check: visual + element: 骑缝章` |
| `contract.lease/2.0/rules.yaml` | `ZL-LEASE-032` | `check: visual + element: 骑缝章` |
| `contract.tech/1.0/rules.yaml` | `JS-TECH-032` | `check: visual + element: 骑缝章` |
| `contract.evaluation.delegation/0.1/rules.yaml` | `EVAL-SEAL-001` | `check: visual + element: seal + expect: type_in` |
| `contract.evaluation.delegation/0.1/rules.yaml` | `EVAL-SEAL-002` | `check: visual + element: seal + expect: text_match` |
| `contract.evaluation.delegation/0.1/rules.yaml` | `EVAL-CROSS-001` | `check: visual + element: cross_page_seal + expect: present` |
| `contract.evaluation.delegation/0.1/rules.yaml` | `EVAL-CROSS-002` | `check: visual + element: cross_page_seal + expect: complete` |
| `contract.evaluation.delegation/0.1/rules.yaml` | `EVAL-SIGN-001` | `check: visual + element: signature + expect: present` |

正确迁移方向：

```yaml
visual_elements:
  cross_page_seals:
  - id: 骑缝章
    name: 合同骑缝章
    required: true
    required_from: executed

rules:
- group: 默认规则组
  rules:
  - rule_id: JS-TECH-032
    name: 骑缝章检查
    risk: medium
    score: 2
    type: deterministic
    applies_in:
    - executed
    stages:
    - id: '1'
      type: cross_page_seal.complete
      seal_id: 骑缝章
    logic: '1'
```

### 4.3 `field: visual.xxx`

当前命中文件：

| 文件 | 位置 | 问题 |
|------|------|------|
| `contract.purchase.general/1.0/rules.yaml` | remediation actions | `field: visual.甲方签章`、`field: visual.乙方签章` |

这不是 stage 校验字段，所以当前失败优先暴露为 `ctx`，但它仍是错误语义。补救动作不应让用户“重查 visual.xxx 字段”，而应指向具体视觉要素或普通抽取字段。

推荐改法：

```yaml
actions:
- type: recheck_visual
  label: 核对甲方印章文字
  visual_type: seal
  seal_id: 甲方签章
- type: recheck_visual
  label: 核对乙方印章文字
  visual_type: seal
  seal_id: 乙方签章
```

如果前端暂时没有 `recheck_visual` 动作渲染能力，则先改成普通说明类动作，避免继续写 `field: visual.xxx`。

## 5. `contract.evaluation.delegation/0.1` 额外结构错误

该文件除 `field: ctx` 和旧视觉写法外，还有 YAML 层级错误：

```text
rules.1.messages Extra inputs are not permitted
rules.1.type Extra inputs are not permitted
```

这说明 `messages` 和 `type` 被放到了 `rules` 顶层列表的第二个元素上，而不是某个具体 rule 内。正确结构必须是：

```yaml
rules:
- group: 签字合规
  rules:
  - rule_id: EVAL-SIGN-001
    name: 甲乙双方签名存在
    risk: high
    score: 10
    stages:
    - id: '1'
      type: signature.present
      signature_id: 甲乙方代理人签名
    logic: '1'
    messages:
      pass: 合同存在甲乙双方的手写签名
      fail: 合同缺少甲方或乙方的手写签名
    type: deterministic
```

## 6. 入库/发布前建议顺序

建议不要一口气把 31 份全部入库。按以下顺序处理可控：

1. 先修复 10 份校验失败文件，目标是 `RuleValidator.ValidateYaml` 全部通过。
2. 再迁移 13 处旧视觉写法，目标是规则详情页回显、保存、发布后 YAML 不再出现 `check: visual`。
3. 单独处理 `field: ctx` 的系统级方案，建议由引擎支持 `full_text/document_text` 内置上下文，而不是把全文伪装成抽取字段。
4. 修复 `contract.evaluation.delegation/0.1` 的层级错误后再做视觉迁移。
5. 对每个 `rule_type` 选择一个当前版本做租户物化，不要把历史所有版本一次性设为所有租户当前版本。

## 7. 可重复校验命令

在平台根目录执行：

```bash
python - <<'PY'
from pathlib import Path
from fastapi_modules.fastapi_leaudit.leaudit_bridge.ruleValidator import RuleValidator

root = Path('leaudit-oss-yaml-files')
validator = RuleValidator()

total = ok = 0
for path in sorted(root.rglob('*.yaml')):
    total += 1
    result = validator.ValidateYaml(path.read_text(encoding='utf-8'))
    if result.valid:
        ok += 1
        continue
    print(f'\nFAIL {path}')
    for error in result.errors or []:
        print(error)

print(f'\nTOTAL={total} OK={ok} FAIL={total - ok}')
PY
```

当前结果应为：

```text
TOTAL=31 OK=21 FAIL=10
```

## 8. 当前不建议立即做的事

| 不建议动作 | 原因 |
|------------|------|
| 直接把这 31 份全部导入生产库 | 有 10 份发布校验失败 |
| 用 `ctx` 作为普通 extract 字段补丁 | 会污染抽取字段语义，且运行时全文来源不稳定 |
| 继续让前端生成 `visual-时间戳` | 业务不可读，回滚/对比/迁移都困难 |
| 保留 `field: visual.xxx` | 视觉要素不是抽取字段，后续页面和执行器都会继续出错 |

## 9. 后续开发任务

| 优先级 | 任务 | 验收点 |
|--------|------|--------|
| P0 | 引擎/校验器支持正式全文上下文变量 | `field: ctx` 不再需要，全文 AI 规则可发布可执行 |
| P0 | 修复 10 份失败 YAML | 31 份全部通过 `RuleValidator.ValidateYaml` |
| P1 | 旧视觉 stage 迁移为正式 stage | 不再出现 `check: visual`，规则详情页 YAML 片段正确 |
| P1 | 修复 `contract.evaluation.delegation/0.1` 层级 | schema 校验通过 |
| P1 | 修复 `contract.purchase.general` 的视觉补救动作 | 不再出现 `field: visual.xxx` |
| P2 | 增加批量规则体检脚本 | 本地、CI、入库前都能重复执行同一套检查 |

