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

43 KiB
Raw Permalink Blame History

COBOL 迁移验证平台 第二阶段设计书

版本: v2.0 | 日期: 2026-06-19 基于: cobol-test-benchmark.md 的 33+2 程序类型分类体系 范围: 12 个 Phase,从类型判定引擎完善到完整测试基准实现


目录

  1. 设计总则
  2. Phase 1: extract_structure 输出扩展
  3. Phase 2: 混淆组判定规则引擎
  4. Phase 3: 确信度 4 因子计算
  5. Phase 4: 33+2 种程序类型 COBOL 测试样本
  6. Phase 5: 参数化测试数据生成引擎
  7. Phase 6: 日文测试数据生成查找表
  8. Phase 7-10: 类型别测试套件
  9. Phase 11: 完整类型判定管道
  10. Phase 12: 文档更新
  11. 依赖关系与分工矩阵
  12. 接口变更一览
  13. COBOL 覆盖率测试体系
  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

# 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__.pyextract_structure() 返回字典中追加:

# 新增字段(原有字段不变)
{
    # ── 文件相关 ──
    "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.pyparse_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 接口变更

# 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 混淆组规则

# 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 矛盾检测

# 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 回溯机制

# 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 接口变更

# 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

# 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 接口变更

# 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 覆盖率,定位虚假覆盖

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 注释:
      * ==== 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 类型专属参数化

# 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 通用数据生成工具

# 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 接口变更

# 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(项目根目录,独立文件)

# 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 接口变更

# 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 测试模板

# 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-N001012, AM-N001008
test_division.py 50/25/100 分割 + 余数 + 不足 + OPEN失败 + 命名 9 S-N001007, S-A001002
test_csv_conversion.py 无换行/有换行/引用符/空項目/超长 8 CF-N001006, CF-A001002

8.4 Phase 8 测试矩阵

测试文件 覆盖内容 测试项数 对应文档
test_sort_merge.py SORT升/降/多键/稳定/INPUT/OUTPUT PROCESS + MERGE 16 SR-N001010, MR-N001003
test_call_search.py CALL字面量/动态/USING/IS INITIAL/嵌套 + SEARCH ALL 20 C-N001009, T-N001007

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 管道流程

# 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 输出格式

{
    "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

# 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 更新内容

## 测试预期(更新版)

| 维度 | 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 汇总

# 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 扩展)

# 1. 扩展 read.py — 添加 SELECT organization 和 OPEN 模式检测
# 2. 扩展 core.py — 添加 DIVIDE/INSPECT/STRING 检测、PERFORM 分类、IF 统计、变量模式、主循环
# 3. 更新 __init__.py __all__

对于 D(规则引擎 + 确信度 + 管道)

# 1. 创建 hina/rule_engine/ — 8 混淆组规则(独立命名函数)
# 2. 创建 hina/confidence.py — 四因子计算
# 3. 创建 hina/pipeline/ — 完整管道编排
# 4. 修改 orchestrator.py — 替换 HINA 分类步骤

对于 CCOBOL 样本 + 测试)

# 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(日文处理 + 文档)

# 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 中列出的公开函数有类型注解