From 4efae91e423fc23f6ab52b8b30be11ec8096c60f Mon Sep 17 00:00:00 2001 From: Codex Date: Mon, 1 Jun 2026 13:07:11 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=9B=BA=E5=8C=96=20HWLAB=20=E5=9F=BA?= =?UTF-8?q?=E7=BA=BF=E6=89=BF=E6=8E=A5=20SPEC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/reference/spec-v01-agentrun-mgr.md | 29 +++++++++++++++++++ docs/reference/spec-v01-agentrun-runner.md | 28 ++++++++++++++++++ docs/reference/spec-v01-backend-adapter.md | 13 +++++++++ .../spec-v01-hwlab-manual-dispatch.md | 17 +++++++++++ docs/reference/spec-v01-runtime-assembly.md | 14 ++++++++- docs/reference/spec-v01-validation.md | 17 +++++++++++ 6 files changed, 117 insertions(+), 1 deletion(-) diff --git a/docs/reference/spec-v01-agentrun-mgr.md b/docs/reference/spec-v01-agentrun-mgr.md index e5cc5c8..15e0c4e 100644 --- a/docs/reference/spec-v01-agentrun-mgr.md +++ b/docs/reference/spec-v01-agentrun-mgr.md @@ -59,6 +59,19 @@ POST /api/v1/commands/:commandId/ack 所有 API 成功和失败响应都必须是 JSON。失败响应至少包含 `failureKind`、`message` 和 trace correlation;不得出现空 stdout/空 response 被误判为成功的情况。 +## HWLAB v0.2 基线承接 + +Manager 只承接 HWLAB v0.2 Code Agent 的通用执行事实,不承接 HWLAB 的用户鉴权、device-pod 授权或 Workbench schema。HWLAB 侧能力吸收总表见 [spec-v01-hwlab-manual-dispatch.md](spec-v01-hwlab-manual-dispatch.md)。本服务需要把以下能力固化为 AgentRun 自身合同: + +| HWLAB 原有能力 | Manager 承接合同 | 不归 Manager 管的内容 | +| --- | --- | --- | +| `/v1/agent/chat` 短连接提交后后台运行 | `POST /api/v1/runs`、`POST /api/v1/runs/:runId/commands` 和 `POST /api/v1/runs/:runId/runner-jobs` 均短返回 JSON,持久化 run/command/job identity | HWLAB HTTP route、浏览器同源代理、用户登录态 | +| result 轮询判断终态 | `GET /api/v1/runs/:runId/result` 和 command result 必须聚合 terminal status、reply、failureKind、blocker、event cursor 和 attempt | HWLAB result schema 和用户可见文案 | +| trace 轮询/回放 | `events` 是 append-only durable facts,单 run 内 `seq` 单调,支持 `afterSeq/limit` 分页 | Workbench trace UI、HWLAB event 展示分组 | +| 取消当前 turn | run/command cancel 幂等;pending cancel 阻止新 runner job,running cancel 通过 runner/backend interrupt 收敛,terminal 后返回当前终态 | HWLAB cancel 按 owner/admin 鉴权 | +| provider/backend 失败分类 | manager 统一保存并返回 failureKind;缺少 Secret、provider 鉴权失败、provider 不可用、backend 失败、infra 失败和 cancelled 必须可区分 | HWLAB 业务 blocker 分类或 device 授权失败 | +| runner/job 定位证据 | runner job 创建响应和后续查询至少能回答 `attemptId`、`jobName`、namespace、runnerId、pod/log identity 和当前 terminal 摘要 | 直接暴露 Kubernetes 控制权给业务客户端 | + ## Run 与 Command 合同 `POST /api/v1/runs` 必须持久化以下字段: @@ -93,6 +106,22 @@ POST /api/v1/commands/:commandId/ack - health/readiness 必须返回 Postgres reachable、schema migration ready、SecretRef redacted 状态和 build/source metadata。 - 日志、event、trace、health 和 diagnostics 不得输出 provider credential、Codex auth/config 内容、DSN password、token 或 URL credential。 +### Result envelope + +面向 HWLAB v0.2 原有 Code Agent 的承接基线,manager 的 run/command result envelope 至少包含: + +| 字段 | 规则 | +| --- | --- | +| `status` | run/command 当前聚合状态,只能由 command state 和 terminal_status 推导。 | +| `terminalStatus` | `completed`、`failed`、`blocked` 或 `cancelled`;没有 terminal event 时为 `null` 或 equivalent running 状态。 | +| `reply` | 从 `assistant_message` 聚合的最终用户可见文本;没有 terminal completed 时不得伪造 completed reply。 | +| `failureKind` / `blocker` | 结构化失败分类和摘要;必须 redacted。 | +| `lastSeq` / `eventCount` | 支持调用方增量轮询和 result/trace reconciliation。 | +| `runId` / `commandId` / `attemptId` | 支持调用方持久关联和问题定位。 | +| `artifactSummary` | 第一阶段只放有界摘要、字节数、截断标记和必要引用;不内嵌大 stdout/stderr。 | + +`assistant_message` partial、`command_output` 存在、stdout 非空、backend transport close 或 idle timeout 都不能单独让 result 进入 `completed`。 + ## 测试规格 ### T1 Manager health/readiness diff --git a/docs/reference/spec-v01-agentrun-runner.md b/docs/reference/spec-v01-agentrun-runner.md index dc357d9..bb8253d 100644 --- a/docs/reference/spec-v01-agentrun-runner.md +++ b/docs/reference/spec-v01-agentrun-runner.md @@ -32,6 +32,19 @@ Kubernetes Job runner 必须把 credential source 与 runtime home 分开:Secr RuntimeAssembly P0 中 `SessionRef` 可以显式为 `null`,runner 不得把完整 `CODEX_HOME`、Secret projection 或节点 host path 当作 session store。`ResourceBundleRef` P0 收敛为 Git-only;runner 已支持把 `repoUrl + full commitId` checkout 到 `AGENTRUN_WORKSPACE_ROOT` 下的隔离目录,并记录 commit/tree 摘要,不能把用户上传文件或 env dump 混入 Git-only bundle。 +## HWLAB v0.2 执行经验承接 + +Runner 承接的是 HWLAB v0.2 原有 Code Agent 的执行层经验,不承接 HWLAB cloud-api 的业务路由和权限判断。实现时优先参考 HWLAB 已验证的代码路径,而不是重新定义 Codex session、trace 和输出裁剪语义: + +| HWLAB v0.2 参考能力 | 参考入口 | Runner 承接规则 | +| --- | --- | --- | +| Codex app-server stdio thread/turn 生命周期 | `internal/cloud/codex-stdio-session.ts` | 有 `SessionRef.threadId` 时执行 resume,再 start turn;无 thread 时 start thread;turn terminal 才能上报 completed。 | +| cancel/interrupt | `internal/cloud/server-code-agent-http.ts`、`internal/cloud/codex-stdio-session.ts` | runner 必须轮询 manager cancel 状态并中止 backend;backend 不支持精确 interrupt 时终止受控进程组。 | +| runnerTrace 事件可见性 | `internal/cloud/code-agent-trace-store.ts` | backend 输出必须转成 manager events;每个 terminal/错误/取消都要有事件和 final status。 | +| workspace-write 边界 | `internal/cloud/code-agent-contract.ts` | runner 只使用 ResourceBundleRef materialized workspace,不猜 HWLAB Pod 的 `/workspace/hwlab` 或 host path。 | +| Secret 与 writable CODEX_HOME 分离 | `internal/cloud/code-agent-contract.ts`、`docs/reference/code-agent-chat-readiness.md` | profile Secret 只读投影,复制到当前 run/profile writable runtime home;不同 profile 不共享 runtime home。 | +| bounded stdout/stderr | `docs/reference/code-agent-chat-readiness.md` | `command_output` 记录摘要、字节数、截断标记和必要引用;不得把大输出直接塞进单个 event/result。 | + Kubernetes Job runner 必须设置有限保留时间。`v0.1` 默认 `ttlSecondsAfterFinished=86400`,用于保留最近完成 Job 的调试窗口,同时避免长期堆积 `Completed` runner Job 污染运行面观察。该 TTL 是 Job manifest 的运行面属性,不是 CI/CD 门禁;需要延长保留时间时必须通过受控 Job render/input 显式覆盖,并在 issue 或 PR 中说明原因。 ## Runner 生命周期 @@ -84,6 +97,21 @@ Runner 必须把以下失败归类为结构化 failureKind: Runner 日志必须实时 flush 到文件或 pod log,CLI 启动 runner 时必须返回 logPath 或 job/pod identity。日志、event、trace 和 CLI 输出不得出现 provider credential、`auth.json`、`config.toml` 内容、DSN password、token 或 URL credential。 +## Runner Job 最小状态 + +HWLAB v0.2 原有 Code Agent 在 cloud-api 进程内执行,失败时依赖本地 trace 定位;AgentRun 将执行迁到 runner Job 后,runner 必须把最小定位事实交回 manager。`runner-jobs` 创建响应和后续查询至少包含: + +| 字段 | 规则 | +| --- | --- | +| `attemptId` | 同一 command 的一次执行尝试;重复 idempotency key 和相同 payload 返回同一 attempt。 | +| `jobName` / `namespace` | Kubernetes Job identity;不得要求业务客户端自己构造名称。 | +| `runnerId` | runner register 后的执行者身份。 | +| `podIdentity` / `logPath` | 至少提供一种可定位 runner 日志的 redacted 引用。 | +| `phase` / `exitCode` | 若可用,返回 Job/Pod/container 的最小状态摘要;不可用时必须说明 `waitingFor` 或 failureKind。 | +| `startedAt` / `finishedAt` | 用于区分 pending、running、terminal 和 TTL retention 窗口。 | + +这些字段只用于可观测性,不授予调用方直接操作 Kubernetes Job 或读取 Secret 的权限。 + ## 测试规格 ### T1 Runner 启动可见性 diff --git a/docs/reference/spec-v01-backend-adapter.md b/docs/reference/spec-v01-backend-adapter.md index c428c1f..e2ab2c9 100644 --- a/docs/reference/spec-v01-backend-adapter.md +++ b/docs/reference/spec-v01-backend-adapter.md @@ -30,6 +30,19 @@ Backend adapter 消费 RuntimeAssembly 中的 `BackendImageRef` 和 `ProfileRef` `v0.1` 的第一真实 adapter 是 Codex stdio adapter。它必须走 Codex CLI app-server JSON-RPC over stdio;adapter 合同把 Codex 的 thread、turn、notification、tool lifecycle 和 stderr/exit 信息归一化为 AgentRun 标准 events。`codex` 与 `deepseek` 只是该 adapter 的 profile/config/SecretRef 选择,不允许复制两套协议实现。 +## HWLAB v0.2 Code Agent 能力吸收 + +Backend adapter 的第一阶段实现应吸收 HWLAB v0.2 已验证的 Codex stdio 行为,而不是另写一套不兼容协议。吸收只限通用 backend 执行能力,HWLAB 的自然语言业务路由、device-pod 授权和 Workbench 展示不进入 adapter。 + +| HWLAB v0.2 基线 | 参考入口 | Adapter 固化规则 | +| --- | --- | --- | +| Codex app-server JSON-RPC stdio | `internal/cloud/codex-stdio-session.ts`、`internal/cloud/codex-stdio-session-turn-state.ts` | 支持 `initialize`、`thread/start`、`thread/resume`、`turn/start`,并处理 app-server client request;未知请求要记录 unsupported error,不能静默等待。 | +| completed 判定 | `docs/reference/code-agent-chat-readiness.md` | 只有 Codex turn terminal completed 且 assistant reply 可聚合时才输出 completed;assistant delta、item completed、stdout 或 transport close 不能单独完成。 | +| assistant stream 和 trace | `internal/cloud/code-agent-trace-store.ts` | assistant delta 可归并为 `assistant_message`;event 必须保留 `threadId`、`turnId`、session 摘要和 redacted backend metadata。 | +| command/tool output bounded | `docs/reference/code-agent-chat-readiness.md`、`web/hwlab-cloud-web/app-trace.ts` | `tool_call` 和 `command_output` 必须记录状态、摘要、字节数、截断标记;完整大输出只能通过后续 log/artifact 引用。 | +| provider/profile 隔离 | `internal/cloud/code-agent-contract.ts` | `codex` 与 `deepseek` 共享同一 backend kind,但必须使用 profile-scoped SecretRef、model/base-url/config 和 writable runtime home。 | +| Secret redaction | `internal/cloud/code-agent-trace-store.ts` | `OPENAI_API_KEY`、auth/config、token、password、kubeconfig、URL credential 不得进入 event、result、log 或 health。 | + ## Backend Profile Registry `GET /api/v1/backends` 和 adapter 内部 registry 至少报告以下 profile: diff --git a/docs/reference/spec-v01-hwlab-manual-dispatch.md b/docs/reference/spec-v01-hwlab-manual-dispatch.md index 41c2f6d..6c75e2b 100644 --- a/docs/reference/spec-v01-hwlab-manual-dispatch.md +++ b/docs/reference/spec-v01-hwlab-manual-dispatch.md @@ -34,6 +34,23 @@ HWLAB Workbench HWLAB 应保存 `traceId -> runId/commandId/attemptId/jobName` 映射。用户轮询 HWLAB result/trace 时,HWLAB 从 AgentRun command status 与 run events 读取进展,再转换为 HWLAB 自己的前端 schema;浏览器不直接理解 AgentRun 内部 event schema。 +## HWLAB v0.2 Code Agent 能力吸收基线 + +AgentRun `v0.1` 承接 HWLAB v0.2 时,只吸收原有 Code Agent 的通用执行能力,不吸收 HWLAB 的用户鉴权、device-pod 授权、Workbench UI 或业务 trace schema。下表是后续实现时的代码追溯入口,目的是复用 HWLAB 已验证的边界和判定标准,而不是重新发明一套 Agent 行为。 + +| HWLAB v0.2 原有能力 | HWLAB 代码/文档追溯入口 | AgentRun 自身承接点 | SPEC 归属 | +| --- | --- | --- | --- | +| 短连接 submit + result/trace 轮询 | `internal/cloud/server-code-agent-http.ts`、`docs/reference/spec-v02-hwlab-cloud-api.md` | `run + command + runner-job` 三段式手动调度,所有写操作短返回 JSON | [spec-v01-agentrun-mgr.md](spec-v01-agentrun-mgr.md) | +| 只有真实 terminal completed + 非空 reply 才算通过 | `docs/reference/code-agent-chat-readiness.md`、`internal/cloud/code-agent-chat.ts` | result envelope 和 terminal status 规则;partial、stdout、transport close 不升级为 completed | [spec-v01-agentrun-mgr.md](spec-v01-agentrun-mgr.md)、[spec-v01-backend-adapter.md](spec-v01-backend-adapter.md) | +| runnerTrace 可见,能展示请求、工具、输出、错误和终态 | `internal/cloud/code-agent-trace-store.ts`、`web/hwlab-cloud-web/app-trace.ts` | 标准 event schema、单 run 内 seq 单调、bounded payload、Secret redaction | [spec-v01-backend-adapter.md](spec-v01-backend-adapter.md)、[spec-v01-agentrun-runner.md](spec-v01-agentrun-runner.md) | +| 取消正在执行的 turn | `internal/cloud/server-code-agent-http.ts`、`internal/cloud/codex-stdio-session.ts` | durable run/command cancel、pending 阻止启动、running interrupt、terminal 幂等返回 | [spec-v01-agentrun-mgr.md](spec-v01-agentrun-mgr.md)、[spec-v01-agentrun-runner.md](spec-v01-agentrun-runner.md) | +| conversation/session/thread 复用 | `internal/cloud/codex-stdio-session.ts`、`internal/cloud/code-agent-session-registry.ts` | `SessionRef` 保存 session/thread 摘要,runner 有 thread 则 resume,无 thread 则 start | [spec-v01-runtime-assembly.md](spec-v01-runtime-assembly.md) | +| 固定 repo workspace 执行 | `internal/cloud/code-agent-contract.ts`、`docs/reference/code-agent-chat-readiness.md` | `ResourceBundleRef` 使用 Git-only `repoUrl + full commitId` checkout 到隔离 workspace | [spec-v01-runtime-assembly.md](spec-v01-runtime-assembly.md)、[spec-v01-agentrun-runner.md](spec-v01-agentrun-runner.md) | +| provider profile 隔离和 Secret 不泄露 | `internal/cloud/code-agent-contract.ts`、`docs/reference/code-agent-chat-readiness.md` | `ProfileRef/SecretRef` profile-scoped 投影、缺失为 `secret-unavailable`、禁止 fallback 和泄露值 | [spec-v01-runtime-assembly.md](spec-v01-runtime-assembly.md)、[spec-v01-backend-adapter.md](spec-v01-backend-adapter.md) | +| provider/backend/cancel 等失败可区分 | `scripts/src/code-agent-response-contract.mjs`、`internal/cloud/code-agent-chat.ts` | failureKind 最小矩阵和 JSON 错误响应 | [spec-v01-agentrun-mgr.md](spec-v01-agentrun-mgr.md)、[spec-v01-backend-adapter.md](spec-v01-backend-adapter.md) | +| stdout/stderr/tool 输出必须有界 | `docs/reference/code-agent-chat-readiness.md`、`internal/cloud/code-agent-trace-store.ts` | `command_output`/`tool_call` 记录摘要、字节数、截断标记和必要引用 | [spec-v01-backend-adapter.md](spec-v01-backend-adapter.md) | +| runner/job 失败需要定位证据 | `internal/cloud/server-code-agent-http.ts` 的 trace/result 可见性 | runner job identity、attempt、jobName、pod/log identity 和最小 phase/exit 摘要 | [spec-v01-agentrun-runner.md](spec-v01-agentrun-runner.md)、[spec-v01-agentrun-mgr.md](spec-v01-agentrun-mgr.md) | + ## 手动调度 API `POST /api/v1/runs/:runId/runner-jobs` 是 HWLAB canary 的正式手动调度入口。它只负责为一个已存在 run 和 command 显式创建 runner Job,不负责扫描 pending queue。 diff --git a/docs/reference/spec-v01-runtime-assembly.md b/docs/reference/spec-v01-runtime-assembly.md index 94bc36a..6f29d45 100644 --- a/docs/reference/spec-v01-runtime-assembly.md +++ b/docs/reference/spec-v01-runtime-assembly.md @@ -34,6 +34,18 @@ P0 最小 JSON 形态: `executionPolicy`、`observabilityPolicy`、tenant identity、network、GC、failureKind、provenance 和 resource limit 都不是新的要素;它们分别挂在四要素或 run policy 上。 +## HWLAB v0.2 承接口径 + +HWLAB v0.2 原有 Code Agent 已经验证了 profile、session、workspace 和 Secret 的基本边界。RuntimeAssembly 需要把这些边界固化为 AgentRun 自身四要素,避免 runner 继续依赖 HWLAB cloud-api Pod 内路径或本地进程状态。 + +| HWLAB v0.2 基线能力 | HWLAB 参考入口 | RuntimeAssembly 承接字段 | 承接规则 | +| --- | --- | --- | --- | +| provider profile 可切换 | `internal/cloud/code-agent-contract.ts` | `ProfileRef.profile`、`ProfileRef.secretRef` | `deepseek` 与 `codex` 只选择 profile/config/SecretRef,不复制 backend 协议;缺失 Secret 必须失败,不 fallback。 | +| Codex app-server thread 复用 | `internal/cloud/codex-stdio-session.ts`、`internal/cloud/code-agent-session-registry.ts` | `SessionRef.sessionId`、`conversationId`、`threadId` | AgentRun 保存 backend thread/session 摘要;不保存 API KEY、`auth.json`、`config.toml` 或完整 `CODEX_HOME`。 | +| 固定 `/workspace/hwlab` 代码上下文 | `internal/cloud/code-agent-contract.ts` | `ResourceBundleRef.repoUrl`、`commitId` | 用 Git-only full commit 取代 HWLAB Pod 内固定路径;runner checkout 到隔离 workspace。 | +| writable `CODEX_HOME` 与 Secret 投影分离 | `docs/reference/code-agent-chat-readiness.md` | `ProfileRef` + runner runtime home | Secret 只读投影,复制到当前 run/profile writable runtime home;profile 间不共享。 | +| runner/image 可追溯 | HWLAB live build/source metadata | `BackendImageRef.image` | runner/backend image 必须可追溯 digest/source commit,不能由调用方任意传未受控镜像。 | + ## 四要素边界 ### BackendImageRef @@ -53,7 +65,7 @@ P0 最小 JSON 形态: ### SessionRef - P0 允许 `sessionRef=null`,表示不持久化 backend session 文件。 -- 面向 HWLAB 手动调度 canary,SessionRef 是 P1 必补能力:需要支持 `conversationId/sessionId/threadId` 到 backend session identity 的稳定映射。 +- 面向 HWLAB v0.2 原有长会话能力,SessionRef 是承接 Code Agent thread 复用的核心字段:需要支持 `conversationId/sessionId/threadId` 到 backend session identity 的稳定映射。 - 一旦启用 session,必须只保存 backend session/cache,不保存 API KEY、`auth.json`、`config.toml` 或完整 `CODEX_HOME`。 - session 文件目录必须和 profile credential、Git workspace 分开。 - runner 启动时,有 SessionRef 则执行 `thread/resume`,没有 SessionRef 则执行 `thread/start`;profile 切换不得复用另一 profile 的 session。 diff --git a/docs/reference/spec-v01-validation.md b/docs/reference/spec-v01-validation.md index f81ec54..05c2982 100644 --- a/docs/reference/spec-v01-validation.md +++ b/docs/reference/spec-v01-validation.md @@ -90,6 +90,23 @@ RESTful API 交互联调必须满足: CLI 与 RESTful API 可以复用同一个真实 run 做联调。若两者观察到的 run id、command id、state、terminal_status、failureKind、event seq 或 redaction 结果不一致,综合联调不通过。 +## HWLAB v0.2 基线承接验收 + +涉及 HWLAB v0.2 Code Agent 承接的变更,验收目标不是复刻 HWLAB adapter,而是证明 AgentRun 自身已经具备 HWLAB 原有 Code Agent 所依赖的执行元语。验收时直接使用 AgentRun API/CLI,不经过 HWLAB `/v1/agent/chat`。 + +| HWLAB 原有能力 | AgentRun 验收口径 | 通过标准 | +| --- | --- | --- | +| 短连接 submit + 后台执行 | 创建 run、command、runner job 均 60 秒内返回 JSON | 返回 runId、commandId、attemptId、job identity 和后续 poll 入口。 | +| result 终态判断 | 轮询 command/run result | 只有 terminal completed 且 reply 非空才算成功;failed/blocked/cancelled 均有 failureKind/blocker。 | +| trace 可见性 | 分页读取 events | event seq 单调,包含 backend_status、assistant 或 error、terminal_status;payload 有界且 redacted。 | +| cancel | 对 pending/running/terminal 分别调用 cancel | cancel 幂等,pending 不再启动 runner,running 收敛为 cancelled 或既有 terminal,events/result 可见。 | +| SessionRef | 连续两轮使用同一 sessionRef 或 conversation/session/thread 摘要 | 第二轮可 resume backend thread;session 不包含 credential 文件或完整 CODEX_HOME。 | +| ResourceBundleRef | 使用 `repoUrl + full commitId` 启动 runner | runner checkout 到允许 workspace,event/result 能回答 repo、commit、workspace 摘要;不使用 branch/tag/HEAD 或 host path。 | +| ProfileRef/SecretRef | 分别验证 `codex` 与 `deepseek` profile | 只使用当前 profile SecretRef;缺失时 `secret-unavailable`,不 fallback,不泄露 Secret 值。 | +| bounded output | 触发工具/命令输出摘要 | result/event 只含摘要、字节数、截断标记和必要引用,不把大 stdout/stderr 塞入单个 JSON 响应。 | + +这组验收吸收 HWLAB v0.2 的成熟判定口径,但不验证 HWLAB 用户鉴权、device-pod 授权、Workbench UI、`traceId -> runId` 业务映射或 HWLAB result/trace schema 转换。 + ## 发布判定 `v0.1` 发布通过必须同时满足: