From 1566e2d3eb6e984550f9082ad6a69d3f327ad3d7 Mon Sep 17 00:00:00 2001 From: johnQ Date: Sun, 1 Nov 2026 05:33:50 +0800 Subject: [PATCH] =?UTF-8?q?feat(skill):=20beta=20=E6=8A=80=E8=83=BD=20diag?= =?UTF-8?q?nosing-bugs=20+=20=E6=9C=88=E5=BA=A6=E5=AE=A1=E9=98=85=E4=B8=8E?= =?UTF-8?q?=20evals=20=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 diagnosing-bugs(beta):先建红循环再推理、二分定位、补回归测试;含 evals 与四段式文档 - 路由表加入难查 bug 行 - scripts/monthly-review.sh:一条命令跑月度审阅 - scripts/evals-status.py + reports/evals/TEMPLATE.md:evals 覆盖与回归报告模板 - skill-creator 实战记录 #1(待观察后晋升) --- CHANGELOG.md | 7 +++ MAINTENANCE.md | 5 +- catalog.json | 18 +++++- docs/skill-routing.md | 1 + docs/skills/diagnosing-bugs.md | 26 ++++++++ reports/evals/TEMPLATE.md | 15 +++++ scripts/evals-status.py | 31 ++++++++++ scripts/monthly-review.sh | 25 ++++++++ .../.claude-plugin/plugin.json | 11 ++++ .../diagnosing-bugs-plugin/skills/SKILL.md | 62 +++++++++++++++++++ .../skills/evals/evals.json | 27 ++++++++ 11 files changed, 224 insertions(+), 4 deletions(-) create mode 100644 docs/skills/diagnosing-bugs.md create mode 100644 reports/evals/TEMPLATE.md create mode 100755 scripts/evals-status.py create mode 100755 scripts/monthly-review.sh create mode 100644 skills-dev/diagnosing-bugs-plugin/.claude-plugin/plugin.json create mode 100644 skills-dev/diagnosing-bugs-plugin/skills/SKILL.md create mode 100644 skills-dev/diagnosing-bugs-plugin/skills/evals/evals.json diff --git a/CHANGELOG.md b/CHANGELOG.md index af61462..f02faa2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,3 +53,10 @@ - 补齐剩余 24 个技能(dev 类为主)的 `evals/evals.json`(各 3 条)与 `docs/skills/.md`(四段式)。 - `--coverage`:40 个 promoted+model-invoked 技能的 evals 与文档缺口 **24 → 0**。 + +### 继续推进(2026-11-01) + +- 新增 beta 技能 `diagnosing-bugs`(难查 bug 诊断纪律:先建红循环再推理),补齐 evals 与四段式文档;路由表同步。 +- 新增 `scripts/monthly-review.sh`:一条命令跑月度审阅(覆盖率 / 扫描 / 第三方 / catalog / description 异常)。 +- 新增 `scripts/evals-status.py` 与 `reports/evals/TEMPLATE.md`:evals 覆盖率与回归报告模板。 +- `skill-creator` 实战记录 #1:用标准流程新建 `diagnosing-bugs`(beta,待观察后晋升)。 diff --git a/MAINTENANCE.md b/MAINTENANCE.md index d6759bf..ec4a6bd 100644 --- a/MAINTENANCE.md +++ b/MAINTENANCE.md @@ -25,7 +25,8 @@ - 范围:上周改过的技能 + 3 个高风险技能(`dev-coding`、`dev-review`、`req-design`)。 - 每技能取 1 条关键用例,做「有技能 / 无技能」对比,按 rubric 打分。 -- 结果记录到 `reports/evals/YYYY-Www.md`,进周报。 +- 结果记录到 `reports/evals/YYYY-Www.md`(模板 `reports/evals/TEMPLATE.md`),进周报。 +- 用 `python3 scripts/evals-status.py` 看哪些技能已有 evals、哪些已有回归报告。 - 连续两次无增量的技能 → 按 `SCOPE.md` 评估降级。 - 不做全量(61 技能 × 3 用例成本过高);全量只在治理大改时做。 @@ -34,7 +35,7 @@ - 两台机器 `--audit` 漂移必须为 0(beta/deprecated 除外)。 - 审 `catalog.json`:`description` 长度 <80 或 >600 的标黄;含「各种 / 等等 / 相关」这类泛化词的标出。 - 第三方技能(arkcli 等)有变动时,评估是否影响团队技能;跑一次 `./scripts/scan-installed.sh`。 -- 跑 `python3 scripts/validate-skills.py --coverage`:报告缺 evals / 缺四段式文档的技能,按 `SCOPE.md` 的覆盖率路线图推进。 +- 跑 `./scripts/monthly-review.sh` 一次出齐:覆盖率、本仓库扫描、第三方扫描、catalog 一致性、description 异常项。 ## 每季度首月 1 日 10:30 — 治理复核 diff --git a/catalog.json b/catalog.json index 55d4b0b..4c798c1 100644 --- a/catalog.json +++ b/catalog.json @@ -7,13 +7,14 @@ "missing_evals": [], "missing_docs": [] }, - "generated_at": "2026-10-31T21:19:23Z", - "total": 61, + "generated_at": "2026-10-31T21:33:50Z", + "total": 62, "counts": { "promoted/user-invoked": 18, "deprecated/user-invoked": 1, "promoted/model-invoked": 40, "beta/user-invoked": 1, + "beta/model-invoked": 1, "deprecated/model-invoked": 1 }, "skills": [ @@ -420,6 +421,19 @@ "has_evals": true, "has_docs": true }, + { + "name": "diagnosing-bugs", + "category": "dev", + "version": "0.1.0", + "status": "beta", + "invocation": "model-invoked", + "description": "难查 bug 的诊断纪律:先造出一条「现在就为这个 bug 变红」的紧反馈循环,再二分定位、最小验证、补回归测试。当 bug 难复现、间歇失败、或第一次看没头绪时使用。", + "description_len": 84, + "path": "skills-dev/diagnosing-bugs-plugin/skills/SKILL.md", + "digest": "d93fb95c073858cc", + "has_evals": true, + "has_docs": true + }, { "name": "executing-plans", "category": "dev", diff --git a/docs/skill-routing.md b/docs/skill-routing.md index 3bba4ab..46ce631 100644 --- a/docs/skill-routing.md +++ b/docs/skill-routing.md @@ -21,6 +21,7 @@ | 设计 / 拆任务 | `req-design`、`dev-arch`、`db-migration` | | 编码 | `dev-coding`、`karpathy-guidelines` | | 测试 | `dev-test`、`req-test-gate` | +| 难查的 bug / 间歇失败 | `diagnosing-bugs`(先建红循环再推理) | | 代码评审 | `dev-review`、`review-checklist` | | 发布(Slark 仓库/Desktop) | `slark-cicd` | | 发布(DSH 插件/宿主补丁) | `slark-dsh-cicd` | diff --git a/docs/skills/diagnosing-bugs.md b/docs/skills/diagnosing-bugs.md new file mode 100644 index 0000000..3b601ef --- /dev/null +++ b/docs/skills/diagnosing-bugs.md @@ -0,0 +1,26 @@ +# diagnosing-bugs + +## What it does + +给难查的 bug 一套诊断纪律:先造出「现在就为这个 bug 变红」的紧反馈循环,再二分定位、一次验一个假设、最小改动修复,最后补一条曾经红过的回归测试。 + +## When to reach for it + +- 间歇失败、偶发问题,第一次看没头绪 +- 已知两个好版本之间引入的回归(适合 git bisect) +- 修过几次没修好的 bug + +一眼可见的拼写/配置错误不需要它,直接修。 + +## Common questions + +- **为什么不能先猜着改?** 没有红循环就没有验证手段,改了也不知道是不是这次改动生效。 +- **复现不出来怎么办?** 提高复现率(缩小输入、调整时序、加观测),或用 git bisect 从版本维度定位,而不是盲上。 +- **修完就完了吗?** 不,必须补一条回归测试,并证明修复前它是红的。 +- **和 dev-test 的区别?** dev-test 管测试怎么写;本技能管「怎么找到 bug」。 + +## It's working if + +- 动手改代码前,先给出了一条现在为红的命令 +- 每次改动只变一个变量,并能说出上次结果的差异 +- 修复结论包含根因 + 回归测试 + 「曾经红过」的证据 diff --git a/reports/evals/TEMPLATE.md b/reports/evals/TEMPLATE.md new file mode 100644 index 0000000..065e0fd --- /dev/null +++ b/reports/evals/TEMPLATE.md @@ -0,0 +1,15 @@ +# 技能 evals 抽样回归 + +- 日期:YYYY-MM-DD +- 范围:上周改动过的技能 + 高风险技能(dev-coding / dev-review / req-design) +- 方法:每技能取 1 条关键用例,做「有技能 / 无技能」两组独立输出对比,按 rubric 打分(0–2) + +| 技能 | 用例 | 有技能 | 无技能 | 差值 | 结论 | +| --- | --- | --- | --- | --- | --- | +| | | | | | | + +## 结论与新发现 + +- 有效技能: +- 无增量技能(按 SCOPE 评估是否降级): +- 需要补的用例: diff --git a/scripts/evals-status.py b/scripts/evals-status.py new file mode 100755 index 0000000..4090584 --- /dev/null +++ b/scripts/evals-status.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +"""列出各技能的 evals 与是否已有回归报告(reports/evals/.md)。""" +from __future__ import annotations +import json +from pathlib import Path + +ROOT = Path(__file__).resolve().parent.parent +rows = [] +for pj in sorted(ROOT.glob("skills-*/*-plugin/.claude-plugin/plugin.json")): + meta = json.loads(pj.read_text()) + name = meta.get("install_name") + if not name: + continue + ev = next((pj.parent.parent / "skills").rglob("evals/evals.json"), None) + cases = 0 + if ev: + try: + cases = len(json.loads(ev.read_text()).get("evals", [])) + except Exception: + cases = 0 + report = ROOT / "reports" / "evals" / f"{name}.md" + rows.append((name, meta.get("status", "promoted"), cases, report.is_file())) + +with_evals = sum(1 for r in rows if r[2] > 0) +with_report = sum(1 for r in rows if r[3]) +print(f"{'技能':32} {'status':10} {'用例':4} 回归报告") +for name, status, cases, has_report in rows: + if cases == 0: + continue + print(f"{name:32} {status:10} {cases:<4} {'有' if has_report else '-'}") +print(f"\n有 evals 的技能: {with_evals}/{len(rows)};已有回归报告: {with_report}/{with_evals}") diff --git a/scripts/monthly-review.sh b/scripts/monthly-review.sh new file mode 100755 index 0000000..e263f44 --- /dev/null +++ b/scripts/monthly-review.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# 月度技能审阅:一条命令跑完 MAINTENANCE 里的月度项。 +# 用法: ./scripts/monthly-review.sh +set -uo pipefail +cd "$(git rev-parse --show-toplevel)" || exit 1 +echo "== 技能月度审阅 $(date '+%F %H:%M') ==" +echo; echo "-- 1. 覆盖率(promoted + model-invoked)--" +python3 scripts/validate-skills.py --coverage +echo; echo "-- 2. 本仓库安全扫描 --" +./scripts/scan-skill.sh | tail -2 +echo; echo "-- 3. 第三方已装技能扫描 --" +./scripts/scan-installed.sh | tail -2 +echo; echo "-- 4. catalog 是否最新 --" +python3 scripts/generate-catalog.py --check +echo; echo "-- 5. catalog 摘要与 description 异常项 --" +python3 - <<'PY' +import json +d = json.load(open('catalog.json')) +print("总数:", d['total'], "| 分布:", d['counts']) +bad = [(x['name'], x['description_len']) for x in d['skills'] + if x['description_len'] < 60 or x['description_len'] > 600] +print("description 长度异常:", bad if bad else "无") +cov = d.get('coverage', {}) +print(f"覆盖率: evals {cov.get('with_evals')}/{cov.get('required')},文档 {cov.get('with_docs')}/{cov.get('required')}") +PY diff --git a/skills-dev/diagnosing-bugs-plugin/.claude-plugin/plugin.json b/skills-dev/diagnosing-bugs-plugin/.claude-plugin/plugin.json new file mode 100644 index 0000000..e457aa1 --- /dev/null +++ b/skills-dev/diagnosing-bugs-plugin/.claude-plugin/plugin.json @@ -0,0 +1,11 @@ +{ + "name": "diagnosing-bugs-plugin", + "description": "难查 bug 的诊断纪律:先造出会变红的紧反馈循环,再二分定位、最小验证、补回归测试。", + "version": "0.1.0", + "author": { "name": "qiudl" }, + "install_name": "diagnosing-bugs", + "install_type": "skill", + "dir_category": "dev", + "status": "beta", + "invocation": "model-invoked" +} diff --git a/skills-dev/diagnosing-bugs-plugin/skills/SKILL.md b/skills-dev/diagnosing-bugs-plugin/skills/SKILL.md new file mode 100644 index 0000000..a9faac9 --- /dev/null +++ b/skills-dev/diagnosing-bugs-plugin/skills/SKILL.md @@ -0,0 +1,62 @@ +--- +name: diagnosing-bugs +description: 难查 bug 的诊断纪律:先造出一条「现在就为这个 bug 变红」的紧反馈循环,再二分定位、最小验证、补回归测试。当 bug 难复现、间歇失败、或第一次看没头绪时使用。 +metadata: + invocation: model-invoked + owner: qiudl +--- + +# 难查 bug 诊断 + +## 0. 一句话 + +**没有红循环就不推理**:先有一条几秒内能跑、且现在就为这个 bug 变红的命令,再开始猜。 + +## 1. 何时用 + +- 间歇性失败、偶发问题 +- 第一次看没头绪、日志线索不足 +- 已知两个好版本之间引入的回归 +- 别人修过几次没修好的 bug + +何时不用:一眼可见的拼写/配置错误、明确报错指向单行 → 直接修。 + +## 2. 铁律 + +1. **先复现**:能手动复现最好;不能就缩小到最小输入/最小步骤。 +2. **建红循环**:一条命令(测试/脚本/curl),现在跑必须是红的,且失败原因就是这个 bug。 +3. **一次只验一个假设**:改一个变量,跑一次,记录结果。 +4. **修完补回归测试**:确认测试在修复前是红的(临时回退验证一次)。 + +## 3. 步骤 + +1. 收集信息:报错、日志、复现步骤、最近改动(`git log`/`git bisect`)。 +2. 写最小复现:能稳定触发的最小输入或最小步骤。 +3. 建立反馈循环:命令固定、几秒内出结果、失败信息可读。 +4. 二分定位:git bisect / 输入二分 / 代码路径二分,把范围砍半。 +5. 假设 → 最小改动 → 跑循环验证;不做"顺手重构"。 +6. 回归测试:补一条覆盖该 bug 的测试,并证明它曾经红过。 +7. 记录根因与预防(进复盘或 memory)。 + +## 4. 反模式 + +- 没复现就开始改代码 +- 同时改多个地方,不知道哪个生效 +- 靠"看了日志觉得是缓存问题"直接改 +- 修完不补回归测试 +- 间歇失败归因于"环境问题"就收工 + +## 5. 验证清单 + +- [ ] 有一个现在为红的命令(不是偶发) +- [ ] 每次改动只变一个变量,并有结果记录 +- [ ] 修复后同一命令变绿 +- [ ] 回归测试存在,且回退修复后它会红 +- [ ] 根因已写清(不是"不知道,反正好了") + +## 6. 与其他技能 + +- 需要写测试规范 → `dev-test` +- 需要判断是不是设计缺陷 → `defect-analysis` +- 修复后要评审 → `dev-review` +- 任务状态与证据 → `ai-proj`(REQ 未 released 不算完成) diff --git a/skills-dev/diagnosing-bugs-plugin/skills/evals/evals.json b/skills-dev/diagnosing-bugs-plugin/skills/evals/evals.json new file mode 100644 index 0000000..7d7275e --- /dev/null +++ b/skills-dev/diagnosing-bugs-plugin/skills/evals/evals.json @@ -0,0 +1,27 @@ +{ + "skill_name": "diagnosing-bugs", + "skill_version": "0.1.0", + "evals": [ + { + "id": 1, + "kind": "happy_path", + "prompt": "这个接口偶尔返回 500,日志看不出原因,帮查一下", + "expected_output": "先要求/建立最小复现与一条现在为红的命令(测试或 curl 循环),说明偶发失败要先提高复现率,再二分定位;不在没有红循环时直接给修复方案", + "files": [] + }, + { + "id": 2, + "kind": "edge_case", + "prompt": "我看日志就感觉是缓存没失效,直接把缓存清一下就好", + "expected_output": "不直接改:把假设变成可验证实验(一条能证伪的命令),先证明是缓存问题再改,并说明如何确认修复", + "files": [] + }, + { + "id": 3, + "kind": "failure_recovery", + "prompt": "试了几次复现不出来,算了先上线吧", + "expected_output": "拒绝盲上:改为加观测(日志/埋点)、提高复现率(输入二分/时序调整)、或用 git bisect 定位引入点;明确记录未复现风险", + "files": [] + } + ] +} -- 2.54.0