Files
pikasTech-agentrun/docs/reference/spec-v01-validation.md
T
2026-06-02 07:57:09 +08:00

212 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# v0.1 两层验证规格
本文定义 AgentRun `v0.1` 的测试、联调和验收模型。`v0.1` 只保留两层验证:组件自测试和综合联调。自测试允许 mock,用于快速迭代;综合联调必须 100% 真实,用于判断能否交付或发布。
## 两层模型
| 层级 | 目的 | 是否允许 mock | 运行位置 | 通过含义 |
| --- | --- | --- | --- | --- |
| 自测试 | 单个组件内部快速反馈,覆盖纯函数、schema、状态机、错误分类和 redaction。 | 允许 | 本地或 Tekton Task | 组件内部逻辑没有明显回归。 |
| 综合联调 | 验证 v0.1 runtime 的真实闭环。 | 禁止 | G14 k8s `agentrun-v01` + Tekton/Argo | 当前版本可作为真实运行面候选。 |
除这两层外,不新增单独的“半真实”“准联调”“dry-run pass”或“模拟上线”验收层。mock 结果只能证明自测试通过,不能作为综合联调或发布通过证据。
## 自测试
自测试属于每个组件自己的 `spec-v01-*.md` 的“测试规格”子项。它可以使用 mock、fake backend、临时 Postgres、内存对象、fixture 和本地进程,但必须明确标记为自测试。
自测试应覆盖:
- `agentrun-mgr`Run schema、tenant fields、idempotency、command 状态机、event seq、claim/lease 冲突、failureKind。
- `agentrun-runner`claim/poll/report client、heartbeat、backend event normalization、interrupt/cancel、logPath、Secret redaction。
- backend adapter:输入输出转换、assistant/tool/error/terminal event、provider auth failure 分类、provider credential 不进 event/log。
- CLI:默认 JSON、空 stdout 失败、长操作短返回、错误结构化。
- Postgres adaptermigration、事务、run/command/event round-trip、重启后可查询。
- Secret 分发:SecretRef schema、missing secret failure、redaction。
- AgentRun Queuetask schema、attempt 状态机、summary/stats/read cursor、Queue 与 Session 引用边界、旧 MiniMax/OpenCode 直连入口废弃和 redaction。
- HWLAB v0.2 基线承接:可以用 fake backend/临时 manager 做组件自测试,覆盖 event contract、result completed 防误判、bounded output、runner job status、SessionRef profile 隔离、ResourceBundleRef 失败分类和 backend preflight redaction;这些自测试不能替代真实 `agentrun-v01` CLI 交互验收。
自测试应使用 Bun + TypeScript 运行,Codex 相关自测试可以使用 fake app-server JSON-RPC client 模拟 `initialize``thread/start``thread/resume``turn/start`、assistant 输出、协议错误、timeout 和 transport close。
仓库内自测试入口必须保持可并行扩展:`src/selftest/run.ts` 只负责发现和调度 `src/selftest/cases/*.ts`,公共 fixture 和断言辅助放 `src/selftest/harness.ts`。新增组件自测试优先新增独立 case 文件,避免多个并行任务修改同一个总入口导致反复冲突。若某个 case 需要跨组件验证,可以依赖正式 manager/runner/backend API,但仍应作为独立 case 命名和维护。
自测试输出可以是 Tekton TaskRun result、JUnit、tap、JSON summary 或普通日志,但不得回写 source branch,也不得伪装成综合联调通过。
## 综合联调
综合联调必须在真实 `agentrun-v01` 运行面执行,且不得使用 mock 或 fake 替代核心链路。
综合联调必须使用:
- 真实 `origin/v0.1` source commit。
- 真实 Tekton PipelineRun 构建和 promotion。
- 真实 `v0.1-gitops` artifact catalog 与 `deploy/gitops/g14/runtime-v01/**`
- 真实 Argo CD Application `agentrun-g14-v01` 同步到 `agentrun-v01`
- 真实 `agentrun-v01-postgres` StatefulSet、PVC、Service 和 migration ledger。
- 真实 Kubernetes SecretRef 注入 Postgres DSN 和 Code Agent provider credentialCodex stdio profile 测试凭据必须来自 profile 专属 `auth.json``config.toml` 的 Kubernetes Secret projection。
- Codex Secret projection 必须先保持只读,再复制到 writable `CODEX_HOME` 后启动 app-server;综合联调不得把只读 Secret volume 直接当作 `CODEX_HOME` 的通过证据。
- 真实 `agentrun-mgr`、runner Job 或受控 runner process、真实 backend adapter。
- 至少一个真实 Code Agent provider turnCodex stdio backend 必须通过 `codex app-server --listen stdio://` 的 JSON-RPC stdio turn 完成,mock、fixture、source-only、dry-run、fake provider、直接 Responses HTTP 或 `codex exec` 一次性输出不能作为通过证据。如果 provider credential SecretRef 缺失,综合联调必须标记 blocked,不能降级为 mock pass。
- 若变更涉及 backend profile,综合联调必须分别覆盖 `backendProfile=codex``backendProfile=deepseek``backendProfile=minimax-m3`,并按 `codex -> deepseek -> minimax-m3 -> codex` 顺序证明 profile 切换不互相污染。
综合联调最小闭环:
1. Argo CD 已同步目标 GitOps revision`agentrun-v01` 长驻 workload ready。
2. `agentrun-mgr` health/readiness 返回 Postgres ready、migration ready 和 SecretRef redacted 状态。
3. 使用 manager API 创建带 `tenantId``projectId``workspaceRef``providerId``backendProfile``executionPolicy``traceSink` 的 run。
4. 通过真实 runner claim 该 run。
5. runner 使用真实 SecretRef 调用真实 backend provider,完成一个最短 turn。
6. manager 可查询 command state、append-only events、terminal_status 和 redacted logPath/job identity。
7. 重启 `agentrun-mgr` 后,run、command、events 和 terminal_status 仍可从 Postgres 查询。
8. 日志、event、CLI 输出和 health 中没有 provider credential、DSN password、token 或 URL credential 明文。
9. 若变更涉及 RuntimeAssembly,必须能追溯 `BackendImageRef``ProfileRef``SessionRef``ResourceBundleRef` 的装配状态;未提供 session/resource 时必须显式为 `null`,提供时必须能查到 session/thread 和 Git commit/tree/workspace 摘要,不能由 runner 隐式猜测。
### CLI 交互联调标准
CLI 交互联调验证正式操作入口是否能支撑人工使用和自动脚本串联。它必须只调用正式 AgentRun CLI 命令,不使用 debug 子命令、临时 `kubectl exec`、数据库直连或 mock backend 作为通过证据。故障定位可以另行采样日志,但通过条件必须来自 CLI 输出、manager API 和 Postgres durable facts。
CLI 交互联调必须满足:
- 使用 `./scripts/agentrun` 完成 create run、create command、start runner、show command 和 events polling;直接使用 `bun scripts/agentrun-cli.ts` 前必须证明当前 shell 的 PATH 能找到 Bun。
- 每个 CLI 调用默认输出 JSON,stdout 不为空,且 60 秒内返回;长时间模型 turn 必须通过后续 status/events 命令观察。
- 创建类命令必须返回 `runId``commandId`、status、job/process identity、logPath 和下一步 poll command;查询类命令必须返回当前 state、terminal_status、failureKind 和 event cursor。
- CLI 输出、日志摘要和错误信息必须保留可观测性,不能只返回成功/失败布尔值;错误必须能区分 missing SecretRef、provider auth failure、runner lease conflict、backend failure 和 infra failure。
- CLI 不得输出 provider credential、Postgres DSN password、token、URL credential 或 Secret value;只能输出 redacted value 或 SecretRef。
- 重启或滚动 `agentrun-mgr` 后,CLI 仍能查询同一 run、command、events 和 terminal_status,证明结果来自 Postgres 而不是进程内存。
- 本地临时 manager 验收必须使用 `server start/status/stop` 生命周期命令管理进程。不得把长驻前台 `server start` 留给 SSH/tran 顶层超时清理;若需要前台模式,必须显式 `--foreground` 并在同一终端可控结束。
### RESTful API 交互联调标准
RESTful API 交互联调验证 `agentrun-mgr` 对外 HTTP JSON 合同,而不是 CLI wrapper。它必须直接访问真实 `agentrun-v01` runtime 中的 manager API,且使用同一个真实 runner、backend adapter 和 provider credential 完成一个 run 生命周期。
RESTful API 交互联调必须满足:
- health/readiness 返回 manager、Postgres migration 和 SecretRef redacted 状态;缺少关键 SecretRef 时必须结构化返回 blocked 或 failed,不能降级为 mock pass。
- `POST /api/v1/runs` 接受并持久化 `tenantId``projectId``workspaceRef``providerId``backendProfile``executionPolicy``traceSink`
- `workspaceRef` 必须指向 runner 容器或受控 runner process 可访问的真实工作区;不存在的 path、只存在于 manager pod 的临时目录或未挂载的 host path 都不能作为综合联调通过证据。若因此导致 backend spawn 失败,应先按无效 workspace 前置条件归因,再排查 provider 或镜像依赖。
- `POST /api/v1/runs/:runId/commands` 创建 `turn` command 后立即返回 command id 和初始 state,不等待完整模型 turn。
- 真实 runner 通过 manager 私有 API claim run、poll commands、append events、ack command 并上报 statusAPI 联调不得绕过 manager 直接写数据库。
- `GET /api/v1/runs/:runId/commands/:commandId``GET /api/v1/runs/:runId/events?afterSeq=N&limit=M` 能轮询到 terminal_statusevent `seq` 单调递增,分页重复读取不丢失也不重复。
- 所有成功和失败响应都必须是 JSON;失败响应必须包含可判定的 failureKind、message 和 trace correlation,且不得泄露 Secret value。
真实 provider 返回 HTTP 5xx/503、`Service Unavailable`、携带 5xx 的 `responseStreamDisconnected` 或明确 temporary/provider unavailable 文案时,综合联调结论应归类为外部 provider availability blockerfailureKind 使用 `provider-unavailable`。这类结果不能证明真实 turn 成功,但也不得被记录为本地 runner/backend 执行面 `backend-failed` blocker。
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_statuspayload 有界且 redacted。 |
| cancel | 对 pending/running/terminal 分别调用 cancel | cancel 幂等,pending 不再启动 runnerrunning 收敛为 cancelled 或既有 terminalevents/result 可见。 |
| SessionRef | 连续两轮使用同一 sessionRef 或 conversation/session/thread 摘要 | 第二轮可 resume backend threadsession 不包含 credential 文件或完整 CODEX_HOME。 |
| ResourceBundleRef | 使用 `repoUrl + full commitId` 启动 runner | runner checkout 到允许 workspaceevent/result 能回答 repo、commit、workspace 摘要;不使用 branch/tag/HEAD 或 host path。 |
| ProfileRef/SecretRef | 分别验证 `codex``deepseek``minimax-m3` 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` 发布通过必须同时满足:
- 相关组件自测试通过。
- Tekton/Argo CI/CD 链路通过,source branch 不含自动构造物。
- 综合联调通过。
以下结果不能单独作为发布通过证据:
- mock backend run 成功。
- 本地临时 Postgres 或 sqlite 测试成功。
- GitOps branch 已推送但 Argo 未同步。
- Argo Synced 但没有真实 run terminal_status。
- provider credential 缺失时的跳过结果。
- 只读 health 成功但没有完成真实 Code Agent turn。
## 测试规格
### T1 自测试归类
阅读本文,然后检查每个组件 spec 的“测试规格”是否明确属于自测试,且 mock/fake/fixture 只出现在自测试层。
### T2 综合联调真实性
阅读本文,然后执行一次综合联调,确认所有关键依赖均为真实 `agentrun-v01` runtime、Postgres、SecretRef、runner、backend 和 provider credentialCodex stdio profile 测试凭据必须通过 Kubernetes Secret projection 注入当前 profile 的 `auth.json``config.toml`。任何缺失必须返回 blocked 或 failed。
### T3 发布判定
阅读本文和 [spec-v01-cicd.md](spec-v01-cicd.md),确认发布结论同时引用自测试、Tekton/Argo 和综合联调证据;不得用 mock pass 替代综合联调。
### T4 CLI 交互联调
阅读 `AGENTS.md`、本文和 [spec-v01-cli.md](spec-v01-cli.md),然后用 `./scripts/agentrun` 手动测试以下内容:在真实 `agentrun-v01` 运行面创建 run,提交一个 `turn` command,启动或触发真实 runner,并轮询 command status 与 run events 直到出现 terminal_status。确认每个步骤只使用正式 CLI 命令,不使用 debug 子命令或 mock/fake backend;每次调用 60 秒内返回非空 JSON,包含 runId、commandId、status、job/process identity、logPath 或下一步 poll command;日志、event 和 CLI 输出不得出现 provider credential、DSN password、token 或 URL credential 明文。最后重启或滚动 `agentrun-mgr`,再用 CLI 查询同一个 run,确认 command state、events 和 terminal_status 仍可见。
### T5 RESTful API 交互联调
阅读 `AGENTS.md`、本文和 [spec-v01-services.md](spec-v01-services.md),然后用 RESTful API 手动测试以下内容:直接调用真实 `agentrun-mgr` HTTP JSON API,先检查 health/readiness,再调用 `POST /api/v1/runs` 创建带 tenant/project/workspace/provider/backend/execution/trace 字段的 run,其中 `workspaceRef` 必须是真实 runner 可访问路径;调用 `POST /api/v1/runs/:runId/commands` 提交 `turn` command,使用真实 runner 完成 provider turn,并轮询 `GET /api/v1/runs/:runId/commands/:commandId``GET /api/v1/runs/:runId/events?afterSeq=N&limit=M` 直到 terminal_status。确认所有响应为 JSONevent seq 单调且分页无重复,缺少 provider SecretRef 时返回 blocked 或 failed 的结构化 failureKind,任何响应、event、trace 和日志都不得泄露 Secret value。
### T6 CLI 与 RESTful 观察一致性
阅读本文、[spec-v01-cli.md](spec-v01-cli.md) 和 [spec-v01-services.md](spec-v01-services.md),然后对同一个真实 run 分别用 CLI 和 RESTful API 查询 run、command、events 和 terminal_status。确认 CLI 只是正式 API 的受控操作入口,不维护一套独立状态;两种交互面看到的 run id、command id、state、terminal_status、failureKind、event seq 和 redaction 结果必须一致。
### T7 手动负向交互验收
阅读本文和各组件 spec,然后在真实 `agentrun-v01` 运行面用正式 CLI 或 RESTful API 手动验证以下负向场景。该项是人工验收标准,不是自动化脚本、CI 门禁或固定 gate:
- 使用非法 `tenantId`、非法 `backendProfile` 或缺失必填 run 字段创建 run,确认返回 JSON,包含 `failureKind``message`
- 对同一 run 使用相同 idempotency key 提交相同 command 两次,再用相同 key 提交不同 payload,确认前两次返回同一个 command,第三次结构化失败。
- 对同一 pending run 启动两个真实 runner 或重复 claim,确认只有一个 owner 成功,失败方为 `runner-lease-conflict` 或等价 failureKind,且不继续调用 backend。
- 用不存在的 provider SecretRef 创建 run 并启动 runner,确认失败为 `secret-unavailable`,不会降级为 mock pass,也不会打印 Secret value。
-`backendProfile=deepseek``backendProfile=minimax-m3` 但只提供 `codex` SecretRef 的 run 启动 runner,确认失败为 `secret-unavailable`,不会 fallback 到 `codex`
- 对同一 run 分页读取 events,确认 `seq` 单调、`afterSeq` 翻页无重复、重复读取同一页不会改变 durable facts。
T7 只定义人工验收的检查面和判定口径。若后续为减少人工操作引入 helper 命令,它只能输出手动步骤、当前证据或 dry-run 计划,不能把这些负向场景改造成阻断发布的自动门禁。
### T8 Backend profile 真实切换验收
阅读本文、[spec-v01-services.md](spec-v01-services.md)、[spec-v01-backend-codex.md](spec-v01-backend-codex.md) 和 [spec-v01-secret-distribution.md](spec-v01-secret-distribution.md),然后在真实 `agentrun-v01` 运行面用正式 CLI 和 RESTful API 手动验证以下内容:
- `GET /api/v1/backends``./scripts/agentrun backends list` 同时列出 `codex``deepseek``minimax-m3`,并显示三者共享 `backendKind=codex-app-server-stdio``protocol=codex-app-server-jsonrpc-stdio``transport=stdio`
-`backendProfile=codex` 完成一个真实 app-server stdio turn,记录 runId、commandId、terminal_status 和 redacted backend_status。
-`backendProfile=deepseek` 完成一个真实 app-server stdio turn,确认 SecretRef 为 `agentrun-v01-provider-deepseek`runtime `CODEX_HOME``codex` run 隔离,assistant 回复非空或失败被正确归类为 provider blocker。
-`backendProfile=minimax-m3` 完成一个真实 app-server stdio turn,确认 SecretRef 为 `agentrun-v01-provider-minimax-m3`runtime `CODEX_HOME``codex`/`deepseek` run 隔离,assistant 回复非空或失败被正确归类为 provider blocker。
- 再次用 `backendProfile=codex` 完成真实 turn,确认没有继承 DeepSeek 或 MiniMax-M3 model/base URL/config。
- 删除或替换 `deepseek`/`minimax-m3` SecretRef 后复测,必须 `secret-unavailable`,不能使用 `codex` SecretRef 或默认 Codex config。
T8 是涉及 backend profile 变更时的综合联调标准;不涉及 backend profile 的普通发布仍至少执行已有真实主闭环。
### T9 RuntimeAssembly 四要素验收
阅读本文和 [spec-v01-runtime-assembly.md](spec-v01-runtime-assembly.md),然后检查一次真实 runner Job 或 dry-run manifest,确认四个问题都有明确答案:用哪一个 digest-pinned image、用哪一个 profile/SecretRef、是否使用 session、使用哪一个 Git repo/full commit。P0 未启用 session 或 Git-only resource materialization 时,必须明确为 `null` 或 deferred,不能由 runner 隐式使用 host path。任何 Secret value、用户文件正文、env dump、branch/tag/HEAD 形式的 resource commit 都不能作为通过证据。
### T10 HWLAB 手动调度 canary 验收
阅读本文和 [spec-v01-hwlab-manual-dispatch.md](spec-v01-hwlab-manual-dispatch.md),然后在真实 `agentrun-v01` runtime 中模拟 HWLAB dispatcher:创建 `tenantId=hwlab` 的 run,提交 `turn` command,调用 `POST /api/v1/runs/:runId/runner-jobs`,轮询 command、events 和 result 到 terminal。确认 API 全部短返回 JSONrunner Job identity 可见,events/result 能转换为 HWLAB result/trace,并验证 runner job idempotency、cancel、SessionRef 和 ResourceBundleRef 的真实路径;不能用 mock pass 替代真实 canary。
### T11 Queue 吸收 Code Queue 手动验收
阅读本文和 [spec-v01-queue.md](spec-v01-queue.md),然后在真实 `agentrun-v01` runtime 中用正式 CLI 手动验证 Queue 首版闭环:创建 Queue task,轮询 `queue list/show/stats/commander/read`,用 `queue dispatch` 触发真实 Codex/Codex-compatible attempt 到 terminal,再用 `queue refresh` 从 Core run/command 终态回写 Queue task/latestAttempt。确认 `queue show` 返回 `sessionPath`,输出和 trace 只通过 Session API/CLI 查询。该验收不得使用 mock,不写自动交互脚本,不做 Web/Playwright。确认 Queue overview、stats、read 和 commander 均来自 Queue summary/stats/read 模型,不从 Core trace 或 Session trace 反推;确认不存在首版 OA/Event/OA sink/integrations/notification/GitHub sink 依赖;确认旧 MiniMax/OpenCode 直连路线不作为 Queue 首版能力,MiniMax-M3 只能通过 Codex-compatible `minimax-m3` profile 使用;确认旧 UniDesk Code Queue 不接收新任务且历史数据不迁移到 AgentRun。若使用 `host-path` workspace,必须先证明该路径在 runner 运行面可访问且不会破坏 backend command resolution;否则应使用 `opaque` 或 Git-only ResourceBundleRef 做 Queue dispatch 最小验收。
## 规格的实现情况
| 规格项 | 状态 | 说明 |
| --- | --- | --- |
| 两层验证模型 | 已定义 | 本文为 v0.1 验证权威。 |
| 自测试 task | 已实现 | `src/selftest/run.ts` 自动发现 `src/selftest/cases/*.ts`;覆盖 redaction/Postgres contract、manager memory、runner Job render/create、Codex fake app-server stdio 和 Secret render。 |
| HWLAB 基线承接自测试 | 已实现 | `src/selftest/cases/60-hwlab-baseline-contract.ts` 固化 event/result/failureKind/bounded output/runner job status/session/profile/bundle/preflight 的组件合同;综合联调仍必须走正式 AgentRun CLI 且不能使用 mock。 |
| 综合联调验收规格 | 已增强 | 本文保留人工交互验收模型;T4-T8 定义 CLI、RESTful、一致性、负向场景和 backend profile 切换的手动验收标准,不新增自动脚本或门禁。 |
| CLI 交互联调标准 | 已定义 | 必须只使用正式 CLI,验证真实 run 生命周期和可观测输出。 |
| RESTful API 交互联调标准 | 已定义 | 必须直连真实 manager HTTP JSON API,验证服务合同和 durable facts。 |
| 真实主闭环 | 已通过 | 当前 v0.1 已通过真实 Tekton/Argo、Postgres、SecretRef、Kubernetes runner Job、Codex stdio turn、RESTful API 和 CLI 主闭环;每次发布仍需按本文手动复验。 |
| `deepseek` profile 切换验收 | 已通过主闭环 | 自测试和 CLI smoke 已覆盖 profile registry、Secret render、fake stdio turn、无 fallback 和结构化错误;真实 `agentrun-v01` 已按 T8 完成 `codex -> deepseek -> codex` 切换综合联调。后续涉及 backend profile 的发布仍必须按 T8 复验。 |
| `minimax-m3` profile 切换验收 | 已定义/待真实主闭环 | 自测试和 CLI smoke 覆盖 profile registry、Secret render、fake stdio turn、无 fallback 和结构化错误;真实 `agentrun-v01` 需要按 T8 完成 `codex -> deepseek -> minimax-m3 -> codex` 切换综合联调。 |
| RuntimeAssembly 四要素验收 | 已定义 | T9 收敛为四个最简问题:image digest、profile/SecretRef、session null/deferred、Git-only repo/full commitsession/resource materialization 后续实现时必须补真实联调。 |
| HWLAB 手动调度 canary 验收 | 已定义 | T10 规定 HWLAB dispatcher 通过手动 runner Job API 使用 AgentRun 的真实联调口径;自动 scheduler 不是前置条件。 |
| Queue 吸收 Code Queue 验收 | 已定义 | T11 规定 Queue RESTful/CLI/Session 分层的真实手动交互验收;mock 只允许在自测试层。 |
| Queue Q2 受控 dispatch/refresh 主闭环 | 已通过 | 已在真实 `agentrun-v01` Postgres 与 G14 k3s runner Job 上完成正式 CLI 手动验收;通过样本使用 `opaque` workspace 完成 Codex stdio turn`queue refresh` 后 Queue task/latestAttempt 为 completed。 |
| mock 作为发布证据 | 不采用 | mock 只能证明自测试通过。 |