Преглед изворни кода

docs(tdd): 测试负责人第124轮闭环汇报(3501/3444=98.37%零漂移·B-121销号·B-74根因实锤LLM凭据401)

E2E Test Bot пре 2 дана
родитељ
комит
167387161c

+ 339 - 0
docs/tdd/orchestration/report-test-2026-11-10-R124.md

@@ -0,0 +1,339 @@
+# 测试闭环报告 · 第 124 轮(2026-11-10 14:20 GMT+8)
+
+> 主理人:陆谨(软件测试专家团 · 测试架构师)
+> 执行档:**review 档**(内网 `cfc.iwintrue.com` 已授权;无联网外部请求;未装依赖;未改生产代码)
+> 对象:`d:/cfc`(浠艾福 XAF)
+> 触发:定时自动化「测试负责人闭环(全部用例通过 + 覆盖 SRS/场景含异常流)+ 浏览器走 `/admin` 与 `/frontend`(189/本机每节点单任务)+ langgraph 派 251 + 结果有变提交远程并通知研发」
+
+---
+
+## 0. 本轮结论速览
+
+| 项 | 值 |
+|----|----|
+| 基线 | `cfclub @ 2f04b1033`(跑前 = 跑后;收尾 fetch 远端前进 1 提交 `67b5f6325` chore auto bump,零源码变更) |
+| 全量用例 | **3501 例 / 3444 过 = 98.37%**(红 50 / 跳过 7) |
+| 对比上轮(R123 `98.37% / 3444 过`) | **严格零漂移**(逐套件一致) |
+| 后端全量 | **2865 例 / 2828 过 = 98.71%**,30F+3E+4S,14 红类 / 33 红例,34:03,XML 339/339 无沉默 |
+| 浏览器自动化 | **28/28 全绿**(live 15 + health 13) |
+| langgraph @ 251 | **43 例 / 42 过 / 1 红**(`test_auto_tag_valid_format`,LLM API key 401) |
+| 门禁 | **不通过(有条件)** — 见 §9 |
+
+**三件必须让研发看到的事**
+
+1. **后端全量持续新高稳态**:98.71%(2865/2828)与 R123 逐例一致,红例 33 的类级差集为空;`MindFortuneControllerTest` 维持不在红类清单(B-69 落码稳定)。**全量结果已连续两轮零漂移**——上轮的 30F+3E+4S 分布在本轮完全复现,说明红例均已稳定归因,可批量派研发处置。
+2. **langgraph 红例名漂移(B-74 观察)**:R123 红例 `test_auto_tag_content_relevance` → 本轮 `test_auto_tag_valid_format`。同库同文件,二者均依赖 LLM 语义输出,且本轮日志直接暴露根因:**API key `****ab12` 返回 401 Authentication Fails**。这从「疑似凭据问题」升级为「凭据问题实锤」——需研发/运维轮换有效 LLM 凭据后复跑闭环。
+3. **B-121(admin U05)连续第 2 轮绿**:57.8s 通过、U04 9.9s 通过,首轮即绿无重跑。按 R123 判据(连续 2 轮绿 → 销号),**本轮满足销号条件**,转销号登记。
+
+---
+
+## 1. 历史审查记录
+
+| 项 | 内容 |
+|----|------|
+| 上次本对象审查 | R123 @ 2026-11-10 12:35(`2f04b1033`,即本轮起点 HEAD 自身) |
+| 上次结论 | 不通过(有条件):G2 50 红 / G9 锚点 17.1% / G11 无 CI 阻塞放行 |
+| 上次遗留缺口 | ① 后端全量核对(已从 R123 起恢复实测)② B-121 U05 转观察 ③ B-74 收窄至 1 例 ④ 覆盖率/变异/压测/安全 长期未实测 |
+| 本次是否改善 | ① 维持实测且零漂移 ✅ ② **B-121 连续 2 轮绿 → 本轮销号** ✅ ③ B-74 根因实锤(API key 401)✅(闭环仍待凭据轮换)④ 未变(execute 档未授权) |
+| 是否首次审查 | 否。同对象已连续审查 ≥124 轮 |
+
+> 本节仅作对照。本轮全部结论均以本轮实测取证;仅「SRS 台账计数」因窗口零变更而标注沿用。
+
+---
+
+## 2. 项目画像
+
+| 维度 | 结论 |
+|------|------|
+| 业务定位 | 家庭教育 SaaS:家长/孩子(能登录/不能登录用户)双角色、成长规划师、五维能量、健康报告解析、测评订单、商城、AI 管家 |
+| 技术栈 | 后端 Spring Boot 2.7.18 + MyBatis-Plus + Java 8(端口 9082);小程序 uni-app Vue2;管理端 Vue2 + Element UI;AI 侧 Python FastAPI + LangGraph + ChromaDB(9000,生产 `ai.etotem.com.cn`);独立商城 Spring Boot(8888) |
+| 规模(本轮实测) | 后端测试类 **339**、`@Test` **2854**、`@Disabled` **4**、控制器 **363**、`@GetMapping` **8 处**(仍违 AGENTS.md「统一 @PostMapping」);SRS 规格 **200 份**;用例台账 **14 份** |
+| 关键路径 | 登录鉴权(JWT 拦截 + 8 公开路径)→ 家庭成员/关系 → 成长任务与能量 → 健康报告上传-解析-入库 → 测评订单 → 商城下单/分润 → AI 对话/画像 |
+| 质量目标 | 全量用例通过率、SRS/场景锚点覆盖、线上鉴权契约、浏览器双端可用性、跨节点可派发 |
+| 本轮风险点 | LLM 凭据 401(langgraph 红例根因已实锤);真实 DB 集成测试依赖 `192.168.16.251:3306`;A 类夹具 16 红;`platform_fee` 列溢出;189 节点仓库陈旧 |
+
+---
+
+## 3. 20 类测试覆盖矩阵
+
+图例:● 已发现(有资产且有本轮/近期实测证据)/○ 未发现(扫描未命中)/◐ 待核实(有资产但本轮未实测或被降级)
+
+| # | 类别 | 状态 | 证据 |
+|---|------|------|------|
+| 1 | 单元测试 | ● | 后端 339 类 2865 例实跑;cfc-web 116、cfc-frontend 426 Jest 实跑 |
+| 2 | 组件测试 | ● | 后端 `*ControllerTest`(MockMvc)批量实跑;前端 Vue 组件 `__tests__` 实跑 |
+| 3 | 接口 API 测试 | ● | 浏览器侧 health 契约 13 例(10 端点未鉴权全 401)+ shop-sort 4 例实跑 |
+| 4 | 系统 / 端到端 | ● | `/admin` 5 例 + `/frontend` 6 例真浏览器实跑(Playwright 1 worker) |
+| 5 | 验收 UAT | ◐ | 有 `tests/user-scenarios` 198 场景映射,但无独立 UAT 执行记录(业务凭据不全) |
+| 6 | 冒烟测试 | ● | 每轮固定 28 例 live/health 冒烟;本轮全绿 |
+| 7 | 回归测试 | ● | 后端全量 2865 例 + 三套 Jest 全量 = 本轮回归基线 |
+| 8 | 探索性测试 | ○ | 无 chartered 探索会话记录 |
+| 9 | 契约测试 | ● | health 13 + shop-sort 4 + 后端 `*ContractTest`(DimensionRegistryMap / TeamProfitCron / WechatLoginContract 等) |
+| 10 | 性能测试 | ○ | 无压测脚本与基线(execute 档,需联网授权) |
+| 11 | 可靠性测试 | ○ | 无故障注入/恢复演练;仅线上 502 抖动被观测(B-72 历史) |
+| 12 | 安全测试 | ◐ | 鉴权契约 23 端点实测(全 401);SAST/DAST/依赖扫描未执行(execute 档) |
+| 13 | 兼容性测试 | ◐ | 仅 Chromium;多浏览器/多机型矩阵未执行 |
+| 14 | 可用性测试 | ○ | 无真实用户可用性证据 |
+| 15 | 无障碍测试 | ○ | 无 WCAG 检查 |
+| 16 | 覆盖率度量 | ◐ | cfc-web 引用历史 10.11/6.12/7.51/9.98%;后端 JaCoCo 离线不可用 |
+| 17 | 变异测试 | ○ | 无 PIT/mutation 配置 |
+| 18 | 质量指标 | ● | 通过率/红例分布/桶分布本轮重算(§8) |
+| 19 | QA 流程 | ● | 自动化闭环 124 轮可追溯;门禁脚本化不足(G11) |
+| 20 | 代码审查 | ● | 本轮抽检红例对应生产代码 6 处(EnergySystem / DimensionRegistry / platform_fee / ArticleAutoTag / CfCommission / WechatLogin) |
+
+**缺口初判**:5 类 ○ 全为「非功能 + 探索性 + 变异」,均属 execute 档或需专项排期;5 类 ◐ 为本轮降级项,已在 §7 转成缺口条目。
+
+---
+
+## 4. 测试方案(本轮实际执行)
+
+| 项 | 内容 |
+|----|------|
+| 目标 | 全量用例重新取证(验证 R123 零漂移是否成立);验证 SRS/场景零变更;验证上轮遗留(B-121 连续绿计数 / B-74 根因) |
+| 范围 | 后端全量 339 类、cfc-web 17 套、cfc-frontend 26 套、根级 tests 3 套、langgraph@251 43 例、浏览器 live 15 + health 13 |
+| 覆盖维度 | 功能层次 5 类 + 功能保障 4 类 + 非功能鉴权/兼容(部分) |
+| 执行档 | review(离线白名单);内网 HTTP 探针与内网站点浏览器访问均为已授权范围 |
+| 优先级 | P0:后端全量 + 鉴权契约 + 浏览器双端;P1:251 派发;P2:度量口径 |
+| 排除项 | 压测、DAST/SCA、变异、多浏览器矩阵、UAT 全流量(未授权/无凭据)——报告中标「未实测」,不计通过 |
+
+---
+
+## 5. 执行结果明细
+
+### 5.1 后端全量(`mvn -o -B clean test`,JDK1.8.0_25 + Maven 3.6.1)
+
+| 项 | 值 |
+|----|----|
+| 总耗时 | **34:03** |
+| 结果 | **2865 例 / 2828 过 / 30F + 3E + 4S = 98.71%**(剔 skip 98.85%) |
+| 红类 / 红例 | **14 类 / 33 例** |
+| 完整性 | surefire XML **339/339**,与 339 个测试类一一对应,**沉默丢失 0** |
+| 恒等式 | `@Test 2854 − @Disabled 4 + 参数化/早退净增 15 = 2865`,误差 0 |
+| 环境红 | **0**(B-13 观察第 2 轮) |
+| 对比 R123 | **逐例一致**:2865/2828/98.71%,红类 14 的类级集合差集为空,33 红例逐条同名同型 |
+
+**33 红三层归因**(与 R123 同分布)
+
+| 桶 | 例数 | 明细 |
+|----|------|------|
+| A 装置(测试自身缺陷) | 16 | `CfCommissionServiceSettleTest` 8(Wanted but not invoked)· `ArticleAutoTagServiceTest` 4(execute 未命中/过多)· `GrowthRecordSyncFlowTest` 3(1F+2E)· `TaskPlanServiceTest` 1(expected 100 but null) |
+| B 产品 | 13 | `EnergySystemFlowTest` 6(5×500 + 1 false)· `OrchestrationEngine` 1 + `OrchestrationIntegration` 1 · `MembershipPaySwitch` 1 · `PaymentORD` 1 · `WechatLogin` 2 · `TeamProfitCron` 1 |
+| C 数据 | 1 | `GuideModuleIntegrationTest` — platform_fee Out of range(第 13 轮) |
+| 契约待裁决 | 3 | `DimensionRegistryMapContractTest`(unknown/empty/missing 三例) |
+
+**B-69 稳定**:`MindFortuneControllerTest` 连续第 2 轮不在红类清单;线上 `POST /api/mind/fortune` → 401(见 5.6)。
+
+### 5.2 前端 / 管理端 / 根级
+
+| 套件 | 套件数 | 例数 | 过 | 红 | 跳过 | 与基线 |
+|------|-------|------|----|----|------|--------|
+| cfc-web Jest | 17 | 116 | 116 | 0 | 0 | 零漂移 |
+| cfc-frontend Jest | 26 | 426 | 423 | 0 | 3 | 零漂移 |
+| tests 根级 Jest | 3 | 23 | 7 | 16 | 0 | 零漂移(B-36,9082 未启动 → ECONNREFUSED) |
+
+### 5.3 浏览器自动化(`workers=1`,单节点单任务)
+
+| 套件 | 例数 | 结果 | 耗时 | 备注 |
+|------|------|------|------|------|
+| `admin-desktop`(`/admin`) | 5 | **5/5** | 6.5/3.8/3.6/9.9/**57.8**s | U04 真实登录通过;**U05 连续第 2 轮绿(B-121 销号判据达成)** |
+| `frontend-mobile`(`/frontend`) | 6 | **6/6** | 3.9~9.7s | 游客流 TC-F-U01~U06 |
+| `shop-api` | 4 | **4/4** | 77~115ms | 价格排序契约 TC-S-U01~U04 |
+| `health-api`(契约) | 13 | **13/13** | 9.7s | 华为 5 + 小米 5 + 健康方案 3,**全部 401** |
+
+合计 **28/28 全绿**,与 R118/R120/R123 基线一致。
+
+### 5.4 langgraph @ 192.168.16.251(实派第 2 轮)
+
+| 项 | 值 |
+|----|----|
+| 通道 | `POST /api/shell?location[directory]=/sc-data/cfc/cfc-langgraph`(Basic,port 4096)→ 文件落盘 → 单次读(B-125 模式,kick 分离 + sleep + 单次读) |
+| 节点 HEAD | 随 kick 内 `git reset --hard origin/cfclub` 对齐远端 |
+| 命令 | `.venv/bin/python -m pytest tests --ignore=tests/qna --ignore=tests/test_chat.py -q --tb=line` |
+| 结果 | **1 failed, 42 passed, 8 warnings in 593.85s**(43 例,主口径「不含 test_chat」) |
+| 唯一红例 | `tests/test_auto_tag.py::test_auto_tag_valid_format` — `AssertionError: 标签数量应为 3-5 个, 实际 0: []` |
+| **根因实锤** | 日志捕获 `Authentication Fails, Your api key: ****ab12 is invalid`(401)→ LLM 调用失败 → 打标返回空 → 断言失败。**凭据问题而非代码缺陷** |
+| 对比 | R123 43/42/1(红例 `content_relevance`)→ 本轮红例名变化,同文件同 LLM 依赖(B-74 同源) |
+
+**附独立复核**:`test_analyze`(B-65 销号项)2 例、`test_intent`(B-82 销号项)4 例均不在失败清单;`test_auto_tag` 5 例中仅 1 红。
+
+### 5.5 节点可达性
+
+| 节点 | 端口 | 结论 |
+|------|------|------|
+| 本机 | — | 浏览器 28/28 全量承担(单任务) |
+| `192.168.16.189` | 4090 **OPEN**(Basic 通过,shell 可建可读) | **不可承载(B-122 延续第 2 轮)**:仓库仍 `C:\worktrees\cfc-user-is-child @ e3e52ca38`(`feature/user-is-child`),`tests\e2e-live=False`、`node_modules=False` → 未派发 |
+| `192.168.16.251` | 4096 OPEN / 9000 OPEN | **langgraph 实派成功**(第 2 轮) |
+| `192.168.16.204` | 4090 CLOSED | 延续失联(B-95) |
+
+### 5.6 线上鉴权与可达性(curl 探针)
+
+| 目标 | 结果 |
+|------|------|
+| `GET http://cfc.iwintrue.com/admin` | 302(登录墙,0.07ms) |
+| `GET http://cfc.iwintrue.com/frontend` | 302(0.71ms) |
+| `POST /api/mind/fortune`(匿名) | **401** `{"code":401,"message":"请先登录"}` |
+| `POST /api/energy/overview`(匿名,对照) | **401** |
+
+---
+
+## 6. 覆盖缺口清单
+
+| 编号 | 缺口类型 | 现状 | 风险 | 建议测试设计 | 优先级 | 闭环方式 |
+|------|---------|------|------|-------------|--------|---------|
+| G-124-1 | 性能测试 | 无脚本无基线 | 健康报告解析、AI 对话为长耗时链路,无容量依据 | 用 k6 对 `POST /api/health/report/upload`、`/api/v1/chat` 做 20/50 并发阶梯,记录 P95 | P2 | 需 execute 档联网授权后执行,产出基线表 |
+| G-124-2 | 可靠性 | 无故障注入 | `EnergySystem` 500 类问题在生产会直接暴露 | 对 MySQL 断连 + LLM 超时各注入 1 次,断言降级而非 5xx | P2 | 与研发约定注入窗口 |
+| G-124-3 | 安全扫描 | 仅鉴权契约 | 仅覆盖 23 个端点的未鉴权路径 | SAST(Semgrep)+ 依赖漏洞(`mvn dependency-check`) | P2 | execute 档授权 |
+| G-124-4 | 兼容性/无障碍 | 仅 Chromium | 小程序多机型、管理端 IE 类浏览器、WCAG 均空 | Playwright projects 加 firefox/webkit;axe-core 扫 `/admin` 5 页 | P3 | 增配置后纳入冒烟 |
+| G-124-5 | 覆盖率 | 后端 JaCoCo 离线不可得 | 98.71% 通过率不等于行覆盖率 | 离线环境预置 jacoco agent jar 后 `mvn test jacoco:report` | P1 | 预置依赖后补测 |
+| G-124-6 | 变异测试 | 无 | 高通过率可能掩盖弱断言 | 对 `EnergySystemService`、`CfCommissionService` 引入 PIT,目标 kill ≥60% | P3 | 专项排期 |
+| G-124-7 | UAT / BDD | 198 场景仅文档映射 | 场景与断言未一一绑定,锚点率低 | 将锚点规范落到 `tests/test-cases`,每场景至少 1 可执行断言 | P1 | 见 B-124 |
+| G-124-8 | LLM 凭据 | langgraph 红例根因 = API key 401 | 打标/画像等 LLM 链路随时可用性归零 | 凭据注入成环境变量 + 每轮探活 `POST /api/v1/chat` 冒烟 | P1 | B-74 闭环 |
+
+---
+
+## 7. 域结论表
+
+| 审查维度 | 负责专家 | 结论 | 关键证据 |
+|---------|---------|------|---------|
+| 单元·组件级 | 苏雅 | **有条件通过** | 后端 2865 例 98.71%,14 红类(16 A 类夹具红阻塞口径);cfc-web 116/116、frontend 423/426 |
+| 集成·接口级 | 柯砚 | **不通过(局部)** | 契约 23 端点全 401 ✅;但 `DimensionRegistryMap` 3 例契约口径未裁决、`platform_fee` 溢出 1 例 |
+| 系统·验收级 | 白樾 | **有条件通过** | 浏览器 28/28 ✅;UAT 全流量未执行(无凭据),场景锚点偏低 |
+| 测试保障级 | 闻朔 | **通过** | 冒烟 28/28;回归全量 3501 例连续两轮零漂移可复跑;探索性缺失(登记缺口) |
+| 性能·可靠性 | 骆骋 | **未实测(降级)** | execute 档未授权 → 转 G-124-1/2 测试设计 |
+| 安全 | 关屿 | **有条件通过** | 匿名 23 端点全 401(含 `/api/mind/**` 已修,第 2 轮稳定);SAST/SCA 未执行 |
+| 兼容·体验 | 阮清 | **未实测(降级)** | 仅 Chromium;无 axe/WCAG → G-124-4 |
+| 流程·度量·代码 | 何序 | **不通过(局部)** | `@GetMapping` 8 处仍违规范;锚点口径三套不一致(B-124 未闭环);251 派发器 B-125 等待时长未自适应 |
+
+---
+
+## 8. 五要素问题清单
+
+### #1 langgraph `test_auto_tag_valid_format` 红 + LLM 凭据 401 实锤(B-74 根因升级)
+
+- **① 问题描述**:251 实派 43 例中唯一失败为 `test_auto_tag_valid_format`;日志捕获 **LLM API key `****ab12` → 401 Authentication Fails** → 打标返回空标签(`实际 0: []`)→ 断言失败。R123 红例 `content_relevance` 本轮转绿、`valid_format` 转红——同文件内用例次序随 LLM 输出漂移,**根因同一:凭据失效**。
+- **② 测试 bug 点**:`cfc-langgraph/tests/test_auto_tag.py::test_auto_tag_valid_format`(断言依赖 LLM 打标输出,无固定桩);服务端 `.env`/启动参数中 LLM API key 失效。
+- **③ 最优修改方案**:① 运维/研发轮换有效 LLM 凭据并注入环境变量(251 与生产同源);② 同时按 R123 建议把主断言改确定性桩(mock 固定标签集),另设 `@pytest.mark.llm` 真实链路冒烟(允许 skip);③ 251 `.venv` 装 `pytest-timeout` 防挂起。
+- **④ 修改目的**:把「凭据/网络」与「打标逻辑回归」彻底分离,使该维度可稳定门禁;凭据轮换解决的是**线上 LLM 能力可用性**(直接影响真实用户)。
+- **⑤ 闭环**:凭据轮换后 251 复跑该文件 5/5 全绿;且无凭据时用例走确定性桩绿、`@pytest.mark.llm` 显式 skip——两者任一达成即销号。
+
+### #2 根级黑盒 16 红(B-36,第 27 轮零漂移)
+
+- **① 问题描述**:`tests/` 根级 3 套 23 例,稳定 7 绿 / 16 红,全部 `ECONNREFUSED`(后端 9082 未启动)。
+- **② 测试 bug 点**:`tests/integration/*.spec.js`(如 `mini-games-api.spec.js:259`)硬编码 `http://127.0.0.1:9082`,无「服务未起则 skip」保护。
+- **③ 最优修改方案**:加 `beforeAll` 探活,未起则 `test.skip` 并打印启动指引;CI 中由 `globalSetup` 拉起后端。
+- **④ 修改目的**:消除「环境未起」被统计为「产品失败」的长期噪声(每轮固定 16 红)。
+- **⑤ 闭环**:连续 1 轮根级 0 红(或 16 例显式 skip 而非 fail)。
+
+### #3 A 类夹具 16 红(装置缺陷,非产品)
+
+- **① 问题描述**:`CfCommissionServiceSettleTest` 8、`ArticleAutoTagServiceTest` 4、`GrowthRecordSyncFlowTest` 3、`TaskPlanServiceTest` 1 红,形态集中于 `Wanted but not invoked` / `execute` 未命中 / NPE。
+- **② 测试 bug 点**:`CfCommission...:settle_F03a...` 等 8 例;`ArticleAutoTag...:toggleStatus_...` 等 4 例。
+- **③ 最优修改方案**:`CfCommission` 逐例核对 mock 方法签名与生产 7 参 overload;`ArticleAutoTag` 改为注入同步 `Executor` 替身(避免线程池异步断言);`TaskPlan` 补齐 `@Mock` 返回值;`GrowthRecordSync` 2 例 E 读 `Caused by` 最内层。
+- **④ 修改目的**:让 16 红退出统计,暴露真实产品缺口。
+- **⑤ 闭环**:定向复跑 4 类全绿(`mvn -Dtest=A,B,C,D`,必须看 `Tests run:` 行)。
+
+### #4 B 产品 13 红(连续两轮零漂移,可批量派单)
+
+- **① 问题描述**:`EnergySystemFlowTest` 6(5×500)、`Orchestration*` 2、`MembershipPaySwitch` 1、`PaymentORD` 1、`WechatLogin` 2、`TeamProfitCron` 1——**与 R123 逐例同名同型,连续 2 轮零漂移**。
+- **② 测试 bug 点**:`EnergySystemFlowTest:parentGetsEnergyOverview_Success` 等 6 例;`TeamProfitCronContractTest:refundWithinCooling_cancelAllRecordsFundsNotPaid`。
+- **③ 最优修改方案**:EnergySystem 5 例 500 抓服务端堆栈定位(疑 DB/事务);TeamProfitCron 冷静期退款未置 `cancelled` 核对 §8.2 实现;WechatLogin 2 例疑 mock 凭据缺失。
+- **④ 修改目的**:把「疑似产品缺陷」转成可派研发的具体缺陷单(连续两轮稳定 = 已不是偶发)。
+- **⑤ 闭环**:对应类 0 红 + 线上同路径 200。
+
+### #5 `platform_fee` 列溢出(C 数据,第 13 轮)
+
+- **① 问题描述**:`GuideModuleIntegrationTest` 写库报 `Data truncation: Out of range value for column 'platform_fee'`。
+- **② 测试 bug 点**:`GuideModuleIntegrationTest::testGuidePackageCreationFlow`(造数金额超出列宽)。
+- **③ 最优修改方案**:核对 `guide_order.platform_fee` 列类型与业务上限;若业务值合法则扩列(DDL 走 `DatabaseInitializer` 迁移 + 同步 `schema.sql`),否则修造数。
+- **④ 修改目的**:避免真实大额订单写库失败。
+- **⑤ 闭环**:迁移后该类转绿 + 用边界值(上限 ±1)复测。
+
+### #6 `DimensionRegistryMap` 契约 3 例待裁决
+
+- **① 问题描述**:`unknown_legacy`/`empty` 期望 `data=null` 实为原值/空串;`missing` 期望 400 实为 200。
+- **② 测试 bug 点**:`DimensionRegistryMapContractTest:map_unknownLegacy_returnsNullData`、`map_emptyLegacy_returnsNullData`、`map_missingLegacy_returnsBadRequest`。
+- **③ 最优修改方案**:由产品/研发对「未知 legacy 键」语义拍板(null vs 原样回传),单向修正契约或用例,写入 SRS。
+- **④ 修改目的**:消除长期悬空契约,避免前后端对同一键不同解释。
+- **⑤ 闭环**:契约条款落 SRS 后 3 例按新条款全绿。
+
+### #7 环境探针 SOP(B-123 处置,第 2 轮通过)
+
+- **① 问题描述**:曾 4 次以「本机无 Maven」跳过后端全量;本轮与 R123 两轮均前置探针且实测通过 98.71%。
+- **② 测试 bug 点**:SOP(已修复,见 `automation-run-R124` 环境探针节)。
+- **③ 最优修改方案**:维持「每轮固定 `java -version && mvn -v && df -h`,未跑探针不得写降级」。
+- **④ 修改目的**:杜绝「凭记忆判环境」导致整模块漏测。
+- **⑤ 闭环**:连续 3 轮报告含探针输出且无 Maven 类降级 → 销号(本轮为第 2 轮)。
+
+### #8 251 派发等待时长未自适应(B-125 观察)
+
+- **① 问题描述**:本轮第 1 读只取到 `...F..`(sleep 400s 小于 LLM 慢链路 593.85s);第 2 读才取回完整 summary。
+- **② 测试 bug 点**:`_r124_dispatch_251.cjs` 固定 WAIT_MS;`docs/tdd/tools/dispatch_shell.cjs` 轮询建 shell(会杀进程)。
+- **③ 最优修改方案**:读 Log 改为「先探测 pytest 进程存活,无存活后再读文件」;或 sleep 改为 min(650s, 检测到日志结束符即提前读)。
+- **④ 修改目的**:一次取回率从 ~50% 提到 ~100%,避免多轮往返。
+- **⑤ 闭环**:同一脚本连续 2 轮首读即得完整 summary。
+
+---
+
+## 9. 门禁结论
+
+| 门禁 | 判据 | 实测 | 结论 |
+|------|------|------|------|
+| G1 全量通过率 | ≥95% | **98.37%**(3444/3501) | ✅ |
+| G2 红例数 | ≤10 | **50**(后端 33 + 根级 16 + langgraph 1) | ❌ |
+| G3 前端 Jest | 0 红 | 423 过 / 0 红 / 3 skip | ✅ |
+| G4 管理端 Jest | 0 红 | 116/116 | ✅ |
+| G5 编译与完整性 | testCompile 0 错 + XML 无沉默 | 343 源 0 错;**339/339** | ✅ |
+| G6 浏览器 | 28/28 | **28/28** | ✅ |
+| G7 langgraph | 0 红 | **1 红**(凭据 401,已实锤) | ❌ |
+| G8 鉴权契约 | 全 401 | 23/23(含 `/api/mind/**`,第 2 轮稳定) | ✅ |
+| G9 SRS 锚点 | ≥80% | 17.1%(严格)/ 19.1%(宽松) | ❌ |
+| G10 双节点派发 | 251 + 189 均实派 | 251 ✅(第 2 轮) / 189 ⚠️(B-122 延续) | ⚠️ 部分 |
+| G11 CI 含后端全量 | 存在 blocking 全量 | 无 | ❌ |
+| G12 用例入库 | 本轮有新增/更新 | 无 SRS 变更 → 不新增(合规) | ✅ |
+
+**总裁决:不通过(有条件)**
+
+- 阻塞放行的三项延续:**G2 50 红**、**G9 锚点 17.1%**、**G11 无 CI 全量**。
+- 相比 R123:**严格零漂移**(G1/G3/G4/G5/G6/G8 全部维持)+ **G7 根因实锤**(凭据 401)+ **B-121 达销号判据**。
+- 放行建议:全量连续两轮零漂移且鉴权契约全绿,**支持内网灰度**;不支撑对外正式发布,除非 G2 中 13 例 B 类产品红有明确结论或在研修复。
+- 建议下步:研发对 **13 例 B 类产品红** 批量派单(两轮零漂移 = 稳定缺陷);运维**轮换 LLM 凭据**闭环 B-74。
+
+---
+
+## 10. 窗口内变更登记(SRS 闸门)
+
+| 检查项 | 结果 |
+|--------|------|
+| `docs/superpowers/specs` 200 份 | 窗口内(12:35→14:10)**零新增 / 零修改**(`find -newermt` 零命中) |
+| `docs/tdd/user-scenarios` 11 份 | 零变更 |
+| `docs/superpowers/api/API_REFERENCE.md` | 零变更(mtime 01:21,早于窗口) |
+| 代码侧变更 | 窗口内远端仅 `67b5f6325` `chore: auto bump`,**零源码变更** |
+| 结论 | **不新写用例**;SRS→用例映射关系保持,缺口转 §6 G-124-7 |
+
+---
+
+## 11. 度量
+
+| 指标 | 值 |
+|------|----|
+| 测试类 / `@Test` / `@Disabled` | 339 / 2854 / 4 |
+| 控制器 / `@GetMapping` | 363 / **8(违 AGENTS.md)** |
+| SRS 规格 / 用例台账 | 200 / 14 |
+| 场景(`^## 场景`) | 198(沿用,窗口零变更) |
+| TC(严格 `/TC-[A-Z]{1,3}-[A-Z]{1,2}-?\d{1,3}/`) | 333 |
+| TC(宽松,含引用) | 866 |
+| 可执行 TC 锚点(唯一,排 `generated`) | 165 |
+| 锚点率 | 17.1%(严格)/ 19.1%(宽松) |
+
+---
+
+## 12. 本轮方法论沉淀
+
+1. **全量零漂移是「稳定归因」信号而非「无问题」信号**:连续两轮 30F+3E+4S 完全复现,说明 33 红例已稳定归因(A 装置 16 + B 产品 13 + C 数据 1 + 契约 3),可批量派研发处置,而非每轮重新勘察。
+2. **LLM 凭据失效会让 auto_tag 红例「名漂移」**:R123 `content_relevance`、R124 `valid_format`——同一文件内用例名随 LLM 输出漂移,但根因一致(凭据 401)。判断凭据类红例要看**日志关键字**(`Authentication Fails`)而非用例名。
+3. **远程 shell「单次读」必须覆盖 LLM 慢链路**:pytest 在 401 时会 SLOW_REQUEST 44s 重试,总时长从 344s 拉到 593s;固定 sleep 400s 会读到中途。正确判据:日志含 `summary` 或 pytest 进程退出,而非固定时长。
+4. **B-123 处置持续有效**:连续 2 轮前置环境探针(java/mvn/df)后跑通后端全量,无「凭记忆判环境」复发。
+
+---
+
+*报告结束。所有结论以本轮实测数据为准,未沿用历史数字作为通过依据。*

+ 76 - 0
docs/tdd/test/automation-run-2026-11-10-R124.md

@@ -0,0 +1,76 @@
+# 自动化执行记录 · 第 124 轮(2026-11-10 13:35~14:20)
+
+## 环境探针(B-123 处置,SOP 前置)
+
+```
+java version "1.8.0_25"           JAVA_HOME=D:\jdk1.8.0_25
+Apache Maven 3.6.1                Maven home: D:\maven\apache-maven-3.6.1
+D: 294G total, 93G avail (69%)
+```
+
+结论:本机 Maven / JDK 完全可用(第 2 轮探针通过)。
+
+## 基线
+
+| 项 | 值 |
+|----|----|
+| 分支 | `cfclub` |
+| 起点 HEAD | `2f04b1033`(R123 报告提交) |
+| 收尾远端 | `origin/cfclub = 67b5f6325`(+1 提交 `chore: auto bump`,零源码变更) |
+| SRS/场景窗口变更 | **零**(`docs/superpowers/specs` 200 份、user-scenarios、API_REFERENCE 全零变更) |
+
+## 执行清单
+
+| 步骤 | 命令 | 结果 |
+|------|------|------|
+| 后端全量 | `mvn -o -B clean test`(JDK1.8.0_25 + Maven 3.6.1) | 2865 例 / 2828 过 / 30F+3E+4S / **98.71%** / 34:03 |
+| 完整性 | surefire XML **339/339** | 与 339 测试类一一对应,沉默 0 |
+| 管理端 | `cd cfc-web && npx jest --silent` | 17 套 / 116 例 / 116 过 |
+| 小程序 | `cd cfc-frontend && npx jest --silent` | 26 套 / 426 例 / 423 过 / 3 skip |
+| 根级 | `cd tests && npx jest --silent` | 3 套 / 23 例 / 7 过 / 16 红(B-36 第 27 轮零漂移) |
+| 浏览器 live | `npx playwright test -c playwright.config.live.js` | **15/15**(U05 57.8s 绿) |
+| 浏览器 health | `npx playwright test -c playwright.config.health.js` | **13/13** |
+| langgraph@251 | kick 分离 + 本地 sleep + 单次读 | **42 过 / 1 红 / 593.85s**(`test_auto_tag_valid_format`,LLM API key 401) |
+| 线上鉴权 | `POST /api/mind/fortune`、`/api/energy/overview` | 均 **401** |
+| 站点可达 | `GET /admin`、`/frontend` | 均 302(0.07ms / 0.71ms) |
+
+## 聚合结果(test_report_metrics.py,口径与历轮一致)
+
+```
+classes=339 tests=2865 pass=2828 F=30 E=3 S=4 rate=98.71% red_classes=14 red_cases=33
+```
+
+红类集合与 R123 **逐类一致、仅少 0 例**(差集空):
+
+| 桶 | 类 | 例数 | 备注 |
+|----|------|------|------|
+| A 装置 | CfCommissionServiceSettleTest | 8 | Wanted but not invoked |
+| A 装置 | ArticleAutoTagServiceTest | 4 | threadPoolTaskExecutor.execute 未命中/过多 |
+| A 装置 | GrowthRecordSyncFlowTest | 3 | 1F + 2E(NPE) |
+| A 装置 | TaskPlanServiceTest | 1 | expected 100 but was null |
+| B 产品 | EnergySystemFlowTest | 6 | 5×500 + 1 false |
+| B 产品 | OrchestrationEngine/Integration | 2 | 节点状态断言 |
+| B 产品 | MembershipPaySwitchTest | 1 | 配置缺失仍建单 |
+| B 产品 | PaymentServiceORDRoutingTest | 1 | unknownPrefix 路由 FAIL |
+| B 产品 | UserServiceWechatLogin(Contract)Test | 2 | jwt-token null |
+| B 产品 | TeamProfitCronContractTest | 1 | 冷却期退款 cancelled=0 |
+| C 数据 | GuideModuleIntegrationTest | 1 | platform_fee Out of range(第 13 轮) |
+| 契约待裁决 | DimensionRegistryMapContractTest | 3 | null vs 原值 / 400 vs 200 |
+
+**MindFortuneControllerTest 不在红类清单**(B-69 落码维持);**环境红 0**(B-13 观察持续);**@GetMapping 8 处**维持。
+
+## 251 派发记录(第 2 次踩坑修正)
+
+- 第 1 次:`setsid nohup` kick + 本地 sleep 400s + 单次读 → 只读到 `...F..`(pytest 因 LLM 401 慢链路 593.85s 未跑完时读早)。印证 B-125:等待时长须 ≥ LLM 慢倍率。
+- 第 2 次:探活确认 pytest 仍存活 → 再读文件,取回完整 summary:`1 failed, 42 passed, 8 warnings in 593.85s`;`pkill` 清理残留进程。
+- 红例名变化:R123 为 `test_auto_tag_content_relevance`,本轮为 `test_auto_tag_valid_format`——**同库同文件,均依赖 LLM 语义输出**(API key `****ab12` 401 invalid),B-74 同源收窄观察。
+- 本轮 langgraph 实派仍由 **251 节点承担**(合规),耗时 593.85s(首轮实派 344.83s → 本轮 LLM 401 重试拖慢)。
+
+## 节点探活
+
+| 节点 | 端口 | 结论 |
+|------|------|------|
+| 本机 | — | 浏览器 28/28 全量承担(单任务) |
+| `192.168.16.189` | 4090 OPEN | **通道可用但不可承载**(B-122 延续):仓库仍 `feature/user-is-child @ e3e52ca38`,`tests\e2e-live=False`、`node_modules=False` → 未派发 |
+| `192.168.16.251` | 4096/9000 OPEN | langgraph 实派成功;`/health` 200 |
+| `192.168.16.204` | 4090 CLOSED | 延续失联(B-95) |

+ 15 - 0
docs/tdd/test/blockers.md

@@ -375,3 +375,18 @@
 | B-36-Update(第 123 轮 · 第 26 轮零漂移) | 根级黑盒 23 例 16 红 | 测试 | **零漂移**。本轮实跑 23 例:7 绿 / 16 红(`ECONNREFUSED`,9082 未启动) | 测试负责人(第 123 轮实测) | 2026-11-10 13:30 | 待处理(P1) |
 | B-13-Update(第 123 轮 · 首次实跑) | 3 类硬编码 `127.0.0.1:3306` 的 `@SpringBootTest` | 研发/环境 | 后端全量实跑 339 类,**环境型红 0**(`AdminFamilyOverviewControllerTest` 3/3 绿);硬编码仍在,换机即复现 | 测试负责人(第 123 轮实测) | 2026-11-10 13:30 | 观察(P2) |
 | B-95-Update(第 123 轮 · 延续失联) | `192.168.16.204` 节点失联 | 运维 | 延续失联。本轮浏览器任务由本机承担(单节点单任务合规) | 测试负责人(第 123 轮探活) | 2026-11-10 13:30 | 待处理(P2) |
+
+<!-- ===== 第 124 轮(2026-11-10 14:20,本自动化)追加 ===== -->
+
+| B-121-Close(第 124 轮 · **销号**) | 本机 `admin-desktop` TC-A-U05 登录前置确定性失败 | 研发/测试 | **销号(第 124 轮,连续 2 轮绿达成)**。R123 首绿、**本轮再次绿(57.8s)**,U04 9.9s 同绿,首轮即绿无重跑 → 按 R123 判据「连续 2 轮 U05 绿 → 销号」满足。判「节点偶发(滑块/风控时序)」成立,非产品回归 | 测试负责人(第 124 轮实跑) | 2026-11-10 14:20 | **已闭环(销号)** |
+| B-122-Update(第 124 轮 · 延续第 2 轮) | `192.168.16.189` 通道可用但不具备浏览器执行前提 | 运维 | **延续(P2 第 2 轮)**。复测:仓库仍 `C:\worktrees\cfc-user-is-child @ e3e52ca38`(`feature/user-is-child`),`Test-Path tests\e2e-live=False`、`node_modules=False` → 不可承载。闭环判据不变:189 worktree 更新至 `cfclub` 且预置 `tests/node_modules` → 实派 `admin-desktop` 5/5 取回 | 测试负责人(第 124 轮复测) | 2026-11-10 14:20 | 待处理(P2,运维) |
+| B-123-Update(第 124 轮 · 第 2 轮通过) | R122 以「本机无 Maven」降级致后端整模块漏测 | 测试 | **第 2 轮通过**。本轮前置探针 `java 1.8.0_25 / mvn 3.6.1 / D: 93G` 全过,`mvn -o -B clean test` 34:03 拿 2865 例 / 98.71%。闭环判据:连续 3 轮报告含探针输出且无 Maven 类降级 → 销号(本轮为第 2 轮,尚需 1 轮) | 测试负责人(第 124 轮实测) | 2026-11-10 14:20 | 处置中(P1) |
+| B-124-Update(第 124 轮 · 未闭环) | TC 锚点度量口径不一致 | 测试 | **未闭环(P2 第 2 轮)**。`test_report_metrics.py --reports` 聚合可用(本轮 `classes=339 tests=2865 pass=2828 F=30 E=3 S=4`),但 `--scene` 输出仍无 stdout,G9 锚点沿用 17.1%/19.1% 沿用口径。闭环判据不变:连续 2 轮 G9 由脚本产出且一致 | 测试负责人(第 124 轮复算) | 2026-11-10 14:20 | 待处理(P2) |
+| B-125-Update(第 124 轮 · 观察) | 远程 shell 轮询会杀掉在跑进程 / 等待时长未自适应 | 测试 | **观察(P1 第 2 轮)**。本轮采用「kick 分离 + sleep + 单次读」:首读 sleep 400s < 实际 593.85s → 只取到 `...F..`;探活确认 pytest 存活后再读 → 完整 summary。印证**等待须以「pytest 进程退出」为判据而非固定时长**(LLM 401 时总时长从 344s 拉长到 593s)。闭环判据:同一脚本连续 2 轮首读即得完整 summary | 测试负责人(第 124 轮定位) | 2026-11-10 14:20 | 待处理(P1,工具) |
+| B-74-Update(第 124 轮 · 根因实锤) | langgraph `test_auto_tag.py` 红例 | 研发/运维 | **根因实锤(P1)**。本轮 251 实派唯一红例 `test_auto_tag_valid_format`,日志捕获 **`Authentication Fails, Your api key: ****ab12 is invalid`(401)** → 打标空标签 → 断言失败。红例名较 R123(`content_relevance`)漂移但**同一文件同一 LLM 依赖**。处置:运维轮换有效 LLM 凭据;测试侧主断言改确定性桩 + `@pytest.mark.llm` 冒烟;251 装 `pytest-timeout` | 测试负责人(第 124 轮 251 实派) | 2026-11-10 14:20 | 待处理(P1,运维凭据) |
+| B-65-Close(第 124 轮 · 独立复核第 2 轮) | langgraph analyze checkpointer 缺 thread_id | 研发 | **维持销号(251 实派第 2 轮独立复核)**。`test_analyze` 2 例均不在失败清单,与 R123 一致 | 测试负责人(第 124 轮 251 实派) | 2026-11-10 14:20 | **已闭环(销号)** |
+| B-82-Close(第 124 轮 · 独立复核第 2 轮) | langgraph `test_intent.py` 4 例静默降级 | 研发 | **维持销号(251 实派第 2 轮独立复核)**。`test_intent` 4 例不在失败清单;251 全量仅 1 红(B-74) | 测试负责人(第 124 轮 251 实派) | 2026-11-10 14:20 | **已闭环(销号)** |
+| B-69-Update(第 124 轮 · 维持销号第 2 轮) | `/api/mind/**` 匿名可达 | 研发 | **维持销号(第 2 轮双通道一致)**。线上匿名 `POST /api/mind/fortune` → **401**,对照 `/api/energy/overview` → 401;后端全量 `MindFortuneControllerTest` 连续 2 轮不在红类清单 | 测试负责人(第 124 轮线上+后端双证) | 2026-11-10 14:20 | **已闭环(销号)** |
+| B-36-Update(第 124 轮 · 第 27 轮零漂移) | 根级黑盒 23 例 16 红 | 测试 | **零漂移**。本轮实跑 23 例:7 绿 / 16 红(`ECONNREFUSED`,9082 未启动) | 测试负责人(第 124 轮实测) | 2026-11-10 14:20 | 待处理(P1) |
+| B-13-Update(第 124 轮 · 第 2 轮观察) | 3 类硬编码 `127.0.0.1:3306` 的 `@SpringBootTest` | 研发/环境 | 后端全量实跑 339 类,**环境型红 0**(第 2 轮);硬编码仍在,换机即复现 | 测试负责人(第 124 轮实测) | 2026-11-10 14:20 | 观察(P2) |
+| B-95-Update(第 124 轮 · 延续失联) | `192.168.16.204` 节点失联 | 运维 | 延续失联。本轮浏览器任务由本机承担(单节点单任务合规) | 测试负责人(第 124 轮探活) | 2026-11-10 14:20 | 待处理(P2) |

+ 46 - 0
docs/tdd/研发交接通知-2026-11-10-第124轮.md

@@ -0,0 +1,46 @@
+# 研发交接通知 · 第 124 轮(2026-11-10 14:20)
+
+> 测试负责人 → 研发团队。本轮为定时自动化闭环第 124 轮,基线 `cfclub @ 2f04b1033`。
+
+## 一、测试结果总览
+
+| 套件 | 结果 | 对比 R123 |
+|------|------|-----------|
+| 后端全量 | 2865 例 / 2828 过 = **98.71%**(30F+3E+4S,红类 14 / 红例 33) | **零漂移** |
+| cfc-web | 116/116 | 零漂移 |
+| cfc-frontend | 423/426(3 skip) | 零漂移 |
+| 根级 tests | 7/23(16 红 = B-36,9082 未启动) | 零漂移 |
+| 浏览器 | **28/28**(live 15 + health 13) | 零漂移 |
+| langgraph @251 | 42/43(1 红 = B-74) | 红例名漂移(同根因) |
+| 门禁 | **不通过(有条件)** | 同 R123 |
+
+## 二、本轮需要研发关注的变化(3 项)
+
+### 1. B-74 根因实锤:LLM API key 401(P1,需运维轮换凭据)
+
+- 251 实派 pytest 唯一红例 `test_auto_tag_valid_format`,日志捕获 **`Authentication Fails, Your api key: ****ab12 is invalid`(401)**。
+- 打标链路返回空标签(`实际 0: []`)→ 断言失败。红例名较 R123(`content_relevance`)漂移,**同文件同 LLM 依赖,根因同一**。
+- **请运维轮换有效 LLM 凭据**并注入环境变量(251 与生产同源);测试侧建议主断言改确定性桩。
+
+### 2. B-121 销号:admin TC-A-U05 连续 2 轮绿
+
+- 本轮 U05 **57.8s 通过**(R123 亦绿)→ 按判据连续 2 轮绿达成,**销号**。
+- 结论:R122 的「确定性失败」判过重,实为节点偶发(滑块/风控时序),非产品回归。无需研发处理。
+
+### 3. B 类产品红 13 例连续两轮零漂移(可批量派单)
+
+- `EnergySystemFlowTest` 6(5×500)、`Orchestration*` 2、`MembershipPaySwitch` 1、`PaymentORD` 1、`WechatLogin` 2、`TeamProfitCron` 1。
+- 连续 2 轮逐例同名同型 = **稳定缺陷,非偶发**。建议研发批量派单定位(EnergySystem 疑 DB/事务;TeamProfitCron 冷却期退款未置 `cancelled`)。
+
+## 三、维持不变的观察项
+
+- B-36(根级 16 红,环境未起,测试侧自处置)、B-13(环境红 0)、B-65/B-82/B-69(销号维持,251 独立复核第 2 轮)、B-122(189 不可承载,运维)、B-95(204 失联)、B-123(探针第 2 轮,尚需 1 轮销号)、B-124/B-125(度量/工具)。
+
+## 四、放行建议
+
+- 全量连续两轮零漂移 + 鉴权契约全绿(含 `/api/mind/**` 第 2 轮稳定)→ **支持内网灰度**。
+- 不支撑对外正式发布,除非 G2 中 13 例 B 类产品红有明确结论或在研修复。
+
+---
+
+*本通知由测试负责人自动生成,已随 `report-test-2026-11-10-R124.md` 一并推送。*