198 lines
9.1 KiB
Markdown
198 lines
9.1 KiB
Markdown
# 自动发布闸门实现说明
|
||
|
||
## 当前状态
|
||
|
||
自动发布闸门采用 fail-closed 设计。机器目录从 `production-release-guardian.md` 加载并校验
|
||
187 个连续、唯一场景编号,但常规发布只执行 16 项核心场景和 Git diff 选择的影响域。
|
||
关键、共享或无法映射的运行时路径自动升级为完整 187 项;执行器不能把被选择但没有实现、
|
||
没有执行或没有证据的场景视为成功。
|
||
|
||
已经实现:
|
||
|
||
- `release-gate/catalog.mjs`:187 场景机器目录和永远不可豁免清单。
|
||
- `release-gate/safety.mjs`:拒绝生产 IP、`*.tkmind.cn`、生产路径和生产关联环境变量。
|
||
- `release-gate/artifact.mjs`:runtime 排序目录树 SHA256、依赖闭包和持久数据扫描。
|
||
- `release-gate/impact.mjs`:Core Gate、changed-path 业务域映射、依赖闭包和全量触发规则。
|
||
- `release-gate/runner.mjs`:suite 执行、日志归档和失败关闭。
|
||
- `release-gate/report.mjs`:`report.json`、Markdown、JUnit、环境指纹及四小时有效期。
|
||
- `release-gate/regression-corpus.mjs`:脱敏生产回归 fixture 和 active manifest 校验。
|
||
- `scripts/verify-release-gate-report.mjs`:校验完整 `main` SHA、artifact SHA,并从 Git diff 重算风险分层选择结果。
|
||
- `scripts/release-portal-runtime-prod.sh`:任何 103 连接或上传之前强制验证 Gate report。
|
||
|
||
当前已经有自动判定证据的场景如下。这里的“覆盖”必须同时满足
|
||
`release-gate/coverage.mjs` 中逐场景的业务断言;仅仅执行过一个通用测试文件不能计入。
|
||
|
||
| 场景组 | 已自动判定 | 总数 | 已覆盖编号 |
|
||
|---|---:|---:|---|
|
||
| REL | 11 | 11 | REL-01 至 REL-11 |
|
||
| AUTH | 8 | 8 | AUTH-01 至 AUTH-08 |
|
||
| CHAT | 15 | 15 | CHAT-01 至 CHAT-15 |
|
||
| MEM | 16 | 16 | MEM-01 至 MEM-16 |
|
||
| FILE | 8 | 8 | FILE-01 至 FILE-08 |
|
||
| IMGPG | 8 | 8 | IMGPG-01 至 IMGPG-08 |
|
||
| XLS | 12 | 12 | XLS-01 至 XLS-12 |
|
||
| PAGE | 13 | 13 | PAGE-01 至 PAGE-13 |
|
||
| DATA | 13 | 13 | DATA-01 至 DATA-13 |
|
||
| SEARCH | 8 | 8 | SEARCH-01 至 SEARCH-08 |
|
||
| AGENT | 11 | 11 | AGENT-01 至 AGENT-11 |
|
||
| SCHED | 5 | 5 | SCHED-01 至 SCHED-05 |
|
||
| WX | 13 | 13 | WX-01 至 WX-13 |
|
||
| BILL | 7 | 7 | BILL-01 至 BILL-07 |
|
||
| MS | 9 | 9 | MS-01 至 MS-09 |
|
||
| PLAZA | 5 | 5 | PLAZA-01 至 PLAZA-05 |
|
||
| CFG | 8 | 8 | CFG-01 至 CFG-08 |
|
||
| UI | 8 | 8 | UI-01 至 UI-08 |
|
||
| COMP | 9 | 9 | COMP-01 至 COMP-09 |
|
||
| **合计** | **187** | **187** | 184 个 suite 映射,加 REL-01/REL-02/REL-04 三项直接检查 |
|
||
|
||
`REL-03` 会比较候选和两次干净重建的排序目录树 SHA256;`REL-06`、`REL-07`
|
||
分别执行生产配置冷启动和脱敏旧库升级,并断言运行前后 artifact 哈希不变;`REL-11`
|
||
在无网络 Linux ARM64 容器中实际加载 Portal、WeChat、worker 和每个 MCP 模块。
|
||
|
||
全部 187 项都已有自动判定路径。完整 Gate 中未执行的 mode 仍保持 `unknown`;风险分层
|
||
Gate 只为自动选中的场景生成结果,所有选中项都必须执行并通过。UI-01 至 UI-08
|
||
在隔离本地 Portal、390×844 移动视口和公开页 fixture 上运行;COMP-09 由独立执行器
|
||
要求 active 脱敏回归 manifest 并逐条回放。没有 manifest 时 COMP-09 明确 `failed`,
|
||
不会因“没有用例”而通过。`REL-02` 在候选等于 `origin/main` 且 Gitea commit status 为
|
||
`success` 时通过;也可显式注入 `MEMIND_RELEASE_CI_STATUS=success`。
|
||
|
||
常规发布使用风险分层 Gate:
|
||
|
||
```bash
|
||
node scripts/run-release-gate-impact.mjs --artifact .runtime/portal --deployed-commit <103-stable-sha>
|
||
```
|
||
|
||
它固定执行 16 项核心场景,再根据 `<103-stable-sha>..HEAD` 的 changed paths 选择业务域及
|
||
依赖闭包。`server.mjs`、鉴权/会话基础设施、schema/migration、依赖、runtime 构建、
|
||
生产启动/发布脚本、Gate 自身或未映射运行时代码会自动选择完整 187 项。发布脚本在有效报告
|
||
缺失或过期时自动执行该入口,不再要求人工先跑多个 mode 或逐项填写 129 条豁免。
|
||
离线 `--dry-run` 不连接 103;如需模拟风险分层,可设置
|
||
`MEMIND_RELEASE_BASE_COMMIT=<known-stable-sha>`,未提供时安全退化为本地 Full Gate。
|
||
|
||
2026-07-26 本地补齐验证中,历史完整报告为 180/187 通过;`REL-01` 因当前仍在功能
|
||
分支且工作区不干净而失败。PAGE-01/02 与 DATA-01/02/03/04 的隔离栈现在使用后台
|
||
直连 LLM(`custom_deepseek` / `deepseek-v4-pro`),关闭 relay bootstrap,并将代码/技能
|
||
根与隔离数据根分离,避免技能目录为空导致普通用户丢失 `static_publish` 工具。页面发布
|
||
约束也明确要求 `sandbox-fs__write_file/edit_file` 命名空间,避免模型误调用不存在的裸工具。
|
||
修复后的真实 Agent 回归仍需在最新 runtime 上完成全 6 项终态断言;在此之前不能伪装成通过,
|
||
也不能标记为合法 `not_applicable`。生产发布继续禁止。
|
||
|
||
## 本地命令
|
||
|
||
先运行框架单元测试:
|
||
|
||
```bash
|
||
npm run test:release-gate:unit
|
||
```
|
||
|
||
构建候选 runtime 后,普通发布运行风险分层闸门:
|
||
|
||
```bash
|
||
npm run build:portal-runtime
|
||
node scripts/run-release-gate-impact.mjs \
|
||
--artifact .runtime/portal \
|
||
--deployed-commit <103-stable-sha>
|
||
```
|
||
|
||
高风险变更、选择器自身变化或定期回归运行完整闸门:
|
||
|
||
```bash
|
||
npm run test:release-gate:all -- --artifact .runtime/portal
|
||
```
|
||
|
||
风险分层或完整报告路径:
|
||
|
||
```text
|
||
.release-gate/<full-main-sha>/report.json
|
||
```
|
||
|
||
单层执行结果存放在:
|
||
|
||
```text
|
||
.release-gate/<full-main-sha>/partials/<mode>/
|
||
```
|
||
|
||
只验证已有报告与当前 artifact:
|
||
|
||
```bash
|
||
npm run verify:release-gate-report -- --artifact .runtime/portal
|
||
```
|
||
|
||
### 耗时控制
|
||
|
||
完整覆盖不等于 187 条都等待在线 Agent 串行执行:
|
||
|
||
- 业务规则、权限、账务、记忆、文件和交付契约优先做成确定性 fixture/replay,随
|
||
`deterministic` 模式并行执行。
|
||
- Gate 执行器默认同时运行 4 个独立 suite,可通过
|
||
`--suite-concurrency` 或 `RELEASE_GATE_SUITE_CONCURRENCY` 在 1~16 之间调整;
|
||
每个 suite 仍写独立日志并单独判定。
|
||
- 必须验证真实 Agent 的场景按不同 session 并行;Page Data 场景默认并发 4,
|
||
单个 Agent 步骤上限 300 秒、子进程总上限 360 秒。超时直接失败,不允许无限等待。
|
||
- 可用 `RELEASE_GATE_SCENARIO_CONCURRENCY`、
|
||
`RELEASE_GATE_SCENARIO_TIMEOUT_MS` 和
|
||
`RELEASE_GATE_SCENARIO_PROCESS_TIMEOUT_MS` 在 CI 资源范围内收紧预算,不得用它们
|
||
放宽为无限超时。
|
||
- 风险分层或完整闸门只为干净 `main` 的精确 commit + artifact 生成一次四小时有效报告;
|
||
发布脚本复用并校验这份报告,不重复跑慢场景。commit、artifact 或环境指纹变化后
|
||
证据立即失效并重新执行。
|
||
- 本地开发先跑相关确定性 suite;普通发布候选执行 Core + Impact,完整 187 项用于高风险
|
||
候选和定期回归。任何被选择但未执行、超时或缺证据项仍保持 `unknown/failed` 并阻断发布。
|
||
|
||
报告出现以下任意状态都会返回非零:
|
||
|
||
- `failed`
|
||
- `skipped`
|
||
- `blocked`
|
||
- `unknown`
|
||
- `cleanup_failed`
|
||
- 缺少被选择场景,或影响选择结果无法从 Git diff 重现
|
||
- 非法 `not_applicable`
|
||
- commit、branch 或 artifact SHA 不匹配
|
||
- 报告超过四小时
|
||
|
||
## 增加自动化场景
|
||
|
||
1. 先在 `release-gate/` 或现有模块中实现确定性测试。
|
||
2. 在 `release-gate/coverage.mjs` 新增 suite,明确列出唯一场景 ID 和可执行命令。
|
||
3. 一个场景只有在守门员列出的所有强制参数 case 都有断言时,才能映射为 `passed`。
|
||
4. 为 suite 失败、超时和日志路径增加框架测试。
|
||
5. 运行 `npm run test:release-gate:unit` 和对应 mode,确认失败时不会被吞掉。
|
||
6. 更新本文的覆盖表。
|
||
|
||
禁止把大型通用测试命令直接映射到大量场景并据此宣称覆盖;每个映射必须能指出真实业务断言。
|
||
|
||
## 生产失败回归 fixture
|
||
|
||
active manifest 约定位置:
|
||
|
||
```text
|
||
scenarios/production-regressions/manifests/active.json
|
||
```
|
||
|
||
每个 active fixture 必须位于 approved bucket,具有:
|
||
|
||
- `PRC-<GROUP>-NNN` ID。
|
||
- 一个或多个 guardian scenario ID。
|
||
- 合成意图、规范化失败签名和可执行 replay 命令。
|
||
- 不可反查用户的证据摘要和审计批次 ID。
|
||
- `contains_personal_data=false`。
|
||
- 隐私审核人和时间。
|
||
|
||
当前 active manifest 已包含 `PRC-REL-001`,用于回放 runtime worker 的 18036 端口冲突
|
||
回归。原始聊天、用户身份、附件和生产资源地址不得进入仓库或 Gate report。
|
||
|
||
## 发布脚本保护
|
||
|
||
生产脚本执行顺序固定为:
|
||
|
||
1. 检查干净、完整且不落后远端的 `main`。
|
||
2. 运行既有本地 verify。
|
||
3. 构建并检查 `.runtime/portal`。
|
||
4. 验证与当前 commit 和 runtime tree SHA256 完全一致的风险分层或完整 Gate report;缺失时自动执行风险分层 Gate。
|
||
5. Gate report 通过后才允许执行 103 只读预检和任何生产写操作。
|
||
6. 再次请求本次发布的明确人工确认。
|
||
7. 确认后才允许上传和切换。
|
||
|
||
`--skip-tests`、范围绕过变量和公开页问题绕过变量均被硬拒绝。
|