Files
group_fqcd_jr/开发文档/D4.7-投顾模块恢复记录-2026-09-20.md
T

97 lines
8.6 KiB
Markdown
Raw Normal View History

# D4.7 · 投顾模块恢复记录
> **体系编号**:`D4.7` · 域:四、清除与重建留痕 · 编号体系见 `D1.1` §4.0
> **编号**:CS-PURGE-2026-014 | **版本**:v1.0 | **日期**:2026-09-20 | **状态**:**现行(本件描述仓库现状;`D4.4`/`D4.5` 降级为历史留痕)**
> **性质**:**状态单据(现状)**。回答「投顾模块到底删了没有、现在还在不在、怎么恢复的」—— 这是答辩现场**必被追问**的一点(因为 `D4.4`/`D4.5` 两份文档的标题与结论都写着「清除」)。
> **时间线证据**:会话留痕 `D1.6` §4.37;合并提交 `e5b4d02`;远端 3 个投顾提交 `5607751` / `2fe7d0c` / `74b7d00`。
> **配套**:范围与影响面 `D4.4`(仍是有效的历史留痕);清除执行报告 `D4.5`(顶部已加状态更新);纪律凭据 `docs\48` / `docs\49`。
---
## 0. 一句话结论(现状)
**投顾模块在仓库中「有效存在」** —— 2026-09-17 曾按 `D4.4`/`D4.5` 整体清除(94 个文件),2026-09-20 合并远端组员 3 个投顾提交时,因其代码**反向依赖被删除的模块**,裁定「**组员新功能 > 本地清除**」⇒ **恢复**。
| 问题 | 答案 |
|---|---|
| 投顾代码还在吗? | **在**(`app\service\*.py` 投顾服务、`app\api\controllers\recommendations.py`、`employee-advisor/` 前端等,取远端版本) |
| `D4.4` / `D4.5` 还有效吗? | **作为历史留痕有效**;作为「仓库现状」**已失效**(`D4.5` 顶部已加状态更新指向本件) |
| 客服 Agent 受影响吗? | **不受影响**。客服的范围裁定(`D2.2` §1.7 两条业务线 / `RK-10` 不越界实现投顾)**原样成立** |
| 恢复有遗留吗? | **有 1 项**:投顾的 `config_release` 工具白名单(`advisor:*`)**尚未发布** ⇒ 投顾 Agent 工具调用 fail closed(见 §5) |
---
## 1. 时间线
| 时间 | 事件 | 依据 |
|---|---|---|
| 2026-09-16 | 组员在 `qyqy_develop` 落 **3 个投顾提交**(需求与架构文档 / 客户主动申报 + 受理出草稿 / 方案交付落点与 LLM 增强) | `5607751` `2fe7d0c` `74b7d00` |
| 2026-09-17 | 本线按 `D4.4`/`D4.5` **整体清除投顾**(94 文件删除) | `D4.5` |
| 2026-09-20 | 推送被拒(**non-fast-forward**):`fetch` 后发现远端领先 3 个提交,且新代码 `import` 了已删模块 | `D1.6` §4.37 一 |
| 2026-09-20 | **裁定恢复投顾**:合并提交 `e5b4d02`(parents = `5d0becb` + `74b7d00`) | `D1.6` §4.37 二 / 九 |
| 2026-09-20 | 补数据库夹具 + 修 1 条「远端本身就是红的」断言 ⇒ 全量回归 **1909 passed / 3 skipped / 0 failed** | `D1.6` §4.37 六/七/八 |
**为什么不能两全**:`D4.4` 在清除**之前**就预警过两条风险 —— ① 按名字清投顾会**同时删掉产品数据底座与 MVP 的硬阻断实现**;② 会**失去「改 6 个底座文件时的对照组」**。组员在**同一个模块**上落了新功能 ⇒ 清除与新功能**不可能同时成立**。裁定取「组员新功能」,依据正是 `D4.4` 自己写下的预警。
---
## 2. 恢复动作清单(做了什么)
| # | 动作 | 说明 |
|---|---|---|
| 1 | **取远端版本** | 8 处 `modify/delete` 冲突全部**取远端**:`recommendations.py`、`product_recommendation_service.py`、`employee-advisor/dashboard/` 4 文件、`tools/check_portal_modules.py`、`tools/grant_advisor_role.py` |
| 2 | **取远端版本(内容冲突 3 处)** | `app/main.py`(投顾 import + `include_router`)、`common/api-client.js`(投顾端点表)、`tests/unit/api/test_portal_frontend.py`(4 条投顾前端契约) |
| 3 | **定点保留我方改动 1 处** | `app/main.py` 解除冲突的同时,**保留**本轮「移除 `/customer-service-test` 挂载」(联调页与用例已随重构作废) |
| 4 | **语义回滚(4 处)** | 因「取消清除」而必须回滚:`app/service/agent/bootstrap.py`(`AdvisorAgent` + 5 个投顾工具注册)、`app/core/config.py`(`advisor_rollout_*`)、`app/static/portal/common/layout/app-shell.js`(投顾工作台导航 + `advisor` 角色名)、`tools/seed_test_rbac.py`(admin 全量元组授权模型) |
| 5 | **叠加我方修复** | `app/static/portal/common/api-client.js`:以远端为基准,**重新叠加**本轮的「访客令牌 `Authorization` 优先」修复(否则该修复被合并静默吃掉) |
| 6 | **数据库夹具同步** | `tools/grant_advisor_role.py` → 新建 `advisor` 角色(实测 **34 项**权限);`tools/create_test_user.py --id 9020 --username advisor_t --role advisor --password abc12345` → 重建演示账号。补夹具前 3 条投顾集成用例全红,补后 **2 passed / 1 skipped** |
| 7 | **修一条「远端本身就是红的」断言** | `tests/unit/test_advisor_migration_contract.py` 把 alembic 末端钉死在 `20260914_baseline_auto_increment`,而远端新增 `20260916_advisor_service_request` ⇒ 该断言在远端 `qyqy_develop` 上**本身就失败**(不是合并引入的)。已更新到新末端并补注释 |
| 8 | **顺带修掉一类假红** | `tools/portal_api_check.py` 新增 `empty_collection_note()`:被渲染的集合为空时判 **`SKIP`(附原因)** 而非 `FAIL` ——「没有行」与「字段没带」是两回事。改后 40 项:**通过 35 / 失败 0 / 跳过 5** |
> 🔑 **未用 `--force`**:强推会毁掉组员 3 个提交。
---
## 3. 恢复后,「客服线」的哪些结论**不变**
| 结论 | 状态 |
|---|---|
| 客服 Agent 范围 = **两条业务线**(游客线 + 客服线),不承接投顾能力 | **不变**(`D2.2` §1.7 / `RK-10`) |
| 长期记忆召回 = **关**、画像 = 客户侧字段级只读 | **不变**(`DEC-19`;理由见 §4) |
| 客服知识库三集合 / 三档可见性 / 分区隔离 | **不变**(`D2.4`;投顾知识**不进**客服知识库) |
| 五出口决策链 + 安全不变量 `INV-1`~`INV-5` | **不变**(`D3.6`) |
| 46 条金标与全部指标(转人工率 10.9% / 出口 100% / 事实 100%) | **不变**(`D3.7` / `D2.6`) |
| 全量门禁 | **更强了**:对照组回归 ⇒ 1909 passed / 3 skipped / 0 failed |
---
## 4. 一处必须更正的**理由表述**(不是结论)
`DEC-19`(长期记忆召回 = 关)的**结论不变**,但**理由**里有一条曾经写着「收益方(投顾)已整体清除」—— 该理由**随恢复失效**。
**正确理由(继续成立、且更硬)**:
1. **客服 Agent 不产生长期记忆**:`app/worker/runtime.py` 的 `NO_LONG_TERM_MEMORY_AGENT_TYPES` 显式含 `customer_service`(`W7` 发现并修回的真实合规回归 `D-10`);
2. **注入生成上下文与证据约束生成直接冲突**:`E4` 的输入必须是**证据包**(`INV-2`),把长期记忆注入进去会让答案出现证据包外的内容;
3. **`PROFILE_CANDIDATE_AGENT_TYPES` 为空集是裁定落地**,不是「重构期临时状态」—— 要重开必须**先改口径**,而不是往集合里加 `agent_type`。
---
## 5. 遗留(**1 项,与客服线无关**)
| # | 遗留 | 说明 | 怎么解 |
|---|---|---|---|
| 1 | 投顾 `config_release` 工具白名单(`advisor:*`)**未发布** | 2026-09-20 连库实测 `active_agent_tools` 只有 `customer_service:*` 与 `risk:*` 共 8 项 ⇒ 投顾 Agent 的工具调用**正确 fail closed**(代码在、白名单不在) | 要演投顾线时跑 `tools/publish_advisor_demo_config.py --apply`(该脚本由组员提交 `9c6f839` 提供)。**客服线完全不受影响** |
| 2 | 投顾演示数据未灌 | `AD011` / `A047` 需要带 `source_url` + `document_sha256` 的适当性证据行,披露文件不在仓库;`tools/seed_advisor_demo.py` 明令**不编证据**(fail closed) | 空集 `SKIP`,不是缺陷(`D1.6` §4.37 十-2) |
---
## 6. 如实登记(含我的失误)
| # | 事项 | 说明 |
|---|---|---|
| 1 | 🔴 **清理临时产物时误删 `_advisor_db_backup.sql`** | 属我的操作失误。缓解:真正的代码级备份 `_advisor_purge_backup/`(**51 文件**)与 `_cs_purge_backup/`(34 文件)**完好**;且该库投顾表本为空 |
| 2 | **本件是「补记」,不是当时的记录** | 恢复发生在 2026-09-20(`W12`),当时的留痕在 `D1.6` §4.37 与 `D4.5` 顶部状态更新。本件是 `W13` 文档审计时**补的上游单据** —— 补记的理由是:`D4.4`/`D4.5` 两份文档标题都叫「清除」,未来检索「投顾 恢复」会**查不到** |
| 3 | 「恢复」的**边界**需明确 | 恢复的是**模块代码 + 数据库夹具**;投顾的**演示数据/工具白名单**仍是空的(§5)—— 「恢复了」≠「投顾线演示已就绪」 |