remove-technical-debt

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Remove Technical Debt

消除技术债务

Take a large, aged, tangled codebase that everyone is afraid to touch and pay its debt down in place — no big-bang rewrite, the old system always shipping. The instinct to rewrite is the one reliable way to turn a struggling-but-shipping product into a struggling-and-not-shipping one; this journey is the alternative. It is interactive and resumable across eight phases: the agent asks before every decision and records the outcome in your project's
docs/
folder, so you can stop after any phase and pick up later. The first phase builds a safety net at your change points; every phase after it is verifiable because that net exists.
针对人人都不敢触碰的大型老旧混乱代码库,直接在现有基础上偿还技术债务——无需大规模重写,旧系统始终保持可发布状态。重写的本能是将一个勉强能发布的产品变成完全无法发布产品的可靠方式;本流程则是替代方案。它具备交互性,可跨八个阶段继续推进:Agent在每个决策前都会提问,并将结果记录在项目的
docs/
文件夹中,因此你可以在任意阶段暂停,之后再继续。第一阶段会在你的变更点构建安全网;后续每个阶段都因这个安全网的存在而可验证。

Core Principle

核心原则

Feedback over fear: cover and modify, never edit and pray — pay debt down in place on the paths you actually walk, and never stop shipping. This skill sequences the phases, asks the decision questions, and records every choice in
docs/
. The constituent skills carry the method — invoke them rather than improvising their frameworks. You do not pay down a mountain of debt by rebuilding the mountain; you pay it down one safe, tested step at a time along the paths you already change. Skipping ahead — cleaning before the safety net, splitting services before the boundaries are real — is the exact failure mode this ordering exists to prevent.
用反馈替代恐惧:先覆盖再修改,绝不盲目编辑——仅在实际修改的路径上逐步偿还债务,且始终保持发布状态。 本技能按顺序编排各阶段,提出决策问题,并将每个选择记录在
docs/
中。各组成技能承载具体方法——请调用这些技能而非自行摸索其框架。偿还技术债务不是重建一座山,而是沿着你已在修改的路径,一步一步安全地、经过测试地推进。跳过前置步骤(比如在搭建安全网前就清理代码,在边界明确前就拆分服务)正是本流程的顺序设计要避免的失败模式。

Journey Map

流程地图

PhaseSkillQuestion it answersArtifact
1working-with-legacy-codeCan I change this code without breaking it unknowingly, and where do I start?Creates docs/TESTING.md + docs/TECH-DEBT.md — GATE
2refactoring-patternsCan I reshape structure without changing behavior?Extends docs/TECH-DEBT.md
3clean-codeIs what I touch legible to the next reader and agent?Extends docs/TECH-DEBT.md
4software-design-philosophyIs complexity hidden behind deep modules?Extends docs/TECH-DEBT.md
5clean-architectureDo business rules depend on the framework, or vice versa?Extends docs/ARCHITECTURE.md
6pragmatic-programmerWhat habits stop debt from re-accumulating?Extends docs/TECH-DEBT.md
7release-itWill it survive a hostile production?Extends docs/RELIABILITY.md
8domain-driven-designHow do I carve the monolith into bounded contexts?Extends docs/ARCHITECTURE.md
阶段技能解决的问题产出物
1working-with-legacy-code我能否在不意外破坏代码的情况下修改它?从哪里开始?创建docs/TESTING.md + docs/TECH-DEBT.md —— 必经关卡
2refactoring-patterns我能否在不改变行为的前提下重构代码结构?扩展docs/TECH-DEBT.md
3clean-code我修改的代码对下一位阅读者和Agent来说是否清晰易懂?扩展docs/TECH-DEBT.md
4software-design-philosophy复杂度是否被隐藏在深层模块之后?扩展docs/TECH-DEBT.md
5clean-architecture业务规则依赖框架,还是框架依赖业务规则?扩展docs/ARCHITECTURE.md
6pragmatic-programmer哪些习惯能防止技术债务再次累积?扩展docs/TECH-DEBT.md
7release-it它能否在复杂的生产环境中稳定运行?扩展docs/RELIABILITY.md
8domain-driven-design如何将单体应用拆分为有界上下文?扩展docs/ARCHITECTURE.md

Operating Rules

操作规则

  1. Resume first. Before anything else, read
    docs/REMOVE-TECHNICAL-DEBT-PLAN.md
    and every artifact in the Journey Map. If the tracker exists, summarize the journey state in 3-5 lines and ask which phase to enter. Done when the user has confirmed an entry point. A journey with a tracker is resumed, never restarted.
  2. Intake on first run only. No tracker: run the Intake below, then create
    docs/REMOVE-TECHNICAL-DEBT-PLAN.md
    with every phase statused
    pending | in-progress | awaiting-evidence | done | deferred: reason | skipped: reason
    . Done when the tracker exists and the user has confirmed the phase plan.
  3. Phase entry. Announce: what the phase does, the decision it forces, the artifact it produces, rough effort. Offer proceed / skip / defer — phases marked GATE may be deferred, never skipped. Mark the phase
    in-progress
    on proceed. Done when the user chose.
  4. Skill invocation and fallback. Load the phase's skill and use it: each phase's Invoke line names the skill by slug — use that skill to run the phase. If it is not available, offer:
    npx skills add wondelai/skills/<slug> --global
    . If the user declines, run the phase from its Brief — the minimum viable method. State which mode you are in.
  5. In-phase decisions. Ask every question under "Decide with the user" — with concrete options and your recommendation. Record the choice in the tracker's Key Decisions. A decision made silently is a defect.
  6. Phase exit. Present the draft artifact content for sign-off before writing. On approval: write or extend the docs/ files, update the tracker (status, Key Decisions, Next Actions). Done when the files are written and the phase row shows
    done
    .
  7. Artifact discipline. Read before writing; create a file only if missing, otherwise extend — add or update your sections, preserve everyone else's. Files are UPPERCASE in
    docs/
    . Every recommendation lands as a checkbox or a table row with owner and priority. See references/artifact-templates.md when creating a docs/ file for the first time — create it from the full skeleton (all section headings), then fill the sections your phase names.
  8. Phase 1 is a GATE, commits stay single-purpose, and found bugs get pinned not fixed. No transformation touches code absent from the Safety Net Map — pin it first (absent means not listed under Pinned behaviors; entries in the Gaps column are off-limits too). Structural and behavioral changes never share a commit: refactor with tests green in a structure-only commit, then change behavior in its own commit; a red test mid-refactoring means revert, not debug; safety-net test additions and docs/ updates are single-purpose commits of their own. Bugs found while characterizing get pinned and ticketed in the Debt Ledger, never silently fixed — callers may depend on the quirk.
  1. 优先恢复流程。首先读取
    docs/REMOVE-TECHNICAL-DEBT-PLAN.md
    和流程地图中的所有产出物。如果存在跟踪文件,用3-5行总结当前流程状态,并询问进入哪个阶段。当用户确认进入点后完成此步骤。已有跟踪文件的流程需恢复,而非重启。
  2. 仅首次运行时收集信息。若无跟踪文件:执行以下信息收集步骤,然后创建
    docs/REMOVE-TECHNICAL-DEBT-PLAN.md
    ,将每个阶段标记为
    pending | in-progress | awaiting-evidence | done | deferred: reason | skipped: reason
    。当跟踪文件存在且用户确认阶段计划后完成此步骤。
  3. 进入阶段。告知:本阶段的作用、需要做出的决策、产出的文档、大致工作量。提供继续/跳过/延期选项——标记为必经关卡的阶段可延期,但不可跳过。选择继续则将阶段标记为
    in-progress
    。当用户做出选择后完成此步骤。
  4. 调用技能与备选方案。加载对应阶段的技能并使用:每个阶段的调用行通过别名指定技能——使用该技能推进阶段。若技能不可用,提供:
    npx skills add wondelai/skills/<slug> --global
    。若用户拒绝,则使用该技能的简要说明(最小可行方法)推进阶段,并说明当前使用的模式。
  5. 阶段内决策。询问“与用户共同决策”下的所有问题——提供具体选项和你的建议。将选择记录在跟踪文件的关键决策部分。未明确做出的决策视为缺陷。
  6. 退出阶段。在写入前展示产出物草稿内容供用户确认。获得批准后:写入或扩展docs/文件,更新跟踪文件(状态、关键决策、下一步行动)。当文件写入完成且阶段行显示
    done
    后完成此步骤。
  7. 产出物规范。先读后写;仅当文件不存在时创建,否则扩展——添加或更新你的部分,保留其他人的内容。docs/中的文件为大写。每条建议以复选框或包含负责人和优先级的表格行呈现。首次创建docs/文件时,请参考references/artifact-templates.md——从完整框架(所有章节标题)创建,然后填充本阶段对应的章节。
  8. 阶段1为必经关卡,提交需保持单一目的,发现的缺陷需标记而非修复。安全网地图未涵盖的代码不可进行任何改造——先标记(未涵盖指未在已标记行为中列出;空白列中的条目也不可触碰)。结构变更和行为变更不可在同一提交中:在仅变更结构的提交中保持测试通过,然后在单独的提交中变更行为;重构过程中测试失败意味着回滚,而非调试;安全网测试添加和docs/更新需作为单独的单一目的提交。在梳理代码时发现的缺陷需标记并记录在债务台账中,绝不悄悄修复——调用方可能依赖这些异常行为。

Intake

信息收集

Ask these before creating the tracker:
  1. What does the system do, how large and old is it, and what is the worst thing that happens if it breaks? (frames risk and sets phase priority)
  2. Which file are you changing next, and which files show up most in
    git log
    churn or are core domain? (picks the Phase 1 starting module — the three-axis heuristic)
  3. Does a test suite exist, does it run green in CI today, or was it disabled as flaky? (scopes the Phase 1 safety net)
  4. What is the stack — framework, ORM, database — and is business logic tangled inside controllers or ORM models? (gates Phase 5 boundary work and Phase 8 context mapping)
  5. Is it in production with real users, and what outbound dependencies does it call — third-party APIs, payments, email, queues? (gates Phase 7 integration-point audit)
  6. Is anyone proposing a big-bang rewrite? (surfaces the decision this journey exists to replace with the incremental path)
  7. How much of the journey do you want now? (Phases 1-3 change the team's relationship with the code fastest; 5-8 as boundaries and decomposition become the bottleneck)
Phase-skip heuristics: skip Phase 8 when the codebase is small enough that a single model still fits comfortably. Add optional system-design or ddia-systems only when paydown surfaces real scaling or data-layer limits — start from requirements, not solutions. Phase 7 is not optional once real users exist — timeouts and a circuit breaker are table stakes (it may stay
deferred: reason
, never
skipped
). Never skip Phase 1; it is the gate. Then create the tracker from the template and confirm the plan.
Done when
docs/REMOVE-TECHNICAL-DEBT-PLAN.md
exists with every phase statused and the user has confirmed the plan.
创建跟踪文件前需询问以下问题:
  1. 系统的功能是什么?规模和使用年限如何?如果系统故障,最严重的后果是什么?(确定风险并设置阶段优先级)
  2. 你接下来要修改哪个文件?哪些文件在
    git log
    中变更最频繁,或是核心领域文件?(选择阶段1的起始模块——三维启发式方法)
  3. 是否存在测试套件?它目前在CI中能否正常运行,还是因不稳定被禁用?(确定阶段1安全网的范围)
  4. 技术栈是什么——框架、ORM、数据库?业务逻辑是否混杂在控制器或ORM模型中?(为阶段5的边界工作和阶段8的上下文映射设置关卡)
  5. 它是否已投入生产并面向真实用户?它调用哪些外部依赖——第三方API、支付系统、邮件服务、队列?(为阶段7的集成点审计设置关卡)
  6. 是否有人提议大规模重写?(揭示本流程旨在替代的决策,提供增量式路径)
  7. 你现在希望推进流程的多少阶段?(阶段1-3能最快改变团队与代码的关系;当边界和拆分成为瓶颈时推进阶段5-8)
阶段跳过启发式规则:当代码库足够小,单个模型仍能轻松容纳时,跳过阶段8。仅当债务偿还过程中出现实际的扩展或数据层限制时,才添加可选的system-design或ddia-systems技能——从需求出发,而非解决方案。一旦面向真实用户,阶段7不可选——超时和Circuit Breaker是必备项(可标记为
deferred: reason
,但不可标记为
skipped
)。绝不能跳过阶段1;它是必经关卡。然后从模板创建跟踪文件并确认计划。
docs/REMOVE-TECHNICAL-DEBT-PLAN.md
存在且每个阶段都已标记状态,且用户确认计划后完成此步骤。

Phases

各阶段详情

Phase 1 — Build the safety net and find where to start (working-with-legacy-code) — GATE

阶段1 — 构建安全网并确定起始点(working-with-legacy-code)—— 必经关卡

Purpose: Pin current behavior at your change points and map blast radius, so every later phase is verifiable. No phase may touch code absent from the Safety Net Map.
Brief (fallback): Legacy code is code without tests — cover and modify, never edit and pray. Run the Legacy Code Change Algorithm: identify change points, find test points, break dependencies with the least-invasive seam (Parameterize Constructor with a production default; Extract Interface), write characterization tests that pin actual behavior (assert something wrong, read the failure, pin the real value), then change. Bound blast radius with an effect sketch; find the pinch point where a few tests cover the most behavior. Urgent change you can't cover in time: Sprout/Wrap and track the untested host as debt.
Invoke: Use the
working-with-legacy-code
skill with the starting module chosen at intake. Ask for an effect sketch from the entry method, the pinch points, the seams to break, and the smallest characterization-test set that pins current behavior.
Decide with the user: (1) Confirm the starting module by the three-axis heuristic — changing next, high churn (
git log
), core domain. (2) Bugs found while characterizing: pin the wrong behavior and file it in the Debt Ledger, never silently fix — callers may depend on the quirk. Confirm the user accepts this.
Artifact: Create docs/TESTING.md with
## Test Strategy
,
## Safety Net Map
(module | pinned behaviors | test files | gaps), and
## Characterization Backlog
; create docs/TECH-DEBT.md with
## Debt Ledger
(item | location | type | risk | effort | priority | status) and
## Sprout / Wrap Register
, registering any sprouted or wrapped code. Record the effect-sketch pinch points under
## Test Strategy
. Update the tracker.
Done when: the target module's behavior is pinned, the suite runs green, both files exist, and the tracker shows Phase 1 done — only then is Phase 2 unlocked.
目标: 在你的变更点标记当前行为并影响范围,确保后续每个阶段都可验证。任何阶段都不可触碰安全网地图未涵盖的代码。
简要说明(备选方案): 遗留代码是没有测试的代码——先覆盖再修改,绝不盲目编辑。执行遗留代码变更算法:确定变更点,找到测试点,用侵入性最小的接缝打破依赖(带生产默认值的参数化构造函数;提取接口),编写表征测试标记实际行为(断言错误内容,读取失败信息,标记真实值),然后进行修改。用影响草图界定影响范围;找到少量测试即可覆盖大部分行为的关键点。若紧急变更无法及时覆盖:使用Sprout/Wrap方法,并将未测试的主体标记为债务。
调用: 使用
working-with-legacy-code
技能,搭配信息收集阶段选择的起始模块。请求从入口方法生成影响草图、关键点、需打破的接缝,以及能标记当前行为的最小表征测试集。
与用户共同决策: (1) 通过三维启发式方法确认起始模块——即将修改、高变更频率(
git log
)、核心领域。(2) 梳理代码时发现的缺陷:标记错误行为并记录在债务台账中,绝不悄悄修复——调用方可能依赖这些异常行为。确认用户接受此规则。
产出物: 创建docs/TESTING.md,包含
## Test Strategy
## Safety Net Map
(模块 | 已标记行为 | 测试文件 | 空白项)和
## Characterization Backlog
;创建docs/TECH-DEBT.md,包含
## Debt Ledger
(条目 | 位置 | 类型 | 风险 | 工作量 | 优先级 | 状态)和
## Sprout / Wrap Register
,记录所有使用Sprout或Wrap方法的代码。在
## Test Strategy
下记录影响草图的关键点。更新跟踪文件。
完成标志: 目标模块的行为已标记,测试套件运行通过,两个文件均已创建,跟踪文件显示阶段1完成——此时阶段2才会解锁。

Phase 2 — Restructure with named refactorings (refactoring-patterns)

阶段2 — 使用命名重构模式调整结构(refactoring-patterns)

Purpose: Turn "clean it up" into named, behavior-preserving transformations applied one small step at a time.
Brief (fallback): Refactoring is not rewriting: small behavior-preserving transformations, each backed by tests. Each smell maps to a named refactoring — Extract Method is the workhorse (if you'd write a comment to explain a block, extract it and name it after the comment). Also Replace Nested Conditional with Guard Clauses, Replace Conditional with Polymorphism, Introduce Parameter Object, Extract Class. Workflow: tests green, one transformation, tests green, commit; a red test means revert, not debug. Branch by Abstraction migrates large structures in production; Preparatory Refactoring makes the change easy first; Rule of Three guards against premature abstraction.
Invoke: Use the
refactoring-patterns
skill with a smelly module and the Phase 1 tests. Ask it to name each smell, cite the transformation, and apply one at a time with tests run between each; for a large migration ask for a Branch by Abstraction plan.
Decide with the user: Scope — which smells this pass; whether an upcoming feature warrants a Preparatory Refactoring at its insertion point first; and whether a big migration should go behind a Branch by Abstraction.
Artifact: Extend docs/TECH-DEBT.md
## Smell Inventory
(smell | location | refactoring | status): one row per smell with the named refactoring applied and its status. Update the tracker.
Done when: targeted smells show a named refactoring and
done
/
ticketed
status, tests are green, and every structural change landed in a structure-only commit.
目标: 将“清理代码”转化为可命名的、不改变行为的小步改造,逐一应用。
简要说明(备选方案): 重构不是重写:小步的、不改变行为的改造,每一步都有测试支持。每个代码异味对应一种命名重构——提取方法是核心工具(如果你需要写注释解释代码块,就提取它并以注释内容命名)。还包括用卫语句替换嵌套条件、用多态替换条件、引入参数对象、提取类。工作流程:测试通过,进行一次改造,测试通过,提交;测试失败意味着回滚,而非调试。分支抽象法可在生产环境中迁移大型结构;预备重构先让变更变得容易;三次法则避免过早抽象。
调用: 使用
refactoring-patterns
技能,搭配有异味的模块和阶段1的测试。请求命名每个代码异味,引用对应的改造方法,并逐一应用,每次应用后运行测试;若进行大型迁移,请求分支抽象法计划。
与用户共同决策: 范围——本次处理哪些代码异味;即将开发的功能是否需要在插入点先进行预备重构;大型迁移是否应采用分支抽象法。
产出物: 扩展docs/TECH-DEBT.md的
## Smell Inventory
(异味 | 位置 | 重构方法 | 状态):每个异味对应一行,记录应用的命名重构方法及其状态。更新跟踪文件。
完成标志: 目标异味已记录命名重构方法和
done
/
ticketed
状态,测试通过,所有结构变更均在仅变更结构的提交中完成。

Phase 3 — Raise legibility where you touch the code (clean-code)

阶段3 — 提升修改区域的代码可读性(clean-code)

Purpose: Optimize for the reader — names, small single-purpose functions, safe error handling — on the regions you are already changing.
Brief (fallback): Code is read far more than written (10:1+). Names reveal intent (
elapsedTimeInDays
, not
d
); booleans read as predicates; one word per concept; functions do one thing at one level of abstraction with 0-2 arguments (a flag argument is two functions). Command-Query Separation: change state or return a value, never both. Error handling is where legacy incidents hide: prefer exceptions to return codes, catch specific types, never return or pass null (empty collection, Optional, Null Object), wrap noisy third-party APIs behind an adapter, put operation + state in every error. Boy Scout Rule: leave code cleaner than you found it.
Invoke: Use the
clean-code
skill with a target module. Ask for a 0-10 score across the six disciplines, the top ten fixes in priority order, and an error-handling audit (bare catches, null returns, contextless errors, unwrapped third-party SDKs).
Decide with the user: Which fixes to apply now versus log as debt, and the naming / error-handling conventions the team adopts going forward.
Artifact: Extend docs/TECH-DEBT.md: add
## Smell Inventory
rows for each name / function / error smell, and record the agreed rules under
## Adopted Conventions
. Update the tracker.
Done when: the module scores 8+ or every gap below 8 is a Smell Inventory row with a fix, conventions are recorded, and the Phase 1 tests still pass.
目标: 为阅读者优化——命名、小巧单一职责的函数、安全的错误处理——针对你正在修改的区域。
简要说明(备选方案): 代码的阅读次数远多于编写次数(10:1以上)。命名需体现意图(
elapsedTimeInDays
,而非
d
);布尔值需作为谓词阅读;一个概念对应一个词;函数仅做一件事,处于同一抽象层级,参数为0-2个(标志参数相当于两个函数)。命令查询分离:要么改变状态,要么返回值,不可两者兼具。错误处理是遗留代码事故的隐藏点:优先使用异常而非返回码,捕获特定类型,绝不返回或传递null(使用空集合、Optional、空对象),将繁琐的第三方API包装在适配器后,每个错误都包含操作+状态。童子军规则:让代码比你发现时更整洁。
调用: 使用
clean-code
技能,搭配目标模块。请求对六项准则进行0-10分评分,按优先级列出前十项修复,以及错误处理审计(裸捕获、返回null、无上下文错误、未包装的第三方SDK)。
与用户共同决策: 哪些修复现在应用,哪些记录为债务;团队后续采用的命名/错误处理规范。
产出物: 扩展docs/TECH-DEBT.md:为每个命名/函数/错误异味添加
## Smell Inventory
行,并在
## Adopted Conventions
下记录商定的规则。更新跟踪文件。
完成标志: 模块评分达到8分以上,或8分以下的每个差距都在Smell Inventory中记录了修复方案,规范已记录,且阶段1的测试仍能通过。

Phase 4 — Reduce complexity with deep modules (software-design-philosophy)

阶段4 — 用深层模块降低复杂度(software-design-philosophy)

Purpose: Attack the complexity itself — hide real machinery behind simple interfaces instead of the classitis an unsupervised agent creates.
Brief (fallback): Complexity is the enemy; judge every change by whether it raises or lowers overall complexity. Symptoms: change amplification, cognitive load, unknown unknowns. Module depth = functionality ÷ interface complexity; deep modules hide machinery behind small interfaces, shallow ones don't (classitis) — merge shallow classes that always travel together. Watch information leakage (one decision reflected across many modules) and temporal decomposition (organizing by order-of-execution, not by knowledge). This is the tactical→strategic flip: invest 10-20% to keep the design clean.
Invoke: Use the
software-design-philosophy
skill with the module set touched so far. Ask which classes are shallow, where a design decision leaks across modules, and how to consolidate into deeper modules with simpler interfaces — with each change labeled as raising or lowering complexity.
Decide with the user: Which consolidations to make now versus defer, guarding against over-merging genuinely unrelated concerns.
Artifact: Extend docs/TECH-DEBT.md
## Smell Inventory
with classitis / shallow-module / information-leakage entries and the consolidation applied. Update the tracker.
Done when: each shallow-module cluster is consolidated or logged with a fix, interface count did not grow for the sake of "modularity", and tests are green.
目标: 直接解决复杂度问题——将实际逻辑隐藏在简单接口后,而非让无监督Agent创建过多零散类。
简要说明(备选方案): 复杂度是敌人;每项变更都需判断是增加还是降低整体复杂度。症状:变更放大、认知负荷、未知未知。模块深度 = 功能 ÷ 接口复杂度;深层模块将逻辑隐藏在小接口后,浅层模块则不然(类膨胀)——合并始终一起使用的浅层类。注意信息泄露(一个决策体现在多个模块中)和时间分解(按执行顺序而非知识组织)。这是从战术到战略的转变:投入10-20%的精力保持设计整洁。
调用: 使用
software-design-philosophy
技能,搭配目前已修改的模块集。请求指出哪些类是浅层的,哪些设计决策在模块间泄露,以及如何合并为接口更简单的深层模块——每项变更需标记为增加或降低复杂度。
与用户共同决策: 哪些合并现在进行,哪些延期,避免过度合并真正无关的关注点。
产出物: 扩展docs/TECH-DEBT.md的
## Smell Inventory
,添加类膨胀/浅层模块/信息泄露条目及应用的合并方案。更新跟踪文件。
完成标志: 每个浅层模块集群已合并或记录了修复方案,接口数量未因“模块化”而增加,测试通过。

Phase 5 — Draw the dependency boundary (clean-architecture)

阶段5 — 绘制依赖边界(clean-architecture)

Purpose: Make the framework and database depend on the business rules, module by module — not the reverse.
Brief (fallback): The Dependency Rule: source dependencies point inward — Entities, Use Cases, Interface Adapters, Frameworks/Drivers; nothing inner names anything outer. Database and web are details, plugins to your rules. Enforce with Dependency Inversion: a Use Case owns a repository interface; the Postgres/Stripe implementation lives in an outer adapter. SOLID are the mid-level tools; Common Closure and Acyclic Dependencies find real boundaries. Microservices sharing one data model are a distributed monolith — apply the rule inside the monolith first.
Invoke: Use the
clean-architecture
skill with the current module map and the stack from intake. Ask it to map the dependency graph, list every violation where business logic imports the ORM or framework, pick the most-changed module first, and show the extraction to framework-free Use Cases behind owned interfaces.
Decide with the user: How far to push the boundary this pass; which vendors (payments, storage) to wrap first; and whether any proposed service split is a real boundary or would only add a distributed monolith.
Artifact: Extend docs/ARCHITECTURE.md: record layers and violations under
## Layer Map & Dependency Rule
(violation | location | fix | status) and the boundary choices under
## Decision Log
. Update the tracker.
Done when: every Dependency Rule violation is a tracked row with a fix, at least the highest-risk vendor is wrapped, business-rule tests run with no framework, and tests are green.
目标: 让框架和数据库依赖业务规则,逐个模块实现——而非反过来。
简要说明(备选方案): 依赖规则:源码依赖指向内部——实体、用例、接口适配器、框架/驱动;内部模块绝不引用外部模块的内容。数据库和Web是细节,是业务规则的插件。通过依赖倒置原则实现:用例拥有仓库接口;Postgres/Stripe的实现位于外部适配器中。SOLID是中层工具;共同闭包和无环依赖可找到真实边界。共享一个数据模型的微服务是分布式单体应用——先在单体应用内部应用该规则。
调用: 使用
clean-architecture
技能,搭配当前模块地图和信息收集阶段的技术栈。请求绘制依赖图,列出所有业务逻辑引用ORM或框架的违规项,优先选择变更最频繁的模块,并展示将其提取为无框架用例、置于自有接口后的方案。
与用户共同决策: 本次边界推进的程度;优先包装哪些供应商(支付、存储);提议的服务拆分是否为真实边界,还是只会增加分布式单体应用的问题。
产出物: 扩展docs/ARCHITECTURE.md:在
## Layer Map & Dependency Rule
(违规项 | 位置 | 修复方案 | 状态)下记录层级和违规项,在
## Decision Log
下记录边界选择。更新跟踪文件。
完成标志: 每个依赖规则违规项都已记录修复方案,至少最高风险的供应商已被包装,业务规则测试无需框架即可运行,测试通过。

Phase 6 — Lock in the habits (pragmatic-programmer)

阶段6 — 固化良好习惯(pragmatic-programmer)

Purpose: Set the meta-principles that stop the codebase from silently re-accruing debt after this journey ends.
Brief (fallback): Broken Window Theory: one unrepaired hack drops the bar for the next — fix immediately or board it up with a tracked ticket, never an untracked
// TODO
. DRY is about knowledge, not text — de-duplicate the same rule in two places (validation on client and server), leave coincidental look-alikes alone. Orthogonality: changing one component shouldn't affect another. Reversibility: wrap vendors behind your own interfaces. Design by Contract + crash early: guard preconditions and invariants at hardened boundaries so an invalid state fails loudly at the source.
Invoke: Use the
pragmatic-programmer
skill across the codebase. Ask it to flag duplicated knowledge (ignoring coincidental duplication), broken windows and untracked TODOs to board up, and the boundaries that need Design-by-Contract guard clauses.
Decide with the user: The debt budget per iteration and the broken-windows policy — what gets fixed now versus ticketed.
Artifact: Extend docs/TECH-DEBT.md: record duplicated-knowledge and broken-window items in
## Debt Ledger
, and the agreed policy under
## Debt Budget & Broken-Windows Policy
and
## Adopted Conventions
. Update the tracker.
Done when: duplicated-knowledge hits are ledgered or fixed, no untracked hacks remain, and the debt-budget policy is written down.
目标: 设定元原则,防止流程结束后代码库再次悄悄累积技术债务。
简要说明(备选方案): 破窗理论:一个未修复的 hack 会降低下一个 hack 的标准——立即修复或用跟踪工单标记,绝不留下未跟踪的
// TODO
。DRY是关于知识,而非文本——消除同一规则在两处的重复(客户端和服务端的验证),保留偶然的相似代码。正交性:修改一个组件不应影响另一个组件。可逆性:将供应商包装在自有接口后。契约式设计+尽早崩溃:在强化边界处守卫前置条件和不变量,使无效状态在源头就明显失败。
调用: 使用
pragmatic-programmer
技能遍历整个代码库。请求标记重复知识(忽略偶然重复)、需标记的破窗和未跟踪的TODO,以及需要契约式设计守卫条款的边界。
与用户共同决策: 每次迭代的债务预算,以及破窗政策——哪些现在修复,哪些记录为工单。
产出物: 扩展docs/TECH-DEBT.md:在
## Debt Ledger
中记录重复知识和破窗条目,在
## Debt Budget & Broken-Windows Policy
## Adopted Conventions
下记录商定的政策。更新跟踪文件。
完成标志: 重复知识已记录或修复,无未跟踪的hack,债务预算政策已书面记录。

Phase 7 — Harden the integration points (release-it)

阶段7 — 强化集成点(release-it)

Purpose: Make every integration point degrade gracefully so a slow or failing dependency can't take the whole system down.
Brief (fallback): The software that passes QA is not what survives production. Integration points are the number-one killer — a slow response is worse than none. Non-negotiables: connect + read timeouts on every outbound call; a Circuit Breaker on failing dependencies (trips open, fails fast, half-open recovery); Bulkheads to isolate resource pools; Retry with exponential backoff + jitter; Steady State cleanup of accumulating cruft. Bound every query — unbounded result sets crash at scale, so add LIMITs and pagination. Decouple deploy from release with feature flags and expand-contract migrations; add deep health checks, RED metrics, symptom-based alerts.
Invoke: Use the
release-it
skill with the outbound dependencies from intake. Ask for an audit of calls with no timeout, unbounded queries and list endpoints, circuit-breaker + bulkhead placement, an expand-contract migration plan for a risky schema, and a deep health check + RED metrics + alert design.
Decide with the user: Breaker thresholds, which dependencies get dedicated pools, and the alert symptoms and thresholds (error rate, latency).
Artifact: Extend docs/RELIABILITY.md with
## Integration-Point Audit
(dependency | timeout | circuit breaker | bulkhead | retry policy | status),
## Query & Resource Findings
,
## Health Checks & Metrics
, and
## Deploy vs Release
. Update the tracker.
Done when: every outbound call has a timeout, critical dependencies have breakers and bulkheads, unbounded queries are bounded, a deep health check + RED metrics + symptom alerts exist, and the audit has no open rows for critical paths.
目标: 让每个集成点都能优雅降级,避免缓慢或故障的依赖拖垮整个系统。
简要说明(备选方案): 通过QA的软件不一定能在生产环境存活。集成点是头号杀手——缓慢响应比无响应更糟。必备项:每个外部调用都设置连接+读取超时;对故障依赖使用Circuit Breaker(触发断开、快速失败、半开恢复);使用隔离舱隔离资源池;带指数退避+抖动的重试;定期清理累积的冗余内容。限制每个查询——无限制结果集会在规模扩大时崩溃,因此添加LIMIT和分页。用功能标志和扩缩迁移解耦部署与发布;添加深度健康检查、RED指标、基于症状的告警。
调用: 使用
release-it
技能,搭配信息收集阶段的外部依赖。请求审计无超时的调用、无限制查询和列表端点、Circuit Breaker+隔离舱的位置、高风险模式的扩缩迁移计划,以及深度健康检查+RED指标+告警设计。
与用户共同决策: 断路器阈值,哪些依赖使用专用资源池,以及告警症状和阈值(错误率、延迟)。
产出物: 扩展docs/RELIABILITY.md,包含
## Integration-Point Audit
(依赖 | 超时 | 断路器 | 隔离舱 | 重试策略 | 状态)、
## Query & Resource Findings
## Health Checks & Metrics
## Deploy vs Release
。更新跟踪文件。
完成标志: 每个外部调用都设置了超时,关键依赖配备了断路器和隔离舱,无限制查询已被限制,存在深度健康检查+RED指标+基于症状的告警,审计中关键路径无未完成条目。

Phase 8 — Carve into bounded contexts (domain-driven-design)

阶段8 — 拆分为有界上下文(domain-driven-design)

Purpose: Decompose the big ball of mud into contexts the team can own and eventually extract — without a rewrite.
Brief (fallback): The model is the code. Start with Ubiquitous Language: rename technical-only names (
DataManager
,
Helper
) to domain terms; a concept hard to name signals a wrong model. Map Bounded Contexts (the same word can mean different things in different contexts) starting from what exists, aligned with team boundaries. The Anti-Corruption Layer lets a clean new context talk to the legacy core without the old model leaking in — the foundation of the Strangler Fig. Inside a context: small Aggregates with one root, reference others by ID, immutable Value Objects, past-tense Domain Events. Invest hardest in the Core Domain.
Invoke: Use the
domain-driven-design
skill with the tangled modules and the boundaries from Phase 5. Ask it to build a ubiquitous language, map current and target bounded contexts, design an anti-corruption layer for a new clean context, and shrink any god aggregate to its true consistency boundary.
Decide with the user: Which context to carve first (the Core Domain where value lives); which boundaries align with team structure; and whether cross-context calls become Domain Events.
Artifact: Extend docs/ARCHITECTURE.md: record the map under
## Bounded Contexts & Context Map
, terms under
## Domain Glossary (Ubiquitous Language)
, and the decomposition choices under
## Decision Log
. Update the tracker.
Done when: the current context map is drawn, the first target context and its anti-corruption layer are defined, key domain terms are in the glossary, and any reshaped aggregate keeps tests green.
目标: 将混乱的单体应用拆分为团队可独立拥有并最终提取的上下文——无需重写。
简要说明(备选方案): 模型即代码。从通用语言开始:将纯技术名称(
DataManager
Helper
)重命名为领域术语;难以命名的概念表明模型存在问题。从现有代码出发,结合团队边界绘制有界上下文(同一词汇在不同上下文可能有不同含义)。防腐层让新的整洁上下文与遗留核心通信,同时避免旧模型渗透——这是绞杀者模式的基础。在上下文内部:小型聚合根,通过ID引用其他聚合根,不可变值对象,过去式领域事件。在核心领域投入最多精力。
调用: 使用
domain-driven-design
技能,搭配混乱的模块和阶段5的边界。请求构建通用语言,绘制当前和目标有界上下文,为新的整洁上下文设计防腐层,将上帝聚合缩小到其真实一致性边界。
与用户共同决策: 首先拆分哪个上下文(价值所在的核心领域);哪些边界与团队结构对齐;跨上下文调用是否应变为领域事件。
产出物: 扩展docs/ARCHITECTURE.md:在
## Bounded Contexts & Context Map
下记录地图,在
## Domain Glossary (Ubiquitous Language)
下记录术语,在
## Decision Log
下记录拆分选择。更新跟踪文件。
完成标志: 当前上下文地图已绘制,第一个目标上下文及其防腐层已定义,关键领域术语已纳入术语表,任何重构后的聚合仍保持测试通过。

Optional Phases

可选阶段

SkillAdd whenArtifact
system-designPaydown reveals real scaling limits that need re-architectureExtends docs/ARCHITECTURE.md (
## System Context
)
ddia-systemsData-layer decisions (isolation, replication, storage fit) are part of the debtExtends docs/ARCHITECTURE.md (
## Data & Storage Decisions
)
team-topologiesDebt clusters where team boundaries fight the architectureExtends docs/OPERATIONS.md (
## Team Structure
)
Optional phases follow the same operating rules — load and use each listed skill exactly as a core phase would; insert where the Add-when condition first becomes true — the scaling and data phases after Phase 5, the team-topology phase alongside Phase 8's context boundaries.
技能添加时机产出物
system-design债务偿还过程中出现需要重新架构的实际扩展限制扩展docs/ARCHITECTURE.md(
## System Context
ddia-systems数据层决策(隔离、复制、存储适配)属于技术债务的一部分扩展docs/ARCHITECTURE.md(
## Data & Storage Decisions
team-topologies技术债务集中在团队边界与架构冲突的区域扩展docs/OPERATIONS.md(
## Team Structure
可选阶段遵循相同的操作规则——完全按照核心阶段的方式加载和使用每个列出的技能;在“添加时机”条件首次满足时插入——扩展和数据阶段在阶段5之后,团队拓扑阶段与阶段8的上下文边界同步进行。

Common Mistakes

常见错误

MistakeFix
Proposing the big-bang rewriteCommit to paying debt down in place; every phase leaves the system better and still shipping, worst case a fast revert. Show one small, fast win first.
Cleaning before writing a single testPin behavior with characterization tests in Phase 1 (working-with-legacy-code) first; coverage follows the paths you actually change.
Trying to fix everything at onceTriage by the three-axis heuristic — invest where change is frequent and the Core Domain lives; a one-off spot gets a sprout, not a refactor.
Letting the agent "modularize" into tiny classesHold it to software-design-philosophy's deep-module rule — merge shallow classes that travel together; that is classitis, not architecture.
Calling external services with no timeoutIn Phase 7 (release-it) add connect + read timeouts on every outbound call, plus a circuit breaker on critical dependencies.
Mistaking microservices for architectureApply the Dependency Rule and find real bounded contexts inside the monolith first (clean-architecture, domain-driven-design); services sharing one database are a distributed monolith.
错误修复方案
提议大规模重写承诺在现有基础上偿还技术债务;每个阶段都让系统变得更好且保持可发布状态,最坏情况可快速回滚。先展示一个小而快的成果。
未编写任何测试就清理代码先在阶段1(working-with-legacy-code)用表征测试标记行为;覆盖范围跟随你实际修改的路径。
试图一次性修复所有问题通过三维启发式方法进行分类——在变更频繁且属于核心领域的地方投入精力;一次性修改的地方使用Sprout方法,而非重构。
让Agent“模块化”为大量零散类遵循software-design-philosophy的深层模块规则——合并始终一起使用的浅层类;那是类膨胀,而非架构。
调用外部服务未设置超时在阶段7(release-it)为每个外部调用添加连接+读取超时,为关键依赖添加Circuit Breaker。
将微服务误认为架构先在单体应用内部应用依赖规则并找到真实有界上下文(clean-architecture、domain-driven-design);共享一个数据库的服务是分布式单体应用。

Completing the Journey

流程完成

Exit checklist — every box tied to an artifact:
  • Changed modules have characterization tests that run green (TESTING.md Safety Net Map complete for the paths you touched).
  • Every outbound call has a timeout and critical dependencies have circuit breakers and bulkheads (RELIABILITY.md Integration-Point Audit clear).
  • The Dependency Rule holds for reworked modules — business logic imports no framework or ORM (ARCHITECTURE.md Layer Map, violations closed).
  • The monolith has a current context map and at least one clean context behind an anti-corruption layer (ARCHITECTURE.md Bounded Contexts & Context Map).
  • No untracked hacks remain; the debt budget and broken-windows policy are written down (TECH-DEBT.md Debt Budget & Broken-Windows Policy).
Close the tracker: every phase
done
or
skipped: reason
, with remaining Next Actions carried into the TECH-DEBT.md Debt Ledger so nothing is lost. Then route forward: when the starting point was a younger prototype and you want the production-readiness variant of this journey, continue with the
improve-code-quality
skill; when code health is restored and the product experience is next, continue with the
improve-app
skill.
退出检查清单——每个条目都关联产出物:
  • 修改过的模块有运行通过的表征测试(TESTING.md的安全网地图涵盖你修改的路径)。
  • 每个外部调用都设置了超时,关键依赖配备了断路器和隔离舱(RELIABILITY.md的集成点审计无未完成条目)。
  • 重构后的模块遵循依赖规则——业务逻辑不引用框架或ORM(ARCHITECTURE.md的层级地图,违规项已关闭)。
  • 单体应用有当前上下文地图,且至少有一个整洁上下文位于防腐层之后(ARCHITECTURE.md的有界上下文与上下文地图)。
  • 无未跟踪的hack;债务预算和破窗政策已书面记录(TECH-DEBT.md的债务预算与破窗政策)。
关闭跟踪文件:每个阶段标记为
done
skipped: reason
,剩余的下一步行动纳入TECH-DEBT.md的债务台账,确保无遗漏。然后引导后续流程:如果起始点是较新的原型,想要本流程的生产就绪版本,请继续使用
improve-code-quality
技能;如果代码健康已恢复,下一步优化产品体验,请继续使用
improve-app
技能。