docs: plan device pod cli and server mvp

This commit is contained in:
Codex
2026-05-27 17:44:27 +08:00
parent 356f2f4e74
commit feb3bbab02
3 changed files with 202 additions and 0 deletions
+85
View File
@@ -0,0 +1,85 @@
# Device Pod CLI MVP 计划
本文描述 `device-pod-cli` 第一阶段实现计划。长期设备模型以 [../reference/device-pod.md](../reference/device-pod.md) 为准;本文只约束如何开发、调试和验收 CLI MVP。
## 目标
`device-pod-cli` 是给 HWLAB code agent 使用的独立硬件能力 CLI,不并入 `hwlab-cli`,也不继承 `hwlab-cli` 的广泛管理权限。第一版目标是先不实现真正的 `device-pod-server`,而是把 `device-pod` 当作 profile 驱动的抽象能力单元,通过以下路径跑通最小真实闭环:
```text
code agent -> device-pod-cli -> hwlab cloud-api/gateway -> device-host-cli -> debug probe / serial / WiFi / vendor protocol -> target
```
gateway 保持单纯 cmd 转发;硬件协议、串口、下载器和厂商工具复杂度隔离在用户 PC 上的 `device-host-cli` 后面。`device-pod-cli` 只暴露 workspace、debug-probe、io-probe 的受控语义能力,不提供泛化远程 shell。
## Profile 来源
CLI 每次执行都从 HWLAB code agent workspace 的 `.device-pod/` 目录读取 profile。推荐文件名为 `.device-pod/<devicePodId>.json`;后续可以兼容 YAML,但 MVP 优先使用 JSON,方便 schema 校验和 trace 记录。
profile 是灵活 source-of-truth,不做中心注册。CLI 输出必须包含 `profilePath``profileHash``devicePodId``targetId`,便于确认每次操作实际使用的是哪个 profile。profile 中只允许描述 route、受控 workspace root、debug-probe 能力、io-probe 能力和 host CLI 能力;不得写入 Git key、云端 token、kubeconfig、数据库 URL 或长期 secret。
## 命令口径
统一 locator 语法为:
```text
device-pod-cli <devicePodId>:<surface>[:<resourcePath>] <operation> [args...]
```
MVP surface 固定为:
- `workspace`:源码、工程、构建产物和受控文件操作。
- `debug-probe`:下载、复位、探针状态和芯片 ID。
- `io-probe`UART、GPIO、AI/AO/DI/DO、状态采样和日志读取。
workspace 操作采用 busybox 风格白名单,不提供 `cmd` 子命令。第一版建议只开放 `ls``cat``stat``rg``find``head``tail``wc``apply-patch``upload``download``build``clean``artifact list`。所有文件路径必须限制在 profile 声明的 workspace root 内。
示例:
```text
device-pod-cli device-pod-71-freq:workspace:/firmware ls
device-pod-cli device-pod-71-freq:workspace:/firmware/main.c cat --max-bytes 12000
device-pod-cli device-pod-71-freq:workspace:/firmware/main.c apply-patch < fix.patch
device-pod-cli device-pod-71-freq:workspace:/firmware build --profile debug
device-pod-cli device-pod-71-freq:debug-probe download --artifact build/app.hex --approved --reason "DEV smoke"
device-pod-cli device-pod-71-freq:debug-probe reset --approved --reason "DEV smoke"
device-pod-cli device-pod-71-freq:debug-probe chip-id
device-pod-cli device-pod-71-freq:io-probe:/uart/1 read --max-bytes 12000
device-pod-cli device-pod-71-freq:io-probe:/inner/gpio/pa1 read
```
`io-probe:/inner/...` 必须显式表示从 target 内部状态读取,例如寄存器、全局变量、debug memory 或固件导出的状态。默认 `io-probe:/gpio/pa1``io-probe:/uart/1` 等路径表示外部真实 I/O probe、仪器或另一个设备观测到的物理信号。验收证据中不得混淆 inner 和外部 I/O。
## 输出与权限
CLI 默认输出 JSON。成功和失败都必须包含 `devicePodId``targetId``surface``operation``traceId``operationId``profileHash``route``status``blocker``evidence` 和截断元数据。输出文本、串口日志和命令日志必须有 `maxBytes` 或分页边界。
下载、复位、写 I/O、修改 workspace 等动作属于 mutating operation,必须要求显式 approval 参数,并写入 reason。长耗时操作返回 `jobId`CLI 轮询或拉取 job output,不让一次 HTTP/gateway 调用长期阻塞。
## 开发方式
1. 先实现 profile schema、loader、locator parser 和 JSON 输出合同,用 fake profile 在本地单元测试覆盖成功、缺 profile、坏 profile、路径越界和未知 surface。
2. 实现 workspace busybox 操作和 fake gateway adapter,先在不接硬件时证明路径裁剪、输出截断和错误结构稳定。
3. 实现 debug-probe 与 io-probe 的 adapter 接口,先用 fake `device-host-cli` 返回 chip ID、UART 样例和下载 job 状态。
4. 在 D518 Windows 上开发 `device-host-cli`,通过 `D518:win` 做真实 DAPLink、串口或下载器 smoke;D518 侧只承载硬件上位机逻辑,不改变 G14 source truth。
5. 在 G14 code agent pod 中开发和验证 `device-pod-cli`code agent pod 不放完整 HWLAB 源码和 Git keyCLI 通过 skill 分发到预装位置,并在 skill 说明中写清仅适用于 HWLAB 内部 code agent。
6. fake 闭环通过后再做 G14 -> gateway -> D518 -> 硬件的最小 live smoke,然后把修复固化到源码、测试和长期参考。
## 调试方式
- `--dry-run` 只解析 profile、locator 和路由计划,不触发 gateway 或硬件动作。
- `--trace-id` 可传入外部 trace;未传入时 CLI 生成 trace,并在所有 adapter 输出中透传。
- `--verbose` 只展开结构化 adapter 阶段和截断摘要,不直接打印 secret 或无限日志。
- fake adapter 用于本地和 CIlive adapter 只在明确选择 profile route 时启用。
- 真实硬件问题先在 D518 `device-host-cli` 单独复现,再通过 `device-pod-cli` 验证端到端链路。
## 验收标准
MVP 通过至少需要满足:
- `.device-pod/<devicePodId>.json` 能被读取、校验、hash 并体现在每次 CLI JSON 输出中。
- workspace `ls/cat/rg/apply-patch/build/artifact list` 在受控 root 内可用,路径越界、过大输出和未知命令有结构化失败。
- `debug-probe chip-id/download/reset` 能通过 fake adapter 稳定返回 job/evidencelive smoke 至少证明一次真实 debug probe 路径可达。
- `io-probe:/uart/1 read``io-probe:/inner/... read` 在输出中明确标注外部/内部来源,不互相冒充。
- gateway 仍只是 cmd transportCLI 不暴露任意 shell、不接收泛化 `cmd` 子命令、不绕过 profile 访问硬件。
- 文档、CLI 帮助和 skill 说明明确写明该 CLI 只用于 HWLAB 内部 code agent,不适用于 UniDesk 外部开发者工作区。
+102
View File
@@ -0,0 +1,102 @@
# Device Pod Server MVP 计划
本文描述 `device-pod-cli` 跑通后的第二阶段:实现真正的 `device-pod-server`。长期设备模型以 [../reference/device-pod.md](../reference/device-pod.md) 为准;本文只约束 server MVP 的开发、调试、目标和验收。
## 目标
`device-pod-server` 是一个与 `device-pod` 一一对应的服务实例,用来提供短同步 RESTful API、短异步 RESTful job API 和后台监控缓存。它解决 CLI 直连 profile/gateway 之后仍无法持续监控设备的问题。
MVP 对外目标是:
- `device-pod-cli` 的稳定语义能力都能映射到 REST API。
- server 后台维护 debug-probe 和 io-probe 的最新状态、freshness 和错误 blocker。
- HWLAB cloud-api 代理 server API,前端只通过 cloud-api 查看设备状态,不直连 gateway 或用户 PC。
- 前端最小版本只显示 `io-probe:/uart/1` 的最新状态/日志尾部,以及 `debug-probe` 的 chip ID 和 probe 状态。
## Profile 同步
server 阶段仍不引入中心 profile 注册表。HWLAB code agent workspace 的 `.device-pod/` 目录继续作为 profile source-of-truth`device-pod-cli` 或 code agent 每次连接 server 前读取 `.device-pod/<devicePodId>.json`,自动上传或刷新 profile。
server 只保存 active profile、`profileHash`、加载时间和校验结果,作为运行时缓存。profile 修改后不需要改 server 配置或重启服务;下一次 CLI/agent 同步即可更新 active profile。server 收到缺失、坏格式或能力不匹配的 profile 时返回 `profile-missing``profile-invalid``capability-mismatch` blocker,不回退到历史 profile 执行 mutating operation。
建议最小 profile API
```text
PUT /v1/profile
GET /v1/profile
```
CLI 可以提供调试入口:
```text
device-pod-cli device-pod-71-freq:profile sync
```
`profile` 是 CLI/server 控制面同步动作,不属于 deviceTarget 四要素之一。
## 最小 REST API
同步 API 只返回短状态和缓存快照:
```text
GET /health
GET /v1/status
GET /v1/capabilities
GET /v1/debug-probe/status
GET /v1/debug-probe/chip-id
GET /v1/io-probe/status
GET /v1/io-probe/uart/1
GET /v1/io-probe/uart/1/tail?maxBytes=12000
```
异步 API 用于下载、复位、workspace build、串口写入和采样窗口等动作:
```text
POST /v1/workspace/jobs
POST /v1/debug-probe/jobs
POST /v1/io-probe/jobs
GET /v1/jobs/{jobId}
GET /v1/jobs/{jobId}/output
POST /v1/jobs/{jobId}/cancel
```
cloud-api 代理最小口径:
```text
GET /v1/device-pods
GET /v1/device-pods/{devicePodId}/status
GET /v1/device-pods/{devicePodId}/debug-probe/chip-id
GET /v1/device-pods/{devicePodId}/io-probe/uart/1
GET /v1/device-pods/{devicePodId}/io-probe/uart/1/tail?maxBytes=12000
```
所有响应必须包含 `devicePodId``targetId``profileHash``traceId``operationId``status``freshness``blocker``evidence`。server、cloud-api 和 frontend 不得把 fake、dry-run、SOURCE、LOCAL 或缓存过期状态标成 `DEV-LIVE`
## 开发方式
1. 从已跑通的 `device-pod-cli` profile schema、locator parser、operation adapter 和 JSON 输出合同中抽取共享模块,避免 CLI 与 server 两套语义分叉。
2. 实现 server skeletonhealth、profile sync、status、capabilities、job store、bounded output、lock 和 freshness 模型。
3. 先接 fake `device-host-cli` adapter,稳定 chip ID、UART tail、job 状态和 blocker 行为。
4. 再接 gateway/cmd/device-host-cli live adapter,保持 gateway 仍是 transport,不把 server 做成任意 shell 代理。
5. 在 G14 DEV k3s 中部署单个 device-pod server 实例做 smoke,不改 PROD、不重启无关服务。
6. 增加 cloud-api proxy 和前端最小展示,只显示 chip ID、probe 状态、UART1 最新片段和 freshness。
## 调试方式
- `GET /health` 只验证进程、profile loader 和基础依赖,不触发硬件动作。
- `GET /v1/profile` 展示脱敏后的 active profile 摘要、`profileHash` 和校验状态。
- fake profile + fake host CLI 用于 server 单测和 G14 DEV 无硬件 smoke。
- live 调试先看 server 结构化日志中的 `profileHash``route``jobId``freshness` 和 blocker,再到 D518 `device-host-cli` 单独复现硬件问题。
- UART tail、job output 和日志都必须截断或分页;默认调试输出不能 dump 全量串口日志、源码或 secret。
## 验收标准
MVP 通过至少需要满足:
- 修改 `.device-pod/<devicePodId>.json` 后,无需重启 server,下一次 CLI/agent 同步即可看到新的 `profileHash`
- 无 profile、坏 profile、过期 profile 和 capability mismatch 都有明确 blocker,不执行下载、复位或 I/O 写入。
- `GET /v1/debug-probe/chip-id` 能通过 fake adapter 和至少一次 live smoke 返回 chip ID 或结构化硬件 blocker。
- `GET /v1/io-probe/uart/1` 和 tail API 能显示 UART1 最新状态、freshness、截断信息和 evidence。
- cloud-api 代理能返回同一组字段,前端最小页面能显示 chip ID、UART1 和 freshness,不直连 server/gateway。
- mutating job 都是短 HTTP 创建、异步轮询、可取消、有 lock、有 approval reason。
- server 与 CLI 的 operation 名称、错误码、profileHash 和 evidence 字段保持一致。
+15
View File
@@ -12,6 +12,21 @@ device-pod
+ ioInterface
```
## 实施计划
长期模型以本文为准;分阶段实现计划单独维护,避免把一次性开发步骤写进长期参考:
- [Device Pod CLI MVP 计划](../plan/device-pod-cli-mvp.md):先做 code agent 可调用的独立 CLI,通过 profile、gateway 和用户 PC 侧 `device-host-cli` 跑通 workspace、debug-probe 和 io-probe 的最小闭环。
- [Device Pod Server MVP 计划](../plan/device-pod-server-mvp.md):在 CLI 跑通后再实现真正的 `device-pod-server`,提供与 CLI 对应的 RESTful API、后台监控缓存和前端最小可视化。
## Profile 注册与同步
MVP 不使用刚性的中心 profile 注册表。`device-pod` profile 的灵活源头是 HWLAB code agent workspace 下的 `.device-pod/` 目录,推荐按 `devicePodId` 存放 profile 文件,例如 `.device-pod/device-pod-71-freq.json`
`device-pod-cli` 每次执行都从当前 code agent workspace 的 `.device-pod/` 读取 profile,并在输出中保留 `profilePath``profileHash`。进入 `device-pod-server` 阶段后,CLI 或 code agent 仍以 `.device-pod/` 为 profile source-of-truth;每次连接 server 前自动上传或刷新 profileserver 只把 active profile 当作运行时缓存,不把它变成长期配置真相。
profile 必须只描述 target、debugInterface、projectWorkspace、ioInterface、gateway route、host CLI 能力和受控路径边界;不得放入 Git key、云端 token、kubeconfig、数据库 URL 或其他长期 secret。profile 校验失败时应返回 `profile-invalid``profile-missing` blocker,而不是回退到默认设备或任意 shell。
## 四要素
### `deviceTarget`