From 53aafde5bdb94bf7cb4707705937640e848422de Mon Sep 17 00:00:00 2001 From: Codex Agent Date: Sat, 6 Jun 2026 23:50:53 +0800 Subject: [PATCH] fix: clarify caserun hwpod job polling --- docs/reference/spec-hwpod-harness.md | 4 +++- skills/hwpod-cli/SKILL.md | 2 +- tools/hwlab-cli/caserun.test.ts | 3 ++- tools/src/hwlab-caserun-lib.ts | 4 ++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/reference/spec-hwpod-harness.md b/docs/reference/spec-hwpod-harness.md index 93e0f76d..7729f860 100644 --- a/docs/reference/spec-hwpod-harness.md +++ b/docs/reference/spec-hwpod-harness.md @@ -211,7 +211,7 @@ bun tools/hwpod-cli.ts job status --spec .hwlab/hwpod-spec.yaml bun tools/hwpod-cli.ts uart read --spec .hwlab/hwpod-spec.yaml --port uart1 --max-bytes 4096 ``` -直调入口只用于单步定位和原链路复测:`build` / `download` 返回 Keil async job accepted 只能证明命令已投递,不能等同于编译或下载成功;必须继续用 `hwpod-cli job status ` 轮询终态,并结合 `uart read`、Keil result 或目标串口日志解释结果。串口被人工工具占用时,应先释放 COM 口或读取已有 serial-monitor 数据解释现象,不得把 COM 口占用误判成 DAPLink、目标板或 API 不可用。 +直调入口只用于单步定位和原链路复测:`build` / `download` 返回 Keil async job accepted 只能证明命令已投递,不能等同于编译或下载成功;必须继续用独立短命令 `hwpod-cli job status ` 轮询终态,不要把轮询包进 `sleep &&`、`timeout`、`watch`、`head`、pipe 或 shell loop。解释结果时结合 `uart read`、Keil result 或目标串口日志。串口被人工工具占用时,应先释放 COM 口或读取已有 serial-monitor 数据解释现象,不得把 COM 口占用误判成 DAPLink、目标板或 API 不可用。 ### CaseRun 让 code agent 调 hwpod-cli @@ -230,6 +230,8 @@ hwpod job status --spec .hwlab/hwpod-spec.yaml hwpod uart read --spec .hwlab/hwpod-spec.yaml --port uart1 --max-bytes 4096 ``` +对 Code Agent 而言,Keil/HWPOD 长任务同样遵循 cli-spec 短连接组合:`build` 或 `download` 只负责返回 async job id,`job status` 必须作为独立短命令少量轮询;若仍处于 running,应报告 job id、status、diagnostics 和当前判断,不要用长 shell 等待把 agent 子阶段拖成黑盒。 + CaseRun prompt 只能描述任务、边界、允许修改的文件、必须尝试的 HWPOD 命令和需要回报的 raw output/job id/串口尾部;不得把具体源码补丁、预期答案或自动评价逻辑写成 prompt。CaseRun result 负责归档 agent session id、trace id、agent message、final response、workspace diff、HWPOD command trace 和 registry run 产物;不做 evidence 自动评价、不做门禁、不把 runner 后置命令伪装成 agent 命令。若某个步骤卡住,先用人工单步直调入口复测同一 spec 和同一 subject worktree,确认是 HWPOD CLI/Keil/serial-monitor/hwpod-node 业务问题后再修复对应组合层或 node 本体。 ## CaseRun 无服务阶段 diff --git a/skills/hwpod-cli/SKILL.md b/skills/hwpod-cli/SKILL.md index 96f78595..699a5c93 100644 --- a/skills/hwpod-cli/SKILL.md +++ b/skills/hwpod-cli/SKILL.md @@ -24,7 +24,7 @@ The HWPOD spec is code-agent-side state. The default path is `.hwlab/hwpod-spec. - Inspect the HWPOD path: `hwpod inspect --spec .hwlab/hwpod-spec.yaml`. - Workspace read/edit: use `hwpod workspace ls|cat|read|write|replace|insert-after|apply-patch --spec .hwlab/hwpod-spec.yaml`. `read` is an alias for `cat`; `--file` and `--remote-path` are accepted as path aliases. - Build/download/reset: use `hwpod build`, `hwpod download`, and `hwpod reset`; the compiler must translate these through existing file ops and `cmd.run` where possible. -- Keil async status: after build/download returns a job id, use `hwpod job status --spec .hwlab/hwpod-spec.yaml` instead of shell polling wrappers. +- Keil async status: after build/download returns a job id, use separate short `hwpod job status --spec .hwlab/hwpod-spec.yaml` calls instead of shell polling wrappers such as `sleep &&`, `timeout`, `watch`, `head`, pipes, or loops. - UART read: use `hwpod uart read --spec .hwlab/hwpod-spec.yaml --port uart1`; the compiler runs the configured serial-monitor CLI through `cmd.run`. - For early debug bindings, put command bindings in `.hwlab/hwpod-spec.yaml` with `spec.workspace.buildCommand`, `spec.debugProbe.downloadCommand`, or `spec.debugProbe.resetCommand`. diff --git a/tools/hwlab-cli/caserun.test.ts b/tools/hwlab-cli/caserun.test.ts index df66678d..ca0ff64f 100644 --- a/tools/hwlab-cli/caserun.test.ts +++ b/tools/hwlab-cli/caserun.test.ts @@ -465,7 +465,8 @@ test("case run orchestrates agent prompt, diff capture, and compile evidence wit assert.match(prompt, /hwpod-ctl spec validate --spec \.hwlab\/hwpod-spec\.yaml/u); assert.match(prompt, /standard hwpod\/hwpod-ctl commands/u); assert.match(prompt, /hwpod job status --spec \.hwlab\/hwpod-spec\.yaml/u); - assert.match(prompt, /不要再用 shell timeout\/head\/pipe 包住/u); + assert.match(prompt, /不要再用 shell sleep\/&&\/timeout\/watch\/head\/pipe/u); + assert.match(prompt, /separate short `hwpod job status --spec \.hwlab\/hwpod-spec\.yaml` commands/u); const diff = await readFile(path.join(cwd, ".state", "hwlab-cli", "caserun", "run-agent-flow", "agent-diff.patch"), "utf8"); assert.match(diff, /printf\("hello"\)/u); assert.equal(requests.some((item) => item.url === "http://web.test/v1/agent/sessions"), true); diff --git a/tools/src/hwlab-caserun-lib.ts b/tools/src/hwlab-caserun-lib.ts index d3afdfd1..5c737183 100644 --- a/tools/src/hwlab-caserun-lib.ts +++ b/tools/src/hwlab-caserun-lib.ts @@ -1043,7 +1043,7 @@ async function renderAgentTaskPrompt(run: PreparedCaseRun, agentTask: PreparedAg "如果 .hwlab/hwpod-spec.yaml 缺失或内容明显不是本次 case,请报告 CaseRun workspace setup 错误,不要自行编造或迁移 spec。", "若 case prompt 要求源码修改,必须只改 subjectWorktreePath;若 prompt 未要求源码修改,则保持 subject 源码不变。", "不要运行 CaseRun 答案执行器;你本人必须通过 hwpod/hwpod-ctl 标准入口触发编译验证。", - "hwpod build/download 是长任务短连接入口;不要再用 shell timeout/head/pipe 包住它们。记录返回 JSON 里的 jobId/job_id,再用 hwpod job status --spec .hwlab/hwpod-spec.yaml 做有限轮询。" + "hwpod build/download 是长任务短连接入口;不要再用 shell sleep/&&/timeout/watch/head/pipe 或 shell loop 包住它们。记录返回 JSON 里的 jobId/job_id,再用独立的 hwpod job status --spec .hwlab/hwpod-spec.yaml 短命令做有限轮询。" ].filter(Boolean); return [ `# HWPOD CaseRun Code Agent Task`, @@ -1070,7 +1070,7 @@ async function renderAgentTaskPrompt(run: PreparedCaseRun, agentTask: PreparedAg `- Run \`hwpod-ctl spec validate --spec .hwlab/hwpod-spec.yaml\`.`, `- Run \`hwpod inspect --spec .hwlab/hwpod-spec.yaml\`.`, `- Follow the case task using standard hwpod/hwpod-ctl commands. Run build/download/UART steps only when the case explicitly asks for them, and report returned JSON/job/artifact/serial summaries.`, - `- For hwpod build/download, keep the HWPOD command unwrapped so it can return async JSON; then poll the returned job id with \`hwpod job status --spec .hwlab/hwpod-spec.yaml\` a bounded number of times.`, + `- For hwpod build/download, keep the HWPOD command unwrapped so it can return async JSON; then poll the returned job id with separate short \`hwpod job status --spec .hwlab/hwpod-spec.yaml\` commands a bounded number of times. Do not wrap status polling with shell sleep, &&, timeout, watch, head, pipes, or shell loops.`, `- CaseRun will inspect git diff under subjectWorktreePath after your turn completes and may run a runner post-check compile as separate evidence.`, `- CaseRun records trace/session/conversation, agent commandExecution, workspace diff and Keil build evidence without auto-grading them.` ].join("\n");