fix: use k8s git mirror source snapshots

This commit is contained in:
Codex
2026-07-01 10:32:05 +00:00
parent 79e419ce98
commit c90ad04bff
19 changed files with 481 additions and 168 deletions
@@ -22,7 +22,7 @@
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) |
| 上级规格 | [PJ2026-010603 YAML运维](PJ2026-010603-yaml-first-ops.md) |
| 关联规格 | [PJ2026-010601 发布流水](PJ2026-010601-controlled-release.md)、[PJ2026-010602 源码同步](PJ2026-010602-source-sync.md)、[PJ2026-010604 公开入口](PJ2026-010604-public-entry.md)、[PJ2026-010605 运维监控](PJ2026-010605-observability-monitoring.md) |
| 实现引用版本 | draft-2026-06-25-p0 |
| 实现引用版本 | draft-2026-06-25-p0; draft-2026-07-01-cicd-source-snapshot |
| 规格治理索引 | [规格治理](spec-governance.md) |
本文采用 ISO/IEC/IEEE 29148 需求规格模板的项目裁剪版:正文只保留 CI/CD、YAML-first 和平台运维 CLI 控制面源码拆分的稳定目标、边界、架构、阶段和验收口径。
@@ -31,7 +31,7 @@
### 2.1 目的
控制面模块化负责把 UniDesk CI/CD、YAML-first 和平台运维 CLI 中的超大 TypeScript 入口拆成可维护的领域模块,使命令路由、配置解析、manifest 渲染、远端脚本、Secret/public exposure、git-mirror、Tekton/Argo、status summary 和 bounded output 各有明确归属。
控制面模块化负责把 UniDesk CI/CD、YAML-first 和平台运维 CLI 中的超大 TypeScript 入口拆成可维护的领域模块,使命令路由、配置解析、manifest 渲染、远端脚本、Secret/public exposure、git-mirror、source snapshot resolver、Tekton/Argo、status summary 和 bounded output 各有明确归属。
本规格的直接治理对象是超过 3000 行的控制面入口文件。第一阶段先做机械拆分和兼容入口保留,第二阶段再收紧 import/export、模块边界和共享 helper;不得在规格未落地前直接进行行为重写。
@@ -39,7 +39,7 @@
- `scripts/src/hwlab-g14.ts``scripts/src/hwlab-node-impl.ts``scripts/src/platform-infra-sub2api-codex.ts``scripts/src/agentrun.ts``scripts/src/platform-infra.ts``scripts/src/deploy.ts``scripts/src/artifact-registry.ts``scripts/src/ci.ts``scripts/src/platform-infra-observability.ts` 的职责拆分。
- 领域子目录的建立、兼容 re-export 入口、机械搬迁追溯标注和 public API 保持。
- 配置解析、manifest 渲染、远端脚本、Secret/public exposure、git-mirror、Tekton/Argo、status summary、bounded output 和低层 helper 的模块边界。
- 配置解析、manifest 渲染、远端脚本、Secret/public exposure、git-mirror、source snapshot resolver、Tekton/Argo、status summary、bounded output 和低层 helper 的模块边界。
- 与 YAML-first source of truth、发布流水、源码同步、公开入口和运维监控规格的一致性。
- `bun scripts/cli.ts <domain> --help`、plan/status/validate/dry-run 等原入口 smoke 验证。
@@ -67,7 +67,7 @@
| 边界项 | 内容 |
| --- | --- |
| 外部使用者 | 平台维护者、发布操作人员、自动化任务和后续代码维护者。 |
| 外部输入 | CLI 命令、YAML 配置、node/lane/target 参数、Secret sourceRef、Git commit 和运行面状态查询请求。 |
| 外部输入 | CLI 命令、YAML 配置、node/lane/target 参数、Secret sourceRef、source snapshot、Git commit 和运行面状态查询请求。 |
| 受控资源 | `scripts/src` 控制面源码、领域子目录、共享 helper、兼容入口、CLI 输出摘要和原入口命令。 |
| 外部输出 | 原 CLI 命令结果、help、plan/status/validate 摘要、dry-run 计划和 redacted 错误。 |
| 用户接口 | 既有 `bun scripts/cli.ts hwlab g14 ...``hwlab nodes ...``agentrun ...``platform-infra ...``ci ...``deploy ...``artifact-registry ...`。 |
@@ -86,10 +86,12 @@ flowchart LR
DomainIndex --> Actions[plan apply status actions]
Actions --> Render[manifest and summary renderers]
Actions --> Remote[remote script builders and capture]
Actions --> Source[git-mirror source snapshot resolver]
Actions --> Secret[Secret/public exposure/git-mirror helpers]
Config --> Ops[common ops primitives]
Render --> Ops
Remote --> Ops
Source --> Ops
Secret --> Ops
Ops --> Runtime[target runtime or dry-run evidence]
```
@@ -163,7 +165,7 @@ CI/CD、YAML-first 和平台运维控制面文件超过 3000 行时,必须进
| --- | --- | --- | --- |
| OPS-MOD-REQ-004 | 模块边界 | PJ2026-01060307 控制面模块化 | [公开入口](PJ2026-010604-public-entry.md)、[运维监控](PJ2026-010605-observability-monitoring.md) |
第二阶段应把 import/export 和依赖方向收敛到稳定边界:options/config 只解析输入,manifest/render 只生成输出,remote/script builder 只封装远端执行文本,Secret/public exposure/git-mirror/Tekton/Argo/status summary 分别归属领域模块或公共 helper。
第二阶段应把 import/export 和依赖方向收敛到稳定边界:options/config 只解析输入,manifest/render 只生成输出,remote/script builder 只封装远端执行文本,source snapshot resolver、Secret/public exposure/git-mirror/Tekton/Argo/status summary 分别归属领域模块或公共 helper。
若多个领域重复实现同一机制,应优先抽到公共 helper;若差异是业务领域真实差异,应保留在领域 adapter 中并在 closeout 说明为 `keep-domain-special`
@@ -187,6 +189,18 @@ Secret 相关模块只能输出对象名、key 名、sourceRef、presence、fing
回滚策略是通过 Git revert 恢复模块边界,不通过复制旧文件、手工 patch 运行面或保留并行 legacy 入口实现长期双路径。若模块化后发现行为回归,应先修复 import/export 或职责边界,再决定是否回退。
### 6.7 OPS-MOD-REQ-007 source plane 单一路径
| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| OPS-MOD-REQ-007 | source plane | PJ2026-01060307 控制面模块化 | [YAML目标治理](PJ2026-01060308-cicd-yaml-first-target-governance.md)、[源码同步](PJ2026-010602-source-sync.md) |
控制面模块必须把 source selection、mirror sync、snapshot creation、PipelineRun source acquisition 和 GitOps publish 明确拆分并串成单一路径。正式入口只能先通过 YAML 解析目标,再通过 k8s git-mirror resolver 得到 source snapshot,随后把同一 snapshot 注入 PipelineRun、status 和 closeout。
不得在同一正式流程中并存 operator host `git ls-remote`、固定 host worktree clone/fetch、node-host shared worktree、PipelineRun mutable branch fetch 和 GitHub direct fetch 等多个 source resolver。历史 local render 或 host workspace 逻辑若暂时保留,必须标注为显式 legacy/debug adapter,不得由 `trigger-current`、Web 哨兵 publish 或 runtime rollout 默认调用。
PipelineRun/status 模块必须把 selected snapshot 与 latest branch/mirror head 分开展示。source snapshot 缺对象、mirror 追新、GitOps flush pending、Argo progressing 和 runtime readiness 是不同阶段,不得用一个 `sourceHead` 字段覆盖全部判断。
## 7. 过程控制
本规格的执行 issue 为 [#903](https://github.com/pikasTech/unidesk/issues/903)。源码文件头部应标注 `SPEC: PJ2026-01060307 控制面模块化 draft-2026-06-25-p0`,并说明文件是薄入口、领域模块还是公共 helper。纯配置、锁文件、生成产物和无法承载注释头的二进制文件可例外。
@@ -22,7 +22,7 @@
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) |
| 上级规格 | [PJ2026-010603 YAML运维](PJ2026-010603-yaml-first-ops.md) |
| 关联规格 | [PJ2026-010601 发布流水](PJ2026-010601-controlled-release.md)、[PJ2026-010602 源码同步](PJ2026-010602-source-sync.md)、[PJ2026-01060307 控制面模块化](PJ2026-01060307-control-plane-modularity.md)、[PJ2026-010604 公开入口](PJ2026-010604-public-entry.md)、[PJ2026-010605 运维监控](PJ2026-010605-observability-monitoring.md) |
| 实现引用版本 | draft-2026-06-25-cicd-yaml-targets |
| 实现引用版本 | draft-2026-06-25-cicd-yaml-targets; draft-2026-07-01-cicd-source-snapshot |
| 规格治理索引 | [规格治理](spec-governance.md) |
本文采用 ISO/IEC/IEEE 29148 需求规格模板的项目裁剪版:正文只保留 CI/CD、YAML-first 和平台运维控制面中 target、lane、Secret、public exposure、PipelineRun/Argo/git-mirror 与公共 ops primitive 的稳定治理口径。
@@ -58,6 +58,8 @@ YAML目标治理负责把 CI、deploy、artifact-registry、HWLAB node/lane、Ag
| lane | YAML 中描述一条 runtime 或 control-plane 运行线的对象,通常包含 node、source truth、runtime namespace、gitops、CI、Secret 和 publicExposure。 |
| configRef | `path/to/file.yaml#object.path` 形式的跨 YAML 引用,解析器只校验引用存在性、类型和摘要,不把合并结果写成第二真相。 |
| sourceRef | Secret 来源声明。输出只能显示来源标识、key 名、presence、fingerprint、字节数和 `valuesPrinted=false`。 |
| source snapshot | CI/CD 触发时由 k8s 托管 git-mirror 解析出的不可变源码快照,至少包含 repository、branch、selectedCommit、stageRef、mirrorCommit、objectPresent、resolver job 和 YAML 来源。 |
| host workspace | operator host 或目标节点上的固定源码 checkout。正式 CI/CD 只能把它作为开发便利或显式 legacy/debug adapter,不得作为发布 source truth。 |
| hidden default | 代码在未显式参数或未读取 YAML 时自动选择固定目标、namespace、route、registry、lane 或工作目录。 |
| legacy adapter | 为历史入口保留的隔离兼容路径。它可以拒绝 mutation 或提示替代命令,但不得污染主 runtime lane 解析。 |
| ops primitive | 跨领域复用的配置引用、目标解析、Secret redaction、K8s apply/status、public exposure 和 bounded output helper。 |
@@ -161,6 +163,26 @@ sequenceDiagram
状态输出必须区分 PR merge commit、current source head、PipelineRun、Argo revision、git-mirror pendingFlush 和 runtime readiness;不得只用一个当前 head 推断所有阶段完成。
### 5.6 k8s source snapshot 链路
```mermaid
sequenceDiagram
participant CLI
participant Target as YAML target
participant Resolver as k8s git-mirror resolver
participant Mirror as git-mirror cache
participant Tekton
CLI->>Target: resolve node/lane/sourceAuthority
CLI->>Resolver: ensure or read source snapshot
Resolver->>Mirror: sync/read selected commit and create stageRef
Mirror-->>Resolver: selectedCommit + stageRef + objectPresent
Resolver-->>CLI: sourceSnapshot summary
CLI->>Tekton: create PipelineRun with sourceSnapshot
Tekton->>Mirror: fetch/checkout immutable stageRef or snapshot artifact
```
正式 CI/CD 的源码身份以 source snapshot 为准。`trigger-current`、image publish、GitOps render 和 closeout 不得再从 operator host 的 dirty/stale worktree、当前 branch tip 或 GitHub direct fetch 推导本轮 source identity。upstream fetch 只允许发生在受控 k8s git-mirror resolver/sync 组件内;PipelineRun 只消费 node-local mirror 的不可变 stageRef、PVC 或 bundle artifact。
## 6. 原子需求
### 6.1 OPS-TARGET-REQ-001 YAML target 真相
@@ -217,6 +239,18 @@ D601 maintenance deploy、G14 DEV/PROD retirement、v02-only runtime migration
验收至少覆盖 `ci plan/status --target <id>``artifact-registry plan/status --target <id>``deploy apply --dry-run` 目标来源说明、`hwlab nodes control-plane status --node <node> --lane <lane>` 的 YAML-declared lane、`platform-infra observability plan/status --full` 的 configRef 解析链和 `secrets status --config ... --full` 的脱敏输出。
### 6.7 OPS-TARGET-REQ-007 source snapshot 与 host worktree 禁用
| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| OPS-TARGET-REQ-007 | 源码快照 | PJ2026-01060308 YAML目标治理 | [源码同步](PJ2026-010602-source-sync.md)、[发布流水](PJ2026-010601-controlled-release.md) |
CI/CD source authority 必须由 owning YAML 声明。主路径应支持 `sourceAuthority.mode=gitMirrorSnapshot` 或等价字段,使受控 CLI 通过 k8s git-mirror resolver 选择本轮 `selectedCommit` 并创建不可变 snapshot/stageRef。`sourceAuthority.allowHostGit=false` 时,正式 `trigger-current`、image publish、GitOps render 和 closeout 不得执行 operator host `git ls-remote``git fetch``git clone``git rev-parse HEAD` 或读写固定 host workspace。
PipelineRun source step 不得以 mutable `refs/heads/<branch>` 作为本轮源码身份。它只能从 source snapshot 的 `stageRef`、commit-pinned mirror ref、PVC 或 bundle artifact checkout;若对象缺失,应返回 `source-snapshot-missing`,并输出受控 `git-mirror sync/ensure-snapshot` 下一步,不得回退到 GitHub direct clone、host workspace repair 或第二套 source resolver。
status/closeout 必须同时展示 selected snapshot、PipelineRun snapshot、latest mirror head、GitOps revision 和 runtime provenance。branch 在发布过程中前进只能标记为 `latest-drift``superseded`,不得把 selected commit 的成功发布误判为本轮失败。
## 7. 过程控制
本规格的执行 issue 为 [#911](https://github.com/pikasTech/unidesk/issues/911)。源码文件头部应标注 `SPEC: PJ2026-01060308 cicd-yaml-targets draft-2026-06-25-cicd-yaml-targets`;自动生成文件、纯配置、锁文件和无法承载注释头的二进制产物可例外。
@@ -25,6 +25,7 @@
| Monitor Web 聚合实现引用版本 | draft-2026-06-26-p10-monitor-web-aggregation |
| Monitor Web 观察面板治理实现引用版本 | draft-2026-06-27-p11-monitor-web-observability-dashboard; draft-2026-06-27-p12-cadence-scheduler-monitor-web |
| Cadence/OTel 稳定性实现引用版本 | draft-2026-07-01-p15-cadence-otel |
| CI/CD source snapshot 实现引用版本 | draft-2026-07-01-p16-cicd-source-snapshot |
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) |
| 上级规格 | [PJ2026-010605 运维监控](PJ2026-010605-observability-monitoring.md) |
| 关联规格 | [PJ2026-010401 Web工作台](PJ2026-010401-web-workbench.md)、[PJ2026-0104010803 Workbench唯一投影](PJ2026-0104010803-workbench-unique-projection.md)、[PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[PJ2026-010601 发布流水](PJ2026-010601-controlled-release.md)、[PJ2026-010602 源码同步](PJ2026-010602-source-sync.md)、[PJ2026-010603 YAML运维](PJ2026-010603-yaml-first-ops.md)、[PJ2026-010604 公开入口](PJ2026-010604-public-entry.md)、[PJ2026-01060505 Workbench性能](PJ2026-01060505-workbench-performance.md) |
@@ -49,6 +50,7 @@ Web哨兵必须遵循 UniDesk YAML-first ops。目标 node/lane、public origin
- 常驻 TypeScript 单 Pod wrapper 服务、scheduler、scenario runner、PVC/SQLite index、health、metrics、maintenance API 和 dashboard。
- `sentinel plan|apply|status|validate|report|maintenance``sentinel image|control-plane` 等受控 CLI 入口。
- 发布流水 maintenance start/stop、quick verify、targetValidation、GitOps/Argo/git-mirror closeout 和 public exposure 验证。
- 哨兵自身 CI/CD 的 k8s git-mirror source snapshot、PipelineRun source acquisition、GitOps publish 和 selected/latest closeout。
- Dashboard 信息架构、规范化 API、前端组件分层、自动刷新、筛选、深链和 trace/turn 两层阅读视图。
- Vue `monitor-web` 观察面板的趋势曲线、固定视口三栏、运行时间线、cadence freshness、root cause 可见性和配套 CI/CD。
- `workbench-dsflash-go-tool-call-10x` 生产 canary 和 24 小时 dry-run 收口。
@@ -93,6 +95,7 @@ Web哨兵必须遵循 UniDesk YAML-first ops。目标 node/lane、public origin
| auto refresh | Dashboard 的受控刷新能力;刷新只读 API/report/index,不发送 control command、不启动采样、不制造第二事实源。 |
| public exposure | YAML 声明的 `monitor.pikapython.com` HTTPS 暴露,通过共享 PK01 Caddy + FRP managed-block helper 到达 ClusterIP Service。 |
| targetValidation | 发布流水中的目标验证结果;对 HWLAB Web 恢复的判定必须来自 observe/analyze 对 public origin 的观察,不得只看 Argo green。 |
| source snapshot | 哨兵自身 CI/CD 触发时由 k8s git-mirror 解析出的不可变源码快照,绑定 selected commit、mirror ref、PipelineRun、GitOps revision 和 runtime image。 |
| monitor-web | 独立于 sentinel-runner 的 Vue 3 + TypeScript + Vite 展示和聚合层,承载 `monitor.pikapython.com` root、多哨兵总览、趋势曲线、时间线、单哨兵详情和受控截图验收。 |
| cadence freshness | 根据 YAML cadence、scheduler heartbeat、latest run age、active/planned run 和 analyzed report 更新时间计算的运行新鲜度;它默认是非阻塞值守告警,只有真正导致 run/report 不产生或业务链路不可用时才升级为 blocker。 |
| env reuse | CI/CD 复用既有 env image、依赖缓存、BuildKit 层和未受影响服务的发布产物,以避免无关重建;小范围变更应在 status/closeout 中暴露 build/reuse 摘要。 |
@@ -515,6 +518,10 @@ P8 恢复判定必须把 Workbench 业务失败继续 drill-down 到运行面依
Web哨兵自身必须纳入受控且独立的 sentinel control-planesource 来自 UniDesk `master`,镜像、GitOps path、Argo Application、publicExposure 和 targetValidation 由 Web 哨兵 owning YAML 声明。D601/v03 当前可通过 `web-probe sentinel image|control-plane` 的独立 publish Job 实现构建、推送、GitOps 写回和 Argo 收敛;后续也可以切换到 Tekton Pipeline,但 builder 类型必须来自 YAML,不得依赖 operator 本地 dirty worktree。
哨兵自身 CI/CD 的 source identity 必须来自 k8s git-mirror source snapshot。`trigger-current` 应先通过 YAML 声明的 git-mirror cache/service 在 k8s 内解析并同步 selected commit,再把同一 source snapshot 注入 publish PipelineRun、GitOps 写回、status 和 closeout。operator host 上的 `git ls-remote``git fetch``git clone``git rev-parse HEAD` 和固定 host worktree 读写不得参与正式 source selection。
publish PipelineRun 的 source step 只能消费 source snapshot 的 commit-pinned mirror ref、stageRef、PVC 或 bundle artifact;不得把 mutable `refs/heads/<branch>` 作为本轮 source identity,也不得在 mirror 对象缺失时回退到 GitHub direct clone 或 host workspace repair。mirror 缺对象时必须结构化失败为 `source-snapshot-missing` 或等价故障码,并输出受控 source-mirror sync/ensure 命令。
哨兵 rollout 与 HWLAB runtime rollout 不是同一个滚动单元。哨兵 dashboard/API/服务代码变更应通过 Web 哨兵独立 control-plane 滚动;HWLAB runtime 发布流水只调用当前已部署哨兵的 `maintenance/start``maintenance/stop` 和 quick verify 作为恢复判定。哨兵 control-plane 的顶层状态只表达哨兵自身 source、镜像、GitOps、Argo、runtime、metrics 和 dashboard 是否发布成功;HWLAB quick verify 必须作为独立 `targetValidation` 状态、warning 和 report 证据输出。哨兵 validate、maintenance 和 quick verify 控制路径必须优先走 k3s 内部 Service DNS,不绕 `monitor.pikapython.com` 公网入口。
哨兵镜像构建应使用 YAML 声明的 tools image、base image、registry、egress proxy 和 env-reuse 配方。Node/Bun/Playwright/Chromium 依赖不得在 runtime Pod 中临时下载。Secret 与 env 复用只走 sourceRef/keyMapping;日志、status、dashboard 和 issue closeout 只输出 object/key/presence/fingerprint/digest。
@@ -525,6 +532,8 @@ HWLAB runtime 发布 Pipeline 应在 Argo sync 前调用当前哨兵 `maintenanc
`web-probe sentinel control-plane trigger-current --confirm --wait` 只等待 source mirror、publish、flush、publicExposure、Argo 和 runtime observed 收敛;CI/CD confirm-wait 超过 YAML `confirmWait.maxSeconds` 时必须输出 warning,并先优化等待阶段耗时,不得继续把长业务验证塞在部署同步路径里死等。`sentinel validate --quick-verify --confirm --wait` 和 maintenance stop quick verify 才执行 targetValidation 业务验证;业务 quick verify 的等待预算由 YAML `targetValidation.maxSeconds` 控制。计时超限本身只作为非阻塞告警;只有真正影响 Code Agent 多轮业务链路、submit/command 执行、trace/final 可见性或 session 连续性的失败才构成 targetValidation blocker。不得通过减少业务轮次、吞掉 submit 失败、fallback 到第二执行路径或读侧 repair 来消除红灯。
status/closeout 必须同时展示 selected source snapshot、latest mirror head、PipelineRun source snapshot、GitOps revision、runtime image digest 和 runtime observed 状态。若 `master` 在发布过程中继续前进,只能标记为 `latest-drift``superseded`;不得把 selected commit 已发布成功的结果覆盖成“追最新失败”。
### 6.6 OPS-SENTINEL-REQ-006 dsflash-go 十轮 canary
| 编号 | 短名 | 主责模块 | 关联模块 |