# 项目开发实践指南（VIBECODING GUIDE）

> 本文档是基于"踩过的坑"沉淀下来的项目工作方式约定，适用于本仓库及后续所有同性质的项目。
> 它的姊妹文件是 [`SELF_CONSTRAINTS.md`](./SELF_CONSTRAINTS.md) —— 那是 Agent 每次开工前必须自查的硬约束清单。
> 本文回答 "为什么这么做"；`SELF_CONSTRAINTS.md` 回答 "具体不许做什么"。

---

## 0. 三条核心教训（本指南的来由，优先级严格递减）

1. **版本控制必须从第 0 天开始。**
   不是 "等做出点东西再说"，是写第一行代码之前先初始化仓库、写好 ignore 规则、提交一个空骨架。
   理由：高频改动 + 频繁推翻是 AI 协作的常态，没有版本控制兜底就等于在悬崖边裸奔。

2. **文档必须在写代码之前定下来。**
   需求、架构、路线图、开发规范、目录结构、命名规范、模块边界 —— 这些不是"做完之后补的"，是"做之前定的"。
   理由：一旦上下文被代码细节占满，后续每个新会话都只能 freestyle，项目会朝不可逆的方向漂移。

3. **架构 > UI > 用户体验。**
   最致命的不是界面丑、不是体验差，而是模块互相纠缠到无法定位问题。
   一个出问题就能立刻指认 "是 X 模块的责任" 的项目，比一个好看但耦合一团的项目，存活率高一个数量级。
   理由：耦合一旦发生，AI 协作模式会迅速放大它 —— 因为每次新会话都看不全全貌，只会在原有耦合上继续添乱。

> 这三条的优先级是严格递减的：先有版本控制，再有文档，再谈架构；架构稳了之后才轮到 UI 和体验。

---

## 1. 项目启动 Checklist（Day 0）

下列每一项都必须在写第一行业务代码之前完成。顺序即优先级。

### 1.1 仓库与版本控制
- [ ] 初始化版本控制并立即建立 ignore 规则（语言 / IDE / 系统三类至少齐全）
- [ ] 提交一个 **空骨架 commit**（README + ignore 规则 + 空目录结构），作为"零点参照系"
- [ ] 约定分支模型（最简：主干 + 短命的功能分支；不要等到分叉时才想）
- [ ] 约定 commit message 风格（推荐 Conventional Commits，至少要求动词开头 + 一句话原因）

### 1.2 文档骨架（必须先于代码存在）
在 `.project.agents/docs/context` 下建立以下文件，**哪怕只有大纲也比没有强**：

| 文件 | 角色 | 上下游关系 |
|---|---|---|
| `PRD.md` | 产品需求（要做什么） | 上游 |
| `ARCHITECTURE.md` | 架构（怎么拆） | 上游 |
| `ROADMAP.md` | 路线图（什么时候做哪一块） | 由需求 + 架构推导 |
| `CONVENTIONS.md` | 开发规范（命名、目录、提交、风格） | 上游 |
| `UIUX.md` | 视觉与交互细节（仅有 UI 的项目需要） | 上游（与需求并列） |
| 派生文档（实现 spec / 资产清单等） | 屏幕级实现 / 资产清单 | **派生**，由上游产生 |

**判断标准**：如果一个新会话的 Agent 只读需求 + 架构 + 开发规范就能正确开始一个任务 —— 文档就算合格。

### 1.3 Agent 协作配置
- [ ] 在 `CLAUDE.md` 写明项目级规则（已有，保持更新）
- [ ] 在本文件 + `SELF_CONSTRAINTS.md` 中固化经验
- [ ] 在 `.project.agents/settings.json` 中配置必要的 hook / 权限（不要散落到根目录或全局）

---

## 2. 架构原则

### 2.1 三条硬规则

1. **单一职责到模块级**
   每个模块只回答一个问题。
   反例："一个模块既管数据持久化，又管网络请求，又管 UI 状态" —— 这种模块必须拆。

2. **依赖方向单向**
   高层依赖低层，UI 依赖业务，业务依赖数据；**反向依赖一律禁止**，遇到就用接口/事件/回调倒置。
   依赖关系必须能画成一张**有向无环图（DAG）**，且这张图要在 `ARCHITECTURE.md` 里画出来。

3. **跨模块只走"接口契约"**
   模块 A 想用模块 B 的能力，只能通过 B 暴露的接口/协议，不能 reach into B 的内部实现。
   接口契约必须在 `ARCHITECTURE.md` 中显式声明（哪怕只是函数签名清单）。

### 2.2 判断架构是否健康的三个问句

随时可以用这三个问句自检：

1. **指认问题**：现在出 bug 了，我能否在 30 秒内指出"这是哪个模块的责任"？
2. **替换实现**：如果要把模块 X 整体换掉（换数据库、换框架），改动是否能控制在 X 内部 + 一个接口适配层？
3. **新增功能归属**：用户要加一个新功能，我能否立刻说出它"属于哪个模块、或需要新增哪个模块"？

任何一个回答不出来，架构就有问题，**先停下修架构，再写代码**。

### 2.3 反耦合纪律

- **不在新功能开发时顺手重构无关模块**（重构走单独 commit + 单独会话）
- **不在 UI 层做业务判断**（UI 只接收状态、发送意图）
- **不让数据模型自己跑业务逻辑**（模型类保持瘦，业务放 Service / UseCase）
- **不要"为了少写一个文件"把两个模块塞进同一个文件**

---

## 3. 项目架构文档生成流程

这是从零到 `ARCHITECTURE.md` 的标准流程。每一步都有产出物，下一步必须基于上一步的产出物。

### Step 1 — 需求收敛（产出 `PRD.md`）
- 列功能清单，按 **核心 / 增强 / 可选** 三档分类
- 每个核心功能写一句 "用户故事"（"作为 X，我想 Y，以便 Z"）
- **冻结 MVP 范围**：圈出 MVP 包含哪些核心功能，其余明确标 "Out of MVP"

### Step 2 — 领域建模（产出 `ARCHITECTURE.md` §1 领域模型）
- 列出所有**名词实体**（用户、订单、会话…）
- 标注每个实体的字段、关系、生命周期
- 标记哪些是**持久化实体**，哪些是**瞬态状态**

### Step 3 — 模块划分（产出 `ARCHITECTURE.md` §2 模块清单）
对照领域模型与需求功能清单，拆分模块。每个模块写一张卡片：

```
## 模块名：<Name>
- 职责：一句话
- 不负责：明确写出"不做什么"（防止职责蔓延）
- 输入：从哪些模块/外部来
- 输出：暴露给谁
- 关键类型/接口：列签名（不写实现）
- 持有状态：有没有自己的状态？
```

**经验**：如果一个模块的"不负责"写不出来，说明它的职责还没想清楚，回到 Step 2。

### Step 4 — 依赖图（产出 `ARCHITECTURE.md` §3 依赖图）
- 画出模块间依赖箭头（推荐 Mermaid，纯文本可 diff）
- **手动验证 DAG**：从任一节点 DFS 不应回到自己
- 标出"接口边界"：哪些依赖是接口注入，哪些是直接调用

### Step 5 — 路线图（产出 `ROADMAP.md`）
按依赖图的拓扑顺序排开发节奏：
- 先做被依赖最多的底层模块
- 每个 milestone 必须能独立通过编译/构建并跑出某种"可见行为"
- 写明每个 milestone 完成的"验收标准"（不是"做完了"，是"做完了之后能演示什么"）

### Step 6 — 开发规范（产出 `CONVENTIONS.md`）
- 命名（类型 / 文件 / 目录 / 资产）
- 代码风格（缩进 / 注释策略 / 错误处理边界）
- 提交规范
- 测试策略（哪些必须有测试，哪些不要求）

### Step 7 — 派生文档（产出实现 spec / 资产清单等）
**只有上面 6 步都齐了，才能开始写派生文档**。
派生文档必须显式引用上游章节（"对应 `ARCHITECTURE.md` §2.3 的 XxxService 模块"），方便后续 diff 校验。

---

## 4. 文档变更协议

文档不是写完就锁死的，但变更必须**沿着上下游传播**：

| 变更点 | 必须同步更新 |
|---|---|
| 需求加/删/改功能 | 架构模块清单、路线图、派生文档 |
| 架构调整模块边界 | 依赖图、开发规范（如有命名调整）、派生文档 |
| UI/UX 改视觉 token | 派生文档（实现 spec / 资产清单），不影响架构 |
| 加新模块 | 架构 §2 + §3、路线图、开发规范（如新目录） |

**权威链**：`PRD.md > ARCHITECTURE.md > UIUX.md > CONVENTIONS.md > 派生文档`。
派生文档永远不能**反向**修改上游。如果在派生文档中发现矛盾，回去改上游，再让派生文档重新对齐。
**代码与架构漂移 > 24 小时即违规。**

---

## 5. 实施日志（execution log）

写代码 / 执行路线图期间，**每完成一个可独立验收的"部分"，必须在 `.project.agents/log` 写一份日志**。日志是给"下一个会话的我"看的 —— 让接手的会话能在不读所有代码的情况下知道：刚才完成了什么、哪些提交、下一步是什么。

### 5.1 何时写日志
- 完成一个路线图 milestone
- 完成一个 milestone 内独立可验收的子任务
- 完成一次非平凡的重构 / bug 修复
- 当前会话即将结束时（兜底，把上下文沉淀下来）

**判断标准**：如果这段工作下一个会话需要知道，就写。

### 5.2 日志文件命名
`.project.agents/log/YYYY-MM-DD-<slug>.md`
- `<slug>` = 简短动词 + 范围，kebab-case
- 同日多份日志按写作顺序累积（不覆盖、不合并），文件名加序号后缀：`-1`、`-2`…

### 5.3 日志内容模板
```markdown
# <一句话标题：完成了什么>

- **日期**：YYYY-MM-DD
- **关联**：路线图 M<N> / 子任务名 / 关联文档
- **会话上下文**：（可选）本会话从哪开始接手的

## 做了什么
- bullet 1
- bullet 2

## 提交
- `<short hash>` <commit subject>

（若本段未提交：明确写"未提交，工作树状态：…"并说明原因）

## 状态变更
- 架构文档：是否动过？动了哪一节？
- 需求/UI 文档：是否触发回归？
- 测试：跑了什么，结果

## 下一步
- 接下来要做的第一件事（具体到任务名）
- 已知阻塞 / 待澄清项
```

### 5.4 与提交的关系
日志**不替代** commit message，commit message 仍按 `CONVENTIONS.md` 写；日志是提交的**索引与解释**。

### 5.5 不写日志的情况
- 还没完成一个"可独立验收"的部分 —— 不要"写日志凑数"
- 纯文档调整 —— commit 自身已足够说明
- 实验性探索（最终被回滚的内容）—— 用 commit message 记录即可

---

## 6. 出问题时的排查流程

bug 来了不要直接钻进代码。按下列顺序：

1. **复现并定位现象**：能在哪个入口 / 哪个调用稳定复现？
2. **回到架构图**：这个现象涉及哪些模块？沿着依赖图圈出可能责任方。
3. **审查接口契约**：跨模块调用是否符合 `ARCHITECTURE.md` 中声明的接口？输入输出是否符合契约？
4. **缩小到单模块**：把嫌疑缩小到一个模块后，再读该模块代码。
5. **修复并回写经验**：如果发现是架构层面的漏洞，修完代码后**必须更新 `ARCHITECTURE.md` 或 `CONVENTIONS.md`**。

**反模式**：bug 一来就 grep 关键字、改一行试一下、再改一行试一下 —— 这是死亡螺旋，必须用流程压下去。

---

## 7. 反模式清单（"看到这些立刻警觉"）

- 出现语义为空的模块名（`Manager` / `Helper` / `Util` / `Common` / `Misc` / `Tools`）且行数 > 100 行
- 一个文件 import 超过 10 个本地模块
- 改一个 UI 改动需要动 3 个以上其他模块
- 同一份业务逻辑在两个地方各写了一遍
- PR 描述写"顺便修了 X"
- 新增功能时发现"无处归属"，于是塞进入口文件或主组件
- 文档与代码不一致超过 24 小时
- 出现没有在 `ARCHITECTURE.md` 中登记的新模块/新依赖方向

任何一条出现，**先停下来回到本指南或架构文档，不要继续往前推**。

---

## 8. 本项目当前阶段

> 本节随项目演进，不是规则的一部分。由 Agent 在每个 milestone 后更新。

<!-- 由 /ads:init（2026-08-19，Retrofit）填入：本项目为前端底座模板，治理已入位。 -->
- 当前状态：前端底座（`abacus-static-framework`）已完成治理落地（Retrofit），`src/framework/**` 只读、业务只写 `src/subsystem/**`；前后端共享约束单源化于工作区 `docs/`（`../../../docs/coding-standards.md`）。
- 下一步合规动作：新业务子系统按 `docs/coding-standards.md §7`（AI 生成工作流）开发；任何新增模块、目录或依赖方向先回写本仓库 `ARCHITECTURE.md`，再写代码。
