design-code-architecture
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDesign Code Architecture
代码架构设计
Design the architecture for a new app: get the small number of expensive-to-reverse decisions right and stay aggressively simple everywhere else. This is an interactive, resumable journey of eight phases — the agent asks before every decision and records the outcome in your project's folder, so you can stop after any phase and resume later. It runs from the most foundational and hardest-to-reverse (boundaries, domain) through the tunable (data, resilience) to the cross-cutting disciplines (complexity, reversibility, scope) you apply throughout. A weekend project uses three phases lightly; a funded team building toward launch wants the whole stack.
docs/为新应用设计架构:精准敲定少数难以回滚的关键决策,其余部分保持极致简洁。这是一个包含八个阶段的交互式可续流程——Agent会在每个决策前提问,并将结果记录在项目的文件夹中,你可在任意阶段暂停并后续继续。流程从最基础、最难回滚的内容(边界、领域),过渡到可调整的内容(数据、弹性),再到贯穿始终的跨领域原则(复杂度、可回滚性、范围)。周末项目可简化使用三个阶段;筹备上线的资金团队则需要完整执行全流程。
docs/Core Principle
核心原则
Architecture is the set of decisions that are expensive to reverse: make exactly those deliberately, and defer everything cheap. This skill sequences the phases, asks the decision questions, and records every choice in . The constituent skills carry the method — invoke them rather than improvising their frameworks. The whole strategy is to convert expensive decisions into cheap ones by putting a boundary in front of them, so the irreducibly expensive set stays small enough to get right with care.
docs/架构是指难以回滚的决策集合:仅针对这些决策进行审慎规划,其余所有可回滚决策均延后处理。 本技能按顺序排列各阶段,提出决策问题,并将每一项选择记录在文件夹中。各子技能承载具体方法——请直接调用这些技能,而非自行摸索框架。整体策略是通过在决策前设置边界,将昂贵决策转化为廉价决策,从而让必须审慎处理的不可回滚决策集合保持在可控范围内。
docs/Journey Map
流程路线图
| Phase | Skill | Question it answers | Artifact |
|---|---|---|---|
| 1 | clean-architecture | Do source-code dependencies point inward — is the core testable with no DB, web, or framework? | Creates docs/ARCHITECTURE.md |
| 2 | domain-driven-design | Where does the business actually split, and what does each term mean? | Extends docs/ARCHITECTURE.md |
| 3 | system-design | How little system does our real load actually need? | Extends docs/ARCHITECTURE.md |
| 4 | ddia-systems | Which data model, storage engine, and consistency does each workload need? | Extends docs/ARCHITECTURE.md |
| 5 | software-design-philosophy | Is complexity hidden behind deep modules, or is this classitis? | Extends docs/TECH-DEBT.md |
| 6 | release-it | Will it degrade gracefully when a dependency is slow or down? | Creates docs/RELIABILITY.md |
| 7 | pragmatic-programmer | What thin slice proves the boundaries, and what habits keep them reversible? | Extends docs/TESTING.md + docs/TECH-DEBT.md |
| 8 | 37signals-way | What is essential for v1, and what speculative abstraction do we cut? | Extends docs/ARCHITECTURE.md + docs/TECH-DEBT.md |
| 阶段 | 技能 | 要解决的问题 | 产出物 |
|---|---|---|---|
| 1 | clean-architecture | 源代码依赖是否指向内部——核心模块能否在无需DB、Web或框架的情况下完成测试? | 创建docs/ARCHITECTURE.md |
| 2 | domain-driven-design | 业务的实际划分边界在哪里?每个术语的具体含义是什么? | 扩展docs/ARCHITECTURE.md |
| 3 | system-design | 实际负载所需的最小系统规模是多少? | 扩展docs/ARCHITECTURE.md |
| 4 | ddia-systems | 每个工作负载需要哪种数据模型、存储引擎和一致性保障? | 扩展docs/ARCHITECTURE.md |
| 5 | software-design-philosophy | 复杂度是否隐藏在深层模块中,还是陷入了“类膨胀”问题? | 扩展docs/TECH-DEBT.md |
| 6 | release-it | 当依赖服务响应缓慢或宕机时,系统能否优雅降级? | 创建docs/RELIABILITY.md |
| 7 | pragmatic-programmer | 哪些精简流程可验证边界合理性?哪些习惯能保持架构的可回滚性? | 扩展docs/TESTING.md + docs/TECH-DEBT.md |
| 8 | 37signals-way | v1版本的核心功能是什么?需要砍掉哪些投机性抽象? | 扩展docs/ARCHITECTURE.md + docs/TECH-DEBT.md |
Operating Rules
操作规则
- Resume first. Before anything else, read 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.
docs/DESIGN-CODE-ARCHITECTURE-PLAN.md - Intake on first run only. No tracker: run the Intake below, then create with every phase statused
docs/DESIGN-CODE-ARCHITECTURE-PLAN.md. Done when the tracker exists and the user has confirmed the phase plan.pending | in-progress | awaiting-evidence | done | deferred: reason | skipped: reason - 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 on proceed. Done when the user chose.
in-progress - 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: . If the user declines, run the phase from its Brief — the minimum viable method. State which mode you are in.
npx skills add wondelai/skills/<slug> --global - 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.
- 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 - 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 . 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.
docs/ - Every expensive-to-reverse decision gets a Decision Log row (decision, why, alternatives rejected) before any code assumes it. Default to a modular monolith: services split only along proven bounded contexts.
- 优先恢复流程。在任何操作前,先读取和流程路线图中的所有产出物。若存在跟踪文件,用3-5行总结当前流程状态,并询问进入哪个阶段。当用户确认进入点后完成此步骤。已有跟踪文件的流程需恢复,不得重启。
docs/DESIGN-CODE-ARCHITECTURE-PLAN.md - 仅首次运行时进行初始调研。若无跟踪文件:执行下方的初始调研,然后创建,将每个阶段标记为
docs/DESIGN-CODE-ARCHITECTURE-PLAN.md。当跟踪文件创建完成且用户确认阶段计划后完成此步骤。pending | in-progress | awaiting-evidence | done | deferred: reason | skipped: reason - 阶段进入。告知用户:本阶段的作用、需敲定的决策、产出的文档、大致工作量。提供继续/跳过/延后选项——标记为GATE的阶段可延后,但不得跳过。选择继续则将阶段标记为。当用户做出选择后完成此步骤。
in-progress - 技能调用与备选方案。加载对应阶段的技能并使用:每个阶段的调用行通过别名指定技能——使用该技能执行阶段流程。若技能不可用,提供命令:。若用户拒绝,使用该技能的简要说明执行阶段流程——即最小可行方法。说明当前使用的模式。
npx skills add wondelai/skills/<slug> --global - 阶段内决策。询问“与用户决策”下的所有问题——提供具体选项及推荐方案。将选择记录在跟踪文件的“关键决策”部分。未经询问直接做出的决策视为缺陷。
- 阶段退出。在写入前呈现文档草稿供用户确认。获得批准后:写入或扩展docs/文件夹下的文件,更新跟踪文件(状态、关键决策、下一步行动)。当文件写入完成且阶段标记为后完成此步骤。
done - 文档规范。先读后写;仅在文件不存在时创建,否则进行扩展——添加或更新你的部分,保留其他所有内容。docs/文件夹下的文件均为大写。每条建议需以复选框或带负责人和优先级的表格行形式呈现。首次创建docs/文件时,请参考references/artifact-templates.md——从完整骨架(所有章节标题)创建,然后填充当前阶段对应的章节。
- 所有难以回滚的决策,在代码依赖前需记录在决策日志中(决策内容、原因、被否决的备选方案)。默认采用模块化单体架构:仅在已验证的限界上下文基础上拆分服务。
Intake
初始调研
Ask these before creating the tracker:
- What will the app do, and what is the one feature that is genuinely your competitive advantage? (frames the core subdomain in Phase 2 — where to invest deep modeling versus buy off-the-shelf)
- What stack are you leaning toward — language, web framework, ORM, database? (gates the Phase 1 boundary and Phase 4 data decisions; treated as a detail, never the skeleton)
- What load is realistic in year one — rough daily active users and the main actions each takes? (gates Phase 3 sizing: requirements before solutions)
- What outbound dependencies will it call — payments, email, LLM APIs, shipping, queues? (gates the Phase 6 integration-point audit)
- Which data is the system of record, and are there second read patterns like search, analytics, or feeds? (gates Phase 4 consistency and derived-data decisions)
- Has anyone validated that people actually want this app? (if not, route to create-business / create-app first — do not architect an unvalidated idea)
- How many teams will own this system, and how much of the journey do you want now? (gates the team-topologies optional phase and the Phase 8 appetite)
Phase-skip heuristics: skip Phase 3's scaling machinery and most of Phase 4's replication when year-one load is far below any threshold (a single indexed DB is the answer — record it and move on); skip the team-topologies optional phase for a single-team app. Never skip Phase 1 or Phase 2 — boundaries and the domain model are the additive work that makes every later decision cheap; Phase 6 resilience is not optional once real users and outbound calls exist. Then create the tracker from the template and confirm the plan.
Done when exists with every phase statused and the user has confirmed the plan.
docs/DESIGN-CODE-ARCHITECTURE-PLAN.md创建跟踪文件前需询问以下问题:
- 该应用的功能是什么?哪一项功能是真正的竞争优势?(为阶段2的核心子域奠定基础——确定深入建模的方向与可外购的部分)
- 你倾向使用哪些技术栈——编程语言、Web框架、ORM、数据库?(为阶段1的边界和阶段4的数据决策提供依据;视为细节,而非架构骨架)
- 第一年的实际负载大致是多少——日活跃用户数量及用户主要执行的操作?(为阶段3的规模规划提供依据:先明确需求再考虑解决方案)
- 应用将调用哪些外部依赖——支付、邮件、LLM API、物流、队列?(为阶段6的集成点审计提供依据)
- 哪些数据是系统记录的核心,是否存在搜索、分析或信息流等二次读取模式?(为阶段4的一致性和衍生数据决策提供依据)
- 是否已验证用户确实需要这款应用?(若未验证,先引导至create-business / create-app——不为未验证的创意设计架构)
- 将有多少团队负责该系统?你当前需要完成流程的哪些部分?(为可选的team-topologies阶段和阶段8的范围规划提供依据)
阶段跳过准则:当第一年负载远低于阈值时,跳过阶段3的扩展机制和阶段4的大部分复制逻辑——单个带索引的数据库即可满足需求,记录该决策后继续;单团队应用跳过可选的team-topologies阶段。不得跳过阶段1或阶段2——边界和领域模型是后续所有决策成本降低的基础;一旦有真实用户和外部调用,阶段6的弹性设计即为必填项。然后从模板创建跟踪文件并确认计划。
当创建完成且所有阶段已标记状态、用户确认计划后完成此步骤。
docs/DESIGN-CODE-ARCHITECTURE-PLAN.mdPhases
各阶段
Phases run in the listed order, from hardest-to-reverse to tunable to cross-cutting — each assumes the previous phase's artifact exists. Any phase can be entered, skipped, or deferred per the Operating Rules; Phases 1-2 are the additive work that makes everything after them cheap to change.
The phases form a dependency chain that mirrors the system: Domain-Driven Design says where the boundaries belong (contexts and aggregate seams); Clean Architecture says which way dependencies cross them; Data-Intensive Apps decides what lives inside them at the persistence layer; System Design says how much infrastructure that actually requires — usually far less than feared. Software Design keeps the modules deep instead of multiplying into shallow ceremony, Release It! hardens the integration points, Pragmatic Programmer supplies the cross-cutting habits that hold the structure over time, and the 37signals Way governs the whole thing by fixing time and cutting scope.
阶段按指定顺序执行,从最难回滚到可调整再到跨领域——每个阶段均假设前一阶段的产出物已存在。根据操作规则,任何阶段均可进入、跳过或延后;阶段1-2是后续所有内容低成本变更的基础工作。
各阶段形成的依赖链与系统结构一致:Domain-Driven Design确定边界位置(上下文和聚合边界);Clean Architecture确定依赖方向;Data-Intensive Apps确定持久化层内部的内容;System Design确定实际所需的基础设施规模——通常远低于预期。Software Design保持模块深度而非拆分为浅层模板;Release It!强化集成点;Pragmatic Programmer提供长期维护架构的跨领域习惯;37signals Way通过固定时间和缩减范围管控整体流程。
Phase 1 — Draw the boundaries (clean-architecture)
阶段1:划定边界(clean-architecture)
Purpose: Keep business rules independent of the framework, database, and vendors so every later decision stays swappable — the move that buys back all the others.
Brief (fallback): The Dependency Rule — source-code dependencies point inward: Frameworks → Interface Adapters → Use Cases → Entities; nothing inner names anything outer. Database, web, and vendors 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. Draw full boundaries only at real volatility (DB, external services, delivery); collapse layers elsewhere — direction matters, not folder count.
Invoke: Use the skill with a concrete first feature and the stack from intake. Ask it to layer that feature (entities, a use case with request/response models, repository + gateway interfaces, the HTTP controller and DB adapter in the outer ring), and to flag which boundaries are ceremony versus earning their cost at real volatility.
clean-architectureDecide with the user: (1) Modular monolith versus services — default to a modular monolith with clean internal boundaries; a microservice with a shared data model is a distributed monolith, strictly worse. (2) Which volatility points get full boundaries with interfaces now versus collapsed layers.
Artifact: Create docs/ARCHITECTURE.md with (what it does, integrations), (layers, what depends on what; violation | location | fix | status), and the monolith-versus-services choice in (date | decision | why | alternatives rejected). Update the tracker.
## System Context## Layer Map & Dependency Rule## Decision LogDone when: the layer map exists, the first feature is layered with framework/ORM types confined to the outer ring, the core is designed to test with no DB/web/framework, the monolith-versus-services decision is a Decision Log row, and Phase 1 shows .
done目标: 保持业务规则独立于框架、数据库和供应商,确保后续所有决策均可灵活替换——这一举措将为其他所有决策争取调整空间。
简要说明(备选方案): Dependency Rule——源代码依赖指向内部:Frameworks → Interface Adapters → Use Cases → Entities;内部模块不得引用外部模块的名称。数据库、Web和供应商均为细节,是业务规则的插件。通过Dependency Inversion实现:用例定义仓储接口;Postgres/Stripe的实现位于外部适配器中。仅在真实可变点(DB、外部服务、交付层)划定完整边界;其他层可合并——依赖方向至关重要,而非文件夹数量。
调用: 使用技能,结合具体的首个功能和初始调研中的技术栈。要求对该功能进行分层(实体、带请求/响应模型的用例、仓储+网关接口、位于外层的HTTP控制器和DB适配器),并标记哪些边界属于仪式性边界,哪些是针对真实可变点的必要边界。
clean-architecture与用户决策: (1) 模块化单体架构还是微服务——默认采用带清晰内部边界的模块化单体架构;共享数据模型的微服务本质是分布式单体架构,效果更差。(2) 哪些可变点现在需要带接口的完整边界,哪些可合并层。
产出物: 创建docs/ARCHITECTURE.md,包含(功能、集成关系)、(分层结构、依赖关系;违规项 | 位置 | 修复方案 | 状态),并在中记录单体与微服务的选择(日期 | 决策内容 | 原因 | 被否决的备选方案)。更新跟踪文件。
## 系统上下文## 分层图与Dependency Rule## 决策日志完成标准: 分层图已创建,首个功能完成分层且框架/ORM类型被限制在外层,核心模块可在无需DB/Web/框架的情况下测试,单体与微服务的决策已记录在决策日志中,阶段1标记为。
donePhase 2 — Model the domain (domain-driven-design)
阶段2:领域建模(domain-driven-design)
Purpose: Put boundaries where the business actually splits and make the code speak the domain — cheapest now, inventing the vocabulary from a blank page.
Brief (fallback): The model is the code — build a Ubiquitous Language so team words are code words. Name after domain concepts (, not ); a name that resists is a design signal, not an annoyance. Bounded contexts: a region where a word means exactly one thing ("Customer" differs in billing versus support) — these are your future service seams. Aggregates: a small root cluster enforcing invariants, immediately consistent inside and eventually consistent outside; reference other aggregates by ID. Push behavior into entities — no anemic data bags.
Order.place()OrderManager.process()Invoke: Use the skill with the domain vocabulary and the Phase 1 layer map. Ask for the bounded-context map built from the words the team actually uses, the core aggregates with their invariants, and a subdomain classification (core / supporting / generic).
domain-driven-designDecide with the user: (1) Where the same word legitimately means different things across contexts — do NOT unify into one omniscient model. (2) Which subdomain is core (invest deep modeling) versus generic (buy or use OSS — auth, email, payments).
Artifact: Extend docs/ARCHITECTURE.md: (contexts, relationships, anti-corruption layers) and (term | meaning | code name); record aggregate and core-domain choices in . Update the tracker.
## Bounded Contexts & Context Map## Domain Glossary (Ubiquitous Language)## Decision LogDone when: contexts are mapped with their relationships, the glossary names the core terms, each aggregate states its invariants and by-ID references, the core subdomain is chosen, and the context boundaries line up with the Phase 1 layer map.
目标: 在业务实际划分的位置设置边界,让代码使用领域术语——现在做这件事成本最低,可从零开始构建统一词汇。
简要说明(备选方案): 模型即代码——构建Ubiquitous Language,让团队术语与代码术语一致。以领域概念命名(如,而非);难以命名的情况是设计信号,而非麻烦。Bounded Contexts:同一术语具有唯一含义的区域(“Customer”在计费和支持场景中的含义不同)——这些是未来的服务边界。Aggregates:小型根集群,内部强一致,最终一致;通过ID引用其他聚合。将行为推入实体——避免贫血数据对象。
Order.place()OrderManager.process()调用: 使用技能,结合领域词汇和阶段1的分层图。要求基于团队实际使用的术语构建Bounded Context地图,带不变量的核心聚合,以及子域分类(核心/支撑/通用)。
domain-driven-design与用户决策: (1) 同一术语在不同上下文中的合理差异——不得统一为单一全能模型。(2) 哪些子域是核心(投入深度建模),哪些是通用(外购或使用OSS——认证、邮件、支付)。
产出物: 扩展docs/ARCHITECTURE.md:添加(上下文、关系、防腐层)和(术语 | 含义 | 代码名称);在中记录聚合和核心子域的选择。更新跟踪文件。
## Bounded Contexts与上下文地图## 领域术语表(Ubiquitous Language)## 决策日志完成标准: 已映射上下文及其关系,术语表命名核心术语,每个聚合明确其不变量和ID引用,已选择核心子域,上下文边界与阶段1的分层图对齐。
Phase 3 — Size the system honestly (system-design)
阶段3:合理规划系统规模(system-design)
Purpose: Prove with numbers how small the system can be, so you skip the machinery you cannot justify.
Brief (fallback): Start with requirements, not solutions. Back-of-envelope: QPS = daily-active-users × actions/day ÷ 86,400, peak 2-5× average; storage = records/day × size × retention. For hundreds-to-thousands of users, a single indexed DB plus a read-path cache carries you a long time. Scale in order: vertical first, then cache-aside (TTL + explicit invalidation), then read replicas, and shard last, only with evidence. Reach for a message queue to decouple slow/spiky work, a CDN for global static assets. Premature sharding and premature service-splitting are named mistakes.
Invoke: Use the skill with the load reality from intake. Ask for average and peak QPS, yearly storage, which component bottlenecks first, and a plain list of the techniques (sharding, replicas, CDN, queues, multi-region) you do NOT need yet.
system-designDecide with the user: Which scaling moves to make now versus defer — tied to the numbers (don't build for 50k users while at 50) — and the first slow workload, if any, to move behind a message queue.
Artifact: Extend docs/ARCHITECTURE.md with the load reality and back-of-envelope numbers; record each scaling move (adopt now / defer with trigger) in . Update the tracker.
## System Context## Decision LogDone when: average/peak QPS and yearly storage are written down, the first bottleneck is named, and every scaling technique is either adopted with a reason or deferred with the number that would trigger it.
目标: 用数据证明系统可最小化,从而跳过不必要的复杂机制。
简要说明(备选方案): 从需求出发,而非解决方案。粗略估算:QPS = 日活跃用户数 × 每日操作数 ÷ 86400,峰值为平均值的2-5倍;存储量 = 每日记录数 × 单条记录大小 × 保留时长。对于数百到数千用户,单个带索引的DB加读路径缓存即可满足长期需求。扩展顺序:先垂直扩展,再缓存(TTL + 显式失效),然后读副本,最后分片——仅在有证据时才进行分片。使用消息队列解耦慢/峰值负载的工作,使用CDN处理全球静态资源。过早分片和过早拆分服务是明确的错误。
调用: 使用技能,结合初始调研中的实际负载。要求提供平均和峰值QPS、年存储量、首个瓶颈组件,以及无需立即使用的扩展技术列表(分片、副本、CDN、队列、多区域)。
system-design与用户决策: 哪些扩展措施现在实施,哪些延后——需基于数据(不要在用户数50时为5万用户构建系统),以及是否将首个慢工作负载移至消息队列后。
产出物: 扩展docs/ARCHITECTURE.md的部分,添加实际负载和粗略估算数据;在中记录每个扩展措施(立即采用/延后及触发条件)。更新跟踪文件。
## 系统上下文## 决策日志完成标准: 已记录平均/峰值QPS和年存储量,已命名首个瓶颈,每个扩展技术要么已采用并说明原因,要么已延后并明确触发阈值。
Phase 4 — Make deliberate data decisions (ddia-systems)
阶段4:审慎制定数据决策(ddia-systems)
Purpose: Get the layer that outlives the code right — data model, storage engine, and consistency chosen by access pattern, not habit.
Brief (fallback): Data outlives code. Match model to access pattern — relational for many-to-many and ad-hoc queries, document for self-contained aggregates with locality, graph for recursive traversals; storage engines trade reads against writes (LSM write-throughput versus B-tree read-latency). Most databases default to read-committed or snapshot, NOT serializable — naive read-then-write triggers write skew (two buyers taking the last unit). Lock explicitly () or use a serializable transaction where invariants demand it. Single-leader + read replicas is the read-heavy default; replication lag forces deliberate read-your-writes. Separate system-of-record from rebuildable derived data.
SELECT ... FOR UPDATEInvoke: Use the skill with the workloads implied by the Phase 2 aggregates and the Phase 3 replica plan. Ask for a per-workload model + storage-engine fit, the actual default isolation level and its anomalies, and which read-then-write paths need locking.
ddia-systemsDecide with the user: (1) One datastore versus polyglot persistence, per workload fit. (2) Which paths get a lock or serializable transaction versus tolerate eventual consistency; whether a second read pattern (search, analytics) justifies derived data kept in sync by CDC.
Artifact: Extend docs/ARCHITECTURE.md (models, engines, isolation level, locked paths, system-of-record versus derived) and log the reasoning in . Update the tracker.
## Data & Storage Decisions## Decision LogDone when: each workload has a model + engine chosen by fit, the default isolation level is documented, every write-skew-prone path is locked or serializable, and any derived data has a defined sync mechanism.
目标: 敲定比代码生命周期更长的层面——根据访问模式而非习惯选择数据模型、存储引擎和一致性保障。
简要说明(备选方案): 数据的生命周期比代码长。匹配模型与访问模式——关系型数据库适用于多对多和临时查询,文档型适用于自包含聚合,图数据库适用于递归遍历;存储引擎在读写之间权衡(LSM树写吞吐量 vs B树读延迟)。大多数数据库默认隔离级别为读已提交或快照,而非可序列化——简单的读-写操作会触发写倾斜(两个买家购买最后一件商品)。在需要保障不变量的场景下,显式加锁()或使用可序列化事务。单主节点+读副本是读密集场景的默认方案;复制延迟需审慎处理读自己写的数据的需求。区分系统记录数据与可重建的衍生数据。
SELECT ... FOR UPDATE调用: 使用技能,结合阶段2聚合隐含的工作负载和阶段3的副本计划。要求为每个工作负载匹配模型+存储引擎,说明实际默认隔离级别及其异常,以及哪些读-写路径需要加锁。
ddia-systems与用户决策: (1) 单一数据存储还是多语言持久化,需根据工作负载适配。(2) 哪些路径需要加锁或可序列化事务,哪些可容忍最终一致性;是否为二次读取模式(搜索、分析)通过CDC同步衍生数据。
产出物: 扩展docs/ARCHITECTURE.md的部分(模型、引擎、隔离级别、加锁路径、系统记录数据 vs 衍生数据),并在中记录推理过程。更新跟踪文件。
## 数据与存储决策## 决策日志完成标准: 每个工作负载已根据适配性选择模型+引擎,已记录默认隔离级别,所有易发生写倾斜的路径已加锁或使用可序列化事务,任何衍生数据已定义同步机制。
Phase 5 — Keep modules deep (software-design-philosophy)
阶段5:保持模块深度(software-design-philosophy)
Purpose: Stop the structure from becoming its own disease — hide machinery behind simple interfaces instead of shattering into shallow classes.
Brief (fallback): Complexity is the enemy; the test for every decision is whether it makes the whole system simpler. Module depth = functionality ÷ interface complexity — deep modules hide power behind small interfaces; shallow ones (classitis) add interface cost without hiding complexity. Clean layering and deep modules are allies; clean layering and classitis are not. Information leakage — one design decision reflected in many modules — is a top red flag; encapsulate each piece of knowledge once. Strategic over tactical: invest 10-20% to keep the design clean; startup shortcuts compound into debt as the team grows.
Invoke: Use the skill with the module set proposed in Phases 1-2. Ask which modules are shallow pass-throughs to consolidate, where knowledge leaks across boundaries, and whether any planned boundary is ceremony rather than depth.
software-design-philosophyDecide with the user: Which shallow modules to consolidate into deeper ones now, guarding against over-merging genuinely unrelated concerns; the design conventions the team adopts (naming, where behavior lives, one file per piece of knowledge).
Artifact: Extend docs/TECH-DEBT.md (shallow-module / information-leakage entries with the consolidation applied) and record the agreed rules under . Update the tracker.
## Smell Inventory## Adopted ConventionsDone when: each shallow-module cluster is consolidated or logged with a fix, no single design decision is duplicated across modules, and the design conventions are written down.
目标: 避免架构沦为自身的负担——将复杂机制隐藏在简单接口后,而非拆分为大量浅层类。
简要说明(备选方案): 复杂度是敌人;每个决策的检验标准是是否让整个系统更简单。模块深度 = 功能 ÷ 接口复杂度——深层模块通过小接口隐藏强大功能;浅层模块(类膨胀)增加接口成本却未隐藏复杂度。清晰分层与深层模块相辅相成;清晰分层与类膨胀则相反。信息泄漏——一个设计决策体现在多个模块中——是顶级危险信号;将每一项知识封装一次。战略重于战术:投入10-20%的精力保持设计整洁;初创公司的捷径会随着团队规模扩大而累积成技术债务。
调用: 使用技能,结合阶段1-2提出的模块集合。要求指出哪些是需合并的浅层传递模块,哪些边界存在知识泄漏,以及哪些规划的边界属于仪式性而非深层边界。
software-design-philosophy与用户决策: 哪些浅层模块现在合并为深层模块,需避免过度合并真正无关的关注点;团队采用的设计规范(命名、行为位置、单文件单知识)。
产出物: 扩展docs/TECH-DEBT.md的(浅层模块/信息泄漏条目及合并方案),并在下记录约定规则。更新跟踪文件。
## 问题清单## 采用的规范完成标准: 每个浅层模块集群已合并或记录修复方案,无单一设计决策重复出现在多个模块中,设计规范已书面记录。
Phase 6 — Design for failure (release-it)
阶段6:面向故障设计(release-it)
Purpose: Make the system degrade gracefully instead of collapsing when a dependency is slow or down — cheapest to design in now, not at 2 a.m.
Brief (fallback): The software that passes QA is not what survives production. Integration points are the number-one killer and a slow response is worse than none — a hanging dependency exhausts threads and pools with nothing in the logs. Non-negotiable: connect + read timeouts on every outbound call; a circuit breaker on critical ones (trips open, fails fast, half-open recovery); bulkheads to isolate pools per dependency; retry with backoff + jitter. Paginate every list endpoint (unbounded result sets crash under real data); schedule steady-state cleanup. Decouple deploy from release with feature flags and backward-compatible expand-contract migrations.
Invoke: Use the skill with the outbound dependencies from intake. Ask for timeout values and breaker thresholds per dependency, bulkhead placement, a graceful-degradation path per integration, and the deep-health-check + RED-metrics + expand-contract-migration essentials.
release-itDecide with the user: Breaker thresholds, which dependencies get dedicated pools, how core flows degrade when a non-critical dependency is down, and the rollback path you trust. Resist chaos engineering / multi-region failover for the first thousand users.
Artifact: Create docs/RELIABILITY.md with (dependency | timeout | circuit breaker | bulkhead | retry policy | status), , , and . Update the tracker.
## Integration-Point Audit## Query & Resource Findings## Health Checks & Metrics## Deploy vs ReleaseDone when: every planned outbound call has a timeout, critical dependencies have breakers and bulkheads, every list endpoint is paginated, a deep health check + RED metrics + expand-contract migration + trusted rollback are specified, and the audit has no open rows for critical paths.
目标: 让系统在依赖服务响应缓慢或宕机时优雅降级,而非崩溃——现在设计成本最低,而非在凌晨2点紧急处理。
简要说明(备选方案): 通过QA的软件不等于能在生产环境存活。集成点是头号杀手,缓慢响应比完全不可用更糟——挂起的依赖会耗尽线程和连接池,且无日志记录。必备措施:每个外部调用设置连接+读取超时;关键依赖设置断路器(触发后快速失败,半开状态恢复);为每个依赖设置隔离池;带退避+抖动的重试机制。所有列表端点实现分页(无限制结果集会在真实数据下崩溃);定期清理稳态数据。通过功能标志和向后兼容的扩展-收缩迁移实现部署与发布解耦。
调用: 使用技能,结合初始调研中的外部依赖。要求为每个依赖提供超时值和断路器阈值、隔离池位置、每个集成的优雅降级路径,以及深度健康检查+RED指标+扩展-收缩迁移的核心内容。
release-it与用户决策: 断路器阈值、哪些依赖使用专用池、核心流程在非关键依赖宕机时的降级方式,以及可信的回滚路径。用户数不足一千时,避免混沌工程/多区域故障转移。
产出物: 创建docs/RELIABILITY.md,包含(依赖 | 超时 | 断路器 | 隔离池 | 重试策略 | 状态)、、、。更新跟踪文件。
## 集成点审计## 查询与资源发现## 健康检查与指标## 部署与发布解耦完成标准: 每个计划的外部调用均设置超时,关键依赖配置断路器和隔离池,所有列表端点已分页,已指定深度健康检查+RED指标+扩展-收缩迁移+可信回滚方案,审计中关键路径无未完成条目。
Phase 7 — Prove the wiring and lock in habits (pragmatic-programmer)
阶段7:验证架构连通性并固化习惯(pragmatic-programmer)
Purpose: Build one thin real slice through every layer to prove the boundaries connect, and set the habits that keep the architecture reversible.
Brief (fallback): Tracer bullet — build one thin but fully real vertical slice (HTTP → use case → repository → DB → back), kept as production code, for end-to-end feedback on day two and proof the boundaries link before you flesh them out. Reversibility: abstract every vendor behind your own interface (forking-road test — could you swap DB or LLM provider in a week?). Orthogonality: a dramatic change to one requirement should touch one module. DRY for knowledge, not coincidence — merge duplicated rules, leave look-alikes alone. Broken Window: fix the first hack or board it up with a tracked ticket.
Invoke: Use the skill with the Phase 1 boundaries. Ask for the thinnest end-to-end tracer bullet that exercises every layer, an adapter interface for each vendor, and an audit of where one change would touch many modules or a vendor API would leak into business logic.
pragmatic-programmerDecide with the user: Which slice is the tracer bullet (one authenticated core action, minimal functionality); the broken-windows policy and debt budget per iteration; which vendors get an owned interface first.
Artifact: Extend docs/TESTING.md , (the tracer-bullet path as the first end-to-end test), and ; extend docs/TECH-DEBT.md and (reversibility, orthogonality). Update the tracker.
## Test Strategy## Safety Net Map## CI Gates## Debt Budget & Broken-Windows Policy## Adopted ConventionsDone when: the tracer-bullet slice runs end-to-end through every layer and is pinned as the first CI gate, each vendor sits behind an owned interface, and the broken-windows policy and debt budget are written down.
目标: 构建贯穿所有层的精简真实流程,验证边界连通性,并建立保持架构可回滚性的习惯。
简要说明(备选方案): 跟踪子弹——构建一个精简但完整的垂直流程(HTTP → 用例 → 仓储 → DB → 返回),作为生产代码保留,在第二天获得端到端反馈,并在扩展边界前验证其连通性。可回滚性:将每个供应商封装在自定义接口后(分叉路测试——能否在一周内替换DB或LLM提供商?)。正交性:对某一需求的重大变更应仅影响一个模块。DRY针对知识而非巧合——合并重复规则,保留相似但无关的代码。破窗理论:修复第一个 hack 或用跟踪工单记录。
调用: 使用技能,结合阶段1的边界。要求提供贯穿所有层的最精简端到端跟踪子弹流程、每个供应商的适配器接口,以及审计哪些变更会影响多个模块或供应商API泄漏到业务逻辑中。
pragmatic-programmer与用户决策: 跟踪子弹流程的具体内容(一个带认证的核心操作,最小功能);破窗处理策略和每次迭代的债务预算;优先为哪些供应商封装自定义接口。
产出物: 扩展docs/TESTING.md的、(跟踪子弹流程作为首个端到端测试)、;扩展docs/TECH-DEBT.md的、(可回滚性、正交性)。更新跟踪文件。
## 测试策略## 安全网地图## CI门禁## 债务预算与破窗策略## 采用的规范完成标准: 跟踪子弹流程已贯穿所有层并作为首个CI门禁,每个供应商均位于自定义接口后,破窗策略和债务预算已书面记录。
Phase 8 — Cut scope to the essential (37signals-way)
阶段8:缩减至核心范围(37signals-way)
Purpose: Decide whether any of this ships — fix time, flex scope, and delete speculative abstraction before it becomes complexity you carry.
Brief (fallback): Build less — the best products do fewer things well; half a product beats a half-assed one. Fix an appetite (the time this work is genuinely worth) and cut scope to fit, rather than estimating an open-ended architecture that balloons. YAGNI: every speculative abstraction (generic plugin system, event sourcing, configurable multi-tenancy for zero users) is a decision deferred to an imaginary future at the cost of present complexity. Make tiny reversible decisions; say no by default so the great decisions breathe. Never cut the small set of expensive-to-reverse decisions.
Invoke: Use the skill with the full architecture plan from Phases 1-7. Ask it to shape the work into a fixed appetite, separate essential-for-launch from gold-plating, name the rabbit holes, and list the speculative abstractions to delete or replace with the simplest thing that could work.
37signals-wayDecide with the user: The appetite for v1 architecture work; which abstractions to cut now, defer with a revisit trigger, or replace with the simplest thing; confirm no expensive-to-reverse decision is being cut just to save time.
Artifact: Extend docs/ARCHITECTURE.md with what is deliberately NOT built for v1; extend docs/TECH-DEBT.md (deferred abstractions as deliberately-taken debt, each with the trigger that would revisit it). Update the tracker.
## Decision Log## Debt LedgerDone when: v1 scope is fixed to an appetite, every cut or deferred abstraction is a Decision Log or Debt Ledger row with a revisit trigger, and no expensive-to-reverse decision was cut for time.
目标: 确定哪些内容可上线——固定时间范围,灵活调整范围,在投机性抽象演变为持续负担前删除它们。
简要说明(备选方案): 少做——优秀产品专注于少数功能并做到极致;半成品产品优于完成度低的全功能产品。固定投入时间(该工作真正值得花费的时间)并缩减范围以适配,而非估算不断膨胀的开放式架构。YAGNI:每个投机性抽象(通用插件系统、事件溯源、为零用户配置的多租户)都是为假想未来做出的决策,会增加当前复杂度。做出微小的可回滚决策;默认拒绝,让重要决策有空间。不得削减少数难以回滚的关键决策。
调用: 使用技能,结合阶段1-7的完整架构计划。要求将工作调整为固定时间范围,区分上线必备功能与镀金功能,指出陷阱,列出需删除或替换为最简可行方案的投机性抽象。
37signals-way与用户决策: v1架构工作的时间范围;哪些抽象现在删除、延后(带重新评估触发条件)或替换为最简方案;确认未因节省时间而削减难以回滚的关键决策。
产出物: 扩展docs/ARCHITECTURE.md的,记录v1版本刻意不构建的内容;扩展docs/TECH-DEBT.md的(将延后的抽象视为刻意承担的债务,每个均标注重新评估的触发条件)。更新跟踪文件。
## 决策日志## 债务台账完成标准: v1范围已固定至时间范围,每个删除或延后的抽象均记录在决策日志或债务台账中并标注触发条件,未因时间原因削减难以回滚的关键决策。
Optional Phases
可选阶段
| Skill | Add when | Artifact |
|---|---|---|
| team-topologies | More than one team will own the system, so module boundaries must align with team boundaries (Conway) | Extends docs/OPERATIONS.md ( |
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 — here, right after Phase 2, once the bounded contexts that team boundaries must mirror exist.
| 技能 | 适用场景 | 产出物 |
|---|---|---|
| team-topologies | 多个团队负责系统,模块边界需与团队边界对齐(Conway定律) | 扩展docs/OPERATIONS.md( |
可选阶段遵循相同操作规则——完全按照核心阶段的方式加载并使用每个列出的技能;在适用场景首次出现时插入——此处为阶段2之后,一旦存在团队边界需镜像的Bounded Contexts即可插入。
Common Mistakes
常见错误
| Mistake | Fix |
|---|---|
| Letting the framework be the architecture | Apply Clean Architecture's Dependency Rule (Phase 1) — framework calls inward; ORM and request types stay confined to the outer ring. |
| Over-engineering for scale you cannot prove you need | Run back-of-envelope QPS/storage math first (system-design, Phase 3); one indexed DB plus a cache is usually years of runway. |
| Over-correcting into classitis | Apply the deep-module rule (software-design-philosophy, Phase 5) — a few deep modules beat a swarm of shallow ones; boundaries at real volatility only. |
| Ignoring the database's actual consistency guarantees | Check the default isolation level and lock write-skew-prone paths (ddia-systems, Phase 4) — write skew passes every single-user test. |
| Treating resilience as a post-launch concern | Design timeouts, breakers, and pagination in from the start (release-it, Phase 6) — a slow dependency with no timeout freezes everything. |
| Confusing build-less with build-carelessly | Cut features and speculative abstractions (37signals-way, Phase 8), never the small set of expensive-to-reverse decisions. |
| 错误 | 修复方案 |
|---|---|
| 让框架成为架构 | 应用Clean Architecture的Dependency Rule(阶段1)——框架向内调用;ORM和请求类型限制在外层。 |
| 为未验证的规模过度设计 | 先进行QPS/存储量的粗略计算(system-design,阶段3);单个带索引的DB加缓存通常可支撑多年需求。 |
| 过度纠正导致类膨胀 | 应用深层模块规则(software-design-philosophy,阶段5)——少量深层模块优于大量浅层模块;仅在真实可变点设置边界。 |
| 忽略数据库的实际一致性保障 | 检查默认隔离级别并为易发生写倾斜的路径加锁(ddia-systems,阶段4)——写倾斜可通过所有单用户测试。 |
| 将弹性设计视为上线后事项 | 从一开始就设计超时、断路器和分页(release-it,阶段6)——无超时的慢依赖会冻结整个系统。 |
| 将“少做”等同于“随意做” | 削减功能和投机性抽象(37signals-way,阶段8),但绝不削减少数难以回滚的关键决策。 |
Completing the Journey
流程完成
Match the dose to the project: a weekend build leans on the Phase 1 Dependency Rule, a quick Ubiquitous Language, timeouts on outbound calls, and the Phase 8 instinct to cut scope — a few hours that save weeks. A funded team building toward launch works the whole stack, pulling the data and resilience phases in as real bottlenecks and integration points appear.
Exit checklist — every box tied to an artifact:
- Each expensive-to-reverse decision (boundaries, contexts, data/consistency) is a Decision Log row with alternatives rejected (ARCHITECTURE.md).
- Core business rules are designed to run with no DB, web, or framework (ARCHITECTURE.md Layer Map, no inward-pointing violations).
- Every outbound call has a timeout, critical ones have breakers, and every list is paginated (RELIABILITY.md Integration-Point Audit clear).
- A tracer-bullet slice proves the boundaries connect end-to-end and is the first CI gate (TESTING.md).
- v1 scope is fixed to an appetite with speculative abstractions cut or deferred with a trigger (TECH-DEBT.md Debt Ledger).
Close the tracker: every phase or , with remaining Next Actions carried into the ARCHITECTURE.md Decision Log and TECH-DEBT.md so nothing is lost. Then route forward: when the architecture serves a product that still needs validating and building, continue with the skill; when an existing prototype must be brought up to this structure, continue with the skill.
doneskipped: reasoncreate-appimprove-code-quality根据项目规模调整流程:周末项目可简化使用阶段1的Dependency Rule、快速构建Ubiquitous Language、为外部调用设置超时,以及阶段8的范围缩减本能——数小时的工作可节省数周时间。筹备上线的资金团队需执行全流程,在出现真实瓶颈和集成点时引入数据和弹性阶段。
退出检查清单——每个条目均对应产出物:
- 每个难以回滚的决策(边界、上下文、数据/一致性)均记录在决策日志中,并标注被否决的备选方案(ARCHITECTURE.md)。
- 核心业务规则可在无需DB、Web或框架的情况下运行(ARCHITECTURE.md分层图,无向内依赖违规)。
- 每个外部调用均设置超时,关键依赖配置断路器,所有列表均已分页(RELIABILITY.md集成点审计无未完成项)。
- 跟踪子弹流程已验证边界端到端连通性,并作为首个CI门禁(TESTING.md)。
- v1范围已固定至时间范围,投机性抽象已删除或延后并标注触发条件(TECH-DEBT.md债务台账)。
关闭跟踪文件:每个阶段标记为或,剩余下一步行动记录在ARCHITECTURE.md决策日志和TECH-DEBT.md中,确保无遗漏。然后引导后续流程:若架构服务于仍需验证和开发的产品,继续使用技能;若现有原型需调整至该架构,继续使用技能。
doneskipped: reasoncreate-appimprove-code-quality