# PJ2026-010601 发布流水

## 修改历史

| 版本 | 对应 commit id | 更新日期 | 变更说明 |
| --- | --- | --- | --- |

当前正文仍在规格治理草稿中；未定稿前不新增版本号，不为单次编辑追加 `待提交` 版本。

## 正文

## PJ2026-010601 发布流水需求规格

## 1. 文档控制

| 字段 | 内容 |
| --- | --- |
| 编号 | PJ2026-010601 |
| 短名 | 发布流水 |
| 层级 | L2 课题 |
| 状态 | 已生效 |
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) |
| 上级规格 | [PJ2026-0106 平台运维](PJ2026-0106-platform-ops.md) |
| 规格治理索引 | [规格治理](spec-governance.md) |

本文采用 ISO/IEC/IEEE 29148 需求规格模板的项目裁剪版：正文只保留受控发布、版本 lane、CI/CD、运行面发布判定和发布入口的通用稳定使命、范围、术语、系统边界、内部分工和原子需求。

## 2. 目的和范围

### 2.1 目的

发布流水负责把 HWLAB 平台服务从 source commit 通过受控 CI/CD、镜像、GitOps 和 rollout 交付到目标 runtime，使发布状态、运行版本、镜像来源和发布判定可追踪、可恢复、可审查。具体服务的固定 branch、namespace、pipeline、镜像、验证组合和 lane 数值只进入对应服务专项规格，不写成通用发布规则。

### 2.2 范围内

- HWLAB 各服务 lane 的通用发布模型、runtime namespace、CI pipeline、GitOps promotion 和 rollout 入口。
- Tekton PipelineRun、Argo CD sync、runtime image、env image reuse、digest-pinned image 和 artifact promotion。
- 发布候选判定中 source revision、GitOps desired state、runtime live state、Postgres migration、SecretRef presence 和 workload readiness 的一致性。
- UniDesk 受控 CI/CD CLI、服务自有 CLI 和服务 health/readiness 在发布验收中的正式入口边界。
- 自测试和综合联调在发布决策中的分层口径：自测试允许 mock，综合联调必须使用真实运行面。

### 2.3 范围外

- Git mirror、source commit authority、bundle/mirror URL 和 artifact catalog 的来源真相归 [源码同步](PJ2026-010602-source-sync.md)。
- YAML 配置、SecretRef sourceRef/targetKey、fingerprint 和受控下发归 [YAML运维](PJ2026-010603-yaml-first-ops.md)。
- 具体服务的业务执行事实归对应业务规格；AgentRun run、command、event、runner job 和 terminal status 归 [AgentRun核心](PJ2026-010201-agentrun-core.md)，AgentRun `v0.1` 专项发布 lane 归 [AgentRun发布Lane](PJ2026-01060105-agentrun-v01-release-lane.md)。
- RuntimeAssembly、AipodSpec、gitbundle 和 Secret projection 归 [Runtime装配](PJ2026-010202-runtime-assembly.md)。
- Backend adapter、provider profile 和真实 provider turn 语义归 [后端Profile](PJ2026-010204-backend-profile.md)。
- 一次性排障、长日志、PR 过程、证据堆叠和文档治理规则不进入本规格正文。

## 3. 术语表

| 术语 | 定义 |
| --- | --- |
| 发布流水 | 从 source commit 到目标 runtime 的受控构建、promotion、GitOps sync、rollout 和发布状态查询链路。 |
| 版本 lane | 按版本隔离的 source branch、runtime namespace、GitOps branch、CI pipeline 和发布验收集合。 |
| PipelineRun | Tekton 中执行构建、镜像发布或 GitOps promotion 的一次流水线运行。 |
| GitOps desired state | GitOps branch 中声明的目标运行面资源状态。 |
| runtime live state | 目标 namespace 中实际运行的 workload、image、config、health 和 readiness 状态。 |
| env image reuse | 基础执行环境镜像按 env identity 复用，普通业务源码变更只改变 boot commit。 |
| 发布计划 | 对精确 source commit 和目标 lane 的只读发布影响分析，至少包含 env reuse、待构建镜像、rollout 服务和范围变化。 |
| 手动发布触发 | 操作者审阅发布计划后，通过受控 CLI 向 PaC 发送 webhook，由 PaC 创建 commit-pinned PipelineRun 的唯一发布 mutation。 |
| 综合联调 | 在真实目标运行面、真实 SecretRef、真实 backend/provider 或服务入口上完成的发布候选验证。 |

## 4. 系统边界和接口

本规格把发布流水作为平台运维内的服务交付系统看待；本章只描述输入、输出和责任边界。

| 边界项 | 内容 |
| --- | --- |
| 外部使用者 | 平台管理员、发布操作人员、服务维护者和需要发布状态的业务模块。 |
| 外部输入 | source commit、deploy 配置、lane 选择、发布计划请求、带 `plan identity` 的手动触发请求、SecretRef presence 和验证请求。 |
| 受控资源 | Tekton PipelineRun、Argo Application、runtime namespace、workload、image、release status、health/readiness 和发布判定结果。 |
| 外部输出 | PipelineRun 状态、image digest、promotion revision、Argo sync 状态、runtime readiness、发布候选结论和 redacted 失败信息。 |
| 用户接口 | UniDesk CI/CD CLI、服务自有 CLI 发布/验证相关入口、服务 health/readiness、Tekton/Argo 受控状态查询入口。 |
| 系统边界 | 发布流水负责让变更以可追踪、可恢复、可判定的方式进入运行面；不替代业务功能实现，不绕过受控 CLI，不把 mock 或 source-only 结果当作发布通过。 |

## 5. 内部分工与规格索引

本规格前四个 L3 只承载服务无关的通用发布规则。AgentRun 固定 branch、namespace、Pipeline、GitOps path、真实 provider turn 等内容只在 AgentRun 专项 L3 中展开，通用发布条款只保留可复用的发布边界。

| 编号 | 模块或课题 | 规格文档 | 主责边界 | 上游依赖 | 下游支撑 |
| --- | --- | --- | --- | --- | --- |
| PJ2026-01060101 | Lane发布 | 本规格 6.1 | source/GitOps/runtime namespace、CI pipeline 和 rollout 入口 | 源码同步、YAML运维 | 全部 runtime 服务 |
| PJ2026-01060102 | 镜像Promotion | 本规格 6.2 | env image reuse、digest-pinned image、artifact promotion 和 image readiness | Source commit、Containerfile、registry | 需要运行镜像的服务 |
| PJ2026-01060103 | 发布判定 | 本规格 6.3 | source/GitOps/runtime 一致性、health/readiness 和 migration/SecretRef presence | CI/CD、GitOps、YAML运维 | 平台管理员、业务模块 |
| PJ2026-01060104 | 验证分层 | 本规格 6.4 | 自测试、综合联调、CLI/API 交互和真实运行面通过口径 | 目标 runtime、业务模块测试需求 | 发布决策 |
| PJ2026-01060108 | 手动发布 | 本规格 6.5 | L2/L3 发布计划、范围审阅和带 plan identity 的受控手动触发 | 源码同步、YAML运维、镜像Promotion | 全部 L2/L3 runtime 服务 |
| PJ2026-01060105 | AgentRun发布 | [PJ2026-01060105 AgentRun发布Lane](PJ2026-01060105-agentrun-v01-release-lane.md) | AgentRun `v0.1` 的发布 lane、Pipeline、runtime namespace 和真实联调细则 | 源码同步、YAML运维、Agent编排 | AgentRun runtime |
| PJ2026-01060106 | HWLAB双环境 | [PJ2026-01060106 HWLAB双环境](PJ2026-01060106-hwlab-dev-production-lanes.md) | HWLAB `v0.3` development 与 `release` production 的分支、流水线、公开入口和数据隔离 | 源码同步、YAML运维、Workbench实时权威 | HWLAB runtime |
| PJ2026-01060107 | NC01 CI资源治理 | [PJ2026-01060107 NC01 CI资源治理](PJ2026-01060107-nc01-ci-resource-governance.md) | NC01 构建并发、排队、资源合同、稳定去重和核心运行面保护 | 发布流水、YAML运维、CI/CD目标治理 | NC01 CI 与核心服务 |

## 6. 原子需求

### 6.1 OPS-RELEASE-REQ-001 版本 Lane 发布

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| OPS-RELEASE-REQ-001 | Lane发布 | PJ2026-01060101 Lane发布 | [源码同步](PJ2026-010602-source-sync.md)、[YAML运维](PJ2026-010603-yaml-first-ops.md)、[Agent编排](PJ2026-0102-agent-orchestration.md) |

发布流水应为 HWLAB 平台服务提供版本 lane 发布能力，使 source branch、runtime namespace、GitOps branch、CI pipeline 和 rollout 入口相互隔离。

具体服务的 lane 固定值、历史口径废弃项和运行面名称应写入对应服务专项规格；通用发布流水只定义隔离、受控入口、可追溯和不可绕过原则。

CI/CD 目标必须由当前 issue、PR、CLI 参数或受控 lane 配置解析为明确 node + lane。G14 DEV/PROD、G14 v0.2、D601 v0.3 和后续 lane 都只是实例，不得把某个节点、namespace、GitOps path、FRP 端口或历史 `dev/prod` 口径写成通用默认。发布流水只能作用于被选中的 node/lane，不接管其他运行面。

### 6.2 OPS-RELEASE-REQ-002 镜像与 Promotion

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| OPS-RELEASE-REQ-002 | 镜像Promotion | PJ2026-01060102 镜像Promotion | [源码同步](PJ2026-010602-source-sync.md)、[Runtime装配](PJ2026-010202-runtime-assembly.md) |

发布流水应提供镜像构建、env image reuse、digest-pinned image 和 GitOps promotion 能力，使运行面使用的镜像能够追溯到 source commit、Containerfile、env identity 和 artifact 摘要。

需要 work-ready env image 的服务应在自身专项规格中声明工具和依赖要求；通用发布流水只保证镜像来源、digest、promotion 和运行面引用可追溯，不替业务模块定义运行时功能。

Artifact catalog 的 per-service provenance 是镜像 digest 的身份证明，必须能说明 source commit、component input hash、Containerfile hash、build args hash、base image identity、reuse/build 状态和最终 digest。复用旧 artifact 前必须能证明旧 digest 对应的 source tree 与本轮输入一致；缺 digest、缺 provenance 或 hash 不一致时应重新发布，不得用旧 guard、历史 PipelineRun 成功或 mutable tag 伪装通过。

### 6.3 OPS-RELEASE-REQ-003 发布一致性判定

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| OPS-RELEASE-REQ-003 | 发布判定 | PJ2026-01060103 发布判定 | [源码同步](PJ2026-010602-source-sync.md)、[YAML运维](PJ2026-010603-yaml-first-ops.md)、[Agent编排](PJ2026-0102-agent-orchestration.md) |

发布流水应以 source revision、GitOps desired state、runtime live state、image digest、workload readiness、Postgres migration、SecretRef presence 和 service health/readiness 的一致性判断发布候选。

PipelineRun 成功、Argo Synced、health 可访问或 source check 通过都不能单独替代业务运行面通过。发布判定只能输出 redacted 状态和摘要，不得包含 provider credential、Postgres DSN password、token、URL credential 或 Secret value。

- CI/CD 发布就绪只承担最小运行面联通判定：
  - 服务 probe 只调用不依赖数据库、Temporal、外部 provider 或业务数据的 live endpoint；
  - rollout gate 只要求目标 source identity 已进入计划内 workload，且期望副本已 updated 和 ready；
  - Argo 聚合 `Healthy`、业务依赖 readiness 和用户功能验证只能作为发布后独立证据，不得延长或阻塞 CI/CD rollout；
  - 业务综合联调仍按本规格 6.4 独立执行，不得回填到 Kubernetes readiness 或 CI/CD health gate。

### 6.4 OPS-RELEASE-REQ-004 两层验证口径

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| OPS-RELEASE-REQ-004 | 验证分层 | PJ2026-01060104 验证分层 | [Agent编排](PJ2026-0102-agent-orchestration.md)、[客户端](PJ2026-0104-client.md)、[HarnessRL](PJ2026-0103-harness-rl.md) |

发布流水应区分组件自测试和综合联调：自测试允许 mock，用于快速反馈；综合联调必须在真实目标运行面、真实依赖、真实配置和服务原入口上完成。

mock、fake dependency、source-only、dry-run、缺关键配置时的 skip、只读 health 成功或没有真实业务终态的运行面状态，都不能作为综合联调或发布通过证据。具体服务需要哪些真实依赖和终态，由对应服务专项规格定义。

### 6.5 OPS-RELEASE-REQ-005 L2/L3手动计划与触发

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| OPS-RELEASE-REQ-005 | 手动发布 | PJ2026-01060108 手动发布 | [源码同步](PJ2026-010602-source-sync.md)、[YAML运维](PJ2026-010603-yaml-first-ops.md)、[NC01 CI资源治理](PJ2026-01060107-nc01-ci-resource-governance.md) |

L2 与 L3 发布必须使用 `plan -> 人工审阅 -> trigger` 的受控手动链。PR merge、push、branch update、mirror 同步、定时任务和 L0/L1 开发动作只能更新 source authority 或只读状态，不得创建 PipelineRun、构建镜像、推进 GitOps 或触发 rollout。

`plan` 必须是只读操作，并针对精确 target、lane 和 source commit 输出：env identity 及 reuse/build 判定、待构建镜像数量与服务列表、待 rollout 服务、全部受影响服务、范围基线和相对基线新增项。`plan` 不得同步 mirror、创建 snapshot、修改 branch、创建 PipelineRun 或写入运行面。

- `plan identity` 必须由规范化的计划输入与执行范围确定：
  - 输入至少绑定 target、consumer、lane、source commit、base commit、catalog authority、catalog source、catalog digest、registry probe 模式和结果；
  - 执行范围至少绑定 build、rollout 和 affected 服务列表；
  - 列表与对象键必须规范排序，时间戳、临时路径和运行编号不得参与 identity；
  - 相同输入与范围必须产生相同 identity，任一绑定输入或范围变化必须产生不同 identity。
- `trigger` 必须显式携带操作者刚审阅的 `plan identity`：
  - 发送 webhook 前必须用当前 source、base、catalog 和 registry 输入重新生成计划；
  - 重算 identity 与已审阅 identity 不一致时不得发送 webhook；
  - webhook 只携带规范化计划事实，不引入可变计划存储或第二 authority。
- Pipeline 必须在 build 前用同一组输入重新生成计划：
  - 实际 identity 与 webhook 携带的已审阅 identity 不一致时立即失败；
  - build、rollout 或 affected 范围任一扩大时必须输出 expected、actual 和新增服务；
  - identity 校验通过前不得启动镜像构建，CLI 显示 `build=0` 时 Pipeline 不得构建镜像；
  - 不得通过补跑、提高 timeout、忽略 warning 或继续后续 Task 绕过该失败。

`plan` 恢复 artifact catalog 时必须满足：

- 读取 owning YAML 声明的 GitOps read URL 与 branch；
- 与 Argo 和 promotion 使用同一 GitOps authority；
- Source mirror 只用于读取 source commit，不得代替 GitOps authority；
- catalog 无法读取、来源不一致或落后于已部署 revision 时，停止触发并返回重新 plan 的只读引导。
- 发布范围基线必须来自 catalog source：
  - 调用方省略 `base commit` 时，必须使用恢复出的 `catalogSourceCommitId`；
  - 禁止静默回退到 `source commit` 的 parent；
  - 显式 `base commit` 只覆盖请求范围诊断，输出必须同时披露 catalog source 和两者是否对齐；
  - 缺少有效 catalog source 时必须保持只读并 fail closed，不得猜测 parent 或创建 PipelineRun。

范围相对 owning YAML 声明的发布意图扩大时，`plan` 必须明确列出新增项。操作者应先修正源码、配置或 planner，使范围回到预期后重新生成计划；不得通过确认参数、白名单、忽略 warning 或扩大资源预算继续触发。

- 依赖与 component path 重叠时必须保持同一语义判定：
  - `package.json` 只按 dependencies、engine 和模块类型等运行字段参与服务范围与 hash；
  - scripts、格式或其他开发元数据变化不得因 owning YAML 重复声明 `package.json` 而进入服务 changed paths；
  - planner hash 算法升级后，必须从 catalog source commit 按新算法重算并识别 metadata drift；
  - source tree 在新算法下未变化时不得把 metadata drift 判为构建或 rollout。
- `build=0`、`rollout=0` 且 `affected=0` 的计划是终态 no-op：
  - 不得发送 webhook 或创建 PipelineRun；
  - 动态 `next` 必须明确结束，不得指向 `release trigger`。

- Renderer rollout 范围必须对应实际 GitOps Pod template diff：
  - renderer 重建完整 runtime tree 并改写未选 workload 的 source identity 时，`plan` 必须把全部实际受影响 workload 计入 rollout；
  - 只有未选 workload 的 manifest 和 source identity 均保持不变时，才允许显示局部 rollout；
  - renderer 入口拆分到子模块后，全部参与 runtime materialization 的源码路径仍必须属于 planner 的 renderer 输入集合。

唯一 mutation 是受控手动 `trigger`。它必须显式选择 target、lane、精确 source commit 和 pipeline intent，并向 PaC 发送 webhook；PaC 从同一 source authority 创建 commit-pinned PipelineRun。触发前必须先审阅当前输入的非空 plan；计划输入或范围已变化时必须重新 plan。禁止对零范围 plan 触发，禁止 CLI 直建或裸创建 PipelineRun、由 PR 合并回调 trigger，或为兼容旧自动链保留第二入口。

`trigger` 被 PaC 接收后，动态 `next` 必须指向同一 source commit 的只读 `delivery-observe`。不得引导旧 `closeout`、自动同步、人工 PipelineRun 或 Argo mutation；触发失败或输入变化时只能回到重新 plan。

- 手动发布耗时必须按 owning YAML 预算判定：
  - 起点是 CLI webhook 被 PaC durable admission 接收的时间，PR merge 到人工 trigger 的等待不计入发布耗时；
  - 终点是 GitOps promotion 完成且计划内 workload 达到最小运行面联通就绪；
  - env 和服务 artifact 均复用且 build、rollout、affected 全为零时必须以 no-op 结束，不创建 PipelineRun；
  - 超出预算时必须输出 trigger、prepare、plan、build、collect、promote 和 rollout 的可用阶段耗时、最慢阶段与缺失证据，然后停止；
  - 禁止通过提高 timeout、增加业务 health 检查或重复触发掩盖超预算。
