@nylorun/runtime 0.10.0-beta → 0.11.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 (190) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +53 -51
  3. package/dist/adapters/execution/restate.d.ts +130 -0
  4. package/dist/adapters/execution/restate.js +442 -0
  5. package/dist/adapters/sandbox/virtual.js +1 -1
  6. package/dist/adapters/streams/s2.d.ts +18 -0
  7. package/dist/adapters/streams/s2.js +361 -0
  8. package/dist/core/executors.d.ts +4 -1
  9. package/dist/core/executors.js +20 -1
  10. package/dist/core/flow-host.d.ts +93 -132
  11. package/dist/core/flow-host.js +282 -547
  12. package/dist/core/sandbox-routes.d.ts +8 -3
  13. package/dist/core/sandbox-routes.js +10 -10
  14. package/dist/execution/memory.d.ts +54 -0
  15. package/dist/execution/memory.js +217 -0
  16. package/dist/execution/types.d.ts +125 -0
  17. package/dist/execution/types.js +52 -0
  18. package/dist/host/config-for.d.ts +2 -1
  19. package/dist/host/config-for.js +3 -21
  20. package/dist/host/config.d.ts +0 -8
  21. package/dist/host/create-host.d.ts +36 -1
  22. package/dist/host/create-host.js +48 -24
  23. package/dist/host/execution.d.ts +61 -0
  24. package/dist/host/execution.js +69 -0
  25. package/dist/host/http.d.ts +4 -0
  26. package/dist/host/http.js +6 -0
  27. package/dist/host/index.d.ts +3 -1
  28. package/dist/host/index.js +2 -0
  29. package/dist/host/main.js +106 -47
  30. package/dist/host/stack-config.d.ts +72 -0
  31. package/dist/host/stack-config.js +193 -0
  32. package/dist/index.d.ts +1 -1
  33. package/dist/infra/database.d.ts +16 -0
  34. package/dist/infra/database.js +31 -0
  35. package/dist/infra/execution.d.ts +39 -0
  36. package/dist/infra/execution.js +68 -0
  37. package/dist/infra/index.d.ts +42 -0
  38. package/dist/infra/index.js +56 -0
  39. package/dist/infra/readiness.d.ts +33 -0
  40. package/dist/infra/readiness.js +53 -0
  41. package/dist/infra/streams.d.ts +17 -0
  42. package/dist/infra/streams.js +33 -0
  43. package/dist/infra/workers.d.ts +39 -0
  44. package/dist/infra/workers.js +31 -0
  45. package/dist/model/pi-model.d.ts +2 -2
  46. package/dist/model/pi-model.js +5 -5
  47. package/dist/sandbox/manager.d.ts +26 -8
  48. package/dist/sandbox/manager.js +95 -47
  49. package/dist/sandbox/select.d.ts +1 -1
  50. package/dist/sandbox/select.js +4 -5
  51. package/dist/sandbox/types.d.ts +2 -2
  52. package/dist/store/canonical.d.ts +5 -0
  53. package/dist/store/canonical.js +17 -0
  54. package/dist/store/cursor.d.ts +9 -0
  55. package/dist/store/cursor.js +18 -0
  56. package/dist/store/memory.d.ts +57 -0
  57. package/dist/store/memory.js +643 -0
  58. package/dist/store/ownership.d.ts +19 -0
  59. package/dist/store/ownership.js +33 -0
  60. package/dist/store/postgres/connect.d.ts +25 -0
  61. package/dist/store/postgres/connect.js +25 -0
  62. package/dist/store/postgres/locking.d.ts +16 -0
  63. package/dist/store/postgres/locking.js +22 -0
  64. package/dist/store/postgres/migrations/001_initial.d.ts +27 -0
  65. package/dist/store/postgres/migrations/001_initial.js +196 -0
  66. package/dist/store/postgres/migrations/index.d.ts +49 -0
  67. package/dist/store/postgres/migrations/index.js +75 -0
  68. package/dist/store/postgres/names.d.ts +11 -0
  69. package/dist/store/postgres/names.js +42 -0
  70. package/dist/store/postgres/store.d.ts +11 -0
  71. package/dist/store/postgres/store.js +790 -0
  72. package/dist/store/postgres/tenants.d.ts +90 -0
  73. package/dist/store/postgres/tenants.js +207 -0
  74. package/dist/store/types.d.ts +440 -0
  75. package/dist/store/types.js +10 -0
  76. package/dist/streams/basin.d.ts +23 -0
  77. package/dist/streams/basin.js +51 -0
  78. package/dist/streams/memory.d.ts +25 -0
  79. package/dist/streams/memory.js +124 -0
  80. package/dist/streams/relay.d.ts +37 -0
  81. package/dist/streams/relay.js +254 -0
  82. package/dist/streams/types.d.ts +115 -0
  83. package/dist/streams/types.js +86 -0
  84. package/dist/tenant/actions.d.ts +153 -0
  85. package/dist/tenant/actions.js +191 -0
  86. package/dist/tenant/advance.d.ts +15 -0
  87. package/dist/tenant/advance.js +439 -0
  88. package/dist/tenant/auth.d.ts +11 -0
  89. package/dist/tenant/auth.js +34 -0
  90. package/dist/tenant/commands.d.ts +3 -0
  91. package/dist/tenant/commands.js +384 -0
  92. package/dist/tenant/context.d.ts +140 -0
  93. package/dist/tenant/context.js +40 -0
  94. package/dist/tenant/effects.d.ts +20 -0
  95. package/dist/tenant/effects.js +539 -0
  96. package/dist/tenant/envelope.d.ts +0 -3
  97. package/dist/tenant/envelope.js +2 -34
  98. package/dist/tenant/ephemeral.d.ts +15 -4
  99. package/dist/tenant/ephemeral.js +106 -38
  100. package/dist/tenant/http.d.ts +32 -0
  101. package/dist/tenant/http.js +51 -0
  102. package/dist/tenant/live.d.ts +92 -0
  103. package/dist/tenant/live.js +290 -0
  104. package/dist/tenant/model-setting.d.ts +16 -0
  105. package/dist/tenant/model-setting.js +12 -0
  106. package/dist/tenant/module.d.ts +29 -8
  107. package/dist/tenant/module.js +162 -158
  108. package/dist/tenant/paths.d.ts +12 -8
  109. package/dist/tenant/paths.js +38 -12
  110. package/dist/tenant/principals.d.ts +9 -13
  111. package/dist/tenant/principals.js +31 -38
  112. package/dist/tenant/quarantine-error.d.ts +1 -1
  113. package/dist/tenant/quarantine-error.js +2 -8
  114. package/dist/tenant/quarantine.d.ts +0 -8
  115. package/dist/tenant/quarantine.js +8 -30
  116. package/dist/tenant/reset.d.ts +7 -6
  117. package/dist/tenant/reset.js +7 -51
  118. package/dist/tenant/routes-tenant.d.ts +12 -0
  119. package/dist/tenant/routes-tenant.js +126 -0
  120. package/dist/tenant/routes.d.ts +9 -0
  121. package/dist/tenant/routes.js +142 -0
  122. package/dist/tenant/runtime.d.ts +59 -58
  123. package/dist/tenant/runtime.js +243 -2201
  124. package/dist/tenant/scheduler.d.ts +25 -0
  125. package/dist/tenant/scheduler.js +84 -0
  126. package/dist/tenant/session.d.ts +60 -0
  127. package/dist/tenant/session.js +94 -0
  128. package/dist/tenant/sessions.d.ts +34 -0
  129. package/dist/tenant/sessions.js +149 -0
  130. package/dist/tenant/status.d.ts +13 -4
  131. package/dist/tenant/status.js +76 -41
  132. package/dist/tenant/store-memory.d.ts +9 -12
  133. package/dist/tenant/store-memory.js +79 -68
  134. package/dist/tenant/store-pg.d.ts +15 -0
  135. package/dist/tenant/store-pg.js +140 -0
  136. package/dist/tenant/streams.d.ts +126 -0
  137. package/dist/tenant/streams.js +419 -0
  138. package/dist/tenant/sweep.d.ts +15 -0
  139. package/dist/tenant/sweep.js +122 -0
  140. package/dist/tenant/types.d.ts +95 -15
  141. package/dist/tenant/types.js +23 -1
  142. package/dist/tenant/worker.d.ts +84 -0
  143. package/dist/tenant/worker.js +189 -0
  144. package/dist/vault/service.d.ts +37 -31
  145. package/dist/vault/service.js +439 -359
  146. package/dist/version.d.ts +1 -1
  147. package/dist/version.js +1 -1
  148. package/package.json +13 -13
  149. package/dist/adapters/sandbox/microsandbox.d.ts +0 -2
  150. package/dist/adapters/sandbox/microsandbox.js +0 -238
  151. package/dist/core/store.d.ts +0 -32
  152. package/dist/core/store.js +0 -143
  153. package/dist/launcher/commands.d.ts +0 -24
  154. package/dist/launcher/commands.js +0 -260
  155. package/dist/launcher/ensure-config.d.ts +0 -16
  156. package/dist/launcher/ensure-config.js +0 -79
  157. package/dist/launcher/errors.d.ts +0 -12
  158. package/dist/launcher/errors.js +0 -22
  159. package/dist/launcher/host-config.d.ts +0 -17
  160. package/dist/launcher/host-config.js +0 -64
  161. package/dist/launcher/host-state.d.ts +0 -17
  162. package/dist/launcher/host-state.js +0 -61
  163. package/dist/launcher/lifecycle.d.ts +0 -66
  164. package/dist/launcher/lifecycle.js +0 -407
  165. package/dist/launcher/locks.d.ts +0 -26
  166. package/dist/launcher/locks.js +0 -117
  167. package/dist/launcher/logs.d.ts +0 -18
  168. package/dist/launcher/logs.js +0 -117
  169. package/dist/launcher/main.d.ts +0 -2
  170. package/dist/launcher/main.js +0 -66
  171. package/dist/launcher/output.d.ts +0 -11
  172. package/dist/launcher/output.js +0 -68
  173. package/dist/launcher/paths.d.ts +0 -20
  174. package/dist/launcher/paths.js +0 -36
  175. package/dist/launcher/probe.d.ts +0 -23
  176. package/dist/launcher/probe.js +0 -72
  177. package/dist/launcher/protocol.d.ts +0 -62
  178. package/dist/launcher/protocol.js +0 -1
  179. package/dist/launcher/schema-guard.d.ts +0 -6
  180. package/dist/launcher/schema-guard.js +0 -36
  181. package/dist/launcher/spawn.d.ts +0 -22
  182. package/dist/launcher/spawn.js +0 -85
  183. package/dist/launcher/status.d.ts +0 -6
  184. package/dist/launcher/status.js +0 -65
  185. package/dist/tenant/migration.d.ts +0 -16
  186. package/dist/tenant/migration.js +0 -116
  187. package/dist/tenant/schema.d.ts +0 -23
  188. package/dist/tenant/schema.js +0 -151
  189. package/dist/tenant/store-fs.d.ts +0 -16
  190. package/dist/tenant/store-fs.js +0 -205
package/CHANGELOG.md CHANGED
@@ -1,5 +1,51 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.11.0-beta
4
+
5
+ ### Minor Changes
6
+
7
+ - bf1c2da: **`nylorun dev --ephemeral` runs on the Docker stack, with a Tenant-level fixture model (breaking beta).**
8
+
9
+ - `nylorun dev --ephemeral` creates a temporary Tenant through `@nylorun/admin` (no Project link written), seeds it from `.env` with the fixture model, opens Studio on it and runs the watcher; the Tenant is deleted with its active work cancelled when the watcher ends, Ctrl-C included. It needs a Runtime that advertises `tenant-fixture-model`.
10
+ - `PUT /v1/tenant/config/seed` accepts `fixtureModel: true`, stored as Tenant setting `model.fixture`: that Tenant's model calls use the Runtime's fixture model while other Tenants on the Host keep theirs. `HOST_PROTOCOL` advertises the new optional feature `tenant-fixture-model` (`OPTIONAL_HOST_FEATURES` in `@nylorun/core/compatibility`); clients do not require it.
11
+ - `startEphemeralRuntime()` keeps its signature but its Tenants live in memory instead of SQLite under the Host root; nothing survives `close()`.
12
+ - Closing a Tenant waits for running advances at most the advance grace period (30 s by default) and then abandons them; their lease lapses and the next advance takes over.
13
+ - A Worker stop, Tenant close or ended Restate attempt no longer fails or cancels the turn it interrupts: outcomes already returned are recorded, nothing is settled, and the next advance resumes the turn from its checkpoint. Only a user cancel settles `cancelled`; an advance deadline fails the turn with the deadline's message.
14
+
15
+ - bf1c2da: **The microsandbox backend is removed; the Runtime runs sandbox tools on the virtual backend only.** The optional `microsandbox` dependency is gone. `sandbox.backend` and `NYLORUN_SANDBOX` accept `auto` or `virtual`, and `auto` selects `virtual`. A Tenant that stored `microsandbox` reads it as `auto`. `nylorun doctor sandbox` and the `nylorun dev` banner report only the virtual shell.
16
+ - bf1c2da: **Tenants are Postgres schemas only; SQLite and the `nylorun-runtime` launcher are removed (breaking beta).**
17
+
18
+ - The Runtime runs on Postgres (the Session Store, one schema per Tenant), Restate (Durable Session Execution: one advance per session, fenced by an ownership epoch, and a per-Tenant sweep) and S2 (Durable Streams: every event is written to a Postgres outbox and relayed to the session's stream, which history and SSE read). `--role api|worker|all` selects the process role; `/ready` covers Postgres, Restate and S2.
19
+ - SQLite Tenants are not migrated. On first start the Runtime moves every `tenants/<id>/` directory that holds a `tenant.sqlite` to `trash/<id>-sqlite-<time>/` and logs `sqlite_tenant_moved_to_trash`; recreate those Tenants.
20
+ - `@nylorun/runtime` has no bin: the `nylorun-runtime` launcher and `host-state.json` are gone. The Runtime runs as the `ghcr.io/nylorun/runtime` image (`nylorun start`); its Host entry requires `NYLORUN_DATABASE_URL`.
21
+ - `openTenantRuntime(config, hooks)` requires the Tenant's opened `store` and `envelope`; `OpenTenantRuntime` receives them from the Tenant store. `HostStateFile` is no longer exported.
22
+ - `@nylorun/core`: `LAUNCHER_PROTOCOL` and the launcher error codes are removed; `QuarantineSchema` drops `locked`, `lockPath` and `lockPid`; `TenantStatusSchema.checks.sqlite` is now `checks.store`. `TenantStatusSchema` gains optional `execution` (stuck invocations) and `streams` (basin, outbox depth, relay lag); `HostAggregateSchema` gains optional `outboxDepth` and `relayLagMs`.
23
+
24
+ - bf1c2da: **Tenants can register a Studio principal.** `CreateTenantRequest` gains optional `studioCredentialHash` behind the new protocol feature `studio-principal`; the Runtime stores it as application principal `studio`, and idempotent create compares it too. `@nylorun/admin` exports `deriveStudioToken(adminKey, tenantId)` (HMAC-SHA256 over `nylorun/studio/v1`, NUL, Tenant id) and `createTenant` sends the hash of that key, so Studio can reach any Tenant's API with a key derived from the admin key. Clients require the new feature, so upgrade the Runtime with them.
25
+ - 1d84b3e: **Native Windows is no longer supported; Windows developers use WSL2.** Nylorun runs on macOS and Linux. On native Windows, `nylorun` and `npm create @nylorun/agent` stop with WSL2 guidance. Install Node 24 and Docker (Docker Desktop's WSL integration) inside your WSL distribution and keep projects in its Linux filesystem. The Windows-only process handling (`taskkill`, `.cmd` shims, `npm.cmd`) is removed. `nylorun doctor` reports WSL as `Linux (WSL: <distribution>)`.
26
+
27
+ ### Patch Changes
28
+
29
+ - ba1b239: **`nylorun` sets up the local stack; `@nylorun/cli` becomes the Runtime client `nylo` (breaking beta).**
30
+
31
+ - New unscoped package **`nylorun`**: `npx nylorun up` sets up the Docker stack on the first run and starts it after that, from any directory; `npx nylorun down` stops it (volumes are kept). `up` and `down` are aliases of `start` and `stop`. It also owns `status`, `logs`, `studio`, `reset` and `doctor`, pins the Runtime and Studio images (`package.json` `nylorun.runtime` / `nylorun.studio`), depends on `@nylorun/core` only, and never creates Tenants.
32
+ - **`@nylorun/cli`** is the Runtime client with the command **`nylo`**: `nylo tenant create [name]` (creates the Tenant; in a project, writes the Project link and seeds the model provider and sandbox from `.env`), `nylo tenant current|list|use|status|reset|delete`, `nylo configure`, `nylo env` (was `nylorun status --env`) and `nylo doctor sandbox`. It no longer provides the `nylorun` command or the stack commands.
33
+ - **Removed:** `nylorun dev` and `nylorun dev --ephemeral`. Link once with `nylo tenant create`, then run the project's own `npm run dev`. Moved commands exit 2 and name their replacement.
34
+ - **Starter:** the generated project depends on `@nylorun/agents` only (no Nylorun devDependency); `dev` is `tsx watch --env-file-if-exists=.env src/main.ts`. `npm create @nylorun/agent` installs the project and prints the next steps (`npx nylorun up`, `npx @nylorun/cli tenant create`, `npm run dev`) instead of starting development; `--no-open` is accepted and ignored.
35
+ - `connectAgents` names those steps when it finds no Runtime connection. Runtime repair hints, model errors and core's sandbox message name `nylo` and `nylorun up`.
36
+
37
+ - 262bded: A Tenant's stream wiring no longer logs after it stops. A basin repair that failed after the Tenant closed could write to a Tenant log directory that was already removed and end the process with an unhandled rejection.
38
+ - Pin core to the tested release.
39
+ - Pin harness to the tested release.
40
+ - Updated dependencies [bf1c2da]
41
+ - Updated dependencies [ba1b239]
42
+ - Updated dependencies [bf1c2da]
43
+ - Updated dependencies [bf1c2da]
44
+ - Updated dependencies [bf1c2da]
45
+ - Updated dependencies
46
+ - @nylorun/core@0.6.0-beta
47
+ - @nylorun/harness@0.19.1-beta
48
+
3
49
  ## 0.10.0-beta
4
50
 
5
51
  ### Minor Changes
package/README.md CHANGED
@@ -15,51 +15,53 @@ npm run build --workspace @nylorun/harness
15
15
  npm run build --workspace @nylorun/runtime
16
16
  ```
17
17
 
18
- ## Install and the launcher
19
-
20
- Developers install the Runtime as a prerequisite; nothing downloads it for
21
- them ([runtime distribution](../docs/design/runtime-distribution.md)):
22
-
23
- ```sh
24
- node --version # 24 or newer
25
- npm install --global @nylorun/runtime # provides nylorun-runtime
26
- nylorun-runtime --version
27
- ```
28
-
29
- The **launcher** (`nylorun-runtime`, source in `src/launcher/`, not listed in
30
- `exports`) starts, stops and restarts the Host on the Node it runs on, from
31
- this package. Clients (CLI, desktop apps) find it on PATH and run it as a
32
- process; prefer `nylorun runtime up`. A project may instead add this package
33
- as a devDependency to pin its Runtime version; do not make it an application
34
- production dependency. For tests and ephemeral embeds, use
35
- `startEphemeralRuntime()` from `@nylorun/runtime/core`. See
36
- [MIGRATION.md](../MIGRATION.md#runtime-clients-and-admin-api-breaking-beta) and
37
- [building a desktop client](../docs/building-a-desktop-client.md).
38
-
39
- Default address: loopback port `8787` (persisted in `host.json`). The Host root
40
- is `NYLORUN_HOME` or `~/.nylorun`. Tenants live under `tenants/<tenantId>/`.
18
+ ## Running the Runtime
19
+
20
+ The Runtime runs as the `ghcr.io/nylorun/runtime` image, next to Postgres,
21
+ Restate and S2: `nylorun start` runs that stack on a developer machine. The
22
+ package is a library with no bin; its Host entry is `@nylorun/runtime/server`
23
+ (`dist/host/main.js`), which requires `NYLORUN_DATABASE_URL`. For tests and
24
+ ephemeral embeds, use `startEphemeralRuntime()` from `@nylorun/runtime/core`.
25
+ See [MIGRATION.md](../MIGRATION.md).
26
+
27
+ No Tenant state lives only in the Runtime process. Each Tenant's data is the
28
+ Postgres schema `tenant_<id>` (the Session Store); Restate runs one advance of a session at a
29
+ time and holds the Tenant's sweep timer (Durable Session Execution); every
30
+ session's events are relayed from the schema's outbox to its own S2 stream,
31
+ which history and SSE read (Durable Streams). An API node serves the Tenant API,
32
+ Admin API and SSE, and a Worker runs advances; `--role api|worker|all` picks
33
+ them, and the local stack runs one process with `all`.
34
+
35
+ The container is configured by its environment, which the stack's Compose file
36
+ sets: `NYLORUN_DATABASE_URL` (required), `NYLORUN_RESTATE_INGRESS_URL`,
37
+ `NYLORUN_RESTATE_ADMIN_URL`, `NYLORUN_WORKER_URL` and
38
+ `NYLORUN_RESTATE_IDENTITY_KEY` (Restate), `NYLORUN_S2_ENDPOINT` and
39
+ `NYLORUN_S2_TOKEN`, and in container mode `NYLORUN_LISTEN_HOST`,
40
+ `NYLORUN_LISTEN_PORT`, `NYLORUN_ALLOWED_HOSTS` and `NYLORUN_PUBLIC_URL`.
41
+
42
+ The Host root is `NYLORUN_HOME` or `~/.nylorun` (bind-mounted at `/nylorun` in
43
+ the stack). What stays on the Host is under `tenants/<tenantId>/`.
41
44
 
42
45
  ## Layout
43
46
 
44
47
  ```text
45
48
  <host root>/
46
- host.json # format 1: hostId, bind, port, runtimeVersion, …
47
- host-state.json # pid, url — removed on shutdown
49
+ host.json # format 1: hostId, host, port, runtimeVersion, …
48
50
  host-credentials.json # adminKey (0600)
49
- runtime.log
50
- tenants/<tenantId>/ # envelope, SQLite, KEK, logs, sandboxes, …
51
- trash/ # deleted Tenants
51
+ stack/ # compose.yaml, .env (0600), Restate identity key
52
+ tenants/<tenantId>/ # vault-kek, plugin-data, logs, home, tmp, sandboxes
53
+ trash/ # SQLite Tenants from before the Postgres switch
52
54
  ```
53
55
 
54
56
  ## HTTP surface
55
57
 
56
58
  | Route | Auth | Notes |
57
59
  | --- | --- | --- |
58
- | `GET /health` | none | `service: "nylorun-runtime"`, `hostId`, protocol `{min,max,features}` (includes `admin-status`), pid |
59
- | `GET /ready` | none | Listener up and Tenant discovery finished |
60
+ | `GET /health` | none | `service: "nylorun-runtime"`, `hostId`, protocol `{min,max,features}`, pid |
61
+ | `GET /ready` | none | Listener up, Tenants discovered, and Postgres, Restate and S2 answer (`checks`) |
60
62
  | `GET /v1/admin/status` | admin key | `AdminStatusSchema`; alias `GET /v1/admin/host` |
61
63
  | `/v1/admin/tenants*` | admin key | Create / list / get / delete Tenants |
62
- | `POST /v1/admin/host/shutdown` | admin key | Launcher-private; not in `@nylorun/admin` |
64
+ | `POST /v1/admin/host/shutdown` | admin key | Host-private; not in `@nylorun/admin` |
63
65
  | `/v1/*` Tenant routes | application or executor | Require `Nylorun-Tenant` + `Nylorun-Protocol` |
64
66
 
65
67
  Every route checks `Host` first (`421 host_rejected`), rejects any `Origin`
@@ -72,7 +74,10 @@ authentication. Unknown, quarantined or rejected Tenant credentials → opaque
72
74
 
73
75
  Tests and ephemeral embeds use `startEphemeralRuntime()` from
74
76
  `@nylorun/runtime/core`: private Host on port 0, temporary Host root, one Tenant,
75
- returns `{ url, tenantId, applicationKey, adminKey, close() }`.
77
+ returns `{ url, tenantId, applicationKey, adminKey, close() }`. It is not durable:
78
+ its Tenants live in memory and are gone after `close()`. The smoke checks'
79
+ temporary Tenants (`scripts/lib/temporary-tenant.mjs`) do not use it; they are
80
+ created on the Docker stack.
76
81
 
77
82
  Register executors with `PUT /v1/executors` using the application principal
78
83
  (application-mode `connectAgents` does this with derived tokens). Model gateway
@@ -87,36 +92,33 @@ definition/session APIs; executor credentials authorize authenticated SSE
87
92
  connect, action discovery, claims, renewal and results. Session observers cannot
88
93
  claim actions.
89
94
 
90
- SQLite transactions persist session checkpoints, command receipts, individual
91
- effects/actions, waits and canonical history — **per Tenant**. One process owns
92
- each Tenant database (`.runtime-lock`). Keep the database and its WAL/journal
93
- together. Vault ciphertext needs that Tenant's own KEK.
95
+ Postgres transactions persist session checkpoints, command receipts, individual
96
+ effects/actions, waits and the event outbox — **per Tenant schema**; history is
97
+ read from Durable Streams (S2). An advance owns its session through a lease with
98
+ an epoch; a Worker that takes over after a crash marks in-flight effects
99
+ `uncertain`. Vault ciphertext needs that Tenant's own KEK.
94
100
 
95
101
  Agents that declare `.use(sandbox())` get Runtime-executed sandbox tools. The
96
102
  Tenant owns each sandbox; backend names are prefixed `nylorun-<tenant-id>-`.
97
103
 
98
104
  ## Local Project workflow
99
105
 
100
- Install `@nylorun/cli` as a devDependency. `nylorun runtime up` starts the Host
101
- via the launcher; `nylorun dev` creates or uses a Project link and runs
102
- `src/main.ts` under `tsx watch`. Studio is `nylorun-studio` / `npm run studio`.
103
-
104
- ```sh
105
- eval "$(npx nylorun runtime status --env)"
106
- # → NYLORUN_RUNTIME_URL, NYLORUN_SERVER_KEY, NYLORUN_TENANT
107
- ```
106
+ A project depends on `@nylorun/agents` only. `npx nylorun up` runs the local
107
+ stack (Docker); `npx @nylorun/cli tenant create` (`nylo`) creates the
108
+ project's Tenant and writes its Project link; the project's `npm run dev` runs
109
+ `src/main.ts` under `tsx watch`; `npx nylorun studio` opens Studio.
108
110
 
109
111
  ## Troubleshooting
110
112
 
111
113
  | Symptom | What to do |
112
114
  | --- | --- |
113
- | Tenant `locked` | Another process holds `.runtime-lock`. `nylorun tenant status` prints `repair` |
114
- | `kek-missing` | Restore the Tenant KEK beside the database |
115
- | `corrupt` / `migration-failed` / `envelope-invalid` | Follow `nylorun tenant status` repair string |
116
- | `schema-too-new` / `host_schema_newer` | Upgrade the Host build (`nylorun runtime restart`) |
115
+ | `kek-missing` | Restore `vault-kek` in the Tenant directory |
116
+ | `corrupt` / `migration-failed` / `envelope-invalid` / `open-failed` / `open-timeout` | Follow the `nylo tenant status` repair string |
117
+ | `schema-too-new` | Run a Runtime at least as new as the one that migrated the schema |
117
118
  | `426 protocol_unsupported` | Upgrade clients or Host to a compatible set |
118
- | `421 host_rejected` / `403 origin_rejected` | Call from main process / Node; loopback Host only |
119
- | Port in use | Explicit `--port` fails closed. First setup may pick a free loopback port |
120
- | Logs | `nylorun runtime logs [--follow]` |
119
+ | `421 host_rejected` / `403 origin_rejected` | Call from a server process, not a browser; in a container, list the `Host` in `NYLORUN_ALLOWED_HOSTS` |
120
+ | `503` for a Tenant | Postgres or Restate is unreachable; `GET /ready` names which |
121
+ | Port in use | Change `NYLORUN_PORT` in `<Host root>/stack/.env` and run `nylorun up` |
122
+ | Logs | `nylorun logs runtime` |
121
123
 
122
124
  Definitions have no `agent.run()`; applications use `@nylorun/agents`.
@@ -0,0 +1,130 @@
1
+ import { type DurableExecution, type StuckInvocation, type Wake, type WorkerHandlers } from "../../execution/types.js";
2
+ export interface RestateTimeouts {
3
+ /**
4
+ * How long an invocation may run without journal progress before Restate
5
+ * asks it to suspend. An advance makes no journal entries while it runs, so
6
+ * this must exceed the longest segment. Default one hour.
7
+ */
8
+ inactivityMs?: number;
9
+ /** How long after the inactivity timeout Restate aborts the attempt. Default one hour. */
10
+ abortMs?: number;
11
+ }
12
+ /**
13
+ * Retries of a handler that throws (an infrastructure error). After
14
+ * `maxAttempts` the invocation is paused, never killed, and shows up in
15
+ * `listStuckInvocations` until an operator resumes it.
16
+ */
17
+ export interface RestateRetry {
18
+ /** Default 100. */
19
+ initialIntervalMs?: number;
20
+ /** Default 30000. */
21
+ maxIntervalMs?: number;
22
+ /** Default 2. */
23
+ exponentiationFactor?: number;
24
+ /** Attempts, including the first, before pausing. Default 70. */
25
+ maxAttempts?: number;
26
+ }
27
+ export interface RestateExecutionOptions {
28
+ /** Restate ingress, e.g. `http://restate:8080`. */
29
+ ingressUrl: string;
30
+ /** Restate admin API, e.g. `http://restate:9070`. Needed by `start`. */
31
+ adminUrl: string;
32
+ /** Where `start` serves the Worker endpoint (HTTP/2 cleartext). */
33
+ workerListen?: {
34
+ host: string;
35
+ port: number;
36
+ };
37
+ /** The endpoint URL Restate calls, registered by `start`. */
38
+ workerAdvertisedUrl?: string;
39
+ /**
40
+ * Prepended to every service name, so several Runtimes (or test runs) can
41
+ * share one Restate server without taking each other's invocations.
42
+ * Letters, digits and `_` only. Default "".
43
+ */
44
+ servicePrefix?: string;
45
+ /**
46
+ * Request identity public keys (`publickeyv1_...`). When given, the Worker
47
+ * endpoint accepts only requests signed by a Restate server holding the
48
+ * matching private key.
49
+ */
50
+ identityKeys?: string[];
51
+ timeouts?: RestateTimeouts;
52
+ retry?: RestateRetry;
53
+ /** Delay between sweep passes of one Tenant. Default 5000. */
54
+ sweepIntervalMs?: number;
55
+ /**
56
+ * How long wakes with a `dedupeKey` are remembered. Default and minimum
57
+ * 24 hours (§12.3).
58
+ */
59
+ dedupeRetentionMs?: number;
60
+ /**
61
+ * Overwrite a deployment already registered at `workerAdvertisedUrl`, so a
62
+ * restarted Worker with changed code takes effect. Default true, which suits
63
+ * a stable URL on a developer machine. Rolling upgrades should advertise a
64
+ * versioned URL instead (§14.6).
65
+ */
66
+ forceRegistration?: boolean;
67
+ /** How long `start` keeps retrying registration while Restate comes up. Default 60000. */
68
+ registrationTimeoutMs?: number;
69
+ /** Replaces the SDK's console logging. */
70
+ logger?: (level: string, message: string) => void;
71
+ }
72
+ /** A Restate invocation that needs an operator: paused, or retrying after failures. */
73
+ export type { StuckInvocation };
74
+ export declare function createRestateExecution(options: RestateExecutionOptions): RestateExecution;
75
+ export declare class RestateExecution implements DurableExecution {
76
+ private readonly options;
77
+ private handlers?;
78
+ private stopping;
79
+ private server?;
80
+ private readonly sessions;
81
+ private readonly controllers;
82
+ private readonly inflight;
83
+ private readonly names;
84
+ private readonly ingressUrl;
85
+ private readonly adminUrl;
86
+ private readonly sweepIntervalMs;
87
+ constructor(options: RestateExecutionOptions);
88
+ /** Service names this execution registers, for diagnostics and tests. */
89
+ get serviceNames(): {
90
+ session: string;
91
+ tenant: string;
92
+ timer: string;
93
+ };
94
+ wake(tenantId: string, sessionId: string, wake: Wake): Promise<void>;
95
+ timer(tenantId: string, key: string, at: Date): Promise<void>;
96
+ armSweep(tenantId: string): Promise<void>;
97
+ disarmSweep(tenantId: string): Promise<void>;
98
+ /**
99
+ * Readiness: the admin API (`/health`), which `start` registers with, and the
100
+ * ingress (`/restate/health`), which every wake, timer and sweep goes
101
+ * through, both answer.
102
+ */
103
+ probe(signal: AbortSignal): Promise<void>;
104
+ /** This Runtime's paused or backing-off invocations for `tenantId` (Tenant status). */
105
+ stuckInvocations(tenantId: string): Promise<StuckInvocation[]>;
106
+ start(handlers: WorkerHandlers): Promise<void>;
107
+ stop(): Promise<void>;
108
+ private definitions;
109
+ /** Runs `advance` with a signal aborted by `stop` or by the end of the Restate attempt. */
110
+ private runAdvance;
111
+ /** Runs a Worker handler so that `stop` waits for it. Refuses once stopping; Restate retries. */
112
+ private runTracked;
113
+ private staleSweepMs;
114
+ private serviceOptions;
115
+ /** One-way send through the ingress. Retries while the ingress is unreachable or overloaded. */
116
+ private send;
117
+ /** Registers the Worker endpoint with the admin API, retrying until Restate is up. */
118
+ private register;
119
+ }
120
+ /**
121
+ * Lists invocations of this Runtime's services that need an operator: paused
122
+ * after exhausting retries, or backing off after a failure. Reads Restate's
123
+ * SQL introspection (`POST /query` on the admin API).
124
+ */
125
+ export declare function listStuckInvocations(options: {
126
+ adminUrl: string;
127
+ servicePrefix?: string;
128
+ tenantId?: string;
129
+ limit?: number;
130
+ }): Promise<StuckInvocation[]>;