Files

8.6 KiB
Raw Permalink Blame History

generate_report_tool 入参 Schema(权威参考)

依据 code-review-graph 源码 code_review_graph/scoring.py::build_report_datarender_markdown_report 反推的精确约定。任何偏离都会导致报告静默丢内容。

1. 顶层键

工具从 review_data dict 中只读取以下键(scoring.py:620-633):

类型 默认值 作用
scope str "change-level" 审查范围
tier str "standard" 审查档位
timestamp str "" 生成时间
files str "" 审查文件(逗号分隔字符串,兼容字段)
reviewed_files list[str] [] 本轮审查文件数组;报告顶部以可折叠列表(details/summary)展示,缺省回退 files
baseline str "generic" git 基线 SHA
verdict str "❌ FAIL" 结论,"PASS""FAIL"
quality_score int/float None PR 质量分
counts dict {} 严重度统计
metrics dict {} 客观指标(值必须是 dict
findings list[dict] [] 问题清单
manual_review list[str] [] 人工复核项
llm_judged list[str] [] 保留兼容字段,一律置空;不再新增 LLM 判定指标
summary str "" 摘要(仅 HTML 渲染)

2. findings 条目字段(scoring.py:645-658

工具对每条 finding 做如下映射:

data["issues"].append({
    "severity": f.get("severity", "minor"),
    "category": f.get("category", ""),
    "message": f.get("summary", f.get("message", "")),   # summary 优先,其次 message
    "location": f"{f.get('path','')}:{f.get('line','')}"  # 仅当 line 非空
                if f.get("line") else str(f.get("path","")),
    "confidence": f.get("confidence"),
    "fix": f.get("fix", ""),
})
字段 说明 若不传会怎样
path 文件路径 line 合成 location;仅传 path 也可显示路径
line 行号 line 为空则 location 只有 path(无 :行号
message 问题描述 缺失 → 报告只剩类别/位置
summary 问题描述(优先级高于 message 同上
fix 修复建议 缺失 → 无修复建议段
severity blocker/major/minor(也接受 critical/warn/informational 默认 minor
category business/security/data 默认空
confidence int 1-10 缺失则不显示置信度

3. metrics 结构(scoring.py:636-643

metrics 的值必须是 dict,每项支持 grade/value/note/evidencenote 必传(透传 score_review_tool 返回的 note/evidence),否则报告"说明"列为空。

"metrics": {
  "sql_risk": {"value": 0, "grade": "good", "note": "全部参数化查询,无注入风险。"},
  "exception_coverage": {"value": 0, "grade": "fail", "note": "Rust Result 误报。"}
}

MD 报告显示标签来自硬编码映射:sql_risk→SQL 注入风险、exception_coverage→异常分支覆盖、redundancy_rate→代码冗余率、high_risk_density→高风险场景密度、vulnerability_risk→漏洞风险。其他指标名直接显示原名。指标表应仅含上述五个客观指标(指标集约束见 SKILL.md Step 4),禁止手工注入 requirement_coverage/logic_alignment/llm_trust_boundary/shell_injection/enum_completeness 等 LLM 判定指标;也不要混入 blast_radius/objective_grade 等键——build_report_data 会按五指标白名单过滤,非五指标键一律丢弃。

4. counts 说明(scoring.py:727-732

MD 报告的问题统计行只读 counts.criticalcounts.informational

f"- **问题统计**{counts.get('critical', 0)} 严重 · {counts.get('informational', 0)} 次要"

因此若想统计正确,counts 需用 critical/informational 键(或将 major/minor 数量合入)。

4b. coverage 字段(Step 7.5 G3,引擎 v2.5.0

review_data.coverage 直接透传 coverage_tool 返回值全部字段(不要手挑子集,否则计数字段渲染 0/0 或 N/A):

字段 说明
coverage_pct 全库覆盖(已深读文件数 / 全部源文件数,文件数口径);gate="line+unit"feature)时为 None
high_risk_coverage_pct 高风险覆盖(已深读高风险文件数 / 信号点名文件数,文件数口径);gate="line+unit"feature)时为 None
grade good/warn/fail
deep_read_count / total_files 已深读数 / 总源文件数
high_risk_total_files / high_risk_deep_count 高风险文件数 / 已深读高风险数
deep_read_weight / total_weight 已深读权重 / 总权重(兼容保留,仅用于排序参考)
target_reached / target 门禁结果 / 高风险目标值(gate="both" 时需全库 ≥85% 且 高风险 ≥95% 才 Truestandard=85/95
overall_target / high_risk_target 双目标值:全库 85% / 高风险 95%(报告据此分别显示)
gate 门禁口径(high_risk/overall/both/both+line/line+unit
remaining_files_to_target 距全库目标还差多少文件数(驱动补轮的主字段
remaining_weight_to_target 距目标还差多少权重(兼容保留)
priority_deep_read_files 按风险权重降序的待深读文件([{path, weight}]
uncovered_files 未深读文件清单(G1
silent_files 静默文件清单(G2 抽检源)
note 引擎口径说明

增量:coverage_tool(include_prior=True) 合并跨轮索引 .code-review-graph/coverage-index.json 中 SHA 未变的已深读文件。报告后必须 save_coverage_index_tool 写索引供下轮复用。

4b-1. feature(单功能)审查:gate="line+unit"

feature 覆盖度门禁只保留行级覆盖 + 单元覆盖,不做全库/高风险文件数覆盖检查:

"coverage": {
  "gate": "line+unit",
  "coverage_pct": null,
  "high_risk_coverage_pct": null,
  "line_coverage_pct": 100.0,
  "unit_coverage_pct": 100.0,
  "line_gap_files": [],
  "unit_gap_files": [],
  "target_reached": true
}
  • coverage_pct / high_risk_coverage_pctnull预期行为(不做文件数覆盖检查),勿误判失败。
  • target_reached 只由行覆盖 ≥95% + 单元完整性无缺口决定。
  • 报告 ## 覆盖度 区块只渲染行/单元覆盖与状态行,不渲染全库/高风险行。
  • 必须同时传 reviewed_files(本轮深读文件数组),报告顶部以可折叠列表展示。

5. 完整可复制模板

{
  "verdict": "PASS",
  "scope": "feature",
  "target": "EVM",
  "tier": "standard",
  "timestamp": "2026-08-06T15:24:47",
  "files": "server/src/api/evm_api.rs, server/src/services/evm_service.rs",
  "baseline": "f4235d00008a0de651ad8988adc1bca27ede1fb2",
  "quality_score": 7.5,
  "counts": {"blocker": 0, "major": 3, "minor": 5},
  "metrics": {
    "sql_risk": {"value": 0, "grade": "good", "note": "全部参数化查询,无注入风险。"}
  },
  "findings": [
    {
      "path": "server/src/services/workflow_service.rs",
      "line": 111,
      "severity": "major",
      "category": "business",
      "confidence": 8,
      "message": "progressive 模式下 EV 计算依赖 workflow_states.completion_percentage,更新后未失效 EVM 缓存,5 分钟 TTL 内显示过期数据。",
      "fix": "在 update_state / create_state / delete_state 中调用 EvmService::invalidate_evm_cache(project_id, None)。"
    }
  ],
  "manual_review": [
    "list_evm_cases 无 data_scope 是否为有意设计(需产品/权限负责人确认)"
  ],
  "summary": "发现 3 个 major 与 5 个 minor。SQL 全部参数化无注入风险,无 blocker,结论 PASS。"
}

6. 错误用法 → 现象对照表

错误用法 代码示例 现象
issues {"issues": [...]} 问题清单(0,条目全丢
finding 用 title/detail {"title": "...", "detail": "..."} 只剩类别+位置,描述/修复为空
传合并 location {"location": "a.rs:5"} 位置为空(工具只认 path+line)
metrics 传扁平标量 "sql_risk": 0 指标表空(要求 dict
counts 用 major/minor {"counts":{"major":3}} MD 统计行显示 0 严重·0 次要

7. 生成后自检清单(Step 8.5)

生成报告后必须打开 .md 验证:

  • ## 问题清单(NN == findings 条数,且 > 0
  • 每条 issue 同时含描述 + 位置(`path:line`+ 修复建议
  • 若任一缺失 → 修正 review_data 字段后重新调用 generate_report_tool 覆盖