Explorar el Código

docs(tdd): 测试负责人第125轮闭环汇报(3501/3445=98.40%·langgraph@251 43/43首次全绿·B-123销号)

- 浏览器自动化 28/28(admin 5/5 首轮·frontend 6/6·shop 4/4·health 13/13)
- langgraph@251 43 例 43 过 0 红(756.13s),B-74 连续22轮红例后首次全绿(观察第1轮)
- cfc-frontend 426(423+3skip)/ cfc-web 116 / 根级 23(7过16红 B-36)
- 后端采信 R124(源码零变更)2865/2828=98.71%
- B-123 连续3轮探针通过销号;B-121 销号后维持绿
- 台账刷新:363控制器/1969handler/覆盖442(22.5%)/@Test 2853/跨源4168
- 线上鉴权 mind/fortune、energy/overview 均401(B-69维持)
E2E Test Bot hace 2 días
padre
commit
3e385144ca

+ 320 - 0
docs/tdd/orchestration/report-test-2026-11-10-R125.md

@@ -0,0 +1,320 @@
+# 测试闭环报告 · 第 125 轮(2026-11-10 14:55 GMT+8)
+
+> 主理人:陆谨(软件测试专家团 · 测试架构师)
+> 执行档:**review 档**(内网 `cfc.iwintrue.com` 已授权;无联网外部请求;未装依赖;未改生产代码)
+> 对象:`d:/cfc`(浠艾福 XAF)
+> 触发:定时自动化「测试负责人闭环(全部用例通过 + 覆盖 SRS/场景含异常流)+ 浏览器走 `/admin` 与 `/frontend`(189/本机每节点单任务)+ langgraph 派 251 + 结果有变提交远程并通知研发」
+
+---
+
+## 0. 本轮结论速览
+
+| 项 | 值 |
+|----|----|
+| 基线 | `cfclub @ 75bf2c841`(pull --rebase 后与 origin 同步;R124 后源码零变更) |
+| 全量用例 | **3501 例 / 3445 过 = 98.40%**(红 49 / 跳过 7) |
+| 对比上轮(R124 `98.37% / 3444 过`) | **langgraph 红例 1→0**(+1 过),其余套件零漂移 |
+| 后端全量 | **采信 R124**(源码零变更):2865 例 / 2828 过 = 98.71%,30F+3E+4S,14 红类 / 33 红例 |
+| 浏览器自动化 | **28/28 全绿**(live 15 + health 13) |
+| langgraph @ 251 | **43 例 / 43 过 / 0 红**(756.13s)——**B-74 连续 22 轮红例后首次全绿** |
+| 门禁 | **不通过(有条件)** — 见 §9 |
+
+**三件必须让研发看到的事**
+
+1. **langgraph@251 首次全量全绿(B-74 重大转机)**:R103~R124 连续 22 轮 `test_auto_tag.py` 5 例红(LLM API key 401,红例名 content_relevance/valid_format 漂移)后,本轮 **43/43 全绿(0 红,756.13s)**。251 已 `git reset --hard origin/cfclub`(`f5a014a46`)对齐远端。按判据需连续 ≥2 轮全绿才销号,本轮为**观察第 1 轮无复现**。
+2. **B-123 达销号判据(连续 3 轮探针通过)**:R123/R124/R125 三轮均前置环境探针(java 1.8.0_25 / Maven 3.6.1 / 磁盘充足)且无「凭记忆判环境」导致的 Maven 类降级 → **销号**。
+3. **B-121 销号后持续稳定**:`TC-A-U05` 本轮 56.7s 通过、首轮即绿无重跑(R124 销号后第 1 轮),「admin 登录滑块偶发自愈」结论成立。
+
+---
+
+## 1. 历史审查记录
+
+| 项 | 内容 |
+|----|------|
+| 上次本对象审查 | R124 @ 2026-11-10 14:20(`67b5f6325`,即本轮起点 HEAD 前身) |
+| 上次结论 | 不通过(有条件):G2 50 红 / G7 langgraph 1 红(凭据 401)/ G9 锚点 / G11 无 CI |
+| 上次遗留缺口 | ① B-74 LLM 凭据 401(已实锤、未闭环)② B-125 派发等待未自适应 ③ 覆盖率/变异/压测/安全 长期未实测 |
+| 本次是否改善 | ① **B-74 首次全绿(观察第 1 轮)** ✅ ② B-123 连续 3 轮 → **销号** ✅ ③ B-125 继续观察(本月度工具改进项)④ 未变(execute 档未授权) |
+| 是否首次审查 | 否。同对象已连续审查 ≥125 轮 |
+
+> 本节仅作对照。本轮全部结论均以本轮实测取证;仅「后端全量」因源码零变更采信 R124 实跑结果(纪律允许),并仍以 R124 红类清单为口径。
+
+---
+
+## 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) |
+| 规模(本轮实测) | 测试文件 **345**、`@Test` **2853**、控制器 **363**、handler **1969**(覆盖 442=22.5%);SRS 规格 200 份 |
+| 关键路径 | 登录鉴权(JWT 拦截 + 8 公开路径)→ 家庭成员/关系 → 成长任务与能量 → 健康报告上传-解析-入库 → 测评订单 → 商城下单/分润 → AI 对话/画像 |
+| 质量目标 | 全量用例通过率、SRS/场景锚点覆盖、线上鉴权契约、浏览器双端可用性、跨节点可派发 |
+| 本轮风险点 | 后端 33 红(A 装置 16 + B 产品 13 + C 数据 1 + 契约 3)待派单;G9 锚点率 17.1%(B-124 未闭环);189 节点仓库陈旧(B-122);251 派发等待时长未自适应(B-125) |
+
+---
+
+## 3. 20 类测试覆盖矩阵
+
+图例:● 已发现(有资产且有本轮/近期实测证据)/○ 未发现(扫描未命中)/◐ 待核实(有资产但本轮未实测或被降级)
+
+| # | 类别 | 状态 | 证据 |
+|---|------|------|------|
+| 1 | 单元测试 | ● | 后端 2865 例(采信 R124 实跑);cfc-web 116、cfc-frontend 426 Jest 本轮实跑 |
+| 2 | 组件测试 | ● | 后端 `*ControllerTest`(MockMvc)+ 前端 Vue 组件 `__tests__` |
+| 3 | 接口 API 测试 | ● | health 契约 13 例(全 401)+ shop-sort 4 例本轮实跑 |
+| 4 | 系统 / 端到端 | ● | `/admin` 5 例 + `/frontend` 6 例真浏览器实跑(Playwright 1 worker) |
+| 5 | 验收 UAT | ◐ | 198 场景文档映射存续,无独立 UAT 执行记录(凭据不全) |
+| 6 | 冒烟测试 | ● | 每轮固定 28 例 live/health 冒烟;本轮全绿 |
+| 7 | 回归测试 | ● | 后端全量 + 三套 Jest + 浏览器 = 本轮回归基线 |
+| 8 | 探索性测试 | ○ | 无 chartered 探索会话记录 |
+| 9 | 契约测试 | ● | health 13 + shop-sort 4 + 后端 `*ContractTest`(DimensionRegistryMap 3 红待裁决等) |
+| 10 | 性能测试 | ○ | 无压测脚本与基线(execute 档,需联网授权) |
+| 11 | 可靠性测试 | ○ | 无故障注入/恢复演练 |
+| 12 | 安全测试 | ◐ | 鉴权契约 23 端点实测(全 401);SAST/DAST/依赖扫描未执行 |
+| 13 | 兼容性测试 | ◐ | 仅 Chromium;多浏览器/多机型矩阵未执行 |
+| 14 | 可用性测试 | ○ | 无真实用户可用性证据 |
+| 15 | 无障碍测试 | ○ | 无 WCAG 检查 |
+| 16 | 覆盖率度量 | ◐ | 后端 JaCoCo 离线不可用;handler 覆盖 442/1969=22.5%(静态口径) |
+| 17 | 变异测试 | ○ | 无 PIT/mutation 配置 |
+| 18 | 质量指标 | ● | 通过率/红例分布/桶分布本轮重算(§8) |
+| 19 | QA 流程 | ● | 自动化闭环 125 轮可追溯;门禁脚本化不足(G11) |
+| 20 | 代码审查 | ● | 本轮抽检后端红类清单与 R124 一致(14 红类) |
+
+---
+
+## 4. 测试方案(本轮实际执行)
+
+| 项 | 内容 |
+|----|------|
+| 目标 | 验证 R124 后是否零漂移;重点复核 langgraph B-74 红例;SRS/场景变更检测;浏览器双端可用性 |
+| 范围 | 浏览器 live 15 + health 13、cfc-web 17 套、cfc-frontend 26 套、根级 3 套、langgraph@251 43 例;后端采信 R124(源码零变更) |
+| 覆盖维度 | 功能层次 5 类 + 功能保障 4 类 + 非功能鉴权(部分) |
+| 执行档 | review(离线白名单);内网 HTTP 探针与 cfc.iwintrue.com 浏览器访问均属已授权范围 |
+| 优先级 | P0:浏览器双端 + 鉴权契约 + 251 派发;P1:前端 jest;P2:台账刷新 |
+| 排除项 | 压测、DAST/SCA、变异、多浏览器矩阵、UAT 全流量(未授权/无凭据)——报告中标「未实测」,不计通过 |
+
+---
+
+## 5. 执行结果明细
+
+### 5.1 后端全量(采信 R124,源码零变更)
+
+| 项 | 值 |
+|----|----|
+| 结果(R124 实跑) | **2865 例 / 2828 过 / 30F + 3E + 4S = 98.71%**(34:03) |
+| 红类 / 红例 | 14 类 / 33 例 |
+| 完整性 | surefire XML 339/339,沉默 0 |
+| 本轮采信依据 | `git diff 167387161..HEAD -- src 全模块` 为空(仅 docs + bump/changelog) |
+
+**33 红三层归因**(与 R124 逐类一致):A 装置 16(CfCommission 8 / ArticleAutoTag 4 / GrowthRecordSync 3 / TaskPlan 1)· B 产品 13(EnergySystem 6 / Orchestration 2 / MembershipPaySwitch / PaymentORD / WechatLogin 2 / TeamProfitCron)· C 数据 1(GuideModule platform_fee)· 契约待裁决 3(DimensionRegistryMap)。
+
+### 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 未启动) |
+
+### 5.3 浏览器自动化(workers=1,单节点单任务)
+
+| 套件 | 例数 | 结果 | 耗时 |
+|------|------|------|------|
+| `admin-desktop`(/admin) | 5 | **5/5** | U04 9.5s / **U05 56.7s**(首轮即绿) |
+| `frontend-mobile`(/frontend) | 6 | **6/6** | 3.3~9.1s |
+| `shop-api` | 4 | **4/4** | 59~147ms |
+| `health-api`(契约) | 13 | **13/13** | 4.1s(全 401) |
+
+合计 **28/28 全绿**,与 R118/R120/R123/R124 基线一致。
+
+### 5.4 langgraph @ 192.168.16.251(实派)
+
+| 项 | 值 |
+|----|----|
+| 通道 | `_r125_dispatch_251.cjs`(kick 分离写盘 → sleep 620s → 单次读),port 4096 |
+| 节点 HEAD | `f5a014a46`(随 kick 内 `git reset --hard origin/cfclub` 对齐远端) |
+| 结果 | **43 passed / 0 failed / 8 warnings in 756.13s** |
+| 对比 R124 | R124 42/1(auto_tag_valid_format,LLM 401)→ **本轮 B-74 红例首次消失** |
+| 观察 | 待连续 ≥2 轮全绿后按判据销号(本轮为第 1 轮全绿) |
+
+### 5.5 节点可达性
+
+| 节点 | 端口 | 结论 |
+|------|------|------|
+| 本机 | — | 浏览器 28/28 全量承担(单任务) |
+| `192.168.16.189` | 4090 OPEN | **不可承载(B-122 第 3 轮)**:仓库 `feature/user-is-child @ e3e52ca38`、`tests\e2e-live=False → 未派发 |
+| `192.168.16.251` | 4096/9000 OPEN | **langgraph 实派成功**(43/43 全绿) |
+| `192.168.16.204` | — | 延续失联(B-95) |
+
+### 5.6 线上鉴权与可达性(curl 探针)
+
+| 目标 | 结果 |
+|------|------|
+| `GET http://cfc.iwintrue.com/admin` | 302(登录墙) |
+| `GET http://cfc.iwintrue.com/frontend` | 302 |
+| `POST /api/mind/fortune`(匿名) | **401**(B-69 维持销号) |
+| `POST /api/energy/overview`(匿名) | **401** |
+
+---
+
+## 6. 覆盖缺口清单
+
+| 编号 | 缺口类型 | 现状 | 风险 | 建议测试设计 | 优先级 | 闭环方式 |
+|------|---------|------|------|-------------|--------|---------|
+| G-125-1 | 性能测试 | 无脚本无基线 | 健康报告解析/AI 对话为长耗时链路 | k6 对 `POST /api/health/report/upload`、`/api/v1/chat` 做 20/50 并发阶梯,记录 P95 | P2 | execute 档授权后执行 |
+| G-125-2 | 可靠性 | 无故障注入 | EnergySystem 500 类问题生产直接暴露 | MySQL 断连 + LLM 超时各注入 1 次,断言降级 | P2 | 与研发约定注入窗口 |
+| G-125-3 | 安全扫描 | 仅鉴权契约 | 覆盖仅 23 端点未鉴权路径 | SAST(Semgrep)+ 依赖漏洞(mvn dependency-check) | P2 | execute 档授权 |
+| G-125-4 | 兼容性/无障碍 | 仅 Chromium | 小程序多机型、WCAG 均空 | Playwright 加 firefox/webkit;axe-core 扫 /admin 5 页 | P3 | 增配置后纳入冒烟 |
+| G-125-5 | 覆盖率 | 后端 JaCoCo 离线不可得 | 通过率≠行覆盖率 | 预置 jacoco agent 后 `mvn test jacoco:report` | P1 | 预置依赖后补测 |
+| G-125-6 | 变异测试 | 无 | 高通过率可能掩盖弱断言 | EnergySystemService/CfCommissionService 引 PIT,kill ≥60% | P3 | 专项排期 |
+| G-125-7 | UAT / BDD | 198 场景仅文档映射 | 场景与断言未一一绑定 | 锚点规范落到 `tests/test-cases`,每场景 ≥1 可执行断言 | P1 | B-124 |
+| G-125-8 | A/B 类红例 | 后端 33 红连续多轮零漂移 | 真实产品缺口被装置红掩盖 | 批量派研发处置 B 类 13 例 + 测试侧自修 A 类 16 例 | P0 | 派单 + 自修双线 |
+| G-125-9 | 根级黑盒 | 23 例 16 红(ECONNREFUSED) | 环境未起被计为产品失败 | 根级套件加 beforeAll 探活 skip | P1 | B-36 |
+
+---
+
+## 7. 域结论表
+
+| 审查维度 | 负责专家 | 结论 | 关键证据 |
+|---------|---------|------|---------|
+| 单元·组件级 | 苏雅 | **有条件通过** | 后端 2865 例 98.71%(采信 R124);14 红类(A 装置 16 阻塞口径);web 116/116、frontend 423/426 |
+| 集成·接口级 | 柯砚 | **不通过(局部)** | 契约 23 端点全 401 ✅;DimensionRegistryMap 3 例待裁决、platform_fee 1 例 |
+| 系统·验收级 | 白樾 | **有条件通过** | 浏览器 28/28 ✅;UAT 全流量未执行(无凭据) |
+| 测试保障级 | 闻朔 | **通过** | 冒烟 28/28;回归全量连续多轮可复跑;探索性缺失(登记缺口) |
+| 性能·可靠性 | 骆骋 | **未实测(降级)** | execute 档未授权 → G-125-1/2 |
+| 安全 | 关屿 | **有条件通过** | 匿名 23 端点全 401(含 /api/mind/**,维持销号);SAST/SCA 未执行 |
+| 兼容·体验 | 阮清 | **未实测(降级)** | 仅 Chromium;无 axe/WCAG → G-125-4 |
+| 流程·度量·代码 | 何序 | **不通过(局部)** | @GetMapping 8 处仍违规范;G9 锚点 3 套口径未统一(B-124);B-125 等待未自适应 |
+
+---
+
+## 8. 五要素问题清单
+
+### #1 langgraph B-74 首次全绿——观察而非销号(根因仍待凭据确认)
+
+- **① 问题描述**:R103~R124 连续 22 轮 `test_auto_tag.py` 红例(LLM API key `****ab12` 401)后,本轮 251 实派 **43/43 全绿(0 红)**。红例名漂移(content_relevance→valid_format)本轮消失;`test_analyze`/`test_intent` 同步全绿。
+- **② 测试 bug 点**:`cfc-langgraph/tests/test_auto_tag.py`(5 例依赖 LLM 语义输出,历史在主断言无固定桩时随凭据状态漂移)。
+- **③ 最优修改方案**:① 运维确认 251 上 LLM 凭据状态(是否已轮换/注入),如已轮换则稳定闭环;② 测试侧按 R124 建议把主断言改确定性桩(mock 固定标签集)+ `@pytest.mark.llm` 真链路冒烟;③ 251 `.venv` 装 `pytest-timeout` 防挂起(B-125 同源)。
+- **④ 修改目的**:把「凭据/网络」与「打标逻辑回归」彻底分离,使该维度可稳定门禁;凭据轮换解决的是**线上 LLM 能力可用性**(直接影响真实用户)。
+- **⑤ 闭环**:下轮(R126)251 复跑连续第 2 轮全绿 → 按判据销号;或凭据轮换后 5/5 稳定绿。
+
+### #2 B-123 达销号判据(连续 3 轮探针通过)
+
+- **① 问题描述**:R122 曾以「本机无 Maven」降级致后端整模块漏测;R123~R125 三轮均前置环境探针(java/mvn/df)且实测通过。
+- **② 测试 bug 点**:SOP(已修复,探针输出入报告固定节)。
+- **③ 最优修改方案**:维持「每轮固定探针,未跑探针不得写降级」。
+- **④ 修改目的**:杜绝「凭记忆判环境」导致整模块漏测。
+- **⑤ 闭环**:连续 3 轮达成 → **本轮销号**(B-123-Update 已登记)。
+
+### #3 A 类夹具 16 红(装置缺陷,非产品)
+
+- **① 问题描述**:`CfCommissionServiceSettleTest` 8、`ArticleAutoTagServiceTest` 4、`GrowthRecordSyncFlowTest` 3、`TaskPlanServiceTest` 1 红(Wanted but not invoked / execute 未命中 / NPE)。
+- **② 测试 bug 点**:`CfCommission...settle_*` 8 例;`ArticleAutoTag...toggleStatus_*` 4 例。
+- **③ 最优修改方案**:CfCommission 逐例核对 mock 方法签名与生产 7 参 overload;ArticleAutoTag 注入同步 Executor 替身;TaskPlan 补齐 @Mock 返回值;GrowthRecordSync 读 Caused by 最内层。
+- **④ 修改目的**:16 红退出统计,暴露真实产品缺口。
+- **⑤ 闭环**:定向复跑 4 类全绿(mvn -Dtest 精确集)。
+
+### #4 B 产品 13 红(连续多轮零漂移,可批量派单)
+
+- **① 问题描述**:EnergySystemFlowTest 6(5×500)、Orchestration 2、MembershipPaySwitch 1、PaymentORD 1、WechatLogin 2、TeamProfitCron 1——与 R123/R124 逐例同名同型,连续 3 轮零漂移。
+- **② 测试 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 数据,第 14 轮)
+
+- **① 问题描述**:`GuideModuleIntegrationTest` 写库报 `Data truncation: Out of range value for column 'platform_fee'`。
+- **② 测试 bug 点**:`GuideModuleIntegrationTest::testGuidePackageCreationFlow`(造数金额超出列宽)。
+- **③ 最优修改方案**:核对 `guide_order.platform_fee` 列类型与业务上限;合法则扩列(DatabaseInitializer 迁移 + schema.sql 同步),否则修造数。
+- **④ 修改目的**:避免真实大额订单写库失败。
+- **⑤ 闭环**:迁移后该类转绿 + 边界值(上限 ±1)复测。
+
+### #6 `DimensionRegistryMap` 契约 3 例待裁决
+
+- **① 问题描述**:`unknown_legacy`/`empty` 期望 data=null 实为原值/空串;`missing` 期望 400 实为 200。
+- **② 测试 bug 点**:`DimensionRegistryMapContractTest` 三例。
+- **③ 最优修改方案**:产品/研发对「未知 legacy 键」语义拍板,单向修正契约或用例,写入 SRS。
+- **④ 修改目的**:消除长期悬空契约。
+- **⑤ 闭环**:契约条款落 SRS 后 3 例按新条款全绿。
+
+### #7 根级黑盒 16 红(B-36,第 28 轮零漂移)
+
+- **① 问题描述**:`tests/` 根级 23 例稳定 7 绿 / 16 红,全部 ECONNREFUSED(后端 9082 未启动)。
+- **② 测试 bug 点**:`tests/integration/*.spec.js` 硬编码 `http://127.0.0.1:9082`,无「服务未起则 skip」保护。
+- **③ 最优修改方案**:beforeAll 探活,未起则 test.skip + 打印启动指引。
+- **④ 修改目的**:消除「环境未起被计为产品失败」的长期噪声。
+- **⑤ 闭环**:连续 1 轮根级 0 红(或 16 例显式 skip 而非 fail)。
+
+### #8 251 派发等待时长未自适应(B-125 第 3 轮观察)
+
+- **① 问题描述**:本轮首读 sleep 620s 仍只读到 35 个点(pytest 756.13s 未写完,缓冲未 flush),需第 2 次探活读取。
+- **② 测试 bug 点**:`_r125_dispatch_251.cjs` 固定 WAIT_MS,无「pytest 进程退出」判据。
+- **③ 最优修改方案**:等待循环改为「探测 pytest 进程存活,退出后再读文件」;或装 pytest-timeout 限制 LLM 网络重试挂起时长。
+- **④ 修改目的**:首读取回率从 ~50% 提到 ~100%,减少往返。
+- **⑤ 闭环**:同一脚本连续 2 轮首读即得完整 summary。
+
+---
+
+## 9. 门禁结论
+
+| 门禁 | 判据 | 实测 | 结论 |
+|------|------|------|------|
+| G1 全量通过率 | ≥95% | **98.40%**(3445/3501) | ✅ |
+| G2 红例数 | ≤10 | **49**(后端 33 + 根级 16) | ❌ |
+| G3 前端 Jest | 0 红 | 423 过 / 0 红 / 3 skip | ✅ |
+| G4 管理端 Jest | 0 红 | 116/116 | ✅ |
+| G5 编译与完整性 | testCompile 0 错 + XML 无沉默 | 采信 R124:343 源 0 错、339/339 | ✅ |
+| G6 浏览器 | 28/28 | **28/28** | ✅ |
+| G7 langgraph | 0 红 | **0 红(43/43,B-74 观察第 1 轮)** | ✅(观察) |
+| G8 鉴权契约 | 全 401 | 23/23(含 /api/mind/**) | ✅ |
+| G9 SRS 锚点 | ≥80% | 17.1%(严格) | ❌ |
+| G10 双节点派发 | 251 + 189 均实派 | 251 ✅ / 189 ⚠️(B-122 第 3 轮) | ⚠️ 部分 |
+| G11 CI 含后端全量 | 存在 blocking 全量 | 无 | ❌ |
+| G12 用例入库 | 本轮有新增/更新 | 无 SRS 变更 → 不新增(合规) | ✅ |
+
+**总裁决:不通过(有条件)**
+
+- 阻塞放行的三项延续:**G2 49 红**、**G9 锚点 17.1%**、**G11 无 CI 全量**。
+- 相比 R124:**G1 +0.03pp**(langgraph 红例 1→0)、**G7 首次全绿(观察第 1 轮)**、**B-123 销号**、**B-121 销号后稳定**;其余套件严格零漂移。
+- 放行建议:全量多轮零漂移 + 鉴权契约全绿 + langgraph 首次全绿,**支持内网灰度**;不支撑对外正式发布,除非 G2 中 13 例 B 类产品红有明确结论或在研修复。
+- 建议下步:研发对 13 例 B 类产品红批量派单;运维确认 251 LLM 凭据状态(如已轮换则 B-74 走向销号);测试侧推进 A 类 16 例自修。
+
+---
+
+## 10. 窗口内变更登记(SRS 闸门)
+
+| 检查项 | 结果 |
+|--------|------|
+| `docs/superpowers/specs` 200 份 | 窗口内(14:20→14:55)**零变更** |
+| `docs/tdd/user-scenarios` | 零变更 |
+| `docs/superpowers/api/API_REFERENCE.md` | 零变更 |
+| 代码侧变更 | 远端仅 `chore: auto bump`/研发汇报/docs,**零源码变更** |
+| 结论 | **不新写用例**;SRS→用例映射关系保持,缺口转 §6 G-125-7 |
+
+---
+
+## 11. 度量
+
+| 指标 | 值 |
+|------|----|
+| 测试文件 / `@Test` | 345 / 2853 |
+| 控制器 / handler / 覆盖 | 363 / 1969 / 442(22.5%) |
+| SRS 规格 / 用例台账 | 200 / 14 |
+| 场景(`^## 场景`) | 198(沿用,窗口零变更) |
+| TC 严格 / 宽松 | 333 / 866(沿用) |
+| 可执行 TC 锚点 | 165 |
+| 锚点率 | 17.1%(严格,B-124 沿用口径) |
+
+---
+
+## 12. 本轮方法论沉淀
+
+1. **langgraph 全绿 ≠ 凭据已修复**:连续 22 轮红例后首次全绿,原因可能是 251 `git reset --hard` 拉到最新代码(`f5a014a46`)、或 LLM 服务端瞬时恢复。判断依据是「连续 2 轮全绿」而非单轮结果——单轮全绿只能转观察,不销号。
+2. **「pytest 进程退出」优于固定 sleep**:620s 仍读到 35 点(缓冲未 flush),探活确认进程退出后才拿到完整 summary——B-125 判据从「固定时长」改为「进程退出 + 文件读完」。
+3. **远端 reset --hard 是双刃剑**:251 对齐 origin/cfclub 保证测的是最新代码,但也可能静默丢弃 251 本地未提交实验——每月派发前应确认 251 无 WIP。
+
+---
+
+*报告结束。所有结论以本轮实测数据为准,未沿用历史数字作为通过依据。后端全量采信依据为「源码零变更」纪律,R124 实跑结果仍有效。*

+ 95 - 0
docs/tdd/test/automation-run-2026-11-10-R125.md

@@ -0,0 +1,95 @@
+# 自动化执行记录 · 第 125 轮(2026-11-10 14:24~14:55)
+
+## 环境探针(SOP 前置)
+
+```
+本机:9082 DOWN / 4090 DOWN / 4091 UP(opencode)
+cfc.iwintrue.com:200 级(/admin 302、/frontend 302)
+192.168.16.189:ping 通(7ms),4090 OPEN,其余 HTTP 端口 CLOSED
+192.168.16.251:4096 OPEN(opencode shell)/ 9000 OPEN(langgraph /health {"status":"ok"})/ 3306 TCP OPEN
+```
+
+结论:浏览器自动化由本机单节点承担;langgraph 实派 251(合规);189 仓库仍陈旧(B-122)不可承载。
+
+## 基线
+
+| 项 | 值 |
+|----|----|
+| 分支 | `cfclub` |
+| 起点 HEAD | `75bf2c841`(`chore: auto bump`;`git pull --rebase` 后与 origin 同步) |
+| SRS/场景窗口变更 | **零**(`docs/superpowers/specs`、`tests/user-scenarios`、`API_REFERENCE.md` 全零变更) |
+| 源码变更(R124 之后) | **零**(`git diff 167387161..HEAD -- cfc-backend/src cfc-frontend cfc-web/src cfc-langgraph tests` 为空) |
+
+## 执行清单
+
+| 步骤 | 命令 | 结果 |
+|------|------|------|
+| 后端全量 | **采信 R124**(源码零变更,R124 13:35~14:20 实跑 34:03) | 2865 例 / 2828 过 / 30F+3E+4S / **98.71%** |
+| 浏览器 live | `npx playwright test -c playwright.config.live.js`(workers=1) | **15/15**(admin 5/5 首轮全绿、frontend 6/6、shop 4/4) |
+| 浏览器 health | `npx playwright test -c playwright.config.health.js` | **13/13** |
+| 管理端 | `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 零漂移,9082 未启动) |
+| langgraph@251 | `_r125_dispatch_251.cjs`(kick 分离 + sleep + 单次读) | **43 过 / 0 红 / 756.13s**(8 warnings) |
+| 线上鉴权 | `POST /api/mind/fortune`、`/api/energy/overview` | 均 **401** |
+| 站点可达 | `GET /admin`、`/frontend` | 均 302 |
+
+## 聚合结果(全量口径,与历轮一致)
+
+```
+全量 3501 例 / 3445 过 / 49 红 / 7 跳过 = 98.40%
+后端 2865 例 / 2828 过 = 98.71%(红类 14 / 红例 33)
+```
+
+## 本轮关键变化
+
+### 1. langgraph@251 红例归零(B-74 观察改善,最重要)
+
+| 轮次 | 结果 | 红例 |
+|------|------|------|
+| R123 | 42 过 / 1 红 | `test_auto_tag_content_relevance`(LLM 401) |
+| R124 | 42 过 / 1 红 | `test_auto_tag_valid_format`(LLM 401) |
+| **R125** | **43 过 / 0 红** | —(756.13s,8 warnings,0 failed) |
+
+- 红例名连续两轮漂移后本轮消失;251 已 `git reset --hard origin/cfclub`(`f5a014a46`)对齐远端。
+- **不销号**:需连续 ≥2 轮全绿才按 R123 判据转销号;本轮仅第 1 轮全绿,标注「B-74 观察第 1 轮无复现」。
+- 8 warnings 为 `coroutine ... was never awaited`(test_analyze_missing_report),同 R124 非缺陷信号。
+
+### 2. 后端全量维持(零源码变更采信)
+
+R124 在相同源码基线(`2f04b1033`==`75bf2c841` 均仅 bump,源码零变更)实跑 34:03,2865/2828/98.71%,本轮采信成立。红类 14 与 R124 逐类一致:A 装置 16(CfCommission 8/ArticleAutoTag 4/GrowthRecordSync 3/TaskPlan 1)、B 产品 13、C 数据 1(platform_fee)、契约待裁决 3(DimensionRegistryMap)。
+
+### 3. 浏览器自动化全绿(B-121 销号后维持)
+
+- admin **5/5 首轮全绿**(U04 9.5s / U05 56.7s),连续第 3 轮无重跑偶发。
+- frontend 6/6、shop-api 4/4、health 13/13(华为 5 + 小米 5 + 健康方案 3,全 401)。
+- 合计 **28/28**,与 R118/R120/R123/R124 基线一致。
+
+## 覆盖台账(本轮刷新)
+
+- discovery:控制器 **363** / handler **1969** / 覆盖 **442**(22.5%,covered=31 partial=200 uncovered=131 no-handler=1)/ 测试文件 **345** / @Test **2853**。
+- inventory:跨源合计 **4168**(md 701 + pw 566 + py 48 + java 2853 + 场景 11)。
+- 自动化状态:`docs/tdd/test/automation-status.md` 已重写。
+
+## 节点探活
+
+| 节点 | 端口 | 结论 |
+|------|------|------|
+| 本机 | — | 浏览器 28/28 全量承担(单任务) |
+| `192.168.16.189` | 4090 OPEN | **不可承载(B-122 延续)**:ping 通但仓库陈旧、`tests\e2e-live` 缺失 → 未派发 |
+| `192.168.16.251` | 4096/9000 OPEN | **langgraph 实派成功**(43/43 全绿,756.13s) |
+| `192.168.16.204` | — | 延续失联(B-95) |
+
+## 未实测项(如实标注)
+
+- 后端全量本轮未重跑(采信 R124,源码零变更;避免 34 分钟重复)。
+- 编译验证(指令排除,本轮未触发 mvn compile/test-compile)。
+- JaCoCo 行覆盖率、PIT 变异、性能压测、SAST/DAST/SCA(未接入或 execute 档未授权)。
+- UAT/BDD 全流量(无业务凭据)、多浏览器矩阵、无障碍(仅 Chromium)。
+- 根级 jest 16 红(B-36,9082 未启动 → ECONNREFUSED,非产品回归)。
+
+## 结论
+
+**不通过(有条件)**——G1 98.40% ✅、G3/G4/G5 前端与管理端全绿 ✅、G6 浏览器 28/28 ✅、G8 鉴权契约全 401 ✅;G2 49 红(后端 33 + 根级 16)❌、G7 langgraph 0 红(观察第 1 轮)✅、G9 锚点率 ❌、G11 无 CI ❌。
+
+**结果有变化(langgraph 红例 1→0,B-74 观察改善)→ 提交远程 + 通知研发。**

+ 24 - 34
docs/tdd/test/automation-status.md

@@ -19,12 +19,12 @@
 
 | 来源类型 | 文件数 | 用例/方法数 | 已自动化 | 待自动化 | 未跟踪 | 已执行 | 通过 | 失败 | 阻塞 |
 | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
-| 结构化测试用例(md) | 9 | 682 | 62 | 620 | 387 | 255 | 14 | 0 | 26 |
+| 结构化测试用例(md) | 10 | 701 | 63 | 638 | 406 | 255 | 14 | 0 | 26 |
 | 用户场景(md) | 11 | 0 | 0 | 11 | 11 | 0 | 0 | 0 | 0 |
 | Playwright(e2e/integration) | 96 | 566 | 96 | 0 | 86 | 0 | 7 | 3 | 0 |
 | Python(pytest) | 11 | 48 | 11 | 0 | 11 | 0 | 0 | 0 | 0 |
-| Java后端测试 | 343 | 2834 | 343 | 0 | 326 | 0 | 15 | 2 | 0 |
-| **合计** | — | **4130** | **512** | **631** | 821 | 255 | 36 | 5 | 26 |
+| Java后端测试 | 345 | 2853 | 345 | 0 | 328 | 0 | 15 | 2 | 0 |
+| **合计** | — | **4168** | **515** | **649** | 842 | 255 | 36 | 5 | 26 |
 
 ## 二、结构化测试用例自动化状态(`tests/test-cases/*.md`)
 
@@ -259,6 +259,25 @@
 | `tests/test-cases/guest.md#TC-G-N03` | 非微信H5 | 游客 | P2 | 已关联自动化 | 阻塞 | 设计:H5 兜底|e2e:e2e/api/nonfunc-perf-compat.spec.js |
 | `tests/test-cases/guest.md#TC-G-N04` | 落地页 | 游客 | P0 | 已关联自动化 | 阻塞 | 设计:接口鉴权|e2e:e2e/api/nonfunc-security.spec.js |
 | `tests/test-cases/guest.md#TC-G-N05` | 登录注册 | 游客 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:登录限流|e2e:— |
+| `tests/test-cases/health-datasource-bridge.md#TC-HB-01` | 桥接宿主 | 系统 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:§3.2-1|e2e:HealthDataSourceBridgeContractTest#bridgeHost_classExists |
+| `tests/test-cases/health-datasource-bridge.md#TC-HB-02` | 桥接宿主 | 系统 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:§3.2-1|e2e:#bridgeHost_hasBridgeMethod |
+| `tests/test-cases/health-datasource-bridge.md#TC-HB-03` | 华为同步 | 家长 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:§3.1 全字段|e2e:#bridge_huaweiStep_fieldMappingConformToSpec |
+| `tests/test-cases/health-datasource-bridge.md#TC-HB-04` | 小米同步 | 家长 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:§3.1 + §2.2|e2e:#bridge_xiaomiStep_sameDeviceMapping |
+| `tests/test-cases/health-datasource-bridge.md#TC-HB-05` | 体重双维展开 | 家长 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:§3.1 dimension 切分|e2e:#bridge_bodyWeight_expandTwoDimensions |
+| `tests/test-cases/health-datasource-bridge.md#TC-HB-06` | 未知维度丢弃 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:§3.1「未知码丢弃」|e2e:#bridge_unknownDimensionCodes_dropped |
+| `tests/test-cases/health-datasource-bridge.md#TC-HB-07` | 混合合法非法 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:§3.1|e2e:#bridge_mixedValidAndUnknown_writeOnlyValid |
+| `tests/test-cases/health-datasource-bridge.md#TC-HB-08` | percentile 可空 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:§3.1「percentile 可空」|e2e:#bridge_percentileNull_stillWrites |
+| `tests/test-cases/health-datasource-bridge.md#TC-HB-09` | 同日多源覆盖 | 家长 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:§3.1 读最新覆盖 + §6 ④ 不加唯一索引|e2e:#bridge_sameDayMultipleRows_latestWins |
+| `tests/test-cases/health-datasource-bridge.md#TC-HB-10` | 不覆盖报告行 | 家长 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:§3.1 写入语义|e2e:#bridge_mustNotOverwriteExistingReportRow |
+| `tests/test-cases/health-datasource-bridge.md#TC-HB-11` | 华为同步接线 | 家长 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:§3.2-2|e2e:#huaweiSyncEngine_injectBridgeHook |
+| `tests/test-cases/health-datasource-bridge.md#TC-HB-12` | 小米同步接线 | 家长 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:§3.2-2|e2e:#xiaomiSyncEngine_injectBridgeHook |
+| `tests/test-cases/health-datasource-bridge.md#TC-HB-13` | 死注入解除 | 系统 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:§3.2-1|e2e:#dimensionScoreServiceImpl_deadInjectionResolved |
+| `tests/test-cases/health-datasource-bridge.md#TC-HB-14` | schema 枚举 | 系统 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:§4-1 + §6 ①|e2e:#schema_dimensionScores_dataSourceCommentContainsDevice |
+| `tests/test-cases/health-datasource-bridge.md#TC-HB-15` | 不加唯一索引 | 系统 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:§4-2 + §6 ④|e2e:#schema_dimensionScores_noUniqueIndex |
+| `tests/test-cases/health-datasource-bridge.md#TC-HB-16` | 鉴权归口 | 系统 | P1 | 已关联自动化 | 未跟踪 | 设计:§3.4|e2e:#permissionFlow_notApplicable` + `e2e-live/health-contract.spec.js |
+| `tests/test-cases/health-datasource-bridge.md#TC-HB-03-E` | 映射码全非法 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:§3.1|e2e:#bridge_unknownDimensionCodes_dropped |
+| `tests/test-cases/health-datasource-bridge.md#TC-HB-08-E` | 归一化缺失 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:§3.1|e2e:未覆盖(缺口 G-115-1) |
+| `tests/test-cases/health-datasource-bridge.md#TC-HB-09-E` | 并发同秒写入 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:§3.1|e2e:未覆盖(缺口 G-115-1) |
 | `tests/test-cases/parent.md#TC-P-01` | 家庭 | 家长 | P0 | 已关联自动化 | 已执行 | 设计:FamilyInviteController|e2e:e2e/roles/parent/family-management.spec.js |
 | `tests/test-cases/parent.md#TC-P-02` | 家庭/成员 | 家长 | P1 | 文档用例(待自动化) | 已执行 | 设计:FamilyInviteController|e2e:— |
 | `tests/test-cases/parent.md#TC-P-02-B` | 家庭加入准入校验 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:FamilyJoinRequestService/FamilyInviteController(S-cfc-57/58/59,5bef71317)|e2e:FamilyJoinValidationRulesContractTest`/`FamilyJoinRequestServiceJoinRequiredInfoContractTest`/`FamilyJoinRequestServiceJoinValidationGateTest |
@@ -855,6 +874,7 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthCheckinCfEarnCallSiteTest.java` | 6 | 已自动化(@Test) | 未跟踪 | HealthCheckinCfEarnCallSite |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthDimensionControllerUploadContractTest.java` | 21 | 已自动化(@Test) | 未跟踪 | HealthDimensionControllerUploadContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthPlanDeleteControllerTest.java` | 6 | 已自动化(@Test) | 未跟踪 | HealthPlanDeleteController |
+| `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthPlanProductSelectionContractTest.java` | 14 | 已自动化(@Test) | 未跟踪 | HealthPlanProductSelectionContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerCreateReportTest.java` | 5 | 已自动化(@Test) | 未跟踪 | HealthReportControllerCreateReport |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerListPaginationTest.java` | 4 | 已自动化(@Test) | 未跟踪 | HealthReportControllerListPagination |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerProxyParseBindingTest.java` | 6 | 已自动化(@Test) | 未跟踪 | HealthReportControllerProxyParseBinding |
@@ -1013,6 +1033,7 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/service/MembershipServiceTest.java` | 17 | 已自动化(@Test) | 未跟踪 | MembershipService |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/NormalizeIndicatorPipelineTest.java` | 3 | 已自动化(@Test) | 未跟踪 | NormalizeIndicatorPipeline |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/NumSoulCalculatorTest.java` | 5 | 已自动化(@Test) | 未跟踪 | NumSoulCalculator |
+| `cfc-backend/src/test/java/com/etotem/cfc/service/OrderWebhookNotifyTest.java` | 5 | 已自动化(@Test) | 未跟踪 | OrderWebhookNotify |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/PaymentServiceORDRoutingTest.java` | 3 | 已自动化(@Test) | 未跟踪 | PaymentServiceORDRouting |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/PlatformPointsServiceTest.java` | 9 | 已自动化(@Test) | 未跟踪 | PlatformPointsService |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/PointsExchangeServiceTest.java` | 4 | 已自动化(@Test) | 未跟踪 | PointsExchangeService |
@@ -1202,34 +1223,3 @@
 2. **发布共享(推送给测试团队)**:运行本脚本(默认即生成此文件),把 `docs/tdd/` 下文档提交推送。
    - 命令:`python test_inventory.py --automation-status`(或直接 `python test_inventory.py`)。
 3. **原始用例零侵入**:`.md/.spec.js/.py/.java` 一律不改;`.tdd/` 已在 `.gitignore` 排除。
-
-## 附录 A · 预期 RED 登记(第 112 轮)
-
-> 依据研发 `faebb1964` 交接:「S-cfc-129 RED 测试 `6da900595` 已产出,请测试侧 `--mark-red` 登记」。
-> 下表 14 例在 `HealthDataSourceBridgeContractTest` 中以 `RED[health.dataSource.bridgeWrite]` 前缀声明失败原因,
-> **属契约先行(TDD RED),不计入产品回归**;实现落地转绿后应移除本登记。
-
-| 契约用例(`cfc-backend/src/test/java/com/etotem/cfc/unit/HealthDataSourceBridgeContractTest.java`) | 契约条款 | 期望 |
-|------|----------|------|
-| `bridgeHost_classExists` | §3.1 桥接宿主 | 转绿 |
-| `bridgeHost_hasBridgeMethod` | §3.1 bridge 入口 | 转绿 |
-| `bridge_huaweiStep_fieldMappingConformToSpec` | §3.1 字段映射 | 转绿 |
-| `bridge_xiaomiStep_sameDeviceMapping` | §3.1 字段映射 | 转绿 |
-| `bridge_bodyWeight_expandTwoDimensions` | §3.1 体重→2 维 | 转绿 |
-| `bridge_sameDayMultipleRows_latestWins` | §3.1 同日 latest-wins | 转绿 |
-| `bridge_unknownDimensionCodes_dropped` | §3.1 未知维度码丢弃 | 转绿 |
-| `bridge_mixedValidAndUnknown_writeOnlyValid` | §3.1 混合写入 | 转绿 |
-| `bridge_percentileNull_stillWrites` | §3.1 空百分位仍写 | 转绿 |
-| `bridge_mustNotOverwriteExistingReportRow` | §3.1 不覆盖报告行 | 转绿 |
-| `huaweiSyncEngine_injectBridgeHook` | §3.2-2 触发点 A(华为) | 转绿 |
-| `xiaomiSyncEngine_injectBridgeHook` | §3.2-2 触发点 A(小米) | 转绿 |
-| `dimensionScoreServiceImpl_deadInjectionResolved` | §3.2-1 死注入解除 | 转绿 |
-| `schema_dimensionScores_dataSourceCommentContainsDevice` | §6 ① DEVICE 取值 | 转绿 |
-
-**附带缺口(B-112)**:~~`docs/superpowers/specs` 未见 `bridgeWrite` 规格文件~~ → **第 115 轮勘误**:规格文件 `docs/superpowers/specs/2026-11-08-dx-health-bridge.md` 一直存在(含 §3.1 字段映射全表 / §3.2 接线 / §4 SQL 契约 / §6 四项拍板),R112 的 grep 未命中 `bridgeWrite` 字面导致误判。
-
-### 附录 A-1 · 本登记已解除(第 115 轮)
-
-> `47d203981`(2026-11-10 02:42)合入 S-cfc-130 实现后,上表 14 例 + 另 2 例(`schema_dimensionScores_noUniqueIndex`、`permissionFlow_notApplicable`)经**全量 clean 实跑**确认:`HealthDataSourceBridgeContractTest` **16 tests / 0 failures / 0 errors / 0 skipped,全绿**。
-> 契约级用例文档已补:`tests/test-cases/health-datasource-bridge.md`(TC-HB-01~16 + 3 条异常流 + 缺口 G-115-1~3)。
-> 本附录 A 自本轮起**仅作历史留痕**,不再作为「预期 RED」计入红例池。

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

@@ -390,3 +390,9 @@
 | 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) |
+| B-74-Update(第 125 轮 · 首次全绿观察) | langgraph `test_auto_tag.py` 红例 | 研发/运维 | **重大改善(第 125 轮)**:251 实派 43 例 **43 过 / 0 红 / 756.13s**(8 warnings),自连续 22 轮红例(R103~R124,LLM 401)后**首次全量全绿**。红例名漂移(content_relevance/valid_format)本轮消失。**不销号**:按判据需连续 ≥2 轮全绿,本轮仅第 1 轮,转「B-74 观察第 1 轮无复现」;待下轮(R126)复跑确认后销号。运维仍建议注入有效 LLM 凭据 + 251 装 `pytest-timeout` 防挂起(B-125) | 测试负责人(第 125 轮 251 实派) | 2026-11-10 14:55 | 观察(P1,待连续 2 轮全绿销号) |
+| B-36-Update(第 125 轮 · 第 28 轮零漂移) | 根级黑盒 23 例 16 红 | 测试 | **零漂移**。本轮实跑 23 例:7 绿 / 16 红(`ECONNREFUSED`,9082 未启动,非产品回归) | 测试负责人(第 125 轮实测) | 2026-11-10 14:55 | 待处理(P1) |
+| B-121-Confirm(第 125 轮 · 销号后第 1 轮) | 本机 `admin-desktop` TC-A-U05 偶发 | 研发/测试 | **维持绿**。本轮 `TC-A-U05` 56.7s 通过(R124 销号后第 1 轮,首轮即绿无重跑),B-121 销号结论成立 | 测试负责人(第 125 轮实跑) | 2026-11-10 14:55 | **已闭环(销号)** |
+| B-122-Update(第 125 轮 · 延续第 3 轮) | `192.168.16.189` 通道可用但不具备浏览器执行前提 | 运维 | **延续(P2 第 3 轮)**。复测:ping 7ms、4090 OPEN(opencode),但仓库仍 `feature/user-is-child @ e3e52ca38`、`tests\e2e-live` 缺失、`node_modules` 缺失 → 不可承载。闭环判据不变:189 worktree 更新至 `cfclub` 且预置 `tests/node_modules` | 测试负责人(第 125 轮复测) | 2026-11-10 14:55 | 待处理(P2,运维) |
+| B-123-Update(第 125 轮 · 第 3 轮通过) | R122 以「本机无 Maven」降级致后端整模块漏测 | 测试 | **第 3 轮通过**(采信 R124 全量 2865/98.71%,源码零变更;本轮探针确认 9082 DOWN 但 Maven 可用)。闭环判据:连续 3 轮报告含探针且无 Maven 降级 → 本轮达成,**转销号** | 测试负责人(第 125 轮核验) | 2026-11-10 14:55 | **已闭环(销号)** |
+| B-125-Update(第 125 轮 · 第 3 轮) | 远程 shell 等待时长未自适应 | 测试 | **观察(P1 第 3 轮)**。本轮沿用「kick + sleep + 单次读」:首读 sleep 620s 仍只读到 35 点(pytest 756.13s 未写完,缓冲未 flush);探活确认 pytest 存活后重读 → 完整 summary 43/43。印证「等待须以 pytest 进程退出为判据」。改进:探测到进程退出再读;或给 251 装 `pytest-timeout` | 测试负责人(第 125 轮定位) | 2026-11-10 14:55 | 待处理(P1,工具) |

+ 49 - 20
docs/tdd/test/discovery.md

@@ -7,22 +7,22 @@
 
 | 指标 | 数值 |
 | --- | --- |
-| 控制器总数 | 361 |
-| handler 方法总数 | 1956 |
-| handler 方法已覆盖 | 440 (22.5%) |
-| 单元-全覆盖(handler 方法) | 32 |
-| 单元-部分覆盖(handler 方法) | 199 |
-| 单元-未覆盖(handler 方法) | 129 |
+| 控制器总数 | 363 |
+| handler 方法总数 | 1969 |
+| handler 方法已覆盖 | 442 (22.4%) |
+| 单元-全覆盖(handler 方法) | 31 |
+| 单元-部分覆盖(handler 方法) | 200 |
+| 单元-未覆盖(handler 方法) | 131 |
 | 单元-无handler 方法 | 1 |
-| 测试文件数 | 317 |
-| @Test 方法总数 | 2617 |
+| 测试文件数 | 345 |
+| @Test 方法总数 | 2853 |
 | 含跳过/假设项(test 级 partial) | 4 |
 
 ## 二、未覆盖控制器(发现「缺口」· 非发明)
 
 > 以下控制器在当前测试源中**没有任何handler 方法被命中**。这是真实扫描得到的覆盖缺口。
 
-共 129 个:
+共 131 个:
 
 - `DanAssessmentController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/DanAssessmentController.java`,29 方法)
 - `AdminInventoryController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminInventoryController.java`,15 方法)
@@ -41,6 +41,7 @@
 - `PurchaseController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/PurchaseController.java`,8 方法)
 - `SysMenuController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/SysMenuController.java`,8 方法)
 - `TaskReminderController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/task/TaskReminderController.java`,8 方法)
+- `TeamProfitAdminController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/TeamProfitAdminController.java`,8 方法)
 - `AdminDistributionController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminDistributionController.java`,7 方法)
 - `AssessmentAdminController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AssessmentAdminController.java`,7 方法)
 - `BeijingNutritionController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/nutrition/BeijingNutritionController.java`,7 方法)
@@ -83,21 +84,21 @@
 - `InnatePortraitController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/mind/InnatePortraitController.java`,4 方法)
 - `PackagePurchaseController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/guide/PackagePurchaseController.java`,4 方法)
 - `PlanReviewController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/guide/PlanReviewController.java`,4 方法)
-- `PortraitController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/user/PortraitController.java`,4 方法)
-- …(其余 69 个见完整扫描)
+- …(其余 71 个见完整扫描)
 
 ## 三、部分覆盖控制器(已做一部分测试)
 
 > 这些控制器**已有测试但只覆盖了部分handler 方法**——即用户要求的「已经做了一部分测试的情况,要能够找到」。
 
-共 199 个:
+共 200 个:
 
 - `AdminController`:覆盖 1/65,未覆盖方法:getUsers、createUser、getUser、updateUser、resetUserPassword、searchUsers、deleteUser、getChild、updateChild、adjustPoints
 - `HealthReportController`:覆盖 1/59,未覆盖方法:createReport、getLatestReport、listFamilyReports、listAllReports、getReportIndicatorsWithPrevious、listIndicators、getMemberIndicators、getGutFlora、rebuildIndicatorCurrent、getMemberIndicatorCurrent
-- `HealthKnowledgeBaseController`:覆盖 2/28,未覆盖方法:batchQuery、add、update、delete、importKnowledgeBase、queryBacteria、batchQueryBacteria、queryIndicator、queryFood、getSection
+- `HealthKnowledgeBaseController`:覆盖 2/29,未覆盖方法:batchQuery、add、update、delete、importKnowledgeBase、queryBacteria、batchQueryBacteria、queryIndicator、queryFood、getSection
 - `AdminArticleController`:覆盖 2/22,未覆盖方法:create、update、detail、delete、publishById、backfillTags、toggleFeatured、move、audit、submitReview
 - `ProductOrderController`:覆盖 7/19,未覆盖方法:myOrderCounts、vendorConfirm、reviewUpdate、ship、applyRefund、handlePaymentSuccess、notify、activityAudit、activitySignIn、activityComplete
 - `AuthController`:覆盖 14/18,未覆盖方法:setSwitchPassword、verifyToken、ssoTicket、ssoLogin
+- `HealthPlanController`:覆盖 17/18,未覆盖方法:SuppressWarnings
 - `TaskController`:覆盖 7/18,未覆盖方法:getMinigameOptions、getTodayTasks、completeTask、startTask、getTodayParentTasks、completeParentTask、deleteTask、completeMinigameTask、batchComplete、batchDelete
 - `FamilyUserController`:覆盖 3/17,未覆盖方法:getUserInfo、updateUserInfo、joinFamily、createFamily、switchMode、switchToFamilyMember、switchBackToParent、switchBackVerify、getFamilyMemberren、updateFamilyMember
 - `GuideManagementController`:覆盖 3/17,未覆盖方法:resubmitApplication、getUserApplications、getApplicationRecords、generateInviteCode、getInviteCodes、validateInviteCode、getChildGuides、getAllChildGuides、getParentGuide、getGuidePackageTemplates
@@ -303,7 +304,7 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/WishControllerTest.java` | com | 29 | 4 | 11 | WishController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/AssessmentQuotaAppointmentContractTest.java` | com | 27 | 9 | 0 | AssessmentQuotaController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/CfBalanceServiceTest.java` | com | 25 | 0 | 0 | CfBalanceController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/unit/TeamStarMyViewContractTest.java` | com | 24 | 0 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/TeamStarMyViewContractTest.java` | com | 24 | 0 | 0 | TeamStarController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/IndicatorChangeServiceTest.java` | com | 23 | 0 | 0 | IndicatorController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeamProfitCronContractTest.java` | com | 22 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/DimensionScoreServiceTest.java` | com | 21 | 0 | 0 | — | — |
@@ -314,7 +315,7 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/GuideFamilyTaskControllerTest.java` | com | 20 | 11 | 8 | GuideFamilyTaskController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/IndicatorChangeServiceSemanticTest.java` | com | 20 | 0 | 0 | IndicatorController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ProductOrderControllerTest.java` | com | 20 | 3 | 7 | ProductOrderController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/unit/TeamProfitAdminManageContractTest.java` | com | 20 | 0 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/TeamProfitAdminManageContractTest.java` | com | 20 | 0 | 0 | TeamProfitAdminController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/PlanReviewTeacherContractTest.java` | com | 19 | 4 | 4 | PlanReviewController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/config/ScG06JwtGuardTest.java` | com | 19 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/ai/AIChatControllerGateTest.java` | com | 18 | 15 | 6 | AIChatController | — |
@@ -327,6 +328,7 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/task/TaskControllerReviewTest.java` | com | 17 | 1 | 4 | TaskController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ActivityControllerTest.java` | com | 16 | 9 | 6 | ActivityController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/CfGrowthPathwayEarnServiceTest.java` | com | 16 | 6 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/HealthDataSourceBridgeContractTest.java` | com | 16 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerUploadTest.java` | com | 16 | 0 | 0 | HealthReportController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ProductControllerTest.java` | com | 16 | 8 | 6 | ProductController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/ActivityOrderServiceTest.java` | com | 15 | 0 | 0 | ActivityController | — |
@@ -338,18 +340,20 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/ArticleWorkflowTest.java` | com | 14 | 0 | 0 | ArticleController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/CoachButlerNotificationContractTest.java` | com | 14 | 7 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/FamilyJoinValidationRulesContractTest.java` | com | 14 | 0 | 0 | FamilyController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthPlanProductSelectionContractTest.java` | com | 14 | 25 | 3 | HealthPlanController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/NutritionDeficiencyServiceTest.java` | com | 14 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/OrderCreatePayShipConfirmScX07ContractTest.java` | com | 14 | 2 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/PlanActivationExecutionContractTest.java` | com | 14 | 2 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TaskCreateScP10ContractTest.java` | com | 14 | 0 | 0 | TaskController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/unit/TeamStarDigestContractTest.java` | com | 14 | 0 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/TeamStarDigestContractTest.java` | com | 14 | 0 | 0 | TeamStarController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/DimensionAdminControllerTest.java` | com | 13 | 0 | 7 | DimensionAdminController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/FamilyUserSwitchRoleTest.java` | com | 13 | 1 | 1 | FamilyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/GuidePackageServiceTest.java` | com | 13 | 0 | 0 | GuideController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ManualDimensionScoreContractTest.java` | com | 13 | 6 | 2 | ManualDimensionScoreController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/PersonalLayerDualAssertionTest.java` | com | 13 | 4 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/ScG03LoginMethodContractTest.java` | com | 13 | 1 | 4 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TaskTemplatePackageContractTest.java` | com | 13 | 4 | 11 | TaskTemplatePackageController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/unit/TeamStarMultiplierContractTest.java` | com | 13 | 0 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/TeamStarMultiplierContractTest.java` | com | 13 | 0 | 0 | TeamStarController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ActivityTeamServiceUnitTest.java` | com | 12 | 0 | 0 | ActivityController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/AfterSalesScS06ContractTest.java` | com | 12 | 0 | 0 | AfterSalesController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/CfCommissionServiceSettleTest.java` | com | 12 | 2 | 0 | CfCommissionController | — |
@@ -357,12 +361,15 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/service/FamilyJoinRequestServiceJoinValidationGateTest.java` | com | 12 | 0 | 0 | FamilyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/FiveDimensionScoreServiceTest.java` | com | 12 | 10 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FoodServiceTest.java` | com | 12 | 0 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/GuheEvidenceIsolateContractTest.java` | com | 12 | 0 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/GuheGateLowSideRedlineContractTest.java` | com | 12 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthSleepControllerContractTest.java` | com | 12 | 1 | 2 | HealthSleepController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/IndicatorTimelineServiceTest.java` | com | 12 | 24 | 0 | IndicatorController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/MembershipServiceAiGateTest.java` | com | 12 | 0 | 0 | MembershipController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/PaymentControllerTest.java` | com | 12 | 17 | 5 | PaymentController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/AdminAuthWechatScanTest.java` | com | 11 | 11 | 2 | AdminAuthController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ArticleControllerTest.java` | com | 11 | 7 | 4 | ArticleController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/AttributionComplianceGateTest.java` | com | 11 | 0 | 0 | AttributionController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/CfReferralServiceSalesTierTest.java` | com | 11 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/CfSpendDispatchServiceTest.java` | com | 11 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/CouponUseScP57ScP75ContractTest.java` | com | 11 | 0 | 0 | CouponController | — |
@@ -371,6 +378,7 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/DataMigrationServiceTest.java` | com | 11 | 5 | 0 | DataMigrationController | skip×1、⚠部分 |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/EnergyLogsContractScoreHistoryTest.java` | com | 11 | 3 | 3 | EnergyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/config/FamilyAccessInterceptorTest.java` | com | 11 | 0 | 0 | FamilyController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/GuheKbVersionSenseContractTest.java` | com | 11 | 2 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/GuideConfigServiceTest.java` | com | 11 | 13 | 0 | GuideConfigController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/OrderRefundScP56ScA12ContractTest.java` | com | 11 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/PdfParseServiceTest.java` | com | 11 | 0 | 0 | — | — |
@@ -384,8 +392,13 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/AdminAuthControllerLoginStatusTest.java` | com | 10 | 1 | 3 | AdminAuthController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/AuthWechatLoginContractTest.java` | com | 10 | 0 | 1 | AuthController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ComboServiceTest.java` | com | 10 | 3 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/ConditionalPathogenLowSideRuleTest.java` | com | 10 | 0 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/DietFoodHealthAdjustContractTest.java` | com | 10 | 2 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/FamilyJoinRequestServiceJoinRequiredInfoContractTest.java` | com | 10 | 0 | 0 | FamilyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/GrowthRecordSyncFlowTest.java` | com | 10 | 9 | 4 | GrowthController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/GuheLowSideRuleLoadContractTest.java` | com | 10 | 0 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/GuheNoPathMapContractTest.java` | com | 10 | 6 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/GuideFamilyAccessGuardTest.java` | com | 10 | 0 | 0 | GuideController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/GuideHierarchyServiceTest.java` | com | 10 | 0 | 0 | GuideController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/HealthPlanReviewGuardTest.java` | com | 10 | 0 | 0 | HealthPlanController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/IndicatorFavoriteControllerTest.java` | com | 10 | 8 | 3 | IndicatorFavoriteController | — |
@@ -401,7 +414,7 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/EnergyGrantContractTest.java` | com | 9 | 4 | 1 | EnergyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FamilyFoodOverviewServiceTest.java` | com | 9 | 9 | 0 | FamilyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/growth/GrowthHistoryViewContractTest.java` | com | 9 | 3 | 0 | GrowthController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/unit/GuideFamilyAccessGuardTest.java` | com | 9 | 0 | 0 | GuideController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/GuheReportPersonalAssertContractTest.java` | com | 9 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/GuideTeamControllerTest.java` | com | 9 | 6 | 5 | GuideTeamController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/IndicatorTrendServiceTest.java` | com | 9 | 17 | 0 | IndicatorController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/KnowledgeBaseBackfillTest.java` | com | 9 | 6 | 0 | KnowledgeBaseController | — |
@@ -417,6 +430,7 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ActivityRegistrationQuotaUnitTest.java` | com | 8 | 3 | 0 | ActivityController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/AdminSpecialPriceControllerTest.java` | com | 8 | 12 | 4 | AdminSpecialPriceController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ArticleAutoTagServiceTest.java` | com | 8 | 0 | 0 | ArticleController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/service/ArticleServiceAudioInvalidationTest.java` | com | 8 | 0 | 0 | ArticleController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/AttributionRedlinesTest.java` | com | 8 | 0 | 0 | AttributionController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/CfBalanceControllerTest.java` | com | 8 | 7 | 3 | CfBalanceController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/CfEarnDispatchServiceTest.java` | com | 8 | 0 | 0 | — | — |
@@ -426,6 +440,8 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/FamilyControllerTest.java` | com | 8 | 1 | 3 | FamilyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/FamilyEarningsAdminRoleGateTest.java` | com | 8 | 3 | 3 | FamilyEarningsController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/FamilyMemberRelationshipLabelTest.java` | com | 8 | 0 | 0 | FamilyController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/GuheKbQueryLowSidePatchContractTest.java` | com | 8 | 0 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/GuheV2RouteContractTest.java` | com | 8 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/GuideApplicationServiceTest.java` | com | 8 | 0 | 0 | GuideController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/GuideOrderControllerTest.java` | com | 8 | 11 | 3 | GuideOrderController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/HealthReportAuditContractTest.java` | com | 8 | 3 | 0 | HealthReportController | — |
@@ -447,10 +463,12 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/family/FamilyInviteApproveRequestTest.java` | com | 7 | 0 | 0 | FamilyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/FamilyMemberDimensionBaseScoreServiceTest.java` | com | 7 | 10 | 0 | FamilyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/family/FamilyMembersControllerAddMemberTest.java` | com | 7 | 1 | 1 | FamilyController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/GuheShellGuardContractTest.java` | com | 7 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/GuideFamilyServiceTest.java` | com | 7 | 0 | 0 | GuideController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/LegacyDimensionCallLogServiceTest.java` | com | 7 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/orchestration/OrchestrationIntegrationTest.java` | com | 7 | 0 | 0 | OrchestrationController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ProductDetailScP53ContractTest.java` | com | 7 | 0 | 0 | ProductController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/RolesUtilTest.java` | com | 7 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/ScG01LandingContractTest.java` | com | 7 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/ScG10RegisterGuideContractTest.java` | com | 7 | 0 | 2 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/SupplyTeamControllerInviteTest.java` | com | 7 | 7 | 0 | SupplyTeamController | — |
@@ -465,9 +483,16 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/AssessmentComparisonContractTest.java` | com | 6 | 0 | 0 | AssessmentComparisonController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/BadgeServiceUnlockNoticeTest.java` | com | 6 | 1 | 0 | BadgeController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/CfTransferServiceTest.java` | com | 6 | 0 | 0 | CfTransferController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/integration/DailyCheckinStreakFlowTest.java` | com | 6 | 13 | 6 | DailyCheckinController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/integration/DailyCheckinStreakFlowTest.java` | com | 6 | 14 | 6 | DailyCheckinController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/config/DatabaseInitializerSeedTest.java` | com | 6 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/impl/DimensionScoreServiceImplTest.java` | com | 6 | 0 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/FamilyRelationshipServiceLabelTest.java` | com | 6 | 0 | 0 | FamilyController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/service/FoodRecommendMemberViewResolutionTest.java` | com | 6 | 8 | 0 | FoodRecommendController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/GuheGateStrainBlockContractTest.java` | com | 6 | 0 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/GuheKbFieldExposeContractTest.java` | com | 6 | 8 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/GuheLowSideAggregateContractTest.java` | com | 6 | 0 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/GuheLowSideNoSupplementContractTest.java` | com | 6 | 0 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/GuhePageTailCleanContractTest.java` | com | 6 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/GuidePackageTemplateServiceTest.java` | com | 6 | 0 | 0 | GuideController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/GuidePlanReviewControllerAuthTest.java` | com | 6 | 1 | 4 | GuideController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthCheckinCfEarnCallSiteTest.java` | com | 6 | 0 | 2 | HealthCheckinController | — |
@@ -509,12 +534,14 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/FamilyNamingSupportTest.java` | com | 5 | 0 | 0 | FamilyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/FamilyPlatformPointsServiceCouponTest.java` | com | 5 | 0 | 0 | FamilyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/GlobalSearchScP82ContractTest.java` | com | 5 | 12 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/GuheVersionSplitContractTest.java` | com | 5 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/HealthPlanLazyBackfillTest.java` | com | 5 | 0 | 0 | HealthPlanController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerCreateReportTest.java` | com | 5 | 2 | 0 | HealthReportController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/HealthReportServiceBackfillResilienceTest.java` | com | 5 | 7 | 0 | HealthReportController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/config/JwtInterceptorLoginRequiredTest.java` | com | 5 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/MiniGameServiceTest.java` | com | 5 | 0 | 0 | MiniGameController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/NumSoulCalculatorTest.java` | com | 5 | 0 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/service/OrderWebhookNotifyTest.java` | com | 5 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ProductUpdateClearTest.java` | com | 5 | 0 | 0 | ProductController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/RelationshipQuestionnaireServiceTest.java` | com | 5 | 0 | 0 | RelationshipQuestionnaireController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ReportParserAdminContractTest.java` | com | 5 | 6 | 2 | ReportParserController | — |
@@ -550,11 +577,13 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/TeacherLoginTest.java` | com | 4 | 0 | 0 | TeacherController | skip×1、⚠部分 |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeamUserPortalContractTest.java` | com | 4 | 1 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/TencentTtsServiceAuthorizationTest.java` | com | 4 | 0 | 0 | — | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/UnifiedKnowledgeBaseLowSidePatchTest.java` | com | 4 | 3 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/WishServiceTest.java` | com | 4 | 0 | 0 | WishController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/dto/ActivityDTOTest.java` | com | 3 | 0 | 0 | ActivityController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ActivityRegistrationListTest.java` | com | 3 | 5 | 0 | ActivityController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ActivityRegistrationRejectTest.java` | com | 3 | 0 | 0 | ActivityController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/AdminFamilyOverviewControllerTest.java` | com | 3 | 0 | 2 | AdminFamilyOverviewController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/service/ArticleAudioServiceAutoGenTest.java` | com | 3 | 0 | 0 | ArticleController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/ArticleAudioServiceChunkFilterTest.java` | com | 3 | 0 | 0 | ArticleController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ArticleCategoryControllerTest.java` | com | 3 | 0 | 1 | ArticleCategoryController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/AttributionSurveyRoutingTest.java` | com | 3 | 5 | 1 | AttributionController | — |
@@ -581,7 +610,7 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TaskProgressUpdateTest.java` | com | 3 | 0 | 0 | TaskController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/AdminCommissionConfigPartialUpdateTest.java` | com | 2 | 0 | 1 | AdminCommissionConfigController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ArticleBackfillTest.java` | com | 2 | 0 | 0 | ArticleController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/unit/AttributionPipelineMockTest.java` | com | 2 | 36 | 0 | AttributionController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/AttributionPipelineMockTest.java` | com | 2 | 38 | 0 | AttributionController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/AttributionPlanServiceTest.java` | com | 2 | 8 | 0 | AttributionController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/CfCommissionServiceTest.java` | com | 2 | 0 | 0 | CfCommissionController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/ConsigneeServiceBackfillTest.java` | com | 2 | 0 | 0 | ConsigneeController | — |

+ 24 - 3
docs/tdd/test/inventory.md

@@ -8,12 +8,12 @@
 
 | 来源类型 | 文件数 | 用例/方法数 |
 | --- | --- | --- |
-| 结构化测试用例(md) | 9 | 682 |
+| 结构化测试用例(md) | 10 | 701 |
 | Playwright(spec.js) | 96 | 566 |
 | Python(pytest) | 11 | 48 |
-| Java后端(测试文件) | 343 | 2834 (@Test) |
+| Java后端(测试文件) | 345 | 2853 (@Test) |
 | 用户场景(md) | 11 | 文件级 |
-| **合计** | — | **4130** 用例/方法 |
+| **合计** | — | **4168** 用例/方法 |
 
 ## 二、结构化测试用例(`tests/test-cases/*.md`)
 
@@ -250,6 +250,25 @@
 | `TC-G-N03` | 非微信H5 | 游客 | P2 | 兼容 | `tests/test-cases/guest.md#TC-G-N03` | e2e/api/nonfunc-perf-compat.spec.js | H5 兜底 |
 | `TC-G-N04` | 落地页 | 游客 | P0 | 安全 | `tests/test-cases/guest.md#TC-G-N04` | e2e/api/nonfunc-security.spec.js | 接口鉴权 |
 | `TC-G-N05` | 登录注册 | 游客 | P0 | 安全 | `tests/test-cases/guest.md#TC-G-N05` | — | 登录限流 |
+| `TC-HB-01` | 桥接宿主 | 系统 | P0 | 契约 | `tests/test-cases/health-datasource-bridge.md#TC-HB-01` | HealthDataSourceBridgeContractTest#bridgeHost_classExists | §3.2-1 |
+| `TC-HB-02` | 桥接宿主 | 系统 | P0 | 契约 | `tests/test-cases/health-datasource-bridge.md#TC-HB-02` | #bridgeHost_hasBridgeMethod | §3.2-1 |
+| `TC-HB-03` | 华为同步 | 家长 | P0 | 功能 | `tests/test-cases/health-datasource-bridge.md#TC-HB-03` | #bridge_huaweiStep_fieldMappingConformToSpec | §3.1 全字段 |
+| `TC-HB-04` | 小米同步 | 家长 | P0 | 功能 | `tests/test-cases/health-datasource-bridge.md#TC-HB-04` | #bridge_xiaomiStep_sameDeviceMapping | §3.1 + §2.2 |
+| `TC-HB-05` | 体重双维展开 | 家长 | P0 | 功能 | `tests/test-cases/health-datasource-bridge.md#TC-HB-05` | #bridge_bodyWeight_expandTwoDimensions | §3.1 dimension 切分 |
+| `TC-HB-06` | 未知维度丢弃 | 家长 | P1 | 异常 | `tests/test-cases/health-datasource-bridge.md#TC-HB-06` | #bridge_unknownDimensionCodes_dropped | §3.1「未知码丢弃」 |
+| `TC-HB-07` | 混合合法非法 | 家长 | P1 | 异常 | `tests/test-cases/health-datasource-bridge.md#TC-HB-07` | #bridge_mixedValidAndUnknown_writeOnlyValid | §3.1 |
+| `TC-HB-08` | percentile 可空 | 家长 | P1 | 边界 | `tests/test-cases/health-datasource-bridge.md#TC-HB-08` | #bridge_percentileNull_stillWrites | §3.1「percentile 可空」 |
+| `TC-HB-09` | 同日多源覆盖 | 家长 | P0 | 功能 | `tests/test-cases/health-datasource-bridge.md#TC-HB-09` | #bridge_sameDayMultipleRows_latestWins | §3.1 读最新覆盖 + §6 ④ 不加唯一索引 |
+| `TC-HB-10` | 不覆盖报告行 | 家长 | P0 | 回归 | `tests/test-cases/health-datasource-bridge.md#TC-HB-10` | #bridge_mustNotOverwriteExistingReportRow | §3.1 写入语义 |
+| `TC-HB-11` | 华为同步接线 | 家长 | P0 | 集成 | `tests/test-cases/health-datasource-bridge.md#TC-HB-11` | #huaweiSyncEngine_injectBridgeHook | §3.2-2 |
+| `TC-HB-12` | 小米同步接线 | 家长 | P0 | 集成 | `tests/test-cases/health-datasource-bridge.md#TC-HB-12` | #xiaomiSyncEngine_injectBridgeHook | §3.2-2 |
+| `TC-HB-13` | 死注入解除 | 系统 | P1 | 契约 | `tests/test-cases/health-datasource-bridge.md#TC-HB-13` | #dimensionScoreServiceImpl_deadInjectionResolved | §3.2-1 |
+| `TC-HB-14` | schema 枚举 | 系统 | P0 | 契约 | `tests/test-cases/health-datasource-bridge.md#TC-HB-14` | #schema_dimensionScores_dataSourceCommentContainsDevice | §4-1 + §6 ① |
+| `TC-HB-15` | 不加唯一索引 | 系统 | P0 | 契约 | `tests/test-cases/health-datasource-bridge.md#TC-HB-15` | #schema_dimensionScores_noUniqueIndex | §4-2 + §6 ④ |
+| `TC-HB-16` | 鉴权归口 | 系统 | P1 | 权限 | `tests/test-cases/health-datasource-bridge.md#TC-HB-16` | #permissionFlow_notApplicable` + `e2e-live/health-contract.spec.js | §3.4 |
+| `TC-HB-03-E` | 映射码全非法 | 家长 | P2 | 异常 | `tests/test-cases/health-datasource-bridge.md#TC-HB-03-E` | #bridge_unknownDimensionCodes_dropped | §3.1 |
+| `TC-HB-08-E` | 归一化缺失 | 家长 | P2 | 异常 | `tests/test-cases/health-datasource-bridge.md#TC-HB-08-E` | 未覆盖(缺口 G-115-1) | §3.1 |
+| `TC-HB-09-E` | 并发同秒写入 | 家长 | P2 | 并发 | `tests/test-cases/health-datasource-bridge.md#TC-HB-09-E` | 未覆盖(缺口 G-115-1) | §3.1 |
 | `TC-P-01` | 家庭 | 家长 | P0 | 功能 | `tests/test-cases/parent.md#TC-P-01` | e2e/roles/parent/family-management.spec.js | FamilyInviteController |
 | `TC-P-02` | 家庭/成员 | 家长 | P1 | 功能 | `tests/test-cases/parent.md#TC-P-02` | — | FamilyInviteController |
 | `TC-P-02-B` | 家庭加入准入校验 | 家长 | P1 | 功能 | `tests/test-cases/parent.md#TC-P-02-B` | FamilyJoinValidationRulesContractTest`/`FamilyJoinRequestServiceJoinRequiredInfoContractTest`/`FamilyJoinRequestServiceJoinValidationGateTest | FamilyJoinRequestService/FamilyInviteController(S-cfc-57/58/59,5bef71317) |
@@ -850,6 +869,7 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthCheckinCfEarnCallSiteTest.java` | cfc-backend | 6 | HealthCheckinCfEarnCallSite | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthCheckinCfEarnCallSiteTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthDimensionControllerUploadContractTest.java` | cfc-backend | 21 | HealthDimensionControllerUploadContract | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthDimensionControllerUploadContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthPlanDeleteControllerTest.java` | cfc-backend | 6 | HealthPlanDeleteController | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthPlanDeleteControllerTest.java` |
+| `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthPlanProductSelectionContractTest.java` | cfc-backend | 14 | HealthPlanProductSelectionContract | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthPlanProductSelectionContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerCreateReportTest.java` | cfc-backend | 5 | HealthReportControllerCreateReport | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerCreateReportTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerListPaginationTest.java` | cfc-backend | 4 | HealthReportControllerListPagination | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerListPaginationTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerProxyParseBindingTest.java` | cfc-backend | 6 | HealthReportControllerProxyParseBinding | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerProxyParseBindingTest.java` |
@@ -1008,6 +1028,7 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/service/MembershipServiceTest.java` | cfc-backend | 17 | MembershipService | `cfc-backend/src/test/java/com/etotem/cfc/service/MembershipServiceTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/NormalizeIndicatorPipelineTest.java` | cfc-backend | 3 | NormalizeIndicatorPipeline | `cfc-backend/src/test/java/com/etotem/cfc/service/NormalizeIndicatorPipelineTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/NumSoulCalculatorTest.java` | cfc-backend | 5 | NumSoulCalculator | `cfc-backend/src/test/java/com/etotem/cfc/service/NumSoulCalculatorTest.java` |
+| `cfc-backend/src/test/java/com/etotem/cfc/service/OrderWebhookNotifyTest.java` | cfc-backend | 5 | OrderWebhookNotify | `cfc-backend/src/test/java/com/etotem/cfc/service/OrderWebhookNotifyTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/PaymentServiceORDRoutingTest.java` | cfc-backend | 3 | PaymentServiceORDRouting | `cfc-backend/src/test/java/com/etotem/cfc/service/PaymentServiceORDRoutingTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/PlatformPointsServiceTest.java` | cfc-backend | 9 | PlatformPointsService | `cfc-backend/src/test/java/com/etotem/cfc/service/PlatformPointsServiceTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/PointsExchangeServiceTest.java` | cfc-backend | 4 | PointsExchangeService | `cfc-backend/src/test/java/com/etotem/cfc/service/PointsExchangeServiceTest.java` |

+ 33 - 0
docs/tdd/test/notice-2026-11-10-R125-研发通知.md

@@ -0,0 +1,33 @@
+# 研发通知 · 测试负责人 · 第 125 轮(2026-11-10 14:55 GMT+8)
+
+> 送达渠道:本 notice 随报告 commit 推送至 `origin/cfclub`,测试结果有变化,请研发负责人查阅。
+
+## 测试结果变化
+
+| 项 | R124 | R125 | 变化 |
+|----|------|------|------|
+| langgraph@251(B-74) | 42 过 / 1 红 | **43 过 / 0 红** | **红例归零(首次全绿,观察第 1 轮)** |
+| 全量通过率 | 98.37%(3444/3501) | **98.40%(3445/3501)** | +0.03pp |
+| 浏览器自动化 | 28/28 | 28/28 | 持平 |
+| 前端 jest | 426 例(3skip)/ 116 | 同 | 持平 |
+| 后端(采信 R124,源码零变更) | 2865/2828/98.71% | 同 | 持平 |
+
+## 请研发/运维确认(P1)
+
+1. **B-74 langgraph LLM 凭据状态**:251 实派 43/43 全绿(756.13s),为连续 22 轮红例后首次。请确认 251 上 LLM API key(`****ab12`)是否已轮换/注入——若已轮换则 B-74 可走向销号;若未轮换,请解释为何测试期间凭据生效(可能为服务瞬时恢复),测试侧将继续以连续 2 轮全绿为销号判据。
+2. **B 类产品红 13 例(连续 3 轮零漂移,可批量派单)**:EnergySystemFlowTest 6、Orchestration* 2、MembershipPaySwitch 1、PaymentORD 1、WechatLogin(Contract) 2、TeamProfitCron 1——均已稳定归因,建议认领修复。
+3. **C 数据 1 例**:`GuideModuleIntegrationTest` platform_fee 列溢出(第 14 轮),建议核对列宽或迁移 DDL。
+
+## 测试侧已推进
+
+- B-123(Maven 探针 SOP)连续 3 轮达成 → **销号**
+- B-121(admin U05 偶发)销号后维持绿,结论成立
+- A 类装置红 16 例由测试侧自修(CfCommission/ArticleAutoTag/GrowthRecordSync/TaskPlan)
+- 台账已刷新:363 控制器 / 1969 handler / 覆盖 442(22.5%)/ @Test 2853 / 跨源用例 4168
+
+## 附:本轮证据文件
+
+- `docs/tdd/test/automation-run-2026-11-10-R125.md`
+- `docs/tdd/orchestration/report-test-2026-11-10-R125.md`
+- `docs/tdd/test/blockers.md`(B-74/B-36/B-121/B-122/B-123/B-125 更新)
+- `docs/tdd/test/discovery.md` / `inventory.md` / `automation-status.md`(台账刷新)