@fitlab-ai/agent-infra 0.9.12 → 0.9.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (402) hide show
  1. package/README.md +11 -11
  2. package/README.zh-CN.md +11 -11
  3. package/bin/cli.ts +26 -9
  4. package/dist/bin/cli.js +173 -157
  5. package/dist/bin/internal-cli.js +66 -40
  6. package/dist/lib/agent-client.js +5 -0
  7. package/dist/lib/agent-clients/next-steps.js +6 -1
  8. package/dist/lib/decide.js +3 -3
  9. package/dist/lib/internal/agent-client.js +5 -2
  10. package/dist/lib/internal/cli-route-inventory.js +152 -0
  11. package/dist/lib/internal/codex-lifecycle.js +9 -6
  12. package/dist/lib/internal/codex-sandbox-controller.js +8 -2
  13. package/dist/lib/internal/git-workflow.js +10 -6
  14. package/dist/lib/internal/platform-checks.js +19 -7
  15. package/dist/lib/internal/platform-comment.js +25 -13
  16. package/dist/lib/internal/platform-context.js +6 -3
  17. package/dist/lib/internal/platform-issue.js +20 -13
  18. package/dist/lib/internal/platform-metadata.js +88 -0
  19. package/dist/lib/internal/platform-pr-review.js +26 -13
  20. package/dist/lib/internal/platform-pr.js +84 -31
  21. package/dist/lib/internal/platform-release-notes.js +9 -6
  22. package/dist/lib/internal/platform-security.js +93 -0
  23. package/dist/lib/internal/pr-review-grade.js +25 -12
  24. package/dist/lib/internal/release-workflow.js +23 -9
  25. package/dist/lib/internal/sandbox-control.js +50 -7
  26. package/dist/lib/internal/task-activity.js +16 -7
  27. package/dist/lib/internal/task-artifact.js +235 -24
  28. package/dist/lib/internal/task-context.js +4 -1
  29. package/dist/lib/internal/task-create.js +50 -17
  30. package/dist/lib/internal/task-delivery.js +4 -1
  31. package/dist/lib/internal/task-event.js +10 -4
  32. package/dist/lib/internal/task-finalization.js +6 -3
  33. package/dist/lib/internal/task-invalidation.js +63 -0
  34. package/dist/lib/internal/task-ledger.js +20 -6
  35. package/dist/lib/internal/task-lifecycle.js +6 -3
  36. package/dist/lib/internal/task-operation-registry.js +421 -0
  37. package/dist/lib/internal/task-orchestration.js +12 -0
  38. package/dist/lib/internal/task-override.js +14 -7
  39. package/dist/lib/internal/task-qualification.js +90 -0
  40. package/dist/lib/internal/task-review.js +7 -4
  41. package/dist/lib/internal/task-short-id.js +11 -1
  42. package/dist/lib/internal/task-snapshot.js +4 -1
  43. package/dist/lib/internal/task-validate.js +7 -2
  44. package/dist/lib/internal/task-verify.js +11 -7
  45. package/dist/lib/internal/task-warning.js +11 -4
  46. package/dist/lib/platform/adapters.js +1 -3
  47. package/dist/lib/platform/change-request-git-evidence.js +27 -7
  48. package/dist/lib/platform/comment-safety.js +226 -0
  49. package/dist/lib/platform/completion-backfill.js +6 -5
  50. package/dist/lib/platform/context.js +70 -130
  51. package/dist/lib/platform/github-client.js +1 -1
  52. package/dist/lib/platform/github-provider.js +1130 -0
  53. package/dist/lib/platform/in-label-sync.js +143 -0
  54. package/dist/lib/platform/issue-comments.js +237 -72
  55. package/dist/lib/platform/issues.js +335 -189
  56. package/dist/lib/platform/metadata-labels.js +6 -2
  57. package/dist/lib/platform/none-provider.js +28 -0
  58. package/dist/lib/platform/pr-change-report.js +545 -0
  59. package/dist/lib/platform/pr-checks.js +119 -104
  60. package/dist/lib/platform/pr-review.js +88 -72
  61. package/dist/lib/platform/pr-summary.js +541 -50
  62. package/dist/lib/platform/provider-bridge.js +45 -0
  63. package/dist/lib/platform/provider-contract.d.ts +553 -0
  64. package/dist/lib/platform/provider-contract.js +99 -0
  65. package/dist/lib/platform/provider-loader.js +251 -0
  66. package/dist/lib/platform/provider-validation.js +577 -0
  67. package/dist/lib/platform/pull-request-metadata.js +8 -6
  68. package/dist/lib/platform/pull-requests.js +734 -543
  69. package/dist/lib/platform/release-notes.js +78 -55
  70. package/dist/lib/platform/releases.js +79 -50
  71. package/dist/lib/platform/repository-metadata.js +377 -0
  72. package/dist/lib/platform/resource-identity.d.ts +26 -0
  73. package/dist/lib/platform/resource-identity.js +92 -0
  74. package/dist/lib/platform/security-alerts.js +155 -0
  75. package/dist/lib/platform/task-identities.js +31 -0
  76. package/dist/lib/platform/verification-required.js +11 -12
  77. package/dist/lib/platform/verification-sync.js +129 -248
  78. package/dist/lib/pr-review/evidence-grading.js +19 -6
  79. package/dist/lib/process-data/index.js +7 -0
  80. package/dist/lib/run/index.js +68 -23
  81. package/dist/lib/sandbox/commands/control-status.js +22 -0
  82. package/dist/lib/sandbox/commands/create.js +32 -6
  83. package/dist/lib/sandbox/commands/ls.js +5 -0
  84. package/dist/lib/sandbox/commands/rm.js +827 -120
  85. package/dist/lib/sandbox/commands/show.js +16 -0
  86. package/dist/lib/sandbox/control/client.js +174 -19
  87. package/dist/lib/sandbox/control/completed-reentry.js +85 -0
  88. package/dist/lib/sandbox/control/container-identity.js +28 -31
  89. package/dist/lib/sandbox/control/executor.js +151 -16
  90. package/dist/lib/sandbox/control/lifecycle.js +621 -127
  91. package/dist/lib/sandbox/control/native-file-lock.js +177 -0
  92. package/dist/lib/sandbox/control/protocol.js +77 -0
  93. package/dist/lib/sandbox/control/server.js +677 -34
  94. package/dist/lib/sandbox/control/state.js +209 -4
  95. package/dist/lib/sandbox/control/task-view.js +183 -0
  96. package/dist/lib/sandbox/engines/authority.js +289 -0
  97. package/dist/lib/sandbox/engines/docker-exact-discovery.js +97 -0
  98. package/dist/lib/sandbox/index.js +5 -0
  99. package/dist/lib/sandbox/recovery.js +21 -1
  100. package/dist/lib/sandbox/workspace-view.js +2 -1
  101. package/dist/lib/sandbox/worktree-safety.js +4 -1
  102. package/dist/lib/server/index.js +8 -0
  103. package/dist/lib/server/protocol.js +38 -1
  104. package/dist/lib/task/activity-log.js +8 -1
  105. package/dist/lib/task/artifact-lifecycle.js +75 -18
  106. package/dist/lib/task/artifact-operations.js +520 -0
  107. package/dist/lib/task/artifact-repair-intent.js +59 -0
  108. package/dist/lib/task/artifact-schema.js +135 -0
  109. package/dist/lib/task/capabilities.js +310 -0
  110. package/dist/lib/task/commands/status.js +32 -0
  111. package/dist/lib/task/commit-operation.js +12 -1
  112. package/dist/lib/task/control-authority.js +12 -5
  113. package/dist/lib/task/create-service.js +111 -12
  114. package/dist/lib/task/create.js +25 -0
  115. package/dist/lib/task/current-contract.js +5 -1
  116. package/dist/lib/task/decision-details.js +1 -1
  117. package/dist/lib/task/events.js +416 -17
  118. package/dist/lib/task/finalization.js +37 -13
  119. package/dist/lib/task/human-override.js +58 -36
  120. package/dist/lib/task/index.js +11 -3
  121. package/dist/lib/task/invalidation-command.js +86 -0
  122. package/dist/lib/task/invalidation.js +260 -0
  123. package/dist/lib/task/ledger-intents.js +37 -0
  124. package/dist/lib/task/local-artifact-finalization.js +299 -0
  125. package/dist/lib/task/orchestration.js +240 -144
  126. package/dist/lib/task/pr-delivery-fact.js +102 -101
  127. package/dist/lib/task/qualification-audit.js +490 -0
  128. package/dist/lib/task/qualification-confirmation.js +109 -0
  129. package/dist/lib/task/qualification-intents.js +148 -0
  130. package/dist/lib/task/review-artifacts.js +22 -23
  131. package/dist/lib/task/review-finalization.js +121 -4
  132. package/dist/lib/task/review-fingerprint.js +24 -2
  133. package/dist/lib/task/rework-intent.js +138 -0
  134. package/dist/lib/task/sections.js +6 -4
  135. package/dist/lib/task/skill-scope.js +23 -0
  136. package/dist/lib/task/task-execution-lock.js +27 -17
  137. package/dist/lib/task/verification-config.js +11 -0
  138. package/dist/lib/task/verification-engine.js +93 -16
  139. package/dist/lib/task/verification.js +3 -3
  140. package/dist/lib/task/workflow-warning-intents.js +1 -1
  141. package/dist/lib/task/write.js +11 -0
  142. package/dist/lib/version.js +11 -1
  143. package/dist/lifecycle-build-manifest.json +3 -3
  144. package/lib/agent-client.ts +9 -0
  145. package/lib/agent-clients/next-steps.ts +6 -1
  146. package/lib/decide.ts +3 -3
  147. package/lib/init.ts +1 -1
  148. package/lib/internal/agent-client.ts +4 -2
  149. package/lib/internal/cli-route-inventory.ts +140 -0
  150. package/lib/internal/codex-lifecycle.ts +8 -6
  151. package/lib/internal/codex-sandbox-controller.ts +7 -2
  152. package/lib/internal/git-workflow.ts +9 -6
  153. package/lib/internal/platform-checks.ts +14 -6
  154. package/lib/internal/platform-comment.ts +20 -12
  155. package/lib/internal/platform-context.ts +5 -3
  156. package/lib/internal/platform-issue.ts +17 -11
  157. package/lib/internal/platform-metadata.ts +70 -0
  158. package/lib/internal/platform-pr-review.ts +23 -12
  159. package/lib/internal/platform-pr.ts +65 -27
  160. package/lib/internal/platform-release-notes.ts +8 -6
  161. package/lib/internal/platform-security.ts +83 -0
  162. package/lib/internal/pr-review-grade.ts +20 -11
  163. package/lib/internal/release-workflow.ts +21 -9
  164. package/lib/internal/sandbox-control.ts +44 -6
  165. package/lib/internal/task-activity.ts +15 -7
  166. package/lib/internal/task-artifact.ts +204 -22
  167. package/lib/internal/task-context.ts +3 -1
  168. package/lib/internal/task-create.ts +78 -17
  169. package/lib/internal/task-delivery.ts +3 -1
  170. package/lib/internal/task-event.ts +9 -4
  171. package/lib/internal/task-finalization.ts +6 -4
  172. package/lib/internal/task-invalidation.ts +41 -0
  173. package/lib/internal/task-ledger.ts +21 -8
  174. package/lib/internal/task-lifecycle.ts +5 -3
  175. package/lib/internal/task-operation-registry.ts +482 -0
  176. package/lib/internal/task-orchestration.ts +12 -0
  177. package/lib/internal/task-override.ts +15 -9
  178. package/lib/internal/task-qualification.ts +61 -0
  179. package/lib/internal/task-review.ts +6 -4
  180. package/lib/internal/task-short-id.ts +10 -1
  181. package/lib/internal/task-snapshot.ts +3 -1
  182. package/lib/internal/task-validate.ts +6 -2
  183. package/lib/internal/task-verify.ts +10 -7
  184. package/lib/internal/task-warning.ts +10 -4
  185. package/lib/platform/adapters.ts +3 -2
  186. package/lib/platform/change-request-git-evidence.ts +36 -9
  187. package/lib/platform/comment-safety.ts +250 -0
  188. package/lib/platform/completion-backfill.ts +9 -8
  189. package/lib/platform/context.ts +97 -134
  190. package/lib/platform/github-client.ts +2 -2
  191. package/lib/platform/github-provider.ts +1132 -0
  192. package/lib/platform/in-label-sync.ts +208 -0
  193. package/lib/platform/issue-comments.ts +255 -80
  194. package/lib/platform/issues.ts +344 -174
  195. package/lib/platform/metadata-labels.ts +5 -2
  196. package/lib/platform/none-provider.ts +35 -0
  197. package/lib/platform/pr-change-report.ts +639 -0
  198. package/lib/platform/pr-checks.ts +126 -106
  199. package/lib/platform/pr-review.ts +88 -85
  200. package/lib/platform/pr-summary.ts +581 -53
  201. package/lib/platform/provider-bridge.ts +82 -0
  202. package/lib/platform/provider-contract.ts +611 -0
  203. package/lib/platform/provider-loader.ts +307 -0
  204. package/lib/platform/provider-validation.ts +611 -0
  205. package/lib/platform/pull-request-metadata.ts +10 -7
  206. package/lib/platform/pull-requests.ts +781 -550
  207. package/lib/platform/release-notes.ts +76 -59
  208. package/lib/platform/releases.ts +77 -43
  209. package/lib/platform/repository-metadata.ts +453 -0
  210. package/lib/platform/resource-identity.ts +121 -0
  211. package/lib/platform/security-alerts.ts +191 -0
  212. package/lib/platform/task-identities.ts +40 -0
  213. package/lib/platform/types.ts +4 -2
  214. package/lib/platform/verification-required.ts +11 -13
  215. package/lib/platform/verification-sync.ts +128 -304
  216. package/lib/pr-review/evidence-grading.ts +25 -8
  217. package/lib/process-data/index.ts +7 -0
  218. package/lib/run/index.ts +62 -22
  219. package/lib/sandbox/commands/control-status.ts +26 -0
  220. package/lib/sandbox/commands/create.ts +46 -6
  221. package/lib/sandbox/commands/ls.ts +7 -0
  222. package/lib/sandbox/commands/rm.ts +1000 -87
  223. package/lib/sandbox/commands/show.ts +16 -0
  224. package/lib/sandbox/control/client.ts +203 -19
  225. package/lib/sandbox/control/completed-reentry.ts +98 -0
  226. package/lib/sandbox/control/container-identity.ts +27 -43
  227. package/lib/sandbox/control/executor.ts +180 -15
  228. package/lib/sandbox/control/lifecycle.ts +629 -17
  229. package/lib/sandbox/control/native-file-lock.ts +209 -0
  230. package/lib/sandbox/control/protocol.ts +118 -2
  231. package/lib/sandbox/control/server.ts +724 -34
  232. package/lib/sandbox/control/state.ts +257 -4
  233. package/lib/sandbox/control/task-view.ts +240 -0
  234. package/lib/sandbox/engines/authority.ts +365 -0
  235. package/lib/sandbox/engines/docker-exact-discovery.ts +132 -0
  236. package/lib/sandbox/index.ts +7 -0
  237. package/lib/sandbox/recovery.ts +21 -1
  238. package/lib/sandbox/workspace-view.ts +9 -3
  239. package/lib/sandbox/worktree-safety.ts +4 -1
  240. package/lib/server/index.ts +10 -0
  241. package/lib/server/protocol.ts +36 -1
  242. package/lib/task/activity-log.ts +8 -0
  243. package/lib/task/artifact-lifecycle.ts +70 -22
  244. package/lib/task/artifact-operations.ts +626 -0
  245. package/lib/task/artifact-repair-intent.ts +71 -0
  246. package/lib/task/artifact-schema.ts +192 -0
  247. package/lib/task/capabilities.ts +331 -0
  248. package/lib/task/commands/status.ts +38 -0
  249. package/lib/task/commit-operation.ts +12 -1
  250. package/lib/task/control-authority.ts +22 -9
  251. package/lib/task/create-service.ts +139 -14
  252. package/lib/task/create.ts +27 -0
  253. package/lib/task/current-contract.ts +6 -1
  254. package/lib/task/decision-details.ts +6 -2
  255. package/lib/task/events.ts +392 -16
  256. package/lib/task/finalization.ts +50 -14
  257. package/lib/task/human-override.ts +70 -46
  258. package/lib/task/index.ts +16 -3
  259. package/lib/task/invalidation-command.ts +86 -0
  260. package/lib/task/invalidation.ts +332 -0
  261. package/lib/task/ledger-intents.ts +35 -1
  262. package/lib/task/local-artifact-finalization.ts +432 -0
  263. package/lib/task/orchestration.ts +223 -133
  264. package/lib/task/pr-delivery-fact.ts +131 -148
  265. package/lib/task/qualification-audit.ts +599 -0
  266. package/lib/task/qualification-confirmation.ts +117 -0
  267. package/lib/task/qualification-intents.ts +150 -0
  268. package/lib/task/review-artifacts.ts +21 -22
  269. package/lib/task/review-finalization.ts +133 -4
  270. package/lib/task/review-fingerprint.ts +23 -2
  271. package/lib/task/rework-intent.ts +165 -0
  272. package/lib/task/sections.ts +6 -4
  273. package/lib/task/skill-scope.ts +24 -0
  274. package/lib/task/task-execution-lock.ts +23 -14
  275. package/lib/task/verification-config.ts +12 -0
  276. package/lib/task/verification-engine.ts +103 -17
  277. package/lib/task/verification.ts +4 -4
  278. package/lib/task/workflow-warning-intents.ts +1 -1
  279. package/lib/task/write.ts +19 -0
  280. package/lib/update.ts +1 -1
  281. package/lib/version.ts +15 -1
  282. package/package.json +12 -1
  283. package/templates/.agents/rules/README.en.md +3 -1
  284. package/templates/.agents/rules/README.zh-CN.md +3 -1
  285. package/templates/.agents/rules/decision-qualification.en.md +22 -0
  286. package/templates/.agents/rules/decision-qualification.zh-CN.md +22 -0
  287. package/templates/.agents/rules/evidence-reporting.en.md +28 -0
  288. package/templates/.agents/rules/evidence-reporting.zh-CN.md +28 -0
  289. package/templates/.agents/rules/issue-pr-commands.en.md +1 -1
  290. package/templates/.agents/rules/issue-pr-commands.zh-CN.md +1 -1
  291. package/templates/.agents/rules/issue-sync.en.md +2 -0
  292. package/templates/.agents/rules/issue-sync.zh-CN.md +2 -0
  293. package/templates/.agents/rules/label-milestone-setup.en.md +7 -7
  294. package/templates/.agents/rules/label-milestone-setup.zh-CN.md +7 -7
  295. package/templates/.agents/rules/local-artifact-repair.en.md +13 -2
  296. package/templates/.agents/rules/local-artifact-repair.zh-CN.md +13 -2
  297. package/templates/.agents/rules/pr-sync.en.md +10 -4
  298. package/templates/.agents/rules/pr-sync.zh-CN.md +17 -4
  299. package/templates/.agents/rules/security-alerts.en.md +8 -8
  300. package/templates/.agents/rules/security-alerts.zh-CN.md +8 -8
  301. package/templates/.agents/rules/task-short-id.en.md +1 -4
  302. package/templates/.agents/rules/task-short-id.zh-CN.md +1 -3
  303. package/templates/.agents/skills/analyze-task/SKILL.en.md +28 -5
  304. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +29 -5
  305. package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -12
  306. package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -12
  307. package/templates/.agents/skills/check-task/SKILL.en.md +16 -37
  308. package/templates/.agents/skills/check-task/SKILL.zh-CN.md +16 -37
  309. package/templates/.agents/skills/close-codescan/SKILL.en.md +2 -2
  310. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +2 -2
  311. package/templates/.agents/skills/close-dependabot/SKILL.en.md +2 -2
  312. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +2 -2
  313. package/templates/.agents/skills/code-task/SKILL.en.md +41 -9
  314. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +43 -11
  315. package/templates/.agents/skills/code-task/config/verify.en.json +6 -14
  316. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +6 -14
  317. package/templates/.agents/skills/code-task/reference/code-rules.en.md +5 -4
  318. package/templates/.agents/skills/code-task/reference/code-rules.zh-CN.md +5 -4
  319. package/templates/.agents/skills/code-task/reference/dual-mode.en.md +1 -1
  320. package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +1 -1
  321. package/templates/.agents/skills/code-task/reference/fix-mode.en.md +3 -1
  322. package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +3 -1
  323. package/templates/.agents/skills/code-task/reference/report-template.en.md +42 -15
  324. package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +39 -12
  325. package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +2 -0
  326. package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +2 -0
  327. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +3 -3
  328. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +3 -3
  329. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +10 -4
  330. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +10 -4
  331. package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +2 -0
  332. package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +2 -0
  333. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +4 -3
  334. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +4 -3
  335. package/templates/.agents/skills/complete-task/SKILL.en.md +26 -21
  336. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +25 -21
  337. package/templates/.agents/skills/create-pr/SKILL.en.md +7 -6
  338. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +7 -7
  339. package/templates/.agents/skills/create-pr/config/verify.json +1 -0
  340. package/templates/.agents/skills/create-pr/reference/change-report.en.md +16 -4
  341. package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +16 -4
  342. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +5 -3
  343. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +5 -3
  344. package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +1 -1
  345. package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +1 -1
  346. package/templates/.agents/skills/create-pr/scripts/change-report.mjs +3 -0
  347. package/templates/.agents/skills/create-task/SKILL.en.md +8 -0
  348. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +7 -0
  349. package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
  350. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
  351. package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
  352. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
  353. package/templates/.agents/skills/init-labels/SKILL.en.md +8 -8
  354. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +8 -8
  355. package/templates/.agents/skills/init-milestones/SKILL.en.md +9 -11
  356. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +9 -11
  357. package/templates/.agents/skills/plan-task/SKILL.en.md +27 -4
  358. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +26 -4
  359. package/templates/.agents/skills/plan-task/config/verify.en.json +4 -14
  360. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +4 -14
  361. package/templates/.agents/skills/review-analysis/SKILL.en.md +17 -4
  362. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +17 -4
  363. package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -18
  364. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -18
  365. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +50 -23
  366. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +45 -18
  367. package/templates/.agents/skills/review-code/SKILL.en.md +18 -5
  368. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +18 -5
  369. package/templates/.agents/skills/review-code/config/verify.en.json +1 -23
  370. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -23
  371. package/templates/.agents/skills/review-code/reference/report-template.en.md +49 -22
  372. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +45 -18
  373. package/templates/.agents/skills/review-plan/SKILL.en.md +17 -4
  374. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +17 -4
  375. package/templates/.agents/skills/review-plan/config/verify.en.json +1 -18
  376. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -18
  377. package/templates/.agents/skills/review-plan/reference/report-template.en.md +49 -22
  378. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +45 -18
  379. package/templates/.agents/skills/review-pr/SKILL.en.md +5 -1
  380. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +5 -1
  381. package/templates/.agents/skills/review-pr/reference/report-template.en.md +4 -3
  382. package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +4 -3
  383. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +9 -3
  384. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +9 -3
  385. package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +3 -1
  386. package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +3 -1
  387. package/templates/.agents/skills/test/SKILL.en.md +13 -2
  388. package/templates/.agents/skills/test/SKILL.zh-CN.md +13 -2
  389. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +14 -0
  390. package/templates/.agents/skills/watch-pr/SKILL.en.md +2 -2
  391. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +2 -2
  392. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +6 -0
  393. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +6 -0
  394. package/templates/.agents/templates/task.en.md +24 -1
  395. package/templates/.agents/templates/task.zh-CN.md +24 -1
  396. package/templates/.github/workflows/pr-label.yml +7 -26
  397. package/templates/.agents/scripts/security-alerts.github.sh +0 -151
  398. package/templates/.agents/scripts/security-alerts.sh +0 -31
  399. package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +0 -146
  400. package/templates/.agents/skills/init-labels/scripts/init-labels.sh +0 -32
  401. package/templates/.agents/skills/init-milestones/scripts/init-milestones.github.sh +0 -294
  402. package/templates/.agents/skills/init-milestones/scripts/init-milestones.sh +0 -6
@@ -7,6 +7,7 @@ import { fetchSandboxRows, selectSandboxContainer } from './list-running.js';
7
7
  import { resolveTools, toolConfigDirCandidates } from '../tools.js';
8
8
  import { detectEngine } from '../engine.js';
9
9
  import { resolveSandboxTarget } from '../workspace-identity.js';
10
+ import { readSandboxControlStatusForRow } from './control-status.js';
10
11
  const USAGE = `Usage: ai sandbox show <branch | TASK-id | N>
11
12
 
12
13
  Shows one sandbox's worktree path and per-tool state paths (Claude Code,
@@ -62,6 +63,21 @@ export function show(args = []) {
62
63
  p.log.step('Workspace identity');
63
64
  process.stdout.write(` Mode: ${container?.workspaceMode ?? 'legacy-invalid'}\n`);
64
65
  process.stdout.write(` Task: ${container?.taskId ?? '-'}\n`);
66
+ p.log.step('Control status');
67
+ const controlStatus = container
68
+ ? readSandboxControlStatusForRow(config, container)
69
+ : null;
70
+ if (!controlStatus) {
71
+ p.log.warn(' Control status unavailable');
72
+ }
73
+ else {
74
+ process.stdout.write(` Health: ${controlStatus.state}\n`);
75
+ process.stdout.write(` Task view: ${controlStatus.taskView.state}\n`);
76
+ process.stdout.write(` Task source: ${controlStatus.taskView.observedSource ?? '-'}\n`);
77
+ if (controlStatus.taskView.reasonCode) {
78
+ process.stdout.write(` Task view reason: ${controlStatus.taskView.reasonCode}\n`);
79
+ }
80
+ }
65
81
  for (const tool of detail.toolStates) {
66
82
  p.log.step(`${tool.name} state`);
67
83
  if (tool.entries.length === 0) {
@@ -3,25 +3,79 @@ import path from 'node:path';
3
3
  import { randomUUID } from 'node:crypto';
4
4
  import { SANDBOX_CONTROL_ADMISSION_WINDOW_MS, SANDBOX_CONTROL_MAX_BYTES, SANDBOX_CONTROL_STATUS_STALE_MS, isSandboxControlFamily } from './protocol.js';
5
5
  import { normalizeAgentToken } from '../../agent-clients/tokens.js';
6
- import { readSandboxControlStatus } from './state.js';
6
+ import { readSandboxControlPayload, readSandboxControlStatus } from './state.js';
7
+ import { accessSandboxTaskView, taskViewFromStatus } from './task-view.js';
7
8
  const SANDBOX_CONTROL_RESPONSE_SETTLE_MS = 250;
9
+ export function classifySandboxControlEnvironment(env = process.env) {
10
+ const controlKeys = [
11
+ 'AGENT_INFRA_CONTROL_TOKEN',
12
+ 'AGENT_INFRA_CONTROL_GENERATION',
13
+ 'AGENT_INFRA_CONTROL_DIR',
14
+ 'AGENT_INFRA_CONTROL_STATUS_DIR'
15
+ ];
16
+ const hasControlMarker = controlKeys.some((key) => Boolean(env[key]));
17
+ const hasTaskIdentity = Boolean(env.AGENT_INFRA_TASK_ID);
18
+ const hasRuntime = Boolean(env.AGENT_INFRA_RUNTIME_DIR);
19
+ const hasExecutorMarker = Boolean(env.AGENT_INFRA_EXECUTOR_MANIFEST);
20
+ const hasControllerBinding = Boolean(env.AGENT_INFRA_CONTROL_CONTROLLER_BINDING);
21
+ const hasAnyMarker = hasControlMarker || hasTaskIdentity || hasRuntime || hasExecutorMarker || hasControllerBinding;
22
+ const hasCompleteControl = controlKeys.every((key) => Boolean(env[key]));
23
+ if (!hasAnyMarker)
24
+ return { kind: 'direct' };
25
+ if (hasExecutorMarker) {
26
+ return {
27
+ kind: 'invalid',
28
+ code: 'TASK_CONTROL_TRANSPORT_INVALID',
29
+ message: 'executor context is only valid for sandbox-control execute'
30
+ };
31
+ }
32
+ if (hasControllerBinding) {
33
+ return {
34
+ kind: 'invalid',
35
+ code: 'TASK_CONTROL_TRANSPORT_INVALID',
36
+ message: 'sandbox client control configuration is incomplete or conflicting'
37
+ };
38
+ }
39
+ if (!hasCompleteControl) {
40
+ return {
41
+ kind: 'invalid',
42
+ code: 'TASK_CONTROL_TRANSPORT_INVALID',
43
+ message: 'sandbox client control configuration is incomplete or conflicting'
44
+ };
45
+ }
46
+ if (hasTaskIdentity !== hasRuntime) {
47
+ return {
48
+ kind: 'invalid',
49
+ code: 'TASK_CONTROL_TRANSPORT_INVALID',
50
+ message: 'sandbox task identity and runtime binding must be provided together'
51
+ };
52
+ }
53
+ return { kind: 'controlled', mode: hasTaskIdentity ? 'task-bound' : 'branch-only' };
54
+ }
8
55
  export class SandboxControlClientError extends Error {
9
56
  detail;
10
57
  accepted;
11
- constructor(detail, accepted = false) {
58
+ requestId;
59
+ constructor(detail, accepted = false, requestId = null) {
12
60
  super(detail.message);
13
61
  this.name = 'SandboxControlClientError';
14
62
  this.detail = detail;
15
63
  this.accepted = accepted;
64
+ this.requestId = requestId;
16
65
  }
17
66
  }
18
67
  function sleep(milliseconds) {
19
68
  Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);
20
69
  }
21
- function clientError(code, message, retryable, accepted = false) {
22
- throw new SandboxControlClientError({ code, message: `${code}: ${message}`, retryable }, accepted);
70
+ function clientError(code, message, retryable, accepted = false, requestId = null) {
71
+ throw new SandboxControlClientError({ code, message: `${code}: ${message}`, retryable }, accepted, requestId);
72
+ }
73
+ function hasTaskBoundMarker(env = process.env) {
74
+ return Boolean(env.AGENT_INFRA_TASK_ID)
75
+ && Boolean(env.AGENT_INFRA_CONTROL_TOKEN || env.AGENT_INFRA_CONTROL_GENERATION
76
+ || env.AGENT_INFRA_CONTROL_STATUS_DIR || env.AGENT_INFRA_RUNTIME_DIR || env.AGENT_INFRA_CONTROL_DIR);
23
77
  }
24
- function preflight(statusDir, generation, now = Date.now()) {
78
+ function preflight(statusDir, generation, taskViewEffect = null, now = Date.now(), env = process.env) {
25
79
  let status;
26
80
  try {
27
81
  status = readSandboxControlStatus(statusDir);
@@ -43,16 +97,56 @@ function preflight(statusDir, generation, now = Date.now()) {
43
97
  }
44
98
  if (status.state !== 'healthy')
45
99
  clientError('SANDBOX_CONTROL_BROKER_UNAVAILABLE', 'broker is not ready', true);
100
+ if (taskViewEffect && hasTaskBoundMarker(env)) {
101
+ const view = taskViewFromStatus(status);
102
+ if (view.taskId !== env.AGENT_INFRA_TASK_ID) {
103
+ clientError('SANDBOX_TASK_VIEW_TASK_ID_MISMATCH', 'task view task id does not match the sandbox task marker', false);
104
+ }
105
+ const access = accessSandboxTaskView(view, taskViewEffect);
106
+ if (!access.allowed) {
107
+ clientError(access.reasonCode ?? 'SANDBOX_TASK_VIEW_DENIED', access.message ?? 'task view denied', false);
108
+ }
109
+ }
110
+ }
111
+ function taskViewEffectForRequest(request) {
112
+ if (request.family === 'task-lifecycle' || request.family === 'task-finalization')
113
+ return 'progress';
114
+ if (request.family === 'task-orchestration')
115
+ return request.args[1] === 'status' ? 'diagnostic' : 'progress';
116
+ return null;
46
117
  }
47
- function parseResponse(raw, id) {
118
+ function parseResponse(raw, id, accepted = false) {
48
119
  const response = JSON.parse(raw);
49
120
  if (response.version !== 2 || response.id !== id
50
- || !['accepted', 'completed', 'rejected'].includes(response.phase)
51
- || (response.phase === 'completed' && !Number.isInteger(response.exitCode))) {
52
- clientError('SANDBOX_CONTROL_RESPONSE_INVALID', 'broker response is invalid', false);
121
+ || !['completed', 'rejected'].includes(response.phase)
122
+ || (response.phase === 'completed' && !Number.isInteger(response.exitCode))
123
+ || (response.outputState !== undefined && response.outputState !== 'available' && response.outputState !== 'unavailable')
124
+ || (response.outputState === 'available' && !response.payload)
125
+ || (response.outputState === 'unavailable' && response.payload !== null && response.payload !== undefined)) {
126
+ clientError('SANDBOX_CONTROL_RESPONSE_INVALID', 'broker response is invalid', false, accepted, id);
53
127
  }
54
128
  return response;
55
129
  }
130
+ function readPublishedResponse(raw, id, channelDir, accepted = false) {
131
+ const response = parseResponse(raw, id, accepted);
132
+ if (response.outputState !== 'available')
133
+ return response;
134
+ const filePath = path.join(channelDir, 'responses', `${id}.payload.json`);
135
+ let payload;
136
+ try {
137
+ payload = readSandboxControlPayload(filePath);
138
+ }
139
+ catch {
140
+ clientError('SANDBOX_CONTROL_RESPONSE_INVALID', 'broker payload is missing or invalid', false, true, id);
141
+ }
142
+ if (!response.payload || response.payload.version !== payload.version
143
+ || response.payload.id !== payload.id || response.payload.generation !== payload.generation
144
+ || response.payload.stdoutBytes !== payload.stdoutBytes || response.payload.stderrBytes !== payload.stderrBytes
145
+ || response.payload.stdoutSha256 !== payload.stdoutSha256 || response.payload.stderrSha256 !== payload.stderrSha256) {
146
+ clientError('SANDBOX_CONTROL_RESPONSE_INVALID', 'broker payload reference is invalid', false, true, id);
147
+ }
148
+ return { ...response, stdout: payload.stdout, stderr: payload.stderr };
149
+ }
56
150
  function cancelPendingRequest(requestPath) {
57
151
  try {
58
152
  fs.unlinkSync(requestPath);
@@ -67,16 +161,20 @@ function cancelPendingRequest(requestPath) {
67
161
  function exchangeSandboxControl(request, params) {
68
162
  const channelDir = params.channelDir ?? process.env.AGENT_INFRA_CONTROL_DIR ?? '/run/agent-infra/control';
69
163
  const statusDir = params.statusDir ?? process.env.AGENT_INFRA_CONTROL_STATUS_DIR ?? '/run/agent-infra/control-status';
70
- preflight(statusDir, request.generation);
164
+ const taskViewEffect = taskViewEffectForRequest(request);
165
+ preflight(statusDir, request.generation, taskViewEffect);
71
166
  const encoded = `${JSON.stringify(request)}\n`;
72
167
  if (Buffer.byteLength(encoded, 'utf8') > SANDBOX_CONTROL_MAX_BYTES) {
73
- clientError('SANDBOX_CONTROL_REQUEST_TOO_LARGE', 'request exceeds the control limit', false);
168
+ clientError('SANDBOX_CONTROL_REQUEST_TOO_LARGE', 'request exceeds the control limit', false, false, request.id);
74
169
  }
75
170
  const requestsDir = path.join(channelDir, 'requests');
76
171
  const responsesDir = path.join(channelDir, 'responses');
77
172
  const temporary = path.join(requestsDir, `.${request.id}.tmp`);
78
173
  const requestPath = path.join(requestsDir, `${request.id}.json`);
79
174
  const responsePath = path.join(responsesDir, `${request.id}.json`);
175
+ if (fs.existsSync(responsePath)) {
176
+ clientError('SANDBOX_CONTROL_REQUEST_REPLAYED', 'request id already has a terminal response', false, false, request.id);
177
+ }
80
178
  fs.writeFileSync(temporary, encoded, { mode: 0o600, flag: 'wx' });
81
179
  fs.renameSync(temporary, requestPath);
82
180
  const deadline = Date.now() + (params.timeoutMs ?? 30_000);
@@ -84,6 +182,9 @@ function exchangeSandboxControl(request, params) {
84
182
  let malformedResponseRaw = null;
85
183
  let malformedResponseObservedAt = 0;
86
184
  while (Date.now() < deadline) {
185
+ const acceptedPath = path.join(responsesDir, `${request.id}.accepted.json`);
186
+ if (fs.existsSync(acceptedPath))
187
+ accepted = true;
87
188
  if (fs.existsSync(responsePath)) {
88
189
  let raw;
89
190
  try {
@@ -96,7 +197,9 @@ function exchangeSandboxControl(request, params) {
96
197
  }
97
198
  let response;
98
199
  try {
99
- response = parseResponse(raw, request.id);
200
+ // The request-specific terminal proves the broker claimed the request; preserve recovery evidence if marker cleanup won the race.
201
+ accepted = true;
202
+ response = readPublishedResponse(raw, request.id, channelDir, accepted);
100
203
  malformedResponseRaw = null;
101
204
  }
102
205
  catch (error) {
@@ -108,7 +211,7 @@ function exchangeSandboxControl(request, params) {
108
211
  malformedResponseObservedAt = now;
109
212
  }
110
213
  else if (now - malformedResponseObservedAt >= SANDBOX_CONTROL_RESPONSE_SETTLE_MS) {
111
- clientError('SANDBOX_CONTROL_RESPONSE_INVALID', 'broker response remained malformed', false, accepted);
214
+ clientError('SANDBOX_CONTROL_RESPONSE_INVALID', 'broker response remained malformed', false, accepted, request.id);
112
215
  }
113
216
  sleep(25);
114
217
  continue;
@@ -117,29 +220,81 @@ function exchangeSandboxControl(request, params) {
117
220
  accepted = true;
118
221
  }
119
222
  else {
120
- fs.rmSync(responsePath, { force: true });
121
223
  return response;
122
224
  }
123
225
  }
124
226
  if (!accepted) {
125
227
  try {
126
- preflight(statusDir, request.generation);
228
+ preflight(statusDir, request.generation, taskViewEffect);
127
229
  }
128
230
  catch (error) {
129
231
  if (cancelPendingRequest(requestPath))
130
232
  throw error;
131
- clientError('SANDBOX_CONTROL_RESULT_UNKNOWN', 'request was claimed before broker availability was lost; inspect domain state before retrying', false, true);
233
+ clientError('SANDBOX_CONTROL_RESULT_UNKNOWN', 'request was claimed before broker availability was lost; inspect domain state before retrying', false, true, request.id);
132
234
  }
133
235
  }
134
236
  sleep(25);
135
237
  }
136
238
  if (accepted) {
137
- clientError('SANDBOX_CONTROL_RESULT_UNKNOWN', 'accepted request did not produce a final result; inspect domain state before retrying', false, true);
239
+ clientError('SANDBOX_CONTROL_RESULT_UNKNOWN', 'accepted request did not produce a final result; inspect domain state before retrying', false, true, request.id);
138
240
  }
139
241
  if (!cancelPendingRequest(requestPath)) {
140
- clientError('SANDBOX_CONTROL_RESULT_UNKNOWN', 'request was claimed but no acceptance result was observed; inspect domain state before retrying', false, true);
242
+ clientError('SANDBOX_CONTROL_RESULT_UNKNOWN', 'request was claimed but no acceptance result was observed; inspect domain state before retrying', false, true, request.id);
243
+ }
244
+ clientError('SANDBOX_CONTROL_BROKER_UNAVAILABLE', `broker did not accept the request within ${params.timeoutMs ?? 30_000}ms`, true, false, request.id);
245
+ }
246
+ export function recoverSandboxControl(requestId, params = {}) {
247
+ if (!/^[a-f0-9-]{16,64}$/u.test(requestId)) {
248
+ clientError('SANDBOX_CONTROL_REQUEST_INVALID', 'request id is invalid', false, true);
249
+ }
250
+ const channelDir = params.channelDir ?? process.env.AGENT_INFRA_CONTROL_DIR ?? '/run/agent-infra/control';
251
+ const responsePath = path.join(channelDir, 'responses', `${requestId}.json`);
252
+ const deadline = Date.now() + (params.timeoutMs ?? 30_000);
253
+ let accepted = false;
254
+ let malformedResponseRaw = null;
255
+ let malformedResponseObservedAt = 0;
256
+ while (Date.now() < deadline) {
257
+ if (fs.existsSync(path.join(channelDir, 'responses', `${requestId}.accepted.json`)))
258
+ accepted = true;
259
+ if (fs.existsSync(responsePath)) {
260
+ let raw;
261
+ try {
262
+ raw = fs.readFileSync(responsePath, 'utf8');
263
+ }
264
+ catch (error) {
265
+ if (error.code === 'ENOENT')
266
+ continue;
267
+ throw error;
268
+ }
269
+ let response;
270
+ try {
271
+ // The request-specific terminal proves the broker claimed the request; preserve recovery evidence if marker cleanup won the race.
272
+ accepted = true;
273
+ response = readPublishedResponse(raw, requestId, channelDir, accepted);
274
+ malformedResponseRaw = null;
275
+ }
276
+ catch (error) {
277
+ if (!(error instanceof SyntaxError))
278
+ throw error;
279
+ const now = Date.now();
280
+ if (malformedResponseRaw !== raw) {
281
+ malformedResponseRaw = raw;
282
+ malformedResponseObservedAt = now;
283
+ }
284
+ else if (now - malformedResponseObservedAt >= SANDBOX_CONTROL_RESPONSE_SETTLE_MS) {
285
+ clientError('SANDBOX_CONTROL_RESPONSE_INVALID', 'broker response remained malformed', false, accepted, requestId);
286
+ }
287
+ sleep(25);
288
+ continue;
289
+ }
290
+ if (response.phase === 'accepted')
291
+ accepted = true;
292
+ else
293
+ return response;
294
+ }
295
+ sleep(25);
141
296
  }
142
- clientError('SANDBOX_CONTROL_BROKER_UNAVAILABLE', `broker did not accept the request within ${params.timeoutMs ?? 30_000}ms`, true);
297
+ clientError('SANDBOX_CONTROL_RESULT_UNKNOWN', 'request did not produce a final result; inspect domain state before retrying', false, accepted, requestId);
143
298
  }
144
299
  function authority(params) {
145
300
  const token = params.token ?? process.env.AGENT_INFRA_CONTROL_TOKEN;
@@ -0,0 +1,85 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { resolveTaskWorkspace } from '../task-resolver.js';
4
+ import { assertGitWorktreeBinding } from '../../git/worktree-identity.js';
5
+ import { parseTypedTaskFrontmatter } from '../../task/frontmatter.js';
6
+ import { readTaskFinalizationReceipt } from '../../task/finalization.js';
7
+ import { inspectSandboxControlContainer } from './container-identity.js';
8
+ import { atomicWriteJson, readSandboxControlStatus } from './state.js';
9
+ import { taskViewForManifest } from './task-view.js';
10
+ function evidencePath(manifest) {
11
+ return path.join(path.dirname(manifest.processingDir), 'completed-reentry.json');
12
+ }
13
+ function invalid() {
14
+ return new Error('SANDBOX_COMPLETED_REENTRY_EVIDENCE_INVALID');
15
+ }
16
+ export async function prepareCompletedReentry(manifest, inspect = inspectSandboxControlContainer) {
17
+ if (manifest.mode !== 'task-bound' || !manifest.taskId)
18
+ throw invalid();
19
+ assertGitWorktreeBinding(manifest.repoRoot, manifest.worktreeRoot, manifest.branch);
20
+ const container = await inspect(manifest);
21
+ if (container.state !== 'found' || container.id !== manifest.containerIdentity.id)
22
+ throw invalid();
23
+ const task = resolveTaskWorkspace(manifest.taskId, manifest.repoRoot);
24
+ const metadata = parseTypedTaskFrontmatter(fs.readFileSync(task.taskMd, 'utf8'));
25
+ if (task.state !== 'completed' || task.branch !== manifest.branch
26
+ || metadata.id !== manifest.taskId || metadata.status !== 'completed')
27
+ throw invalid();
28
+ const receipt = readTaskFinalizationReceipt(manifest.repoRoot, manifest.taskId);
29
+ if (!receipt || receipt.taskId !== manifest.taskId)
30
+ throw invalid();
31
+ const view = taskViewForManifest({ ...manifest, receipt });
32
+ if (view.state !== 'current' || view.observedSource !== 'completed' || !view.receipt)
33
+ throw invalid();
34
+ const status = readSandboxControlStatus(manifest.publicStatusDir);
35
+ const previous = status.taskView;
36
+ if (status.generation !== manifest.generation || status.activeRequestId !== null
37
+ || previous.taskId !== manifest.taskId || !previous.receipt
38
+ || previous.receipt.receiptId !== view.receipt.receiptId
39
+ || previous.receipt.generation !== view.receipt.generation
40
+ || previous.receipt.requestId !== view.receipt.requestId
41
+ || previous.receipt.revision > view.receipt.revision)
42
+ throw invalid();
43
+ const completedRoot = fs.realpathSync.native(path.join(manifest.repoRoot, '.agents', 'workspace', 'completed'));
44
+ const source = fs.realpathSync.native(path.join(completedRoot, manifest.taskId));
45
+ if (source !== path.join(completedRoot, manifest.taskId))
46
+ throw invalid();
47
+ const stat = fs.statSync(source, { bigint: true });
48
+ return {
49
+ taskId: manifest.taskId, generation: manifest.generation,
50
+ containerId: container.id, branch: manifest.branch,
51
+ worktreeRoot: fs.realpathSync.native(manifest.worktreeRoot),
52
+ source, sourceDevice: String(stat.dev), sourceInode: String(stat.ino), receipt: view.receipt
53
+ };
54
+ }
55
+ export function publishCompletedReentry(manifest, evidence) {
56
+ atomicWriteJson(evidencePath(manifest), evidence);
57
+ }
58
+ export async function completedReentryView(manifest, inspect = inspectSandboxControlContainer) {
59
+ const file = evidencePath(manifest);
60
+ if (!fs.existsSync(file))
61
+ return null;
62
+ const evidence = JSON.parse(fs.readFileSync(file, 'utf8'));
63
+ const current = await prepareCompletedReentry(manifest, inspect);
64
+ if (JSON.stringify(evidence) !== JSON.stringify(current))
65
+ throw invalid();
66
+ return {
67
+ state: 'current', taskId: current.taskId, observedSource: 'completed',
68
+ receipt: current.receipt, reasonCode: null
69
+ };
70
+ }
71
+ export async function waitForCompletedReentry(manifest, evidence) {
72
+ const deadline = Date.now() + 10_000;
73
+ while (Date.now() < deadline) {
74
+ const status = readSandboxControlStatus(manifest.publicStatusDir);
75
+ if (status.generation !== evidence.generation)
76
+ throw invalid();
77
+ if (status.taskView.state === 'current' && status.taskView.observedSource === 'completed'
78
+ && status.taskView.taskId === evidence.taskId
79
+ && JSON.stringify(status.taskView.receipt) === JSON.stringify(evidence.receipt))
80
+ return;
81
+ await new Promise((resolve) => setTimeout(resolve, 100));
82
+ }
83
+ throw new Error('SANDBOX_COMPLETED_REENTRY_STATUS_TIMEOUT');
84
+ }
85
+ //# sourceMappingURL=completed-reentry.js.map
@@ -1,15 +1,11 @@
1
- import { commandForEngine, runEngine, runProbe } from '../shell.js';
2
- function isAuthoritativeNotFound(error) {
3
- const message = error instanceof Error ? error.message : String(error);
4
- return /(?:no such (?:container|object)|container .* not found|cannot find container)/i.test(message);
5
- }
1
+ import { runProbe } from '../shell.js';
2
+ import { captureSandboxAuthority, isSandboxAuthorityEvidence, verifySandboxAuthority } from '../engines/authority.js';
3
+ import { discoverExactContainer } from '../engines/docker-exact-discovery.js';
6
4
  export function classifySandboxContainerInspection(expected, inspection) {
7
5
  if ('notFound' in inspection)
8
6
  return { state: 'absent', id: expected.id };
9
7
  if ('error' in inspection) {
10
- return isAuthoritativeNotFound(inspection.error)
11
- ? { state: 'absent', id: expected.id }
12
- : { state: 'unknown', reason: `container inspection failed: ${inspection.error instanceof Error ? inspection.error.message : String(inspection.error)}` };
8
+ return { state: 'unknown', reason: `container inspection failed: ${inspection.error instanceof Error ? inspection.error.message : String(inspection.error)}` };
13
9
  }
14
10
  const response = inspection;
15
11
  if (typeof response.id !== 'string' || response.id !== expected.id
@@ -30,32 +26,33 @@ export function classifySandboxContainerInspection(expected, inspection) {
30
26
  };
31
27
  }
32
28
  export async function inspectSandboxControlContainer(manifest, options = {}) {
29
+ if (!isSandboxAuthorityEvidence(manifest.authorityEvidence)) {
30
+ return { state: 'unknown', reason: 'SANDBOX_AUTHORITY_EVIDENCE_MISSING' };
31
+ }
33
32
  try {
34
- const args = ['inspect', '--format', '{{json .}}', manifest.containerIdentity.id];
35
- let raw;
36
- if (options.run) {
37
- raw = options.run(manifest.engine, 'docker', args, options.timeoutMs === undefined ? {} : { timeout: options.timeoutMs });
38
- }
39
- else {
40
- const command = commandForEngine(manifest.engine, 'docker', args);
41
- const result = (options.probe ?? runProbe)(command.cmd, command.args, options.timeoutMs === undefined ? {} : { timeout: options.timeoutMs });
42
- if (result.status !== 0) {
43
- const stderr = typeof result.stderr === 'string' ? result.stderr : result.stderr?.toString('utf8') ?? '';
44
- return classifySandboxContainerInspection(manifest.containerIdentity, {
45
- error: new Error(stderr || `container inspection exited with ${result.status ?? 'unknown'}`)
46
- });
47
- }
48
- raw = typeof result.stdout === 'string' ? result.stdout : result.stdout?.toString('utf8') ?? '';
33
+ const authority = captureSandboxAuthority(manifest.engine, {
34
+ probe: options.probe,
35
+ timeoutMs: options.timeoutMs,
36
+ lockDomain: manifest.authorityEvidence.lockDomain,
37
+ route: manifest.authorityEvidence
38
+ });
39
+ const authorityState = verifySandboxAuthority(manifest.authorityEvidence, authority);
40
+ if (authorityState.state !== 'verified') {
41
+ return { state: 'unknown', reason: authorityState.reason ?? 'SANDBOX_AUTHORITY_UNAVAILABLE' };
49
42
  }
50
- const parsed = JSON.parse(raw);
51
- const value = Array.isArray(parsed) && parsed.length === 1 ? parsed[0] : parsed;
52
- if (!value || Array.isArray(value))
53
- return { state: 'unknown', reason: 'container inspection response is incomplete' };
54
- return classifySandboxContainerInspection(manifest.containerIdentity, {
55
- id: value.Id,
56
- running: value.State?.Running,
57
- labels: value.Config?.Labels
43
+ const discovered = discoverExactContainer(manifest.engine, manifest.containerIdentity.id, {
44
+ probe: options.probe,
45
+ timeoutMs: options.timeoutMs,
46
+ authority: manifest.authorityEvidence
58
47
  });
48
+ if (discovered.state === 'absent')
49
+ return { state: 'absent', id: discovered.id };
50
+ if (discovered.state === 'conflict') {
51
+ return { state: 'unknown', reason: `SANDBOX_CONTROL_CONTAINER_CONFLICT: ${discovered.reason}` };
52
+ }
53
+ if (discovered.state === 'unknown')
54
+ return discovered;
55
+ return classifySandboxContainerInspection(manifest.containerIdentity, discovered);
59
56
  }
60
57
  catch (error) {
61
58
  return classifySandboxContainerInspection(manifest.containerIdentity, { error });