﻿# 项目开发规范（AI协作）

本文档是面向 AI 与开发者的项目开发规范。

阅读顺序要求：

1. [项目文件结构说明.md](./项目文件结构说明.md)
2. [项目完整链路说明.md](./项目完整链路说明.md)
3. 当前文件

原则：

- 目标是“让项目更清晰、更可维护、更可测试”，不是单纯把代码拆碎。
- 重构优先考虑稳定性、职责边界与可理解性。
- 任何新增功能都必须沿现有分层接入，禁止重新堆回大文件。
- 乱码问题视为阻塞问题，不是“后面再顺手修”的小问题。

## 0. AI 协作执行协议

本节是所有 AI 开发、审查、合并、发版任务的前置要求，优先级高于后续各专项规则。

### 0.1 开发前必须实际阅读

- 任何涉及代码、流程、UI、步骤、配置、测试、文档、提交、合并、发布的任务，开始前必须实际阅读或重新核对：
  - [项目文件结构说明.md](./项目文件结构说明.md)
  - [项目完整链路说明.md](./项目完整链路说明.md)
  - 当前文件
- 不能只凭历史记忆、上一次会话摘要或“看起来知道项目”直接开发。
- 如果用户指出“先分析”“只分析”“暂时不改”，只能输出分析，不得擅自改代码或提交。
- 如果用户要求“开始开发”“按照清单开发”“提交代码”，必须按阶段推进到完成，不能停在方案层。

### 0.2 开发方案与开发清单

用户要求写开发方案时，方案必须至少包含：

1. 需求理解与真实目标。
2. 现有源码链路分析。
3. 是否符合要求、是否完善、是否完整、是否正确。
4. 是否符合本开发规范、现有架构和现有命名。
5. 方案自身是否有缺陷、边界遗漏或上下游设计冲突。
6. 与本功能无直接 UI 关系但有逻辑关联的模块检查。
7. 分阶段开发清单。
8. 每个阶段完成后的自检项。
9. 最终全量审查项。

如果方案文件创建在 `docs/md/` 下，默认认为它是本地开发方案，不随提交上传；除非用户明确要求上传，否则不要强行 `git add` 该目录。

### 0.3 阶段化开发硬要求

- 进入开发后，必须按开发清单一个阶段一个阶段完成。
- 每完成一个阶段，必须自检：
  - 相关代码是否都改到。
  - 步骤流、状态流、日志流、UI 流是否一致。
  - 是否有设计缺漏、逻辑缺陷和边界问题。
  - 是否引入乱码、错码、异常替换字符。
  - 定向测试或必要的静态检查是否通过。
- 阶段自检未通过时，不能进入下一阶段。
- 最终提交前必须再做一次全局审查，不能只依赖单个局部测试。

### 0.4 分析与实现不能脱节

- 分析中确认“不应该出现”的页面或状态，开发时就应从对应步骤清理掉，不要继续保留一堆“保险式兼容”造成流程混乱。
- 如果需求是“直接升级项目”，不要再保留旧分支兼容、旧页面兜底或旧隐藏逻辑；除非用户明确要求保留。
- 如果为了防御未知页面而保留分支，必须说明它属于哪个真实模式、哪个真实步骤，否则视为职责泄漏。
- 不能把某个步骤本不该处理的页面偷偷塞到后续步骤里收尾。

### 0.5 提交、合并、推送前置检查

提交前至少确认：

1. `git status --short` 只包含本次任务应提交文件。
2. `git diff --check` 无空白错误。
3. 修改过的 JavaScript 文件通过 `node --check`。
4. 定向测试已覆盖本次改动的关键路径。
5. 代码改动任务默认执行 `npm test`，除非用户明确要求不跑或环境确实无法运行；无法运行必须说明原因。
6. 中文文案、日志、注释、文档无可见乱码。
7. 如果提交，提交信息必须用中文说明真实改动，不得写“update”“fix”“AI 修改”这类空泛信息。
8. 如果用户要求推送或更新 `master`，推送后必须确认本地 `master` 与 `origin/master` 指向同一提交。

## 1. 架构原则

### 1.1 背景层原则

- [background.js](./background.js) 应尽量保持为入口壳、装配层和少量保留函数。
- 业务流程优先放到：
  - `background/steps/`
  - `background/*.js` 的共享模块
- 不要把新 provider、大段自动运行逻辑、大段消息分发逻辑直接写回 `background.js`。

### 1.2 步骤原则

- 每个步骤必须有清晰边界。
- 步骤文件应优先使用语义化名称，不再使用 `stepX.js` 命名。
- 步骤顺序统一由：
  - [data/step-definitions.js](./data/step-definitions.js)
  - [background/steps/registry.js](./background/steps/registry.js)
  共同管理。
- 步骤显示和执行必须以 `key / nodeId` 为主，不得重新回到硬编码步骤号驱动流程的写法。
- 同一个可见步骤号在不同模式下可能代表不同业务位置；日志、完成信号、错误恢复和 UI 渲染必须按当前步骤定义解析。
- 如果某个模式需要新增中间步骤，应通过共享步骤定义新增节点，而不是在旧步骤里暗中串联多个业务动作。

### 1.3 前后端步骤定义共享原则

- 任何步骤标题、顺序、key 变更，必须优先改 [data/step-definitions.js](./data/step-definitions.js)。
- 不允许只改 sidepanel 文案而不改共享定义。
- 不允许只改 registry 而不改共享定义。
- 不允许让 sidepanel 用一套步骤、background 用另一套步骤；步骤列表、节点注册、手动跳过、自动运行、状态恢复必须指向同一套定义。
- 新模式下某个步骤不应存在时，执行器和自动运行都必须能从当前模式 registry 中得到一致结论，不能靠运行时碰错后再回退。

### 1.4 Flow / Workflow / nodeId 架构基线

项目已经从“固定 1~10 步数字流程”升级为“flow + workflow node”模型。后续开发必须以这个模型为基线，不能退回旧写法。

当前约定：

- `activeFlowId` 是当前 flow 标识，默认是 `openai`。
- [data/step-definitions.js](./data/step-definitions.js) 的 `FLOW_DEFINITION_BUILDERS` 是 flow 注册入口。
- `getSteps(options)` 返回面向兼容和 UI 的步骤列表。
- `getNodes(options)` / `getWorkflow(options)` 返回面向执行与状态机的 workflow 节点列表。
- `step.id` 是 legacy 可见步骤号，只能用于 UI 展示、人工沟通和兼容旧入口。
- `step.key` / `node.nodeId` 才是流程执行、状态、跳过、恢复、日志归属的主键。
- `node.executeKey` 表示实际执行器 key；默认与 `nodeId` 一致，只有确有复用需求时才允许不同。
- `node.next` 表示 workflow 后继节点；没有显式 next 时才允许按当前节点列表线性补全。

不允许的退化写法：

- 新代码用 `if (step === 8)` 判断业务含义。
- 新代码用固定数组 `[1,2,3...]` 推导当前流程。
- 新代码只更新 `STEP_IDS / STEP_DEFAULT_STATUSES`，却不更新 `NODE_IDS / NODE_DEFAULT_STATUSES`。
- 新代码绕过 `getStepDefinitionsForState / getStepRegistryForState / getWorkflowNodesForMode` 自己拼步骤。
- 新代码把 Plus、手机号注册、绑定后重登等模式写成 sidepanel 局部硬编码列表。
- 新 code path 只按可见步骤号重试，不按当前 `nodeId` 找恢复锚点。

### 1.5 步骤 key / nodeId 状态原则

- 后台执行必须优先通过当前 state 解析 node registry：`activeFlowId`、`plusModeEnabled`、`plusPaymentMethod`、`signupMethod`、以及影响步骤列表的开关都必须参与解析。
- 自动运行、手动跳过、节点完成、节点失败、节点等待器必须优先使用 `nodeId`。
- 可见步骤号只能作为兼容输入；一旦进入后台，必须尽快解析为当前模式下的 `nodeId`。
- 如果同一个可见步骤号在不同模式下对应不同节点，必须以当前 workflow 为准，不能用普通模式含义推断。
- 新增步骤时必须同步检查：
  - `data/step-definitions.js` 的 step / node 定义。
  - `background.js` 或 registry 装配中的执行器映射。
  - `AUTH_CHAIN_NODE_IDS`、自动运行后台完成集合、手动跳过和等待器是否需要纳入。
  - sidepanel 的 `workflowNodes`、`NODE_IDS`、状态渲染和手动按钮是否能自动覆盖。
  - 测试是否覆盖新节点在所有相关模式下的顺序、标题和最后一步。
- 不允许只为了复用旧测试而保留“数字步骤即业务含义”的假设。

### 1.6 运行模式与能力解析原则

项目现在至少有这些会改变流程或步骤含义的维度：

- `activeFlowId`
- `plusModeEnabled`
- `plusPaymentMethod`
- `signupMethod`
- `phoneVerificationEnabled`
- `phoneSignupReloginAfterBindEmailEnabled`
- `contributionMode`

开发时必须先判断某个配置是：

- 持久配置。
- 当前轮冻结状态。
- sidepanel 运行态 UI 模式。
- flow 能力或步骤定义参数。
- 单次执行 payload。

不能把它们混在一起。例如：

- `contributionMode` 是运行态 UI 模式，不是新的 `panelMode`。
- `resolvedSignupMethod` 是当前轮冻结结果，不等同于用户此刻 UI 上选择的 `signupMethod`。
- 强制绑定邮箱后重登用邮箱身份，只能通过单次执行参数覆盖登录身份，不能持久改写 `signupMethod`。
- flow 能力不足时必须在步骤定义层或启动校验层处理，不能等执行到不存在的节点后才报错。

### 1.7 日志步骤号原则

- 步骤相关日志必须通过结构化元数据传递步骤号：`addLog(message, level, { step, stepKey })` 或内容脚本 `log(message, level, { step, stepKey })`。
- sidepanel 只能读取日志条目的 `entry.step` 渲染步骤标签，禁止再用正则从日志正文解析 `步骤 X` / `Step X`。
- Plus 模式复用普通执行器时，必须先按当前运行态解析可见步骤号，再传给日志、完成信号、错误信号和内容脚本 payload；禁止在复用执行器里写死普通模式步骤号。
- 日志正文可以在业务说明里提到“回到步骤 X”这类操作目标，但不能把正文前缀当作当前日志所属步骤。
- 不做旧日志文本兼容；如果旧日志没有结构化 `step`，sidepanel 不需要补推断步骤标签。

## 2. 模块边界规则

### 2.1 可以继续增长的文件

允许增长，但必须保持边界清晰：

- provider 领域实现文件
- 某个单独步骤文件
- 某个单独 manager 文件

### 2.2 不应继续膨胀的文件

- [background.js](./background.js)
- [sidepanel/sidepanel.js](./sidepanel/sidepanel.js)

如果在这两个文件里新增了大段逻辑，应优先判断是否应该下沉到模块。

## 3. 新增功能接入规范

### 3.1 新增步骤

必须同步检查：

1. 是否需要新增步骤文件到 `background/steps/`，还是复用现有语义执行器。
2. 更新 [data/step-definitions.js](./data/step-definitions.js) 的 step / node 定义。
3. 更新后台执行器映射或 registry 装配。
4. 检查 `getSteps / getNodes / getWorkflow` 是否能在所有相关模式下返回正确顺序。
5. 检查 sidepanel 动态步骤渲染是否已自动覆盖，包括 `workflowNodes / NODE_IDS`。
6. 检查 auto-run 是否需要纳入此节点。
7. 检查手动跳过、节点等待、完成状态、失败恢复锚点是否按 `nodeId` 工作。
8. 检查状态流、回退流、日志流是否完整。
9. 补测试。

新增步骤时不能只加一个执行函数。只要用户能在 UI 看到、自动流程能跑到、失败后能恢复，就必须完成上面整条链路。

### 3.2 新增 provider

必须同步检查：

1. 是否有纯工具模块
2. 是否需要 background provider 调度逻辑
3. 是否需要 sidepanel 配置项
4. 是否需要 Step 4 / 8 验证码链路接入
5. 是否需要成功收尾逻辑
6. 是否需要 README 与完整链路文档更新

补充约定：

- 如果新增来源本身已经提供稳定的后台协议接口，可以直接走协议分支接入：
  - 步骤 7 通过 `background/panel-bridge.js` 生成 `auth_url`
  - 步骤 10 通过 `background/steps/platform-verify.js` 直接提交 localhost callback
- 这类来源优先复用现有 OpenAI 授权页与 localhost callback 主链，不要为了“看起来统一”再额外新增一套页面 DOM 自动点击内容脚本。
- 只有当目标来源没有可用协议接口、必须依赖后台页面按钮时，才新增对应的 panel content script。

### 3.2.1 共享别名邮箱逻辑补充

当 Gmail / 2925 这类“既影响注册邮箱生成，又影响 sidepanel 表单行为”的 provider 发生变化时，必须优先检查是否应落入共享层，而不是继续把规则分散写在：

- `background.js`
- `sidepanel/sidepanel.js`
- 某一个单独 provider 分支里

当前约定：

- Gmail / 2925 的基邮箱解析、兼容性判断、别名生成、UI 文案优先收敛到 `managed-alias-utils.js`
- `2925` 是否参与“共享别名邮箱链路”必须由共享层统一判断；当前只有 `mail2925Mode = provide` 才允许把 `2925` 视为别名邮箱 provider，`receive` 不能在 sidepanel / step / provider 分支里各自偷写一套判断
- `background/generated-email-helpers.js` 只负责调度，不应再次复制 Gmail / 2925 规则
- `background/signup-flow-helpers.js` 只负责“复用已有邮箱还是重新生成”的流程决策
- `sidepanel/sidepanel.js` 只负责 UI 接线、校验触发和状态同步
- Hotmail / 2925 账号池这类跨 provider 的 sidepanel 表单显隐、头部按钮文案切换与共用操作行，应优先收敛到共享 UI helper（当前为 `sidepanel/account-pool-ui.js`），不要在各自 manager 中复制一套近似状态机
- 如果 `2925` 的某个运行态模式会让“别名基邮箱”和“账号池 / 当前账号选择”出现不同显隐规则，必须优先拆行或拆成独立配置块，不能把账号池开关绑死在别名基邮箱那一行里

### 3.3 新增配置项

必须同步检查：

1. 默认值
2. 归一化
3. 导入导出
4. state restore
5. sidepanel UI
6. 是否挂在正确的职责域中
7. 文档

### 3.4 新增运行态模式

如果新增的是“运行态 UI 模式”而不是持久配置或新来源，必须先把边界说清楚，再落代码。

当前约定示例：

- `contributionMode` 是 sidepanel 的运行态 UI 模式，不是新的 `panelMode`
- `panelMode` 当前允许 `cpa | sub2api | codex2api`
- 运行态模式不能混进 `PERSISTED_SETTING_DEFAULTS`
- 运行态模式不能混进配置导入/导出
- 如果运行态模式会临时覆盖某些持久配置的显示值，必须同时处理好“退出模式后恢复”和“自动保存不能误覆盖原配置”这两个问题
- 如果运行态模式要隐藏某一行 UI，必须先检查这行里是否绑定了不该一起隐藏的其他设置；必要时先拆行，再做显隐

当前贡献模式补充约定：

- 贡献模式属于 `CPA` 来源下的特殊业务模式，不是新的 provider
- 贡献模式允许扩展内承接公开 OAuth 交互，但只能调用公开接口，不能触碰 `/v0/management/*`
- 如果产品要求“开始贡献”和主自动流走同一条链路，则优先把贡献服务接入步骤 7 / 10，而不是额外分出一套平行 mini-flow
- 贡献流程的后台公开 OAuth 状态机应优先收敛到独立模块，例如 `background/contribution-oauth.js`
- 贡献模式的侧栏按钮、状态展示和轮询调度应优先收敛到独立 manager，例如 `sidepanel/contribution-mode.js`
- 如果服务端当前返回“无需手动提交 callback”，扩展端必须把它当兼容成功态处理，不能简单按 HTTP 非 200 直接视为失败

### 3.4.1 iCloud Hide My Email 维护补充

- iCloud Hide My Email 的会话校验、页面上下文回退、别名缓存回退和 `maildomainws` 兼容参数属于同一条链路；修改其中任一环时，必须同步检查列表加载、别名生成、保留、删除、自动运行等待邮箱和 sidepanel 登录提示。
- iCloud 登录态判断不能只看单个 HTTP 状态码。`401 / 403 / 421 / 429 / 5xx` 可能来自后台请求上下文、CORS 或服务节点波动，必须结合错误文案、页面上下文回退结果和用户提示文案判断。
- iCloud 别名缓存只能作为短暂失败回退，不允许替代线上列表成为最终状态来源；已用和保留状态仍然以 `manualAliasUsage`、`preservedAliases` 与最新线上列表合并后的结果为准。
- 如果新增 iCloud 相关回退路径，必须补覆盖登录提示、缓存回退、自动运行停止重试和 reserve 异常恢复的测试，并同步更新 [项目完整链路说明.md](./项目完整链路说明.md)。

### 3.5 OAuth / 接码 / 注册身份链路规范

OAuth 登录后链路是本项目最容易出现“功能重复、页面冲突、步骤偷跑”的区域。任何改动都必须先区分注册模式、登录身份和当前认证页状态。

#### 3.5.1 邮箱注册模式

- `刷新 OAuth 并登录` 只输入邮箱身份。
- 提交邮箱后可以进入密码页，也可以进入一次性邮箱登录验证码页。
- 密码提交后允许：
  - 进入登录验证码页。
  - 直接进入 OAuth 授权页。
  - 直接进入手机号验证相关页面，交给后续 `手机号验证` 节点。
- `获取登录验证码` 只处理邮箱登录验证码页。
- 如果已经在 OAuth 授权页或手机号验证相关页面，`获取登录验证码` 只能跳过并交给对应后续节点，不得处理添加邮箱。
- `手机号验证` 节点只属于邮箱注册模式的 OAuth 后置补手机号链路：
  - 已经在 OAuth 授权页则跳过。
  - 进入添加手机号页但未开启手机接码则报错。
  - 开启手机接码才允许添加手机号并获取短信验证码。
- `自动确认 OAuth` 只处理 OAuth 授权页和 localhost 回调，不得再隐式处理手机号页或添加邮箱页。

#### 3.5.2 手机号注册模式

- `刷新 OAuth 并登录` 只输入手机号身份，使用本轮 `signupPhone* / accountIdentifier*` 中确认的手机号。
- `获取登录验证码` 只处理手机号登录短信验证码或 OAuth 授权页跳过，不得落回邮箱 provider。
- 如果手机号注册登录后进入添加邮箱页，必须交给独立 `绑定邮箱` 节点。
- `绑定邮箱` 只处理添加邮箱页和已在 OAuth 授权页时的跳过；提交邮箱后必须进入邮箱验证码页或由后续设计显式重登。
- 旧流程下 `获取绑定邮箱验证码` 只处理绑定邮箱验证码页。
- 新增“绑定后重登”这类流程时，必须新增显式节点，例如：
  - `绑定邮箱后刷新 OAuth 并登录（邮箱）`
  - `获取登录验证码（邮箱）`
  - `手机号验证`
- 强制邮箱重登只能在该次执行参数中生效，不能把全局 `signupMethod` 持久改成邮箱注册。
- 手机号注册模式不得使用号码复用或白嫖复用；UI 必须自动禁用并锁定相关开关，切回邮箱注册模式后再恢复。

#### 3.5.3 不允许的 OAuth 写法

- 不允许手机号注册模式的登录验证码页识别失败后落回 Cloudflare Temp Email 或其他邮箱 provider。
- 不允许邮箱注册模式进入 `add-email`。
- 不允许手机号注册模式进入 `add-phone` 后走邮箱注册补手机号逻辑。
- 不允许 `confirm-oauth` 暗中完成手机号验证、绑定邮箱或邮箱验证码。
- 不允许为了“看起来稳”在一个步骤里同时处理邮箱验证码、短信验证码、添加邮箱、添加手机号、OAuth 授权页；确实存在多分支时必须拆成独立节点。
- 不允许只改后台流程，不同步更新侧栏步骤显示、手动跳过、自动运行、失败恢复和测试。

### 3.6 UI 与配置项放置规范

- 新开关必须放在对应业务域附近，不得随便插入到无关配置区。
- 接码相关配置必须放在接码卡内；注册方式相关配置必须靠近 `注册方式`。
- 配置项显隐必须和真实可用模式一致：不可用时隐藏或禁用，不能只靠用户“不要点”。
- 持久配置、运行态输入、当前订单状态必须区分清楚；不能把接码订单手机号、账号身份手机号、后置验证手机号混成一个字段。
- 如果某个 UI 开关会改变步骤列表，必须立即同步刷新共享步骤定义，并保持状态恢复后显示一致。

## 4. 测试规范

### 4.1 原则

- 任何结构性重构都必须伴随测试迁移或新增。
- 优先测试：
  - 模块是否接入
  - 核心纯函数是否仍可验证
  - 回退、停止、异常传播是否仍正确

### 4.2 不允许的做法

- 修改结构后不补测试
- 只跑局部测试，不跑全量回归
- 为了通过测试而破坏实际运行边界

### 4.3 最低要求

完成一次结构性改动后，至少执行：

```bash
bun test
```

补充说明：

- 实际执行命令以仓库当前 `package.json` 为准
- 本仓库当前全量回归命令为：

```bash
npm test
```

### 4.4 分阶段测试要求

- 每个开发阶段完成后，至少运行与该阶段直接相关的定向测试或静态检查。
- 如果新增步骤定义，必须覆盖：
  - `getSteps` 与 `getNodes` 两套输出。
  - `getWorkflow` 的 `nodeIds` 顺序。
  - 普通模式步骤列表。
  - Plus 模式步骤列表。
  - 邮箱注册模式步骤列表。
  - 手机号注册模式步骤列表。
  - 新开关打开 / 关闭两种步骤列表。
- 如果新增或调整自动运行节点，必须覆盖 registry、后台执行器、完成状态、跳过状态、失败恢复锚点，并确认恢复锚点按 `nodeId` 或当前 workflow 解析。
- 如果调整 sidepanel 配置或步骤显示，必须覆盖保存、恢复、显隐、禁用态、动态步骤刷新。
- 如果只修文档，可不运行全量代码测试，但必须至少做文档内容、链接和乱码检查。
- 测试失败时不得提交；除非用户明确要求保留失败状态用于排查，否则必须先修复。

## 5. 文档更新规范

### 5.1 必须更新文档的场景

- 文件新增、删除、重命名后
  更新 [项目文件结构说明.md](./项目文件结构说明.md)
- 功能链路变化
  更新 [项目完整链路说明.md](./项目完整链路说明.md)
- 开发流程、边界、约束变化
  更新当前文件

### 5.2 文档更新要求

- 不能只改代码不改文档
- 不能只改文档标题不改正文细节
- 不能让结构文档漏文件
- 不能让链路文档落后于真实实现
- 不能只在 `docs/md/` 写开发方案，而不更新根目录长期文档。
- 不能把旧机器路径、旧下载目录路径写入新文档链接；仓库内文档必须优先使用相对路径。
- 如果实现和开发方案不一致，最终必须以真实实现更新长期文档，不能让方案文档成为唯一说明。

### 5.3 `docs/md/` 开发方案约定

- `docs/md/` 默认是本地方案、分析、草稿目录，当前被 `.gitignore` 忽略。
- 用户要求“写开发方案”但又说明“不上传”时，方案应放在 `docs/md/`，并且提交时不得加入暂存区。
- 用户明确要求方案也上传时，必须先确认 `.gitignore` 与文件路径策略，再决定是否移动到非忽略目录。
- 开发完成后，如果功能链路、文件结构或协作规范发生变化，必须更新根目录长期文档；不能用 `docs/md/` 草稿替代。

### 5.4 乱码要求

- 所有中文文档、中文注释、中文日志、sidepanel 文案、错误提示文案都必须避免乱码。
- 修改任何包含中文的文件时，必须把“乱码检查”视为与“功能是否正确”同级的必做项。
- 如果某次修改引入了可见乱码，则该次开发视为未完成，不能提交为最终结果。
- 不允许把“当前终端显示有点乱，但文件也许没问题”当作默认成立；必须做显式检查。
- 如果文件历史上曾出现过编码问题，修改后必须再次审查该文件整体，而不是只看改动片段。
- 如果终端输出乱码但文件可能正常，必须通过 `Get-Content -Encoding UTF8`、编辑器视图、或其他可靠方式确认文件真实内容。
- 禁止在未确认编码的情况下批量重写中文文件。

## 6. 命名规范

### 6.1 文件命名

- 步骤文件使用语义化名称
- 工具文件按职责命名
- 不要再新增 `misc.js`、`temp.js`、`new.js`、`helper2.js` 这种模糊文件名

### 6.2 key 命名

- 步骤 key 使用短语义英文 kebab-case
- message type 保持稳定，新增时优先语义化大写常量风格

## 7. 代码风格与实现要求

- 优先复用现有模块，不重复发明一套新流程
- 共享逻辑先提公共层，再让步骤层调用
- 代码新增后应尽量减少主文件体积，而不是只做“形式拆分”
- 观察、留档、日志、导出这类横切能力必须优先挂在独立配置域下，不能借某个 provider 的业务开关隐式控制
- 保留少量兼容型薄包装是允许的，但必须有明确目的：
  - 运行时装配
  - 测试迁移过渡
- 如果某个薄包装已经没有存在意义，应在后续重构中清掉
- 涉及中文内容的文件必须保持稳定编码，修改后要主动检查是否出现乱码、错码、异常替换字符。
- 不能用“临时兼容”替代清晰设计。用户要求清理旧逻辑时，应删除不再可能出现的页面分支和状态分支。
- 不能把业务模式判断散落到多个文件里各写一份；优先收敛到共享工具、共享步骤定义或明确的执行器入口。
- 新增配置项必须走完整链路：默认值、归一化、保存、恢复、导入导出、UI 显隐、步骤刷新、测试。
- 新增流程节点必须走完整链路：共享定义、后台 registry、执行器、自动运行、手动跳过、完成状态、失败恢复、日志元数据、测试。

## 8. AI 开发时的自检清单

每次修改后至少自问：

1. 我开发前是否重新核对了三份根目录文档？
2. 我这次新增逻辑是不是应该下沉到模块？
3. 我有没有破坏共享步骤定义？
4. 我有没有漏掉 auto-run / sidepanel / message-router 其中之一？
5. 我有没有补或迁移测试？
6. 我有没有更新三份根目录文档？
7. 我新增或修改的文件是否有可见乱码？
8. 我有没有逐个检查本次改动涉及的中文文案、日志、注释、文档没有乱码？
9. 如果改动影响 Gmail / 2925 别名邮箱逻辑，我有没有同步检查 `managed-alias-utils.js`、sidepanel 接线、background 调度、auto-run reset 和回归测试？
10. 如果改动影响步骤日志，我有没有确认日志步骤号来自结构化 `step`，而不是来自日志正文？
11. 如果改动影响 OAuth / 接码 / 注册身份链路，我有没有逐项区分邮箱注册模式、手机号注册模式、OAuth 授权页、添加邮箱页、添加手机号页、邮箱验证码页、短信验证码页？
12. 如果某个页面在当前步骤不应该出现，我有没有删除或禁止对应分支，而不是继续兜底兼容？
13. 如果新增开关会改变流程，我有没有确认开关关闭时旧流程完全不变，打开时新流程完整可见？
14. 如果新增 UI，我有没有确认它放在正确业务域，并且显隐、禁用、保存、恢复都一致？
15. 如果创建了 `docs/md/` 方案文件，我有没有确认它是否应被提交？
16. 如果改动涉及 flow、步骤、模式切换，我有没有同时检查 `getSteps / getNodes / getWorkflow`、后台 registry、sidepanel `workflowNodes` 和 node 状态？
17. 我有没有新增任何用数字步骤判断业务含义的代码？如果有，是否能改为 `key / nodeId`？

## 9. 完成标准

当满足以下条件时，可以视为一次合格开发完成：

- 代码职责边界清晰
- 新旧功能链路完整
- 开发清单各阶段已逐项完成并自检
- flow / workflow / nodeId 链路保持一致，没有回退到数字步骤硬编码
- 开关关闭路径与旧流程保持一致
- 开关打开路径或新功能路径完整可见
- 全量测试通过
- 三份根目录文档已同步
- 没有可见乱码
- 已对本次修改涉及的文件做过乱码审查
- 提交前 `git diff --check` 通过
- 提交前工作区范围已确认，没有误提交忽略目录、草稿、密钥或无关文件

## 10. 特别要求

以后每次开发，如果影响到项目结构、功能链路或开发边界：

- 必须同步检查并在必要时更新：
  - [项目文件结构说明.md](./项目文件结构说明.md)
  - [项目完整链路说明.md](./项目完整链路说明.md)
  - [项目开发规范（AI协作）.md](./项目开发规范（AI协作）.md)

- 每次开发结束前，必须审查本次修改文件与关键运行文案没有乱码：
  - 文档正文
  - sidepanel 中文文案
  - 日志文案
  - 报错文案
  - 中文注释

这是硬要求，不是建议。

## 11. AI 最终回执要求

完成开发或审查后，最终回复必须简明说明：

1. 改了什么。
2. 是否遵守本规范，尤其是步骤边界、文档同步、测试和乱码检查。
3. 跑了哪些测试或检查。
4. 是否提交、提交号是什么。
5. 是否推送、推送到哪个分支。
6. 如果有未完成项、未运行测试或残余风险，必须明确说出。

不能只回复“已完成”，也不能把失败测试、未跑测试、未更新文档藏起来。
