@fitlab-ai/agent-infra 0.11.7 → 0.11.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/README.md +1 -1
  2. package/README.zh-CN.md +1 -1
  3. package/dist/bin/internal-cli.js +8 -2
  4. package/dist/lib/agent-clients/adapters/codex.js +1 -1
  5. package/dist/lib/agent-clients/config.js +11 -3
  6. package/dist/lib/agent-clients/custom-tool-invocations.js +92 -0
  7. package/dist/lib/agent-clients/next-steps.js +1 -1
  8. package/dist/lib/agent-clients/reconcile.js +3 -3
  9. package/dist/lib/agent-clients/schema.js +18 -10
  10. package/dist/lib/defaults.json +6 -3
  11. package/dist/lib/init.js +2 -2
  12. package/dist/lib/internal/agent-client.js +3 -3
  13. package/dist/lib/internal/cli-route-inventory.js +3 -0
  14. package/dist/lib/internal/platform-pr-review.js +20 -3
  15. package/dist/lib/internal/task-operation-registry.js +3 -1
  16. package/dist/lib/internal/task-platform-recovery.js +56 -0
  17. package/dist/lib/merge.js +25 -5
  18. package/dist/lib/platform/completion-backfill.js +2 -1
  19. package/dist/lib/platform/in-label-sync.js +12 -1
  20. package/dist/lib/platform/issue-comments.js +58 -4
  21. package/dist/lib/platform/issues.js +105 -5
  22. package/dist/lib/platform/operation-coordinator.js +74 -0
  23. package/dist/lib/platform/pr-review.js +107 -1
  24. package/dist/lib/platform/pr-summary.js +79 -57
  25. package/dist/lib/platform/pull-requests.js +96 -4
  26. package/dist/lib/sandbox/commands/create.js +6 -3
  27. package/dist/lib/sandbox/commands/ls.js +4 -3
  28. package/dist/lib/sandbox/commands/rm.js +1 -1
  29. package/dist/lib/sandbox/config.js +22 -4
  30. package/dist/lib/sandbox/git-metadata.js +50 -0
  31. package/dist/lib/sandbox/index.js +1 -1
  32. package/dist/lib/sandbox/mounts.js +12 -0
  33. package/dist/lib/sandbox/recovery.js +12 -22
  34. package/dist/lib/sandbox/removal.js +58 -20
  35. package/dist/lib/sandbox/tools.js +31 -7
  36. package/dist/lib/task/activity-intent.js +4 -3
  37. package/dist/lib/task/create-service.js +5 -3
  38. package/dist/lib/task/create.js +22 -5
  39. package/dist/lib/task/finalization-artifacts.js +4 -1
  40. package/dist/lib/task/finalization.js +243 -113
  41. package/dist/lib/task/lifecycle.js +38 -2
  42. package/dist/lib/task/platform-operation-journal.js +152 -0
  43. package/dist/lib/task/platform-operation-recovery.js +459 -0
  44. package/dist/lib/task/verification.js +0 -1
  45. package/dist/lib/task/workflow-warning-intents.js +7 -1
  46. package/dist/lib/update.js +2 -2
  47. package/dist/lifecycle-build-manifest.json +3 -3
  48. package/lib/agent-clients/adapters/codex.ts +1 -1
  49. package/lib/agent-clients/config.ts +9 -3
  50. package/lib/agent-clients/custom-tool-invocations.ts +129 -0
  51. package/lib/agent-clients/next-steps.ts +3 -3
  52. package/lib/agent-clients/reconcile.ts +3 -3
  53. package/lib/agent-clients/schema.ts +18 -10
  54. package/lib/defaults.json +6 -3
  55. package/lib/init.ts +2 -2
  56. package/lib/internal/agent-client.ts +3 -3
  57. package/lib/internal/cli-route-inventory.ts +2 -0
  58. package/lib/internal/platform-pr-review.ts +14 -3
  59. package/lib/internal/task-operation-registry.ts +3 -1
  60. package/lib/internal/task-platform-recovery.ts +53 -0
  61. package/lib/merge.ts +26 -6
  62. package/lib/platform/completion-backfill.ts +2 -1
  63. package/lib/platform/in-label-sync.ts +12 -0
  64. package/lib/platform/issue-comments.ts +59 -3
  65. package/lib/platform/issues.ts +103 -5
  66. package/lib/platform/operation-coordinator.ts +96 -0
  67. package/lib/platform/pr-review.ts +113 -1
  68. package/lib/platform/pr-summary.ts +22 -1
  69. package/lib/platform/pull-requests.ts +105 -5
  70. package/lib/sandbox/commands/create.ts +7 -8
  71. package/lib/sandbox/commands/ls.ts +4 -3
  72. package/lib/sandbox/commands/rm.ts +1 -1
  73. package/lib/sandbox/config.ts +23 -5
  74. package/lib/sandbox/git-metadata.ts +66 -0
  75. package/lib/sandbox/index.ts +1 -1
  76. package/lib/sandbox/mounts.ts +14 -0
  77. package/lib/sandbox/recovery.ts +13 -25
  78. package/lib/sandbox/removal.ts +57 -19
  79. package/lib/sandbox/tool-types.ts +2 -1
  80. package/lib/sandbox/tools.ts +38 -7
  81. package/lib/task/activity-intent.ts +4 -3
  82. package/lib/task/create-service.ts +5 -3
  83. package/lib/task/create.ts +17 -5
  84. package/lib/task/finalization-artifacts.ts +4 -1
  85. package/lib/task/finalization.ts +242 -106
  86. package/lib/task/lifecycle.ts +35 -3
  87. package/lib/task/platform-operation-journal.ts +230 -0
  88. package/lib/task/platform-operation-recovery.ts +435 -0
  89. package/lib/task/verification.ts +1 -2
  90. package/lib/task/workflow-warning-intents.ts +9 -1
  91. package/lib/update.ts +2 -3
  92. package/package.json +1 -1
  93. package/templates/.agents/README.en.md +20 -66
  94. package/templates/.agents/README.zh-CN.md +19 -65
  95. package/templates/.agents/rules/README.en.md +1 -1
  96. package/templates/.agents/rules/README.zh-CN.md +1 -1
  97. package/templates/.agents/rules/next-step-output.en.md +1 -1
  98. package/templates/.agents/rules/next-step-output.zh-CN.md +1 -1
  99. package/templates/.agents/rules/task-management.en.md +12 -0
  100. package/templates/.agents/rules/task-management.zh-CN.md +12 -0
  101. package/templates/.agents/scripts/lib/agent-infra-package.js +0 -7
  102. package/templates/.agents/skills/cancel-task/SKILL.en.md +4 -2
  103. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +4 -2
  104. package/templates/.agents/skills/code-task/SKILL.en.md +2 -2
  105. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +2 -2
  106. package/templates/.agents/skills/commit/SKILL.en.md +1 -1
  107. package/templates/.agents/skills/commit/SKILL.zh-CN.md +1 -1
  108. package/templates/.agents/skills/complete-task/SKILL.en.md +2 -0
  109. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +2 -0
  110. package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +1 -1
  111. package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +1 -1
  112. package/templates/.agents/skills/plan-task/config/verify.en.json +1 -1
  113. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +1 -1
  114. package/templates/.agents/skills/review-code/SKILL.en.md +1 -1
  115. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +1 -1
  116. package/templates/.agents/skills/review-code/reference/output-templates.en.md +15 -6
  117. package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +15 -6
  118. package/templates/.agents/skills/review-pr/SKILL.en.md +11 -11
  119. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +11 -11
  120. package/templates/.agents/skills/review-pr/reference/output-guidance.en.md +3 -3
  121. package/templates/.agents/skills/review-pr/reference/output-guidance.zh-CN.md +3 -3
  122. package/templates/.agents/skills/review-pr/reference/report-template.en.md +4 -0
  123. package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +4 -0
  124. package/templates/.agents/skills/update-agent-infra/SKILL.en.md +1 -1
  125. package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +1 -1
  126. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +21 -274
  127. package/dist/lib/agent-clients/custom-tuis.js +0 -99
  128. package/lib/agent-clients/custom-tuis.ts +0 -149
@@ -252,7 +252,7 @@ ai agent-client configure
252
252
 
253
253
  TraeCode CLI uses `.agents/skills/` as the canonical Skill source. agent-infra generates lightweight slash-command wrappers under `.traecli/commands/`; each wrapper reads the corresponding shared Skill and forwards `$ARGUMENTS` when that Skill declares arguments. It does not mirror Skill packages into `.trae/skills/`, which remains user-owned for intentional Trae-specific overrides.
254
254
 
255
- `agentClients` is the sole source of truth for built-in client state. The top-level array must contain all five built-in clients in the fixed canonical order; `sandbox.tools` lists only non-client tools such as `agent-infra` and custom tools. A legacy `tuis` field or a built-in client id in `sandbox.tools` is rejected, and configuration is never rewritten automatically.
255
+ `agentClients` is the sole source of truth for built-in client state. The top-level array must contain all five built-in clients in the fixed canonical order; `sandbox.tools.ids` lists non-client tools such as `agent-infra` and custom tools, while `sandbox.tools.definitions` maps custom tool IDs to their definitions. A legacy `tuis` field or a built-in client id in `sandbox.tools.ids` is rejected, and configuration is never rewritten automatically.
256
256
 
257
257
  ### Side effects of disabling an Agent Client
258
258
 
@@ -260,66 +260,18 @@ When you disable a built-in client, reconciliation stops maintaining its seed co
260
260
 
261
261
  ### Relation to other config fields
262
262
 
263
- - `sandbox.tools` now lists non-client tools such as `agent-infra` and custom tools. Built-in client installation belongs in `agentClients[].installInSandbox`.
264
- - `agentClients` is independent from `customTUIs` (see below). Custom TUI command files are preserved even when their directory is under a disabled built-in client's path prefix.
265
-
266
- ## Custom TUI Configuration
267
-
268
- Use the top-level `.agents/.airc.json` `customTUIs` array when your team uses an AI TUI that is not one of the built-in command targets. This config lets agent-infra show the correct next-step commands and generate command files for project custom skills by learning from an existing command in the custom TUI directory.
269
-
270
- | Field | Required | Meaning |
271
- |-------|----------|---------|
272
- | `name` | Yes | Display name shown in reports and next-step guidance, for example `<your-tui-name>`. |
273
- | `dir` | Yes | Command directory relative to the project root, for example `.<your-tui>/commands`. The path must stay inside the project root. |
274
- | `invoke` | Yes | User-facing command template used in next-step guidance. |
275
-
276
- Supported `invoke` placeholders:
277
-
278
- | Placeholder | Replaced with | Example |
279
- |-------------|---------------|---------|
280
- | `${skillName}` | The skill command name, such as `review-code` or `commit`. | `<your-cli> ${skillName}` -> `<your-cli> review-code` |
281
- | `${projectName}` | The `.airc.json` `project` value. Use this for namespaced commands. | `/${projectName}:${skillName}` -> `/your-project:review-code` |
282
-
283
- Non-namespaced custom TUI:
284
-
285
- ```json
286
- {
287
- "customTUIs": [
288
- {
289
- "name": "<your-tui-name>",
290
- "dir": ".<your-tui>/commands",
291
- "invoke": "<your-cli> ${skillName}"
292
- }
293
- ]
294
- }
295
- ```
296
-
297
- Namespaced custom TUI:
298
-
299
- ```json
300
- {
301
- "project": "your-project",
302
- "customTUIs": [
303
- {
304
- "name": "<your-tui-name>",
305
- "dir": ".<your-tui>/commands",
306
- "invoke": "/${projectName}:${skillName}"
307
- }
308
- ]
309
- }
310
- ```
311
-
312
- `customTUIs` should contain one entry per custom TUI. To let `update-agent-infra` generate command files for custom skills, keep at least one existing command file in `dir` that references a built-in skill path such as `.agents/skills/analyze-task/SKILL.md`; agent-infra uses that file as the format reference.
263
+ - `sandbox.tools.ids` lists non-client tools such as `agent-infra` and custom tools; custom definitions belong in `sandbox.tools.definitions`. Built-in client installation belongs in `agentClients[].installInSandbox`.
264
+ - Custom tool next-step commands are configured with `sandbox.tools.definitions.<id>.invoke`. See [Custom Tool Invocations](https://github.com/fitlab-ai/agent-infra/blob/main/docs/en/custom-tool-invocations.md) for the full example.
313
265
 
314
266
  ## Sandbox Custom Tools
315
267
 
316
- `customTUIs` generates slash-command files but does not change the sandbox image. To install a non-npm CLI or tool (pip / cargo / curl-based / pre-built binary) into the sandbox image and live-mount its credentials, declare it under `sandbox.customTools` in `.agents/.airc.json`. Built-in Agent Clients are installed according to `agentClients[].installInSandbox`; `agent-infra` remains a non-client entry in `sandbox.tools` and only provides the in-sandbox `ai` / `agent-infra` CLI.
268
+ To install a non-npm CLI or tool (pip / cargo / curl-based / pre-built binary) into the sandbox image and live-mount its credentials, declare it under an ID key in `sandbox.tools.definitions` in `.agents/.airc.json`. Built-in Agent Clients are installed according to `agentClients[].installInSandbox`; `agent-infra` remains a non-client entry in `sandbox.tools.ids` and only provides the in-sandbox `ai` / `agent-infra` CLI.
317
269
 
318
270
  ### Required fields
319
271
 
320
272
  | Field | Meaning |
321
273
  |-------|---------|
322
- | `id` | Lowercase id matching `^[a-z0-9][a-z0-9-]*$`. Referenced from `sandbox.tools`. Must not collide with a built-in id. |
274
+ | Definition object key | Lowercase tool ID matching `^[a-z0-9][a-z0-9-]*$`. Every selected custom tool in `sandbox.tools.ids` needs a matching definition. Definitions not listed in `ids` may remain unused. Keys must not collide with a built-in id. |
323
275
  | `install` | Install descriptor. `{ "type": "npm", "cmd": "<npm package spec>" }` runs `npm install -g <cmd>`. `{ "type": "shell", "cmd": "<shell>" }` runs the shell command(s) as `devuser` during image build. `cmd` must be non-empty. |
324
276
 
325
277
  Minimal entry — the contract for getting a tool into the image is just these two fields:
@@ -327,13 +279,14 @@ Minimal entry — the contract for getting a tool into the image is just these t
327
279
  ```json
328
280
  {
329
281
  "sandbox": {
330
- "tools": ["my-shell-tool"],
331
- "customTools": [
332
- {
333
- "id": "my-shell-tool",
334
- "install": { "type": "shell", "cmd": "curl -fsSL https://example.com/install.sh | bash" }
282
+ "tools": {
283
+ "ids": ["my-shell-tool"],
284
+ "definitions": {
285
+ "my-shell-tool": {
286
+ "install": { "type": "shell", "cmd": "curl -fsSL https://example.com/install.sh | bash" }
287
+ }
335
288
  }
336
- ]
289
+ }
337
290
  }
338
291
  }
339
292
  ```
@@ -354,24 +307,25 @@ Add only the fields your tool actually needs. Omit them and the loader fills sen
354
307
  | `hostLiveMounts` | (none) | Share host credentials live (e.g. OAuth tokens) with the container. Read-write. |
355
308
  | `postSetupCmds` | (none) | Run commands inside the container after first setup (e.g. symlinks). |
356
309
 
357
- > **`sandboxBase` is not user-configurable.** The loader always assigns `~/.agent-infra/sandboxes/<id>` so `ai sandbox rm` / `prune` can find tool state. Any `sandboxBase` value in `customTools` entries is silently ignored.
310
+ > **`sandboxBase` is not user-configurable.** The loader always assigns `~/.agent-infra/sandboxes/<id>` so `ai sandbox rm` / `prune` can find tool state. Any `sandboxBase` value in a definition is silently ignored.
358
311
 
359
312
  Real-world example — `anthropic-claude` as a user-defined id with binary name `claude` and host credential live-mount:
360
313
 
361
314
  ```json
362
315
  {
363
316
  "sandbox": {
364
- "tools": ["claude-code", "anthropic-claude"],
365
- "customTools": [
366
- {
367
- "id": "anthropic-claude",
317
+ "tools": {
318
+ "ids": ["anthropic-claude"],
319
+ "definitions": {
320
+ "anthropic-claude": {
368
321
  "install": { "type": "npm", "cmd": "@anthropic-ai/claude-code@stable" },
369
322
  "versionCmd": "claude --version",
370
323
  "hostLiveMounts": [
371
324
  { "hostPath": "~/.claude/.credentials.json", "containerSubpath": ".credentials.json" }
372
325
  ]
326
+ }
373
327
  }
374
- ]
328
+ }
375
329
  }
376
330
  }
377
331
  ```
@@ -386,7 +340,7 @@ Real-world example — `anthropic-claude` as a user-defined id with binary name
386
340
 
387
341
  ### Interaction with `sandbox.dockerfile`
388
342
 
389
- When you set `sandbox.dockerfile` to point at your own Dockerfile, agent-infra still passes both `AI_TOOL_PACKAGES` (space-separated npm package specs) and `AI_TOOLS_SHELL_INSTALL_B64` (base64-encoded shell install script) as `--build-arg`. Your custom Dockerfile decides whether to consume them; if it does not declare the matching `ARG`, the shell installs for `customTools` are silently skipped — taking over the Dockerfile means taking over the install path.
343
+ When you set `sandbox.dockerfile` to point at your own Dockerfile, agent-infra still passes both `AI_TOOL_PACKAGES` (space-separated npm package specs) and `AI_TOOLS_SHELL_INSTALL_B64` (base64-encoded shell install script) as `--build-arg`. Your custom Dockerfile decides whether to consume them; if it does not declare the matching `ARG`, the shell installs declared in `sandbox.tools.definitions` are silently skipped — taking over the Dockerfile means taking over the install path.
390
344
 
391
345
  ## Skill Authoring Conventions
392
346
 
@@ -250,7 +250,7 @@ ai agent-client configure
250
250
 
251
251
  TraeCode CLI 以 `.agents/skills/` 作为 Skill 的唯一权威源。agent-infra 仅在 `.traecli/commands/` 下生成轻量 slash-command 包装文件;每个包装文件读取对应的共享 Skill,并在该 Skill 声明参数时转发 `$ARGUMENTS`。它不会把 Skill 包镜像到 `.trae/skills/`;该目录继续由用户所有,仅用于有意添加的 Trae 专属覆盖。
252
252
 
253
- `agentClients` 是内建客户端状态的唯一配置来源。顶层数组必须按固定规范顺序包含全部五个内建客户端;`sandbox.tools` 只列出 `agent-infra` 和自定义工具等非客户端工具。旧 `tuis` 字段或 `sandbox.tools` 中的内建客户端 id 会被拒绝,配置不会被自动改写。
253
+ `agentClients` 是内建客户端状态的唯一配置来源。顶层数组必须按固定规范顺序包含全部五个内建客户端;`sandbox.tools.ids` 按顺序列出 `agent-infra` 和自定义工具等非客户端工具,`sandbox.tools.definitions` 用工具 ID 键控自定义工具定义。旧 `tuis` 字段或 `sandbox.tools.ids` 中的内建客户端 id 会被拒绝,配置不会被自动改写。
254
254
 
255
255
  ### 取消 Agent Client 的副作用
256
256
 
@@ -258,66 +258,18 @@ TraeCode CLI 以 `.agents/skills/` 作为 Skill 的唯一权威源。agent-infra
258
258
 
259
259
  ### 与其他配置字段的关系
260
260
 
261
- - `sandbox.tools` 现在只列出 `agent-infra` 和自定义工具等非客户端工具。内建客户端的安装状态由 `agentClients[].installInSandbox` 表达。
262
- - `agentClients` 与 `customTUIs`(见下)相互独立。即使自定义 TUI 目录落在已取消的内建客户端路径前缀下,其命令文件也会被保留。
263
-
264
- ## 自定义 TUI 配置
265
-
266
- 当团队使用的 AI TUI 不属于内置命令目标时,可以在 `.agents/.airc.json` 顶层配置 `customTUIs` 数组。该配置用于让 agent-infra 输出正确的下一步命令,并通过学习自定义 TUI 目录中的既有命令文件,为项目自定义 skill 生成同格式命令。
267
-
268
- | 字段 | 必填 | 含义 |
269
- |------|------|------|
270
- | `name` | 是 | 报告和下一步提示中展示的工具名称,例如 `<your-tui-name>`。 |
271
- | `dir` | 是 | 相对项目根目录的命令目录,例如 `.<your-tui>/commands`。路径必须位于项目根目录内。 |
272
- | `invoke` | 是 | 面向用户展示的命令模板,用于生成下一步提示。 |
273
-
274
- `invoke` 支持的占位符:
275
-
276
- | 占位符 | 替换为 | 示例 |
277
- |--------|--------|------|
278
- | `${skillName}` | skill 命令名,例如 `review-code` 或 `commit`。 | `<your-cli> ${skillName}` -> `<your-cli> review-code` |
279
- | `${projectName}` | `.airc.json` 中的 `project` 值,适用于带命名空间的命令。 | `/${projectName}:${skillName}` -> `/your-project:review-code` |
280
-
281
- 不带命名空间的自定义 TUI:
282
-
283
- ```json
284
- {
285
- "customTUIs": [
286
- {
287
- "name": "<your-tui-name>",
288
- "dir": ".<your-tui>/commands",
289
- "invoke": "<your-cli> ${skillName}"
290
- }
291
- ]
292
- }
293
- ```
294
-
295
- 带命名空间的自定义 TUI:
296
-
297
- ```json
298
- {
299
- "project": "your-project",
300
- "customTUIs": [
301
- {
302
- "name": "<your-tui-name>",
303
- "dir": ".<your-tui>/commands",
304
- "invoke": "/${projectName}:${skillName}"
305
- }
306
- ]
307
- }
308
- ```
309
-
310
- `customTUIs` 每个条目对应一个自定义 TUI。若希望 `update-agent-infra` 为自定义 skill 生成命令文件,请在 `dir` 中保留至少一个引用内置 skill 路径的既有命令文件,例如 `.agents/skills/analyze-task/SKILL.md`;agent-infra 会以该文件作为格式参考。
261
+ - `sandbox.tools.ids` 只列出 `agent-infra` 和自定义工具等非客户端工具;自定义定义放在 `sandbox.tools.definitions`。内建客户端的安装状态由 `agentClients[].installInSandbox` 表达。
262
+ - 自定义工具的下一步命令通过 `sandbox.tools.definitions.<id>.invoke` 配置。完整示例见 [自定义工具调用说明](https://github.com/fitlab-ai/agent-infra/blob/main/docs/zh-CN/custom-tool-invocations.md)。
311
263
 
312
264
  ## 沙箱自定义工具(Sandbox Custom Tools)
313
265
 
314
- `customTUIs` 只负责生成 slash-command 文件,**不影响沙箱镜像**。如果要把一个非 npm 分发的 CLI 或工具(pip / cargo / curl 脚本 / 裸二进制)装进沙箱镜像、并 live-mount 它的凭证目录,需要在 `.agents/.airc.json` 的 `sandbox.customTools` 中声明。内建 Agent Client 按 `agentClients[].installInSandbox` 安装;`agent-infra` 仍是 `sandbox.tools` 中的非客户端条目,只提供沙箱内的 `ai` / `agent-infra` CLI。
266
+ 自定义沙箱工具通过 `.agents/.airc.json` 的 `sandbox.tools.definitions` 按工具 ID 声明。需要把非 npm 分发的 CLI 或工具(pip / cargo / curl 脚本 / 裸二进制)装进沙箱镜像,或 live-mount 它的凭证目录时,可在对应定义中配置。内建 Agent Client 按 `agentClients[].installInSandbox` 安装;`agent-infra` 仍是 `sandbox.tools.ids` 中的非客户端条目,只提供沙箱内的 `ai` / `agent-infra` CLI。
315
267
 
316
268
  ### 必填字段
317
269
 
318
270
  | 字段 | 含义 |
319
271
  |------|------|
320
- | `id` | 小写 id,匹配 `^[a-z0-9][a-z0-9-]*$`;由 `sandbox.tools` 引用;不可与内建 id 冲突。 |
272
+ | 定义对象的键 | 小写工具 ID,匹配 `^[a-z0-9][a-z0-9-]*$`;`ids` 中选用的自定义工具必须有对应定义;未列入 `ids` 的定义可以保留为未启用工具;不可与内建 id 冲突。 |
321
273
  | `install` | 安装描述符。`{ "type": "npm", "cmd": "<npm 包规范>" }` 执行 `npm install -g <cmd>`;`{ "type": "shell", "cmd": "<shell>" }` 在镜像构建阶段以 `devuser` 执行 shell。`cmd` 必须非空。 |
322
274
 
323
275
  最小入口——把一个工具装进镜像所需的契约只有这两个字段:
@@ -325,13 +277,14 @@ TraeCode CLI 以 `.agents/skills/` 作为 Skill 的唯一权威源。agent-infra
325
277
  ```json
326
278
  {
327
279
  "sandbox": {
328
- "tools": ["my-shell-tool"],
329
- "customTools": [
330
- {
331
- "id": "my-shell-tool",
332
- "install": { "type": "shell", "cmd": "curl -fsSL https://example.com/install.sh | bash" }
280
+ "tools": {
281
+ "ids": ["my-shell-tool"],
282
+ "definitions": {
283
+ "my-shell-tool": {
284
+ "install": { "type": "shell", "cmd": "curl -fsSL https://example.com/install.sh | bash" }
285
+ }
333
286
  }
334
- ]
287
+ }
335
288
  }
336
289
  }
337
290
  ```
@@ -352,24 +305,25 @@ TraeCode CLI 以 `.agents/skills/` 作为 Skill 的唯一权威源。agent-infra
352
305
  | `hostLiveMounts` | (无) | 把宿主凭证(如 OAuth token)实时挂进容器,读写共享。 |
353
306
  | `postSetupCmds` | (无) | 首次安装完成后在容器内执行命令(如建符号链接)。 |
354
307
 
355
- > **`sandboxBase` 不由用户配置。** loader 永远使用 `~/.agent-infra/sandboxes/<id>`,这样 `ai sandbox rm` / `prune` 才能找到工具状态目录。`customTools` 条目里写的任何 `sandboxBase` 都会被静默忽略。
308
+ > **`sandboxBase` 不由用户配置。** loader 永远使用 `~/.agent-infra/sandboxes/<id>`,这样 `ai sandbox rm` / `prune` 才能找到工具状态目录。定义对象里写的任何 `sandboxBase` 都会被静默忽略。
356
309
 
357
310
  实际场景示例——`anthropic-claude` 作为用户自定义 id,二进制名是 `claude`,并把宿主凭证 live-mount 进来:
358
311
 
359
312
  ```json
360
313
  {
361
314
  "sandbox": {
362
- "tools": ["claude-code", "anthropic-claude"],
363
- "customTools": [
364
- {
365
- "id": "anthropic-claude",
315
+ "tools": {
316
+ "ids": ["anthropic-claude"],
317
+ "definitions": {
318
+ "anthropic-claude": {
366
319
  "install": { "type": "npm", "cmd": "@anthropic-ai/claude-code@stable" },
367
320
  "versionCmd": "claude --version",
368
321
  "hostLiveMounts": [
369
322
  { "hostPath": "~/.claude/.credentials.json", "containerSubpath": ".credentials.json" }
370
323
  ]
324
+ }
371
325
  }
372
- ]
326
+ }
373
327
  }
374
328
  }
375
329
  ```
@@ -29,7 +29,7 @@ so you can quickly find "which ones to read" without opening each file.
29
29
 
30
30
  ## Task Workflow
31
31
 
32
- - [`task-management.md`](task-management.md) — Task intent detection and workflow-command mapping.
32
+ - [`task-management.md`](task-management.md) — Task intent detection, workflow-command mapping, and skill blocking boundaries.
33
33
  - [`lifecycle-orchestration.md`](lifecycle-orchestration.md) — Fresh executor/reviewer, one-use receipt, pause/recovery, and safe endpoint rules for `run-task`.
34
34
  - [`review-handshake.md`](review-handshake.md) — Three-stage bidirectional review handshake: four-state disposition, symmetric evidence, disagreement ledger, convergence and post-review commit gate.
35
35
  - [`review-method.md`](review-method.md) — Shared three-stage review method: multi-pass review, risk lenses, traceability, and finding evidence.
@@ -28,7 +28,7 @@
28
28
 
29
29
  ## 任务工作流
30
30
 
31
- - [`task-management.md`](task-management.md) — 任务语义识别与工作流命令映射。
31
+ - [`task-management.md`](task-management.md) — 任务语义识别、工作流命令映射与技能阻塞边界。
32
32
  - [`lifecycle-orchestration.md`](lifecycle-orchestration.md) — `run-task` 的 fresh executor/reviewer、一次性 receipt、暂停恢复与安全终点规则。
33
33
  - [`review-handshake.md`](review-handshake.md) — 三阶段双向审查握手协议:四态处置、对称证据、分歧账本、收敛与 post-review commit 门禁。
34
34
  - [`review-method.md`](review-method.md) — 三阶段共享检视方法:多遍检视、风险镜头、追踪与 finding 证据契约。
@@ -33,7 +33,7 @@ agent-infra-internal agent-client next-steps \
33
33
 
34
34
  - Pass the next skill name for the already-selected scenario. Include `--task-ref` only when that command needs a task reference.
35
35
  - Include `--version` only for a versioned release command. It must start with a digit and satisfy `semver.valid(raw) === raw`; never pass an action, complete command, shell fragment, whitespace, or a `v` / `V` / `=` prefix.
36
- - The helper lists only built-in clients enabled in `.agents/.airc.json` `agentClients`, followed by valid `customTUIs` in configuration order.
36
+ - The helper lists enabled built-in clients, followed by selected sandbox custom tools with a valid `invoke` field in `sandbox.tools.ids` order.
37
37
  - Insert non-empty stdout verbatim at `{next-step-commands}` below the current "Next steps" heading. When stdout is empty, omit the client command block while still rendering reminders, warnings, and `Completed at`.
38
38
  - If the helper writes stderr or exits non-zero, use the current skill's error path and stop; never fall back to a hard-coded client table.
39
39
  - A complex skill selects one scenario first and invokes the helper once for that scenario; it must not pre-render every branch.
@@ -33,7 +33,7 @@ agent-infra-internal agent-client next-steps \
33
33
 
34
34
  - 静态传入当前已选场景的下一 skill 名;只有命令需要任务引用时才传 `--task-ref`。
35
35
  - 只有版本化发布命令需要版本时才传 `--version`;值必须是以数字开头且 `semver.valid(raw) === raw` 的规范 SemVer。不得传 action、完整命令、shell 片段、空白或 `v` / `V` / `=` 前缀。
36
- - helper 只展示 `.agents/.airc.json` 中 `agentClients` 已启用的内建客户端,并在其后按配置顺序追加合法的 `customTUIs`。
36
+ - helper 展示 `.agents/.airc.json` 中 `agentClients` 已启用的内建客户端,并按 `sandbox.tools.ids` 顺序追加具有有效 `invoke` 的已选自定义沙箱工具。
37
37
  - 将非空 stdout 原样放入当前“下一步”标题后的 `{next-step-commands}`;stdout 为空时省略整个客户端命令块,但继续输出提醒、告警和 `Completed at`。
38
38
  - helper 写 stderr 或返回非零时,按当前 skill 的错误路径报告并停止;禁止回退到硬编码客户端表。
39
39
  - 复杂 skill 先选定唯一场景,再只为该场景调用一次 helper,不得提前渲染所有分支。
@@ -36,6 +36,18 @@ The seven internal commands (`task-event` / `task-lifecycle` / `task-finalizatio
36
36
  - `task-verify` executes the typed catalog/check registry in-process; skills declare business events only.
37
37
  - Both entrypoints are read-only. Verification exits remain `0=pass`, `1=fail`, and `2=blocked`; network or platform blocking must never be downgraded to success.
38
38
 
39
+ ## Platform Results and Skill Blocking Boundaries
40
+
41
+ A `blocked` platform write means only that the operation is unfinished. Whether the skill stops depends on its delivery goal. The typed core handles write queuing, recovery, and idempotency; skills consume structured results and do not replay writes themselves.
42
+
43
+ - `import-issue`: stop importing when the source Issue cannot be read.
44
+ - `create-pr`: stop the creation flow when the PR was not created or its identity cannot be confirmed.
45
+ - `review-pr`: stop reviewing when the PR or reviewed head cannot be read. After local review is complete, record recoverable comment or formal Review write failures as the skill specifies without blocking the completed local review.
46
+ - `cancel-task`: apply the skill's full cancellation criteria; do not claim full cancellation when required Issue synchronization fails.
47
+ - `complete-task`: apply the skill's full completion criteria; resolve pending recoverable operations before archiving and do not claim completion while required remote facts remain unconfirmed.
48
+
49
+ Other skills continue past deferrable writes according to their local delivery goals. If `create-task` has created the local task but creation of the associated Issue fails, retain the local task and record the failure so independent subsequent work can continue.
50
+
39
51
  ## Required State Updates by Command
40
52
 
41
53
  - `create-task`: create `branch`, `workflow`, `status`, `created_at`, `updated_at`, `assigned_to`, `agent_infra_version`
@@ -36,6 +36,18 @@
36
36
  - `task-verify` 在进程内执行 typed catalog/check registry;SKILL 只声明业务事件,不传 task-dir、skill 名或特殊 check 序列。
37
37
  - 两个入口均保持只读;验证退出码固定为 `0=pass`、`1=fail`、`2=blocked`,网络或平台阻塞不得降格为成功。
38
38
 
39
+ ## 平台结果与技能阻塞边界
40
+
41
+ 平台写入返回 `blocked` 只表示该操作尚未完成;技能是否停止由当前技能的交付目标决定。平台写入的排队、恢复和幂等由 typed core 执行,技能只消费结构化结果,不自行重放。
42
+
43
+ - `import-issue`:源 Issue 读取失败时停止导入。
44
+ - `create-pr`:PR 未创建或无法确认其身份时停止创建流程。
45
+ - `review-pr`:PR 或被审 head 无法读取时停止审查;本地审查完成后,评论或正式 Review 写入失败按技能记录待恢复事实,不阻断已完成的本地审查。
46
+ - `cancel-task`:按技能的完整取消标准判断;必要的 Issue 同步失败时不得宣称取消全部完成。
47
+ - `complete-task`:按技能的完整完成标准判断;归档前收敛待恢复操作,必要的远端事实未确认时不得宣称任务完成。
48
+
49
+ 其他技能按各自的本地交付目标继续处理可延后写入。`create-task` 已在本地创建任务、但伴生 Issue 创建失败时,保留本地任务并记录失败,不停止后续可独立执行的工作。
50
+
39
51
  ## 常见命令的状态更新要求
40
52
 
41
53
  - `create-task`:创建 `branch`、`workflow`、`status`、`created_at`、`updated_at`、`assigned_to`、`agent_infra_version`
@@ -1,7 +1,6 @@
1
1
  import childProcess from "node:child_process";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
- import { fileURLToPath } from "node:url";
5
4
 
6
5
  const PACKAGE_NAME = "@fitlab-ai/agent-infra";
7
6
  const COMMAND_NAMES = ["ai", "agent-infra"];
@@ -82,7 +81,6 @@ function rootsForCommand(commandPath, platform) {
82
81
  function resolveAgentInfraPackage(options = {}) {
83
82
  const env = options.env || process.env;
84
83
  const platform = options.platform || process.platform;
85
- const startPath = options.startPath || fileURLToPath(import.meta.url);
86
84
  const attempts = [];
87
85
  const tryRoot = (candidate, source) => {
88
86
  const inspected = inspectPackageRoot(candidate, source);
@@ -95,11 +93,6 @@ function resolveAgentInfraPackage(options = {}) {
95
93
  if (explicit) return { ...explicit, attempts };
96
94
  }
97
95
 
98
- for (const candidate of packageRootsAbove(startPath)) {
99
- const self = tryRoot(candidate, "current installation");
100
- if (self) return { ...self, attempts };
101
- }
102
-
103
96
  for (const command of COMMAND_NAMES) {
104
97
  const commandPaths = lookupCommand(command, platform);
105
98
  if (commandPaths.length === 0) {
@@ -39,11 +39,13 @@ Check these directories in order:
39
39
 
40
40
  Handling rules:
41
41
  - If found in `active/` or `blocked/`: continue
42
- - If found only in `completed/`: inform the user the task is already moved and stop
42
+ - If found only in `completed/` with valid `cancelled_at` and `cancel_reason`, reuse the recorded reason, skip Steps 3-5, and continue at Step 6 to recover Issue closure and comments; stop for other completed tasks
43
43
  - If not found anywhere: prompt `Task {task-id} not found`
44
44
 
45
45
  ### 2. Choose the Cancellation Label
46
46
 
47
+ When retrying a completed task, use only the `cancel_reason` already recorded in `task.md`; do not replace it with new input.
48
+
47
49
  Infer the Issue closing label from the cancellation reason:
48
50
  - `status: superseded`: reason implies duplicate, replaced, merged into, or already covered by another Issue or PR
49
51
  - `status: invalid`: reason implies invalid report, no real problem, cannot reproduce, or no issue after investigation
@@ -76,7 +78,7 @@ Confirm the task directory was moved successfully.
76
78
 
77
79
  Check whether `task.md` contains a valid `platform_issue_identity`. If not, skip this step.
78
80
 
79
- If a valid `platform_issue_identity` exists:
81
+ If a valid `platform_issue_identity` exists, require `applied` / `no-op` without an error for every operation before declaring cancellation fully complete. On failure, retain the local terminal state and recovery record, then retry this skill for the same task after repair:
80
82
  - Run `agent-infra-internal platform-issue sync {task-id} --agent {standard-agent-token} --status {reason} --in-labels none --assignees none --milestone none --state closed --close-reason not_planned`
81
83
  - Write the cancellation body to a temporary file and run `agent-infra-internal platform-comment sync {task-id} --kind cancel --body-file {path} --agent {standard-agent-token}`
82
84
  - Run `agent-infra-internal platform-comment sync {task-id} --kind task --agent {standard-agent-token}`
@@ -38,11 +38,13 @@ description: >
38
38
 
39
39
  处理规则:
40
40
  - 如果在 `active/` 或 `blocked/` 中找到:继续
41
- - 如果只在 `completed/` 中找到:告知用户任务已转移,停止
41
+ - 如果只在 `completed/` 中找到且 `cancelled_at` 与 `cancel_reason` 有效:复用已记录的取消原因,跳过步骤 3-5,继续步骤 6 补齐 Issue 关闭与评论;其他 completed 任务停止
42
42
  - 如果都不存在:提示 `Task {task-id} not found`
43
43
 
44
44
  ### 2. 判断取消标签
45
45
 
46
+ 从 completed 任务重试时,只使用 `task.md` 已记录的 `cancel_reason`,不得采用本次输入改写取消原因。
47
+
46
48
  根据取消原因推断 Issue 关闭标签:
47
49
  - `status: superseded`:原因包含“重复”、“替代”、“合并到”、“已由 #123 / PR 替代”等语义
48
50
  - `status: invalid`:原因包含“误报”、“不存在”、“无法复现”、“排查后无问题”等语义
@@ -75,7 +77,7 @@ ls .agents/workspace/completed/{task-id}/task.md
75
77
 
76
78
  检查 `task.md` 中是否存在有效的 `platform_issue_identity`。如果没有,跳过此步骤。
77
79
 
78
- 如果存在有效的 `platform_issue_identity`:
80
+ 如果存在有效的 `platform_issue_identity`,以下操作均须取得 `applied` / `no-op` 且无错误后才能宣称取消全部完成;失败时保留本地终态和待恢复记录,修复后以同一任务重试本技能:
79
81
  - 调用 `agent-infra-internal platform-issue sync {task-id} --agent {standard-agent-token} --status {reason} --in-labels none --assignees none --milestone none --state closed --close-reason not_planned`
80
82
  - 将取消正文写入临时文件,调用 `agent-infra-internal platform-comment sync {task-id} --kind cancel --body-file {path} --agent {standard-agent-token}`
81
83
  - 调用 `agent-infra-internal platform-comment sync {task-id} --kind task --agent {standard-agent-token}`
@@ -118,7 +118,7 @@ When triaging a test failure or unexpected behavior, first read `.agents/rules/d
118
118
 
119
119
  After tests pass, call the shared commit core with `agent-infra-internal git-workflow commit --input {checkpoint-input}`. Pass `delivery: { "mode": "local" }`, explicit paths, expected HEAD/tree, task ref, agent, and the code round. This creates only a local checkpoint and does not contact a remote. The core writes a durable intent before committing and removes it after task-writer synchronization; do not emit `code.completed` if either checkpoint or task synchronization fails.
120
120
 
121
- After the checkpoint succeeds, when task.md has a `platform_issue_identity`, run `agent-infra-internal platform-issue sync {task-id} --agent {standard-agent-token} --in-labels from-diff --base {delivery-base-ref}`. The task-bound `delivery_base_ref` is the only source for Issue `in:` evidence; record a warning and stop this round without emitting `code.completed` if this sync fails.
121
+ After the checkpoint succeeds, when task.md has a `platform_issue_identity`, run `agent-infra-internal platform-issue sync {task-id} --agent {standard-agent-token} --in-labels from-diff --base {delivery-base-ref}`. The task-bound `delivery_base_ref` is the only source for Issue `in:` evidence; record a warning and continue the local code stage if this sync fails. `complete-task` restores and verifies this evidence before archiving.
122
122
 
123
123
  ### 9. Write the Code Report
124
124
 
@@ -154,7 +154,7 @@ Do not rescan or manually write digest data; the completion event must include `
154
154
 
155
155
  After requirement checkboxes are updated, run the initial event `agent-infra-internal task-event {task-id} code.completed --agent {standard-agent-token} --initiator {trigger-initiator} --request-id {request-id} --reason-code {reason-code} --artifact {code-artifact} --artifact-sha256 {artifact-sha256} --semantic-digest {semantic-digest} --files-modified {n} --tests-passed {n} {execution-flag}`; in fix mode add `--fix-for {review-artifact} --blockers {n} --major {n} --minor {n} --manual-validation {n} {execution-flag}` instead; in decision mode add `--implementation-input {input-id}` to the initial counts. The core atomically records the artifact link, stage, metadata, done log, and decision-input consumption.
156
156
 
157
- If task.md has a valid `platform_issue_identity`, read `.agents/rules/issue-sync.md`, then (status/comment failures follow the warning rules; an Issue `in:` evidence failure must not emit `code.completed`):
157
+ If task.md has a valid `platform_issue_identity`, read `.agents/rules/issue-sync.md`, then run these syncs. Record failures as warnings and continue the local workflow:
158
158
  - Run `agent-infra-internal platform-issue sync {task-id} --agent {standard-agent-token} --status in-progress`
159
159
  - Run `agent-infra-internal platform-comment sync {task-id} --kind task --agent {standard-agent-token}`
160
160
  - Run `agent-infra-internal platform-comment sync {task-id} --kind artifact --artifact {code-artifact} --agent {standard-agent-token}`
@@ -155,7 +155,7 @@ echo "$result"
155
155
 
156
156
  测试通过后,先创建报告并运行 `task-artifact {task-id} preflight --family code --artifact {code-artifact}`;preflight 失败只允许在同一受控 candidate 中修复并完整重跑,且不得产生 checkpoint、ledger、completed 或平台副作用。preflight 通过后,才通过 `agent-infra-internal git-workflow commit --input {checkpoint-input}` 调用共享 commit core,输入 `delivery: { "mode": "local" }`、明确 paths、expected HEAD/tree、task ref、agent 和 code round。该调用只创建本地 checkpoint,不访问远端;core 会在 commit 前写入 durable intent,并在 task writer 成功后清理 intent。checkpoint 失败或 task 状态未闭合时,不得发送 `code.completed`。
157
157
 
158
- checkpoint 成功后,若任务存在 `platform_issue_identity`,调用 `agent-infra-internal platform-issue sync {task-id} --agent {standard-agent-token} --in-labels from-diff --base {delivery-base-ref}`,由 task-bound `delivery_base_ref` 产生 Issue 的 `in:` target;该同步失败时记录 warning 并停止本轮,不发送 `code.completed`。
158
+ checkpoint 成功后,若任务存在 `platform_issue_identity`,调用 `agent-infra-internal platform-issue sync {task-id} --agent {standard-agent-token} --in-labels from-diff --base {delivery-base-ref}`,由 task-bound `delivery_base_ref` 产生 Issue 的 `in:` target;同步失败时记录 warning,继续完成本地代码阶段。`complete-task` 在归档前补齐并核验该证据。
159
159
 
160
160
  排查测试失败或行为不符合预期时,先读取 `.agents/rules/debugging-guide.md`,按其四阶段流程定位根因,禁止盲目改代码重试。
161
161
 
@@ -199,7 +199,7 @@ echo "$finalizer"
199
199
  - 修复模式:`agent-infra-internal task-event {task-id} code.completed --agent {standard-agent-token} --initiator {trigger-initiator} --request-id {request-id} --reason-code {reason-code} --artifact {code-artifact} --artifact-sha256 {artifact-sha256} --semantic-digest {semantic-digest} --fix-for {review-artifact} --blockers {n} --major {n} --minor {n} --manual-validation {n} {execution-flag}`
200
200
  - 裁决模式:`agent-infra-internal task-event {task-id} code.completed --agent {standard-agent-token} --initiator {trigger-initiator} --request-id {request-id} --reason-code {reason-code} --artifact {code-artifact} --artifact-sha256 {artifact-sha256} --semantic-digest {semantic-digest} --implementation-input {input-id} --files-modified {n} --tests-passed {n} {execution-flag}`
201
201
 
202
- 如果 task.md 中存在有效的 `platform_issue_identity`,执行以下同步操作(状态/评论失败按规则记录 warning;Issue `in:` evidence 同步失败不得发送 `code.completed`;边界见 `.agents/rules/issue-sync.md`):
202
+ 如果 task.md 中存在有效的 `platform_issue_identity`,执行以下同步操作(失败按规则记录 warning,继续本地流程;边界见 `.agents/rules/issue-sync.md`):
203
203
  - 调用 `agent-infra-internal platform-issue sync {task-id} --agent {standard-agent-token} --status in-progress`
204
204
  - 调用 `agent-infra-internal platform-comment sync {task-id} --kind task --agent {standard-agent-token}`
205
205
  - 调用 `agent-infra-internal platform-comment sync {task-id} --kind artifact --artifact {code-artifact} --agent {standard-agent-token}`
@@ -96,7 +96,7 @@ Present the verification summary per `.agents/rules/validation-output.md`; do no
96
96
 
97
97
  ## 6. Render the next step
98
98
 
99
- Before rendering the next step, read `.agents/rules/next-step-output.md` and call the unified helper exactly once based on the latest task and PR state. A failed push keeps the task active and reports only diagnostics; a final commit routes to `create-pr` or `complete-task` according to `prFlow`.
99
+ Before rendering the next step, read `.agents/rules/next-step-output.md` and call the unified helper exactly once based on the latest task and PR state. A failed push keeps the task active and reports only diagnostics. When a verified PR is already bound, route to `watch-pr`; without a bound PR, route to `create-pr` or `complete-task` according to `prFlow`.
100
100
 
101
101
  ## Notes
102
102
 
@@ -96,7 +96,7 @@ agent-infra-internal task-verify {task-id} commit.completed --format text
96
96
 
97
97
  ## 6. 输出下一步
98
98
 
99
- 渲染下一步前先读取 `.agents/rules/next-step-output.md`,并根据最新 task/PR 状态只调用一次统一 helper。push 失败时保持任务 active,只输出诊断;最终提交则按 `prFlow` 选择 `create-pr` 或 `complete-task`。
99
+ 渲染下一步前先读取 `.agents/rules/next-step-output.md`,并根据最新 task/PR 状态只调用一次统一 helper。push 失败时保持任务 active,只输出诊断;已有 verified 绑定 PR 时路由到 `watch-pr`;没有绑定 PR 时,按 `prFlow` 选择 `create-pr` 或 `complete-task`。
100
100
 
101
101
  ## 注意事项
102
102
 
@@ -178,6 +178,8 @@ If a summary must mirror a human-decided `post-review-commit` exemption, make a
178
178
  agent-infra-internal task-finalization {task-id} complete --agent {standard-agent-token}
179
179
  ```
180
180
 
181
+ For an active task, finalization first recovers pending platform operations, then syncs and rereads Issue `in:` labels from `delivery_base_ref` together with requirements, Issue Type, and fields. If a required fact cannot be confirmed, the task stays active and completion is not committed.
182
+
181
183
  Finalization runs allowed artifact backfill -> lifecycle -> terminal task comment -> core verification -> warning task-comment update -> summary seal in a fixed order. Every backfill that actually runs must reach a successful terminal result before lifecycle starts; an ordinary replay with a complete receipt and no recovery fact does not rerun backfill, comments, verification, or summary. A completed recovery that may write a managed comment first persists a done summary as pending, then seals it only at the end. Summary seal always reads the durable staging record retained in the task directory; the platform entry point validates marker, owner, and digest, performs any required delete/recreate, and reads back final remote order. `result=completed` means the host safely completed the task from structured results and the receipt; if peripheral warnings or pending steps remain, return `result=completed_with_warnings`, warnings, and pending steps. Use `result=failed` or `result=blocked` only for hard or receipt/capability failures, then fix the cause and retry through the same entry point; do not claim completion or hand-repair partial state. A sandbox must not run `ls completed` or a local terminal verification against its historical mount to re-decide this result.
182
184
 
183
185
  ### 7. Handle Finalization Retries and Results
@@ -177,6 +177,8 @@ agent-infra-internal task-verify {task-id} complete-task.preflight --format text
177
177
  agent-infra-internal task-finalization {task-id} complete --agent {standard-agent-token}
178
178
  ```
179
179
 
180
+ active 任务的 finalization 先恢复账本中的待处理平台操作,并将 `delivery_base_ref` 对应的 Issue `in:` 标签与需求、Issue Type、字段一并同步及复读。任一必要事实无法确认时保持 active,不提交完成状态。
181
+
180
182
  finalization 按允许的 artifact backfill → lifecycle → task 评论 → core verification → warning task 评论更新 → summary seal 的固定顺序执行。每项实际运行的 backfill 必须取得成功终态,否则不得进入 lifecycle;完整 receipt 且无恢复事实的普通重入不执行 backfill、评论、验证或 summary。任何可能写入 managed comment 的 completed 恢复会先把 done summary 持久化为 pending,恢复末尾才重新 seal。summary seal 始终读取任务目录中保留的 durable staging record;平台入口负责校验 marker、owner 和 digest,必要时删除并重建摘要,再复读最终远端顺序。`result=completed` 即表示宿主已依据结构化结果和 receipt 安全完成;若还有外围 warning 或 pending step,返回 `result=completed_with_warnings`、warnings 和 pending steps。`result=failed` 或 `result=blocked` 仅用于硬失败或 receipt/capability 失败,修复原因后以同一入口重试,不得宣称完成或手工补写局部状态。沙箱不得从旧挂载执行 `ls completed` 或本地终态校验来重新裁决该结果。
181
183
 
182
184
  ### 7. 处理 finalization 重试与结果
@@ -57,7 +57,7 @@ Milestone rule:
57
57
 
58
58
  - Extract `platform_issue_identity` from task.md when this work belongs to an active task
59
59
  - If `platform_issue_identity` exists, complete the prerequisite code-hosting platform detection steps first, then query the Issue via `.agents/rules/issue-pr-commands.md`
60
- - Before calling the PR creation command, check whether the current branch already has a PR. If it does, report the PR URL and state, then stop without repeating metadata sync or summary publication
60
+ - Before calling `platform-pr create`, check whether the current branch already has a PR. If the task is bound to the unique PR, the core reuses that bound identity and continues metadata sync, change reporting, and summary publication. If an existing PR is unbound, verify and bind its identity before continuing; an ordinary create request without a bound PR identity may create a new PR
61
61
  - Use HEREDOC to pass the PR body
62
62
  - Replace `{$IssueNumber}` in the template when present
63
63
  - End the PR body with `Generated with AI assistance`
@@ -57,7 +57,7 @@ Milestone 规则:
57
57
 
58
58
  - 当前工作属于 active task 时,从 task.md 提取 `platform_issue_identity`
59
59
  - 如果存在 `platform_issue_identity`,先完成代码托管平台检测,再通过 `.agents/rules/issue-pr-commands.md` 查询 Issue
60
- - 调用 PR 创建命令前,先检查当前分支是否已有 PR;若已有,报告 PR URL 和状态后停止,不重复执行元数据同步或 summary 发布
60
+ - 调用 `platform-pr create` 前检查当前分支是否已有 PR;任务已绑定到唯一 PR 时,core 复用该绑定身份并继续完成元数据同步、变更报告和摘要发布;发现已有 PR 但任务尚未绑定时,先核验并绑定其身份再继续;未绑定 PR 身份的普通创建请求可能会创建新的 PR
61
61
  - 使用 HEREDOC 传入 PR 正文
62
62
  - 模板中存在 `{$IssueNumber}` 时进行替换
63
63
  - PR 正文以 `Generated with AI assistance` 结尾
@@ -20,7 +20,7 @@
20
20
  "schema": "plan"
21
21
  },
22
22
  "activity-log": {
23
- "expected_action_pattern": "(Plan Task|Technical Design) \\(Round \\d+\\)"
23
+ "expected_action_pattern": "((Plan Task|Technical Design) \\(Round \\d+\\)|Human Decision)"
24
24
  },
25
25
  "review-ledger": {
26
26
  "stage_scope": [
@@ -20,7 +20,7 @@
20
20
  "schema": "plan"
21
21
  },
22
22
  "activity-log": {
23
- "expected_action_pattern": "(Plan Task|Technical Design) \\(Round \\d+\\)"
23
+ "expected_action_pattern": "((Plan Task|Technical Design) \\(Round \\d+\\)|Human Decision)"
24
24
  },
25
25
  "review-ledger": {
26
26
  "stage_scope": [
@@ -175,7 +175,7 @@ manual-validation counts do not influence branch selection; they are displayed o
175
175
 
176
176
  > Before rendering the final output, read `.agents/rules/next-step-output.md` and apply both of its rules: (1) render `{task-ref}` in the "Next steps" commands as the current task's short id `NN` (see that file for lookup and fallback), while other `{task-id}` placeholders (report titles, paths) keep the full TASK-id form; (2) append the `Completed at` line as the very last line of the user-facing output (this applies to every user-facing output — success, error, and early-return paths alike, not only the success path).
177
177
 
178
- render the selected next-step commands through the shared helper. If `.agents/.airc.json` configures custom TUIs (via `customTUIs`), read each tool's `name` and `invoke`, then add the matching command line in the same format (`${skillName}` becomes the skill name and `${projectName}` becomes the project name).
178
+ Render only the selected scenario's commands returned by the shared helper. The helper builds custom tool commands from `sandbox.tools.ids` and `sandbox.tools.definitions`; do not reread configuration or manually append commands.
179
179
 
180
180
  ## Completion Checklist
181
181
 
@@ -171,7 +171,7 @@ manual-validation 的数量不参与分支选择,只作为人工校验计数
171
171
 
172
172
  > 渲染最终输出前先读取 `.agents/rules/next-step-output.md` 并落实其两类规则:(1) 「下一步」命令的 `{task-ref}` 渲染为当前任务短号 `NN`(取值与回退见该文件),其他 `{task-id}` 占位(报告标题、路径)保持完整 TASK-id 形式;(2) 在面向用户输出的绝对最后一行追加 `Completed at` 收尾行(成功、错误、早退等任何面向用户输出都适用,不限于校验通过的成功态)。
173
173
 
174
- 向用户通过统一 helper 渲染已选场景的下一步命令。如果 `.agents/.airc.json` 中配置了自定义 TUI(`customTUIs`),读取每个工具的 `name` 和 `invoke`,按同样格式补充对应命令行(`${skillName}` 替换为技能名,`${projectName}` 替换为项目名)。
174
+ 向用户只展示统一 helper 返回的已选场景命令。自定义工具命令由 helper 按 `sandbox.tools.ids` 和 `sandbox.tools.definitions` 生成;不得再次读取配置或手工追加命令。
175
175
 
176
176
  ## 完成检查清单
177
177