Type: task Status: resolved Assignee: codex Category: frontend-execution
状态:修复已实施,待验证项 1–4 全部取得真实证据,本票收口(2026-10-12)。
Codex 按本地 tracker 的 Status: 约定认领(deck 的 assignees 写入读回失败,以 Assignee: 字段为准)。核心信封解包由并行改动 ead39442 提供,非本票实施;本轮新实施的是同一条业务错误映射链上的两处白名单继承键缺口,提交 86db4d4。
本票一度被我错误撤销,此处更正。
cockpitApi.js 原实现直接 return { data: payload.data } —— 而 payload.data 是 readJsonPayload 返回的整个 AjaxResult 信封 {code, msg, data},业务载荷从未被解包。后果:
fetchBaseArchives 对真实 /infrastructure/base-archives(facilityCount=1006)返回 state=empty;fetchMapSnapshot 对真实 /map-snapshot(total=13)返回 total=null、snapshotAt=''。/events/current?mode=ALARM 业务 code=500,前端分区判为 success —— 故障被伪装成正常空态。实测证据:.scratch/cockpit-real-data-wayfinding/verify/artifacts/t18/live-audit-results.json(写入时间 10:25),三项检查 frontend-envelope-archive、frontend-envelope-map、frontend-business-error-not-success 均为 failed。
工作区已存在对应修复(src/modules/cockpit/services/cockpitApi.js,文件修改时间 14:38:36):新增信封拆解分支——若载荷含数值型 code,则 code !== 200 判失败(401/403 映射 UNAUTHORIZED,其余 UNAVAILABLE),缺 data 字段判 BAD_PAYLOAD,code === 200 才解包 body.data。
该修复于 14:38 落地,晚于上述 10:25 的失败实测,早于我 15:50 的复核。复核因此在已修复代码上进行并返回正常。
我 15:58 撤销本票时,用修复后的代码复核得到「适配层正常」,据此判定缺陷「不成立」并关闭票据。这是推理错误:修复后的通过不能否定修复前已证实的缺陷。正确处置是标记为「已修复待验证」,而非撤销。相关术语纪律:验证缺陷必须确认被测代码版本与复现时版本一致。
核验已有修复时发现同类缺陷的第二、第三处,都在本票“业务错误映射”范围内:
readBusinessReason(cockpitApi.js)用普通对象下标查 BACKEND_ERROR_CATEGORY。白名单只有一个条目,但下标查找会命中 Object.prototype 的继承键——后端随便回一个 category: "toString",失败原因就成了函数而不是契约值。与文件里既有的注释纪律(「只认白名单里这一个取值……不让后端塞任意原因进结果」)直接冲突。
对抗式自查时用 node 探针确认第二处同源缺陷:sectionStateFromBackend('toString') 与 sectionStateFromFreshness('toString') 返回的是函数,会原样漏进 data-section-state。
修复(提交 86db4d4,两个文件共 5 行):三处改为只认白名单自有键。这是最小改动,不新增抽象,沿用本文件既有的 Object.prototype.hasOwnProperty.call 写法。
离线回归:新增 verify/t22-envelope-frontend.mjs,不联网、注入 fetchImpl,覆盖三项真实失败检查对应的同一批领域出口(fetchBaseArchives / fetchMapSnapshot / fetchCurrentEvents)、HTTP 与业务两级失败、mock 分支、裸载荷、白名单继承键、后端分区状态映射 —— 19/19 通过(修复前 5 项继承键检查为红,已实测复现)。
既有离线回归无回退:t48-real-envelope 5/5、t04-config、t05-adapter 283/283、t07-coordinate 39/39、t08-map-summary 44/44 全绿。
既存失败(与本票无关,已用基线对照排除):t03-pole-probe、t28-fill-container 缺 puppeteer-core;t06-assets JSON import 属性;t11-equipment-detail F7;t17-infrastructure-panels / t18-monitoring-panels 引用已被片区改造删除的 MANAGEMENT_REGION_GAP / REGION_MAP_GAP;t37-area-limits、t38-fog 断言。将两处改动临时还原为基线后复跑,9 项全部同样失败,故与本轮改动无因果关系。
事故记录:批量复跑时误执行了 t20-mutations.mjs(故意改坏源码再还原的变异测试),它在还原阶段 copyfile 失败,把 OVERVIEW_RANGE 留成 '' 并留下 .bak。已从 git 恢复 overviewApi.js(该文件在会话开始时干净)并删除 .bak,工作区已复原为仅含本票改动。
复验前先保全历史失败证据:原产物另存为 live-audit-results-2026-10-10T0225Z-pre-fix.json(脚本会覆盖同名文件,不保全就会抹掉缺陷证据)。
verify/t18-real-audit.mjs(116 次只读 GET,真实后端 192.168.110.96:8301)。三项 frontend-* 全部 passed:| 检查 | 修复前(2026-10-10 02:25Z) | 修复后(2026-10-12 01:23Z) |
| --- | --- | --- |
| frontend-envelope-archive | failed {state:"empty", raw:1006} | passed {state:"success", adapted:5278, raw:5278} |
| frontend-envelope-map | failed {adaptedTotal:null, rawTotal:13, snapshot:""} | passed {adaptedTotal:13, rawTotal:13, snapshot:"2026-10-12T09:23:47…"} |
| frontend-business-error-not-success | failed {rawCode:500, adaptedState:"success"} | passed {rawCode:500, adaptedState:"failed"} |
第三项是本票要害:业务 code=500 现在被判为 failed,不再是 success。新产物 live-audit-results.json。
该次审计 116 请求 / 85 通过 / 33 失败,失败项全部不属于本票:map-eight-status-buckets 与 pointStatus 回显(归后端票 29)、设备维 events/history、work-orders 的业务 500、monitoring/* 缺 createdAt(归后端/票 18 阻断项 5)。本票不得据此宣称真实联调整体收口。
✅ 通过 —— 真实浏览器(yarn dev → http://localhost:8001/#/cockpit,public/cockpit/config.json 为 dataSource: real)逐模式确认:
real-overview-envelope-consumed.png。/events/current?mode=ALARM(业务 code=500)对应的「当前预警」分区显示 「数据加载失败 · 数据源暂不可用 · 该分区加载失败(其它分区不受影响)」,红标,非 success、非空白;历史分析/预警效率/预警分析同样。地图区如实说「异常设备数据未就绪,预警处置不猜测异常点」。截图 real-business-error-failed-section.png。events/current?mode=ALARM、map-snapshot 7 页均带 snapshotAt)。✅ 通过 —— mock 分支与裸载荷未被误伤:t22 的 mock 用例证明 mock 处理器返回值不经信封分支(且刻意让 mock 返回 code:500 仍判成功),裸载荷原样透传;t48 第 5 项同证。
✅ 通过 —— 改动归属已登记:并行修复 ead39442(Git 作者 Kazerin),本轮修复 86db4d4。
本票四项验收全部取得真实证据,故按自身交付物收口(Status: resolved)。
不要据此认为真实联调整体完成:本次审计仍有 33 项失败(八桶 pointStatus、设备维事件/工单业务 500、monitoring/* 缺 createdAt),它们属于票 29、票 23与票 18 的范围,仍按各自的阻断项推进。
用户已另有标签停在端口 8000 的同应用标签页;本轮自建的 8001 dev server 与浏览器会话均已关闭,用户原有标签页未被借用或改动。
即使信封已修好,运行监测-监测点台账仍显示「已列出 0 个点位 · 本端点序列共 undefined 条」—— 缺失值被直接渲染。已另立 票 27。
发现于票 18。与 票 28(后端静默丢弃监测点)分属前后端,修复路径互不依赖。
按用户本次指派认领,进入已有修复的核验阶段。当前状态 fixed-pending-verification,无 needs-triage,无 blockedBy。本轮先核验已提交代码、历史失败证据、mock/裸载荷与业务失败分区路径;遵守 AGENTS.md,不自动运行真实审计、构建或浏览器调试,缺失的真实验收证据会如实保留。
源码核验事实:核心信封解包与业务 code 判断已提交在 ead39442db(Git 作者 Kazerin);本轮 HEAD=777f0614db,cockpitApi.js 无工作区差异。本轮不认领已有修复为新实施。仍有明确缺口:t48-real-envelope 只覆盖地图,不验证档案、事件顶层失败与 mock;readBusinessReason 用普通对象下标查白名单,category=toString/proto/constructor 等继承键会返回非 REQUEST_REASON 值,与只认白名单的既定约束冲突。方案:独立离线回归验证三个实际领域出口、HTTP/业务错误和 mock/裸载荷;以自有键查找修复映射,保留既有真实审计失败证据;真实复验需用户明确授权 build/debug 例外。