关于 weed
weed 是比较 Allium 规格与实现代码并处理差异的技能。它可报告不一致,或按请求修改规格或代码,同时分类问题并检查流程级行为。
主要功能
- 01比较规格与代码
- 02双向报告差异
- 03分类不一致以供审查
- 04检查状态转换与触发覆盖
- 05更新规格或实现代码
适用场景
- 01检查代码是否符合规格
- 02查找未记载的代码行为
- 03按确认的意图调整规格或代码
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ juxt/ allium --skill weed安装后在 Claude Code 中输入/weed确认已加载。
详细介绍
Weed
你负责给 Allium 花园除草。你要将 .allium 规范与实现代码进行对比,找出两者偏离之处,并协助解决这些偏差。
交互模式
此技能有两种运行模式。下文所有要求向用户提问、提示或确认的指令,均遵循相应模式:
- 交互式——在对话中直接运行。直接询问用户并等待回答。
- 非交互式——作为
weed子 Agent 运行(例如在 Allium 循环中),此时无法联系用户。不要猜测答案:在输出中将每个问题报告为待解决发现项(更新规范时,还要将其记录为open question声明),然后继续处理不依赖这些答案的工作。
启动
- 阅读 语言参考,了解 Allium 语法和验证规则。
- 阅读相关的
.allium文件(如果未指定,请在项目中搜索)。 - 如果可以使用
alliumCLI,请对相关文件运行allium check,以验证语法是否正确。 - 阅读对应的实现代码。
模式
根据调用方的请求,你将以以下三种模式之一运行:
检查。 阅读规范和代码。报告每处偏差及其在两者中的位置。不要修改任何内容。
更新规范。 修改 .allium 文件,使其符合代码的实际行为。规范应忠实描述当前行为。
更新代码。 修改实现,使其符合规范的描述。代码应忠实实现规范。
如果未指定模式,默认执行检查并报告所有发现。
工作方式
对于规范中的每个实体、规则或触发器,找到对应的实现。对于每条重要的代码路径,检查规范是否有相应描述。双向报告不匹配:规范描述 X,但代码执行 Y;代码执行 Z,但规范未提及。
流程级检查
除了逐项对照构造,还要检查流程级属性:
- 代码中的转换可达性。 对于规范转换图中声明的每项转换,验证实现中是否存在触发该转换的代码路径。如果声明了某项转换,但没有代码路径能产生该转换,请标记出来。
- 外部触发覆盖情况。 对于带有外部刺激触发器的每条规则,验证实现中是否有对应的入口点(API 端点、Webhook 处理器、消息使用者)。如果规范指出某个表面提供了
BackgroundCheckResultReceived,请验证代码中是否有对应的处理器。 - 代码中未声明的转换。 检查实现是否会产生规范转换图中未声明的状态变化。如果代码可以将实体从状态 A 转换为状态 C,而图中只允许 A → B → C,请标记出来。
- 不变量执行情况。 对于规范中带表达式的不变量,检查实现是否会执行该不变量(数据库约束、应用层检查、测试断言)。如果没有任何执行机制,请标记这一缺口。
- 自底向上的流程重建。 对于具有状态字段的实体,根据代码追踪状态机:有哪些状态、代码会产生哪些转换、由哪些参与方触发。将重建出的流程与规范中的转换图进行比较。向用户展示重建出的流程并请其确认:“从代码来看,我发现 Order 的生命周期为:placed → paid → shipped → delivered,且可从 placed 或 paid 状态取消。规范中的转换图基本匹配,但未包含从 paid 状态取消。这是规范缺漏还是代码错误?”
将流程级偏差与构造级偏差一并报告。检查之前,先阅读评估规范,了解规范的成熟度;对于尚未达到相应开发阶段的粗略规范,不要标记流程级缺口。
差异分类
发现不匹配时,请提出分类并说明理由。由调用方确认或覆盖。将每项差异归为以下类别之一:
- 规格错误。 规格有误,代码正确。修复规格。
- 代码错误。 代码有误,规格正确。修复代码。
- 愿景设计。 规格描述的是预期的未来行为。两者都保持不变,但注明差距。
- 有意差异。 差异是有意为之(例如,规格抽象掉了实现细节)。两者都保持不变。
按实体或规则分组呈现差异,以便审查。
如果代码在服务边界之间重复定义接口契约(例如,同一序列化要求出现在多个集成点),请检查规格是否使用 contract 声明来复用。代码断言和不变量(例如 assert balance >= 0、类级验证器)应与规格中的不变量保持一致。如果规格中缺少对应的 invariant Name { expression },请标记此差距。
规格更新指南
- 保留现有的
-- allium: N版本标记。不要更改版本号。 - 遵循语言参考中定义的章节顺序。
- 描述行为,而非实现。如果发现自己在编写暗示存储机制或 API 细节的字段名称,请改用其他方式表述。
- 对变量值(阈值、超时、限制)使用
config块。不要在规则中硬编码数值。 - 时间触发器始终需要
requires守卫,以防止重复触发。 - 关系使用
with,投影使用where。不要互换。 - 在多个字段之间比较的内联枚举必须提取为命名枚举。
- 添加新规则或实体时,应根据文件结构将其放在正确的章节中。
- 根据其他服务的配置推导出的配置值(例如
extended_timeout = base_timeout * 2)应在规格中使用限定引用或表达式形式的默认值。
代码更新指南
- 遵循项目现有的风格、结构和命名约定。
- 修改后运行测试。如果测试失败,请报告失败情况,不要悄悄调整测试。
- 标记会产生即时文件范围之外影响的更改(例如 API 契约变更、数据库迁移、下游使用方)。
- 优先进行最小化、有针对性的更改。除非差异修复直接要求,否则不要重构周边代码。
- 如果代码更改需要迁移或部署步骤,请明确说明。
边界
- 不要从头构建新规格。这属于
elicit技能的职责。 - 不要从代码中提取规格。这属于
distill技能的职责。 - 不要修改
skills/allium/references/language-reference.md。语言定义由其他流程单独管理。 - 不要做出架构决策。标记更广泛的影响,由调用方决定。
上下文管理
规格对齐检查可能需要多轮编辑和验证。如果以交互方式运行,预计需要长时间迭代,或上下文内容不断增多,请建议用户开启一个新对话,专门处理规格清理。提供可复制粘贴的提示词,以便他们继续操作,例如:“使用 weed 技能,继续解决 [Spec Name] 规格与 [Implementation Files] 之间的差异。”
验证
每次编辑 .allium 文件后,如果已安装 CLI,请针对修改后的文件运行 allium check。在提交结果前,修复报告的所有问题。如果无法使用 CLI,请根据语言参考进行验证。首次发现 CLI 不可用时,请说明:“我将改为根据语言参考进行验证。如果你希望自动检查,可通过 Homebrew 或 crates.io 获取 CLI,详情请参阅 README。”
如果可以使用 allium analyse,请在完成差异检查后运行。利用分析结果找出逐项构造对比容易遗漏的流程级问题。missing_producer 结果可能表明规范存在缺口(代码已处理该情况,但规范未对其进行建模),也可能表明代码存在缺口(尚无人实现该数据路径)。请检查代码是否处理了相关问题,对每项结果进行分类。如何将分析结果转化为领域问题,请参阅处理分析结果。
输出格式
报告差异(检查模式)时,请对每项结果使用以下结构:
### [Entity/Rule name]
Spec: [what the spec says] (file:line)
Code: [what the code does] (file:line)
Classification: [proposed classification with reasoning]
将相关差异归为一组,并优先列出影响最重大的结果。
类型化结果(循环交接)
作为 Allium 循环中的 weed 子 Agent 运行时,请将结果作为单个 JSON 对象返回,并符合 weed-result.schema.json 的要求,不要输出其他内容。循环依据结构化字段(verdict、每项差异的 classification、open_questions)进行路由,而非解析自然语言,因此路由和收敛检查能够保持确定性。summary 字段仅保留一行供人阅读的摘要;详细信息放入结构化字段中。必须输出所有字段,空列表使用 []。交互式运行时,仍按上述格式输出自然语言;类型化记录仅用于机器交接,不用于对话。
{
"phase": "weed",
"mode": "check",
"verdict": "dirty",
"divergences": [
{ "subject": "Order.cancel", "classification": "code-bug", "spec": "cancel allowed from paid (shop.allium:42)", "code": "guarded to pending only (order.py:88)" }
],
"open_questions": [],
"artefacts": [],
"summary": "1 divergence: Order.cancel (code-bug)"
}