@fitlab-ai/agent-infra 0.9.12 → 0.9.14

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 (402) hide show
  1. package/README.md +11 -11
  2. package/README.zh-CN.md +11 -11
  3. package/bin/cli.ts +26 -9
  4. package/dist/bin/cli.js +173 -157
  5. package/dist/bin/internal-cli.js +66 -40
  6. package/dist/lib/agent-client.js +5 -0
  7. package/dist/lib/agent-clients/next-steps.js +6 -1
  8. package/dist/lib/decide.js +3 -3
  9. package/dist/lib/internal/agent-client.js +5 -2
  10. package/dist/lib/internal/cli-route-inventory.js +152 -0
  11. package/dist/lib/internal/codex-lifecycle.js +9 -6
  12. package/dist/lib/internal/codex-sandbox-controller.js +8 -2
  13. package/dist/lib/internal/git-workflow.js +10 -6
  14. package/dist/lib/internal/platform-checks.js +19 -7
  15. package/dist/lib/internal/platform-comment.js +25 -13
  16. package/dist/lib/internal/platform-context.js +6 -3
  17. package/dist/lib/internal/platform-issue.js +20 -13
  18. package/dist/lib/internal/platform-metadata.js +88 -0
  19. package/dist/lib/internal/platform-pr-review.js +26 -13
  20. package/dist/lib/internal/platform-pr.js +84 -31
  21. package/dist/lib/internal/platform-release-notes.js +9 -6
  22. package/dist/lib/internal/platform-security.js +93 -0
  23. package/dist/lib/internal/pr-review-grade.js +25 -12
  24. package/dist/lib/internal/release-workflow.js +23 -9
  25. package/dist/lib/internal/sandbox-control.js +50 -7
  26. package/dist/lib/internal/task-activity.js +16 -7
  27. package/dist/lib/internal/task-artifact.js +235 -24
  28. package/dist/lib/internal/task-context.js +4 -1
  29. package/dist/lib/internal/task-create.js +50 -17
  30. package/dist/lib/internal/task-delivery.js +4 -1
  31. package/dist/lib/internal/task-event.js +10 -4
  32. package/dist/lib/internal/task-finalization.js +6 -3
  33. package/dist/lib/internal/task-invalidation.js +63 -0
  34. package/dist/lib/internal/task-ledger.js +20 -6
  35. package/dist/lib/internal/task-lifecycle.js +6 -3
  36. package/dist/lib/internal/task-operation-registry.js +421 -0
  37. package/dist/lib/internal/task-orchestration.js +12 -0
  38. package/dist/lib/internal/task-override.js +14 -7
  39. package/dist/lib/internal/task-qualification.js +90 -0
  40. package/dist/lib/internal/task-review.js +7 -4
  41. package/dist/lib/internal/task-short-id.js +11 -1
  42. package/dist/lib/internal/task-snapshot.js +4 -1
  43. package/dist/lib/internal/task-validate.js +7 -2
  44. package/dist/lib/internal/task-verify.js +11 -7
  45. package/dist/lib/internal/task-warning.js +11 -4
  46. package/dist/lib/platform/adapters.js +1 -3
  47. package/dist/lib/platform/change-request-git-evidence.js +27 -7
  48. package/dist/lib/platform/comment-safety.js +226 -0
  49. package/dist/lib/platform/completion-backfill.js +6 -5
  50. package/dist/lib/platform/context.js +70 -130
  51. package/dist/lib/platform/github-client.js +1 -1
  52. package/dist/lib/platform/github-provider.js +1130 -0
  53. package/dist/lib/platform/in-label-sync.js +143 -0
  54. package/dist/lib/platform/issue-comments.js +237 -72
  55. package/dist/lib/platform/issues.js +335 -189
  56. package/dist/lib/platform/metadata-labels.js +6 -2
  57. package/dist/lib/platform/none-provider.js +28 -0
  58. package/dist/lib/platform/pr-change-report.js +545 -0
  59. package/dist/lib/platform/pr-checks.js +119 -104
  60. package/dist/lib/platform/pr-review.js +88 -72
  61. package/dist/lib/platform/pr-summary.js +541 -50
  62. package/dist/lib/platform/provider-bridge.js +45 -0
  63. package/dist/lib/platform/provider-contract.d.ts +553 -0
  64. package/dist/lib/platform/provider-contract.js +99 -0
  65. package/dist/lib/platform/provider-loader.js +251 -0
  66. package/dist/lib/platform/provider-validation.js +577 -0
  67. package/dist/lib/platform/pull-request-metadata.js +8 -6
  68. package/dist/lib/platform/pull-requests.js +734 -543
  69. package/dist/lib/platform/release-notes.js +78 -55
  70. package/dist/lib/platform/releases.js +79 -50
  71. package/dist/lib/platform/repository-metadata.js +377 -0
  72. package/dist/lib/platform/resource-identity.d.ts +26 -0
  73. package/dist/lib/platform/resource-identity.js +92 -0
  74. package/dist/lib/platform/security-alerts.js +155 -0
  75. package/dist/lib/platform/task-identities.js +31 -0
  76. package/dist/lib/platform/verification-required.js +11 -12
  77. package/dist/lib/platform/verification-sync.js +129 -248
  78. package/dist/lib/pr-review/evidence-grading.js +19 -6
  79. package/dist/lib/process-data/index.js +7 -0
  80. package/dist/lib/run/index.js +68 -23
  81. package/dist/lib/sandbox/commands/control-status.js +22 -0
  82. package/dist/lib/sandbox/commands/create.js +32 -6
  83. package/dist/lib/sandbox/commands/ls.js +5 -0
  84. package/dist/lib/sandbox/commands/rm.js +827 -120
  85. package/dist/lib/sandbox/commands/show.js +16 -0
  86. package/dist/lib/sandbox/control/client.js +174 -19
  87. package/dist/lib/sandbox/control/completed-reentry.js +85 -0
  88. package/dist/lib/sandbox/control/container-identity.js +28 -31
  89. package/dist/lib/sandbox/control/executor.js +151 -16
  90. package/dist/lib/sandbox/control/lifecycle.js +621 -127
  91. package/dist/lib/sandbox/control/native-file-lock.js +177 -0
  92. package/dist/lib/sandbox/control/protocol.js +77 -0
  93. package/dist/lib/sandbox/control/server.js +677 -34
  94. package/dist/lib/sandbox/control/state.js +209 -4
  95. package/dist/lib/sandbox/control/task-view.js +183 -0
  96. package/dist/lib/sandbox/engines/authority.js +289 -0
  97. package/dist/lib/sandbox/engines/docker-exact-discovery.js +97 -0
  98. package/dist/lib/sandbox/index.js +5 -0
  99. package/dist/lib/sandbox/recovery.js +21 -1
  100. package/dist/lib/sandbox/workspace-view.js +2 -1
  101. package/dist/lib/sandbox/worktree-safety.js +4 -1
  102. package/dist/lib/server/index.js +8 -0
  103. package/dist/lib/server/protocol.js +38 -1
  104. package/dist/lib/task/activity-log.js +8 -1
  105. package/dist/lib/task/artifact-lifecycle.js +75 -18
  106. package/dist/lib/task/artifact-operations.js +520 -0
  107. package/dist/lib/task/artifact-repair-intent.js +59 -0
  108. package/dist/lib/task/artifact-schema.js +135 -0
  109. package/dist/lib/task/capabilities.js +310 -0
  110. package/dist/lib/task/commands/status.js +32 -0
  111. package/dist/lib/task/commit-operation.js +12 -1
  112. package/dist/lib/task/control-authority.js +12 -5
  113. package/dist/lib/task/create-service.js +111 -12
  114. package/dist/lib/task/create.js +25 -0
  115. package/dist/lib/task/current-contract.js +5 -1
  116. package/dist/lib/task/decision-details.js +1 -1
  117. package/dist/lib/task/events.js +416 -17
  118. package/dist/lib/task/finalization.js +37 -13
  119. package/dist/lib/task/human-override.js +58 -36
  120. package/dist/lib/task/index.js +11 -3
  121. package/dist/lib/task/invalidation-command.js +86 -0
  122. package/dist/lib/task/invalidation.js +260 -0
  123. package/dist/lib/task/ledger-intents.js +37 -0
  124. package/dist/lib/task/local-artifact-finalization.js +299 -0
  125. package/dist/lib/task/orchestration.js +240 -144
  126. package/dist/lib/task/pr-delivery-fact.js +102 -101
  127. package/dist/lib/task/qualification-audit.js +490 -0
  128. package/dist/lib/task/qualification-confirmation.js +109 -0
  129. package/dist/lib/task/qualification-intents.js +148 -0
  130. package/dist/lib/task/review-artifacts.js +22 -23
  131. package/dist/lib/task/review-finalization.js +121 -4
  132. package/dist/lib/task/review-fingerprint.js +24 -2
  133. package/dist/lib/task/rework-intent.js +138 -0
  134. package/dist/lib/task/sections.js +6 -4
  135. package/dist/lib/task/skill-scope.js +23 -0
  136. package/dist/lib/task/task-execution-lock.js +27 -17
  137. package/dist/lib/task/verification-config.js +11 -0
  138. package/dist/lib/task/verification-engine.js +93 -16
  139. package/dist/lib/task/verification.js +3 -3
  140. package/dist/lib/task/workflow-warning-intents.js +1 -1
  141. package/dist/lib/task/write.js +11 -0
  142. package/dist/lib/version.js +11 -1
  143. package/dist/lifecycle-build-manifest.json +3 -3
  144. package/lib/agent-client.ts +9 -0
  145. package/lib/agent-clients/next-steps.ts +6 -1
  146. package/lib/decide.ts +3 -3
  147. package/lib/init.ts +1 -1
  148. package/lib/internal/agent-client.ts +4 -2
  149. package/lib/internal/cli-route-inventory.ts +140 -0
  150. package/lib/internal/codex-lifecycle.ts +8 -6
  151. package/lib/internal/codex-sandbox-controller.ts +7 -2
  152. package/lib/internal/git-workflow.ts +9 -6
  153. package/lib/internal/platform-checks.ts +14 -6
  154. package/lib/internal/platform-comment.ts +20 -12
  155. package/lib/internal/platform-context.ts +5 -3
  156. package/lib/internal/platform-issue.ts +17 -11
  157. package/lib/internal/platform-metadata.ts +70 -0
  158. package/lib/internal/platform-pr-review.ts +23 -12
  159. package/lib/internal/platform-pr.ts +65 -27
  160. package/lib/internal/platform-release-notes.ts +8 -6
  161. package/lib/internal/platform-security.ts +83 -0
  162. package/lib/internal/pr-review-grade.ts +20 -11
  163. package/lib/internal/release-workflow.ts +21 -9
  164. package/lib/internal/sandbox-control.ts +44 -6
  165. package/lib/internal/task-activity.ts +15 -7
  166. package/lib/internal/task-artifact.ts +204 -22
  167. package/lib/internal/task-context.ts +3 -1
  168. package/lib/internal/task-create.ts +78 -17
  169. package/lib/internal/task-delivery.ts +3 -1
  170. package/lib/internal/task-event.ts +9 -4
  171. package/lib/internal/task-finalization.ts +6 -4
  172. package/lib/internal/task-invalidation.ts +41 -0
  173. package/lib/internal/task-ledger.ts +21 -8
  174. package/lib/internal/task-lifecycle.ts +5 -3
  175. package/lib/internal/task-operation-registry.ts +482 -0
  176. package/lib/internal/task-orchestration.ts +12 -0
  177. package/lib/internal/task-override.ts +15 -9
  178. package/lib/internal/task-qualification.ts +61 -0
  179. package/lib/internal/task-review.ts +6 -4
  180. package/lib/internal/task-short-id.ts +10 -1
  181. package/lib/internal/task-snapshot.ts +3 -1
  182. package/lib/internal/task-validate.ts +6 -2
  183. package/lib/internal/task-verify.ts +10 -7
  184. package/lib/internal/task-warning.ts +10 -4
  185. package/lib/platform/adapters.ts +3 -2
  186. package/lib/platform/change-request-git-evidence.ts +36 -9
  187. package/lib/platform/comment-safety.ts +250 -0
  188. package/lib/platform/completion-backfill.ts +9 -8
  189. package/lib/platform/context.ts +97 -134
  190. package/lib/platform/github-client.ts +2 -2
  191. package/lib/platform/github-provider.ts +1132 -0
  192. package/lib/platform/in-label-sync.ts +208 -0
  193. package/lib/platform/issue-comments.ts +255 -80
  194. package/lib/platform/issues.ts +344 -174
  195. package/lib/platform/metadata-labels.ts +5 -2
  196. package/lib/platform/none-provider.ts +35 -0
  197. package/lib/platform/pr-change-report.ts +639 -0
  198. package/lib/platform/pr-checks.ts +126 -106
  199. package/lib/platform/pr-review.ts +88 -85
  200. package/lib/platform/pr-summary.ts +581 -53
  201. package/lib/platform/provider-bridge.ts +82 -0
  202. package/lib/platform/provider-contract.ts +611 -0
  203. package/lib/platform/provider-loader.ts +307 -0
  204. package/lib/platform/provider-validation.ts +611 -0
  205. package/lib/platform/pull-request-metadata.ts +10 -7
  206. package/lib/platform/pull-requests.ts +781 -550
  207. package/lib/platform/release-notes.ts +76 -59
  208. package/lib/platform/releases.ts +77 -43
  209. package/lib/platform/repository-metadata.ts +453 -0
  210. package/lib/platform/resource-identity.ts +121 -0
  211. package/lib/platform/security-alerts.ts +191 -0
  212. package/lib/platform/task-identities.ts +40 -0
  213. package/lib/platform/types.ts +4 -2
  214. package/lib/platform/verification-required.ts +11 -13
  215. package/lib/platform/verification-sync.ts +128 -304
  216. package/lib/pr-review/evidence-grading.ts +25 -8
  217. package/lib/process-data/index.ts +7 -0
  218. package/lib/run/index.ts +62 -22
  219. package/lib/sandbox/commands/control-status.ts +26 -0
  220. package/lib/sandbox/commands/create.ts +46 -6
  221. package/lib/sandbox/commands/ls.ts +7 -0
  222. package/lib/sandbox/commands/rm.ts +1000 -87
  223. package/lib/sandbox/commands/show.ts +16 -0
  224. package/lib/sandbox/control/client.ts +203 -19
  225. package/lib/sandbox/control/completed-reentry.ts +98 -0
  226. package/lib/sandbox/control/container-identity.ts +27 -43
  227. package/lib/sandbox/control/executor.ts +180 -15
  228. package/lib/sandbox/control/lifecycle.ts +629 -17
  229. package/lib/sandbox/control/native-file-lock.ts +209 -0
  230. package/lib/sandbox/control/protocol.ts +118 -2
  231. package/lib/sandbox/control/server.ts +724 -34
  232. package/lib/sandbox/control/state.ts +257 -4
  233. package/lib/sandbox/control/task-view.ts +240 -0
  234. package/lib/sandbox/engines/authority.ts +365 -0
  235. package/lib/sandbox/engines/docker-exact-discovery.ts +132 -0
  236. package/lib/sandbox/index.ts +7 -0
  237. package/lib/sandbox/recovery.ts +21 -1
  238. package/lib/sandbox/workspace-view.ts +9 -3
  239. package/lib/sandbox/worktree-safety.ts +4 -1
  240. package/lib/server/index.ts +10 -0
  241. package/lib/server/protocol.ts +36 -1
  242. package/lib/task/activity-log.ts +8 -0
  243. package/lib/task/artifact-lifecycle.ts +70 -22
  244. package/lib/task/artifact-operations.ts +626 -0
  245. package/lib/task/artifact-repair-intent.ts +71 -0
  246. package/lib/task/artifact-schema.ts +192 -0
  247. package/lib/task/capabilities.ts +331 -0
  248. package/lib/task/commands/status.ts +38 -0
  249. package/lib/task/commit-operation.ts +12 -1
  250. package/lib/task/control-authority.ts +22 -9
  251. package/lib/task/create-service.ts +139 -14
  252. package/lib/task/create.ts +27 -0
  253. package/lib/task/current-contract.ts +6 -1
  254. package/lib/task/decision-details.ts +6 -2
  255. package/lib/task/events.ts +392 -16
  256. package/lib/task/finalization.ts +50 -14
  257. package/lib/task/human-override.ts +70 -46
  258. package/lib/task/index.ts +16 -3
  259. package/lib/task/invalidation-command.ts +86 -0
  260. package/lib/task/invalidation.ts +332 -0
  261. package/lib/task/ledger-intents.ts +35 -1
  262. package/lib/task/local-artifact-finalization.ts +432 -0
  263. package/lib/task/orchestration.ts +223 -133
  264. package/lib/task/pr-delivery-fact.ts +131 -148
  265. package/lib/task/qualification-audit.ts +599 -0
  266. package/lib/task/qualification-confirmation.ts +117 -0
  267. package/lib/task/qualification-intents.ts +150 -0
  268. package/lib/task/review-artifacts.ts +21 -22
  269. package/lib/task/review-finalization.ts +133 -4
  270. package/lib/task/review-fingerprint.ts +23 -2
  271. package/lib/task/rework-intent.ts +165 -0
  272. package/lib/task/sections.ts +6 -4
  273. package/lib/task/skill-scope.ts +24 -0
  274. package/lib/task/task-execution-lock.ts +23 -14
  275. package/lib/task/verification-config.ts +12 -0
  276. package/lib/task/verification-engine.ts +103 -17
  277. package/lib/task/verification.ts +4 -4
  278. package/lib/task/workflow-warning-intents.ts +1 -1
  279. package/lib/task/write.ts +19 -0
  280. package/lib/update.ts +1 -1
  281. package/lib/version.ts +15 -1
  282. package/package.json +12 -1
  283. package/templates/.agents/rules/README.en.md +3 -1
  284. package/templates/.agents/rules/README.zh-CN.md +3 -1
  285. package/templates/.agents/rules/decision-qualification.en.md +22 -0
  286. package/templates/.agents/rules/decision-qualification.zh-CN.md +22 -0
  287. package/templates/.agents/rules/evidence-reporting.en.md +28 -0
  288. package/templates/.agents/rules/evidence-reporting.zh-CN.md +28 -0
  289. package/templates/.agents/rules/issue-pr-commands.en.md +1 -1
  290. package/templates/.agents/rules/issue-pr-commands.zh-CN.md +1 -1
  291. package/templates/.agents/rules/issue-sync.en.md +2 -0
  292. package/templates/.agents/rules/issue-sync.zh-CN.md +2 -0
  293. package/templates/.agents/rules/label-milestone-setup.en.md +7 -7
  294. package/templates/.agents/rules/label-milestone-setup.zh-CN.md +7 -7
  295. package/templates/.agents/rules/local-artifact-repair.en.md +13 -2
  296. package/templates/.agents/rules/local-artifact-repair.zh-CN.md +13 -2
  297. package/templates/.agents/rules/pr-sync.en.md +10 -4
  298. package/templates/.agents/rules/pr-sync.zh-CN.md +17 -4
  299. package/templates/.agents/rules/security-alerts.en.md +8 -8
  300. package/templates/.agents/rules/security-alerts.zh-CN.md +8 -8
  301. package/templates/.agents/rules/task-short-id.en.md +1 -4
  302. package/templates/.agents/rules/task-short-id.zh-CN.md +1 -3
  303. package/templates/.agents/skills/analyze-task/SKILL.en.md +28 -5
  304. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +29 -5
  305. package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -12
  306. package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -12
  307. package/templates/.agents/skills/check-task/SKILL.en.md +16 -37
  308. package/templates/.agents/skills/check-task/SKILL.zh-CN.md +16 -37
  309. package/templates/.agents/skills/close-codescan/SKILL.en.md +2 -2
  310. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +2 -2
  311. package/templates/.agents/skills/close-dependabot/SKILL.en.md +2 -2
  312. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +2 -2
  313. package/templates/.agents/skills/code-task/SKILL.en.md +41 -9
  314. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +43 -11
  315. package/templates/.agents/skills/code-task/config/verify.en.json +6 -14
  316. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +6 -14
  317. package/templates/.agents/skills/code-task/reference/code-rules.en.md +5 -4
  318. package/templates/.agents/skills/code-task/reference/code-rules.zh-CN.md +5 -4
  319. package/templates/.agents/skills/code-task/reference/dual-mode.en.md +1 -1
  320. package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +1 -1
  321. package/templates/.agents/skills/code-task/reference/fix-mode.en.md +3 -1
  322. package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +3 -1
  323. package/templates/.agents/skills/code-task/reference/report-template.en.md +42 -15
  324. package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +39 -12
  325. package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +2 -0
  326. package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +2 -0
  327. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +3 -3
  328. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +3 -3
  329. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +10 -4
  330. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +10 -4
  331. package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +2 -0
  332. package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +2 -0
  333. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +4 -3
  334. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +4 -3
  335. package/templates/.agents/skills/complete-task/SKILL.en.md +26 -21
  336. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +25 -21
  337. package/templates/.agents/skills/create-pr/SKILL.en.md +7 -6
  338. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +7 -7
  339. package/templates/.agents/skills/create-pr/config/verify.json +1 -0
  340. package/templates/.agents/skills/create-pr/reference/change-report.en.md +16 -4
  341. package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +16 -4
  342. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +5 -3
  343. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +5 -3
  344. package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +1 -1
  345. package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +1 -1
  346. package/templates/.agents/skills/create-pr/scripts/change-report.mjs +3 -0
  347. package/templates/.agents/skills/create-task/SKILL.en.md +8 -0
  348. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +7 -0
  349. package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
  350. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
  351. package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
  352. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
  353. package/templates/.agents/skills/init-labels/SKILL.en.md +8 -8
  354. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +8 -8
  355. package/templates/.agents/skills/init-milestones/SKILL.en.md +9 -11
  356. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +9 -11
  357. package/templates/.agents/skills/plan-task/SKILL.en.md +27 -4
  358. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +26 -4
  359. package/templates/.agents/skills/plan-task/config/verify.en.json +4 -14
  360. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +4 -14
  361. package/templates/.agents/skills/review-analysis/SKILL.en.md +17 -4
  362. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +17 -4
  363. package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -18
  364. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -18
  365. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +50 -23
  366. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +45 -18
  367. package/templates/.agents/skills/review-code/SKILL.en.md +18 -5
  368. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +18 -5
  369. package/templates/.agents/skills/review-code/config/verify.en.json +1 -23
  370. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -23
  371. package/templates/.agents/skills/review-code/reference/report-template.en.md +49 -22
  372. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +45 -18
  373. package/templates/.agents/skills/review-plan/SKILL.en.md +17 -4
  374. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +17 -4
  375. package/templates/.agents/skills/review-plan/config/verify.en.json +1 -18
  376. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -18
  377. package/templates/.agents/skills/review-plan/reference/report-template.en.md +49 -22
  378. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +45 -18
  379. package/templates/.agents/skills/review-pr/SKILL.en.md +5 -1
  380. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +5 -1
  381. package/templates/.agents/skills/review-pr/reference/report-template.en.md +4 -3
  382. package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +4 -3
  383. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +9 -3
  384. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +9 -3
  385. package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +3 -1
  386. package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +3 -1
  387. package/templates/.agents/skills/test/SKILL.en.md +13 -2
  388. package/templates/.agents/skills/test/SKILL.zh-CN.md +13 -2
  389. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +14 -0
  390. package/templates/.agents/skills/watch-pr/SKILL.en.md +2 -2
  391. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +2 -2
  392. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +6 -0
  393. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +6 -0
  394. package/templates/.agents/templates/task.en.md +24 -1
  395. package/templates/.agents/templates/task.zh-CN.md +24 -1
  396. package/templates/.github/workflows/pr-label.yml +7 -26
  397. package/templates/.agents/scripts/security-alerts.github.sh +0 -151
  398. package/templates/.agents/scripts/security-alerts.sh +0 -31
  399. package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +0 -146
  400. package/templates/.agents/skills/init-labels/scripts/init-labels.sh +0 -32
  401. package/templates/.agents/skills/init-milestones/scripts/init-milestones.github.sh +0 -294
  402. package/templates/.agents/skills/init-milestones/scripts/init-milestones.sh +0 -6
@@ -42,7 +42,7 @@ function failed(taskId, error, overrides = {}) {
42
42
  ...overrides
43
43
  };
44
44
  }
45
- function emptyReceipt(taskId) {
45
+ function emptyReceipt(taskId, controlBinding) {
46
46
  return {
47
47
  version: RECEIPT_VERSION,
48
48
  taskId,
@@ -54,6 +54,7 @@ function emptyReceipt(taskId) {
54
54
  verification: 'pending',
55
55
  warningProjection: 'done',
56
56
  warnings: [],
57
+ ...(controlBinding ? { controlBinding } : {}),
57
58
  updatedAt: now(),
58
59
  lastError: null
59
60
  };
@@ -79,6 +80,7 @@ function validateReceipt(value, taskId) {
79
80
  if (!value || typeof value !== 'object' || Array.isArray(value))
80
81
  throw new Error('receipt must be an object');
81
82
  const receipt = value;
83
+ const controlBinding = receipt.controlBinding;
82
84
  const states = ['pending', 'done', 'skipped'];
83
85
  if (receipt.version !== RECEIPT_VERSION || receipt.taskId !== taskId || receipt.intent !== 'complete'
84
86
  || typeof receipt.receiptId !== 'string' || receipt.receiptId.length === 0
@@ -89,7 +91,11 @@ function validateReceipt(value, taskId) {
89
91
  || !['pending', 'done'].includes(String(receipt.warningProjection))
90
92
  || !Array.isArray(receipt.warnings) || receipt.warnings.some((warning) => !validWarning(warning))
91
93
  || typeof receipt.updatedAt !== 'string'
92
- || (receipt.lastError !== null && (typeof receipt.lastError !== 'object' || Array.isArray(receipt.lastError))))
94
+ || (receipt.lastError !== null && (typeof receipt.lastError !== 'object' || Array.isArray(receipt.lastError)))
95
+ || (receipt.controlBinding !== undefined && (!controlBinding || typeof controlBinding !== 'object'
96
+ || Array.isArray(controlBinding)
97
+ || typeof controlBinding.generation !== 'string' || controlBinding.generation.length === 0
98
+ || typeof controlBinding.requestId !== 'string' || !/^[a-f0-9-]{16,64}$/u.test(controlBinding.requestId))))
93
99
  throw new Error('receipt schema is invalid');
94
100
  return receipt;
95
101
  }
@@ -100,6 +106,13 @@ function readReceipt(repoRoot, taskId) {
100
106
  const value = JSON.parse(fs.readFileSync(file, 'utf8'));
101
107
  return validateReceipt(value, taskId);
102
108
  }
109
+ function readTaskFinalizationReceipt(repoRoot, taskId) {
110
+ return readReceipt(path.resolve(repoRoot), taskId);
111
+ }
112
+ function controlBindingMatches(receipt, binding) {
113
+ return receipt.controlBinding?.generation === binding.generation
114
+ && receipt.controlBinding.requestId === binding.requestId;
115
+ }
103
116
  function writeReceipt(repoRoot, receipt) {
104
117
  const directory = finalizationRoot(repoRoot);
105
118
  fs.mkdirSync(directory, { recursive: true, mode: 0o700 });
@@ -346,7 +359,7 @@ function reconcileWarningProjection(repoRoot, taskId, receipt, consumed) {
346
359
  return receipt;
347
360
  }
348
361
  }
349
- function syncPendingTaskComment(input) {
362
+ async function syncPendingTaskComment(input) {
350
363
  const { repoRoot, taskId, agent, commentSync, consumedCapabilities } = input;
351
364
  let receipt = input.receipt;
352
365
  if (receipt.taskComment !== 'pending') {
@@ -358,7 +371,7 @@ function syncPendingTaskComment(input) {
358
371
  };
359
372
  }
360
373
  try {
361
- const result = commentSync(taskId, { kind: 'task', agent, cwd: repoRoot });
374
+ const result = await commentSync(taskId, { kind: 'task', agent, cwd: repoRoot });
362
375
  const step = commentStep(result);
363
376
  if (result.status === 'applied' || result.status === 'no-op') {
364
377
  const skipped = result.error?.code === 'ISSUE_NOT_LINKED';
@@ -416,7 +429,7 @@ function terminalResult(taskId, receipt, steps, changed, error = null) {
416
429
  error: hardError ? error : postLifecyclePending ? null : error
417
430
  };
418
431
  }
419
- function applyUnderLock(request, taskId, options) {
432
+ async function applyUnderLock(request, taskId, options) {
420
433
  const repoRoot = path.resolve(options.repoRoot);
421
434
  const lifecycle = options.lifecycle ?? applyTaskLifecycle;
422
435
  const commentSync = options.commentSync ?? syncPlatformComment;
@@ -426,17 +439,28 @@ function applyUnderLock(request, taskId, options) {
426
439
  try {
427
440
  const file = receiptPath(repoRoot, taskId);
428
441
  const existed = fs.existsSync(file);
429
- receipt = readReceipt(repoRoot, taskId) ?? emptyReceipt(taskId);
442
+ receipt = readReceipt(repoRoot, taskId) ?? emptyReceipt(taskId, options.controlBinding);
430
443
  if (!existed)
431
444
  writeReceipt(repoRoot, receipt);
432
445
  }
433
446
  catch (error) {
434
447
  return failed(taskId, errorOf(error, 'TASK_FINALIZATION_RECEIPT_INVALID'));
435
448
  }
449
+ if (options.controlBinding && !controlBindingMatches(receipt, options.controlBinding)) {
450
+ const error = {
451
+ code: 'TASK_FINALIZATION_CONTROL_BINDING_CONFLICT',
452
+ message: 'finalization receipt belongs to a different sandbox request or generation',
453
+ retryable: false
454
+ };
455
+ return failed(taskId, error, {
456
+ completedSteps: completedSteps(receipt),
457
+ pendingSteps: pendingSteps(receipt)
458
+ });
459
+ }
436
460
  const preflightState = resolveTaskRef(taskId, { repoRoot });
437
461
  if (options.preflight && preflightState.ok && preflightState.state === 'active') {
438
462
  try {
439
- const preflight = options.preflight({ taskRef: taskId, event: 'complete-task.preflight' }, { repoRoot });
463
+ const preflight = await options.preflight({ taskRef: taskId, event: 'complete-task.preflight' }, { repoRoot });
440
464
  if (preflight.status !== 'pass') {
441
465
  const detail = verificationFailure(preflight);
442
466
  return failed(taskId, detail, {
@@ -510,7 +534,7 @@ function applyUnderLock(request, taskId, options) {
510
534
  }
511
535
  let taskComment = null;
512
536
  receipt = reconcileWarningProjection(repoRoot, taskId, receipt, consumedCapabilities);
513
- const initialComment = syncPendingTaskComment({
537
+ const initialComment = await syncPendingTaskComment({
514
538
  repoRoot, taskId, agent: request.agent, receipt, commentSync, consumedCapabilities
515
539
  });
516
540
  receipt = initialComment.receipt;
@@ -526,7 +550,7 @@ function applyUnderLock(request, taskId, options) {
526
550
  verification = { status: 'no-op', changed: false, error: null };
527
551
  }
528
552
  else {
529
- const result = verify({ taskRef: taskId, event: 'complete-task.completed' }, { repoRoot });
553
+ const result = await verify({ taskRef: taskId, event: 'complete-task.completed' }, { repoRoot });
530
554
  verification = verificationStep(result);
531
555
  if (result.status === 'pass') {
532
556
  const capability = issueCapability(receipt, 'verification');
@@ -534,7 +558,7 @@ function applyUnderLock(request, taskId, options) {
534
558
  scope: 'verification', operation: 'succeeded'
535
559
  }, consumedCapabilities);
536
560
  receipt = reconcileWarningProjection(repoRoot, taskId, receipt, consumedCapabilities);
537
- const finalComment = syncPendingTaskComment({
561
+ const finalComment = await syncPendingTaskComment({
538
562
  repoRoot, taskId, agent: request.agent, receipt, commentSync, consumedCapabilities
539
563
  });
540
564
  receipt = finalComment.receipt;
@@ -571,7 +595,7 @@ function applyUnderLock(request, taskId, options) {
571
595
  receipt = reconcileWarningProjection(repoRoot, taskId, receipt, consumedCapabilities);
572
596
  return terminalResult(taskId, receipt, { lifecycle: lifecycleResult, taskComment, verification }, changed);
573
597
  }
574
- function applyTaskFinalization(request, options) {
598
+ async function applyTaskFinalization(request, options) {
575
599
  if (request.intent !== 'complete' || !request.taskRef || !request.agent) {
576
600
  return failed(null, { code: 'TASK_FINALIZATION_PAYLOAD_INVALID', message: 'complete finalization requires taskRef and agent', retryable: false });
577
601
  }
@@ -580,7 +604,7 @@ function applyTaskFinalization(request, options) {
580
604
  if (!resolved.ok)
581
605
  return failed(resolved.taskId, { code: resolved.code, message: resolved.message, retryable: false });
582
606
  try {
583
- return withTaskExecutionLock(repoRoot, resolved.taskId, 'task-finalization.complete', () => applyUnderLock(request, resolved.taskId, options));
607
+ return await withTaskExecutionLock(repoRoot, resolved.taskId, 'task-finalization.complete', () => applyUnderLock(request, resolved.taskId, options));
584
608
  }
585
609
  catch (error) {
586
610
  const detail = error instanceof TaskExecutionLockError
@@ -589,5 +613,5 @@ function applyTaskFinalization(request, options) {
589
613
  return failed(resolved.taskId, detail);
590
614
  }
591
615
  }
592
- export { applyFinalizationReceiptMutation, applyTaskFinalization, issueCapability as createFinalizationCapability };
616
+ export { applyFinalizationReceiptMutation, applyTaskFinalization, issueCapability as createFinalizationCapability, readTaskFinalizationReceipt };
593
617
  //# sourceMappingURL=finalization.js.map
@@ -20,6 +20,8 @@ import { verifyTaskEvent } from './verification.js';
20
20
  import { verifyInProcess } from './verification-engine.js';
21
21
  import { canonicalTimestamp, writeTask } from './write.js';
22
22
  import { readPrDeliveryFact } from './pr-delivery-fact.js';
23
+ import { resourceIdentity, resourceIdentityNumber } from '../platform/provider-bridge.js';
24
+ import { taskIssueIdentity } from '../platform/task-identities.js';
23
25
  const LIFECYCLE_PRODUCER = 'lifecycle.apply';
24
26
  const HUMAN_OVERRIDE_SECTION_ALIASES = ['人工豁免账本', 'Human Override Ledger'];
25
27
  const HUMAN_OVERRIDE_COLUMNS = [
@@ -402,13 +404,20 @@ function snapshotEvidence(taskId, failureIdValue, target, content, frontmatter,
402
404
  }
403
405
  function resourceForSnapshot(policy, options, frontmatter) {
404
406
  if (policy.producerId === 'platform.issue') {
405
- const number = options.probeIssueNumber ?? toPositiveInteger(frontmatter?.issue_number);
406
- return number === null ? null : { kind: 'issue', number };
407
+ const identity = options.probeIssueNumber !== undefined
408
+ ? resourceIdentity(options.probeIssueNumber)
409
+ : taskIssueIdentity((frontmatter || {})) || (() => {
410
+ const number = toPositiveInteger(frontmatter?.issue_number);
411
+ return number === null ? null : resourceIdentity(number);
412
+ })();
413
+ return identity ? { kind: 'issue', identity, number: resourceIdentityNumber(identity) } : null;
407
414
  }
408
415
  if (policy.producerId === 'platform.pull-request') {
409
416
  const fact = frontmatter ? readPrDeliveryFact(frontmatter) : null;
410
- const number = options.probePullRequestNumber ?? (fact?.status === 'valid' && fact.fact.state === 'bound' ? fact.fact.identity.number : null);
411
- return number === null ? null : { kind: 'pull-request', number };
417
+ const identity = options.probePullRequestNumber !== undefined
418
+ ? resourceIdentity(options.probePullRequestNumber)
419
+ : fact?.status === 'valid' && fact.fact.state === 'bound' ? fact.fact.identity.resource : null;
420
+ return identity ? { kind: 'pull-request', identity, number: resourceIdentityNumber(identity) } : null;
412
421
  }
413
422
  return null;
414
423
  }
@@ -461,7 +470,7 @@ function probeResult(policy, result, state) {
461
470
  function probeNotObserved(policy) {
462
471
  return error('OVERRIDE_FAILURE_NOT_PRESENT', `producer ${policy.producerId} did not produce ${policy.code}`);
463
472
  }
464
- function probePlatformFailure(taskRef, policy, resolved, options) {
473
+ async function probePlatformFailure(taskRef, policy, resolved, options) {
465
474
  let frontmatter;
466
475
  try {
467
476
  frontmatter = parseTypedTaskFrontmatter(fs.readFileSync(path.join(resolved.taskDir, 'task.md'), 'utf8'));
@@ -469,30 +478,40 @@ function probePlatformFailure(taskRef, policy, resolved, options) {
469
478
  catch (cause) {
470
479
  return error('OVERRIDE_DOCUMENT_INVALID', cause instanceof Error ? cause.message : String(cause));
471
480
  }
472
- const issueNumber = options.probeIssueNumber ?? toPositiveInteger(frontmatter.issue_number);
481
+ const issueIdentity = options.probeIssueNumber !== undefined
482
+ ? resourceIdentity(options.probeIssueNumber)
483
+ : taskIssueIdentity(frontmatter) || (() => {
484
+ const number = toPositiveInteger(frontmatter.issue_number);
485
+ return number === null ? null : resourceIdentity(number);
486
+ })();
473
487
  const fact = readPrDeliveryFact(frontmatter);
474
- const pullRequestNumber = options.probePullRequestNumber ?? (fact.status === 'valid' && fact.fact.state === 'bound' ? fact.fact.identity.number : null);
475
- const operation = policy.producerId === 'platform.issue'
476
- ? issueNumber === null
488
+ const pullRequestIdentity = options.probePullRequestNumber !== undefined
489
+ ? resourceIdentity(options.probePullRequestNumber)
490
+ : fact.status === 'valid' && fact.fact.state === 'bound' ? fact.fact.identity.resource : null;
491
+ const token = (identity) => identity ? String(identity.value) : null;
492
+ const issueToken = token(issueIdentity);
493
+ const pullRequestToken = token(pullRequestIdentity);
494
+ const operation = await (policy.producerId === 'platform.issue'
495
+ ? issueToken === null
477
496
  ? null
478
497
  : bindPlatformIssue(taskRef, {
479
- issue: issueNumber,
498
+ issue: issueToken,
480
499
  agent: options.probeOperator ?? 'local-operator',
481
500
  dryRun: true,
482
501
  cwd: resolved.repoRoot,
483
502
  ...(options.platformClient ? { client: options.platformClient } : {})
484
503
  })
485
- : pullRequestNumber === null
504
+ : pullRequestToken === null
486
505
  ? null
487
506
  : bindPlatformPullRequest(taskRef, {
488
- pr: pullRequestNumber,
507
+ pr: pullRequestToken,
489
508
  agent: options.probeOperator ?? 'local-operator',
490
509
  dryRun: true,
491
510
  cwd: resolved.repoRoot,
492
511
  ...(options.platformClient ? { client: options.platformClient } : {})
493
- });
512
+ }));
494
513
  if (!operation)
495
- return error('OVERRIDE_PROBE_INPUT_MISSING', `${policy.producerId} requires a bound issue or pull request number`);
514
+ return error('OVERRIDE_PROBE_INPUT_MISSING', `${policy.producerId} requires a bound issue or pull request identity`);
496
515
  if (operation.status !== 'failed' && operation.status !== 'blocked')
497
516
  return probeNotObserved(policy);
498
517
  if (!operation.error)
@@ -530,6 +549,9 @@ function probeTaskEventFailure(taskRef, policy, resolved) {
530
549
  event: candidate.event,
531
550
  agent: 'codex',
532
551
  dryRun: true,
552
+ initiator: 'model',
553
+ requestId: `override-probe:${taskRef}:${candidate.event}`,
554
+ reasonCode: 'user-request',
533
555
  ...(candidate.artifact ? { artifact: candidate.artifact } : {})
534
556
  }, { repoRoot: resolved.repoRoot, lockAlreadyHeld: true });
535
557
  const matched = probeResult(policy, result, resolved.state);
@@ -538,8 +560,8 @@ function probeTaskEventFailure(taskRef, policy, resolved) {
538
560
  }
539
561
  return probeNotObserved(policy);
540
562
  }
541
- function probeVerificationFailure(taskRef, policy, resolved) {
542
- const result = verifyTaskEvent({
563
+ async function probeVerificationFailure(taskRef, policy, resolved) {
564
+ const result = await verifyTaskEvent({
543
565
  taskRef,
544
566
  event: 'review-code.completed',
545
567
  artifact: policy.code === 'VERIFY_ARTIFACT_INVALID' ? 'invalid-artifact.md' : 'review-code.md'
@@ -562,7 +584,7 @@ function latestArtifact(taskDir, family) {
562
584
  });
563
585
  return candidates[0];
564
586
  }
565
- function probeVerificationEngineFailure(policy, resolved) {
587
+ async function probeVerificationEngineFailure(policy, resolved) {
566
588
  const candidates = [
567
589
  { skillName: 'review-code', family: 'review-code' },
568
590
  { skillName: 'review-plan', family: 'review-plan' },
@@ -577,7 +599,7 @@ function probeVerificationEngineFailure(policy, resolved) {
577
599
  if (candidate.family && !artifactFile)
578
600
  continue;
579
601
  try {
580
- const payload = verifyInProcess({
602
+ const payload = await verifyInProcess({
581
603
  mode: 'gate',
582
604
  skillName: candidate.skillName,
583
605
  taskDir: resolved.taskDir,
@@ -601,7 +623,7 @@ function probeVerificationEngineFailure(policy, resolved) {
601
623
  }
602
624
  return probeNotObserved(policy);
603
625
  }
604
- function probeGenericFailure(taskRef, policy, resolved, options = {}) {
626
+ async function probeGenericFailure(taskRef, policy, resolved, options = {}) {
605
627
  switch (policy.producerId) {
606
628
  case 'task.resolve':
607
629
  return probeNotObserved(policy);
@@ -610,9 +632,9 @@ function probeGenericFailure(taskRef, policy, resolved, options = {}) {
610
632
  case 'task-event':
611
633
  return probeTaskEventFailure(taskRef, policy, resolved);
612
634
  case 'task-verify':
613
- return probeVerificationFailure(taskRef, policy, resolved);
635
+ return await probeVerificationFailure(taskRef, policy, resolved);
614
636
  case 'verification-engine':
615
- return probeVerificationEngineFailure(policy, resolved);
637
+ return await probeVerificationEngineFailure(policy, resolved);
616
638
  case 'activity-intent':
617
639
  return probeResult(policy, applyPrReviewActivityIntent({
618
640
  kind: 'pr-review-start', taskRef, agent: 'codex', artifact: 'pr-review.md', head: '0'.repeat(40), dryRun: true
@@ -648,7 +670,7 @@ function probeGenericFailure(taskRef, policy, resolved, options = {}) {
648
670
  }
649
671
  case 'platform.issue':
650
672
  case 'platform.pull-request':
651
- return probePlatformFailure(taskRef, policy, resolved, options);
673
+ return await probePlatformFailure(taskRef, policy, resolved, options);
652
674
  default:
653
675
  return error('OVERRIDE_PROBE_INPUT_MISSING', `no producer probe is registered for ${policy.producerId}`);
654
676
  }
@@ -656,7 +678,7 @@ function probeGenericFailure(taskRef, policy, resolved, options = {}) {
656
678
  function isProducerFailure(value) {
657
679
  return 'observedFacts' in value && 'state' in value && Array.isArray(value.observedFacts);
658
680
  }
659
- function captureFailureSnapshot(taskRef, failureIdValue, target, options = {}) {
681
+ async function captureFailureSnapshot(taskRef, failureIdValue, target, options = {}) {
660
682
  const policy = policyFor(failureIdValue);
661
683
  if (!policy)
662
684
  return error('OVERRIDE_FAILURE_UNKNOWN', `failure policy '${failureIdValue}' is not registered`);
@@ -679,7 +701,7 @@ function captureFailureSnapshot(taskRef, failureIdValue, target, options = {}) {
679
701
  catch { /* probe reports an unconfirmed identity */ }
680
702
  const producer = policy.producerId === LIFECYCLE_PRODUCER
681
703
  ? probeLifecycleFailure(taskRef, policy, resolved, options)
682
- : probeGenericFailure(taskRef, policy, resolved, options);
704
+ : await probeGenericFailure(taskRef, policy, resolved, options);
683
705
  if (!isProducerFailure(producer))
684
706
  return producer;
685
707
  const digest = computeFailureDigest(snapshotEvidence(resolved.taskId, failureIdValue, target, content, frontmatter, producer, resourceForSnapshot(policy, options, frontmatter)));
@@ -736,7 +758,7 @@ function validateResourceNumbers(request) {
736
758
  }
737
759
  return null;
738
760
  }
739
- function issueHumanOverride(request, options = {}) {
761
+ async function issueHumanOverride(request, options = {}) {
740
762
  const invalid = validateCommon(request);
741
763
  if (invalid)
742
764
  return failedIssue(invalid.code, invalid.message);
@@ -765,7 +787,7 @@ function issueHumanOverride(request, options = {}) {
765
787
  return failedIssue(document.code, document.message, resolved.taskId);
766
788
  if (document.frontmatter.id !== resolved.taskId)
767
789
  return failedIssue('OVERRIDE_DOCUMENT_INVALID', 'task frontmatter id does not match resolved task', resolved.taskId);
768
- const snapshotResult = captureFailureSnapshot(request.taskRef, request.failureId, request.target, {
790
+ const snapshotResult = await captureFailureSnapshot(request.taskRef, request.failureId, request.target, {
769
791
  ...options,
770
792
  probeIntent: request.intent,
771
793
  probeOperator: request.operator,
@@ -891,14 +913,14 @@ function lifecycleRequestFor(taskRef, intent, operator, reason, values = {}) {
891
913
  return error('OVERRIDE_EFFECT_INPUT_MISSING', 'restore requires the original staging directory and issue number');
892
914
  return { taskRef, intent: 'restore', agent: operator, stagingDir, issueNumber };
893
915
  }
894
- function applyOutcomeEffect(request, row, snapshot, outcome, options) {
916
+ async function applyOutcomeEffect(request, row, snapshot, outcome, options) {
895
917
  if (outcome.effect === 'no-write' || outcome.effect === 'record-only')
896
918
  return null;
897
919
  const intent = outcome.target === 'safe-close' ? 'cancel' : row.intent || request.intent;
898
920
  if (!intent && outcome.target === 'continue-local') {
899
921
  if (!options.effectExecutor)
900
922
  return error('OVERRIDE_EFFECT_EXECUTOR_MISSING', 'the producer must supply an effect executor for a continue-local outcome');
901
- return options.effectExecutor({
923
+ return await options.effectExecutor({
902
924
  failureId: request.failureId,
903
925
  operator: row.operator ?? 'local-operator',
904
926
  reason: row.reason ?? snapshot.message
@@ -991,7 +1013,7 @@ function snapshotFromTicket(taskId, row) {
991
1013
  source: 'producer-result'
992
1014
  };
993
1015
  }
994
- function consumeHumanOverride(request, options = {}) {
1016
+ async function consumeHumanOverride(request, options = {}) {
995
1017
  const values = [request.taskRef, request.ticketId, request.failureId, request.target, request.scope];
996
1018
  if (values.some((value) => !singleLine(value))) {
997
1019
  return failedConsume('OVERRIDE_PAYLOAD_INVALID', 'consume fields must be non-empty single-line values', request.ticketId || null);
@@ -1043,7 +1065,7 @@ function consumeHumanOverride(request, options = {}) {
1043
1065
  snapshot = recoverySnapshot;
1044
1066
  }
1045
1067
  else {
1046
- const snapshotResult = captureFailureSnapshot(request.taskRef, request.failureId, request.target, {
1068
+ const snapshotResult = await captureFailureSnapshot(request.taskRef, request.failureId, request.target, {
1047
1069
  ...options,
1048
1070
  probeIntent: row.values.intent ? row.values.intent : request.intent,
1049
1071
  probeOperator: row.values.operator,
@@ -1097,7 +1119,7 @@ function consumeHumanOverride(request, options = {}) {
1097
1119
  return failedConsume('OVERRIDE_WRITE_INVALID', 'override writes cannot be planned', request.ticketId, resolved.taskId);
1098
1120
  effectRow = { ...row.values, status: 'consuming', effect: outcome.effect, result: outcome.result, context_id: outcome.contextId, residual: `effect pending: ${outcome.residual}` };
1099
1121
  }
1100
- const effectError = applyOutcomeEffect(request, effectRow, snapshot, outcome, options);
1122
+ const effectError = await applyOutcomeEffect(request, effectRow, snapshot, outcome, options);
1101
1123
  if (effectError)
1102
1124
  return failedConsume(effectError.code, effectError.message, request.ticketId, resolved.taskId);
1103
1125
  const after = resolveTask(request.taskRef, options);
@@ -1137,7 +1159,7 @@ function diagnoseHumanOverride(failure, target) {
1137
1159
  error: null
1138
1160
  };
1139
1161
  }
1140
- function diagnoseHumanOverrideForTask(taskRef, failure, target, options = {}) {
1162
+ async function diagnoseHumanOverrideForTask(taskRef, failure, target, options = {}) {
1141
1163
  const resolved = resolveTask(taskRef, options);
1142
1164
  if (!resolved.ok) {
1143
1165
  return {
@@ -1176,12 +1198,12 @@ function diagnoseHumanOverrideForTask(taskRef, failure, target, options = {}) {
1176
1198
  error: error('OVERRIDE_FAILURE_UNKNOWN', `failure policy '${failure}' is not registered`)
1177
1199
  };
1178
1200
  }
1179
- const probes = policies
1201
+ const probes = await Promise.all(policies
1180
1202
  .filter((policy) => !target || policy.targets.includes(target))
1181
- .map((policy) => {
1203
+ .map(async (policy) => {
1182
1204
  const producer = policy.producerId === LIFECYCLE_PRODUCER
1183
1205
  ? probeLifecycleFailure(taskRef, policy, resolved, options)
1184
- : probeGenericFailure(taskRef, policy, resolved, options);
1206
+ : await probeGenericFailure(taskRef, policy, resolved, options);
1185
1207
  const observed = isProducerFailure(producer);
1186
1208
  return {
1187
1209
  failureId: policy.id,
@@ -1195,7 +1217,7 @@ function diagnoseHumanOverrideForTask(taskRef, failure, target, options = {}) {
1195
1217
  message: observed ? producer.message : producer.message,
1196
1218
  errorCode: observed ? null : producer.code
1197
1219
  };
1198
- });
1220
+ }));
1199
1221
  const blockedBy = probes.filter((probe) => probe.status === 'observed');
1200
1222
  return {
1201
1223
  status: 'ready',
@@ -1,3 +1,4 @@
1
+ import { PUBLIC_CLI_ROUTE_SELECTORS, PUBLIC_CLI_SELECTOR_ALIASES } from '../internal/cli-route-inventory.js';
1
2
  const USAGE = `Usage: ai task <command> [options]
2
3
 
3
4
  Commands:
@@ -30,6 +31,7 @@ Examples:
30
31
  ai task status --task 11
31
32
 
32
33
  Run 'ai task <command> --help' for details.`;
34
+ const TASK_OPERATIONS = PUBLIC_CLI_ROUTE_SELECTORS.task;
33
35
  export async function runTask(args) {
34
36
  const [subcommand, ...rest] = args;
35
37
  if (!subcommand) {
@@ -41,14 +43,20 @@ export async function runTask(args) {
41
43
  process.stdout.write(`${USAGE}\n`);
42
44
  return;
43
45
  }
44
- switch (subcommand) {
46
+ const routeSelector = PUBLIC_CLI_SELECTOR_ALIASES.task[subcommand] ?? subcommand;
47
+ if (!TASK_OPERATIONS.includes(routeSelector)) {
48
+ process.stderr.write(`Unknown task command: ${subcommand}\n\n`);
49
+ process.stdout.write(`${USAGE}\n`);
50
+ process.exitCode = 1;
51
+ return;
52
+ }
53
+ switch (routeSelector) {
45
54
  case 'cat': {
46
55
  const { cat } = await import('./commands/cat.js');
47
56
  cat(rest);
48
57
  break;
49
58
  }
50
- case 'decisions':
51
- case 'd': {
59
+ case 'decisions': {
52
60
  const { decisions } = await import('./commands/decisions.js');
53
61
  decisions(rest);
54
62
  break;
@@ -0,0 +1,86 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { parseArtifactReceipts, sha256File } from './artifact-receipts.js';
4
+ import { invalidationMutation, parseInvalidationDocument, reconcileInvalidation } from './invalidation.js';
5
+ import { resolveTaskRef } from './resolve-ref.js';
6
+ import { writeTask } from './write.js';
7
+ function reconcileTaskInvalidation(taskRef, options = {}) {
8
+ const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
9
+ if (!resolved.ok)
10
+ return { status: 'failed', changed: false, taskId: resolved.taskId, processed: 0, remaining: 0, error: { code: resolved.code, message: resolved.message } };
11
+ let content;
12
+ try {
13
+ content = fs.readFileSync(resolved.taskMdPath, 'utf8');
14
+ }
15
+ catch (error) {
16
+ return { status: 'failed', changed: false, taskId: resolved.taskId, processed: 0, remaining: 0, error: { code: 'TASK_READ_FAILED', message: error instanceof Error ? error.message : String(error) } };
17
+ }
18
+ const parsed = parseInvalidationDocument(content);
19
+ if (!parsed.ok)
20
+ return { status: 'failed', changed: false, taskId: resolved.taskId, processed: 0, remaining: 0, error: { code: parsed.code, message: parsed.message } };
21
+ if (!parsed.present)
22
+ return { status: 'no-op', changed: false, taskId: resolved.taskId, processed: 0, remaining: 0, error: null };
23
+ const beforePending = parsed.document.targets.filter((target) => target.status !== 'completed').length;
24
+ let receipts;
25
+ try {
26
+ receipts = parseArtifactReceipts(content).rows;
27
+ }
28
+ catch (error) {
29
+ if (parsed.document.targets.some((target) => target.status !== 'completed' && target.targetKind === 'receipt')) {
30
+ return {
31
+ status: 'failed', changed: false, taskId: resolved.taskId, processed: 0, remaining: beforePending,
32
+ error: { code: 'INVALIDATION_TARGET_HASH_CONFLICT', message: error instanceof Error ? error.message : String(error) }
33
+ };
34
+ }
35
+ receipts = [];
36
+ }
37
+ for (const target of parsed.document.targets) {
38
+ if (target.status === 'completed')
39
+ continue;
40
+ if (target.targetKind === 'receipt') {
41
+ const receipt = receipts.find((candidate) => candidate.output === target.targetArtifact);
42
+ if (!receipt || receipt.inputSha256 !== target.targetSha256) {
43
+ return {
44
+ status: 'failed', changed: false, taskId: resolved.taskId, processed: 0, remaining: beforePending,
45
+ error: { code: 'INVALIDATION_TARGET_HASH_CONFLICT', message: `invalidation receipt target '${target.targetArtifact}' changed before reconcile` }
46
+ };
47
+ }
48
+ continue;
49
+ }
50
+ const targetPath = path.join(resolved.taskDir, target.targetArtifact);
51
+ try {
52
+ const stat = fs.lstatSync(targetPath);
53
+ if (!stat.isFile() || stat.isSymbolicLink() || sha256File(targetPath) !== target.targetSha256) {
54
+ return {
55
+ status: 'failed', changed: false, taskId: resolved.taskId, processed: 0, remaining: beforePending,
56
+ error: { code: 'INVALIDATION_TARGET_HASH_CONFLICT', message: `invalidation target '${target.targetArtifact}' changed before reconcile` }
57
+ };
58
+ }
59
+ }
60
+ catch {
61
+ return {
62
+ status: 'failed', changed: false, taskId: resolved.taskId, processed: 0, remaining: beforePending,
63
+ error: { code: 'INVALIDATION_TARGET_HASH_CONFLICT', message: `invalidation target '${target.targetArtifact}' is unavailable before reconcile` }
64
+ };
65
+ }
66
+ }
67
+ const reconciled = reconcileInvalidation(parsed.document, (options.now ?? (() => new Date().toISOString()))(), options.maxTargets);
68
+ if (!reconciled.ok)
69
+ return { status: 'failed', changed: false, taskId: resolved.taskId, processed: 0, remaining: beforePending, error: { code: reconciled.code, message: reconciled.message } };
70
+ if (!reconciled.changed)
71
+ return { status: 'no-op', changed: false, taskId: resolved.taskId, processed: 0, remaining: beforePending, error: null };
72
+ const result = writeTask({
73
+ taskRef, expectedState: resolved.state, dryRun: options.dryRun,
74
+ mutations: [invalidationMutation(content, reconciled.document)]
75
+ }, { ...options, invalidationContext: 'reconcile', taskLocation: { repoRoot: resolved.repoRoot, taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, state: resolved.state } });
76
+ if (result.status === 'failed')
77
+ return { status: 'failed', changed: false, taskId: resolved.taskId, processed: beforePending - reconciled.document.targets.filter((target) => target.status !== 'completed').length, remaining: reconciled.document.targets.filter((target) => target.status !== 'completed').length, error: result.error };
78
+ return {
79
+ status: result.status, changed: result.changed, taskId: resolved.taskId,
80
+ processed: beforePending - reconciled.document.targets.filter((target) => target.status !== 'completed').length,
81
+ remaining: reconciled.document.targets.filter((target) => target.status !== 'completed').length,
82
+ error: null
83
+ };
84
+ }
85
+ export { reconcileTaskInvalidation };
86
+ //# sourceMappingURL=invalidation-command.js.map