mcpField
W
wk-code-review

wk-code-review

github.com/whalezhaoTesting & quality36 installs
Repository

About wk-code-review

A code-review skill for auditing changes in a single repository, with emphasis on Java and XML files. It creates plans and checkpoints, supports resumable batch reviews, and produces a deduplicated report across seven review dimensions.

Key features

  1. 01Review Java and XML changes
  2. 02Check seven code-review dimensions
  3. 03Create plans and per-batch files
  4. 04Resume work using progress checkpoints
  5. 05Merge and deduplicate findings into a report

Use cases

  1. 01Audit a branch against a base branch
  2. 02Review large changes in resumable batches
  3. 03Produce a consolidated report for code fixes

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/whalezhao/wk-code-review --skill wk-code-review

After installing, type/wk-code-reviewin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

README.md
references/
.DS_Store
java-specification_02.md
git-specification.md
error-code-specification.md
frontend-backend-conventions.md
java-specification_01.md
naming-specification.md
i18n-specification.md

Details

From the project README

WK Code Review Skill

自动模式判断

在执行任何确认步骤之前,先判断当前运行模式:

  • 读取最新一轮 system-reminder 中的 auto mode is active 标识

  • 或检查当前对话上下文中是否有 auto_mode、autonomous、continuous 等关键字

  • 若无法判断,按**手动模式(默认)**处理

  • Auto Mode:跳过所有用户确认步骤,直接执行审计

    • 不输出确认提示,不等待用户输入
    • Phase 0 使用默认输出目录:优先使用 {OUTPUT_DIR}/,若未定义则放到桌面 ~/Desktop/code-review/
    • Phase 1.5 直接检查并恢复/跳过
    • Phase 2.6 每批次完成后自动继续下一批次
  • 手动模式(默认):严格按流程执行,所有确认点生效

Skill 调用者有责任在调用时声明运行模式(auto_mode=true/false)。


目标

执行完整代码审计,覆盖七个维度:

  1. 规范审计 — 命名、日志、异常、事务、MyBatis、Spring、并发、MySQL、前后端交互规范
  2. 业务逻辑审计 — 验证业务规则实现、边界条件、错误处理完整性
  3. 方案合理性审计 — 评估架构设计、事务边界、数据一致性、方案选择
  4. 代码性能审计 — 评估代码性能、方案合理性、代码容错、安全兜底
  5. 可靠性审计 — MQ消费幂等、定时任务防重、分布式锁、资源泄漏、Istio/K8s场景
  6. 宕机恢复与逻辑接续审计 — 状态机完整性、可重入性、补偿机制、分布式事务边界(新增重点维度)

核心原则

⚠️ 强制要求:必须先生成审计计划文件,再决定是否执行审计。

  1. 审计计划文件必须实际写入磁盘 {OUTPUT_DIR}/<branch>-plan.md
  2. 每个Agent读取自己的计划文件和规范文件执行审计
  3. 每批次Agent完成后,更新主计划中的待合并结果文件列表
  4. 最终汇总所有Agent结果到完整审计报告

架构限制:本 Skill 仅支持单仓库场景。多仓库(monorepo 跨仓库或不同仓库的服务)需分别调用本 Skill,或使用 CI 层面的全局审计工具。


Phase 0:输出目录确认

⚠️ 必须在执行审计前确认输出目录,后续所有步骤均使用此目录。

使用 AskUserQuestion 工具询问用户:

请选择审计报告的输出目录(审计结果将保存至此目录):
选项路径说明
默认{OUTPUT_DIR}/此前习惯使用的目录
当前目录{当前git仓库根目录}/code-review/与代码同级的目录
自定义用户输入用户手动输入绝对路径
  • 手动模式:必须询问用户,等待用户选择后继续
  • Auto Mode:使用默认路径 {OUTPUT_DIR}/,不询问

目录命名建议:输出目录名建议包含分支名,如 {OUTPUT_DIR}/{branch-name}/。

确认后记录:OUTPUT_DIR 变量在本次审计会话中全程有效,后续所有 Phase 均引用此变量,不再重复询问。


Phase 0.5:预检查

执行以下命令获取上下文:

# 1. 获取当前分支(如果没有传入分支名,则取当前分支)
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
echo "当前分支: $CURRENT_BRANCH"

# 2. 获取基准分支(优先使用传入的 BASE_BRANCH,否则检测仓库默认分支)
BASE_BRANCH=${BASE_BRANCH:-$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||')}

# 3. 检查差异文件数
git diff --name-only ${BASE_BRANCH}...${BRANCH:-$CURRENT_BRANCH} 2>/dev/null | wc -l

# 4. 获取提交历史(理解需求背景)
git log ${BASE_BRANCH}..${BRANCH:-$CURRENT_BRANCH} --oneline -15

# 5. 获取变更统计
git diff --stat ${BASE_BRANCH}...${BRANCH:-$CURRENT_BRANCH}

无差异时:提示"当前分支与 ${BASE_BRANCH} 没有差异",终止审计。

参数说明:

  • ${BRANCH}:待审计分支名(可省略,默认当前分支)
  • ${BASE_BRANCH}:基准分支名(可省略,自动检测仓库默认分支,通常为 master/main)

Phase 1:生成主计划文件

1.1 统计变更文件
# 获取所有变更的Java和XML文件
# 注意:使用 ${BRANCH:-$CURRENT_BRANCH} 而非 HEAD,确保多批次执行时取到正确分支
git diff --name-only ${BASE_BRANCH}...${BRANCH:-$CURRENT_BRANCH} 2>/dev/null | grep -E '\.(java|xml)$'
1.2 筛选文件
必须审计的文件
  • 所有 *.java 文件(排除规则除外)
  • 所有 *Mapper.xml 文件
排除规则
模式说明是否计入审计
*Test.java / **/test/**测试类❌ 排除
**/generated/**生成代码❌ 排除
**/target/**编译产物❌ 排除
**/pom.xmlMaven配置❌ 排除
**/resources/META-INF/**Spring/META-INF配置❌ 排除
**/resources/application*.yml应用配置文件❌ 排除
**/resources/application*.properties应用配置文件❌ 排除
**/resources/static/**静态资源❌ 排除
**/resources/templates/**模板文件❌ 排除
**/resources/i18n/**国际化资源文件❌ 排除
**/resources/mapper/**/*.xmlMyBatis XML✅ 纳入审计(检查SQL注入、拼接)
**/resources/migration/**/*.sql数据库迁移脚本✅ 纳入审计(检查SQL质量、索引)

关于 YAML 配置文件:如本次变更涉及 application.yml / application.properties,不纳入审计范围(已在排除规则中)。配置合理性(如连接池大小、超时配置)属于运维层面,不在代码审计维度内。

1.3 生成主计划文件

输出位置:{OUTPUT_DIR}/<branch-name>-plan.md

使用 Write 工具创建主计划文件,内容包括:

  1. 统计信息表

    • 变更文件总数、Java文件数、XML文件数、应审计文件数
  2. 审计批次清单

    • 按模块/层级分组,每个批次的文件列表
  3. 执行步骤(按步骤确认)

  4. 待合并结果文件列表

    • 初始为空,每批次完成后动态追加
  5. 重点关注项

1.4 为每个Agent生成独立计划文件

输出位置:{OUTPUT_DIR}/<branch-name>-plan-<批次序号>-<批次名>.md

注意:批次名中不能包含 / 字符,避免文件系统路径问题。用 - 替代。

每个Agent计划文件必须包含:

  1. 本次批次的文件列表(完整路径)
  2. 需求背景(提交历史摘要)
  3. 规范文件列表(Agent 通过 rules 自动加载,无需手动读取;必要时可使用以下绝对路径作为参考)
  4. 审计维度说明
  5. 结果文件路径
1.5 输出计划摘要并等待确认(手动模式)
📋 审计计划已生成

分支:{branch-name}
变更文件:{total-files} 个
应审计:{to-audit-files} 个

审计批次:
  批次1:{name} ({n}个文件)
  批次2:{name} ({n}个文件)
  ...

执行步骤:
  Step 1: 批次1审计(启动{n1}个Agent)→ 更新待合并列表
  Step 2: 批次2审计(启动{n2}个Agent)→ 更新待合并列表
  Step 3: 汇总所有结果,生成最终报告
  Step 4: 输出摘要

计划文件:
  主计划:{OUTPUT_DIR}/{branch-name}-plan.md
  各批次:{OUTPUT_DIR}/{branch-name}-plan-*.md

请确认是否按此计划执行审计。

手动模式:只有用户确认后,才能进入 Phase 2 执行审计。 Auto Mode:跳过确认,直接进入 Phase 1.5。


Phase 1.5:中断检查与恢复

在执行 Phase 2 前,检查是否有未完成的审计:

# 检查是否存在进行中的审计状态文件
STATUS_FILE="{OUTPUT_DIR}/${BRANCH}-status.json"
PLAN_FILE="{OUTPUT_DIR}/${BRANCH}-plan.md"
RESULT_FILES=$(ls {OUTPUT_DIR}/${BRANCH}-result-*.json 2>/dev/null)

# 优先检查 status.json(最可靠的进度来源)
if [ -f "$STATUS_FILE" ]; then
  echo "发现历史审计状态文件"
  cat "$STATUS_FILE"
  # 解析 completed_batches 和 pending_batches 确定断点
elif [ -f "$PLAN_FILE" ]; then
  echo "未找到 status.json,但发现主计划文件,视为完全中断"
  # 无 status.json 但有 plan.md,从 Phase 1.5 恢复
fi

if [ -n "$RESULT_FILES" ]; then
  echo "发现历史结果文件:"
  echo "$RESULT_FILES"
fi

恢复场景:

  1. 完全中断:主计划存在但未任何 batch 完成

    • 手动模式:提示用户"发现未完成的审计计划,是否继续?"
    • Auto Mode:自动从 Phase 1.5 继续,从第一个未完成的批次开始
  2. 部分完成:某些 batch 已完成,但不是全部

    • 读取 status.json 的 completed_batches 和 pending_batches 数组
    • 跳过 completed_batches 中的批次
    • 从 pending_batches 的第一个批次继续执行
  3. 新审计:无任何历史审计文件

    • 正常开始新的审计流程

Phase 2:执行审计(按步骤执行)

Step 1-N:批次审计

每批次执行以下步骤:

2.1 检查进度
# 确认本批次尚未完成
BATCH_RESULT="{OUTPUT_DIR}/${BRANCH}-result-${BATCH_ID}-merged.json"
if [ -f "$BATCH_RESULT" ]; then
  echo "批次 ${BATCH_ID} 已完成,跳过"
  # 若在脚本上下文中:exit 0;若在交互上下文中:continue 到下一批次
fi
2.2 创建进度检查点

写入进度文件:{OUTPUT_DIR}/${BRANCH}-status.json

{
  "branch": "{branch-name}",
  "timestamp": "{current-time}",
  "phase": 2,
  "current_batch": {n},
  "total_batches": {total},
  "completed_batches": [{已完成批次}],
  "pending_batches": [{待执行批次}],
  "in_progress": true
}
2.3 启动Agent(每批次最多4个并行)

每个Agent执行:

  1. Read 计划文件
  2. Read 每个待审计文件的完整内容
  3. Bash git diff 获取代码变更
  4. 逐维度逐文件分析,对每个维度明确输出结论(有问题/无问题/不适用)
  5. 将结果写入JSON临时文件(必须遵守 JSON 安全规则,见本模板末尾「JSON 输出安全规则」章节)
  6. 使用 Read 工具重新读取JSON文件,确认格式正确
  7. 使用 python3 -c "import json; json.load(open('文件路径'))" 验证JSON合法性,若失败则修复后重新验证

⚠️ 逐维度强制要求:

对批次的每个文件,必须按以下顺序逐维声明:

维度必须声明
A. 规范审计有/无问题(子类型见 Agent 计划模板 A 节)
B. 业务逻辑有/无问题(子类型见 Agent 计划模板 B 节)
C. 方案合理性有/无问题(子类型见 Agent 计划模板 C 节)
D. 性能有/无问题(子类型见 Agent 计划模板 D 节)
E. 可靠性(Istio/K8s)有/无问题(子类型见 Agent 计划模板 E 节)
F. 宕机恢复与逻辑接续有/无问题(重点审计,子类型见 Agent 计划模板 F 节)
G. 安全审计有/无问题(子类型见 Agent 计划模板 G 节)

维度审计详细清单:各维度的具体检查项(如 A 节的 MyBatis/日志/异常规范、F 节的 FMEA 追问清单等)见下方「Agent 计划文件模板」→「审计维度」章节。Agent 生成计划文件时需将对应维度内容写入计划。

⚠️ 不得跳维度:每个文件必须对 A-G 七个维度逐一声明结论,不能只输出有问题的维度。

⚠️ F维度特别提醒:宕机恢复审计是本次新增的重点维度。审计时必须追问:

  • "如果在这行代码之后JVM宕机,会发生什么?"
  • "重启后这条消息会被重新投递吗?业务逻辑能否正确处理?"
  • "跨系统的两阶段操作(DB+MQ、DB+OSS、MQ+外部服务)是否有补偿机制?"

Agent异常处理:

  • Agent 应在执行过程中每处理 5 个文件后保存一次中间结果
  • 如果 Agent 崩溃,下次恢复时应检查中间结果并从断点继续
  • 使用结果文件命名约定:result-<batch>-<agent-id>-checkpoint-{n}.json
  • 检查点恢复逻辑:重启 Agent 时,检查是否存在 result-<batch>-<agent-id>-checkpoint-*.json,找到最大序号的检查点,读取已完成文件列表,跳过这些文件,从下一个文件开始审计。审计完成后合并所有检查点结果。
2.4 监控进度
  • 使用 TaskList 查看任务状态
  • 超时时间动态计算:超时(min) = max(5, min(文件数 / 2, 20))(最少5分钟,最多20分钟)
  • 每 1 min 检查一次是否有 Agent 超时或异常
2.5 合并批次结果

本批次所有 Agent 完成后:

  1. JSON 合法性校验与修复(在去重合并之前,必须先确保所有 Agent 结果文件格式正确)

    • 对每个 Agent 的结果文件执行 python3 -c "import json; json.load(open('文件路径'))" 校验
    • 若校验通过:进入去重合并流程
    • 若校验失败:使用以下修复流程
      1. 用 Bash 执行 python3 脚本定位损坏位置:

        python3 -c "
        import json, sys
        try:
            json.load(open('${RESULT_FILE}'))
            print('JSON_VALID')
        except json.JSONDecodeError as e:
            print(f'JSON_ERROR: line={e.lineno}, col={e.colno}, msg={e.msg}')
        "
        
      2. 用 Read 工具读取文件,定位损坏行附近的字段

      3. 常见损坏模式及修复方法:

        损坏模式原因修复方法
        字段值中出现了未配对的双引号 "问题代码或描述中的双引号未转义将字段值中的双引号替换为单引号或 \"
        文件中出现了实际的换行符(非\n字面量)描述或宕机后果字段包含实际换行将实际换行替换为 \n 字面量
        \\ 后紧跟非转义字符反斜杠未双重转义补充为 \\\\
        字段值末尾缺少引号引号被内容中的 " 提前关闭找到并转义内容中多余的 "
      4. 修复后重新执行校验,直到通过

      5. 若同一文件修复 3 次仍未通过,标记该 Agent 结果为异常,按 场景4:Agent 返回空结果 处理

  2. 批次内去重(同一 Agent 内)

    • 按 文件路径 + 行号 + 维度 + 问题类型 去重
    • 保留严重程度最高的问题(CRITICAL > WARNING > SUGGESTION)
  3. 批次间去重(同一批次不同 Agent 间)

    • 读取该批次所有 Agent 的结果文件
    • 按 文件路径 + 行号 + 维度 + 问题类型 去重
    • 同一个问题多个 Agent 发现时,保留 CRITICAL > WARNING > SUGGESTION
  4. 合并到批次结果文件

    • 写入 {OUTPUT_DIR}/${BRANCH}-result-${BATCH_ID}-merged.json
    • 写入后必须再次执行 python3 JSON 校验,确认合并结果文件合法
  5. 立即更新进度检查点(必须在合并文件写入后立即执行,顺序不可颠倒)

    {
      "...": "...",
      "completed_batches": [..., {n}],
      "pending_batches": [{剩余批次}],
      "last_completed_at": "{timestamp}"
    }
    

    ⚠️ 顺序保证:步骤 3(合并文件写入)和步骤 4(status 更新)必须是原子操作。若 status 更新失败,下次恢复时步骤 2.1 会检测到 merged.json 已存在并跳过,status.json 的 pending_batches 不准确但无害。

⚠️ 注意:跨批次的全局去重统一在 Phase 3 执行,此处仅处理批次内和批次间去重。

2.6 更新主计划中的待合并列表

每批次完成并合并后:

  1. 更新主计划的待合并列表
  2. 追加本批次的合并结果文件路径
  3. 标记该批次为 ✅ 完成

手动模式:输出确认提示

✅ 批次{n}审计完成(共 {file-count} 个文件,{problem-count} 个问题)

本批次结果文件:
  - {OUTPUT_DIR}/{batch-name}-merged.json

已更新主计划待合并列表。
共 {total-n} 个结果文件待汇总。

是否继续下一批次?

Auto Mode:自动继续下一批次,不等待确认。

2.7 异常恢复策略

场景1:单个Agent失败

  • 记录失败 Agent 的文件列表
  • 启动备用 Agent 重新审计这些文件
  • 最多重试 2 次

场景2:整批次超时

  • 将该批次分解为更小的子批次(每个 3 文件)
  • 重新启动,每个子批次用 1 个 Agent

场景3:主进程中断

  • 下次恢复时自动检测进度检查点
  • 从上次未完成的批次开始

场景4:Agent 返回空结果

  • Agent 返回了结果但问题列表为空,视为异常
  • 检查 Agent 是否正确读取了所有文件内容
  • 启动备用 Agent 重新审计该批次所有文件
  • 如果连续2次空结果,则报告该批次审计异常,需人工介入
2.8 循环执行直到所有批次完成

重复 Step 1-N 直到所有批次完成

更新进度检查点为:

{
  "...": "...",
  "phase": 3,
  "in_progress": false,
  "completed_at": "{timestamp}"
}

Phase 3:汇总结果

3.1 执行全局去重脚本(关键步骤)

⚠️ 必须在生成报告前执行此步骤,否则会导致 KeyError。

  1. 使用 Bash 执行 Python 脚本(见下方 Phase 3.2)
  2. 脚本会:
    • 收集所有批次结果文件(*-result-*-merged.json)
    • 统一字段名(file/文件/path → 文件)
    • 全局去重
    • 按维度权重排序
    • 分配 ISS-{序号} ID
    • 生成 {OUTPUT_DIR}/{BRANCH}-result-all.json
3.2 全局去重 Python 脚本

必须执行此脚本:

cd {OUTPUT_DIR}
python3 << 'PYTHON_EOF'
import json
import glob
from collections import Counter

BRANCH = "{BRANCH}"

# 收集所有批次结果文件
merged_files = glob.glob(f"{BRANCH}-result-*-merged.json")
if not merged_files:
    print(f"未找到: {BRANCH}-result-*-merged.json")
    exit(1)

all_issues = []
for f in merged_files:
    with open(f, 'r', encoding='utf-8') as fp:
        data = json.load(fp)
        if isinstance(data, list):
            all_issues.extend(data)
        else:
            all_issues.extend(data.get("问题列表", data.get("issues", [])))

print(f"收集问题: {len(all_issues)} 个")

# 字段名标准化
for p in all_issues:
    p["文件"] = p.get("文件") or p.get("file") or p.get("path") or ""
    p["行号"] = str(p.get("行号") or p.get("line") or "")
    p["维度"] = p.get("维度") or p.get("dimension") or ""
    p["类型"] = p.get("类型") or p.get("type") or ""
    p["严重程度"] = p.get("严重程度") or p.get("severity") or "WARNING"

# 全局去重
seen = set()
deduped = []
for p in all_issues:
    key = (p["文件"], p["行号"], p["维度"], p["类型"])
    if key not in seen:
        seen.add(key)
        deduped.append(p)

print(f"去重后: {len(deduped)} 个")

# 统计涉及文件清单(按问题数降序,全部列出,不得截断)
SEV_ORDER = {"CRITICAL": 0, "WARNING": 1, "SUGGESTION": 2}
file_stats = {}
for p in deduped:
    f = p["文件"]
    if f not in file_stats:
        file_stats[f] = {"count": 0, "severities": []}
    file_stats[f]["count"] += 1
    file_stats[f]["severities"].append(p.get("严重程度", "WARNING"))

# 计算每个文件的最高严重程度
file_list = []
for f, stats in file_stats.items():
    # 取最高严重程度
    min_sev = min(stats["severities"], key=lambda s: SEV_ORDER.get(s, 1))
    file_list.append((f, stats["count"], min_sev))

# 按问题数降序
file_list.sort(key=lambda x: (-x[1], SEV_ORDER.get(x[2], 1)))
all_files_sorted = file_list

print(f"涉及文件: {len(all_files_sorted)} 个")

# 排序
DIM_ORDER = {"G": 0, "F": 1, "E": 2, "B": 3, "A": 4, "C": 5, "D": 6}
deduped.sort(key=lambda p: (
    next((v for k, v in DIM_ORDER.items() if k in p.get("维度", "")), 7),
    SEV_ORDER.get(p.get("严重程度", "WARNING"), 1),
    p.get("文件", "")
))

# 分配ID
for i, p in enumerate(deduped, 1):
    p["id"] = f"ISS-{i:03d}"

# 保存
result_all = {
    "问题列表": deduped,
    "文件清单": [{"文件": f, "问题数": c, "最高严重程度": s} for f, c, s in all_files_sorted]
}
with open(f"{BRANCH}-result-all.json", 'w', encoding='utf-8') as fp:
    json.dump(result_all, fp, ensure_ascii=False, indent=2)

print(f"保存到: {BRANCH}-result-all.json")

# 统计
sev = Counter(p.get("严重程度") for p in deduped)
print(f"总问题数: {len(deduped)}")
print(f"CRITICAL: {sev.get('CRITICAL', 0)}")
print(f"WARNING: {sev.get('WARNING', 0)}")
print(f"SUGGESTION: {sev.get('SUGGESTION', 0)}")
PYTHON_EOF
3.3 生成最终报告

⚠️ 前置步骤:必须先执行 Phase 3.2 的 Python 脚本生成 {OUTPUT_DIR}/{BRANCH}-result-all.json,然后从此文件读取已排序、去重、分配ID的问题列表。

⚠️ 强制要求:JSON 中的所有数据必须完整写入 .md 报告,不得遗漏任何一个问题。

result-all.json 是中间产物,在 Phase 3.6 会被清理删除。.md 报告是唯一最终产物,也是下游 review-bug-fix Skill 的唯一数据源。如果 JSON 中有问题没有写入 .md,该问题将永久丢失,无法恢复。

具体要求:

  • 问题列表 中的每一条问题,都必须出现在 .md 报告对应维度章节的表格中
  • 文件清单 中的每一个文件,都必须出现在 .md 报告的"涉及文件清单"表格中
  • 如果 Write 工具因内容过长无法一次性写入,必须分多次写入,直到全部问题写完
  • 分次写入策略:以维度章节(3.3.2~3.3.8)为天然分界点,每次 Write 至少完整写入一个维度章节(含该维度所有文件的所有问题),不得在表格中间断开。如需进一步拆分,按文件分组边界切分,确保每个文件的表格完整
  • 写完后执行 Phase 3.4 校验,确认 .md 中的 ISS 编号数量与 JSON 问题数完全一致

使用 Write 工具创建 {OUTPUT_DIR}/<branch-name>.md

报告按以下十一个部分组织,每个审计维度独立一章,章内先按严重程度排序,再按文件分组。同一文件的问题归入同一个文件节点下。全部问题必须从 {OUTPUT_DIR}/{BRANCH}-result-all.json 读取。

📐 维度章节标准化模板:3.3.2~3.3.8 七个维度章节均遵循统一模板:

  1. 维度说明 → 2. 按文件分组的问题表格(含 ID/行号/子类型/描述/问题代码/修复建议列;F 维度额外含宕机后果列)→ 3. 本维度子类型分类表 → 4. 无问题时输出 "✅ 未发现" 声明

各维度仅子类型和表格列数(F 维度 7 列,其余 6 列)不同,结构完全一致。

⚠️ 问题编号规则:全局去重后,按维度权重从高到低(G→F→E→B→A→C→D)、同维度内按严重程度(CRITICAL→WARNING→SUGGESTION)、同严重程度内按文件路径排序,为每个问题分配唯一ID:ISS-{3位序号}(如 ISS-001, ISS-002)。此ID用于下游 review-bug-fix 追踪,必须在报告表格和JSON中一致出现。


3.3.1 问题统计总览

按严重程度:

严重程度数量
🔴 CRITICAL{n}
🟡 WARNING{n}
🟢 SUGGESTION{n}

按维度(全局去重后):

维度CRITICALWARNINGSUGGESTION权重
A. 规范审计{n}{n}{n}×1.5
B. 业务逻辑{n}{n}{n}×1.5
C. 方案合理性{n}{n}{n}×1
D. 性能{n}{n}{n}×1
E. 可靠性(Istio/K8s){n}{n}{n}×2
F. 宕机恢复与逻辑接续{n}{n}{n}×2.5
G. 安全审计{n}{n}{n}×3

涉及文件清单(出现问题的所有文件,去重,按问题数降序):

⚠️ 强制要求:此表格必须列出所有出现问题的文件,不得遗漏,不得截断。从 {BRANCH}-result-all.json 的 文件清单 字段读取数据后填入。

生成步骤:

  1. 读取 {OUTPUT_DIR}/{BRANCH}-result-all.json 的 文件清单 字段
  2. 按以下格式生成表格,每行对应一个文件:
    • 第一列:文件路径(使用反引号包裹,便于复制)
    • 第二列:问题数
    • 第三列:该文件所有问题中的最高严重程度

示例(真实数据):

文件问题数最高严重程度
cn/cisdigital/datakits/di/task/biz/service/TaskServiceImpl.java5WARNING
cn/cisdigital/datakits/di/task/biz/repository/mapper/TaskMapper.xml3CRITICAL
.........

若 文件清单 字段为空,报告生成失败,必须修复 Phase 3.2 的 Python 脚本。此表格填写完成后,result-all.json 的使命已完成,将在 Phase 3.6 清理中删除。


3.3.2 A. 规范审计问题(按类分组)

维度说明:覆盖命名规范、日志规范、异常规范、事务规范、MyBatis规范、并发规范、i18n规范、包命名规范、枚举规范、循环规范、API交互规范。

排序规则:维度内先 CRITICAL → WARNING → SUGGESTION,同一严重程度内按文件分组。

### {类名A.java}

| ID | 行号 | 子类型 | 问题描述 | 问题代码 | 修复建议 |
|---|---|---|---|---|---|
| ISS-{nnn} | {n} | {日志规范/异常规范/...} | {描述} | `{问题代码}` | {修复建议} |
| ISS-{nnn} | {n} | {...} | {...} | `{...}` | {...} |

### {类名B.java}

| ID | 行号 | 子类型 | 问题描述 | 问题代码 | 修复建议 |
|---|---|---|---|---|---|
| ... | ... | ... | ... | ... | ... |

子类型分类:

子类型说明
命名规范类名/方法名/变量名/包名违反命名约定
日志规范日志使用字符串拼接、未使用占位符{}、debug/info缺少条件判断
异常规范使用RuntimeException/throw new Exception、未使用ErrorCode枚举
事务规范@Transactional加在非public方法、事务范围包含网络调用
MyBatis规范XML中${}拼接、OGNL表达式调用静态方法、LIMIT/OFFSET拼接
并发规范ThreadLocal未在finally中remove、DateTimeFormatter重复创建
循环规范循环内单条insert/update/delete
i18n规范硬编码国际化文本、使用非dot.case格式的key
枚举规范枚举未实现BizEnum、使用ordinal比较
API交互规范Long未序列化为String、时间未使用毫秒时间戳

如本维度无问题:

### A. 规范审计

✅ 本次变更未发现规范审计问题。

3.3.3 B. 业务逻辑问题(按类分组)

维度说明:验证业务规则实现、边界条件处理、错误处理完整性、数据一致性。

### {类名A.java}

| ID | 行号 | 子类型 | 问题描述 | 问题代码 | 修复建议 |
|---|---|---|---|---|---|
| ISS-{nnn} | {n} | {需求覆盖/边界条件/null检查/数据一致性} | {描述} | `{问题代码}` | {修复建议} |

### {类名B.java}

| ID | 行号 | 子类型 | 问题描述 | 问题代码 | 修复建议 |
|---|---|---|---|---|---|
| ... | ... | ... | ... | ... | ... |

子类型分类:

子类型说明
需求覆盖代码未完整实现需求中的业务规则
边界条件数组越界、数值边界(最大值/最小值)、空指针风险
null检查入参未校验、返回值未判空、级联对象访问未判空
数据一致性并发修改未加锁、分布式场景数据不一致

如本维度无问题:

### B. 业务逻辑

✅ 本次变更未发现业务逻辑问题。

3.3.4 C. 方案合理性(按类分组)

维度说明:评估架构设计、N+1查询、重复代码、过度设计。

### {类名A.java}

| ID | 行号 | 子类型 | 问题描述 | 问题代码 | 修复建议 |
|---|---|---|---|---|---|
| ISS-{nnn} | {n} | {N+1查询/重复代码/过度设计/事务边界} | {描述} | `{问题代码}` | {修复建议} |

### {类名B.java}

| ID | 行号 | 子类型 | 问题描述 | 问题代码 | 修复建议 |
|---|---|---|---|---|---|
| ... | ... | ... | ... | ... | ... |

子类型分类:

子类型说明
N+1查询循环内执行单条SQL查询
重复代码相同逻辑在不同类中重复实现,未抽取复用
过度设计不必要的抽象、多层包装导致可读性下降
事务边界长事务、跨网络调用的操作放在事务内

如本维度无问题:

### C. 方案合理性

✅ 本次变更未发现方案合理性问题。

3.3.5 D. 性能问题(按类分组)

维度说明:评估分页限制、批量操作、异步超时、大数据量处理、慢查询。

### {类名A.java}

| ID | 行号 | 子类型 | 问题描述 | 问题代码 | 修复建议 |
|---|---|---|---|---|---|
| ISS-{nnn} | {n} | {分页限制/批量操作/异步超时/大数据量/慢查询} | {描述} | `{问题代码}` | {修复建议} |

### {类名B.java}

| ID | 行号 | 子类型 | 问题描述 | 问题代码 | 修复建议 |
|---|---|---|---|---|---|
| ... | ... | ... | ... | ... | ... |

子类型分类:

子类型说明
分页限制未限制最大页数、内存溢出风险
批量操作应批量但单条处理(insert/update/delete)
异步超时@Async方法未设置超时、线程池未监控
大数据量未使用流式处理、一次性加载全量数据
慢查询未建索引、未利用索引、全表扫描

如本维度无问题:

### D. 性能

✅ 本次变更未发现性能问题。

3.3.6 E. 可靠性问题 - Istio/K8s 场景(按类分组)

维度说明:MQ消费幂等、定时任务防重、分布式锁、资源泄漏、Pod重启后业务连续性。

### {类名A.java}

| ID | 行号 | 子类型 | 问题描述 | 问题代码 | 修复建议 |
|---|---|---|---|---|---|
| ISS-{nnn} | {n} | {幂等性/状态外化/分布式锁/资源泄漏/降级兜底} | {描述} | `{问题代码}` | {修复建议} |

### {类名B.java}

| ID | 行号 | 子类型 | 问题描述 | 问题代码 | 修复建议 |
|---|---|---|---|---|---|
| ... | ... | ... | ... | ... | ... |

子类型分类:

子类型说明
幂等性MQ消费/Istio重试导致重复执行无幂等保护
状态外化业务状态存储在内存而非DB/Redis,Pod重启后丢失
分布式锁锁未设置超时、锁未绑定唯一标识
资源泄漏DB连接/IO/线程池未在finally/try-with-resources释放
降级兜底非核心依赖故障时核心业务无兜底直接失败

如本维度无问题:

### E. 可靠性

✅ 本次变更未发现可靠性问题。

3.3.7 F. 宕机恢复与逻辑接续问题(按类分组)

维度说明:状态机完整性、可重入性、补偿机制、分布式事务边界、故障模式分析(FMEA)。

⚠️ 重点维度:必须通过故障模式分析(Failure Mode Analysis)追问:

  • "如果在这行代码之后JVM宕机,会发生什么?"
  • "重启后这条消息会被重新投递吗?业务逻辑能否正确处理?"
  • "跨系统的两阶段操作(DB+MQ、DB+OSS、MQ+外部服务)是否有补偿机制?"
### {类名A.java}

| ID | 行号 | 子类型 | 问题描述 | 问题代码 | 宕机后果 | 修复建议 |
|---|---|---|---|---|---|---|
| ISS-{nnn} | {n} | {状态机完整性/可重入性/补偿机制/分布式事务/补偿任务} | {描述} | `{问题代码}` | {如果宕机会发生什么} | {修复建议} |

### {类名B.java}

| ID | 行号 | 子类型 | 问题描述 | 问题代码 | 宕机后果 | 修复建议 |
|---|---|---|---|---|---|---|
| ... | ... | ... | ... | ... | ... | ... |

子类型分类:

子类型说明
状态机完整性状态流转无闭环、中间状态无超时恢复机制、状态变更和下游操作顺序错误
可重入性消息重推时状态检查跳过但后续操作丢失、PROCESSING状态无最大处理时长
补偿机制两阶段操作(DB+MQ/DB+OSS)第二步失败无补偿、资源泄漏(OSS分片/临时文件)
分布式事务事务中调用外部服务、本地事务成功但外部调用失败
补偿任务无补偿定时任务扫描"卡死"状态、补偿任务无防重复执行保护

宕机后果列(必填):简要描述"如果在这行代码后宕机,会发生什么"。

如本维度无问题:

### F. 宕机恢复与逻辑接续

✅ 本次变更未发现宕机恢复与逻辑接续问题。

3.3.8 G. 安全审计问题(按类分组)

维度说明:SQL注入、XSS、命令注入、敏感信息泄露、权限校验缺失、越权风险、日志脱敏。

### {类名A.java}

| ID | 行号 | 子类型 | 问题描述 | 问题代码 | 修复建议 |
|---|---|---|---|---|---|
| ISS-{nnn} | {n} | {SQL注入/XSS/命令注入/敏感信息/权限校验/越权风险/日志脱敏} | {描述} | `{问题代码}` | {修复建议} |

### {类名B.java}

| ID | 行号 | 子类型 | 问题描述 | 问题代码 | 修复建议 |
|---|---|---|---|---|---|
| ... | ... | ... | ... | ... | ... |

子类型分类:

子类型说明
SQL注入动态SQL拼接用户输入、MyBatis XML使用${}直接代入用户参数
XSS未对用户输入进行HTML转义即输出到响应
命令注入用户输入拼接到系统命令执行
敏感信息硬编码密码/密钥/Token/AWS凭证、密码在日志中打印
权限校验接口缺少权限检查、直接通过参数ID访问他人数据
越权风险数据归属权未校验、水平越权/垂直越权
日志脱敏日志打印手机号/身份证/银行卡等敏感字段

如本维度无问题:

### G. 安全审计

✅ 本次变更未发现安全审计问题。

3.3.9 修复优先级总览

🔴 CRITICAL(必须优先修复,按维度权重从高到低):

ID文件行号维度问题描述修复建议
ISS-{nnn}{文件}{n}{维度}{描述}{建议}

🟡 WARNING(按维度权重从高到低):

ID文件行号维度问题描述修复建议
ISS-{nnn}{文件}{n}{维度}{描述}{建议}

🟢 SUGGESTION(可计划修复):

ID文件行号维度问题描述修复建议
ISS-{nnn}{文件}{n}{维度}{描述}{建议}

3.3.10 审计结论

加权 WARNING 分数计算:

维度WARNING数权重小计
A. 规范审计{n}×1.5{n}
B. 业务逻辑{n}×1.5{n}
C. 方案合理性{n}×1{n}
D. 性能{n}×1{n}
E. 可靠性(Istio/K8s){n}×2{n}
F. 宕机恢复与逻辑接续{n}×2.5{n}
G. 安全审计{n}×3{n}
合计{total}-{score}

判定结果:

条件结论
任何 🔴 CRITICAL × 安全/可靠性维度阻塞合并
任何 🔴 CRITICAL需整改
加权 WARNING 分数 ≥ 3需整改
加权 WARNING 分数 < 3通过

本次审计加权 WARNING 分数:{score} 审计结论:{通过 / 需整改 / 阻塞合并}

本次审计综合评价: {简要说明本次变更的整体质量,突出最需要关注的问题。}

3.4 报告完整性校验(强制)

⚠️ 报告生成后必须执行此校验,确保 .md 报告包含 result-all.json 中的全部问题,不得遗漏。

校验步骤:

  1. 问题数校验:统计 .md 报告中出现的 ISS- 编号数量,与 result-all.json 的 问题列表 数组长度对比,两者必须相等

    # 统计 .md 报告中的 ISS 编号数量
    REPORT_COUNT=$(grep -c 'ISS-[0-9]\{3\}' "{OUTPUT_DIR}/{BRANCH}.md")
    # 统计 JSON 中的问题数量
    JSON_COUNT=$(python3 -c "import json; print(len(json.load(open('{OUTPUT_DIR}/{BRANCH}-result-all.json')).get('问题列表', [])))")
    echo "报告问题数: ${REPORT_COUNT}, JSON问题数: ${JSON_COUNT}"
    if [ "${REPORT_COUNT}" -ne "${JSON_COUNT}" ]; then
      echo "⚠️ 警告: 报告(${REPORT_COUNT})与JSON(${JSON_COUNT})问题数不一致,存在遗漏!"
    fi
    
  2. 文件清单校验:.md 报告中"涉及文件清单"的行数,与 result-all.json 的 文件清单 数组长度对比,两者必须相等

  3. 维度覆盖校验:确认 .md 报告中 3.3.2~3.3.8 七个维度章节都存在(即使无问题也要有"✅ 未发现"的声明)。

    ⚠️ 空维度处理:读取 result-all.json 的 问题列表 后,按 维度 字段分组。若某维度在 JSON 中无任何问题,报告中仍须写入该维度的"✅ 未发现"声明。不能因为 JSON 无数据就跳过该维度章节。

  4. ID连续性校验:确认 .md 报告中所有 ISS- 编号从 ISS-001 开始连续无断号

若校验不通过,必须补充报告中遗漏的问题,直到全部通过。

3.5 审计结论判定标准(参考汇总)

说明:本节为审计结论判定规则的汇总参考。报告中的实际判定结果见 3.3.10 审计结论章节。两处规则一致,此处便于快速查阅。

根据问题严重程度 × 维度交叉判定,而非简单计数:

维度权重(影响越大权重越高)
维度权重说明
安全审计(SQL注入/XSS/权限)×3直接影响系统安全
宕机恢复与逻辑接续(状态机/补偿/SAGA)×2.5影响故障后业务正确接续,数据丢失风险
可靠性(幂等/状态外化/事务/Istio)×2影响 Pod 重启后业务连续性
规范审计(异常/日志/并发)×1.5代码健壮性
业务逻辑(边界/null)×1.5功能正确性
性能(分页/批量)×1运行时性能
方案合理性(N+1/重复代码)×1长期可维护性
判定规则
条件结论说明
任何 CRITICAL × 安全/可靠性 问题阻塞合并必须修复
任何 CRITICAL 问题需整改影响功能/安全,需修复
加权 WARNING 分数 ≥ 3需整改多个问题累积
加权 WARNING 分数 < 3通过仅低影响建议

加权 WARNING 计算示例:

  • 1个安全 WARNING(×3)= 3 → 需整改
  • 2个规范 WARNING(×1.5)= 3 → 需整改
  • 3个性能建议(SUGGESTION ×0.5)= 1.5 → 通过
维度特殊规则
  • 安全维度:1个 CRITICAL 安全问题直接阻塞,无论其他维度
  • 宕机恢复维度:状态机不完整(无恢复路径)、无补偿机制的跨系统两阶段操作、无法重入的消息处理 → 直接阻塞
  • 可靠性维度:Pod 重启场景下的问题优先处理,不接受降级兜底缺失
  • 规范维度:仅在循环内单条 insert/delete、吞异常(无兜底)时升级为 CRITICAL
3.6 清理中间文件

汇总完成后,删除所有中间结果文件,只保留最终报告:

# =============================================
# Phase 3.6 清理 — 必须全部执行
# =============================================
AUDIT_DIR="{OUTPUT_DIR}"
BRANCH_NAME="${BRANCH}"

# 1. 清理 OUTPUT_DIR 内的所有中间文件
echo "清理 OUTPUT_DIR: ${AUDIT_DIR}"
rm -f "${AUDIT_DIR}/${BRANCH_NAME}-result-"*-merged.json
rm -f "${AUDIT_DIR}/${BRANCH_NAME}-result-"*checkpoint*.json
rm -f "${AUDIT_DIR}/${BRANCH_NAME}-result-all.json"
rm -f "${AUDIT_DIR}/${BRANCH_NAME}-status.json"

# 2. 清理主计划文件(与最终报告同目录,需显式删除)
rm -f "${AUDIT_DIR}/${BRANCH_NAME}-plan.md"
echo "已删除: ${AUDIT_DIR}/${BRANCH_NAME}-plan.md"

# 3. 清理 Agent 计划文件(批次级计划)
rm -f "${AUDIT_DIR}/${BRANCH_NAME}-plan-"*.md
echo "已删除: ${AUDIT_DIR}/${BRANCH_NAME}-plan-*.md"

# 4. 清理 Agent 运行目录中产生的 references 文件夹(由 Agent 读取规范文件时创建)
if [ -d "./references" ]; then
  REF_COUNT=$(find ./references -type f 2>/dev/null | wc -l)
  if [ "$REF_COUNT" -eq 0 ]; then
    rmdir ./references 2>/dev/null && echo "已删除空目录: ./references" || true
  fi
fi

echo "清理完成"

清理说明:

  • result-all.json 是汇总阶段的中间产物(用于去重、排序、分配ID),报告生成后已无用,一并清理
  • .md 报告是唯一产物,包含全部问题和文件清单,下游 Skill 直接读取 .md 即可

清理后保留的文件:

{OUTPUT_DIR}/{branch-name}.md       # ✅ 最终审计报告(唯一产物)

Phase 4:输出摘要

✅ 代码审计完成

分支:{branch-name} | 基准:{base-branch}
变更文件:{total-files} 个 | 审计:{audited-files} 个
审计批次:{batch-count} 批次

问题统计:
🔴 严重:{critical} | 🟡 中等:{warning} | 🟢 建议:{suggestion}

审计结论:{通过 / 需整改 / 阻塞合并}

详细报告:{OUTPUT_DIR}/{branch-name}.md
问题追踪ID:ISS-001 ~ ISS-{total-issues}

⚠️ 新增输出:审计报告中的每个问题已分配唯一 ISS-{序号} ID,可用于下游 review-bug-fix Skill 追踪。


自检清单

  • 主计划文件已生成 {OUTPUT_DIR}/<branch>-plan.md
  • 每个批次的计划文件已生成 {OUTPUT_DIR}/<branch>-plan-*.md
  • 手动模式下用户已确认审计计划
  • 每批次Agent完成后已更新待合并列表
  • 每个Agent的JSON结果文件已通过 python3 合法性校验(Phase 2.5 步骤0)
  • 全局合并前已做字段名标准化(file → 文件,兜底空值)
  • 全局去重已完成(批次间无重复问题)
  • 全局问题ID已分配(ISS-{序号},按维度权重从高到低排序)
  • 涉及文件清单已生成(从 {BRANCH}-result-all.json 的 文件清单 字段读取,所有出现问题文件完整列出,表格完整无占位符)
  • JSON 全部数据已写入 .md 报告(result-all.json 中的每一条问题和每一个文件都已写入 .md,无遗漏。.md 是唯一最终产物,JSON 清理后不可恢复)
  • 报告完整性校验已通过(问题数、文件数、维度覆盖、ID连续性,Phase 3.4)
  • 最终报告已写入 {OUTPUT_DIR}/<branch-name>.md
  • 报告按维度分章节(3.3.2~3.3.8),各章节内按文件分组,维度内按 CRITICAL→WARNING→SUGGESTION 排序
  • 报告各维度表格包含 ID 列(大部分6列:ID/行号/子类型/描述/问题代码/修复建议;F维度7列额外含宕机后果)
  • F维度每个问题的"宕机后果"列已填写(其他维度填-)
  • F维度(宕机恢复与逻辑接续)审计已完成,特别是Listener/导出服务等关键文件的故障模式分析
  • 摘要已输出到对话中
  • 审计结论已判定并输出(含加权WARNING分数计算过程)
  • 中间文件已清理(Phase 3.6 清理步骤已执行,仅保留最终报告 {branch-name}.md)

Agent计划文件模板

每个批次的计划文件应包含以下内容:

# 审计计划 - 批次{n}

## 批次信息
- 批次名称:{name}
- 批次ID:{batch-id}
- 审计文件数:{count}
- 计划文件:{path}
- 结果文件:{OUTPUT_DIR}/{branch-name}-result-{批次ID}.json

## 需求背景
{提交历史摘要}

## 本批次文件列表
{完整文件路径列表}

## 规范文件(Agent 通过 rules 自动加载,无需手动读取。以下为参考路径)
- /Users/han/.agents/skills/wk-code-review/references/java-specification_01.md
- /Users/han/.agents/skills/wk-code-review/references/java-specification_02.md
- /Users/han/.agents/skills/wk-code-review/references/error-code-specification.md
- /Users/han/.agents/skills/wk-code-review/references/frontend-backend-conventions.md
- /Users/han/.agents/skills/wk-code-review/references/naming-specification.md
- /Users/han/.agents/skills/wk-code-review/references/i18n-specification.md

## 审计维度

### A. 规范审计
- **MyBatis规范**:
  - XML中禁止使用 `${}` 直接拼接(SQL注入风险)
  - XML中禁止使用 `${@...@}` OGNL表达式调用静态方法
  - XML中禁止使用 `+` 拼接字符串
  - LIMIT/OFFSET必须使用参数绑定,禁止拼接
- **异常规范**:必须使用ErrorCode枚举,禁止RuntimeException/throw new Exception
- **日志规范**:使用占位符`{}`,禁止字符串`+`拼接;debug/info级别日志需条件判断
- **并发规范**:ThreadLocal需在finally中remove;DateTimeFormatter需复用实例
- **事务规范**:@Transactional注解必须在public方法上
- **循环规范**:禁止循环内单条insert/update/delete,必须批量操作
- **i18n规范**:国际化key格式为`dot.case`
- **包命名规范**:使用`dot.case`,遵循`cn.<company>.<product>[.<domain>].<service>[.<layer>][.<business>][.<mvc>]`
- **枚举规范**:枚举类实现BizEnum;messageKey使用国际化KEY;禁止ordinal比较
- **前后端交互**:Long类型序列化为String;时间使用时间戳毫秒;禁止RESTful路径参数

### B. 业务逻辑审计
- 需求覆盖度:代码是否完整实现需求
- 边界值处理:空指针、数组越界、边界数值
- null检查:入参校验、返回值处理
- 数据一致性:事务边界、并发数据一致

### C. 方案合理性审计
- N+1查询:循环内查询数据库
- 重复代码:相同逻辑是否抽取复用
- 过度设计:是否有不必要的抽象

### D. 性能审计
- 分页限制:是否限制最大页数
- 批量操作:是否使用批量insert/update
- 异步超时:@Async方法是否设置超时
- 大数据量:是否考虑流式处理

### E. 可靠性审计

#### E1. 服务宜机能力(Istio + K8s 场景)
> **⚠️ 背景**:系统使用 Istio + Kubernetes 部署,流量治理由 Istio 接管。
- 是否配置了 healthCheck / readinessProbe / livenessProbe(K8s 层)
- 启动探针是否通过(Pod Ready 之前不会被 Istio 路由流量)
- 是否存在启动时预加载数据到内存(Pod 重启后数据丢失)

#### E2. Pod 重启 / 异常恢复(Istio 自动流量切换)
> **核心问题**:Pod 被 Kill 或异常退出后,Istio 会自动将流量切换到其他实例。业务逻辑能否无缝接续?
- **MQ 消息可靠性**:消费端是否在处理完成后才 ACK;是否有死信队列;消费端是否实现幂等
- **定时任务可靠性**:是否持久化执行进度;多实例是否使用分布式锁;任务失败是否有补偿
- **缓存可靠性**:是否存在缓存击穿;缓存故障时是否有降级兜底
- **分布式锁可靠性**:锁是否设置了合理的超时时间;锁是否绑定唯一标识

#### E3. 异常恢复与容错
> **⚠️ 背景**:Istio 管理熔断/重试/超时/限流。应用层审计聚焦 Pod 重启/异常时业务逻辑能否继续。
- **幂等性保障**:MQ 消费端幂等;对外 HTTP/Feign 调用幂等;重试场景数据库操作有唯一约束或状态机校验
- **降级兜底逻辑**:远程服务不可用时返回兜底数据;非核心依赖故障时核心业务可降级
- **状态外部化**:业务状态存储在 DB/Redis 而非内存;定时任务持久化执行进度
- **数据一致性**:长事务拆分;分布式事务使用 Seata TCC;补偿事务/消息表用于最终一致性
- **资源泄漏防护**:DB 连接使用 try-with-resources;线程池在 Bean 初始化时创建
- **并发控制**:多实例定时任务使用分布式锁;分布式锁设置超时

#### E4. 数据一致性
- **事务策略**:长事务拆分为短事务;分布式事务使用 XA/TCC/SAGA;事务回滚完整
- **数据变更兜底**:危险操作(批量删除/更新)有人工确认或二次校验

#### E5. 兜底与防护完整性
- **禁止吞没异常**:catch 块不能为空或只打印日志不处理
- **资源释放**:IO/DB连接/线程池使用 try-with-resources 或 finally 释放
- **日志中断点**:关键操作有日志记录
- **幂等性保障**:MQ 消费/重试/并发场景下保证幂等

### F. 宕机恢复与逻辑接续审计(重点维度)

> **⚠️ 核心问题**:JVM在处理业务逻辑的过程中宕机,重启后业务能否正确接续?必须通过**故障模式分析(FMEA)**来审计。

#### F1. 状态机完整性审计
**核心问题**:对每个状态变更节点,问"如果在这行代码之后宕机,会发生什么?"
审计要点:状态流转是否形成闭环;状态变更是否原子化;是否有"卡死"状态
审计检查项:状态变更前是否有checklist;状态变更和下游操作顺序是否正确;是否存在两步操作但只检查一个状态;是否有超时机制恢复"卡死"状态

#### F2. 可重入性审计(幂等消息处理)
**核心问题**:消息被重复投递,业务逻辑能否正确处理?
审计要点:状态检查是否接受所有合法重入状态;是否实现检查-执行-再检查幂等模式
审计检查项:状态检查是否验证当前持有者;PROCESSING状态是否有最大处理时长;是否存在状态被更新但未完成导致无法重入

#### F3. 补偿机制审计
**核心问题**:跨系统两阶段操作(DB+MQ、DB+OSS、MQ+外部服务),第二步失败后是否有补偿?
审计检查项:两阶段操作是否有补偿事务;失败后补偿操作是否有幂等保护;补偿失败是否有告警;是否存在资源泄漏风险

#### F4. 分布式事务边界审计
**核心问题**:跨数据库/跨服务的操作,是否有正确的事务边界?
审计检查项:事务是否只包含DB操作;跨服务操作是否使用最终一致性方案;是否存在本地事务成功外部调用失败的场景

#### F5. 宕机恢复与补偿任务审计
**核心问题**:是否有定时任务扫描"卡死"状态并恢复?
审计检查项:PROCESSING/中间状态是否有最大处理时长限制;是否有补偿/恢复定时任务;补偿任务是否使用分布式锁

#### F6. 故障模式分析(FMEA)追问清单
**消息消费类**:消息重复投递时状态检查是否会跳过?如果在更新状态为PROCESSING之后宕机重启后消息重推会被跳过吗?ACK在成功之后还是之前?失败消息是否有DLQ?
**导出/异步任务类**:状态变更和消息发送的顺序?在更新数据库之后发送消息之前宕机怎么办?文件上传成功后通知外部失败如何处理?是否有补偿定时任务?
**分片上传类**:分片上传成功但合并通知失败会产生垃圾碎片吗?有没有清理补偿机制?
**多阶段状态机类**:每个状态变更是否有超时机制?超时后如何恢复?恢复后能否正确接续?

### G. 安全审计
- **注入攻击**:SQL注入、XSS、命令注入
- **敏感信息**:硬编码密码/密钥/Token
- **权限校验**:接口是否缺少权限检查
- **越权风险**:数据访问是否校验所属权
- **日志脱敏**:日志是否打印敏感字段(手机号、身份证、密码)

## 执行步骤

> **⚠️ 必须按顺序执行,每一步完成前不要进入下一步**

### 严重程度判定标准(各维度通用)

| 严重程度 | 判定规则 |
|---|---|
| **CRITICAL** | 违反规范,且在特定运行时场景下**必然**导致功能错误、数据丢失或安全问题 |
| **WARNING** | 违反规范,在常见运行时场景下**可能**导致问题,或存在一定风险 |
| **SUGGESTION** | 违反规范,但当前上下文风险极低,属于优化建议 |

> **同一问题可能因上下文不同而判不同级别**。例如:日志字符串拼接在核心业务流程中判 WARNING,在简单的工具类中判 SUGGESTION。

1. **读取规范文件**:使用 Read 工具读取上述 6 个参考规范文件,理解审计标准
2. **读取计划文件**:使用 Read 工具读取本计划文件,了解本次批次的文件列表和审计范围
3. **读取文件内容**:使用 Read 工具逐一读取每个需要审计的 Java/XML 文件的完整内容
   > **必须读取文件内容后才能进行分析,不能仅靠 git diff 的变更片段判断问题**
   > git diff 只显示变更的部分,完整判断需要结合文件的上下文
4. **执行 git diff**:获取代码变更对比,了解本次提交改了什么:
   ```bash
   git diff ${BASE_BRANCH}...${BRANCH} -- {文件路径1} {文件路径2} ...

⚠️ 使用 ${BRANCH} 而非 HEAD,确保多批次执行时取到正确分支差异。

  1. 按审计维度(A-G)逐文件分析:
    • 对每个文件,结合文件内容和 diff,逐一检查是否符合规范
    • 检查每个问题必须包含:文件路径、行号、严重程度、维度、类型、描述、问题代码、修复建议
    • 特别注意:问题代码、描述、宕机后果、修复建议字段中若包含特殊字符(双引号 "、反斜杠 \、换行符),必须转义后才能写入 JSON(参见下方 JSON 安全规则)
  2. 写入结果文件:将结果按指定 JSON 格式写入结果文件

    ⚠️ JSON 安全强制规则:

    • 问题代码字段:只保留关键行(≤150字符),优先将代码中的双引号替换为单引号("x" → 'x'),避免 \" 转义;反斜杠需双重转义(\ → \\)
    • 描述、宕机后果、修复建议:禁止出现未转义的双引号,禁止包含实际换行符(用 \n 字面量表示)
    • 引用代码时用反引号 `code` 包裹,禁止用双引号
  3. 写入后立即自检:
    • 用 Read 工具重新读取写入的 JSON 文件,核对内容完整
    • 执行 python3 -c "import json; json.load(open('文件路径'))" 验证合法性
    • 若验证失败:按上方 JSON 安全规则修复对应字段,重新写入,直到验证通过
  4. 结果文件路径:{OUTPUT_DIR}/{branch-name}-result-{批次ID}.json

输出要求

将结果写入JSON文件,格式:

{
  "批次": "{name}",
  "批次ID": "{batch-id}",
  "文件总数": {count},
  "问题列表": [
    {
      "id": "ISS-{由Python脚本统一分配,Agent无需填写}",
      "严重程度": "CRITICAL|WARNING|SUGGESTION",
      "文件": "文件路径",
      "行号": "行号",
      "维度": "A. 规范审计|B. 业务逻辑|C. 方案合理性|D. 性能|E. 可靠性|F. 宕机恢复与逻辑接续|G. 安全审计",
      "类型": "问题类型(子类型,如:日志规范/null检查/N+1查询等)",
      "描述": "问题描述",
      "问题代码": "代码片段",
      "宕机后果": "如果在这行代码后宕机会发生什么(F维度必填,其他维度填\"-\")",
      "修复建议": "修复建议"
    }
  ]
}

⚠️ 新增 id 字段:id 字段由主进程在 Phase 3.2 Python 脚本中统一分配(ISS-{序号}),Agent 无需填写。Agent 输出的 id 值将被脚本覆写。

⚠️ JSON 输出安全规则(强制遵守,否则最终合并必然失败):

以下规则是为了防止子代理输出的 JSON 字段(如问题代码、描述、宕机后果、修复建议)中包含的特殊字符(双引号、反斜杠、换行符)破坏 JSON 结构。必须严格执行。

特殊字符转义方式示例
\(反斜杠)\\C:\data → C:\\data
"(双引号)\""test" → \"test\"
实际换行符\n(字面量)实际换行 → \n
制表符\t实际 tab → \t

转义顺序(必须按此顺序):

  1. \ → \\
  2. " → \"
  3. 换行符 → \n

代码片段(问题代码字段)处理规则:

  1. 只保留关键的一行代码,不超过 150 字符;超出部分用 ... 截断
  2. 优先将代码中的双引号替换为单引号再嵌入 JSON("name" → 'name'),避免转义
  3. 代码中若含大量双引号无法替换,再使用 \" 转义
  4. 反斜杠在正则表达式中需双重转义:\d → JSON 中写 \\d

描述文本(描述、宕机后果、修复建议字段)处理规则:

  1. 引用代码片段时用反引号(`code`)包裹,禁止用双引号包裹代码
  2. 文本内换行用 \n 字面量表示,禁止包含实际换行符
  3. 禁止在文本字段中出现未转义的双引号

正确示例:

{
  "问题描述": "logger.debug使用了字符串拼接,应使用占位符",
  "问题代码": "logger.debug('Processing id: ' + id);",
  "宕机后果": "日志输出可能因格式化错误而丢失关键信息",
  "修复建议": "改为 logger.debug('Processing id: {}', id);"
}

错误示例(会导致JSON损坏):

{
  "问题描述": "logger.debug("Processing id: " + id) 使用了字符串拼接",
  "问题代码": "logger.debug("Processing id: " + id);  // 内层双引号未转义,会破坏JSON
  "宕机后果": "宕机后
任务状态丢失",
  "修复建议": "改为 logger.debug("Processing id: {}", id);"
}

写后自检流程(强制执行):

  1. 用 Write 工具写入 JSON 文件
  2. 立即用 Read 工具重新读取该文件,核对内容是否完整
  3. 用 Bash 执行 python3 -c "import json; json.load(open('文件路径'))" 验证合法性
  4. 若验证失败:用 Bash python3 -c "import json; print(json.dumps(json.load(open('文件路径').read().replace('破坏的字符','正确的转义'))))" 定位错误字段,重新 Write 该字段的修复值,重复步骤 2-4 直到通过

主计划文件模板

# 代码审计计划

> 分支:{branch-name}
> 生成时间:{timestamp}
> 基准分支:{base-branch}

---

## 统计信息

| 项目 | 值 |
|---|---|
| 变更文件总数 | {total-files} |
| Java文件 | {java-files} |
| XML文件 | {xml-files} |
| 应审计文件数 | {to-audit-files} |
| 审计批次 | {batch-count} |

---

## 审计批次清单

### 批次{n}:{name}
- 批次ID:{batch-id}
- 文件数:{count}
- 计划文件:{OUTPUT_DIR}/{branch-name}-plan-{batch-id}.md

...(继续列出所有批次)

---

## 执行步骤

- [ ] Step 1: 批次1审计
- [ ] Step 2: 批次2审计
- [ ] Step 3: 汇总结果,生成报告

---

## 待合并结果文件列表

(每批次完成后动态追加)

<!-- 待合并结果文件列表开始 -->
<!-- 待合并结果文件列表结束 -->

---

## 重点关注项

1. 新增的核心业务文件
2. 涉及安全的文件
3. 涉及并发/事务的文件
4. Mapper XML文件(SQL注入风险)

示例对话

用户输入处理方式
对这个分支进行代码审计预检查 → 生成主计划 → 用户确认 → 分批次执行 → 更新待合并列表 → 汇总报告
代码审计 feature/1.4.0/xxx/489822同上,针对指定分支
wk-code-review feature/xxx同上

Comments

Markdown supported