Claude Skill

auto-test-skill

当用户明确要求"测试技能"、"运行 auto-test"或"进行批判性测试"时使用。通过多轮 A 轮批判性测试 + B 轮质量原则检查,系统化发现、记录、修复问题,并沉淀可追溯的 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/` 与 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/` 文档。⚠️ 不适用:用户只是想优化功能(应直接修改)、只是询问技能问题(应直接回答)、没有明

LLM Mart · 0 points · 18 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download huangwb8-skills-skills_alpha_auto-test-skill-0b4095f.zip · 69 KB
Part of huangwb8/skills — 22 skills

Install

skills CLI npx skills add https://github.com/huangwb8/skills/tree/main/skills/alpha/auto-test-skill
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install huangwb8-skills@llmmart
Git git clone https://github.com/huangwb8/skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole huangwb8/skills collection as a plugin from our marketplace. Git is the plain clone.

README

auto-test-skill

批判性思维驱动的测试驱动优化技能 - 用于在 AI 辅助开发后进行系统性测试与迭代优化。

概述

本技能提供了一套完整的测试驱动优化工作流,帮助用户在AI辅助开发后进行系统性的测试、问题修复和迭代优化。

核心价值:

  • ✅ 结构化问题管理: 从bug发现到优先级排序的全流程管理
  • ✅ 可重复测试: 规范化的测试目录和文档结构
  • ✅ 独立评估 + 迭代修复: 每轮 A 轮独立审查当前状态,按计划修复并用轻量测试验证
  • ✅ 完整追溯: 每轮迭代都有明确的测试计划和报告

设计理念: 本技能借鉴了成熟的软件测试实践(如时间戳命名测试会话、规范化文档结构、测试数据/脚本/输出分离等),确保每个测试会话都是独立、透明、可重复的;其中 A 轮默认采用“独立评估”模式(不查看 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/ 与 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/),以降低确认偏差并提升多轮价值。

适用场景

  • ✅ 用户完成AI辅助开发后,需要进行系统性测试
  • ✅ 发现bug需要记录和优先级排序
  • ✅ 需要制定结构化的优化和测试计划
  • ✅ 需要管理多轮迭代测试和修复流程
  • ✅ 需要生成规范的测试报告和总结文档

使用方法

推荐用法(自动完整测试流程)

开发者推荐 Prompt:

使用 auto-test-skill 对 xxx 这个skill进行1次迭代优化。

补充要求(推荐):每轮 A 轮为独立评估(不查看上一轮 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/ / .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/),并明确本轮审查范围与排除范围。

人机协作用法(手动审核 AI 建议)

本技能支持灵活的"人机协作"模式,你可以手动查看和审核 AI 的建议,而不必自动执行完整的修复流程。

典型场景:

根据 auto-test-skill 的B轮原则,目前 bensz-rmd-rules 还有哪些优化的地方?

优势:

  • 你可以先查看 AI 发现的问题,再决定是否修复
  • 可以选择性采纳建议,而不是全盘接受
  • 适合用于代码审查、质量评估等场景

更多人机协作示例:

根据 auto-test-skill 的批判性思维框架,分析一下 my-skill 在架构设计上可能有哪些问题?
用 auto-test-skill 的A轮独立评估模式,检查这个 skill 是否存在过度设计的问题。

触发方式

在支持 Agent Skills 的工具(如 Codex CLI、Claude Code、Cursor 等)中使用以下表述之一触发本技能:

自动测试模式:

  • "帮我测试一下这个技能"
  • "我需要制定测试计划"
  • "需要进行迭代优化"
  • "生成测试报告"

人机协作模式:

  • "根据 auto-test-skill 的 B 轮原则分析这个 skill"
  • "用 auto-test-skill 的批判性思维检查这个项目"
  • "根据 auto-test-skill 的质量原则给出优化建议"

输入要求

使用本技能前,请准备:

  1. 目标技能的根目录路径

    • 示例: /path/to/skills/your-skill
  2. 测试发现的问题列表

    • 可来自:用户反馈、测试结果、代码审查等
    • 至少包含:问题描述、复现步骤、期望行为
  3. 可选: 已有测试数据或测试用例

    • 如果有,请提供数据路径

工作流程

本技能遵循 A轮×N + B轮 的多轮迭代工作流:

用户输入
  ↓
[A轮 × N]:分析 → 计划 → 优化 → 轻量测试
  ↓
B轮:质量原则检查 → 针对性优化 → 轻量验证
  ↓
完成(文档齐全 + 问题闭环)

详细说明请参阅 SKILL.md。

输出交付

使用本技能后,您将获得:

  1. 规划文档(A轮):.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/vYYYYMMDDHHMM.md
  2. 测试会话目录(A轮):.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/vYYYYMMDDHHMM/(包含 TEST_PLAN.md、TEST_REPORT.md)
  3. 质量检查报告(B轮):.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/B轮-vYYYYMMDDHHMM.md
  4. 验证会话目录(B轮):.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/B轮-vYYYYMMDDHHMM/(包含 TEST_PLAN.md、TEST_REPORT.md)

确定性辅助脚本(推荐)

为避免每轮手工创建目录与文档骨架,推荐使用:

python3 auto-test-skill/scripts/create_test_session.py --skill-root /path/to/target-skill --task-root /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description --kind a --id vYYYYMMDDHHMM --create-plan

# 或:省略 --id 自动生成 vYYYYMMDDHHMM
python3 auto-test-skill/scripts/create_test_session.py --skill-root /path/to/target-skill --task-root /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description --kind a --create-plan

验证会话完整性(推荐,避免“空报告/占位符残留”):

# 在目标 skill 根目录内执行
python3 /path/to/auto-test-skill/scripts/verify_test_session.py --skill-root /path/to/target-skill --task-root /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description --require-plan /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description/auto-test-skill/output/tests/vYYYYMMDDHHMM

说明:

  • --skill-root 指向“要被测试/被优化”的目标 skill 根目录(必须包含 SKILL.md)
  • --create-plan 会在缺失时生成 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/ 下对应的计划文档骨架(默认不覆盖)
  • 脚本会优先使用目标 skill 的 templates/(如存在);否则使用 auto-test-skill 自带 templates/ 作为回退模板
  • B 轮可选:使用 --a-test-id vYYYYMMDDHHMM 记录“对应的 A 轮会话 id”(用于 B 轮报告可追溯)
  • --seed-test-plan-from-plan(高级,不推荐):会将 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/ 下的计划文档直接复制为 TEST_PLAN.md,通常你应当基于 templates/TEST_PLAN_TEMPLATE.md 补全验证点即可

文件结构

auto-test-skill/
├── SKILL.md                           # 技能主文档
├── README.md                          # 本文件
├── config.yaml                        # 配置文件
├── .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/  # 规划文档目录
├── .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/  # 测试会话目录
├── scripts/                           # 确定性辅助脚本(可选)
├── templates/                         # 文档模板
│   ├── BUG_REPORT_TEMPLATE.md         # Bug报告模板
│   ├── OPTIMIZATION_PLAN_TEMPLATE.md  # 优化计划模板
│   ├── TEST_PLAN_TEMPLATE.md          # 测试计划模板
│   ├── TEST_REPORT_TEMPLATE.md        # 测试报告模板
│   ├── FINAL_SUMMARY_TEMPLATE.md      # 最终总结模板
│   └── B_ROUND_CHECK_TEMPLATE.md      # B轮质量检查模板
└── references/                        # 参考文档
    └── TESTING_BEST_PRACTICES.md      # 测试最佳实践

配置说明

本技能使用 config.yaml 作为口径统一与部分脚本参数的单一来源。

主要配置项:

  • 脚本会读取:
    • directories.*:.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/ 与 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/ 的相对目录(scripts/create_test_session.py 会做路径安全校验)
    • templates.*:计划/报告等模板路径(相对 skill 根目录)
  • 规划口径(AI/人类参考):
    • test_rounds:每轮数量阈值(10-20、P0+P1≥60%、系统性问题≥3 等)
    • a_round_check.independent_review:A 轮独立评估的审查范围与排除范围(不看 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/ 与 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/)
    • b_round_check:B 轮质量检查是否强制、数量阈值、修复率要求、检查维度(b_round_check.dimensions)

版本更新顺序(推荐):先更新 config.yaml:skill_info.version,再同步 SKILL.md YAML 表头与 CHANGELOG.md。

详细配置请参阅 config.yaml。

示例使用场景

场景 1: 修复技能的 Bug

输入:

  • 用户报告某个技能的3个bug
  • 技能根目录: /path/to/skills/your-skill

执行流程:

  1. A轮:生成 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/vYYYYMMDDHHMM.md(问题清单 + 改进计划)
  2. A轮:创建 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/vYYYYMMDDHHMM/ 并按计划修复与验证
  3. B轮:生成 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/B轮-vYYYYMMDDHHMM.md(质量原则检查;维度以 config.yaml:b_round_check.dimensions 为准)
  4. B轮:创建 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/B轮-vYYYYMMDDHHMM/ 并做针对性验证
  5. 验收:更新 CHANGELOG.md

输出:

  • 修复后的代码
  • 完整的测试文档
  • CHANGELOG.md 更新

场景 2: 多轮迭代优化

背景: 第一次测试发现10个问题,计划分3轮迭代

迭代轮次:

  • 第1轮 (v202601021313): 修复 P0(2个) + P1(3个) → 测试通过
  • 第2轮 (v202601031015): 修复 P1(2个) + P2(3个) → 测试通过
  • 第3轮 (v202601041420): 修复剩余 P2 + 新发现的问题 → 测试通过

最终输出:

  • FINAL_SUMMARY.md(总结3轮优化历程)
  • 所有问题已修复
  • 测试覆盖率提升

最佳实践

1. 问题分类原则

严重程度判断标准:

严重程度 判断问题
Critical 数据丢失、安全漏洞、完全无法使用
High 主要功能失效、性能严重退化、用户体验严重受损
Medium 边缘功能失效、性能轻微退化、用户体验一般受损
Low 文档错误、UI瑕疵、体验优化建议

2. 迭代计划原则

每次迭代应该:

  • ✅ 专注修复少量高优先级问题(3-5个)
  • ✅ 确保每个修复都有对应的测试
  • ✅ 验证无回归后再合并

每次迭代不应该:

  • ❌ 试图修复所有问题
  • ❌ 修复没有测试的问题
  • ❌ 引入新的破坏性变更

3. 测试设计原则

好的测试用例:

  • ✅ 快速执行(几秒内)
  • ✅ 独立运行(不依赖顺序)
  • ✅ 结果明确(通过/失败清晰)
  • ✅ 可重复执行(结果稳定)

测试用例模板:

def test_fix_problem_1():
    """测试问题#1的修复效果"""
    # Arrange
    input_data = {...}

    # Act
    result = function_to_test(input_data)

    # Assert
    assert result == expected_output

4. 文档管理原则

测试文档应该:

  • ✅ 简洁明了(重点信息突出)
  • ✅ 结构一致(使用统一模板)
  • ✅ 及时更新(每个阶段结束后立即更新)
  • ✅ 独立完整(不依赖外部文档)

常见问题

Q1: 如果测试会话太多怎么办?

A: 测试会话目录本身就很轻量(主要是文档),可以保留所有历史会话。如果需要清理,建议:

  • 保留最近10个会话
  • 归档早期的会话到 tests_archive/(如你在项目里有该约定)
  • 保留关键里程碑的会话(如首次完整测试、重大修复等)

Q2: 如果一个问题需要多轮迭代才能修复怎么办?

A:

  • 在第一轮迭代中,尝试最小化修复(缓解问题而非完美解决)
  • 在后续迭代中,逐步完善修复
  • 在 BUG_REPORT.md 中标记问题的演进历史

Q3: 如果在修复过程中引入新问题怎么办?

A:

  • 立即记录新问题到 BUG_REPORT.md
  • 评估新问题的严重程度
  • 如果是 P0/P1,停止当前修复,优先处理新问题
  • 如果是 P2/P3,记录到下次迭代计划

Q4: 如何确保测试的轻量级?

A:

  • 优先使用单元测试而非集成测试
  • 使用 mock/stub 隔离外部依赖
  • 测试数据尽量小而精
  • 避免耗时操作(如网络请求、文件IO)

参考资源

相关阅读:

  • 测试驱动开发(TDD)最佳实践
  • 敏捷开发中的迭代优化方法
  • 软件质量保证(SQA)标准流程

WHICHMODEL - 模型选择最佳实践

披露信息

  • 最后更新:2026-01-25
  • 覆盖厂商:Anthropic(Claude 系列)
  • 来源构成:官方文档 60%、技术博客 25%、社区讨论 15%
  • 数据时效:2025-2026
  • 局限性:本次调研主要基于 Anthropic 官方文档,未包含第三方独立基准测试

场景一:批判性代码分析与问题发现(A 轮核心任务)

  • 推荐模型:Claude Sonnet 4.5
  • 推荐参数:
    • Extended Thinking:开启,budget_tokens: 10000-16000
    • Temperature:不可调(Thinking 模式下固定)
    • Max Tokens:16384
  • 理由:Sonnet 4.5 在 SWE-bench Verified 上达到 77.2%(state-of-the-art),特别擅长"测试其自己的代码"。官方文档明确指出其"在代码分析任务上表现卓越",且相比前代模型"代码编辑错误率从 9% 降至 0%"。
  • 来源:Anthropic Models Overview、Sonnet 4.5 Performance Summary

场景二:测试计划与优化方案制定(A 轮规划任务)

  • 推荐模型:Claude Opus 4.5
  • 推荐参数:
    • Extended Thinking:开启,budget_tokens: 16000-32000
    • Max Tokens:32768
  • 理由:Opus 4.5 官方定位为"Premium model combining maximum intelligence with practical performance",在复杂推理任务上表现最佳。官方案例显示其能"发现未预料但合法的 workaround",证明其深度推理能力。此外,用户报告"工具调用错误和构建错误减少 50%-75%"。
  • 适用:多轮迭代优化计划、复杂依赖关系分析、P0/P1 优先级评估
  • 来源:Anthropic Models Overview、Opus 4.5 Announcement

场景三:B 轮质量原则检查(8 维度系统性审查)

  • 推荐模型:Claude Sonnet 4.5
  • 推荐参数:
    • Extended Thinking:开启,budget_tokens: 8000-12000
    • Max Tokens:16384
  • 理由:B 轮检查涉及 8 个标准化维度(硬编码/AI 规划、冗余检查、安全性等),属于结构化分析任务。Sonnet 4.5 在此类任务上性价比最高($3/MTok input vs Opus 的 $5/MTok),且官方推荐其用于"complex agents and coding"。
  • 来源:Anthropic Models Overview

场景四:轻量测试验证(快速筛查)

  • 推荐模型:Claude Haiku 4.5
  • 推荐参数:
    • Extended Thinking:关闭(简单任务无需深度推理)
    • Temperature:0.3
    • Max Tokens:4096
  • 理由:Haiku 4.5 官方定位为"near-frontier intelligence"的最快模型,价格仅 $1/MTok input。适合简单的语法检查、格式验证等轻量任务,可节省时间和成本。
  • 适用:早期问题筛查、简单格式验证、快速反馈循环
  • 来源:Anthropic Models Overview

场景五:多步骤工具调用与交叉验证

  • 推荐模型:Claude Sonnet 4.5 / Opus 4.5
  • 推荐参数:
    • Extended Thinking:开启
    • Interleaved Thinking:开启(需 beta header interleaved-thinking-2025-05-14)
    • budget_tokens:可超过 max_tokens(工具调用场景特殊规则)
  • 理由:auto-test-skill 涉及大量 Glob/Read/Grep 工具调用。启用 Interleaved Thinking 后,Claude 可在每次工具调用结果返回后进行推理,做出"更细致的决策"。官方文档明确支持此功能用于"chain multiple tool calls with reasoning steps in between"。
  • 来源:Extended Thinking with Tool Use

模型对比总结

场景 推荐模型 Thinking 核心优势 成本(input)
A 轮问题发现 Sonnet 4.5 开 SWE-bench 77.2%,代码分析 SOTA $3/MTok
A 轮规划制定 Opus 4.5 开 最强推理,复杂规划 $5/MTok
B 轮质量检查 Sonnet 4.5 开 结构化分析性价比 $3/MTok
轻量验证 Haiku 4.5 关 最快响应,低成本 $1/MTok
多步工具调用 Sonnet/Opus 开+交叉 工具间推理 $3-5/MTok

通用原则

  1. 默认用 Sonnet 4.5:官方明确推荐"如果不确定用哪个模型,从 Sonnet 4.5 开始"——它在"智能、速度和成本之间提供最佳平衡"
  2. 复杂规划升级 Opus:当任务涉及多因素权衡、长期规划、架构决策时,使用 Opus 4.5
  3. Extended Thinking 是关键:auto-test-skill 的批判性分析任务强烈推荐开启 Thinking 模式,预算建议 10000-16000 tokens
  4. Interleaved Thinking 用于工具密集型任务:涉及多次 Glob/Read/Grep 调用时,启用交叉推理可提升分析质量
  5. Haiku 用于快速验证:轻量任务用 Haiku 可节省 70%+ 成本

更新记录

  • 2026-01-25:基于 Anthropic 官方文档(2025-2026)全面更新,新增 Extended Thinking 和 Interleaved Thinking 最佳实践
  • 2026-01-03:初始调研

版本历史

  • v1.0.0 (2026-01-02): 初始版本
    • 6阶段工作流
    • 结构化问题管理
    • 测试会话管理
    • 文档模板系统

许可证

本技能遵循 Agent Skills 开放标准。

联系方式

  • 作者: bensz
  • 创建时间: 2026-01-02
  • 反馈渠道: 通过 GitHub Issues 或项目讨论区反馈

祝您测试愉快! 🎉

Skill manifest

auto-test-skill(批判性思维驱动的测试优化技能)

目标

当用户明确要求"测试技能"、"运行 auto-test"或"进行批判性测试"时使用。通过多轮 A 轮批判性测试 + B 轮质量原则检查,系统化发现、记录、修复问题,并将中间产物写入调用方锁定的 .bensz-api/task-*/auto-test-skill/ 工作区。⚠️ 不适用:用户只是想优化功能(应直接修改)、只是询问技能问题(应直接回答)、没有明确"测试"意图。

流程

输入

输入为待测试的 Agent Skill 根目录;可选输入包括测试提示、A/B 轮次数、运行 ID、config.yaml 参数和输出路径。测试前确认目标 SKILL.md、配置、脚本、模板与必要 references 可读,且不把测试产物写回被测 Skill 源目录。

执行步骤

你要产出的东西

本 skill 的交付不是“口头建议”,而是一组可追溯的文件:

(目录位置以 config.yaml:directories 为准;默认 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/ + .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/)

  • .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/vYYYYMMDDHHMM.md:A 轮问题分析与改进计划(每轮 1 份)
  • .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/vYYYYMMDDHHMM/:A 轮测试会话目录(包含 TEST_PLAN.md + TEST_REPORT.md)
  • .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/B轮-vYYYYMMDDHHMM.md:B 轮质量原则检查报告(维度以 config.yaml:b_round_check.dimensions 为准)
  • .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/B轮-vYYYYMMDDHHMM/:B 轮验证会话目录(包含 TEST_PLAN.md + TEST_REPORT.md)

工作流程

概览
用户输入
  ↓
[A轮 × N]:分析 → 计划 → 优化 → 轻量测试
  ↓
B轮:质量原则检查 → 针对性优化 → 轻量验证
  ↓
完成(文档齐全 + 问题闭环)
A 轮测试(可重复 N 次)
A.1 初始化会话(生成测试 ID + 目录)

目标:在已锁定的 --task-root 下创建本轮 auto-test-skill/output/plans/ 与 auto-test-skill/output/tests/ 骨架,不向被测 Skill 源目录写入产物。

推荐使用确定性脚本(避免 AI 每次手动拼目录/文件名):

# 复用已锁定的项目任务目录
python3 /path/to/auto-test-skill/scripts/create_test_session.py --skill-root /path/to/target-skill --task-root /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description --kind a --id vYYYYMMDDHHMM --create-plan

# 方式2:在任意位置执行(--skill-root 指向目标 skill 根目录)
python3 auto-test-skill/scripts/create_test_session.py --skill-root /path/to/target-skill --task-root /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description --kind a --id vYYYYMMDDHHMM --create-plan

说明:

  • 脚本会优先使用目标 skill 的 templates/(如存在);否则回退到 auto-test-skill 自带的 templates/,确保对任意 skill 都可用。
  • --id 可省略(脚本自动生成 vYYYYMMDDHHMM);如显式指定,必须为 vYYYYMMDDHHMM 格式。

最低要求:

  • .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/ 与 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/ 存在
  • .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/vYYYYMMDDHHMM/TEST_PLAN.md 与 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/vYYYYMMDDHHMM/TEST_REPORT.md 存在 可选增强(推荐):
  • 使用 --create-plan 自动生成 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/vYYYYMMDDHHMM.md 的骨架(默认不覆盖)
A.2 批判性分析与计划生成(写入 `.bensz-api/task-

目标:使用批判性思维发现系统性问题,写成可执行计划,按 P0/P1/P2 排序。

输出:.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/vYYYYMMDDHHMM.md

⚠️ 批判性思维是核心要求(不是可选项):

  • 必须使用「刁钻角度」思考(详见 references/CRITICAL_THINKING_GUIDE.md)
  • 必须发现至少 3 个系统性问题(架构/过度设计/一致/安全)
  • 禁止列出"不痛不痒"的表面问题(如"缺少注释"等 P2 级别问题不应占多数)

质量要求(强制):

  • 每轮至少发现 10 个问题(P0 + P1 + P2 总和)
  • 鼓励达到 15-20 个问题(深入挖掘)
  • P0 + P1 占比必须 ≥ 60%(确保问题有价值)
  • 系统性问题 ≥ 3 个(架构设计/过度设计/一致性/安全性)

核心要求:

  • 独立评估原则(强制):
    • 每轮 A 轮必须基于目标 skill 的当前工作状态独立分析
    • 不查看上轮的 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/ 和 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/ 文件,避免"确认偏差"与"路径依赖"
    • 每轮都是一次完整的、无偏见的系统性审查
  • 审查范围(强制):
    • 必须审查:SKILL.md、config.yaml(核心工作文件)
    • 必须审查目录:scripts/、references/、templates/、assets/(如不存在可在计划中说明)
    • 排除范围:.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/、.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/、CHANGELOG.md、README.md(测试产物、变更记录和用户文档,不属于 skill 的工作代码),以及 config.yaml 中 a_round_check.independent_review.exclude_patterns 命中的文件
    • 审查方法:使用 Glob/Read/Grep(如 rg/find)对工作文件做全量扫描,确保不遗漏
  • 批判性聚焦:每轮选择 1-2 个聚焦维度(系统架构/过度设计/一致性/安全性/边缘情况/用户体验)
  • 刁钻角度:必须使用至少一个刁钻角度(边缘情况/恶意输入/隐式假设/自我质疑/跨文件矛盾)
  • 优先级依据:P0/P1/P2 必须有明确的判定标准
    • P0: 阻塞性问题、安全风险、核心功能缺失、架构设计缺陷
    • P1: 重要优化(过度设计/冗余/不一致)、功能增强、测试覆盖不足
    • P2: 锦上添花、文档改进、后续迭代项
  • 可追溯性:每个问题必须包含位置、现象、影响、修复建议、验证方法
  • 建设性:每条建议必须可执行、有证据、有价值、可验证(详见 references/CONSTRUCTIVE_SUGGESTION_GUIDELINES.md)

批判性思维框架(必读):

  • references/CRITICAL_THINKING_GUIDE.md ⚠️ 核心文档,必须使用
    • 框架 1: 系统视角思考(架构设计/过度设计/一致性)
    • 框架 2: 刁钻角度思考(边缘情况/恶意输入/隐式假设/自我质疑)
    • 框架 3: 问题质量标准(黄金公式 + 质量检查清单)
  • references/A_ROUND_PLAN_TEMPLATE.md ⚠️ 已简化,突出批判性思维要求
  • references/ISSUE_DISCOVERY_TECHNIQUES.md 问题挖掘技巧(辅助工具)
  • references/CONSTRUCTIVE_SUGGESTION_GUIDELINES.md 建设性建议标准
  • references/ANTI_PATTERNS_LIBRARY.md 反例库(快速识别常见问题)
A.3 执行优化与轻量测试(写入 `.bensz-api/task-

目标:按计划逐项修复,并用轻量测试验证。

输出:.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/vYYYYMMDDHHMM/TEST_REPORT.md

轻量测试原则:

  • 只验证“核心路径”与“本轮变更点”
  • 每条结论必须有可复现证据(命令输出、文件、对比结果)
  • 中间产物放入 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/vYYYYMMDDHHMM/_artifacts/,不污染主目录

可选增强(推荐,确定性自检):

python3 auto-test-skill/scripts/verify_test_session.py --skill-root /path/to/target-skill --task-root /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description --require-plan /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description/auto-test-skill/output/tests/vYYYYMMDDHHMM
A.4 是否进入下一轮

⚠️ 强制检查(必须满足才能进入下一轮):

  • 本轮已提出至少 10 个问题(P0 + P1 + P2 总和)
  • 如未达到,必须继续挖掘问题(使用 references/ISSUE_DISCOVERY_TECHNIQUES.md 中的技巧)

进入下一轮 A 轮的条件(在满足强制检查的前提下):

  • 用户指定的轮次数未完成
  • 本轮问题(P0/P1/P2)已全部闭环:修复完成,并在 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/ 会话的 TEST_REPORT.md 中给出验证证据

注意:每轮 A 轮都是独立评估,不因“问题已解决”而提前终止;如用户指定 N 轮,则按 N 轮执行。

重要:A 轮结束后(无论多少轮),必须进入 B 轮质量检查,不得跳过。

B 轮质量原则检查(当前 8 项)

⚠️ 强制执行:B 轮质量检查是自动测试流程的强制性环节,除非用户明确要求跳过,否则不得省略。

B.1 产出质量检查报告(写入 `.bensz-api/task-

目标:对 A 轮后的最新状态做系统性质量检查。

输出:.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/B轮-vYYYYMMDDHHMM.md

检查维度(以 config.yaml 的 b_round_check.dimensions 为准):

  • 硬编码/AI 功能规划
  • 冗余残留错误检查
  • 安全性检查
  • 过度设计检查
  • 通用性检查
  • 一致性检查
  • 配置集中化检查:检查精确端(config.yaml)与模糊端(工作文档)是否完全分离,确保所有可配置参数集中在 config.yaml 作为单一真相来源
  • SKILL.md 瘦身检查:检查 SKILL.md 是否过于冗长,应将详细内容模块化到 references/

模板:templates/B_ROUND_CHECK_TEMPLATE.md

B.2 B 轮优化与验证(写入 `.bensz-api/task-

⚠️ 强制修复要求:

  • B 轮发现的 所有 P0-P2 问题都必须处理(修复或明确说明不修复理由)
  • P0 问题必须修复
  • P1 问题必须修复(除非有合理理由)
  • P2 问题应尽可能修复
  • 每个修复必须有验证证据(命令输出、文件对比、测试结果)
  • 修复后必须更新 CHANGELOG.md

验证报告必须包含:

  1. 修复清单:每个 P0-P2 问题的修复方案和证据
  2. 遗留问题:未修复问题及原因(无论优先级)
  3. 变更记录:更新目标 skill 的 CHANGELOG.md

可选增强(推荐,确定性自检):

python3 auto-test-skill/scripts/verify_test_session.py --skill-root /path/to/target-skill --task-root /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description --require-plan /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description/auto-test-skill/output/tests/B轮-vYYYYMMDDHHMM

完成条件:

  • P0 问题修复率 = 100%
  • P1 问题修复率 = 100%(除非有合理的不修复理由)
  • P2 问题修复率 ≥ 60%(鼓励全部修复)
  • 所有修复都有可复现证据

目标:对 B 轮发现的所有问题(P0-P2)进行系统性修复并验证。

推荐创建独立会话目录:

python3 /path/to/auto-test-skill/scripts/create_test_session.py --skill-root /path/to/target-skill --task-root /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description --kind b --id vYYYYMMDDHHMM --a-test-id vYYYYMMDDHHMM --create-plan

输出:.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/B轮-vYYYYMMDDHHMM/TEST_REPORT.md

可复用资源

  • 配置:config.yaml
  • 模板:templates/
    • A 轮计划:templates/OPTIMIZATION_PLAN_TEMPLATE.md
    • B 轮质量检查:templates/B_ROUND_CHECK_TEMPLATE.md
    • Bug 报告:templates/BUG_REPORT_TEMPLATE.md
    • 最终总结:templates/FINAL_SUMMARY_TEMPLATE.md
    • 测试计划:templates/TEST_PLAN_TEMPLATE.md
    • 测试报告:templates/TEST_REPORT_TEMPLATE.md
  • 参考:references/
    • 批判性思维指南:references/CRITICAL_THINKING_GUIDE.md ⚠️ 核心文档,必须使用
    • A 轮计划结构:references/A_ROUND_PLAN_TEMPLATE.md ⚠️ 已简化,突出批判性思维
    • 测试最佳实践:references/TESTING_BEST_PRACTICES.md
    • 建设性建议标准:references/CONSTRUCTIVE_SUGGESTION_GUIDELINES.md
    • 问题挖掘技巧:references/ISSUE_DISCOVERY_TECHNIQUES.md
    • 反例库:references/ANTI_PATTERNS_LIBRARY.md
  • 辅助脚本:scripts/create_test_session.py
  • 辅助脚本:scripts/verify_test_session.py

输出

每轮必须交付可追溯文件:A 轮计划 output/plans/vYYYYMMDDHHMM.md、A 轮会话 output/tests/vYYYYMMDDHHMM/,B 轮报告 output/plans/B轮-vYYYYMMDDHHMM.md 和 B 轮会话 output/tests/B轮-vYYYYMMDDHHMM/;各会话至少包含 TEST_PLAN.md 与 TEST_REPORT.md,具体目录以 config.yaml:directories 为准。

输出管理

BenszAPI 任务工作区

目录与命名规范

  • 测试会话 ID:vYYYYMMDDHHMM(分钟级时间戳)
  • 规划文档:默认放在 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/(以 config.yaml:directories.plans 为准)
  • 测试会话:默认放在 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/(以 config.yaml:directories.tests 为准)
  • B 轮统一加前缀:B轮-

校验

完成条件(验收)

  • 用户指定的 A 轮次数已完成(或明确说明提前结束原因)
  • B 轮质量检查已完成并形成报告(⚠️ 强制要求,参考 config.yaml 的 b_round_check.mandatory)
  • 每轮 A 轮平均问题数量 ≥ 10 个(P0 + P1 + P2 总和)
  • 每轮 P0 + P1 占比 ≥ 60%(确保问题有价值)
  • 每轮系统性问题 ≥ 3 个(架构/过度设计/一致/安全)
  • 关键问题(P0/P1)已闭环:计划 → 修复 → 证据 → 结论
  • B 轮 P0 问题修复率 = 100%,P1 问题修复率 = 100%(或在报告中逐条说明不修复理由)
  • .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/ 与 .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/ 结构完整且可追溯
  • 目标 skill 的 CHANGELOG.md 已更新

失败与恢复

脚本、目标 Skill 读取或测试执行失败时,保留当前会话的计划、日志和测试报告,明确区分输入缺失、环境错误与行为失败,并给出复现命令;可在同一任务工作区重试未完成阶段。证据不足时不得臆测通过,A 轮与 B 轮的强制环节不得静默跳过。

约束

公共硬约束

本块由 docs/templates/skill-common-constraints.md 统一维护;每个 SKILL.md 的 ## 约束 必须逐字同步本块,不得在副本中改写公共规则。

  • 任务需要落盘时,使用唯一的 ./.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/ 根目录;共享材料放入 shared/,Skill 专属材料放入该 Skill 的 input/、output/、log/。
  • 正式交付物、源代码和正式计划按项目约定保存,不写入任务工作区;未经授权不覆盖、删除、迁移或远程写入。
  • 项目维护变更检查 BAC 可用性并记录需求、AI 产出、工具结果、文件改动和验证摘要;BAC 只做过程审计,不替代署名、责任或合规判断。
  • 不记录 API Key、访问令牌、密码、Cookie、环境/凭据文件、私有 Prompt、身份信息、本地用户名、主机名或不必要的大体积原始数据。
  • 文件路径必须规范化并限制在授权项目范围内;外部 URL、子进程和网络访问遵循最小权限,防止路径遍历、SSRF 和命令注入。
  • Skill 版本唯一记录在自身 config.yaml:skill_info.version;公开 API、协议、目录或配置变更同步文档与 CHANGELOG.md。
  • bensz-collect-bugs 是一个 Agent Skill;仅将 Bensz Agent Skill 或 Bensz 基础设施本身的设计缺陷交给它。先脱敏写入 ~/.bensz-skills/bugs/,当前任务不中断,只有用户明确要求才公开上报,禁止直接修改用户已安装的 Skill 源码。
Files (skills)
  • references
    • ANTI_PATTERNS_LIBRARY.md 13.5 KB
      # 技能开发反例库
      
      **文档版本**:v1.0.0
      **创建时间**:2026-01-14
      **用途**:为 auto-test-skill 提供常见反例库,用于快速识别问题
      
      ---
      
      ## 使用说明
      
      本文档按照"B 轮质量原则检查维度"分类(以 `config.yaml:b_round_check.dimensions` 为准),每类包含常见反例。
      
      **使用方法**:
      1. 在检查 skill 时,对比本文档中的反例
      2. 发现相似模式时,记录为问题
      3. 参考"正确做法"给出修复建议
      
      ---
      
      ## 1. 硬编码/AI功能规划反例
      
      ### 反例 1: 让 AI "手动创建目录"
      
      **错误表现**:
      ```markdown
      ## 执行步骤
      1. 创建目录:`output/reports/{timestamp}/`
      2. 创建文件:`output/reports/{timestamp}/summary.md`
      ```
      
      **问题**:这是确定性操作,应脚本化
      
      **正确做法**:
      ```markdown
      ## 执行步骤
      1. 运行 `scripts/init_session.py` 自动创建目录和文件
      ```
      
      ---
      
      ### 反例 2: 配置值硬编码在文档中
      
      **错误表现**:
      ```markdown
      ## 配置说明
      最大重试次数:3次
      超时时间:30秒
      ```
      
      **问题**:应移至 config.yaml
      
      **正确做法**:
      ```yaml
      # config.yaml
      retries:
        max: 3
      timeout: 30  # 秒
      ```
      
      ```markdown
      ## 配置说明
      详见 config.yaml 中的 `retries.max` 和 `timeout` 配置项
      ```
      
      ---
      
      ### 反例 3: 让 AI 每次编写相同代码
      
      **错误表现**:
      ```markdown
      ## 步骤 2
      用 Python 读取 CSV 文件:
      ```python
      import csv
      with open(file, 'r') as f:
          reader = csv.reader(f)
          ...
      ```
      
      **问题**:AI 每次都要"记住"这段代码
      
      **正确做法**:
      ```markdown
      ## 步骤 2
      运行 `scripts/read_csv.py --input {file}` 自动读取
      ```
      
      ---
      
      ### 反例 4: 过度配置化
      
      **错误表现**:
      ```yaml
      # config.yaml
      file_formats:
        csv:
          extension: ".csv"
          delimiter: ","
          encoding: "utf-8"
      ```
      
      **问题**:这些是 CSV 标准定义,不需要配置
      
      **正确做法**:
      ```python
      # scripts/reader.py
      DELIMITER = ","  # CSV 标准
      ENCODING = "utf-8"  # 现代标准
      ```
      
      ---
      
      ## 2. 冗余残留错误检查反例
      
      ### 反例 1: 残留引用
      
      **错误表现**:
      ```markdown
      # SKILL.md
      详见 references/OLD_TEMPLATE.md
      ```
      ```bash
      # 实际情况
      $ ls references/OLD_TEMPLATE.md
      ls: cannot access: No such file or directory
      ```
      
      **问题**:引用已删除的文件
      
      **正确做法**:
      ```markdown
      # SKILL.md
      详见 references/NEW_TEMPLATE.md
      ```
      
      ---
      
      ### 反例 2: 重复段落
      
      **错误表现**:
      ```markdown
      ## 输入格式
      输入必须是 PDF 格式,文件大小不超过 10MB...
      
      ## 使用示例
      示例 1:输入一个 PDF 文件...
      示例 2:输入一个 PDF 文件...(与示例 1 几乎相同)
      ```
      
      **问题**:内容重复,应合并
      
      **正确做法**:
      ```markdown
      ## 输入格式
      输入必须是 PDF 格式,文件大小不超过 10MB...
      
      ## 使用示例
      示例:输入一个 PDF 文件并解析...
      ```
      
      ---
      
      ### 反例 3: 僵尸文件
      
      **错误表现**:
      ```
      references/unused_guide.md  # 从未被 SKILL.md 或任何脚本引用
      assets/old_template.txt     # 已被新模板替代,但未删除
      scripts/backup_old.py       # 标记为"备份",但未说明用途
      ```
      
      **问题**:无用的文件占用空间,污染代码库
      
      **正确做法**:
      ```bash
      # 使用 Grep 搜索引用
      grep -r "unused_guide" .
      # 如果无结果,删除文件
      rm references/unused_guide.md
      ```
      
      ---
      
      ### 反例 4: 配置重复定义
      
      **错误表现**:
      ```yaml
      # config.yaml
      output:
        directory: "./output"
        format: "json"
      ```
      ```markdown
      # SKILL.md
      ## 配置说明
      - output_dir: 输出目录(默认:`output/`)
      - output_format: 输出格式(默认:`json`)
      ```
      
      **问题**:配置项名称不一致(`output.directory` vs `output_dir`)
      
      **正确做法**:
      ```markdown
      ## 配置说明
      详见 config.yaml 中的 `output.directory` 和 `output.format`
      ```
      
      ---
      
      ## 3. 安全性检查反例
      
      ### 反例 1: 路径遍历漏洞
      
      **错误表现**:
      ```python
      # 危险:未验证用户输入
      user_path = input("输入文件路径:")
      with open(user_path, 'r') as f:  # 可能访问任意文件
          ...
      ```
      
      **问题**:用户可输入 `../../etc/passwd` 访问任意文件
      
      **正确做法**:
      ```python
      import os
      
      user_path = input("输入文件路径:")
      resolved = os.path.realpath(user_path)
      base_dir = os.path.realpath("./data")
      
      if not resolved.startswith(base_dir):
          raise ValueError("路径必须在 data 目录内")
      
      with open(resolved, 'r') as f:
          ...
      ```
      
      ---
      
      ### 反例 2: 敏感信息泄露
      
      **错误表现**:
      ```python
      # 错误日志中暴露详细信息
      except Exception as e:
          print(f"错误:处理文件 {user_path} 时失败,详情:{str(e)}")
          # user_path 可能是用户数据,e 可能包含内部路径
      ```
      
      **问题**:泄露用户数据和系统内部信息
      
      **正确做法**:
      ```python
      except Exception as e:
          logger.error(f"处理文件失败:{e}", exc_info=True)
          # 不记录 user_path,使用日志系统而非 print
      ```
      
      ---
      
      ### 反例 3: 命令注入风险
      
      **错误表现**:
      ```python
      # 危险:用户输入直接用于系统命令
      os.system(f"convert {user_input} output.pdf")
      ```
      
      **问题**:用户可输入 `; rm -rf /` 执行任意命令
      
      **正确做法**:
      ```python
      import subprocess
      
      subprocess.run(["convert", user_input, "output.pdf"], check=True)
      # 使用参数化 API,而非字符串拼接
      ```
      
      ---
      
      ### 反例 4: 硬编码密钥
      
      **错误表现**:
      ```python
      # config.yaml
      api_key: "sk-1234567890abcdef"
      ```
      
      **问题**:密钥硬编码,会提交到 Git
      
      **正确做法**:
      ```python
      # config.yaml
      api_key: ${API_KEY}  # 从环境变量读取
      ```
      
      ```bash
      # .env(不提交到 Git)
      API_KEY=sk-1234567890abcdef
      ```
      
      ---
      
      ## 4. 过度设计检查反例
      
      ### 反例 1: 为未来预留功能
      
      **错误表现**:
      ```yaml
      # config.yaml
      output_formats:
        pdf:
          enabled: true
          engine: "reportlab"
        docx:
          enabled: false  # 未来可能支持
        html:
          enabled: false  # 未来可能支持
        markdown:
          enabled: false  # 未来可能支持
      ```
      
      **问题**:当前只支持 PDF,其他格式不应硬编码
      
      **正确做法**:
      ```yaml
      # config.yaml
      output_format: "pdf"  # 唯一支持的格式
      # 未来需要时再添加
      ```
      
      ---
      
      ### 反例 2: 过度抽象
      
      **错误表现**:
      ```python
      class OutputFormatFactory:
          """输出格式工厂(当前只有一种格式)"""
          def create_formatter(self, format_type):
              if format_type == "pdf":
                  return PDFFormatter()
              # 未来扩展点...
      
      class PDFFormatter(AbstractFormatter):
          def format(self, data):
              # 实际上就是直接调用一个函数
              return convert_to_pdf(data)
      ```
      
      **问题**:只有一种格式时,工厂和抽象层都是不必要的
      
      **正确做法**:
      ```python
      def format_output(data, output_path):
          """格式化输出为 PDF"""
          convert_to_pdf(data, output_path)
      ```
      
      ---
      
      ### 反例 3: 配置项过多
      
      **错误表现**:
      ```yaml
      # 本可以简单的功能,配置项却超过 20 个
      processing:
        retries: 3
        retry_delay: 1.0
        retry_backoff: 2.0
        retry_jitter: true
        timeout:
          connect: 10
          read: 30
          total: 60
        validation:
          strict: true
          level: "high"
          custom_rules: []
        # ... 还有 10+ 个配置项
      ```
      
      **问题**:大部分场景下这些值不需要改变
      
      **正确做法**:
      ```yaml
      # 只暴露真正需要配置的项
      processing:
        timeout: 30  # 大部分场景够用
        retries: 3   # 大部分场景够用
      # 其他值使用合理的默认值,硬编码在代码中
      ```
      
      ---
      
      ## 5. 通用性检查反例
      
      ### 反例 1: 年份限定
      
      **错误表现**:
      ```markdown
      ## 功能说明
      本 skill 用于处理 2024 年度 NSFC 申请书格式
      ```
      
      **问题**:年份硬编码,2025 年就需要修改
      
      **正确做法**:
      ```markdown
      ## 功能说明
      本 skill 用于处理 NSFC 申请书格式(支持所有版本)
      ```
      
      ---
      
      ### 反例 2: 场景限定过窄
      
      **错误表现**:
      ```markdown
      ## 适用场景
      - 将 WeChat 文章同步到 Notion
      ```
      
      **问题**:限制了平台,实际逻辑可通用化
      
      **正确做法**:
      ```markdown
      ## 适用场景
      - 将网页文章同步到笔记应用(支持 WeChat、Notion、Obsidian 等)
      ```
      
      ---
      
      ### 反例 3: 时间敏感示例
      
      **错误表现**:
      ```markdown
      ## 示例
      输入:`--date 2025-01-14`
      输出:`report_20250114.pdf`
      ```
      
      **问题**:示例日期会过时
      
      **正确做法**:
      ```markdown
      ## 示例
      输入:`--date {YYYY-MM-DD}`
      输出:`report_{YYYYMMDD}.pdf`
      ```
      
      ---
      
      ### 反例 4: 不必要的品牌限定
      
      **错误表现**:
      ```markdown
      本 skill 专为 ChatGPT Plus 用户设计...
      ```
      
      **问题**:限制了 AI 平台,实际功能通用
      
      **正确做法**:
      ```markdown
      本 skill 适用于各类 AI 助手平台(Claude、ChatGPT、Gemini 等)
      ```
      
      ---
      
      ## 6. 一致性检查反例
      
      ### 反例 1: YAML 与正文不一致
      
      **错误表现**:
      ```yaml
      ---
      name: pdf-merger
      description: 合并多个 PDF 文件
      ---
      ```
      ```markdown
      # SKILL.md
      ## 功能说明
      本 skill 用于分割和提取 PDF 页面...
      ```
      
      **问题**:YAML 说是合并,正文说是分割提取
      
      **正确做法**:
      ```yaml
      ---
      name: pdf-splitter
      description: 分割和提取 PDF 页面
      ---
      ```
      
      ---
      
      ### 反例 2: 配置项不一致
      
      **错误表现**:
      ```markdown
      # SKILL.md
      ## 配置说明
      - `output_dir`: 输出目录(默认:`output/`)
      - `max_retries`: 最大重试次数(默认:3)
      ```
      ```yaml
      # config.yaml
      output:
        directory: "./output"
      retries:
        max: 5  # 与文档中的默认值 3 不一致
      ```
      
      **问题**:文档与配置不一致
      
      **正确做法**:
      ```markdown
      # SKILL.md
      ## 配置说明
      详见 config.yaml 中的 `output.directory` 和 `retries.max`
      ```
      ```yaml
      # config.yaml
      output:
        directory: "./output"  # 默认输出目录
      retries:
        max: 5  # 最大重试次数
      ```
      
      ---
      
      ### 反例 3: 示例与实际不一致
      
      **错误表现**:
      ```markdown
      # README.md
      ## 使用示例
      /run pdf-merger --input file1.pdf,file2.pdf --output merged.pdf
      ```
      ```markdown
      # SKILL.md(当前版本)
      ## 参数说明
      - `--input`: 输入文件(支持目录和文件,非逗号分隔列表)
      ```
      
      **问题**:README 中的语法是旧版本
      
      **正确做法**:
      ```markdown
      # README.md
      ## 使用示例
      /run pdf-merger --input ./input_dir --output merged.pdf
      ```
      
      ---
      
      ### 反例 4: 术语不一致
      
      **错误表现**:
      ```markdown
      # 一处文档使用"测试会话"(session)
      ## 创建测试会话
      v202601141900
      
      # 另一处使用"测试轮次"(round)
      ## 测试轮次说明
      第一轮测试...
      ```
      
      **问题**:术语不统一
      
      **正确做法**:
      ```markdown
      # 统一使用"测试会话"(session)
      ## 创建测试会话
      v202601141900
      
      ## 测试会话说明
      第一个测试会话...
      ```
      
      ---
      
      ## 7. SKILL.md 瘦身检查反例
      
      ### 反例 1: 完整模板内容嵌入 SKILL.md
      
      **错误表现**:
      ```markdown
      # SKILL.md(臃肿)
      ## A 轮计划模板
      
      ## 测试 ID: {{TEST_ID}}
      ## 测试时间: {{CHECK_TIME}}
      ## ... 完整的 100 行模板内容 ...
      ```
      
      **问题**:应引用 `references/A_ROUND_PLAN_TEMPLATE.md`
      
      **正确做法**:
      ```markdown
      # SKILL.md(精简)
      ## A 轮计划模板
      
      详见 `references/A_ROUND_PLAN_TEMPLATE.md`
      ```
      
      ---
      
      ### 反例 2: 详细配置说明
      
      **错误表现**:
      ```markdown
      # SKILL.md(臃肿)
      ## 配置说明
      
      ### output_dir
      - 类型:字符串
      - 默认值:"output/"
      - 说明:指定输出目录的路径。可以是相对路径或绝对路径...
      - 示例:output_dir: "./reports"
      
      ### max_retries
      - 类型:整数
      - 默认值:3
      - 说明:最大重试次数。当操作失败时会自动重试...
      - 示例:max_retries: 5
      
      # ... 20+ 个配置项的详细说明
      ```
      
      **问题**:应移至 config.yaml 注释
      
      **正确做法**:
      ```markdown
      # SKILL.md(精简)
      ## 配置说明
      
      详见 config.yaml 中的注释说明。
      ```
      
      ```yaml
      # config.yaml
      # 输出目录(可包含环境变量,如:${HOME}/reports)
      output_dir: "./output"
      
      # 最大重试次数(0 表示不重试)
      max_retries: 3
      ```
      
      ---
      
      ### 反例 3: 详细技术实现
      
      **错误表现**:
      ```markdown
      # SKILL.md(臃肿)
      ## 实现细节
      
      ### PDF 解析逻辑
      使用 PyPDF2 库解析 PDF 文件。首先打开文件,然后逐页读取...
      具体实现:[100 行技术说明]
      ```
      
      **问题**:应移至 scripts/ 注释或独立技术文档
      
      **正确做法**:
      ```markdown
      # SKILL.md(精简)
      ## 实现细节
      
      详见 `scripts/parse_pdf.py` 中的 docstring 和注释。
      ```
      
      ---
      
      ### 反例 4: 行数过多
      
      **错误表现**:
      ```
      SKILL.md: 500+ 行
      references/: 空目录或只有 1-2 个文件
      ```
      
      **问题**:SKILL.md 过于冗长
      
      **正确做法**:
      - SKILL.md 控制在 300 行以内
      - 详细内容移至 references/
      - 技术细节移至 scripts/ 注释
      - 配置说明移至 config.yaml 注释
      
      ---
      
      ## 使用反例库进行问题发现
      
      ### 步骤 1: 快速扫描
      
      浏览 skill 文件,对比反例库中的模式:
      - 是否有"让 AI 手动操作"的模式?
      - 是否有"为未来预留功能"的配置?
      - 是否有"年份限定"的文档?
      
      ### 步骤 2: 深度验证
      
      对发现的疑似问题,进一步验证:
      - 这个配置项真的需要吗?
      - 这个抽象真的有必要吗?
      - 这个限定真的合理吗?
      
      ### 步骤 3: 记录问题
      
      使用问题记录模板记录:
      ```
      #### 问题 X: [反例名称]
      
      **位置**: `文件:行号`
      
      **反例类型**: [质量原则之一]
      
      **问题描述**:
      [具体描述问题现象,参考反例库]
      
      **优先级**: P0/P1/P2
      
      **修复建议**:
      [参考反例库中的"正确做法"]
      
      **验证方法**:
      [如何确认修复成功]
      ```
      
      ---
      
      **模板说明**:
      
      本文档用于 auto-test-skill 快速识别常见问题。
      
      使用时:
      1. 熟悉质量原则的反例模式
      2. 检查 skill 时对比反例库
      3. 发现相似模式时记录为问题
      4. 参考"正确做法"给出修复建议
      
    • A_ROUND_PLAN_TEMPLATE.md 6 KB
      # A 轮优化计划模板
      
      **计划版本**: v{{TIMESTAMP}}
      **制定时间**: {{PLAN_DATE}}
      **当前版本**: {{CURRENT_VERSION}}
      **目标技能**: {{TARGET_SKILL_NAME}}
      **目标技能路径**: {{TARGET_SKILL_ROOT}}
      
      ---
      
      ## 第一部分:独立评估与审查范围(必填)
      
      ### 独立评估原则(强制)
      
      - [ ] 本轮 A 轮评估基于目标 skill 的**当前工作状态**独立完成
      - [ ] **未查看** `plans/` 与 `tests/`(避免确认偏差/路径依赖)
      - [ ] 不以历史问题清单为先验,仅以“当前工作文件”的证据为准
      
      **当前轮次**: A 轮 #{{ROUND_NUMBER}} / 共 {{TOTAL_ROUNDS}} 轮
      
      ### 审查范围(强制)
      
      **必须审查文件**(参考 `config.yaml:a_round_check.independent_review.required_files`):
      - `SKILL.md`
      - `config.yaml`
      
      **必须审查目录**(参考 `config.yaml:a_round_check.independent_review.required_dirs`):
      - `scripts/`
      - `references/`
      - `templates/`
      - `assets/`(如不存在无需补)
      
      **排除范围**:
      - `plans/`、`tests/`、`README.md`、`CHANGELOG.md` 以及 `exclude_patterns` 命中的文件(测试产物、用户文档和变更记录不属于工作代码)
      
      **审查方法(建议)**:使用 Glob/Read/Grep(如 `rg`/`find`)对上述范围做全量扫描,确保不遗漏。
      
      ### 本轮的批判性思维聚焦维度
      
      ⚠️ **必须选择至少一个聚焦维度**(从以下选择):
      
      - [ ] **系统架构**:工作流/配置/文件结构的设计合理性
      - [ ] **过度设计**:不必要的抽象/配置/灵活性
      - [ ] **一致性**:跨文件/跨文档的矛盾
      - [ ] **安全性**:路径遍历/命令注入/信息泄露
      - [ ] **边缘情况**:极端输入/恶意输入/隐式假设
      - [ ] **用户体验**:可理解性/可预测性/错误恢复
      
      **聚焦维度**: {{FOCUS_DIMENSION}}
      
      ### 本轮解决的核心问题(一句话)
      
      {{ONE_LINE_SUMMARY}}
      
      ---
      
      ## 第二部分:批判性思维分析(必填)
      
      ⚠️ **必须使用「刁钻角度」思考**(从 references/CRITICAL_THINKING_GUIDE.md 选择):
      
      ### 选择的刁钻角度
      
      - [ ] **边缘情况**: {{EXTREME_INPUT}} → {{EXTREME_ACTUAL}} → 应该是 {{EXTREME_EXPECTATION}}
      - [ ] **恶意输入**: {{MALICIOUS_SCENARIO}} → 攻击向量 {{ATTACK_VECTOR}} → 当前防御 {{CURRENT_DEFENSE}}
      - [ ] **隐式假设**: {{IMPLICIT_ASSUMPTION}} → 失效场景 {{ASSUMPTION_FAILURE_SCENARIO}}
      - [ ] **自我质疑**: {{QUESTIONED_DESIGN}} → 质疑理由 {{REASON_FOR_QUESTIONING}}
      - [ ] **跨文件矛盾**: 文件 A ({{FILE_A_STATEMENT}}) vs 文件 B ({{FILE_B_STATEMENT}}) → 是否矛盾 {{IS_CONTRADICTORY}}
      
      ### 发现的系统性问题
      
      ⚠️ **必须列出至少 3 个系统性问题**(架构/过度设计/一致/安全):
      
      1. {{SYSTEMIC_ISSUE_1}}
      2. {{SYSTEMIC_ISSUE_2}}
      3. {{SYSTEMIC_ISSUE_3}}
      
      ---
      
      ## 第三部分:问题清单(P0-P2)
      
      ### 优先级定义
      
      | 优先级 | 定义 | 示例 |
      |--------|------|------|
      | **P0** | 阻塞性问题:不修复就无法继续;或安全风险 | 路径遍历漏洞、核心功能缺失 |
      | **P1** | 重要优化:显著提升质量/安全性/可维护性 | 过度设计、冗余、不一致 |
      | **P2** | 锦上添花:改进体验、完善细节 | 注释优化、代码风格 |
      
      **数量要求**:
      - P0 + P1 + P2 总和 ≥ 10
      - P0 + P1 占比 ≥ 60%
      - 系统性问题 ≥ 3 个
      
      ---
      
      ### P0(阻塞/安全/核心)
      
      #### 问题 1: {{P0_1_TITLE}}
      
      **位置**: `{{FILE}}:{{LINE}}`
      
      **问题类型**: [架构设计/安全性/核心功能缺失]
      
      **现象**:
      {{P0_1_PHENOMENON}}
      
      **影响**:
      {{P0_1_IMPACT}}
      
      **修复建议**:
      {{P0_1_FIX}}
      
      **验证方法**:
      {{P0_1_VERIFY}}
      
      ---
      
      ### P1(重要优化)
      
      #### 问题 1: {{P1_1_TITLE}}
      
      **位置**: `{{FILE}}:{{LINE}}`
      
      **问题类型**: [过度设计/冗余/不一致/用户体验]
      
      **现象**:
      {{P1_1_PHENOMENON}}
      
      **影响**:
      {{P1_1_IMPACT}}
      
      **修复建议**:
      {{P1_1_FIX}}
      
      **验证方法**:
      {{P1_1_VERIFY}}
      
      ---
      
      ### P2(锦上添花)
      
      #### 问题 1: {{P2_1_TITLE}}
      
      **位置**: `{{FILE}}:{{LINE}}`
      
      **现象**:
      {{P2_1_PHENOMENON}}
      
      **修复建议**:
      {{P2_1_FIX}}
      
      **验证方法**:
      {{P2_1_VERIFY}}
      
      ---
      
      ## 第四部分:问题质量检查(必填)
      
      ⚠️ **提交前必须确认**:
      
      - [ ] **数量达标**: P0+P1+P2 ≥ 10,P0+P1 占比 ≥ 60%
      - [ ] **系统问题**: 至少 3 个系统性问题(架构/过度设计/一致/安全)
      - [ ] **位置精确**: 每个问题都有精确的 `文件:行号`
      - [ ] **现象具体**: 每个问题都描述了具体现象(不是"应该XX")
      - [ ] **影响明确**: 每个问题都说明了"为什么重要"
      - [ ] **修复具体**: 每个问题都有具体的修复方案(不是"建议优化")
      - [ ] **验证明确**: 每个问题都有可执行的验证方法
      - [ ] **独立评估**: 未查看 `plans/` 与 `tests/`,避免确认偏差/路径依赖
      - [ ] **范围覆盖**: 已覆盖 required_files/required_dirs(并明确排除 tests/plans)
      
      ---
      
      ## 第五部分:执行计划(可选)
      
      {{EXECUTION_PLAN}}
      
      ---
      
      ## 第六部分:完成后的下一轮预告
      
      **预计下一轮聚焦**: {{NEXT_ROUND_FOCUS}}
      
      **预计完成时间**: {{NEXT_ROUND_TIME}}
      
      ---
      
      **模板说明**:
      
      本模板用于 A 轮优化计划的生成。使用时:
      
      1. **替换占位符**: 将 `{{VAR}}` 替换为实际内容
      2. **删除不需要的章节**: 如某些章节不适用,可删除
      3. **核心章节**: 第一部分(全局视图)+ 第二部分(批判性思维)+ 第三部分(问题清单)+ 第四部分(质量检查)必须完整
      
      **关键原则**:
      
      - **独立评估**: 每轮 A 轮基于当前工作状态独立审查,不看 `plans/` 与 `tests/`
      - **批判性思维**: 必须使用"刁钻角度"思考
      - **系统视角**: 必须发现至少 3 个系统性问题
      - **问题质量**: 每个问题都必须有精确的位置、具体的修复方案、可执行的验证方法
      
      **参考文档**:
      
      - 批判性思维框架:`references/CRITICAL_THINKING_GUIDE.md`
      - 问题挖掘技巧:`references/ISSUE_DISCOVERY_TECHNIQUES.md`
      - 建设性建议标准:`references/CONSTRUCTIVE_SUGGESTION_GUIDELINES.md`
      - 反例库:`references/ANTI_PATTERNS_LIBRARY.md`
      
    • CONSTRUCTIVE_SUGGESTION_GUIDELINES.md 7.4 KB
      # 建设性建议标准
      
      **文档版本**:v1.0.0
      **创建时间**:2026-01-14
      **用途**:为 auto-test-skill 提供"什么是建设性建议"的判断标准
      
      ---
      
      ## 核心定义
      
      **建设性建议** = 具体可执行的改进方案,包含明确的修复路径和验证方法。
      
      ---
      
      ## ✅ 建设性建议的特征
      
      ### 1. 可执行
      
      每条建议必须包含具体的修复方案,不是"应该改进XX"这种泛泛而谈。
      
      **示例**:
      - ❌ "建议增加更多日志"
      - ✅ "在 `scripts/foo.py` 第 42 行的 `except` 块中,记录具体的异常类型和堆栈信息"
      
      ### 2. 有证据
      
      每条建议必须基于具体文件/行号/代码,不是凭空猜测。
      
      **示例**:
      - ❌ "建议优化文档结构"
      - ✅ "SKILL.md 第 30 行的描述与 config.yaml 第 15 行不一致,应统一为'XXX'"
      
      ### 3. 有价值
      
      修复后能带来明显的质量提升(安全性/可维护性/用户体验)。
      
      **示例**:
      - ❌ "建议优化注释风格"(价值低)
      - ✅ "建议增加路径遍历防御"(安全性提升)
      
      ### 4. 可验证
      
      每条建议必须包含明确的验证方法,确认修复成功。
      
      **示例**:
      - ❌ "建议修复配置加载逻辑"
      - ✅ "建议修复配置加载逻辑:验证方法 → 在 `tests/` 中运行空配置文件测试,确认有默认值回退"
      
      ---
      
      ## ❌ 非建设性建议的例子
      
      ### 类型 1:泛泛而谈
      
      | ❌ 泛泛建议 | ✅ 建设性建议 |
      |------------|--------------|
      | "建议增加更多日志" | "在 `scripts/foo.py` 第 42 行的 `except` 块中,记录异常类型和堆栈" |
      | "建议优化文档" | "SKILL.md 第 30 行与 config.yaml 第 15 行不一致,应统一为..." |
      | "建议增强测试" | "缺少 `--dry-run` 参数的测试,应在 `tests/` 中增加验证用例" |
      | "建议改进错误处理" | "第 88 行的 `except` 块捕获了所有异常但未记录,应细化为具体异常类型" |
      
      ### 类型 2:无具体位置
      
      | ❌ 无位置建议 | ✅ 建设性建议 |
      |--------------|--------------|
      | "某个配置项没有说明" | "config.yaml 第 23 行的 `timeout` 项缺少单位说明,应补充为'秒'" |
      | "代码中有重复逻辑" | "`scripts/bar.py` 第 105-110 行与第 145-150 行完全相同,应提取为函数" |
      | "示例无法运行" | "README.md 第 18 行的示例命令缺少必需的 `--input` 参数" |
      
      ### 类型 3:价值不明确
      
      | ❌ 价值不明确 | ✅ 建设性建议 |
      |--------------|--------------|
      | "建议统一注释风格" | "建议统一注释风格:当前混用 `#` 和 `//`,导致某些编辑器语法高亮失效" |
      | "建议优化变量命名" | "建议优化变量命名:`tmp1`/`tmp2` 无法表达用途,改为 `input_path`/`output_path`" |
      | "建议重构函数" | "建议重构 `process()` 函数:当前 200 行,包含 3 层嵌套,难以测试" |
      
      ### 类型 4:无验证方法
      
      | ❌ 无验证方法 | ✅ 建设性建议 |
      |--------------|--------------|
      | "建议修复路径验证" | "建议修复路径验证:验证方法 → 构造输入 `../../etc/passwd`,确认被拒绝" |
      | "建议增加默认值" | "建议增加默认值:验证方法 → 删除 config.yaml 中的该配置项,确认仍能运行" |
      | "建议更新文档" | "建议更新文档:验证方法 → 按照文档步骤执行,确认能成功运行" |
      
      ---
      
      ## 建设性建议的"黄金公式"
      
      ```
      位置 + 问题现象 + 影响分析 + 具体修复方案 + 验证方法
      ```
      
      ### 完整示例
      
      **位置**:`scripts/validator.py:45-48`
      
      **问题现象**:
      ```python
      # 当前代码
      if path.startswith("../"):
          raise ValueError("Invalid path")
      ```
      
      **影响分析**:
      - 只检查 `../` 前缀,无法防御 `..\\`(Windows)、`./../`、绝对路径绕过等攻击向量
      - 存在路径遍历漏洞风险
      
      **具体修复方案**:
      ```python
      # 修复后代码
      import os
      resolved = os.path.realpath(path)
      if not resolved.startswith(os.path.realpath(base_dir)):
          raise ValueError(f"Path {path} is outside base directory")
      ```
      
      **验证方法**:
      1. 构造恶意输入 `../../etc/passwd`,确认被拒绝
      2. 构造绕过输入 `./../../etc/passwd`,确认被拒绝
      3. 构造合法输入 `data/test.csv`,确认通过验证
      
      ---
      
      ## 建议质量自检清单
      
      在提交建议前,确认每条建议都满足:
      
      - [ ] **包含具体位置**:文件名 + 行号(如 `SKILL.md:30`)
      - [ ] **包含修复方案**:不是"建议"而是"改为..."
      - [ ] **包含验证方法**:如何确认修复成功
      - [ ] **有明确价值**:能提升安全性/可维护性/用户体验
      - [ ] **可独立执行**:不需要额外的上下文信息
      
      ---
      
      ## 常见反模式
      
      ### 反模式 1:"应该"式建议
      
      ❌ "应该增加错误处理"
      ✅ "第 42 行缺少对 `FileNotFoundError` 的处理,应增加 `try-except` 块"
      
      ### 反模式 2:"问题列表"式建议
      
      ❌ "问题:1) 无日志 2) 无测试 3) 无文档"
      ✅ 拆分为 3 条独立建议,每条都有位置和修复方案
      
      ### 反模式 3:"模糊优化"式建议
      
      ❌ "建议优化性能"
      ✅ "第 88 行的循环嵌套复杂度为 O(n²),建议改用字典降低到 O(n)"
      
      ### 反模式 4:"假设用户会"式建议
      
      ❌ "建议用户先创建目录"
      ✅ "脚本应自动创建目录,而非假设用户已创建(见 `scripts/foo.py:55`)"
      
      ---
      
      ## 不同优先级的建议标准
      
      ### P0 建议(必须修复)
      
      **特征**:
      - 阻塞性问题:不修复就无法继续
      - 安全风险:路径遍历、命令注入、敏感信息泄露
      - 核心功能缺失:缺少关键功能、无法完成基本任务
      
      **示例**:
      - "存在路径遍历漏洞(`scripts/validator.py:45`),用户可访问任意文件"
      - "缺少必需的配置项 `api_key`(`config.yaml`),导致脚本无法启动"
      
      ### P1 建议(强烈建议)
      
      **特征**:
      - 重要优化:显著提升质量/安全性/可维护性
      - 测试覆盖不足:核心功能缺少测试
      - 文档缺失:用户无法理解如何使用
      
      **示例**:
      - "缺少对 `--dry-run` 参数的测试(`tests/`),建议增加验证用例"
      - "SKILL.md 第 30 行缺少步骤 2 的详细说明,用户无法正确执行"
      
      ### P2 建议(可选)
      
      **特征**:
      - 改进体验:提升可用性、易读性
      - 完善细节:注释、代码风格、命名
      - 后续迭代:不影响当前使用的改进
      
      **示例**:
      - "变量名 `tmp1`/`tmp2` 不够直观(`scripts/bar.py:105`),建议改为 `input_path`/`output_path`"
      - "建议统一注释风格:当前混用 `#` 和 `//`(`scripts/*.py`)"
      
      ---
      
      ## 数量要求
      
      根据 auto-test-skill 的要求:
      
      - **每轮 A 轮**:至少 10 个问题(P0 + P1 + P2 总和),鼓励 15-20 个
      - **B 轮检查**:至少 10-20 个建设性建议
      
      **建议分布**(参考):
      - P0:2-4 个(如无严重问题,可少于 2 个)
      - P1:4-8 个(重点)
      - P2:4-8 个(锦上添花)
      
      ---
      
      ## 本轮建议质量检查
      
      在提交建议前,回答以下问题:
      
      1. **位置明确吗?** 每条建议都包含文件名和行号
      2. **方案具体吗?** 每条建议都描述了"改为..."而非"建议..."
      3. **可验证吗?** 每条建议都有明确的验证方法
      4. **有价值吗?** 每条建议都能带来明显的质量提升
      5. **数量达标吗?** 总数 ≥ 10,且 P0+P1 占比 ≥ 60%
      
      ---
      
      **模板说明**:
      
      本文档用于指导 auto-test-skill 生成高质量的建设性建议。
      
      使用时:
      1. 参考本文档的"黄金公式"撰写建议
      2. 使用"建议质量自检清单"验证每条建议
      3. 确保建议数量和优先级分布符合要求
      
    • CRITICAL_THINKING_GUIDE.md 13.8 KB
      # 批判性思维指南
      
      **文档版本**:v1.1.0
      **创建时间**:2026-01-16
      **用途**:为 auto-test-skill 提供「如何进行批判性思考」的思考框架
      
      ---
      
      ## 核心思想
      
      **批判性思维** ≠ 找茬
      = 系统性质疑 + 多角度验证 + 边缘情况探索 + 深度挖掘
      
      本文档提供**三大思考框架**,帮助 AI 在每轮 A 轮中发现真正有价值的问题。
      
      ---
      
      ## A 轮独立评估(强制)
      
      在 auto-test-skill 中,每轮 A 轮默认采用**独立评估**模式:
      
      - **不查看**上轮的 `plans/` 与 `tests/`(避免确认偏差/路径依赖)
      - 只基于目标 skill 的**当前工作文件**证据(如 `SKILL.md`、`config.yaml`、`scripts/`、`references/`、`templates/` 等;排除 `README.md`、`CHANGELOG.md` 等非工作文件)
      - 目标:让"多轮"带来"多角度",而不是"重复确认同一结论"
      
      ### 独立评估 vs 渐进式评估(对比)
      
      | 维度 | 独立评估(默认) | 渐进式评估(谨慎使用) |
      |------|------------------|------------------------|
      | 输入依赖 | 不依赖上轮产物 | 强依赖上轮计划/报告 |
      | 偏差风险 | 更低(减少确认偏差) | 更高(容易路径依赖) |
      | 多轮价值 | 更稳定(角度更分散) | 递减风险更高(只盯变更点) |
      | 适用场景 | 用户要求多轮审查/需要多角度发现问题 | 用户明确要求“沿着上轮路线持续修复/追踪同一议题” |
      
      ---
      
      ## 框架 1: 系统视角思考
      
      ### 目的
      避免"盲人摸象",从**系统架构**层面审视技能的设计合理性。
      
      ### 思考维度
      
      #### 维度 1: 这个技能的核心价值是什么?
      
      **自问清单**:
      - 这个技能要解决的核心问题是什么?
      - 当前设计是否真的解决了这个问题?
      - 是否有更简单的解决方案?
      
      **高质量问题示例**:
      ```
      问题:auto-test-skill 的核心价值是"发现系统性问题",
      但当前工作流只要求"列出 10 个问题",没有区分"表面问题"vs"深层问题"。
      位置:SKILL.md:87-90(问题数量要求)
      优先级:P0
      修复:增加"问题深度检查",要求每轮至少 3 个"系统性问题"
      ```
      
      #### 维度 2: 工作流的每个步骤都必要吗?
      
      **自问清单**:
      - 这个步骤是否真正贡献于最终目标?
      - 删除这个步骤会怎样?
      - 能否合并相似步骤?
      
      **高质量问题示例**:
      ```
      问题:工作流包含"执行优化"和"轻量测试"两个独立步骤,
      但"优化"的本质就是"验证修复效果",两者重叠。
      位置:SKILL.md:105-115
      优先级:P1
      修复:合并为"修复并验证"步骤,减少文档冗余
      ```
      
      #### 维度 3: 配置项真的需要可配置吗?
      
      **自问清单**:
      - 这个配置项在不同使用场景下会有不同值吗?
      - 如果只有一个合理值,为什么还要配置?
      - 硬编码会失去什么灵活性?
      
      **高质量问题示例**:
      ```
      问题:output_format 配置项只有 "json" 一个有效值(无其他格式支持),
      过度配置化,增加理解成本。
      位置:config.yaml:30
      优先级:P1
      修复:移除配置项,直接硬编码为 "json"
      ```
      
      #### 维度 4: 文件结构反映了什么样的设计理念?
      
      **自问清单**:
      - 目录结构是否清晰传达了技能的用途?
      - 是否存在"职责不清"的文件?
      - 文件之间的依赖关系是否合理?
      
      **高质量问题示例**:
      ```
      问题:references/ 目录下混合了"模板"和"指南"两类文档,
      但没有清晰的命名区分,难以快速定位。
      位置:references/
      优先级:P2
      修复:重命名文件,添加前缀:TEMPLATE_*.md vs GUIDE_*.md
      ```
      
      ---
      
      ## 框架 2: 刁钻角度思考
      
      ### 目的
      通过**极端情况、恶意输入、隐式假设**等刁钻角度,发现隐藏问题。
      
      ### 角度 1: 边缘情况压力测试
      
      **测试场景矩阵**:
      
      | 输入类型 | 正常输入 | 边缘输入 | 极端输入 | 恶意输入 |
      |----------|----------|----------|----------|----------|
      | **路径** | `data/test.csv` | `path with spaces` | `""` (空字符串) | `../../etc/passwd` |
      | **配置** | 完整 YAML | `{}` (空配置) | `timeout: -1` (非法值) | 恶意 YAML 注入 |
      | **文件** | 1MB 文件 | 0 字节文件 | 10GB 文件 | 特殊字符文件 (`\n`, `\0`) |
      
      **高质量问题示例**:
      ```
      问题:路径验证只检查 `../` 前缀,无法防御 `./../` 绕过攻击。
      攻击向量:用户输入 `./../../etc/passwd` 可访问任意文件
      位置:scripts/validator.py:45
      优先级:P0
      修复:使用 os.path.realpath() 规范化后再验证
      验证:构造输入 `./../../etc/passwd`,确认被拒绝
      ```
      
      ### 角度 2: 恶意用户测试
      
      **攻击场景清单**:
      1. **路径遍历**:能否访问 `../../etc/passwd`?
      2. **命令注入**:能否通过 `; rm -rf /` 执行任意命令?
      3. **资源耗尽**:能否通过超大文件(>1GB)耗尽内存?
      4. **并发竞态**:能否通过同时修改配置文件破坏系统?
      5. **符号链接攻击**:能否通过 symlink 读取敏感文件?
      
      **高质量问题示例**:
      ```
      问题:未验证符号链接,用户可创建 symlink 到 `/etc/passwd`,
      脚本会跟随 symlink 读取敏感文件。
      位置:scripts/reader.py:34
      优先级:P0
      修复:验证解析后的路径是否在 base_dir 内
      验证:创建 symlink 到敏感文件,确认被拒绝
      ```
      
      ### 角度 3: 隐式假设识别
      
      **关键词搜索**(发现未验证的假设):
      - `应该` → 通常意味着"实际上没做"
      - `会` → 通常意味着"假设会发生"
      - `自动` → 通常意味着"没有验证"
      - `用户` → 通常意味着"假设用户会做某事"
      
      **高质量问题示例**:
      ```
      问题:"用户应先创建目录" → 假设用户会手动创建目录,
      但实际不会,导致脚本失败。
      位置:SKILL.md:55
      优先级:P1
      修复:脚本应自动创建目录(见 scripts/setup.py:12)
      验证:在空目录运行脚本,确认自动创建目录
      ```
      
      ### 角度 4: 自我质疑法
      
      **对每个设计决策问**:
      - "这个设计真的有用吗?还是'自我感动'?"
      - "有更简单的实现方式吗?"
      - "这个配置项真的需要吗?"
      
      **高质量问题示例**:
      ```
      问题:session_format 配置项使用复杂的 Jinja2 模板语法
      (`v{year}{month}{day}{hour}{minute}`),但实际只有一个固定格式。
      位置:config.yaml:24
      优先级:P1
      修复:移除配置项,直接使用 Python datetime 格式化
      理由:过度设计,增加理解成本
      ```
      
      ---
      
      ## 框架 3: 问题质量标准
      
      ### 目的
      避免"凑够 10 个问题",确保每个问题都有**真正的价值**。
      
      ### 黄金标准
      
      每个问题必须满足:
      
      ```
      位置 + 现象 + 影响(为什么重要) + 修复方案 + 验证方法
      ```
      
      ### 质量检查清单
      
      在提交问题前,确认每条问题都满足:
      
      #### 检查 1: 位置精确吗?
      - ❌ "某个配置项没有说明"
      - ✅ "config.yaml 第 23 行的 `retry_delay` 配置项缺少说明"
      
      #### 检查 2: 现象具体吗?
      - ❌ "建议增加错误处理"
      - ✅ "第 42 行缺少对 `FileNotFoundError` 的处理,文件不存在时会崩溃"
      
      #### 检查 3: 影响明确吗?
      - ❌ "影响用户体验"
      - ✅ "用户无法恢复错误,只能重新运行整个流程"
      
      #### 检查 4: 修复方案具体吗?
      - ❌ "建议优化文档"
      - ✅ "在 config.yaml 第 23 行增加注释:`# 重试延迟(秒)`"
      
      #### 检查 5: 验证方法明确吗?
      - ❌ "验证修复成功"
      - ✅ "构造输入 `../../etc/passwd`,确认被拒绝"
      
      ---
      
      ## 问题优先级判定
      
      ### P0(阻塞/安全/核心)
      
      **特征**:
      - 不修复就无法使用
      - 存在安全风险(路径遍历、命令注入、信息泄露)
      - 核心功能缺失
      
      **示例**:
      ```
      问题:存在路径遍历漏洞,用户可访问任意文件
      位置:scripts/validator.py:45
      优先级:P0
      理由:安全风险,可能泄露敏感信息
      ```
      
      ### P1(重要优化)
      
      **特征**:
      - 显著提升质量/安全性/可维护性
      - 影响核心工作流
      - 过度设计/冗余/不一致
      
      **示例**:
      ```
      问题:output_format 配置项只有一个有效值,过度设计
      位置:config.yaml:30
      优先级:P1
      理由:增加理解成本,无实际灵活性
      ```
      
      ### P2(锦上添花)
      
      **特征**:
      - 改进体验、完善细节
      - 不影响核心功能
      - 后续迭代
      
      **示例**:
      ```
      问题:变量名 `tmp1` 不够直观
      位置:scripts/bar.py:105
      优先级:P2
      理由:不影响功能,但影响可读性
      ```
      
      ---
      
      ## 数量要求(强制)
      
      ### A 轮要求
      
      **最低要求**(不满足则继续挖掘):
      - P0 + P1 + P2 总和 ≥ 10
      - P0 + P1 占比 ≥ 60%
      
      **推荐分布**:
      - P0:2-4 个(系统性问题、安全风险)
      - P1:4-8 个(过度设计、冗余、一致性)
      - P2:3-6 个(细节优化)
      
      ### 系统性问题专项要求
      
      **每轮必须包含至少 3 个"系统性问题"**:
      
      | 系统性问题类型 | 定义 | 示例 |
      |---------------|------|------|
      | **架构设计问题** | 工作流/配置/文件结构层面的设计缺陷 | "工作流步骤重叠,无明确职责分工" |
      | **过度设计问题** | 不必要的抽象/配置/灵活性 | "只有一个值的配置项" |
      | **一致性问题** | 跨文件/跨文档的矛盾 | "SKILL.md 说 X,config.yaml 说 Y" |
      | **安全性问题** | 路径遍历/命令注入/信息泄露 | "未验证符号链接" |
      
      ---
      
      ## 批判性思维检查清单
      
      ### 在提交 A 轮计划前,确认:
      
      - [ ] **系统视角**:是否从架构层面审视设计合理性?
      - [ ] **刁钻角度**:是否测试了边缘情况、恶意输入、隐式假设?
      - [ ] **问题质量**:每个问题都包含位置+现象+影响+修复+验证吗?
      - [ ] **优先级合理**:P0/P1 占比 ≥ 60% 吗?
      - [ ] **系统性问题**:至少 3 个系统性问题(架构/过度设计/一致/安全)吗?
      - [ ] **独立评估**:是否未查看 `plans/` 与 `tests/`,避免确认偏差/路径依赖?
      - [ ] **范围覆盖**:是否覆盖必要工作文件/目录(而非只看变更点)?
      
      ---
      
      ## 高质量问题示例库
      
      ### 示例 1: 系统性架构问题
      
      ```
      问题:auto-test-skill 的核心价值是"发现系统性问题",
      但当前工作流只要求"列出 10 个问题",没有区分"表面问题"vs"深层问题"。
      
      位置:SKILL.md:87-90(问题数量要求)
      
      问题类型:架构设计问题
      
      现象:
      工作流只规定了问题数量(≥ 10),未规定问题质量,
      导致 AI 倾向于列出"不痛不痒"的表面问题(如"缺少注释")。
      
      影响:
      技能无法实现"发现系统性问题"的核心价值,
      沦为"表面问题列表生成器"。
      
      优先级:P0
      
      修复建议:
      在 SKILL.md 第 87-90 行增加"问题深度要求":
      ```
      ### 问题深度要求(强制)
      每轮必须包含至少 3 个"系统性问题":
      - 架构设计问题(工作流/配置/文件结构)
      - 过度设计问题(不必要的抽象/配置)
      - 一致性问题(跨文件矛盾)
      - 安全性问题(路径遍历/命令注入)
      ```
      
      验证方法:
      执行 3 轮 A 轮测试,确认每轮都包含至少 3 个系统性问题。
      ```
      
      ### 示例 2: 过度设计问题
      
      ```
      问题:session_format 配置项使用复杂的 Jinja2 模板语法,
      但实际只有一个固定格式。
      
      位置:config.yaml:24
      
      问题类型:过度设计问题
      
      现象:
      ```yaml
      session_format: "v{year}{month}{day}{hour}{minute}"
      ```
      这个配置项看似"灵活",但实际上:
      1. 没有其他格式选项
      2. 用户不需要自定义时间戳格式
      3. 增加 YAML 解析复杂度(需要 Jinja2 引擎)
      
      影响:
      - 过度设计,增加理解成本
      - 增加 YAML 解析复杂度
      - 无实际灵活性
      
      优先级:P1
      
      修复建议:
      移除 session_format 配置项,直接使用 Python datetime 格式化:
      ```python
      # scripts/create_test_session.py
      session_id = datetime.now().strftime("v%Y%m%d%H%M")
      ```
      
      验证方法:
      1. 删除 config.yaml 中的 session_format
      2. 运行 scripts/create_test_session.py
      3. 确认生成的 session_id 格式为 v202601161200
      ```
      
      ### 示例 3: 安全性问题
      
      ```
      问题:路径验证只检查 `../` 前缀,无法防御绕过攻击。
      
      位置:scripts/validator.py:45-48
      
      问题类型:安全性问题
      
      现象:
      ```python
      if path.startswith("../"):
          raise ValueError("Invalid path")
      ```
      只检查 `../` 前缀,但以下攻击向量可绕过:
      - `./../etc/passwd`
      - `.././../etc/passwd`
      - 绝对路径 `/etc/passwd`
      - Windows: `..\\..\\windows\\system32`
      
      影响:
      存在路径遍历漏洞,用户可访问任意文件,
      包括敏感信息(如 `/etc/passwd`、`~/.ssh/id_rsa`)。
      
      优先级:P0
      
      修复建议:
      ```python
      import os
      
      resolved = os.path.realpath(path)
      base_dir = os.path.realpath("./data")
      
      if not resolved.startswith(base_dir):
          raise ValueError(f"Path {path} is outside base directory")
      
      return resolved
      ```
      
      验证方法:
      1. 构造输入 `./../../etc/passwd`,确认被拒绝
      2. 构造输入 `.././../etc/passwd`,确认被拒绝
      3. 构造输入 `data/test.csv`,确认通过
      ```
      
      ---
      
      ## 使用指南
      
      ### 何时使用本文档?
      
      在执行 A 轮测试时,按以下顺序使用:
      
      1. **开始前**:阅读「框架 1: 系统视角思考」,建立全局意识
      2. **分析时**:使用「框架 2: 刁钻角度思考」,挖掘隐藏问题
      3. **评估时**:使用「框架 3: 问题质量标准」,确保问题价值
      4. **提交前**:使用「批判性思维检查清单」,最后把关
      
      ### 组合使用技巧
      
      为达到 10-20 个高质量问题,建议组合使用:
      
      1. **系统视角**(框架 1)→ 发现 3-5 个系统性问题(P0/P1)
      2. **刁钻角度**(框架 2)→ 发现 3-5 个安全性/边缘问题(P0/P1)
      3. **常规检查**(ISSUE_DISCOVERY_TECHNIQUES.md)→ 发现 4-8 个细节问题(P1/P2)
      
      **总计**:10-18 个问题,P0+P1 占比 ≥ 60%
      
      ---
      
      **模板说明**:
      
      本文档是 auto-test-skill 的核心思考指南。
      
      使用时:
      1. 每轮 A 轮开始前,快速浏览三大框架
      2. 挖掘问题时,对照框架检查是否遗漏重要角度
      3. 提交前,使用检查清单最后把关
      
    • ISSUE_DISCOVERY_TECHNIQUES.md 9.8 KB
      # 问题挖掘技巧
      
      **文档版本**:v1.0.0
      **创建时间**:2026-01-14
      **用途**:为 auto-test-skill 提供"如何深入挖掘问题"的技巧库
      
      ---
      
      ## 核心思想
      
      **问题挖掘** = 系统化的质疑 + 多角度的验证 + 边缘情况的探索
      
      本文档提供 10 大类问题挖掘技巧,帮助 AI 在每轮 A 轮中发现 10-20 个建设性问题。
      
      ---
      
      ## 技巧 1: 文件间交叉验证
      
      ### 方法
      检查 A 文件引用的内容,在 B 文件中是否存在/一致。
      
      ### 检查清单
      - [ ] SKILL.md 引用的配置项,在 config.yaml 中是否存在?
      - [ ] README.md 中的示例,与 SKILL.md 的工作流是否一致?
      - [ ] 脚本注释中的"路径",与实际目录结构是否匹配?
      - [ ] 文档中引用的模板文件(`references/XXX.md`),实际是否存在?
      - [ ] YAML frontmatter 中的 `name`,与目录名是否一致?
      
      ### 典型发现
      ```
      问题:SKILL.md 第 30 行说"参考 config.output_dir",但 config.yaml 中是 "output.directory"
      位置:SKILL.md:30, config.yaml:15
      优先级:P1
      修复:统一为 "output.directory"
      ```
      
      ---
      
      ## 技巧 2: 逻辑推演找漏洞
      
      ### 方法
      问自己:"如果 X 发生,会怎样?"(X 是异常情况)
      
      ### 检查清单
      - [ ] 如果用户跳过步骤 1,直接执行步骤 2 会怎样?
      - [ ] 如果 config.yaml 中的这个参数是空值会怎样?
      - [ ] 如果用户输入的路径包含空格或特殊字符会怎样?
      - [ ] 如果网络请求失败会怎样?有重试机制吗?
      - [ ] 如果输入文件是空的会怎样?
      
      ### 典型发现
      ```
      问题:如果 config.timeout 为空,脚本会崩溃(未设置默认值)
      位置:scripts/loader.py:42
      优先级:P0
      修复:增加默认值 timeout = config.get("timeout", 30)
      ```
      
      ---
      
      ## 技巧 3: 文档"读心术"
      
      ### 方法
      找出文档中的"模糊词"和"未验证的假设"
      
      ### 关键词搜索
      搜索以下词汇,发现潜在问题:
      - `应该` → 通常意味着"实际上没做"
      - `会` → 通常意味着"假设会发生"
      - `自动` → 通常意味着"没有手动验证"
      - `例如`、`如` → 检查示例是否真的可运行
      - `详见`、`参考` → 检查被引用的文件是否存在
      - `用户` → 检查是否假设用户会做某事
      
      ### 典型发现
      ```
      问题:"用户应先创建目录" → 假设用户会手动创建,实际不会
      位置:SKILL.md:55
      优先级:P1
      修复:脚本应自动创建目录(见 scripts/setup.py:12)
      ```
      
      ---
      
      ## 技巧 4: 代码/文档"模式匹配"
      
      ### 方法
      使用 Grep 工具搜索特定模式,发现隐藏问题
      
      ### 搜索模式
      | 模式 | 目的 | 典型问题 |
      |------|------|----------|
      | `TODO`、`FIXME`、`HACK` | 未完成的技术债 | 功能未完成、临时方案未清理 |
      | `print(`、`console.log` | 未清理的调试代码 | 生产代码包含调试输出 |
      | `#` 注释中的"临时"、"测试" | 未清理的临时内容 | 标记为临时的代码仍在使用 |
      | `except:` (无异常类型) | 过于宽泛的异常捕获 | 隐藏真实错误、难以调试 |
      | `os.system`、`subprocess.call` | 潜在的命令注入风险 | 未验证用户输入 |
      | `pass` | 空的实现 | 函数/类未实现 |
      
      ### 典型发现
      ```
      问题:scripts/processor.py:88 包含 `except:` 捕获所有异常,隐藏真实错误
      位置:scripts/processor.py:88
      优先级:P1
      修复:细化为具体异常类型(如 FileNotFoundError, ValueError)
      ```
      
      ---
      
      ## 技巧 5: "挑刺"清单
      
      ### 方法
      系统化地检查每个"应该有"的东西是否真的存在
      
      ### 通用清单
      - [ ] 每个配置项都有说明吗?
      - [ ] 每个示例都能运行吗?
      - [ ] 每个引用的文件都存在吗?
      - [ ] 每个步骤都有验证方法吗?
      - [ ] 每个错误都有明确的错误提示吗?
      - [ ] 每个函数都有 docstring 吗?
      - [ ] 每个脚本都有 `if __name__ == "__main__"` 保护吗?
      
      ### SKILL.md 专项清单
      - [ ] YAML `description` 与正文描述一致吗?
      - [ ] 工作流步骤完整吗?(从输入到输出)
      - [ ] 配置说明与 config.yaml 一致吗?
      - [ ] 示例命令可复制粘贴运行吗?
      - [ ] 完成条件可验证吗?
      
      ### 典型发现
      ```
      问题:config.yaml 第 23 行的 `retry_delay` 配置项在文档中无说明
      位置:config.yaml:23
      优先级:P2
      修复:在 config.yaml 中增加注释说明用途和默认值
      ```
      
      ---
      
      ## 技巧 6: 边缘情况压力测试
      
      ### 方法
      构造极端输入,验证 skill 的鲁棒性
      
      ### 测试场景
      | 输入类型 | 测试值 | 预期行为 |
      |----------|--------|----------|
      | **路径** | `../../etc/passwd` | 被拒绝(路径遍历防御) |
      | **路径** | `path with spaces` | 正常处理(路径规范化) |
      | **路径** | 空字符串 `""` | 有明确错误提示 |
      | **配置** | 空文件 `{}` | 使用默认值 |
      | **配置** | 无效值(如 `timeout: -1`) | 有明确错误提示 |
      | **输入** | 超大文件(>1GB) | 有进度提示或分块处理 |
      | **输入** | 空文件 | 有明确错误提示 |
      | **输入** | 特殊字符(`\n`, `\0`) | 正确转义或拒绝 |
      
      ### 典型发现
      ```
      问题:路径验证只检查 `../` 前缀,无法防御 `./../` 绕过
      位置:scripts/validator.py:45
      优先级:P0
      修复:使用 os.path.realpath() 规范化后再验证
      ```
      
      ---
      
      ## 技巧 7: "自我质疑"法
      
      ### 方法
      对每个设计决策问:"真的需要吗?有更简单的方式吗?"
      
      ### 质疑清单
      - [ ] 这个配置项真的需要可配置吗?还是可以硬编码?
      - [ ] 这个函数/类真的需要抽象吗?还是可以简化?
      - [ ] 这个步骤真的需要用户手动执行吗?还是可以自动化?
      - [ ] 这个检查真的需要吗?还是过度防御?
      - [ ] 这个文档真的需要单独文件吗?还是可以合并?
      
      ### 典型发现
      ```
      问题:output_format 配置项只有 "json" 一个有效值,过度设计
      位置:config.yaml:30
      优先级:P2
      修复:移除配置项,直接硬编码为 "json"
      ```
      
      ---
      
      ## 技巧 8: 安全性扫描
      
      ### 方法
      系统性检查常见安全漏洞
      
      ### 扫描清单
      - [ ] **路径遍历**:用户输入的路径是否验证?
      - [ ] **命令注入**:用户输入是否直接用于系统命令?
      - [ ] **敏感信息泄露**:日志/错误中是否包含密钥、密码?
      - [ ] **不安全的反序列化**:对不可信数据直接反序列化?
      - [ ] **硬编码密钥**:API 密钥、密码是否写在代码中?
      
      ### 典型发现
      ```
      问题:用户输入直接用于 os.system,存在命令注入风险
      位置:scripts/runner.py:67
      优先级:P0
      修复:使用 subprocess.run 与参数化参数
      ```
      
      ---
      
      ## 技巧 9: 用户体验(UX)审查
      
      ### 方法
      模拟真实用户,评估使用体验
      
      ### 评估维度
      - [ ] **第一印象**:新用户能在 5 分钟内理解如何使用吗?
      - [ ] **错误恢复**:出错时,文档是否告诉用户如何恢复?
      - [ ] **反馈及时**:长时间操作是否有进度提示?
      - [ ] **错误友好**:错误信息是否告诉用户具体问题和解决方法?
      - [ ] **可预测性**:用户能预期每一步的结果吗?
      
      ### 典型发现
      ```
      问题:错误信息 "Error: failed" 无法告诉用户具体问题
      位置:scripts/loader.py:52
      优先级:P1
      修复:改为 "Error: failed to load config.yaml: file not found"
      ```
      
      ---
      
      ## 技巧 10: "如果我是恶意用户"测试
      
      ### 方法
      站在攻击者视角,尝试破坏 skill
      
      ### 攻击场景
      1. **路径遍历攻击**:输入 `../../etc/passwd`
      2. **命令注入攻击**:输入 `; rm -rf /`
      3. **配置注入**:输入恶意 YAML(如利用 YAML 解析器漏洞)
      4. **资源耗尽**:输入超大文件(>1GB)
      5. **并发竞态**:同时修改配置文件
      6. **符号链接攻击**:创建符号链接到敏感文件
      
      ### 典型发现
      ```
      问题:未验证符号链接,用户可能通过 symlink 读取任意文件
      位置:scripts/reader.py:34
      优先级:P0
      修复:验证解析后的路径是否在 base_dir 内
      ```
      
      ---
      
      ## 组合使用技巧
      
      ### 单轮检查策略
      
      为达到 10-20 个问题,建议组合使用:
      
      1. **技巧 1(交叉验证)**:2-4 个问题
      2. **技巧 2(逻辑推演)**:2-3 个问题
      3. **技巧 3(读心术)**:2-3 个问题
      4. **技巧 4(模式匹配)**:1-2 个问题
      5. **技巧 6(边缘情况)**:2-3 个问题
      6. **技巧 8(安全性)**:1-2 个问题(如无安全问题可跳过)
      7. **技巧 9(UX 审查)**:1-2 个问题
      
      **总计**:11-19 个问题
      
      ### 深度挖掘策略
      
      当表面问题已发现完,需要深入挖掘时:
      
      1. **逐行阅读**:从 SKILL.md 第一行开始,逐行质疑
      2. **执行演练**:假装执行工作流,记录每个卡点
      3. **反向思考**:从输出倒推,验证每个步骤是否必要
      4. **对比分析**:与类似 skill 对比,找出差异点
      
      ---
      
      ## 问题记录模板
      
      发现问题时,使用以下模板记录:
      
      ```
      #### 问题 X: [简短标题]
      
      **位置**: `文件:行号`
      
      **问题类型**: [交叉验证/逻辑漏洞/文档模糊/安全性/UX/...]
      
      **问题描述**:
      [具体描述问题现象]
      
      **影响**:
      [这个问题会导致什么后果]
      
      **优先级**: P0/P1/P2
      
      **修复建议**:
      [具体的修复方案]
      
      **验证方法**:
      [如何确认修复成功]
      ```
      
      ---
      
      ## 数量达标策略
      
      ### 策略 1: "每个技巧至少 1 个问题"
      
      使用 10 大技巧,每技巧至少发现 1 个问题 = 10 个问题
      
      ### 策略 2: "逐文件地毯式搜索"
      
      对每个文件使用"挑刺清单":
      - SKILL.md:5-8 个问题
      - config.yaml:2-3 个问题
      - scripts/*.py:3-5 个问题
      - README.md:2-3 个问题
      
      总计:12-19 个问题
      
      ### 策略 3: "优先级分布法"
      
      - P0:2-4 个(安全/阻塞问题)
      - P1:5-8 个(重要优化)
      - P2:3-6 个(锦上添花)
      
      总计:10-18 个问题
      
      ---
      
      **模板说明**:
      
      本文档用于指导 auto-test-skill 深入挖掘问题。
      
      使用时:
      1. 选择 3-5 个技巧组合使用
      2. 每个技巧至少发现 2 个问题
      3. 确保问题总数 ≥ 10,且 P0+P1 占比 ≥ 60%
      4. 使用"问题记录模板"标准化记录
      
    • TESTING_BEST_PRACTICES.md 1.3 KB
      # 测试驱动优化:轻量测试最佳实践
      
      本文件用于为 `auto-test-skill` 提供稳定、可复用的参考原则,避免在 SKILL.md 中反复硬编码细节。
      
      ## 轻量测试的边界
      
      - 目标:验证“关键路径”与“最近修改的行为”是否正确,不追求全覆盖。
      - 原则:快、明确、可重复、可追溯。
      
      ## 测试会话的最小产出
      
      每轮测试会话目录至少包含:
      
      - `TEST_PLAN.md`:本轮验证点与通过标准
      - `TEST_REPORT.md`:本轮结果、证据与结论
      
      推荐包含:
      
      - `_artifacts/`:日志、输出、截图、对比结果等
      - `_scripts/`:必要的临时测试脚本(尽量保持小且可删)
      
      ## 命名与目录
      
      - 规划文档:`.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/vYYYYMMDDHHMM.md`
      - A轮测试:`.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/vYYYYMMDDHHMM/`
      - B轮检查:`.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/B轮-vYYYYMMDDHHMM.md`
      - B轮验证:`.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/B轮-vYYYYMMDDHHMM/`
      
      ## 记录原则
      
      - 一个结论必须对应至少一个可复现的证据(命令输出、文件、截图、对比结果)。
      - 发现新问题时:立刻记录优先级(P0/P1/P2)与复现步骤。
      
  • scripts
    • create_test_session.py 15.2 KB
      #!/usr/bin/env python3
      from __future__ import annotations
      
      import argparse
      import datetime as dt
      import re
      import shutil
      import sys
      import typing
      from pathlib import Path
      
      _TEST_ID_RE = re.compile(r"^v\d{12}$")
      
      _DEFAULT_DIRECTORIES = {
          "plans": "output/plans",
          "tests": "output/tests",
      }
      
      _DEFAULT_TEMPLATES = {
          "optimization_plan": "templates/OPTIMIZATION_PLAN_TEMPLATE.md",
          "b_round_check": "templates/B_ROUND_CHECK_TEMPLATE.md",
          "test_plan": "templates/TEST_PLAN_TEMPLATE.md",
          "test_report": "templates/TEST_REPORT_TEMPLATE.md",
      }
      
      
      def _generate_test_id(now: dt.datetime) -> str:
          return f"v{now:%Y%m%d%H%M}"
      
      
      def _ensure_dir(path: Path) -> None:
          path.mkdir(parents=True, exist_ok=True)
      
      
      def _safe_write(path: Path, content: str, *, overwrite: bool) -> None:
          if path.exists() and not overwrite:
              raise FileExistsError(f"Refusing to overwrite existing file: {path}")
          path.write_text(content, encoding="utf-8")
      
      
      def _render_template(template: str, *, values: dict[str, str]) -> str:
          rendered = template
          for key, value in values.items():
              rendered = rendered.replace(f"{{{{{key}}}}}", value)
          return rendered
      
      
      def _copy_or_template(
          *,
          dst_path: Path,
          src_path: Path | None,
          template_path: Path | None,
          template_values: dict[str, str] | None,
          overwrite: bool,
      ) -> None:
          if dst_path.exists() and not overwrite:
              return
      
          if src_path is not None and src_path.exists():
              if dst_path.exists():
                  dst_path.unlink()
              shutil.copyfile(src_path, dst_path)
              return
      
          if template_path is not None and template_path.exists():
              template_text = template_path.read_text(encoding="utf-8")
              if template_values:
                  template_text = _render_template(template_text, values=template_values)
              _safe_write(dst_path, template_text, overwrite=overwrite)
              return
      
          _safe_write(
              dst_path,
              "# TEST_PLAN\n\n(未找到可复制的计划文档或模板,请手动补全)\n",
              overwrite=overwrite,
          )
      
      
      def _normalize_kind(kind: str) -> str:
          kind = kind.strip().lower()
          if kind in {"a", "a_round", "a-round", "a轮"}:
              return "a"
          if kind in {"b", "b_round", "b-round", "b轮"}:
              return "b"
          raise ValueError("kind must be a/b (also accepts: A轮/B轮)")
      
      
      def _fail(parser: argparse.ArgumentParser, message: str) -> typing.NoReturn:
          parser.print_usage(sys.stderr)
          print(f"error: {message}", file=sys.stderr)
          raise SystemExit(2)
      
      
      def _strip_inline_comment(value: str) -> str:
          # Best-effort: config.yaml in this repo uses simple scalar strings for
          # directories/templates; we only need those sections and should not require
          # non-stdlib dependencies.
          if "#" not in value:
              return value
          return value.split("#", 1)[0].rstrip()
      
      
      def _parse_simple_yaml_sections(text: str, *, wanted_sections: set[str]) -> dict[str, dict[str, str]]:
          """
          Parse a minimal subset of YAML:
          - top-level mapping keys (no indentation)
          - one level nested key/value pairs under a wanted section (2+ spaces)
          This is used as a fallback when PyYAML isn't available.
          """
          result: dict[str, dict[str, str]] = {}
          current: str | None = None
          for raw in text.splitlines():
              line = raw.rstrip("\n")
              if not line.strip() or line.lstrip().startswith("#"):
                  continue
      
              # Section header: "directories:" / "templates:"
              if not line.startswith(" ") and line.endswith(":"):
                  section = line[:-1].strip()
                  current = section if section in wanted_sections else None
                  continue
      
              if current is None:
                  continue
      
              # Section entry: "  key: value"
              if line.startswith("  ") and ":" in line:
                  key, value = line.split(":", 1)
                  key = key.strip()
                  value = _strip_inline_comment(value.strip())
                  if not value:
                      continue
                  if (value.startswith('"') and value.endswith('"')) or (value.startswith("'") and value.endswith("'")):
                      value = value[1:-1]
                  result.setdefault(current, {})[key] = value
      
          return result
      
      
      def _load_config_sections(config_path: Path) -> dict[str, dict[str, str]]:
          wanted = {"directories", "templates"}
          if not config_path.exists():
              return {}
      
          text = config_path.read_text(encoding="utf-8")
          try:
              import yaml  # type: ignore
          except Exception:
              return _parse_simple_yaml_sections(text, wanted_sections=wanted)
      
          try:
              data = yaml.safe_load(text) or {}
          except Exception:
              return _parse_simple_yaml_sections(text, wanted_sections=wanted)
      
          out: dict[str, dict[str, str]] = {}
          for section in wanted:
              v = data.get(section)
              if isinstance(v, dict):
                  out[section] = {str(k): str(vv) for k, vv in v.items() if isinstance(vv, (str, int, float))}
          return out
      
      
      def _merge_section(
          *,
          base: dict[str, str],
          override: dict[str, str] | None,
      ) -> dict[str, str]:
          merged = dict(base)
          if override:
              merged.update({k: v for k, v in override.items() if v})
          return merged
      
      
      def _safe_rel_path(value: str, *, default: str) -> str:
          """
          Prevent writing outside the target skill root when reading config-provided
          directories/templates.
          """
          if not value:
              return default
          p = Path(value)
          if p.is_absolute() or ".." in p.parts:
              return default
          return value
      
      
      def _resolve_template_path(
          *,
          target_skill_root: Path,
          bundled_skill_root: Path,
          rel_path: str,
      ) -> Path | None:
          # Prefer target skill templates, then fall back to auto-test-skill bundled templates.
          #
          # Safety: if the template path is a symlink that resolves outside the expected
          # root, ignore it (prevents accidental/hostile template substitution).
          def _candidate_within(root: Path) -> Path | None:
              candidate = root / rel_path
              if not candidate.exists():
                  return None
              resolved = candidate.resolve()
              try:
                  resolved.relative_to(root)
              except ValueError:
                  return None
              return resolved
      
          return _candidate_within(target_skill_root) or _candidate_within(bundled_skill_root)
      
      
      def _ensure_dir_within_root(
          parser: argparse.ArgumentParser,
          *,
          skill_root: Path,
          path: Path,
          label: str,
      ) -> None:
          """
          Ensure we only create/write under --skill-root, even when directories are configured.
          """
          if path.exists():
              if path.is_symlink():
                  _fail(parser, f"{label} must not be a symlink: {path}")
              if not path.is_dir():
                  _fail(parser, f"{label} must be a directory: {path}")
      
          _ensure_dir(path)
          resolved = path.resolve()
          try:
              resolved.relative_to(skill_root)
          except ValueError:
              _fail(parser, f"{label} resolves outside --skill-root: {path} -> {resolved}")
      
      
      def main() -> int:
          parser = argparse.ArgumentParser(
              description="Create an auto-test-skill test session skeleton (A round or B round).",
          )
          parser.add_argument(
              "--skill-root",
              required=True,
              help="Target Skill source directory (must contain SKILL.md); never used for artifacts.",
          )
          parser.add_argument(
              "--task-root",
              required=True,
              help="Locked project task root under .bensz-api/task-*; artifacts are written below its auto-test-skill/ child.",
          )
          parser.add_argument(
              "--kind",
              default="a",
              help="Session kind: a (default) or b (also accepts: A轮/B轮).",
          )
          parser.add_argument(
              "--id",
              default="",
              help="Explicit test id like vYYYYMMDDHHMM (optional).",
          )
          parser.add_argument(
              "--create-plan",
              action="store_true",
              help="Create missing plan doc skeleton under configured plans dir (optional).",
          )
          parser.add_argument(
              "--seed-test-plan-from-plan",
              action="store_true",
              help="Copy the plan doc into TEST_PLAN.md (advanced; usually you should edit the template instead).",
          )
          parser.add_argument(
              "--a-test-id",
              default="",
              help="For B round: the corresponding A-round id (defaults to --id).",
          )
          parser.add_argument(
              "--overwrite",
              action="store_true",
              help="Overwrite existing session files (not recommended).",
          )
          args = parser.parse_args()
      
          skill_root = Path(args.skill_root).expanduser().resolve()
          if not skill_root.exists() or not skill_root.is_dir():
              _fail(parser, f"--skill-root does not exist or is not a directory: {skill_root}")
          if not (skill_root / "SKILL.md").exists():
              _fail(parser, f"--skill-root is not a Skill directory (missing SKILL.md): {skill_root}")
      
          task_root = Path(args.task_root).expanduser().resolve()
          if not task_root.exists() or not task_root.is_dir() or task_root.is_symlink():
              _fail(parser, f"--task-root must be an existing real directory: {task_root}")
          bensz_root = task_root.parent
          if bensz_root.name != ".bensz-api" or not task_root.name.startswith("task-"):
              _fail(parser, f"--task-root must be a direct .bensz-api/task-* directory: {task_root}")
      
          try:
              kind = _normalize_kind(args.kind)
          except ValueError as exc:
              _fail(parser, str(exc))
          now = dt.datetime.now()
          test_id = args.id.strip() or _generate_test_id(now)
          if not _TEST_ID_RE.fullmatch(test_id):
              _fail(
                  parser,
                  "test id must match vYYYYMMDDHHMM, e.g. v202601010000 (omit --id to auto-generate).",
              )
      
          bundled_skill_root = Path(__file__).resolve().parent.parent
          # Artifact directories belong to this Skill's task workspace. Target Skill
          # config may provide templates, but must not redirect test artifacts.
          target_cfg = _load_config_sections(skill_root / "config.yaml")
          bundled_cfg = _load_config_sections(bundled_skill_root / "config.yaml")
          directories = _merge_section(
              base=_DEFAULT_DIRECTORIES,
              override=bundled_cfg.get("directories"),
          )
          templates = _merge_section(
              base=_DEFAULT_TEMPLATES,
              override=target_cfg.get("templates") or bundled_cfg.get("templates"),
          )
      
          workspace_root = task_root / bundled_skill_root.name
          plans_dir = workspace_root / _safe_rel_path(directories.get("plans", ""), default=_DEFAULT_DIRECTORIES["plans"])
          tests_dir = workspace_root / _safe_rel_path(directories.get("tests", ""), default=_DEFAULT_DIRECTORIES["tests"])
      
          def template_path(config_key: str) -> Path | None:
              rel = _safe_rel_path(templates.get(config_key, ""), default="")
              if not rel:
                  return None
              return _resolve_template_path(
                  target_skill_root=skill_root,
                  bundled_skill_root=bundled_skill_root,
                  rel_path=rel,
              )
      
          _ensure_dir_within_root(parser, skill_root=task_root, path=workspace_root, label="Skill workspace")
          _ensure_dir_within_root(parser, skill_root=task_root, path=plans_dir, label="plans directory")
          _ensure_dir_within_root(parser, skill_root=task_root, path=tests_dir, label="tests directory")
      
          template_values: dict[str, str] = {
              "TEST_ID": test_id,
              "TARGET_SKILL_NAME": skill_root.name,
              # Display paths in docs with forward slashes for cross-platform consistency.
              "TARGET_SKILL_ROOT": skill_root.as_posix(),
              "PLAN_TIME": now.isoformat(timespec="minutes"),
              "CHECK_TIME": now.isoformat(timespec="minutes"),
              "PLAN_DATE": now.date().isoformat(),
              # Provide sensible defaults for common placeholders so skeleton docs are usable
              # without leaving raw `{{...}}` everywhere.
              "CHANGED_FILE_1": "(待填写)",
              "CHANGED_FILE_2": "(待填写)",
              "BEHAVIOR_CHANGE_1": "(待填写)",
              "BEHAVIOR_CHANGE_2": "(待填写)",
              "P0_CHECK_1": "(待填写)",
              "P0_CHECK_2": "(待填写)",
              "P1_CHECK_1": "(待填写)",
              "P1_CHECK_2": "(待填写)",
              "P2_CHECK_1": "(待填写)",
          }
      
          if kind == "a":
              session_name = test_id
              test_plan_template = template_path("test_plan")
              plan_doc_path = plans_dir / f"{test_id}.md"
              plan_template = template_path("optimization_plan")
              round_kind = "A轮"
          else:
              session_name = f"B轮-{test_id}"
              test_plan_template = template_path("test_plan")
              plan_doc_path = plans_dir / f"B轮-{test_id}.md"
              plan_template = template_path("b_round_check")
              round_kind = "B轮"
      
          template_values["ROUND_KIND"] = round_kind
          template_values["SESSION_NAME"] = session_name
          template_values["PLAN_DOC_PATH"] = plan_doc_path.relative_to(task_root).as_posix()
      
          # Provide session-relative paths to avoid hardcoding "tests/" in templates.
          session_dir_rel = (tests_dir / session_name).relative_to(task_root).as_posix()
          template_values["SESSION_DIR_REL"] = session_dir_rel
          template_values["TEST_PLAN_REL"] = f"{session_dir_rel}/TEST_PLAN.md"
          template_values["TEST_REPORT_REL"] = f"{session_dir_rel}/TEST_REPORT.md"
      
          if kind == "b":
              a_test_id = args.a_test_id.strip() or test_id
              if not _TEST_ID_RE.fullmatch(a_test_id):
                  _fail(parser, "--a-test-id must match vYYYYMMDDHHMM (e.g. v202601010000)")
              template_values["A_TEST_ID"] = a_test_id
      
          if args.create_plan and (not plan_doc_path.exists() or args.overwrite):
              if plan_template is not None:
                  _safe_write(
                      plan_doc_path,
                      _render_template(plan_template.read_text(encoding="utf-8"), values=template_values),
                      overwrite=args.overwrite,
                  )
              else:
                  _safe_write(
                      plan_doc_path,
                      f"# 计划文档({session_name})\n\n(未找到模板,请手动补全)\n",
                      overwrite=args.overwrite,
                  )
      
          session_dir = tests_dir / session_name
          _ensure_dir_within_root(parser, skill_root=task_root, path=session_dir, label="session directory")
          _ensure_dir(session_dir / "_artifacts")
          _ensure_dir(session_dir / "_scripts")
      
          _copy_or_template(
              dst_path=session_dir / "TEST_PLAN.md",
              src_path=plan_doc_path if (args.seed_test_plan_from_plan and plan_doc_path.exists()) else None,
              template_path=test_plan_template,
              template_values=template_values,
              overwrite=args.overwrite,
          )
      
          report_path = session_dir / "TEST_REPORT.md"
          test_report_template = template_path("test_report")
          if not report_path.exists() or args.overwrite:
              if test_report_template is not None:
                  _safe_write(
                      report_path,
                      _render_template(test_report_template.read_text(encoding="utf-8"), values=template_values),
                      overwrite=args.overwrite,
                  )
              else:
                  _safe_write(
                      report_path,
                      "# 测试报告(TEST_REPORT)\n\n"
                      f"**测试会话**: {session_name}\n\n"
                      "## 结果\n\n"
                      "- 状态:✅ 通过 / ❌ 失败 / ⚠️ 部分通过\n\n"
                      "## 证据\n\n"
                      "- (填入命令输出、文件路径、对比结果等)\n",
                      overwrite=args.overwrite,
                  )
      
          print(str(session_dir))
          return 0
      
      
      if __name__ == "__main__":
          raise SystemExit(main())
      
    • verify_test_session.py 11.8 KB
      #!/usr/bin/env python3
      from __future__ import annotations
      
      import argparse
      import re
      import sys
      import typing
      from dataclasses import dataclass
      from pathlib import Path
      
      _TEST_ID_RE = re.compile(r"^v\d{12}$")
      _PLACEHOLDER_RE = re.compile(r"\{\{[A-Z0-9_]+\}\}")
      
      
      @dataclass(frozen=True)
      class Issue:
          severity: str  # P0/P1/P2
          message: str
      
      
      def _fail(message: str) -> typing.NoReturn:
          print(f"error: {message}", file=sys.stderr)
          raise SystemExit(2)
      
      
      def _strip_inline_comment(value: str) -> str:
          if "#" not in value:
              return value
          return value.split("#", 1)[0].rstrip()
      
      
      def _parse_simple_yaml_sections(text: str, *, wanted_sections: set[str]) -> dict[str, dict[str, str]]:
          """
          Parse a minimal subset of YAML:
          - top-level mapping keys (no indentation)
          - one level nested key/value pairs under a wanted section (2+ spaces)
          """
          result: dict[str, dict[str, str]] = {}
          current: str | None = None
          for raw in text.splitlines():
              line = raw.rstrip("\n")
              if not line.strip() or line.lstrip().startswith("#"):
                  continue
      
              if not line.startswith(" ") and line.endswith(":"):
                  section = line[:-1].strip()
                  current = section if section in wanted_sections else None
                  continue
      
              if current is None:
                  continue
      
              if line.startswith("  ") and ":" in line:
                  key, value = line.split(":", 1)
                  key = key.strip()
                  value = _strip_inline_comment(value.strip())
                  if not value:
                      continue
                  if (value.startswith('"') and value.endswith('"')) or (value.startswith("'") and value.endswith("'")):
                      value = value[1:-1]
                  result.setdefault(current, {})[key] = value
      
          return result
      
      
      def _load_directories(config_path: Path) -> dict[str, str]:
          if not config_path.exists():
              return {}
          text = config_path.read_text(encoding="utf-8")
          data = _parse_simple_yaml_sections(text, wanted_sections={"directories"})
          out = data.get("directories") or {}
          return {str(k): str(v) for k, v in out.items()}
      
      
      def _load_effective_directories() -> dict[str, str]:
          bundled_root = Path(__file__).resolve().parent.parent
          return _load_directories(bundled_root / "config.yaml")
      
      
      def _safe_rel_path(value: str, *, default: str) -> str:
          if not value:
              return default
          p = Path(value)
          if p.is_absolute() or ".." in p.parts:
              return default
          return value
      
      
      def _extract_markdown_field(text: str, field_label: str) -> str | None:
          # Example: **关联规划文档**: .bensz-api/skills/auto-test-skill/output/plans/v202601162330.md
          pat = re.compile(rf"^\*\*{re.escape(field_label)}\*\*:\s*(.+?)\s*$", re.MULTILINE)
          m = pat.search(text)
          if not m:
              return None
          return m.group(1).strip()
      
      
      def _scan_placeholders(text: str) -> list[str]:
          return [m.group(0) for m in _PLACEHOLDER_RE.finditer(text)]
      
      
      def _check_report_status(text: str) -> tuple[bool, bool]:
          """
          Returns (is_ok, found).
          Template placeholder looks like: "- 状态:✅ 通过 / ❌ 失败 / ⚠️ 部分通过"
          """
          for line in text.splitlines():
              if "状态:" in line:
                  return ("/" not in line, True)
          return (False, False)
      
      
      def _classify_session(session_dir: Path) -> tuple[str, str] | None:
          name = session_dir.name
          if name.startswith("B轮-"):
              test_id = name.removeprefix("B轮-")
              if _TEST_ID_RE.fullmatch(test_id):
                  return ("b", test_id)
              return None
          if _TEST_ID_RE.fullmatch(name):
              return ("a", name)
          return None
      
      
      def verify_test_session(
          *,
          session_dir: Path,
          skill_root: Path,
          task_root: Path,
          require_plan: bool,
      ) -> list[Issue]:
          issues: list[Issue] = []
      
          if not session_dir.exists() or not session_dir.is_dir():
              return [Issue("P0", f"session_dir is not a directory: {session_dir}")]
      
          directories = _load_effective_directories()
          workspace_root = task_root / Path(__file__).resolve().parent.parent.name
          tests_dir = workspace_root / _safe_rel_path(directories.get("tests", ""), default="output/tests")
          if not tests_dir.exists():
              issues.append(Issue("P0", f"configured tests directory does not exist: {tests_dir}"))
          else:
              if tests_dir.is_symlink():
                  issues.append(Issue("P1", f"tests directory is a symlink (discouraged): {tests_dir}"))
              try:
                  session_dir.resolve().relative_to(tests_dir.resolve())
              except Exception:
                  issues.append(Issue("P1", f"session_dir is not under configured tests directory: {tests_dir}"))
          try:
              session_dir.resolve().relative_to(task_root)
          except ValueError:
              issues.append(Issue("P0", f"session_dir resolves outside task_root: {session_dir}"))
      
          kind_info = _classify_session(session_dir)
          if kind_info is None:
              issues.append(Issue("P1", f"unexpected session directory name (expected vYYYYMMDDHHMM or B轮-vYYYYMMDDHHMM): {session_dir.name}"))
              kind = "unknown"
              test_id = ""
          else:
              kind, test_id = kind_info
      
          required_paths = [
              (session_dir / "TEST_PLAN.md", "TEST_PLAN.md"),
              (session_dir / "TEST_REPORT.md", "TEST_REPORT.md"),
              (session_dir / "_artifacts", "_artifacts/"),
              (session_dir / "_scripts", "_scripts/"),
          ]
          for p, label in required_paths:
              if not p.exists():
                  issues.append(Issue("P0", f"missing required {label}: {p}"))
              elif label.endswith("/") and not p.is_dir():
                  issues.append(Issue("P0", f"{label} is not a directory: {p}"))
      
          plan_text = ""
          report_text = ""
          test_plan_text = ""
      
          plan_path: Path | None = None
          if require_plan and kind in {"a", "b"} and test_id:
              plans_dir = workspace_root / _safe_rel_path(directories.get("plans", ""), default="output/plans")
              if kind == "a":
                  plan_path = plans_dir / f"{test_id}.md"
              else:
                  plan_path = plans_dir / f"B轮-{test_id}.md"
      
              if not plan_path.exists():
                  issues.append(Issue("P0", f"missing plan doc (expected by session id): {plan_path}"))
              else:
                  plan_text = plan_path.read_text(encoding="utf-8", errors="replace")
      
          test_plan_path = session_dir / "TEST_PLAN.md"
          if test_plan_path.exists():
              test_plan_text = test_plan_path.read_text(encoding="utf-8", errors="replace")
              placeholders = _scan_placeholders(test_plan_text)
              if placeholders:
                  uniq = sorted(set(placeholders))
                  shown = uniq[:8]
                  suffix = " (and more)" if len(uniq) > len(shown) else ""
                  issues.append(Issue("P0", f"TEST_PLAN.md contains unresolved placeholders: {shown}{suffix}"))
      
          report_path = session_dir / "TEST_REPORT.md"
          if report_path.exists():
              report_text = report_path.read_text(encoding="utf-8", errors="replace")
              placeholders = _scan_placeholders(report_text)
              if placeholders:
                  uniq = sorted(set(placeholders))
                  shown = uniq[:8]
                  suffix = " (and more)" if len(uniq) > len(shown) else ""
                  issues.append(Issue("P0", f"TEST_REPORT.md contains unresolved placeholders: {shown}{suffix}"))
              ok, found = _check_report_status(report_text)
              if not found:
                  issues.append(Issue("P1", "TEST_REPORT.md is missing a status line ('状态:...')."))
              elif not ok:
                  issues.append(Issue("P1", "TEST_REPORT.md status line looks like the template placeholder; set it to a single status (e.g. ✅ 通过)."))
      
          if require_plan and plan_path is not None and plan_text:
              if kind == "a":
                  placeholders = _scan_placeholders(plan_text)
                  if placeholders:
                      uniq = sorted(set(placeholders))
                      shown = uniq[:8]
                      suffix = " (and more)" if len(uniq) > len(shown) else ""
                      issues.append(Issue("P0", f"A-round plan doc contains unresolved placeholders (should be fully rendered): {shown}{suffix}"))
              elif kind == "b":
                  # B-round plan templates are intentionally verbose; only enforce that auto-filled header fields are not left as placeholders.
                  for ph in ["{{TEST_ID}}", "{{CHECK_TIME}}", "{{A_TEST_ID}}", "{{TARGET_SKILL_NAME}}", "{{TARGET_SKILL_ROOT}}"]:
                      if ph in plan_text:
                          issues.append(Issue("P0", f"B-round plan doc still contains required auto-filled placeholder: {ph}"))
      
          if require_plan:
              # Validate that TEST_PLAN/TEST_REPORT reference an existing plan file.
              expected_plan_resolved = plan_path.resolve() if (plan_path is not None and plan_path.exists()) else None
              for label, text in [("TEST_PLAN.md", test_plan_text), ("TEST_REPORT.md", report_text)]:
                  if not text:
                      continue
                  ref = _extract_markdown_field(text, "关联规划文档")
                  if ref is None:
                      issues.append(Issue("P1", f"{label} missing '**关联规划文档**: ...' field"))
                      continue
                  ref_path = Path(ref)
                  if ref_path.is_absolute() or ".." in ref_path.parts:
                      issues.append(Issue("P0", f"{label} has unsafe plan path: {ref}"))
                      continue
                  abs_ref = (task_root / ref_path).resolve()
                  try:
                      abs_ref.relative_to(task_root)
                  except ValueError:
                      issues.append(Issue("P0", f"{label} plan path resolves outside task_root: {ref} -> {abs_ref}"))
                      continue
                  if not abs_ref.exists():
                      issues.append(Issue("P0", f"{label} references missing plan doc: {ref}"))
                      continue
                  if expected_plan_resolved is not None and abs_ref != expected_plan_resolved:
                      issues.append(Issue("P1", f"{label} references a different plan doc than expected by session id: {ref}"))
      
          return issues
      
      
      def main() -> int:
          parser = argparse.ArgumentParser(description="Verify an auto-test-skill test session directory for completeness.")
          parser.add_argument(
              "session_dir",
              help="Session directory under .bensz-api/task-*/auto-test-skill/output/tests/.",
          )
          parser.add_argument(
              "--skill-root",
              required=True,
              help="Target Skill source directory (must contain SKILL.md).",
          )
          parser.add_argument(
              "--task-root",
              required=True,
              help="Locked project task root under .bensz-api/task-*.",
          )
          parser.add_argument(
              "--require-plan",
              action="store_true",
              help="Require the corresponding plan doc to exist and be consistent with TEST_PLAN/TEST_REPORT.",
          )
          args = parser.parse_args()
      
          session_dir = Path(args.session_dir).expanduser()
          skill_root = Path(args.skill_root).expanduser().resolve()
          if not (skill_root / "SKILL.md").exists():
              _fail(f"--skill-root is not a Skill directory (missing SKILL.md): {skill_root}")
          task_root = Path(args.task_root).expanduser().resolve()
          if not task_root.exists() or not task_root.is_dir() or task_root.is_symlink():
              _fail(f"--task-root must be an existing real directory: {task_root}")
          if task_root.parent.name != ".bensz-api" or not task_root.name.startswith("task-"):
              _fail(f"--task-root must be a direct .bensz-api/task-* directory: {task_root}")
      
          issues = verify_test_session(
              session_dir=session_dir.resolve(),
              skill_root=skill_root,
              task_root=task_root,
              require_plan=args.require_plan,
          )
      
          if issues:
              # Print in severity order.
              order = {"P0": 0, "P1": 1, "P2": 2}
              issues_sorted = sorted(issues, key=lambda i: order.get(i.severity, 99))
              for it in issues_sorted:
                  print(f"{it.severity}: {it.message}", file=sys.stderr)
              return 2
      
          print("OK")
          return 0
      
      
      if __name__ == "__main__":
          raise SystemExit(main())
      
  • templates
    • BUG_REPORT_TEMPLATE.md 3.8 KB
      # Bug报告: [项目名称]
      
      **报告时间**: {{DATE}}
      **测试环境**: {{ENVIRONMENT}}
      **测试人员**: {{TESTER}}
      
      ---
      
      ## 问题概述
      
      - **测试时间**: {{TEST_DATE}}
      - **项目名称**: {{PROJECT_NAME}}
      - **测试版本**: {{VERSION}}
      - **问题总数**: {{TOTAL_ISSUES}}
      - **严重程度分布**:
        - Critical: {{CRITICAL_COUNT}}
        - High: {{HIGH_COUNT}}
        - Medium: {{MEDIUM_COUNT}}
        - Low: {{LOW_COUNT}}
      
      ---
      
      ## 问题清单
      
      ### 问题 #1: [简短标题]
      
      **基本信息**:
      - **严重程度**: Critical / High / Medium / Low
      - **优先级**: P0 / P1 / P2 / P3
      - **状态**: Open / Fixed / Verified
      - **发现时间**: {{DISCOVERY_DATE}}
      - **报告人**: {{REPORTER}}
      
      **问题描述**:
      - **现象**: 描述问题的具体表现
      - **复现步骤**:
        1. 步骤1
        2. 步骤2
        3. 步骤3
      - **实际行为**: 描述当前的实际行为
      - **期望行为**: 描述期望的正确行为
      - **影响范围**: 描述问题影响的功能模块/用户群体
      
      **根因分析**:
      - **问题根源**: 分析问题的根本原因
      - **相关代码/文件**: 列出相关的代码文件和行号
      - **为什么会出现**: 解释问题产生的背景和原因
      
      **修复建议**:
      - **推荐方案**: 详细描述推荐的修复方案
      - **替代方案**: 列出可能的替代方案(如果有)
      - **预期效果**: 描述修复后的预期效果
      - **风险评估**: 评估修复可能带来的风险
      
      **验证方法**:
      - **如何验证修复**: 描述验证修复效果的方法
      - **测试用例**: 列出用于验证的测试用例
      - **预期结果**: 描述修复后的预期测试结果
      - **回归测试**: 列出需要回归测试的相关功能
      
      **参考信息**:
      - **相关Issue/PR**: 链接到相关的Issue或PR
      - **参考文档**: 链接到相关的技术文档
      - **类似问题**: 链接到类似的已修复问题
      
      ---
      
      ### 问题 #2: [简短标题]
      
      (重复上述结构)
      
      ---
      
      (按优先级排序,列出所有问题)
      
      ---
      
      ## 优先级矩阵
      
      | 问题 # | 标题 | 严重程度 | 优先级 | 状态 | 预计工作量 |
      |--------|------|----------|--------|------|-----------|
      | #1 | ... | Critical | P0 | Open | 2小时 |
      | #2 | ... | High | P1 | Open | 4小时 |
      | #3 | ... | Medium | P2 | Open | 1小时 |
      | #4 | ... | Low | P3 | Open | 0.5小时 |
      
      ---
      
      ## 统计分析
      
      ### 按严重程度分布
      - Critical: {{CRITICAL_COUNT}} 个 ({{CRITICAL_PERCENT}}%)
      - High: {{HIGH_COUNT}} 个 ({{HIGH_PERCENT}}%)
      - Medium: {{MEDIUM_COUNT}} 个 ({{MEDIUM_PERCENT}}%)
      - Low: {{LOW_COUNT}} 个 ({{LOW_PERCENT}}%)
      
      ### 按功能模块分布
      - 模块A: {{MODULE_A_COUNT}} 个问题
      - 模块B: {{MODULE_B_COUNT}} 个问题
      - 模块C: {{MODULE_C_COUNT}} 个问题
      
      ### 按问题类型分布
      - 功能缺陷: {{BUG_COUNT}} 个
      - 性能问题: {{PERFORMANCE_COUNT}} 个
      - 安全问题: {{SECURITY_COUNT}} 个
      - 文档问题: {{DOC_COUNT}} 个
      - 体验优化: {{UX_COUNT}} 个
      
      ---
      
      ## 修复建议总结
      
      ### 立即修复(P0)
      1. 问题 #1: ... (预计2小时)
      2. 问题 #2: ... (预计4小时)
      **总预计工作量**: 6小时
      
      ### 近期修复(P1)
      1. 问题 #3: ... (预计3小时)
      2. 问题 #4: ... (预计2小时)
      **总预计工作量**: 5小时
      
      ### 计划修复(P2)
      1. 问题 #5: ... (预计1小时)
      2. 问题 #6: ... (预计1.5小时)
      **总预计工作量**: 2.5小时
      
      ### 可选优化(P3)
      1. 问题 #7: ... (预计0.5小时)
      2. 问题 #8: ... (预计0.5小时)
      **总预计工作量**: 1小时
      
      ---
      
      ## 附录
      
      ### 术语表
      - **Critical**: 阻塞性问题,完全无法使用
      - **High**: 严重问题,核心功能受影响
      - **Medium**: 中等问题,部分功能受限
      - **Low**: 轻微问题,不影响主要功能
      
      ### 优先级定义
      - **P0**: 立即修复(24小时内)
      - **P1**: 尽快修复(3天内)
      - **P2**: 计划修复(1周内)
      - **P3**: 有空再修(1个月内)
      
      ### 相关链接
      - 项目主页: {{PROJECT_URL}}
      - 问题追踪: {{ISSUES_URL}}
      - 文档: {{DOCS_URL}}
      
    • B_ROUND_CHECK_TEMPLATE.md 30.2 KB
      # B轮质量检查报告(质量原则检查)
      
      **检查ID**: B轮-{{TEST_ID}}
      **检查时间**: {{CHECK_TIME}}
      **对应A轮测试**: {{A_TEST_ID}}
      **目标技能**: {{TARGET_SKILL_NAME}}
      **目标技能路径**: {{TARGET_SKILL_ROOT}}
      
      ---
      
      ## 检查结果总览
      
      | 维度 | 状态 | 备注 |
      |------|------|------|
      | 硬编码/AI功能规划 | ✅ / ⚠️ / ❌ | {{NOTE_1}} |
      | 冗余残留错误检查 | ✅ / ⚠️ / ❌ | {{NOTE_2}} |
      | 安全性检查 | ✅ / ⚠️ / ❌ | {{NOTE_3}} |
      | 过度设计检查 | ✅ / ⚠️ / ❌ | {{NOTE_4}} |
      | 通用性检查 | ✅ / ⚠️ / ❌ | {{NOTE_5}} |
      | 一致性检查 | ✅ / ⚠️ / ❌ | {{NOTE_6}} |
      | 配置集中化检查 | ✅ / ⚠️ / ❌ | {{NOTE_7}} |
      | SKILL.md瘦身检查 | ✅ / ⚠️ / ❌ | {{NOTE_8}} |
      
      ---
      
      ## 1. 硬编码/AI 功能规划
      
      **状态**: ✅ / ⚠️ / ❌
      
      ### 核心原则
      **确定性操作应脚本化,启发式判断由AI处理**。两者应协调配合,让skill功能发挥更完全。
      
      ### 判断标准
      
      #### ✅ 合理的硬编码/AI分工
      - **确定性操作已脚本化**:文件解析、目录创建、命名规范、数据验证、格式转换等操作已通过 `scripts/` 中的脚本实现
      - **可配置参数已集中**:阈值、路径、模板、选项等参数已提取到 `config.yaml`,避免硬编码在SKILL.md或脚本中
      - **AI专注启发式任务**:AI仅负责需求理解、方案设计、内容生成、语义判断等需要灵活性的任务
      - **无重复造轮子**:AI不会在每次执行时重复编写相同的代码逻辑
      
      #### ⚠️ 需要改进的信号
      - AI每次都要"手动"执行固定操作(如"创建目录X"、"复制模板Y")
      - 配置值硬编码在文档或脚本中,而非从config.yaml读取
      - AI被要求执行确定性计算(如日期格式、路径拼接、数据验证)
      
      #### ❌ 严重问题示例
      - 让AI反复编写相同的文件操作代码(每次执行都从头写一遍)
      - 时间戳、路径等基础逻辑未脚本化,依赖AI"每次记得正确执行"
      - 可配置参数分散在多个文件中,难以统一维护
      
      ### 典型反例
      
      **反例1**:SKILL.md中要求AI"手动创建目录"
      ```markdown
      ## 执行步骤
      1. 创建目录:`output/reports/{timestamp}/`
      2. 创建文件:`output/reports/{timestamp}/summary.md`
      ```
      **问题**:这是确定性操作,应脚本化
      
      **反例2**:配置值硬编码在文档中
      ```markdown
      ## 配置说明
      最大重试次数:3次
      超时时间:30秒
      ```
      **问题**:应移至config.yaml
      
      ### 改进方向
      - 将重复的确定性操作提取到 `scripts/`
      - 将可配置参数集中到 `config.yaml`
      - SKILL.md中仅描述AI需要做什么,而非如何一步步操作
      
      ### 本轮发现
      - {{FINDING_1}}
      
      ### 改进建议
      - {{SUGGESTION_1}}
      
      ### 🚨 挑衅性检查(必须回答)
      
      1. **找出一个"伪脚本化"的例子**:看似已脚本化,但 AI 仍在手动执行的操作
         - 位置:{{PSEUDO_SCRIPT_LOCATION}}
         - 伪脚本化表现:{{PSEUDO_SCRIPT_MANIFESTATION}}
         - 应如何改进:{{PSEUDO_SCRIPT_FIX}}
      
      2. **找出一个"过度配置化"的例子**:本应硬编码的常量,却放到了 config.yaml
         - 位置:{{OVER_CONFIG_LOCATION}}
         - 过度配置化表现:{{OVER_CONFIG_MANIFESTATION}}
         - 应如何改进:{{OVER_CONFIG_FIX}}
      
      3. **质疑隐式假设**:文档假设用户会做 X(如"用户会先创建目录"),实际可能不会
         - 假设内容:{{IMPLICIT_ASSUMPTION}}
         - 失效场景:{{ASSUMPTION_FAILURE_SCENARIO}}
         - 应如何改进:{{ASSUMPTION_FIX}}
      
      4. **边缘情况挑战**:如果用户输入的路径是 `../../etc/passwd`,当前逻辑能防御吗?
         - 位置:{{EDGE_CASE_LOCATION}}
         - 防御措施:{{EDGE_CASE_DEFENSE}}
         - 是否足够?:{{EDGE_CASE_ADEQUATE}}
      
      ---
      
      ## 2. 冗余残留错误检查
      
      **状态**: ✅ / ⚠️ / ❌
      
      ### 核心原则
      **消除冗余、清理残留、修复错误**。确保skill结构清晰、无遗留问题。
      
      ### 判断标准
      
      #### ✅ 无冗余残留
      - **无重复逻辑**:相似逻辑已抽象复用,无复制粘贴的代码段或文档段落
      - **无残留引用**:已删除的文件/功能,其引用已全部清理
      - **无僵尸文件**:所有文件都有明确用途,被其他文件引用或被工作流使用
      - **无逻辑错误**:文档描述与实际实现一致,无矛盾或错误陈述
      
      #### ⚠️ 需要清理的信号
      - 存在相似或相同的代码段/文档段落(可合并但未合并)
      - 文档中引用了不存在的文件、目录或配置项
      - `references/`、`assets/` 中存在未被SKILL.md或脚本引用的文件
      - 文档中存在"已废弃"、"旧版本"、"TODO"等未清理的标记
      
      #### ❌ 严重问题示例
      - 删除功能后,相关引用散落在多个文件中未清理
      - 相同的配置参数在config.yaml和SKILL.md中重复定义
      - 存在"备份文件"(如file_old.md、file_backup.md)但未说明用途
      
      ### 典型反例
      
      **反例1**:残留引用
      ```
      文档中:参考 `references/OLD_TEMPLATE.md`
      实际情况:该文件已被删除,应引用 `references/NEW_TEMPLATE.md`
      ```
      
      **反例2**:重复段落
      ```markdown
      # SKILL.md
      ## 输入格式
      输入必须是PDF格式...
      
      ## 使用示例
      示例1:输入一个PDF文件...
      示例2:输入一个PDF文件...(与示例1几乎相同)
      ```
      
      **反例3**:僵尸文件
      ```
      references/unused_guide.md  # 从未被SKILL.md或任何脚本引用
      assets/old_template.txt     # 已被新模板替代,但未删除
      ```
      
      ### 改进方向
      - 使用Grep工具全局搜索被删除文件/功能的引用
      - 合并相似的文档段落或代码逻辑
      - 清理未使用的参考文件和资产
      - 移除过时的标记和注释
      
      ### 本轮发现
      - {{FINDING_2}}
      
      ### 改进建议
      - {{SUGGESTION_2}}
      
      ---
      
      ## 3. 安全性检查
      
      **状态**: ✅ / ⚠️ / ❌
      
      ### 核心原则
      **预防常见安全漏洞和风险**。确保skill在输入处理、文件操作、信息泄露等方面无重大安全隐患。
      
      ### 判断标准
      
      #### ✅ 安全性良好
      - **输入路径已规范化和校验**:用户提供的路径已验证其合法性(防止路径遍历攻击),确保在项目范围内
      - **无敏感信息泄露**:日志、错误消息、示例中不包含密钥、凭证、内部路径等敏感信息
      - **外部调用可控**:网络请求、系统调用等外部操作显式、可控、可复现,不执行任意用户输入
      - **文件路径跨平台兼容**:使用正斜杠,确保在Windows/macOS/Linux上都能正常工作
      
      #### ⚠️ 潜在安全风险
      - 用户输入直接用于文件路径操作,未做边界检查
      - 错误消息中包含详细路径或系统信息
      - 外部调用使用用户输入作为参数,未做验证
      - 硬编码了临时路径或测试路径
      
      #### ❌ 严重安全漏洞
      - 路径遍历漏洞:允许访问项目目录外的文件(如 `../../../etc/passwd`)
      - 命令注入风险:用户输入未过滤直接传递给系统命令
      - 敏感信息硬编码:API密钥、密码等直接写在代码或配置中
      - 不安全的反序列化/解析:对不可信数据直接反序列化
      
      ### 典型反例
      
      **反例1**:路径遍历风险
      ```python
      # 危险:未验证用户输入
      user_path = input("输入文件路径:")
      with open(user_path, 'r') as f:  # 可能访问任意文件
          ...
      ```
      **修复**:验证路径在项目范围内
      
      **反例2**:敏感信息泄露
      ```python
      # 错误日志中暴露详细信息
      except Exception as e:
          print(f"错误:处理文件 {user_path} 时失败,详情:{str(e)}")
          # user_path可能是用户数据,e可能包含内部路径
      ```
      
      **反例3**:命令注入风险
      ```python
      # 危险:用户输入直接用于系统命令
      os.system(f"convert {user_input} output.pdf")
      ```
      **修复**:使用参数化API或严格验证输入
      
      ### 改进方向
      - 所有用户输入必须验证和规范化
      - 文件操作前检查路径是否在允许范围内
      - 避免在日志/错误中泄露敏感信息
      - 使用参数化API而非字符串拼接执行外部命令
      - 敏感配置使用环境变量或加密存储
      
      ### 本轮发现
      - {{FINDING_3}}
      
      ### 改进建议
      - {{SUGGESTION_3}}
      
      ---
      
      ## 4. 过度设计检查
      
      **状态**: ✅ / ⚠️ / ❌
      
      ### 核心原则
      **用奥卡姆剃刀原则审视每个设计决策**。避免为"未来可能用到"的场景预留功能,优先选择最简单的解决方案。
      
      ### 判断标准
      
      #### ✅ 设计简洁适度
      - **只实现当前需要的功能**:无"为未来预留"的复杂抽象或扩展点
      - **配置项合理**:配置项数量适中,每个都有明确用途,不过度抽象
      - **实现直观**:使用最直观、最易理解的实现方式
      - **职责单一**:每个函数/模块/文件只做一件事,职责清晰
      
      #### ⚠️ 存在过度设计信号
      - 配置项过多(超过15-20个)且大量嵌套,难以理解
      - 引入了多层抽象解决简单问题(如"管理器工厂的建造者")
      - 提供了大量可选配置,但大部分场景下只需使用默认值
      - 文档中大量解释"这个设计是为了未来的XX场景"
      
      #### ❌ 严重过度设计
      - 明显的YAGNI违反:为"未来可能需要"的功能预留接口/配置
      - 过度泛化:试图用一套逻辑处理所有场景,导致代码难以理解
      - 不必要的抽象层次:引入"中间层"但只起到简单的传递作用
      
      ### 典型反例
      
      **反例1**:为未来预留功能
      ```yaml
      # config.yaml
      output_formats:
        pdf:
          enabled: true
          engine: "reportlab"
        docx:
          enabled: false  # 未来可能支持
        html:
          enabled: false  # 未来可能支持
        markdown:
          enabled: false  # 未来可能支持
      ```
      **问题**:当前只支持PDF,其他格式不应硬编码在配置中
      
      **反例2**:过度抽象
      ```python
      class OutputFormatFactory:
          """输出格式工厂(当前只有一种格式)"""
          def create_formatter(self, format_type):
              if format_type == "pdf":
                  return PDFFormatter()
              # 未来扩展点...
      
      class PDFFormatter(AbstractFormatter):
          def format(self, data):
              # 实际上就是直接调用一个函数
              return convert_to_pdf(data)
      ```
      **问题**:只有一种格式时,工厂和抽象层都是不必要的
      
      **反例3**:配置项过多
      ```yaml
      # 本可以简单的功能,配置项却超过20个
      processing:
        retries: 3
        retry_delay: 1.0
        retry_backoff: 2.0
        retry_jitter: true
        timeout:
          connect: 10
          read: 30
          total: 60
        validation:
          strict: true
          level: "high"
          custom_rules: []
        # ... 还有10+个配置项
      ```
      **问题**:大部分场景下这些值不需要改变,应简化为必要的配置
      
      ### 改进方向
      - 删除未使用的"预留"功能和配置
      - 合并相似的配置项,使用合理的默认值
      - 简化抽象层次,优先使用直接的实现方式
      - 遵循KISS原则:能用简单方法解决的,不引入复杂设计
      
      ### 本轮发现
      - {{FINDING_4}}
      
      ### 改进建议
      - {{SUGGESTION_4}}
      
      ---
      
      ## 5. 通用性检查
      
      **状态**: ✅ / ⚠️ / ❌
      
      ### 核心原则
      **避免不必要的场景和年份限制**。提高skill复用性,使其能适应更广泛的场景和时间跨度。
      
      ### 判断标准
      
      #### ✅ 通用性良好
      - **无时间敏感性**:不包含具体年份、日期等会过时的信息(除非是命名规范要求)
      - **无场景限制**:不过度限定使用场景,可适配多种类似需求
      - **无平台依赖**:不强制依赖特定平台或工具(除非是skill的核心定位)
      - **使用相对时间**:描述使用"当前版本"、"最新版"等相对时间表述
      - **通用术语**:使用通用术语,避免特定品牌或产品名称(除非必要)
      
      #### ⚠️ 通用性受限
      - 文档中包含"2024年版"、"2025年"等具体年份(非必要)
      - 示例硬编码了特定场景(如"用于NSFC申请书"而非"用于科研申请书")
      - 假设了特定语言或文化背景
      - 依赖特定平台的特有功能(非核心需求)
      
      #### ❌ 严重通用性问题
      - skill名称或描述中包含年份(如`nsfc-2025-formatter`)
      - 硬编码了特定工作流(如"适配XX公司的内部流程")
      - 包含特定品牌的专有术语或缩写(无解释)
      
      ### 典型反例
      
      **反例1**:年份限定
      ```markdown
      ## 功能说明
      本skill用于处理2024年度NSFC申请书格式
      ```
      **问题**:年份硬编码,2025年就需要修改
      **修复**:改为"本skill用于处理NSFC申请书格式"
      
      **反例2**:场景限定过窄
      ```markdown
      ## 适用场景
      - 将WeChat文章同步到Notion
      ```
      **问题**:限制了平台,实际逻辑可通用化
      **修复**:改为"将网页文章同步到笔记应用(支持WeChat、Notion等)"
      
      **反例3**:时间敏感示例
      ```markdown
      ## 示例
      输入:`--date 2025-01-14`
      输出:`report_20250114.pdf`
      ```
      **问题**:示例日期会过时
      **修复**:使用占位符`--date {YYYY-MM-DD}`
      
      **反例4**:不必要的品牌限定
      ```markdown
      本skill专为ChatGPT Plus用户设计...
      ```
      **问题**:限制了AI平台,实际功能通用
      **修复**:改为"本skill适用于各类AI助手平台..."
      
      ### 改进方向
      - 将具体年份改为相对时间表述("当前版本")
      - 将特定场景泛化为通用场景(如"NSFC"→"科研基金")
      - 提供扩展机制(如config.yaml),而非硬编码特定配置
      - 在YAML `description` 中说明适用场景,而非硬编码到工作流
      - 使用占位符替代时间敏感的示例数据
      
      ### 本轮发现
      - {{FINDING_5}}
      
      ### 改进建议
      - {{SUGGESTION_5}}
      
      ---
      
      ## 6. 一致性检查
      
      **状态**: ✅ / ⚠️ / ❌
      
      ### 核心原则
      **确保文档、配置、实现三者一致**。避免相互矛盾、描述不符、版本不匹配等问题。
      
      ### 判断标准
      
      #### ✅ 一致性良好
      - **YAML frontmatter 与 SKILL.md 正文一致**:
        - `name`、`description` 与正文中的技能名称、功能描述一致
        - `metadata.keywords` 涵盖了正文中的关键场景
        - 版本号(如有)与 config.yaml 一致
      - **SKILL.md 与 config.yaml 一致**:
        - 文档中提到的配置项在 config.yaml 中存在
        - 文档中提到的路径、模板在 config.yaml 中定义且路径正确
        - config.yaml 中的配置项在文档中都有说明
      - **README.md 与 SKILL.md 一致**(B 轮额外检查):
        - README 中的示例与 SKILL.md 中的工作流一致
        - README 中的触发方式与 YAML `description` 一致
      - **术语一致**:同一概念在所有文件中使用相同的术语
      - **示例一致**:文档中的示例可以实际运行,与当前版本功能一致
      
      #### ⚠️ 存在不一致信号
      - YAML frontmatter 中的 `description` 与正文描述有差异
      - SKILL.md 中引用了 config.yaml 中不存在的配置项
      - README 中的示例使用旧版语法或已废弃的功能
      - 同一概念在不同文件中使用不同术语(如"测试会话"vs"测试轮次")
      
      #### ❌ 严重不一致问题
      - YAML frontmatter 中的 `name` 与实际目录名不一致
      - 文档中提到的核心功能在当前版本中不存在或已移除
      - config.yaml 中的路径指向不存在的文件或目录
      - 版本号在不同文件中不一致
      
      ### 典型反例
      
      **反例1**:YAML与正文不一致
      ```yaml
      ---
      name: pdf-merger
      description: 合并多个PDF文件
      ---
      ```
      ```markdown
      # SKILL.md
      ## 功能说明
      本skill用于分割和提取PDF页面...
      ```
      **问题**:YAML说是合并,正文说是分割提取
      
      **反例2**:配置项不一致
      ```markdown
      # SKILL.md
      ## 配置说明
      - `output_dir`: 输出目录(默认:`output/`)
      - `max_retries`: 最大重试次数(默认:3)
      ```
      ```yaml
      # config.yaml
      output:
        directory: "./output"
      retries:
        max: 5  # 与文档中的默认值3不一致
      ```
      
      **反例3**:示例与实际不一致
      ```markdown
      # README.md
      ## 使用示例
      /run pdf-merger --input file1.pdf,file2.pdf --output merged.pdf
      ```
      ```markdown
      # SKILL.md(当前版本)
      ## 参数说明
      - `--input`: 输入文件(支持目录和文件,非逗号分隔列表)
      ```
      **问题**:README中的语法是旧版本
      
      **反例4**:术语不一致
      ```markdown
      # 一处文档使用"测试会话"(session)
      ## 创建测试会话
      v202601141900
      
      # 另一处使用"测试轮次"(round)
      ## 测试轮次说明
      第一轮测试...
      ```
      
      ### 改进方向
      - 更新 YAML frontmatter 使其准确反映当前技能的功能
      - 确保文档中引用的所有配置项在 config.yaml 中存在且名称一致
      - 同步更新 README 中的示例,使其与当前版本一致
      - 统一术语,在所有文件中使用相同的词汇描述同一概念
      - 定期检查:文档描述 → config.yaml → 实际脚本/模板 三者是否匹配
      
      ### 本轮发现
      - {{FINDING_6}}
      
      ### 改进建议
      - {{SUGGESTION_6}}
      
      ---
      
      ## 7. SKILL.md 瘦身检查
      
      **状态**: ✅ / ⚠️ / ❌
      
      ### 核心原则
      **遵循渐进披露(Progressive Disclosure)原则**。SKILL.md 应保持简洁,只包含 AI 执行所需的核心信息;详细内容应模块化到 `references/`。
      
      ### 判断标准
      
      #### ✅ SKILL.md 瘦身良好
      - **行数合理**:SKILL.md 不超过 300 行(建议阈值,可根据复杂度调整)
      - **核心内容保留**:工作流概览、输入输出、关键步骤、验证标准
      - **详细内容已模块化**:详细策略、标准、模板、示例已移至 `references/`
      - **配置说明已分离**:配置项的详细说明已移至 `config.yaml` 注释
      - **技术细节已下沉**:实现逻辑、参数说明已移至 `scripts/` 注释或 README
      
      #### ⚠️ 存在臃肿信号
      - SKILL.md 超过 300-400 行
      - 包含大量详细的策略说明(可独立为文档)
      - 包含完整的模板内容(可移至 `assets/` 或 `references/`)
      - 包含冗长的配置项说明(可移至 config.yaml 注释)
      - 包含详细的技术实现细节(可移至脚本注释或 README)
      
      #### ❌ 严重臃肿问题
      - SKILL.md 超过 500 行
      - 包含多个完整的模板文件内容
      - 包含大量配置项的详细说明(每个配置项一段说明)
      - 包含详细的技术架构和实现细节
      - `references/` 目录几乎为空,但 SKILL.md 非常长
      
      ### 渐进披露策略
      
      | 内容类型 | 保留位置 | 示例 |
      |---------|---------|------|
      | **核心工作流** | SKILL.md | 概览、输入输出、关键步骤、验证标准 |
      | **详细模板** | references/ 或 assets/ | 完整的 A 轮计划结构、B 轮检查清单 |
      | **技术实现细节** | scripts/ 注释或 README | 实现逻辑、参数说明、算法细节 |
      | **配置说明** | config.yaml 注释 | 参数含义、默认值、使用示例 |
      | **详细策略/标准** | references/ | 质量原则、最佳实践、设计决策 |
      
      ### 典型反例
      
      **反例1**:完整模板内容嵌入 SKILL.md
      ```markdown
      # SKILL.md(臃肿)
      ## A 轮计划模板
      
      ## 测试 ID: {{TEST_ID}}
      ## 测试时间: {{CHECK_TIME}}
      ## ... 完整的 100 行模板内容 ...
      ```
      **问题**:应引用 `references/A_ROUND_PLAN_TEMPLATE.md`
      
      **反例2**:详细配置说明
      ```markdown
      # SKILL.md(臃肿)
      ## 配置说明
      
      ### output_dir
      - 类型:字符串
      - 默认值:"output/"
      - 说明:指定输出目录的路径。可以是相对路径或绝对路径...
      - 示例:output_dir: "./reports"
      
      ### max_retries
      - 类型:整数
      - 默认值:3
      - 说明:最大重试次数。当操作失败时会自动重试...
      - 示例:max_retries: 5
      
      # ... 20+ 个配置项的详细说明
      ```
      **问题**:应移至 config.yaml 注释
      
      **反例3**:详细技术实现
      ```markdown
      # SKILL.md(臃肿)
      ## 实现细节
      
      ### PDF 解析逻辑
      使用 PyPDF2 库解析 PDF 文件。首先打开文件,然后逐页读取...
      具体实现:[100 行技术说明]
      ```
      **问题**:应移至 scripts/ 注释或独立技术文档
      
      ### 瘦身操作指南
      
      #### 步骤1:识别可迁移内容
      - [ ] 完整的模板文件(移至 `assets/` 或 `references/`)
      - [ ] 详细的策略/标准/最佳实践(移至 `references/`)
      - [ ] 配置项的详细说明(移至 `config.yaml` 注释)
      - [ ] 技术实现细节(移至 `scripts/` 注释或 README)
      
      #### 步骤2:执行迁移
      - 在 SKILL.md 中使用引用而非嵌入内容:`详见 references/XXX.md`
      - 在 config.yaml 中添加注释说明配置项
      - 在脚本中添加 docstring 和注释说明实现逻辑
      - 在 references/ 中创建详细文档
      
      #### 步骤3:精简 SKILL.md
      - 保留核心工作流和关键步骤
      - 使用简洁的描述,避免冗长说明
      - 用链接/引用替代详细内容
      
      ### 本轮发现
      - {{FINDING_7}}
      
      ### 瘦身建议
      - {{SUGGESTION_7}}
      
      ---
      
      ## 7. 配置集中化检查
      
      **状态**: ✅ / ⚠️ / ❌
      
      ### 核心原则
      **精确端(config.yaml)与模糊端(工作文档)完全分离**。所有可配置参数必须集中在 `config.yaml` 作为单一真相来源,工作文档仅引用配置,不硬编码任何值。
      
      ### 判断标准
      
      #### ✅ 配置集中化良好
      - **config.yaml 是唯一参数来源**:所有阈值、路径、选项、超时、重试次数等可配置参数都定义在 `config.yaml` 中
      - **scripts/ 仅读取配置**:脚本通过加载 `config.yaml` 获取参数,不硬编码任何魔法数字或路径
      - **SKILL.md 仅引用配置**:文档中提及参数时,仅说明"参考 config.yaml 中的 `xxx` 选项",不直接写出具体值
      - **无参数分散**:不存在"同一个参数在多个文件中重复定义"的情况
      - **无硬编码常量**:代码和文档中不存在 `MAX_RETRY = 3`、`TIMEOUT = 30` 这类硬编码(除非是真正的数学/物理常数)
      
      #### ⚠️ 存在配置分散信号
      - 部分参数在 `config.yaml` 中定义,但部分参数硬编码在 `scripts/` 中
      - SKILL.md 中写死了参数值(如"最大重试 3 次"),而非引用 `config.yaml`
      - 修改参数需要同时修改多个文件
      - 不同环境/用户使用时,需要修改代码而非仅修改配置
      
      #### ❌ 严重配置分散问题
      - 完全没有 `config.yaml`,所有参数硬编码在代码和文档中
      - 存在 `config.yaml` 但内容为空或仅有少量配置,大量参数仍硬编码
      - 同一参数在多个文件中有不同的值(如文档说"默认 3 次",代码写的是 5 次)
      - 脚本中存在大量魔法数字且无注释说明来源
      
      ### 典型反例
      
      **反例1**:参数硬编码在脚本中
      ```python
      # scripts/process.py - 错误做法
      MAX_RETRIES = 3  # 硬编码
      TIMEOUT = 30     # 硬编码
      OUTPUT_DIR = "./output"  # 硬编码
      
      def process_file(file):
          for i in range(MAX_RETRIES):  # 应该从 config.yaml 读取
              ...
      ```
      **问题**:修改参数需要改代码,且无法针对不同环境提供不同配置
      
      **正确做法**:
      ```python
      # scripts/process.py - 正确做法
      import yaml
      
      def load_config():
          with open('config.yaml', 'r') as f:
              return yaml.safe_load(f)
      
      config = load_config()
      MAX_RETRIES = config.get('max_retries', 3)
      TIMEOUT = config.get('timeout', 30)
      OUTPUT_DIR = config.get('output_dir', './output')
      ```
      
      **反例2**:文档中写死参数值
      ```markdown
      # SKILL.md - 错误做法
      ## 配置说明
      本技能最大重试 3 次,超时时间 30 秒。
      ```
      **问题**:修改 config.yaml 后,文档仍然显示旧的默认值
      
      **正确做法**:
      ```markdown
      # SKILL.md - 正确做法
      ## 配置说明
      重试次数和超时时间请参考 `config.yaml` 中的 `max_retries` 和 `timeout` 选项。
      ```
      
      **反例3**:同一参数多处定义且不一致
      ```python
      # scripts/process.py
      MAX_RETRIES = 3
      ```
      ```markdown
      # README.md
      默认最大重试次数:5 次
      ```
      ```yaml
      # config.yaml
      max_retries: 5
      ```
      **问题**:文档与代码不一致,用户会困惑
      
      ### 改进方向
      - 将所有可配置参数提取到 `config.yaml`,提供合理的默认值
      - 脚本启动时加载 `config.yaml`,使用 `config.get('key', default_value)` 模式读取参数
      - 文档中仅说明参数的含义和位置,不写出具体值
      - 使用环境变量或配置文件覆盖机制,支持不同环境的配置需求
      
      ### 检查方法(建议)
      ```bash
      # 搜索脚本中的硬编码数字
      rg "(?<=MAX_RETRIES|TIMEOUT|DELAY)\s*=\s*\d+" scripts/
      
      # 搜索硬编码路径
      rg "(?<=path|dir|file)\s*=\s*[\"'][\w/]+[\"']" scripts/
      
      # 搜索 SKILL.md 中的具体数值
      rg "\d+\s*(次|秒|分钟|字节)" SKILL.md
      
      # 对比 config.yaml 和脚本中的变量名
      rg "config\.get\(" scripts/ | grep -oP 'get\(\K[^\)]+' | sort -u
      ```
      
      ### 本轮发现
      - {{FINDING_7}}
      
      ### 改进建议
      - {{SUGGESTION_7}}
      
      ---
      
      ## 8. SKILL.md 瘦身检查
      
      **状态**: ✅ / ⚠️ / ❌
      
      ### 核心原则
      **遵循渐进披露原则**。SKILL.md 应保持简洁,只包含 AI 执行所需的核心信息;详细内容应模块化到 `references/`。
      
      ### 判断标准
      
      #### ✅ SKILL.md 瘦身良好
      - **行数合理**:SKILL.md 不超过 300 行(建议阈值,可根据复杂度调整)
      - **核心内容保留**:工作流概览、输入输出、关键步骤、验证标准
      - **详细内容已模块化**:详细策略、标准、模板、示例已移至 `references/`
      - **配置说明已分离**:配置项的详细说明已移至 `config.yaml` 注释
      - **技术细节已下沉**:实现逻辑、参数说明已移至 `scripts/` 注释或 README
      
      #### ⚠️ 存在臃肿信号
      - SKILL.md 超过 300-400 行
      - 包含大量详细的策略说明(可独立为文档)
      - 包含完整的模板内容(可移至 `assets/` 或 `references/`)
      - 包含冗长的配置项说明(可移至 `config.yaml` 注释)
      - 包含详细的技术实现细节(可移至脚本注释或 README)
      
      #### ❌ 严重臃肿问题
      - SKILL.md 超过 500 行
      - 包含多个完整的模板文件内容
      - 包含大量配置项的详细说明(每个配置项一段说明)
      - 包含详细的技术架构和实现细节
      - `references/` 目录几乎为空,但 SKILL.md 非常长
      
      ### 渐进披露策略
      
      | 内容类型 | 保留位置 | 示例 |
      |---------|---------|------|
      | **核心工作流** | SKILL.md | 概览、输入输出、关键步骤、验证标准 |
      | **详细模板** | references/ 或 assets/ | 完整的 A 轮计划结构、B 轮检查清单 |
      | **技术实现细节** | scripts/ 注释或 README | 实现逻辑、参数说明、算法细节 |
      | **配置说明** | config.yaml 注释 | 参数含义、默认值、使用示例 |
      | **详细策略/标准** | references/ | 质量原则、最佳实践、设计决策 |
      
      ### 本轮发现
      - {{FINDING_8}}
      
      ### 瘦身建议
      - {{SUGGESTION_8}}
      
      ---
      
      ## 改进建议汇总(按优先级)
      
      ⚠️ **数量要求**:B 轮必须提出至少 10-20 个建设性建议(P0 + P1 + P2 总和)
      
      ### P0(必须修复)
      - {{P0_ITEM_1}}
      
      ### P1(强烈建议)
      - {{P1_ITEM_1}}
      
      ### P2(可选)
      - {{P2_ITEM_1}}
      
      ---
      
      ## 🚨 全局挑衅性检查(必须全部回答)
      
      ### 1. 最挑剔的问题:这个 skill 有哪些"自我感动"的设计?
      
      列出 3 个"看似专业,实际无用"的过度设计:
      
      - {{SELF_INDULGENT_1}}
      - {{SELF_INDULGENT_2}}
      - {{SELF_INDULGENT_3}}
      
      ### 2. 边缘情况压力测试
      
      模拟极端输入场景,验证 skill 的鲁棒性:
      
      - 如果用户输入**空目录**会怎样?
        - 预期行为:{{EMPTY_DIR_EXPECTATION}}
        - 实际行为:{{EMPTY_DIR_ACTUAL}}
        - 是否有明确的错误提示?{{YES_NO}}
      
      - 如果用户输入**包含特殊字符的路径**(如空格、引号、`../`)会怎样?
        - 预期行为:{{SPECIAL_CHARS_EXPECTATION}}
        - 实际行为:{{SPECIAL_CHARS_ACTUAL}}
        - 是否有路径规范化?{{YES_NO}}
      
      - 如果 config.yaml **被用户删空或包含无效值**会怎样?
        - 预期行为:{{INVALID_CONFIG_EXPECTATION}}
        - 实际行为:{{INVALID_CONFIG_ACTUAL}}
        - 是否有默认值回退?{{YES_NO}}
      
      ### 3. 隐式假设挖掘
      
      列出 5 个文档未说明、但 AI 默认假设会成立的条件:
      
      1. {{ASSUMPTION_1}} → 在什么情况下会失效?{{ASSUMPTION_1_FAILURE}}
      2. {{ASSUMPTION_2}} → 在什么情况下会失效?{{ASSUMPTION_2_FAILURE}}
      3. {{ASSUMPTION_3}} → 在什么情况下会失效?{{ASSUMPTION_3_FAILURE}}
      4. {{ASSUMPTION_4}} → 在什么情况下会失效?{{ASSUMPTION_4_FAILURE}}
      5. {{ASSUMPTION_5}} → 在什么情况下会失效?{{ASSUMPTION_5_FAILURE}}
      
      ### 4. "如果我是恶意用户"测试
      
      尝试构造 3 个恶意输入场景,验证 skill 是否安全:
      
      - **场景 1**:{{MALICIOUS_SCENARIO_1}}
        - 攻击向量:{{ATTACK_VECTOR_1}}
        - 当前防御:{{DEFENSE_1}}
        - 是否足够?{{YES_NO}}
      
      - **场景 2**:{{MALICIOUS_SCENARIO_2}}
        - 攻击向量:{{ATTACK_VECTOR_2}}
        - 当前防御:{{DEFENSE_2}}
        - 是否足够?{{YES_NO}}
      
      - **场景 3**:{{MALICIOUS_SCENARIO_3}}
        - 攻击向量:{{ATTACK_VECTOR_3}}
        - 当前防御:{{DEFENSE_3}}
        - 是否足够?{{YES_NO}}
      
      ### 5. 文档与实现的"鸿沟"
      
      找出 3 个"文档说 A,实际做 B"的不一致之处:
      
      1. **位置**:{{INCONSISTENCY_1_LOCATION}}
         - 文档说:{{DOC_SAYS_1}}
         - 实际做:{{CODE_DOES_1}}
         - 影响:{{INCONSISTENCY_1_IMPACT}}
      
      2. **位置**:{{INCONSISTENCY_2_LOCATION}}
         - 文档说:{{DOC_SAYS_2}}
         - 实际做:{{CODE_DOES_2}}
         - 影响:{{INCONSISTENCY_2_IMPACT}}
      
      3. **位置**:{{INCONSISTENCY_3_LOCATION}}
         - 文档说:{{DOC_SAYS_3}}
         - 实际做:{{CODE_DOES_3}}
         - 影响:{{INCONSISTENCY_3_IMPACT}}
      
      ### 6. "你会真的用这个 skill 吗?"测试
      
      模拟真实使用场景,评估 skill 的可用性:
      
      - **第一印象**:如果我是新用户,看到 SKILL.md 后,我能在 5 分钟内理解如何使用吗?
        - 评分(1-10):{{FIRST_IMPRESSION_SCORE}}
        - 主要障碍:{{FIRST_IMPRESSION_BARRIER}}
      
      - **实际操作**:如果我要按照文档执行一次,我会卡在哪里?
        - 预期卡点 1:{{FRICTION_POINT_1}}
        - 预期卡点 2:{{FRICTION_POINT_2}}
        - 预期卡点 3:{{FRICTION_POINT_3}}
      
      - **错误处理**:如果我在中间步骤出错了,文档是否告诉我如何恢复?
        - 是否有错误恢复指南?{{YES_NO}}
        - 如果没有,应该补充什么?{{RECOVERY_GUIDANCE}}
      
      ---
      
      ## 技能评分(百分制)
      
      | 维度 | 得分 | 满分 | 扣分原因 |
      |------|------|------|----------|
      | 硬编码/AI功能规划 | {{SCORE_1}} | 15 | {{REASON_1}} |
      | 冗余残留错误检查 | {{SCORE_2}} | 15 | {{REASON_2}} |
      | 安全性检查 | {{SCORE_3}} | 20 | {{REASON_3}} |
      | 过度设计检查 | {{SCORE_4}} | 15 | {{REASON_4}} |
      | 通用性检查 | {{SCORE_5}} | 10 | {{REASON_5}} |
      | 一致性检查 | {{SCORE_6}} | 15 | {{REASON_6}} |
      | 配置集中化检查 | {{SCORE_7}} | 15 | {{REASON_7}} |
      | SKILL.md瘦身检查 | {{SCORE_8}} | 10 | {{REASON_8}} |
      | **总分** | **{{TOTAL_SCORE}}** | **115** | |
      
      ### 评分标准
      - **90-100 分**:优秀(生产就绪)
      - **75-89 分**:良好(可用于生产,有改进空间)
      - **60-74 分**:及格(需要重要优化)
      - **< 60 分**:不及格(需要重大改进)
      
      ### 与上轮对比
      - 上轮得分:{{PREV_SCORE}}(如有)
      - 本轮进步:{{IMPROVEMENT}}
      
    • FINAL_SUMMARY_TEMPLATE.md 924 B
      # 最终总结(FINAL_SUMMARY)
      
      **目标技能**: {{TARGET_SKILL_NAME}}
      **目标技能路径**: {{TARGET_SKILL_ROOT}}
      **起止时间**: {{START_TIME}} ~ {{END_TIME}}
      **A轮迭代次数**: {{A_ROUNDS_COUNT}}
      **B轮质量检查**: ✅ 已完成 / ❌ 未完成
      
      ---
      
      ## 修复概览
      
      - 初始问题数:{{ISSUES_BEFORE}}
      - 修复问题数:{{ISSUES_FIXED}}
      - 新增问题数:{{ISSUES_NEW}}
      - 最终遗留问题数:{{ISSUES_REMAIN}}
      
      ---
      
      ## 测试会话列表
      
      ### A轮
      - {{A_SESSION_1}}
      - {{A_SESSION_2}}
      
      ### B轮
      - {{B_SESSION_1}}
      
      ---
      
      ## 关键变更
      
      - {{KEY_CHANGE_1}}
      - {{KEY_CHANGE_2}}
      
      ---
      
      ## 验收结论
      
      - [ ] 所有 P0 / P1 问题已修复
      - [ ] 轻量测试通过(核心验证点均通过)
      - [ ] 目录与文档可追溯(plans/ + tests/)
      - [ ] CHANGELOG.md 已更新
      
      ---
      
      ## 经验与后续
      
      ### 做得好的地方
      - {{GOOD_1}}
      - {{GOOD_2}}
      
      ### 下次可优化点
      - {{NEXT_1}}
      - {{NEXT_2}}
      
      
    • OPTIMIZATION_PLAN_TEMPLATE.md 1.5 KB
      # 优化计划({{TEST_ID}})
      
      **计划日期**: {{PLAN_DATE}}  
      **计划ID**: {{TEST_ID}}  
      **目标技能**: {{TARGET_SKILL_NAME}}  
      **目标技能路径**: {{TARGET_SKILL_ROOT}}
      
      ---
      
      ## 独立评估与审查范围(强制)
      
      - [ ] 本轮基于目标 skill 的**当前工作状态**独立评估
      - [ ] **未查看**历史轮次的 `plans/` 与 `tests/`(计划阶段不依赖历史产物,避免确认偏差/路径依赖)
      
      **必须审查文件**(参考 `config.yaml:a_round_check.independent_review.required_files`):
      - `SKILL.md` / `config.yaml`
      
      **必须审查目录**(参考 `config.yaml:a_round_check.independent_review.required_dirs`):
      - `scripts/` / `references/` / `templates/` / `assets/`
      
      **排除范围**:`plans/`、`tests/`、`README.md`、`CHANGELOG.md` 以及 `exclude_patterns` 命中的文件。
      
      **扫描/审查证据(建议填入命令)**:
      - `rg -n \"...\" ...`
      - `find ...`
      
      ---
      
      ## 问题清单(按优先级)
      
      > 每个问题至少包含:位置(文件:行号)、影响、修复方式、验证方法。
      
      ### P0(必须修复)
      
      1) 标题:
      - 位置:`path/to/file:line`
      - 影响:
      - 修复:
      - 验证:
      
      ### P1(强烈建议)
      
      1) 标题:
      - 位置:`path/to/file:line`
      - 影响:
      - 修复:
      - 验证:
      
      ### P2(可选)
      
      1) 标题:
      - 位置:`path/to/file:line`
      - 影响:
      - 修复:
      - 验证:
      
      ---
      
      ## 执行步骤(按顺序)
      
      1) ...
      2) ...
      
      ---
      
      ## 本轮轻量测试
      
      - 会话目录:`{{SESSION_DIR_REL}}/`
      - 测试计划:`{{TEST_PLAN_REL}}`
      - 测试报告:`{{TEST_REPORT_REL}}`
      
    • TEST_PLAN_TEMPLATE.md 1.2 KB
      # 轻量测试计划(TEST_PLAN)
      
      **测试ID**: {{TEST_ID}}
      **目标技能**: {{TARGET_SKILL_NAME}}
      **目标技能路径**: {{TARGET_SKILL_ROOT}}
      **轮次类型**: {{ROUND_KIND}}
      **关联规划文档**: {{PLAN_DOC_PATH}}
      **计划时间**: {{PLAN_TIME}}
      
      ---
      
      ## 目标
      
      - 本轮要验证的核心行为是什么?
      - 本轮要解决/验证的 P0-P2 问题是什么?
      - 本轮的“通过”标准是什么?
      
      ---
      
      ## 变更范围(本轮)
      
      - 修改文件:
        - {{CHANGED_FILE_1}}
        - {{CHANGED_FILE_2}}
      - 重要行为变化:
        - {{BEHAVIOR_CHANGE_1}}
        - {{BEHAVIOR_CHANGE_2}}
      
      ---
      
      ## 验证点(轻量测试)
      
      ### P0(必须通过)
      - [ ] {{P0_CHECK_1}}
      - [ ] {{P0_CHECK_2}}
      
      ### P1(强烈建议通过)
      - [ ] {{P1_CHECK_1}}
      - [ ] {{P1_CHECK_2}}
      
      ### P2(可选)
      - [ ] {{P2_CHECK_1}}
      
      ---
      
      ## 执行步骤
      
      1. 准备:确认目标 skill 当前版本、目录结构与依赖
      2. 按顺序执行验证点(每完成一个验证点就记录结果)
      3. 如发现新问题:记录到本轮报告“新问题”章节,并标注优先级
      
      ---
      
      ## 产出清单
      
      - `TEST_REPORT.md`(必需)
      - `_artifacts/`(中间文件、输出、日志;可选但推荐)
      - `_scripts/`(必要时的测试脚本;可选)
      
    • TEST_REPORT_TEMPLATE.md 834 B
      # 测试报告({{SESSION_NAME}})
      
      **测试ID**: {{TEST_ID}}  
      **目标技能**: {{TARGET_SKILL_NAME}}  
      **目标技能路径**: {{TARGET_SKILL_ROOT}}  
      **关联规划文档**: {{PLAN_DOC_PATH}}  
      **测试时间**: {{PLAN_TIME}}
      
      ---
      
      ## 结论
      
      - 状态:✅ 通过 / ❌ 失败 / ⚠️ 部分通过
      - 一句话结论:
      
      ---
      
      ## 覆盖的变更(本轮)
      
      - 修改文件:
        - (填入本轮实际修改的文件)
      
      ---
      
      ## 执行命令与证据
      
      按时间顺序记录,确保每条结论可复现:
      
      1) 命令:`...`
         - 期望:
         - 实际:
         - 证据:`_artifacts/...`(如有)
      
      ---
      
      ## 验证点打勾清单
      
      ### P0(必须通过)
      - [ ] ...
      
      ### P1(强烈建议)
      - [ ] ...
      
      ### P2(可选)
      - [ ] ...
      
      ---
      
      ## 新问题(如有)
      
      - P0/P1/P2:问题描述 + 复现步骤 + 建议处理方式
      
      
  • CHANGELOG.md 14.5 KB
    # auto-test-skill - 变更日志
    
    格式遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/)。
    
    ## [Unreleased]
    
    ### Changed(变更)
    - 计划与测试会话改由显式 `--task-root` 托管到项目根 `.bensz-api/task-*/auto-test-skill/output/`;`--skill-root` 仅作为被测源目录,不再承载中间产物。
    - `directories.plans/tests` 改为相对于任务内 `auto-test-skill/` 的 `output/plans` 与 `output/tests`,验证脚本同步采用同一解析基准。
    
    - 版本升级:2.3.0 → 2.3.1;将计划与测试会话默认目录从目标 skill 根 `plans/` / `tests/` 收敛到 `.bensz-api/skills/auto-test-skill/output/plans/` 与 `.bensz-api/skills/auto-test-skill/output/tests/`,同步更新 `SKILL.md`、README、references 与脚本说明。
    
    ### Added(新增)
    - `scripts/verify_test_session.py`:确定性验证测试会话完整性(会话结构/关联计划/占位符残留/报告状态),支持 `--require-plan` 与自动发现 skill_root
    - **B 轮全覆盖修复机制**:B 轮优化与验证现在要求处理所有 P0-P2 问题(修复或说明不修复理由),确保所有发现的问题都有闭环处理
    - **B 轮第八质量原则:配置集中化检查**:新增"精确端(config.yaml)与模糊端(工作文档)完全分离"检查维度,确保所有可配置参数集中在 config.yaml 作为单一真相来源,提升 skill 可维护性
    - **批判性思维框架**:auto-test-skill 现在强制使用"刁钻角度"思考,确保发现系统性问题
    - `references/CRITICAL_THINKING_GUIDE.md`:批判性思维指南(核心文档)
      - 框架 1: 系统视角思考(架构设计/过度设计/一致性)
      - 框架 2: 刁钻角度思考(边缘情况/恶意输入/隐式假设/自我质疑)
      - 框架 3: 问题质量标准(黄金公式 + 质量检查清单)
      - 高质量问题示例库(系统性架构问题/过度设计问题/安全性问题)
    - `config.yaml`:
      - 新增 `test_rounds.min_p0_p1_ratio: 60`(A 轮 P0+P1 最小占比)
      - 新增 `test_rounds.min_systemic_issues: 3`(A 轮系统性问题最小数量)
      - 新增 `a_round_check.independent_review`(A 轮独立评估配置:审查范围 + 排除范围)
    
    ### Changed(变更)
    
    - 版本升级:2.2.2 → 2.3.0(新增会话验证脚本、配置瘦身、脚本安全/可用性增强)
    - `scripts/create_test_session.py`:
      - 新增 `--a-test-id`(B 轮记录对应 A 轮会话 id,并替换 B 轮模板的 `A_TEST_ID`)
      - 为 `TEST_PLAN_TEMPLATE.md` 的常用占位符提供默认值,避免残留 `{{...}}`
      - 会话/计划模板中不再硬编码 `tests/` 路径(通过 `SESSION_DIR_REL/TEST_PLAN_REL/TEST_REPORT_REL` 注入)
      - 路径安全:拒绝 symlink 目录,并校验 plans/tests/session 解析后仍位于 `--skill-root`
    - `scripts/verify_test_session.py`:新增会话结构与一致性验证(可选但推荐)
    - `config.yaml`:
      - 裁剪为“脚本读取 + 规划口径”的最小集合,并明确脚本仅解析 `directories.*` 与 `templates.*`
      - `exclude_patterns` 增加 `tests/**` 与 `plans/**`(并保留旧写法兼容)
    - `templates/OPTIMIZATION_PLAN_TEMPLATE.md`:本轮轻量测试路径引用改为脚本注入,支持自定义 tests 目录
    - `SKILL.md`:
      - 版本同步到 2.3.0
      - A.3/B.2 增加 `verify_test_session.py` 推荐自检命令
      - B 轮会话创建示例补充 `--a-test-id`
    - `README.md`:
      - 更新 config 说明为“脚本读取范围 + 规划口径”,并补充版本更新顺序
      - 补充 `verify_test_session.py` 最小用法示例
    - 版本升级:2.2.1 → 2.2.2(配置/文档一致性修复)
    - **核心定位升级**:从"自动化测试驱动优化技能"升级为"批判性思维驱动的测试优化技能"
    - **A 轮独立评估机制**:A 轮评估默认不查看 `plans/` 与 `tests/`,并强制声明审查范围(required_files/required_dirs)与排除范围(exclude_patterns),降低确认偏差、提升多轮价值
    - **create_test_session.py**:
      - 对任意目标 skill 可用:优先使用目标 skill 的 `templates/`,否则回退到 auto-test-skill 自带模板
      - 严格校验 `--id` 为 `vYYYYMMDDHHMM`(省略 `--id` 时自动生成),避免不规范会话目录
      - `--kind` 支持 `A轮/B轮`(中文环境更自然)
      - 会话元数据时间字段在同一时刻生成,避免边界条件不一致
    - **SKILL.md**:
      - 版本升级:2.2.0 → 2.2.1
      - 版本升级:2.1.0 → 2.2.0
      - description:新增"批判性思维驱动"和"系统性问题"关键词
      - A.2 章节:从"问题分析与计划生成"重构为"批判性分析与计划生成"
      - A.2 章节:新增"批判性思维是核心要求"警告(不是可选项)
      - A.2 章节:新增"质量要求"(P0+P1 占比 ≥ 60%,系统性问题 ≥ 3 个)
      - A.2 章节:新增"独立评估原则"与"审查范围"强制要求(不看 `plans/` 与 `tests/`)
      - A.2 章节:新增"批判性聚焦"和"刁钻角度"核心要求
      - A.2 章节:新增"批判性思维框架"必读文档列表(CRITICAL_THINKING_GUIDE.md 放在首位)
      - A.4 章节:进入下一轮条件改为“本轮问题闭环 + 用户轮次数未完成”,并明确“每轮独立评估,不因问题已解决提前终止”
      - 完成条件:新增"P0+P1 占比 ≥ 60%"和"系统性问题 ≥ 3 个"验收标准
      - 可复用资源:突出 CRITICAL_THINKING_GUIDE.md 为核心文档
    - **references/A_ROUND_PLAN_TEMPLATE.md**:大幅简化(从 200+ 行简化为核心结构)
      - 第一部分:独立评估与审查范围(不看 plans/tests + required_files/required_dirs)
      - 第二部分:批判性思维分析(刁钻角度 + 系统性问题)⚠️ 新增
      - 第三部分:问题清单(P0-P2,明确质量要求)
      - 第四部分:问题质量检查(9 条强制检查)⚠️ 新增
    - **templates/OPTIMIZATION_PLAN_TEMPLATE.md**:补齐 A 轮独立评估与审查范围章节,避免仅列问题而遗漏“范围覆盖/排除范围”声明
    - **README.md**:补齐 A 轮独立评估说明与配置项索引,统一 B 轮为“七大质量原则”,并补充脚本模板回退说明
    - **config.yaml**:
      - skill_info.version: 2.1.0 → 2.2.0
      - skill_info.version: 2.2.0 → 2.2.1
      - skill_info.description: 更新为"批判性思维驱动的测试优化技能"
      - test_rounds: 新增质量门槛配置(min_p0_p1_ratio, min_systemic_issues)
      - skill_info.description: 补充 A 轮“独立评估”口径
    
    - **测试会话**:
      - A 轮验证会话:`tests/v202601162213/`
      - B 轮验证会话:`tests/B轮-v202601162227/`
    
    ### Fixed(修复)
    
    - 修复 A 轮计划模板对 tests 目录的硬编码:现在会正确引用自定义 `directories.tests`
    - 修复 B 轮计划模板关键字段 `A_TEST_ID` 无法自动替换的问题(新增 `--a-test-id`)
    - 修复 B 轮“七大/八大”口径漂移:统一为“质量原则检查”,并明确以 `config.yaml:b_round_check.dimensions` 为准
    - 修复 B 轮 P1 修复率阈值规则冲突:将 `config.yaml:b_round_check.p1_fix_rate_required` 统一为 100%,并同步更新 `auto-test-skill/SKILL.md` 验收口径
    - 修复 `scripts/create_test_session.py` 的“伪配置”风险:脚本现在会读取 `config.yaml` 中的 `directories.*` 与 `templates.*`(缺失/解析失败时回退默认值),并统一使用正斜杠展示路径
    - 修复"问题挖掘技巧"未强调的问题(现在通过 CRITICAL_THINKING_GUIDE.md 强制使用)
    - 修复 A 轮模板过于复杂导致 AI 选择性忽略的问题(大幅简化,突出核心要求)
    - 修复缺乏"系统性问题"挖掘引导的问题(现在强制要求 ≥ 3 个系统性问题)
    
    ### Removed(移除)
    
    - 移除 A_ROUND_PLAN_TEMPLATE.md 中冗余的"修改步骤"和"轻量测试计划"章节(聚焦核心批判性思维)
    - `config.yaml`:移除未被引用的过度设计段落(test_session/priority/testing/reporting/quality/acceptance),降低误用
    
    ---
    
    ## [2.1.0] - 2026-01-14
    
    ### Added(新增)
    
    - **"非常挑剔"升级**:auto-test-skill 现在强制每轮提出 10-20 个建设性建议
    - `references/CONSTRUCTIVE_SUGGESTION_GUIDELINES.md`:建设性建议标准文档(可执行、有证据、有价值、可验证)
    - `references/ISSUE_DISCOVERY_TECHNIQUES.md`:问题挖掘技巧文档(10 大类技巧,系统化发现 10+ 问题)
    - `references/ANTI_PATTERNS_LIBRARY.md`:反例库文档(七大原则的常见反例,快速识别问题)
    - `templates/B_ROUND_CHECK_TEMPLATE.md`:
      - 新增"🚨 挑衅性检查"(仅在第一个维度,其他维度待补充)
      - 新增"全局挑衅性检查"(6 大类挑战性问题)
      - 新增"技能评分系统"(百分制,7 个维度评分)
    - `config.yaml`:
      - 新增 `test_rounds.min_suggestions_per_round: 10`(A 轮最小建议数量)
      - 新增 `test_rounds.target_suggestions_range: [15, 20]`(A 轮目标范围)
      - 新增 `b_round_check.min_suggestions: 10`(B 轮最小建议数量)
      - 新增 `b_round_check.constructive_suggestion_required: true`(强制建设性建议)
      - 新增 `b_round_check.p0_fix_rate_required: 100`(P0 修复率要求)
      - 新增 `b_round_check.p1_fix_rate_required: 80`(P1 修复率要求)
    
    ### Changed(变更)
    
    - `SKILL.md`:
      - A.2 章节:新增"数量要求"(强制每轮至少 10 个问题,鼓励 15-20 个)
      - A.2 章节:新增"建设性"要求(引用 `references/CONSTRUCTIVE_SUGGESTION_GUIDELINES.md`)
      - A.4 章节:重构为"强制检查" + "进入下一轮条件"(数量门槛前置)
      - B.2 章节:新增"强制修复要求"(P0 必须修复,P1 高比例修复)
      - 完成条件:新增"每轮 A 轮平均问题数量 ≥ 10"和"B 轮 P0/P1 修复率"要求
      - 可复用资源:补充新增的 3 个 references/ 文件和 3 个 templates/ 文件
    - `references/A_ROUND_PLAN_TEMPLATE.md`:
      - 新增"全局意识检查清单"(必填)
      - 新增"本轮的刁钻角度"(至少选择一个)
    
    ### Fixed(修复)
    
    - 修复 SKILL.md 中"可复用资源"章节未列出新增 references 文件的问题
    - 修复 A.4 节逻辑不一致的问题(强制检查现在前置)
    - 修复"问题挖掘技巧"未强调的问题(现在标记为⚠️强烈建议)
    
    ---
    
    ## [2.0.4] - 2026-01-14
    
    ### Added(新增)
    
    - B 轮质量检查新增第 7 个维度:**SKILL.md 瘦身检查**
      - 检查 SKILL.md 是否超过 300 行(建议阈值)
      - 检查是否存在可独立到 `references/` 的详细内容
      - 检查是否存在冗余的配置说明(应移至 `config.yaml` 注释)
      - 提供渐进披露原则的瘦身策略表(核心工作流→SKILL.md,详细模板→references/,技术细节→scripts/)
    - `references/A_ROUND_PLAN_TEMPLATE.md`:A 轮优化计划结构模板(全局视图、与上轮关联、优先级定义、问题清单)
    - `SKILL.md`:
      - A.2 章节新增"全局意识"、"上下文连贯"、"优先级依据"三大核心要求
      - 明确 P0/P1/P2 优先级判定标准(P0: 阻塞/安全/核心;P1: 重要优化;P2: 锦上添花)
      - 引用 `references/A_ROUND_PLAN_TEMPLATE.md` 作为详细结构模板
      - 更新"可复用资源"章节,新增模板与参考文档的分类列表
    - `config.yaml`:新增 `b_round_check.mandatory: true` 配置项,明确 B 轮为强制环节(除非用户明确要求跳过)
      - A.4 章节增加强制提示:"A 轮结束后(无论多少轮),必须进入 B 轮质量检查,不得跳过"
      - B 轮章节开头增加 ⚠️ 警告:"B 轮质量检查是自动测试流程的强制性环节,除非用户明确要求跳过,否则不得省略"
      - 完成条件引用 `config.yaml` 的 `mandatory` 配置,形成配置-文档联动
    
    ### Changed(变更)
    
    - B 轮质量检查从"六大原则"扩展为"七大原则",新增 SKILL.md 瘦身检查维度
    - `templates/B_ROUND_CHECK_TEMPLATE.md`:**重大重构** - 所有七大原则的检查说明更加详细和可操作
      - 每个原则新增"核心原则"一句话总结
      - 每个原则新增三级判断标准(✅ 良好 / ⚠️ 改进信号 / ❌ 严重问题)
      - 每个原则新增"典型反例"章节,包含具体代码/配置示例
      - 每个原则新增"改进方向"操作指南
      - 目标:让模型在执行 B 轮检查时更清晰理解每个原则的定义、判断标准和改进方向,避免歧义
    - `SKILL.md` A.2 章节:从简略的"问题清单"要求,重构为结构化的"全局视图 + 上下文 + 优先级 + 可追溯性"框架,解决 A 轮计划可读性差、缺少全局意识的问题
    - 版本号升级为 `2.0.4`(`config.yaml: skill_info.version` 同步到 `SKILL.md` YAML frontmatter)
    
    ## [2.0.1] - 2026-01-12
    
    ### Added(新增)
    
    - `scripts/create_test_session.py`:
      - 新增 `--create-plan`(可选生成 `plans/` 计划文档骨架,默认不覆盖)
      - 新增 `--seed-test-plan-from-plan`(可选用计划文档初始化 `TEST_PLAN.md`)
    - `templates/`:
      - 轻量化 `templates/TEST_REPORT_TEMPLATE.md`(结论/变更/证据/验证点/新问题)
      - 轻量化 `templates/OPTIMIZATION_PLAN_TEMPLATE.md`(位置/影响/修复/验证 + 执行步骤 + 测试引用)
    
    ### Changed(变更)
    
    - 版本号升级为 `2.0.1`(`config.yaml: skill_info.version` 同步到 `SKILL.md` YAML frontmatter)。
    - `templates/TEST_PLAN_TEMPLATE.md`:新增 `{{ROUND_KIND}}`,由脚本自动替换 A/B 轮。
    - `scripts/create_test_session.py`:
      - CLI 错误输出改为 usage + 单行 `error:`(无 traceback)
      - `PLAN_DOC_PATH` 使用 `plans/...` 相对路径(更可移植)
    - `auto-test-skill/SKILL.md`、`auto-test-skill/README.md`:补充脚本两种调用方式与 `--create-plan` 推荐用法;README 触发说明改为平台中立。
    
    ### Fixed(修复)
    
    - B 轮报告模板中的 `{{A_TEST_ID}}` 不再被脚本默认替换为当前 B 轮 ID(避免产生“看似填写但实际错误”的追溯信息)。
    
    ## [2.0.0] - 2026-01-12
    
    ### Added(新增)
    
    - 新增 `plans/` 与 `tests/` 的目录规范与多轮 A 轮 × N + B 轮工作流(六大质量原则)。
    - 新增 B 轮质量检查模板:`templates/B_ROUND_CHECK_TEMPLATE.md`。
    - 新增缺失模板:`templates/TEST_PLAN_TEMPLATE.md`、`templates/FINAL_SUMMARY_TEMPLATE.md`。
    - 新增确定性辅助脚本:`scripts/create_test_session.py`(创建测试会话骨架)。
    - 新增参考文档:`references/TESTING_BEST_PRACTICES.md`。
    
    ### Changed(变更)
    
    - 更新 `auto-test-skill/config.yaml`:补充轮次、目录、B 轮检查维度与模板配置。
    - 重构 `auto-test-skill/SKILL.md` 与 `auto-test-skill/README.md`:统一输出交付与目录命名为 `plans/` + `tests/`,并改为 A/B 轮工作流描述。
    
  • config.yaml 5 KB
    # auto-test-skill 配置文件
    #
    # 注意:
    # - `scripts/create_test_session.py` 仅解析 `directories.*` 与 `templates.*`(并做路径安全校验:拒绝 symlink、拒绝解析后越界)。
    # - 其余字段用于 A/B 轮规划口径(供 AI/人类参考),避免把“确定性行为”写进 SKILL.md。
    
    # ============================================================================
    # Skill 信息(建议作为版本号等信息的主要来源)
    # ============================================================================
    
    skill_info:
      name: "auto-test-skill"
      version: "2.3.1"
      description: "批判性思维驱动的测试优化技能 - 支持多轮 A 轮独立评估与 B 轮质量原则检查(以 b_round_check.dimensions 为准),强制每轮提出 10-20 个高质量建议(P0+P1 占比≥60%,系统性问题≥3个)"
      author: "Bensz Conan"
      category: "normal"
    
    # ============================================================================
    # 目录与命名规范(脚本会读取)
    # ============================================================================
    
    directories:
      # 相对于 <task-root>/auto-test-skill/;不写入被测 Skill 源目录
      plans: "output/plans"
      tests: "output/tests"
    
    # ============================================================================
    # 文档模板配置(脚本会读取)
    # ============================================================================
    
    templates:
      bug_report: "templates/BUG_REPORT_TEMPLATE.md"
      optimization_plan: "templates/OPTIMIZATION_PLAN_TEMPLATE.md"
      test_plan: "templates/TEST_PLAN_TEMPLATE.md"
      test_report: "templates/TEST_REPORT_TEMPLATE.md"
      final_summary: "templates/FINAL_SUMMARY_TEMPLATE.md"
      b_round_check: "templates/B_ROUND_CHECK_TEMPLATE.md"
    
    # ============================================================================
    # 轮次控制(规划口径)
    # ============================================================================
    
    test_rounds:
      # A轮测试默认轮次
      default_a_rounds: 1
      # 最大A轮测试轮次(防止无限循环)
      max_a_rounds: 10
      # A轮每轮必须提出的最小建议数量(P0 + P1 + P2 总和)
      min_suggestions_per_round: 10
      # A轮建议数量目标范围
      target_suggestions_range: [15, 20]
      # A轮 P0+P1 最小占比(百分比)- 确保问题有价值
      min_p0_p1_ratio: 60
      # A轮系统性问题最小数量(架构/过度设计/一致/安全)
      min_systemic_issues: 3
    
    # ============================================================================
    # A轮审查范围(独立评估;规划口径)
    # ============================================================================
    
    a_round_check:
      independent_review:
        enabled: true  # 是否启用独立评估模式(A轮不看 plans/ 与 tests/)
        exclude_patterns:
          - "tests/**"
          - "plans/**"
          - ".bensz-api/skills/auto-test-skill/**"
          # 兼容旧写法(更浅层,但保留避免历史文档/工具误解)
          - "tests/*"
          - "plans/*"
          - "*.bak"
        required_files:  # 必须审查的核心工作文件
          - "SKILL.md"
          - "config.yaml"
        required_dirs:  # 必须审查的目录(不存在可在计划中说明)
          - "scripts/"
          - "references/"
          - "templates/"
          - "assets/"
    
    # ============================================================================
    # B轮质量检查(质量原则检查;规划口径;维度以 b_round_check.dimensions 为准)
    # ============================================================================
    
    b_round_check:
      mandatory: true
      min_suggestions: 10
      target_suggestions_range: [15, 20]
      constructive_suggestion_required: true
      p0_fix_rate_required: 100
      p1_fix_rate_required: 100
      dimensions:
        - name: "hardcoded_ai_plan"
          label: "硬编码/AI功能规划"
          description: "检查确定性操作是否应硬编码,启发式判断是否由AI处理"
        - name: "redundancy_check"
          label: "冗余残留错误检查"
          description: "检查是否存在重复逻辑、残留引用、僵尸文件"
        - name: "security_check"
          label: "安全性检查"
          description: "检查输入验证、路径处理、敏感信息、权限控制"
        - name: "overdesign_check"
          label: "过度设计检查"
          description: "检查是否存在YAGNI违反、不必要的抽象、配置臃肿"
        - name: "generality_check"
          label: "通用性检查"
          description: "检查是否包含不必要的年份/场景限制/平台依赖等"
        - name: "consistency_check"
          label: "一致性检查"
          description: "检查 YAML frontmatter、SKILL.md、config.yaml 与示例的一致性"
        - name: "config_centralization_check"
          label: "配置集中化检查"
          description: "检查精确端(config.yaml)与模糊端(工作文档)是否完全分离,确保所有可配置参数集中在 config.yaml 作为单一真相来源"
        - name: "skill_md_weight_check"
          label: "SKILL.md瘦身检查"
          description: "检查 SKILL.md 是否过于冗长,应将详细内容模块化到 references/"
    
  • README.md 18.2 KB
    # auto-test-skill
    
    批判性思维驱动的测试驱动优化技能 - 用于在 AI 辅助开发后进行系统性测试与迭代优化。
    
    ## 概述
    
    本技能提供了一套完整的测试驱动优化工作流,帮助用户在AI辅助开发后进行系统性的测试、问题修复和迭代优化。
    
    **核心价值**:
    - ✅ **结构化问题管理**: 从bug发现到优先级排序的全流程管理
    - ✅ **可重复测试**: 规范化的测试目录和文档结构
    - ✅ **独立评估 + 迭代修复**: 每轮 A 轮独立审查当前状态,按计划修复并用轻量测试验证
    - ✅ **完整追溯**: 每轮迭代都有明确的测试计划和报告
    
    **设计理念**:
    本技能借鉴了成熟的软件测试实践(如时间戳命名测试会话、规范化文档结构、测试数据/脚本/输出分离等),确保每个测试会话都是独立、透明、可重复的;其中 **A 轮默认采用“独立评估”模式**(不查看 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/` 与 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/`),以降低确认偏差并提升多轮价值。
    
    ## 适用场景
    
    - ✅ 用户完成AI辅助开发后,需要进行系统性测试
    - ✅ 发现bug需要记录和优先级排序
    - ✅ 需要制定结构化的优化和测试计划
    - ✅ 需要管理多轮迭代测试和修复流程
    - ✅ 需要生成规范的测试报告和总结文档
    
    ## 使用方法
    
    ### 推荐用法(自动完整测试流程)
    
    **开发者推荐 Prompt**:
    
    ```
    使用 auto-test-skill 对 xxx 这个skill进行1次迭代优化。
    ```
    
    补充要求(推荐):每轮 A 轮为**独立评估**(不查看上一轮 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/` / `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/`),并明确本轮审查范围与排除范围。
    
    ### 人机协作用法(手动审核 AI 建议)
    
    本技能支持灵活的"人机协作"模式,你可以手动查看和审核 AI 的建议,而不必自动执行完整的修复流程。
    
    **典型场景**:
    
    ```
    根据 auto-test-skill 的B轮原则,目前 bensz-rmd-rules 还有哪些优化的地方?
    ```
    
    **优势**:
    - 你可以先查看 AI 发现的问题,再决定是否修复
    - 可以选择性采纳建议,而不是全盘接受
    - 适合用于代码审查、质量评估等场景
    
    **更多人机协作示例**:
    
    ```
    根据 auto-test-skill 的批判性思维框架,分析一下 my-skill 在架构设计上可能有哪些问题?
    ```
    
    ```
    用 auto-test-skill 的A轮独立评估模式,检查这个 skill 是否存在过度设计的问题。
    ```
    
    ### 触发方式
    
    在支持 Agent Skills 的工具(如 Codex CLI、Claude Code、Cursor 等)中使用以下表述之一触发本技能:
    
    **自动测试模式**:
    - "帮我测试一下这个技能"
    - "我需要制定测试计划"
    - "需要进行迭代优化"
    - "生成测试报告"
    
    **人机协作模式**:
    - "根据 auto-test-skill 的 B 轮原则分析这个 skill"
    - "用 auto-test-skill 的批判性思维检查这个项目"
    - "根据 auto-test-skill 的质量原则给出优化建议"
    
    ### 输入要求
    
    使用本技能前,请准备:
    
    1. **目标技能的根目录路径**
       - 示例: `/path/to/skills/your-skill`
    
    2. **测试发现的问题列表**
       - 可来自:用户反馈、测试结果、代码审查等
       - 至少包含:问题描述、复现步骤、期望行为
    
    3. **可选**: 已有测试数据或测试用例
       - 如果有,请提供数据路径
    
    ### 工作流程
    
    本技能遵循 **A轮×N + B轮** 的多轮迭代工作流:
    
    ```
    用户输入
      ↓
    [A轮 × N]:分析 → 计划 → 优化 → 轻量测试
      ↓
    B轮:质量原则检查 → 针对性优化 → 轻量验证
      ↓
    完成(文档齐全 + 问题闭环)
    ```
    
    详细说明请参阅 [SKILL.md](SKILL.md)。
    
    ## 输出交付
    
    使用本技能后,您将获得:
    
    1. **规划文档(A轮)**:`.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/vYYYYMMDDHHMM.md`
    2. **测试会话目录(A轮)**:`.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/vYYYYMMDDHHMM/`(包含 `TEST_PLAN.md`、`TEST_REPORT.md`)
    3. **质量检查报告(B轮)**:`.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/B轮-vYYYYMMDDHHMM.md`
    4. **验证会话目录(B轮)**:`.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/B轮-vYYYYMMDDHHMM/`(包含 `TEST_PLAN.md`、`TEST_REPORT.md`)
    
    ## 确定性辅助脚本(推荐)
    
    为避免每轮手工创建目录与文档骨架,推荐使用:
    
    ```bash
    python3 auto-test-skill/scripts/create_test_session.py --skill-root /path/to/target-skill --task-root /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description --kind a --id vYYYYMMDDHHMM --create-plan
    
    # 或:省略 --id 自动生成 vYYYYMMDDHHMM
    python3 auto-test-skill/scripts/create_test_session.py --skill-root /path/to/target-skill --task-root /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description --kind a --create-plan
    ```
    
    验证会话完整性(推荐,避免“空报告/占位符残留”):
    
    ```bash
    # 在目标 skill 根目录内执行
    python3 /path/to/auto-test-skill/scripts/verify_test_session.py --skill-root /path/to/target-skill --task-root /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description --require-plan /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description/auto-test-skill/output/tests/vYYYYMMDDHHMM
    ```
    
    说明:
    - `--skill-root` 指向“要被测试/被优化”的目标 skill 根目录(必须包含 `SKILL.md`)
    - `--create-plan` 会在缺失时生成 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/` 下对应的计划文档骨架(默认不覆盖)
    - 脚本会优先使用目标 skill 的 `templates/`(如存在);否则使用 auto-test-skill 自带 `templates/` 作为回退模板
    - B 轮可选:使用 `--a-test-id vYYYYMMDDHHMM` 记录“对应的 A 轮会话 id”(用于 B 轮报告可追溯)
    - `--seed-test-plan-from-plan`(高级,不推荐):会将 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/` 下的计划文档直接复制为 `TEST_PLAN.md`,通常你应当基于 `templates/TEST_PLAN_TEMPLATE.md` 补全验证点即可
    
    ## 文件结构
    
    ```
    auto-test-skill/
    ├── SKILL.md                           # 技能主文档
    ├── README.md                          # 本文件
    ├── config.yaml                        # 配置文件
    ├── .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/  # 规划文档目录
    ├── .bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/  # 测试会话目录
    ├── scripts/                           # 确定性辅助脚本(可选)
    ├── templates/                         # 文档模板
    │   ├── BUG_REPORT_TEMPLATE.md         # Bug报告模板
    │   ├── OPTIMIZATION_PLAN_TEMPLATE.md  # 优化计划模板
    │   ├── TEST_PLAN_TEMPLATE.md          # 测试计划模板
    │   ├── TEST_REPORT_TEMPLATE.md        # 测试报告模板
    │   ├── FINAL_SUMMARY_TEMPLATE.md      # 最终总结模板
    │   └── B_ROUND_CHECK_TEMPLATE.md      # B轮质量检查模板
    └── references/                        # 参考文档
        └── TESTING_BEST_PRACTICES.md      # 测试最佳实践
    ```
    
    ## 配置说明
    
    本技能使用 `config.yaml` 作为**口径统一**与**部分脚本参数**的单一来源。
    
    主要配置项:
    
    - **脚本会读取**:
      - **directories.\***:`.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/` 与 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/` 的相对目录(`scripts/create_test_session.py` 会做路径安全校验)
      - **templates.\***:计划/报告等模板路径(相对 skill 根目录)
    - **规划口径(AI/人类参考)**:
      - **test_rounds**:每轮数量阈值(10-20、P0+P1≥60%、系统性问题≥3 等)
      - **a_round_check.independent_review**:A 轮独立评估的审查范围与排除范围(不看 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/` 与 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/`)
      - **b_round_check**:B 轮质量检查是否强制、数量阈值、修复率要求、检查维度(`b_round_check.dimensions`)
    
    版本更新顺序(推荐):先更新 `config.yaml:skill_info.version`,再同步 `SKILL.md` YAML 表头与 `CHANGELOG.md`。
    
    详细配置请参阅 [config.yaml](config.yaml)。
    
    ## 示例使用场景
    
    ### 场景 1: 修复技能的 Bug
    
    **输入**:
    - 用户报告某个技能的3个bug
    - 技能根目录: `/path/to/skills/your-skill`
    
    **执行流程**:
    1. A轮:生成 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/vYYYYMMDDHHMM.md`(问题清单 + 改进计划)
    2. A轮:创建 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/vYYYYMMDDHHMM/` 并按计划修复与验证
    3. B轮:生成 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/B轮-vYYYYMMDDHHMM.md`(质量原则检查;维度以 `config.yaml:b_round_check.dimensions` 为准)
    4. B轮:创建 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/B轮-vYYYYMMDDHHMM/` 并做针对性验证
    5. 验收:更新 `CHANGELOG.md`
    
    **输出**:
    - 修复后的代码
    - 完整的测试文档
    - CHANGELOG.md 更新
    
    ### 场景 2: 多轮迭代优化
    
    **背景**: 第一次测试发现10个问题,计划分3轮迭代
    
    **迭代轮次**:
    - **第1轮** (`v202601021313`): 修复 P0(2个) + P1(3个) → 测试通过
    - **第2轮** (`v202601031015`): 修复 P1(2个) + P2(3个) → 测试通过
    - **第3轮** (`v202601041420`): 修复剩余 P2 + 新发现的问题 → 测试通过
    
    **最终输出**:
    - FINAL_SUMMARY.md(总结3轮优化历程)
    - 所有问题已修复
    - 测试覆盖率提升
    
    ## 最佳实践
    
    ### 1. 问题分类原则
    
    **严重程度判断标准**:
    
    | 严重程度 | 判断问题 |
    |----------|----------|
    | **Critical** | 数据丢失、安全漏洞、完全无法使用 |
    | **High** | 主要功能失效、性能严重退化、用户体验严重受损 |
    | **Medium** | 边缘功能失效、性能轻微退化、用户体验一般受损 |
    | **Low** | 文档错误、UI瑕疵、体验优化建议 |
    
    ### 2. 迭代计划原则
    
    **每次迭代应该**:
    - ✅ 专注修复少量高优先级问题(3-5个)
    - ✅ 确保每个修复都有对应的测试
    - ✅ 验证无回归后再合并
    
    **每次迭代不应该**:
    - ❌ 试图修复所有问题
    - ❌ 修复没有测试的问题
    - ❌ 引入新的破坏性变更
    
    ### 3. 测试设计原则
    
    **好的测试用例**:
    - ✅ 快速执行(几秒内)
    - ✅ 独立运行(不依赖顺序)
    - ✅ 结果明确(通过/失败清晰)
    - ✅ 可重复执行(结果稳定)
    
    **测试用例模板**:
    ```python
    def test_fix_problem_1():
        """测试问题#1的修复效果"""
        # Arrange
        input_data = {...}
    
        # Act
        result = function_to_test(input_data)
    
        # Assert
        assert result == expected_output
    ```
    
    ### 4. 文档管理原则
    
    **测试文档应该**:
    - ✅ 简洁明了(重点信息突出)
    - ✅ 结构一致(使用统一模板)
    - ✅ 及时更新(每个阶段结束后立即更新)
    - ✅ 独立完整(不依赖外部文档)
    
    ## 常见问题
    
    ### Q1: 如果测试会话太多怎么办?
    
    **A**: 测试会话目录本身就很轻量(主要是文档),可以保留所有历史会话。如果需要清理,建议:
    - 保留最近10个会话
    - 归档早期的会话到 `tests_archive/`(如你在项目里有该约定)
    - 保留关键里程碑的会话(如首次完整测试、重大修复等)
    
    ### Q2: 如果一个问题需要多轮迭代才能修复怎么办?
    
    **A**:
    - 在第一轮迭代中,尝试最小化修复(缓解问题而非完美解决)
    - 在后续迭代中,逐步完善修复
    - 在 BUG_REPORT.md 中标记问题的演进历史
    
    ### Q3: 如果在修复过程中引入新问题怎么办?
    
    **A**:
    - 立即记录新问题到 BUG_REPORT.md
    - 评估新问题的严重程度
    - 如果是 P0/P1,停止当前修复,优先处理新问题
    - 如果是 P2/P3,记录到下次迭代计划
    
    ### Q4: 如何确保测试的轻量级?
    
    **A**:
    - 优先使用单元测试而非集成测试
    - 使用 mock/stub 隔离外部依赖
    - 测试数据尽量小而精
    - 避免耗时操作(如网络请求、文件IO)
    
    ## 参考资源
    
    - **技能主文档**: [SKILL.md](SKILL.md)
    - **配置文件**: [config.yaml](config.yaml)
    - **文档模板**: [templates/](templates/)
    - **Agent Skills标准**: [https://agentskills.io](https://agentskills.io)
    
    **相关阅读**:
    - 测试驱动开发(TDD)最佳实践
    - 敏捷开发中的迭代优化方法
    - 软件质量保证(SQA)标准流程
    
    ## WHICHMODEL - 模型选择最佳实践
    
    ### 披露信息
    - **最后更新**:2026-01-25
    - **覆盖厂商**:Anthropic(Claude 系列)
    - **来源构成**:官方文档 60%、技术博客 25%、社区讨论 15%
    - **数据时效**:2025-2026
    - **局限性**:本次调研主要基于 Anthropic 官方文档,未包含第三方独立基准测试
    
    ### 场景一:批判性代码分析与问题发现(A 轮核心任务)
    - **推荐模型**:Claude Sonnet 4.5
    - **推荐参数**:
      - Extended Thinking:开启,budget_tokens: 10000-16000
      - Temperature:不可调(Thinking 模式下固定)
      - Max Tokens:16384
    - **理由**:Sonnet 4.5 在 SWE-bench Verified 上达到 **77.2%**(state-of-the-art),特别擅长"测试其自己的代码"。官方文档明确指出其"在代码分析任务上表现卓越",且相比前代模型"代码编辑错误率从 9% 降至 0%"。
    - **来源**:[Anthropic Models Overview](https://platform.claude.com/docs/en/docs/about-claude/models/all-models)、[Sonnet 4.5 Performance Summary](https://www.anthropic.com/claude/sonnet)
    
    ### 场景二:测试计划与优化方案制定(A 轮规划任务)
    - **推荐模型**:Claude Opus 4.5
    - **推荐参数**:
      - Extended Thinking:开启,budget_tokens: 16000-32000
      - Max Tokens:32768
    - **理由**:Opus 4.5 官方定位为"Premium model combining maximum intelligence with practical performance",在复杂推理任务上表现最佳。官方案例显示其能"发现未预料但合法的 workaround",证明其深度推理能力。此外,用户报告"工具调用错误和构建错误减少 50%-75%"。
    - **适用**:多轮迭代优化计划、复杂依赖关系分析、P0/P1 优先级评估
    - **来源**:[Anthropic Models Overview](https://platform.claude.com/docs/en/docs/about-claude/models/all-models)、[Opus 4.5 Announcement](https://www.anthropic.com/news/claude-opus-4-5)
    
    ### 场景三:B 轮质量原则检查(8 维度系统性审查)
    - **推荐模型**:Claude Sonnet 4.5
    - **推荐参数**:
      - Extended Thinking:开启,budget_tokens: 8000-12000
      - Max Tokens:16384
    - **理由**:B 轮检查涉及 8 个标准化维度(硬编码/AI 规划、冗余检查、安全性等),属于结构化分析任务。Sonnet 4.5 在此类任务上性价比最高($3/MTok input vs Opus 的 $5/MTok),且官方推荐其用于"complex agents and coding"。
    - **来源**:[Anthropic Models Overview](https://platform.claude.com/docs/en/docs/about-claude/models/all-models)
    
    ### 场景四:轻量测试验证(快速筛查)
    - **推荐模型**:Claude Haiku 4.5
    - **推荐参数**:
      - Extended Thinking:关闭(简单任务无需深度推理)
      - Temperature:0.3
      - Max Tokens:4096
    - **理由**:Haiku 4.5 官方定位为"near-frontier intelligence"的最快模型,价格仅 $1/MTok input。适合简单的语法检查、格式验证等轻量任务,可节省时间和成本。
    - **适用**:早期问题筛查、简单格式验证、快速反馈循环
    - **来源**:[Anthropic Models Overview](https://platform.claude.com/docs/en/docs/about-claude/models/all-models)
    
    ### 场景五:多步骤工具调用与交叉验证
    - **推荐模型**:Claude Sonnet 4.5 / Opus 4.5
    - **推荐参数**:
      - Extended Thinking:开启
      - Interleaved Thinking:开启(需 beta header `interleaved-thinking-2025-05-14`)
      - budget_tokens:可超过 max_tokens(工具调用场景特殊规则)
    - **理由**:auto-test-skill 涉及大量 Glob/Read/Grep 工具调用。启用 Interleaved Thinking 后,Claude 可在每次工具调用结果返回后进行推理,做出"更细致的决策"。官方文档明确支持此功能用于"chain multiple tool calls with reasoning steps in between"。
    - **来源**:[Extended Thinking with Tool Use](https://platform.claude.com/docs/en/docs/build-with-claude/extended-thinking#extended-thinking-with-tool-use)
    
    ### 模型对比总结
    
    | 场景 | 推荐模型 | Thinking | 核心优势 | 成本(input) |
    |------|----------|----------|----------|---------------|
    | A 轮问题发现 | Sonnet 4.5 | 开 | SWE-bench 77.2%,代码分析 SOTA | $3/MTok |
    | A 轮规划制定 | Opus 4.5 | 开 | 最强推理,复杂规划 | $5/MTok |
    | B 轮质量检查 | Sonnet 4.5 | 开 | 结构化分析性价比 | $3/MTok |
    | 轻量验证 | Haiku 4.5 | 关 | 最快响应,低成本 | $1/MTok |
    | 多步工具调用 | Sonnet/Opus | 开+交叉 | 工具间推理 | $3-5/MTok |
    
    ### 通用原则
    
    1. **默认用 Sonnet 4.5**:官方明确推荐"如果不确定用哪个模型,从 Sonnet 4.5 开始"——它在"智能、速度和成本之间提供最佳平衡"
    2. **复杂规划升级 Opus**:当任务涉及多因素权衡、长期规划、架构决策时,使用 Opus 4.5
    3. **Extended Thinking 是关键**:auto-test-skill 的批判性分析任务强烈推荐开启 Thinking 模式,预算建议 10000-16000 tokens
    4. **Interleaved Thinking 用于工具密集型任务**:涉及多次 Glob/Read/Grep 调用时,启用交叉推理可提升分析质量
    5. **Haiku 用于快速验证**:轻量任务用 Haiku 可节省 70%+ 成本
    
    ### 更新记录
    - 2026-01-25:基于 Anthropic 官方文档(2025-2026)全面更新,新增 Extended Thinking 和 Interleaved Thinking 最佳实践
    - 2026-01-03:初始调研
    
    ## 版本历史
    
    - **v1.0.0** (2026-01-02): 初始版本
      - 6阶段工作流
      - 结构化问题管理
      - 测试会话管理
      - 文档模板系统
    
    ## 许可证
    
    本技能遵循 [Agent Skills 开放标准](https://agentskills.io)。
    
    ## 联系方式
    
    - **作者**: bensz
    - **创建时间**: 2026-01-02
    - **反馈渠道**: 通过 GitHub Issues 或项目讨论区反馈
    
    ---
    
    **祝您测试愉快!** 🎉
    
  • SKILL.md 17.2 KB
    ---
    name: auto-test-skill
    category: normal
    description: 当用户明确要求测试 Skill、运行 auto-test 或对 Skill 进行批判性测试时使用。系统化发现、记录并验证 Skill 问题。⚠️ 不适用:用户只是想开发或优化 Skill,或没有明确测试意图。
    metadata:
      author: Bensz Conan
      short-description: 批判性思维驱动的测试驱动优化流水线(多轮 A 轮 + B 轮质量原则检查)
      keywords:
        - auto-test-skill
        - 批判性测试
        - QA review
    ---
    
    # auto-test-skill(批判性思维驱动的测试优化技能)
    
    ## 目标
    
    当用户明确要求"测试技能"、"运行 auto-test"或"进行批判性测试"时使用。通过多轮 A 轮批判性测试 + B 轮质量原则检查,系统化发现、记录、修复问题,并将中间产物写入调用方锁定的 `.bensz-api/task-*/auto-test-skill/` 工作区。⚠️ 不适用:用户只是想优化功能(应直接修改)、只是询问技能问题(应直接回答)、没有明确"测试"意图。
    
    ## 流程
    
    ### 输入
    
    输入为待测试的 Agent Skill 根目录;可选输入包括测试提示、A/B 轮次数、运行 ID、`config.yaml` 参数和输出路径。测试前确认目标 `SKILL.md`、配置、脚本、模板与必要 references 可读,且不把测试产物写回被测 Skill 源目录。
    
    ### 执行步骤
    
    #### 你要产出的东西
    
    本 skill 的交付不是“口头建议”,而是一组可追溯的文件:
    
    (目录位置以 `config.yaml:directories` 为准;默认 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/` + `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/`)
    
    - `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/vYYYYMMDDHHMM.md`:A 轮问题分析与改进计划(每轮 1 份)
    - `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/vYYYYMMDDHHMM/`:A 轮测试会话目录(包含 `TEST_PLAN.md` + `TEST_REPORT.md`)
    - `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/B轮-vYYYYMMDDHHMM.md`:B 轮质量原则检查报告(维度以 `config.yaml:b_round_check.dimensions` 为准)
    - `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/B轮-vYYYYMMDDHHMM/`:B 轮验证会话目录(包含 `TEST_PLAN.md` + `TEST_REPORT.md`)
    
    #### 工作流程
    
    ##### 概览
    
    ```
    用户输入
      ↓
    [A轮 × N]:分析 → 计划 → 优化 → 轻量测试
      ↓
    B轮:质量原则检查 → 针对性优化 → 轻量验证
      ↓
    完成(文档齐全 + 问题闭环)
    ```
    
    ##### A 轮测试(可重复 N 次)
    
    ###### A.1 初始化会话(生成测试 ID + 目录)
    
    目标:在已锁定的 `--task-root` 下创建本轮 `auto-test-skill/output/plans/` 与 `auto-test-skill/output/tests/` 骨架,不向被测 Skill 源目录写入产物。
    
    推荐使用确定性脚本(避免 AI 每次手动拼目录/文件名):
    
    ```bash
    # 复用已锁定的项目任务目录
    python3 /path/to/auto-test-skill/scripts/create_test_session.py --skill-root /path/to/target-skill --task-root /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description --kind a --id vYYYYMMDDHHMM --create-plan
    
    # 方式2:在任意位置执行(--skill-root 指向目标 skill 根目录)
    python3 auto-test-skill/scripts/create_test_session.py --skill-root /path/to/target-skill --task-root /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description --kind a --id vYYYYMMDDHHMM --create-plan
    ```
    
    说明:
    - 脚本会优先使用目标 skill 的 `templates/`(如存在);否则回退到 auto-test-skill 自带的 `templates/`,确保对任意 skill 都可用。
    - `--id` 可省略(脚本自动生成 `vYYYYMMDDHHMM`);如显式指定,必须为 `vYYYYMMDDHHMM` 格式。
    
    最低要求:
    - `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/` 与 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/` 存在
    - `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/vYYYYMMDDHHMM/TEST_PLAN.md` 与 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/vYYYYMMDDHHMM/TEST_REPORT.md` 存在
    可选增强(推荐):
    - 使用 `--create-plan` 自动生成 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/vYYYYMMDDHHMM.md` 的骨架(默认不覆盖)
    
    ###### A.2 批判性分析与计划生成(写入 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/`)
    
    目标:使用**批判性思维**发现系统性问题,写成可执行计划,按 P0/P1/P2 排序。
    
    输出:`.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/vYYYYMMDDHHMM.md`
    
    ⚠️ **批判性思维是核心要求**(不是可选项):
    - **必须使用「刁钻角度」思考**(详见 `references/CRITICAL_THINKING_GUIDE.md`)
    - **必须发现至少 3 个系统性问题**(架构/过度设计/一致/安全)
    - **禁止列出"不痛不痒"的表面问题**(如"缺少注释"等 P2 级别问题不应占多数)
    
    **质量要求**(强制):
    - 每轮至少发现 10 个问题(P0 + P1 + P2 总和)
    - 鼓励达到 15-20 个问题(深入挖掘)
    - **P0 + P1 占比必须 ≥ 60%**(确保问题有价值)
    - **系统性问题 ≥ 3 个**(架构设计/过度设计/一致性/安全性)
    
    **核心要求**:
    - **独立评估原则**(强制):
      - 每轮 A 轮必须基于目标 skill 的**当前工作状态**独立分析
      - **不查看**上轮的 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/` 和 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/` 文件,避免"确认偏差"与"路径依赖"
      - 每轮都是一次完整的、无偏见的系统性审查
    - **审查范围**(强制):
      - 必须审查:`SKILL.md`、`config.yaml`(核心工作文件)
      - 必须审查目录:`scripts/`、`references/`、`templates/`、`assets/`(如不存在可在计划中说明)
      - 排除范围:`.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/`、`.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/`、`CHANGELOG.md`、`README.md`(测试产物、变更记录和用户文档,不属于 skill 的工作代码),以及 `config.yaml` 中 `a_round_check.independent_review.exclude_patterns` 命中的文件
      - 审查方法:使用 Glob/Read/Grep(如 `rg`/`find`)对工作文件做全量扫描,确保不遗漏
    - **批判性聚焦**:每轮选择 1-2 个聚焦维度(系统架构/过度设计/一致性/安全性/边缘情况/用户体验)
    - **刁钻角度**:必须使用至少一个刁钻角度(边缘情况/恶意输入/隐式假设/自我质疑/跨文件矛盾)
    - **优先级依据**:P0/P1/P2 必须有明确的判定标准
      - P0: 阻塞性问题、安全风险、核心功能缺失、架构设计缺陷
      - P1: 重要优化(过度设计/冗余/不一致)、功能增强、测试覆盖不足
      - P2: 锦上添花、文档改进、后续迭代项
    - **可追溯性**:每个问题必须包含位置、现象、影响、修复建议、验证方法
    - **建设性**:每条建议必须可执行、有证据、有价值、可验证(详见 `references/CONSTRUCTIVE_SUGGESTION_GUIDELINES.md`)
    
    **批判性思维框架**(必读):
    - `references/CRITICAL_THINKING_GUIDE.md` ⚠️ **核心文档,必须使用**
      - 框架 1: 系统视角思考(架构设计/过度设计/一致性)
      - 框架 2: 刁钻角度思考(边缘情况/恶意输入/隐式假设/自我质疑)
      - 框架 3: 问题质量标准(黄金公式 + 质量检查清单)
    - `references/A_ROUND_PLAN_TEMPLATE.md` ⚠️ **已简化,突出批判性思维要求**
    - `references/ISSUE_DISCOVERY_TECHNIQUES.md` 问题挖掘技巧(辅助工具)
    - `references/CONSTRUCTIVE_SUGGESTION_GUIDELINES.md` 建设性建议标准
    - `references/ANTI_PATTERNS_LIBRARY.md` 反例库(快速识别常见问题)
    
    ###### A.3 执行优化与轻量测试(写入 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/`)
    
    目标:按计划逐项修复,并用轻量测试验证。
    
    输出:`.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/vYYYYMMDDHHMM/TEST_REPORT.md`
    
    轻量测试原则:
    - 只验证“核心路径”与“本轮变更点”
    - 每条结论必须有可复现证据(命令输出、文件、对比结果)
    - 中间产物放入 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/vYYYYMMDDHHMM/_artifacts/`,不污染主目录
    
    可选增强(推荐,确定性自检):
    
    ```bash
    python3 auto-test-skill/scripts/verify_test_session.py --skill-root /path/to/target-skill --task-root /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description --require-plan /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description/auto-test-skill/output/tests/vYYYYMMDDHHMM
    ```
    
    ###### A.4 是否进入下一轮
    
    ⚠️ **强制检查**(必须满足才能进入下一轮):
    - [ ] 本轮已提出至少 10 个问题(P0 + P1 + P2 总和)
    - 如未达到,必须继续挖掘问题(使用 `references/ISSUE_DISCOVERY_TECHNIQUES.md` 中的技巧)
    
    **进入下一轮 A 轮的条件**(在满足强制检查的前提下):
    - [ ] 用户指定的轮次数未完成
    - [ ] 本轮问题(P0/P1/P2)已全部闭环:修复完成,并在 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/` 会话的 `TEST_REPORT.md` 中给出验证证据
    
    注意:每轮 A 轮都是独立评估,不因“问题已解决”而提前终止;如用户指定 N 轮,则按 N 轮执行。
    
    **重要**:A 轮结束后(无论多少轮),必须进入 B 轮质量检查,不得跳过。
    
    ##### B 轮质量原则检查(当前 8 项)
    
    ⚠️ **强制执行**:B 轮质量检查是自动测试流程的强制性环节,除非用户明确要求跳过,否则不得省略。
    
    ###### B.1 产出质量检查报告(写入 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/`)
    
    目标:对 A 轮后的最新状态做系统性质量检查。
    
    输出:`.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/B轮-vYYYYMMDDHHMM.md`
    
    检查维度(以 `config.yaml` 的 `b_round_check.dimensions` 为准):
    - 硬编码/AI 功能规划
    - 冗余残留错误检查
    - 安全性检查
    - 过度设计检查
    - 通用性检查
    - 一致性检查
    - 配置集中化检查:检查精确端(config.yaml)与模糊端(工作文档)是否完全分离,确保所有可配置参数集中在 config.yaml 作为单一真相来源
    - SKILL.md 瘦身检查:检查 SKILL.md 是否过于冗长,应将详细内容模块化到 `references/`
    
    模板:`templates/B_ROUND_CHECK_TEMPLATE.md`
    
    ###### B.2 B 轮优化与验证(写入 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/`)
    
    ⚠️ **强制修复要求**:
    - B 轮发现的 **所有 P0-P2 问题都必须处理**(修复或明确说明不修复理由)
    - P0 问题必须修复
    - P1 问题必须修复(除非有合理理由)
    - P2 问题应尽可能修复
    - 每个修复必须有验证证据(命令输出、文件对比、测试结果)
    - 修复后必须更新 `CHANGELOG.md`
    
    **验证报告必须包含**:
    1. 修复清单:每个 P0-P2 问题的修复方案和证据
    2. 遗留问题:未修复问题及原因(无论优先级)
    3. 变更记录:更新目标 skill 的 CHANGELOG.md
    
    可选增强(推荐,确定性自检):
    
    ```bash
    python3 auto-test-skill/scripts/verify_test_session.py --skill-root /path/to/target-skill --task-root /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description --require-plan /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description/auto-test-skill/output/tests/B轮-vYYYYMMDDHHMM
    ```
    
    **完成条件**:
    - [ ] P0 问题修复率 = 100%
    - [ ] P1 问题修复率 = 100%(除非有合理的不修复理由)
    - [ ] P2 问题修复率 ≥ 60%(鼓励全部修复)
    - [ ] 所有修复都有可复现证据
    
    目标:对 B 轮发现的所有问题(P0-P2)进行系统性修复并验证。
    
    推荐创建独立会话目录:
    
    ```bash
    python3 /path/to/auto-test-skill/scripts/create_test_session.py --skill-root /path/to/target-skill --task-root /path/to/project/.bensz-api/task-YYYYMMDD-HHMM-description --kind b --id vYYYYMMDDHHMM --a-test-id vYYYYMMDDHHMM --create-plan
    ```
    
    输出:`.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/B轮-vYYYYMMDDHHMM/TEST_REPORT.md`
    
    #### 可复用资源
    
    - 配置:`config.yaml`
    - 模板:`templates/`
      - A 轮计划:`templates/OPTIMIZATION_PLAN_TEMPLATE.md`
      - B 轮质量检查:`templates/B_ROUND_CHECK_TEMPLATE.md`
      - Bug 报告:`templates/BUG_REPORT_TEMPLATE.md`
      - 最终总结:`templates/FINAL_SUMMARY_TEMPLATE.md`
      - 测试计划:`templates/TEST_PLAN_TEMPLATE.md`
      - 测试报告:`templates/TEST_REPORT_TEMPLATE.md`
    - 参考:`references/`
      - **批判性思维指南**:`references/CRITICAL_THINKING_GUIDE.md` ⚠️ **核心文档,必须使用**
      - A 轮计划结构:`references/A_ROUND_PLAN_TEMPLATE.md` ⚠️ **已简化,突出批判性思维**
      - 测试最佳实践:`references/TESTING_BEST_PRACTICES.md`
      - 建设性建议标准:`references/CONSTRUCTIVE_SUGGESTION_GUIDELINES.md`
      - 问题挖掘技巧:`references/ISSUE_DISCOVERY_TECHNIQUES.md`
      - 反例库:`references/ANTI_PATTERNS_LIBRARY.md`
    - 辅助脚本:`scripts/create_test_session.py`
    - 辅助脚本:`scripts/verify_test_session.py`
    
    ### 输出
    
    每轮必须交付可追溯文件:A 轮计划 `output/plans/vYYYYMMDDHHMM.md`、A 轮会话 `output/tests/vYYYYMMDDHHMM/`,B 轮报告 `output/plans/B轮-vYYYYMMDDHHMM.md` 和 B 轮会话 `output/tests/B轮-vYYYYMMDDHHMM/`;各会话至少包含 `TEST_PLAN.md` 与 `TEST_REPORT.md`,具体目录以 `config.yaml:directories` 为准。
    
    ### 输出管理
    
    #### BenszAPI 任务工作区
    
    
    #### 目录与命名规范
    
    - 测试会话 ID:`vYYYYMMDDHHMM`(分钟级时间戳)
    - 规划文档:默认放在 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/`(以 `config.yaml:directories.plans` 为准)
    - 测试会话:默认放在 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/`(以 `config.yaml:directories.tests` 为准)
    - B 轮统一加前缀:`B轮-`
    
    ### 校验
    
    #### 完成条件(验收)
    
    - [ ] 用户指定的 A 轮次数已完成(或明确说明提前结束原因)
    - [ ] B 轮质量检查已完成并形成报告(⚠️ 强制要求,参考 `config.yaml` 的 `b_round_check.mandatory`)
    - [ ] 每轮 A 轮平均问题数量 ≥ 10 个(P0 + P1 + P2 总和)
    - [ ] **每轮 P0 + P1 占比 ≥ 60%**(确保问题有价值)
    - [ ] **每轮系统性问题 ≥ 3 个**(架构/过度设计/一致/安全)
    - [ ] 关键问题(P0/P1)已闭环:计划 → 修复 → 证据 → 结论
    - [ ] B 轮 P0 问题修复率 = 100%,P1 问题修复率 = 100%(或在报告中逐条说明不修复理由)
    - [ ] `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/plans/` 与 `.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/auto-test-skill/output/tests/` 结构完整且可追溯
    - [ ] 目标 skill 的 `CHANGELOG.md` 已更新
    
    ### 失败与恢复
    
    脚本、目标 Skill 读取或测试执行失败时,保留当前会话的计划、日志和测试报告,明确区分输入缺失、环境错误与行为失败,并给出复现命令;可在同一任务工作区重试未完成阶段。证据不足时不得臆测通过,A 轮与 B 轮的强制环节不得静默跳过。
    
    
    ## 约束
    
    <!-- BEGIN COMMON CONSTRAINTS -->
    <!-- Source-Hash: sha256:15120201e9e0c7569517261d57ecefb63ac279c26ed13876f8e95b6dc35854d3 -->
    <!-- Template-ID: skill-common-constraints; Template-Version: 1; Sync-Policy: exact-block -->
    
    ### 公共硬约束
    
    本块由 `docs/templates/skill-common-constraints.md` 统一维护;每个 `SKILL.md` 的 `## 约束` 必须逐字同步本块,不得在副本中改写公共规则。
    
    - 任务需要落盘时,使用唯一的 `./.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/` 根目录;共享材料放入 `shared/`,Skill 专属材料放入该 Skill 的 `input/`、`output/`、`log/`。
    - 正式交付物、源代码和正式计划按项目约定保存,不写入任务工作区;未经授权不覆盖、删除、迁移或远程写入。
    - 项目维护变更检查 BAC 可用性并记录需求、AI 产出、工具结果、文件改动和验证摘要;BAC 只做过程审计,不替代署名、责任或合规判断。
    - 不记录 API Key、访问令牌、密码、Cookie、环境/凭据文件、私有 Prompt、身份信息、本地用户名、主机名或不必要的大体积原始数据。
    - 文件路径必须规范化并限制在授权项目范围内;外部 URL、子进程和网络访问遵循最小权限,防止路径遍历、SSRF 和命令注入。
    - Skill 版本唯一记录在自身 `config.yaml:skill_info.version`;公开 API、协议、目录或配置变更同步文档与 `CHANGELOG.md`。
    - `bensz-collect-bugs` 是一个 Agent Skill;仅将 Bensz Agent Skill 或 Bensz 基础设施本身的设计缺陷交给它。先脱敏写入 `~/.bensz-skills/bugs/`,当前任务不中断,只有用户明确要求才公开上报,禁止直接修改用户已安装的 Skill 源码。
    
    <!-- End of canonical common constraints. -->
    <!-- END COMMON CONSTRAINTS -->
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related