# generate_report_tool 入参 Schema(权威参考) > 依据 `code-review-graph` 源码 `code_review_graph/scoring.py::build_report_data` > 与 `render_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 做如下映射: ```python 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`/`evidence`。**`note` 必传**(透传 `score_review_tool` 返回的 note/evidence),否则报告"说明"列为空。 ```json "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.critical` 和 `counts.informational`: ```python 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% 才 True;standard=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 覆盖度门禁**只保留行级覆盖 + 单元覆盖**,不做全库/高风险文件数覆盖检查: ```json "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_pct` 为 `null` 是**预期行为**(不做文件数覆盖检查),勿误判失败。 - `target_reached` 只由行覆盖 ≥95% + 单元完整性无缺口决定。 - 报告 `## 覆盖度` 区块只渲染行/单元覆盖与状态行,不渲染全库/高风险行。 - 必须同时传 `reviewed_files`(本轮深读文件数组),报告顶部以可折叠列表展示。 ## 5. 完整可复制模板 ```json { "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` 验证: - [ ] `## 问题清单(N)`,N == findings 条数,且 > 0 - [ ] 每条 issue 同时含描述 + 位置(`` `path:line` ``)+ 修复建议 - [ ] 若任一缺失 → 修正 `review_data` 字段后重新调用 `generate_report_tool` 覆盖