From 7806e413fdc29b5fafcd687896f146a848905bb2 Mon Sep 17 00:00:00 2001 From: zh Date: Tue, 22 Sep 2026 18:26:30 +0800 Subject: [PATCH] =?UTF-8?q?docs(adr):=20=E5=BB=BA=E7=AB=8B=20ADR=20?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E7=BA=A6=E5=AE=9A=E4=B8=8E=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=EF=BC=8C=E8=A1=A5=E9=BD=90=20ADR-0001?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/adr/0000-template.md | 34 ++++++++++++++++++++ docs/adr/0001-tech-stack-and-repo.md | 39 +++++++++++++++++++++++ docs/adr/README.md | 47 ++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 docs/adr/0000-template.md create mode 100644 docs/adr/0001-tech-stack-and-repo.md create mode 100644 docs/adr/README.md diff --git a/docs/adr/0000-template.md b/docs/adr/0000-template.md new file mode 100644 index 0000000..361e66e --- /dev/null +++ b/docs/adr/0000-template.md @@ -0,0 +1,34 @@ +# ADR-0000:<把决定写成一句话> + +- **状态**:提议 +- **日期**:YYYY-MM-DD +- **决策人**: +- **相关**:任务表 <编号>;设计文档 <章节> + +## 背景 + +为什么现在必须做这个决定。说清约束:时间、人力、既有系统、外部依赖。不复述背景知识,只写"是什么逼着我们现在选"。 + +## 选项 + +| 选项 | 做法 | 代价 | 不选的理由 | +| --- | --- | --- | --- | +| A | | | | +| B | | | | + +至少两条,代价要写实。只有一个选项的"决定"通常不是决定,是既成事实。 + +## 结论 + +选了哪个,一句话说清,再写一条最重要的理由。 + +## 影响 + +- **对代码**:哪些模块或目录按这个决定组织 +- **对任务**:任务表里哪些条目因此调整、依赖怎么变 +- **对文档**:哪些设计文档章节要同步 +- **不这么做的后果**:如果反过来选会怎样 + +## 遗留 + +还没定的点,逐条写明责任人与时限。没有就写"无"。 diff --git a/docs/adr/0001-tech-stack-and-repo.md b/docs/adr/0001-tech-stack-and-repo.md new file mode 100644 index 0000000..72059ec --- /dev/null +++ b/docs/adr/0001-tech-stack-and-repo.md @@ -0,0 +1,39 @@ +# ADR-0001:采用原地重写 + 孤儿分支,历史从零开始 + +- **状态**:已接受 +- **日期**:2026-09-22 +- **决策人**: +- **相关**:任务表 A0.1、A0.2;设计文档《架构设计》第 2 节 + +## 背景 + +现有仓库是「APS 产品 + 内嵌智能体层」的混合实现:网关一个文件 5232 行、数据库 18 张表混装平台与 APS 数据、APS 领域有 14 个文件反向依赖智能体层。重构的目标是把平台与 APS 拆开,平台从零重写。 + +同时有两项硬约束:APS 的求解依赖 Python 生态(OR-Tools CP-SAT 在 TS 侧没有等价实现),所以 APS 只能搬迁适配、不能重写;旧系统仍在生产使用,切换必须可回退。 + +## 选项 + +| 选项 | 做法 | 代价 | 不选的理由 | +| --- | --- | --- | --- | +| A 新仓库重写 | 另建仓库写新平台 | 历史干净、体积归零 | issue、CI、权限、制品发布都要重搭,两仓库协同复杂 | +| B 原地重写,继承历史 | 从 main 切分支继续写 | 切换简单 | git log 与 blame 混着旧历史,"从零"名不副实 | +| C 原地重写,孤儿分支 | 同一仓库,新分支无父提交 | 切换需强推,回退依赖备份分支 | 选定 | + +## 结论 + +选 C。同一仓库建孤儿分支 `rewrite/platform`:工作区从 `main` 的内容出发,但提交历史从首个提交 `b878fd6` 开始,不继承旧历史。切换时以本分支强推覆盖 `main`(`--force-with-lease`),切换前把 `main` 备份为 `legacy/main` 并设为只读。 + +理由是两条同时满足:既保留原仓库的 issue、CI、权限与制品通道,又让新分支的历史真正从零开始。 + +## 影响 + +- **对代码**:新分支只保留工程配置(`.gitignore`、`.dockerignore`、`.env.example`),目录按 `client/`、`server/`、`providers/`、`contracts/` 重建 +- **对任务**:A1.1 脚手架与 A1.6 CI 基线都依赖 A0.2 的分支与 CI 分流规则;A0.10 的设计文档随本分支首个提交入库 +- **对文档**:设计文档第 2 节的项目结构以此为准 +- **不这么做的后果**:选 A 会把管理成本前移且长期并行两套仓库;选 B 会让新代码的每一行 blame 都落在不该负责的旧提交上 + +## 遗留 + +- `legacy/main` 备份分支的创建与只读设置:切换前执行,见 A0.2 +- 孤儿历史**不会**减小仓库体积(旧对象仍在对象库);要体积归零只能另立仓库,本次不做 +- 移植旧逻辑时在提交信息里写明 `移植自 main:`,否则 `git blame` 追不到来源 diff --git a/docs/adr/README.md b/docs/adr/README.md new file mode 100644 index 0000000..a992c5d --- /dev/null +++ b/docs/adr/README.md @@ -0,0 +1,47 @@ +# 架构决策记录(ADR) + +> 一份文件记一个决定。设计文档写"怎么落地",ADR 写"为什么这么定、放弃了什么"。 + +## 目录约定 + +| 项 | 约定 | +| --- | --- | +| 位置 | `docs/adr/` | +| 命名 | `NNNN-英文短标题.md`,四位递增,从 0001 开始 | +| 粒度 | 一份文件只记一个决定;相关联的决定分文件写,互相引用 | +| 语言 | 文件名用英文短横线小写,正文用中文 | +| 评审 | 走 MR:有 diff、有讨论、有提交历史 | + +## 不可更改原则 + +ADR 写完不再修改。要改结论就**新写一份**,并在两份里互相标注取代关系: + +- 新 ADR 的 `状态` 写 `已接受(取代 ADR-0002)` +- 旧 ADR 的 `状态` 改为 `已取代(被 ADR-0007 取代)` + +这样任何时候都能回答"当初为什么这么定、后来为什么改"。 + +## 状态取值 + +| 状态 | 含义 | +| --- | --- | +| 提议 | 已写出,等待决策人签字 | +| 已接受 | 决策人签字,作为当前依据 | +| 已取代 | 被更新的 ADR 覆盖 | +| 已废弃 | 决定不再适用,且未被替代 | + +## 谁写、谁定 + +任何人可以提议(状态 `提议`)。决策人在文件里签字后状态改为 `已接受`。签字栏留空表示还没定。 + +## 索引 + +| 编号 | 标题 | 状态 | 来源 | +| --- | --- | --- | --- | +| [0001](./0001-tech-stack-and-repo.md) | 技术栈与仓库形态 | 已接受 | 任务表 A0.1、A0.2 | +| 0002 | 引擎与 Provider 部署形态 | 待写 | 任务表 A0.3(决策 D1) | +| 0003 | 数据作用域与权威数据源 | 待写 | 任务表 A0.4(决策 D2) | +| 0004 | 桌面端与本地能力边界 | 待写 | 任务表 A0.5(决策 D4) | +| 0005 | 迁移与切换策略 | 待写 | 任务表 A0.9(决策 D7) | + +编号在写之前先在本表登记,避免多人并行时撞号。