Deployment and CI

The versioned commands below use the published 0.9.0-beta.5 package. The release page describes its redesigned dashboard, starter navigation and existing scope boundaries. Earlier public versions keep their original behavior. Review storage and upgrades before changing versions.

On this page

Worlds runs on your machine, in CI or on a private server. The dashboard and CLI use the same local runtime, which needs no Sparta account or hosted control plane. The beta.5 includes optional aggregate usage reporting; tests, records and evidence remain local. New onboarding discloses the default-on choice with an opt-out. Existing users and unknown CLI/CI installations remain off until a saved choice; WORLDS_TELEMETRY=0 or DO_NOT_TRACK=1 hard-disables reporting. Previously published packages keep their original behavior.

Use Start here
Interactive testing Local dashboard
Terminal and automated tests CLI and CI
A shared runtime Shared servers

You need Node 24 or newer. macOS and Linux are supported; Windows is unverified. Website beta signup unlocks first-party installation instructions on Get started.

Local dashboard workflow

Use the complete printed 127.0.0.1 address, including its #token=... fragment, or rerun the command to obtain a fresh one. Beta.4 also supports the validated localhost loopback alias. The older beta.3 package rejects that hostname substitution; return to its printed address.

The dashboard starts a loopback host and owns a runtime under the project's .worlds-dashboard/ directory, which it adds to .gitignore. Closing the browser leaves work running; stopping the host stops its owned runtime. The host runs one executable job at a time and retains history until explicitly deleted. After host loss, unfinished jobs become interrupted, without automatic reruns.

Reopening an active project preserves jobs and browser sessions. If the active host uses a different runtime version, port or connection, use that host or stop it before changing settings.

For an existing runtime, --connect <url> attaches without taking ownership; stopping the dashboard leaves that runtime running. Admin credentials come from the launcher's environment. The dashboard stays on loopback; remote access uses SSH forwarding.

Follow the dashboard guide to describe a test, review its starting situation and success rules, connect an agent and inspect results. Beta.5 uses Tests as home and exposes Starter workflows through Templates; older packages retain their version’s navigation. Saved-input reruns retain test inputs, but do not snapshot agent code or dependencies. Commands run in the selected project; interactive terminal input remains a CLI workflow.

CLI and CI

For a long-running local API server:

For automated agent tests, use the workflow generated by worlds init, described in the CLI quickstart. It pins the runtime version and uses --server auto to start and stop a temporary server within the job. Public users do not need the private repository's GitHub Action. Internal team CI is permitted by the beta license.

Run a trusted test harness

worlds run -- <command> starts a temporary server on a free port, requires authentication and passes WORLDS_URL, WORLDS_ADMIN_TOKEN and WORLDS_PUBLIC_URL to the command. This is for a trusted harness, which can administer every world on that server. Agent evaluation uses passk or try, which withhold the admin token from the agent.

The wrapper returns the command's exit code and cleans up its temporary server. Command failures export world dumps, request logs and the run log to a directory named on stderr. Review that evidence before uploading it to CI artifacts; it may contain private data.

Run options and exit behavior
Option Effect
--seed <name> Create one world and provide WORLDS_BASE_URL, WORLDS_API_KEY and WORLDS_WORLD_ID.
--evidence <dir> Choose where failure evidence is written.
--port <n> Request a fixed port; a busy port is refused.
--timeout <sec> Stop the command's process tree on timeout; exit 124.
--keep Retain the temporary data directory after the wrapper exits.
--no-preload Disable the Stripe SDK preload; configure the agent's SDK endpoint yourself.

passk --server auto and try --server auto manage their own temporary server. Their --keep-worlds option retains its data directory too.

Wrapper setup failures use exit 3 for server, port or directory failures and 2 for an invalid seed or unstartable command. SIGINT and SIGTERM stop the command tree and return 128 + signal; requested interruption does not trigger the wrapper's failure-evidence export.

The result contract

For Stripe and legacy-desk workflows, passk, try, selftest and doctor return status, reason, next_action and exit_code in JSON. Text output ends with status: and next: lines.

Exit Status Meaning
0 passed The command's checks passed.
1 policy_failed Outcomes failed, or the agent exited unsuccessfully after reaching the world.
2 configuration_incomplete Invalid configuration or an agent command that cannot start.
3 setup_failed The server or required world could not be prepared.
4 inconclusive No agent traffic in a keyed run, unsupported API calls, or unavailable/failed grading.

When several conditions apply, precedence is setup, configuration, inconclusive, then policy failure. An interrupted evaluation is inconclusive but exits 128 + signal. Follow the reported next action before treating a run as a verdict about the agent.

Native Zendesk and combined runs have a separate report format. worlds-zendesk-results uses failed for exit 1, rather than policy_failed, and has no reason or next_action fields. Native diagnostics use worlds-zendesk-doctor with reason_code and reached/missing surfaces. Parse the declared format; see native results and exit codes.

Shared servers

Use one server per trust domain. The operator token reaches every world; world tokens can administer one existing world, including destroying it. There is no project or tenant scope. Teams that must not see each other's worlds need separate servers.

Admin authentication

Configuration Default admin authentication
Loopback, no token Off, for trusted local processes.
WORLDS_ADMIN_TOKEN set Required, including on loopback.
Non-loopback bind Required; an operator token is created if absent.
--trust-proxy / WORLDS_TRUST_PROXY=1 Required, including on loopback.

An auto-created token is printed on its first start and saved at <data-dir>/operator-token with mode 0600. Later starts load it and print only its path. Configured tokens must be at least 16 characters. GET /admin/health needs no token and reports the auth mode.

Creating worlds needs the operator token. The create response's admin_token administers only that world. Agents receive the connector api_key and base_url; keep both kinds of admin token with the harness. See admin authentication for token rotation and endpoints.

Local browser protection and trust boundaries

Unauthenticated loopback admin requests require a loopback/localhost Host. Browser requests also need a matching Origin. Opaque and cross-site origins are refused, including for health checks. Custom hostnames and proxies should use token-protected access.

This protects against browser-driven operations and DNS rebinding. It does not isolate an untrusted agent process: any local process can reach an unauthenticated admin API. Removing admin credentials from the agent environment is credential hygiene, not process isolation.

WORLDS_AUTH=required forces authentication. WORLDS_AUTH=off overrides the default and warns when exposed; the loopback browser guard does not protect an exposed unauthenticated server.

TLS and reverse proxies

Worlds serves HTTP. Terminate TLS at a reverse proxy and keep the runtime port private. With a local proxy, bind Worlds to loopback, pin WORLDS_PUBLIC_URL=https://worlds.internal.example.com, and set WORLDS_ADMIN_TOKEN or WORLDS_AUTH=required. A pinned public URL alone does not enable authentication.

Alternatively, enable WORLDS_TRUST_PROXY=1 and forward X-Forwarded-Host and X-Forwarded-Proto. Worlds uses the first hop in each chain; the proxy must control those headers. Proxy trust enables admin authentication by default.

Point clients at the proxy origin through WORLDS_URL. Verify a connector SDK call through that origin, since a health check alone does not prove the returned base_url works.

Storage and upgrades

Run one server process per data directory. Locks and coordination are in-process; a second server sharing the directory is unsupported.

Worlds stores one SQLite file per world. Storage is disposable: WAL with synchronous=OFF can lose recent writes on a crash. Export needed evidence and keep source seeds and suites separately.

There is no automatic expiry. Destroy worlds after tests; listing retained worlds opens their files, so large directories accumulate handles and slow listing. Incompatible-schema or damaged files appear as unreadable in world listings and are refused with 409 elsewhere, without preventing startup. World files are not migrated: inspect the reason, destroy disposable incompatible worlds and recreate them from saved inputs.

The beta.5 and current source use world schema 7 as the base for path-scoped native creation replay. Schema-6 files from beta.3 and earlier are refused, including Stripe-only worlds, because the version applies to the whole world file. Before upgrading, use the old writer runtime to export any needed settled state, retain your original seeds and suites, and back up the project. Stop the old host before starting the new version. Create a new world from compatible saved inputs; replay-cache history does not carry over. No migration or in-place cache clearing is performed.

Optional profiles have additional schema barriers: SAP/Dataverse use schema 8, Confluence 10, Freshservice 11, JSM foundations 12 and Agentforce Runtime 13. Browser commerce uses a separate schema-14 world profile. The selected profile determines the required format; these numbers do not imply a sequence of automatic migrations. Old runtimes must not be assumed to read newer files. Preserve originals before opening any data with another version. Schema refusal does not promise byte preservation of active SQLite WAL/SHM files when an older SQLite reader inspects them; stop the writer and copy settled data for recovery.

Dashboard history stays in .worlds-dashboard/ until deleted. Keep that directory, credentials, identity maps and detailed local evidence out of shared artifacts. Review worlds/workspace.json before sharing; it can contain machine-specific commands and private environment-file paths.

Compatibility

The TypeScript and Python clients check the admin protocol on their first create/list operation and raise IncompatibleServerError for a mismatch. A handle built directly with a world token does not perform that handshake.

Treat non-empty diff.unknown_resources as do not grade. Upgrade compatible client and server versions before asserting that nothing else changed.

Platforms and operational details

Linux and macOS are tested. Windows remains unverified; process-tree cleanup uses taskkill /T /F and is best effort. The runtime needs Node 24+; the JavaScript client alone supports Node 18+.

Server settings
Setting Flag / environment
Bind address and port --host, --port; defaults 127.0.0.1:4242.
Data directory --data-dir / WORLDS_DATA_DIR; default ./.worlds.
Additional seeds --seeds-dir / WORLDS_SEEDS_DIR; default ./seeds, layered over the bundled library.
Additional scenarios --scenarios-dir / WORLDS_SCENARIOS_DIR; default ./scenarios, layered over the bundled library.
Advertised origin --public-url / WORLDS_PUBLIC_URL.
Freshservice reserved authority (experimental beta.5) --freshservice-authority / WORLDS_FRESHSERVICE_AUTHORITY; pair with the Freshservice public URL.
Freshservice advertised base (experimental beta.5) --freshservice-public-url / WORLDS_FRESHSERVICE_PUBLIC_URL; full HTTP(S) URL, including any proxy mount.
Proxy headers --trust-proxy / WORLDS_TRUST_PROXY=1; --no-trust-proxy overrides the environment.
Admin token --admin-token / WORLDS_ADMIN_TOKEN.
Authentication --auth / WORLDS_AUTH: required or off.
Optional aggregate reporting (beta.5) WORLDS_TELEMETRY=0 or DO_NOT_TRACK=1 hard-disables; all controls and CI identity.

The beta.5's optional Freshservice ingress requires both settings. Each explicit flag takes precedence over its corresponding environment variable; an empty environment variable counts as absent, while an empty explicit flag is invalid. With neither setting, the ingress is disabled. Programmatic servers receive freshserviceIngress: { authority, publicUrl } explicitly and do not read these environment variables. These settings are not available in the older published beta.3 runtime.

Freshservice and Zendesk share /api/v2 paths, so the reserved raw Host selects Freshservice. A reverse proxy must validate its public authority, pin that upstream Host, reject alternate forwarding and keep the backend private. Forwarded host headers and world keys do not select the connector. Freshservice worlds advertise freshservice_base_url only when this ingress is enabled; clients must use that full URL with the world key as the Basic username and a dummy password. Host selection does not replace admin authentication. The Freshservice plan records the native read scope and remaining provider, SDK and proxy qualification.

Interruptions and child processes

On Linux/macOS, passk stops the agent's process group on timeout or interruption. A child that creates its own session or process group escapes that cleanup and must be stopped separately.

For passk, SIGINT, SIGTERM, SIGHUP and SIGQUIT trigger cleanup and exit 128 + signal. The first signal wins; later lifecycle signals do not interrupt cleanup. A ten-second hard deadline can leave a world behind if cleanup is stuck. Broken terminal output does not prevent cleanup.

Use a terminal multiplexer for work that must survive a terminal closing. nohup alone does not prevent the handled hangup. Windows cleanup remains best effort.

Network access and version pinning

The installed dashboard assets and keyless workflows work offline. Agent model calls, optional drafting/judging, and configured webhooks use their selected external services. Judging can send world customer records and agent replies to its provider; transcript judging sends the transcript. Live account imports and source-checkout drift probes contact the real connector.

A fixed npm version pins Worlds package bytes; dependency ranges can still resolve during installation. Versioned tarballs and checksum sidecars are also available. A tarball does not bundle dependencies: offline installation requires a prepared dependency cache or mirror. Never use bare npx worlds, which names a different package.

Generated CI uses the CLI's package/version in WORLDS_RUNTIME. The init command's --tarball <url> or --runtime <spec> option selects a different package source. The JavaScript client remains a versioned direct download; no npm registry installation for its unresolved scope is advertised.

Maintainer packaging and publication steps are in the release reference.