mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-06 17:23:28 +08:00
fix: harden unicode safety checks
This commit is contained in:
@@ -158,9 +158,9 @@ model: sonnet
|
||||
|
||||
## 你的角色
|
||||
|
||||
- 主要职责
|
||||
- 次要职责
|
||||
- 你不做的事情(界限)
|
||||
- 主要职责
|
||||
- 次要职责
|
||||
- 你不做的事情(界限)
|
||||
|
||||
## 工作流程
|
||||
|
||||
@@ -322,17 +322,17 @@ description: 在 /help 中显示的简要描述
|
||||
|
||||
## 用法
|
||||
|
||||
```
|
||||
```
|
||||
|
||||
/your-command [args]
|
||||
```
|
||||
```
|
||||
|
||||
|
||||
## 工作流程
|
||||
|
||||
1. 第一步
|
||||
2. 第二步
|
||||
3. 最后一步
|
||||
1. 第一步
|
||||
2. 第二步
|
||||
3. 最后一步
|
||||
|
||||
## 输出
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
**🌐 语言 / 语言 / 語言**
|
||||
**语言 / 语言 / 語言**
|
||||
|
||||
[**English**](../../README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md)
|
||||
|
||||
@@ -150,7 +150,7 @@
|
||||
|
||||
***
|
||||
|
||||
## 🚀 快速开始
|
||||
## 快速开始
|
||||
|
||||
在 2 分钟内启动并运行:
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
|
||||
### 步骤 2:安装规则(必需)
|
||||
|
||||
> ⚠️ **重要提示:** Claude Code 插件无法自动分发 `rules`。请手动安装它们:
|
||||
> WARNING: **重要提示:** Claude Code 插件无法自动分发 `rules`。请手动安装它们:
|
||||
|
||||
```bash
|
||||
# Clone the repo first
|
||||
@@ -209,11 +209,11 @@ npx ecc-install typescript
|
||||
/plugin list everything-claude-code@everything-claude-code
|
||||
```
|
||||
|
||||
✨ **搞定!** 你现在可以使用 28 个智能体、116 项技能和 59 个命令了。
|
||||
**搞定!** 你现在可以使用 28 个智能体、116 项技能和 59 个命令了。
|
||||
|
||||
***
|
||||
|
||||
## 🌐 跨平台支持
|
||||
## 跨平台支持
|
||||
|
||||
此插件现已完全支持 **Windows、macOS 和 Linux**,并与主流 IDE(Cursor、OpenCode、Antigravity)和 CLI 平台紧密集成。所有钩子和脚本都已用 Node.js 重写,以实现最大兼容性。
|
||||
|
||||
@@ -260,7 +260,7 @@ export ECC_DISABLED_HOOKS="pre:bash:tmux-reminder,post:edit:typecheck"
|
||||
|
||||
***
|
||||
|
||||
## 📦 包含内容
|
||||
## 包含内容
|
||||
|
||||
此仓库是一个 **Claude Code 插件** - 可以直接安装或手动复制组件。
|
||||
|
||||
@@ -461,7 +461,7 @@ everything-claude-code/
|
||||
|
||||
***
|
||||
|
||||
## 🛠️ 生态系统工具
|
||||
## 生态系统工具
|
||||
|
||||
### 技能创建器
|
||||
|
||||
@@ -527,11 +527,11 @@ npx ecc-agentshield init
|
||||
|
||||
[GitHub](https://github.com/affaan-m/agentshield) | [npm](https://www.npmjs.com/package/ecc-agentshield)
|
||||
|
||||
### 🔬 Plankton — 编写时代码质量强制执行
|
||||
### Plankton — 编写时代码质量强制执行
|
||||
|
||||
Plankton(致谢:@alxfazio)是用于编写时代码质量强制执行的推荐伴侣。它通过 PostToolUse 钩子在每次文件编辑时运行格式化程序和 20 多个代码检查器,然后生成 Claude 子进程(根据违规复杂度路由到 Haiku/Sonnet/Opus)来修复主智能体遗漏的问题。采用三阶段架构:静默自动格式化(解决 40-50% 的问题),将剩余的违规收集为结构化 JSON,委托给子进程修复。包含配置保护钩子,防止智能体修改检查器配置以通过检查而非修复代码。支持 Python、TypeScript、Shell、YAML、JSON、TOML、Markdown 和 Dockerfile。与 AgentShield 结合使用,实现安全 + 质量覆盖。完整集成指南请参阅 `skills/plankton-code-quality/`。
|
||||
|
||||
### 🧠 持续学习 v2
|
||||
### 持续学习 v2
|
||||
|
||||
基于本能的学习系统会自动学习您的模式:
|
||||
|
||||
@@ -546,7 +546,7 @@ Plankton(致谢:@alxfazio)是用于编写时代码质量强制执行的推
|
||||
|
||||
***
|
||||
|
||||
## 📋 要求
|
||||
## 要求
|
||||
|
||||
### Claude Code CLI 版本
|
||||
|
||||
@@ -562,7 +562,7 @@ claude --version
|
||||
|
||||
### 重要提示:钩子自动加载行为
|
||||
|
||||
> ⚠️ **对于贡献者:** 请勿向 `.claude-plugin/plugin.json` 添加 `"hooks"` 字段。这由回归测试强制执行。
|
||||
> WARNING: **对于贡献者:** 请勿向 `.claude-plugin/plugin.json` 添加 `"hooks"` 字段。这由回归测试强制执行。
|
||||
|
||||
Claude Code v2.1+ **会自动加载** 任何已安装插件中的 `hooks/hooks.json`(按约定)。在 `plugin.json` 中显式声明会导致重复检测错误:
|
||||
|
||||
@@ -574,7 +574,7 @@ Claude Code v2.1+ **会自动加载** 任何已安装插件中的 `hooks/hooks.j
|
||||
|
||||
***
|
||||
|
||||
## 📥 安装
|
||||
## 安装
|
||||
|
||||
### 选项 1:作为插件安装(推荐)
|
||||
|
||||
@@ -630,7 +630,7 @@ Claude Code v2.1+ **会自动加载** 任何已安装插件中的 `hooks/hooks.j
|
||||
|
||||
***
|
||||
|
||||
### 🔧 选项 2:手动安装
|
||||
### 选项 2:手动安装
|
||||
|
||||
如果您希望对安装的内容进行手动控制:
|
||||
|
||||
@@ -658,7 +658,7 @@ cp -r everything-claude-code/skills/search-first ~/.claude/skills/
|
||||
|
||||
# Optional: add niche/framework-specific skills only when needed
|
||||
# for s in django-patterns django-tdd laravel-patterns springboot-patterns; do
|
||||
# cp -r everything-claude-code/skills/$s ~/.claude/skills/
|
||||
# cp -r everything-claude-code/skills/$s ~/.claude/skills/
|
||||
# done
|
||||
```
|
||||
|
||||
@@ -674,7 +674,7 @@ cp -r everything-claude-code/skills/search-first ~/.claude/skills/
|
||||
|
||||
***
|
||||
|
||||
## 🎯 关键概念
|
||||
## 关键概念
|
||||
|
||||
### 智能体
|
||||
|
||||
@@ -738,7 +738,7 @@ rules/
|
||||
|
||||
***
|
||||
|
||||
## 🗺️ 我应该使用哪个代理?
|
||||
## 我应该使用哪个代理?
|
||||
|
||||
不确定从哪里开始?使用这个快速参考:
|
||||
|
||||
@@ -787,7 +787,7 @@ rules/
|
||||
|
||||
***
|
||||
|
||||
## ❓ 常见问题
|
||||
## 常见问题
|
||||
|
||||
<details>
|
||||
<summary><b>如何检查已安装的代理/命令?</b></summary>
|
||||
@@ -895,7 +895,7 @@ cp -r everything-claude-code/rules/common/* ~/.claude/rules/
|
||||
|
||||
***
|
||||
|
||||
## 🧪 运行测试
|
||||
## 运行测试
|
||||
|
||||
该插件包含一个全面的测试套件:
|
||||
|
||||
@@ -911,7 +911,7 @@ node tests/hooks/hooks.test.js
|
||||
|
||||
***
|
||||
|
||||
## 🤝 贡献
|
||||
## 贡献
|
||||
|
||||
**欢迎并鼓励贡献。**
|
||||
|
||||
@@ -1074,7 +1074,7 @@ ECC 附带了三个示例角色配置:
|
||||
|
||||
***
|
||||
|
||||
## 🔌 OpenCode 支持
|
||||
## OpenCode 支持
|
||||
|
||||
ECC 提供 **完整的 OpenCode 支持**,包括插件和钩子。
|
||||
|
||||
@@ -1094,13 +1094,13 @@ opencode
|
||||
|
||||
| 功能特性 | Claude Code | OpenCode | 状态 |
|
||||
|---------|-------------|----------|--------|
|
||||
| 智能体 | ✅ 28 个 | ✅ 12 个 | **Claude Code 领先** |
|
||||
| 命令 | ✅ 59 个 | ✅ 31 个 | **Claude Code 领先** |
|
||||
| 技能 | ✅ 116 项 | ✅ 37 项 | **Claude Code 领先** |
|
||||
| 钩子 | ✅ 8 种事件类型 | ✅ 11 种事件 | **OpenCode 更多!** |
|
||||
| 规则 | ✅ 29 条 | ✅ 13 条指令 | **Claude Code 领先** |
|
||||
| MCP 服务器 | ✅ 14 个 | ✅ 完整 | **完全对等** |
|
||||
| 自定义工具 | ✅ 通过钩子 | ✅ 6 个原生工具 | **OpenCode 更优** |
|
||||
| 智能体 | PASS: 28 个 | PASS: 12 个 | **Claude Code 领先** |
|
||||
| 命令 | PASS: 59 个 | PASS: 31 个 | **Claude Code 领先** |
|
||||
| 技能 | PASS: 116 项 | PASS: 37 项 | **Claude Code 领先** |
|
||||
| 钩子 | PASS: 8 种事件类型 | PASS: 11 种事件 | **OpenCode 更多!** |
|
||||
| 规则 | PASS: 29 条 | PASS: 13 条指令 | **Claude Code 领先** |
|
||||
| MCP 服务器 | PASS: 14 个 | PASS: 完整 | **完全对等** |
|
||||
| 自定义工具 | PASS: 通过钩子 | PASS: 6 个原生工具 | **OpenCode 更优** |
|
||||
|
||||
### 通过插件实现的钩子支持
|
||||
|
||||
@@ -1229,7 +1229,7 @@ ECC 是**第一个最大化利用每个主要 AI 编码工具的插件**。以
|
||||
|
||||
***
|
||||
|
||||
## 📖 背景
|
||||
## 背景
|
||||
|
||||
我从实验性推出以来就一直在使用 Claude Code。在 2025 年 9 月,与 [@DRodriguezFX](https://x.com/DRodriguezFX) 一起使用 Claude Code 构建 [zenith.chat](https://zenith.chat),赢得了 Anthropic x Forum Ventures 黑客马拉松。
|
||||
|
||||
@@ -1311,7 +1311,7 @@ ECC 是**第一个最大化利用每个主要 AI 编码工具的插件**。以
|
||||
|
||||
***
|
||||
|
||||
## ⚠️ 重要说明
|
||||
## WARNING: 重要说明
|
||||
|
||||
### 令牌优化
|
||||
|
||||
@@ -1344,7 +1344,7 @@ ECC 是**第一个最大化利用每个主要 AI 编码工具的插件**。以
|
||||
|
||||
***
|
||||
|
||||
## 💜 赞助商
|
||||
## 赞助商
|
||||
|
||||
这个项目是免费和开源的。赞助商帮助保持其维护和发展。
|
||||
|
||||
@@ -1352,13 +1352,13 @@ ECC 是**第一个最大化利用每个主要 AI 编码工具的插件**。以
|
||||
|
||||
***
|
||||
|
||||
## 🌟 Star 历史
|
||||
## Star 历史
|
||||
|
||||
[](https://star-history.com/#affaan-m/everything-claude-code\&Date)
|
||||
|
||||
***
|
||||
|
||||
## 🔗 链接
|
||||
## 链接
|
||||
|
||||
* **速查指南(从这里开始):** [Claude Code 速查指南](https://x.com/affaanmustafa/status/2012378465664745795)
|
||||
* **详细指南(进阶):** [Claude Code 详细指南](https://x.com/affaanmustafa/status/2014040193557471352)
|
||||
@@ -1368,7 +1368,7 @@ ECC 是**第一个最大化利用每个主要 AI 编码工具的插件**。以
|
||||
|
||||
***
|
||||
|
||||
## 📄 许可证
|
||||
## 许可证
|
||||
|
||||
MIT - 自由使用,根据需要修改,如果可以请回馈贡献。
|
||||
|
||||
|
||||
@@ -129,33 +129,33 @@ model: opus
|
||||
## 实施步骤
|
||||
|
||||
### 阶段 1:数据库与后端 (2 个文件)
|
||||
1. **创建订阅数据迁移** (文件:supabase/migrations/004_subscriptions.sql)
|
||||
1. **创建订阅数据迁移** (文件:supabase/migrations/004_subscriptions.sql)
|
||||
- 操作:使用 RLS 策略 CREATE TABLE subscriptions
|
||||
- 原因:在服务器端存储计费状态,绝不信任客户端
|
||||
- 依赖:无
|
||||
- 风险:低
|
||||
|
||||
2. **创建 Stripe webhook 处理器** (文件:src/app/api/webhooks/stripe/route.ts)
|
||||
2. **创建 Stripe webhook 处理器** (文件:src/app/api/webhooks/stripe/route.ts)
|
||||
- 操作:处理 checkout.session.completed、customer.subscription.updated、customer.subscription.deleted 事件
|
||||
- 原因:保持订阅状态与 Stripe 同步
|
||||
- 依赖:步骤 1(需要 subscriptions 表)
|
||||
- 风险:高 — webhook 签名验证至关重要
|
||||
|
||||
### 阶段 2:Checkout 流程 (2 个文件)
|
||||
3. **创建 checkout API 路由** (文件:src/app/api/checkout/route.ts)
|
||||
3. **创建 checkout API 路由** (文件:src/app/api/checkout/route.ts)
|
||||
- 操作:使用 price_id 和 success/cancel URL 创建 Stripe Checkout 会话
|
||||
- 原因:服务器端会话创建可防止价格篡改
|
||||
- 依赖:步骤 1
|
||||
- 风险:中 — 必须验证用户已认证
|
||||
|
||||
4. **构建定价页面** (文件:src/components/PricingTable.tsx)
|
||||
4. **构建定价页面** (文件:src/components/PricingTable.tsx)
|
||||
- 操作:显示三个等级,包含功能对比和升级按钮
|
||||
- 原因:面向用户的升级流程
|
||||
- 依赖:步骤 3
|
||||
- 风险:低
|
||||
|
||||
### 阶段 3:功能权限控制 (1 个文件)
|
||||
5. **添加基于等级的中间件** (文件:src/middleware.ts)
|
||||
5. **添加基于等级的中间件** (文件:src/middleware.ts)
|
||||
- 操作:在受保护的路由上检查订阅等级,重定向免费用户
|
||||
- 原因:在服务器端强制执行等级限制
|
||||
- 依赖:步骤 1-2(需要订阅数据)
|
||||
|
||||
@@ -81,7 +81,7 @@ What would you like to know? (ask your question and I'll answer without losing t
|
||||
```
|
||||
ASIDE: [answer]
|
||||
|
||||
⚠️ Note: This answer suggests [issue] with the current approach. Want to address this before continuing, or proceed as planned?
|
||||
WARNING: Note: This answer suggests [issue] with the current approach. Want to address this before continuing, or proceed as planned?
|
||||
```
|
||||
|
||||
等待用户的决定后再恢复。
|
||||
@@ -128,7 +128,7 @@ That's the short version. Want a deeper explanation after we finish [current tas
|
||||
```
|
||||
ASIDE: [answer]
|
||||
|
||||
📝 Worth fixing: [what should be changed]. I'll flag this after the current task unless you want to address it now.
|
||||
Worth fixing: [what should be changed]. I'll flag this after the current task unless you want to address it now.
|
||||
```
|
||||
|
||||
**问题含糊不清或过于笼统:**
|
||||
@@ -159,7 +159,7 @@ No — the shared cache object in src/cache/store.ts:34 is mutated without locki
|
||||
Under concurrent requests this is a race condition. It's low risk in a single-process
|
||||
Node.js server but would be a real problem with worker threads or clustering.
|
||||
|
||||
⚠️ Note: This could affect the feature we're building. Want to address this now or continue and fix it in a follow-up?
|
||||
WARNING: Note: This could affect the feature we're building. Want to address this now or continue and fix it in a follow-up?
|
||||
```
|
||||
|
||||
***
|
||||
|
||||
@@ -128,7 +128,7 @@ All tests passed.
|
||||
| 已修改的文件 | 2 |
|
||||
| 剩余问题 | 0 |
|
||||
|
||||
构建状态:✅ 成功
|
||||
构建状态:PASS: 成功
|
||||
|
||||
```
|
||||
## 常见错误修复
|
||||
|
||||
@@ -115,16 +115,16 @@ void processUser(const User& user) {
|
||||
* 高:1
|
||||
* 中:0
|
||||
|
||||
建议:❌ 在严重问题修复前阻止合并
|
||||
建议:FAIL: 在严重问题修复前阻止合并
|
||||
|
||||
```
|
||||
## 批准标准
|
||||
|
||||
| 状态 | 条件 |
|
||||
|--------|-----------|
|
||||
| ✅ 批准 | 没有 CRITICAL 或 HIGH 级别的问题 |
|
||||
| ⚠️ 警告 | 仅有 MEDIUM 级别的问题(谨慎合并) |
|
||||
| ❌ 阻止 | 发现 CRITICAL 或 HIGH 级别的问题 |
|
||||
| PASS: 批准 | 没有 CRITICAL 或 HIGH 级别的问题 |
|
||||
| WARNING: 警告 | 仅有 MEDIUM 级别的问题(谨慎合并) |
|
||||
| FAIL: 阻止 | 发现 CRITICAL 或 HIGH 级别的问题 |
|
||||
|
||||
## 与其他命令的集成
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ Artifacts generated:
|
||||
╔══════════════════════════════════════════════════════════════╗
|
||||
║ E2E 测试结果 ║
|
||||
╠══════════════════════════════════════════════════════════════╣
|
||||
║ 状态: ✅ 所有测试通过 ║
|
||||
║ 状态: PASS: 所有测试通过 ║
|
||||
║ 总计: 3 项测试 ║
|
||||
║ 通过: 3 (100%) ║
|
||||
║ 失败: 0 ║
|
||||
@@ -193,15 +193,15 @@ Artifacts generated:
|
||||
╚══════════════════════════════════════════════════════════════╝
|
||||
|
||||
产物:
|
||||
📸 截图: 2 个文件
|
||||
📹 视频: 0 个文件(仅在失败时生成)
|
||||
🔍 追踪文件: 0 个文件(仅在失败时生成)
|
||||
📊 HTML 报告: playwright-report/index.html
|
||||
截图: 2 个文件
|
||||
视频: 0 个文件(仅在失败时生成)
|
||||
追踪文件: 0 个文件(仅在失败时生成)
|
||||
HTML 报告: playwright-report/index.html
|
||||
|
||||
查看报告: npx playwright show-report
|
||||
```
|
||||
|
||||
✅ E2E 测试套件已准备好进行 CI/CD 集成!
|
||||
PASS: E2E 测试套件已准备好进行 CI/CD 集成!
|
||||
|
||||
````
|
||||
## 测试产物
|
||||
@@ -238,7 +238,7 @@ open artifacts/search-results.png
|
||||
如果测试间歇性失败:
|
||||
|
||||
```
|
||||
⚠️ FLAKY TEST DETECTED: tests/e2e/markets/trade.spec.ts
|
||||
WARNING: FLAKY TEST DETECTED: tests/e2e/markets/trade.spec.ts
|
||||
|
||||
测试通过了 7/10 次运行 (70% 通过率)
|
||||
|
||||
@@ -258,10 +258,10 @@ open artifacts/search-results.png
|
||||
|
||||
默认情况下,测试在多个浏览器上运行:
|
||||
|
||||
* ✅ Chromium(桌面版 Chrome)
|
||||
* ✅ Firefox(桌面版)
|
||||
* ✅ WebKit(桌面版 Safari)
|
||||
* ✅ 移动版 Chrome(可选)
|
||||
* PASS: Chromium(桌面版 Chrome)
|
||||
* PASS: Firefox(桌面版)
|
||||
* PASS: WebKit(桌面版 Safari)
|
||||
* PASS: 移动版 Chrome(可选)
|
||||
|
||||
在 `playwright.config.ts` 中配置以调整浏览器。
|
||||
|
||||
@@ -289,7 +289,7 @@ open artifacts/search-results.png
|
||||
|
||||
对于 PMX,请优先考虑以下 E2E 测试:
|
||||
|
||||
**🔴 关键(必须始终通过):**
|
||||
**关键(必须始终通过):**
|
||||
|
||||
1. 用户可以连接钱包
|
||||
2. 用户可以浏览市场
|
||||
@@ -299,7 +299,7 @@ open artifacts/search-results.png
|
||||
6. 市场正确结算
|
||||
7. 用户可以提取资金
|
||||
|
||||
**🟡 重要:**
|
||||
**重要:**
|
||||
|
||||
1. 市场创建流程
|
||||
2. 用户资料更新
|
||||
@@ -312,21 +312,21 @@ open artifacts/search-results.png
|
||||
|
||||
**应该:**
|
||||
|
||||
* ✅ 使用页面对象模型以提高可维护性
|
||||
* ✅ 使用 data-testid 属性作为选择器
|
||||
* ✅ 等待 API 响应,而不是使用任意超时
|
||||
* ✅ 测试关键用户旅程的端到端
|
||||
* ✅ 在合并到主分支前运行测试
|
||||
* ✅ 在测试失败时审查工件
|
||||
* PASS: 使用页面对象模型以提高可维护性
|
||||
* PASS: 使用 data-testid 属性作为选择器
|
||||
* PASS: 等待 API 响应,而不是使用任意超时
|
||||
* PASS: 测试关键用户旅程的端到端
|
||||
* PASS: 在合并到主分支前运行测试
|
||||
* PASS: 在测试失败时审查工件
|
||||
|
||||
**不应该:**
|
||||
|
||||
* ❌ 使用不稳定的选择器(CSS 类可能会改变)
|
||||
* ❌ 测试实现细节
|
||||
* ❌ 针对生产环境运行测试
|
||||
* ❌ 忽略不稳定测试
|
||||
* ❌ 在失败时跳过工件审查
|
||||
* ❌ 使用 E2E 测试每个边缘情况(使用单元测试)
|
||||
* FAIL: 使用不稳定的选择器(CSS 类可能会改变)
|
||||
* FAIL: 测试实现细节
|
||||
* FAIL: 针对生产环境运行测试
|
||||
* FAIL: 忽略不稳定测试
|
||||
* FAIL: 在失败时跳过工件审查
|
||||
* FAIL: 使用 E2E 测试每个边缘情况(使用单元测试)
|
||||
|
||||
## 重要注意事项
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ ok project/internal/handler 0.023s
|
||||
| 已修改的文件 | 2 |
|
||||
| 剩余问题 | 0 |
|
||||
|
||||
构建状态:✅ 成功
|
||||
构建状态:PASS: 成功
|
||||
|
||||
```
|
||||
## 常见错误修复
|
||||
|
||||
@@ -131,16 +131,16 @@ return fmt.Errorf("get user %s: %w", userID, err)
|
||||
* 高:1
|
||||
* 中:0
|
||||
|
||||
建议:❌ 在严重问题修复前阻止合并
|
||||
建议:FAIL: 在严重问题修复前阻止合并
|
||||
|
||||
```
|
||||
## 批准标准
|
||||
|
||||
| 状态 | 条件 |
|
||||
|--------|-----------|
|
||||
| ✅ 批准 | 无 CRITICAL 或 HIGH 级别问题 |
|
||||
| ⚠️ 警告 | 仅有 MEDIUM 级别问题 (谨慎合并) |
|
||||
| ❌ 阻止 | 发现 CRITICAL 或 HIGH 级别问题 |
|
||||
| PASS: 批准 | 无 CRITICAL 或 HIGH 级别问题 |
|
||||
| WARNING: 警告 | 仅有 MEDIUM 级别问题 (谨慎合并) |
|
||||
| FAIL: 阻止 | 发现 CRITICAL 或 HIGH 级别问题 |
|
||||
|
||||
## 与其他命令的集成
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ python3 ~/.claude/skills/continuous-learning-v2/scripts/instinct-cli.py import <
|
||||
## 导入过程
|
||||
|
||||
```
|
||||
📥 从 team-instincts.yaml 导入本能
|
||||
从 team-instincts.yaml 导入本能
|
||||
================================================
|
||||
|
||||
发现 12 个待导入的本能。
|
||||
@@ -60,12 +60,12 @@ python3 ~/.claude/skills/continuous-learning-v2/scripts/instinct-cli.py import <
|
||||
|
||||
## 重复本能 (3)
|
||||
已存在类似本能:
|
||||
⚠️ prefer-functional-style
|
||||
WARNING: prefer-functional-style
|
||||
本地: 0.8 置信度, 12 次观察
|
||||
导入: 0.7 置信度
|
||||
→ 保留本地 (置信度更高)
|
||||
|
||||
⚠️ test-first-workflow
|
||||
WARNING: test-first-workflow
|
||||
本地: 0.75 置信度
|
||||
导入: 0.9 置信度
|
||||
→ 更新为导入 (置信度更高)
|
||||
@@ -105,10 +105,10 @@ project_name: "my-project"
|
||||
导入后:
|
||||
|
||||
```
|
||||
✅ 导入完成!
|
||||
PASS: 导入完成!
|
||||
|
||||
新增:8 项本能
|
||||
更新:1 项本能
|
||||
新增:8 项本能
|
||||
更新:1 项本能
|
||||
跳过:3 项本能(已存在同等或更高置信度的版本)
|
||||
|
||||
新本能已保存至:~/.claude/homunculus/instincts/inherited/
|
||||
|
||||
@@ -132,7 +132,7 @@ $ ./gradlew test
|
||||
| Files modified | 2 |
|
||||
| Remaining issues | 0 |
|
||||
|
||||
Build Status: ✅ SUCCESS
|
||||
Build Status: PASS: SUCCESS
|
||||
````
|
||||
|
||||
## 常见的已修复错误
|
||||
|
||||
@@ -84,7 +84,7 @@ Agent:
|
||||
## Static Analysis Results
|
||||
✓ Build: Successful
|
||||
✓ detekt: No issues
|
||||
⚠ ktlint: 2 formatting warnings
|
||||
WARNING: ktlint: 2 formatting warnings
|
||||
|
||||
## Issues Found
|
||||
|
||||
@@ -120,16 +120,16 @@ launch {
|
||||
- HIGH: 1
|
||||
- MEDIUM: 0
|
||||
|
||||
Recommendation: ❌ Block merge until CRITICAL issue is fixed
|
||||
Recommendation: FAIL: Block merge until CRITICAL issue is fixed
|
||||
````
|
||||
|
||||
## 批准标准
|
||||
|
||||
| 状态 | 条件 |
|
||||
|--------|-----------|
|
||||
| ✅ 批准 | 无严重或高优先级问题 |
|
||||
| ⚠️ 警告 | 仅存在中优先级问题(谨慎合并) |
|
||||
| ❌ 阻止 | 发现严重或高优先级问题 |
|
||||
| PASS: 批准 | 无严重或高优先级问题 |
|
||||
| WARNING: 警告 | 仅存在中优先级问题(谨慎合并) |
|
||||
| FAIL: 阻止 | 发现严重或高优先级问题 |
|
||||
|
||||
## 与其他命令的集成
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ origin: auto-extracted
|
||||
| **吸收到 \[X]** | 应追加到现有技能 | 显示目标技能和添加内容 → 步骤 6 |
|
||||
| **放弃** | 琐碎、冗余或过于抽象 | 解释原因并停止 |
|
||||
|
||||
**指导维度**(用于告知裁决,不进行评分):
|
||||
**指导维度**(用于告知裁决,不进行评分):
|
||||
|
||||
* **具体性和可操作性**:包含可立即使用的代码示例或命令
|
||||
* **范围契合度**:名称、触发条件和内容保持一致,并专注于单一模式
|
||||
|
||||
@@ -209,11 +209,11 @@ mcp__ace-tool__search_context({
|
||||
|
||||
3. 以 **粗体文本** 输出提示(必须使用实际保存的文件路径):
|
||||
|
||||
***
|
||||
***
|
||||
|
||||
**计划已生成并保存至 `.claude/plan/actual-feature-name.md`**
|
||||
**计划已生成并保存至 `.claude/plan/actual-feature-name.md`**
|
||||
|
||||
**请审阅以上计划。您可以:**
|
||||
**请审阅以上计划。您可以:**
|
||||
|
||||
* **修改计划**:告诉我需要调整的内容,我会更新计划
|
||||
* **执行计划**:复制以下命令到新会话
|
||||
@@ -222,9 +222,9 @@ mcp__ace-tool__search_context({
|
||||
/ccg:execute .claude/plan/actual-feature-name.md
|
||||
```
|
||||
|
||||
***
|
||||
***
|
||||
|
||||
**注意**:上面的 `actual-feature-name.md` 必须替换为实际保存的文件名!
|
||||
**注意**:上面的 `actual-feature-name.md` 必须替换为实际保存的文件名!
|
||||
|
||||
4. **立即终止当前响应**(在此停止。不再进行工具调用。)
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ Agent:
|
||||
## Static Analysis Results
|
||||
✓ ruff: No issues
|
||||
✓ mypy: No errors
|
||||
⚠️ black: 2 files need reformatting
|
||||
WARNING: black: 2 files need reformatting
|
||||
✓ bandit: No security issues
|
||||
|
||||
## Issues Found
|
||||
@@ -171,7 +171,7 @@ with open("config.json") as f: # Good
|
||||
* 高:1
|
||||
* 中:2
|
||||
|
||||
建议:❌ 在关键问题修复前阻止合并
|
||||
建议:FAIL: 在关键问题修复前阻止合并
|
||||
|
||||
## 所需的格式化
|
||||
|
||||
@@ -182,9 +182,9 @@ with open("config.json") as f: # Good
|
||||
|
||||
| 状态 | 条件 |
|
||||
|--------|-----------|
|
||||
| ✅ 批准 | 无 CRITICAL 或 HIGH 级别问题 |
|
||||
| ⚠️ 警告 | 仅存在 MEDIUM 级别问题(谨慎合并) |
|
||||
| ❌ 阻止 | 发现 CRITICAL 或 HIGH 级别问题 |
|
||||
| PASS: 批准 | 无 CRITICAL 或 HIGH 级别问题 |
|
||||
| WARNING: 警告 | 仅存在 MEDIUM 级别问题(谨慎合并) |
|
||||
| FAIL: 阻止 | 发现 CRITICAL 或 HIGH 级别问题 |
|
||||
|
||||
## 与其他命令的集成
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
已跳过: 2 个项目(测试失败)
|
||||
已节省: ~450 行代码被移除
|
||||
──────────────────────────────
|
||||
所有测试通过 ✅
|
||||
所有测试通过 PASS:
|
||||
```
|
||||
|
||||
## 规则
|
||||
|
||||
@@ -64,9 +64,9 @@ description: 从 ~/.claude/sessions/ 加载最新的会话文件,并从上次
|
||||
[用你自己的话总结 2-3 句话]
|
||||
|
||||
当前状态:
|
||||
✅ 已完成:[数量] 项已确认
|
||||
🔄 进行中:[列出进行中的文件]
|
||||
🗒️ 未开始:[列出计划但未开始的文件]
|
||||
PASS: 已完成:[数量] 项已确认
|
||||
进行中:[列出进行中的文件]
|
||||
未开始:[列出计划但未开始的文件]
|
||||
|
||||
不应重试的内容:
|
||||
[列出每个失败的方法及其原因——此部分至关重要]
|
||||
@@ -98,10 +98,10 @@ description: 从 ~/.claude/sessions/ 加载最新的会话文件,并从上次
|
||||
加载该日期最近修改的匹配文件,无论其使用的是旧的无ID格式还是当前的短ID格式。
|
||||
|
||||
**会话文件引用了已不存在的文件:**
|
||||
在简报中注明 — "⚠️ 会话中引用了 `path/to/file.ts`,但在磁盘上未找到。"
|
||||
在简报中注明 — "WARNING: 会话中引用了 `path/to/file.ts`,但在磁盘上未找到。"
|
||||
|
||||
**会话文件来自超过7天前:**
|
||||
注明时间间隔 — "⚠️ 此会话来自 N 天前(阈值:7天)。情况可能已发生变化。" — 然后正常继续。
|
||||
注明时间间隔 — "WARNING: 此会话来自 N 天前(阈值:7天)。情况可能已发生变化。" — 然后正常继续。
|
||||
|
||||
**用户直接提供了文件路径(例如,从队友处转发而来):**
|
||||
读取它并遵循相同的简报流程 — 无论来源如何,格式都是相同的。
|
||||
@@ -124,13 +124,13 @@ SESSION LOADED: /Users/you/.claude/sessions/2024-01-15-abc123de-session.tmp
|
||||
注册和登录端点已部分完成。通过中间件进行路由保护尚未开始。
|
||||
|
||||
当前状态:
|
||||
✅ 已完成:3 项(注册端点、JWT 生成、密码哈希)
|
||||
🔄 进行中:app/api/auth/login/route.ts(令牌有效,但 cookie 尚未设置)
|
||||
🗒️ 未开始:middleware.ts、app/login/page.tsx
|
||||
PASS: 已完成:3 项(注册端点、JWT 生成、密码哈希)
|
||||
进行中:app/api/auth/login/route.ts(令牌有效,但 cookie 尚未设置)
|
||||
未开始:middleware.ts、app/login/page.tsx
|
||||
|
||||
需避免的事项:
|
||||
❌ Next-Auth — 与自定义 Prisma 适配器冲突,每次请求均抛出适配器错误
|
||||
❌ localStorage 存储 JWT — 导致 SSR 水合不匹配,与 Next.js 不兼容
|
||||
FAIL: Next-Auth — 与自定义 Prisma 适配器冲突,每次请求均抛出适配器错误
|
||||
FAIL: localStorage 存储 JWT — 导致 SSR 水合不匹配,与 Next.js 不兼容
|
||||
|
||||
待解决问题 / 阻碍:
|
||||
- cookies().set() 在路由处理器中是否有效,还是仅适用于服务器操作?
|
||||
|
||||
@@ -122,10 +122,10 @@ mkdir -p ~/.claude/sessions
|
||||
|
||||
| 文件 | 状态 | 备注 |
|
||||
| ----------------- | -------------- | ---------------------------- |
|
||||
| `path/to/file.ts` | ✅ 完成 | [其作用] |
|
||||
| `path/to/file.ts` | 🔄 进行中 | [已完成什么,剩余什么] |
|
||||
| `path/to/file.ts` | ❌ 损坏 | [问题所在] |
|
||||
| `path/to/file.ts` | 🗒️ 未开始 | [计划但尚未接触] |
|
||||
| `path/to/file.ts` | PASS: 完成 | [其作用] |
|
||||
| `path/to/file.ts` | 进行中 | [已完成什么,剩余什么] |
|
||||
| `path/to/file.ts` | FAIL: 损坏 | [问题所在] |
|
||||
| `path/to/file.ts` | 未开始 | [计划但尚未接触] |
|
||||
|
||||
如果未修改任何文件:"本次会话未修改任何文件。"
|
||||
|
||||
@@ -213,11 +213,11 @@ mkdir -p ~/.claude/sessions
|
||||
|
||||
| 文件 | 状态 | 备注 |
|
||||
| -------------------------------- | -------------- | ----------------------------------------------- |
|
||||
| `app/api/auth/register/route.ts` | ✅ 已完成 | 工作正常,已测试 |
|
||||
| `app/api/auth/login/route.ts` | 🔄 进行中 | 令牌已生成但尚未设置 cookie |
|
||||
| `lib/auth.ts` | ✅ 已完成 | JWT 辅助函数,全部已测试 |
|
||||
| `middleware.ts` | 🗒️ 未开始 | 路由保护,需要先实现 cookie 读取逻辑 |
|
||||
| `app/login/page.tsx` | 🗒️ 未开始 | UI 尚未开始 |
|
||||
| `app/api/auth/register/route.ts` | PASS: 已完成 | 工作正常,已测试 |
|
||||
| `app/api/auth/login/route.ts` | 进行中 | 令牌已生成但尚未设置 cookie |
|
||||
| `lib/auth.ts` | PASS: 已完成 | JWT 辅助函数,全部已测试 |
|
||||
| `middleware.ts` | 未开始 | 路由保护,需要先实现 cookie 读取逻辑 |
|
||||
| `app/login/page.tsx` | 未开始 | UI 尚未开始 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ FAIL lib/liquidity.test.ts
|
||||
1 test failed, 0 passed
|
||||
```
|
||||
|
||||
✅ 测试按预期失败。准备实施。
|
||||
PASS: 测试按预期失败。准备实施。
|
||||
|
||||
## 步骤 4:实现最小化代码(绿)
|
||||
|
||||
@@ -180,7 +180,7 @@ PASS lib/liquidity.test.ts
|
||||
3 tests passed
|
||||
```
|
||||
|
||||
✅ 所有测试通过!
|
||||
PASS: 所有测试通过!
|
||||
|
||||
## 步骤 6:重构(改进)
|
||||
|
||||
@@ -237,7 +237,7 @@ PASS lib/liquidity.test.ts
|
||||
3 tests passed
|
||||
```
|
||||
|
||||
✅ 重构完成,测试仍然通过!
|
||||
PASS: 重构完成,测试仍然通过!
|
||||
|
||||
## 步骤 8:检查覆盖率
|
||||
|
||||
@@ -248,29 +248,29 @@ File | % Stmts | % Branch | % Funcs | % Lines
|
||||
---------------|---------|----------|---------|--------
|
||||
liquidity.ts | 100 | 100 | 100 | 100
|
||||
|
||||
Coverage: 100% ✅ (Target: 80%)
|
||||
Coverage: 100% PASS: (Target: 80%)
|
||||
```
|
||||
|
||||
✅ TDD 会话完成!
|
||||
PASS: TDD 会话完成!
|
||||
|
||||
```
|
||||
## TDD 最佳实践
|
||||
|
||||
**应做:**
|
||||
- ✅ 先写测试,再写实现
|
||||
- ✅ 运行测试并确认失败,再实现功能
|
||||
- ✅ 编写最少代码使测试通过
|
||||
- ✅ 仅在测试通过后进行重构
|
||||
- ✅ 添加边界情况和错误场景
|
||||
- ✅ 目标覆盖率 80% 以上(关键代码 100%)
|
||||
- PASS: 先写测试,再写实现
|
||||
- PASS: 运行测试并确认失败,再实现功能
|
||||
- PASS: 编写最少代码使测试通过
|
||||
- PASS: 仅在测试通过后进行重构
|
||||
- PASS: 添加边界情况和错误场景
|
||||
- PASS: 目标覆盖率 80% 以上(关键代码 100%)
|
||||
|
||||
**不应做:**
|
||||
- ❌ 先写实现再写测试
|
||||
- ❌ 每次更改后跳过运行测试
|
||||
- ❌ 一次性编写过多代码
|
||||
- ❌ 忽略失败的测试
|
||||
- ❌ 测试实现细节(应测试行为)
|
||||
- ❌ 过度模拟(优先使用集成测试)
|
||||
- FAIL: 先写实现再写测试
|
||||
- FAIL: 每次更改后跳过运行测试
|
||||
- FAIL: 一次性编写过多代码
|
||||
- FAIL: 忽略失败的测试
|
||||
- FAIL: 测试实现细节(应测试行为)
|
||||
- FAIL: 过度模拟(优先使用集成测试)
|
||||
|
||||
## 应包含的测试类型
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
src/services/auth.ts 45% 88%
|
||||
src/utils/validation.ts 32% 82%
|
||||
──────────────────────────────
|
||||
总计: 67% 84% ✅
|
||||
总计: 67% 84% PASS:
|
||||
```
|
||||
|
||||
## 重点关注领域
|
||||
|
||||
@@ -39,7 +39,7 @@ AI 编写修复 → AI 审查修复 → AI 表示“看起来正确” → 漏
|
||||
→ 修复了生产路径,忘记了沙箱路径
|
||||
→ AI 审核时再次遗漏(第 4 次出现)
|
||||
|
||||
修复 4:测试在首次运行时立即捕获了问题 ✅
|
||||
修复 4:测试在首次运行时立即捕获了问题 PASS:
|
||||
```
|
||||
|
||||
模式:**沙盒/生产环境路径不一致**是 AI 引入的 #1 回归问题。
|
||||
@@ -249,14 +249,14 @@ User: "バグチェックして" (or "/bug-check")
|
||||
**频率**:最常见(在 4 个回归问题中观察到 3 个)
|
||||
|
||||
```typescript
|
||||
// ❌ AI adds field to production path only
|
||||
// FAIL: AI adds field to production path only
|
||||
if (isSandboxMode()) {
|
||||
return { data: { id, email, name } }; // Missing new field
|
||||
}
|
||||
// Production path
|
||||
return { data: { id, email, name, notification_settings } };
|
||||
|
||||
// ✅ Both paths must return the same shape
|
||||
// PASS: Both paths must return the same shape
|
||||
if (isSandboxMode()) {
|
||||
return { data: { id, email, name, notification_settings: null } };
|
||||
}
|
||||
@@ -282,7 +282,7 @@ it("sandbox and production return same fields", async () => {
|
||||
**频率**:在使用 Supabase/Prisma 添加新列时常见
|
||||
|
||||
```typescript
|
||||
// ❌ New column added to response but not to SELECT
|
||||
// FAIL: New column added to response but not to SELECT
|
||||
const { data } = await supabase
|
||||
.from("users")
|
||||
.select("id, email, name") // notification_settings not here
|
||||
@@ -291,7 +291,7 @@ const { data } = await supabase
|
||||
return { data: { ...data, notification_settings: data.notification_settings } };
|
||||
// → notification_settings is always undefined
|
||||
|
||||
// ✅ Use SELECT * or explicitly include new columns
|
||||
// PASS: Use SELECT * or explicitly include new columns
|
||||
const { data } = await supabase
|
||||
.from("users")
|
||||
.select("*")
|
||||
@@ -303,13 +303,13 @@ const { data } = await supabase
|
||||
**频率**:中等——当向现有组件添加错误处理时
|
||||
|
||||
```typescript
|
||||
// ❌ Error state set but old data not cleared
|
||||
// FAIL: Error state set but old data not cleared
|
||||
catch (err) {
|
||||
setError("Failed to load");
|
||||
// reservations still shows data from previous tab!
|
||||
}
|
||||
|
||||
// ✅ Clear related state on error
|
||||
// PASS: Clear related state on error
|
||||
catch (err) {
|
||||
setReservations([]); // Clear stale data
|
||||
setError("Failed to load");
|
||||
@@ -319,14 +319,14 @@ catch (err) {
|
||||
### 模式 4:乐观更新未正确回滚
|
||||
|
||||
```typescript
|
||||
// ❌ No rollback on failure
|
||||
// FAIL: No rollback on failure
|
||||
const handleRemove = async (id: string) => {
|
||||
setItems(prev => prev.filter(i => i.id !== id));
|
||||
await fetch(`/api/items/${id}`, { method: "DELETE" });
|
||||
// If API fails, item is gone from UI but still in DB
|
||||
};
|
||||
|
||||
// ✅ Capture previous state and rollback on failure
|
||||
// PASS: Capture previous state and rollback on failure
|
||||
const handleRemove = async (id: string) => {
|
||||
const prevItems = [...items];
|
||||
setItems(prev => prev.filter(i => i.id !== id));
|
||||
@@ -362,11 +362,11 @@ const handleRemove = async (id: string) => {
|
||||
|
||||
| AI 回归模式 | 测试策略 | 优先级 |
|
||||
|---|---|---|
|
||||
| 沙盒/生产环境不匹配 | 断言沙盒模式下响应结构相同 | 🔴 高 |
|
||||
| SELECT 子句遗漏 | 断言响应中包含所有必需字段 | 🔴 高 |
|
||||
| 错误状态泄漏 | 断言出错时状态已清理 | 🟡 中 |
|
||||
| 缺少回滚 | 断言 API 失败时状态已恢复 | 🟡 中 |
|
||||
| 类型转换掩盖 null | 断言字段不为 undefined | 🟡 中 |
|
||||
| 沙盒/生产环境不匹配 | 断言沙盒模式下响应结构相同 | 高 |
|
||||
| SELECT 子句遗漏 | 断言响应中包含所有必需字段 | 高 |
|
||||
| 错误状态泄漏 | 断言出错时状态已清理 | 中 |
|
||||
| 缺少回滚 | 断言 API 失败时状态已恢复 | 中 |
|
||||
| 类型转换掩盖 null | 断言字段不为 undefined | 中 |
|
||||
|
||||
## 要 / 不要
|
||||
|
||||
|
||||
@@ -37,10 +37,10 @@ project/
|
||||
### 依赖规则
|
||||
|
||||
```
|
||||
app → presentation, domain, data, core
|
||||
presentation → domain, design-system, core
|
||||
data → domain, core
|
||||
domain → core (或无依赖)
|
||||
app → presentation, domain, data, core
|
||||
presentation → domain, design-system, core
|
||||
data → domain, core
|
||||
domain → core (或无依赖)
|
||||
core → (无依赖)
|
||||
```
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ origin: ECC
|
||||
### RESTful API 结构
|
||||
|
||||
```typescript
|
||||
// ✅ Resource-based URLs
|
||||
// PASS: Resource-based URLs
|
||||
GET /api/markets # List resources
|
||||
GET /api/markets/:id # Get single resource
|
||||
POST /api/markets # Create resource
|
||||
@@ -31,7 +31,7 @@ PUT /api/markets/:id # Replace resource
|
||||
PATCH /api/markets/:id # Update resource
|
||||
DELETE /api/markets/:id # Delete resource
|
||||
|
||||
// ✅ Query parameters for filtering, sorting, pagination
|
||||
// PASS: Query parameters for filtering, sorting, pagination
|
||||
GET /api/markets?status=active&sort=volume&limit=20&offset=0
|
||||
```
|
||||
|
||||
@@ -131,7 +131,7 @@ export default withAuth(async (req, res) => {
|
||||
### 查询优化
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Select only needed columns
|
||||
// PASS: GOOD: Select only needed columns
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('id, name, status, volume')
|
||||
@@ -139,7 +139,7 @@ const { data } = await supabase
|
||||
.order('volume', { ascending: false })
|
||||
.limit(10)
|
||||
|
||||
// ❌ BAD: Select everything
|
||||
// FAIL: BAD: Select everything
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('*')
|
||||
@@ -148,13 +148,13 @@ const { data } = await supabase
|
||||
### N+1 查询预防
|
||||
|
||||
```typescript
|
||||
// ❌ BAD: N+1 query problem
|
||||
// FAIL: BAD: N+1 query problem
|
||||
const markets = await getMarkets()
|
||||
for (const market of markets) {
|
||||
market.creator = await getUser(market.creator_id) // N queries
|
||||
}
|
||||
|
||||
// ✅ GOOD: Batch fetch
|
||||
// PASS: GOOD: Batch fetch
|
||||
const markets = await getMarkets()
|
||||
const creatorIds = markets.map(m => m.creator_id)
|
||||
const creators = await getUsers(creatorIds) // 1 query
|
||||
|
||||
@@ -7,7 +7,7 @@ origin: ECC
|
||||
metadata:
|
||||
author: evos
|
||||
clawdbot:
|
||||
emoji: "🤝"
|
||||
emoji: ""
|
||||
---
|
||||
|
||||
# 承运商关系管理
|
||||
|
||||
@@ -97,7 +97,7 @@ ORDER BY hour DESC;
|
||||
### 高效过滤
|
||||
|
||||
```sql
|
||||
-- ✅ GOOD: Use indexed columns first
|
||||
-- PASS: GOOD: Use indexed columns first
|
||||
SELECT *
|
||||
FROM markets_analytics
|
||||
WHERE date >= '2025-01-01'
|
||||
@@ -106,7 +106,7 @@ WHERE date >= '2025-01-01'
|
||||
ORDER BY date DESC
|
||||
LIMIT 100;
|
||||
|
||||
-- ❌ BAD: Filter on non-indexed columns first
|
||||
-- FAIL: BAD: Filter on non-indexed columns first
|
||||
SELECT *
|
||||
FROM markets_analytics
|
||||
WHERE volume > 1000
|
||||
@@ -117,7 +117,7 @@ WHERE volume > 1000
|
||||
### 聚合
|
||||
|
||||
```sql
|
||||
-- ✅ GOOD: Use ClickHouse-specific aggregation functions
|
||||
-- PASS: GOOD: Use ClickHouse-specific aggregation functions
|
||||
SELECT
|
||||
toStartOfDay(created_at) AS day,
|
||||
market_id,
|
||||
@@ -130,7 +130,7 @@ WHERE created_at >= today() - INTERVAL 7 DAY
|
||||
GROUP BY day, market_id
|
||||
ORDER BY day DESC, total_volume DESC;
|
||||
|
||||
-- ✅ Use quantile for percentiles (more efficient than percentile)
|
||||
-- PASS: Use quantile for percentiles (more efficient than percentile)
|
||||
SELECT
|
||||
quantile(0.50)(trade_size) AS median,
|
||||
quantile(0.95)(trade_size) AS p95,
|
||||
@@ -173,7 +173,7 @@ const clickhouse = new ClickHouse({
|
||||
}
|
||||
})
|
||||
|
||||
// ✅ Batch insert (efficient)
|
||||
// PASS: Batch insert (efficient)
|
||||
async function bulkInsertTrades(trades: Trade[]) {
|
||||
const values = trades.map(trade => `(
|
||||
'${trade.id}',
|
||||
@@ -189,7 +189,7 @@ async function bulkInsertTrades(trades: Trade[]) {
|
||||
`).toPromise()
|
||||
}
|
||||
|
||||
// ❌ Individual inserts (slow)
|
||||
// FAIL: Individual inserts (slow)
|
||||
async function insertTrade(trade: Trade) {
|
||||
// Don't do this in a loop!
|
||||
await clickhouse.query(`
|
||||
|
||||
@@ -52,12 +52,12 @@ origin: ECC
|
||||
### 变量命名
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Descriptive names
|
||||
// PASS: GOOD: Descriptive names
|
||||
const marketSearchQuery = 'election'
|
||||
const isUserAuthenticated = true
|
||||
const totalRevenue = 1000
|
||||
|
||||
// ❌ BAD: Unclear names
|
||||
// FAIL: BAD: Unclear names
|
||||
const q = 'election'
|
||||
const flag = true
|
||||
const x = 1000
|
||||
@@ -66,12 +66,12 @@ const x = 1000
|
||||
### 函数命名
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Verb-noun pattern
|
||||
// PASS: GOOD: Verb-noun pattern
|
||||
async function fetchMarketData(marketId: string) { }
|
||||
function calculateSimilarity(a: number[], b: number[]) { }
|
||||
function isValidEmail(email: string): boolean { }
|
||||
|
||||
// ❌ BAD: Unclear or noun-only
|
||||
// FAIL: BAD: Unclear or noun-only
|
||||
async function market(id: string) { }
|
||||
function similarity(a, b) { }
|
||||
function email(e) { }
|
||||
@@ -80,7 +80,7 @@ function email(e) { }
|
||||
### 不可变性模式 (关键)
|
||||
|
||||
```typescript
|
||||
// ✅ ALWAYS use spread operator
|
||||
// PASS: ALWAYS use spread operator
|
||||
const updatedUser = {
|
||||
...user,
|
||||
name: 'New Name'
|
||||
@@ -88,7 +88,7 @@ const updatedUser = {
|
||||
|
||||
const updatedArray = [...items, newItem]
|
||||
|
||||
// ❌ NEVER mutate directly
|
||||
// FAIL: NEVER mutate directly
|
||||
user.name = 'New Name' // BAD
|
||||
items.push(newItem) // BAD
|
||||
```
|
||||
@@ -96,7 +96,7 @@ items.push(newItem) // BAD
|
||||
### 错误处理
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Comprehensive error handling
|
||||
// PASS: GOOD: Comprehensive error handling
|
||||
async function fetchData(url: string) {
|
||||
try {
|
||||
const response = await fetch(url)
|
||||
@@ -112,7 +112,7 @@ async function fetchData(url: string) {
|
||||
}
|
||||
}
|
||||
|
||||
// ❌ BAD: No error handling
|
||||
// FAIL: BAD: No error handling
|
||||
async function fetchData(url) {
|
||||
const response = await fetch(url)
|
||||
return response.json()
|
||||
@@ -122,14 +122,14 @@ async function fetchData(url) {
|
||||
### Async/Await 最佳实践
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Parallel execution when possible
|
||||
// PASS: GOOD: Parallel execution when possible
|
||||
const [users, markets, stats] = await Promise.all([
|
||||
fetchUsers(),
|
||||
fetchMarkets(),
|
||||
fetchStats()
|
||||
])
|
||||
|
||||
// ❌ BAD: Sequential when unnecessary
|
||||
// FAIL: BAD: Sequential when unnecessary
|
||||
const users = await fetchUsers()
|
||||
const markets = await fetchMarkets()
|
||||
const stats = await fetchStats()
|
||||
@@ -138,7 +138,7 @@ const stats = await fetchStats()
|
||||
### 类型安全
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Proper types
|
||||
// PASS: GOOD: Proper types
|
||||
interface Market {
|
||||
id: string
|
||||
name: string
|
||||
@@ -150,7 +150,7 @@ function getMarket(id: string): Promise<Market> {
|
||||
// Implementation
|
||||
}
|
||||
|
||||
// ❌ BAD: Using 'any'
|
||||
// FAIL: BAD: Using 'any'
|
||||
function getMarket(id: any): Promise<any> {
|
||||
// Implementation
|
||||
}
|
||||
@@ -161,7 +161,7 @@ function getMarket(id: any): Promise<any> {
|
||||
### 组件结构
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Functional component with types
|
||||
// PASS: GOOD: Functional component with types
|
||||
interface ButtonProps {
|
||||
children: React.ReactNode
|
||||
onClick: () => void
|
||||
@@ -186,7 +186,7 @@ export function Button({
|
||||
)
|
||||
}
|
||||
|
||||
// ❌ BAD: No types, unclear structure
|
||||
// FAIL: BAD: No types, unclear structure
|
||||
export function Button(props) {
|
||||
return <button onClick={props.onClick}>{props.children}</button>
|
||||
}
|
||||
@@ -195,7 +195,7 @@ export function Button(props) {
|
||||
### 自定义 Hooks
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Reusable custom hook
|
||||
// PASS: GOOD: Reusable custom hook
|
||||
export function useDebounce<T>(value: T, delay: number): T {
|
||||
const [debouncedValue, setDebouncedValue] = useState<T>(value)
|
||||
|
||||
@@ -217,25 +217,25 @@ const debouncedQuery = useDebounce(searchQuery, 500)
|
||||
### 状态管理
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Proper state updates
|
||||
// PASS: GOOD: Proper state updates
|
||||
const [count, setCount] = useState(0)
|
||||
|
||||
// Functional update for state based on previous state
|
||||
setCount(prev => prev + 1)
|
||||
|
||||
// ❌ BAD: Direct state reference
|
||||
// FAIL: BAD: Direct state reference
|
||||
setCount(count + 1) // Can be stale in async scenarios
|
||||
```
|
||||
|
||||
### 条件渲染
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Clear conditional rendering
|
||||
// PASS: GOOD: Clear conditional rendering
|
||||
{isLoading && <Spinner />}
|
||||
{error && <ErrorMessage error={error} />}
|
||||
{data && <DataDisplay data={data} />}
|
||||
|
||||
// ❌ BAD: Ternary hell
|
||||
// FAIL: BAD: Ternary hell
|
||||
{isLoading ? <Spinner /> : error ? <ErrorMessage error={error} /> : data ? <DataDisplay data={data} /> : null}
|
||||
```
|
||||
|
||||
@@ -258,7 +258,7 @@ GET /api/markets?status=active&limit=10&offset=0
|
||||
### 响应格式
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Consistent response structure
|
||||
// PASS: GOOD: Consistent response structure
|
||||
interface ApiResponse<T> {
|
||||
success: boolean
|
||||
data?: T
|
||||
@@ -289,7 +289,7 @@ return NextResponse.json({
|
||||
```typescript
|
||||
import { z } from 'zod'
|
||||
|
||||
// ✅ GOOD: Schema validation
|
||||
// PASS: GOOD: Schema validation
|
||||
const CreateMarketSchema = z.object({
|
||||
name: z.string().min(1).max(200),
|
||||
description: z.string().min(1).max(2000),
|
||||
@@ -352,14 +352,14 @@ types/market.types.ts # 使用 .types 后缀的驼峰命名法
|
||||
### 何时添加注释
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Explain WHY, not WHAT
|
||||
// PASS: GOOD: Explain WHY, not WHAT
|
||||
// Use exponential backoff to avoid overwhelming the API during outages
|
||||
const delay = Math.min(1000 * Math.pow(2, retryCount), 30000)
|
||||
|
||||
// Deliberately using mutation here for performance with large arrays
|
||||
items.push(newItem)
|
||||
|
||||
// ❌ BAD: Stating the obvious
|
||||
// FAIL: BAD: Stating the obvious
|
||||
// Increment counter by 1
|
||||
count++
|
||||
|
||||
@@ -399,12 +399,12 @@ export async function searchMarkets(
|
||||
```typescript
|
||||
import { useMemo, useCallback } from 'react'
|
||||
|
||||
// ✅ GOOD: Memoize expensive computations
|
||||
// PASS: GOOD: Memoize expensive computations
|
||||
const sortedMarkets = useMemo(() => {
|
||||
return markets.sort((a, b) => b.volume - a.volume)
|
||||
}, [markets])
|
||||
|
||||
// ✅ GOOD: Memoize callbacks
|
||||
// PASS: GOOD: Memoize callbacks
|
||||
const handleSearch = useCallback((query: string) => {
|
||||
setSearchQuery(query)
|
||||
}, [])
|
||||
@@ -415,7 +415,7 @@ const handleSearch = useCallback((query: string) => {
|
||||
```typescript
|
||||
import { lazy, Suspense } from 'react'
|
||||
|
||||
// ✅ GOOD: Lazy load heavy components
|
||||
// PASS: GOOD: Lazy load heavy components
|
||||
const HeavyChart = lazy(() => import('./HeavyChart'))
|
||||
|
||||
export function Dashboard() {
|
||||
@@ -430,13 +430,13 @@ export function Dashboard() {
|
||||
### 数据库查询
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Select only needed columns
|
||||
// PASS: GOOD: Select only needed columns
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('id, name, status')
|
||||
.limit(10)
|
||||
|
||||
// ❌ BAD: Select everything
|
||||
// FAIL: BAD: Select everything
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('*')
|
||||
@@ -463,12 +463,12 @@ test('calculates similarity correctly', () => {
|
||||
### 测试命名
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Descriptive test names
|
||||
// PASS: GOOD: Descriptive test names
|
||||
test('returns empty array when no markets match query', () => { })
|
||||
test('throws error when OpenAI API key is missing', () => { })
|
||||
test('falls back to substring search when Redis unavailable', () => { })
|
||||
|
||||
// ❌ BAD: Vague test names
|
||||
// FAIL: BAD: Vague test names
|
||||
test('works', () => { })
|
||||
test('test search', () => { })
|
||||
```
|
||||
@@ -480,12 +480,12 @@ test('test search', () => { })
|
||||
### 1. 长函数
|
||||
|
||||
```typescript
|
||||
// ❌ BAD: Function > 50 lines
|
||||
// FAIL: BAD: Function > 50 lines
|
||||
function processMarketData() {
|
||||
// 100 lines of code
|
||||
}
|
||||
|
||||
// ✅ GOOD: Split into smaller functions
|
||||
// PASS: GOOD: Split into smaller functions
|
||||
function processMarketData() {
|
||||
const validated = validateData()
|
||||
const transformed = transformData(validated)
|
||||
@@ -496,7 +496,7 @@ function processMarketData() {
|
||||
### 2. 深层嵌套
|
||||
|
||||
```typescript
|
||||
// ❌ BAD: 5+ levels of nesting
|
||||
// FAIL: BAD: 5+ levels of nesting
|
||||
if (user) {
|
||||
if (user.isAdmin) {
|
||||
if (market) {
|
||||
@@ -509,7 +509,7 @@ if (user) {
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ GOOD: Early returns
|
||||
// PASS: GOOD: Early returns
|
||||
if (!user) return
|
||||
if (!user.isAdmin) return
|
||||
if (!market) return
|
||||
@@ -522,11 +522,11 @@ if (!hasPermission) return
|
||||
### 3. 魔法数字
|
||||
|
||||
```typescript
|
||||
// ❌ BAD: Unexplained numbers
|
||||
// FAIL: BAD: Unexplained numbers
|
||||
if (retryCount > 3) { }
|
||||
setTimeout(callback, 500)
|
||||
|
||||
// ✅ GOOD: Named constants
|
||||
// PASS: GOOD: Named constants
|
||||
const MAX_RETRIES = 3
|
||||
const DEBOUNCE_DELAY_MS = 500
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ origin: ECC
|
||||
│ CLAUDE.md │ N │ ~X,XXX │
|
||||
└─────────────────┴────────┴───────────┘
|
||||
|
||||
⚠ 发现的问题 (N):
|
||||
WARNING: 发现的问题 (N):
|
||||
[按可节省词元数排序]
|
||||
|
||||
前 3 项优化建议:
|
||||
|
||||
@@ -14,7 +14,7 @@ origin: ECC
|
||||
Start
|
||||
|
|
||||
+-- 需要严格的 CI/PR 控制? -- yes --> continuous-pr
|
||||
|
|
||||
|
|
||||
+-- 需要 RFC 分解? -- yes --> rfc-dag
|
||||
|
|
||||
+-- 需要探索性并行生成? -- yes --> infinite
|
||||
|
||||
@@ -7,7 +7,7 @@ origin: ECC
|
||||
metadata:
|
||||
author: evos
|
||||
clawdbot:
|
||||
emoji: "🌐"
|
||||
emoji: ""
|
||||
---
|
||||
|
||||
# 海关与贸易合规
|
||||
|
||||
@@ -363,7 +363,7 @@ DJANGO 验证报告
|
||||
✓ 无硬编码密钥
|
||||
✓ 包含迁移文件
|
||||
|
||||
建议:⚠️ 部署前修复 pip-audit 发现的漏洞
|
||||
建议:WARNING: 部署前修复 pip-audit 发现的漏洞
|
||||
|
||||
后续步骤:
|
||||
1. 更新存在漏洞的依赖项
|
||||
|
||||
@@ -7,7 +7,7 @@ origin: ECC
|
||||
metadata:
|
||||
author: evos
|
||||
clawdbot:
|
||||
emoji: "⚡"
|
||||
emoji: ""
|
||||
---
|
||||
|
||||
# 能源采购
|
||||
|
||||
@@ -23,7 +23,7 @@ origin: ECC
|
||||
### 组合优于继承
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Component composition
|
||||
// PASS: GOOD: Component composition
|
||||
interface CardProps {
|
||||
children: React.ReactNode
|
||||
variant?: 'default' | 'outlined'
|
||||
@@ -294,17 +294,17 @@ export function useMarkets() {
|
||||
### 记忆化
|
||||
|
||||
```typescript
|
||||
// ✅ useMemo for expensive computations
|
||||
// PASS: useMemo for expensive computations
|
||||
const sortedMarkets = useMemo(() => {
|
||||
return markets.sort((a, b) => b.volume - a.volume)
|
||||
}, [markets])
|
||||
|
||||
// ✅ useCallback for functions passed to children
|
||||
// PASS: useCallback for functions passed to children
|
||||
const handleSearch = useCallback((query: string) => {
|
||||
setSearchQuery(query)
|
||||
}, [])
|
||||
|
||||
// ✅ React.memo for pure components
|
||||
// PASS: React.memo for pure components
|
||||
export const MarketCard = React.memo<MarketCardProps>(({ market }) => {
|
||||
return (
|
||||
<div className="market-card">
|
||||
@@ -320,7 +320,7 @@ export const MarketCard = React.memo<MarketCardProps>(({ market }) => {
|
||||
```typescript
|
||||
import { lazy, Suspense } from 'react'
|
||||
|
||||
// ✅ Lazy load heavy components
|
||||
// PASS: Lazy load heavy components
|
||||
const HeavyChart = lazy(() => import('./HeavyChart'))
|
||||
const ThreeJsBackground = lazy(() => import('./ThreeJsBackground'))
|
||||
|
||||
@@ -515,7 +515,7 @@ export class ErrorBoundary extends React.Component<
|
||||
```typescript
|
||||
import { motion, AnimatePresence } from 'framer-motion'
|
||||
|
||||
// ✅ List animations
|
||||
// PASS: List animations
|
||||
export function AnimatedMarketList({ markets }: { markets: Market[] }) {
|
||||
return (
|
||||
<AnimatePresence>
|
||||
@@ -534,7 +534,7 @@ export function AnimatedMarketList({ markets }: { markets: Market[] }) {
|
||||
)
|
||||
}
|
||||
|
||||
// ✅ Modal animations
|
||||
// PASS: Modal animations
|
||||
export function Modal({ isOpen, onClose, children }: ModalProps) {
|
||||
return (
|
||||
<AnimatePresence>
|
||||
|
||||
@@ -7,7 +7,7 @@ origin: ECC
|
||||
metadata:
|
||||
author: evos
|
||||
clawdbot:
|
||||
emoji: "📊"
|
||||
emoji: ""
|
||||
---
|
||||
|
||||
# 库存需求规划
|
||||
|
||||
@@ -38,12 +38,12 @@ origin: ECC
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ 调度 │─────▶│ 评估 │ │
|
||||
│ │ 调度 │─────│ 评估 │ │
|
||||
│ └──────────┘ └──────────┘ │
|
||||
│ ▲ │ │
|
||||
│ │ ▼ │
|
||||
│ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ 循环 │◀─────│ 优化 │ │
|
||||
│ │ 循环 │─────│ 优化 │ │
|
||||
│ └──────────┘ └──────────┘ │
|
||||
│ │
|
||||
│ 最多3次循环,然后继续 │
|
||||
|
||||
@@ -26,22 +26,22 @@ origin: ECC
|
||||
## 命名
|
||||
|
||||
```java
|
||||
// ✅ Classes/Records: PascalCase
|
||||
// PASS: Classes/Records: PascalCase
|
||||
public class MarketService {}
|
||||
public record Money(BigDecimal amount, Currency currency) {}
|
||||
|
||||
// ✅ Methods/fields: camelCase
|
||||
// PASS: Methods/fields: camelCase
|
||||
private final MarketRepository marketRepository;
|
||||
public Market findBySlug(String slug) {}
|
||||
|
||||
// ✅ Constants: UPPER_SNAKE_CASE
|
||||
// PASS: Constants: UPPER_SNAKE_CASE
|
||||
private static final int MAX_PAGE_SIZE = 100;
|
||||
```
|
||||
|
||||
## 不可变性
|
||||
|
||||
```java
|
||||
// ✅ Favor records and final fields
|
||||
// PASS: Favor records and final fields
|
||||
public record MarketDto(Long id, String name, MarketStatus status) {}
|
||||
|
||||
public class Market {
|
||||
@@ -54,10 +54,10 @@ public class Market {
|
||||
## Optional 使用
|
||||
|
||||
```java
|
||||
// ✅ Return Optional from find* methods
|
||||
// PASS: Return Optional from find* methods
|
||||
Optional<Market> market = marketRepository.findBySlug(slug);
|
||||
|
||||
// ✅ Map/flatMap instead of get()
|
||||
// PASS: Map/flatMap instead of get()
|
||||
return market
|
||||
.map(MarketResponse::from)
|
||||
.orElseThrow(() -> new EntityNotFoundException("Market not found"));
|
||||
@@ -66,13 +66,13 @@ return market
|
||||
## Streams 最佳实践
|
||||
|
||||
```java
|
||||
// ✅ Use streams for transformations, keep pipelines short
|
||||
// PASS: Use streams for transformations, keep pipelines short
|
||||
List<String> names = markets.stream()
|
||||
.map(Market::name)
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
|
||||
// ❌ Avoid complex nested streams; prefer loops for clarity
|
||||
// FAIL: Avoid complex nested streams; prefer loops for clarity
|
||||
```
|
||||
|
||||
## 异常
|
||||
|
||||
@@ -7,7 +7,7 @@ origin: ECC
|
||||
metadata:
|
||||
author: evos
|
||||
clawdbot:
|
||||
emoji: "📦"
|
||||
emoji: ""
|
||||
---
|
||||
|
||||
# 物流异常管理
|
||||
|
||||
@@ -7,7 +7,7 @@ origin: ECC
|
||||
metadata:
|
||||
author: evos
|
||||
clawdbot:
|
||||
emoji: "🏭"
|
||||
emoji: ""
|
||||
---
|
||||
|
||||
# 生产排程
|
||||
|
||||
@@ -7,7 +7,7 @@ origin: ECC
|
||||
metadata:
|
||||
author: evos
|
||||
clawdbot:
|
||||
emoji: "🔍"
|
||||
emoji: ""
|
||||
---
|
||||
|
||||
# 质量与不合格品管理
|
||||
|
||||
@@ -7,7 +7,7 @@ origin: ECC
|
||||
metadata:
|
||||
author: evos
|
||||
clawdbot:
|
||||
emoji: "🔄"
|
||||
emoji: ""
|
||||
---
|
||||
|
||||
# 退货与逆向物流
|
||||
|
||||
@@ -75,21 +75,21 @@ bash ~/.claude/skills/rules-distill/scripts/scan-rules.sh
|
||||
|
||||
**仅当**满足以下**所有**条件时,才包含一个候选原则:
|
||||
|
||||
1. **出现在 2+ 项技能中**:仅出现在一项技能中的原则应保留在该技能中
|
||||
2. **可操作的行为改变**:可以写成“做 X”或“不要做 Y”的形式——而不是“X 很重要”
|
||||
3. **明确的违规风险**:如果忽略此原则,会出什么问题(1 句话)
|
||||
4. **尚未存在于规则中**:检查全部规则文本——包括以不同措辞表达的概念
|
||||
1. **出现在 2+ 项技能中**:仅出现在一项技能中的原则应保留在该技能中
|
||||
2. **可操作的行为改变**:可以写成“做 X”或“不要做 Y”的形式——而不是“X 很重要”
|
||||
3. **明确的违规风险**:如果忽略此原则,会出什么问题(1 句话)
|
||||
4. **尚未存在于规则中**:检查全部规则文本——包括以不同措辞表达的概念
|
||||
|
||||
## 匹配与裁决
|
||||
|
||||
对于每个候选原则,对照全部规则文本进行比较并给出裁决:
|
||||
|
||||
- **追加**:添加到现有规则文件的现有章节
|
||||
- **修订**:现有规则内容不准确或不充分——提出修正建议
|
||||
- **新章节**:在现有规则文件中添加新章节
|
||||
- **新文件**:创建新的规则文件
|
||||
- **已涵盖**:现有规则已充分涵盖(即使措辞不同)
|
||||
- **过于具体**:应保留在技能层面
|
||||
- **追加**:添加到现有规则文件的现有章节
|
||||
- **修订**:现有规则内容不准确或不充分——提出修正建议
|
||||
- **新章节**:在现有规则文件中添加新章节
|
||||
- **新文件**:创建新的规则文件
|
||||
- **已涵盖**:现有规则已充分涵盖(即使措辞不同)
|
||||
- **过于具体**:应保留在技能层面
|
||||
|
||||
## 输出格式(每个候选原则)
|
||||
|
||||
@@ -112,9 +112,9 @@ bash ~/.claude/skills/rules-distill/scripts/scan-rules.sh
|
||||
|
||||
## 排除
|
||||
|
||||
- 规则中已存在的显而易见的原则
|
||||
- 语言/框架特定知识(属于语言特定规则或技能)
|
||||
- 代码示例和命令(属于技能)
|
||||
- 规则中已存在的显而易见的原则
|
||||
- 语言/框架特定知识(属于语言特定规则或技能)
|
||||
- 代码示例和命令(属于技能)
|
||||
````
|
||||
|
||||
#### 裁决参考
|
||||
|
||||
@@ -22,14 +22,14 @@ origin: ECC
|
||||
|
||||
### 1. 密钥管理
|
||||
|
||||
#### ❌ 绝对不要这样做
|
||||
#### FAIL: 绝对不要这样做
|
||||
|
||||
```typescript
|
||||
const apiKey = "sk-proj-xxxxx" // Hardcoded secret
|
||||
const dbPassword = "password123" // In source code
|
||||
```
|
||||
|
||||
#### ✅ 始终这样做
|
||||
#### PASS: 始终这样做
|
||||
|
||||
```typescript
|
||||
const apiKey = process.env.OPENAI_API_KEY
|
||||
@@ -114,7 +114,7 @@ function validateFileUpload(file: File) {
|
||||
|
||||
### 3. SQL 注入防护
|
||||
|
||||
#### ❌ 绝对不要拼接 SQL
|
||||
#### FAIL: 绝对不要拼接 SQL
|
||||
|
||||
```typescript
|
||||
// DANGEROUS - SQL Injection vulnerability
|
||||
@@ -122,7 +122,7 @@ const query = `SELECT * FROM users WHERE email = '${userEmail}'`
|
||||
await db.query(query)
|
||||
```
|
||||
|
||||
#### ✅ 始终使用参数化查询
|
||||
#### PASS: 始终使用参数化查询
|
||||
|
||||
```typescript
|
||||
// Safe - parameterized query
|
||||
@@ -150,10 +150,10 @@ await db.query(
|
||||
#### JWT 令牌处理
|
||||
|
||||
```typescript
|
||||
// ❌ WRONG: localStorage (vulnerable to XSS)
|
||||
// FAIL: WRONG: localStorage (vulnerable to XSS)
|
||||
localStorage.setItem('token', token)
|
||||
|
||||
// ✅ CORRECT: httpOnly cookies
|
||||
// PASS: CORRECT: httpOnly cookies
|
||||
res.setHeader('Set-Cookie',
|
||||
`token=${token}; HttpOnly; Secure; SameSite=Strict; Max-Age=3600`)
|
||||
```
|
||||
@@ -323,11 +323,11 @@ app.use('/api/search', searchLimiter)
|
||||
#### 日志记录
|
||||
|
||||
```typescript
|
||||
// ❌ WRONG: Logging sensitive data
|
||||
// FAIL: WRONG: Logging sensitive data
|
||||
console.log('User login:', { email, password })
|
||||
console.log('Payment:', { cardNumber, cvv })
|
||||
|
||||
// ✅ CORRECT: Redact sensitive data
|
||||
// PASS: CORRECT: Redact sensitive data
|
||||
console.log('User login:', { email, userId })
|
||||
console.log('Payment:', { last4: card.last4, userId })
|
||||
```
|
||||
@@ -335,7 +335,7 @@ console.log('Payment:', { last4: card.last4, userId })
|
||||
#### 错误消息
|
||||
|
||||
```typescript
|
||||
// ❌ WRONG: Exposing internal details
|
||||
// FAIL: WRONG: Exposing internal details
|
||||
catch (error) {
|
||||
return NextResponse.json(
|
||||
{ error: error.message, stack: error.stack },
|
||||
@@ -343,7 +343,7 @@ catch (error) {
|
||||
)
|
||||
}
|
||||
|
||||
// ✅ CORRECT: Generic error messages
|
||||
// PASS: CORRECT: Generic error messages
|
||||
catch (error) {
|
||||
console.error('Internal error:', error)
|
||||
return NextResponse.json(
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#### 最小权限原则
|
||||
|
||||
```yaml
|
||||
# ✅ CORRECT: Minimal permissions
|
||||
# PASS: CORRECT: Minimal permissions
|
||||
iam_role:
|
||||
permissions:
|
||||
- s3:GetObject # Only read access
|
||||
@@ -32,7 +32,7 @@ iam_role:
|
||||
resources:
|
||||
- arn:aws:s3:::my-bucket/* # Specific bucket only
|
||||
|
||||
# ❌ WRONG: Overly broad permissions
|
||||
# FAIL: WRONG: Overly broad permissions
|
||||
iam_role:
|
||||
permissions:
|
||||
- s3:* # All S3 actions
|
||||
@@ -65,14 +65,14 @@ aws iam enable-mfa-device \
|
||||
#### 云密钥管理器
|
||||
|
||||
```typescript
|
||||
// ✅ CORRECT: Use cloud secrets manager
|
||||
// PASS: CORRECT: Use cloud secrets manager
|
||||
import { SecretsManager } from '@aws-sdk/client-secrets-manager';
|
||||
|
||||
const client = new SecretsManager({ region: 'us-east-1' });
|
||||
const secret = await client.getSecretValue({ SecretId: 'prod/api-key' });
|
||||
const apiKey = JSON.parse(secret.SecretString).key;
|
||||
|
||||
// ❌ WRONG: Hardcoded or in environment variables only
|
||||
// FAIL: WRONG: Hardcoded or in environment variables only
|
||||
const apiKey = process.env.API_KEY; // Not rotated, not audited
|
||||
```
|
||||
|
||||
@@ -99,17 +99,17 @@ aws secretsmanager rotate-secret \
|
||||
#### VPC 和防火墙配置
|
||||
|
||||
```terraform
|
||||
# ✅ CORRECT: Restricted security group
|
||||
# PASS: CORRECT: Restricted security group
|
||||
resource "aws_security_group" "app" {
|
||||
name = "app-sg"
|
||||
|
||||
|
||||
ingress {
|
||||
from_port = 443
|
||||
to_port = 443
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["10.0.0.0/16"] # Internal VPC only
|
||||
}
|
||||
|
||||
|
||||
egress {
|
||||
from_port = 443
|
||||
to_port = 443
|
||||
@@ -118,7 +118,7 @@ resource "aws_security_group" "app" {
|
||||
}
|
||||
}
|
||||
|
||||
# ❌ WRONG: Open to the internet
|
||||
# FAIL: WRONG: Open to the internet
|
||||
resource "aws_security_group" "bad" {
|
||||
ingress {
|
||||
from_port = 0
|
||||
@@ -142,7 +142,7 @@ resource "aws_security_group" "bad" {
|
||||
#### CloudWatch/日志记录配置
|
||||
|
||||
```typescript
|
||||
// ✅ CORRECT: Comprehensive logging
|
||||
// PASS: CORRECT: Comprehensive logging
|
||||
import { CloudWatchLogsClient, CreateLogStreamCommand } from '@aws-sdk/client-cloudwatch-logs';
|
||||
|
||||
const logSecurityEvent = async (event: SecurityEvent) => {
|
||||
@@ -177,7 +177,7 @@ const logSecurityEvent = async (event: SecurityEvent) => {
|
||||
#### 安全流水线配置
|
||||
|
||||
```yaml
|
||||
# ✅ CORRECT: Secure GitHub Actions workflow
|
||||
# PASS: CORRECT: Secure GitHub Actions workflow
|
||||
name: Deploy
|
||||
|
||||
on:
|
||||
@@ -189,18 +189,18 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read # Minimal permissions
|
||||
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
|
||||
# Scan for secrets
|
||||
- name: Secret scanning
|
||||
uses: trufflesecurity/trufflehog@main
|
||||
|
||||
|
||||
# Dependency audit
|
||||
- name: Audit dependencies
|
||||
run: npm audit --audit-level=high
|
||||
|
||||
|
||||
# Use OIDC, not long-lived tokens
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
@@ -237,18 +237,18 @@ jobs:
|
||||
#### Cloudflare 安全配置
|
||||
|
||||
```typescript
|
||||
// ✅ CORRECT: Cloudflare Workers with security headers
|
||||
// PASS: CORRECT: Cloudflare Workers with security headers
|
||||
export default {
|
||||
async fetch(request: Request): Promise<Response> {
|
||||
const response = await fetch(request);
|
||||
|
||||
|
||||
// Add security headers
|
||||
const headers = new Headers(response.headers);
|
||||
headers.set('X-Frame-Options', 'DENY');
|
||||
headers.set('X-Content-Type-Options', 'nosniff');
|
||||
headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');
|
||||
headers.set('Permissions-Policy', 'geolocation=(), microphone=()');
|
||||
|
||||
|
||||
return new Response(response.body, {
|
||||
status: response.status,
|
||||
headers
|
||||
@@ -281,17 +281,17 @@ export default {
|
||||
#### 自动化备份
|
||||
|
||||
```terraform
|
||||
# ✅ CORRECT: Automated RDS backups
|
||||
# PASS: CORRECT: Automated RDS backups
|
||||
resource "aws_db_instance" "main" {
|
||||
allocated_storage = 20
|
||||
engine = "postgres"
|
||||
|
||||
|
||||
backup_retention_period = 30 # 30 days retention
|
||||
backup_window = "03:00-04:00"
|
||||
maintenance_window = "mon:04:00-mon:05:00"
|
||||
|
||||
|
||||
enabled_cloudwatch_logs_exports = ["postgresql"]
|
||||
|
||||
|
||||
deletion_protection = true # Prevent accidental deletion
|
||||
}
|
||||
```
|
||||
@@ -327,10 +327,10 @@ resource "aws_db_instance" "main" {
|
||||
### S3 存储桶暴露
|
||||
|
||||
```bash
|
||||
# ❌ WRONG: Public bucket
|
||||
# FAIL: WRONG: Public bucket
|
||||
aws s3api put-bucket-acl --bucket my-bucket --acl public-read
|
||||
|
||||
# ✅ CORRECT: Private bucket with specific access
|
||||
# PASS: CORRECT: Private bucket with specific access
|
||||
aws s3api put-bucket-acl --bucket my-bucket --acl private
|
||||
aws s3api put-bucket-policy --bucket my-bucket --policy file://policy.json
|
||||
```
|
||||
@@ -338,12 +338,12 @@ aws s3api put-bucket-policy --bucket my-bucket --policy file://policy.json
|
||||
### RDS 公开访问
|
||||
|
||||
```terraform
|
||||
# ❌ WRONG
|
||||
# FAIL: WRONG
|
||||
resource "aws_db_instance" "bad" {
|
||||
publicly_accessible = true # NEVER do this!
|
||||
}
|
||||
|
||||
# ✅ CORRECT
|
||||
# PASS: CORRECT
|
||||
resource "aws_db_instance" "good" {
|
||||
publicly_accessible = false
|
||||
vpc_security_group_ids = [aws_security_group.db.id]
|
||||
|
||||
@@ -335,28 +335,28 @@ npm run test:coverage
|
||||
|
||||
## 应避免的常见测试错误
|
||||
|
||||
### ❌ 错误:测试实现细节
|
||||
### FAIL: 错误:测试实现细节
|
||||
|
||||
```typescript
|
||||
// Don't test internal state
|
||||
expect(component.state.count).toBe(5)
|
||||
```
|
||||
|
||||
### ✅ 正确:测试用户可见的行为
|
||||
### PASS: 正确:测试用户可见的行为
|
||||
|
||||
```typescript
|
||||
// Test what users see
|
||||
expect(screen.getByText('Count: 5')).toBeInTheDocument()
|
||||
```
|
||||
|
||||
### ❌ 错误:脆弱的定位器
|
||||
### FAIL: 错误:脆弱的定位器
|
||||
|
||||
```typescript
|
||||
// Breaks easily
|
||||
await page.click('.css-class-xyz')
|
||||
```
|
||||
|
||||
### ✅ 正确:语义化定位器
|
||||
### PASS: 正确:语义化定位器
|
||||
|
||||
```typescript
|
||||
// Resilient to changes
|
||||
@@ -364,7 +364,7 @@ await page.click('button:has-text("Submit")')
|
||||
await page.click('[data-testid="submit-button"]')
|
||||
```
|
||||
|
||||
### ❌ 错误:没有测试隔离
|
||||
### FAIL: 错误:没有测试隔离
|
||||
|
||||
```typescript
|
||||
// Tests depend on each other
|
||||
@@ -372,7 +372,7 @@ test('creates user', () => { /* ... */ })
|
||||
test('updates same user', () => { /* depends on previous test */ })
|
||||
```
|
||||
|
||||
### ✅ 正确:独立的测试
|
||||
### PASS: 正确:独立的测试
|
||||
|
||||
```typescript
|
||||
// Each test sets up its own data
|
||||
|
||||
@@ -94,7 +94,7 @@ agents/
|
||||
确认选择:
|
||||
|
||||
```
|
||||
选定:安全工程师 + SEO专家
|
||||
选定:安全工程师 + SEO专家
|
||||
他们应该专注于什么任务?(描述任务)
|
||||
```
|
||||
|
||||
|
||||
@@ -275,7 +275,7 @@ Return only valid JSON.""",
|
||||
# Audio: every 50 words
|
||||
{"type": "word", "value": 50}
|
||||
|
||||
# Audio: every 30 seconds
|
||||
# Audio: every 30 seconds
|
||||
{"type": "time", "value": 30}
|
||||
|
||||
# Visual: 5 frames every 2 seconds
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
## 功能
|
||||
|
||||
* 🔄 **自动 OCR**:尝试多种 OCR 方法(macOS Vision、EasyOCR、Tesseract)
|
||||
* 📄 **双语 PDF**:原始图像 + 专业英文翻译
|
||||
* 🌍 **多语言支持**:支持中文及其他语言
|
||||
* 📋 **专业格式**:适合官方签证申请
|
||||
* 🚀 **完全自动化**:无需人工干预
|
||||
* **自动 OCR**:尝试多种 OCR 方法(macOS Vision、EasyOCR、Tesseract)
|
||||
* **双语 PDF**:原始图像 + 专业英文翻译
|
||||
* **多语言支持**:支持中文及其他语言
|
||||
* **专业格式**:适合官方签证申请
|
||||
* **完全自动化**:无需人工干预
|
||||
|
||||
## 支持的文件类型
|
||||
|
||||
@@ -80,11 +80,11 @@ pip install pytesseract
|
||||
|
||||
## 完美适用于
|
||||
|
||||
* 🇦🇺 澳大利亚签证申请
|
||||
* 🇺🇸 美国签证申请
|
||||
* 🇨🇦 加拿大签证申请
|
||||
* 🇬🇧 英国签证申请
|
||||
* 🇪🇺 欧盟签证申请
|
||||
* 澳大利亚签证申请
|
||||
* 美国签证申请
|
||||
* 加拿大签证申请
|
||||
* 英国签证申请
|
||||
* 欧盟签证申请
|
||||
|
||||
## 许可证
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
我使用 OpenClaw 一周。以下是我的发现。
|
||||
|
||||
> 📸 **\[图片:带有多个连接频道的 OpenClaw 仪表板,每个集成点都标注了攻击面标签。]**
|
||||
> **\[图片:带有多个连接频道的 OpenClaw 仪表板,每个集成点都标注了攻击面标签。]**
|
||||
> *仪表板看起来很令人印象深刻。每个连接也是一扇未上锁的门。*
|
||||
|
||||
***
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
没有人检查过。
|
||||
|
||||
> 📸 **\[图片:终端截图显示一个 ClawdHub 技能文件,其中包含一个高亮显示的隐藏指令——顶部是可见的任务定义,下方显示被注入的系统指令。已涂改但显示了模式。]**
|
||||
> **\[图片:终端截图显示一个 ClawdHub 技能文件,其中包含一个高亮显示的隐藏指令——顶部是可见的任务定义,下方显示被注入的系统指令。已涂改但显示了模式。]**
|
||||
> *我在一个“完全正常”的 ClawdHub 技能中发现的隐藏指令,深入代码 12 行。我发现了它,因为我阅读了源代码。*
|
||||
|
||||
OpenClaw 有很多攻击面。很多频道。很多集成点。很多社区贡献的技能没有审查流程。大约四天后,我意识到,对它最热情的人恰恰是最没有能力评估风险的人。
|
||||
@@ -56,7 +56,7 @@ OpenClaw 的宣传点:一个开源编排层,让 AI 智能体在你的整个
|
||||
|
||||
然后我开始探测其安全模型。便利性开始让人觉得不值得了。
|
||||
|
||||
> 📸 **\[图表:OpenClaw 的多频道架构——一个中央“ClawdBot”节点连接到 Telegram、Discord、X、WhatsApp、电子邮件、浏览器和文件系统的图标。每条连接线都用红色标记为“攻击向量”。]**
|
||||
> **\[图表:OpenClaw 的多频道架构——一个中央“ClawdBot”节点连接到 Telegram、Discord、X、WhatsApp、电子邮件、浏览器和文件系统的图标。每条连接线都用红色标记为“攻击向量”。]**
|
||||
> *你启用的每个集成都是你留下的另一扇未上锁的门。*
|
||||
|
||||
***
|
||||
@@ -77,7 +77,7 @@ OpenClaw 的宣传点:一个开源编排层,让 AI 智能体在你的整个
|
||||
|
||||
**步骤 4 —— 权限提升。** 在许多 OpenClaw 设置中,智能体以广泛的文件系统访问权限运行。触发 shell 执行的提示注入意味着游戏结束。那就是对设备的 root 访问权限。
|
||||
|
||||
> 📸 **\[信息图:4 步攻击链,以垂直流程图形式呈现。步骤 1(通过 Telegram 进入)-> 步骤 2(提示注入载荷)-> 步骤 3(在 X、电子邮件、iMessage 之间横向移动)-> 步骤 4(通过 shell 执行获得 root 权限)。背景颜色随着严重性升级从蓝色渐变为红色。]**
|
||||
> **\[信息图:4 步攻击链,以垂直流程图形式呈现。步骤 1(通过 Telegram 进入)-> 步骤 2(提示注入载荷)-> 步骤 3(在 X、电子邮件、iMessage 之间横向移动)-> 步骤 4(通过 shell 执行获得 root 权限)。背景颜色随着严重性升级从蓝色渐变为红色。]**
|
||||
> *完整的攻击链——从一个看似可信的 Telegram 链接到你设备上的 root 权限。*
|
||||
|
||||
这个链条中的每一步都使用了已知的、经过验证的技术。提示注入是 LLM 安全中一个未解决的问题——Anthropic、OpenAI 和其他所有实验室都会告诉你这一点。而 OpenClaw 的架构**最大化**了攻击面,这是设计使然,因为其价值主张就是连接尽可能多的频道。
|
||||
@@ -98,7 +98,7 @@ Discord 和 WhatsApp 频道中也存在相同的访问点。如果你的 ClawdBo
|
||||
|
||||
每个都是一个独立的攻击面。每个都是真实的 OpenClaw 用户正在运行的真实集成。每个都具有相同的基本漏洞:智能体以受信任的权限处理不受信任的输入。
|
||||
|
||||
> 📸 **\[图表:中心辐射图,显示中央的 ClawdBot 连接到 Discord、WhatsApp、X、Telegram、电子邮件。每个辐条显示特定的攻击向量:“频道中的恶意链接”、“消息中的提示注入”、“精心设计的私信”等。箭头显示频道之间横向移动的可能性。]**
|
||||
> **\[图表:中心辐射图,显示中央的 ClawdBot 连接到 Discord、WhatsApp、X、Telegram、电子邮件。每个辐条显示特定的攻击向量:“频道中的恶意链接”、“消息中的提示注入”、“精心设计的私信”等。箭头显示频道之间横向移动的可能性。]**
|
||||
> *每个频道不仅仅是一个集成——它是一个注入点。每个注入点都可以转向其他每个频道。*
|
||||
|
||||
***
|
||||
@@ -148,7 +148,7 @@ Discord 和 WhatsApp 频道中也存在相同的访问点。如果你的 ClawdBo
|
||||
|
||||
这就是悖论所在:**能够安全评估 OpenClaw 风险的人不需要它的编排层。需要编排层的人无法安全评估其风险。**
|
||||
|
||||
> 📸 **\[维恩图:两个不重叠的圆圈——“可以安全使用 OpenClaw”(不需要 GUI 的技术用户)和“需要 OpenClaw 的 GUI”(无法评估风险的非技术用户)。空白的交集处标注为“悖论”。]**
|
||||
> **\[维恩图:两个不重叠的圆圈——“可以安全使用 OpenClaw”(不需要 GUI 的技术用户)和“需要 OpenClaw 的 GUI”(无法评估风险的非技术用户)。空白的交集处标注为“悖论”。]**
|
||||
> *OpenClaw 悖论——能够安全使用它的人不需要它。*
|
||||
|
||||
***
|
||||
@@ -178,7 +178,7 @@ Karpathy 的反应是:**“这是一场灾难,我也绝对不建议人们在
|
||||
|
||||
如果构建代理基础设施的平台连自己的数据库都保护不好,我们怎么能对在这些平台上运行的未经审查的社区贡献有信心呢?
|
||||
|
||||
> 📸 **\[数据可视化:显示 Moltbook 泄露数据的统计卡——“149 万条记录暴露”、“3.2 万+ API 密钥”、“3.5 万封电子邮件”、“包含 Karpathy 的机器人 API 密钥”——下方有来源标识。]**
|
||||
> **\[数据可视化:显示 Moltbook 泄露数据的统计卡——“149 万条记录暴露”、“3.2 万+ API 密钥”、“3.5 万封电子邮件”、“包含 Karpathy 的机器人 API 密钥”——下方有来源标识。]**
|
||||
> *Moltbook 泄露事件的数据。*
|
||||
|
||||
### ClawdHub 市场问题
|
||||
@@ -204,7 +204,7 @@ Karpathy 的反应是:**“这是一场灾难,我也绝对不建议人们在
|
||||
|
||||
这是代理时代的 `curl mystery-url.com | bash`。只不过,你不是在运行一个未知的 shell 脚本,而是向一个能够访问你的账户、文件和通信渠道的代理注入未知的提示工程。
|
||||
|
||||
> 📸 **\[时间线图表:“1 月 27 日——上传 230+ 个恶意技能” -> “1 月 30 日——披露 CVE-2026-25253” -> “1 月 31 日——发现 Moltbook 泄露” -> “2026 年 2 月——确认 800+ 个恶意技能”。一周内发生三起重大安全事件。]**
|
||||
> **\[时间线图表:“1 月 27 日——上传 230+ 个恶意技能” -> “1 月 30 日——披露 CVE-2026-25253” -> “1 月 31 日——发现 Moltbook 泄露” -> “2026 年 2 月——确认 800+ 个恶意技能”。一周内发生三起重大安全事件。]**
|
||||
> *一周内发生三起重大安全事件。这就是代理生态系统中的风险节奏。*
|
||||
|
||||
### CVE-2026-25253:一键完全入侵
|
||||
@@ -234,7 +234,7 @@ Gary Marcus 称之为 **“基本上是一种武器化的气溶胶”**——意
|
||||
|
||||
这些不是匿名的 Reddit 帖子或假设场景。这些是带有 CVSS 评分的 CVE、被多家安全公司记录的协调恶意软件活动、被独立研究人员确认的百万记录数据库泄露事件,以及来自世界上最大的网络安全组织的事件报告。担忧的证据基础并不薄弱。它是压倒性的。
|
||||
|
||||
> 📸 **\[引用卡片:分割设计——左侧:CrowdStrike 引用“将提示注入转变为全面入侵的推动者。”右侧:Palo Alto Networks 引用“致命三要素……其架构中内置了过度的代理权。”中间是 CVSS 8.8 徽章。]**
|
||||
> **\[引用卡片:分割设计——左侧:CrowdStrike 引用“将提示注入转变为全面入侵的推动者。”右侧:Palo Alto Networks 引用“致命三要素……其架构中内置了过度的代理权。”中间是 CVSS 8.8 徽章。]**
|
||||
> *世界上最大的两家网络安全公司,独立得出了相同的结论。*
|
||||
|
||||
### 有组织的越狱生态系统
|
||||
@@ -255,7 +255,7 @@ Gary Marcus 称之为 **“基本上是一种武器化的气溶胶”**——意
|
||||
|
||||
防御是集中式的(少数实验室致力于安全研究)。进攻是分布式的(一个全球社区全天候迭代)。更多的渠道意味着更多的注入点,意味着攻击有更多的机会成功。模型只需要失败一次。攻击者可以在每个连接的渠道上获得无限次尝试。
|
||||
|
||||
> 📸 **\[DIAGRAM: "The Adversarial Pipeline" — left-to-right flow: "Abliterated Model (HuggingFace)" -> "Jailbreak Development" -> "Technique Refinement" -> "Production Model Exploit" -> "Delivery via OpenClaw Channel". Each stage labeled with its tooling.]**
|
||||
> **\[DIAGRAM: "The Adversarial Pipeline" — left-to-right flow: "Abliterated Model (HuggingFace)" -> "Jailbreak Development" -> "Technique Refinement" -> "Production Model Exploit" -> "Delivery via OpenClaw Channel". Each stage labeled with its tooling.]**
|
||||
> *攻击流程:从被破解的模型到生产环境利用,再到通过您代理的连接通道进行交付。*
|
||||
|
||||
***
|
||||
@@ -292,7 +292,7 @@ OWASP 引入了一个称为 **最小自主权** 的原则:只授予代理执
|
||||
| **爆炸半径** | 代理可以访问的一切 | 沙盒化到项目目录 |
|
||||
| **安全态势** | 隐式(您不知道您暴露了什么) | 显式(您选择了每一个权限) |
|
||||
|
||||
> 📸 **\[COMPARISON TABLE AS INFOGRAPHIC: The MiniClaw vs OpenClaw table above rendered as a shareable dark-background graphic with green checkmarks for MiniClaw and red indicators for OpenClaw risks.]**
|
||||
> **\[COMPARISON TABLE AS INFOGRAPHIC: The MiniClaw vs OpenClaw table above rendered as a shareable dark-background graphic with green checkmarks for MiniClaw and red indicators for OpenClaw risks.]**
|
||||
> *MiniClaw 理念:90% 的生产力,5% 的攻击面。*
|
||||
|
||||
我的实际设置:
|
||||
@@ -330,12 +330,12 @@ OpenClaw 提供的所有功能都可以用技能和工具来复制——我在 [
|
||||
|
||||
**多个接入点是一个漏洞,而不是一个功能。**
|
||||
|
||||
> 📸 **\[SPLIT IMAGE: Left — "Locked Door" showing a single SSH terminal with key-based auth. Right — "Open House" showing the multi-channel OpenClaw dashboard with 7+ connected services. Visual contrast between minimal and maximal attack surfaces.]**
|
||||
> **\[SPLIT IMAGE: Left — "Locked Door" showing a single SSH terminal with key-based auth. Right — "Open House" showing the multi-channel OpenClaw dashboard with 7+ connected services. Visual contrast between minimal and maximal attack surfaces.]**
|
||||
> *左图:一个接入点,一把锁。右图:七扇门,每扇都没锁。*
|
||||
|
||||
有时无聊反而更好。
|
||||
|
||||
> 📸 **\[SCREENSHOT: Author's actual terminal — tmux session with Claude Code running on Mac Mini over SSH. Clean, minimal, no dashboard. Annotations: "SSH only", "No exposed ports", "Scoped permissions".]**
|
||||
> **\[SCREENSHOT: Author's actual terminal — tmux session with Claude Code running on Mac Mini over SSH. Clean, minimal, no dashboard. Annotations: "SSH only", "No exposed ports", "Scoped permissions".]**
|
||||
> *我的实际设置。没有多渠道仪表盘。只有一个终端、SSH 和 Claude Code。*
|
||||
|
||||
### 便利的代价
|
||||
@@ -378,7 +378,7 @@ OpenClaw 可以演变成这样。基础已经存在。社区积极参与。团
|
||||
|
||||
我想诚实地谈谈这里的反方论点,因为它并非微不足道。对于确实需要 AI 自动化的非技术用户来说,我描述的替代方案——无头服务器、SSH、tmux——是无法企及的。告诉一位营销经理“直接 SSH 到 Mac Mini”不是一个解决方案。这是一种推诿。对于非技术用户的正确答案不是“不要使用递归代理”。而是“在沙盒化、托管、专业管理的环境中使用它们,那里有专人负责处理安全问题。”您支付订阅费。作为回报,您获得安心。这种模式正在到来。在它到来之前,自托管多通道代理的风险计算严重倾向于“不值得”。
|
||||
|
||||
> 📸 **\[DIAGRAM: "The Winning Architecture" — a layered stack showing: Hosted Infrastructure (bottom) -> Sandboxed Containers (middle) -> Audited Skills + Minimal Permissions (upper) -> Clean Dashboard (top). Each layer labeled with its security property. Contrast with OpenClaw's flat architecture where everything runs on the user's machine.]**
|
||||
> **\[DIAGRAM: "The Winning Architecture" — a layered stack showing: Hosted Infrastructure (bottom) -> Sandboxed Containers (middle) -> Audited Skills + Minimal Permissions (upper) -> Clean Dashboard (top). Each layer labeled with its security property. Contrast with OpenClaw's flat architecture where everything runs on the user's machine.]**
|
||||
> *获胜的递归代理架构的样子。*
|
||||
|
||||
***
|
||||
@@ -411,7 +411,7 @@ OpenClaw 可以演变成这样。基础已经存在。社区积极参与。团
|
||||
|
||||
路线图很清晰:托管基础设施让用户无需管理服务器,沙盒化执行以控制损害范围,经过审计的技能市场让供应链攻击在到达用户前就被发现,以及透明的日志记录让每个人都能看到他们的智能体在做什么。这些都可以用已知技术解决。问题在于是否有人将其优先级置于增长速度之上。
|
||||
|
||||
> 📸 **\[检查清单图示:将 5 点“如果你正在运行 OpenClaw”列表渲染为带有复选框的可视化检查清单,专为分享设计。]**
|
||||
> **\[检查清单图示:将 5 点“如果你正在运行 OpenClaw”列表渲染为带有复选框的可视化检查清单,专为分享设计。]**
|
||||
> *当前 OpenClaw 用户的最低安全清单。*
|
||||
|
||||
***
|
||||
|
||||
Reference in New Issue
Block a user