Files
cobol-java-v3/docs/enhanced-test-design.md
T
NB-076 50995d3335 chore: SETUP.md + 测试报告脚本 + 文档更新
- SETUP.md: 完整环境搭建指南(同事用)
- SETUP_QUICK.md: 快速搭环境(4步)
- s22~s26: TNA端到端、覆盖率报告、回归检查
- procedure_grammar.lark: 实验性Lark语法

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-25 08:50:17 +08:00

660 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# COBOL 迁移验证平台 — 增强测试方案 v3
> 版本: v4.0 | 基于多角色评审(架构师/设计师/COBOL专家)发现的 3 个问题修正
> 融合: HINA 程序分类 × 测试基准 × 覆盖率(静态+动态) × 质量门禁 × 分层重试
> 基于现有管线改造,不改 runners/comparator/web/worker 等稳定模块
---
## 一、总览
### 1.1 现状与目标
```
现状:
COPYBOOK → Agent1(解析) → Agent2(LLM盲生成) → DataWriter → Runners → Comparator → Report
↑ PASS 只说明 COBOL 和 Java 输出一致,不说明测试数据覆盖了全部逻辑
目标:
同一管线 → 新增 HINA 类型判定 → 规则引擎路径覆盖 + 语义化补充
→ 质量门禁拦截覆盖率不足的数据
→ 静态+动态双重验证覆盖率
→ 报告包含覆盖率/HINA信息/质量评分
```
### 1.2 不变的部分
| 模块 | 说明 |
|:-----|:------|
| `runners/*` | 编译执行逻辑不变(cobol_runner.py 仅新增编译参数,不改变原有流程) |
| `comparator/*` | 字段比对逻辑不依赖数据来源 |
| `agents/agent1_parser.py` | COPYBOOK → FieldTree 逻辑不变 |
| `agents/agent3_diagnostic.py` | 差异诊断逻辑不变 |
| `web/*` | Web UI 不改变 |
| `worker.py` | 任务队列逻辑不变 |
| `jcl/*` | JCL 解析执行不变 |
| `tests/*` | 现有 42 个测试不受影响 |
### 1.3 成本说明
每次验证涉及 4 个 Agent 调用:Agent1(~$0.001) + HINA Agent(~$0.002) + 策略 Agent(~$0.002) + Agent3(~$0.001 仅 mismatch 时),合计约 $0.005-0.006。准确性优先,不因成本压缩 Agent 调用。
### 1.4 术语说明
| 术语 | 说明 |
|:-----|:------|
| HINA | COBOL 程序类型分类体系(33+2 种类型) |
| cobol_testgen | 已有纯规则引擎(5000 行),可解析 COBOL 源码、枚举路径、生成覆盖率 |
| 质量门禁 | 执行前检查测试数据是否满足覆盖率和边界要求 |
| 交叉验证 | 静态(代码分析)与动态(gcov 插桩)覆盖率比对 |
### 1.5 版本变更记录
| 版本 | 变更 |
|:-----|:------|
| v1 | 初版 |
| v2 | 修复退回混用、分支树复用、Phase 1 保留 Agent2、补充 prompt 模板、定义评分公式 |
| v3 | 修复循环体每次重跑、重试计数器竞争条件、断言公式不适用 COBOL、Phase 1 门禁维度、类型优先级顺序、decision_gaps 未定义、交叉验证差异=0、拼写错误、重试可提前实施、文件映射依赖 |
| v4 | 修复 cobol_testgen 输出格式未定义(补充数据格式schema+映射函数)、固定格式 COBOL 源文件解析风险(补充格式检测逻辑)、阻断状态后用户操作路径缺失(补充操作指南+覆盖率分阶段展示规则) |
---
## 二、管线流程
### 2.1 增强后的管线
```
输入:
--copybook <文件> → Agent1
--cobol-src <文件> → cobol_testgen + HINA Agent
流程:
Step 1: Agent1(COPYBOOK) → FieldTree
Step 2: cobol_testgen.extract_structure(--cobol-src)
→ 分支树 + 结构摘要
Step 3: HINA Agent(--cobol-src + 结构摘要)
→ HINA 类型 + 確信度 + 策略参数
Step 4: cobol_testgen.generate_data(--cobol-src, 分支树)
→ base_test_cases (100% 路径覆盖)
Step 5: 策略 Agent(base + HINA 类型)
→ complete_test_cases (基础数据 + 语义化补充 + 边界值)
Step 6: 质量门禁(执行前检查)
├── 通过 → 继续
└── 不通过 → 分类退回(见 2.4)
Step 7: DataWriter(测试数据写入,不变)
Step 8: CobolRunner + JavaRunner(编译运行)
└── COBOL 编译加 -fprofile-arcs -ftest-coverage(可选)
Step 9: gcov 覆盖率采集(可选)
└── 不可用时降级为仅静态
Step 10: 交叉验证(静态 vs 动态)
Step 11: Comparator(字段比对,不变)
Step 12: Agent3 差异诊断(不变)
Step 13: 增强报告
```
### 2.2 数据流
```
Agent1 ── FieldTree ───────────────────────────────────────────┐
cobol_testgen.extract_structure() ── 分支树 ──┬──→ HINA Agent │
├──→ generate_data│
└──→ 质量门禁 │
HINA Agent ── 类型+策略参数 ──→ 策略 Agent ──→ complete_tests ──┤
DataWriter
```
关键设计: **extract_structure() 输出的分支树同时传递给 HINA Agent、generate_data() 和质量门禁**,避免重复解析。
```
extract_structure() 输出的结构摘要 schema:
{
"paragraphs": ["100-MAIN", "200-PROCESS", ...],
"decision_points": [
{"id":1, "kind":"IF", "label":"TX-TYPE = 'P'", "branches":2},
{"id":2, "kind":"EVALUATE", "label":"MEM-STATUS", "branches":4},
],
"branch_tree": <BrSeq object>, // 完整的可遍历分支树对象
"file_count": 2,
"open_directions": {"TRANSIN":"INPUT", "VALIDOUT":"OUTPUT"},
"has_search_all": true,
"has_evaluate": true,
"total_branches": 25,
"total_paragraphs": 12,
}
```
### 2.3 数据格式与映射层
generate_data() 的输出格式必须与 DataWriter 的输入格式兼容。两者之间的映射关系:
```
cobol_testgen generate_data() 输出格式:
list[dict] — 每条记录:
{
"TX-CARD-NO": "6222021234567800", // 字段名 = COBOL 变量名
"TX-AMOUNT": "00000128050", // 值 = 字符串(COBOL DISPLAY 格式)
"TX-TYPE": "P",
...
}
现有 TestCase (data/test_case.py) 格式:
TestCase(id="TC-001", fields={"BR-AMT": 1500000})
// 字段名 = 映射后的业务名, 值 = Python 原生类型
DataWriter 需要的格式(runners/data_writer.py:
write_cobol_binary(): 接收 TestCase[] → 按 FieldTree 偏移写二进制
write_native_json(): 接收 TestCase[] → 写 JSON Lines
```
**Phase 1 适配方式**: 在 orchestrator.py 中增加一个轻量转换函数 `_cobol_testgen_to_testcases()`,将 cobol_testgen 的输出转换为 `TestCase[]`
```python
def _cobol_testgen_to_testcases(records: list[dict]) -> list:
"""
将 cobol_testgen 的输出(字段名→字面值)转换为 TestCase 列表。
字段值保留为字符串(COBOL 原始格式),DataWriter 根据 PIC 类型自动解析。
"""
from data.test_case import TestCase
result = []
for i, rec in enumerate(records):
tc = TestCase(id=f"CTG-{i+1:04d}", fields=dict(rec))
result.append(tc)
return result
```
**分支树复用时的 COBOL 格式检测问题**:
cobol_testgen 的 `preprocess()` 在解析源码前需要检测文件格式(fixed/free)。**大型机迁移的 COBOL 程序 99% 是固定格式**(列 7-72 为代码区)。如果格式检测错误,PROCEDURE DIVISION 解析会失败或返回空分支树。
`extract_structure()` 的实现必须注意:
1. 强制指定格式假设: 默认按 fixed 格式解析(大型机迁移场景)
2. 如果解析后分支树为空,尝试另一种格式
3. 记录格式检测结果到结构摘要中 `"source_format": "fixed" | "free" | "auto"`
```python
# extract_structure() 中的格式处理逻辑
# 默认以 fixed 格式解析(大型机 COBOL 的行业惯例)
# 如果解析后无决策点,尝试 free 格式
source_format = "fixed"
proc = extract_procedure_division(preprocess(source))
tree, _ = build_branch_tree(proc)
if not has_any_decision(tree):
source_format = "free"
proc = extract_procedure_division(preprocess_free(source))
tree, _ = build_branch_tree(proc)
```
### 2.4 质量门禁的循环机制
**generate_data() 只执行一次,放在循环外部。** 每次迭代只做增量补充,不重跑全量生成。
```python
# 首次生成(循环外)
base_tests = cobol_testgen.generate_data(cobol_src_text, branch_tree)
complete_tests = strategy_agent.supplement(base_tests, hina_result)
# 质量门禁循环(只做增量补充,不重跑 generate_data
MAX_TOTAL_RETRIES = 4
total_retry = 0
while total_retry < MAX_TOTAL_RETRIES:
gate_result = quality_gate.check(complete_tests, hina_result, coverage_data)
if gate_result["passed"]:
break
total_retry += 1
issues = gate_result["issues"]
# 格式: {"decision_gaps": [1, 3], "hina_gaps": ["MT-N002", "COM-A002"]}
made_progress = False
if issues.get("decision_gaps"):
# 对未覆盖的决策点增量补充
delta = cobol_testgen.incremental_supplement(
branch_tree, issues["decision_gaps"]
)
complete_tests = complete_tests + delta
made_progress = True
if issues.get("hina_gaps"):
# 对未满足的 HINA 必须项增量补充
delta = strategy_agent.supplement_only(complete_tests, issues["hina_gaps"])
complete_tests = complete_tests + delta
made_progress = True
if not made_progress:
# 没有可修复的问题 → 跳出(避免死循环)
break
# 循环结束后检查 final 结果
if not gate_result["passed"]:
# 经过 MAX_TOTAL_RETRIES 或无可修复项后仍未通过
# 不阻断管道(数据可以执行),但报告标记为 QUALITY_WARN
vr.status = "QUALITY_WARN"
vr.debug["quality_issues"] = gate_result["issues"]
```
**decision_gaps 的格式**:
```python
decision_gaps = [1, 3, 5] # 未覆盖的决策点 ID(对应结构摘要中的 decision_points[].id
# cobol_testgen.incremental_supplement() 根据 ID 找到对应的分支条件,
# 生成恰好覆盖该分支的测试数据
```
**hina_gaps 的格式**:
```python
hina_gaps = ["MT-N002", "COM-A002"] # 未满足的 HINA 必须项 ID
# strategy_agent.supplement_only() 根据 ID 找到对应的测试场景,
# 补充必要的测试数据
```
### 2.4 不通过时的原因分类与处置
```
质量门禁检查结果 → 原因分类
决策点覆盖率 < 95%:
→ incremental_supplement(decision_point_ids),补充决策点覆盖
→ 不超过 4 次总循环
HINA 必须项不足(Phase 2 之后):
→ supplement_only(missing_item_ids)
→ 不超过 4 次总循环
字段覆盖不足:
→ 补字段值(数值 0 算非空,空格/空串算空,unused 字段跳过)
边界条件不足:
→ 策略 Agent 根据类型模板补充
```
### 2.5 交叉验证
```
交叉验证以 cobol_testgen 静态分析为计数基准,gcov 仅提供"实际执行了"的佐证。
验证方式:
1. cobol_testgen 统计静态分支总数和已覆盖数 → 分支覆盖率(静态)
2. gcov 统计实际运行时执行过的行/分支
3. 对比: 静态覆盖率 ≥ 95% 且 gcov 确认了执行
注意:
- 不要求"差异=0",因为静态和动态对分支的计数方式可能不同
- gcov 的作用是确认测试数据确实被执行了,而不是验证数量
- 如果 gcov 不可用,降级为仅静态分析,报告标记"仅静态"
```
---
## 三、阶段实施
### Phase 1: cobol_testgen 集成 + Agent2 保留(P0
```
改动:
cobol_testgen/__init__.py → 暴露 extract_structure()、generate_data()
orchestrator.py → 插入 extract_structure() + generate_data()
└── Agent2(LLM) 仍然保留,在 cobol_testgen 之后补充语义化数据
流程:
cobol_testgen(路径覆盖) → Agent2(语义补充) → 质量门禁(初步)
Phase 1 质量门禁检查维度:
├── 决策点覆盖率 ≥90%? ✅ cobol_testgen 静态分析可用
├── 段落覆盖率 100%? ✅ cobol_testgen 静态分析可用
└── 其他维度(HINA/字段/边界)→ 尚未集成,跳过
中间状态:
- 报告包含"覆盖率(初步)"标记,注明仅含决策点和段落维度
- 覆盖率标准 ≥90%(低于正式标准的 95%)
```
**为什么要保留 Agent2**: cobol_testgen 按 PIC 类型生成边界值,但不知道字段的业务含义("TX-MERCHANT"应该用空/超长/特殊字符)。Agent2(LLM) 至少能看到字段名,能猜出业务含义。Phase 2 上线后 Agent2 被策略 Agent 取代。
**分层重试可在 Phase 1 同时部署:** retry.py 部署在调用者层,不依赖其他 Phase 的组件。
### Phase 2: HINA Agent + 策略 AgentP1
```
新增:
hina/classifier.py # HINA Agent 调用 (类型判定)
hina/strategy.py # 策略模板 + 策略 Agent 调用 (测试补充)
hina/gate.py # 质量门禁 (覆盖率和必须项检查)
修改:
orchestrator.py → Agent2 替换为策略 Agent
范围:
优先覆盖 jcl-cobol-git 中实际需要的类型(按匹配现有程序优先级排列):
1. マッチング系(M:N)— GENDATA/CRDVAL/CRDCALC 都需要
2. キーブレイク系(键中断)— CRDCALC/CRDRPT 需要
3. 内部表検索 (SEARCH/SEARCH ALL) — CRDVAL/CRDCALC 需要
4. 条件分岐系 (IF/EVALUATE) — 所有程序都有
5. 項目チェック系(字段校验)— CRDVAL 需要
匹配系的高级检查(多文件数据映射)包含在本阶段优先级中。
```
### Phase 3: 动态覆盖(P2
```
修改:
runners/cobol_runner.py → 编译加 -fprofile-arcs
如果 GnuCOBOL 不支持插桩,降级为仅静态
新增:
hina/gcov_collector.py # gcov 解析 + 降级逻辑
修改:
orchestrator.py → 运行后采集 gcov + 交叉验证
```
### Phase 4: 增强报告(P2
```
修改:
report/generator.py → 增加覆盖率/HINA/质量评分/重试历史
依赖:
- 覆盖率数据 → Phase 1/3 可用
- HINA 信息 → Phase 2 完成后可用
- 质量评分公式 → 依赖 Phase 2 的 HINA 必须项数据
质量评分公式(COBOL 版):
质量评分 = 覆盖质量 × 0.6 + 边界质量 × 0.4
覆盖质量 = 段落覆盖率 × 0.5 + 分支覆盖率 × 0.5
例: (1.0 × 0.5 + 0.92 × 0.5) = 0.96
边界质量 = HINA 必须项覆盖率(Phase 2 之后可用,之前以"待集成"显示)
例: 10/10 = 1.0
总评分 = 0.96 × 0.6 + 1.0 × 0.4 = 0.976 → 98/100
```
---
## 四、Agent 体系
### 4.1 4 个 Agent 分布
| Agent | 职责 | 输入 | 输出 | 位置 |
|:------|:-----|:-----|:-----|:-----|
| **Agent1** | COPYBOOK → FieldTree | COPYBOOK 文本 | 字段结构树 | Phase 0 原有 |
| **HINA Agent** | 程序类型判定 | COBOL 源码 + 结构摘要 | HINA 类型 + 確信度 | Phase 2 新增 |
| **策略 Agent** | 测试数据补充 | HINA 类型 + 规则数据 | 语义化测试值 | Phase 2 新增 |
| **Agent3** | 差异诊断 | 不匹配字段 | 诊断建议 | Phase 0 原有 |
**Phase 1 特殊状态**: Agent2 保留,在 cobol_testgen 之后做语义补充。Phase 2 上线后 Agent2 被策略 Agent 取代。
### 4.2 HINA Agent 的职责和 Prompt 模板
HINA Agent 遵循 cobol-test-benchmark.md 第3部的 Agent 边界设计。
**输入**: COBOL 源码 + 结构摘要
**输出**: JSON 格式的类型判定结果
```json
{
"category": "マッチング",
"subtype": "1:N",
"confidence": 0.95,
"method": "hybrid",
"features": ["MATCHING paragraph", "2 INPUT files", "KEY-BREAK processing"],
"required_tests": ["MT-N001", "MT-N002", "MT-N004", "MT-N005", "COM-N001"],
"strategy_params": {
"min_data_pairs": [3, 3],
"special_boundaries": ["不平衡: 主1件从N件", "空文件"],
"coverage_requirements": {"branch": 0.95, "paragraph": 1.0}
}
}
```
### 4.3 策略 Agent 的职责
```
输入:
- cobol_testgen 生成的基础数据(保证路径覆盖)
- HINA 类型 + 策略参数
- FieldTree(字段定义)
职责:
1. 字段语义补充
"PIC X(20) 字段名为 TX-MERCHANT"→ 商户名 → 需要空值/超长/特殊字符
"PIC X(16) 字段名为 TX-CARD-NO"→ 卡号 → 需要 Luhn校验/全零/格式化
2. 类型特有边界
匹配系 → 不平衡比(1件 vs N件)
键中断 → 键值变化序列
校验系 → 异常值矩阵
3. 日文数据
检测到 PIC N → 根据字段用途选择全角/半角/外字
输出:
complete_test_cases(向已有数据追加补充)
```
---
## 五、质量门禁
### 5.1 检查项
| 检查 | 阶段 | 方法 | 标准 | 不通过处置 | 可用阶段 |
|:-----|:-----|:-----|:-----|:----------|:---------|
| 决策点覆盖 | 执行前 | cobol_testgen 静态 | ≥95% | 增量补充(≤4次) | Phase 1 |
| 段落覆盖 | 执行前 | cobol_testgen 静态 | 100% | 增量补充 | Phase 1 |
| HINA 必须项 | 执行前 | 规则判定 | 100% | 增量补充 | Phase 2 |
| 字段覆盖 | 执行前 | 枚举检查 | 100% | 补充值 | Phase 2 |
| 语句覆盖 | 执行后 | gcov 动态 | 佐证 | 记录到报告 | Phase 3 |
| 分支覆盖(动态) | 执行后 | gcov 动态 | 佐证 | 记录到报告 | Phase 3 |
### 5.2 HINA 必须项判定规则
HINA_CHECK_RULES 中的每条规则需要定义明确的判定函数和依赖:
```python
HINA_CHECK_RULES = {
"COM-A002": {
"description": "全部0件",
"depends_on": "file_mapping", # 需要知道哪些文件是输入文件
"check": "any(empty for each INPUT file)",
"note": "所有类型通用"
},
"MT-N001": {
"description": "1:1 主键完全匹配",
"depends_on": "file_mapping", # 需要文件→FD→方向映射
"check": "len(file_a) >= 1 and len(file_b) >= 1 and all_match(...)",
"note": "匹配系特有"
},
# ... 其他必须项
}
```
**文件映射逻辑**: 门禁需要知道哪些 FD 是 INPUT、哪些是 OUTPUT,才能判断"全部0件"。这个信息来自 `extract_structure().open_directions`
### 5.3 质量评分公式(COBOL 版)
```
质量评分 = 覆盖质量 × 0.6 + 边界质量 × 0.4
覆盖质量 = 段落覆盖率 × 0.5 + 分支覆盖率 × 0.5
例: (1.0 × 0.5 + 0.92 × 0.5) = 0.96
边界质量 = HINA 必须项覆盖率
例: 10/10 = 1.0
总评分 = 0.96 × 0.6 + 1.0 × 0.4 = 0.976 → 98/100
```
---
## 六、增强报告
```
字段比对(原有):
BR-AMT: PASS (COBOL=1500.00, Java=1500.00)
覆盖率:
├── 覆盖率方式: ✅ 静态+动态 / 🟡 仅静态
├── 段落覆盖率: 100% (12/12) ✅
├── 分支覆盖率(静态): 96% (24/25) → 1个未覆盖
├── 分支覆盖率(动态): 已执行 ✅(佐证)
├── 语句覆盖率(动态): 已执行 ✅(佐证/或 不可用)
├── 决策点覆盖率: 96% (24/25) → 1个未覆盖
└── 交叉验证: gcov 确认执行 ✅
HINA 信息(Phase 2+:
├── 判定类型: マッチング(1:N) — 確信度 95%
├── 判定方法: Agent (关键字+混淆组)
└── ◎必须项: 10/10 覆盖 ✅
质量评分(Phase 2+:
├── 覆盖质量: 96/100
├── 边界质量: 100/100
└── 总评分: 97/100 ✅ PASS
重试历史:
├── heal_retry: 1 (编译修复)
├── simple_retry: 0
├── quality_retries: 0
└── 最终状态: PASS
```
---
## 七、分层重试
### 7.1 部署位置
分层重试部署在 **orchestrator.py 调用者层**(在 main.py 和 worker.py 中),而不是在 orchestrator 内部。
```
worker.py: orchestrator.py:
result = retry_handler.run( run_pipeline(...)
lambda: run_pipeline(...) ↑ 失败时返回状态码
)
↑ 根据状态码决定重试策略 不负责重试
retry_handler 的责任:
1. 匹配已知失败模式 → 修复后 heal_retry
2. 未知原因 → simple_retry
3. 超出上限 → FATAL
```
**分层重试不依赖 Phase 2/3 的组件,可在 Phase 1 部署。**
### 7.2 重试层级
```
失败 → 匹配已知模式?
├── 编译失败 (COBCPY路径/方言不匹配) → 修复后 heal_retry +1
├── S0C7 (数值字段含非数值) → 数据补零后 heal_retry +1
├── 文件 OPEN 失败 → 检查 JCL/DD 后 heal_retry +1
├── HINA 判定低確信度 → Agent 重判定后 heal_retry +1
├── gcov 数据异常 → 重新编译插桩后 heal_retry +1
└── 其他 → simple_retry +1
累计判断:
heal_retry > 2 → HEAL_FAILED(降级,报告标注)
simple_retry > 3 → RETRY_EXHAUSTEDFATAL
total_retry > 6 → FATAL
```
---
## 八、阻断状态与用户操作指南
### 8.1 阻断状态一览
| 条件 | 状态 | 对用户的影响 | 用户操作路径 |
|:-----|:-----|:------------|:------------|
| gcov 不可用 | ⚠️ 降级(继续) | 报告标记"仅静态" | 不需要操作。覆盖率以静态分析为准 |
| 质量门禁 4 次后仍未通过 | ⚠️ QUALITY_WARN(继续) | 报告包含未覆盖分支清单 | 查看报告中的未覆盖清单 → 补充测试数据覆盖缺失的分支 → 重新运行 |
| HINA Agent 確信度 < 70% | 🔴 阻断 | 命令行提示 "HINA 判定不确定,请指定类型"。候选类型列表随提示输出 | CLI: `--hina-type "マッチング"` 手动指定。Web: 待实现 |
| LLM API 超时 | ⚠️ 降级(继续) | Agent1/Agent3 降级。覆盖率/HINA 信息为 unknown | 检查 API 连接后重试 |
| cobol_testgen 路径枚举超 | ⚠️ 降级(继续) | 覆盖率标记"可能不完整" | 评估是否适合此程序的大路径数。可忽略 |
### 8.2 覆盖率展示规则(Phase 1-4 分阶段)
覆盖率在报告中按可用数据分阶段展示,避免展示不准确的数据造成误导:
| Phase | 报告展示 | 示例 | 说明 |
|:------|:---------|:-----|:------|
| Phase 1 | 总分支数 + 已生成记录数 + 不可计算 | `总分支: 25 / 记录: 15 / 覆盖率: ⏳ 需要 gcov` | 不展示百分比 |
| Phase 2 | 同上 + HINA 必须项数 | `HINA 必须项: 10/10 ✅` | 覆盖质量独立展示 |
| Phase 3 | 同上 + gcov 行覆盖率 | `行覆盖率(gcov): 92%` | 只展示 gcov 实际数据 |
| Phase 4 | 完整评分 | `总评分: 97/100` | 汇总所有维度 |
### 8.3 阻断后的恢复流程
```
HINA Agent 確信度 < 70% → 阻断
├── CLI 用户:
│ 查看提示的候选类型列表
│ 重新运行: python main.py --cobol-src ... --hina-type "マッチング"
│ 指定后跳过 Agent 判定,直接使用指定类型
├── Web 用户(待实现):
│ 页面显示 "类型判定失败,请选择正确的程序类型"
│ 下拉框显示候选类型 → 选择后自动继续
└── 不确定类型:
参考 cobol-test-benchmark.md 第1部的关键字识别表
按 PROGRAM-ID 命名规则、FILE-CONTROL 中的文件数、PROCEDURE DIVISION 中的段落名判断
QUALITY_WARN(不阻断,但覆盖率不足):
├── 查看报告中的未覆盖决策点清单
├── 针对每个未覆盖 ID,在源码中找到对应的 IF/EVALUATE 条件
├── 补充覆盖该条件的测试数据
└── 重新运行验证
```
---
## 九、实施步骤
```
Phase 1 (P0): cobol_testgen 集成 + Agent2 保留 + 分层重试
├── 暴露 extract_structure() + generate_data()+incremental_supplement()
├── 修改 orchestrator.py 插入路径覆盖
├── Agent2 保留做语义补充
├── 质量门禁(初步,仅决策点+段落维度,≥90%)
└── hina/retry.py 分层重试部署
Phase 2 (P1): HINA Agent + 策略 Agent
├── hina/classifier.py (HINA Agent)
├── hina/strategy.py (策略模板 + 策略 Agent)
├── hina/gate.py (质量门禁 + HINA 必须项)
├── Agent2 替换为策略 Agent
└── 优先覆盖: 匹配系 > 键中断 > 内部表 > 条件分支 > 校验系
Phase 3 (P2): 动态覆盖
├── CobolRunner 新增编译参数
├── hina/gcov_collector.py
└── 交叉验证
Phase 4 (P2): 增强报告
├── report/generator.py 增强(覆盖率/HINA/质量评分)
├── 质量评分公式(依赖 Phase 2 的 HINA 数据,之前显示"待集成")
└── 重试历史展示
```