M4 发布实施与验收
# M4 发布实施与验收
2026-10-23 开始实施。用户已明确当前没有生产环境,本轮按本地发布候选验收范围实施;生产部署验收单列,不等待未知环境。M1、M2 已按用户确认结项,M3 工程与自动化验收已完成。本记录仅列实际执行的发布工程证据;M4 本地候选的工程与自动化验收已完成;生产部署验收未执行,不宣称生产发布或等保测评通过。
# 工作范围与实现
- 新增真实 TCP/TLS 的
TestIntegrationReleaseE2E,在 MySQL/PostgreSQL 上分别执行明文 JSON、RSA JWE、SM2/SM4 三种链路。贯通平台创建租户、初始化、管理员首次改密、部门/普通用户/角色授权、普通用户首次改密与 SELF 查询、撤权、停用/恢复和登出。平台账号是离线夹具入口;业务写入全部通过正式 HTTP 中间件与事务,不用改库跳过改密。 - 新增
TestIntegrationMigrationReleaseFailure,真实上一版本之后注入第二条 DDL 故障,检查 dirty、ready 与重跑 fencing。MySQL 第一条 DDL 保留,PostgreSQL 本版事务回滚,均不自动清除 dirty。既有空库与历史升级测试继续执行。 - 新增
scripts/release-recovery.py,隔离库演练 v12→v13、当前全库恢复与上一版快照回滚,逐表比较行数与数据摘要,并检查恢复后 AUTO_INCREMENT/序列可新增。逻辑备份只保存在私有临时目录,退出删除;不向生产库恢复。 - 新增固定容量场景及
scripts/release-acceptance.sh,E2E/race、容量、发布二进制分别可复验,容量串行测量。 - API 提供独立 loopback 指标端口,包含请求量、延迟直方图、登录失败、权限拒绝和连接池。配置边界、并发计数、panic/未知路径的低基数与凭证不泄漏均有回归。真实进程检查确认指标不出现在业务 listener,SIGTERM 正常结束。
- 修复发布检查发现的已有偏差:前端生成类型未同步 widgets 合同;代码生成验证占位包和 CLI 生成头改为
fagocodegenverify;本地 Go file proxy 改为临时文件写完后原子替换,避免并行验证读到半份 zip。
依赖扫描发现 golang.org/x/net、quic-go 的六条可达漏洞后,已将声明这些依赖的模块更新到 x/net v0.60.0、quic-go v0.59.1,并更新 edwards25519 v1.1.1、PostgreSQL 的 pgx v5.9.2;重新 tidy 同步依赖闭包与校验和。依据 Go 漏洞库 HTTP/2 报告 (opens new window)、quic-go 报告 (opens new window) 与 edwards25519 报告 (opens new window) 及 pgx 占位符处理报告 (opens new window) 执行修复。新增固定版本扫描入口与双库 CI 门槛,不将无修复版本的 OpenPGP 模块级提示伪称为漏洞已消除;以源码是否导入及可达为本轮实际结论。
操作步骤、指标配置与失败处理见 发布验证与恢复演练。
# 本轮实际验证
本机 Apple M4、24GiB 内存,Docker 29.8.2(10 CPU、约 7.75GiB 内存),Go 1.27.3;MySQL 8.4.13、PostgreSQL 16.6。最终容量在其他构建和回归结束后串行测量。运行日志放在本机 .cache/m4/,公开结果汇总只包含版本、统计和摘要。
| 检查 | 实际结果 |
|---|---|
| 双库完整业务回归 | 各 32 项顶层 TestIntegration* race 测试通过,容量项按要求单独执行 |
| 新全链路 E2E | 双库各 plain/RSA JWE/SM2-SM4 三套通过,真实 TCP/TLS;首次改密未被改库绕过 |
| 迁移 | 双库空库、v1/v4/v5/v6/v8/v9 历史升级,以及 v12→v13 故障 dirty/readiness/重跑保护通过 |
| 模块 | 18 个 workspace 成员(含 CLI)race/vet 与 GOWORK=off 独立验证通过;静态 DAG 扫描的 19 个后端源码模块含两个 vendor 模块,计数口径不同 |
| OpenAPI | 659 个示例校验;634 条本轮真实响应通过(加密 368、明文 266);前端生成类型同步 |
| 前端 | 91 项回归、typecheck、生产 build 与包内 mock/统计脚本排查通过 |
| 密码学夹具 | Go/前端 SM4 向量内容一致;发现 CRLF/LF 差异后固定 Go testdata 的 LF,字节比对通过 |
| 运行 | 两种构建各 API/worker 就绪、独立指标、业务 listener /metrics 404、SIGTERM 与错误配置脱敏通过 |
| 漏洞 | govulncheck v1.9.0 按两种真实构建标签扫描 API/worker/CLI,均 0 可达、0 导入包漏洞;保留 1 条未导入/不可达的 OpenPGP 模块级提示 |
| 代码生成 | CLI 真实 server workspace 编译通过;包名符合 Fago 约定 |
| 本地代理 | 并发发布/读取归档复验全部有效;不再原地截断 zip |
| 文档 | 同步、链接检查、/fago-doc/ 子路径构建及浏览器四分册/新增页面导航通过 |
golangci-lint 本机未安装,本轮以 gofmt、race、vet、独立构建和增量只读检查验证,未声称运行了 golangci-lint。
# 容量结果
两租户各 1000 个禁用普通用户与一位管理员;GET /api/admin/v1/system/users?pageNo=1&pageSize=20&keyword=capacity_,TLS loopback、明文 JSON,真实主库鉴权与列表/count。每库共 2700 次请求,并发 1/8/32 各三轮、每轮 300 次,18 轮全部错误率 0,p95 均低于 500ms 本地门槛。
| 数据库 | 并发 1 三轮 p95 范围 | 并发 8 三轮 p95 范围 | 并发 32 三轮 p95 范围 |
|---|---|---|---|
| MySQL | 12.040–13.385ms | 33.397–35.880ms | 93.748–122.226ms |
| PostgreSQL | 5.281–5.752ms | 28.964–31.190ms | 94.590–100.328ms |
逐轮数据与固定 SQL 计划见 MySQL、PostgreSQL。查询始终含租户和删除谓词;MySQL 使用租户索引筛选后再做字面子串匹配。%keyword% 的前导通配不能直接由普通 B-tree 解决,count 仍随本租户匹配数据量增长,不能从 1000 行基线推断大租户容量。PostgreSQL 在小数据集可能选择顺序扫描/排序,计划选择不作为跨环境性能承诺。没有依据本次基线盲目加索引或降低主库鉴权。
# 备份恢复结果
每库三个随机隔离库,31 张表均参与行数及摘要比较;权限、菜单、用户组织关系、会话摘要与登录审计有非空夹具。验证当前逻辑快照恢复、上一版 v12 快照回滚、幂等迁移和恢复后 ID 序列新增。三个临时库与私有 dump 均已删除。MySQL 报告、PostgreSQL 报告记录本次耗时和逐表摘要;这些秒数不是生产 RTO,也不包含异地下载或流量切换。
本轮有效实施时长约 0.6 AI 小时(以会话活动时间记录,非生产等待);外部生产等待为不适用,因用户明确当前没有生产环境。后续正式部署仍需独立验收。
原 deploy/mlps-hardening-checklist.md 的逐项本地审查与部署待验项已单独归档,未获得证据的生产项不代替负责人勾选。
# 发布边界
- 本轮 E2E 是真实 HTTP/TLS 测试报告,未新增浏览器点击流程或视频,不能表述为新的用户人工验收。
- 容量基线不覆盖生产 JWE 负载、长时间稳定性或真实用户并发;生产目标由部署方另行确定。
- 数据库快照恢复不等于旧版二进制和实际生产流量切换已完成。
- HTTPS 证书、网络/主机加固、最小权限账号、异地备份、组织制度、告警渠道与 RPO/RTO 需要部署环境证据。未获得证据的项保持待验,不代替部署方签字。
- R1 以 MySQL 为主线、PostgreSQL 核心合同为范围,达梦开发回归不代替 R4;Oracle、SQL Server、完整 SSO、生产工作流等后续范围没有因 M4 开始而变为已认证。