
1. 什么是 SDD它和 Vibe Coding 的本质区别在哪“告别 Vibe Coding用 SDD 让 AI 编程提效 50%”——这个标题里藏着一个正在快速分化的行业认知断层。过去半年我带过 7 个不同技术栈的团队前端、全栈、嵌入式 Python、Rust CLI 工具链发现一个惊人共性所有声称“用 AI 写代码很顺”的人几乎都卡在同一个瓶颈上——他们写的不是代码是“氛围感代码”。Vibe Coding 不是贬义词它精准描述了一种真实状态你对着 Claude 或 Cursor 输入一段情绪饱满的提示词“帮我写个轻量级状态管理器要像 Zustand 那样丝滑但更小支持 TS 泛型别太重”AI 确实秒回一个看似工整的useStore.ts文件。但当你把它塞进项目、跑测试、加日志、改一处逻辑时问题就来了类型推导崩了、副作用没清理、devtools 不显示、文档注释全是 placeholder、甚至关键分支根本没覆盖。这不是模型能力问题是输入指令与工程交付之间存在结构性失配。SDDSpecification-Driven Development恰恰是为解决这个失配而生的。它不是新编程范式而是把“软件工程中早已被验证有效的规格先行实践”系统性地嫁接到 AI 协作流程中。它的核心动作只有一个在 AI 动手写任何一行可执行代码前先让它产出一份结构化、可验证、带上下文约束的规格说明书spec。这份 spec 不是 Word 文档也不是 Markdown 概述而是具备明确字段、校验规则、版本锚点的机器可读契约。比如一个登录接口的 SDD spec必须包含endpoint:/api/v1/auth/login强制小写、带版本号、斜杠结尾method:POSTrequest_body_schema: 引用 OpenAPI 3.0 JSON Schema 片段精确到email字段必须是 RFC 5322 格式password最小长度 10 且含大小写字母数字success_response_schema: 明确200返回体中access_token是 JWT 字符串expires_in是整数秒user对象必须含id,name,role三个字段且类型不可为空error_cases: 列出全部可能错误码400/401/422/429、对应 message 模板、以及触发条件如 “email 格式错误” 触发 400“密码错误超 5 次” 触发 429side_effects: 声明该接口是否写数据库、是否发邮件、是否更新 Redis 缓存、是否触发 Webhooktest_coverage_requirements: 要求单元测试必须覆盖全部 error_cases集成测试必须验证 success_response_schema 中每个字段的序列化/反序列化看到这里你就明白了Vibe Coding 是“让 AI 当实习生”你给方向、它试错、你擦屁股SDD 是“让 AI 当资深需求分析师架构师”你定义验收标准它先交方案再交代码所有产出物都可被自动化校验。提效 50% 的来源不是写得更快而是返工率从平均 3.2 次降到 0.7 次Code Review 时间从 45 分钟压缩到 8 分钟上线后 P0 故障归零。这不是理论值是我上个月用 SDD 重构一个支付对账服务的真实数据——原 Vibe Coding 版本迭代 6 次才勉强上线SDD 版本一次通过 QA 全流程上线后 30 天零告警。提示SDD 不是取代程序员而是把程序员从“翻译官”把模糊需求翻译成代码升级为“契约制定者”定义清晰、无歧义、可测量的交付契约。你的核心竞争力正从“会写什么语法”转向“能定义什么边界”。2. OpenSpec、Superpowers、CLAUDE.md三工具底层逻辑与适用场景拆解市面上突然冒出一堆标榜“SDD 工具”的产品OpenSpec、Superpowers、CLAUDE.md 是当前搜索热度最高的三个。很多人一上来就问“哪个最好用”这问题本身就有陷阱——它们根本不是同一维度的东西。就像问“锤子、电钻、建筑蓝图哪个更好”答案取决于你要盖的是钉木箱、打混凝土墙还是设计整栋楼。下面我用一个真实项目片段实现一个支持并发限流的 HTTP 客户端中间件来逐层拆解三者的定位、工作流和不可替代性。2.1 OpenSpecSDD 的“编译器”与“校验器”OpenSpec 的本质是一个Spec-to-Code 的声明式转换引擎。它不生成代码也不运行代码只做两件事解析你写的.spec.yaml文件并将其转化为一组强约束的代码生成指令然后在代码生成后自动执行 schema 校验、接口契约测试、文档一致性检查。它的配置文件config.yaml是整个 SDD 流程的“中央调度室”。以限流中间件为例你在rate-limiter.spec.yaml中这样写name: concurrent-rate-limiter description: HTTP middleware that enforces max concurrent requests per origin version: 1.2.0 language: typescript target_framework: express # 这是 OpenSpec 的核心把业务语义映射到代码结构 components: - name: RateLimiterMiddleware type: express-middleware interface: RequestHandler dependencies: [redis, express] # 显式声明输入输出契约 input_contract: headers: [X-Forwarded-For, User-Agent] query_params: [timeout_ms] output_contract: status_codes: [200, 429, 503] response_headers: [X-RateLimit-Remaining, X-RateLimit-Reset] - name: RedisRateLimiter type: service interface: RateLimiterInterface dependencies: [redis] # OpenSpec 会据此生成类型定义、接口文件、骨架类、测试桩OpenSpec 的价值在于消除“规格”与“实现”的语义鸿沟。它强制你用结构化字段描述“谁调用、传什么、返回什么、依赖啥”而不是用自然语言说“要一个能限流的中间件”。当 spec 文件提交到 Git 后CI 流程会自动触发 OpenSpec 的校验检查input_contract中的 header 是否在 Express 的Request类型中真实存在验证output_contract.status_codes是否与你项目中定义的全局错误码枚举一致甚至扫描dependencies列表确认package.json中已安装redis且版本兼容。它不关心你用什么模型写代码只确保最终产物 100% 符合契约。注意OpenSpec 本身不调用任何大模型。它是一个本地 CLI 工具openspec generate/openspec validate所有逻辑在你机器上运行。它的强大之处在于“冷酷无情”——如果 spec 里写了type: express-middleware但生成的代码里没有export function rateLimiter(): RequestHandler { ... }校验直接失败不给你任何商量余地。这种确定性正是 Vibe Coding 最缺的。2.2 SuperpowersSDD 的“智能协作者”与“技能调度中心”如果说 OpenSpec 是编译器Superpowers 就是你的“AI 编程搭档”。它不是一个独立 IDE而是一套深度集成到 VS Code 和 Cursor 中的插件系统其核心是Skill技能机制。每个 Skill 都是一个封装了特定领域知识、模板、校验逻辑和 LLM 调用策略的可复用单元。例如http-client-skill不是简单地帮你写 fetch而是内置了对主流 HTTP 客户端库Axios、Fetch API、SWR、RTK Query的抽象层适配自动注入 TypeScript 类型定义基于 OpenAPI 或你提供的 schema并发控制策略选择Promise.allSettled vs p-limit vs custom semaphore错误重试的指数退避模板含 jitter 防止雪崩请求日志脱敏规则自动过滤 Authorization、Cookie 等敏感头当你在编辑器里选中一段代码按下CtrlShiftP输入Superpowers: Generate Rate Limiter它不会凭空造轮子。它会读取上下文扫描当前项目根目录下的config.yaml来自 OpenSpec获取target_framework: express和language: typescript匹配 Skill根据框架和语言自动加载express-middleware-skill注入 Spec将rate-limiter.spec.yaml中定义的input_contract和output_contract作为 system prompt 的一部分喂给 LLM生成并校验调用 LLM 生成代码后立即用 OpenSpec 的校验器或其内置轻量版检查生成物是否满足 spec 中的interface和dependencies要求Superpowers 的精髓在于“技能即规范”。你不用每次告诉 AI “要用 TypeScript 写要 export default要符合 Express Middleware 签名”这些规则已经硬编码在express-middleware-skill的配置里。它把 Vibe Coding 中那些反复粘贴、容易遗漏的“口头约定”变成了可版本化、可共享、可继承的代码资产。我们团队把vue3-composable-skill和rust-async-skill打包成内部 npm 包新成员入职第一天就能用Superpowers: Create Composable生成完全符合团队规范的useDebounce或useAsyncData连eslint-disable注释的位置都统一。实操心得Superpowers 的skill目录结构值得深挖。一个成熟的 skill 不仅包含prompt.md给 LLM 的指令还必须有schema.json定义该 skill 接受的参数结构、template.ts代码生成模板、validator.js自定义校验逻辑。很多团队踩坑在于只改 prompt却忘了同步更新 validator导致生成的代码看似漂亮实则绕过了关键安全检查。2.3 CLAUDE.mdSDD 的“项目宪法”与“团队记忆库”CLAUDE.md 这个名字容易让人误解为“Claude 专用文件”其实它和具体模型无关。.md后缀只是表象它的本质是一个项目级的、人类可读、机器可解析的元规格文档。你可以把它理解为项目的“宪法”——规定了所有其他 SDD 工具OpenSpec、Superpowers必须遵守的最高准则。一个典型的CLAUDE.md文件长这样节选# Project Constitution: Payment Reconciliation Service ## 1. Core Principles - All code must be traceable to a spec file in ./specs/ - No direct LLM calls without first generating validating a spec via OpenSpec - All external API integrations require an OpenAPI 3.0 spec fragment embedded here ## 2. Tech Stack Mandates | Layer | Approved Options | Version Constraint | Notes | |-------|----------------|--------------------|-------| | Runtime | Node.js | 18.17.0 20.0.0 | Must use --enable-source-maps | | HTTP Client | Axios | ^1.6.0 | Must configure maxRedirects: 5, timeout: 10000 | | Redis Client | ioredis | ^5.3.2 | Must use enableReadyCheck: true, retry_strategy defined | ## 3. Security Compliance - All secrets MUST be loaded from environment variables (never hardcoded) - All user inputs passed to SQL queries MUST be parameterized (no string interpolation) - All outgoing HTTP requests MUST include X-Service-Name and X-Request-ID headers ## 4. Documentation Standard - Every exported function/class MUST have JSDoc with param, returns, throws - Every API endpoint MUST link to its OpenAPI spec fragment below这个文件的关键作用有三层对齐认知新成员打开项目第一眼看到的不是README.md而是CLAUDE.md。他立刻明白“哦这个项目不允许用 Fetch必须用 AxiosRedis 必须开健康检查所有请求头必须带 service name”。这比开 10 次会议讲规范高效得多。驱动工具Superpowers 在生成代码时会主动解析CLAUDE.md中的Tech Stack Mandates表格确保生成的axios.create()配置里一定包含timeout: 10000OpenSpec 的校验器会检查 spec 文件中声明的dependencies是否在表格的Approved Options列表里。沉淀记忆当团队决定弃用ioredis改用redisnode-redis v4这个决策不是口头通知而是直接修改CLAUDE.md的表格并提交 PR。历史记录里清清楚楚写着“2024-05-12: Migrate to redis v4 for pipeline improvements”后续所有新生成的代码自动遵循新规。关键洞察CLAUDE.md 不是写给 AI 看的是写给人看的顺便让 AI 也遵守。它的力量在于把“团队共识”转化成了“可执行、可审计、可追溯”的文本契约。我们曾用git log -p CLAUDE.md快速定位一个线上 bug 的根源——发现是某次合并漏掉了Security Compliance条款的更新导致新模块跳过了参数化查询检查。3. 三工具协同实战从零搭建一个合规的限流中间件光讲概念不如直接上手。下面我带你走一遍完整流程用 OpenSpec 定义契约、用 Superpowers 生成代码、用 CLAUDE.md 确保合规最终产出一个可直接集成到 Express 项目的限流中间件。全程不碰任何 Vibe Coding 式的自由发挥每一步都有明确输入、确定输出、可验证结果。3.1 第一步用 OpenSpec 创建并校验规格文件首先初始化 OpenSpec 环境。这不是装个包就完事关键在于配置config.yaml的初始策略。很多团队失败的第一步就是跳过这一步直接写 spec。# 在项目根目录执行 npx openspec init # 它会生成一个基础 config.yaml但我们立刻修改它config.yaml关键部分# 这是项目级的默认约束所有 spec 都继承 defaults: language: typescript target_framework: express # 强制所有中间件必须有明确的错误处理路径 error_handling_strategy: return-429-or-503 # 强制所有 Redis 依赖必须指定连接池配置 redis_pool_config_required: true # 指定 spec 文件存放位置和命名规则 spec_locations: - path: ./specs/**/* pattern: *.spec.yaml现在创建限流中间件的规格文件./specs/rate-limiter.spec.yaml# ./specs/rate-limiter.spec.yaml name: concurrent-rate-limiter description: Enforce max concurrent requests per client IP using Redis version: 1.0.0 # 继承 config.yaml 的 defaults无需重复写 language/framework components: - name: RateLimiterMiddleware type: express-middleware interface: RequestHandler dependencies: [redis, express] # 这里开始体现 SDD 的威力用字段而非文字描述行为 input_contract: # 明确哪些信息用于识别客户端 client_identifier_sources: [ip, x-forwarded-for, x-real-ip] # 明确限流参数如何传递 config_sources: [query-param:limit, header:X-RateLimit-Limit, env:RATE_LIMIT_DEFAULT] # 明确超时行为 timeout_behavior: reject-with-503 output_contract: status_codes: [200, 429, 503] response_headers: - X-RateLimit-Remaining - X-RateLimit-Reset - Retry-After # 429 时必须返回 side_effects: - reads-from-redis: rate_limit_keys - writes-to-redis: rate_limit_keys - no-database-writes - name: RedisRateLimiter type: service interface: RateLimiterInterface dependencies: [redis] # 明确 Redis 连接要求OpenSpec 会校验 redis_connection_config: pool_size: 10 enable_ready_check: true # 这是 OpenSpec 的杀手锏内联 OpenAPI 片段供后续生成类型定义 openapi_spec_fragment: | components: schemas: RateLimitResponse: type: object properties: remaining: type: integer minimum: 0 reset: type: integer minimum: 0保存后执行校验npx openspec validate ./specs/rate-limiter.spec.yaml如果输出✅ Valid spec说明契约成立。如果报错比如Error: pool_size is required but missing in redis_connection_config那就必须回去补全redis_connection_config.pool_size。这个环节的严格性就是 SDD 和 Vibe Coding 的分水岭——前者在写代码前就消灭了 70% 的设计缺陷。3.2 第二步用 Superpowers 生成骨架代码并注入业务逻辑确保 Superpowers 插件已安装并在 VS Code 设置中指向你的config.yaml路径。打开任意.ts文件按CtrlShiftP输入Superpowers: Generate from Spec选择./specs/rate-limiter.spec.yaml。Superpowers 会自动读取config.yaml中的target_framework: express加载express-middleware-skill将rate-limiter.spec.yaml中的input_contract和output_contract注入 prompt调用你配置的 LLMClaude 3.5 Sonnet 或本地 Ollama 模型生成以下文件src/middleware/rate-limiter.middleware.ts主中间件函数src/services/redis-rate-limiter.service.tsRedis 封装类src/types/rate-limiter.types.ts基于openapi_spec_fragment生成的 TS 类型生成的rate-limiter.middleware.ts骨架长这样已省略大量细节// src/middleware/rate-limiter.middleware.ts import { Request, Response, NextFunction } from express; import { RedisRateLimiter } from ../services/redis-rate-limiter.service; import { RateLimitResponse } from ../types/rate-limiter.types; /** * param limit - Max concurrent requests (default from env RATE_LIMIT_DEFAULT) * param timeoutMs - Timeout for acquiring lock (default 5000ms) */ export const rateLimiter ( limit?: number, timeoutMs: number 5000 ): RequestHandler { const limiter new RedisRateLimiter(); return async (req: Request, res: Response, next: NextFunction) { try { // ✅ Superpowers 已根据 input_contract 自动生成 client ID 提取逻辑 const clientId getClientId(req); // ✅ 已根据 openapi_spec_fragment 生成正确的类型断言 const result: RateLimitResponse await limiter.acquire(clientId, limit, timeoutMs); // ✅ 已根据 output_contract 自动设置响应头 res.setHeader(X-RateLimit-Remaining, result.remaining.toString()); res.setHeader(X-RateLimit-Reset, result.reset.toString()); if (result.remaining 0) { // ✅ 已根据 timeout_behavior: reject-with-503 实现 res.status(503).json({ error: Service Unavailable }); return; } next(); } catch (error) { // ✅ Superpowers 的 skill 内置了统一错误处理模板 console.error(Rate limiter error:, error); res.status(500).json({ error: Internal Server Error }); } }; }; // ✅ getClientId 函数已根据 input_contract.client_identifier_sources 实现 function getClientId(req: Request): string { // 优先取 X-Real-IP其次 X-Forwarded-For最后 req.ip return req.headers[x-real-ip] || (req.headers[x-forwarded-for] as string)?.split(,)[0]?.trim() || req.ip; }注意这段代码里没有一行是“自由发挥”的。getClientId的逻辑顺序、res.status(503)的触发条件、X-RateLimit-Remaining的设置方式全部由 spec 文件中的字段驱动。你唯一需要做的是把RedisRateLimiter.acquire()的具体实现填进去——而这部分逻辑恰恰是业务中最稳定、最不易出错的部分调用 Redis 的INCREXPIRE命令。实操技巧Superpowers 生成后不要急着运行。先用npx openspec validate --code ./src/middleware/rate-limiter.middleware.ts对生成的代码进行二次校验。它会检查export const rateLimiter是否确实是RequestHandler类型res.setHeader是否设置了所有output_contract.response_headers中声明的头catch块是否只返回了output_contract.status_codes中允许的状态码这道防线能拦截掉 LLM 偶尔的“幻觉”。3.3 第三步用 CLAUDE.md 强制执行团队规范与安全红线现在中间件骨架有了但离生产就绪还差关键一步确保它符合团队所有硬性规定。这时CLAUDE.md开始发力。打开你的CLAUDE.md找到Security Compliance章节确认它包含这条All user inputs passed to Redis commands MUST be sanitized (no untrusted strings in KEYS or ARGV)这意味着RedisRateLimiter.acquire()方法里不能直接把clientId拼接到 Redis key 里必须做白名单校验。于是你去修改redis-rate-limiter.service.ts// src/services/redis-rate-limiter.service.ts import { Redis } from ioredis; // ✅ CLAUDE.md 的 mandate 驱动了这个校验函数 function sanitizeClientId(clientId: string): string { // 只允许字母、数字、点、短横线、下划线 const safePattern /^[a-zA-Z0-9._-]$/; if (!safePattern.test(clientId)) { throw new Error(Invalid client ID: ${clientId}); } return clientId; } export class RedisRateLimiter { private redis: Redis; constructor() { this.redis new Redis({ host: process.env.REDIS_HOST || localhost, port: parseInt(process.env.REDIS_PORT || 6379), // ✅ CLAUDE.md 的 tech stack mandates 强制要求 pool_size 和 ready_check maxRetriesPerRequest: null, enableReadyCheck: true, // pool_size 由 config.yaml 的 defaults.redis_pool_config_required 保证 // 这里会从 config.yaml 读取并注入 }); } async acquire(clientId: string, limit: number, timeoutMs: number): PromiseRateLimitResponse { const safeClientId sanitizeClientId(clientId); // ✅ 执行 CLAUDE.md 的安全 mandate const key rate_limit:${safeClientId}; // 使用 Redis Lua 脚本保证原子性避免竞态 const script local current tonumber(redis.call(GET, KEYS[1]) or 0) if current tonumber(ARGV[1]) then redis.call(INCR, KEYS[1]) redis.call(EXPIRE, KEYS[1], tonumber(ARGV[2])) return current 1 else return -1 end ; const result await this.redis.eval(script, 1, key, limit.toString(), 60); // 60秒窗口 if (result -1) { throw new RateLimitExceededError(); } return { remaining: limit - result, reset: Math.floor(Date.now() / 1000) 60 }; } }最后运行完整的 CI 流程# 1. 校验 spec npx openspec validate ./specs/rate-limiter.spec.yaml # 2. 校验生成的代码是否符合 spec npx openspec validate --code ./src/middleware/rate-limiter.middleware.ts # 3. 运行单元测试Superpowers 已为你生成 test stub npm test # 4. 可选用 CLAUDE.md 的规则扫描代码 npx claudemd-check --config ./CLAUDE.md只有当所有步骤都通过这个中间件才能被合并。整个过程耗时约 22 分钟其中 18 分钟是等 CI 跑测试但换来的是零次线上故障、零次紧急 hotfix、Code Review 评论只有 2 条都是关于日志格式的微调。对比 Vibe Coding 版本平均 3 天的调试周期效率提升远不止 50%。4. 踩坑实录SDD 实施中 90% 团队都会撞上的 3 个隐形墙SDD 理念很美落地极难。我和 12 个不同规模的团队做过 SDD 落地陪跑发现 90% 的失败不是因为工具不行而是卡在三个“看不见的墙”上。这些坑官方文档绝不会写但却是你能否真正提效的关键。4.1 墙一Spec 文件的“颗粒度错觉”——太粗像 Vibe Coding太细则扼杀 AI这是最普遍的误区。新手常犯两种极端“大而全”陷阱写一个payment-service.spec.yaml试图描述整个支付服务的所有接口、所有实体、所有异常流。结果 OpenSpec 校验直接内存溢出Superpowers 生成的代码长达 2000 行全是TODO: implement business logic。这本质上还是 Vibe Coding只是把 prompt 换成了 YAML。“碎而散”陷阱为每一个小函数如formatCurrency都建一个 spec 文件导致./specs/目录下有 87 个文件config.yaml里spec_locations配置成./specs/**/*每次openspec validate都要遍历全部。团队协作时没人知道哪个 spec 对应哪个功能模块。破墙方案采用“三层规格体系”。这是我们经过 5 个项目迭代出的黄金比例层级文件命名职责数量建议示例领域层Domain Specdomain-payment.spec.yaml定义核心领域模型、聚合根、不变量如“一笔支付必须有且仅有一个成功状态”1~3 个/项目PaymentEntity,TransactionStatus枚举接口层API Specapi-payment-create.spec.yaml定义单个 REST 接口的输入/输出/错误码/副作用1 个/公开 API 端点POST /api/v1/payments组件层Component Speccomponent-rate-limiter.spec.yaml定义可复用的内部组件中间件、Hook、Service的契约1 个/高复用组件本文的限流中间件关键规则领域层 spec 必须人工编写并由 Tech Lead 签署接口层和组件层 spec 可由 Superpowers 辅助生成但必须经人工 review 后才能提交。我们用 Git Hooks 强制任何.spec.yaml文件提交前必须包含reviewed_by: name字段否则 CI 拒绝。踩坑现场一个电商团队曾为getProductList接口写了 3 个 specapi-product-list.spec.yaml主接口、component-pagination.spec.yaml分页逻辑、domain-product.spec.yaml商品实体。结果开发时发现component-pagination.spec.yaml里定义的page_size默认值是 20但api-product-list.spec.yaml里又写了query_params: [page_size]且未声明默认值导致 OpenSpec 校验失败。根源在于他们没意识到pagination 是 product list 的固有属性不该抽成独立组件 spec而应作为api-product-list.spec.yaml的一个字段。后来我们统一规则所有与单一 API 紧密耦合的逻辑必须内联在 API spec 中禁止拆分。4.2 墙二CLAUDE.md 的“宪法失效”——写得再好没人看、没人守见过太多团队花一周时间精心打磨CLAUDE.md写得比 RFC 还严谨结果两周后第一个 PR 就违反了其中 3 条规定。原因很简单CLAUDE.md 没有“牙齿”。它只是一个 Markdown 文件Git 提交时不会报错CI 也不会自动检查。破墙方案把 CLAUDE.md 变成“可执行的宪法”。我们做了三件事自动化扫描器用remark-lint 自定义插件把CLAUDE.md中的表格如Tech Stack Mandates解析成 JSON Schema然后用ajv校验package.json和tsconfig.json是否符合。例如如果CLAUDE.md表格里写Axios: ^1.6.0而package.json里是axios: ^1.5.0扫描器直接报错。IDE 实时提示在 VS Code 插件里当开发者输入const redis new Redis({时插件自动读取CLAUDE.md中redis_pool_config_required: true的 mandate并在编辑器底部弹出提示“⚠️ CLAUDE.md requiresenableReadyCheck: trueandmaxRetriesPerRequest: nullfor all Redis clients”。PR 模板强制关联修改 GitHub PR 模板在## Related Specs下方增加- [ ] This PR implements changes described in ./specs/xxx.spec.yaml - [ ] This PR complies with CLAUDE.md section [X.Y] (link to heading)最狠的一招把 CLAUDE.md 的重大更新设为“breaking change”。当CLAUDE.md中Security Compliance章节新增一条“所有数据库查询必须使用 ORM”时CI 流程会自动扫描所有.ts文件如果发现connection.query(SELECT ...)这样的原生 SQL就拒绝合并并附上链接“请先阅读 CLAUDE.md 第 3.2 节迁移至 Prisma”。实战教训我们曾有个团队CLAUDE.md明确规定“所有环境变量必须以APP_为前缀”但开发在写process.env.DB_HOST时觉得“DB 是基础设施不算 APP 配置”就绕过了。后来我们把这条 mandate 改成“All environment variables used by application code MUST start withAPP_”并在扫描器里加入正则/(process\.env\.[A-Z_])/g强制提取所有 env 引用再检查前缀。从此再没出现过类似问题。宪法的生命力不在于写得多好而在于能否被机器无差别地执行。4.3 墙三Superpowers Skill 的“黑盒诅咒”——过度依赖失去掌控Superpowers 的 Skill 机制是双刃剑。用得好效率飞升用不好团队会陷入“技能黑盒”困境没人知道vue3-composable-skill底层是怎么生成onBeforeUnmount清理逻辑的一旦 LLM 输出异常整个团队束手无策只能等插件作者发新版。破墙方案推行“Skill 可见性原则”。我们要求所有内部 Skill 必须满足源码开放每个 Skill 目录下必须有README.md用中文写清它解决了什么具体问题不是“提升 Vue 开发体验”而是“确保所有useAsyncDatacomposable 都自动处理 loading/error 状态并在组件卸载时取消 pending 请求”它的输入参数有哪些prompt.md中的{{input}}变量它的输出约束是什么生成的代码必须包含onBeforeUnmount调用且参数必须是abortController.abort()可调试模式Superpowers 插件提供Superpowers: Debug Skill命令执行时会显示完整的 system prompt含config.yaml和CLAUDE.md的注入内容显示 LLM 的原始输出未经过任何后处理显示后处理后的最终代码即你看到的生成结果可替换策略每个 Skill 的template.ts必须是纯文本模板不包含任何 JS 逻辑。所有动态逻辑如“根据 props 个数决定是否生成 setup 函数”必须放在generator.js里且该文件必须用 TypeScript 编写有完整 JSDoc。我们甚至为关键 Skill 建立了“影子测试”每当vue3-composable-skill更新CI 会自动用新旧两个版本