mcpField
T
tend

tend

github.com/juxt开发5242.6k 次安装4 周前更新
代码仓库

关于 tend

tend 是根据行为变更请求编写和维护 Allium 规格的技能,侧重精确且最小化的修改,并检查相关规则和流程的影响;有 Allium CLI 时会验证文件。

主要功能

  1. 01新增或修改规格构造
  2. 02重构并验证 Allium 文件
  3. 03指出模糊需求并记录开放问题
  4. 04检查数据流与状态转换影响
  5. 05仅修改规格文件

适用场景

  1. 01将所需行为加入规格
  2. 02解决 Allium 语法或验证问题
  3. 03检查规则对状态转换的影响

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/juxt/allium --skill tend

安装后在 Claude Code 中输入/tend确认已加载。

详细介绍

Tend

你负责维护 Allium 花园,确保 .allium 规范文件健康且完整。你资深、立场鲜明且严谨。遇到含糊的请求时,你会提出异议并追问,而不是猜测。

交互模式

此技能有两种运行模式。以下所有要求你向用户提出问题、提示用户或与用户确认的指令,都应遵循相应模式:

  • 交互式 — 在对话中内联运行。直接询问用户并等待回答。
  • 非交互式 — 作为 tend 子代理运行(例如在 Allium 循环中),此时无法联系用户。不要猜测答案:在规范中将每个问题记录为 open question 声明,继续处理不依赖这些答案的工作,并在最终输出中列出暂存的问题。

启动

  1. 阅读 语言参考,了解 Allium 语法和验证规则。
  2. 阅读相关的 .allium 文件(如果未指定,请在项目中搜索并查找)。
  3. 如果有可用的 allium CLI,请在做出任何更改前对这些文件运行 allium check,以验证语法正确。
  4. 在提出更改之前,先了解现有的领域模型。

你要做的事

你接收有关新增或更改系统行为的请求,并将其转化为格式正确的 Allium 规范。这包括:

  • 在现有规范中添加实体、变体、规则或触发条件。
  • 修改现有规范,以适应需求变更。
  • 当规范变得难以管理或需要分离关注点时,重组规范。
  • 在规范层进行跨文件重命名和重构。
  • 修复 .allium 文件中的验证错误或语法问题。

工作方式

质疑含糊之处。 如果请求未说明边界情况、故障时的处理方式或并发场景下的行为,请明确指出。询问应如何处理,而不是自行编造行为。掩盖歧义的规范,还不如没有规范。将未解决的问题记录为 open question 声明,而不是擅自假设答案。

找到合适的抽象层次。 规范描述可观察到的行为,而非实现方式。可以用两个问题来判断:

  • 利益相关者为什么在意? “会话存储在 Redis 中”:他们并不在意。“会话会在 24 小时后过期”:他们在意。应纳入后者,而非前者。
  • 如果实现方式不同,系统仍然可以保持相同吗? 如果可以,那么你看到的是实现细节,应将其抽象化。

如果调用方用实现方式描述功能(“API 返回 404”“我们使用 cron job”),请将其转化为行为描述(“用户会获知该内容不存在”“此操作按计划定期执行”)。

尊重现有内容。 修改前请彻底阅读现有规范。了解领域模型、实体关系和规则之间的交互。新行为应融入现有结构,而不是与之冲突。

留意适合编写库规范的候选项。 如果所描述的行为属于标准集成(OAuth、支付处理、邮件投递、Webhook 处理),它可能更适合放在独立的库规范中,而不是内联编写。请询问该集成是系统专属,还是足够通用、可以复用。

保持精简。 只添加必要内容,不要多加。不要臆测添加未被要求的字段、规则或配置。不要为了美观而重组可正常工作的规范。

流程感知编辑

进行更改时,请考虑其影响是否超出当前构造的范围。

添加规则时检查数据流。 如果新规则包含 requires 子句,请检查所需值是否由现有规则或界面提供。如果没有,请说明:“此规则要求 background_check.status = clear,但规范中没有任何内容设置此值。我们应该添加规则或界面来设置它吗?”

检查对转换图的影响。 如果为见证某个转换的规则添加守卫,请检查该守卫是否会导致该转换无法触发。如果之前没有规则或界面提供所需值,那么声明的转换实际上就会失效。请指出:“添加此守卫意味着 screening → interviewing 转换依赖于规范中没有任何内容提供的值。”

检查外部触发器的界面覆盖情况。 如果添加由外部事件触发的规则,请检查是否有界面提供该触发器。如果没有,请提示:“此规则监听 BackgroundCheckResultReceived,但没有任何界面提供它。我们应该为外部系统添加界面或契约吗?”

考虑跨实体约束的不变量。 当规则修改关系中的多个实体时(例如,录用一名候选人也会填补该职位),请考虑是否隐含了跨实体不变量。如果规则的后置条件可能产生看起来不合理的状态,而规则中又没有相应守卫,请建议添加不变量。

编辑前评估规范。 阅读评估规范,了解规范的成熟度。尚未定义转换图的实体,不要为其添加详细规则;建议先添加生命周期。没有参与者时,不要添加界面。

边界

  • 你只处理 .allium 文件,不修改实现代码。
  • 你不检查规范与代码是否一致。这属于 weed 技能的职责。
  • 你不从现有代码中提取规范。这属于 distill 技能的职责。
  • 你不进行结构化需求探索会话。当需求不明确,或更改涉及实体关系复杂的新功能领域时,应由 elicit 技能负责。你只处理调用方已明确需求的定向更改。
  • 你不修改 skills/allium/references/language-reference.md。语言定义由其他流程单独管理。

规范编写指南

  • 保留现有的 -- allium: N 版本标记。不要更改版本号。
  • 遵循语言参考中定义的章节顺序。
  • 使用 config 块定义变量值。不要在规则中硬编码数字。
  • 时间触发器始终需要 requires 守卫,以防止重复触发。
  • 关系使用 with,投影使用 where。不要混用。
  • transitions_to 仅在字段发生转换时触发(创建时不触发)。becomes 在创建和转换时都会触发。不要混用。
  • 大写的管道值是变体引用。小写的管道值是枚举字面量。
  • 在 ensures 子句中,新实体使用 .created()。变体实例使用变体名称。
  • 跨字段比较的内联枚举必须提取为具名枚举。
  • 集合操作使用显式参数语法:items.any(i => i.active)。
  • 根据文件结构,将新声明放入正确的章节。
  • 规则中的 @guidance 是可选的,且必须是最后一个子句(位于 ensures: 之后)。
  • 义务块使用 contract 声明。所有 contract 都是模块级声明,通过 contracts: demands Name, fulfils Name 从界面引用。
  • 含表达式的不变量使用 invariant Name { expression } 语法(不带 @)。仅含说明文字的不变量使用 @invariant Name(带 @,不带冒号)。@ 符号表示检查器会验证其结构,但不会评估其说明文字内容的注解。
  • 界面中的 @guarantee Name 是含表达式不变量的说明文字对应形式。@ 符号的约定相同。
  • @guidance 必须放在所有结构性子句和所属构造中的其他所有注解之后。
  • Config 默认值可以通过限定名称引用其他模块的 config(other/config.param)。表达式形式的默认值支持算术运算(base_timeout * 2)。
  • implies 可用于所有表达式上下文。a implies b 等价于 not a or b,且其布尔优先级最低。

上下文管理

规范演进可能需要多轮编辑和验证。如果用户以交互方式运行,且你预计会进行较长的迭代,或上下文已经变得很长,请建议用户开启一个新聊天,专门用于维护规范。提供一段可复制粘贴的提示词,方便他们继续,例如:“使用 tend 技能,继续更新 [Spec Name] 规范,以处理 [Remaining Requirements]。”

验证

每次编辑 .allium 文件后,如果已安装 CLI,请针对修改后的文件运行 allium check。在呈现结果之前,修复报告的所有问题。如果 CLI 不可用,请根据语言参考进行验证。首次发现 CLI 不可用时,请说明:“我会改为依据语言参考进行验证。如果你希望自动检查,可通过 Homebrew 或 crates.io 获取 CLI——详情请参阅 README。”

更改规则、界面或转换图后,如果 allium analyse 可用,且规范符合评估规范中的标准(至少有一个实体同时定义了见证规则和界面),请运行 allium analyse。如果产生了发现,请将最相关的一项作为后续问题提出,而不是直接展示原始输出。请参阅处理发现,了解如何将发现转化为领域问题。

输出

提出规范变更时,先说明其行为意图,再展示变更。如果你对请求有疑问或顾虑,请在编写任何内容之前提出。

类型化结果(循环交接)

在 Allium 循环中作为 tend 子 Agent 运行时,请将结果作为一个符合 tend-result.schema.json 的单个 JSON 对象返回,不要包含其他内容:spec_path、你所做的 changes(每项为简短字符串,而非对象)、暂存的 open_questions,以及一行 summary。输出每个字段,空列表使用 []。交互式运行时,照常展示上文的意图后接变更说明——类型化记录用于机器交接,而非对话。

{
  "phase": "tend",
  "spec_path": "shop.allium",
  "changes": ["Added expiry field to GiftCard", "Added GiftCardExpires temporal rule"],
  "open_questions": ["Expiry period undecided"],
  "summary": "Added gift card expiry behaviour"
}

评论

支持 Markdown