Aikodoc
SDD 能力底座

为什么不要复制粘贴

一条事实只在一个文档里写 —— SSoT 实操指南

写文档时最容易踩的坑:"这条业务规则 PRD 写过了,我在测试用例里再复述一遍方便看"。然后 PRD 改了,测试用例忘了改,对不齐就翻车。

Aiko IDE 用 SSoT(单一事实源) 准则解决这个问题:每条事实只能在一个文档里定义,其他文档只通过 ID 引用。

四条铁律

  1. 一处定义:一条事实只有一个主笔文档
  2. ID 引用:其他文档引用主笔的稳定 ID(REQ-FN-007 / ACC-012 / ADR-003
  3. 延伸不重复:下游可以加新事实,不能复述上游
  4. 职责单一:每个文档只回答一个问题

这套约束被 ssot Validator 守门,违规直接 ERROR

怎么知道事实归谁?事实归属表

PD 层 10 件

这条事实归哪个文档写用什么 ID 引用
问题陈述 / 目标 / 用户 / 范围 / 里程碑vision.mdVISION-* / GOAL-* / PERSONA-* / SCOPE-* / MILE-*
用户场景 + 故事stories.mdSCEN-* / STORY-*
系统功能能力requirements.mdREQ-FN-* / REQ-ALG-* / REQ-SEC-* / REQ-DOC-*
非功能数字目标nfr.mdREQ-NFR-*
验收门禁acceptance.mdACC-*
产品设计约束product-design.mdDESIGN-* / IA-* / INTERACT-* / INTEG-* / CONSTR-*
风险 / 假设 / 依赖risks.mdASSUM-* / DEP-* / RISK-*
灰度 / 监控 / 告警 / 回滚rollout.mdROLL-* / METRIC-* / ALERT-* / SOP-*
术语定义glossary.mdGLOSS-*
AI 能力规约ai-spec.mdAI-FRAME-* / MODEL-* / DATA-* / EVAL-* / GUARD-*

架构层 3 件

这条事实归哪个文档ID
系统架构边界architecture.mdARCH-*
关键技术决策adr.mdADR-*
NFR 实现策略quality-attributes.mdQA-*

开发层 4 件

这条事实归哪个文档ID
工程 change 说明proposal.mdchange id
capability 行为契约specs/**/*.mdOpenSpec Requirement / Scenario
capability 内部实现design.md章节标题 + 上游 trace
实施步骤tasks.mdcheckbox / task id

测试层 2 件

这条事实归哪个文档ID
测试用例test-cases.mdTC-*
测试证据test-evidence.mdEV-*

常见违规:你可能想这么写但不该这么写

❌ 在 vision.md 里写"登录页应有忘记密码按钮"

vision.md 是"为什么做",功能能力归 requirements.md

对的写法:在 requirements.mdREQ-FN-005 登录页提供忘记密码入口,vision 里需要时只引 REQ-FN-005

❌ 在 requirements.md 里写"TPS ≥ 1000"

具体数字是 NFR 目标值,归 nfr.md

对的写法requirements.md 只写"系统应支持高并发查询",nfr.md 写 REQ-NFR-PERF-003 p99 latency ≤ 100ms @ TPS=1000

❌ 在 acceptance.md 里写"测试步骤:1. 打开浏览器..."

acceptance 写"怎样算达标"(Given/When/Then),具体执行步骤归 test-cases.md

对的写法

# acceptance.md
- id: ACC-012
  given: 用户已登录
  when: 提交订单
  then: 订单创建成功 + 库存扣减
# test-cases.md
- id: TC-007
  satisfies: [ACC-012]
  steps:
    - 1. 打开浏览器,登录...
    - 2. 添加商品到购物车...

❌ 在 adr.md 里写"新增 order_status 字段"

adr 写"为什么选某个方案",普通工程任务归 tasks.md

对的写法

  • adr.md:ADR-005 订单状态选择枚举而非状态机表(理由 + 取舍)
  • tasks.md:[ ] T-021 给 orders 表加 order_status 字段

❌ 在 test-cases.md 里重述"应能成功登录"

test-cases 写"怎么测",验收标准归 acceptance.md

对的写法

- id: TC-007
  satisfies: [ACC-012]   # 引用 acceptance.md 的 ACC-012
  steps: [...]

这样做有什么好处

  1. 改一处,下游自动跟改:改 REQ-FN-007,所有引用它的 spec / test / design 都被 trace Validator 标记
  2. AI 上下文清晰:让 AI 写 design 时只读 specs + adr,不被 PD 长篇业务背景污染
  3. 影响分析机器化:改一个 ID,trace graph 立刻列出受影响的下游,不用人工 grep
  4. 永远只有一份事实源:避免 5 个对不齐的副本,team 撕逼说"我看的是哪份"

实操技巧

想引用一条已存在的事实

直接写 ID 字符串:

- id: ACC-012
  satisfies: [REQ-FN-007]    # 引用 requirements.md
  references_adr: [ADR-005]   # 引用 adr.md

trace Validator 自动检查这些 ID 真的存在。

想看 trace graph

./scripts/build-trace-graph.sh
# 自动生成 docs/trace-graph.md (mermaid)

打开看引用关系图。

Workbench 内 hover ID 看上游

在 PD / dev sidebar 编辑器里,鼠标悬停一个 ID 显示主笔文档的对应段落(不用切文件)。

写完文档自检 3 个问题

  1. 这页文档"只回答一个问题"吗?回答不了就拆分
  2. 重复的内容能改成引用 ID 吗?能就改
  3. 主笔文档里的事实下游能正确引用吗?跑一遍 aiko-validate.sh

关联

On this page