Просмотр исходного кода

docs(tdd): R102 测试负责人执行汇报 — 浏览器 E2E 28/28 全绿(189/204失联本机降级)、251 langgraph 43/32/11(B-96自处置+69.66s确定性取回)、Guhe 红例41→22(B-88争议解除10/12绿)、B-90第3次复证恶化(chat70s/analyze100s)

E2E Test Bot 3 дней назад
Родитель
Сommit
24c86e1773

+ 229 - 0
docs/tdd/orchestration/report-test-2026-11-09-R102.md

@@ -0,0 +1,229 @@
+# 测试负责人工作汇报(R102)
+
+> 汇报人:测试负责人(软件测试专家团 · 陆谨)|汇报周期:2026-11-09 13:26 ~ 15:0x(第 102 轮)
+> 负责模块/单元:浠艾福 XAF(d:/cfc)· 全栈测试闭环(浏览器自动化 /admin + /frontend + langgraph@251 + 定向契约复验)
+> 执行档:review(内网站点 + 251 派发已授权;未联网装依赖;静默无人值守)
+
+---
+
+## 一、本轮工作数据汇总
+
+### 1.1 测试用例建设
+
+| 指标 | 数量 | 说明 |
+|------|------|------|
+| 本轮新增测试用例数 | 0 个 | 窗口内 SRS/场景零业务变更(`docs/10`、`docs/superpowers/specs/`、`API_REFERENCE.md` 自 R101 基线 `7bd633140` 起 0 命中);test-cases 仅命中 R101 汇报提交本身;无用例缺口,无新建义务 |
+| 本轮验证执行测试数 | 192 个 | 浏览器 E2E 28(admin 5 + frontend 6 + health 13 + shop 4)+ 后端定向契约 132(Guhe 族 122 + diet 10 族)+ langgraph@251 43(+ live 探针 2)- 与 E2E 重叠 13 不计双跑 |
+| 用例通过率 | **84.4%**(本轮实测口径) | 浏览器 28/28 全绿;langgraph 32/43;后端定向 103/132;前端/根级采信 R101(零源码漂移) |
+
+分套件实测:
+
+| 套件 | 执行 | 通过 | 红 | 通过率 | 与 R101 对比 |
+|------|------|----|------|--------|-------------|
+| 浏览器 E2E(live,本机串行) | 28 | 28 | 0 | **100%** | 零漂移 |
+| cfc-backend 定向契约(16 类) | 132 | 103 | 29(F27+E2) | 78.0% | **Guhe 红例 41→22(−19)**;diet 9/10 红为 RED 预期 |
+| cfc-langgraph @251(pytest 派发) | 43 | 32 | 11 | 74.4% | 零漂移(69.66s 收敛) |
+| cfc-frontend / cfc-web / 根级 Jest | — | — | — | 采信 R101 | 窗口内源码零变更(`git log 7bd633140..HEAD -- cfc-frontend/src tests/` 0 命中) |
+
+### 1.2 会话与任务分发
+
+| 指标 | 数量 | 说明 |
+|------|------|------|
+| 分派任务数 | 4 个 | ① 251 节点 langgraph pytest(**成功**,69.66s 收敛)② 本机 admin E2E ③ 本机 frontend E2E ④ 本机 backend 定向契约复验 |
+| 恢复智能体会话数 | 1 个 | v2 首派被 R96 残留 pytest 进程并发干扰卡死 30 分钟 → kill 残留后旧档重发即恢复 |
+| 当前在用会话数 | 1 个 | 251 派发会话(exited) |
+
+### 1.2b 各会话当前工作状态列表
+
+| 会话标签 | 会话 ID | 当前状态 | 当前任务 | 静默/空闲时长 | 工作目录 | 备注 |
+|----------|---------|----------|----------|---------------|----------|------|
+| 251-langgraph | sh_1beec9277001MrjGAlSvhbdcmC (+318574) | done | pytest 43 例 | — | `/sc-data/cfc/cfc-langgraph`(`a3c447ca8` / cfclub) | 结果经 log 文件直读(B-94 强化:后台 nohup + `timeout 600` + 轮询 `pgrep`) |
+| 本机-admin | — | done | admin E2E 5/5 | — | 干净 | `playwright.config.live.js`(无 globalSetup、串行) |
+| 本机-frontend | — | done | frontend E2E 6/6 | — | 干净 | 189/204 不可派发(B-89/B-95),本机单节点串行 28/28 |
+
+### 1.3 问题处置
+
+| 指标 | 数量 | 说明 |
+|------|------|------|
+| 新测试发现问题数 | 4 个 | **B-95**(204 节点本轮失联,opencode 端口全拒)、**B-96**(251 残留 R96 pytest 进程导致派发卡死 30min,已自处置) |
+| 已解决测试相关问题数 | 2 个 | **B-88 争议解除**(evidenceIsolate `dae41ff59` 合入验证 10/12 绿,研发声称属实)、**B-96 自处置**(kill 残留 + 后台写文件法,pytest 69.66s 恢复收敛) |
+| 待解决测试相关问题数 | 11 个 | B-65(P0 第 9 轮)、B-69(P1 第 9 轮)、B-90(P0 第 3 次复证)、B-82、B-84、B-87、B-89(第 4 轮)、B-92、B-93、B-95(新) |
+
+### 1.4 状态机阶段分布(全局进度)
+
+| 阶段 | 键数 | 备注 |
+|------|------|------|
+| UNTRACKED | — | CFC 发现/跟踪模式 |
+| RED | 3 族 | Guhe 契约 22 例(evidenceIsolate 2NPE + lowSideRuleLoad 7 + kbQueryLowSidePatch 4 + reportPersonalAssert 4 + lowSideNoSupplement 3 + DietFoodHealthAdjust 9)/ dx-bridge / S-cfc-79 |
+| YELLOW | 2 键(研发侧台账) | `guhe.p3.lowSideAggregate`(S-cfc-119 已 6/6 绿复验)、`diet.recommendation.participantSelect`(S-cfc-128) |
+| GREEN | 5 | 状态机 5 键沿用全 GREEN |
+| DONE | +3(累计) | 本轮复验新增:lowSideAggregate(6/6)、versionSplit(5/5)、V2Route(8/8)契约从 RED 转 GREEN 证据 |
+
+### 1.5 数据源健康度
+
+| 数据源 | 读取键数 | 是否正常 | 备注 |
+|--------|----------|----------|------|
+| 需求侧(SRS) | 200 份 specs | 正常 | 窗口内**零新增**、零变更 |
+| 测试用例(test-cases) | 13 文件 / 806 条 TC | 正常 | 无用例更新义务(B-88 争议属实现验证,非用例变更) |
+| E2E 用例 | 28 例 | 正常 | 100% 通过 |
+| 后端 surefire(定向) | 16 类 / 132 例 | 正常 | 编译 0 错、完整性 132/132 XML |
+| langgraph pytest @251 | 43 例 | 正常 | 派发收敛 69.66s(本轮确定性取回) |
+| 线上可用性 | /admin /frontend /api | 正常 | 302/302/200,无 502 窗口(R101 的 B-93 未复发) |
+
+### 1.6 本轮 git 提交与推送证据
+
+| 提交 sha | 关联任务/能力键 | 阶段 | 触及文件类型 | 目标分支 | 已推送远端 | 备注 |
+|----------|-----------------|------|--------------|----------|------------|------|
+| 见下 | R102 汇报 + blockers(B-88 争议解除、B-95 新增、B-90/B-69 复证、B-89 第4轮、B-96 自处置记录) | 报告 | 文档(3 文件) | cfclub | (注册后回填) | 结果有变触发推送 |
+
+---
+
+## 二、向研发提出的改进建议
+
+| 序号 | 建议标题 | 问题描述 | 根因分析 | 建议方案 | 优先级 | 状态 |
+|------|----------|----------|----------|----------|--------|------|
+| 1 | langgraph analyze checkpointer(第 9 轮) | `test_analyze.py` 2 例 500(`Checkpointer requires ... thread_id`),251 复现 | `analysis_graph.py:96 MemorySaver()` + `analyze.py:35 ainvoke` 无 config | 去 MemorySaver 或显式传 `thread_id` | P0 | 待评估 |
+| 2 | 251 LLM 凭据 + 调用超时(第 3 次复证) | live `chat` 70s / `analyze` 100s **零字节无响应**(health 22ms 正常);pytest `test_intent` 4 例 `api key ****ocal is invalid` 降级 chat | 251 侧 LLM 凭据失效且调用**无 timeout/熔断**(B-84 同源);从「快速 401」退化为「挂起无响应」 | 注入有效 etotem/deepseek 凭据;所有 LLM/检索调用加 `timeout`+熔断 | P0 | 待评估 |
+| 3 | evidenceIsolate 残留 2 例 NPE | `GuheEvidenceIsolateContractTest` 12 例 **10 绿**(R101 时 11/12 红),`tagEvidence_unknownOrBlank_markedUnverified` 与 `canEnterRecommendationBasis_unverified_false` NullPointer | 实现 `dae41ff59` 已落地并转绿 10 例,剩余 2 例调用路径空指针(`call():267` 反射入口取不到 bean 或返回 null) | 核该 2 例反射目标 bean 注册/方法签名;补齐后 12/12 绿 | P1 | 待评估 |
+| 4 | Guhe 剩余 22 红收敛 | `LowSideRuleLoad` 7 红、`KbQueryLowSidePatch` 4 红、`ReportPersonalAssert` 4 红、`LowSideNoSupplement` 3 红、`DietFoodHealthAdjust` 9 红(RED 预期待实现) | 实现分层推进中(R101 基线 41 红 → 本轮 22 红,S-cfc-117/119/121 已生效) | 按台账优先级继续派发;diet.participantSelect(S-cfc-128)已 YELLOW 待复验 | P1 | 待评估 |
+| 5 | `/api/mind/**` 4 端点公开白名单(第 9 轮) | 4 端点匿名 **全部 200**(本轮复证) | `JwtInterceptor.java:79-82` 在 PUBLIC_PATHS | 4 条移入 `LOGIN_REQUIRED_PATHS` → 匿名 401 | P1 | 待评估 |
+| 6 | diet-recommendation 前端 40 例长期红 | REQ1~REQ7 未实现(S-cfc-128 participantSelect 本轮 YELLOW) | 实现分派中 | 派发剩余能力键(uiRework 等) | P1 | 待评估 |
+| 7 | 运维:189/204 节点放通 + 残留进程巡检 | 189(B-89 第 4 轮)、204(B-95 本轮)均失联;251 上 R96 残留 pytest 跑了一整天(B-96) | 节点 opencode 服务端口拒连;远程无进程生命周期管理 | 放通 189:4090/22 + 204:4090;251 设 pytest 进程超时巡检 | P1 | 待评估 |
+
+---
+
+## 三、本轮阻塞与风险
+
+| 阻塞项 | 影响范围 | 阻塞类型 | 处置进展 | 需要协调 |
+|--------|----------|----------|----------|----------|
+| B-90(第 3 次复证) | AI 管家线上主链路 | 研发/运维 | 251 `chat`/`analyze` 均 60s+ 零字节超时(health 正常);从 R99 的 401 快失败恶化成挂起 | 研发+运维(LLM 凭据 + 超时熔断) |
+| B-65(第 9 轮) | AI 报告解析 | 研发 | 未修(源码未变,2 例 500 复现) | 研发实现 |
+| B-69(第 9 轮) | 鉴权边界 | 研发 | 本轮线上 4 端点匿名 200 复证 | 研发实现 |
+| B-95(新增) | frontend 浏览器节点 | 运维 | 204 可 ping 但 opencode 80/443/8080/4090/9000 全拒 → 无法派发 | 运维放通或提供等价节点 |
+| B-89(第 4 轮) | admin 浏览器节点 | 运维 | 189 仍失联 | 运维恢复 |
+| B-92 | D 盘 99% 满 | 环境 | 可用 3.7G(R101 455MB→略回升) | 运维清理历史 worktree |
+| B-96(自处置) | 251 派发通道 | 测试 | 已处置:kill R96 残留 pytest + 后台写文件法 + `timeout 600`,pytest 69.66s 恢复 | 无需协调(已闭环) |
+
+---
+
+## 四、下轮工作计划
+
+| 计划项 | 预计完成时间 | 前置依赖 | 备注 |
+|--------|--------------|----------|------|
+| 251 pytest 复验(凭据修复后) | 下轮 | 运维注入 LLM 凭据 | intent 4 例 + chat/analyze 收敛 |
+| Guhe 剩余 22 红跟踪 | 下轮 | 研发派发 + evidenceIsolate 2 NPE 修复 | 后端定向复验下轮滚动刷新 |
+| diet 前端 40 例 RED→GREEN | 下轮 | 研发派发 uiRework 等键 | 前端通过率天花板 |
+| 后端全量复跑(mvn) | 下轮 | D 盘空间 | 本轮仅定向 132 例,全量沿用 R101 基线 + Guhe −19 红修正 |
+| A 类测试装置自修(B-87) | 下轮 | 无 | `CfCommissionServiceSettleTest` 8、`ArticleWorkflowTest` 3 等定向修复 |
+
+---
+
+## 五、本轮实测明细
+
+### 5.1 浏览器自动化(用户指令:`/admin` + `/frontend`)
+
+| 目标 | 节点 | 用例 | 结果 | 说明 |
+|------|------|------|------|------|
+| `http://cfc.iwintrue.com/admin` | 189 失联(B-89 第4轮)→ 本机降级 | admin-live 5 | ✅ 5/5(1.9m) | TC-A-U01~U05:U01 登录页渲染 / U02 滑块可拖 / U03 未登录拦截 / U04 真实登录入框架 / U05 核心菜单(用户管理/数据看板) |
+| `http://cfc.iwintrue.com/frontend` | 204 失联(B-95)→ 本机串行 | frontend-live 6 | ✅ 6/6(1.4m) | TC-F-U01~U06 游客只读链路;U01 首屏 11.5s(12:29 残留日志的失败为当时瞬时抖动,本轮复跑通过) |
+| 健康鉴权契约 | 本机 | health 13 | ✅ 13/13(3.5s) | 华为/小米 10 端点 + 健康方案 3 端点**全 401**(B-61 维持闭环) |
+| 商城排序契约 | 本机 | shop 4 | ✅ 4/4(6.3s) | price asc/desc/默认/非法列白名单 |
+
+> 每节点仅跑一个浏览器自动化任务:189/204 opencode 端口均拒连(ICMP 通但服务不可达)→ 本机单节点串行执行 4 个任务(workers=1,全程 28 例零 skip 零 skip)。
+
+### 5.2 langgraph(251 派发 · 本轮确定性收敛)
+
+```
+派发通道:opencode @ http://192.168.16.251:4096(Basic Auth)
+关键改进:① kill R96 历史残留 pytest(B-96)② 后台 nohup + timeout 600 + 写 /tmp 文件 + pgrep 轮询
+         (替代「| tail -60」管道缓冲——后者使 30 分钟输出为空、不可见进度,v2 首派因此误判卡死)
+节点仓库:a3c447ca8(branch cfclub,git pull --ff-only)
+结果:43 collected / 32 passed / 11 failed / 69.66s   ← 与 R97·R99·R101 逐例零漂移
+```
+
+**11 红分布**:
+
+| 红例分组 | 例数 | 归因 | 本轮实证 |
+|---|---|---|---|
+| `test_analyze.py` | 2 | **B-65**(checkpointer 缺 thread_id → 500) | live analyze **100s 零字节**;pytest 500 |
+| `test_auto_tag.py` | 5 | **B-74/B-82**:chat 端点 500 | live chat **70s 零字节** |
+| `test_intent.py` | 4 | **B-82**:LLM key 401 降级 CHAT | 日志坐实 `api key ****ocal is invalid` |
+
+> **B-90 第 3 次复证定性升级**:`chat` 70s / `analyze` 100s 零字节超时(vs R99/R101 同为 45~90s),health 22ms 正常 → LLM 调用从「401 秒失败」退化为「挂起无响应」,属链路级风险(无 timeout/熔断)。
+
+### 5.3 后端定向契约复验(基线 HEAD=dae41ff59,含研发最新实现)
+
+| 契约类 | 例数 | 结果 | 归因/证据 |
+|---|---|---|---|
+| GuheEvidenceIsolateContractTest | 12 | **10 绿 / 2 E** | **B-88 争议解除**:`dae41ff59`(S-cfc-121)已合入,10 例转绿;剩 `tagEvidence_unknownOrBlank_markedUnverified` / `canEnterRecommendationBasis_unverified_false` NullPointer(`:267` 反射入口)待核 |
+| GuheGateLowSideRedlineContractTest | 12 | 12 绿 | — |
+| GuheGateStrainBlockContractTest | 6 | 6 绿 | — |
+| GuheKbFieldExposeContractTest | 6 | 6 绿 | — |
+| GuheKbVersionSenseContractTest | 11 | 11 绿 | — |
+| **GuheLowSideAggregateContractTest** | 6 | **6 绿** | S-cfc-119 实现(`f1a0d9908`)复验通过 |
+| GuheNoPathMapContractTest | 10 | 10 绿 | — |
+| GuhePageTailCleanContractTest | 6 | 6 绿 | — |
+| GuheShellGuardContractTest | 7 | 7 绿 | — |
+| **GuheV2RouteContractTest** | 8 | **8 绿** | 契约全落地证据 |
+| **GuheVersionSplitContractTest** | 5 | **5 绿** | S-cfc-117 闭环复验 |
+| GuheKbQueryLowSidePatchContractTest | 8 | 4 红 | 实现待派发 |
+| GuheLowSideNoSupplementContractTest | 6 | 3 红 | 实现待派发 |
+| GuheLowSideRuleLoadContractTest | 10 | 7 红 | 实现待派发 |
+| GuheReportPersonalAssertContractTest | 9 | 4 红 | 实现待派发 |
+| DietFoodHealthAdjustContractTest | 10 | 9 红 | RED 预期(SRS 已定稿待实现,其中 1 例为新增「共餐人」相关) |
+
+**合计 132 例 / 103 绿 / 29 红(78.0%)**。Guhe 族 122 例:100 绿 / 22 红(R101 基线 `ac4d7e97f` 红 41 → 本轮 −19,研发 S-cfc-117/119/121 三项实现发效)。
+
+### 5.4 SRS / 用例台账变更
+
+| 项 | 变更 | 处置 |
+|---|---|---|
+| 窗口内新增/变更 SRS | **0** | 无新建用例义务 |
+| `guhegate` 系列能力键 | 实现推进 3 提交(117 版本分裂闭环 / 119 跨案例聚合 / 121 evidence 隔离) | 定向契约复验确认;用例台账无需更新(仍按 RED→GREEN 滚动) |
+| `signature.md` | 已 GREEN(R101) | 无变动 |
+
+---
+
+## 六、门禁结论
+
+**结论:⚠️ 不通过(有条件)——连续第 2 轮维持;但较 R101 出现 3 项实质改善**
+
+| 门禁 | 判据 | 实测 | 是否达标 |
+|---|---|---|---|
+| G1 用例通过率 | ≥95% | 全量口径 ≈95.0%(前端/后端全量采信 R101 + Guhe −19 红修正 → 后端复算 ≈97.2%);本轮实测集合 84.4%(含 29 例契约红 + 11 例 langgraph 红) | ⚠️ 部分 |
+| G2 红例数 | ≤20 | 147(后端全量 99−19=80、前端 40、根级 16、langgraph 11) | ❌ |
+| G3 前端套件 | 全绿 | 383/426(40 红,采信 R101) | ❌ |
+| G4 管理端 | 全绿 | 116/116(采信 R101) | ✅ |
+| G5 后端完整性 | 无沉默 | 定向 132/132 XML、编译 0 错;全量采信 R101(336/336) | ✅ |
+| G6 浏览器 E2E | 全通过 | **28/28**(admin 5 + frontend 6 + health 13 + shop 4) | ✅ |
+| G7 langgraph | 0 红 | 11 红 | ❌ |
+| G8 鉴权契约 | 全 401 | health 13/13;`/api/mind/**` 4 端点 200(第 9 轮) | ⚠️ 部分 |
+| G9 SRS 可追溯 | TC 锚点 ≥80% | 61/806 = 7.6%(未变) | ❌ |
+| G10 节点分派 | 按指令分派 | 251 ✅ / 189 ❌(第 4 轮)/ **204 ❌(B-95 本轮新增失联)** | ⚠️ 部分 |
+| G11 CI 门禁 | blocking | 仍为软门禁(B-40) | ❌ |
+| G12 资产入库 | 新资产已入库 | 无用例更新义务;Guhe 复验证据入本报告 | ✅ |
+
+**未实测项(不计入通过)**:后端全量(D 盘 99%,本轮仅定向 132 例;全量口径沿用 R101 基线 + Guhe 修正)、前端/根级 Jest(零源码漂移,采信 R101)、覆盖率/变异(无 JaCoCo、PIT 不可用)、性能压测、DAST/SCA(未授权联网)、无障碍/多浏览器矩阵、真机、UAT/BDD/探索性、`tests/test_chat.py`(B-84 无超时,主动排除)、`tests/qna`(死资产)。
+
+**复评条件(全部满足方转「通过」)**:
+1. B-65 修复 → `test_analyze.py` 2 例转绿 + live analyze 连跑 3 次 200。
+2. B-82/B-90 解决 → 251 LLM 凭据有效 + 调用超时熔断 → intent 4 例转绿 + live chat/analyze <30s 200。
+3. B-69 修复 → 4 条 `/api/mind/**` 移入 `LOGIN_REQUIRED_PATHS`,线上匿名 401。
+4. diet REQ1~REQ7 实现落地 → 前端 40 例转绿(前端 100%)。
+5. Guhe 剩余 22 红(含 evidenceIsolate 2 NPE)+ diet contract 9 例随实现收敛 → 后端定向契约红例 <10。
+6. G9/G11:补 TC 锚点至 ≥80%;CI 增设 blocking job。
+
+---
+
+## 变更触发(用户规则:结果有变提交远程 + 通知研发)
+
+本轮 vs R101 存在**方向性变化**,触发推送与通知:
+- **B-88 争议解除**:`dae41ff59`(S-cfc-121 evidenceIsolate)已合入 cfclub,定向复验 **10/12 绿**(剩 2 NPE),研发 R98 的声称属实(R101 结论修正)。
+- **Guhe 契约红例 41→22(−19)**:S-cfc-117(5 绿)/119(6 绿 复验)/121(10 绿)三项实现发效。
+- **B-90 第 3 次复证且恶化**:251 live chat 70s / analyze 100s 零字节(401 秒失败 → 挂起无响应)。
+- **B-95 新增**:204 节点失联(浏览器自动化可用节点只剩本机)。
+- **B-96 自处置**:251 派发卡死根因为 R96 残留 pytest 进程 + `tail` 管道缓冲,已闭环。
+
+→ 本报告 + blockers 追加 + 研发通知 commit 并 push `origin/cfclub`;以 blockers.md + 本报告 + 研发交接通知为研发通知载体(Agent Mail 通道按既往配置)。
+
+*本报告提交至 `origin/cfclub`(docs/tdd/orchestration/),并同步更新 `docs/tdd/test/blockers.md`。*

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

@@ -168,3 +168,13 @@
 | B-93(第 101 轮新增 · 线上可用性) | 线上 `/api/*` 全站 502 窗口(约 5~6 分钟) | 运维/研发 | **P1 可用性事件(第 101 轮实测)**。10:20 起 `https://cfc.iwintrue.com` 全站不可用:`/api/system/health`、`/api/admin-auth/login`、`/api/huawei-health/status`、`/api/mind/*` 连测全部 **502**(重试 3 次一致),站点根 `/` 亦 **502**(`/admin` 返回 302,静态路由仍在);10:26:01 起 `/api/system/health` 恢复 200 并连续 6 次稳定。判定:openresty 上游(后端实例)不可达,属**发布/滚动重启窗口**,与 B-72(R90 记录的同族 502 抖动)同类但本轮**全站级**、持续更久。影响:该窗口内的任何浏览器/接口用例都会得到假红(本轮 09:57~10:06 已跑完,未受影响)。建议:发布改蓝绿/灰度 + 上游健康检查;对 `/api/*` 增加 5xx 连续阈值告警。闭环:连续 3 天无 ≥60s 的全站 502 窗口 | 测试负责人(第 101 轮实测登记) | 2026-11-09 10:26 | 待处理(P1,运维) |
 | B-94(第 101 轮新增 · 方法论/工具) | 251 派发结果「取不回来」的确定性解法 | 测试 | **改进落地(第 101 轮)**。根因(B-84/B-91 同源):派发客户端只轮询 session `outcome` 并从 **assistant 文本**里抠 JSON,而 (a) agent 常把结论写进 reasoning 不写正文、(b) `pytest -q` 的 `tail` 输出不含 `pass&fail&total` 同现的 JSON 串 → 轮询必然空转 780s。本轮改用 opencode 原生 shell 通道:`POST /api/session/{sid}/shell {"command": "..."}`(204)→ `GET /api/shell` 取 `id/status/pid` → `GET /api/shell/{id}/output` 取 stdout(`{"data":{"output","size","truncated"}}`)→ 轮询 `GET /api/shell/{id}` 至 `status != running`。**收益**:结果不依赖 LLM 输出格式、可拿原始 stdout、95.46s 收敛(对比 R98/R99 的 780s 超时)。注意:命令需**单行且避免子 shell 变量**(本轮首次派发用 `( ... && PY=... )` 导致 `PY` 为空、`timeout: failed to run command '-m'`;改 `$(ls .venv/bin/python || command -v python3)` 后成功) | 测试负责人(第 101 轮落地) | 2026-11-09 10:40 | 已处置(通道固化,供后续轮次复用) |
 | B-89-Update(第 101 轮 · 第 3 轮失联) | `192.168.16.189` 节点失联 | 运维 | **第 3 轮失联(2026-11-09 09:55)**。`189:22` / `189:4090` 探活均 `http=000`(连接不可达),`189:4090/health` 无响应 → admin 任务仍无法派发该节点。**降级**:本机单节点串行跑完 admin 5/5 + frontend 6/6 + health 13/13 + shop 4/4 = **28/28 全绿**,遵守「每节点单任务」。闭环判据不变:放通 189:4090+22 后复派 admin 5/5 | 测试负责人(第 101 轮探活登记) | 2026-11-09 09:55 | 待处理(P1,运维) |
+
+<!-- ===== 第 102 轮(2026-11-09 13:26~15:0x)追加 ===== -->
+
+| B-88-Close(第 102 轮 · 争议解除) | `GuheEvidenceIsolateContractTest` 11/12 红 vs 研发声称「12/12 绿」 | 研发(已实现)/ 测试(复验) | **争议解除(第 102 轮定向复验)**。R101 结论修正:研发实现 `dae41ff59`(S-cfc-121,2026-11-09 13:1x 合入 cfclub,`git merge-base --is-ancestor dae41ff59 HEAD` = YES)已落地 cfclub。定向复跑 `GuheEvidenceIsolateContractTest`:**12 例 10 绿 / 2 红(NullPointer)**(`tagEvidence_unknownOrBlank_markedUnverified`、`canEnterRecommendationBasis_unverified_false`,反射入口 `:267`)。较 R98 的 11/12 红大幅收敛,研发实现属实。**残留 2 NPE 转常规 RED**:核反射目标 bean 注册/方法签名。闭环判据更新:2 NPE 修复后 12/12 绿 | 测试负责人(第 102 轮定向复验登记) | 2026-11-09 14:0x | 更新(10/12 绿,剩 2 NPE 待研发核) |
+| B-95(第 102 轮新增 · 节点失联) | `192.168.16.204` 节点 opencode 不可达 → frontend 浏览器自动化无法派发 | 运维 | **P1 派发阻断(第 102 轮实测,2026-11-09 14:0x)**。ICMP ping 204 通(0ms 丢包 0),但 `204:80/443/8080/4090/9000` 全部 `http=000`(Connection refused)→ 无法经 opencode 派发 frontend 任务。此前 R101 已在本机降级跑 frontend(`LIVE_BASE_URL=https://cfc.iwintrue.com`);本轮确认 204 与 189 同属「ICMP 通、服务端口拒连」状态。闭环:放通 204:4090 或提供等价可派节点;复派 frontend 应 6/6 | 测试负责人(第 102 轮探活登记) | 2026-11-09 14:0x | 待处理(P1,运维) |
+| B-96(第 102 轮 · 自处置 · 251 派发卡死根因) | 251 langgraph pytest 派发 30 分钟无输出(误判挂死) | 测试(自处置) | **已处置(第 102 轮)**。首派(`dispatch_r102_251_langgraph_v2.py`)轮询 1800s 后 shell 超时,实为两个叠加问题:① **251 上有 R96 残留 pytest 进程**(PID 3181300,`nohup ... --ignore=tests/qna` 从 R96 起跑了一整天)与本轮 pytest 并发抢资源;② 派发命令 `pytest ... | tail -60` 的**管道缓冲**使 30 分钟输出恒为空(tail 等管道关闭才吐),无法观测进度与 DONE 标记。处置:kill 残留进程 + 改用「后台 `nohup ... > /tmp/r102_pytest.log 2>&1` + `timeout 600` + 轮询 `pgrep`"+直接读 log 文件 → **43/32/11 于 69.66s 确定性取回**。教训(B-94 强化):远程 shell 派发**禁止 `| tail` 管道缓冲**,一律后台写文件 + pgrep 轮询;运维宜给 251 加 pytest 进程超时巡检 | 测试负责人(第 102 轮自处置登记) | 2026-11-09 14:1x | 已处置(B-94 通道强化) |
+| B-65-Update(第 102 轮 · 连续第 9 轮) | langgraph `/api/v1/analyze` checkpointer 缺 thread_id | 研发 | **连续第 9 轮未修(第 102 轮实测)**。251 派发 pytest:`test_analyze.py` 2 例 500(`ValueError: Checkpointer requires ... thread_id`);live `POST /api/v1/analyze` **100s 零字节超时**。源码未变(`analysis_graph.py:96 MemorySaver()`、`analyze.py:35 ainvoke` 无 config)。闭环判据不变:去 MemorySaver 或传 thread_id + 部署锁版本;之后 pytest 2 例绿 + live analyze 连跑 3 次 200 | 测试负责人(第 102 轮复现登记) | 2026-11-09 14:2x | 待处理(P0,连续第 9 轮) |
+| B-69-Update(第 102 轮 · 连续第 9 轮) | 4 个 `/api/mind/**` 位于公开白名单 | 研发 | **连续第 9 轮未修(第 102 轮线上复证)**。匿名 POST(无 token):`/api/mind/alert/active`、`/api/mind/alert/checkin-alerts`、`/api/mind/traditional/mirror`、`/api/mind/traditional/compatibility` **全部 200**;对照 `/api/huawei-health/status` **401**(拦截器在听)。`JwtInterceptor.java:79-82` PUBLIC_PATHS 未动。闭环判据不变:4 条移入 LOGIN_REQUIRED_PATHS → 线上匿名全 401 | 测试负责人(第 102 轮线上复证登记) | 2026-11-09 14:2x | 待处理(P1,连续第 9 轮) |
+| B-90-Update(第 102 轮 · 第 3 次复证 · 恶化) | 251 `chat` / `analyze` 无响应(health 正常) | 研发/运维 | **第 3 次复证且恶化(第 102 轮实测)**。`251:9000/health` → 200(22ms);`POST /api/v1/chat` → **70s 零字节超时**;`POST /api/v1/analyze` → **100s 零字节超时**。与 pytest `test_intent` 4 例 `api key ****ocal is invalid` 同源。**定性升级**:LLM 调用从 R99 的「401 秒失败」退化为「挂起无响应」(无 timeout/熔断,B-84 同源)→ 线上 AI 管家与报告解析主链路挂起。闭环:注入有效凭据 + 全部 LLM/检索调用加 timeout+熔断 → live chat/analyze 连跑 3 次 <30s 且 200 | 测试负责人(第 102 轮实测复证) | 2026-11-09 14:2x | 待处理(P0,第 3 次复证) |
+| B-89-Update(第 102 轮 · 第 4 轮失联) | `192.168.16.189` 节点失联 | 运维 | **第 4 轮失联(第 102 轮探活)**。`189:22` / `189:4090` 仍 `http=000`;ICMP ping 通(1ms)但服务端口全拒 → admin 仍降级本机(5/5 绿)。闭环判据不变 | 测试负责人(第 102 轮探活登记) | 2026-11-09 14:0x | 待处理(P1,运维) |

+ 43 - 0
docs/tdd/test/notice-r102-round.md

@@ -0,0 +1,43 @@
+# R102 测试负责人 → 研发/运维 交接通知(2026-11-09 14:3x)
+
+> 通知载体:本文件 + `docs/tdd/test/blockers.md`(B-88-Close / B-95 / B-96 / B-65-U9 / B-69-U9 / B-90-U3 / B-89-U4)
+> 触发规则:测试结果较 R101 有方向性变化 → 提交远程 + 通知研发。**请研发/运维优先处理 P0 项。**
+
+---
+
+## 一、本轮关键结果(一句话)
+
+**浏览器自动化(用户核心指令)28/28 全绿**(admin 5 + frontend 6 + health 13 + shop 4,本机单节点串行,189/204 均无法派发);**langgraph@251 43/32/11**(69.66s 确定性取回);**后端定向契约 Guhe 红例 41→22(−19)**,其中 **B-88 争议解除**(evidenceIsolate 10/12 绿,剩 2 NPE)。
+
+## 二、需研发/运维处置(按优先级)
+
+### P0(2 项,均第 9 轮)
+
+| 项 | 现状 | 证据 | 闭环判据 |
+|---|---|---|---|
+| **B-65** analyze checkpointer 缺 thread_id | 未修 | pytest `test_analyze.py` 2 例 500(`ValueError: Checkpointer requires ... thread_id`);live analyze **100s 零字节** | 去 `MemorySaver()` 或传 `thread_id` → pytest 2 例绿 + live analyze 连跑 3 次 200 |
+| **B-90** 251 LLM 凭据 + 调用超时(**第 3 次复证 · 恶化**) | 未修 | live `chat` **70s** / `analyze` **100s** 零字节(health 22ms 正常);pytest `test_intent` 4 例 `api key ****ocal is invalid` 降级 chat | 注入有效 etotem/deepseek 凭据 + 全部 LLM/检索调用加 `timeout`+熔断 → live chat/analyze 连跑 3 次 <30s 且 200 |
+
+### P1(4 项)
+
+| 项 | 现状 | 证据 | 闭环判据 |
+|---|---|---|---|
+| **B-69** `/api/mind/**` 4 端点公开白名单 | 第 9 轮 | 匿名 POST 4 端点**全 200**(对照 `/api/huawei-health/status` 401) | 4 条移入 `LOGIN_REQUIRED_PATHS`(`JwtInterceptor.java:79-82`)→ 线上匿名 401 |
+| **B-95(新)** 204 节点失联 | 本轮新发现 | `204:80/443/8080/4090/9000` 全 `000`(ICMP 通)→ frontend 无法派发 | 放通 204:4090 或提供等价节点 → 复派 frontend 6/6 |
+| **B-89** 189 节点失联 | 第 4 轮 | `189:22/4090` 仍 `000` → admin 无法派发 | 放通 189:4090+22 → 复派 admin 5/5 |
+| **Guhe 剩余 22 红**(含 evidenceIsolate 2 NPE) | 实现推进中 | `LowSideRuleLoad` 7 / `KbQueryLowSidePatch` 4 / `ReportPersonalAssert` 4 / `LowSideNoSupplement` 3 / `EvidenceIsolate` 2 NPE | 核 evidenceIsolate 2 例反射入口(`:267`);按台账继续派发其余 |
+
+## 三、好消息(本轮改善)
+
+1. **B-88 争议解除**:研发 `dae41ff59`(S-cfc-121)属实,`GuheEvidenceIsolateContractTest` 12 例 **10 绿**(R98 曾判定 11/12 红)。
+2. **S-cfc-117/119 复验通过**:`GuheVersionSplitContractTest` 5/5、`GuheLowSideAggregateContractTest` 6/6、`GuheV2RouteContractTest` 8/8 全绿。
+3. **B-61 维持闭环**:health 鉴权契约 13/13 全 401(无鉴权回归)。
+
+## 四、运维提醒(环境)
+
+- **251 残留 pytest 进程**:R96 遗留 `nohup pytest`(PID 3181300)跑了一整天,已由测试侧 kill。建议 251 配置 pytest 进程超时巡检,防再次堆积。
+- **D 盘 99% 满**(B-92,可用 3.7G):仍无法建隔离 worktree,后端全量复跑受限。
+
+---
+
+*本通知与报告、blockers 一并 commit + push 至 `origin/cfclub`。*