docs: clarify HWLAB session resume boundaries

This commit is contained in:
Codex
2026-06-04 01:02:12 +08:00
parent a3422b4c76
commit 2ebb51eed7
5 changed files with 26 additions and 12 deletions
+6
View File
@@ -26,6 +26,12 @@ UniDesk 与 HWLAB 是 tenant/client。UniDesk 负责平台入口、provider 清
- `executionPolicy`,包含 sandbox、approval、timeout、network 和 secret scope - `executionPolicy`,包含 sandbox、approval、timeout、network 和 secret scope
- `traceSink`,说明标准化 event 镜像到哪里。 - `traceSink`,说明标准化 event 镜像到哪里。
HWLAB 接入时必须显式分离业务 identity 和执行 identityHWLAB `conversationId` / `sessionId` / `threadId` 是业务会话,AgentRun `runId` / `commandId` / `runnerJobId` 是执行尝试,AgentRun `SessionRef` / PVC 是 backend profile 续接状态。HWLAB Workbench 的 project/workspace 字段只能作为 HWLAB metadata 或 `workspaceRef` 子字段,不得写入 AgentRun `projectId`AgentRun `projectId` 仍固定表达 tenant policy 边界,例如 `pikasTech/HWLAB`
架构混乱的临时处理原则:发现 HWLAB provider/session/project/workspace 与 AgentRun tenant/project/run/job 字段混用时,不放宽 manager tenant policy、不改成 fallback backend、不靠 prompt 历史模拟续接。先在目标 runtime 用最小真实请求核对 run payload、runner job env、`SessionRef`、PVC phase、lease 和 command events;必要时热补丁只用于证明单变量修复,随后必须回到源码、CI/CD 和原入口复测。
长期收敛建议:跨仓库 API/schema 应使用不同字段名表达不同层级,例如 `hwlabProjectId` / `agentRunProjectId``hwlabSessionId` / `agentRunSessionId``providerProfile` / `backendProfile``runId` / `sessionId`。客户端和 Web 应同时展示业务 session/thread/provider 与执行 run/job/command,避免 operator 把 replacement runner 当作新业务 session 或把业务 workspace project 当作 AgentRun tenant policy。
## 服务形态 ## 服务形态
AgentRun 应构建为小型服务族: AgentRun 应构建为小型服务族:
+4 -3
View File
@@ -136,7 +136,7 @@ Manager 只承接 HWLAB v0.2 Code Agent 的通用执行事实,不承接 HWLAB
- events append-only,单 run 内 `seq` 单调递增。 - events append-only,单 run 内 `seq` 单调递增。
- command terminal 与 run terminal 必须分离。普通 turn completed 只终结对应 commandrun 可以保持 `claimed/running` 以继续接收后续 command;每个 command result 必须能从 command record 与 command-scoped events 得到 authoritative terminal。run 级 `terminal_status` 只用于 run cancel、runner 级不可恢复失败或明确 run terminalassistant partial、stdout、transport close 或 idle timeout 不能替代 terminal completed。 - command terminal 与 run terminal 必须分离。普通 turn completed 只终结对应 commandrun 可以保持 `claimed/running` 以继续接收后续 command;每个 command result 必须能从 command record 与 command-scoped events 得到 authoritative terminal。run 级 `terminal_status` 只用于 run cancel、runner 级不可恢复失败或明确 run terminalassistant partial、stdout、transport close 或 idle timeout 不能替代 terminal completed。
- failureKind 至少能区分 `schema-invalid``tenant-policy-denied``secret-unavailable``runner-lease-conflict``backend-failed``provider-auth-failed``provider-unavailable``infra-failed``cancelled` - failureKind 至少能区分 `schema-invalid``tenant-policy-denied``secret-unavailable``runner-lease-conflict``backend-failed``provider-auth-failed``provider-unavailable``infra-failed``cancelled``runner-lease-conflict` 对普通并发 runner 是拒绝原因;对 replacement runner 是可恢复的 transient 状态,manager 响应必须包含当前 owner、lease expiry 或等价等待依据,便于 runner 等待 stale lease 并重试。
- health/readiness 必须返回 Postgres reachable、schema migration ready、SecretRef redacted 状态和 build/source metadata。 - 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。 - 日志、event、trace、health 和 diagnostics 不得输出 provider credential、Codex auth/config 内容、DSN password、token 或 URL credential。
@@ -175,7 +175,7 @@ Manager 只承接 HWLAB v0.2 Code Agent 的通用执行事实,不承接 HWLAB
### T4 Runner claim 与 event pagination ### T4 Runner claim 与 event pagination
阅读本文和 [spec-v01-agentrun-runner.md](spec-v01-agentrun-runner.md),然后让两个真实 runner 尝试 claim 同一个 run。确认只有一个 owner 成功,另一个返回 `runner-lease-conflict` 或等价 failureKind;随后分页读取 events,确认 `seq` 单调、不重复、不丢失。 阅读本文和 [spec-v01-agentrun-runner.md](spec-v01-agentrun-runner.md),然后让两个真实 runner 尝试 claim 同一个 run。确认只有一个 owner 成功,另一个返回 `runner-lease-conflict` 或等价 failureKind,并包含足够判断 owner/lease expiry 的结构化字段;随后分页读取 events,确认 `seq` 单调、不重复、不丢失。再模拟旧 runner pod 删除后的 replacement runner,确认旧 lease 过期后 replacement runner 可以接管,且 claim waiting/recovered 事件可见。
### T5 手动 runner Job 调度 API ### T5 手动 runner Job 调度 API
@@ -197,7 +197,8 @@ Manager 只承接 HWLAB v0.2 Code Agent 的通用执行事实,不承接 HWLAB
| command/run terminal 分离 | 已实现最小闭环 | `PATCH /api/v1/commands/:commandId/status` 终结 command 并更新 SessionRef;普通 turn completed 不终结 runrun status 仅由 run cancel 或 runner 级不可恢复失败终结。 | | command/run terminal 分离 | 已实现最小闭环 | `PATCH /api/v1/commands/:commandId/status` 终结 command 并更新 SessionRef;普通 turn completed 不终结 runrun status 仅由 run cancel 或 runner 级不可恢复失败终结。 |
| Tenant policy boundary | 已实现最小边界 | v0.1 已做 schema、tenant/backend allowlist、executionPolicy 和 secretScope 结构校验;业务授权仍由 UniDesk/HWLAB 自己判定。 | | Tenant policy boundary | 已实现最小边界 | v0.1 已做 schema、tenant/backend allowlist、executionPolicy 和 secretScope 结构校验;业务授权仍由 UniDesk/HWLAB 自己判定。 |
| `deepseek` backendProfile allowlist | 已实现/已通过主闭环 | Manager validation、backend capability 和 matching SecretRef 校验已支持 `deepseek`;真实 runtime 已经通过 CI/CD 发布并确认 Postgres migration `002_v01_backend_profiles` 应用。 | | `deepseek` backendProfile allowlist | 已实现/已通过主闭环 | Manager validation、backend capability 和 matching SecretRef 校验已支持 `deepseek`;真实 runtime 已经通过 CI/CD 发布并确认 Postgres migration `002_v01_backend_profiles` 应用。 |
| `minimax-m3` backendProfile allowlist | 已实现/待真实主闭环 | Manager validation、backend capability 和 matching SecretRef 校验已支持 `minimax-m3`;真实 runtime 需要通过 CI/CD 发布并完成 AgentRun CLI 手动验收。 | | `minimax-m3` backendProfile allowlist | 已实现/已通过 HWLAB v0.2 原入口复测 | Manager validation、backend capability 和 matching SecretRef 校验已支持 `minimax-m3`;真实 runtime 通过 HWLAB 显式 session CLI 原入口复测。 |
| Postgres durable adapter | 已实现/已通过主闭环 | live runtime 通过 `DATABASE_URL` 使用 Postgres durable storememory store 仅用于显式 self-test/dev。见 [spec-v01-postgres.md](spec-v01-postgres.md)。 | | Postgres durable adapter | 已实现/已通过主闭环 | live runtime 通过 `DATABASE_URL` 使用 Postgres durable storememory store 仅用于显式 self-test/dev。见 [spec-v01-postgres.md](spec-v01-postgres.md)。 |
| Observability 最小合同 | 已实现主路径 | events append-only、command-scoped terminal status、failureKind、health/readiness store 状态、runner claim/lease/backend events 和 Secret/DSN redaction 已进入 manager;集中 trace 和部署级观测仍属后续工作。 | | Observability 最小合同 | 已实现主路径 | events append-only、command-scoped terminal status、failureKind、health/readiness store 状态、runner claim/lease/backend events 和 Secret/DSN redaction 已进入 manager;集中 trace 和部署级观测仍属后续工作。 |
| durable cancel API | 已实现最小闭环 | 已提供 run/command cancel APIpending command cancel 阻止新 runner Jobrunning runner 轮询 cancel 并中止 Codex stdio backend,终态使用 `cancelled`。 | | durable cancel API | 已实现最小闭环 | 已提供 run/command cancel APIpending command cancel 阻止新 runner Jobrunning runner 轮询 cancel 并中止 Codex stdio backend,终态使用 `cancelled`。 |
| stale lease recovery | 已实现/已通过 HWLAB v0.2 原入口复测 | replacement runner 遇到旧 lease 时等待 stale lease 并重试 claim,成功接管后继续同一 SessionRef/PVC/thread;正常并发 runner 仍返回 `runner-lease-conflict`。 |
+6 -5
View File
@@ -114,6 +114,7 @@ claimed -> lease_lost
- runner 必须先 register,再 claim runclaim 失败不能继续调用 backend。 - runner 必须先 register,再 claim runclaim 失败不能继续调用 backend。
- lease heartbeat 必须通过 manager lease/status 可观察;不得把周期性心跳或 backend running tick 写成 durable trace event 刷屏。长 turn 只在 `backend-turn-finished` 中输出有界 progress 摘要;过期或冲突时写入 failure event 或明确退出原因。 - lease heartbeat 必须通过 manager lease/status 可观察;不得把周期性心跳或 backend running tick 写成 durable trace event 刷屏。长 turn 只在 `backend-turn-finished` 中输出有界 progress 摘要;过期或冲突时写入 failure event 或明确退出原因。
- replacement runner 在 claim 时遇到 `runner-lease-conflict`,且 manager 响应显示旧 lease 未过期但可能来自已删除 pod 或失联 runner 时,不得立即把同一 HWLAB session 判为失败;应在 `AGENTRUN_RUNNER_CLAIM_RETRY_TIMEOUT_MS` 窗口内按 `AGENTRUN_RUNNER_CLAIM_RETRY_INTERVAL_MS` 等待旧 lease 过期并重试 claim。等待期间必须写入或输出 `runner-claim-waiting-for-stale-lease`,成功接管后写入 `runner-claim-recovered`;超过窗口才把 `runner-lease-conflict` 作为 terminal failureKind。并发双 runner 的正常冲突仍必须拒绝,不能抢占未 stale 的 active lease。
- command 只能从 manager poll;不得从本地文件或临时参数伪造正式 command。 - command 只能从 manager poll;不得从本地文件或临时参数伪造正式 command。
- runner 的普通 poll 只选择 pending `turn`;当 backend adapter 暴露 active turn control 后,runner 才在同 run 内轮询 pending `steer` commandack 后调用 backend 的 steer 能力并单独终结该 steer command。active turn 结束后到达的 steer 必须结构化 blocked,不得启动新 turn,也不得把 run 标为 terminal。 - runner 的普通 poll 只选择 pending `turn`;当 backend adapter 暴露 active turn control 后,runner 才在同 run 内轮询 pending `steer` commandack 后调用 backend 的 steer 能力并单独终结该 steer command。active turn 结束后到达的 steer 必须结构化 blocked,不得启动新 turn,也不得把 run 标为 terminal。
- backend 产生的所有可见输出必须先经过 adapter normalization 和 redaction,再 append 到 managerbackend_status 至少包含 redacted profile/backendKind/protocol 摘要。 - backend 产生的所有可见输出必须先经过 adapter normalization 和 redaction,再 append 到 managerbackend_status 至少包含 redacted profile/backendKind/protocol 摘要。
@@ -146,7 +147,7 @@ Runner 必须把以下失败归类为结构化 failureKind
- `provider-auth-failed`:上游 provider 鉴权失败。 - `provider-auth-failed`:上游 provider 鉴权失败。
- `provider-unavailable`:上游 provider 返回 HTTP 5xx/503、`Service Unavailable`、携带 5xx 的 `responseStreamDisconnected` 或明确 temporary/provider unavailable 文案;这是外部 provider availability blocker,不得归为本地 `backend-failed` - `provider-unavailable`:上游 provider 返回 HTTP 5xx/503、`Service Unavailable`、携带 5xx 的 `responseStreamDisconnected` 或明确 temporary/provider unavailable 文案;这是外部 provider availability blocker,不得归为本地 `backend-failed`
- `backend-failed`:backend 进程退出、协议错误或返回 terminal error。 - `backend-failed`:backend 进程退出、协议错误或返回 terminal error。
- `runner-lease-conflict`claim/lease 被其他 runner 持有。 - `runner-lease-conflict`claim/lease 被其他 runner 持有。replacement runner 遇到未过期旧 lease 时先按 stale lease recovery 规则等待并重试;仅在重试窗口耗尽、active lease 明确未 stale 或并发 runner 正常竞争时作为 terminal failureKind。
- `infra-failed`Job 启动、网络、manager API 或文件系统基础设施失败。 - `infra-failed`Job 启动、网络、manager API 或文件系统基础设施失败。
- `cancelled`:收到 interrupt/cancel 且已停止执行。 - `cancelled`:收到 interrupt/cancel 且已停止执行。
@@ -175,7 +176,7 @@ HWLAB v0.2 原有 Code Agent 在 cloud-api 进程内执行,失败时依赖本
### T2 Claim 与 lease 冲突 ### T2 Claim 与 lease 冲突
阅读本文和 [spec-v01-agentrun-mgr.md](spec-v01-agentrun-mgr.md),然后对同一个 run 启动两个 runner。确认只有一个 runner claim 成功,失败方输出结构化 failureKind,并且 manager events 中能看到冲突或拒绝原因。 阅读本文和 [spec-v01-agentrun-mgr.md](spec-v01-agentrun-mgr.md),然后对同一个 run 启动两个 runner。确认只有一个 runner claim 成功,失败方输出结构化 failureKind,并且 manager events 中能看到冲突或拒绝原因。再模拟旧 runner pod 删除但 lease 尚未过期的 replacement runner,确认 replacement runner 等待 stale lease、输出 `runner-claim-waiting-for-stale-lease`,接管后输出 `runner-claim-recovered`,并继续使用同一 `SessionRef`/PVC/thread 执行后续 command。
### T3 Backend event round-trip ### T3 Backend event round-trip
@@ -204,10 +205,10 @@ HWLAB v0.2 原有 Code Agent 在 cloud-api 进程内执行,失败时依赖本
| `agentrun-runner` 服务规格 | 已定义 | 本文为 v0.1 runner 权威。 | | `agentrun-runner` 服务规格 | 已定义 | 本文为 v0.1 runner 权威。 |
| Kubernetes Job runner | 已实现/已通过主闭环 | `runner job` 通过 manager REST 创建 Kubernetes Job,固定使用 `agentrun-v01-runner` ServiceAccount、manager URL、runId/commandId/attemptId、executionPolicy、SecretRef 文件投影、writable Codex runtime home、idle timeout 和有限 TTL;真实 `agentrun-v01` runner Job 已完成 Codex turn。 | | Kubernetes Job runner | 已实现/已通过主闭环 | `runner job` 通过 manager REST 创建 Kubernetes Job,固定使用 `agentrun-v01-runner` ServiceAccount、manager URL、runId/commandId/attemptId、executionPolicy、SecretRef 文件投影、writable Codex runtime home、idle timeout 和有限 TTL;真实 `agentrun-v01` runner Job 已完成 Codex turn。 |
| host process runner | 已实现 | `runner start``src/runner/main.ts` 进入同一套 `runOnce`,可通过 manager register/claim/poll/report 执行自测试,并支持 `--one-shot` 或 idle timeout 控制。 | | host process runner | 已实现 | `runner start``src/runner/main.ts` 进入同一套 `runOnce`,可通过 manager register/claim/poll/report 执行自测试,并支持 `--one-shot` 或 idle timeout 控制。 |
| claim/lease/report client | 已实现 | 已拆出 runner manager API client,覆盖 register、claim、lease heartbeat、poll command、ack、append event、command status 和必要 run statuslive runtime 通过 manager 写入 Postgres durable store。 | | claim/lease/report client | 已实现/已通过 stale lease recovery 复测 | 已拆出 runner manager API client,覆盖 register、claim、lease heartbeat、poll command、ack、append event、command status 和必要 run statusreplacement runner 遇到旧 lease 时会等待 stale lease 并重试 claimlive runtime 通过 manager 写入 Postgres durable store。 |
| cancel observation | 已实现最小闭环 | runner 在 backend 执行期间轮询 run/command cancel,触发 AbortController 中止 Codex stdio backend,并按 `cancelled` 上报 command/run 终态。 | | cancel observation | 已实现最小闭环 | runner 在 backend 执行期间轮询 run/command cancel,触发 AbortController 中止 Codex stdio backend,并按 `cancelled` 上报 command/run 终态。 |
| SessionRef/ResourceBundleRef 消费 | 已实现最小闭环/待 promptRefs 与 skillRefs | runner 会使用 run 中的 SessionRef threadId 执行 resume,并 materialize Git-only ResourceBundleRef 到隔离 workspace 后再启动 backend`toolAliases` 已实现,`promptRefs``skillRefs` 装配按本规格待补齐。 | | SessionRef/ResourceBundleRef 消费 | 已实现最小闭环/待 promptRefs 与 skillRefs | runner 会使用 run 中的 SessionRef threadId 执行 resume,并 materialize Git-only ResourceBundleRef 到隔离 workspace 后再启动 backendper-session PVC 直接挂载已通过 HWLAB v0.2 原入口恢复复测,`toolAliases` 已实现,`promptRefs``skillRefs` 装配按本规格待补齐。 |
| 同 run/runner 多 turn | 已实现最小闭环 | runner 在同一 Job 中 materialize bundle 一次后循环 poll command;普通 turn completed 只终结 commandrun 保持可继续接后续 turn,直到 idle timeout 或 run terminal。 | | 同 run/runner 多 turn | 已实现最小闭环 | runner 在同一 Job 中 materialize bundle 一次后循环 poll command;普通 turn completed 只终结 commandrun 保持可继续接后续 turn,直到 idle timeout 或 run terminal。 |
| runner redaction | 已实现主路径 | runner/backend event 和 Job 输出使用 redaction;复杂审计仍按 [spec-v01-validation.md](spec-v01-validation.md) 的人工验收抽查。 | | runner redaction | 已实现主路径 | runner/backend event 和 Job 输出使用 redaction;复杂审计仍按 [spec-v01-validation.md](spec-v01-validation.md) 的人工验收抽查。 |
| `deepseek` profile runner selection | 已实现/已通过主闭环 | Runner Job 和 host runner 已按 run `backendProfile` 选择 matching SecretRef、projection、`CODEX_HOME` 和 backend metadata;真实 Kubernetes Job 已完成 `codex -> deepseek -> codex` 切换联调。 | | `deepseek` profile runner selection | 已实现/已通过主闭环 | Runner Job 和 host runner 已按 run `backendProfile` 选择 matching SecretRef、projection、`CODEX_HOME` 和 backend metadata;真实 Kubernetes Job 已完成 `codex -> deepseek -> codex` 切换联调。 |
| `minimax-m3` profile runner selection | 已实现/待真实主闭环 | Runner Job 和 host runner 已按 run `backendProfile=minimax-m3` 选择 matching SecretRef、projection、`CODEX_HOME` 和 backend metadata;真实 Kubernetes Job 需要完成 MiniMax-M3 CLI 手动联调后收口。 | | `minimax-m3` profile runner selection | 已实现/已通过 HWLAB v0.2 原入口复测 | Runner Job 和 host runner 已按 run `backendProfile=minimax-m3` 选择 matching SecretRef、projection、`CODEX_HOME` 和 backend metadata;真实 Kubernetes Job 已通过 HWLAB 显式 session CLI 原入口复测。 |
@@ -94,6 +94,8 @@ HWLAB canary 创建 run 时应使用以下字段口径:
| `executionPolicy.secretScope.toolCredentials[]` | 需要 UniDesk SSH passthrough 时必须声明 `tool=unidesk-ssh``purpose=ssh-passthrough`、SecretRef `agentrun-v01-tool-unidesk-ssh`、projection env `UNIDESK_SSH_CLIENT_TOKEN`;不得把 token 放入 command payload 或 runner-job transientEnv。 | | `executionPolicy.secretScope.toolCredentials[]` | 需要 UniDesk SSH passthrough 时必须声明 `tool=unidesk-ssh``purpose=ssh-passthrough`、SecretRef `agentrun-v01-tool-unidesk-ssh`、projection env `UNIDESK_SSH_CLIENT_TOKEN`;不得把 token 放入 command payload 或 runner-job transientEnv。 |
| `traceSink` | 可指向 HWLAB trace adapter;为 `null` 时 HWLAB 仍可通过 AgentRun events 轮询。 | | `traceSink` | 可指向 HWLAB trace adapter;为 `null` 时 HWLAB 仍可通过 AgentRun events 轮询。 |
`tenantId` / `projectId` 是 AgentRun manager 的 policy 边界,不是 HWLAB Workbench project。HWLAB adapter 可以把业务 project/workspace 写入 `metadata.hwlabProjectId``metadata.hwlabWorkspaceId``workspaceRef`,但不得覆盖 AgentRun `projectId=pikasTech/HWLAB`;否则 manager 必须按 `tenant-policy-denied` 拒绝。`providerProfile` 是 HWLAB 入口字段,进入 AgentRun 后必须映射为 `backendProfile`;同一个 HWLAB session 的后续 turn 应继承 session provider profile,不能被 stale workspace provider 覆盖。
Command 第一阶段要求 `type=turn``type=steer``turn` 保存用户原始 prompt、conversation metadata、profile 选择和 HWLAB trace correlation;稳定业务 prompt、skill 清单和工具入口不写入 command payload,而是通过 `ResourceBundleRef.promptRefs``skillRefs``toolAliases` 装配。`steer` 保存运行中引导文本,并由 runner 在同 run active turn 期间转发到 backend。业务 cancel 仍走 run/command cancel API,不用 `steer` 伪装。不得把 cookie、session token、provider credential、device internal token、Secret value、历史消息或大段 skill manifest 写入 payload。 Command 第一阶段要求 `type=turn``type=steer``turn` 保存用户原始 prompt、conversation metadata、profile 选择和 HWLAB trace correlation;稳定业务 prompt、skill 清单和工具入口不写入 command payload,而是通过 `ResourceBundleRef.promptRefs``skillRefs``toolAliases` 装配。`steer` 保存运行中引导文本,并由 runner 在同 run active turn 期间转发到 backend。业务 cancel 仍走 run/command cancel API,不用 `steer` 伪装。不得把 cookie、session token、provider credential、device internal token、Secret value、历史消息或大段 skill manifest 写入 payload。
## 需要补齐的能力 ## 需要补齐的能力
@@ -137,6 +139,7 @@ AgentRun 需要提供 durable cancel 能力,建议形态为 `POST /api/v1/runs
- `POST /api/v1/runs/:runId/commands``storage_kind='evicted'` 时直接短路返回 `session-store-evicted`,不创建 runner Job。 - `POST /api/v1/runs/:runId/commands``storage_kind='evicted'` 时直接短路返回 `session-store-evicted`,不创建 runner Job。
- runner Job manifest 必须含 `volumes: [{ name: agentrun-sessions, persistentVolumeClaim: { claimName: ... } }]` 与对应 `volumeMounts`PVC `Phase=Bound` 才允许启动 turn。 - runner Job manifest 必须含 `volumes: [{ name: agentrun-sessions, persistentVolumeClaim: { claimName: ... } }]` 与对应 `volumeMounts`PVC `Phase=Bound` 才允许启动 turn。
- runner pod 被删除、Job 被重建或旧 runner lease 过期时,replacement runner 可以作为新的执行壳 claim 同一个 run 或 replacement run,但 resume 通过的判定仍必须是同一个 HWLAB session 映射到同一个 `SessionRef.sessionId``threadId``backendProfile` 和 PVC。不能把 replacement run/job 写成新业务 session,也不能用历史 prompt、messages 或 fake resume 代替 PVC 上的 Codex rollout。
- codex 写 `${CODEX_HOME}/<subdir>/YYYY/MM/DD/rollout-<timestamp>-<threadId>.jsonl`;其他路径不进入 PVC。 - codex 写 `${CODEX_HOME}/<subdir>/YYYY/MM/DD/rollout-<timestamp>-<threadId>.jsonl`;其他路径不进入 PVC。
- GC 在 `expires_at` 过期且无 active run 时删 PVC;删 PVC 同时把 `storage_kind` 置为 `evicted` - GC 在 `expires_at` 过期且无 active run 时删 PVC;删 PVC 同时把 `storage_kind` 置为 `evicted`
- HWLAB Cloud Web WorkbenchPR D)收到 `session-store-evicted` 时走「同 conversationId + 新 sessionId + `threadId=null`」的 reset UX,不假装续接;新 session 走 `POST /api/v1/sessions` 重新创建 PVC。 - HWLAB Cloud Web WorkbenchPR D)收到 `session-store-evicted` 时走「同 conversationId + 新 sessionId + `threadId=null`」的 reset UX,不假装续接;新 session 走 `POST /api/v1/sessions` 重新创建 PVC。
@@ -233,7 +236,7 @@ HWLAB 旧 Code Agent 的业务 prompt 和 skill 注入必须迁移为 `ResourceB
| trace/result 元语 | 已实现最小合同 | 新增 run/command result envelope,聚合 terminal status、reply、failureKind、event cursor、artifact summary、attempt、SessionRef 和 ResourceBundleRef 摘要。 | | trace/result 元语 | 已实现最小合同 | 新增 run/command result envelope,聚合 terminal status、reply、failureKind、event cursor、artifact summary、attempt、SessionRef 和 ResourceBundleRef 摘要。 |
| cancel | 已实现最小闭环 | 已提供 run/command cancel APIpending cancel 会阻止新 runner Jobrunning runner 通过轮询触发 backend abort,终态写入 event、command state 和 run status。 | | cancel | 已实现最小闭环 | 已提供 run/command cancel APIpending cancel 会阻止新 runner Jobrunning runner 通过轮询触发 backend abort,终态写入 event、command state 和 run status。 |
| SessionRef | 已实现最小持久化 | run 可携带 `sessionRef`manager 保存 session/threadrunner 会按 threadId resumeresult envelope 暴露脱敏 session 摘要;TTL/GC 仍按后续运维策略细化。 | | SessionRef | 已实现最小持久化 | run 可携带 `sessionRef`manager 保存 session/threadrunner 会按 threadId resumeresult envelope 暴露脱敏 session 摘要;TTL/GC 仍按后续运维策略细化。 |
| SessionRef | v0.1.1 实现中/未发布 | 在「metadata-only 最小持久化」基础上把 session 真实持久化:每个 session 绑 RWO PVC`agentrun-v01-session-<sessionId>`),runner Job 把 PVC 直接挂到 `${CODEX_HOME}/<codex_rollout_subdir>`codex app-server 自己落盘;HWLAB Cloud Web Workbench 收到 `session-store-evicted` 走 reset UX**不**写 fake 续接。 | | SessionRef | v0.1.1 实现/已通过 HWLAB v0.2 原入口复测 | 在「metadata-only 最小持久化」基础上把 session 真实持久化:每个 session 绑 RWO PVC`agentrun-v01-session-<sessionId>`),runner Job 把 PVC 直接挂到 `${CODEX_HOME}/<codex_rollout_subdir>`codex app-server 自己落盘;HWLAB 原入口已验证 runner pod 删除后同 session/thread/PVC 可以恢复,仍禁止 fake 续接。 |
| ResourceBundleRef | 已实现 Git-only materialization/待 promptRefs 与 skillRefs | run 可携带 `repoUrl + full commitId`runner checkout 到 `AGENTRUN_WORKSPACE_ROOT` 下的隔离目录并记录 commit/tree/workspace 摘要;`toolAliases` 已实现;上传文件和对象存储仍不进入 v0.1;HWLAB 初始 prompt 与 skill 注入按本规格待补齐。 | | ResourceBundleRef | 已实现 Git-only materialization/待 promptRefs 与 skillRefs | run 可携带 `repoUrl + full commitId`runner checkout 到 `AGENTRUN_WORKSPACE_ROOT` 下的隔离目录并记录 commit/tree/workspace 摘要;`toolAliases` 已实现;上传文件和对象存储仍不进入 v0.1;HWLAB 初始 prompt 与 skill 注入按本规格待补齐。 |
| 同 run/runner 多 turn | 已实现最小闭环 | runner Job 在 idle timeout 内持续 poll 同一 run 的后续 command;普通 turn completed 不终结 runbundle 只 materialize 一次,command result 按 commandId 独立聚合。 | | 同 run/runner 多 turn | 已实现最小闭环 | runner Job 在 idle timeout 内持续 poll 同一 run 的后续 command;普通 turn completed 不终结 runbundle 只 materialize 一次,command result 按 commandId 独立聚合。 |
| HWLAB v0.2 canary | 实现 | 需要 HWLAB dispatcher adapter 调 AgentRun 手动调度 API,并转换 result/trace。 | | HWLAB v0.2 canary | 实现/已通过 HWLAB v0.2 原入口复测 | HWLAB dispatcher adapter 调 AgentRun 手动调度 API,并转换 result/traceMiniMax-M3 显式 session、provider profile 继承和 runner pod 删除后的同 session resume 已通过原入口 CLI 复测。 |
+5 -2
View File
@@ -101,6 +101,8 @@ HWLAB v0.2 原有 Code Agent 已经验证了 profile、session、workspace 和 S
| writable `CODEX_HOME` 与 Secret 投影分离 | `docs/reference/code-agent-chat-readiness.md` | `ProfileRef` + runner runtime home | Secret 只读投影,复制到当前 run/profile writable runtime homeprofile 间不共享。 | | writable `CODEX_HOME` 与 Secret 投影分离 | `docs/reference/code-agent-chat-readiness.md` | `ProfileRef` + runner runtime home | Secret 只读投影,复制到当前 run/profile writable runtime homeprofile 间不共享。 |
| runner/image 可追溯 | HWLAB live build/source metadata | `BackendImageRef.image` | runner/backend image 必须可追溯 digest/source commit,不能由调用方任意传未受控镜像。 | | runner/image 可追溯 | HWLAB live build/source metadata | `BackendImageRef.image` | runner/backend image 必须可追溯 digest/source commit,不能由调用方任意传未受控镜像。 |
HWLAB Workbench 的 project/workspace 不属于 RuntimeAssembly 四要素,也不是 AgentRun `projectId`。这些业务字段只能作为 metadata 或 `workspaceRef` 的 HWLAB 子字段进入 runAgentRun policy 字段仍以 `tenantId` / `projectId` / `providerId` / `backendProfile` 为准。HWLAB `providerProfile` 在 RuntimeAssembly 中只映射为 `ProfileRef.profile` 和 run `backendProfile`,并应由显式 HWLAB session 继承,不能从 stale workspace fallback 覆盖。
## 四要素边界 ## 四要素边界
### BackendImageRef ### BackendImageRef
@@ -139,6 +141,7 @@ HWLAB v0.2 原有 Code Agent 已经验证了 profile、session、workspace 和 S
- runner 启动时把 PVC 名、namespace、mount path、codex rollout subdir 写入 env`AGENTRUN_SESSION_PVC_NAME``AGENTRUN_SESSION_PVC_NAMESPACE``AGENTRUN_SESSION_PVC_MOUNT_PATH``AGENTRUN_CODEX_ROLLOUT_SUBDIR`),backend adapter 不需要直接读 k8s API。 - runner 启动时把 PVC 名、namespace、mount path、codex rollout subdir 写入 env`AGENTRUN_SESSION_PVC_NAME``AGENTRUN_SESSION_PVC_NAMESPACE``AGENTRUN_SESSION_PVC_MOUNT_PATH``AGENTRUN_CODEX_ROLLOUT_SUBDIR`),backend adapter 不需要直接读 k8s API。
- `codex_rollout_subdir` 走 env,默认 `sessions`,codex CLI 升级改子目录时只改该 env,不改 runner/backend 装配。 - `codex_rollout_subdir` 走 env,默认 `sessions`,codex CLI 升级改子目录时只改该 env,不改 runner/backend 装配。
- `POST /api/v1/sessions` 创建 session 时同步创建 PVC`POST /api/v1/runs/:runId/commands` 命中已有 session 且 `storage_kind='evicted'` 时短路返回 `session-store-evicted`,不创建 runner Job。 - `POST /api/v1/sessions` 创建 session 时同步创建 PVC`POST /api/v1/runs/:runId/commands` 命中已有 session 且 `storage_kind='evicted'` 时短路返回 `session-store-evicted`,不创建 runner Job。
- runner pod 删除或旧 lease 过期后的 replacement runner 只改变执行尝试 identity,不改变 RuntimeAssembly 的 `SessionRef``ProfileRef``ResourceBundleRef`。验收时应证明 replacement run/job 仍使用同一 `SessionRef.sessionId``threadId``ProfileRef.profile` 和 PVC;不能通过新 session、新 profile 或历史 prompt 拼接来制造 resume 表象。
- GC 循环(默认 5min,可调 `AGENTRUN_SESSION_GC_INTERVAL_MS`)扫到 `expires_at` 过 + 无 active run 的 session 删 PVC。 - GC 循环(默认 5min,可调 `AGENTRUN_SESSION_GC_INTERVAL_MS`)扫到 `expires_at` 过 + 无 active run 的 session 删 PVC。
- runner Job 启动后把 PVC 摘要(`pvcName`/`pvcPhase`/`storage_size_bytes`/`storage_files_count`/`storage_sha256`/`storage_updated_at`)通过 `POST /api/v1/sessions/:id/storage/refresh` 写回 managermanager 不读 PVC 内容,只读摘要。 - runner Job 启动后把 PVC 摘要(`pvcName`/`pvcPhase`/`storage_size_bytes`/`storage_files_count`/`storage_sha256`/`storage_updated_at`)通过 `POST /api/v1/sessions/:id/storage/refresh` 写回 managermanager 不读 PVC 内容,只读摘要。
@@ -280,8 +283,8 @@ HWLAB v0.2 原有 Code Agent 已经验证了 profile、session、workspace 和 S
| 要素 | v0.1 状态 | 说明 | | 要素 | v0.1 状态 | 说明 |
| --- | --- | --- | | --- | --- | --- |
| `BackendImageRef` | 部分实现 | CI/CD 已使用 digest-pinned runtime image;当前 runner/backend 仍复用 agentrun 镜像。 | | `BackendImageRef` | 部分实现 | CI/CD 已使用 digest-pinned runtime image;当前 runner/backend 仍复用 agentrun 镜像。 |
| `ProfileRef` | 已实现/待 MiniMax-M3 主闭环 | `codex``deepseek` 已通过 SecretRef、writable runtime home 和真实 stdio turn 验证;`minimax-m3` 已进入 profile/SecretRef 装配,需要完成真实 CLI 手动验收。 | | `ProfileRef` | 已实现/已通过 HWLAB v0.2 原入口复测 | `codex``deepseek``minimax-m3` 已通过 SecretRef、writable runtime home 和真实 stdio turn 验证;MiniMax-M3 已通过 HWLAB 显式 session 原入口复测,后续只允许作为 profile/config/SecretRef 选择,不新增直连 backend。 |
| `SessionRef` | 已实现最小持久化 | manager 持久化 `sessionId/conversationId/threadId`run 创建会解析既有 sessionrunner 按 threadId resumesession 不保存 credential 文件,TTL/GC 后续细化。 | | `SessionRef` | 已实现最小持久化 | manager 持久化 `sessionId/conversationId/threadId`run 创建会解析既有 sessionrunner 按 threadId resumesession 不保存 credential 文件,TTL/GC 后续细化。 |
| `SessionRef` | v0.1.1 实现中/未发布 | manager 持久化 `sessionId/conversationId/threadId` + 每个 session 绑 RWO PVC`agentrun-v01-session-<sessionId>`),runner Job 把 PVC 直接挂到 `${CODEX_HOME}/<codex_rollout_subdir>`codex app-server 自己落盘;不允许 copy/restore,不允许 replacement threadIdTTL/GC 由 mgr 周期任务管理。 | | `SessionRef` | v0.1.1 实现/已通过 HWLAB v0.2 原入口复测 | manager 持久化 `sessionId/conversationId/threadId` + 每个 session 绑 RWO PVC`agentrun-v01-session-<sessionId>`),runner Job 把 PVC 直接挂到 `${CODEX_HOME}/<codex_rollout_subdir>`codex app-server 自己落盘;runner pod 删除后 replacement runner 仍复用同一 SessionRef/PVC/thread,禁止 copy/restorereplacement threadId 和 fake resume。 |
| `ResourceBundleRef` | 已实现 Git-only materialization/待 promptRefs 与 skillRefs 实现 | `repoUrl + full commitId` 已进入 run schema 和 runner checkoutworkspace 受 `AGENTRUN_WORKSPACE_ROOT` 限制,event/result 记录 commit/tree/workspace 摘要;`toolAliases` 已实现,`promptRefs` thread-start 注入和 `skillRefs` registry 聚合待实现。 | | `ResourceBundleRef` | 已实现 Git-only materialization/待 promptRefs 与 skillRefs 实现 | `repoUrl + full commitId` 已进入 run schema 和 runner checkoutworkspace 受 `AGENTRUN_WORKSPACE_ROOT` 限制,event/result 记录 commit/tree/workspace 摘要;`toolAliases` 已实现,`promptRefs` thread-start 注入和 `skillRefs` registry 聚合待实现。 |
| `toolCredentials` | 已实现最小 env projection | GitHub PR 和 UniDesk SSH passthrough 等 agent shell/tool 授权通过装配 SPEC 的 SecretRef 进入 runnerv0.1 支持 `tool=github``tool=unidesk-ssh``projection.kind=env`runner Job 使用 `valueFrom.secretKeyRef` 注入,不用 `transientEnv` 绕过。 | | `toolCredentials` | 已实现最小 env projection | GitHub PR 和 UniDesk SSH passthrough 等 agent shell/tool 授权通过装配 SPEC 的 SecretRef 进入 runnerv0.1 支持 `tool=github``tool=unidesk-ssh``projection.kind=env`runner Job 使用 `valueFrom.secretKeyRef` 注入,不用 `transientEnv` 绕过。 |