From 7721d1578bd5d291ed9368ac785f4eb4929dcc59 Mon Sep 17 00:00:00 2001 From: Code Queue Review Date: Sat, 23 May 2026 13:20:01 +0000 Subject: [PATCH] docs: complete DEV CD authority contract --- AGENTS.md | 2 +- docs/reference/README.md | 3 +- docs/reference/deployment-publish.md | 103 ++++++++++++++++++++++++--- 3 files changed, 95 insertions(+), 13 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index db5072b3..38faf63c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -34,7 +34,7 @@ HWLAB 是硬件实验室运行面和控制面项目。本文是 agent、指挥 - 文档治理与 docs-spec 本地权威:[docs/reference/documentation-governance.md](docs/reference/documentation-governance.md) - 架构和 M3 主线:[docs/reference/architecture.md](docs/reference/architecture.md) - DEV 运行态、端口、k3s 和 DB DNS 边界:[docs/reference/dev-runtime-boundary.md](docs/reference/dev-runtime-boundary.md) -- 部署正规化、`deploy.json` DEV CD 路径、镜像发布、回滚和 Cloud Web 路径:[docs/reference/deployment-publish.md](docs/reference/deployment-publish.md) +- 部署正规化、`deploy.json` DEV CD 路径、SecretRef preflight、runner/host 边界和镜像发布:[docs/reference/deployment-publish.md](docs/reference/deployment-publish.md) - Code Agent 对话就绪与真实回复判定:[docs/reference/code-agent-chat-readiness.md](docs/reference/code-agent-chat-readiness.md) - MVP E2E 验收测试与带编号测试报告 issue 规则:[docs/reference/MVP-e2e-acceptance.md](docs/reference/MVP-e2e-acceptance.md) - 指挥官协作、PR 和 runner 交接:[docs/reference/commander-collaboration.md](docs/reference/commander-collaboration.md) diff --git a/docs/reference/README.md b/docs/reference/README.md index 3db463c7..f8233271 100644 --- a/docs/reference/README.md +++ b/docs/reference/README.md @@ -20,7 +20,7 @@ | 文档治理与 docs-spec 本地权威 | [documentation-governance.md](documentation-governance.md) | | 架构和 M3 上位约束 | [architecture.md](architecture.md) | | DEV 运行态、端口、k3s、DB readiness 和环境边界 | [dev-runtime-boundary.md](dev-runtime-boundary.md) | -| 部署正规化、`deploy.json` DEV CD 路径、单事务入口、artifact 发布、回滚和 Cloud Web rollout | [deployment-publish.md](deployment-publish.md) | +| 部署正规化、`deploy.json` DEV CD 路径、SecretRef preflight、runner/host 边界、artifact 发布和 Cloud Web rollout | [deployment-publish.md](deployment-publish.md) | | Cloud Workbench 默认界面和 UX 边界 | [cloud-workbench.md](cloud-workbench.md) | | Code Agent chat 同源通道 readiness 与真实回复判定 | [code-agent-chat-readiness.md](code-agent-chat-readiness.md) | | MVP E2E 验收测试与带编号测试报告 issue 规则 | [MVP-e2e-acceptance.md](MVP-e2e-acceptance.md) | @@ -41,6 +41,7 @@ - [pikasTech/HWLAB#61](https://github.com/pikasTech/HWLAB/issues/61):DEV 手动 rollout 复盘,以及走向 CLI 加 `deploy/deploy.json` 自动化的路径。 - [pikasTech/HWLAB#109](https://github.com/pikasTech/HWLAB/issues/109):文档治理和长期参考体系。 - [pikasTech/HWLAB#116](https://github.com/pikasTech/HWLAB/issues/116):服务部署正规化三阶段:长期参考、受控 CLI/脚本入口、UniDesk CI/CD 加镜像化交付。 +- [pikasTech/HWLAB#235](https://github.com/pikasTech/HWLAB/issues/235):Cloud API、DB、部署与运行态专题,承载 deploy.json、DEV CD、runtime 和 16666/16667 运行态收敛关系。 - [pikasTech/HWLAB#340](https://github.com/pikasTech/HWLAB/issues/340):`deploy.json` DEV CD 路径长期化、master CLI wrapper、Secret preflight 和恢复后健康审计。 当 issue、报告或旧文档与本目录 reference 文档冲突时,先更新 reference 文档,再让 `AGENTS.md` 保持短索引。过程记录不得被改写;只能把稳定结论蒸馏进这里。 diff --git a/docs/reference/deployment-publish.md b/docs/reference/deployment-publish.md index 33c0a6ff..c2bbfc2a 100644 --- a/docs/reference/deployment-publish.md +++ b/docs/reference/deployment-publish.md @@ -23,7 +23,9 @@ Every DEV CD status, apply, rollback, smoke, and manual Kubernetes command must use `KUBECONFIG=/etc/rancher/k3s/k3s.yaml` and verify node `d601` before any mutation or acceptance. Bare `kubectl`, `docker-desktop` context, `desktop-control-plane`, or `127.0.0.1:11700` are wrong-control-plane signals, -not HWLAB DEV-LIVE evidence. +not HWLAB DEV-LIVE evidence. A second `hwlab-dev` control plane, including a +Docker Desktop cluster that happens to contain similarly named resources, is a +blocker and cannot be used as deploy, rollout, smoke, or acceptance proof. ## Workspaces @@ -107,7 +109,7 @@ status/dry-run 中执行 rollout。这些模式 host commander 和 runner 都可 不可用时,状态面应返回 `lock.status=unavailable` 和脱敏原因,而不是把 只读观测失败升级成写路径 blocker。 -## 当前已验证的 `deploy.json` 部署路径 +## `deploy.json` DEV CD 路径 当前已经验证可用的过渡路径是:master server 只作为受控指挥入口,通过 UniDesk CLI 进入 D601;D601 上使用干净 HWLAB 工作区运行本仓库 @@ -119,18 +121,29 @@ UniDesk CLI 进入 D601;D601 上使用干净 HWLAB 工作区运行本仓库 单事务入口和发布锁见 [pikasTech/HWLAB#274](https://github.com/pikasTech/HWLAB/issues/274), D601 控制面归一见 [pikasTech/unidesk#138](https://github.com/pikasTech/unidesk/issues/138)。 -受控入口形态: +稳定调用合同如下;外层 master CLI 或 UniDesk wrapper 只能包裹这些 +repo-owned 入口,不能绕过它们直接拼接 publish、apply、rollout 或 smoke: + +| 目的 | 稳定入口 | 副作用边界 | +| --- | --- | --- | +| 读取 DEV CD 状态 | `node scripts/dev-cd-apply.mjs --status` | 不写入、不获取 Lease、不读取 Secret value。 | +| 事务 dry-run preflight | `node scripts/dev-cd-apply.mjs --dry-run` | 不 publish、不 apply、不 rollout。 | +| 检查 desired-state 收敛 | `node scripts/deploy-desired-state-plan.mjs --promotion-commit --check` | 只读 source/report。 | +| 执行 DEV CD 事务 | `node scripts/dev-cd-apply.mjs --apply --confirm-dev --confirmed-non-production --write-report` | 仅 DEV,在 `Lease/hwlab-dev/hwlab-dev-cd-lock` 下 publish/apply/verify。 | +| 读取 D601 k3s 证据 | `node scripts/d601-k3s-readonly-observability.mjs` | 只读可见性报告;不 rollout、不输出 Secret value。 | + +使用 master-side wrapper 时,稳定形态是: ```sh cd /root/unidesk -bun scripts/cli.ts ssh D601 argv bash -lc 'cd /home/ubuntu/hwlab-cd-master-cli && node scripts/dev-cd-apply.mjs --status' -bun scripts/cli.ts ssh D601 argv bash -lc 'cd /home/ubuntu/hwlab-cd-master-cli && node scripts/dev-cd-apply.mjs --apply --confirm-dev --confirmed-non-production --write-report' +bun scripts/cli.ts ssh D601 argv bash -lc 'cd && KUBECONFIG=/etc/rancher/k3s/k3s.yaml node scripts/dev-cd-apply.mjs --status' +bun scripts/cli.ts ssh D601 argv bash -lc 'cd && KUBECONFIG=/etc/rancher/k3s/k3s.yaml node scripts/dev-cd-apply.mjs --apply --confirm-dev --confirmed-non-production --write-report' ``` -`/home/ubuntu/hwlab-cd-master-cli` 必须指向干净工作区。该工作区可以是固定 -clean mirror,也可以是一次性 `git clone --shared --no-checkout` 生成的 -ephemeral worktree;它不能是 `/home/ubuntu/hwlab` 这类 runner/历史任务集合 -目录。进入 apply 前必须证明: +`` 必须指向干净工作区。该工作区可以是固定 clean +mirror,也可以是一次性 `git clone --shared --no-checkout` 生成的 ephemeral +worktree;它不能是 `/home/ubuntu/hwlab` 这类 runner/历史任务集合目录。进入 +apply 前必须证明: - `git status --short` 为空; - `.git/FETCH_HEAD` 和 `.git/worktrees` 没有阻止普通部署用户读取或创建 @@ -138,11 +151,45 @@ ephemeral worktree;它不能是 `/home/ubuntu/hwlab` 这类 runner/历史任 - `node scripts/dev-cd-apply.mjs --status` 显示 `promotionSource=deploy-json`; - `deploy/deploy.json` 的 commit、`deploy/artifact-catalog.dev.json` 和 `deploy/k8s/base/workloads.yaml` 收敛到同一个 promotion commit / image tag; -- `kubectl.kubeconfigSource` 指向 D601 原生 k3s,或命令显式设置 - `KUBECONFIG=/etc/rancher/k3s/k3s.yaml`; +- `KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl get nodes` 能看到节点 `d601`; +- `kubectl config current-context`、cluster server 或节点列表没有 + `docker-desktop`、`desktop-control-plane`、`127.0.0.1:11700` 或第二套 + `hwlab-dev` 控制面证据; - `Lease/hwlab-dev-cd-lock` 未被未过期事务持有,或者 stale lock 已由受控 `--break-stale-lock --confirm-dev` 审计处理。 +desired-state 来源关系固定如下: + +| 来源 | 权威范围 | +| --- | --- | +| `deploy/deploy.json` | DEV environment、namespace、endpoint、service set、promotion commit 和事务消费的 image tag。 | +| `deploy/artifact-catalog.dev.json` | 同一 promotion commit 的不可变 artifact digest/tag 证据。 | +| `deploy/k8s/base/workloads.yaml` | Kubernetes workload desired state,必须镜像 `deploy.json` 和 artifact catalog 后才能 apply。 | +| `reports/dev-gate/*.json` | 只作为证据快照;不能覆盖 repo desired state。 | +| `Lease/hwlab-dev/hwlab-dev-cd-lock` | 只作为事务互斥锁和审计状态;永远不是 desired-state 来源。 | + +只改文档的 commit 如果没有修改 `deploy/deploy.json`、 +`deploy/artifact-catalog.dev.json`、`deploy/k8s/base/workloads.yaml`、service +source 或 runtime manifest,就不会产生新的 DEV image 或 promotion commit。 +这类 commit 的 artifact build/publish 结论是 not applicable,除非另一个 +artifact 任务明确更新 desired state。 + +## Runner 和 Host 边界 + +Deployment/CD 工作按以下边界分工: + +| 角色 | 可以执行 | 没有明确 rollout 授权时不得执行 | +| --- | --- | --- | +| Code Queue runner | 准备分支和 PR;在任务授权且检查通过后更新或自合并 docs/code/artifact PR;通过 repo-owned 路径 build/publish artifact;在被分配时刷新 artifact report 或 desired-state 文件;运行只读 `status`/`dry-run`/preflight 检查。 | 竞争 DEV CD Lease、执行 DEV apply、rollout、声称 `16666/16667` live verification、收口 `#7` 或 `#242`、修改 PROD、打印 Secret value、手工修 live resource。 | +| Host commander | 在需要指挥官 review 时审阅并合并最终 PR;执行单一 DEV deploy apply 事务;执行 rollout 和 `16666/16667` live verification;收口 `#7`/`#242` 状态。 | 绕过 repo-owned CD 入口、使用第二控制面、用 UniDesk runtime 替代 HWLAB runtime、只凭报告而不做一手复验就当作 live evidence。 | + +Runner 自合并权限只在任务边界内生效。它不授予 DEV apply、rollout、 +live health verification 或看板/status 收口权限。Runner 发布 artifact 时, +输出必须包含 tag、digest 和 report 证据,并把 desired-state convergence 与 +live rollout evidence 分开。 + +## SecretRef Preflight + apply 前还必须把必要 SecretRef 作为 preflight 条件处理,而不是等待 runtime Job 进入 `CreateContainerConfigError`: @@ -156,6 +203,40 @@ DEV-only secret reconcile 从 `unidesk-dev/postgres-dev` runtime source 生成 并写入 `hwlab-dev`;长期应迁移到 declarative secret、sealed/external secret 或统一 secret controller。 +SecretRef preflight report 必须使用布尔值和脱敏 metadata: + +| 检查项 | 必要证据 | 缺失时 blocker | +| --- | --- | --- | +| Source desired-state reference | `deploy/deploy.json` 和 `deploy/k8s/base/workloads.yaml` 声明预期 `secretRef` / `secretKeyRef` name 和 key。 | `contract_blocker`,scope 指向所属 manifest 或 service。 | +| Live D601 Secret presence | 在 `hwlab-dev` namespace 中,repo-owned preflight 或 controller 证明必要 Secret resource 和 key 存在。 | `runtime_blocker`,scope 指向缺失的 SecretRef。 | +| k3s access for the check | 检查使用 `/etc/rancher/k3s/k3s.yaml`,解析到节点 `d601`,没有命中 Docker Desktop 或第二控制面。 | `environment_blocker` 或 `observability_blocker`,scope 指向 D601 k3s visibility。 | +| Redaction | Report 字段声明 `secretValuesPrinted=false`;日志不包含 decoded data、DSN、token、password、kubeconfig material 或 base64 Secret payload。 | `safety_blocker`;在 publish/apply 前停止。 | + +preflight 可以报告 Secret name、key name、namespace、presence boolean、 +owning workload、missing scope 和 repair runbook。它不得粘贴 +`HWLAB_CLOUD_DB_URL`, `HWLAB_CLOUD_DB_ADMIN_URL`, `OPENAI_API_KEY`, bearer +tokens, passwords, kubeconfig contents, or Secret `.data` values into reports, +issues, PRs, logs, screenshots, or chat. + +## Blocker 分类 + +DEV CD report 必须保持 blocker 分类稳定,使 runner 和 host 不读完整事务日志 +也能路由工作: + +| Type | 含义 | +| --- | --- | +| `safety_blocker` | 请求动作会违反 DEV-only、non-secret、non-PROD、lock 或控制面安全规则。 | +| `environment_blocker` | 必要 local/D601 tool、kubeconfig、k3s node、registry、workspace 或 permission 不可用。 | +| `contract_blocker` | Source manifest、desired-state 文件、artifact catalog、report schema 或 promotion provenance 不一致。 | +| `runtime_blocker` | DEV runtime 前置条件或后置条件缺失,包括 SecretRef presence、DB readiness、durable runtime、rollout 或 workload image convergence。 | +| `agent_blocker` | Code Agent provider/model/egress/SecretRef readiness 不完整。 | +| `network_blocker` | public 或 internal endpoint 不可达,或返回无效 health response。 | +| `observability_blocker` | runner 无法观测足够只读证据来证明状态,但底层 runtime 可能仍然健康。 | + +每个 blocker 必须包含 `type`、`scope`、`status` 和单行 `summary`。可行时还 +应包含 `unblockHint` 或 `nextTask`。Secret 相关 blocker 必须声明没有打印 +value。 + 成功收口必须同时具备以下证据: - `scripts/dev-cd-apply.mjs --status` 返回 `status=pass`;