---
name: unidesk-hwpod-ops
description: >-
  UniDesk HWLAB HWPOD 节点运维技能，覆盖 Windows 单文件 Python 图形节点 `hwlab-node.py`
  的发现、安装、界面/托盘、连接、更新、日志、诊断、nodeId、工作区、HWPOD 节点操作、
  MDTODO 来源和旧 Bun 运行器漂移。用户提到 hwpod-node、hwlab-node、Python 图形节点、
  HWPOD 节点上下线、D601/G14-WSL 硬件节点、工作区绑定或 HWLAB Web MDTODO 读取时使用。
---

# UniDesk HWPOD 运维

- 本 skill 中的 MDTODO 仅表示遗留工作区来源与旧 Web 验收面；恢复相关任务前按 `$unidesk-tasktree` 迁移，不得新增文件式任务。

- 运维对象：

  - 默认对象：当前 HWLAB v0.3 Python 图形节点；
  - 历史调查：旧 `$hwpod-ops` 中的 TypeScript/Bun `serve|connect`；
  - 禁止事项：旧运行器不得作为新节点完成态。

## P0 边界

- 当前 HWLAB 固定运行面由 UniDesk `config/hwlab-node-lanes.yaml` 选择：
  - 先运行 `cicd status` 和 `source-workspace status`；
  - 不得复用旧 G14/v0.2 地址。
- Python 图形节点的来源：
  - 权威源码是选中 HWLAB 源工作区的 `tools/hwlab-node.py`；
  - 发布版本由选中入口的 `/v1/hwlab-node/update` 给出；
  - 发布文件和 SHA 由 `/v1/hwlab-node/download/hwlab-node.py` 与更新元数据共同确定。
- 平台资源真相：
  - 节点、工作区、HWPOD 资源、MDTODO 来源、端点和 Secret 必须进入权威 YAML/配置引用；
  - `~/.hwlab/config.json` 只属于桌面应用配置。
- Secret 规则：
  - 只通过 YAML `sourceRef`/`targetKey` 和受控入口下发；
  - 状态、日志和 issue 只披露是否存在、指纹和脱敏摘要。
- Windows 节点使用主动出站 WebSocket；不要为用户电脑增加入站端口或直连地址兜底。
- Windows Python 图形节点启动规则：
  - 优先使用目标 Windows 交互用户可见的原生 `python.exe`；
  - 不得用 WSL Python、SSH 辅助程序自带解释器、Bun 运行器或非交互 Windows 服务替代；
  - 解释器路径/版本必须进入节点配置和状态证据。
- HWPOD 节点部署必须采用 YAML-first + 仓库自带 CLI：
  - 只支持权威 YAML 已声明且 `trans` 路由可解析、可访问的节点；
  - CLI 可以在内部使用 `trans` 作为传输层；
  - 操作者不得用手写 `trans`/PowerShell/cmd 完成安装、更新、配置或自启动；
  - 受控 CLI 缺失时先实现 CLI，不把手工部署当临时完成态。
- 调查可只读访问现场；发生以下变更时加载对应 skill：
  - 安装、注册、更新、停止旧运行器或修改 MDTODO 来源：`$unidesk-daddev`；
  - L2/L3 部署或发布：同时加载 `$unidesk-cicd`；
  - L1 native API、worker、Web 和 Windows desktop node 的启动、恢复与回归不加载、
    不依赖 `$unidesk-cicd` 或 Kubernetes；
  - YAML 变更：同时加载 `$unidesk-ymalops`。
- 远端操作走 `$unidesk-trans`。普通 `trans` 保持短连接；图形进程不得作为透传子进程长挂。
- Python 节点可用性：
  - 必须具备工作区允许列表/规范化；
  - 必须具备注册认证和能力对齐；
  - 缺失任一项时，不得把“WebSocket 已连接”报告为 HWPOD/MDTODO 可用。

## 只读调查

```bash
bun scripts/cli.ts cicd status --node NC01
bun scripts/cli.ts hwlab nodes control-plane source-workspace status --node NC01 --lane v03

trans <provider>:win ps <<'POWERSHELL'
[ordered]@{
  home = $HOME
  python = (python --version 2>&1 | Out-String).Trim()
  config = Test-Path (Join-Path $HOME ".hwlab\\config.json")
  log = Test-Path (Join-Path $HOME ".hwlab\\logs\\hwlab-node.log")
} | ConvertTo-Json -Compress
POWERSHELL

trans <provider>:win ps <<'POWERSHELL'
Get-CimInstance Win32_Process |
  Where-Object { $_.CommandLine -match "hwlab-node|hwpod-node" } |
  Select-Object ProcessId, Name, CommandLine |
  ConvertTo-Json -Compress
POWERSHELL

trans <provider>:win ps <<'POWERSHELL'
Get-ScheduledTask -ErrorAction SilentlyContinue |
  Where-Object { $_.TaskName -match "HWLAB|HWPOD" } |
  Select-Object TaskName, State |
  ConvertTo-Json -Compress
POWERSHELL
```

- 状态分类：

  - `desktop-ready`：Python/tkinter 和交互式 Windows 会话可用。
  - `process-ready`：只有一个预期的 Python 图形进程存活，不存在冲突的 Bun 执行权威。
  - `registered`：云端注册表已确认预期 nodeId。
  - `workspace-ready`：`node.inventory` 和有界工作区读取指向 YAML 选中的根目录。
  - `mdtodo-ready`：项目管理来源通过公共 HWPOD 工作区操作完成保存、探测和重建索引。

- 当前应用合同、更新流程和已知缺口：
  - 读 [references/python-ui-node.md](references/python-ui-node.md)。
- 新增节点、绑定工作区或验收 HWLAB Web MDTODO：
  - 读 [references/workspace-mdtodo.md](references/workspace-mdtodo.md)。

## 变更流程

- 观察运行上下文：
  - 选中的 HWLAB 节点/通道；
  - 公共入口和 Python 发布元数据；
  - Windows 用户/会话；
  - 当前节点进程、任务/启动项、配置是否存在和旧运行器。
- 节点身份、工作区根、资源绑定、认证、能力或 MDTODO 来源变化时：
  - 先更新权威规格。
- 使用当前 CLI 帮助选定的仓库自带 `hwlab nodes hwpod-node` 规划/状态/应用命令族：
  - 变更前要求预检解析 YAML 节点配置；
  - 证明节点的 `trans` 路由可达；
  - 命令族不存在时先实现它。
  - 云端认证与桌面部署分阶段执行：
    - `--component cloud-auth` 先同步节点认证 Secret；
    - HWLAB 发布完成后使用 `--component desktop` 部署桌面节点；
    - `--component all` 只用于云端已引用该 Secret 的稳定运行面。
- 由受控 CLI 完成部署：
  - 渲染并校验配置；
  - 获取已发布 Python 文件并校验 SHA；
  - 解析目标交互用户的 Windows `python.exe`；
  - 安装文件并应用 YAML 声明的登录自启动策略；
  - nodeId、地址、工作区和重连/更新设置不得硬编码进生成的辅助代码。
- Windows UART backend 由 HWPOD spec 的 YAML 字段选择：
  - `serial-monitor` 是默认 backend；
  - 目标机已有 `pyserial` 且 serial-monitor server 不可用时，可对该 spec 显式声明
    `backend: pyserial`，不得改成全局隐式回退；
  - compiler 必须把同一 backend 对称传入 `open`、`read`、`write`、`close` 四类 plan；
  - `pyserial` 节点在四步操作之间持有同一串口连接，回归结束必须执行 `close`。
- 证明节点状态：
  - 单一执行权威；
  - 预期版本/nodeId 和注册；
  - `node.health` 和 `node.inventory`；
  - 有界工作区读取和结构化诊断。
- 通过 HWLAB Web 等价路径验收 MDTODO：
  - 来源保存；
  - 探测；
  - 重建索引；
  - 文件/任务可见；
  - 直接 `trans cat` 只属于 P1 诊断。
- 记录证据：
  - 源提交、文件 SHA 和 nodeId；
  - 工作区指纹/路径摘要和注册状态；
  - 操作 request/trace 标识；
  - MDTODO 来源/重建索引结果；
  - 默认不得记录 Markdown 正文或凭据。

## Windows 运行态判定

- 使用 Windows Store Python 启动图形节点时：
  - `pyw.exe` 可能作为常驻启动器；
  - 实际节点进程是其派生的 `pythonw*.exe`；
  - 单实例状态只统计 `python*.exe` 解释器；
  - 停止旧实例时同时清理启动器和解释器。
- 通过 `trans` 启动图形节点时：
  - 必须显式重定向标准输出和标准错误；
  - 禁止让图形进程继承 PowerShell 或 trans 的管道句柄；
  - `apply` 和 `status` 必须返回结构化终态后才算入口可用。
- 验收 MDTODO 文件时：
  - `workspace.ls` 证明目录原始文件可达；
  - Project Management `reindex` 只投影可识别的 MDTODO 文档；
  - Web 文件选择必须使用已进入投影的文件名；
  - 原始目录存在但未进入投影的文件，不得用于 Web 选择命令验收。

## 停止条件

- 选中的通道/源权威不清晰或过期时，在变更前停止。
- 部署前停止条件：
  - 目标未进入权威 YAML；
  - 没有可解析且可达的 `trans` 路由；
  - 仓库自带规划/状态/应用 CLI 缺失。
- 现有进程控制相同 nodeId/资源时，在启动第二个运行器前停止。
- 工作区未实施包含性约束或来源可能逃逸声明根目录时，在 MDTODO 写入/重建索引前停止。
- 必须区分以下阻塞项：
  - 节点不匹配和认证失败；
  - 工作区缺失和能力不匹配；
  - 旧运行器漂移；
  - 来源投影失败。
- 不得只凭进程健康关闭 HWPOD issue；必须使用用户原始的 HWLAB Web/CaseRun/MDTODO 入口。

## 参考文档

- Python 图形节点合同、本地文件、更新端点和漂移：
  - [references/python-ui-node.md](references/python-ui-node.md)。
- 节点接入、工作区绑定和 MDTODO 验收：[references/workspace-mdtodo.md](references/workspace-mdtodo.md)。
