From 679e8bd227bed42ceb86e9268ad4a585a0e12b2c Mon Sep 17 00:00:00 2001
From: huangning <huangning@boborobots.com>
Date: Sat, 18 Jul 2026 01:32:27 +0800
Subject: [PATCH] 完善研发治理与员工改密最小闭环
---
docs/任务/202607/0717-架构会话修复/00-需求与验收.md | 4
docs/研发体系/协作规范.md | 3
docs/任务/202607/0717-研发体系本地化/03-验收记录.md | 2
docs/任务/统一计划台账.md | 31
docs/任务/202607/0717-员工修改密码/导读.md | 10
docs/任务/202607/0717-模块化单体架构方案/04-本轮结论.md | 11
docs/架构/多客户端API与认证契约.md | 213 ++
docs/任务/202607/0717-架构会话修复/02-实现与自测记录.md | 14
docs/任务/202607/0717-模块化单体架构方案/01-计划改动清单.md | 40
docs/任务/202607/0717-研发体系本地化/导读.md | 4
docs/任务/协作事件.md | 1922 ++++++++++++++++++++++++++
docs/环境/导读.md | 1
docs/任务/202607/0717-研发体系本地化/04-本轮结论.md | 6
docs/任务/202607/0717-员工修改密码/01-计划改动清单.md | 206 ++
outputs/sales_crm_full_demo.html | 275 +++
docs/任务/角色队列/产品与项目管理.md | 11
docs/研发体系/角色会话串行调度规范.md | 4
docs/任务/角色队列/后端开发.md | 9
docs/研发体系/采用与裁剪记录.md | 20
docs/研发体系/会话故障迁移与交接规范.md | 100 +
docs/任务/角色队列/运维与发布.md | 4
docs/任务/202607/0717-架构会话修复/导读.md | 2
docs/架构/MySQL数据与渐进迁移方案.md | 227 +++
AGENTS.md | 1
docs/任务/202607/0717-模块化单体架构方案/03-验收记录.md | 25
work/crm_full_server.js | 361 ++++
docs/任务/角色队列/测试与质量.md | 8
docs/任务/202607/0717-员工修改密码/04-本轮结论.md | 12
docs/任务/202607/0717-架构会话修复/01-计划改动清单.md | 2
docs/任务/202607/0717-架构会话修复/04-本轮结论.md | 8
docs/架构/模块化单体目标架构方案.md | 255 +++
docs/环境/本地开发环境方案.md | 179 ++
docs/任务/角色队列/架构与数据治理.md | 7
docs/任务/202607/0717-模块化单体架构方案/00-需求与验收.md | 41
docs/任务/202607/0717-架构会话修复/03-验收记录.md | 2
docs/研发体系/角色/角色会话清单.md | 16
docs/任务/202607/0717-研发体系本地化/02-实现与自测记录.md | 10
docs/任务/202607/0717-模块化单体架构方案/02-实现与自测记录.md | 35
全局约束.md | 1
docs/任务/角色队列/UI与交互设计.md | 7
docs/任务/角色队列/代码审核与安全.md | 6
docs/任务/202607/0717-会话串行调度/04-本轮结论.md | 4
docs/任务/202607/0717-员工修改密码/03-验收记录.md | 82 +
docs/任务/202607/0717-员工修改密码/00-需求与验收.md | 35
docs/任务/202607/0717-员工修改密码/02-实现与自测记录.md | 48
docs/任务/202607/0717-模块化单体架构方案/导读.md | 26
docs/任务/202607/0717-会话串行调度/02-实现与自测记录.md | 9
docs/任务/角色队列/前端开发.md | 8
docs/任务/202607/0717-会话串行调度/导读.md | 2
docs/任务/角色队列/导读.md | 8
docs/研发体系/角色/角色索引.md | 12
docs/研发体系/导读.md | 1
52 files changed, 4,147 insertions(+), 183 deletions(-)
diff --git a/AGENTS.md b/AGENTS.md
index d2cbe85..cecfda2 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -21,6 +21,7 @@
- 协作事件可以先建立,但新消息必须先入队;会话为`active`或队列有锁时,调度器禁止向该会话发送新任务。
- 会话中断后优先恢复原队列项;普通追加消息默认排队,不能覆盖当前任务。
- 只有Owner明确要求停止或替换时才允许抢占;抢占前必须保存检查点并把原任务标记为`PAUSED/CANCELLED`。
+- 正式会话不可用时必须遵守[会话故障迁移与交接规范](<./docs/研发体系/会话故障迁移与交接规范.md>):新会话完整回读旧历史并通过交接验收后,旧会话才能归档。
## 当前代码入口
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\344\274\232\350\257\235\344\270\262\350\241\214\350\260\203\345\272\246/02-\345\256\236\347\216\260\344\270\216\350\207\252\346\265\213\350\256\260\345\275\225.md" "b/docs/\344\273\273\345\212\241/202607/0717-\344\274\232\350\257\235\344\270\262\350\241\214\350\260\203\345\272\246/02-\345\256\236\347\216\260\344\270\216\350\207\252\346\265\213\350\256\260\345\275\225.md"
index 4e2c651..8f843c5 100644
--- "a/docs/\344\273\273\345\212\241/202607/0717-\344\274\232\350\257\235\344\270\262\350\241\214\350\260\203\345\272\246/02-\345\256\236\347\216\260\344\270\216\350\207\252\346\265\213\350\256\260\345\275\225.md"
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\344\274\232\350\257\235\344\270\262\350\241\214\350\260\203\345\272\246/02-\345\256\236\347\216\260\344\270\216\350\207\252\346\265\213\350\256\260\345\275\225.md"
@@ -2,7 +2,7 @@
- 起始分支:`main`
- 起始commit:`6e62407`
-- 当前状态:本地完成,Gate P `PASS`。
+- 当前状态:已提交并推送,Gate P `PASS`。
- 业务影响:仅治理Markdown,不修改业务代码、配置、数据或运行态。
## 验证结果
@@ -10,16 +10,17 @@
| 检查 | 状态 |
| --- | --- |
| 8个正式角色各有唯一队列 | PASS;8个队列文件、8个唯一正式Thread ID |
-| 每个队列WIP=1且最多一个执行锁 | PASS;最终8个队列均IDLE,每个只有1个COMPLETED项,无RUNNING/WAITING残留 |
+| 每个队列WIP=1且最多一个执行锁 | PASS;最终8个队列均IDLE,无RUNNING/WAITING残留 |
| active/有锁时禁止投递规则已进入全部入口 | PASS;AGENTS、全局约束、开发流程、协作规范、角色宪章和8份职责卡均有规则 |
| 中断恢复与Owner显式抢占规则完整 | PASS;旧UI投递异常后保留QUEUE-003,由新正式会话恢复同一项后释放锁 |
| 8个角色接入回执 | PASS;COLLAB-20260717-042,8/8确认WIP=1和禁止抢占 |
| Markdown链接与敏感值扫描 | PASS;当前61份Markdown断链0、非模板占位符0、敏感值模式0 |
| 协作事件完整性 | PASS;42条事件编号重复0、必填字段缺失0 |
-| 已有业务文件未修改 | PASS;跟踪文件diff为0,61个未跟踪文件全部为Markdown |
+| 已有业务文件未修改 | PASS;提交前61个未跟踪文件全部为Markdown;远程交付只包含治理Markdown |
+| 队列编号全局唯一 | PASS;并发占号复核后保留架构QUEUE-009,后登记产品队列更正为QUEUE-010 |
## 未执行项
- 没有故意向正在active的会话注入第二条任务消息;该动作本身违反本次建立的安全规则。
- 后续真实多任务迭代需要继续观察FIFO、WAITING转PAUSED和Owner显式抢占流程。
-- 本轮文档尚未commit或push,HEAD仍为`6e62407`。
+- 本轮文档已随治理基线提交并推送到`origin/main`;首轮交付commit为`9ad42b5`。
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\344\274\232\350\257\235\344\270\262\350\241\214\350\260\203\345\272\246/04-\346\234\254\350\275\256\347\273\223\350\256\272.md" "b/docs/\344\273\273\345\212\241/202607/0717-\344\274\232\350\257\235\344\270\262\350\241\214\350\260\203\345\272\246/04-\346\234\254\350\275\256\347\273\223\350\256\272.md"
index 534f8f1..6061632 100644
--- "a/docs/\344\273\273\345\212\241/202607/0717-\344\274\232\350\257\235\344\270\262\350\241\214\350\260\203\345\272\246/04-\346\234\254\350\275\256\347\273\223\350\256\272.md"
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\344\274\232\350\257\235\344\270\262\350\241\214\350\260\203\345\272\246/04-\346\234\254\350\275\256\347\273\223\350\256\272.md"
@@ -1,8 +1,8 @@
# 本轮结论
-- 当前结论:本地完成,Gate P `PASS`。
+- 当前结论:已提交并推送,Gate P `PASS`。
- 已完成:规则设计、入口更新、8个独立队列、WIP=1执行锁、8/8角色接入和中断恢复演练。
-- 未完成:尚未提交或推送;后续真实多任务仍需持续遵守投递前双重检查。
+- 未完成:后续真实多任务仍需持续遵守全局队列编号检查和投递前双重检查。
- 当前Gate:Gate P `PASS`。
- 业务系统Go/No-Go:继续`No-Go`,本任务不解除BLOCK-001至003。
- 下一责任人:产品与项目管理、项目管理员按新队列机制恢复后续任务;Owner未明确抢占时不得打断。
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\344\274\232\350\257\235\344\270\262\350\241\214\350\260\203\345\272\246/\345\257\274\350\257\273.md" "b/docs/\344\273\273\345\212\241/202607/0717-\344\274\232\350\257\235\344\270\262\350\241\214\350\260\203\345\272\246/\345\257\274\350\257\273.md"
index ca4815c..4cb5d12 100644
--- "a/docs/\344\273\273\345\212\241/202607/0717-\344\274\232\350\257\235\344\270\262\350\241\214\350\260\203\345\272\246/\345\257\274\350\257\273.md"
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\344\274\232\350\257\235\344\270\262\350\241\214\350\260\203\345\272\246/\345\257\274\350\257\273.md"
@@ -1,7 +1,7 @@
# CRM-20260717-007 角色会话串行调度导读
- 优先级:P0
-- 状态:本地完成
+- 状态:已提交并推送
- 当前Gate:Gate P `PASS`
- 目标:所有正式角色会话WIP为1,协作消息只排队、不抢占当前任务
- 统一台账:[统一计划台账](<../../统一计划台账.md>)
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/00-\351\234\200\346\261\202\344\270\216\351\252\214\346\224\266.md" "b/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/00-\351\234\200\346\261\202\344\270\216\351\252\214\346\224\266.md"
index 0dc99fa..8489048 100644
--- "a/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/00-\351\234\200\346\261\202\344\270\216\351\252\214\346\224\266.md"
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/00-\351\234\200\346\261\202\344\270\216\351\252\214\346\224\266.md"
@@ -1,14 +1,23 @@
# 员工修改密码需求与验收
-- 需求版本:v0.2-MVP
-- 产品原则:先能用,再逐步好用;首版只解决员工不能自行修改本人密码的问题
-- 当前状态:MVP范围已收敛,待Owner确认问题并重新执行Gate N
+- 需求版本:v0.3-MVP(Owner冻结)
+- 产品原则:先落地基本需求,再分段迭代完善;首版只解决员工不能自行修改本人密码的问题,以可用闭环和交付效率优先,避免小题大做
+- 当前状态:MVP产品决策、Gate N、Gate R、一次独立Gate C和隔离环境最小Gate A均已PASS;第一阶段本地/隔离验收完成,Gate D/P和部署均未开始
## 目标
员工登录系统后,可以自行修改本人的登录密码,不再每次都依赖主管代为修改。
首版只建立“进入修改密码页面 → 验证当前密码 → 设置新密码 → 重新登录”的最小可用闭环,不在同一版本中完成整套账号安全体系重构。
+
+## 交付与迭代原则
+
+- 第一阶段只交付最小可用闭环,不因未来安全、架构或体验规划扩大本期范围。
+- 需求和技术边界清楚且Gate N/R已通过后,直接进入实现;除非范围、安全边界或唯一接口发生实质变化,不再追加重复方案评审。
+- 后续发现的增强项进入第二、三阶段清单,不阻塞首版基本功能落地。
+- 文档以“足够实现、足够验收、能够追溯”为准,不追求与当前小需求不相称的材料规模。
+- 首版执行路线压缩为:前后端最小实现 → 开发自测 → 一次独立代码审核 → 隔离测试环境验收。
+- 提高效率不能突破三条底线:只能修改本人密码、当前密码必须正确、密码不得泄露或在后端离线时假成功。
## MVP用户故事
@@ -37,11 +46,11 @@
- 后端再次校验新密码规则,不能只依赖前端校验。
- 修改成功后,旧密码不能继续登录,新密码可以正常登录。
- 修改密码接口后端不可用时,前端不得回退到浏览器本地模拟并显示假成功。
-- 请求、响应、普通日志和协作记录不得包含新旧密码值。
+- 当前密码和新密码只允许出现在已认证的专用改密接口请求体中;不得进入URL或查询参数、接口响应、普通日志、协作记录或浏览器持久化。非本地隔离环境必须通过HTTPS传输,本任务仍禁止正式生产部署。
### MVP密码规则
-- 新密码长度暂定为8至64个字符。
+- 新密码长度为8至64个字符。
- 新密码不得与当前密码相同。
- 新密码与确认密码必须完全一致。
- 首版不强制大小写、数字和符号组合,避免规则过度复杂。
@@ -66,6 +75,7 @@
- 不做多设备会话管理页面。
- 不在本任务中清理Git历史或完成全部运行数据治理;这些仍由`CRM-20260717-002`负责。
- 不为本功能进行前后端整体模块化重构。
+- 不部署到当前正式线上环境;第一阶段只允许在隔离的测试环境完成实现验证。
## MVP验收标准
@@ -107,12 +117,15 @@
## 已知风险与边界
- 当前系统的密码保存和登录凭证机制仍属于P0风险。MVP收敛是为了先完成基本功能,不代表接受明文密码作为长期方案。
-- 第一阶段可以形成可测试实现,但是否允许部署到当前线上环境,仍需代码审核与安全、测试和Owner依据精确版本决定。
+- 第一阶段可以形成可测试实现,但本需求版本明确禁止部署到当前正式线上环境。未来若申请线上部署,必须另行获得Owner授权并通过当时适用的安全、测试、部署和发布Gate。
- `BLOCK-001`至`BLOCK-003`和项目整体`No-Go`不会因MVP完成自动解除。
-## 需要Owner确认的问题
+## Owner决策(已确认)
-1. 是否接受首版密码长度规则为8至64个字符,暂不强制复杂组合?产品建议:接受。
-2. 是否接受修改成功后直接退出并要求重新登录?产品建议:接受,行为简单且容易验证。
-3. 是否接受首版继续沿用主管当前的密码重置方式,不做一次性临时密码和首次强制改密?产品建议:接受,后续单独增强。
-4. 第一阶段开发完成后,是否只先在测试环境验证,等密码哈希等P0安全整改完成后再正式部署?产品建议:是;如果要求立即部署,需要Owner明确接受仍存在的安全风险,但专业Gate仍不能被跳过。
+1. 首版密码长度为8至64个字符,暂不强制大小写、数字和符号组合。
+2. 修改成功后直接退出当前登录,员工使用新密码重新登录。
+3. 首版继续沿用主管当前的密码重置方式,不做一次性临时密码和首次登录强制改密。
+4. 第一阶段只在隔离测试环境验证,暂不部署到当前正式线上环境。
+5. 本需求按“小步快跑”推进:先完成基本功能,再分段完善;避免重复评审和过度设计,提高交付效率。
+
+以上五项由Owner于2026-07-17确认。前三项采用产品建议,第四项由Owner明确决定“先不部署到线上”,第五项由Owner在Gate R通过后再次强调。后续若改变任一决策,必须建立新的变更记录并重新判断受影响Gate,不得在实现中自行扩展。
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/01-\350\256\241\345\210\222\346\224\271\345\212\250\346\270\205\345\215\225.md" "b/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/01-\350\256\241\345\210\222\346\224\271\345\212\250\346\270\205\345\215\225.md"
index e835dc4..a79bdac 100644
--- "a/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/01-\350\256\241\345\210\222\346\224\271\345\212\250\346\270\205\345\215\225.md"
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/01-\350\256\241\345\210\222\346\224\271\345\212\250\346\270\205\345\215\225.md"
@@ -1,8 +1,8 @@
# 计划改动清单
-- 对应需求版本:v0.2-MVP
-- 当前阶段:Gate N需求整改
-- 原则:只做员工本人修改密码闭环,不在首版重构整套认证体系
+- 对应需求版本:v0.3-MVP(Owner冻结)
+- 当前阶段:前后端实现/开发自测、一次独立Gate C和QUEUE-043隔离环境最小Gate A均PASS;第一阶段本地/隔离验收完成,未部署线上
+- 原则:先落地基本功能、再分段迭代;只做员工本人修改密码闭环,不在首版重构整套认证体系,不重复评审已经冻结的方案
## 第一阶段候选改动
@@ -14,6 +14,199 @@
| 登录状态 | 修改成功后清除当前登录并返回登录页 | 前端/后端 | 旧密码失败、新密码成功 |
| 主管账号管理 | 保持现有新建账号和重置密码流程 | 前端/后端 | 原功能回归不受影响 |
| 最小测试 | 覆盖MVP十项验收标准 | 开发/测试 | 自动化或可复验的最小测试记录 |
+
+## Gate R统一冻结清单
+
+Gate R只冻结第一阶段最小实现材料,不把延期安全能力重新并入MVP。以下各项必须有明确结论、责任角色和可复核证据;任一适用项未PASS时不得进入业务实现。
+
+| 编号 | 必须冻结的内容 | 主责角色 | 通过条件 |
+| --- | --- | --- | --- |
+| R-01 | 本人改密专用接口契约 | 架构、后端、前端、安全 | 路径、方法、认证方式、请求字段、响应字段明确;不接受目标账号参数;当前密码和新密码只进入请求体 |
+| R-02 | 登录身份与账号状态 | 架构、后端、安全、测试 | 只使用后端已认证身份;未登录、停用账号和越权构造均被拒绝 |
+| R-03 | 密码与确认规则 | 后端、前端、测试 | 8至64字符的计数口径、两端空格不裁剪、新旧不同、确认密码归属及前后端一致性明确 |
+| R-04 | 原子更新、并发与失败语义 | 架构、后端、测试 | 校验和写入的顺序、并发冲突、失败不落盘、旧密码保留及错误返回明确 |
+| R-05 | 成功退出与重新认证 | 前端、后端、架构、测试 | 成功后清理当前登录并返回登录页;旧密码失败、新密码成功;完整多设备会话撤销继续延期 |
+| R-06 | 最小交互规格 | UI、前端 | 顶部入口、三字段表单、提交/取消、移动端单列、焦点与关闭、防重、提示和无障碍规则明确 |
+| R-07 | 稳定错误码和页面映射 | 架构、后端、前端、UI、测试 | 未登录、停用、当前密码错误、规则错误、新旧相同、并发冲突和后端不可用均有稳定且不泄密的映射 |
+| R-08 | 敏感值与故障关闭 | 安全、前端、后端、运维 | 密码不进入URL、查询参数、响应、日志、文档或浏览器持久化;后端离线不回退;非本地隔离环境使用HTTPS |
+| R-09 | 十项验收测试矩阵 | 测试、前端、后端、安全 | 隔离环境、虚构角色账号、正常/异常/越权/停用/离线/敏感值用例、自动化或可复验入口明确 |
+| R-10 | 测试数据复位与回滚 | 运维、架构、后端、测试 | 环境身份、备份点、虚构账号密码复位、失败回滚、验证与责任人明确;禁止接触生产账号数据 |
+| R-11 | 实现拆分与精确基线计划 | 前端、后端、架构、测试 | 前后端改动边界、自测项、精确diff/commit冻结方式及Gate C输入明确,不夹带模块化重构 |
+
+## Gate R角色输出
+
+- 架构与数据治理:统一接口、身份、原子性、并发、重新认证和回滚边界。
+- UI与交互设计:最小页面结构、状态、移动端和无障碍规格。
+- 前端开发:页面承载点、请求状态机、错误映射、登录清理和自测方案。
+- 后端开发:接口字段、认证身份、校验、持久化、并发和主管重置回归方案。
+- 代码审核与安全:威胁边界、敏感值规则、停止线及未来Gate C证据清单。
+- 测试与质量:十项验收矩阵、虚构样本、环境前置、自动化和脱敏证据。
+- 运维与发布:仅限隔离测试环境的部署、备份、复位和回滚方案;正式生产部署不在范围。
+
+## Gate R首轮结果与契约冲突
+
+| 角色 | 首轮结论 | 事件 | 当前处理 |
+| --- | --- | --- | --- |
+| 架构与数据治理 | PASS | COLLAB-20260717-077 | 分项通过;负责收敛唯一接口契约 |
+| UI与交互设计 | PASS | COLLAB-20260717-078 | 交互规格已冻结 |
+| 前端开发 | CHANGES_REQUESTED | COLLAB-20260717-079 | QUEUE-024保持WAITING,等待唯一契约后复评 |
+| 后端开发 | PASS | COLLAB-20260717-080 | 分项通过;须确认架构收敛契约可实施 |
+| 代码审核与安全 | PASS | COLLAB-20260717-081 | 安全停止线与Gate C证据已冻结 |
+| 测试与质量 | CHANGES_REQUESTED | COLLAB-20260717-082 | QUEUE-027保持WAITING,等待唯一契约和可执行入口后复评 |
+| 运维与发布 | PASS | COLLAB-20260717-083 | 隔离测试环境机械方案已冻结 |
+
+当前必须收敛的技术差异:
+
+1. 接口路径:架构建议`POST /api/v1/me/password/change`,后端建议`POST /api/account/change-password`。
+2. 请求字段:架构与UI建议确认密码只在前端校验、请求体仅含当前密码和新密码;后端建议三字段均提交并由后端最终校验。
+3. 成功响应:架构建议`204 No Content`,后端建议`200`和脱敏成功标识。
+4. 错误码命名:两份分项的HTTP语义基本一致,但机器码名称尚未统一。
+5. 字符计数:前端与后端建议Unicode码点计数,需由架构写入唯一契约。
+
+共同事实保持不变:账号只来自后端认证上下文、不接受目标账号字段、停用账号拒绝、失败不落盘、同账号并发最多一次成功、后端离线失败关闭、成功后当前登录失效、密码不进入URL/响应/日志/文档/持久化。
+
+协作事件标题已只读复核为76个且76个唯一,重复0;测试和安全在文件并发更新期间看到的重复快照不再作为持续阻塞。
+
+## Gate R v0.4唯一接口契约(当前事实源)
+
+以下契约由架构与数据治理在COLLAB-20260717-087收敛为`PASS`,取代首轮架构和后端分项中的全部备选接口。产品需求版本仍为v0.3-MVP;v0.4仅是Gate R技术契约版本。
+
+### 接口与请求
+
+- 方法和路径:`POST /api/v1/me/password/change`。
+- `Content-Type`:`application/json`。
+- 认证:只使用`Authorization`头建立的后端认证上下文;账号不得来自路径、查询参数或请求体。
+- 请求体严格且只能包含`currentPassword: string`和`newPassword: string`。
+- `confirmPassword`只属于前端防误输入校验,不发送后端;它和任何用户名、用户ID、角色、状态、Token或未知字段均按`INVALID_REQUEST`拒绝。
+- 接口不接受查询参数。
+
+### 字符与校验
+
+- 新密码长度按Unicode码点计数,前后端等价于`Array.from(value).length`;8和64有效,7和65无效。
+- 当前密码和新密码均不裁剪、不折叠、不做Unicode规范化;空格计入码点数,新旧按原始字符串比较。
+- 后端顺序固定为:严格Schema → 认证 → 进入账号级临界区 → 重新读取账号与启用状态 → 验证当前密码 → 校验新密码长度 → 校验新旧不同 → CAS/原子持久化。
+
+### 成功响应
+
+- 成功返回`204 No Content`,响应体必须为空。
+- 设置`Cache-Control: no-store`。
+- 不返回账号对象、新Token或其他凭据。
+- 成功后当前认证失效;前端清除表单、认证和业务态并返回登录页。完整多设备会话撤销继续延期。
+
+### 稳定错误码
+
+错误结构固定为`error.code`、安全的`error.message`和`error.requestId`,不得包含密码、账号明细、存储细节、堆栈或完整请求。
+
+| HTTP | 稳定错误码 | UI唯一语义 |
+| --- | --- | --- |
+| 400 | `INVALID_REQUEST` | 固定“请求无效”,不得展示原始响应 |
+| 401 | `AUTHENTICATION_REQUIRED` | 清空表单和认证,返回登录页 |
+| 403 | `ACCOUNT_DISABLED` | 清空表单和认证,返回登录页并提示账号不可用 |
+| 422 | `CURRENT_PASSWORD_INCORRECT` | 只清空并聚焦当前密码 |
+| 422 | `PASSWORD_LENGTH_INVALID` | 聚焦新密码,提示8至64个Unicode码点 |
+| 422 | `NEW_PASSWORD_SAME_AS_CURRENT` | 聚焦新密码,提示不能与当前密码相同 |
+| 409 | `PASSWORD_UPDATE_CONFLICT` | 清空表单和认证,返回登录页并重新认证 |
+| 503 | `PASSWORD_CHANGE_UNAVAILABLE` | 保持失败状态、解除忙碌,禁止本地回退和自动重试 |
+| 500 | `INTERNAL_ERROR` | 固定通用错误,禁止展示原始响应或堆栈 |
+
+确认密码不一致是前端字段错误,不存在服务端确认密码错误码。网络断开和格式未知响应分别作为前端本地状态处理,均不得显示成功。
+
+### 原子、并发与兼容
+
+- 本人改密、主管重置和账号停用共享账号级写入原语与修订号/CAS;重叠写入最多一个成功。
+- 持久化失败不得发布内存新状态,原密码和原数据保持不变。
+- 主管原重置业务和授权保持不变,但不得新增第二套直接密码写入路径。
+- 当前隔离测试阶段限定单后端进程/单写入实例;多进程或多实例必须先补共享事务或锁方案,否则停止实施。
+
+### 已废止的备选
+
+- `POST /api/account/change-password`废止。
+- 三字段后端请求废止。
+- 成功`200`及带成功标识响应废止。
+- `AUTH_REQUIRED`、`CURRENT_PASSWORD_INVALID`、`PASSWORD_UNCHANGED`、`PASSWORD_CHANGE_CONFLICT`、`PASSWORD_UPDATE_UNAVAILABLE`等首轮备选命名废止。
+
+## Gate R跨角色实现细则 v0.4
+
+本节整合架构、UI、前后端、安全、测试和运维结论,是v0.4唯一接口契约的实现细则。前端、后端和测试已在原队列项完成复评,产品已汇总为整体PASS;若本节与首轮回执冲突,以本节及上方“Gate R v0.4唯一接口契约”为准。
+
+### 本人改密接口
+
+| 项目 | 冻结结论 |
+| --- | --- |
+| 方法与路径 | `POST /api/v1/me/password/change` |
+| 认证身份 | 仅使用现有受保护API的后端认证上下文;当前实现沿用认证头,禁止从URL、查询参数或请求体接收账号、用户ID、角色、状态或Token |
+| 请求体 | 严格只允许`currentPassword`、`newPassword`两个字符串字段;`confirmPassword`只在前端校验,不发送后端;出现额外字段返回`INVALID_REQUEST` |
+| 字符口径 | 新密码按Unicode码点计数,8和64均有效;不裁剪、不规范化两端空格;新旧密码按原始字符串比较 |
+| 成功响应 | `204 No Content`,设置禁止缓存语义;不返回账号、密码、新Token或其他凭据 |
+| 账号状态 | 进入写入临界区后重新读取权威账号状态;未认证、认证失效和停用账号均不得写入 |
+| 当前密码 | 后端必须基于临界区内最新状态验证;失败不得写入;当前密码不套用新密码长度规则 |
+| 原子与并发 | 本人改密、主管重置和账号停用共享同一账号级凭据写入原语;当前单进程隔离环境采用账号锁加版本/CAS,重叠写入最多一个成功,其余返回冲突;多进程或多写入实例必须停止并另行评审共享事务/CAS |
+| 失败语义 | 校验、临时写入或原子替换任一步失败,原密码和原数据保持不变;禁止自动重试密码写请求 |
+| 成功退出 | 后端不签发新凭据;前端清空三字段、当前认证和当前业务态并返回登录页;旧密码失败、新密码成功;完整多设备会话撤销继续延期 |
+| 主管兼容 | 保留主管原新建/重置业务语义和授权,接入同一凭据写入原语;本轮不得扩大主管权限或新增第二套直接写密码路径 |
+
+### 稳定错误码与页面动作
+
+| HTTP | 错误码 | 页面动作 |
+| --- | --- | --- |
+| 400 | `INVALID_REQUEST` | 表单级安全提示;缺字段、类型错误或额外字段 |
+| 401 | `AUTHENTICATION_REQUIRED` | 清空认证与表单,返回登录页并提示重新登录 |
+| 403 | `ACCOUNT_DISABLED` | 清空认证与表单,返回登录页并提示账号不可用 |
+| 422 | `CURRENT_PASSWORD_INCORRECT` | 仅清空并聚焦当前密码字段 |
+| 422 | `PASSWORD_LENGTH_INVALID` | 聚焦新密码字段,提示8至64字符 |
+| 422 | `NEW_PASSWORD_SAME_AS_CURRENT` | 聚焦新密码字段 |
+| 409 | `PASSWORD_UPDATE_CONFLICT` | 清空认证与表单,返回登录页并要求重新认证确认状态 |
+| 503 | `PASSWORD_CHANGE_UNAVAILABLE` | 留在对话框,解除忙碌,固定安全提示;禁止本地回退和自动重试 |
+| 500 | `INTERNAL_ERROR` | 留在对话框并显示固定安全提示,不展示原始响应或堆栈 |
+
+`confirmPassword`不进入后端,因此“两次输入不一致”是前端字段错误而不是服务端错误码。所有错误响应只允许稳定代码、安全提示和请求ID,不得包含密码、账号明细、存储状态、堆栈或完整请求内容。
+
+### 冻结交互规格
+
+- 入口位于顶部账号操作区、账号标识和退出附近;所有已登录且启用账号可见,不依赖业务权限;不新增侧边导航或URL参数。
+- 模态框按“当前密码—新密码—确认新密码”单列排列,均为密码输入,不预填、不恢复历史值、不持久化;确认字段仅用于前端一致性校验。
+- 打开后焦点进入当前密码;背景不可交互;Tab限制在模态框内;可见标签、错误关联和状态播报齐全,不只依赖颜色。
+- 提交前依次检查必填、Unicode码点8至64、新旧不同和确认一致,聚焦首个错误;当前密码正确性只由后端判断。
+- 提交前同步建立忙碌锁;提交中禁用字段、确认、取消和Esc,重复点击、回车或事件重入最多产生一个请求;失败后允许人工重试,禁止自动重试。
+- 空闲状态下取消或Esc立即清空三字段、错误和临时状态,关闭后焦点回到入口;遮罩点击不关闭。
+- 只有收到明确`204`才视为成功;随后清空敏感内存和登录状态并返回登录页,显示一次性“密码已修改,请使用新密码重新登录”。
+- 移动端360 CSS像素及以上保持单列、左右至少16像素安全间距、触控目标至少44×44 CSS像素;软键盘下可滚动,无水平溢出。
+- 后端离线、超时和未知响应必须失败关闭,不调用现有本地模拟接口,不写浏览器持久化,不显示成功。
+
+### 隔离测试环境与计划入口
+
+| 项目 | 冻结结论 |
+| --- | --- |
+| 环境标识 | `local-isolated-test`,固定Windows本机、单后端进程、单写入实例和精确commit |
+| 网络 | 只绑定`127.0.0.1`时可使用HTTP;任何非本机回环访问必须使用有效HTTPS,禁止忽略证书错误 |
+| 配置与数据 | 配置、虚构账号模板和快照只放在已忽略的`docs/local/测试环境/`;不得引用生产地址、凭据或当前运行数据文件 |
+| 虚构样本 | 启用员工A、启用员工B、主管、停用员工和匿名客户端;密码只在运行时注入,不进入文档、命令行、截图或Git |
+| 备份与复位 | 每轮前生成脱敏快照编号和校验值;测试后优先恢复完整快照;复位或校验失败立即停止 |
+| 计划自动化入口 | 实现阶段补齐`npm run test:password:api`、`npm run test:password:web`、`npm run test:password:concurrency`、`npm run test:password:sensitive`、`npm run test:password:reset`,并将结果映射到十项验收标准 |
+| 证据 | 只记录commit、环境ID、运行ID、用例编号、HTTP状态、稳定错误码、并发生效次数、快照校验值和脱敏扫描结论;不保存原始日志、完整请求响应或敏感值 |
+
+### 首轮冲突关闭记录
+
+- `confirmPassword`只在前端校验;后端新正式会话在原`QUEUE-20260717-032`确认两字段严格Schema可实施,结论见COLLAB-092。
+- 接口统一为`POST /api/v1/me/password/change`和`204 No Content`;前端在原`QUEUE-20260717-024`复评PASS,结论见COLLAB-095。
+- 前端首轮提出的接口、字符口径、错误码与交互分歧均已关闭,原执行锁已释放。
+- 测试首轮提出的事件唯一性、矩阵输入、环境复位和计划命令问题均已关闭;原`QUEUE-20260717-027`复评PASS,结论见COLLAB-096。
+- 产品通过COLLAB-098汇总七个专业角色最终均PASS,v0.4契约唯一且R-01至R-11无未决分歧;Gate R整体PASS。
+
+## Gate R最终结论
+
+| 角色/汇总 | 最终结论 | 结果事件 |
+| --- | --- | --- |
+| 架构与数据治理 | PASS | COLLAB-20260717-087 |
+| UI与交互设计 | PASS | COLLAB-20260717-078 |
+| 前端开发 | PASS | COLLAB-20260717-095 |
+| 后端开发 | PASS | COLLAB-20260717-092 |
+| 代码审核与安全 | PASS | COLLAB-20260717-081 |
+| 测试与质量 | PASS | COLLAB-20260717-096 |
+| 运维与发布 | PASS | COLLAB-20260717-083 |
+| 产品整体汇总 | PASS | COLLAB-20260717-098 |
+
+Gate R通过时只打开“另建精确实现任务”的前置条件,不等于自动授权实现。该时间点功能实现进度为0%,无可审核代码基线,未测试、未部署、不可上线;后续实现与验收结果以本文顶部状态和实现/验收记录为准。
## 首版明确不改
@@ -32,7 +225,10 @@
## 实施停止线
-- 新需求版本未通过适用Gate N前,不修改业务代码。
-- Gate R未冻结接口、字段、错误码和最小测试前,不进入实现。
+- Gate N已经PASS,但不等于实现授权。
+- Gate R已经整体PASS,但仍不等于实现授权;必须由Owner/项目管理员另建实现事件、精确队列和可审核基线后才能修改业务代码。
+- 首轮五项契约差异已经由v0.4唯一契约和COLLAB-092、095、096关闭;旧接口、三字段请求、成功200和旧错误码不得恢复。
+- 实现若发现多进程、多写入实例或无法提供账号级原子/CAS,必须停止并重新进入架构评审。
+- 第一阶段只允许部署到隔离测试环境进行验证;当前正式线上环境禁止部署,后续线上发布必须另立授权并通过适用Gate。
- 员工可以修改他人密码、当前密码错误仍能修改、后端断开却显示成功,任一情况均不得交付。
- 任何密码值进入URL、接口响应、普通日志或协作文档时立即停止并整改。
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/02-\345\256\236\347\216\260\344\270\216\350\207\252\346\265\213\350\256\260\345\275\225.md" "b/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/02-\345\256\236\347\216\260\344\270\216\350\207\252\346\265\213\350\256\260\345\275\225.md"
index 5197e2b..f0b6d11 100644
--- "a/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/02-\345\256\236\347\216\260\344\270\216\350\207\252\346\265\213\350\256\260\345\275\225.md"
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/02-\345\256\236\347\216\260\344\270\216\350\207\252\346\265\213\350\256\260\345\275\225.md"
@@ -1,7 +1,45 @@
# 实现与自测记录
-- 当前状态:未开始实现。
-- 当前 Gate:Gate N需求整改。
-- 已完成:根据Owner“先能用、再逐步好用”的要求,把需求收敛为v0.2-MVP,并把复杂安全与体验能力拆到后续阶段。
-- 未授权:业务代码、运行账号数据、部署配置和线上环境修改。
-- 下一步:Owner确认4项产品问题,重新收集适用角色Gate N结论;Gate R冻结最小接口与测试后再由开发角色记录精确实现基线。
+- 当前状态:前端QUEUE-039、后端QUEUE-040开发自测、一次独立Gate C和QUEUE-043隔离环境最小验收均`PASS`;第一阶段本地/隔离里程碑已完成。
+- 当前 Gate:Gate N/R/C和隔离环境最小Gate A均`PASS`;Gate D/P均未执行,部署和正式线上授权均未开始。
+- 已完成:根据Owner“先能用、再逐步好用”的要求,把需求冻结为v0.3-MVP;四项产品决策已经确认,复杂安全与体验能力拆到后续阶段。
+- 实现授权:Owner已明确按“先落地基本功能、再分段迭代”推进;本轮冻结代码已经形成,运行账号数据、部署配置、任何环境修改和正式线上部署仍未授权。
+- Gate N结果:架构、UI、前端、后端、安全、测试六角色均PASS;前端发现的密码请求边界矛盾已在同一QUEUE-014整改并复评PASS;COLLAB-065完成产品汇总。
+- Gate R首轮(历史):架构、UI、后端、安全、运维PASS;前端、测试CHANGES_REQUESTED。接口路径、字段、成功响应、错误码和字符计数当时尚未形成唯一契约。
+- 契约整改:COLLAB-20260717-087已冻结`POST /api/v1/me/password/change`、两字段请求、Unicode码点计数、成功204空响应和九个稳定错误码;首轮备选均已废止。
+- 复评结果:后端COLLAB-092、前端COLLAB-095、测试COLLAB-096均PASS;产品COLLAB-098汇总七个专业角色最终均PASS,Gate R整体PASS。
+- 当前队列:前端QUEUE-039、后端QUEUE-040、审核QUEUE-042和测试QUEUE-043均COMPLETED,相关执行锁均已释放。
+
+## 测试QUEUE-043隔离环境验收回填(2026-07-18)
+
+- 执行范围:`QUEUE-20260717-043 / COLLAB-20260717-148、149、151`;只验证Owner冻结的本人改密基本闭环,不重做Gate N/R/C,不扩大延期项。
+- 执行方式:前端做7项静态契约检查;后端通过`createServer`、`127.0.0.1`随机端口和进程内虚构存储完成12项回环API检查。短生命周期服务已关闭,未读取或修改`data/`、真实账号、客户数据、文件、代码、配置、Git、部署或生产运行态。
+- 验收结果:`PASS`,共19/19项通过。覆盖入口、三字段与确认、当前密码、Unicode 8至64码点且不裁剪/规范化、新旧不同、仅本人、严格两字段、仅204成功、成功退出并验证旧密码失效/新密码可登录、未知响应/离线失败关闭且无`localApi`、防重复、停用账号、主管重置/停用兼容、同账号并发最多一次成功、写失败不发布和敏感值扫描。
+- 未执行:真实浏览器E2E、真实文件持久化、多进程/多实例、部署、Gate D/P、生产环境,以及延期的哈希迁移、完整会话撤销、限流、审计和移动端能力。
+- 测试结论:首版在单进程、单写实例、虚构数据的本地隔离环境可用;不代表已部署、Gate D/P或正式线上可用。
+
+## 前端QUEUE-039实现与自测回填(2026-07-17)
+
+- 执行范围:`QUEUE-20260717-039 / COLLAB-20260717-109、132`;沿用原唯一执行锁,无新增业务队列。
+- 交接证据:新正式前端会话完整分页回读旧Thread `019f702e-eb7e-70d3-8271-06269945435a`的3个可见turn至`hasMore=false`;其中2个已完成、1个仍在进行。进行中turn没有完成或落盘证据,只继承其已公开的专用请求、禁止通用`api()`本地回退和单HTML局部实现检查点。
+- 实际代码改动:仅修改`outputs/sales_crm_full_demo.html`,增加顶部账号区“修改密码”入口、三字段无预填模态框、前端必填/确认/Unicode码点8至64/新旧不同校验、同步提交锁、独立15秒超时请求、严格两字段请求体、仅204成功、九个稳定错误码动作、网络及未知响应失败关闭、成功清理三字段/认证/内存业务态并返回登录页,以及360px单列、44px触控目标、焦点圈定、Esc/取消清理和状态播报。
+- 精确代码diff:相对当前Git基线,`outputs/sales_crm_full_demo.html`为`+271/-4`;未修改后端、`package.json`、`data/`、部署、配置或运行态。
+- 语法与静态检查:`PASS`。内联脚本经`new Function`语法解析通过;静态契约检查确认唯一专用路径、严格两字段序列化、仅204成功、九码、Unicode码点计数、密码自动完成语义和`aria-modal`均存在,且专用路径未调用通用`api()`。
+- 最小虚构自测:`PASS`。使用运行时生成的虚构字符串验证7/8/64/65码点、补充平面字符、8个空格不裁剪、新旧相同和确认不一致;模拟204、非204未知响应和网络失败,确认请求键只有`currentPassword`/`newPassword`、非204不成功、网络失败映射不可用且不触发本地回退。自测未输出字段值或完整请求响应。
+- diff质量:`PASS`。`git diff --check -- outputs/sales_crm_full_demo.html`无空白错误,仅有仓库既有LF/CRLF提示。
+- 未执行:未连接后端、未读取或修改运行账号数据、未启动服务、未做真实账号联调、浏览器人工/辅助技术测试、主管重置回归、隔离环境测试、部署或Gate C/D/A/P。
+- 风险与停止线:后端精确实现尚未在本记录中验收,前后端联调和独立Gate C仍是下一步;若出现非204判成功、额外请求字段、本地回退、重复写、敏感值泄露、360px不可用或主管重置回归失败,必须退回实现整改。`BLOCK-001`至`BLOCK-003`和正式生产`No-Go`继续有效。
+- 前端开发结论:`PASS`(仅QUEUE-039实现与脱敏自测职责域);不代表Gate C/D/A/P或上线通过。
+
+## 后端QUEUE-040实现与自测回填(2026-07-17)
+
+- 执行范围:`QUEUE-20260717-040 / COLLAB-20260717-110、130`;故障迁移保留原唯一执行锁,未新建或切换业务队列。并发建立的COLLAB-114已取消,其Thread以零代码diff停止并归档。
+- 交接证据:新正式后端会话完整分页回读旧Thread `019f7014-60d2-7972-ba52-46d834fe49f2`的2个已完成turn至`hasMore=false`;旧会话只完成v0.4可实施性和CRM-003只读复核,未修改文件或运行态。恢复点为从零开始实现QUEUE-040。
+- 实际代码改动:仅修改`work/crm_full_server.js`。新增`POST /api/v1/me/password/change`专用路由;严格限制JSON请求体为`currentPassword`和`newPassword`且拒绝查询参数;身份只取Authorization认证头;按Schema、认证、账号锁、权威重读、停用、当前密码、Unicode码点8至64、新旧不同、CAS/原子持久化顺序处理;成功返回204空响应和`Cache-Control: no-store`;失败使用v0.4九个稳定错误码和安全请求ID。
+- 原子与主管兼容:本人改密、`/api/accounts/save`中的主管密码重置和`/api/accounts/status`停用均调用同一`mutateAccountWithCas`账号写入原语;同账号通过进程内锁串行,整份JSON快照通过`_version`真实CAS、唯一临时文件和原子替换发布。所有既有`save()`调用同时获得版本CAS保护,避免旧快照覆盖凭据更新;失败不发布新状态。
+- 精确代码diff:相对当前Git基线,`work/crm_full_server.js`为`+296/-65`;未修改前端、`package.json`、`data/`、部署、配置或运行态。
+- 语法与diff检查:`PASS`。`node --check work/crm_full_server.js`通过;`git diff --check -- work/crm_full_server.js`无空白错误,仅有仓库既有LF/CRLF提示。
+- 虚构内存自测:`PASS`。完整内存HTTP用例21项通过,覆盖严格Schema、认证、停用、当前密码、Unicode边界、不裁剪/规范化、204空响应/no-store、CAS、写入失败不发布、九码和同账号并发最多一次成功;按收尾要求另行精简复跑204、当前密码错误、长度边界、并发冲突、主管重置共享原语、停用共享原语,全部通过。首次`node -e`调用仅因PowerShell引号传递未启动测试代码,改用标准输入后通过,不属于应用失败。
+- 未执行:未读取或修改运行数据,未启动真实数据服务,未使用真实账号或凭据,未做前后端联调、真实主管回归、隔离环境部署、Gate C/D/A/P或正式线上发布。
+- 风险与停止线:当前原语仅适用于单进程、单写实例;出现多进程/多实例、绕过共享写入原语、CAS缺失、错误当前密码仍落盘、停用账号可改、重叠写多成功、持久化失败仍发布、敏感值泄露或v0.4契约漂移时必须停止。密码哈希、认证体系迁移、完整多设备会话撤销及`BLOCK-001`至`BLOCK-003`继续延期,正式生产保持`No-Go`。
+- 后端开发结论:`PASS`(仅QUEUE-040实现与脱敏自测职责域);不代表独立Gate C/D/A/P或上线通过。下一责任人:项目管理员登记交接与队列结果,代码审核与安全基于前后端精确diff执行一次独立Gate C。
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/03-\351\252\214\346\224\266\350\256\260\345\275\225.md" "b/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/03-\351\252\214\346\224\266\350\256\260\345\275\225.md"
index 608f0a3..69877c8 100644
--- "a/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/03-\351\252\214\346\224\266\350\256\260\345\275\225.md"
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/03-\351\252\214\346\224\266\350\256\260\345\275\225.md"
@@ -4,24 +4,88 @@
| Gate | 结论 | 说明 |
| --- | --- | --- |
-| Owner方向 | PASS | Owner明确要求增加员工修改密码功能 |
-| Gate N | CHANGES_REQUESTED | 首轮结论保留;需求已收敛为v0.2-MVP,待Owner确认后重新评审 |
-| Gate R | PENDING | 待密码、会话、迁移、测试、部署和回滚方案冻结 |
-| Gate C | PENDING | 尚无可审核实现基线 |
-| Gate D | PENDING | 尚未部署目标版本 |
-| Gate A | PENDING | 尚未形成Gate D通过版本和隔离测试环境 |
-| Gate P | PENDING | 尚未进入产品验收 |
+| Owner方向 | PASS | Owner确认v0.3-MVP四项产品决策,要求先能用、再逐步好用,并明确第一阶段不部署线上 |
+| Gate N | PASS | COLLAB-20260717-057至061、063六角色均PASS;COLLAB-065产品汇总PASS |
+| Gate R | PASS | COLLAB-092、095、096关闭复评项;COLLAB-098确认七个专业角色均PASS且R-01至R-11无未决分歧 |
+| Gate C | PASS | COLLAB-147基于父基线和前后端精确diff完成一次独立审核;语法、16项虚构负向/Unicode/并发/CAS/写失败复算、九码一致性和敏感流均PASS |
+| Gate D | PENDING | Owner明确第一阶段不部署线上;本轮未形成任何已部署版本,也未代签运行态结论 |
+| Gate A(隔离环境最小验收) | PASS | COLLAB-149;前端静态契约7项、回环内存API 12项,共19/19通过,短生命周期服务已关闭 |
+| Gate P | PENDING | 本轮先收口为本地/隔离环境可用;尚未对已部署版本执行正式产品验收 |
## 当前结论
-本任务已完成首轮独立 Gate N,但总体结论为 `CHANGES_REQUESTED`。当前不代表员工修改密码功能已实现、已部署或可在线使用。
+本任务第一阶段已经完成需求冻结、前后端最小实现、开发自测、一次独立Gate C和隔离环境最小Gate A,结论为首版在单进程、单写实例和虚构数据条件下本地可用。当前没有部署版本,Gate D/P和正式线上授权均未开始,因此不能描述为已经上线或生产可用。
+
+## 隔离环境最小验收结果
+
+- 结果事件:`COLLAB-20260717-149`,结论`PASS`。
+- 实际结果:19/19项通过,其中前端静态契约7项、实际回环内存API 12项。
+- 核心闭环:员工仅能修改本人密码;当前密码错误、停用账号、非法字段、离线/未知响应、并发冲突和写入失败均失败关闭;成功仅接受204,随后退出,旧密码失效且新密码可重新登录。
+- 兼容结果:主管现有密码重置和停用路径与本人改密共享写入原语,隔离验收通过。
+- 边界:没有读取或修改运行数据,没有使用真实账号/客户数据,没有执行部署、真实浏览器E2E、多进程/多实例或生产验证。
## MVP需求整改
- 已解决:原需求把本人改密、密码哈希迁移、全会话撤销、强制轮换、一次性临时凭据、限流、审计和完整迁移一次性绑定,范围过大。
- 当前方案:第一阶段只实现员工本人改密、基本校验、成功后重新登录,并保留主管现有重置能力。
- 延后处理:密码哈希、旧认证退役、完整会话撤销、强制首次改密、临时凭据、复杂限流和审计。
-- 待处理:Owner确认4项产品问题后,所有受需求版本变化影响的Gate N结论重新评审。
+- 已处理:Owner确认密码长度、成功退出、主管原重置方式以及只在测试环境验证四项产品问题。
+- 已处理:六个受影响专业角色完成Gate N复评,前端发现的请求传输矛盾已修正并复评PASS。
+- 已处理:Gate R已统一冻结接口、错误码、原子性、交互、隔离测试环境和回滚材料;第一阶段正式线上部署仍不在授权范围内。
+
+## Gate R启动状态
+
+- 已完成:形成R-01至R-11统一冻结清单和七角色输出边界。
+- 首轮结果(历史):架构、UI、后端、安全、运维PASS;前端、测试CHANGES_REQUESTED。
+- 整改结果:架构COLLAB-087形成v0.4唯一契约;后端COLLAB-092确认可实施,前端COLLAB-095和测试COLLAB-096在原队列项复评PASS。
+- 汇总结论:产品COLLAB-098确认全部适用专业结论PASS,Gate R整体PASS;实现仍须新的明确授权和精确基线。
+
+## Gate R最终专业结论
+
+| 角色 | 结论 | 事件 | 说明 |
+| --- | --- | --- | --- |
+| 架构与数据治理 | PASS | COLLAB-20260717-087 | v0.4唯一契约已冻结 |
+| UI与交互设计 | PASS | COLLAB-20260717-078 | 交互规格跟随唯一契约 |
+| 前端开发 | PASS | COLLAB-20260717-095 | 原QUEUE-024同项复评通过 |
+| 后端开发 | PASS | COLLAB-20260717-092 | 新正式会话完成历史交接并确认可实施 |
+| 代码审核与安全 | PASS | COLLAB-20260717-081 | 安全停止线与Gate C证据要求已冻结 |
+| 测试与质量 | PASS | COLLAB-20260717-096 | 原QUEUE-027同项复评通过 |
+| 运维与发布 | PASS | COLLAB-20260717-083 | 隔离环境与回滚方案通过设计评审,尚未实际执行 |
+| 产品整体汇总 | PASS | COLLAB-20260717-098 | 七角色均PASS,R-01至R-11无未决分歧 |
+
+## v0.4契约整改
+
+- 架构结论:COLLAB-20260717-087 `PASS`。
+- 已统一:接口路径、两字段严格Schema、确认密码前端归属、Unicode码点计数、成功204空响应、九个错误码和UI语义。
+- 已废止:后端首轮提出的另一接口路径、三字段请求、成功200及备选错误码命名。
+- 已完成:后端确认单写实例可实施;前端QUEUE-024和测试QUEUE-027复评PASS;产品完成整体汇总。
+
+## Gate R首轮专业评审
+
+| 角色 | 首轮结论 | 队列 | 处理 |
+| --- | --- | --- | --- |
+| 架构与数据治理 | PASS | QUEUE-022 | 接口、身份、原子性、并发、重新认证和回滚边界已给出 |
+| UI与交互设计 | PASS | QUEUE-023 | 入口、三字段、状态、移动端、焦点和无障碍规则已给出 |
+| 前端开发 | CHANGES_REQUESTED | QUEUE-024 | 等待唯一接口、错误码、字符口径和交互候选稿后同项复评 |
+| 后端开发 | 单角色PASS但存在跨角色冲突 | QUEUE-025 | 与架构/UI在路径、确认字段和成功响应上不一致,同项复评后才可释放 |
+| 代码审核与安全 | PASS | QUEUE-026 | 威胁边界、停止线和未来Gate C证据已给出 |
+| 测试与质量 | CHANGES_REQUESTED | QUEUE-027 | 事件编号重复已修复;等待具体契约、矩阵输入、复位和计划命令后同项复评 |
+| 运维与发布 | PASS | QUEUE-028 | 隔离测试环境、HTTPS、备份、复位和回滚边界已给出 |
+
+跨角色实现细则见[计划改动清单](<./01-计划改动清单.md>)。当前Gate R整体为`PASS`,前端、后端、测试执行锁均已释放;任何业务实现仍须新的明确授权。
+
+## v0.3-MVP Gate N复评结果
+
+| 角色 | 结论 | 事件 | Gate R主要前置 |
+| --- | --- | --- | --- |
+| 架构与数据治理 | PASS | COLLAB-20260717-057 | 接口、身份、凭据边界、原子性、并发和回滚 |
+| UI与交互设计 | PASS | COLLAB-20260717-063 | 入口、三字段对话框、状态、移动端布局和无障碍 |
+| 前端开发 | PASS | COLLAB-20260717-058 | 请求字段、错误映射、防重、故障关闭和成功清理登录 |
+| 后端开发 | PASS | COLLAB-20260717-059 | 后端身份、校验、原子持久化、并发、错误码和主管回归 |
+| 代码审核与安全 | PASS | COLLAB-20260717-060 | 最低安全停止线、敏感值边界、隔离环境和Gate C证据 |
+| 测试与质量 | PASS | COLLAB-20260717-061 | 10项标准10/10可测,需环境、虚构样本和自动化矩阵 |
+
+产品与项目管理在COLLAB-20260717-065汇总为Gate N整体`PASS`。
## Gate N首轮结果
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/04-\346\234\254\350\275\256\347\273\223\350\256\272.md" "b/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/04-\346\234\254\350\275\256\347\273\223\350\256\272.md"
index 5636738..a99ddaa 100644
--- "a/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/04-\346\234\254\350\275\256\347\273\223\350\256\272.md"
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/04-\346\234\254\350\275\256\347\273\223\350\256\272.md"
@@ -1,9 +1,9 @@
# 本轮结论
-- 当前结论:v0.2-MVP需求已收敛,待Owner确认4项问题,未完成。
-- 当前 Gate:Gate N 需求整改。
-- 实际改动:仅调整产品需求、MVP验收、分期范围和任务管理文档。
-- 未执行:架构方案、业务实现、代码审核、部署、测试和产品验收。
+- 当前结论:v0.3-MVP Gate N/R、前后端实现/开发自测、一次独立Gate C和隔离环境最小Gate A均已PASS;第一阶段达到本地/隔离环境可用。
+- 当前 Gate:隔离环境最小Gate A `PASS`;Gate D/P未执行。
+- 实际改动:需求已加入“先落地基本功能、再分段迭代、避免过度设计”的交付原则;前端入口/表单/专用请求与后端专用接口/校验/账号锁CAS已经形成精确diff,并通过19/19项隔离验收。
+- 未执行:真实浏览器E2E、真实文件持久化、多进程/多实例、部署和Gate D/P。
- 风险:现有密码保存、旧认证机制、运行数据与Git历史风险继续有效;MVP不关闭这些问题。
-- Go/No-Go:`No-Go`;本任务未通过全部适用 Gate 前不得部署到正式线上环境。
-- 下一责任人:Owner确认v0.2-MVP的密码长度、成功退出、主管原重置方式及是否先测试后部署;产品与项目管理随后重新发起Gate N。
+- Go/No-Go:`No-Go`;第一阶段只允许在隔离测试环境验证,当前正式线上环境明确禁止部署。
+- 下一责任人:本轮无需继续专业评审;如Owner后续授权部署,应另立部署范围并由运维、开发、测试和产品依次执行Gate D/A/P,正式线上部署前仍须关闭适用P0风险。
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/\345\257\274\350\257\273.md" "b/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/\345\257\274\350\257\273.md"
index 3dbade9..454dec4 100644
--- "a/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/\345\257\274\350\257\273.md"
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\345\221\230\345\267\245\344\277\256\346\224\271\345\257\206\347\240\201/\345\257\274\350\257\273.md"
@@ -1,13 +1,13 @@
# CRM-20260717-006 员工修改密码导读
- 优先级:P0
-- 状态:MVP需求已收敛,待Owner确认4项问题并重新评审
-- 当前 Gate:Gate N 需求整改(v0.2-MVP)
+- 状态:v0.3-MVP需求不变;Gate N/R/C、前后端实现/开发自测和QUEUE-043隔离环境最小Gate A均已PASS,第一阶段本地/隔离验收完成
+- 当前 Gate:隔离环境最小Gate A已PASS;Gate D/P未执行,未部署线上
- Owner 方向:先实现员工自主改密的基本功能,再逐步完善安全和体验
-- 当前授权:仅允许需求与方案评审,尚未授权修改业务代码、运行数据或线上环境
+- 当前授权:Owner已明确授权按“先落地基本功能、再分段迭代”执行最小实现;只允许冻结范围内的前后端代码与必要实现记录,运行数据、部署配置、运行环境和正式线上部署仍未授权
- 关联任务:`CRM-20260717-002`继续负责账号密码轮换与数据治理;不再作为MVP需求文档完成的前置条件,但仍影响正式部署结论
- 统一台账:[统一计划台账](<../../统一计划台账.md>)
-- 协作事件:[协作事件 COLLAB-20260717-027 至 032](<../../协作事件.md>)
+- 协作事件:[协作事件](<../../协作事件.md>)中的`COLLAB-20260717-027`至`038`、`045`至`046`及`048`起的MVP冻结与复评事件
## 文档
@@ -19,4 +19,4 @@
## 下一责任人
-Owner确认v0.2-MVP中的4项产品问题;产品与项目管理随后重新发起适用角色Gate N。第一阶段只验收员工本人改密闭环,不代签专业技术结论,也不把MVP完成写成安全整改全部完成。
+本轮无需继续专业评审;后续部署必须另行授权并重新进入部署、Gate D/A/P链路,正式线上部署继续禁止。
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/00-\351\234\200\346\261\202\344\270\216\351\252\214\346\224\266.md" "b/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/00-\351\234\200\346\261\202\344\270\216\351\252\214\346\224\266.md"
index 02982a6..36301d8 100644
--- "a/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/00-\351\234\200\346\261\202\344\270\216\351\252\214\346\224\266.md"
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/00-\351\234\200\346\261\202\344\270\216\351\252\214\346\224\266.md"
@@ -14,6 +14,8 @@
- 新建正式架构与数据治理会话并完成角色接管。
- 更新角色会话清单、角色队列索引和架构角色队列中的正式Thread ID。
- 使用同一个队列项完成首次接入和第二次提交验证。
+- 建立通用的会话故障迁移与交接规范,强制新会话回读旧历史后再归档旧会话。
+- 补齐现有架构/UI替代会话的历史回读、交接验收和旧会话归档证据。
## 不做项
@@ -30,3 +32,5 @@
4. 新会话连续两次提交都产生正常完成的turn。
5. 架构队列最终恢复`IDLE`,迁移队列项为`COMPLETED`,没有任务丢失。
6. 其他角色队列、业务代码、配置、数据和运行态不受影响。
+7. 专门规范明确故障判定、队列保护、全量回读、交接清单、入口切换和归档顺序。
+8. 现有新架构会话确认已回读旧记录;新UI会话补读两代旧UI记录后,旧会话才归档。
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/01-\350\256\241\345\210\222\346\224\271\345\212\250\346\270\205\345\215\225.md" "b/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/01-\350\256\241\345\210\222\346\224\271\345\212\250\346\270\205\345\215\225.md"
index 6171b90..571282c 100644
--- "a/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/01-\350\256\241\345\210\222\346\224\271\345\212\250\346\270\205\345\215\225.md"
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/01-\350\256\241\345\210\222\346\224\271\345\212\250\346\270\205\345\215\225.md"
@@ -7,5 +7,7 @@
| 串行队列 | 用一个迁移队列项覆盖接管与复测 | 测试消息被当成新任务抢占 | 同一QUEUE项内顺次执行 |
| 入口映射 | 更新清单、索引和角色队列 | 多处ID不一致 | 唯一Thread ID扫描 |
| 连通性 | 完成首次接入和第二次提交 | 只验证创建、未验证后续发送 | 两个正常完成的turn |
+| 历史交接 | 新会话完整回读旧会话并形成脱敏检查点 | 只换窗口导致决策和任务上下文丢失 | 标准交接回执与Thread证据 |
+| 旧会话归档 | 交接PASS后重命名并归档旧会话 | 过早归档导致无法补读 | 归档前八项检查 |
不修改`outputs/`、`work/`、`data/`、`deploy/`和`package.json`。
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/02-\345\256\236\347\216\260\344\270\216\350\207\252\346\265\213\350\256\260\345\275\225.md" "b/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/02-\345\256\236\347\216\260\344\270\216\350\207\252\346\265\213\350\256\260\345\275\225.md"
index 00b95a1..d87c2e9 100644
--- "a/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/02-\345\256\236\347\216\260\344\270\216\350\207\252\346\265\213\350\256\260\345\275\225.md"
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/02-\345\256\236\347\216\260\344\270\216\350\207\252\346\265\213\350\256\260\345\275\225.md"
@@ -2,7 +2,7 @@
- 起始分支:`main`
- 起始commit:`6e62407`
-- 当前状态:本地完成,Gate P `PASS`。
+- 当前状态:已提交并推送,Gate P `PASS`。
- 业务影响:仅修复角色会话入口和治理Markdown,不修改业务代码、配置、数据或运行态。
## 验证结果
@@ -14,10 +14,16 @@
| 第二次消息提交 | PASS;会话idle后成功提交,turn `019f6f89-fc6f-7b61-bcdb-319e87cd6a63`约8秒完成 |
| 三处正式Thread ID一致 | PASS;角色清单、队列索引和架构队列一致 |
| 队列锁释放且其他队列不变 | PASS;架构队列IDLE,QUEUE-009 COMPLETED |
-| Markdown链接和敏感值扫描 | PASS;75份Markdown断链0,46条事件重复0/必填字段缺失0,67个未跟踪交付文件均为Markdown,普通交付文件敏感值模式0;本机敏感文件1份且已被Git忽略 |
+| Markdown链接和敏感值扫描 | PASS;提交前75份Markdown断链0,46条事件重复0/必填字段缺失0,67个交付文件均为Markdown,普通交付文件敏感值模式0;本机敏感文件1份且已被Git忽略 |
+| Git交付 | PASS;治理与会话修复文档已提交并推送到`origin/main`,`docs/local/`未进入提交 |
+| 会话迁移规范 | PASS;已建立历史全量回读、交接验收、入口切换和旧会话归档强制流程 |
+| 架构历史交接 | PASS;新架构会话完整回读旧会话并恢复原架构讨论,旧会话已归档 |
+| UI历史交接 | PASS;第三代UI读完两代旧会话3个turn,分页到头且QUEUE-003/013无遗漏,两代旧会话已归档 |
+| 后端历史交接 | PASS;新后端会话读完旧会话5个turn至`hasMore=false`,恢复并完成QUEUE-032,旧会话允许归档 |
+| 前端历史交接 | PASS;新前端会话读完旧会话6个turn至`hasMore=false`,恢复并完成QUEUE-024,旧会话允许归档 |
## 未执行项
-- 未修改或诊断Codex客户端、网络或服务端内部实现;通过正式会话迁移恢复可用性。
+- 未修改或诊断Codex客户端、网络或服务端内部实现;通过正式会话迁移、历史回读和交接验收恢复可用性。
- 未向旧异常会话再次投递,避免重复失败或历史状态进一步混乱。
-- 本轮文档尚未commit或push,HEAD仍为`6e62407`。
+- 本轮文档已提交并推送;本任务没有修改业务代码、配置、数据或运行态。
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/03-\351\252\214\346\224\266\350\256\260\345\275\225.md" "b/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/03-\351\252\214\346\224\266\350\256\260\345\275\225.md"
index 6dbed6d..a1146f6 100644
--- "a/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/03-\351\252\214\346\224\266\350\256\260\345\275\225.md"
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/03-\351\252\214\346\224\266\350\256\260\345\275\225.md"
@@ -8,5 +8,7 @@
| Gate D | 项目管理员 | N/A | 无部署或运行态变更 |
| Gate A | 项目管理员 | PASS | 两次提交、ID一致性和队列状态检查通过;无业务可执行产物 |
| Gate P | Owner/项目管理员 | PASS | 用户明确修复目标;新正式入口连续提交验证闭环 |
+| 历史交接 | 新架构与新UI会话 | PASS | 架构旧历史已回读;UI两代旧历史3个turn已读到分页末尾,任务无遗漏 |
+| 旧会话归档 | 项目管理员 | PASS | 旧架构和两代旧UI会话均在交接PASS、入口切换后重命名并归档 |
业务系统BLOCK-001至003和正式上线No-Go继续有效。
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/04-\346\234\254\350\275\256\347\273\223\350\256\272.md" "b/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/04-\346\234\254\350\275\256\347\273\223\350\256\272.md"
index 61d26db..88322f5 100644
--- "a/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/04-\346\234\254\350\275\256\347\273\223\350\256\272.md"
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/04-\346\234\254\350\275\256\347\273\223\350\256\272.md"
@@ -1,8 +1,8 @@
# 本轮结论
-- 当前结论:本地完成,Gate P `PASS`。
-- 已完成:故障诊断、旧会话隔离、新正式会话创建、连续两次提交验证、三处入口映射更新和队列释放。
-- 未完成:尚未提交或推送;本任务没有修补Codex客户端或服务端内部故障。
+- 当前结论:已提交并推送,Gate P `PASS`。
+- 已完成:故障诊断、旧会话隔离、新正式会话创建、连续提交验证、三处入口映射、历史全量回读、交接规范、旧会话归档和队列释放。
+- 未完成:本任务没有修补Codex客户端或服务端内部故障;若新会话再次发生同类错误,继续使用保留历史并迁移正式入口的流程。
- 当前Gate:Gate P `PASS`。
- 业务系统Go/No-Go:继续`No-Go`,本任务不解除BLOCK-001至003。
-- 下一责任人:架构与数据治理会话按统一队列等待后续任务;项目管理员持续执行投递前双重检查。
+- 下一责任人:各正式角色按统一队列等待后续任务;项目管理员持续执行投递前双重检查和“交接PASS后再归档”流程。
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/\345\257\274\350\257\273.md" "b/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/\345\257\274\350\257\273.md"
index bf33906..a13e10b 100644
--- "a/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/\345\257\274\350\257\273.md"
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\346\236\266\346\236\204\344\274\232\350\257\235\344\277\256\345\244\215/\345\257\274\350\257\273.md"
@@ -1,7 +1,7 @@
# CRM-20260717-008 架构角色会话故障迁移导读
- 优先级:P0
-- 状态:本地完成
+- 状态:已提交并推送
- 当前Gate:Gate P `PASS`
- 目标:修复架构与数据治理会话无法提交消息的问题,并验证新正式会话可连续接收任务
- 统一台账:[统一计划台账](<../../统一计划台账.md>)
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\346\236\266\346\236\204\346\226\271\346\241\210/00-\351\234\200\346\261\202\344\270\216\351\252\214\346\224\266.md" "b/docs/\344\273\273\345\212\241/202607/0717-\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\346\236\266\346\236\204\346\226\271\346\241\210/00-\351\234\200\346\261\202\344\270\216\351\252\214\346\224\266.md"
new file mode 100644
index 0000000..6821b49
--- /dev/null
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\346\236\266\346\236\204\346\226\271\346\241\210/00-\351\234\200\346\261\202\344\270\216\351\252\214\346\224\266.md"
@@ -0,0 +1,41 @@
+# 模块化单体架构方案需求与验收
+
+## Owner已确认方向
+
+- 数据库采用`MySQL`,不采用此前建议的PostgreSQL。
+- 现有功能逐步迁移到新架构,不进行一次性重写。
+- 当前只把本地开发和验证环境搞清楚,暂不部署生产环境。
+- 后续要建设移动端,API必须作为Web与移动端共享的稳定契约设计。
+
+## 目标
+
+基于现有单HTML前端、单Node.js后端和JSON数据文件现状,形成可执行的小型工程级模块化单体架构方案,明确目录、模块、契约、MySQL数据模型与迁移、本地环境、分阶段迁移、验证和回滚边界。
+
+## 范围
+
+- 现状与目标架构、关键技术选型和不采用项。
+- 前端、后端、共享契约、数据库迁移和测试的工程目录。
+- 业务模块边界、依赖方向和第一条纵向迁移链路。
+- MySQL本地实例、Schema、迁移、种子数据、事务、备份和JSON迁移策略。
+- `/api/v1`多客户端契约:错误码、分页、时间、幂等、版本兼容和认证差异。
+- Web安全Cookie与未来移动端令牌生命周期的边界设计。
+- 新旧系统渐进共存、切流、数据一致性、停止线和回滚。
+- 复查移动端/iOS/Android角色原N/A裁剪决定。
+
+## 不做项
+
+- 不修改业务代码、运行数据、账号、部署或线上运行态。
+- 不搭建生产环境,不执行生产迁移,不解除项目`No-Go`。
+- 不一次性拆微服务,不引入Kubernetes等超出当前规模的基础设施。
+- 不把方案文档描述为代码、测试、部署或上线已经完成。
+
+## 验收标准
+
+1. 明确目标技术栈、模块化单体边界、依赖方向和仓库目标目录。
+2. 明确MySQL作为唯一目标业务数据库,并给出本地配置、Schema/迁移/种子数据和JSON迁移策略。
+3. 明确新旧功能渐进迁移顺序、第一条纵向链路、兼容期数据写入原则和可回滚停止线。
+4. API设计同时覆盖Web与未来移动端,包含版本、认证、错误、分页、时间、幂等和兼容规则。
+5. 给出本地开发、测试、数据初始化和验证流程,不包含生产部署执行。
+6. 明确安全、测试、CI和数据治理前置条件,并保留BLOCK-001至003和正式上线No-Go。
+7. 现状、目标、计划和已实现事实分开;所有新增文档使用中文命名且相对链接有效。
+8. 架构角色完成方案后回传PASS/CHANGES_REQUESTED/BLOCKED、风险、未决项和下一Gate责任人。
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\346\236\266\346\236\204\346\226\271\346\241\210/01-\350\256\241\345\210\222\346\224\271\345\212\250\346\270\205\345\215\225.md" "b/docs/\344\273\273\345\212\241/202607/0717-\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\346\236\266\346\236\204\346\226\271\346\241\210/01-\350\256\241\345\210\222\346\224\271\345\212\250\346\270\205\345\215\225.md"
new file mode 100644
index 0000000..adcb94b
--- /dev/null
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\346\236\266\346\236\204\346\226\271\346\241\210/01-\350\256\241\345\210\222\346\224\271\345\212\250\346\270\205\345\215\225.md"
@@ -0,0 +1,40 @@
+# 计划改动清单
+
+| 改动面 | 计划输出 | 主要风险 | 验证 |
+| --- | --- | --- | --- |
+| 目标架构 | 模块化单体、技术栈和依赖方向 | 过度设计或边界含糊 | 与当前规模和代码事实核对 |
+| 工程目录 | 前端、后端、契约、数据库、测试目录 | 只换目录不拆职责 | 模块职责和禁止依赖清单 |
+| MySQL | 本地实例、Schema、迁移、种子和JSON迁移 | 数据双写、丢失、不可回滚 | 迁移阶段与校验/回滚表 |
+| API契约 | Web/移动端共享`/api/v1`规范 | 接口绑死页面或认证混乱 | 多客户端契约检查 |
+| 本地环境 | 启动、初始化、测试和开发依赖 | 文档不可复现 | 本地步骤和前置条件 |
+| 渐进迁移 | 纵向链路、切流、停止线和回滚 | 新旧事实源并存 | 每阶段入口/出口条件 |
+| 角色裁剪 | 复查移动端角色N/A决定 | 职责缺口 | 角色矩阵更新建议 |
+
+本任务只产出和评审方案文档,不修改`outputs/`、`work/`、`data/`、`deploy/`或业务配置。
+
+## 实际文档范围
+
+| 文件 | 实际改动 |
+| --- | --- |
+| [模块化单体目标架构方案](<../../../架构/模块化单体目标架构方案.md>) | 新增目标技术栈、目录、模块边界、共存切流、首条链路、阶段、停止线和Gate R冻结项 |
+| [MySQL数据与渐进迁移方案](<../../../架构/MySQL数据与渐进迁移方案.md>) | 新增Schema规范、迁移、种子、事务、备份、JSON渐进迁移、校验和回滚设计 |
+| [多客户端API与认证契约](<../../../架构/多客户端API与认证契约.md>) | 新增`/api/v1`版本、错误、分页、时间、金额、幂等、Web Cookie与移动Token边界 |
+| [本地开发环境方案](<../../../环境/本地开发环境方案.md>) | 新增Windows本地MySQL主路径、隔离库、目标命令、验证清单和禁止生产边界 |
+| [环境文档导读](<../../../环境/导读.md>) | 增加本地开发环境方案入口 |
+| [采用与裁剪记录](<../../../研发体系/采用与裁剪记录.md>) | 将移动端从永久N/A修正为共享契约立即适用、客户端角色条件待激活 |
+| [角色索引](<../../../研发体系/角色/角色索引.md>) | 明确现有角色的多客户端契约职责和Web/APP实现边界 |
+| 本任务目录 | 回填实际范围、自测、架构角色Gate结论、风险和下一责任人 |
+
+## COLLAB-112一次性整改映射
+
+首轮跨角色评审不新增方案分支,全部意见归并到同一基线:
+
+| 首轮角色结论 | 必须关闭项 | 本轮唯一落点 |
+| --- | --- | --- |
+| 前端`PASS`(COLLAB-104) | 明确同源代理、契约生成、模块公共入口、新旧认证隔离和首个实现任务 | [目标架构第12节](<../../../架构/模块化单体目标架构方案.md>)、[API契约第2/9/11节](<../../../架构/多客户端API与认证契约.md>) |
+| 后端`CHANGES_REQUESTED`(COLLAB-105) | 唯一Node/MySQL/查询迁移栈、首链物理Schema/事务/幂等、Web会话/CSRF、单写切换和可重复命令 | [目标架构](<../../../架构/模块化单体目标架构方案.md>)、[MySQL方案第10至14节](<../../../架构/MySQL数据与渐进迁移方案.md>)、[API契约](<../../../架构/多客户端API与认证契约.md>)、[本地环境](<../../../环境/本地开发环境方案.md>) |
+| 安全`CHANGES_REQUESTED`(COLLAB-106) | 本地HTTPS、Cookie/会话轮换、具体CSRF、权限新鲜度、移动Token停止线、配置失败关闭、迁移摘要不可识别 | [API契约第9节](<../../../架构/多客户端API与认证契约.md>)、[MySQL方案第12节](<../../../架构/MySQL数据与渐进迁移方案.md>)、[本地环境第3至6节](<../../../环境/本地开发环境方案.md>) |
+| 测试`CHANGES_REQUESTED`(COLLAB-107) | 契约/恢复入口、生成式夹具、迁移异常夹具、脱敏对账结构、环境守卫和证据路径 | [MySQL方案第12/14节](<../../../架构/MySQL数据与渐进迁移方案.md>)、[本地环境第6/8节](<../../../环境/本地开发环境方案.md>) |
+| 运维`CHANGES_REQUESTED`(COLLAB-108) | Windows MySQL补丁/服务/目录/身份、配置优先级、预检、启动健康、备份恢复、单写与回退审批 | [本地环境第2至9节](<../../../环境/本地开发环境方案.md>)、[MySQL方案第13节](<../../../架构/MySQL数据与渐进迁移方案.md>) |
+
+整改完成只表示架构文档具备再次只读复评输入,不代签后端可实施性、安全、测试、运维或整体Gate R。
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\346\236\266\346\236\204\346\226\271\346\241\210/02-\345\256\236\347\216\260\344\270\216\350\207\252\346\265\213\350\256\260\345\275\225.md" "b/docs/\344\273\273\345\212\241/202607/0717-\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\346\236\266\346\236\204\346\226\271\346\241\210/02-\345\256\236\347\216\260\344\270\216\350\207\252\346\265\213\350\256\260\345\275\225.md"
new file mode 100644
index 0000000..788f8d2
--- /dev/null
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\346\236\266\346\236\204\346\226\271\346\241\210/02-\345\256\236\347\216\260\344\270\216\350\207\252\346\265\213\350\256\260\345\275\225.md"
@@ -0,0 +1,35 @@
+# 实现与自测记录
+
+- 起始分支:`main`
+- 起始基线:`9ad42b5c22880b21c09897a5c249d48909c2a3ad`
+- 当前状态:架构方案和角色裁剪说明已编制;后端、安全、测试、运维同项复评均PASS,前端原PASS经项目级确认无回归,整体Gate R和产品Gate P均已PASS;方案阶段闭环
+- 业务影响:仅文档,不修改业务代码、配置、数据、部署或运行态
+
+## 文档验证
+
+| 检查 | 状态 | 证据 |
+| --- | --- | --- |
+| 目标架构和目录边界 | PASS | 模块化单体技术栈、目标目录、模块所有权和禁止依赖已写明 |
+| MySQL与渐进数据迁移 | PASS | 唯一Kysely/mysql2栈、首链物理Schema、事务/幂等、异常夹具、HMAC脱敏对账、环境守卫和单写切换已写明 |
+| Web/移动端API契约 | PASS | 首链DTO、TypeBox/OpenAPI生成、同源HTTPS、严格Cookie/CSRF、权限新鲜度和移动Token停止线已写明 |
+| 本地环境和验证流程 | PASS | 精确Node/npm/MySQL基线、Windows服务/目录/身份、配置失败关闭、启动健康、契约/恢复命令与本地证据路径已写明 |
+| 新旧共存、停止线和回滚 | PASS | 模块迁移状态机、首条链路、切流停止线和有新写入后的回滚限制已写明 |
+| 移动端角色裁剪 | PASS | 共享契约职责立即适用;APP/iOS/Android/打包条件待激活;Web前端不代替APP角色 |
+| 文档链接、事实分层和敏感值 | PASS | 13份范围内Markdown共61个相对链接可解析;21项必需基线无缺项;无旧版本/HTTP例外残留、尾随空白或常见敏感值模式;未读取`data/`、凭据值、原始日志或完整请求响应 |
+
+## 首轮意见关闭情况
+
+| 角色 | 首轮结论 | 架构整改状态 | 复评边界 |
+| --- | --- | --- | --- |
+| 前端 | PASS | 保持COLLAB-104 PASS;COLLAB-113明确不回退前端PASS项 | 项目级确认无回归,不重复创建同义评审 |
+| 后端 | CHANGES_REQUESTED | COLLAB-20260718-002复评PASS | 首链Schema/API、迁移栈、HTTPS会话/CSRF、单写切流和可重复命令已关闭 |
+| 代码审核与安全 | CHANGES_REQUESTED | COLLAB-143复评PASS | P1-01至P1-05全部在方案级关闭 |
+| 测试与质量 | CHANGES_REQUESTED | COLLAB-144复评PASS | 测试/恢复入口、夹具、环境守卫和证据位置已关闭;脚本仍待实现 |
+| 运维与发布 | CHANGES_REQUESTED | COLLAB-145复评PASS | Windows基线、预检、健康、恢复和切换已关闭;不代表生产就绪 |
+
+## 未执行项
+
+- 未安装或启动MySQL,未创建Schema、运行迁移、种子、备份或恢复。
+- 未运行目标`npm run db:*`、契约、集成或E2E命令;这些脚本尚未实现。
+- 未读取或迁移`data/`真实业务数据,未验证真实JSON字段映射。
+- 未修改业务代码、配置、运行数据、部署或运行态;未执行切分支、暂存、提交、回退等Git写操作,未部署生产。
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\346\236\266\346\236\204\346\226\271\346\241\210/03-\351\252\214\346\224\266\350\256\260\345\275\225.md" "b/docs/\344\273\273\345\212\241/202607/0717-\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\346\236\266\346\236\204\346\226\271\346\241\210/03-\351\252\214\346\224\266\350\256\260\345\275\225.md"
new file mode 100644
index 0000000..d03c240
--- /dev/null
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\346\236\266\346\236\204\346\226\271\346\241\210/03-\351\252\214\346\224\266\350\256\260\345\275\225.md"
@@ -0,0 +1,25 @@
+# 验收记录
+
+| Gate/检查 | 角色 | 状态 | 证据 |
+| --- | --- | --- | --- |
+| Owner方向 | Owner | PASS | MySQL、渐进迁移、先本地、面向后续移动端 |
+| Gate N/R技术结论 | 架构与数据治理 | PASS | COLLAB-113一次性整改已完成;只代表架构文档定稿和本角色结论 |
+| Gate R | 前端 | PASS | COLLAB-104;COLLAB-113不回退前端PASS项,项目级确认无回归且不重复评审 |
+| Gate R整改复评 | 后端 | PASS | COLLAB-20260718-002;首轮实施级缺口全部在方案级关闭 |
+| Gate R整改复评 | 代码审核与安全 | PASS | COLLAB-143;P1-01至P1-05全部在方案级关闭 |
+| Gate R整改复评 | 测试与质量 | PASS | COLLAB-144;测试入口、夹具、对账、恢复和保护规则全部关闭 |
+| Gate R整改复评 | 运维与发布 | PASS | COLLAB-145;Windows MySQL机械基线、健康、恢复和切流证据全部关闭 |
+| Gate R整体 | 全部适用角色 | PASS | COLLAB-20260718-003;全部适用专业角色最终输入均PASS,只代表方案冻结 |
+| 产品范围 | 产品与项目管理/Owner | PASS | COLLAB-20260718-005;第一实施任务冻结为“本地工程骨架 + Windows MySQL薄型样例”,只用生成数据;后置范围不进入本任务 |
+| Gate C | 代码审核与安全 | N/A | 本轮只产出方案文档,无代码/配置/数据改动 |
+| Gate D | 运维与发布 | N/A | 明确禁止生产部署,本轮无部署对象 |
+| Gate A | 测试与质量 | N/A | 本轮无业务可执行产物,只做文档验证 |
+| Gate P | 产品与项目管理/Owner | PASS | COLLAB-20260718-005;八项需求验收全部通过,仅代表方案阶段闭环 |
+
+BLOCK-001至003和正式上线`No-Go`继续有效。
+
+## 下一责任人
+
+1. 项目管理员:后续以独立任务登记“本地工程骨架 + Windows MySQL薄型样例”,不得在CRM-003内直接实施。
+2. 独立任务只允许生成数据,不得读取现有`data/`、直接全量迁移业务或部署生产。
+3. BLOCK-001至003和生产No-Go继续有效;真实字段映射、移动端平台/离线/推送和生产拓扑仍后置。
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\346\236\266\346\236\204\346\226\271\346\241\210/04-\346\234\254\350\275\256\347\273\223\350\256\272.md" "b/docs/\344\273\273\345\212\241/202607/0717-\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\346\236\266\346\236\204\346\226\271\346\241\210/04-\346\234\254\350\275\256\347\273\223\350\256\272.md"
new file mode 100644
index 0000000..e4f747b
--- /dev/null
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\346\236\266\346\236\204\346\226\271\346\241\210/04-\346\234\254\350\275\256\347\273\223\350\256\272.md"
@@ -0,0 +1,11 @@
+# 本轮结论
+
+- 整体Gate R结论:`PASS`。架构COLLAB-113、前端COLLAB-104、后端COLLAB-20260718-002、安全COLLAB-143、测试COLLAB-144、运维COLLAB-145均为PASS;唯一整体汇总为COLLAB-20260718-003。该结论只代表方案冻结,不是工程实现或上线通过。
+- 已完成:精确技术栈和目标目录;前后端模块边界;TypeBox/OpenAPI共享契约;首链物理Schema、事务和幂等;JSON渐进迁移;`/api/v1`首链DTO;Web本地HTTPS、Cookie、CSRF和权限新鲜度;移动Token停止线;Windows MySQL机械基线;配置失败关闭;测试夹具、环境守卫和证据;备份恢复;单写切流、停止线和回滚审批边界。
+- 本轮实际影响:仅授权文档;未修改业务代码、配置、数据、部署或运行态,未执行切分支、暂存、提交、回退等Git写操作,未读取真实业务数据或凭据值。
+- 未完成:MySQL/工程和全部目标脚本实现、真实字段映射、自动化测试执行、任何生产准备或部署。
+- 已知风险:当前真实数据治理BLOCK-001至003未关闭;旧系统存在集中式路由/JSON写入和浏览器降级数据路径;MySQL和目标脚本尚未在本机安装实现;移动端平台和弱网/离线范围未冻结。
+- 停止线:无脱敏数据字典、旧新双写、迁移校验不闭合、恢复未验证、权限/契约测试失败、敏感信息进入Git或需要触碰生产时立即停止。
+- 当前Gate:整体Gate R和产品Gate P均为`PASS`;仅方案阶段闭环。
+- 业务系统Go/No-Go:继续`No-Go`,禁止生产部署。
+- 下一责任人:项目管理员后续以独立任务登记“本地工程骨架 + Windows MySQL薄型样例”;不得在CRM-003内直接做全量业务迁移或生产部署。
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\346\236\266\346\236\204\346\226\271\346\241\210/\345\257\274\350\257\273.md" "b/docs/\344\273\273\345\212\241/202607/0717-\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\346\236\266\346\236\204\346\226\271\346\241\210/\345\257\274\350\257\273.md"
new file mode 100644
index 0000000..8455526
--- /dev/null
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\346\236\266\346\236\204\346\226\271\346\241\210/\345\257\274\350\257\273.md"
@@ -0,0 +1,26 @@
+# CRM-20260717-003 模块化单体架构方案导读
+
+- 优先级:P1
+- 状态:整体Gate R和产品Gate P均已PASS,方案阶段闭环;第一实施任务待独立登记
+- 当前Gate:Gate P-PASS(仅方案)
+- 目标:冻结面向Web与后续移动端的模块化单体目标架构、MySQL数据方案、本地开发环境和渐进迁移路线
+- 统一台账:[统一计划台账](<../../统一计划台账.md>)
+- 协作事件:[COLLAB-20260717-056](<../../协作事件.md>)
+- 角色队列:[架构与数据治理任务队列](<../../角色队列/架构与数据治理.md>)
+
+## 文档
+
+- [00-需求与验收](<./00-需求与验收.md>)
+- [01-计划改动清单](<./01-计划改动清单.md>)
+- [02-实现与自测记录](<./02-实现与自测记录.md>)
+- [03-验收记录](<./03-验收记录.md>)
+- [04-本轮结论](<./04-本轮结论.md>)
+
+## 方案输出
+
+- [模块化单体目标架构方案](<../../../架构/模块化单体目标架构方案.md>)
+- [MySQL数据与渐进迁移方案](<../../../架构/MySQL数据与渐进迁移方案.md>)
+- [多客户端API与认证契约](<../../../架构/多客户端API与认证契约.md>)
+- [本地开发环境方案](<../../../环境/本地开发环境方案.md>)
+- [移动端采用与裁剪记录](<../../../研发体系/采用与裁剪记录.md>)
+- [角色索引](<../../../研发体系/角色/角色索引.md>)
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\347\240\224\345\217\221\344\275\223\347\263\273\346\234\254\345\234\260\345\214\226/02-\345\256\236\347\216\260\344\270\216\350\207\252\346\265\213\350\256\260\345\275\225.md" "b/docs/\344\273\273\345\212\241/202607/0717-\347\240\224\345\217\221\344\275\223\347\263\273\346\234\254\345\234\260\345\214\226/02-\345\256\236\347\216\260\344\270\216\350\207\252\346\265\213\350\256\260\345\275\225.md"
index 2cab1d4..1a18017 100644
--- "a/docs/\344\273\273\345\212\241/202607/0717-\347\240\224\345\217\221\344\275\223\347\263\273\346\234\254\345\234\260\345\214\226/02-\345\256\236\347\216\260\344\270\216\350\207\252\346\265\213\350\256\260\345\275\225.md"
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\347\240\224\345\217\221\344\275\223\347\263\273\346\234\254\345\234\260\345\214\226/02-\345\256\236\347\216\260\344\270\216\350\207\252\346\265\213\350\256\260\345\275\225.md"
@@ -32,13 +32,19 @@
- 测试与质量:Gate N `PASS`,Gate A `N/A_CONFIRMED`,文档质量`PASS`,见COLLAB-20260717-024、026。
- 上述结论之后新增的结果回写仅修改治理文档;Gate P前由项目管理员重新执行全量链接、占位符、敏感模式和影响面检查。
-## 最终本地验证
+## 提交前最终本地验证
- 当前工作区共有45份未跟踪Markdown:39份属于本任务,另6份属于并行的CRM-20260717-006;两者在台账中分别管理。
- 45份Markdown相对链接断链`0`、非模板占位符`0`、敏感值模式命中`0`。
- 协作事件共40条,事件编号重复`0`、必填字段缺失`0`。
- 相对起始commit `6e62407`的跟踪文件diff为`0`,未跟踪文件均为Markdown;本任务没有修改已有业务代码、配置或数据。
-- 本任务未执行Git commit或push,远程仓库尚未包含本轮治理文档。
+- 以上为Gate P复验时的提交前快照。
+
+## 远程交付
+
+- 2026-07-17,本任务文档已随治理基线提交并推送到`origin/main`。
+- 首轮远程交付commit为`9ad42b5`;本机`docs/local/`敏感文件保持Git忽略,未进入提交。
+- 远程交付不解除BLOCK-001至003,也不代表CRM-006或其他业务任务完成。
## 已知限制
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\347\240\224\345\217\221\344\275\223\347\263\273\346\234\254\345\234\260\345\214\226/03-\351\252\214\346\224\266\350\256\260\345\275\225.md" "b/docs/\344\273\273\345\212\241/202607/0717-\347\240\224\345\217\221\344\275\223\347\263\273\346\234\254\345\234\260\345\214\226/03-\351\252\214\346\224\266\350\256\260\345\275\225.md"
index cd3c06e..13e1d92 100644
--- "a/docs/\344\273\273\345\212\241/202607/0717-\347\240\224\345\217\221\344\275\223\347\263\273\346\234\254\345\234\260\345\214\226/03-\351\252\214\346\224\266\350\256\260\345\275\225.md"
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\347\240\224\345\217\221\344\275\223\347\263\273\346\234\254\345\234\260\345\214\226/03-\351\252\214\346\224\266\350\256\260\345\275\225.md"
@@ -17,5 +17,5 @@
## 剩余边界
- CRM-20260717-001已通过Gate P并标记本地完成,无任务内未通过项。
-- 39份治理文档当前仍是未跟踪文件,尚未形成Git commit;本轮完成状态只代表本地交付闭环,不代表已提交或推送。
+- 39份CRM-001治理文档已随治理基线提交并推送到`origin/main`;COLLAB-20260717-047记录远程交付结果。
- BLOCK-001至BLOCK-003不属于本任务的整改范围,继续保持业务系统正式上线`No-Go`。
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\347\240\224\345\217\221\344\275\223\347\263\273\346\234\254\345\234\260\345\214\226/04-\346\234\254\350\275\256\347\273\223\350\256\272.md" "b/docs/\344\273\273\345\212\241/202607/0717-\347\240\224\345\217\221\344\275\223\347\263\273\346\234\254\345\234\260\345\214\226/04-\346\234\254\350\275\256\347\273\223\350\256\272.md"
index a833488..4c7d707 100644
--- "a/docs/\344\273\273\345\212\241/202607/0717-\347\240\224\345\217\221\344\275\223\347\263\273\346\234\254\345\234\260\345\214\226/04-\346\234\254\350\275\256\347\273\223\350\256\272.md"
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\347\240\224\345\217\221\344\275\223\347\263\273\346\234\254\345\234\260\345\214\226/04-\346\234\254\350\275\256\347\273\223\350\256\272.md"
@@ -1,11 +1,11 @@
# 本轮结论
-- 交付结果:本地完成;8个正式角色会话和治理文档已建立,首轮问题已整改,Gate P复验`PASS`。
+- 交付结果:已提交并推送;8个正式角色会话和治理文档已建立,首轮问题已整改,Gate P复验`PASS`。
- 用户可见变化:项目已具备独立角色入口、统一研发流程、可追溯台账和中文任务目录规则。
- 已完成:39份治理文档初始交付、8/8角色接入、链接/占位符/敏感模式扫描、业务文件未改检查。
- 已完成:独立Gate N、Gate C/D/A的任务级N/A确认与文档安全/质量复核。
-- 未完成:39份CRM-001治理文档尚未提交或推送;这不影响本地完成,但远程仓库尚未交付本轮成果。
+- 未完成:业务系统BLOCK-001至003和后续真实迭代不属于本任务;治理文档远程交付已完成。
- 当前Gate:Gate P `PASS`。
- Go/No-Go:研发体系可进入试运行;业务系统正式上线仍为`No-Go`。
- 回滚入口:删除本任务新增的研发体系文档;不会影响业务代码和运行数据。
-- 下一责任人:Owner决定是否提交并推送;并行需求和P0整改按各自任务继续。
+- 下一责任人:Owner和项目管理员维护远程治理基线;并行需求和P0整改按各自任务继续。
diff --git "a/docs/\344\273\273\345\212\241/202607/0717-\347\240\224\345\217\221\344\275\223\347\263\273\346\234\254\345\234\260\345\214\226/\345\257\274\350\257\273.md" "b/docs/\344\273\273\345\212\241/202607/0717-\347\240\224\345\217\221\344\275\223\347\263\273\346\234\254\345\234\260\345\214\226/\345\257\274\350\257\273.md"
index 960942e..8a2d212 100644
--- "a/docs/\344\273\273\345\212\241/202607/0717-\347\240\224\345\217\221\344\275\223\347\263\273\346\234\254\345\234\260\345\214\226/\345\257\274\350\257\273.md"
+++ "b/docs/\344\273\273\345\212\241/202607/0717-\347\240\224\345\217\221\344\275\223\347\263\273\346\234\254\345\234\260\345\214\226/\345\257\274\350\257\273.md"
@@ -1,10 +1,10 @@
# CRM-20260717-001 研发体系本地化导读
-- 状态:本地完成
+- 状态:已提交并推送
- 当前Gate:Gate P `PASS`
- 统一台账:[统一计划台账](<../../统一计划台账.md>)
- 主协作事件:[协作事件COLLAB-20260717-001至026、039至040](<../../协作事件.md>)
-- 当前下一棒:Owner决定是否提交并推送本地治理文档;业务整改按独立任务继续
+- 当前下一棒:Owner与项目管理员维护远程治理基线;业务整改按独立任务继续
## 文档
diff --git "a/docs/\344\273\273\345\212\241/\345\215\217\344\275\234\344\272\213\344\273\266.md" "b/docs/\344\273\273\345\212\241/\345\215\217\344\275\234\344\272\213\344\273\266.md"
index 7a2fb3e..87e2324 100644
--- "a/docs/\344\273\273\345\212\241/\345\215\217\344\275\234\344\272\213\344\273\266.md"
+++ "b/docs/\344\273\273\345\212\241/\345\215\217\344\275\234\344\272\213\344\273\266.md"
@@ -438,7 +438,7 @@
- 上游事件:Owner员工修改密码需求
- 结果事件:COLLAB-20260717-033
- 当前Gate:CRM-20260717-006 / Gate N
-- 状态:PENDING
+- 状态:IN_PROGRESS
- 目标:评审员工自主改密需求的可实现性、安全依赖、数据迁移和回滚影响。
- 输入:[需求与验收](<./202607/0717-员工修改密码/00-需求与验收.md>)、[计划改动清单](<./202607/0717-员工修改密码/01-计划改动清单.md>)、[系统现状与改造路线](<../架构/系统现状与改造路线.md>)。
- 范围:只读评审密码哈希、会话撤销、现有账号迁移、强制轮换、备份和回滚边界。
@@ -881,7 +881,7 @@
- 不做项:不修改业务代码、运行账号数据、Git状态、部署或运行态;不处理CRM-20260717-008或其他任务;不代签技术Gate。
- 验收:MVP至少包含员工本人改密、当前密码校验、新密码确认、基本错误提示和主管原有重置能力;复杂会话、强制轮换、审计、限流和大规模迁移明确延期;输出剩余问题和下一责任人。
- 敏感边界:不得读取、记录或输出任何真实密码、Token、账号明细、客户数据或完整请求响应。
-- 队列编号:QUEUE-20260717-009
+- 队列编号:QUEUE-20260717-010(结项时纠正并发占用的临时编号009)
- 下一责任人:产品与项目管理
## COLLAB-20260717-046 | 员工修改密码MVP需求收敛结果
@@ -903,5 +903,1921 @@
- 结论:产品需求整改`PASS`。v0.2-MVP保留10项可验证的基本功能标准;密码哈希、旧认证退役、强制轮换、一次性临时凭据、完整会话撤销、复杂限流和审计延期处理。
- 证据:[需求与验收](<./202607/0717-员工修改密码/00-需求与验收.md>)、[计划改动清单](<./202607/0717-员工修改密码/01-计划改动清单.md>);任务内6份Markdown断链0。
- 未完成项:Owner确认密码长度、成功退出、主管原重置方式及是否先测试后部署;随后重新执行受影响角色Gate N。现有P0风险和No-Go继续有效。
-- 队列编号:QUEUE-20260717-009
+- 队列编号:QUEUE-20260717-010(结项时纠正并发占用的临时编号009)
- 下一责任人:Owner
+
+## COLLAB-20260717-047 | 治理文档远程交付与队列编号纠正
+
+- 事件类型:交付结果
+- 发起时间:2026-07-17
+- 发起角色:项目管理员
+- 目标角色:Owner/全部正式角色
+- 上游事件:COLLAB-20260717-040、042、044、046
+- 结果事件:无
+- 当前Gate:CRM-20260717-001、007、008 / Gate P
+- 状态:PASS
+- 目标:把已验收治理与会话修复文档提交并推送,并消除并发登记造成的队列编号重复。
+- 输入:67份待提交Markdown、`origin/main`、全部8个角色队列和COLLAB-20260717-043至046。
+- 范围:治理Markdown的Git提交与推送;架构QUEUE-009和后登记产品队列的编号一致性纠正。
+- 不做项:不修改业务代码、配置、数据、部署或运行态;不把CRM-006需求收敛描述为实现完成或业务Gate通过。
+- 验收:普通交付文件敏感值模式0,本机敏感文件保持Git忽略;首轮提交`9ad42b5`已推送;架构保留QUEUE-009,产品更正为全局唯一QUEUE-010;全部队列IDLE。
+- 敏感边界:`docs/local/`不进入Git;事件不记录凭据值、客户数据、原始日志或完整请求响应。
+- 结论:PASS。治理基线和会话修复已进入远程`main`,并发编号冲突已消除。
+- 未完成项:业务系统BLOCK-001至003和正式上线No-Go继续有效;CRM-006仍需Owner确认后重新执行Gate N。
+- 下一责任人:Owner处理CRM-006剩余产品决策;项目管理员继续执行全局队列编号和投递前双重检查
+
+## COLLAB-20260717-048 | 员工修改密码MVP决策冻结
+
+- 事件类型:产品决策与迭代启动请求
+- 发起时间:2026-07-17
+- 发起角色:Owner
+- 目标角色:产品与项目管理
+- 上游事件:COLLAB-20260717-045至047
+- 结果事件:待回传
+- 当前Gate:CRM-20260717-006 / Gate N需求冻结
+- 状态:IN_PROGRESS
+- 目标:确认v0.2-MVP的四项产品问题,冻结最小可用需求,并按标准开发迭代流程重新建立Gate N复评队列。
+- 输入:Owner确认第一阶段不部署线上,其余三项采用产品建议;要求不要做大而全,先能用、再逐步好用,并进入开发迭代流程。
+- 范围:冻结密码长度、修改成功后的登录行为、主管原重置方式和首阶段环境边界;同步需求、计划、验收、台账与协作队列。
+- 不做项:不修改业务代码、运行账号数据、部署配置、Git状态或运行态;不执行测试环境部署;不授权或执行正式线上部署;不代签专业Gate。
+- 验收:四项Owner决策形成唯一事实源;MVP范围和10项验收不扩张;测试环境限定及线上部署禁止清晰;六个适用专业角色Gate N复评可串行调度。
+- 敏感边界:不得读取、记录或输出任何真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 队列编号:QUEUE-20260717-011
+- 下一责任人:产品与项目管理
+
+## COLLAB-20260717-049 | 员工修改密码MVP决策冻结结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:Owner/项目管理员
+- 上游事件:COLLAB-20260717-048
+- 结果事件:COLLAB-20260717-050至055
+- 当前Gate:CRM-20260717-006 / Gate N需求冻结
+- 状态:PASS
+- 目标:回传v0.3-MVP产品决策冻结结果并进入专业Gate N复评排队。
+- 输入:Owner确认前三项采用产品建议、第四项暂不部署线上,以及v0.2-MVP需求与验收。
+- 范围:冻结密码长度、成功后退出重登、主管原重置方式、测试环境边界和线上部署停止线;同步产品事实源。
+- 不做项:未修改业务代码、运行账号数据、部署配置、Git状态或运行态;未执行任何环境部署;未代签专业Gate。
+- 验收:四项Owner决策已写入v0.3-MVP;10项MVP验收未扩张;测试环境限定和线上部署禁止明确;后续角色可独立复评。
+- 敏感边界:未读取、记录或输出真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 结论:产品需求冻结`PASS`。第一阶段只做员工本人改密最小闭环,复杂安全与体验能力继续延期;当前不构成业务实现或部署授权。
+- 证据:[需求与验收](<./202607/0717-员工修改密码/00-需求与验收.md>)、[计划改动清单](<./202607/0717-员工修改密码/01-计划改动清单.md>)、[验收记录](<./202607/0717-员工修改密码/03-验收记录.md>)。
+- 未完成项:架构、UI、前端、后端、安全和测试尚未对v0.3-MVP重新执行Gate N;`BLOCK-001`至`BLOCK-003`和项目整体`No-Go`继续有效。
+- 队列编号:QUEUE-20260717-011
+- 下一责任人:项目管理员建立并串行派发六个专业角色Gate N复评项
+
+## COLLAB-20260717-050 | 员工修改密码MVP架构Gate N复评
+
+- 事件类型:Gate请求
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:架构与数据治理
+- 上游事件:COLLAB-20260717-049
+- 结果事件:COLLAB-20260717-057
+- 当前Gate:CRM-20260717-006 / Gate N复评
+- 状态:CLOSED
+- 目标:判断v0.3-MVP最小本人改密闭环在当前架构下是否可行,并列出Gate R必须冻结的最小接口、身份、密码更新和兼容边界。
+- 输入:[需求与验收](<./202607/0717-员工修改密码/00-需求与验收.md>)、[计划改动清单](<./202607/0717-员工修改密码/01-计划改动清单.md>)及首轮架构意见COLLAB-20260717-033。
+- 范围:只读复评本人改密接口、当前登录身份、现有主管重置兼容、修改成功后退出重登,以及未来密码哈希迁移不被MVP阻断的边界。
+- 不做项:不设计或实现延期能力,不修改代码、数据、配置、Git状态或运行态,不部署测试或线上环境,不把Gate N写成Gate R或上线批准。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED、首轮问题在MVP裁剪后的适用性、Gate R最小前置项和已知风险;确认正式线上部署仍禁止。
+- 敏感边界:不读取或记录真实密码、账号明细、客户数据、凭据值、原始日志或完整请求响应。
+- 队列编号:QUEUE-20260717-012
+- 下一责任人:项目管理员在目标队列无锁且会话idle时投递
+
+## COLLAB-20260717-051 | 员工修改密码MVP交互Gate N复评
+
+- 事件类型:Gate请求
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:UI与交互设计
+- 上游事件:COLLAB-20260717-049
+- 结果事件:COLLAB-20260717-063
+- 当前Gate:CRM-20260717-006 / Gate N复评
+- 状态:CLOSED
+- 目标:判断v0.3-MVP的入口、三字段表单、基本错误状态和成功退出流程是否足以形成最小可用交互。
+- 输入:[需求与验收](<./202607/0717-员工修改密码/00-需求与验收.md>)、[计划改动清单](<./202607/0717-员工修改密码/01-计划改动清单.md>)及首轮交互意见COLLAB-20260717-034。
+- 范围:只读复评入口位置、表单字段、提交/取消、五类基本提示、后端离线和成功返回登录页;主管重置只做现状兼容判断。
+- 不做项:不扩展强制改密、密码找回、会话中心或完整视觉改版,不修改文件、代码、数据、Git状态或运行态,不部署任何环境。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED、最小页面/状态清单、首轮问题关闭或延期依据和Gate R所需交互规格;确认线上部署不在范围。
+- 敏感边界:原型、示例和记录不得含真实密码、真实账号或客户数据。
+- 队列编号:QUEUE-20260717-013
+- 下一责任人:项目管理员在目标队列无锁且会话idle时投递
+
+## COLLAB-20260717-052 | 员工修改密码MVP前端Gate N复评
+
+- 事件类型:Gate请求
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:前端开发
+- 上游事件:COLLAB-20260717-049
+- 结果事件:COLLAB-20260717-058
+- 当前Gate:CRM-20260717-006 / Gate N复评
+- 状态:CLOSED
+- 目标:判断v0.3-MVP在当前前端中的最小实现范围是否清晰、可行且可验证。
+- 输入:[需求与验收](<./202607/0717-员工修改密码/00-需求与验收.md>)、[计划改动清单](<./202607/0717-员工修改密码/01-计划改动清单.md>)及首轮前端意见COLLAB-20260717-035。
+- 范围:只读复评入口、三字段表单、前端基本校验、提交防重、错误展示、后端离线禁止本地假成功和成功后清除当前登录。
+- 不做项:不编写或修改前端代码,不扩展路由/认证整体重构,不修改数据、配置、Git状态或运行态,不部署任何环境。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED、最小改动面、Gate R必须明确的接口/错误约定、首轮问题关闭或延期依据;确认线上部署禁止。
+- 敏感边界:不得在浏览器日志、示例、测试记录或文档中写入真实密码、Token、账号明细或客户数据。
+- 队列编号:QUEUE-20260717-014
+- 下一责任人:项目管理员在目标队列无锁且会话idle时投递
+
+## COLLAB-20260717-053 | 员工修改密码MVP后端Gate N复评
+
+- 事件类型:Gate请求
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:后端开发
+- 上游事件:COLLAB-20260717-049
+- 结果事件:COLLAB-20260717-059
+- 当前Gate:CRM-20260717-006 / Gate N复评
+- 状态:CLOSED
+- 目标:重新确认v0.3-MVP本人改密接口在当前后端中的最小实现范围、依赖和主要风险。
+- 输入:[需求与验收](<./202607/0717-员工修改密码/00-需求与验收.md>)、[计划改动清单](<./202607/0717-员工修改密码/01-计划改动清单.md>)及首轮后端意见COLLAB-20260717-036。
+- 范围:只读复评登录身份绑定、当前密码校验、8至64字符规则、新旧不同、密码更新、旧密码失效、主管原重置回归和错误边界。
+- 不做项:不编写或修改后端代码,不执行密码迁移或真实账号试验,不修改数据、配置、Git状态或运行态,不部署任何环境。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED、最小接口边界、Gate R必须冻结项、与现有P0风险的关系;确认测试环境限定和线上部署禁止。
+- 敏感边界:不读取、复制、输出或记录真实密码、密码字段值、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 队列编号:QUEUE-20260717-015
+- 下一责任人:项目管理员在目标队列无锁且会话idle时投递
+
+## COLLAB-20260717-054 | 员工修改密码MVP安全Gate N复评
+
+- 事件类型:Gate请求
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:代码审核与安全
+- 上游事件:COLLAB-20260717-049
+- 结果事件:COLLAB-20260717-060
+- 当前Gate:CRM-20260717-006 / Gate N复评
+- 状态:CLOSED
+- 目标:判断v0.3-MVP是否在不扩大现有P0风险的前提下具备进入Gate R的最小安全边界。
+- 输入:[需求与验收](<./202607/0717-员工修改密码/00-需求与验收.md>)、[计划改动清单](<./202607/0717-员工修改密码/01-计划改动清单.md>)、现有BLOCK-001至003及首轮安全意见COLLAB-20260717-037。
+- 范围:只读复评仅本人修改、当前密码验证、后端强制身份、密码不泄露、后端离线不假成功、主管原重置兼容,以及延期安全项不被误报为已解决。
+- 不做项:不执行Gate C,不审核不存在的实现,不修改代码、数据、配置、Git状态或运行态,不部署任何环境,不解除项目No-Go。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED、MVP最低安全停止线、首轮问题关闭或延期依据、Gate R/C所需证据;明确线上部署仍禁止。
+- 敏感边界:不读取或记录真实密码、密码散列、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 队列编号:QUEUE-20260717-016
+- 下一责任人:项目管理员在目标队列无锁且会话idle时投递
+
+## COLLAB-20260717-055 | 员工修改密码MVP测试Gate N复评
+
+- 事件类型:Gate请求
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:测试与质量
+- 上游事件:COLLAB-20260717-049
+- 结果事件:COLLAB-20260717-061
+- 当前Gate:CRM-20260717-006 / Gate N复评
+- 状态:CLOSED
+- 目标:确认v0.3-MVP的10项验收标准在隔离测试环境中可测,并明确Gate R最小测试前置条件。
+- 输入:[需求与验收](<./202607/0717-员工修改密码/00-需求与验收.md>)、[计划改动清单](<./202607/0717-员工修改密码/01-计划改动清单.md>)及首轮测试意见COLLAB-20260717-038。
+- 范围:只读复评正常、当前密码错误、确认不一致、长度、新旧相同、越权、旧新密码登录、主管回归、停用账号、后端离线和敏感值泄露等最小测试面。
+- 不做项:不执行Gate A,不运行测试或创建真实账号,不修改文件、代码、数据、Git状态或运行态,不部署测试或线上环境。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED、10项标准可测性、Gate R所需环境/样本/接口前置和延期项边界;确认只允许未来在隔离测试环境验证。
+- 敏感边界:测试设计只使用虚构账号与占位值,不记录真实密码、Token、客户数据、原始日志或完整请求响应。
+- 队列编号:QUEUE-20260717-017
+- 下一责任人:项目管理员在目标队列无锁且会话idle时投递
+
+## COLLAB-20260717-056 | 模块化单体与MySQL渐进迁移架构方案
+
+- 事件类型:架构方案请求
+- 发起时间:2026-07-17
+- 发起角色:Owner
+- 目标角色:架构与数据治理
+- 上游事件:Owner在正式架构会话确认MySQL、渐进迁移、本地优先和移动端范围
+- 结果事件:COLLAB-20260717-076
+- 当前Gate:CRM-20260717-003 / Gate N、Gate R
+- 状态:CLOSED
+- 目标:形成面向Web与未来移动端的小型模块化单体目标架构、MySQL数据方案、本地环境和渐进迁移路线。
+- 输入:[需求与验收](<./202607/0717-模块化单体架构方案/00-需求与验收.md>)、[计划改动清单](<./202607/0717-模块化单体架构方案/01-计划改动清单.md>)、当前代码与[系统现状](<../架构/系统现状与改造路线.md>)。
+- 范围:只修改CRM-003任务文档、架构文档及必要的角色裁剪说明;覆盖技术栈、目录、模块、MySQL、API契约、本地环境、迁移和回滚。
+- 不做项:不修改业务代码、配置、运行数据、账号、部署或运行态;不部署生产环境;不抢占前序CRM-006 Gate N复评。
+- 验收:满足任务8项标准,回传PASS/CHANGES_REQUESTED/BLOCKED、文档清单、关键裁决、风险、未决项和下一Gate责任人。
+- 敏感边界:不读取或输出真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 队列编号:QUEUE-20260717-018
+- 下一责任人:架构与数据治理在QUEUE-012完成并释放锁后顺次处理
+
+## COLLAB-20260717-057 | 员工修改密码MVP架构Gate N复评结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:架构与数据治理
+- 目标角色:产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-050
+- 结果事件:无
+- 当前Gate:CRM-20260717-006 / Gate N复评
+- 状态:PASS
+- 目标:回传v0.3-MVP架构可行性、首轮意见处理和Gate R最小边界。
+- 输入:COLLAB-20260717-050指定材料、当前认证/账号代码结构和QUEUE-20260717-012。
+- 范围:只读复评本人改密、后端身份、主管重置兼容、重新认证和未来密码存储迁移边界。
+- 不做项:未修改文件、代码、配置、数据、Git状态、部署或运行态;未执行Gate R/C/D/A/P;未部署生产环境。
+- 验收:结论包含首轮问题关闭/延期、Gate R接口与凭据边界、原子更新、并发、回滚、测试材料、风险和停止线。
+- 敏感边界:未读取或输出真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 结论:PASS。v0.3-MVP当前架构可实现;Gate R必须冻结本人改密独立接口、后端认证身份、稳定错误码、最小凭据访问边界、原子更新/并发语义、重新认证和隔离测试材料。
+- 证据:Codex Thread `019f6f85-bee8-7f70-8d0a-af638ece0782`,turn `019f6fa8-790f-7ef0-b870-1e6cdccbd8ee`。
+- 未完成项:其他角色Gate N复评和汇总尚未完成;密码哈希、旧认证退役、完整会话撤销及数据治理仍延期;BLOCK-001至003和正式上线No-Go继续有效。
+- 队列编号:QUEUE-20260717-012
+- 下一责任人:项目管理员汇总其余Gate N结果;架构角色按自身队列顺次处理QUEUE-018
+
+## COLLAB-20260717-058 | 员工修改密码MVP前端Gate N复评结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:前端开发
+- 目标角色:产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-052
+- 结果事件:无
+- 当前Gate:CRM-20260717-006 / Gate N复评
+- 状态:PASS
+- 目标:回传v0.3-MVP前端最小范围、文档矛盾整改和Gate R前置。
+- 输入:COLLAB-20260717-052指定材料、修正后的密码传输边界和QUEUE-20260717-014。
+- 范围:只读复评入口、三字段表单、校验、防重、错误、离线禁止回退和成功后清除登录。
+- 不做项:未修改代码、配置、数据、Git状态、部署或运行态;未处理其他任务;未执行Gate R/C/D/A/P。
+- 验收:首轮发现“请求不得含密码”与改密接口矛盾后保持同一执行锁;需求修正为密码只允许进入专用请求体,复评PASS。
+- 敏感边界:密码不得进入URL、查询参数、响应、日志、协作记录或浏览器持久化;未读取真实凭据或客户数据。
+- 结论:PASS。Gate R需冻结接口与字段、确认密码归属、字符计数、稳定错误码、单次在途、禁本地回退、成功清理登录和最小自测矩阵。
+- 证据:Codex Thread `019f6ea8-7abd-7ca2-8b6c-8e3e54cfd8b1`,复评turn `019f6fae-0797-77f0-9fb0-35b04f64a5ed`。
+- 未完成项:Gate R、实现、自测和Gate C/D/A/P尚未完成;BLOCK-001至003和正式上线No-Go继续有效。
+- 队列编号:QUEUE-20260717-014
+- 下一责任人:产品与项目管理汇总Gate N
+
+## COLLAB-20260717-059 | 员工修改密码MVP后端Gate N复评结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:后端开发
+- 目标角色:产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-053
+- 结果事件:无
+- 当前Gate:CRM-20260717-006 / Gate N复评
+- 状态:PASS
+- 目标:回传v0.3-MVP后端范围、依赖、风险和Gate R最小冻结项。
+- 输入:COLLAB-20260717-053指定材料和QUEUE-20260717-015。
+- 范围:只读复评登录身份、当前密码、长度与一致性、原子更新、旧新密码登录和主管回归。
+- 不做项:未修改代码、配置、数据、Git状态、部署或运行态;未执行迁移、测试或其他Gate。
+- 验收:结论覆盖首轮意见关闭/延期、接口、身份、校验、原子性、并发、错误码、主管回归、隔离环境和停止线。
+- 敏感边界:未读取或输出真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 结论:PASS。Gate R需冻结独立接口、后端身份、启用状态、8至64字符、原子持久化、并发冲突、稳定错误码、主管回归和隔离测试复位。
+- 证据:Codex Thread `019f6ea8-9633-7a82-9034-789ecc7888da`,turn `019f6fa8-85c2-7c32-b038-5f37754bdc68`。
+- 未完成项:Gate R、实现、自测和Gate C/D/A/P尚未完成;延期安全能力及CRM-002数据治理未处理。
+- 队列编号:QUEUE-20260717-015
+- 下一责任人:产品与项目管理汇总Gate N
+
+## COLLAB-20260717-060 | 员工修改密码MVP安全Gate N复评结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:代码审核与安全
+- 目标角色:产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-054
+- 结果事件:无
+- 当前Gate:CRM-20260717-006 / Gate N复评
+- 状态:PASS
+- 目标:回传v0.3-MVP最低安全边界、延期风险和Gate R/C证据要求。
+- 输入:COLLAB-20260717-054指定材料、BLOCK-001至003和QUEUE-20260717-016。
+- 范围:只读复评仅本人修改、当前密码、后端身份、敏感值、离线禁止回退、主管兼容和隔离环境。
+- 不做项:未执行Gate C,未修改代码、数据、配置、Git状态或运行态,未部署任何环境或解除No-Go。
+- 验收:结论列明首轮关闭/延期项、Gate R最小接口/身份/校验/原子性/并发/敏感值/环境规则、停止线及Gate C证据。
+- 敏感边界:未读取或记录真实密码、散列、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 结论:PASS,仅限隔离测试环境需求。任何越权、错误当前密码仍写入、停用账号可改、离线假成功或敏感值泄露必须停止。
+- 证据:Codex Thread `019f6ea8-b081-7121-9d98-4c9714bf50e1`,turn `019f6fa8-8ea6-7142-83e7-7373517d0f92`。
+- 未完成项:Gate R/C/D/A/P尚未执行;密码哈希、旧认证退役、会话撤销、限流、审计及Git历史治理延期且不得误报完成。
+- 队列编号:QUEUE-20260717-016
+- 下一责任人:产品与项目管理汇总Gate N
+
+## COLLAB-20260717-061 | 员工修改密码MVP测试Gate N复评结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:测试与质量
+- 目标角色:产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-055
+- 结果事件:无
+- 当前Gate:CRM-20260717-006 / Gate N复评
+- 状态:PASS
+- 目标:回传v0.3-MVP十项验收可测性和Gate R测试前置。
+- 输入:COLLAB-20260717-055指定材料和QUEUE-20260717-017。
+- 范围:只读复评正常、错误、边界、越权、登录、主管回归、停用、离线和敏感值测试面。
+- 不做项:未执行Gate A或业务测试,未修改文件、代码、数据、Git状态、部署或运行态。
+- 验收:十项标准10/10可测,结论给出接口、会话、隔离环境、虚构样本、自动化矩阵和脱敏证据要求。
+- 敏感边界:只允许虚构账号与占位密码,不记录真实凭据、客户数据、原始日志或完整请求响应。
+- 结论:PASS,仅为Gate N可测性;接口/错误码/环境/样本/自动化矩阵未冻结前Gate R不得通过。
+- 证据:Codex Thread `019f6ea8-ca49-7472-9a9e-24848071c22b`,turn `019f6fa8-8f3a-7943-89ac-cb3706b2f83f`。
+- 未完成项:未执行测试、Gate A或其他后续Gate;BLOCK-001至003和正式上线No-Go继续有效。
+- 队列编号:QUEUE-20260717-017
+- 下一责任人:产品与项目管理汇总Gate N
+
+## COLLAB-20260717-062 | 员工修改密码MVP六角色Gate N汇总
+
+- 事件类型:Gate请求
+- 发起时间:2026-07-17
+- 发起角色:项目管理员
+- 目标角色:产品与项目管理
+- 上游事件:COLLAB-20260717-057至061、063
+- 结果事件:COLLAB-20260717-065
+- 当前Gate:CRM-20260717-006 / Gate N汇总
+- 状态:CLOSED
+- 目标:在六个专业角色复评结果全部回传后,判断v0.3-MVP Gate N是否整体通过并给出Gate R入口条件。
+- 输入:CRM-006冻结需求、首轮结果和COLLAB-20260717-057至061、063六个PASS结果。
+- 范围:只读汇总范围一致性、角色结论、需求整改、延期边界、停止线和下一阶段责任人。
+- 不做项:不修改业务代码、数据、配置、Git状态、部署或运行态;不代签Gate R/C/D/A/P;不解除No-Go。
+- 验收:只有六个专业角色均PASS且矛盾关闭时才能回传整体PASS;否则列出整改和重评项。
+- 敏感边界:只使用脱敏结论,不读取或输出真实凭据、账号明细、客户数据、原始日志或完整请求响应。
+- 队列编号:QUEUE-20260717-019
+- 下一责任人:产品与项目管理汇总六角色Gate N结论
+
+## COLLAB-20260717-063 | 员工修改密码MVP交互Gate N复评结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:UI与交互设计
+- 目标角色:产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-051
+- 结果事件:无
+- 当前Gate:CRM-20260717-006 / Gate N复评
+- 状态:PASS
+- 目标:回传v0.3-MVP最小页面、状态和Gate R交互规格。
+- 输入:COLLAB-20260717-051指定材料和QUEUE-20260717-013。
+- 范围:只读复评顶部账号入口、三字段对话框、提交/取消、基本提示、后端离线和成功返回登录页。
+- 不做项:未修改文件、代码、配置、数据、Git状态、部署或运行态;未制作原型、执行测试或处理其他任务。
+- 验收:结论覆盖首轮意见关闭/延期、最小承载点、状态清单、Gate R交互规格、风险和停止线。
+- 敏感边界:密码字段不得预填、回显、持久化或进入URL、提示、日志和文档;未读取真实凭据或客户数据。
+- 结论:PASS。最小交互为顶部“修改密码”入口、三字段对话框和成功后的登录页提示;Gate R需冻结移动端单列、焦点/关闭、校验与提示、错误码映射、防重、故障关闭、清理登录和无障碍规则。
+- 证据:Codex Thread `019f6fa9-44a2-7313-892d-886b43af1be9`,turn `019f6fa9-5f44-7a32-9409-08eb23642bf8`。
+- 未完成项:Gate R、原型、实现、浏览器测试和Gate C/D/A/P尚未完成;正式生产部署继续禁止。
+- 队列编号:QUEUE-20260717-013
+- 下一责任人:产品与项目管理汇总Gate N
+
+## COLLAB-20260717-064 | UI新旧会话历史交接与归档
+
+- 事件类型:会话交接请求
+- 发起时间:2026-07-17
+- 发起角色:Owner/项目管理员
+- 目标角色:UI与交互设计
+- 上游事件:Owner要求替代会话先完整回读旧聊天记录再归档旧会话
+- 结果事件:COLLAB-20260717-066
+- 当前Gate:CRM-20260717-008 / 会话交接验收
+- 状态:CLOSED
+- 目标:让第三代正式UI会话完整回读前两代UI会话历史,确认决策、任务和恢复点无遗漏后再归档旧会话。
+- 输入:[会话故障迁移与交接规范](<../研发体系/会话故障迁移与交接规范.md>)、旧Thread `019f6ea8-61fa-7fa3-ae43-2a11f6b6f354`、旧Thread `019f6f41-7c33-7200-97b4-5bb4690de8c2`、新正式Thread `019f6fa9-44a2-7313-892d-886b43af1be9`及UI角色队列。
+- 范围:只读完整历史、输出脱敏交接清单、核对QUEUE-003/013和角色边界;不处理新业务任务。
+- 不做项:不修改文件、代码、配置、数据、Git状态、部署或运行态;交接PASS前不归档旧UI会话。
+- 验收:新UI回传标准交接回执,确认Owner决策、方案取舍、已完成/未完成项、队列和风险无遗漏,并明确是否允许归档。
+- 敏感边界:不得复制原始聊天、真实凭据、客户数据、原始日志或完整请求响应,只记录脱敏摘要和Thread/turn ID。
+- 队列编号:QUEUE-20260717-020
+- 下一责任人:UI与交互设计完成历史回读并回传交接结论
+
+## COLLAB-20260717-065 | 员工修改密码MVP六角色Gate N汇总结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:Owner/项目管理员
+- 上游事件:COLLAB-20260717-062
+- 结果事件:无
+- 当前Gate:CRM-20260717-006 / Gate N汇总
+- 状态:PASS
+- 目标:回传v0.3-MVP六角色复评汇总和统一Gate R入口条件。
+- 输入:冻结需求、COLLAB-20260717-057至061、063及前端同项整改复评证据。
+- 范围:只读汇总MVP范围、延期项、接口/交互/安全/测试前置、风险和下一责任人。
+- 不做项:未修改文件、代码、配置、数据、Git状态、部署或运行态;未执行Gate R/C/D/A/P;未处理CRM-003。
+- 验收:六个适用角色均PASS,密码请求边界矛盾关闭,范围与延期项一致,Gate R统一清单和角色责任明确。
+- 敏感边界:仅使用脱敏结论,未读取或输出真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 结论:PASS。v0.3-MVP Gate N整体通过,只代表具备进入Gate R条件;业务实现进度仍为0%。
+- Gate R入口:冻结专用接口/字段/身份/停用处理、字符与确认规则、稳定错误码、原子更新/并发、成功退出、UI交互与移动端布局、敏感值边界、隔离测试环境/虚构样本/自动化矩阵和测试数据恢复。
+- 风险与停止线:BLOCK-001至003和项目No-Go继续有效;越权、错误密码仍写入、停用账号可改、离线假成功、敏感值泄露或非隔离环境无HTTPS必须停止;正式生产部署禁止。
+- 证据:Codex Thread `019f6ea8-234e-7450-80fd-edc7c8c5438b`,turn `019f6fb5-d87f-7680-b21c-f7b4e63437c5`。
+- 未完成项:Gate R、实现、自测、Gate C/D/A/P均未完成;延期安全能力和CRM-002数据治理未处理。
+- 队列编号:QUEUE-20260717-019
+- 下一责任人:产品与项目管理、架构、UI、前后端、安全、测试及测试环境运维按新任务进入Gate R
+
+## COLLAB-20260717-066 | UI新旧会话历史交接与归档结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:UI与交互设计/项目管理员
+- 目标角色:Owner/产品与项目管理
+- 上游事件:COLLAB-20260717-064
+- 结果事件:无
+- 当前Gate:CRM-20260717-008 / 会话交接验收
+- 状态:PASS
+- 目标:回传两代旧UI历史回读、任务轨迹核对和旧会话归档结果。
+- 输入:两代旧UI Thread、第三代正式UI Thread、会话迁移规范和QUEUE-20260717-020。
+- 范围:只读回读全部旧turn、核对决策/方案/队列/恢复点、三处正式ID及执行归档。
+- 不做项:未修改业务代码、配置、数据、Git状态、部署或运行态;未处理CRM-003、CRM-006后续或其他任务。
+- 验收:第一代2个turn/2页、第二代1个turn/1页均读到`hasMore=false`;QUEUE-003/013无取消、替换、跳过或丢失;三处正式ID一致;旧会话允许归档。
+- 敏感边界:只记录脱敏摘要和Thread/turn ID,未复制原始聊天、凭据、客户数据、原始日志或完整请求响应。
+- 结论:PASS。第三代UI完整继承两代旧记录;旧会话无遗留任务,已分别重命名并归档。
+- 证据:新Codex Thread `019f6fa9-44a2-7313-892d-886b43af1be9`,交接turn `019f6fbd-559a-7121-9d01-7bdc0a37fb6f`;旧Thread `019f6ea8-61fa-7fa3-ae43-2a11f6b6f354`、`019f6f41-7c33-7200-97b4-5bb4690de8c2`。
+- 未完成项:无会话交接遗留;CRM-006 Gate R和其他业务任务按各自队列继续,正式生产部署仍禁止。
+- 队列编号:QUEUE-20260717-020
+- 下一责任人:项目管理员按新规范处理后续会话故障;UI角色等待新的正式队列项
+
+## COLLAB-20260717-067 | 员工修改密码MVP Gate R启动
+
+- 事件类型:方案阶段启动请求
+- 发起时间:2026-07-17
+- 发起角色:Owner
+- 目标角色:产品与项目管理
+- 上游事件:COLLAB-20260717-065
+- 结果事件:COLLAB-20260717-068
+- 当前Gate:CRM-20260717-006 / Gate R启动
+- 状态:CLOSED
+- 目标:依据Gate N整体PASS结论形成统一Gate R冻结清单,并建立架构、交互、前后端、安全、测试和测试环境运维的方案评审任务。
+- 输入:Owner要求继续推进;v0.3-MVP冻结需求、COLLAB-20260717-065及六角色Gate N复评结果。
+- 范围:仅维护CRM-006方案阶段的任务文档、台账、协作事件和角色队列;明确各角色必须冻结的最小方案与停止线。
+- 不做项:不修改业务代码、运行账号数据、部署配置、Git历史或运行态;不部署测试或正式环境;不处理CRM-003或其他任务;不代签专业Gate R结论。
+- 验收:形成编号清晰、责任唯一、可独立评审的Gate R统一清单;七个专业角色任务先建事件再入队;架构现有QUEUE-018不被抢占;正式生产部署继续禁止。
+- 敏感边界:不读取、记录或输出真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 队列编号:QUEUE-20260717-021
+- 下一责任人:产品与项目管理
+
+## COLLAB-20260717-068 | 员工修改密码MVP Gate R启动结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:Owner/项目管理员
+- 上游事件:COLLAB-20260717-067
+- 结果事件:COLLAB-20260717-069至075
+- 当前Gate:CRM-20260717-006 / Gate R启动
+- 状态:PASS
+- 目标:回传Gate R统一冻结清单、专业角色责任和调度入口。
+- 输入:Owner继续推进指令、COLLAB-20260717-065及v0.3-MVP冻结需求。
+- 范围:仅更新CRM-006 Gate R任务文档、台账、事件和产品队列。
+- 不做项:未修改业务代码、运行账号数据、部署配置、Git历史或运行态;未部署任何环境;未处理CRM-003;未代签专业Gate R。
+- 验收:R-01至R-11覆盖接口、身份、规则、原子性、重新认证、交互、错误、安全、测试、回滚和实现基线;七角色责任明确;架构现有锁不被抢占。
+- 敏感边界:未读取、记录或输出真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 结论:PASS。CRM-006已具备分别派发专业Gate R方案评审的材料,但Gate R整体仍为`PENDING`,业务实现仍未授权。
+- 证据:[计划改动清单](<./202607/0717-员工修改密码/01-计划改动清单.md>)、[验收记录](<./202607/0717-员工修改密码/03-验收记录.md>)及[统一计划台账](<./统一计划台账.md>)。
+- 未完成项:七角色专业Gate R结论、产品汇总、业务实现、自测及Gate C/D/A/P均未完成;正式生产部署继续禁止。
+- 队列编号:QUEUE-20260717-021
+- 下一责任人:项目管理员按角色队列安全投递COLLAB-20260717-069至075
+
+## COLLAB-20260717-069 | 员工修改密码MVP架构Gate R方案评审
+
+- 事件类型:Gate请求
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:架构与数据治理
+- 上游事件:COLLAB-20260717-068
+- 结果事件:COLLAB-20260717-077
+- 当前Gate:CRM-20260717-006 / Gate R
+- 状态:CLOSED
+- 目标:冻结R-01、R-02、R-04、R-05、R-07、R-10、R-11涉及的统一接口、身份、原子性、并发、重新认证、回滚和实现边界。
+- 输入:[需求与验收](<./202607/0717-员工修改密码/00-需求与验收.md>)、[Gate R统一清单](<./202607/0717-员工修改密码/01-计划改动清单.md>)、COLLAB-20260717-057与065。
+- 范围:只读形成可供前后端、安全、测试和运维共同采用的最小契约与方案结论;说明与未来密码存储迁移的兼容边界。
+- 不做项:不修改业务代码、数据、配置、Git状态、部署或运行态;不扩展密码哈希迁移、完整会话撤销和模块化重构;不处理CRM-003以外的新范围。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED、接口与身份契约、原子/并发/错误/重认证/回滚语义、实施停止线和后续责任人。
+- 敏感边界:不读取或输出真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 队列编号:QUEUE-20260717-022
+- 下一责任人:架构与数据治理处理已锁定QUEUE-022
+
+## COLLAB-20260717-070 | 员工修改密码MVP交互Gate R方案评审
+
+- 事件类型:Gate请求
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:UI与交互设计
+- 上游事件:COLLAB-20260717-068
+- 结果事件:COLLAB-20260717-078
+- 当前Gate:CRM-20260717-006 / Gate R
+- 状态:CLOSED
+- 目标:冻结R-06、R-07的顶部入口、三字段表单、移动端、焦点/关闭、提示、防重和无障碍规格。
+- 输入:[需求与验收](<./202607/0717-员工修改密码/00-需求与验收.md>)、[Gate R统一清单](<./202607/0717-员工修改密码/01-计划改动清单.md>)、COLLAB-20260717-063与065。
+- 范围:只读输出最小页面与状态规格,覆盖成功、校验失败、后端错误、离线和返回登录页;不制作大范围视觉改版。
+- 不做项:不修改页面或业务代码,不制作强制改密、找回密码或会话中心方案,不修改数据、配置、Git状态、部署或运行态。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED、可实施交互规格、错误码映射需求、可访问性规则、停止线和下一责任人。
+- 敏感边界:密码字段不得预填、回显、持久化或进入URL、提示、日志和文档;只用占位示例。
+- 队列编号:QUEUE-20260717-023
+- 下一责任人:UI与交互设计处理已锁定QUEUE-023
+
+## COLLAB-20260717-071 | 员工修改密码MVP前端Gate R方案评审
+
+- 事件类型:Gate请求
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:前端开发
+- 上游事件:COLLAB-20260717-068
+- 结果事件:COLLAB-20260717-079
+- 当前Gate:CRM-20260717-006 / Gate R
+- 状态:CHANGES_REQUESTED
+- 目标:冻结R-01、R-03、R-05至R-09、R-11涉及的前端承载点、请求状态机、错误映射、登录清理和自测方案。
+- 输入:[需求与验收](<./202607/0717-员工修改密码/00-需求与验收.md>)、[Gate R统一清单](<./202607/0717-员工修改密码/01-计划改动清单.md>)、COLLAB-20260717-058与065。
+- 范围:只读说明最小文件影响、字段与字符处理、防重复提交、离线失败关闭、成功清理登录以及前端测试入口。
+- 不做项:不修改前端或后端代码,不选择新框架,不扩展认证重构,不修改数据、配置、Git状态、部署或运行态。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED、前端方案、依赖的稳定契约、最小自测矩阵、停止线和下一责任人。
+- 敏感边界:密码只允许存在于内存中的专用请求体,不进入URL、响应、日志、文档或浏览器持久化。
+- 队列编号:QUEUE-20260717-024
+- 下一责任人:前端开发处理已锁定QUEUE-024
+
+## COLLAB-20260717-072 | 员工修改密码MVP后端Gate R方案评审
+
+- 事件类型:Gate请求
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:后端开发
+- 上游事件:COLLAB-20260717-068
+- 结果事件:COLLAB-20260717-080
+- 当前Gate:CRM-20260717-006 / Gate R
+- 状态:CLOSED
+- 目标:冻结R-01至R-05、R-07至R-11涉及的接口字段、身份、账号状态、校验、持久化、并发、重新认证、回滚和自测方案。
+- 输入:[需求与验收](<./202607/0717-员工修改密码/00-需求与验收.md>)、[Gate R统一清单](<./202607/0717-员工修改密码/01-计划改动清单.md>)、COLLAB-20260717-059与065。
+- 范围:只读形成当前后端可实施的最小方案,明确失败不落盘、旧新密码登录、主管重置回归和测试账号复位边界。
+- 不做项:不修改后端代码或运行数据,不执行密码迁移,不处理真实账号,不修改配置、Git状态、部署或运行态。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED、后端契约与状态语义、原子/并发/错误/回滚方案、最小自测矩阵和下一责任人。
+- 敏感边界:不读取、复制或输出真实密码、密码字段值、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 队列编号:QUEUE-20260717-025
+- 下一责任人:后端开发处理已锁定QUEUE-025
+
+## COLLAB-20260717-073 | 员工修改密码MVP安全Gate R方案评审
+
+- 事件类型:Gate请求
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:代码审核与安全
+- 上游事件:COLLAB-20260717-068
+- 结果事件:COLLAB-20260717-081
+- 当前Gate:CRM-20260717-006 / Gate R
+- 状态:CLOSED
+- 目标:冻结R-01、R-02、R-04、R-07、R-08、R-10、R-11的最低安全边界、威胁检查、停止线和未来Gate C证据要求。
+- 输入:[需求与验收](<./202607/0717-员工修改密码/00-需求与验收.md>)、[Gate R统一清单](<./202607/0717-员工修改密码/01-计划改动清单.md>)、COLLAB-20260717-060、065及BLOCK-001至003。
+- 范围:只读评审仅本人修改、当前密码、停用账号、敏感值、故障关闭、HTTPS、回滚材料及延期风险不误报规则。
+- 不做项:不执行Gate C,不审核不存在的实现,不修改代码、数据、配置、Git状态、部署或运行态,不解除No-Go。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED、最低安全方案、阻断条件、Gate C精确基线与证据清单、风险责任人。
+- 敏感边界:不读取或记录真实密码、密码散列、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 队列编号:QUEUE-20260717-026
+- 下一责任人:代码审核与安全处理已锁定QUEUE-026
+
+## COLLAB-20260717-074 | 员工修改密码MVP测试Gate R方案评审
+
+- 事件类型:Gate请求
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:测试与质量
+- 上游事件:COLLAB-20260717-068
+- 结果事件:COLLAB-20260717-082
+- 当前Gate:CRM-20260717-006 / Gate R
+- 状态:CHANGES_REQUESTED
+- 目标:冻结R-02至R-05、R-07至R-11的十项验收矩阵、虚构样本、环境、自动化、复位和脱敏证据要求。
+- 输入:[需求与验收](<./202607/0717-员工修改密码/00-需求与验收.md>)、[Gate R统一清单](<./202607/0717-员工修改密码/01-计划改动清单.md>)、COLLAB-20260717-061与065。
+- 范围:只读形成正常、错误、边界、越权、停用、旧新密码登录、主管回归、离线和敏感值检查的可执行测试设计。
+- 不做项:不执行Gate A或业务测试,不创建真实账号,不修改文件、代码、数据、Git状态、部署或运行态。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED、用例矩阵、环境和虚构样本前置、自动化入口、复位/证据规则和下一责任人。
+- 敏感边界:只允许虚构账号和占位密码,不使用生产数据,不记录真实凭据、原始日志或完整请求响应。
+- 队列编号:QUEUE-20260717-027
+- 下一责任人:测试与质量处理已锁定QUEUE-027
+
+## COLLAB-20260717-075 | 员工修改密码MVP测试环境运维Gate R方案评审
+
+- 事件类型:Gate请求
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:运维与发布
+- 上游事件:COLLAB-20260717-068
+- 结果事件:COLLAB-20260717-083
+- 当前Gate:CRM-20260717-006 / Gate R
+- 状态:CLOSED
+- 目标:冻结R-08至R-10的隔离测试环境身份、HTTPS、配置边界、虚构数据备份/复位、部署检查和回滚方案。
+- 输入:[需求与验收](<./202607/0717-员工修改密码/00-需求与验收.md>)、[Gate R统一清单](<./202607/0717-员工修改密码/01-计划改动清单.md>)、COLLAB-20260717-060、061、065及非敏感环境说明。
+- 范围:只读编制测试环境机械方案和停止线;明确不接触生产账号、生产客户数据或正式线上环境。
+- 不做项:不连接服务器,不执行部署、备份或回滚,不修改代码、数据、配置、Git状态或运行态,不代签Gate D。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED、环境识别、HTTPS、配置注入、虚构数据复位、部署/回滚步骤、证据和责任人。
+- 敏感边界:正式文档只记录敏感材料位置和脱敏结论,不写密码、Token、私钥、Cookie、客户数据或原始日志。
+- 队列编号:QUEUE-20260717-028
+- 下一责任人:运维与发布处理已锁定QUEUE-028
+
+## COLLAB-20260717-076 | 模块化单体与MySQL渐进迁移架构方案结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:架构与数据治理
+- 目标角色:Owner/产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-056
+- 结果事件:无
+- 当前Gate:CRM-20260717-003 / Gate N、Gate R架构技术结论
+- 状态:PASS
+- 目标:回传模块化单体、MySQL、本地环境、多客户端API和渐进迁移方案。
+- 输入:Owner确认的MySQL、渐进迁移、本地优先和未来移动端方向,以及CRM-003任务材料。
+- 范围:仅形成架构、环境、移动端职责和任务文档;未读取运行数据,未修改业务代码、配置、数据、部署或运行态。
+- 不做项:未代签跨角色Gate R或Gate P,未实施模块拆分、数据库迁移、移动客户端或生产部署。
+- 验收:架构角色结论PASS;目标采用Vue 3、Fastify、TypeScript、npm workspaces、MySQL 8.x、OpenAPI 3.1和`/api/v1`,按模块单一写入源渐进迁移,首条链路为登录—客户分页/详情—新增跟进—动作时间线。
+- 敏感边界:未读取或输出真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 证据:Codex Thread `019f6f85-bee8-7f70-8d0a-af638ece0782`,turn `019f6fac-a828-72b1-a54e-05981be72e97`;架构会话自检13份文档PASS。
+- 风险与未决:BLOCK-001至003继续有效;缺少脱敏数据字典;MySQL小版本和迁移/查询库待薄型样例冻结;移动平台、离线、推送和分发范围待Owner确认。
+- 队列编号:QUEUE-20260717-018
+- 下一责任人:项目管理员释放架构锁并优先投递CRM-006 Gate R;之后调度CRM-003跨角色复核和产品Gate P
+
+## COLLAB-20260717-077 | 员工修改密码MVP架构Gate R方案评审结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:架构与数据治理
+- 目标角色:产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-069
+- 结果事件:无
+- 当前Gate:CRM-20260717-006 / Gate R架构分项
+- 状态:PASS
+- 目标:回传本人改密统一接口、身份、原子性、并发、重新认证和回滚语义。
+- 输入:COLLAB-20260717-069指定材料和QUEUE-20260717-022。
+- 范围:只读冻结架构职责域方案;不代签其他专业或整体Gate R。
+- 不做项:未修改文件、代码、配置、数据、Git状态、部署或运行态;未处理延期能力。
+- 验收:覆盖专用接口、认证身份、停用状态、账号级临界区、并发冲突、主管兼容、重新认证、错误和测试停止线。
+- 敏感边界:未读取或输出真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 结论:PASS。建议采用`POST /api/v1/me/password/change`、请求体仅含当前密码和新密码、成功`204`;账号只取后端认证上下文,同账号写入串行化,成功后重新认证。
+- 未完成项:与后端分项在接口路径、确认字段、成功状态及错误码命名上存在差异,须形成唯一契约后再允许前端与测试复评。
+- 证据:Codex Thread `019f6f85-bee8-7f70-8d0a-af638ece0782`,turn `019f6fe8-6a47-7990-bd4e-8f27c5d1ec1d`。
+- 队列编号:QUEUE-20260717-022
+- 下一责任人:产品与项目管理组织唯一契约收敛
+
+## COLLAB-20260717-078 | 员工修改密码MVP交互Gate R方案评审结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:UI与交互设计
+- 目标角色:产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-070
+- 结果事件:无
+- 当前Gate:CRM-20260717-006 / Gate R交互分项
+- 状态:PASS
+- 目标:回传顶部入口、三字段对话框、移动端、状态、焦点和无障碍规格。
+- 输入:COLLAB-20260717-070指定材料和QUEUE-20260717-023。
+- 范围:只读冻结R-06、R-07交互规格。
+- 不做项:未修改设计稿、页面、代码、数据、配置、Git状态、部署或运行态。
+- 验收:覆盖入口、字段、取消、提交中、校验、成功退出、错误映射、360像素移动端、键盘和辅助技术。
+- 敏感边界:密码字段不预填、回显或持久化;未使用真实账号、密码或客户数据。
+- 结论:PASS。确认密码仅用于前端一致性校验;明确成功后清理表单和当前登录、返回登录页并显示一次性安全提示。
+- 未完成项:具体机器错误码须与唯一接口契约映射;实现、浏览器测试和后续Gate未执行。
+- 证据:Codex Thread `019f6fa9-44a2-7313-892d-886b43af1be9`,turn `019f6fe8-7300-7391-ad78-a369704a485e`。
+- 队列编号:QUEUE-20260717-023
+- 下一责任人:产品与项目管理汇总Gate R
+
+## COLLAB-20260717-079 | 员工修改密码MVP前端Gate R方案评审结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:前端开发
+- 目标角色:产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-071
+- 结果事件:COLLAB-20260717-093
+- 当前Gate:CRM-20260717-006 / Gate R前端分项
+- 状态:CHANGES_REQUESTED
+- 目标:回传前端承载点、请求状态机、错误映射、登录清理和自测方案。
+- 输入:COLLAB-20260717-071指定材料和QUEUE-20260717-024。
+- 范围:只读评审前端最小方案。
+- 不做项:未修改前后端代码、数据、配置、Git状态、部署或运行态。
+- 验收:前端影响面和自测矩阵已形成,但跨角色契约尚未唯一冻结。
+- 敏感边界:未读取或输出真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 结论:CHANGES_REQUESTED。接口路径、字段、Unicode字符计数、成功响应、稳定错误码和UI规格必须形成共同冻结版本后才能PASS。
+- 未完成项:等待架构与后端收敛唯一契约;随后在同一QUEUE-024复评,不另开实现任务。
+- 证据:Codex Thread `019f6ea8-7abd-7ca2-8b6c-8e3e54cfd8b1`,turn `019f6fe8-7a89-7931-8a06-ba56b91131b0`。
+- 队列编号:QUEUE-20260717-024
+- 下一责任人:产品与项目管理/架构/后端完成契约收敛
+
+## COLLAB-20260717-080 | 员工修改密码MVP后端Gate R方案评审结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:后端开发
+- 目标角色:产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-072
+- 结果事件:无
+- 当前Gate:CRM-20260717-006 / Gate R后端分项
+- 状态:PASS
+- 目标:回传接口、身份、账号状态、校验、原子持久化、并发、重新认证、回滚和自测方案。
+- 输入:COLLAB-20260717-072指定材料和QUEUE-20260717-025。
+- 范围:只读冻结后端职责域方案;不代签整体Gate R。
+- 不做项:未修改代码、配置、数据、Git状态、部署或运行态;未执行真实账号或密码迁移。
+- 验收:覆盖请求字段、Unicode码点计数、账号身份、CAS/原子替换、并发写入、主管兼容、错误码和后端自测矩阵。
+- 敏感边界:未读取或输出真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 结论:PASS。建议采用`POST /api/account/change-password`、三字段请求和成功`200`;账号从认证上下文确定,单写实例使用统一修订号/CAS入口。
+- 未完成项:与架构分项在接口路径、确认字段、成功状态及错误码命名上存在差异,必须收敛后再作为实现输入。
+- 证据:Codex Thread `019f6ea8-9633-7a82-9034-789ecc7888da`,turn `019f6fe8-8865-7162-8f90-745183dd3c34`。
+- 队列编号:QUEUE-20260717-025
+- 下一责任人:产品与项目管理组织唯一契约收敛
+
+## COLLAB-20260717-081 | 员工修改密码MVP安全Gate R方案评审结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:代码审核与安全
+- 目标角色:产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-073
+- 结果事件:无
+- 当前Gate:CRM-20260717-006 / Gate R安全分项
+- 状态:PASS
+- 目标:回传最低安全边界、停止线和未来Gate C证据要求。
+- 输入:COLLAB-20260717-073指定材料和QUEUE-20260717-026。
+- 范围:只读冻结本人身份、停用账号、敏感值、故障关闭、HTTPS、延期风险和Gate C证据边界。
+- 不做项:未执行Gate C,未修改代码、数据、配置、Git状态、部署或运行态,未解除No-Go。
+- 验收:覆盖越权、停用、当前密码、并发、错误脱敏、敏感值、离线失败关闭、主管兼容和精确基线证据。
+- 敏感边界:未读取或记录真实密码、密码散列、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 结论:PASS。专业安全边界可冻结;事件标题复核为76/76唯一,评审期间的重复判断属于并发更新快照,不形成持续阻塞。
+- 未完成项:整体Gate R、实现和Gate C/D/A/P未完成;延期安全项和BLOCK-001至003继续有效。
+- 证据:Codex Thread `019f6ea8-b081-7121-9d98-4c9714bf50e1`,turn `019f6fe8-9559-70b3-808e-880842987f0f`;事件标题唯一性复核76个、重复0。
+- 队列编号:QUEUE-20260717-026
+- 下一责任人:产品与项目管理汇总Gate R
+
+## COLLAB-20260717-082 | 员工修改密码MVP测试Gate R方案评审结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:测试与质量
+- 目标角色:产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-074
+- 结果事件:COLLAB-20260717-096
+- 当前Gate:CRM-20260717-006 / Gate R测试分项
+- 状态:CHANGES_REQUESTED
+- 目标:回传十项验收矩阵、虚构样本、环境、自动化、复位和脱敏证据要求。
+- 输入:COLLAB-20260717-074指定材料和QUEUE-20260717-027。
+- 范围:只读评审测试方案,不执行Gate A。
+- 不做项:未执行测试、创建真实账号或修改文件、代码、数据、Git状态、部署、运行态。
+- 验收:十项场景矩阵已形成,但唯一接口/错误/并发契约和可重复自动化入口未冻结。
+- 敏感边界:只使用虚构账号和占位密码,未读取或输出真实凭据、客户数据、原始日志或完整请求响应。
+- 结论:CHANGES_REQUESTED。需先收敛接口字段、错误码、并发语义、环境复位步骤和自动化命令;事件标题当前76/76唯一,重复0,不再作为持续问题。
+- 未完成项:等待唯一契约、运维方案和可执行测试入口形成后,在同一QUEUE-027复评。
+- 证据:Codex Thread `019f6ea8-ca49-7472-9a9e-24848071c22b`,turn `019f6fe8-9e71-7251-9f5b-1952862f8a96`;事件标题唯一性复核76个、重复0。
+- 队列编号:QUEUE-20260717-027
+- 下一责任人:产品与项目管理/架构/后端先收敛唯一契约
+
+## COLLAB-20260717-083 | 员工修改密码MVP测试环境运维Gate R方案评审结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:运维与发布
+- 目标角色:产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-075
+- 结果事件:无
+- 当前Gate:CRM-20260717-006 / Gate R运维分项
+- 状态:PASS
+- 目标:回传隔离测试环境身份、HTTPS、配置、虚构数据复位、部署检查和回滚方案。
+- 输入:COLLAB-20260717-075指定材料和QUEUE-20260717-028。
+- 范围:只读冻结测试环境机械方案;不执行部署。
+- 不做项:未连接服务器,未执行部署、备份或回滚,未修改代码、数据、配置、Git状态或运行态。
+- 验收:覆盖test环境标识、独立身份/配置/数据路径、HTTPS、非root、精确基线、虚构数据快照、回滚和分角色证据。
+- 敏感边界:未记录密码、Token、私钥、Cookie、客户数据、原始日志或完整请求响应。
+- 结论:PASS。仅允许隔离测试环境;现有root、HTTP、`0.0.0.0`和备份不足的Linux状态不能直接作为合格测试环境。
+- 未完成项:实际测试环境、证书、非root账号、构建基线、虚构模板、复位工具和演练证据未形成;未执行Gate D/A。
+- 证据:Codex Thread `019f6ea8-ec46-70d2-9122-0968c7946c23`,turn `019f6fe8-a93e-7f83-af6e-a80845638b36`。
+- 队列编号:QUEUE-20260717-028
+- 下一责任人:产品与项目管理汇总Gate R
+
+## COLLAB-20260717-084 | 员工修改密码MVP Gate R首轮汇总
+
+- 事件类型:Gate汇总请求
+- 发起时间:2026-07-17
+- 发起角色:项目管理员
+- 目标角色:产品与项目管理
+- 上游事件:COLLAB-20260717-077至083
+- 结果事件:COLLAB-20260717-085
+- 当前Gate:CRM-20260717-006 / Gate R首轮汇总
+- 状态:CLOSED
+- 目标:汇总七角色Gate R首轮结果,识别跨角色契约冲突并建立最小整改顺序。
+- 输入:架构、UI、前端、后端、安全、测试和运维结果COLLAB-20260717-077至083。
+- 范围:只维护CRM-006方案事实源、冲突清单、Gate状态和下一责任人;不替专业角色选择技术契约。
+- 不做项:不修改业务代码、运行数据、配置、Git历史、部署或运行态;不处理CRM-003;不把分项PASS写成整体Gate R PASS。
+- 验收:逐角色结论完整;接口路径、字段、成功响应和错误码差异明确;事件标题唯一性事实澄清;前端与测试保持原队列WAITING;下一整改角色唯一。
+- 敏感边界:不读取、记录或输出真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 队列编号:QUEUE-20260717-029
+- 下一责任人:产品与项目管理
+
+## COLLAB-20260717-085 | 员工修改密码MVP Gate R首轮汇总结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:Owner/项目管理员
+- 上游事件:COLLAB-20260717-084
+- 结果事件:COLLAB-20260717-086
+- 当前Gate:CRM-20260717-006 / Gate R首轮汇总
+- 状态:CHANGES_REQUESTED
+- 目标:回传七角色首轮结论、跨角色契约冲突和最小整改顺序。
+- 输入:COLLAB-20260717-077至083及R-01至R-11统一清单。
+- 范围:仅汇总专业结论和维护CRM-006方案事实源。
+- 不做项:未修改业务代码、运行数据、配置、Git历史、部署或运行态;未处理CRM-003;未代签专业方案。
+- 验收:七角色结论完整;5项PASS、2项CHANGES_REQUESTED;五类契约差异明确;前端和测试保持原队列WAITING;事件标题唯一性已复核。
+- 敏感边界:未读取、记录或输出真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 结论:CHANGES_REQUESTED。架构、UI、后端、安全、运维PASS;前端、测试待整改。整体Gate R尚未通过,业务实现保持0%。
+- 整改顺序:架构先形成唯一接口契约,后端确认可实施,再恢复前端QUEUE-024和测试QUEUE-027复评,最后由产品汇总。
+- 事实源复核:协作事件标题76个、唯一76个、重复0;并发读取期间的重复快照不再构成阻塞。
+- 未完成项:唯一契约、后端确认、前端/测试复评、整体Gate R、实现及Gate C/D/A/P均未完成。
+- 队列编号:QUEUE-20260717-029
+- 下一责任人:项目管理员投递COLLAB-20260717-086给架构与数据治理
+
+## COLLAB-20260717-086 | 员工修改密码MVP唯一接口契约收敛
+
+- 事件类型:Gate R整改请求
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:架构与数据治理
+- 上游事件:COLLAB-20260717-077、079、080、082、085
+- 结果事件:COLLAB-20260717-087
+- 当前Gate:CRM-20260717-006 / Gate R整改
+- 状态:CLOSED
+- 目标:以架构契约Owner身份对架构、UI、前端、后端和测试意见形成唯一可实施接口契约,关闭跨角色分歧。
+- 输入:[Gate R统一清单与首轮冲突](<./202607/0717-员工修改密码/01-计划改动清单.md>)、架构结果COLLAB-077、UI结果078、前端结果079、后端结果080、测试结果082及首轮汇总085。
+- 范围:只读冻结五项唯一结论:接口路径/方法、请求字段与确认密码归属、成功HTTP响应、稳定错误码、Unicode字符计数;同时确认认证身份、原子并发和重新认证共同事实不变。
+- 不做项:不修改业务代码、数据、配置、Git状态、部署或运行态;不扩展延期安全能力或模块化重构;不代替后端确认可实施性。
+- 验收:只输出一个无备选项的完整契约;逐项说明采用结论及兼容理由;错误码能唯一映射UI状态和测试矩阵;明确后端确认、前端/测试复评输入。
+- 敏感边界:示例不得包含真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 队列编号:QUEUE-20260717-030
+- 下一责任人:架构与数据治理处理已锁定QUEUE-030
+
+## COLLAB-20260717-087 | 员工修改密码MVP唯一接口契约收敛结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:架构与数据治理
+- 目标角色:产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-086
+- 结果事件:无
+- 当前Gate:CRM-20260717-006 / Gate R整改
+- 状态:PASS
+- 目标:回传无备选的v0.4唯一接口契约并关闭首轮跨角色分歧。
+- 输入:COLLAB-20260717-077、078、079、080、082、085和R-01至R-11冲突清单。
+- 范围:只读冻结接口路径、字段、字符计数、成功响应、错误码和共同语义。
+- 不做项:未修改业务代码、数据、配置、Git状态、部署或运行态;未代替后端确认可实施性;未处理其他任务。
+- 验收:一个无备选的契约;逐项裁决五类分歧;错误码唯一映射UI与测试;明确后端、前端和测试复评输入。
+- 敏感边界:未读取或输出真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 结论:PASS。唯一接口为`POST /api/v1/me/password/change`;严格请求体仅含当前密码和新密码;确认密码只在前端;Unicode码点计数且不裁剪/规范化;成功`204 No Content`并`Cache-Control: no-store`。
+- 稳定错误:`INVALID_REQUEST`、`AUTHENTICATION_REQUIRED`、`ACCOUNT_DISABLED`、`CURRENT_PASSWORD_INCORRECT`、`PASSWORD_LENGTH_INVALID`、`NEW_PASSWORD_SAME_AS_CURRENT`、`PASSWORD_UPDATE_CONFLICT`、`PASSWORD_CHANGE_UNAVAILABLE`、`INTERNAL_ERROR`。
+- 共同语义:账号只取认证上下文;停用拒绝;本人改密、主管重置和停用共享账号级写入原语与CAS;失败不落盘;成功后当前认证失效;完整多设备会话撤销延期。
+- 未完成项:产品写入唯一事实源、后端确认单写实例可实施、前端QUEUE-024和测试QUEUE-027复评、整体Gate R汇总。
+- 证据:Codex Thread `019f6f85-bee8-7f70-8d0a-af638ece0782`,turn `019f7002-004a-74a0-9776-c51b6ce6d07d`。
+- 队列编号:QUEUE-20260717-030
+- 下一责任人:产品与项目管理同步v0.4契约事实源
+
+## COLLAB-20260717-088 | 员工修改密码MVP v0.4契约事实源同步
+
+- 事件类型:方案事实源同步请求
+- 发起时间:2026-07-17
+- 发起角色:项目管理员
+- 目标角色:产品与项目管理
+- 上游事件:COLLAB-20260717-087
+- 结果事件:COLLAB-20260717-089
+- 当前Gate:CRM-20260717-006 / Gate R整改
+- 状态:CLOSED
+- 目标:把架构PASS的v0.4唯一接口契约写入CRM-006方案事实源,作为后端确认和前端/测试复评的唯一输入。
+- 输入:COLLAB-20260717-087、首轮冲突清单及R-01至R-11统一清单。
+- 范围:仅更新CRM-006计划、自测、验收、结论和台账中的方案状态。
+- 不做项:不修改业务代码、数据、配置、Git历史、部署或运行态;不替后端签可实施性;不恢复前端或测试队列。
+- 验收:接口路径、字段、字符、响应、错误码、校验顺序和共同语义形成唯一文本;旧备选明确废止;下一责任人为后端确认。
+- 敏感边界:不记录真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 队列编号:QUEUE-20260717-031
+- 下一责任人:产品与项目管理
+
+## COLLAB-20260717-089 | 员工修改密码MVP v0.4契约事实源同步结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:Owner/项目管理员
+- 上游事件:COLLAB-20260717-088
+- 结果事件:COLLAB-20260717-090
+- 当前Gate:CRM-20260717-006 / Gate R整改
+- 状态:PASS
+- 目标:回传v0.4唯一契约的事实源同步结果和下一复评入口。
+- 输入:COLLAB-20260717-087及CRM-006 Gate R首轮冲突清单。
+- 范围:仅同步CRM-006任务目录和统一计划台账。
+- 不做项:未修改业务代码、数据、配置、Git历史、部署或运行态;未替后端签可实施性;未恢复前端或测试队列。
+- 验收:唯一接口、字段、字符、响应、错误码、校验顺序、原子并发和废止备选均已记录;下一责任人为后端确认。
+- 敏感边界:未记录真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 结论:PASS。v0.4成为后端确认、前端QUEUE-024和测试QUEUE-027复评的唯一输入;整体Gate R仍为CHANGES_REQUESTED。
+- 未完成项:后端可实施确认、前端和测试复评、整体Gate R汇总、实现及Gate C/D/A/P。
+- 队列编号:QUEUE-20260717-031
+- 下一责任人:项目管理员投递COLLAB-20260717-090给后端开发
+
+## COLLAB-20260717-090 | 员工修改密码MVP v0.4后端可实施确认
+
+- 事件类型:Gate R整改复评请求
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:后端开发
+- 上游事件:COLLAB-20260717-087、089
+- 结果事件:COLLAB-20260717-092
+- 当前Gate:CRM-20260717-006 / Gate R整改
+- 状态:CLOSED
+- 目标:确认v0.4唯一接口契约在当前单进程、单写实例后端中可实施,不再提出备选契约。
+- 输入:[Gate R v0.4唯一契约](<./202607/0717-员工修改密码/01-计划改动清单.md>)、架构结果COLLAB-087和事实源同步结果COLLAB-089。
+- 范围:只读确认唯一路径、两字段Schema、Unicode码点、204空响应、九个错误码、校验顺序、账号级写入原语/CAS、主管兼容和自测入口。
+- 不做项:不修改业务代码、数据、配置、Git状态、部署或运行态;不重新提出旧路径、三字段、成功200或旧错误码命名;不处理其他任务。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED;逐项确认v0.4可实施性、当前代码所需最小改动边界、单写实例限制、自测与停止线;明确能否作为前端和测试复评输入。
+- 敏感边界:不读取或输出真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 队列编号:QUEUE-20260717-032
+- 下一责任人:后端新正式会话在完成历史交接后恢复已锁定QUEUE-032
+
+## COLLAB-20260717-091 | 后端正式会话故障迁移与历史交接
+
+- 事件类型:会话修复请求
+- 发起时间:2026-07-17
+- 发起角色:Owner/项目管理员
+- 目标角色:后端开发
+- 上游事件:COLLAB-20260717-090;旧正式后端会话连续两次投递未产生turn并返回`no active turn to steer`
+- 结果事件:COLLAB-20260717-092
+- 当前Gate:CRM-20260717-008 / 会话故障迁移;保持CRM-006 Gate R整改锁
+- 状态:CLOSED
+- 目标:创建可用的后端正式会话,完整回读旧后端会话历史,并从最后检查点恢复同一QUEUE-032。
+- 输入:[会话故障迁移与交接规范](<../研发体系/会话故障迁移与交接规范.md>)、旧Thread `019f6ea8-9633-7a82-9034-789ecc7888da`、COLLAB-090、后端角色队列和v0.4唯一契约。
+- 范围:完整分页回读旧会话全部turn,提取脱敏决策、方案取舍、已完成/未完成项、队列、风险和恢复点;随后只读完成QUEUE-032可实施性确认。
+- 不做项:不修改业务代码、数据、配置、Git状态、部署或运行态;交接PASS前不归档旧会话;不创建第二套职责或新业务队列。
+- 验收:新会话按标准交接回执PASS;QUEUE-032编号和锁保持;后端职责、WIP=1、禁止抢占和停止线无遗漏;完成一次接管turn和v0.4确认。
+- 敏感边界:不得复制原始聊天、真实密码、Token、账号明细、客户数据、原始日志或完整请求响应,只记录脱敏摘要和Thread/turn ID。
+- 队列编号:QUEUE-20260717-032
+- 下一责任人:项目管理员切换正式ID并归档旧后端会话
+
+## COLLAB-20260717-092 | 后端正式会话交接与v0.4可实施确认结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:后端开发/项目管理员
+- 目标角色:Owner/产品与项目管理/前端开发/测试与质量
+- 上游事件:COLLAB-20260717-090、091
+- 结果事件:无
+- 当前Gate:CRM-20260717-008 / 会话交接验收;CRM-20260717-006 / Gate R整改
+- 状态:PASS
+- 目标:回传旧后端历史完整交接、同一QUEUE-032恢复和v0.4后端可实施性确认。
+- 输入:旧Thread `019f6ea8-9633-7a82-9034-789ecc7888da`、新Thread `019f7014-60d2-7972-ba52-46d834fe49f2`、COLLAB-087、089、090、091及v0.4唯一契约。
+- 范围:完整分页回读旧会话并只读核对当前后端源码结构;确认接口、认证、校验、原子并发、主管兼容、自测和单写实例停止线。
+- 不做项:未修改文件、业务代码、数据、配置、Git状态、部署或运行态;未执行测试;未处理其他任务或代签整体Gate R。
+- 验收:旧会话5个已完成turn全部读到`hasMore=false`;无中断turn和未记录修改;原QUEUE-032保持并从最后检查点完成;v0.4全部项目可实施。
+- 敏感边界:只记录脱敏摘要和Thread/turn ID,未复制原始聊天、真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 结论:PASS。新正式后端会话完整继承旧历史;唯一路径、两字段、Unicode码点、204/no-store、九个错误码、固定校验顺序、账号锁/CAS、主管兼容和单进程单写实例均可实施。
+- 最小改动边界:实现阶段需增加专用路由和严格Schema、仅认证头的专用认证入口、账号级锁与真实CAS、204空响应、稳定错误封装,并让主管重置和停用接入统一写入原语。
+- 证据:新Thread `019f7014-60d2-7972-ba52-46d834fe49f2`,交接与确认turn `019f7014-75d5-7680-86cd-65dcbccf9394`;旧Thread共5个已完成turn。
+- 未完成项:前端QUEUE-024最终复评、整体Gate R汇总、业务实现、自测、Gate C/D/A/P、隔离测试环境和延期安全项。
+- 队列编号:QUEUE-20260717-032
+- 下一责任人:项目管理员完成入口切换和旧会话归档;随后恢复前端QUEUE-024最终复评
+
+## COLLAB-20260717-093 | 员工修改密码MVP前端Gate R同项复评
+
+- 事件类型:Gate R整改复评请求
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理/项目管理员
+- 目标角色:前端开发
+- 上游事件:COLLAB-20260717-079、087、089、092
+- 结果事件:COLLAB-20260717-095
+- 当前Gate:CRM-20260717-006 / Gate R整改复评
+- 状态:CLOSED
+- 目标:在架构唯一契约和后端可实施性均PASS后,关闭前端首轮契约、字符、响应、错误码和交互阻塞。
+- 输入:[Gate R v0.4唯一契约](<./202607/0717-员工修改密码/01-计划改动清单.md>)、架构结果COLLAB-087、后端结果COLLAB-092、UI结果COLLAB-078及前端首轮结果COLLAB-079。
+- 范围:只读复评页面承载、两字段请求、确认密码本地校验、Unicode码点、204响应、错误映射、请求状态机、成功清理登录、移动端和实现期自测入口。
+- 不做项:不修改文件、业务代码、配置、数据、Git状态、部署或运行态;不顺手重构单文件页面;不创建新队列项。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED、首轮问题逐项关闭、实现最小边界、自测和停止线;确认是否可作为整体Gate R输入。
+- 敏感边界:密码只短暂存在内存和专用请求体,不进入URL、查询参数、响应、日志、文档或浏览器持久化。
+- 队列编号:QUEUE-20260717-024
+- 下一责任人:前端新正式会话在完成历史交接后恢复同一QUEUE-024
+
+## COLLAB-20260717-094 | 前端正式会话故障迁移与历史交接
+
+- 事件类型:会话修复请求
+- 发起时间:2026-07-17
+- 发起角色:Owner/项目管理员
+- 目标角色:前端开发
+- 上游事件:COLLAB-20260717-093;旧正式前端会话连续两次投递均未产生turn并返回`agent loop died unexpectedly`
+- 结果事件:COLLAB-20260717-095
+- 当前Gate:CRM-20260717-008 / 会话故障迁移;保持CRM-006 Gate R整改复评锁
+- 状态:CLOSED
+- 目标:创建可用的前端正式会话,完整回读旧前端历史,并从最后检查点恢复同一QUEUE-024。
+- 输入:[会话故障迁移与交接规范](<../研发体系/会话故障迁移与交接规范.md>)、旧Thread `019f6ea8-7abd-7ca2-8b6c-8e3e54cfd8b1`、COLLAB-093、前端角色队列和v0.4唯一契约。
+- 范围:完整分页回读旧会话全部turn,提取脱敏决策、方案取舍、已完成/未完成项、队列、风险和恢复点;随后只读完成QUEUE-024最终复评。
+- 不做项:不修改业务代码、文件、数据、配置、Git状态、部署或运行态;交接PASS前不归档旧会话;不创建第二套职责或新业务队列。
+- 验收:新会话按标准交接回执PASS;QUEUE-024编号和锁保持;前端职责、WIP=1、禁止抢占和停止线无遗漏;完成一次接管turn和v0.4复评。
+- 敏感边界:不得复制原始聊天、真实密码、Token、账号明细、客户数据、原始日志或完整请求响应,只记录脱敏摘要和Thread/turn ID。
+- 队列编号:QUEUE-20260717-024
+- 下一责任人:项目管理员切换正式ID并归档旧前端会话
+
+## COLLAB-20260717-095 | 前端正式会话交接与Gate R复评结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:前端开发/项目管理员
+- 目标角色:Owner/产品与项目管理/测试与质量
+- 上游事件:COLLAB-20260717-093、094
+- 结果事件:无
+- 当前Gate:CRM-20260717-008 / 会话交接验收;CRM-20260717-006 / Gate R整改复评
+- 状态:PASS
+- 目标:回传旧前端历史完整交接、同一QUEUE-024恢复和v0.4前端分项复评。
+- 输入:旧Thread `019f6ea8-7abd-7ca2-8b6c-8e3e54cfd8b1`、新Thread `019f702e-eb7e-70d3-8271-06269945435a`、COLLAB-078、079、087、092、093、094及v0.4唯一契约。
+- 范围:完整分页回读旧会话并只读核对页面承载、两字段请求、Unicode码点、204响应、错误映射、状态机、成功清理、移动端和自测入口。
+- 不做项:未修改文件、业务代码、配置、数据、Git状态、部署或运行态;未运行测试;未重构巨型单文件或代签整体Gate R。
+- 验收:旧会话6个已完成turn全部读到`hasMore=false`;无中断turn和未记录修改;原QUEUE-024保持并从首轮CHANGES恢复;五类契约缺口全部关闭。
+- 敏感边界:只记录脱敏摘要和Thread/turn ID,未复制原始聊天、真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 结论:PASS。唯一接口、两字段、确认字段归属、Unicode码点、204/no-store、九个错误码、UI和计划自测入口均可作为整体Gate R输入。
+- 最小改动边界:实现阶段仅修改`outputs/sales_crm_full_demo.html`顶部账号区、改密模态框、专用请求函数、样式和状态;现有通用`api()`会解析JSON并离线回退,不得用于改密;不执行单文件重构。
+- 证据:新Thread `019f702e-eb7e-70d3-8271-06269945435a`,交接与复评turn `019f702f-0141-7031-a24b-5208b2bb918b`;旧Thread共6个已完成turn。
+- 未完成项:测试QUEUE-027最终落账、整体Gate R产品汇总、业务实现、自测、Gate C/D/A/P、隔离测试环境和延期安全项。
+- 队列编号:QUEUE-20260717-024
+- 下一责任人:项目管理员完成入口切换和旧会话归档;随后完成测试QUEUE-027最终复评落账
+
+## COLLAB-20260717-096 | 员工修改密码MVP测试Gate R同项复评结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:测试与质量
+- 目标角色:产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-082、087、089
+- 结果事件:无
+- 当前Gate:CRM-20260717-006 / Gate R整改复评
+- 状态:PASS
+- 目标:回传事件唯一性修复和v0.4十项验收矩阵最终可执行性复评。
+- 输入:COLLAB-074、082、v0.4唯一契约、隔离环境方案、计划自动化入口和同一QUEUE-027。
+- 范围:只读复核事件编号、接口、规则、错误、并发、环境复位、五个计划命令、脱敏证据和十项验收映射。
+- 不做项:未执行Gate A、测试或账号创建,未修改文件、代码、数据、Git状态、部署或运行态。
+- 验收:事件标题唯一且重复0;接口、字符、错误码、CAS、隔离环境、快照复位和自动化入口满足Gate R设计层;十项矩阵10/10可执行。
+- 敏感边界:只使用虚构样本和脱敏证据规则,未读取或输出真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 结论:PASS。首轮问题全部关闭;架构COLLAB-087采用的v0.4与本次复评输入一致,后端COLLAB-092确认可实施,不需要改变测试结论。
+- 证据:Codex Thread `019f6ea8-ca49-7472-9a9e-24848071c22b`,复评turn `019f6ffc-339b-7932-9df1-45eabdfcdc07`。
+- 未完成项:五个npm测试入口、虚构样本、复位脚本和实际Gate A均属于实现/验证期;整体Gate R产品汇总、实现及Gate C/D/A/P未完成。
+- 队列编号:QUEUE-20260717-027
+- 下一责任人:产品与项目管理执行整体Gate R汇总
+
+## COLLAB-20260717-097 | 员工修改密码MVP整体Gate R最终汇总
+
+- 事件类型:Gate汇总请求
+- 发起时间:2026-07-17
+- 发起角色:Owner/项目管理员
+- 目标角色:产品与项目管理
+- 上游事件:COLLAB-077、078、080、081、083、087、089、092、095、096
+- 结果事件:COLLAB-20260717-098
+- 当前Gate:CRM-20260717-006 / Gate R最终汇总
+- 状态:CLOSED
+- 目标:在七个专业分项、唯一契约、后端确认、前端和测试复评均PASS后,判断Gate R整体结论并冻结实现入口条件。
+- 输入:v0.4唯一契约、R-01至R-11、七角色结果、会话交接结果和CRM-006任务事实源。
+- 范围:只读汇总范围一致性、契约唯一性、角色结论、延期项、停止线、实现最小边界、Gate C输入和下一责任人。
+- 不做项:不修改业务代码、数据、配置、Git状态、部署或运行态;不执行实现、Gate C/D/A/P;不解除项目No-Go或授权正式生产。
+- 验收:全部适用专业结论PASS;旧备选明确废止;实现范围、精确基线、自测、隔离环境和停止线无歧义;回传PASS/CHANGES_REQUESTED/BLOCKED。
+- 敏感边界:只使用脱敏结论,不读取或输出真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 队列编号:QUEUE-20260717-033
+- 下一责任人:项目管理员登记Gate R结果;实现仍需新的明确授权和精确队列
+
+## COLLAB-20260717-098 | 员工修改密码MVP整体Gate R最终汇总结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:产品与项目管理
+- 目标角色:Owner/项目管理员
+- 上游事件:COLLAB-20260717-097
+- 结果事件:无
+- 当前Gate:CRM-20260717-006 / Gate R最终汇总
+- 状态:PASS
+- 目标:回传七个专业分项、v0.4唯一契约和同队列复评的整体汇总结论。
+- 输入:COLLAB-077、078、080、081、083、087、089、092、095、096及R-01至R-11。
+- 范围:只读汇总范围一致性、契约唯一性、角色结论、实现边界、延期项、停止线和后续Gate输入。
+- 不做项:未修改业务代码、数据、配置、Git状态、部署或运行态;未执行实现、测试或Gate C/D/A/P;未解除项目No-Go。
+- 验收:七个专业角色最终均PASS;v0.4契约唯一;R-01至R-11无未决分歧;前后端边界、自测、隔离环境和停止线明确。
+- 敏感边界:仅使用脱敏结论,未读取或输出真实密码、Token、账号明细、客户数据、原始日志或完整请求响应。
+- 结论:PASS。只代表CRM-006具备建立精确实现任务的方案前置条件;功能实现进度仍为0%,未测试、未部署、不可上线。
+- 冻结范围:本人改密最小闭环、v0.4唯一接口、UI状态机、账号级原子/CAS、主管兼容、十项矩阵及仅限隔离测试环境的复位/回滚方案。
+- 风险与停止线:BLOCK-001至003和正式生产No-Go继续有效;越权、停用账号可改、错误当前密码仍写入、并发多成功、离线假成功、敏感值泄露、复位失败或多写入实例均须停止。
+- 证据:产品Thread `019f6ea8-234e-7450-80fd-edc7c8c5438b`,汇总turn `019f6fca-52d4-7b20-8211-94375f5e575d`;七角色结果及迁移证据见上游事件。
+- 未完成项:业务实现、计划npm测试入口、虚构样本/复位脚本、精确实现基线、Gate C/D/A/P、隔离测试环境及延期安全能力。
+- 队列编号:QUEUE-20260717-033
+- 下一责任人:Owner/项目管理员在新的明确实现授权下另建实现事件和精确队列;当前不自动投递实现
+
+## COLLAB-20260717-099 | 模块化单体方案前端Gate R复核
+
+- 事件类型:Gate R只读复核请求
+- 发起时间:2026-07-17
+- 发起角色:项目管理员
+- 目标角色:前端开发
+- 上游事件:COLLAB-20260717-076
+- 结果事件:COLLAB-20260717-104
+- 当前Gate:CRM-20260717-003 / Gate R跨角色复核
+- 状态:CLOSED
+- 目标:确认目标前端目录、模块边界、共享契约、渐进迁移和Web/移动端职责边界可实施。
+- 输入:CRM-003任务目录、模块化单体目标架构、MySQL迁移方案、多客户端API契约和本地环境方案。
+- 范围:只读评审Vue 3/TypeScript/workspaces目标、旧单HTML渐进迁移、第一条纵向链路、API消费和前端测试边界。
+- 不做项:不修改文件、代码、数据、配置、Git状态、部署或运行态;不开始框架迁移或业务实现。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED、可实施性、最小前置、风险、停止线和第一实施任务建议。
+- 敏感边界:不读取或输出真实凭据、客户数据、原始日志、完整请求响应或运行数据。
+- 队列编号:QUEUE-20260717-034
+- 下一责任人:项目管理员登记COLLAB-104;前端按P0优先级转CRM-006最小实现
+
+## COLLAB-20260717-100 | 模块化单体方案后端Gate R复核
+
+- 事件类型:Gate R只读复核请求
+- 发起时间:2026-07-17
+- 发起角色:项目管理员
+- 目标角色:后端开发
+- 上游事件:COLLAB-20260717-076
+- 结果事件:COLLAB-20260717-105
+- 当前Gate:CRM-20260717-003 / Gate R跨角色复核
+- 状态:CLOSED
+- 目标:确认模块化单体、Fastify/TypeScript、MySQL和JSON渐进迁移方案在当前后端基线上可实施。
+- 输入:CRM-003任务目录、模块化单体目标架构、MySQL迁移方案、多客户端API契约和本地环境方案。
+- 范围:只读评审模块依赖、单一写入源、事务/迁移/回滚、`/api/v1`契约、认证边界和第一条纵向链路。
+- 不做项:不修改文件、代码、数据、配置、Git状态、部署或运行态;不安装MySQL,不执行迁移或业务实现。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED、可实施性、最小前置、风险、停止线和第一实施任务建议。
+- 敏感边界:不读取或输出真实凭据、客户数据、原始日志、完整请求响应或运行数据。
+- 队列编号:QUEUE-20260717-035
+- 下一责任人:项目管理员登记COLLAB-105;后端按P0优先级转CRM-006最小实现
+
+## COLLAB-20260717-101 | 模块化单体方案安全Gate R复核
+
+- 事件类型:Gate R设计安全复核请求
+- 发起时间:2026-07-17
+- 发起角色:项目管理员
+- 目标角色:代码审核与安全
+- 上游事件:COLLAB-20260717-076
+- 结果事件:COLLAB-20260717-106
+- 当前Gate:CRM-20260717-003 / Gate R跨角色复核
+- 状态:IN_PROGRESS
+- 目标:确认多客户端认证、权限强制、敏感配置、数据迁移和渐进切流的安全边界足以进入后续实现计划。
+- 输入:CRM-003任务目录、模块化单体目标架构、MySQL迁移方案、多客户端API契约和本地环境方案。
+- 范围:只读威胁审查Web Cookie、移动端短期令牌/轮换刷新令牌、后端授权、密钥边界、迁移与回滚停止线。
+- 不做项:不执行正式Gate C,不修改文件、代码、数据、配置、Git状态、部署或运行态;不解除BLOCK-001至003。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED、P0/P1风险、实现前安全前置、Gate C证据和停止线。
+- 敏感边界:不读取或输出真实凭据、客户数据、原始日志、完整请求响应或运行数据。
+- 队列编号:QUEUE-20260717-036
+- 下一责任人:代码审核与安全
+
+## COLLAB-20260717-102 | 模块化单体方案测试Gate R复核
+
+- 事件类型:Gate R可测试性复核请求
+- 发起时间:2026-07-17
+- 发起角色:项目管理员
+- 目标角色:测试与质量
+- 上游事件:COLLAB-20260717-076
+- 结果事件:COLLAB-20260717-107
+- 当前Gate:CRM-20260717-003 / Gate R跨角色复核
+- 状态:IN_PROGRESS
+- 目标:确认目标架构、MySQL迁移、API契约和渐进切流具有可执行的验证与回归边界。
+- 输入:CRM-003任务目录、模块化单体目标架构、MySQL迁移方案、多客户端API契约和本地环境方案。
+- 范围:只读评审契约/集成/E2E分层、虚构样本、迁移校验、快照恢复、首条纵向链路和Gate A前置。
+- 不做项:不执行业务Gate A,不修改文件、代码、数据、配置、Git状态、部署或运行态;不读取真实业务数据。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED、可测性、最小测试入口、风险、停止线和第一验证任务建议。
+- 敏感边界:不读取或输出真实凭据、客户数据、原始日志、完整请求响应或运行数据。
+- 队列编号:QUEUE-20260717-037
+- 下一责任人:测试与质量
+
+## COLLAB-20260717-103 | 模块化单体方案运维Gate R复核
+
+- 事件类型:Gate R本地环境与恢复复核请求
+- 发起时间:2026-07-17
+- 发起角色:项目管理员
+- 目标角色:运维与发布
+- 上游事件:COLLAB-20260717-076
+- 结果事件:COLLAB-20260717-108
+- 当前Gate:CRM-20260717-003 / Gate R跨角色复核
+- 状态:IN_PROGRESS
+- 目标:确认Windows本地MySQL主路径、配置隔离、备份恢复和渐进迁移回滚方案可机械执行。
+- 输入:CRM-003任务目录、模块化单体目标架构、MySQL迁移方案、多客户端API契约和本地环境方案。
+- 范围:只读评审本地前置、MySQL 8.x、配置与敏感值隔离、启动/健康检查、备份/恢复、单写切流和生产禁止边界。
+- 不做项:不执行Gate D,不安装软件,不修改文件、代码、数据、配置、Git状态、部署或运行态;不接触生产。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED、可操作性、环境前置、恢复检查、风险、停止线和第一环境任务建议。
+- 敏感边界:不读取或输出真实凭据、客户数据、原始日志、完整请求响应或运行数据。
+- 队列编号:QUEUE-20260717-038
+- 下一责任人:运维与发布
+
+## COLLAB-20260717-109 | 安全正式会话卡死迁移与同队列接管
+
+- 事件类型:会话故障迁移请求
+- 发起时间:2026-07-17
+- 发起角色:Owner/项目管理员
+- 目标角色:代码审核与安全
+- 上游事件:COLLAB-20260717-101;旧正式安全会话在同一只读检索节点连续多次检查无状态变化
+- 结果事件:COLLAB-20260717-110
+- 当前Gate:CRM-20260717-008 / 会话故障迁移;保持CRM-003 Gate R的QUEUE-036执行锁
+- 状态:IN_PROGRESS
+- 目标:创建可用的安全正式会话,完整回读旧安全会话历史,并从当前检查点恢复同一QUEUE-036,不丢失已形成的安全判断。
+- 输入:[会话故障迁移与交接规范](<../研发体系/会话故障迁移与交接规范.md>)、旧Thread `019f6ea8-b081-7121-9d98-4c9714bf50e1`、COLLAB-101、角色队列、旧活跃turn可见检查点和CRM-003方案材料。
+- 范围:完整分页回读旧会话全部已完成turn到`hasMore=false`,结合本次活跃turn已落账的队列、事件和脱敏检查点,恢复安全Gate R设计复核并给出结论。
+- 不做项:不打断或归档旧会话,不修改业务代码、数据、配置、Git状态、部署或运行态;不创建第二个业务队列;不执行正式Gate C。
+- 验收:新会话交接回执PASS;QUEUE-036编号和锁保持;职责、WIP=1、禁止抢占、已确认安全方向、未决差距和停止线无遗漏;完成安全分项结论。
+- 敏感边界:不得复制原始聊天、真实密码、Token、账号明细、客户数据、原始日志或完整请求响应,只记录脱敏摘要和Thread/turn ID。
+- 队列编号:QUEUE-20260717-036
+- 下一责任人:安全新正式会话完成历史交接与同队列复核;验收PASS后项目管理员才可切换正式ID并归档旧会话
+
+## COLLAB-20260717-104 | 模块化单体方案前端Gate R复核结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:前端开发
+- 目标角色:Owner/产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-099
+- 结果事件:无
+- 当前Gate:CRM-20260717-003 / Gate R跨角色复核
+- 状态:PASS
+- 目标:回传目标前端目录、渐进迁移、多客户端契约和第一纵向链路的可实施性结论。
+- 输入:COLLAB-099指定材料和QUEUE-034。
+- 范围:只读复核Vue 3/TypeScript/workspaces目标、旧单HTML渐进迁移、共享契约和首链路。
+- 不做项:未修改文件、代码、数据、配置、Git状态、部署或运行态;未开始框架迁移或业务实现。
+- 验收:目标技术栈和目录可实施;新旧入口并存、模块单写、OpenAPI共享边界及第一链路合理;实施期需再冻结本地拓扑、生成器和E2E前置。
+- 敏感边界:未读取或输出真实凭据、客户数据、原始日志、完整请求响应或运行数据。
+- 结论:PASS。仅代表前端职责域方案可实施,不代表CRM-003整体Gate R或任何实现/上线通过。
+- 证据:Codex Thread `019f702e-eb7e-70d3-8271-06269945435a`,turn `019f705c-355f-7d20-bf91-c30d0c2b5acd`。
+- 未完成项:CRM-003其他专业结论和整体汇总;本轮未产生实现。
+- 队列编号:QUEUE-20260717-034
+- 下一责任人:项目管理员汇总CRM-003;前端按Owner最新P0指令处理CRM-006
+
+## COLLAB-20260717-109 | 员工修改密码MVP前端最小实现
+
+- 事件类型:实现请求
+- 发起时间:2026-07-17
+- 发起角色:Owner/产品与项目管理
+- 目标角色:前端开发
+- 上游事件:COLLAB-20260717-098、095;Owner最新“小需求先落地基本功能、后续分段迭代、提高效率”决策
+- 结果事件:待目标角色回传
+- 当前Gate:CRM-20260717-006 / 实现与自测
+- 状态:IN_PROGRESS
+- 目标:按v0.4唯一契约实现员工本人修改密码的最小前端闭环,不再追加方案评审。
+- 输入:[需求与验收](<./202607/0717-员工修改密码/00-需求与验收.md>)、[计划改动清单](<./202607/0717-员工修改密码/01-计划改动清单.md>)、COLLAB-095和098。
+- 范围:只修改`outputs/sales_crm_full_demo.html`及本任务实现记录;增加账号区入口、三字段模态框、本地校验、专用两字段请求、204成功处理、九个错误映射、防重、离线失败关闭、成功清理登录和最小响应式/无障碍行为。
+- 不做项:不修改后端、运行数据、部署配置或运行态;不改`package.json`;不拆分或重构巨型单文件;不实现延期能力;不部署线上。
+- 验收:请求只含`currentPassword`/`newPassword`且不走通用本地回退;确认密码只在前端;Unicode码点8至64;只有204成功;失败不显示成功;成功清理敏感字段和当前登录;形成最小自测和精确diff。
+- 敏感边界:不读取真实密码、Token、账号或客户数据;密码不得进入URL、查询、响应、日志、文档或浏览器持久化。
+- 队列编号:QUEUE-20260717-039
+- 下一责任人:前端开发处理已锁定QUEUE-039
+
+## COLLAB-20260717-110 | 员工修改密码MVP后端最小实现
+
+- 事件类型:实现请求
+- 发起时间:2026-07-17
+- 发起角色:Owner/产品与项目管理
+- 目标角色:后端开发
+- 上游事件:COLLAB-20260717-098、092;Owner最新“小需求先落地基本功能、后续分段迭代、提高效率”决策
+- 结果事件:待目标角色回传
+- 当前Gate:CRM-20260717-006 / 实现与自测
+- 状态:IN_PROGRESS
+- 目标:按v0.4唯一契约实现员工本人修改密码的最小后端闭环,不再追加方案评审。
+- 输入:[需求与验收](<./202607/0717-员工修改密码/00-需求与验收.md>)、[计划改动清单](<./202607/0717-员工修改密码/01-计划改动清单.md>)、COLLAB-092和098。
+- 范围:只修改`work/crm_full_server.js`及本任务实现记录;实现专用路由、严格两字段Schema、认证头身份、停用检查、当前密码验证、Unicode码点规则、新旧不同、204/no-store、九个错误码、账号级原子/CAS和主管重置/停用兼容。
+- 不做项:不读取或修改`data/`运行数据,不修改前端、部署配置或运行态,不改`package.json`,不迁移密码哈希或认证体系,不部署线上。
+- 验收:失败不落盘、本人/主管重置/停用重叠写最多一个成功;旧路径和三字段/200响应不得恢复;完成语法检查、虚构内存/临时夹具自测和精确diff。
+- 敏感边界:不得读取或输出真实密码、Token、账号、客户数据、原始日志或完整请求响应。
+- 队列编号:QUEUE-20260717-040
+- 下一责任人:后端开发处理已锁定QUEUE-040
+
+## COLLAB-20260717-105 | 模块化单体方案后端Gate R复核结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:后端开发
+- 目标角色:Owner/产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-100
+- 结果事件:无
+- 当前Gate:CRM-20260717-003 / Gate R跨角色复核
+- 状态:CHANGES_REQUESTED
+- 目标:回传模块化单体、MySQL、API和渐进迁移的后端可实施性结论。
+- 输入:COLLAB-100指定材料和QUEUE-035。
+- 范围:只读复核模块依赖、单一写入源、事务/迁移/回滚、API、认证边界和第一纵向链路。
+- 不做项:未修改文件、代码、数据、配置、Git状态、部署或运行态;未安装MySQL或执行迁移。
+- 验收:总体方向可实施;进入CRM-003实现前仍需冻结查询/迁移技术栈、精确版本、首链Schema/OpenAPI、会话/CSRF、旧写入口关闭和可重复测试入口。
+- 敏感边界:未读取或输出真实凭据、客户数据、原始日志、完整请求响应或运行数据。
+- 结论:CHANGES_REQUESTED。仅代表CRM-003后端分项需补实施级材料,不影响已通过Gate R且已授权实现的CRM-006。
+- 证据:Codex Thread `019f7014-60d2-7972-ba52-46d834fe49f2`,turn `019f705c-3645-7433-b3d4-29ccbe7ae10e`。
+- 未完成项:CRM-003整改与同项复核;本轮未产生实现。
+- 队列编号:QUEUE-20260717-035
+- 下一责任人:项目管理员汇总CRM-003;后端按Owner最新P0指令处理CRM-006
+
+## COLLAB-20260717-106 | 模块化单体方案安全Gate R复核结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:代码审核与安全
+- 目标角色:Owner/产品与项目管理/项目管理员/架构与数据治理
+- 上游事件:COLLAB-20260717-101
+- 结果事件:无
+- 当前Gate:CRM-20260717-003 / Gate R跨角色复核
+- 状态:CHANGES_REQUESTED
+- 目标:回传多客户端认证、服务端授权、配置、迁移和回滚的设计安全结论。
+- 输入:COLLAB-101指定材料和QUEUE-036。
+- 范围:只读复核Web Cookie/会话/CSRF、移动令牌方向、授权与撤销、配置密钥、迁移摘要和单写切流。
+- 不做项:未执行Gate C,未修改文件、代码、数据、配置、Git状态、部署或运行态;未读取真实数据或敏感值。
+- 验收:主安全方向可继续;进入CRM-003实现前补齐P1-01至P1-05的实施级约束、负向测试与停止线。
+- 敏感边界:未读取或输出真实凭据、客户数据、原始日志、完整请求响应或运行数据。
+- 结论:CHANGES_REQUESTED。无新增P0;需冻结本地HTTPS和Cookie/会话轮换、具体CSRF机制、授权与撤销最大延迟、移动令牌激活前置、配置故障关闭及HMAC/非识别性迁移摘要。
+- 证据:Codex Thread `019f6ea8-b081-7121-9d98-4c9714bf50e1`,turn `019f705c-3b42-7503-8c4d-fb1f27a95927`。
+- 未完成项:架构一次性整改和同QUEUE-036复评;本轮未产生实现。
+- 队列编号:QUEUE-20260717-036
+- 下一责任人:架构与数据治理合并整改;安全在当前P1等待项恢复后同项复评
+
+## COLLAB-20260717-107 | 模块化单体方案测试Gate R复核结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:测试与质量
+- 目标角色:Owner/产品与项目管理/项目管理员/架构与数据治理
+- 上游事件:COLLAB-20260717-102
+- 结果事件:无
+- 当前Gate:CRM-20260717-003 / Gate R跨角色复核
+- 状态:CHANGES_REQUESTED
+- 目标:回传目标架构、契约、迁移、恢复和首链路的可测试性结论。
+- 输入:COLLAB-102指定材料和QUEUE-037。
+- 范围:只读复核契约/集成/E2E分层、虚构样本、迁移对账、快照恢复和计划测试入口。
+- 不做项:未执行Gate A或测试,未修改文件、代码、数据、配置、Git状态、部署或运行态;未读取真实业务数据。
+- 验收:总体结构可测;进入实现前冻结可重复命令、虚构矩阵、迁移异常夹具、脱敏对账报告和数据库保护规则。
+- 敏感边界:未读取或输出真实凭据、客户数据、原始日志、完整请求响应或运行数据。
+- 结论:CHANGES_REQUESTED。需补`test:contract`、恢复验证入口、最小虚构样本矩阵、异常夹具、脱敏报告结构及非零退出/证据位置。
+- 证据:Codex Thread `019f6ea8-ca49-7472-9a9e-24848071c22b`,turn `019f705c-3c5e-76b1-98e5-24096a15567a`。
+- 未完成项:架构一次性整改和同QUEUE-037复评;本轮不是业务Gate A。
+- 队列编号:QUEUE-20260717-037
+- 下一责任人:架构与数据治理合并整改;测试同项复评
+
+## COLLAB-20260717-108 | 模块化单体方案运维Gate R复核结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:运维与发布
+- 目标角色:Owner/产品与项目管理/项目管理员/架构与数据治理
+- 上游事件:COLLAB-20260717-103
+- 结果事件:无
+- 当前Gate:CRM-20260717-003 / Gate R跨角色复核
+- 状态:CHANGES_REQUESTED
+- 目标:回传Windows本地MySQL、配置隔离、启动健康、备份恢复和切流回滚的可操作性结论。
+- 输入:COLLAB-103指定材料和QUEUE-038。
+- 范围:只读复核MySQL精确基线、配置保护、前置检查、健康入口、恢复Runbook和单写切流证据。
+- 不做项:未执行Gate D,未安装软件,未修改文件、代码、数据、配置、Git状态、部署或运行态;未接触生产。
+- 验收:总体方向可操作;进入实现前补齐可机械执行的版本、服务、目录、配置、检查、恢复和切流规范。
+- 敏感边界:未读取或输出真实凭据、客户数据、原始日志、完整请求响应或运行数据。
+- 结论:CHANGES_REQUESTED。需冻结MySQL 8.4.x补丁版本与安装标识、Windows服务/目录/身份、故障关闭配置、健康入口、仓库外备份恢复Runbook和单写开关证据。
+- 证据:Codex Thread `019f6ea8-ec46-70d2-9122-0968c7946c23`,turn `019f705c-42ad-7de1-8e97-f3774c89d85f`。
+- 未完成项:架构一次性整改和同QUEUE-038复评;本轮不是Gate D。
+- 队列编号:QUEUE-20260717-038
+- 下一责任人:架构与数据治理合并整改;运维同项复评
+
+## COLLAB-20260717-111 | 安全会话迁移编号冲突更正与动作废止
+
+- 事件类型:事实源更正
+- 发起时间:2026-07-17
+- 发起角色:Owner/项目管理员
+- 目标角色:全体项目角色
+- 上游事件:同文件中误用`COLLAB-20260717-109`标题的“安全正式会话卡死迁移与同队列接管”记录;原安全结果COLLAB-106
+- 结果事件:无
+- 当前Gate:CRM-20260717-008 / 会话状态纠正
+- 状态:CLOSED
+- 目标:按只追加原则纠正编号碰撞并废止误判迁移动作,不覆盖原始记录。
+- 输入:原安全Thread最终turn、替代Thread状态核对和当前CRM-006实现事件109/110。
+- 范围:声明误用109编号的安全迁移块不再作为有效事件;有效`COLLAB-109`为CRM-006前端实现,有效`COLLAB-110`为CRM-006后端实现;本更正使用唯一编号111。
+- 不做项:不删除或覆盖历史块,不切换正式安全Thread ID,不归档原安全会话,不重复安全评审。
+- 验收:正式安全入口仍为Thread `019f6ea8-b081-7121-9d98-4c9714bf50e1`;QUEUE-036结论以COLLAB-106为准;替代会话只读核对后停用归档。
+- 敏感边界:仅记录脱敏状态、Thread/turn ID,不记录凭据、客户数据、原始日志或完整请求响应。
+- 结论:PASS。原安全会话已正常完成;误判迁移动作取消,替代Thread `019f7079-c60f-7fd0-a099-899ca8a4708b`未修改文件或状态、未成为正式入口并已归档。
+- 证据:替代Thread状态核对turn `019f7079-daab-7ff3-be7c-2bcd91d91389`;原安全结果见COLLAB-106。
+- 下一责任人:项目管理员/架构与数据治理继续CRM-003一次性整改
+
+## COLLAB-20260717-112 | 模块化单体方案跨角色缺口一次性整改
+
+- 事件类型:Gate R整改请求
+- 发起时间:2026-07-17
+- 发起角色:Owner/项目管理员
+- 目标角色:架构与数据治理
+- 上游事件:COLLAB-20260717-104、105、106、107、108、111
+- 结果事件:COLLAB-20260717-113
+- 当前Gate:CRM-20260717-003 / Gate R跨角色整改
+- 状态:IN_PROGRESS
+- 目标:一次性合并后端、安全、测试和运维缺口,修订现有四份方案及CRM-003任务事实源,形成唯一实施级定稿,不拆成多轮零散动作。
+- 输入:五个专业分项结果、四份现有方案、Owner“不断完善方案文档、最终定稿、快速推进”指令。
+- 范围:补齐精确技术基线、首链Schema/OpenAPI、Web HTTPS/会话/CSRF、授权撤销时效、配置与迁移摘要安全、可重复测试入口/夹具/对账、Windows MySQL机械基线、健康检查、备份恢复Runbook和单写切流证据;同步CRM-003验收与结论。
+- 不做项:不修改业务代码、运行数据或部署;不安装MySQL;不执行迁移、测试、Gate C/D/A/P;不新增备选架构或扩大到生产。
+- 验收:四类CHANGES逐项映射到唯一修订;前端已PASS项不回退;相对链接和敏感边界通过;输出可供原QUEUE-034至038同项复评的唯一材料。
+- 敏感边界:只使用虚构/脱敏样本规范,不读取或输出真实凭据、客户数据、原始日志、完整请求响应或运行数据。
+- 队列编号:QUEUE-20260717-041
+- 下一责任人:架构与数据治理完成一次性整改并回传结果;随后原五角色同项复评
+
+## COLLAB-20260717-130 | 后端正式会话再次故障迁移与实现队列接管
+
+- 事件类型:会话故障迁移请求
+- 发起时间:2026-07-17
+- 发起角色:Owner/项目管理员
+- 目标角色:后端开发
+- 上游事件:COLLAB-20260717-110;当前正式后端Thread连续两次投递QUEUE-040均未生成turn并返回`no active turn to steer`
+- 结果事件:COLLAB-20260717-131
+- 当前Gate:CRM-20260717-008 / 会话故障迁移;保持CRM-006实现QUEUE-040
+- 状态:CLOSED
+- 目标:创建可用的后端正式会话,完整回读当前后端会话全部历史,并从最后检查点恢复同一QUEUE-040最小实现。
+- 输入:[会话故障迁移与交接规范](<../研发体系/会话故障迁移与交接规范.md>)、旧Thread `019f7014-60d2-7972-ba52-46d834fe49f2`、COLLAB-110、后端队列和CRM-006 v0.4唯一契约。
+- 范围:完整分页回读旧会话全部turn到`hasMore=false`,提取脱敏决策、已完成/未完成项、队列、风险和恢复点;随后在同一接管turn恢复QUEUE-040实现。
+- 不做项:交接PASS前不归档旧会话;不创建第二个业务队列;不修改前端、package.json、data运行数据、部署或生产;不实现延期项。
+- 验收:新会话交接回执PASS;QUEUE-040编号和锁保持;职责、WIP=1、Owner授权、v0.4契约、CRM-003 CHANGES结果和停止线无遗漏;产生一次实现接管turn。
+- 敏感边界:不得复制原始聊天、真实密码、Token、账号明细、客户数据、原始日志或完整请求响应;只记录脱敏摘要和Thread/turn ID。
+- 队列编号:QUEUE-20260717-040
+- 下一责任人:后端新正式会话完成历史交接并恢复实现;验收PASS后项目管理员切换正式ID并归档旧会话
+
+## COLLAB-20260717-132 | 前端正式会话再次卡死迁移与实现队列接管
+
+- 事件类型:会话故障迁移请求
+- 发起时间:2026-07-17
+- 发起角色:Owner/项目管理员
+- 目标角色:前端开发
+- 上游事件:COLLAB-20260717-109;当前正式前端Thread启动QUEUE-039后长时间停留在同一已完成命令检查点且无文件变更
+- 结果事件:COLLAB-20260717-133
+- 当前Gate:CRM-20260717-008 / 会话故障迁移;保持CRM-006实现QUEUE-039
+- 状态:CLOSED
+- 目标:创建可用的前端正式会话,完整回读当前前端会话全部历史,并从可见检查点恢复同一QUEUE-039最小实现。
+- 输入:[会话故障迁移与交接规范](<../研发体系/会话故障迁移与交接规范.md>)、旧Thread `019f702e-eb7e-70d3-8271-06269945435a`、COLLAB-109、前端队列、v0.4唯一契约和旧活跃turn脱敏检查点。
+- 范围:完整分页回读旧会话全部已完成turn到`hasMore=false`;保留当前活跃turn已确认的专用请求、禁止通用`api()`本地回退、原单文件局部实现和WIP=1检查点;随后恢复QUEUE-039。
+- 不做项:交接PASS前不归档旧会话;不创建第二个业务队列;不修改后端、package.json、data、部署或生产;不重构巨型单文件或实现延期项。
+- 验收:新会话交接回执PASS;QUEUE-039编号和锁保持;职责、Owner授权、v0.4契约、UI边界、自测、风险和停止线无遗漏;产生一次实现接管turn。
+- 敏感边界:不得复制原始聊天、真实密码、Token、账号明细、客户数据、原始日志或完整请求响应;只记录脱敏摘要和Thread/turn ID。
+- 队列编号:QUEUE-20260717-039
+- 下一责任人:前端新正式会话完成历史交接并恢复实现;验收PASS后项目管理员切换正式ID并归档旧会话
+
+## COLLAB-20260717-114 | 后端正式会话故障迁移并恢复改密最小实现
+
+- 事件类型:会话故障迁移请求
+- 发起时间:2026-07-17
+- 发起角色:Owner/产品与项目管理
+- 目标角色:后端开发
+- 上游事件:COLLAB-20260717-110;旧正式后端会话连续两次投递均未产生新turn
+- 结果事件:COLLAB-20260717-130(采用项目管理员先建立的唯一权威迁移)
+- 当前Gate:CRM-20260717-006 / 实现与自测;保持QUEUE-20260717-040唯一执行锁
+- 状态:CANCELLED
+- 目标:迁移不可继续投递的后端正式会话,完整继承同一QUEUE-040,并直接恢复员工修改密码后端最小实现,不重新评审、不扩大范围。
+- 输入:[会话故障迁移与交接规范](<../研发体系/会话故障迁移与交接规范.md>)、旧Thread `019f7014-60d2-7972-ba52-46d834fe49f2`、新Thread `019f7089-4438-7dc2-95cd-251b74919643`、COLLAB-110及CRM-006 v0.4唯一契约。
+- 范围:新会话先核对旧会话完整历史、Owner决策、当前锁和停止线,再在同一QUEUE-040内仅修改`work/crm_full_server.js`及必要实现记录,完成最小后端实现和脱敏自测。
+- 不做项:不新建业务队列,不重复Gate N/R,不读取或修改`data/`,不修改前端、依赖、配置、部署或运行态,不实施延期项,不部署线上。
+- 验收:交接无遗漏、WIP=1、QUEUE-040保持;v0.4专用接口、严格两字段、认证/停用/当前密码校验、Unicode长度、新旧不同、204/no-store、九码、原子/CAS及主管兼容实现并完成安全自测;旧会话停止接收新任务。
+- 敏感边界:不得复制原始聊天、真实密码、Token、账号、客户数据、原始日志或完整请求响应,只记录脱敏证据和Thread/turn ID。
+- 队列编号:QUEUE-20260717-040
+- 结论:本事件与项目管理员并行建立的COLLAB-130重复。Thread `019f7089-4438-7dc2-95cd-251b74919643`识别重复锁后以BLOCKED停止,未修改代码、数据、配置或运行态;QUEUE-040及COLLAB-110保持不变。
+- 下一责任人:以COLLAB-130指定的新后端会话为唯一权威接管入口,继续同一QUEUE-040;本事件不再投递
+
+## COLLAB-20260717-133 | 前端会话接管与改密最小实现结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:前端开发
+- 目标角色:Owner/产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-109、132
+- 结果事件:无
+- 当前Gate:CRM-20260717-006 / 实现与自测
+- 状态:PASS
+- 目标:回传前端正式会话接管、QUEUE-039最小实现和开发自测结果。
+- 输入:v0.3-MVP/v0.4唯一契约、旧Thread `019f702e-eb7e-70d3-8271-06269945435a`、QUEUE-039及冻结UI边界。
+- 范围:完整回读旧会话可见历史;仅修改`outputs/sales_crm_full_demo.html`和必要实现记录,完成入口、三字段模态框、校验、专用两字段请求、仅204成功、九码、失败关闭、退出重登和最小无障碍/响应式。
+- 不做项:未修改后端、依赖、数据、配置、部署或运行态;未连接真实账号、执行隔离环境测试、Gate C/D/A/P或上线。
+- 验收:内联脚本语法、静态契约、Unicode边界、204/非204/网络失败、无本地回退及`git diff --check`均PASS;请求体严格两字段,成功清除敏感表单、认证和内存业务态。
+- 敏感边界:自测仅使用运行时虚构字符串,未读取或输出真实密码、Token、账号或客户数据、原始日志或完整响应。
+- 结论:PASS,仅代表QUEUE-039前端实现与开发自测完成,不代表Gate C/D/A/P或上线通过。
+- 证据:新Thread `019f7097-ba42-7610-a05d-2d427d3027db`,turn `019f7097-cfb1-77d0-aeb1-f0ae27874b51`;HTML相对基线`+271/-4`。
+- 队列编号:QUEUE-20260717-039
+- 下一责任人:项目管理员切换前端正式入口并释放QUEUE-039;等待后端QUEUE-040完成后建立一次独立Gate C
+
+## COLLAB-20260717-131 | 后端会话接管与改密最小实现结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:后端开发
+- 目标角色:Owner/产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-110、130
+- 结果事件:无
+- 当前Gate:CRM-20260717-006 / 实现与自测
+- 状态:PASS
+- 目标:回传后端正式会话接管、QUEUE-040最小实现和开发自测结果。
+- 输入:v0.3-MVP/v0.4唯一契约、旧Thread `019f7014-60d2-7972-ba52-46d834fe49f2`、QUEUE-040及冻结后端边界。
+- 范围:完整回读旧会话历史;仅修改`work/crm_full_server.js`和必要实现记录,完成专用改密路由、严格两字段、Header认证、停用/当前密码/Unicode校验、204/no-store、九码、账号锁与版本CAS,并使主管重置和账号停用共享同一写入原语。
+- 不做项:未修改`data/`、前端、依赖、配置、部署或运行态;未迁移密码哈希/认证体系,未执行隔离环境测试、Gate C/D/A/P或上线。
+- 验收:`node --check`、21项虚构内存HTTP测试、精简并发/主管重置/停用复跑和`git diff --check`均PASS;首次失败仅为PowerShell引号导致测试代码未启动,改用标准输入后通过。
+- 敏感边界:仅使用虚构内存数据,未读取或输出真实密码、Token、账号、客户数据、原始日志或完整响应。
+- 结论:PASS,仅代表QUEUE-040后端实现与开发自测完成,不代表Gate C/D/A/P或上线通过。
+- 证据:新Thread `019f708a-ed37-72b0-887d-77a00f869701`,turn `019f708b-0386-7593-a0b0-cb7bd4ca4c9d`;后端代码相对基线`+296/-65`。
+- 队列编号:QUEUE-20260717-040
+- 下一责任人:项目管理员切换后端正式入口并释放QUEUE-040;代码审核与安全基于前后端精确diff执行一次独立Gate C
+
+## COLLAB-20260717-113 | 模块化单体方案跨角色缺口一次性整改结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:架构与数据治理
+- 目标角色:Owner/产品与项目管理/项目管理员/前端/后端/安全/测试/运维
+- 上游事件:COLLAB-20260717-112
+- 结果事件:无
+- 当前Gate:CRM-20260717-003 / Gate R跨角色整改
+- 状态:PASS
+- 目标:回传四类CHANGES_REQUESTED一次性合并后的唯一实施级方案和同项复评入口。
+- 输入:COLLAB-104至108、111、112及四份原方案。
+- 范围:修订四份架构/环境方案和CRM-003任务事实源,冻结技术基线、Schema/API、安全、测试、环境、恢复和切流规则。
+- 不做项:未修改业务代码、配置、数据、部署或运行态;未安装/启动MySQL,未执行迁移、测试、恢复、切流或Gate P;未读取真实数据或敏感值。
+- 验收:四类CHANGES逐项形成唯一裁决;前端PASS项不回退;原QUEUE-034至038可按同一材料复评。
+- 敏感边界:只记录脱敏规则和虚构样本规范,未读取或输出真实凭据、客户数据、原始日志、完整请求响应或运行数据。
+- 结论:PASS。冻结Node.js 24.18.0 LTS/npm 11.16.0/MySQL 8.4.10 LTS、Fastify 5/TypeScript/TypeBox/OpenAPI 3.1/Kysely/mysql2;模块单写、首链Schema/DTO、HTTPS会话/CSRF、授权撤销、配置/HMAC摘要、测试/恢复入口和Windows MySQL机械Runbook均已定稿。
+- 验证:13份范围文档、61个相对链接断链0;21项必需基线缺失0;旧版本/HTTP例外残留0;尾随空白0;常见敏感值模式0;`git diff --check`通过。
+- 证据:架构Thread `019f6f85-bee8-7f70-8d0a-af638ece0782`,turn `019f705c-46d8-7422-a8dc-0ba2becca896`。
+- 未完成项:原五角色同项复评、产品Gate P、工程/MySQL/迁移/测试/恢复及生产准备。
+- 队列编号:QUEUE-20260717-041
+- 下一责任人:项目管理员释放QUEUE-041并恢复原QUEUE-034至038同项复评
+
+## COLLAB-20260717-140 | 模块化单体方案安全同项复评
+
+- 事件类型:Gate R整改复评请求
+- 发起时间:2026-07-17
+- 发起角色:项目管理员
+- 目标角色:代码审核与安全
+- 上游事件:COLLAB-20260717-106、113
+- 结果事件:COLLAB-20260717-143
+- 当前Gate:CRM-20260717-003 / Gate R整改复评
+- 状态:CLOSED
+- 目标:在同一QUEUE-036复评P1-01至P1-05是否全部关闭,不重新扩展方案。
+- 输入:COLLAB-106、113及四份修订方案。
+- 范围:只读核对HTTPS/会话、CSRF、授权撤销、移动令牌前置、配置和HMAC迁移摘要。
+- 不做项:不修改文件/代码/数据/配置/Git/部署/运行态,不执行Gate C,不新增P1范围外方案。
+- 验收:逐项回传关闭/未关闭及PASS/CHANGES_REQUESTED/BLOCKED;说明是否可作为整体Gate R输入。
+- 敏感边界:不读取或输出真实凭据、客户数据、原始日志、完整请求响应或运行数据。
+- 队列编号:QUEUE-20260717-036
+- 下一责任人:代码审核与安全
+
+## COLLAB-20260717-141 | 模块化单体方案测试同项复评
+
+- 事件类型:Gate R整改复评请求
+- 发起时间:2026-07-17
+- 发起角色:项目管理员
+- 目标角色:测试与质量
+- 上游事件:COLLAB-20260717-107、113
+- 结果事件:COLLAB-20260717-144
+- 当前Gate:CRM-20260717-003 / Gate R整改复评
+- 状态:CLOSED
+- 目标:在同一QUEUE-037复评测试入口、虚构夹具、迁移对账、恢复证据和数据库保护是否全部可执行。
+- 输入:COLLAB-107、113及四份修订方案。
+- 范围:只读核对`test:contract`/`test:recovery`、样本/异常夹具、脱敏报告、非零退出和证据位置。
+- 不做项:不修改文件/代码/数据/配置/Git/部署/运行态,不执行Gate A或实际测试,不读取真实数据。
+- 验收:逐项回传关闭/未关闭及PASS/CHANGES_REQUESTED/BLOCKED;说明是否可作为整体Gate R输入。
+- 敏感边界:不读取或输出真实凭据、客户数据、原始日志、完整请求响应或运行数据。
+- 队列编号:QUEUE-20260717-037
+- 下一责任人:测试与质量
+
+## COLLAB-20260717-142 | 模块化单体方案运维同项复评
+
+- 事件类型:Gate R整改复评请求
+- 发起时间:2026-07-17
+- 发起角色:项目管理员
+- 目标角色:运维与发布
+- 上游事件:COLLAB-20260717-108、113
+- 结果事件:COLLAB-20260717-145
+- 当前Gate:CRM-20260717-003 / Gate R整改复评
+- 状态:CLOSED
+- 目标:在同一QUEUE-038复评Windows MySQL机械基线、配置、健康、备份恢复和单写切流是否全部闭合。
+- 输入:COLLAB-108、113及四份修订方案。
+- 范围:只读核对版本/安装标识、服务/目录/身份、故障关闭、健康入口、仓库外恢复Runbook和切流证据。
+- 不做项:不修改文件/代码/数据/配置/Git/部署/运行态,不执行Gate D,不安装软件或接触生产。
+- 验收:逐项回传关闭/未关闭及PASS/CHANGES_REQUESTED/BLOCKED;说明是否可作为整体Gate R输入。
+- 敏感边界:不读取或输出真实凭据、客户数据、原始日志、完整请求响应或运行数据。
+- 队列编号:QUEUE-20260717-038
+- 下一责任人:运维与发布
+
+## COLLAB-20260717-145 | 模块化单体方案运维同项复评结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-18
+- 发起角色:运维与发布
+- 目标角色:Owner/产品与项目管理/项目管理员/架构与数据治理
+- 上游事件:COLLAB-20260717-108、113、142
+- 结果事件:无
+- 当前Gate:CRM-20260717-003 / Gate R整改复评
+- 状态:PASS
+- 目标:回传Windows MySQL机械基线、配置、健康、恢复Runbook和单写切流的关闭性复评。
+- 输入:COLLAB-113唯一修订、四份定稿方案和QUEUE-038。
+- 范围:只读核对MySQL版本与安装标识、Windows服务/目录/身份、配置失败关闭、健康入口、仓库外备份恢复和单写切流证据。
+- 不做项:未安装软件,未执行Gate D、迁移、备份、恢复、切流或测试;未修改文件、代码、数据、配置、Git状态、部署或运行态,未读取真实数据或敏感值。
+- 结论:PASS。原运维分项缺口均在方案级关闭,可作为CRM-003整体Gate R运维输入,不代表环境已就绪、Gate D或上线通过。
+- 残余风险:MySQL、服务账号、证书、数据库、脚本和健康端点仍待首个实施任务实际创建、执行并形成脱敏机械证据;全部Runbook仅适用于本地生成数据。
+- 证据:Thread `019f6ea8-ec46-70d2-9122-0968c7946c23`,turn `019f70ac-d85a-7733-9486-c3c6d7a24918`。
+- 队列编号:QUEUE-20260717-038
+- 下一责任人:项目管理员汇总CRM-003;BLOCK-001至003和生产No-Go继续有效
+
+## COLLAB-20260717-143 | 模块化单体方案安全同项复评结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-17
+- 发起角色:代码审核与安全
+- 目标角色:Owner/产品与项目管理/项目管理员/架构与数据治理
+- 上游事件:COLLAB-20260717-106、113、140
+- 结果事件:无
+- 当前Gate:CRM-20260717-003 / Gate R整改复评
+- 状态:PASS
+- 目标:回传原P1-01至P1-05关闭性复评结论。
+- 输入:COLLAB-113唯一修订、四份定稿方案和QUEUE-036。
+- 范围:只读核对HTTPS/会话固定、CSRF、授权撤销、移动令牌前置、配置/HMAC迁移摘要。
+- 不做项:未执行Gate C,未修改文件、代码、数据、配置、Git状态、部署或运行态,未读取真实数据或敏感值。
+- 验收:P1-01至P1-05逐项关闭;设计已形成可机械验证规则,可作为CRM-003整体Gate R安全输入。
+- 结论:PASS。仅代表CRM-003安全整改复评,不代表实现、Gate C/D/A/P或上线通过。
+- 证据:Thread `019f6ea8-b081-7121-9d98-4c9714bf50e1`,turn `019f70ac-be39-7293-be45-efdbbabb0e84`。
+- 队列编号:QUEUE-20260717-036
+- 下一责任人:项目管理员汇总CRM-003;安全角色转入已排队的CRM-006一次独立Gate C
+
+## COLLAB-20260717-146 | 员工修改密码MVP独立Gate C审核
+
+- 事件类型:Gate C审核请求
+- 发起时间:2026-07-17
+- 发起角色:Owner/产品与项目管理
+- 目标角色:代码审核与安全
+- 上游事件:COLLAB-20260717-098、131、133
+- 结果事件:COLLAB-20260717-147
+- 当前Gate:CRM-20260717-006 / Gate C
+- 状态:CLOSED
+- 目标:对已经完成开发自测的员工修改密码前后端精确diff执行一次且仅一次独立代码与安全审核,快速判定是否可进入隔离环境验收。
+- 输入:[需求与验收](<./202607/0717-员工修改密码/00-需求与验收.md>)、[实现与自测记录](<./202607/0717-员工修改密码/02-实现与自测记录.md>)、`outputs/sales_crm_full_demo.html`和`work/crm_full_server.js`相对当前Git基线的精确diff、COLLAB-131和133。
+- 范围:只读审查本人身份、停用、当前密码、长度、新旧不同、严格两字段、204/no-store、九码、前端失败关闭/退出重登、账号锁/CAS、失败不落盘、主管重置/停用共享原语、敏感信息和单写限制;允许使用虚构内存夹具复算语法与最小负向/并发证据。
+- 不做项:不修改任何文件、代码、数据、配置、Git状态、部署或运行态;不读取`data/`,不做需求扩展、重复Gate N/R、隔离环境Gate A或线上部署。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED;若有Finding须给出文件、行号、复现与最小修复建议;明确是否允许进入隔离环境测试,不代签Gate D/A/P。
+- 敏感边界:不得读取或输出真实密码、Token、账号、客户数据、原始日志或完整请求响应;证据只能使用虚构值并脱敏摘要。
+- 队列编号:QUEUE-20260717-042
+- 下一责任人:代码审核与安全
+
+## COLLAB-20260717-144 | 模块化单体方案测试同项复评结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-18
+- 发起角色:测试与质量
+- 目标角色:Owner/产品与项目管理/项目管理员/架构与数据治理
+- 上游事件:COLLAB-20260717-107、113、141
+- 结果事件:无
+- 当前Gate:CRM-20260717-003 / Gate R整改复评
+- 状态:PASS
+- 目标:回传测试入口、夹具、对账、退出码、数据库保护和证据位置的关闭性复评。
+- 输入:COLLAB-113唯一修订、四份定稿方案和QUEUE-037。
+- 范围:只读核对`test:contract`、`test:recovery`、虚构/异常夹具、脱敏对账、非零退出、数据库保护和证据位置。
+- 不做项:未执行实际测试或Gate A,未修改文件、代码、数据、配置、Git状态、部署或运行态,未读取真实数据或敏感值。
+- 结论:PASS。原测试分项缺口均在方案级关闭,可作为CRM-003整体Gate R测试输入,不代表实现、Gate A或上线通过。
+- 证据:Thread `019f6ea8-ca49-7472-9a9e-24848071c22b`,turn `019f70ac-c5a2-7663-aa84-868c8b8769b5`。
+- 队列编号:QUEUE-20260717-037
+- 下一责任人:项目管理员汇总CRM-003;测试角色转入CRM-006隔离环境最小验收
+
+## COLLAB-20260717-147 | 员工修改密码MVP独立Gate C结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-18
+- 发起角色:代码审核与安全
+- 目标角色:Owner/产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-131、133、146
+- 结果事件:无
+- 当前Gate:CRM-20260717-006 / Gate C
+- 状态:PASS
+- 目标:回传员工修改密码前后端精确diff的一次独立代码与安全审核结论。
+- 输入:父基线`9ad42b5c22880b21c09897a5c249d48909c2a3ad`、前端`+271/-4`、后端`+296/-65`及开发自测记录。
+- 范围:只读审核本人身份、停用/当前密码/长度/新旧不同、严格两字段、204/no-store、九码、前端失败关闭/退出、账号锁/CAS、共享写入原语、失败不落盘、敏感流和单写限制。
+- 不做项:未修改文件、代码、数据、配置、Git状态、部署或运行态;未读取`data/`或真实敏感信息,未执行Gate D/A/P或上线。
+- 验收:后端语法、前端内联脚本、16项虚构负向/Unicode/并发/CAS/写失败复算、九码一致性、敏感流和`git diff --check`均PASS;未发现阻塞首版Finding。
+- 结论:PASS。允许进入隔离环境测试;两个受审源码diff变化后本结论失效。仅支持单进程单写实例。
+- 证据:Thread `019f6ea8-b081-7121-9d98-4c9714bf50e1`,turn `019f70c6-fdb9-76a2-b36e-f9bdd90a7062`。
+- 队列编号:QUEUE-20260717-042
+- 下一责任人:测试与质量执行QUEUE-043隔离环境最小验收
+
+## COLLAB-20260717-148 | 员工修改密码MVP隔离环境最小验收
+
+- 事件类型:Gate A验收请求
+- 发起时间:2026-07-18
+- 发起角色:Owner/产品与项目管理
+- 目标角色:测试与质量
+- 上游事件:COLLAB-20260717-131、133、147
+- 结果事件:COLLAB-20260717-149
+- 当前Gate:CRM-20260717-006 / Gate A隔离环境验收
+- 状态:IN_PROGRESS
+- 目标:只验证首版最小闭环能用,不扩大测试范围;通过后形成“本地/隔离环境可验收”结论,不部署线上。
+- 输入:冻结需求、前后端源码精确diff、开发自测、Gate C PASS及现有可注入虚构内存存储入口。
+- 范围:使用虚构内存或仓库外临时夹具验证登录后入口、三字段/本地校验、当前密码正确才能修改、8至64码点、新旧不同、仅本人、204后退出、旧密码失效/新密码可登录、错误/离线不假成功、防重复、主管重置和停用兼容、单进程并发最多一次成功;可做最小360px静态/浏览器检查。
+- 不做项:不读取或修改`data/`,不使用真实账号/客户数据,不修改代码/配置/Git,不连接生产,不执行部署/Gate D/P,不测试延期的哈希迁移、完整会话撤销、限流、审计或移动端。
+- 验收:逐项回传PASS/CHANGES_REQUESTED/BLOCKED、执行证据、未测项和风险;如失败只给最小复现,不顺手修改;明确是否达到首版隔离环境可用。
+- 敏感边界:全部使用虚构值,证据不得包含密码/Token原文、账号明细、客户数据、原始日志或完整响应。
+- 队列编号:QUEUE-20260717-043
+- 下一责任人:测试与质量
+
+## COLLAB-20260717-150 | 测试正式会话故障迁移并恢复改密验收
+
+- 事件类型:会话故障迁移请求
+- 发起时间:2026-07-18
+- 发起角色:Owner/产品与项目管理
+- 目标角色:测试与质量
+- 上游事件:COLLAB-20260717-148;原测试正式会话连续两次投递均未产生新turn
+- 结果事件:与COLLAB-20260717-149合并回传
+- 当前Gate:CRM-20260717-006 / Gate A隔离环境验收;保持QUEUE-20260717-043唯一执行锁
+- 状态:BLOCKED
+- 目标:迁移不可继续投递的测试正式会话,完整继承同一QUEUE-043并直接恢复最小验收,不重新评审、不扩大测试范围。
+- 输入:[会话故障迁移与交接规范](<../研发体系/会话故障迁移与交接规范.md>)、旧Thread `019f6ea8-ca49-7472-9a9e-24848071c22b`、新Thread `019f70ec-c8b9-7312-97b6-ce9d0b58976e`、COLLAB-148及CRM-006冻结基线。
+- 范围:新会话核对旧历史、Owner决策、当前锁和停止线后,在同一turn使用虚构内存/仓库外临时夹具完成首版隔离验收并回传结果。
+- 不做项:不新建业务队列,不修改代码/文件/data/配置/Git/部署/生产运行态,不测试延期项,不部署线上。
+- 验收:交接无遗漏、WIP=1、QUEUE-043保持;最小闭环逐项验收并明确是否隔离环境可用;旧会话停止接收新任务。
+- 敏感边界:只使用虚构值和脱敏摘要,不记录密码、Token、账号明细、客户数据、原始日志或完整响应。
+- 队列编号:QUEUE-20260717-043
+- 下一责任人:新测试正式会话完成接管并恢复同一验收卡;PASS后项目管理员切换正式入口
+
+## COLLAB-20260717-151 | 测试会话二次故障迁移并从检查点恢复验收
+
+- 事件类型:会话故障迁移请求
+- 发起时间:2026-07-18
+- 发起角色:Owner/产品与项目管理
+- 目标角色:测试与质量
+- 上游事件:COLLAB-20260717-148、150;首个替代Thread在事实源核对阶段进入`systemError`,未执行测试或产生修改
+- 结果事件:与COLLAB-20260717-149合并回传
+- 当前Gate:CRM-20260717-006 / Gate A隔离环境验收;继续保持QUEUE-20260717-043唯一锁
+- 状态:IN_PROGRESS
+- 目标:使用新的可用会话从已确认检查点直接恢复最小验收,避免重复长篇评审和文档回读。
+- 输入:旧正式Thread `019f6ea8-ca49-7472-9a9e-24848071c22b`、故障替代Thread `019f70ec-c8b9-7312-97b6-ce9d0b58976e`、新Thread `019f70f1-b6bd-7d82-9c43-d254c66f46b9`、COLLAB-148和脱敏检查点。
+- 范围:确认QUEUE-043和禁止边界后,直接使用虚构内存/回环短生命周期进程执行最小验收;不重复Gate N/R/C。
+- 不做项:不修改代码/文件/data/配置/Git/部署/生产运行态,不新增业务队列或扩大测试,不使用真实数据。
+- 验收:回传COLLAB-149逐项结果和标准接管结论;未运行测试的故障会话不作为验收证据。
+- 敏感边界:只记录虚构值的脱敏摘要,不记录密码、Token、账号明细、客户数据、原始日志或完整响应。
+- 队列编号:QUEUE-20260717-043
+- 下一责任人:新测试会话直接执行最小验收
+
+## COLLAB-20260717-150 | 模块化单体方案后端同项复评
+
+- 事件类型:Gate R整改复评请求
+- 发起时间:2026-07-18
+- 发起角色:项目管理员
+- 目标角色:后端开发
+- 上游事件:COLLAB-20260717-100、113
+- 结果事件:COLLAB-20260717-151
+- 当前Gate:CRM-20260717-003 / Gate R整改复评
+- 状态:CLOSED
+- 目标:在原QUEUE-035复评后端首轮实施级缺口是否已由COLLAB-113唯一修订全部关闭,不重新扩展方案。
+- 输入:COLLAB-100、113及四份定稿方案。
+- 范围:只读确认第一纵向链路Schema/API、Kysely与`mysql2/promise`迁移栈、Web本地HTTPS会话与CSRF、单写切流及可重复命令是否形成可实施基线。
+- 不做项:不修改文件、代码、数据、配置、Git、部署或运行态;不实现工程骨架、MySQL、迁移或业务功能;不扩展首轮后端Finding。
+- 验收:逐项回传关闭/未关闭及PASS/CHANGES_REQUESTED/BLOCKED;说明是否可作为CRM-003整体Gate R后端输入。
+- 敏感边界:不读取或输出真实凭据、客户数据、原始日志、完整请求响应或运行数据。
+- 队列编号:QUEUE-20260717-035
+- 下一责任人:后端开发
+
+## COLLAB-20260717-151 | 模块化单体方案后端同项复评结果
+
+- 事件类型:结果回传
+- 发起时间:2026-07-18
+- 发起角色:后端开发
+- 目标角色:Owner/产品与项目管理/项目管理员/架构与数据治理
+- 上游事件:COLLAB-20260717-100、113、150
+- 结果事件:无
+- 当前Gate:CRM-20260717-003 / Gate R整改复评
+- 状态:PASS
+- 目标:回传后端首轮实施级缺口的关闭性复评。
+- 输入:COLLAB-113唯一修订、四份定稿方案和QUEUE-035。
+- 范围:只读核对首链物理Schema/API、Kysely与`mysql2/promise`迁移栈、Web本地HTTPS会话与CSRF、单写切流及可重复命令。
+- 不做项:未执行命令验证、MySQL操作、真实数据读取或工程实施;未修改文件、代码、配置、Git、部署或运行态。
+- 结论:PASS。COLLAB-100首轮五类后端缺口均已在方案级关闭,可作为CRM-003整体Gate R后端输入,不代表工程实现或上线通过。
+- 残余风险:Schema、脚本、MySQL、迁移、恢复、切流和测试均尚未实现或运行。
+- 证据:Thread `019f708a-ed37-72b0-887d-77a00f869701`,turn `019f70e4-c66f-7823-ae16-c3e4e31c52f6`。
+- 队列编号:QUEUE-20260717-035
+- 下一责任人:项目管理员形成CRM-003整体Gate R汇总
+
+## COLLAB-20260717-152 | 模块化单体方案整体Gate R汇总结果
+
+- 事件类型:Gate R汇总结果
+- 发起时间:2026-07-18
+- 发起角色:项目管理员
+- 目标角色:Owner/产品与项目管理/架构与数据治理及全部适用专业角色
+- 上游事件:COLLAB-20260717-104、113、143、144、145、151
+- 结果事件:无
+- 当前Gate:CRM-20260717-003 / Gate R整体汇总
+- 状态:PASS
+- 目标:基于全部适用专业角色最终结论,形成唯一整体Gate R裁决并转入产品Gate P。
+- 输入:架构COLLAB-113、前端COLLAB-104、后端COLLAB-151、安全COLLAB-143、测试COLLAB-144、运维COLLAB-145。
+- 范围:汇总模块化单体、MySQL、共享API/认证、本地环境、测试/恢复和渐进切流方案的可实施性结论。
+- 前端无回归裁决:不重复创建同义评审。COLLAB-104保持PASS;COLLAB-113明确“前端PASS项不回退”,本次整改仅补充同源代理、契约生成和公共入口,未改变前端目标边界,因此项目级确认无须重审。
+- 结论:PASS。全部适用Gate R专业输入均为PASS,方案可进入产品Gate P;只代表方案冻结,不代表代码、MySQL、迁移、测试、部署或生产上线完成。
+- 不做项:未实现工程骨架、Schema、脚本或业务迁移,未执行Gate C/D/A,未部署生产,未读取真实数据或敏感值。
+- 风险与停止线:BLOCK-001至003和生产No-Go继续有效;第一实施任务仅允许“本地工程骨架 + Windows MySQL薄型样例”,禁止全量业务迁移和生产部署。
+- 队列编号:无(项目管理员汇总)
+- 下一责任人:产品与项目管理执行Gate P,冻结第一实施任务和本地范围
+
+## COLLAB-20260717-160 | COLLAB-150并发编号冲突更正与后端复评重新登记
+
+- 事件类型:事实源编号更正/结果关联
+- 发起时间:2026-07-18
+- 发起角色:项目管理员
+- 目标角色:Owner/产品与项目管理/后端开发/测试与质量/架构与数据治理
+- 上游事件:COLLAB-20260717-150(两个原始块)、151
+- 结果事件:COLLAB-20260717-151
+- 当前Gate:CRM-20260717-003 / Gate R整改复评
+- 状态:CLOSED
+- 冲突事实:并发写入产生两个原始`COLLAB-20260717-150`标题;按只追加规则保留历史,不覆盖或删除任一原始块。
+- 唯一裁决:标题为“测试正式会话故障迁移并恢复改密验收”的原始150继续作为CRM-006会话迁移事件;标题为“模块化单体方案后端同项复评”的原始150仅因编号冲突失效,其请求内容在本事件重新登记并以本事件编号为唯一引用。
+- 重新登记范围:在原QUEUE-035只读复评第一纵向链路Schema/API、Kysely与`mysql2/promise`迁移栈、Web本地HTTPS会话与CSRF、单写切流及可重复命令;禁止扩展或实现。
+- 完成证据:后端已在Thread `019f708a-ed37-72b0-887d-77a00f869701`、turn `019f70e4-c66f-7823-ae16-c3e4e31c52f6`回传PASS,结果事件仍为唯一的COLLAB-151。
+- 队列编号:QUEUE-20260717-035
+- 下一责任人:项目管理员按COLLAB-151和152继续Gate R收尾;后续引用不得再使用冲突的架构原始150
+
+## COLLAB-20260717-161 | 模块化单体方案产品Gate P验收
+
+- 事件类型:Gate P验收请求
+- 发起时间:2026-07-18
+- 发起角色:项目管理员
+- 目标角色:产品与项目管理/Owner
+- 上游事件:COLLAB-20260717-152
+- 结果事件:COLLAB-20260717-162
+- 当前Gate:CRM-20260717-003 / Gate P
+- 状态:QUEUED
+- 目标:对照冻结需求验收整体Gate R方案,确认本地优先、渐进迁移、Web/后续移动端边界及第一实施任务。
+- 输入:CRM-003任务目录、四份定稿方案、COLLAB-152整体Gate R PASS。
+- 范围:只读确认需求八项验收、方案范围和风险接受顺序;将第一实施任务冻结为“本地工程骨架 + Windows MySQL薄型样例”。
+- 不做项:不修改业务代码、配置、数据、部署或运行态;不实施工程/MySQL;不直接全量迁移业务;不部署生产;不替代专业Gate。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED;明确第一实施任务、不做项、残余风险、BLOCK-001至003和生产No-Go。
+- 敏感边界:不读取或输出真实凭据、客户数据、原始日志、完整请求响应或运行数据。
+- 调度说明:产品正式会话当前正在处理CRM-006 P0最小验收协调;本事件先入队,不发送、不抢占,待该turn结束并确认idle后再投递。
+- 队列编号:QUEUE-20260717-044
+- 下一责任人:产品与项目管理
+
+## COLLAB-20260718-001 | 旧日期段并发编号冲突总更正与后端复评重新登记
+
+- 事件类型:事实源编号更正/Gate R复评请求重新登记
+- 发起时间:2026-07-18
+- 发起角色:项目管理员
+- 目标角色:Owner/产品与项目管理/后端开发/测试与质量/架构与数据治理
+- 上游事件:两个原始COLLAB-20260717-150、两个原始COLLAB-20260717-151、COLLAB-20260717-160
+- 结果事件:COLLAB-20260718-002
+- 当前Gate:CRM-20260717-003 / Gate R整改复评
+- 状态:CLOSED
+- 冲突事实:产品会话迁移和项目管理员Gate R收尾并发写入,导致旧日期段原始150和151各出现两个标题;按只追加规则保留全部原始块,不覆盖、不删除。
+- 唯一裁决:旧日期段150和151中,两个“测试会话故障迁移”块继续作为CRM-006有效历史;两个“模块化单体方案后端复评/结果”块仅因编号冲突失效,分别由本事件和COLLAB-20260718-002重新登记。
+- 重新登记范围:在原QUEUE-035只读复评首链Schema/API、Kysely与`mysql2/promise`迁移栈、Web本地HTTPS会话与CSRF、单写切流和可重复命令;禁止扩展或实现。
+- 完成事实:后端复评已于Thread `019f708a-ed37-72b0-887d-77a00f869701`、turn `019f70e4-c66f-7823-ae16-c3e4e31c52f6`完成,结论PASS,实际diff为零。
+- 队列编号:QUEUE-20260717-035
+- 下一责任人:项目管理员引用COLLAB-20260718-002,不再引用冲突的旧日期段后端150/151
+
+## COLLAB-20260718-002 | 模块化单体方案后端同项复评结果重新登记
+
+- 事件类型:结果回传重新登记
+- 发起时间:2026-07-18
+- 发起角色:后端开发
+- 目标角色:Owner/产品与项目管理/项目管理员/架构与数据治理
+- 上游事件:COLLAB-20260717-100、113、COLLAB-20260718-001
+- 结果事件:无
+- 当前Gate:CRM-20260717-003 / Gate R整改复评
+- 状态:PASS
+- 范围:只读核对首链物理Schema/API、Kysely与`mysql2/promise`迁移栈、Web本地HTTPS会话与CSRF、单写切流及可重复命令。
+- 结论:PASS。COLLAB-100首轮五类后端缺口均已在方案级关闭,可作为CRM-003整体Gate R后端输入,不代表工程实现或上线通过。
+- 未执行项:未执行MySQL、迁移、恢复、切流或工程实现,未读取真实数据,未修改文件、配置、Git、部署或运行态。
+- 证据:Thread `019f708a-ed37-72b0-887d-77a00f869701`,turn `019f70e4-c66f-7823-ae16-c3e4e31c52f6`。
+- 队列编号:QUEUE-20260717-035
+- 下一责任人:项目管理员形成更正后的整体Gate R汇总
+
+## COLLAB-20260718-003 | 模块化单体方案整体Gate R汇总结果更正
+
+- 事件类型:Gate R汇总结果/事实源更正
+- 发起时间:2026-07-18
+- 发起角色:项目管理员
+- 目标角色:Owner/产品与项目管理/架构与数据治理及全部适用专业角色
+- 上游事件:COLLAB-20260717-104、113、143、144、145、COLLAB-20260718-002
+- 结果事件:无
+- 当前Gate:CRM-20260717-003 / Gate R整体汇总
+- 状态:PASS
+- 更正关系:取代COLLAB-20260717-152作为唯一整体Gate R引用;原152结论本身不变,但其旧日期段后端151上游编号存在歧义。
+- 前端无回归裁决:COLLAB-104保持PASS;COLLAB-113明确前端PASS项不回退,本次整改未改变前端目标边界,不重复创建同义评审。
+- 结论:PASS。架构113、前端104、后端20260718-002、安全143、测试144、运维145全部PASS,方案可进入产品Gate P;只代表方案冻结。
+- 未执行项:未实现工程、MySQL、Schema、脚本或业务迁移,未执行Gate C/D/A,未部署生产,未读取真实数据或敏感值。
+- 风险与停止线:BLOCK-001至003和生产No-Go继续有效;第一实施任务只允许“本地工程骨架 + Windows MySQL薄型样例”,禁止全量业务迁移和生产部署。
+- 队列编号:无(项目管理员汇总)
+- 下一责任人:产品与项目管理执行Gate P
+
+## COLLAB-20260718-004 | 模块化单体方案产品Gate P验收重新登记
+
+- 事件类型:Gate P验收请求/事实源更正
+- 发起时间:2026-07-18
+- 发起角色:项目管理员
+- 目标角色:产品与项目管理/Owner
+- 上游事件:COLLAB-20260718-003
+- 结果事件:COLLAB-20260718-005
+- 当前Gate:CRM-20260717-003 / Gate P
+- 状态:CLOSED
+- 更正关系:取代COLLAB-20260717-161作为产品Gate P唯一引用,避免继续使用发生并发冲突的旧日期编号段。
+- 范围:只读对照需求八项验收,确认本地优先、渐进迁移、Web/后续移动端边界和风险接受顺序;冻结第一实施任务为“本地工程骨架 + Windows MySQL薄型样例”。
+- 不做项:不修改业务代码、配置、数据、部署或运行态;不直接全量迁移业务;不部署生产;不替代专业Gate。
+- 验收:回传PASS/CHANGES_REQUESTED/BLOCKED,并明确第一实施任务、不做项、残余风险、BLOCK-001至003和生产No-Go。
+- 调度说明:CRM-006 P0最小验收协调turn已完成且产品正式会话恢复idle;QUEUE-044已取得唯一执行锁并投递。
+- 队列编号:QUEUE-20260717-044
+- 下一责任人:产品与项目管理
+
+## COLLAB-20260718-005 | 模块化单体方案产品Gate P验收结果
+
+- 事件类型:Gate P结果回传
+- 发起时间:2026-07-18
+- 发起角色:产品与项目管理
+- 目标角色:Owner/项目管理员/架构与数据治理及全部适用专业角色
+- 上游事件:COLLAB-20260718-003、004
+- 结果事件:无
+- 当前Gate:CRM-20260717-003 / Gate P
+- 状态:PASS
+- 目标:回传模块化单体方案八项产品验收与第一实施任务冻结结论。
+- 输入:CRM-003需求八项验收、四份定稿方案、COLLAB-20260718-003整体Gate R PASS。
+- 结论:PASS。八项验收全部通过;CRM-003方案阶段闭环,可建立独立的本地薄型样例实施任务,但不代表业务工程、Gate C/D/A、数据迁移、部署或上线通过。
+- 历史收口:COLLAB-20260717-161已由COLLAB-20260718-004取代,不再构成待办;QUEUE-044仅以20260718-004/005为当前有效引用。
+- 第一实施任务:冻结为“本地工程骨架 + Windows MySQL薄型样例”;只使用运行时生成的账号、客户和测试数据,不读取或复制现有`data/`业务数据。
+- 不做项:不直接实现或迁移完整首条业务链路,不做全量迁移或长期双写,不部署生产;真实字段映射、移动端平台/离线/推送和生产拓扑后置并另立任务。
+- 未完成与风险:MySQL、工程骨架、Schema、脚本、测试和恢复流程均尚未实际实现或执行;BLOCK-001至003继续有效,生产保持No-Go。
+- 证据:产品Thread `019f6ea8-234e-7450-80fd-edc7c8c5438b`,turn `019f7113-1adf-78a0-a7e8-957379dff74a`;本轮实际diff为零。
+- 队列编号:QUEUE-20260717-044
+- 下一责任人:项目管理员释放QUEUE-044;后续按独立任务登记本地薄型样例,不在CRM-003内直接实施
+
+## COLLAB-20260717-149 | 员工修改密码MVP隔离环境最小验收结果
+
+- 事件类型:Gate A结果回传
+- 发起时间:2026-07-18
+- 发起角色:测试与质量
+- 目标角色:Owner/产品与项目管理/项目管理员
+- 上游事件:COLLAB-20260717-148、150、151
+- 结果事件:无
+- 当前Gate:CRM-20260717-006 / Gate A隔离环境最小验收
+- 状态:PASS
+- 目标:回传Owner冻结的员工本人改密基本闭环在本地隔离条件下的最小验收结果。
+- 输入:冻结需求、前后端精确diff、开发自测、COLLAB-147 Gate C PASS及QUEUE-043。
+- 范围:前端7项静态契约检查;后端使用`createServer`、`127.0.0.1`随机端口和进程内虚构存储完成12项回环API检查。
+- 结论:PASS,共19/19项通过;首版在单进程、单写实例、虚构数据的本地隔离环境可用。短生命周期服务已关闭。
+- 验收摘要:入口/三字段/确认、当前密码、Unicode 8至64且不裁剪/规范化、新旧不同、仅本人、严格两字段、仅204成功、成功退出与新旧密码重登、错误/未知/离线失败关闭且无`localApi`、防重、停用、主管重置/停用兼容、同账号并发最多一次成功、写失败不发布和敏感值扫描均PASS。
+- 不做项:未读取或修改`data/`,未使用真实账号/客户数据,未修改文件、代码、配置、Git、部署或生产运行态;未测试真实浏览器E2E、真实文件持久化、多进程/多实例及延期项。
+- 闭环关系:COLLAB-148和测试迁移事件COLLAB-151据此视为CLOSED;COLLAB-150保留为首个替代会话故障历史,不作为验收证据。
+- 风险与停止线:现有明文密码、旧认证机制、`BLOCK-001`至`BLOCK-003`及生产`No-Go`继续有效;本结论不代表Gate D/P、部署或上线许可。
+- 证据:Thread `019f70f1-b6bd-7d82-9c43-d254c66f46b9`,turn `019f70f8-1e8a-7372-9cd2-e8683674ff2e`。
+- 队列编号:QUEUE-20260717-043
+- 下一责任人:项目管理员完成正式测试入口切换和队列释放;后续部署另行授权
diff --git "a/docs/\344\273\273\345\212\241/\347\273\237\344\270\200\350\256\241\345\210\222\345\217\260\350\264\246.md" "b/docs/\344\273\273\345\212\241/\347\273\237\344\270\200\350\256\241\345\210\222\345\217\260\350\264\246.md"
index 8bd5f63..59e2fbd 100644
--- "a/docs/\344\273\273\345\212\241/\347\273\237\344\270\200\350\256\241\345\210\222\345\217\260\350\264\246.md"
+++ "b/docs/\344\273\273\345\212\241/\347\273\237\344\270\200\350\256\241\345\210\222\345\217\260\350\264\246.md"
@@ -2,26 +2,26 @@
- 版本:v1.0
- 维护角色:产品与项目管理
-- 最后更新:2026-07-17 Asia/Shanghai
+- 最后更新:2026-07-18 Asia/Shanghai
## 当前目标
- 产品目标:把 SalesCRM 从单文件演示原型改造成安全、可维护、可测试、可部署的正式内部系统。
- 当前里程碑:研发治理基线封版、角色会话串行调度整改与P0安全整改准备。
-- 当前 Gate:CRM-20260717-008 Gate P `PASS`并本地完成;CRM-20260717-006仍在Gate N需求决策。
+- 当前 Gate:CRM-20260717-006隔离环境最小Gate A已PASS,第一阶段本地/隔离验收完成;CRM-003整体Gate R和产品Gate P均已PASS,方案阶段闭环。
- Go/No-Go:`No-Go`,P0账号/数据/Git历史风险未关闭前不得正式生产上线。
-- 当前唯一下一棒:Owner处理CRM-20260717-006待确认产品决策;后续跨角色任务由产品/项目管理员按新队列顺次投递。
+- 当前唯一下一棒:产品与项目管理按既有队列处理CRM-003 Gate P;CRM-006本轮不再增加评审,后续部署须另行授权,当前仍无正式线上授权。
## 活跃任务
| 优先级 | 任务编号 | 目标 | 当前状态 | 当前Gate | 下一责任人 | 需求目录/事件 |
| --- | --- | --- | --- | --- | --- | --- |
-| P0 | CRM-20260717-008 | 修复架构角色会话`Error submitting message`并迁移正式入口 | 本地完成 | Gate P-PASS | 项目管理员持续维护 | [任务目录](<./202607/0717-架构会话修复/导读.md>) |
-| P0 | CRM-20260717-007 | 防止协作消息打断角色任务,建立WIP=1持久队列和执行锁 | 本地完成 | Gate P-PASS | 产品/项目管理员持续执行 | [任务目录](<./202607/0717-会话串行调度/导读.md>) |
-| P0 | CRM-20260717-001 | 本地化研发体系并初始化角色会话 | 本地完成 | Gate P-PASS | Owner(Git基线) | [任务目录](<./202607/0717-研发体系本地化/导读.md>) |
+| P0 | CRM-20260717-008 | 修复架构角色会话`Error submitting message`并迁移正式入口 | 已提交并推送 | Gate P-PASS | 项目管理员持续维护 | [任务目录](<./202607/0717-架构会话修复/导读.md>) |
+| P0 | CRM-20260717-007 | 防止协作消息打断角色任务,建立WIP=1持久队列和执行锁 | 已提交并推送 | Gate P-PASS | 产品/项目管理员持续执行 | [任务目录](<./202607/0717-会话串行调度/导读.md>) |
+| P0 | CRM-20260717-001 | 本地化研发体系并初始化角色会话 | 已提交并推送 | Gate P-PASS | Owner/项目管理员维护Git基线 | [任务目录](<./202607/0717-研发体系本地化/导读.md>) |
| P0 | CRM-20260717-002 | 隔离Git中的运行数据和账号密码,完成轮换与历史治理 | 待Owner裁决 | Gate N | 产品/架构/安全 | [系统现状](<../架构/系统现状与改造路线.md>) |
-| P0 | CRM-20260717-006 | 员工登录后自主修改本人密码,安全与体验能力分期完善 | MVP需求待确认 | Gate N-需求整改 | Owner/产品与项目管理 | [任务目录](<./202607/0717-员工修改密码/导读.md>) |
-| P1 | CRM-20260717-003 | 前后端模块化重构并冻结目标技术架构 | 待登记需求 | Gate N | 产品/架构 | [系统现状](<../架构/系统现状与改造路线.md>) |
+| P0 | CRM-20260717-006 | 员工登录后自主修改本人密码,安全与体验能力分期完善 | 第一阶段前后端实现、自测、Gate C及隔离环境最小验收均PASS;本地/隔离可用,未部署 | Gate A-PASS(隔离) | Owner/项目管理员;部署另行授权 | [任务目录](<./202607/0717-员工修改密码/导读.md>) |
+| P1 | CRM-20260717-003 | 冻结面向Web与移动端的模块化单体、MySQL、本地环境和渐进迁移方案 | 整体Gate R和产品Gate P均PASS,方案阶段闭环;第一实施任务待独立登记 | Gate P-PASS | 项目管理员 | [任务目录](<./202607/0717-模块化单体架构方案/导读.md>) |
| P1 | CRM-20260717-004 | 建立自动化测试、质量门禁和最小CI | 待架构方案 | Gate N | 测试/架构 | [系统现状](<../架构/系统现状与改造路线.md>) |
| P1 | CRM-20260717-005 | 加固部署、HTTPS、最小权限、备份和恢复 | 待安全整改 | Gate N | 运维/架构 | [系统现状](<../架构/系统现状与改造路线.md>) |
@@ -42,6 +42,8 @@
| 2026-07-17 | 新增业务文档优先使用中文文件名 | Owner明确要求 | Owner | 新增文档 | 工具强制命名除外 |
| 2026-07-17 | 任务目录采用`MMDD-中文任务名`,不沿用参考体系英文slug | Owner中文命名要求与本项目本地化约定 | Owner/项目管理员 | 新建任务目录 | 外部工具强制英文时记录例外 |
| 2026-07-17 | 每个角色会话WIP=1,新协作消息必须先入持久队列,active/有锁时禁止投递 | Owner发现协作消息抢占导致原任务丢失 | Owner/项目管理员 | 全部角色会话和跨角色协作 | 首轮真实多任务串行完成后 |
+| 2026-07-17 | CRM-003采用MySQL、模块化单体、渐进迁移和本地优先;API面向Web与后续移动端 | Owner在正式架构会话确认方向并补充移动端范围 | Owner | 目标架构与后续工程改造 | Gate N/R方案完成后复核 |
+| 2026-07-17 | CRM-006先落地基本改密闭环,再分段迭代完善;避免重复评审和过度设计,以交付效率优先 | Owner在Gate R通过后明确要求“小需求不要小题大做” | Owner | CRM-20260717-006实现与后续迭代 | 范围或安全底线发生实质变化时 |
## 进展日志
@@ -58,7 +60,18 @@
- 调度冻结:CRM-20260717-007接入完成前,不向任何active角色会话发送新的CRM-006协作消息。
- 完成:8/8正式角色接入WIP=1串行调度;中断恢复演练保留并恢复原QUEUE-003,没有任务丢失。
- 完成:旧架构会话因`Error submitting message`停止新投递;新正式架构会话完成首次接入和第二次后续消息提交,均PASS,QUEUE-009已释放。
+- 完成:67份治理与会话修复Markdown已提交并推送到`origin/main`;并发队列编号冲突已纠正为架构QUEUE-009、产品QUEUE-010。
- 新增:Owner明确要求员工登录后可以自主修改密码,已登记`CRM-20260717-006`;当前只进入Gate N,不构成代码或线上变更授权。
- 首轮Gate N:后端、测试PASS;架构、设计、前端、安全CHANGES_REQUESTED。待Owner确认临时凭据交付、存量账号统一轮换、全会话撤销、停用账号和主管恢复规则。
- 需求收敛:Owner要求CRM-006先能用、再逐步好用;v0.2-MVP只保留员工本人改密闭环和主管原重置能力,密码哈希、强制轮换、临时凭据、完整会话撤销、限流与审计延期。
-- 下一棒:Owner确认CRM-006产品决策;产品/项目管理员按角色队列检查执行锁和会话状态后顺次派工。
+- 决策冻结:Owner接受首版8至64个字符且不强制复杂组合、修改成功后退出重登、保留主管原重置方式,并明确第一阶段只在隔离测试环境验证、暂不部署线上;需求升级并冻结为v0.3-MVP。
+- 下一棒:项目管理员按角色队列检查执行锁和会话状态后,串行派发CRM-006的六个Gate N复评项;Gate N通过前不修改业务代码。
+- Gate N闭环:六个专业角色复评及产品汇总均PASS,前端发现的密码请求边界矛盾已在同一队列项内关闭;只代表可进入Gate R。
+- Gate R启动:形成R-01至R-11统一冻结清单;架构、UI、前后端、安全、测试和测试环境运维按持久队列评审,全部PASS前业务实现保持0%。
+- Gate R首轮:架构、UI、后端、安全、运维PASS;前端和测试CHANGES_REQUESTED。主要问题是架构与后端接口路径、请求字段、成功响应、错误码和字符计数未形成唯一版本;前端QUEUE-024和测试QUEUE-027保持WAITING。
+- 契约收敛:架构COLLAB-087 PASS,v0.4唯一契约冻结为`POST /api/v1/me/password/change`、两字段严格请求、Unicode码点计数、204空响应和九个稳定错误码;待后端确认可实施。
+- 会话交接:后端和前端故障会话均按完整历史回读、同队列恢复、验收PASS、正式ID切换、旧会话归档的顺序完成;无任务丢失。
+- Gate R闭环:后端COLLAB-092、前端COLLAB-095、测试COLLAB-096均PASS;产品COLLAB-098确认七个专业角色最终均PASS、v0.4契约唯一、R-01至R-11无未决分歧。该时间点CRM-006实现仍为0%,未测试、未部署、不可上线。
+- CRM-006第一阶段闭环:前端QUEUE-039、后端QUEUE-040开发自测和一次独立Gate C均PASS;测试QUEUE-043使用虚构内存与回环短生命周期服务完成19/19项隔离验收,结论为首版本地/隔离可用。未部署、Gate D/P未执行,生产No-Go继续有效。
+- CRM-003 Gate R闭环:架构COLLAB-113、前端COLLAB-104、后端COLLAB-20260718-002、安全COLLAB-143、测试COLLAB-144、运维COLLAB-145均PASS;COLLAB-20260718-003为更正后的唯一整体Gate R PASS。前端依据COLLAB-104及COLLAB-113“不回退PASS项”作项目级无回归裁决,不重复创建同义评审。
+- CRM-003 Gate P闭环:COLLAB-20260718-005 PASS;第一实施任务冻结为“本地工程骨架 + Windows MySQL薄型样例”,只用生成数据,并须另立任务。BLOCK-001至003和生产No-Go继续有效。
diff --git "a/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/UI\344\270\216\344\272\244\344\272\222\350\256\276\350\256\241.md" "b/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/UI\344\270\216\344\272\244\344\272\222\350\256\276\350\256\241.md"
index 3100323..1e8f6ba 100644
--- "a/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/UI\344\270\216\344\272\244\344\272\222\350\256\276\350\256\241.md"
+++ "b/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/UI\344\270\216\344\272\244\344\272\222\350\256\276\350\256\241.md"
@@ -1,11 +1,14 @@
# UI与交互设计任务队列
-- Thread ID:`019f6f41-7c33-7200-97b4-5bb4690de8c2`
+- Thread ID:`019f6fa9-44a2-7313-892d-886b43af1be9`
- WIP上限:`1`
- 执行锁:`IDLE`
- 当前队列项:无
-- 最后检查点:2026-07-17,旧会话投递异常后由新正式会话恢复同一QUEUE-003,PASS并完成回传
+- 最后检查点:2026-07-17,QUEUE-023交互Gate R PASS并回传COLLAB-078,执行锁已释放
| 顺序 | 队列编号 | 任务/事件 | 优先级 | 状态 | 入队时间 | 验收 |
| --- | --- | --- | --- | --- | --- | --- |
| 1 | `QUEUE-20260717-003` | `CRM-20260717-007 / COLLAB-20260717-041` | P0 | COMPLETED | 2026-07-17 | PASS;验证中断保留原锁并由新正式会话恢复同一项 |
+| 2 | `QUEUE-20260717-013` | `CRM-20260717-006 / COLLAB-20260717-051` | P0 | COMPLETED | 2026-07-17 | PASS;最小入口、三字段对话框、状态和Gate R交互规格已明确 |
+| 3 | `QUEUE-20260717-020` | `CRM-20260717-008 / COLLAB-20260717-064` | P0 | COMPLETED | 2026-07-17 | PASS;3个旧turn全部读到分页末尾,QUEUE-003/013无遗漏,旧会话已归档 |
+| 4 | `QUEUE-20260717-023` | `CRM-20260717-006 / COLLAB-20260717-070` | P0 | COMPLETED | 2026-07-17 | PASS;入口、三字段表单、状态、移动端单列和无障碍规格已冻结 |
diff --git "a/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\344\272\247\345\223\201\344\270\216\351\241\271\347\233\256\347\256\241\347\220\206.md" "b/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\344\272\247\345\223\201\344\270\216\351\241\271\347\233\256\347\256\241\347\220\206.md"
index 0902dc0..5731d66 100644
--- "a/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\344\272\247\345\223\201\344\270\216\351\241\271\347\233\256\347\256\241\347\220\206.md"
+++ "b/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\344\272\247\345\223\201\344\270\216\351\241\271\347\233\256\347\256\241\347\220\206.md"
@@ -4,9 +4,16 @@
- WIP上限:`1`
- 执行锁:`IDLE`
- 当前队列项:无
-- 最后检查点:2026-07-17,QUEUE-20260717-009完成MVP需求收敛并回传COLLAB-20260717-046
+- 最后检查点:2026-07-18,COLLAB-20260718-005产品Gate P PASS,第一实施任务已冻结,QUEUE-044已释放
| 顺序 | 队列编号 | 任务/事件 | 优先级 | 状态 | 入队时间 | 验收 |
| --- | --- | --- | --- | --- | --- | --- |
| 1 | `QUEUE-20260717-001` | `CRM-20260717-007 / COLLAB-20260717-041` | P0 | COMPLETED | 2026-07-17 | PASS;调度算法可执行 |
-| 2 | `QUEUE-20260717-009` | `CRM-20260717-006 / COLLAB-20260717-045` | P0 | COMPLETED | 2026-07-17 | PASS;v0.2-MVP范围、10项验收、分期和4项Owner问题已明确 |
+| 2 | `QUEUE-20260717-010` | `CRM-20260717-006 / COLLAB-20260717-045` | P0 | COMPLETED | 2026-07-17 | PASS;v0.2-MVP范围、10项验收、分期和4项Owner问题已明确;结项时纠正并发占用的临时编号009 |
+| 3 | `QUEUE-20260717-011` | `CRM-20260717-006 / COLLAB-20260717-048` | P0 | COMPLETED | 2026-07-17 | PASS;v0.3-MVP四项Owner决策、10项验收和线上部署停止线已冻结 |
+| 4 | `QUEUE-20260717-019` | `CRM-20260717-006 / COLLAB-20260717-062` | P0 | COMPLETED | 2026-07-17 | PASS;六角色均PASS,矛盾关闭,Gate R统一入口清单已形成 |
+| 5 | `QUEUE-20260717-021` | `CRM-20260717-006 / COLLAB-20260717-067` | P0 | COMPLETED | 2026-07-17 | PASS;R-01至R-11统一清单、七角色责任和停止线已形成 |
+| 6 | `QUEUE-20260717-029` | `CRM-20260717-006 / COLLAB-20260717-084` | P0 | COMPLETED | 2026-07-17 | CHANGES_REQUESTED;5项PASS、2项待整改,唯一契约整改顺序已明确 |
+| 7 | `QUEUE-20260717-031` | `CRM-20260717-006 / COLLAB-20260717-088` | P0 | COMPLETED | 2026-07-17 | PASS;v0.4唯一契约、废止项和后端确认输入已同步 |
+| 8 | `QUEUE-20260717-033` | `CRM-20260717-006 / COLLAB-20260717-097` | P0 | COMPLETED | 2026-07-17 | PASS;七角色最终均PASS,v0.4唯一契约和R-01至R-11整体冻结 |
+| 9 | `QUEUE-20260717-044` | `CRM-20260717-003 / COLLAB-20260718-004、005` | P1 | COMPLETED | 2026-07-18 | PASS;第一实施任务冻结为本地工程骨架 + Windows MySQL薄型样例;不做全量迁移或生产部署 |
diff --git "a/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\344\273\243\347\240\201\345\256\241\346\240\270\344\270\216\345\256\211\345\205\250.md" "b/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\344\273\243\347\240\201\345\256\241\346\240\270\344\270\216\345\256\211\345\205\250.md"
index e045f3b..f9712d4 100644
--- "a/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\344\273\243\347\240\201\345\256\241\346\240\270\344\270\216\345\256\211\345\205\250.md"
+++ "b/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\344\273\243\347\240\201\345\256\241\346\240\270\344\270\216\345\256\211\345\205\250.md"
@@ -4,8 +4,12 @@
- WIP上限:`1`
- 执行锁:`IDLE`
- 当前队列项:无
-- 最后检查点:2026-07-17,QUEUE-20260717-006 PASS并完成回传
+- 最后检查点:2026-07-18,QUEUE-042一次独立Gate C PASS并回传COLLAB-147,允许进入隔离环境测试
| 顺序 | 队列编号 | 任务/事件 | 优先级 | 状态 | 入队时间 | 验收 |
| --- | --- | --- | --- | --- | --- | --- |
| 1 | `QUEUE-20260717-006` | `CRM-20260717-007 / COLLAB-20260717-041` | P0 | COMPLETED | 2026-07-17 | PASS;Gate C N/A确认,当前无任务丢失风险 |
+| 2 | `QUEUE-20260717-016` | `CRM-20260717-006 / COLLAB-20260717-054` | P0 | COMPLETED | 2026-07-17 | PASS;最低安全边界、延期风险、停止线和Gate C证据已列出 |
+| 3 | `QUEUE-20260717-026` | `CRM-20260717-006 / COLLAB-20260717-073` | P0 | COMPLETED | 2026-07-17 | PASS;最低安全边界、停止线和Gate C证据清单已冻结 |
+| 4 | `QUEUE-20260717-036` | `CRM-20260717-003 / COLLAB-20260717-101、140、143` | P1 | COMPLETED | 2026-07-17 | PASS;P1-01至P1-05全部关闭 |
+| 5 | `QUEUE-20260717-042` | `CRM-20260717-006 / COLLAB-20260717-146、147` | P0 | COMPLETED | 2026-07-17 | PASS;未发现阻塞首版Finding,允许进入隔离环境测试 |
diff --git "a/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\345\211\215\347\253\257\345\274\200\345\217\221.md" "b/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\345\211\215\347\253\257\345\274\200\345\217\221.md"
index c72ed08..53dbce5 100644
--- "a/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\345\211\215\347\253\257\345\274\200\345\217\221.md"
+++ "b/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\345\211\215\347\253\257\345\274\200\345\217\221.md"
@@ -1,11 +1,15 @@
# 前端开发任务队列
-- Thread ID:`019f6ea8-7abd-7ca2-8b6c-8e3e54cfd8b1`
+- Thread ID:`019f7097-ba42-7610-a05d-2d427d3027db`
- WIP上限:`1`
- 执行锁:`IDLE`
- 当前队列项:无
-- 最后检查点:2026-07-17,QUEUE-20260717-004 PASS并完成回传
+- 最后检查点:2026-07-17,新正式会话完成接管,QUEUE-039前端最小实现与自测PASS并回传COLLAB-133
| 顺序 | 队列编号 | 任务/事件 | 优先级 | 状态 | 入队时间 | 验收 |
| --- | --- | --- | --- | --- | --- | --- |
| 1 | `QUEUE-20260717-004` | `CRM-20260717-007 / COLLAB-20260717-041` | P0 | COMPLETED | 2026-07-17 | PASS;确认新消息只入队且中断恢复原项 |
+| 2 | `QUEUE-20260717-014` | `CRM-20260717-006 / COLLAB-20260717-052` | P0 | COMPLETED | 2026-07-17 | PASS;请求传输矛盾整改后复评通过,Gate R最小前端项已列出 |
+| 3 | `QUEUE-20260717-024` | `CRM-20260717-006 / COLLAB-20260717-071、093、094` | P0 | COMPLETED | 2026-07-17 | PASS;完整交接旧历史,v0.4接口、字符、响应、错误码、交互和自测输入全部关闭 |
+| 4 | `QUEUE-20260717-034` | `CRM-20260717-003 / COLLAB-20260717-099` | P1 | COMPLETED | 2026-07-17 | PASS;技术栈、目录、渐进迁移、多客户端契约和第一链路可实施 |
+| 5 | `QUEUE-20260717-039` | `CRM-20260717-006 / COLLAB-20260717-109、132、133` | P0 | COMPLETED | 2026-07-17 | PASS;完成账号入口、改密表单、专用请求、错误映射、退出和最小自测 |
diff --git "a/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\345\220\216\347\253\257\345\274\200\345\217\221.md" "b/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\345\220\216\347\253\257\345\274\200\345\217\221.md"
index 836fa83..6184597 100644
--- "a/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\345\220\216\347\253\257\345\274\200\345\217\221.md"
+++ "b/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\345\220\216\347\253\257\345\274\200\345\217\221.md"
@@ -1,11 +1,16 @@
# 后端开发任务队列
-- Thread ID:`019f6ea8-9633-7a82-9034-789ecc7888da`
+- Thread ID:`019f708a-ed37-72b0-887d-77a00f869701`
- WIP上限:`1`
- 执行锁:`IDLE`
- 当前队列项:无
-- 最后检查点:2026-07-17,QUEUE-20260717-005 PASS并完成回传
+- 最后检查点:2026-07-18,COLLAB-151复评PASS,QUEUE-035已释放;未执行工程实现
| 顺序 | 队列编号 | 任务/事件 | 优先级 | 状态 | 入队时间 | 验收 |
| --- | --- | --- | --- | --- | --- | --- |
| 1 | `QUEUE-20260717-005` | `CRM-20260717-007 / COLLAB-20260717-041` | P0 | COMPLETED | 2026-07-17 | PASS;确认中断恢复原项且禁止抢占 |
+| 2 | `QUEUE-20260717-015` | `CRM-20260717-006 / COLLAB-20260717-053` | P0 | COMPLETED | 2026-07-17 | PASS;后端范围可行,Gate R接口、原子性、并发和测试前置已列出 |
+| 3 | `QUEUE-20260717-025` | `CRM-20260717-006 / COLLAB-20260717-072` | P0 | COMPLETED | 2026-07-17 | PASS;后端接口、身份、校验、原子持久化、并发和自测方案已回传 |
+| 4 | `QUEUE-20260717-032` | `CRM-20260717-006 / COLLAB-20260717-090、091` | P0 | COMPLETED | 2026-07-17 | PASS;完整交接旧历史,v0.4唯一契约和当前单写实例可实施性确认完成 |
+| 5 | `QUEUE-20260717-035` | `CRM-20260717-003 / COLLAB-20260717-100、COLLAB-20260718-001、002` | P1 | COMPLETED | 2026-07-17 | PASS;20260718-001/002更正旧日期并发编号冲突,首链Schema/API、迁移栈、HTTPS会话/CSRF、单写切流和可重复命令缺口已在方案级关闭 |
+| 6 | `QUEUE-20260717-040` | `CRM-20260717-006 / COLLAB-20260717-110、130、131` | P0 | COMPLETED | 2026-07-17 | PASS;完成v0.4专用接口、校验、原子/CAS、错误码、主管兼容和虚构自测 |
diff --git "a/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\345\257\274\350\257\273.md" "b/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\345\257\274\350\257\273.md"
index 8b2604f..6410f4a 100644
--- "a/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\345\257\274\350\257\273.md"
+++ "b/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\345\257\274\350\257\273.md"
@@ -15,11 +15,11 @@
| --- | --- | --- | --- |
| 产品与项目管理 | `019f6ea8-234e-7450-80fd-edc7c8c5438b` | [产品与项目管理](<./产品与项目管理.md>) | 1 |
| 架构与数据治理 | `019f6f85-bee8-7f70-8d0a-af638ece0782` | [架构与数据治理](<./架构与数据治理.md>) | 1 |
-| UI与交互设计 | `019f6f41-7c33-7200-97b4-5bb4690de8c2` | [UI与交互设计](<./UI与交互设计.md>) | 1 |
-| 前端开发 | `019f6ea8-7abd-7ca2-8b6c-8e3e54cfd8b1` | [前端开发](<./前端开发.md>) | 1 |
-| 后端开发 | `019f6ea8-9633-7a82-9034-789ecc7888da` | [后端开发](<./后端开发.md>) | 1 |
+| UI与交互设计 | `019f6fa9-44a2-7313-892d-886b43af1be9` | [UI与交互设计](<./UI与交互设计.md>) | 1 |
+| 前端开发 | `019f7097-ba42-7610-a05d-2d427d3027db` | [前端开发](<./前端开发.md>) | 1 |
+| 后端开发 | `019f708a-ed37-72b0-887d-77a00f869701` | [后端开发](<./后端开发.md>) | 1 |
| 代码审核与安全 | `019f6ea8-b081-7121-9d98-4c9714bf50e1` | [代码审核与安全](<./代码审核与安全.md>) | 1 |
-| 测试与质量 | `019f6ea8-ca49-7472-9a9e-24848071c22b` | [测试与质量](<./测试与质量.md>) | 1 |
+| 测试与质量 | `019f70f1-b6bd-7d82-9c43-d254c66f46b9` | [测试与质量](<./测试与质量.md>) | 1 |
| 运维与发布 | `019f6ea8-ec46-70d2-9122-0968c7946c23` | [运维与发布](<./运维与发布.md>) | 1 |
备用或复验会话不拥有独立业务队列,只有Owner或项目管理员明确启用时才临时承接一个冻结任务,且不得与正式角色会话同时处理同一职责域的不同任务。
diff --git "a/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\346\236\266\346\236\204\344\270\216\346\225\260\346\215\256\346\262\273\347\220\206.md" "b/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\346\236\266\346\236\204\344\270\216\346\225\260\346\215\256\346\262\273\347\220\206.md"
index 588e544..f022eac 100644
--- "a/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\346\236\266\346\236\204\344\270\216\346\225\260\346\215\256\346\262\273\347\220\206.md"
+++ "b/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\346\236\266\346\236\204\344\270\216\346\225\260\346\215\256\346\262\273\347\220\206.md"
@@ -4,9 +4,14 @@
- WIP上限:`1`
- 执行锁:`IDLE`
- 当前队列项:无
-- 最后检查点:2026-07-17,QUEUE-20260717-009两次消息提交均PASS,迁移完成并释放执行锁
+- 最后检查点:2026-07-17,QUEUE-041一次性整改PASS并回传COLLAB-113,执行锁已释放
| 顺序 | 队列编号 | 任务/事件 | 优先级 | 状态 | 入队时间 | 验收 |
| --- | --- | --- | --- | --- | --- | --- |
| 1 | `QUEUE-20260717-002` | `CRM-20260717-007 / COLLAB-20260717-041` | P0 | COMPLETED | 2026-07-17 | PASS;状态机、双重检查和中断恢复无冲突 |
| 2 | `QUEUE-20260717-009` | `CRM-20260717-008 / COLLAB-20260717-043` | P0 | COMPLETED | 2026-07-17 | PASS;首次接入与第二次后续提交均正常完成 |
+| 3 | `QUEUE-20260717-012` | `CRM-20260717-006 / COLLAB-20260717-050` | P0 | COMPLETED | 2026-07-17 | PASS;当前架构可实现,Gate R最小接口、凭据边界、并发和回滚项已列出 |
+| 4 | `QUEUE-20260717-018` | `CRM-20260717-003 / COLLAB-20260717-056` | P1 | COMPLETED | 2026-07-17 | PASS;架构技术方案完成,跨角色Gate R和产品Gate P待后续调度 |
+| 5 | `QUEUE-20260717-022` | `CRM-20260717-006 / COLLAB-20260717-069` | P0 | COMPLETED | 2026-07-17 | PASS;架构接口、身份、原子更新、并发、重新认证和回滚方案已回传 |
+| 6 | `QUEUE-20260717-030` | `CRM-20260717-006 / COLLAB-20260717-086` | P0 | COMPLETED | 2026-07-17 | PASS;v0.4唯一接口、字段、Unicode计数、204响应和错误码已冻结 |
+| 7 | `QUEUE-20260717-041` | `CRM-20260717-003 / COLLAB-20260717-112` | P1 | COMPLETED | 2026-07-17 | PASS;四类CHANGES一次性映射到唯一修订,形成原队列同项复评材料 |
diff --git "a/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\346\265\213\350\257\225\344\270\216\350\264\250\351\207\217.md" "b/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\346\265\213\350\257\225\344\270\216\350\264\250\351\207\217.md"
index ae509fa..aa0f480 100644
--- "a/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\346\265\213\350\257\225\344\270\216\350\264\250\351\207\217.md"
+++ "b/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\346\265\213\350\257\225\344\270\216\350\264\250\351\207\217.md"
@@ -1,11 +1,15 @@
# 测试与质量任务队列
-- Thread ID:`019f6ea8-ca49-7472-9a9e-24848071c22b`
+- Thread ID:`019f70f1-b6bd-7d82-9c43-d254c66f46b9`
- WIP上限:`1`
- 执行锁:`IDLE`
- 当前队列项:无
-- 最后检查点:2026-07-17,QUEUE-20260717-007 PASS并完成回传
+- 最后检查点:2026-07-18,QUEUE-043隔离环境最小Gate A共19/19项PASS并回传COLLAB-149;短生命周期回环服务已关闭,未触碰运行数据或仓库状态
| 顺序 | 队列编号 | 任务/事件 | 优先级 | 状态 | 入队时间 | 验收 |
| --- | --- | --- | --- | --- | --- | --- |
| 1 | `QUEUE-20260717-007` | `CRM-20260717-007 / COLLAB-20260717-041` | P0 | COMPLETED | 2026-07-17 | PASS;7项标准可验证,Gate A N/A确认 |
+| 2 | `QUEUE-20260717-017` | `CRM-20260717-006 / COLLAB-20260717-055` | P0 | COMPLETED | 2026-07-17 | PASS;十项标准10/10可测,Gate R环境、样本和自动化前置已列出 |
+| 3 | `QUEUE-20260717-027` | `CRM-20260717-006 / COLLAB-20260717-074` | P0 | COMPLETED | 2026-07-17 | PASS;v0.4契约、十项矩阵、隔离环境、复位和计划自动化入口均可执行 |
+| 4 | `QUEUE-20260717-037` | `CRM-20260717-003 / COLLAB-20260717-102、141、144` | P1 | COMPLETED | 2026-07-17 | PASS;方案级测试入口、夹具、对账、恢复和保护规则全部关闭 |
+| 5 | `QUEUE-20260717-043` | `CRM-20260717-006 / COLLAB-20260717-148、149、151` | P0 | COMPLETED | 2026-07-18 | PASS;前端静态契约7项、回环内存API 12项,共19/19通过,首版隔离环境可用 |
diff --git "a/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\350\277\220\347\273\264\344\270\216\345\217\221\345\270\203.md" "b/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\350\277\220\347\273\264\344\270\216\345\217\221\345\270\203.md"
index 4ca5a6d..08b93ce 100644
--- "a/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\350\277\220\347\273\264\344\270\216\345\217\221\345\270\203.md"
+++ "b/docs/\344\273\273\345\212\241/\350\247\222\350\211\262\351\230\237\345\210\227/\350\277\220\347\273\264\344\270\216\345\217\221\345\270\203.md"
@@ -4,8 +4,10 @@
- WIP上限:`1`
- 执行锁:`IDLE`
- 当前队列项:无
-- 最后检查点:2026-07-17,QUEUE-20260717-008 PASS并完成回传
+- 最后检查点:2026-07-18,COLLAB-145复评PASS,QUEUE-038已释放;未执行Gate D或环境变更
| 顺序 | 队列编号 | 任务/事件 | 优先级 | 状态 | 入队时间 | 验收 |
| --- | --- | --- | --- | --- | --- | --- |
| 1 | `QUEUE-20260717-008` | `CRM-20260717-007 / COLLAB-20260717-041` | P0 | COMPLETED | 2026-07-17 | PASS;确认部署步骤不中断且恢复原项 |
+| 2 | `QUEUE-20260717-028` | `CRM-20260717-006 / COLLAB-20260717-075` | P0 | COMPLETED | 2026-07-17 | PASS;隔离测试环境、备份、复位、回滚和HTTPS停止线已冻结 |
+| 3 | `QUEUE-20260717-038` | `CRM-20260717-003 / COLLAB-20260717-103、142、145` | P1 | COMPLETED | 2026-07-17 | PASS;机械MySQL基线、健康、恢复Runbook和单写切流证据已在方案级关闭 |
diff --git "a/docs/\346\236\266\346\236\204/MySQL\346\225\260\346\215\256\344\270\216\346\270\220\350\277\233\350\277\201\347\247\273\346\226\271\346\241\210.md" "b/docs/\346\236\266\346\236\204/MySQL\346\225\260\346\215\256\344\270\216\346\270\220\350\277\233\350\277\201\347\247\273\346\226\271\346\241\210.md"
new file mode 100644
index 0000000..26cb70f
--- /dev/null
+++ "b/docs/\346\236\266\346\236\204/MySQL\346\225\260\346\215\256\344\270\216\346\270\220\350\277\233\350\277\201\347\247\273\346\226\271\346\241\210.md"
@@ -0,0 +1,227 @@
+# MySQL数据与渐进迁移方案
+
+- 任务:`CRM-20260717-003`
+- 状态:目标设计,尚未创建数据库、迁移脚本或种子数据
+- 范围:本地开发和验证;不读取或迁移当前真实业务数据,不授权生产迁移
+- 上位方案:[模块化单体目标架构方案](<./模块化单体目标架构方案.md>)
+
+## 1. 数据目标与原则
+
+MySQL是新架构唯一目标业务数据库,使用InnoDB事务和`utf8mb4`字符集。JSON只在渐进迁移期作为未迁移模块的旧事实源,不发展为缓存、消息队列或长期备库。
+
+核心原则:
+
+- 一个业务模块在任意时刻只有一个权威写入源,禁止JSON/MySQL长期双写。
+- Schema修改必须由版本化迁移完成,禁止依赖开发者手工改表。
+- 种子和夹具只使用生成或脱敏的最小数据,禁止复制`data/`真实内容进源码、文档或Git。
+- 迁移先可重复导入和核验,再切写入;失败优先前滚,数据反向迁移必须单独评审。
+- 业务事务与模块边界一致;跨模块只在确有原子业务不变量时共享同一MySQL事务。
+
+## 2. Schema通用规范
+
+### 2.1 类型与命名
+
+| 数据 | 约定 | 原因 |
+| --- | --- | --- |
+| 主键 | `BIGINT UNSIGNED`,API中序列化为字符串 | 数据库高效,避免JavaScript/移动语言整数精度差异 |
+| 旧标识 | 独立`legacy_id`或映射表,唯一索引 | 保留迁移追溯,不污染新主键语义 |
+| 时间戳 | `DATETIME(3)`,按UTC写入 | 精确、无会话时区歧义;API统一输出RFC 3339 `Z` |
+| 纯日期 | `DATE` | 生日、计划日等不应被时区偏移 |
+| 金额 | `DECIMAL(18,2)`,API输出十进制字符串 | 禁止二进制浮点误差 |
+| 状态 | 受应用与检查约束的短字符串 | 比MySQL `ENUM`更便于渐进扩展和跨客户端契约 |
+| 文本 | 明确长度的`VARCHAR`或有边界的`TEXT` | 避免无差别大字段 |
+| JSON列 | 仅扩展元数据或审计上下文 | 核心关系、金额和状态不能藏入JSON列 |
+| 并发 | `version`整数,更新时比较并递增 | 支持乐观锁和API条件更新 |
+| 生命周期 | `created_at`、`updated_at`,按需`deleted_at` | 软删除仅用于有恢复/审计需求的实体 |
+
+表、列和索引使用`snake_case`;外键命名`fk_<子表>_<父表>`,唯一索引`uq_<表>_<列>`,普通索引`ix_<表>_<列>`。所有外键动作必须显式选择,业务主数据默认`RESTRICT`,禁止未评估的级联删除。
+
+### 2.2 首期逻辑Schema
+
+首条纵向链路至少需要:
+
+| 表组 | 建议表 | 关键约束 |
+| --- | --- | --- |
+| 身份 | `users`、`password_credentials` | 登录名规范化后唯一;凭据与用户资料隔离;保存哈希算法/参数版本 |
+| 权限 | `roles`、`permissions`、`user_roles`、`role_permissions` | 权限代码唯一;后端按动作计算有效权限 |
+| Web会话 | `web_sessions` | 只存会话标识摘要、用户、过期/撤销时间和必要安全元数据 |
+| 移动令牌 | `mobile_refresh_tokens` | 后续激活;只存刷新令牌摘要、族、轮换/撤销状态,不存明文 |
+| 客户 | `customers`、`customer_contacts`、`customer_assignments` | 客户业务唯一键需产品确认;归属变化可追溯 |
+| 跟进 | `customer_followups`、`customer_actions` | 必须关联客户和操作者;时间线记录稳定动作类型 |
+| 审计 | `audit_events` | 只记录动作、实体标识、结果和最小上下文,不记录敏感原文 |
+| 幂等 | `idempotency_keys` | `(主体, 路由, key)`唯一;保存请求摘要、状态和受控响应摘要 |
+| 迁移 | `migration_batches`、`migration_mappings`、`migration_rejects` | 批次状态、旧新ID映射、拒绝原因可追溯 |
+
+后续模块按拥有关系增加`quotes`、`sales_orders`、`sales_order_items`、`production_tasks`、`inventory_items`、`inventory_movements`、`shipments`、`receivables`、`receipts`等表。具体字段必须从脱敏数据字典和业务验收反推,不能照搬旧JSON全部字段。
+
+## 3. 迁移文件与执行纪律
+
+- 迁移文件使用单调递增版本与中文任务无关的稳定英文标识,例如`0001_identity_base`;提交后不得修改已应用文件。
+- 迁移元数据表记录版本、校验和、执行时间和执行结果。校验和变化应中止,而不是静默重跑。
+- 空库必须能从零依次升级到当前版本;至少保留一个已发布本地基线到当前版本的升级测试。
+- 破坏性修改采用expand/contract:先加兼容字段或表,回填并验证,切换读写,最后在独立任务中删除旧结构。
+- DDL和大批量数据变更分开;数据迁移按可恢复批次提交,不能把不可控全表变更塞进应用启动。
+- 回退优先用新的前滚修复迁移。只有经过验证的可逆DDL才提供`down`,不能假装所有数据变换都可逆。
+- 应用启动不自动修改业务Schema;本地由明确的迁移命令执行,测试环境由测试夹具显式执行。
+
+查询与迁移技术栈唯一冻结为Kysely、`mysql2/promise`和Kysely Migrator。Repository只暴露领域所需查询;迁移文件只追加并由项目自有迁移元数据表记录文件名、SHA-256校验和、开始/结束时间和结果。不得并存第二套ORM、自动同步Schema或应用启动隐式迁移。
+
+## 4. 种子与测试数据
+
+种子分为两类:
+
+1. **结构种子**:权限代码、系统角色等稳定参考数据,按自然键`upsert`且重复执行结果一致;删除和权限缩减必须单独迁移。
+2. **演示夹具**:本地开发用的生成用户、客户和跟进数据,只能进入开发/测试库,不得在任何环境自动创建可预测的正式账号。
+
+种子不得包含真实姓名、电话、客户、密码、Token、Cookie或从原始日志复制的请求响应。测试密码由运行时测试工具生成或从Git忽略的本机配置提供,文档和Git只保留占位符。
+
+## 5. 事务边界
+
+| 用例 | 同一事务内必须完成 | 事务外动作 |
+| --- | --- | --- |
+| 创建客户 | 客户、初始联系人、归属、客户动作 | 通知或非关键统计 |
+| 新增跟进 | 跟进、客户最近跟进时间/版本、时间线、审计最小事件 | 外部提醒推送 |
+| 创建订单 | 订单、订单行、金额汇总、客户关联 | 报表刷新 |
+| 确认出库 | 库存流水、可用量版本、发货准备状态 | 物流外部调用 |
+| 登记收款 | 收款、核销、应收余额、业务审计 | 非关键通知 |
+
+应用服务开启事务并把事务上下文传给Repository;Repository不得自行提交导致半成功。事务内不得执行不受控网络调用。需要事务后动作时,首期可使用同库`outbox_events`表,由同进程任务在提交后处理;只有出现真实吞吐或隔离需求后才评估外部消息系统。
+
+死锁和锁等待按有限次数重试,重试必须结合幂等键或乐观锁。业务冲突返回稳定错误,不用“最后写入覆盖”掩盖并发修改。
+
+## 6. JSON到MySQL渐进迁移
+
+### 6.1 前置条件
+
+- 先由数据治理任务给出脱敏数据字典、字段分类、合法性规则和可用于测试的夹具;本方案不直接读取当前`data/`。
+- 明确目标模块的所有旧写入口、定时任务和浏览器本地降级路径。
+- 建立迁移批次、旧新ID映射、拒绝记录和聚合校验,不把包含业务原文的逐行转储写入普通日志。
+- 切流前完成可恢复备份并实际验证恢复,不以“文件存在”代替恢复证据。
+
+### 6.2 每个模块的迁移步骤
+
+1. **盘点**:根据脱敏字典冻结字段映射、默认值、枚举映射、唯一键、外键和拒绝规则。
+2. **建表**:应用只追加迁移,在空库和测试升级路径验证。
+3. **导入器**:按`migration_batch_id`和`legacy_id`幂等写入;同一输入重复运行不得产生重复实体。
+4. **影子导入**:旧系统仍读写JSON;MySQL只接受受控导入,用聚合数据对账,不对客户端提供结果。
+5. **校验**:比较实体数、按状态分组数、金额/数量聚合、空值/日期范围、映射覆盖和拒绝数;敏感字段只比较摘要或规则结果。
+6. **冻结写入**:在本地停止目标模块旧写入,执行最终增量导入并复核。
+7. **切流**:新API读写MySQL,关闭旧模块写入口;其他未迁移模块继续使用JSON。
+8. **观察与恢复演练**:运行契约、权限、E2E和重复导入测试,验证应用路由恢复与数据库恢复。
+9. **关闭回滚窗口**:只有证据通过后才能标记模块`RETIRED`并另行清理旧实现。
+
+### 6.3 一致性校验清单
+
+- 输入记录数 = 成功映射数 + 明确拒绝数,差额必须为零。
+- 每个外键引用都有映射;孤儿记录必须停止,不可静默丢弃。
+- 唯一键冲突有可解释规则;不得自动合并疑似同名客户。
+- 金额、数量和状态分组聚合在约定精度内一致。
+- UTC时间转换和纯日期字段抽样边界正确。
+- 导入器重复执行结果一致,批次中断后可从检查点恢复。
+- 迁移后权限结果与基线矩阵一致。
+
+### 6.4 停止线
+
+遇到下列任一情况不得切流或必须立即停止:
+
+- 校验差额非零或拒绝记录没有Owner/产品认可的处置;
+- 唯一键、外键、金额、状态或时间转换存在未解释差异;
+- 旧系统仍能写目标模块,或发现浏览器`localStorage`继续形成业务事实;
+- 迁移脚本不可幂等、无法从中断恢复或生成不可追溯的默认值;
+- 备份恢复未验证,或者迁移证据包含凭据、客户原文、原始日志;
+- BLOCK-001至003或正式上线`No-Go`被误解为已经解除。
+
+## 7. 备份与恢复
+
+本地开发库备份放在仓库之外的受控目录,文件名只含环境、时间和迁移批次,不含客户或账号信息。建议使用MySQL官方客户端的事务一致性导出能力;命令从Git忽略的本机连接配置读取凭据,文档不保存具体值。
+
+每次破坏性迁移演练至少验证:
+
+1. 从空库执行全部迁移与结构种子;
+2. 从迁移前备份恢复到独立数据库;
+3. 恢复后运行结构校验、聚合校验和首条纵向链路;
+4. 记录工具版本、迁移版本、开始/结束时间和PASS/FAIL,不记录敏感输出。
+
+当前本机尚未验证MySQL客户端或服务可用,以上均为待实施流程,不能记录为已完成备份或恢复。
+
+## 8. 数据回滚决策
+
+- **切流前失败**:清理失败的测试库或标记批次失败,修复映射后重新执行;JSON仍为事实源。
+- **切流后、无新写入**:关闭新入口,路由退回JSON,保留MySQL批次和证据。
+- **切流后、已有新写入**:JSON已经落后,禁止直接退回。优先修复应用并前滚;若必须恢复旧应用,应让旧应用临时读取MySQL兼容接口,或建立经评审的反迁移任务。
+- **生产环境**:本方案没有生产执行授权,不能把上述本地步骤直接当成生产Runbook。
+
+## 9. 未决项
+
+- 现有JSON字段映射、合法性和去重规则必须等脱敏数据字典,不在本方案中猜测。
+- 客户业务唯一键、数据保留期、软删除恢复期、审计保留与清理规则需产品、架构、安全共同确认。
+- 附件/图片等二进制存储若进入范围,应另立方案,不写入核心业务表或Git。
+
+MySQL版本与查询/迁移库已冻结为MySQL Community Server 8.4.10 LTS、Kysely、`mysql2/promise`和Kysely Migrator;npm包精确补丁版本由首个实施任务的`package-lock.json`固定。
+
+## 10. 首链物理Schema v1
+
+以下字段是首条纵向链路的最小物理边界。所有表使用InnoDB、`utf8mb4_0900_ai_ci`,时间按UTC写入`DATETIME(3)`;登录规范化字段使用区分规则明确的唯一索引。未列字段不得在实现时临时扩张。
+
+| 表 | 最小字段 | 关键约束与索引 |
+| --- | --- | --- |
+| `users` | `id BIGINT UNSIGNED`、`legacy_id VARCHAR(128) NULL`、`username VARCHAR(128)`、`username_normalized VARCHAR(128)`、`display_name VARCHAR(128)`、`status VARCHAR(32)`、`auth_version BIGINT UNSIGNED`、`permission_version BIGINT UNSIGNED`、`version BIGINT UNSIGNED`、创建/更新时间 | PK `id`;`username_normalized`唯一;`legacy_id`唯一且可空;`status`只允许`active/disabled`;版本初值1 |
+| `password_credentials` | `user_id`、`password_hash VARCHAR(255)`、`algorithm VARCHAR(32)`、`parameters_json JSON`、`changed_at`、`version` | `user_id`为PK/FK;只保存强哈希及参数版本;禁止明文、可逆密文和可推导会话值 |
+| `roles` | `id BIGINT UNSIGNED`、`code VARCHAR(64)`、`name VARCHAR(128)` | PK `id`;`code`唯一 |
+| `permissions` | `id BIGINT UNSIGNED`、`code VARCHAR(128)`、`name VARCHAR(128)` | PK `id`;`code`唯一;首链至少包含`customer.read`、`followup.read`、`followup.create` |
+| `user_roles` | `user_id BIGINT UNSIGNED`、`role_id BIGINT UNSIGNED` | 复合PK;双向外键 |
+| `role_permissions` | `role_id BIGINT UNSIGNED`、`permission_id BIGINT UNSIGNED` | 复合PK;双向外键 |
+| `web_sessions` | `session_id_hash BINARY(32)`、`user_id BIGINT UNSIGNED NULL`、`state VARCHAR(16)`、`auth_version BIGINT UNSIGNED NULL`、`permission_version BIGINT UNSIGNED NULL`、`csrf_token_hash BINARY(32)`、`created_at`、`last_seen_at`、`idle_expires_at`、`absolute_expires_at`、`revoked_at` | 会话摘要PK;`state`只允许`anonymous/authenticated/revoked`;匿名CSRF会话无用户,登录成功必须换新会话标识;按用户与撤销/过期索引;不保存会话或CSRF明文 |
+| `customers` | `id BIGINT UNSIGNED`、`legacy_id VARCHAR(128) NULL`、`name VARCHAR(255)`、`status VARCHAR(32)`、`owner_user_id BIGINT UNSIGNED`、`last_followup_at DATETIME(3) NULL`、`next_action_at DATETIME(3) NULL`、`version BIGINT UNSIGNED`、创建/更新/删除时间 | PK `id`;`legacy_id`唯一可空;owner FK;列表索引`(owner_user_id,status,updated_at,id)`;`version`初值1 |
+| `customer_contacts` | `id BIGINT UNSIGNED`、`customer_id BIGINT UNSIGNED`、`type VARCHAR(32)`、`value_protected VARBINARY(512)`、`is_primary BOOLEAN`、创建/更新时间 | PK `id`;customer FK;联系值按数据分类加密/脱敏,列表响应不默认返回原值 |
+| `customer_followups` | `id BIGINT UNSIGNED`、`customer_id BIGINT UNSIGNED`、`author_user_id BIGINT UNSIGNED`、`followup_type VARCHAR(32)`、`content TEXT`、`occurred_at DATETIME(3)`、`next_action_at DATETIME(3) NULL`、`created_at DATETIME(3)` | PK `id`;customer/author FK;分页索引`(customer_id,occurred_at,id)`;类型由受控字典校验 |
+| `customer_actions` | `id BIGINT UNSIGNED`、`customer_id BIGINT UNSIGNED`、`actor_user_id BIGINT UNSIGNED`、`action_type VARCHAR(64)`、`entity_type VARCHAR(64)`、`entity_id BIGINT UNSIGNED NULL`、`occurred_at DATETIME(3)`、`metadata_json JSON` | PK `id`;customer/actor FK;时间线索引`(customer_id,occurred_at,id)`;metadata禁止放凭据和客户原文快照 |
+| `idempotency_keys` | `subject_user_id BIGINT UNSIGNED`、`route_code VARCHAR(128)`、`key_hash BINARY(32)`、`request_hash BINARY(32)`、`state VARCHAR(16)`、`http_status SMALLINT UNSIGNED NULL`、`resource_type VARCHAR(64) NULL`、`resource_id BIGINT UNSIGNED NULL`、`expires_at DATETIME(3)`、创建/更新时间 | `(subject_user_id,route_code,key_hash)`唯一;同键异请求返回冲突 |
+| `audit_events` | `id BIGINT UNSIGNED`、`actor_user_id BIGINT UNSIGNED NULL`、`action_code VARCHAR(128)`、`entity_type VARCHAR(64)`、`entity_id VARCHAR(128)`、`result_code VARCHAR(64)`、`request_id VARCHAR(64)`、`occurred_at DATETIME(3)`、`context_json JSON` | PK `id`;按实体/时间和操作者/时间索引;context只存白名单摘要 |
+| `migration_batches` | `id BIGINT UNSIGNED`、`source_code VARCHAR(64)`、`module_code VARCHAR(64)`、`input_fingerprint BINARY(32)`、`status VARCHAR(16)`、计数字段、开始/结束时间 | PK `id`;批次ID唯一;计数必须闭合 |
+| `migration_mappings` | `batch_id BIGINT UNSIGNED`、`source_code VARCHAR(64)`、`entity_type VARCHAR(64)`、`legacy_id VARCHAR(128)`、`new_id BIGINT UNSIGNED` | `(source_code,entity_type,legacy_id)`唯一;batch FK |
+| `migration_rejects` | `batch_id BIGINT UNSIGNED`、`entity_type VARCHAR(64)`、`legacy_id_hmac BINARY(32)`、`reason_code VARCHAR(64)`、`occurred_at DATETIME(3)` | 只存隔离密钥HMAC或非识别性结果,不存客户原文 |
+| `environment_guard` | `environment_code VARCHAR(16)`、`instance_id CHAR(36)`、`created_at DATETIME(3)` | 单行表;本地库为`local`,测试/迁移库为`test`;所有破坏性脚本先校验 |
+
+首个实现任务只创建身份、权限、会话、客户、跟进、动作、幂等、审计和迁移元数据表;报价、订单、库存等后续表不得提前空建。
+
+## 11. 首链事务与并发
+
+`POST /api/v1/customers/{customerId}/followups`使用一个MySQL事务:
+
+1. 以认证主体、路由和`Idempotency-Key`摘要插入`idempotency_keys`的`processing`记录;唯一冲突时比较请求摘要并返回第一次结果或`IDEMPOTENCY_CONFLICT`。
+2. 读取客户并校验后端权限与数据范围;用`version`条件更新,禁止只信客户端owner或权限字段。
+3. 插入`customer_followups`。
+4. 更新`customers.last_followup_at`和请求给出的`next_action_at`并递增`version`。
+5. 插入`customer_actions`和最小`audit_events`。
+6. 将幂等记录改为`completed`并提交。任一步失败全部回滚。
+
+事务隔离级别使用MySQL默认`REPEATABLE READ`,写冲突通过唯一键、条件版本和有限死锁重试处理;自动重试最多2次且必须复用同一幂等键。权限拒绝、版本冲突和业务校验失败不得重试。
+
+账号停用、权限回收、密码变化和管理员撤销在相同事务中递增`auth_version`或`permission_version`并撤销相关Web会话;首期API每个请求读取服务端权威版本,不启用权限缓存,因此生效延迟不得超过数据库事务提交到下一请求。
+
+## 12. 迁移夹具与脱敏对账协议
+
+### 12.1 最小异常夹具
+
+迁移测试必须包含:重复旧ID、孤儿外键、唯一冲突、非法状态、必填空值、超长文本、非法日期、UTC边界、金额精度边界、中断批次和明确拒绝记录。每类至少一条生成记录,且禁止从当前`data/`复制。
+
+### 12.2 对账报告
+
+每个批次只输出以下脱敏字段:`runId`、`batchId`、`moduleCode`、输入数、成功数、拒绝数、映射覆盖数、孤儿数、按状态聚合、金额/数量聚合、迁移文件校验和、输入指纹、备份快照ID和最终`PASS/FAIL`。必须满足输入数等于成功数加拒绝数,差额为零。
+
+手机号、邮箱、账号等低熵字段禁止使用普通哈希作对账标识。优先比较数量、规则结果和聚合;确需稳定关联时使用HMAC-SHA-256,密钥`MIGRATION_HMAC_KEY`仅存在Git忽略的本地配置,与会话、CSRF、数据库密码完全隔离并支持轮换。报告、拒绝表和测试证据不得保存原文。
+
+## 13. 单写切流机械协议
+
+- 唯一配置:`docs/local/环境/module-routing.local.json`,由JSON Schema校验并以临时文件加原子替换更新。
+- 唯一操作者:当前实施任务的后端责任人执行,测试责任人见证并记录`runId`;任何页面不得修改该文件。
+- 旧Node和新Fastify只在启动时加载;配置缺失、未知模块、非法状态或两个写端同时启用时拒绝启动。
+- 旧Node必须为客户、跟进及相关通用写路由增加模块写守卫;新Fastify也必须在应用服务入口检查权威源。只在前端隐藏按钮不算关闭证据。
+- 切流步骤固定为:停止两端写服务 → 备份与恢复预检 → 最终迁移/对账 → 原子替换路由配置 → 启动MySQL权威端 → `/health/ready`验证迁移版本和模块权威源 → 启动旧端只读/未迁移模块 → 运行负向写入测试与首链E2E。
+- 关闭证据只记录配置摘要、两个进程启动结果、权威源、旧写路由拒绝计数和测试结论,不保存请求体或业务原文。
+- MySQL已有新写入后,只允许应用版本前滚或兼容读取MySQL;数据回退JSON必须另立反迁移任务并经架构、数据、安全和测试批准。
+
+## 14. 数据库防误操作
+
+三个库都必须存在`environment_guard`单行表,记录固定环境代码和随机实例ID。任何迁移、种子、清理、恢复脚本在执行前同时校验:`APP_ENV`、允许的数据库名、回环主机、`environment_guard`环境代码和显式命令确认。任一不匹配立即非零退出;测试脚本不得接受通配数据库名或生产地址覆盖参数。
diff --git "a/docs/\346\236\266\346\236\204/\345\244\232\345\256\242\346\210\267\347\253\257API\344\270\216\350\256\244\350\257\201\345\245\221\347\272\246.md" "b/docs/\346\236\266\346\236\204/\345\244\232\345\256\242\346\210\267\347\253\257API\344\270\216\350\256\244\350\257\201\345\245\221\347\272\246.md"
new file mode 100644
index 0000000..812dad2
--- /dev/null
+++ "b/docs/\346\236\266\346\236\204/\345\244\232\345\256\242\346\210\267\347\253\257API\344\270\216\350\256\244\350\257\201\345\245\221\347\272\246.md"
@@ -0,0 +1,213 @@
+# 多客户端API与认证契约
+
+- 任务:`CRM-20260717-003`
+- 状态:Gate R整改定稿,尚未实现
+- 客户端:当前Web与后续移动端
+- 上位方案:[模块化单体目标架构方案](<./模块化单体目标架构方案.md>)
+
+## 1. 设计目标
+
+API表达业务资源和动作,不表达某个Web页面的表单、标签页或浏览器存储。Web与移动端共享业务语义、授权模型、错误码、数据格式和幂等规则,仅认证凭据的安全传输与本机存储方式不同。
+
+禁止事项:
+
+- 不在URL、查询参数、响应或日志中传递Token、密码或Cookie。
+- 不让客户端提交`kind + 任意patch`来选择数据库实体或字段。
+- 不返回完整数据库对象、全量业务状态或页面专用组合包。
+- 不把前端隐藏按钮当作权限控制,不因移动端暂未实现而省略契约兼容。
+- 不以`localStorage`、设备数据库或页面缓存作为服务端业务事实源。
+
+## 2. 版本和路径
+
+- 所有新业务接口使用`/api/v1`前缀,例如`GET /api/v1/customers`。
+- `v1`内允许新增可选字段、可选查询参数和新端点;删除字段、改变含义、收紧原有合法输入或改变认证语义属于破坏性变更。
+- 破坏性变更建立`/api/v2`并提供明确并行期。弃用通过文档、响应`Deprecation`/`Sunset`等元数据和客户端构建告警传达,不能静默替换。
+- OpenAPI 3.1定义是外部协议事实源。API响应校验、Web生成类型和未来移动端客户端均从同一版本生成。
+- 契约版本与应用发布版本分开;修复实现不自动提升API大版本。
+- 唯一契约源位于`packages/contracts/src/`,使用TypeBox定义请求、响应和错误Schema;Fastify直接消费同一Schema并生成`packages/contracts/openapi/openapi.json`。
+- Web客户端由同一OpenAPI生成到`apps/web/src/generated/api/`。源Schema可编辑,OpenAPI和客户端均为生成物,不得手工修改;生成物随代码提交并由差异检查阻止漂移。
+- 实现阶段固定提供`npm run contract:generate`和`npm run test:contract`;后者必须先生成到临时目录,再与已提交产物比较,并执行OpenAPI语法、破坏性变更和服务端Schema一致性检查,任一失败非零退出。
+
+## 3. 资源与动作
+
+首条纵向链路冻结如下,不再提供同义备选路径:
+
+| 方法与路径 | 语义 | 权限动作 |
+| --- | --- | --- |
+| `GET /api/v1/auth/csrf` | 建立或读取Web会话绑定的CSRF令牌 | 匿名可调用,受速率限制,不创建已认证身份 |
+| `POST /api/v1/web-sessions` | Web登录并建立Cookie会话 | 匿名可调用,受速率限制 |
+| `DELETE /api/v1/web-sessions/current` | 注销当前Web会话 | 已认证 |
+| `GET /api/v1/me` | 当前身份、角色和有效权限摘要 | 已认证 |
+| `GET /api/v1/customers` | 授权范围内的客户游标分页列表 | `customer.read` |
+| `GET /api/v1/customers/{customerId}` | 客户详情 | `customer.read`并校验数据范围 |
+| `GET /api/v1/customers/{customerId}/followups` | 跟进游标分页 | `followup.read`并校验客户范围 |
+| `POST /api/v1/customers/{customerId}/followups` | 新增跟进 | `followup.create`并校验客户范围 |
+| `GET /api/v1/customers/{customerId}/actions` | 客户动作时间线 | `customer.read` |
+
+复杂业务状态迁移使用显式命令端点,例如`POST /api/v1/orders/{id}:confirm`,而不是允许客户端任意改`status`。普通资源字段更新使用`PATCH`与字段白名单;批量接口必须有独立授权、数量上限和逐项结果规则。
+
+首链字段和查询参数冻结为:
+
+- `POST /api/v1/web-sessions`请求仅含`loginName`、`password`;成功返回`200`以及`Me`,并通过Cookie建立会话,不在响应中返回会话标识。
+- `GET /api/v1/auth/csrf`成功返回`200`和`data.csrfToken`;`DELETE /api/v1/web-sessions/current`成功返回`204`。认证、客户和跟进端点一律返回`Cache-Control: no-store`,不得被浏览器、代理或移动端共享缓存持久化。
+- `GET /api/v1/me`返回`id`、`displayName`、`roles[]`、`permissions[]`、`authVersion`;角色和权限仅供界面呈现及体验优化,不能代替后端逐请求授权。
+- `GET /api/v1/customers`接受`limit`、`cursor`、`ownerId`、`status`、`updatedAfter`,`limit`默认20、最大100,固定按`updatedAt desc, id desc`排序;元素为`id`、`name`、`status`、`owner{id,displayName}`、`lastFollowupAt`、`updatedAt`、`version`。
+- `GET /api/v1/customers/{customerId}`在列表字段之外返回`contactSummary`、`nextActionAt`、`createdAt`;不返回数据库内部列或页面布局字段。
+- `GET /api/v1/customers/{customerId}/followups`接受`limit`和`cursor`,固定按`occurredAt desc, id desc`排序;元素为`id`、`customerId`、`type`、`content`、`occurredAt`、`createdBy{id,displayName}`、`createdAt`。
+- `POST /api/v1/customers/{customerId}/followups`必须带`Idempotency-Key`请求头,请求仅含`type`、`content`、`occurredAt`、可空`nextActionAt`;成功返回`201`、新建`Followup`和`Location`。`content`前后空白保留但不允许去除Unicode空白后为空,长度按Unicode码点计1至2000。
+- `GET /api/v1/customers/{customerId}/actions`接受`limit`和`cursor`,元素为`id`、`kind`、`occurredAt`、`actor{id,displayName}`和受控`summary`,不得把审计原文或内部载荷透传给客户端。
+- 路径ID和响应ID均为十进制字符串;请求出现未声明字段一律`400 VALIDATION_FAILED`,不得静默忽略。
+
+## 4. 成功响应
+
+单资源:
+
+```json
+{
+ "data": {
+ "id": "10001",
+ "version": 3,
+ "createdAt": "2026-07-17T08:30:00.000Z"
+ },
+ "meta": {
+ "requestId": "generated-request-id"
+ }
+}
+```
+
+列表:
+
+```json
+{
+ "data": [],
+ "page": {
+ "nextCursor": null,
+ "limit": 20,
+ "hasMore": false
+ },
+ "meta": {
+ "requestId": "generated-request-id"
+ }
+}
+```
+
+- ID一律使用字符串,金额使用十进制字符串,布尔值使用JSON布尔值。
+- 不需要响应体的成功删除返回`204`;创建返回`201`并提供`Location`。
+- `meta`只放协议元数据,不放页面文案、按钮权限或敏感调试信息。
+
+## 5. 错误模型
+
+```json
+{
+ "error": {
+ "code": "CUSTOMER_NOT_FOUND",
+ "message": "客户不存在或不可访问",
+ "details": [],
+ "requestId": "generated-request-id"
+ }
+}
+```
+
+| HTTP状态 | 语义 | 典型稳定码 |
+| --- | --- | --- |
+| `400` | 格式或语义无效 | `VALIDATION_FAILED` |
+| `401` | 未认证、会话/令牌失效 | `AUTHENTICATION_REQUIRED`、`SESSION_EXPIRED` |
+| `403` | CSRF失败,或已认证但无动作/数据范围权限 | `CSRF_VALIDATION_FAILED`、`PERMISSION_DENIED`、`ACCOUNT_DISABLED` |
+| `404` | 不存在或为防枚举而隐藏 | `<RESOURCE>_NOT_FOUND` |
+| `409` | 状态冲突、重复键、幂等冲突 | `VERSION_CONFLICT`、`IDEMPOTENCY_CONFLICT` |
+| `422` | 格式正确但违反业务规则 | `BUSINESS_RULE_VIOLATION` |
+| `429` | 速率限制 | `RATE_LIMITED` |
+| `500` | 未预期错误 | `INTERNAL_ERROR` |
+| `503` | 依赖尚未就绪或服务进入受控停止 | `SERVICE_NOT_READY` |
+
+`code`供客户端分支,`message`为安全、可直接展示的默认中文信息。字段错误可放在`details`的受控结构中,不返回堆栈、SQL、内部文件路径、账号明细或完整请求响应。客户端不得解析`message`决定业务逻辑。
+
+首链稳定错误码全集固定为:`VALIDATION_FAILED`、`CREDENTIALS_INVALID`、`AUTHENTICATION_REQUIRED`、`SESSION_EXPIRED`、`CSRF_VALIDATION_FAILED`、`ACCOUNT_DISABLED`、`PERMISSION_DENIED`、`CUSTOMER_NOT_FOUND`、`VERSION_CONFLICT`、`IDEMPOTENCY_CONFLICT`、`FOLLOWUP_TYPE_UNSUPPORTED`、`RATE_LIMITED`、`INTERNAL_ERROR`、`SERVICE_NOT_READY`。登录名不存在、密码错误或停用账号的登录尝试统一返回`401 CREDENTIALS_INVALID`,避免账号枚举;已有会话对应账号被停用时返回`403 ACCOUNT_DISABLED`并撤销会话。Web和未来移动端只按`code`映射:`401`清除当前认证上下文并进入重新认证,`403`保留当前页面且隐藏受限动作,`409`提示刷新/保持原输入,`429/503`遵循`Retry-After`或显式重试,其他错误给出通用失败提示和`requestId`。
+
+## 6. 分页、筛选与排序
+
+- 业务列表默认游标分页,`limit`默认20、上限由端点契约固定;客户端不能请求无上限全量数据。
+- 游标为不透明字符串,客户端只回传,不解析或持久依赖其结构。
+- 排序必须稳定,例如`updatedAt desc, id desc`;游标包含完整排序位置,避免同时间记录丢失或重复。
+- 筛选使用业务字段,例如`ownerId`、`status`、`updatedAfter`,不接受任意SQL字段、表达式或排序列。
+- 报表类确需页码时可独立定义offset分页,并明确最大偏移与异步导出边界,不能改变业务列表默认规则。
+- 搜索结果仍受后端权限和数据范围过滤;总数昂贵时不强制返回`total`。
+
+## 7. 时间、日期、金额和空值
+
+- 时刻用RFC 3339 UTC字符串并带`Z`,例如`2026-07-17T08:30:00.000Z`;服务端不根据Web或移动端时区改写事实。
+- 纯日期用`YYYY-MM-DD`;客户端本地展示时不能把纯日期当UTC时刻转换。
+- 客户端可通过标准请求头传展示时区/语言偏好,但数据库仍写UTC;审计同时记录服务端事实时间。
+- 金额在JSON中使用十进制字符串并配套币种代码,禁止浮点累计。
+- “未知/无值”用`null`,空字符串只代表合法的空文本;缺省字段和显式`null`在`PATCH`中必须有不同定义。
+
+## 8. 幂等与并发
+
+### 8.1 幂等键
+
+可能因移动网络、弱网或用户重复点击而重试的创建/命令接口必须支持`Idempotency-Key`。规则:
+
+- 由客户端生成足够随机的键;服务端按“认证主体 + 路由 + 键”唯一保存请求摘要和受控结果。
+- 同一键、同一请求摘要重复提交,返回第一次的业务结果;同一键、不同请求返回`409 IDEMPOTENCY_CONFLICT`。
+- 处理中重复请求返回可重试冲突或等待后的同一结果,不重复执行业务事务。
+- 保存期限由端点风险冻结;过期不意味着客户端可复用旧键。
+- 服务端日志和错误不回显完整请求体或凭据。
+
+### 8.2 乐观并发
+
+可编辑资源返回`version`并支持条件更新。客户端提交预期版本(例如`If-Match`或契约字段),版本不符返回`409 VERSION_CONFLICT`及重新读取提示,不进行静默覆盖。创建跟进等追加型操作使用幂等键,不用资源版本代替。
+
+## 9. 认证边界
+
+认证层把两种凭据统一解析为不可变`AuthContext`:`userId`、会话/令牌标识、有效权限、数据范围和安全属性。业务模块只依赖该上下文,不判断客户端是Web还是移动端。
+
+### 9.1 Web
+
+- Web本地开发也只允许HTTPS。浏览器入口固定为`https://localhost:5173`,由Vite同源代理把`/api/v1`转发到`https://localhost:3000`;浏览器不直接跨域调用API,首阶段不启用带凭据CORS。
+- 服务端建立至少256位随机、不可推导的会话标识,Cookie固定命名为`__Host-salescrm_session`,属性固定为`Secure; HttpOnly; SameSite=Strict; Path=/`且不设置`Domain`。不存在本地HTTP或关闭`Secure`的例外。
+- 会话标识的服务端存储只保留摘要;空闲过期30分钟、绝对过期8小时。登录、权限提升、本人改密和主管重置成功后轮换或撤销相关会话,旧会话标识不得继续使用。
+- `GET /api/v1/auth/csrf`返回与当前匿名/已认证Web会话绑定的随机令牌。除`GET`、`HEAD`、`OPTIONS`外,所有请求(包括登录和注销)必须同时提供`X-CSRF-Token`并通过严格`Origin: https://localhost:5173`校验;缺失、不匹配或来源不符返回`403 CSRF_VALIDATION_FAILED`,不执行业务事务。
+- Token、权限全集和业务数据不得放入`localStorage`或URL。Web不能为了与移动端“统一”而使用长期Bearer Token。
+
+### 9.2 未来移动端
+
+- 当前禁止新增、占位或暴露任何移动Token端点。启用移动端前必须另立任务并通过安全评审,冻结OAuth 2.1/OIDC授权服务器边界、Authorization Code + PKCE、系统浏览器回跳、访问/刷新令牌寿命与撤销模型。
+- 原生移动客户端不得携带客户端密钥,不得使用嵌入式WebView收集密码。刷新令牌只能进入iOS Keychain、Android Keystore支持的安全存储或所选跨平台框架等价安全区,不得进入普通偏好、日志、剪贴板或URL。
+- 后续若采用刷新令牌,服务端只存摘要和令牌族元数据,每次刷新必须轮换;发现旧令牌重放时撤销整个令牌族。注销、设备丢失、密码修改、账号停用和管理员撤销均必须进入同一撤销模型。
+- 本文已冻结的业务路径、DTO、错误码、分页、UTC、幂等与权限动作供Web和未来移动端共用;不得为了未来Token方案改变业务模块接口或让业务模块识别客户端类型。
+
+### 9.3 共同要求
+
+- 登录和令牌端点限速,失败响应避免账号枚举;认证日志只记录最小事件和请求ID。
+- 密码仅通过TLS传输,服务端使用经安全评审的强哈希;数据库不存明文、可逆密文或可由密码直接推导的会话Token。
+- 后端对每个动作和数据范围授权;主管重置、本人改密、导出等高风险动作使用独立权限和审计事件。
+- `AuthContext`每次请求从服务端会话、用户状态和授权关系构造。第一阶段不缓存权限结果;账号停用、密码变更、角色/权限变更与对应`auth_version`/`permission_version`更新、会话撤销在同一事务提交,最迟下一次请求生效。
+- 已停用账号统一返回`403 ACCOUNT_DISABLED`并撤销其活动会话;不存在“已签发会话继续使用至自然过期”的兼容窗口。
+
+## 10. 客户端重试与网络行为
+
+- `GET`、`HEAD`可在超时/瞬时网络错误时有限指数退避重试;`401/403/404/422`不自动重试。
+- 写请求只有携带幂等键且错误类型允许时才能自动重试。移动端网络恢复后不得无界重放队列。
+- `429`和暂时不可用响应可带`Retry-After`;客户端遵守上限并允许用户取消。
+- 超时不等于业务失败:客户端先用同一幂等键查询/重试结果,不另建新键造成重复记录。
+- 离线编辑、冲突合并和后台同步属于未来移动端产品范围,未冻结前不在API中假设“最后写入胜出”。
+
+## 11. 契约验证与变更流程
+
+`npm run test:contract`是唯一契约检查入口。每个API变更至少通过:
+
+1. OpenAPI语法、命名和安全规则检查;
+2. 服务器请求/响应Schema集成测试;
+3. 生成Web客户端的编译测试;
+4. 既有v1响应兼容测试和错误码快照;
+5. 权限矩阵、数据范围、ID/金额/时间序列化测试;
+6. 幂等重复、同键异请求、并发版本冲突测试;
+7. 当移动端激活后,增加至少一个独立生成客户端的契约构建和弱网重试测试。
+
+契约变更先由产品冻结业务语义,架构冻结兼容性和数据边界,后端实现,Web/移动端各自验证,代码审核与安全、测试与质量独立给Gate。不能用“Web能调通”代替多客户端兼容结论。
+
+## 12. 首条链路冻结结论
+
+本文件已唯一冻结首链路径、请求/响应字段、权限动作和数据范围、客户列表排序游标、跟进创建幂等键、字符串ID、UTC/纯日期、统一错误码、Web会话与CSRF、`/me`最小权限摘要、审计脱敏边界以及OpenAPI生成/检查命令。对应物理表、事务和单写切换见[MySQL数据与渐进迁移方案](<./MySQL数据与渐进迁移方案.md>),本地机械执行基线见[本地开发环境方案](<../环境/本地开发环境方案.md>)。
+
+移动端平台、UI和令牌端点明确后置且尚未实现;以上业务契约不得绑定Web页面或浏览器存储。任何实现若需要新增同义路径、弱化HTTPS/CSRF、延迟停用生效或绕过后端权限,必须停止并重新进入Gate R。
diff --git "a/docs/\346\236\266\346\236\204/\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\347\233\256\346\240\207\346\236\266\346\236\204\346\226\271\346\241\210.md" "b/docs/\346\236\266\346\236\204/\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\347\233\256\346\240\207\346\236\266\346\236\204\346\226\271\346\241\210.md"
new file mode 100644
index 0000000..ccdb49e
--- /dev/null
+++ "b/docs/\346\236\266\346\236\204/\346\250\241\345\235\227\345\214\226\345\215\225\344\275\223\347\233\256\346\240\207\346\236\266\346\236\204\346\226\271\346\241\210.md"
@@ -0,0 +1,255 @@
+# 模块化单体目标架构方案
+
+- 任务:`CRM-20260717-003`
+- 决策状态:架构方案,待跨角色 Gate R 和 Gate P 确认后进入实现
+- 适用范围:本地开发与验证;不授权生产部署
+- 关联文档:[系统现状与改造路线](<./系统现状与改造路线.md>)、[MySQL数据与渐进迁移方案](<./MySQL数据与渐进迁移方案.md>)、[多客户端API与认证契约](<./多客户端API与认证契约.md>)、[本地开发环境方案](<../环境/本地开发环境方案.md>)
+
+## 1. 事实分层
+
+### 1.1 当前已实现事实
+
+- Web 入口是`outputs/sales_crm_full_demo.html`,页面、样式、状态管理和大部分业务交互集中在单个HTML文件中。
+- Node.js 入口是`work/crm_full_server.js`,HTTP路由、认证、业务规则和JSON文件访问集中在单个进程、单个源码文件中。
+- 当前业务数据由`data/crm_full_data.json`承载;本方案未读取其中的真实业务内容。
+- 当前工程只有原生Node.js启动和语法检查脚本,尚无本文所述的工作区、MySQL迁移、共享契约或自动化测试实现。
+
+### 1.2 已冻结目标
+
+- 采用一个代码仓库、一个后端部署单元和一个MySQL业务数据库的**模块化单体**。
+- 新功能按纵向业务链路逐步迁移,不做一次性重写,不拆微服务。
+- API从第一天同时面向Web和后续移动端,不依赖页面结构、DOM、`localStorage`或浏览器专用状态。
+- 当前只建设本地开发与验证能力,生产部署、生产数据迁移和上线继续禁止。
+
+### 1.3 尚未实现
+
+本文中的目标目录、依赖、接口、数据表、命令和测试均为后续实现约束,不代表仓库当前已经具备。每个实施阶段仍须建立任务、通过适用Gate并由对应角色执行。
+
+## 2. 架构裁决
+
+| 决策面 | 目标选择 | 取舍 |
+| --- | --- | --- |
+| 总体形态 | TypeScript模块化单体 | 保留单进程事务和低运维成本,用模块边界解决当前职责混杂;规模和团队条件未证明需要微服务 |
+| Web | Vue 3、Vite、TypeScript | 组件化替代单HTML,构建轻量;不引入服务端渲染,当前CRM无此必要 |
+| API | Node.js 24.18.0、Fastify 5、TypeScript | 保留团队现有Node.js方向,使用Schema校验和插件边界;不继续扩展原生`http`路由 |
+| 契约 | TypeBox、Fastify JSON Schema、OpenAPI 3.1、生成客户端 | 契约与页面解耦,Web和移动端共用;禁止手工维护多套请求类型 |
+| 数据 | MySQL Community Server 8.4.10 LTS、InnoDB、`utf8mb4` | 冻结当前Windows本地薄型样例基线;升级必须独立验证迁移、驱动和恢复 |
+| 数据访问 | Kysely、`mysql2/promise`、Kysely Migrator | 只保留一套类型安全查询与迁移栈;Repository隔离业务和SQL,迁移增加校验和保护 |
+| 测试 | Vitest、API集成测试、Playwright、契约与迁移测试 | 覆盖模块、接口、浏览器主链路和数据升级;移动端进入实现后复用契约用例 |
+| 工程管理 | npm workspaces | 与现有npm生态一致,单仓共享版本和契约;当前不引入复杂构建编排平台 |
+
+不采用项:微服务、Kubernetes、事件总线作为首期必需设施、一次性重写、长期双写、前端直连数据库、按页面划分后端接口、把完整业务状态一次性返回给客户端。
+
+## 3. 目标运行关系
+
+```mermaid
+flowchart LR
+ W["Web 客户端"] -->|"/api/v1 + Cookie"| A["模块化单体 API"]
+ M["未来移动客户端"] -->|"/api/v1 + Bearer Token"| A
+ A --> I["身份与权限模块"]
+ A --> C["客户与跟进模块"]
+ A --> S["销售订单模块"]
+ A --> O["履约与财务模块"]
+ I --> DB[("MySQL")]
+ C --> DB
+ S --> DB
+ O --> DB
+ X["旧 HTML/Node/JSON"] -."按模块逐步退出".-> A
+```
+
+后端仍是一个进程和一个部署单元。模块之间通过应用服务、明确的只读查询或同进程领域事件协作,不通过HTTP自调用,也不绕过对方Repository直接改表。
+
+## 4. 仓库目标目录
+
+```text
+SalesCRM/
+├─ apps/
+│ ├─ web/ # Vue Web客户端
+│ │ └─ src/
+│ │ ├─ app/ # 路由、启动、全局依赖
+│ │ ├─ modules/ # 按业务能力组织页面和组件
+│ │ ├─ shared/ # 无业务归属的UI和工具
+│ │ └─ api/ # 生成客户端的薄封装
+│ └─ api/ # Fastify模块化单体
+│ └─ src/
+│ ├─ app/ # 服务装配、HTTP插件、配置
+│ ├─ modules/ # 业务模块
+│ ├─ infrastructure/ # MySQL、审计、时钟等适配器
+│ └─ shared/ # 少量稳定内核类型
+├─ packages/
+│ ├─ contracts/ # OpenAPI/JSON Schema和生成类型
+│ ├─ web-api-client/ # 从契约生成的Web TypeScript客户端
+│ └─ test-support/ # 生成式测试数据、测试时钟、夹具
+├─ database/
+│ ├─ migrations/ # 只追加、带版本的Schema迁移
+│ ├─ seeds/ # 幂等的非真实本地种子
+│ └─ fixtures/ # 脱敏、最小化测试夹具
+├─ tests/
+│ ├─ contract/
+│ ├─ integration/
+│ ├─ migration/
+│ └─ e2e/
+├─ outputs/ # 迁移期保留当前Web入口
+├─ work/ # 迁移期保留当前Node入口
+├─ data/ # 迁移期受控保留,禁止新增真实数据入Git
+└─ docs/
+```
+
+迁移初期不移动`outputs/`、`work/`和`data/`,避免目录重排与业务迁移混在同一个变更中。只有当对应模块切流、验证和回滚窗口结束后,才能在独立任务中清理旧入口。
+
+## 5. 模块边界
+
+### 5.1 后端模块
+
+| 模块 | 拥有的数据与职责 | 可以依赖 |
+| --- | --- | --- |
+| 身份与访问 | 用户、凭据、角色、权限、会话/令牌、认证上下文 | 审计基础设施 |
+| 客户与分配 | 客户、联系人、来源、归属、公海/分配规则 | 身份模块的用户只读投影 |
+| 跟进与提醒 | 跟进记录、提醒、客户动作时间线 | 客户标识、身份只读投影 |
+| 报价与成交 | 报价、成交复访和相关状态 | 客户模块公开查询 |
+| 销售订单 | 订单、订单行、销售单据 | 客户只读投影、身份上下文 |
+| 生产 | 生产任务与进度 | 销售订单公开事件/查询 |
+| 库存 | 库存项目、出入库流水、可用量 | 订单和生产公开事件/查询 |
+| 物流 | 发货、承运和签收 | 订单、库存公开查询 |
+| 应收与收款 | 应收、收款、核销 | 订单公开事件/查询 |
+| 报表与导出 | 授权后的只读聚合和异步导出任务 | 各模块公开只读接口,不拥有源业务状态 |
+| 审计 | 安全与关键业务动作的不可变事件 | 接收模块事件,不反向控制业务 |
+
+物理上这些模块位于同一API进程;逻辑上每个模块拥有自己的表、应用服务、Repository和HTTP适配器。跨模块写入由拥有模块的应用服务完成;确需同一业务事务时,由显式编排服务在同一个MySQL事务中调用,不能形成循环依赖。
+
+### 5.2 模块内部依赖方向
+
+```text
+HTTP/任务适配器 -> 应用服务 -> 领域规则与端口
+ ^ |
+ | v
+ 基础设施适配器 <- Repository接口
+```
+
+- HTTP层负责认证上下文、输入校验、协议映射,不承载业务规则。
+- 应用服务定义用例、事务边界、授权动作和跨模块编排。
+- 领域层只表达业务规则,不读取环境变量、HTTP请求或浏览器状态。
+- Repository实现只对所属模块开放,禁止通用`create/update/delete(kind, patch)`式跨实体入口。
+
+### 5.3 Web模块
+
+Web按业务能力而非按“页面大小”拆分,例如`auth`、`customers`、`followups`、`orders`、`inventory`。每个模块包含路由页面、模块组件、查询/命令和视图模型。`shared`只能放无业务归属的UI、日期/金额展示和协议基础设施,不能演变为第二个业务杂物箱。
+
+服务端数据以API为事实源;浏览器状态只保留临时UI选择和无敏感偏好。禁止把认证凭据、完整客户状态或离线业务写入`localStorage`作为降级事实源。移动端也必须通过同一API语义获得数据,不复刻Web页面状态。
+
+## 6. 共享契约
+
+- `packages/contracts`保存可审查的OpenAPI 3.1定义、请求/响应JSON Schema、错误码和示例;生成产物不可手工改动。
+- API启动和测试必须按同一Schema校验请求与响应;Web通过生成客户端调用,禁止散落裸`fetch`与自造类型。
+- 未来移动端从同一OpenAPI生成所选平台客户端;只有选择TypeScript跨平台方案时才复用Web客户端代码。平台专用网络层只负责安全存储、重试和网络状态,不改变业务语义。
+- 内部领域对象不得直接序列化为外部响应;使用显式DTO和字段白名单,避免数据库字段或密码元数据泄露。
+- 契约兼容、认证和分页细节见[多客户端API与认证契约](<./多客户端API与认证契约.md>)。
+
+## 7. 新旧共存与切流
+
+### 7.1 单一写入源原则
+
+每个业务模块在任意时刻只能有一个权威写入源:JSON或MySQL。禁止为了“平滑”而让旧服务和新服务长期双写,因为跨文件/数据库无法提供原子性,失败时难以判断真实状态。
+
+模块切换使用以下状态:
+
+| 状态 | 读 | 写 | 说明 |
+| --- | --- | --- | --- |
+| `LEGACY` | JSON | JSON | 当前状态 |
+| `SHADOW_READ` | JSON为准,MySQL只做对账 | JSON | 仅脱敏本地数据验证,不向用户展示MySQL结果 |
+| `CUTOVER_READY` | JSON | 冻结 | 完成最终增量和核验的短暂停写窗口 |
+| `MYSQL` | MySQL | MySQL | 新API是唯一入口,旧模块写入口关闭 |
+| `RETIRED` | MySQL | MySQL | 回滚窗口结束后才允许清理旧实现 |
+
+切流开关的唯一目标来源为Git忽略的`docs/local/环境/module-routing.local.json`。旧Node和新Fastify均只在启动时读取并按Schema校验;同一模块只能处于`LEGACY`或`MYSQL`之一,任何同时开启两个写入口的组合都必须拒绝启动。切流时停止两端、原子替换配置、先启动权威写入端并检查就绪状态,再启动只读/未迁移端。跨模块引用迁移期通过稳定的`legacy_id`映射维护,不允许用名称或数组位置关联。本方案只冻结该机制,没有创建配置或修改旧入口。
+
+### 7.2 第一条纵向链路
+
+首条链路冻结为“登录 -> 客户分页列表 -> 客户详情 -> 新增跟进 -> 动作时间线”。它同时验证:
+
+1. 身份、角色和后端权限校验;
+2. Web Cookie认证和统一认证上下文;
+3. `/api/v1`查询、分页、错误和幂等规则;
+4. 用户、客户、跟进和审计的MySQL表与事务;
+5. 脱敏测试数据导入、对账、切流和恢复;
+6. Web组件、生成客户端、API集成和端到端测试。
+
+第一条链路不包含移动端客户端实现,但其接口必须通过多客户端契约检查,不能使用Web页面字段或浏览器存储作为参数。未来移动端令牌端点可以后续激活,不阻塞Web本地链路。
+
+### 7.3 停止线与回滚
+
+出现任一条件立即停止切流:迁移校验不一致、存在未解释拒绝记录、外键/唯一约束失败、重复执行不幂等、旧入口仍可写、权限行为与基线不一致、备份无法恢复、契约或主链路测试失败、发现真实敏感数据将进入Git。
+
+- 切流前:关闭目标模块写入,生成本地受控备份,记录迁移批次和聚合校验结果。
+- MySQL尚无新写入时:可将模块路由退回JSON,保留失败批次供分析。
+- MySQL已有新写入后:不得把数据盲目反向覆盖JSON;应用回退与数据回退必须拆开裁决。默认保留MySQL事实,修复后前滚;确需反迁移必须另建任务和可验证脚本。
+- 本地测试可销毁并重建专用测试库,但不得把该手段当作生产回滚方案。
+
+详细规则见[MySQL数据与渐进迁移方案](<./MySQL数据与渐进迁移方案.md>)。
+
+## 8. 分阶段实施
+
+| 阶段 | 范围 | 进入条件 | 退出条件 |
+| --- | --- | --- | --- |
+| 0 数据安全前置 | 数据分类、脱敏夹具、Git历史处置决策 | CRM-003方案通过Gate R/P | BLOCK-001至003有明确处置,不以真实业务数据做普通测试 |
+| 1 本地基础 | workspaces、Web/API骨架、契约、MySQL迁移/种子、测试框架 | 独立实施任务获锁 | 空库可迁移、种子幂等、API健康检查与测试可重复执行 |
+| 2 首条链路 | 身份、客户查询、跟进写入、审计 | 阶段1通过适用Gate | 链路E2E和权限矩阵通过,模块在本地可独立切到MySQL并恢复 |
+| 3 客户域完善 | 分配/公海、提醒、报价、成交复访、客户报表 | 首链稳定 | 客户域只有一个写入源,旧写入口关闭 |
+| 4 销售单据 | 订单、订单行和关联单据 | 客户域稳定 | 金额/状态事务和回归通过 |
+| 5 履约与财务 | 生产、库存、物流、应收、收款 | 订单域稳定 | 跨模块编排、审计和对账通过 |
+| 6 移动客户端 | 平台选择、移动UI、令牌、设备安全、弱网策略 | Owner冻结移动产品范围且角色激活;v1契约稳定 | 独立移动端Gate通过;不改变Web业务语义 |
+| 7 旧系统退役 | 移除JSON业务写入、旧路由和浏览器降级数据 | 所有模块回滚窗口结束 | 旧入口无流量/无依赖,归档和清理经独立审核 |
+
+各阶段只面向本地开发/验证。生产环境拓扑、容量、监控、密钥、域名、证书、备份保留和发布回滚必须另立生产准备任务,不在本方案中推定。
+
+## 9. 安全与测试前置
+
+- 所有授权由后端按动作强制执行;前端隐藏按钮仅是体验措施。
+- 密码凭据独立存储,只保存经过审查的强密码哈希和算法版本;不得沿用可逆或可推导令牌设计。
+- 输入按Schema拒绝未知/越权字段,输出使用白名单;审计记录不得包含密码、Token、完整请求响应或客户原文快照。
+- Web需覆盖Cookie属性、CSRF、XSS和会话失效;移动端需覆盖安全存储、刷新令牌轮换、撤销、设备丢失和重放风险。
+- 每个迁移阶段至少包含单元测试、API集成测试、权限矩阵、空库升级、历史版本升级、种子幂等、契约兼容、E2E主链路和恢复演练。
+- 自动化流水线属于后续实现;没有独立审核和测试证据时不得声称Gate C/A通过。
+
+## 10. 移动端范围与职责复查
+
+移动端已从“完全不在产品方向”变为“后续明确范围”。因此,当前立即激活的是多客户端API、认证边界、契约兼容和移动场景测试设计;原有Web前端角色不自动承担原生客户端开发。
+
+在创建移动客户端代码前,Owner/产品必须冻结:目标平台、原生或跨平台方案、首期功能、离线与弱网策略、推送、扫码/相机等设备能力、分发渠道和最低系统版本。随后再建立APP开发、iOS/Android测试和打包职责卡与队列。当前没有客户端产物,相关角色处于“条件待激活”,不是继续永久`N/A`。
+
+## 11. Gate R最小冻结项与未决项
+
+进入首个实现任务前,Gate R至少冻结:
+
+1. 目标目录、模块依赖和第一条纵向链路;
+2. Node.js 24.18.0、npm 11.16.0、MySQL 8.4.10、Kysely与`mysql2/promise`唯一基线,以及ID/时间/金额/软删除约定;
+3. 首链物理Schema、事务、幂等和迁移校验和规则;
+4. TypeBox契约源、OpenAPI生成物和Web客户端生成物的归属、命令与漂移检查;
+5. 本地HTTPS、Web会话、CSRF、授权新鲜度及未来移动令牌停止线;
+6. JSON迁移的单一写入源、校验、停止线和回滚责任;
+7. 脱敏测试数据来源和BLOCK-001至003的处置前置;
+8. 本地验收命令与独立审核、测试责任人。
+
+仍需后续裁决:移动端技术栈和平台、离线/推送范围、审计/业务数据保留期、文件附件存储、生产拓扑与发布策略。MySQL小版本、查询/迁移栈、本地HTTPS和首链契约已在本次Gate R整改中冻结,不再列为选型未决项。
+
+## 12. 首个实施任务唯一范围
+
+第一实施任务固定为“本地模块化单体基础骨架与可验证薄型样例”,不迁移真实业务,不读取当前`data/`,不修改旧业务写入口:
+
+1. 建立npm workspaces、`apps/web`、`apps/api`、`packages/contracts`、`packages/web-api-client`和测试目录;
+2. 锁定Node.js 24.18.0、npm 11.16.0及所有npm依赖的精确补丁版本到单一锁文件;
+3. 以TypeBox为请求/响应Schema源,通过Fastify路由生成OpenAPI 3.1,再生成Web客户端;生成物提交Git但禁止手改;
+4. 创建MySQL 8.4.10三库和最小权限账号,使用Kysely、`mysql2/promise`及唯一Migrator完成空库迁移、幂等种子和事务回滚样例;
+5. 建立本地HTTPS、Cookie/会话/CSRF与配置故障关闭骨架;
+6. 实现`/health/live`、`/health/ready`以及契约、迁移、恢复的空白可重复测试入口;
+7. 证明旧入口与新壳可同时启动,但新壳不访问真实数据、不复制`localApi`、不写任何业务模块。
+
+该任务通过适用Gate后,第二实施任务才迁移“会话/当前身份 → 客户分页 → 客户详情 → 跟进查询/新增 → 动作时间线”。第二任务开始前必须以[MySQL数据与渐进迁移方案](<./MySQL数据与渐进迁移方案.md>)的首链物理Schema和[多客户端API与认证契约](<./多客户端API与认证契约.md>)的首链契约为唯一编码输入。
+
+### 12.1 前端公开边界
+
+- `apps/web`只能依赖`packages/contracts`、`packages/web-api-client`和前端共享UI,不得导入`apps/api`、`database`、`work`或`data`。
+- 业务模块只能从对方`public.ts`公开入口依赖,不得深层导入内部组件、状态或查询键。
+- `shared`不得保存客户、订单、权限或迁移业务规则。
+- 浏览器只访问`https://localhost:5173`;`/api/v1`由Vite同源代理到本地HTTPS API,不启用浏览器跨源凭据模式。
+- 旧页面和新Web不得通过URL、全局变量、`localStorage`或复制旧令牌桥接认证与业务状态。
diff --git "a/docs/\347\216\257\345\242\203/\345\257\274\350\257\273.md" "b/docs/\347\216\257\345\242\203/\345\257\274\350\257\273.md"
index 5ffdcc9..9e6a340 100644
--- "a/docs/\347\216\257\345\242\203/\345\257\274\350\257\273.md"
+++ "b/docs/\347\216\257\345\242\203/\345\257\274\350\257\273.md"
@@ -1,5 +1,6 @@
# 环境文档导读
- [运行环境说明](<./运行环境说明.md>):当前本地和服务器运行入口、端口及非敏感配置。
+- [本地开发环境方案](<./本地开发环境方案.md>):模块化单体与MySQL的目标本地环境、隔离、启动和验证方案;当前尚未实施。
- 敏感凭据位于Git忽略的`docs/local/`,本目录不得复制其值。
- 详细阿里云部署步骤参见[阿里云Linux部署执行文档](<../aliyun_linux_deployment_runbook.md>),其中部分内容将在P1部署加固任务中修订。
diff --git "a/docs/\347\216\257\345\242\203/\346\234\254\345\234\260\345\274\200\345\217\221\347\216\257\345\242\203\346\226\271\346\241\210.md" "b/docs/\347\216\257\345\242\203/\346\234\254\345\234\260\345\274\200\345\217\221\347\216\257\345\242\203\346\226\271\346\241\210.md"
new file mode 100644
index 0000000..929bd81
--- /dev/null
+++ "b/docs/\347\216\257\345\242\203/\346\234\254\345\234\260\345\274\200\345\217\221\347\216\257\345\242\203\346\226\271\346\241\210.md"
@@ -0,0 +1,179 @@
+# 本地开发环境方案
+
+- 任务:`CRM-20260717-003`
+- 状态:Gate R整改定稿;尚未安装MySQL、创建新工程或执行命令
+- 范围:开发者本机和本地自动化验证;不包含生产部署
+- 架构依据:[模块化单体目标架构方案](<../架构/模块化单体目标架构方案.md>)、[MySQL数据与渐进迁移方案](<../架构/MySQL数据与渐进迁移方案.md>)
+
+## 1. 当前本机事实
+
+本轮只读检查确认:当前工作目录使用Windows和PowerShell;Node.js与npm可用,现有工程仍通过`npm start`运行旧Node服务。当前命令路径中未发现MySQL客户端和Docker,因此本文的MySQL启动、迁移、种子和新工程命令均未执行,不能描述为环境已就绪。
+
+敏感配置只能放在Git忽略的`docs/local/`或后续工程约定的本地环境文件中,正式文档只说明变量名和位置,不保存值。
+
+## 2. 目标本地基线
+
+| 组件 | 目标 | 说明 |
+| --- | --- | --- |
+| Node.js | `24.18.0` LTS | 仓库版本文件、CI和本地预检必须一致,不接受仅锁定大版本 |
+| npm | `11.16.0` | 使用Node 24.18.0配套版本、单一`package-lock.json`和npm workspaces |
+| MySQL | MySQL Community Server `8.4.10` LTS | Windows x86_64 MSI与MySQL Configurator;InnoDB、`utf8mb4` |
+| Git | 现有本地Git | 不提交本地凭据、备份、数据库文件或真实运行数据 |
+| 浏览器 | 当前受支持的Chromium基线 | 用于Web开发与Playwright;版本矩阵由测试任务冻结 |
+
+本机当前没有Docker,故第一条实现路径唯一采用**Windows本地MySQL服务**,不安装容器平台。未来若另立任务采用容器,必须重新验证版本、目录、备份和恢复;同一开发机一次只能存在一个被应用配置选中的MySQL来源。
+
+### 2.1 Windows MySQL机械基线
+
+- 安装介质:MySQL Community Server `8.4.10` LTS Windows x86_64 MSI及配套MySQL Configurator;安装包来源和SHA-256摘要写入Git忽略的本机检查表,不在正式文档复制下载凭据。
+- Windows服务名固定为`SalesCRMMySQL84`;服务使用专用本地账户`.\SalesCRMMySQLSvc`,禁止交互登录,不使用开发者个人账户或管理员账户运行。
+- 根目录固定为`E:\SalesCRMLocal\mysql\8.4.10\`,其下分为`data\`、`logs\`、`backups\`、`tmp\`;均不得位于仓库目录或被Git跟踪。
+- 仅监听`127.0.0.1:3306`,关闭MySQL X Plugin监听;不允许`0.0.0.0`、局域网或公网绑定。
+- 服务端默认`character_set_server=utf8mb4`、`collation_server=utf8mb4_0900_ai_ci`、`default_time_zone=+00:00`,固定`sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION`。
+- 应用启动前核对服务名、二进制版本、端口进程、数据目录和服务账户;任一不符即失败关闭,不尝试自动改写系统服务。
+
+## 3. 目标端口与入口
+
+| 服务 | 建议本地地址 | 状态 |
+| --- | --- | --- |
+| 新Web | `https://localhost:5173` | 待实现;浏览器唯一入口 |
+| 新API | `https://localhost:3000` | 待实现;由Web开发代理访问 |
+| 本地MySQL | `127.0.0.1:3306` | 待安装/验证 |
+| 旧系统 | `http://127.0.0.1:8090` | 当前入口,迁移期按需保留且与新认证隔离 |
+
+服务默认只监听回环地址。浏览器只访问`https://localhost:5173`,Vite把同源`/api/v1`代理到新API;不启用带凭据跨域,也不存在HTTP或`Secure=false`例外。旧系统不得共享新Cookie、Bearer Token、`localStorage`或业务数据回退通道。需要真机联调时,不能临时把服务暴露到公网;应另建移动端联调任务,确定局域网TLS、开发证书、防火墙、测试账号和设备撤销策略。
+
+本地证书由后续工程脚本`npm run tls:bootstrap`调用锁定版本的`mkcert`创建:证书SAN仅包含`localhost`和`127.0.0.1`,产物放在`docs/local/证书/localhost.pem`与`docs/local/证书/localhost-key.pem`并保持Git忽略。脚本必须验证本机信任链、私钥文件权限和SAN;失败时拒绝启动,不允许降级到HTTP。
+
+## 4. 本地数据库隔离
+
+建议至少创建三个互不复用的库:
+
+- `sales_crm_local`:开发者本地开发;
+- `sales_crm_test`:自动化测试,允许测试进程清理;
+- `sales_crm_migration_test`:迁移与恢复演练,禁止应用日常连接。
+
+应用使用最小权限账号,不使用MySQL管理员账号日常运行。迁移账号与应用账号分离:迁移账号可执行受控DDL,应用账号仅有目标Schema的必要DML权限。测试进程必须检查库名/环境标记后才允许清理,禁止把可清理命令指向未明确标记的数据库。
+
+本地配置只有一个入口:环境变量`APP_CONFIG_FILE`必须指向Git忽略的`docs/local/环境/local.env`。应用不得再合并工作目录`.env`、用户环境变量或浏览器存储形成隐式优先级;系统只允许`APP_CONFIG_FILE`本身由启动进程提供。数据库连接字符串、密码和证书值放在该忽略文件中。仓库后续只提交无可运行值的`.env.example`占位符,例如:
+
+```dotenv
+APP_ENV=local
+WEB_PORT=<本地端口>
+API_PORT=<本地端口>
+DATABASE_URL=<从本机忽略文件提供>
+WEB_SESSION_SECRET=<从本机忽略文件提供>
+CSRF_SECRET=<从本机忽略文件提供>
+MIGRATION_HMAC_KEY=<从本机忽略文件提供>
+TLS_CERT_FILE=<从本机忽略文件提供>
+TLS_KEY_FILE=<从本机忽略文件提供>
+MODULE_ROUTING_FILE=<指向本机忽略的单写路由文件>
+```
+
+示例只表达形状,不能使用可运行的默认密码或Token。`npm run config:check`必须拒绝缺失变量、示例占位符、短于32随机字节的三个独立密钥、非`local/test`的`APP_ENV`、非回环数据库地址、未标记环境的库名、证书/私钥不存在、路由文件中同一模块多写者或JSON结构未知字段;错误只报告变量名和规则,不回显值。
+
+## 5. 首次安装计划
+
+以下是后续基础设施任务的执行顺序,不是本轮已执行事实:
+
+1. 安装并锁定Node.js/npm版本,验证版本文件和锁文件一致。
+2. 安装本文件冻结的MySQL Community Server `8.4.10` LTS与官方命令行客户端,按Windows机械基线配置并记录安装包摘要。
+3. 在`docs/local/`建立本机安装检查表和敏感连接配置;该目录保持Git忽略。
+4. 执行`npm run tls:bootstrap`和`npm run config:check`,未建立可信HTTPS或配置不合格时不得启动应用。
+5. 创建迁移、应用和测试所需的最小权限本地账号与隔离数据库,并由`npm run db:preflight`核对版本、服务、端口、库标记和权限。
+6. 从空库运行版本化迁移,再运行幂等结构种子和生成式演示夹具。
+7. 按“MySQL服务→迁移→API→API就绪→Web”的顺序启动,执行健康、契约、权限、API集成和E2E主链路。
+8. 执行一次本地备份到仓库外目录,恢复到`migration_test`库并复跑验证。
+
+安装过程中不得导入当前真实`data/`。JSON迁移验证必须等待脱敏数据字典与夹具任务通过适用Gate。
+
+## 6. 目标开发命令
+
+后续工程应把常用动作固化为仓库脚本,避免复制长命令。建议最终提供:
+
+```powershell
+npm ci
+npm run config:check
+npm run tls:bootstrap
+npm run db:preflight
+npm run db:migrate
+npm run db:seed
+npm run dev
+npm run check
+npm run test
+npm run test:contract
+npm run test:integration
+npm run test:migration
+npm run test:recovery
+npm run test:e2e
+```
+
+这些脚本当前不存在或未按新架构实现,本轮没有运行。脚本要求:
+
+- `db:migrate`打印迁移版本和结果,不打印连接凭据;失败时非零退出。
+- `db:seed`重复执行不产生重复结构数据,并拒绝在非local/test环境运行演示夹具。
+- `dev`并行启动新Web/API,但数据库仍由开发者明确管理,不在应用启动时隐式建库改表。
+- `check`至少覆盖格式、静态检查、类型检查和OpenAPI生成产物是否最新。
+- `test:contract`从TypeBox源重新生成OpenAPI/Web客户端到临时目录,检查产物漂移、破坏性变更和服务端Schema一致性。
+- `test:recovery`执行本文件的备份恢复演练并复用迁移、结构、聚合对账和首链集成检查;恢复步骤不得藏在人工说明中。
+- 集成/迁移测试只连接带明确测试标记的库;E2E使用生成账号和数据。
+
+所有测试命令必须先运行同一`environment_guard`:只允许`APP_ENV=test`,数据库名只能是`sales_crm_test`或`sales_crm_migration_test`,目标库必须存在环境标记表且连接地址为回环。失败、跳过必需步骤或发现异常均非零退出。生成式夹具固定覆盖匿名、停用、不同权限/数据范围、空列表、游标边界、并发冲突、幂等重放,以及迁移中的缺键、重复键、无效枚举、失效引用、时间歧义;每次运行只把脱敏汇总写入`docs/local/验证证据/<runId>/`,不保存完整请求响应或业务原文。
+
+### 6.1 启动与健康语义
+
+- API提供`GET /health/live`和`GET /health/ready`,均不需要认证且只返回状态、版本和请求ID,不返回配置、依赖地址或错误堆栈。
+- `live`只表示进程事件循环可响应;`ready`必须同时满足配置校验、证书加载、MySQL连接、迁移版本等于应用要求和单写路由文件有效。任一失败时`ready`返回`503 SERVICE_NOT_READY`。
+- Web只能在API `ready`成功后启动;`npm run dev`任一子进程失败必须停止整组进程并非零退出,不留下看似可用的半启动环境。
+
+## 7. 日常开发流程
+
+1. 更新代码后执行`npm ci`或经批准的依赖安装,检查锁文件差异。
+2. 查看待应用迁移,备份需要保留的本地开发数据,再执行迁移。
+3. 启动MySQL、新API和Web;旧系统仅在对照或未迁移模块需要时启动。
+4. 修改契约时先更新OpenAPI/Schema并生成客户端,再实现后端和Web。
+5. 提交前执行`check`、受影响单元/集成/契约测试和首条E2E;数据变更追加迁移测试。
+6. 只提交生成/脱敏夹具和非敏感证据,检查Git状态中没有`.env`、备份、数据库文件、真实数据或原始日志。
+
+## 8. 本地验证清单
+
+| 检查 | PASS条件 |
+| --- | --- |
+| 工具版本 | 与仓库锁定版本兼容,版本命令成功 |
+| 空库迁移 | 从零应用全部迁移,Schema校验一致 |
+| 种子幂等 | 连续执行两次,稳定数据不重复 |
+| API健康 | API可启动,错误不泄露配置或堆栈 |
+| Web/API契约 | 生成客户端编译,服务器响应Schema通过 |
+| 身份权限 | 未登录、无权限、越数据范围和正常路径结果正确 |
+| 首条链路 | 登录、客户分页/详情、新增跟进、时间线E2E通过 |
+| 幂等并发 | 重复跟进不重复创建,同键异请求和版本冲突正确 |
+| 迁移对账 | 仅使用脱敏夹具,聚合、映射和拒绝数闭合 |
+| 备份恢复 | 从备份恢复到隔离库并复跑结构/主链路验证 |
+| 敏感信息 | Git差异、测试报告和日志不含凭据、客户原文或完整请求响应 |
+
+### 8.1 备份恢复运行手册
+
+1. `npm run db:backup -- --source=sales_crm_migration_test`先执行环境守卫和迁移版本检查,生成`runId`,再调用锁定版本的`mysqldump`把仅结构和生成式夹具备份到`E:\SalesCRMLocal\mysql\8.4.10\backups\<runId>\`。
+2. 脚本生成备份SHA-256、MySQL版本、迁移版本、起止时间、表数量和行数聚合;不得记录连接凭据、业务字段原文或完整SQL输出。
+3. `npm run db:restore -- --snapshot=<runId> --target=sales_crm_migration_test`只接受经环境守卫确认的隔离库,校验摘要后清空并恢复;目标不是`migration_test`、摘要不符或快照版本不匹配时必须停止。
+4. 恢复后自动执行`db:migrate`、Schema快照比较、表/状态聚合对账、首链集成与幂等/并发测试;任一差异非零退出并保留脱敏摘要。
+5. 快照和证据均在仓库外或`docs/local/`,验证完成后按本地保留规则清理。本文不授权生产备份、生产恢复或任何生产数据访问。
+
+## 9. 新旧系统本地共存
+
+- 默认使用不同端口并在界面上明确标记“旧系统/新系统”,避免误操作。
+- 未迁移模块继续由旧入口读写JSON;切到MySQL的模块只能通过新API写入,旧页面对应写入口必须关闭。
+- 禁止浏览器网络失败后静默切换到`localStorage`继续写业务数据。连接失败应明确提示并保持数据未提交。
+- 切流、恢复和删除本地测试数据都由显式脚本/步骤执行,不由页面自动触发。
+
+单写路由事实源固定为Git忽略的`docs/local/环境/module-routing.local.json`,每个模块只允许`legacy-json`或`modular-mysql`一个写者。切换前运行`npm run cutover:check -- --module=<name>`冻结旧写入口、等待在途写完成、记录旧/新聚合水位和路由文件摘要;操作者确认后原子替换路由文件并重启新旧进程。两端启动时都校验同一文件并拒绝多写者或未知模块。切换后证据至少包含配置摘要、进程版本、迁移版本、旧写入口不可写断言、首链写入与对账结果。
+
+MySQL已经产生切换后写入时,不允许直接把路由改回JSON。回退必须先停止写入、确认新写集合、通过受控反向迁移或业务补偿恢复一致性,并由架构、数据和发布职责共同批准;无法证明零丢失时保持停止状态并回到Gate R/P。
+
+## 10. 停止线
+
+出现以下情况停止环境搭建或验证并回到对应Gate:工具版本无法复现、MySQL迁移不可重复、测试脚本可能连接非测试库、需要读取真实凭据或`data/`才能继续、Git出现真实数据/备份、旧新系统同时写同一模块、恢复演练失败,或任何步骤要求生产服务器/域名/证书/数据。
+
+## 11. 生产明确不在范围
+
+本文没有定义生产主机、拓扑、容量、域名、TLS、密钥托管、监控、告警、备份保留、灾备、发布或回滚Runbook。任何生产部署请求都必须等待BLOCK-001至003关闭、建立独立生产准备任务并通过Gate C/A/D/P;不能从本地方案直接推导上线许可。
diff --git "a/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\344\274\232\350\257\235\346\225\205\351\232\234\350\277\201\347\247\273\344\270\216\344\272\244\346\216\245\350\247\204\350\214\203.md" "b/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\344\274\232\350\257\235\346\225\205\351\232\234\350\277\201\347\247\273\344\270\216\344\272\244\346\216\245\350\247\204\350\214\203.md"
new file mode 100644
index 0000000..299e7cd
--- /dev/null
+++ "b/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\344\274\232\350\257\235\346\225\205\351\232\234\350\277\201\347\247\273\344\270\216\344\272\244\346\216\245\350\247\204\350\214\203.md"
@@ -0,0 +1,100 @@
+# SalesCRM 会话故障迁移与交接规范
+
+- 版本:v1.0
+- 生效时间:2026-07-17
+- 维护角色:项目管理员、产品与项目管理
+- 适用范围:全部正式角色会话、备用/复验会话及其历史会话
+- 调度前置:[角色会话串行调度规范](<./角色会话串行调度规范.md>)
+- 会话登记:[角色会话清单](<./角色/角色会话清单.md>)
+
+## 目的
+
+当正式会话出现`Error submitting message`、连续无法启动turn、历史可读但无法继续投递或其他会话级故障时,既恢复可用窗口,也保证旧会话中的用户决策、讨论上下文、当前任务、未完成项和执行锁不丢失。新建会话不是修复完成;完成条件是“历史已回读、任务已接管、入口已切换、旧会话已归档”。
+
+## 不得混淆的状态
+
+- `notLoaded`本身不是故障结论。若最新turn已完成、无用户侧错误且恢复投递成功,可以继续使用。
+- 单次网络或客户端提交失败先按同一队列项恢复,不立即换会话。
+- 同一锁定项连续两次投递均未产生turn,或用户持续看到`Error submitting message`,可判定该正式会话不再是可靠入口。
+- 会话故障不改变任务状态。原`RUNNING/WAITING`锁、队列编号和验收标准必须保留。
+
+## 强制迁移流程
+
+### 1. 冻结旧会话
+
+1. 立即停止向旧会话发送新任务、提醒或协作消息。
+2. 若存在`RUNNING/WAITING`项,保持原队列编号和执行锁;不得标记完成、取消或跳到下一项。
+3. 只读记录旧Thread ID、标题、状态、最新turn、错误现象、当前队列项和最后检查点。
+4. 建立会话修复事件,写明范围、不做项、敏感边界和验收标准。
+
+### 2. 完整回读旧会话
+
+新正式会话开始任何业务工作前,必须完整读取旧会话历史,必要时逐页读取到最早turn。回读至少提取:
+
+- Owner和用户已经确认的方向、范围、取舍与新增约束;
+- 已讨论方案、已否决方案及原因;
+- 当前任务/事件/队列编号、Gate和执行锁;
+- 已完成内容、未完成内容、阻塞、风险、证据和下一责任人;
+- 被中断turn的恢复点;
+- 旧会话是否修改过文件或运行态,以及对应精确证据。
+
+不得把原始聊天、密码、Token、客户数据、完整日志或完整请求响应复制到普通文档。正式交接只记录脱敏摘要和旧Thread/turn ID。
+
+如果新会话无法直接读取旧会话,项目管理员必须先完成全量回读,并把脱敏交接摘要放入修复任务或协作事件,再交给新会话确认;未完成前不得归档旧会话。
+
+### 3. 创建并初始化新会话
+
+1. 新会话沿用相同正式角色和职责卡,不创建第二套职责。
+2. 初始提示必须包含旧Thread ID、当前队列项、故障事实、回读要求、WIP=1和禁止越级边界。
+3. 有原执行锁时,新会话恢复同一个队列项;无执行业务项时,只执行“历史回读与接管验证”。
+4. 新会话必须回传`PASS / CHANGES_REQUESTED / BLOCKED`和交接清单,不得只回复“已接管”。
+
+## 交接验收清单
+
+只有以下项目全部`PASS`,才允许切换正式入口:
+
+1. 新会话已完整回读旧会话或已确认项目管理员提供的完整脱敏摘要。
+2. 用户决策、方案取舍、当前任务、未完成项和阻塞没有遗漏。
+3. 原`RUNNING/WAITING`项仍使用同一队列编号,并从最后检查点恢复。
+4. 新会话明确WIP=1、禁止新消息抢占和中断恢复规则。
+5. 新会话未越权修改范围外文件、代码、数据、Git或运行态。
+6. 新会话至少完成一次接管turn;必要时再完成一次后续消息提交验证。
+7. 角色会话清单、角色队列索引和角色队列文件中的正式Thread ID一致。
+8. 旧会话被标记为历史入口,不再接受新任务。
+
+## 旧会话归档
+
+归档顺序必须是:
+
+1. 新会话交接验收`PASS`;
+2. 正式入口ID完成三处切换;
+3. 当前任务在新会话中恢复或确认无遗留任务;
+4. 旧会话重命名为“历史|角色名(已停用)”;
+5. 在角色会话清单记录故障、接管Thread ID、交接证据和任务是否丢失;
+6. 使用Codex归档操作归档旧会话。
+
+归档不等于删除。旧会话继续作为历史证据保留,但不得再接收新任务。若新会话在验收前失败,旧会话暂不归档,原队列锁保持,继续创建下一替代会话接管同一项。
+
+## 标准交接回执
+
+```text
+结论:PASS / CHANGES_REQUESTED / BLOCKED
+新正式Thread ID:
+已回读旧Thread ID:
+当前任务/事件/队列:
+继承的Owner决策与方案取舍:
+已完成内容:
+未完成内容与恢复点:
+阻塞、风险和停止线:
+WIP=1与禁止抢占确认:
+实际修改:
+旧会话是否允许归档:是/否 + 原因
+下一责任人:
+```
+
+## 当前项目迁移证据
+
+- 前端开发:新正式会话`019f702e-eb7e-70d3-8271-06269945435a`已完整回读旧会话`019f6ea8-7abd-7ca2-8b6c-8e3e54cfd8b1`的6个已完成turn至`hasMore=false`,保持并完成原QUEUE-024,前端Gate R复评PASS;旧会话已重命名并归档。
+- 后端开发:新正式会话`019f7014-60d2-7972-ba52-46d834fe49f2`已完整回读旧会话`019f6ea8-9633-7a82-9034-789ecc7888da`的5个已完成turn至`hasMore=false`,保持并完成原QUEUE-032,确认v0.4后端可实施;旧会话已重命名并归档。
+- 架构与数据治理:新正式会话`019f6f85-bee8-7f70-8d0a-af638ece0782`已完整回读旧会话`019f6ea8-3df3-7260-a18f-18adb6ebef63`,恢复模块化单体讨论并承接后续MySQL、渐进迁移和移动端约束;旧会话已重命名并归档。
+- UI与交互设计:第三代正式会话`019f6fa9-44a2-7313-892d-886b43af1be9`已完整回读前两代UI会话`019f6ea8-61fa-7fa3-ae43-2a11f6b6f354`和`019f6f41-7c33-7200-97b4-5bb4690de8c2`共3个turn,确认QUEUE-003/013无任务遗漏;两代旧会话已重命名并归档。
diff --git "a/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\345\215\217\344\275\234\350\247\204\350\214\203.md" "b/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\345\215\217\344\275\234\350\247\204\350\214\203.md"
index 51f06ca..2d2de82 100644
--- "a/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\345\215\217\344\275\234\350\247\204\350\214\203.md"
+++ "b/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\345\215\217\344\275\234\350\247\204\350\214\203.md"
@@ -11,6 +11,7 @@
- 任务因缺范围、环境、权限、数据、设计或决策而阻塞。
- 发生 Gate N/R/C/D/A/P 的请求和结果回传。
- 发生部署、回滚、数据迁移、Git 历史处理或生产风险操作。
+- 正式角色会话无法提交、无法启动turn、需要替代入口或归档旧会话。
同一角色内部的小步骤不重复建事件;纯说明且没有责任转移的聊天不建事件。
@@ -44,6 +45,8 @@
6. 会话中断后只允许发送“恢复当前队列项”,禁止直接发送下一个事件。
7. 默认FIFO。优先级变化只调整尚未开始的`QUEUED`项;`RUNNING/WAITING`项只能由Owner明确暂停或取消。
+会话故障时不改变上述队列顺序。替代会话必须按[会话故障迁移与交接规范](<./会话故障迁移与交接规范.md>)完整回读旧历史、恢复同一队列项并通过交接验收,旧会话随后才能归档。
+
## 回执要求
角色回执至少说明:已读取的版本、自己的职责/输入/输出/签字权、处理范围、禁止越级、当前任务接入点、阻塞和下一步。仅回复“收到”不构成有效回执。
diff --git "a/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\345\257\274\350\257\273.md" "b/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\345\257\274\350\257\273.md"
index e2100e3..2957ef4 100644
--- "a/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\345\257\274\350\257\273.md"
+++ "b/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\345\257\274\350\257\273.md"
@@ -17,6 +17,7 @@
| [开发迭代流程](<./开发迭代流程.md>) | 唯一阶段和 Gate 入口 |
| [角色协作宪章](<./角色协作宪章.md>) | 定义职责、签字权和禁止越级 |
| [协作规范](<./协作规范.md>) | 定义跨角色事件、回执和阻塞处理 |
+| [会话故障迁移与交接规范](<./会话故障迁移与交接规范.md>) | 定义不可用会话的历史回读、任务接管和旧会话归档 |
| [角色索引](<./角色/角色索引.md>) | 各角色稳定职责卡 |
| [统一计划台账](<../任务/统一计划台账.md>) | 当前任务、优先级和下一责任人 |
| [协作事件](<../任务/协作事件.md>) | 跨角色请求和结果事实源 |
diff --git "a/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\350\247\222\350\211\262/\350\247\222\350\211\262\344\274\232\350\257\235\346\270\205\345\215\225.md" "b/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\350\247\222\350\211\262/\350\247\222\350\211\262\344\274\232\350\257\235\346\270\205\345\215\225.md"
index f08f3d8..9f92acc 100644
--- "a/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\350\247\222\350\211\262/\350\247\222\350\211\262\344\274\232\350\257\235\346\270\205\345\215\225.md"
+++ "b/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\350\247\222\350\211\262/\350\247\222\350\211\262\344\274\232\350\257\235\346\270\205\345\215\225.md"
@@ -8,11 +8,11 @@
| --- | --- | --- | --- | --- |
| 产品与项目管理 | SalesCRM|产品与项目管理 | `019f6ea8-234e-7450-80fd-edc7c8c5438b` | PASS | [职责卡](<./02-产品与项目管理.md>) |
| 架构与数据治理 | SalesCRM|架构与数据治理 | `019f6f85-bee8-7f70-8d0a-af638ece0782` | PASS,已接替旧会话并通过两次提交验证 | [职责卡](<./03-架构与数据治理.md>) |
-| UI与交互设计 | SalesCRM|UI与交互设计 | `019f6f41-7c33-7200-97b4-5bb4690de8c2` | PASS,已接替旧会话 | [职责卡](<./04-UI与交互设计.md>) |
-| 前端开发 | SalesCRM|前端开发 | `019f6ea8-7abd-7ca2-8b6c-8e3e54cfd8b1` | PASS | [职责卡](<./05-前端开发.md>) |
-| 后端开发 | SalesCRM|后端开发 | `019f6ea8-9633-7a82-9034-789ecc7888da` | PASS | [职责卡](<./06-后端开发.md>) |
+| UI与交互设计 | SalesCRM|UI与交互设计 | `019f6fa9-44a2-7313-892d-886b43af1be9` | PASS,已接替异常会话并完成QUEUE-013 | [职责卡](<./04-UI与交互设计.md>) |
+| 前端开发 | SalesCRM|前端开发 | `019f7097-ba42-7610-a05d-2d427d3027db` | PASS,已接替卡死会话并完成QUEUE-039最小实现 | [职责卡](<./05-前端开发.md>) |
+| 后端开发 | SalesCRM|后端开发 | `019f708a-ed37-72b0-887d-77a00f869701` | PASS,已接替故障会话并完成QUEUE-040最小实现 | [职责卡](<./06-后端开发.md>) |
| 代码审核与安全 | SalesCRM|代码审核与安全 | `019f6ea8-b081-7121-9d98-4c9714bf50e1` | PASS | [职责卡](<./07-代码审核与安全.md>) |
-| 测试与质量 | SalesCRM|测试与质量 | `019f6ea8-ca49-7472-9a9e-24848071c22b` | PASS | [职责卡](<./08-测试与质量.md>) |
+| 测试与质量 | SalesCRM|测试与质量 | `019f70f1-b6bd-7d82-9c43-d254c66f46b9` | PASS,已接替故障会话并完成QUEUE-043隔离验收 | [职责卡](<./08-测试与质量.md>) |
| 运维与发布 | SalesCRM|运维与发布 | `019f6ea8-ec46-70d2-9122-0968c7946c23` | PASS | [职责卡](<./09-运维与发布.md>) |
Owner由当前主会话中的用户承担,不另建会话。角色任务只从统一计划台账和协作事件领取,创建会话不等于自动授权实现。
@@ -23,5 +23,9 @@
## 历史角色会话
-- 原架构与数据治理会话 `019f6ea8-3df3-7260-a18f-18adb6ebef63` 已重命名为“历史|架构与数据治理(已停用)”并保留历史评审记录。该会话在界面提交消息时返回`Error submitting message`且任务列表状态为`notLoaded`,因此自CRM-20260717-008起不再承担新任务;其队列没有遗留业务项,由新正式架构会话接管。
-- 原UI与交互设计会话 `019f6ea8-61fa-7fa3-ae43-2a11f6b6f354` 保留历史评审记录。该会话在QUEUE-20260717-003首次投递未启动turn,随后两次恢复投递均失败,因此自CRM-20260717-007起不再承担新任务;队列项未丢失,由新正式UI会话继续处理。
+- 原测试与质量会话 `019f6ea8-ca49-7472-9a9e-24848071c22b` 连续两次投递未产生新turn后停止投递;首个替代会话 `019f70ec-c8b9-7312-97b6-ce9d0b58976e` 在事实源核对阶段发生`systemError`,未执行测试或产生修改。新正式会话 `019f70f1-b6bd-7d82-9c43-d254c66f46b9` 继承同一QUEUE-043检查点,使用虚构内存数据完成19/19项隔离验收并回传COLLAB-149;两个旧入口均不再承担新任务。
+- 原前端开发会话 `019f6ea8-7abd-7ca2-8b6c-8e3e54cfd8b1` 连续两次启动turn失败后停止投递。新正式会话 `019f702e-eb7e-70d3-8271-06269945435a` 完整回读其6个已完成turn至`hasMore=false`,恢复同一QUEUE-024并完成v0.4复评;旧会话无遗留任务,已重命名并归档。
+- 原后端开发会话 `019f6ea8-9633-7a82-9034-789ecc7888da` 连续两次未能启动新turn后停止投递。新正式会话 `019f7014-60d2-7972-ba52-46d834fe49f2` 完整回读其5个已完成turn至`hasMore=false`,恢复同一QUEUE-032并完成v0.4可实施性确认;旧会话无遗留任务,已重命名并归档。
+- 原架构与数据治理会话 `019f6ea8-3df3-7260-a18f-18adb6ebef63` 已重命名为“历史|架构与数据治理(已停用)”并归档。新正式架构会话完整回读其历史、恢复模块化单体讨论并通过接管验证;原会话不再承担新任务。
+- 第二代UI与交互设计会话 `019f6f41-7c33-7200-97b4-5bb4690de8c2` 已重命名为“历史|UI与交互设计(已停用2)”并归档。它保留QUEUE-003接管记录,但QUEUE-013两次未产生turn;第三代正式UI完整回读历史并恢复同一QUEUE-013。
+- 第一代UI与交互设计会话 `019f6ea8-61fa-7fa3-ae43-2a11f6b6f354` 已重命名为“历史|UI与交互设计(已停用1)”并归档。第三代正式UI已完整回读其2个turn及第二代1个turn,确认QUEUE-003/013没有取消、替换、跳过或丢失。
diff --git "a/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\350\247\222\350\211\262/\350\247\222\350\211\262\347\264\242\345\274\225.md" "b/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\350\247\222\350\211\262/\350\247\222\350\211\262\347\264\242\345\274\225.md"
index 7451748..14af549 100644
--- "a/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\350\247\222\350\211\262/\350\247\222\350\211\262\347\264\242\345\274\225.md"
+++ "b/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\350\247\222\350\211\262/\350\247\222\350\211\262\347\264\242\345\274\225.md"
@@ -6,14 +6,18 @@
| --- | --- | --- | --- |
| 01 | [项目Owner](<./01-项目Owner.md>) | 活跃,当前主会话 | 方向、优先级、重大范围和风险裁决 |
| 02 | [产品与项目管理](<./02-产品与项目管理.md>) | 活跃,独立会话 | 需求入口、计划台账、Gate汇总、产品验收 |
-| 03 | [架构与数据治理](<./03-架构与数据治理.md>) | 活跃,独立会话 | 技术边界、数据设计、契约和架构裁决 |
+| 03 | [架构与数据治理](<./03-架构与数据治理.md>) | 活跃,独立会话 | 技术边界、数据设计、Web/移动端共享契约和架构裁决 |
| 04 | [UI与交互设计](<./04-UI与交互设计.md>) | 按需,独立会话 | 信息架构、交互规格和设计验收 |
-| 05 | [前端开发](<./05-前端开发.md>) | 活跃,独立会话 | Web前端实现、自测和部署后验证 |
-| 06 | [后端开发](<./06-后端开发.md>) | 活跃,独立会话 | Node.js API、数据访问、鉴权和后端自测 |
+| 05 | [前端开发](<./05-前端开发.md>) | 活跃,独立会话 | Web前端实现、自测和部署后验证;不代替未来移动客户端角色 |
+| 06 | [后端开发](<./06-后端开发.md>) | 活跃,独立会话 | 面向Web/移动端的Node.js API、数据访问、鉴权和后端自测 |
| 07 | [代码审核与安全](<./07-代码审核与安全.md>) | 活跃,独立会话 | 独立Gate C、安全与数据风险审查 |
-| 08 | [测试与质量](<./08-测试与质量.md>) | 活跃,独立会话 | Web/API/权限/数据回归和Gate A |
+| 08 | [测试与质量](<./08-测试与质量.md>) | 活跃,独立会话 | Web/API/权限/数据回归、移动契约前置验证和Gate A |
| 09 | [运维与发布](<./09-运维与发布.md>) | 活跃,独立会话 | 部署、备份、回滚、运行机械证据 |
## 通用要求
每个角色开始工作前必须读取根目录 `AGENTS.md`、项目导读、全局约束、开发迭代流程、统一计划台账、本职责卡和自己的[角色任务队列](<../../任务/角色队列/导读.md>)。只有队首任务获得唯一执行锁后才能开工;新消息默认排队,不得覆盖当前任务。任务输入缺少目标、范围、验收或当前 Gate 时,角色应回写 `CHANGES_REQUESTED` 或 `BLOCKED`,不能自行补造上游结论。
+
+## 移动端职责激活说明
+
+Owner已确认移动端进入后续范围,因此共享API、认证边界、幂等和多客户端契约现在纳入现有架构、后端、审核安全和测试职责。当前没有移动客户端实现任务,Web前端角色不自动承担APP开发。开始原生或跨平台客户端实现前,产品与项目管理必须冻结平台、技术栈、首期功能、弱网/离线、设备能力和分发方式,并补齐对应开发、平台测试、打包职责卡、正式会话和唯一队列锁。
diff --git "a/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\350\247\222\350\211\262\344\274\232\350\257\235\344\270\262\350\241\214\350\260\203\345\272\246\350\247\204\350\214\203.md" "b/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\350\247\222\350\211\262\344\274\232\350\257\235\344\270\262\350\241\214\350\260\203\345\272\246\350\247\204\350\214\203.md"
index b929b3d..738143f 100644
--- "a/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\350\247\222\350\211\262\344\274\232\350\257\235\344\270\262\350\241\214\350\260\203\345\272\246\350\247\204\350\214\203.md"
+++ "b/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\350\247\222\350\211\262\344\274\232\350\257\235\344\270\262\350\241\214\350\260\203\345\272\246\350\247\204\350\214\203.md"
@@ -38,7 +38,7 @@
## 标准投递算法
1. 在统一计划台账和协作事件中确认任务授权、范围、验收和目标角色。
-2. 在目标角色自己的队列文件中追加`QUEUED`项,记录唯一队列编号、任务编号和事件编号。
+2. 扫描全部角色队列后分配全局唯一的队列编号,再在目标角色自己的队列文件中追加`QUEUED`项,记录队列编号、任务编号和事件编号;并发登记发生占号时,后登记项必须先更正编号再投递。
3. 读取角色队列:如有`RUNNING/WAITING`,停止投递,新项保持排队。
4. 读取实际Codex会话状态:如为`active`或存在进行中turn,停止投递;即使队列误写为空闲也不得发送。
5. 只有“队列无执行锁 + 会话为idle,或notLoaded且无进行中turn”同时成立时,才把队首项改为`RUNNING`并写入执行锁。
@@ -63,6 +63,8 @@
| 队列项缺任务/事件编号 | `CHANGES_REQUESTED`,不得投递 |
| 同一角色出现两个`RUNNING/WAITING` | `BLOCKED`,由项目管理员修复队列后再继续 |
+如果异常属于会话入口不可用,不能只创建新Thread并修改ID。必须继续执行[会话故障迁移与交接规范](<./会话故障迁移与交接规范.md>):冻结旧会话、完整回读历史、新会话恢复同一队列项、交接验收、正式入口切换,最后归档旧会话。
+
## 调度责任
- 产品与项目管理:维护业务优先级、协作事件和队列顺序。
diff --git "a/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\351\207\207\347\224\250\344\270\216\350\243\201\345\211\252\350\256\260\345\275\225.md" "b/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\351\207\207\347\224\250\344\270\216\350\243\201\345\211\252\350\256\260\345\275\225.md"
index b1e7d45..e5e5c9f 100644
--- "a/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\351\207\207\347\224\250\344\270\216\350\243\201\345\211\252\350\256\260\345\275\225.md"
+++ "b/docs/\347\240\224\345\217\221\344\275\223\347\263\273/\351\207\207\347\224\250\344\270\216\350\243\201\345\211\252\350\256\260\345\275\225.md"
@@ -8,7 +8,7 @@
## 采用结论
-SalesCRM 采用标准模式。保留需求入口、架构设计、实现、自测、独立审核、独立测试、部署和产品验收的责任链;不原样复制来源项目的组织、Java/Maven、移动端和多仓细节。
+SalesCRM 采用标准模式。保留需求入口、架构设计、实现、自测、独立审核、独立测试、部署和产品验收的责任链;不原样复制来源项目的组织、Java/Maven和多仓细节。移动端已进入后续产品方向,当前先激活多客户端API和安全边界,具体客户端角色随平台与任务范围再激活。
## 本地化调整
@@ -19,9 +19,9 @@
| Java/Spring/MyBatis 专项 | 不采用;后端规范按 Node.js 当前事实和后续技术选型另行制定 |
| 多仓、多 worktree | 当前为单仓;复杂并行需求再启用 worktree |
| `MMDD-英文任务slug` | 本项目改为 `MMDD-中文任务名`;Owner 已明确要求文件习惯使用中文,工具强制名称才保留英文并记录原因 |
-| iOS/Android/APP/NativeSDK | 当前 `N/A`,原因是项目只有 Web 管理端 |
-| APP 打包 | 当前 `N/A`,发布产物是 Web 静态页面和 Node.js 服务 |
-| SQL 流程 | 当前处于条件适用;数据库选型和迁移进入 Gate R 后正式启用 |
+| iOS/Android/APP/NativeSDK | 移动端进入后续范围;共享API/认证/契约现在适用,原生或跨平台客户端职责待平台和首期范围冻结后激活;NativeSDK仍按独立SDK需求判断 |
+| APP 打包 | 条件待激活;当前没有APK/IPA等客户端产物,也未授权移动端发布 |
+| SQL 流程 | 已进入方案适用;目标数据库冻结为MySQL,具体Schema和迁移仍须逐任务通过Gate R后实施 |
| 全系统 L4 重建 | 当前先以 L2“主流程可重建”为目标,架构改造后再提升 |
## 激活角色
@@ -36,15 +36,17 @@
8. 测试与质量
9. 运维与发布
-## 不适用角色
+## 条件适用与待激活角色
| 角色 | 结论 | 原因 | 重新激活条件 |
| --- | --- | --- | --- |
-| APP开发 | N/A | 当前无移动客户端 | Owner 批准移动端产品范围 |
+| APP开发 | 条件待激活 | Owner已确认后续建设移动端,但平台、技术栈和首期客户端任务未冻结 | Owner/产品冻结平台、首期功能和交付方式,建立职责卡、会话和队列 |
| NativeSDK开发 | N/A | 当前无 SDK 产物 | 形成 SDK 正式需求 |
-| iOS测试 | N/A | 当前无 iOS 影响面 | iOS 客户端进入范围 |
-| Android测试 | N/A | 当前无 Android 影响面 | Android 客户端进入范围 |
-| APP打包 | N/A | 当前无 APK/IPA | 移动端发布链建立 |
+| iOS测试 | 条件待激活 | 当前无 iOS 客户端产物 | iOS进入冻结平台范围并有可测版本 |
+| Android测试 | 条件待激活 | 当前无 Android 客户端产物 | Android进入冻结平台范围并有可测版本 |
+| APP打包 | 条件待激活 | 当前无 APK/IPA且禁止生产发布 | 平台、签名托管、分发渠道和移动端发布链通过独立Gate |
+
+当前激活角色中的架构、后端、代码审核与安全、测试与质量应立即把移动场景纳入共享API、Token生命周期、幂等重试和契约验证;前端开发仍只承担Web客户端,不自动代签或承担未来原生/跨平台客户端实现。
## 不可裁剪原则
diff --git a/outputs/sales_crm_full_demo.html b/outputs/sales_crm_full_demo.html
index bbbbd40..6afcf0c 100644
--- a/outputs/sales_crm_full_demo.html
+++ b/outputs/sales_crm_full_demo.html
@@ -111,10 +111,26 @@
.login-card h2 { margin: 0 0 6px; font-size: 22px; }
.login-card .field { margin-top: 14px; }
.account-chip { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
+ .password-modal { display: none; position: fixed; inset: 0; z-index: 30; align-items: center; justify-content: center; padding: 16px; background: rgba(15, 23, 42, .48); }
+ .password-modal.active { display: flex; }
+ .password-card { width: min(460px, 100%); max-height: calc(100vh - 32px); overflow-y: auto; background: #fff; border: 1px solid #d9e0ea; border-radius: 10px; box-shadow: 0 20px 50px rgba(15, 23, 42, .24); }
+ .password-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 18px 18px 12px; border-bottom: 1px solid #e5eaf1; }
+ .password-head h2 { margin: 0; font-size: 20px; }
+ .password-form { display: grid; gap: 14px; padding: 18px; }
+ .password-form .field label { color: #334155; font-size: 13px; font-weight: 700; }
+ .password-form input:focus, .password-form button:focus-visible, #changePasswordButton:focus-visible { outline: 3px solid rgba(37, 99, 235, .3); outline-offset: 2px; }
+ .password-form input[aria-invalid="true"] { border-color: #c24136; }
+ .password-hint { color: #66758b; font-size: 12px; margin-top: 5px; }
+ .password-status { display: none; border: 1px solid #fecaca; background: #fff1f1; color: #991b1b; padding: 10px 12px; border-radius: 8px; }
+ .password-status.show { display: block; }
+ .password-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 2px; }
+ .password-actions .btn { min-height: 44px; }
+ .alert.notice { border-color: #cfe0ff; background: #eef5ff; color: #1d4ed8; }
.permission-grid { display: grid; grid-template-columns: repeat(3, minmax(160px, 1fr)); gap: 8px 12px; padding: 10px; border: 1px solid #dde3ec; border-radius: 8px; background: #fbfcfe; }
.permission-grid label { display: flex; gap: 7px; align-items: center; color: #334155; font-size: 13px; margin: 0; }
.permission-grid input { width: auto; }
- @media (max-width: 960px) { body { overflow: auto; } .app { grid-template-columns: 1fr; height: auto; } header { height: auto; padding: 14px; flex-direction: column; align-items: flex-start; } .stats, .grid, .form, .permission-grid, .sheet-top, .sheet-lower, .settle-grid { grid-template-columns: 1fr; } .wide { grid-column: span 1; } aside { position: static; height: auto; max-height: 46vh; } main { height: auto; overflow: visible; } .panel { overflow-x: auto; } table { min-width: 860px; } .sheet-card { inset: 10px; min-width: 0; } }
+ @media (max-width: 960px) { body { overflow: auto; } .app { grid-template-columns: 1fr; height: auto; } header { height: auto; padding: 14px; flex-direction: column; align-items: flex-start; } .account-chip { justify-content: flex-start; } .stats, .grid, .form, .permission-grid, .sheet-top, .sheet-lower, .settle-grid { grid-template-columns: 1fr; } .wide { grid-column: span 1; } aside { position: static; height: auto; max-height: 46vh; } main { height: auto; overflow: visible; } .panel { overflow-x: auto; } table { min-width: 860px; } .sheet-card { inset: 10px; min-width: 0; } }
+ @media (max-width: 480px) { .password-modal { align-items: flex-start; padding: 16px; overflow-y: auto; } .password-card { max-height: none; } .password-head, .password-form { padding-left: 16px; padding-right: 16px; } .password-actions { flex-direction: column-reverse; } .password-actions .btn { width: 100%; } }
</style>
</head>
<body>
@@ -184,7 +200,7 @@
<main>
<header>
<div><h1 id="title">工作台</h1><div class="sub" id="subtitle">请先登录账号。</div></div>
- <div class="account-chip"><span class="tag blue-tag" id="accountBadge">未登录</span><button class="btn" onclick="logout()">退出</button></div>
+ <div class="account-chip"><span class="tag blue-tag" id="accountBadge">未登录</span><button class="btn" id="changePasswordButton" type="button" onclick="openPasswordChangeModal()" hidden>修改密码</button><button class="btn" type="button" onclick="logout()">退出</button></div>
</header>
<div class="workspace-tabs" id="workspaceTabs"></div>
<section class="content">
@@ -578,6 +594,34 @@
</div>
</div>
</div>
+
+ <div class="password-modal" id="passwordChangeModal" aria-hidden="true">
+ <div class="password-card" role="dialog" aria-modal="true" aria-labelledby="passwordChangeTitle" aria-describedby="passwordChangeDescription">
+ <div class="password-head">
+ <div><h2 id="passwordChangeTitle">修改密码</h2><div class="sub" id="passwordChangeDescription">修改成功后将退出当前登录,请使用新密码重新登录。</div></div>
+ </div>
+ <form class="password-form" id="passwordChangeForm" novalidate>
+ <div class="field">
+ <label for="currentPassword">当前密码</label>
+ <input id="currentPassword" name="currentPassword" type="password" autocomplete="current-password" aria-describedby="passwordChangeAlert" required>
+ </div>
+ <div class="field">
+ <label for="newPassword">新密码</label>
+ <input id="newPassword" name="newPassword" type="password" autocomplete="new-password" aria-describedby="newPasswordHint passwordChangeAlert" required>
+ <div class="password-hint" id="newPasswordHint">8至64个Unicode码点,输入内容不会被裁剪或规范化。</div>
+ </div>
+ <div class="field">
+ <label for="confirmPassword">确认新密码</label>
+ <input id="confirmPassword" name="confirmPassword" type="password" autocomplete="new-password" aria-describedby="passwordChangeAlert" required>
+ </div>
+ <div class="password-status" id="passwordChangeAlert" role="alert" aria-live="assertive" tabindex="-1"></div>
+ <div class="password-actions">
+ <button class="btn" id="passwordChangeCancel" type="button" onclick="closePasswordChangeModal()">取消</button>
+ <button class="btn primary" id="passwordChangeSubmit" type="submit">确认修改</button>
+ </div>
+ </form>
+ </div>
+ </div>
<div class="toast" id="toast"></div>
<script>
@@ -623,6 +667,8 @@
const localStoreKey = "sales_crm_full_demo_state_v1";
const accountStoreKey = "sales_crm_account_v1";
let auth = null;
+ let passwordChangeSubmitting = false;
+ let passwordChangeReturnFocus = null;
localStorage.removeItem(accountStoreKey);
const dealStatuses = ["已成交", "待发货/执行", "已交付", "售后维护中", "复购跟进中"];
const customerCategoryOptions = ["公众号", "快手", "抖音", "淘宝店铺", "天猫", "京东POP", "京东自营", "百度", "视频号", "360", "阿里店铺", "阿里新店", "爱采购", "微信小店", "小红书", "1688商家", "公司自营", "渠道经销商", "线上经销商", "其他"];
@@ -688,6 +734,165 @@
}
throw err;
});
+ }
+
+ const passwordChangeErrorMessages = Object.freeze({
+ INVALID_REQUEST: "请求无效,请检查输入后重试。",
+ AUTHENTICATION_REQUIRED: "登录状态已失效,请重新登录。",
+ ACCOUNT_DISABLED: "账号不可用,请联系主管。",
+ CURRENT_PASSWORD_INCORRECT: "当前密码不正确。",
+ PASSWORD_LENGTH_INVALID: "新密码必须为8至64个Unicode码点。",
+ NEW_PASSWORD_SAME_AS_CURRENT: "新密码不能与当前密码相同。",
+ PASSWORD_UPDATE_CONFLICT: "账号状态已变化,请重新登录后再试。",
+ PASSWORD_CHANGE_UNAVAILABLE: "修改密码服务暂时不可用,请稍后手动重试。",
+ INTERNAL_ERROR: "修改失败,请稍后重试。"
+ });
+
+ async function requestPasswordChange(currentPassword, newPassword) {
+ if (!auth?.token) {
+ const error = new Error("Password change authentication required");
+ error.code = "AUTHENTICATION_REQUIRED";
+ throw error;
+ }
+ const controller = new AbortController();
+ const timeout = setTimeout(() => controller.abort(), 15000);
+ try {
+ const response = await fetch(apiBase + "/api/v1/me/password/change", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: `Bearer ${auth.token}`
+ },
+ body: JSON.stringify({ currentPassword, newPassword }),
+ cache: "no-store",
+ signal: controller.signal
+ });
+ if (response.status === 204) return;
+
+ let code = "";
+ try {
+ const data = await response.json();
+ if (typeof data?.error?.code === "string") code = data.error.code;
+ } catch {
+ code = "";
+ }
+ const error = new Error("Password change failed");
+ error.code = Object.prototype.hasOwnProperty.call(passwordChangeErrorMessages, code) ? code : "UNKNOWN_RESPONSE";
+ throw error;
+ } catch (error) {
+ if (error.name === "AbortError" || error instanceof TypeError) {
+ const networkError = new Error("Password change unavailable");
+ networkError.code = "PASSWORD_CHANGE_UNAVAILABLE";
+ throw networkError;
+ }
+ throw error;
+ } finally {
+ clearTimeout(timeout);
+ }
+ }
+
+ function clearPasswordChangeFeedback() {
+ const alert = document.getElementById("passwordChangeAlert");
+ alert.textContent = "";
+ alert.classList.remove("show");
+ document.querySelectorAll("#passwordChangeForm input").forEach(input => input.removeAttribute("aria-invalid"));
+ }
+
+ function clearPasswordChangeForm() {
+ document.getElementById("passwordChangeForm").reset();
+ clearPasswordChangeFeedback();
+ }
+
+ function setPasswordChangeError(message, fieldName = "") {
+ clearPasswordChangeFeedback();
+ const alert = document.getElementById("passwordChangeAlert");
+ alert.textContent = message;
+ alert.classList.add("show");
+ const field = fieldName ? document.querySelector(`#passwordChangeForm [name="${fieldName}"]`) : null;
+ if (field) {
+ field.setAttribute("aria-invalid", "true");
+ field.focus();
+ } else {
+ alert.focus?.();
+ }
+ }
+
+ function setPasswordChangeBusy(busy) {
+ passwordChangeSubmitting = busy;
+ document.querySelectorAll("#passwordChangeForm input, #passwordChangeForm button").forEach(control => { control.disabled = busy; });
+ const submit = document.getElementById("passwordChangeSubmit");
+ submit.textContent = busy ? "正在修改…" : "确认修改";
+ document.getElementById("passwordChangeForm").setAttribute("aria-busy", busy ? "true" : "false");
+ }
+
+ function openPasswordChangeModal() {
+ if (!auth?.token || passwordChangeSubmitting) return;
+ passwordChangeReturnFocus = document.activeElement;
+ clearPasswordChangeForm();
+ const modal = document.getElementById("passwordChangeModal");
+ modal.classList.add("active");
+ modal.setAttribute("aria-hidden", "false");
+ const app = document.querySelector(".app");
+ app.inert = true;
+ app.setAttribute("aria-hidden", "true");
+ document.body.style.overflow = "hidden";
+ document.getElementById("currentPassword").focus();
+ }
+
+ function closePasswordChangeModal(options = {}) {
+ if (passwordChangeSubmitting && !options.force) return;
+ clearPasswordChangeForm();
+ const modal = document.getElementById("passwordChangeModal");
+ modal.classList.remove("active");
+ modal.setAttribute("aria-hidden", "true");
+ const app = document.querySelector(".app");
+ app.inert = false;
+ app.removeAttribute("aria-hidden");
+ document.body.style.overflow = "";
+ if (options.restoreFocus !== false && passwordChangeReturnFocus?.focus) passwordChangeReturnFocus.focus();
+ passwordChangeReturnFocus = null;
+ }
+
+ function validatePasswordChange(form) {
+ clearPasswordChangeFeedback();
+ const currentPassword = form.elements.currentPassword.value;
+ const newPassword = form.elements.newPassword.value;
+ const confirmPassword = form.elements.confirmPassword.value;
+ if (!currentPassword) return { message: "请输入当前密码。", field: "currentPassword" };
+ if (!newPassword) return { message: "请输入新密码。", field: "newPassword" };
+ if (!confirmPassword) return { message: "请再次输入新密码。", field: "confirmPassword" };
+ const codePointLength = Array.from(newPassword).length;
+ if (codePointLength < 8 || codePointLength > 64) return { message: passwordChangeErrorMessages.PASSWORD_LENGTH_INVALID, field: "newPassword" };
+ if (newPassword === currentPassword) return { message: passwordChangeErrorMessages.NEW_PASSWORD_SAME_AS_CURRENT, field: "newPassword" };
+ if (confirmPassword !== newPassword) return { message: "两次输入的新密码不一致。", field: "confirmPassword" };
+ return { currentPassword, newPassword };
+ }
+
+ function handlePasswordChangeError(error) {
+ const code = error?.code || "UNKNOWN_RESPONSE";
+ if (code === "AUTHENTICATION_REQUIRED") {
+ logout(passwordChangeErrorMessages[code]);
+ return;
+ }
+ if (code === "ACCOUNT_DISABLED") {
+ logout(passwordChangeErrorMessages[code]);
+ return;
+ }
+ if (code === "PASSWORD_UPDATE_CONFLICT") {
+ logout(passwordChangeErrorMessages[code]);
+ return;
+ }
+ if (code === "CURRENT_PASSWORD_INCORRECT") {
+ document.getElementById("currentPassword").value = "";
+ setPasswordChangeError(passwordChangeErrorMessages[code], "currentPassword");
+ return;
+ }
+ if (code === "PASSWORD_LENGTH_INVALID" || code === "NEW_PASSWORD_SAME_AS_CURRENT") {
+ setPasswordChangeError(passwordChangeErrorMessages[code], "newPassword");
+ return;
+ }
+ const message = passwordChangeErrorMessages[code] || "修改失败,未确认任何更改,请稍后重试。";
+ setPasswordChangeError(message);
}
function loadLocalState() {
@@ -1129,6 +1334,7 @@
? `当前账号:${currentUser}。可管理账号权限和全部业务。`
: `当前账号:${currentUser}。已开通 ${permissionCount} 项权限,按权限显示对应功能。`;
document.getElementById("accountBadge").textContent = `${currentUser}|${roleText}`;
+ document.getElementById("changePasswordButton").hidden = false;
const accountsNav = document.getElementById("accountsNav");
if (accountsNav) accountsNav.style.display = hasPerm("accounts:manage") ? "" : "none";
if (!hasPerm("accounts:manage") && activeView === "accounts") setView("dashboard");
@@ -1229,12 +1435,32 @@
document.getElementById("loginScreen").classList.remove("active");
}
- function logout() {
+ function logout(message = "", notice = false) {
+ closePasswordChangeModal({ force: true, restoreFocus: false });
auth = null;
localStorage.removeItem(accountStoreKey);
state = { customers: [], reminders: [] };
+ role = "sales";
+ currentUser = "";
+ activeView = "dashboard";
+ activeFeature = "dashboard";
+ openedTabs = [{ view: "dashboard", feature: "dashboard", title: "工作台" }];
+ closeDrawer();
document.getElementById("accountBadge").textContent = "未登录";
+ document.getElementById("changePasswordButton").hidden = true;
+ document.getElementById("subtitle").textContent = "请先登录账号。";
+ document.querySelectorAll(".view").forEach(view => view.classList.toggle("active", view.id === "dashboard"));
+ document.querySelectorAll(".nav button").forEach(button => button.classList.toggle("active", button.dataset.view === "dashboard"));
+ document.getElementById("title").textContent = "工作台";
+ render();
+ const loginForm = document.getElementById("loginForm");
+ loginForm.elements.password.value = "";
+ const loginAlert = document.getElementById("loginAlert");
+ loginAlert.textContent = message;
+ loginAlert.classList.toggle("show", !!message);
+ loginAlert.classList.toggle("notice", !!message && notice);
showLogin();
+ setTimeout(() => loginForm.elements.username.focus(), 0);
}
function updateOwnerControls() {
@@ -2338,11 +2564,52 @@
setPermissionChecks(defaultPermissionSet(event.target.value));
});
renderPermissionChecks(defaultPermissionSet("sales"));
+ document.getElementById("passwordChangeForm").addEventListener("submit", async (event) => {
+ event.preventDefault();
+ if (passwordChangeSubmitting) return;
+ const form = event.currentTarget;
+ const values = validatePasswordChange(form);
+ if (values.message) {
+ setPasswordChangeError(values.message, values.field);
+ return;
+ }
+ setPasswordChangeBusy(true);
+ try {
+ await requestPasswordChange(values.currentPassword, values.newPassword);
+ setPasswordChangeBusy(false);
+ logout("密码已修改,请使用新密码重新登录。", true);
+ } catch (error) {
+ setPasswordChangeBusy(false);
+ handlePasswordChangeError(error);
+ }
+ });
+ document.getElementById("passwordChangeModal").addEventListener("keydown", (event) => {
+ if (!event.currentTarget.classList.contains("active")) return;
+ if (event.key === "Escape") {
+ if (!passwordChangeSubmitting) {
+ event.preventDefault();
+ closePasswordChangeModal();
+ }
+ return;
+ }
+ if (event.key !== "Tab" || passwordChangeSubmitting) return;
+ const focusable = [...event.currentTarget.querySelectorAll("input:not([disabled]), button:not([disabled]), [tabindex]:not([tabindex='-1'])")];
+ if (!focusable.length) return;
+ const first = focusable[0];
+ const last = focusable[focusable.length - 1];
+ if (event.shiftKey && document.activeElement === first) {
+ event.preventDefault();
+ last.focus();
+ } else if (!event.shiftKey && document.activeElement === last) {
+ event.preventDefault();
+ first.focus();
+ }
+ });
document.getElementById("loginForm").addEventListener("submit", async (event) => {
event.preventDefault();
const form = event.target;
const loginAlert = document.getElementById("loginAlert");
- loginAlert.classList.remove("show");
+ loginAlert.classList.remove("show", "notice");
try {
const body = Object.fromEntries(new FormData(form).entries());
const result = await api("/api/login", { method: "POST", body: JSON.stringify(body) });
diff --git a/work/crm_full_server.js b/work/crm_full_server.js
index 9d5f451..df82345 100644
--- a/work/crm_full_server.js
+++ b/work/crm_full_server.js
@@ -1,4 +1,5 @@
const http = require("http");
+const crypto = require("crypto");
const fs = require("fs");
const path = require("path");
@@ -33,6 +34,9 @@
"reports:view",
"accounts:manage"
]);
+const accountWriteLocks = new Map();
+const passwordChangePath = "/api/v1/me/password/change";
+const passwordChangeBodyLimit = 16 * 1024;
const defaultUsers = [
{ username: "admin", password: "123456", name: "主管", role: "supervisor" },
{ username: "ops1", password: "123456", name: "运营一", role: "ops" },
@@ -130,6 +134,30 @@
function accountFromToken(token, data) {
if (!token) return null;
return getUsers(data).find((user) => user.status !== "disabled" && makeToken(user) === token) || null;
+}
+
+function accountFromTokenIncludingDisabled(token, data) {
+ if (!token) return null;
+ return getUsers(data).find((user) => makeToken(user) === token) || null;
+}
+
+function bearerTokenFromHeader(req) {
+ const auth = String(req.headers.authorization || "");
+ return auth.startsWith("Bearer ") && auth.length > 7 ? auth.slice(7) : "";
+}
+
+function passwordChangeError(status, code, message) {
+ const err = new Error(message);
+ err.status = status;
+ err.passwordChangeCode = code;
+ return err;
+}
+
+function dataVersionConflictError() {
+ const err = new Error("数据已被其他请求更新");
+ err.status = 409;
+ err.code = "DATA_VERSION_CONFLICT";
+ return err;
}
function requireAccount(req, url, body = {}, data = load()) {
@@ -414,11 +442,55 @@
return data;
}
-function save(data) {
- data._version = (Number(data._version) || 0) + 1;
- const tmpFile = `${dataFile}.${process.pid}.tmp`;
- fs.writeFileSync(tmpFile, JSON.stringify(data, null, 2), "utf8");
- fs.renameSync(tmpFile, dataFile);
+function dataVersion(data) {
+ const value = Number(data && data._version);
+ return Number.isSafeInteger(value) && value >= 0 ? value : 0;
+}
+
+function save(data, expectedVersion = dataVersion(data)) {
+ ensureData();
+ const stored = JSON.parse(fs.readFileSync(dataFile, "utf8"));
+ if (dataVersion(stored) !== expectedVersion) throw dataVersionConflictError();
+
+ const nextData = { ...data, _version: expectedVersion + 1 };
+ const tmpFile = `${dataFile}.${process.pid}.${crypto.randomUUID()}.tmp`;
+ try {
+ fs.writeFileSync(tmpFile, JSON.stringify(nextData, null, 2), "utf8");
+ fs.renameSync(tmpFile, dataFile);
+ data._version = nextData._version;
+ } finally {
+ if (fs.existsSync(tmpFile)) {
+ try { fs.unlinkSync(tmpFile); } catch (_) { /* best-effort cleanup */ }
+ }
+ }
+}
+
+async function withAccountWriteLock(accountKey, task) {
+ const key = String(accountKey);
+ const previous = accountWriteLocks.get(key) || Promise.resolve();
+ let release;
+ const current = new Promise((resolve) => { release = resolve; });
+ accountWriteLocks.set(key, current);
+ await previous;
+ try {
+ return await task();
+ } finally {
+ release();
+ if (accountWriteLocks.get(key) === current) accountWriteLocks.delete(key);
+ }
+}
+
+function mutateAccountWithCas(accountKey, expectedVersion, mutator, store = { load, save }) {
+ return withAccountWriteLock(accountKey, () => {
+ const data = store.load();
+ if (dataVersion(data) !== expectedVersion) throw dataVersionConflictError();
+ const result = mutator(data);
+ if (result && typeof result.then === "function") {
+ throw new Error("账号写入回调必须同步完成");
+ }
+ store.save(data, expectedVersion);
+ return result;
+ });
}
function requireSupervisor(account) {
@@ -427,6 +499,12 @@
err.status = 403;
throw err;
}
+}
+
+function httpError(status, message) {
+ const err = new Error(message);
+ err.status = status;
+ return err;
}
function action(data, customer, user, type, title, content) {
@@ -450,6 +528,137 @@
try { resolve(raw ? JSON.parse(raw) : {}); } catch (err) { reject(err); }
});
});
+}
+
+function parsePasswordChangeBody(req) {
+ return new Promise((resolve, reject) => {
+ let raw = "";
+ let size = 0;
+ let tooLarge = false;
+ req.on("data", (chunk) => {
+ size += chunk.length;
+ if (size > passwordChangeBodyLimit) {
+ tooLarge = true;
+ raw = "";
+ } else if (!tooLarge) {
+ raw += chunk;
+ }
+ });
+ req.on("end", () => {
+ if (tooLarge || !raw) {
+ reject(passwordChangeError(400, "INVALID_REQUEST", "请求无效"));
+ return;
+ }
+ try {
+ resolve(JSON.parse(raw));
+ } catch (_) {
+ reject(passwordChangeError(400, "INVALID_REQUEST", "请求无效"));
+ }
+ });
+ req.on("aborted", () => reject(passwordChangeError(400, "INVALID_REQUEST", "请求无效")));
+ req.on("error", () => reject(passwordChangeError(400, "INVALID_REQUEST", "请求无效")));
+ });
+}
+
+function validatePasswordChangeEnvelope(req, url) {
+ const contentType = String(req.headers["content-type"] || "").split(";", 1)[0].trim().toLowerCase();
+ if (contentType !== "application/json" || !url.searchParams.keys().next().done) {
+ throw passwordChangeError(400, "INVALID_REQUEST", "请求无效");
+ }
+}
+
+function validatePasswordChangePayload(body) {
+ if (!body || Array.isArray(body) || typeof body !== "object") {
+ throw passwordChangeError(400, "INVALID_REQUEST", "请求无效");
+ }
+ const keys = Object.keys(body);
+ const allowed = new Set(["currentPassword", "newPassword"]);
+ if (keys.length !== 2 || keys.some((key) => !allowed.has(key))
+ || typeof body.currentPassword !== "string" || typeof body.newPassword !== "string") {
+ throw passwordChangeError(400, "INVALID_REQUEST", "请求无效");
+ }
+}
+
+function passwordChangeRequestId() {
+ return `pwd-${crypto.randomUUID()}`;
+}
+
+function writePasswordChangeError(res, err, requestId) {
+ const body = JSON.stringify({
+ error: {
+ code: err.passwordChangeCode,
+ message: err.message,
+ requestId
+ }
+ });
+ res.writeHead(err.status, {
+ "Content-Type": "application/json; charset=utf-8",
+ "Cache-Control": "no-store"
+ });
+ res.end(body);
+}
+
+function normalizedPasswordChangeError(err) {
+ if (err && err.passwordChangeCode) return err;
+ if (err && err.code === "DATA_VERSION_CONFLICT") {
+ return passwordChangeError(409, "PASSWORD_UPDATE_CONFLICT", "密码状态已变化,请重新登录");
+ }
+ if (err instanceof SyntaxError || (err && typeof err.code === "string" && /^E[A-Z]+$/.test(err.code))) {
+ return passwordChangeError(503, "PASSWORD_CHANGE_UNAVAILABLE", "密码修改暂不可用");
+ }
+ return passwordChangeError(500, "INTERNAL_ERROR", "服务暂时无法处理请求");
+}
+
+async function handlePasswordChange(req, res, url, store = { load, save }) {
+ const requestId = passwordChangeRequestId();
+ try {
+ validatePasswordChangeEnvelope(req, url);
+ const body = await parsePasswordChangeBody(req);
+ validatePasswordChangePayload(body);
+
+ let initialData;
+ try {
+ initialData = store.load();
+ } catch (err) {
+ throw normalizedPasswordChangeError(err);
+ }
+ const token = bearerTokenFromHeader(req);
+ const authenticated = accountFromTokenIncludingDisabled(token, initialData);
+ if (!authenticated) {
+ throw passwordChangeError(401, "AUTHENTICATION_REQUIRED", "请重新登录");
+ }
+ const expectedVersion = dataVersion(initialData);
+
+ await mutateAccountWithCas(authenticated.username, expectedVersion, (latestData) => {
+ const latest = getUsers(latestData).find((row) => row.username === authenticated.username);
+ if (!latest) {
+ throw passwordChangeError(409, "PASSWORD_UPDATE_CONFLICT", "密码状态已变化,请重新登录");
+ }
+ if (latest.status === "disabled") {
+ throw passwordChangeError(403, "ACCOUNT_DISABLED", "账号不可用");
+ }
+ if (makeToken(latest) !== token) {
+ throw passwordChangeError(409, "PASSWORD_UPDATE_CONFLICT", "密码状态已变化,请重新登录");
+ }
+ if (latest.password !== body.currentPassword) {
+ throw passwordChangeError(422, "CURRENT_PASSWORD_INCORRECT", "当前密码不正确");
+ }
+ const codePointLength = Array.from(body.newPassword).length;
+ if (codePointLength < 8 || codePointLength > 64) {
+ throw passwordChangeError(422, "PASSWORD_LENGTH_INVALID", "新密码长度必须为8至64个字符");
+ }
+ if (body.newPassword === body.currentPassword) {
+ throw passwordChangeError(422, "NEW_PASSWORD_SAME_AS_CURRENT", "新密码不能与当前密码相同");
+ }
+ latest.password = body.newPassword;
+ latest.updatedAt = nowText();
+ }, store);
+
+ res.writeHead(204, { "Cache-Control": "no-store" });
+ res.end();
+ } catch (err) {
+ writePasswordChangeError(res, normalizedPasswordChangeError(err), requestId);
+ }
}
function remindersFor(data, account) {
@@ -480,9 +689,13 @@
return rows;
}
-async function handleApi(req, res) {
+async function handleApi(req, res, options = {}) {
+ const url = new URL(req.url, "http://127.0.0.1");
+ if (req.method === "POST" && url.pathname === passwordChangePath) {
+ await handlePasswordChange(req, res, url, options.passwordStore || { load, save });
+ return;
+ }
const data = load();
- const url = new URL(req.url, `http://${req.headers.host}`);
if (req.method === "POST" && url.pathname === "/api/login") {
const body = await parseBody(req);
@@ -559,44 +772,45 @@
json(res, 400, { error: "请填写账号、姓名和岗位" });
return;
}
- const accountRows = getUsers(data);
- let row = accountRows.find((item) => item.username === username);
- if (!row && accountRows.some((item) => item.phone === phone)) {
- json(res, 409, { error: "这个手机号已经存在账号" });
- return;
- }
- if (!row && !password) {
- json(res, 400, { error: "新增账号必须设置初始密码" });
- return;
- }
- if (row && row.username === account.username && status === "disabled") {
- json(res, 400, { error: "不能停用当前登录的主管账号" });
- return;
- }
- if (row) {
- row.name = name;
- row.phone = phone;
- row.role = roleValue;
- row.status = status;
- row.permissions = permissions;
- if (password) row.password = password;
- row.updatedAt = nowText();
- } else {
- row = {
- username,
- phone,
- password,
- name,
- role: roleValue,
- status,
- permissions,
- createdAt: nowText(),
- updatedAt: ""
- };
- accountRows.push(row);
- }
- save(data);
- json(res, 200, { account: publicUser(row), accounts: accountRows.map(publicUser) });
+ const result = await mutateAccountWithCas(username, dataVersion(data), (latestData) => {
+ const latestActor = getUsers(latestData).find((item) => item.username === account.username && item.status !== "disabled");
+ if (!latestActor) throw httpError(401, "请先登录账号");
+ requireSupervisor(latestActor);
+
+ const accountRows = getUsers(latestData);
+ let row = accountRows.find((item) => item.username === username);
+ if (!row && accountRows.some((item) => item.phone === phone)) {
+ throw httpError(409, "这个手机号已经存在账号");
+ }
+ if (!row && !password) throw httpError(400, "新增账号必须设置初始密码");
+ if (row && row.username === latestActor.username && status === "disabled") {
+ throw httpError(400, "不能停用当前登录的主管账号");
+ }
+ if (row) {
+ row.name = name;
+ row.phone = phone;
+ row.role = roleValue;
+ row.status = status;
+ row.permissions = permissions;
+ if (password) row.password = password;
+ row.updatedAt = nowText();
+ } else {
+ row = {
+ username,
+ phone,
+ password,
+ name,
+ role: roleValue,
+ status,
+ permissions,
+ createdAt: nowText(),
+ updatedAt: ""
+ };
+ accountRows.push(row);
+ }
+ return { account: publicUser(row), accounts: accountRows.map(publicUser) };
+ });
+ json(res, 200, result);
return;
}
@@ -608,15 +822,19 @@
json(res, 400, { error: "不能修改当前登录账号状态" });
return;
}
- const row = getUsers(data).find((item) => item.username === username);
- if (!row) {
- json(res, 404, { error: "账号不存在" });
- return;
- }
- row.status = status;
- row.updatedAt = nowText();
- save(data);
- json(res, 200, { account: publicUser(row), accounts: getUsers(data).map(publicUser) });
+ const result = await mutateAccountWithCas(username, dataVersion(data), (latestData) => {
+ const latestActor = getUsers(latestData).find((item) => item.username === account.username && item.status !== "disabled");
+ if (!latestActor) throw httpError(401, "请先登录账号");
+ requireSupervisor(latestActor);
+
+ const accountRows = getUsers(latestData);
+ const row = accountRows.find((item) => item.username === username);
+ if (!row) throw httpError(404, "账号不存在");
+ row.status = status;
+ row.updatedAt = nowText();
+ return { account: publicUser(row), accounts: accountRows.map(publicUser) };
+ });
+ json(res, 200, result);
return;
}
@@ -1049,15 +1267,28 @@
});
}
-const server = http.createServer((req, res) => {
- if (req.url.startsWith("/api/")) {
- handleApi(req, res).catch((err) => json(res, err.status || 500, { error: err.message }));
- } else {
- serveFile(req, res);
- }
-});
+function createServer(options = {}) {
+ return http.createServer((req, res) => {
+ if (req.url.startsWith("/api/")) {
+ handleApi(req, res, options).catch((err) => json(res, err.status || 500, { error: err.message }));
+ } else {
+ serveFile(req, res);
+ }
+ });
+}
-ensureData();
-server.listen(port, "0.0.0.0", () => {
- console.log(`Full CRM demo is running at http://127.0.0.1:${port}/`);
-});
+if (require.main === module) {
+ ensureData();
+ const server = createServer();
+ server.listen(port, "0.0.0.0", () => {
+ console.log(`Full CRM demo is running at http://127.0.0.1:${port}/`);
+ });
+}
+
+module.exports = {
+ createServer,
+ dataVersion,
+ makeToken,
+ mutateAccountWithCas,
+ validatePasswordChangePayload
+};
diff --git "a/\345\205\250\345\261\200\347\272\246\346\235\237.md" "b/\345\205\250\345\261\200\347\272\246\346\235\237.md"
index 1a203b9..d029413 100644
--- "a/\345\205\250\345\261\200\347\272\246\346\235\237.md"
+++ "b/\345\205\250\345\261\200\347\272\246\346\235\237.md"
@@ -24,6 +24,7 @@
- 新协作事件不等于已投递,不能用消息通知抢占正在执行的工作。
- 异常中断后必须恢复原执行锁对应的任务;没有结果、检查点和锁释放记录时不得开始下一项。
- 普通追加要求默认进入队尾;只有Owner明确停止/替换且保存原任务检查点后才允许改变顺序。
+- 会话故障迁移不得只替换Thread ID;新会话必须完整回读旧历史、确认决策和恢复点并通过交接验收,旧会话才允许归档,详见[会话故障迁移与交接规范](<./docs/研发体系/会话故障迁移与交接规范.md>)。
## 修改范围
--
Gitblit v1.9.3