@fitlab-ai/agent-infra 0.9.11 → 0.9.13

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 (356) hide show
  1. package/README.md +13 -13
  2. package/README.zh-CN.md +13 -13
  3. package/dist/bin/internal-cli.js +29 -19
  4. package/dist/lib/agent-clients/adapters/codex-lifecycle/build-identity.js +71 -10
  5. package/dist/lib/agent-clients/next-steps.js +6 -1
  6. package/dist/lib/decide.js +3 -3
  7. package/dist/lib/defaults.json +4 -0
  8. package/dist/lib/git/workflow.js +43 -1
  9. package/dist/lib/init.js +1 -0
  10. package/dist/lib/internal/git-workflow.js +8 -1
  11. package/dist/lib/internal/platform-checks.js +3 -3
  12. package/dist/lib/internal/platform-comment.js +9 -9
  13. package/dist/lib/internal/platform-context.js +2 -2
  14. package/dist/lib/internal/platform-issue.js +8 -9
  15. package/dist/lib/internal/platform-pr-review.js +10 -10
  16. package/dist/lib/internal/platform-pr.js +68 -23
  17. package/dist/lib/internal/platform-release-notes.js +3 -3
  18. package/dist/lib/internal/pr-review-grade.js +11 -9
  19. package/dist/lib/internal/release-workflow.js +4 -4
  20. package/dist/lib/internal/sandbox-control.js +30 -4
  21. package/dist/lib/internal/task-activity.js +3 -3
  22. package/dist/lib/internal/task-artifact.js +76 -24
  23. package/dist/lib/internal/task-create.js +2 -2
  24. package/dist/lib/internal/task-delivery.js +59 -0
  25. package/dist/lib/internal/task-event.js +6 -3
  26. package/dist/lib/internal/task-finalization.js +2 -2
  27. package/dist/lib/internal/task-invalidation.js +60 -0
  28. package/dist/lib/internal/task-ledger.js +9 -6
  29. package/dist/lib/internal/task-lifecycle.js +2 -2
  30. package/dist/lib/internal/task-override.js +4 -4
  31. package/dist/lib/internal/task-review.js +3 -3
  32. package/dist/lib/internal/task-verify.js +6 -6
  33. package/dist/lib/internal/task-warning.js +3 -3
  34. package/dist/lib/platform/adapters.js +1 -3
  35. package/dist/lib/platform/change-request-git-evidence.js +27 -7
  36. package/dist/lib/platform/completion-backfill.js +6 -5
  37. package/dist/lib/platform/context.js +70 -130
  38. package/dist/lib/platform/github-client.js +8 -2
  39. package/dist/lib/platform/github-provider.js +903 -0
  40. package/dist/lib/platform/in-label-sync.js +143 -0
  41. package/dist/lib/platform/issue-comments.js +94 -41
  42. package/dist/lib/platform/issues.js +335 -189
  43. package/dist/lib/platform/metadata-labels.js +6 -2
  44. package/dist/lib/platform/none-provider.js +28 -0
  45. package/dist/lib/platform/pr-change-report.js +551 -0
  46. package/dist/lib/platform/pr-checks.js +124 -106
  47. package/dist/lib/platform/pr-review.js +88 -72
  48. package/dist/lib/platform/pr-summary.js +523 -49
  49. package/dist/lib/platform/provider-bridge.js +45 -0
  50. package/dist/lib/platform/provider-contract.d.ts +487 -0
  51. package/dist/lib/platform/provider-contract.js +95 -0
  52. package/dist/lib/platform/provider-loader.js +251 -0
  53. package/dist/lib/platform/provider-validation.js +504 -0
  54. package/dist/lib/platform/pull-request-metadata.js +8 -6
  55. package/dist/lib/platform/pull-requests.js +1050 -502
  56. package/dist/lib/platform/release-notes.js +78 -55
  57. package/dist/lib/platform/releases.js +79 -50
  58. package/dist/lib/platform/resource-identity.d.ts +26 -0
  59. package/dist/lib/platform/resource-identity.js +92 -0
  60. package/dist/lib/platform/task-identities.js +31 -0
  61. package/dist/lib/platform/verification-required.js +22 -12
  62. package/dist/lib/platform/verification-sync.js +118 -239
  63. package/dist/lib/pr-review/evidence-grading.js +30 -9
  64. package/dist/lib/run/index.js +63 -23
  65. package/dist/lib/sandbox/config.js +5 -0
  66. package/dist/lib/sandbox/control/client.js +96 -15
  67. package/dist/lib/sandbox/control/executor.js +3 -3
  68. package/dist/lib/sandbox/control/lifecycle.js +29 -7
  69. package/dist/lib/sandbox/control/protocol.js +77 -0
  70. package/dist/lib/sandbox/control/server.js +398 -25
  71. package/dist/lib/sandbox/control/state.js +204 -1
  72. package/dist/lib/server/process-state.js +2 -2
  73. package/dist/lib/server/protocol.js +38 -1
  74. package/dist/lib/task/activity-log.js +8 -1
  75. package/dist/lib/task/artifact-lifecycle.js +35 -7
  76. package/dist/lib/task/capabilities.js +239 -0
  77. package/dist/lib/task/commands/status.js +32 -0
  78. package/dist/lib/task/commit-intent.js +100 -0
  79. package/dist/lib/task/commit-operation.js +207 -102
  80. package/dist/lib/task/control-authority.js +8 -5
  81. package/dist/lib/task/create-service.js +8 -8
  82. package/dist/lib/task/create.js +33 -7
  83. package/dist/lib/task/current-contract.js +5 -1
  84. package/dist/lib/task/decision-details.js +3 -48
  85. package/dist/lib/task/delivery-target.js +97 -0
  86. package/dist/lib/task/delivery.js +153 -0
  87. package/dist/lib/task/events.js +297 -17
  88. package/dist/lib/task/finalization.js +37 -13
  89. package/dist/lib/task/human-override.js +61 -36
  90. package/dist/lib/task/invalidation-command.js +86 -0
  91. package/dist/lib/task/invalidation.js +260 -0
  92. package/dist/lib/task/ledger-intents.js +37 -0
  93. package/dist/lib/task/lifecycle.js +106 -9
  94. package/dist/lib/task/local-artifact-finalization.js +374 -0
  95. package/dist/lib/task/orchestration.js +100 -151
  96. package/dist/lib/task/pr-delivery-fact.js +183 -0
  97. package/dist/lib/task/review-finalization.js +4 -8
  98. package/dist/lib/task/review-fingerprint.js +32 -2
  99. package/dist/lib/task/rework-intent.js +138 -0
  100. package/dist/lib/task/skill-scope.js +23 -0
  101. package/dist/lib/task/task-execution-lock.js +27 -17
  102. package/dist/lib/task/verification-engine.js +89 -38
  103. package/dist/lib/task/verification-review.js +1 -1
  104. package/dist/lib/task/verification.js +3 -3
  105. package/dist/lib/task/workflow-warning-intents.js +1 -1
  106. package/dist/lib/task/write.js +11 -0
  107. package/dist/lib/update.js +9 -0
  108. package/dist/lib/version.js +11 -1
  109. package/dist/lifecycle-build-manifest.json +3 -3
  110. package/lib/agent-clients/adapters/codex-lifecycle/build-identity.ts +105 -10
  111. package/lib/agent-clients/adapters/codex-lifecycle/manifest-files.json +12 -1
  112. package/lib/agent-clients/next-steps.ts +6 -1
  113. package/lib/decide.ts +3 -3
  114. package/lib/defaults.json +4 -0
  115. package/lib/git/workflow.ts +38 -1
  116. package/lib/init.ts +4 -1
  117. package/lib/internal/git-workflow.ts +7 -1
  118. package/lib/internal/platform-checks.ts +3 -3
  119. package/lib/internal/platform-comment.ts +8 -8
  120. package/lib/internal/platform-context.ts +2 -2
  121. package/lib/internal/platform-issue.ts +7 -8
  122. package/lib/internal/platform-pr-review.ts +9 -9
  123. package/lib/internal/platform-pr.ts +53 -21
  124. package/lib/internal/platform-release-notes.ts +3 -3
  125. package/lib/internal/pr-review-grade.ts +10 -8
  126. package/lib/internal/release-workflow.ts +4 -4
  127. package/lib/internal/sandbox-control.ts +27 -3
  128. package/lib/internal/task-activity.ts +3 -3
  129. package/lib/internal/task-artifact.ts +65 -22
  130. package/lib/internal/task-create.ts +2 -2
  131. package/lib/internal/task-delivery.ts +53 -0
  132. package/lib/internal/task-event.ts +6 -3
  133. package/lib/internal/task-finalization.ts +3 -3
  134. package/lib/internal/task-invalidation.ts +39 -0
  135. package/lib/internal/task-ledger.ts +11 -8
  136. package/lib/internal/task-lifecycle.ts +2 -2
  137. package/lib/internal/task-override.ts +6 -6
  138. package/lib/internal/task-review.ts +3 -3
  139. package/lib/internal/task-verify.ts +6 -6
  140. package/lib/internal/task-warning.ts +3 -3
  141. package/lib/platform/adapters.ts +3 -2
  142. package/lib/platform/change-request-git-evidence.ts +36 -9
  143. package/lib/platform/completion-backfill.ts +9 -8
  144. package/lib/platform/context.ts +97 -134
  145. package/lib/platform/github-client.ts +10 -3
  146. package/lib/platform/github-provider.ts +910 -0
  147. package/lib/platform/in-label-sync.ts +208 -0
  148. package/lib/platform/issue-comments.ts +97 -47
  149. package/lib/platform/issues.ts +344 -174
  150. package/lib/platform/metadata-labels.ts +5 -2
  151. package/lib/platform/none-provider.ts +35 -0
  152. package/lib/platform/pr-change-report.ts +645 -0
  153. package/lib/platform/pr-checks.ts +129 -107
  154. package/lib/platform/pr-review.ts +88 -85
  155. package/lib/platform/pr-summary.ts +562 -52
  156. package/lib/platform/provider-bridge.ts +82 -0
  157. package/lib/platform/provider-contract.ts +536 -0
  158. package/lib/platform/provider-loader.ts +307 -0
  159. package/lib/platform/provider-validation.ts +529 -0
  160. package/lib/platform/pull-request-metadata.ts +10 -7
  161. package/lib/platform/pull-requests.ts +1126 -505
  162. package/lib/platform/release-notes.ts +76 -59
  163. package/lib/platform/releases.ts +77 -43
  164. package/lib/platform/resource-identity.ts +121 -0
  165. package/lib/platform/task-identities.ts +40 -0
  166. package/lib/platform/types.ts +4 -2
  167. package/lib/platform/verification-required.ts +21 -13
  168. package/lib/platform/verification-sync.ts +118 -293
  169. package/lib/pr-review/evidence-grading.ts +31 -11
  170. package/lib/run/index.ts +57 -22
  171. package/lib/sandbox/config.ts +7 -0
  172. package/lib/sandbox/control/client.ts +105 -15
  173. package/lib/sandbox/control/executor.ts +4 -4
  174. package/lib/sandbox/control/lifecycle.ts +30 -8
  175. package/lib/sandbox/control/protocol.ts +113 -0
  176. package/lib/sandbox/control/server.ts +431 -23
  177. package/lib/sandbox/control/state.ts +251 -1
  178. package/lib/server/process-state.ts +2 -2
  179. package/lib/server/protocol.ts +36 -1
  180. package/lib/task/activity-log.ts +8 -0
  181. package/lib/task/artifact-lifecycle.ts +34 -8
  182. package/lib/task/capabilities.ts +262 -0
  183. package/lib/task/commands/status.ts +38 -0
  184. package/lib/task/commit-intent.ts +137 -0
  185. package/lib/task/commit-operation.ts +186 -88
  186. package/lib/task/control-authority.ts +11 -8
  187. package/lib/task/create-service.ts +8 -8
  188. package/lib/task/create.ts +34 -9
  189. package/lib/task/current-contract.ts +6 -1
  190. package/lib/task/decision-details.ts +8 -64
  191. package/lib/task/delivery-target.ts +130 -0
  192. package/lib/task/delivery.ts +160 -0
  193. package/lib/task/events.ts +296 -16
  194. package/lib/task/finalization.ts +50 -14
  195. package/lib/task/human-override.ts +73 -46
  196. package/lib/task/invalidation-command.ts +86 -0
  197. package/lib/task/invalidation.ts +332 -0
  198. package/lib/task/ledger-intents.ts +35 -1
  199. package/lib/task/lifecycle.ts +93 -4
  200. package/lib/task/local-artifact-finalization.ts +563 -0
  201. package/lib/task/orchestration.ts +110 -146
  202. package/lib/task/pr-delivery-fact.ts +237 -0
  203. package/lib/task/review-finalization.ts +4 -14
  204. package/lib/task/review-fingerprint.ts +33 -2
  205. package/lib/task/rework-intent.ts +165 -0
  206. package/lib/task/skill-scope.ts +24 -0
  207. package/lib/task/task-execution-lock.ts +23 -14
  208. package/lib/task/verification-engine.ts +95 -43
  209. package/lib/task/verification-review.ts +2 -0
  210. package/lib/task/verification.ts +4 -4
  211. package/lib/task/workflow-warning-intents.ts +1 -1
  212. package/lib/task/write.ts +19 -0
  213. package/lib/update.ts +11 -1
  214. package/lib/version.ts +15 -1
  215. package/package.json +7 -1
  216. package/templates/.agents/rules/README.en.md +4 -2
  217. package/templates/.agents/rules/README.zh-CN.md +4 -2
  218. package/templates/.agents/rules/create-issue.en.md +11 -2
  219. package/templates/.agents/rules/create-issue.zh-CN.md +24 -2
  220. package/templates/.agents/rules/issue-pr-commands.en.md +4 -17
  221. package/templates/.agents/rules/issue-pr-commands.zh-CN.md +1 -1
  222. package/templates/.agents/rules/issue-sync.en.md +28 -5
  223. package/templates/.agents/rules/issue-sync.zh-CN.md +64 -5
  224. package/templates/.agents/rules/label-milestone-setup.en.md +15 -2
  225. package/templates/.agents/rules/label-milestone-setup.zh-CN.md +15 -2
  226. package/templates/.agents/rules/local-artifact-repair.en.md +53 -0
  227. package/templates/.agents/rules/local-artifact-repair.zh-CN.md +53 -0
  228. package/templates/.agents/rules/milestone-inference.en.md +12 -2
  229. package/templates/.agents/rules/milestone-inference.zh-CN.md +25 -3
  230. package/templates/.agents/rules/pr-sync.en.md +28 -13
  231. package/templates/.agents/rules/pr-sync.zh-CN.md +39 -5
  232. package/templates/.agents/rules/release-commands.en.md +42 -3
  233. package/templates/.agents/rules/release-commands.zh-CN.md +42 -3
  234. package/templates/.agents/rules/security-alerts.en.md +17 -2
  235. package/templates/.agents/rules/security-alerts.zh-CN.md +17 -2
  236. package/templates/.agents/rules/sync-content-generation.en.md +8 -0
  237. package/templates/.agents/rules/sync-content-generation.zh-CN.md +8 -0
  238. package/templates/.agents/rules/task-management.en.md +1 -1
  239. package/templates/.agents/rules/task-management.zh-CN.md +1 -1
  240. package/templates/.agents/rules/task-short-id.en.md +1 -4
  241. package/templates/.agents/rules/task-short-id.zh-CN.md +1 -3
  242. package/templates/.agents/scripts/security-alerts.github.sh +151 -0
  243. package/templates/.agents/scripts/security-alerts.sh +31 -0
  244. package/templates/.agents/skills/analyze-task/SKILL.en.md +14 -3
  245. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +11 -3
  246. package/templates/.agents/skills/check-task/SKILL.en.md +16 -37
  247. package/templates/.agents/skills/check-task/SKILL.zh-CN.md +16 -37
  248. package/templates/.agents/skills/close-codescan/SKILL.en.md +2 -2
  249. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +2 -2
  250. package/templates/.agents/skills/close-dependabot/SKILL.en.md +2 -2
  251. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +2 -2
  252. package/templates/.agents/skills/code-task/SKILL.en.md +32 -10
  253. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +35 -13
  254. package/templates/.agents/skills/code-task/config/verify.en.json +1 -0
  255. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +1 -0
  256. package/templates/.agents/skills/commit/SKILL.en.md +3 -3
  257. package/templates/.agents/skills/commit/SKILL.zh-CN.md +3 -3
  258. package/templates/.agents/skills/commit/config/verify.json +1 -1
  259. package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +3 -3
  260. package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +3 -3
  261. package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +2 -0
  262. package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +2 -0
  263. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +4 -4
  264. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +4 -4
  265. package/templates/.agents/skills/commit/reference/task-status-update.en.md +2 -2
  266. package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +2 -2
  267. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +7 -4
  268. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +7 -4
  269. package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -1
  270. package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -1
  271. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +5 -4
  272. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +5 -4
  273. package/templates/.agents/skills/complete-task/SKILL.en.md +31 -13
  274. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +30 -13
  275. package/templates/.agents/skills/complete-task/reference/external-delivery.en.md +2 -2
  276. package/templates/.agents/skills/complete-task/reference/external-delivery.zh-CN.md +2 -2
  277. package/templates/.agents/skills/create-pr/SKILL.en.md +11 -10
  278. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +11 -11
  279. package/templates/.agents/skills/create-pr/config/verify.json +1 -0
  280. package/templates/.agents/skills/create-pr/reference/change-report.en.md +16 -4
  281. package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +16 -4
  282. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +5 -3
  283. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +5 -3
  284. package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +1 -1
  285. package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +1 -1
  286. package/templates/.agents/skills/create-pr/scripts/change-report.mjs +3 -0
  287. package/templates/.agents/skills/create-task/SKILL.en.md +1 -0
  288. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +1 -0
  289. package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
  290. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
  291. package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
  292. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
  293. package/templates/.agents/skills/init-labels/SKILL.en.md +9 -10
  294. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +9 -10
  295. package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +57 -1
  296. package/templates/.agents/skills/init-labels/scripts/init-labels.sh +27 -1
  297. package/templates/.agents/skills/init-milestones/SKILL.en.md +3 -5
  298. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +3 -5
  299. package/templates/.agents/skills/plan-task/SKILL.en.md +14 -3
  300. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +11 -3
  301. package/templates/.agents/skills/review-analysis/SKILL.en.md +6 -5
  302. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +6 -5
  303. package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +18 -0
  304. package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +18 -0
  305. package/templates/.agents/skills/review-code/SKILL.en.md +10 -9
  306. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +10 -9
  307. package/templates/.agents/skills/review-code/reference/output-templates.en.md +19 -1
  308. package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +19 -1
  309. package/templates/.agents/skills/review-code/reference/report-template.en.md +4 -2
  310. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +4 -2
  311. package/templates/.agents/skills/review-plan/SKILL.en.md +6 -5
  312. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +6 -5
  313. package/templates/.agents/skills/review-plan/reference/output-templates.en.md +18 -0
  314. package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +18 -0
  315. package/templates/.agents/skills/review-pr/SKILL.en.md +1 -0
  316. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +1 -0
  317. package/templates/.agents/skills/review-pr/reference/evidence-grading.en.md +2 -2
  318. package/templates/.agents/skills/review-pr/reference/evidence-grading.zh-CN.md +2 -2
  319. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +5 -2
  320. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +5 -2
  321. package/templates/.agents/skills/run-task/SKILL.en.md +1 -1
  322. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +1 -1
  323. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +4 -0
  324. package/templates/.agents/skills/watch-pr/SKILL.en.md +6 -6
  325. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +6 -6
  326. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +6 -0
  327. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +6 -0
  328. package/templates/.agents/templates/task.en.md +23 -2
  329. package/templates/.agents/templates/task.zh-CN.md +23 -2
  330. package/templates/.agents/workflows/bug-fix.en.yaml +9 -8
  331. package/templates/.agents/workflows/bug-fix.zh-CN.yaml +9 -8
  332. package/templates/.agents/workflows/feature-development.en.yaml +9 -8
  333. package/templates/.agents/workflows/feature-development.zh-CN.yaml +9 -8
  334. package/templates/.agents/workflows/refactoring.en.yaml +9 -8
  335. package/templates/.agents/workflows/refactoring.zh-CN.yaml +9 -8
  336. package/templates/.github/workflows/pr-label.yml +7 -26
  337. package/templates/.agents/rules/create-issue.github.en.md +0 -14
  338. package/templates/.agents/rules/create-issue.github.zh-CN.md +0 -27
  339. package/templates/.agents/rules/issue-pr-commands.github.en.md +0 -34
  340. package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +0 -49
  341. package/templates/.agents/rules/issue-sync.github.en.md +0 -40
  342. package/templates/.agents/rules/issue-sync.github.zh-CN.md +0 -76
  343. package/templates/.agents/rules/label-milestone-setup.github.en.md +0 -60
  344. package/templates/.agents/rules/label-milestone-setup.github.zh-CN.md +0 -60
  345. package/templates/.agents/rules/milestone-inference.github.en.md +0 -15
  346. package/templates/.agents/rules/milestone-inference.github.zh-CN.md +0 -27
  347. package/templates/.agents/rules/pr-checks-commands.github.en.md +0 -18
  348. package/templates/.agents/rules/pr-checks-commands.github.zh-CN.md +0 -34
  349. package/templates/.agents/rules/pr-sync.github.en.md +0 -43
  350. package/templates/.agents/rules/pr-sync.github.zh-CN.md +0 -69
  351. package/templates/.agents/rules/release-commands.github.en.md +0 -44
  352. package/templates/.agents/rules/release-commands.github.zh-CN.md +0 -44
  353. package/templates/.agents/rules/security-alerts.github.en.md +0 -43
  354. package/templates/.agents/rules/security-alerts.github.zh-CN.md +0 -43
  355. /package/templates/.agents/rules/{issue-fields.github.en.md → issue-fields.en.md} +0 -0
  356. /package/templates/.agents/rules/{issue-fields.github.zh-CN.md → issue-fields.zh-CN.md} +0 -0
@@ -7,6 +7,8 @@ import { fileURLToPath } from "node:url";
7
7
 
8
8
  import {
9
9
  extractReviewBaseline,
10
+ extractReviewTargetHead,
11
+ extractReviewedHead,
10
12
  extractReviewDiffBase,
11
13
  extractReviewDiffFingerprint,
12
14
  extractReviewedSnapshotTree,
@@ -30,6 +32,9 @@ import { inspectDecisionDetailDuplicates } from "./decision-details.ts";
30
32
  import { loadVerificationConfig } from "./verification-config.ts";
31
33
  import { snapshotReview } from "../git/review-snapshot.ts";
32
34
  import { OrchestrationStateError, readRun } from "./orchestration.ts";
35
+ import { resolveDeliveryTarget } from "./delivery-target.ts";
36
+ import { readPrDeliveryFact } from "./pr-delivery-fact.ts";
37
+ import { validateLocalArtifact } from "./local-artifact-finalization.ts";
33
38
 
34
39
  const TASK_ENUMS = {
35
40
  type: ["feature", "bugfix", "refactor", "docs", "chore"],
@@ -84,7 +89,7 @@ let repoRoot = path.resolve(path.dirname(scriptPath), "..", "..");
84
89
 
85
90
  const PLATFORM_ADAPTERS: Record<string, (context: any, shared: any) => any> = {
86
91
  "platform-sync": checkPlatformSync,
87
- "platform-sync-preflight": (context: any, shared: any) => ({ ...checkPlatformSync(context, shared), type: "platform-sync-preflight" }),
92
+ "platform-sync-preflight": async (context: any, shared: any) => ({ ...await checkPlatformSync(context, shared), type: "platform-sync-preflight" }),
88
93
  "required-checks": checkRequiredChecks
89
94
  };
90
95
  const OPTIONAL_PLATFORM_CHECKS = new Set(["platform-sync"]);
@@ -103,7 +108,7 @@ const sharedUtils = {
103
108
  parsePrNumber
104
109
  };
105
110
 
106
- function runCheck(type: any, context: any, shared: any): any {
111
+ async function runCheck(type: any, context: any, shared: any): Promise<any> {
107
112
  switch (type) {
108
113
  case "task-meta":
109
114
  return checkTaskMeta(context);
@@ -143,7 +148,7 @@ function runCheck(type: any, context: any, shared: any): any {
143
148
  return failResult(type, `Unsupported check type '${type}'.`);
144
149
  }
145
150
 
146
- return adapter(context, shared);
151
+ return await adapter(context, shared);
147
152
  }
148
153
  }
149
154
  }
@@ -195,15 +200,14 @@ function validateCleanCompletionEvidence(run: any): string | null {
195
200
  || !shaPattern.test(evidence.headTree)
196
201
  || !shaPattern.test(evidence.worktreeTree)
197
202
  || !shaPattern.test(evidence.lastReviewedCommit)
198
- || !Number.isInteger(evidence.prNumber)
199
- || evidence.prNumber <= 0
200
- || !shaPattern.test(evidence.prHead)
203
+ || !(evidence.prNumber === null || (Number.isInteger(evidence.prNumber) && evidence.prNumber > 0))
204
+ || !(evidence.prHead === null || shaPattern.test(evidence.prHead))
201
205
  ) {
202
206
  return 'Clean completion evidence has an invalid structure';
203
207
  }
204
208
  if (
205
209
  evidence.head !== evidence.lastReviewedCommit
206
- || evidence.head !== evidence.prHead
210
+ || (evidence.prHead !== null && evidence.head !== evidence.prHead)
207
211
  || evidence.headTree !== evidence.worktreeTree
208
212
  ) {
209
213
  return 'Clean completion evidence does not bind matching commit and tree identities';
@@ -276,12 +280,8 @@ function checkOrchestrationEvidence({ taskDir }: any): any {
276
280
  if (run.completionEvidence != null) {
277
281
  const evidenceError = validateCleanCompletionEvidence(run);
278
282
  if (evidenceError) return failResult('orchestration-evidence', evidenceError);
279
- } else if (run.status === 'completed' && (
280
- run.receipts.length === 0
281
- || run.receipts.at(-1)?.stage !== 'commit'
282
- || run.receipts.at(-1)?.status !== 'consumed'
283
- )) {
284
- return failResult('orchestration-evidence', 'Completed run requires a final consumed commit receipt');
283
+ } else if (run.status === 'completed') {
284
+ return failResult('orchestration-evidence', 'Completed run requires reviewed-head-clean completion evidence');
285
285
  }
286
286
  if (run.pendingDelegation && !['prepared', 'activated', 'stage-completed'].includes(run.pendingDelegation.status)) {
287
287
  return failResult('orchestration-evidence', `Pending receipt has unsafe status '${run.pendingDelegation.status}'`);
@@ -489,7 +489,7 @@ function checkTaskMeta({ taskDir, config }: any): any {
489
489
  );
490
490
  }
491
491
 
492
- function checkRequiredPrDelivery({ taskDir, repositoryRoot, mode }: any): any {
492
+ async function checkRequiredPrDelivery({ taskDir, repositoryRoot, mode }: any): Promise<any> {
493
493
  const task = loadTask(taskDir);
494
494
  if (!task.ok) return failResult('required-pr-delivery', task.message);
495
495
  let projectConfig: any = {};
@@ -500,23 +500,24 @@ function checkRequiredPrDelivery({ taskDir, repositoryRoot, mode }: any): any {
500
500
  return failResult('required-pr-delivery', 'Project configuration is invalid');
501
501
  }
502
502
  const flow = projectConfig.prFlow;
503
- const status = String(task.metadata.pr_status || 'pending');
504
- const prNumber = parsePrNumber(task.metadata.pr_number);
503
+ const factRead = readPrDeliveryFact(task.metadata);
504
+ if (factRead.status === 'invalid') return failResult('required-pr-delivery', factRead.error.message);
505
+ const fact = factRead.status === 'valid' ? factRead.fact : null;
506
+ const status = fact?.state || 'unbound';
507
+ const prIdentity = fact?.state === 'bound' ? fact.identity.resource : null;
508
+ const prNumber = prIdentity?.kind === 'number' ? prIdentity.value : null;
505
509
  if (flow === 'disabled') return passResult('required-pr-delivery', 'Pull request delivery is disabled by project policy');
506
- if (flow === 'required' && (status !== 'created' || prNumber === null)) {
510
+ if (flow === 'required' && (status !== 'bound' || !prIdentity)) {
507
511
  return failResult('required-pr-delivery', 'Project policy requires a bound pull request before completion');
508
512
  }
509
- if (flow !== 'required' && status === 'pending') {
513
+ if (flow !== 'required' && status === 'unbound') {
510
514
  return failResult('required-pr-delivery', 'Pull request delivery is pending; create a PR or explicitly skip it');
511
515
  }
512
- if (status === 'created' && prNumber === null) {
513
- return failResult('required-pr-delivery', 'Task claims a created pull request without a valid pr_number');
514
- }
515
516
  if (flow === 'required') {
516
517
  if (mode === 'gate') {
517
518
  return passResult('required-pr-delivery', 'Bound pull request shape is valid; merged-state inspection is reserved for hard preflight');
518
519
  }
519
- const inspected = inspectPlatformPullRequest(task.metadata.id, { cwd: repositoryRoot });
520
+ const inspected = await inspectPlatformPullRequest(task.metadata.id, { cwd: repositoryRoot });
520
521
  if (inspected.status === 'blocked') {
521
522
  return blockedResult(
522
523
  'required-pr-delivery',
@@ -527,7 +528,8 @@ function checkRequiredPrDelivery({ taskDir, repositoryRoot, mode }: any): any {
527
528
  const pullRequest = inspected.pullRequest;
528
529
  const repository = inspected.platform.repository?.toLowerCase() || '';
529
530
  const taskBranch = String(task.metadata.branch || '').trim();
530
- if (inspected.status !== 'no-op' || !pullRequest || pullRequest.number !== prNumber) {
531
+ const deliveryBaseRef = String(task.metadata.delivery_base_ref || projectConfig.delivery?.baseRef || '').trim();
532
+ if (inspected.status !== 'no-op' || !pullRequest) {
531
533
  return failResult('required-pr-delivery', 'Bound pull request identity could not be verified');
532
534
  }
533
535
  if (
@@ -535,13 +537,14 @@ function checkRequiredPrDelivery({ taskDir, repositoryRoot, mode }: any): any {
535
537
  || pullRequest.repository.toLowerCase() !== repository
536
538
  || pullRequest.base.repository.toLowerCase() !== repository
537
539
  || (taskBranch && pullRequest.head.ref !== taskBranch)
540
+ || (deliveryBaseRef && pullRequest.base.ref !== deliveryBaseRef)
538
541
  ) {
539
542
  return failResult('required-pr-delivery', 'Bound pull request identity does not match the task');
540
543
  }
541
544
  if (pullRequest.state !== 'closed' || !pullRequest.mergedAt || !pullRequest.mergeCommitSha) {
542
545
  return failResult('required-pr-delivery', 'Project policy requires the bound pull request to be merged');
543
546
  }
544
- return passResult('required-pr-delivery', `Pull request delivery policy satisfied (merged PR #${prNumber})`);
547
+ return passResult('required-pr-delivery', `Pull request delivery policy satisfied (merged PR ${prNumber === null ? 'identity' : `#${prNumber}`})`);
545
548
  }
546
549
  return passResult('required-pr-delivery', `Pull request delivery policy satisfied (${status})`);
547
550
  }
@@ -580,7 +583,7 @@ function loadProjectName(): any {
580
583
  }
581
584
  }
582
585
 
583
- function checkArtifact({ taskDir, config, artifactFile }: any): any {
586
+ function checkArtifact({ taskDir, config, artifactFile, skillName }: any): any {
584
587
  const resolvedArtifact = resolveArtifactPath(taskDir, config.file_pattern, artifactFile);
585
588
  if (!resolvedArtifact.ok) {
586
589
  return failResult("artifact", resolvedArtifact.message);
@@ -598,6 +601,26 @@ function checkArtifact({ taskDir, config, artifactFile }: any): any {
598
601
 
599
602
  const content = fs.readFileSync(artifactPath, "utf8");
600
603
  const requiredSections = config.required_sections || [];
604
+ const localFamily = skillName === "analyze-task"
605
+ ? "analysis"
606
+ : skillName === "plan-task" ? "plan" : skillName === "code-task" ? "code" : null;
607
+ if (localFamily) {
608
+ const local = validateLocalArtifact(content, {
609
+ family: localFamily,
610
+ requiredSections: requiredSections.filter((section: unknown): section is string => typeof section === "string"),
611
+ requiredPatterns: (config.required_patterns || []).filter((pattern: unknown): pattern is string => typeof pattern === "string")
612
+ });
613
+ if (!local.ok) {
614
+ return failResult(
615
+ "artifact",
616
+ `${path.basename(artifactPath)} has local structural errors: ${local.diagnostics.map((item) => `${item.code}: ${item.message}`).join('; ')}`
617
+ );
618
+ }
619
+ return passResult(
620
+ "artifact",
621
+ `${path.basename(artifactPath)} passed (${requiredSections.length} sections)`
622
+ );
623
+ }
601
624
  const missingSections = requiredSections.filter(
602
625
  (section: any) => !new RegExp(`^##\\s+${escapeRegExp(section)}\\s*$`, "m").test(content)
603
626
  );
@@ -1030,6 +1053,7 @@ function checkManualValidation({ taskDir }: any): any {
1030
1053
  // 1. Latest review-code artifact; none -> pass (no review, check not applicable).
1031
1054
  const review = findAuthoritativeReviewCodeArtifact(taskDir);
1032
1055
  if (!review.ok) {
1056
+ if (review.error) return failResult("manual-validation", `Review-code artifact is unavailable: ${review.error}`);
1033
1057
  return passResult("manual-validation", "No review-code artifact; manual validation not applicable");
1034
1058
  }
1035
1059
  // 2. Parse the numeric manual-validation count; unparseable/null -> fail closed
@@ -1095,9 +1119,10 @@ function checkManualValidation({ taskDir }: any): any {
1095
1119
  return passResult("manual-validation", `Manual validation completed → ${artifactName}`);
1096
1120
  }
1097
1121
 
1098
- function checkPostReviewCommit({ taskDir, config }: any): any {
1122
+ async function checkPostReviewCommit({ taskDir, config }: any): Promise<any> {
1099
1123
  const reviewArtifact = findAuthoritativeReviewCodeArtifact(taskDir);
1100
1124
  if (!reviewArtifact.ok) {
1125
+ if (reviewArtifact.error) return failResult("post-review-commit", `Review-code artifact is unavailable: ${reviewArtifact.error}`);
1101
1126
  return passResult("post-review-commit", "No review-code artifact; check inactive");
1102
1127
  }
1103
1128
 
@@ -1110,12 +1135,15 @@ function checkPostReviewCommit({ taskDir, config }: any): any {
1110
1135
 
1111
1136
  const task = loadTask(taskDir);
1112
1137
  if (!task.ok) return failResult("post-review-commit", task.message);
1138
+ const factRead = readPrDeliveryFact(task.metadata);
1139
+ if (factRead.status === 'invalid') return failResult("post-review-commit", factRead.error.message);
1140
+ const fact = factRead.status === 'valid' ? factRead.fact : null;
1113
1141
  const lastReviewedCommit = task.ok ? (task.metadata.last_reviewed_commit || "").trim() : "";
1114
1142
  const globs = resolvePostReviewGlobs(config, loadPostReviewConfig(repoRoot));
1115
- const hasPullRequest = Number(task.metadata.pr_number) > 0;
1116
- let inspected: ReturnType<typeof inspectPlatformPullRequest> | null = null;
1143
+ const hasPullRequest = fact?.state === 'bound';
1144
+ let inspected: Awaited<ReturnType<typeof inspectPlatformPullRequest>> | null = null;
1117
1145
  if (hasPullRequest) {
1118
- inspected = inspectPlatformPullRequest(task.metadata.id, { cwd: gitRoot });
1146
+ inspected = await inspectPlatformPullRequest(task.metadata.id, { cwd: gitRoot });
1119
1147
  if (!inspected.pullRequest) {
1120
1148
  const message = inspected.error?.message || "PR merge snapshot is unavailable";
1121
1149
  const code = inspected.error?.code || "PR_INSPECTION_INVALID";
@@ -1128,7 +1156,7 @@ function checkPostReviewCommit({ taskDir, config }: any): any {
1128
1156
  inspected.pullRequest.mergedAt &&
1129
1157
  inspected.pullRequest.mergeCommitSha
1130
1158
  ) {
1131
- const relation = resolveMaterializedReviewedHeadRelation({
1159
+ const relation = await resolveMaterializedReviewedHeadRelation({
1132
1160
  cwd: gitRoot,
1133
1161
  platformType: inspected.platform.type,
1134
1162
  lastReviewedCommit,
@@ -1295,6 +1323,17 @@ function checkReviewFact({ taskDir, artifactFile }: any): any {
1295
1323
  return failResult("review-fact", resolvedArtifact.message);
1296
1324
  }
1297
1325
 
1326
+ const authoritative = findAuthoritativeReviewCodeArtifact(taskDir);
1327
+ if (!authoritative.ok) {
1328
+ return failResult("review-fact", authoritative.error ?? "No active review-code artifact is available");
1329
+ }
1330
+ if (path.basename(resolvedArtifact.path) !== authoritative.fileName) {
1331
+ return failResult(
1332
+ "review-fact",
1333
+ `review-code artifact ${path.basename(resolvedArtifact.path)} is not the current active artifact ${authoritative.fileName}; re-run review-code`
1334
+ );
1335
+ }
1336
+
1298
1337
  const task = loadTask(taskDir);
1299
1338
  if (!task.ok) {
1300
1339
  return failResult("review-fact", task.message);
@@ -1302,7 +1341,8 @@ function checkReviewFact({ taskDir, artifactFile }: any): any {
1302
1341
 
1303
1342
  const content = fs.readFileSync(resolvedArtifact.path, "utf8");
1304
1343
  const verdict = parseReviewVerdict(content);
1305
- const reviewBaseline = extractReviewBaseline(content);
1344
+ const reviewTargetHead = extractReviewTargetHead(content);
1345
+ const reviewReviewedHead = extractReviewedHead(content);
1306
1346
  const reviewDiffBase = extractReviewDiffBase(content);
1307
1347
  const reviewedFingerprint = extractReviewDiffFingerprint(content);
1308
1348
  const reviewedTree = extractReviewedSnapshotTree(content);
@@ -1311,30 +1351,42 @@ function checkReviewFact({ taskDir, artifactFile }: any): any {
1311
1351
  return failResult("review-fact", `Unsupported review verdict '${verdict}'`);
1312
1352
  }
1313
1353
 
1354
+ const deliveryRemote = String(task.metadata.delivery_remote || "").trim();
1355
+ const deliveryBaseRef = String(task.metadata.delivery_base_ref || "").trim();
1356
+ if (!deliveryRemote || !deliveryBaseRef) {
1357
+ return failResult("review-fact", "Task delivery target is not bound; re-run task branch preparation before review-code");
1358
+ }
1359
+ if (!reviewTargetHead || !reviewReviewedHead || !reviewDiffBase) {
1360
+ return failResult("review-fact", "Review fact must record target head, reviewed head, and diff base");
1361
+ }
1362
+
1314
1363
  let gitRoot;
1315
1364
  let head;
1316
1365
  let baseline;
1366
+ let targetHead;
1317
1367
  let diffBase;
1318
1368
  try {
1319
1369
  gitRoot = execFileSync("git", ["-C", taskDir, "rev-parse", "--show-toplevel"], { encoding: "utf8" }).trim();
1320
1370
  head = execFileSync("git", ["-C", gitRoot, "rev-parse", "HEAD"], { encoding: "utf8" }).trim();
1321
- baseline = execFileSync("git", ["-C", gitRoot, "rev-parse", `${reviewBaseline}^{commit}`], { encoding: "utf8" }).trim();
1322
- diffBase = execFileSync(
1323
- "git",
1324
- ["-C", gitRoot, "rev-parse", `${reviewDiffBase || reviewBaseline}^{commit}`],
1325
- { encoding: "utf8" }
1326
- ).trim();
1371
+ const target = resolveDeliveryTarget(gitRoot, { remote: deliveryRemote, baseRef: deliveryBaseRef });
1372
+ if (!target.ok) throw new Error(target.message);
1373
+ const reviewedRef = reviewReviewedHead;
1374
+ baseline = execFileSync("git", ["-C", gitRoot, "rev-parse", `${reviewedRef}^{commit}`], { encoding: "utf8" }).trim();
1375
+ targetHead = execFileSync("git", ["-C", gitRoot, "rev-parse", `${reviewTargetHead}^{commit}`], { encoding: "utf8" }).trim();
1376
+ const computed = execFileSync("git", ["-C", gitRoot, "merge-base", baseline, targetHead], { encoding: "utf8" }).trim();
1377
+ diffBase = execFileSync("git", ["-C", gitRoot, "rev-parse", `${reviewDiffBase}^{commit}`], { encoding: "utf8" }).trim();
1378
+ if (diffBase !== computed) throw new Error('saved review diff base does not match merge-base(reviewed head, target head)');
1327
1379
  } catch {
1328
1380
  return blockedResult(
1329
1381
  "review-fact",
1330
- `Unable to resolve review baseline '${reviewBaseline}' in the task repository; re-run review-code`
1382
+ `Unable to resolve saved review commits in the task repository; re-run review-code`
1331
1383
  );
1332
1384
  }
1333
1385
 
1334
1386
  if (baseline !== head) {
1335
1387
  return failResult(
1336
1388
  "review-fact",
1337
- `Review baseline ${baseline.slice(0, 8)} does not match current HEAD ${head.slice(0, 8)}; re-run review-code`
1389
+ `Reviewed head ${baseline.slice(0, 8)} does not match current HEAD ${head.slice(0, 8)}; re-run review-code`
1338
1390
  );
1339
1391
  }
1340
1392
 
@@ -1378,7 +1430,7 @@ function checkReviewFact({ taskDir, artifactFile }: any): any {
1378
1430
  if (cleanSnapshot && lastReviewedCommit !== baseline) {
1379
1431
  return failResult(
1380
1432
  "review-fact",
1381
- `Approved clean review must set task last_reviewed_commit to baseline ${baseline.slice(0, 8)}`
1433
+ `Approved clean review must set task last_reviewed_commit to reviewed head ${baseline.slice(0, 8)}`
1382
1434
  );
1383
1435
  }
1384
1436
  if (!cleanSnapshot && lastReviewedCommit) {
@@ -1638,7 +1690,7 @@ function isBlank(value: any): any {
1638
1690
  return value === undefined || value === null || String(value).trim() === "";
1639
1691
  }
1640
1692
 
1641
- function verifyInProcess({ mode, skillName, taskDir, artifactFile, checks: requestedChecks, repositoryRoot }: any): any {
1693
+ async function verifyInProcess({ mode, skillName, taskDir, artifactFile, checks: requestedChecks, repositoryRoot }: any): Promise<any> {
1642
1694
  if (repositoryRoot) repoRoot = path.resolve(repositoryRoot);
1643
1695
  else {
1644
1696
  let cursor = path.resolve(taskDir);
@@ -1651,7 +1703,7 @@ function verifyInProcess({ mode, skillName, taskDir, artifactFile, checks: reque
1651
1703
  const checks = [];
1652
1704
  for (const [type, checkConfig] of Object.entries(verifyConfig.checks || {})) {
1653
1705
  if (checkConfig === null) continue;
1654
- const result = runCheck(type, {
1706
+ const result = await runCheck(type, {
1655
1707
  mode,
1656
1708
  skillName,
1657
1709
  taskDir: path.resolve(taskDir),
@@ -1671,7 +1723,7 @@ function verifyInProcess({ mode, skillName, taskDir, artifactFile, checks: reque
1671
1723
  if (config === null) return { skill: skillName, ...passResult(type, `Check '${type}' is disabled for skill '${skillName}'.`) };
1672
1724
  return {
1673
1725
  skill: skillName,
1674
- ...runCheck(type, {
1726
+ ...await runCheck(type, {
1675
1727
  skillName,
1676
1728
  taskDir: path.resolve(taskDir),
1677
1729
  artifactFile,
@@ -1,5 +1,7 @@
1
1
  export {
2
2
  extractReviewBaseline,
3
+ extractReviewTargetHead,
4
+ extractReviewedHead,
3
5
  extractReviewDiffBase,
4
6
  extractReviewDiffFingerprint,
5
7
  extractReviewedSnapshotTree,
@@ -49,7 +49,7 @@ type TaskVerificationResult = {
49
49
  };
50
50
  type VerificationOptions = {
51
51
  repoRoot?: string;
52
- engine?: typeof verifyInProcess;
52
+ engine?: (input: Parameters<typeof verifyInProcess>[0]) => Record<string, unknown> | Promise<Record<string, unknown>>;
53
53
  manualOverride?: ManualOverrideCapability;
54
54
  };
55
55
 
@@ -91,7 +91,7 @@ function failure(request: { taskRef: string; event: string; artifact?: string },
91
91
  };
92
92
  }
93
93
 
94
- function verifyTaskEvent(request: { taskRef: string; event: string; artifact?: string }, options: VerificationOptions = {}): TaskVerificationResult {
94
+ async function verifyTaskEvent(request: { taskRef: string; event: string; artifact?: string }, options: VerificationOptions = {}): Promise<TaskVerificationResult> {
95
95
  const spec = VERIFICATION_CATALOG[request.event as VerificationEvent];
96
96
  if (!spec) return failure(request, 'VERIFY_EVENT_UNKNOWN', `unknown verification event '${request.event}'`);
97
97
  const resolved = resolveTaskRef(request.taskRef, { repoRoot: options.repoRoot });
@@ -113,7 +113,7 @@ function verifyTaskEvent(request: { taskRef: string; event: string; artifact?: s
113
113
  const invocations: VerificationInvocation[] = [];
114
114
  const engine = options.engine ?? verifyInProcess;
115
115
  if (spec.mode === 'gate') {
116
- const payload = engine({ mode: 'gate', skillName: spec.skill, taskDir: resolved.taskDir, artifactFile: request.artifact, checks: [], repositoryRoot: resolved.repoRoot }) as Record<string, unknown>;
116
+ const payload = await engine({ mode: 'gate', skillName: spec.skill, taskDir: resolved.taskDir, artifactFile: request.artifact, checks: [], repositoryRoot: resolved.repoRoot });
117
117
  const status = payload.gate as 'pass' | 'fail' | 'blocked';
118
118
  if (status !== 'pass' && allowsManualOverride(options.manualOverride, 'verification-engine', status === 'blocked' ? 'CHECK_BLOCKED' : 'CHECK_FAILED')) {
119
119
  invocations.push({ status: 'pass', exitCode: 0, payload: { ...payload, gate: 'pass', humanOverride: 'human-approved', originalGate: status } });
@@ -125,7 +125,7 @@ function verifyTaskEvent(request: { taskRef: string; event: string; artifact?: s
125
125
  invocations.push({ status, exitCode: ({ pass: 0, fail: 1, blocked: 2 } as const)[status], payload });
126
126
  } else {
127
127
  for (const check of spec.checks ?? []) {
128
- const payload = engine({ mode: 'checks', skillName: spec.skill, taskDir: resolved.taskDir, artifactFile: request.artifact, checks: [check], repositoryRoot: resolved.repoRoot }) as Record<string, unknown>;
128
+ const payload = await engine({ mode: 'checks', skillName: spec.skill, taskDir: resolved.taskDir, artifactFile: request.artifact, checks: [check], repositoryRoot: resolved.repoRoot });
129
129
  const status = payload.status as 'pass' | 'fail' | 'blocked';
130
130
  if (status !== 'pass' && allowsManualOverride(options.manualOverride, 'verification-engine', status === 'blocked' ? 'CHECK_BLOCKED' : 'CHECK_FAILED')) {
131
131
  invocations.push({ status: 'pass', exitCode: 0, payload: { ...payload, status: 'pass', humanOverride: 'human-approved', originalStatus: status } });
@@ -68,7 +68,7 @@ function sectionMutation(content: string): TaskMutation[] {
68
68
  const english = /^##\s+Activity Log\s*$/m.test(content);
69
69
  return [{
70
70
  kind: 'section', aliases: WORKFLOW_WARNING_HEADINGS, heading: english ? 'Workflow Warnings' : '工作流告警',
71
- body: `| ${WORKFLOW_WARNING_COLUMNS.join(' | ')} |\n|----|------|------|----------|------|--------|--------|---------|--------|-------------|------------|`
71
+ body: `| ${WORKFLOW_WARNING_COLUMNS.join(' | ')} |\n|----|------|------|----------|------|--------|---------|--------|-------------|------------|------------|`
72
72
  }];
73
73
  }
74
74
 
package/lib/task/write.ts CHANGED
@@ -16,6 +16,7 @@ import { allowsManualOverride } from './guard-override.ts';
16
16
  import type { ManualOverrideCapability } from './guard-override.ts';
17
17
  import { mutateTableRow, upsertSection } from './sections.ts';
18
18
  import { validateCurrentTaskContract } from './current-contract.ts';
19
+ import { invalidationBlocks, parseInvalidationDocument } from './invalidation.ts';
19
20
  import type {
20
21
  TableRowDeleteMutation,
21
22
  TableRowUpsertMutation
@@ -86,6 +87,8 @@ type TaskWriteErrorCode =
86
87
  | ResolveTaskRefErrorCode
87
88
  | 'TASK_STATE_MISMATCH'
88
89
  | 'TASK_CURRENT_CONTRACT_INVALID'
90
+ | 'TASK_INVALIDATION_INVALID'
91
+ | 'TASK_INVALIDATION_BLOCKED'
89
92
  | 'TASK_READ_FAILED'
90
93
  | 'TASK_DOCUMENT_INVALID'
91
94
  | 'MUTATION_INVALID'
@@ -161,6 +164,7 @@ type TaskWriteOptions = {
161
164
  randomSuffix?: () => string;
162
165
  fileSystem?: Partial<TaskFileSystem>;
163
166
  manualOverride?: ManualOverrideCapability;
167
+ invalidationContext?: 'standard' | 'source-completion' | 'reconcile';
164
168
  };
165
169
 
166
170
  const DEFAULT_FILE_SYSTEM: TaskFileSystem = {
@@ -275,6 +279,21 @@ function writeTask(request: TaskWriteRequest, options: TaskWriteOptions = {}): T
275
279
  if (!contract.ok) {
276
280
  return failure(request, identity, contract.code, contract.message);
277
281
  }
282
+ if (
283
+ invalidationBlocks(contract.invalidation)
284
+ && options.invalidationContext !== 'source-completion'
285
+ && options.invalidationContext !== 'reconcile'
286
+ ) {
287
+ return failure(
288
+ request,
289
+ identity,
290
+ 'TASK_INVALIDATION_BLOCKED',
291
+ 'task has an incomplete artifact invalidation operation; reconcile it before writing downstream state'
292
+ );
293
+ }
294
+ } else {
295
+ const invalidation = parseInvalidationDocument(original);
296
+ if (!invalidation.ok) return failure(request, identity, 'TASK_INVALIDATION_INVALID', invalidation.message);
278
297
  }
279
298
 
280
299
  let candidate = original;
package/lib/update.ts CHANGED
@@ -19,10 +19,11 @@ type UpdateConfig = {
19
19
  project: string;
20
20
  org: string;
21
21
  language: string;
22
- platform?: { type?: string };
22
+ platform?: { type?: string; providers?: Record<string, unknown> };
23
23
  prFlow?: 'required' | 'disabled';
24
24
  sandbox?: Record<string, unknown>;
25
25
  task?: { shortIdLength: number };
26
+ delivery?: { remote?: string; baseRef?: string };
26
27
  labels?: Record<string, unknown>;
27
28
  files?: Partial<FileRegistry>;
28
29
  agentClients?: unknown;
@@ -33,6 +34,7 @@ type Defaults = {
33
34
  platform: { type: string };
34
35
  sandbox: Record<string, unknown>;
35
36
  task: { shortIdLength: number };
37
+ delivery: { remote: string; baseRef: string };
36
38
  labels: Record<string, unknown>;
37
39
  files: FileRegistry;
38
40
  };
@@ -83,10 +85,12 @@ async function cmdSync(): Promise<void> {
83
85
  const sandboxAdded = !config.sandbox;
84
86
  const taskAdded = !config.task;
85
87
  const labelsAdded = !config.labels;
88
+ const deliveryAdded = !config.delivery;
86
89
  if (platformAdded) config.platform = structuredClone(defaults.platform);
87
90
  if (sandboxAdded) config.sandbox = structuredClone(defaults.sandbox);
88
91
  if (taskAdded) config.task = structuredClone(defaults.task);
89
92
  if (labelsAdded) config.labels = structuredClone(defaults.labels);
93
+ if (deliveryAdded) config.delivery = structuredClone(defaults.delivery);
90
94
 
91
95
  const workflowPlan = planAgentClientReconciliation({
92
96
  config: config as unknown as Record<string, unknown>,
@@ -150,6 +154,9 @@ async function cmdSync(): Promise<void> {
150
154
  if (labelsAdded) {
151
155
  info(`Default labels.in config added to ${CONFIG_PATH}.`);
152
156
  }
157
+ if (deliveryAdded) {
158
+ info(`Default delivery target added to ${CONFIG_PATH}.`);
159
+ }
153
160
  } else {
154
161
  info(`File registry changed in ${CONFIG_PATH}.`);
155
162
  }
@@ -165,6 +172,9 @@ async function cmdSync(): Promise<void> {
165
172
  if (hasNewEntries && platformAdded) {
166
173
  info(`Default platform config added to ${CONFIG_PATH}.`);
167
174
  }
175
+ if (hasNewEntries && deliveryAdded) {
176
+ info(`Default delivery target added to ${CONFIG_PATH}.`);
177
+ }
168
178
  ok(`Updated ${CONFIG_PATH}`);
169
179
  }
170
180
 
package/lib/version.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { existsSync, readFileSync } from 'node:fs';
2
+ import semver from 'semver';
2
3
 
3
4
  const packageJsonUrl = [
4
5
  new URL('../package.json', import.meta.url),
@@ -12,9 +13,22 @@ if (!packageJsonUrl) {
12
13
  const { version } = JSON.parse(readFileSync(packageJsonUrl, 'utf8'));
13
14
  const VERSION = `v${version}`;
14
15
  const AGENT_INFRA_VERSION_PATTERN = /^v\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
16
+ const LEGACY_COMPATIBILITY_CUTOFF_VERSION = '1.0.0';
15
17
 
16
18
  function isValidAgentInfraVersion(value: unknown): value is string {
17
19
  return typeof value === 'string' && AGENT_INFRA_VERSION_PATTERN.test(value);
18
20
  }
19
21
 
20
- export { VERSION, isValidAgentInfraVersion };
22
+ function isLegacyCompatibilityEnabled(runtimeVersion = VERSION): boolean {
23
+ const normalized = runtimeVersion.startsWith('v') ? runtimeVersion.slice(1) : runtimeVersion;
24
+ const parsed = semver.valid(normalized);
25
+ return parsed !== null && semver.lt(parsed, LEGACY_COMPATIBILITY_CUTOFF_VERSION);
26
+ }
27
+
28
+ function legacyCompatibilityError(resource: string, runtimeVersion = VERSION): Error & { code: string } {
29
+ return Object.assign(new Error(
30
+ `PLATFORM_IDENTITY_LEGACY_UNSUPPORTED: ${resource} requires migration to the current schema before v${LEGACY_COMPATIBILITY_CUTOFF_VERSION} runtime ${runtimeVersion}`
31
+ ), { code: 'PLATFORM_IDENTITY_LEGACY_UNSUPPORTED' });
32
+ }
33
+
34
+ export { LEGACY_COMPATIBILITY_CUTOFF_VERSION, VERSION, isLegacyCompatibilityEnabled, isValidAgentInfraVersion, legacyCompatibilityError };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fitlab-ai/agent-infra",
3
- "version": "0.9.11",
3
+ "version": "0.9.13",
4
4
  "description": "Bootstrap tool for AI multi-tool collaboration infrastructure — works with Claude Code, Codex, Antigravity CLI, and OpenCode",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -17,6 +17,12 @@
17
17
  "access": "public",
18
18
  "registry": "https://registry.npmjs.org/"
19
19
  },
20
+ "exports": {
21
+ "./platform-provider": {
22
+ "types": "./dist/lib/platform/provider-contract.d.ts",
23
+ "import": "./dist/lib/platform/provider-contract.js"
24
+ }
25
+ },
20
26
  "bin": {
21
27
  "agent-infra": "./dist/bin/cli.js",
22
28
  "ai": "./dist/bin/cli.js",
@@ -13,6 +13,7 @@ so you can quickly find "which ones to read" without opening each file.
13
13
  - [`version-stamp.md`](version-stamp.md) — How and when to stamp `agent_infra_version`.
14
14
  - [`debugging-guide.md`](debugging-guide.md) — Structured debugging flow: gather evidence → form hypothesis → verify hypothesis → fix the root cause; no blind patch-and-retry.
15
15
  - [`compatibility-policy.md`](compatibility-policy.md) — Compatibility by exception: admission evidence, implementation boundaries, exit conditions, and lifecycle review requirements.
16
+ - [`sync-content-generation.md`](sync-content-generation.md) — Producer-side Markdown constraints for task and lifecycle content synchronized to Issues.
16
17
 
17
18
  ## Issue / PR
18
19
 
@@ -29,11 +30,12 @@ so you can quickly find "which ones to read" without opening each file.
29
30
  - [`lifecycle-orchestration.md`](lifecycle-orchestration.md) — Fresh executor/reviewer, one-use receipt, pause/recovery, and safe endpoint rules for `run-task`.
30
31
  - [`review-handshake.md`](review-handshake.md) — Three-stage bidirectional review handshake: four-state disposition, symmetric evidence, disagreement ledger, convergence and post-review commit gate.
31
32
  - [`review-method.md`](review-method.md) — Shared three-stage review method: multi-pass review, risk lenses, traceability, and finding evidence.
33
+ - [`local-artifact-repair.md`](local-artifact-repair.md) — Pre-completion local artifact validation for analysis/plan/code and model-per-case repair, safety gates, and convergence for failed review artifacts.
32
34
  - [`human-decision-context.md`](human-decision-context.md) — Self-contained context and canonical structure for new human-decision details.
33
35
  - [`task-short-id.md`](task-short-id.md) — Resolution, allocation and lifecycle of bare-number short ids.
34
36
  - [`milestone-inference.md`](milestone-inference.md) — Milestone inference for create-task / code-task / create-pr.
35
- - [`label-milestone-setup.md`](label-milestone-setup.md) — Platform commands to initialize labels / milestones.
36
- - [`security-alerts.md`](security-alerts.md) — Commands to import / close Dependabot and Code Scanning alerts.
37
+ - [`label-milestone-setup.md`](label-milestone-setup.md) — Shared entry points to initialize labels / milestones.
38
+ - [`security-alerts.md`](security-alerts.md) — Shared entry point to import / close dependency and code-scanning alerts.
37
39
 
38
40
  ## Commit & Release
39
41
 
@@ -12,6 +12,7 @@
12
12
  - [`version-stamp.md`](version-stamp.md) — `agent_infra_version` 版本戳的取值命令与写入时机。
13
13
  - [`debugging-guide.md`](debugging-guide.md) — 结构化调试流程:收集证据→形成假设→验证假设→修复根因,禁止盲目改代码重试。
14
14
  - [`compatibility-policy.md`](compatibility-policy.md) — 兼容性默认关闭:准入证据、实现边界、退出条件与生命周期审查要求。
15
+ - [`sync-content-generation.md`](sync-content-generation.md) — 同步到 Issue 的任务和生命周期 Markdown 生成约束。
15
16
 
16
17
  ## Issue / PR
17
18
 
@@ -28,11 +29,12 @@
28
29
  - [`lifecycle-orchestration.md`](lifecycle-orchestration.md) — `run-task` 的 fresh executor/reviewer、一次性 receipt、暂停恢复与安全终点规则。
29
30
  - [`review-handshake.md`](review-handshake.md) — 三阶段双向审查握手协议:四态处置、对称证据、分歧账本、收敛与 post-review commit 门禁。
30
31
  - [`review-method.md`](review-method.md) — 三阶段共享检视方法:多遍检视、风险镜头、追踪与 finding 证据契约。
32
+ - [`local-artifact-repair.md`](local-artifact-repair.md) — analysis/plan/code completed 前的本地产物校验、review artifact 失败后的模型逐例修复、机械安全门与收敛契约。
31
33
  - [`human-decision-context.md`](human-decision-context.md) — 新建人工裁决详情的自足上下文与规范结构。
32
34
  - [`task-short-id.md`](task-short-id.md) — 裸数字任务短号的解析、分配与生命周期。
33
35
  - [`milestone-inference.md`](milestone-inference.md) — create-task / code-task / create-pr 的 milestone 推断。
34
- - [`label-milestone-setup.md`](label-milestone-setup.md) — 初始化 label / milestone 的平台命令集。
35
- - [`security-alerts.md`](security-alerts.md) — 导入 / 关闭 Dependabot 与 Code Scanning 告警的命令集。
36
+ - [`label-milestone-setup.md`](label-milestone-setup.md) — 初始化 label / milestone 的共享入口。
37
+ - [`security-alerts.md`](security-alerts.md) — 导入 / 关闭依赖与代码扫描告警的共享入口。
36
38
 
37
39
  ## 提交与发布
38
40
 
@@ -1,5 +1,14 @@
1
1
  # Issue Creation
2
2
 
3
- This code platform does not provide an Issue adapter. `platform-issue create` returns a structured no-op/degraded result.
3
+ > `--agent` values are defined in `.agents/rules/task-management.md` under “Collaborator Token Specification”.
4
4
 
5
- `create-task` skips the cascade Issue creation step on this platform; the local `task.md` remains a valid artifact. If you later want to bind the task to an Issue, manually write `issue_number` into `task.md` and the subsequent skills (`commit` / `code-task` / `complete-task`, etc.) will pick up Issue metadata syncing through the existing cascade rules.
5
+ After `create-task` writes task.md, create and initialize the Issue through declarative internal intents:
6
+
7
+ ```bash
8
+ agent-infra-internal platform-issue create {task-id} --agent {standard-agent-token}
9
+ agent-infra-internal platform-issue sync {task-id} --agent {standard-agent-token} --status waiting-for-triage --assignees current --milestone initial --issue-type --fields
10
+ ```
11
+
12
+ The core reads only persisted task identity, title, type, description, and requirements, and reuses deterministic `ai task issue-body` rendering. It owns template selection, upstream/capabilities, duplicate prevention, POST outcome boundaries, response validation, and atomic `issue_number` binding.
13
+
14
+ `planned|applied|no-op|degraded` exit 0, `failed` exits 1, and `blocked` exits 2. Callers must not fall back to direct platform CLI or GraphQL orchestration.
@@ -1,5 +1,27 @@
1
1
  # Issue 创建
2
2
 
3
- 当前代码平台未提供 Issue 适配器;`platform-issue create` 返回结构化 no-op/degraded 结果。
3
+ > `--agent` 取值见 `.agents/rules/task-management.md`「合作者 token 规范」。
4
4
 
5
- `create-task` 在本平台上会跳过级联创建 Issue 步骤;本地 `task.md` 仍然是有效产物。如果将来需要把任务绑定到一个 Issue,可手动在 `task.md` 中写入 `issue_number`,后续技能(`commit` / `code-task` / `complete-task` 等)会按既有的级联同步规则自动接管 Issue 元数据更新。
5
+ 当 `create-task` 完成本地 `task.md` 落盘后,通过声明式内部命令创建 Issue:
6
+
7
+ ```bash
8
+ agent-infra-internal platform-issue create {task-id} --agent {standard-agent-token}
9
+ ```
10
+
11
+ 命令只从已落盘 task.md 读取身份、标题、类型、描述与需求,并复用 `ai task issue-body` 的确定性正文渲染。它负责模板选择、upstream/capability、已有绑定检查、非幂等 POST 边界、响应身份校验及通过任务写入内核回写 `issue_number`。
12
+
13
+ 创建后的初始元数据使用同一适配层同步:
14
+
15
+ ```bash
16
+ agent-infra-internal platform-issue sync {task-id} --agent {standard-agent-token} \
17
+ --status waiting-for-triage --assignees current --milestone initial --issue-type --fields
18
+ ```
19
+
20
+ ## 结果处理
21
+
22
+ - `planned|applied|no-op|degraded`:exit 0;调用方按 operations 继续评论同步。
23
+ - `failed`:exit 1;调用方登记 `ISSUE_CREATE_FAILED` warning,不伪造绑定。
24
+ - `blocked`:exit 2;认证、网络或创建 outcome 不确定,调用方保留远端 identity 证据并停止盲目重试。
25
+ - 已绑定有效 Issue 时只验证绑定并返回 no-op,绝不重复创建。
26
+
27
+ 自定义或空平台返回 no-op/degraded;调用方不得回退到直接平台 CLI 或 GraphQL 编排。