docs: 固化 Queue 终态重试资源原语
Pipelines as Code CI / agentrun-nc01-v02-ci-0386058f5b50f471e2f9752a774d0f90b6b53cd3 Success
Pipelines as Code CI / agentrun-nc01-v02-ci-0386058f5b50f471e2f9752a774d0f90b6b53cd3 Success
This commit is contained in:
@@ -137,9 +137,11 @@ CLI 官方 TypeScript 入口固定为 `scripts/agentrun-cli.ts`。在 G14 非交
|
||||
- `tool-credentials list|show` 调用 manager REST 读取固定 tool credential 状态,只显示 SecretRef、key presence 和 hash 后缀;不得输出 Secret data。
|
||||
- `tool-credentials set-github-ssh` 是 GitHub SSH runtime Secret 的受控 bootstrap 入口;输入只能来自本地文件,CLI/manager response 只能显示 bytes、hash suffix、SecretRef 和 `valuesPrinted=false`,不得输出 private key、known_hosts 或 ssh config 内容。
|
||||
- `backends list` 必须显示 `codex`、`deepseek`、`minimax-m3` 与 `dsflash-go` profile 的 backendKind、protocol、transport、command、requiredSecretKeys 和状态;`dsflash-go` 的 `requiredSecretKeys` 必须包含 `model-catalog.json`;已配置的动态 provider profile(例如 `hy`)必须同样可见,并带动态 discovery 状态;不得因为某个 provider Secret 尚未配置就隐藏 capability。
|
||||
- `queue submit/read/cancel/dispatch/refresh --dry-run` 必须只返回 non-mutating plan,固定 `dryRun=true`、`mutation=false`,不得创建 task、mark read、cancel、dispatch、refresh 或启动 runner job。
|
||||
- `queue submit/read/cancel/dispatch/refresh/retry --dry-run` 必须只返回 non-mutating plan,固定 `dryRun=true`、`mutation=false`,不得创建 task、mark read、cancel、dispatch、refresh、attempt、run、command 或 runner job。
|
||||
- `queue dispatch` 是 Q2 的受控手动调度入口,只对单个 task 显式创建 attempt 和 Core run/command/runner job;不得伪装成自动 scheduler;带 `--dry-run` 时只读取 task 并展示将要 POST 的路径和有界 request 摘要。
|
||||
- `queue refresh` 只根据 Queue task 中保存的 Core run/command 引用回写 Queue attempt 状态,不读取 Core trace 反推 commander 或统计;带 `--dry-run` 时不得写回状态。
|
||||
- `queue attempts <taskId>` 必须通过 manager REST 分页读取正式 attempt 历史;默认只展示 identity、retry index、状态、Core 资源引用和有界失败可见性,完整记录只能显式 `--full|--raw`。
|
||||
- `queue retry <taskId> --idempotency-key <key> --reason <text>` 只调用正式 retry 资源原语;不得接受 task/dispatch patch,也不得在 CLI 本地创建 run、command 或 runner Job。相同 key 重放返回同一 attempt;`--dry-run` 做全校验、零写入。
|
||||
- `queue list/show/commander` 默认返回低噪声 summary,只显示 task/attempt/session ids、state、read cursor、stats 相关字段、compact supervisor 和 drill-down 命令;commander 的 supervisor 只能放 `phase`、last activity source seq/id、timeout budget 和恢复动作摘要,不得展开完整 payload、trace、tool command、stdout/stderr 或 runnerTrace。需要完整 task payload、resource bundle 或 metadata 时显式使用 `--full|--raw`;需要 trace/output 细节时继续按返回的 `sessionId`/`sourceSeq` 走 `sessions trace|output --seq/--event-id/--item-id --full`。
|
||||
- `queue show` 不得返回或代理完整 output/trace;输出和 trace 只能通过返回的 `sessionPath` 对应 `sessions ...` 命令查询。
|
||||
- 需要提交较长 Queue task、dispatch body、run base 或 command payload 时,CLI 必须把 `--json-stdin` 作为首选入口,避免为了 heredoc/stdin 内容先写临时 dump 文件再传 `--json-file`;`--json-file` 只用于可复用、已受控的输入文件。`queue submit/dispatch --dry-run` 的 `next.confirm` 不得默认推荐 `--json-file`,有 JSON body 时应提示 `--json-stdin`;只有用户显式维护可复用文件时才使用 file fallback。`sessions send` 的 runner job override 也必须支持 `--runner-json-stdin`。所有 stdin JSON 仍必须解析为 object,并在 dry-run 中只展示有界 body 摘要、bytes 和 keys。
|
||||
@@ -223,6 +225,7 @@ CLI 官方 TypeScript 入口固定为 `scripts/agentrun-cli.ts`。在 G14 非交
|
||||
| result/cancel CLI | 已实现 | `runs result`、`commands result`、`runs cancel` 和 `commands cancel` 均调用 manager REST,不维护独立状态。 |
|
||||
| Queue CLI | 已实现/Q1 | 已提供 `queue submit/list/show/stats/commander/read/cancel`,通过 manager REST 访问 Queue task 和 stats,不直连 Postgres。 |
|
||||
| Queue dispatch/refresh CLI | 已实现/Q2 | `queue dispatch` 受控创建 Core run/command/runner job;`queue refresh` 从 Core run/command 终态回写 Queue task/latestAttempt。 |
|
||||
| Queue retry/attempts CLI | 已实现/Q5 最小切片 | `queue retry` 提供显式幂等终态重试,`queue attempts` 查询正式历史;自动 scheduler、backoff 和 judge 不在该入口内实现。 |
|
||||
| 本地 server 生命周期 CLI | 已实现/Q2 hardening | `server start` 默认后台短返回,`server status/stop` 提供 pid、port、logPath 和 readiness 可见性;`--foreground` 保留给容器/显式调试。 |
|
||||
| stdio 事件部分重建 CLI | 已实现/debug | 按 `sessionId` 从 Kafka 或 JSONL 调用生产 reducer,默认写独立 debug topic/group,永久禁止写产品 topic,并显式披露不可恢复的 durable identity 与 lifecycle。 |
|
||||
| Session CLI | 已实现/Q3 | 已提供 `sessions ps/show/send/cancel/trace/output/read`;默认 ps 只显示 running/unread,terminal 后自动 unread,read cursor 由 CLI 标记。用户级 CLI 只保留 `send`;`turn/steer` 只作为 manager 内部 command type,不再作为 CLI 入口或兼容 alias。 |
|
||||
|
||||
@@ -38,7 +38,7 @@ Secret 名称和 key 可以在实现时按 Kubernetes 命名限制微调,但
|
||||
- `agentrun_sessions`:SessionRef 到 backend thread/cache identity、execution projection、active run/command、terminal/unread 水位的映射,不保存 credential 文件或 Secret 值。
|
||||
- `agentrun_session_read_cursors`:按 reader 记录 Session 已读 version,用于 CLI 默认只看 running/unread。
|
||||
- `agentrun_queue_tasks`:AgentRun Queue task identity、queue/lane、tenant/project、priority、state、backendProfile、workspace/resource 引用、可选 `sessionRef` 和 version;携带 `sessionRef` 的 task dispatch 后必须把 `sessionPath` 写回 Queue 记录。
|
||||
- `agentrun_queue_attempts`:task attempt identity、runId、commandId、runnerJobId、sessionId、state、failureKind、retry index 和 timestamps。
|
||||
- `agentrun_queue_attempts`:以 `(task_id, attempt_id)` 为主键,保存 retry index/key、previous attempt、runId、commandId、runnerJobId、sessionId、state、failureKind、failureMessage 和 timestamps;`latest_attempt` 只保留 task 最新摘要。
|
||||
- `agentrun_task_summaries` / `agentrun_attempt_summaries`:Queue 列表、详情和 commander 使用的轻量摘要;不能从 Core trace 反推 overview。
|
||||
- `agentrun_queue_stats`:按 queue/lane/state/backendProfile 聚合的统计水位。
|
||||
- `agentrun_queue_read_cursors`:按 user/agent/client 记录 Queue 已读水位。
|
||||
@@ -63,6 +63,7 @@ Secret 名称和 key 可以在实现时按 Kubernetes 命名限制微调,但
|
||||
- CI 可以校验 migration 顺序、checksum 和向前兼容,但不得把 live DB dump 写回 source。
|
||||
- 启动时 `agentrun-mgr` 可以执行幂等 migration 或在 migration 缺失时 fail fast;不得静默以空 schema 继续服务。
|
||||
- schema migration 记录必须写入 `agentrun_schema_migrations`。
|
||||
- `014_v02_queue_attempt_history_retry` 必须从既有 `agentrun_queue_tasks.latest_attempt` 回填首个正式 history row,并建立 `(task_id,idempotency_key)` retry identity、每 task 单一 `reserved/running` attempt 和 `(task_id,retry_index)` 唯一约束。
|
||||
|
||||
## 测试规格
|
||||
|
||||
@@ -78,13 +79,17 @@ Secret 名称和 key 可以在实现时按 Kubernetes 命名限制微调,但
|
||||
|
||||
阅读本文和 [spec-v01-services.md](spec-v01-services.md),然后创建 run、command、event 和 terminal status,重启 `agentrun-mgr` 后确认 facts 仍可通过 manager API 查询。
|
||||
|
||||
### T4 Queue retry 并发
|
||||
|
||||
使用隔离的真实 PostgreSQL,通过 `AGENTRUN_SELFTEST_DATABASE_URL=<dsn> bun run self-test:postgres-queue-retry` 启动两个 store 实例,验证同 retry key 并发只创建一个 reservation 和一组稳定 identity、不同 key 命中 active attempt fence、`dryRun` 不写 attempt 或 task version。该入口禁止回退到 memory store。
|
||||
|
||||
## 规格的实现情况
|
||||
|
||||
| 规格项 | 状态 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| Postgres durable store 规格 | 已定义 | 本文为 v0.1 存储权威。 |
|
||||
| StatefulSet/Service/PVC | 已实现/已通过主闭环 | `agentrun-v01-postgres` StatefulSet、Service 和 PVC 已由 GitOps runtime 提供,作为 `agentrun-v01` durable store。 |
|
||||
| migration ledger | 已实现/已通过主闭环 | `agentrun-mgr` 启动 Postgres adapter 时幂等创建 `agentrun_schema_migrations` 并记录 migration id/checksum;当前最新 migration 为 `006_v01_session_control`,用于在不改写既有 migration checksum 的前提下新增 session projection/read cursor;readiness 必须显示 migration ready。 |
|
||||
| manager Postgres adapter | 已实现/已通过主闭环 | `agentrun-mgr` 通过 `DATABASE_URL` 启用 Postgres adapter,持久化 runs、commands、events、runners、runner_jobs、sessions、session read cursors、backends、leases、Queue task 和 read cursor;缺少 `DATABASE_URL` 时 live runtime fail fast,memory 只允许显式 self-test/dev。 |
|
||||
| migration ledger | 已实现/已通过主闭环 | `agentrun-mgr` 启动 Postgres adapter 时幂等创建 `agentrun_schema_migrations` 并记录 migration id/checksum;当前最新 migration 为 `014_v02_queue_attempt_history_retry`,新增正式 attempt history、回填和终态重试并发约束;readiness 必须显示 migration ready。 |
|
||||
| manager Postgres adapter | 已实现/已通过主闭环 | `agentrun-mgr` 通过 `DATABASE_URL` 启用 Postgres adapter,持久化 runs、commands、events、runners、runner_jobs、sessions、session read cursors、backends、leases、Queue task、attempt history 和 read cursor;缺少 `DATABASE_URL` 时 live runtime fail fast,memory 只允许显式 self-test/dev。 |
|
||||
| health/readiness store 状态 | 已实现 | health/readiness 返回 adapter、reachable、migrationReady、migrationId、failureKind 和 redacted Secret 状态,不输出 DSN 明文。 |
|
||||
| file/sqlite durable store | 不采用 | 只可用于临时本地测试,不作为 v0.1 runtime truth。 |
|
||||
|
||||
@@ -36,6 +36,8 @@ POST /api/v1/queue/tasks/:taskId/cancel
|
||||
POST /api/v1/queue/tasks/:taskId/read
|
||||
POST /api/v1/queue/tasks/:taskId/dispatch
|
||||
POST /api/v1/queue/tasks/:taskId/refresh
|
||||
GET /api/v1/queue/tasks/:taskId/attempts?cursor=<retryIndex>&limit=<limit>
|
||||
POST /api/v1/queue/tasks/:taskId/retry
|
||||
GET /api/v1/queue/stats?queue=<queue>
|
||||
GET /api/v1/queue/commander?queue=<queue>
|
||||
```
|
||||
@@ -86,6 +88,8 @@ AgentRun CLI 必须提供 Queue 和 Session 两组命令。Queue 命令只操作
|
||||
./scripts/agentrun queue cancel <taskId> [--reason <text>] [--dry-run] [--full|--raw]
|
||||
./scripts/agentrun queue dispatch <taskId> [--json-stdin|--json-file <dispatch.json>] [--dry-run] [--full|--raw]
|
||||
./scripts/agentrun queue refresh <taskId> [--dry-run] [--full|--raw]
|
||||
./scripts/agentrun queue attempts <taskId> [--cursor <retry-index>] [--limit <limit>] [--full|--raw]
|
||||
./scripts/agentrun queue retry <taskId> --idempotency-key <key> --reason <text> [--dry-run] [--full|--raw]
|
||||
```
|
||||
|
||||
Session 命令负责输出、trace 和会话控制:
|
||||
@@ -100,7 +104,39 @@ Session 命令负责输出、trace 和会话控制:
|
||||
./scripts/agentrun sessions read <sessionId> [--reader-id <reader>]
|
||||
```
|
||||
|
||||
不得新增 `queue output`、`queue trace` 或 `queue session/*` 这类子路径代理。`queue list/show/commander` 默认输出低噪声 summary,最多打印 task/attempt/session ids、状态、统计、`sessionPath`、compact supervisor 和下一步 `sessions ...` 命令;supervisor 只允许披露 phase、last activity source seq/id、timeout budget 和恢复动作摘要,不得展开完整 payload、trace、tool command、stdout/stderr 或 runnerTrace。完整 payload/resource bundle/metadata 只能通过显式 `--full|--raw` 展开;trace/output 细节继续按 `sessionId` + `sourceSeq/eventId/itemId` 走 Session CLI 渐进披露。Queue mutation 命令带 `--dry-run` 时必须只返回 `mutation=false` 的计划,不得写 Queue、Core run/command 或 runner job。一次性 Queue task、dispatch body、run base 或 command payload 必须优先用 `--json-stdin` 接 quoted heredoc;禁止为了把 heredoc/stdin 内容交给 CLI 而先写临时 JSON dump 文件再传 `--json-file`。`--json-file` 只用于可复用、已受控的输入文件。
|
||||
不得新增 `queue output`、`queue trace` 或 `queue session/*` 这类子路径代理。
|
||||
|
||||
- `queue list/show/commander/attempts` 默认输出低噪声 summary,只打印 task/attempt/session ids、状态、失败分类、统计、`sessionPath`、compact supervisor 和下一步 `sessions ...` 命令。
|
||||
- supervisor 只允许披露 phase、last activity source seq/id、timeout budget 和恢复动作摘要。
|
||||
- 禁止默认展开完整 payload、trace、tool command、stdout/stderr 或 runnerTrace。
|
||||
- 完整 payload/resource bundle/metadata 只能通过显式 `--full|--raw` 展开。
|
||||
- trace/output 细节继续按 `sessionId` + `sourceSeq/eventId/itemId` 走 Session CLI 渐进披露。
|
||||
- Queue mutation 命令带 `--dry-run` 时必须只返回 `mutation=false` 的计划,不得写 Queue、Core run/command 或 runner job。
|
||||
- 一次性 Queue task、dispatch body、run base 或 command payload 必须优先用 `--json-stdin` 接 quoted heredoc。
|
||||
- 禁止为了把 heredoc/stdin 内容交给 CLI 而先写临时 JSON dump 文件再传 `--json-file`。
|
||||
- `--json-file` 只用于可复用、已受控的输入文件。
|
||||
|
||||
### 终态重试
|
||||
|
||||
`POST /api/v1/queue/tasks/:taskId/retry` 只接受以下请求体,不接受 task、dispatch 或 runtime patch:
|
||||
|
||||
```json
|
||||
{
|
||||
"idempotencyKey": "retry-20260712-01",
|
||||
"reason": "依赖已恢复",
|
||||
"dryRun": false
|
||||
}
|
||||
```
|
||||
|
||||
- 新 key 只允许重试 `failed` 或 `blocked` task;`completed`、`cancelled` 和正在运行的 task 必须拒绝。
|
||||
- 同一 task 的相同 key 必须先于当前状态检查返回原 attempt;相同 key 携带不同 reason 必须冲突。
|
||||
- `dryRun=true` 必须完成相同的合同、payload hash、状态和依赖校验,但不得创建 attempt、run、command、runner Job 或更新 task version。
|
||||
- 重试仍使用同一个 Queue task,创建新的正式 attempt 历史;`latestAttempt` 只保存最新摘要,不能替代 `agentrun_queue_attempts`。
|
||||
- attempt reservation 必须预留稳定的 attempt、run 和 runner Job identity;崩溃或并发重放只能续建同一组 Core 资源,不能产生重复 run、command 或 Job。
|
||||
- 启用 runner retention 时,Job 创建继续使用 namespace 级 fence 与容量回收 CAS 互斥;未启用 retention 时,必须改用 run 与 idempotency/attempt identity 的细粒度 fence,不得串行整个 namespace。
|
||||
- runner Job 物化成功前 task 必须保持原 `failed` 或 `blocked` 状态,reserved attempt 不得伪装为 running。
|
||||
- 物化失败必须在 reserved attempt 上持久化有界且脱敏的 `failureKind` 与 `failureMessage`;同 key 成功续建时清空该暂态错误。
|
||||
- 旧 terminal attempt、原 task 合同和 `payloadHash` 不可改写;禁止用自动 scheduler、backoff 或 judge 填充本次最小重试原语。
|
||||
|
||||
推荐 Queue task 提交形态:
|
||||
|
||||
@@ -131,7 +167,7 @@ Queue task 的 `resourceBundleRef` 在 dispatch 时原样进入 Core run。若
|
||||
Queue 首版新增或扩展的稳定表方向:
|
||||
|
||||
- `agentrun_queue_tasks`:任务 identity、tenant/project、queue/lane、title、priority、state、backendProfile、workspace/resource 引用、可选 `sessionRef`、创建者、version 和 timestamps。
|
||||
- `agentrun_queue_attempts`:attempt identity、taskId、runId、commandId、runnerJobId、sessionId、state、failureKind、retry index 和 timestamps。
|
||||
- `agentrun_queue_attempts`:以 `(taskId, attemptId)` 为 identity,保存 retry key/index、前序 attempt、runId、commandId、runnerJobId、sessionId、state、failureKind、failureMessage 和 timestamps。
|
||||
- `agentrun_task_summaries`:task 级摘要、当前状态、最新 attempt、最新 sessionPath、最后用户可见摘要和统计字段。
|
||||
- `agentrun_attempt_summaries`:attempt 级摘要、terminalStatus、failureKind、runner identity、耗时和有界输出摘要引用。
|
||||
- `agentrun_queue_stats`:按 queue/lane/state/backendProfile 聚合的轻量统计,可由 Queue 写入或按 Queue 表查询生成。
|
||||
@@ -171,7 +207,7 @@ Queue 首版新增或扩展的稳定表方向:
|
||||
| Q2 | attempt 到 Core run/command/runner job 的真实闭环 | Queue submit 后通过受控 `queue dispatch` 产生 attempt,并创建真实 Core run/command/runner job;`queue refresh` 从 Core run/command 终态回写 Queue attempt;自动 Scheduler 仍 deferred。 |
|
||||
| Q3 | Session 引用边界 | `queue show` 返回 `sessionPath`,输出和 trace 只能通过 `sessions ...` 查询。 |
|
||||
| Q4 | summary/stats/read/commander | Queue overview、stats、read cursor、commander 全部直接查 Queue 模型。 |
|
||||
| Q5 | retry/judge/cancel | retry/backoff、judge、cancel 与 attempt/session/core 状态一致。 |
|
||||
| Q5 | retry/judge/cancel | 先提供终态 task 的显式 retry 与正式 attempt 历史;自动 backoff、scheduler 和 judge 继续 deferred。 |
|
||||
| Q6 | 冻结旧 UniDesk Code Queue 新任务入口 | 新任务只进入 AgentRun Queue;旧系统只归档或只读。 |
|
||||
|
||||
## 验收规格
|
||||
@@ -183,7 +219,7 @@ Queue Q2 的真实手动验收必须覆盖以下稳定边界:
|
||||
- `queue submit` 只创建 Queue task,不触发自动 scheduler。
|
||||
- `queue dispatch` 是受控手动调度入口,必须创建 Core run、command 和 runner job,并把 attempt 引用写回 Queue task。
|
||||
- `queue refresh` 只读取 Queue task 保存的 run/command 引用,将 Core 终态回写到 Queue task 和 latestAttempt;不得读取 Core trace、Session trace 或 events 来反推 Queue stats/commander。
|
||||
- `queue submit/read/cancel/dispatch/refresh --dry-run` 必须只返回计划,不得改变 task state、read cursor、attempt、run、command 或 runner job。
|
||||
- `queue submit/read/cancel/dispatch/refresh/retry --dry-run` 必须只返回计划,不得改变 task state、read cursor、attempt、run、command 或 runner job。
|
||||
- `queue show/list/stats/commander` 的统计口径必须来自 Queue 模型;默认输出必须有界,输出、trace 和会话控制继续由 Session API/CLI 承接。
|
||||
- 综合联调里的 `workspaceRef` 必须是 runner 实际可访问且能启动 backend command 的工作区。`opaque` workspace 可用于不依赖 Git checkout 的最小 Queue dispatch 验收;`host-path` 只有在该 path 在 runner 容器/进程内可访问且不破坏 Codex command resolution 时才能作为通过证据。
|
||||
- 因 workspace 形态导致的 backend command spawn 失败,应归类为 runtime workspace/command 一致性问题,不能误判为 Queue dispatch 或 Queue refresh 失败。
|
||||
@@ -207,6 +243,7 @@ Queue Q2 的真实手动验收必须覆盖以下稳定边界:
|
||||
| Queue RESTful API | 已实现/Q1 | 已通过 `agentrun-mgr` 暴露 `submit/list/show/stats/read/cancel/commander`,使用短请求和 Queue version/cursor 轻量轮询;Q2 再接入 attempt 与真实执行。 |
|
||||
| Queue CLI | 已实现/Q1 | 已加入 `queue submit/list/show/stats/commander/read/cancel`;Queue 命令只返回 task summary、stats、read cursor 和 `sessionPath`。 |
|
||||
| Queue dispatch/refresh | 已实现/Q2 | `queue dispatch` 受控创建 Core run/command/runner job;`queue refresh` 从 Core run/command 终态回写 Queue task/latestAttempt;自动 Scheduler 仍 deferred。 |
|
||||
| Queue terminal retry/attempt history | 已实现/Q5 最小切片 | `queue retry/attempts` 在同一 task 下提供幂等终态重试、正式 attempt 历史和失败物化可见性;自动 scheduler、backoff 与 judge 仍 deferred。 |
|
||||
| Session API/CLI | 已实现/Q3 | Queue 只返回 `sessionPath`;Session 层已承接 `ps/show/turn/steer/cancel/output/trace/read`,默认列表只显示 running/unread。 |
|
||||
| Scheduler 接入 | 待实现 | 旧 Code Queue scheduler 不保留;AgentRun Scheduler 是唯一调度方向。 |
|
||||
| OA/Event/integrations | 不采用 | 首版不做,后续如需外部 connector/sink 必须单独立规格。 |
|
||||
|
||||
Reference in New Issue
Block a user