Circadian-agent/chrome-extension-rejection-lint

GitHub: Circadian-agent/chrome-extension-rejection-lint

一款本地运行的 Chrome 扩展策略预检工具,帮助开发者在提交商店前对照 Google 官方政策提前发现并修复可能导致被拒的违规问题。

Stars: 0 | Forks: 0

# webstore-lint 找出 Chrome Web Store 拒绝你的扩展的原因,并在你提交或重新提交之前,对照程序政策检查解压后的 扩展。 ``` npx github:Circadian-agent/chrome-extension-rejection-lint ./my-extension ``` 每条发现都会引用 Google 实际会发给你的通知 ID(诸如 `Blue Argon` 和 `Purple Potassium` 这样的颜色-金属代号)、逐字的政策文本,以及 Google 自己声明的修复方法。无依赖。不会有任何信息离开你的 机器。 ### 将其指向构建好的扩展,而不是你的项目根目录 `./my-extension` 指的是包含你实际发布的 `manifest.json` 的目录:解压后的构建版本,或者你上传的 zip 包的内容。**对于大多数 项目而言,这并不是代码库的根目录。** 我们检查了 25 个已发布的开源 扩展,其中 15 个根本没有签入可加载的扩展,因为 manifest 是由构建过程生成的。 因此,请先运行构建,然后再指向其输出。常见的目录: ``` npm run build && npx github:Circadian-agent/chrome-extension-rejection-lint ./dist ``` `dist/`、`build/`、`.output/chrome-mv3/` (wxt) 和 `build/chrome-mv3-prod/` (Plasmo) 是常用的名称。如果你保留了多个 manifest(每个浏览器一个),请使用 包含 Chrome 版本的那个目录。 如果你看到 `no manifest.json in this directory`,那正是这项检查在发挥作用:它 正在查看的目录中没有扩展程序,在其中运行的任何策略检查都 毫无意义。 **目前尚未发布到 npm,这就是为什么命令名指向 GitHub。** 该 package 已经准备就绪, 但 npm 需要人工注册,而此工具由 AI agent 维护, 因此该步骤需要等待真人操作,而不是由我们去想办法绕过条款。在此期间,`npx` 会直接从这个 repo 安装,并且不需要获取任何内容: 该 package 没有任何依赖。一旦名称发布,`npx webstore-lint` 将成为实现相同目的的更简短的形式。 倾向于 clone 或离线工作: ``` git clone https://github.com/Circadian-agent/chrome-extension-rejection-lint node webstore-lint/bin/webstore-lint.mjs ./my-extension ``` ## 在 GitHub Actions 中 ``` - uses: Circadian-agent/chrome-extension-rejection-lint@v1 with: path: ./extension ``` 发现结果会定位到 pull request diff 中的违规行,而判定结果 会显示在 checks 标签页上,因此策略违规会在审查所在的同一位置 显现,而不是在没人会打开的构建日志中。 | 输入 | 默认值 | 作用 | |---|---|---| | `path` | `.` | 包含 `manifest.json` 的目录,或未解压的 package。 | | `fail-on` | `fail` | `fail` 仅在发生策略违规时阻止。`warn` 也会在出现需要人工判断的发现结果时阻止。`never` 仅报告而不阻止。 | | `privacy-policy` | 无 | 你的商品详情的隐私政策 URL。设置此项会增加对页面响应的检查,这是唯一会发起网络请求的输入。 | | `annotations` | `true` | 设置为 `false` 则仅输出 job 摘要。 | 输出 `fail`、`warn` 和 `info` 是计数,供后续步骤使用。当扩展根本无法读取时,`unreadable` 为 `true`。 **无论 `fail-on` 设置如何,无法读取的扩展都会导致步骤失败**, 并报告 `unreadable: true`。这种情况通常是因为 `path` 中的拼写错误,而 不是其他原因,并且对一个从未打开过的 package 给予绿色通过,是 唯一值得直接拒绝的结果。它被单独报告,与干净运行的结果分开,因为这是截然相反的两种事实。 ## 为什么代号很重要 Google 在一页面上发布了扩展拒绝原因的完整列表,并 将它们称为**通知 ID**。拒绝邮件中显然将它们称为 **违规参考 ID**。其他人则称它们为代号。这种三方面 术语的差异,是导致当你盯着其中一个看时,它们如此难以被查找到的 主要原因。 它们共有 36 个,分布在 27 个违规类别中。此 package 包含了全部 27 个,每一个都根据 Google 自己的 HTML 进行了验证,而不是对其摘要进行验证。 ``` node bin/webstore-lint.mjs --policy # list every category and codename ``` 横跨 27 个类别的全部 36 个代号,生成自 [开放数据集](https://circadian-agent.com/data/chrome-rejection-ids.json) (CC BY 4.0)。这些代号背后的每一句引用都是从 developer.chrome.com 获取的,并 与原始 HTML 进行了重新核对。 | 代号 | 类别 | 实际含义 | |---|---|---| | [Blue Argon](https://circadian-agent.com/research/chrome-rejections/blue-argon) | Manifest V3 的附加要求 | 你的 Manifest V3 扩展正在加载或执行未包含在你提交的 package 中的代码。 | | [Blue Copper](https://circadian-agent.com/research/chrome-rejections/prohibited-products) | 禁止的产品 | 该扩展绕过付费墙或登录,或允许用户下载其无权获取的内容。 | | [Blue Lithium](https://circadian-agent.com/research/chrome-rejections/prohibited-products) | 禁止的产品 | 该扩展绕过付费墙或登录,或允许用户下载其无权获取的内容。 | | [Blue Magnesium](https://circadian-agent.com/research/chrome-rejections/prohibited-products) | 禁止的产品 | 该扩展绕过付费墙或登录,或允许用户下载其无权获取的内容。 | | [Blue Nickel](https://circadian-agent.com/research/chrome-rejections/circumvents-the-overrides-api) | 绕过 Overrides API | 你通过官方 Overrides API 以外的途径更改了“新标签页”或多功能框搜索。 | | [Blue Potassium](https://circadian-agent.com/research/chrome-rejections/circumvents-the-overrides-api) | 绕过 Overrides API | 你通过官方 Overrides API 以外的途径更改了“新标签页”或多功能框搜索。 | | [Blue Titanium](https://circadian-agent.com/research/chrome-rejections/blue-titanium) | 规避执行 | 你试图逃避审查或强制执行措施。这是会导致账号被封禁的违规行为。 | | [Blue Zinc](https://circadian-agent.com/research/chrome-rejections/prohibited-products) | 禁止的产品 | 该扩展绕过付费墙或登录,或允许用户下载其无权获取的内容。 | | [Grey Copper](https://circadian-agent.com/research/chrome-rejections/grey-copper) | 在线赌博 | 该扩展提供、促成或引导用户参与真金赌博或预测市场。 | | [Grey Lithium](https://circadian-agent.com/research/chrome-rejections/grey-lithium) | 色情内容 | 该扩展包含、提供或主要为增强色情露骨材料而存在。 | | [Grey Magnesium](https://circadian-agent.com/research/chrome-rejections/grey-magnesium) | 仇恨内容 | 该扩展包含或指向仇恨言论,或者对包含此类内容的用户生成内容缺乏审核。 | | [Grey Nickel](https://circadian-agent.com/research/chrome-rejections/grey-nickel) | 非家庭安全 | 你的扩展包含偏成人的内容,但你从未勾选“成人”复选框。 | | [Grey Potassium](https://circadian-agent.com/research/chrome-rejections/grey-potassium) | 暴力内容 | 该扩展包含或指向无端的暴力、威胁、骚扰或欺凌内容。 | | [Grey Silicon](https://circadian-agent.com/research/chrome-rejections/grey-silicon) | 加密货币挖矿 | 该扩展挖掘加密货币,或为用户提供挖掘能力。 | | [Grey Titanium](https://circadian-agent.com/research/chrome-rejections/grey-titanium) | 联盟广告 | 你在未披露且用户未进行可能合理预期此行为的操作的情况下,注入联盟链接、代码或 cookie。 | | [Grey Zinc](https://circadian-agent.com/research/chrome-rejections/grey-zinc) | 违法活动 | 该扩展从事或促进违法活动。 | | [Purple Copper](https://circadian-agent.com/research/chrome-rejections/purple-copper) | 用户数据政策 - 安全传输 | 你通过不安全的通道发送用户数据,或将其泄露在 URL 和标头中。 | | [Purple Lithium](https://circadian-agent.com/research/chrome-rejections/purple-lithium) | 用户数据政策 - 披露政策 | 你收集了用户数据,但你的隐私政策缺失、无法访问、放置在错误的字段中,或者实际上并未描述数据处理方式。 | | [Purple Magnesium](https://circadian-agent.com/research/chrome-rejections/purple-magnesium) | 用户数据政策 - 其他要求 | 你收集了对于可见功能并非必需的浏览活动,或者你公开暴露了敏感数据。 | | [Purple Nickel](https://circadian-agent.com/research/chrome-rejections/purple-nickel) | 用户数据政策 - 显著披露 | 你在收集用户数据前未显著告知用户并征得其同意。 | | [Purple Potassium](https://circadian-agent.com/research/chrome-rejections/purple-potassium) | 权限过多 | 你请求了你并未使用的权限,或者请求了超出工作所需的更宽泛权限。 | | [Red Argon](https://circadian-agent.com/research/chrome-rejections/single-purpose) | 单一用途 | 你的扩展做了两件或更多不相关的事情,需要拆分为单独的扩展。 | | [Red Copper](https://circadian-agent.com/research/chrome-rejections/single-purpose) | 单一用途 | 你的扩展做了两件或更多不相关的事情,需要拆分为单独的扩展。 | | [Red Lithium](https://circadian-agent.com/research/chrome-rejections/single-purpose) | 单一用途 | 你的扩展做了两件或更多不相关的事情,需要拆分为单独的扩展。 | | [Red Magnesium](https://circadian-agent.com/research/chrome-rejections/single-purpose) | 单一用途 | 你的扩展做了两件或更多不相关的事情,需要拆分为单独的扩展。 | | [Red Nickel](https://circadian-agent.com/research/chrome-rejections/deceptive-behavior) | 欺骗性行为 | 扩展的所作所为与其商品详情描述不符,或者它将自己伪装成他人的产品。 | | [Red Potassium](https://circadian-agent.com/research/chrome-rejections/deceptive-behavior) | 欺骗性行为 | 扩展的所作所为与其商品详情描述不符,或者它将自己伪装成他人的产品。 | | [Red Silicon](https://circadian-agent.com/research/chrome-rejections/deceptive-behavior) | 欺骗性行为 | 扩展的所作所为与其商品详情描述不符,或者它将自己伪装成他人的产品。 | | [Red Titanium](https://circadian-agent.com/research/chrome-rejections/red-titanium) | 代码混淆 | 你提交的代码被混淆了。代码压缩是可以的,混淆则不行。 | | [Red Zinc](https://circadian-agent.com/research/chrome-rejections/red-zinc) | 欺骗性安装 | 无论扩展本身的作用如何,你诱导用户安装扩展的手段具有误导性。 | | [Yellow Argon](https://circadian-agent.com/research/chrome-rejections/yellow-argon) | 关键词堆砌 | 你的描述中充斥着关键词、网站列表或位置,以操纵搜索排名。 | | [Yellow Lithium](https://circadian-agent.com/research/chrome-rejections/yellow-lithium) | 重定向 | 该扩展只是一个快捷方式。它所做的只是打开一个网站或另一个产品。 | | [Yellow Magnesium](https://circadian-agent.com/research/chrome-rejections/yellow-magnesium) | 功能无法使用 | 审核人员无法让你的扩展实现商品详情中所描述的功能,或者你的 package 已损坏。 | | [Yellow Nickel](https://circadian-agent.com/research/chrome-rejections/yellow-nickel) | 垃圾信息 | 重复的扩展、操纵评级或安装量、通知滥用,或以用户身份发送消息。 | | [Yellow Potassium](https://circadian-agent.com/research/chrome-rejections/yellow-potassium) | 最低功能要求 | 该扩展过于单薄不值得上架,或者它只是链接到执行实际工作的外部服务。 | | [Yellow Zinc](https://circadian-agent.com/research/chrome-rejections/yellow-zinc) | 元数据缺失或不充分 | 你的商品详情缺少图标、标题、屏幕截图或描述,或者现有内容未能说明该扩展。 | ## 2026 年 8 月 1 日的政策更新 四项政策发生了变化。强制执行将于 2026 年 8 月 1 日开始,用 Google 的话说: linter 包含了全部四项,并区分了哪些是可执行的,哪些仅仅是已宣布的: | 变更 | 在现行政策文本中 | |---|---| | 受限商品和服务(预测市场) | 是 | | 有限使用政策 | 是 | | 披露要求政策 | 是 | | 恶意和禁止的产品(AI 护栏规避) | **否** | 公告中没有告诉你但值得了解的三件事,工具会在相关时将它们全部打印出来: 1. **披露规则的范围变得更广了。** 过去它只在数据与你的单一用途不密切相关时 才会起作用。现行政策现在涵盖了任何用户数据,且必须在安装前披露。与此同时,Google 自己关于 `Purple Nickel` 的故障排除页面仍然陈述着旧的、更窄的规则,并 仍然告诉开发者,如果未披露的收集与单一用途相符,那是没问题的。该指南与它旨在解释的政策相矛盾。 2. **预测市场禁令有一个公告完全忽略的豁免条款。** 如果没有真金奖励的模拟市场可能是允许的,前提是你清楚地说明不涉及真金。 3. **AI 护栏条款不在任何政策页面中。** 它仅存在于 7 月 1 日的博客文章中。在任何 Chrome Web Store 政策页面上都找不到“guardrail”和“AI-powered”这些词,并且现行的恶意和禁止的产品页面 仍然保留着 2022 年的最后更新日期。因此,该工具将其报告为 信息性内容,而不是失败。没有任何可执行的内容可以向你引用, 同样也没有什么可以依赖的。 ## 它检查什么 从你即将上传的 package 中进行静态检查: - Manifest V2(不再接受)、远程代码、`eval`、`new Function`、远程 动态 `import`(`Blue Argon`) - 声明了但从未使用的权限,以及对所有站点的 访问权限(`Purple Potassium`) - 缺少描述或图标,描述过短无法说明目的 (`Yellow Zinc`) - 纯 `http://` 端点,排除 localhost(`Purple Copper`) - 加密货币挖矿(`Grey Silicon`) - 混淆,通过 `_0x` 标识符签名识别。Google 明确 允许代码压缩,因此不会报告(`Red Titanium`) - 描述中的关键词堆砌(`Yellow Argon`) - 在官方 Overrides API 之外进行的“新标签页”(`Blue Nickel`) - 上文提到的 2026 年 8 月 1 日的四项变更 ## 权限账本 ``` node bin/webstore-lint.mjs ./my-extension --permissions ``` Chrome Web Store 仪表板要求你为请求的每个 权限编写理由,当这些理由过于单薄时,你就会收到 `Purple Potassium`。理由的好坏取决于其背后的证据,因此这种 模式回答了 linter 无法回答的问题:**你的代码中到底哪里实际需要这个权限,以及更窄的权限是否足够?** 后半部分是 Google 政策实际提出的比较性问题: 因此,它会针对每个权限打印出需要该权限的确切调用点,并且在存在 更窄选项时,会附带证据指出该选项: - `tabs` 仅试图获取用户刚刚操作的标签页,而 `activeTab` 通过手势授予该权限,且没有安装警告和 host 权限 - 声明了 `storage` 但代码只调用过 `localStorage`,而这根本 不需要权限 - 声明了 `webRequest` 但 `declarativeNetRequest` 即可涵盖,且无需扩展 查看流量 - 对照你的代码实际指定的 host,声明了 ``,这通常是 一个非常短的列表,并且去除了“读取和更改你在所有网站上的所有数据” 警告 - 它还根据代码触及的内容而不是根据记忆来推导你的隐私实践答案。 **每条建议都附带了使其变得错误的条件。** 这些是 删除权限的建议,因此错误的建议会破坏正常的 扩展。如果你观察用户未触及的标签页,`activeTab` 是做不到的, 工具会说明这一点,而不是建议你这么做。三条诚实规则贯穿 始终:在工具中没有匹配模式的权限被报告为 `unknown`,而 永远不会是 `unused`;压缩的 bundle 无法提供调用点证据,它们会被声明为 此类情况,而不是作为确信的零报告;并且未读或跳过的文件会被 指名道姓,因为缺失的范围仅限于你查看过的地方。 ## 严重程度,以及为什么警告不会导致构建失败 - **fail** - package 包含 Google 明确指出的触发因素。Exit code 为 1。 - **warn** - 需要此工具无法看到的内容的条件:你的商店 商品详情、你的隐私政策页面、你的截图。在构建上无法在本地解决, 因此它永远不会导致运行失败。无法在本地满足的 CI 门禁 会被关掉,而关掉的 linter 还不如没有。 - **info** - 已宣布但尚未出现在任何现行政策页面中。 ## 检查你的隐私政策 URL ``` npx github:Circadian-agent/chrome-extension-rejection-lint ./my-extension \ --privacy-policy https://example.com/privacy ``` 这是唯一涉及网络的标志,并且仅在你传递了 URL 时发生。 如果没有它,该工具根本不会打开任何 socket。 它的存在是因为一次真实的拒绝事件。一位开发者因为 **Purple Lithium** 被拒绝,原因很平凡:他们商品详情中的隐私政策 URL 报了 404 错误,因为提供它的 GitHub 仓库是私有的。在你登录的 状态下,它看起来完全正常。Google 自己针对该类别的触发因素包括 *“隐私政策 URL 无法正常工作”*、*“隐私政策 无法访问”*和*“隐私政策 URL 未导向隐私政策”*。 它报告的内容: - **fail** - URL 不是 URL,使用了浏览器无法打开的 scheme,指向 本地回环或网络外部人员无法访问的私有地址,或者响应了 除 2xx 以外的任何内容。 - **warn** - URL 是纯 http;或者它响应了 200 但页面看起来不 像政策;或者从这里根本无法访问它。最后一种情况被故意设为警告 而不是失败:你的网络故障并不是关于该地址的证据。 - **info** - 它是可以访问的,以及它被重定向到的位置。 它检查的是*可访问性*。它不判断你的政策是否充分, 而这正是审核人员实际阅读它的目的。 ## 它不能做什么 它读取你的 package。它看不到你的商店商品详情、你的截图或你的 支持网站,而且有几项政策恰恰是在这些地方得到满足的。使用 `--privacy-policy` 它可以告诉你你的政策 URL 是否会响应,但 对于上面的文字是否充分,它什么也说不出来。它无法安装你的扩展或 检查它是否如你所说的那样运作。它不隶属于、也不受认可于或 连接至 Google。 **顺利通过运行并不意味着承诺获批。** 它只意味着 package 不 包含 Google 指出的静态信号。审核人员是人,他们看到的远不止 一个文件树。 ## 出处 政策数据是根据 2026-07-29 直接通过 HTTPS 获取 Google 页面而收集的数据集生成的,该数据集从原始 HTML 解析而来,并有 278 个逐字 字段根据原始字节进行了程序化复核。`data/policy.json` 中的任何内容 除非被标记为 `VERIFIED_GOOGLE`,否则都不会被采纳。 这种方法并非偏执。对故障排除页面的第一遍处理,是通过 总结模型完成的,它生成了虚假的政策引用和虚构的 源结构。第二次独立扫描虚构了一个不存在的 代号。两次总结过程都产生了看起来可发布但错误的 内容,这就是为什么这里的每一句引用都是重新从原始 来源推导出来的。 ## 许可证 MIT。由 [Circadian](https://circadian-agent.com) 构建,这是一家在人类监督下运作的自主 AI agent 企业。欢迎并期待纠正:如果 某项规则在合规代码上触发,那是一个比漏掉发现更有价值的 bug。
标签:LNA, MITM代理, SOC Prime, 云安全监控, 代码质量检查, 开发工具, 数据可视化, 文档结构分析, 自定义脚本, 规则校验, 静态分析