关于 analyze-if-func-spec-too-complex
面向 `.plain` 功能规格编写者的技能,用于判断草稿是否可能超过渲染器的复杂度上限。它结合规格上下文进行分析,并仅返回 `ACCEPTABLE` 或 `TOO COMPLEX`。
主要功能
- 01检查行为与构造数量
- 02评估分支及横切关注点
- 03考量界面与数据转换复杂度
- 04仅返回单词判定结果
适用场景
- 01将草稿加入 `.plain` 文件前进行筛查
- 02结合模块现有内容检查规格复杂度
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ plainlang/ plain-forge --skill analyze-if-func-spec-too-complex安装后在 Claude Code 中输入/analyze-if-func-spec-too-complex确认已加载。
详细介绍
分析功能规范是否过于复杂
先加载规则。 在读取、编辑或编写任何 .plain 文件之前,请先调用 load-plain-reference 技能,并阅读它指向的规则文件。仅当本次对话中已运行 load-plain-reference 时,才可跳过此步骤。
为什么这很重要
渲染器会强制执行严格的复杂度上限:每项功能规范最多只能涉及 200 行代码变更。如果规范超出此限制,渲染器会以“Functional spec too complex!” 拒绝,并且必须拆分该规范。在插入之前发现这一点,可以避免渲染失败。
输入
一份尚未插入文件的功能规范草稿,以及要添加该规范的 .plain 文件的完整上下文——定义、实现要求和现有功能规范。
工作流
- 阅读完整的
.plain文件(以及任何requires/import模块),以了解当前代码库的上下文——已有内容以及新规范基于哪些内容构建。 - 仔细阅读功能规范草稿。
- 使用下方的检查清单进行复杂度分析。
- 只输出判定结果,不得输出其他内容——只能是
ACCEPTABLE或TOO COMPLEX。不要给出理由、LOC 估算或拆分方案。
复杂度分析检查清单
逐项检查每个指标。单个“是”并不自动意味着规范过于复杂,但多个“是”是强烈的警示信号。
0. 首个规范的引导成本
这是一个新根模块中的首个功能规范,且没有通过 requires 提供实现基线吗?如果是,请将创建项目结构、软件包元数据、框架配置、入口点、初始源文件和单元测试基础设施所需的隐含成本计算在内。
首个规范必须比后续规范简单得多。它应提供一个最简、确定且可调用和测试的功能。只有设置而没有可观察结果是不可接受的,但如果同时包含引导工作、持久化、集成、多种接口、分支工作流或横切行为,则强烈表明规范过于复杂。
1. 不同行为的数量
规范是否描述了多个可独立测试的行为?
过于复杂:
***functional specs***
# manage-tasks
A :User: can create, edit, delete, and archive :Task: items, with validation on all fields and confirmation dialogs for destructive actions.
可接受(每项规范只包含一种行为):
***functional specs***
# create-task
A :User: can create :Task:. Only valid :Task: items can be added.
# edit-task
A :User: can edit :Task:.
# delete-task
A :User: can delete :Task:.
# archive-task
A :User: can archive :Task:.
2. 引入或修改的概念数量
规范是否要求引入新的数据结构、UI 组件、API 端点或其他现有构造中不存在的内容?请统计数量。
- 0–1 个新构造 → 通常没问题
- 2–3 个新构造 → 临界情况,需仔细判断
- 4 个或更多新构造 → 几乎肯定过于复杂
3. 分支逻辑和条件
规范是否描述了多个条件路径、模式或特殊情况?
过于复杂:
***functional specs***
# process-order
:Order: processing depends on :OrderType:. Standard orders are validated and stored. Express orders skip validation and are queued for immediate dispatch. Bulk orders are split into sub-orders of 100 items each, validated individually, and processed in parallel with progress tracking.
可接受(拆分不同模式):
***functional specs***
# process-standard-order
A standard :Order: is validated and stored.
# process-express-order
An express :Order: is queued for immediate dispatch without validation.
# split-bulk-order
A bulk :Order: is split into sub-orders of 100 items each.
- Each sub-order is processed individually.
4. 横切关注点
规范是否将核心功能与错误处理、日志记录、重试逻辑、分页或缓存等横切关注点捆绑在一起?
过于复杂:
***functional specs***
# fetch-resources
:Resource: items are fetched from the external API with pagination support, retry on transient errors with exponential backoff, caching for 5 minutes, and logging of all API calls.
可接受(拆分关注点):
***functional specs***
# fetch-resources
:Resource: items are fetched from the external API.
# fetch-resources-paged
:Resource: items are fetched from the external API in pages.
# retry-resource-fetch
Fetching :Resource: items is retried on transient errors using exponential backoff.
5. UI 复杂度
规范是否描述了一个包含多个交互元素、布局和状态转换的完整屏幕或页面?
过于复杂:
***functional specs***
# dashboard
The dashboard shows :User: profile, recent :Task: items in a sortable table, a notification bell with unread count, and a sidebar with navigation links that highlights the active page.
可接受(逐步构建):
***functional specs***
# dashboard-page
A dashboard page is shown for :User:.
# dashboard-recent-tasks
Recent :Task: items are shown in a sortable table on the dashboard.
# dashboard-notifications
A notification indicator with the unread count is shown on the dashboard.
6. 数据转换复杂度
规范是否涉及跨多个实体进行复杂的数据映射、聚合或转换?
- 简单的字段映射或筛选 → 通常没问题
- 多步骤转换、跨实体联接或聚合 → 通常过于复杂
7. 隐含技术组件
规范是否暗示需要构建一个重要的技术组件——引擎、解析器、调度器、布局算法、状态机或同步机制——除了其描述的行为之外?组件不是现成的基本功能:也必须为其生成代码,因此它会计入 200 行代码预算,并且必须作为估算的一部分进行评估。如果规范既需要一个组件,又在其上实现行为,那实际上就是在一个规范中包含两部分代码——这是“过于复杂”的强烈信号。计算组件本身的实现,而不只是调用它的粘合代码。
过于复杂(在一个规范中构建组件并使用它):
***functional specs***
# export-report-pdf
A :Report: is exported to PDF, laying out multi-page tables with repeating headers and page numbers, and charts rendered from :Report: data.
可接受(组件在独立的规范中实现,然后引用它):
***functional specs***
# pdf-renderer-tables
:PdfRenderer: lays out multi-page tables from structured content.
- Table headers repeat at the top of each page.
- Each page shows its page number.
# export-report-pdf
A :Report: is exported to PDF using :PdfRenderer:, embedding charts rendered from :Report: data.
出现此指标时,应使用 break-down-func-spec Strategy 6 进行修正——将组件提取到更早的独立规范中,并在此处引用。
8. 粗略估算代码行数
在脑中估算实现所需的代码量。请考虑:
- 需要创建的新文件
- 新函数/方法
- 隐含技术组件(引擎、解析器、算法)的代码,而不仅是使用它的粘合代码
- 数据模型变更(架构、迁移、类型)
- UI 组件(如适用)
- 测试设置和断言(单元测试会自动一并生成)
- 对于新根模块中的第一个规范,实现要求所隐含的所有项目和测试脚手架
- 错误处理路径
- 导入语句和样板代码
如果估算超过约 150 行代码,该规范就有很高的复杂度风险(应留出余量,以便渲染器添加必要的样板代码)。
输出格式
该技能只会输出以下两个字符串之一,不带任何外围文本、解释、估算或拆解:
ACCEPTABLE
或
TOO COMPLEX
内部分析(检查清单、代码行数估算、推理)用于得出结论,但不得出现在输出中。由调用方决定如何处理结果。
与 add-functional-spec / add-functional-specs 的集成
此技能会在 add-functional-spec 工作流的第 3 步中调用(或在 add-functional-specs 中针对每个规范分别调用),在起草规范之后、将其插入文件之前执行。调用方根据单词形式的结论采取行动:
- ACCEPTABLE — 继续插入规范。
- TOO COMPLEX — 调用
break-down-func-spec生成更小的规范,然后逐一插入(并分别对每个规范运行冲突检查)。