@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
  import { normalizeAgentToken } from '../agent-clients/tokens.js';
3
5
  import { isAgentClientId } from '../agent-clients/types.js';
4
6
  import { consumeHumanOverride, failureId, overrideDryRunConflict } from './human-override.js';
@@ -6,9 +8,357 @@ import { activateMatchingOrchestrationDelegation, activateOrchestrationDelegatio
6
8
  import { prepareCodexOrchestrationDelegation } from './codex-orchestration.js';
7
9
  import { applyTaskFinalization } from './finalization.js';
8
10
  import { applyTaskLifecycle, taskLifecycleFailure } from './lifecycle.js';
11
+ import { locateActivityLog } from './activity-log.js';
9
12
  import { resolveTaskRef, TASK_ID_RE } from './resolve-ref.js';
10
13
  import { TaskExecutionLockError, withTaskExecutionLock } from './task-execution-lock.js';
11
14
  import { verifyTaskEvent } from './verification.js';
15
+ import { createCodexCapabilityStore } from '../agent-clients/adapters/codex-lifecycle/capability-store.js';
16
+ import { findArtifactRepairIntentsByOperation, writeArtifactRepairIntent } from './artifact-repair-intent.js';
17
+ import { computeLifecycleBuildIdentity, verifyLifecycleBuildIdentity } from '../agent-clients/adapters/codex-lifecycle/build-identity.js';
18
+ const lifecycleAuthorityPhases = [
19
+ 'orchestration.prepare', 'artifact.finalize-local', 'task-event.completed'
20
+ ];
21
+ const lifecycleAuthorityFamilies = ['analysis', 'plan', 'code'];
22
+ const lifecycleAuthorityArtifact = /^(?:analysis|plan|code)(?:-r[1-9]\d*)?\.md$/u;
23
+ const lifecycleAuthorityDigest = (value) => crypto.createHash('sha256').update(value, 'utf8').digest('hex');
24
+ const lifecycleAuthorityBuildDigest = (value) => lifecycleAuthorityDigest(JSON.stringify(value));
25
+ export function lifecycleRecoveryAttestationDigest(value) {
26
+ return lifecycleAuthorityDigest(JSON.stringify(value));
27
+ }
28
+ function authorityExactKeys(value, keys) {
29
+ return Object.keys(value).sort().join(',') === [...keys].sort().join(',');
30
+ }
31
+ export function validateLifecycleAuthorityRequest(value) {
32
+ if (!value || typeof value !== 'object' || Array.isArray(value))
33
+ throw new Error('LIFECYCLE_AUTHORITY_REQUEST_INVALID');
34
+ const request = value;
35
+ if (!authorityExactKeys(request, [
36
+ 'artifact', 'authorityRef', 'expectedBuildIdentityDigest', 'expectedControlGeneration',
37
+ 'expectedControllerInstanceDigest', 'expectedHookDefinitionHash', 'family', 'lifecycleRequestId',
38
+ 'operationId', 'phase', 'requestId', 'round', 'taskId', 'version'
39
+ ])
40
+ || request.version !== 1
41
+ || typeof request.requestId !== 'string' || !/^[a-f0-9-]{16,64}$/u.test(request.requestId)
42
+ || typeof request.operationId !== 'string' || !/^[a-f0-9-]{16,64}$/u.test(request.operationId)
43
+ || !lifecycleAuthorityPhases.includes(request.phase)
44
+ || typeof request.taskId !== 'string' || !/^TASK-\d{8}-\d{6}$/u.test(request.taskId)
45
+ || !lifecycleAuthorityFamilies.includes(request.family)
46
+ || typeof request.artifact !== 'string' || !lifecycleAuthorityArtifact.test(request.artifact)
47
+ || !Number.isSafeInteger(request.round) || request.round < 1
48
+ || typeof request.lifecycleRequestId !== 'string' || !request.lifecycleRequestId || /[\r\n]/u.test(request.lifecycleRequestId)
49
+ || typeof request.authorityRef !== 'string' || !request.authorityRef || /[\r\n]/u.test(request.authorityRef)
50
+ || typeof request.expectedControlGeneration !== 'string' || !request.expectedControlGeneration
51
+ || typeof request.expectedControllerInstanceDigest !== 'string' || !/^[a-f0-9]{64}$/u.test(request.expectedControllerInstanceDigest)
52
+ || typeof request.expectedBuildIdentityDigest !== 'string' || !/^[a-f0-9]{64}$/u.test(request.expectedBuildIdentityDigest)
53
+ || typeof request.expectedHookDefinitionHash !== 'string' || !/^[a-f0-9]{64}$/u.test(request.expectedHookDefinitionHash)) {
54
+ throw new Error('LIFECYCLE_AUTHORITY_REQUEST_INVALID');
55
+ }
56
+ const expectedArtifactFamily = request.artifact;
57
+ if (!expectedArtifactFamily.startsWith(request.family))
58
+ throw new Error('LIFECYCLE_AUTHORITY_REQUEST_INVALID');
59
+ return request;
60
+ }
61
+ export function validateLifecycleRecoveryAttestation(value, now = Date.now()) {
62
+ if (!value || typeof value !== 'object' || Array.isArray(value))
63
+ throw new Error('LIFECYCLE_AUTHORITY_ATTESTATION_INVALID');
64
+ const attestation = value;
65
+ if (!authorityExactKeys(attestation, [
66
+ 'artifact', 'attestationId', 'authorityRefDigest', 'buildIdentityDigest', 'controlGeneration',
67
+ 'controllerInstanceDigest', 'expiresAt', 'family', 'hookDefinitionHash', 'issuedAt',
68
+ 'lifecycleRequestId', 'operationId', 'phase', 'requestId', 'round', 'sessionId',
69
+ 'taskId', 'toolUseId', 'turnId', 'version'
70
+ ])
71
+ || attestation.version !== 1
72
+ || typeof attestation.attestationId !== 'string' || !/^[a-f0-9-]{16,64}$/u.test(attestation.attestationId)
73
+ || typeof attestation.authorityRefDigest !== 'string' || !/^[a-f0-9]{64}$/u.test(attestation.authorityRefDigest)
74
+ || typeof attestation.operationId !== 'string' || !/^[a-f0-9-]{16,64}$/u.test(attestation.operationId)
75
+ || !lifecycleAuthorityPhases.includes(attestation.phase)
76
+ || typeof attestation.requestId !== 'string' || !/^[a-f0-9-]{16,64}$/u.test(attestation.requestId)
77
+ || typeof attestation.lifecycleRequestId !== 'string' || !attestation.lifecycleRequestId
78
+ || typeof attestation.taskId !== 'string' || !/^TASK-\d{8}-\d{6}$/u.test(attestation.taskId)
79
+ || !lifecycleAuthorityFamilies.includes(attestation.family)
80
+ || typeof attestation.artifact !== 'string' || !lifecycleAuthorityArtifact.test(attestation.artifact)
81
+ || !Number.isSafeInteger(attestation.round) || attestation.round < 1
82
+ || typeof attestation.controlGeneration !== 'string' || !attestation.controlGeneration
83
+ || typeof attestation.controllerInstanceDigest !== 'string' || !/^[a-f0-9]{64}$/u.test(attestation.controllerInstanceDigest)
84
+ || typeof attestation.sessionId !== 'string' || !attestation.sessionId
85
+ || typeof attestation.turnId !== 'string' || !attestation.turnId
86
+ || typeof attestation.toolUseId !== 'string' || !attestation.toolUseId
87
+ || typeof attestation.buildIdentityDigest !== 'string' || !/^[a-f0-9]{64}$/u.test(attestation.buildIdentityDigest)
88
+ || typeof attestation.hookDefinitionHash !== 'string' || !/^[a-f0-9]{64}$/u.test(attestation.hookDefinitionHash)
89
+ || !Number.isSafeInteger(attestation.issuedAt) || !Number.isSafeInteger(attestation.expiresAt)
90
+ || attestation.expiresAt <= attestation.issuedAt
91
+ || attestation.expiresAt <= now) {
92
+ throw new Error('LIFECYCLE_AUTHORITY_ATTESTATION_INVALID');
93
+ }
94
+ return attestation;
95
+ }
96
+ const authorityOperationMap = new WeakMap();
97
+ const authorityRecords = new Map();
98
+ const consumedAuthorityPhases = new Set();
99
+ export function issueLifecycleRecoveryAttestation(input, options = {}) {
100
+ let request;
101
+ try {
102
+ request = validateLifecycleAuthorityRequest(input);
103
+ }
104
+ catch (error) {
105
+ return { version: 1, requestId: String(input?.requestId ?? ''), operationId: String(input?.operationId ?? ''), phase: input?.phase ?? 'artifact.finalize-local', status: 'rejected', attestation: null, error: { code: 'LIFECYCLE_AUTHORITY_REQUEST_INVALID', message: error instanceof Error ? error.message : String(error) } };
106
+ }
107
+ const binding = options.controllerBinding ?? null;
108
+ if (!binding)
109
+ return authorityRejected(request, 'LOCAL_EXECUTION_AUTHORITY_UNAVAILABLE', 'current controller authority is unavailable');
110
+ if (binding.controlGeneration !== request.expectedControlGeneration
111
+ || binding.instanceDigest !== request.expectedControllerInstanceDigest) {
112
+ return authorityRejected(request, 'LIFECYCLE_AUTHORITY_CONTROLLER_MISMATCH', 'current controller binding does not match the request');
113
+ }
114
+ const buildIdentity = options.buildIdentity ?? computeLifecycleBuildIdentity(process.cwd());
115
+ if (lifecycleAuthorityBuildDigest(buildIdentity) !== request.expectedBuildIdentityDigest) {
116
+ return authorityRejected(request, 'LIFECYCLE_AUTHORITY_BUILD_MISMATCH', 'current lifecycle build does not match the request');
117
+ }
118
+ const store = options.capabilityStore ?? createCodexCapabilityStore();
119
+ const registry = options.operationAttestations ?? authorityOperationMap.get(store) ?? new Map();
120
+ authorityOperationMap.set(store, registry);
121
+ const key = `${request.requestId}\0${request.operationId}\0${request.phase}`;
122
+ const prior = registry.get(key);
123
+ if (prior)
124
+ return { version: 1, requestId: request.requestId, operationId: request.operationId, phase: request.phase, status: 'already-completed', attestation: prior, error: null };
125
+ try {
126
+ const expected = {
127
+ taskId: request.taskId,
128
+ hookDefinitionHash: request.expectedHookDefinitionHash,
129
+ buildIdentity,
130
+ controller: binding
131
+ };
132
+ const record = store.reserveReference(request.authorityRef, request.operationId, expected);
133
+ if (!record.sessionId || !record.turnId || !record.toolUseId)
134
+ throw new Error('CODEX_CAPABILITY_IDENTITY_INVALID: capability hook attestation is incomplete');
135
+ const now = (options.now ?? Date.now)();
136
+ const attestation = validateLifecycleRecoveryAttestation({
137
+ version: 1,
138
+ attestationId: crypto.randomUUID(),
139
+ authorityRefDigest: lifecycleAuthorityDigest(request.authorityRef),
140
+ operationId: request.operationId,
141
+ phase: request.phase,
142
+ requestId: request.requestId,
143
+ lifecycleRequestId: request.lifecycleRequestId,
144
+ taskId: request.taskId,
145
+ family: request.family,
146
+ artifact: request.artifact,
147
+ round: request.round,
148
+ controlGeneration: binding.controlGeneration,
149
+ controllerInstanceDigest: binding.instanceDigest,
150
+ sessionId: record.sessionId,
151
+ turnId: record.turnId,
152
+ toolUseId: record.toolUseId,
153
+ buildIdentityDigest: lifecycleAuthorityBuildDigest(buildIdentity),
154
+ hookDefinitionHash: request.expectedHookDefinitionHash,
155
+ issuedAt: now,
156
+ expiresAt: Math.min(record.expiresAt, now + 30_000)
157
+ }, now);
158
+ store.reserveRecoveryPhase(request.authorityRef, request.operationId, request.phase, request.requestId, expected);
159
+ registry.set(key, attestation);
160
+ authorityRecords.set(attestation.attestationId, { store, capabilityRef: request.authorityRef, expected });
161
+ return { version: 1, requestId: request.requestId, operationId: request.operationId, phase: request.phase, status: 'issued', attestation, error: null };
162
+ }
163
+ catch (error) {
164
+ return authorityRejected(request, error instanceof Error && error.name.startsWith('CODEX_') ? error.name : 'LIFECYCLE_AUTHORITY_REJECTED', error instanceof Error ? error.message : String(error));
165
+ }
166
+ }
167
+ export function consumeLifecycleRecoveryAttestation(value, now = Date.now()) {
168
+ const attestation = validateLifecycleRecoveryAttestation(value, now);
169
+ if (consumedAuthorityPhases.has(attestation.attestationId))
170
+ return;
171
+ const record = authorityRecords.get(attestation.attestationId);
172
+ if (!record)
173
+ throw new Error('LIFECYCLE_AUTHORITY_ATTESTATION_UNKNOWN');
174
+ record.store.consumeRecoveryPhase(record.capabilityRef, attestation.operationId, attestation.phase, attestation.requestId, record.expected);
175
+ if (attestation.phase === 'task-event.completed') {
176
+ record.store.consumeReference(record.capabilityRef, attestation.operationId, record.expected);
177
+ }
178
+ consumedAuthorityPhases.add(attestation.attestationId);
179
+ }
180
+ export function queryLifecycleRecoveryOperation(operationId, options = {}) {
181
+ if (!/^[a-f0-9-]{16,64}$/u.test(operationId)) {
182
+ throw new Error('LIFECYCLE_RECOVERY_OPERATION_INVALID');
183
+ }
184
+ const store = options.capabilityStore ?? createCodexCapabilityStore();
185
+ const registry = authorityOperationMap.get(store);
186
+ const known = [...(registry?.values() ?? [])].filter((value) => value.operationId === operationId);
187
+ const intents = options.repoRoot ? findArtifactRepairIntentsByOperation(options.repoRoot, operationId) : [];
188
+ const capabilities = store.findByRecoveryOperation(operationId);
189
+ const phaseMap = new Map();
190
+ for (const capability of capabilities) {
191
+ for (const phase of capability.recoveryPhases) {
192
+ phaseMap.set(`${phase.phase}\0${phase.requestId}`, {
193
+ phase: phase.phase,
194
+ requestId: phase.requestId,
195
+ attestationId: null,
196
+ state: phase.state === 'consumed' ? 'consumed' : 'observed'
197
+ });
198
+ }
199
+ }
200
+ for (const attestation of known) {
201
+ const key = `${attestation.phase}\0${attestation.requestId}`;
202
+ const durable = phaseMap.get(key);
203
+ phaseMap.set(key, {
204
+ phase: attestation.phase,
205
+ requestId: attestation.requestId,
206
+ attestationId: attestation.attestationId,
207
+ state: durable?.state === 'consumed' || consumedAuthorityPhases.has(attestation.attestationId)
208
+ ? 'consumed' : 'issued'
209
+ });
210
+ }
211
+ for (const intent of intents) {
212
+ if (!intent.phase)
213
+ continue;
214
+ const key = `${intent.phase}\0${intent.requestId}`;
215
+ if (phaseMap.has(key))
216
+ continue;
217
+ phaseMap.set(key, {
218
+ phase: intent.phase,
219
+ requestId: intent.requestId,
220
+ attestationId: null,
221
+ state: intent.state === 'consumed' ? 'consumed' : 'observed'
222
+ });
223
+ }
224
+ const capabilityState = capabilities.some((record) => record.recoveryState === 'consumed')
225
+ ? 'consumed'
226
+ : capabilities.some((record) => record.recoveryState === 'reserved') ? 'reserved' : 'unknown';
227
+ const committed = capabilityState === 'consumed' || intents.some((intent) => intent.state === 'consumed');
228
+ return {
229
+ version: 1,
230
+ operationId,
231
+ status: committed ? 'committed' : capabilityState === 'reserved' || phaseMap.size > 0 ? 'in-progress' : 'unknown',
232
+ capabilityState,
233
+ phases: Object.freeze([...phaseMap.values()])
234
+ };
235
+ }
236
+ function lifecycleRecoveryCompensationError(code, message) {
237
+ const error = new Error(`${code}: ${message}`);
238
+ error.name = code;
239
+ return error;
240
+ }
241
+ function lifecycleRecoveryEventCommitted(selector, repoRoot) {
242
+ const resolved = resolveTaskRef(selector.taskId, { repoRoot });
243
+ if (!resolved.ok || resolved.taskId !== selector.taskId)
244
+ return false;
245
+ let content;
246
+ try {
247
+ content = fs.readFileSync(resolved.taskMdPath, 'utf8');
248
+ }
249
+ catch {
250
+ return false;
251
+ }
252
+ const section = locateActivityLog(content);
253
+ if (!section)
254
+ return false;
255
+ const labels = { analysis: 'Analyze Task', plan: 'Plan Task', code: 'Code Task' };
256
+ const prefix = `${labels[selector.family]} (Round ${selector.round}`;
257
+ return section.entries.some((entry) => {
258
+ if (entry.step.endsWith(' [started]') || !entry.step.startsWith(prefix))
259
+ return false;
260
+ const delimiter = entry.step[prefix.length];
261
+ return (delimiter === ',' || delimiter === ')') && entry.note.endsWith(`→ ${selector.artifact}`);
262
+ });
263
+ }
264
+ function lifecycleRecoveryIntentMatches(intent, selector) {
265
+ return intent.taskId === selector.taskId
266
+ && intent.family === selector.family
267
+ && intent.artifact === selector.artifact
268
+ && (intent.state === 'commit-started' || intent.state === 'consumed');
269
+ }
270
+ /**
271
+ * Completes only the durable tail of a committed task event after a process
272
+ * restart. The task event itself is the commit boundary and is never replayed.
273
+ */
274
+ export function recoverLifecycleRecoveryOperation(input, options) {
275
+ const selector = validateLifecycleAuthorityRequest(input);
276
+ if (selector.phase !== 'task-event.completed') {
277
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_RECOVERY_PHASE_UNSUPPORTED', 'only task-event.completed supports durable compensation');
278
+ }
279
+ const buildIdentity = options.buildIdentity ?? computeLifecycleBuildIdentity(options.repoRoot);
280
+ if (selector.expectedBuildIdentityDigest !== lifecycleAuthorityBuildDigest(buildIdentity)) {
281
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_AUTHORITY_BUILD_MISMATCH', 'current lifecycle build does not match the recovery request');
282
+ }
283
+ if (selector.expectedControlGeneration !== options.controllerBinding.controlGeneration
284
+ || selector.expectedControllerInstanceDigest !== options.controllerBinding.instanceDigest) {
285
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_AUTHORITY_CONTROLLER_MISMATCH', 'current controller binding does not match the recovery request');
286
+ }
287
+ const store = options.capabilityStore ?? createCodexCapabilityStore();
288
+ const expected = {
289
+ taskId: selector.taskId,
290
+ hookDefinitionHash: selector.expectedHookDefinitionHash,
291
+ buildIdentity,
292
+ controller: options.controllerBinding
293
+ };
294
+ const capabilities = store.findByRecoveryOperation(selector.operationId);
295
+ if (capabilities.length !== 1 || capabilities[0].capabilityRefDigest !== lifecycleAuthorityDigest(selector.authorityRef)) {
296
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_RECOVERY_PROVENANCE_INVALID', 'durable capability provenance does not identify this operation');
297
+ }
298
+ const capability = capabilities[0];
299
+ const build = verifyLifecycleBuildIdentity(capability.buildIdentity, buildIdentity);
300
+ const expiredReserved = capability.status === 'expired' && capability.recoveryState === 'reserved';
301
+ if (!build.ok
302
+ || capability.taskId !== selector.taskId
303
+ || capability.hookDefinitionHash !== selector.expectedHookDefinitionHash
304
+ || capability.controller?.controlGeneration !== options.controllerBinding.controlGeneration
305
+ || capability.controller?.instanceDigest !== options.controllerBinding.instanceDigest
306
+ || capability.recoveryState === 'unreserved'
307
+ || capability.recoveryOperationId !== selector.operationId
308
+ || (!['attested', 'consumed'].includes(capability.status) && !expiredReserved)) {
309
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_RECOVERY_PROVENANCE_INVALID', 'durable capability provenance does not match the recovery request');
310
+ }
311
+ const phase = capability.recoveryPhases.find((entry) => entry.phase === selector.phase);
312
+ if (!phase) {
313
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_RECOVERY_PHASE_MISSING', 'durable task completion phase is missing');
314
+ }
315
+ const intents = findArtifactRepairIntentsByOperation(options.repoRoot, selector.operationId)
316
+ .filter((intent) => intent.taskId === selector.taskId
317
+ && intent.family === selector.family
318
+ && intent.artifact === selector.artifact);
319
+ if (intents.length !== 1) {
320
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_RECOVERY_INTENT_INVALID', 'durable artifact repair intent does not identify this task event');
321
+ }
322
+ const intent = intents[0];
323
+ if (!lifecycleRecoveryIntentMatches(intent, selector)
324
+ || intent.phase !== selector.phase
325
+ || intent.requestId !== selector.lifecycleRequestId
326
+ || intent.authorityDigest === null) {
327
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_RECOVERY_INTENT_INVALID', 'durable artifact repair intent does not match the recovery request');
328
+ }
329
+ if (!lifecycleRecoveryEventCommitted(selector, options.repoRoot)) {
330
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_RECOVERY_COMMIT_UNCONFIRMED', 'task completion is not durably present; compensation is not allowed');
331
+ }
332
+ if (capability.recoveryState === 'reserved') {
333
+ if (phase.state === 'issued') {
334
+ store.consumeRecoveryPhase(selector.authorityRef, selector.operationId, selector.phase, phase.requestId, expected, { allowExpiredReserved: true });
335
+ }
336
+ store.consumeReference(selector.authorityRef, selector.operationId, expected, { allowExpiredReserved: true });
337
+ }
338
+ else if (phase.state !== 'consumed') {
339
+ throw lifecycleRecoveryCompensationError('LIFECYCLE_RECOVERY_STATE_INVALID', 'consumed capability has an unconsumed completion phase');
340
+ }
341
+ if (intent.state !== 'consumed') {
342
+ writeArtifactRepairIntent(options.repoRoot, {
343
+ ...intent,
344
+ state: 'consumed',
345
+ updatedAt: (options.now ?? Date.now)()
346
+ }, { expected: intent });
347
+ }
348
+ return queryLifecycleRecoveryOperation(selector.operationId, { repoRoot: options.repoRoot, capabilityStore: store });
349
+ }
350
+ function authorityRejected(request, code, message) {
351
+ return { version: 1, requestId: request.requestId, operationId: request.operationId, phase: request.phase, status: 'rejected', attestation: null, error: { code, message } };
352
+ }
353
+ export function taskControlOperationKey(operation) {
354
+ if (operation.family === 'task-finalization')
355
+ return 'complete';
356
+ if (operation.family === 'task-lifecycle')
357
+ return operation.request.intent;
358
+ return operation.intent === 'route'
359
+ ? operation.input && operation.input.completed === true ? 'route.clean-completion' : 'route.read'
360
+ : operation.intent;
361
+ }
12
362
  function invalidContext(message) {
13
363
  throw new Error(`TASK_CONTROL_CONTEXT_INVALID: ${message}`);
14
364
  }
@@ -31,7 +381,11 @@ export function createDirectHostExecutionContext(params) {
31
381
  mode: 'direct-host',
32
382
  repoRoot: absolute('repoRoot', params.repoRoot),
33
383
  ...(params.runtimeDir === undefined ? {} : { runtimeDir: absolute('runtimeDir', params.runtimeDir) }),
34
- ...(params.controllerBinding === undefined ? {} : { controllerBinding: binding(params.controllerBinding) })
384
+ ...(params.controllerBinding === undefined ? {} : { controllerBinding: binding(params.controllerBinding) }),
385
+ ...(params.lifecycleRecoveryAttestation === undefined ? {} : {
386
+ lifecycleRecoveryAttestation: params.lifecycleRecoveryAttestation === null
387
+ ? null : validateLifecycleRecoveryAttestation(params.lifecycleRecoveryAttestation)
388
+ })
35
389
  };
36
390
  }
37
391
  export function createSandboxExecutorExecutionContext(params) {
@@ -52,7 +406,12 @@ export function createSandboxExecutorExecutionContext(params) {
52
406
  generation: params.generation,
53
407
  manifestPath: absolute('manifestPath', params.manifestPath),
54
408
  requestId: params.requestId,
55
- ...(params.controllerBinding === undefined ? {} : { controllerBinding: binding(params.controllerBinding) })
409
+ ...(params.diagnosticLog === undefined ? {} : { diagnosticLog: params.diagnosticLog }),
410
+ ...(params.controllerBinding === undefined ? {} : { controllerBinding: binding(params.controllerBinding) }),
411
+ ...(params.lifecycleRecoveryAttestation === undefined ? {} : {
412
+ lifecycleRecoveryAttestation: params.lifecycleRecoveryAttestation === null
413
+ ? null : validateLifecycleRecoveryAttestation(params.lifecycleRecoveryAttestation)
414
+ })
56
415
  };
57
416
  }
58
417
  export function assertTaskControlExecutionContext(context) {
@@ -63,6 +422,8 @@ export function assertTaskControlExecutionContext(context) {
63
422
  if (context.runtimeDir !== undefined)
64
423
  absolute('runtimeDir', context.runtimeDir);
65
424
  binding(context.controllerBinding);
425
+ if (context.lifecycleRecoveryAttestation)
426
+ validateLifecycleRecoveryAttestation(context.lifecycleRecoveryAttestation);
66
427
  return;
67
428
  }
68
429
  if (context.mode !== 'task-bound-sandbox' || !/^TASK-\d{8}-\d{6}$/u.test(context.taskId)
@@ -77,6 +438,8 @@ export function assertTaskControlExecutionContext(context) {
77
438
  invalidContext('runtimeDir is not bound to the manifest control root');
78
439
  }
79
440
  binding(context.controllerBinding);
441
+ if (context.lifecycleRecoveryAttestation)
442
+ validateLifecycleRecoveryAttestation(context.lifecycleRecoveryAttestation);
80
443
  }
81
444
  function operationTaskId(context, taskRef) {
82
445
  if (context.source === 'sandbox-executor' && taskRef !== context.taskId) {
@@ -87,6 +450,9 @@ function domainOptions(context, options) {
87
450
  return {
88
451
  ...options,
89
452
  repoRoot: context.repoRoot,
453
+ ...(context.source === 'sandbox-executor' && context.diagnosticLog !== undefined
454
+ ? { diagnosticLog: context.diagnosticLog }
455
+ : {}),
90
456
  ...(context.source === 'sandbox-executor' ? { gitWorktreeRoot: context.worktreeRoot } : {})
91
457
  };
92
458
  }
@@ -162,12 +528,16 @@ function orchestration(context, operation) {
162
528
  client: input.client,
163
529
  requestedModel: input.requestedModel,
164
530
  requestedReasoningEffort: input.requestedReasoningEffort,
165
- ...(input.capabilityToken === undefined ? {} : { capabilityToken: input.capabilityToken })
531
+ ...(input.capabilityRef === undefined ? {} : { capabilityRef: input.capabilityRef }),
532
+ ...(context.lifecycleRecoveryAttestation === undefined
533
+ ? {}
534
+ : { lifecycleRecoveryAttestation: context.lifecycleRecoveryAttestation })
166
535
  };
167
536
  if (prepareInput.client === 'codex') {
168
537
  return prepareCodexOrchestrationDelegation(operation.taskRef, prepareInput, {
169
538
  repoRoot: context.repoRoot,
170
539
  orchestrationOptions: options,
540
+ deferLifecycleRecoveryConsumption: context.source === 'sandbox-executor',
171
541
  ...(context.controllerBinding ? { controllerBinding: context.controllerBinding } : {})
172
542
  });
173
543
  }
@@ -252,7 +622,7 @@ const FINALIZATION_FLAGS = new Set(['--agent']);
252
622
  const ORCHESTRATION_FLAGS = new Set([
253
623
  '--agent', '--max-steps', '--executor-model', '--executor-reasoning-effort', '--reviewer-model',
254
624
  '--reviewer-reasoning-effort', '--client', '--requested-model', '--requested-reasoning-effort',
255
- '--capability-token', '--parent-id', '--before-fingerprint', '--stage', '--round', '--artifact', '--role',
625
+ '--capability-ref', '--parent-id', '--before-fingerprint', '--stage', '--round', '--artifact', '--role',
256
626
  '--native-agent', '--child-id', '--spawn-mode', '--actual-model', '--actual-reasoning-effort',
257
627
  '--model-fallback-reason', '--reasoning-effort-fallback-reason', '--exit-code', '--after-fingerprint',
258
628
  '--changed-paths', '--code', '--message', '--recoverable', '--git-worktree-root'
@@ -368,7 +738,7 @@ export function parseTaskControlOperation(family, args) {
368
738
  if (parsedIntent === 'prepare') {
369
739
  input.requestedModel = value(values, '--requested-model');
370
740
  input.requestedReasoningEffort = value(values, '--requested-reasoning-effort');
371
- input.capabilityToken = value(values, '--capability-token');
741
+ input.capabilityRef = value(values, '--capability-ref');
372
742
  }
373
743
  if (parsedIntent === 'await-activation') {
374
744
  required(values, ['--stage', '--round', '--artifact', '--role']);
@@ -0,0 +1,128 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { isCompletionEvidence } from './orchestration.js';
3
+ import { TASK_WORKFLOW_OPERATIONS } from './workflow-command.js';
4
+ /** Normalize the command result once at the control transport boundary. */
5
+ export function parseControlOutput(output) {
6
+ if (output === null)
7
+ return null;
8
+ try {
9
+ const value = JSON.parse(output);
10
+ if (!value || typeof value !== 'object' || Array.isArray(value))
11
+ return null;
12
+ return value.result && typeof value.result === 'object' && !Array.isArray(value.result) ? value.result : value;
13
+ }
14
+ catch {
15
+ return null;
16
+ }
17
+ }
18
+ export const SANDBOX_CONTROL_REQUIRED_COMPLETION_PHASES = Object.freeze([
19
+ 'completed', 'evidence-written', 'publish-authorized'
20
+ ]);
21
+ const LIFECYCLE_INTENTS = ['block', 'activate', 'cancel', 'complete', 'close-codescan', 'close-dependabot', 'restore'];
22
+ const ORCHESTRATION_INTENTS = [
23
+ 'begin-or-resume', 'route.read', 'route.clean-completion', 'status', 'prepare', 'dispatch',
24
+ 'await-activation', 'recover-prepared', 'hook-start', 'hook-stop', 'advance', 'pause'
25
+ ];
26
+ export const SANDBOX_CONTROL_RECOVERY_OPERATIONS = Object.freeze([
27
+ ...LIFECYCLE_INTENTS.map((intent) => ({ family: 'task-lifecycle', intent, class: 'lifecycle-mutation' })),
28
+ { family: 'task-finalization', intent: 'complete', class: 'finalization' },
29
+ ...ORCHESTRATION_INTENTS.map((intent) => ({
30
+ family: 'task-orchestration',
31
+ intent,
32
+ class: intent === 'route.clean-completion' ? 'route.clean-completion' : intent === 'route.read' || intent === 'status' ? 'read-only' : 'orchestration'
33
+ })),
34
+ { family: 'task-create', intent: 'create', class: 'task-create' },
35
+ ...TASK_WORKFLOW_OPERATIONS.map((intent) => ({ family: 'task-workflow', intent, class: intent === 'artifact-inspect' || intent === 'decision-next-id' ? 'read-only' : 'workflow' })),
36
+ ...['open', 'close', 'verify'].map((intent) => ({ family: 'codex-controller', intent, class: 'codex-controller' }))
37
+ ]);
38
+ export function digestControlRecoveryIntent(family, intent) {
39
+ return createHash('sha256').update(`${family}\0${intent}`, 'utf8').digest('hex');
40
+ }
41
+ export function findSandboxControlRecoveryOperation(family, intent) {
42
+ return SANDBOX_CONTROL_RECOVERY_OPERATIONS.find((operation) => operation.family === family && operation.intent === intent) ?? null;
43
+ }
44
+ function bindingMatchesResult(binding, result) {
45
+ return result.requestId === binding.requestId
46
+ && result.generation === binding.generation
47
+ && (result.taskId === undefined || result.taskId === binding.taskId)
48
+ && (result.intentDigest === undefined || result.intentDigest === binding.intentDigest);
49
+ }
50
+ function domainEvidenceMatches(operation, result, domain) {
51
+ if (!domain)
52
+ return false;
53
+ if (domain.consistent !== true)
54
+ return false;
55
+ if (operation.class === 'route.clean-completion') {
56
+ const completion = domain.completionEvidence;
57
+ const snapshot = domain.snapshot;
58
+ const lastReviewedCommit = domain.lastReviewedCommit;
59
+ return result.status === 'completed'
60
+ && domain.status === 'completed'
61
+ && domain.pendingDelegation === null
62
+ && isCompletionEvidence(completion)
63
+ && snapshot?.head === completion.head
64
+ && snapshot.headTree === completion.headTree
65
+ && snapshot.worktreeTree === completion.worktreeTree
66
+ && lastReviewedCommit === completion.lastReviewedCommit;
67
+ }
68
+ if (operation.class === 'read-only')
69
+ return result.changed === false && domain.snapshotValid === true;
70
+ return true;
71
+ }
72
+ export function classifySandboxControlRecovery(input) {
73
+ const result = input.terminalResult ?? null;
74
+ if (input.evidenceConflict)
75
+ return { outcome: 'unknown', responseReconstructable: false, reasonCode: 'RECOVERY_EVIDENCE_CONFLICT' };
76
+ if (input.explicitRejection && !input.startedCommitted) {
77
+ return { outcome: 'not-executed', responseReconstructable: true, reasonCode: 'RECOVERY_EXPLICIT_REJECTION' };
78
+ }
79
+ if (!input.startedCommitted) {
80
+ return { outcome: 'not-executed', responseReconstructable: false, reasonCode: 'RECOVERY_NOT_STARTED' };
81
+ }
82
+ if (!result)
83
+ return { outcome: 'unknown', responseReconstructable: false, reasonCode: 'RECOVERY_TERMINAL_RESULT_MISSING' };
84
+ if (!bindingMatchesResult(input.binding, result)) {
85
+ return { outcome: 'unknown', responseReconstructable: false, reasonCode: 'RECOVERY_RESULT_BINDING_MISMATCH' };
86
+ }
87
+ if (!SANDBOX_CONTROL_REQUIRED_COMPLETION_PHASES.every((phase) => input.criticalPhases?.includes(phase))) {
88
+ return { outcome: 'unknown', responseReconstructable: false, reasonCode: 'RECOVERY_CRITICAL_AUDIT_INCOMPLETE' };
89
+ }
90
+ const status = result.status;
91
+ const failed = status === 'failed' || result.error !== null && result.error !== undefined;
92
+ if (failed) {
93
+ if (input.domain && input.domain.consistent === false) {
94
+ return { outcome: 'failure', responseReconstructable: true, reasonCode: 'RECOVERY_TERMINAL_FAILURE' };
95
+ }
96
+ return { outcome: 'unknown', responseReconstructable: false, reasonCode: 'RECOVERY_FAILURE_EVIDENCE_INCOMPLETE' };
97
+ }
98
+ if (result.changed === null) {
99
+ return { outcome: 'unknown', responseReconstructable: false, reasonCode: 'RECOVERY_RESULT_CHANGE_FLAG_MISSING' };
100
+ }
101
+ if (!domainEvidenceMatches(input.operation, result, input.domain)) {
102
+ if (input.journal?.exists && (input.journal.completedSteps?.length ?? 0) > 0) {
103
+ return { outcome: 'in-progress', responseReconstructable: false, reasonCode: 'RECOVERY_DOMAIN_EVIDENCE_INCOMPLETE' };
104
+ }
105
+ return { outcome: 'unknown', responseReconstructable: false, reasonCode: 'RECOVERY_DOMAIN_EVIDENCE_MISSING' };
106
+ }
107
+ if (input.operation.family === 'task-lifecycle' && input.journal?.exists) {
108
+ if (input.journal.failure) {
109
+ return { outcome: 'failure', responseReconstructable: true, reasonCode: 'RECOVERY_LIFECYCLE_JOURNAL_FAILURE' };
110
+ }
111
+ return {
112
+ outcome: input.journal.completedSteps && input.journal.completedSteps.length > 0 ? 'in-progress' : 'unknown',
113
+ responseReconstructable: false,
114
+ reasonCode: 'RECOVERY_LIFECYCLE_JOURNAL_PRESENT'
115
+ };
116
+ }
117
+ return {
118
+ outcome: 'success',
119
+ responseReconstructable: true,
120
+ reasonCode: input.operation.class === 'route.clean-completion' && result.changed === false
121
+ ? 'RECOVERY_ROUTE_COMPLETION_NOOP'
122
+ : 'RECOVERY_TERMINAL_AND_DOMAIN_MATCH'
123
+ };
124
+ }
125
+ export function operationRecoveryBinding(requestId, generation, taskId, family, intent) {
126
+ return { requestId, generation, taskId, intentDigest: digestControlRecoveryIntent(family, intent) };
127
+ }
128
+ //# sourceMappingURL=control-recovery.js.map