mcpField
A
add-functional-specs

add-functional-specs

github.com/plainlang开发8037 次安装今天更新
代码仓库

关于 add-functional-specs

add-functional-specs 将单条规格编写流程用于按顺序排列的多条规格。每条规格插入前都会经过复杂度和冲突检查,之后可添加一致性测试。

主要功能

  1. 01按依赖顺序起草规格
  2. 02逐条检查复杂度
  3. 03与已有规格批量分析冲突
  4. 04逐条插入规格
  5. 05为每条规格添加测试

适用场景

  1. 01编写多个相关功能的规格
  2. 02批量编写并逐条完成检查
  3. 03添加有序规格及一致性测试

安装

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

$npx skills add https://github.com/plainlang/plain-forge --skill add-functional-specs

安装后在 Claude Code 中输入/add-functional-specs确认已加载。

详细介绍

添加功能规格

先加载规则。 在阅读、编辑或编写任何 .plain 文件之前,调用 load-plain-reference 技能,并阅读它指向的规则文件。仅当本次对话中已运行过 load-plain-reference 时,才可跳过此步骤。

适用场景

  • 用户要求一次性添加多项功能规格(例如“添加这三项规格”“用几条要点描述此功能的规格”)。
  • 更高级别的技能或工作流(forge-plain、add-feature、debug-specs)需要编写一组紧密相关的规格。
  • 任何情况下,若你本来打算在不逐项分析的情况下编写多项功能规格。

如果只需添加一项规格,请改用 add-functional-spec 技能。无论使用哪种技能,都不得手动编辑 ***functional specs*** 部分——每个新条目都必须通过这两种技能之一添加,以确保实际执行复杂度和冲突检查。

工作流

此技能是按顺序逐项应用 add-functional-spec,不得走捷径。批量操作也必须严格逐项执行。

  1. 确定目标 .plain 文件。 如果目标不明确,请询问用户。
  2. 阅读整个文件,了解现有定义、实现要求和所有当前功能规格(包括通过 import / requires 引入的规格)。
  3. 拟定所有准备添加的规格,按应出现的时间顺序排列,并按照 semantic-ids.md 为每项分配自己的 func-id;该 ID 在模块内以及本批次内都必须唯一。将草稿保存在工作列表中,暂不插入任何内容。继续之前,按照 concise-specs.md 对每份草稿进行审阅;在保留所有事实的前提下,将每份内容精简至最短。
  4. 按顺序处理每份草稿规格:
    1. 分析复杂度。 对该规格运行 analyze-if-func-spec-too-complex。如果结论为 TOO COMPLEX,运行 break-down-func-spec,用拆分后的小规格替换工作列表中的条目(保持顺序),然后从第一份拆分后的规格重新执行此步骤。

    2. 检查冲突。 使用以下单一输入集运行一次 analyze-func-specs:

      • 新规格,以及
      • 文件中所有现有功能规格及其 requires 链中的规格,以及
      • 本批次中已插入的所有规格。

      批量分析器会在一次调用中返回所有冲突的规格对——不要循环调用逐对分析器。对于它报告的每一对冲突,运行 resolve-spec-conflict。应用解决方案——可能需要修改新规格、现有规格,或两者——然后针对已修改的规格集重新运行一次 analyze-func-specs,直至结论为 COMPATIBLE。

    3. 追加规格。 将规格以 # <func-id> 标题及其正文的形式,添加到 ***functional specs*** 部分。规格按时间顺序排列;新条目放在末尾(除非有某项较早的现有规格必须排在它之后——这种情况很少见,此时应插入正确位置)。

  5. 再次阅读文件,确认整批规格的位置、顺序和语法均正确。
  6. 编写测试 plain 文件。 如果该模块启用了符合性测试,则针对每项已插入的功能,按顺序调用一次 add-test-scenarios。

顺序很重要:每项新规格只有在通过复杂度和冲突检查后才能插入,因此批次中的后续规格始终会基于已验证的文件进行检查。

规则

add-functional-spec 的所有规则都适用于每项规格。为使此技能内容完整,现再次列出这些规则。

复杂度上限(每项规格)

每项功能规格必须确保最多改动 200 行代码。如果规格规模过大,请使用 break-down-func-spec 将其拆分为多个更小且相互独立的规格。不要在规格文本中加入代码行数估算。

按时间顺序排序

规格会从上到下逐步呈现。渲染器不了解后续规格——上下文中只有此前已呈现的规格。

  • 新规格可以引用此前规格中定义的行为。
  • 新规格不能假设后续规格中的任何内容。
  • 排列这一批规格,使每个规格仅依赖排在它前面的规格。如果两个新规格会相互引用,则依赖其他规格的那个排在后面。
语言无关性

描述行为、概念和领域逻辑,而不是实现结构。避免使用特定语言的类型、泛型语法、框架注解,或其他与特定语言或框架绑定的结构。通用技术术语(空值、JSON 类型、HTTP 状态码)可以使用。特定语言的指导应放在 ***implementation reqs*** 中。

不得冲突(每个规格通过一次批量调用实现全面覆盖)

新规格之间不得相互矛盾,也不得与任何现有功能规格矛盾。规格冲突是代价最高的结果。冲突检查必须覆盖:

  • 每一组(新规格 × 现有规格)配对;以及
  • 批次内每一组(新规格 × 新规格)配对。

通过对每个待插入规格各运行一次 analyze-func-specs 来实现上述覆盖:将新规格、所有现有规格以及本批次中所有已插入的规格作为一个集合传入。批量分析器会在一次调用中列出所有冲突配对——不要逐对调用分析器。如果存在歧义,请添加明确的细节,以消除所有可能的冲突解释。对于批量分析器报告的每一组冲突配对,在继续之前都使用 resolve-spec-conflict 技能进行诊断并修复。

消除歧义(每个规格)

每个功能规格都必须明确无歧义——渲染器只能有一种合理的解读。如果陈述本身不足以完全明确行为,请在其下添加 - 项目或句子。这些细节用于阐明陈述,不会引入独立功能。即使添加了这些细节,规格所暗示的代码量仍必须 ≤ 200 行。

***functional specs***

# send-message
A :User: can send a :Message: to a :Conversation:.
- A :Message: must have non-empty content.
- The :Message: is appended to the end of the :Conversation:.
- All :Participant: members of the :Conversation: can see the new :Message:.
确定性接口

规格必须足够详细,让开发者无需阅读生成的代码就能使用已构建的软件。必须明确规定所有外部接口——REST 端点路径和 HTTP 方法、CLI 命令名称和参数、文件格式、消息架构等。绝不能将接口细节留给渲染器自行决定。

封装

功能必须在规格文本中自包含。requires 模块只会导入功能规格,因此不要依赖实现需求来传达行为——下游模块看不到这些内容。

测试场景

插入完这一批规格后,按顺序对每项已插入的功能调用一次 add-test-scenarios。该工具会为每项功能写入测试纯文本文件(按惯例为 tests/<module>/<func-id>.plain);当模块启用一致性测试时,该文件应至少包含一个一致性测试场景。每个规格都要单独执行此操作,不要将其作为批量处理的一部分。

反模式

  • 不要因为批次“看起来”很小就跳过逐项规范检查。 即使只有两项规范,也需要进行两次复杂度检查,并执行一次包含两项新规范的批量冲突检查。
  • 不要退回到逐对分析冲突。 每插入一项规范,就使用完整的相关集合调用一次 analyze-func-specs,而不是对每一对都调用 analyze-2-func-specs。
  • 不要先完成所有复杂度检查,最后再做所有冲突检查。 按工作流中的说明逐项交替执行;否则,前面的复杂度检查若未通过,就会浪费后续的冲突检查。
  • 不要先插入所有规范,然后再进行分析。 不合格的规范一旦写入文件,就会影响后续的冲突分析。
  • 不要因为要添加的规范“很多”就改为手动编写。 正确做法是增加分析器调用次数,而不是减少。
  • 不要将此技能用于单项规范。 请使用 add-functional-spec;它包含相同的检查,但无需批量处理记录。

验证清单

  • 批次中的每项规范都意味着代码变更不超过 200 行(通过 analyze-if-func-spec-too-complex 验证)
  • 每项新规范都与任何现有规范不冲突(通过批量调用 analyze-func-specs 验证)
  • 批次中的任意两项新规范都不冲突(由相同的批量 analyze-func-specs 调用检查)
  • 批量分析器报告的每一对冲突都在批次完成前通过 resolve-spec-conflict 解决
  • 所有规范均使用与语言无关的表述(不涉及特定语言或框架)
  • 所有外部接口均明确(端点路径、方法、CLI 参数、格式等)
  • 所有引用的 :Concepts: 均在 ***definitions*** 中定义
  • 句子简短、清晰且明确
  • 每项规范均按照 concise-specs.md 精简:不写显而易见的内容,不写理由,不使用无法验证的形容词或模糊措辞,全程使用直白的词语
  • 不与现有规范或批次内的其他规范重复
  • 规范均放置在正确的时间顺序位置
  • 每个 func-id 均遵循 semantic-ids.md,且在模块内和批次内唯一
  • 启用一致性测试时,已为每项插入的功能调用 add-test-scenarios

评论

支持 Markdown