# HWLAB 指挥侧参考 本文定义 UniDesk 指挥官推进 `pikasTech/HWLAB` 时的固定入口、workspace、上线口径和常见误判边界。HWLAB 的项目内操作细则以 HWLAB 仓库自己的 `AGENTS.md` 和 `docs/reference/` 为准;本文只记录 UniDesk 侧如何进入和监督。 ## 固定入口 - UniDesk 指挥侧 workspace:`/root/unidesk`,固定使用 `master`,开始前执行 `git status` 和 `git pull --ff-only origin master`。 - HWLAB legacy G14 DEV/PROD 已退役;`G14`/`G14-gitops`、`hwlab-dev`/`hwlab-prod`、17666/17667 和 18666/18667 不再是当前 source/runtime truth。退役状态和执行入口是 `bun scripts/cli.ts hwlab g14 retirement status|plan|execute --confirm`,细则见 `docs/reference/g14.md`。 - HWLAB 指挥侧目标选择必须以 issue 或 CLI 中明确写出的 lane/node 为准;只有没有明确目标时,才读取 `config/hwlab-node-lanes.yaml` 的默认值。`config/hwlab-node-lanes.yaml` 是 node、lane、workspace、CI/CD repo、namespace、GitOps path、公网入口和 Secret sourceRef 的配置真相,长期参考不能把 G14、D601、v0.2 或 v0.3 写成隐藏默认。 - 进入任何 HWLAB lane 工作前,先解析目标 `--node --lane ` 或 issue 中的“目标分支/目标节点”,再用 YAML 解析出的 route/workspace/sourceBranch/kubeRoute/runtime namespace 做预检、快进和验证。例如 `目标分支: HWLAB v0.3` 且 `目标节点: D601` 时,工作面是 `D601:/home/ubuntu/workspace/hwlab-v03`、source branch 是 `v0.3`、k3s route 是 `D601:k3s`、runtime namespace 是 `hwlab-v03`、公网入口是 `https://hwlab.pikapython.com`。 - HWLAB 项目内长期规则入口仍以目标 repo 的 `AGENTS.md` 为准。进入已解析的目标 workspace 后,必须重新读取该 workspace 的规则文件;不能只凭主 server 的压缩上下文继续操作。 - 每次开始 node/lane 工作前必须通过 UniDesk SSH 桥检查目标 workspace,例如 `trans : sh -- 'git fetch origin && git pull --ff-only origin && git status --short --branch && git remote -v'`;若不满足目标 lane 预期,先修正 workspace,不能继续开发、render、polling 或部署。 - k3s 操作必须使用 YAML 解析出的 route 语法,例如 `trans D601:k3s ...` 或 `trans G14:k3s ...`。第一个 route token 必须定位分布式目标,后续 token 才是 operation。 - D601 node-scoped runtime(例如 `D601` + `v0.3`)不是 legacy;只要 issue/CLI 明确选择 D601 node/lane,就按 YAML 中的 D601 target 执行。D601 legacy 只指旧 DEV/迁移/回滚对照路径(如 `/home/ubuntu/workspace/hwlab-dev`、16666/16667 或历史 `deploy/deploy.json` wrapper),必须由 issue/CLI 明确写成 legacy/迁移/回滚才使用。 - `/root/HWLAB`、`/workspace/hwlab`、`/home/ubuntu/hwlab`、`/tmp/hwlab-*`、无关 runner clone、master-server checkout 或未由 YAML 选中的 workspace 都不能作为当前 HWLAB source truth。 ## 关键 GitHub 入口 - UniDesk 总看板:`pikasTech/unidesk#20`。 - HWLAB 总看板:`pikasTech/HWLAB#7`。 - HWLAB 上位会议/冻结规则:`pikasTech/HWLAB#78`,当前 P0 是 M3 虚拟硬件可信闭环。 - HWLAB Cloud Workbench 用户界面:`pikasTech/HWLAB#99`。 - HWLAB 用户反馈入口:`pikasTech/HWLAB#108`。 - HWLAB 手动发布复盘与自动化收敛:`pikasTech/HWLAB#61`。 `pikasTech/unidesk#20` 只记录 UniDesk 侧 commander、Code Queue、CLI 和 infra governance。HWLAB 用户反馈、Cloud Workbench、DEV-LIVE、M3 闭环和其他产品事项必须写入 `pikasTech/HWLAB` 的 issue;如果需要在 #20 出现,只能作为 UniDesk 侧调度、CLI guard、infra blocker 或验收治理 lane 的上下文,而不能作为 HWLAB 产品 row。 ## 规格真相与仓库 Reference 边界 HWLAB 需求规格的唯一长期正文在 UniDesk OA `project-management/PJ2026-01/specs/`。L0 总规格、硬件池、Agent编排、HarnessRL、客户端、用户管理、平台运维及其 L2/L3 都从这里索引;HWLAB repo 的 issue、PR、runtime reference 和阶段验证 issue 只能承载执行讨论、证据和操作入口,不能重新定义需求。 HWLAB v0.2/v0.3 仓库内 `docs/reference/spec-*`,以及已收编的 `cloud-workbench.md`、`code-agent-chat-readiness.md`、`g14-gitops-cicd.md` / `node-gitops-cicd.md`、`dev-runtime-boundary.md`、`gateway-outbound-demo.md`、`MVP-e2e-acceptance.md`、`architecture.md` 只保留到 UniDesk OA 的交叉引用或历史 stub。repo-local runbook 可以继续说明命令、路径、lane 和调试入口,但不得把公开能力、CLI/API 语义、测试大纲、Gateway 主动出站或 AgentRun 接入要求写成第二份规格正文。 公开入口、FRP/Caddy/域名和 Web/API 可达性需求以 [PJ2026-010604 公开入口](../../project-management/PJ2026-01/specs/PJ2026-010604-public-entry.md) 为权威;Prometheus、日志、trace、health、status 和运维监控需求以 [PJ2026-010605 可观测监控](../../project-management/PJ2026-01/specs/PJ2026-010605-observability-monitoring.md) 为权威。运行配置数值仍以 UniDesk YAML 和目标 HWLAB repo 的受控配置为准,长期 reference 只记录解析与验证方法。 重大规划型 issue 必须执行 P0 SPEC-first:P0 阶段先在 UniDesk OA `project-management/PJ2026-01/specs/` 维护对应 SPEC,确认 SPEC 编号、上级/关联规格、架构图、数据流图、关键时序图和代码引用规则,再进入后续实现。该 issue 范围内新增或修改的源码文件头部必须标注遵循的 SPEC 编号、短名和实现引用版本;自动生成、vendored、纯配置、锁文件或不能承载注释头的二进制产物可例外,但对应生成器、渲染器或配置入口必须能追溯到 SPEC。issue 正文和评论只承载执行计划、讨论和证据,不替代长期 SPEC。 ## DEV 入口 - 退役 G14 DEV/PROD 前端/API 入口曾使用 `http://74.48.78.17:17666/`、`http://74.48.78.17:17667/health/live`、`http://74.48.78.17:18666/` 和 `http://74.48.78.17:18667/health/live`;这些端口不再作为当前 HWLAB runtime 证据。 - 当前入口必须从 `config/hwlab-node-lanes.yaml` 的选中 node/lane 读取,不从长期文档硬编码推断。G14 `v0.2` 的公开入口、G14 `v0.3` 的公开入口和 D601 `v0.3` 的 `https://hwlab.pikapython.com` 都只是各自 YAML target 的结果,不是彼此 fallback。 - D601 `v0.3` 前端/API 入口固定为 `https://hwlab.pikapython.com`,只能按 `config/hwlab-node-lanes.yaml` 中的 `lanes.v03.targets.D601.publicExposure` 验证;域名侧浏览器验收比裸 IP 或旧端口更能覆盖 Caddy、FRP、同源 cookie 和 Vue workbench 路由。 - D601 legacy DEV 前端/API 入口曾使用 `http://74.48.78.17:16666/` 和 `http://74.48.78.17:16667/health/live`;只在显式 D601 legacy 排障或迁移对照时使用,不能作为当前 HWLAB DEV 运行面证据。 - 旧公网 `:6666` 和 `:6667` 不是浏览器验收入口;内部 k3s service 仍可使用 `6667` 作为服务端口。 - 不要把 master 上的其他 UniDesk frontend/backend-core 路径误判为 HWLAB 前端。D601 legacy `16666/16667` 和 retired G14 DEV/PROD 端口的 FRP 说明只用于历史对照。 ## D601 v0.3 User-Billing 管理闭环 D601 node-scoped `v0.3` 已按 `pikasTech/HWLAB#1176` 收敛到 Sub2API-style 的最小多用户运营基线。该基线包括 app-local 注册登录、用户自服务 API key/profile/password、admin users 管理、credit adjust、Code Agent reservation/terminal billing、`/v1/billing/summary`、plan/entitlement/quota/concurrency/RPM、admin usage/ledger filter/export、manual credit audit、redeem/manual recharge,以及 subscription/payment 的 provider-agnostic `unconfigured` 占位。审计细节、PR、PipelineRun、public smoke 和 closeout 证据以 #1176 及其 R1-R6 子 issue 为准;长期参考只记录完成态边界和复验入口。 该能力的 authority 仍是 HWLAB `hwlab-user-billing` 和 PK01 外置 PostgreSQL。Cloud API 只做代理和同源 Web session/API key 鉴权,不维护第二套 user、credit、usage、ledger、redeem、subscription 或 payment 状态;Cloud Web 只消费 Cloud API 暴露的正式路径,不直连 user-billing 内部端口。D601 `hwlab-v03` namespace 内不得为了 user-billing 恢复本地 PostgreSQL StatefulSet/PVC 或第二账户库;`localPostgresAbsent=true` 和 PK01 bridge ready 是关闭和复验时的必要状态证据。 复验 D601 `v0.3` user-billing 管理闭环时使用 `https://hwlab.pikapython.com`,不要用 G14 `v0.2` 的 `19666/19667` 或旧 D601 legacy 端口替代。最小 smoke 应覆盖:`/health/live` revision 指向目标 source commit;admin Web session 登录;admin 创建/list/disable redeem code;普通用户注册或登录后兑换 code;重复兑换 one-time code 不重复入账;admin redemptions 和 ledger 能查到同一 ledger/redemption;subscription/payment summary 在没有真实 provider 配置时明确返回 `unconfigured`;`/billing` 和 `/admin/billing` 页面加载且部署 bundle 包含对应 endpoint。验证输出只能记录对象 id、prefix、状态、计数和 redacted presence,不能打印 bootstrap admin password、raw redeem code、API key secret、DB DSN 或 provider token。 真实 payment provider、外部支付回调、订单结算和增长活动策略不是 #1176 完成态的一部分。只有当 `config/hwlab-node-lanes.yaml` 或 HWLAB 自有受控 YAML 明确声明 provider/sourceRef,并且 Secret sync、回调入口、ledger/order 状态机和 public end-to-end smoke 都齐备时,才可以把 D601 `v0.3` 从 provider-agnostic placeholder 扩展到真实支付;不得通过硬编码 provider、手写 k8s Secret、临时 SQL 或 Cloud API 平行账本绕过 user-billing authority。 ## HWLAB 测试账号 YAML 归属 HWLAB node/lane 测试账号、bootstrap admin API key 观测、普通测试用户固定 API key、workbench 绑定、user-billing DB sync 输入和 sourceRef/targetKey 映射属于 UniDesk 指挥侧运维真相,必须写入 UniDesk `config/hwlab-test-accounts.yaml`,并通过 `bun scripts/cli.ts hwlab nodes test-accounts status|sync --node --lane ` 受控读取和同步。HWLAB 仓库可以保留应用代码、user-billing schema/migration 和业务 API,但不能另建一份账号 YAML 真相,也不能用运行面 Secret、pod env、日志或 DB 结果反推 owner-only key source。 `config/hwlab-test-accounts.yaml` 中的相对 `sourceRef` 以该文件的 `sourceRoot` 为根解析,属于 UniDesk 指挥侧 owner-only source,不要求也不应要求同名文件存在于 D601/G14 目标 host。目标 host 或 runtime pod 中没有该 env 文件不能判定为 key 缺失;应先用 UniDesk 受控 CLI 确认 source 与 target fingerprint,再把选中身份的 `HWLAB_API_KEY` 仅作为一次性进程环境注入目标 HWLAB CLI。不要为了复验把测试用户 key 持久化复制到目标 workspace、shell 启动文件、issue、日志或 Git tracked 文档。 该入口的输出只能记录 logicalId、role、permissions、workbench、sourceRef、sourceKey、targetKey、对象 id、byte count、prefix、fingerprint、presence、matchesSourceFingerprint 和 mutation 摘要;不得打印完整 `HWLAB_API_KEY`、完整 `DATABASE_URL`、base64 payload 或可复制凭据。D601 `v0.3` T1/T2 类验证如果需要 admin/test 两套身份,先用此 UniDesk YAML/CLI 准备账号,再在目标 HWLAB workspace 使用原 `hwlab-cli` 切换 `HWLAB_API_KEY` 做真实入口复验。 身份、权限、workbench、trace/result 和 usage/billing 复验优先使用目标 HWLAB repo 的 typed CLI;`client request` 只能作为缺 typed wrapper 时的有界探测或后端路径确认。若 raw request 覆盖了真实用户验收所需的字段,关闭前必须把缺失的 typed CLI 包装登记到对应 HWLAB issue,不能把 raw request 静默当成长期正式用户入口。 ### Code Agent TraceResult 展示证据 Code Agent trace 的长期 API 和 Web 行为规格以 UniDesk OA 为权威:API 资源形态见 [PJ2026-010403 API契约](../../project-management/PJ2026-01/specs/PJ2026-010403-api-contract.md) 的 `GET /v1/agent/traces/{traceId}`,Web 自动补齐和分片显示见 [PJ2026-010401 Web工作台](../../project-management/PJ2026-01/specs/PJ2026-010401-web-workbench.md) 的 Trace阅读要求。UniDesk 指挥侧只记录验证入口和误判边界,不在本参考重新定义 trace endpoint、分页字段、游标语义或自动折叠策略。 实时 Trace 展示必须把 turn 状态和 trace event 分页视为两条独立读路径。`/v1/agent/turns/:traceId` 只回答 running/terminal/final/error 等 turn 状态;`/v1/agent/traces/:traceId` 只负责按下游读 cursor 拉取已经持久化的 trace events。Web 在运行中不能等 turn terminal 后才 hydrate trace,也不能让 compact turn snapshot 覆盖已经拉到的 trace rows。后端刷新 AgentRun 上游失败时,trace API 仍应返回本地 trace store 中已有的分页快照,并把 refresh failure 作为诊断字段暴露;已有事件不得被硬 502 遮住。关闭“运行中 Trace 加载不出”类 issue 时,应证明 running 期间 trace API 与 Web DOM 都能看到已写入事件,而不是只展示最终完成后的 timeline。 Code Agent trace/result 展示类问题的 typed CLI 关闭证据以 `hwlab-cli client agent result `、`hwlab-cli client agent trace --render web` 和必要的 `hwlab-cli client agent inspect --trace-id ` 为准,具体操作说明见 `$hwlab-code-agent` skill。三者的默认 JSON 都应暴露 `traceResultSummary`,其中 `ids`、`toolCalls`、`agentMessages`、`finalResponse`、`diagnostics`、`counts` 和 `upstreamGaps` 是给用户和审计者阅读的稳定摘要;不要要求关闭者从 raw `body`、`runnerTrace.events`、`rows` 或 `terminalEvidence` 人工拼事实。 `result` 和 `trace --render web` 必须能直接证明 final assistant response、实际工具调用及状态、关键 trace/session/conversation/run/command/runner ID 和 runner/provider/lane 诊断。`inspect` 用于确认 trace 所属 session/conversation/thread、恢复上下文和下一步入口;它可以佐证 ID 和上下文,但不能单独替代 final response 或 Web renderer 行。验证必须打到 issue/CLI 选中的同一 node/lane public origin 或等价 Cloud Web/Cloud API dispatcher,不能用临时 AgentRun manager 调用、手写 raw request 或旧 lane trace 代替。 失败详情类问题必须优先核对 `client agent result ` 的顶层 `error` 与 `agentRun`。`trace --render web` 只证明 rows/timeline 渲染,可能不携带 terminal result 的 `error`、`agentRun.runId`、`commandId`、`runnerId`、`jobName`、`namespace` 或 `terminalStatus`;Cloud Web 恢复会话时必须从 result 补齐这些诊断,再渲染详情弹窗。空字段不得渲染成大面积“未观测”占位;用户第一眼应看到错误码、错误类别和错误消息,有值的 AgentRun provenance 才进入状态摘要。 AgentRun terminal `failed`、`blocked` 或 `canceled` 也是最终结果,不是“没有 final response”。当 `/v1/agent/chat/result/:traceId` 或 `/v1/agent/turns/:traceId` 返回顶层 `error.message`、`blocker.summary` 或 terminal failure message 时,HWLAB Cloud API 必须把可读错误生成为 `finalResponse.text` 和 `traceSummary.finalAssistantRow`,Cloud Web 的 final response 展示区必须直接显示该错误文本。TraceTimeline 可以同时展示失败事件,但不能让用户只能从 trace rows 里找错误;也不能用“没有返回可展示的 final response”覆盖已有 terminal error。 `traceResultSummary.valuesPrinted=false` 只是脱敏声明,不等于免检。关闭前仍应扫描输出中是否出现完整 `HWLAB_API_KEY`、`hwl_live_*`、Authorization Bearer header、DB DSN、Secret payload 或 provider token。若 `upstreamGaps` 出现 `prompt_not_returned_by_upstream`,表示上游 trace/result payload 没有返回可脱敏展示的 prompt metadata;客户端不得发明 prompt 真相,应把该缺口拆到 Agent 编排或 trace payload issue,并说明它是否阻塞当前展示项。 ### Workbench 浏览器回归专项 Workbench 浏览器回归需求以 UniDesk OA [PJ2026-010401 Web工作台](../../project-management/PJ2026-01/specs/PJ2026-010401-web-workbench.md) 为权威;具体 Web 开发、fake-server Playwright、fixture 采集脱敏、移动端断言、截图 artifact 和线上 web-probe 闭环统一见 `$unidesk-webdev`。HWLAB repo 只保留入口边界:专项代码位于 `web/hwlab-cloud-web`,命令必须在 issue/CLI 选中的目标 node/lane workspace 或独立 worktree 上运行,不得在 master server 本地跑浏览器或仓库级前端 check。 ### Web Live DOM Probe 验收 `scripts/web-live-dom-probe.mjs` 和 UniDesk `hwlab nodes web-probe run|script` 是 Cloud Web 原入口 DOM 验收底座。登录 sourceRef、同源 page helper、URL 构造、readiness、Trace 采样、浏览器噪声分类和 artifact 规则统一见 `$unidesk-webdev`;本文件不复制使用细则,避免与 UniDesk WebDev 操作面分叉。只修改该 helper 时属于无服务交付,按目标 HWLAB repo `AGENTS.md` 选择直接提交或 PR,关闭证据写明 `rollout=not-applicable`。 Cloud Web runtime config 或 YAML-first UI policy 类修复关闭前,除源码/fake-server 证据外,还必须证明选中 node/lane 的配置已进入部署链路:YAML 字段、GitOps render/env、Deployment 或 Pod env、public origin DOM/API 证据要分别记录。缓存、Pod 滚动和 browser helper 返回包装对象的细节由 `$unidesk-webdev` 规定;本文件只要求这些层次不能混为一个结论。 ### Cloud Web Workbench Prompt 浏览器闭环 Workbench prompt、TraceTimeline、final response、详情弹窗、session 切换、deep link 和运行态一致性问题的浏览器证据要求统一见 `$unidesk-webdev`;typed CLI 交叉验证仍见 `$hwlab-code-agent`。这里不再复制 selector、fresh context、turn authority 或登录排障细则,避免与 WebDev 操作面产生多路径。 ## HWLAB FRP 维护 HWLAB 公网 FRP server 由 master server 上的 `hwlab-frps-dev` 容器承担,容器使用 host network,并把 `/opt/hwlab-frp/frps.dev.toml` 只读挂载到 `/etc/frp/frps.toml`。这个 server 侧 allowlist 是 UniDesk 指挥侧维护对象,不属于 G14 k3s GitOps desired state;G14 侧 `frpc` ConfigMap/Deployment 只负责各 runtime namespace 的客户端 tunnel。 新增或恢复 HWLAB 公网入口时,先判断问题是否只是 server 侧 `allowPorts` 缺口。若 `frpc` 日志出现 `port not allowed`,优先在 master server 修改 `/opt/hwlab-frp/frps.dev.toml` 的 `allowPorts`,而不是改 active runtime lane 的 GitOps、Service 或 `frpc` ConfigMap。修改前保留一份本机备份,例如 `/opt/hwlab-frp/frps.dev.toml.bak-`;修改后只重启 `hwlab-frps-dev`,不要重建镜像、清理 Docker volume、重启无关 UniDesk/HWLAB 服务或触碰数据库状态。 当前 HWLAB FRP server allowlist 至少应覆盖 `config/hwlab-node-lanes.yaml` 中 active target 声明的 publicExposure 入口以及仍被明确使用的维护端口。Legacy `16666/16667` 和 retired G14 DEV/PROD `17666/17667`、`18666/18667` 只作为历史对照,不应作为新增 runtime 入口要求。新增端口或域名必须对应一个明确的 node/lane/namespace/runtime 入口,不能把大范围端口段作为默认放行策略。 FRP 维护验证顺序是:确认 `hwlab-frps-dev` 或 `config/hwlab-node-lanes.yaml` 指定的 publicExposure 入口仍挂载/渲染目标配置;重启或 apply 后用等价只读命令确认 FRP/Caddy 正在监听目标公网端口或 hostname;再在目标 namespace 查看 `frpc` 日志,确认对应 proxy `start proxy success`;最后验证选中 node/lane 的 active runtime 入口。D601 `v0.3` 验证使用 `https://hwlab.pikapython.com`;其他 node/lane 使用 YAML 中的 public URL。 FRP 文档、issue 和日志只能记录端口、容器名、ConfigMap 名、Secret 对象/key 是否存在和健康摘要;不得记录 Secret value、provider token、完整 DB URL、Codex auth JSON 或其他凭据内容。 ## 门禁最小化与扩容治理 不要滑向不必要的复杂门禁是 HWLAB 指挥侧通用原则。Legacy G14 DEV/PROD 退役、runtime lane 扩容、CI/CD 迁移、运行面热修和文档治理都应优先靠固定边界、清晰命名、唯一真相源、标准入口和长期参考文档收敛,不要把每个设计约定、运行策略或回滚手册都做成新的 preflight、guard、gate 或报告生成器。 旧 DEV/main/G14/D601 特例门禁如果阻碍 issue/CLI 明确选中的 node/lane 路径,默认处理是从当前调用链删除,而不是做兼容迁移、fallback、legacy mode、双路径绕行或在旧门禁上叠加例外。新增门禁只能覆盖明确高价值风险,且必须最小、低噪声、容易删除;资源配额、RBAC 命名、清理策略、回滚顺序、人工同步策略等默认是设计约定或 runbook,不是 CI/CD 通过条件。 每个 runtime lane 的硬边界必须从 `config/hwlab-node-lanes.yaml` 的选中 target 解析:source branch、CI/CD source repo、GitOps branch/path、runtime namespace、publicExposure、service 列表和 workspace 都以 YAML 为准。长期文档只记录“如何解析和验证”,不得把某个 node/lane 的当前数值写成全局默认。其他事项应先作为决策表或 runbook 固化,只有被证明无法靠边界和标准入口自然收敛时,才允许加最小检查。 ## 最小 Device Agent/Gateway 桥接模型 最小打通目标是只新增桥接面,不改动既有 HWLAB 应用、GitOps、FRP、CD 或前端路径: - 在选中 node/lane runtime namespace 手动建立一个 standalone `device-agent-71-freq` Pod/Deployment 和 ClusterIP Service。它暴露设备语义入口,例如 `/health`、`/skills`、`/workspace/*`、`/run`,并把真实硬件调用转成 HWLAB cloud-api 的 gateway operation,而不是在 Pod 内直接访问 Windows 硬件。 - 在 `D601:win` 上启动 `hwlab-gateway`,作为 71-FREQ/ConStart/Keil/串口资源的外部 host bridge。gateway 通过公网或受控网络出站连接选中 node/lane 的 cloud-api,注册稳定的 `gatewaySessionId`、`resourceId` 和 `capabilityId`。 - `hwlab-gateway` 是 Windows 长驻 outbound poll 进程,不能用 `trans D601:win cmd start ...` 或 PowerShell `Start-Process` 直接挂在一次性 trans/tran 会话下;这种启动方式可能继承输出句柄或被 provider 按子进程树等待,导致 trans/tran 卡住并阻塞后续 provider session。临时实验也应通过 Windows Task Scheduler、Windows Service、NSSM、PM2 service 或等价 detached launcher 启动,`trans` 只负责触发和读取状态;通用规则见 `docs/reference/windows-passthrough.md`。 - D601 Windows gateway 的最小配置必须来自 profile 或环境变量,核心字段是 `HWLAB_GATEWAY_CLOUD_URL=`、`HWLAB_GATEWAY_ID`、`HWLAB_GATEWAY_SESSION_ID`、`HWLAB_GATEWAY_RESOURCE_ID`、`HWLAB_GATEWAY_CMD_CAPABILITY_ID`、`HWLAB_GATEWAY_CMD_EXEC_ENABLED=1`、`HWLAB_GATEWAY_DEMO_OPEN=1`、`HWLAB_GATEWAY_MAX_INFLIGHT` 和 `HWLAB_GATEWAY_CMD_TIMEOUT_MS`。这些值用于声明能力和执行边界,不得散落在 device-agent 代码里。 - device-agent 访问集群内 cloud-api 时优先使用选中 runtime lane 的 Service DNS;Node 实现访问 `6667` 时遵循 Node/Lane 运行面口径里的 bad-port 规则,不为 device-agent 单独维护另一套例外。 - 71-FREQ 的 device profile 必须配置化保存,至少包含工程根目录、Keil project/target、默认串口波特率、gateway/resource/capability 选择器和 workspace 根。不得把 `F:\Work\ConStart`、工程名、串口号或 probe UID 硬编码进 device-agent 镜像。 - 最小验收顺序是:选中 node/lane cloud-api `/health/live` ready;D601 Windows 能访问该 lane 的 public `/health/live`;D601 `hwlab-gateway` 注册后 cloud-api 能看到 gateway session/resource/capability;`device-agent-71-freq` `/health` 和 `/skills` 返回 ready;通过 device-agent 发起一条只读或 `echo` 级 gateway shell operation,并返回 operation/evidence/trace 摘要。 - 这个模型只证明 `device-agent Pod -> 选中 lane cloud-api -> D601 hwlab-gateway -> Windows host` 的控制链路。Keil 编译下载、串口日志抓取和 workspace CRUD 可以作为后续 device-agent skill 子命令逐步接入;未接入前不能把 device-agent 标成完整 71-FREQ 硬件代理。 ## Master Server 校验边界 - master server 是 UniDesk/HWLAB 的生产入口且资源紧张;它只能承担轻量源码编辑、Git 操作、日志/健康观察、JSON CLI 指挥和受控 CD 审阅,不能承担正式校验执行面。 - 禁止在 master server 上运行 HWLAB 或 UniDesk 的仓库级 `check`/`test`/smoke 命令,包括但不限于 `bun scripts/cli.ts check`、`node --test`、`node web/hwlab-cloud-web/scripts/check.mjs`、`node scripts/dev-cloud-workbench-smoke.mjs`、Playwright/browser layout smoke,以及其他会长时间占用 CPU/内存、启动浏览器或遍历大仓库的校验流程。 - 需要正式验证时,固定切到 issue/CLI 选中的 node/lane workspace、k3s/Tekton、HWLAB repo-owned CI 或其他获批外部执行面;master server 只负责发起、观察和记录,不负责实际跑 check。 - 如果为了排障必须从 master server 生成命令或查看源码,后续验证命令也必须显式改到目标 node/lane 路径执行,例如 `trans D601:/home/ubuntu/workspace/hwlab-v03 sh -- ...` 或 `trans D601:k3s ...`,而不是直接在 `/root/unidesk` 或 master server 上本地运行。 ## Node/Lane 运行面口径 HWLAB 当前真实 runtime 由 issue/CLI 选中的 node/lane 决定。只读观察使用 YAML 解析出的 kube route、namespace 和 public endpoint;例如 D601 `v0.3` 使用: ```sh trans D601:k3s kubectl -n hwlab-v03 get deploy,svc,pod -o wide ``` `hwlab-cloud-api` 和 `hwlab-edge-proxy` 在集群内可使用 `6667` Service 端口;对外入口以选中 target 的 publicExposure/public URL 为准。Node/Bun/undici 的 Fetch 实现会按 Fetch bad-port 规则拒绝 `6667`,因此任何需要代理、转发、探测或服务间访问该端口的 Node 实现都必须使用 `node:http`/`node:https`、已有 repo-owned HTTP helper,或改用不触发 bad-port 的受控代理端口;不要把 Fetch bad-port 造成的 `fetch failed` / 502 误判为 Service DNS、PVC、数据库或 trace 数据缺失。G14 local details 见 `docs/reference/g14.md` 和 G14 节点 `/root/docs/hwlab-g14-workspace.md`;D601 node-scoped target 以 `config/hwlab-node-lanes.yaml` 的 `nodes.D601` 和 `lanes.v03.targets.D601` 为准。 D601 原生 k3s 是 D601 node-scoped runtime 的正式控制面;D601 legacy 对照也使用同一 native k3s guard。任何 D601 k3s 操作都必须显式使用 UniDesk route `D601:k3s` 或等价的 `/etc/rancher/k3s/k3s.yaml`,不能使用裸默认 kubeconfig: ```sh KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-dev get deploy,svc,pod -o wide ``` D601 上不要直接相信默认 `kubectl` context。默认 context 可能是 `docker-desktop`,它会展示另一套与公网 legacy `16666/16667` 无关的状态,并可能给出误导性的 `ImagePullBackOff`。 历史 D601 legacy `frpc` 配置不是 D601 host `/etc/frp/frpc.toml`,而是 D601 legacy `hwlab-dev` namespace 里的 `hwlab-frpc-config` ConfigMap 和 `hwlab-frpc` Deployment。D601 `v0.3` publicExposure 以 `config/hwlab-node-lanes.yaml` 和 PK01 Caddy/FRP target 为准。 ## Code Agent 模型通道 HWLAB 的 DeepSeek/Codex 兼容性属于 HWLAB runtime 规则,长期真相在 HWLAB 仓库 `AGENTS.md` 和目标 lane 对应的 `docs/reference/`。UniDesk 指挥侧只保留监督边界:诊断这类问题时,先在选中 node/lane 的目标 Pod 或临时 passthrough Pod 内闭环证明 Codex stdio、Responses 请求、tool call/tool result 顺序、模型目录和真实 provider 返回,再考虑 GitOps/CI/CD;不要用完整 CI/CD 作为每轮协议试错工具。 DeepSeek profile 应优先使用成熟 Responses/Anthropic 协议桥接方案,例如 Moon Bridge,来保留 prompt cache、tool-result 顺序和模型目录语义。HWLAB repo-owned compatibility bridge 只能承担薄层职责,例如 Codex zstd request body 解码、非 `function` tool 过滤、`/v1/models` 或 readiness 适配;不要在 UniDesk 或 HWLAB 中手写完整 Responses-to-Chat 转换器替代成熟桥接层。Secret 值、provider token 和完整模型请求正文不得写入 UniDesk 文档、issue 或日志。 HWLAB 与 AgentRun 协同修复必须按 `docs/reference/agentrun.md` 的职责边界执行:AgentRun 拥有的共享执行、trace/result、backend event、runner 和 CLI 能力缺失时改 AgentRun;HWLAB 拥有的鉴权、Cloud Web/CLI 对外 API、adapter 消费、业务和前端问题改 HWLAB。不得用一侧的观测、fallback 或兼容逻辑迁就另一侧未实现或未修复的能力。 ### Code Agent Provider Profile 配置与验收 本小节只适用于明确选择 HWLAB `v0.2` provider profile 的任务;其他 node/lane 的 profile 配置必须先按 issue/CLI 目标和 `config/hwlab-node-lanes.yaml` 解析运行面,再读取目标 HWLAB repo 的对应规则。G14 节点参考、CLI 参考和 `hwlab-code-agent` skill 只交叉引用这里;AgentRun 内部 Secret 物化和 backend adapter 设计仍以 AgentRun 仓库自身为准。 HWLAB v0.2 provider profile 必须通过已部署的 HWLAB Cloud API/CLI 管理,正式入口是 `hwlab-cli client provider-profiles`。不要把手工 patch `agentrun-v01` Secret、直接调用 AgentRun manager 或临时 runner job 当作正式配置路径或关闭证据;这些只可作为基础设施定位证据。标准执行面是 `G14:/root/hwlab-v02`,调用前锁定 `HWLAB_RUNTIME_NAMESPACE=hwlab-v02`、`HWLAB_RUNTIME_WEB_URL=http://74.48.78.17:19666` 和 `HWLAB_RUNTIME_ENDPOINT_LOCKED=1`,`HWLAB_API_KEY` 从 `/root/.config/hwlab-v02/master-server-admin-api-key.env` 加载。 当明确需要把当前 operator 的 Codex 凭据作为 AgentRun 动态 profile 提供给 HWLAB Code Agent 或 CaseRun 使用时,固定操作手册在 `$hwlab-code-agent` 的 `AgentRun 动态 sub2api profile` 小节。该场景是 AgentRun runtime profile 投影,不替代上面的 HWLAB provider-profiles 正式配置路径;默认 profile 名为 `sub2api`、模型为 `gpt-5.5`,优先使用 G14 k3s 内 Sub2API ClusterIP 作为 `base_url`,并只记录 SecretRef、keyPresence、hash suffix 和原入口验收结果。 `config.toml` 和 Codex `auth.json` 是两个独立输入。`set-config --config-stdin` 写入 profile 的 Codex 配置文本;`set-auth-json --auth-json-stdin` 写入完整 Codex auth JSON object,并在 AgentRun runtime Secret 中作为 `auth.json` key 保留。`set-key --key-stdin` 只用于单值 API key profile;当输入本来就是 Codex `auth.json` 时,不得再把它压扁、拆成单个 key、改走 legacy API-key-only 路径或保留旧断言阻塞提交。遇到 CLI 不支持完整 auth JSON、输出不可见或缺少 hash/keyPresence 等证据时,先补 HWLAB CLI/API 和 AgentRun provider-profile 能力,再继续试机。 标准命令形态如下,文件名可按实际 profile 替换: ```bash bun tools/hwlab-cli/bin/hwlab-cli.ts client provider-profiles set-config --config-stdin --no-session < config.toml bun tools/hwlab-cli/bin/hwlab-cli.ts client provider-profiles set-auth-json --auth-json-stdin --no-session < auth.json bun tools/hwlab-cli/bin/hwlab-cli.ts client provider-profiles list --no-session ``` AgentRun `v0.1` 运行面物化对象是 `agentrun-v01` namespace 中的 `agentrun-v01-provider-` Secret。基础 Codex profile 的稳定 key 是 `config.toml` 和 `auth.json`;需要本地模型目录的 profile 还必须按 AgentRun backend profile 声明补齐额外 key,例如 `dsflash-go` 必须同时具备 `model-catalog.json`,且 `config.toml` 中的 `model_catalog_json` 指向 runner 内 profile-local catalog 路径。文档、issue、trace 和 CLI 输出只能记录 profile 名、SecretRef、key 是否存在、字节数、redacted hash/hash suffix、resourceVersion 和验证结果;不得记录 Secret value、完整 `auth.json`、provider token、完整 API key 或可复用凭据命令。 profile 配置后的最小真实验收是通过同一 HWLAB v0.2 Cloud API/Web dispatcher 路径创建 Code Agent session 并完成一轮真实 turn:`client agent session create --provider-profile `,再 `client agent send --session-id --provider-profile `,最后用 `client agent result ` 和 `client agent trace --render web` 确认终端状态和最终 assistant 文本。只看到 Secret 存在、AgentRun canary 通过、PipelineRun 成功或源码测试通过,都不能替代这一真实入口验收。对 profile-sensitive CaseRun 或 provider 修复,关闭证据还必须来自原入口 `case run`/Web 等价路径,结果中应同时显示 `requestedProviderProfile`、`resolvedBackendProfile`、AgentRun `backendProfile`、模型名和终端状态;涉及 ds-flash/Moon Bridge 时,还要确认 `deepseek-v4-flash`、1M context/model catalog 元数据生效,且归档中不再出现 `responses/compact 404` 或 `404 page not found`。当前 HY 凭据对的稳定 profile 名是 `hy`;复测时使用同一标准入口,不在任何长期文档或 issue 中记录凭据内容。 CaseRun 的 case/registry/aggregate、评价、回放、训练反馈和硬件证据闭环需求以 UniDesk OA 的 [PJ2026-0103 HarnessRL](../../project-management/PJ2026-01/specs/PJ2026-0103-harness-rl.md) 为权威;HWPOD 服务、AI 网关和 HWLAB 到 AgentRun 的装配接入分别以 [PJ2026-010103 HWPOD服务](../../project-management/PJ2026-01/specs/PJ2026-010103-hwpod-service.md)、[PJ2026-010104 AI网关](../../project-management/PJ2026-01/specs/PJ2026-010104-ai-gateway.md) 和 [PJ2026-010205 HWLAB接入](../../project-management/PJ2026-01/specs/PJ2026-010205-hwlab-dispatch.md) 为权威。HWLAB 仓库内 `docs/reference/spec-hwpod-harness.md` 只保留历史交叉引用 stub;UniDesk 指挥侧按 issue/CLI 选中的 node/lane 重新读取 HWLAB `AGENTS.md`、使用目标 workspace 原入口验证,并在关闭 issue 时记录 runId、traceId、provider profile、registry commit 和负向检索摘要。不要在 UniDesk reference 里复写 CaseRun prompt 细则或 `.agents/skills` 装配实现。 CaseRun skill 交付边界按 `docs/reference/agentrun.md#agentrun--hwlab-协同职责边界` 判定:专用 skill 通过 AgentRun `gitbundle` 装配给 Code Agent,subject repo 不能携带 `.agents/skills` 副本。关闭要求涉及 skill 的 case 时,除 runId、traceId、provider profile 和 registry commit 外,还应记录 `resourceBundlePolicy`、实际装配的 skill 名、AgentRun/CaseRun 归档中的 skill 读取证据,以及 subject repo diff 或 artifact 中没有新增 `.agents/skills` 的负向检索结果。 CaseRun `summary.md`、`result.json` 和 registry aggregate 是阅读索引,不是替代原始执行证据的判定器。若 summary 中的 build/download/UART 字段与 AgentRun trace、HWPOD command output、Keil job、下载日志或 UART 输出不一致,应先用原始 trace rows、terminal command id、硬件命令输出和串口证据收口当前用户问题,同时把 summary/aggregate 语义缺口提到拥有该契约的仓库继续修复。D601 硬件 case 的 UART 证据必须来自当前 run 的串口输出;`serial-monitor` 服务或 Windows wrapper 不可用时,应先恢复或登记基础设施问题,不能把串口不可见误判为 subject 源码失败。 ## D601 Legacy HWLAB DEV CD Wrapper 以下 UniDesk wrapper 是旧 D601 DEV CD 指挥入口,只用于显式 legacy 诊断和迁移对照。当前 HWLAB 发布、GitOps 和运行面收敛必须优先按 issue/CLI 选中的 node/lane 与 HWLAB repo-owned 规则执行;不要把下面的 D601 legacy wrapper 当作 D601 `v0.3` 或其他当前 HWLAB release truth。 本节里的 `deploy/deploy.json` 只属于 D601 legacy DEV CD wrapper。当前 node/lane 的部署配置源以 HWLAB repo 和 UniDesk YAML 声明为准,并由对应 format-agnostic config layer 读取;不要把 legacy `deploy/deploy.json` 当作 D601 `v0.3` truth。 UniDesk 指挥侧固定入口: ```sh bun scripts/cli.ts hwlab cd status --env dev bun scripts/cli.ts hwlab cd audit --env dev bun scripts/cli.ts hwlab cd preflight --env dev bun scripts/cli.ts hwlab cd apply --env dev --dry-run ``` wrapper 的职责是把 host commander 常用的 HWLAB DEV rollout 查看/准备动作收敛到单一入口。默认路径通过 UniDesk main-server frontend/backend-core 的 provider `host.ssh` 能力进入 D601;frontend transport 先用多个短 `host.ssh` 命令把远端 runner 分块上传到 `/tmp/unidesk-hwlab-cd/`,再在 D601 上执行有界检查脚本,避免 provider-gateway 的短命令长度限制成为审计入口单点故障。经 frontend/backend-core 返回的 stdout 只允许承载短 JSON 摘要;完整结果必须写入 D601 `~/.state/unidesk-hwlab-cd//result.full.json`,防止 backend JSON 安全摘要把 stdout 截断后导致 CLI 失明。它只调用 HWLAB repo-owned 受控脚本,不在 UniDesk 内重写发布流程或拼接 ad hoc `kubectl apply`: - 默认 HWLAB CD repo 是每次运行在 D601 `~/.state/unidesk-hwlab-cd//ephemeral-repo/HWLAB` 新建的一次性 clone。一次性 repo 只从专用 full bare cache `~/.cache/unidesk/hwlab-cd/git-cache/HWLAB.git` 拷贝生成,必须使用 `--no-hardlinks` 形成独立 `.git` 对象库,不能通过 `--shared` 或 alternates 在运行时依赖 cache 对象库。cache 本身只允许作为 HWLAB CD 专用 Git 加速源,不承载 runner workspace、部署副本、手工改代码、报告留痕或任何其他用途。 - 专用 cache 由当前 `host.ssh` 执行用户拥有,`~/.cache/unidesk/hwlab-cd` 必须保持 owner-only 权限;owner 不匹配、不可写或权限收紧失败时返回结构化 blocker。cache 初始化可以从本机已有 HWLAB clone seed 一次性拷贝,但 seed 只能用于降低首次出网成本,不能作为 release truth。cache remote 固定优先 `git@github.com:pikasTech/HWLAB.git`,GitHub 出网通过 D601 provider egress proxy `127.0.0.1:18789` 和 SSH `ProxyCommand`。cache 必须保存 full bare repo 历史,而不是 depth=1 浅缓存;wrapper 需要能解析 `refs/heads/main:deploy/deploy.json` 指向的 promotion commit,浅缓存即使 main HEAD 一致也不能证明 CD desired-state 完整。若 GitHub refresh 失败但本地 full cache 同时满足 main HEAD 和 deploy promotion commit,可作为 stale-cache 诊断继续读数,但必须暴露 `hwlab-cache-refresh` blocker,不能伪装成 release-truth PASS。 - 一次性 repo 是当前 `host.ssh` 执行用户创建的临时发布读数,避免长期 `/home/ubuntu/hwlab_cd` 被 root 或其他 runner owner 污染后成为 CD 单点故障。`--hwlab-repo` 或 `UNIDESK_HWLAB_REPO` 仍可显式指定同等干净 clone 供人工诊断;被指定的 clone 必须由执行用户拥有并可读写。root-owned 或其他用户拥有的 clone 会触发 Git dubious ownership、`FETCH_HEAD` 不可写和 `.git/worktrees` 权限 blocker。修复 owner 污染应重建或显式修正 mirror 权限,不能用 `git config --global safe.directory` 掩盖发布真相污染。wrapper 必须检查 `git status --short --branch`、origin remote、当前 branch `main`、本地 `origin/main`、`FETCH_HEAD` 和 worktree 权限;任何 dirty worktree、错误 remote、非 main、HEAD 未跟上本地 `origin/main` 或权限异常都返回结构化 blocker。`/home/ubuntu/hwlab` 是 runner 历史目录,不得作为发布真相。 - `deploy/deploy.json` 是唯一 desired-state。wrapper 只把 `deploy/artifact-catalog.dev.json`、`deploy/k8s/base/workloads.yaml` 和 `reports/dev-gate/dev-artifacts.json` 当作派生/证据读数;`status`/`preflight` 必须显示 target commit/ref、deploy.json、artifact catalog、workloads 和 live workload image 是否同源/收敛,不引入第二套 desired state。 - `status` 只读汇总 HWLAB repo path、Git clean/main/origin-main、desired-state 收敛、D601 native k3s guard 和 `Lease/hwlab-dev/hwlab-dev-cd-lock`;同时调用 HWLAB `scripts/dev-cd-apply.mjs --status --skip-live-verify` 取得 repo-owned target/promotion/deploy.json/artifact 摘要。16666/16667 live verification 不由本 runner 执行。 - `audit` 是 DEV CD 恢复后的只读健康审计,不是验收 gate 或报告生成器。它在 `status` 受控路径上补充只读 `kubectl get`/HTTP health probes,输出有界 JSON summary,分类 `control-plane-unavailable`、`docker-desktop-context-risk`、`second-control-plane-risk`、`workspace-unavailable`、`dirty-worktree`、`secret-missing`、`registry-unavailable`、`lease-held`、`lease-stale-candidate`、`artifact-missing`、`artifact-mismatch`、`runtime-job-blocked`、`rollout-unhealthy`、`public-tunnel-unhealthy` 和 `db-runtime-durability-risk`。audit 只显示 Secret 对象/key 是否存在,不显示值;只读判断 Lease 是否 stale,不释放或 break;只读拉取 16666/16667 `/health/live` 的 commit/readiness 摘要,不把它当作 M3 DEV-LIVE 验收。 - `preflight` 在 `status` 的基础上检查 apply 前 SecretRef:`hwlab-cloud-api-dev-db/database-url`、`hwlab-cloud-api-dev-db-admin/admin-url`、`hwlab-code-agent-provider/openai-api-key`。只验证 Secret 对象和 key 元数据存在性,缺失时返回 blocker、影响范围和修复 runbook;禁止读取或打印 Secret value。 - `apply --dry-run` 调用 HWLAB `scripts/dev-cd-apply.mjs --dry-run --kubeconfig /etc/rancher/k3s/k3s.yaml --skip-live-verify`,只生成受控事务准备/阻塞摘要,不做真实 apply、rollout、Lease mutation 或 live verification。历史 `scripts/dev-deploy-apply.mjs` 可作为 HWLAB 内部支持脚本出现,但 UniDesk wrapper 不能把它当成平行 CD 入口。 - 完整下游 stdout/stderr 和 kubectl 读命令输出写入 D601 `~/.state/unidesk-hwlab-cd//`,UniDesk 本地仅保存 provider task stdout/stderr dump;CLI stdout 只显示有界摘要和 dump path。 - wrapper 显式注入 `KUBECONFIG=/etc/rancher/k3s/k3s.yaml` 并以这个显式目标作为唯一 gate:目标 context/server/nodes 若出现 `docker-desktop`、`desktop-control-plane` 或 `127.0.0.1:11700` 必须拒绝继续,写操作计划或 `apply --dry-run` 前目标 nodes 必须包含 `d601`。裸 `kubectl` 默认 context 只作为诊断输出;即使默认 kubeconfig 仍残留 Docker Desktop,只要显式 D601 kubeconfig 通过,也不能把默认 context 当成 CD blocker。 真实 DEV apply 只允许 host commander 在明确授权后执行。UniDesk wrapper 可以展示受控命令形状: ```sh node scripts/dev-cd-apply.mjs --apply --confirm-dev --confirmed-non-production --write-report --kubeconfig /etc/rancher/k3s/k3s.yaml ``` 本 Code Queue runner 没有 `ROLLOUT_OK` 时不得执行真实 apply、rollout、CD lock 竞争或 live health 复验。 ## HWLAB 热修边界 当 HWLAB DEV runtime 的 Secret、环境变量、rollout、DNS、egress 或 provider 权限缺口阻塞业务闭环,并且 Code Queue runner 无法安全完成对应运行态操作时,UniDesk 指挥官只能承担指挥入口、授权确认、监督验收和误判边界收敛。UniDesk reference 可以记录“哪些状态不能被误判”和“哪些动作必须上收”,但不能成为 HWLAB runtime truth。 这类热修必须满足以下边界: - 先确认用户或项目负责人已授权具体运行态修复范围;没有授权时只做只读诊断、issue 记录和修复方案准备。 - 证据只记录对象名、状态、revision、健康结果和已脱敏差异;不得把 Secret 值、token、可复用凭证命令或完整敏感 env 输出写入 issue、PR、日志或文档。 - live Secret、env、ConfigMap、Deployment patch 或 rollout 结果只能作为临时恢复证据,不能成为长期部署真相。 - HWLAB runtime truth 必须回写到 HWLAB 仓库自己的 issue、`AGENTS.md`、`docs/reference/`、部署配置或 secret 管理入口;UniDesk 只保留指挥侧边界和交叉引用。 - 热修后必须说明 durable source fix 如何进入 HWLAB 的 CLI、manifest、选中 node/lane 的配置/CI/CD/GitOps 路径,或显式 D601 legacy `deploy/deploy.json`;如果尚未完成,要保留 HWLAB issue 追踪。 ## D601 Legacy Cloud Web 手动 DEV 发布路径 以下路径是 D601 legacy DEV 的历史手动发布基准,只用于迁移对照或显式 D601 回滚排障。当前 HWLAB 发布必须优先按 issue/CLI 选中的 node/lane、对应 GitOps 和 HWLAB repo-owned 规则执行;不要把这里的 D601 legacy 命令当作 D601 `v0.3` 发布入口。 1. 更新 D601 部署副本: ```sh trans D601 'cd /home/ubuntu/workspace/hwlab && git pull --ff-only origin main' ``` 2. 刷新 Cloud Web 静态构建产物。运行时 wrapper 优先读取 `web/hwlab-cloud-web/dist`,如果该目录残留旧内容,即使源码已经更新,镜像仍可能继续服务旧页面: ```sh trans D601 'cd /home/ubuntu/workspace/hwlab && node web/hwlab-cloud-web/scripts/build.mjs' ``` 3. 发布镜像到 D601 本地 registry: ```sh trans D601 'cd /home/ubuntu/workspace/hwlab && node scripts/dev-artifact-publish.mjs --publish --services hwlab-cloud-web --report reports/dev-gate/dev-artifacts-hwlab-cloud-web-.json' ``` 4. 在滚动前用一次本地容器探针确认镜像内容,不把 commit tag 等同于页面内容: ```sh trans D601 'docker run --rm -d --name hwlab-cloud-web-probe -p 127.0.0.1:18088:8080 127.0.0.1:5000/hwlab/hwlab-cloud-web: && sleep 1 && curl -fsS http://127.0.0.1:18088/health/live && curl -fsS http://127.0.0.1:18088/ | sed -n "1,40p"; docker rm -f hwlab-cloud-web-probe' ``` 5. 滚动 D601 原生 k3s: ```sh trans D601 'KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-dev set image deployment/hwlab-cloud-web hwlab-cloud-web=127.0.0.1:5000/hwlab/hwlab-cloud-web: && KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-dev rollout status deployment/hwlab-cloud-web --timeout=180s' ``` 6. 用公网入口验收: ```sh curl -fsS http://74.48.78.17:16666/health/live curl -fsS http://74.48.78.17:16666/ | sed -n '1,80p' curl -fsS http://74.48.78.17:16666/styles.css | rg 'overflow: hidden|100dvh' ``` 验收时必须同时看 `health/live` 的 revision、HTML 语言/标题和 CSS 外层滚动锁定。不能只看镜像 tag 或 deployment 镜像字段。 ## 监督原则 - HWLAB 派单 prompt 必须自包含,并在开头引用 `DC-DCSN-P0-2026-003`,说明任务服务 M3 闭环的哪一环。 - `SOURCE`、`LOCAL`、`DRY-RUN`、fixture 或只读报告不能被当作 `DEV-LIVE`。真正的 M3 DEV-LIVE 需要证明 `res_boxsimu_1:DO1 -> hwlab-patch-panel -> res_boxsimu_2:DI1` 并带有 operation、audit、evidence 链。 - 前端体验、Cloud Workbench polish、Gate 页面、诊断页和发布路径修复都是支撑任务,不等同于 M3 PASS。 - 指挥官可以手动处理 PR 冲突和最终合并判断;runner 不应承担复杂冲突合并。 - 任何临时手动上线或绕行都要回写 HWLAB issue 与 HWLAB 长期参考文档,并标明后续如何收敛到 CLI、选中 node/lane 的配置/CI/CD/GitOps 路径、显式 D601 legacy `deploy/deploy.json` 或等价发布路径。 - HWLAB Secret/env/rollout 热修按本文“HWLAB 热修边界”和 `docs/reference/devops-hygiene.md` 执行;UniDesk 侧只沉淀边界,HWLAB 侧沉淀运行真相。