Skill Learning

domain-modeling

1. Bilingual SKILL.md

左右滑动可直接切换英文版与中文版;两种语言按段落自动对齐。英文中的蓝色虚线词语可点击查看解释。共标记 16 处。

入口 skill:domain-modeling左右滑动切换语言 · 段落位置自动对齐
# Domain Modeling
Actively the project's domain model as you design. This is the *active* discipline: challenging terms, inventing edge-case scenarios, and writing the glossary and decisions down . (Merely *reading* `CONTEXT.md` for vocabulary is not this skill: that's a one-line habit any skill can do. This skill is for when you're changing the model, .)
## File structure
Most repos have a single context:
``` / ├── CONTEXT.md ├── docs/ │ └── adr/ │ ├── 0001-event-sourced-orders.md │ └── 0002-postgres-for-write-model.md └── src/ ```
If a `CONTEXT-MAP.md` exists at the root, the repo has multiple contexts. The map points to where each one lives:
``` / ├── CONTEXT-MAP.md ├── docs/ │ └── adr/ ← system-wide decisions ├── src/ │ ├── ordering/ │ │ ├── CONTEXT.md │ │ └── docs/adr/ ← context-specific decisions │ └── billing/ │ ├── CONTEXT.md │ └── docs/adr/ ```
: only when you have something to write. If no `CONTEXT.md` exists, create one when the first term is resolved. If no `docs/adr/` exists, create it when the first ADR is needed.
## During the session
### Challenge against the glossary
When the user uses a term that conflicts with the existing language in `CONTEXT.md`, . "Your glossary defines 'cancellation' as X, but you seem to mean Y. Which is it?"
### Sharpen fuzzy language
When the user uses , propose . "You're saying 'account': do you mean the Customer or the User? Those are different things."
### Discuss concrete scenarios
When domain relationships are being discussed, with specific scenarios. Invent scenarios that and force the user to be precise about the boundaries between concepts.
###
When the user states how something works, check whether the code agrees. If you find a contradiction, : "Your code cancels entire Orders, but you just said partial cancellation is possible. Which is right?"
### Update CONTEXT.md inline
When a term is resolved, update `CONTEXT.md` right there. : capture them as they happen. Use the format in [CONTEXT-FORMAT.md](./CONTEXT-FORMAT.md).
`CONTEXT.md` should be . Do not treat `CONTEXT.md` as a spec, a scratch pad, or a repository for implementation decisions. It is a glossary and nothing else.
###
Only offer to create an ADR when all three are true:
1. **Hard to reverse**: the cost of changing your mind later is meaningful 2. **Surprising without context**: a future reader will wonder "why did they do it this way?" 3. ****: there were genuine alternatives and you picked one for specific reasons
If any of the three is missing, skip the ADR. Use the format in [ADR-FORMAT.md](./ADR-FORMAT.md).
# 领域建模
在设计过程中,主动构建并打磨项目的领域模型。这是一门*主动的*纪律:质疑术语、构造边界案例,并在术语表和决策刚刚成形的那一刻把它们写下来。(仅仅为了查词而*阅读* `CONTEXT.md` 并不属于这个技能:那只是任何技能都能采用的一行式习惯。这个技能用于改变模型,而不只是使用模型。)
## 文件结构
大多数仓库只有一个语境:
``` / ├── CONTEXT.md ├── docs/ │ └── adr/ │ ├── 0001-event-sourced-orders.md │ └── 0002-postgres-for-write-model.md └── src/ ```
如果根目录存在 `CONTEXT-MAP.md`,仓库就包含多个语境。这张地图会指向每个语境所在的位置:
``` / ├── CONTEXT-MAP.md ├── docs/ │ └── adr/ ← 系统级决策 ├── src/ │ ├── ordering/ │ │ ├── CONTEXT.md │ │ └── docs/adr/ ← 特定语境的决策 │ └── billing/ │ ├── CONTEXT.md │ └── docs/adr/ ```
延迟创建文件:只有真正有内容可写时才创建。如果不存在 `CONTEXT.md`,就在第一个术语得到确认时创建;如果不存在 `docs/adr/`,就在需要第一份 ADR 时创建。
## 会话期间
### 对照术语表提出质疑
当用户使用的术语与 `CONTEXT.md` 中已有语言冲突时,立即指出:“你的术语表把 ‘cancellation’ 定义为 X,但你现在似乎是指 Y。到底是哪一个?”
### 澄清模糊语言
当用户使用含糊或一词多义的术语时,提出一个精确的规范术语:“你说的是 ‘account’:究竟指 Customer 还是 User?它们是两个不同的概念。”
### 讨论具体场景
讨论领域关系时,用具体场景对它们做压力测试。构造能够探测边界情况的场景,迫使用户精确定义概念之间的边界。
### 与代码交叉核对
当用户说明某件事如何运作时,检查代码是否一致。如果发现矛盾,就把它摆出来:“你的代码会取消整个 Order,但你刚才说可以部分取消。哪一个才对?”
### 就地更新 CONTEXT.md
术语一旦确定,就立即更新 `CONTEXT.md`。不要攒到最后批量处理:术语发生时就捕获它。使用 [CONTEXT-FORMAT.md](./CONTEXT-FORMAT.md) 中的格式。
`CONTEXT.md` 应当完全不包含实现细节。不要把 `CONTEXT.md` 当作规格、草稿纸或实现决策的存储库。它只是术语表,仅此而已。
### 谨慎提议 ADR
只有以下三个条件全部成立时,才提议创建 ADR:
1. **难以逆转**:日后改变决定的成本很高 2. **缺少背景就会显得意外**:未来读者会疑惑“他们为什么要这样做?” 3. **来自真实的权衡**:确实存在不同选项,而你出于具体理由选择了其中一个
只要缺少其中任一条件,就跳过 ADR。使用 [ADR-FORMAT.md](./ADR-FORMAT.md) 中的格式。

Entry SHA-256: 327a2b50620e2fd70abc6893cd6965e76b20f8d0adb0dc2c8d5eb3845efb643e

2. Why This Skill Is Clever

一句话核心机制

它把领域建模变成会话内的持续校准回路:术语冲突 → 具体场景 → 代码核验 → 当场记录,并把词汇事实与实现决策分开存放。

触发与边界

直接来源: 描述明确限定了触发面:讨论代码库术语、编写或编辑 CONTEXT.md、记录或编辑 ADR 时使用。正文又用 “when you're changing the model, not just consuming it” 排除了仅仅读取术语表的情况。因此它不是所有工程任务的默认前置步骤,而是模型发生变化时的主动纪律。

辅助上下文: agents/openai.yaml 只提供显示名称与短描述,没有添加隐式调用政策;是否自动触发仍取决于具体 harness 如何解释 skill 描述。

信息架构 / 执行顺序

  1. 先判断仓库是单一语境,还是由根目录 CONTEXT-MAP.md 指向多个语境。
  2. 会话中持续监测语言冲突和含糊术语,提出规范名称。
  3. 用具体边界案例对领域关系做压力测试。
  4. 把用户陈述与代码交叉核对,主动暴露不一致。
  5. 术语一旦确定就写入纯术语表 CONTEXT.md,不延迟批处理。
  6. 只有难以逆转、缺少背景会令人意外、且来自真实权衡时,才单独记录 ADR。

最巧妙的设计点

1. 用否定边界保护触发精度

“not just consuming it”

直接来源: 技能明确区分“读取模型”和“改变模型”。这避免简单查词也启动一整套建模流程,降低过度介入和文档噪声。

2. 用具体场景把词义争论变成可判定问题

“stress-test them with specific scenarios”

直接来源: 与其抽象争论 “Account” 的定义,它要求构造退款、部分取消等边界案例。场景迫使参与者说明实体关系和责任边界,使语言选择能够被行为事实检验。

3. 让代码成为独立证据源

“check whether the code agrees”

直接来源: 口头模型并不自动获胜,当前实现也不自动获胜;发现冲突时把选择交还给用户。这种做法将“文档同步”升级为模型与现实之间的显式对账。

4. 在上下文最完整时捕获知识

“Don't batch these up”

直接来源: 确认术语后立即写入,避免会话结束时依靠记忆批量回填。即时记录既减少遗漏,也保留了决策刚成形时的语义精度。

5. 用两种文件承担不同知识寿命

“It is a glossary and nothing else.”

直接来源: CONTEXT.md 只保存领域语言,ADR 只保存值得解释的实现决策。辅助上下文: CONTEXT-FORMAT.md 进一步要求定义简短、列出应避免的近义词;ADR-FORMAT.md 则允许 ADR 只有一个段落。两者都在压制模板膨胀,但没有把实现事实混入术语表。

6. 用三重门槛阻止 ADR 通胀

“Only offer to create an ADR when all three are true”

直接来源: 三个条件是“并且”关系,不是任选其一。它过滤掉容易逆转、无需解释或根本没有备选项的普通决定,让未来读者更愿意信任 ADR 集合中的信号。

防失败机制与 trade-off

明确不变量: CONTEXT.md 不得包含实现细节;术语确定后当场写入;ADR 必须同时通过三项门槛;多语境仓库由 CONTEXT-MAP.md 定位。

解释与权衡: 即时写文件提高一致性,但会增加会话中的小幅写入频率;用现有代码核验能发现漂移,却不能证明代码一定代表正确业务;只保留少量 ADR 提高信噪比,也可能漏掉后来才显出重要性的决定。文件位置和 Markdown 模板是仓库约定,迁移到 wiki、数据库或不同 agent harness 时需要适配。

可迁移原则

今日实践题

如果团队把 Customer、User 和 Account 混着使用,你会设计哪两个具体边界场景,来迫使三者的身份、权限和生命周期被分别定义?

Evidence note

主要机制与所有引文均来自本次选中的 SKILL.md;文件模板细节来自同目录的 CONTEXT-FORMAT.md、ADR-FORMAT.md 和 agents/openai.yaml,仅作为辅助上下文;对信噪比、知识寿命和迁移风险的判断属于设计解释。

Source & provenance
Repository path
skills/engineering/domain-modeling/SKILL.md
Generated
2026-09-02 08:23 Asia/Shanghai
Upstream commit
6654f6b60cd9d5be8b54c6fafe44346dabeb3b76
Source
View on GitHub