Files
pikasTech-HWLAB/docs/reference/spec-device-pod.md
T
2026-06-05 11:52:47 +08:00

25 KiB
Raw Blame History

Device Pod 迁移对照规格

本文保留 HWLAB v0.2 既有 device-pod 正式接入口径,作为 HWPOD Harness 迁移对照。新的 HWPOD 业务方向以 spec-hwpod-harness.mdpikasTech/HWLAB#897 为准:快速迭代阶段先把 hwpod-spechwpod-clihwpod-ctlhwpod-compiler-cli 放在 Code Agent workspace 内,hwlab-api 只做 hwpod-node-ops 转发,hwpod-node 只维护少量稳定 ops。

device-pod 是一个逻辑设备能力单元,不是 Kubernetes Pod 名称,也不是 HWPOD 目标状态下的产品主概念。旧 profile/server authority 路径仍可用于现有 v0.2 兼容和迁移对照,但新增业务翻译应优先进入 hwpod-compiler-cli,不要继续堆在 hwlab-device-pod executor 或 device-host-cli.mjs 中。

实施跟踪见 pikasTech/HWLAB#533,原 docs/plan/v02-device-pod-spec-migration.md 和旧 device-pod MVP 计划全文已迁入该 issue 评论。

旧的 device-pod-cli 本地 profile 闭环只用于 CLI MVP 和真实硬件最小验证。既有正式多用户 device-pod 路径曾收敛到:

browser Cloud Web UI or hwpod/device-pod-cli
-> cloud-api AuthPrincipal + OpenFGA relation check
-> hwlab-device-pod internal REST
-> gateway transport
-> device-host-cli
-> Keil / pyOCD / UART / target

AgentRun runner 和 hwpod 的标准设备 API 入口是 HWLAB_RUNTIME_API_URL=http://hwlab-cloud-api.<namespace>.svc.cluster.local:6667,不是 hwlab-cloud-web。Cloud Web 只服务浏览器同源 UI 代理;hwpod 必须携带映射到发起用户的 HWLAB_API_KEY 直连 cloud-api,由 cloud-api 按该用户 grant 授权。内部 :6667 属于 WHATWG bad port 时,hwpod 必须使用 Node http/https 原生请求层访问 cloud-api,不能为了规避 bad-port 把设备 API 改走 Cloud Web。

在系统中的职责划分

device-pod 是云端可授权、可审计的逻辑设备能力单元。hwlab-cloud-api 是用户身份、用户 API key、grant、profile authority 和用户态 REST API 的入口;hwlab-device-pod 是内部执行服务;hwlab-gateway 只承载 transportdevice-host-cli 只在硬件 host 侧执行 Keil、pyOCD、UART 和 workspace 操作。

普通用户、浏览器和 Code Agent session 不直接持有 gateway route、host workspace route、Kubernetes Service 直连能力或 profile 修改权。

设计目标

  • 用最少组件把 device-pod-cli 从“本地 profile + RPC/gateway 调用”迁到“1:1 REST 请求”。
  • cloud-api 是用户身份、用户 API key、OpenFGA relation 和 profile authority 判断入口。
  • hwlab-device-pod 承接设备业务:profile 校验后的运行、job 生命周期、freshness、blocker、bounded output 和 gateway 调用。
  • device-pod-cli 只做 selector 解析、cloud-api REST 请求和 JSON 输出;默认正式模式不读取 .device-pod/*.json,不保存、不上传、不修改权威 profile。
  • 第一阶段只部署一个 hwlab-device-pod Deployment/Service,管理多个逻辑 devicePodId,避免为每台设备创建独立 k8s Service/Deployment。
  • 普通用户和 code agent session 不获得 Kubernetes 用户、Service 直连权限、gateway route 或 host workspace route。

逻辑模型

一个 device-pod 由四个设备能力要素组成:

device-pod
= deviceTarget
+ debugInterface
+ projectWorkspace
+ ioInterface
  • deviceTarget:被测设备目标,例如开发板、用户 PCB 或仪器模块。
  • debugInterface:下载、复位、chip-id、probe 状态和调试连接能力。
  • projectWorkspace:源码、工程、构建工具链和 artifact 边界。
  • ioInterface:UART、DI/DO、采样、日志和其他设备 I/O 观测/控制能力。

devicePodId 是云端和用户界面的稳定身份。实际 k8s Pod 可以重建、滚动或扩容;用户和 code agent 不依赖实际 Pod name。

Profile Authority

正式接入后,profile 是管理员侧资源:

admin UI/API
-> cloud-api
-> device_pods.profile_json + profile_hash
-> hwlab-device-pod internal execution

code agent 本地文件只能作为非权威 hint/cache,最多包含:

{
  "devicePodId": "device-pod-71-freq",
  "profileHash": "sha256:...",
  "cloudApiUrl": "..."
}

本地 hint/cache 不得包含以下字段,也不得参与授权或执行路由:

  • gatewaySessionId
  • resourceId
  • capabilityId
  • hostWorkspaceRoot
  • hostCli
  • Windows workspace 路径
  • probe UID、串口端口、Keil 路径等硬件路由字段

正式 profile 必须由 cloud-api 从 DB 读取;hwlab-device-pod 不接受浏览器、code agent 或 CLI 上传的 profile 作为执行依据。若 hwlab-device-pod 需要 profile snapshot,应只接受 cloud-api 内部服务凭据转发的 snapshot,或通过内部服务凭据向 cloud-api 拉取。该凭据不得挂载进 code agent session Pod。

内部架构

正式 device-pod 由 profile registry、job lifecycle、freshness/blocker、bounded output、gateway/device-host adapter 和用户 API key integration 组成。第一阶段只有一个 hwlab-device-pod Deployment 管理多个 devicePodIdprofile authority、OpenFGA relation 和 api_keys 在 cloud-api/Postgres 中,device-pod 服务只接受 cloud-api 内部调用。

当前 v02 部署中的 hwlab-device-pod 微服务实现情况见 spec-v02-hwlab-device-pod-service.md

Profile Shape

device_pods.profile_json 至少表达以下 server-side 字段:

{
  "schemaVersion": 1,
  "devicePodId": "device-pod-71-freq",
  "target": {
    "id": "target-id"
  },
  "projectWorkspace": {
    "workspaceRoot": "F:\\Work\\Project",
    "projectPath": "FirmWare/MDK-ARM/app.uvprojx",
    "targetName": "app",
    "hexPath": "FirmWare/MDK-ARM/app/app.hex"
  },
  "debugInterface": {
    "type": "cmsis-dap",
    "probeUid": "...",
    "uv4Path": "C:\\Keil_v5\\UV4\\UV4.exe"
  },
  "ioInterface": {
    "uart": [
      { "id": "uart/1", "port": "COM4", "baudRate": 921600 }
    ]
  },
  "route": {
    "gatewaySessionId": "gws_...",
    "resourceId": "res_...",
    "capabilityId": "cap_...",
    "hostWorkspaceRoot": "F:\\Work\\Project",
    "hostCli": "node tools\\device-host-cli.mjs"
  }
}

profile_json 不得保存 Git key、云 token、kubeconfig、数据库 URL 或长期 secret。profile_hashcloud-api 对规范化 profile JSON 计算并在所有响应中返回;用户可见响应只能返回脱敏 profile 摘要和 hash。

数据表口径

正式规格推荐 device_pods 直接保存权威 profile 和 hash,避免额外 profile 微服务:

CREATE TABLE IF NOT EXISTS device_pods (
  id TEXT PRIMARY KEY,
  name TEXT NOT NULL DEFAULT '',
  status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'disabled')),
  profile_json TEXT NOT NULL DEFAULT '{}',
  profile_hash TEXT NOT NULL DEFAULT '',
  created_at TEXT NOT NULL,
  updated_at TEXT NOT NULL
);

历史版本中的 profile_refgateway_refdevice_pod_json 可以在迁移时折叠进 profile_json。第一阶段不新增 device_pod_profile_revisions;需要审计版本、回滚或多环境批准时再引入 profile revision 表。

历史版本中的 device_pod_grants 不是当前 v0.2 device pod 授权契约。目标状态的 device pod 可见、操作、profile 修改和 job 提交权限只由 OpenFGA relation 表达;旧表若仍存在于已发布数据库中,只能作为历史迁移输入,不得作为写入口、健康必需表或 allow 判定来源。

REST API

API 接口说明

用户态 API 只经过 cloud-api 暴露:

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
POST /v1/device-pods/{devicePodId}/jobs
GET  /v1/device-pods/{devicePodId}/jobs/{jobId}
GET  /v1/device-pods/{devicePodId}/jobs/{jobId}/output
POST /v1/device-pods/{devicePodId}/jobs/{jobId}/cancel

管理员 API 由 cloud-api 提供:

POST /v1/admin/device-pods
PUT  /v1/admin/device-pods/{devicePodId}
PUT  /v1/admin/access/users/{userId}/device-pods/{devicePodId}/{relation}
DELETE /v1/admin/access/users/{userId}/device-pods/{devicePodId}/{relation}

POST /v1/device-pods/{devicePodId}/jobsintent 表达具体业务,避免把 REST surface 扩张成大量一次性 route

{
  "intent": "workspace.build",
  "args": { "profile": "debug" },
  "reason": "DEV smoke"
}

第一阶段 intent 集合:

  • workspace.ls
  • workspace.bootsharp
  • workspace.cat
  • workspace.rg
  • workspace.apply-patch
  • workspace.put
  • workspace.rm
  • workspace.rmdir
  • workspace.keil
  • workspace.build
  • debug.status
  • debug.chip-id
  • debug.download
  • debug.reset
  • io.ports
  • io.uart.read
  • io.uart.read-after-launch-flash
  • io.uart.write
  • io.uart.jsonrpc

GET /debug-probe/chip-idGET /io-probe/uart/1GET /io-probe/uart/1/tail 是用户态便捷 REST surface,但不能停留在静态面板或 fake probecloud-api 必须在完成 authenticate/grant 后创建对应只读 job,再经 hwlab-device-pod executor/gateway/device-host-cli 执行或返回同一套 blocker。

所有 job/status/output 和 probe GET 响应必须包含 devicePodIdtargetIdprofileHashtraceIdoperationIdstatusfreshnessblocker 和 bounded output metadata。job output 文本默认最大 12000 bytes;超出时必须设置 truncation.truncated=truetruncation.originalBytes,并避免把完整 executor/gateway 原始输出嵌回 JSON。真实硬件响应不得把 fake、dry-run、SOURCE、LOCAL 或过期缓存标为 DEV-LIVE

微服务职责

服务 职责
hwlab-cloud-api 用户身份、admin/user、用户 API key、OpenFGA relation、profile authority、用户态 REST API、转发到内部 device-pod。
hwlab-device-pod devicePodId 运行 registry、profile runtime validation、job store、freshness、bounded output、gateway/device-host-cli adapter。
device-pod-cli devicePodId:surface:path operation args 1:1 转成 cloud-api REST;不保存权威 profile、不读取本地 profile 作为默认 authority、不直连 gateway。
device-host-cli Windows host 侧自包含业务工具,负责 Keil、pyOCD、UART、workspace 文件操作。
hwlab-gateway 只做受控 transport,不理解用户权限和 device-pod 授权。
hwlab-cloud-web 展示用户可见 device pod、admin 管理 profile/relation、显示 job/status/freshness。

Kubernetes 口径

v0.2 第一阶段使用一个 hwlab-device-pod Deployment 和一个 ClusterIP Service

hwlab-v02/hwlab-device-pod
replicas: 1
manages: many devicePodId

不为每个 devicePodId 创建 Deployment、Service、Ingress、Secret 或 namespace。这样更符合当前规模:运维对象少、GitOps diff 少、问题定位简单,也不会把设备数量直接放大成 k8s 资源数量。

只有在满足以下条件时,才考虑拆分为多个 hwlab-device-pod shard 或 per-device workload

  • 单个服务内 job 队列和 freshness 监控互相影响;
  • 不同设备需要不同 host network、USB、Secret 或资源 request
  • 设备数量增长到单实例状态管理明显吃力;
  • 强隔离需求超过应用层 OpenFGA relation 和内部服务凭据能覆盖的范围。

普通用户和 code agent session Pod 不应直接调用 hwlab-device-pod Service。正式路径是 code agent -> cloud-api -> hwlab-device-pod

验收标准

  • device-pod-cli 在正式模式下不读取 .device-pod/<devicePodId>.json 作为权威 profile,只向 cloud-api 提交 devicePodId、intent 和 args。
  • 普通用户无授权时不能看到或使用任何 device pod;拥有 viewer 只能看到摘要,拥有 operator/job_submitter 才能提交对应 job,拥有 profile_editor 才能修改 profile。
  • code agent 不能通过修改本地文件改变 gateway session、resource、host workspace、probe UID 或 UART port。
  • hwlab-device-pod 不接受无内部服务凭据的 profile snapshot 或 job 请求。
  • hwlab-device-pod 一个实例可以列出并执行多个 devicePodId 的状态/job。
  • cloud-api legacy compatibility entry 只能返回 blocked authority payload,不得合成 fake device pod 数据或作为正式 device-pod DEV-LIVE 证据。
  • 强副作用 job 必须有 reason;正式路径只使用 Web session/cookie 或映射到具体用户的 HWLAB_API_KEY 做身份授权。
  • AgentRun runner 访问 device-pod 必须使用 cloud-api 组装的用户 HWLAB_API_KEY,该 key 恢复为发起 Code Agent session 的 owner 用户;不得使用跨用户共享、对所有正式 device-pod 授权的 system key。
  • 撤销 device pod relation 必须同时影响该用户通过 Web session、CLI API key 和 AgentRun hwpod 的可见性与使用权;revoke API key 后 CLI 和 runner 内旧 key 都必须失效。

CLI 实现口径

tools/device-pod-cli.ts 是 v0.2 正式 CLI 实现;HWLAB code-agent runner 内的唯一稳定短入口是 hwpod。runner 镜像必须把 hwpod 放入 PATH;缺少 hwpod 时应判定为 runner image/package 错误并修复镜像或封装,不得改走 /app/skills/device-pod-cli/scripts/device-pod-cli.mjs 长路径。正式 CLI 的默认行为是:

  • profile list/show 调用 cloud-api /v1/device-pods/status,只显示服务端脱敏 profile 摘要和 profileHash
  • AgentRun runner 中只使用装配好的 HWLAB_RUNTIME_API_URL 和映射到当前用户的 HWLAB_API_KEY,直接访问 hwlab-cloud-api;不得手动传 --api-base-url,也不得改走 Cloud Web 同源代理。
  • setup first-adminadmin device-pod upsert 只作为 cloud-api REST wrapper,用于首次空库 seed 或 admin profile 管理;device pod 授权统一使用 hwlab-cli client access device-pods grant/revoke 的 Admin Access API,不走 hwpod admin grant
  • devicePodId:workspace|debug-probe|io-probe... selector 转换为 POST /v1/device-pods/{devicePodId}/jobs 或 job status/output/cancel REST,不直接调用 /v1/rpc/hardware.invoke.shell
  • bootsharp --pod-id <devicePodId><devicePodId>:workspace:/ bootsharp 都转换为 workspace.bootsharp job,用于返回 workspace tree、AGENTS.md 摘要和当前路径提示;该入口是上下文恢复和 DS 派单的首个探测动作,不读取本地 profile。
  • workspace 写操作覆盖 apply-patchputrmrmdirbuildkeil add-source/remove-source 等 Keil 工程维护动作。
  • 源码局部编辑优先使用 apply-patchput 只用于明确的整文件写入或新文件创建。
  • UART 业务覆盖 readwriteread-after-launch-flashjsonrpcJSON-RPC 请求必须由 device-host-cli 校验 response id,除非显式传入允许 id mismatch 的业务参数。
  • apply-patch 类失败必须返回可定位的 patch hint,例如缺少 *** End Patch、hunk 上下文不匹配或 header 错误;调用方应先重新读取目标文件再重试小 hunk,不应默认绕到整文件覆盖。
  • mutating job 由 cloud-api 侧强制 reasonCLI 只转发 intentargsreason
  • profile create 这类本地 profile bootstrap 在正式默认路径中返回 legacy_profile_create_removed;管理员应使用 cloud-api admin API 管理服务端 profile,并使用 Admin Access API 管理 relation。
  • DS/device-pod prompt 和 skill 示例必须优先使用 hwpod,避免把长路径 wrapper 复制成常态命令;host job 轮询时 job id 必须作为 status/output/cancel 的紧随位置参数传入,不能放到 flags 后面或靠 shell 管道解析 JSON。

D601 F103 v0.2 Gateway SOP

D601 Windows F103 gateway 的稳定命名使用 gws_D601_F103。不要因为当前 devicePodId 或样例设备名是 device-pod-71-freq / 71-FREQ,把 gateway session 改成旧的 gws_d601_win_71_freqprofile route 和 Windows gateway 运行脚本必须使用同一组 F103 命名。

当前正式接入的 F103 v2 逻辑设备名为 D601-F103-V2。它的 Windows workspace 固定为 F:\Work\D601-HWLABKeil 工程为 projects/01_baseline/Projects/MDK-ARM/atk_f103.uvprojxKeil target 为 USARTKeil 可执行文件为 C:\Keil_v5\UV4\UV4.exeUART 为 COM9/115200。v0.2 服务端 profile 必须使用 devicePodId=D601-F103-V2,不得继续把该 workspace 暴露成 device-pod-71-freq

Windows 侧固定入口:

Task Scheduler: HWLAB-DevicePodGateway-D601-F103
run script: C:\Users\liang\device-pod-gateway-rust\run-D601-F103.cmd
local status: http://127.0.0.1:7001/status
cloud API: http://74.48.78.17:19667

run-D601-F103.cmd 中的关键环境变量应保持为:

set "HWLAB_GATEWAY_CLOUD_URL=http://74.48.78.17:19667"
set "HWLAB_ENVIRONMENT=v02"
set "HWLAB_GATEWAY_ID=gtw_D601_F103"
set "HWLAB_GATEWAY_SESSION_ID=gws_D601_F103"
set "HWLAB_GATEWAY_RESOURCE_ID=res_windows_host"
set "HWLAB_GATEWAY_BOX_ID=box_windows_host"
set "HWLAB_GATEWAY_CMD_CAPABILITY_ID=cap_windows_cmd_exec"
set "HWLAB_GATEWAY_CMD_EXEC_ENABLED=1"
set "HWLAB_GATEWAY_MAX_INFLIGHT=4"
set "HWLAB_GATEWAY_CMD_TIMEOUT_MS=120000"
set "HWLAB_GATEWAY_PORT=7001"

v0.2 D601-F103-V2 的服务端 profile route 必须和 gateway 注册保持一致:

{
  "gatewaySessionId": "gws_D601_F103",
  "resourceId": "res_windows_host",
  "capabilityId": "cap_windows_cmd_exec",
  "hostWorkspaceRoot": "F:\\Work\\D601-HWLAB",
  "hostCli": "node tools\\device-host-cli.mjs"
}

重启 gateway 时使用计划任务,不从临时 shell 直接启动长期进程:

schtasks /End /TN HWLAB-DevicePodGateway-D601-F103
schtasks /Run /TN HWLAB-DevicePodGateway-D601-F103
powershell -NoProfile -Command "Invoke-RestMethod http://127.0.0.1:7001/status | ConvertTo-Json -Depth 12"

通过 UniDesk Windows route 操作时,工作目录应直接定位到 gateway 目录,例如 D601:win/c/Users/liang/device-pod-gateway-rust,再读取 run-D601-F103.cmd 或查询 /status/status 中至少应看到 gatewaySessionId=gws_D601_F103cloudUrl=http://74.48.78.17:19667session.status=connectedoutbound.lastPollError=null

G14 v0.2 验收在 G14:/root/hwlab-v02 执行,先确认 Cloud Web 同源 CLI 能看到 device pod 状态,再用正式 device-pod-cli 创建并轮询 job

bun tools/hwlab-cli/bin/hwlab-cli.ts client device-pods status device-pod-71-freq \
  --base-url http://74.48.78.17:19666 \
  --full

COOKIE=$(node -pe 'require("./.state/hwlab-cli/session.json").cookie')
bun tools/device-pod-cli.ts device-pod-71-freq:workspace:/ ls \
  --api-base-url http://74.48.78.17:19667 \
  --cookie "$COOKIE" \
  --reason "v02 gws_D601_F103 smoke" \
  --timeout-ms 120000 | tee /tmp/hwlab-device-pod-job.json

JOB=$(node -e 'const fs=require("fs"); const payload=JSON.parse(fs.readFileSync("/tmp/hwlab-device-pod-job.json", "utf8")); console.log(payload.body.job.id)')

bun tools/device-pod-cli.ts job status --pod-id device-pod-71-freq "$JOB" \
  --api-base-url http://74.48.78.17:19667 \
  --cookie "$COOKIE"

bun tools/device-pod-cli.ts job output --pod-id device-pod-71-freq "$JOB" \
  --api-base-url http://74.48.78.17:19667 \
  --cookie "$COOKIE"

D601-F103-V2 的验收命令使用同一条 v0.2 CLI 链路,只替换 devicePodId 并从 bootsharp 开始:

bun tools/hwlab-cli/bin/hwlab-cli.ts client device-pods status D601-F103-V2 \
  --base-url http://74.48.78.17:19666 \
  --full

COOKIE=$(node -pe 'require("./.state/hwlab-cli/session.json").cookie')
bun tools/device-pod-cli.ts bootsharp --pod-id D601-F103-V2 \
  --api-base-url http://74.48.78.17:19667 \
  --cookie "$COOKIE"

bun tools/device-pod-cli.ts D601-F103-V2:workspace:/ build start \
  --api-base-url http://74.48.78.17:19667 \
  --cookie "$COOKIE" \
  --reason "D601-F103-V2 Keil build validation" \
  --timeout-ms 120000

bun tools/device-pod-cli.ts D601-F103-V2:debug-probe download start \
  --api-base-url http://74.48.78.17:19667 \
  --cookie "$COOKIE" \
  --reason "D601-F103-V2 Keil download validation" \
  --capture-uart uart/1 \
  --capture-duration-ms 8000 \
  --timeout-ms 120000

Code-agent/DS runner 内执行同类验收时,把 bun tools/device-pod-cli.ts 换成 hwpodhwpod 不在 PATH 时应判定为 runner 镜像或包安装错误并修复该标准入口,不得临时改走长路径 wrapper。UART 串口若被 Windows 侧工具占用,应把 COM busy/access denied 记录为可选串口证据缺口,Keil build/download 是否通过以 job output 中的 build summary、Programming DoneVerify OKApplication running 为准。

DS 或其他 code-agent runner 由 hwlab-cli client harness submit 触发时,控制面应保持短连接:提交后用 client harness resultclient harness trace --limit <N>client harness audit --require-bootsharp 轮询,不把 UniDesk ssh/tran 连接长期挂在一次 wait 上。client harness wait 只用于短窗口观察,CLI 会把超长等待压到低于 UniDesk 透传硬超时的安全窗口,并在 JSON 中返回后续短轮询命令。

job 观察优先使用 cloud-api job 入口,避免从 shell 管道里解析整段 JSON:

hwpod job status --pod-id D601-F103-V2 <jobId> --api-base-url <url> --cookie "$COOKIE"
hwpod job output --pod-id D601-F103-V2 <jobId> --api-base-url <url> --cookie "$COOKIE"

build status/output/cancel <jobId>download status/output/cancel <jobId> 只作为 selector 便捷别名;当 <jobId>job_devicepod_* 这类 cloud-api job 时,别名必须映射到 /jobs/<jobId>/jobs/<jobId>/output,不得误启动新的 build/download job。Keil host 侧子 job 仍保留 build status <hostJobId>download status <hostJobId> 语义,用于查看 Windows device-host-cli 创建的嵌套 job。

搜索下载、烧录或串口证据时,带空格、管道符或较长正则的 workspace rg 应使用显式参数,避免本地 shell、selector 和 Windows host 三层参数解析产生歧义:

hwpod D601-F103-V2:workspace:/ rg \
  --pattern "Programming Done|Verify OK|Application running|Error" \
  --path projects/01_baseline/captures \
  --api-base-url <url> --cookie "$COOKIE"

验收通过条件:client device-pods status 返回 status=okblocker=nullgateway sessions 中 gws_D601_F103 为 onlinedevice-pod-cli job 进入 completed,且 D601 Windows gateway /status.lastDispatch.operationId 与该 job 的 operationId 一致并有 lastResultAt。旧 gws_d601_win_71_freq session 只能作为历史 stale 线索,不能作为 v0.2 F103 gateway 的目标命名。

测试规格

T1

阅读 docs/reference/spec-device-pod.md,然后用 cli 手动测试以下内容:普通用户无 grant 时访问 /v1/device-pods 不得看到任何 device pod;获得 grant 后能看到对应 devicePodId 和脱敏 profileHash,不能看到 gatewaySessionId、hostWorkspaceRoot 或 probe UID 等敏感路由字段。

T2

阅读 docs/reference/spec-device-pod.md,然后用 cli 手动测试以下内容:尝试通过本地 .device-pod/*.json 修改 gateway route 或 workspace route,正式 cloud-api/device-pod 路径必须忽略该本地文件并继续使用服务端 profile authority。

T3

阅读 docs/reference/spec-device-pod.md,然后用 cli 手动测试以下内容:提交一个强副作用 job,例如 download/reset,缺少 reason 时必须被拒绝;补充 reason 后必须经同一条 cloud-api job REST 路径进入 executor,并返回 devicePodId、profileHash、traceId、operationId、freshness、blocker 和 bounded output metadata。

T4

阅读 docs/reference/spec-device-pod.md,然后用 cli 手动测试以下内容:对授权 Device Pod 运行 workspace putworkspace rmworkspace rmdirworkspace keil add-source/remove-sourceio-probe jsonrpc--dry-run 与一次真实小闭环。确认请求只经过 cloud-api job REST,输出 intent、reason、traceId 和 bounded output,不读取本地 profile、不直连 gateway。

规格的实现情况

规格项 状态 说明
逻辑 device-pod 模型 已实现为规格 四要素、profile shape 和 Kubernetes 口径已定义。
profile server authority 部分实现 cloud-api 保存正式 DB profile 并向用户返回脱敏摘要;device-pod executor 不接受用户上传 profile。
用户 relation + 用户 API key 部分实现 cloud-api 已实现 Admin Access relation、可见性过滤和强副作用 job reason 校验;AgentRun/hwpod 仍需从旧 shared device-pod key 收敛到映射用户的 HWLAB_API_KEY
REST/job API 部分实现 cloud-api 已实现 list/status/events/probe/job/output/cancel,并可把已授权 job 转发给内部 hwlab-device-pod executorexecutor 已实现内部 job create/get/output/cancel lifecycle 和 gateway/device-host-cli dispatch adapter,无在线 gateway/device-host-cli 时返回 blocker。
G14 device-host 功能吸收 部分实现 v0.2 job intent 已覆盖 workspace put/rm/rmdir、Keil 工程维护和 UART JSON-RPC,保持 cloud-api profile authority、OpenFGA relation 和用户 API key runtime auth。
禁止 fake 作为 DEV-LIVE 已实现/持续约束 规格和服务 payload 要求显式标记 fake/source。