docs(agentrun): 收口重试与资源包可靠性

This commit is contained in:
Codex
2026-07-12 03:20:03 +02:00
parent b717f4e204
commit 2d4c397259
12 changed files with 157 additions and 18 deletions
+6 -2
View File
@@ -1,11 +1,11 @@
---
name: unidesk-code-queue
description: UniDesk AgentRun-backed Code Queue CLI — Skill(cli-spec)。legacy `codex` 子命令只保留历史只读和残留停止;新任务提交、Aipod/Artificer 派单、session follow-up、events/logs/result、ack/cancel、dispatch、run/command/runner 状态 drill-down 和 HWLAB Code Agent/CaseRun follow-up 必须使用 `agentrun get|describe|events|logs|result|ack|cancel|dispatch|create|apply|send` 资源原语。用户提到 codex、Code Queue、submit、send、resume、tasks、unread、code-queue、aipod、Artificer、HWLAB Code Agent 时使用。
description: UniDesk AgentRun-backed Code Queue CLI — Skill(cli-spec)。legacy `codex` 子命令只保留历史只读和残留停止;新任务提交、Aipod/Artificer 派单、session follow-up、events/logs/result、attempts/retry、ack/cancel、dispatch、run/command/runner 状态 drill-down 和 HWLAB Code Agent/CaseRun follow-up 必须使用 `agentrun get|describe|events|logs|result|retry|ack|cancel|dispatch|create|apply|send` 资源原语。用户提到 codex、Code Queue、submit、send、resume、retry、tasks、unread、code-queue、aipod、Artificer、HWLAB Code Agent 时使用。
---
# UniDesk Code Queue / AgentRun CLI
新任务、Aipod/Artificer 派单、session follow-up、events/logs/result、ack/cancel、dispatch 和 run/command/runner drill-down 走 AgentRun 资源原语。legacy `codex` 只保留历史只读、未读积压和残留任务停止。
新任务、Aipod/Artificer 派单、session follow-up、events/logs/result、attempts/retry、ack/cancel、dispatch 和 run/command/runner drill-down 走 AgentRun 资源原语。legacy `codex` 只保留历史只读、未读积压和残留任务停止。
## 高频入口
@@ -15,6 +15,8 @@ bun scripts/cli.ts agentrun describe task <task>
bun scripts/cli.ts agentrun events <task> --limit 80
bun scripts/cli.ts agentrun logs <task> --tail 120
bun scripts/cli.ts agentrun result <task>
bun scripts/cli.ts agentrun get attempts --task <taskId>
bun scripts/cli.ts agentrun retry task/<taskId> --idempotency-key <key> --reason <text> --dry-run
bun scripts/cli.ts agentrun send <session> --prompt-stdin
```
@@ -27,6 +29,8 @@ AipodSpec/Artificer、task manifest 和 queue 渐进披露见 [references/resour
- 新写入口不要用 `codex submit/steer/resume`;这些 legacy mutation 已冻结。
- 默认输出保持低噪声表格/摘要;机器消费显式 `-o json|yaml``--raw`
- Session follow-up 使用 `agentrun send`,由服务端决定内部 steer vs turn。
- 终态失败重试只使用 `agentrun retry task/<taskId>`:保持同一 task,新增不可变 attempt;先用 `--dry-run` 完成服务端全校验,再以同一幂等键执行真实重试。
- retry 只接受 Queue 已处于 `failed``blocked``completed``cancelled` 和其他状态必须 fail closed。不得复制 task、重置 task、引入本地 scheduler/backoff/judge 或直接创建 runner Job 来模拟重试。
- HWLAB Code Agent/CaseRun follow-up 也优先落到 AgentRun resource primitive,不绕过队列状态。
## 何时读取 reference
@@ -1,10 +1,21 @@
# AgentRun Resources
# AgentRun 资源原语
New Code Queue work uses AgentRun resource primitives:
Code Queue 工作统一使用 AgentRun 资源原语:
- `agentrun create|apply` for task/AipodSpec manifests.
- `agentrun get|describe` for bounded list/detail reads.
- `agentrun events|logs|result` for progressive disclosure.
- `agentrun dispatch|ack|cancel` for lifecycle control.
- `agentrun create|apply`:创建 task 或应用 AipodSpec manifest
- `agentrun get|describe`:有界读取列表和详情;
- `agentrun events|logs|result`:渐进披露运行证据;
- `agentrun get attempts --task <taskId>`:读取同一 task 的不可变 attempt 历史;
- `agentrun retry task/<taskId> --idempotency-key <key> --reason <text> [--dry-run]`:对终态失败 task 创建下一次 attempt
- `agentrun dispatch|ack|cancel`:控制生命周期。
Do not add new mutation paths under legacy `codex`.
retry 必须遵守以下边界:
- task identity 不变,每次执行使用新的 attempt、run、command 和 runner Job identity
- 同一幂等键返回同一 retry 结果,不重复创建 attempt
- 只允许 Queue 已处于 `failed``blocked`,其他终态与非终态 fail closed
- `--dry-run` 由服务端完成与真实 retry 相同的校验,但零写入;
- retry 不主动刷新 Core 终态。若 Queue 摘要仍是非终态,先通过正式 `get task``get attempts` 刷新权威状态,再重试;
- 禁止复制或重置 task,禁止在 UniDesk 增加 scheduler、backoff、judge、projector 或直接 runner 编排。
不要在 legacy `codex` 下增加新的 mutation 路径。
+8 -8
View File
@@ -5,16 +5,16 @@
范围:长期跟踪 AgentRun admission、dispatch、runner、resource bundle、provider 建立、终态失败可见性与自动交付可靠性。单次故障作为 MDTODO ITEM 纳入,不为每个 issue 新建文件。
## R1 [in_progress]
## R1 [completed]
依据 [AgentRun #294](https://github.com/pikasTech/agentrun/issues/294) 恢复 Artificer resource-bundle Git 获取与失败可见性,完成任务后将详细报告写入[任务报告](./details/agentrun-resource-bundle-git-fetch/R1_Task_Report.md)。
### R1.1
### R1.1 [completed]
用固定四个 run 单步披露 bundle source、fetch 阶段、脱敏 remote/credential sourceRef 与首个失败分类,完成任务后将详细报告写入[任务报告](./details/agentrun-resource-bundle-git-fetch/R1.1_Task_Report.md)。
### R1.2
### R1.2 [completed]
在 YAML/sourceRef 或 AgentRun runner/resource-bundle 权威路径修复 code 128,并统一 task terminal failure 摘要,完成任务后将详细报告写入[任务报告](./details/agentrun-resource-bundle-git-fetch/R1.2_Task_Report.md)。
### R1.3
### R1.3 [completed]
通过 PR 合并自动 CI/CD 后重派同类 Artificer 任务,验收 bundle materialized、provider established 和业务执行开始,完成任务后将详细报告写入[任务报告](./details/agentrun-resource-bundle-git-fetch/R1.3_Task_Report.md)。
@@ -38,18 +38,18 @@
登记 [UniDesk #1801](https://github.com/pikasTech/unidesk/issues/1801)diagnose 的 command/result 读取会向同一业务 trace 补记 command_result span,使重复读取改变 instrumentation completeness;该问题涉及 trace context 与诊断证据隔离,本轮按架构变更边界跳过,完成任务后将详细报告写入[任务报告](./details/agentrun-runtime-reliability/R2.4_Task_Report.md)。
## R3 [in_progress]
## R3 [completed]
依据 [AgentRun #307](https://github.com/pikasTech/agentrun/issues/307) 实现 Queue Q5 的同 task 不可变 attempt 历史与显式终态失败 retry,禁止通过重置 task 或复制 task 合同绕过资源语义,完成任务后将详细报告写入[任务报告](./details/agentrun-runtime-reliability/R3_Task_Report.md)。
### R3.1
### R3.1 [completed]
在 AgentRun 增加正式 `agentrun_queue_attempts` 存储、现有 latestAttempt 回填和不可变历史查询;task.latestAttempt 只保留为摘要指针,完成任务后将详细报告写入[任务报告](./details/agentrun-runtime-reliability/R3.1_Task_Report.md)。
### R3.2
### R3.2 [completed]
实现服务端 `POST /api/v1/queue/tasks/:id/retry`:同 task 新 attempt、retry key 幂等、failed/blocked 白名单、completed/cancelled fail closed,并让 dry-run 全校验且零写入,完成任务后将详细报告写入[任务报告](./details/agentrun-runtime-reliability/R3.2_Task_Report.md)。
### R3.3
### R3.3 [completed]
在 UniDesk 受控 CLI 增加 task retry 资源入口,完成内存/PostgreSQL 并发测试、PR 自动交付和固定任务 `qt_5b65a086385a49bdb874cf8f9d191169` 的 bundle/provider/业务启动验收,完成任务后将详细报告写入[任务报告](./details/agentrun-runtime-reliability/R3.3_Task_Report.md)。
@@ -0,0 +1,14 @@
# R1.1 任务报告
## 固定证据
[AgentRun #294](https://github.com/pikasTech/agentrun/issues/294) 的四个独立 run 均在 `runner:resource-bundle` 阶段、provider 建立前以 Git code 128 失败:
- `run_ab6459bc3a474d57bc380acc99bd755b`
- `run_cb8888b29385495a844a6a4b19cf7f15`
- `run_d6cf26f8a9084150b5b70966194decd9`
- `run_928e88312d61464a80a01ad548244feb`
固定 runner Job `rjob_78f48c88d9454ab3a7130cf19f7de2e4` 的首个失败 bundle 是 `dad-dev-skill`,声明仓库为 `pikasTech/agent_skills`,有效 sourceRef 为 `master`。声明 remote fingerprint 为 `sha256:2653f2a25978ecc0`,实际 managed mirror fingerprint 为 `sha256:e3e738de93024780``mirrorUsed=true`。credentialRef 不存在是预期行为,因为 runner 只读集群 managed mirror;首个 stderr 分类为 `repository-not-found`,不是 timeout、TLS、DNS、proxy 或 GitHub token 错误。
源码与运行证据共同定位首个漂移:owning YAML 已声明仓库,但 shared repository renderer/controller 尚未把该依赖自动物化到 managed mirror;同时 task 顶层摘要没有投影 command/run 的 `infra-failed`,错误显示 `Failure: none`
@@ -0,0 +1,13 @@
# R1.2 任务报告
## AgentRun 失败可见性
[AgentRun PR #295](https://github.com/pikasTech/agentrun/pull/295) 已合并,merge commit 为 `4805e02441f576ca19fae22a5815c7385f9ba110`。resource-bundle Git fetch 首错现在结构化披露 bundle、sourceRef、credential presence、脱敏 remote fingerprint、mirror 使用情况和 stderr 分类,不回显 URL、credential 或完整 stdout/stderr。terminal Queue task 从 supervisor 权威投影顶层 `failureKind` 和有界 `failureMessage`,不再显示 `Failure: none`
## Managed mirror 根因
UniDesk [PR #1806](https://github.com/pikasTech/unidesk/pull/1806) 由 `config/agentrun.yaml#...gitMirror.repositories` 唯一渲染通用 managed repository controllermerge commit 为 `d3eb1650`。controller 不包含 `agent_skills` 特例,不增加第二仓库列表或 runner GitHub fallback。
随后 [PR #1814](https://github.com/pikasTech/unidesk/pull/1814) 修复 controller 的 credential authoritymerge commit 为 `eb8e531c26c12f3f1ccb31c2aa1875d7effdd2c7`:通过 Gitea owning YAML capability 与 AgentRun `configRef` 投影单一 credential keytoken 不进入 URL、argv、env、ConfigMap、日志、status 或 repository config;缺 Secret/key 时 fail closed。两个 PR 都只通过正常 merge 自动交付,没有人工 mirror、cache、sync、flush、PipelineRun 或运行面 patch。
修复后固定 task 的下一 attempt 成功出现 `resource-bundle-materialized; tools=4; bundles=6; promptRefs=0`,证明 `pikasTech/agent_skills@master` 已由正式 managed mirror 路径物化,原 code 128 根因已消失。
@@ -0,0 +1,13 @@
# R1.3 任务报告
固定失败 task `qt_5b65a086385a49bdb874cf8f9d191169` 在自动交付完成后,通过正式 Queue retry 原语保持同一 task identity 重新执行,没有新建替代 task,也没有直接启动 runner。
新 attempt `qa_b22c668cb5434cb0a7cea2693916bcb0` 对应 run `run_d7f1cbb11ab04a75ad435ee462c2e60d`、command `cmd_34c61a8758c640bdabba5206994dbee4` 和 runner Job `rjob_deb5ec4b61f14d86a6b210951b7f8c10`。事件证明:
- `runner-job-created`
- `resource-bundle-materialized; tools=4; bundles=6; promptRefs=0`
- `backend-turn-started`
- provider initialize 完成;
- thread 与 turn 已开始。
这同时验收了 bundle materialized、provider established 和业务执行开始。达到目标后通过正式 cancel 停止已过时业务;旧失败 attempt 保持不可变,新 attempt/run/command 的取消事实均可查询。
@@ -0,0 +1,5 @@
# R1 任务报告
Artificer resource-bundle 故障已沿唯一权威链路收口:只读 drill-down 定位为 YAML desired 到 managed repository controller 的首个漂移;AgentRun 补全首错和 terminal failure 可见性;UniDesk 由 owning YAML 自动渲染 repository controller,并通过 owning credential capability 修复导入认证。未增加 runner GitHub fallback、第二仓库列表或人工 mirror 操作。
PR merge 自动交付后,原固定失败 task 通过正式同 task retry 成功完成 resource bundle 物化、provider 初始化并进入业务 turn。详细证据见 R1.1、R1.2、R1.3,以及 [AgentRun #294](https://github.com/pikasTech/agentrun/issues/294)。
@@ -0,0 +1,16 @@
# R3.1 任务报告
## 结果
[AgentRun #307](https://github.com/pikasTech/agentrun/issues/307) 已由 [PR #308](https://github.com/pikasTech/agentrun/pull/308) 实现并合并到 `v0.2`merge commit 为 `9ec8e24c82fbef350f93e7a6e4e7ec4d3fd5437a`
- 新增正式 `agentrun_queue_attempts` 表和 migration `014_v02_queue_attempt_history_retry`
- 从既有 `latest_attempt` 回填历史,task 上的 `latestAttempt` 只保留为摘要指针;
- attempt 与 task、retry key、retry index 之间建立唯一约束;
- 同一 task 最多只有一个 `reserved``running` attempt
- 初次 dispatch 和后续 retry 都进入同一不可变历史;
- `GET /api/v1/queue/tasks/:id/attempts` 读取历史,并从既有 Core 权威刷新执行状态,不新增 projector。
## 验证
定向自测覆盖内存存储、PostgreSQL migration/回填合同、并发唯一性、初次 dispatch 和历史查询。完整 selftest 在补齐仓库声明的 runner runtime 测试配置后退出码为 0;未配置 `AGENTRUN_SELFTEST_DATABASE_URL`,因此本轮没有执行真实 PostgreSQL 集成实例测试,相关数据库合同完成了 migration、fixture 和独立静态审查。
@@ -0,0 +1,18 @@
# R3.2 任务报告
## 结果
[AgentRun PR #308](https://github.com/pikasTech/agentrun/pull/308) 已增加正式 `POST /api/v1/queue/tasks/:id/retry`
- retry 保持原 task identity、payload、session 和资源合同不变;
- 每次真实 retry 分配新的 attempt、run、command 和 runner Job identity
- 同一 retry idempotency key 在状态检查前解析,重复请求返回同一结果;
- 只接受 Queue 已处于 `failed``blocked``completed``cancelled` 及其他状态 fail closed
- `--dry-run` 执行与真实请求相同的服务端校验,但不修改 task/version,也不创建 attempt、run、command 或 runner Job
- runner Job 创建失败会落到预留 attempt,允许使用同一 key 恢复;
- public dispatch 拒绝调用方注入 `runnerJobId`,只有服务端 retry 内部可以使用预留 identity
- terminal run 上同 key、同 payload 的 command 重放返回原 command,不重复 event 或 Kafka outbox。
## 验证
case `00/21/22/35/78` 共 75 个命名测试通过;独立审查结论为 APPROVE。残余边界是 retry 不会主动刷新 Core:若 Queue 摘要尚未进入 `failed/blocked`,先通过正式 task/attempt 读取刷新权威状态,这一行为已写入长期参考,未引入隐式写入或第二状态投影。
@@ -0,0 +1,23 @@
# R3.3 任务报告
## CLI 与自动交付
UniDesk [PR #1816](https://github.com/pikasTech/unidesk/pull/1816) 已合并,merge commit 为 `b717f4e20411dafa3d1d57249ebfaa934f3475e8`,提供:
- `agentrun get attempts --task <taskId>`
- `agentrun retry task/<taskId> --idempotency-key <key> --reason <text> [--dry-run]`
AgentRun PR #308 合并后自动 PipelineRun `agentrun-nc01-v02-ci-9ec8e24c82fbef350f93e7a6e4e7ec4d3fd542xv6q` 成功,GitOps revision `f285f6d70679`Argo `Synced/Healthy/exact`runtime `1/1 ready`。UniDesk PR #1816 合并后自动 PipelineRun `unidesk-host-98h7v` 成功,GitOps revision `f40504e3b855`Argo `Synced/Healthy/exact`runtime `1/1 ready`。全程没有人工 mirror、PipelineRun、sync、flush、trigger、apply 或 closeout。
## 固定任务验收
固定 task `qt_5b65a086385a49bdb874cf8f9d191169` 使用 key `q5-accept-307-20260712-v1` 完成服务端 dry-run,确认 `mutation=false`、计划 `retryIndex=1` 且历史仍只有原 attempt。
真实 retry 保持同一 task,创建:
- attempt`qa_b22c668cb5434cb0a7cea2693916bcb0`
- run`run_d7f1cbb11ab04a75ad435ee462c2e60d`
- command`cmd_34c61a8758c640bdabba5206994dbee4`
- runner Job`rjob_deb5ec4b61f14d86a6b210951b7f8c10`
事件依次证明 `runner-job-created``queue-retried``resource-bundle-materialized; tools=4; bundles=6; promptRefs=0``backend-turn-started`、provider initialize 完成、thread/turn started。原失败 attempt 保持不变。达到验收目标后使用正式 cancel 终止过时业务,task、最新 attempt、run 和 command 均进入 cancelled,旧 attempt 仍可查询。
@@ -0,0 +1,7 @@
# R3 任务报告
Queue Q5 已完成:AgentRun 以同一 task 的不可变 attempt 历史实现显式终态 retryUniDesk 仅提供 render-only 受控 CLI。服务端幂等、状态白名单、零写 dry-run、失败可见性和 command/event/outbox 不重复合同均已测试;两个仓库的 PR merge 均只走自动 CI/CD。
固定失败 task 的 dry-run、真实 retry 和正式 cancel 证明:旧 attempt 未被覆盖,新 attempt 使用稳定的新执行 identityresource bundle、provider 和业务 turn 均已实际启动。实现没有复制或重置 task,也没有增加 scheduler、backoff、judge、projector 或人工运行面补偿。
详细证据见 R3.1、R3.2 和 R3.3 报告,以及 [AgentRun #307](https://github.com/pikasTech/agentrun/issues/307)。
+16 -1
View File
@@ -208,7 +208,22 @@ AgentRun 的产品边界、REST resource/API 语义、run/command/event/session/
AgentRun 指挥官任务面已经按 AgentRun issue #105 完成真实运行面验收,可作为新任务派发、commander queue 观察、events/logs/result、steer/send、ack 和 cancel 的 AgentRun 侧标准路径。长期能力规格以 UniDesk OA 的 [队列会话](../../project-management/PJ2026-01/specs/PJ2026-010203-queue-session.md) 和 [AgentRun核心](../../project-management/PJ2026-01/specs/PJ2026-010201-agentrun-core.md) 为准;UniDesk 只记录该路径以 NC01 `agentrun-v02` 运行面和 YAML profile 为准。
UniDesk 指挥官新任务入口固定使用 `bun scripts/cli.ts agentrun get|describe|events|logs|result|ack|cancel|dispatch|create|apply|steer|send` 资源原语。该入口是 render-only clientUniDesk 客户端保留 k8s 风格命令解析、human 表格、生命周期摘要、下一步命令、分页、`-o json|yaml` 稳定客户端 schema 和错误展示;AgentRun 服务端只提供稳定 RESTful API、鉴权和业务事实,不承载 UniDesk CLI 渲染。日常派单优先用 `agentrun create task --aipod Artificer --prompt-stdin``agentrun apply -f -` 的 quoted YAML/JSON heredoc/stdin 形式;已创建未运行任务用 `agentrun dispatch task/<taskId>` 派发;`--json-file``--prompt-file``--runner-json-file` 只是客户端输入来源,用于已审阅且可复用的受控文件。UniDesk 不实现 AgentRun queue 协议,也不把任务 double-write 回旧 Code Queue。
UniDesk 指挥官新任务入口固定使用 `bun scripts/cli.ts agentrun get|describe|events|logs|result|retry|ack|cancel|dispatch|create|apply|steer|send` 资源原语。该入口是 render-only clientUniDesk 客户端保留 k8s 风格命令解析、human 表格、生命周期摘要、下一步命令、分页、`-o json|yaml` 稳定客户端 schema 和错误展示;AgentRun 服务端只提供稳定 RESTful API、鉴权和业务事实,不承载 UniDesk CLI 渲染。日常派单优先用 `agentrun create task --aipod Artificer --prompt-stdin``agentrun apply -f -` 的 quoted YAML/JSON heredoc/stdin 形式;已创建未运行任务用 `agentrun dispatch task/<taskId>` 派发;`--json-file``--prompt-file``--runner-json-file` 只是客户端输入来源,用于已审阅且可复用的受控文件。UniDesk 不实现 AgentRun queue 协议,也不把任务 double-write 回旧 Code Queue。
Queue 终态失败重试使用正式资源入口:
```bash
bun scripts/cli.ts agentrun get attempts --task <taskId>
bun scripts/cli.ts agentrun retry task/<taskId> \
--idempotency-key <key> \
--reason <text> \
--dry-run
bun scripts/cli.ts agentrun retry task/<taskId> \
--idempotency-key <key> \
--reason <text>
```
retry 保持 task identity 不变,服务端为每次执行保留不可变 attempt 历史,并分配新的 run、command 和 runner Job identity。同一幂等键必须返回同一结果;`--dry-run` 必须执行服务端全校验且零写入。只有 Queue 已处于 `failed``blocked` 时允许 retry`completed``cancelled` 和其他状态 fail closed。retry 不主动刷新 Core 终态;若 Queue 摘要尚未进入可重试状态,先通过正式 task/attempt 读取刷新权威状态。禁止通过复制 task、重置 task、本地 scheduler/backoff/judge、projector 或直接 runner 编排模拟重试。
使用 lane-scoped AipodSpec 派单前,必须通过 `get/describe aipodspec`、render 输出或首个 runner job 摘要确认 `backendProfile`、provider credential SecretRef、tool credential SecretRef 和 bundle/workspaceRef 都存在于选中 lane 的 YAML 事实中。NC01/nc01-v02 的 Artificer 默认装配应从 lane YAML 绑定真实存在的 provider credential 和 tool credentialGitHub PR token 用 `tool=github``purpose=github-pr`、Secret key/projection env `GH_TOKEN`UniDesk 透传 token 用 `tool=unidesk-ssh``purpose=ssh-passthrough`、Secret key/projection env `UNIDESK_SSH_CLIENT_TOKEN``tool=github-ssh``sub2api` 或其他 legacy tool credential 只有在 YAML 明确声明完整 SecretRef、keys 和 projection 时才允许渲染。若 runner Pod 出现 `FailedMount`,且缺失对象是渲染出的 SecretRef,应归为 AipodSpec/YAML 绑定问题并修正受控配置;不得在 runtime namespace 手工创建 legacy Secret 或把其他 lane 的 Secret 复制过去。AipodSpec render 的默认输出也应是 bounded summary/table/drill-down;完整 render JSON 只在显式 `--full``--raw``-o json` 或机器消费路径展开,残余 dump 问题继续归 [#862](https://github.com/pikasTech/unidesk/issues/862) 跟踪。