# 生产发布守门员 > 适用目标:生产 `103` Portal runtime 及其共享链路。 > 规则状态:已确认为生产发布的强制验收规范。 > 当前实施状态:187 场景机器目录保留为回归审计资产;生产发布使用 16 项 Core Gate 加 Git diff 自动选择的影响域 Gate,不再自动执行完整 187 项。关键共享路径展开到预定义影响域;无法映射的运行时代码、无有效基线或不可重现的选择结果直接阻断发布。任何被选择但未实现、未执行或证据不完整的场景保持 `unknown` 并阻断发布。 ## 1. 目标 本守门员将生产发布从“运行若干测试后人工判断”升级为绑定同一源码和同一产物的可审计硬闸门: 1. 只有完整、干净、可追溯的 `main` 可以成为候选版本。 2. 同一个 `main` commit 构建出的同一个 runtime artifact,必须完成 Core Gate 和影响选择器选出的全部场景;生产发布脚本不执行完整 187 项。 3. 结果必须满足 `failed=0`、`skipped=0`、`cleanup_failed=0`。 4. 常规风险分层报告不要求为未选场景逐项填写 `not_applicable`;选择器必须记录 changed paths、影响域和选择证据,被选中的场景不能豁免。 5. 即使机器闸门全部通过,仍须取得用户针对“发布 103”动作本身的明确批准。 6. 未获得批准时,禁止上传、切换 runtime、重启服务或执行任何生产写操作。 ## 2. 核心术语 | 术语 | 含义 | |---|---| | Candidate commit | 已进入远端 `main`、CI 通过、准备构建发布包的完整 Git SHA | | Candidate artifact | 由 Candidate commit 构建的 Portal runtime 包及其 SHA256 | | Scenario family | 本文定义的一条业务或运行时场景;可包含多个参数化 case | | Core Gate | 每次生产候选都必须执行的 16 项最小安全闭包 | | Impact Gate | 根据线上 commit 到候选 commit 的 Git diff 自动选择的业务域场景 | | Catalog audit | 人工或定期执行的完整 187 项回归资产,不是生产发布前置条件 | | Deterministic case | 不依赖真实外部模型输出、可以稳定重复的单元或集成测试 | | Live canary | 在隔离或预生产环境调用真实 LLM、图片、搜索等服务的最小验证 | | `not_applicable` | 有完整影响证明并经审核后,确认本次发布不适用的场景状态 | | Gate report | 绑定 commit、artifact 和环境指纹的机器可读验收报告 | | Release approval | 所有闸门通过后,用户对本次 103 发布作出的明确授权 | ## 3. 发布硬规则 ### 3.1 允许发布的唯一条件 以下条件必须同时成立: - Candidate commit 位于完整 `main`,工作区干净,不落后 `origin/main`。 - Candidate commit 已在远端 CI 通过,且没有未合并的关键变更。 - Candidate artifact 的 SHA256 与 Gate report 完全一致。 - Core Gate 和影响选择器选出的全部场景均为 `passed`。 - 没有 `failed`、`skipped`、`blocked`、`unknown` 或未执行场景。 - 风险分层报告的 base commit、changed paths、影响域和 selected IDs 能够从 Git diff 重算且完全一致。 - 测试数据和临时资源清理完成。 - Gate report 未过期;默认有效期不超过 4 小时。 - 103 只读预检通过。 - 用户再次明确批准本次 103 发布。 任何一项不满足,发布脚本必须在上传 artifact 之前退出。 ### 3.2 常规发布的 Core Gate 以下 16 项每次生产候选都必须执行: - `REL-01`、`REL-02`、`REL-04` 至 `REL-06`、`REL-09`、`REL-11`。 - `AUTH-01`、`AUTH-05`。 - `CHAT-01`、`CHAT-06`、`CHAT-07`。 - `AGENT-01`、`AGENT-03`。 - `MS-01`。 - `COMP-09` 脱敏生产回归语料回放。 Core Gate 之外,选择器以当前 103 manifest 中的 `git_head` 为 base commit,比较候选 commit 的 changed paths,并按 `release-gate/impact.mjs` 的版本化规则选择业务域和依赖闭包。 正常风险分层报告中的被选场景必须真实执行,不能标记为 `not_applicable`。 ### 3.3 关键路径与阻断规则 生产选择器不再升级为完整 187 项,按以下规则处理: - `server.mjs`、鉴权/会话基础设施、数据库 schema/migration、runtime 构建、依赖、 goosed/worker/代理、公共配置和发布闸门自身变化时,展开到版本化规则声明的影响域。 - 影响选择器无法映射任一运行时代码路径时直接失败,必须先提交映射与测试。 - 线上 base commit 不可用、不是候选祖先,或选择结果无法从 Git diff 重现时直接失败。 - 上次灰度或生产发布失败时先回滚并修复;新的候选重新执行 Core + Impact。 ### 3.4 回归目录中永远不可豁免的场景 下列场景不允许标记为 `not_applicable`: - `REL-*` 全部发布、升级、备份和回滚场景。 - `AUTH-01`、`AUTH-04`、`AUTH-05`、`AUTH-06`。 - `CHAT-01`、`CHAT-02`、`CHAT-06`、`CHAT-07`、`CHAT-08`、`CHAT-09`、`CHAT-11`、`CHAT-12`、`CHAT-13`、`CHAT-15`。 - `MEM-08`、`MEM-13`、`MEM-14`、`MEM-15`、`MEM-16`。 - `FILE-07` 附件跨用户隔离。 - `PAGE-08`、`PAGE-09`、`PAGE-10`、`PAGE-12`。 - `DATA-06`、`DATA-10`、`DATA-12`。 - `AGENT-10`、`AGENT-11`。 - `WX-09` 至 `WX-13`。 - `BILL-02`、`BILL-03`、`BILL-04`。 - `MS-01`、`MS-03`、`MS-04`。 - `COMP-01` 至 `COMP-04` 既有生产数据兼容场景。 - `CFG-08` 模型配置兼容场景。 - `COMP-08`、`COMP-09`。 ### 3.5 人工目录审计中 `not_applicable` 的判定 只有同时满足以下条件,才允许将场景标记为 `not_applicable`: 1. 本次 diff 不触达该场景映射的代码、配置、数据库对象、依赖、运行时打包清单或公共契约。 2. 本次 diff 不触达共享入口,包括 `server.mjs`、鉴权、会话、数据库初始化、runtime 构建、goosed 配置、worker、代理、公共环境变量。 3. 场景所依赖的生产功能处于明确关闭状态,并且“关闭状态行为”已经通过测试。 4. 影响分析能够列出 changed paths、依赖链和不受影响的理由。 5. 审核人对该 Candidate commit 作出明确确认。 每条豁免记录必须包含: ```json { "scenario_id": "SEARCH-04", "status": "not_applicable", "commit_sha": "", "reason": "生产 GitHub Search 功能关闭,且本次变更不触达搜索配置或共享网关", "changed_paths_checked": ["..."], "dependency_evidence": ["..."], "reviewed_by": "", "reviewed_at": "" } ``` 如果无法确定是否受影响,默认必须执行,不得豁免。 ## 4. 分层闸门 | Gate | 名称 | 环境 | 主要产物 | 失败处理 | |---|---|---|---|---| | G0 | 源码与 CI | 本地 + Git 远端 | commit 证明、CI 状态 | 阻断 | | G1 | 确定性测试 | 隔离本地副本 | 单元/集成/回归结果 | 阻断 | | G2 | API 全栈场景 | 隔离全栈 | 场景报告、数据库和文件断言 | 阻断 | | G3 | 浏览器场景 | 隔离全栈 | Playwright 报告、截图、控制台日志 | 阻断 | | G4 | 真实服务 Canary | 预生产 | LLM/图片/搜索/Deep Search 结果 | 阻断 | | G5 | 升级与回滚演练 | 脱敏生产快照 | 升级、持久化、回滚证据 | 阻断 | | G6 | 103 只读预检 | 生产只读 | 健康、任务、锁、空间、备份检查 | 阻断 | | G7 | 人工批准 | 发布前 | 明确批准记录 | 未批准不得发布 | | G8 | 发布后烟雾与自动回滚 | 生产 | 最小业务验收 | 失败立即回滚 | G8 不能替代 G0-G7;发布后健康检查也不能为发布前缺失的场景补票。 ## 5. 测试环境和数据隔离 ### 5.1 禁止测试连接生产 全场景执行器必须在代码层拒绝以下目标: - `58.38.22.103` - `m.tkmind.cn` - 生产 MySQL、PostgreSQL、Redis、SearXNG、Deep Search 和图片服务地址 - 生产用户工作区、发布目录和对象存储 G6 仅允许明确列出的只读检查;不得创建会话、页面、订单、问卷、记忆、充值或 Agent Run。 ### 5.2 隔离要求 每次执行必须使用: - 唯一 `run_id` - 独立测试数据库或独立 schema - 独立用户工作区和公开页根目录 - 专用普通用户 A、普通用户 B、creator、developer、admin、低余额用户 - 专用微信绑定账号和模拟支付数据 - 独立 Portal、MindSpace、goosed、worker 端口 - 可控的 LLM、图片、搜索 Stub,以及单独的真实服务 Canary 凭据 测试结束必须删除或归档: - 测试会话和 Agent Run - 用户记忆 - 上传附件和生成图片 - MindSpace 页面、缩略图和 Conversation Package - Page Data dataset、policy 和测试行 - 计费、充值、微信和 Plaza 测试记录 - 临时数据库/schema、容器、进程和日志 清理失败等同测试失败。 ## 6. 场景用例标准 每个场景文件必须具备: ```yaml id: MEM-02 name: 新会话召回用户偏好 gate: G2 owners: [memory, chat] impact_paths: - memory-v2*.mjs - chat-intent-router.mjs preconditions: - user_a 已保存一条确定性偏好 steps: - 新建会话 - 使用不同措辞询问偏好 assertions: - 路由启用 memory_recall - 回复包含目标事实 - 不包含 user_b 的记忆 cleanup: - 删除本次测试记忆和会话 evidence: - API 响应 - memory query trace - database assertion production_regression_refs: - PRC-MEM-001 ``` LLM 场景不得只断言固定文案,应优先断言: - 路由、skill、tool 和 Provider 选择 - 工具请求/响应是否真实发生 - 数据库、文件和 artifact 是否正确产生 - 数字结果和标准 fixture 是否一致 - 用户可见结果是否包含关键事实和可访问链接 - 不应出现的敏感信息、内部提示和旧资产是否缺失 ## 7. 场景目录 以下共 19 个场景包、187 个场景族。每个场景族可以在场景文件中继续扩展参数化 case,但不得减少本文要求。 ### 7.1 发布与运行时(11) - **REL-01**:候选来源必须是干净、非 detached 的完整 `main`;记录完整 SHA。 - **REL-02**:候选不落后 `origin/main` 且已推送;Gitea commit status 为 `success`,或未接入 commit status 时候选 SHA 等于 `origin/main`。 - **REL-03**:同一 commit 可重复生成可追踪的 manifest 和 runtime artifact SHA256。 - **REL-04**:artifact 必需文件完整,不包含开发垃圾、运行态数据、源码备份或密钥。 - **REL-05**:前端和 runtime 不包含 localhost、错误内网地址或错误公共域名。 - **REL-06**:使用生产同构配置冷启动,数据库初始化和 Portal 健康检查通过。 - **REL-07**:从脱敏生产数据库快照升级,DDL 成功、数据保留且重复启动幂等。 - **REL-08**:9 个 goosed、worker、Portal 和隧道全部指向并识别新 runtime。 - **REL-09**:注入启动或健康检查失败后,完整恢复旧 live 目录和旧 release。 - **REL-10**:活动任务排空、备份一致、上传中断和切换前失败均不影响当前版本。 - **REL-11**:启用扩展及 runtime 的依赖闭包完整;每个打包的 MCP 模块都存在,并能在生产同构容器内实际启动。 ### 7.2 登录、账号和权限(8) - **AUTH-01**:正确账号密码登录,返回合法 Cookie 和用户信息。 - **AUTH-02**:错误密码、连续错误尝试和限流行为正确。 - **AUTH-03**:Portal 重启后合法会话状态符合配置,不出现幽灵登录。 - **AUTH-04**:登出清除 Cookie,旧 Cookie 无法访问受保护 API。 - **AUTH-05**:用户 A 无法访问用户 B 的会话、附件、页面和私有数据。 - **AUTH-06**:普通用户无法访问管理员接口或提升自身权限。 - **AUTH-07**:访问策略 `off`、`enforce` 和 kill switch 三种模式符合预期。 - **AUTH-08**:路径穿越、XSS、SQL 注入和敏感配置泄露防护有效。 ### 7.3 聊天、会话和流式恢复(15) - **CHAT-01**:普通问候进入 Direct Chat 并返回用户可见回复。 - **CHAT-02**:页面、文件和工具任务进入 Agent 路径。 - **CHAT-03**:实时信息问题进入 Web Search,而不是使用过期直接回答。 - **CHAT-04**:多轮任务及“继续/确认”保持在原 Agent 会话。 - **CHAT-05**:明确新会话与自动复用会话的行为正确。 - **CHAT-06**:Finish 与最终消息正确 merge,不丢用户或助手消息。 - **CHAT-07**:SSE 中断后按 Portal 游标续播,不重放、不漏事件。 - **CHAT-08**:Portal replay ID 不直接作为 Goose `Last-Event-ID`。 - **CHAT-09**:SSE 不可用时,轮询能够恢复 Agent 最终状态和消息。 - **CHAT-10**:重复请求、失败重试、取消和损坏 tool history 修复正确。 - **CHAT-11**:已有活动请求时再次发送消息,排队、取消或新建会话的行为明确,不暴露原始技术错误,也不丢失任一请求。 - **CHAT-12**:兼容历史消息契约,包括 `userVisible`/`agentVisible` 字段和 legacy、非 UUID request ID。 - **CHAT-13**:只有助手消息、Finish、会话快照和规范化消息全部持久化且顺序、时间一致后,任务才允许标记成功。 - **CHAT-14**:用户纠正“不是这个文件/对象”时,本轮纠正覆盖过期上下文,真实任务不会被 routing、skill 或内部提示覆盖。 - **CHAT-15**:快照中的每条用户可见文本都同步到规范化消息表,单字回复、Finish 边界和恢复流程均不得静默丢消息。 ### 7.4 用户记忆与记忆召回(16) - **MEM-01**:用户明确要求“记住”后成功保存偏好。 - **MEM-02**:新会话能够准确召回已保存偏好。 - **MEM-03**:换一种表达仍能通过语义检索召回正确记忆。 - **MEM-04**:能够召回历史会话中的具体事实和讨论主题。 - **MEM-05**:偏好变更时新值生效,不同时注入冲突的新旧内容。 - **MEM-06**:用户要求遗忘后,后续无法继续召回目标记忆。 - **MEM-07**:无关问题不注入无关记忆。 - **MEM-08**:两个用户的长期记忆和历史会话完全隔离。 - **MEM-09**:敏感信息遵循披露、保存、拒绝和删除策略。 - **MEM-10**:候选记忆、确认、晋升、过期和作用域生命周期正确。 - **MEM-11**:Memory V2 不可用时按配置降级到 legacy,核心聊天仍可用。 - **MEM-12**:大量记忆按相关性和 token 限额截断,并保留来源追踪。 - **MEM-13**:routing prompt、Memory Context、skill/tool 指令和系统模板不得被提取为用户记忆。 - **MEM-14**:单条证据消息的记忆提取数量和 fan-out 有硬上限,异常输入不能生成数百或数千条记忆。 - **MEM-15**:重复处理同一证据保持幂等,精确和语义重复均被去重,且每条记忆必须保留合法 evidence/source。 - **MEM-16**:用户纠正、遗忘或删除的内容,不能被 episodic、legacy 或上下文重摄取重新写回。 ### 7.5 文件和附件基础能力(8) - **FILE-01**:图片上传、预览、关联会话并可被 Agent 读取。 - **FILE-02**:XLSX 上传、解析和附件选择正确。 - **FILE-03**:CSV 的编码、分隔符、中文字段和空值解析正确。 - **FILE-04**:PDF、DOCX 文本抽取和文件元数据正确。 - **FILE-05**:多附件的选择、顺序、取消选择和会话复用正确。 - **FILE-06**:损坏文件、错误 MIME、超限文件和不支持格式明确拒绝。 - **FILE-07**:附件访问令牌过期后失效,跨用户访问被拒绝。 - **FILE-08**:生成文件、公开 URL、下载按钮和微信原生交付均指向真实可下载 artifact,访问令牌和权限正确。 ### 7.6 根据图片生成页面(8) - **IMGPG-01**:单张产品或风景图片生成响应式页面。 - **IMGPG-02**:截图经过视觉识别和 OCR 后生成结构相符的页面。 - **IMGPG-03**:多张图片按用户指定顺序生成图集或内容页面。 - **IMGPG-04**:图片与文字要求共同决定页面结构、文案和风格。 - **IMGPG-05**:页面引用合法上传资产,不包含本地绝对路径或失效 URL。 - **IMGPG-06**:公开页、封面、缩略图、OG 和分享链接完整。 - **IMGPG-07**:后续修改文案或布局时保留原图片和页面地址。 - **IMGPG-08**:图片不可读或用户无权限时明确失败,不伪造识别结果。 ### 7.7 Excel/CSV 分析并生成页面(12) - **XLS-01**:单工作表生成指标摘要和可访问页面。 - **XLS-02**:多工作表关联分析得到 fixture 规定的结果。 - **XLS-03**:公式、日期、货币和百分比计算与标准答案一致。 - **XLS-04**:合并单元格、空行、脏数据和重复数据处理正确。 - **XLS-05**:页面 KPI 和图表数值可追溯到 Excel 原始数据。 - **XLS-06**:大文件分页、采样、超时和内存限制符合阈值。 - **XLS-07**:XLSX、XLS、CSV 支持范围和降级提示准确。 - **XLS-08**:后续对话修改分析维度,无需重新上传文件。 - **XLS-09**:页面保留原文件下载入口和数据来源说明。 - **XLS-10**:Excel 私有数据默认不公开,用户之间严格隔离。 - **XLS-11**:约 5MB、多工作表 Excel 在 xlsx 工具超时时安全降级,数字经过验证并仍能交付真实 artifact。 - **XLS-12**:新 Excel 能增量更新已有数据看板,保留页面身份、既有数据和用户已确认的纠正。 ### 7.8 页面生成和 AI 配图(13) - **PAGE-01**:纯文字需求生成公开页面并返回可访问链接。 - **PAGE-02**:长内容整理为适合阅读和分享的富页面。 - **PAGE-03**:视觉类页面自动判断是否需要配图。 - **PAGE-04**:强制生图必须使用本轮新生成资产。 - **PAGE-05**:用户明确不要图片时不得调用生图。 - **PAGE-06**:生图失败时如实报告,不使用旧图冒充成功。 - **PAGE-07**:主图、卡片封面和缩略图复用合法资产,避免重复生成。 - **PAGE-08**:`edit_file` 修改必须 materialize 到 `public/*.html`。 - **PAGE-09**:多页面任务只更新本轮相关页面,不污染其他页面。 - **PAGE-10**:文件名冲突、canonical、CSP、公开链接和域名正确。 - **PAGE-11**:复合每日资讯页同时覆盖当日新闻、天气、市场/股票、知识卡片、权威引用、合规说明和可访问公开页。 - **PAGE-12**:首次缺少公开 HTML、artifact 或必要交付物时只允许一次有界自修复;仍缺失则形成正确失败终态。 - **PAGE-13**:独立生图请求不得被强制转成页面;用户说“换一个”时必须产生本轮新位图,不能复用旧资产。 ### 7.9 Page Data、问卷和业务后台(13) - **DATA-01**:AI 使用调查完成页面、dataset、提交和后台查看。 - **DATA-02**:客户下单系统前台提交和后台管理完整。 - **DATA-03**:供应商数据上报、校验和后台查看完整。 - **DATA-04**:TKMind 功能偏好调查完成交付。 - **DATA-05**:儿童问卷新增饮食字段且保留历史数据。 - **DATA-06**:匿名前台可以按 policy 提交,后台必须登录。 - **DATA-07**:新增、查询、修改、删除和字段校验正确。 - **DATA-08**:HTML 使用 `updateRow`/`deleteRow` 时权限自动匹配。 - **DATA-09**:验证码、重复提交、重放和限流有效。 - **DATA-10**:dataset、page policy 和 workspace 绑定一致。 - **DATA-11**:remote 模式同步,storage 缺失时回退 workspace。 - **DATA-12**:跨用户、SQL 注入、越权字段和审计日志验证通过。 - **DATA-13**:不完整 schema 能安全修复并重新绑定,覆盖缺字段、重复 `created_at`、误判只读、禁用软删、legacy API/client/localStorage 和过期页面版本。 ### 7.10 搜索和 Deep Search(8) - **SEARCH-01**:实时信息通过 Web Search 获取并提供可验证来源。 - **SEARCH-02**:SearXNG 查询和结果解析正确。 - **SEARCH-03**:网页 Reader 抽取正文并处理失败页面。 - **SEARCH-04**:GitHub Search 启用和禁用状态符合配置。 - **SEARCH-05**:Deep Search 使用真实 LLM 网关完成最小研究任务。 - **SEARCH-06**:密钥不匹配时明确返回鉴权失败,不能以 health 200 代替功能成功。 - **SEARCH-07**:搜索超时、取消和 Provider fallback 正确。 - **SEARCH-08**:容器内 loopback 地址正确重写为 host gateway。 ### 7.11 Agent、goosed、worker 和代码执行(11) - **AGENT-01**:普通 Agent 任务可由 goosed 成功执行。 - **AGENT-02**:并发任务分配和 session affinity 正确。 - **AGENT-03**:Portal 与 worker runtime/build identity 匹配。 - **AGENT-04**:identity 不匹配时 fail closed,不误领任务。 - **AGENT-05**:任务重试、幂等和重复消费防护正确。 - **AGENT-06**:worker 重启后任务恢复或形成明确失败终态。 - **AGENT-07**:获得授权的用户可以执行 Aider 开发任务。 - **AGENT-08**:未授权用户和非允许 task type 被拒绝。 - **AGENT-09**:代码产物正确交付,不能逃逸用户工作区。 - **AGENT-10**:扩展启动兼容目标数据库方言、PostgreSQL role 权限和模块路径;Page Data 扩展失败不能拖垮非数据任务。 - **AGENT-11**:超时、心跳过期或 worker 重启后任务恰好恢复或终结一次,只产生一个终态和一份用户可见结果。 ### 7.12 日程和提醒(5) - **SCHED-01**:按照用户时区创建提醒。 - **SCHED-02**:模糊时间要求澄清,不擅自确定错误时间。 - **SCHED-03**:修改和取消提醒正确。 - **SCHED-04**:worker 只发送一次,失败重试不重复通知。 - **SCHED-05**:服务重启后提醒仍存在并按计划执行。 ### 7.13 微信渠道(13) - **WX-01**:签名和连通性验证正确。 - **WX-02**:重复消息 ID 不重复执行。 - **WX-03**:绑定用户聊天及用户数据隔离正确。 - **WX-04**:页面交付返回正确公开链接。 - **WX-05**:图片需求发送微信原生图片消息。 - **WX-06**:服务号页面使用本轮新缩略图,缺失时按规则修复。 - **WX-07**:OAuth 回调、return URL 和 state 校验正确。 - **WX-08**:支付通知签名、幂等和渠道隔离通过沙箱数据验证。 - **WX-09**:每条入站消息最终进入 done 或 failed,长期 processing 记录能够自动恢复或关闭。 - **WX-10**:仅图片的历史和内容能为纯文本模型安全归一化,图片后的文字追问不会触发 `image_url` 400。 - **WX-11**:微信 45047 响应次数和 45015 时间窗口错误可恢复,不重复发送,并在下一次被动回复机会完成交付。 - **WX-12**:AMR 语音转换及 ASR 成功链路可用,转换或识别失败时给出明确用户提示。 - **WX-13**:微信页面交付为原子组合:真实页面 artifact、本轮封面、摘要、品牌标记和可发送公开链接缺一不可。 ### 7.14 计费、额度和充值(7) - **BILL-01**:免费、订阅和管理员权益计算正确。 - **BILL-02**:Direct Chat 和 Agent 分别只扣费一次。 - **BILL-03**:失败、取消和超时任务不重复扣费。 - **BILL-04**:SSE 重连和消息重放不重复结算。 - **BILL-05**:并发任务下余额扣减保持原子性。 - **BILL-06**:充值回调签名和幂等正确。 - **BILL-07**:余额不足时拒绝执行且不创建残留任务。 ### 7.15 MindSpace 和交付物(9) - **MS-01**:MindSpace `/health` 和 `/mindspace/v1/contract` 正常。 - **MS-02**:local/remote adapter 的核心行为一致。 - **MS-03**:公开页访问、canonical、OG 和分享正确。 - **MS-04**:页面同步、缩略图和 workspace fallback 正确。 - **MS-05**:Conversation Package 创建、校验和历史回填正确。 - **MS-06**:DOCX 和长图下载可用,链接不指向本地地址。 - **MS-07**:内容扫描、CSP 和危险脚本处理正确。 - **MS-08**:删除、清理和 purge 不留下孤立资源。 - **MS-09**:PDF/DOCX 生成不依赖运行时联网下载字体,真实文件可下载,并可通过原生或直接链路交付。 ### 7.16 Plaza 集成(5) - **PLAZA-01**:页面发布到 Plaza 后内容和链接正确。 - **PLAZA-02**:发现、搜索和 SEO 数据正确。 - **PLAZA-03**:点赞、评论、关注和权限正确。 - **PLAZA-04**:推荐和排序在固定 fixture 下稳定。 - **PLAZA-05**:页面删除或转私密后不再公开访问。 ### 7.17 配置、功能开关和可观测性(8) - **CFG-01**:Orchestrator 关闭时不成为 Portal 启动或请求依赖。 - **CFG-02**:Orchestrator shadow 模式不改变用户结果。 - **CFG-03**:kill switch 可以立即阻断新的受控执行。 - **CFG-04**:Analytics 关闭时零上报,开启时上下文正确。 - **CFG-05**:System Disclosure 的 shadow/enforce 行为正确。 - **CFG-06**:环境变量迁移到数据库配置且重复执行幂等。 - **CFG-07**:日志、指标和审计可追踪,且不泄露密钥和用户隐私。 - **CFG-08**:活动 Provider 接受全部已配置数据库模型;模型目录升级时自动迁移或明确拒绝 legacy 配置,不把无效模型带入运行。 ### 7.18 浏览器和移动端(8) - **UI-01**:桌面端登录、聊天和历史记录完整。 - **UI-02**:移动端聊天、流式消息和 Finish 完整。 - **UI-03**:图片、Excel 和其他附件上传交互正确。 - **UI-04**:页面预览、修改、发布和分享流程正确。 - **UI-05**:公开 Page Data 表单可以真实提交并看到结果。 - **UI-06**:空状态、加载、错误、重试和禁用状态完整。 - **UI-07**:刷新、前进后退和重新进入会话不丢状态。 - **UI-08**:无控制台错误、无布局重叠,并通过基础可访问性检查。 ### 7.19 生产兼容、故障恢复和性能(9) - **COMP-01**:脱敏生产旧会话升级后可以继续聊天。 - **COMP-02**:现有公开页面升级后仍可访问且内容未损坏。 - **COMP-03**:现有 Page Data 数据、policy 和表单升级后仍可使用。 - **COMP-04**:现有用户记忆升级后仍可召回。 - **COMP-05**:单个 goosed 容器故障时隔离并恢复。 - **COMP-06**:数据库短暂不可用后服务能够恢复并保持一致性。 - **COMP-07**:图片、搜索或记忆 Provider 故障不拖垮核心聊天。 - **COMP-08**:并发聊天、文件分析和页面生成满足延迟、错误率和资源泄漏阈值。 - **COMP-09**:每次候选发布都在隔离环境回放脱敏生产回归语料库,且执行器从代码层禁止连接生产。 ## 8. 既有场景迁移 现有 `scenarios/*.json` 场景必须保留,并映射到新编号: | 既有场景 | 新场景 | |---|---| | `ai-usage-survey` | DATA-01 | | `customer-order-system` | DATA-02 | | `dev-logout` | AUTH-04 | | `john2-suzhou-page` | PAGE-01、MS-03 | | `john4-children-hobby-diet-update` | DATA-05 | | `supplier-data-report` | DATA-03 | | `suzhou-page` | PAGE-01、PAGE-08 | | `tkmind-feature-survey` | DATA-04 | | `event-registration-page-data` | DATA-06、DATA-07、DATA-10 | | `event-registration-page-data-repair` | DATA-07、DATA-10、DATA-11 | 现有执行器只支持 `login`、`logout`、`chat`。实施时至少增加: - `seed`、`cleanup` - `grant`、`revoke` - `upload`、`select_asset` - `disconnect_stream`、`reconnect_stream` - `assert_memory` - `assert_page` - `assert_dataset` - `assert_billing` - `assert_audit` - `restart_service` - `inject_fault` - `browser` - `rollback` ## 9. 自动化命令和报告接口 当前已提供以下入口: ```bash npm run test:release-gate:unit npm run test:release-gate:deterministic -- --artifact .runtime/portal npm run test:release-gate:scenarios -- --artifact .runtime/portal npm run test:release-gate:browser -- --artifact .runtime/portal npm run test:release-gate:providers -- --artifact .runtime/portal npm run test:release-gate:upgrade -- --artifact .runtime/portal npm run test:release-gate:all -- --artifact .runtime/portal node scripts/run-release-gate-impact.mjs --artifact .runtime/portal --deployed-commit <103-stable-sha> npm run verify:release-gate-report -- --artifact .runtime/portal ``` `test:release-gate:all` 生成: ```text .release-gate// ├── report.json ├── report.md ├── junit.xml ├── artifact.sha256 ├── environment.json ├── scenarios/ ├── screenshots/ ├── logs/ └── partials/ ``` 当前执行器从本文解析并校验 187 个连续唯一编号。187 项是完整回归目录,不是常规发布 必须逐项执行的固定数量。现有自动化 suite 已为 184 个场景提供逐项业务断言,仓库/候选检查另直接判定 `REL-01`、`REL-02` 和 `REL-04`,共 187 个场景都有自动判定能力。未执行 mode 仍为 `unknown`; 缺少 active 脱敏回归 fixture 时 `COMP-09` 明确失败;候选不等于 `origin/main` 或缺少成功 CI 证据时 `REL-02` 仅在候选未推送、CI 明确失败或仍为 pending 时失败。任何不完整证据都会让完整闸门返回非零, 这是发布保护而不是测试故障。精确分组覆盖、命令和扩展方式见 [自动发布闸门实现说明](release-gate-automation.md)。 常规风险分层 `report.json` 至少包含: ```json { "schema_version": 1, "mode": "impact", "commit_sha": "", "branch": "main", "artifact_sha256": "", "started_at": "", "completed_at": "", "expires_at": "", "environment_fingerprint": "", "selection": { "policy_version": 2, "strategy": "core|impact", "base_commit": "<103 stable sha>", "catalog_total": 187, "selected_total": 32, "core_ids": [], "impact_groups": [], "changed_paths": [], "unmapped_paths": [], "full_gate_reasons": [], "selected_ids": [] }, "summary": { "required": 32, "passed": 32, "not_applicable": 0, "failed": 0, "skipped": 0, "blocked": 0, "unknown": 0, "cleanup_failed": 0 }, "scenarios": [], "exemptions": [], "approved_for_release": false } ``` 风险分层报告必须满足: ```text passed = required = selected_total failed = skipped = blocked = unknown = cleanup_failed = 0 ``` 人工或定期目录审计如果存在合法 `not_applicable`,必须满足: ```text passed + not_applicable = required failed = skipped = blocked = unknown = cleanup_failed = 0 ``` ## 10. 发布脚本的最终阻断点 ### 10.0 用户级灰度前置条件 用户级灰度入口由 `scripts/release-portal-canary-prod.sh` 安装:稳定 Portal 保持 8081, 候选 Portal 使用 18081,候选 goosed 使用 18015,身份路由器使用 18082;105 使用独立 19082 反向隧道访问路由器。活动 nginx 上游在脚本备份、`nginx -t` 和健康检查后,才允许 从稳定 `58.38.22.103:8081` 切到 `127.0.0.1:19082`。灰度身份必须 使用不可变用户 ID、唯一用户名或微信绑定账号标识;禁止按显示昵称(包括“唐”)匹配。未命中、 身份解析失败或候选不可用必须自动回落稳定版本。 完整契约和回滚入口见 [103 用户级灰度发布](release-canary-103.md),对应测试至少包括 `release-gate/canary-routing.test.mjs`、`memind-canary-proxy.test.mjs` 和 `release-gate/release-script.test.mjs`。测试通过不代表已经部署;103 灰度仍须绑定同一 commit、artifact 和 Gate report,并完成备份、只读预检及人工批准。 `scripts/release-portal-runtime-prod.sh` 会替换 8081 live 目录。它只用于同一候选完成灰度 验收后的全量晋升;在晋升证据校验完成前继续硬阻断非 dry-run,不能拿灰度入口替代晋升批准。 `scripts/release-portal-runtime-prod.sh` 必须按以下顺序执行: 1. `check-release-ready.sh` 2. 获取完整 `main` SHA 和远端 CI 状态 3. 构建 Candidate artifact 4. 计算 artifact SHA256 5. 读取对应 Gate report;不存在或过期时自动读取 103 稳定 commit 并执行 Core + Impact Gate 6. 从 Git diff 重算并校验 base commit、changed paths、影响域、selected IDs、artifact、环境和有效期 7. 执行 103 只读预检 8. 请求本次发布的明确人工批准,批准后才允许上传 以下情况必须直接退出: - 使用 `--skip-tests` - 使用范围绕过变量 - report 不存在、过期或解析失败 - commit 或 artifact SHA 不一致 - 任一被选场景失败、跳过、未知、未执行或清理失败 - 影响选择结果不可重现或存在未映射路径 - 103 有活动任务且未完成排空 - 备份、磁盘空间、数据库锁或回滚预检失败 当前脚本会先尝试验证已有报告;报告缺失或过期时,只读获取 103 稳定 manifest 的 `git_head` 并自动执行风险分层 Gate。任何 artifact 上传、runtime 切换或生产写操作前都必须 再次通过 `verify-release-gate-report.mjs`,并硬拒绝 `--skip-tests`、 `ALLOW_PORTAL_RELEASE_SCOPE_BYPASS` 和 `ALLOW_MINDSPACE_PUBLIC_LINK_ISSUES`。Gate report 绑定 `.runtime/portal` 的排序目录树 SHA256;打包后的传输压缩包另行记录自身 SHA256。 ## 11. 发布后的最小保护 生产切换后立即执行只产生最小业务影响的烟雾验证: - Portal 本地和公网健康检查 - 登录与登出 - 新建最小聊天并收到回复 - SSE 终态 - 读取一张既有公开页 - 读取一个既有 Page Data 页面 - MindSpace health/contract - 9 个 goosed、worker 和隧道状态 - 日志中无数据库迁移、鉴权、循环重启和大面积 5xx 任何一项失败,必须自动回滚到 Gate report 记录的旧 release,并保存失败证据。 ## 12. 审核与维护 1. 新增生产功能时,必须同时新增场景或明确映射到已有场景。 2. 删除场景必须说明对应生产功能已删除,并经过审核。 3. 事故修复必须把复现路径加入本守门员或 `docs/regression-guards/`。 4. 场景实现不能只检查 HTTP 200,必须验证真实业务结果。 5. 任何脚本都不得自动把失败改成 `not_applicable`。 6. 发布人不能单独审批自己提出的豁免。 7. Gate report 和发布 manifest 应按 release ID 归档。 8. 本文、`PRODUCTION_RELEASE_RULES.md` 和发布脚本的规则必须保持一致。 ## 13. 生产失败回归语料库 ### 13.1 2026-07-26 只读审计基线 以下数字仅用于说明场景来源和风险优先级,是一次性时间点证据,不是生产实时不变量,也不能替代发布前重新验证: | 对象 | 审计结果 | 对应守卫重点 | |---|---:|---| | 注册用户 / 有聊天用户 | 122 / 70 | 用户隔离、旧数据兼容、长尾任务 | | 会话快照 / 快照消息 | 739 / 16,628 | Finish、恢复、消息顺序、历史契约 | | 规范化消息 | 10,009 | 快照与规范化消息一致性 | | 快照中未进入规范化表的用户或助手文本 | 824 | CHAT-13、CHAT-15 | | Agent Run | 1,297,失败 108(8.33%) | 故障分类、终态、恢复与真实交付 | | 当前生产版本以来 Agent Run(自 2026-07-23 17:48:55 +08:00) | 42,失败 8(19.05%) | 当前版本 P0 回归样本 | | 微信消息 | 1,701,失败 245,仍 processing 17 | 微信终态、窗口限制、图片和交付 | | 当前生产版本以来微信消息(自 2026-07-23 17:48:55 +08:00) | 78,失败 13 | 当前版本 P0 微信回归样本 | | 活跃记忆 / 有 evidence 的记忆 | 8,709 / 418 | 来源追踪和异常扩张 | | 缺少 evidence/source 的活跃记忆 | 3,457 | MEM-15 | | 单条 evidence 最大记忆数 | 1,019 | MEM-14 | | 精确重复组 / 额外重复记录 | 164 / 182 | MEM-15 | | 疑似内部提示型记忆 | 13 | MEM-13、MEM-16 | Agent 失败按规范化根因聚类后,至少覆盖以下 14 类 fixture: | 根因 | 审计计数 | 场景映射 | |---|---:|---| | Page Data schema、绑定或扩展错误 | 33 | DATA-10、DATA-13、AGENT-10 | | 心跳过期或 stale run | 12 | AGENT-11 | | 已有活动请求冲突 | 10 | CHAT-11 | | 缺少公开页或交付物 | 9 | PAGE-12、FILE-08、WX-13 | | 工具或任务超时 | 7 | XLS-11、AGENT-11 | | Finish / 终态代码异常 | 7 | CHAT-06、CHAT-13、CHAT-15 | | 生图工具或结果异常 | 7 | PAGE-04、PAGE-06、PAGE-13 | | 数据库 role / 权限错误 | 6 | AGENT-10 | | 历史消息契约异常 | 5 | CHAT-12 | | 数据库方言错误 | 4 | AGENT-10 | | runtime 模块缺失 | 4 | REL-11、AGENT-10 | | request ID 格式异常 | 2 | CHAT-12 | | 数据库连接池耗尽 | 1 | AGENT-11、COMP-08 | | worker 重启中断 | 1 | AGENT-11 | ### 13.2 回归语料结构 建议在实现阶段建立以下目录;本节只定义契约,不代表目录或执行器已经创建: ```text scenarios/production-regressions/ ├── agent-run/ ├── page-data/ ├── memory/ ├── wechat/ ├── files/ └── manifests/ ``` 每个 fixture 必须包含: - 稳定 ID,例如 `PRC-AGENT-001`,以及映射的 guardian scenario ID。 - 脱敏后的用户意图和最小合成输入,不保存原始聊天全文。 - 规范化失败签名、触发能力、依赖和故障注入条件。 - 预期终态、用户可见结果、数据库/文件断言和清理断言。 - 受控审计批次 ID、不可逆且不可反查用户的证据摘要、首次发现版本和修复版本,用于审计追踪。 - `contains_personal_data=false`、隐私审核人和审核时间。 严禁写入 Git 或 Gate report: - 原始用户聊天、记忆正文、附件内容或生产数据库快照。 - 姓名、邮箱、手机号、OpenID、Cookie、token、密钥、内部用户 ID 和可反查标识。 - 生产文件 URL、workspace 路径或能够重新定位用户资源的哈希。 ### 13.3 从生产失败晋升为回归用例 1. 对生产只做授权范围内的只读聚合;原始数据留在受控环境。 2. 按语义根因去重,不能简单地把每条失败记录复制成一个测试。 3. 用合成用户、合成文件和最小输入重建失败,替换全部身份和业务内容。 4. 完成隐私审核,确认无法从 fixture 反推出用户或原始任务。 5. 将 fixture 映射到至少一个场景 ID;新能力或新根因必须新增场景。 6. 在隔离环境复现旧版本失败,并验证修复版本通过,保存确定性证据。 7. 当前版本审计发现的 8 个 Agent 失败和 13 个微信失败必须先去重、脱敏并进入 P0 回归清单。 未完成脱敏、无法稳定重建或仍依赖生产数据的记录,保留为待分析证据,不能伪装成已覆盖测试。 ### 13.4 闸门判定 - `COMP-09` 每次发布强制执行,不能标记为 `not_applicable`。 - 回归语料库中的全部 active fixture 必须通过;`failed`、`skipped`、`unknown` 和未执行均阻断。 - fixture 只能使用隔离数据库、合成账号、Stub 或独立 Canary,执行器必须拒绝生产地址和凭据。 - 新生产事故或用户任务失败在归因后必须进入回归待办;修复关闭前必须落为可回放 fixture 或给出经审核的不可自动化理由。 - 历史 fixture 只在对应功能已删除且完成审核后才能退役,不能因为不稳定或失败而删除。 ### 13.5 首批强制参数化 case 场景族通过不等于只跑一条 happy path。首批实现必须至少包含下表参数;同一行可以由多个 fixture 覆盖,但报告必须能反查到每个参数的执行证据: | 场景 | 必测参数 | |---|---| | CHAT-11 | active request 下排队、取消、新会话;前一任务成功、失败、超时三种终态 | | CHAT-12 | legacy `userVisible`/`agentVisible`、非 UUID request ID、缺失可选字段、损坏 tool history | | CHAT-13、CHAT-15 | 单字回复、Finish 同批到达、Finish 先后乱序、SSE 断线、轮询恢复、重复同步 | | MEM-13 至 MEM-16 | routing/skill/tool prompt、无 evidence、单证据超量、重复摄取、语义重复、纠正、遗忘、legacy 回灌 | | FILE-08 | 登录下载、公开下载、token 过期、跨用户、按钮 URL、微信 media/link 交付 | | XLS-11、XLS-12 | 约 5MB、多 sheet、工具超时、降级解析、数字校验、已有看板增量更新、用户纠正保留 | | PAGE-11 至 PAGE-13 | 搜索 Provider 失败不得伪造来源;缺 HTML/artifact/封面/摘要/品牌;强制生图无工具、无有效位图及“换一个” | | DATA-13 | `survey_page_should_not_be_read_only`、缺 page-data client、legacy API、localStorage、缺字段、重复 `created_at`、禁用软删、过期页面版本 | | AGENT-10、AGENT-11 | SQLite/MySQL/PostgreSQL 方言、role 权限、模块缺失、连接池耗尽、timeout、stale heartbeat、worker restart | | WX-09 至 WX-13 | 重复 callback 不重复执行/扣费、stale processing、图片历史 + 文字追问、45047、45015、AMR/ASR 失败、原子页面交付 | | MS-09 | 无网络字体、缺字体、PDF/DOCX 生成失败、文件不存在、直接下载和原生渠道交付 | | CFG-08 | 当前模型、legacy 模型、未知模型、Provider 切换、目录升级迁移,例如无效 `deepseek-chat` 到有效目录项 | | COMP-09 | 每个 active 生产回归 fixture、生产地址拒绝、生产凭据拒绝、清理失败 | 任何参数缺少结果时,对应场景状态必须为 `failed` 或 `unknown`,不能只用场景族中的其他 case 通过来覆盖。