From 65c567152e4f57bd25af03da52cc7078ea264984 Mon Sep 17 00:00:00 2001 From: wangzhibiao Date: Thu, 15 Oct 2026 01:35:06 +0800 Subject: [PATCH] docs(qa): attribute legacy retry writes and separate software signoff --- DEMO_RUNBOOK.md | 33 ++++++- docs/iot/ROUND5V4_SOFTWARE_QA.md | 9 +- docs/iot/ROUND5V6_FINAL_SIGNOFF.md | 141 +++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+), 4 deletions(-) create mode 100644 docs/iot/ROUND5V6_FINAL_SIGNOFF.md diff --git a/DEMO_RUNBOOK.md b/DEMO_RUNBOOK.md index 6da136407..ea58d65b5 100644 --- a/DEMO_RUNBOOK.md +++ b/DEMO_RUNBOOK.md @@ -5,15 +5,24 @@ ## 当前验收边界 +截至 2026-10-15 Round 5V-6,三项结论必须分开: +`SOFTWARE_FUNCTIONAL_QA_PASSED=YES`;`SOFTWARE_FINAL_SIGNOFF=PENDING_OPERATING_ISOLATION`; +`REAL_HARDWARE_VERIFIED=NO`。 +Round 5V-5 已经通过 Tailscale 跳板恢复访问,并对新融合后端完成登录、培训页、IoT页和既有Mock状态冒烟。 +此前的断网不是撤销已通过的功能验收。两条旧授权的同步时间现已定位到旧实验进程的补偿写入, +不是新融合后端的正常Mock回执,也不能再标成“原因未知”。 +完整时间线、脱敏证据、运行隔离阻塞和安全归档方案见 +[Round 5V-6 验收收口](docs/iot/ROUND5V6_FINAL_SIGNOFF.md)。 + Round 5V-4 已在获准的新建离线 Kingbase V9 容器中实际恢复原生备份,完成 005 的提交、重复执行、异常/断连/锁超时回滚及原备份恢复演练,然后才对 `railwaysystem_fusion_qa_20261013` 执行 16 列 / 4 索引增量迁移。 11 项真实 Kingbase Service/Mapper/事务测试(含独立测试 JVM 强制中断)已通过。 当前 QA 后端、15 个 Chrome 路由与合成学员入住/调宿/退宿的 Mock 双回执闭环已实际验收。 详见 [本轮软件验收记录](docs/iot/ROUND5V4_SOFTWARE_QA.md)。 -但收尾18:27实测服务器22/4321均超时,后端出现08001/EOF;当前就绪状态为 -`BLOCKED_NETWORK`,不是软件功能失败或迁移未执行。已停止本轮本机QA三进程。 -管理员恢复合法连接后,重新执行只读预检和隔离启动即可;不要重做005、覆盖恢复或修改系统路由。 +Round 5V-4 收尾18:27实测服务器22/4321均超时,后端出现08001/EOF;当时状态为 +`BLOCKED_NETWORK`,不是软件功能失败或迁移未执行。Round 5V-5 已恢复合法链路并完成最小冒烟, +且已停止该轮本机QA三进程和临时隧道。不要重做005、覆盖恢复或修改系统路由。 不能将 H2/替身测试、构建成功或登录页显示称为 Kingbase 事务/浏览器业务闭环验收。真实硬件验收始终未进行。 迁移前置、失败回滚和核验清单见 [迁移计划](docs/iot/ROUND5V_KINGBASE_MIGRATION_PLAN.md)。 @@ -86,6 +95,24 @@ Round 5V-4 已另获明确授权,复用服务器现有 V9 镜像创建专用 ## 3. 启停隔离 QA(目标库 005 已完成) +### 经跳板访问时的强制运行隔离前置 + +旧实验进程曾配置 `DB_HOST=127.0.0.1 / DB_PORT=14321`。端口没有监听者,**不代表没有旧客户端等着重连**。 +Round 5V-5 在该端口建立隧道时,旧实验进程重新访问同一QA库,补偿任务写了两条旧授权的同步时间。 +不得再次复用14321,也不能只检查新后端/Redis/前端端口就声称客户端隔离。 + +未来启动前,先只读核对现有Java进程身份、数据源目标及环境变量中的非秘密Host/Port, +确认所选隧道端口没有其他客户端依赖。可考虑任务专用14326,但它只是候选值,仍须现场核验。 +仅绑定127.0.0.1,例如经 `ssh -J wzbmatebook ... sict-218` 转发 +`127.0.0.1:14326 -> 127.0.0.1:4321`;不修改路由、Tailscale、SSH持久配置或全局代理。 +在Git外0600的本轮专用配置中设置 +`FUSION_QA_DB_URL=jdbc:kingbase8://127.0.0.1:14326/railwaysystem_fusion_qa_20261013`。 +原始Kingbase测试驱动仍锁定原地址,不应直接拿该隧道配置重跑完整矩阵。 + +`qa.py` 当前不检查其他进程的出站数据库目标;上述是人工强制前置,不声称已实现自动防冲突。 +如需停止旧实验进程、调整旧运行配置或修订自动预检,须在对应授权下单独实施。 +未证明旧客户端不能借用新链路前,不开放数据库转发、不启动写入演示。 + ```bash python3 scripts/qa/qa.py start --config /protected/round5v.env python3 scripts/qa/qa.py frontend diff --git a/docs/iot/ROUND5V4_SOFTWARE_QA.md b/docs/iot/ROUND5V4_SOFTWARE_QA.md index 1e1cffb64..f0f2de921 100644 --- a/docs/iot/ROUND5V4_SOFTWARE_QA.md +++ b/docs/iot/ROUND5V4_SOFTWARE_QA.md @@ -4,6 +4,11 @@ 本轮基线:`ba5dc7a6af9e6bb6b5166ef04d49af621c4f8de2`。 GitLab 已归档融合基线仍为 `feat/boot4-iot-fusion@37392144`;本轮没有 Push、Merge 或共享部署。 +后续状态说明(2026-10-15):以下网络阻塞是本轮当时的真实状态,不覆盖后来已完成的恢复。 +Round 5V-5 已通过跳板复核共享服务并通过新后端最小冒烟;Round 5V-6 已定位两条旧授权同步时间的 +后续变化。当前功能通过、最终签署待运行隔离收口、硬件未验收的分项结论见 +[Round 5V-6](ROUND5V6_FINAL_SIGNOFF.md)。本文件保留历史证据,不倒改当时结果。 + **收尾状态(18:27之后):BLOCKED_NETWORK,不声明当前 SOFTWARE_QA_READY=YES。** 下列迁移、11项真实Kingbase测试、15路由及浏览器业务闭环在17:35前已实际通过并保留证据。 之后数据库连接中断(后端首条记录17:50:55,SQLSTATE08001;后续EOF),18:27独立TCP探测 @@ -100,7 +105,9 @@ sys_controldata确认cluster state=shut down,最后停止容器入口。没有 使用已有管理角色,不提权业务账号。设置 lock_timeout=3s、statement_timeout=30s, 显式事务及两表ACCESS EXCLUSIVE锁,在锁内再次核对原行指纹,执行相同005并COMMIT。 源 QA 的后验清单与隔离迁移后清单完全对应。旧10授权/15命令为 LEGACY/QUARANTINED、 -version0、无来源环境/意图key,未转换为REAL。业务验收后再次过滤LEGACY核对其完整原记录指纹,仍一致。 +version0、无来源环境/意图key,未转换为REAL。业务验收后17:23保存的过滤LEGACY核验摘要报告其完整原记录指纹仍一致。 +该结论仅对应当时核验点;Round 5V-5之后观察到的两条sync_time变化及其旧实验写入来源, +见Round 5V-6追补,不将历史核验外推为永久不变。 一次性执行/核验代码:`scripts/qa/round5v4_database_stage.py`。不要对已在使用的QA库重跑该一次性编排。 `fusion_qa_app` 真实连接成功,现有SELECT/INSERT/UPDATE及序列权限足够全部业务测试; diff --git a/docs/iot/ROUND5V6_FINAL_SIGNOFF.md b/docs/iot/ROUND5V6_FINAL_SIGNOFF.md new file mode 100644 index 000000000..8912ebf10 --- /dev/null +++ b/docs/iot/ROUND5V6_FINAL_SIGNOFF.md @@ -0,0 +1,141 @@ +# Round 5V-6 — 数据差异归因、验收事实与安全归档 + +日期:2026-10-15(Asia/Shanghai)。分析输入提交:`6e73d34561af192298dac81c82211087c9a460a3`。 +仅修改当前归档工作树的验收文档;原工程、实验工程、已有进程及远端分支未修改。 +本轮没有启动应用、创建数据库转发、重跑测试矩阵、迁移、恢复或业务写入。 +SSH使用既有 `wzbmatebook -> sict-218`;仅临时loopback SOCKS供Git只读访问,不修改持久代理或网络配置。 + +## 1. 三项独立结论 + +| 标识 | 结论 | 范围 | +| --- | --- | --- | +| SOFTWARE_FUNCTIONAL_QA_PASSED | YES | 下列真实Kingbase事务、86项选定回归、12项工具测试、15路由及住宿Mock闭环已通过;不是本轮重跑 | +| SOFTWARE_FINAL_SIGNOFF | PENDING_OPERATING_ISOLATION | 差异已归因,但旧客户端借用隧道的运行隔离缺口尚未经过修复/复验或风险接受 | +| REAL_HARDWARE_VERIFIED | NO | 真实MQTT控制、门锁、人脸和网关均未完成现场验收 | + +功能测试的通过不因当时断网或最终签署未完成而失效;也不等同生产可发布或真实设备已撤权。 + +## 2. 已完成的实际验收及时间 + +时间均为Asia/Shanghai;日志修改时间用于定位文件,不单独充当测试执行证明。 + +| 时间/证据 | 已实际完成 | 证据边界 | +| --- | --- | --- | +| 2026-10-14,17:00前后完成的原生结果 | 新离线V9恢复容器实际恢复63表,005隔离提交、重复执行、故障/断连/锁超时回滚、原备份恢复;随后源QA库005提交16列/4索引 | `round5v4/isolated-results.json`、`source-migration-results.json`及原生清单;不涉及其他源库 | +| 2026-10-14,最终一次17:27–17:29 | 11项真实Kingbase Service/Mapper/事务测试,含独立JVM中断后恢复、并发、回滚、UNKNOWN及晚到ACK保护 | JUnit XML:tests=11、failure/error/skipped=0;MQTT仅替身,不是物理执行 | +| 2026-10-14 | 85项选定回归及1项Boot4缺路由回归,共86项 | 现存12个选定JUnit XML合计86,failure/error/skipped=0;不混入11项Kingbase测试 | +| 2026-10-14,17:32工具日志 | 12项QA工具测试通过;Java21后端及锁定依赖的前端生产构建通过 | `qa-tools-tests.log`及构建日志;本轮未重建/重测 | +| 2026-10-14,17:05–17:36证据窗口 | 实际Chrome 15路由、品牌菜单/首页四图、九个IoT组件;合成住宿入住→Mock授权双ACK→调宿撤旧建新→退宿撤权;界面/数据库对账 | `browser-final-regression.log`、`browser-fixture-verify.log`及截图;最终路由结果15/15、JS错误0,闭环两个授权最终REVOKE/CONFIRMED | +| 2026-10-14,17:50后/18:27探测 | 数据库EOF/08001,Mac直连SSH/DB超时;当时停止本轮应用 | 历史BLOCKED_NETWORK是真实状态,不改写为当时在线 | +| 2026-10-15,00:36–00:52,Round 5V-5 | 跳板SSH及22/4321/9980连通;Kingbase/GitLab健康、容器身份/启动时间未变、恢复容器仍停止;005完整;新Java21/Boot4后端及Chrome登录/Student/Auth/既有Mock查询通过 | `round5v5/result.json`、登录/Student/IoT日志;不是全量复验,进程/隧道均已停止 | +| 2026-10-15,01:24起,Round 5V-6 | 原生备份只在内存中解码,与源QA原始记录只读比较;追查旧进程与SQL日志;GitLab元数据和远端引用只读复核 | 本轮没有恢复库、没有业务写入,不把当前分析称为新一次软件E2E | + +受保护的本机证据根为归档工作树 `.qa-runtime/round5v4/`、`round5v5/`、`round5v6/`。 +JUnit XML位于各模块`target/surefire-reports/`,截图位于`output/playwright/`;这些不提交Git。 +Round 5V-4原生备份/恢复的详细对象、SHA、许可及容器证据见[历史验收](ROUND5V4_SOFTWARE_QA.md)。 + +## 3. 两条sync_time差异的归因 + +**结论:ATTRIBUTED_UNEXPECTED_LEGACY_RETRY_MUTATION。不是EXPECTED_TEST_MUTATION,也不再是UNATTRIBUTED。** +已直接证明写入来自旧实验工程定时补偿的失败/跳过路径;没有证据把它称为本次受控住宿E2E或正常Mock回执。 + +脱敏标识为任务内稳定散列,不包含人员编号、姓名、设备编号、授权值或原主键: + +| 脱敏记录 | 原生备份sync_time | 本轮直接读取sync_time | 旧实验日志对应时间 | +| --- | --- | --- | --- | +| legacy-auth-6567381348 | 2026-10-13 09:19:41 | 2026-10-14 16:51:29 | 2026-10-15 00:51:29.222 | +| legacy-auth-dcd17b2e31 | 2026-10-13 09:19:41 | 2026-10-14 16:51:30 | 2026-10-15 00:51:30.078 | + +字段为无时区`timestamp`,当前数据库TimeZone=UTC;按UTC与Mac的+08:00对齐,上述秒级时间吻合。 +不能仅靠时间吻合归因,下面还有绑定参数和影响行数证据。 +Round 5V-5只保留两条日期/delta汇总(113195秒),反推为10-14 16:46:16,非独立保留的原始行快照; +旧实验日志同一分钟00:46:15.572/.839已有同样跳过事件,随后仍在约每分钟补偿。 +不改写Round 5V-5旧证据;当前直接读值以及完整写入链比该聚合摘要更强。 + +### 已证明的链路 + +1. `lsof`确认旧PID51901的cwd和stdout是`boot4-iot-fusion-test`及其`backend.log`,不是归档新后端。 +2. 对该进程环境只提取非秘密项:`DB_HOST=127.0.0.1`、`DB_PORT=14321`、业务账号`fusion_qa_app`。 + 实验工程`start_demo.sh:69–71`和`application-druid.yml:11`固定对应上述Host/Port及目标QA数据库。 + Round 5V-5确实在14321建立过转发;这使原先断连的旧客户端可以借用新链路。 +3. 实验工程`backend.log:3959478`、`:3959491`分别对应上述两条脱敏记录。 + 前置日志不仅出现`LockAuthMapper.updateSyncStatus`的Preparing SQL,绑定的原主键也匹配, + 且各有`Updates: 1`,紧接着记录“授权下发跳过”,原因是授权内容为空。 + 这是直接写入证据,不只是源代码可能性或时间推测;原日志不复制进Git。 +4. 旧`LockCommandRetryTask.execute`→`LockAuthServiceImpl.retryPending`选择正常/失败授权, + 进入`pushInternal`的空授权值分支(旧Service:409–415),调用旧Mapper:158–161: + `update lock_auth set sync_status = ?, sync_time = CURRENT_TIMESTAMP ... where auth_id = ?`。 + 该分支在构造命令/调用传输前返回,因此此次记录更新不是发送成功或设备回执。 +5. 本轮未开放14321;源QA没有旧应用活动连接,两次只读对账的原始字段、来源元数据和数量一致。 + 未停止或重配PID51901,也没有纠正原记录。 + +### 当前代码所有相关写入入口、任务与触发器 + +- 当前`LockAuthMapper.xml:176–180`仍保留兼容`updateSyncStatus`,会写sync_time;全仓当前生产调用搜索无调用者。 +- 当前Mapper:195–199的`updateExecution`会写sync_time,且以auth_id+intent_key+intent_version匹配。 + 调用来自当前`LockAuthServiceImpl.enqueue`的非法载荷处理,以及`LockCommandServiceImpl.project`。 + 后者用于发送占用、等待ACK、超时/未知、取消、拒绝及双ACK确认;不是每次查询更新。 +- `insertAuth`、`updateAuth`、软删除及设备删除没有为旧记录直接设置sync_time; + 其他网关/设备/培训表的last_sync_time或学习时长sync_time不是此授权字段。 +- 当前定时任务仅在retry开关开启时调用恢复;新后端上轮强制关闭。 + READY扫描不选择LEGACY/QUARANTINED,当前ACK路径有来源/意图版本校验,handleResult兼容方法不独立改写状态。 +- 实际源QA `iotlocks.lock_auth`为普通表,`pg_trigger`和`pg_rules`检查无该表触发器/规则。 + 数据库`log_statement=none`、语句时长日志关闭、commit timestamp跟踪关闭;没有额外数据库审计记录可以归属所有历史写入。 +- 运行JAR与上轮私有副本SHA一致,嵌入的是新Service、新Mapper版本及补偿开关,不是误启动旧JAR。 + +### 数据与安全影响 + +原10条授权和15条命令全部存在。只有两条旧授权sync_time不同,其余所有原始字段一致; +原15条命令的原始字段指纹一致。两条授权status仍0、sync_status仍3,来源仍LEGACY、 +execution_state仍QUARANTINED、intent_version仍0,intent/environment/action仍空。 +没有与这两条授权关联的0011/0012命令;总授权45、总命令83与上轮一致,REAL行数均0。 +未观察到业务版本、授权状态或历史来源隔离被更改,也不能据此宣称真实设备权限已验证。 + +已确认的缺陷是**运行链路隔离不足,允许旧版补偿器绕过新来源契约继续改旧元数据**。 +当前新版本的物理外发门禁未因此被证明失效,但它不能保护另一个旧进程直接写同一库。 +不通过UPDATE恢复旧时间掩盖真实失败尝试;如需数据纠正,须另行批准。 + +最小处置方案:不复用14321;先检查其他进程的出站数据库配置,使用无其他客户端依赖的专用loopback端口及Git外QA配置。 +必要时由用户批准后停止/隔离旧实验服务;后续可给QA启动预检增加“其他客户端目标”检查。 +本轮按任务要求只报告方案,不修改旧工程、旧进程、网络或业务数据;`qa.py`尚无该自动检查。 +在隔离措施经过验证或明确风险接受之前,最终签署继续挂起,但不否认已通过的软件功能测试。 + +## 4. 安全归档核验和后续MR建议 + +本轮起点相对`373921447fa4727c20aed7b28c5d1519fe26fa78`有六笔提交,融合基线是它们的祖先: +`0c1d97a6f`、`47bc6604e`、`5560a3ac0`、`b94ac7f05`、`ba5dc7a6a`、`6e73d3456`。 +本轮仅追加验收文档提交,不改写这些提交。新文档提交的完整SHA通过`git rev-parse HEAD`取得,避免文档自引用。 + +2026-10-15只读远端确认:`feat/boot4-iot-fusion`仍为上述37392144, +`fix/iot-safety-hardening`远端不存在。原融合基线不被覆盖。 + +候选CI仅接受`CI_PIPELINE_SOURCE=web`且`RUN_FUSION_VALIDATION=true`,其余拒绝;只有构建/验证,无部署job或外部include/trigger。 +GitLab原生只读元数据确认项目使用默认`.gitlab-ci.yml`;项目Hook=0,非项目Hook=0, +相关项目及全局活跃Integration=0;两个融合分支流水线记录=0。 +不是仅依据配置推断此前没有执行任务;也不声称已试运行远程Runner。 +标签`railway-deploy`只是Runner选择标签,不是候选文件中的部署动作。 + +敏感扫描范围覆盖六笔提交的所有变更文件版本(130个唯一blob/路径组合),而非只看最终净差异; +另检查本轮文档、Git跟踪清单及忽略规则。未检出本机受保护凭据值、私钥正文、新备份/日志/二进制/人脸照片或个人资料文件。 +通用凭据赋值命中已区分环境变量读取、占位符和合成测试内容,不称整个历史仓库绝无秘密。 +`.qa-runtime/`、浏览器日志/截图、JAR、已知备份位置不被本轮跟踪。 +真实备份和外部配置仍在Git外受保护位置;不要将任意扩展名/任意路径的文件都视为自动安全排除。 +融合基线已继承的node-ipc测试密钥夹具、旧素材等风险仍见[安全收口清单](ROUND5S_SAFETY_HARDENING.md#6-认证值与历史资料),不改写远端历史。 + +**可以准备安全归档该修复分支,但不等于允许推送或最终签署通过。** 后续获得明确Push授权后: +重新核对远端引用和Hook/CI状态,只推送已审查的精确提交到`refs/heads/fix/iot-safety-hardening`, +使用单次SSH SOCKS及`git -c http.proxy=...`,附`-o ci.skip`作为额外防护;不改持久代理、不Force Push、不改融合基线。 +当前共享Git配置内可能留有旧19999代理,不能不加核验直接使用。 + +适合随后通过MR向`feat/boot4-iot-fusion`提交评审:保留提交历史、审查安全机制/005/构建/验收边界, +将运行隔离处置列为最终签署门槛。先评审不自动合并,不将MR视为部署或硬件放行。 +本轮不Push、不创建MR、不Merge、不触发CI或共享部署。 + +## 5. 剩余事项 + +- 旧实验进程的数据库访问链路隔离尚须处置/验证;本轮关闭了自己的临时访问链路,不停止其他进程。 +- 历史JWT/OpenAPI/Druid/DB/MQTT/预置账号凭据轮换、历史素材和依赖测试密钥的来源/留存审核未执行;不复制真实认证值。 +- 既有业务账号三张系统表过宽授权须管理员另行最小化,本轮未扩大或撤销权限。 +- Kingbase现有V9企业试用许可支持已完成的获准QA演练,不代替长期/生产许可和供应链来源确认。 +- Vue2/CLI4依赖遗留、真实协议校验/回执语义、Broker ACL/TLS、UNKNOWN人工核对和现场单台许可仍待后续阶段。 +- 所有真实门锁/MQTT/人脸写入仍不放行;本轮没有任何新的设备控制验证结果。