@wardby/cli 0.5.3 → 0.7.0

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 (763) hide show
  1. package/.env.example +33 -0
  2. package/README.md +25 -14
  3. package/deploy/local/docker-compose.quickstart-coding.yml +13 -0
  4. package/dist/claude-coding-worker/context.d.ts +22 -0
  5. package/dist/claude-coding-worker/context.js +92 -0
  6. package/dist/claude-coding-worker/driver.d.ts +27 -3
  7. package/dist/claude-coding-worker/driver.js +161 -20
  8. package/dist/claude-coding-worker/main.js +34 -6
  9. package/dist/claude-coding-worker/sdk.js +25 -5
  10. package/dist/claude-coding-worker/tool-socket.d.ts +27 -0
  11. package/dist/claude-coding-worker/tool-socket.js +111 -0
  12. package/dist/claude-coding-worker/transcript.d.ts +18 -0
  13. package/dist/claude-coding-worker/transcript.js +77 -0
  14. package/dist/cli-help.d.ts +1 -1
  15. package/dist/cli-help.js +6 -2
  16. package/dist/cli-native-mode.d.ts +9 -0
  17. package/dist/cli-native-mode.js +20 -0
  18. package/dist/cli.d.ts +3 -1
  19. package/dist/cli.js +161 -11
  20. package/dist/coding/claude-context.d.ts +45 -0
  21. package/dist/coding/claude-context.js +434 -0
  22. package/dist/coding/continuation-wording.d.ts +35 -0
  23. package/dist/coding/continuation-wording.js +73 -0
  24. package/dist/coding/linked-issue-note.d.ts +23 -0
  25. package/dist/coding/linked-issue-note.js +47 -0
  26. package/dist/coding/merge-wording.d.ts +28 -0
  27. package/dist/coding/merge-wording.js +78 -0
  28. package/dist/coding/pr-description-note.d.ts +9 -0
  29. package/dist/coding/pr-description-note.js +32 -0
  30. package/dist/coding/profile.d.ts +50 -118
  31. package/dist/coding/profile.js +51 -4
  32. package/dist/coding/protected-path-wording.d.ts +8 -0
  33. package/dist/coding/protected-path-wording.js +1 -1
  34. package/dist/coding/protocol.d.ts +292 -270
  35. package/dist/coding/protocol.js +322 -15
  36. package/dist/coding/redact.d.ts +3 -0
  37. package/dist/coding/redact.js +12 -0
  38. package/dist/coding/registry/allowlist.d.ts +12 -0
  39. package/dist/coding/registry/allowlist.js +14 -1
  40. package/dist/coding/registry/audit-mode.d.ts +153 -0
  41. package/dist/coding/registry/audit-mode.js +304 -0
  42. package/dist/coding/registry/lockfile-shared.d.ts +36 -0
  43. package/dist/coding/registry/lockfile-shared.js +128 -0
  44. package/dist/coding/registry/lockfiles.js +1 -1
  45. package/dist/coding/registry/npm-lockfile-formats.d.ts +11 -0
  46. package/dist/coding/registry/npm-lockfile-formats.js +41 -0
  47. package/dist/coding/registry/npm-lockfile.d.ts +8 -4
  48. package/dist/coding/registry/npm-lockfile.js +4 -6
  49. package/dist/coding/registry/npm.js +78 -8
  50. package/dist/coding/registry/pnpm-lockfile.d.ts +17 -0
  51. package/dist/coding/registry/pnpm-lockfile.js +189 -0
  52. package/dist/coding/registry/pypi-plan.d.ts +50 -0
  53. package/dist/coding/registry/pypi-plan.js +406 -0
  54. package/dist/coding/registry/pypi-requirements.d.ts +58 -0
  55. package/dist/coding/registry/pypi-requirements.js +155 -0
  56. package/dist/coding/registry/pypi.d.ts +3 -27
  57. package/dist/coding/registry/pypi.js +40 -154
  58. package/dist/coding/registry/refusal-hints.d.ts +20 -0
  59. package/dist/coding/registry/refusal-hints.js +61 -0
  60. package/dist/coding/registry/refusal-wording.d.ts +11 -0
  61. package/dist/coding/registry/refusal-wording.js +56 -0
  62. package/dist/coding/registry/report.d.ts +70 -8
  63. package/dist/coding/registry/report.js +112 -5
  64. package/dist/coding/registry/types.d.ts +58 -8
  65. package/dist/coding/registry/yarn-lockfile.d.ts +30 -0
  66. package/dist/coding/registry/yarn-lockfile.js +367 -0
  67. package/dist/coding/services/catalog.d.ts +37 -351
  68. package/dist/coding/transcript/claude-code.d.ts +13 -0
  69. package/dist/coding/transcript/claude-code.js +273 -0
  70. package/dist/coding/transcript/download-protocol.d.ts +30 -0
  71. package/dist/coding/transcript/download-protocol.js +18 -0
  72. package/dist/coding/transcript/format.d.ts +20 -0
  73. package/dist/coding/transcript/format.js +32 -0
  74. package/dist/coding/transcript/recorder.d.ts +51 -0
  75. package/dist/coding/transcript/recorder.js +225 -0
  76. package/dist/coding/transcript/resume/checkout.d.ts +31 -0
  77. package/dist/coding/transcript/resume/checkout.js +203 -0
  78. package/dist/coding/transcript/resume/command.d.ts +17 -0
  79. package/dist/coding/transcript/resume/command.js +176 -0
  80. package/dist/coding/transcript/resume/download.d.ts +20 -0
  81. package/dist/coding/transcript/resume/download.js +153 -0
  82. package/dist/coding/transcript/resume/launch.d.ts +38 -0
  83. package/dist/coding/transcript/resume/launch.js +128 -0
  84. package/dist/coding/transcript/resume/session-file.d.ts +13 -0
  85. package/dist/coding/transcript/resume/session-file.js +79 -0
  86. package/dist/coding/transcript/resume/stand-in.d.ts +11 -0
  87. package/dist/coding/transcript/resume/stand-in.js +49 -0
  88. package/dist/coding-worker/artifact.d.ts +16 -3
  89. package/dist/coding-worker/artifact.js +5 -3
  90. package/dist/coding-worker/debug-trace.d.ts +6 -5
  91. package/dist/coding-worker/debug-trace.js +13 -18
  92. package/dist/coding-worker/dependency-cache.d.mts +229 -0
  93. package/dist/coding-worker/dependency-cache.mjs +2123 -0
  94. package/dist/coding-worker/driver.d.ts +4 -3
  95. package/dist/coding-worker/driver.js +118 -38
  96. package/dist/coding-worker/errors.d.ts +1 -0
  97. package/dist/coding-worker/errors.js +32 -0
  98. package/dist/coding-worker/sdk.d.ts +6 -0
  99. package/dist/coding-worker/sdk.js +1 -0
  100. package/dist/coding-worker/skills.d.ts +23 -0
  101. package/dist/coding-worker/skills.js +117 -0
  102. package/dist/coding-worker/task-note.d.ts +11 -0
  103. package/dist/coding-worker/task-note.js +13 -0
  104. package/dist/coding-worker/types.d.ts +13 -0
  105. package/dist/config/dependency-cache.d.ts +23 -0
  106. package/dist/config/dependency-cache.js +32 -0
  107. package/dist/config/github-allowed-accounts.d.ts +15 -0
  108. package/dist/config/github-allowed-accounts.js +36 -0
  109. package/dist/config/low-power.d.ts +12 -0
  110. package/dist/config/low-power.js +18 -0
  111. package/dist/config/mobile.d.ts +12 -0
  112. package/dist/config/mobile.js +18 -0
  113. package/dist/config/providers.d.ts +65 -3
  114. package/dist/config/providers.js +147 -11
  115. package/dist/config/test-simulators.d.ts +82 -0
  116. package/dist/config/test-simulators.js +305 -0
  117. package/dist/core/async-context.d.ts +2 -0
  118. package/dist/core/async-context.js +12 -0
  119. package/dist/core/budget-events.d.ts +108 -0
  120. package/dist/core/budget-events.js +346 -0
  121. package/dist/core/budget-groups.d.ts +50 -1
  122. package/dist/core/budget-groups.js +236 -27
  123. package/dist/core/budget-stopped-head.d.ts +46 -0
  124. package/dist/core/budget-stopped-head.js +81 -0
  125. package/dist/core/budget-topup.d.ts +51 -0
  126. package/dist/core/budget-topup.js +156 -0
  127. package/dist/core/budget-wording.d.ts +16 -2
  128. package/dist/core/budget-wording.js +40 -2
  129. package/dist/core/coding-queue.d.ts +2 -1
  130. package/dist/core/coding-queue.js +7 -0
  131. package/dist/core/cron.d.ts +19 -1
  132. package/dist/core/cron.js +17 -0
  133. package/dist/core/datastores.js +1 -1
  134. package/dist/core/db.d.ts +16 -6
  135. package/dist/core/db.js +12 -10
  136. package/dist/core/deferred-coding.d.ts +14 -0
  137. package/dist/core/deferred-coding.js +62 -0
  138. package/dist/core/delegation-child.d.ts +25 -0
  139. package/dist/core/delegation-child.js +37 -0
  140. package/dist/core/dispatch.d.ts +53 -0
  141. package/dist/core/dispatch.js +167 -57
  142. package/dist/core/engine-native.js +10 -6
  143. package/dist/core/error-code.d.ts +38 -0
  144. package/dist/core/error-code.js +168 -0
  145. package/dist/core/grants.d.ts +19 -6
  146. package/dist/core/grants.js +55 -6
  147. package/dist/core/host-events.d.ts +67 -5
  148. package/dist/core/host-events.js +571 -37
  149. package/dist/core/host-status.d.ts +85 -3
  150. package/dist/core/host-status.js +298 -20
  151. package/dist/core/issue-bridge.d.ts +50 -6
  152. package/dist/core/issue-bridge.js +151 -20
  153. package/dist/core/issue-events.d.ts +1 -1
  154. package/dist/core/issue-events.js +16 -11
  155. package/dist/core/issue-status.d.ts +1 -1
  156. package/dist/core/issue-status.js +68 -29
  157. package/dist/core/logger.d.ts +5 -0
  158. package/dist/core/logger.js +14 -1
  159. package/dist/core/lost-run-children.d.ts +6 -0
  160. package/dist/core/lost-run-children.js +32 -0
  161. package/dist/core/mark-ready.d.ts +34 -0
  162. package/dist/core/mark-ready.js +152 -0
  163. package/dist/core/markdown-code.d.ts +8 -0
  164. package/dist/core/markdown-code.js +107 -0
  165. package/dist/core/memory-tools.js +7 -0
  166. package/dist/core/merge-order-check.d.ts +130 -0
  167. package/dist/core/merge-order-check.js +343 -0
  168. package/dist/core/notification-dispatcher.d.ts +70 -0
  169. package/dist/core/notification-dispatcher.js +368 -0
  170. package/dist/core/notification-templates.d.ts +19 -0
  171. package/dist/core/notification-templates.js +139 -0
  172. package/dist/core/notifications.d.ts +10 -0
  173. package/dist/core/notifications.js +38 -0
  174. package/dist/core/pg-auth.d.ts +22 -0
  175. package/dist/core/pg-auth.js +152 -0
  176. package/dist/core/power-composition.d.ts +16 -0
  177. package/dist/core/power-composition.js +37 -0
  178. package/dist/core/power-idle.d.ts +14 -0
  179. package/dist/core/power-idle.js +30 -0
  180. package/dist/core/power.d.ts +71 -0
  181. package/dist/core/power.js +202 -0
  182. package/dist/core/pull-request-state-sync.js +2 -2
  183. package/dist/core/reconciler.d.ts +8 -5
  184. package/dist/core/reconciler.js +37 -6
  185. package/dist/core/related-pull-requests.d.ts +59 -7
  186. package/dist/core/related-pull-requests.js +140 -25
  187. package/dist/core/reply-parts.d.ts +21 -0
  188. package/dist/core/reply-parts.js +73 -0
  189. package/dist/core/repo-access.d.ts +15 -0
  190. package/dist/core/repo-access.js +66 -0
  191. package/dist/core/review-fix.d.ts +38 -1
  192. package/dist/core/review-fix.js +209 -7
  193. package/dist/core/review-host-checks.d.ts +1 -1
  194. package/dist/core/review-host-tools.d.ts +23 -0
  195. package/dist/core/review-host-tools.js +156 -14
  196. package/dist/core/review-reads.d.ts +55 -0
  197. package/dist/core/review-reads.js +233 -0
  198. package/dist/core/run-status.d.ts +12 -0
  199. package/dist/core/run-status.js +12 -0
  200. package/dist/core/runner.d.ts +384 -5
  201. package/dist/core/runner.js +1244 -372
  202. package/dist/core/schedule-start.d.ts +12 -0
  203. package/dist/core/schedule-start.js +14 -0
  204. package/dist/core/secret-broker-config.d.ts +39 -0
  205. package/dist/core/secret-broker-config.js +112 -0
  206. package/dist/core/secret-guard.d.ts +46 -0
  207. package/dist/core/secret-guard.js +104 -0
  208. package/dist/core/secret-guarded-stores.d.ts +12 -0
  209. package/dist/core/secret-guarded-stores.js +41 -0
  210. package/dist/core/secret-spans.d.ts +50 -0
  211. package/dist/core/secret-spans.js +94 -0
  212. package/dist/core/secrets.d.ts +39 -4
  213. package/dist/core/secrets.js +148 -40
  214. package/dist/core/stop-run.d.ts +46 -0
  215. package/dist/core/stop-run.js +61 -0
  216. package/dist/core/workflow-event-recorder.d.ts +14 -0
  217. package/dist/core/workflow-event-recorder.js +120 -0
  218. package/dist/core/workflow-events.d.ts +94 -0
  219. package/dist/core/workflow-events.js +48 -0
  220. package/dist/core/workflow-run-events.d.ts +18 -0
  221. package/dist/core/workflow-run-events.js +75 -0
  222. package/dist/core/zod-json-schema.d.ts +4 -0
  223. package/dist/core/zod-json-schema.js +39 -0
  224. package/dist/core/zod3-window.d.ts +35 -0
  225. package/dist/core/zod3-window.js +124 -0
  226. package/dist/generated/prisma/browser.d.ts +92 -3
  227. package/dist/generated/prisma/client.d.ts +92 -3
  228. package/dist/generated/prisma/commonInputTypes.d.ts +364 -54
  229. package/dist/generated/prisma/enums.d.ts +37 -0
  230. package/dist/generated/prisma/enums.js +31 -0
  231. package/dist/generated/prisma/internal/class.d.ts +132 -0
  232. package/dist/generated/prisma/internal/class.js +4 -4
  233. package/dist/generated/prisma/internal/prismaNamespace.d.ts +1332 -142
  234. package/dist/generated/prisma/internal/prismaNamespace.js +227 -5
  235. package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +234 -0
  236. package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +227 -5
  237. package/dist/generated/prisma/models/Agent.d.ts +464 -7
  238. package/dist/generated/prisma/models/AgentRepository.d.ts +42 -1
  239. package/dist/generated/prisma/models/CodingAgentProfile.d.ts +301 -1
  240. package/dist/generated/prisma/models/CodingProxyRequest.d.ts +207 -3
  241. package/dist/generated/prisma/models/CodingProxySession.d.ts +114 -1
  242. package/dist/generated/prisma/models/CodingRun.d.ts +1841 -1
  243. package/dist/generated/prisma/models/DeferredReview.d.ts +78 -1
  244. package/dist/generated/prisma/models/DependencySnapshot.d.ts +1668 -0
  245. package/dist/generated/prisma/models/DependencySnapshot.js +1 -0
  246. package/dist/generated/prisma/models/IssuePullRequest.d.ts +6 -2
  247. package/dist/generated/prisma/models/LocalReview.d.ts +40 -1
  248. package/dist/generated/prisma/models/NativeGatewayCall.d.ts +1713 -0
  249. package/dist/generated/prisma/models/NativeGatewayCall.js +1 -0
  250. package/dist/generated/prisma/models/NativeGatewaySession.d.ts +1551 -0
  251. package/dist/generated/prisma/models/NativeGatewaySession.js +1 -0
  252. package/dist/generated/prisma/models/NativeWarmWorker.d.ts +1296 -0
  253. package/dist/generated/prisma/models/NativeWarmWorker.js +1 -0
  254. package/dist/generated/prisma/models/NotificationChannel.d.ts +1543 -0
  255. package/dist/generated/prisma/models/NotificationChannel.js +1 -0
  256. package/dist/generated/prisma/models/NotificationDelivery.d.ts +1502 -0
  257. package/dist/generated/prisma/models/NotificationDelivery.js +1 -0
  258. package/dist/generated/prisma/models/NotificationThread.d.ts +1090 -0
  259. package/dist/generated/prisma/models/NotificationThread.js +1 -0
  260. package/dist/generated/prisma/models/RegistryAllowance.d.ts +41 -1
  261. package/dist/generated/prisma/models/RegistryApprovedVersion.d.ts +75 -1
  262. package/dist/generated/prisma/models/RegistryAuditRecord.d.ts +1364 -0
  263. package/dist/generated/prisma/models/RegistryAuditRecord.js +1 -0
  264. package/dist/generated/prisma/models/Run.d.ts +1619 -58
  265. package/dist/generated/prisma/models/RunBudgetEvent.d.ts +1211 -0
  266. package/dist/generated/prisma/models/RunBudgetEvent.js +1 -0
  267. package/dist/generated/prisma/models/RunHostCheck.d.ts +36 -1
  268. package/dist/generated/prisma/models/RunTranscript.d.ts +1339 -0
  269. package/dist/generated/prisma/models/RunTranscript.js +1 -0
  270. package/dist/generated/prisma/models/Secret.d.ts +37 -1
  271. package/dist/generated/prisma/models/SecretBrokerChange.d.ts +1101 -0
  272. package/dist/generated/prisma/models/SecretBrokerChange.js +1 -0
  273. package/dist/generated/prisma/models/WorkflowEvent.d.ts +1422 -0
  274. package/dist/generated/prisma/models/WorkflowEvent.js +1 -0
  275. package/dist/generated/prisma/models.d.ts +12 -0
  276. package/dist/help/build.js +4 -2
  277. package/dist/help/catalog.d.ts +1 -1
  278. package/dist/help/catalog.js +31 -6
  279. package/dist/help-index.json +2584 -146
  280. package/dist/import/create.js +49 -3
  281. package/dist/import/neutral-schema.d.ts +50 -277
  282. package/dist/import/neutral-schema.js +7 -4
  283. package/dist/knowledge/check.d.ts +1 -1
  284. package/dist/knowledge/cli.d.ts +11 -1
  285. package/dist/knowledge/cli.js +37 -4
  286. package/dist/knowledge/concept.d.ts +3 -19
  287. package/dist/knowledge/location.d.ts +31 -0
  288. package/dist/knowledge/location.js +78 -0
  289. package/dist/mcp/auth/access.d.ts +11 -2
  290. package/dist/mcp/auth/access.js +15 -1
  291. package/dist/mcp/auth/ownership.d.ts +7 -7
  292. package/dist/mcp/auth/repo-authorization.js +14 -0
  293. package/dist/mcp/auth/resource-server.d.ts +2 -1
  294. package/dist/mcp/auth/resource-server.js +7 -2
  295. package/dist/mcp/auth/self-hosted/browser.d.ts +1 -1
  296. package/dist/mcp/auth/self-hosted/browser.js +19 -6
  297. package/dist/mcp/auth/self-hosted/credentials.d.ts +3 -3
  298. package/dist/mcp/auth/self-hosted/session.d.ts +2 -2
  299. package/dist/mcp/context.d.ts +6 -0
  300. package/dist/mcp/host-events/github-ingress.d.ts +25 -1
  301. package/dist/mcp/host-events/github-ingress.js +70 -1
  302. package/dist/mcp/index.d.ts +19 -0
  303. package/dist/mcp/index.js +117 -20
  304. package/dist/mcp/server.d.ts +13 -0
  305. package/dist/mcp/server.js +33 -14
  306. package/dist/mcp/tools/agents.d.ts +4 -0
  307. package/dist/mcp/tools/agents.js +277 -24
  308. package/dist/mcp/tools/datastore.js +17 -8
  309. package/dist/mcp/tools/grants.js +9 -3
  310. package/dist/mcp/tools/memory.js +11 -1
  311. package/dist/mcp/tools/notification-channels.d.ts +2 -0
  312. package/dist/mcp/tools/notification-channels.js +293 -0
  313. package/dist/mcp/tools/packages.d.ts +2 -0
  314. package/dist/mcp/tools/packages.js +195 -0
  315. package/dist/mcp/tools/power.d.ts +2 -0
  316. package/dist/mcp/tools/power.js +77 -0
  317. package/dist/mcp/tools/repositories.js +18 -5
  318. package/dist/mcp/tools/run-access.d.ts +16 -0
  319. package/dist/mcp/tools/run-access.js +25 -0
  320. package/dist/mcp/tools/run-transcript-download.d.ts +30 -0
  321. package/dist/mcp/tools/run-transcript-download.js +129 -0
  322. package/dist/mcp/tools/run-transcript.d.ts +19 -0
  323. package/dist/mcp/tools/run-transcript.js +70 -0
  324. package/dist/mcp/tools/runs.d.ts +0 -6
  325. package/dist/mcp/tools/runs.js +41 -14
  326. package/dist/mcp/tools/scheduling.js +3 -1
  327. package/dist/mcp/tools/secret-broker-compat.d.ts +12 -0
  328. package/dist/mcp/tools/secret-broker-compat.js +23 -0
  329. package/dist/mcp/tools/secret-elicitation-form.d.ts +22 -2
  330. package/dist/mcp/tools/secret-elicitation-form.js +205 -10
  331. package/dist/mcp/tools/secret-elicitation-server.d.ts +6 -0
  332. package/dist/mcp/tools/secret-elicitation-server.js +10 -54
  333. package/dist/mcp/tools/secret-elicitation.d.ts +38 -3
  334. package/dist/mcp/tools/secret-elicitation.js +110 -12
  335. package/dist/mcp/tools/secrets.js +186 -9
  336. package/dist/mcp/tools/stop-run.d.ts +2 -0
  337. package/dist/mcp/tools/stop-run.js +82 -0
  338. package/dist/mcp/tools/subagents.js +2 -2
  339. package/dist/mcp/tools/tools.d.ts +2 -2
  340. package/dist/mcp/tools/tools.js +47 -11
  341. package/dist/mcp/transport/stdio-link-host.d.ts +20 -0
  342. package/dist/mcp/transport/stdio-link-host.js +67 -0
  343. package/dist/mcp/transport/streamable-http.d.ts +13 -0
  344. package/dist/mcp/transport/streamable-http.js +41 -1
  345. package/dist/native-worker/composition.d.ts +23 -0
  346. package/dist/native-worker/composition.js +77 -0
  347. package/dist/native-worker/docker-isolation.d.ts +65 -0
  348. package/dist/native-worker/docker-isolation.js +183 -0
  349. package/dist/native-worker/docker-launcher.d.ts +110 -0
  350. package/dist/native-worker/docker-launcher.js +297 -0
  351. package/dist/native-worker/gateway-server.d.ts +77 -0
  352. package/dist/native-worker/gateway-server.js +412 -0
  353. package/dist/native-worker/gateway.d.ts +70 -0
  354. package/dist/native-worker/gateway.js +263 -0
  355. package/dist/native-worker/http-server.d.ts +24 -0
  356. package/dist/native-worker/http-server.js +113 -0
  357. package/dist/native-worker/http-transport.d.ts +17 -0
  358. package/dist/native-worker/http-transport.js +88 -0
  359. package/dist/native-worker/kubernetes-isolation.d.ts +90 -0
  360. package/dist/native-worker/kubernetes-isolation.js +218 -0
  361. package/dist/native-worker/kubernetes-launcher.d.ts +106 -0
  362. package/dist/native-worker/kubernetes-launcher.js +375 -0
  363. package/dist/native-worker/launch.d.ts +62 -0
  364. package/dist/native-worker/launch.js +49 -0
  365. package/dist/native-worker/ledger.d.ts +125 -0
  366. package/dist/native-worker/ledger.js +245 -0
  367. package/dist/native-worker/loopback.d.ts +12 -0
  368. package/dist/native-worker/loopback.js +44 -0
  369. package/dist/native-worker/main.d.ts +8 -0
  370. package/dist/native-worker/main.js +85 -0
  371. package/dist/native-worker/protocol.d.ts +296 -0
  372. package/dist/native-worker/protocol.js +246 -0
  373. package/dist/native-worker/sandbox-executor.d.ts +83 -0
  374. package/dist/native-worker/sandbox-executor.js +284 -0
  375. package/dist/native-worker/stderr-redaction.d.ts +77 -0
  376. package/dist/native-worker/stderr-redaction.js +237 -0
  377. package/dist/native-worker/stdio.d.ts +29 -0
  378. package/dist/native-worker/stdio.js +189 -0
  379. package/dist/native-worker/warm-delivery.d.ts +16 -0
  380. package/dist/native-worker/warm-delivery.js +33 -0
  381. package/dist/native-worker/warm-pool-ledger.d.ts +39 -0
  382. package/dist/native-worker/warm-pool-ledger.js +73 -0
  383. package/dist/native-worker/warm-pool.d.ts +107 -0
  384. package/dist/native-worker/warm-pool.js +283 -0
  385. package/dist/native-worker/worker.d.ts +17 -0
  386. package/dist/native-worker/worker.js +141 -0
  387. package/dist/observability/metrics.js +6 -1
  388. package/dist/providers/auth/authorization-server.d.ts +3 -0
  389. package/dist/providers/auth/index.js +2 -0
  390. package/dist/providers/auth/self-hosted.d.ts +14 -2
  391. package/dist/providers/auth/self-hosted.js +54 -4
  392. package/dist/providers/chat/fake.d.ts +46 -0
  393. package/dist/providers/chat/fake.js +39 -0
  394. package/dist/providers/chat/index.d.ts +4 -0
  395. package/dist/providers/chat/index.js +8 -0
  396. package/dist/providers/chat/slack.d.ts +37 -0
  397. package/dist/providers/chat/slack.js +105 -0
  398. package/dist/providers/chat/types.d.ts +42 -0
  399. package/dist/providers/chat/types.js +19 -0
  400. package/dist/providers/coding-proxy/dependency-cache/eviction.d.ts +29 -0
  401. package/dist/providers/coding-proxy/dependency-cache/eviction.js +87 -0
  402. package/dist/providers/coding-proxy/dependency-cache/key.d.ts +33 -0
  403. package/dist/providers/coding-proxy/dependency-cache/key.js +86 -0
  404. package/dist/providers/coding-proxy/dependency-cache/model-request-seal.d.ts +18 -0
  405. package/dist/providers/coding-proxy/dependency-cache/model-request-seal.js +40 -0
  406. package/dist/providers/coding-proxy/dependency-cache/prisma-store.d.ts +25 -0
  407. package/dist/providers/coding-proxy/dependency-cache/prisma-store.js +131 -0
  408. package/dist/providers/coding-proxy/dependency-cache/service.d.ts +70 -0
  409. package/dist/providers/coding-proxy/dependency-cache/service.js +409 -0
  410. package/dist/providers/coding-proxy/dependency-cache/store.d.ts +85 -0
  411. package/dist/providers/coding-proxy/dependency-cache/store.js +95 -0
  412. package/dist/providers/coding-proxy/hold.d.ts +32 -0
  413. package/dist/providers/coding-proxy/hold.js +86 -0
  414. package/dist/providers/coding-proxy/interrupted.d.ts +70 -0
  415. package/dist/providers/coding-proxy/interrupted.js +104 -0
  416. package/dist/providers/coding-proxy/memory-ledger.d.ts +15 -2
  417. package/dist/providers/coding-proxy/memory-ledger.js +84 -8
  418. package/dist/providers/coding-proxy/metering.d.ts +16 -0
  419. package/dist/providers/coding-proxy/metering.js +27 -4
  420. package/dist/providers/coding-proxy/prisma-ledger.d.ts +15 -2
  421. package/dist/providers/coding-proxy/prisma-ledger.js +179 -67
  422. package/dist/providers/coding-proxy/proxy.d.ts +14 -1
  423. package/dist/providers/coding-proxy/proxy.js +166 -14
  424. package/dist/providers/coding-proxy/registry/audit.d.ts +53 -10
  425. package/dist/providers/coding-proxy/registry/audit.js +94 -17
  426. package/dist/providers/coding-proxy/registry/lockfile-parse-worker.d.ts +36 -0
  427. package/dist/providers/coding-proxy/registry/lockfile-parse-worker.js +67 -0
  428. package/dist/providers/coding-proxy/registry/lockfile-parse.d.ts +16 -0
  429. package/dist/providers/coding-proxy/registry/lockfile-parse.js +110 -0
  430. package/dist/providers/coding-proxy/registry/plan.d.ts +9 -0
  431. package/dist/providers/coding-proxy/registry/plan.js +201 -48
  432. package/dist/providers/coding-proxy/registry/prisma-store.d.ts +11 -5
  433. package/dist/providers/coding-proxy/registry/prisma-store.js +120 -17
  434. package/dist/providers/coding-proxy/registry/service.d.ts +97 -16
  435. package/dist/providers/coding-proxy/registry/service.js +579 -112
  436. package/dist/providers/coding-proxy/registry/store.d.ts +84 -9
  437. package/dist/providers/coding-proxy/registry/store.js +54 -1
  438. package/dist/providers/coding-proxy/runtime.d.ts +4 -0
  439. package/dist/providers/coding-proxy/runtime.js +78 -16
  440. package/dist/providers/coding-proxy/server.d.ts +6 -1
  441. package/dist/providers/coding-proxy/server.js +45 -1
  442. package/dist/providers/coding-proxy/types.d.ts +65 -1
  443. package/dist/providers/datastore/types.d.ts +5 -0
  444. package/dist/providers/engine/types.d.ts +36 -2
  445. package/dist/providers/engine/types.js +39 -0
  446. package/dist/providers/executor/composition.d.ts +31 -1
  447. package/dist/providers/executor/composition.js +81 -8
  448. package/dist/providers/executor/container.d.ts +385 -9
  449. package/dist/providers/executor/container.js +1234 -99
  450. package/dist/providers/executor/dbos-status.d.ts +31 -0
  451. package/dist/providers/executor/dbos-status.js +64 -0
  452. package/dist/providers/executor/dbos.d.ts +91 -0
  453. package/dist/providers/executor/dbos.js +319 -26
  454. package/dist/providers/executor/deferred.d.ts +44 -0
  455. package/dist/providers/executor/deferred.js +100 -0
  456. package/dist/providers/executor/in-process.d.ts +9 -1
  457. package/dist/providers/executor/in-process.js +14 -4
  458. package/dist/providers/executor/linked-issue-reader.d.ts +16 -0
  459. package/dist/providers/executor/linked-issue-reader.js +30 -0
  460. package/dist/providers/executor/routing.d.ts +39 -10
  461. package/dist/providers/executor/routing.js +77 -32
  462. package/dist/providers/executor/types.d.ts +25 -0
  463. package/dist/providers/index.d.ts +2 -1
  464. package/dist/providers/issue-tracker/types.d.ts +17 -0
  465. package/dist/providers/issue-tracker/types.js +39 -1
  466. package/dist/providers/jobs/claude-tool-setup.d.ts +4 -0
  467. package/dist/providers/jobs/claude-tool-setup.js +5 -2
  468. package/dist/providers/jobs/docker-isolation.d.ts +8 -0
  469. package/dist/providers/jobs/docker-isolation.js +17 -0
  470. package/dist/providers/jobs/docker.d.ts +1 -0
  471. package/dist/providers/jobs/docker.js +29 -4
  472. package/dist/providers/jobs/fake-kubernetes-api.d.ts +23 -2
  473. package/dist/providers/jobs/fake-kubernetes-api.js +45 -1
  474. package/dist/providers/jobs/kubernetes-api.d.ts +25 -1
  475. package/dist/providers/jobs/kubernetes-api.js +17 -0
  476. package/dist/providers/jobs/kubernetes-client.d.ts +10 -1
  477. package/dist/providers/jobs/kubernetes-client.js +61 -3
  478. package/dist/providers/jobs/kubernetes-dry-run-fixture.d.ts +6 -1
  479. package/dist/providers/jobs/kubernetes-dry-run-fixture.js +6 -3
  480. package/dist/providers/jobs/kubernetes-isolation.d.ts +5 -1
  481. package/dist/providers/jobs/kubernetes-isolation.js +23 -1
  482. package/dist/providers/jobs/kubernetes-platform.d.ts +4 -1
  483. package/dist/providers/jobs/kubernetes-platform.js +38 -1
  484. package/dist/providers/jobs/kubernetes-preflight.d.ts +2 -1
  485. package/dist/providers/jobs/kubernetes-preflight.js +4 -2
  486. package/dist/providers/jobs/kubernetes.d.ts +42 -2
  487. package/dist/providers/jobs/kubernetes.js +178 -19
  488. package/dist/providers/jobs/metadata-probes.d.ts +11 -0
  489. package/dist/providers/jobs/metadata-probes.js +13 -0
  490. package/dist/providers/jobs/types.d.ts +42 -0
  491. package/dist/providers/jobs/types.js +13 -1
  492. package/dist/providers/llm/anthropic.js +5 -1
  493. package/dist/providers/llm/bedrock.d.ts +0 -12
  494. package/dist/providers/llm/bedrock.js +4 -0
  495. package/dist/providers/llm/claude-messages.d.ts +3 -1
  496. package/dist/providers/llm/claude-messages.js +4 -1
  497. package/dist/providers/llm/claude-provider.d.ts +2 -2
  498. package/dist/providers/llm/claude-provider.js +2 -2
  499. package/dist/providers/llm/openai.d.ts +2 -2
  500. package/dist/providers/llm/openai.js +6 -2
  501. package/dist/providers/llm/routing.d.ts +2 -2
  502. package/dist/providers/llm/routing.js +2 -2
  503. package/dist/providers/llm/types.d.ts +12 -2
  504. package/dist/providers/review-host/github-events.d.ts +9 -1
  505. package/dist/providers/review-host/github-events.js +34 -12
  506. package/dist/providers/review-host/github.d.ts +39 -2
  507. package/dist/providers/review-host/github.js +274 -29
  508. package/dist/providers/review-host/local.d.ts +8 -4
  509. package/dist/providers/review-host/local.js +49 -31
  510. package/dist/providers/review-host/patch-pages.d.ts +41 -0
  511. package/dist/providers/review-host/patch-pages.js +176 -0
  512. package/dist/providers/review-host/review-format.d.ts +19 -1
  513. package/dist/providers/review-host/review-format.js +38 -7
  514. package/dist/providers/review-host/types.d.ts +157 -2
  515. package/dist/providers/review-host/types.js +8 -0
  516. package/dist/providers/storage/gcs.d.ts +63 -0
  517. package/dist/providers/storage/gcs.js +69 -0
  518. package/dist/providers/storage/index.d.ts +15 -0
  519. package/dist/providers/storage/index.js +14 -0
  520. package/dist/providers/storage/local.d.ts +24 -0
  521. package/dist/providers/storage/local.js +92 -0
  522. package/dist/providers/storage/meter.d.ts +14 -0
  523. package/dist/providers/storage/meter.js +34 -0
  524. package/dist/providers/storage/s3.d.ts +41 -0
  525. package/dist/providers/storage/s3.js +107 -0
  526. package/dist/providers/storage/types.d.ts +37 -3
  527. package/dist/providers/storage/types.js +21 -4
  528. package/dist/providers/vcs/git.d.ts +33 -2
  529. package/dist/providers/vcs/git.js +324 -22
  530. package/dist/providers/vcs/github-remote.d.ts +26 -3
  531. package/dist/providers/vcs/github-remote.js +124 -14
  532. package/dist/providers/vcs/github.d.ts +246 -12
  533. package/dist/providers/vcs/github.js +521 -61
  534. package/dist/providers/vcs/index.js +8 -1
  535. package/dist/providers/vcs/pr-description.d.ts +127 -0
  536. package/dist/providers/vcs/pr-description.js +270 -0
  537. package/dist/providers/vcs/remote.d.ts +33 -1
  538. package/dist/providers/vcs/routing.d.ts +4 -2
  539. package/dist/providers/vcs/routing.js +6 -0
  540. package/dist/providers/vcs/types.d.ts +80 -3
  541. package/dist/quickstart/coding-seed.d.ts +21 -3
  542. package/dist/quickstart/coding-seed.js +283 -3
  543. package/dist/quickstart/images.d.ts +2 -0
  544. package/dist/quickstart/images.js +7 -1
  545. package/dist/quickstart/reviewer-prompt.d.ts +1 -1
  546. package/dist/quickstart/reviewer-prompt.js +6 -6
  547. package/dist/quickstart-images.json +1 -1
  548. package/dist/sandbox/brokered-fetch.d.ts +23 -0
  549. package/dist/sandbox/brokered-fetch.js +37 -0
  550. package/dist/sandbox/generated/zod.bundle.js +62 -1
  551. package/dist/sandbox/generated/zod3.bundle.js +5 -0
  552. package/dist/sandbox/host-functions.d.ts +35 -0
  553. package/dist/sandbox/host-functions.js +150 -91
  554. package/dist/sandbox/prelude.js +7 -1
  555. package/dist/sandbox/run-in-sandbox.d.ts +19 -0
  556. package/dist/sandbox/run-in-sandbox.js +28 -10
  557. package/dist/sandbox/safe-fetch.d.ts +2 -0
  558. package/dist/sandbox/safe-fetch.js +3 -1
  559. package/dist/sandbox/secret-broker-sigv4.d.ts +2 -0
  560. package/dist/sandbox/secret-broker-sigv4.js +49 -0
  561. package/dist/sandbox/secret-broker.d.ts +34 -0
  562. package/dist/sandbox/secret-broker.js +161 -0
  563. package/dist/sandbox/tool-capabilities.d.ts +10 -30
  564. package/dist/sandbox/user-tool.d.ts +14 -0
  565. package/dist/sandbox/user-tool.js +32 -0
  566. package/dist/sandbox/zod-params.d.ts +37 -5
  567. package/dist/sandbox/zod-params.js +181 -26
  568. package/dist/serve.js +25 -0
  569. package/dist/viewer/api-schema.d.ts +372 -2454
  570. package/dist/viewer/api-schema.js +29 -0
  571. package/dist/viewer/build-schemas.js +10 -3
  572. package/dist/viewer/event-bus.d.ts +6 -0
  573. package/dist/viewer/event-bus.js +16 -7
  574. package/dist/viewer/graph.d.ts +5 -2
  575. package/dist/viewer/graph.js +7 -2
  576. package/dist/viewer/http.d.ts +0 -1
  577. package/dist/viewer/http.js +2 -2
  578. package/dist/viewer/infra.js +25 -2
  579. package/dist/viewer/limits.d.ts +4 -0
  580. package/dist/viewer/limits.js +4 -0
  581. package/dist/viewer/openapi.d.ts +15 -0
  582. package/dist/viewer/openapi.js +170 -0
  583. package/dist/wardby-bin.js +10 -0
  584. package/docs/README.md +7 -0
  585. package/docs/agent-recipes.md +114 -27
  586. package/docs/architecture-runtime.md +16 -1
  587. package/docs/code-review-agents.md +689 -45
  588. package/docs/coding-agent-setup.md +602 -12
  589. package/docs/coding-packages.md +1037 -92
  590. package/docs/coding-services.md +30 -13
  591. package/docs/coding-worker-byo-images.md +218 -6
  592. package/docs/coding-worker-isolation.md +173 -44
  593. package/docs/getting-started-gke.md +332 -129
  594. package/docs/getting-started-identity-provider.md +31 -11
  595. package/docs/getting-started.md +14 -4
  596. package/docs/jira-agents.md +22 -9
  597. package/docs/knowledge/blob-not-found-semantics.md +41 -0
  598. package/docs/knowledge/bounded-file-descriptor.md +52 -0
  599. package/docs/knowledge/delegation-admission-slots.md +52 -0
  600. package/docs/knowledge/http-dispatcher-bootstrap.md +61 -0
  601. package/docs/knowledge/import-rename-target.md +52 -0
  602. package/docs/knowledge/index.md +57 -0
  603. package/docs/knowledge/log.md +9 -0
  604. package/docs/knowledge/mcp-cancelled-task-precedence.md +41 -0
  605. package/docs/knowledge/mcp-http-prompt-discovery.md +41 -0
  606. package/docs/knowledge/mcp-schema-module-boundary.md +41 -0
  607. package/docs/knowledge/nullable-tool-uniqueness.md +52 -0
  608. package/docs/knowledge/overview-cli.md +74 -0
  609. package/docs/knowledge/overview-coding-proxy.md +72 -0
  610. package/docs/knowledge/overview-coding.md +72 -0
  611. package/docs/knowledge/overview-config.md +60 -0
  612. package/docs/knowledge/overview-core.md +72 -0
  613. package/docs/knowledge/overview-deploy.md +83 -0
  614. package/docs/knowledge/overview-mcp.md +61 -0
  615. package/docs/knowledge/overview-prisma.md +72 -0
  616. package/docs/knowledge/overview-providers.md +89 -0
  617. package/docs/knowledge/overview-sandbox.md +83 -0
  618. package/docs/knowledge/overview-surfaces.md +83 -0
  619. package/docs/knowledge/private-datastore-shared-boundary.md +54 -0
  620. package/docs/knowledge/proxy-settlement-projections.md +41 -0
  621. package/docs/knowledge/run-pricing-first-writer.md +43 -0
  622. package/docs/knowledge/schedule-claim-transaction.md +41 -0
  623. package/docs/knowledge/secret-entry-replica-contract.md +52 -0
  624. package/docs/knowledge/terminal-run-first-writer.md +41 -0
  625. package/docs/knowledge/transactional-agent-authorization.md +52 -0
  626. package/docs/knowledge/viewer-notify-write-isolation.md +30 -0
  627. package/docs/knowledge/warm-input-publication.md +30 -0
  628. package/docs/knowledge/workspace-staging-failure.md +54 -0
  629. package/docs/knowledge.md +54 -14
  630. package/docs/native-sandbox.md +731 -0
  631. package/docs/observability.md +4 -0
  632. package/docs/release-verification.md +9 -0
  633. package/docs/security-deployment.md +146 -14
  634. package/docs/slack-notifications.md +268 -0
  635. package/docs/tool-secrets.md +284 -0
  636. package/docs/viewer-api.md +46 -5
  637. package/docs/viewer-api.openapi.yml +1404 -0
  638. package/help/admin-viewer.md +29 -3
  639. package/help/agent-recipes.md +27 -0
  640. package/help/architecture-agent.md +11 -6
  641. package/help/brokered-secrets.md +79 -0
  642. package/help/build-claude-code-image.md +131 -0
  643. package/help/build-worker-image.md +6 -7
  644. package/help/builder-agent.md +19 -6
  645. package/help/code-review-agents.md +243 -10
  646. package/help/coding-packages.md +156 -6
  647. package/help/cost-attribution.md +9 -5
  648. package/help/creating-agents.md +14 -1
  649. package/help/dependency-cache.md +143 -0
  650. package/help/deploy-gke.md +23 -9
  651. package/help/deployment-targets.md +25 -14
  652. package/help/errors/budget-exhausted.md +187 -0
  653. package/help/errors/budget-group-exhausted.md +5 -1
  654. package/help/errors/coding-provider-not-configured.md +2 -2
  655. package/help/errors/coding-stream-quota-exceeded.md +33 -0
  656. package/help/errors/coding-workspace-disk-exceeds-limit.md +39 -0
  657. package/help/errors/continuation-closed.md +9 -12
  658. package/help/errors/database-auth-invalid.md +28 -0
  659. package/help/errors/delegation-conflict.md +24 -0
  660. package/help/errors/file-list-truncated.md +45 -0
  661. package/help/errors/full-read-required.md +49 -0
  662. package/help/errors/github-account-not-allowed.md +29 -0
  663. package/help/errors/graph-incomplete.md +43 -0
  664. package/help/errors/graph-limit.md +43 -0
  665. package/help/errors/low-power-disabled.md +29 -0
  666. package/help/errors/low-power-scale-forbidden.md +35 -0
  667. package/help/errors/low-power-wake-timeout.md +30 -0
  668. package/help/errors/merge-conflict.md +49 -0
  669. package/help/errors/mobile-disabled.md +31 -0
  670. package/help/errors/native-sandbox-capacity.md +22 -0
  671. package/help/errors/native-sandbox-deadline-exceeded.md +19 -0
  672. package/help/errors/native-sandbox-docker-failed.md +20 -0
  673. package/help/errors/native-sandbox-gateway-error.md +20 -0
  674. package/help/errors/native-sandbox-gateway-unavailable.md +21 -0
  675. package/help/errors/native-sandbox-image-not-pinned.md +19 -0
  676. package/help/errors/native-sandbox-isolation-mismatch.md +20 -0
  677. package/help/errors/native-sandbox-launch-abandoned.md +21 -0
  678. package/help/errors/native-sandbox-network-unenforced.md +22 -0
  679. package/help/errors/native-sandbox-requires-catalog.md +31 -0
  680. package/help/errors/native-sandbox-unavailable.md +19 -0
  681. package/help/errors/native-sandbox-warm-delivery-failed.md +21 -0
  682. package/help/errors/native-sandbox-worker-exited.md +21 -0
  683. package/help/errors/native-sandbox-worker-lost.md +20 -0
  684. package/help/errors/native-sandbox-worker-unready.md +22 -0
  685. package/help/errors/package-not-allowed-pending.md +52 -0
  686. package/help/errors/package-not-allowed.md +51 -0
  687. package/help/errors/package-refusals.md +43 -0
  688. package/help/errors/patch-cursor-malformed.md +31 -0
  689. package/help/errors/run-lost.md +39 -0
  690. package/help/errors/run-transcript-download.md +44 -0
  691. package/help/errors/secret-broker-body-invalid.md +26 -0
  692. package/help/errors/secret-broker-changed.md +20 -0
  693. package/help/errors/secret-broker-config-invalid.md +30 -0
  694. package/help/errors/secret-broker-conflict.md +27 -0
  695. package/help/errors/secret-broker-destination-denied.md +28 -0
  696. package/help/errors/secret-broker-value-invalid.md +28 -0
  697. package/help/errors/secret-brokered.md +24 -0
  698. package/help/errors/secret-in-value.md +69 -0
  699. package/help/errors/secret-not-brokered.md +25 -0
  700. package/help/errors/slack-auth-failed.md +48 -0
  701. package/help/errors/slack-channel-unreachable.md +39 -0
  702. package/help/errors/slack-not-configured.md +33 -0
  703. package/help/errors/target-merge.md +40 -0
  704. package/help/fix-merge-conflicts.md +73 -0
  705. package/help/getting-started.md +4 -5
  706. package/help/github-app-setup.md +132 -0
  707. package/help/github.md +40 -1
  708. package/help/identity-and-access.md +7 -1
  709. package/help/jira.md +23 -6
  710. package/help/knowledge.md +16 -7
  711. package/help/local-repositories.md +3 -4
  712. package/help/low-power-mode.md +131 -0
  713. package/help/merge-order-check.md +122 -0
  714. package/help/mobile-app.md +54 -0
  715. package/help/native-capabilities.md +29 -1
  716. package/help/native-sandbox.md +150 -0
  717. package/help/observability.md +8 -0
  718. package/help/operating-agents.md +5 -0
  719. package/help/package-audit-mode.md +91 -0
  720. package/help/related-pull-requests.md +80 -16
  721. package/help/repo-instructions-and-skills.md +91 -0
  722. package/help/resume-runs-locally.md +131 -0
  723. package/help/review-fix-rounds.md +43 -1
  724. package/help/sharing-agents.md +59 -0
  725. package/help/slack-notifications.md +76 -0
  726. package/help/status-comments.md +31 -0
  727. package/help/stop-run.md +58 -0
  728. package/help/troubleshooting/budgets.md +28 -0
  729. package/help/troubleshooting/coding-workers.md +99 -7
  730. package/package.json +27 -13
  731. package/prisma/migrations/20261009000003_native_execution_mode/migration.sql +12 -0
  732. package/prisma/migrations/20261009000004_native_gateway_ledger/migration.sql +65 -0
  733. package/prisma/migrations/20261009000005_native_gateway_call_child_agent/migration.sql +5 -0
  734. package/prisma/migrations/20261009000006_run_deferred_start_stop/migration.sql +14 -0
  735. package/prisma/migrations/20261009000007_native_gateway_network_ready/migration.sql +5 -0
  736. package/prisma/migrations/20261010000001_workflow_notifications/migration.sql +99 -0
  737. package/prisma/migrations/20261011000001_native_gateway_session_status_index/migration.sql +2 -0
  738. package/prisma/migrations/20261012000001_native_warm_worker/migration.sql +32 -0
  739. package/prisma/migrations/20261013000001_coding_run_merge_order/migration.sql +2 -0
  740. package/prisma/migrations/20261013000001_secret_broker/migration.sql +17 -0
  741. package/prisma/migrations/20261013000002_deferred_review_request/migration.sql +4 -0
  742. package/prisma/migrations/20261014000000_repo_skills/migration.sql +15 -0
  743. package/prisma/migrations/20261015000001_coding_run_merge_order_index/migration.sql +2 -0
  744. package/prisma/migrations/20261015000002_no_change_rereview/migration.sql +2 -0
  745. package/prisma/migrations/20261016000000_registry_approved_accepted_advisories/migration.sql +3 -0
  746. package/prisma/migrations/20261016000001_mark_ready_when_passing/migration.sql +3 -0
  747. package/prisma/migrations/20261017000000_debug_trace_max_mb/migration.sql +4 -0
  748. package/prisma/migrations/20261018000000_dependency_cache/migration.sql +53 -0
  749. package/prisma/migrations/20261019000000_claude_max_output_tokens/migration.sql +5 -0
  750. package/prisma/migrations/20261021000000_pr_description_hash/migration.sql +4 -0
  751. package/prisma/migrations/20261022000000_dependency_snapshot_validation_metadata/migration.sql +4 -0
  752. package/prisma/migrations/20261023000000_package_audit_mode/migration.sql +27 -0
  753. package/prisma/migrations/20261024000000_budget_events/migration.sql +26 -0
  754. package/prisma/migrations/20261025000000_cache_aware_holds/migration.sql +9 -0
  755. package/prisma/migrations/20261026000000_budget_overrun/migration.sql +4 -0
  756. package/prisma/migrations/20261027000000_coding_run_request/migration.sql +1 -0
  757. package/prisma/migrations/20261028000000_native_gateway_review_reads/migration.sql +6 -0
  758. package/prisma/migrations/20261029000000_lead_survives_deploy/migration.sql +6 -0
  759. package/prisma/migrations/20261030000000_local_review_covered_sha/migration.sql +2 -0
  760. package/prisma/migrations/20261031000000_coding_run_budget_limit/migration.sql +9 -0
  761. package/prisma/migrations/20261101000000_run_transcripts/migration.sql +22 -0
  762. package/prisma/schema.prisma +631 -146
  763. package/dist/sandbox/generated/zod-to-json-schema.bundle.js +0 -5
@@ -0,0 +1,731 @@
1
+ # Native sandbox
2
+
3
+ > **Requires Wardby 0.5.4 or later.**
4
+
5
+ By default a native agent runs inside the Wardby server process: its turn loop
6
+ and any user tool code you attach execute next to the database connection, the
7
+ LLM credentials, and every other agent's runs. **Sandbox mode** moves the whole
8
+ turn loop and the agent's user tools into a single-use worker that holds no
9
+ credentials, no database access, no container-runtime access, and no network
10
+ except one path to a separate **native gateway**. The worker is a Docker
11
+ container or, on a Kubernetes cluster, a pod; you choose with
12
+ `NATIVE_SANDBOX_LAUNCHER`.
13
+
14
+ Use it when a native agent runs tool code or prompts you do not fully trust, for
15
+ example tools written by people other than the operators, or agents that fetch
16
+ and process untrusted content. Leave agents in the default `control-plane` mode
17
+ when you trust the tools and want the simplest deployment.
18
+
19
+ Sandbox mode applies to native agents only. Coding agents have their own
20
+ isolation model; see [Coding-worker isolation](coding-worker-isolation.md).
21
+
22
+ ## What is isolated and what is not
23
+
24
+ | Component | Trusted? | Where it runs |
25
+ | ------------------------- | -------- | ---------------------------------------- |
26
+ | Wardby server / scheduler | Yes | Your host, VM, or cluster |
27
+ | Native gateway | Yes | A separate container or Deployment |
28
+ | Postgres, LLM provider | Yes | Reachable only from server/gateway |
29
+ | Agent turn loop (worker) | No | Single-use container or pod, one per run |
30
+ | User tool code (worker) | No | The same worker |
31
+
32
+ The Docker worker container:
33
+
34
+ - has no LLM keys, secrets, database URL, or Docker socket, and receives only a
35
+ run-scoped capability on its standard input (never in its environment,
36
+ arguments, labels, or `docker inspect` output);
37
+ - runs as non-root (uid 10001) on a read-only root filesystem with a
38
+ size-capped `/tmp` (no exec), all Linux capabilities dropped,
39
+ `no-new-privileges`, and CPU, memory, and PID limits;
40
+ - sits on an internal Docker network created for that run alone, shared only
41
+ with the gateway container, with no route to the internet, the host, or any
42
+ other run.
43
+
44
+ On Kubernetes the worker is a pod with the same posture; see
45
+ [Set up with Kubernetes](#set-up-with-kubernetes) for what the pod and its
46
+ NetworkPolicy contain and how the isolation is proven before the run starts.
47
+
48
+ Everything the worker needs from the outside world (model calls, the built-in
49
+ tools, and tool access to datastores, secrets, and outbound fetch) goes through
50
+ the gateway, which enforces each tool attachment's grants. A worker can only
51
+ ask for what the agent's attachments already allow.
52
+
53
+ Containers are defense in depth, not a virtual-machine boundary. On Kubernetes,
54
+ set a sandboxing runtime class such as gVisor where you have one. Run the Docker
55
+ host on a machine that holds no production credentials beyond what the server
56
+ and gateway need.
57
+
58
+ ## Topology (Docker)
59
+
60
+ ```
61
+ Docker host
62
+ +---------------------------------------------------------+
63
+ | wardby serve (server + scheduler) |
64
+ | | docker run / network create / network connect |
65
+ | v |
66
+ | per-run internal network (no external route) |
67
+ | +--------------------+ +--------------------+ |
68
+ | | native worker | HTTP | native gateway | |
69
+ | | (no credentials) +------->| wardby-native- |--+--> LLM provider
70
+ | | single-use | | gateway :8790 |--+--> Postgres
71
+ | +--------------------+ | (credentials, DB) | |
72
+ | +--------------------+ |
73
+ +---------------------------------------------------------+
74
+ ```
75
+
76
+ For each run the server creates a new internal network, connects the gateway
77
+ container to it under the alias `wardby-native-gateway`, and starts the worker
78
+ on it. When the run ends the worker, the network, and the gateway's membership
79
+ of it are removed.
80
+
81
+ The gateway is stateless: all state is in Postgres. You can restart it while
82
+ runs are in flight; workers retry their calls. It must not be given the Docker
83
+ socket, because workers can reach it.
84
+
85
+ ## Requirements
86
+
87
+ - **Docker launcher:** Docker on the host that runs `wardby serve` (or
88
+ `wardby scheduler`). The server launches workers with the `docker` CLI, so its
89
+ user must be able to use the Docker daemon. A running native gateway container
90
+ (below) on the same Docker host, with access to the same Postgres database as
91
+ the server.
92
+ - **Kubernetes launcher:** a cluster whose CNI enforces `NetworkPolicy`, a
93
+ namespace holding the native gateway, and a server identity with the
94
+ permissions in [Server permissions](#server-permissions).
95
+ - The `wardby-native-worker` image, pinned by digest (Docker also accepts a
96
+ local image id; Kubernetes requires a registry digest).
97
+ - A running `wardby serve` or `wardby scheduler`. Sub-agents of a sandboxed run
98
+ are started by the scheduler leader (see [Sub-agents](#sub-agents)).
99
+
100
+ ## Set up with Docker
101
+
102
+ ### 1. Choose the worker image
103
+
104
+ Releases publish the image to the GitHub Container Registry as
105
+ `ghcr.io/<org>/wardby-native-worker`. The exact digest-pinned reference for the
106
+ installed version is listed as `nativeWorker` in `dist/quickstart-images.json`
107
+ inside the npm package. Use that reference as-is:
108
+
109
+ ```dotenv
110
+ NATIVE_SANDBOX_WORKER_IMAGE=ghcr.io/your-org/wardby-native-worker@sha256:replace-with-digest
111
+ ```
112
+
113
+ The image must be immutable: a `repo@sha256:...` digest or a local image id.
114
+ A mutable tag such as `:latest` is refused with
115
+ [`native_sandbox_image_not_pinned`](../help/errors/native-sandbox-image-not-pinned.md).
116
+
117
+ To build it yourself from a repository checkout:
118
+
119
+ ```bash
120
+ npm run native-worker:image:local
121
+ docker image inspect --format '{{.Id}}' wardby-native-worker:local
122
+ ```
123
+
124
+ Use the printed `sha256:...` image id as `NATIVE_SANDBOX_WORKER_IMAGE`. A local
125
+ id must already exist on the Docker host; a digest reference is pulled once if
126
+ missing.
127
+
128
+ ### 2. Run the native gateway
129
+
130
+ The gateway is the same Wardby build as the server, started with the
131
+ `native-gateway` command. It needs the server's database, LLM, secrets, and
132
+ integration settings, and **no Docker access**.
133
+
134
+ | Gateway variable | Purpose |
135
+ | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
136
+ | `NATIVE_GATEWAY_LISTEN` | `host:port` to listen on. Default `0.0.0.0:8790`. |
137
+ | `DATABASE_URL` | The same database the server uses. With `DATABASE_AUTH=rds-iam` the gateway also needs `DATABASE_AUTH`, `AWS_REGION` (or `DATABASE_AWS_REGION`) and the CA bundle file named by `sslrootcert` ([details](security-deployment.md#database-authentication)). |
138
+ | LLM provider keys | The same provider settings as the server (for example `OPENAI_API_KEY`). |
139
+ | `SECRET_APP_KEY` | Same value as the server, so tools can read their bound secrets or send brokered ones ([details](tool-secrets.md)). |
140
+ | Integration settings | The same repository-host and issue-tracker settings as the server. |
141
+
142
+ For local development, the repository ships a compose overlay
143
+ (`deploy/local/docker-compose.native-sandbox.yml`) that runs the gateway next to
144
+ the local Postgres from `deploy/local/docker-compose.yml`:
145
+
146
+ ```bash
147
+ docker compose -f deploy/local/docker-compose.yml -f deploy/local/docker-compose.native-sandbox.yml --env-file .env.local up -d --build native-gateway
148
+ ```
149
+
150
+ The overlay names the container `wardby-native-gateway`, passes the database
151
+ URL for the compose network and your LLM keys from the environment file. It
152
+ runs with a read-only root filesystem and all capabilities dropped, and mounts
153
+ no Docker socket.
154
+ It defines its own health check against `/healthz`.
155
+
156
+ For other deployments, run `wardby native-gateway` in a container built from
157
+ the same image as the server, on the same Docker host, with any container
158
+ name you choose, and give that name to the server in the next step. Do not
159
+ publish its port to the internet; only the per-run networks and your own
160
+ health checks need to reach it.
161
+
162
+ ### 3. Configure the server
163
+
164
+ Add these to the server's environment (`wardby serve` or `wardby scheduler`),
165
+ then restart it:
166
+
167
+ ```dotenv
168
+ NATIVE_SANDBOX_LAUNCHER=docker
169
+ NATIVE_SANDBOX_WORKER_IMAGE=ghcr.io/your-org/wardby-native-worker@sha256:replace-with-digest
170
+ NATIVE_GATEWAY_CONTAINER=wardby-native-gateway
171
+ ```
172
+
173
+ See [Configuration reference](#configuration-reference) for every variable,
174
+ including the Kubernetes ones. A missing required variable, or a launcher other
175
+ than `docker` or `kubernetes`, stops the server at startup with a message naming the variable. When
176
+ `NATIVE_SANDBOX_LAUNCHER` is unset, sandbox mode is off and any sandbox-mode
177
+ run fails closed (see [Failure modes](#failure-modes)).
178
+
179
+ `JOB_LAUNCHER` (coding agents) is a separate setting; you can enable either,
180
+ both, or neither.
181
+
182
+ ### 4. Set an agent's mode
183
+
184
+ Each native agent has a `nativeExecutionMode` setting:
185
+
186
+ - `control-plane` (default): the run executes in the server process.
187
+ - `sandbox`: the run executes in a worker container as described above.
188
+
189
+ Set it with the MCP tools `create_agent` or `update_agent` (field
190
+ `nativeExecutionMode`, native agents only), or in an import bundle. Setting
191
+ `sandbox` is refused while the server has no native sandbox configured.
192
+
193
+ From the command line, with the same environment as the server:
194
+
195
+ ```bash
196
+ wardby agent create --name <n> --model <m> --prompt <p> --budget <usd> --native-execution-mode sandbox
197
+ ```
198
+
199
+ ```bash
200
+ wardby agent mode <name> sandbox
201
+ ```
202
+
203
+ The CLI refuses `sandbox` with `native_sandbox_unavailable` when its own
204
+ environment has no `NATIVE_SANDBOX_LAUNCHER`, so run it where the server's
205
+ sandbox variables are set. `wardby agent list` marks sandbox-mode agents.
206
+ `get_run` and `list_runs` report each run's mode as `nativeExecutionMode`
207
+ (`control-plane`, `sandbox`, or `null` for a coding run).
208
+
209
+ Each run keeps the mode it started with. Changing an agent affects only the
210
+ runs that start afterwards.
211
+
212
+ ## Set up with Kubernetes
213
+
214
+ With `NATIVE_SANDBOX_LAUNCHER=kubernetes` the server starts one pod per
215
+ sandbox run in a namespace you choose and deletes it when the run ends. The
216
+ native gateway runs in the same namespace as an ordinary Deployment.
217
+
218
+ ```
219
+ cluster namespace
220
+ +---------------------------------------------------------------+
221
+ | wardby serve --create pod / Secret / NetworkPolicy--> |
222
+ | |
223
+ | native-run pod (no credentials) native gateway pods |
224
+ | +---------------------------+ 8790 +-------------------+ |
225
+ | | worker, single-use +------->| wardby-native- |--+--> LLM provider
226
+ | | egress: gateway:8790 only | x | gateway Service |--+--> Postgres
227
+ | +---------------------------+ 8791 +-------------------+ |
228
+ +---------------------------------------------------------------+
229
+ ```
230
+
231
+ ### 1. Choose the worker image
232
+
233
+ Use the digest-pinned `nativeWorker` reference from
234
+ `dist/quickstart-images.json`, or push your own build to a registry your
235
+ cluster can pull from. The reference must be a registry digest,
236
+ `repo@sha256:...`. A local image id means nothing to a cluster, and a
237
+ mutable tag is refused; both stop the server at startup or fail the run with
238
+ [`native_sandbox_image_not_pinned`](../help/errors/native-sandbox-image-not-pinned.md).
239
+
240
+ ### 2. Deploy the native gateway
241
+
242
+ Run `wardby native-gateway` as a Deployment in the run namespace, from the
243
+ same Wardby image as the server. Requirements:
244
+
245
+ - **Environment:** the server's `DATABASE_URL`, `SECRET_APP_KEY` (so tools can
246
+ read their bound secrets or send brokered ones; see
247
+ [tool-secrets.md](tool-secrets.md)), the LLM provider keys, and any integration or
248
+ other settings the server has (see the gateway table in the Docker
249
+ setup above). Also `NATIVE_GATEWAY_LISTEN` (default `0.0.0.0:8790`) and
250
+ `NATIVE_GATEWAY_DENY_PORT` (default `8791`). Keep these in a Secret.
251
+ - **No Kubernetes access:** `automountServiceAccountToken: false` and no Role
252
+ or RoleBinding. Workers can reach the gateway, so it must not be able to
253
+ touch the cluster. A read-only root filesystem with a small `/tmp`,
254
+ all capabilities dropped, and a non-root user all apply.
255
+ - **Pod label:** `app.kubernetes.io/name: wardby-native-gateway`. The per-run
256
+ NetworkPolicy selects the gateway pods by this label.
257
+ - **A ClusterIP Service** named `wardby-native-gateway` (or set
258
+ `NATIVE_GATEWAY_SERVICE`) exposing **both** port 8790 and the deny port 8791. Nothing is served on 8791; it exists only so isolation can be proven.
259
+ - **A NetworkPolicy on the gateway pods** that admits pods labeled
260
+ `wardby.io/component: native-run` on **both 8790 and 8791**, with egress to
261
+ cluster DNS, the model providers (HTTPS), and the database. Do not drop the
262
+ 8791 rule: the check that a worker cannot reach 8791 only means something if
263
+ 8791 is open at the destination, so that the worker's own policy is the only
264
+ thing that can block it. Without it, a worker whose policy was never
265
+ programmed would read the port as blocked and its isolation could be
266
+ wrongly proven.
267
+ - Replicas are fine; the gateway is stateless.
268
+
269
+ The gateway ships in every target's manifests: the Deployment, Service, and
270
+ NetworkPolicy are in `deploy/kind-coding/manifests/base/native-gateway.yaml`,
271
+ and each overlay (`kind`, `gke-autopilot`) supplies its own database egress and
272
+ the `wardby-native-gateway-env` Secret. On a cluster you manage yourself, copy
273
+ that file and adapt it. On GKE Autopilot the gateway also gets its own Workload
274
+ Identity and Cloud SQL database user; see
275
+ [Getting started on GKE](getting-started-gke.md#native-sandbox).
276
+
277
+ ### 3. Server permissions
278
+
279
+ The server (`wardby serve` or `wardby scheduler`) needs a Role in the run
280
+ namespace that allows:
281
+
282
+ | Resource | Verbs |
283
+ | ----------------------------------- | --------------------------------- |
284
+ | `pods` | `create`, `get`, `delete`, `list` |
285
+ | `pods/exec` | `create`, `get` |
286
+ | `pods/log` | `get` |
287
+ | `secrets` | `create`, `delete` |
288
+ | `networking.k8s.io/networkpolicies` | `create`, `get`, `delete` |
289
+ | `services` | `get` |
290
+
291
+ `list` on pods lets the startup sweep find leftover worker pods by label;
292
+ `pods/exec` is how the server proves isolation from inside the pod; `pods/log`
293
+ is read only when a worker exits non-zero, for the redacted tail it logs (without
294
+ it the server logs the exit with no tail); `services` is read once to find the
295
+ gateway's ClusterIP. Coding runs on Kubernetes use a
296
+ largely overlapping Role (`deploy/kind-coding/manifests/base/launcher-role.yaml`).
297
+
298
+ ### 4. Configure the server
299
+
300
+ ```dotenv
301
+ NATIVE_SANDBOX_LAUNCHER=kubernetes
302
+ NATIVE_SANDBOX_WORKER_IMAGE=registry.example.com/wardby-native-worker@sha256:replace-with-digest
303
+ NATIVE_SANDBOX_NAMESPACE=wardby
304
+ ```
305
+
306
+ Optional: `KUBERNETES_CONTEXT` (the kubeconfig context; unset uses the
307
+ in-cluster identity or the current context), `NATIVE_SANDBOX_RUNTIME_CLASS`
308
+ (for example a gVisor class), `NATIVE_GATEWAY_SERVICE`, the CPU and memory
309
+ limits, `NATIVE_SANDBOX_MAX_CONCURRENT`, `NATIVE_SANDBOX_PRIORITY_CLASS`, and
310
+ the two start-up time limits. See [Configuration reference](#configuration-reference). Then set
311
+ agents to `sandbox` mode as described in
312
+ [Set an agent's mode](#4-set-an-agents-mode).
313
+
314
+ ### What each run gets
315
+
316
+ For every run the server creates, then deletes when the run ends:
317
+
318
+ - A **Secret** holding the run's input and capability, immutable and mounted
319
+ read-only into the pod. The capability is never in the pod's environment,
320
+ arguments, or labels.
321
+ - A **NetworkPolicy** selecting only that pod: no ingress, and egress only to
322
+ the gateway pods on port 8790.
323
+ - The **pod**, with no service-account token, non-root (uid and fsGroup
324
+ 10001), a read-only root filesystem with a 64 MiB `/tmp`, all capabilities
325
+ dropped, no privilege escalation, the runtime-default seccomp profile, CPU
326
+ and memory requests equal to limits, an optional priority class
327
+ (`NATIVE_SANDBOX_PRIORITY_CLASS`), and `activeDeadlineSeconds` set to the
328
+ run's deadline. Kubernetes has no per-pod process limit, so
329
+ `NATIVE_SANDBOX_PIDS` does not apply.
330
+
331
+ Workers dial the gateway Service's ClusterIP, so they need no DNS egress. Set
332
+ `NATIVE_GATEWAY_URL` only to override that.
333
+
334
+ ### How isolation is proven
335
+
336
+ A NetworkPolicy takes effect a few seconds after its pod starts, so the run
337
+ does not begin until the server has proven the isolation. A new sandbox run
338
+ starts **not ready**: the gateway refuses every call from it with a
339
+ `not_ready` response, and the worker keeps retrying. Meanwhile the server:
340
+
341
+ 1. Reads back the pod and NetworkPolicy it created and compares them with what
342
+ it built. If an admission controller or mutating webhook changed the
343
+ security-relevant parts (service-account token, host networking, runtime
344
+ class, priority class, image, container resources and security context,
345
+ extra containers, or the policy),
346
+ the run fails with
347
+ [`native_sandbox_isolation_mismatch`](../help/errors/native-sandbox-isolation-mismatch.md).
348
+ 2. Waits for the pod to run, then executes a short probe inside it. The probe
349
+ must reach the gateway on 8790, must fail to reach the gateway's deny port
350
+ 8791 at the same address, and must fail to reach an outside address or any
351
+ cloud metadata endpoint: `169.254.169.254:80`, the EKS Pod Identity agent
352
+ (`169.254.170.23:80` and its IPv6 address `[fd00:ec2::23]:80`) and EC2's IPv6
353
+ metadata address `[fd00:ec2::254]:80`.
354
+ 3. Only when the probe passes does it mark the run ready. The gateway then
355
+ accepts the worker's calls.
356
+
357
+ If the probe cannot pass within its time limit the run fails with
358
+ [`native_sandbox_network_unenforced`](../help/errors/native-sandbox-network-unenforced.md)
359
+ and the pod is removed. What operators see while this happens: a run that
360
+ stays in its starting state for a few seconds (longer on a cold image pull),
361
+ and nothing in the model or tool logs until it is ready. A cluster whose CNI
362
+ does not enforce NetworkPolicy fails every sandbox run this way, by design.
363
+
364
+ ### Managed Kubernetes platforms
365
+
366
+ Set `KUBERNETES_PLATFORM=eks` on Amazon EKS clusters that have a gVisor node
367
+ group. It requires the same gVisor runtime class as `gke-autopilot` (the server
368
+ refuses to start unless `NATIVE_SANDBOX_RUNTIME_CLASS` or
369
+ `KUBERNETES_RUNTIME_CLASS` is `gvisor`) and expects a RuntimeClass `gvisor`
370
+ (handler `runsc`) whose scheduling block selects nodes labelled
371
+ `wardby.dev/sandbox=gvisor` and tolerates their `sandbox=gvisor:NoSchedule`
372
+ taint.
373
+
374
+ Set `KUBERNETES_PLATFORM=gke-autopilot` on GKE Autopilot. It applies to native
375
+ worker pods as well as coding pods: pod resources are conformed to Autopilot's
376
+ rules (CPU in 250m steps, 1 to 6.5 GiB of memory per vCPU) so admission changes
377
+ nothing, and the attestation above then passes. Autopilot also requires a
378
+ sandboxing runtime: with this platform the server refuses to start unless
379
+ `NATIVE_SANDBOX_RUNTIME_CLASS` (or `KUBERNETES_RUNTIME_CLASS`) is `gvisor`
380
+ ("runs native workers only under gVisor"). A cold gVisor node can take about
381
+ two minutes to come up, so raise `NATIVE_SANDBOX_READY_TIMEOUT_MS` (for example
382
+ to `600000`).
383
+
384
+ A run's worker launch (in low-power mode, the gateway wake first, then the pod
385
+ start and the isolation probe) can take several minutes on cold nodes. The
386
+ control plane keeps the run's heartbeat fresh for the whole launch, so the run
387
+ shows as running and the reconciler does not reap it as orphaned. The launch
388
+ is bounded by its own limits instead: the gateway wake
389
+ ([`low_power_wake_timeout`](../help/errors/low-power-wake-timeout.md)),
390
+ `NATIVE_SANDBOX_READY_TIMEOUT_MS`
391
+ ([`native_sandbox_worker_unready`](../help/errors/native-sandbox-worker-unready.md))
392
+ and the isolation probe
393
+ ([`native_sandbox_network_unenforced`](../help/errors/native-sandbox-network-unenforced.md)).
394
+ If the run is stopped during the launch, no worker pod is created
395
+ ([`native_sandbox_launch_abandoned`](../help/errors/native-sandbox-launch-abandoned.md)).
396
+ If the control-plane process running the launch exits partway, the run is
397
+ reported [`native_sandbox_worker_lost`](../help/errors/native-sandbox-worker-lost.md)
398
+ and is not relaunched.
399
+
400
+ ### Capacity
401
+
402
+ `NATIVE_SANDBOX_MAX_CONCURRENT` caps how many sandbox runs may be active at
403
+ once across all server replicas (it counts active gateway sessions). A start
404
+ past the cap fails immediately with
405
+ [`native_sandbox_capacity`](../help/errors/native-sandbox-capacity.md); it does
406
+ not queue. The same code is returned when the namespace's ResourceQuota has no
407
+ room for another worker pod. Raise the ResourceQuota together with
408
+ `NATIVE_SANDBOX_MAX_CONCURRENT` (and `CODING_MAX_CONCURRENT`, which shares the
409
+ namespace): each worker pod needs its CPU and memory limits from the quota.
410
+
411
+ ## Warm pool
412
+
413
+ By default every sandbox run starts its own worker, so a run waits for the
414
+ worker to be created and, on Kubernetes, for pod scheduling, the image pull, and
415
+ the in-pod isolation proof. The warm pool keeps a few idle, already-isolated
416
+ workers ready so a run can take one instead. It works with both
417
+ `NATIVE_SANDBOX_LAUNCHER=docker` and `kubernetes`.
418
+
419
+ ### Enable it
420
+
421
+ Set `NATIVE_SANDBOX_WARM_POOL_SIZE` on the server to the number of idle workers
422
+ to keep (0 to 50; the default `0` means no pool and every run cold-starts as
423
+ before). `NATIVE_SANDBOX_WARM_MAX_AGE_MS` (60000 to 21600000, default `1800000`,
424
+ 30 minutes) is how long an idle worker may wait: an older one is replaced and
425
+ never claimed. A pool worker that nobody claims also exits by itself five
426
+ minutes after its max age.
427
+
428
+ The worker image must support pool workers: rebuild or update
429
+ `wardby-native-worker` with the release that adds the pool. An older image still
430
+ runs cold runs but cannot be a pool worker. The release adds a database
431
+ migration (the `NativeWarmWorker` table); apply it with `prisma migrate deploy`
432
+ as with any upgrade.
433
+
434
+ ### Sizing and idle cost
435
+
436
+ `NATIVE_SANDBOX_MAX_CONCURRENT` still counts only active runs. Idle pool workers
437
+ are extra running containers or pods on top of it. On Kubernetes the namespace
438
+ ResourceQuota must have room for `NATIVE_SANDBOX_MAX_CONCURRENT` plus
439
+ `NATIVE_SANDBOX_WARM_POOL_SIZE` worker pods, plus the gateway and any coding
440
+ runs. A pool worker that does not fit is skipped and logged; it never fails a
441
+ run.
442
+
443
+ Each idle worker reserves its CPU and memory continuously. On GKE Autopilot you
444
+ pay for each idle pod's requests (500m and 512Mi in the reference overlay). In
445
+ return, a claimed run skips pod scheduling, the image pull, node boot, and the
446
+ in-pod isolation probe; on Autopilot a cold gVisor node can take about two
447
+ minutes to come up. Start with a small size and raise it if runs still
448
+ cold-start under load.
449
+
450
+ ### How claims keep the isolation guarantees
451
+
452
+ - A pool worker is started and its isolation proven before any run exists (on
453
+ Kubernetes it is attested and probed from inside the pod, the same as a cold
454
+ pod). It holds no run data and no gateway capability.
455
+ - A run claims an idle worker atomically through the database, so claims are
456
+ safe across server replicas and processes. A worker is never given to two
457
+ runs.
458
+ - The run's input, including its one-time gateway capability, is delivered by
459
+ exec over stdin only after the claim. It never travels in the environment,
460
+ the command line, labels, or a Kubernetes Secret.
461
+ - At claim the worker is re-checked: still running, and the pod and
462
+ NetworkPolicy still as built (Docker: attached only to its own network). It is
463
+ not probed again; the max age bounds how old the isolation proof can be.
464
+ - The worker is single-use and destroyed after the run, exactly like a cold one.
465
+
466
+ ### Fallback
467
+
468
+ - No idle worker, or the claimed one fails the re-check: the run cold-launches
469
+ as if there were no pool.
470
+ - Delivery fails: the worker is removed and, once it is confirmed gone, the run
471
+ cold-launches. If it cannot be confirmed gone within 30 seconds, the run fails
472
+ with
473
+ [`native_sandbox_warm_delivery_failed`](../help/errors/native-sandbox-warm-delivery-failed.md)
474
+ rather than risk a second worker holding the same capability.
475
+
476
+ ### Upkeep
477
+
478
+ Every `wardby serve`, `wardby scheduler`, and `wardby mcp` process with the
479
+ sandbox configured keeps the pool up every 15 seconds. They coordinate through
480
+ the database, so running several never overfills it. Each pass starts workers up
481
+ to the size, retires idle workers that are older than the max age, gone, or over
482
+ the size (oldest first), and removes leftovers. Changing the worker image, CPU or
483
+ memory, runtime class, priority class, platform, namespace, gateway, or max age
484
+ retires all idle workers of the old configuration automatically, about a
485
+ minute after they started (a grace that keeps two replicas from retiring each
486
+ other's workers mid rolling update); they are never claimed meanwhile. Lowering the
487
+ size to `0` retires leftover pool workers within a pass, including any that a
488
+ replica still running the old size refills during a rolling update. A short-lived
489
+ command such as `wardby run` claims workers but does not warm new ones.
490
+
491
+ ### Naming, labels, and logs
492
+
493
+ Pool workers are named `wardby-nwarm-<token>`. Kubernetes pods carry
494
+ `wardby.io/pool=warm` and `wardby.io/warm-worker=<token>`, and still carry
495
+ `wardby.io/component=native-run`, so the gateway NetworkPolicy admits them.
496
+ Docker containers carry `io.wardby.pool=warm`. No new RBAC is needed: the
497
+ permissions in [Server permissions](#3-server-permissions) already cover it.
498
+
499
+ List idle workers with
500
+ `kubectl get pods -n <namespace> -l wardby.io/pool=warm` or
501
+ `docker ps --filter label=io.wardby.pool=warm`.
502
+
503
+ Pool logs use the module `native-warm-pool`, with an `event` field:
504
+
505
+ | `event` | Meaning |
506
+ | ---------- | ------------------------------------------------------------------------------ |
507
+ | `warmed` | A pool worker became ready (with the time it took, in ms). |
508
+ | `claimed` | A run took an idle worker. |
509
+ | `miss` | No idle worker was available; the run cold-launched. |
510
+ | `fallback` | A claimed worker failed the re-check or delivery; see the run's outcome above. |
511
+ | `retired` | An idle worker was replaced (with the reason: `stale`, `gone`, or `excess`). |
512
+ | `reaped` | An abandoned or orphaned pool worker was removed. |
513
+
514
+ If runs keep logging `miss`, the pool is smaller than demand, workers cannot be
515
+ started (look for "starting a warm worker failed", and check the ResourceQuota),
516
+ or the server running upkeep is not up.
517
+
518
+ ## Configuration reference
519
+
520
+ | Variable | Launcher | Required | Default | Purpose |
521
+ | --------------------------------------- | ---------- | -------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
522
+ | `NATIVE_SANDBOX_LAUNCHER` | both | Yes | unset (sandbox off) | `docker` or `kubernetes`. Independent of `JOB_LAUNCHER`. |
523
+ | `NATIVE_SANDBOX_WORKER_IMAGE` | both | Yes | | Pinned worker image. Docker: `repo@sha256:...` or a local image id. Kubernetes: a registry digest `repo@sha256:...` only. |
524
+ | `NATIVE_GATEWAY_CONTAINER` | Docker | Yes | | Name of the running gateway container the server connects to each run's network. |
525
+ | `NATIVE_SANDBOX_NAMESPACE` | Kubernetes | No | `KUBERNETES_NAMESPACE`, else `wardby-coding` | Namespace for run pods and the gateway. |
526
+ | `KUBERNETES_CONTEXT` | Kubernetes | No | in-cluster or current context | Kubeconfig context the server uses. |
527
+ | `NATIVE_SANDBOX_RUNTIME_CLASS` | Kubernetes | No | `KUBERNETES_RUNTIME_CLASS`, else none | RuntimeClass for run pods (for example gVisor). |
528
+ | `NATIVE_GATEWAY_SERVICE` | Kubernetes | No | `wardby-native-gateway` | Name of the gateway Service in the run namespace. |
529
+ | `NATIVE_GATEWAY_URL` | both | No | Docker: `http://wardby-native-gateway:8790/native-gateway/v1/call`; Kubernetes: the Service's ClusterIP on 8790 | What workers dial. Change only if the gateway is reachable another way. Must be an `http(s)` URL. |
530
+ | `NATIVE_SANDBOX_CPUS` | both | No | `1` | CPU limit per worker (Kubernetes: request and limit). |
531
+ | `NATIVE_SANDBOX_MEMORY_MB` | both | No | `512` | Memory limit per worker (Docker: swap disabled; Kubernetes: request and limit). |
532
+ | `NATIVE_SANDBOX_PIDS` | Docker | No | `128` | Process limit per worker. Docker only: Kubernetes has no per-pod process limit. |
533
+ | `NATIVE_SANDBOX_MAX_CONCURRENT` | both | No | unset (no cap) | At most this many sandbox runs at once across all replicas (counts active gateway sessions). A start past it fails with `native_sandbox_capacity`. |
534
+ | `NATIVE_SANDBOX_WARM_POOL_SIZE` | both | No | `0` (no pool; range 0-50) | Idle, already-isolated workers kept ready for runs to claim. See [Warm pool](#warm-pool). On Kubernetes, size the ResourceQuota for this many extra pods. Must be `0` when `WARDBY_LOW_POWER=1`. |
535
+ | `NATIVE_SANDBOX_WARM_MAX_AGE_MS` | both | No | `1800000` (range 60000-21600000) | An idle pool worker older than this is replaced and never claimed. |
536
+ | `NATIVE_SANDBOX_READY_TIMEOUT_MS` | Kubernetes | No | `120000` (range 1000-1800000) | How long a worker pod may take to start running. Use about `600000` on GKE Autopilot, where a cold gVisor node takes about two minutes. |
537
+ | `NATIVE_SANDBOX_ENFORCEMENT_TIMEOUT_MS` | Kubernetes | No | `30000` (range 1000-600000) | How long the in-pod isolation proof may take. |
538
+ | `NATIVE_SANDBOX_PRIORITY_CLASS` | Kubernetes | No | `KUBERNETES_RUN_PRIORITY_CLASS`, else none | PriorityClass for worker pods. Must not be a `system-` class. |
539
+ | `KUBERNETES_PLATFORM` | Kubernetes | No | none | `gke-autopilot` conforms worker pod resources to Autopilot's rules and requires the gVisor runtime class; `eks` targets EKS with a gVisor node group and also requires it. Shared with coding runs. |
540
+
541
+ Gateway-side variables (`NATIVE_GATEWAY_LISTEN`, `NATIVE_GATEWAY_DENY_PORT`) are
542
+ set on the gateway, not the server.
543
+
544
+ ## Limits and deadline
545
+
546
+ - Each worker is limited by `NATIVE_SANDBOX_CPUS`, `NATIVE_SANDBOX_MEMORY_MB`,
547
+ and (Docker only) `NATIVE_SANDBOX_PIDS`, with a 64 MiB `/tmp`. Raise the
548
+ limits if tools run out of memory or processes.
549
+ - A sandbox run has a maximum lifetime of 60 minutes. Past it the worker is
550
+ stopped and the run fails with `native_sandbox_deadline_exceeded`.
551
+ - The agent's own turn and budget limits still apply as for any native agent.
552
+
553
+ ## Stopping a run
554
+
555
+ `stop_run` (or cancelling the MCP task that started the run) stops a sandboxed
556
+ run whether it is still waiting for a worker or already running:
557
+
558
+ 1. The run is recorded `cancelled` with the caller's reason, unless it already
559
+ finished (the first terminal state wins; a finished run is not changed).
560
+ 2. Its gateway session ends. The worker's next call (a model turn, a tool, or
561
+ its result) is refused, and the worker exits on its own.
562
+ 3. A worker still running 5 seconds later is killed. Either way the worker is
563
+ then removed; a worker claimed from the warm pool is discarded with its pool
564
+ row and never returned to the pool.
565
+ 4. Sub-agent runs it delegated that are still open are stopped too.
566
+
567
+ A run stopped before its worker started never starts one. See
568
+ [Stop or cancel a run](../help/stop-run.md).
569
+
570
+ ## Sub-agents
571
+
572
+ A sandboxed run can delegate to sub-agents, including several in parallel.
573
+ Sub-agents of a sandboxed run are always **managed runs**: the gateway records
574
+ the delegation, and the server's scheduler leader starts the child on its next
575
+ tick (about every 10 seconds). Each delegation therefore adds up to about ten
576
+ seconds of start-up latency, and `wardby serve` or `wardby scheduler` must be
577
+ running or the child never starts.
578
+
579
+ A child runs in its own configured mode (a `control-plane` child runs in the
580
+ server, a `sandbox` child in its own worker). Cancelling a parent run stops its
581
+ open children.
582
+
583
+ A coding agent (Codex or Claude Code) can be a child too. The gateway only
584
+ records the delegation. When the server's scheduler leader starts the child, the
585
+ server resolves its worker image (and the Claude Code tool-runner image), reads
586
+ `.wardby/services.yaml` and resolves its services, reads the knowledge bundle
587
+ index, and composes the final task. The gateway therefore needs no `CODING_*`
588
+ settings, and a gateway that sets them can drop them.
589
+
590
+ A problem with those, such as a `workerImageRef` that is not pinned by digest,
591
+ a toolchain with no image, an invalid or unavailable services declaration, an
592
+ unknown service, or a launcher that cannot run services, shows as the child run
593
+ ending `failed` or `refused` when it starts, with the same error code as at
594
+ dispatch. The parent's `delegate_to_*` call receives the child's result: for a
595
+ failed child `status: "failed"` with the `errorCode`, for a refused child the
596
+ refusal sentence. The full error is on the child run (see it with `get_run`). For agents not
597
+ in sandbox mode these errors still appear at dispatch. If creating a sub-agent
598
+ run fails unexpectedly during a sandboxed run's delegation, the delegating agent
599
+ receives a tool result `{"error":"dispatch_failed","message":"The sub-agent run
600
+ could not be created (<code>)."}` instead of the run failing.
601
+
602
+ **Upgrading:** upgrade `wardby serve` and `wardby scheduler` before or together
603
+ with the gateway. An older server starts such a child without resolving it: a Codex child
604
+ then runs on the deployment's default Codex image (ignoring its toolchain and
605
+ `workerImageRef`) and without its standing instructions, services, or knowledge
606
+ note, and a Claude Code child fails to start with
607
+ `coding_provider_not_configured:claude-code`.
608
+
609
+ ## Budget behavior
610
+
611
+ The gateway is the budget authority for sandboxed runs. Before each model call
612
+ it reserves that call's worst-case cost against the run's budget (and any
613
+ budget group), calls the provider, then settles at the actual usage. A call the
614
+ remaining budget cannot cover is refused and the run ends `budget_exhausted`
615
+ instead of overspending. The worker cannot raise or bypass its budget because it
616
+ never talks to the provider directly. A call that breaks off before its final
617
+ usage is settled at an estimate (never more than its reservation) and
618
+ included in the run's cost. The estimate is the call's input plus the output
619
+ streamed so far (text and tool calls), counted high. If the provider's response
620
+ had started but no output had arrived yet (for example while the model was
621
+ thinking or reasoning), the run's median completed reply is used, or no output
622
+ if there is none yet. A call that failed before the provider's response started is released,
623
+ because nothing was generated.
624
+
625
+ ## Failure modes
626
+
627
+ | Error code | Meaning | What to do |
628
+ | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
629
+ | [`native_sandbox_unavailable`](../help/errors/native-sandbox-unavailable.md) | Agent is in `sandbox` mode but the server has no native sandbox. Fails before any spend. | Configure the sandbox (steps above) or set the agent back to `control-plane`. |
630
+ | [`native_sandbox_worker_exited`](../help/errors/native-sandbox-worker-exited.md) | The worker ended without producing a result. | Check the tool code and the worker's memory and PID limits; run again. |
631
+ | [`native_sandbox_deadline_exceeded`](../help/errors/native-sandbox-deadline-exceeded.md) | The run passed its 60-minute maximum; the worker was stopped. | Split the work into smaller runs or sub-agents. |
632
+ | [`native_sandbox_worker_lost`](../help/errors/native-sandbox-worker-lost.md) | The worker container or pod disappeared (for example its host or node restarted). It is never relaunched. | Trigger the run again; check the Docker host or node stability. |
633
+ | [`native_sandbox_image_not_pinned`](../help/errors/native-sandbox-image-not-pinned.md) | `NATIVE_SANDBOX_WORKER_IMAGE` is a mutable tag. | Use a `repo@sha256:...` digest or a local image id. |
634
+ | [`native_sandbox_docker_failed`](../help/errors/native-sandbox-docker-failed.md) | A Docker command (pull, network create, connect, run) failed. | Read the message, then check the Docker daemon, image availability, and gateway name. |
635
+ | [`native_sandbox_network_unenforced`](../help/errors/native-sandbox-network-unenforced.md) | Kubernetes: the pod's egress isolation could not be proven in time; the pod was removed. | Check that the CNI enforces NetworkPolicy and the gateway Service exposes 8790 and 8791. |
636
+ | [`native_sandbox_isolation_mismatch`](../help/errors/native-sandbox-isolation-mismatch.md) | Kubernetes: the stored pod or NetworkPolicy differs from what Wardby built (an admission change). | Exempt the run namespace's native-run pods from mutating policies. |
637
+ | [`native_sandbox_gateway_unavailable`](../help/errors/native-sandbox-gateway-unavailable.md) | Kubernetes: the gateway Service is missing or has no ClusterIP. | Create the Service (ClusterIP, not headless) or fix `NATIVE_GATEWAY_SERVICE`. |
638
+ | [`native_sandbox_worker_unready`](../help/errors/native-sandbox-worker-unready.md) | Kubernetes: the worker pod did not reach Running in time. | Check image pull, quotas, and scheduling with `kubectl describe pod`. |
639
+ | [`native_sandbox_capacity`](../help/errors/native-sandbox-capacity.md) | `NATIVE_SANDBOX_MAX_CONCURRENT` runs are already active, or the namespace ResourceQuota is full. Not queued. | Wait and retry, or raise the cap together with the ResourceQuota. |
640
+ | [`native_sandbox_warm_delivery_failed`](../help/errors/native-sandbox-warm-delivery-failed.md) | A claimed warm worker could not receive the run's input and could not be confirmed stopped within 30 seconds. | Trigger the run again; check the node or Docker host and pod exec access. |
641
+ | [`native_sandbox_requires_catalog`](../help/errors/native-sandbox-requires-catalog.md) | No model catalog entry was recorded for the run: the process running it does not use the catalog-backed model router. | Run it on a standard `wardby serve`/`scheduler`/`mcp` process, or keep the agent on `control-plane`. |
642
+ | [`native_sandbox_gateway_error`](../help/errors/native-sandbox-gateway-error.md) | The worker's call to the gateway failed with an error the run could not continue from (`native_sandbox_gateway_error: <code>: <message>`; for `internal`, only `native_sandbox_gateway_error: internal: <cause code>`, never the message; the cause code is one of wardby's declared codes and never one that matches a secret value the run can read). | Read the code and message; for `internal` (`internal: <cause code>` when the gateway named one), read the gateway's logs. Trigger the run again. |
643
+
644
+ A run's error appears in its `error` field in `get_run` and `list_runs`.
645
+
646
+ For the gateway's `internal` code, the run's error carries a `causeCode` only
647
+ when the failing error's message led with one of wardby's own declared codes,
648
+ the gateway could read the run's secret values, and that code does not match
649
+ any of them; it is shown as `native_sandbox_gateway_error: internal: <causeCode>`.
650
+ Otherwise the error is just `native_sandbox_gateway_error: internal`. The
651
+ gateway's own log line (`native gateway request failed`) carries the error with
652
+ its message and stack, the run's secret values replaced by `[REDACTED]`, so the
653
+ message itself starts with the code; it has no separate `causeCode` field. Only
654
+ when the gateway could not read the run's secret values does the line carry just
655
+ the error's name (`errName`) and a `causeCode` field, with no message.
656
+ See [Native sandbox gateway error](../help/errors/native-sandbox-gateway-error.md).
657
+
658
+ ## Roll back
659
+
660
+ Set the agent back to `control-plane` with `update_agent` or
661
+ `wardby agent mode <name> control-plane`. Only new runs are
662
+ affected: runs already started in sandbox mode finish there. To switch sandbox mode off for the whole
663
+ deployment, unset `NATIVE_SANDBOX_LAUNCHER`; sandbox-mode agents then fail
664
+ closed with `native_sandbox_unavailable` rather than running unisolated, so move
665
+ them back to `control-plane` first if they should keep running.
666
+
667
+ ## Acceptance tests
668
+
669
+ Three opt-in checks exercise the real isolation against a real runtime. Each is
670
+ skipped unless its script sets its flag:
671
+
672
+ - `npm run test:native-docker`: the Docker launcher on the local Docker host.
673
+ - `npm run test:native-kind`: the Kubernetes launcher on a kind cluster
674
+ (`NATIVE_TEST_KIND_WORKER_IMAGE`).
675
+ - `npm run test:native-cluster`: launcher-only isolation checks against the
676
+ deployed gateway of any cluster. It needs no database or model. Set
677
+ `NATIVE_TEST_WORKER_IMAGE` (required, a registry digest) and, as needed,
678
+ `NATIVE_TEST_CONTEXT`, `NATIVE_TEST_NAMESPACE`, `NATIVE_TEST_PLATFORM`,
679
+ `NATIVE_TEST_RUNTIME_CLASS`, `NATIVE_TEST_PRIORITY_CLASS`, and
680
+ `NATIVE_TEST_FORBIDDEN`, a comma-separated list of `host:port` addresses that
681
+ must be unreachable from a worker (for example the database's private IP on
682
+ port 3307).
683
+
684
+ ## Troubleshooting
685
+
686
+ - **Gateway health.** `GET /healthz` on the gateway returns `{"ok":true}` when
687
+ its database answers and 503 otherwise. From the Docker host:
688
+ `docker exec wardby-native-gateway node -e "fetch('http://127.0.0.1:8790/healthz').then(r => r.text()).then(console.log)"`.
689
+ - **List worker containers.** Workers and networks carry the label
690
+ `io.wardby.component=native-worker`:
691
+ `docker ps --all --filter label=io.wardby.component=native-worker`.
692
+ The server removes finished workers and, at startup, sweeps leftovers whose
693
+ runs have ended or passed their deadline.
694
+ - **Kubernetes: list worker pods.** Run pods carry the label
695
+ `wardby.io/component=native-run`:
696
+ `kubectl get pods -n <namespace> -l wardby.io/component=native-run`.
697
+ The server removes finished pods (with their Secret and NetworkPolicy) and,
698
+ at startup, sweeps leftovers whose runs have ended or passed their deadline.
699
+ - **Kubernetes: gateway health.** `kubectl get deploy,svc,endpoints -n <namespace> wardby-native-gateway`;
700
+ the Service must list ports 8790 and 8791 and have ready endpoints.
701
+ - **Check a run.** Call `get_run` for the run's status and error code, then use
702
+ the matching error article from `search_help` or `get_help_article`.
703
+ - **A worker exited non-zero.** The server logs `native worker exited non-zero`
704
+ with the exit code and `stderrTail`, the last 2,000 characters of the worker's
705
+ output. Before logging it, the server masks the run's gateway capability and
706
+ every secret value the agent's tools can read as `[REDACTED]`. Encoded forms
707
+ of a value (URL-encoded, base64) are not matched. Instead of a tail, the line
708
+ may carry `stderrTailOmitted`: `secrets_unavailable` means one of those
709
+ secrets could not be read within 10 seconds, so the tail could not be
710
+ redacted; `log_read_failed` (Kubernetes) means the worker pod's log could not
711
+ be read within 10 seconds. Either way the run's failure is still recorded. On
712
+ Kubernetes the tail comes from the last 100 lines of the worker pod's log (the
713
+ launcher needs `get` on `pods/log`). That read may begin partway through a
714
+ line (the kubelet splits very long lines, and logs rotate), so its first few
715
+ dozen characters are always masked, more when an attached secret is long.
716
+ - **Workers cannot reach the gateway.** Confirm `NATIVE_GATEWAY_CONTAINER`
717
+ matches the running container's name exactly and that the gateway listens on
718
+ the port in `NATIVE_GATEWAY_URL` (default 8790).
719
+ - **Sub-agents never start.** Confirm `wardby serve` or `wardby scheduler` is
720
+ running; the scheduler leader starts them.
721
+ - **A tool's console output is missing.** If the gateway logs
722
+ `sandbox tool console line withheld: the tool's secret values could not be read`,
723
+ reading one of the tool's attached secrets failed. Without every value it
724
+ cannot redact the line, so it logs none of it. The tool call itself still
725
+ succeeds. Check the secret store and the tool's attached secrets.
726
+ - **Tool code fails inside the sandbox.** The worker has no network except the
727
+ gateway and a read-only filesystem apart from `/tmp`; tools must use the
728
+ provided fetch, datastore, and secret functions.
729
+
730
+ See also [Security deployment](security-deployment.md) and the
731
+ [runtime architecture](architecture-runtime.md).