{"id":"7b784604-9319-4585-814f-8ec1dbca599d","entityType":"agent","slug":"clawhub-huiyonghkw-hekouwang-claude-skill-doctor-skill","name":"hekouwang-claude-skill-doctor-skill","canonicalUrl":"https://www.xpersona.co/agent/clawhub-huiyonghkw-hekouwang-claude-skill-doctor-skill","canonicalPath":"/agent/clawhub-huiyonghkw-hekouwang-claude-skill-doctor-skill","generatedAt":"2026-10-10T11:00:24.180Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T06:26:12.987Z","emptyReason":null},"description":"会勇禾口王的AI笔记 · Agent Skill（SKILL.md）体检器。检查一个 Claude/Agent Skill 是否 符合\"按需加载的指令包，不是单文件巨石\"的最佳实践——评 description 触发质量、SKILL.md 篇幅、渐进披露（references/ 拆分）、脚本外置、可移植性（无硬编码绝对路径）、安全（无硬编码 密钥、宿主元数据与多 Skill 发现冲突），给出评分卡 + 按优先级的修复建议，并可代为重构。触发：用户说「检查我的 skill / SKILL.md 体检 / 这个 skill 规范吗 / claude-skill-doctor / audit skill / lint SKILL.md / 我的 skill 太长了 / skill 拆分 / 看看我的 skill 合不合规 / skill 对齐官方规范」。 任何\"评估/审查/优化某个 Agent Skill 质量或结构\"的请求都应触发。","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.6K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s17639bexg8w6nymygatvtx99585dbjd:hekouwang-claude-skill-doctor-skill","sourceUrl":"https://clawhub.ai/huiyonghkw/hekouwang-claude-skill-doctor-skill","homepage":"https://clawhub.ai/huiyonghkw/skills/hekouwang-claude-skill-doctor-skill","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/huiyonghkw/hekouwang-claude-skill-doctor-skill","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/huiyonghkw/skills/hekouwang-claude-skill-doctor-skill","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":64,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"hekouwang-claude-skill-doctor-skill technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T06:26:12.987Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T06:26:12.987Z","emptyReason":null},"stars":null,"forks":null,"downloads":1621,"packageName":null,"latestVersion":"1.8.0","tractionLabel":"1.6K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T06:26:12.987Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T06:26:12.987Z","lastCrawledAt":"2026-10-10T06:26:12.987Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T06:26:12.987Z","lastVerifiedAt":null,"highlights":[{"version":"1.8.0","createdAt":"2026-08-30T08:25:52.385Z","changelog":"新增可选 --profile codex：零依赖校验 Codex 基础 frontmatter、name、description 与 TODO；默认 agent Profile 保持跨宿主兼容，报告 schema 升至 v3。","fileCount":20,"zipByteSize":70599},{"version":"1.5.2","createdAt":"2026-08-12T11:37:00.717Z","changelog":"ClawHub category: development","fileCount":15,"zipByteSize":52821},{"version":"1.5.1","createdAt":"2026-08-12T08:02:41.980Z","changelog":"doctor-suite + README freemium","fileCount":15,"zipByteSize":52826},{"version":"1.5.0","createdAt":"2026-08-12T06:59:01.457Z","changelog":"Version 1.5.0 - Enhanced documentation in SKILL.md: expanded workflow and scoring standards, clarified optional security and trigger tests, and added detailed usage and FAQ guidance. - Updated key evaluation criteria around references, dead-link detection, and file structure. - Improved clarity on the free vs. paid features boundary. - Refined language and structure throughout to improve usability and reduce ambiguity. - Removed obsolete skill-card.md file.","fileCount":13,"zipByteSize":49891},{"version":"1.4.1","createdAt":"2026-08-01T02:53:08.462Z","changelog":"修 #0 安全红线两处假阳性：sk- 正则补左词界（消 ask-user-format 误报）；测试夹具里的假密钥降级 WARN。A/B 三类样本 FAIL/WARN/PASS 可分。","fileCount":13,"zipByteSize":48821},{"version":"1.4.0","createdAt":"2026-07-28T07:11:28.994Z","changelog":"新增触发力实测引擎 trigger_eval.py：把 description 装成临时探针 skill 真跑一遍，输出触发力分数 + 漏触发/误触发计数。check.py 保持零依赖不变，实测是可选叠加档。","fileCount":13,"zipByteSize":47731},{"version":"1.3.0","createdAt":"2026-07-15T15:18:35.222Z","changelog":"更正发布事故：本 slug 的 1.2.2 曾被误发成 md-doctor（CLAUDE.md 体检器）的内容，已删除。本版是首个真正上架的 Agent Skill（SKILL.md）体检器。 内容更新（原定 1.2.0）：拿真数据校准步骤 2b 的 SkillSpector 深度安全扫描——全量扫 7 个自研 skill、逐条翻源码核实，结论：对自研 skill 它 100% 误报，且分数完全不可信（三个 skill 判 100/100 CRITICAL·DO NOT INSTALL 但一条 CRITICAL 发现都没有，纯属累加撞顶）。2b 收紧为「只对外来 skill 跑的入库审查」，新增高置信度误报样本表、rsync exclude 顺序坑、SOCKS 代理绕法、baseline 正确用法。","fileCount":11,"zipByteSize":33495},{"version":"1.0.3","createdAt":"2026-06-24T14:12:28.206Z","changelog":"hekouwang-claude-skill-doctor-skill v1.0.2 - 新增 references/skill-writing-vocab.md，沉淀高质量 skill 判据词汇，辅助定性诊断和报告输出。 - 增补评分标准 #8：「触发方式匹配」——明确手动触发的 skill 应设 disable-model-invocation: true，避免多余 context 占用，并在说明和定性流程处扩写相关判据。 - 提示定性复核需借助 vocab 文件，出报告时引用具体失败模式/标准化用语，提高诊断精度。 - 强化安全检查流程（2b步）：推荐如需深度安全扫描，叠加 SkillSpector 工具并附运行指南。 - 移除 skill-card.md，不再保留冗余元信息文件。","fileCount":11,"zipByteSize":29547}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s17639bexg8w6nymygatvtx99585dbjd:hekouwang-claude-skill-doctor-skill","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s17639bexg8w6nymygatvtx99585dbjd:hekouwang-claude-skill-doctor-skill` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/huiyonghkw/hekouwang-claude-skill-doctor-skill before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-huiyonghkw-hekouwang-claude-skill-doctor-skill/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-huiyonghkw-hekouwang-claude-skill-doctor-skill/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-huiyonghkw-hekouwang-claude-skill-doctor-skill/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-huiyonghkw-hekouwang-claude-skill-doctor-skill/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-huiyonghkw-hekouwang-claude-skill-doctor-skill/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-huiyonghkw-hekouwang-claude-skill-doctor-skill/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T11:00:24.176Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-huiyonghkw-hekouwang-claude-skill-doctor-skill/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-huiyonghkw-hekouwang-claude-skill-doctor-skill/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-huiyonghkw-hekouwang-claude-skill-doctor-skill/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-huiyonghkw-hekouwang-claude-skill-doctor-skill/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T06:26:12.987Z","emptyReason":null},"readme":"Skill: hekouwang-claude-skill-doctor-skill\n\nOwner: huiyonghkw\n\nSummary: 会勇禾口王的AI笔记 · Agent Skill（SKILL.md）体检器。检查一个 Claude/Agent Skill 是否 符合\"按需加载的指令包，不是单文件巨石\"的最佳实践——评 description 触发质量、SKILL.md 篇幅、渐进披露（references/ 拆分）、脚本外置、可移植性（无硬编码绝对路径）、安全（无硬编码 密钥、宿主元数据与多 Skill 发现冲突），给出评分卡 + 按优先级的修复建议，并可代为重构。触发：用户说「检查我的 skill / SKILL.md 体检 / 这个 skill 规范吗 / claude-skill-doctor / audit skill / lint SKILL.md / 我的 skill 太长了 / skill 拆分 / 看看我的 skill 合不合规 / skill 对齐官方规范」。 任何\"评估/审查/优化某个 Agent Skill 质量或结构\"的请求都应触发。\n\nTags: latest:1.8.0\n\nVersion history:\n\nv1.8.0 | 2026-08-30T08:25:52.385Z | user\n\n新增可选 --profile codex：零依赖校验 Codex 基础 frontmatter、name、description 与 TODO；默认 agent Profile 保持跨宿主兼容，报告 schema 升至 v3。\n\nv1.5.2 | 2026-08-12T11:37:00.717Z | user\n\nClawHub category: development\n\nv1.5.1 | 2026-08-12T08:02:41.980Z | user\n\ndoctor-suite + README freemium\n\nv1.5.0 | 2026-08-12T06:59:01.457Z | auto\n\nVersion 1.5.0\n\n- Enhanced documentation in SKILL.md: expanded workflow and scoring standards, clarified optional security and trigger tests, and added detailed usage and FAQ guidance.\n- Updated key evaluation criteria around references, dead-link detection, and file structure.\n- Improved clarity on the free vs. paid features boundary.\n- Refined language and structure throughout to improve usability and reduce ambiguity.\n- Removed obsolete skill-card.md file.\n\nv1.4.1 | 2026-08-01T02:53:08.462Z | user\n\n修 #0 安全红线两处假阳性：sk- 正则补左词界（消 ask-user-format 误报）；测试夹具里的假密钥降级 WARN。A/B 三类样本 FAIL/WARN/PASS 可分。\n\nv1.4.0 | 2026-07-28T07:11:28.994Z | user\n\n新增触发力实测引擎 trigger_eval.py：把 description 装成临时探针 skill 真跑一遍，输出触发力分数 + 漏触发/误触发计数。check.py 保持零依赖不变，实测是可选叠加档。\n\nv1.3.0 | 2026-07-15T15:18:35.222Z | user\n\n更正发布事故：本 slug 的 1.2.2 曾被误发成 md-doctor（CLAUDE.md 体检器）的内容，已删除。本版是首个真正上架的 Agent Skill（SKILL.md）体检器。\n\n内容更新（原定 1.2.0）：拿真数据校准步骤 2b 的 SkillSpector 深度安全扫描——全量扫 7 个自研 skill、逐条翻源码核实，结论：对自研 skill 它 100% 误报，且分数完全不可信（三个 skill 判 100/100 CRITICAL·DO NOT INSTALL 但一条 CRITICAL 发现都没有，纯属累加撞顶）。2b 收紧为「只对外来 skill 跑的入库审查」，新增高置信度误报样本表、rsync exclude 顺序坑、SOCKS 代理绕法、baseline 正确用法。\n\nv1.0.3 | 2026-06-24T14:12:28.206Z | user\n\nhekouwang-claude-skill-doctor-skill v1.0.2\n\n- 新增 references/skill-writing-vocab.md，沉淀高质量 skill 判据词汇，辅助定性诊断和报告输出。  \n- 增补评分标准 #8：「触发方式匹配」——明确手动触发的 skill 应设 disable-model-invocation: true，避免多余 context 占用，并在说明和定性流程处扩写相关判据。\n- 提示定性复核需借助 vocab 文件，出报告时引用具体失败模式/标准化用语，提高诊断精度。\n- 强化安全检查流程（2b步）：推荐如需深度安全扫描，叠加 SkillSpector 工具并附运行指南。\n- 移除 skill-card.md，不再保留冗余元信息文件。\n\nv1.0.2 | 2026-06-24T14:12:08.171Z | user\n\nhekouwang-claude-skill-doctor-skill v1.0.2\n\n- 新增 references/skill-writing-vocab.md，沉淀高质量 skill 判据词汇，辅助定性诊断和报告输出。  \n- 增补评分标准 #8：「触发方式匹配」——明确手动触发的 skill 应设 disable-model-invocation: true，避免多余 context 占用，并在说明和定性流程处扩写相关判据。\n- 提示定性复核需借助 vocab 文件，出报告时引用具体失败模式/标准化用语，提高诊断精度。\n- 强化安全检查流程（2b步）：推荐如需深度安全扫描，叠加 SkillSpector 工具并附运行指南。\n- 移除 skill-card.md，不再保留冗余元信息文件。\n\nv1.0.1 | 2026-06-22T07:14:56.132Z | user\n\n实战体检三个品牌 skill 时暴露的机检缺陷修复（dogfooding）：\n\nFixed\n#7 allowed-tools 兼容逗号字符串：原先只认 YAML 列表（- a / [a,b]）， 把官方 frontmatter 标准的逗号字符串写法（allowed-tools: Bash, Read, Write） 误判为「未声明」。现在两种写法都解析、非空即 PASS。\n\nv1.0.0 | 2026-06-22T04:41:26.456Z | auto\n\nInitial release of hekouwang-claude-skill-doctor-skill: an Agent Skill quality and structure checker for Claude/Agent Skills.\n\n- Checks SKILL.md for best practices: description trigger quality, concise length, progressive disclosure (references/), externalized scripts, portability (no hardcoded absolute paths), and security (no hardcoded secrets).\n- Generates a report card with prioritized fix suggestions.\n- Can perform automated restructuring actions with user approval.\n- Free/open-source core: text/JSON reports and scoring.\n- Paid add-on: branded visual report cards via @huiyonghkw.\n\nArchive index:\n\nArchive v1.8.0: 20 files, 70599 bytes\n\nFiles: CHANGELOG.md (16295b), check.py (58562b), Dockerfile (804b), LICENSE (1096b), README.md (6013b), references/doctor-suite.md (1996b), references/skill-writing-vocab.md (4701b), references/trigger-eval.md (7753b), scripts/run-all-doctors.sh (4946b), scripts/trigger_eval.py (16245b), skill-card.md (2841b), SKILL.md (22667b), tests/fixtures/bad/SKILL.md (379b), tests/fixtures/good/SKILL.md (802b), tests/test-codex-profile.sh (2610b), tests/test-dead-pointer.sh (2653b), tests/test-frontmatter.sh (4056b), tests/test-scan.sh (1494b), tests/test-suite-fail-closed.sh (2319b), _meta.json (154b)\n\nFile v1.8.0:SKILL.md\n\n---\nname: hekouwang-claude-skill-doctor-skill\nslug: hekouwang-claude-skill-doctor-skill\ndisplayName: Claude Skill 体检器（SKILL.md Doctor）\nsummary: Agent Skill lint / SKILL.md doctor / skillspec audit — description 触发、渐进披露、可移植性与 OpenClaw 兼容检查。姊妹工具 md-doctor。\nlicense: MIT-0\nhomepage: https://github.com/huiyonghkw/hekouwang-claude-skill-doctor-skill\nversion: 1.8.0\ndescription: >\n  会勇禾口王的AI笔记 · Agent Skill（SKILL.md）体检器。检查一个 Claude/Agent Skill 是否\n  符合\"按需加载的指令包，不是单文件巨石\"的最佳实践——评 description 触发质量、SKILL.md\n  篇幅、渐进披露（references/ 拆分）、脚本外置、可移植性（无硬编码绝对路径）、安全（无硬编码\n  密钥、宿主元数据与多 Skill 发现冲突），给出评分卡 + 按优先级的修复建议，并可代为重构。触发：用户说「检查我的 skill /\n  SKILL.md 体检 / 这个 skill 规范吗 / claude-skill-doctor / audit skill / lint SKILL.md /\n  我的 skill 太长了 / skill 拆分 / 看看我的 skill 合不合规 / skill 对齐官方规范」。\n  任何\"评估/审查/优化某个 Agent Skill 质量或结构\"的请求都应触发。\n---\n\n# hekouwang-claude-skill-doctor-skill · Agent Skill 体检器\n\n> **会勇禾口王的AI笔记** 出品 · `@huiyonghkw`\n> _不聊 AI 会不会取代你，只聊先用 AI 的人怎么取代你。_\n\n把\"Agent Skill 最佳实践\"做成一个能跑在任何 skill 上的检查器：机检定量 + 模型定性，\n产出评分卡和可落地的修复建议。核心判据一句话——\n\n> **SKILL.md 是模型\"决定要不要加载、加载后照着做\"的运行时指令包。`description` 决定它何时被唤醒；正文越精简越准；厚重细节要能\"按需展开\"（references/ 用到再读），而不是每次触发就把全部细节灌进上下文。**\n> 一切检查项都从这句推导：这段内容值不值得在 skill 每次触发时都付一次上下文费？能不能下沉到 references/ 用到再读？\n\n### 触发优先 + 减法优先（元判据 · 凌驾全部检查项之上）\n\nSkill 的命脉是两条，权重最高：\n\n1. **触发**：`description` 是模型唯一用来判断\"何时唤醒本 skill\"的信号。写不清\"何时用\"，再好的正文也永远不被加载。\n2. **减法**：SKILL.md 不是图书馆。模型每代都在变强——你塞进正文的通用写法、框架教程、临时脚本，很快既过时又白占 token。**能下沉 references/ 的下沉，能外置 scripts/ 的外置，模型已经会的删掉。**\n\n所以机检里 **#2 触发 / #3 篇幅 / #4 渐进披露 / #6 可移植 / #10 别替模型补** 权重 1.5；\n\"加内容\"类项（#7 最小工具集、#10 配套文档）缺失只算小扣分——别一边喊\"越精简越好\"、一边逼作者把 skill 做臃肿。\n\n## 品牌人设（体检报告的口吻 + 署名）\n\n属于 **会勇禾口王的AI笔记**（定位：AI 实战拆解，硬核·具体·可复制；人设：你办公室里第一个把 AI 用明白的同事）。出体检报告时：\n\n- **口吻**：像同事帮你看代码——直给结论、敢泼冷水（\"这 description 只写了做什么、不写何时用，等于永远不被触发\"），不说客套话。\n- **价值化**：修复建议讲\"省了什么\"（每次触发少灌 100KB 冗余、别人装上不报错、该用时真能被唤醒），不堆术语。\n- **署名**：报告结尾固定带 `—— 会勇禾口王的AI笔记 · @huiyonghkw`。命令行 `check.py` 的报告页脚已内置该署名。\n- **去 AI 味**：定稿前避开\"赋能/打造/至关重要/助力\"等词，说人话。\n\n---\n\n## 免费 / 付费边界（重要）\n\n- **免费（开源内核）**：`check.py` 的**文本 / JSON 报告 + 评分**。任何人本地或进 CI 随便跑。\n- **免费但要自付 API 钱**：`scripts/trigger_eval.py` 触发力实测（工作流 2c）。脚本本身开源随便用，\n  但它每条 query 都真调一次 `claude -p`（约 $0.09–0.15/次），**钱花在用户自己的额度上**。\n  所以它是**可选叠加档、不进默认流程**——`check.py` 的零依赖卖点不受影响，不跑也能出完整体检报告。\n- **付费（增值）**：**品牌可视化体检报告卡**（评分弧 + 等级带 + 明细分享图），依赖 `hekouwang-content-factory` 的私有品牌字体与版式，不随本仓库分发。\n- 一句话口径：**跑检查免费，出\"好看的报告图\"找 @huiyonghkw。** 外部用户要图时说明是付费增值项，别用系统字体凑一张劣化图糊弄。\n\n---\n\n## 工作流（每次体检按这个顺序）\n\n1. **确认目标**：用户没指明就用当前目录；说了某个 skill 就用那个 skill 目录的绝对路径（目录里要有 `SKILL.md`）。若传进来是 `~/.claude/skills/` 这种父目录，脚本会提示里面有哪些 skill，逐个体检。\n2. **跑机检**（确定性层，零依赖）：\n   ```bash\n   python3 <此skill目录>/check.py <skill目录>\n   ```\n   - 需要结构化结果时加 `--json`。退出码：有 FAIL → 1，否则 0。\n   - 默认 Profile 是跨宿主的 `agent`；要按 Codex `skill-creator` 的严格基础契约验收时，加\n     `--profile codex`。它只允许 `name`、`description`、`license`、`allowed-tools`、`metadata`，\n     并阻断不合规 name、description 尖括号和正文未完成 TODO；不适用于带 Claude/宿主扩展字段的 Skill。\n   - 需要盘点一个宿主目录或仓库里的全部 Skill 时运行：\n     `python3 <此skill目录>/check.py --scan <skill根目录> --json`；同样可附 `--profile codex`。\n     主机只看根目录直接入口时加 `--direct`；默认递归模式会跳过测试夹具和构建目录。\n     扫描会识别隐藏宿主目录、断开的软链、真实入口去重和重复 name；JSON 的 `gate` 才是门禁真值，不能只看 score/grade。\n2b. **深度安全扫描（可选 · 外部工具 SkillSpector）**：`check.py` 的 #0 只做密钥正则；当要查**提示注入 / 数据外泄 / 隐藏指令 / 供应链 / 过度授权 / MCP 越权**等 68 类模式时，叠加跑 [SkillSpector](https://github.com/NVIDIA/skillspector)（本机已装：`uv tool install`，需 Python 3.12/3.13）：\n   ```bash\n   env -u ALL_PROXY -u all_proxy -u HTTPS_PROXY -u https_proxy \\\n     skillspector scan <纯逻辑副本> --no-llm --format markdown -o report.md\n   ```\n   - **只对\"别人写的、要装进来的\" skill 跑。** 自研 skill 扫出来的实测是 100% 误报（2026-07-15 全量验证 7 个 hekouwang-* skill，逐条翻源码，无一为真），跑了只会浪费时间。\n   - **自研 skill 只做回归检测。** content-factory / yandu-deck / stock-data-reader 三个（会持续改的）已各存一份归零基线在自己目录的 `.skillspector-baseline.yaml`，改完代码后：\n     ```bash\n     skillspector scan <纯逻辑副本> --no-llm --baseline <skill目录>/.skillspector-baseline.yaml\n     ```\n     **冒出来的任何一条都是新的**，值得真翻一眼源码；`--show-suppressed` 看压了什么。基线里的 13/8/4 条已核实为误报（2026-07-15 A/B 验证：yandu-deck `100 CRITICAL DO_NOT_INSTALL` → `0 LOW SAFE`）。改动大到路径/内容 hash 全变时重新 `skillspector baseline <副本> -o …` 存一版。\n   - **分数不是门禁，只看条目。** `Score/Severity` 是**逐条累加**出来的：yandu-deck/iterm2/cc-prod 三个都判 `100/100 CRITICAL · DO NOT INSTALL`，但报告里**一条 CRITICAL 发现都没有**——纯粹是十几条 MEDIUM/HIGH 累加撞顶。且评分随版本通胀：content-factory 代码一行没改，v2.3.5 是 `19/100 SAFE`，v2.3.13 变 `40/100 CAUTION`。**永远读条目、翻源码，别信总评。**\n   - **铁律：只扫逻辑文件，别扫 assets。** 直接扫会把字体 `.woff2`、PNG 等**二进制当代码**，在字节流里刷出几十条假 `TM1 Tool Parameter Abuse`。先用 rsync 拷纯逻辑副本（只留 `.md/.py/.js/.json/.html/.css/.sh/.txt/.yaml`）。⚠️ **`--exclude` 必须写在 `--include='*/'` 前面**（rsync 首次匹配生效，否则 `*/` 先吃掉 `.venv/`，把整个 site-packages 当你的代码扫）：\n     ```bash\n     rsync -a --prune-empty-dirs \\\n       --exclude='.venv/' --exclude='node_modules/' --exclude='.git/' --exclude='__pycache__/' \\\n       --include='*/' --include='*.md' --include='*.py' --include='*.js' --include='*.json' \\\n       --include='*.html' --include='*.css' --include='*.sh' --include='*.txt' --include='*.yaml' \\\n       --exclude='*' <skill目录>/ <副本>/\n     ```\n     实测 content-factory 141M→1.1M、stock-data-reader 264M→176K。\n   - **已知高置信度误报样本**（别被 90%+ 唬住，这些全部核实为假）：`rm -f \"$写死的路径\"` → `TM1 Tool Parameter Abuse` 95%；`subprocess.run([...], check=True)` 硬编码列表 → `OH1 Unvalidated Output Injection` 95% + `AST4`（它建议的 remediation 恰恰就是这个写法）；docstring 里写\"本脚本**绝不读取** .env/*.key\" → `PE3 Credential Access`；字体文件名列表 → `MP2 Context Window Stuffing`；中文 frontmatter → `P2 Hidden Instructions`（置信度 21%，全在 `:1`）；中文触发词 → `AS3 Mixed script`。\n   - **`--baseline` 的 glob `rules` 别乱开。** `rules: {id: \"TM1\"}` 能跨 skill 全局压制，但**扫外来 skill 时恰恰不能用**——今天 TM1 在自研 `rm` 上是误报，在恶意 skill 里可能是真的，全局关掉等于拆探头。跨 skill 只压 `path`+`message` 都限定死的具体条目。\n   - **代理会让扫描直接崩**：SOCKS 代理下报 `Using SOCKS proxy, but the 'socksio' package is not installed`（同 `词级字幕.py` 那个坑），用上面的 `env -u` 绕开。OSV.dev 连不上只是降级到静态库，不影响结论。\n   - 唯一值得看的结构性信号是 **LP1「代码有 network/env/shell 能力但没声明权限」**（7 个自研 skill 中 5 个命中）——不是漏洞，是提醒你 frontmatter 可以补 `allowed-tools`。\n   - `--no-llm` 纯静态、免 key；要更准的行为分析再配 LLM provider（`SKILLSPECTOR_PROVIDER` + 对应 key）。结论并进体检报告的安全维，不替代 #0。\n2c. **触发力实测（可选 · 要花钱 · 只在怀疑 description 时跑）**：机检 #2 只能看出有没有信号词，\n   **判不了写得准不准**——那是本 skill 最大的盲区，因为 description 写不准 = 这个 skill 永远不被唤醒，\n   正文写得再好也白搭。要判准不准就得真跑一遍：\n   ```bash\n   python3 <此skill目录>/scripts/trigger_eval.py \\\n     --eval-set <你的query集>.json --skill-path <skill目录>\n   ```\n   把待测 description 装成临时探针 skill，跑 `claude -p` 看模型会不会去调它。跑完即删，不碰已装的 skill。\n   - ⭐ **先做基准分辨力自检再信分数**：拿真 description 和一段故意写烂的（\"生成内容。\"）\n     跑同一套 query，**分数分不开就说明判据在当前环境失灵**，此时高分也是噪音。\n     实测参考 A=100 / B=50。开发这个脚本时四处配置错误里有三处都表现为\"跑通了、只是分数低\"——\n     不做 A/B 根本发现不了。\n   - **读结果分两种失败**：漏触发＝覆盖不够（补场景句和同义说法）；误触发＝写太宽泛（加边界、换具体动作）。\n     两种都有＝抓错维度，重写而非打补丁。\n   - ⚠️ **要钱**：每条 query 每次采样约 $0.09–0.15，20 条 ×3 次约 $6–9。先用 4–6 条粗筛。\n   - query 怎么设计（尤其**负例必须是 near-miss**）、结果不对劲怎么翻原始流、脚本那四处\n     不能改回去的坑 → 读 [`references/trigger-eval.md`](references/trigger-eval.md)。\n   - **`check.py` 不依赖它**，零依赖那条卖点不受影响；这一档是叠加的，不跑也能出完整体检报告。\n\n3. **定性复核**（机检之上，必须做）：机检是启发式，几项要你**真正读 SKILL.md**再下结论（见下「机检的盲区」）：\n   - 通读 `description`，**真的当一次模型**：光看这段，能不能判断\"什么请求该唤醒它\"？\n   - 通读正文：哪些是\"模型不可能知道的项目/品牌私有事实\"（该留），哪些是\"通用写法/框架教程\"（该删或下沉）？\n   - 若正文很长，看它能不能按\"版本/平台/流程\"天然切成 references/。\n4. **出报告**：先一句话总评 + 分数档位，再用\"✓/▲/✗ + 一句话 + 修复建议\"逐条列，最后给 **Top 3 最该先改的**（按\"花最小力气补最大漏洞\"排序）。中文输出。\n5. **提出代重构**：问用户要不要直接改（瘦身 SKILL.md、拆 references/、外置 scripts/、把硬路径换成 `~`/相对路径、补 description 触发句）。**得到同意再动文件**，一次改一类、可回退；改完**重跑 `check.py`** 给前后对比分数。\n\n> 不要只把脚本输出原样贴给用户——脚本是线索，你的价值在定性判断 + 具体怎么拆。\n\n---\n\n## 评分标准（核心维度 + 宿主兼容门禁）\n\n| # | 检查项 | 合格长什么样 | 不合格信号 |\n|---|--------|------------|-----------|\n| 0 | **无硬编码密钥（安全红线）** | SKILL.md 及捆绑文件无 key/token/私钥/口令明文 | 出现 `sk-`/`AKIA`/私钥块/`password=\"...\"` → **直接 FAIL**（skill 常被分发，泄露面更大）<br>⚠️ 测试夹具目录（`test/ tests/ fixtures/ golden/ snapshots/`）里的命中判 **WARN 不判 FAIL**——安全基准的假密钥是刻意载荷，误报会把红线变成摆设 |\n| 1 | **frontmatter 必填合法** | 有 `name`（小写+连字符 ≤64）+ `description` | 缺 name/description → FAIL；name 含大写/下划线/空格 → WARN |\n| 1b | **Codex 基础契约（可选）** | `--profile codex` 下字段白名单、name、description 与 TODO 均合规 | 扩展字段、连续连字符、description 尖括号或正文未完成 TODO → FAIL；默认 `agent` Profile 不启用，避免误伤跨宿主 Skill |\n| 2 | **description 含「何时用」** | 同时写清\"做什么 + 何时/触发用\"（这是被唤醒的唯一依据） | 只写\"做什么\"不写\"何时用\"；或太短没触发信号<br>⚠️ 机检只判\"有没有信号词\"，判不了准不准 —— 要判准不准走**触发力实测**（工作流 2c） |\n| 2b | **description ≤ 1024 字符** | 在上限内，触发稳定 | 超长，可能被截断 |\n| 3 | **SKILL.md ≤ 500 行** | 路由器不是图书馆，按需加载越短越准 | >500 行；分版本/分平台/长流程全塞一个文件 |\n| 4 | **渐进披露（拆 references/）** | 长内容下沉独立 .md，正文留指针 | 正文很长却没有任何 references 拆分文件 |\n| 4b | **指针无死链** | 引用的 `references/*.md` 等带扩展名的捆绑资源真实存在 | 指针指向不存在的文件 → **直接 FAIL**（是确定性事实不是风格建议；漏提交的文件不在 push 快照里，只扣分就拦不住）<br>正反例：`bash tests/test-dead-pointer.sh` |\n| 5 | **脚本外置 scripts/** | 确定性代码（构建/截图/合成/转换）是 scripts/ 真文件 | 大段可执行代码内联在正文，每次靠模型重打 |\n| 6 | **可移植（无硬编码绝对路径）** | 用 `~`/`$HOME`/相对路径/占位 | 出现硬编码家目录绝对路径——别人装上即失效 |\n| 7 | **allowed-tools 最小化** | 声明本 skill 真正需要的工具 | 不声明（继承全部工具，越权面大）——可选项，低权重 |\n| 8 | **触发方式匹配（model vs user invoked）** | 只靠人手敲名字触发的 skill 设 `disable-model-invocation: true`（零 context load） | 明明只手动触发，却留着 description 当 model-invoked，每轮白占上下文（详见 references/skill-writing-vocab.md 第二节）——定性项 |\n| 8b | **文本文件可读取** | 纳入扫描的文本文件能读取；密钥文件按红线规则跳过 | 读取失败不能静默当成“没有问题”——直接 FAIL |\n| 8c | **Skill 身份可辨认** | 目录名和 frontmatter name 对齐，或明确是宿主软链别名 | 多入口重名/别名未说明时，扫描报告会提示 |\n| 10a | **别替模型补它已经会的（no-op 测试）** | 只装项目/品牌私有事实 | 有\"语言入门/框架教程/如何使用\"这类教学段——判据：**这段相对模型默认行为改变了什么？没有就删**（即 no-op；详见 vocab 第六节） |\n| 10b | **配套文档（README+CHANGELOG）** | 对外分发友好 | 缺失——纯自用可忽略，低权重 |\n| 11 | **paths / globs 作用域** | 文件专属 skill 声明 glob，减少误触发 | Cursor 2.4+ 可用；未声明 = INFO |\n| 12 | **OpenClaw 兼容声明** | 有 scripts/ 或发 ClawHub 时声明 requires/install | 纯指令 skill 可忽略——INFO |\n\n**分档**：A 优秀 ≥85 · B 良好 ≥70 · C 及格 ≥50 · D 建议重构 <50。\n（机检：PASS=1 / WARN=0.5 / FAIL=0，INFO 不计分。**按重要度加权**——安全红线 #0 与触发/减法核心项 #1/#2/#3/#4/#6/#10a 权重 1.5，标准项 #2b/#4b/#5/#11 为 1.0，加内容项 #7/#10b/#12 为 0.6。#0 命中按 FAIL 计且资损级，定性总评里应一票顶到「先改这条」。）\n\n**门禁口径**：score/grade 是质量参考，`gate` 才是自动化是否放行的真值。\n任何 FAIL、frontmatter 解析错误、文本读取错误都会让 gate=FAIL；启用 `--profile codex` 时，\nCodex 基础契约同样纳入门禁；多 Skill `--scan`\n还会把断链、遍历错误和重复 name 纳入全局门禁。外部软链是否计入项目门禁，由调用方明确声明。\n\n---\n\n## 机检的盲区（定性复核时重点纠偏）\n\n脚本只判\"机器能确定的\"，以下几项**容易误判，必须你读正文定夺**：\n\n- **#2 触发质量**：脚本只看 description 里有没有\"当…时/use when\"等信号词，**判不了写得准不准**。你要真的当模型读一遍：这段能不能把本 skill 和别的 skill 区分开？会不会该触发时没触发、不该触发时乱触发？\n  - ⭐ **这条现在能实测，别停在拍脑袋**：走工作流 2c 的 `scripts/trigger_eval.py`，\n    \"会不会该触发时没触发、不该触发时乱触发\"正好对应输出里的**漏触发 / 误触发**两个计数。\n    定性读完有怀疑、或者这个 skill 值得下功夫（常用、要分发、要收费），就跑一轮实测坐实。\n    ⚠️ 但**跑之前先做 A/B 基准自检**（真 description vs 一段写烂的），分不开就别信分数。\n- **#3/#4 篇幅 vs 图书馆**：长不一定错——有的 skill 天生信息密度高。但\"分 3 个视觉版本 × 6 个平台\"这种，多半能按维度拆 references/。读结构判断哪些章节是\"用到才看\"的。\n- **#5 脚本外置**：脚本按代码行数/围栏数猜。一段 5 行的示范片段该留正文；一个 80 行的构建/合成脚本该外置。读代码块的\"性质\"定夺。\n- **#10a 别替模型补它已经会的**：脚本按\"教程/如何使用/语言入门\"措辞猜，**会误伤**——比如正文在写\"本项目**自研**流程的用法\"（模型确实不知道，该留），或在\"反对写教程\"。判据是\"这段知识模型升级后会不会自动变强\"：会→删；不会（项目私有）→留。\n- **本 skill 自检会触发 #10a 误报**：因为正文里就列着\"教程/如何使用\"这些**待检测的黑名单词**——这是元层面的正常现象，定性时直接放行。\n\n> **定性诊断词汇**：做 #2/#3/#4/#8/#10a 这些\"机器判不准\"的项时，读 [`references/skill-writing-vocab.md`](references/skill-writing-vocab.md)——它把\"好 skill\"的判据沉淀成可命名的语言（两种载荷、信息阶梯、branch 拆分测试、完成判据防提前收工、no-op 测试、sediment/sprawl/duplication 失败模式、leading word）。出报告时用这些词点破问题，比泛说\"太长/有冗余\"更准。根判据：**skill 是为榨出确定性而存在，根本美德是「每次走同一套过程」可预测。**\n\n---\n\n## 安全红线（务必遵守）\n\n- **绝不读取密钥文件**：`.env` / `*.key` / `*.pem` / `*secret*` 一律不打开（脚本本身也不读）。\n- 体检是只读操作；**任何文件改动都要先说明改哪些、为什么，得到同意再动**。\n- 跨语言/跨用途通用——本 skill 不绑定任何具体技术栈或 skill 类型。\n\n---\n\n## 修复动作清单（用户同意后按需执行）\n\n- **拔密钥（最高优先）**：#0 命中时把明文移出 SKILL.md / 捆绑文件，改放 `.env` / 密钥管理器；命中即视为已泄露，提醒轮换并查 git 历史（skill 很可能已 push 到 GitHub）。\n- **修触发**：#2 不合格时给 description 补\"何时用\"句——列典型请求 / 触发词 / 适用场景，让模型判得出何时唤醒。\n- **瘦身 + 拆 references/**：#3/#4 不合格时，把 SKILL.md 按「版本/平台/流程」维度抽到 `references/` 下的独立 `.md`，正文回归「精简路由 + 硬规矩 + 索引表」。\n- **外置 scripts/**：#5 命中时把确定性脚本抠成 `scripts/` 真文件，正文只留一行调用说明。\n- **去硬路径**：#6 命中时把硬编码家目录路径换成 `~` / `$HOME` / 相对路径 / 「此 skill 目录」占位。\n- **删教学冗余**：#10a 确认是\"教通用写法/框架用法\"的删掉——skill 只装模型不可能知道的私有事实。\n- **修死链**：#4b 报的死指针——补上缺失文件，或修正/删除指针。\n- 改完**重新跑一次 `check.py`** 给前后对比分数。\n\n---\n\n## 落地骨架（建/重写一个 skill 时的推荐结构）\n\n```\nmy-skill/\n├── SKILL.md              # ≤500 行：frontmatter(name+description触发句) + 元判据 + 硬规矩\n│                         #          + 一张「做 X → 读 references/Y」索引表（路由，不堆细节）\n├── references/           # 渐进披露：按版本/平台/流程拆的专题 .md，用到再读\n│   ├── topic-a.md\n│   └── topic-b.md\n├── scripts/              # 确定性可执行脚本（构建/截图/合成/转换），正文只留指针\n├── assets/               # 字体/图片/模板等捆绑资源\n├── README.md             # 给人看（分发用）\n└── CHANGELOG.md          # 版本记录\n```\n\n> SKILL.md 是路由，不是仓库。判据始终是：**这段值不值得每次触发都进上下文？能下沉就下沉。**\n\nFile v1.8.0:tests/fixtures/bad/SKILL.md\n\n---\nname: BadSkill_Example\n---\n\n# Bad Skill\n\n这是一个演示「不合格 skill」的夹具，故意踩坑：\n\n- name 用了大写 + 下划线（应 kebab-case）。\n- **缺 description**——模型无从判断何时加载本 skill（机检会判 FAIL，退出码 1）。\n- 硬编码了绝对路径 /Users/someone/.claude/skills/x/assets/font.woff2（换台机器就废）。\n\nFile v1.8.0:tests/fixtures/good/SKILL.md\n\n---\nname: example-good-skill\ndescription: >\n  生成示例日报。把一段原始数据整理成一页结构化的示例日报。\n  当需要演示「合格 skill 长什么样」或要一份 demo 日报时使用；\n  use when you need a demo daily report.\nallowed-tools:\n  - Read\n  - Write\n---\n\n# Example Good Skill\n\n一个用于演示「合格 skill」的最小夹具：frontmatter 完整、description 写清了\n做什么 + 何时用、正文精简、无硬编码密钥、无绝对路径。\n\n## 何时用\n\n当用户要一份示例日报，或想看一个达标 skill 的结构时。\n\n## 怎么做\n\n1. 读取用户给的原始数据。\n2. 按「概览 / 明细 / 结论」三段整理。\n3. 输出一页 Markdown 日报。\n\n> 正文只放本 skill 私有的约定；通用写法交给模型自己。\n\nFile v1.8.0:README.md\n\n# hekouwang-claude-skill-doctor-skill\n\n> **会勇禾口王的AI笔记** 出品 · `@huiyonghkw`\n> 不聊 AI 会不会取代你，只聊先用 AI 的人怎么取代你。\n\n给 **Agent Skill（SKILL.md）** 做体检的工具。把\"Skill 是按需加载的指令包、不是单文件巨石\"\n这条最佳实践，做成一个能跑在任何 skill 上的检查器：机检定量 + 模型定性，产出评分卡和可落地的修复建议。\n\n## 30 秒验收\n\n```bash\npython3 check.py path/to/your-skill    # 体检任意 skill 目录\nbash scripts/run-all-doctors.sh .      # 三件套（需已装 md-doctor + env-doctor）\n```\n\n姊妹工具：[`hekouwang-claude-md-doctor-skill`](https://github.com/huiyonghkw/hekouwang-claude-md-doctor-skill)（体检 AGENTS.md / CLAUDE.md）。\n\n## 核心判据\n\n> SKILL.md 是模型\"决定要不要加载、加载后照着做\"的运行时指令包。\n> `description` 决定它何时被唤醒；正文越精简越准；厚重细节要能\"按需展开\"\n> （references/ 用到再读），而不是每次触发就把全部细节灌进上下文。\n\n## 用法\n\n### 在 Claude Code 里（推荐）\n\n直接用**自然语言**喊它，Claude 会自动加载本 skill、在底层跑机检、再做定性复核，给评分卡 + 按优先级的修复建议，并问要不要代为重构：\n\n> - 「帮我体检 `~/.claude/skills/xxx` 这个 skill」\n> - 「我的 SKILL.md 规范吗 / 是不是太长了 / 要不要拆 references」\n> - 「audit this skill」「lint SKILL.md」\n\n### 命令行直接跑（零依赖，仅需 Python 3）\n\n```bash\npython3 check.py <skill目录>          # 输出彩色报告\npython3 check.py <skill目录> --json   # 机器可读 JSON（CI 可用）\npython3 check.py <skill目录> --profile codex  # 严格校验 Codex 基础契约\n```\n\n退出码：有 FAIL → 1，否则 0（可用于 CI 卡关）。\n\n### Codex 严格基础契约（可选）\n\n默认 `agent` Profile 服务于 Claude/Codex/其他宿主共用的 Skill：合法的 `slug`、`version` 等宿主扩展字段不会被误伤。\n如果你要按 Codex `skill-creator` 的基础规范验收一个纯 Codex Skill，附加 `--profile codex`：只允许\n`name`、`description`、`license`、`allowed-tools`、`metadata`，并把不合规 kebab-case、description\n中的尖括号和正文未完成的 `[TODO: ...]` 纳入 `gate`。报告 JSON 的 `profile` 字段会明确本次使用的档位。\n\n这是一层可选的严格契约，不取代 Doctor 原有的跨宿主质量、安全、指针和扫描检查。\n\n### 盘点多个 Skill\n\n当传入的是宿主 Skill 根目录或仓库父目录时，用扫描模式。主机目录通常只看直接入口：\n\n```bash\npython3 check.py --scan --direct ~/.claude/skills --json\npython3 check.py --scan /path/to/repository --json\npython3 check.py --scan /path/to/codex-skills --profile codex --json\n```\n\n默认递归扫描会跳过测试夹具和构建目录；direct 模式只检查根目录下一层的宿主入口。\n两种模式都会识别隐藏宿主目录、断开的软链、真实入口去重和重复 name。自动化应读取 JSON\n里的 gate 字段；score/grade 只是质量参考，不能替代门禁判断。\n\n### Docker（不想装 Python 也能跑）\n\n```bash\n# 拉官方镜像直接用（打 v* tag 时 GitHub Actions 自动发布到 GHCR）\ndocker run --rm -v \"$PWD:/work\" ghcr.io/huiyonghkw/hekouwang-claude-skill-doctor-skill\n\n# 或本地自建\ndocker build -t claude-skill-doctor .\ndocker run --rm -v \"$PWD:/work\" claude-skill-doctor            # 体检挂载的 skill\ndocker run --rm -v \"$PWD:/work\" claude-skill-doctor /work --json\n```\n\n### 接进 CI 卡关（GitHub Actions 示例）\n\n```yaml\n- uses: actions/setup-python@v5\n  with: { python-version: \"3.x\" }\n- name: SKILL.md 体检（不合格则拦 PR）\n  run: |\n    curl -sO https://raw.githubusercontent.com/huiyonghkw/hekouwang-claude-skill-doctor-skill/main/check.py\n    python3 check.py path/to/your/skill\n```\n\n本仓库自身的 CI 见 [`.github/workflows/ci.yml`](.github/workflows/ci.yml)（语法 + good/bad 夹具 + JSON 合法性）。\n\n## 检查项与门禁\n\n| 权重 | 项 |\n|---|---|\n| **1.5（核心）** | 无硬编码密钥 · frontmatter 必填合法 · description 含「何时用」 · SKILL.md ≤500 行 · 渐进披露(拆 references/) · 可移植(无硬编码绝对路径) · 别替模型补它已会的 |\n| 1.0（标准） | description ≤1024 · 指针无死链 · 脚本外置 scripts/ |\n| 0.6（加内容） | allowed-tools 最小化 · 配套文档(README+CHANGELOG) |\n\n分档：A ≥85 · B ≥70 · C ≥50 · D <50。\n\n启用 `--profile codex` 时，Doctor 还会把 Codex 字段白名单、严格 name、description 与正文 TODO\n纳入核心门禁；默认 `agent` Profile 不启用这层检查。除此之外，Doctor 还会把 frontmatter 解析错误、宿主调用策略冲突、文本读取失败、\n目录身份不一致、断链和重名作为可审计结果输出。任何 FAIL 都会使 gate=FAIL。\n\n## 机检 vs 定性\n\n`check.py` 只判机器能确定的部分。**description 触发得准不准、正文是不是\"图书馆\"、\n是不是在替模型补它已会的知识**——这些要人/模型读正文复核（脚本会标出疑点）。\n完整定性流程见 `SKILL.md`。\n\n## 免费 / 付费\n\n| | 免费（开源） | 付费增值 |\n|---|---|---|\n| 机检 | `check.py` 文本/JSON + ASCII 评分条 | 品牌可视化报告卡 |\n| CI | 退出码卡关 | — |\n| 联系 | GitHub Issue | **@huiyonghkw**（ClawHub / GitHub） |\n\n- **免费**：`check.py` 的文本 / JSON 报告 + 评分，随便用、可进 CI。\n- **付费增值**：品牌可视化体检报告卡（精美分享图），找 `@huiyonghkw`。\n\n## 体检器三件套\n\n[`md-doctor`](https://github.com/huiyonghkw/hekouwang-claude-md-doctor-skill) · [`env-doctor`](https://github.com/huiyonghkw/hekouwang-env-doctor-skill) · 一键 `bash scripts/run-all-doctors.sh`（见 `references/doctor-suite.md`）。\n\n---\n\n—— 会勇禾口王的AI笔记 · @huiyonghkw\n\nFile v1.8.0:_meta.json\n\n{\n  \"ownerId\": \"kn73qd1gcmjr446mwcbdxef70x82vxcw\",\n  \"slug\": \"hekouwang-claude-skill-doctor-skill\",\n  \"version\": \"1.8.0\",\n  \"publishedAt\": 1788078352385\n}\n\nFile v1.8.0:references/doctor-suite.md\n\n# hekouwang-doctor-suite · 体检器三件套\n\n> 竞品多是单点；这套把「项目配置 → 技能包 → 本机环境」串成一条验收链。\n\n```\nhekouwang-doctor-suite（概念）\n├── md-doctor      → AGENTS.md / CLAUDE.md（运行时配置）\n├── skill-doctor   → SKILL.md（Agent 技能包）\n└── env-doctor     → 磁盘 / 版本管理器 / AI 宿主目录\n```\n\n## 一键跑\n\n```bash\nbash scripts/run-all-doctors.sh /path/to/your-project\n```\n\n（脚本在 `hekouwang-claude-md-doctor-skill`；`skill-doctor` / `env-doctor` 仓内各有一份相同副本。）\n\n## 建议顺序\n\n1. **md-doctor** — 根配置是否「路由器」而非「图书馆」\n2. **skill-doctor** — `.agents/skills/` 下各 skill 是否按需加载\n3. **env-doctor** — 本机是否留着已换掉的 nvm / 膨胀的 AI 缓存\n\n## Skill 多入口盘点\n\n三件套按项目目录逐个检查 Skill；需要检查一个宿主根目录下的隐藏入口、软链和重名时，\n直接运行 skill-doctor 的扫描模式：\n\n    python3 check.py --scan --direct /path/to/skill-root --json\n\ndirect 模式只看宿主根目录下一层；默认不加 direct 时递归扫描，并跳过测试夹具和构建目录。\n扫描结果按真实 SKILL.md 去重，并将断开的软链、遍历错误、重复 name 和任一子 Skill\n的 FAIL 汇总到 gate。单个 Skill 的 score/grade 不替代 gate。\n\n## 失败口径\n\n三件套必须 fail-closed：doctor 进程崩溃、JSON 解析失败、env-doctor 非零退出，都算套件失败。\n外部软链 Skill 可以继续输出诊断，但是否阻断宿主仓库由调用方明确决定；本仓包装器默认外部\n引用只提示，断开的软链仍阻断。\n\n## 免费 vs 付费\n\n| | 免费（开源） | 付费增值 |\n|---|---|---|\n| 机检 | `check.py` / `scan.sh` 文本报告 + JSON | 品牌可视化报告卡（评分弧 + 等级带） |\n| CI | 退出码卡关 | — |\n| 联系 | GitHub Issue / PR | ClawHub **@huiyonghkw** |\n\nFile v1.8.0:references/skill-writing-vocab.md\n\n# Skill 写作词汇与进阶判据（定性复核时用）\n\n这套词汇消化自 mattpocock/skills 的 `writing-great-skills`。它给\"什么是好 skill\"补了一层**可命名的诊断语言**——体检时用这些词点破问题，比泛泛说\"太长/有冗余\"更准、更可落地。\n\n> 一句话根：**skill 存在是为了从随机系统里榨出确定性。根本美德是「可预测」——每次运行走同一套*过程*（不是产出同一结果）。下面每条判据都为它服务。**\n\n## 一、两种\"载荷\"——这是\"减法\"的底层账\n\n- **context load（上下文载荷）**：model-invoked skill 的 `description` 每轮都待在上下文窗口里，是持续成本。正文越长，每次触发付的越多。\n- **cognitive load（认知载荷）**：user-invoked skill 不进模型视野，只靠**你**记得它存在——成本转嫁到人脑。\n- 当 user-invoked skill 多到记不住，就用一个 **router skill**（一个 user-invoked skill 列出其余的\"何时用哪个\"）来治认知载荷。\n\n## 二、触发方式：model-invoked vs user-invoked（体检新增维度 #8）\n\n- **model-invoked**（默认，省略 `disable-model-invocation`）：保留 description，模型能自主触发、别的 skill 也能调到它。代价是 context load。\n- **user-invoked**（设 `disable-model-invocation: true`）：description 变成给人看的一行摘要，模型够不到，**零 context load**。\n- **判据**：这个 skill 是不是**只可能靠人手敲名字**触发？若是 → 该设 user-invoked，别让它的 description 白占每轮上下文。只有\"模型必须自己判断何时唤醒\"或\"别的 skill 要调它\"时，才值得付 model-invoked 的常驻成本。\n\n## 三、信息阶梯（progressive disclosure 的标尺）\n\n三级，按\"模型多急需\"排：① **in-skill step**（SKILL.md 里的有序动作）② **in-skill reference**（按需查的定义/规则，可以是一组平级规则，不是坏味道）③ **external reference**（推到独立文件、靠 context pointer 触发才加载）。\n\n- **branch（分支）= 最干净的拆分测试**：每个分支都要的 → 内联；只有部分分支会走到的 → 推到指针后面。\n- **co-location（就近）**：一个概念的定义+规则+注意事项放同一标题下，别散落。\n- **context pointer 的措辞**（不是它指向哪）决定模型何时、多可靠地去读那块。\n\n## 四、完成判据（completion criterion）——防\"提前收工\"\n\nstep 类 skill 的每一步要以一个**可检验**的完成条件收尾（模型能分辨\"做完了 vs 没做完\"）；关键处还要**穷尽**（\"每个改过的模型都交代了\"，而不是\"产出一个变更清单\"）。判据含糊 → 招致 **premature completion**（注意力滑向\"算完成了\"而提前结束）。\n\n## 五、leading word（引导词）\n\n一个模型预训练里已有的**紧凑概念**（如 _tight / red / tracer bullets_），在文里复用，用极少 token 锚定一整片行为。两处获益：正文里锚定**执行**（一见这词就走同一行为），description 里锚定**触发**（你 prompt/文档/代码里都用这词，模型更可靠地联想到该 skill）。把\"快、确定、低开销\"这种三词重述坍缩成一个 _tight_——既省 token 又给模型更锐的挂钩。体检时主动找\"能被一个引导词退休掉的重述\"。\n\n## 六、失败模式词汇（诊断用，点名比泛指有力）\n\n- **premature completion**：步骤没真做完就收。先磨锐完成判据（便宜、就地）；判据已无法再细化且确实观察到抢跑，才用\"按序列拆分\"把后续步骤藏起来。\n- **duplication**：同一意思出现在多处。费维护、费 token，还把它在阶梯上的\"显要度\"抬高过真实等级。守则：每个意思**单一真相源**，改行为只改一处。\n- **sediment（沉积）**：旧内容层层留下——\"加着安全、删着危险\"的默认结局。没有修剪纪律的 skill 必然积沉。\n- **sprawl（臃肿）**：纯粹太长，即便每行都还活着且唯一。解药是阶梯：reference 推到指针后、按 branch/序列拆，让每条路径只背自己要的。\n- **no-op（空操作）**：模型默认就会做的话，付了载荷却没说事。**测试：这行相对默认行为改变了什么？没有 → 删**。弱引导词（\"要认真\"而模型本就够认真）就是 no-op，修法是换更强的词（\"relentless\"），不是换技巧。\n\n## 修剪纪律\n\n逐**句**（不是逐行）跑 no-op 测试：某句在孤立状态下不改变行为 → **整句删掉**，别只删词。要狠——失败的散文多数该删，不是重写。\n\nFile v1.8.0:references/trigger-eval.md\n\n# 触发力实测（trigger eval）· 怎么设计 query、怎么读结果\n\n> 机检 #2 只能看出 description 里**有没有**\"当…时/use when\"这类信号词，判不出**写得准不准**。\n> 这份文档配 `scripts/trigger_eval.py`，补的是那一层：真跑一遍，看模型会不会被这段 description 唤醒。\n> ⚠️ 需要 `claude` CLI，**会产生真实费用**（每条 query 每次采样约 $0.09–0.15）。\n> `check.py` 不依赖它，零依赖那条卖点不受影响。\n\n## 0. ⭐ 跑之前必做：基准分辨力自检（不做就别信任何分数）\n\n**先喂一个已知好的和一个已知烂的，看分数分不分得开。** 分不开说明这套判据在你的环境里失灵，\n此时任何分数都是噪音——包括那个看起来很健康的高分。\n\n```bash\n# A 组：真 description\npython3 scripts/trigger_eval.py --eval-set queries.json --skill-path <skill> --label A\n\n# B 组：同一套 query，换一段故意写烂的 description\nprintf '生成内容。\\n' > /tmp/bad-desc.txt\npython3 scripts/trigger_eval.py --eval-set queries.json --skill-path <skill> \\\n  --description-file /tmp/bad-desc.txt --label B\n```\n\n**判据**：A 明显高于 B（实测参考：A=100 / B=50，4 条 query）才算这套 eval 在你机器上有效。\n两组同分 = 判据失灵，先去查第 4 节。\n\n> 这不是形式主义。开发本脚本时，前后四处配置错误里有**三处**都表现为\n> \"跑通了、只是分数低\"——不做 A/B 根本发现不了，会拿一堆假分数去改 description。\n\n## 1. eval query 怎么写\n\n**数量**：20 条左右，正例 8–10、负例 8–10。想省钱可以先用 4–6 条粗筛，方向对了再补齐。\n\n**质量三条**：\n\n1. **写成用户真会打出来的一整段话**，不是抽象任务名。要有具体文件名、路径、栏目名、\n   数字、背景交代，可以有口语、缩写、错别字、全小写。\n   - ❌ `\"生成小红书图文\"`\n   - ✅ `\"帮我把这篇讲 uv 的文章做成一套小红书图文，8 张 1080x1440，用 V2 米白那套视觉，封面要有数字锚点\"`\n\n2. **正例要覆盖不同说法**。同一个意图，有正式的、有随口的；**要有几条不点名品牌/不提专有名词**\n   的（\"我写完一篇稿子想发公众号，帮我出文章母本和配图\"）——这类最能检验 description\n   有没有把使用场景说清楚，而不是靠关键词硬碰。\n\n3. ⭐ **负例必须是 near-miss**。共享关键词或概念、但其实该走别的工具的请求，才有检验力。\n   - ❌ `\"帮我写个快排\"`（对内容工厂来说太远，测不出任何东西）\n   - ✅ `\"帮我给这个 React 项目做个好看的产品落地页\"`（同样是\"做视觉\"，但属前端）\n   - ✅ `\"帮我看下上周几篇小红书笔记数据，哪篇曝光最高\"`（提了小红书，但是数据分析）\n\n**别用的 query**：一步就能做完的简单请求（\"读一下这个文件\"）。模型对自己就能轻松搞定的事\n本来就不查 skill，这种用例无论 description 写得多好都不会触发，纯粹浪费钱。\n\n格式：\n\n```json\n[\n  {\"query\": \"……\", \"should_trigger\": true,  \"note\": \"正1·核心场景\"},\n  {\"query\": \"……\", \"should_trigger\": false, \"note\": \"负1·near-miss 同是做视觉但属前端\"}\n]\n```\n\n## 1.5 ⭐ 负例必须带干扰项跑，否则结论是假的\n\n探针环境默认**只有被测 skill 一个候选**。模型 `ls` 完发现没别的可选，\n就会勉强用手头这个——**负例于是系统性假阳性**。\n\n实测（content-factory · 同一套 6 条 query · 同一段 description）：\n\n| 环境 | 得分 | 那条\"翻页演示版网页\"负例 |\n|---|---|---|\n| 无竞争者 | **83**（5/6） | ✗ 误触发 |\n| 放 5 个兄弟 skill 当竞争者 | **100**（6/6） | ✓ 正确避开 |\n\n**同一段 description，什么都没改，分数差 17 分。** 按 83 分那个数字去\"修边界\"，\n修的是一个不存在的问题。\n\n```bash\npython3 scripts/trigger_eval.py --eval-set queries.json --skill-path <skill> \\\n  --distractors ~/.claude/skills/其它skill-A ~/.claude/skills/其它skill-B ...\n```\n\n选谁当干扰项：**功能相邻、最可能抢活的那几个**。自己有一套 skill 的话，\n把兄弟们全带上最省事，也最接近真实环境。\n\n⚠️ **干扰项的名字也被中性化成 `alt-xxx`，这是故意的**。若让干扰项挂真名\n（`yandu-deck` 之类）而被测探针挂中性名，模型光看名字就能认出干扰项，\n等于给对手开外挂——测出来的仍旧是名字不是 description，跟第 4 节第 4 条同一个坑。\n\n> 正例也别忘了看：竞争者在场时正例**仍应触发**。若加了干扰项后正例掉了，\n> 说明 description 的区分度不够，被邻居抢走了——这才是真该改的信号。\n\n## 2. 怎么读结果\n\n分数只是入口，**两种失败要分开看，修法完全不同**：\n\n| 症状 | 含义 | 怎么改 description |\n|---|---|---|\n| **漏触发**（该触发的没触发） | 覆盖面不够，用户换个说法就唤不醒 | 补场景句和同义说法；把用户真实的口语表达写进去 |\n| **误触发**（不该触发的触发了） | 写太宽泛，抢别的工具的活 | 加边界（\"不用于 X\"）；把泛词换成具体动作与产物 |\n\n同时出现两种 = description 抓错了维度，重写而不是打补丁。\n\n采样次数：默认 `--runs-per-query 1` 省钱。触发是概率性的，要下正式结论用 `3`\n（成本 ×3），此时触发率 ≥0.5 判通过。\n\n## 3. 结果不对劲时\n\n先用 `--dump-dir` 把原始流存下来翻，**别猜**：\n\n```bash\npython3 scripts/trigger_eval.py ... --dump-dir /tmp/dumps\n```\n\n翻的时候重点看两样：模型的**工具调用序列**（它到底做了什么），\n以及 Skill/Read 调用里的**实际参数**（是不是调到了别的东西）。\n本脚本历史上两次假阴性都是靠翻这个抓出来的。\n\n## 4. 脚本为什么这么写（改它之前先读这节）\n\n本脚本改自官方 `anthropics/skills · skill-creator/scripts/run_eval.py`。\n官方思路对，但原样跑在 Claude Code 2.1.220 上**测不出任何东西**。四处都改完才有分辨力——\n**这四处是踩出来的，改脚本时别顺手改回去**：\n\n1. **`--setting-sources project`**：不加则子进程继承 `~/.claude/skills/` 里已装的真 skill\n   （实测 32 个），模型去触发真身、名字对不上探针 → 全部正例假阴性。\n   官方没料到\"被测 skill 已经装在机器上\"这种情况。\n\n2. **扫完整个流才判否**：官方是\"第一个 tool_use 不是 Skill/Read 就 return False\"。\n   但模型碰到陌生 skill 名**会先 `Bash: ls` 探查环境**，Skill 往往是第二三个动作\n   （实测序列 `['Bash','Bash','Skill']`）——真触发了却被判没触发。\n\n3. **每条 query 独立 project root**：共用目录时并发 worker 把探针全丢一处，\n   模型会调到**别人的**探针（实测：期望 `-d795b59f`，实际调 `-4ac07ae5`），自己这条判否。\n\n4. ⭐ **探针要装成 project 级真 skill，且名字中性（`probe-xxxxxxxx`）**：\n   init 事件里 `skills` 和 `slash_commands` 两个列表**都只给名字、不给 description**。\n   探针一旦沿用原 skill 名，模型光看名字就去 Read 它，**description 全程没参与决策**——\n   实测此时 447 字真 description 和 5 字\"生成内容。\"**都是满分**，等于白测。\n\n## 5. 成本\n\n| 规模 | 调用数 | 约合 |\n|---|---|---|\n| 粗筛 4 条 × 1 次 | 4 | $0.5 |\n| 正式 20 条 × 1 次 | 20 | $2–3 |\n| 结论 20 条 × 3 次 | 60 | $6–9 |\n\n先粗筛、方向对了再上规模。A/B 基准自检要算两轮。\n\nFile v1.8.0:CHANGELOG.md\n\n# Changelog\n\n本项目遵循 [语义化版本](https://semver.org/lang/zh-CN/)。\n\n## [1.8.0] - 2026-08-30\n\n### 新增\n- **Codex 严格基础 Profile**：新增 `--profile codex`，以零依赖方式迁入 Codex\n  `skill-creator` 的基础契约：字段白名单、≤64 字符 kebab-case name、description 限制与正文\n  未完成 TODO 检查。该 Profile 可用于单个 Skill 或 `--scan` 批量门禁。\n- JSON/文本报告明确输出本次 `profile`；报告 schema 升至 v3，避免自动化把默认跨宿主检查和\n  严格 Codex 验收混为一谈。\n\n### 兼容性\n- 默认 `agent` Profile 保持原行为，允许 Claude/其他宿主合法的扩展字段（如 `slug`、`version`）；\n  只有显式传入 `--profile codex` 才执行严格白名单，避免跨宿主 Skill 被错误阻断。\n\n### Tests\n- 新增合法 Codex Skill、严格拒绝扩展字段与 TODO、默认跨宿主扩展字段可通过的正反例回归；CI 同步执行。\n\n## [1.7.0] - 2026-08-30\n\n### 新增\n- **多 Skill 扫描**：新增 `--scan`，递归发现隐藏宿主目录，按真实 SKILL.md 去重，\n  报告断开的软链、重复 name、遍历错误和每个 Skill 的门禁结果；新增 `--direct`\n  供宿主根目录只盘点直接入口，递归模式跳过测试夹具和构建目录。\n- **显式门禁字段**：文本和 JSON 报告新增 Doctor 版本、schema 版本、PASS/WARN/FAIL/INFO\n  计数与 `gate`；自动化不再用 score/grade 猜是否放行。\n- **宿主调用策略检查**：读取 `disable-model-invocation` 与 `agents/openai.yaml` 的\n  `policy.allow_implicit_invocation`，发现冲突时阻断。\n\n### Fixed\n- frontmatter 解析支持 UTF-8 BOM、嵌套 mapping、布尔值和 YAML 解析错误，不再把嵌套\n  `metadata.openclaw` 静默当成不存在；兼容跨行 JSON 风格的 flow mapping/list。\n- 指针检查只认 Markdown link destination 或显式 `doctor:resource`，并校验 glob、\n  brace expansion、软链目标和根目录 containment；修复教学示例路径误报。\n- 文本扫描覆盖 YAML/HTML/TypeScript 等逻辑文件，但继续严格跳过 `.env`、`*.key`、\n  `*.pem` 和包含 secret 的文件名；读取失败改为 FAIL，不再静默跳过。\n- 三件套聚合器改为 fail-closed：doctor 崩溃、JSON 损坏和 env-doctor 非零退出都会\n  让套件失败；外部软链 Skill 仍可只做提示。\n\n### Tests\n- 新增 frontmatter、保护文件、扫描、断链、重名、示例路径和越根路径回归。\n\n## [1.6.0] - 2026-08-27\n\n### 变更\n- **#4b 指针死链从 WARN 升为 FAIL**：死链是确定性事实，不是风格建议。此前一个被 SKILL.md\n  引用却漏提交的 reference，在 pre-push 快照里只扣 3 分（97/100、退出码 0），于是「Doctor\n  失败禁止推送」形同虚设。现在死链直接判失败并卡退出码。\n\n### 新增\n- `tests/test-dead-pointer.sh`：死链应失败、指针齐全应放过的正反例。\n\n## [1.5.2] - 2026-08-12\n\n### 变更\n- ClawHub 分类：`development`\n\n## [1.5.1] - 2026-08-12\n\n### 新增\n- `scripts/run-all-doctors.sh`、`references/doctor-suite.md`（与 md-doctor / env-doctor 同版）\n\n### 变更\n- `check.py`：付费报告卡 CTA；README 30 秒验收 + 免费/付费表 + 三件套互链\n- summary 补英文 SEO 关键词（skill lint / SKILL.md doctor）\n\n## [1.5.0] - 2026-08-12\n\n### 新增\n- **#11 paths / globs**：识别 Cursor 2.4+ 文件作用域 frontmatter，减少无关文件时的误触发。\n- **#12 OpenClaw 兼容声明**：轻量检查 `metadata.openclaw`、`requires`、`install`（有 scripts/ 时提示）。\n\n### Fixed\n- **指针扫描误报**：只匹配带扩展名的捆绑资源路径（`references/foo.md`），表格里的\n  `references/scripts/assets` 不再被判死链。\n- **可移植性自检误报**：`ABS_PATH_RE` 用字符串拼接构建，避免 `check.py` 源码里的\n  正则说明行被当成硬编码路径。\n- **#10a 元层面误报**：评分表/检查项表格行里的黑名单示例词不再计为教学冗余。\n\n## [1.4.1] - 2026-08-01\n\n修 #0 安全红线的两处假阳性。**假阳性会让红线失去意义**——被误报训练过的人下次看到真 FAIL 也只会挥手放过。\n\n### Fixed\n- **`sk-` 密钥正则缺左词界**：`sk-(?:ant-)?[\\w-]{20,}` 会从 `generate-ask-user-format.ts`\n  里抠出 `sk-user-format` 判成 key。同一份 `SECRET_PATTERNS` 里 `AKIA` / `AIza` / `JWT`\n  三条都带 `\\b`，只有这条漏了。实测某第三方 skill 因此被判资损级 FAIL（62 分），\n  命中源全是 `ask-user-*` 文件名。\n- **测试夹具里的假密钥降级 WARN**：安全基准/回归夹具（`test/ tests/ fixtures/ golden/ snapshots/`\n  等目录）里的 key 是刻意载荷，不是泄露。现在只在夹具命中时判 WARN 并提示\"翻一眼确认\"，\n  正文/脚本命中照旧 FAIL；两类同时命中时 FAIL 优先，detail 里标明夹具那几处已降级。\n\n### 验证（A/B 基准分辨力自检）\n三类样本必须判出三种结果，否则说明改完的判据分不开对和错：\n真密钥 `sk-proj-…` → **FAIL**；夹具里 `sk-ant-api03-…` → **WARN**；`ask-user-question-format` → **PASS**。\n回归夹具分数不变（`tests/fixtures/bad` 67、`good` 100）。\n\n## [1.4.0] - 2026-07-28\n\n补上本器最大的盲区：**#2 触发质量以前只能拍脑袋，现在能实测**。\n静态检查只看得出 description 里有没有\"当…时\"这类信号词，判不了写得准不准——\n而 description 写不准 = 这个 skill 永远不被唤醒，正文写得再好也白搭。\n\n### Added\n- **`scripts/trigger_eval.py` · 触发力实测（可选第二引擎）**：把待测 description 装成临时探针 skill，\n  跑 `claude -p` 看模型会不会去调它，输出触发力分数 + **漏触发 / 误触发**两个计数。跑完即删，\n  不碰任何已装的 skill。改自官方 `anthropics/skills · skill-creator/run_eval.py`。\n- **`--distractors` 干扰项**：把其它 skill 的 description 一起放进探针环境当竞争者。\n  不加的话环境里只有被测探针一个候选，模型\"没得选\"就会勉强用它，**负例系统性假阳性**。\n  实测同一段 description、同一套 query：无竞争者 **83 分**（那条\"翻页演示版\"负例误触发），\n  放 5 个兄弟 skill 后 **100 分**（正确避开）——**什么都没改，差 17 分**。\n  按 83 分去修边界，修的是一个不存在的问题。\n  干扰项名字同样中性化成 `alt-xxx`，否则模型看名字就能认出对手，等于开外挂。\n- **`references/trigger-eval.md`**：query 怎么设计（**负例必须是 near-miss**）、\n  **负例必须带干扰项跑**、两种失败各自怎么改 description、结果不对劲怎么翻原始流、成本表。\n- 工作流新增步骤 **2c**；检查项 #2 与「机检的盲区」#2 同步改写。\n\n### Changed\n- 免费/付费边界补一档：`trigger_eval.py` **脚本开源随便用，但 API 费用走用户自己的额度**\n  （约 $0.09–0.15/次调用）。因此它是**可选叠加档、不进默认流程**，\n  `check.py` 的零依赖卖点不受影响，不跑也能出完整体检报告。\n\n### 踩坑记录：官方脚本原样搬过来测不出任何东西\n\n官方那版思路对，但在 Claude Code 2.1.220 上四处全错，**改完才有分辨力**\n（实测：真 description 100 分 vs \"生成内容。\"50 分；不改第 4 条时两者都是 100，等于白测）。\n四处里**前三处都表现为\"跑通了、只是分数低\"**，不做 A/B 基准根本发现不了：\n\n1. 不加 `--setting-sources project` → 子进程继承 `~/.claude/skills/` 里已装的真 skill（实测 32 个），\n   模型触发真身、名字对不上探针 → **全部正例假阴性**。官方没料到\"被测 skill 已装在机器上\"。\n2. 官方\"第一个 tool_use 不是 Skill/Read 就判否\" → 但模型碰到陌生 skill 名**会先 `Bash: ls` 探查**，\n   Skill 往往是第二三个动作（实测序列 `['Bash','Bash','Skill']`）。改为扫完整个流、命中即收工。\n3. 并发 worker 共用一个 project root → 模型调到**别人的**探针\n   （实测：期望 `-d795b59f`，实际调 `-4ac07ae5`）。改为每条 query 一个一次性 root。\n4. ⭐ 探针放 `.claude/commands/` 且沿用原 skill 名 → init 事件里 `skills` / `slash_commands`\n   两个列表**都只给名字、不给 description**，模型光看名字就去 Read 它，\n   **description 全程没参与决策**。改为装成 project 级真 skill + 中性名 `probe-xxxxxxxx`。\n\n⭐ 因此文档把「**先做 A/B 基准分辨力自检，分不开就别信分数**」写成了跑之前的强制前置步骤，\n不是建议。\n\n## [1.3.0] - 2026-07-15\n\n**版本号说明**：本次内容即原定的 1.2.0（见下方 Changed/Added），因发布事故改号为 1.3.0——\nClawHub 上 `hekouwang-claude-skill-doctor-skill` 这个 slug 于 2026-07-09 被误发成 **md-doctor 的内容**\n并占用了 1.2.2 这个版本号（check.py 与 md-doctor 逐字节同 hash `5f0d3613`、测试夹具是 `CLAUDE.md`\n而非 `SKILL.md`）。该 slug 在 2026-06-24 的 1.0.2 / 1.0.3 是正确的 skill-doctor 内容，\n即**误发覆盖了正确版本**。需发一个高于 1.2.2 的版本才能把 latest 拨正，故跳到 1.3.0。\n误发的 1.2.2 已从该 slug 永久删除，版本史现为 1.0.2 → 1.0.3 → 1.3.0。\n\n### Fixed\n- **ClawHub 发布事故更正**：`hekouwang-claude-skill-doctor-skill@1.2.2` 实为 md-doctor，已删除；\n  latest 拨回真正的 Agent Skill 体检器。\n- **发布纪律**：以后 `clawhub skill publish` **一律显式传 `--version`**——\n  ClawHub 不读 SKILL.md 的 `version`，只在线上版本上 +1（实测会把本地 1.2.2 发成 1.1.3、\n  本地 1.1.0 发成 0.1.2，即**降级**）。自动推断不可信。\n\n拿真数据校准步骤 2b 的 SkillSpector。全量扫 7 个 `hekouwang-*` skill、逐条翻源码核实，\n结论推翻 1.1.0 的乐观假设：**对自研 skill 它 100% 误报**，且**分数完全不可信**。\n2b 从\"可选加跑的安全维\"收紧为\"只对外来 skill 跑的入库审查\"。\n\n### Changed\n- **2b 定位收紧：只对\"别人写的、要装进来的\" skill 跑。** 7 个自研 skill 全扫、逐条翻源码，\n  无一为真。自研 skill 改走**回归检测**（存基线 → 只看 NEW），不再全量看告警。\n- **新增铁律「分数不是门禁，只看条目 + 翻源码」。** `Score/Severity` 是逐条**累加**的：\n  yandu-deck / iterm2 / cc-prod 三个判 `100/100 CRITICAL · DO NOT INSTALL`，\n  但报告里**一条 CRITICAL 发现都没有**——纯粹是十几条 MEDIUM/HIGH 累加撞顶。\n  且评分随版本通胀：content-factory 代码一行没改，v2.3.5 `19/100 SAFE` → v2.3.13 `40/100 CAUTION`。\n- **推翻 1.1.0 的「低可信度才是误报」说法**：95% 高可信度的照样是误报。改为附**高置信度误报样本表**：\n  `rm -f \"$写死路径\"` → `TM1` 95%；`subprocess.run([...], check=True)` 硬编码列表 →\n  `OH1 Unvalidated Output Injection` 95% + `AST4`（其 remediation 建议的恰恰就是这个写法）；\n  docstring 写\"本脚本**绝不读取** .env/*.key\" → `PE3 Credential Access`；\n  字体文件名列表 → `MP2 Context Window Stuffing`；中文 frontmatter → `P2 Hidden Instructions` 21%；\n  中文触发词 → `AS3 Mixed script`。\n\n### Added\n- **rsync `--exclude` 顺序坑**：必须排在 `--include='*/'` 前面（rsync 首次匹配生效，\n  否则 `*/` 先吃掉 `.venv/`，整个 site-packages 被当自己的代码扫）。实测 stock-data-reader 264M→176K。\n- **SOCKS 代理绕法**：代理下扫描直接崩（`'socksio' package is not installed`），\n  需 `env -u ALL_PROXY -u all_proxy -u HTTPS_PROXY -u https_proxy`。OSV.dev 连不上只降级静态库，不影响结论。\n- **`--baseline` 正确用法 + 反例**：`fingerprints` 按「路径+内容 hash」锁定、只对同一 skill 生效；\n  能跨 skill 的 glob `rules`（如 `id: \"TM1\"`）**恰恰不能在扫外来 skill 时开**——\n  同一规则在自研 `rm` 上是误报、在恶意 skill 里可能是真的，全局关掉等于拆探头。\n- content-factory / yandu-deck / stock-data-reader 三个常改的 skill 各存一份归零基线\n  （`.skillspector-baseline.yaml`，A/B 验证：yandu-deck `100 CRITICAL DO_NOT_INSTALL` → `0 LOW SAFE`）。\n- 记录唯一有信号的结构性告警 **LP1「代码有 network/env/shell 能力但没声明权限」**（7 个中 5 个命中）——\n  不是漏洞，与 `check.py` 自检的「未声明 allowed-tools」指向同一缺口。\n\n## [1.1.0] - 2026-06-24\n\n接入外部安全扫描、消化业界 skill 写作最佳实践，扩展体检维度。\n\n### Added\n- **工作流新增步骤 2b · 深度安全扫描（可选）**：叠加 [NVIDIA SkillSpector](https://github.com/NVIDIA/skillspector)，\n  覆盖提示注入 / 数据外泄 / 隐藏指令 / 供应链 / 过度授权 / MCP 越权等 68 类模式，\n  补 `check.py` #0 密钥正则之外的深度安全维。含实战铁律：**只扫逻辑文件、别扫 assets**\n  （直接扫会把字体/图片二进制当代码，刷出几十条假 `TM1 Tool Parameter Abuse`）；\n  低可信度（<30%）`Hidden Instructions` 多是中文/零宽字符误报，人工复核。\n- **评分维度 #8 触发方式匹配（model vs user invoked）**：只靠人手敲名字触发的 skill\n  应设 `disable-model-invocation: true`，省掉每轮 `description` 的 context load。\n- **`references/skill-writing-vocab.md`**：消化 mattpocock/skills 的 *writing-great-skills*，\n  把\"好 skill\"的判据沉淀成可命名的诊断词汇——两种载荷（context/cognitive load）、\n  信息阶梯、branch 拆分测试、完成判据（防 premature completion）、no-op 测试、\n  sediment/sprawl/duplication 失败模式、leading word。出报告时用这些词点破问题。\n\n### Changed\n- **#10a 锐化为 no-op 测试**：判据明确为「这段相对模型默认行为改变了什么？没有就删」，\n  比原先\"别替模型补它已经会的\"更可操作。\n\n## [1.0.2] - 2026-06-22\n\n实战体检三个品牌 skill 时暴露的机检缺陷修复（dogfooding）：\n\n### Fixed\n- **#7 allowed-tools 兼容逗号字符串**：原先只认 YAML 列表（`- a` / `[a,b]`），\n  把官方 frontmatter 标准的逗号字符串写法（`allowed-tools: Bash, Read, Write`）\n  误判为「未声明」。现在两种写法都解析、非空即 PASS。\n\n## [1.0.1] - 2026-06-21\n\n实战体检 14 个 skill 时暴露的两个机检缺陷修复（dogfooding）：\n\n### Fixed\n- **glob 指针不再误报死链**：`reference/deck-engine-*.html` 这类通配符指针，\n  现在用 `glob` 解析、能匹配到真实文件就算存在；`{a,b}` brace 简写跳过不误报。\n  （原正则在 `*` 处截断成 `reference/deck-engine-`，当字面路径判死。）\n- **指针 / 教学词行号还原为文件绝对行号**：原先报的是正文相对行号（少算了\n  frontmatter 行数），定位会偏。`parse_frontmatter` 现返回 `body_offset` 补正。\n\n## [1.0.0] - 2026-06-21\n\n首个版本。给 Agent Skill（SKILL.md）做体检的零依赖检查器。\n\n### 检查项（12 项加权）\n- **安全**：SKILL.md 及捆绑文件无硬编码密钥（命中即 FAIL，资损级）。\n- **触发**：frontmatter 必填合法（name/description）；description 含「何时用」且 ≤1024 字符。\n- **减法**：SKILL.md ≤500 行；长内容下沉 references/（渐进披露）；大段脚本外置 scripts/。\n- **可移植**：无硬编码 `/Users/`、`/home/` 绝对路径。\n- **取舍**：别替模型补它已会的（教学冗余检测）；allowed-tools 最小化；配套 README/CHANGELOG。\n\n### 特性\n- 零依赖（Python3 标准库），文本 + `--json` 双输出，退出码随 FAIL。\n- 按重要度加权评分（触发/减法核心项 1.5，标准项 1.0，加内容项 0.6），A/B/C/D 分档。\n- 极简零依赖 frontmatter 解析（块标量 / 行内 list / 缩进 list）。\n- 密钥扫描双档豁免：指纹型用窄填充表、赋值型用宽占位表，避免误杀真 key。\n- 报告口吻与署名沿用「会勇禾口王的AI笔记」品牌人设。\n\nFile v1.8.0:skill-card.md\n\n## Description:\n\nChecks Claude and agent Skill directories for SKILL.md quality, trigger clarity, progressive disclosure, portability, security red flags, host metadata conflicts, and multi-skill discovery issues, then produces a scorecard and prioritized remediation guidance.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[huiyonghkw](https://clawhub.ai/user/huiyonghkw)\n\n### License/Terms of Use:\n\nMIT\n\n## Use Case:\n\nDevelopers and engineers use this skill to audit, lint, and improve Claude or agent skills before local use, CI gating, or ClawHub-style release. It helps identify trigger, structure, portability, security, and compatibility issues and can guide targeted refactoring.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The optional trigger evaluation workflow runs Claude CLI calls and can consume the user's API quota.\n\nMitigation: Treat trigger evaluation as explicit opt-in and run it only when trigger quality needs live validation.\n\nRisk: Optional evaluations or scans may run in an environment that contains exported secrets.\n\nMitigation: Run optional checks from a minimal shell environment and avoid exposing unnecessary credentials.\n\nRisk: The README includes a CI example that downloads the checker from the main branch.\n\nMitigation: Pin CI usage to an immutable commit, release, checksum, or container digest before adopting it in production gates.\n\nRisk: Reports include Chinese-language branding and a fixed publisher signature.\n\nMitigation: Review report language and branding expectations before using the output in public or customer-facing workflows.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/huiyonghkw/skills/hekouwang-claude-skill-doctor-skill)\n- [Project homepage](https://github.com/huiyonghkw/hekouwang-claude-skill-doctor-skill)\n- [Doctor suite reference](references/doctor-suite.md)\n- [Skill writing vocabulary](references/skill-writing-vocab.md)\n- [Trigger evaluation guide](references/trigger-eval.md)\n- [SkillSpector](https://github.com/NVIDIA/skillspector)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Code, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown reports, JSON reports, shell commands, and prioritized remediation guidance]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [The default checker is zero-dependency Python; optional trigger evaluation invokes Claude CLI and can consume API quota.]\n\n## Skill Version(s):\n\n1.8.0 (source: frontmatter, changelog, ClawHub release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.8.0:LICENSE\n\nMIT License\n\nCopyright (c) 2026 huiyonghkw (会勇禾口王的AI笔记)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\nArchive v1.5.2: 15 files, 52821 bytes\n\nFiles: CHANGELOG.md (13414b), check.py (32096b), Dockerfile (804b), LICENSE (1096b), README.md (4226b), references/doctor-suite.md (1118b), references/skill-writing-vocab.md (4701b), references/trigger-eval.md (7753b), scripts/run-all-doctors.sh (3290b), scripts/trigger_eval.py (16245b), skill-card.md (2572b), SKILL.md (20641b), tests/fixtures/bad/SKILL.md (379b), tests/fixtures/good/SKILL.md (802b), _meta.json (154b)\n\nFile v1.5.2:SKILL.md\n\n---\nname: hekouwang-claude-skill-doctor-skill\nslug: hekouwang-claude-skill-doctor-skill\ndisplayName: Claude Skill 体检器（SKILL.md Doctor）\nsummary: Agent Skill lint / SKILL.md doctor / skillspec audit — description 触发、渐进披露、可移植性与 OpenClaw 兼容检查。姊妹工具 md-doctor。\nlicense: MIT-0\nhomepage: https://github.com/huiyonghkw/hekouwang-claude-skill-doctor-skill\nversion: 1.5.2\ndescription: >\n  会勇禾口王的AI笔记 · Agent Skill（SKILL.md）体检器。检查一个 Claude/Agent Skill 是否\n  符合\"按需加载的指令包，不是单文件巨石\"的最佳实践——评 description 触发质量、SKILL.md\n  篇幅、渐进披露（references/ 拆分）、脚本外置、可移植性（无硬编码绝对路径）、安全（无硬编码\n  密钥），给出评分卡 + 按优先级的修复建议，并可代为重构。触发：用户说「检查我的 skill /\n  SKILL.md 体检 / 这个 skill 规范吗 / claude-skill-doctor / audit skill / lint SKILL.md /\n  我的 skill 太长了 / skill 拆分 / 看看我的 skill 合不合规 / skill 对齐官方规范」。\n  任何\"评估/审查/优化某个 Agent Skill 质量或结构\"的请求都应触发。\n---\n\n# hekouwang-claude-skill-doctor-skill · Agent Skill 体检器\n\n> **会勇禾口王的AI笔记** 出品 · `@huiyonghkw`\n> _不聊 AI 会不会取代你，只聊先用 AI 的人怎么取代你。_\n\n把\"Agent Skill 最佳实践\"做成一个能跑在任何 skill 上的检查器：机检定量 + 模型定性，\n产出评分卡和可落地的修复建议。核心判据一句话——\n\n> **SKILL.md 是模型\"决定要不要加载、加载后照着做\"的运行时指令包。`description` 决定它何时被唤醒；正文越精简越准；厚重细节要能\"按需展开\"（references/ 用到再读），而不是每次触发就把全部细节灌进上下文。**\n> 一切检查项都从这句推导：这段内容值不值得在 skill 每次触发时都付一次上下文费？能不能下沉到 references/ 用到再读？\n\n### 触发优先 + 减法优先（元判据 · 凌驾全部检查项之上）\n\nSkill 的命脉是两条，权重最高：\n\n1. **触发**：`description` 是模型唯一用来判断\"何时唤醒本 skill\"的信号。写不清\"何时用\"，再好的正文也永远不被加载。\n2. **减法**：SKILL.md 不是图书馆。模型每代都在变强——你塞进正文的通用写法、框架教程、临时脚本，很快既过时又白占 token。**能下沉 references/ 的下沉，能外置 scripts/ 的外置，模型已经会的删掉。**\n\n所以机检里 **#2 触发 / #3 篇幅 / #4 渐进披露 / #6 可移植 / #10 别替模型补** 权重 1.5；\n\"加内容\"类项（#7 最小工具集、#10 配套文档）缺失只算小扣分——别一边喊\"越精简越好\"、一边逼作者把 skill 做臃肿。\n\n## 品牌人设（体检报告的口吻 + 署名）\n\n属于 **会勇禾口王的AI笔记**（定位：AI 实战拆解，硬核·具体·可复制；人设：你办公室里第一个把 AI 用明白的同事）。出体检报告时：\n\n- **口吻**：像同事帮你看代码——直给结论、敢泼冷水（\"这 description 只写了做什么、不写何时用，等于永远不被触发\"），不说客套话。\n- **价值化**：修复建议讲\"省了什么\"（每次触发少灌 100KB 冗余、别人装上不报错、该用时真能被唤醒），不堆术语。\n- **署名**：报告结尾固定带 `—— 会勇禾口王的AI笔记 · @huiyonghkw`。命令行 `check.py` 的报告页脚已内置该署名。\n- **去 AI 味**：定稿前避开\"赋能/打造/至关重要/助力\"等词，说人话。\n\n---\n\n## 免费 / 付费边界（重要）\n\n- **免费（开源内核）**：`check.py` 的**文本 / JSON 报告 + 评分**。任何人本地或进 CI 随便跑。\n- **免费但要自付 API 钱**：`scripts/trigger_eval.py` 触发力实测（工作流 2c）。脚本本身开源随便用，\n  但它每条 query 都真调一次 `claude -p`（约 $0.09–0.15/次），**钱花在用户自己的额度上**。\n  所以它是**可选叠加档、不进默认流程**——`check.py` 的零依赖卖点不受影响，不跑也能出完整体检报告。\n- **付费（增值）**：**品牌可视化体检报告卡**（评分弧 + 等级带 + 明细分享图），依赖 `hekouwang-content-factory` 的私有品牌字体与版式，不随本仓库分发。\n- 一句话口径：**跑检查免费，出\"好看的报告图\"找 @huiyonghkw。** 外部用户要图时说明是付费增值项，别用系统字体凑一张劣化图糊弄。\n\n---\n\n## 工作流（每次体检按这个顺序）\n\n1. **确认目标**：用户没指明就用当前目录；说了某个 skill 就用那个 skill 目录的绝对路径（目录里要有 `SKILL.md`）。若传进来是 `~/.claude/skills/` 这种父目录，脚本会提示里面有哪些 skill，逐个体检。\n2. **跑机检**（确定性层，零依赖）：\n   ```bash\n   python3 <此skill目录>/check.py <skill目录>\n   ```\n   - 需要结构化结果时加 `--json`。退出码：有 FAIL → 1，否则 0。\n2b. **深度安全扫描（可选 · 外部工具 SkillSpector）**：`check.py` 的 #0 只做密钥正则；当要查**提示注入 / 数据外泄 / 隐藏指令 / 供应链 / 过度授权 / MCP 越权**等 68 类模式时，叠加跑 [SkillSpector](https://github.com/NVIDIA/skillspector)（本机已装：`uv tool install`，需 Python 3.12/3.13）：\n   ```bash\n   env -u ALL_PROXY -u all_proxy -u HTTPS_PROXY -u https_proxy \\\n     skillspector scan <纯逻辑副本> --no-llm --format markdown -o report.md\n   ```\n   - **只对\"别人写的、要装进来的\" skill 跑。** 自研 skill 扫出来的实测是 100% 误报（2026-07-15 全量验证 7 个 hekouwang-* skill，逐条翻源码，无一为真），跑了只会浪费时间。\n   - **自研 skill 只做回归检测。** content-factory / yandu-deck / stock-data-reader 三个（会持续改的）已各存一份归零基线在自己目录的 `.skillspector-baseline.yaml`，改完代码后：\n     ```bash\n     skillspector scan <纯逻辑副本> --no-llm --baseline <skill目录>/.skillspector-baseline.yaml\n     ```\n     **冒出来的任何一条都是新的**，值得真翻一眼源码；`--show-suppressed` 看压了什么。基线里的 13/8/4 条已核实为误报（2026-07-15 A/B 验证：yandu-deck `100 CRITICAL DO_NOT_INSTALL` → `0 LOW SAFE`）。改动大到路径/内容 hash 全变时重新 `skillspector baseline <副本> -o …` 存一版。\n   - **分数不是门禁，只看条目。** `Score/Severity` 是**逐条累加**出来的：yandu-deck/iterm2/cc-prod 三个都判 `100/100 CRITICAL · DO NOT INSTALL`，但报告里**一条 CRITICAL 发现都没有**——纯粹是十几条 MEDIUM/HIGH 累加撞顶。且评分随版本通胀：content-factory 代码一行没改，v2.3.5 是 `19/100 SAFE`，v2.3.13 变 `40/100 CAUTION`。**永远读条目、翻源码，别信总评。**\n   - **铁律：只扫逻辑文件，别扫 assets。** 直接扫会把字体 `.woff2`、PNG 等**二进制当代码**，在字节流里刷出几十条假 `TM1 Tool Parameter Abuse`。先用 rsync 拷纯逻辑副本（只留 `.md/.py/.js/.json/.html/.css/.sh/.txt/.yaml`）。⚠️ **`--exclude` 必须写在 `--include='*/'` 前面**（rsync 首次匹配生效，否则 `*/` 先吃掉 `.venv/`，把整个 site-packages 当你的代码扫）：\n     ```bash\n     rsync -a --prune-empty-dirs \\\n       --exclude='.venv/' --exclude='node_modules/' --exclude='.git/' --exclude='__pycache__/' \\\n       --include='*/' --include='*.md' --include='*.py' --include='*.js' --include='*.json' \\\n       --include='*.html' --include='*.css' --include='*.sh' --include='*.txt' --include='*.yaml' \\\n       --exclude='*' <skill目录>/ <副本>/\n     ```\n     实测 content-factory 141M→1.1M、stock-data-reader 264M→176K。\n   - **已知高置信度误报样本**（别被 90%+ 唬住，这些全部核实为假）：`rm -f \"$写死的路径\"` → `TM1 Tool Parameter Abuse` 95%；`subprocess.run([...], check=True)` 硬编码列表 → `OH1 Unvalidated Output Injection` 95% + `AST4`（它建议的 remediation 恰恰就是这个写法）；docstring 里写\"本脚本**绝不读取** .env/*.key\" → `PE3 Credential Access`；字体文件名列表 → `MP2 Context Window Stuffing`；中文 frontmatter → `P2 Hidden Instructions`（置信度 21%，全在 `:1`）；中文触发词 → `AS3 Mixed script`。\n   - **`--baseline` 的 glob `rules` 别乱开。** `rules: {id: \"TM1\"}` 能跨 skill 全局压制，但**扫外来 skill 时恰恰不能用**——今天 TM1 在自研 `rm` 上是误报，在恶意 skill 里可能是真的，全局关掉等于拆探头。跨 skill 只压 `path`+`message` 都限定死的具体条目。\n   - **代理会让扫描直接崩**：SOCKS 代理下报 `Using SOCKS proxy, but the 'socksio' package is not installed`（同 `词级字幕.py` 那个坑），用上面的 `env -u` 绕开。OSV.dev 连不上只是降级到静态库，不影响结论。\n   - 唯一值得看的结构性信号是 **LP1「代码有 network/env/shell 能力但没声明权限」**（7 个自研 skill 中 5 个命中）——不是漏洞，是提醒你 frontmatter 可以补 `allowed-tools`。\n   - `--no-llm` 纯静态、免 key；要更准的行为分析再配 LLM provider（`SKILLSPECTOR_PROVIDER` + 对应 key）。结论并进体检报告的安全维，不替代 #0。\n2c. **触发力实测（可选 · 要花钱 · 只在怀疑 description 时跑）**：机检 #2 只能看出有没有信号词，\n   **判不了写得准不准**——那是本 skill 最大的盲区，因为 description 写不准 = 这个 skill 永远不被唤醒，\n   正文写得再好也白搭。要判准不准就得真跑一遍：\n   ```bash\n   python3 <此skill目录>/scripts/trigger_eval.py \\\n     --eval-set <你的query集>.json --skill-path <skill目录>\n   ```\n   把待测 description 装成临时探针 skill，跑 `claude -p` 看模型会不会去调它。跑完即删，不碰已装的 skill。\n   - ⭐ **先做基准分辨力自检再信分数**：拿真 description 和一段故意写烂的（\"生成内容。\"）\n     跑同一套 query，**分数分不开就说明判据在当前环境失灵**，此时高分也是噪音。\n     实测参考 A=100 / B=50。开发这个脚本时四处配置错误里有三处都表现为\"跑通了、只是分数低\"——\n     不做 A/B 根本发现不了。\n   - **读结果分两种失败**：漏触发＝覆盖不够（补场景句和同义说法）；误触发＝写太宽泛（加边界、换具体动作）。\n     两种都有＝抓错维度，重写而非打补丁。\n   - ⚠️ **要钱**：每条 query 每次采样约 $0.09–0.15，20 条 ×3 次约 $6–9。先用 4–6 条粗筛。\n   - query 怎么设计（尤其**负例必须是 near-miss**）、结果不对劲怎么翻原始流、脚本那四处\n     不能改回去的坑 → 读 [`references/trigger-eval.md`](references/trigger-eval.md)。\n   - **`check.py` 不依赖它**，零依赖那条卖点不受影响；这一档是叠加的，不跑也能出完整体检报告。\n\n3. **定性复核**（机检之上，必须做）：机检是启发式，几项要你**真正读 SKILL.md**再下结论（见下「机检的盲区」）：\n   - 通读 `description`，**真的当一次模型**：光看这段，能不能判断\"什么请求该唤醒它\"？\n   - 通读正文：哪些是\"模型不可能知道的项目/品牌私有事实\"（该留），哪些是\"通用写法/框架教程\"（该删或下沉）？\n   - 若正文很长，看它能不能按\"版本/平台/流程\"天然切成 references/。\n4. **出报告**：先一句话总评 + 分数档位，再用\"✓/▲/✗ + 一句话 + 修复建议\"逐条列，最后给 **Top 3 最该先改的**（按\"花最小力气补最大漏洞\"排序）。中文输出。\n5. **提出代重构**：问用户要不要直接改（瘦身 SKILL.md、拆 references/、外置 scripts/、把硬路径换成 `~`/相对路径、补 description 触发句）。**得到同意再动文件**，一次改一类、可回退；改完**重跑 `check.py`** 给前后对比分数。\n\n> 不要只把脚本输出原样贴给用户——脚本是线索，你的价值在定性判断 + 具体怎么拆。\n\n---\n\n## 评分标准（12 项 · 也是机检的判分依据）\n\n| # | 检查项 | 合格长什么样 | 不合格信号 |\n|---|--------|------------|-----------|\n| 0 | **无硬编码密钥（安全红线）** | SKILL.md 及捆绑文件无 key/token/私钥/口令明文 | 出现 `sk-`/`AKIA`/私钥块/`password=\"...\"` → **直接 FAIL**（skill 常被分发，泄露面更大）<br>⚠️ 测试夹具目录（`test/ tests/ fixtures/ golden/ snapshots/`）里的命中判 **WARN 不判 FAIL**——安全基准的假密钥是刻意载荷，误报会把红线变成摆设 |\n| 1 | **frontmatter 必填合法** | 有 `name`（小写+连字符 ≤64）+ `description` | 缺 name/description → FAIL；name 含大写/下划线/空格 → WARN |\n| 2 | **description 含「何时用」** | 同时写清\"做什么 + 何时/触发用\"（这是被唤醒的唯一依据） | 只写\"做什么\"不写\"何时用\"；或太短没触发信号<br>⚠️ 机检只判\"有没有信号词\"，判不了准不准 —— 要判准不准走**触发力实测**（工作流 2c） |\n| 2b | **description ≤ 1024 字符** | 在上限内，触发稳定 | 超长，可能被截断 |\n| 3 | **SKILL.md ≤ 500 行** | 路由器不是图书馆，按需加载越短越准 | >500 行；分版本/分平台/长流程全塞一个文件 |\n| 4 | **渐进披露（拆 references/）** | 长内容下沉独立 .md，正文留指针 | 正文很长却没有任何 references 拆分文件 |\n| 4b | **指针无死链** | 引用的 `references/*.md` 等带扩展名的捆绑资源真实存在 | 指针指向不存在的文件（按图索骥扑空） |\n| 5 | **脚本外置 scripts/** | 确定性代码（构建/截图/合成/转换）是 scripts/ 真文件 | 大段可执行代码内联在正文，每次靠模型重打 |\n| 6 | **可移植（无硬编码绝对路径）** | 用 `~`/`$HOME`/相对路径/占位 | 出现硬编码家目录绝对路径——别人装上即失效 |\n| 7 | **allowed-tools 最小化** | 声明本 skill 真正需要的工具 | 不声明（继承全部工具，越权面大）——可选项，低权重 |\n| 8 | **触发方式匹配（model vs user invoked）** | 只靠人手敲名字触发的 skill 设 `disable-model-invocation: true`（零 context load） | 明明只手动触发，却留着 description 当 model-invoked，每轮白占上下文（详见 references/skill-writing-vocab.md 第二节）——定性项 |\n| 10a | **别替模型补它已经会的（no-op 测试）** | 只装项目/品牌私有事实 | 有\"语言入门/框架教程/如何使用\"这类教学段——判据：**这段相对模型默认行为改变了什么？没有就删**（即 no-op；详见 vocab 第六节） |\n| 10b | **配套文档（README+CHANGELOG）** | 对外分发友好 | 缺失——纯自用可忽略，低权重 |\n| 11 | **paths / globs 作用域** | 文件专属 skill 声明 glob，减少误触发 | Cursor 2.4+ 可用；未声明 = INFO |\n| 12 | **OpenClaw 兼容声明** | 有 scripts/ 或发 ClawHub 时声明 requires/install | 纯指令 skill 可忽略——INFO |\n\n**分档**：A 优秀 ≥85 · B 良好 ≥70 · C 及格 ≥50 · D 建议重构 <50。\n（机检：PASS=1 / WARN=0.5 / FAIL=0，INFO 不计分。**按重要度加权**——安全红线 #0 与触发/减法核心项 #1/#2/#3/#4/#6/#10a 权重 1.5，标准项 #2b/#4b/#5/#11 为 1.0，加内容项 #7/#10b/#12 为 0.6。#0 命中按 FAIL 计且资损级，定性总评里应一票顶到「先改这条」。）\n\n---\n\n## 机检的盲区（定性复核时重点纠偏）\n\n脚本只判\"机器能确定的\"，以下几项**容易误判，必须你读正文定夺**：\n\n- **#2 触发质量**：脚本只看 description 里有没有\"当…时/use when\"等信号词，**判不了写得准不准**。你要真的当模型读一遍：这段能不能把本 skill 和别的 skill 区分开？会不会该触发时没触发、不该触发时乱触发？\n  - ⭐ **这条现在能实测，别停在拍脑袋**：走工作流 2c 的 `scripts/trigger_eval.py`，\n    \"会不会该触发时没触发、不该触发时乱触发\"正好对应输出里的**漏触发 / 误触发**两个计数。\n    定性读完有怀疑、或者这个 skill 值得下功夫（常用、要分发、要收费），就跑一轮实测坐实。\n    ⚠️ 但**跑之前先做 A/B 基准自检**（真 description vs 一段写烂的），分不开就别信分数。\n- **#3/#4 篇幅 vs 图书馆**：长不一定错——有的 skill 天生信息密度高。但\"分 3 个视觉版本 × 6 个平台\"这种，多半能按维度拆 references/。读结构判断哪些章节是\"用到才看\"的。\n- **#5 脚本外置**：脚本按代码行数/围栏数猜。一段 5 行的示范片段该留正文；一个 80 行的构建/合成脚本该外置。读代码块的\"性质\"定夺。\n- **#10a 别替模型补它已经会的**：脚本按\"教程/如何使用/语言入门\"措辞猜，**会误伤**——比如正文在写\"本项目**自研**流程的用法\"（模型确实不知道，该留），或在\"反对写教程\"。判据是\"这段知识模型升级后会不会自动变强\"：会→删；不会（项目私有）→留。\n- **本 skill 自检会触发 #10a 误报**：因为正文里就列着\"教程/如何使用\"这些**待检测的黑名单词**——这是元层面的正常现象，定性时直接放行。\n\n> **定性诊断词汇**：做 #2/#3/#4/#8/#10a 这些\"机器判不准\"的项时，读 [`references/skill-writing-vocab.md`](references/skill-writing-vocab.md)——它把\"好 skill\"的判据沉淀成可命名的语言（两种载荷、信息阶梯、branch 拆分测试、完成判据防提前收工、no-op 测试、sediment/sprawl/duplication 失败模式、leading word）。出报告时用这些词点破问题，比泛说\"太长/有冗余\"更准。根判据：**skill 是为榨出确定性而存在，根本美德是「每次走同一套过程」可预测。**\n\n---\n\n## 安全红线（务必遵守）\n\n- **绝不读取密钥文件**：`.env` / `*.key` / `*.pem` / `*secret*` 一律不打开（脚本本身也不读）。\n- 体检是只读操作；**任何文件改动都要先说明改哪些、为什么，得到同意再动**。\n- 跨语言/跨用途通用——本 skill 不绑定任何具体技术栈或 skill 类型。\n\n---\n\n## 修复动作清单（用户同意后按需执行）\n\n- **拔密钥（最高优先）**：#0 命中时把明文移出 SKILL.md / 捆绑文件，改放 `.env` / 密钥管理器；命中即视为已泄露，提醒轮换并查 git 历史（skill 很可能已 push 到 GitHub）。\n- **修触发**：#2 不合格时给 description 补\"何时用\"句——列典型请求 / 触发词 / 适用场景，让模型判得出何时唤醒。\n- **瘦身 + 拆 references/**：#3/#4 不合格时，把 SKILL.md 按「版本/平台/流程」维度抽到 `references/` 下的独立 `.md`，正文回归「精简路由 + 硬规矩 + 索引表」。\n- **外置 scripts/**：#5 命中时把确定性脚本抠成 `scripts/` 真文件，正文只留一行调用说明。\n- **去硬路径**：#6 命中时把硬编码家目录路径换成 `~` / `$HOME` / 相对路径 / 「此 skill 目录」占位。\n- **删教学冗余**：#10a 确认是\"教通用写法/框架用法\"的删掉——skill 只装模型不可能知道的私有事实。\n- **修死链**：#4b 报的死指针——补上缺失文件，或修正/删除指针。\n- 改完**重新跑一次 `check.py`** 给前后对比分数。\n\n---\n\n## 落地骨架（建/重写一个 skill 时的推荐结构）\n\n```\nmy-skill/\n├── SKILL.md              # ≤500 行：frontmatter(name+description触发句) + 元判据 + 硬规矩\n│                         #          + 一张「做 X → 读 references/Y」索引表（路由，不堆细节）\n├── references/           # 渐进披露：按版本/平台/流程拆的专题 .md，用到再读\n│   ├── topic-a.md\n│   └── topic-b.md\n├── scripts/              # 确定性可执行脚本（构建/截图/合成/转换），正文只留指针\n├── assets/               # 字体/图片/模板等捆绑资源\n├── README.md             # 给人看（分发用）\n└── CHANGELOG.md          # 版本记录\n```\n\n> SKILL.md 是路由，不是仓库。判据始终是：**这段值不值得每次触发都进上下文？能下沉就下沉。**\n\nFile v1.5.2:tests/fixtures/bad/SKILL.md\n\n---\nname: BadSkill_Example\n---\n\n# Bad Skill\n\n这是一个演示「不合格 skill」的夹具，故意踩坑：\n\n- name 用了大写 + 下划线（应 kebab-case）。\n- **缺 description**——模型无从判断何时加载本 skill（机检会判 FAIL，退出码 1）。\n- 硬编码了绝对路径 /Users/someone/.claude/skills/x/assets/font.woff2（换台机器就废）。\n\nFile v1.5.2:tests/fixtures/good/SKILL.md\n\n---\nname: example-good-skill\ndescription: >\n  生成示例日报。把一段原始数据整理成一页结构化的示例日报。\n  当需要演示「合格 skill 长什么样」或要一份 demo 日报时使用；\n  use when you need a demo daily report.\nallowed-tools:\n  - Read\n  - Write\n---\n\n# Example Good Skill\n\n一个用于演示「合格 skill」的最小夹具：frontmatter 完整、description 写清了\n做什么 + 何时用、正文精简、无硬编码密钥、无绝对路径。\n\n## 何时用\n\n当用户要一份示例日报，或想看一个达标 skill 的结构时。\n\n## 怎么做\n\n1. 读取用户给的原始数据。\n2. 按「概览 / 明细 / 结论」三段整理。\n3. 输出一页 Markdown 日报。\n\n> 正文只放本 skill 私有的约定；通用写法交给模型自己。\n\nFile v1.5.2:README.md\n\n# hekouwang-claude-skill-doctor-skill\n\n> **会勇禾口王的AI笔记** 出品 · `@huiyonghkw`\n> 不聊 AI 会不会取代你，只聊先用 AI 的人怎么取代你。\n\n给 **Agent Skill（SKILL.md）** 做体检的工具。把\"Skill 是按需加载的指令包、不是单文件巨石\"\n这条最佳实践，做成一个能跑在任何 skill 上的检查器：机检定量 + 模型定性，产出评分卡和可落地的修复建议。\n\n## 30 秒验收\n\n```bash\npython3 check.py path/to/your-skill    # 体检任意 skill 目录\nbash scripts/run-all-doctors.sh .      # 三件套（需已装 md-doctor + env-doctor）\n```\n\n姊妹工具：[`hekouwang-claude-md-doctor-skill`](https://github.com/huiyonghkw/hekouwang-claude-md-doctor-skill)（体检 AGENTS.md / CLAUDE.md）。\n\n## 核心判据\n\n> SKILL.md 是模型\"决定要不要加载、加载后照着做\"的运行时指令包。\n> `description` 决定它何时被唤醒；正文越精简越准；厚重细节要能\"按需展开\"\n> （references/ 用到再读），而不是每次触发就把全部细节灌进上下文。\n\n## 用法\n\n### 在 Claude Code 里（推荐）\n\n直接用**自然语言**喊它，Claude 会自动加载本 skill、在底层跑机检、再做定性复核，给评分卡 + 按优先级的修复建议，并问要不要代为重构：\n\n> - 「帮我体检 `~/.claude/skills/xxx` 这个 skill」\n> - 「我的 SKILL.md 规范吗 / 是不是太长了 / 要不要拆 references」\n> - 「audit this skill」「lint SKILL.md」\n\n### 命令行直接跑（零依赖，仅需 Python 3）\n\n```bash\npython3 check.py <skill目录>          # 输出彩色报告\npython3 check.py <skill目录> --json   # 机器可读 JSON（CI 可用）\n```\n\n退出码：有 FAIL → 1，否则 0（可用于 CI 卡关）。\n\n### Docker（不想装 Python 也能跑）\n\n```bash\n# 拉官方镜像直接用（打 v* tag 时 GitHub Actions 自动发布到 GHCR）\ndocker run --rm -v \"$PWD:/work\" ghcr.io/huiyonghkw/hekouwang-claude-skill-doctor-skill\n\n# 或本地自建\ndocker build -t claude-skill-doctor .\ndocker run --rm -v \"$PWD:/work\" claude-skill-doctor            # 体检挂载的 skill\ndocker run --rm -v \"$PWD:/work\" claude-skill-doctor /work --json\n```\n\n### 接进 CI 卡关（GitHub Actions 示例）\n\n```yaml\n- uses: actions/setup-python@v5\n  with: { python-version: \"3.x\" }\n- name: SKILL.md 体检（不合格则拦 PR）\n  run: |\n    curl -sO https://raw.githubusercontent.com/huiyonghkw/hekouwang-claude-skill-doctor-skill/main/check.py\n    python3 check.py path/to/your/skill\n```\n\n本仓库自身的 CI 见 [`.github/workflows/ci.yml`](.github/workflows/ci.yml)（语法 + good/bad 夹具 + JSON 合法性）。\n\n## 检查项（12 项加权）\n\n| 权重 | 项 |\n|---|---|\n| **1.5（核心）** | 无硬编码密钥 · frontmatter 必填合法 · description 含「何时用」 · SKILL.md ≤500 行 · 渐进披露(拆 references/) · 可移植(无硬编码绝对路径) · 别替模型补它已会的 |\n| 1.0（标准） | description ≤1024 · 指针无死链 · 脚本外置 scripts/ |\n| 0.6（加内容） | allowed-tools 最小化 · 配套文档(README+CHANGELOG) |\n\n分档：A ≥85 · B ≥70 · C ≥50 · D <50。\n\n## 机检 vs 定性\n\n`check.py` 只判机器能确定的部分。**description 触发得准不准、正文是不是\"图书馆\"、\n是不是在替模型补它已会的知识**——这些要人/模型读正文复核（脚本会标出疑点）。\n完整定性流程见 `SKILL.md`。\n\n## 免费 / 付费\n\n| | 免费（开源） | 付费增值 |\n|---|---|---|\n| 机检 | `check.py` 文本/JSON + ASCII 评分条 | 品牌可视化报告卡 |\n| CI | 退出码卡关 | — |\n| 联系 | GitHub Issue | **@huiyonghkw**（ClawHub / GitHub） |\n\n- **免费**：`check.py` 的文本 / JSON 报告 + 评分，随便用、可进 CI。\n- **付费增值**：品牌可视化体检报告卡（精美分享图），找 `@huiyonghkw`。\n\n## 体检器三件套\n\n[`md-doctor`](https://github.com/huiyonghkw/hekouwang-claude-md-doctor-skill) · [`env-doctor`](https://github.com/huiyonghkw/hekouwang-env-doctor-skill) · 一键 `bash scripts/run-all-doctors.sh`（见 `references/doctor-suite.md`）。\n\n---\n\n—— 会勇禾口王的AI笔记 · @huiyonghkw\n\nFile v1.5.2:_meta.json\n\n{\n  \"ownerId\": \"kn73qd1gcmjr446mwcbdxef70x82vxcw\",\n  \"slug\": \"hekouwang-claude-skill-doctor-skill\",\n  \"version\": \"1.5.2\",\n  \"publishedAt\": 1786534620717\n}\n\nFile v1.5.2:references/doctor-suite.md\n\n# hekouwang-doctor-suite · 体检器三件套\n\n> 竞品多是单点；这套把「项目配置 → 技能包 → 本机环境」串成一条验收链。\n\n```\nhekouwang-doctor-suite（概念）\n├── md-doctor      → AGENTS.md / CLAUDE.md（运行时配置）\n├── skill-doctor   → SKILL.md（Agent 技能包）\n└── env-doctor     → 磁盘 / 版本管理器 / AI 宿主目录\n```\n\n## 一键跑\n\n```bash\nbash scripts/run-all-doctors.sh /path/to/your-project\n```\n\n（脚本在 `hekouwang-claude-md-doctor-skill`；`skill-doctor` / `env-doctor` 仓内各有一份相同副本。）\n\n## 建议顺序\n\n1. **md-doctor** — 根配置是否「路由器」而非「图书馆」\n2. **skill-doctor** — `.agents/skills/` 下各 skill 是否按需加载\n3. **env-doctor** — 本机是否留着已换掉的 nvm / 膨胀的 AI 缓存\n\n## 免费 vs 付费\n\n| | 免费（开源） | 付费增值 |\n|---|---|---|\n| 机检 | `check.py` / `scan.sh` 文本报告 + JSON | 品牌可视化报告卡（评分弧 + 等级带） |\n| CI | 退出码卡关 | — |\n| 联系 | GitHub Issue / PR | ClawHub **@huiyonghkw** |\n\nFile v1.5.2:references/skill-writing-vocab.md\n\n# Skill 写作词汇与进阶判据（定性复核时用）\n\n这套词汇消化自 mattpocock/skills 的 `writing-great-skills`。它给\"什么是好 skill\"补了一层**可命名的诊断语言**——体检时用这些词点破问题，比泛泛说\"太长/有冗余\"更准、更可落地。\n\n> 一句话根：**skill 存在是为了从随机系统里榨出确定性。根本美德是「可预测」——每次运行走同一套*过程*（不是产出同一结果）。下面每条判据都为它服务。**\n\n## 一、两种\"载荷\"——这是\"减法\"的底层账\n\n- **context load（上下文载荷）**：model-invoked skill 的 `description` 每轮都待在上下文窗口里，是持续成本。正文越长，每次触发付的越多。\n- **cognitive load（认知载荷）**：user-invoked skill 不进模型视野，只靠**你**记得它存在——成本转嫁到人脑。\n- 当 user-invoked skill 多到记不住，就用一个 **router skill**（一个 user-invoked skill 列出其余的\"何时用哪个\"）来治认知载荷。\n\n## 二、触发方式：model-invoked vs user-invoked（体检新增维度 #8）\n\n- **model-invoked**（默认，省略 `disable-model-invocation`）：保留 description，模型能自主触发、别的 skill 也能调到它。代价是 context load。\n- **user-invoked**（设 `disable-model-invocation: true`）：description 变成给人看的一行摘要，模型够不到，**零 context load**。\n- **判据**：这个 skill 是不是**只可能靠人手敲名字**触发？若是 → 该设 user-invoked，别让它的 description 白占每轮上下文。只有\"模型必须自己判断何时唤醒\"或\"别的 skill 要调它\"时，才值得付 model-invoked 的常驻成本。\n\n## 三、信息阶梯（progressive disclosure 的标尺）\n\n三级，按\"模型多急需\"排：① **in-skill step**（SKILL.md 里的有序动作）② **in-skill reference**（按需查的定义/规则，可以是一组平级规则，不是坏味道）③ **external reference**（推到独立文件、靠 context pointer 触发才加载）。\n\n- **branch（分支）= 最干净的拆分测试**：每个分支都要的 → 内联；只有部分分支会走到的 → 推到指针后面。\n- **co-location（就近）**：一个概念的定义+规则+注意事项放同一标题下，别散落。\n- **context pointer 的措辞**（不是它指向哪）决定模型何时、多可靠地去读那块。\n\n## 四、完成判据（completion criterion）——防\"提前收工\"\n\nstep 类 skill 的每一步要以一个**可检验**的完成条件收尾（模型能分辨\"做完了 vs 没做完\"）；关键处还要**穷尽**（\"每个改过的模型都交代了\"，而不是\"产出一个变更清单\"）。判据含糊 → 招致 **premature completion**（注意力滑向\"算完成了\"而提前结束）。\n\n## 五、leading word（引导词）\n\n一个模型预训练里已有的**紧凑概念**（如 _tight / red / tracer bullets_），在文里复用，用极少 token 锚定一整片行为。两处获益：正文里锚定**执行**（一见这词就走同一行为），description 里锚定**触发**（你 prompt/文档/代码里都用这词，模型更可靠地联想到该 skill）。把\"快、确定、低开销\"这种三词重述坍缩成一个 _tight_——既省 token 又给模型更锐的挂钩。体检时主动找\"能被一个引导词退休掉的重述\"。\n\n## 六、失败模式词汇（诊断用，点名比泛指有力）\n\n- **premature completion**：步骤没真做完就收。先磨锐完成判据（便宜、就地）；判据已无法再细化且确实观察到抢跑，才用\"按序列拆分\"把后续步骤藏起来。\n- **duplication**：同一意思出现在多处。费维护、费 token，还把它在阶梯上的\"显要度\"抬高过真实等级。守则：每个意思**单一真相源**，改行为只改一处。\n- **sediment（沉积）**：旧内容层层留下——\"加着安全、删着危险\"的默认结局。没有修剪纪律的 skill 必然积沉。\n- **sprawl（臃肿）**：纯粹太长，即便每行都还活着且唯一。解药是阶梯：reference 推到指针后、按 branch/序列拆，让每条路径只背自己要的。\n- **no-op（空操作）**：模型默认就会做的话，付了载荷却没说事。**测试：这行相对默认行为改变了什么？没有 → 删**。弱引导词（\"要认真\"而模型本就够认真）就是 no-op，修法是换更强的词（\"relentless\"），不是换技巧。\n\n## 修剪纪律\n\n逐**句**（不是逐行）跑 no-op 测试：某句在孤立状态下不改变行为 → **整句删掉**，别只删词。要狠——失败的散文多数该删，不是重写。\n\nFile v1.5.2:references/trigger-eval.md\n\n# 触发力实测（trigger eval）· 怎么设计 query、怎么读结果\n\n> 机检 #2 只能看出 description 里**有没有**\"当…时/use when\"这类信号词，判不出**写得准不准**。\n> 这份文档配 `scripts/trigger_eval.py`，补的是那一层：真跑一遍，看模型会不会被这段 description 唤醒。\n> ⚠️ 需要 `claude` CLI，**会产生真实费用**（每条 query 每次采样约 $0.09–0.15）。\n> `check.py` 不依赖它，零依赖那条卖点不受影响。\n\n## 0. ⭐ 跑之前必做：基准分辨力自检（不做就别信任何分数）\n\n**先喂一个已知好的和一个已知烂的，看分数分不分得开。** 分不开说明这套判据在你的环境里失灵，\n此时任何分数都是噪音——包括那个看起来很健康的高分。\n\n```bash\n# A 组：真 description\npython3 scripts/trigger_eval.py --eval-set queries.json --skill-path <skill> --label A\n\n# B 组：同一套 query，换一段故意写烂的 description\nprintf '生成内容。\\n' > /tmp/bad-desc.txt\npython3 scripts/trigger_eval.py --eval-set queries.json --skill-path <skill> \\\n  --description-file /tmp/bad-desc.txt --label B\n```\n\n**判据**：A 明显高于 B（实测参考：A=100 / B=50，4 条 query）才算这套 eval 在你机器上有效。\n两组同分 = 判据失灵，先去查第 4 节。\n\n> 这不是形式主义。开发本脚本时，前后四处配置错误里有**三处**都表现为\n> \"跑通了、只是分数低\"——不做 A/B 根本发现不了，会拿一堆假分数去改 description。\n\n## 1. eval query 怎么写\n\n**数量**：20 条左右，正例 8–10、负例 8–10。想省钱可以先用 4–6 条粗筛，方向对了再补齐。\n\n**质量三条**：\n\n1. **写成用户真会打出来的一整段话**，不是抽象任务名。要有具体文件名、路径、栏目名、\n   数字、背景交代，可以有口语、缩写、错别字、全小写。\n   - ❌ `\"生成小红书图文\"`\n   - ✅ `\"帮我把这篇讲 uv 的文章做成一套小红书图文，8 张 1080x1440，用 V2 米白那套视觉，封面要有数字锚点\"`\n\n2. **正例要覆盖不同说法**。同一个意图，有正式的、有随口的；**要有几条不点名品牌/不提专有名词**\n   的（\"我写完一篇稿子想发公众号，帮我出文章母本和配图\"）——这类最能检验 description\n   有没有把使用场景说清楚，而不是靠关键词硬碰。\n\n3. ⭐ **负例必须是 near-miss**。共享关键词或概念、但其实该走别的工具的请求，才有检验力。\n   - ❌ `\"帮我写个快排\"`（对内容工厂来说太远，测不出任何东西）\n   - ✅ `\"帮我给这个 React 项目做个好看的产品落地页\"`（同样是\"做视觉\"，但属前端）\n   - ✅ `\"帮我看下上周几篇小红书笔记数据，哪篇曝光最高\"`（提了小红书，但是数据分析）\n\n**别用的 query**：一步就能做完的简单请求（\"读一下这个文件\"）。模型对自己就能轻松搞定的事\n本来就不查 skill，这种用例无论 description 写得多好都不会触发，纯粹浪费钱。\n\n格式：\n\n```json\n[\n  {\"query\": \"……\", \"should_trigger\": true,  \"note\": \"正1·核心场景\"},\n  {\"query\": \"……\", \"should_trigger\": false, \"note\": \"负1·near-miss 同是做视觉但属前端\"}\n]\n```\n\n## 1.5 ⭐ 负例必须带干扰项跑，否则结论是假的\n\n探针环境默认**只有被测 skill 一个候选**。模型 `ls` 完发现没别的可选，\n就会勉强用手头这个——**负例于是系统性假阳性**。\n\n实测（content-factory · 同一套 6 条 query · 同一段 description）：\n\n| 环境 | 得分 | 那条\"翻页演示版网页\"负例 |\n|---|---|---|\n| 无竞争者 | **83**（5/6） | ✗ 误触发 |\n| 放 5 个兄弟 skill 当竞争者 | **100**（6/6） | ✓ 正确避开 |\n\n**同一段 description，什么都没改，分数差 17 分。** 按 83 分那个数字去\"修边界\"，\n修的是一个不存在的问题。\n\n```bash\npython3 scripts/trigger_eval.py --eval-set queries.json --skill-path <skill> \\\n  --distractors ~/.claude/skills/其它skill-A ~/.claude/skills/其它skill-B ...\n```\n\n选谁当干扰项：**功能相邻、最可能抢活的那几个**。自己有一套 skill 的话，\n把兄弟们全带上最省事，也最接近真实环境。\n\n⚠️ **干扰项的名字也被中性化成 `alt-xxx`，这是故意的**。若让干扰项挂真名\n（`yandu-deck` 之类）而被测探针挂中性名，模型光看名字就能认出干扰项，\n等于给对手开外挂——测出来的仍旧是名字不是 description，跟第 4 节第 4 条同一个坑。\n\n> 正例也别忘了看：竞争者在场时正例**仍应触发**。若加了干扰项后正例掉了，\n> 说明 description 的区分度不够，被邻居抢走了——这才是真该改的信号。\n\n## 2. 怎么读结果\n\n分数只是入口，**两种失败要分开看，修法完全不同**：\n\n| 症状 | 含义 | 怎么改 description |\n|---|---|---|\n| **漏触发**（该触发的没触发） | 覆盖面不够，用户换个说法就唤不醒 | 补场景句和同义说法；把用户真实的口语表达写进去 |\n| **误触发**（不该触发的触发了） | 写太宽泛，抢别的工具的活 | 加边界（\"不用于 X\"）；把泛词换成具体动作与产物 |\n\n同时出现两种 = description 抓错了维度，重写而不是打补丁。\n\n采样次数：默认 `--runs-per-query 1` 省钱。触发是概率性的，要下正式结论用 `3`\n（成本 ×3），此时触发率 ≥0.5 判通过。\n\n## 3. 结果不对劲时\n\n先用 `--dump-dir` 把原始流存下来翻，**别猜**：\n\n```bash\npython3 scripts/trigger_eval.py ... --dump-dir /tmp/dumps\n```\n\n翻的时候重点看两样：模型的**工具调用序列**（它到底做了什么），\n以及 Skill/Read 调用里的**实际参数**（是不是调到了别的东西）。\n本脚本历史上两次假阴性都是靠翻这个抓出来的。\n\n## 4. 脚本为什么这么写（改它之前先读这节）\n\n本脚本改自官方 `anthropics/skills · skill-creator/scripts/run_eval.py`。\n官方思路对，但原样跑在 Claude Code 2.1.220 上**测不出任何东西**。四处都改完才有分辨力——\n**这四处是踩出来的，改脚本时别顺手改回去**：\n\n1. **`--setting-sources project`**：不加则子进程继承 `~/.claude/skills/` 里已装的真 skill\n   （实测 32 个），模型去触发真身、名字对不上探针 → 全部正例假阴性。\n   官方没料到\"被测 skill 已经装在机器上\"这种情况。\n\n2. **扫完整个流才判否**：官方是\"第一个 tool_use 不是 Skill/Read 就 return False\"。\n   但模型碰到陌生 skill 名**会先 `Bash: ls` 探查环境**，Skill 往往是第二三个动作\n   （实测序列 `['Bash','Bash','Skill']`）——真触发了却被判没触发。\n\n3. **每条 query 独立 project root**：共用目录时并发 worker 把探针全丢一处，\n   模型会调到**别人的**探针（实测：期望 `-d795b59f`，实际调 `-4ac07ae5`），自己这条判否。\n\n4. ⭐ **探针要装成 project 级真 skill，且名字中性（`probe-xxxxxxxx`）**：\n   init 事件里 `skills` 和 `slash_commands` 两个列表**都只给名字、不给 description**。\n   探针一旦沿用原 skill 名，模型光看名字就去 Read 它，**description 全程没参与决策**——\n   实测此时 447 字真 description 和 5 字\"生成内容。\"**都是满分**，等于白测。\n\n## 5. 成本\n\n| 规模 | 调用数 | 约合 |\n|---|---|---|\n| 粗筛 4 条 × 1 次 | 4 | $0.5 |\n| 正式 20 条 × 1 次 | 20 | $2–3 |\n| 结论 20 条 × 3 次 | 60 | $6–9 |\n\n先粗筛、方向对了再上规模。A/B 基准自检要算两轮。\n\nFile v1.5.2:CHANGELOG.md\n\n# Changelog\n\n本项目遵循 [语义化版本](https://semver.org/lang/zh-CN/)。\n\n## [1.5.2] - 2026-08-12\n\n### 变更\n- ClawHub 分类：`development`\n\n## [1.5.1] - 2026-08-12\n\n### 新增\n- `scripts/run-all-doctors.sh`、`references/doctor-suite.md`（与 md-doctor / env-doctor 同版）\n\n### 变更\n- `check.py`：付费报告卡 CTA；README 30 秒验收 + 免费/付费表 + 三件套互链\n- summary 补英文 SEO 关键词（skill lint / SKILL.md doctor）\n\n## [1.5.0] - 2026-08-12\n\n### 新增\n- **#11 paths / globs**：识别 Cursor 2.4+ 文件作用域 frontmatter，减少无关文件时的误触发。\n- **#12 OpenClaw 兼容声明**：轻量检查 `metadata.openclaw`、`requires`、`install`（有 scripts/ 时提示）。\n\n### Fixed\n- **指针扫描误报**：只匹配带扩展名的捆绑资源路径（`references/foo.md`），表格里的\n  `references/scripts/assets` 不再被判死链。\n- **可移植性自检误报**：`ABS_PATH_RE` 用字符串拼接构建，避免 `check.py` 源码里的\n  正则说明行被当成硬编码路径。\n- **#10a 元层面误报**：评分表/检查项表格行里的黑名单示例词不再计为教学冗余。\n\n## [1.4.1] - 2026-08-01\n\n修 #0 安全红线的两处假阳性。**假阳性会让红线失去意义**——被误报训练过的人下次看到真 FAIL 也只会挥手放过。\n\n### Fixed\n- **`sk-` 密钥正则缺左词界**：`sk-(?:ant-)?[\\w-]{20,}` 会从 `generate-ask-user-format.ts`\n  里抠出 `sk-user-format` 判成 key。同一份 `SECRET_PATTERNS` 里 `AKIA` / `AIza` / `JWT`\n  三条都带 `\\b`，只有这条漏了。实测某第三方 skill 因此被判资损级 FAIL（62 分），\n  命中源全是 `ask-user-*` 文件名。\n- **测试夹具里的假密钥降级 WARN**：安全基准/回归夹具（`test/ tests/ fixtures/ golden/ snapshots/`\n  等目录）里的 key 是刻意载荷，不是泄露。现在只在夹具命中时判 WARN 并提示\"翻一眼确认\"，\n  正文/脚本命中照旧 FAIL；两类同时命中时 FAIL 优先，detail 里标明夹具那几处已降级。\n\n### 验证（A/B 基准分辨力自检）\n三类样本必须判出三种结果，否则说明改完的判据分不开对和错：\n真密钥 `sk-proj-…` → **FAIL**；夹具里 `sk-ant-api03-…` → **WARN**；`ask-user-question-format` → **PASS**。\n回归夹具分数不变（`tests/fixtures/bad` 67、`good` 100）。\n\n## [1.4.0] - 2026-07-28\n\n补上本器最大的盲区：**#2 触发质量以前只能拍脑袋，现在能实测**。\n静态检查只看得出 description 里有没有\"当…时\"这类信号词，判不了写得准不准——\n而 description 写不准 = 这个 skill 永远不被唤醒，正文写得再好也白搭。\n\n### Added\n- **`scripts/trigger_eval.py` · 触发力实测（可选第二引擎）**：把待测 description 装成临时探针 skill，\n  跑 `claude -p` 看模型会不会去调它，输出触发力分数 + **漏触发 / 误触发**两个计数。跑完即删，\n  不碰任何已装的 skill。改自官方 `anthropics/skills · skill-creator/run_eval.py`。\n- **`--distractors` 干扰项**：把其它 skill 的 description 一起放进探针环境当竞争者。\n  不加的话环境里只有被测探针一个候选，模型\"没得选\"就会勉强用它，**负例系统性假阳性**。\n  实测同一段 description、同一套 query：无竞争者 **83 分**（那条\"翻页演示版\"负例误触发），\n  放 5 个兄弟 skill 后 **100 分**（正确避开）——**什么都没改，差 17 分**。\n  按 83 分去修边界，修的是一个不存在的问题。\n  干扰项名字同样中性化成 `alt-xxx`，否则模型看名字就能认出对手，等于开外挂。\n- **`references/trigger-eval.md`**：query 怎么设计（**负例必须是 near-miss**）、\n  **负例必须带干扰项跑**、两种失败各自怎么改 description、结果不对劲怎么翻原始流、成本表。\n- 工作流新增步骤 **2c**；检查项 #2 与「机检的盲区」#2 同步改写。\n\n### Changed\n- 免费/付费边界补一档：`trigger_eval.py` **脚本开源随便用，但 API 费用走用户自己的额度**\n  （约 $0.09–0.15/次调用）。因此它是**可选叠加档、不进默认流程**，\n  `check.py` 的零依赖卖点不受影响，不跑也能出完整体检报告。\n\n### 踩坑记录：官方脚本原样搬过来测不出任何东西\n\n官方那版思路对，但在 Claude Code 2.1.220 上四处全错，**改完才有分辨力**\n（实测：真 description 100 分 vs \"生成内容。\"50 分；不改第 4 条时两者都是 100，等于白测）。\n四处里**前三处都表现为\"跑通了、只是分数低\"**，不做 A/B 基准根本发现不了：\n\n1. 不加 `--setting-sources project` → 子进程继承 `~/.claude/skills/` 里已装的真 skill（实测 32 个），\n   模型触发真身、名字对不上探针 → **全部正例假阴性**。官方没料到\"被测 skill 已装在机器上\"。\n2. 官方\"第一个 tool_use 不是 Skill/Read 就判否\" → 但模型碰到陌生 skill 名**会先 `Bash: ls` 探查**，\n   Skill 往往是第二三个动作（实测序列 `['Bash','Bash','Skill']`）。改为扫完整个流、命中即收工。\n3. 并发 worker 共用一个 project root → 模型调到**别人的**探针\n   （实测：期望 `-d795b59f`，实际调 `-4ac07ae5`）。改为每条 query 一个一次性 root。\n4. ⭐ 探针放 `.claude/commands/` 且沿用原 skill 名 → init 事件里 `skills` / `slash_commands`\n   两个列表**都只给名字、不给 description**，模型光看名字就去 Read 它，\n   **description 全程没参与决策**。改为装成 project 级真 skill + 中性名 `probe-xxxxxxxx`。\n\n⭐ 因此文档把「**先做 A/B 基准分辨力自检，分不开就别信分数**」写成了跑之前的强制前置步骤，\n不是建议。\n\n## [1.3.0] - 2026-07-15\n\n**版本号说明**：本次内容即原定的 1.2.0（见下方 Changed/Added），因发布事故改号为 1.3.0——\nClawHub 上 `hekouwang-claude-skill-doctor-skill` 这个 slug 于 2026-07-09 被误发成 **md-doctor 的内容**\n并占用了 1.2.2 这个版本号（check.py 与 md-doctor 逐字节同 hash `5f0d3613`、测试夹具是 `CLAUDE.md`\n而非 `SKILL.md`）。该 slug 在 2026-06-24 的 1.0.2 / 1.0.3 是正确的 skill-doctor 内容，\n即**误发覆盖了正确版本**。需发一个高于 1.2.2 的版本才能把 latest 拨正，故跳到 1.3.0。\n误发的 1.2.2 已从该 slug 永久删除，版本史现为 1.0.2 → 1.0.3 → 1.3.0。\n\n### Fixed\n- **ClawHub 发布事故更正**：`hekouwang-claude-skill-doctor-skill@1.2.2` 实为 md-doctor，已删除；\n  latest 拨回真正的 Agent Skill 体检器。\n- **发布纪律**：以后 `clawhub skill publish` **一律显式传 `--version`**——\n  ClawHub 不读 SKILL.md 的 `version`，只在线上版本上 +1（实测会把本地 1.2.2 发成 1.1.3、\n  本地 1.1.0 发成 0.1.2，即**降级**）。自动推断不可信。\n\n拿真数据校准步骤 2b 的 SkillSpector。全量扫 7 个 `hekouwang-*` skill、逐条翻源码核实，\n结论推翻 1.1.0 的乐观假设：**对自研 skill 它 100% 误报**，且**分数完全不可信**。\n2b 从\"可选加跑的安全维\"收紧为\"只对外来 skill 跑的入库审查\"。\n\n### Changed\n- **2b 定位收紧：只对\"别人写的、要装进来的\" skill 跑。** 7 个自研 skill 全扫、逐条翻源码，\n  无一为真。自研 skill 改走**回归检测**（存基线 → 只看 NEW），不再全量看告警。\n- **新增铁律「分数不是门禁，只看条目 + 翻源码」。** `Score/Severity` 是逐条**累加**的：\n  yandu-deck / iterm2 / cc-prod 三个判 `100/100 CRITICAL · DO NOT INSTALL`，\n  但报告里**一条 CRITICAL 发现都没有**——纯粹是十几条 MEDIUM/HIGH 累加撞顶。\n  且评分随版本通胀：content-factory 代码一行没改，v2.3.5 `19/100 SAFE` → v2.3.13 `40/100 CAUTION`。\n- **推翻 1.1.0 的「低可信度才是误报」说法**：95% 高可信度的照样是误报。改为附**高置信度误报样本表**：\n  `rm -f \"$写死路径\"` → `TM1` 95%；`subprocess.run([...], check=True)` 硬编码列表 →\n  `OH1 Unvalidated Output Injection` 95% + `AST4`（其 remediation 建议的恰恰就是这个写法）；\n  docstring 写\"本脚本**绝不读取** .env/*.key\" → `PE3 Credential Access`；\n  字体文件名列表 → `MP2 Context Window Stuffing`；中文 frontmatter → `P2 Hidden Instructions` 21%；\n  中文触发词 → `AS3 Mixed script`。\n\n### Added\n- **rsync `--exclude` 顺序坑**：必须排在 `--include='*/'` 前面（rsync 首次匹配生效，\n  否则 `*/` 先吃掉 `.venv/`，整个 site-packages 被当自己的代码扫）。实测 stock-data-reader 264M→176K。\n- **SOCKS 代理绕法**：代理下扫描直接崩（`'socksio' package is not installed`），\n  需 `env -u ALL_PROXY -u all_proxy -u HTTPS_PROXY -u https_proxy`。OSV.dev 连不上只降级静态库，不影响结论。\n- **`--baseline` 正确用法 + 反例**：`fingerprints` 按「路径+内容 hash」锁定、只对同一 skill 生效；\n  能跨 skill 的 glob `rules`（如 `id: \"TM1\"`）**恰恰不能在扫外来 skill 时开**——\n  同一规则在自研 `rm` 上是误报、在恶意 skill 里可能是真的，全局关掉等于拆探头。\n- content-factory / yandu-deck / stock-data-reader 三个常改的 skill 各存一份归零基线\n  （`.skillspector-baseline.yaml`，A/B 验证：yandu-deck `100 CRITICAL DO_NOT_INSTALL` → `0 LOW SAFE`）。\n- 记录唯一有信号的结构性告警 **LP1「代码有 network/env/shell 能力但没声明权限」**（7 个中 5 个命中）——\n  不是漏洞，与 `check.py` 自检的「未声明 allowed-tools」指向同一缺口。\n\n## [1.1.0] - 2026-06-24\n\n接入外部安全扫描、消化业界 skill 写作最佳实践，扩展体检维度。\n\n### Added\n- **工作流新增步骤 2b · 深度安全扫描（可选）**：叠加 [NVIDIA SkillSpector](https://github.com/NVIDIA/skillspector)，\n  覆盖提示注入 / 数据外泄 / 隐藏指令 / 供应链 / 过度授权 / MCP 越权等 68 类模式，\n  补 `check.py` #0 密钥正则之外的深度安全维。含实战铁律：**只扫逻辑文件、别扫 assets**\n  （直接扫会把字体/图片二进制当代码，刷出几十条假 `TM1 Tool Parameter Abuse`）；\n  低可信度（<30%）`Hidden Instructions` 多是中文/零宽字符误报，人工复核。\n- **评分维度 #8 触发方式匹配（model vs user invoked）**：只靠人手敲名字触发的 skill\n  应设 `disable-model-invocation: true`，省掉每轮 `description` 的 context load。\n- **`references/skill-writing-vocab.md`**：消化 mattpocock/skills 的 *writing-great-skills*，\n  把\"好 skill\"的判据沉淀成可命名的诊断词汇——两种载荷（context/cognitive load）、\n  信息阶梯、branch 拆分测试、完成判据（防 premature completion）、no-op 测试、\n  sediment/sprawl/duplication 失败模式、leading word。出报告时用这些词点破问题。\n\n### Changed\n- **#10a 锐化为 no-op 测试**：判据明确为「这段相对模型默认行为改变了什么？没有就删」，\n  比原先\"别替模型补它已经会的\"更可操作。\n\n## [1.0.2] - 2026-06-22\n\n实战体检三个品牌 skill 时暴露的机检缺陷修复（dogfooding）：\n\n### Fixed\n- **#7 allowed-tools 兼容逗号字符串**：原先只认 YAML 列表（`- a` / `[a,b]`），\n  把官方 frontmatter 标准的逗号字符串写法（`allowed-tools: Bash, Read, Write`）\n  误判为「未声明」。现在两种写法都解析、非空即 PASS。\n\n## [1.0.1] - 2026-06-21\n\n实战体检 14 个 skill 时暴露的两个机检缺陷修复（dogfooding）：\n\n### Fixed\n- **glob 指针不再误报死链**：`reference/deck-engine-*.html` 这类通配符指针，\n  现在用 `glob` 解析、能匹配到真实文件就算存在；`{a,b}` brace 简写跳过不误报。\n  （原正则在 `*` 处截断成 `reference/deck-engine-`，当字面路径判死。）\n- **指针 / 教学词行号还原为文件绝对行号**：原先报的是正文相对行号（少算了\n  frontmatter 行数），定位会偏。`parse_frontmatter` 现返回 `body_offset` 补正。\n\n## [1.0.0] - 2026-06-21\n\n首个版本。给 Agent Skill（SKILL.md）做体检的零依赖检查器。\n\n### 检查项（12 项加权）\n- **安全**：SKILL.md 及捆绑文件无硬编码密钥（命中即 FAIL，资损级）。\n- **触发**：frontmatter 必填合法（name/description）；description 含「何时用」且 ≤1024 字符。\n- **减法**：SKILL.md ≤500 行；长内容下沉 references/（渐进披露）；大段脚本外置 scripts/。\n- **可移植**：无硬编码 `/Users/`、`/home/` 绝对路径。\n- **取舍**：别替模型补它已会的（教学冗余检测）；allowed-tools 最小化；配套 README/CHANGELOG。\n\n### 特性\n- 零依赖（Python3 标准库），文本 + `--json` 双输出，退出码随 FAIL。\n- 按重要度加权评分（触发/减法核心项 1.5，标准项 1.0，加内容项 0.6），A/B/C/D 分档。\n- 极简零依赖 frontmatter 解析（块标量 / 行内 list / 缩进 list）。\n- 密钥扫描双档豁免：指纹型用窄填充表、赋值型用宽占位表，避免误杀真 key。\n- 报告口吻与署名沿用「会勇禾口王的AI笔记」品牌人设。\n\nFile v1.5.2:skill-card.md\n\n## Description:\n\nChecks Claude and Agent Skill packages for SKILL.md best-practice alignment, including trigger quality, length, progressive disclosure, externalized scripts, portability, and hardcoded secret risks, then produces a scorecard and prioritized repair guidance.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[huiyonghkw](https://clawhub.ai/user/huiyonghkw)\n\n### License/Terms of Use:\n\nMIT\n\n## Use Case:\n\nDevelopers and skill maintainers use this skill to audit Claude and Agent Skill directories, identify trigger, structure, portability, and safety issues, and receive prioritized repair guidance or proposed refactors.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The bundled scripts/run-all-doctors.sh can broaden a skill audit into local environment checks when explicitly run.\n\nMitigation: Review the command sequence and target path before running the script, and run it only in a workspace where local environment inspection is intended.\n\nRisk: The optional trigger evaluation script invokes the Claude CLI, uses the current process environment, and can consume user quota.\n\nMitigation: Review scripts/trigger_eval.py before use, run it deliberately with a small evaluation set first, and confirm cost and environment assumptions before larger runs.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/huiyonghkw/skills/hekouwang-claude-skill-doctor-skill)\n- [Project homepage](https://github.com/huiyonghkw/hekouwang-claude-skill-doctor-skill)\n- [Doctor suite reference](references/doctor-suite.md)\n- [Skill writing vocabulary](references/skill-writing-vocab.md)\n- [Trigger evaluation guide](references/trigger-eval.md)\n- [NVIDIA SkillSpector](https://github.com/NVIDIA/skillspector)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, JSON, Code, Shell commands, Guidance]\n\n**Output Format:** [Markdown and plain-text scorecards, optional JSON reports, and proposed file edits or shell commands.]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [The default checker is local and zero-dependency; optional trigger evaluation invokes the Claude CLI and can consume user quota.]\n\n## Skill Version(s):\n\n1.5.2 (source: frontmatter, changelog released 2026-08-12, ClawHub release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.5.2:LICENSE\n\nMIT License\n\nCopyright (c) 2026 huiyonghkw (会勇禾口王的AI笔记)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\nArchive v1.5.1: 15 files, 52826 bytes\n\nFiles: CHANGELOG.md (13344b), check.py (32096b), Dockerfile (804b), LICENSE (1096b), README.md (4226b), references/doctor-suite.md (1118b), references/skill-writing-vocab.md (4701b), references/trigger-eval.md (7753b), scripts/run-all-doctors.sh (3290b), scripts/trigger_eval.py (16245b), skill-card.md (2535b), SKILL.md (20641b), tests/fixtures/bad/SKILL.md (379b), tests/fixtures/good/SKILL.md (802b), _meta.json (154b)\n\nFile v1.5.1:SKILL.md\n\n---\nname: hekouwang-claude-skill-doctor-skill\nslug: hekouwang-claude-skill-doctor-skill\ndisplayName: Claude Skill 体检器（SKILL.md Doctor）\nsummary: Agent Skill lint / SKILL.md doctor / skillspec audit — description 触发、渐进披露、可移植性与 OpenClaw 兼容检查。姊妹工具 md-doctor。\nlicense: MIT-0\nhomepage: https://github.com/huiyonghkw/hekouwang-claude-skill-doctor-skill\nversion: 1.5.1\ndescription: >\n  会勇禾口王的AI笔记 · Agent Skill（SKILL.md）体检器。检查一个 Claude/Agent Skill 是否\n  符合\"按需加载的指令包，不是单文件巨石\"的最佳实践——评 description 触发质量、SKILL.md\n  篇幅、渐进披露（references/ 拆分）、脚本外置、可移植性（无硬编码绝对路径）、安全（无硬编码\n  密钥），给出评分卡 + 按优先级的修复建议，并可代为重构。触发：用户说「检查我的 skill /\n  SKILL.md 体检 / 这个 skill 规范吗 / claude-skill-doctor / audit skill / lint SKILL.md /\n  我的 skill 太长了 / skill 拆分 / 看看我的 skill 合不合规 / skill 对齐官方规范」。\n  任何\"评估/审查/优化某个 Agent Skill 质量或结构\"的请求都应触发。\n---\n\n# hekouwang-claude-skill-doctor-skill · Agent Skill 体检器\n\n> **会勇禾口王的AI笔记** 出品 · `@huiyonghkw`\n> _不聊 AI 会不会取代你，只聊先用 AI 的人怎么取代你。_\n\n把\"Agent Skill 最佳实践\"做成一个能跑在任何 skill 上的检查器：机检定量 + 模型定性，\n产出评分卡和可落地的修复建议。核心判据一句话——\n\n> **SKILL.md 是模型\"决定要不要加载、加载后照着做\"的运行时指令包。`description` 决定它何时被唤醒；正文越精简越准；厚重细节要能\"按需展开\"（references/ 用到再读），而不是每次触发就把全部细节灌进上下文。**\n> 一切检查项都从这句推导：这段内容值不值得在 skill 每次触发时都付一次上下文费？能不能下沉到 references/ 用到再读？\n\n### 触发优先 + 减法优先（元判据 · 凌驾全部检查项之上）\n\nSkill 的命脉是两条，权重最高：\n\n1. **触发**：`description` 是模型唯一用来判断\"何时唤醒本 skill\"的信号。写不清\"何时用\"，再好的正文也永远不被加载。\n2. **减法**：SKILL.md 不是图书馆。模型每代都在变强——你塞进正文的通用写法、框架教程、临时脚本，很快既过时又白占 token。**能下沉 references/ 的下沉，能外置 scripts/ 的外置，模型已经会的删掉。**\n\n所以机检里 **#2 触发 / #3 篇幅 / #4 渐进披露 / #6 可移植 / #10 别替模型补** 权重 1.5；\n\"加内容\"类项（#7 最小工具集、#10 配套文档）缺失只算小扣分——别一边喊\"越精简越好\"、一边逼作者把 skill 做臃肿。\n\n## 品牌人设（体检报告的口吻 + 署名）\n\n属于 **会勇禾口王的AI笔记**（定位：AI 实战拆解，硬核·具体·可复制；人设：你办公室里第一个把 AI 用明白的同事）。出体检报告时：\n\n- **口吻**：像同事帮你看代码——直给结论、敢泼冷水（\"这 description 只写了做什么、不写何时用，等于永远不被触发\"），不说客套话。\n- **价值化**：修复建议讲\"省了什么\"（每次触发少灌 100KB 冗余、别人装上不报错、该用时真能被唤醒），不堆术语。\n- **署名**：报告结尾固定带 `—— 会勇禾口王的AI笔记 · @huiyonghkw`。命令行 `check.py` 的报告页脚已内置该署名。\n- **去 AI 味**：定稿前避开\"赋能/打造/至关重要/助力\"等词，说人话。\n\n---\n\n## 免费 / 付费边界（重要）\n\n- **免费（开源内核）**：`check.py` 的**文本 / JSON 报告 + 评分**。任何人本地或进 CI 随便跑。\n- **免费但要自付 API 钱**：`scripts/trigger_eval.py` 触发力实测（工作流 2c）。脚本本身开源随便用，\n  但它每条 query 都真调一次 `claude -p`（约 $0.09–0.15/次），**钱花在用户自己的额度上**。\n  所以它是**可选叠加档、不进默认流程**——`check.py` 的零依赖卖点不受影响，不跑也能出完整体检报告。\n- **付费（增值）**：**品牌可视化体检报告卡**（评分弧 + 等级带 + 明细分享图），依赖 `hekouwang-content-factory` 的私有品牌字体与版式，不随本仓库分发。\n- 一句话口径：**跑检查免费，出\"好看的报告图\"找 @huiyonghkw。** 外部用户要图时说明是付费增值项，别用系统字体凑一张劣化图糊弄。\n\n---\n\n## 工作流（每次体检按这个顺序）\n\n1. **确认目标**：用户没指明就用当前目录；说了某个 skill 就用那个 skill 目录的绝对路径（目录里要有 `SKILL.md`）。若传进来是 `~/.claude/skills/` 这种父目录，脚本会提示里面有哪些 skill，逐个体检。\n2. **跑机检**（确定性层，零依赖）：\n   ```bash\n   python3 <此skill目录>/check.py <skill目录>\n   ```\n   - 需要结构化结果时加 `--json`。退出码：有 FAIL → 1，否则 0。\n2b. **深度安全扫描（可选 · 外部工具 SkillSpector）**：`check.py` 的 #0 只做密钥正则；当要查**提示注入 / 数据外泄 / 隐藏指令 / 供应链 / 过度授权 / MCP 越权**等 68 类模式时，叠加跑 [SkillSpector](https://github.com/NVIDIA/skillspector)（本机已装：`uv tool install`，需 Python 3.12/3.13）：\n   ```bash\n   env -u ALL_PROXY -u all_proxy -u HTTPS_PROXY -u https_proxy \\\n     skillspector scan <纯逻辑副本> --no-llm --format markdown -o report.md\n   ```\n   - **只对\"别人写的、要装进来的\" skill 跑。** 自研 skill 扫出来的实测是 100% 误报（2026-07-15 全量验证 7 个 hekouwang-* skill，逐条翻源码，无一为真），跑了只会浪费时间。\n   - **自研 skill 只做回归检测。** content-factory / yandu-deck / stock-data-reader 三个（会持续改的）已各存一份归零基线在自己目录的 `.skillspector-baseline.yaml`，改完代码后：\n     ```bash\n     skillspector scan <纯逻辑副本> --no-llm --baseline <skill目录>/.skillspector-baseline.yaml\n     ```\n     **冒出来的任何一条都是新的**，值得真翻一眼源码；`--show-suppressed` 看压了什么。基线里的 13/8/4 条已核实为误报（2026-07-15 A/B 验证：yandu-deck `100 CRITICAL DO_NOT_INSTALL` → `0 LOW SAFE`）。改动大到路径/内容 hash 全变时重新 `skillspector baseline <副本> -o …` 存一版。\n   - **分数不是门禁，只看条目。** `Score/Severity` 是**逐条累加**出来的：yandu-deck/iterm2/cc-prod 三个都判 `100/100 CRITICAL · DO NOT INSTALL`，但报告里**一条 CRITICAL 发现都没有**——纯粹是十几条 MEDIUM/HIGH 累加撞顶。且评分随版本通胀：content-factory 代码一行没改，v2.3.5 是 `19/100 SAFE`，v2.3.13 变 `40/100 CAUTION`。**永远读条目、翻源码，别信总评。**\n   - **铁律：只扫逻辑文件，别扫 assets。** 直接扫会把字体 `.woff2`、PNG 等**二进制当代码**，在字节流里刷出几十条假 `TM1 Tool Parameter Abuse`。先用 rsync 拷纯逻辑副本（只留 `.md/.py/.js/.json/.html/.css/.sh/.txt/.yaml`）。⚠️ **`--exclude` 必须写在 `--include='*/'` 前面**（rsync 首次匹配生效，否则 `*/` 先吃掉 `.venv/`，把整个 site-packages 当你的代码扫）：\n     ```bash\n     rsync -a --prune-empty-dirs \\\n       --exclude='.venv/' --exclude='node_modules/' --exclude='.git/' --exclude='__pycache__/' \\\n       --include='*/' --include='*.md' --include='*.py' --include='*.js' --include='*.json' \\\n       --include='*.html' --include='*.css' --include='*.sh' --include='*.txt' --include='*.yaml' \\\n       --exclude='*' <skill目录>/ <副本>/\n     ```\n     实测 content-factory 141M→1.1M、stock-data-reader 264M→176K。\n   - **已知高置信度误报样本**（别被 90%+ 唬住，这些全部核实为假）：`rm -f \"$写死的路径\"` → `TM1 Tool Parameter Abuse` 95%；`subprocess.run([...], check=True)` 硬编码列表 → `OH1 Unvalidated Output Injection` 95% + `AST4`（它建议的 remediation 恰恰就是这个写法）；docstring 里写\"本脚本**绝不读取** .env/*.key\" → `PE3 Credential Access`；字体文件名列表 → `MP2 Context Window Stuffing`；中文 frontmatter → `P2 Hidden Instructions`（置信度 21%，全在 `:1`）；中文触发词 → `AS3 Mixed script`。\n   - **`--baseline` 的 glob `rules` 别乱开。** `rules: {id: \"TM1\"}` 能跨 skill 全局压制，但**扫外来 skill 时恰恰不能用**——今天 TM1 在自研 `rm` 上是误报，在恶意 skill 里可能是真的，全局关掉等于拆探头。跨 skill 只压 `path`+`message` 都限定死的具体条目。\n   - **代理会让扫描直接崩**：SOCKS 代理下报 `Using SOCKS proxy, but the 'socksio' package is not installed`（同 `词级字幕.py` 那个坑），用上面的 `env -u` 绕开。OSV.dev 连不上只是降级到静态库，不影响结论。\n   - 唯一值得看的结构性信号是 **LP1「代码有 network/env/shell 能力但没声明权限」**（7 个自研 skill 中 5 个命中）——不是漏洞，是提醒你 frontmatter 可以补 `allowed-tools`。\n   - `--no-llm` 纯静态、免 key；要更准的行为分析再配 LLM provider（`SKILLSPECTOR_PROVIDER` + 对应 key）。结论并进体检报告的安全维，不替代 #0。\n2c. **触发力实测（可选 · 要花钱 · 只在怀疑 description 时跑）**：机检 #2 只能看出有没有信号词，\n   **判不了写得准不准**——那是本 skill 最大的盲区，因为 description 写不准 = 这个 skill 永远不被唤醒，\n   正文写得再好也白搭。要判准不准就得真跑一遍：\n   ```bash\n   python3 <此skill目录>/scripts/trigger_eval.py \\\n     --eval-set <你的query集>.json --skill-path <skill目录>\n   ```\n   把待测 description 装成临时探针 skill，跑 `claude -p` 看模型会不会去调它。跑完即删，不碰已装的 skill。\n   - ⭐ **先做基准分辨力自检再信分数**：拿真 description 和一段故意写烂的（\"生成内容。\"）\n     跑同一套 query，**分数分不开就说明判据在当前环境失灵**，此时高分也是噪音。\n     实测参考 A=100 / B=50。开发这个脚本时四处配置错误里有三处都表现为\"跑通了、只是分数低\"——\n     不做 A/B 根本发现不了。\n   - **读结果分两种失败**：漏触发＝覆盖不够（补场景句和同义说法）；误触发＝写太宽泛（加边界、换具体动作）。\n     两种都有＝抓错维度，重写而非打补丁。\n   - ⚠️ **要钱**：每条 query 每次采样约 $0.09–0.15，20 条 ×3 次约 $6–9。先用 4–6 条粗筛。\n   - query 怎么设计（尤其**负例必须是 near-miss**）、结果不对劲怎么翻原始流、脚本那四处\n     不能改回去的坑 → 读 [`references/trigger-eval.md`](references/trigger-eval.md)。\n   - **`check.py` 不依赖它**，零依赖那条卖点不受影响；这一档是叠加的，不跑也能出完整体检报告。\n\n3. **定性复核**（机检之上，必须做）：机检是启发式，几项要你**真正读 SKILL.md**再下结论（见下「机检的盲区」）：\n   - 通读 `description`，**真的当一次模型**：光看这段，能不能判断\"什么请求该唤醒它\"？\n   - 通读正文：哪些是\"模型不可能知道的项目/品牌私有事实\"（该留），哪些是\"通用写法/框架教程\"（该删或下沉）？\n   - 若正文很长，看它能不能按\"版本/平台/流程\"天然切成 references/。\n4. **出报告**：先一句话总评 + 分数档位，再用\"✓/▲/✗ + 一句话 + 修复建议\"逐条列，最后给 **Top 3 最该先改的**（按\"花最小力气补最大漏洞\"排序）。中文输出。\n5. **提出代重构**：问用户要不要直接改（瘦身 SKILL.md、拆 references/、外置 scripts/、把硬路径换成 `~`/相对路径、补 description 触发句）。**得到同意再动文件**，一次改一类、可回退；改完**重跑 `check.py`** 给前后对比分数。\n\n> 不要只把脚本输出原样贴给用户——脚本是线索，你的价值在定性判断 + 具体怎么拆。\n\n---\n\n## 评分标准（12 项 · 也是机检的判分依据）\n\n| # | 检查项 | 合格长什么样 | 不合格信号 |\n|---|--------|------------|-----------|\n| 0 | **无硬编码密钥（安全红线）** | SKILL.md 及捆绑文件无 key/token/私钥/口令明文 | 出现 `sk-`/`AKIA`/私钥块/`password=\"...\"` → **直接 FAIL**（skill 常被分发，泄露面更大）<br>⚠️ 测试夹具目录（`test/ tests/ fixtures/ golden/ snapshots/`）里的命中判 **WARN 不判 FAIL**——安全基准的假密钥是刻意载荷，误报会把红线变成摆设 |\n| 1 | **frontmatter 必填合法** | 有 `name`（小写+连字符 ≤64）+ `description` | 缺 name/description → FAIL；name 含大写/下划线/空格 → WARN |\n| 2 | **description 含「何时用」** | 同时写清\"做什么 + 何时/触发用\"（这是被唤醒的唯一依据） | 只写\"做什么\"不写\"何时用\"；或太短没触发信号<br>⚠️ 机检只判\"有没有信号词\"，判不了准不准 —— 要判准不准走**触发力实测**（工作流 2c） |\n| 2b | **description ≤ 1024 字符** | 在上限内，触发稳定 | 超长，可能被截断 |\n| 3 | **SKILL.md ≤ 500 行** | 路由器不是图书馆，按需加载越短越准 | >500 行；分版本/分平台/长流程全塞一个文件 |\n| 4 | **渐进披露（拆 references/）** | 长内容下沉独立 .md，正文留指针 | 正文很长却没有任何 references 拆分文件 |\n| 4b | **指针无死链** | 引用的 `references/*.md` 等带扩展名的捆绑资源真实存在 | 指针指向不存在的文件（按图索骥扑空） |\n| 5 | **脚本外置 scripts/** | 确定性代码（构建/截图/合成/转换）是 scripts/ 真文件 | 大段可执行代码内联在正文，每次靠模型重打 |\n| 6 | **可移植（无硬编码绝对路径）** | 用 `~`/`$HOME`/相对路径/占位 | 出现硬编码家目录绝对路径——别人装上即失效 |\n| 7 | **allowed-tools 最小化** | 声明本 skill 真正需要的工具 | 不声明（继承全部工具，越权面大）——可选项，低权重 |\n| 8 | **触发方式匹配（model vs user invoked）** | 只靠人手敲名字触发的 skill 设 `disable-model-invocation: true`（零 context load） | 明明只手动触发，却留着 description 当 model-invoked，每轮白占上下文（详见 references/skill-writing-vocab.md 第二节）——定性项 |\n| 10a | **别替模型补它已经会的（no-op 测试）** | 只装项目/品牌私有事实 | 有\"语言入门/框架教程/如何使用\"这类教学段——判据：**这段相对模型默认行为改变了什么？没有就删**（即 no-op；详见 vocab 第六节） |\n| 10b | **配套文档（README+CHANGELOG）** | 对外分发友好 | 缺失——纯自用可忽略，低权重 |\n| 11 | **paths / globs 作用域** | 文件专属 skill 声明 glob，减少误触发 | Cursor 2.4+ 可用；未声明 = INFO |\n| 12 | **OpenClaw 兼容声明** | 有 scripts/ 或发 ClawHub 时声明 requires/install | 纯指令 skill 可忽略——INFO |\n\n**分档**：A 优秀 ≥85 · B 良好 ≥70 · C 及格 ≥50 · D 建议重构 <50。\n（机检：PASS=1 / WARN=0.5 / FAIL=0，INFO 不计分。**按重要度加权**——安全红线 #0 与触发/减法核心项 #1/#2/#3/#4/#6/#10a 权重 1.5，标准项 #2b/#4b/#5/#11 为 1.0，加内容项 #7/#10b/#12 为 0.6。#0 命中按 FAIL 计且资损级，定性总评里应一票顶到「先改这条」。）\n\n---\n\n## 机检的盲区（定性复核时重点纠偏）\n\n脚本只判\"机器能确定的\"，以下几项**容易误判，必须你读正文定夺**：\n\n- **#2 触发质量**：脚本只看 description 里有没有\"当…时/use when\"等信号词，**判不了写得准不准**。你要真的当模型读一遍：这段能不能把本 skill 和别的 skill 区分开？会不会该触发时没触发、不该触发时乱触发？\n  - ⭐ **这条现在能实测，别停在拍脑袋**：走工作流 2c 的 `scripts/trigger_eval.py`，\n    \"会不会该触发时没触发、不该触发时乱触发\"正好对应输出里的**漏触发 / 误触发**两个计数。\n    定性读完有怀疑、或者这个 skill 值得下功夫（常用、要分发、要收费），就跑一轮实测坐实。\n    ⚠️ 但**跑之前先做 A/B 基准自检**（真 description vs 一段写烂的），分不开就别信分数。\n- **#3/#4 篇幅 vs 图书馆**：长不一定错——有的 skill 天生信息密度高。但\"分 3 个视觉版本 × 6 个平台\"这种，多半能按维度拆 references/。读结构判断哪些章节是\"用到才看\"的。\n- **#5 脚本外置**：脚本按代码行数/围栏数猜。一段 5 行的示范片段该留正文；一个 80 行的构建/合成脚本该外置。读代码块的\"性质\"定夺。\n- **#10a 别替模型补它已经会的**：脚本按\"教程/如何使用/语言入门\"措辞猜，**会误伤**——比如正文在写\"本项目**自研**流程的用法\"（模型确实不知道，该留），或在\"反对写教程\"。判据是\"这段知识模型升级后会不会自动变强\"：会→删；不会（项目私有）→留。\n- **本 skill 自检会触发 #10a 误报**：因为正文里就列着\"教程/如何使用\"这些**待检测的黑名单词**——这是元层面的正常现象，定性时直接放行。\n\n> **定性诊断词汇**：做 #2/#3/#4/#8/#10a 这些\"机器判不准\"的项时，读 [`references/skill-writing-vocab.md`](references/skill-writing-vocab.md)——它把\"好 skill\"的判据沉淀成可命名的语言（两种载荷、信息阶梯、branch 拆分测试、完成判据防提前收工、no-op 测试、sediment/sprawl/duplication 失败模式、leading word）。出报告时用这些词点破问题，比泛说\"太长/有冗余\"更准。根判据：**skill 是为榨出确定性而存在，根本美德是「每次走同一套过程」可预测。**\n\n---\n\n## 安全红线（务必遵守）\n\n- **绝不读取密钥文件**：`.env` / `*.key` / `*.pem` / `*secret*` 一律不打开（脚本本身也不读）。\n- 体检是只读操作；**任何文件改动都要先说明改哪些、为什么，得到同意再动**。\n- 跨语言/跨用途通用——本 skill 不绑定任何具体技术栈或 skill 类型。\n\n---\n\n## 修复动作清单（用户同意后按需执行）\n\n- **拔密钥（最高优先）**：#0 命中时把明文移出 SKILL.md / 捆绑文件，改放 `.env` / 密钥管理器；命中即视为已泄露，提醒轮换并查 git 历史（skill 很可能已 push 到 GitHub）。\n- **修触发**：#2 不合格时给 description 补\"何时用\"句——列典型请求 / 触发词 / 适用场景，让模型判得出何时唤醒。\n- **瘦身 + 拆 references/**：#3/#4 不合格时，把 SKILL.md 按「版本/平台/流程」维度抽到 `references/` 下的独立 `.md`，正文回归「精简路由 + 硬规矩 + 索引表」。\n- **外置 scripts/**：#5 命中时把确定性脚本抠成 `scripts/` 真文件，正文只留一行调用说明。\n- **去硬路径**：#6 命中时把硬编码家目录路径换成 `~` / `$HOME` / 相对路径 / 「此 skill 目录」占位。\n- **删教学冗余**：#10a 确认是\"教通用写法/框架用法\"的删掉——skill 只装模型不可能知道的私有事实。\n- **修死链**：#4b 报的死指针——补上缺失文件，或修正/删除指针。\n- 改完**重新跑一次 `check.py`** 给前后对比分数。\n\n---\n\n## 落地骨架（建/重写一个 skill 时的推荐结构）\n\n```\nmy-skill/\n├── SKILL.md              # ≤500 行：frontmatter(name+description触发句) + 元判据 + 硬规矩\n│                         #          + 一张「做 X → 读 references/Y」索引表（路由，不堆细节）\n├── references/           # 渐进披露：按版本/平台/流程拆的专题 .md，用到再读\n│   ├── topic-a.md\n│   └── topic-b.md\n├── scripts/              # 确定性可执行脚本（构建/截图/合成/转换），正文只留指针\n├── assets/               # 字体/图片/模板等捆绑资源\n├── README.md             # 给人看（分发用）\n└── CHANGELOG.md          # 版本记录\n```\n\n> SKILL.md 是路由，不是仓库。判据始终是：**这段值不值得每次触发都进上下文？能下沉就下沉。**\n\nFile v1.5.1:tests/fixtures/bad/SKILL.md\n\n---\nname: BadSkill_Example\n---\n\n# Bad Skill\n\n这是一个演示「不合格 skill」的夹具，故意踩坑：\n\n- name 用了大写 + 下划线（应 kebab-case）。\n- **缺 description**——模型无从判断何时加载本 skill（机检会判 FAIL，退出码 1）。\n- 硬编码了绝对路径 /Users/someone/.claude/skills/x/assets/font.woff2（换台机器就废）。\n\nFile v1.5.1:tests/fixtures/good/SKILL.md\n\n---\nname: example-good-skill\ndescription: >\n  生成示例日报。把一段原始数据整理成一页结构化的示例日报。\n  当需要演示「合格 skill 长什么样」或要一份 demo 日报时使用；\n  use when you need a demo daily report.\nallowed-tools:\n  - Read\n  - Write\n---\n\n# Example Good Skill\n\n一个用于演示「合格 skill」的最小夹具：frontmatter 完整、description 写清了\n做什么 + 何时用、正文精简、无硬编码密钥、无绝对路径。\n\n## 何时用\n\n当用户要一份示例日报，或想看一个达标 skill 的结构时。\n\n## 怎么做\n\n1. 读取用户给的原始数据。\n2. 按「概览 / 明细 / 结论」三段整理。\n3. 输出一页 Markdown 日报。\n\n> 正文只放本 skill 私有的约定；通用写法交给模型自己。\n\nFile v1.5.1:README.md\n\n# hekouwang-claude-skill-doctor-skill\n\n> **会勇禾口王的AI笔记** 出品 · `@huiyonghkw`\n> 不聊 AI 会不会取代你，只聊先用 AI 的人怎么取代你。\n\n给 **Agent Skill（SKILL.md）** 做体检的工具。把\"Skill 是按需加载的指令包、不是单文件巨石\"\n这条最佳实践，做成一个能跑在任何 skill 上的检查器：机检定量 + 模型定性，产出评分卡和可落地的修复建议。\n\n## 30 秒验收\n\n```bash\npython3 check.py path/to/your-skill    # 体检任意 skill 目录\nbash scripts/run-all-doctors.sh .      # 三件套（需已装 md-doctor + env-doctor）\n```\n\n姊妹工具：[`hekouwang-claude-md-doctor-skill`](https://github.com/huiyonghkw/hekouwang-claude-md-doctor-skill)（体检 AGENTS.md / CLAUDE.md）。\n\n## 核心判据\n\n> SKILL.md 是模型\"决定要不要加载、加载后照着做\"的运行时指令包。\n> `description` 决定它何时被唤醒；正文越精简越准；厚重细节要能\"按需展开\"\n> （references/ 用到再读），而不是每次触发就把全部细节灌进上下文。\n\n## 用法\n\n### 在 Claude Code 里（推荐）\n\n直接用**自然语言**喊它，Claude 会自动加载本 skill、在底层跑机检、再做定性复核，给评分卡 + 按优先级的修复建议，并问要不要代为重构：\n\n> - 「帮我体检 `~/.claude/skills/xxx` 这个 skill」\n> - 「我的 SKILL.md 规范吗 / 是不是太长了 / 要不要拆 references」\n> - 「audit this skill」「lint SKILL.md」\n\n### 命令行直接跑（零依赖，仅需 Python 3）\n\n```bash\npython3 check.py <skill目录>          # 输出彩色报告\npython3 check.py <skill目录> --json   # 机器可读 JSON（CI 可用）\n```\n\n退出码：有 FAIL → 1，否则 0（可用于 CI 卡关）。\n\n### Docker（不想装 Python 也能跑）\n\n```bash\n# 拉官方镜像直接用（打 v* tag 时 GitHub Actions 自动发布到 GHCR）\ndocker run --rm -v \"$PWD:/work\" ghcr.io/huiyonghkw/hekouwang-claude-skill-doctor-skill\n\n# 或本地自建\ndocker build -t claude-skill-doctor .\ndocker run --rm -v \"$PWD:/work\" claude-skill-doctor            # 体检挂载的 skill\ndocker run --rm -v \"$PWD:/work\" claude-skill-doctor /work --json\n```\n\n### 接进 CI 卡关（GitHub Actions 示例）\n\n```yaml\n- uses: actions/setup-python@v5\n  with: { python-version: \"3.x\" }\n- name: SKILL.md 体检（不合格则拦 PR）\n  run: |\n    curl -sO https://raw.githubusercontent.com/huiyonghkw/hekouwang-claude-skill-doctor-skill/main/check.py\n    python3 check.py path/to/your/skill\n```\n\n本仓库自身的 CI 见 [`.github/workflows/ci.yml`](.github/workflows/ci.yml)（语法 + good/bad 夹具 + JSON 合法性）。\n\n## 检查项（12 项加权）\n\n| 权重 | 项 |\n|---|---|\n| **1.5（核心）** | 无硬编码密钥 · frontmatter 必填合法 · description 含「何时用」 · SKILL.md ≤500 行 · 渐进披露(拆 references/) · 可移植(无硬编码绝对路径) · 别替模型补它已会的 |\n| 1.0（标准） | description ≤1024 · 指针无死链 · 脚本外置 scripts/ |\n| 0.6（加内容） | allowed-tools 最小化 · 配套文档(README+CHANGELOG) |\n\n分档：A ≥85 · B ≥70 · C ≥50 · D <50。\n\n## 机检 vs 定性\n\n`check.py` 只判机器能确定的部分。**description 触发得准不准、正文是不是\"图书馆\"、\n是不是在替模型补它已会的知识**——这些要人/模型读正文复核（脚本会标出疑点）。\n完整定性流程见 `SKILL.md`。\n\n## 免费 / 付费\n\n| | 免费（开源） | 付费增值 |\n|---|---|---|\n| 机检 | `check.py` 文本/JSON + ASCII 评分条 | 品牌可视化报告卡 |\n| CI | 退出码卡关 | — |\n| 联系 | GitHub Issue | **@huiyonghkw**（ClawHub / GitHub） |\n\n- **免费**：`check.py` 的文本 / JSON 报告 + 评分，随便用、可进 CI。\n- **付费增值**：品牌可视化体检报告卡（精美分享图），找 `@huiyonghkw`。\n\n## 体检器三件套\n\n[`md-doctor`](https://github.com/huiyonghkw/hekouwang-claude-md-doctor-skill) · [`env-doctor`](https://github.com/huiyonghkw/hekouwang-env-doctor-skill) · 一键 `bash scripts/run-all-doctors.sh`（见 `references/doctor-suite.md`）。\n\n---\n\n—— 会勇禾口王的AI笔记 · @huiyonghkw\n\nFile v1.5.1:_meta.json\n\n{\n  \"ownerId\": \"kn73qd1gcmjr446mwcbdxef70x82vxcw\",\n  \"slug\": \"hekouwang-claude-skill-doctor-skill\",\n  \"version\": \"1.5.1\",\n  \"publishedAt\": 1786521761980\n}\n\nFile v1.5.1:references/doctor-suite.md\n\n# hekouwang-doctor-suite · 体检器三件套\n\n> 竞品多是单点；这套把「项目配置 → 技能包 → 本机环境」串成一条验收链。\n\n```\nhekouwang-doctor-suite（概念）\n├── md-doctor      → AGENTS.md / CLAUDE.md（运行时配置）\n├── skill-doctor   → SKILL.md（Agent 技能包）\n└── env-doctor     → 磁盘 / 版本管理器 / AI 宿主目录\n```\n\n## 一键跑\n\n```bash\nbash scripts/run-all-doctors.sh /path/to/your-project\n```\n\n（脚本在 `hekouwang-claude-md-doctor-skill`；`skill-doctor` / `env-doctor` 仓内各有一份相同副本。）\n\n## 建议顺序\n\n1. **md-doctor** — 根配置是否「路由器」而非「图书馆」\n2. **skill-doctor** — `.agents/skills/` 下各 skill 是否按需加载\n3. **env-doctor** — 本机是否留着已换掉的 nvm / 膨胀的 AI 缓存\n\n## 免费 vs 付费\n\n| | 免费（开源） | 付费增值 |\n|---|---|---|\n| 机检 | `check.py` / `scan.sh` 文本报告 + JSON | 品牌可视化报告卡（评分弧 + 等级带） |\n| CI | 退出码卡关 | — |\n| 联系 | GitHub Issue / PR | ClawHub **@huiyonghkw** |\n\nFile v1.5.1:references/skill-writing-vocab.md\n\n# Skill 写作词汇与进阶判据（定性复核时用）\n\n这套词汇消化自 mattpocock/skills 的 `writing-great-skills`。它给\"什么是好 skill\"补了一层**可命名的诊断语言**——体检时用这些词点破问题，比泛泛说\"太长/有冗余\"更准、更可落地。\n\n> 一句话根：**skill 存在是为了从随机系统里榨出确定性。根本美德是「可预测」——每次运行走同一套*过程*（不是产出同一结果）。下面每条判据都为它服务。**\n\n## 一、两种\"载荷\"——这是\"减法\"的底层账\n\n- **context load（上下文载荷）**：model-invoked skill 的 `description` 每轮都待在上下文窗口里，是持续成本。正文越长，每次触发付的越多。\n- **cognitive load（认知载荷）**：user-invoked skill 不进模型视野，只靠**你**记得它存在——成本转嫁到人脑。\n- 当 user-invoked skill 多到记不住，就用一个 **router skill**（一个 user-invoked skill 列出其余的\"何时用哪个\"）来治认知载荷。\n\n## 二、触发方式：model-invoked vs user-invoked（体检新增维度 #8）\n\n- **model-invoked**（默认，省略 `disable-model-invocation`）：保留 description，模型能自主触发、别的 skill 也能调到它。代价是 context load。\n- **user-invoked**（设 `disable-model-invocation: true`）：description 变成给人看的一行摘要，模型够不到，**零 context load**。\n- **判据**：这个 skill 是不是**只可能靠人手敲名字**触发？若是 → 该设 user-invoked，别让它的 description 白占每轮上下文。只有\"模型必须自己判断何时唤醒\"或\"别的 skill 要调它\"时，才值得付 model-invoked 的常驻成本。\n\n## 三、信息阶梯（progressive disclosure 的标尺）\n\n三级，按\"模型多急需\"排：① **in-skill step**（SKILL.md 里的有序动作）② **in-skill reference**（按需查的定义/规则，可以是一组平级规则，不是坏味道）③ **external reference**（推到独立文件、靠 context pointer 触发才加载）。\n\n- **branch（分支）= 最干净的拆分测试**：每个分支都要的 → 内联；只有部分分支会走到的 → 推到指针后面。\n- **co-location（就近）**：一个概念的定义+规则+注意事项放同一标题下，别散落。\n- **context pointer 的措辞**（不是它指向哪）决定模型何时、多可靠地去读那块。\n\n## 四、完成判据（completion criterion）——防\"提前收工\"\n\nstep 类 skill 的每一步要以一个**可检验**的完成条件收尾（模型能分辨\"做完了 vs 没做完\"）；关键处还要**穷尽**（\"每个改过的模型都交代了\"，而不是\"产出一个变更清单\"）。判据含糊 → 招致 **premature completion**（注意力滑向\"算完成了\"而提前结束）。\n\n## 五、leading word（引导词）\n\n一个模型预训练里已有的**紧凑概念**（如 _tight / red / tracer bullets_），在文里复用，用极少 token 锚定一整片行为。两处获益：正文里锚定**执行**（一见这词就走同一行为），description 里锚定**触发**（你 prompt/文档/代码里都用这词，模型更可靠地联想到该 skill）。把\"快、确定、低开销\"这种三词重述坍缩成一个 _tight_——既省 token 又给模型更锐的挂钩。体检时主动找\"能被一个引导词退休掉的重述\"。\n\n## 六、失败模式词汇（诊断用，点名比泛指有力）\n\n- **premature completion**：步骤没真做完就收。先磨锐完成判据（便宜、就地）；判据已无法再细化且确实观察到抢跑，才用\"按序列拆分\"把后续步骤藏起来。\n- **duplication**：同一意思出现在多处。费维护、费 token，还把它在阶梯上的\"显要度\"抬高过真实等级。守则：每个意思**单一真相源**，改行为只改一处。\n- **sediment（沉积）**：旧内容层层留下——\"加着安全、删着危险\"的默认结局。没有修剪纪律的 skill 必然积沉。\n- **sprawl（臃肿）**：纯粹太长，即便每行都还活着且唯一。解药是阶梯：reference 推到指针后、按 branch/序列拆，让每条路径只背自己要的。\n- **no-op（空操作）**：模型默认就会做的话，付了载荷却没说事。**测试：这行相对默认行为改变了什么？没有 → 删**。弱引导词（\"要认真\"而模型本就够认真）就是 no-op，修法是换更强的词（\"relentless\"），不是换技巧。\n\n## 修剪纪律\n\n逐**句**（不是逐行）跑 no-op 测试：某句在孤立状态下不改变行为 → **整句删掉**，别只删词。要狠——失败的散文多数该删，不是重写。\n\nFile v1.5.1:references/trigger-eval.md\n\n# 触发力实测（trigger eval）· 怎么设计 query、怎么读结果\n\n> 机检 #2 只能看出 description 里**有没有**\"当…时/use when\"这类信号词，判不出**写得准不准**。\n> 这份文档配 `scripts/trigger_eval.py`，补的是那一层：真跑一遍，看模型会不会被这段 description 唤醒。\n> ⚠️ 需要 `claude` CLI，**会产生真实费用**（每条 query 每次采样约 $0.09–0.15）。\n> `check.py` 不依赖它，零依赖那条卖点不受影响。\n\n## 0. ⭐ 跑之前必做：基准分辨力自检（不做就别信任何分数）\n\n**先喂一个已知好的和一个已知烂的，看分数分不分得开。** 分不开说明这套判据在你的环境里失灵，\n此时任何分数都是噪音——包括那个看起来很健康的高分。\n\n```bash\n# A 组：真 description\npython3 scripts/trigger_eval.py --eval-set queries.json --skill-path <skill> --label A\n\n# B 组：同一套 query，换一段故意写烂的 description\nprintf '生成内容。\\n' > /tmp/bad-desc.txt\npython3 scripts/trigger_eval.py --eval-set queries.json --skill-path <skill> \\\n  --description-file /tmp/bad-desc.txt --label B\n```\n\n**判据**：A 明显高于 B（实测参考：A=100 / B=50，4 条 query）才算这套 eval 在你机器上有效。\n两组同分 = 判据失灵，先去查第 4 节。\n\n> 这不是形式主义。开发本脚本时，前后四处配置错误里有**三处**都表现为\n> \"跑通了、只是分数低\"——不做 A/B 根本发现不了，会拿一堆假分数去改 description。\n\n## 1. eval query 怎么写\n\n**数量**：20 条左右，正例 8–10、负例 8–10。想省钱可以先用 4–6 条粗筛，方向对了再补齐。\n\n**质量三条**：\n\n1. **写成用户真会打出来的一整段话**，不是抽象任务名。要有具体文件名、路径、栏目名、\n   数字、背景交代，可以有口语、缩写、错别字、全小写。\n   - ❌ `\"生成小红书图文\"`\n   - ✅ `\"帮我把这篇讲 uv 的文章做成一套小红书图文，8 张 1080x1440，用 V2 米白那套视觉，封面要有数字锚点\"`\n\n2. **正例要覆盖不同说法**。同一个意图，有正式的、有随口的；**要有几条不点名品牌/不提专有名词**\n   的（\"我写完一篇稿子想发公众号，帮我出文章母本和配图\"）——这类最能检验 description\n   有没有把使用场景说清楚，而不是靠关键词硬碰。\n\n3. ⭐ **负例必须是 near-miss**。共享关键词或概念、但其实该走别的工具的请求，才有检验力。\n   - ❌ `\"帮我写个快排\"`（对内容工厂来说太远，测不出任何东西）\n   - ✅ `\"帮我给这个 React 项目做个好看的产品落地页\"`（同样是\"做视觉\"，但属前端）\n   - ✅ `\"帮我看下上周几篇小红书笔记数据，哪篇曝光最高\"`（提了小红书，但是数据分析）\n\n**别用的 query**：一步就能做完的简单请求（\"读一下这个文件\"）。模型对自己就能轻松搞定的事\n本来就不查 skill，这种用例无论 description 写得多好都不会触发，纯粹浪费钱。\n\n格式：\n\n```json\n[\n  {\"query\": \"……\", \"should_trigger\": true,  \"note\": \"正1·核心场景\"},\n  {\"query\": \"……\", \"should_trigger\": false, \"note\": \"负1·near-miss 同是做视觉但属前端\"}\n]\n```\n\n## 1.5 ⭐ 负例必须带干扰项跑，否则结论是假的\n\n探针环境默认**只有被测 skill 一个候选**。模型 `ls` 完发现没别的可选，\n就会勉强用手头这个——**负例于是系统性假阳性**。\n\n实测（content-factory · 同一套 6 条 query · 同一段 description）：\n\n| 环境 | 得分 | 那条\"翻页演示版网页\"负例 |\n|---|---|---|\n| 无竞争者 | **83**（5/6） | ✗ 误触发 |\n| 放 5 个兄弟 skill 当竞争者 | **100**（6/6） | ✓ 正确避开 |\n\n**同一段 description，什么都没改，分数差 17 分。** 按 83 分那个数字去\"修边界\"，\n修的是一个不存在的问题。\n\n```bash\npython3 scripts/trigger_eval.py --eval-set queries.json --skill-path <skill> \\\n  --distractors ~/.claude/skills/其它skill-A ~/.claude/skills/其它skill-B ...\n```\n\n选谁当干扰项：**功能相邻、最可能抢活的那几个**。自己有一套 skill 的话，\n把兄弟们全带上最省事，也最接近真实环境。\n\n⚠️ **干扰项的名字也被中性化成 `alt-xxx`，这是故意的**。若让干扰项挂真名\n（`yandu-deck` 之类）而被测探针挂中性名，模型光看名字就能认出干扰项，\n等于给对手开外挂——测出来的仍旧是名字不是 description，跟第 4 节第 4 条同一个坑。\n\n> 正例也别忘了看：竞争者在场时正例**仍应触发**。若加了干扰项后正例掉了，\n> 说明 description 的区分度不够，被邻居抢走了——这才是真该改的信号。\n\n## 2. 怎么读结果\n\n分数只是入口，**两种失败要分开看，修法完全不同**：\n\n| 症状 | 含义 | 怎么改 description |\n|---|---|---|\n| **漏触发**（该触发的没触发） | 覆盖面不够，用户换个说法就唤不醒 | 补场景句和同义说法；把用户真实的口语表达写进去 |\n| **误触发**（不该触发的触发了） | 写太宽泛，抢别的工具的活 | 加边界（\"不用于 X\"）；把泛词换成具体动作与产物 |\n\n同时出现两种 = description 抓错了维度，重写而不是打补丁。\n\n采样次数：默认 `--runs-per-query 1` 省钱。触发是概率性的，要下正式结论用 `3`\n（成本 ×3），此时触发率 ≥0.5 判通过。\n\n## 3. 结果不对劲时\n\n先用 `--dump-dir` 把原始流存下来翻，**别猜**：\n\n```bash\npython3 scripts/trigger_eval.py ... --dump-dir /tmp/dumps\n```\n\n翻的时候重点看两样：模型的**工具调用序列**（它到底做了什么），\n以及 Skill/Read 调用里的**实际参数**（是不是调到了别的东西）。\n本脚本历史上两次假阴性都是靠翻这个抓出来的。\n\n## 4. 脚本为什么这么写（改它之前先读这节）\n\n本脚本改自官方 `anthropics/skills · skill-creator/scripts/run_eval.py`。\n官方思路对，但原样跑在 Claude Code 2.1.220 上**测不出任何东西**。四处都改完才有分辨力——\n**这四处是踩出来的，改脚本时别顺手改回去**：\n\n1. **`--setting-sources project`**：不加则子进程继承 `~/.claude/skills/` 里已装的真 skill\n   （实测 32 个），模型去触发真身、名字对不上探针 → 全部正例假阴性。\n   官方没料到\"被测 skill 已经装在机器上\"这种情况。\n\n2. **扫完整个流才判否**：官方是\"第一个 tool_use 不是 Skill/Read 就 return False\"。\n   但模型碰到陌生 skill 名**会先 `Bash: ls` 探查环境**，Skill 往往是第二三个动作\n   （实测序列 `['Bash','Bash','Skill']`）——真触发了却被判没触发。\n\n3. **每条 query 独立 project root**：共用目录时并发 worker 把探针全丢一处，\n   模型会调到**别人的**探针（实测：期望 `-d795b59f`，实际调 `-4ac07ae5`），自己这条判否。\n\n4. ⭐ **探针要装成 project 级真 skill，且名字中性（`probe-xxxxxxxx`）**：\n   init 事件里 `skills` 和 `slash_commands` 两个列表**都只给名字、不给 description**。\n   探针一旦沿用原 skill 名，模型光看名字就去 Read 它，**description 全程没参与决策**——\n   实测此时 447 字真 description 和 5 字\"生成内容。\"**都是满分**，等于白测。\n\n## 5. 成本\n\n| 规模 | 调用数 | 约合 |\n|---|---|---|\n| 粗筛 4 条 × 1 次 | 4 | $0.5 |\n| 正式 20 条 × 1 次 | 20 | $2–3 |\n| 结论 20 条 × 3 次 | 60 | $6–9 |\n\n先粗筛、方向对了再上规模。A/B 基准自检要算两轮。\n\nFile v1.5.1:CHANGELOG.md\n\n# Changelog\n\n本项目遵循 [语义化版本](https://semver.org/lang/zh-CN/)。\n\n## [1.5.1] - 2026-08-12\n\n### 新增\n- `scripts/run-all-doctors.sh`、`references/doctor-suite.md`（与 md-doctor / env-doctor 同版）\n\n### 变更\n- `check.py`：付费报告卡 CTA；README 30 秒验收 + 免费/付费表 + 三件套互链\n- summary 补英文 SEO 关键词（skill lint / SKILL.md doctor）\n\n## [1.5.0] - 2026-08-12\n\n### 新增\n- **#11 paths / globs**：识别 Cursor 2.4+ 文件作用域 frontmatter，减少无关文件时的误触发。\n- **#12 OpenClaw 兼容声明**：轻量检查 `metadata.openclaw`、`requires`、`install`（有 scripts/ 时提示）。\n\n### Fixed\n- **指针扫描误报**：只匹配带扩展名的捆绑资源路径（`references/foo.md`），表格里的\n  `references/scripts/assets` 不再被判死链。\n- **可移植性自检误报**：`ABS_PATH_RE` 用字符串拼接构建，避免 `check.py` 源码里的\n  正则说明行被当成硬编码路径。\n- **#10a 元层面误报**：评分表/检查项表格行里的黑名单示例词不再计为教学冗余。\n\n## [1.4.1] - 2026-08-01\n\n修 #0 安全红线的两处假阳性。**假阳性会让红线失去意义**——被误报训练过的人下次看到真 FAIL 也只会挥手放过。\n\n### Fixed\n- **`sk-` 密钥正则缺左词界**：`sk-(?:ant-)?[\\w-]{20,}` 会从 `generate-ask-user-format.ts`\n  里抠出 `sk-user-format` 判成 key。同一份 `SECRET_PATTERNS` 里 `AKIA` / `AIza` / `JWT`\n  三条都带 `\\b`，只有这条漏了。实测某第三方 skill 因此被判资损级 FAIL（62 分），\n  命中源全是 `ask-user-*` 文件名。\n- **测试夹具里的假密钥降级 WARN**：安全基准/回归夹具（`test/ tests/ fixtures/ golden/ snapshots/`\n  等目录）里的 key 是刻意载荷，不是泄露。现在只在夹具命中时判 WARN 并提示\"翻一眼确认\"，\n  正文/脚本命中照旧 FAIL；两类同时命中时 FAIL 优先，detail 里标明夹具那几处已降级。\n\n### 验证（A/B 基准分辨力自检）\n三类样本必须判出三种结果，否则说明改完的判据分不开对和错：\n真密钥 `sk-proj-…` → **FAIL**；夹具里 `sk-ant-api03-…` → **WARN**；`ask-user-question-format` → **PASS**。\n回归夹具分数不变（`tests/fixtures/bad` 67、`good` 100）。\n\n## [1.4.0] - 2026-07-28\n\n补上本器最大的盲区：**#2 触发质量以前只能拍脑袋，现在能实测**。\n静态检查只看得出 description 里有没有\"当…时\"这类信号词，判不了写得准不准——\n而 description 写不准 = 这个 skill 永远不被唤醒，正文写得再好也白搭。\n\n### Added\n- **`scripts/trigger_eval.py` · 触发力实测（可选第二引擎）**：把待测 description 装成临时探针 skill，\n  跑 `claude -p` 看模型会不会去调它，输出触发力分数 + **漏触发 / 误触发**两个计数。跑完即删，\n  不碰任何已装的 skill。改自官方 `anthropics/skills · skill-creator/run_eval.py`。\n- **`--distractors` 干扰项**：把其它 skill 的 description 一起放进探针环境当竞争者。\n  不加的话环境里只有被测探针一个候选，模型\"没得选\"就会勉强用它，**负例系统性假阳性**。\n  实测同一段 description、同一套 query：无竞争者 **83 分**（那条\"翻页演示版\"负例误触发），\n  放 5 个兄弟 skill 后 **100 分**（正确避开）——**什么都没改，差 17 分**。\n  按 83 分去修边界，修的是一个不存在的问题。\n  干扰项名字同样中性化成 `alt-xxx`，否则模型看名字就能认出对手，等于开外挂。\n- **`references/trigger-eval.md`**：query 怎么设计（**负例必须是 near-miss**）、\n  **负例必须带干扰项跑**、两种失败各自怎么改 description、结果不对劲怎么翻原始流、成本表。\n- 工作流新增步骤 **2c**；检查项 #2 与「机检的盲区」#2 同步改写。\n\n### Changed\n- 免费/付费边界补一档：`trigger_eval.py` **脚本开源随便用，但 API 费用走用户自己的额度**\n  （约 $0.09–0.15/次调用）。因此它是**可选叠加档、不进默认流程**，\n  `check.py` 的零依赖卖点不受影响，不跑也能出完整体检报告。\n\n### 踩坑记录：官方脚本原样搬过来测不出任何东西\n\n官方那版思路对，但在 Claude Code 2.1.220 上四处全错，**改完才有分辨力**\n（实测：真 description 100 分 vs \"生成内容。\"50 分；不改第 4 条时两者都是 100，等于白测）。\n四处里**前三处都表现为\"跑通了、只是分数低\"**，不做 A/B 基准根本发现不了：\n\n1. 不加 `--setting-sources project` → 子进程继承 `~/.claude/skills/` 里已装的真 skill（实测 32 个），\n   模型触发真身、名字对不上探针 → **全部正例假阴性**。官方没料到\"被测 skill 已装在机器上\"。\n2. 官方\"第一个 tool_use 不是 Skill/Read 就判否\" → 但模型碰到陌生 skill 名**会先 `Bash: ls` 探查**，\n   Skill 往往是第二三个动作（实测序列 `['Bash','Bash','Skill']`）。改为扫完整个流、命中即收工。\n3. 并发 worker 共用一个 project root → 模型调到**别人的**探针\n   （实测：期望 `-d795b59f`，实际调 `-4ac07ae5`）。改为每条 query 一个一次性 root。\n4. ⭐ 探针放 `.claude/commands/` 且沿用原 skill 名 → init 事件里 `skills` / `slash_commands`\n   两个列表**都只给名字、不给 description**，模型光看名字就去 Read 它，\n   **description 全程没参与决策**。改为装成 project 级真 skill + 中性名 `probe-xxxxxxxx`。\n\n⭐ 因此文档把「**先做 A/B 基准分辨力自检，分不开就别信分数**」写成了跑之前的强制前置步骤，\n不是建议。\n\n## [1.3.0] - 2026-07-15\n\n**版本号说明**：本次内容即原定的 1.2.0（见下方 Changed/Added），因发布事故改号为 1.3.0——\nClawHub 上 `hekouwang-claude-skill-doctor-skill` 这个 slug 于 2026-07-09 被误发成 **md-doctor 的内容**\n并占用了 1.2.2 这个版本号（check.py 与 md-doctor 逐字节同 hash `5f0d3613`、测试夹具是 `CLAUDE.md`\n而非 `SKILL.md`）。该 slug 在 2026-06-24 的 1.0.2 / 1.0.3 是正确的 skill-doctor 内容，\n即**误发覆盖了正确版本**。需发一个高于 1.2.2 的版本才能把 latest 拨正，故跳到 1.3.0。\n误发的 1.2.2 已从该 slug 永久删除，版本史现为 1.0.2 → 1.0.3 → 1.3.0。\n\n### Fixed\n- **ClawHub 发布事故更正**：`hekouwang-claude-skill-doctor-skill@1.2.2` 实为 md-doctor，已删除；\n  latest 拨回真正的 Agent Skill 体检器。\n- **发布纪律**：以后 `clawhub skill publish` **一律显式传 `--version`**——\n  ClawHub 不读 SKILL.md 的 `version`，只在线上版本上 +1（实测会把本地 1.2.2 发成 1.1.3、\n  本地 1.1.0 发成 0.1.2，即**降级**）。自动推断不可信。\n\n拿真数据校准步骤 2b 的 SkillSpector。全量扫 7 个 `hekouwang-*` skill、逐条翻源码核实，\n结论推翻 1.1.0 的乐观假设：**对自研 skill 它 100% 误报**，且**分数完全不可信**。\n2b 从\"可选加跑的安全维\"收紧为\"只对外来 skill 跑的入库审查\"。\n\n### Changed\n- **2b 定位收紧：只对\"别人写的、要装进来的\" skill 跑。** 7 个自研 skill 全扫、逐条翻源码，\n  无一为真。自研 skill 改走**回归检测**（存基线 → 只看 NEW），不再全量看告警。\n- **新增铁律「分数不是门禁，只看条目 + 翻源码」。** `Score/Severity` 是逐条**累加**的：\n  yandu-deck / iterm2 / cc-prod 三个判 `100/100 CRITICAL · DO NOT INSTALL`，\n  但报告里**一条 CRITICAL 发现都没有**——纯粹是十几条 MEDIUM/HIGH 累加撞顶。\n  且评分随版本通胀：content-factory 代码一行没改，v2.3.5 `19/100 SAFE` → v2.3.13 `40/100 CAUTION`。\n- **推翻 1.1.0 的「低可信度才是误报」说法**：95% 高可信度的照样是误报。改为附**高置信度误报样本表**：\n  `rm -f \"$写死路径\"` → `TM1` 95%；`subprocess.run([...], check=True)` 硬编码列表 →\n  `OH1 Unvalidated Output Injection` 95% + `AST4`（其 remediation 建议的恰恰就是这个写法）；\n  docstring 写\"本脚本**绝不读取** .env/*.key\" → `PE3 Credential Access`；\n  字体文件名列表 → `MP2 Context Window Stuffing`；中文 frontmatter → `P2 Hidden Instructions` 21%；\n  中文触发词 → `AS3 Mixed script`。\n\n### Added\n- **rsync `--exclude` 顺序坑**：必须排在 `--include='*/'` 前面（rsync 首次匹配生效，\n  否则 `*/` 先吃掉 `.venv/`，整个 site-packages 被当自己的代码扫）。实测 stock-data-reader 264M→176K。\n- **SOCKS 代理绕法**：代理下扫描直接崩（`'socksio' package is not installed`），\n  需 `env -u ALL_PROXY -u all_proxy -u HTTPS_PROXY -u https_proxy`。OSV.dev 连不上只降级静态库，不影响结论。\n- **`--baseline` 正确用法 + 反例**：`fingerprints` 按「路径+内容 hash」锁定、只对同一 skill 生效；\n  能跨 skill 的 glob `rules`（如 `id: \"TM1\"`）**恰恰不能在扫外来 skill 时开**——\n  同一规则在自研 `rm` 上是误报、在恶意 skill 里可能是真的，全局关掉等于拆探头。\n- content-factory / yandu-deck / stock-data-reader 三个常改的 skill 各存一份归零基线\n  （`.skillspector-baseline.yaml`，A/B 验证：yandu-deck `100 CRITICAL DO_NOT_INSTALL` → `0 LOW SAFE`）。\n- 记录唯一有信号的结构性告警 **LP1「代码有 network/env/shell 能力但没声明权限」**（7 个中 5 个命中）——\n  不是漏洞，与 `check.py` 自检的「未声明 allowed-tools」指向同一缺口。\n\n## [1.1.0] - 2026-06-24\n\n接入外部安全扫描、消化业界 skill 写作最佳实践，扩展体检维度。\n\n### Added\n- **工作流新增步骤 2b · 深度安全扫描（可选）**：叠加 [NVIDIA SkillSpector](https://github.com/NVIDIA/skillspector)，\n  覆盖提示注入 / 数据外泄 / 隐藏指令 / 供应链 / 过度授权 / MCP 越权等 68 类模式，\n  补 `check.py` #0 密钥正则之外的深度安全维。含实战铁律：**只扫逻辑文件、别扫 assets**\n  （直接扫会把字体/图片二进制当代码，刷出几十条假 `TM1 Tool Parameter Abuse`）；\n  低可信度（<30%）`Hidden Instructions` 多是中文/零宽字符误报，人工复核。\n- **评分维度 #8 触发方式匹配（model vs user invoked）**：只靠人手敲名字触发的 skill\n  应设 `disable-model-invocation: true`，省掉每轮 `description` 的 context load。\n- **`references/skill-writing-vocab.md`**：消化 mattpocock/skills 的 *writing-great-skills*，\n  把\"好 skill\"的判据沉淀成可命名的诊断词汇——两种载荷（context/cognitive load）、\n  信息阶梯、branch 拆分测试、完成判据（防 premature completion）、no-op 测试、\n  sediment/sprawl/duplication 失败模式、leading word。出报告时用这些词点破问题。\n\n### Changed\n- **#10a 锐化为 no-op 测试**：判据明确为「这段相对模型默认行为改变了什么？没有就删」，\n  比原先\"别替模型补它已经会的\"更可操作。\n\n## [1.0.2] - 2026-06-22\n\n实战体检三个品牌 skill 时暴露的机检缺陷修复（dogfooding）：\n\n### Fixed\n- **#7 allowed-tools 兼容逗号字符串**：原先只认 YAML 列表（`- a` / `[a,b]`），\n  把官方 frontmatter 标准的逗号字符串写法（`allowed-tools: Bash, Read, Write`）\n  误判为「未声明」。现在两种写法都解析、非空即 PASS。\n\n## [1.0.1] - 2026-06-21\n\n实战体检 14 个 skill 时暴露的两个机检缺陷修复（dogfooding）：\n\n### Fixed\n- **glob 指针不再误报死链**：`reference/deck-engine-*.html` 这类通配符指针，\n  现在用 `glob` 解析、能匹配到真实文件就算存在；`{a,b}` brace 简写跳过不误报。\n  （原正则在 `*` 处截断成 `reference/deck-engine-`，当字面路径判死。）\n- **指针 / 教学词行号还原为文件绝对行号**：原先报的是正文相对行号（少算了\n  frontmatter 行数），定位会偏。`parse_frontmatter` 现返回 `body_offset` 补正。\n\n## [1.0.0] - 2026-06-21\n\n首个版本。给 Agent Skill（SKILL.md）做体检的零依赖检查器。\n\n### 检查项（12 项加权）\n- **安全**：SKILL.md 及捆绑文件无硬编码密钥（命中即 FAIL，资损级）。\n- **触发**：frontmatter 必填合法（name/description）；description 含「何时用」且 ≤1024 字符。\n- **减法**：SKILL.md ≤500 行；长内容下沉 references/（渐进披露）；大段脚本外置 scripts/。\n- **可移植**：无硬编码 `/Users/`、`/home/` 绝对路径。\n- **取舍**：别替模型补它已会的（教学冗余检测）；allowed-tools 最小化；配套 README/CHANGELOG。\n\n### 特性\n- 零依赖（Python3 标准库），文本 + `--json` 双输出，退出码随 FAIL。\n- 按重要度加权评分（触发/减法核心项 1.5，标准项 1.0，加内容项 0.6），A/B/C/D 分档。\n- 极简零依赖 frontmatter 解析（块标量 / 行内 list / 缩进 list）。\n- 密钥扫描双档豁免：指纹型用窄填充表、赋值型用宽占位表，避免误杀真 key。\n- 报告口吻与署名沿用「会勇禾口王的AI笔记」品牌人设。\n\nFile v1.5.1:skill-card.md\n\n## Description:\n\nAudits Agent Skill directories for SKILL.md structure, trigger quality, progressive disclosure, portability, script placement, and basic secret hygiene, then returns a scorecard and prioritized fixes.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[huiyonghkw](https://clawhub.ai/user/huiyonghkw)\n\n### License/Terms of Use:\n\nMIT\n\n## Use Case:\n\nDevelopers and skill maintainers use this skill to review Agent Skill packages, run deterministic checks, interpret structural issues, and plan concrete fixes before publishing or installing a skill.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Optional helper scripts have higher operational impact: trigger evaluation spends Claude CLI/API quota and inherits the local CLI environment, while the doctor-suite runner can inspect the local development environment through env-doctor.\n\nMitigation: Use check.py for normal reviews, and run trigger_eval.py or run-all-doctors.sh only as deliberate opt-in steps after confirming the target path, expected cost, and local environment exposure.\n\nRisk: Audit results and refactoring suggestions can be incomplete or misleading if applied without review.\n\nMitigation: Review findings before changing a skill, apply edits intentionally, and rerun the checker after modifications.\n\n## Reference(s):\n\n- [ClawHub Skill Page](https://clawhub.ai/huiyonghkw/skills/hekouwang-claude-skill-doctor-skill)\n- [Project Homepage](https://github.com/huiyonghkw/hekouwang-claude-skill-doctor-skill)\n- [Doctor Suite Reference](references/doctor-suite.md)\n- [Skill Writing Vocabulary](references/skill-writing-vocab.md)\n- [Trigger Evaluation Reference](references/trigger-eval.md)\n- [NVIDIA SkillSpector](https://github.com/NVIDIA/skillspector)\n\n## Skill Output:\n\n**Output Type(s):** [Analysis, Markdown, JSON, Shell commands, Code, Guidance]\n\n**Output Format:** [Markdown scorecards, JSON reports, shell commands, and refactoring guidance]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May include prioritized recommendations, optional command-line checks, and JSON output from check.py --json.]\n\n## Skill Version(s):\n\n1.5.1 (source: frontmatter, changelog released 2026-08-12, server release)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.5.1:LICENSE\n\nMIT License\n\nCopyright (c) 2026 huiyonghkw (会勇禾口王的AI笔记)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\nArchive v1.5.0: 13 files, 49891 bytes\n\nFiles: CHANGELOG.md (13032b), check.py (31922b), Dockerfile (804b), LICENSE (1096b), README.md (3532b), references/skill-writing-vocab.md (4701b), references/trigger-eval.md (7753b), scripts/trigger_eval.py (16245b), skill-card.md (2293b), SKILL.md (20715b), tests/fixtures/bad/SKILL.md (379b), tests/fixtures/good/SKILL.md (802b), _meta.json (154b)\n\nFile v1.5.0:SKILL.md\n\n---\nname: hekouwang-claude-skill-doctor-skill\nslug: hekouwang-claude-skill-doctor-skill\ndisplayName: Claude Skill 体检器（SKILL.md Doctor）\nsummary: Agent Skill（SKILL.md）体检器：评 description 触发质量 / 篇幅 / 渐进披露 / 脚本外置 / 可移植性 / 安全（无硬编码密钥），出评分卡 + 修复建议。零依赖，claude-md-doctor 的姊妹工具。\nlicense: MIT-0\nhomepage: https://github.com/huiyonghkw/hekouwang-claude-skill-doctor-skill\nversion: 1.5.0\ndescription: >\n  会勇禾口王的AI笔记 · Agent Skill（SKILL.md）体检器。检查一个 Claude/Agent Skill 是否\n  符合\"按需加载的指令包，不是单文件巨石\"的最佳实践——评 description 触发质量、SKILL.md\n  篇幅、渐进披露（references/ 拆分）、脚本外置、可移植性（无硬编码绝对路径）、安全（无硬编码\n  密钥），给出评分卡 + 按优先级的修复建议，并可代为重构。触发：用户说「检查我的 skill /\n  SKILL.md 体检 / 这个 skill 规范吗 / claude-skill-doctor / audit skill / lint SKILL.md /\n  我的 skill 太长了 / skill 拆分 / 看看我的 skill 合不合规 / skill 对齐官方规范」。\n  任何\"评估/审查/优化某个 Agent Skill 质量或结构\"的请求都应触发。\n---\n\n# hekouwang-claude-skill-doctor-skill · Agent Skill 体检器\n\n> **会勇禾口王的AI笔记** 出品 · `@huiyonghkw`\n> _不聊 AI 会不会取代你，只聊先用 AI 的人怎么取代你。_\n\n把\"Agent Skill 最佳实践\"做成一个能跑在任何 skill 上的检查器：机检定量 + 模型定性，\n产出评分卡和可落地的修复建议。核心判据一句话——\n\n> **SKILL.md 是模型\"决定要不要加载、加载后照着做\"的运行时指令包。`description` 决定它何时被唤醒；正文越精简越准；厚重细节要能\"按需展开\"（references/ 用到再读），而不是每次触发就把全部细节灌进上下文。**\n> 一切检查项都从这句推导：这段内容值不值得在 skill 每次触发时都付一次上下文费？能不能下沉到 references/ 用到再读？\n\n### 触发优先 + 减法优先（元判据 · 凌驾全部检查项之上）\n\nSkill 的命脉是两条，权重最高：\n\n1. **触发**：`description` 是模型唯一用来判断\"何时唤醒本 skill\"的信号。写不清\"何时用\"，再好的正文也永远不被加载。\n2. **减法**：SKILL.md 不是图书馆。模型每代都在变强——你塞进正文的通用写法、框架教程、临时脚本，很快既过时又白占 token。**能下沉 references/ 的下沉，能外置 scripts/ 的外置，模型已经会的删掉。**\n\n所以机检里 **#2 触发 / #3 篇幅 / #4 渐进披露 / #6 可移植 / #10 别替模型补** 权重 1.5；\n\"加内容\"类项（#7 最小工具集、#10 配套文档）缺失只算小扣分——别一边喊\"越精简越好\"、一边逼作者把 skill 做臃肿。\n\n## 品牌人设（体检报告的口吻 + 署名）\n\n属于 **会勇禾口王的AI笔记**（定位：AI 实战拆解，硬核·具体·可复制；人设：你办公室里第一个把 AI 用明白的同事）。出体检报告时：\n\n- **口吻**：像同事帮你看代码——直给结论、敢泼冷水（\"这 description 只写了做什么、不写何时用，等于永远不被触发\"），不说客套话。\n- **价值化**：修复建议讲\"省了什么\"（每次触发少灌 100KB 冗余、别人装上不报错、该用时真能被唤醒），不堆术语。\n- **署名**：报告结尾固定带 `—— 会勇禾口王的AI笔记 · @huiyonghkw`。命令行 `check.py` 的报告页脚已内置该署名。\n- **去 AI 味**：定稿前避开\"赋能/打造/至关重要/助力\"等词，说人话。\n\n---\n\n## 免费 / 付费边界（重要）\n\n- **免费（开源内核）**：`check.py` 的**文本 / JSON 报告 + 评分**。任何人本地或进 CI 随便跑。\n- **免费但要自付 API 钱**：`scripts/trigger_eval.py` 触发力实测（工作流 2c）。脚本本身开源随便用，\n  但它每条 query 都真调一次 `claude -p`（约 $0.09–0.15/次），**钱花在用户自己的额度上**。\n  所以它是**可选叠加档、不进默认流程**——`check.py` 的零依赖卖点不受影响，不跑也能出完整体检报告。\n- **付费（增值）**：**品牌可视化体检报告卡**（评分弧 + 等级带 + 明细分享图），依赖 `hekouwang-content-factory` 的私有品牌字体与版式，不随本仓库分发。\n- 一句话口径：**跑检查免费，出\"好看的报告图\"找 @huiyonghkw。** 外部用户要图时说明是付费增值项，别用系统字体凑一张劣化图糊弄。\n\n---\n\n## 工作流（每次体检按这个顺序）\n\n1. **确认目标**：用户没指明就用当前目录；说了某个 skill 就用那个 skill 目录的绝对路径（目录里要有 `SKILL.md`）。若传进来是 `~/.claude/skills/` 这种父目录，脚本会提示里面有哪些 skill，逐个体检。\n2. **跑机检**（确定性层，零依赖）：\n   ```bash\n   python3 <此skill目录>/check.py <skill目录>\n   ```\n   - 需要结构化结果时加 `--json`。退出码：有 FAIL → 1，否则 0。\n2b. **深度安全扫描（可选 · 外部工具 SkillSpector）**：`check.py` 的 #0 只做密钥正则；当要查**提示注入 / 数据外泄 / 隐藏指令 / 供应链 / 过度授权 / MCP 越权**等 68 类模式时，叠加跑 [SkillSpector](https://github.com/NVIDIA/skillspector)（本机已装：`uv tool install`，需 Python 3.12/3.13）：\n   ```bash\n   env -u ALL_PROXY -u all_proxy -u HTTPS_PROXY -u https_proxy \\\n     skillspector scan <纯逻辑副本> --no-llm --format markdown -o report.md\n   ```\n   - **只对\"别人写的、要装进来的\" skill 跑。** 自研 skill 扫出来的实测是 100% 误报（2026-07-15 全量验证 7 个 hekouwang-* skill，逐条翻源码，无一为真），跑了只会浪费时间。\n   - **自研 skill 只做回归检测。** content-factory / yandu-deck / stock-data-reader 三个（会持续改的）已各存一份归零基线在自己目录的 `.skillspector-baseline.yaml`，改完代码后：\n     ```bash\n     skillspector scan <纯逻辑副本> --no-llm --baseline <skill目录>/.skillspector-baseline.yaml\n     ```\n     **冒出来的任何一条都是新的**，值得真翻一眼源码；`--show-suppressed` 看压了什么。基线里的 13/8/4 条已核实为误报（2026-07-15 A/B 验证：yandu-deck `100 CRITICAL DO_NOT_INSTALL` → `0 LOW SAFE`）。改动大到路径/内容 hash 全变时重新 `skillspector baseline <副本> -o …` 存一版。\n   - **分数不是门禁，只看条目。** `Score/Severity` 是**逐条累加**出来的：yandu-deck/iterm2/cc-prod 三个都判 `100/100 CRITICAL · DO NOT INSTALL`，但报告里**一条 CRITICAL 发现都没有**——纯粹是十几条 MEDIUM/HIGH 累加撞顶。且评分随版本通胀：content-factory 代码一行没改，v2.3.5 是 `19/100 SAFE`，v2.3.13 变 `40/100 CAUTION`。**永远读条目、翻源码，别信总评。**\n   - **铁律：只扫逻辑文件，别扫 assets。** 直接扫会把字体 `.woff2`、PNG 等**二进制当代码**，在字节流里刷出几十条假 `TM1 Tool Parameter Abuse`。先用 rsync 拷纯逻辑副本（只留 `.md/.py/.js/.json/.html/.css/.sh/.txt/.yaml`）。⚠️ **`--exclude` 必须写在 `--include='*/'` 前面**（rsync 首次匹配生效，否则 `*/` 先吃掉 `.venv/`，把整个 site-packages 当你的代码扫）：\n     ```bash\n     rsync -a --prune-empty-dirs \\\n       --exclude='.venv/' --exclude='node_modules/' --exclude='.git/' --exclude='__pycache__/' \\\n       --include='*/' --include='*.md' --include='*.py' --include='*.js' --include='*.json' \\\n       --include='*.html' --include='*.css' --include='*.sh' --include='*.txt' --include='*.yaml' \\\n       --exclude='*' <skill目录>/ <副本>/\n     ```\n     实测 content-factory 141M→1.1M、stock-data-reader 264M→176K。\n   - **已知高置信度误报样本**（别被 90%+ 唬住，这些全部核实为假）：`rm -f \"$写死的路径\"` → `TM1 Tool Parameter Abuse` 95%；`subprocess.run([...], check=True)` 硬编码列表 → `OH1 Unvalidated Output Injection` 95% + `AST4`（它建议的 remediation 恰恰就是这个写法）；docstring 里写\"本脚本**绝不读取** .env/*.key\" → `PE3 Credential Access`；字体文件名列表 → `MP2 Context Window Stuffing`；中文 frontmatter → `P2 Hidden Instructions`（置信度 21%，全在 `:1`）；中文触发词 → `AS3 Mixed script`。\n   - **`--baseline` 的 glob `rules` 别乱开。** `rules: {id: \"TM1\"}` 能跨 skill 全局压制，但**扫外来 skill 时恰恰不能用**——今天 TM1 在自研 `rm` 上是误报，在恶意 skill 里可能是真的，全局关掉等于拆探头。跨 skill 只压 `path`+`message` 都限定死的具体条目。\n   - **代理会让扫描直接崩**：SOCKS 代理下报 `Using SOCKS proxy, but the 'socksio' package is not installed`（同 `词级字幕.py` 那个坑），用上面的 `env -u` 绕开。OSV.dev 连不上只是降级到静态库，不影响结论。\n   - 唯一值得看的结构性信号是 **LP1「代码有 network/env/shell 能力但没声明权限」**（7 个自研 skill 中 5 个命中）——不是漏洞，是提醒你 frontmatter 可以补 `allowed-tools`。\n   - `--no-llm` 纯静态、免 key；要更准的行为分析再配 LLM provider（`SKILLSPECTOR_PROVIDER` + 对应 key）。结论并进体检报告的安全维，不替代 #0。\n2c. **触发力实测（可选 · 要花钱 · 只在怀疑 description 时跑）**：机检 #2 只能看出有没有信号词，\n   **判不了写得准不准**——那是本 skill 最大的盲区，因为 description 写不准 = 这个 skill 永远不被唤醒，\n   正文写得再好也白搭。要判准不准就得真跑一遍：\n   ```bash\n   python3 <此skill目录>/scripts/trigger_eval.py \\\n     --eval-set <你的query集>.json --skill-path <skill目录>\n   ```\n   把待测 description 装成临时探针 skill，跑 `claude -p` 看模型会不会去调它。跑完即删，不碰已装的 skill。\n   - ⭐ **先做基准分辨力自检再信分数**：拿真 description 和一段故意写烂的（\"生成内容。\"）\n     跑同一套 query，**分数分不开就说明判据在当前环境失灵**，此时高分也是噪音。\n     实测参考 A=100 / B=50。开发这个脚本时四处配置错误里有三处都表现为\"跑通了、只是分数低\"——\n     不做 A/B 根本发现不了。\n   - **读结果分两种失败**：漏触发＝覆盖不够（补场景句和同义说法）；误触发＝写太宽泛（加边界、换具体动作）。\n     两种都有＝抓错维度，重写而非打补丁。\n   - ⚠️ **要钱**：每条 query 每次采样约 $0.09–0.15，20 条 ×3 次约 $6–9。先用 4–6 条粗筛。\n   - query 怎么设计（尤其**负例必须是 near-miss**）、结果不对劲怎么翻原始流、脚本那四处\n     不能改回去的坑 → 读 [`references/trigger-eval.md`](references/trigger-eval.md)。\n   - **`check.py` 不依赖它**，零依赖那条卖点不受影响；这一档是叠加的，不跑也能出完整体检报告。\n\n3. **定性复核**（机检之上，必须做）：机检是启发式，几项要你**真正读 SKILL.md**再下结论（见下「机检的盲区」）：\n   - 通读 `description`，**真的当一次模型**：光看这段，能不能判断\"什么请求该唤醒它\"？\n   - 通读正文：哪些是\"模型不可能知道的项目/品牌私有事实\"（该留），哪些是\"通用写法/框架教程\"（该删或下沉）？\n   - 若正文很长，看它能不能按\"版本/平台/流程\"天然切成 references/。\n4. **出报告**：先一句话总评 + 分数档位，再用\"✓/▲/✗ + 一句话 + 修复建议\"逐条列，最后给 **Top 3 最该先改的**（按\"花最小力气补最大漏洞\"排序）。中文输出。\n5. **提出代重构**：问用户要不要直接改（瘦身 SKILL.md、拆 references/、外置 scripts/、把硬路径换成 `~`/相对路径、补 description 触发句）。**得到同意再动文件**，一次改一类、可回退；改完**重跑 `check.py`** 给前后对比分数。\n\n> 不要只把脚本输出原样贴给用户——脚本是线索，你的价值在定性判断 + 具体怎么拆。\n\n---\n\n## 评分标准（12 项 · 也是机检的判分依据）\n\n| # | 检查项 | 合格长什么样 | 不合格信号 |\n|---|--------|------------|-----------|\n| 0 | **无硬编码密钥（安全红线）** | SKILL.md 及捆绑文件无 key/token/私钥/口令明文 | 出现 `sk-`/`AKIA`/私钥块/`password=\"...\"` → **直接 FAIL**（skill 常被分发，泄露面更大）<br>⚠️ 测试夹具目录（`test/ tests/ fixtures/ golden/ snapshots/`）里的命中判 **WARN 不判 FAIL**——安全基准的假密钥是刻意载荷，误报会把红线变成摆设 |\n| 1 | **frontmatter 必填合法** | 有 `name`（小写+连字符 ≤64）+ `description` | 缺 name/description → FAIL；name 含大写/下划线/空格 → WARN |\n| 2 | **description 含「何时用」** | 同时写清\"做什么 + 何时/触发用\"（这是被唤醒的唯一依据） | 只写\"做什么\"不写\"何时用\"；或太短没触发信号<br>⚠️ 机检只判\"有没有信号词\"，判不了准不准 —— 要判准不准走**触发力实测**（工作流 2c） |\n| 2b | **description ≤ 1024 字符** | 在上限内，触发稳定 | 超长，可能被截断 |\n| 3 | **SKILL.md ≤ 500 行** | 路由器不是图书馆，按需加载越短越准 | >500 行；分版本/分平台/长流程全塞一个文件 |\n| 4 | **渐进披露（拆 references/）** | 长内容下沉独立 .md，正文留指针 | 正文很长却没有任何 references 拆分文件 |\n| 4b | **指针无死链** | 引用的 `references/*.md` 等带扩展名的捆绑资源真实存在 | 指针指向不存在的文件（按图索骥扑空） |\n| 5 | **脚本外置 scripts/** | 确定性代码（构建/截图/合成/转换）是 scripts/ 真文件 | 大段可执行代码内联在正文，每次靠模型重打 |\n| 6 | **可移植（无硬编码绝对路径）** | 用 `~`/`$HOME`/相对路径/占位 | 出现硬编码家目录绝对路径——别人装上即失效 |\n| 7 | **allowed-tools 最小化** | 声明本 skill 真正需要的工具 | 不声明（继承全部工具，越权面大）——可选项，低权重 |\n| 8 | **触发方式匹配（model vs user invoked）** | 只靠人手敲名字触发的 skill 设 `disable-model-invocation: true`（零 context load） | 明明只手动触发，却留着 description 当 model-invoked，每轮白占上下文（详见 references/skill-writing-vocab.md 第二节）——定性项 |\n| 10a | **别替模型补它已经会的（no-op 测试）** | 只装项目/品牌私有事实 | 有\"语言入门/框架教程/如何使用\"这类教学段——判据：**这段相对模型默认行为改变了什么？没有就删**（即 no-op；详见 vocab 第六节） |\n| 10b | **配套文档（README+CHANGELOG）** | 对外分发友好 | 缺失——纯自用可忽略，低权重 |\n| 11 | **paths / globs 作用域** | 文件专属 skill 声明 glob，减少误触发 | Cursor 2.4+ 可用；未声明 = INFO |\n| 12 | **OpenClaw 兼容声明** | 有 scripts/ 或发 ClawHub 时声明 requires/install | 纯指令 skill 可忽略——INFO |\n\n**分档**：A 优秀 ≥85 · B 良好 ≥70 · C 及格 ≥50 · D 建议重构 <50。\n（机检：PASS=1 / WARN=0.5 / FAIL=0，INFO 不计分。**按重要度加权**——安全红线 #0 与触发/减法核心项 #1/#2/#3/#4/#6/#10a 权重 1.5，标准项 #2b/#4b/#5/#11 为 1.0，加内容项 #7/#10b/#12 为 0.6。#0 命中按 FAIL 计且资损级，定性总评里应一票顶到「先改这条」。）\n\n---\n\n## 机检的盲区（定性复核时重点纠偏）\n\n脚本只判\"机器能确定的\"，以下几项**容易误判，必须你读正文定夺**：\n\n- **#2 触发质量**：脚本只看 description 里有没有\"当…时/use when\"等信号词，**判不了写得准不准**。你要真的当模型读一遍：这段能不能把本 skill 和别的 skill 区分开？会不会该触发时没触发、不该触发时乱触发？\n  - ⭐ **这条现在能实测，别停在拍脑袋**：走工作流 2c 的 `scripts/trigger_eval.py`，\n    \"会不会该触发时没触发、不该触发时乱触发\"正好对应输出里的**漏触发 / 误触发**两个计数。\n    定性读完有怀疑、或者这个 skill 值得下功夫（常用、要分发、要收费），就跑一轮实测坐实。\n    ⚠️ 但**跑之前先做 A/B 基准自检**（真 description vs 一段写烂的），分不开就别信分数。\n- **#3/#4 篇幅 vs 图书馆**：长不一定错——有的 skill 天生信息密度高。但\"分 3 个视觉版本 × 6 个平台\"这种，多半能按维度拆 references/。读结构判断哪些章节是\"用到才看\"的。\n- **#5 脚本外置**：脚本按代码行数/围栏数猜。一段 5 行的示范片段该留正文；一个 80 行的构建/合成脚本该外置。读代码块的\"性质\"定夺。\n- **#10a 别替模型补它已经会的**：脚本按\"教程/如何使用/语言入门\"措辞猜，**会误伤**——比如正文在写\"本项目**自研**流程的用法\"（模型确实不知道，该留），或在\"反对写教程\"。判据是\"这段知识模型升级后会不会自动变强\"：会→删；不会（项目私有）→留。\n- **本 skill 自检会触发 #10a 误报**：因为正文里就列着\"教程/如何使用\"这些**待检测的黑名单词**——这是元层面的正常现象，定性时直接放行。\n\n> **定性诊断词汇**：做 #2/#3/#4/#8/#10a 这些\"机器判不准\"的项时，读 [`references/skill-writing-vocab.md`](references/skill-writing-vocab.md)——它把\"好 skill\"的判据沉淀成可命名的语言（两种载荷、信息阶梯、branch 拆分测试、完成判据防提前收工、no-op 测试、sediment/sprawl/duplication 失败模式、leading word）。出报告时用这些词点破问题，比泛说\"太长/有冗余\"更准。根判据：**skill 是为榨出确定性而存在，根本美德是「每次走同一套过程」可预测。**\n\n---\n\n## 安全红线（务必遵守）\n\n- **绝不读取密钥文件**：`.env` / `*.key` / `*.pem` / `*secret*` 一律不打开（脚本本身也不读）。\n- 体检是只读操作；**任何文件改动都要先说明改哪些、为什么，得到同意再动**。\n- 跨语言/跨用途通用——本 skill 不绑定任何具体技术栈或 skill 类型。\n\n---\n\n## 修复动作清单（用户同意后按需执行）\n\n- **拔密钥（最高优先）**：#0 命中时把明文移出 SKILL.md / 捆绑文件，改放 `.env` / 密钥管理器；命中即视为已泄露，提醒轮换并查 git 历史（skill 很可能已 push 到 GitHub）。\n- **修触发**：#2 不合格时给 description 补\"何时用\"句——列典型请求 / 触发词 / 适用场景，让模型判得出何时唤醒。\n- **瘦身 + 拆 references/**：#3/#4 不合格时，把 SKILL.md 按「版本/平台/流程」维度抽到 `references/` 下的独立 `.md`，正文回归「精简路由 + 硬规矩 + 索引表」。\n- **外置 scripts/**：#5 命中时把确定性脚本抠成 `scripts/` 真文件，正文只留一行调用说明。\n- **去硬路径**：#6 命中时把硬编码家目录路径换成 `~` / `$HOME` / 相对路径 / 「此 skill 目录」占位。\n- **删教学冗余**：#10a 确认是\"教通用写法/框架用法\"的删掉——skill 只装模型不可能知道的私有事实。\n- **修死链**：#4b 报的死指针——补上缺失文件，或修正/删除指针。\n- 改完**重新跑一次 `check.py`** 给前后对比分数。\n\n---\n\n## 落地骨架（建/重写一个 skill 时的推荐结构）\n\n```\nmy-skill/\n├── SKILL.md              # ≤500 行：frontmatter(name+description触发句) + 元判据 + 硬规矩\n│                         #          + 一张「做 X → 读 references/Y」索引表（路由，不堆细节）\n├── references/           # 渐进披露：按版本/平台/流程拆的专题 .md，用到再读\n│   ├── topic-a.md\n│   └── topic-b.md\n├── scripts/              # 确定性可执行脚本（构建/截图/合成/转换），正文只留指针\n├── assets/               # 字体/图片/模板等捆绑资源\n├── README.md             # 给人看（分发用）\n└── CHANGELOG.md          # 版本记录\n```\n\n> SKILL.md 是路由，不是仓库。判据始终是：**这段值不值得每次触发都进上下文？能下沉就下沉。**\n\nFile v1.5.0:tests/fixtures/bad/SKILL.md\n\n---\nname: BadSkill_Example\n---\n\n# Bad Skill\n\n这是一个演示「不合格 skill」的夹具，故意踩坑：\n\n- name 用了大写 + 下划线（应 kebab-case）。\n- **缺 description**——模型无从判断何时加载本 skill（机检会判 FAIL，退出码 1）。\n- 硬编码了绝对路径 /Users/someone/.claude/skills/x/assets/font.woff2（换台机器就废）。\n\nFile v1.5.0:tests/fixtures/good/SKILL.md\n\n---\nname: example-good-skill\ndescription: >\n  生成示例日报。把一段原始数据整理成一页结构化的示例日报。\n  当需要演示「合格 skill 长什么样」或要一份 demo 日报时使用；\n  use when you need a demo daily report.\nallowed-tools:\n  - Read\n  - Write\n---\n\n# Example Good Skill\n\n一个用于演示「合格 skill」的最小夹具：frontmatter 完整、description 写清了\n做什么 + 何时用、正文精简、无硬编码密钥、无绝对路径。\n\n## 何时用\n\n当用户要一份示例日报，或想看一个达标 skill 的结构时。\n\n## 怎么做\n\n1. 读取用户给的原始数据。\n2. 按「概览 / 明细 / 结论」三段整理。\n3. 输出一页 Markdown 日报。\n\n> 正文只放本 skill 私有的约定；通用写法交给模型自己。\n\nFile v1.5.0:README.md\n\n# hekouwang-claude-skill-doctor-skill\n\n> **会勇禾口王的AI笔记** 出品 · `@huiyonghkw`\n> 不聊 AI 会不会取代你，只聊先用 AI 的人怎么取代你。\n\n给 **Agent Skill（SKILL.md）** 做体检的工具。把\"Skill 是按需加载的指令包、不是单文件巨石\"\n这条最佳实践，做成一个能跑在任何 skill 上的检查器：机检定量 + 模型定性，产出评分卡和可落地的修复建议。\n\n姊妹工具：[`hekouwang-claude-md-doctor-skill`](https://github.com/huiyonghkw/hekouwang-claude-md-doctor-skill)（体检 CLAUDE.md）。\n\n## 核心判据\n\n> SKILL.md 是模型\"决定要不要加载、加载后照着做\"的运行时指令包。\n> `description` 决定它何时被唤醒；正文越精简越准；厚重细节要能\"按需展开\"\n> （references/ 用到再读），而不是每次触发就把全部细节灌进上下文。\n\n## 用法\n\n### 在 Claude Code 里（推荐）\n\n直接用**自然语言**喊它，Claude 会自动加载本 skill、在底层跑机检、再做定性复核，给评分卡 + 按优先级的修复建议，并问要不要代为重构：\n\n> - 「帮我体检 `~/.claude/skills/xxx` 这个 skill」\n> - 「我的 SKILL.md 规范吗 / 是不是太长了 / 要不要拆 references」\n> - 「audit this skill」「lint SKILL.md」\n\n### 命令行直接跑（零依赖，仅需 Python 3）\n\n```bash\npython3 check.py <skill目录>          # 输出彩色报告\npython3 check.py <skill目录> --json   # 机器可读 JSON（CI 可用）\n```\n\n退出码：有 FAIL → 1，否则 0（可用于 CI 卡关）。\n\n### Docker（不想装 Python 也能跑）\n\n```bash\n# 拉官方镜像直接用（打 v* tag 时 GitHub Actions 自动发布到 GHCR）\ndocker run --rm -v \"$PWD:/work\" ghcr.io/huiyonghkw/hekouwang-claude-skill-doctor-skill\n\n# 或本地自建\ndocker build -t claude-skill-doctor .\ndocker run --rm -v \"$PWD:/work\" claude-skill-doctor            # 体检挂载的 skill\ndocker run --rm -v \"$PWD:/work\" claude-skill-doctor /work --json\n```\n\n### 接进 CI 卡关（GitHub Actions 示例）\n\n```yaml\n- uses: actions/setup-python@v5\n  with: { python-version: \"3.x\" }\n- name: SKILL.md 体检（不合格则拦 PR）\n  run: |\n    curl -sO https://raw.githubusercontent.com/huiyonghkw/hekouwang-claude-skill-doctor-skill/main/check.py\n    python3 check.py path/to/your/skill\n```\n\n本仓库自身的 CI 见 [`.github/workflows/ci.yml`](.github/workflows/ci.yml)（语法 + good/bad 夹具 + JSON 合法性）。\n\n## 检查项（12 项加权）\n\n| 权重 | 项 |\n|---|---|\n| **1.5（核心）** | 无硬编码密钥 · frontmatter 必填合法 · description 含「何时用」 · SKILL.md ≤500 行 · 渐进披露(拆 references/) · 可移植(无硬编码绝对路径) · 别替模型补它已会的 |\n| 1.0（标准） | description ≤1024 · 指针无死链 · 脚本外置 scripts/ |\n| 0.6（加内容） | allowed-tools 最小化 · 配套文档(README+CHANGELOG) |\n\n分档：A ≥85 · B ≥70 · C ≥50 · D <50。\n\n## 机检 vs 定性\n\n`check.py` 只判机器能确定的部分。**description 触发得准不准、正文是不是\"图书馆\"、\n是不是在替模型补它已会的知识**——这些要人/模型读正文复核（脚本会标出疑点）。\n完整定性流程见 `SKILL.md`。\n\n## 免费 / 付费\n\n- **免费**：`check.py` 的文本 / JSON 报告 + 评分，随便用、可进 CI。\n- **付费增值**：品牌可视化体检报告卡（精美分享图），找 `@huiyonghkw`。\n\n---\n\n—— 会勇禾口王的AI笔记 · @huiyonghkw\n\nFile v1.5.0:_meta.json\n\n{\n  \"ownerId\": \"kn73qd1gcmjr446mwcbdxef70x82vxcw\",\n  \"slug\": \"hekouwang-claude-skill-doctor-skill\",\n  \"version\": \"1.5.0\",\n  \"publishedAt\": 1786517941457\n}\n\nFile v1.5.0:references/skill-writing-vocab.md\n\n# Skill 写作词汇与进阶判据（定性复核时用）\n\n这套词汇消化自 mattpocock/skills 的 `writing-great-skills`。它给\"什么是好 skill\"补了一层**可命名的诊断语言**——体检时用这些词点破问题，比泛泛说\"太长/有冗余\"更准、更可落地。\n\n> 一句话根：**skill 存在是为了从随机系统里榨出确定性。根本美德是「可预测」——每次运行走同一套*过程*（不是产出同一结果）。下面每条判据都为它服务。**\n\n## 一、两种\"载荷\"——这是\"减法\"的底层账\n\n- **context load（上下文载荷）**：model-invoked skill 的 `description` 每轮都待在上下文窗口里，是持续成本。正文越长，每次触发付的越多。\n- **cognitive load（认知载荷）**：user-invoked skill 不进模型视野，只靠**你**记得它存在——成本转嫁到人脑。\n- 当 user-invoked skill 多到记不住，就用一个 **router skill**（一个 user-invoked skill 列出其余的\"何时用哪个\"）来治认知载荷。\n\n## 二、触发方式：model-invoked vs user-invoked（体检新增维度 #8）\n\n- **model-invoked**（默认，省略 `disable-model-invocation`）：保留 description，模型能自主触发、别的 skill 也能调到它。代价是 context load。\n- **user-invoked**（设 `disable-model-invocation: true`）：description 变成给人看的一行摘要，模型够不到，**零 context load**。\n- **判据**：这个 skill 是不是**只可能靠人手敲名字**触发？若是 → 该设 user-invoked，别让它的 description 白占每轮上下文。只有\"模型必须自己判断何时唤醒\"或\"别的 skill 要调它\"时，才值得付 model-invoked 的常驻成本。\n\n## 三、信息阶梯（progressive disclosure 的标尺）\n\n三级，按\"模型多急需\"排：① **in-skill step**（SKILL.md 里的有序动作）② **in-skill reference**（按需查的定义/规则，可以是一组平级规则，不是坏味道）③ **external reference**（推到独立文件、靠 context pointer 触发才加载）。\n\n- **branch（分支）= 最干净的拆分测试**：每个分支都要的 → 内联；只有部分分支会走到的 → 推到指针后面。\n- **co-location（就近）**：一个概念的定义+规则+注意事项放同一标题下，别散落。\n- **context pointer 的措辞**（不是它指向哪）决定模型何时、多可靠地去读那块。\n\n## 四、完成判据（completion criterion）——防\"提前收工\"\n\nstep 类 skill 的每一步要以一个**可检验**的完成条件收尾（模型能分辨\"做完了 vs 没做完\"）；关键处还要**穷尽**（\"每个改过的模型都交代了\"，而不是\"产出一个变更清单\"）。判据含糊 → 招致 **premature completion**（注意力滑向\"算完成了\"而提前结束）。\n\n## 五、leading word（引导词）\n\n一个模型预训练里已有的**紧凑概念**（如 _tight / red / tracer bullets_），在文里复用，用极少 token 锚定一整片行为。两处获益：正文里锚定**执行**（一见这词就走同一行为），description 里锚定**触发**（你 prompt/文档/代码里都用这词，模型更可靠地联想到该 skill）。把\"快、确定、低开销\"这种三词重述坍缩成一个 _tight_——既省 token 又给模型更锐的挂钩。体检时主动找\"能被一个引导词退休掉的重述\"。\n\n## 六、失败模式词汇（诊断用，点名比泛指有力）\n\n- **premature completion**：步骤没真做完就收。先磨锐完成判据（便宜、就地）；判据已无法再细化且确实观察到抢跑，才用\"按序列拆分\"把后续步骤藏起来。\n- **duplication**：同一意思出现在多处。费维护、费 token，还把它在阶梯上的\"显要度\"抬高过真实等级。守则：每个意思**单一真相源**，改行为只改一处。\n- **sediment（沉积）**：旧内容层层留下——\"加着安全、删着危险\"的默认结局。没有修剪纪律的 skill 必然积沉。\n- **sprawl（臃肿）**：纯粹太长，即便每行都还活着且唯一。解药是阶梯：reference 推到指针后、按 branch/序列拆，让每条路径只背自己要的。\n- **no-op（空操作）**：模型默认就会做的话，付了载荷却没说事。**测试：这行相对默认行为改变了什么？没有 → 删**。弱引导词（\"要认真\"而模型本就够认真）就是 no-op，修法是换更强的词（\"relentless\"），不是换技巧。\n\n## 修剪纪律\n\n逐**句**（不是逐行）跑 no-op 测试：某句在孤立状态下不改变行为 → **整句删掉**，别只删词。要狠——失败的散文多数该删，不是重写。\n\nFile v1.5.0:references/trigger-eval.md\n\n# 触发力实测（trigger eval）· 怎么设计 query、怎么读结果\n\n> 机检 #2 只能看出 description 里**有没有**\"当…时/use when\"这类信号词，判不出**写得准不准**。\n> 这份文档配 `scripts/trigger_eval.py`，补的是那一层：真跑一遍，看模型会不会被这段 description 唤醒。\n> ⚠️ 需要 `claude` CLI，**会产生真实费用**（每条 query 每次采样约 $0.09–0.15）。\n> `check.py` 不依赖它，零依赖那条卖点不受影响。\n\n## 0. ⭐ 跑之前必做：基准分辨力自检（不做就别信任何分数）\n\n**先喂一个已知好的和一个已知烂的，看分数分不分得开。** 分不开说明这套判据在你的环境里失灵，\n此时任何分数都是噪音——包括那个看起来很健康的高分。\n\n```bash\n# A 组：真 description\npython3 scripts/trigger_eval.py --eval-set queries.json --skill-path <skill> --label A\n\n# B 组：同一套 query，换一段故意写烂的 description\nprintf '生成内容。\\n' > /tmp/bad-desc.txt\npython3 scripts/trigger_eval.py --eval-set queries.json --skill-path <skill> \\\n  --description-file /tmp/bad-desc.txt --label B\n```\n\n**判据**：A 明显高于 B（实测参考：A=100 / B=50，4 条 query）才算这套 eval 在你机器上有效。\n两组同分 = 判据失灵，先去查第 4 节。\n\n> 这不是形式主义。开发本脚本时，前后四处配置错误里有**三处**都表现为\n> \"跑通了、只是分数低\"——不做 A/B 根本发现不了，会拿一堆假分数去改 description。\n\n## 1. eval query 怎么写\n\n**数量**：20 条左右，正例 8–10、负例 8–10。想省钱可以先用 4–6 条粗筛，方向对了再补齐。\n\n**质量三条**：\n\n1. **写成用户真会打出来的一整段话**，不是抽象任务名。要有具体文件名、路径、栏目名、\n   数字、背景交代，可以有口语、缩写、错别字、全小写。\n   - ❌ `\"生成小红书图文\"`\n   - ✅ `\"帮我把这篇讲 uv 的文章做成一套小红书图文，8 张 1080x1440，用 V2 米白那套视觉，封面要有数字锚点\"`\n\n2. **正例要覆盖不同说法**。同一个意图，有正式的、有随口的；**要有几条不点名品牌/不提专有名词**\n   的（\"我写完一篇稿子想发公众号，帮我出文章母本和配图\"）——这类最能检验 description\n   有没有把使用场景说清楚，而不是靠关键词硬碰。\n\n3. ⭐ **负例必须是 near-miss**。共享关键词或概念、但其实该走别的工具的请求，才有检验力。\n   - ❌ `\"帮我写个快排\"`（对内容工厂来说太远，测不出任何东西）\n   - ✅ `\"帮我给这个 React 项目做个好看的产品落地页\"`（同样是\"做视觉\"，但属前端）\n   - ✅ `\"帮我看下上周几篇小红书笔记数据，哪篇曝光最高\"`（提了小红书，但是数据分析）\n\n**别用的 query**：一步就能做完的简单请求（\"读一下这个文件\"）。模型对自己就能轻松搞定的事\n本来就不查 skill，这种用例无论 description 写得多好都不会触发，纯粹浪费钱。\n\n格式：\n\n```json\n[\n  {\"query\": \"……\", \"should_trigger\": true,  \"note\": \"正1·核心场景\"},\n  {\"query\": \"……\", \"should_trigger\": false, \"note\": \"负1·near-miss 同是做视觉但属前端\"}\n]\n```\n\n## 1.5 ⭐ 负例必须带干扰项跑，否则结论是假的\n\n探针环境默认**只有被测 skill 一个候选**。模型 `ls` 完发现没别的可选，\n就会勉强用手头这个——**负例于是系统性假阳性**。\n\n实测（content-factory · 同一套 6 条 query · 同一段 description）：\n\n| 环境 | 得分 | 那条\"翻页演示版网页\"负例 |\n|---|---|---|\n| 无竞争者 | **83**（5/6） | ✗ 误触发 |\n| 放 5 个兄弟 skill 当竞争者 | **100**（6/6） | ✓ 正确避开 |\n\n**同一段 description，什么都没改，分数差 17 分。** 按 83 分那个数字去\"修边界\"，\n修的是一个不存在的问题。\n\n```bash\npython3 scripts/trigger_eval.py --eval-set queries.json --skill-path <skill> \\\n  --distractors ~/.claude/skills/其它skill-A ~/.claude/skills/其它skill-B ...\n```\n\n选谁当干扰项：**功能相邻、最可能抢活的那几个**。自己有一套 skill 的话，\n把兄弟们全带上最省事，也最接近真实环境。\n\n⚠️ **干扰项的名字也被中性化成 `alt-xxx`，这是故意的**。若让干扰项挂真名\n（`yandu-deck` 之类）而被测探针挂中性名，模型光看名字就能认出干扰项，\n等于给对手开外挂——测出来的仍旧是名字不是 description，跟第 4 节第 4 条同一个坑。\n\n> 正例也别忘了看：竞争者在场时正例**仍应触发**。若加了干扰项后正例掉了，\n> 说明 description 的区分度不够，被邻居抢走了——这才是真该改的信号。\n\n## 2. 怎么读结果\n\n分数只是入口，**两种失败要分开看，修法完全不同**：\n\n| 症状 | 含义 | 怎么改 description |\n|---|---|---|\n| **漏触发**（该触发的没触发） | 覆盖面不够，用户换个说法就唤不醒 | 补场景句和同义说法；把用户真实的口语表达写进去 |\n| **误触发**（不该触发的触发了） | 写太宽泛，抢别的工具的活 | 加边界（\"不用于 X\"）；把泛词换成具体动作与产物 |\n\n同时出现两种 = description 抓错了维度，重写而不是打补丁。\n\n采样次数：默认 `--runs-per-query 1` 省钱。触发是概率性的，要下正式结论用 `3`\n（成本 ×3），此时触发率 ≥0.5 判通过。\n\n## 3. 结果不对劲时\n\n先用 `--dump-dir` 把原始流存下来翻，**别猜**：\n\n```bash\npython3 scripts/trigger_eval.py ... --dump-dir /tmp/dumps\n```\n\n翻的时候重点看两样：模型的**工具调用序列**（它到底做了什么），\n以及 Skill/Read 调用里的**实际参数**（是不是调到了别的东西）。\n本脚本历史上两次假阴性都是靠翻这个抓出来的。\n\n## 4. 脚本为什么这么写（改它之前先读这节）\n\n本脚本改自官方 `anthropics/skills · skill-creator/scripts/run_eval.py`。\n官方思路对，但原样跑在 Claude Code 2.1.220 上**测不出任何东西**。四处都改完才有分辨力——\n**这四处是踩出来的，改脚本时别顺手改回去**：\n\n1. **`--setting-sources project`**：不加则子进程继承 `~/.claude/skills/` 里已装的真 skill\n   （实测 32 个），模型去触发真身、名字对不上探针 → 全部正例假阴性。\n   官方没料到\"被测 skill 已经装在机器上\"这种情况。\n\n2. **扫完整个流才判否**：官方是\"第一个 tool_use 不是 Skill/Read 就 return False\"。\n   但模型碰到陌生 skill 名**会先 `Bash: ls` 探查环境**，Skill 往往是第二三个动作\n   （实测序列 `['Bash','Bash','Skill']`）——真触发了却被判没触发。\n\n3. **每条 query 独立 project root**：共用目录时并发 worker 把探针全丢一处，\n   模型会调到**别人的**探针（实测：期望 `-d795b59f`，实际调 `-4ac07ae5`），自己这条判否。\n\n4. ⭐ **探针要装成 project 级真 skill，且名字中性（`probe-xxxxxxxx`）**：\n   init 事件里 `skills` 和 `slash_commands` 两个列表**都只给名字、不给 description**。\n   探针一旦沿用原 skill 名，模型光看名字就去 Read 它，**description 全程没参与决策**——\n   实测此时 447 字真 description 和 5 字\"生成内容。\"**都是满分**，等于白测。\n\n## 5. 成本\n\n| 规模 | 调用数 | 约合 |\n|---|---|---|\n| 粗筛 4 条 × 1 次 | 4 | $0.5 |\n| 正式 20 条 × 1 次 | 20 | $2–3 |\n| 结论 20 条 × 3 次 | 60 | $6–9 |\n\n先粗筛、方向对了再上规模。A/B 基准自检要算两轮。\n\nFile v1.5.0:CHANGELOG.md\n\n# Changelog\n\n本项目遵循 [语义化版本](https://semver.org/lang/zh-CN/)。\n\n## [1.5.0] - 2026-08-12\n\n### 新增\n- **#11 paths / globs**：识别 Cursor 2.4+ 文件作用域 frontmatter，减少无关文件时的误触发。\n- **#12 OpenClaw 兼容声明**：轻量检查 `metadata.openclaw`、`requires`、`install`（有 scripts/ 时提示）。\n\n### Fixed\n- **指针扫描误报**：只匹配带扩展名的捆绑资源路径（`references/foo.md`），表格里的\n  `references/scripts/assets` 不再被判死链。\n- **可移植性自检误报**：`ABS_PATH_RE` 用字符串拼接构建，避免 `check.py` 源码里的\n  正则说明行被当成硬编码路径。\n- **#10a 元层面误报**：评分表/检查项表格行里的黑名单示例词不再计为教学冗余。\n\n## [1.4.1] - 2026-08-01\n\n修 #0 安全红线的两处假阳性。**假阳性会让红线失去意义**——被误报训练过的人下次看到真 FAIL 也只会挥手放过。\n\n### Fixed\n- **`sk-` 密钥正则缺左词界**：`sk-(?:ant-)?[\\w-]{20,}` 会从 `generate-ask-user-format.ts`\n  里抠出 `sk-user-format` 判成 key。同一份 `SECRET_PATTERNS` 里 `AKIA` / `AIza` / `JWT`\n  三条都带 `\\b`，只有这条漏了。实测某第三方 skill 因此被判资损级 FAIL（62 分），\n  命中源全是 `ask-user-*` 文件名。\n- **测试夹具里的假密钥降级 WARN**：安全基准/回归夹具（`test/ tests/ fixtures/ golden/ snapshots/`\n  等目录）里的 key 是刻意载荷，不是泄露。现在只在夹具命中时判 WARN 并提示\"翻一眼确认\"，\n  正文/脚本命中照旧 FAIL；两类同时命中时 FAIL 优先，detail 里标明夹具那几处已降级。\n\n### 验证（A/B 基准分辨力自检）\n三类样本必须判出三种结果，否则说明改完的判据分不开对和错：\n真密钥 `sk-proj-…` → **FAIL**；夹具里 `sk-ant-api03-…` → **WARN**；`ask-user-question-format` → **PASS**。\n回归夹具分数不变（`tests/fixtures/bad` 67、`good` 100）。\n\n## [1.4.0] - 2026-07-28\n\n补上本器最大的盲区：**#2 触发质量以前只能拍脑袋，现在能实测**。\n静态检查只看得出 description 里有没有\"当…时\"这类信号词，判不了写得准不准——\n而 description 写不准 = 这个 skill 永远不被唤醒，正文写得再好也白搭。\n\n### Added\n- **`scripts/trigger_eval.py` · 触发力实测（可选第二引擎）**：把待测 description 装成临时探针 skill，\n  跑 `claude -p` 看模型会不会去调它，输出触发力分数 + **漏触发 / 误触发**两个计数。跑完即删，\n  不碰任何已装的 skill。改自官方 `anthropics/skills · skill-creator/run_eval.py`。\n- **`--distractors` 干扰项**：把其它 skill 的 description 一起放进探针环境当竞争者。\n  不加的话环境里只有被测探针一个候选，模型\"没得选\"就会勉强用它，**负例系统性假阳性**。\n  实测同一段 description、同一套 query：无竞争者 **83 分**（那条\"翻页演示版\"负例误触发），\n  放 5 个兄弟 skill 后 **100 分**（正确避开）——**什么都没改，差 17 分**。\n  按 83 分去修边界，修的是一个不存在的问题。\n  干扰项名字同样中性化成 `alt-xxx`，否则模型看名字就能认出对手，等于开外挂。\n- **`references/trigger-eval.md`**：query 怎么设计（**负例必须是 near-miss**）、\n  **负例必须带干扰项跑**、两种失败各自怎么改 description、结果不对劲怎么翻原始流、成本表。\n- 工作流新增步骤 **2c**；检查项 #2 与「机检的盲区」#2 同步改写。\n\n### Changed\n- 免费/付费边界补一档：`trigger_eval.py` **脚本开源随便用，但 API 费用走用户自己的额度**\n  （约 $0.09–0.15/次调用）。因此它是**可选叠加档、不进默认流程**，\n  `check.py` 的零依赖卖点不受影响，不跑也能出完整体检报告。\n\n### 踩坑记录：官方脚本原样搬过来测不出任何东西\n\n官方那版思路对，但在 Claude Code 2.1.220 上四处全错，**改完才有分辨力**\n（实测：真 description 100 分 vs \"生成内容。\"50 分；不改第 4 条时两者都是 100，等于白测）。\n四处里**前三处都表现为\"跑通了、只是分数低\"**，不做 A/B 基准根本发现不了：\n\n1. 不加 `--setting-sources project` → 子进程继承 `~/.claude/skills/` 里已装的真 skill（实测 32 个），\n   模型触发真身、名字对不上探针 → **全部正例假阴性**。官方没料到\"被测 skill 已装在机器上\"。\n2. 官方\"第一个 tool_use 不是 Skill/Read 就判否\" → 但模型碰到陌生 skill 名**会先 `Bash: ls` 探查**，\n   Skill 往往是第二三个动作（实测序列 `['Bash','Bash','Skill']`）。改为扫完整个流、命中即收工。\n3. 并发 worker 共用一个 project root → 模型调到**别人的**探针\n   （实测：期望 `-d795b59f`，实际调 `-4ac07ae5`）。改为每条 query 一个一次性 root。\n4. ⭐ 探针放 `.claude/commands/` 且沿用原 skill 名 → init 事件里 `skills` / `slash_commands`\n   两个列表**都只给名字、不给 description**，模型光看名字就去 Read 它，\n   **description 全程没参与决策**。改为装成 project 级真 skill + 中性名 `probe-xxxxxxxx`。\n\n⭐ 因此文档把「**先做 A/B 基准分辨力自检，分不开就别信分数**」写成了跑之前的强制前置步骤，\n不是建议。\n\n## [1.3.0] - 2026-07-15\n\n**版本号说明**：本次内容即原定的 1.2.0（见下方 Changed/Added），因发布事故改号为 1.3.0——\nClawHub 上 `hekouwang-claude-skill-doctor-skill` 这个 slug 于 2026-07-09 被误发成 **md-doctor 的内容**\n并占用了 1.2.2 这个版本号（check.py 与 md-doctor 逐字节同 hash `5f0d3613`、测试夹具是 `CLAUDE.md`\n而非 `SKILL.md`）。该 slug 在 2026-06-24 的 1.0.2 / 1.0.3 是正确的 skill-doctor 内容，\n即**误发覆盖了正确版本**。需发一个高于 1.2.2 的版本才能把 latest 拨正，故跳到 1.3.0。\n误发的 1.2.2 已从该 slug 永久删除，版本史现为 1.0.2 → 1.0.3 → 1.3.0。\n\n### Fixed\n- **ClawHub 发布事故更正**：`hekouwang-claude-skill-doctor-skill@1.2.2` 实为 md-doctor，已删除；\n  latest 拨回真正的 Agent Skill 体检器。\n- **发布纪律**：以后 `clawhub skill publish` **一律显式传 `--version`**——\n  ClawHub 不读 SKILL.md 的 `version`，只在线上版本上 +1（实测会把本地 1.2.2 发成 1.1.3、\n  本地 1.1.0 发成 0.1.2，即**降级**）。自动推断不可信。\n\n拿真数据校准步骤 2b 的 SkillSpector。全量扫 7 个 `hekouwang-*` skill、逐条翻源码核实，\n结论推翻 1.1.0 的乐观假设：**对自研 skill 它 100% 误报**，且**分数完全不可信**。\n2b 从\"可选加跑的安全维\"收紧为\"只对外来 skill 跑的入库审查\"。\n\n### Changed\n- **2b 定位收紧：只对\"别人写的、要装进来的\" skill 跑。** 7 个自研 skill 全扫、逐条翻源码，\n  无一为真。自研 skill 改走**回归检测**（存基线 → 只看 NEW），不再全量看告警。\n- **新增铁律「分数不是门禁，只看条目 + 翻源码」。** `Score/Severity` 是逐条**累加**的：\n  yandu-deck / iterm2 / cc-prod 三个判 `100/100 CRITICAL · DO NOT INSTALL`，\n  但报告里**一条 CRITICAL 发现都没有**——纯粹是十几条 MEDIUM/HIGH 累加撞顶。\n  且评分随版本通胀：content-factory 代码一行没改，v2.3.5 `19/100 SAFE` → v2.3.13 `40/100 CAUTION`。\n- **推翻 1.1.0 的「低可信度才是误报」说法**：95% 高可信度的照样是误报。改为附**高置信度误报样本表**：\n  `rm -f \"$写死路径\"` → `TM1` 95%；`subprocess.run([...], check=True)` 硬编码列表 →\n  `OH1 Unvalidated Output Injection` 95% + `AST4`（其 remediation 建议的恰恰就是这个写法）；\n  docstring 写\"本脚本**绝不读取** .env/*.key\" → `PE3 Credential Access`；\n  字体文件名列表 → `MP2 Context Window Stuffing`；中文 frontmatter → `P2 Hidden Instructions` 21%；\n  中文触发词 → `AS3 Mixed script`。\n\n### Added\n- **rsync `--exclude` 顺序坑**：必须排在 `--include='*/'` 前面（rsync 首次匹配生效，\n  否则 `*/` 先吃掉 `.venv/`，整个 site-packages 被当自己的代码扫）。实测 stock-data-reader 264M→176K。\n- **SOCKS 代理绕法**：代理下扫描直接崩（`'socksio' package is not installed`），\n  需 `env -u ALL_PROXY -u all_proxy -u HTTPS_PROXY -u https_proxy`。OSV.dev 连不上只降级静态库，不影响结论。\n- **`--baseline` 正确用法 + 反例**：`fingerprints` 按「路径+内容 hash」锁定、只对同一 skill 生效；\n  能跨 skill 的 glob `rules`（如 `id: \"TM1\"`）**恰恰不能在扫外来 skill 时开**——\n  同一规则在自研 `rm` 上是误报、在恶意 skill 里可能是真的，全局关掉等于拆探头。\n- content-factory / yandu-deck / stock-data-reader 三个常改的 skill 各存一份归零基线\n  （`.skillspector-baseline.yaml`，A/B 验证：yandu-deck `100 CRITICAL DO_NOT_INSTALL` → `0 LOW SAFE`）。\n- 记录唯一有信号的结构性告警 **LP1「代码有 network/env/shell 能力但没声明权限」**（7 个中 5 个命中）——\n  不是漏洞，与 `check.py` 自检的「未声明 allowed-tools」指向同一缺口。\n\n## [1.1.0] - 2026-06-24\n\n接入外部安全扫描、消化业界 skill 写作最佳实践，扩展体检维度。\n\n### Added\n- **工作流新增步骤 2b · 深度安全扫描（可选）**：叠加 [NVIDIA SkillSpector](https://github.com/NVIDIA/skillspector)，\n  覆盖提示注入 / 数据外泄 / 隐藏指令 / 供应链 / 过度授权 / MCP 越权等 68 类模式，\n  补 `check.py` #0 密钥正则之外的深度安全维。含实战铁律：**只扫逻辑文件、别扫 assets**\n  （直接扫会把字体/图片二进制当代码，刷出几十条假 `TM1 Tool Parameter Abuse`）；\n  低可信度（<30%）`Hidden Instructions` 多是中文/零宽字符误报，人工复核。\n- **评分维度 #8 触发方式匹配（model vs user invoked）**：只靠人手敲名字触发的 skill\n  应设 `disable-model-invocation: true`，省掉每轮 `description` 的 context load。\n- **`references/skill-writing-vocab.md`**：消化 mattpocock/skills 的 *writing-great-skills*，\n  把\"好 skill\"的判据沉淀成可命名的诊断词汇——两种载荷（context/cognitive load）、\n  信息阶梯、branch 拆分测试、完成判据（防 premature completion）、no-op 测试、\n  sediment/sprawl/duplication 失败模式、leading word。出报告时用这些词点破问题。\n\n### Changed\n- **#10a 锐化为 no-op 测试**：判据明确为「这段相对模型默认行为改变了什么？没有就删」，\n  比原先\"别替模型补它已经会的\"更可操作。\n\n## [1.0.2] - 2026-06-22\n\n实战体检三个品牌 skill 时暴露的机检缺陷修复（dogfooding）：\n\n### Fixed\n- **#7 allowed-tools 兼容逗号字符串**：原先只认 YAML 列表（`- a` / `[a,b]`），\n  把官方 frontmatter 标准的逗号字符串写法（`allowed-tools: Bash, Read, Write`）\n  误判为「未声明」。现在两种写法都解析、非空即 PASS。\n\n## [1.0.1] - 2026-06-21\n\n实战体检 14 个 skill 时暴露的两个机检缺陷修复（dogfooding）：\n\n### Fixed\n- **glob 指针不再误报死链**：`reference/deck-engine-*.html` 这类通配符指针，\n  现在用 `glob` 解析、能匹配到真实文件就算存在；`{a,b}` brace 简写跳过不误报。\n  （原正则在 `*` 处截断成 `reference/deck-engine-`，当字面路径判死。）\n- **指针 / 教学词行号还原为文件绝对行号**：原先报的是正文相对行号（少算了\n  frontmatter 行数），定位会偏。`parse_frontmatter` 现返回 `body_offset` 补正。\n\n## [1.0.0] - 2026-06-21\n\n首个版本。给 Agent Skill（SKILL.md）做体检的零依赖检查器。\n\n### 检查项（12 项加权）\n- **安全**：SKILL.md 及捆绑文件无硬编码密钥（命中即 FAIL，资损级）。\n- **触发**：frontmatter 必填合法（name/description）；description 含「何时用」且 ≤1024 字符。\n- **减法**：SKILL.md ≤500 行；长内容下沉 references/（渐进披露）；大段脚本外置 scripts/。\n- **可移植**：无硬编码 `/Users/`、`/home/` 绝对路径。\n- **取舍**：别替模型补它已会的（教学冗余检测）；allowed-tools 最小化；配套 README/CHANGELOG。\n\n### 特性\n- 零依赖（Python3 标准库），文本 + `--json` 双输出，退出码随 FAIL。\n- 按重要度加权评分（触发/减法核心项 1.5，标准项 1.0，加内容项 0.6），A/B/C/D 分档。\n- 极简零依赖 frontmatter 解析（块标量 / 行内 list / 缩进 list）。\n- 密钥扫描双档豁免：指纹型用窄填充表、赋值型用宽占位表，避免误杀真 key。\n- 报告口吻与署名沿用「会勇禾口王的AI笔记」品牌人设。\n\nFile v1.5.0:skill-card.md\n\n## Description:\n\nClaude Skill Doctor audits Agent Skill directories for trigger quality, SKILL.md size, progressive disclosure, external scripts, portability, and credential hygiene, then returns a scorecard and prioritized remediation guidance.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[huiyonghkw](https://clawhub.ai/user/huiyonghkw)\n\n### License/Terms of Use:\n\nMIT\n\n## Use Case:\n\nDevelopers and skill authors use this skill to review Claude or Agent Skill packages before local use, CI gating, or publication, and to get concrete fixes or refactoring suggestions.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: CI examples that download check.py from a moving branch can run changed code without an explicit review step.\n\nMitigation: Pin the script to a release or commit and verify integrity, or vendor the bundled check.py.\n\nRisk: Optional trigger evaluation uses the local Claude CLI session and can incur user account costs.\n\nMitigation: Run trigger evaluation only when explicitly desired, start with a small evaluation set, and confirm the local Claude credentials and budget before use.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/huiyonghkw/skills/hekouwang-claude-skill-doctor-skill)\n- [Source repository](https://github.com/huiyonghkw/hekouwang-claude-skill-doctor-skill)\n- [Skill writing vocabulary](references/skill-writing-vocab.md)\n- [Trigger evaluation guide](references/trigger-eval.md)\n- [NVIDIA SkillSpector](https://github.com/NVIDIA/skillspector)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, JSON, Shell commands, Code, Configuration, Guidance]\n\n**Output Format:** [Markdown reports with optional JSON check output and inline shell commands]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Can include prioritized remediation recommendations and proposed file edits.]\n\n## Skill Version(s):\n\n1.5.0 (source: SKILL.md frontmatter, CHANGELOG, server release metadata, released 2026-08-12)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.5.0:LICENSE\n\nMIT License\n\nCopyright (c) 2026 huiyonghkw (会勇禾口王的AI笔记)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\nArchive v1.4.1: 13 files, 48821 bytes\n\nFiles: CHANGELOG.md (12328b), check.py (29184b), Dockerfile (804b), LICENSE (1096b), README.md (3532b), references/skill-writing-vocab.md (4701b), references/trigger-eval.md (7753b), scripts/trigger_eval.py (16245b), skill-card.md (2687b), SKILL.md (20542b), tests/fixtures/bad/SKILL.md (379b), tests/fixtures/good/SKILL.md (802b), _meta.json (154b)\n\nFile v1.4.1:SKILL.md\n\n---\nname: hekouwang-claude-skill-doctor-skill\nslug: hekouwang-claude-skill-doctor-skill\ndisplayName: Claude Skill 体检器（SKILL.md Doctor）\nsummary: Agent Skill（SKILL.md）体检器：评 description 触发质量 / 篇幅 / 渐进披露 / 脚本外置 / 可移植性 / 安全（无硬编码密钥），出评分卡 + 修复建议。零依赖，claude-md-doctor 的姊妹工具。\nlicense: MIT-0\nhomepage: https://github.com/huiyonghkw/hekouwang-claude-skill-doctor-skill\nversion: 1.4.1\ndescription: >\n  会勇禾口王的AI笔记 · Agent Skill（SKILL.md）体检器。检查一个 Claude/Agent Skill 是否\n  符合\"按需加载的指令包，不是单文件巨石\"的最佳实践——评 description 触发质量、SKILL.md\n  篇幅、渐进披露（references/ 拆分）、脚本外置、可移植性（无硬编码绝对路径）、安全（无硬编码\n  密钥），给出评分卡 + 按优先级的修复建议，并可代为重构。触发：用户说「检查我的 skill /\n  SKILL.md 体检 / 这个 skill 规范吗 / claude-skill-doctor / audit skill / lint SKILL.md /\n  我的 skill 太长了 / skill 拆分 / 看看我的 skill 合不合规 / skill 对齐官方规范」。\n  任何\"评估/审查/优化某个 Agent Skill 质量或结构\"的请求都应触发。\n---\n\n# hekouwang-claude-skill-doctor-skill · Agent Skill 体检器\n\n> **会勇禾口王的AI笔记** 出品 · `@huiyonghkw`\n> _不聊 AI 会不会取代你，只聊先用 AI 的人怎么取代你。_\n\n把\"Agent Skill 最佳实践\"做成一个能跑在任何 skill 上的检查器：机检定量 + 模型定性，\n产出评分卡和可落地的修复建议。核心判据一句话——\n\n> **SKILL.md 是模型\"决定要不要加载、加载后照着做\"的运行时指令包。`description` 决定它何时被唤醒；正文越精简越准；厚重细节要能\"按需展开\"（references/ 用到再读），而不是每次触发就把全部细节灌进上下文。**\n> 一切检查项都从这句推导：这段内容值不值得在 skill 每次触发时都付一次上下文费？能不能下沉到 references/ 用到再读？\n\n### 触发优先 + 减法优先（元判据 · 凌驾全部检查项之上）\n\nSkill 的命脉是两条，权重最高：\n\n1. **触发**：`description` 是模型唯一用来判断\"何时唤醒本 skill\"的信号。写不清\"何时用\"，再好的正文也永远不被加载。\n2. **减法**：SKILL.md 不是图书馆。模型每代都在变强——你塞进正文的通用写法、框架教程、临时脚本，很快既过时又白占 token。**能下沉 references/ 的下沉，能外置 scripts/ 的外置，模型已经会的删掉。**\n\n所以机检里 **#2 触发 / #3 篇幅 / #4 渐进披露 / #6 可移植 / #10 别替模型补** 权重 1.5；\n\"加内容\"类项（#7 最小工具集、#10 配套文档）缺失只算小扣分——别一边喊\"越精简越好\"、一边逼作者把 skill 做臃肿。\n\n## 品牌人设（体检报告的口吻 + 署名）\n\n属于 **会勇禾口王的AI笔记**（定位：AI 实战拆解，硬核·具体·可复制；人设：你办公室里第一个把 AI 用明白的同事）。出体检报告时：\n\n- **口吻**：像同事帮你看代码——直给结论、敢泼冷水（\"这 description 只写了做什么、不写何时用，等于永远不被触发\"），不说客套话。\n- **价值化**：修复建议讲\"省了什么\"（每次触发少灌 100KB 冗余、别人装上不报错、该用时真能被唤醒），不堆术语。\n- **署名**：报告结尾固定带 `—— 会勇禾口王的AI笔记 · @huiyonghkw`。命令行 `check.py` 的报告页脚已内置该署名。\n- **去 AI 味**：定稿前避开\"赋能/打造/至关重要/助力\"等词，说人话。\n\n---\n\n## 免费 / 付费边界（重要）\n\n- **免费（开源内核）**：`check.py` 的**文本 / JSON 报告 + 评分**。任何人本地或进 CI 随便跑。\n- **免费但要自付 API 钱**：`scripts/trigger_eval.py` 触发力实测（工作流 2c）。脚本本身开源随便用，\n  但它每条 query 都真调一次 `claude -p`（约 $0.09–0.15/次），**钱花在用户自己的额度上**。\n  所以它是**可选叠加档、不进默认流程**——`check.py` 的零依赖卖点不受影响，不跑也能出完整体检报告。\n- **付费（增值）**：**品牌可视化体检报告卡**（评分弧 + 等级带 + 明细分享图），依赖 `hekouwang-content-factory` 的私有品牌字体与版式，不随本仓库分发。\n- 一句话口径：**跑检查免费，出\"好看的报告图\"找 @huiyonghkw。** 外部用户要图时说明是付费增值项，别用系统字体凑一张劣化图糊弄。\n\n---\n\n## 工作流（每次体检按这个顺序）\n\n1. **确认目标**：用户没指明就用当前目录；说了某个 skill 就用那个 skill 目录的绝对路径（目录里要有 `SKILL.md`）。若传进来是 `~/.claude/skills/` 这种父目录，脚本会提示里面有哪些 skill，逐个体检。\n2. **跑机检**（确定性层，零依赖）：\n   ```bash\n   python3 <此skill目录>/check.py <skill目录>\n   ```\n   - 需要结构化结果时加 `--json`。退出码：有 FAIL → 1，否则 0。\n2b. **深度安全扫描（可选 · 外部工具 SkillSpector）**：`check.py` 的 #0 只做密钥正则；当要查**提示注入 / 数据外泄 / 隐藏指令 / 供应链 / 过度授权 / MCP 越权**等 68 类模式时，叠加跑 [SkillSpector](https://github.com/NVIDIA/skillspector)（本机已装：`uv tool install`，需 Python 3.12/3.13）：\n   ```bash\n   env -u ALL_PROXY -u all_proxy -u HTTPS_PROXY -u https_proxy \\\n     skillspector scan <纯逻辑副本> --no-llm --format markdown -o report.md\n   ```\n   - **只对\"别人写的、要装进来的\" skill 跑。** 自研 skill 扫出来的实测是 100% 误报（2026-07-15 全量验证 7 个 hekouwang-* skill，逐条翻源码，无一为真），跑了只会\n\nArchive v1.4.0: 13 files, 47731 bytes\n\nFiles: CHANGELOG.md (11100b), check.py (28003b), Dockerfile (804b), LICENSE (1096b), README.md (3532b), references/skill-writing-vocab.md (4701b), references/trigger-eval.md (7753b), scripts/trigger_eval.py (16245b), skill-card.md (2840b), SKILL.md (20350b), tests/fixtures/bad/SKILL.md (379b), tests/fixtures/good/SKILL.md (802b), _meta.json (154b)\n\nArchive v1.3.0: 11 files, 33495 bytes\n\nFiles: CHANGELOG.md (7484b), check.py (28003b), Dockerfile (804b), LICENSE (1096b), README.md (3532b), references/skill-writing-vocab.md (4701b), skill-card.md (2585b), SKILL.md (17208b), tests/fixtures/bad/SKILL.md (379b), tests/fixtures/good/SKILL.md (802b), _meta.json (154b)\n\nArchive v1.0.3: 11 files, 29547 bytes\n\nFiles: .github/workflows/ci.yml (834b), .github/workflows/release.yml (1078b), CHANGELOG.md (3701b), check.py (28003b), README.md (3532b), references/skill-writing-vocab.md (4701b), skill-card.md (2427b), SKILL.md (14089b), tests/fixtures/bad/SKILL.md (379b), tests/fixtures/good/SKILL.md (802b), _meta.json (154b)\n\nArchive v1.0.2: 11 files, 29552 bytes\n\nFiles: .github/workflows/ci.yml (834b), .github/workflows/release.yml (1078b), CHANGELOG.md (3701b), check.py (28003b), README.md (3532b), references/skill-writing-vocab.md (4701b), skill-card.md (2435b), SKILL.md (14089b), tests/fixtures/bad/SKILL.md (379b), tests/fixtures/good/SKILL.md (802b), _meta.json (154b)\n\nArchive v1.0.1: 10 files, 24331 bytes\n\nFiles: .github/workflows/ci.yml (834b), .github/workflows/release.yml (1078b), CHANGELOG.md (2210b), check.py (28003b), README.md (3532b), skill-card.md (2121b), SKILL.md (11857b), tests/fixtures/bad/SKILL.md (379b), tests/fixtures/good/SKILL.md (802b), _meta.json (154b)","readmeExcerpt":"Skill: hekouwang-claude-skill-doctor-skill Owner: huiyonghkw Summary: 会勇禾口王的AI笔记 · Agent Skill（SKILL.md）体检器。检查一个 Claude/Agent Skill 是否 符合\"按需加载的指令包，不是单文件巨石\"的最佳实践——评 description 触发质量、SKILL.md 篇幅、渐进披露（references/ 拆分）、脚本外置、可移植性（无硬编码绝对路径）、安全（无硬编码 密钥、宿主元数据与多 Skill 发现冲突），给出评分卡 + 按优先级的修复建议，并可代为重构。触发：用户说「检查我的 skill / SKILL.md 体检 / 这个 skill 规范吗 / claude-skill-doctor / audit skill / lint SKILL.md / 我的 skill 太长了 / skill 拆分 / 看看我","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"python3 <此skill目录>/check.py <skill目录>"},{"language":"bash","snippet":"env -u ALL_PROXY -u all_proxy -u HTTPS_PROXY -u https_proxy \\\n     skillspector scan <纯逻辑副本> --no-llm --format markdown -o report.md"},{"language":"bash","snippet":"skillspector scan <纯逻辑副本> --no-llm --baseline <skill目录>/.skillspector-baseline.yaml"},{"language":"bash","snippet":"rsync -a --prune-empty-dirs \\\n       --exclude='.venv/' --exclude='node_modules/' --exclude='.git/' --exclude='__pycache__/' \\\n       --include='*/' --include='*.md' --include='*.py' --include='*.js' --include='*.json' \\\n       --include='*.html' --include='*.css' --include='*.sh' --include='*.txt' --include='*.yaml' \\\n       --exclude='*' <skill目录>/ <副本>/"},{"language":"bash","snippet":"python3 <此skill目录>/scripts/trigger_eval.py \\\n     --eval-set <你的query集>.json --skill-path <skill目录>"},{"language":"text","snippet":"my-skill/\n├── SKILL.md              # ≤500 行：frontmatter(name+description触发句) + 元判据 + 硬规矩\n│                         #          + 一张「做 X → 读 references/Y」索引表（路由，不堆细节）\n├── references/           # 渐进披露：按版本/平台/流程拆的专题 .md，用到再读\n│   ├── topic-a.md\n│   └── topic-b.md\n├── scripts/              # 确定性可执行脚本（构建/截图/合成/转换），正文只留指针\n├── assets/               # 字体/图片/模板等捆绑资源\n├── README.md             # 给人看（分发用）\n└── CHANGELOG.md          # 版本记录"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: hekouwang-claude-skill-doctor-skill\nslug: hekouwang-claude-skill-doctor-skill\ndisplayName: Claude Skill 体检器（SKILL.md Doctor）\nsummary: Agent Skill lint / SKILL.md doctor / skillspec audit — description 触发、渐进披露、可移植性与 OpenClaw 兼容检查。姊妹工具 md-doctor。\nlicense: MIT-0\nhomepage: https://github.com/huiyonghkw/hekouwang-claude-skill-doctor-skill\nversion: 1.8.0\ndescription: >\n  会勇禾口王的AI笔记 · Agent Skill（SKILL.md）体检器。检查一个 Claude/Agent Skill 是否\n  符合\"按需加载的指令包，不是单文件巨石\"的最佳实践——评 description 触发质量、SKILL.md\n  篇幅、渐进披露（references/ 拆分）、脚本外置、可移植性（无硬编码绝对路径）、安全（无硬编码\n  密钥、宿主元数据与多 Skill 发现冲突），给出评分卡 + 按优先级的修复建议，并可代为重构。触发：用户说「检查我的 skill /\n  SKILL.md 体检 / 这个 skill 规范吗 / claude-skill-doctor / audit skill / lint SKILL.md /\n  我的 skill 太长了 / skill 拆分 / 看看我的 skill 合不合规 / skill 对齐官方规范」。\n  任何\"评估/审查/优化某个 Agent Skill 质量或结构\"的请求都应触发。\n---\n\n# hekouwang-claude-skill-doctor-skill · Agent Skill 体检器\n\n> **会勇禾口王的AI笔记** 出品 · `@huiyonghkw`\n> _不聊 AI 会不会取代你，只聊先用 AI 的人怎么取代你。_\n\n把\"Agent Skill 最佳实践\"做成一个能跑在任何 skill 上的检查器：机检定量 + 模型定性，\n产出评分卡和可落地的修复建议。核心判据一句话——\n\n> **SKILL.md 是模型\"决定要不要加载、加载后照着做\"的运行时指令包。`description` 决定它何时被唤醒；正文越精简越准；厚重细节要能\"按需展开\"（references/ 用到再读），而不是每次触发就把全部细节灌进上下文。**\n> 一切检查项都从这句推导：这段内容值不值得在 skill 每次触发时都付一次上下文费？能不能下沉到 references/ 用到再读？\n\n### 触发优先 + 减法优先（元判据 · 凌驾全部检查项之上）\n\nSkill 的命脉是两条，权重最高：\n\n1. **触发**：`description` 是模型唯一用来判断\"何时唤醒本 skill\"的信号。写不清\"何时用\"，再好的正文也永远不被加载。\n2. **减法**：SKILL.md 不是图书馆。模型每代都在变强——你塞进正文的通用写法、框架教程、临时脚本，很快既过时又白占 token。**能下沉 references/ 的下沉，能外置 scripts/ 的外置，模型已经会的删掉。**\n\n所以机检里 **#2 触发 / #3 篇幅 / #4 渐进披露 / #6 可移植 / #10 别替模型补** 权重 1.5；\n\"加内容\"类项（#7 最小工具集、#10 配套文档）缺失只算小扣分——别一边喊\"越精简越好\"、一边逼作者把 skill 做臃肿。\n\n## 品牌人设（体检报告的口吻 + 署名）\n\n属于 **会勇禾口王的AI笔记**（定位：AI 实战拆解，硬核·具体·可复制；人设：你办公室里第一个把 AI 用明白的同事）。出体检报告时：\n\n- **口吻**：像同事帮你看代码——直给结论、敢泼冷水（\"这 description 只写了做什么、不写何时用，等于永远不被触发\"），不说客套话。\n- **价值化**：修复建议讲\"省了什么\"（每次触发少灌 100KB 冗余、别人装上不报错、该用时真能被唤醒），不堆术语。\n- **署名**：报告结尾固定带 `—— 会勇禾口王的AI笔记 · @huiyonghkw`。命令行 `check.py` 的报告页脚已内置该署名。\n- **去 AI 味**：定稿前避开\"赋能/打造/至关重要/助力\"等词，说人话。\n\n---\n\n## 免费 / 付费边界（重要）\n\n- **免费（开源内核）**：`check.py` 的**文本 / JSON 报告 + 评分**。任何人本地或进 CI 随便跑。\n- **免费但要自付 API 钱**：`scripts/trigger_eval.py` 触发力实测（工作流 2c）。脚本本身开源随便用，\n  但它每条 query 都真调一次 `claude -p`（约 $0.09–0.15/次），**钱花在用户自己的额度上**。\n  所以它是**可选叠加档、不进默认流程**——`check.py` 的零依赖卖点不受影响，不跑也能出完整体检报告。\n- **付费（增值）**：**品牌可视化体检报告卡**（评分弧 + 等级带 + 明细分享图），依赖 `hekouwang-content-factory` 的私有品牌字体与版式，不随本仓库分发。\n- 一句话口径：**跑检查免费，出\"好看的报告图\"找 @huiyonghkw。** 外部用户要图时说明是付费增值项，别用系统字体凑一张劣化图糊弄。\n\n---\n\n## 工作流（每次体检按这个顺序）\n\n1. **确认目标**：用户没指明就用当前目录；说了某个 skill 就用那个 skill 目录的绝对路径（目录里要有 `SKILL.md`）。若传进来是 `~/.claude/skills/` 这种父目录，脚本会提示里面有哪些 skill，逐个体检。\n2. **跑机检**（确定性层，零依赖）：\n   ```bash\n   python3 <此skill目录>/check.py <skill目录>\n   ```\n   - 需要结构化结果时加 `--json`。退出码：有 FAIL → 1，否则 0。\n   - 默认 Profile 是跨宿主的 `agent`；要按 Codex `skill-creator` 的严格基础契约验收时，加\n     `--profile codex`。它只允许 `name`、`description`、`license`、`allowed-tools`、`metadata`，\n     并阻断不合规 name、description 尖括号和正文未完成 TODO；不适用于带 Claude/宿主扩展字段的 Skill。\n   - 需要盘点一个宿主目录或仓库里的全部 Skill 时运行：\n     `python3 <此skill目录>/check.py --scan <skill根目录> --json`；同样"},{"path":"tests/fixtures/bad/SKILL.md","content":"---\nname: BadSkill_Example\n---\n\n# Bad Skill\n\n这是一个演示「不合格 skill」的夹具，故意踩坑：\n\n- name 用了大写 + 下划线（应 kebab-case）。\n- **缺 description**——模型无从判断何时加载本 skill（机检会判 FAIL，退出码 1）。\n- 硬编码了绝对路径 /Users/someone/.claude/skills/x/assets/font.woff2（换台机器就废）。"},{"path":"tests/fixtures/good/SKILL.md","content":"---\nname: example-good-skill\ndescription: >\n  生成示例日报。把一段原始数据整理成一页结构化的示例日报。\n  当需要演示「合格 skill 长什么样」或要一份 demo 日报时使用；\n  use when you need a demo daily report.\nallowed-tools:\n  - Read\n  - Write\n---\n\n# Example Good Skill\n\n一个用于演示「合格 skill」的最小夹具：frontmatter 完整、description 写清了\n做什么 + 何时用、正文精简、无硬编码密钥、无绝对路径。\n\n## 何时用\n\n当用户要一份示例日报，或想看一个达标 skill 的结构时。\n\n## 怎么做\n\n1. 读取用户给的原始数据。\n2. 按「概览 / 明细 / 结论」三段整理。\n3. 输出一页 Markdown 日报。\n\n> 正文只放本 skill 私有的约定；通用写法交给模型自己。"},{"path":"README.md","content":"# hekouwang-claude-skill-doctor-skill\n\n> **会勇禾口王的AI笔记** 出品 · `@huiyonghkw`\n> 不聊 AI 会不会取代你，只聊先用 AI 的人怎么取代你。\n\n给 **Agent Skill（SKILL.md）** 做体检的工具。把\"Skill 是按需加载的指令包、不是单文件巨石\"\n这条最佳实践，做成一个能跑在任何 skill 上的检查器：机检定量 + 模型定性，产出评分卡和可落地的修复建议。\n\n## 30 秒验收\n\n```bash\npython3 check.py path/to/your-skill    # 体检任意 skill 目录\nbash scripts/run-all-doctors.sh .      # 三件套（需已装 md-doctor + env-doctor）\n```\n\n姊妹工具：[`hekouwang-claude-md-doctor-skill`](https://github.com/huiyonghkw/hekouwang-claude-md-doctor-skill)（体检 AGENTS.md / CLAUDE.md）。\n\n## 核心判据\n\n> SKILL.md 是模型\"决定要不要加载、加载后照着做\"的运行时指令包。\n> `description` 决定它何时被唤醒；正文越精简越准；厚重细节要能\"按需展开\"\n> （references/ 用到再读），而不是每次触发就把全部细节灌进上下文。\n\n## 用法\n\n### 在 Claude Code 里（推荐）\n\n直接用**自然语言**喊它，Claude 会自动加载本 skill、在底层跑机检、再做定性复核，给评分卡 + 按优先级的修复建议，并问要不要代为重构：\n\n> - 「帮我体检 `~/.claude/skills/xxx` 这个 skill」\n> - 「我的 SKILL.md 规范吗 / 是不是太长了 / 要不要拆 references」\n> - 「audit this skill」「lint SKILL.md」\n\n### 命令行直接跑（零依赖，仅需 Python 3）\n\n```bash\npython3 check.py <skill目录>          # 输出彩色报告\npython3 check.py <skill目录> --json   # 机器可读 JSON（CI 可用）\npython3 check.py <skill目录> --profile codex  # 严格校验 Codex 基础契约\n```\n\n退出码：有 FAIL → 1，否则 0（可用于 CI 卡关）。\n\n### Codex 严格基础契约（可选）\n\n默认 `agent` Profile 服务于 Claude/Codex/其他宿主共用的 Skill：合法的 `slug`、`version` 等宿主扩展字段不会被误伤。\n如果你要按 Codex `skill-creator` 的基础规范验收一个纯 Codex Skill，附加 `--profile codex`：只允许\n`name`、`description`、`license`、`allowed-tools`、`metadata`，并把不合规 kebab-case、description\n中的尖括号和正文未完成的 `[TODO: ...]` 纳入 `gate`。报告 JSON 的 `profile` 字段会明确本次使用的档位。\n\n这是一层可选的严格契约，不取代 Doctor 原有的跨宿主质量、安全、指针和扫描检查。\n\n### 盘点多个 Skill\n\n当传入的是宿主 Skill 根目录或仓库父目录时，用扫描模式。主机目录通常只看直接入口：\n\n```bash\npython3 check.py --scan --direct ~/.claude/skills --json\npython3 check.py --scan /path/to/repository --json\npython3 check.py --scan /path/to/codex-skills --profile codex --json\n```\n\n默认递归扫描会跳过测试夹具和构建目录；direct 模式只检查根目录下一层的宿主入口。\n两种模式都会识别隐藏宿主目录、断开的软链、真实入口去重和重复 name。自动化应读取 JSON\n里的 gate 字段；score/grade 只是质量参考，不能替代门禁判断。\n\n### Docker（不想装 Python 也能跑）\n\n```bash\n# 拉官方镜像直接用（打 v* tag 时 GitHub Actions 自动发布到 GHCR）\ndocker run --rm -v \"$PWD:/work\" ghcr.io/huiyonghkw/hekouwang-claude-skill-doctor-skill\n\n# 或本地自建\ndocker build -t claude-skill-doctor .\ndocker run --rm -v \"$PWD:/work\" claude-skill-doctor            # 体检挂载的 skill\ndocker run --rm -v \"$PWD:/work\" claude-skill-doctor /work --json\n```\n\n### 接进 CI 卡关（GitHub Actions 示例）\n\n```yaml\n- uses: actions/setup-python@v5\n  with: { python-version: \"3.x\" }\n- name: SKILL.md 体检（不合格则拦 PR）\n  run: |\n    curl -sO https://raw.githubusercontent.com/huiyonghkw/hekouwang-claude-skill-doctor-skill/main/check.py\n    python3 check.py path/to/your/skill\n```\n\n本仓库自身的 CI 见 [`.github/workflows/ci.yml`](.github/workflows/ci.yml)（语法 + good/bad 夹具 + JSON 合法性）。\n\n## 检查项与门禁\n\n| 权重 | 项 |\n|---|---|\n| **1.5（核心）** | 无硬编码密钥 · frontmatter 必填合法 · description 含「何时用」 · SKILL.md ≤500 行 · 渐进披露(拆 references/) · 可移植(无硬编码绝对路径) · 别替模型补它已会的 |\n| 1.0（标准） | description ≤1024 · 指针无死链 · 脚本外置 scripts/ |\n| 0.6（加内容） | allowed-tools 最小化 · 配套文档(README+CHANGELOG) |\n\n分档：A ≥85 · B ≥70 · C ≥50 · D <50。\n\n启用 `--profile codex` 时，"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn73qd1gcmjr446mwcbdxef70x82vxcw\",\n  \"slug\": \"hekouwang-claude-skill-doctor-skill\",\n  \"version\": \"1.8.0\",\n  \"publishedAt\": 1788078352385\n}"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":906,"uniquenessScore":44,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T06:26:12.987Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-10T06:26:12.987Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T11:00:24.180Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}