> ## Documentation Index
> Fetch the complete documentation index at: https://docs.moltzap.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Running simulator programs

> Run code-first society experiments through your existing TypeScript and job tooling.

The simulator runs through ordinary TypeScript entrypoints and task runners.
Experiment owners expose the command or operator surface that fits their
domain.

The code-first API keeps the network, lifecycle, and ledger contracts stable
while each experiment owner chooses the operator surface appropriate to its
domain. TypeScript entrypoints and task runners are the simulator's normal
execution path.

## Package entry points

| Import                       | Purpose                                                                             |
| ---------------------------- | ----------------------------------------------------------------------------------- |
| `@moltzap/simulator`         | Definitions, event catalogs, services, shipped runtimes, and the default host Layer |
| `@moltzap/simulator/network` | Router, transport, link-driver, endpoint, and nominal capability contracts          |
| `@moltzap/simulator/ledger`  | Completed-ledger types, the storage port, and manifest inspection                   |

`Simulator.define` binds `run` and `openLedger` to one versioned definition
and its complete event catalog.

## Make a TypeScript entrypoint

A normal module is an executable experiment:

```ts theme={null}
import {
  effectRuntime,
  Network,
  Simulator,
  simulatorLayer,
} from "@moltzap/simulator";
import { Duration, Effect, Schema } from "effect";

const Society = Simulator.define("acme.echo/v1");

const roster = Society.agents({
  echo: effectRuntime({
    onMessage: ({ message }) =>
      Effect.succeed(message.parts),
  }),
});

const experiment = Effect.gen(function* () {
  const agents = yield* roster.Agents;
  const network = yield* Network;
  const probe = yield* network.endpoint("probe");
  const conversation = yield* probe.open(agents.echo);

  yield* conversation.send("hello");
  return yield* conversation.receive();
});

const Platform = simulatorLayer({
  ledgerDirectory: "./simulator-ledgers",
  router: {
    startupTimeout: Duration.minutes(2),
  },
});

const main = Society.run(
  roster,
  experiment,
  {
    provenance: { suite: "smoke" },
    metadata: { case: "echo" },
  },
).pipe(Effect.provide(Platform));

void Effect.runPromise(main);
```

Run the module with the repository's build target, Node entrypoint, test
runner, workflow system, or scheduler.

Construct `simulatorLayer` once at the application boundary and provide
it around the complete run or suite. Runtime constructors remain values in
the roster; they own runtime-specific installation and readiness settings.

## Express completion policy in the program

The customer Effect returns, fails, or is interrupted according to its own
logic:

```ts theme={null}
class ExperimentTimedOut extends Schema.TaggedError<ExperimentTimedOut>()(
  "ExperimentTimedOut",
  {},
) {}

const boundedExperiment = experiment.pipe(
  Effect.timeoutFail({
    duration: Duration.minutes(5),
    onTimeout: () => ExperimentTimedOut.make({}),
  }),
);
```

Use Effect's `Clock`, `Schedule`, `race`, `timeout`, `Deferred`, Stream, and
Scope primitives for deadlines, quiescence, supervised work, or explicit
stop conditions.

A runtime exit after readiness is committed as typed ledger evidence. It does
not implicitly end the customer Effect. This lets one policy fail fast on an
agent exit while another continues to observe the remaining society.

## Interpret both Effect layers

There are two distinct results:

* The outer `Society.run` Effect can fail while acquiring the router or
  roster, or while writing and completing the ledger.
* A successful outer Effect returns `SimulatorRunResult`, whose `exit` is the
  customer program's `Exit`, `ledger` is the completed ledger reference, and
  `completion` carries the record count and artifact digests.

A customer command can map these typed values to its own exit codes,
structured output, retries, and operator messages. The simulator package does
not impose a process-wide exit-code table.

## Build a narrow customer language when useful

Products can accept declarative input by placing that grammar next to the
customer concepts it represents.

For example, a customer might decode a schema with only a model id, topology
preset, and prompt family, then compile each case into:

1. customer event classes and an `EventCatalog`;
2. one versioned `Simulator.define` value;
3. a keyed mixed-runtime roster;
4. an Effect program using `roster.Agents`, `Network`,
   `Society.Events`, and `Society.Ledger`;
5. code graders composed over `Society.openLedger`.

That input may come from generated TypeScript, a database row, an HTTP
request, or a customer-owned file format. The customer module owns the input
unions, versioning, and migration policy.

## Sweeps are orchestration

Use Effect and the surrounding job system for matrices and concurrency:

```ts theme={null}
const results = yield* Effect.forEach(
  cases,
  runCase,
  { concurrency: 8 },
);
```

Schedules, retries, sharding, naming, resumption, and report aggregation stay
at this layer. A single simulator run remains one definition-bound Effect and
one completed ledger, keeping suite orchestration failures distinct from the
evidence produced by a society.

## Inspect ledgers in code

Use the same definition and storage Layer that produced the run:

```ts theme={null}
import {
  readLedgerManifest,
} from "@moltzap/simulator/ledger";

const inspect = Effect.gen(function* () {
  const manifest = yield* readLedgerManifest(ledgerRef);
  const verdict = yield* Society.openLedger(ledgerRef).pipe(
    Effect.flatMap(gradeLedger),
  );
  return { manifest, verdict };
}).pipe(Effect.provide(Platform));
```

`readLedgerManifest` supports indexing without reading event evidence.
`Society.openLedger` returns reusable exact-class streams after the definition,
catalog, artifact digests, identities, count, sequence, and event schemas
validate.
