Files
railwaysystem/docs/iot/ROUND5V6_FINAL_SIGNOFF.md
T

145 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Round 5V-6 — 数据差异归因、验收事实与安全归档
日期:2026-10-15(Asia/Shanghai)。分析输入提交:`6e73d34561af192298dac81c82211087c9a460a3`。
仅修改当前归档工作树的验收文档;原工程、实验工程、已有进程及远端分支未修改。
本轮没有启动应用、创建数据库转发、重跑测试矩阵、迁移、恢复或业务写入。
SSH使用既有 `wzbmatebook -> sict-218`;仅临时loopback SOCKS供Git只读访问,不修改持久代理或网络配置。
后续追补:Round 5V-7 已实现并实测受管隧道、14321拒绝守卫、数据稳定观察及故障退出清理。
以下PENDING是本轮当时的结论,现行受管QA范围签署及剩余边界见[Round 5V-7](ROUND5V7_RUNTIME_ISOLATION.md)。
## 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/人脸写入仍不放行;本轮没有任何新的设备控制验证结果。