Files
cobol-java-v3/docs/phase2-design.md
hangshuo652 bc1d56d1a4 feat: Phase 2 complete — 13 Phases of COBOL type classification and test benchmark
P0.6: gcov infrastructure
P1: extract_structure output expansion (11 new feature fields)
P2: Confusion group rule engine (8 pairs + contradiction + backtrack)
P3: 4-factor confidence calculation + quality gate update
P4: 33+2 COBOL program type test samples (22 files, 7 categories)
P5: parametrized/ test data generation engine
P6: japanese_data.py lookup tables
P7-10: Type-specific test suites (~159 parametrized tests)
P11: Full classification pipeline (classify_program) + orchestrator integration
P12: Documentation (module-interfaces, test-plan v3.0, coverage-matrix)

Architecture decisions:
- classification_pipeline/ merged to hina/pipeline/
- parametrized/ as independent module
- japanese_data.py as root-level file
- hina/__all__ only exports classify_program()

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-19 23:51:55 +08:00

1240 lines
43 KiB
Markdown
Raw Permalink 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 迁移验证平台 第二阶段设计书
> 版本: v2.0 | 日期: 2026-06-19
> 基于: cobol-test-benchmark.md 的 33+2 程序类型分类体系
> 范围: 12 个 Phase,从类型判定引擎完善到完整测试基准实现
---
## 目录
1. [设计总则](#1-设计总则)
2. [Phase 1: extract_structure 输出扩展](#2-phase-1-extract_structure-输出扩展)
3. [Phase 2: 混淆组判定规则引擎](#3-phase-2-混淆组判定规则引擎)
4. [Phase 3: 确信度 4 因子计算](#4-phase-3-确信度-4-因子计算)
5. [Phase 4: 33+2 种程序类型 COBOL 测试样本](#5-phase-4-332-种程序类型-cobol-测试样本)
6. [Phase 5: 参数化测试数据生成引擎](#6-phase-5-参数化测试数据生成引擎)
7. [Phase 6: 日文测试数据生成查找表](#7-phase-6-日文测试数据生成查找表)
8. [Phase 7-10: 类型别测试套件](#8-phase-7-10-类型别测试套件)
9. [Phase 11: 完整类型判定管道](#9-phase-11-完整类型判定管道)
10. [Phase 12: 文档更新](#10-phase-12-文档更新)
11. [依赖关系与分工矩阵](#11-依赖关系与分工矩阵)
12. [接口变更一览](#12-接口变更一览)
13. [COBOL 覆盖率测试体系](#13-cobol-覆盖率测试体系)
14. [架构审核决议汇总](#14-架构审核决议汇总)
---
## 1. 设计总则
### 1.1 新增 Phase 0.6: gcov 基础设施
> 在 Phase 1 之前完成,为所有类型测试提供 gcov 能力。
> 负责: F | 工作量: 3h
为覆盖率测试体系提供可自动化运行的基础设施。Phase 7-10 中所有 gcov 测试的前置条件。
| 步骤 | 内容 | 工作量 |
|:-----|:-----|:------|
| 1 | `cobc --coverage` 环境验证自动化 | 0.5h |
| 2 | `collect_gcov()` 路径修复(含中文目录兼容)| 1h |
| 3 | `Config` 追加 gcov_enabled / gcov_work_dir / gcov_threshold | 0.5h |
| 4 | `test_gcov_basic.py` — gcov 全链路验证测试 | 1h |
**验收**: cobc --coverage 编译 → 运行 → .gcda 生成 → collect_gcov() line_rate > 0
```python
# config/__init__.py — Config 新增字段
gcov_enabled: bool = False
gcov_work_dir: str = ".gcov_output"
gcov_threshold: float = 0.5
```
### 1.3 分层原则
```
Layer 1: data/ — 所有模块共享的数据契约
Layer 2: 核心引擎 — cobol_testgen/ config/ jcl/ quality/ report/ preprocessor/
Layer 3: 业务引擎 — hina/ agents/ comparator/ runners/
Layer 4: 管道集成 — orchestrator/ web/
依赖方向: Layer 1 ← Layer 2 ← Layer 3 ← Layer 4
禁止逆向依赖。
```
### 1.4 模块通信规则
- 所有模块间通信通过 `data/` 层的数据类进行
- 每个模块的公开 API 由 `__init__.py``__all__` 定义
- 禁止钻入模块内部(如 `from cobol_testgen.coverage import ...`
- 详见 `CONTRIBUTING.md`
### 1.5 最终模块布局(经架构审核确认)
```
项目根目录/
├── cobol_testgen/ ← COBOL 解析引擎 (P1扩展)
├── hina/
│ ├── rule_engine/ ← 混淆组规则引擎 (P2)
│ ├── confidence.py ← 确信度 4 因子计算 (P3)
│ └── pipeline/ ← 完整类型判定管道 (P11)
├── parametrized/ ← 独立模块!参数化测试数据生成引擎 (P5)
│ ├── __init__.py
│ ├── matching.py
│ ├── division.py
│ └── common.py
├── japanese_data.py ← 独立文件!日文测试数据查找表 (P6)
├── test-data/cobol/ ← 新增 33+2 种 COBOL 样本 (P4)
├── tests/
│ └── parametrized/ ← 类型别测试套件 (P7-10)
└── docs/ ← 文档更新 (P12)
重要决策:
✅ classification_pipeline/ → 合并到 hina/pipeline/
✅ parametrized/ → 独立模块(项目根目录)
✅ japanese_data.py → 独立文件(项目根目录)
```
---
## 2. Phase 1: extract_structure 输出扩展
### 2.1 目的
当前 `extract_structure()` 输出的结构特征不足以判定 33+2 种程序类型。需要增加以下字段。
### 2.2 新增输出字段
`cobol_testgen/__init__.py``extract_structure()` 返回字典中追加:
```python
# 新增字段(原有字段不变)
{
# ── 文件相关 ──
"select_files": { # SELECT 语句列表
"INFILE": {"assign_to": "INPUT.DAT", "organization": "SEQUENTIAL"},
"OUTFILE": {"assign_to": "OUTPUT.DAT", "organization": "SEQUENTIAL"},
},
"open_directions_detail": { # OPEN 方向详情
"INFILE": "INPUT",
"OUTFILE": "OUTPUT",
"WORKFILE": "I-O",
},
# ── DIVIDE 语句检测 ──
"has_divide": False, # 是否有 DIVIDE 语句
"divide_constants": [], # DIVIDE 的被除数列表: [50, 25, 100]
# ── INSPECT/STRING 语句检测 ──
"has_inspect": False, # 是否有 INSPECT 语句
"has_string": False, # 是否有 STRING 语句
# ── PERFORM 模式分类 ──
"perform_patterns": [ # 每个 PERFORM 的模式
{"type": "inline", "target": None, "condition": None}, # inline / paragraph / thru / varying / times
{"type": "varying", "target": "WS-I", "condition": "WS-I > 100"},
{"type": "times", "times": 50},
{"type": "until", "condition": "WS-A > 5"},
{"type": "thru", "target": "PARA-A", "thru": "PARA-C"},
],
# ── 主循环定位(含 READ 语句的 PERFORM 块)──
"main_loop": { # 主循环信息(None=无循环)
"type": "perform_until", # perform_until / perform_varying / read_loop
"read_file": "INFILE", # 在该循环中 READ 的文件
"has_at_end": True, # 是否有 AT END 处理
"at_end_action": "MOVE 'Y' TO WS-EOF", # AT END 处理内容
},
# ── IF 分支类型统计 ──
"if_types": {
"total": 3, # IF 总数
"comparison": 2, # 比较型 (>, <, >=, <=)
"equality": 1, # 等值型 (=)
"compound": 1, # 复合型 (AND/OR)
"nested_depth": 2, # 最大嵌套深度
},
# ── 变量命名模式检测 ──
"variable_patterns": {
"has_prev_key": True, # WS-PREV-* 模式变量
"has_accumulator": True, # WS-*CNT / WS-*SUM 模式变量
"has_error_field": False, # WS-ERR* / WS-MSG* 模式变量
"has_key_field": True, # WS-*KEY 模式变量
"prev_key_fields": ["WS-PREV-KEY"], # 具体的前键值字段名
"accumulator_fields": ["WS-REC-CNT"], # 具体的累加器字段名
},
# ── OPEN 模式 ──
"open_pattern": "sequential", # sequential / reopen(OPEN→CLOSE→再OPEN)
}
```
### 2.3 实现位置
| 新增特征 | 实现文件 | 实现方法 |
|:---------|:---------|:---------|
| SELECT 文件详情 | `read.py``parse_file_control()` 扩展 | 追加 organization 字段 |
| DIVIDE/INSPECT/STRING | `core.py` `_BrParser` | 添加 IF 语句解析 |
| PERFORM 模式分类 | `core.py` `_BrParser` | BrPerform 属性已存在 |
| 主循环定位 | `core.py` 新函数 `locate_main_loop()` | 搜索含 READ 的 PERFORM 块 |
| IF 类型统计 | `core.py` 新函数 `stat_if_types()` | 遍历 BrIf 的 condition |
| 变量命名模式 | `core.py` 新函数 `detect_variable_patterns()` | 正则匹配字段名 |
| OPEN 模式 | `read.py` 新函数 `detect_open_pattern()` | 检查 OPEN→CLOSE→OPEN |
### 2.4 接口变更
```python
# cobol_testgen/__init__.py — __all__ 不变
# extract_structure() 签名不变,返回字典追加新字段
# 现有调用者不受影响(dict.get() 返回 None 获得默认值)
```
---
## 3. Phase 2: 混淆组判定规则引擎
### 3.1 新模块 `hina/rule_engine/`
创建独立子模块,与现有的 `classifier.py` 互补:
```
hina/
├── __init__.py # 导出 rule_engine 的 API
├── classifier.py # 现有(不变)
├── rule_engine/ # 新增
│ ├── __init__.py
│ ├── confusion_groups.py # 8 混淆组的规则实现
│ ├── contradiction.py # 矛盾检测
│ └── backtrack.py # 回溯机制
```
### 3.2 8 混淆组规则
```python
# hina/rule_engine/confusion_groups.py
def resolve_confusion_pair(features: dict, pair_name: str) -> dict:
"""解决一对混淆组,返回判定结果。
参数:
features — extract_structure() 输出的结构特征
pair_name — 混淆对名称:
"matching_vs_keybreak"
"dedup_vs_nodedup"
"validation_vs_keybreak"
"csv_merge_vs_split"
"simple_vs_two_stage"
"pure_vs_mixed"
"division_50_25_100"
"mn_output_mode"
返回:
{"resolved_type": str, "confidence": float, "evidence": list}
"""
# 规则实现示例 ── "matching_vs_keybreak"
def _matching_vs_keybreak(features: dict) -> dict:
"""匹配 vs key切
判定逻辑:
1. SELECT 文件数 < 2 → 排除匹配 → key切
2. IF 类型统计中 3 路 IF(comparison) 占比 > 50% → 匹配
3. 2 路 IF(equality) 为主 + WS-PREV-KEY 存在 → key切
4. 有累加器(WS-*CNT) + WS-PREV-KEY + 2 路 IF → key切
5. 输入文件 ≥ 2 + 3 路 IF → 匹配
6. 无法确定 → 回退到 conflict_score
"""
file_count = len(features.get("select_files", {}))
if_types = features.get("if_types", {})
var_patterns = features.get("variable_patterns", {})
evidence = []
if file_count >= 2:
evidence.append("file_count>=2 → possible matching")
comp_ratio = if_types.get("comparison", 0) / max(if_types.get("total", 1), 1)
if comp_ratio > 0.5:
evidence.append("comparison IF ratio > 50% → matching signature")
if var_patterns.get("has_prev_key") and var_patterns.get("has_accumulator"):
evidence.append("WS-PREV-KEY + accumulator → keybreak signature")
# 综合判断
matching_score = sum(1 for e in evidence if "matching" in e)
keybreak_score = sum(1 for e in evidence if "keybreak" in e)
if matching_score > keybreak_score:
return {"resolved_type": "マッチング", "confidence": 0.7 + matching_score * 0.1,
"evidence": evidence}
elif keybreak_score > matching_score:
return {"resolved_type": "キーブレイク", "confidence": 0.7 + keybreak_score * 0.1,
"evidence": evidence}
else:
return {"resolved_type": "unknown", "confidence": 0.5, "evidence": evidence}
```
### 3.3 矛盾检测
```python
# hina/rule_engine/contradiction.py
# 7 个矛盾对
CONTRADICTION_PAIRS = [
("matching_vs_keybreak", {
"type_a": "マッチング",
"type_b": "キーブレイク",
"rule": lambda f: f.get("variable_patterns", {}).get("has_prev_key"),
"tiebreaker": "file_count", # file_count ≥ 2 → matching wins
}),
("dedup_vs_nodedup", {
"type_a": "項目チェック(重複含む)",
"type_b": "項目チェック(重複含まず)",
"rule": lambda f: f.get("variable_patterns", {}).get("has_prev_key"),
"tiebreaker": "prev_key_exists", # WS-PREV-KEY → 含重复 wins
}),
("validation_vs_keybreak", {
"type_a": "項目チェック",
"type_b": "キーブレイク",
"rule": lambda f: f.get("variable_patterns", {}).get("has_error_field"),
"tiebreaker": "has_error_field", # WS-ERR* → 校验 wins; WS-*CNT → key切 wins
}),
# ... 其余 4 个
]
def detect_contradictions(features: dict, candidates: list[str]) -> list[dict]:
"""检测候选类型中的矛盾对,返回矛盾列表。"""
def resolve_contradiction(features: dict, contradiction: dict) -> str:
"""使用 tiebreaker 规则解决单个矛盾。"""
```
### 3.4 回溯机制
```python
# hina/rule_engine/backtrack.py
class BacktrackResolver:
"""当混淆组判定进入死胡同时,回溯到 extract_structure 重新提取特征。"""
def __init__(self, structure_extractor: callable):
self.extract = structure_extractor
self.max_rounds = 3
def resolve(self, cobol_source: str, initial_features: dict) -> dict:
"""多轮判定。每轮检测矛盾→回溯→重新提取→重新判定。"""
features = initial_features
for round_num in range(self.max_rounds):
# Step 1: 检测矛盾
contradictions = detect_contradictions(features, candidates)
if not contradictions:
# 无矛盾,返回最终结果
return self._finalize(features)
# Step 2: 解析矛盾
for c in contradictions:
resolution = resolve_contradiction(features, c)
# Step 3: 如果需要更多信息,回溯重新提取
if self._needs_backtrack(contradictions):
refined_source = self._refine_extraction(cobol_source, contradictions)
features = self.extract(refined_source)
return self._finalize_with_warning(features)
```
### 3.5 接口变更
```python
# hina/__init__.py — __all__ 追加
"resolve_confusion_pair", # (features, pair_name) → dict
"detect_contradictions", # (features, candidates) → list[dict]
"BacktrackResolver", # class — 多轮判定
```
---
## 4. Phase 3: 确信度 4 因子计算
### 4.1 新函数
`hina/classifier.py` 中新增确信度计算函数,或者创建 `hina/confidence.py`
```python
# hina/confidence.py — 新增文件
def compute_confidence_v2(
keyword_result: dict, # detect_keyword() 的输出
structure_features: dict, # extract_structure() 的输出
contradictions: list[dict], # contradiction.detect_contradictions() 的输出
resolution: dict # confusion_groups 的输出
) -> dict:
"""四因子确信度计算。
公式:
confidence = base × context_factor × consistency_factor × structure_factor
参数:
keyword_result — {matches: [(category, confidence, keyword)], ...}
structure_features — extract_structure 输出的完整字典
contradictions — 矛盾列表
resolution — 混淆组解决结果
返回:
{
"confidence": float, # 最终确信度 (0~1)
"base": float, # 基础确信度
"context_factor": float, # 上下文因子
"consistency_factor": float, # 一致性因子
"structure_factor": float, # 结构一致性因子
"judgment": str, # "auto" / "review" / "manual" / "impossible"
"needs_review": bool,
}
"""
```
### 4.2 因子定义
```
基础确信度:
L1 关键字规则对应的基准确信度 (0.70~0.99)
DB操作=0.95, SORT=0.95, CALL=0.90, 编辑输出=0.80, ...
上下文因子:
关键字匹配数 ≥ 3 → 1.0
关键字匹配数 = 2 → 0.95
关键字匹配数 = 1 → 0.90
需要上下文确认 → 0.50
一致性因子:
无矛盾 → 1.0
有矛盾已解决 → 0.90
有矛盾未解决 → 0.80
多重矛盾 (≥3) → 0.50
结构一致性因子:
结构完全匹配 (5/5 特征一致) → 1.0
部分一致 (3-4/5) → 0.7
少量一致 (1-2/5) → 0.5
无法确定 → 0.3
综合判定:
≥ 90% → 自动判定 ("auto")
70-89% → 自动判定 + 建议 Review ("review")
50-69% → Agent 提案 + 人工确认 ("manual")
< 50% → 判定不可,全部人工 ("impossible")
```
### 4.3 接口变更
```python
# hina/__init__.py — __all__ 追加
"compute_confidence_v2", # 四因子确信度计算
"compute_confidence", # 已有函数保持不动(旧版调用者不受影响)
```
### 4.4 质量门禁公式更新(gcov 集成)
Phase 0.6 完成后,`hina/gate.py` 的评分公式改为双模式:
```
当前(gcov 未启用):
quality_score = branch_rate×0.5 + paragraph_rate×0.5 + confidence×0.4
新增 quality_score_v2gcov 启用时):
quality_score_v2 = static_cov×0.3 + gcov_cov×0.4 + confidence×0.3
```
- 静态覆盖率 30% — 快速参考,验证数据生成完整性
- gcov 动态覆盖率 **40%** — 权重最高,代表真实执行结果
- HINA 确信度 30%
**新增文件**: `coverage/compare_coverage.py` — 对比静态与 gcov 覆盖率,定位虚假覆盖
```python
def compare_coverage(program_name: str) -> dict:
"""返回 {static, dynamic, gap, misleading_branches}"""
```
---
## 5. Phase 4: 33+2 种程序类型 COBOL 测试样本
### 5.1 目录结构
```
test-data/cobol/ # 已有 HINA001~101 保留
├── HINA001.cbl # 已有
├── ...
├── HINA101.cbl # 已有
├── category_matching/ # 匹配系 (10种)
│ ├── MT01_1TO1.cbl
│ ├── MT02_1TON.cbl
│ ├── MT03_NTO1.cbl
│ ├── MT16_TWO_STAGE_1TO1.cbl
│ ├── MT17_TWO_STAGE_NTO1.cbl
│ ├── MT18_MN_TO_M.cbl
│ ├── MT19_MN_TO_N.cbl
│ ├── MT20_MN_TO_MXN.cbl
│ ├── MT32_MIXED_SAME_KEY.cbl
│ └── MT33_MIXED_DIFF_KEY.cbl
├── category_sort/ # SORT/ MERGE (2种)
│ ├── ST01_SORT.cbl
│ └── ST02_MERGE.cbl
├── category_division/ # 分割系 (3种)
│ ├── DV01_DIVIDE_50.cbl
│ ├── DV02_DIVIDE_25.cbl
│ └── DV03_DIVIDE_100.cbl
├── category_validation/ # 校验 (1种,补充)
│ ├── VL01_CHECK_WITH_DUP.cbl
│ └── VL02_CHECK_NO_DUP.cbl
├── category_csv/ # 文件转换 (3种)
│ ├── CV01_CSV_NO_NEWLINE.cbl
│ ├── CV02_CSV_WITH_NEWLINE.cbl
│ └── CV03_ASCII_EBCDIC.cbl
├── category_cics/ # online (1种)
│ └── CI01_CICS.cbl
└── category_db/ # DB操作 (1种,补充)
└── DB01_SELECT_UPDATE.cbl
```
### 5.2 样本规范
每个 COBOL 测试样本必须:
1. **可编译** — 用 `cobc -x -std=ibm-strict` 编译通过
2. **10-50 行** — 足够表达类型特征,不要过大
3. **包含关键特征** — 每种类型独有的关键字和结构模式
4. **有注释** — 开头的星号注释说明类型编号和名称
5. **HEADER 注释**:
```cobol
* ==== TYPE: MT01 マッチング(1:1) ====
* 特征: 2 输入文件 SELECT, IF KEY = 比较, 3路 IF, 无累加器
* BRANCHES: 4 (2 IFs), DECISIONS: 2
* SELECT COUNT: 2, OPEN COUNT: 2
```
### 5.3 实现顺序
按依赖关系分 3 批创建:
```
第一批 (Phase 4a): 匹配系 10 种 + SORT/MERGE 2 种
依赖: 这 12 个样本是 Phase 7-8 测试的基础
第二批 (Phase 4b): 分割系 3 种 + 校验 2 种 + 文件转换 3 种
依赖: 这 8 个样本是 Phase 7 测试的基础
第三批 (Phase 4c): CICS 1 种 + DB 1 种
依赖: 需要模拟器环境,可先做代码样本,延迟测试
```
---
## 6. Phase 5: 参数化测试数据生成引擎
### 6.1 独立模块 `parametrized/`(项目根目录)
```
项目根目录/
├── parametrized/ ← 独立!不是 cobol_testgen 的子模块
│ ├── __init__.py
│ ├── matching.py # 匹配系数据生成
│ ├── sort.py # SORT 数据生成
│ ├── division.py # 分割系数据生成
│ ├── validation.py # 校验系数据生成
│ ├── csv_conversion.py # CSV→FB 数据生成
│ └── common.py # 通用工具
依赖方向:
parametrized/ → cobol_testgen (需要 PIC 解析算边界值)
parametrized/ → data/ (构造 Field/TestCase 对象)
cobol_testgen → parametrized ❌ 禁止
```
**理由**parametrized/ 的输入是数值参数(记录数、匹配率、不平衡比),不是 COBOL 源码。放在 cobol_testgen/ 下会使 COBOL 解析引擎依赖测试工具。独立模块保持分层干净。
### 6.2 类型专属参数化
```python
# cobol_testgen/parametrized/matching.py
def generate_matching_data(
matching_type: str, # "1:1" / "1:N" / "N:1"
record_count_r01: int,
record_count_r02: int,
key_match_ratio: float = 1.0, # 匹配率(用于剩余件测试)
imbalance_ratio: float = 1.0, # 不平衡比
) -> tuple[list[dict], list[dict]]:
"""生成匹配系测试数据。
返回:
(主文件记录列表, 从件记录列表)
文件间通过 KEY 字段关联。
"""
def generate_keybreak_data(
group_count: int, # key 组数
records_per_group: int, # 每组件数
sum_type: str = "accumulate", # "accumulate" / "aggregate" / "mark"
) -> list[dict]:
"""生成 key 切测试数据。
返回:
按 KEY 分组的数据,组间 KEY 值变化触发中断。
"""
# cobol_testgen/parametrized/division.py
def generate_division_data(
division_type: int, # 50 / 25 / 100
record_count: int, # 总件数(整数倍/余数/不足)
) -> list[list[dict]]:
"""生成分割系测试数据。
返回:
按分割文件分组的记录列表:
[[文件1的记录], [文件2的记录], ...]
文件数 = ceil(record_count / division_type)
"""
```
### 6.3 通用数据生成工具
```python
# cobol_testgen/parametrized/common.py
def generate_zero_byte_file(path: str):
"""生成 0 字节空文件(VSAM 空 cluster 或顺序 0 字节)。"""
def generate_status_35_scenario(path: str):
"""STATUS 35 场景:不生成文件,让 OPEN 找不到 DD。"""
def generate_minimal_records(fields: list[Field]) -> list[dict]:
"""各文件生成 1 条正常记录。"""
def generate_boundary_values(field: Field) -> dict:
"""从 PIC 解析 S9(7)V99 → 生成 max/min/溢出值。"""
def generate_sorted_records(fields: list[Field], record_count: int) -> list[dict]:
"""按 ASCENDING/DESCENDING KEY 生成已排序序列。"""
def generate_duplicate_keys(records: list[dict], key_field: str) -> list[dict]:
"""同键值追加 ≥2 件。"""
```
### 6.4 接口变更
```python
# cobol_testgen/__init__.py — __all__ 追加(parametrized 是独立模块,非子包)
from parametrized import (
generate_matching_data, # 匹配系数据
generate_keybreak_data, # key切数据
generate_division_data, # 分割系数据
generate_zero_byte_file, # 空文件
generate_boundary_values, # 边界值
)
```
---
## 7. Phase 6: 日文测试数据生成查找表
### 7.1 新文件 `japanese_data.py`(项目根目录,独立文件)
```python
# japanese_data.py
# ── 查找表 ──
FULLWIDTH_KATAKANA = "アイウエオカキクケコサシスセソタチツテト..."
FULLWIDTH_HIRAGANA = "あいうえおかきくけこさしすせそたちつてと..."
FULLWIDTH_DIGITS = "0123456789"
FULLWIDTH_ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
HALFWIDTH_KATAKANA = "アイウエオカキクケコサシスセソタチツテト..."
SJIS_5C_PROBLEM = ["", "", ""] # Shift-JIS 第2字节 0x5C
SJIS_7C_PROBLEM = ["", ""] # Shift-JIS 第2字节 0x7C
WAREKI_BOUNDARIES = [
# (元号, 西历开始年, 和历开始, 西历最后日, 和历最后日)
("令和", 2019, "R010501", None, None),
("平成", 1989, "H010108", "2019/04/30", "H310430"),
("昭和", 1926, "S611231", "1989/01/07", "S640107"),
("大正", 1912, "T011231", "1926/12/25", "T151225"),
("明治", 1868, "M451229", "1912/01/29", "M450129"),
]
# ── 生成函数 ──
def generate_fullwidth_text(field: Field) -> str:
"""PIC N 字段 → 全角文字填充。"""
def generate_halfwidth_katakana(field: Field) -> str:
"""PIC X 字段 → 半角假名填充。"""
def generate_sjis_5c_problem(field: Field) -> str:
"""生成含 5C 问题文字的字符串。"""
def generate_sjis_7c_problem(field: Field) -> str:
"""生成含 7C 问题文字的字符串。"""
def generate_wareki_date(wareki_type: str) -> str:
"""生成和历日期字符串。"""
def generate_wareki_boundary(era: str) -> tuple[str, str]:
"""生成指定元号的边界日期对(末日 → 初日)。"""
def generate_encoding_test_data(
from_encoding: str,
to_encoding: str,
) -> tuple[bytes, bytes]:
"""生成编码转换测试数据(EBCDIC→SJIS→UTF-8 三段)。"""
def select_data_type(field: Field) -> str:
"""选择数据类型: PIC N → 日文 / PIC 9 → 数值 / PIC X → 半角"""
```
### 7.2 接口变更
```python
# cobol_testgen/__init__.py — __all__ 追加
"generate_fullwidth_text",
"generate_halfwidth_katakana",
"generate_wareki_date",
```
---
## 8. Phase 7-10: 类型别测试套件
### 8.1 测试文件清单
```
tests/
├── parametrized/
│ ├── test_matching.py # 匹配系 ~15 测试 (Phase 7)
│ ├── test_division.py # 分割系 ~9 测试 (Phase 7)
│ ├── test_csv_conversion.py # 文件转换 ~8 测试 (Phase 7)
│ ├── test_sort_merge.py # SORT/MERGE ~16 测试 (Phase 8)
│ ├── test_call_search.py # CALL/SEARCH ~20 测试 (Phase 8)
│ ├── test_crosscutting.py # 横跨功能 ~70 测试 (Phase 9)
│ └── test_japanese.py # 日文处理 ~31 测试 (Phase 10)
```
### 8.2 测试模板
```python
# tests/parametrized/test_matching.py
"""匹配系深度测试 — 基于 cobol-test-benchmark.md Type 01-03, 16-20, 32-33"""
import pytest
from cobol_testgen.parametrized import generate_matching_data
@pytest.mark.parametrize("r01,r02,match_ratio", [
(10, 10, 1.0), # MT-N001: 1:1 完全匹配
(1, 100, 0.0), # MT-N009: 1:N 极端不平衡
(100, 1, 0.0), # MT-N010: N:1 极端不平衡
])
def test_matching_basic(r01, r02, match_ratio):
"""MT-N001~003: 1:1 / 1:N / N:1 基本匹配"""
main_recs, sub_recs = generate_matching_data(
matching_type="1:1",
record_count_r01=r01,
record_count_r02=r02,
key_match_ratio=match_ratio,
)
assert len(main_recs) == r01
assert len(sub_recs) == r02
```
### 8.3 Phase 7 测试矩阵
| 测试文件 | 覆盖内容 | 测试项数 | 对应文档 |
|:---------|:---------|:--------:|:---------|
| `test_matching.py` | 1:1/1:N/N:1 + 不平衡 + 键重复 + 未排序 + 高级匹配 | 20 | MT-N001~012, AM-N001~008 |
| `test_division.py` | 50/25/100 分割 + 余数 + 不足 + OPEN失败 + 命名 | 9 | S-N001~007, S-A001~002 |
| `test_csv_conversion.py` | 无换行/有换行/引用符/空項目/超长 | 8 | CF-N001~006, CF-A001~002 |
### 8.4 Phase 8 测试矩阵
| 测试文件 | 覆盖内容 | 测试项数 | 对应文档 |
|:---------|:---------|:--------:|:---------|
| `test_sort_merge.py` | SORT升/降/多键/稳定/INPUT/OUTPUT PROCESS + MERGE | 16 | SR-N001~010, MR-N001~003 |
| `test_call_search.py` | CALL字面量/动态/USING/IS INITIAL/嵌套 + SEARCH ALL | 20 | C-N001~009, T-N001~007 |
### 8.5 Phase 9 测试矩阵 (横跨功能)
| 测试文件 | 覆盖内容 | 测试项数 | 对应文档 |
|:---------|:---------|:--------:|:---------|
| `test_crosscutting.py` | 可变长入出力(11) + 循环处理(10) + 数值精度(12) + 日期(18) + 排他(4) + RERUN(4) + 性能(4) | 63 | VL/LP/NP/D/EX/RR/PV |
### 8.6 Phase 10 测试矩阵 (日文)
| 测试文件 | 覆盖内容 | 测试项数 | 对应文档 |
|:---------|:---------|:--------:|:---------|
| `test_japanese.py` | PIC N全角(5) + 半角假名(5) + 外字(6) + 5C/7C(4) + 编码转换(8) + 全角空格(3) | 31 | J-N/K/G/D/X/S |
---
## 9. Phase 11: 完整类型判定管道
### 9.1 新模块 `hina/pipeline/`
```
hina/
├── rule_engine/ # 混淆组规则 (P2)
├── confidence.py # 确信度计算 (P3)
├── pipeline/ # 完整类型判定管道 (合并自 classification_pipeline/)
│ ├── __init__.py
│ └── pipeline.py # 管道编排
```
### 9.2 管道流程
```python
# hina/pipeline/pipeline.py
def classify_program(cobol_source: str) -> dict:
"""完整程序类型判定管道。
流程:
1. 并行执行:
a. 关键字识别 (detect_keyword) — 11 类 L1 关键字
b. 结构提取 (extract_structure) — 全部特征
2. 关键字确信度 ≥ 90% → 直接输出类型
DB操作/SORT/MERGE/online 等高确信度独占类型)
3. 关键字 50-89% → 进入混淆组判定
a. 结构解析 (PERFORM模式/主循环/IF分支)
b. 8 混淆组规则引擎
c. 4 因子确信度计算
d. 矛盾检测 → 有矛盾则回溯
4. 关键字 < 50% → Agent 辅助判定
a. classify_with_llm() 调用
b. LLM 返回建议类型
c. 规则引擎验证 LLM 结果
5. 输出最终判定 JSON
"""
```
### 9.3 输出格式
```python
{
"program_name": "HINA005",
"category": "condition_heavy", # 混淆组
"subtype": "simple_if", # 具体类型
"type_code": "05", # 33+2 中的编号
"method": "keyword", # keyword / rule_engine / agent
# ── 确信度详情 ──
"confidence": 0.92,
"confidence_detail": {
"base": 0.95,
"context_factor": 1.0,
"consistency_factor": 0.9,
"structure_factor": 1.0,
},
# ── 判定依据 ──
"evidence": [
"EXEC SQL → DB操作 (keyword, 95%)",
"SELECT count=1, OPEN count=1",
"IF branches=2, decisions=1",
"No contradictions detected",
],
# ── 是否需要 Review ──
"needs_review": False,
# ── 测试策略建议 ──
"testing_strategy": {
"required_tests": 5,
"coverage_target": "branch",
"supplement_strategy": "incremental",
},
}
```
### 9.4 集成到 orchestrator
```python
# orchestrator.py — 替换现有的 HINA 分类步骤
def run_pipeline(cfg: Config, ...) -> VerificationRun:
# ... 现有代码 ...
# ── 类型判定(替换现有 HINA 步骤) ──
from hina/pipeline import classify_program
classification = classify_program(cobol_src_text)
vr.hina_type = classification["category"]
vr.hina_confidence = classification["confidence"]
vr.debug["classification"] = classification
# 如果确信度 < 50%,标记为人工处理
if classification["confidence"] < 0.5 and classification["needs_review"]:
vr.quality_warn = f"类型判定确信度过低({classification['confidence']:.0%}),建议人工确认"
# ... 后续代码不变 ...
```
---
## 10. Phase 12: 文档更新
### 10.1 更新文件
| 文件 | 更新内容 |
|:-----|:---------|
| `docs/module-interfaces.md` | 追加 hina/pipeline 模块接口;追加 parametrized 子模块接口;更新 hina 模块接口(rule_engine, confidence_v2 |
| `docs/test-plan.md` → v3.0 | 追加 33+2 程序类型覆盖行;追加类型别测试矩阵;追加横跨功能测试行;追加日文测试行;更新总测试数预期(412 → 600+) |
| `docs/cobol-coverage-matrix.md` | 追加程序类型覆盖行;追加测试基准覆盖行;更新覆盖率目标 |
### 10.2 测试计划 v3.0 更新内容
```markdown
## 测试预期(更新版)
| 维度 | v2.0 | v3.0 追加 | v3.0 总计 |
|:-----|:----:|:---------:|:---------:|
| L0 单元测试 | 280 | +50 (参数化引擎) | 330 |
| L1 类型测试 | 0 | +80 (Phase 7-8) | 80 |
| 横跨功能测试 | 0 | +70 (Phase 9) | 70 |
| 日文测试 | 0 | +31 (Phase 10) | 31 |
| 非功能测试 | 6 | +10 | 16 |
| 已有回归 | 112 | — | 112 |
| **总计** | **412** | **+241** | **~653** |
```
---
## 11. 依赖关系与分工矩阵
### 11.1 Phase 依赖图
```
Phase 1 (特征提取) ──→ Phase 2 (规则引擎) ──→ Phase 3 (确信度)
│ │ │
│ └────────┬───────────────┘
│ │
│ ▼
│ Phase 11 (hina/pipeline)
│ │
▼ ▼
Phase 5 (parametrized/) Phase 4 (COBOL样本)
│ │
└────────┬──────────────────┘
Phase 7-10 (测试套件)
Phase 12 (文档)
```
### 11.2 并行执行阶段
```
可以完全并行:
Phase 1 (A) + Phase 4 (C) + Phase 5 (A) + Phase 6 (B)
Phase 2 (D) + Phase 4b (C)
Phase 7-8 (F/G) + Phase 9 (F/G) + Phase 10 (B)
测试执行阶段 (所有人可并行写自己的测试)
需要串行:
Phase 1 → Phase 2 → Phase 3 → Phase 11 (D 负责全链路)
Phase 4 → Phase 7-8 (需要样本才能测试)
Phase 5 → Phase 7-10 (需要参数化引擎才能生成测试数据)
```
### 11.3 分工矩阵
| 开发者 | Phase | 模块 | 工作量 |
|:-------|:------|:-----|:-------|
| **A** | 1, 5 | cobol_testgen 扩展 + parametrized | 3 天 |
| **B** | 6, 10, 12 | japanese_data + 日文测试 + 文档 | 2 天 |
| **C** | 4, 7 | 33+2 COBOL 样本 + 匹配/分割测试 | 3 天 |
| **D** | 2, 3, 11 | rule_engine + confidence + pipeline | 4 天 |
| **E** | 6, 10 | japanese_data + 日文测试、LLM 提示词优化 | 2 天 |
| **F** | 8, 9 | SORT/MERGE/CALL/SEARCH + 横跨功能 | 3 天 |
| **G** | 0.6, 8 | gcov 基础设施 + SORT/MERGE/SEARCH 测试 | 3 天 |
| **H** | 4c, 11 集成 | CICS/DB 样本 + orchestrator 集成 | 2 天 |
### 11.4 总工时估算
| Phase | 内容 | 人日 |
|:------|:-----|:----:|
| P1 | extract_structure 扩展 | 1.5 |
| P2 | 混淆组规则引擎 | 2.0 |
| P3 | 确信度 4 因子 | 1.0 |
| P4 | 33+2 COBOL 样本 | 2.0 |
| P5 | 参数化数据生成 | 2.0 |
| P6 | 日文数据生成 | 1.0 |
| P7 | 匹配/分割/CSV 测试 | 1.5 |
| P8 | SORT/MERGE/CALL/SEARCH 测试 | 1.5 |
| P9 | 横跨功能测试 | 2.5 |
| P10 | 日文测试 | 1.5 |
| P11 | 类型判定管道 | 2.0 |
| P12 | 文档 | 1.0 |
| | **总计** | **~19.5 人日** |
---
## 12. 接口变更一览
### 12.1 向后兼容(现有代码不受影响)
| 变更 | 类型 | 说明 |
|:-----|:-----|:------|
| `extract_structure()` 返回追加字段 | ✅ 兼容 | 现有调用用 `dict.get()`,新字段不出现时返回 None |
| `compute_confidence()` 保留 | ✅ 兼容 | 新增 `compute_confidence_v2()` 并行存在 |
| `orchestrator.py` 导入路径修改 | ✅ 兼容 | 已改为模块顶层导入 |
| `__init__.py``__all__` | ✅ 兼容 | 只是显式声明已有接口 |
### 12.2 非兼容(需同步更新调用者)
| 变更 | 类型 | 如何处理 |
|:-----|:-----|:---------|
| `hina/__init__.py` 新增 `__all__` | ⚠️ 通知 | 仅影响 `from hina import *` 用户(无此类代码)|
| `cobol_testgen/__init__.py` 新增 `__all__` | ⚠️ 通知 | 仅影响 `from cobol_testgen import *` 用户(无此类代码)|
| `orchestrator.py` 导入从 `from x.y import z` 改为 `from x import z` | ⚠️ 通知 | 已在本次修改中同步更新 |
### 12.3 新增公开 API 汇总
```python
# parametrized/ __all__(新增独立模块):
"generate_matching_data" # Phase 5
"generate_keybreak_data" # Phase 5
"generate_division_data" # Phase 5
"generate_boundary_values" # Phase 5
# japanese_data.py(新增独立文件):
from japanese_data import generate_fullwidth_text, generate_halfwidth_katakana, generate_wareki_date
# hina __all__ 追加:
"resolve_confusion_pair" # Phase 2
"detect_contradictions" # Phase 2
"BacktrackResolver" # Phase 2
"compute_confidence_v2" # Phase 3
"classify_program" # Phase 11 — hina.pipeline.pipeline.classify_program
```
---
## 附录:快速开始指南
### 对于 Acobol_testgen 扩展)
```bash
# 1. 扩展 read.py — 添加 SELECT organization 和 OPEN 模式检测
# 2. 扩展 core.py — 添加 DIVIDE/INSPECT/STRING 检测、PERFORM 分类、IF 统计、变量模式、主循环
# 3. 更新 __init__.py __all__
```
### 对于 D(规则引擎 + 确信度 + 管道)
```bash
# 1. 创建 hina/rule_engine/ — 8 混淆组规则(独立命名函数)
# 2. 创建 hina/confidence.py — 四因子计算
# 3. 创建 hina/pipeline/ — 完整管道编排
# 4. 修改 orchestrator.py — 替换 HINA 分类步骤
```
### 对于 CCOBOL 样本 + 测试)
```bash
# 1. 创建 test-data/cobol/category_matching/ — 10 个匹配系样本
# 2. 创建 test-data/cobol/category_sort/ — SORT/MERGE 样本
# 3. 创建 tests/parametrized/test_matching.py
# 4. 驱动测试: python -m pytest tests/parametrized/test_matching.py
```
### 对于 B(日文处理 + 文档)
```bash
# 1. 创建 japanese_data.py(项目根目录)— 查找表 + 生成函数
# 2. 创建 tests/parametrized/test_japanese.py
# 3. 更新 docs/module-interfaces.md
# 4. 更新 docs/test-plan.md → v3.0
```
---
## 13. COBOL 覆盖率测试体系 — 与各 Phase 的集成
> 覆盖率测试不是独立章节,而是贯穿多个 Phase 的基础设施。
> 已在 Phase 1.1Phase 0.6)中新增 gcov 基础设施。
> 以下列出覆盖率的其他部分的分布位置:
| 覆盖率内容 | 所在 Phase | 说明 |
|:-----------|:----------|:------|
| gcov 基础设施(环境验证 + collect_gcov 修复 + Config 字段 + 全链路测试)| **Phase 0.6** (1.1节) | F 负责,3h |
| 质量门禁公式更新(quality_score_v2+ 静态 vs 动态对比报告 | **Phase 3** (4.4节) | 新增 gcov 权重 40% |
| 各类型 gcov 验证测试(约 15 个) | **Phase 7-10** | 每个类型群至少 1 条 gcov 测试 |
| orchestrator gcov_enabled 集成 | **Phase 11** (9.5节) | 连接 Config → orchestrator → gate.py |
### 13.1 覆盖率目标
**模块覆盖率(pytest --cov:**
| 模块 | 目标 |
|:-----|:----:|
| cobol_testgen/* | ≥ 90% |
| hina/* | ≥ 85% |
| comparator/* | ≥ 85% |
| runners/* | ≥ 70% |
| orchestrator.py | ≥ 85% |
**程序覆盖率(gcov 验证,各类型群最低 line_rate):**
| 类型群 | 门槛 | 理由 |
|:-------|:----:|:------|
| 条件分支(IF/EVALUATE) | ≥ 70% | 分支密集,应高覆盖 |
| 匹配系 | ≥ 60% | 至少覆盖关键 IF 分支 |
| SEARCH ALL | ≥ 60% | 命中/未命中均需覆盖 |
| CALL | ≥ 60% | 主程序 + 子程序 |
| SORT | ≥ 50% | 大量 I/O,代码行不多 |
| 分割系 | ≥ 50% | 文件操作密集 |
| 编辑输出 | ≥ 50% | WRITE 语句需要实际输出 |
**静态 vs 动态差距**: 同类差距 ≤ 30%(超过说明静态分析不可靠)
> 门槛说明:基于 HINA 现有 10 个程序的 gcov 预测数据。
> 纯逻辑程序(IF/EVALUATE)可达 70%+I/O 密集程序(SORT/分割)约 50%。
> 上线后根据实测数据调整。
---
## 14. 架构审核决议汇总
> 来源: `/plan-eng-review` | 日期: 2026-06-19
### 14.1 审核决策
| 分类 | 决策 | 方案 | 结果 |
|:-----|:-----|:-----|:-----|
| 架构 | classification_pipeline/ 归属 | 合并到 hina/pipeline/ | ✅ 采纳 |
| 架构 | parametrized/ 归属 | 独立模块(项目根目录) | ✅ 采纳 |
| 架构 | japanese_data.py 归属 | 独立文件(项目根目录) | ✅ 采纳 |
| 架构 | orchestrator 过渡 | 并行开发,一次性替换 | ✅ 采纳 |
| 架构 | COBOL 样本兼容 | 不可编译类型用注释模拟关键字 | ✅ 采纳 |
| 代码质量 | 矛盾判定规则 | 独立命名函数取代 lambda | ✅ 采纳 |
| 测试 | 新模块单元测试 | 每个 Phase 包含自身测试 | ✅ 采纳 |
| 性能 | 回溯机制 | 加 30s 超时降级 | ✅ 采纳 |
### 14.2 NOT in Scope
| 项目 | 理由 |
|:-----|:------|
| CICS/DB 真实环境集成测试 | 需要大型机模拟器 |
| PySpark 完整管道验证 | Java 兼容性问题 |
| 多语言国际化(除日文外) | 33+2 类型未要求 |
| CI/CD 性能基准自动化 | 不属于 12 个 Phase |
### 14.3 实现任务
- [ ] **T1 (P1, human: ~2h)** — 扩展 extract_structure 新增 8 类特征
- [ ] **T2 (P2, human: ~3h)** — hina/rule_engine/ 8 混淆组(独立函数)
- [ ] **T3 (P3, human: ~1.5h)** — hina/confidence.py 4 因子确信度
- [ ] **T4 (P4, human: ~2.5h)** — test-data/cobol/ 33+2 样本
- [ ] **T5 (P5, human: ~2.5h)** — parametrized/ 数据生成引擎
- [ ] **T6 (P6, human: ~1h)** — japanese_data.py 日文查找表
- [ ] **T7 (P7-10, human: ~6h)** — 类型别测试套件 (~241 测试)
- [ ] **T8 (P11, human: ~2.5h)** — hina/pipeline/ 完整管道 + orchestrator 集成
- [ ] **T9 (P12, human: ~1h)** — 文档更新
### 14.4 总测试预期
```
现有: 428 测试
新增: ~60 (新模块自身单元测试)
新增: ~241 (类型别测试套件 P7-10)
总计: ~729 测试
```
### 14.5 并行策略
```
Lane A: P1 (cobol_testgen 扩展) → 独立
Lane B: P4 (COBOL 样本) → 独立,需先完成
Lane C: P5 (parametrized/) → 需要 cobol_testgen 的 PIC 解析
Lane D: P6 (japanese_data) → 独立
Lane E: P2 (rule_engine) → 需要 P1 的特征
└── P3 (confidence) → 需要 P2
└── P11 (pipeline) → 需要 P2+P3
Lane F: P7-10 (测试套件) → 需要 P4+P5+P6
└── P12 (文档) → 最后
启动顺序:
第 1 批 (并行): Lane A + Lane B + Lane D
第 2 批: Lane C (P1 完成 + 已有 data/) + Lane E (P1 完成)
第 3 批: Lane F (P4+P5+P6 完成)
最后: P12
```
---
## 15. 验收标准
> 所有 Phase 完成后,用以下标准验证是否达标。
| 编号 | 验收项 | 验证方法 | 关联 Phase |
|:-----|:-------|:---------|:-----------|
### 15.1 功能验收
| A01 | extract_structure() 返回包含全部 8 个新增字段 | pytest tests/cobol_testgen/ 全部通过 | P1 |
| A02 | 8 个混淆组规则各有 ≥ 2 个测试 | pytest tests/hina/ 覆盖 | P2 |
| A03 | 4 因子确信度的 4 个判定阈值各 ≥ 1 个测试 | pytest tests/hina/ 覆盖 | P3 |
| A04 | 33+2 个 COBOL 样本全部在 test-data/cobol/ 下 | ls test-data/cobol/category_*/ 共 35+ 文件 | P4 |
| A05 | parametrized/ 各生成函数有测试覆盖主要参数组合 | pytest tests/parametrized/ 全部通过 | P5 |
| A06 | japanese_data.py 生成函数返回正确格式 | pytest tests/parametrized/test_japanese.py | P6 |
| A07 | 类型测试套件 ≥ 200 个测试 | pytest --collect-only | P7-10 |
| A08 | hina/pipeline/ 的 3 条判定路径各有测试覆盖 | pytest tests/hina/ 模拟三种路径 | P11 |
| A09 | gcov 全链路验证测试通过 | pytest tests/test_gcov_basic.py | P0.6 |
| A10 | 质量门禁 gcov 模式下 quality_score_v2 工作 | pytest tests/hina/test_gate.py 覆盖 | P3 |
### 15.2 覆盖率验收
| 验收项 | 目标 | 验证方法 |
|:-------|:----:|:---------|
| 模块覆盖率(pytest --cov| ≥ 68% | pytest --cov=. |
| 核心管道覆盖率 | ≥ 85% | pytest --cov=cobol_testgen --cov=hina --cov=orchestrator |
| Python 测试总数 | ≥ 650 | pytest --collect-only -q |
| gcov 动态验证(可编译类型)| line_rate ≥ 50% | pytest tests/test_gcov_basic.py |
### 15.3 回归验收
- [ ] 所有现有测试通过: pytest tests/ --ignore=e2e/ -q → 0 failed
- [ ] 新增测试不降低现有覆盖率
- [ ] 所有 __all__ 中列出的公开函数有类型注解
---
---