| name | module-decomposition |
| description | 独立的“无损修剪式”模块拆解方法论:用于在规划或实现过程中,对既有模块/超大文件(默认阈值≥1000 LOC)做渐进式无损拆解,把单体逻辑拆成互斥子模块以降低耦合与冲突面;支持两种拆分形态:单一主体用 *.*.ts 平铺、子系统用目录组织;以思想/输出协议为主、脚本为辅,可被上层 agent 嵌入任意工作流(不依赖 plan.md 等固定产物)。 |
Module Decomposition(无损修剪式模块拆解)
目标:在不改变语义与对外 API 的前提下,把“过大/过杂”的文件或模块拆成互斥子模块;把拆分的边界、命名与依赖拓扑显式化,支撑上层 agent 做规划、排任务与渐进式重构。
本 skill 是“思想指导工具为主、脚本为辅”:
- 思想:拆分决策树、无损修剪不变量、互斥子模块边界设计、依赖拓扑约束。
- 工具:可选的 LOC 扫描脚本 + 可复制的 Markdown 模板/清单。
快速开始
- 运行扫描脚本列出候选大文件(默认阈值 1000 行):
python .codex/skills/module-decomposition/scripts/scan_large_files.py --min-lines 1000 --top 30 packages/logix-core/src packages/logix-react/src --format md
- 对每个候选目标,先产出一份可复用的“Decomposition Brief”(只写方案,不急着动代码):
- 使用
references/large-file-decomposition-template.md 作为模板(可直接复制到任意文档/Issue/PR 描述/对话)。
- 若要落地到代码,再执行“无损修剪”流程:一次只落地一个互斥子模块(见下文)。
上层 agent 对接(输入/输出协议)
把本 skill 当作“可插拔的拆解子流程”,上层 agent 只需要提供:
- 输入:
- 目标文件/目录(或符号列表)
- 本次目的(行数治理 / 职责治理 / 子系统抽象)
- 必须保持的不变量(对外 API、性能/诊断预算、单向依赖规则等)
- 预计会触及的相邻文件/调用方(用于评估改动波及面)
- 输出(标准化,建议用 Markdown):
- Decomposition Brief:互斥子模块清单 + 命名/落点 + 依赖拓扑 + 渐进迁移步骤 + 验证策略
该输出不绑定任何固定产物:你可以把它粘贴到任意载体(设计文档、任务系统、handoff、PR 描述、spec-kit plan 等),也可以单独落为 decomposition.md。
决策树(拆分形态)
判断拆分原因与形态(必须二选一,避免混合导致目录漂移):
- 单一主体,为行数/职责治理拆分:用
*.*.ts 平铺在同目录。
- 例:
ModuleRuntime.ts → ModuleRuntime.hubs.ts / ModuleRuntime.txnContext.ts / ModuleRuntime.runtimeStore.ts
- 一大类子模块/子系统:用目录承载子模块,并在目录内再按子能力细分。
- 例:
runtime/core/process/*(已是目录)继续在其内拆分 ProcessRuntime.*.ts
工作流(规划 → 实施)
Step 0:先定“无损修剪”不变量(必须)
- 对外导出与语义保持不变(除非明确是 breaking change 且有迁移说明)。
- 拆分只改变文件组织与依赖关系,不引入新行为、新缓存、新调度策略。
- import 拓扑保持单向;出现循环依赖视为“边界设计失败”,回到 Step 2 重画边界。
Step 1:盘点与切面(只读)
- 用脚本确认是否满足阈值(≥1000 LOC)或预计本次会超过阈值(“必然会被本需求触及”也算)。
- 识别“可稳定切面”(用于形成互斥子模块;按职责拆,不按作者习惯拆):
- 纯类型/协议、纯工具、组装/wiring、执行循环、诊断/事件、缓存/索引、IO/平台适配。
- 识别硬约束:
- import 单向拓扑、内部/外部边界(例如
internal/** 深层不得反向依赖浅层)。
- 运行时核心路径的性能/诊断约束(新增开销必须可度量、事件必须 Slim 可序列化)。
Step 2:设计互斥子模块(写计划)
- 产出 Decomposition Brief(必须互斥;不要“都能放这里/先放着”):
- 文件名(遵循平铺/目录规则)
- 单一职责(SRP),输入/输出(导出符号)
- 允许的依赖方向(谁 import 谁)
- 原文件保留的内容:通常只保留顶层
make()/对外导出/最薄 glue
- 载体选择:
- 任意你正在使用的“事实源”(设计文档/任务系统/PR 描述/spec-kit 产物/handoff),只要可追踪、可交接即可。
Step 3:实施拆分(无损修剪)
- 以“移动/提取”为主,不在拆分过程中顺手做语义重写(避免混淆 diff)。
- 优先策略:
- 先新建目标文件,移动一组互斥能力(保持导出签名不变)。
- 原文件改为 import 并 re-export/组装(必要时)。
- 连续小步:每次拆 1 个子模块就做一次类型/测试验证,避免最后一次性爆炸。
Step 4:验证与交接
- 至少完成:类型检查 + 相关测试(按项目约定)。
- 更新事实源:把“已拆/未拆/下一处拆分”同步回你选定的载体(便于交棒)。
反模式(禁止)
- 为了“顺手优化”在拆分过程中引入新的行为/调度/缓存(会破坏无损修剪原则)。
- 引入双真相源(同一份状态/协议/事件定义出现在两个地方)。
- 让拆分后的模块职责重叠,或产生循环依赖(应回到 Step 2 重画边界)。
资源
- 模板:
references/large-file-decomposition-template.md
- 检查清单:
references/safe-pruning-checklist.md
- 扫描脚本:
scripts/scan_large_files.py