# 泛微技能检测 · 检测项清单（Checklist）

本文件定义「泛微技能检测工具」对上传 skill（`.zip` 压缩包 / `.md` 文件 / 目录）的全部检测项与判定标准。
脚本 `scripts/validate_skill.py` 严格按此清单执行静态分析。

判定状态：`PASS`（通过）/ `WARN`（警告，可放行但建议修复）/ `FAIL`（不通过）。
严重程度：`BLOCK`（阻断，致命）/ `HIGH`（高危）/ `MEDIUM`（中）/ `LOW`（低）/ `INFO`（提示）。

---

## 0. 约束归属总览（WorkBuddy 平台 / 泛微专属 / 千问专属）

检测项分属三套来源不同的规范，**违反后果不同**，排查与申诉对象也不同，因此必须区分。

### 0.1 三类约束的区别

| 归属 | 全称 | 来源 | 约束对象 | 违反后果 |
|------|------|------|----------|----------|
| **WB** | WorkBuddy 平台约束 | skillhub.cn / WorkBuddy 平台的加载器与上传校验程序（对齐官方 `expert-reviewer` 规范） | **任何作者**提交的 skill（含外部合作方、个人作者），与是否泛微无关 | 平台**直接拒收或加载异常**：上传失败、frontmatter 解析报错、入口识别不到、文件路径不安全、包体超限等。属于平台技术门槛，无协商空间 |
| **WV** | 泛微专属约束 | 泛微生态内部治理要求（品牌规范、E10 账号与接口调用契约、安全合规红线） | **泛微对外发布 / 上架 / 比赛提交**的 skill；内部自研、外部合作方共建的泛微系技能 | 平台层面通常**不会**拦（平台并不认识「泛微」概念），但**内部发布门禁不予放行**：品牌不符、账号体系不统一、登录与凭证链路违规、隐私合规风险 |
| **WB+WV** | 叠加 | 平台有通用要求，泛微在其上追加了更严的约束 | 同上 | 任一层不满足即判失败 |
| **QW** | 千问办公平台约束 | 千问（QwenWork）生态接入开发指南 | 要上架千问办公市场的 skill（需 `--platform qwenwork` 显式启用） | 千问平台**直接拒收**：包体超限、入口路径不对、字段缺失/取值非法、连接器未做就绪检查 |
| **QW+WB** | 千问叠加 | 千问独有约束，且与 WorkBuddy 通用要求共存 | 同上 | 任一层不满足即判失败 |
| **QW+WV** | 双平台叠加 | 同一 skill 既要上千问又要上泛微 | 双平台上架的 skill | 取两者更严者（如 `name` 既要满足千问命名规范，又要带 `weaver` 前缀） |

**一句话区分**：`WB` = 平台收不收；`WV` = 泛微放不放；`QW` = 千问收不收。

### 0.2 归属图例

- `WB` —— WorkBuddy 平台强制
- `WV` —— 泛微专属
- `WB+WV` —— 平台通用要求 + 泛微追加约束（通常表现为「平台只要求有这个字段，泛微还要求字段值/写法」）
- `QW` —— 千问办公平台强制（仅 `--platform qwenwork` 时启用）
- `QW+WB` —— 千问独有约束 + WorkBuddy 通用要求
- `QW+WV` —— 千问与泛微双平台上架时的叠加约束

### 0.3 归属速查索引

| 归属 | 规则编号 |
|------|----------|
| **WB**（平台强制） | A1、A1a、A1b、A1c、A1d、A1e、A2、A2n、A3、A4、A5、A5b、A6、A7、A8、A9、A10、A11、A11b、A11c、A13、A14、G02、G03、G04a、G04b、G04c、C08、BOM、CRLF、Q1、Q2、Q3、Q4、Q4b、E1、C1–C8、D1–D3 |
| **WV**（泛微专属） | A2m、A4b、A8b、A8c、A8d、A8e、A12、B1、B2、B3、B4、B5、B6、B7、B8、B9、B10a、B10b、B10c |
| **WB+WV**（叠加） | A8f（`version`：平台要求存在且为 SemVer；泛微要求是**顶层**字段，禁止 `metadata:` 嵌套）、E2（平台关注 `dependencies` 声明；泛微只识别 `weaver-e10-` 前缀依赖） |
| **QW**（千问专属，`--platform qwenwork`） | A1c′、A1f、A4′、A5f、A5g、A5h、A6c、A6e、A11d、B11a、B11b |
| **QW+WB**（千问叠加） | A1d（仅纯文本，两平台一致）、A1e（`SKILL.md` 大小写精确）、A2n（frontmatter YAML 真解析）、A3（`name` 命名规范） |
| **QW+WV**（双平台） | A3b（`name` 前缀：千问无品牌要求，泛微要求 `weaver` 前缀）、A8f（`version`：两平台都要 SemVer 且顶层） |

> 数量分布：WB 41 项 ／ WV 19 项 ／ WB+WV 2 项 ／ QW 11 项（不含已停用的 C/D 组）。
> QW 组仅在 `--platform qwenwork` 下执行；默认 `weaver` 模式完全不触发，既有结论逐条不变。

### 0.4 复用与裁剪建议

| 场景 | 建议保留 | 可忽略 |
|------|----------|--------|
| 泛微对外发布 / 上架 / 比赛提交 | 全部（WB + WV） | QW 组 |
| 外部合作方共建的泛微系技能 | 全部（WB + WV） | QW 组 |
| 用本工具检测**非泛微**的第三方 skill（纯平台合规体检） | WB 组 | WV 组（A2m/A4b/A8b–A8e/A12/B*/E2 `weaver-e10-` 前缀限制），此时 `name` 前缀、`display_name` 泛微开头、`author` 泛微署名等均不适用 |
| **上千问办公市场** | WB + QW 组 | WV 组（千问无泛微品牌要求） |
| **千问 + 泛微双平台上架** | 全部（WB + WV + QW） | — 冲突项取更严者 |

---

## A-1. 基础合规 · WorkBuddy 平台约束（WB）

> 平台加载器与上传校验程序的硬性要求，任何作者都必须满足，违反即被平台拒收或加载异常。

| 编号 | 归属 | 检测项 | 严重度 | 判定标准 |
|------|------|--------|--------|----------|
| A1 | WB | SKILL.md 存在 | BLOCK | 压缩包/目录内需存在 `SKILL.md`；单 `.md` 文件需含 frontmatter |
| A1a| WB | **Windows 反斜杠路径分隔符** | **BLOCK** | **仅 zip 输入触发。** 基于 zip 原始条目名（namelist）检查，任一 zip 条目路径含 Windows 反斜杠 `\`（如 `weaver-e10-doc\operations\`）即判 FAIL。skillhub 上传校验运行在 Unix，反斜杠会被判为文件名中的非法/不安全字符，整包标记「文件路径不安全」而拒收。常见于 Windows 资源管理器直接拖拽打包（中文 Windows 易写出反斜杠路径）；须用 `zip -r xxx.zip xxx/` 或 7-Zip「标准 zip」模式重打。目录输入不触发此项（无法从 OS 路径推断打包后的 zip 路径） |
| A1b| WB | **目录层级不超过两级** | **BLOCK** | Skill 包仅支持两级目录结构：`根目录/二级目录/文件`。以 SKILL.md 所在目录为 skill 根，任一文件相对深度 > 2（出现三级及以上子目录，如 `references/attend/xxx.md`）即判 FAIL——平台解析会异常。须把模块子目录拍平：将 `references/<模块>/<文件>` 改为 `references/<文件>` 或把模块目录提升为 references 同级目录 |
| A1c| WB | **文件总数 ≤ 300** | **BLOCK** | 包内（含任意层级、含隐藏/缓存文件）文件总数超过 300 即判 FAIL——平台上传硬性上限，超限直接拒收。须清理 `__pycache__`、`.DS_Store`、临时产物或拆分体积 |
| A1d| WB | **仅纯文本 / 禁止二进制** | **BLOCK** | ZIP 包内任意位置不得含二进制文件（可执行 `.exe`/`.dll`/`.so`/`.dylib`、图片媒体 `.png`/`.jpg`/`.gif`/`.mp4`、压缩归档 `.zip`/`.tar`/`.gz` 等），只允许纯文本（`.md`/`.py`/`.js`/`.txt`/`.json`/`.yaml` 等）。采用「纯文本扩展名允许清单 + 二进制魔数嗅探」双保险：扩展名不在清单内再嗅探文件头（空字节 / PNG·JPEG·PDF·ZIP·EXE 等魔数），"文本扩展名却实为二进制"也漏不掉；无扩展名纯文本（LICENSE/Makefile 等）经已知名单或嗅探放行，避免误杀；macOS 打包垃圾（`.DS_Store`/`._xxx`/`__MACOSX/`）一律判违规 |
| A1e| WB | **SKILL.md 文件名大小写精确** | **BLOCK** | 入口文件名必须精确为 `SKILL.md`（首字母大写、后缀全大写 MD），禁止 `skill.md` / `Skill.md` / `Skill.MD` 等任何大小写变体。平台/工具以区分大小写方式匹配入口文件名，变体不会被识别为 skill 入口（等价「无 SKILL.md」）。变体单独存在 → BLOCK 并提示重命名为 `SKILL.md`；与精确 `SKILL.md` 并存 → 同样 BLOCK 提示删除多余变体 |
| A2 | WB | YAML frontmatter 完整 | BLOCK | 文件以 `---` 包裹的 frontmatter 开头，可被解析 |
| A2n| WB | **frontmatter YAML 语法（真解析）** | **BLOCK** | 平台用真 YAML 解析器解析 frontmatter，语法错误直接报「frontmatter 无法解析 / mapping values are not allowed in this context」拒收。检测器双层校验：装有 PyYAML 时真解析并精确报行号；未装则降级启发式扫描高频错误——① 一行挤多个键值对（`name: xxx display_name: yyy`，粘贴丢换行，最常见）；② 值中含未加引号的冒号+空格（`description: 支持 xx: yy`）；③ 行首 Tab 缩进。整体引号包裹的值内部冒号合法 |
| A3 | WB | `name` 字段 | BLOCK | frontmatter 必须含 `name` |
| A4 | WB | `name` 命名规范 | BLOCK | 仅小写字母（a-z）、数字（0-9）和连字符（-）；不允许大写、下划线、空格、中文或特殊字符；不能以 `-` 开头/结尾，不含连续 `--`；长度必须 3-64 个字符 |
| A5 | WB | `description` 字段 | BLOCK | 必须含 `description`（不能为空） |
| A5b| WB | **`description` 长度（1-1024）** | **BLOCK** | `description` 长度必须在 1-1024 个字符之间，超过 1024 判 FAIL |
| A6 | WB | `description` 无尖括号 | LOW | 平台规范未禁止 `<` 或 `>`，但建议改为全角〈〉或移除，避免个别 YAML 解析器误判 |
| A7 | WB | `description` 充分性 | MEDIUM | description 长度 ≥ 20 字（过简不利于触发匹配） |
| A8 | WB | `agent_created` 标志 | LOW | 推荐含 `agent_created: true`（WorkBuddy 模型生成的技能建议带此标志，便于后续管理） |
| A9 | WB | 目录名与 name 一致 | MEDIUM | 仅 zip/目录：外层目录名须等于 frontmatter `name` |
| A10| WB | 无 TODO 占位残留 | MEDIUM | 正文不得残留 `[TODO]` / 待补充 / placeholder= 等模板占位 |
| A11| WB | 正文内容充实 | MEDIUM | 正文净字符 ≥ 100 |
| A11b| WB | **正文档行数 ≤ 500** | MEDIUM | SKILL.md 正文建议控制在 500 行以内；内容过多时应拆分为 `references/` 目录下的独立文件，正文只保留路由触发与核心说明 |
| A11c| WB | **引用相对路径规范** | MEDIUM | 正文引用其他文件时必须使用相对 Skills 根目录的路径（如 `references/api-docs.md`、`scripts/main.py`）；禁止反斜杠分隔（`scripts\main.py`）与非系统类绝对路径（`/references/api.md`）；`references/`、`scripts/` 等资源目录下的引用文件必须真实存在于包内。运行时系统路径（`/tmp/`、`/Users/`、`~/`、`C:\` 等）与占位符示例（`xxx.md`、`<参数>`）自动豁免，避免误报 |
| A13| WB | **结构化文件可解析性** | **BLOCK** | 包内所有 `.json`/`.yaml`/`.yml`/`.toml` 文件必须可正常解析（JSON 用 `json.loads`，YAML/TOML 做基本语法检查），格式错误会导致平台加载 skill 时直接报错 |
| A14| WB | 依赖引导完整性 | MEDIUM | 若包内含 `scripts/`/`bin/`/`package.json`/`requirements.txt` 等依赖声明，须在 SKILL.md 或 references/ 中提供安装/使用说明（检测「安装」「install」「依赖」「usage」等关键词） |

---

## A-2. 基础合规 · 泛微生态约束（WV）

> 平台并不强制这些（平台不认识「泛微」概念），但泛微对外发布 / 上架 / 比赛提交一律不放行。

| 编号 | 归属 | 检测项 | 严重度 | 判定标准 |
|------|------|--------|--------|----------|
| A2m| WV | **frontmatter 顶层结构（禁止 metadata 嵌套）** | **BLOCK** | 所有字段（`name`/`version`/`author`/`description` 等）均为**顶层**字段，frontmatter 中不得出现 `metadata:` 嵌套块。若嵌套块内含关键字段（author/version 等）→ BLOCK 并提示提升到顶层；仅空 `metadata:` 或嵌套非关键字段 → WARN。依据：泛微与合作方约定的 frontmatter 模板（`author: 合作方名称` / `version: 1.0.0` 均为顶层） |
| A4b| WV | **`name` 前缀（泛微强制）** | **BLOCK** | `name` 必须以 `weaver` 开头（如 `weaver-e10-xxx`），统一泛微生态命名空间，便于市场检索与依赖识别 |
| A8b| WV | **`display_name` 字段** | **BLOCK** | 必须含 `display_name`（中文展示名称），且必须以「泛微」开头 |
| A8c| WV | **`display_name_en` 字段** | **BLOCK** | 必须含 `display_name_en`（英文展示名称） |
| A8d| WV | **`description_zh` 字段** | **BLOCK** | 必须含 `description_zh`（简短中文介绍） |
| A8e| WV | **`description_en` 字段** | **BLOCK** | 必须含 `description_en`（英文简介） |
| A8f| **WB+WV** | **`version` 字段（SemVer + 顶层）** | **BLOCK** | **WB 部分**：必须含 `version` 且严格符合 SemVer「主版本.次版本.修订号」三段纯数字（如 `1.0.0`）；不支持 `v1.0`、`1.0`、`latest`、`1.0.0-beta` 等非标准格式。**WV 部分**：必须是**顶层**字段，不允许 `metadata.version` 嵌套写法（嵌套视为缺失）。另：上架市场时版本号必须严格大于市场已发布版本 |
| A12| WV | **author 作者字段（泛微署名）** | **BLOCK** | frontmatter 必须含**顶层** `author` 字段（不允许 `metadata.author` 嵌套写法，嵌套视为缺失），且值必须精确等于「泛微网络科技股份有限公司」；缺失或值不符一律判 FAIL |

---

## B. 泛微专项质检（WV）—— 对外分发前红线

> 泛微生态的合规与安全红线，全部为泛微专属（WV）。平台侧无对应要求，属于内部发布门禁。

| 编号 | 归属 | 检测项 | 严重度 | 判定标准 |
|------|------|--------|--------|----------|
| B1 | WV | **默认登录地址未指向泛微自用系统** | **BLOCK** | 严禁将 `e-cology.com.cn` / `e-weaver.com` / `weaver.com.cn` / `eteams.cn` 等泛微自用域名写死为默认系统地址；客户下载后会越权访问泛微自用系统 |
| B2 | WV | 无硬编码真实 IP | HIGH | 不得出现真实服务器 IP（127.0.0.1 / 0.0.0.0 / example 占位除外）；对外分发的 skill 必须脱敏为占位符，避免泄露客户/内部系统拓扑 |
| B3 | WV | 无硬编码凭证 | HIGH | 不得出现密码 / token / secret / api_key 等字面量，须走 E10 命名凭据插件 |
| B4 | WV | 凭证应通过插件获取 | MEDIUM | 涉及 Weaver API 调用时，应说明通过 E10 命名凭据插件（如 `key=ETEAMSID`）获取，禁止硬编码或 Playwright 登录兜底 |
| B5 | WV | 敏感词占位规范 | INFO | 向 Weaver 发送内容时，建议复用 `-替换敏感词占位符-` 规范避免敏感词拦截（E10 敏感词拦截特征：HTTP 200 + code 1001 + sensitiveScanCode 401） |
| B6 | WV | 无包外脚本子进程调用 | MEDIUM | 不得通过 `spawnSync`/`spawn`/`exec`/`subprocess` 等调用包外脚本文件（如 `tools/_init_env_cache.py`），避免用户环境自动执行外部代码 |
| B7 | WV | 凭证未通过命令行明文传递 | HIGH | 子进程调用的参数块内不得出现 `ETEAMSID`/`token`/`session`/`cookie`/`password`/`secret` 等凭证字段，禁止以命令行参数或 env 明文传入凭证 |
| B8 | WV | 无硬编码加密密钥 / 本地凭证访问 | HIGH | 不得硬编码密钥常量用于 AES 解密本地会话凭证；不得访问 `<~/.e10-cli/profiles/*/auth>` 等本地敏感凭证路径（须脱敏并限定授权范围） |
| B9 | WV | **API 请求凭证完整性** | **BLOCK** | 发起对外 API 请求（requests / urllib / httpx / fetch / axios / curl 等）时，请求头必须同时携带 ① `Cookie` 完整原始串（禁止裁剪/去重/改写）② `eteamsid` ③ `User-Agent: AgentType=<agentType>,IsAgent=true`；缺任一项即阻断；Cookie 被 split / dict / 切片改写另计 WARN |
| B10a | WV | **登录必须走共享规则（E10 接口型技能）** | **BLOCK** | 仅对 `name` 为 `weaver-e10-` 前缀的技能生效（`weaver-e10-shared` / `weaver-e10-shared-connector` 自身豁免）。若为接口型技能（有脚本 HTTP 调用或文档接口描述），必须依赖 `weaver-e10-shared`；连接器版依赖 `weaver-e10-shared-connector`：frontmatter `dependencies` 声明，或正文/脚本引用共享规则 / `weaver-work-cli auth`。无任何共享登录规则依赖证据 → 阻断 |
| B10b | WV | **禁止自建登录** | **BLOCK** | 同 B10a 适用范围。不得自行实现登录流程：Playwright / Selenium / Puppeteer 自动登录、扫码/二维码登录、账号密码登录、自建 OAuth 取 token。会话必须统一由共享规则与 `weaver-work-cli auth` 托管 |
| ~~B10c~~ | WV | ~~**接口文档声明完整凭证（文档型 E10 技能）**~~ **（2026-09-20 起停用）** | 停用 | 请求头三件套（Cookie 完整原始串 / `eteamsid` / `User-Agent: AgentType=...,IsAgent=true`）已收敛为「唯一权威声明」，只写在 `weaver-e10-shared`（连接器版 `weaver-e10-shared-connector`）入口 SKILL.md 的「请求头契约」章节，业务模块改为指针引用、不再复制代码块。本规则按单个技能目录独立扫描，看不到 shared 正文，继续启用会把正确的引用写法误判为 FAIL，故整段停用；脚本型仍由 B9 覆盖 |
| — | WV | 触发前提与非适用 | INFO | B10 组需先检测到 API 表面（脚本内真实 HTTP 调用，或 Markdown 文档中的接口请求描述）才生效；纯规范/UI 类 E10 技能（如 `weaver-e10-ui-system`）无接口描述 → 自动跳过，不误伤。非 `weaver-e10-` 前缀技能整组不适用 |

---

## QW. 千问办公平台约束（QW）—— 需 `--platform qwenwork`（**非默认，勿主动启用**）

> **默认检测范围 = 泛微专属（WV）+ WorkBuddy 平台（WB）+ 通用质量/安全**，即 `weaver` 模式。
> 千问（QwenWork）生态接入规范的硬性约束，**仅在用户明确说明「上架千问 / 千问办公 / QwenWork」、并显式传 `--platform qwenwork` 时执行**。
> 默认 `weaver`（泛微）模式完全不触发本组规则，既有结论逐条不变，报告中也**不出现** QW 归属项与 QW 图例。
>
> 调度口诀：**用户没说千问，就不是千问。** 「检测 skill」「上架 skillhub」「比赛投稿」「发布前体检」等一律按默认 `weaver` 模式跑。

### QW-0 平台阈值与字段别名对照

| 维度 | 泛微 `weaver`（默认） | 千问 `qwenwork` |
|------|----------------------|-----------------|
| 包内文件总数（A1c / A1c′） | ≤ 300 | **< 1000**（上限 999） |
| zip 包大小（A1f） | 不限制 | **≤ 10 MB**（BLOCK） |
| 入口路径（A4′） | 存在 `SKILL.md` 即可 | **必须精确为 `<name>/SKILL.md`** |
| SKILL.md 正文（A11d） | 不限制 | **≤ 64 KB**（超出在市场详情页截断） |
| `name` 前缀（A3b） | 必须 `weaver` 开头 | 无品牌前缀要求 |
| 中文展示名字段 | `display_name`（须以「泛微」开头） | `displayName`（无前缀要求） |
| 英文展示名字段 | `display_name_en` | `name_en` |
| 中文描述字段 | `description_zh` | `description`（直接是中文） |
| 发布方字段 | `author`（锁定「泛微网络科技股份有限公司」） | `author_name`（表单字段，市场列表展示） |
| 分类 | 无 | `category_code`（14 个固定枚举） |
| 图标 | 无 | `icon`（公网 URL，240*240） |
| 引导语 | 无 | `argument-hint`（推荐，缺失不阻断） |

### QW-1 检测项清单

| 编号 | 归属 | 检测项 | 严重度 | 判定标准 |
|------|------|--------|--------|----------|
| A1c′ | QW | **包内文件总数 < 1000** | **BLOCK** | 包内（含任意层级、含隐藏文件）文件总数 ≥ 1000 即判 FAIL——千问上传硬性上限。须清理 `__pycache__`、`.DS_Store`、临时产物 |
| A1f | QW | **zip 包大小 ≤ 10 MB** | **BLOCK** | 读取**真实归档文件体积**（zip/md 输入为权威值）；目录输入无归档可测，降级为「包内文件合计」并在结论中标注「（目录输入，无归档文件，取包内文件合计近似）」 |
| A4′ | QW | **`<name>/SKILL.md` 精确路径** | **BLOCK** | zip 输入：用 zip 原始 namelist 精确比对 `<name>/SKILL.md`（区分大小写与路径分隔符）；目录输入：校验「SKILL.md 所在目录名 == frontmatter 的 `name`」；单 `.md` 输入无目录结构，跳过。**这是千问最高频失败原因**——macOS Finder 右键「压缩 N 项」只会得到裸 `SKILL.md`，必须用 `zip -r x.zip <name>/` 带上外层目录一起压缩 |
| A5f | QW | **`displayName` 必填** | **BLOCK** | 中文展示名必填且 ≤ 255 字符（千问市场列表展示用） |
| A5g | QW | **`author_name` 必填** | **BLOCK** | 发布方名称必填且 ≤ 255 字符。注意与泛微 `author` 区分：`author_name` 是千问表单字段，`author` 是 frontmatter 字段 |
| A5h | QW | `argument-hint` 引导语 | INFO | 推荐填写（用户输入框的预填引导语），缺失不阻断 |
| A6c | QW | **`category_code` 命中 14 个固定分类** | **BLOCK** | 取值必须属于：`content_creation`、`visual_creative`、`data_analysis`、`consulting_research`、`productivity`、`marketing_sales`、`ecommerce_retail`、`product_development`、`hr_recruiting`、`finance_accounting`、`legal_affairs`、`investment`、`education`、`other`。未设置仅 INFO 提示 |
| A6e | QW | **`icon` 必填且为公网 URL** | **BLOCK** | 缺少 `icon` / `icon_url` 即判 FAIL；非 `http(s)://` 开头判 WARN（规格 240*240 PNG / ≤ 2 MB；SVG 免尺寸校验，工具只校验声明不下载） |
| A11d | QW | **SKILL.md 正文 ≤ 64 KB** | **BLOCK** | 按 UTF-8 字节计，超出部分在市场详情页说明文档展示时会被截断（不影响上传成功，但首屏体验劣化）。须把长知识拆到 `references/` |
| B11a | QW | **连接器就绪性检查（`qw_query`）** | **BLOCK** | 技能若声明依赖连接器（`qwenwork.settings.connector.<类别>.<id>` 或「依赖连接器」表述），必须先调用 `qw_query` 查询连接器就绪状态；未做任何就绪检查即直接调用 → 阻断 |
| B11b | QW | **401/403 与 token 失效回退** | **BLOCK** | 依赖连接器的技能必须处理 401/403 / token 失效：引导用户回 Step 0 重新授权，不得直接报错退出 |

> B11 组触发前提：正文中出现连接器依赖声明（`qwenwork.settings.connector.*` 或「依赖连接器」字样）。未声明的技能不触发，不误伤。

---

## 红线说明（B1 重点）

**为什么 B1 是阻断项：** 泛微自有 demo/生产系统常部署在 e-cology.com.cn 等泛微自用域名。
若 skill 将这些域名作为「默认登录地址 / 默认 base_url / 默认 host」写死，客户下载并运行后会连接到泛微自用系统，
造成越权访问、数据泄露与隐私合规风险。**对外发布/提交的 skill 一律不得提供默认系统地址**，必须由用户显式提供自身系统地址。

**检测工具自身的约束：** 本工具仅做静态分析，**绝不连接任何线上 Weaver 系统**；若被分析的 skill 需要系统地址用于联调，
应要求用户自行填入自有域名，工具与检测结果都不得默认指向 `e-cology.com.cn`。

---

## G. 扩展安全（WB）—— 对齐官方 expert-reviewer G 组

> 平台官方规范组，属 WorkBuddy 平台约束（WB）；其中 G03 内网域名针对腾讯/平台内网，与泛微自用域名（B1）区分。

| 编号 | 归属 | 检测项 | 严重度 | 判定标准 |
|------|------|--------|--------|----------|
| G02 | WB | 无危险 shell 命令 | HIGH | 检测 `rm -rf /`、`rm -rf ~`、`rm -rf *`、fork bomb `:(){ :|:& };:`、`curl\|sh`、`sudo rm/chmod/dd/mkfs`、`chmod 777 /`、`dd if=...of=/dev/`、`mkfs.* /dev/`、`> /dev/sda`、`shutdown`/`reboot` 等危险命令（否定语境「禁止/不得」豁免） |
| G03 | WB | 无内网域名残留 | MEDIUM | 检测 `*.woa.com`/`*.tencent.com`/`*.internal`/`*.local`/`*.intranet`/`*.corp` 等通用内网域名（泛微自用域名 `e-cology.com.cn` 等由 B1 覆盖，否定语境豁免） |
| G04a| WB | 无开发者个人路径残留 | MEDIUM | 检测 `/Users/xxx/`、`/home/xxx/`、`C:\Users\xxx\`、`C:/Users/xxx/` 等开发者个人路径；对外分发后路径不一致会导致脚本/配置失效 |
| G04b| WB | 无 IDE/平台配置目录残留 | LOW | 检测 `.vscode/`/`.idea/`/`.cursor/`/`.codebuddy/`/`.fleet/`/`.claude/`/`.aider/`/`.github/`/`.DS_Store`/`Thumbs.db` 等不应出现在发布包中的文件 |
| G04c| WB | CDN 依赖版本锁定 | MEDIUM | 检测 `cdn.jsdelivr.net/.../@latest`、`unpkg.com/.../@latest`、`cdnjs.cloudflare.com/.../@latest`、`esm.sh/.../@latest` 等未锁定版本的 CDN 引用；上游更新可能引入不兼容或恶意代码 |
| C08 | WB | 无平台虚假技术承诺 | MEDIUM | 检测 Markdown 文档中的「本地AI」「离线运行」「不上云」「完全离线」「无需联网」「纯本地」「数据不出本机」「100%私密」「绝对安全」「永不泄露」「no cloud」「fully offline」等与平台运行方式不符的承诺（否定语境豁免） |
| BOM | WB | 无 BOM 头残留 | LOW | 检测文件开头的 UTF-8 BOM（EF BB BF），可能导致 YAML frontmatter 解析失败 |
| CRLF| WB | 无 CRLF 行尾 | LOW | 检测 Windows CRLF（\r\n）行尾，跨平台分发时可能导致 shell 脚本执行异常或 YAML 解析问题 |

---

## Q. 质量评估（WB）—— 启发式，对齐官方 expert-reviewer Q 组

| 编号 | 归属 | 检测项 | 严重度 | 判定标准 |
|------|------|--------|--------|----------|
| Q1 | WB | 路由触发清晰度 | LOW | SKILL.md 是否有明确的触发场景/关键词描述（检测「当用户」「触发」「适用场景」「使用场景」「何时使用」「trigger」「when to use」等关键词）；缺少触发词可能导致技能无法被正确路由 |
| Q2 | WB | 上下文效率 | LOW | 检测 >100KB 的超大 Markdown 文件；过大文件占用上下文窗口，影响 Agent 处理效率，建议拆分或渐进披露 |
| Q3 | WB | 容错降级 | LOW | 包内含脚本时检查是否有 `try`/`catch`/`except`/`finally`/`.catch()`/`throw`/`raise` 等错误处理逻辑；缺少容错会导致异常时直接崩溃 |
| Q4 | WB | display_name 简洁性 | LOW | `display_name` 建议控制在 20 字以内以便展示 |
| Q4b| WB | description 字数控制 | LOW | `description` 建议控制在 200 字以内（一句话概述），详细内容放在 `description_zh`/`description_en`（对应官方 C02） |

---

## E. 技能能力清单与依赖（透明披露）

| 编号 | 归属 | 检测项 | 严重度 | 判定标准 |
|------|------|--------|--------|----------|
| E1 | WB | 识别到的能力 | INFO | 列出 skill 源码/文档中识别到的运行时能力：`HTTP 请求`、`调用外部 API`、`读取文件`、`写入文件`、`安装依赖包`、`控制浏览器`、`读取环境变量`、`执行系统命令`、`数据库访问`、`网络监听 / Socket / WebSocket` 等 |
| E2 | **WB+WV** | 依赖的其他技能 | INFO | **WB 部分**：平台关注 skill 的 `dependencies` 声明与其他技能引用关系。**WV 部分（泛微收窄）**：只识别 `weaver-e10-` 前缀技能，非 `weaver-e10-` 前缀的 `weaver-ebuilder-*`/`weaver-openserver-*`/`e10-`/`eteams-`/其他命名一律视为平台模块或内部引用、不作为技能依赖。识别来源：frontmatter `dependencies` / `requires` / `depends_on` / `skills` / `uses`（内联或 YAML 块列表）、description 中「由 xxx 提供/负责」、主 SKILL.md 中 `skill: "xxx"` / `/斜杠命令` /「使用 xxx 技能」表述；跳过自身、工具自身与常见路径/占位符片段。市场可达性：**推荐 `--market-live` 动态联网核查 skillhub.cn**（按 `slug` 精确匹配，实时标注 市场可搜[带链接] / 市场未收录 / 核查失败）；离线可用 `--market-catalog catalog.json` 快照替代 |

---

## C. 威胁捕获模型视图（8 类风险卡片，WB）

> 已启用：每次检测默认渲染成「8 卡网格 + 三引擎并行评估」。每张卡片包含三个引擎 chip —— **行为安全**（按 status 着色，绿/橙/红）+ **AI 引擎**（紫色，扫描器自身作为 AI 引擎对外披露）+ **静态引擎**（命中=蓝、未命中=灰）。

| 编号 | 归属 | 检测项 | 严重度 | 判定标准 |
|------|------|--------|--------|----------|
| C1 | WB | 供应链风险 | MEDIUM | 检测到 `pip install` / `npm install` / `yarn add` / `curl \| bash` 等依赖安装或远程脚本拉取行为 |
| C2 | WB | 命令执行风险 | HIGH | 检测到 `eval` / `exec` / `spawn` / `subprocess` / `system` / `os.system` 等动态命令执行点 |
| C3 | WB | 网络请求与数据外传 | MEDIUM | 检测到 `requests` / `axios` / `fetch` / `curl` / `urllib` 等 HTTP 请求能力 |
| C4 | WB | 文件操作与敏感路径 | MEDIUM | 检测到文件读写，或引用 `~/.ssh` / `~/.aws` / `~/.e10-cli/profiles/.../auth` 等敏感路径 |
| C5 | WB | Prompt 注入风险 | HIGH | 提示词诱导用户粘贴 `ETEAMSID` / `token` / `password` 等凭证，或出现典型 prompt 注入话术 |
| C6 | WB | 远程脚本下载执行 | HIGH | 检测到 `curl \| bash`、`powershell -enc`、远程 `.py/.sh` 脚本执行等模式 |
| C7 | WB | 可疑编码/混淆 | MEDIUM | 检测到 `eval(atob(...))` / 长串 base64 / `\x`/ `\u` 转义序列等混淆特征 |
| C8 | WB | 其他安全风险 | HIGH | 检测到 `--no-sandbox` / `--disable-gpu` 等沙箱绕过参数，或截屏、录音、剪贴板读取等隐私采集能力 |

---

## D. 威胁行为图谱解析（具体跨文件/跨行行为，WB）

> 已启用：检测结果渲染到 HTML 报告「威胁行为图谱解析」section，顶部四个 tab —— **全部引擎结果(N)** / **检出恶意(N)** / **检出可疑(N)** / **评估安全(N)**。每条规则一张详情卡（深色日志块 + 具体 `文件:行 → 代码` 命中）。

| 编号 | 归属 | 检测项 | 严重度 | 判定标准 |
|------|------|--------|--------|----------|
| D1 | WB | dangerouslyDisableSandbox + run_in_background 绕过权限确认 | HIGH | 同一 skill 中同时出现 `dangerouslyDisableSandbox: true` 与 `run_in_background: true`，可能用于跳过权限确认并关闭沙箱 |
| D2 | WB | 浏览器启动参数关闭沙箱 | HIGH | 检测到 `--no-sandbox`、`--disable-gpu`、`--disable-setuid-sandbox` 等浏览器启动参数 |
| D3 | WB | 提示词诱导用户明文粘贴会话凭证 | HIGH | 提示词模板要求用户将 `ETEAMSID` / `token` / `session` 等凭证明文粘贴进对话 |

---

## 综合判定规则

- 存在任意 `BLOCK` 级 `FAIL` → 综合判定 **FAIL**（不通过）。
- 无 BLOCK，但存在 `WARN` → **WARN**（通过但建议修复）。
- 全部 PASS → **PASS**（通过）。

> 注：WB 与 WV 的 BLOCK 项在当前实现中**同等对待**（任一命中即不可发布）。
> 若需按归属分级处理（例如只跑 WB 做平台合规体检），参见「0.4 复用与裁剪建议」。
> QW 组同理：启用 `--platform qwenwork` 后，QW 的 BLOCK 项与 WB/WV 同等对待。

---

## 工程约定：扫描性能与正则写法（改动 `validate_skill.py` 必读）

### 扫描截断

| 常量 | 值 | 作用 |
|------|-----|------|
| `MAX_SCAN_FILE_BYTES` | 4 MB | 单文件参与正则扫描的最大字节数，超出部分截断（扫描顺序仍覆盖全部文件） |
| `SCAN_LINE_MAX_CHARS` | 4000 | 单行参与正则扫描的最大字符数，超出部分截断，**行号一一对应不变** |

### 背景（真实事故）

部分路径正则含可回溯量词，在**超长单行**（压缩 JS、无换行数据文件）上会退化为准 O(n²)：
实测 11 MB 单行文本让整体扫描卡死 **180 秒以上**（表现为命令无响应、后台任务挂起）。
加截断 + 正则改写后，同一用例 **8.4 秒**完成。截断只丢弃超长行尾部，正常代码行远小于阈值，检测结论不受影响。

### 正则写法硬约束

逐行扫描的正则必须**先锚定字面量 token**，再向后做「有界尾部 + 定界」校验：

```python
# ✅ 正确：先锚定 token，再校验有界尾部
r"((?:e10|eteams|weaver)[^\s'\"]{0,120}profiles[^\s'\"]{0,120}auth(?:[\"'\s`]|$))"

# ❌ 禁止一：无界量词（超长行直接退化 O(n²)）
r"([^\s'\"]*(?:\.ssh|\.aws|...)(?:[\"'\s`]|$))"

# ❌ 禁止二：可空/通配前缀 + 有界量词（每个起点要试 N 种前缀长度，1.6 MB 单行实测 90+ 秒）
r"([^\s'\"]{0,120}(?:\.ssh|\.aws|...)(?:[\"'\s`]|$))"
```

新增/修改正则后，务必用「逐步放大行长度」验证耗时呈线性增长，不要只看功能用例是否通过。
