void 0.20.2 → 0.20.3

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 (68) hide show
  1. package/dist/{auth-cmd-gniL2fNt.mjs → auth-cmd-CzwquNiP.mjs} +3 -3
  2. package/dist/{auth-link-NZdjCmSc.mjs → auth-link-ElDTgF7j.mjs} +3 -3
  3. package/dist/{build-cmd-sI18tX_O.mjs → build-cmd-BpJe6boP.mjs} +1 -1
  4. package/dist/{cache-IHn5MwBC.mjs → cache-D98YTqeE.mjs} +1 -1
  5. package/dist/{cancel-deploy-C5qTOdLi.mjs → cancel-deploy-CPbEQLMG.mjs} +1 -1
  6. package/dist/cli/cli.mjs +27 -26
  7. package/dist/{client-dHfSJvAN.mjs → client-BQBrZoCX.mjs} +143 -78
  8. package/dist/{connect-Bfk31O_8.mjs → connect-WCQZ_u3m.mjs} +3 -3
  9. package/dist/{create-project-Bk9Z0-Jg.mjs → create-project-D0oXA090.mjs} +2 -3
  10. package/dist/{db-BkRoptAt.mjs → db-DJ-9qs3S.mjs} +2 -2
  11. package/dist/{delete-DouASY9P.mjs → delete-BZ4-WaGm.mjs} +1 -1
  12. package/dist/{deploy-DTaWUS1S.mjs → deploy-BAhhcg5q.mjs} +17 -10
  13. package/dist/{domain-1RhhOVrC.mjs → domain-BxAyhxXN.mjs} +1 -1
  14. package/dist/{email-C-lGh51B.mjs → email-Bj7Cvdwp.mjs} +2 -2
  15. package/dist/{env-DJHsPE7Z.mjs → env-DP_EErve.mjs} +1 -1
  16. package/dist/{github-cmd-PW7ZnWTp.mjs → github-cmd-C-z_xRrQ.mjs} +13 -19
  17. package/dist/index.mjs +4 -4
  18. package/dist/{init-BWZ7q5Z4.mjs → init-BGktCXgA.mjs} +4 -4
  19. package/dist/{link-Rmvu2Wl_.mjs → link-D2kbqhWb.mjs} +2 -2
  20. package/dist/{list-DEE2S6mY.mjs → list-CvkK_G7k.mjs} +1 -1
  21. package/dist/{login-Uvferzmm.mjs → login-WIjNc77c.mjs} +2 -2
  22. package/dist/{logs-27FenuiC.mjs → logs-dLUFCapG.mjs} +1 -1
  23. package/dist/{operator-cmd-CjOTmAYE.mjs → operator-cmd-CKJ7xIRs.mjs} +2 -2
  24. package/dist/{platform-auth-config-DrbQXXiW.mjs → platform-auth-config-CdVWRRJr.mjs} +2 -2
  25. package/dist/{platform-auth-protection-Bhtvp0B_.mjs → platform-auth-protection-Drl0qhrn.mjs} +2 -2
  26. package/dist/{platform-auth-recovery-CeOKGVeJ.mjs → platform-auth-recovery-CmKEWpDo.mjs} +2 -2
  27. package/dist/{platform-cmd-BFhieCdV.mjs → platform-cmd-5q_k56xS.mjs} +3 -3
  28. package/dist/{platform-domain-C74PULqV.mjs → platform-domain-4GiDlcqx.mjs} +2 -2
  29. package/dist/{platform-lifecycle-BwAIgz-t.mjs → platform-lifecycle-R9xAxvtG.mjs} +61 -25
  30. package/dist/{platform-management-COogu_Se.mjs → platform-management-BfWsXHEW.mjs} +5 -3
  31. package/dist/{platform-recovery-ewqLefp1.mjs → platform-recovery-CbK-I1FB.mjs} +2 -2
  32. package/dist/{project-cmd-DmZK9Hxf.mjs → project-cmd-CTdmnzvc.mjs} +12 -12
  33. package/dist/{project-team-D8jOJMUJ.mjs → project-team-CGxsQe3_.mjs} +4 -2
  34. package/dist/{project-token-DA34bf-C.mjs → project-token-Cirx7uwZ.mjs} +1 -1
  35. package/dist/{requests-CUExwGQQ.mjs → requests-4Nq59hOr.mjs} +1 -1
  36. package/dist/{rollback-CDNGU1gr.mjs → rollback-Dr7u0Ljx.mjs} +1 -1
  37. package/dist/runtime/remote/index.mjs +49 -8
  38. package/dist/runtime/sandbox.d.mts +4 -56
  39. package/dist/runtime/sandbox.mjs +81 -220
  40. package/dist/{secret-Bzzi2e9E.mjs → secret-AcPi-FoA.mjs} +1 -1
  41. package/package.json +7 -7
  42. package/skills/void/SKILL.md +2 -2
  43. package/skills/void/docs/guide/deployment.md +14 -14
  44. package/skills/void/docs/guide/email.md +12 -10
  45. package/skills/void/docs/guide/platform/administration/access.md +163 -0
  46. package/skills/void/docs/guide/platform/administration/email.md +121 -0
  47. package/skills/void/docs/guide/platform/administration/operations.md +97 -0
  48. package/skills/void/docs/guide/platform/administration/projects.md +54 -0
  49. package/skills/void/docs/guide/platform/development/local.md +119 -0
  50. package/skills/void/docs/guide/platform/development/runtime.md +124 -0
  51. package/skills/void/docs/guide/platform/development/schema-ci.md +95 -0
  52. package/skills/void/docs/guide/platform/installation/ci.md +55 -0
  53. package/skills/void/docs/guide/platform/installation/credentials.md +80 -0
  54. package/skills/void/docs/guide/platform/installation/domains.md +68 -0
  55. package/skills/void/docs/guide/platform/installation/first-deployment.md +82 -0
  56. package/skills/void/docs/guide/platform/installation/maintenance.md +137 -0
  57. package/skills/void/docs/guide/platform/installation/prerequisites.md +86 -0
  58. package/skills/void/docs/guide/platform/installation/setup.md +169 -0
  59. package/skills/void/docs/guide/platform/installation/uninstall.md +54 -0
  60. package/skills/void/docs/guide/platform-administration.md +6 -414
  61. package/skills/void/docs/guide/platform-development.md +5 -316
  62. package/skills/void/docs/guide/project-collaboration.md +1 -1
  63. package/skills/void/docs/guide/sandboxes.md +9 -24
  64. package/skills/void/docs/guide/self-hosted-platform.md +11 -694
  65. package/skills/void/docs/reference/api.md +34 -34
  66. package/skills/void/docs/reference/cli.md +28 -11
  67. package/skills/void/docs/reference/config.md +1 -1
  68. package/skills/void/docs/reference/resource-inference.md +10 -10
@@ -6,321 +6,10 @@ outline: deep
6
6
 
7
7
  The framework, CLI, and platform live in one repository. You can change the platform, test it locally, and deploy a runtime built from your fork into your own Cloudflare account.
8
8
 
9
- If you want to run the released platform without changing its implementation, start with [Install a Void Platform](./self-hosted-platform.md). Use [Platform Administration](./platform-administration.md) for managing an installed platform.
9
+ If you want to run the released platform without changing its implementation, start with [Install a Void Platform](/guide/self-hosted-platform). Use [Platform Administration](/guide/platform-administration) for managing an installed platform.
10
10
 
11
- ## Setting Up the Repository
11
+ ## Development Guides
12
12
 
13
- Clone your fork and install the workspace dependencies with Vite+:
14
-
15
- ```sh
16
- git clone https://github.com/your-org/void.git
17
- cd void
18
- vp install
19
- vpr install:void-dev
20
- void-dev --help
21
- ```
22
-
23
- Use the Node.js version recorded in `.node-version`. The workspace uses public npm packages; a GitHub Packages token is not required.
24
-
25
- `install:void-dev` builds the CLI, shared packages, and platform runtime, then makes this checkout's built CLI globally available as `void-dev`. Public packages export their built files, so run `vp run build:core` after later source changes to refresh the alias. The installer refuses to replace an unrelated global command. Remove only this checkout's alias with `vpr uninstall:void-dev`. All commands in this guide run from the repository root.
26
-
27
- ## Finding the Implementation
28
-
29
- | Directory | Purpose |
30
- | ---------------------------------------------------- | -------------------------------------------------------------------- |
31
- | `packages/void` | Framework, application runtime, and CLI |
32
- | `packages/platform` | Installer contracts, packaged Workers, and platform migrations |
33
- | `packages/deploy-core`, `packages/deploy-cloudflare` | Shared deployment contracts and Cloudflare upload code |
34
- | `platform/packages/api` | Users, projects, deployments, provisioning, and administrator API/UI |
35
- | `platform/packages/dispatch` | Application routing and static assets |
36
- | `platform/packages/proxy` | AI, remote bindings, and revalidation |
37
- | `platform/packages/tail` | Runtime log ingestion |
38
- | `platform/packages/dashboard` | Dashboard source and local UI components in `ui/` |
39
-
40
- The `@voidcloud/*` names identify workspace implementation packages. Their `private: true` flags prevent publishing those packages to npm. Deployable core Workers are bundled into the public `@void/platform` package.
41
-
42
- The core installer creates the API, dispatch, proxy, and tail Workers. The dashboard and managed GitHub build services are available in the source tree but are not included in that installation. Adding an optional service requires its infrastructure, bindings, authentication, and capability configuration together.
43
-
44
- ## Running the API Locally
45
-
46
- Start a local PostgreSQL server and make `psql` and `pg_isready` available on your path. Then create the development database, apply its migrations, and seed an administrator:
47
-
48
- ```sh
49
- vp run --filter @voidcloud/api setup --admin-email dev@example.com
50
- vp run --filter @voidcloud/api dev --local --enable-containers=false --host localhost --port 8787
51
- ```
52
-
53
- The command disables the optional build containers, so basic API and admin work
54
- does not require Docker. To develop managed builds, install Docker and run the
55
- API with containers enabled.
56
-
57
- Open `http://localhost:8787/admin/`. Setup writes local development values to the API and dashboard `.dev.vars` files, including the development authentication bypass and local database connection. Those files are ignored by Git. Production installations get separate credentials through the installer.
58
-
59
- The API's development bypass lets you work on the browser admin UI without setting up OAuth. Operator CLI sessions still require administrator authentication; they do not use the browser bypass.
60
-
61
- ## Running the Dashboard Locally
62
-
63
- The dashboard is a separate source app. After API setup, start it in another terminal:
64
-
65
- ```sh
66
- vp run --filter @voidcloud/dashboard dev
67
- ```
68
-
69
- Its local `.dev.vars` should point to the API you started:
70
-
71
- ```dotenv
72
- API_URL=http://localhost:8787
73
- SITE_DOMAIN=apps.example.com
74
- ```
75
-
76
- Open the Vite URL and choose **Dev login (local API)**. That button appears for a localhost API and uses the local development sign-in endpoint.
77
-
78
- You can also point the dashboard at an API that you operate. If Cloudflare Access protects that API, install `cloudflared` and opt into the dashboard's local token helper with matching origins:
79
-
80
- ```dotenv
81
- API_URL=https://platform.example.com
82
- CF_ACCESS_APP_URL=https://platform.example.com
83
- SITE_DOMAIN=apps.example.com
84
- ```
85
-
86
- The helper refreshes an Access session before the dev server starts. Human
87
- dashboard requests require the user's Access session as well as their Void login;
88
- a service token does not represent that user. Service-token pairs are for scoped
89
- machine operations. This is dashboard development configuration; Access
90
- credentials are separate from platform login credentials.
91
-
92
- For a deployed dashboard, bind its `API` service to your platform API, configure
93
- `DASHBOARD_URL` on both the dashboard and API, and include that exact dashboard origin in the
94
- platform's Access protection application. The dashboard passes the browser's
95
- company identity to the API using that service binding. Its login page shows
96
- the platform's currently enabled methods, and **Account** supports adding an
97
- additional login identity.
98
-
99
- ## Testing Changes
100
-
101
- Run tests for the area you changed while developing:
102
-
103
- ```sh
104
- vp test run platform/packages/api/test/integration/operator-auth.test.ts
105
- vp run check
106
- ```
107
-
108
- Before preparing a release, build the packages and run the complete checks:
109
-
110
- ```sh
111
- vp run build:all
112
- vp run check
113
- vp lint
114
- vp run lint:platform
115
- vp fmt --check
116
- vp test run
117
- vp run build:docs
118
- ```
119
-
120
- Platform integration tests use their local test database by default. To test against PostgreSQL, set `VOID_TEST_DATABASE_URL` to a disposable database: these tests clear tables between cases.
121
-
122
- To exercise a deployed application, deploy a disposable copy of `playground/kitchen-sink` and pass its URL as `SMOKE_URL` to the smoke test described in `platform/scripts/kitchen-sink-smoke-test.md`. That test creates and removes application data.
123
-
124
- ## Deploying Your Runtime
125
-
126
- Build the runtime. From a Git checkout, the build automatically records the current commit in the runtime manifest. An uncommitted checkout is recorded with a `-dirty` suffix:
127
-
128
- ```sh
129
- vp run build:core
130
- ```
131
-
132
- Build systems may set `VOID_PLATFORM_SOURCE_REVISION` when they need to override automatic detection with another immutable revision. A source archive without Git metadata builds normally but leaves the revision unrecorded.
133
-
134
- The runtime is written to `packages/platform/dist/runtime`. Use the built CLI to preview a new installation from those files:
135
-
136
- ```sh
137
- void-dev platform install \
138
- --name my-team \
139
- --application-domain example.app \
140
- --zone example.app \
141
- --runtime packages/platform/dist/runtime \
142
- --plan
143
- ```
144
-
145
- Before applying the plan, complete the [first-install walkthrough](./self-hosted-platform.md). Run the command without `--plan` to install. For testing before your domain is ready, replace `--application-domain` and `--zone` with `--workers-dev`; PostgreSQL and the runtime/GitHub/R2 credentials are still needed. Use `void-dev` in place of `void` and keep `--runtime packages/platform/dist/runtime` on install and resume commands. For an interrupted installation, keep that runtime build available until it completes.
146
-
147
- Later, run `void-dev platform domain set example.app`. Domain setup uses the existing installed runtime and needs no `--runtime`, rebuild, or app redeploy. It keeps the platform API URL and original workers.dev app URLs available.
148
-
149
- For an existing installation, preview an upgrade using its connection ID:
150
-
151
- ```sh
152
- void-dev platform upgrade <installation-id> \
153
- --runtime packages/platform/dist/runtime --plan
154
- ```
155
-
156
- Then run it without `--plan` to apply the upgrade. Source-built runtimes go through the same artifact, database, ownership, and health checks as released runtimes. The CLI preserves a disabled installation's state and records the source revision in its installation checkpoint.
157
-
158
- ## Optional GitHub Webhook Ingress for Access-Protected APIs
159
-
160
- The core installer does not deploy the dashboard, GitHub App, build Containers,
161
- or webhook ingress. If a source-built installation adds those optional services
162
- and Cloudflare Access protects its API hostname, GitHub cannot deliver directly
163
- to `/webhooks/github`: GitHub does not present your Access credentials. Do not add
164
- an Everyone or bypass policy to the API application.
165
-
166
- The API source package includes an optional, path-isolated Worker for this case.
167
- It accepts only `POST /github`, validates GitHub's signature over the raw body,
168
- and forwards one authenticated internal operation over an API service binding.
169
- The API independently verifies both that internal proof and GitHub's signature
170
- before running the normal webhook handler. Installations without perimeter
171
- protection can continue using the API's direct `/webhooks/github` endpoint.
172
-
173
- To deploy the optional ingress:
174
-
175
- 1. Deploy the source API/build runtime containing the internal operation and its
176
- build bindings, then finish the separate GitHub App/build-service
177
- configuration. A core install or upgrade alone does not add managed builds.
178
- Enable the platform's managed-build capability only when that infrastructure
179
- is ready.
180
- 2. Edit `platform/packages/api/wrangler.github-webhook-ingress.jsonc`. Give the
181
- ingress a name unique to the installation and set its `API` service binding to
182
- the exact installed API Worker name. Keep its public hostname separate from
183
- every human/API hostname covered by Access.
184
- 3. Deploy it from the repository root:
185
-
186
- ```sh
187
- vp run --filter @voidcloud/api deploy:github-webhook-ingress --env production
188
- ```
189
-
190
- Use `--env staging` for the staging entries in the same config.
191
-
192
- 4. In the Cloudflare dashboard, add encrypted Worker secrets. Set the GitHub
193
- App's existing `GITHUB_WEBHOOK_SECRET` on both the API and ingress Workers.
194
- Generate a separate high-entropy value, such as `openssl rand -base64 32`,
195
- and set it as `GITHUB_WEBHOOK_INGRESS_SECRET` on both Workers. Do not reuse a
196
- platform management, JWT, Access, or GitHub webhook credential for that value.
197
- 5. In the GitHub App settings, keep **Content type** set to `application/json`,
198
- keep the same webhook secret, and change **Webhook URL** to the isolated
199
- ingress URL ending in `/github`. Use GitHub's test delivery and confirm a 2xx
200
- response before relying on push builds.
201
-
202
- The ingress has no login, dashboard, project, operator, proxy, or arbitrary
203
- forwarding route. It does not make the GitHub integration part of the core
204
- installer, provision build executors, create a GitHub App, configure Cloudflare
205
- Access, or manage either Worker's secrets. Its body limit is 25 MiB, based on
206
- GitHub's [documented 25 MB webhook payload cap](https://docs.github.com/en/webhooks/webhook-events-and-payloads#payload-cap);
207
- malformed or larger deliveries are rejected before event processing.
208
-
209
- ## Deploying Source Builds from CI {#source-build-ci}
210
-
211
- Build `@void/platform` from your checkout and pass its runtime directory to `install`, `upgrade`, `repair`, `enable`, or `rollback` with `--runtime`. Custom runtimes get the same integrity, migration, health, and rollback checks as packaged releases.
212
-
213
- Void records the runtime's manifest digest, whether it was packaged or custom, and its source revision. A build from a Git checkout automatically records `HEAD`, or `<HEAD>-dirty` when the checkout has uncommitted files. Build systems can set `VOID_PLATFORM_SOURCE_REVISION` to override automatic detection.
214
-
215
- A fresh CI runner can discover the installation each time. Set `CLOUDFLARE_API_TOKEN` and `VOID_PLATFORM_DATABASE_URL` through its protected environment, then:
216
-
217
- ::: details CI commands and recovery inputs
218
-
219
- ```sh
220
- vp run build:core
221
-
222
- export VOID_PLATFORM_REGISTRY_DIR="$RUNNER_TEMP/void-platform-registry"
223
- export VOID_PLATFORM_RECOVERY_KEY="$(openssl rand -base64 32)"
224
- node packages/void/dist/cli/cli.mjs platform discover --account "$CLOUDFLARE_ACCOUNT_ID" \
225
- --installation "$VOID_PLATFORM_INSTALLATION"
226
- node packages/void/dist/cli/cli.mjs platform upgrade "$VOID_PLATFORM_INSTALLATION" \
227
- --runtime packages/platform/dist/runtime --plan
228
- node packages/void/dist/cli/cli.mjs platform upgrade "$VOID_PLATFORM_INSTALLATION" \
229
- --runtime packages/platform/dist/runtime --yes
230
- ```
231
-
232
- Omit the installation selector only if the account has one discoverable installation. Run one deployment per installation at a time, and let it finish before starting the next. Cancelling during migrations or Worker rollout can leave an installation waiting for recovery.
233
-
234
- Keep the management token, database URL, JWT signing secret, email signing secret for email-enabled installations, and complete project-encryption keyring in a protected CI environment. Upgrades inherit deployed Worker secrets. The original values are needed when recreating a missing Worker; configuration credentials are also needed when explicitly rotating them.
235
-
236
- :::
237
-
238
- ## Changing the Platform Schema
239
-
240
- The schema lives in `platform/packages/api/src/schema.ts`. Generate a migration after changing it:
241
-
242
- ```sh
243
- vp run --filter @voidcloud/api db:generate
244
- ```
245
-
246
- Review the generated SQL and migration journal before committing them. Released migrations are append-only. An upgrade applies new migrations while the previous Workers may still serve requests, so schema changes must remain compatible with that code.
247
-
248
- `platform/packages/api/drizzle/compatibility.json` records which earlier runtimes have been verified against the new schema. Add an edge only after testing that compatibility. The runtime build checks that the migration files and recorded schema history agree. See `packages/platform/README.md` for the manifest contract.
249
-
250
- ## CI in a Fork
251
-
252
- The uncredentialed test workflows use GitHub-hosted runners in forks. They build and test the workspace without requiring Void Cloud accounts, tokens, or deployment access.
253
-
254
- If your fork has a released platform version, set the repository variable
255
- `VOID_PLATFORM_PRODUCTION_REF` to its immutable 40-character commit SHA. Platform
256
- pull requests then create that version's database, seed representative user,
257
- project, and encrypted-secret records, and apply the proposed migrations. The
258
- check verifies existing data and runs the previous runtime against the upgraded
259
- schema. Mutable branch or tag names are rejected.
260
-
261
- Without an explicit SHA, required compatibility checks use the latest successful
262
- GitHub deployment to `Prod` (or `VOID_PLATFORM_PRODUCTION_ENV`). They require
263
- read access to deployment history and stop if no completed deployment is found.
264
- Advancing the production branch does not change the selected baseline. Fork
265
- workflows that call platform CI must grant `deployments: read` alongside
266
- `contents: read`.
267
-
268
- The upstream repository also contains workflows for deploying Void Cloud and publishing the official npm packages. Forks should configure their own release workflow around the built CLI and `platform upgrade --runtime`; the [source-build CI example](#source-build-ci) shows the required inputs. Keep production credentials in protected environments restricted to the appropriate release refs.
269
-
270
- Public releases use matching versions for the CLI, scaffolder, adapters, and
271
- packaged platform. The publish workflow rejects mismatched versions and previously
272
- unpublished `void` versions that npm cannot reuse. Stable versions use `latest`;
273
- prereleases use their named channel, such as `beta` or `rc`. Numeric prereleases
274
- use `next`. The scaffolder installs its exact matching CLI version, so
275
- `create-void@beta` cannot silently select the stable CLI. Packaged platform
276
- runtimes record the release commit as their source revision.
277
-
278
- The npm release job uses [trusted publishing](https://docs.npmjs.com/trusted-publishers/)
279
- from GitHub-hosted runners, with `id-token: write` and no stored npm publishing
280
- token. Configure a trusted publisher for each public package using this
281
- repository, `publish.yml`, and the `Release` environment, allowing direct
282
- `npm publish`. A brand-new package
283
- needs an initial authenticated publication before its trusted publisher can be
284
- configured; subsequent releases use OIDC.
285
-
286
- The managed build fallback CLI also derives its version from
287
- `packages/void/package.json`; there are no separate version pins to update.
288
- Build its image from the repository root with
289
- `docker build --file platform/packages/api/container/Dockerfile .`.
290
- The root `.dockerignore` limits that build context to the agent, Dockerfile,
291
- and public SDK manifest.
292
-
293
- Publishing requires both SDK CI and platform CI, including the platform unit and
294
- API integration suites. Release tags also run the Windows SDK checks; a passing
295
- SDK-only build cannot publish a changed control plane.
296
-
297
- ### Retrying a Release
298
-
299
- To retry a failed release without moving an existing tag, add `+retry.N` to a
300
- new Git tag, with `N` starting at `1`. Keep the package versions unchanged:
301
-
302
- | Git tag | Package version | npm channel |
303
- | ------------------------ | --------------- | ----------- |
304
- | `v0.21.0` | `0.21.0` | `latest` |
305
- | `v0.21.0+retry.1` | `0.21.0` | `latest` |
306
- | `v0.21.0-beta.1+retry.2` | `0.21.0-beta.1` | `beta` |
307
-
308
- For example, when the packages are at `0.21.0`, commit the release fix and tag
309
- that commit:
310
-
311
- ```sh
312
- git tag -a 'v0.21.0+retry.1' -m 'Retry 0.21.0 publication.'
313
- git push origin 'refs/tags/v0.21.0+retry.1'
314
- ```
315
-
316
- The retry suffix belongs only in the Git tag, not in `package.json`. A `-1`
317
- suffix is a distinct prerelease version, not a retry. Tag and package versions
318
- are checked before dependency installation and the full CI jobs; retries still
319
- run the normal release checks.
320
-
321
- Retries publish only package versions that are still missing from npm. They
322
- cannot replace an already-published version. If an earlier attempt partially
323
- published the release and you changed its package contents, bump the version
324
- instead of combining different contents under the same version.
325
-
326
- For implementation history, use the design archive at `platform/meta/design-docs/README.md`. Its proposals explain earlier decisions; the source and current guides define the supported behavior.
13
+ - [Local Development](/guide/platform/development/local)
14
+ - [Runtime and Source Builds](/guide/platform/development/runtime)
15
+ - [Schema and CI](/guide/platform/development/schema-ci)
@@ -91,4 +91,4 @@ void project team remove <user-id>
91
91
  void project team revoke <invitation-id>
92
92
  ```
93
93
 
94
- A non-owner member can leave with `void project team leave`. The owner cannot leave; an installation administrator must [transfer ownership](./platform-administration.md#transferring-project-ownership) first.
94
+ A non-owner member can leave with `void project team leave`. The owner cannot leave; an installation administrator must [transfer ownership](./platform/administration/projects.md#transferring-project-ownership) first.
@@ -4,23 +4,6 @@ outline: deep
4
4
 
5
5
  # Sandboxes
6
6
 
7
- > **Managed platform beta paused:** New managed Sandbox deployments and retained
8
- > Sandbox rollbacks are currently disabled. Native Cloudflare deployments keep
9
- > using Cloudflare Sandboxes directly. Platform operators upgrading an existing
10
- > installation must preview and complete
11
- > `void platform system sandbox-drain` before reopening platform traffic. The
12
- > preview is bounded; pass its `nextCursor` back with `--cursor` to inspect later
13
- > pages. Apply is resumable through a leased database checkpoint: rerun it after
14
- > active deployments settle, after it advances a page, or after resolving any
15
- > ownership verification blocker.
16
-
17
- For an `unverified_container` blocker, use the reported resource, project,
18
- binding, application ID, and application name to compare the application's
19
- Durable Object namespace with the project's managed dispatch script. Never
20
- delete an account application by name alone. Remove the application and stale
21
- resource row only after proving that both belong to this platform installation,
22
- then rerun the drain.
23
-
24
7
  Use a Cloudflare Sandbox to run commands, work with files, and expose ports from server code. Each session gets an isolated container.
25
8
 
26
9
  ```ts
@@ -36,7 +19,7 @@ export const POST = defineHandler(async (c) => {
36
19
  });
37
20
  ```
38
21
 
39
- Importing from `void/sandbox` enables the `SANDBOX` Durable Object binding, exports the SDK's `Sandbox` class from the generated Worker entry, and adds the matching `containers` and migration metadata to the Cloudflare worker config.
22
+ Importing from `void/sandbox` enables the required Sandbox resources. Native Cloudflare deployments add the `SANDBOX` Durable Object and Container metadata to the Worker. Void Platform deployments provide the same runtime API through a managed Sandbox controller.
40
23
 
41
24
  ## Configuration
42
25
 
@@ -59,8 +42,8 @@ Available fields:
59
42
 
60
43
  | Field | Default | Description |
61
44
  | ------------------- | -------------------------- | --------------------------------------------------------------------- |
62
- | `binding` | `SANDBOX` | Worker binding name |
63
- | `className` | `Sandbox` | Durable Object class exported by the Worker |
45
+ | `binding` | `SANDBOX` | Binding name for local and native Cloudflare use |
46
+ | `className` | `Sandbox` | Durable Object class for local and native Cloudflare use |
64
47
  | `containerName` | `void-sandbox` | Cloudflare container app name |
65
48
  | `image` | Matching sandbox SDK image | Dockerfile path or registry image for local and native Cloudflare use |
66
49
  | `imageBuildContext` | Directory of `image` | Docker build context for local and native Cloudflare use |
@@ -81,13 +64,13 @@ await sandbox.writeFile('/tmp/input.txt', 'hello');
81
64
  const result = await sandbox.exec('cat /tmp/input.txt');
82
65
  ```
83
66
 
84
- You can also use the namespace directly from `c.env.SANDBOX` when you need lower-level Durable Object control.
67
+ For code that must run on both deployment targets, use `getSandbox()`. Direct access through `c.env.SANDBOX` is available only on local and native Cloudflare deployments; managed platforms intentionally expose the application Sandbox API without the underlying lifecycle namespace.
85
68
 
86
69
  ## State persistence
87
70
 
88
- A sandbox has a persistent Durable Object identity and a container that can restart:
71
+ A sandbox has a Durable Object identity and a container that can restart:
89
72
 
90
- `getSandbox(id)` selects the same Durable Object for that ID across deploys and rollbacks. Data saved in its persistent storage, including its SQLite database, survives container restarts. Use that storage for session metadata and other state you need to keep.
73
+ `getSandbox(id)` selects the same Durable Object for that ID within a deployment. Native Cloudflare deployments preserve that namespace across Worker versions. Each managed platform deployment has its own namespace; rolling back to a retained deployment reconnects to that deployment's namespace.
91
74
 
92
75
  Files, running processes, exposed ports, and in-memory shell sessions last only as long as the container. It can stop after inactivity (the SDK defaults to `sleepAfter: "10m"`), crash, or restart during platform scheduling. `keepAlive: true` disables the idle timer but doesn't prevent other restarts.
93
76
 
@@ -95,6 +78,8 @@ Save anything you need to keep in Durable Object storage, your database, KV, or
95
78
 
96
79
  ## Deployment
97
80
 
98
- `void deploy` provisions the `SANDBOX` Durable Object namespace, attaches the Cloudflare Container metadata to the Worker upload, and creates or updates the matching container application in the Void platform account.
81
+ `void deploy` creates a deployment-scoped Sandbox controller and container application in the Void platform account. The controller owns container lifetime, concurrency admission, and runtime accounting; the application receives only the Sandbox operations exposed by `getSandbox()`.
99
82
 
100
83
  Platform deploys require a registry image reference. The default sandbox works without extra config. If `sandbox.image` points at a custom local Dockerfile, also set `sandbox.platformImage` to an image you have already pushed to a registry.
84
+
85
+ Managed Sandboxes require Workers Paid on the platform's Cloudflare account. The platform runtime token needs Account / Containers: Edit and Account / Cloudchamber: Edit. These are checked only when an application that uses Sandbox is deployed; installing or upgrading a platform and deploying other applications does not probe Containers access.