# AgentRun 资源原语

新 Code Queue 工作统一使用 AgentRun 资源原语：

- `--mdtodo-id` 仅是 AgentRun 遗留兼容字段；任务权威与迁移统一遵循 `$unidesk-tasktree`。

- `agentrun create|apply`：创建 task 或应用 AipodSpec manifest；
- `agentrun get|describe`：有界读取列表和详情；
- `agentrun describe task/<taskId> --input -o json`：读取可重建 task 输入、AipodSpec identity、资源引用和脱敏 provenance；
- `agentrun describe aipodspec/<name>`：读取同构、有界且 SecretRef-only 的 AipodSpec 摘要；
- `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`：控制生命周期。

## Artificer Target 单命令派单

标准入口：

```bash
bun scripts/cli.ts agentrun create task \
  --aipod Artificer \
  --title "修复 HWLAB 的 cicd" \
  --target <Target> \
  --target-workspace <absolute-task-worktree> \
  --repo <owner/repo> \
  --ref <branch> \
  --mdtodo-id <R6.3> \
  --prompt-stdin
```

- `--title` 为必填中文短标题，允许英文专有名和空格；
- 后续 `describe/events/logs/result` 直接传入标题字符串；
- 标题按规范化后的完全匹配解析，重复标题必须改用内部 ID 处理歧义。

- 默认直接执行 live 单命令；不要把 `--dry-run` 作为派单前置步骤；
- live 必须先在 owning YAML 选中的 Target 上完成最小目录 preflight，再通过同一 Target 的 k3s service proxy 请求 manager；
- preflight 必须验证：
  - `targetWorkspace` 已显式提供为绝对路径；
  - Target 上的该路径存在且为目录；
- preflight 禁止读取 task worktree Git 状态：
  - dirty、ahead、behind、detached 和已有 diff 不产生 warning 或 blocker；
  - `repo` 和 `ref` 只保留为显式任务身份；
- preflight 输出必须披露：
  - Target route、repo/ref、projectId 和 `gitStateInspected=false`；
  - 合法的 `workspaceRef.kind/path`；
  - 从 AipodSpec 继承的默认 resource bundle；
  - session identity；
  - provider/tool SecretRef 的对象、key 与 presence；
- preflight 失败固定 `mutation=false`，不得创建 task；
- preflight 通过后在同一命令内 submit 并自动 dispatch，不要求用户再运行第二条命令；
- 未显式传 `--idempotency-key` 时，由 Target/repo/ref/targetWorkspace/MDTODO 和完整请求 payload 派生稳定键；
- 幂等重试遇到已有 running 或 terminal task 时，返回既有 attempt/run/session，不重复 dispatch；
- 最终输出必须包含 task、attempt、run、command、runner 和 session identity。
- Target live 的默认 human、`-o json` 和 `-o yaml` 使用同一份有界投影：
  - 保留 task、attempt、run、command、runner、session 的 identity 与 state；
  - 保留自动派单决策、Target/MDTODO 摘要、Aipod 与 SecretRef presence 摘要；
  - `Next` 使用本次派单的具体 identity，并继承 Target 与 lane；
  - 不展开完整 task、prompt、payload 或 Aipod 对象；
  - 需要完整服务端对象时显式使用 `--raw`。

Artificer 内部执行边界：

- primary workspace 只承载默认 UniDesk bundle、`tools/trans` 和 required skills；
- 任务源码操作全部使用 `trans <Target>:<targetWorkspace>`；
- `targetWorkspace` 是用户显式指定的任务工作目录；
- runner 本地结果不得替代 Target 原入口证据；
- `unidesk-trans`、runner tools bundle、`unidesk-ssh` SecretRef 和 endpoint presence 必须同时存在；
- Secret 值不得进入 prompt、task、日志或报告。

`agentrun events` 是高频渐进披露入口：

- 短只读 canary 使用固定三步闭环：
  1. 用 `agentrun create task` 创建并自动派发。
  2. 只调用一次 `agentrun events run/<runId> --after-seq 0 --expect <高于预期事件总数的值> --timeout <有界时长> --limit 20`。
  3. 看到 `completionReason=run-terminal` 后，只调用一次 `agentrun result run/<runId> --command <commandId>` 获取权威终态和最终回复。
- 短 canary 不按固定小批事件连续翻页：
  - `expect` 只是等待上限条件；
  - run 或 command 进入终态时，manager 必须提前返回；
  - `items` 因默认分页未包含最终 assistant message 时，不继续翻页找正文，直接使用 `result`。
- active run 的推荐观察入口是：
  - `bun scripts/cli.ts agentrun events run/<runId> --after-seq <cursor> --expect 10 --timeout 120s --limit 20`；
  - manager 在单个请求内等待 after-seq 后新增事件达到 `expect`，或目标 run/command 进入终态；
  - 未达到条件时最多等待 `timeout`，默认 `120s`；
  - timeout 的部分返回和空返回都必须明确披露 `timedOut`、`observed` 与 `nextAfterSeq`；
  - 后续继续使用返回的 `nextAfterSeq`，不要恢复高频短轮询；
  - `limit` 是独立输出预算，不能替代 `expect`；
- 默认 human、`-o json` 和 `-o yaml` 最多返回 20 条同构事件摘要，并用一条 lookahead 披露 `hasMore` 与 `nextAfterSeq`；
- tool call 只展示 identity、seq/type/status、commandId、工具、命令首行、exit/duration、output bytes/hash、truncation 与 `outputOmitted`；
- 默认不得展开 stdout、stderr、skill 正文或完整 payload，也不得通过提高全局 stdout 阈值掩盖 dump；
- 单事件有界详情使用 `--detail-seq <seq>`：
  - human、JSON 和 YAML 使用同一 `EventDetail` 投影；
  - 固定读取同一 run 的 durable event，并校验返回 seq 完全一致；
  - 投影保留 identity、correlation、phase-specific evidence、count/bytes/hash/omitted；
  - durable `resolutionAuthority` 保持原事实或显式脱敏，基于其他字段的非权威判断只进入独立 inference 字段；
  - 标准 Git URL 移除 userinfo、query 和 fragment，SCP-like 与未知 remote 只披露不可逆 fingerprint；
  - credential value 和 URL credential 固定脱敏，`valuesPrinted=false`；
- `--detail-seq` 与 `--after-seq`、`--expect`、`--timeout`、`--limit`、`--full`、`--raw` 互斥，并在请求 manager 前 fail closed；
- 完整事件继续使用显式 `--full`、`--raw`，或按 `afterSeq=item.seq-1 --limit 1 --full` 下钻；
- 该 CLI 只渲染 AgentRun durable facts，不删除事件、不按正文去重，也不改变 Kafka/SSE 事件链。

AipodSpec describe 必须遵守以下边界：

- 默认 human、`-o json` 和 `-o yaml` 从同一摘要投影渲染；
- 摘要至少包含：
  - identity/hash 与 lane/profile/provider；
  - workspaceRef 与主 resource bundle source identity；
  - bundle/required skill/credential 引用计数；
  - 脱敏 provenance；
- credential 只保留 SecretRef 名称、namespace、keys 和安全 projection 字段，固定 `valuesPrinted=false`；
- 默认输出必须保留 `--full -o json` 与 `--raw` 语义化下钻，禁止读取临时 dump 再二次裁剪；
- 显式完整路径继续返回服务端完整对象，禁止提高全局 stdout 阈值掩盖默认输出缺陷。

task 输入下钻必须遵守以下边界：

- 默认 `describe task/<taskId>` 的 `Next` 必须给出 `--input -o json` 语义化命令；
- `--input` 只读取现有 task durable fact，不创建、复制、retry 或 dispatch task；
- 输出固定为 task create 字段、AipodSpec identity、bundle/SecretRef 和脱敏 provenance，credential 只保留 SecretRef 并声明 `valuesPrinted=false`；
- `--input` 与 `--full`、`--raw` 互斥，非法组合必须在请求服务端前返回带修正路径的 `validation-failed`；
- 完整服务端资源继续使用显式 `--full -o json` 或 `--raw`，禁止提高全局 stdout 阈值来掩盖大输出。

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 路径。
