ソースを参照

docs(tdd): 测试负责人第173轮闭环汇报 2026-11-12 2010(R173 后端由采信转全量实跑:3103例/3060过/98.61%,存量红零漂移第19次;langgraph@251 45→46;浏览器28/28+2跳、API 32例0红、web 116/116、fe 609/3/12;门禁不通过承袭;CI漏拦5→8类;新登记B-173-1/2/3)

E2E Test Bot 8 時間 前
親
コミット
0043a01a4d

+ 84 - 0
docs/tdd/automation-run-2026-11-12-R173.md

@@ -0,0 +1,84 @@
+# 测试闭环 R173 — 2026-11-12 20:10 (GMT+8)
+
+> 执行档:**review(内网 cfc.iwintrue.com 已授权;不访问外部公网)**
+> 主理人:软件测试专家团·陆谨(测试负责人)| 被审查对象:d:/cfc(浠艾福 XAF)
+> 本轮回合 HEAD `45c00d5c8`(pull --rebase 后;窗口仅 cfc-web 构建元数据);上次本对象记忆轮 = R172(18:34)
+
+## 1. 历史审查记录(记忆召回)
+
+- **非首次审查**:自动化记忆库 `automations/6255181e…/memory.md` 连续记录 R123→R170 多轮闭环;R171/R172 由并行实例提交(本轮已读 R172 报告与记忆尾部)。
+- **直接前驱 R172(18:20,`f354f5091`)结论**:不通过(承袭);langgraph 45/51;后端**采信** R171(3057 例,未实跑);新增 5 契约类 46 例(30 绿 / 16 预期 RED)。
+- **本次对照**:为避免「连续 2 轮采信」风险,本轮**后端从干净 HEAD 全量实跑**(3103 例 / 51:52);存量红逐类逐例零漂移(第 19 次);langgraph 45→46;新增 3 项 blocker(B-173-1/2/3)。
+
+## 2. 执行范围
+
+| 模块 | 命令(离线/内网) | 状态 |
+|---|---|---|
+| cfc-backend 全量 | `cd cfc-backend && JAVA_HOME=/d/jdk1.8.0_25 mvn -o -B clean test` | ✅ 实测 3103 例(3060 过 / 39 红 / 4 跳,51:52) |
+| cfc-web | `npx jest --ci` | ✅ 实测 116/116(36.5s) |
+| cfc-frontend | `npx jest --ci` | ✅ 实测 609/3/12(47.4s) |
+| 根级黑盒 | `cd tests && npx jest --ci` | ✅ 实测 7/16(9082 未起,B-36 第 59 轮,8.8s) |
+| 浏览器 E2E(189 admin + 本机 fe/shop/health/dx) | Playwright config live/health | ✅ 实测 28/28 + dx 2 skip |
+| 线上 API | Playwright config api(**点名 4 文件**) | ✅ 实测 32 例(25 过 / 7 跳 / 0 红,20.4s) |
+| LangGraph@251 | 251 `POST /api/shell` → `.venv/bin/python -m pytest` | ✅ 实测 46/51(5 红全 429/401 环境,129.33s) |
+| 安全/性能/依赖漏洞(公网) | SAST/DAST/SCA/压测 | ⛔ 未授权未执行 |
+
+## 3. 本轮实测数据
+
+| 套件 | 总数 | 通过 | 失败 | 跳过 | 说明 |
+|---|---|---|---|---|---|
+| 后端 JUnit | **3103** | **3060** | **39**(33F+6E) | 4 | 368 类 / 368 XML / 0 dump;存量 18(11 类)零漂移 + 未入库 GrowthPublic 5E + 新契约预期 RED 16 |
+| cfc-web Jest | 116 | 116 | 0 | 0 | 全绿,36.5s |
+| cfc-frontend Jest | 624 | 609 | 3 | 12 | 3 全预期 RED(S-cfc-132/133),47.4s |
+| langgraph@251 | 51 | **46** | 5 | 0 | 5 红全 AgnesAI 429/401(B-142-2),129.33s |
+| 浏览器 E2E | 30 | 28 | 0 | 2 | 189 admin 5(EXIT=0)/ 本机 fe 6、shop 4、health 13;dx 2 skip |
+| 线上 API | 32 | 25 | 0 | 7 | smoke+security 15、perf-compat 4/3skip、trace 6/4skip |
+| 根级黑盒 | 23 | 7 | 16 | 0 | 9082 未监听(B-36) |
+| **合计** | **3979** | **3891** | **63** | **25** | 通过率 **97.79%**(剔 skip 98.41%) |
+
+## 4. 后端红例归因(39)
+
+| 层 | 例数 | 类 | 说明 |
+|---|---|---|---|
+| 存量装置/契约 | **18** | EnergySystemFlow 6F / DimensionRegistryMap 3F / GuideModule 1E / OrchestrationEngine 1F / OrchestrationIntegration 1F / MembershipPaySwitch 1F / PaymentServiceORD 1F / WechatLogin 1F / WechatLoginContract 1F / TaskReviewScP11 1F / TeamProfitCron 1F | 与 R171/R172 **逐类逐例一致(第 19 次零漂移)** |
+| 未入库测试类 | 5E | GrowthPublicEndpointMappingTest | B-162-1(文件 `??` 未跟踪) |
+| 新契约预期 RED | 16 | MembershipPlanPurchase 7 / ShopOrderQueryRefund 4 / SupplierOrderFulfill 5 | S-cfc-168/166/169 待研发实现 |
+
+## 5. G11 CI 清单双向差集(本轮实测)
+
+- CI 清单 33 类 vs 实测红类 15 类
+- **漏拦 8 类**:GrowthPublicEndpointMappingTest、MembershipPlanPurchaseContractTest、ShopOrderQueryRefundContractTest、SupplierOrderFulfillContractTest、TaskReviewScP11ContractTest、TeamProfitCronContractTest、UserServiceWechatLoginContractTest、UserServiceWechatLoginTest
+- **陈旧已绿 26 类**(AuthControllerTest、ProductControllerTest、UserServiceFamilyNameLinkTest 等)
+- 结论:`backend-blocking-junit` 在干净 HEAD 上**必红**,且覆盖被人为缩小 → G11 ❌(第 9 轮)
+
+## 6. 线上探针
+
+| 探针 | 结果 |
+|---|---|
+| 匿名 POST 6 端点(mind/energy/health-plan/huawei/xiaomi/**admin/families/overview**) | **6/6 = 401**(G8 ✅,B-142-1 维持销号) |
+| `/admin` `/frontend` `/` | 302 / 302 / 404 |
+| dx 两端点 | 404 / 404(B-DX-1 第 24 轮) |
+| 节点端口 | 251:4096 200 · 189:4090 200 · 204:4090 **000**(B-95 第 33 轮) |
+| 251 langgraph live | `/health` 200(8.9ms)· `/api/v1/analyze` **000/150s** · `/api/v1/chat` **000/150s** → LLM 链路挂死(B-90 反转延续) |
+
+## 7. 新发现(本轮)
+
+| 编号 | 级别 | 内容 |
+|---|---|---|
+| B-173-1 | P2 测试基础设施 | Playwright 启动即被 safe-delete 守卫拦截(`SAFE_DELETE_BULK_GUARD_ERROR: state lock timeout`);`shop-api`/`dx-bridge`/`api` 三组首次启动均在 **`Running N tests` 之前**中断,人工 `mv` 旧产物目录后恢复 |
+| B-173-2 | P1 度量/CI | `playwright.config.api.js` 不带文件参数收集 **990 例**(含 `e2e/api/generated/**`),点名 4 文件才 32 例 → 门禁口径不可复现 + 线上近千请求 |
+| B-173-3 | P2 性能 | 后端全量 51:52(R171 45m);慢类 GrowthPublic 237s / FamilyNameLink 168s / Activity 104s / ArticleCategory 99s / GuideRolePermission 94s / Stats 91s |
+
+## 8. SRS 闸门
+
+- specs 201 份 / test-cases 16 份 / user-scenarios 11 份 / API_REFERENCE:窗口 `f354f5091..45c00d5c8` **零命中**(`find -newermt` + `git diff --name-only` 双证)
+- → 不新增/不更新用例(G12 ✅)
+- 度量:场景 215 / 映射 TC 155(72.1%)/ TC 表行 861 / 异常流 502(58.3%)/ 锚点 115(13.4%,官方口径)/ 资产 545
+
+## 9. 本轮方法论(已写入报告 §9)
+
+1. 251 派发日志路径**禁止走本地 env 注入**(MSYS 会把 `/tmp/x` 转成 `C:/Users/...`)→ 写在传入 command 字符串里。
+2. 「套件跑不起来」分层:环境 → 工具链 → 用例;判据是日志里有没有 `Running N tests`。
+3. 同一 config 带/不带参数可能是两个口径(990 vs 32)。
+4. 慢 ≠ 卡死:先看 `Time elapsed` 分布与 scheduler 线程数。
+5. 未跟踪测试文件必须在报告里显式声明(HEAD 纯度 371 / 执行 374)。

+ 61 - 0
docs/tdd/orchestration/notice-2026-11-12-R173-研发通知.md

@@ -0,0 +1,61 @@
+# 研发通知 · 测试结果变化(R173 轮,2026-11-12 20:20)
+
+> 发送方:测试负责人(自动化测试闭环任务)| 接收方:研发团队(cfc)
+> 依据:测试结果 vs R172 基线有变化 → 按约定提交推送并通知研发。完整数据见 `docs/tdd/orchestration/report-test-2026-11-12-R173.md`,阻塞台账见 `docs/tdd/test/blockers.md` R173 段。
+> 本轮执行档:**review(离线)**——未安装依赖、未启停服务、未联网装包、未改生产代码。
+
+## 一、结果变化摘要(vs R172:`f354f5091` → 本轮 `45c00d5c8`,窗口仅 cfc-web 构建元数据)
+
+| 维度 | R172 | R173 | 变化 | 性质 |
+|---|---|---|---|---|
+| 全量用例 | 3979 例 / 3890 过 / 97.76% | **3979 例 / 3891 过 / 97.79%**(剔 skip 98.41%) | 例数持平,通过率 +0.03pp | 后端由「采信」转**全量实跑**(证据强度提升) |
+| 后端 JUnit | 3057(采信)+46 定向 | ****3103 例 / 3060 过 / 98.61%**(剔 skip 98.74%)** | 红 **39**(存量 18 零漂移 + 未入库 5E + 新增契约预期 RED 16) | 全量重跑,**存量红逐例零漂移(第 19 次)** |
+| langgraph@251 | 45/51(红 6) | **46/51(红 5)** | ▲+1 过 | 环境型(429/401),非代码回归 |
+| 浏览器 E2E | 28 过 + 2 跳 | **28 过 + 2 跳** | 持平 | 189 admin 5/5 EXIT=0 + 本机 23/23 |
+| 线上 API 层 | 25 过 / 7 跳 / 0 红 | **25 过 / 7 跳 / 0 红** | 持平 | 0 红 |
+| 管理端 Jest | 116/116 | **116/116** | 持平 | — |
+| 前端 Jest | 609/3/12 | **609/3/12** | 持平 | 3 红为 S-cfc-132/133 预期 RED |
+| 根级黑盒 | 7/16 | **7/16** | 持平 | 9082 未监听(环境,B-36 第 59 轮) |
+| 门禁 | 不通过(承袭) | **不通过(承袭)** | 持平 | G2/G7/G9/G11/G14 卡口未变(G11 漏拦由 5 类扩至 **8 类**) |
+
+## 二、请研发处理(按优先级)
+
+| 序号 | 事项 | 类型 | 要求 |
+|---|---|---|---|
+| 1 | **251 LLM 上游**(B-142-2,P0):AgnesAI `429 free limit` ×7 + `401 ****ab12 invalid` ×3;`/api/v1/chat`、`/api/v1/analyze` 实测 **000 / 150s 零字节**,而 `/health` 200/8.9ms | 运维/AI | 换有效 key / 升 Token Plan;另请修 `intent_classifier.py:62` 的「异常兜底 chat」,避免 429 被伪装成分类错误。恢复后 251 连续 2 轮 51/51 销号 |
+| 2 | **CI 排除清单双向失真**(B-152-1/2,P0,**第 9 轮未修**):`.gitlab-ci.yml:61` 33 类清单既漏拦当前红类,又长期排除 26 个已转绿类 → `backend-blocking-junit` 恒红且覆盖虚化 | CI | 落地差集脚本(建议 `docs/tdd/tools/ci_class_diff.py`)作为 CI 前置校验,差集非空即 fail 并打印应增/应删 |
+| 3 | **API 层入口口径**(B-173-2,P1 **新登记**):`tests/playwright.config.api.js:18` `testMatch` 覆盖 `e2e/api/generated/**`,不带文件参数即收集 **990 例**(报告口径 32 例)。CI 若直跑将产生大量假红且对线上发起近千请求 | 测试/CI | 收窄 `testMatch` 为 4 文件白名单,`generated/**` 单列 project 并默认不跑 |
+| 4 | **`nutrition_age_dosage` 建表 SQL**(B-156-1,P1,第 4 轮):`schema.sql:5354` 含 `INDEX idx_product (product_id)` 但无该列 → 建表恒失败且被 `DatabaseInitializer` 静默吞掉;实体另有 `updateTime` 无对应列 | Schema | 修 DDL(删索引或补列)+ 补 `update_time`;建表异常改为汇总 ERROR 打印 |
+| 5 | **3 类未入库测试文件**(B-162-1,P1,第 5 轮):`GrowthPublicEndpointMappingTest`(**5E**)、`JwtInterceptorGrowthPolicyTest`、`ArticleTagsContractTest` 仍为 `??`,却被编译执行(本轮 374 测试源 / HEAD 371) | 治理 | 确认归属后入库(或废弃删除);`GrowthPublicEndpointMappingTest` 先修绿再入库 |
+| 6 | **S-cfc-166/168/169 契约实现**(16 红,P1 承袭):`ProductOrderService#queryRefund`、`MembershipService#purchasePlan`、`ProductOrderService#redeem` 未落地 | TDD YELLOW | 实现 + push 后由测试定向复跑销号 |
+| 7 | **`activities.approved_count` 回填 SQL**(B-170-1,P2):`DatabaseInitializer.java:2261` 别名语法非法,该列持久化恒 0 | 数据一致性 | 修正 UPDATE 语法 |
+| 8 | **后端全量耗时劣化**(B-173-3,P2 **新登记**):本轮 **51:52**(R171 45m),4 个慢类占约 45%;`@EnableScheduling` + `@SpringBootTest` 使 scheduler 线程常驻 | 研发/测试 | 抽 `AbstractSpringTest` 关闭调度、复用上下文,目标 ≤50m |
+| 9 | **pytest 退出码未落盘**(B-126,P2,第 6 轮):日志末行只有 summary,无 `EXIT=` | 测试工具 | 派发器改单引号 `bash -c` 包裹整段 |
+
+## 三、测试侧本轮自处置与新发现(不需研发动作,告知)
+
+| 编号 | 内容 | 处置 |
+|---|---|---|
+| B-173-1(P2) | Playwright 启动即被 safe-delete 守卫拦截(`SAFE_DELETE_BULK_GUARD_ERROR: state lock timeout`),`shop-api`/`dx-bridge`/`api` 三组首次启动均在**用例执行前**中断;人工 `mv` 旧产物目录后即正常(4/4、2 跳过、25 过) | 已记录;建议所有 Playwright 调用固定 `--output=<runid>` 一次性目录(缺口 G-173-8) |
+| 口径修正 | 报告例数必须与命令行一一对应:不带文件参数的 `playwright.config.api.js` = 990 例,点名 4 文件 = 32 例 | 已在报告 §9 与方法论固化 |
+| B-142-1 维持销号 | 匿名 6 端点(mind/energy/health-plan/huawei/xiaomi/**admin/families/overview**)全 **401** | G8 ✅,第 8 轮维持 |
+
+## 四、复跑指引(研发修复后) 
+
+```bash
+# 后端定向(契约批次)
+cd cfc-backend && JAVA_HOME=/d/jdk1.8.0_25 /d/maven/apache-maven-3.6.1/bin/mvn -o -B test \
+  -Dtest='MembershipPlanPurchaseContractTest,ShopCouponApplyContractTest,ShopOrderCreateSpecialDealContractTest,ShopOrderQueryRefundContractTest,SupplierOrderFulfillContractTest'
+
+# langgraph@251
+node docs/tdd/tools/dispatch_251_pytest.cjs run "rm -f /tmp/rX_pytest.log; setsid nohup bash -c 'cd /sc-data/cfc/cfc-langgraph && .venv/bin/python -m pytest -q --ignore=tests/qna --ignore=tests/test_chat.py > /tmp/rX_pytest.log 2>&1; echo EXIT=\$? >> /tmp/rX_pytest.log' >/dev/null 2>&1 & echo KICKED"
+node docs/tdd/tools/dispatch_251_pytest.cjs run "tail -c 3000 /tmp/rX_pytest.log"
+
+# 线上鉴权 6 端点(应全 401)
+for p in /api/mind/fortune /api/energy/overview /api/health/plan/list /api/huawei-health/status /api/xiaomi-health/status /api/admin/families/overview; do
+  curl -s -o /dev/null -w "$p -> %{http_code}\n" -X POST "http://cfc.iwintrue.com$p" -H 'Content-Type: application/json' -d '{}'; done
+```
+
+---
+> 本轮为**结果有变化**轮次(后端采信转全量实跑、langgraph 45→46、新增 3 项 blocker),已提交并推送 `origin/cfclub`,供研发按上表排期。
+> 记忆沉淀:`record` 已写入本轮摘要(含未实测项:变异测试 / SAST / 依赖扫描 / 真实压测 / 无障碍 / UAT 签署)。

+ 353 - 0
docs/tdd/orchestration/report-test-2026-11-12-R173.md

@@ -0,0 +1,353 @@
+# 测试负责人工作汇报(R173 轮)
+
+> 本汇报按《测试负责人工作汇报模板》填写。R173 为**全量回归实跑轮**:后端从干净 HEAD 全量重跑,其余六个套件(管理端/小程序 Jest、浏览器 E2E 双节点、线上 API 非功能层、langgraph@251、根级黑盒)全部本轮实测;窗口内**零 SRS/场景变更、零功能源码变更**(仅 cfc-web 构建元数据)。
+> 对比基线 R172(18:34 提交 `f354f5091`):窗口 `f354f5091..45c00d5c8`(5 文件,全部 cfc-web 版本号/CHANGELOG/`.last_build_commit`)。
+> 本轮核心结论:**全站 3979 例 / 3891 过(97.79%,剔 skip 98.41%)**;后端 3103 例 98.61%(剔 skip 98.74%),存量红 18 例 + 未入库 5E 与 R171 **逐类逐例零漂移(第 19 次)**;langgraph@251 由 45/51 回升至 **46/51**(5 红全为上游 429/401 环境型);浏览器 **28/28 + 2 跳**;线上 API **25 过 / 7 跳 / 0 红**;门禁 **不通过(承袭)**——卡口仍是 G2 红例、G7 环境红、G9 锚点、G11 CI 清单失真。
+
+---
+
+## 基本信息
+
+| 项目 | 内容 |
+|------|------|
+| 汇报人 | 测试负责人(自动化测试闭环任务) |
+| 汇报周期 | 2026年11月12日 18:48 ~ 20:20(第 173 轮) |
+| 基线 | `cfclub @ f354f5091`(R172 结论点,18:34)→ `45c00d5c8`(pull --rebase 后,仅 cfc-web 元数据) |
+| 窗口内需求变更 | **零**:`docs/superpowers/specs`(201 份)/ `tests/test-cases`(16 份)/ `tests/user-scenarios`(11 份)/ `docs/superpowers/api` 窗口零命中(`find -newermt` + `git diff --name-only` 双证) |
+| 窗口内源码变更 | **零功能源码**:5 个文件全为 `cfc-web/{package.json,package-lock.json,public/CHANGELOG*.md,.last_build_commit}` |
+| 负责模块/单元 | 全站:cfc-backend JUnit · 管理端 admin@189 · 小程序 H5/shop/health/dx@本机 · cfc-langgraph@251 · cfc-web/ cfc-frontend Jest · 根级黑盒 · 线上 API 非功能层 |
+
+---
+
+## 一、本轮工作数据汇总
+
+### 1.1 测试用例建设
+
+| 指标 | 数量 | 填写说明 |
+|------|------|----------|
+| **本轮新增测试用例数\*** | **0 个** | SRS/场景窗口零变更、测试资产零新增 → 按 G12「无变更不造用例」纪律不新增;台账 TC 编号仍为 R172 口径(未新增编号) |
+| **本轮验证执行测试数\*** | **3979 个** | 后端 JUnit 3103 + 前端 Jest 624 + 管理端 116 + langgraph 51 + 浏览器 30(28 过 + 2 跳)+ 线上 API 32(25 过 + 7 跳)+ 根级 23 |
+| **用例通过率** | **97.79%**(3891/3979;剔除 skip **98.41%**) | 红 63 / 跳 25(红含环境型 21、预期 RED 19、存量装置 23),明细见 §3.3 |
+| **用例台账** | `tests/test-cases/` 16 份(含 README) | 场景 215 / 映射 TC 155(72.1%)/ TC 表行 861 / 异常流语义 502(58.3%) |
+
+### 1.2 会话与任务分发
+
+| 指标 | 数量 | 填写说明 |
+|------|------|----------|
+| **分派任务数\*** | **3 个** | R173-1 → `opencode-189`(admin-desktop **5/5 EXIT=0**,1.3m);R173-2 → `opencode-251`(langgraph pytest **46/51**,129.33s);R173-3 → 本机串行(3 套 Jest + 4 组浏览器 + API 层 + 后端全量 mvn) |
+| **恢复智能体会话数\*** | 0 个 | 189 首派即 5/5(B-167-1 销号后第 3 轮);251 首派 log 路径被本地 shell 展开为 Windows 路径 → 立即以显式远端路径重派(见 §9 教训①) |
+| **当前在用会话数** | 0 个 | 三节点均已收尾,无残留 shell |
+
+### 1.2b 各会话当前工作状态列表
+
+| 会话标签 | 会话 ID/地址 | 当前状态 | 当前任务 | 静默/空闲时长 | 工作目录 | 备注 |
+|----------|--------------|----------|----------|---------------|----------|------|
+| `opencode-189` | 192.168.16.189:4090 | done | admin-desktop UI E2E | 已完成(1.3m) | `C:\code\cfc\tests` | **5/5 EXIT=0**;节点 HEAD `8524533c8`、spec blob `4703d73fb` = 本机 → 跨节点可比 |
+| `opencode-251` | 192.168.16.251:4096 | done(本会话派发) | langgraph pytest 51 例 | 已完成(129.33s) | `/sc-data/cfc/cfc-langgraph` | **46 过 / 5 红**;节点 HEAD `45c00d5c8` = 本机 HEAD;5 红全 429/401(环境型) |
+| `local-browser` | 本机进程 | done | fe / shop / health / dx | 已完成(1.7m + 8.6s + 11.5s + 跳过) | `d:\cfc\tests` | fe **6/6**、shop **4/4**、health **13/13**、dx **2 skip**(端点 404) |
+| `local-api` | 本机进程 | done | 线上 API 冒烟/安全/性能兼容/追溯 | 已完成(20.4s) | `d:\cfc\tests` | api-smoke+security **15/15**、perf-compat **4 过/3 跳**、traceability **6 过/4 跳**,**0 红** |
+| `local-jest` | 本机进程 | done | cfc-frontend + cfc-web + 根级 | 已完成(47.4s + 36.5s + 8.8s) | `cfc-frontend` / `cfc-web` / `tests` | fe 609/3/12、web **116/116**、根级 7/16(9082 未起,B-36 第 59 轮) |
+| `local-backend` | 本机进程 | done | 后端全量 `mvn -o -B clean test` | 已完成 | `d:\cfc\cfc-backend` | 见 §3.3 |
+
+### 1.3 问题处置
+
+| 指标 | 数量 | 填写说明 |
+|------|------|----------|
+| **新测试发现问题数\*** | **0 个(产品缺陷)** | 63 红全部归因:后端存量 18(装置/契约,零漂移)+ 后端未入库类 5 + 后端新增契约预期 RED 16 + 前端预期 RED 3(S-cfc-132/133)+ 环境 21(根级 16 无 9082 / langgraph 5 上游配额);**无新增产品级缺陷** |
+| **已解决测试相关问题数\*** | 0 个 | 本轮零资产修改 |
+| **待解决测试相关问题数** | 12 个(P0×2 / P1×6 / P2×4) | ① B-142-2 langgraph 上游 429/401(P0);② B-152-1/2 CI 排除清单双向失真(P0/P1,第 9 轮未修);③ **B-173-2 API 层入口默认收集 990 例**(P1 新登记);④ B-156-1 `nutrition_age_dosage` 建表 SQL 无效(P1);⑤ B-162-1 3 类未入库测试文件(P1);⑥ S-cfc-166/168/169 契约 16 红待实现(P1);⑦ **B-173-1 Playwright 被 safe-delete 守卫拦截**(P2 新登记);⑧ B-173-3 后端全量耗时劣化(P2 新登记);⑨ B-170-1 `approved_count` 回填 SQL(P2);⑩ B-126 pytest 退出码未落盘(P2);⑪ B-36 根级 16 红(P2 环境);⑫ B-95 `204:4090` 失联(P2) |
+
+### 1.4 本轮 git 提交与推送证据(真理证据)
+
+| 提交 sha | 关联任务/能力键 | 阶段 | 触及文件类型 | 目标分支 | 已推送远端 | 备注 |
+|----------|-----------------|------|--------------|----------|------------|------|
+| (本轮) | 全站巡检 R173 | 汇报 | 报告/run/通知/blockers | cfclub | ✅ 本轮推送 | 测试结果**有变化**(langgraph 45→46 过、后端由采信转全量实跑、新增 3 项 blocker)→ 按规则提交并通知研发 |
+
+### 1.5 状态机阶段分布(全局进度)
+
+| 阶段 | 键数 | 备注 |
+|------|------|------|
+| UNTRACKED | 0 | 需求侧 ⏳ 0 键(窗口零新增规格) |
+| RED | 8 | 承袭研发口径(含 S-cfc-166/168/169 契约 16 例待实现) |
+| YELLOW | 63 | 承袭 R172(本轮零流转) |
+| GREEN | 8 | 承袭 |
+| DONE | 15 | 承袭 |
+| 合计 | 94 | 与研发 161/162 轮汇报口径一致(研发侧状态机;`.tdd/state.json` 本地仅为 5 键影子副本,见 B-17) |
+
+---
+
+## 二、历史审查记录(阶段 -1 记忆召回)
+
+| 项 | 内容 |
+|---|---|
+| 上次审查 | **R172(2026-11-12 18:20,提交 `f354f5091`)**,结论「不通过(承袭)」,langgraph 45/51、后端采信 R171 |
+| 遗留缺口 | 后端 23 红(17F+6E)· langgraph 6 红(429/401)· 根级 16 红(9082 未起)· CI 清单漏拦 5 类 · G9 锚点 ~20.7% · B-156-1 / B-162-1 / B-170-1 未修 |
+| 本次是否改善 | **部分改善**:langgraph 45→**46 过**(红 6→5);后端由「采信」转**本轮全量实跑**(消除连续采信风险);**新恶化/新登记**:B-173-1(Playwright 守卫拦截)、B-173-2(API 入口 990 例口径)、B-173-3(后端耗时劣化) |
+| 教训应用 | ① 「连续采信不超过 2 轮」→ 本轮必须实跑(已执行);② 251 派发端口 4096 且必须 `.venv/bin/python`(沿用);③ 189 spec blob 哈希比对跨节点可比(沿用,本轮一致);④ 长任务禁止轮询建 shell(沿用 kick+单次读) |
+
+> 本次为该对象**第 173 次**审查,有历史记录;上述内容仅作对照,**本次结论全部来自本轮实测**。
+
+---
+
+## 三、项目画像与覆盖矩阵
+
+### 3.1 项目画像(承袭并本轮核验)
+
+| 维度 | 内容 |
+|---|---|
+| 业务定位 | 家庭教育「五维能量」(身/心/智/行/富)测评 + 成长规划 + 商城 + 健康报告解析的微信小程序 + Web 管理端全栈系统 |
+| 技术栈 | 后端 Spring Boot 2.7.18 + MyBatis-Plus + Java 8(9082)· 小程序 uni-app Vue2 · 管理端 Vue2 + Element UI(8082)· AI 服务 FastAPI + LangGraph + ChromaDB(9000) |
+| 模块结构 | `cfc-backend`(2121 主源 / 374 测试源,含 3 未跟踪)/ `cfc-frontend` / `cfc-web` / `cfc-langgraph` / `dan/danshop` / `tests` |
+| 关键路径 | 登录(微信/direct-register)→ 家庭与成员 → 五维测评/能量 → 成长规划(规划师)→ 商城订单/优惠券/退款 → 健康报告上传解析 → AI 对话(仅会员可见) |
+| 测试现状 | 后端 3103 例本轮实跑(98.61%);前端 Jest 624;管理端 116;浏览器 28+2skip;API 契约层 32;langgraph 51;根级黑盒 23 |
+| 质量目标 | 全量通过率 ≥98%、浏览器 E2E 100%、langgraph 100%、锚点覆盖率 ≥80%、CI 硬门禁可用 |
+| 风险点 | LLM 上游配额(429/401)· 契约 RED 批次(16 例)· 数据库迁移静默失败 · CI 排除清单失真 · 未入库测试资产 · **测试基础设施自身可用性(Playwright 守卫)** |
+
+### 3.2 20 类测试覆盖矩阵(全类不省略)
+
+| # | 测试类型 | 状态 | 本轮证据 |
+|---|---|---|---|
+| 1 | 单元测试 | ✅ 已发现 | 后端 3103 例实跑(98.61%);前端 Jest 624(609 过);管理端 116/116 |
+| 2 | 测试覆盖率 | ⚠️ 部分 | cfc-web `--coverage` 历轮 Lines ~9.95%;**后端 JaCoCo 未配置** → 行覆盖无法量化(G-170-3 延续) |
+| 3 | 变异测试 | ❌ 未发现 | 仓库无 PIT/Stryker 配置;离线档无工具(未实测,不得视为通过) |
+| 4 | 集成测试 | ✅ 已发现 | 后端 `integration/**`(含 `GrowthPublicEndpointMappingTest` 5E—未入库 B-162-1);根级 16 红均因 9082 未起 |
+| 5 | 契约测试 | ✅ 已发现 | 后端 `*ContractTest` 多组(含新增 5 类 46 例:30 绿 / 16 预期 RED);API 层 32 例 0 红 |
+| 6 | 接口 API 测试 | ✅ 已发现 | 线上 32 例:smoke+security 15/15、perf-compat 4 过 3 跳、traceability 6 过 4 跳 |
+| 7 | 系统 / 端到端 | ✅ 已发现 | 浏览器 28/28(189 admin 5 + 本机 fe 6 / shop 4 / health 13)+ dx 2 skip(404) |
+| 8 | 验收 UAT | ⚠️ 待核实 | 无独立 UAT 用例库;以 16 份台账近似验收口径,未与业务方逐条签署 |
+| 9 | BDD 规格 | ❌ 未发现 | 无 `.feature` / Cucumber 资产 |
+| 10 | 冒烟测试 | ✅ 已发现 | `api-smoke.spec.js` 4/4 + 根级冒烟 7/23 过 |
+| 11 | 回归测试 | ✅ 已发现 | 本轮全量回归 3979 例;后端红例与 R171 **逐类逐例零漂移(第 19 次)** |
+| 12 | 探索性测试 | ⚠️ 部分 | 以「安全/健壮性探针」形式执行(畸形上传、空参登录、匿名越权、UA 兼容),未形成独立探索会话记录 |
+| 13 | 性能测试 | ⚠️ 部分 | 仅冒烟级(20 并发无 5xx、<500ms);**无真实压测**(execute 档需联网授权,未执行) |
+| 14 | 可靠性测试 | ⚠️ 部分 | 迁移静默失败持续观察(B-170-1/B-156-1);无故障注入 / 长稳测试 |
+| 15 | 安全测试(SAST/DAST/依赖) | ✅ 已发现(部分) | DAST 类 11 例全绿(IDOR 403、越权拒绝、XSS 不回显、上传被拒)+ 线上匿名 6/6 = 401;**SAST / 依赖漏洞扫描未执行**(需联网未授权) |
+| 16 | 兼容性测试 | ✅ 已发现 | 多端 UA 一致性 1 例通过;仅 Chromium,无 Firefox/WebKit 矩阵 |
+| 17 | 可用性测试 | ❌ 未发现 | 无可用性量表 / 用户任务完成率采集 |
+| 18 | 无障碍测试 | ❌ 未发现 | 无 axe / WCAG 断点 |
+| 19 | QA 流程 | ⚠️ 部分 | 有 blockers/automation-status/台账;**CI 硬门禁因排除清单失真恒红(G11)**;**测试执行入口自身不稳定(B-173-1)** |
+| 20 | 质量指标 | ⚠️ 部分 | 通过率/红/跳可取;锚点率与场景映射两套口径并存(B-124/B-170-4);**API 层口径可被默认入口放大 31 倍(B-173-2)** |
+
+**结论**:20 类中 ✅ 已发现 8 类、⚠️ 部分 8 类、❌ 未发现 4 类(变异、BDD、可用性、无障碍)。「未发现」仅表示扫描未命中,**不等于项目未做**。
+
+### 3.3 本轮实测数据总表
+
+| 套件 | 命令/节点 | 例数 | 过 | 红 | 跳 | 耗时 |
+|---|---|---|---|---|---|---|
+| 后端 JUnit | `cd cfc-backend && JAVA_HOME=jdk1.8.0_25 mvn -o -B clean test` | **3103** | **3060** | **39**(33F+6E) | 4 | **51:52** |
+| 管理端 Jest | `cd cfc-web && npx jest --ci` | 116 | 116 | 0 | 0 | 36.5s |
+| 前端 Jest | `cd cfc-frontend && npx jest --ci` | 624 | 609 | 3 | 12 | 47.4s |
+| langgraph | 251 `POST /api/shell` → `.venv/bin/python -m pytest` | 51 | **46** | 5 | 0 | 129.33s |
+| 浏览器 E2E | 189(admin)+ 本机(fe/shop/health/dx) | 30 | 28 | 0 | 2 | 1.3m + 1.7m/8.6s/11.5s |
+| 线上 API | 4 文件显式点名(api-smoke/security/perf-compat/traceability) | 32 | 25 | 0 | 7 | 20.4s |
+| 根级黑盒 | `cd tests && npx jest --ci` | 23 | 7 | **16** | 0 | 8.8s |
+| **合计** | — | **3979** | **3891** | **63** | **25** | ≈63m(后端 51:52 主导) |
+
+> 通过率 **97.79%**;剔除 skip **98.41%**。环比 R172(3890/3979=97.76%):**总例数持平 3979**(后端全量实跑 3103 例 = 采信 3057 + 新增契约 46,口径完全吻合)、**红 64→63**(langgraph 6→5 改善 1,其余逐类持平)、**跳 25 持平**。后端 368 个测试类 **368 份 surefire XML 全落盘、0 沉默、0 dump**。
+
+### 3.4 可执行锚点双向核对
+
+| 指标 | 数值 |
+|---|---|
+| 场景数 / 被 TC 映射 | 215 / **155(72.1%)** |
+| 用例台账表行 | 861 |
+| 异常流语义条数 | 502(**58.3%**) |
+| 可执行锚点(资产口径,含 generated) | 115 / 861 = **13.4%** |
+| 资产文件扫描数 | 545 |
+| 孤儿锚点(执行有 / 台账无) | 显著存在(`TC-A-U0x`、`TC-A5-0x` 等未登台账)→ G-170-4 延续 |
+
+> 口径声明:13.4% 为 `test_report_metrics.py --scene` 官方口径(资产含 `tests/e2e/api/generated`,会压低比例);严格口径(排除 generated、按唯一编号)历轮为 ~18.5~20.7%。两套口径并存属 **B-124 长期未闭环**,本报告同时给数、不择一掩盖。
+
+---
+
+## 四、测试方案与执行档
+
+| 项 | 内容 |
+|---|---|
+| 目标 | 全量用例通过 + 覆盖 SRS/场景(含异常流);本轮聚焦「后端全量重跑取证 + 存量红是否漂移 + LLM 上游状态 + 测试入口可用性」 |
+| 范围 | cfc-backend(全量实跑)· cfc-web · cfc-frontend · tests(根级 + e2e-live + e2e/api)· cfc-langgraph@251 |
+| 覆盖维度 | 功能(单元/集成/契约/API/E2E)、非功能(安全/性能/兼容)、流程与度量 |
+| **执行档** | **review(离线档,默认)**——未安装依赖、未启停服务、未联网装包、未改生产代码 |
+| 未授权未执行 | 依赖漏洞扫描 / 真实压测 / SAST 商业扫描(需联网,本轮无显式联网授权)→ 对应维度标注「未实测」,不得视为通过 |
+| 排除项 | 微信真机、小程序审核链路、支付真实扣款(涉资金,需人工介入) |
+| 本机环境探针 | JDK `1.8.0_25` ✅ · Maven `3.6.1` ✅ · 2121 主源 + 374 测试源编译 **0 错** · 9082 **未监听**(→ B-36 环境红) |
+| 节点探针 | 251:4096 **200** / 251:9000 `/health` **200(8.9ms)** · 189:4090 **200** · 204:4090 **000**(B-95 第 33 轮) |
+
+> 自动化无人值守运行,按既定默认档位(review 离线)执行;未越过任何需联网/启停服务的边界。
+
+---
+
+## 五、域结论表
+
+| 审查维度 | 负责域 | 结论 | 关键证据 |
+|---|---|---|---|
+| 单元·组件 | 单元域 | ⚠️ 有条件通过 | 后端 3103 例 **98.61%**;红 39 = 存量 18(零漂移)+ 未入库 GrowthPublic 5E + 新增契约预期 RED 16;前端 609/624(3 红为 S-cfc-132/133 预期 RED);管理端 116/116 |
+| 集成·接口·契约 | 集成域 | ⚠️ 部分 | 契约批次 30 绿 / 16 预期 RED 与研发声明一致;API 层 32 例 **0 红**;线上匿名 6/6 = 401 |
+| 系统·验收·BDD | 系统域 | ⚠️ 部分 | E2E 28/28(双节点)+ dx 2 skip;无 BDD 资产;UAT 未签署 |
+| 测试保障 | 保障域 | ⚠️ 部分 | 冒烟 4/4;回归全量 3979 例可复跑;**但执行入口本身不稳定(B-173-1)且 API 入口口径可放大 31 倍(B-173-2)** |
+| 性能·可靠性 | 性能域 | ⚠️ 部分 | 冒烟级并发无 5xx;后端全量耗时 **51:52**(R171 45m,B-173-3 劣化);无真实压测 |
+| 安全 | 安全域 | ✅ 有条件通过 | DAST 11/11 + 匿名 6/6 401;SAST/依赖扫描未执行 |
+| 兼容·体验 | 兼容域 | ⚠️ 部分 | Chromium 单引擎;无障碍零资产 |
+| 流程·度量·代码 | 流程域 | ❌ 不通过 | **CI 排除清单第 9 轮失真**(漏拦/陈旧双向);锚点口径双轨;未入库测试资产长期游离 |
+
+---
+
+## 六、覆盖缺口清单
+
+| 编号 | 缺口类型 | 现状 | 风险 | 建议测试设计 | 优先级 | 闭环方式 |
+|---|---|---|---|---|---|---|
+| G-173-1 | 变异测试 | 无 PIT/Stryker | 断言强度不可度量,「全绿」可能空心 | 后端接 PIT(仅 `unit/` 包,阈值 40%) | P2 | 引入插件后跑基线批次,报 mutation score |
+| G-173-2 | BDD 规格 | 无 `.feature` | 需求→用例→代码链路断裂 | 对 S-cfc-16x 契约批用 Gherkin 描述 Given/When/Then | P2 | 首批 5 个能力键试点 |
+| G-173-3 | 覆盖率 | 后端无 JaCoCo | 行覆盖空白,回归范围靠猜 | 接 JaCoCo + 与 surefire 同批出报告 | P1 | 出首份 line/branch 基线 |
+| G-173-4 | 无障碍 | 零资产 | 违反无障碍合规预期 | axe-core 接 admin 首页 + 小程序 TabBar | P3 | 接入后出违规清单 |
+| G-173-5 | 真实压测 | 仅 20 并发冒烟 | 容量未知,秒杀/批量场景无结论 | k6 脚本 3 档(50/200/500 VU)需联网授权 | P2 | 授权后压测并出 P95/错误率 |
+| G-173-6 | 锚点覆盖 | 13.4%(官方)/ ~20%(严格) | 需求→执行不可双向追溯 | 统一 `TC-<域>-U<NN>` 单套命名 + 台账回填 | P1 | inventory 重生成后 G9 ≥ 60% |
+| G-173-7 | UAT 签署 | 无签署记录 | 验收靠测试自证 | 按 SC 键生成验收清单交业务方签字 | P2 | 首批 20 键签署 |
+| G-173-8 | 执行入口稳定性 | Playwright 启动即被守卫拦截(B-173-1) | CI 上 4 个浏览器/API 套件可能整批不可用 | 固定 `--output` 且启动前不删旧目录;或改 `preserveOutput` | P1 | CI 连续 3 次无人工干预跑通 |
+
+---
+
+## 七、五要素问题清单
+
+> 五要素:① 问题描述 ② 测试 bug 点(文件:行号 / 用例名)③ 最优修改方案 ④ 修改目的 ⑤ 修改后能否闭环(复测方式 + 通过标准)
+
+### P-173-1(P0,环境)langgraph 上游配额/凭据双重失效,5 例恒红
+- **① 问题描述**:251 节点 `pytest` 46 过 / 5 红;5 红全部落在 `test_auto_tag`(3)与 `test_intent`(2),日志实证 `RateLimitError 429 AgnesAI free limit` ×7 与 `401 api key ****ab12 invalid` ×3。
+- **② 测试 bug 点**:`cfc-langgraph/tests/test_auto_tag.py::test_auto_tag_content_relevance|short_content|empty_content`、`tests/test_intent.py::test_classify_analysis|test_classify_health`。
+- **③ 最优修改方案**:运维更换有效 LLM key 并升 Token Plan / 申请提高配额;`intent_classifier.py:62` 的「异常兜底 chat」改为抛错或返回 `UNKNOWN`,避免 429 被伪装成分类错误。
+- **④ 修改目的**:让 AI 能力回归「确定性可测」,否则 langgraph 门禁永远无法转绿。
+- **⑤ 闭环**:251 连续 2 轮 51/51 且 `/api/v1/chat`、`/api/v1/analyze` 均 200(非 000/150s),即可销号 B-142-2。
+
+### P-173-2(P0,CI)后端 CI 排除清单双向失真(第 9 轮未修)
+- **① 问题描述**:`.gitlab-ci.yml:61` 的 `BACKEND_OBSERVED_CLASSES`(33 类)与本轮实测红类集合做双向差集:**漏拦**(当前红类不在清单内 → `backend-blocking-junit` 必红)+ **陈旧**(清单内已转绿类被长期排除 → 硬门禁覆盖被人为缩小)。
+- **② 测试 bug 点**:`.gitlab-ci.yml:61`(清单本身);判定脚本缺失(无自动差集)。
+- **③ 最优修改方案**:新增 `docs/tdd/tools/ci_class_diff.py`,从 `target/surefire-reports` 提取红类并与清单自动双向差集,作为 CI 的 `before_script` 校验(差集非空即 fail 并打印应增/应删列表)。
+- **④ 修改目的**:让 CI 硬门禁「能红能绿」,恢复其作为质量卡口的可信度。
+- **⑤ 闭环**:连续 2 轮 CI 差集为空 + `backend-blocking-junit` 在干净 HEAD 上变绿,G11 转 ✅。
+
+### P-173-3(P1,度量/CI)API 层入口默认收集 990 例,口径可被放大 31 倍
+- **① 问题描述**:`npx playwright test -c playwright.config.api.js` 无文件参数时收集 **990 例**(`testMatch: /api[\\/].*\\.spec\\.js$/` 覆盖 `e2e/api/generated/**`);R172/R173 报告的「32 例」实为**显式点名 4 个文件**的结果。若 CI 直跑该 config,将得到 990 例口径(大量 401/404 假红)并对线上发起近千次请求。
+- **② 测试 bug 点**:`tests/playwright.config.api.js:18`(`testMatch` 过宽)。
+- **③ 最优修改方案**:将 `testMatch` 收窄为显式白名单(`['api-smoke.spec.js','nonfunc-security.spec.js','nonfunc-perf-compat.spec.js','traceability-p94-p95-c26.spec.js']`),`generated/**` 单列 `api-generated` project 并标 `@slow` 默认不跑。
+- **④ 修改目的**:让「API 层 32 例」这一门禁口径**可复现**,避免跨轮数字不可比与线上被打满。
+- **⑤ 闭环**:改后不带文件参数跑该 config 仍为 32 例且 0 红,报告数字与命令一一对应。
+
+### P-173-4(P1,Schema)`nutrition_age_dosage` 建表 SQL 永久失败(第 4 轮未修)
+- **① 问题描述**:`schema.sql:5354` 建表语句含 `INDEX idx_product (product_id)`,但表定义无 `product_id` 列 → 每次上下文启动建表失败;`DatabaseInitializer` catch 后仍打印「数据表检查完成」,导致**该表从未创建成功**且无人察觉。
+- **② 测试 bug 点**:`cfc-backend/src/main/resources/schema.sql:5354`;实体 `NutritionAgeDosage.java:33-34`(有 `updateTime`,DDL 无 `update_time`)。
+- **③ 最优修改方案**:删除该 `INDEX` 行(或补 `product_id` 列)+ DDL 补 `update_time`;`DatabaseInitializer` 对建表异常改为「计数并在收尾汇总打印 ERROR」,不得吞掉。
+- **④ 修改目的**:消除「迁移静默失败」这一类系统性风险(与 B-170-1 同源)。
+- **⑤ 闭环**:全量跑测日志 grep `SQLSyntaxErrorException` = 0,且 `SHOW TABLES LIKE 'nutrition_age_dosage'` 命中。
+
+### P-173-5(P1,治理)3 个测试类长期未入库(第 5 轮未修)
+- **① 问题描述**:`GrowthPublicEndpointMappingTest`(5E)、`JwtInterceptorGrowthPolicyTest`、`ArticleTagsContractTest` 处于 `??` 未跟踪状态却被 `testCompile` 编译并执行 → 本轮 374 测试源中有 3 个不在 HEAD(HEAD 纯度 371);一旦有人 `git clean` 即永久丢失。
+- **② 测试 bug 点**:`cfc-backend/src/test/java/com/etotem/cfc/config/GrowthPublicEndpointMappingTest.java` 等 3 文件;`GrowthPublicEndpointMappingTest` 当前 **5E**(环境/映射断言)。
+- **③ 最优修改方案**:由研发确认归属后入库(`git add` 三者),或明确废弃则删除;`GrowthPublicEndpointMappingTest` 5E 需先修到绿再入库。
+- **④ 修改目的**:让「执行过的用例」=「仓库里的用例」,保证基线纯度与可复现。
+- **⑤ 闭环**:`git status` 对测试目录零 `??`;全量跑测的测试源数 = `git ls-files` 数。
+
+### P-173-6(P2,测试基础设施)Playwright 启动即被 safe-delete 守卫拦截
+- **① 问题描述**:本轮 `shop-api`、`dx-bridge`、`api` 三组套件首次启动均在**跑用例前**中断:`Error: [safe-delete][SAFE_DELETE_BULK_GUARD_ERROR] state lock timeout`(shim 在清理 `outputDir`/`test-results` 时被守卫拦下)。人工先 `mv` 掉旧产物目录后同一命令即 4/4、2 跳过、25 过。
+- **② 测试 bug 点**:`tests/playwright.config.live.js:26` / `tests/playwright.config.health.js:16`(`outputDir` 固定且每次启动清理);执行脚本无 `--output` 参数。
+- **③ 最优修改方案**:所有 Playwright 调用统一追加 `--output=_art/<runid>`(一次性目录,跑完不删);或在 CI 侧设置 `PLAYWRIGHT_HTML_*`/`preserveOutput: 'always'`。
+- **④ 修改目的**:消除「工具链自身把测试拦住」的假失败,保证无人值守与 CI 可复现。
+- **⑤ 闭环**:连续 3 次无人干预跑通全部 4 组浏览器/API 套件(无 safe-delete 报错)即闭环。
+
+### P-173-7(P2,性能)后端全量耗时显著劣化
+- **① 问题描述**:本轮 `mvn -o -B clean test` 耗时 **51:52**(R171 为 45m,R172 采信未跑),368 类平均 8.5s/类但分布极不均;并发负载仅为前端/管理端 Jest(合计 84s)与浏览器套件(~3.5m),不足以解释全部劣化。
+- **② 测试 bug 点**:`cfc-backend/src/test` 中 `@SpringBootTest` 类上下文反复启动(`CfcApplication:12 @EnableScheduling` 使 `cfc-scheduler-*` 线程常驻),慢类:`GrowthPublicEndpointMappingTest` 237s / `ActivityControllerTest` 104s / `ArticleCategoryControllerTest` 99s / `GuideRolePermissionTest` 94s。
+- **③ 最优修改方案**:抽 `AbstractSpringTest` 统一 `@SpringBootTest(webEnvironment=NONE)` + `spring.main.lazy-initialization=true`,并复用上下文缓存;`@EnableScheduling` 在 test profile 关闭。
+- **④ 修改目的**:把全量回归压回 45 分钟以内,使「每轮全量」在时间上可持续。
+- **⑤ 闭环**:同机同 HEAD 连续 2 轮全量 ≤50m 且类数/例数不变。
+
+### P-173-8(P2,环境)根级黑盒 16 红(9082 未监听)
+- **① 问题描述**:`tests && npx jest` → 7 过 / 16 红,全部 `ECONNREFUSED 127.0.0.1:9082`;属环境未起而非产品缺陷,但长期占用 G2 红例名额。
+- **② 测试 bug 点**:`tests/integration/plan-chain.spec.js:21-22`(依赖 `ADMIN_PHONE`/`ADMIN_PASSWORD` 且无 `webServer` 自启)。
+- **③ 最优修改方案**:jest `globalSetup` 起 `webServer`(或 `testEnvironment` 前置探活 + `describe.skip`),并注入 `tests/.env.test`。
+- **④ 修改目的**:让「红」只代表真实缺陷,避免环境红稀释门禁信号。
+- **⑤ 闭环**:后端未启时 16 例转 **skip**(而非 fail),G2 红数下降 16。
+
+### P-173-9(P2,工具)langgraph pytest 退出码未落盘(第 6 轮)
+- **① 问题描述**:`/tmp/r173_pytest.log` 末行为 `5 failed, 46 passed ... 129.33s`,**无 `EXIT=` 行** → 无法据此判断进程是否正常退出(CI 会误判)。
+- **② 测试 bug 点**:`docs/tdd/tools/dispatch_251_pytest.cjs:40`(kick 串里 `$?` 展开时机)。
+- **③ 最优修改方案**:kick 串统一写成 `bash -c '...; rc=$?; echo EXIT=$rc >> LOG'` 并用单引号包裹整段,禁双引号。
+- **④ 修改目的**:让「用例全绿」与「进程正常退出」两个结论都可取证。
+- **⑤ 闭环**:连续 2 轮日志末尾出现 `EXIT=0` 即闭环。
+
+---
+
+## 八、门禁结论
+
+| 门禁 | 项 | 阈值 | 实测 | 判定 |
+|---|---|---|---|---|
+| G1 | 全量通过率 | ≥98% | **97.79%**(剔 skip 98.41%) | ❌ |
+| G2 | 存量红例 | ≤5 | **63**(后端 39 + 根级 16 + 前端 3 + lg 5;其中存量装置 18、未入库 5、预期 RED 19、环境 21) | ❌ |
+| G3 | 前端 Jest | 0 红(除预期 RED) | 609 过 / 3 红(全 S-cfc-132/133 预期 RED)/ 12 跳 | ⚠️ |
+| G4 | 管理端 Jest | 100% | 116/116 | ✅ |
+| G5 | 编译与产物完整性 | 0 错、无沉默类 | 2121 主源 + 374 测试源 0 错;368 类 / 368 XML,0 沉默 / 0 dump | ✅ |
+| G6 | 浏览器 E2E | 100%(skip 需有据) | 28/28 + 2 skip(dx 端点 404,B-DX-1) | ✅ |
+| G7 | langgraph | 100% | 46/51(5 红全 429/401 环境) | ❌ |
+| G8 | 线上匿名鉴权 | 全 401 | 6/6 = 401(含 `/api/admin/families/overview`) | ✅ |
+| G9 | 可执行锚点覆盖 | ≥80% | 13.4%(官方口径)/ ~20%(严格口径) | ❌ |
+| G10 | 双节点派发 | 189 + 251 均成功 | 189 admin 5/5 EXIT=0 + 251 pytest 46/51 | ✅ |
+| G11 | CI 硬门禁可用 | 能红能绿 | `BACKEND_OBSERVED_CLASSES`(33 类)**漏拦 8 类**(GrowthPublic / WechatLogin×2 / 3 个新契约 / TaskReviewScP11 / TeamProfitCron)+ **26 类已绿仍排除**(第 9 轮) | ❌ |
+| G12 | 需求变更→用例同步 | 变更即更新 | 窗口零 SRS/场景变更 → 零新增(合规) | ✅ |
+| G13 | 零漂移 | 存量红逐例一致 | 后端存量 18 例(11 类)+ 未入库 5E 与 R171 逐类逐例一致(**第 19 次**) | ✅ |
+| G14 | 场景→用例映射 | ≥80% | 72.1%(155/215) | ❌ |
+
+**总判定:不通过(承袭)**。可用性维度的核心卡口未变:**G2 红例超阈、G7 langgraph 上游未恢复、G9/G14 追溯不足、G11 CI 门禁失真**。相对 R172 的唯一正向是 langgraph 45→46 与后端由采信转实跑(证据强度提升),无任何产品级新增缺陷。
+
+---
+
+## 九、方法论沉淀(本轮新增)
+
+1. **251 派发的日志路径禁止走本地 env 注入**——`LOG=/tmp/x node dispatch.cjs` 会被 Git Bash 的 MSYS 路径转换为 `C:/Users/.../x`,远端 `tail` 恒报 `No such file`,看起来像「日志未生成」;正解是把远端路径写在**传入的 command 字符串**里(`run "tail -c 3000 /tmp/x"`),不经 env。
+2. **「套件跑不起来」要先分层:环境 → 工具链 → 用例**——本轮 3 组 Playwright 套件在**用例执行前**即失败(守卫拦截 `outputDir` 清理),若按「浏览器红」记入 G2 会凭空多 8 个假红。判据:日志里有没有 `Running N tests`。
+3. **同一配置文件,带参数与不带参数可能是两个口径**——`playwright.config.api.js` 不点名文件收集 990 例、点名 4 文件 32 例;报告里的例数必须与命令行一一对应,否则跨轮对比失真(B-173-2)。
+4. **慢 ≠ 卡死**:全量耗时劣化要先看 `Time elapsed` 分布与 `cfc-scheduler` 线程数,本轮 4 个慢类占约 45% 时长。
+5. **未跟踪测试文件必须在报告里显式声明**:本轮 374 测试源中 3 个不在 HEAD(B-162-1),否则「HEAD 纯度」结论会被污染。
+
+---
+
+## 附录 A:本轮命令(可复现)
+
+```bash
+# 后端全量
+cd cfc-backend && JAVA_HOME=/d/jdk1.8.0_25 /d/maven/apache-maven-3.6.1/bin/mvn -o -B clean test
+
+# 管理端 / 前端 / 根级
+cd cfc-web       && npx jest --ci
+cd cfc-frontend  && npx jest --ci
+cd tests         && npx jest --ci
+
+# 浏览器(本机;每次需给一次性 --output)
+cd tests && npx playwright test -c playwright.config.live.js --project=frontend-mobile --reporter=list --workers=1
+cd tests && npx playwright test -c playwright.config.live.js --project=shop-api        --reporter=list --workers=1
+cd tests && npx playwright test -c playwright.config.health.js                        --reporter=list --workers=1
+cd tests && npx playwright test -c playwright.config.live.js --project=dx-bridge      --reporter=list --workers=1
+
+# 线上 API(必须点名 4 文件,否则收集 990 例)
+cd tests && npx playwright test -c playwright.config.api.js --reporter=list --workers=1 \
+  e2e/api/api-smoke.spec.js e2e/api/nonfunc-security.spec.js \
+  e2e/api/nonfunc-perf-compat.spec.js e2e/api/traceability-p94-p95-c26.spec.js
+
+# 189 admin(远程 PowerShell)
+node docs/tdd/tools/dispatch_189_admin.cjs
+
+# 251 langgraph(kick → 单次读)
+node docs/tdd/tools/dispatch_251_pytest.cjs run "rm -f /tmp/r173_pytest.log; setsid nohup bash -c 'cd /sc-data/cfc/cfc-langgraph && .venv/bin/python -m pytest -q --ignore=tests/qna --ignore=tests/test_chat.py > /tmp/r173_pytest.log 2>&1; echo EXIT=\$? >> /tmp/r173_pytest.log' >/dev/null 2>&1 & echo KICKED"
+node docs/tdd/tools/dispatch_251_pytest.cjs run "tail -c 3000 /tmp/r173_pytest.log"
+
+# 度量
+python docs/tdd/tools/test_report_metrics.py --repo-root . --scene
+```
+
+## 附录 B:未实测与未授权项(不得视为通过)
+
+| 维度 | 状态 | 原因 |
+|---|---|---|
+| 变异测试 | 未实测 | 仓库无 PIT/Stryker,离线档无工具 |
+| SAST / 依赖漏洞扫描 | 未授权未执行 | 需联网(本机无显式联网授权) |
+| 真实压测 | 未授权未执行 | execute 档,需单独联网授权 |
+| 无障碍 / 可用性 | 无资产 | 仓库无 axe/WCAG 与量表 |
+| 微信真机 / 支付扣款 | 排除 | 涉资金与真机,需人工介入 |

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

@@ -1103,3 +1103,15 @@
 | **B-153-1-Update(第 13 轮销号维持)** | 189 admin U05 前置偶发 | 测试(观察项) | **维持销号**。连续 13 轮首轮即 5/5(本轮 1.2m EXIT=0)。 | 测试(R172 实派) | 2026-11-12 18:20 | 已销号 |
 | **B-167-1-Update(观察 5/4,维持销号)** | 189 admin `account-roles` 502 | 环境/网络(P2) | **维持销号**。连续 5 轮首跑 5/5(无 502)。 | 测试(R172 实派) | 2026-11-12 18:20 | 已销号 |
 | **R172 门禁** | 全量 3979 / 3890 | 测试 | **不通过(承袭,结构性进账/环境回摆)**。✅G4 116-116/G5 编译 0 错 dump 0/G6 28-28/G8 6-6 全 401/G10 三节点(189 5/5 + 251 51 例 + 本机)/G12 SRS 零变更/G3 609-624(3 预期 RED);❌G1 97.76%(剔 skip 98.38%)/G2 64 红(后端 39 + 根级 16 + lg 6 + fe 3)/G7 45-51(88.24%)/G9 ~20.7%/G11 CI 必红/G14 ~58.2%;⚠️G13 存量红零漂移(第 18 次)。变化 = +46 契约例(30 绿/16 预期 RED)+ lg 环境红 1→6。 | 测试(R172 闭环) | 2026-11-12 18:20 | 已记录 |
+| **B-173-1** | Playwright 启动即被 safe-delete 守卫拦截 | 测试/CI(P2 新登记) | **新登记**。本轮 `shop-api`、`dx-bridge`、`api` 三组套件首次启动均在 **`Running N tests` 之前**中断:`Error: [safe-delete][SAFE_DELETE_BULK_GUARD_ERROR] state lock timeout`(shim 清理 `outputDir`/`test-results` 时被守卫拦下,10s helper 超时)。人工 `mv` 旧产物目录后同一命令即 4/4、2 skip、25 过。**判据:日志里没有 `Running N tests` 就不是用例红,不得计入 G2。** 建议所有 Playwright 调用固定 `--output=_art/<runid>` 一次性目录。 | 测试(R173 实测) | 2026-11-12 19:55 | 待处理 |
+| **B-173-2** | `playwright.config.api.js` 默认收集 990 例,门禁口径可放大 31 倍 | 测试/CI(P1 新登记) | **新登记**。`tests/playwright.config.api.js:18` `testMatch: /api[\/].*\.spec\.js$/` 覆盖 `e2e/api/generated/**` → 不带文件参数运行时 `Running 990 tests`;R172/R173 报告的「32 例」实为**点名 4 文件**的结果(api-smoke / nonfunc-security / nonfunc-perf-compat / traceability-p94-p95-c26)。CI 若直跑该 config 将产生大量 401/404 假红并对线上发起近千请求。修正:`testMatch` 收窄为 4 文件白名单,`generated/**` 单列 project 默认不跑。 | 测试(R173 实测) | 2026-11-12 19:55 | 待处理 |
+| **B-173-3** | 后端全量耗时劣化(51:52 vs R171 45m) | 研发/测试(P2 新登记) | **新登记**。368 类 / 51:52,平均 8.5s/类但分布极不均:`GrowthPublicEndpointMappingTest` 237s、`UserServiceFamilyNameLinkTest` 168s、`ActivityControllerTest` 104s、`ArticleCategoryControllerTest` 99s、`GuideRolePermissionTest` 94s、`StatsControllerTest` 91s(前 6 类约占 45%)。并发负载仅 Jest 84s + 浏览器 ~3.5m,不足以解释全部。建议抽 `AbstractSpringTest` 关闭 `@EnableScheduling` 并复用上下文缓存。 | 研发/测试 | 2026-11-12 19:55 | 待处理 |
+| **B-142-2-Update(第 7 轮)** | 251 langgraph 上游 429/401 | 研发/运维(P0) | **改善(红 6→5)**。51 例 **46 过 / 5 红 / 129.33s**;5 红 = `test_auto_tag` 3 + `test_intent` 2;日志 `RateLimitError 429 AgnesAI free limit` ×7 + `chat_graph.py:148 401 ****ab12 invalid` ×3。同窗口 live `/health` 200(8.9ms) 但 `/api/v1/chat` 与 `/api/v1/analyze` 均 **000/150s 零字节** → 服务活、LLM 链路挂死。**B-142-2 不销号(观察 0/2)**。 | 研发/运维 | 2026-11-12 19:55 | 待处理 |
+| **B-152-1/2-Update(第 9 轮)** | CI `BACKEND_OBSERVED_CLASSES` 双向失真 | CI(P0/P1) | **恶化(漏拦 5→8 类)**。清单 33 类 vs 本轮实测红类 15 类:**漏拦 8 类**(GrowthPublicEndpointMappingTest、MembershipPlanPurchaseContractTest、ShopOrderQueryRefundContractTest、SupplierOrderFulfillContractTest、TaskReviewScP11ContractTest、TeamProfitCronContractTest、UserServiceWechatLoginContractTest、UserServiceWechatLoginTest)+ **陈旧已绿 26 类** → `backend-blocking-junit` 必红且覆盖虚化。 | CI/研发 | 2026-11-12 19:55 | 待处理 |
+| **B-162-1-Update(第 5 轮)** | 3 个测试类未入库却被编译执行 | 治理(P1) | **延续**。本轮 `testCompile` 374 源 vs HEAD `git ls-files` 371 源 → `GrowthPublicEndpointMappingTest`(5E)、`JwtInterceptorGrowthPolicyTest`、`ArticleTagsContractTest` 仍为 `??`。HEAD 纯度口径 = 371 类。 | 研发/测试 | 2026-11-12 19:55 | 待处理 |
+| **B-126-Update(第 6 轮)** | langgraph pytest 退出码未落盘 | 测试工具(P2) | **复现**。`/tmp/r173_pytest.log` 末行为 `5 failed, 46 passed ... 129.33s`,**无 `EXIT=` 行** → 不能据 summary 判正常退出。修法:kick 串用单引号 `bash -c '...; rc=$?; echo EXIT=$rc >> LOG'`。 | 测试 | 2026-11-12 19:55 | 待处理 |
+| **B-36-Update(第 59 轮零漂移)** | 根级黑盒 23 例 16 红 | 测试(P2 环境) | **零漂移**。`tests && npx jest --ci` → **7 过 / 16 红 / 23**(8.8s),全 `ECONNREFUSED 127.0.0.1:9082`。 | 测试 | 2026-11-12 19:55 | 待处理(环境型) |
+| **B-95-Update(第 33 轮)** | `192.168.16.204:4090` 失联 | 运维(P2) | **延续**。`204:4090` → 000;同期 189:4090=200、251:4096=200、251:9000 `/health`=200。 | 运维 | 2026-11-12 19:55 | 待处理 |
+| **B-142-1-Confirm(销号维持第 8 轮)** | `/api/admin/families/overview` 匿名 200+code:400 | 研发(已闭环) | **维持销号**。匿名 6 端点全 **401**(mind/energy/health-plan/huawei/xiaomi/admin-families)。 | 测试(R173 实测) | 2026-11-12 19:55 | 已销号 |
+| **B-DX-1-Update(第 25 轮)** | dx-bridge 端点 404 | 部署(P2) | **延续**。dx 2 例 skip(不假绿)。 | 部署/运维 | 2026-11-12 19:55 | 待处理 |
+| **R173 门禁** | 全量 3979 / 3891 | 测试 | **不通过(承袭)**。✅G4 116-116 / G5 368 类 368 XML 0 沉默 0 dump / G6 28-28 / G8 6-6 全 401 / G10 双节点(189 5/5 EXIT=0 + 251 46-51)/ G12 SRS 零变更 / G13 存量红零漂移第 19 次;⚠️G3 609-624(3 预期 RED);❌G1 97.79%(剔 skip 98.41%)/ G2 63 / G7 46-51 / G9 13.4%(官方口径)/ G11 漏拦 8 类 / G14 72.1%。 | 测试(R173 全量实跑) | 2026-11-12 19:55 | 结论已发布 |