@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
@@ -0,0 +1,289 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { runProbe } from '../shell.js';
3
+ import { getAdapter } from './index.js';
4
+ function digest(value) {
5
+ return createHash('sha256').update(value).digest('hex');
6
+ }
7
+ function canonical(value) {
8
+ if (Array.isArray(value))
9
+ return `[${value.map(canonical).join(',')}]`;
10
+ if (!value || typeof value !== 'object')
11
+ return JSON.stringify(value) ?? 'null';
12
+ return `{${Object.entries(value)
13
+ .sort(([left], [right]) => left.localeCompare(right))
14
+ .map(([key, entry]) => `${JSON.stringify(key)}:${canonical(entry)}`)
15
+ .join(',')}}`;
16
+ }
17
+ function text(value) {
18
+ return typeof value === 'string' ? value : value?.toString('utf8') ?? '';
19
+ }
20
+ function safeEndpoint(value) {
21
+ if (!value)
22
+ return 'docker-default';
23
+ try {
24
+ const parsed = new URL(value);
25
+ const hasUnreplayableParts = Boolean(parsed.username || parsed.password || parsed.search || parsed.hash);
26
+ parsed.username = '';
27
+ parsed.password = '';
28
+ parsed.search = '';
29
+ parsed.hash = '';
30
+ const normalized = parsed.toString().replace(/\/$/u, '');
31
+ return hasUnreplayableParts
32
+ ? `${normalized}#<redacted>`
33
+ : normalized;
34
+ }
35
+ catch {
36
+ const normalized = value
37
+ .replace(/\/\/[^/@]+@/u, '//<redacted>@')
38
+ .replace(/[?&](?:token|password|secret|key)=[^&]*/giu, '');
39
+ return /[@?#]/u.test(value) ? `${normalized.replace(/[?#].*$/u, '')}#<redacted>` : normalized;
40
+ }
41
+ }
42
+ function lockDomainFor(engine, endpoint) {
43
+ return digest(`${process.platform}\0${process.arch}\0${engine}\0${endpoint}`);
44
+ }
45
+ function contextRoute(context) {
46
+ return {
47
+ kind: 'context',
48
+ selector: { context },
49
+ endpoint: `docker-context://${context}`,
50
+ command: (args) => ({ cmd: 'docker', args: ['--context', context, ...args] })
51
+ };
52
+ }
53
+ function endpointRoute(endpoint, rawEndpoint, unreplayable) {
54
+ return {
55
+ kind: 'endpoint',
56
+ selector: {
57
+ source: 'DOCKER_HOST',
58
+ endpoint,
59
+ ...(unreplayable ? { unreplayable } : {})
60
+ },
61
+ endpoint,
62
+ command: (args) => ({ cmd: 'docker', args: ['--host', rawEndpoint, ...args] })
63
+ };
64
+ }
65
+ function tlsEnvironmentReason(env) {
66
+ return env.DOCKER_TLS_VERIFY || env.DOCKER_CERT_PATH || env.DOCKER_TLS
67
+ ? 'tls-environment'
68
+ : undefined;
69
+ }
70
+ function routeFor(engine, env) {
71
+ const context = getAdapter(engine).dockerContext;
72
+ if (context) {
73
+ return contextRoute(context);
74
+ }
75
+ if (env.DOCKER_CONTEXT) {
76
+ return contextRoute(env.DOCKER_CONTEXT);
77
+ }
78
+ if (env.DOCKER_HOST) {
79
+ return endpointRoute(safeEndpoint(env.DOCKER_HOST), env.DOCKER_HOST, tlsEnvironmentReason(env));
80
+ }
81
+ return contextRoute('default');
82
+ }
83
+ function validRouteName(value) {
84
+ return /^[A-Za-z0-9][A-Za-z0-9_.@/-]*$/u.test(value);
85
+ }
86
+ function resolveWslDistro(probe, timeoutMs, explicit) {
87
+ if (explicit) {
88
+ if (!validRouteName(explicit))
89
+ throw new Error('SANDBOX_AUTHORITY_ROUTE_CAPTURE_FAILED');
90
+ return explicit;
91
+ }
92
+ const result = probe('wsl.exe', ['--list', '--verbose'], timeoutMs === undefined ? {} : { timeout: timeoutMs });
93
+ if (result.status !== 0)
94
+ throw new Error('SANDBOX_AUTHORITY_ROUTE_CAPTURE_FAILED');
95
+ const output = text(result.stdout).replace(/\0/gu, '').replace(/\r/gu, '');
96
+ const defaultLine = output.split('\n').find((line) => /^\s*\*\s+/u.test(line));
97
+ const distro = defaultLine?.replace(/^\s*\*\s+/u, '').replace(/\s+(?:Running|Stopped)\s+\d+\s*$/iu, '').trim();
98
+ if (!distro || !validRouteName(distro))
99
+ throw new Error('SANDBOX_AUTHORITY_ROUTE_CAPTURE_FAILED');
100
+ return distro;
101
+ }
102
+ function wslRoute(distro, context, env) {
103
+ const endpoint = env.DOCKER_HOST
104
+ ? safeEndpoint(env.DOCKER_HOST)
105
+ : `wsl://${distro}/${context ?? 'default'}`;
106
+ const unreplayable = tlsEnvironmentReason(env)
107
+ ?? (endpoint.includes('<redacted>') ? 'ambient-endpoint-secret' : undefined);
108
+ return {
109
+ kind: 'wsl2',
110
+ selector: {
111
+ distro,
112
+ ...(context ? { context } : {}),
113
+ ...(unreplayable ? { unreplayable } : {}),
114
+ ...(env.DOCKER_HOST ? { endpoint } : {})
115
+ },
116
+ endpoint,
117
+ command: (args) => ({
118
+ cmd: 'wsl.exe',
119
+ args: [
120
+ '--distribution', distro,
121
+ '--exec', 'docker',
122
+ ...(context ? ['--context', context] : []),
123
+ ...(env.DOCKER_HOST ? ['--host', env.DOCKER_HOST] : []),
124
+ ...args
125
+ ]
126
+ })
127
+ };
128
+ }
129
+ function currentWslRoute(env, probe, timeoutMs) {
130
+ const distro = resolveWslDistro(probe, timeoutMs, env.WSL_DISTRO_NAME);
131
+ let context = env.DOCKER_CONTEXT;
132
+ if (!context && !env.DOCKER_HOST) {
133
+ const result = probe('wsl.exe', ['--distribution', distro, '--exec', 'docker', 'context', 'show'], timeoutMs === undefined ? {} : { timeout: timeoutMs });
134
+ context = text(result.stdout).trim();
135
+ if (result.status !== 0 || !validRouteName(context)) {
136
+ throw new Error('SANDBOX_AUTHORITY_ROUTE_CAPTURE_FAILED');
137
+ }
138
+ }
139
+ return wslRoute(distro, context, env);
140
+ }
141
+ function routeFromEvidence(evidence) {
142
+ return {
143
+ kind: evidence.routeKind,
144
+ selector: evidence.routeSelector,
145
+ endpoint: evidence.normalizedEndpoint,
146
+ command: (args) => commandForSandboxAuthority(evidence, 'docker', args)
147
+ };
148
+ }
149
+ function currentContextRoute(engine, env, probe, timeoutMs) {
150
+ const configured = routeFor(engine, env);
151
+ if (configured.kind !== 'context' || configured.selector.context !== 'default')
152
+ return configured;
153
+ if (env.DOCKER_CONTEXT || env.DOCKER_HOST || getAdapter(engine).dockerContext)
154
+ return configured;
155
+ const result = probe('docker', ['context', 'show'], timeoutMs === undefined ? {} : { timeout: timeoutMs });
156
+ const context = text(result.stdout).trim();
157
+ if (result.status !== 0 || !/^[A-Za-z0-9][A-Za-z0-9_.@/-]*$/u.test(context)) {
158
+ throw new Error('SANDBOX_AUTHORITY_ROUTE_CAPTURE_FAILED');
159
+ }
160
+ return contextRoute(context);
161
+ }
162
+ /** Build a command using only the route persisted with the sandbox authority. */
163
+ export function commandForSandboxAuthority(evidence, cmd, args = []) {
164
+ if (cmd !== 'docker') {
165
+ throw new Error('SANDBOX_AUTHORITY_ROUTE_UNSUPPORTED');
166
+ }
167
+ if (evidence.routeKind === 'context') {
168
+ const context = evidence.routeSelector.context;
169
+ if (!context)
170
+ throw new Error('SANDBOX_AUTHORITY_ROUTE_INVALID');
171
+ return { cmd, args: ['--context', context, ...args] };
172
+ }
173
+ if (evidence.routeKind === 'endpoint') {
174
+ const endpoint = evidence.routeSelector.endpoint;
175
+ if (!endpoint || endpoint.includes('<redacted>') || evidence.routeSelector.unreplayable) {
176
+ throw new Error('SANDBOX_AUTHORITY_ROUTE_UNREPLAYABLE');
177
+ }
178
+ return { cmd, args: ['--host', endpoint, ...args] };
179
+ }
180
+ if (evidence.routeKind === 'wsl2') {
181
+ const distro = evidence.routeSelector.distro;
182
+ const context = evidence.routeSelector.context;
183
+ const endpoint = evidence.routeSelector.endpoint;
184
+ if (!distro || evidence.routeSelector.unreplayable || endpoint?.includes('<redacted>')) {
185
+ throw new Error('SANDBOX_AUTHORITY_ROUTE_UNREPLAYABLE');
186
+ }
187
+ return {
188
+ cmd: 'wsl.exe',
189
+ args: [
190
+ '--distribution', distro,
191
+ '--exec', cmd,
192
+ ...(context ? ['--context', context] : []),
193
+ ...(endpoint && !endpoint.startsWith('wsl://') ? ['--host', endpoint] : []),
194
+ ...args
195
+ ]
196
+ };
197
+ }
198
+ return { cmd, args: ['--context', 'default', ...args] };
199
+ }
200
+ export function authorityVersionArgs() {
201
+ return ['version', '--format', '{{json .Server}}'];
202
+ }
203
+ export function captureSandboxAuthority(engine, options = {}) {
204
+ const env = options.env ?? process.env;
205
+ const probe = options.probe ?? runProbe;
206
+ const route = options.route
207
+ ? routeFromEvidence(options.route)
208
+ : engine === 'wsl2'
209
+ ? currentWslRoute(env, probe, options.timeoutMs)
210
+ : currentContextRoute(engine, env, probe, options.timeoutMs);
211
+ function probeJson(args) {
212
+ const command = options.route
213
+ ? commandForSandboxAuthority(options.route, 'docker', args)
214
+ : route.command(args);
215
+ try {
216
+ const response = probe(command.cmd, command.args, options.timeoutMs === undefined ? {} : { timeout: options.timeoutMs });
217
+ if (response.status !== 0)
218
+ throw new Error('SANDBOX_AUTHORITY_CAPTURE_FAILED');
219
+ return JSON.parse(text(response.stdout).trim());
220
+ }
221
+ catch {
222
+ throw new Error('SANDBOX_AUTHORITY_CAPTURE_FAILED');
223
+ }
224
+ }
225
+ const server = probeJson(authorityVersionArgs());
226
+ if (!server || typeof server !== 'object' || Array.isArray(server)) {
227
+ throw new Error('SANDBOX_AUTHORITY_CAPTURE_FAILED');
228
+ }
229
+ const record = server;
230
+ const api = typeof record.ApiVersion === 'string' ? /^(\d+)\.(\d+)$/u.exec(record.ApiVersion) : null;
231
+ if (!api)
232
+ throw new Error('SANDBOX_AUTHORITY_CAPTURE_FAILED');
233
+ // Docker version exposes API metadata; the daemon ID belongs to Docker info.
234
+ const serverId = probeJson(['info', '--format', '{{json .ID}}']);
235
+ if (typeof serverId !== 'string' || !serverId.trim())
236
+ throw new Error('SANDBOX_AUTHORITY_CAPTURE_FAILED');
237
+ const normalizedEndpoint = route.endpoint;
238
+ const evidenceWithoutFingerprint = {
239
+ version: 1,
240
+ provider: engine,
241
+ lockDomain: options.lockDomain ?? options.route?.lockDomain ?? lockDomainFor(engine, normalizedEndpoint),
242
+ routeKind: route.kind,
243
+ routeSelector: route.selector,
244
+ normalizedEndpoint,
245
+ endpointFingerprint: digest(normalizedEndpoint),
246
+ daemonIdentity: { kind: 'docker-server-id', fingerprint: digest(serverId) },
247
+ apiVersion: { major: Number(api[1]), minor: Number(api[2]) }
248
+ };
249
+ return {
250
+ ...evidenceWithoutFingerprint,
251
+ authorityFingerprint: digest(canonical(evidenceWithoutFingerprint))
252
+ };
253
+ }
254
+ export function verifySandboxAuthority(expected, actual) {
255
+ if (!expected)
256
+ return { state: 'unknown', reason: 'SANDBOX_AUTHORITY_EVIDENCE_MISSING' };
257
+ if (!actual)
258
+ return { state: 'unknown', reason: 'SANDBOX_AUTHORITY_UNAVAILABLE' };
259
+ if (expected.authorityFingerprint !== actual.authorityFingerprint
260
+ || expected.lockDomain !== actual.lockDomain
261
+ || expected.routeKind !== actual.routeKind
262
+ || expected.endpointFingerprint !== actual.endpointFingerprint
263
+ || expected.daemonIdentity.fingerprint !== actual.daemonIdentity.fingerprint) {
264
+ return { state: 'conflict', reason: 'SANDBOX_AUTHORITY_DRIFT' };
265
+ }
266
+ return { state: 'verified' };
267
+ }
268
+ export function isSandboxAuthorityEvidence(value) {
269
+ if (!value || typeof value !== 'object' || Array.isArray(value))
270
+ return false;
271
+ const evidence = value;
272
+ const selector = evidence.routeSelector;
273
+ const daemon = evidence.daemonIdentity;
274
+ const api = evidence.apiVersion;
275
+ return evidence.version === 1
276
+ && typeof evidence.provider === 'string'
277
+ && /^[a-f0-9]{64}$/u.test(evidence.lockDomain)
278
+ && ['default', 'context', 'endpoint', 'wsl2'].includes(evidence.routeKind)
279
+ && !!selector && typeof selector === 'object' && !Array.isArray(selector)
280
+ && Object.values(selector).every((entry) => typeof entry === 'string')
281
+ && typeof evidence.normalizedEndpoint === 'string'
282
+ && /^[a-f0-9]{64}$/u.test(evidence.endpointFingerprint)
283
+ && !!daemon && daemon.kind === 'docker-server-id'
284
+ && /^[a-f0-9]{64}$/u.test(daemon.fingerprint)
285
+ && !!api && Number.isSafeInteger(api.major) && api.major >= 0
286
+ && Number.isSafeInteger(api.minor) && api.minor >= 0
287
+ && /^[a-f0-9]{64}$/u.test(evidence.authorityFingerprint);
288
+ }
289
+ //# sourceMappingURL=authority.js.map
@@ -0,0 +1,97 @@
1
+ import { commandForEngine, runProbe } from '../shell.js';
2
+ import { commandForSandboxAuthority } from './authority.js';
3
+ const FULL_CONTAINER_ID = /^[a-f0-9]{64}$/u;
4
+ function outputText(value) {
5
+ return typeof value === 'string' ? value : value?.toString('utf8') ?? '';
6
+ }
7
+ function unknown(reason) {
8
+ return { state: 'unknown', reason };
9
+ }
10
+ export function buildExactContainerListArgs(id) {
11
+ if (!FULL_CONTAINER_ID.test(id))
12
+ throw new Error('SANDBOX_CONTAINER_ID_NOT_FULL');
13
+ return ['container', 'ls', '--all', '--no-trunc', '--filter', `id=${id}`, '--format', '{{.ID}}'];
14
+ }
15
+ function buildExactContainerInspectArgs(id) {
16
+ return ['container', 'inspect', '--format', '{{json .}}', id];
17
+ }
18
+ function runDockerProbe(engine, args, options) {
19
+ const command = options.authority
20
+ ? commandForSandboxAuthority(options.authority, 'docker', args)
21
+ : commandForEngine(engine, 'docker', args);
22
+ return (options.probe ?? runProbe)(command.cmd, command.args, options.timeoutMs === undefined ? {} : { timeout: options.timeoutMs });
23
+ }
24
+ function parseExactList(stdout, expectedId) {
25
+ const rows = stdout.split(/\r?\n/u).map((row) => row.trim()).filter(Boolean);
26
+ if (rows.length === 0)
27
+ return 'empty';
28
+ if (rows.length !== 1)
29
+ return 'exact container query returned multiple rows';
30
+ if (!FULL_CONTAINER_ID.test(rows[0]))
31
+ return 'exact container query returned a malformed ID';
32
+ if (rows[0] !== expectedId)
33
+ return 'conflict';
34
+ return 'present';
35
+ }
36
+ function parseExactInspect(stdout, expectedId) {
37
+ let value;
38
+ try {
39
+ value = JSON.parse(stdout);
40
+ }
41
+ catch {
42
+ return unknown('exact container inspection returned malformed JSON');
43
+ }
44
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
45
+ return unknown('exact container inspection returned an incomplete object');
46
+ }
47
+ const inspected = value;
48
+ if (inspected.Id !== expectedId || typeof inspected.State?.Running !== 'boolean'
49
+ || !inspected.Config?.Labels || typeof inspected.Config.Labels !== 'object'
50
+ || Array.isArray(inspected.Config.Labels)) {
51
+ return unknown('exact container inspection identity is incomplete');
52
+ }
53
+ const rawLabels = inspected.Config.Labels;
54
+ if (Object.values(rawLabels).some((value) => typeof value !== 'string')) {
55
+ return unknown('exact container inspection labels are malformed');
56
+ }
57
+ return {
58
+ state: 'found',
59
+ id: expectedId,
60
+ running: inspected.State.Running,
61
+ labels: { ...rawLabels },
62
+ evidence: 'exact-present'
63
+ };
64
+ }
65
+ export function discoverExactContainer(engine, id, options = {}) {
66
+ if (!FULL_CONTAINER_ID.test(id))
67
+ return unknown('container identity is not a full 64-character ID');
68
+ let listed;
69
+ try {
70
+ listed = runDockerProbe(engine, buildExactContainerListArgs(id), options);
71
+ }
72
+ catch {
73
+ return unknown('exact container query failed before producing a result');
74
+ }
75
+ if (listed.status !== 0) {
76
+ return unknown(`exact container query exited with ${listed.status ?? 'unknown status'}`);
77
+ }
78
+ const listState = parseExactList(outputText(listed.stdout), id);
79
+ if (listState === 'empty')
80
+ return { state: 'absent', id, evidence: 'exact-empty' };
81
+ if (listState === 'conflict')
82
+ return { state: 'conflict', reason: 'exact container query returned a different ID' };
83
+ if (listState !== 'present')
84
+ return unknown(listState);
85
+ let inspected;
86
+ try {
87
+ inspected = runDockerProbe(engine, buildExactContainerInspectArgs(id), options);
88
+ }
89
+ catch {
90
+ return unknown('exact container inspection failed before producing a result');
91
+ }
92
+ if (inspected.status !== 0) {
93
+ return unknown(`exact container inspection exited with ${inspected.status ?? 'unknown status'}`);
94
+ }
95
+ return parseExactInspect(outputText(inspected.stdout).trim(), id);
96
+ }
97
+ //# sourceMappingURL=docker-exact-discovery.js.map
@@ -1,3 +1,4 @@
1
+ import { PUBLIC_CLI_ROUTE_SELECTORS } from '../internal/cli-route-inventory.js';
1
2
  const USAGE = `Usage: ai sandbox <command> [options]
2
3
 
3
4
  Commands:
@@ -18,14 +19,15 @@ Commands:
18
19
  rm <branch | TASK-id> | --unbound | --purge
19
20
  Remove one sandbox; use a full TASK-id for task-bound
20
21
  cleanup and a branch for branch-only cleanup. --unbound
21
- removes completed task-bound and branch-only sandboxes;
22
- active, blocked, and archive tasks are protected.
22
+ removes completed task-bound and branch-only sandboxes
23
+ plus verified auxiliary state; active, blocked, and archive tasks are protected.
23
24
  start [--recreate] <branch | TASK-id | N>
24
25
  Verify or recover an existing sandbox container;
25
26
  optionally replace only the container on failure
26
27
  vm status|start|stop Manage the sandbox VM (macOS) or check the backend (Windows)
27
28
 
28
29
  Run 'ai sandbox <command> --help' for details.`;
30
+ const SANDBOX_OPERATIONS = PUBLIC_CLI_ROUTE_SELECTORS.sandbox;
29
31
  export async function runSandbox(args) {
30
32
  const [subcommand, ...rest] = args;
31
33
  if (!subcommand) {
@@ -37,6 +39,9 @@ export async function runSandbox(args) {
37
39
  process.stdout.write(`${USAGE}\n`);
38
40
  return;
39
41
  }
42
+ if (!SANDBOX_OPERATIONS.includes(subcommand)) {
43
+ throw new Error(`Unknown sandbox command: ${subcommand}`);
44
+ }
40
45
  switch (subcommand) {
41
46
  case 'create': {
42
47
  const { create } = await import('./commands/create.js');
@@ -1,3 +1,4 @@
1
+ import { prepareCompletedReentry, publishCompletedReentry, waitForCompletedReentry } from './control/completed-reentry.js';
1
2
  import fs from 'node:fs';
2
3
  import path from 'node:path';
3
4
  import { spawn } from 'node:child_process';
@@ -17,7 +18,9 @@ import { declaredTmpfsSeedEntries, resolveTools, toolConfigDirCandidates } from
17
18
  import { fetchSandboxRows, selectSandboxContainer, startSandboxContainer } from './commands/list-running.js';
18
19
  import { getProcessIdentityState, getProcessStartTime, removePidFileIfMatches } from '../server/process-state.js';
19
20
  import { acquireSandboxControlBrokerStartup, garbageCollectSandboxControlRoot, isSandboxControlRootQuiescing, readSandboxControlManifest } from './control/lifecycle.js';
20
- import { appendSandboxControlAudit, readSandboxControlStatus } from './control/state.js';
21
+ import { readSandboxControlStatus } from './control/state.js';
22
+ import { validateSandboxControlIdentity } from './control/identity-sentinel.js';
23
+ import { appendDiagnosticAudit as appendControlDiagnosticAudit } from './control/audit.js';
21
24
  import { inspectSandboxControlContainer } from './control/container-identity.js';
22
25
  import { SANDBOX_CONTROL_FUTURE_SKEW_MS, SANDBOX_CONTROL_STATUS_STALE_MS } from './control/protocol.js';
23
26
  export function worktreeProbeForEngine(engine, probe = runProbe) {
@@ -60,6 +63,17 @@ export async function startSandboxControlBroker(repoRoot, manifestPath) {
60
63
  const internalCli = path.resolve(directory, '..', '..', 'bin', `internal-cli${extension}`);
61
64
  const manifest = readSandboxControlManifest(manifestPath);
62
65
  const root = path.dirname(manifestPath);
66
+ const identity = validateSandboxControlIdentity({
67
+ publicStatusDir: manifest.publicStatusDir,
68
+ root,
69
+ mode: manifest.mode,
70
+ taskId: manifest.taskId,
71
+ generation: manifest.generation,
72
+ controlRootId: manifest.controlRootId
73
+ });
74
+ if (identity.state !== 'valid') {
75
+ throw new Error(`SANDBOX_CONTROL_IDENTITY_${identity.state.replaceAll('-', '_').toUpperCase()}`);
76
+ }
63
77
  if (isSandboxControlRootQuiescing(root))
64
78
  throw new Error('SANDBOX_CONTROL_QUIESCING');
65
79
  const brokerPath = path.join(root, 'broker.json');
@@ -129,8 +143,8 @@ export async function startSandboxControlBroker(repoRoot, manifestPath) {
129
143
  }
130
144
  }
131
145
  if (replacedBrokerRecord) {
132
- appendSandboxControlAudit(manifest, 'broker-observed-crash');
133
- appendSandboxControlAudit(manifest, 'broker-restart');
146
+ appendControlDiagnosticAudit(manifest, 'broker-observed-crash');
147
+ appendControlDiagnosticAudit(manifest, 'broker-restart');
134
148
  }
135
149
  child = spawn(process.execPath, nodeEntryArgs(internalCli, ['sandbox-control', 'serve', '--manifest', manifestPath]), { cwd: repoRoot, detached: true, stdio: 'ignore' });
136
150
  }
@@ -167,6 +181,17 @@ async function ensureSandboxControlBroker(params) {
167
181
  if (!fs.existsSync(control.manifestPath))
168
182
  return;
169
183
  const validatedManifest = readSandboxControlManifest(control.manifestPath);
184
+ const identity = validateSandboxControlIdentity({
185
+ publicStatusDir: validatedManifest.publicStatusDir,
186
+ root: control.root,
187
+ mode: validatedManifest.mode,
188
+ taskId: validatedManifest.taskId,
189
+ generation: validatedManifest.generation,
190
+ controlRootId: validatedManifest.controlRootId
191
+ });
192
+ if (identity.state !== 'valid') {
193
+ throw new Error(`SANDBOX_CONTROL_IDENTITY_${identity.state.replaceAll('-', '_').toUpperCase()}`);
194
+ }
170
195
  const containerObservation = await inspectSandboxControlContainer(validatedManifest);
171
196
  if (containerObservation.state === 'unknown') {
172
197
  throw new Error(`SANDBOX_CONTROL_CONTAINER_UNKNOWN: ${containerObservation.reason}`);
@@ -441,7 +466,7 @@ function recoveryTaskSources(repoRoot, taskId) {
441
466
  }
442
467
  return { mountPaths, accessiblePaths: [completedSource] };
443
468
  }
444
- function startCompletedSandboxContainer(params) {
469
+ export function startCompletedSandboxContainer(params) {
445
470
  const taskSources = recoveryTaskSources(params.config.repoRoot, params.taskId);
446
471
  const completedSource = taskSources.accessiblePaths[0];
447
472
  const activeRoot = path.join(params.config.repoRoot, '.agents', 'workspace', 'active');
@@ -513,7 +538,7 @@ function expectedMounts(params) {
513
538
  ? {}
514
539
  : {
515
540
  runtimeDir: control.runtimeDir,
516
- taskSources: taskSources.mountPaths,
541
+ taskSources: taskSources.accessiblePaths,
517
542
  taskId: taskId
518
543
  })
519
544
  }).map((mount) => ({
@@ -879,7 +904,17 @@ export async function ensureSandboxReady(params) {
879
904
  throw new Error('Explicit container recreation requested.');
880
905
  }
881
906
  if (!params.row.running) {
907
+ let completedReentry = null;
882
908
  if (params.reentry === 'completed' && params.workspace?.mode === 'task-bound') {
909
+ const control = sandboxControlPaths({
910
+ base: params.config.controlBase, project: params.config.project,
911
+ container: params.row.name, identity: params.workspace
912
+ });
913
+ const manifest = readSandboxControlManifest(control.manifestPath);
914
+ if (manifest.taskId !== params.workspace.taskId || manifest.branch !== params.branch) {
915
+ throw new Error('SANDBOX_COMPLETED_REENTRY_EVIDENCE_INVALID');
916
+ }
917
+ completedReentry = { manifest, evidence: await prepareCompletedReentry(manifest) };
883
918
  startCompletedSandboxContainer({
884
919
  config: params.config,
885
920
  engine: params.engine,
@@ -943,6 +978,15 @@ export async function ensureSandboxReady(params) {
943
978
  if (final.findings.length > 0) {
944
979
  throw new Error(describeFindings(final.findings));
945
980
  }
981
+ if (completedReentry) {
982
+ const { manifest, evidence } = completedReentry;
983
+ const current = await prepareCompletedReentry(manifest);
984
+ if (JSON.stringify(current) !== JSON.stringify(evidence)) {
985
+ throw new Error('SANDBOX_COMPLETED_REENTRY_EVIDENCE_INVALID');
986
+ }
987
+ publishCompletedReentry(manifest, evidence);
988
+ await waitForCompletedReentry(manifest, evidence);
989
+ }
946
990
  return { container: params.row.name, path: 'recovered', warnings };
947
991
  }
948
992
  const initial = assess({