@nylorun/runtime 0.23.0-beta → 0.25.0-beta

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 (301) hide show
  1. package/CHANGELOG.md +252 -0
  2. package/README.md +87 -28
  3. package/dist/adapters/execution/restate.js +1 -1
  4. package/dist/adapters/replication/pgoutput.d.ts +2 -0
  5. package/dist/adapters/replication/pgoutput.js +6 -3
  6. package/dist/adapters/sandbox/local.d.ts +9 -1
  7. package/dist/adapters/sandbox/local.js +16 -4
  8. package/dist/adapters/sandbox/virtual.js +4 -1
  9. package/dist/api/a2a/card.d.ts +11 -1
  10. package/dist/api/a2a/card.js +26 -2
  11. package/dist/api/a2a/endpoint.js +9 -3
  12. package/dist/api/a2a/protocol.d.ts +25 -2
  13. package/dist/api/a2a/protocol.js +20 -3
  14. package/dist/api/a2a/routes.d.ts +6 -1
  15. package/dist/api/a2a/routes.js +67 -9
  16. package/dist/api/a2a/tasks.js +2 -1
  17. package/dist/api/ag-ui/endpoint.js +8 -3
  18. package/dist/api/ag-ui/history.d.ts +6 -1
  19. package/dist/api/ag-ui/history.js +39 -3
  20. package/dist/api/ag-ui/routes.d.ts +4 -1
  21. package/dist/api/ag-ui/routes.js +63 -20
  22. package/dist/api/ag-ui/translate.js +3 -2
  23. package/dist/api/components.d.ts +5327 -1091
  24. package/dist/api/components.js +40 -16
  25. package/dist/api/gate/keys.d.ts +2 -1
  26. package/dist/api/gate/keys.js +14 -1
  27. package/dist/api/gate/routes.d.ts +6 -0
  28. package/dist/api/gate/routes.js +52 -3
  29. package/dist/api/http/app.js +17 -6
  30. package/dist/api/http/body.d.ts +3 -3
  31. package/dist/api/http/body.js +7 -7
  32. package/dist/api/http/define.d.ts +6 -0
  33. package/dist/api/http/define.js +13 -1
  34. package/dist/api/http/respond.js +1 -1
  35. package/dist/api/http/routes/artifacts.js +35 -8
  36. package/dist/api/http/routes/coverage.d.ts +9 -0
  37. package/dist/api/http/routes/coverage.js +34 -0
  38. package/dist/api/http/routes/environment-manifests.d.ts +9 -0
  39. package/dist/api/http/routes/environment-manifests.js +118 -0
  40. package/dist/api/http/routes/environments.d.ts +11 -0
  41. package/dist/api/http/routes/environments.js +332 -0
  42. package/dist/api/http/routes/mcp.d.ts +1 -1
  43. package/dist/api/http/routes/mcp.js +2 -2
  44. package/dist/api/http/routes/me.js +1 -1
  45. package/dist/api/http/routes/reads.d.ts +94 -9
  46. package/dist/api/http/routes/reads.js +54 -5
  47. package/dist/api/http/routes/sessions.js +24 -9
  48. package/dist/api/http/routes/tenant.js +65 -15
  49. package/dist/api/inbound-files.d.ts +65 -0
  50. package/dist/api/inbound-files.js +115 -0
  51. package/dist/api/openapi.js +48 -28
  52. package/dist/artifacts/disk.d.ts +59 -0
  53. package/dist/artifacts/disk.js +569 -0
  54. package/dist/artifacts/export.d.ts +1 -1
  55. package/dist/artifacts/export.js +2 -3
  56. package/dist/artifacts/folders.d.ts +6 -3
  57. package/dist/artifacts/folders.js +17 -12
  58. package/dist/artifacts/media-types.d.ts +15 -0
  59. package/dist/artifacts/media-types.js +56 -4
  60. package/dist/artifacts/parts.d.ts +12 -3
  61. package/dist/artifacts/parts.js +15 -4
  62. package/dist/artifacts/service.d.ts +2 -1
  63. package/dist/artifacts/service.js +6 -1
  64. package/dist/artifacts/workspace.d.ts +5 -5
  65. package/dist/artifacts/workspace.js +7 -19
  66. package/dist/core/flow-host.d.ts +3 -4
  67. package/dist/core/flow-host.js +5 -2
  68. package/dist/core/provider.d.ts +3 -2
  69. package/dist/core/provider.js +5 -37
  70. package/dist/core/sandbox-routes.d.ts +2 -21
  71. package/dist/core/sandbox-routes.js +11 -44
  72. package/dist/core/turn-manifest.d.ts +3 -2
  73. package/dist/core/turn-manifest.js +29 -5
  74. package/dist/execution/types.d.ts +1 -1
  75. package/dist/gates/contract.d.ts +3 -24
  76. package/dist/gates/contract.js +1 -36
  77. package/dist/gates/egress-credentials.d.ts +9 -0
  78. package/dist/gates/egress-credentials.js +11 -4
  79. package/dist/gates/egress.d.ts +22 -1
  80. package/dist/gates/egress.js +116 -10
  81. package/dist/gates/fixture-model.d.ts +28 -0
  82. package/dist/gates/fixture-model.js +92 -0
  83. package/dist/gates/handler.js +4 -4
  84. package/dist/gates/http-tool.d.ts +9 -6
  85. package/dist/gates/http-tool.js +11 -17
  86. package/dist/gates/in-process.d.ts +5 -0
  87. package/dist/gates/in-process.js +12 -1
  88. package/dist/gates/journal.d.ts +30 -0
  89. package/dist/gates/journal.js +51 -0
  90. package/dist/gates/mcp-handler.d.ts +4 -0
  91. package/dist/gates/mcp-handler.js +7 -4
  92. package/dist/gates/meter.d.ts +10 -2
  93. package/dist/gates/meter.js +20 -5
  94. package/dist/gates/policy.d.ts +49 -0
  95. package/dist/gates/policy.js +132 -0
  96. package/dist/gates/tenant-vaults.d.ts +7 -7
  97. package/dist/gates/tenant-vaults.js +5 -5
  98. package/dist/gates/tool-calls.d.ts +10 -5
  99. package/dist/gates/tool-calls.js +28 -10
  100. package/dist/gates/tool-client.d.ts +8 -0
  101. package/dist/gates/tool-client.js +27 -11
  102. package/dist/gates/tool-contract.d.ts +11 -69
  103. package/dist/gates/tool-contract.js +1 -85
  104. package/dist/gates/tool-gate.d.ts +1 -1
  105. package/dist/harness/calls.d.ts +14 -7
  106. package/dist/harness/calls.js +30 -24
  107. package/dist/harness/executors.js +12 -9
  108. package/dist/harness/main.js +24 -5
  109. package/dist/harness/pod.d.ts +39 -0
  110. package/dist/harness/pod.js +46 -0
  111. package/dist/harness/service.d.ts +0 -1
  112. package/dist/harness/service.js +17 -9
  113. package/dist/harness/setup.d.ts +29 -0
  114. package/dist/harness/setup.js +174 -0
  115. package/dist/harness/ws-client.js +3 -2
  116. package/dist/harness/ws-port.d.ts +1 -5
  117. package/dist/harness/ws-port.js +1 -5
  118. package/dist/harness-api/in-process.js +3 -3
  119. package/dist/harness-api/record.d.ts +15 -1
  120. package/dist/harness-api/record.js +180 -50
  121. package/dist/harness-api/redact.d.ts +3 -0
  122. package/dist/harness-api/redact.js +45 -0
  123. package/dist/harness-api/server.d.ts +35 -4
  124. package/dist/harness-api/server.js +130 -17
  125. package/dist/harness-api/start.d.ts +10 -3
  126. package/dist/harness-api/start.js +40 -10
  127. package/dist/harness-api/tool-journal.d.ts +105 -0
  128. package/dist/harness-api/tool-journal.js +132 -0
  129. package/dist/harness-api/tool-status.d.ts +13 -0
  130. package/dist/harness-api/tool-status.js +26 -0
  131. package/dist/harness-api/workspace.d.ts +12 -7
  132. package/dist/harness-api/workspace.js +47 -25
  133. package/dist/harness-api/ws-server.d.ts +11 -3
  134. package/dist/harness-api/ws-server.js +94 -15
  135. package/dist/host/gates.d.ts +2 -1
  136. package/dist/host/gates.js +10 -2
  137. package/dist/host/main.js +54 -5
  138. package/dist/host/operate.js +67 -5
  139. package/dist/host/stack-config.d.ts +64 -0
  140. package/dist/host/stack-config.js +62 -2
  141. package/dist/keys/client.js +4 -1
  142. package/dist/keys/keys.d.ts +13 -6
  143. package/dist/keys/keys.js +9 -8
  144. package/dist/management-openapi.json +1264 -2171
  145. package/dist/mcp/connect.d.ts +26 -22
  146. package/dist/mcp/connect.js +30 -34
  147. package/dist/mcp/pool.d.ts +3 -6
  148. package/dist/mcp/pool.js +14 -28
  149. package/dist/mcp/preview.d.ts +3 -3
  150. package/dist/mcp/preview.js +10 -21
  151. package/dist/mcp/snapshot.d.ts +16 -24
  152. package/dist/mcp/snapshot.js +33 -45
  153. package/dist/model/capabilities.d.ts +26 -0
  154. package/dist/model/capabilities.js +44 -0
  155. package/dist/model/catalog.d.ts +34 -3
  156. package/dist/model/catalog.js +38 -2
  157. package/dist/model/models.d.ts +2 -0
  158. package/dist/model/models.js +1 -1
  159. package/dist/model/native-blocks.d.ts +35 -0
  160. package/dist/model/native-blocks.js +170 -0
  161. package/dist/model/pi-model.js +114 -94
  162. package/dist/openapi.json +12822 -3943
  163. package/dist/reads/types.d.ts +16 -3
  164. package/dist/record/append.d.ts +3 -1
  165. package/dist/record/append.js +1 -0
  166. package/dist/record/envelope.d.ts +5 -1
  167. package/dist/record/envelope.js +7 -3
  168. package/dist/record/environment.d.ts +25 -0
  169. package/dist/record/environment.js +44 -0
  170. package/dist/record/index.d.ts +1 -1
  171. package/dist/record/index.js +1 -1
  172. package/dist/sandbox/disk-fs.d.ts +95 -0
  173. package/dist/sandbox/disk-fs.js +206 -0
  174. package/dist/sandbox/join.d.ts +17 -18
  175. package/dist/sandbox/join.js +46 -15
  176. package/dist/sandbox/manager.d.ts +47 -21
  177. package/dist/sandbox/manager.js +162 -107
  178. package/dist/sandbox/placement.d.ts +14 -13
  179. package/dist/sandbox/placement.js +31 -14
  180. package/dist/sandbox/pods/client.d.ts +9 -2
  181. package/dist/sandbox/pods/lifecycle.d.ts +36 -27
  182. package/dist/sandbox/pods/lifecycle.js +29 -26
  183. package/dist/sandbox/pods/reconcile.js +18 -12
  184. package/dist/sandbox/pods/spec.d.ts +15 -13
  185. package/dist/sandbox/pods/spec.js +17 -20
  186. package/dist/sandbox/records.d.ts +2 -2
  187. package/dist/sandbox/records.js +3 -3
  188. package/dist/sandbox/resolve.d.ts +37 -27
  189. package/dist/sandbox/resolve.js +73 -41
  190. package/dist/sandbox/runtime-tools.d.ts +9 -0
  191. package/dist/sandbox/runtime-tools.js +16 -0
  192. package/dist/sandbox/session-sandbox.d.ts +4 -6
  193. package/dist/sandbox/session-sandbox.js +47 -94
  194. package/dist/sandbox/setup.d.ts +64 -0
  195. package/dist/sandbox/setup.js +160 -0
  196. package/dist/sandbox/share.d.ts +21 -26
  197. package/dist/sandbox/share.js +36 -63
  198. package/dist/sandbox/skills.d.ts +8 -6
  199. package/dist/sandbox/skills.js +24 -23
  200. package/dist/sandbox/tenant-config.d.ts +12 -14
  201. package/dist/sandbox/tenant-config.js +12 -17
  202. package/dist/sandbox/types.d.ts +6 -0
  203. package/dist/store/postgres/drizzle/0020_environments.sql +63 -0
  204. package/dist/store/postgres/drizzle/0021_disk_versions.sql +7 -0
  205. package/dist/store/postgres/drizzle/0022_model_usage_timing.sql +5 -0
  206. package/dist/store/postgres/drizzle/0023_artifact_pages.sql +1 -0
  207. package/dist/store/postgres/drizzle/0024_flat_manifest.sql +7 -0
  208. package/dist/store/postgres/drizzle/0025_environment_manifests.sql +14 -0
  209. package/dist/store/postgres/drizzle/0026_environment_forks.sql +1 -0
  210. package/dist/store/postgres/drizzle/0027_environment_image_digest.sql +1 -0
  211. package/dist/store/postgres/drizzle/meta/_journal.json +56 -0
  212. package/dist/store/postgres/reads.js +123 -17
  213. package/dist/store/postgres/record-writer.d.ts +4 -4
  214. package/dist/store/postgres/record-writer.js +9 -9
  215. package/dist/store/postgres/record.d.ts +7 -0
  216. package/dist/store/postgres/record.js +23 -2
  217. package/dist/store/postgres/schema.d.ts +1126 -736
  218. package/dist/store/postgres/schema.js +136 -73
  219. package/dist/store/postgres/store.js +195 -67
  220. package/dist/store/types.d.ts +165 -50
  221. package/dist/tenant/advance.d.ts +7 -6
  222. package/dist/tenant/advance.js +118 -42
  223. package/dist/tenant/artifact-tool.d.ts +1 -1
  224. package/dist/tenant/artifact-tool.js +46 -26
  225. package/dist/tenant/commands.d.ts +15 -2
  226. package/dist/tenant/commands.js +115 -14
  227. package/dist/tenant/context.d.ts +56 -24
  228. package/dist/tenant/context.js +4 -15
  229. package/dist/tenant/effects.d.ts +1 -1
  230. package/dist/tenant/effects.js +44 -29
  231. package/dist/tenant/environment-manifests.d.ts +57 -0
  232. package/dist/tenant/environment-manifests.js +200 -0
  233. package/dist/tenant/environments.d.ts +174 -0
  234. package/dist/tenant/environments.js +1044 -0
  235. package/dist/tenant/harness-tokens.d.ts +21 -0
  236. package/dist/tenant/harness-tokens.js +61 -0
  237. package/dist/tenant/host-token.d.ts +1 -1
  238. package/dist/tenant/host-token.js +2 -4
  239. package/dist/tenant/identity-file.d.ts +4 -4
  240. package/dist/tenant/identity-file.js +17 -8
  241. package/dist/tenant/issuers.js +3 -3
  242. package/dist/tenant/model-setting.d.ts +14 -0
  243. package/dist/tenant/model-setting.js +51 -0
  244. package/dist/tenant/principals.js +1 -1
  245. package/dist/tenant/reset.js +3 -3
  246. package/dist/tenant/runtime.d.ts +6 -1
  247. package/dist/tenant/runtime.js +7 -1
  248. package/dist/tenant/session.d.ts +3 -3
  249. package/dist/tenant/session.js +0 -14
  250. package/dist/tenant/sessions.d.ts +18 -14
  251. package/dist/tenant/sessions.js +99 -143
  252. package/dist/tenant/signing-keys.d.ts +5 -1
  253. package/dist/tenant/skill-tool.d.ts +3 -3
  254. package/dist/tenant/skill-tool.js +6 -11
  255. package/dist/tenant/status.js +3 -3
  256. package/dist/tenant/sweep.js +13 -7
  257. package/dist/tenant/tool-results.js +1 -1
  258. package/dist/tenant/tool-search.d.ts +7 -11
  259. package/dist/tenant/tool-search.js +8 -5
  260. package/dist/tenant/transcript.d.ts +245 -36
  261. package/dist/tenant/transcript.js +64 -12
  262. package/dist/tenant/turn-timing.d.ts +43 -0
  263. package/dist/tenant/turn-timing.js +39 -0
  264. package/dist/tenant/types.d.ts +2 -0
  265. package/dist/traces/ids.d.ts +41 -0
  266. package/dist/traces/ids.js +81 -0
  267. package/dist/traces/key.d.ts +6 -0
  268. package/dist/traces/key.js +37 -0
  269. package/dist/traces/map.d.ts +113 -0
  270. package/dist/traces/map.js +289 -0
  271. package/dist/traces/options.d.ts +7 -0
  272. package/dist/traces/options.js +1 -0
  273. package/dist/traces/otlp.d.ts +42 -0
  274. package/dist/traces/otlp.js +84 -0
  275. package/dist/traces/projector.d.ts +58 -0
  276. package/dist/traces/projector.js +200 -0
  277. package/dist/traces/read.d.ts +23 -0
  278. package/dist/traces/read.js +16 -0
  279. package/dist/vault/coverage.d.ts +26 -0
  280. package/dist/vault/coverage.js +62 -0
  281. package/dist/vault/error.d.ts +11 -1
  282. package/dist/vault/error.js +5 -1
  283. package/dist/vault/host-model.d.ts +4 -1
  284. package/dist/vault/host-model.js +10 -2
  285. package/dist/vault/service.d.ts +92 -48
  286. package/dist/vault/service.js +462 -376
  287. package/dist/vault/sources.d.ts +5 -16
  288. package/dist/vault/sources.js +6 -8
  289. package/dist/version.d.ts +1 -1
  290. package/dist/version.js +2 -2
  291. package/package.json +13 -13
  292. package/dist/api/http/routes/sandboxes.d.ts +0 -9
  293. package/dist/api/http/routes/sandboxes.js +0 -153
  294. package/dist/api/http/routes/vaults.d.ts +0 -10
  295. package/dist/api/http/routes/vaults.js +0 -139
  296. package/dist/record/sandbox.d.ts +0 -25
  297. package/dist/record/sandbox.js +0 -43
  298. package/dist/sandbox/capability.d.ts +0 -3
  299. package/dist/sandbox/capability.js +0 -10
  300. package/dist/tenant/sandboxes.d.ts +0 -123
  301. package/dist/tenant/sandboxes.js +0 -566
@@ -1,46 +1,41 @@
1
1
  /**
2
- * Shared sandboxes: one sandbox per owning session, attached via PutSession.sandbox =
3
- * { session }; keys use the owner id. A sandbox is either declared by the definition (an agent
4
- * capability or a workflow's `sandbox`) or chosen when the session was opened and pinned on the
5
- * session record (`sandbox`).
2
+ * A session's sandbox: the one of the Environment it names (protocol 11), whose id keys the
3
+ * workspace, with the spec pinned when the session was opened (`Session.sandbox`). Definitions
4
+ * no longer declare one (Sandboxes v3); `sandboxSpecOf` still reads a pinned manifest's.
6
5
  */
7
- import { type AgentManifest, type CapabilityManifest, type SandboxManifest, type WorkflowManifest } from "@nylorun/core/define";
6
+ import { type AgentManifest, type SandboxManifest, type WorkflowManifest } from "@nylorun/core/define";
8
7
  export type SessionSandboxRef = {
9
8
  readonly id: string;
10
9
  readonly ownerUserId: string;
11
10
  readonly manifest: AgentManifest | WorkflowManifest | Record<string, unknown>;
12
- /** Session whose id keys the sandbox. Absent means this session owns its own. */
13
- readonly sandboxOwnerId?: string | null;
14
- /** The sandbox resource the session is attached to; its id keys the workspace. */
15
- readonly sandboxId?: string;
16
- /** The sandbox chosen when the session was opened (or inherited from its owner), resolved. */
11
+ /** The Environment the session names; its id keys the workspace. */
12
+ readonly environmentId?: string;
13
+ /** The Environment's sandbox spec, pinned when the session was opened. */
17
14
  readonly sandbox?: SandboxManifest;
18
15
  };
19
16
  /** The session's sandbox spec: the one pinned at open, else the one its definition declares. */
20
17
  export declare function sessionSandboxSpec(session: SessionSandboxRef): SandboxManifest | undefined;
21
- /** Sandbox spec declared on an agent capability or a workflow manifest. */
18
+ /** The sandbox spec of a pinned agent manifest (its `runtime` block) or a workflow manifest. */
22
19
  export declare function sandboxSpecOf(manifest: AgentManifest | WorkflowManifest | Record<string, unknown> | undefined): SandboxManifest | undefined;
23
20
  /**
24
- * Where a definition document declares a sandbox: agent capabilities, the agents inlined as
25
- * tools or embedded in a flow agent, and a workflow's `sandbox`. Definitions no longer declare
26
- * one (Sandboxes v3), so registration refuses any of these.
21
+ * Where a definition document declares a sandbox: a workflow's `sandbox`, and the agents embedded
22
+ * in a flow agent. Definitions no longer declare one (Sandboxes v3), so registration refuses any
23
+ * of these. An agent manifest cannot: its sandbox is in the `runtime` block, which the schema
24
+ * refuses at registration.
27
25
  */
28
26
  export declare function declaredSandboxes(manifest: unknown, into?: string[]): string[];
29
- export declare function sandboxSpecsEqual(a: SandboxManifest | undefined, b: SandboxManifest | undefined): boolean;
30
- /** Synthetic capability so SandboxManager.run can use a workflow (or shared) spec. */
31
- export declare function capabilityForSandbox(sandbox: SandboxManifest): CapabilityManifest;
32
27
  /**
33
- * Resolve the session id that keys the sandbox. Walks one hop via sandboxOwnerId;
34
- * cycles fall back to the starting session.
28
+ * The agents of a definition document that set `runtime`: the document itself, the agents it
29
+ * uses as tools and those embedded in a flow agent. Only the Runtime writes that block, when it
30
+ * pins a session's manifest, so registration refuses any of these.
35
31
  */
36
- export declare function owningSandboxSessionId(session: SessionSandboxRef, lookup: (id: string) => SessionSandboxRef | undefined): string;
32
+ export declare function authoredRuntimeBlocks(manifest: unknown, into?: string[]): string[];
37
33
  /**
38
- * The workspace a session's sandbox tools run in: the owning session (one hop through
39
- * `sandboxOwnerId`, whose log records the workspace's events) and, when that session is
40
- * attached to a sandbox resource, the resource's id, which keys the workspace.
34
+ * The workspace a session's sandbox tools run in: the session, whose log records the
35
+ * workspace's events, and its Environment, whose id keys the workspace.
41
36
  */
42
- export declare function sandboxWorkspaceOf(session: SessionSandboxRef, lookup: (id: string) => SessionSandboxRef | undefined): {
37
+ export declare function sandboxWorkspaceOf(session: SessionSandboxRef): {
43
38
  readonly ownerId: string;
44
- readonly sandboxId?: string;
39
+ readonly environmentId?: string;
45
40
  };
46
- export declare function sessionHasSandbox(session: SessionSandboxRef, lookup: (id: string) => SessionSandboxRef | undefined): boolean;
41
+ export declare function sessionHasSandbox(session: SessionSandboxRef): boolean;
@@ -1,32 +1,26 @@
1
1
  /**
2
- * Shared sandboxes: one sandbox per owning session, attached via PutSession.sandbox =
3
- * { session }; keys use the owner id. A sandbox is either declared by the definition (an agent
4
- * capability or a workflow's `sandbox`) or chosen when the session was opened and pinned on the
5
- * session record (`sandbox`).
2
+ * A session's sandbox: the one of the Environment it names (protocol 11), whose id keys the
3
+ * workspace, with the spec pinned when the session was opened (`Session.sandbox`). Definitions
4
+ * no longer declare one (Sandboxes v3); `sandboxSpecOf` still reads a pinned manifest's.
6
5
  */
7
- import { canonical, } from "@nylorun/core/define";
6
+ import {} from "@nylorun/core/define";
8
7
  /** The session's sandbox spec: the one pinned at open, else the one its definition declares. */
9
8
  export function sessionSandboxSpec(session) {
10
9
  return session.sandbox ?? sandboxSpecOf(session.manifest);
11
10
  }
12
- /** Sandbox spec declared on an agent capability or a workflow manifest. */
11
+ /** The sandbox spec of a pinned agent manifest (its `runtime` block) or a workflow manifest. */
13
12
  export function sandboxSpecOf(manifest) {
14
13
  if (!manifest || typeof manifest !== "object")
15
14
  return undefined;
16
15
  if (manifest.kind === "workflow")
17
16
  return manifest.sandbox;
18
- const capabilities = manifest.capabilities;
19
- if (!Array.isArray(capabilities))
20
- return undefined;
21
- for (const capability of capabilities)
22
- if (capability.sandbox)
23
- return capability.sandbox;
24
- return undefined;
17
+ return manifest.runtime?.sandbox;
25
18
  }
26
19
  /**
27
- * Where a definition document declares a sandbox: agent capabilities, the agents inlined as
28
- * tools or embedded in a flow agent, and a workflow's `sandbox`. Definitions no longer declare
29
- * one (Sandboxes v3), so registration refuses any of these.
20
+ * Where a definition document declares a sandbox: a workflow's `sandbox`, and the agents embedded
21
+ * in a flow agent. Definitions no longer declare one (Sandboxes v3), so registration refuses any
22
+ * of these. An agent manifest cannot: its sandbox is in the `runtime` block, which the schema
23
+ * refuses at registration.
30
24
  */
31
25
  export function declaredSandboxes(manifest, into = []) {
32
26
  if (!manifest || typeof manifest !== "object")
@@ -39,60 +33,39 @@ export function declaredSandboxes(manifest, into = []) {
39
33
  declaredSandboxes(agent, into);
40
34
  return into;
41
35
  }
42
- for (const capability of document.capabilities ?? []) {
43
- if (capability.sandbox !== undefined)
44
- into.push(`'${document.id}' (capability '${capability.id}')`);
45
- for (const tool of capability.tools ?? [])
46
- declaredSandboxes(tool.agent, into);
47
- }
36
+ for (const tool of document.tools ?? [])
37
+ declaredSandboxes(tool.agent, into);
48
38
  return into;
49
39
  }
50
- export function sandboxSpecsEqual(a, b) {
51
- if (a === undefined && b === undefined)
52
- return true;
53
- if (a === undefined || b === undefined)
54
- return false;
55
- return canonical(a) === canonical(b);
56
- }
57
- /** Synthetic capability so SandboxManager.run can use a workflow (or shared) spec. */
58
- export function capabilityForSandbox(sandbox) {
59
- return {
60
- id: "sandbox",
61
- type: "agent",
62
- sandbox,
63
- tools: [],
64
- };
65
- }
66
40
  /**
67
- * Resolve the session id that keys the sandbox. Walks one hop via sandboxOwnerId;
68
- * cycles fall back to the starting session.
41
+ * The agents of a definition document that set `runtime`: the document itself, the agents it
42
+ * uses as tools and those embedded in a flow agent. Only the Runtime writes that block, when it
43
+ * pins a session's manifest, so registration refuses any of these.
69
44
  */
70
- export function owningSandboxSessionId(session, lookup) {
71
- const seen = new Set();
72
- let current = session;
73
- while (current) {
74
- if (seen.has(current.id))
75
- return session.id;
76
- seen.add(current.id);
77
- const ownerId = current.sandboxOwnerId;
78
- if (!ownerId || ownerId === current.id)
79
- return current.id;
80
- current = lookup(ownerId);
45
+ export function authoredRuntimeBlocks(manifest, into = []) {
46
+ if (!manifest || typeof manifest !== "object")
47
+ return into;
48
+ const document = manifest;
49
+ if (document.kind === "workflow") {
50
+ for (const agent of Object.values(document.agents ?? {}))
51
+ authoredRuntimeBlocks(agent, into);
52
+ return into;
81
53
  }
82
- return session.id;
54
+ if (document.runtime !== undefined)
55
+ into.push(`'${document.id}'`);
56
+ for (const tool of document.tools ?? [])
57
+ authoredRuntimeBlocks(tool.agent, into);
58
+ return into;
83
59
  }
84
60
  /**
85
- * The workspace a session's sandbox tools run in: the owning session (one hop through
86
- * `sandboxOwnerId`, whose log records the workspace's events) and, when that session is
87
- * attached to a sandbox resource, the resource's id, which keys the workspace.
61
+ * The workspace a session's sandbox tools run in: the session, whose log records the
62
+ * workspace's events, and its Environment, whose id keys the workspace.
88
63
  */
89
- export function sandboxWorkspaceOf(session, lookup) {
90
- const ownerId = owningSandboxSessionId(session, lookup);
91
- const owner = ownerId === session.id ? session : lookup(ownerId) ?? session;
92
- return owner.sandboxId === undefined ? { ownerId } : { ownerId, sandboxId: owner.sandboxId };
64
+ export function sandboxWorkspaceOf(session) {
65
+ return session.environmentId === undefined
66
+ ? { ownerId: session.id }
67
+ : { ownerId: session.id, environmentId: session.environmentId };
93
68
  }
94
- export function sessionHasSandbox(session, lookup) {
95
- const ownerId = owningSandboxSessionId(session, lookup);
96
- const owner = ownerId === session.id ? session : lookup(ownerId) ?? session;
97
- return sessionSandboxSpec(owner) !== undefined || sessionSandboxSpec(session) !== undefined;
69
+ export function sessionHasSandbox(session) {
70
+ return sessionSandboxSpec(session) !== undefined;
98
71
  }
@@ -2,12 +2,14 @@ import { type AgentManifest } from "@nylorun/core/define";
2
2
  import type { SandboxHandle } from "./types.js";
3
3
  /** A skill's files, by path in its folder, as `sha256:<hex>`. */
4
4
  export type SkillFiles = Readonly<Record<string, string>>;
5
- /** The skills of the agent and the agents it uses as tools; the first of a name wins. */
5
+ /**
6
+ * The skill versions of the agent and the agents it uses as tools, by folder
7
+ * (`/skills/<name>@<hash>`): each distinct version once.
8
+ */
6
9
  export declare function sandboxSkillsOf(manifest: AgentManifest | undefined, into?: Map<string, Readonly<Record<string, string>>>): Map<string, SkillFiles>;
7
- /** What a mounted skill holds, to tell whether a workspace has these files already. */
8
- export declare function skillSignature(files: SkillFiles): string;
9
10
  /**
10
- * Writes one skill's files to `/skills/<name>/` of the sandbox, replacing what was there, and
11
- * makes them read-only. `read` gives a file's bytes by `sha256:<hex>`.
11
+ * Writes one skill version's files to its folder `root` (`/skills/<name>@<hash>`), replacing a
12
+ * partial copy a failed mount left, and makes them read-only. `read` gives a file's bytes by
13
+ * `sha256:<hex>`.
12
14
  */
13
- export declare function mountSkill(handle: SandboxHandle, name: string, files: SkillFiles, read: (sha256: string) => Promise<Uint8Array>, signal: AbortSignal): Promise<void>;
15
+ export declare function mountSkill(handle: SandboxHandle, root: string, files: SkillFiles, read: (sha256: string) => Promise<Uint8Array>, signal: AbortSignal): Promise<void>;
@@ -1,36 +1,37 @@
1
1
  /**
2
- * A sandbox's skills (track R2 M4): each skill of the session's agent, and of the agents it uses
3
- * as tools (they share its sandbox), gets its files under `/skills/<name>/`, read-only, so the
4
- * model can read them and run their scripts with bash. The SandboxManager mounts them on a
5
- * workspace before the first call of a session's run that opens it, and again when a session
6
- * with other skills uses it; the bytes come from the Tenant's definition files.
2
+ * A sandbox's skills (track R2 M4, D66): each version of a skill of the session's agent, and of
3
+ * the agents it uses as tools (they share its sandbox), gets its files in its own folder,
4
+ * `/skills/<name>@<hash>/` (`skillFolderOf`), read-only, so the model can read them and run their
5
+ * scripts with bash. A version's folder is written once and never replaced: sessions whose agents
6
+ * carry different versions of one skill share an Environment, and run turns at once, without
7
+ * changing each other's files. The SandboxManager mounts the folders a session needs before the
8
+ * first call that needs them; the bytes come from the Tenant's definition files. Folders live
9
+ * outside the persisted disk, so a stop clears them and the next open mounts what is in use.
7
10
  */
8
11
  import { posix } from "node:path";
9
- import { SKILLS_MOUNT } from "@nylorun/core/define";
10
- import { canonical } from "../store/canonical.js";
12
+ import { skillFolderOf } from "@nylorun/core/define";
11
13
  import { quote } from "./tools.js";
12
- /** The skills of the agent and the agents it uses as tools; the first of a name wins. */
14
+ /**
15
+ * The skill versions of the agent and the agents it uses as tools, by folder
16
+ * (`/skills/<name>@<hash>`): each distinct version once.
17
+ */
13
18
  export function sandboxSkillsOf(manifest, into = new Map()) {
14
- for (const capability of manifest?.capabilities ?? []) {
15
- for (const skill of Object.values(capability.skills ?? {}))
16
- if (!into.has(skill.name))
17
- into.set(skill.name, skill.files);
18
- for (const tool of capability.tools ?? [])
19
- if (tool.agent !== undefined && !("kind" in tool.agent))
20
- sandboxSkillsOf(tool.agent, into);
19
+ for (const skill of Object.values(manifest?.skills ?? {})) {
20
+ const folder = skillFolderOf(skill);
21
+ if (!into.has(folder))
22
+ into.set(folder, skill.files);
21
23
  }
24
+ for (const tool of manifest?.tools ?? [])
25
+ if (tool.agent !== undefined && !("kind" in tool.agent))
26
+ sandboxSkillsOf(tool.agent, into);
22
27
  return into;
23
28
  }
24
- /** What a mounted skill holds, to tell whether a workspace has these files already. */
25
- export function skillSignature(files) {
26
- return canonical(files);
27
- }
28
29
  /**
29
- * Writes one skill's files to `/skills/<name>/` of the sandbox, replacing what was there, and
30
- * makes them read-only. `read` gives a file's bytes by `sha256:<hex>`.
30
+ * Writes one skill version's files to its folder `root` (`/skills/<name>@<hash>`), replacing a
31
+ * partial copy a failed mount left, and makes them read-only. `read` gives a file's bytes by
32
+ * `sha256:<hex>`.
31
33
  */
32
- export async function mountSkill(handle, name, files, read, signal) {
33
- const root = `${SKILLS_MOUNT}/${name}`;
34
+ export async function mountSkill(handle, root, files, read, signal) {
34
35
  const exec = async (command) => {
35
36
  const result = await handle.exec({ command, cwd: "/", timeoutMs: 60_000 }, signal);
36
37
  if (result.exitCode !== 0)
@@ -1,41 +1,39 @@
1
1
  /**
2
- * A Tenant's sandbox configuration, stored as Tenant setting `sandbox.config`: the sandbox a
3
- * session gets when it names none, and the limits every session's sandbox must fit. Unset
2
+ * A Tenant's Environment settings, stored as Tenant setting `environments.config`: the limits
3
+ * every Environment's recipe must fit, the pods' stop grace and the harness placement. Unset
4
4
  * fields take the defaults below.
5
5
  */
6
- import { type SandboxInlineRequest, type SandboxPlacementHost, type TenantSandboxConfig } from "@nylorun/core/contracts";
7
- export declare const SANDBOX_CONFIG_SETTING = "sandbox.config";
8
- /** The most a session may ask for when the Tenant sets no maximum. */
6
+ import { type PlacementHost, type TenantEnvironmentsConfig } from "@nylorun/core/contracts";
7
+ export declare const ENVIRONMENTS_CONFIG_SETTING = "environments.config";
8
+ /** The Tenant's settings, as stored (`environments.config`). */
9
+ export type TenantSandboxConfig = TenantEnvironmentsConfig;
10
+ /** The most an Environment may ask for when the Tenant sets no maximum. */
9
11
  export declare const DEFAULT_MAX_CPUS = 4;
10
12
  export declare const DEFAULT_MAX_MEMORY_MIB = 8192;
11
13
  export declare const DEFAULT_SANDBOX_IDLE = "15m";
12
- /** The most sandbox resources a Tenant holds when it sets no limit. */
13
- export declare const DEFAULT_MAX_SANDBOXES = 100;
14
+ /** The most Environments a Tenant holds when it sets no limit. */
15
+ export declare const DEFAULT_MAX_ENVIRONMENTS = 100;
14
16
  export interface SandboxResourcesLimit {
15
17
  readonly cpus: number;
16
18
  readonly memoryMiB: number;
17
19
  }
18
20
  /** A configuration with every default applied. */
19
21
  export interface EffectiveSandboxConfig {
20
- readonly default: "none" | "virtual" | SandboxInlineRequest;
21
22
  readonly limits: {
22
23
  readonly network: readonly string[];
23
24
  readonly resources: SandboxResourcesLimit;
24
25
  readonly defaultResources: SandboxResourcesLimit;
25
26
  readonly idle: string;
26
- /** The most sandbox resources (`PUT /v1/sandboxes/{id}`) the Tenant may hold. */
27
- readonly sandboxes: number;
28
- /** Pods: the longest `lifecycle.ttl`. */
29
- readonly ttl?: string;
27
+ /** The most Environments the Tenant may hold. */
28
+ readonly environments: number;
30
29
  };
31
30
  /** Pods (F7.2, D36). */
32
31
  readonly lifecycle: {
33
- readonly onExpiry: "retain" | "delete";
34
32
  readonly stopGrace: string;
35
33
  };
36
34
  /** Where each harness may run (D38). */
37
35
  readonly placement: Readonly<Record<string, {
38
- readonly hosts: readonly SandboxPlacementHost[];
36
+ readonly hosts: readonly PlacementHost[];
39
37
  }>>;
40
38
  }
41
39
  interface SettingsReader {
@@ -1,18 +1,18 @@
1
1
  /**
2
- * A Tenant's sandbox configuration, stored as Tenant setting `sandbox.config`: the sandbox a
3
- * session gets when it names none, and the limits every session's sandbox must fit. Unset
2
+ * A Tenant's Environment settings, stored as Tenant setting `environments.config`: the limits
3
+ * every Environment's recipe must fit, the pods' stop grace and the harness placement. Unset
4
4
  * fields take the defaults below.
5
5
  */
6
- import { TenantSandboxConfigSchema, } from "@nylorun/core/contracts";
6
+ import { TenantEnvironmentsConfigSchema, } from "@nylorun/core/contracts";
7
7
  import { parseSandboxSize } from "@nylorun/core/define";
8
8
  import { DEFAULT_SANDBOX_CPUS, DEFAULT_SANDBOX_MEMORY_MIB, DEV_PRESET_HOSTS, } from "./policy.js";
9
- export const SANDBOX_CONFIG_SETTING = "sandbox.config";
10
- /** The most a session may ask for when the Tenant sets no maximum. */
9
+ export const ENVIRONMENTS_CONFIG_SETTING = "environments.config";
10
+ /** The most an Environment may ask for when the Tenant sets no maximum. */
11
11
  export const DEFAULT_MAX_CPUS = 4;
12
12
  export const DEFAULT_MAX_MEMORY_MIB = 8192;
13
13
  export const DEFAULT_SANDBOX_IDLE = "15m";
14
- /** The most sandbox resources a Tenant holds when it sets no limit. */
15
- export const DEFAULT_MAX_SANDBOXES = 100;
14
+ /** The most Environments a Tenant holds when it sets no limit. */
15
+ export const DEFAULT_MAX_ENVIRONMENTS = 100;
16
16
  export function memoryMiB(value) {
17
17
  const bytes = parseSandboxSize(value);
18
18
  return bytes === undefined ? 0 : Math.max(128, Math.ceil(bytes / 1024 ** 2));
@@ -26,7 +26,6 @@ function resources(value, fallback) {
26
26
  export function effectiveSandboxConfig(config) {
27
27
  const limits = config.limits ?? {};
28
28
  return {
29
- default: config.default ?? "none",
30
29
  limits: {
31
30
  network: limits.network ?? DEV_PRESET_HOSTS,
32
31
  resources: resources(limits.resources, {
@@ -38,23 +37,19 @@ export function effectiveSandboxConfig(config) {
38
37
  memoryMiB: DEFAULT_SANDBOX_MEMORY_MIB,
39
38
  }),
40
39
  idle: limits.idle ?? DEFAULT_SANDBOX_IDLE,
41
- sandboxes: limits.sandboxes ?? DEFAULT_MAX_SANDBOXES,
42
- ...(limits.ttl === undefined ? {} : { ttl: limits.ttl }),
43
- },
44
- lifecycle: {
45
- onExpiry: config.lifecycle?.onExpiry ?? "retain",
46
- stopGrace: config.lifecycle?.stopGrace ?? "10s",
40
+ environments: limits.environments ?? DEFAULT_MAX_ENVIRONMENTS,
47
41
  },
42
+ lifecycle: { stopGrace: config.lifecycle?.stopGrace ?? "10s" },
48
43
  placement: config.placement ?? { "*": { hosts: ["harness-container", "sandbox"] } },
49
44
  };
50
45
  }
51
46
  /** The stored configuration, or `{}` when the Tenant has none. */
52
47
  export async function readSandboxConfig(t) {
53
- const raw = await t.getSetting(SANDBOX_CONFIG_SETTING);
48
+ const raw = await t.getSetting(ENVIRONMENTS_CONFIG_SETTING);
54
49
  if (raw === undefined)
55
50
  return {};
56
- return TenantSandboxConfigSchema.parse(JSON.parse(raw));
51
+ return TenantEnvironmentsConfigSchema.parse(JSON.parse(raw));
57
52
  }
58
53
  export async function writeSandboxConfig(t, config) {
59
- await t.putSetting(SANDBOX_CONFIG_SETTING, JSON.stringify(config));
54
+ await t.putSetting(ENVIRONMENTS_CONFIG_SETTING, JSON.stringify(config));
60
55
  }
@@ -32,6 +32,7 @@ export interface SandboxSpec {
32
32
  readonly memoryMiB: number;
33
33
  readonly network: ResolvedNetwork;
34
34
  }
35
+ import type { DiskRoots } from "./disk-fs.js";
35
36
  export interface ExecRequest {
36
37
  readonly command: string;
37
38
  readonly cwd: string;
@@ -73,6 +74,11 @@ export interface SandboxHandle {
73
74
  writeFile(path: string, content: string | Uint8Array): Promise<void>;
74
75
  /** Release compute; files persist. */
75
76
  stop(): Promise<void>;
77
+ /**
78
+ * Where the disk's roots are, for disk versions (R2d step 3, `sandbox/disk-fs.ts`): the
79
+ * workspace, and in a pod the engine's `/harness`. Absent for a backend without a disk.
80
+ */
81
+ readonly diskRoots?: DiskRoots;
76
82
  }
77
83
  /** The files `listFiles` found: paths relative to the directory listed. */
78
84
  export interface SandboxListing {
@@ -0,0 +1,63 @@
1
+ -- Protocol 11: Environments (R2d), a fresh start (Q2). Sandbox resources and every vault but
2
+ -- the host's are dropped, not mapped: which Environment a person's key belongs in is the app's
3
+ -- mapping, and each seal binds its vault id. Sessions opened before protocol 11 are closed
4
+ -- (Q12): their history stays readable and a new turn is refused (`session_closed`).
5
+ CREATE TABLE "nylorun_streams"."environment_events" (
6
+ "environment_id" text COLLATE "C" NOT NULL,
7
+ "seq" bigint NOT NULL,
8
+ "type" text NOT NULL,
9
+ "body" json NOT NULL,
10
+ "committed_at" timestamp with time zone DEFAULT now() NOT NULL,
11
+ CONSTRAINT "environment_events_pkey" PRIMARY KEY("environment_id","seq")
12
+ );
13
+ --> statement-breakpoint
14
+ CREATE TABLE "nylorun"."environments" (
15
+ "id" text COLLATE "C" PRIMARY KEY NOT NULL,
16
+ "kind" text NOT NULL,
17
+ "labels" json NOT NULL,
18
+ "recipe" json NOT NULL,
19
+ "applied" json NOT NULL,
20
+ "version" integer DEFAULT 1 NOT NULL,
21
+ "applied_version" integer DEFAULT 1 NOT NULL,
22
+ "owner_user_id" text,
23
+ "last_used_at" timestamp with time zone DEFAULT now() NOT NULL,
24
+ "created_at" text COLLATE "C" NOT NULL,
25
+ "updated_at" text COLLATE "C" NOT NULL,
26
+ "k8s_name" text COLLATE "C",
27
+ "volume_gen" integer DEFAULT 0 NOT NULL,
28
+ "desired" text,
29
+ "observed" text,
30
+ "pod_uid" text,
31
+ "host_epoch" integer DEFAULT 0 NOT NULL,
32
+ "join_token_hash" text,
33
+ "rev" integer DEFAULT 0 NOT NULL,
34
+ "last_active_at" timestamp with time zone,
35
+ "started_at" timestamp with time zone,
36
+ "reason" text,
37
+ "retiring" text COLLATE "C",
38
+ "volume_id" text,
39
+ CONSTRAINT "environments_kind_check" CHECK ("nylorun"."environments"."kind" IN ('virtual', 'pod', 'none'))
40
+ );
41
+ --> statement-breakpoint
42
+ DROP TABLE "nylorun_streams"."sandbox_events" CASCADE;--> statement-breakpoint
43
+ DROP TABLE "nylorun"."sandbox_resources" CASCADE;--> statement-breakpoint
44
+ DELETE FROM "nylorun"."vaults" WHERE "id" <> 'host';--> statement-breakpoint
45
+ DELETE FROM "nylorun"."vault_idempotency" WHERE "id" NOT LIKE 'host-model%';--> statement-breakpoint
46
+ DELETE FROM "nylorun"."sandboxes";--> statement-breakpoint
47
+ DELETE FROM "nylorun"."sandbox_signals";--> statement-breakpoint
48
+ UPDATE "nylorun"."sessions" SET "body" = (("body"::jsonb - 'sandboxId' - 'sandboxSource' - 'sandboxOwnerId' - 'sandbox' - 'vaultIds' - 'credentialSelections') || '{"closedReason":"protocol_11"}'::jsonb)::json;--> statement-breakpoint
49
+ UPDATE "nylorun"."tenant_settings" SET "key" = 'environments.config', "value" = ((("value"::jsonb - 'default') #- '{limits,ttl}' #- '{lifecycle,onExpiry}' #- '{limits,sandboxes}') || CASE WHEN ("value"::jsonb #> '{limits,sandboxes}') IS NULL THEN '{}'::jsonb ELSE jsonb_build_object('limits', (("value"::jsonb -> 'limits') - 'sandboxes' - 'ttl') || jsonb_build_object('environments', "value"::jsonb #> '{limits,sandboxes}')) END)::text WHERE "key" = 'sandbox.config';--> statement-breakpoint
50
+ ALTER TABLE "nylorun"."vaults" DROP CONSTRAINT "vaults_scope_check";--> statement-breakpoint
51
+ DROP INDEX "nylorun"."sessions_sandbox";--> statement-breakpoint
52
+ DROP INDEX "nylorun"."vaults_owner";--> statement-breakpoint
53
+ DROP INDEX "nylorun"."vaults_one_host";--> statement-breakpoint
54
+ ALTER TABLE "nylorun"."sessions" ADD COLUMN "environment_id" text GENERATED ALWAYS AS (nylorun.doc(body)->>'environmentId') STORED;--> statement-breakpoint
55
+ ALTER TABLE "nylorun"."vaults" ADD COLUMN "environment_id" text COLLATE "C";--> statement-breakpoint
56
+ ALTER TABLE "nylorun"."vaults" ADD CONSTRAINT "vaults_environment_id_fkey" FOREIGN KEY ("environment_id") REFERENCES "nylorun"."environments"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
57
+ CREATE INDEX "sessions_environment" ON "nylorun"."sessions" USING btree ("environment_id");--> statement-breakpoint
58
+ CREATE UNIQUE INDEX "vault_credentials_name" ON "nylorun"."vault_credentials" USING btree ("vault_id","name");--> statement-breakpoint
59
+ CREATE UNIQUE INDEX "vaults_environment" ON "nylorun"."vaults" USING btree ("environment_id");--> statement-breakpoint
60
+ ALTER TABLE "nylorun"."sessions" DROP COLUMN "sandbox_id";--> statement-breakpoint
61
+ ALTER TABLE "nylorun"."vaults" DROP COLUMN "owner_user_id";--> statement-breakpoint
62
+ ALTER TABLE "nylorun"."vaults" DROP COLUMN "scope";--> statement-breakpoint
63
+ ALTER TABLE "nylorun"."vaults" ADD CONSTRAINT "vaults_owner_check" CHECK (("nylorun"."vaults"."id" = 'host') = ("nylorun"."vaults"."environment_id" IS NULL));
@@ -0,0 +1,7 @@
1
+ -- R2d step 3: an Environment's disk versions are one folder artifact it owns (environment_id),
2
+ -- and its row holds the disk lease (disk_op) and the version its next volume starts from
3
+ -- (disk_seed).
4
+ ALTER TABLE "nylorun"."artifacts" ADD COLUMN "environment_id" text COLLATE "C";--> statement-breakpoint
5
+ ALTER TABLE "nylorun"."environments" ADD COLUMN "disk_op" json;--> statement-breakpoint
6
+ ALTER TABLE "nylorun"."environments" ADD COLUMN "disk_seed" json;--> statement-breakpoint
7
+ CREATE UNIQUE INDEX "artifacts_environment_disk" ON "nylorun"."artifacts" USING btree ("environment_id") WHERE environment_id IS NOT NULL;
@@ -0,0 +1,5 @@
1
+ -- R7.1: the gate's own timing of a model call (its span): when it sent the call, when the answer
2
+ -- was complete, and how long the provider took to its first stream event. Null on older rows.
3
+ ALTER TABLE "nylorun"."model_usage" ADD COLUMN "started_at" text;--> statement-breakpoint
4
+ ALTER TABLE "nylorun"."model_usage" ADD COLUMN "ended_at" text;--> statement-breakpoint
5
+ ALTER TABLE "nylorun"."model_usage" ADD COLUMN "first_token_ms" integer;
@@ -0,0 +1 @@
1
+ CREATE INDEX "artifacts_creation_order" ON "nylorun"."artifacts" USING btree ("created_at","id");
@@ -0,0 +1,7 @@
1
+ -- Protocol 13: manifest 7, flat (no capabilities), with the Runtime's tools in a `runtime` block.
2
+ -- A fresh start for sessions: one opened before protocol 13 pinned a manifest 5 or 6, which the
3
+ -- engine no longer runs, so it is closed (`session_closed`) and its history stays readable. No
4
+ -- column changes: tool calls are read from the effect journal's documents, whose old
5
+ -- `capabilityId` field is ignored.
6
+ UPDATE "nylorun"."sessions" SET "body" = ("body"::jsonb || '{"closedReason":"protocol_13"}'::jsonb)::json
7
+ WHERE nylorun.doc("body") ->> 'closedReason' IS NULL;
@@ -0,0 +1,14 @@
1
+ CREATE TABLE "nylorun"."environment_manifests" (
2
+ "name" text COLLATE "C" NOT NULL,
3
+ "version" integer NOT NULL,
4
+ "body" json NOT NULL,
5
+ "hash" text COLLATE "C" NOT NULL,
6
+ "saved_by" json NOT NULL,
7
+ "created_at" text COLLATE "C" NOT NULL,
8
+ CONSTRAINT "environment_manifests_pkey" PRIMARY KEY("name","version")
9
+ );
10
+ --> statement-breakpoint
11
+ ALTER TABLE "nylorun"."environments" ADD COLUMN "manifest_name" text COLLATE "C";--> statement-breakpoint
12
+ ALTER TABLE "nylorun"."environments" ADD COLUMN "manifest_version" integer;--> statement-breakpoint
13
+ ALTER TABLE "nylorun"."environments" ADD COLUMN "manifest_hash" text COLLATE "C";--> statement-breakpoint
14
+ CREATE INDEX "environments_manifest" ON "nylorun"."environments" USING btree ("manifest_name","manifest_version");
@@ -0,0 +1 @@
1
+ ALTER TABLE "nylorun"."environments" ADD COLUMN "forked_from" json;
@@ -0,0 +1 @@
1
+ ALTER TABLE "nylorun"."environments" ADD COLUMN "image_digest" text COLLATE "C";
@@ -141,6 +141,62 @@
141
141
  "when": 1791530515498,
142
142
  "tag": "0019_sandbox_signal_outbox",
143
143
  "breakpoints": true
144
+ },
145
+ {
146
+ "idx": 20,
147
+ "version": "7",
148
+ "when": 1791702110945,
149
+ "tag": "0020_environments",
150
+ "breakpoints": true
151
+ },
152
+ {
153
+ "idx": 21,
154
+ "version": "7",
155
+ "when": 1791709466639,
156
+ "tag": "0021_disk_versions",
157
+ "breakpoints": true
158
+ },
159
+ {
160
+ "idx": 22,
161
+ "version": "7",
162
+ "when": 1791717547905,
163
+ "tag": "0022_model_usage_timing",
164
+ "breakpoints": true
165
+ },
166
+ {
167
+ "idx": 23,
168
+ "version": "7",
169
+ "when": 1791730977999,
170
+ "tag": "0023_artifact_pages",
171
+ "breakpoints": true
172
+ },
173
+ {
174
+ "idx": 24,
175
+ "version": "7",
176
+ "when": 1791986741535,
177
+ "tag": "0024_flat_manifest",
178
+ "breakpoints": true
179
+ },
180
+ {
181
+ "idx": 25,
182
+ "version": "7",
183
+ "when": 1791993934444,
184
+ "tag": "0025_environment_manifests",
185
+ "breakpoints": true
186
+ },
187
+ {
188
+ "idx": 26,
189
+ "version": "7",
190
+ "when": 1791995791323,
191
+ "tag": "0026_environment_forks",
192
+ "breakpoints": true
193
+ },
194
+ {
195
+ "idx": 27,
196
+ "version": "7",
197
+ "when": 1791997067694,
198
+ "tag": "0027_environment_image_digest",
199
+ "breakpoints": true
144
200
  }
145
201
  ]
146
202
  }