Skip to main content
Simulator programs are ordinary .mjs modules loaded by the in-cluster controller. The repository-local submitters accept one module path and run it through the same Temporal, Kubernetes, Kueue, Agent Sandbox, controller, and Run.execute path.

Package entry points

The experiment module owns its agents, customer events, customer Effect, and completion policy. The selected profile owns every platform object.

Write a controller-loadable module

Export exactly one named runSpec:
The absolute cluster-services import is available inside the repository-built controller image. It constructs the selected profile’s private Layer from the validated controller environment. Experiment code does not receive raw Kubernetes, Kueue, Sandbox, or Temporal objects. The controller requires the exact value returned by RunSpec.define. It loads the mounted module once and invokes Run.execute(runSpec) once; there is no fallback execution entry point or automatic replay. Every roster runtime must provide a distributed application-container realization. Its bridge resolves only after the application is usable and returns that runtime’s exact .gateway plus .termination observation. The customer Effect starts after all roster entries pass the same readiness gate.

Run on the local Kubernetes profile

Build the shared controller/support image:
The command prints an immutable pinnedImage. Use it to create the pinned kind profile:
The cluster setup prints its exact kube context, tool paths, queue names, Temporal address, and artifact roots. It refuses to replace an existing cluster. Submit the module through the local profile:
MOLTZAP_SUPPORT_IMAGE defaults to MOLTZAP_CONTROLLER_IMAGE for this local path. Both values must be digest-pinned. The checked-in packages/simulator/local/README.md records the component versions and smoke modules.

Run on the GKE profile

Provision the checked-in Terraform profile, install its pinned add-ons, push the controller/support image, and acquire the explicit kube context as described in packages/simulator/gke/README.md. Then submit the same module:
The GKE submitter validates the checked-in profile, uses only the explicit context and bucket, and calls the same Temporal submission code as the local profile. The repository does not select production Temporal hosting or high availability. Static GKE validation does not contact Google Cloud or a cluster:
Passing that check is not a live qualification claim. The GKE acceptance gate still requires a caller-authorized project, the small smoke, an OpenClaw evaluation, readable retained artifacts, and zero run-owned residue.

Express completion policy in execute

The customer Effect returns, fails, or is interrupted according to its own logic. Use Effect’s Clock, Schedule, race, timeout, Deferred, Stream, and Scope primitives for deadlines, quiescence, supervised work, and explicit stop conditions. A runtime exit after readiness is committed as typed ledger evidence. It does not implicitly end the customer Effect. One program may fail fast on that evidence while another continues observing the remaining society. The run returns a ProgramFinished or ClusterLost outcome after ledger allocation succeeds. ProgramFinished.exit preserves customer success, typed failure, defect, or interruption. Infrastructure acquisition, append, controller, teardown, or completion failures stay distinct from behavioral results. The submitters print one final JSON result containing the run namespace and bounded controller result. Applications decide how to map that result into their own exit codes, retries, operator messages, and report states.

Sweeps remain application orchestration

A single simulator invocation is one definition-bound society and one ledger. Schedules, matrices, retries, sharding, naming, resumption, and aggregation stay in the calling application. For example, packages/evals submits every case-condition cell as its own RunSpec through the selected local or GKE profile, then persists the terminal attempt in its report database. This keeps suite orchestration failures separate from the evidence produced by an individual society.

Inspect completed artifacts

After a run publishes a completed receipt, both profiles retain exported files under the same relative path:
Local files are written directly below the artifact root selected during cluster setup. GKE runs build the active ledger on controller-local POSIX storage, then export the three completed artifacts to the Terraform-owned Cloud Storage bucket with completion.json last. The active GKE ledger is not a recovery guarantee for controller or node loss before that export finishes. Retrieve the three retained files, then validate them with the same complete event catalog:
Opening validates the definition identity, exact catalog, schemas, digests, run identity, count, event identities, and logical sequence before exposing reusable typed streams. It does not start a society.