@fitlab-ai/agent-infra 0.9.13 → 0.9.15

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 (428) hide show
  1. package/README.md +10 -0
  2. package/README.zh-CN.md +10 -0
  3. package/bin/cli.ts +26 -9
  4. package/bin/internal-cli.sh +45 -0
  5. package/dist/bin/cli.js +173 -157
  6. package/dist/bin/internal-cli.js +126 -42
  7. package/dist/lib/agent-client.js +5 -0
  8. package/dist/lib/agent-clients/adapters/codex-lifecycle/capability-store.js +165 -27
  9. package/dist/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.js +3 -2
  10. package/dist/lib/defaults.json +103 -103
  11. package/dist/lib/fs/durable-write.js +37 -0
  12. package/dist/lib/fs/file-lock.js +111 -0
  13. package/dist/lib/host-control/audit.js +19 -0
  14. package/dist/lib/host-control/client.js +142 -0
  15. package/dist/lib/host-control/command.js +49 -0
  16. package/dist/lib/host-control/path.js +160 -0
  17. package/dist/lib/host-control/secure-fs.js +140 -0
  18. package/dist/lib/host-control/server.js +159 -0
  19. package/dist/lib/host-control/service.js +112 -0
  20. package/dist/lib/init.js +11 -2
  21. package/dist/lib/internal/agent-client.js +5 -2
  22. package/dist/lib/internal/cli-route-inventory.js +154 -0
  23. package/dist/lib/internal/codex-lifecycle.js +15 -12
  24. package/dist/lib/internal/codex-sandbox-controller.js +8 -2
  25. package/dist/lib/internal/demo-promotion.js +322 -0
  26. package/dist/lib/internal/demo-transcript.js +454 -0
  27. package/dist/lib/internal/git-workflow.js +10 -6
  28. package/dist/lib/internal/host-control.js +28 -0
  29. package/dist/lib/internal/manual-validation.js +322 -0
  30. package/dist/lib/internal/platform-checks.js +16 -4
  31. package/dist/lib/internal/platform-comment.js +16 -4
  32. package/dist/lib/internal/platform-context.js +4 -1
  33. package/dist/lib/internal/platform-issue.js +12 -4
  34. package/dist/lib/internal/platform-metadata.js +88 -0
  35. package/dist/lib/internal/platform-pr-review.js +16 -3
  36. package/dist/lib/internal/platform-pr.js +42 -14
  37. package/dist/lib/internal/platform-release-notes.js +6 -3
  38. package/dist/lib/internal/platform-security.js +93 -0
  39. package/dist/lib/internal/pr-review-grade.js +14 -3
  40. package/dist/lib/internal/release-workflow.js +82 -89
  41. package/dist/lib/internal/sandbox-control.js +171 -7
  42. package/dist/lib/internal/task-activity.js +13 -4
  43. package/dist/lib/internal/task-artifact.js +19 -107
  44. package/dist/lib/internal/task-context.js +4 -1
  45. package/dist/lib/internal/task-create.js +48 -14
  46. package/dist/lib/internal/task-delivery.js +4 -1
  47. package/dist/lib/internal/task-event.js +38 -35
  48. package/dist/lib/internal/task-finalization.js +4 -1
  49. package/dist/lib/internal/task-invalidation.js +4 -1
  50. package/dist/lib/internal/task-ledger.js +12 -1
  51. package/dist/lib/internal/task-lifecycle.js +4 -1
  52. package/dist/lib/internal/task-operation-registry.js +519 -0
  53. package/dist/lib/internal/task-orchestration.js +12 -0
  54. package/dist/lib/internal/task-override.js +10 -3
  55. package/dist/lib/internal/task-qualification.js +90 -0
  56. package/dist/lib/internal/task-review.js +10 -52
  57. package/dist/lib/internal/task-short-id.js +11 -1
  58. package/dist/lib/internal/task-snapshot.js +4 -1
  59. package/dist/lib/internal/task-validate.js +37 -12
  60. package/dist/lib/internal/task-verify.js +5 -1
  61. package/dist/lib/internal/task-warning.js +8 -1
  62. package/dist/lib/owned-path.js +33 -0
  63. package/dist/lib/platform/check-status.js +11 -0
  64. package/dist/lib/platform/comment-safety.js +229 -0
  65. package/dist/lib/platform/completion-backfill.js +1 -1
  66. package/dist/lib/platform/github-data.js +241 -0
  67. package/dist/lib/platform/github-provider.js +248 -26
  68. package/dist/lib/platform/issue-comments.js +146 -34
  69. package/dist/lib/platform/issues.js +1 -179
  70. package/dist/lib/platform/pr-change-report.js +6 -12
  71. package/dist/lib/platform/pr-checks.js +12 -65
  72. package/dist/lib/platform/pr-summary.js +83 -10
  73. package/dist/lib/platform/provider-contract.d.ts +67 -1
  74. package/dist/lib/platform/provider-contract.js +6 -2
  75. package/dist/lib/platform/provider-validation.js +76 -3
  76. package/dist/lib/platform/pull-requests.js +117 -275
  77. package/dist/lib/platform/repository-metadata.js +377 -0
  78. package/dist/lib/platform/security-alerts.js +155 -0
  79. package/dist/lib/platform/snapshots.js +2 -0
  80. package/dist/lib/platform/verification-sync.js +154 -162
  81. package/dist/lib/process-data/index.js +7 -0
  82. package/dist/lib/release/workflow.js +1 -1
  83. package/dist/lib/run/index.js +5 -0
  84. package/dist/lib/sandbox/commands/control-status.js +22 -0
  85. package/dist/lib/sandbox/commands/create.js +39 -8
  86. package/dist/lib/sandbox/commands/ls.js +5 -0
  87. package/dist/lib/sandbox/commands/rm.js +3 -807
  88. package/dist/lib/sandbox/commands/show.js +16 -0
  89. package/dist/lib/sandbox/control/audit.js +203 -0
  90. package/dist/lib/sandbox/control/client.js +125 -12
  91. package/dist/lib/sandbox/control/completed-reentry.js +85 -0
  92. package/dist/lib/sandbox/control/container-identity.js +28 -31
  93. package/dist/lib/sandbox/control/executor.js +233 -34
  94. package/dist/lib/sandbox/control/finalization-response.js +27 -0
  95. package/dist/lib/sandbox/control/identity-sentinel.js +107 -0
  96. package/dist/lib/sandbox/control/lifecycle.js +656 -128
  97. package/dist/lib/sandbox/control/native-file-lock.js +85 -0
  98. package/dist/lib/sandbox/control/protocol.js +55 -4
  99. package/dist/lib/sandbox/control/server.js +720 -79
  100. package/dist/lib/sandbox/control/state.js +63 -3
  101. package/dist/lib/sandbox/control/task-view.js +183 -0
  102. package/dist/lib/sandbox/control/task-workflow.js +74 -0
  103. package/dist/lib/sandbox/control/workflow-executor.js +99 -0
  104. package/dist/lib/sandbox/engines/authority.js +289 -0
  105. package/dist/lib/sandbox/engines/docker-exact-discovery.js +97 -0
  106. package/dist/lib/sandbox/index.js +7 -2
  107. package/dist/lib/sandbox/recovery.js +49 -5
  108. package/dist/lib/sandbox/removal.js +1717 -0
  109. package/dist/lib/sandbox/task-cleanup.js +217 -0
  110. package/dist/lib/sandbox/workspace-view.js +15 -15
  111. package/dist/lib/sandbox/worktree-safety.js +4 -1
  112. package/dist/lib/server/index.js +8 -0
  113. package/dist/lib/task/activity-intent.js +2 -1
  114. package/dist/lib/task/activity-log.js +30 -24
  115. package/dist/lib/task/artifact-command.js +101 -0
  116. package/dist/lib/task/artifact-lifecycle.js +71 -40
  117. package/dist/lib/task/artifact-name.js +36 -0
  118. package/dist/lib/task/artifact-operations.js +474 -0
  119. package/dist/lib/task/artifact-receipts.js +3 -15
  120. package/dist/lib/task/artifact-repair-intent.js +130 -0
  121. package/dist/lib/task/artifact-schema.js +127 -0
  122. package/dist/lib/task/capabilities.js +83 -19
  123. package/dist/lib/task/codex-orchestration.js +71 -25
  124. package/dist/lib/task/commit-identity.js +28 -0
  125. package/dist/lib/task/commit-operation.js +2 -16
  126. package/dist/lib/task/control-authority.js +375 -5
  127. package/dist/lib/task/control-recovery.js +128 -0
  128. package/dist/lib/task/create-service.js +103 -4
  129. package/dist/lib/task/create.js +80 -2
  130. package/dist/lib/task/decision-details.js +2 -46
  131. package/dist/lib/task/events.js +306 -76
  132. package/dist/lib/task/finalization-state.js +9 -0
  133. package/dist/lib/task/human-override.js +3 -6
  134. package/dist/lib/task/implementation-inputs.js +3 -3
  135. package/dist/lib/task/index.js +11 -3
  136. package/dist/lib/task/intermediate-cleanup.js +383 -0
  137. package/dist/lib/task/invalidation.js +18 -65
  138. package/dist/lib/task/ledger-intents.js +7 -22
  139. package/dist/lib/task/ledger.js +1 -3
  140. package/dist/lib/task/lifecycle.js +19 -1
  141. package/dist/lib/task/local-artifact-finalization.js +190 -290
  142. package/dist/lib/task/manual-validation-completion.js +26 -0
  143. package/dist/lib/task/manual-validation-evidence.js +130 -0
  144. package/dist/lib/task/manual-validation-receipt.js +101 -0
  145. package/dist/lib/task/manual-validation-shared.js +40 -0
  146. package/dist/lib/task/manual-validation-transaction.js +243 -0
  147. package/dist/lib/task/markdown.js +47 -0
  148. package/dist/lib/task/orchestration.js +206 -69
  149. package/dist/lib/task/qualification-audit.js +476 -0
  150. package/dist/lib/task/qualification-confirmation.js +109 -0
  151. package/dist/lib/task/qualification-intents.js +148 -0
  152. package/dist/lib/task/review-artifacts.js +23 -40
  153. package/dist/lib/task/review-command.js +25 -0
  154. package/dist/lib/task/review-finalization.js +146 -97
  155. package/dist/lib/task/review-fingerprint.js +2 -2
  156. package/dist/lib/task/sections.js +34 -54
  157. package/dist/lib/task/verification-config.js +11 -0
  158. package/dist/lib/task/verification-engine.js +170 -327
  159. package/dist/lib/task/verification.js +1 -1
  160. package/dist/lib/task/workflow-command.js +17 -0
  161. package/dist/lib/task/workflow-warning-intents.js +0 -16
  162. package/dist/lib/task/workflow-warnings.js +28 -2
  163. package/dist/lib/update.js +2 -0
  164. package/dist/lifecycle-build-manifest.json +3 -3
  165. package/lib/agent-client.ts +9 -0
  166. package/lib/agent-clients/adapters/codex-lifecycle/capability-store.ts +223 -33
  167. package/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.ts +3 -2
  168. package/lib/fs/durable-write.ts +29 -0
  169. package/lib/fs/file-lock.ts +113 -0
  170. package/lib/host-control/audit.ts +22 -0
  171. package/lib/host-control/client.ts +172 -0
  172. package/lib/host-control/command.ts +60 -0
  173. package/lib/host-control/path.ts +167 -0
  174. package/lib/host-control/secure-fs.ts +135 -0
  175. package/lib/host-control/server.ts +180 -0
  176. package/lib/host-control/service.ts +133 -0
  177. package/lib/init.ts +15 -2
  178. package/lib/internal/agent-client.ts +4 -2
  179. package/lib/internal/cli-route-inventory.ts +142 -0
  180. package/lib/internal/codex-lifecycle.ts +14 -12
  181. package/lib/internal/codex-sandbox-controller.ts +7 -2
  182. package/lib/internal/demo-promotion.ts +354 -0
  183. package/lib/internal/demo-transcript.ts +419 -0
  184. package/lib/internal/git-workflow.ts +9 -6
  185. package/lib/internal/host-control.ts +28 -0
  186. package/lib/internal/manual-validation.ts +306 -0
  187. package/lib/internal/platform-checks.ts +12 -4
  188. package/lib/internal/platform-comment.ts +12 -4
  189. package/lib/internal/platform-context.ts +3 -1
  190. package/lib/internal/platform-issue.ts +11 -4
  191. package/lib/internal/platform-metadata.ts +70 -0
  192. package/lib/internal/platform-pr-review.ts +14 -3
  193. package/lib/internal/platform-pr.ts +38 -14
  194. package/lib/internal/platform-release-notes.ts +5 -3
  195. package/lib/internal/platform-security.ts +83 -0
  196. package/lib/internal/pr-review-grade.ts +10 -3
  197. package/lib/internal/release-workflow.ts +91 -87
  198. package/lib/internal/sandbox-control.ts +181 -6
  199. package/lib/internal/task-activity.ts +12 -4
  200. package/lib/internal/task-artifact.ts +15 -79
  201. package/lib/internal/task-context.ts +3 -1
  202. package/lib/internal/task-create.ts +76 -15
  203. package/lib/internal/task-delivery.ts +3 -1
  204. package/lib/internal/task-event.ts +21 -10
  205. package/lib/internal/task-finalization.ts +3 -1
  206. package/lib/internal/task-invalidation.ts +3 -1
  207. package/lib/internal/task-ledger.ts +11 -1
  208. package/lib/internal/task-lifecycle.ts +3 -1
  209. package/lib/internal/task-operation-registry.ts +590 -0
  210. package/lib/internal/task-orchestration.ts +12 -0
  211. package/lib/internal/task-override.ts +9 -3
  212. package/lib/internal/task-qualification.ts +61 -0
  213. package/lib/internal/task-review.ts +7 -50
  214. package/lib/internal/task-short-id.ts +10 -1
  215. package/lib/internal/task-snapshot.ts +3 -1
  216. package/lib/internal/task-validate.ts +32 -12
  217. package/lib/internal/task-verify.ts +4 -1
  218. package/lib/internal/task-warning.ts +7 -1
  219. package/lib/owned-path.ts +26 -0
  220. package/lib/platform/check-status.ts +9 -0
  221. package/lib/platform/comment-safety.ts +255 -0
  222. package/lib/platform/completion-backfill.ts +1 -1
  223. package/lib/platform/github-data.ts +322 -0
  224. package/lib/platform/github-provider.ts +244 -27
  225. package/lib/platform/issue-comments.ts +159 -35
  226. package/lib/platform/issues.ts +4 -245
  227. package/lib/platform/pr-change-report.ts +6 -12
  228. package/lib/platform/pr-checks.ts +13 -77
  229. package/lib/platform/pr-summary.ts +88 -11
  230. package/lib/platform/provider-contract.ts +78 -3
  231. package/lib/platform/provider-validation.ts +85 -3
  232. package/lib/platform/pull-requests.ts +129 -348
  233. package/lib/platform/repository-metadata.ts +453 -0
  234. package/lib/platform/security-alerts.ts +191 -0
  235. package/lib/platform/snapshots.ts +53 -0
  236. package/lib/platform/verification-sync.ts +171 -177
  237. package/lib/process-data/index.ts +7 -0
  238. package/lib/release/workflow.ts +3 -3
  239. package/lib/run/index.ts +5 -0
  240. package/lib/sandbox/commands/control-status.ts +26 -0
  241. package/lib/sandbox/commands/create.ts +53 -12
  242. package/lib/sandbox/commands/ls.ts +7 -0
  243. package/lib/sandbox/commands/rm.ts +3 -996
  244. package/lib/sandbox/commands/show.ts +16 -0
  245. package/lib/sandbox/control/audit.ts +253 -0
  246. package/lib/sandbox/control/client.ts +150 -13
  247. package/lib/sandbox/control/completed-reentry.ts +98 -0
  248. package/lib/sandbox/control/container-identity.ts +27 -43
  249. package/lib/sandbox/control/executor.ts +262 -37
  250. package/lib/sandbox/control/finalization-response.ts +29 -0
  251. package/lib/sandbox/control/identity-sentinel.ts +137 -0
  252. package/lib/sandbox/control/lifecycle.ts +672 -18
  253. package/lib/sandbox/control/native-file-lock.ts +108 -0
  254. package/lib/sandbox/control/protocol.ts +80 -8
  255. package/lib/sandbox/control/server.ts +779 -82
  256. package/lib/sandbox/control/state.ts +84 -3
  257. package/lib/sandbox/control/task-view.ts +240 -0
  258. package/lib/sandbox/control/task-workflow.ts +95 -0
  259. package/lib/sandbox/control/workflow-executor.ts +102 -0
  260. package/lib/sandbox/engines/authority.ts +365 -0
  261. package/lib/sandbox/engines/docker-exact-discovery.ts +132 -0
  262. package/lib/sandbox/index.ts +9 -2
  263. package/lib/sandbox/recovery.ts +49 -6
  264. package/lib/sandbox/removal.ts +2144 -0
  265. package/lib/sandbox/task-cleanup.ts +209 -0
  266. package/lib/sandbox/workspace-view.ts +26 -18
  267. package/lib/sandbox/worktree-safety.ts +4 -1
  268. package/lib/server/index.ts +10 -0
  269. package/lib/task/activity-intent.ts +2 -2
  270. package/lib/task/activity-log.ts +27 -19
  271. package/lib/task/artifact-command.ts +104 -0
  272. package/lib/task/artifact-lifecycle.ts +66 -39
  273. package/lib/task/artifact-name.ts +55 -0
  274. package/lib/task/artifact-operations.ts +580 -0
  275. package/lib/task/artifact-receipts.ts +3 -14
  276. package/lib/task/artifact-repair-intent.ts +152 -0
  277. package/lib/task/artifact-schema.ts +163 -0
  278. package/lib/task/capabilities.ts +82 -22
  279. package/lib/task/codex-orchestration.ts +85 -24
  280. package/lib/task/commit-identity.ts +31 -0
  281. package/lib/task/commit-operation.ts +2 -16
  282. package/lib/task/control-authority.ts +513 -6
  283. package/lib/task/control-recovery.ts +174 -0
  284. package/lib/task/create-service.ts +131 -6
  285. package/lib/task/create.ts +83 -1
  286. package/lib/task/decision-details.ts +3 -71
  287. package/lib/task/events.ts +292 -75
  288. package/lib/task/finalization-state.ts +11 -0
  289. package/lib/task/human-override.ts +3 -8
  290. package/lib/task/implementation-inputs.ts +3 -3
  291. package/lib/task/index.ts +16 -3
  292. package/lib/task/intermediate-cleanup.ts +455 -0
  293. package/lib/task/invalidation.ts +18 -62
  294. package/lib/task/ledger-intents.ts +7 -24
  295. package/lib/task/ledger.ts +1 -3
  296. package/lib/task/lifecycle.ts +17 -1
  297. package/lib/task/local-artifact-finalization.ts +223 -388
  298. package/lib/task/manual-validation-completion.ts +40 -0
  299. package/lib/task/manual-validation-evidence.ts +209 -0
  300. package/lib/task/manual-validation-receipt.ts +152 -0
  301. package/lib/task/manual-validation-shared.ts +50 -0
  302. package/lib/task/manual-validation-transaction.ts +304 -0
  303. package/lib/task/markdown.ts +70 -0
  304. package/lib/task/orchestration.ts +191 -68
  305. package/lib/task/qualification-audit.ts +588 -0
  306. package/lib/task/qualification-confirmation.ts +117 -0
  307. package/lib/task/qualification-intents.ts +150 -0
  308. package/lib/task/review-artifacts.ts +21 -41
  309. package/lib/task/review-command.ts +23 -0
  310. package/lib/task/review-finalization.ts +154 -153
  311. package/lib/task/review-fingerprint.ts +2 -2
  312. package/lib/task/sections.ts +33 -52
  313. package/lib/task/verification-config.ts +12 -0
  314. package/lib/task/verification-engine.ts +165 -370
  315. package/lib/task/verification-types.ts +17 -0
  316. package/lib/task/verification.ts +1 -1
  317. package/lib/task/workflow-command.ts +18 -0
  318. package/lib/task/workflow-warning-intents.ts +0 -13
  319. package/lib/task/workflow-warnings.ts +21 -2
  320. package/lib/update.ts +6 -0
  321. package/package.json +7 -2
  322. package/templates/.agents/hooks/lifecycle-delegation.js +6 -6
  323. package/templates/.agents/rules/README.en.md +2 -0
  324. package/templates/.agents/rules/README.zh-CN.md +2 -0
  325. package/templates/.agents/rules/decision-qualification.en.md +22 -0
  326. package/templates/.agents/rules/decision-qualification.zh-CN.md +22 -0
  327. package/templates/.agents/rules/evidence-reporting.en.md +28 -0
  328. package/templates/.agents/rules/evidence-reporting.zh-CN.md +28 -0
  329. package/templates/.agents/rules/label-milestone-setup.en.md +7 -7
  330. package/templates/.agents/rules/label-milestone-setup.zh-CN.md +7 -7
  331. package/templates/.agents/rules/local-artifact-repair.en.md +5 -1
  332. package/templates/.agents/rules/local-artifact-repair.zh-CN.md +5 -1
  333. package/templates/.agents/rules/security-alerts.en.md +8 -8
  334. package/templates/.agents/rules/security-alerts.zh-CN.md +8 -8
  335. package/templates/.agents/rules/testing-discipline.en.md +2 -0
  336. package/templates/.agents/rules/testing-discipline.zh-CN.md +2 -0
  337. package/templates/.agents/scripts/package.json +3 -0
  338. package/templates/.agents/skills/analyze-task/SKILL.en.md +15 -2
  339. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +19 -2
  340. package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -12
  341. package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -12
  342. package/templates/.agents/skills/close-codescan/SKILL.en.md +2 -2
  343. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +2 -2
  344. package/templates/.agents/skills/close-dependabot/SKILL.en.md +2 -2
  345. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +2 -2
  346. package/templates/.agents/skills/code-task/SKILL.en.md +14 -1
  347. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +14 -1
  348. package/templates/.agents/skills/code-task/config/verify.en.json +5 -14
  349. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +5 -14
  350. package/templates/.agents/skills/code-task/reference/code-rules.en.md +5 -4
  351. package/templates/.agents/skills/code-task/reference/code-rules.zh-CN.md +5 -4
  352. package/templates/.agents/skills/code-task/reference/dual-mode.en.md +1 -1
  353. package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +1 -1
  354. package/templates/.agents/skills/code-task/reference/fix-mode.en.md +3 -1
  355. package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +3 -1
  356. package/templates/.agents/skills/code-task/reference/report-template.en.md +42 -15
  357. package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +39 -12
  358. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +37 -21
  359. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +37 -21
  360. package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -1
  361. package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -1
  362. package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +4 -0
  363. package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +4 -0
  364. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +16 -7
  365. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +16 -7
  366. package/templates/.agents/skills/complete-task/SKILL.en.md +10 -23
  367. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +10 -23
  368. package/templates/.agents/skills/create-task/SKILL.en.md +8 -0
  369. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +7 -0
  370. package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
  371. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
  372. package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
  373. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
  374. package/templates/.agents/skills/init-labels/SKILL.en.md +8 -8
  375. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +8 -8
  376. package/templates/.agents/skills/init-milestones/SKILL.en.md +9 -11
  377. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +9 -11
  378. package/templates/.agents/skills/plan-task/SKILL.en.md +14 -1
  379. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +16 -1
  380. package/templates/.agents/skills/plan-task/config/verify.en.json +4 -14
  381. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +4 -14
  382. package/templates/.agents/skills/release/SKILL.en.md +7 -3
  383. package/templates/.agents/skills/release/SKILL.zh-CN.md +7 -3
  384. package/templates/.agents/skills/review-analysis/SKILL.en.md +14 -1
  385. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +14 -1
  386. package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -18
  387. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -18
  388. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +50 -23
  389. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +45 -18
  390. package/templates/.agents/skills/review-code/SKILL.en.md +14 -1
  391. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +14 -1
  392. package/templates/.agents/skills/review-code/config/verify.en.json +1 -23
  393. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -23
  394. package/templates/.agents/skills/review-code/reference/report-template.en.md +49 -22
  395. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +45 -18
  396. package/templates/.agents/skills/review-plan/SKILL.en.md +14 -1
  397. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +14 -1
  398. package/templates/.agents/skills/review-plan/config/verify.en.json +1 -18
  399. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -18
  400. package/templates/.agents/skills/review-plan/reference/report-template.en.md +49 -22
  401. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +45 -18
  402. package/templates/.agents/skills/review-pr/SKILL.en.md +5 -1
  403. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +5 -1
  404. package/templates/.agents/skills/review-pr/reference/report-template.en.md +4 -3
  405. package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +4 -3
  406. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +25 -4
  407. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +25 -4
  408. package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.en.md +4 -1
  409. package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.zh-CN.md +4 -1
  410. package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +5 -1
  411. package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +5 -1
  412. package/templates/.agents/skills/run-task/SKILL.en.md +1 -1
  413. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +1 -1
  414. package/templates/.agents/skills/test/SKILL.en.md +29 -7
  415. package/templates/.agents/skills/test/SKILL.zh-CN.md +29 -7
  416. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +14 -0
  417. package/templates/.agents/templates/task.en.md +6 -0
  418. package/templates/.agents/templates/task.zh-CN.md +6 -0
  419. package/templates/.claude/commands/run-manual-validation.en.md +1 -1
  420. package/templates/.claude/commands/run-manual-validation.zh-CN.md +1 -1
  421. package/dist/lib/platform/adapters.js +0 -56
  422. package/lib/platform/adapters.ts +0 -197
  423. package/templates/.agents/scripts/security-alerts.github.sh +0 -151
  424. package/templates/.agents/scripts/security-alerts.sh +0 -31
  425. package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +0 -146
  426. package/templates/.agents/skills/init-labels/scripts/init-labels.sh +0 -32
  427. package/templates/.agents/skills/init-milestones/scripts/init-milestones.github.sh +0 -294
  428. package/templates/.agents/skills/init-milestones/scripts/init-milestones.sh +0 -6
@@ -1,4 +1,6 @@
1
1
  import path from 'node:path';
2
+ import crypto from 'node:crypto';
3
+ import fs from 'node:fs';
2
4
 
3
5
  import { normalizeAgentToken } from '../agent-clients/tokens.ts';
4
6
  import { isAgentClientId } from '../agent-clients/types.ts';
@@ -20,7 +22,11 @@ import {
20
22
  sealOrchestrationDelegation,
21
23
  statusOrchestration
22
24
  } from './orchestration.ts';
23
- import type { OrchestrationOptions, OrchestrationResult } from './orchestration.ts';
25
+ import type {
26
+ OrchestrationDiagnosticLogger,
27
+ OrchestrationOptions,
28
+ OrchestrationResult
29
+ } from './orchestration.ts';
24
30
  import { prepareCodexOrchestrationDelegation } from './codex-orchestration.ts';
25
31
  import {
26
32
  applyTaskFinalization,
@@ -33,9 +39,478 @@ import {
33
39
  type TaskLifecycleRequest,
34
40
  type TaskLifecycleResult
35
41
  } from './lifecycle.ts';
42
+ import { locateActivityLog } from './activity-log.ts';
36
43
  import { resolveTaskRef, TASK_ID_RE } from './resolve-ref.ts';
37
44
  import { TaskExecutionLockError, withTaskExecutionLock } from './task-execution-lock.ts';
38
45
  import { verifyTaskEvent } from './verification.ts';
46
+ import { createCodexCapabilityStore } from '../agent-clients/adapters/codex-lifecycle/capability-store.ts';
47
+ import {
48
+ findArtifactRepairIntentsByOperation,
49
+ writeArtifactRepairIntent,
50
+ type ArtifactRepairIntent
51
+ } from './artifact-repair-intent.ts';
52
+ import {
53
+ computeLifecycleBuildIdentity,
54
+ verifyLifecycleBuildIdentity,
55
+ type LifecycleBuildIdentity
56
+ } from '../agent-clients/adapters/codex-lifecycle/build-identity.ts';
57
+
58
+ export type LifecycleAuthorityPhase =
59
+ | 'orchestration.prepare'
60
+ | 'artifact.finalize-local'
61
+ | 'task-event.completed';
62
+
63
+ export type LifecycleAuthorityRequestV1 = Readonly<{
64
+ version: 1;
65
+ requestId: string;
66
+ operationId: string;
67
+ phase: LifecycleAuthorityPhase;
68
+ taskId: string;
69
+ family: 'analysis' | 'plan' | 'code';
70
+ artifact: string;
71
+ round: number;
72
+ lifecycleRequestId: string;
73
+ authorityRef: string;
74
+ expectedControlGeneration: string;
75
+ expectedControllerInstanceDigest: string;
76
+ expectedBuildIdentityDigest: string;
77
+ expectedHookDefinitionHash: string;
78
+ }>;
79
+
80
+ export type LifecycleRecoveryAttestationV1 = Readonly<{
81
+ version: 1;
82
+ attestationId: string;
83
+ authorityRefDigest: string;
84
+ operationId: string;
85
+ phase: LifecycleAuthorityPhase;
86
+ requestId: string;
87
+ lifecycleRequestId: string;
88
+ taskId: string;
89
+ family: 'analysis' | 'plan' | 'code';
90
+ artifact: string;
91
+ round: number;
92
+ controlGeneration: string;
93
+ controllerInstanceDigest: string;
94
+ sessionId: string;
95
+ turnId: string;
96
+ toolUseId: string;
97
+ buildIdentityDigest: string;
98
+ hookDefinitionHash: string;
99
+ issuedAt: number;
100
+ expiresAt: number;
101
+ }>;
102
+
103
+ export type LifecycleAuthorityResponseV1 = Readonly<{
104
+ version: 1;
105
+ requestId: string;
106
+ operationId: string;
107
+ phase: LifecycleAuthorityPhase;
108
+ status: 'issued' | 'already-completed' | 'rejected';
109
+ attestation: LifecycleRecoveryAttestationV1 | null;
110
+ error: { code: string; message: string } | null;
111
+ }>;
112
+
113
+ type LifecycleAuthorityIssuerOptions = Readonly<{
114
+ controllerBinding?: TaskControlControllerBinding | null;
115
+ capabilityStore?: ReturnType<typeof createCodexCapabilityStore>;
116
+ buildIdentity?: LifecycleBuildIdentity;
117
+ now?: () => number;
118
+ operationAttestations?: Map<string, LifecycleRecoveryAttestationV1>;
119
+ }>;
120
+
121
+ export type LifecycleRecoveryOperationQueryV1 = Readonly<{
122
+ version: 1;
123
+ operationId: string;
124
+ status: 'unknown' | 'in-progress' | 'committed';
125
+ capabilityState: 'unknown' | 'reserved' | 'consumed';
126
+ phases: readonly Readonly<{
127
+ phase: LifecycleAuthorityPhase;
128
+ requestId: string;
129
+ attestationId: string | null;
130
+ state: 'issued' | 'consumed' | 'observed';
131
+ }>[];
132
+ }>;
133
+
134
+ const lifecycleAuthorityPhases: readonly LifecycleAuthorityPhase[] = [
135
+ 'orchestration.prepare', 'artifact.finalize-local', 'task-event.completed'
136
+ ];
137
+ const lifecycleAuthorityFamilies = ['analysis', 'plan', 'code'] as const;
138
+ const lifecycleAuthorityArtifact = /^(?:analysis|plan|code)(?:-r[1-9]\d*)?\.md$/u;
139
+ const lifecycleAuthorityDigest = (value: string): string => crypto.createHash('sha256').update(value, 'utf8').digest('hex');
140
+ const lifecycleAuthorityBuildDigest = (value: LifecycleBuildIdentity): string => lifecycleAuthorityDigest(JSON.stringify(value));
141
+
142
+ export function lifecycleRecoveryAttestationDigest(value: LifecycleRecoveryAttestationV1): string {
143
+ return lifecycleAuthorityDigest(JSON.stringify(value));
144
+ }
145
+
146
+ function authorityExactKeys(value: Record<string, unknown>, keys: readonly string[]): boolean {
147
+ return Object.keys(value).sort().join(',') === [...keys].sort().join(',');
148
+ }
149
+
150
+ export function validateLifecycleAuthorityRequest(value: unknown): LifecycleAuthorityRequestV1 {
151
+ if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error('LIFECYCLE_AUTHORITY_REQUEST_INVALID');
152
+ const request = value as Record<string, unknown>;
153
+ if (!authorityExactKeys(request, [
154
+ 'artifact', 'authorityRef', 'expectedBuildIdentityDigest', 'expectedControlGeneration',
155
+ 'expectedControllerInstanceDigest', 'expectedHookDefinitionHash', 'family', 'lifecycleRequestId',
156
+ 'operationId', 'phase', 'requestId', 'round', 'taskId', 'version'
157
+ ])
158
+ || request.version !== 1
159
+ || typeof request.requestId !== 'string' || !/^[a-f0-9-]{16,64}$/u.test(request.requestId)
160
+ || typeof request.operationId !== 'string' || !/^[a-f0-9-]{16,64}$/u.test(request.operationId)
161
+ || !lifecycleAuthorityPhases.includes(request.phase as LifecycleAuthorityPhase)
162
+ || typeof request.taskId !== 'string' || !/^TASK-\d{8}-\d{6}$/u.test(request.taskId)
163
+ || !lifecycleAuthorityFamilies.includes(request.family as typeof lifecycleAuthorityFamilies[number])
164
+ || typeof request.artifact !== 'string' || !lifecycleAuthorityArtifact.test(request.artifact)
165
+ || !Number.isSafeInteger(request.round) || (request.round as number) < 1
166
+ || typeof request.lifecycleRequestId !== 'string' || !request.lifecycleRequestId || /[\r\n]/u.test(request.lifecycleRequestId)
167
+ || typeof request.authorityRef !== 'string' || !request.authorityRef || /[\r\n]/u.test(request.authorityRef)
168
+ || typeof request.expectedControlGeneration !== 'string' || !request.expectedControlGeneration
169
+ || typeof request.expectedControllerInstanceDigest !== 'string' || !/^[a-f0-9]{64}$/u.test(request.expectedControllerInstanceDigest)
170
+ || typeof request.expectedBuildIdentityDigest !== 'string' || !/^[a-f0-9]{64}$/u.test(request.expectedBuildIdentityDigest)
171
+ || typeof request.expectedHookDefinitionHash !== 'string' || !/^[a-f0-9]{64}$/u.test(request.expectedHookDefinitionHash)) {
172
+ throw new Error('LIFECYCLE_AUTHORITY_REQUEST_INVALID');
173
+ }
174
+ const expectedArtifactFamily = request.artifact as string;
175
+ if (!expectedArtifactFamily.startsWith(request.family as string)) throw new Error('LIFECYCLE_AUTHORITY_REQUEST_INVALID');
176
+ return request as LifecycleAuthorityRequestV1;
177
+ }
178
+
179
+ export function validateLifecycleRecoveryAttestation(
180
+ value: unknown,
181
+ now = Date.now()
182
+ ): LifecycleRecoveryAttestationV1 {
183
+ if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error('LIFECYCLE_AUTHORITY_ATTESTATION_INVALID');
184
+ const attestation = value as Record<string, unknown>;
185
+ if (!authorityExactKeys(attestation, [
186
+ 'artifact', 'attestationId', 'authorityRefDigest', 'buildIdentityDigest', 'controlGeneration',
187
+ 'controllerInstanceDigest', 'expiresAt', 'family', 'hookDefinitionHash', 'issuedAt',
188
+ 'lifecycleRequestId', 'operationId', 'phase', 'requestId', 'round', 'sessionId',
189
+ 'taskId', 'toolUseId', 'turnId', 'version'
190
+ ])
191
+ || attestation.version !== 1
192
+ || typeof attestation.attestationId !== 'string' || !/^[a-f0-9-]{16,64}$/u.test(attestation.attestationId)
193
+ || typeof attestation.authorityRefDigest !== 'string' || !/^[a-f0-9]{64}$/u.test(attestation.authorityRefDigest)
194
+ || typeof attestation.operationId !== 'string' || !/^[a-f0-9-]{16,64}$/u.test(attestation.operationId)
195
+ || !lifecycleAuthorityPhases.includes(attestation.phase as LifecycleAuthorityPhase)
196
+ || typeof attestation.requestId !== 'string' || !/^[a-f0-9-]{16,64}$/u.test(attestation.requestId)
197
+ || typeof attestation.lifecycleRequestId !== 'string' || !attestation.lifecycleRequestId
198
+ || typeof attestation.taskId !== 'string' || !/^TASK-\d{8}-\d{6}$/u.test(attestation.taskId)
199
+ || !lifecycleAuthorityFamilies.includes(attestation.family as typeof lifecycleAuthorityFamilies[number])
200
+ || typeof attestation.artifact !== 'string' || !lifecycleAuthorityArtifact.test(attestation.artifact)
201
+ || !Number.isSafeInteger(attestation.round) || (attestation.round as number) < 1
202
+ || typeof attestation.controlGeneration !== 'string' || !attestation.controlGeneration
203
+ || typeof attestation.controllerInstanceDigest !== 'string' || !/^[a-f0-9]{64}$/u.test(attestation.controllerInstanceDigest)
204
+ || typeof attestation.sessionId !== 'string' || !attestation.sessionId
205
+ || typeof attestation.turnId !== 'string' || !attestation.turnId
206
+ || typeof attestation.toolUseId !== 'string' || !attestation.toolUseId
207
+ || typeof attestation.buildIdentityDigest !== 'string' || !/^[a-f0-9]{64}$/u.test(attestation.buildIdentityDigest)
208
+ || typeof attestation.hookDefinitionHash !== 'string' || !/^[a-f0-9]{64}$/u.test(attestation.hookDefinitionHash)
209
+ || !Number.isSafeInteger(attestation.issuedAt) || !Number.isSafeInteger(attestation.expiresAt)
210
+ || (attestation.expiresAt as number) <= (attestation.issuedAt as number)
211
+ || (attestation.expiresAt as number) <= now) {
212
+ throw new Error('LIFECYCLE_AUTHORITY_ATTESTATION_INVALID');
213
+ }
214
+ return attestation as LifecycleRecoveryAttestationV1;
215
+ }
216
+
217
+ const authorityOperationMap = new WeakMap<object, Map<string, LifecycleRecoveryAttestationV1>>();
218
+ const authorityRecords = new Map<string, Readonly<{
219
+ store: ReturnType<typeof createCodexCapabilityStore>;
220
+ capabilityRef: string;
221
+ expected: Readonly<{
222
+ taskId: string;
223
+ hookDefinitionHash: string;
224
+ buildIdentity: LifecycleBuildIdentity;
225
+ controller: TaskControlControllerBinding;
226
+ }>;
227
+ }>>();
228
+ const consumedAuthorityPhases = new Set<string>();
229
+
230
+ export function issueLifecycleRecoveryAttestation(
231
+ input: LifecycleAuthorityRequestV1,
232
+ options: LifecycleAuthorityIssuerOptions = {}
233
+ ): LifecycleAuthorityResponseV1 {
234
+ let request: LifecycleAuthorityRequestV1;
235
+ try { request = validateLifecycleAuthorityRequest(input); }
236
+ catch (error) {
237
+ return { version: 1, requestId: String((input as { requestId?: unknown })?.requestId ?? ''), operationId: String((input as { operationId?: unknown })?.operationId ?? ''), phase: (input as { phase?: LifecycleAuthorityPhase })?.phase ?? 'artifact.finalize-local', status: 'rejected', attestation: null, error: { code: 'LIFECYCLE_AUTHORITY_REQUEST_INVALID', message: error instanceof Error ? error.message : String(error) } };
238
+ }
239
+ const binding = options.controllerBinding ?? null;
240
+ if (!binding) return authorityRejected(request, 'LOCAL_EXECUTION_AUTHORITY_UNAVAILABLE', 'current controller authority is unavailable');
241
+ if (binding.controlGeneration !== request.expectedControlGeneration
242
+ || binding.instanceDigest !== request.expectedControllerInstanceDigest) {
243
+ return authorityRejected(request, 'LIFECYCLE_AUTHORITY_CONTROLLER_MISMATCH', 'current controller binding does not match the request');
244
+ }
245
+ const buildIdentity = options.buildIdentity ?? computeLifecycleBuildIdentity(process.cwd());
246
+ if (lifecycleAuthorityBuildDigest(buildIdentity) !== request.expectedBuildIdentityDigest) {
247
+ return authorityRejected(request, 'LIFECYCLE_AUTHORITY_BUILD_MISMATCH', 'current lifecycle build does not match the request');
248
+ }
249
+ const store = options.capabilityStore ?? createCodexCapabilityStore();
250
+ const registry = options.operationAttestations ?? authorityOperationMap.get(store) ?? new Map<string, LifecycleRecoveryAttestationV1>();
251
+ authorityOperationMap.set(store, registry);
252
+ const key = `${request.requestId}\0${request.operationId}\0${request.phase}`;
253
+ const prior = registry.get(key);
254
+ if (prior) return { version: 1, requestId: request.requestId, operationId: request.operationId, phase: request.phase, status: 'already-completed', attestation: prior, error: null };
255
+ try {
256
+ const expected = {
257
+ taskId: request.taskId,
258
+ hookDefinitionHash: request.expectedHookDefinitionHash,
259
+ buildIdentity,
260
+ controller: binding
261
+ };
262
+ const record = store.reserveReference(request.authorityRef, request.operationId, expected);
263
+ if (!record.sessionId || !record.turnId || !record.toolUseId) throw new Error('CODEX_CAPABILITY_IDENTITY_INVALID: capability hook attestation is incomplete');
264
+ const now = (options.now ?? Date.now)();
265
+ const attestation = validateLifecycleRecoveryAttestation({
266
+ version: 1,
267
+ attestationId: crypto.randomUUID(),
268
+ authorityRefDigest: lifecycleAuthorityDigest(request.authorityRef),
269
+ operationId: request.operationId,
270
+ phase: request.phase,
271
+ requestId: request.requestId,
272
+ lifecycleRequestId: request.lifecycleRequestId,
273
+ taskId: request.taskId,
274
+ family: request.family,
275
+ artifact: request.artifact,
276
+ round: request.round,
277
+ controlGeneration: binding.controlGeneration,
278
+ controllerInstanceDigest: binding.instanceDigest,
279
+ sessionId: record.sessionId,
280
+ turnId: record.turnId,
281
+ toolUseId: record.toolUseId,
282
+ buildIdentityDigest: lifecycleAuthorityBuildDigest(buildIdentity),
283
+ hookDefinitionHash: request.expectedHookDefinitionHash,
284
+ issuedAt: now,
285
+ expiresAt: Math.min(record.expiresAt, now + 30_000)
286
+ }, now);
287
+ store.reserveRecoveryPhase(
288
+ request.authorityRef,
289
+ request.operationId,
290
+ request.phase,
291
+ request.requestId,
292
+ expected
293
+ );
294
+ registry.set(key, attestation);
295
+ authorityRecords.set(attestation.attestationId, { store, capabilityRef: request.authorityRef, expected });
296
+ return { version: 1, requestId: request.requestId, operationId: request.operationId, phase: request.phase, status: 'issued', attestation, error: null };
297
+ } catch (error) {
298
+ return authorityRejected(request, error instanceof Error && error.name.startsWith('CODEX_') ? error.name : 'LIFECYCLE_AUTHORITY_REJECTED', error instanceof Error ? error.message : String(error));
299
+ }
300
+ }
301
+
302
+ export function consumeLifecycleRecoveryAttestation(
303
+ value: LifecycleRecoveryAttestationV1,
304
+ now = Date.now()
305
+ ): void {
306
+ const attestation = validateLifecycleRecoveryAttestation(value, now);
307
+ if (consumedAuthorityPhases.has(attestation.attestationId)) return;
308
+ const record = authorityRecords.get(attestation.attestationId);
309
+ if (!record) throw new Error('LIFECYCLE_AUTHORITY_ATTESTATION_UNKNOWN');
310
+ record.store.consumeRecoveryPhase(
311
+ record.capabilityRef,
312
+ attestation.operationId,
313
+ attestation.phase,
314
+ attestation.requestId,
315
+ record.expected
316
+ );
317
+ if (attestation.phase === 'task-event.completed') {
318
+ record.store.consumeReference(record.capabilityRef, attestation.operationId, record.expected);
319
+ }
320
+ consumedAuthorityPhases.add(attestation.attestationId);
321
+ }
322
+
323
+ export function queryLifecycleRecoveryOperation(
324
+ operationId: string,
325
+ options: Readonly<{
326
+ repoRoot?: string;
327
+ capabilityStore?: ReturnType<typeof createCodexCapabilityStore>;
328
+ }> = {}
329
+ ): LifecycleRecoveryOperationQueryV1 {
330
+ if (!/^[a-f0-9-]{16,64}$/u.test(operationId)) {
331
+ throw new Error('LIFECYCLE_RECOVERY_OPERATION_INVALID');
332
+ }
333
+ const store = options.capabilityStore ?? createCodexCapabilityStore();
334
+ const registry = authorityOperationMap.get(store);
335
+ const known = [...(registry?.values() ?? [])].filter((value) => value.operationId === operationId);
336
+ const intents = options.repoRoot ? findArtifactRepairIntentsByOperation(options.repoRoot, operationId) : [];
337
+ const capabilities = store.findByRecoveryOperation(operationId);
338
+ const phaseMap = new Map<string, LifecycleRecoveryOperationQueryV1['phases'][number]>();
339
+ for (const capability of capabilities) {
340
+ for (const phase of capability.recoveryPhases) {
341
+ phaseMap.set(`${phase.phase}\0${phase.requestId}`, {
342
+ phase: phase.phase,
343
+ requestId: phase.requestId,
344
+ attestationId: null,
345
+ state: phase.state === 'consumed' ? 'consumed' : 'observed'
346
+ });
347
+ }
348
+ }
349
+ for (const attestation of known) {
350
+ const key = `${attestation.phase}\0${attestation.requestId}`;
351
+ const durable = phaseMap.get(key);
352
+ phaseMap.set(key, {
353
+ phase: attestation.phase,
354
+ requestId: attestation.requestId,
355
+ attestationId: attestation.attestationId,
356
+ state: durable?.state === 'consumed' || consumedAuthorityPhases.has(attestation.attestationId)
357
+ ? 'consumed' : 'issued'
358
+ });
359
+ }
360
+ for (const intent of intents) {
361
+ if (!intent.phase) continue;
362
+ const key = `${intent.phase}\0${intent.requestId}`;
363
+ if (phaseMap.has(key)) continue;
364
+ phaseMap.set(key, {
365
+ phase: intent.phase,
366
+ requestId: intent.requestId,
367
+ attestationId: null,
368
+ state: intent.state === 'consumed' ? 'consumed' : 'observed'
369
+ });
370
+ }
371
+ const capabilityState = capabilities.some((record) => record.recoveryState === 'consumed')
372
+ ? 'consumed'
373
+ : capabilities.some((record) => record.recoveryState === 'reserved') ? 'reserved' : 'unknown';
374
+ const committed = capabilityState === 'consumed' || intents.some((intent) => intent.state === 'consumed');
375
+ return {
376
+ version: 1,
377
+ operationId,
378
+ status: committed ? 'committed' : capabilityState === 'reserved' || phaseMap.size > 0 ? 'in-progress' : 'unknown',
379
+ capabilityState,
380
+ phases: Object.freeze([...phaseMap.values()])
381
+ };
382
+ }
383
+
384
+ type LifecycleRecoveryCompensationOptions = Readonly<{
385
+ repoRoot: string;
386
+ controllerBinding: TaskControlControllerBinding;
387
+ capabilityStore?: ReturnType<typeof createCodexCapabilityStore>;
388
+ buildIdentity?: LifecycleBuildIdentity;
389
+ now?: () => number;
390
+ }>;
391
+
392
+ function lifecycleRecoveryCompensationError(code: string, message: string): Error {
393
+ const error = new Error(`${code}: ${message}`);
394
+ error.name = code;
395
+ return error;
396
+ }
397
+
398
+ function lifecycleRecoveryEventCommitted(
399
+ selector: LifecycleAuthorityRequestV1,
400
+ repoRoot: string
401
+ ): boolean {
402
+ const resolved = resolveTaskRef(selector.taskId, { repoRoot });
403
+ if (!resolved.ok || resolved.taskId !== selector.taskId) return false;
404
+ let content: string;
405
+ try { content = fs.readFileSync(resolved.taskMdPath, 'utf8'); }
406
+ catch { return false; }
407
+ const section = locateActivityLog(content);
408
+ if (!section) return false;
409
+ const labels = { analysis: 'Analyze Task', plan: 'Plan Task', code: 'Code Task' } as const;
410
+ const prefix = `${labels[selector.family]} (Round ${selector.round}`;
411
+ return section.entries.some((entry) => {
412
+ if (entry.step.endsWith(' [started]') || !entry.step.startsWith(prefix)) return false;
413
+ const delimiter = entry.step[prefix.length];
414
+ return (delimiter === ',' || delimiter === ')') && entry.note.endsWith(`→ ${selector.artifact}`);
415
+ });
416
+ }
417
+
418
+ function lifecycleRecoveryIntentMatches(
419
+ intent: ArtifactRepairIntent,
420
+ selector: LifecycleAuthorityRequestV1
421
+ ): boolean {
422
+ return intent.taskId === selector.taskId
423
+ && intent.family === selector.family
424
+ && intent.artifact === selector.artifact
425
+ && (intent.state === 'commit-started' || intent.state === 'consumed');
426
+ }
427
+
428
+ /**
429
+ * Completes only the durable tail of a committed task event after a process
430
+ * restart. The task event itself is the commit boundary and is never replayed.
431
+ */
432
+ export function recoverLifecycleRecoveryOperation(
433
+ input: LifecycleAuthorityRequestV1,
434
+ options: LifecycleRecoveryCompensationOptions
435
+ ): LifecycleRecoveryOperationQueryV1 {
436
+ const selector = validateLifecycleAuthorityRequest(input);
437
+ if (selector.phase !== 'task-event.completed') {
438
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_RECOVERY_PHASE_UNSUPPORTED', 'only task-event.completed supports durable compensation');
439
+ }
440
+ const buildIdentity = options.buildIdentity ?? computeLifecycleBuildIdentity(options.repoRoot);
441
+ if (selector.expectedBuildIdentityDigest !== lifecycleAuthorityBuildDigest(buildIdentity)) {
442
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_AUTHORITY_BUILD_MISMATCH', 'current lifecycle build does not match the recovery request');
443
+ }
444
+ if (selector.expectedControlGeneration !== options.controllerBinding.controlGeneration
445
+ || selector.expectedControllerInstanceDigest !== options.controllerBinding.instanceDigest) {
446
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_AUTHORITY_CONTROLLER_MISMATCH', 'current controller binding does not match the recovery request');
447
+ }
448
+ const store = options.capabilityStore ?? createCodexCapabilityStore();
449
+ const expected = {
450
+ taskId: selector.taskId,
451
+ hookDefinitionHash: selector.expectedHookDefinitionHash,
452
+ buildIdentity,
453
+ controller: options.controllerBinding
454
+ };
455
+ const capabilities = store.findByRecoveryOperation(selector.operationId);
456
+ if (capabilities.length !== 1 || capabilities[0]!.capabilityRefDigest !== lifecycleAuthorityDigest(selector.authorityRef)) {
457
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_RECOVERY_PROVENANCE_INVALID', 'durable capability provenance does not identify this operation');
458
+ }
459
+ const capability = capabilities[0]!;
460
+ const build = verifyLifecycleBuildIdentity(capability.buildIdentity, buildIdentity);
461
+ const expiredReserved = capability.status === 'expired' && capability.recoveryState === 'reserved';
462
+ if (!build.ok
463
+ || capability.taskId !== selector.taskId
464
+ || capability.hookDefinitionHash !== selector.expectedHookDefinitionHash
465
+ || capability.controller?.controlGeneration !== options.controllerBinding.controlGeneration
466
+ || capability.controller?.instanceDigest !== options.controllerBinding.instanceDigest
467
+ || capability.recoveryState === 'unreserved'
468
+ || capability.recoveryOperationId !== selector.operationId
469
+ || (!['attested', 'consumed'].includes(capability.status) && !expiredReserved)) {
470
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_RECOVERY_PROVENANCE_INVALID', 'durable capability provenance does not match the recovery request');
471
+ }
472
+ const phase = capability.recoveryPhases.find((entry) => entry.phase === selector.phase);
473
+ if (!phase) {
474
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_RECOVERY_PHASE_MISSING', 'durable task completion phase is missing');
475
+ }
476
+ const intents = findArtifactRepairIntentsByOperation(options.repoRoot, selector.operationId)
477
+ .filter((intent) => intent.taskId === selector.taskId
478
+ && intent.family === selector.family
479
+ && intent.artifact === selector.artifact);
480
+ if (intents.length !== 1) {
481
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_RECOVERY_INTENT_INVALID', 'durable artifact repair intent does not identify this task event');
482
+ }
483
+ const intent = intents[0]!;
484
+ if (!lifecycleRecoveryIntentMatches(intent, selector)
485
+ || intent.phase !== selector.phase
486
+ || intent.requestId !== selector.lifecycleRequestId
487
+ || intent.authorityDigest === null) {
488
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_RECOVERY_INTENT_INVALID', 'durable artifact repair intent does not match the recovery request');
489
+ }
490
+ if (!lifecycleRecoveryEventCommitted(selector, options.repoRoot)) {
491
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_RECOVERY_COMMIT_UNCONFIRMED', 'task completion is not durably present; compensation is not allowed');
492
+ }
493
+ if (capability.recoveryState === 'reserved') {
494
+ if (phase.state === 'issued') {
495
+ store.consumeRecoveryPhase(selector.authorityRef, selector.operationId, selector.phase, phase.requestId, expected, { allowExpiredReserved: true });
496
+ }
497
+ store.consumeReference(selector.authorityRef, selector.operationId, expected, { allowExpiredReserved: true });
498
+ } else if (phase.state !== 'consumed') {
499
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_RECOVERY_STATE_INVALID', 'consumed capability has an unconsumed completion phase');
500
+ }
501
+ if (intent.state !== 'consumed') {
502
+ writeArtifactRepairIntent(options.repoRoot, {
503
+ ...intent,
504
+ state: 'consumed',
505
+ updatedAt: (options.now ?? Date.now)()
506
+ }, { expected: intent });
507
+ }
508
+ return queryLifecycleRecoveryOperation(selector.operationId, { repoRoot: options.repoRoot, capabilityStore: store });
509
+ }
510
+
511
+ function authorityRejected(request: LifecycleAuthorityRequestV1, code: string, message: string): LifecycleAuthorityResponseV1 {
512
+ return { version: 1, requestId: request.requestId, operationId: request.operationId, phase: request.phase, status: 'rejected', attestation: null, error: { code, message } };
513
+ }
39
514
 
40
515
  export type TaskControlControllerBinding = Readonly<{
41
516
  instanceDigest: string;
@@ -49,6 +524,7 @@ export type TaskControlExecutionContext =
49
524
  repoRoot: string;
50
525
  runtimeDir?: string;
51
526
  controllerBinding?: TaskControlControllerBinding | null;
527
+ lifecycleRecoveryAttestation?: LifecycleRecoveryAttestationV1 | null;
52
528
  }>
53
529
  | Readonly<{
54
530
  source: 'sandbox-executor';
@@ -60,7 +536,9 @@ export type TaskControlExecutionContext =
60
536
  generation: string;
61
537
  manifestPath: string;
62
538
  requestId: string;
539
+ diagnosticLog?: OrchestrationDiagnosticLogger;
63
540
  controllerBinding?: TaskControlControllerBinding | null;
541
+ lifecycleRecoveryAttestation?: LifecycleRecoveryAttestationV1 | null;
64
542
  }>;
65
543
 
66
544
  export type TaskControlOrchestrationIntent =
@@ -89,6 +567,14 @@ export type TaskControlOperation =
89
567
 
90
568
  export type TaskControlDispatchResult = TaskLifecycleResult | TaskFinalizationResult | OrchestrationResult;
91
569
 
570
+ export function taskControlOperationKey(operation: TaskControlOperation): string {
571
+ if (operation.family === 'task-finalization') return 'complete';
572
+ if (operation.family === 'task-lifecycle') return operation.request.intent;
573
+ return operation.intent === 'route'
574
+ ? operation.input && operation.input.completed === true ? 'route.clean-completion' : 'route.read'
575
+ : operation.intent;
576
+ }
577
+
92
578
  export type TaskLifecycleControlRequest = TaskLifecycleRequest & Readonly<{
93
579
  overrideTicket?: string;
94
580
  overrideTarget?: string;
@@ -116,13 +602,18 @@ export function createDirectHostExecutionContext(params: Readonly<{
116
602
  repoRoot: string;
117
603
  runtimeDir?: string;
118
604
  controllerBinding?: TaskControlControllerBinding | null;
605
+ lifecycleRecoveryAttestation?: LifecycleRecoveryAttestationV1 | null;
119
606
  }>): TaskControlExecutionContext {
120
607
  return {
121
608
  source: 'direct-host',
122
609
  mode: 'direct-host',
123
610
  repoRoot: absolute('repoRoot', params.repoRoot),
124
611
  ...(params.runtimeDir === undefined ? {} : { runtimeDir: absolute('runtimeDir', params.runtimeDir) }),
125
- ...(params.controllerBinding === undefined ? {} : { controllerBinding: binding(params.controllerBinding) })
612
+ ...(params.controllerBinding === undefined ? {} : { controllerBinding: binding(params.controllerBinding) }),
613
+ ...(params.lifecycleRecoveryAttestation === undefined ? {} : {
614
+ lifecycleRecoveryAttestation: params.lifecycleRecoveryAttestation === null
615
+ ? null : validateLifecycleRecoveryAttestation(params.lifecycleRecoveryAttestation)
616
+ })
126
617
  };
127
618
  }
128
619
 
@@ -134,7 +625,9 @@ export function createSandboxExecutorExecutionContext(params: Readonly<{
134
625
  generation: string;
135
626
  manifestPath: string;
136
627
  requestId: string;
628
+ diagnosticLog?: OrchestrationDiagnosticLogger;
137
629
  controllerBinding?: TaskControlControllerBinding | null;
630
+ lifecycleRecoveryAttestation?: LifecycleRecoveryAttestationV1 | null;
138
631
  }>): TaskControlExecutionContext {
139
632
  if (!/^TASK-\d{8}-\d{6}$/u.test(params.taskId) || !params.generation || !params.requestId) {
140
633
  invalidContext('sandbox binding is incomplete');
@@ -153,7 +646,12 @@ export function createSandboxExecutorExecutionContext(params: Readonly<{
153
646
  generation: params.generation,
154
647
  manifestPath: absolute('manifestPath', params.manifestPath),
155
648
  requestId: params.requestId,
156
- ...(params.controllerBinding === undefined ? {} : { controllerBinding: binding(params.controllerBinding) })
649
+ ...(params.diagnosticLog === undefined ? {} : { diagnosticLog: params.diagnosticLog }),
650
+ ...(params.controllerBinding === undefined ? {} : { controllerBinding: binding(params.controllerBinding) }),
651
+ ...(params.lifecycleRecoveryAttestation === undefined ? {} : {
652
+ lifecycleRecoveryAttestation: params.lifecycleRecoveryAttestation === null
653
+ ? null : validateLifecycleRecoveryAttestation(params.lifecycleRecoveryAttestation)
654
+ })
157
655
  };
158
656
  }
159
657
 
@@ -163,6 +661,7 @@ export function assertTaskControlExecutionContext(context: TaskControlExecutionC
163
661
  absolute('repoRoot', context.repoRoot);
164
662
  if (context.runtimeDir !== undefined) absolute('runtimeDir', context.runtimeDir);
165
663
  binding(context.controllerBinding);
664
+ if (context.lifecycleRecoveryAttestation) validateLifecycleRecoveryAttestation(context.lifecycleRecoveryAttestation);
166
665
  return;
167
666
  }
168
667
  if (context.mode !== 'task-bound-sandbox' || !/^TASK-\d{8}-\d{6}$/u.test(context.taskId)
@@ -177,6 +676,7 @@ export function assertTaskControlExecutionContext(context: TaskControlExecutionC
177
676
  invalidContext('runtimeDir is not bound to the manifest control root');
178
677
  }
179
678
  binding(context.controllerBinding);
679
+ if (context.lifecycleRecoveryAttestation) validateLifecycleRecoveryAttestation(context.lifecycleRecoveryAttestation);
180
680
  }
181
681
 
182
682
  function operationTaskId(context: TaskControlExecutionContext, taskRef: string): void {
@@ -192,6 +692,9 @@ function domainOptions(
192
692
  return {
193
693
  ...options,
194
694
  repoRoot: context.repoRoot,
695
+ ...(context.source === 'sandbox-executor' && context.diagnosticLog !== undefined
696
+ ? { diagnosticLog: context.diagnosticLog }
697
+ : {}),
195
698
  ...(context.source === 'sandbox-executor' ? { gitWorktreeRoot: context.worktreeRoot } : {})
196
699
  };
197
700
  }
@@ -274,12 +777,16 @@ function orchestration(
274
777
  client: input.client as AgentClientId,
275
778
  requestedModel: input.requestedModel as string | undefined,
276
779
  requestedReasoningEffort: input.requestedReasoningEffort as string | undefined,
277
- ...(input.capabilityToken === undefined ? {} : { capabilityToken: input.capabilityToken as string })
780
+ ...(input.capabilityRef === undefined ? {} : { capabilityRef: input.capabilityRef as string }),
781
+ ...(context.lifecycleRecoveryAttestation === undefined
782
+ ? {}
783
+ : { lifecycleRecoveryAttestation: context.lifecycleRecoveryAttestation })
278
784
  };
279
785
  if (prepareInput.client === 'codex') {
280
786
  return prepareCodexOrchestrationDelegation(operation.taskRef, prepareInput, {
281
787
  repoRoot: context.repoRoot,
282
788
  orchestrationOptions: options,
789
+ deferLifecycleRecoveryConsumption: context.source === 'sandbox-executor',
283
790
  ...(context.controllerBinding ? { controllerBinding: context.controllerBinding } : {})
284
791
  });
285
792
  }
@@ -393,7 +900,7 @@ const FINALIZATION_FLAGS = new Set(['--agent']);
393
900
  const ORCHESTRATION_FLAGS = new Set([
394
901
  '--agent', '--max-steps', '--executor-model', '--executor-reasoning-effort', '--reviewer-model',
395
902
  '--reviewer-reasoning-effort', '--client', '--requested-model', '--requested-reasoning-effort',
396
- '--capability-token', '--parent-id', '--before-fingerprint', '--stage', '--round', '--artifact', '--role',
903
+ '--capability-ref', '--parent-id', '--before-fingerprint', '--stage', '--round', '--artifact', '--role',
397
904
  '--native-agent', '--child-id', '--spawn-mode', '--actual-model', '--actual-reasoning-effort',
398
905
  '--model-fallback-reason', '--reasoning-effort-fallback-reason', '--exit-code', '--after-fingerprint',
399
906
  '--changed-paths', '--code', '--message', '--recoverable', '--git-worktree-root'
@@ -509,7 +1016,7 @@ export function parseTaskControlOperation(
509
1016
  if (parsedIntent === 'prepare') {
510
1017
  input.requestedModel = value(values, '--requested-model');
511
1018
  input.requestedReasoningEffort = value(values, '--requested-reasoning-effort');
512
- input.capabilityToken = value(values, '--capability-token');
1019
+ input.capabilityRef = value(values, '--capability-ref');
513
1020
  }
514
1021
  if (parsedIntent === 'await-activation') {
515
1022
  required(values, ['--stage', '--round', '--artifact', '--role']);