关于 code-discipline
code-discipline 是面向编码 Agent 的代码实现与审查技能,适用于新增逻辑、重构和维护性检查。它以复用现有能力和限制不必要抽象为核心,并提供新增抽象的审查准则。
主要功能
- 01优先检查语言、框架和仓库现有能力
- 02限制无必要的辅助函数与包装层
- 03按准入条件评估新增抽象
- 04检查重复工具、常量和样式
- 05提供完成标准与审查要求
适用场景
- 01实现功能时控制抽象和文件增长
- 02重构时识别并合并重复工具
- 03审查辅助函数或服务层是否必要
- 04检查代码变更的可维护性
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mwillbanks/ agent-skills --skill code-discipline安装后在 Claude Code 中输入/code-discipline确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
evals/evals.jsonevals/fixtures/already-remediated.tsasync-compliant.tsasync-unawaited-bad.tsborderline-god-mixed.tscohesive-large-domain.tscomponent-helper-sprawl.tsxes6-class-service.tsfunction-declaration-should-stay.tsfunction-declarations-only.tsfunctional-composition-auth.tsgod-schema.tslibrary-edge-platform-suffices.tsmonorepo-dup-package-a.tsmonorepo-dup-package-b.tsobject-args-vs-params.tsone-off-constants.tspositional-args-small-stable.tspositive-clean-service.tsprisma-resolve-parse-bloat.tsunnecessary-style-split.tsreferences/abstraction-patterns.mdcomponent-logic.mdconstants-and-organization.mdfeature-refactor-first.mdhelper-functions.mdlibrary-preference.md详细介绍
代码规范
只要任务涉及添加或修改逻辑、辅助代码膨胀、不必要的包装器、重复的工具函数、重复的常量、抽象膨胀、巨型文件、模式边界、类与组合的选择、箭头函数与函数声明的选择、对象参数与位置参数的选择,或安全性/可维护性强化,就使用此技能。
这是一项反偷懒技能。它旨在防止 Agent 通过新建文件、辅助代码和间接层来“解决”任务,而现有基础功能其实已足以解决问题。如果某项功能揭示了更好的边界,且改动仍在当前任务范围内,并符合下方的准入门槛,就立即重构到更好的边界。
默认假设:
- 用户希望代码易于维护,且抽象面尽可能小。如果某项功能暴露出明显更好的边界,就立即采用,而不要仅为缩小差异而保留较差的结构;这也包括短期内需要扩大表面范围、以减少长期复杂度,且符合准入门槛的情况。
- 用户不希望出现对现有行为重新命名的重复实现。对 ORM 模式边界、类继承、函数签名和安全敏感决策,也要遵循同样的规范。
- 除非具有明确的架构价值,否则禁止新增辅助代码、包装器、常量模块和仅为样式而添加的间接层。
- 这些规则适用于抽象、辅助代码、工具函数和间接层。新的一级领域文件(例如路由处理程序、实体、页面组件、测试文件)不受准入门槛约束,而应遵循
repo-standards-enforcement。对于主要用于领域逻辑而非共享基础设施的文件,不要应用准入门槛。
适用场景
以下情况请调用此技能:
- 引入新逻辑的功能实现
- 增加工具或服务层的重构
- 可能导致组件本地辅助代码不断增多的 UI 改动
- 可能导致常量、令牌或样式文件被不必要地拆分的前端工作
- 容易诱发快速添加包装器补丁的 bug 修复
- 侧重可维护性与复用规范的代码审查
生产实现工作中,请与 agent-execution-mode 和 repo-standards-enforcement 一起使用。
如果此技能中列出的任何参考文件不可用,请以内嵌于本文档的规则为准,不要因等待缺失的参考文件而阻塞进度,并在输出契约报告中注明不可用的参考文件。 如果所有参考文件都不可用,本文档中的内嵌规则也完整且足够。参考文件仅提供示例和补充说明;没有任何规则必须依赖参考文件才能执行。请依据内嵌规则继续工作,不必降低信心。
核心执行策略
此技能采用强制执行模式。对于硬性规则,不合规的代码必须直接拒绝,不得协商。对于软性规则,应在输出契约中提供书面理由,然后继续;除非处于交互式审查模式,否则不要向用户索要理由。
对每个候选抽象,都遵循同一决策流程:(1) 按照强制评估顺序的步骤 1–6,优先评估复用;(2) 只有在步骤 6 无法采用时,才继续执行步骤 7,并应用新增抽象准入门槛的允许/拒绝检查;(3) 实现后,核验完成定义中的标准。
硬性规则——绝不可覆盖
- 如果逻辑简单且只使用一次,不要创建辅助函数。
- 不要创建只转发调用的包装器。
- 不要为现有工具创建改名后的重复版本。
- 除非至少满足一项准入门槛条件并明确说明理由,否则不要添加会增加间接层的服务、钩子或适配器层。
- 不要重新实现平台或标准库的行为。
- 不要在多个包中重复工具逻辑。
- 不要仅为减少行数而将一次性常量提取到模块中。
- 除非确实存在归属关系和复用需求,否则不要创建
constants、helpers、utils或shared文件。 - 当样式属于局部样式,且拆分不会带来归属价值时,不要将样式拆分到单独文件中。
硬性规则绝不可争议。
规则冲突时的优先级:(1) 硬性规则,(2) Monorepo 和工作区规则,(3) 准入门槛的判定,(4) 功能优先的边界规则,(5) 其余所有软性规则和按具体程度排序的领域规则。
强制评估顺序
在添加任何辅助函数、钩子、服务、包装器、适配器、格式化器、解析器、转换器、常量模块、令牌或工具之前,必须严格按以下顺序评估:
- 语言或运行时原语
- 标准库 API
- 框架原生功能
- 仓库现有工具
- 已安装的依赖项
- 如果现有工具只能部分满足需求,优先在调用点调整其用法(例如,仅在调用点进行组合或使用轻量适配器),而不是创建新的共享抽象;如果多个现有工具都只能部分满足需求,优先选择其领域归属与调用点最匹配的工具;如果归属同等匹配,优先在调用点进行组合,而不是调整任一工具;如果调整工具会改变其公共签名、影响任何现有调用方的行为,或要求当前任务范围之外的调用方更新,则继续执行第 7 步,并明确说明为何无法复用部分匹配的工具,同时在输出约定中记录组合或调整的理由
- 创建新的抽象并说明理由
跳过此顺序属于不合规行为。
对于每个候选抽象,都必须依次执行以下清单:(1) 完整执行强制评估顺序的第 1 至第 7 步;(2) 如果执行到第 7 步,则应用新抽象准入门槛;(3) 实现后,验证完成定义的标准。
新抽象准入门槛
仅当至少满足以下一项时,才允许创建新的抽象、辅助函数、常量模块或共享样式边界:
- 它强制执行领域不变量或策略
- 它封装的逻辑 (a) 复杂度超过单个表达式,且 (b) 在 3 个或更多不同调用点以原样或近似原样的形式出现,并且 (c) 未来要修改该逻辑,必须分别编辑每个调用点
- 它隔离了基础设施边界
- 它提供正确性、验证或安全保障
- 它提升了真正复杂行为的可测试性
- 它为必须在多个使用方之间保持同步的值提供统一事实来源
如果新抽象仅有以下用途,则应予以拒绝:
- 为现有行为改名
- 一对一转发调用
- 包装单个原语或单次库调用
- 仅为风格偏好而存在
- 将内联表达更清晰的一次性字面值隐藏起来
功能优先的边界规则
当更改涉及文件布局、API 形态、架构组织或类与组合的取舍时,请阅读 references/feature-refactor-first.md。当某项功能揭示了更好的边界,且相关工作仍在当前实现范围内时,请遵循该文档。如果 references/feature-refactor-first.md 不可用,则仅当更改仍处于任务范围内、不超出功能边界,并且有准入门槛作为依据时,才优先立即重构为更好的边界。
软性规则——覆盖前必须提供书面理由
将以下情况视为自动触发审查的信号:
- 以
normalize、format、parse、transform、sanitize、safe、to开头的名称 - 以
build、make、create、get、set、use或manage开头,且仅封装单个操作的名称 - 公共接口与仓库或 SDK 方法签名一一对应,且除转发参数外,不增加错误处理、策略、验证或转换的服务
- 只调用另一个 hook 并返回相同结构的 hook
- 只在单个文件中使用一次的辅助函数
- 只包含单行封装函数的工具模块
- 只有一个使用者的常量模块
- 仅移动声明、但不改变归属或复用方式的样式文件
代码异味并非总是错误,但需要明确说明理由。适用软性规则时,Agent 必须在继续之前,在输出规范中提供明确的书面理由。如果 Agent 在无需用户交互的情况下自主运行,应将理由直接写入输出并继续;不要阻塞执行并等待外部批准。硬性规则不可质疑。
组件逻辑规则
- 简单的显示逻辑和一次性转换直接内联。
- 仅在复杂度或复用情况足以证明有必要时才提取。
- 不要让组件文件膨胀成局部工具库。
- 将可复用逻辑移到合适的共享层,而不是最近的文件。
- 一次性常量直接内联,除非它们属于共享契约或在多个文件中重复使用。
- 组件局部的样式声明应保留在本地,除非重复使用的样式确实证明有必要创建共享基础样式。
常量放置规则
- 在有助于提升可读性时,将一次性字面量放在使用位置附近。
- 只有当常量具有共享含义、被重复使用,或属于公共契约或跨文件契约时,才将其提取出来。
- 不要仅为了存放一个常量而创建模块。
- 如果新名称没有增加任何含义,不要将字面量提取为
const X = ...。 - 将共享设计令牌放在主题或设计系统层,而不是页面局部文件中。
- 将共享 UI 常量放在所属领域或共享层,而不是方便归类的目录中。
文件与样式组织规则
- 将辅助函数、常量和样式放在范围最窄且归属正确的位置。
- 对于组件局部的关注点,优先使用与组件共置的样式。
- 只有多个组件确实共享样式时,才优先使用共享样式基础元素。
- 避免创建仅用于隐藏结构的通用杂项目录。
- 避免创建不增加边界或复用价值的重新导出聚合文件。
- 样式文件名应清楚表明所属对象,避免使用通用名称(
Button.styles.ts比styles.ts更清楚)。 - 只有在拆分能够更清晰地说明归属、复用或维护方式时,才拆分样式文件。
- 不要为只使用一次的细小样式片段单独创建文件。
单仓库与工作区规则
- 不要在多个包之间重复辅助函数
- 存在复用时,将共享逻辑提升到合适的共享包中
- 如果工作区依赖关系图未将包 B 列为包 A 的依赖项,不要在包 B 中导入包 A 的工具;如果边界不明确,导入前先询问
- 不要通过便利导入绕过边界
- 不要对代码生成器的输出文件(例如 ORM 迁移文件、架构客户端或构建产物)应用去重或删除规则;应根据文件头注释、工具约定或 generated/ 和 generated/ 目录识别生成文件
审查与重构要求
在审查/重构模式下运行时,Agent 必须:
- 标记不必要的辅助函数和封装
- 在安全的情况下移除琐碎的抽象
- 合并重复的工具函数
- 在适当情况下,用平台/库提供的基础功能替换手写逻辑
- 说明每项移除或合并对可维护性的改善
完成标准
仅当以下条件全部满足时,此技能才算完成:
- 不再有新引入的琐碎辅助函数/包装层
- 修改范围内不再有重复的工具逻辑
- 未在缺乏共享语义理由的情况下提取一次性常量
- 新增的抽象(如有)有准入门槛作为依据
- 优先使用平台、框架和内部工具,而非重新实现
- 修改范围降低了长期维护负担;只有当范围内更优边界的重构有准入门槛作为依据,且确有必要时,才允许短期增加表面积
输出约定
使用此技能后作答时,仅报告非空类别。在实现模式下,报告本任务所做的更改;在审查模式下,报告所审查的已提交代码。如果未考虑抽象候选项,则省略该项。如果没有将常量保留在原处,则省略该项。始终至少报告一项。
如果未评估任何抽象候选项,也未执行任何整合操作,请报告:“未发现抽象候选项。直接使用了现有基础构件,未引入新的辅助函数。”
- 考虑过哪些抽象/辅助函数候选项
- 复用了哪些现有基础构件/工具
- 拒绝了哪些抽象及原因
- 执行了哪些整合/移除操作
- 新增了哪些抽象,以及准入门槛中的哪项条件允许新增
- 哪些常量和样式保留在原处而未提取
- 哪些参考文件不可用(如有)
参考资料
请参阅以下参考指南,了解示例和详细说明:
references/helper-functions.mdreferences/abstraction-patterns.mdreferences/library-preference.mdreferences/feature-refactor-first.mdreferences/component-logic.mdreferences/constants-and-organization.md