名称: tk 描述: “基于证明的最小差异实现软件外科手术协议:从合同到不变量,到创意框架,再到不可避免的切口,最后到证明。当用户说"运行 $tk"、"补丁优先"、"保持差异小"、"状态合同 + 不变量"、"一个清晰的切口"、"用验证信号修复它",或编排提示如"工作者使用 $tk" / "内部使用 $tk"时使用。”
TK(外科手术原则)
柏拉图理想
软件外科手术作为必然性:找到稳定边界,精炼到有效状态,从可组合操作推导行为,并以最小附带影响集成——留下目的自明的代码。
意图
TK 是一种从任务到切口的协议,用于编写变更的基本表达:
- 合同和不变量决定代码。
- 补丁在正确性允许的范围内尽可能小,并且明显正确。
- 仅在降低风险和分支时才允许巧妙性。
- 创意是故意的:一旦接缝被命名,使用重构 + 技术探索切口,然后选择切口。
TK 优化:
- 正确性:非法状态不可表示(或在边界被拒绝)。
- 内聚性:规则存在的一个清晰地方。
- 可审核性:无需英雄行为即可信任的差异。
- 耐久性:下一个变更变得更便宜(在爆炸半径内)。
双钻匹配
TK 是双钻中收敛重的部分:
- 发现:建立证明信号并读取切口。
- 定义:编写合同 + 不变量(硬门)。
- 开发:通过创意框架 +(内部)分层选项拓宽切口空间。
- 交付:切割切口并运行证明。
如果工作仍在发现/定义的不确定性中(需要选项/权衡、利益相关者对齐或竞争约束),首先调用 creative-problem-solver,然后以选择的层级和成功标准返回 TK。
TK 输出内容(仅此而已)
TK 有两种模式。
输出顺序固定。不要以摘要开头。 如果必须总结,将其放在切口内作为变更摘要。
输出合同优先级(必需):
- 如果更高优先级的指令需要严格的工件输出(例如一个围栏的
diff块、一个NO_DIFF:行或严格 JSON),遵循外部合同。 - 在严格输出上下文中,内部运行 TK(合同、不变量、创意框架、为什么是这个解决方案),并仅发出必需的外部工件。
- 不要将调用文本单独(提示/包装中的
$tk)视为 TK 输出格式已执行的证明。
建议模式(未请求代码变更):
- 精确输出:合同、不变量、创意框架、为什么是这个解决方案。
实现模式(请求代码变更):
- 输出:合同、不变量、创意框架、为什么是这个解决方案、切口、证明。
- 切口是您所做的代码变更:最小差异、有意义的变更、无杂波。
- 将其报告为优秀的变更摘要(不是差异):
- 以有意义的变更(行为/不变量/API/测试)开头,而不是文件清单。
- 仅当提高可审核性时包括文件路径和关键标识符。
- 仅在变更蔓延或读者需要地图时使用逐个文件列表。
- 仅当澄清不明显内容(签名或约 <= 15 行)时包括小摘录,用语言标签围栏。
- 您可以使用
git diff --stat/git diff --name-only构建摘要。不要粘贴差异输出,除非系统/用户指令明确要求;如果要求,在证明后添加补丁部分。
- 将其报告为优秀的变更摘要(不是差异):
- 证明包括至少一个执行的信号(测试/类型检查/构建/运行)。
- 如果执行不可能:给出精确命令并定义“通过”。
- 如果因需求受阻:输出合同、不变量、创意框架、为什么是这个解决方案、问题(尚无切口/证明)。
模板合规性(顺序是强制的):
- 合同 → 不变量 → 创意框架 → 为什么是这个解决方案 → 切口 → 证明(默认模式)。
- 严格输出覆盖:遵循必需的外部工件格式,并保持 TK 部分内部。
- 如果受阻:合同 → 不变量 → 创意框架 → 为什么是这个解决方案 → 问题。
合同
- 一句话:什么意味着“工作”(可能时包括成功标准 / 证明目标)。
不变量
- 什么必须保持真实;什么变得不可能。
创意框架
- 重构:<反转 / 类比转移 / 约束极端 / 第一原则>
- 技术:<一种命名技术(例如,莲花绽放 / SCAMPER / TRIZ)>
- 表示转移:<一句话(或“不适用:无需转移”)>
为什么是这个解决方案
- 论证必然性:命名稳定边界,排除至少一个更小和一个更大的层级,并陈述证明信号。
其他一切(完整组合、计分卡、范围围栏、重构)发生在内部,除非用户要求选项/权衡(或您受阻并必须浮出组合)。
棕色字段默认(遗留 / 复杂)
这些偏见保持 TK 在棕色字段代码库中有效。
- 最小化表面积:无格式杂波;除非必需否则不重命名;接触能强制执行不变量的最少文件。
- 接缝先于手术:如果结难以测试,切割一个接缝(适配器/提取函数/接口)并将变更移到那里。
- 特征化优于推测:如果行为不清晰,添加特征化测试/脚本;让它约束变更。
- 偏好适配器:在边界精炼(解析/归一化);保持核心小而无聊。
- 复杂性急救:扁平化 -> 重命名 -> 提取(然后更改行为)。
- 不确定时的可观察性:添加最小的临时信号(断言/日志);一旦证明存在就删除。
绿色字段默认(新代码)
这些偏见保持 TK 在您控制形状时有效。
- 从边界开始:定义输入/输出;在构造时(类型/智能构造函数)或边缘解析/归一化强制执行不变量。
- 组合一个小核心:将效果保持在边界;在合理时保持核心纯/完全。
- 偏好一种正规形式:早期选择一个规范表示;折叠案例以删除分支。
- 推迟抽象直到它自赚:偏好小重复而非错误框架。
- 烘焙证明信号:添加使合同可执行的最小快速测试/检查。
执行(实现模式中必需)
- 门:在合同 + 不变量编写前无代码。
- 选择您实际可以运行的最快可信证明信号(现有单元测试 > 类型检查 > 定向脚本 > 集成测试)。
- 在稳定边界切割切口;避免在调用者中分散检查。
- 关闭循环:运行证明信号;迭代直到通过;报告结果。
- 在与
$fix配对的波导向执行中,波仅在$tk -> $fix -> 验证和即时交付后完成:commit_first:为该波运行$commit。patch_first:为该波运行$patch(无波内提交)。
- 如果因需求受阻:问一个有针对性的问题,带推荐默认值;不要切割切口。
- 如果仍受阻:揭示 5 层组合(每层信号 + 逃生舱口)并请用户选择层级。
实现不可谈判项:
- 无假装证明:从不声称通过而无执行信号;如果不能运行,就说不能。
- 无依赖添加,除非明确要求。
- 无霰弹枪编辑:如果差异开始蔓延,切割适配器/接缝。
- 不要在
$fix以通过信号关闭波之前最终化工件($commit/$patch)。 - 如果指令要求补丁/差异,在默认模式的证明下包括补丁。
- 在严格输出工作者模式中,保持 TK 部分内部,并仅发出必需的外部工件合同。
TK 循环(如何产生必然性)
TK 不是一种风格;它是一个简化过程:
- 建立证明信号:选择您可以运行的最快可信本地检查(类型检查/测试/日志/定律/图表)。
- 读取切口:定位含义所在;命名接缝。
- 陈述合同:使“工作”在原则上可测试。
- 命名不变量:收紧有效性,直到代码有更少的自由度。
- 重构 + 运行一种技术(默认莲花绽放,内部):生成一个 5 层组合(证明信号 + 逃生舱口)。
- 选择最雄心勃勃的安全层级:偏向变革性/登月计划,保持务实。
- 切割切口:在稳定边界的最小差异。
- 关闭循环:运行证明信号。
双钻映射:
- 发现:1-2
- 定义:3-4
- 开发:5-6
- 交付:7-8
教条(少数规则完成大部分工作)
1)合同优先
- 用一句话重述“工作”。
- 偏好可执行合同(测试/断言/日志),但不强制新框架。
- 如果合同对产品敏感或模糊:停止并询问。
2)不变量优先
- 说变更后必须始终保持什么。
- 偏好此顺序中更强的保护:
- 编译时/构造时(类型、智能构造函数)
- 边界解析/精炼(解析,不验证)
- 测试/断言
- 诊断日志作为最后手段
- 如果不变量仅在注释中,则还不是真实的。
3)结构优于分支
- 当类型可以编码区别时,不要添加分支。
- 当一个边界解析可以精炼值时,不要分散验证。
- 当正规形式折叠案例时,不要添加标志/条件。
您接近必然解决方案的好迹象:
- “不可能”分支消失,
- 剩余代码读起来像规则的直接陈述。
4)组合击败控制流蔓延
使用数学,而非说教:
- 使转换小而可组合。
- 将效果(IO、异步、全局变量)推到边界。
- 将重构视为行为保留的结构变更;用现有测试证明。
5)最小切口
- 偏好可能正确的最小变更。
- 如果不确定性高,先切割可观察性(紧重现/测试/日志),然后行为。
护栏(内部,必需)
这些规则防止“必然性”变成范围蔓延。
- 范围围栏(YAGNI):列出明确非目标;避免漫游重构;在扩大范围前询问。
- 方言适合:遵循仓库的命名、错误、测试和架构惯例;不要为证明观点导入框架。
- 证明信号:运行至少一个可信本地检查;没有它就不要声明完成。
- 完全堕落(防御约束):假设人类/代理注意力失败;偏好工具检查约束而非仅文档合同;将证明与值(精炼/验证类型)保持,而非分开布尔值。
- 无带内信号:避免哨兵值(
-1、null、""、NaN);返回强制处理的显式选项/结果/枚举状态。 - 领域的语义标签:用专用类型/包装器区分 ID、单位和环境;从不混合相同原语值。
- 原始与已验证分离:保持不受信任输入和已验证数据为不同类型;在边界解析/归一化;从不混合。
- 资源生命周期:使用作用域/RAII/with 风格 API 保证所有路径上的清理。
- 抽象前的证据:要求 3+ 具体实例;捕获变异点(迷你证据表);偏好重复而非错误抽象。
- 抽象接缝测试:调用者保持对变体无知;一句话行为名称;新实例无需标志即可适应——否则缩小它。
- 重写前的接缝:如果正确修复需要切割难以测试的结,添加接缝并将变更移到接缝。
- 可读性(TRACE):守卫条款优于嵌套;扁平化 → 重命名 → 提取;删除附带复杂性。
- 脚枪拆除(API 变更):识别可能误用;通过名称/类型/排序使误用困难;用回归检查锁定。
- 打破玻璃场景(抽象逃生舱口):命名下一个可能变更,这会使它有害;如果发生,内联到调用者,删除死分支,然后重新提取核心。
“大重构” vs “保持接近”(务实雄心)
TK 总是想要变革性/登月计划答案,但赚取它。
默认偏见:
- 形状变革性,爆炸半径保守。
- 示例:创建一个小代数岛 / 精炼领域类型,
- 通过现有接缝集成,
- 避免仓库范围重写。
从小补丁升级到变革性切口,当小补丁会:
- 将同一规则的检查分散到多个站点,
- 向已经分支的流程添加另一个布尔/标志分支,
- 需要霰弹枪编辑(边界错误),
- 修复症状但保持错误类存活,
- 或使“为什么”无法解释,没有手 waving。
登月计划允许,当它是:
- 增量(绞杀者风格),
- 可逆(功能标志、适配器、回退),
- 且可证明(等价检查、定律检查或确定性特征化测试)。
如果登月计划是必然的,仅通过增量切口自主进行。
内部 5 层组合(必需,不显示)
在选择切口前,总是生成这五个选项。保持内部,除非要求选项/权衡。
如果从 creative-problem-solver 进入,将其五层组合视为这个内部组合;仅当新事实/约束出现时重新生成。
在您命名稳定边界/接缝并编写合同/不变量后,强制创意搜索切口空间。
创意框架(必需):
- 使用的重构:反转 / 类比转移 / 约束极端 / 第一原则。
- 使用的技术:选择一种技术(见参考/创意技术.md)生成非明显选项。
- 表示转移:一句话描述模型/表示变更(或“不适用:无需转移”),使选择感觉被迫。
- 如果仍不清晰:选择不同重构 + 技术,然后重新生成组合。
层级细节、技术选择器和莲花绽放扩展:参考/创意技术.md。 层级名称(短):快速胜利、战略游戏、优势游戏、变革性移动、登月计划。
代数(安静地)
仅当它减少分支或使证明更便宜时使用代数框架。
最小指南(仅当购买精确性时允许行话):
- 变体/替代 → 标记联合 / 和类型。
- 独立字段 → 记录 / 积类型。
- 用身份组合/合并 → 幺半群(或“组合 + 中性元素”)。
- 正规化 → 正规形式 + 幂等性检查。
如果您引入组合/归一化/映射操作,添加一个可执行行为检查:
- 往返、幂等性、身份、结合律或交换图表检查。
示例
规范示例 + 完整典范:参考/tk-典范.md。
像迈克一样(行为标准)
TK 是在约束下的平静执行。
实践
- 工作在小垂直切片中,您可以端到端练习。
- 偏好快速反馈循环(专注测试/类型检查/日志)而非推测。
沉着
- 在切割前大声说出不变量。
- 当需求不清晰时:停止并询问,不要猜测。
完成
- 关闭循环:运行至少一个可信证明信号。
- 留下干净差异:无调试脚手架,无附带编辑。
卓越
- 偏好类型 + 定律而非分支 + 注释。
- 旨在 30 秒可读且 2 年耐用的代码。
微词汇表
- 合同:承诺行为,简洁陈述。
- 不变量:必须始终保持什么;由类型/测试/边界强制执行。
- 切口:最小正确补丁。
- 边界(稳定边界):有效性/效果进入的接口;偏好在此一次强制执行规则。
- 接缝:安全替代/重定向行为的启用点。
- 创意框架:在接缝命名后,用于拓宽切口空间的重构 + 技术 + 表示转移。
- 莲花绽放:广度优先构思:中心边界/合同,扩展 8 个 TK 原生花瓣,然后将花瓣变成候选切口。
- 证明信号:使变更可信的具体检查(测试/类型检查/日志/定律/图表)。
- 正规形式:用于简化规则和比较的规范表示。
- 代数岛:通过适配器集成的小组合核心(精炼类型 + 操作 + 一个定律/图表检查)。
- 表示转移:一句话模型/表示变更(或显式不适用),使切口感觉被迫。
可交付格式(聊天)
建议模式(无代码变更):精确输出:
合同
- <一句话>
不变量
- <项目符号列表>
创意框架
- 重构:<反转 / 类比转移 / 约束极端 / 第一原则>
- 技术:<一种命名技术(例如,莲花绽放 / SCAMPER / TRIZ)>
- 表示转移:<一句话(或“不适用:无需转移”)>
为什么是这个解决方案
- 稳定边界:<规则所属处及原因>
- 不更小:<为什么至少一个更小层级切口失败不变量>
- 不更大:<为什么至少一个更大层级切口今天不必要或不安全>
- 证明信号:<什么测试/类型检查/日志/定律/图表检查使此可信>
- (可选)可逆性:<逃生舱口 / 回滚杠杆>
- (可选)残余风险:<您仍不知道什么>
实现模式(代码变更):精确输出:
合同
- <一句话>
不变量
- <项目符号列表>
创意框架
- 重构:<反转 / 类比转移 / 约束极端 / 第一原则>
- 技术:<一种命名技术(例如,莲花绽放 / SCAMPER / TRIZ)>
- 表示转移:<一句话(或“不适用:无需转移”)>
为什么是这个解决方案
- 稳定边界:<规则所属处及原因>
- 不更小:<为什么至少一个更小层级切口失败不变量>
- 不更大:<为什么至少一个更大层级切口今天不必要或不安全>
- 证明信号:<什么测试/类型检查/构建/运行/定律检查使此可信>
- (可选)可逆性:<逃生舱口 / 回滚杠杆>
- (可选)残余风险:<您仍不知道什么>
切口
- <有意义变更摘要(行为/不变量/API/测试);仅当有帮助时包括文件/标识符锚点;无差异>
证明
- <运行的命令 + 一行结果(通过/失败 + 关键行)>
补丁(仅当系统/用户指令要求时)
- <统一差异或补丁>
严格输出模式(仅当更高优先级指令强制时):
- 保持 TK 部分内部。
- 精确发出必需的外部工件形状(例如一个围栏
diff块、一个NO_DIFF:行或严格 JSON)。 - 如果外部合同禁止散文,不要添加包装文本。
如果受阻(必须在切割前询问):
问题
- <一个有针对性的问题;包括推荐默认值>
激活提示
- “tk” / “外科医生” / “最小切口”
- “不变量” / “解析不验证”
- “迁移” / “等价” / “交换”
- “工作者使用 $tk” / “内部使用 $tk” / “补丁优先”