@wardby/cli 0.5.3 → 0.6.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 (370) hide show
  1. package/.env.example +33 -0
  2. package/README.md +25 -14
  3. package/dist/claude-coding-worker/context.d.ts +22 -0
  4. package/dist/claude-coding-worker/context.js +92 -0
  5. package/dist/claude-coding-worker/driver.d.ts +7 -1
  6. package/dist/claude-coding-worker/driver.js +38 -5
  7. package/dist/claude-coding-worker/sdk.js +13 -4
  8. package/dist/cli-help.d.ts +1 -1
  9. package/dist/cli-help.js +5 -2
  10. package/dist/cli-native-mode.d.ts +9 -0
  11. package/dist/cli-native-mode.js +20 -0
  12. package/dist/cli.d.ts +3 -1
  13. package/dist/cli.js +141 -5
  14. package/dist/coding/claude-context.d.ts +45 -0
  15. package/dist/coding/claude-context.js +434 -0
  16. package/dist/coding/profile.d.ts +12 -0
  17. package/dist/coding/profile.js +6 -0
  18. package/dist/coding/protocol.d.ts +104 -0
  19. package/dist/coding/protocol.js +87 -3
  20. package/dist/coding-worker/artifact.d.ts +8 -0
  21. package/dist/coding-worker/artifact.js +2 -2
  22. package/dist/coding-worker/driver.js +2 -0
  23. package/dist/coding-worker/sdk.d.ts +6 -0
  24. package/dist/coding-worker/sdk.js +1 -0
  25. package/dist/coding-worker/skills.d.ts +23 -0
  26. package/dist/coding-worker/skills.js +117 -0
  27. package/dist/coding-worker/types.d.ts +2 -0
  28. package/dist/config/github-allowed-accounts.d.ts +15 -0
  29. package/dist/config/github-allowed-accounts.js +36 -0
  30. package/dist/config/low-power.d.ts +12 -0
  31. package/dist/config/low-power.js +18 -0
  32. package/dist/config/mobile.d.ts +12 -0
  33. package/dist/config/mobile.js +18 -0
  34. package/dist/config/providers.d.ts +53 -0
  35. package/dist/config/providers.js +92 -6
  36. package/dist/core/db.d.ts +16 -6
  37. package/dist/core/db.js +12 -10
  38. package/dist/core/dispatch.d.ts +11 -0
  39. package/dist/core/dispatch.js +36 -1
  40. package/dist/core/engine-native.js +9 -5
  41. package/dist/core/host-events.d.ts +49 -3
  42. package/dist/core/host-events.js +289 -15
  43. package/dist/core/issue-bridge.js +42 -2
  44. package/dist/core/issue-events.js +12 -1
  45. package/dist/core/issue-status.js +14 -3
  46. package/dist/core/merge-order-check.d.ts +129 -0
  47. package/dist/core/merge-order-check.js +336 -0
  48. package/dist/core/notification-dispatcher.d.ts +70 -0
  49. package/dist/core/notification-dispatcher.js +368 -0
  50. package/dist/core/notification-templates.d.ts +25 -0
  51. package/dist/core/notification-templates.js +105 -0
  52. package/dist/core/notifications.d.ts +10 -0
  53. package/dist/core/notifications.js +38 -0
  54. package/dist/core/pg-auth.d.ts +22 -0
  55. package/dist/core/pg-auth.js +152 -0
  56. package/dist/core/power-composition.d.ts +16 -0
  57. package/dist/core/power-composition.js +37 -0
  58. package/dist/core/power-idle.d.ts +14 -0
  59. package/dist/core/power-idle.js +30 -0
  60. package/dist/core/power.d.ts +71 -0
  61. package/dist/core/power.js +202 -0
  62. package/dist/core/reconciler.d.ts +4 -2
  63. package/dist/core/reconciler.js +29 -5
  64. package/dist/core/related-pull-requests.d.ts +48 -4
  65. package/dist/core/related-pull-requests.js +113 -11
  66. package/dist/core/repo-access.d.ts +15 -0
  67. package/dist/core/repo-access.js +66 -0
  68. package/dist/core/review-fix.d.ts +37 -0
  69. package/dist/core/review-fix.js +207 -6
  70. package/dist/core/review-host-tools.d.ts +20 -0
  71. package/dist/core/review-host-tools.js +58 -2
  72. package/dist/core/runner.d.ts +336 -3
  73. package/dist/core/runner.js +894 -317
  74. package/dist/core/secret-broker-config.d.ts +103 -0
  75. package/dist/core/secret-broker-config.js +112 -0
  76. package/dist/core/secrets.d.ts +39 -4
  77. package/dist/core/secrets.js +148 -40
  78. package/dist/core/workflow-event-recorder.d.ts +14 -0
  79. package/dist/core/workflow-event-recorder.js +120 -0
  80. package/dist/core/workflow-events.d.ts +82 -0
  81. package/dist/core/workflow-events.js +44 -0
  82. package/dist/core/workflow-run-events.d.ts +16 -0
  83. package/dist/core/workflow-run-events.js +40 -0
  84. package/dist/generated/prisma/browser.d.ts +58 -0
  85. package/dist/generated/prisma/client.d.ts +58 -0
  86. package/dist/generated/prisma/commonInputTypes.d.ts +150 -0
  87. package/dist/generated/prisma/enums.d.ts +27 -0
  88. package/dist/generated/prisma/enums.js +23 -0
  89. package/dist/generated/prisma/internal/class.d.ts +88 -0
  90. package/dist/generated/prisma/internal/class.js +4 -4
  91. package/dist/generated/prisma/internal/prismaNamespace.d.ts +772 -1
  92. package/dist/generated/prisma/internal/prismaNamespace.js +135 -4
  93. package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +139 -0
  94. package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +135 -4
  95. package/dist/generated/prisma/models/Agent.d.ts +360 -1
  96. package/dist/generated/prisma/models/CodingAgentProfile.d.ts +73 -1
  97. package/dist/generated/prisma/models/CodingRun.d.ts +205 -1
  98. package/dist/generated/prisma/models/DeferredReview.d.ts +78 -1
  99. package/dist/generated/prisma/models/NativeGatewayCall.d.ts +1675 -0
  100. package/dist/generated/prisma/models/NativeGatewayCall.js +1 -0
  101. package/dist/generated/prisma/models/NativeGatewaySession.d.ts +1517 -0
  102. package/dist/generated/prisma/models/NativeGatewaySession.js +1 -0
  103. package/dist/generated/prisma/models/NativeWarmWorker.d.ts +1296 -0
  104. package/dist/generated/prisma/models/NativeWarmWorker.js +1 -0
  105. package/dist/generated/prisma/models/NotificationChannel.d.ts +1543 -0
  106. package/dist/generated/prisma/models/NotificationChannel.js +1 -0
  107. package/dist/generated/prisma/models/NotificationDelivery.d.ts +1502 -0
  108. package/dist/generated/prisma/models/NotificationDelivery.js +1 -0
  109. package/dist/generated/prisma/models/NotificationThread.d.ts +1090 -0
  110. package/dist/generated/prisma/models/NotificationThread.js +1 -0
  111. package/dist/generated/prisma/models/Run.d.ts +826 -1
  112. package/dist/generated/prisma/models/RunHostCheck.d.ts +36 -1
  113. package/dist/generated/prisma/models/Secret.d.ts +37 -1
  114. package/dist/generated/prisma/models/SecretBrokerChange.d.ts +1101 -0
  115. package/dist/generated/prisma/models/SecretBrokerChange.js +1 -0
  116. package/dist/generated/prisma/models/WorkflowEvent.d.ts +1422 -0
  117. package/dist/generated/prisma/models/WorkflowEvent.js +1 -0
  118. package/dist/generated/prisma/models.d.ts +8 -0
  119. package/dist/help/build.js +4 -2
  120. package/dist/help/catalog.d.ts +1 -1
  121. package/dist/help/catalog.js +31 -6
  122. package/dist/help-index.json +1363 -176
  123. package/dist/import/create.js +17 -0
  124. package/dist/import/neutral-schema.d.ts +6 -2
  125. package/dist/import/neutral-schema.js +2 -0
  126. package/dist/mcp/auth/access.d.ts +1 -0
  127. package/dist/mcp/auth/repo-authorization.js +14 -0
  128. package/dist/mcp/auth/resource-server.d.ts +2 -1
  129. package/dist/mcp/auth/resource-server.js +7 -2
  130. package/dist/mcp/auth/self-hosted/browser.d.ts +1 -1
  131. package/dist/mcp/auth/self-hosted/browser.js +19 -6
  132. package/dist/mcp/context.d.ts +6 -0
  133. package/dist/mcp/host-events/github-ingress.d.ts +23 -1
  134. package/dist/mcp/host-events/github-ingress.js +68 -0
  135. package/dist/mcp/index.d.ts +13 -0
  136. package/dist/mcp/index.js +59 -10
  137. package/dist/mcp/tools/agents.js +82 -11
  138. package/dist/mcp/tools/notification-channels.d.ts +2 -0
  139. package/dist/mcp/tools/notification-channels.js +293 -0
  140. package/dist/mcp/tools/power.d.ts +2 -0
  141. package/dist/mcp/tools/power.js +77 -0
  142. package/dist/mcp/tools/runs.d.ts +0 -6
  143. package/dist/mcp/tools/runs.js +7 -2
  144. package/dist/mcp/tools/secret-broker-compat.d.ts +12 -0
  145. package/dist/mcp/tools/secret-broker-compat.js +23 -0
  146. package/dist/mcp/tools/secret-elicitation-form.d.ts +22 -2
  147. package/dist/mcp/tools/secret-elicitation-form.js +200 -10
  148. package/dist/mcp/tools/secret-elicitation-server.js +8 -1
  149. package/dist/mcp/tools/secret-elicitation.d.ts +38 -3
  150. package/dist/mcp/tools/secret-elicitation.js +110 -12
  151. package/dist/mcp/tools/secrets.js +184 -7
  152. package/dist/mcp/tools/tools.d.ts +1 -1
  153. package/dist/mcp/tools/tools.js +22 -2
  154. package/dist/native-worker/composition.d.ts +23 -0
  155. package/dist/native-worker/composition.js +77 -0
  156. package/dist/native-worker/docker-isolation.d.ts +65 -0
  157. package/dist/native-worker/docker-isolation.js +183 -0
  158. package/dist/native-worker/docker-launcher.d.ts +74 -0
  159. package/dist/native-worker/docker-launcher.js +237 -0
  160. package/dist/native-worker/gateway-server.d.ts +39 -0
  161. package/dist/native-worker/gateway-server.js +315 -0
  162. package/dist/native-worker/gateway.d.ts +44 -0
  163. package/dist/native-worker/gateway.js +197 -0
  164. package/dist/native-worker/http-server.d.ts +22 -0
  165. package/dist/native-worker/http-server.js +109 -0
  166. package/dist/native-worker/http-transport.d.ts +17 -0
  167. package/dist/native-worker/http-transport.js +88 -0
  168. package/dist/native-worker/kubernetes-isolation.d.ts +90 -0
  169. package/dist/native-worker/kubernetes-isolation.js +218 -0
  170. package/dist/native-worker/kubernetes-launcher.d.ts +102 -0
  171. package/dist/native-worker/kubernetes-launcher.js +335 -0
  172. package/dist/native-worker/launch.d.ts +45 -0
  173. package/dist/native-worker/launch.js +44 -0
  174. package/dist/native-worker/ledger.d.ts +109 -0
  175. package/dist/native-worker/ledger.js +192 -0
  176. package/dist/native-worker/loopback.d.ts +12 -0
  177. package/dist/native-worker/loopback.js +49 -0
  178. package/dist/native-worker/main.d.ts +7 -0
  179. package/dist/native-worker/main.js +74 -0
  180. package/dist/native-worker/protocol.d.ts +744 -0
  181. package/dist/native-worker/protocol.js +200 -0
  182. package/dist/native-worker/sandbox-executor.d.ts +68 -0
  183. package/dist/native-worker/sandbox-executor.js +210 -0
  184. package/dist/native-worker/stdio.d.ts +29 -0
  185. package/dist/native-worker/stdio.js +188 -0
  186. package/dist/native-worker/warm-delivery.d.ts +16 -0
  187. package/dist/native-worker/warm-delivery.js +33 -0
  188. package/dist/native-worker/warm-pool-ledger.d.ts +39 -0
  189. package/dist/native-worker/warm-pool-ledger.js +73 -0
  190. package/dist/native-worker/warm-pool.d.ts +107 -0
  191. package/dist/native-worker/warm-pool.js +283 -0
  192. package/dist/native-worker/worker.d.ts +17 -0
  193. package/dist/native-worker/worker.js +115 -0
  194. package/dist/providers/auth/authorization-server.d.ts +3 -0
  195. package/dist/providers/auth/index.js +2 -0
  196. package/dist/providers/auth/self-hosted.d.ts +13 -1
  197. package/dist/providers/auth/self-hosted.js +54 -4
  198. package/dist/providers/chat/fake.d.ts +46 -0
  199. package/dist/providers/chat/fake.js +39 -0
  200. package/dist/providers/chat/index.d.ts +4 -0
  201. package/dist/providers/chat/index.js +8 -0
  202. package/dist/providers/chat/slack.d.ts +37 -0
  203. package/dist/providers/chat/slack.js +105 -0
  204. package/dist/providers/chat/types.d.ts +42 -0
  205. package/dist/providers/chat/types.js +19 -0
  206. package/dist/providers/engine/types.d.ts +19 -0
  207. package/dist/providers/engine/types.js +22 -0
  208. package/dist/providers/executor/composition.d.ts +24 -1
  209. package/dist/providers/executor/composition.js +39 -6
  210. package/dist/providers/executor/container.d.ts +24 -1
  211. package/dist/providers/executor/container.js +101 -11
  212. package/dist/providers/executor/dbos.d.ts +42 -0
  213. package/dist/providers/executor/dbos.js +118 -12
  214. package/dist/providers/executor/deferred.d.ts +56 -0
  215. package/dist/providers/executor/deferred.js +119 -0
  216. package/dist/providers/executor/routing.d.ts +37 -10
  217. package/dist/providers/executor/routing.js +73 -32
  218. package/dist/providers/executor/types.d.ts +12 -0
  219. package/dist/providers/jobs/docker.js +3 -3
  220. package/dist/providers/jobs/fake-kubernetes-api.d.ts +21 -2
  221. package/dist/providers/jobs/fake-kubernetes-api.js +42 -1
  222. package/dist/providers/jobs/kubernetes-api.d.ts +17 -1
  223. package/dist/providers/jobs/kubernetes-api.js +7 -0
  224. package/dist/providers/jobs/kubernetes-client.d.ts +10 -1
  225. package/dist/providers/jobs/kubernetes-client.js +52 -3
  226. package/dist/providers/jobs/kubernetes-dry-run-fixture.d.ts +6 -1
  227. package/dist/providers/jobs/kubernetes-dry-run-fixture.js +6 -3
  228. package/dist/providers/jobs/kubernetes-isolation.d.ts +3 -1
  229. package/dist/providers/jobs/kubernetes-isolation.js +6 -0
  230. package/dist/providers/jobs/kubernetes-platform.d.ts +4 -1
  231. package/dist/providers/jobs/kubernetes-platform.js +38 -1
  232. package/dist/providers/jobs/kubernetes-preflight.d.ts +2 -1
  233. package/dist/providers/jobs/kubernetes-preflight.js +4 -2
  234. package/dist/providers/jobs/kubernetes.d.ts +36 -1
  235. package/dist/providers/jobs/kubernetes.js +74 -4
  236. package/dist/providers/jobs/metadata-probes.d.ts +11 -0
  237. package/dist/providers/jobs/metadata-probes.js +13 -0
  238. package/dist/providers/jobs/types.d.ts +9 -0
  239. package/dist/providers/review-host/github.d.ts +11 -1
  240. package/dist/providers/review-host/github.js +50 -0
  241. package/dist/providers/review-host/types.d.ts +23 -0
  242. package/dist/providers/vcs/github.d.ts +32 -6
  243. package/dist/providers/vcs/github.js +74 -16
  244. package/dist/quickstart/coding-seed.d.ts +10 -3
  245. package/dist/quickstart/coding-seed.js +74 -3
  246. package/dist/quickstart/images.d.ts +2 -0
  247. package/dist/quickstart/images.js +7 -1
  248. package/dist/quickstart/reviewer-prompt.d.ts +1 -1
  249. package/dist/quickstart/reviewer-prompt.js +1 -1
  250. package/dist/quickstart-images.json +1 -1
  251. package/dist/sandbox/brokered-fetch.d.ts +23 -0
  252. package/dist/sandbox/brokered-fetch.js +37 -0
  253. package/dist/sandbox/host-functions.d.ts +34 -0
  254. package/dist/sandbox/host-functions.js +144 -80
  255. package/dist/sandbox/prelude.js +7 -1
  256. package/dist/sandbox/run-in-sandbox.d.ts +19 -0
  257. package/dist/sandbox/run-in-sandbox.js +28 -10
  258. package/dist/sandbox/safe-fetch.d.ts +2 -0
  259. package/dist/sandbox/safe-fetch.js +3 -1
  260. package/dist/sandbox/secret-broker-sigv4.d.ts +2 -0
  261. package/dist/sandbox/secret-broker-sigv4.js +49 -0
  262. package/dist/sandbox/secret-broker.d.ts +34 -0
  263. package/dist/sandbox/secret-broker.js +162 -0
  264. package/dist/sandbox/user-tool.d.ts +14 -0
  265. package/dist/sandbox/user-tool.js +32 -0
  266. package/dist/serve.js +18 -0
  267. package/dist/viewer/api-schema.d.ts +210 -14
  268. package/dist/viewer/api-schema.js +22 -0
  269. package/dist/viewer/build-schemas.js +4 -1
  270. package/dist/viewer/event-bus.d.ts +6 -0
  271. package/dist/viewer/event-bus.js +16 -7
  272. package/dist/viewer/graph.d.ts +5 -2
  273. package/dist/viewer/graph.js +7 -2
  274. package/dist/viewer/http.d.ts +0 -1
  275. package/dist/viewer/http.js +2 -2
  276. package/dist/viewer/infra.js +25 -2
  277. package/dist/viewer/limits.d.ts +4 -0
  278. package/dist/viewer/limits.js +4 -0
  279. package/dist/viewer/openapi.d.ts +15 -0
  280. package/dist/viewer/openapi.js +172 -0
  281. package/docs/README.md +7 -0
  282. package/docs/agent-recipes.md +57 -8
  283. package/docs/architecture-runtime.md +16 -1
  284. package/docs/code-review-agents.md +139 -5
  285. package/docs/coding-agent-setup.md +113 -5
  286. package/docs/coding-packages.md +4 -2
  287. package/docs/coding-services.md +3 -1
  288. package/docs/coding-worker-byo-images.md +198 -6
  289. package/docs/coding-worker-isolation.md +68 -14
  290. package/docs/getting-started-gke.md +225 -9
  291. package/docs/getting-started-identity-provider.md +21 -10
  292. package/docs/getting-started.md +5 -4
  293. package/docs/jira-agents.md +5 -1
  294. package/docs/native-sandbox.md +635 -0
  295. package/docs/release-verification.md +9 -0
  296. package/docs/security-deployment.md +113 -12
  297. package/docs/slack-notifications.md +252 -0
  298. package/docs/tool-secrets.md +252 -0
  299. package/docs/viewer-api.md +46 -5
  300. package/docs/viewer-api.openapi.yml +1404 -0
  301. package/help/admin-viewer.md +6 -2
  302. package/help/agent-recipes.md +27 -0
  303. package/help/architecture-agent.md +1 -1
  304. package/help/brokered-secrets.md +79 -0
  305. package/help/build-claude-code-image.md +131 -0
  306. package/help/build-worker-image.md +3 -6
  307. package/help/code-review-agents.md +68 -6
  308. package/help/deploy-gke.md +8 -1
  309. package/help/deployment-targets.md +25 -14
  310. package/help/errors/coding-provider-not-configured.md +2 -2
  311. package/help/errors/database-auth-invalid.md +28 -0
  312. package/help/errors/github-account-not-allowed.md +25 -0
  313. package/help/errors/low-power-disabled.md +29 -0
  314. package/help/errors/low-power-scale-forbidden.md +35 -0
  315. package/help/errors/low-power-wake-timeout.md +30 -0
  316. package/help/errors/mobile-disabled.md +31 -0
  317. package/help/errors/native-sandbox-capacity.md +22 -0
  318. package/help/errors/native-sandbox-deadline-exceeded.md +19 -0
  319. package/help/errors/native-sandbox-docker-failed.md +20 -0
  320. package/help/errors/native-sandbox-gateway-unavailable.md +21 -0
  321. package/help/errors/native-sandbox-image-not-pinned.md +19 -0
  322. package/help/errors/native-sandbox-isolation-mismatch.md +20 -0
  323. package/help/errors/native-sandbox-network-unenforced.md +22 -0
  324. package/help/errors/native-sandbox-requires-catalog.md +31 -0
  325. package/help/errors/native-sandbox-unavailable.md +19 -0
  326. package/help/errors/native-sandbox-warm-delivery-failed.md +21 -0
  327. package/help/errors/native-sandbox-worker-exited.md +20 -0
  328. package/help/errors/native-sandbox-worker-lost.md +20 -0
  329. package/help/errors/native-sandbox-worker-unready.md +22 -0
  330. package/help/errors/secret-broker-body-invalid.md +26 -0
  331. package/help/errors/secret-broker-changed.md +20 -0
  332. package/help/errors/secret-broker-config-invalid.md +30 -0
  333. package/help/errors/secret-broker-conflict.md +27 -0
  334. package/help/errors/secret-broker-destination-denied.md +28 -0
  335. package/help/errors/secret-broker-value-invalid.md +28 -0
  336. package/help/errors/secret-brokered.md +24 -0
  337. package/help/errors/secret-not-brokered.md +25 -0
  338. package/help/errors/slack-auth-failed.md +48 -0
  339. package/help/errors/slack-channel-unreachable.md +39 -0
  340. package/help/errors/slack-not-configured.md +33 -0
  341. package/help/getting-started.md +4 -5
  342. package/help/github.md +18 -1
  343. package/help/identity-and-access.md +5 -1
  344. package/help/local-repositories.md +2 -3
  345. package/help/low-power-mode.md +125 -0
  346. package/help/merge-order-check.md +117 -0
  347. package/help/mobile-app.md +54 -0
  348. package/help/native-sandbox.md +136 -0
  349. package/help/observability.md +8 -0
  350. package/help/related-pull-requests.md +70 -9
  351. package/help/repo-instructions-and-skills.md +91 -0
  352. package/help/review-fix-rounds.md +10 -0
  353. package/help/slack-notifications.md +62 -0
  354. package/help/troubleshooting/coding-workers.md +21 -0
  355. package/package.json +11 -4
  356. package/prisma/migrations/20261009000003_native_execution_mode/migration.sql +12 -0
  357. package/prisma/migrations/20261009000004_native_gateway_ledger/migration.sql +65 -0
  358. package/prisma/migrations/20261009000005_native_gateway_call_child_agent/migration.sql +5 -0
  359. package/prisma/migrations/20261009000006_run_deferred_start_stop/migration.sql +14 -0
  360. package/prisma/migrations/20261009000007_native_gateway_network_ready/migration.sql +5 -0
  361. package/prisma/migrations/20261010000001_workflow_notifications/migration.sql +99 -0
  362. package/prisma/migrations/20261011000001_native_gateway_session_status_index/migration.sql +2 -0
  363. package/prisma/migrations/20261012000001_native_warm_worker/migration.sql +32 -0
  364. package/prisma/migrations/20261013000001_coding_run_merge_order/migration.sql +2 -0
  365. package/prisma/migrations/20261013000001_secret_broker/migration.sql +17 -0
  366. package/prisma/migrations/20261013000002_deferred_review_request/migration.sql +4 -0
  367. package/prisma/migrations/20261014000000_repo_skills/migration.sql +15 -0
  368. package/prisma/migrations/20261015000001_coding_run_merge_order_index/migration.sql +2 -0
  369. package/prisma/migrations/20261015000002_no_change_rereview/migration.sql +2 -0
  370. package/prisma/schema.prisma +362 -91
@@ -0,0 +1,44 @@
1
+ /**
2
+ * The trusted side of the native sandbox worker contract. `runSandboxedEngine`
3
+ * is an Engine in all but name: the runner hands it the same context it would
4
+ * hand NativeEngine, and it returns an EngineResult — but the turn loop runs
5
+ * in a worker, and this module serves the worker's calls from that context.
6
+ *
7
+ * Authority stays here (invariant 8 of the plan): model usage and cost are
8
+ * metered from what the provider streamed through this gateway, never taken
9
+ * from the worker; every call is validated against the protocol schemas and
10
+ * refused once the run is no longer drivable; built-in tools and privileged
11
+ * sandbox bridges are served only by name from the run's own surface.
12
+ */
13
+ import type { EngineResult, EngineRunContext } from "../providers/engine/types.js";
14
+ import type { LlmStreamEvent } from "../providers/llm/types.js";
15
+ import { type PrivilegedHost } from "../sandbox/host-functions.js";
16
+ import { type WorkerInput } from "./protocol.js";
17
+ /** The trusted gateway as a transport sees it: untrusted requests in, results or GatewayErrors out. */
18
+ export interface NativeGateway {
19
+ call(request: unknown): Promise<unknown>;
20
+ stream(request: unknown): AsyncIterable<LlmStreamEvent>;
21
+ }
22
+ /** Starts a worker for `input`, lets it call `gateway`, and resolves when it exits. */
23
+ export interface WorkerLauncher {
24
+ run(input: WorkerInput, gateway: NativeGateway, signal: AbortSignal): Promise<{
25
+ exitCode: number | null;
26
+ }>;
27
+ }
28
+ /** Where a run stands, read live on every call. */
29
+ export type RunDrivability = "drivable" | "cancelled" | "ended";
30
+ /** Thrown when the worker stopped because the run was cancelled; the runner records `cancelled`. */
31
+ export declare class SandboxRunCancelledError extends Error {
32
+ }
33
+ export interface SandboxedEngineOptions {
34
+ runId: string;
35
+ input: WorkerInput;
36
+ /** The context the runner would hand NativeEngine: the run-bound LLM, onText, and onProgress. */
37
+ ctx: Pick<EngineRunContext, "providers" | "onText" | "onProgress">;
38
+ builtinHandler: (name: string) => ((argsJson: string) => Promise<string>) | undefined;
39
+ privilegedHostFor: (tool: string, signal: AbortSignal) => PrivilegedHost | undefined;
40
+ drivability: () => Promise<RunDrivability>;
41
+ launcher: WorkerLauncher;
42
+ }
43
+ /** Runs one native run's engine in a worker and returns its result with gateway-metered usage. */
44
+ export declare function runSandboxedEngine(options: SandboxedEngineOptions): Promise<EngineResult>;
@@ -0,0 +1,197 @@
1
+ /**
2
+ * The trusted side of the native sandbox worker contract. `runSandboxedEngine`
3
+ * is an Engine in all but name: the runner hands it the same context it would
4
+ * hand NativeEngine, and it returns an EngineResult — but the turn loop runs
5
+ * in a worker, and this module serves the worker's calls from that context.
6
+ *
7
+ * Authority stays here (invariant 8 of the plan): model usage and cost are
8
+ * metered from what the provider streamed through this gateway, never taken
9
+ * from the worker; every call is validated against the protocol schemas and
10
+ * refused once the run is no longer drivable; built-in tools and privileged
11
+ * sandbox bridges are served only by name from the run's own surface.
12
+ */
13
+ import { isPrivilegedBridgeName } from "../sandbox/host-functions.js";
14
+ import { logger } from "../core/logger.js";
15
+ import { GatewayError, GatewayRequestSchema, NATIVE_WORKER_PROTOCOL_VERSION, parseParams, ProtocolError, } from "./protocol.js";
16
+ const gatewayLog = logger.child({ module: "native-gateway" });
17
+ /** Thrown when the worker stopped because the run was cancelled; the runner records `cancelled`. */
18
+ export class SandboxRunCancelledError extends Error {
19
+ }
20
+ /** Runs one native run's engine in a worker and returns its result with gateway-metered usage. */
21
+ export async function runSandboxedEngine(options) {
22
+ const { runId, input, ctx } = options;
23
+ const llm = ctx.providers.llm;
24
+ const controller = new AbortController();
25
+ const usage = { tokensIn: 0, tokensOut: 0, costUsd: 0, cachedInputTokens: 0, cacheWriteTokens: 0 };
26
+ const usedCallIds = new Set();
27
+ const builtinResults = new Map();
28
+ const hosts = new Map();
29
+ let lastTextSeq = -1;
30
+ let finished;
31
+ let cancelled = false;
32
+ const meter = (event) => {
33
+ usage.tokensIn += event.inputTokens;
34
+ usage.tokensOut += event.outputTokens;
35
+ usage.costUsd += event.costUsd;
36
+ usage.cachedInputTokens += event.cachedInputTokens ?? 0;
37
+ usage.cacheWriteTokens += event.cacheWriteTokens ?? 0;
38
+ };
39
+ /** Validates the envelope and the run, and claims the callId; returns the method's params. */
40
+ const admit = async (raw, expected) => {
41
+ const parsed = GatewayRequestSchema.safeParse(raw);
42
+ if (!parsed.success) {
43
+ const v = raw?.v;
44
+ if (v !== undefined && v !== NATIVE_WORKER_PROTOCOL_VERSION) {
45
+ throw new GatewayError("invalid_request", new ProtocolError("unsupported_protocol_version").message);
46
+ }
47
+ throw new GatewayError("invalid_request", parsed.error.issues[0]?.message ?? "invalid request");
48
+ }
49
+ const request = parsed.data;
50
+ if (request.runId !== runId)
51
+ throw new GatewayError("not_allowed", "request for another run");
52
+ if (expected && request.method !== expected)
53
+ throw new GatewayError("invalid_request", "wrong method");
54
+ let params;
55
+ try {
56
+ params = parseParams(request.method, request.params);
57
+ }
58
+ catch (err) {
59
+ throw new GatewayError("invalid_request", err instanceof Error ? err.message : String(err));
60
+ }
61
+ const state = await options.drivability();
62
+ if (state !== "drivable") {
63
+ if (state === "cancelled")
64
+ cancelled = true;
65
+ controller.abort();
66
+ throw new GatewayError("run_not_drivable", "This run is no longer running.");
67
+ }
68
+ return { request, params };
69
+ };
70
+ const claim = (callId) => {
71
+ if (usedCallIds.has(callId))
72
+ throw new GatewayError("duplicate_call", `callId "${callId}" was already used.`);
73
+ usedCallIds.add(callId);
74
+ };
75
+ const gateway = {
76
+ async *stream(raw) {
77
+ const { request, params } = await admit(raw, "llm.stream");
78
+ claim(request.callId);
79
+ // The worker may only call the run's own pinned model.
80
+ if (params.request.model !== input.agent.model) {
81
+ throw new GatewayError("not_allowed", "A run may only call its own model.");
82
+ }
83
+ const req = params.request;
84
+ let sawDone = false;
85
+ let streamedText = "";
86
+ try {
87
+ for await (const event of llm.stream(req, controller.signal)) {
88
+ if (event.type === "done") {
89
+ sawDone = true;
90
+ meter(event.usage);
91
+ }
92
+ else if (event.type === "text") {
93
+ streamedText += event.delta;
94
+ }
95
+ yield event;
96
+ }
97
+ }
98
+ finally {
99
+ // The worker stopped reading (its own mid-stream budget cutoff, or it went away) before the
100
+ // provider reported usage: bill this gateway's own estimate of what was streamed, so an
101
+ // aborted call is never free.
102
+ if (!sawDone) {
103
+ const inputTokens = await llm.countTokens(req.model, req.messages, req.tools).catch(() => 0);
104
+ const outputTokens = streamedText
105
+ ? await llm.countTokens(req.model, [{ role: "assistant", content: streamedText }]).catch(() => 0)
106
+ : 0;
107
+ meter({ inputTokens, outputTokens, costUsd: llm.priceUsd(req.model, { inputTokens, outputTokens }) });
108
+ }
109
+ }
110
+ },
111
+ async call(raw) {
112
+ const { request, params } = await admit(raw);
113
+ switch (request.method) {
114
+ case "llm.countTokens": {
115
+ const p = params;
116
+ return llm.countTokens(p.model, p.messages, p.tools);
117
+ }
118
+ case "builtin.call": {
119
+ const p = params;
120
+ // A repeated callId for a finished built-in returns the same result instead of acting twice.
121
+ const prior = builtinResults.get(request.callId);
122
+ if (prior)
123
+ return prior;
124
+ const handler = input.builtinTools.includes(p.name) ? options.builtinHandler(p.name) : undefined;
125
+ if (!handler)
126
+ throw new GatewayError("not_allowed", `"${p.name}" is not a built-in tool of this run.`);
127
+ const result = handler(p.argsJson);
128
+ builtinResults.set(request.callId, result);
129
+ return result;
130
+ }
131
+ case "host.call": {
132
+ const p = params;
133
+ claim(request.callId);
134
+ if (!isPrivilegedBridgeName(p.bridge))
135
+ throw new GatewayError("not_allowed", "unknown bridge");
136
+ const key = `${p.tool}\u0000${p.invocation}`;
137
+ let host = hosts.get(key);
138
+ if (!host) {
139
+ host = options.privilegedHostFor(p.tool, controller.signal);
140
+ if (!host)
141
+ throw new GatewayError("not_allowed", `"${p.tool}" is not a user tool of this run.`);
142
+ hosts.set(key, host);
143
+ }
144
+ try {
145
+ return await host[p.bridge](p.argsJson);
146
+ }
147
+ catch (err) {
148
+ // What the tool sees, exactly as in-process (bridge.ts truncates the same way).
149
+ const message = err instanceof Error ? err.message.slice(0, 1024) : "Host function failed.";
150
+ throw new GatewayError("bridge_error", message);
151
+ }
152
+ }
153
+ case "progress": {
154
+ const p = params;
155
+ // Turns from the worker, usage from this gateway's own metering.
156
+ const progress = {
157
+ turns: p.turns,
158
+ usage: { tokensIn: usage.tokensIn, tokensOut: usage.tokensOut, costUsd: usage.costUsd },
159
+ };
160
+ await ctx.onProgress?.(progress);
161
+ return null;
162
+ }
163
+ case "text": {
164
+ const p = params;
165
+ if (p.seq > lastTextSeq) {
166
+ lastTextSeq = p.seq;
167
+ ctx.onText?.(p.delta);
168
+ }
169
+ return null;
170
+ }
171
+ case "finish": {
172
+ claim(request.callId);
173
+ finished ??= params;
174
+ return null;
175
+ }
176
+ default:
177
+ throw new GatewayError("invalid_request", `"${request.method}" is a streaming method.`);
178
+ }
179
+ },
180
+ };
181
+ const { exitCode } = await options.launcher.run(input, gateway, controller.signal);
182
+ controller.abort();
183
+ if (cancelled || (!finished && (await options.drivability()) === "cancelled")) {
184
+ throw new SandboxRunCancelledError("The run was cancelled while its sandbox worker was running.");
185
+ }
186
+ if (!finished) {
187
+ gatewayLog.warn({ runId, exitCode }, "native sandbox worker exited without a result");
188
+ throw new Error(`native_sandbox_worker_exited: the sandbox worker exited (code ${exitCode}) without a result.`);
189
+ }
190
+ return {
191
+ status: finished.status,
192
+ finalText: finished.finalText,
193
+ turns: finished.turns,
194
+ ...(finished.error !== undefined ? { error: finished.error } : {}),
195
+ usage,
196
+ };
197
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * The native sandbox gateway's internal HTTP listener (NATIVE_GATEWAY_LISTEN).
3
+ * Deliberately separate from the public MCP/webhook server: only sandbox
4
+ * workers reach it (deployment network policy allows worker → this port and
5
+ * nothing else), and every request carries a one-run bearer capability.
6
+ *
7
+ * POST /native-gateway/v1/call body: GatewayRequest
8
+ * → application/json { ok: true, result } | { ok: false, error: { code, message } }
9
+ * → application/x-ndjson (llm.stream) { event } … then { end: true } or { error }
10
+ */
11
+ import { type Server } from "node:http";
12
+ import { type GatewayServerDeps } from "./gateway-server.js";
13
+ export declare const NATIVE_GATEWAY_PATH = "/native-gateway/v1/call";
14
+ export interface NativeGatewayListen {
15
+ host: string;
16
+ port: number;
17
+ }
18
+ /** Parses NATIVE_GATEWAY_LISTEN ("host:port" or ":port"); undefined when unset. */
19
+ export declare function parseGatewayListen(value: string | undefined): NativeGatewayListen | undefined;
20
+ export declare function createGatewayServer(deps: GatewayServerDeps): Server;
21
+ /** Starts the listener; resolves once it is accepting connections. */
22
+ export declare function startGatewayServer(listen: NativeGatewayListen, deps: GatewayServerDeps): Promise<Server>;
@@ -0,0 +1,109 @@
1
+ /**
2
+ * The native sandbox gateway's internal HTTP listener (NATIVE_GATEWAY_LISTEN).
3
+ * Deliberately separate from the public MCP/webhook server: only sandbox
4
+ * workers reach it (deployment network policy allows worker → this port and
5
+ * nothing else), and every request carries a one-run bearer capability.
6
+ *
7
+ * POST /native-gateway/v1/call body: GatewayRequest
8
+ * → application/json { ok: true, result } | { ok: false, error: { code, message } }
9
+ * → application/x-ndjson (llm.stream) { event } … then { end: true } or { error }
10
+ */
11
+ import { createServer } from "node:http";
12
+ import { logger } from "../core/logger.js";
13
+ import { serveGatewayRequest } from "./gateway-server.js";
14
+ import { GatewayError, MAX_MESSAGE_BYTES } from "./protocol.js";
15
+ const httpLog = logger.child({ module: "native-gateway-http" });
16
+ export const NATIVE_GATEWAY_PATH = "/native-gateway/v1/call";
17
+ /** Parses NATIVE_GATEWAY_LISTEN ("host:port" or ":port"); undefined when unset. */
18
+ export function parseGatewayListen(value) {
19
+ if (!value)
20
+ return undefined;
21
+ const match = /^(.*):(\d{1,5})$/.exec(value.trim());
22
+ const port = match ? Number(match[2]) : NaN;
23
+ if (!match || !Number.isInteger(port) || port < 1 || port > 65_535) {
24
+ throw new Error(`NATIVE_GATEWAY_LISTEN must be host:port or :port (got "${value}").`);
25
+ }
26
+ return { host: match[1] || "0.0.0.0", port };
27
+ }
28
+ function readBody(req) {
29
+ return new Promise((resolve, reject) => {
30
+ let size = 0;
31
+ const chunks = [];
32
+ req.on("data", (chunk) => {
33
+ size += chunk.length;
34
+ if (size > MAX_MESSAGE_BYTES) {
35
+ reject(new GatewayError("invalid_request", "message_too_large"));
36
+ req.destroy();
37
+ return;
38
+ }
39
+ chunks.push(chunk);
40
+ });
41
+ req.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
42
+ req.on("error", reject);
43
+ });
44
+ }
45
+ export function createGatewayServer(deps) {
46
+ return createServer({ maxHeaderSize: 16 * 1024 }, (req, res) => {
47
+ void (async () => {
48
+ const send = (status, body) => {
49
+ res.setHeader("content-type", "application/json");
50
+ res.writeHead(status);
51
+ res.end(JSON.stringify(body));
52
+ };
53
+ if (req.method === "GET" && req.url === "/healthz") {
54
+ // Ready when the database answers: every call needs it.
55
+ const healthy = await deps.db.$queryRaw `SELECT 1`.then(() => true, () => false);
56
+ send(healthy ? 200 : 503, { ok: healthy });
57
+ return;
58
+ }
59
+ if (req.method !== "POST" || req.url !== NATIVE_GATEWAY_PATH) {
60
+ send(404, { ok: false, error: { code: "not_found", message: "not found" } });
61
+ return;
62
+ }
63
+ let body;
64
+ try {
65
+ body = JSON.parse(await readBody(req));
66
+ }
67
+ catch (err) {
68
+ send(400, {
69
+ ok: false,
70
+ error: { code: "invalid_request", message: err instanceof GatewayError ? err.message : "body is not JSON" },
71
+ });
72
+ return;
73
+ }
74
+ const response = await serveGatewayRequest(deps, req.headers.authorization, body);
75
+ if (response.kind === "json") {
76
+ send(response.status, response.body);
77
+ return;
78
+ }
79
+ res.setHeader("content-type", "application/x-ndjson");
80
+ res.writeHead(200);
81
+ try {
82
+ for await (const event of response.events)
83
+ res.write(`${JSON.stringify({ event })}\n`);
84
+ res.end(`${JSON.stringify({ end: true })}\n`);
85
+ }
86
+ catch (err) {
87
+ const error = err instanceof GatewayError
88
+ ? { code: err.code, message: err.message }
89
+ : { code: "internal", message: err instanceof Error ? err.message : String(err) };
90
+ res.end(`${JSON.stringify({ error })}\n`);
91
+ }
92
+ })().catch((err) => {
93
+ httpLog.error({ err }, "native gateway HTTP handler failed");
94
+ if (!res.headersSent)
95
+ res.writeHead(500);
96
+ res.end();
97
+ });
98
+ });
99
+ }
100
+ /** Starts the listener; resolves once it is accepting connections. */
101
+ export async function startGatewayServer(listen, deps) {
102
+ const server = createGatewayServer(deps);
103
+ await new Promise((resolve, reject) => {
104
+ server.once("error", reject);
105
+ server.listen(listen.port, listen.host, () => resolve());
106
+ });
107
+ httpLog.info({ host: listen.host, port: listen.port }, "native sandbox gateway listening");
108
+ return server;
109
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * The worker's HTTP transport to the native sandbox gateway. One-shot calls are
3
+ * retried with the same request (same callId) on a connection failure until a
4
+ * deadline, so a control-plane replica restarting is a retry, not a failure:
5
+ * the gateway replays a finished call's result instead of acting again. A
6
+ * model stream is never retried — its reservation is already taken.
7
+ */
8
+ import type { GatewayTransport } from "./worker.js";
9
+ export interface HttpTransportOptions {
10
+ url: string;
11
+ capability: string;
12
+ fetch?: typeof globalThis.fetch;
13
+ /** How long a one-shot call keeps retrying connection failures. */
14
+ retryForMs?: number;
15
+ sleep?: (ms: number) => Promise<void>;
16
+ }
17
+ export declare function createHttpTransport(options: HttpTransportOptions): GatewayTransport;
@@ -0,0 +1,88 @@
1
+ /**
2
+ * The worker's HTTP transport to the native sandbox gateway. One-shot calls are
3
+ * retried with the same request (same callId) on a connection failure until a
4
+ * deadline, so a control-plane replica restarting is a retry, not a failure:
5
+ * the gateway replays a finished call's result instead of acting again. A
6
+ * model stream is never retried — its reservation is already taken.
7
+ */
8
+ import { GatewayError } from "./protocol.js";
9
+ const RETRY_DELAYS_MS = [100, 250, 500, 1_000, 2_000, 4_000];
10
+ export function createHttpTransport(options) {
11
+ const fetchImpl = options.fetch ?? globalThis.fetch;
12
+ const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
13
+ const retryForMs = options.retryForMs ?? 120_000;
14
+ const post = (request) => fetchImpl(options.url, {
15
+ method: "POST",
16
+ headers: { "content-type": "application/json", authorization: `Bearer ${options.capability}` },
17
+ body: JSON.stringify(request),
18
+ });
19
+ const gatewayError = (error, status) => new GatewayError((error?.code ?? "internal"), error?.message ?? `gateway answered ${status}`);
20
+ return {
21
+ async call(request) {
22
+ const giveUpAt = Date.now() + retryForMs;
23
+ for (let attempt = 0;; attempt += 1) {
24
+ let response;
25
+ try {
26
+ response = await post(request);
27
+ }
28
+ catch (err) {
29
+ if (Date.now() >= giveUpAt) {
30
+ throw new GatewayError("internal", `gateway unreachable: ${err instanceof Error ? err.message : String(err)}`);
31
+ }
32
+ await sleep(RETRY_DELAYS_MS[Math.min(attempt, RETRY_DELAYS_MS.length - 1)]);
33
+ continue;
34
+ }
35
+ const body = (await response.json().catch(() => undefined));
36
+ if (body?.ok === true)
37
+ return body.result;
38
+ // Isolation not proven yet (a pod's NetworkPolicy is still being programmed): wait and ask again.
39
+ if (body?.ok === false && body.error.code === "not_ready" && Date.now() < giveUpAt) {
40
+ await sleep(RETRY_DELAYS_MS[Math.min(attempt, RETRY_DELAYS_MS.length - 1)]);
41
+ continue;
42
+ }
43
+ throw gatewayError(body?.ok === false ? body.error : undefined, response.status);
44
+ }
45
+ },
46
+ async *stream(request) {
47
+ const giveUpAt = Date.now() + retryForMs;
48
+ let response;
49
+ for (let attempt = 0;; attempt += 1) {
50
+ try {
51
+ response = await post(request);
52
+ }
53
+ catch (err) {
54
+ throw new GatewayError("internal", `gateway unreachable: ${err instanceof Error ? err.message : String(err)}`);
55
+ }
56
+ if (response.headers.get("content-type")?.includes("application/x-ndjson") && response.body)
57
+ break;
58
+ const body = (await response.json().catch(() => undefined));
59
+ // Refused before any reservation was taken, so asking again is safe.
60
+ if (body?.error?.code === "not_ready" && Date.now() < giveUpAt) {
61
+ await sleep(RETRY_DELAYS_MS[Math.min(attempt, RETRY_DELAYS_MS.length - 1)]);
62
+ continue;
63
+ }
64
+ throw gatewayError(body?.error, response.status);
65
+ }
66
+ const decoder = new TextDecoder();
67
+ let buffer = "";
68
+ for await (const chunk of response.body) {
69
+ buffer += decoder.decode(chunk, { stream: true });
70
+ let newline;
71
+ while ((newline = buffer.indexOf("\n")) >= 0) {
72
+ const line = buffer.slice(0, newline);
73
+ buffer = buffer.slice(newline + 1);
74
+ if (!line)
75
+ continue;
76
+ const frame = JSON.parse(line);
77
+ if (frame.event)
78
+ yield frame.event;
79
+ else if (frame.error)
80
+ throw gatewayError(frame.error, 200);
81
+ else if (frame.end)
82
+ return;
83
+ }
84
+ }
85
+ throw new GatewayError("internal", "The gateway stream ended without a result.");
86
+ },
87
+ };
88
+ }
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Kubernetes objects for one sandbox-mode native run (docs/native-sandbox.md), as pure builders —
3
+ * the launcher creates exactly these and attests what the API server stored against them. One pod
4
+ * per run, with no service-account token, a read-only non-root container holding no credentials,
5
+ * its WorkerInput (capability included) mounted read-only from a per-run Secret, and a
6
+ * NetworkPolicy whose only egress is the native gateway's port. Names carry a hash of the run id,
7
+ * never the id itself.
8
+ */
9
+ import type { V1NetworkPolicy, V1Pod, V1Secret } from "@kubernetes/client-node";
10
+ import { type KubernetesPlatform } from "../providers/jobs/kubernetes-platform.js";
11
+ import { nativeWarmWorkerName, type NativeWorkerLimits } from "./docker-isolation.js";
12
+ export { nativeWarmWorkerName };
13
+ import type { WorkerInput } from "./protocol.js";
14
+ export declare const NATIVE_RUN_COMPONENT_LABEL: {
15
+ readonly "wardby.io/component": "native-run";
16
+ };
17
+ export declare const NATIVE_GATEWAY_POD_LABEL: {
18
+ readonly "app.kubernetes.io/name": "wardby-native-gateway";
19
+ };
20
+ export declare const NATIVE_RUN_SHA_LABEL = "wardby.io/run-sha256";
21
+ /** The label selector listing every native run pod (the janitor's listing). */
22
+ export declare const NATIVE_RUN_SELECTOR = "wardby.io/component=native-run";
23
+ export declare const NATIVE_WORKER_CONTAINER = "worker";
24
+ export declare const NATIVE_INPUT_MOUNT = "/run/wardby/input";
25
+ export declare const NATIVE_INPUT_KEY = "input.json";
26
+ export declare const NATIVE_INPUT_FILE = "/run/wardby/input/input.json";
27
+ export interface NativeKubernetesNames {
28
+ runSha: string;
29
+ pod: string;
30
+ policy: string;
31
+ secret: string;
32
+ }
33
+ export declare function nativeKubernetesNames(runId: string): NativeKubernetesNames;
34
+ export declare function nativeRunLabels(runId: string): Record<string, string>;
35
+ export declare function buildNativeInputSecret(input: WorkerInput, namespace: string): V1Secret;
36
+ export interface NativeRunPodOptions {
37
+ runId: string;
38
+ namespace: string;
39
+ image: string;
40
+ limits: NativeWorkerLimits;
41
+ /** The pod's hard lifetime: the run's session deadline. */
42
+ activeDeadlineSeconds: number;
43
+ runtimeClassName?: string;
44
+ /** The cluster's admission rules the pod must already satisfy (KUBERNETES_PLATFORM). Default: "generic". */
45
+ platform?: KubernetesPlatform;
46
+ /** KUBERNETES_RUN_PRIORITY_CLASS: the class must exist in the cluster, or every create is refused. */
47
+ priorityClassName?: string;
48
+ }
49
+ export declare const NATIVE_SANDBOX_PLATFORM_ERROR = "native_sandbox_platform_unsupported";
50
+ export declare function buildNativeRunPod(options: NativeRunPodOptions): V1Pod;
51
+ /** The labels of every warm pool pod: still a native-run pod (the gateway admits it), never a run's. */
52
+ export declare const NATIVE_WARM_POOL_LABEL: {
53
+ readonly "wardby.io/pool": "warm";
54
+ };
55
+ export declare const NATIVE_WARM_TOKEN_LABEL = "wardby.io/warm-worker";
56
+ /** The label selector listing every warm pool pod. */
57
+ export declare const NATIVE_WARM_SELECTOR = "wardby.io/component=native-run,wardby.io/pool=warm";
58
+ export declare function nativeWarmLabels(token: string): Record<string, string>;
59
+ export interface NativeWarmPodOptions extends Omit<NativeRunPodOptions, "runId"> {
60
+ token: string;
61
+ /** NATIVE_WORKER_INPUT_WAIT_MS: how long the worker waits to be claimed before it exits. */
62
+ waitMs: number;
63
+ }
64
+ /** A warm pool pod (native sandbox phase 6): no input yet; it waits for one delivered by exec. */
65
+ export declare function buildNativeWarmPod(options: NativeWarmPodOptions): V1Pod;
66
+ /** Ingress: none. Egress: the native gateway's pods, on the gateway port only. */
67
+ export declare function buildNativeRunNetworkPolicy(runId: string, namespace: string): V1NetworkPolicy;
68
+ /** A warm pool pod's policy: the same egress, selecting the pod by its token. */
69
+ export declare function buildNativeWarmNetworkPolicy(token: string, namespace: string): V1NetworkPolicy;
70
+ /** Exit codes of the in-pod enforcement probe. */
71
+ export declare const NATIVE_PROBE: {
72
+ readonly proven: 0;
73
+ readonly gatewayUnreachable: 3;
74
+ readonly denyReachable: 4;
75
+ readonly outsideReachable: 5;
76
+ };
77
+ /** Addresses a worker must not reach: the internet, and the cloud metadata endpoints (node and workload credentials). */
78
+ export declare const NATIVE_PROBE_OUTSIDE: readonly {
79
+ host: string;
80
+ port: number;
81
+ }[];
82
+ /**
83
+ * Run inside the worker container (exec): proves the pod's egress is the gateway port and nothing
84
+ * else — the gateway answers, while its deny port (same address, another port) and every outside
85
+ * address do not. A connection that is refused or times out both count as unreachable.
86
+ */
87
+ export declare function nativeEnforcementProbe(gatewayHost: string, outside?: readonly {
88
+ host: string;
89
+ port: number;
90
+ }[]): string[];