paracosm 0.8.488 → 0.8.492

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.
package/README.md CHANGED
@@ -27,13 +27,13 @@
27
27
 
28
28
  ## What paracosm is
29
29
 
30
- Paracosm starts from a prompt, brief, URL, or hand-written scenario draft; every path compiles down to an LLM-readable world contract before simulation. The durable contract is still JSON: a typed `ScenarioPackage` with five state bags, labels, departments, metrics, setup defaults, and generated hooks. A leader with a HEXACO personality profile runs that world. A deterministic kernel drives state, time, and randomness. An LLM generates events, specialist analyses, and the leader's decisions. Specialists can forge new computational tools at runtime inside a V8 sandbox; an LLM judge approves each forge before it enters the decision pipeline. The kernel applies consequences. Personality traits drift. One turn ends, the next begins.
30
+ Paracosm starts from a prompt, brief, URL, or hand-written scenario draft; every path compiles down to an LLM-readable world contract before simulation. The durable contract is still JSON: a typed `ScenarioPackage` with five state bags, labels, departments, metrics, setup defaults, and generated hooks. An actor with a HEXACO personality profile runs that world. A deterministic kernel drives state, time, and randomness. An LLM generates events, specialist analyses, and the actor's decisions. Specialists can forge new computational tools at runtime inside a V8 sandbox; an LLM judge approves each forge before it enters the decision pipeline. The kernel applies consequences. Personality traits drift. One turn ends, the next begins.
31
31
 
32
32
  **JSON is the contract, not the product boundary.** Today, `compileScenario()` accepts a scenario JSON draft and can ground it with `seedText` or `seedUrl`. The next API layer should be a one-call prompt/document wrapper that asks an LLM to propose that same JSON contract, validates it, then compiles and runs it. It should not bypass the schema, the kernel, or the artifact.
33
33
 
34
- **Same seed. Different leader. Different world.**
34
+ **Same seed. Different actor. Different world.**
35
35
 
36
- Two runs against an identical seed, starting from the same compiled world contract, produce measurably divergent trajectories when you swap one variable: the leader's personality. The kernel's side is reproducible. The divergence comes from the LLM stages reading HEXACO profiles and deciding differently. That structural contrast is the product.
36
+ Two runs against an identical seed, starting from the same compiled world contract, produce measurably divergent trajectories when you swap one variable: the actor's personality. The kernel's side is reproducible. The divergence comes from the LLM stages reading HEXACO profiles and deciding differently. That structural contrast is the product.
37
37
 
38
38
  Paracosm is a **structured world model** in the sense of [Xing 2025](https://arxiv.org/abs/2507.05169) and the [ACM CSUR 2025 world-model survey](https://dl.acm.org/doi/full/10.1145/3746449): a simulator for *actionable possibilities*, not a video generator. It is also a **counterfactual world simulation model** ([Kirfel et al, 2025](https://link.springer.com/article/10.1007/s43681-025-00718-4)): a substrate for replaying an event with one variable changed and surfacing the effect. The closest LLM-world-model implementation anchor is [Yang et al, 2026](https://openreview.net/forum?id=XmYCERErcD), which evaluates LLM-based world models through policy verification, action proposal, and policy planning. Paracosm takes the safe product version of that idea: externalize the world into schema, citations, tools, snapshots, and seeded transitions, then let the LLM reason over that structure. Full taxonomy mapping in [`docs/positioning/world-model-mapping.md`](docs/positioning/world-model-mapping.md).
39
39
 
@@ -42,14 +42,14 @@ Paracosm is a **structured world model** in the sense of [Xing 2025](https://arx
42
42
  - **Not a generative visual world model.** Sora, Genie 3, and World Labs Marble produce pixels or 3D scenes. Paracosm produces a structured `RunArtifact`: metrics, decisions, specialist notes, citations, forged tool summaries.
43
43
  - **Not a JEPA-style predictive-representation model.** LeCun's AMI Labs trains neural representations from sensor streams. Paracosm composes a kernel with an LLM reasoner; no training pipeline.
44
44
  - **Not a multi-agent task orchestration framework.** LangGraph, AutoGen, CrewAI, OpenAI Agents SDK, Google ADK all build agentic workflows that execute real tasks. Paracosm is a simulation; nothing leaves the run.
45
- - **Not a bottom-up swarm intelligence simulator.** MiroFish and OASIS simulate thousands to a million emergent agents for aggregate prediction. Paracosm is top-down (one leader decides), runs ~100 agents by design, and outputs a deterministic trajectory plus divergence across leaders.
45
+ - **Not a bottom-up swarm intelligence simulator.** MiroFish and OASIS simulate thousands to a million emergent agents for aggregate prediction. Paracosm is top-down (one actor decides), runs ~100 agents by design, and outputs a deterministic trajectory plus divergence across actors.
46
46
  - **Not a generative-agents library.** Stanford Generative Agents (Smallville) and Google DeepMind Concordia build emergent social simulacra in open-ended sandboxes. Paracosm ships a deterministic turn loop, personality drift, runtime tool forging, and a universal result schema.
47
47
 
48
- Leaders can be colony commanders, CEOs, generals, ship captains, department heads, AI systems, governing councils, or any entity that receives information, evaluates options, and makes choices that shape the world. The simulation does not care what they represent. It cares how they decide.
48
+ Actors can be colony commanders, CEOs, generals, ship captains, department heads, AI systems, governing councils, or any entity that receives information, evaluates options, and makes choices that shape the world. The simulation does not care what they represent. It cares how they decide.
49
49
 
50
50
  ### Counterfactual simulations with `WorldModel.fork()`
51
51
 
52
- The CWSM positioning is operationalized through `WorldModel.fork()`: run a simulation with snapshots enabled, then branch at any past turn with a different leader or seed, and compare. On resumed runs, `maxTurns` remains the absolute final turn index. To run three additional turns from turn 3, pass `maxTurns: 6`.
52
+ The CWSM positioning is operationalized through `WorldModel.fork()`: run a simulation with snapshots enabled, then branch at any past turn with a different actor or seed, and compare. On resumed runs, `maxTurns` remains the absolute final turn index. To run three additional turns from turn 3, pass `maxTurns: 6`.
53
53
 
54
54
  ```typescript
55
55
  import { WorldModel } from 'paracosm/world-model';
@@ -58,14 +58,14 @@ import worldJson from './my-world.json' with { type: 'json' };
58
58
  const wm = await WorldModel.fromJson(worldJson);
59
59
 
60
60
  // Run the trunk with per-turn snapshots captured.
61
- const trunk = await wm.simulate(visionaryLeader, {
61
+ const trunk = await wm.simulate(visionaryActor, {
62
62
  maxTurns: 6, seed: 42, captureSnapshots: true,
63
63
  });
64
64
 
65
- // Branch at turn 3 with a different leader. No re-compute of turns 1-3;
65
+ // Branch at turn 3 with a different actor. No re-compute of turns 1-3;
66
66
  // the forked kernel resumes from the captured state.
67
67
  const branch = await (await wm.forkFromArtifact(trunk, 3)).simulate(
68
- pragmatistLeader,
68
+ pragmatistActor,
69
69
  { maxTurns: 6, seed: 42 },
70
70
  );
71
71
 
@@ -76,7 +76,7 @@ console.log(trunk.fingerprint, branch.fingerprint); // divergent futures from th
76
76
 
77
77
  The kernel round-trips through `JSON.stringify`, so snapshots persist to disk cleanly for later replay or audit. `captureSnapshots` defaults to `false` to keep normal artifacts lean; set it when you want fork capability.
78
78
 
79
- The paracosm dashboard exposes the same mechanism end-to-end. Every UI-initiated run captures snapshots by default, so the Reports tab shows a `↳ Fork at {Time} N` button on each completed turn. Clicking it opens a fork modal (leader override, optional seed, optional custom events), POSTs to `/setup` with the full parent artifact, and routes the user to a new **Branches** tab where all forks launched from the current parent accumulate as cards with per-metric deltas rendered live as each branch streams to completion.
79
+ The paracosm dashboard exposes the same mechanism end-to-end. Every UI-initiated run captures snapshots by default, so the Reports tab shows a `↳ Fork at {Time} N` button on each completed turn. Clicking it opens a fork modal (actor override, optional seed, optional custom events), POSTs to `/setup` with the full parent artifact, and routes the user to a new **Branches** tab where all forks launched from the current parent accumulate as cards with per-metric deltas rendered live as each branch streams to completion.
80
80
 
81
81
  ### Replay any run for audit
82
82
 
@@ -94,14 +94,14 @@ The kernel's between-turn progression hook re-runs deterministically from each r
94
94
  import { DigitalTwin, type SubjectConfig, type InterventionConfig } from 'paracosm/digital-twin';
95
95
 
96
96
  const twin = await DigitalTwin.fromJson(scenarioJson);
97
- const artifact = await twin.simulateIntervention(subject, intervention, leader);
97
+ const artifact = await twin.simulateIntervention(subject, intervention, actor);
98
98
  ```
99
99
 
100
100
  `DigitalTwin` is an alias of `WorldModel`; the subpath names the use case in the import path. The new `simulateIntervention()` sugar populates `RunArtifact.subject` and `RunArtifact.intervention` for traceability.
101
101
 
102
102
  ### Quickstart: prompt or document to running simulation
103
103
 
104
- `WorldModel.fromPrompt` compiles a scenario from seed source material (paste, URL, or extracted PDF text), then `wm.quickstart` generates N contextual HEXACO leaders and runs them in parallel. Every prompt/document path validates against `DraftScenarioSchema` and routes into the existing `compileScenario` pipeline: the canonical `ScenarioPackage` contract is never bypassed.
104
+ `WorldModel.fromPrompt` compiles a scenario from seed source material (paste, URL, or extracted PDF text), then `wm.quickstart` generates N contextual HEXACO actors and runs them in parallel. Every prompt/document path validates against `DraftScenarioSchema` and routes into the existing `compileScenario` pipeline: the canonical `ScenarioPackage` contract is never bypassed.
105
105
 
106
106
  ```typescript
107
107
  import { WorldModel } from 'paracosm/world-model';
@@ -111,11 +111,11 @@ const wm = await WorldModel.fromPrompt({
111
111
  domainHint: 'corporate strategic decision',
112
112
  });
113
113
 
114
- const { leaders, artifacts } = await wm.quickstart({ leaderCount: 3 });
115
- artifacts.forEach((a, i) => console.log(leaders[i].name, a.fingerprint));
114
+ const { actors, artifacts } = await wm.quickstart({ actorCount: 3 });
115
+ artifacts.forEach((a, i) => console.log(actors[i].name, a.fingerprint));
116
116
  ```
117
117
 
118
- In the dashboard, the Quickstart tab is the default landing view. A user pastes a brief (or drops a PDF, or supplies a URL) and receives three streaming-live leaders plus per-card Download JSON, Copy shareable link, and Fork-in-Branches actions within a minute of first click. A curated library of 10 HEXACO archetypes is exported at `paracosm/leader-presets` for programmatic `runBatch` sweeps or Swap-leader controls in downstream UIs.
118
+ In the dashboard, the Quickstart tab is the default landing view. A user pastes a brief (or drops a PDF, or supplies a URL) and receives three streaming-live actors plus per-card Download JSON, Copy shareable link, and Fork-in-Branches actions within a minute of first click. A curated library of 10 HEXACO archetypes is exported at `paracosm/leader-presets` for programmatic `runBatch` sweeps or Swap-actor controls in downstream UIs.
119
119
 
120
120
  ## Install
121
121
 
@@ -140,7 +140,7 @@ If you omit `labels`, Paracosm falls back to `"colonists"` /
140
140
  feel sharper when you pick your own. "Colony" is the default because
141
141
  it's narratively richer than a neutral "group" / "unit" while still
142
142
  translating to Mars habitats, medieval holds, corporate teams, or any
143
- bounded collective under a leader's decisions.
143
+ bounded collective under an actor's decisions.
144
144
 
145
145
  ```json
146
146
  {
@@ -215,11 +215,11 @@ const scenario = await compileScenario(worldJson, {
215
215
  model: 'claude-sonnet-4-6',
216
216
  });
217
217
 
218
- // Define leaders with HEXACO personality profiles.
219
- // Leaders can be any top-down decision maker: commander, CEO, general,
218
+ // Define actors with HEXACO personality profiles.
219
+ // Actors can be any top-down decision maker: commander, CEO, general,
220
220
  // governing council, AI system, department head. The engine doesn't care
221
221
  // what they represent, only how their personality shapes decisions.
222
- const leaders = [
222
+ const actors = [
223
223
  {
224
224
  name: 'Captain Reyes',
225
225
  archetype: 'The Pragmatist',
@@ -242,8 +242,8 @@ const leaders = [
242
242
 
243
243
  // Run in parallel: same seed, same crises, different outcomes
244
244
  const results = await Promise.all(
245
- leaders.map(leader =>
246
- runSimulation(leader, [], {
245
+ actors.map(actor =>
246
+ runSimulation(actor, [], {
247
247
  scenario,
248
248
  maxTurns: 6,
249
249
  seed: 42,
@@ -256,7 +256,7 @@ const results = await Promise.all(
256
256
  // if (e.type === 'event_start') e.data.title // string
257
257
  // if (e.type === 'outcome') e.data.systemDeltas // Record<string,number>
258
258
  // if (e.type === 'forge_attempt') e.data.approved // boolean
259
- onEvent(e) { console.log(leader.name, e.type, e.data.summary); },
259
+ onEvent(e) { console.log(actor.name, e.type, e.data.summary); },
260
260
  })
261
261
  )
262
262
  );
@@ -275,7 +275,7 @@ for (const r of results) {
275
275
  }
276
276
  ```
277
277
 
278
- Each call to `runSimulation` takes one leader. Run one, two, or twenty. The dashboard runs two side-by-side for comparison, but the API has no limit. Leaders don't need to be people. They can model competing strategies, policy frameworks, organizational philosophies, or autonomous systems responding to the same events with different decision profiles.
278
+ Each call to `runSimulation` takes one actor. Run one, two, or twenty. The dashboard runs two side-by-side for comparison, but the API has no limit. Actors don't need to be people. They can model competing strategies, policy frameworks, organizational philosophies, or autonomous systems responding to the same events with different decision profiles.
279
279
 
280
280
  ### The universal result contract
281
281
 
@@ -285,7 +285,7 @@ Every simulation returns a `RunArtifact`: one universal Zod-validated shape expo
285
285
  import { RunArtifactSchema, type RunArtifact } from 'paracosm/schema';
286
286
  import { runSimulation } from 'paracosm/runtime';
287
287
 
288
- const artifact: RunArtifact = await runSimulation(leader, [], { scenario, maxTurns: 6 });
288
+ const artifact: RunArtifact = await runSimulation(actor, [], { scenario, maxTurns: 6 });
289
289
 
290
290
  // Optional runtime validation (dev mode, untrusted JSON, replays, etc.):
291
291
  const parsed = RunArtifactSchema.parse(artifact);
@@ -331,7 +331,7 @@ const intervention: InterventionConfig = InterventionConfigSchema.parse({
331
331
  adherenceProfile: { expected: 0.7 },
332
332
  });
333
333
 
334
- const artifact = await runSimulation(leader, [], { scenario, maxTurns: 6, subject, intervention });
334
+ const artifact = await runSimulation(actor, [], { scenario, maxTurns: 6, subject, intervention });
335
335
  // artifact.subject + artifact.intervention carry through to any consumer
336
336
  ```
337
337
 
@@ -356,39 +356,39 @@ After `npm install paracosm -g` you get one umbrella binary with subcommands. Ev
356
356
  paracosm --help # lists every subcommand
357
357
  paracosm --version # prints "paracosm 0.7.x"
358
358
 
359
- paracosm run # run a sim against leaders.json
360
- paracosm run --leader 1 --turns 5 # leader index 1, 5 turns
359
+ paracosm run # run a sim against actors.json
360
+ paracosm run --actor 1 --turns 5 # actor index 1, 5 turns
361
361
  paracosm run --name "Reyes" --openness 0.85 --conscientiousness 0.4 --turns 6
362
- paracosm run --leaders ./my-leaders.json --live # custom roster + live web search
362
+ paracosm run --actors ./my-actors.json --live # custom roster + live web search
363
363
 
364
364
  paracosm dashboard # SSE dashboard at http://localhost:3456
365
365
  paracosm dashboard 6 # auto-launch with 6 turns
366
366
 
367
367
  paracosm compile scenarios/lunar.json --seed-url <url> --max-searches 5
368
368
 
369
- paracosm init my-app --domain "Submarine crew of 8" --leaders 3
369
+ paracosm init my-app --domain "Submarine crew of 8" --actors 3
370
370
  ```
371
371
 
372
372
  A second back-compat binary `paracosm-dashboard` is shipped as an alias for `paracosm dashboard` so existing scripts and Docker invocations don't break.
373
373
 
374
- The CLI looks for `leaders.json` in this order:
374
+ The CLI looks for `actors.json` in this order:
375
375
 
376
- 1. `--leaders <path>` flag (explicit)
377
- 2. `./leaders.json` in your current directory
378
- 3. `./config/leaders.json` in your current directory
379
- 4. A bundled `config/leaders.example.json` (so commands work out of the box)
376
+ 1. `--actors <path>` flag (explicit)
377
+ 2. `./actors.json` in your current directory
378
+ 3. `./config/actors.json` in your current directory
379
+ 4. A bundled `config/actors.example.json` (so commands work out of the box)
380
380
 
381
381
  Copy the example to start customizing:
382
382
 
383
383
  ```bash
384
384
  # Option 1: in your project root
385
- cp node_modules/paracosm/config/leaders.example.json leaders.json
385
+ cp node_modules/paracosm/config/actors.example.json actors.json
386
386
 
387
387
  # Option 2: organized in a config/ folder
388
- mkdir -p config && cp node_modules/paracosm/config/leaders.example.json config/leaders.json
388
+ mkdir -p config && cp node_modules/paracosm/config/actors.example.json config/actors.json
389
389
  ```
390
390
 
391
- Then edit the HEXACO sliders and `instructions` fields to describe your own leaders. The simulation picks up the file on the next run.
391
+ Then edit the HEXACO sliders and `instructions` fields to describe your own actors. The simulation picks up the file on the next run.
392
392
 
393
393
  ## Scenario Compiler
394
394
 
@@ -435,13 +435,13 @@ Running a simulation calls real LLM APIs against your key. Paracosm assigns a di
435
435
  | **`quality`** (default) | `gpt-5.4` / `claude-sonnet-4-6` | `gpt-5.4-mini` / `claude-haiku-4-5-20251001` | `gpt-5.4-nano` / `claude-haiku-4-5-20251001` | **~$1-3** | **~$3-7** |
436
436
  | **`economy`** | `gpt-4o` / `claude-sonnet-4-6` | `gpt-5.4-nano` / `claude-haiku-4-5-20251001` | `gpt-5.4-nano` / `claude-haiku-4-5-20251001` | **~$0.20-0.60** | ~$3-5 |
437
437
 
438
- Numbers assume 6 turns, 5 departments, 100 agents, up to 3 events per turn. An 8-turn run on OpenAI `quality` tends to land at ~$1.50-2.00 per leader. The call budget is ~10/turn (1 director + ~5 dept + 1 commander + ~3 reaction batches + 0-2 forges + 0-1 judge), and departments on flagship carry most of the cost.
438
+ Numbers assume 6 turns, 5 departments, 100 agents, up to 3 events per turn. An 8-turn run on OpenAI `quality` tends to land at ~$1.50-2.00 per actor. The call budget is ~10/turn (1 director + ~5 dept + 1 commander + ~3 reaction batches + 0-2 forges + 0-1 judge), and departments on flagship carry most of the cost.
439
439
 
440
440
  Pick the preset explicitly for quick iteration:
441
441
 
442
442
  ```typescript
443
443
  const scenario = await compileScenario(worldJson);
444
- const output = await runSimulation(leader, [], {
444
+ const output = await runSimulation(actor, [], {
445
445
  scenario,
446
446
  maxTurns: 4, // fewer turns = linear cost reduction
447
447
  seed: 42,
@@ -472,7 +472,7 @@ curl -s -X POST http://localhost:3456/simulate \
472
472
  -H 'X-Anthropic-Key: sk-ant-...' \
473
473
  -d '{
474
474
  "scenario": { "id": "submarine-habitat", "labels": { "name": "Deep Ocean Habitat", "populationNoun": "crew", "settlementNoun": "habitat", "timeUnitNoun": "day" }, "setup": { "defaultTurns": 4, "defaultPopulation": 25, "defaultStartTime": 2040 }, "departments": [...], "metrics": [...] },
475
- "leader": { "name": "Captain Reyes", "archetype": "The Pragmatist", "unit": "Deep Ocean Habitat", "hexaco": { "openness": 0.4, "conscientiousness": 0.9, "extraversion": 0.3, "agreeableness": 0.6, "emotionality": 0.5, "honestyHumility": 0.8 }, "instructions": "" },
475
+ "actor": { "name": "Captain Reyes", "archetype": "The Pragmatist", "unit": "Deep Ocean Habitat", "hexaco": { "openness": 0.4, "conscientiousness": 0.9, "extraversion": 0.3, "agreeableness": 0.6, "emotionality": 0.5, "honestyHumility": 0.8 }, "instructions": "" },
476
476
  "options": { "maxTurns": 4, "seed": 42, "captureSnapshots": true, "provider": "anthropic" }
477
477
  }' | jq '.artifact.fingerprint'
478
478
  ```
@@ -507,16 +507,16 @@ const client = createParacosmClient({
507
507
  });
508
508
 
509
509
  const scenario = await client.compileScenario(worldJson);
510
- const out = await client.runSimulation(leader, [], { maxTurns: 6, seed: 42 });
510
+ const out = await client.runSimulation(actor, [], { maxTurns: 6, seed: 42 });
511
511
 
512
512
  // Promote one specific run to quality without touching the client:
513
- const gold = await client.runSimulation(leader, [], {
513
+ const gold = await client.runSimulation(actor, [], {
514
514
  maxTurns: 8, seed: 42, costPreset: 'quality',
515
515
  });
516
516
 
517
517
  // Batch 20 ablations with shared config:
518
518
  const manifest = await client.runBatch({
519
- scenarios: [scenarioA, scenarioB], leaders, turns: 6, seed: 42, maxConcurrency: 4,
519
+ scenarios: [scenarioA, scenarioB], actors, turns: 6, seed: 42, maxConcurrency: 4,
520
520
  });
521
521
  ```
522
522
 
@@ -551,7 +551,7 @@ const client = createParacosmClient(); // no args, pulls from env
551
551
 
552
552
  Direct `runSimulation(...)` / `runBatch(...)` / `compileScenario(...)` calls without a client are still fully supported. The client is purely additive for multi-run workflows.
553
553
 
554
- ### Batch runner: N scenarios × M leaders
554
+ ### Batch runner: N scenarios × M actors
555
555
 
556
556
  ```typescript
557
557
  import { runBatch } from 'paracosm/runtime';
@@ -559,14 +559,14 @@ import { marsScenario, lunarScenario } from 'paracosm';
559
559
 
560
560
  const manifest = await runBatch({
561
561
  scenarios: [marsScenario, lunarScenario],
562
- leaders, // LeaderConfig[], same shape as runSimulation
562
+ actors, // ActorConfig[], same shape as runSimulation
563
563
  turns: 6,
564
564
  seed: 950,
565
565
  maxConcurrency: 2, // how many sims to run in parallel
566
566
  provider: 'anthropic',
567
567
  });
568
568
 
569
- // manifest.results[i] carries { scenarioId, leader, fingerprint, output, duration }
569
+ // manifest.results[i] carries { scenarioId, actor, fingerprint, output, duration }
570
570
  // manifest.timestamp + manifest.config is a reproducible audit trail
571
571
  ```
572
572
 
@@ -592,7 +592,7 @@ The server wires this to a cancel-on-disconnect watchdog; any programmatic consu
592
592
  const ctrl = new AbortController();
593
593
  setTimeout(() => ctrl.abort(), 60_000); // kill after 60s wall time
594
594
 
595
- const output = await runSimulation(leader, [], {
595
+ const output = await runSimulation(actor, [], {
596
596
  scenario, maxTurns: 8, seed: 42,
597
597
  signal: ctrl.signal,
598
598
  });
@@ -605,7 +605,7 @@ if (output.aborted) console.log('partial result; turns completed:', output.turnA
605
605
  When you want a scripted event at a fixed turn (smoke tests, pedagogical demos, reproducing a scenario from a paper), supply `customEvents`:
606
606
 
607
607
  ```typescript
608
- await runSimulation(leader, [], {
608
+ await runSimulation(actor, [], {
609
609
  scenario, maxTurns: 8, seed: 42,
610
610
  customEvents: [
611
611
  { turn: 3, title: 'Dust storm', description: 'A 72-hour planetary dust storm cuts solar output by 80%.' },
@@ -620,7 +620,7 @@ await runSimulation(leader, [], {
620
620
  import { runSimulation, ProviderKeyMissingError } from 'paracosm';
621
621
 
622
622
  try {
623
- const output = await runSimulation(leader, [], { scenario, maxTurns: 8, seed: 42 });
623
+ const output = await runSimulation(actor, [], { scenario, maxTurns: 8, seed: 42 });
624
624
  if (output.providerError) {
625
625
  // Terminal provider failure (invalid key, quota exhausted). The run
626
626
  // aborted mid-way. turnArtifacts / finalState are partial.
@@ -652,6 +652,23 @@ bun src/index.ts
652
652
  PARACOSM_OUTPUT_DIR=./artifacts/run-001 bun src/index.ts
653
653
  ```
654
654
 
655
+ ## Storage backend
656
+
657
+ Paracosm persists run history (the Library tab) and replayable session blobs (the Load menu) through [`@framers/sql-storage-adapter`](https://github.com/framersai/sql-storage-adapter), the open-source SQL abstraction maintained by Frame.dev. The same code paths run unchanged against SQLite (default), Postgres, sql.js, and IndexedDB; switching backends is one env var.
658
+
659
+ ```bash
660
+ # Default: better-sqlite3 against ./data/runs.db + ./data/sessions.db
661
+ paracosm dashboard
662
+
663
+ # Postgres in production (Library + sessions persist to your existing cluster)
664
+ STORAGE_ADAPTER=postgres DATABASE_URL=postgres://user:pass@host/db paracosm dashboard
665
+
666
+ # Pure-WASM SQLite fallback when the native module isn't available
667
+ STORAGE_ADAPTER=sqljs paracosm dashboard
668
+ ```
669
+
670
+ Run-history schema (`runs` table) and session schema (`sessions` table) are bootstrapped idempotently on first boot. Legacy v0.7 databases auto-migrate the `leader_*` columns to `actor_*` in place via `ALTER TABLE RENAME COLUMN`; no manual step needed.
671
+
655
672
  ## Seed Enrichment & Citation Flow
656
673
 
657
674
  Pass real-world source material into the compiler and Paracosm grounds the scenario in citations that flow all the way through to department reports.
@@ -681,17 +698,17 @@ The Event Director also receives the bundle's `topics` and `categories`, so its
681
698
 
682
699
  ## Pluggable Trait Models
683
700
 
684
- Leaders aren't just human personalities. paracosm ships a `TraitModel` registry with two built-ins, and registering more is one call:
701
+ Actors aren't just human personalities. paracosm ships a `TraitModel` registry with two built-ins, and registering more is one call:
685
702
 
686
703
  | Model | Axes | Use for |
687
704
  |-------|------|---------|
688
- | `hexaco` | openness, conscientiousness, extraversion, agreeableness, emotionality, honesty-humility | Human leaders: CEOs, captains, governors, councils, military commanders |
689
- | `ai-agent` | exploration, verification-rigor, deference, risk-tolerance, transparency, instruction-following | AI-system leaders: frontier-lab release directors, autonomous coordinators, alignment-eval substrates |
705
+ | `hexaco` | openness, conscientiousness, extraversion, agreeableness, emotionality, honesty-humility | Human actors: CEOs, captains, governors, councils, military commanders |
706
+ | `ai-agent` | exploration, verification-rigor, deference, risk-tolerance, transparency, instruction-following | AI-system actors: frontier-lab release directors, autonomous coordinators, alignment-eval substrates |
690
707
 
691
708
  ```typescript
692
709
  import { runSimulation, hexacoModel, aiAgentModel, traitModelRegistry } from 'paracosm';
693
710
 
694
- // Human leader (legacy hexaco field, still works)
711
+ // Human actor (legacy hexaco field, still works)
695
712
  const captain = {
696
713
  name: 'Captain Reyes', archetype: 'Pragmatist', unit: 'Station Alpha',
697
714
  hexaco: { openness: 0.4, conscientiousness: 0.9, extraversion: 0.3,
@@ -699,7 +716,7 @@ const captain = {
699
716
  instructions: 'lead by protocol',
700
717
  };
701
718
 
702
- // AI-system leader (new traitProfile slot)
719
+ // AI-system actor (new traitProfile slot)
703
720
  const releaseDirector = {
704
721
  name: 'Atlas-Bot Release Director',
705
722
  archetype: 'Aggressive AI Release Optimizer',
@@ -724,12 +741,12 @@ const releaseDirector = {
724
741
  };
725
742
 
726
743
  // Both run through the same runSimulation; the orchestrator's
727
- // normalizeLeaderConfig resolves either shape.
744
+ // normalizeActorConfig resolves either shape.
728
745
  await runSimulation(captain, [], { scenario, maxTurns: 6, seed: 42 });
729
746
  await runSimulation(releaseDirector, [], { scenario, maxTurns: 6, seed: 42 });
730
747
  ```
731
748
 
732
- Run [`scripts/cookbook-ai-agent.ts`](scripts/cookbook-ai-agent.ts) to capture an end-to-end ai-agent run with full input + output JSON. The captured fingerprint shifts from `riskBehavior:steady` (HEXACO Dr. Sora Wen leader) to `riskBehavior:bold` (ai-agent Atlas-Bot leader) on identical scenario + seed; decision rationale clearly tracks the ai-agent profile.
749
+ Run [`scripts/cookbook-ai-agent.ts`](scripts/cookbook-ai-agent.ts) to capture an end-to-end ai-agent run with full input + output JSON. The captured fingerprint shifts from `riskBehavior:steady` (HEXACO Dr. Sora Wen actor) to `riskBehavior:bold` (ai-agent Atlas-Bot actor) on identical scenario + seed; decision rationale clearly tracks the ai-agent profile.
733
750
 
734
751
  Full surface: [`docs/cookbook.md#pluggable-trait-models-ai-agent-end-to-end`](docs/cookbook.md). Spec: [`docs/superpowers/specs/2026-04-26-trait-model-generalization-design.md`](docs/superpowers/specs/2026-04-26-trait-model-generalization-design.md).
735
752
 
@@ -808,7 +825,7 @@ If you omit `timeUnitNoun`, paracosm falls back to `tick` / `ticks`. The built-i
808
825
 
809
826
  ### Turn 0: Promotions
810
827
 
811
- The commander evaluates the full agent roster and promotes department heads. Each department (Medical, Engineering, Agriculture, etc.) gets a leader chosen by the commander based on personality fit, specialization, and experience. A high-openness commander picks unconventional candidates. A high-conscientiousness commander picks by-the-book specialists.
828
+ The commander evaluates the full agent roster and promotes department heads. Each department (Medical, Engineering, Agriculture, etc.) gets a head chosen by the commander based on personality fit, specialization, and experience. A high-openness commander picks unconventional candidates. A high-conscientiousness commander picks by-the-book specialists.
812
829
 
813
830
  This matters because promoted agents become the department analysis LLM agents for the rest of the simulation. Their personality colors every analysis they produce, which shapes the information the commander sees, which shapes decisions. The commander never directly analyzes events. They only read department reports and decide.
814
831
 
@@ -846,7 +863,7 @@ Each turn represents a configurable time period. Mars and Lunar tick in years (M
846
863
  consolidate into long-term beliefs. Stances drift.
847
864
  Relationships shift based on shared experiences.
848
865
 
849
- 9. PERSONALITY DRIFT HEXACO traits shift through leader pull, role activation,
866
+ 9. PERSONALITY DRIFT HEXACO traits shift through actor pull, role activation,
850
867
  and outcome reinforcement. All six traits drift
851
868
  (openness, conscientiousness, extraversion,
852
869
  agreeableness, emotionality, honesty-humility)
@@ -931,14 +948,14 @@ Paracosm uses [AgentOS](https://agentos.sh) for agent orchestration, LLM calls,
931
948
 
932
949
  ## What You Can Simulate
933
950
 
934
- Leaders are abstract decision-making entities. The same engine handles any domain where top-down decisions shape outcomes over time:
951
+ Actors are abstract decision-making entities. The same engine handles any domain where top-down decisions shape outcomes over time:
935
952
 
936
- | Domain | Leaders | Departments | Events |
953
+ | Domain | Actors | Departments | Events |
937
954
  |--------|---------|-------------|--------|
938
955
  | **Space colonies** | Colony commanders | Medical, Engineering, Agriculture | Dust storms, water crises, first native-born generation |
939
956
  | **Corporate strategy** | CEOs, board members | Finance, Operations, R&D, Legal | Market shifts, acquisitions, regulatory changes |
940
957
  | **Military wargaming** | Theater commanders | Intelligence, Logistics, Air, Ground | Escalation, supply disruption, allied coordination |
941
- | **Game worlds** | Faction leaders, AI governors | Economy, Military, Diplomacy, Culture | Invasions, trade disputes, technological breakthroughs |
958
+ | **Game worlds** | Faction actors, AI governors | Economy, Military, Diplomacy, Culture | Invasions, trade disputes, technological breakthroughs |
942
959
  | **Policy simulation** | Government agencies, councils | Healthcare, Education, Infrastructure | Pandemics, budget crises, demographic shifts |
943
960
  | **Autonomous systems** | AI decision frameworks | Sensor, Planning, Execution | Sensor failure, objective conflict, resource contention |
944
961
 
@@ -948,14 +965,14 @@ Define departments, metrics, events, and progression hooks in JSON. The engine g
948
965
 
949
966
  | | Open Source (Apache-2.0) | Hosted Dashboard (Planned) |
950
967
  |-|--------------------------|---------------------------|
951
- | **Leaders** | Unlimited via API. Dashboard shows 2 side-by-side. | N leaders in parallel with fleet management UI. |
968
+ | **Actors** | Unlimited via API. Dashboard shows 2 side-by-side. | N actors in parallel with fleet management UI. |
952
969
  | **Simulations** | Sequential or self-managed parallelism. | Distributed parallelization across worker nodes. |
953
970
  | **Scenarios** | JSON + Compiler, unlimited. | Visual scenario editor, team sharing, version control. |
954
971
  | **Agent Chat** | Available after first turn completes. | Persistent agents with durable memory across sessions. |
955
972
  | **Cost** | Free forever. You provide LLM API keys. | Tiered pricing for teams, orgs, and government agencies. |
956
973
  | **Support** | Community (Discord, GitHub). | SLA, dedicated support, private deployment. |
957
974
 
958
- The open-source engine and library are the permanent foundation. The API (`runSimulation`, `runBatch`, `compileScenario`) supports unlimited leaders and simulations today. The dashboard demo at [paracosm.agentos.sh](https://paracosm.agentos.sh) runs two leaders side-by-side to demonstrate divergence.
975
+ The open-source engine and library are the permanent foundation. The API (`runSimulation`, `runBatch`, `compileScenario`) supports unlimited actors and simulations today. The dashboard demo at [paracosm.agentos.sh](https://paracosm.agentos.sh) runs two actors side-by-side to demonstrate divergence.
959
976
 
960
977
  The planned hosted product targets organizations that need to run dozens or hundreds of simulations in parallel: defense agencies stress-testing doctrine, corporations modeling leadership scenarios, game studios generating divergent NPC civilizations at scale. Distributed parallelization, fleet orchestration, team workspaces, persistent storage, and enterprise auth are on the roadmap.
961
978
 
@@ -967,11 +984,11 @@ Contact [team@frame.dev](mailto:team@frame.dev) for early access or partnership.
967
984
 
968
985
  | Feature | Description |
969
986
  |---------|-------------|
970
- | **Fleet Orchestration** | Run 10, 50, or 100+ leaders through the same scenario in parallel. Distributed worker nodes. Aggregate comparison dashboards. |
971
- | **Alternate Timelines** | Fork a simulation mid-run to explore "what if" branches. Split at any turn, change leader or settings, compare divergent futures from a single decision point. |
987
+ | **Fleet Orchestration** | Run 10, 50, or 100+ actors through the same scenario in parallel. Distributed worker nodes. Aggregate comparison dashboards. |
988
+ | **Alternate Timelines** | Fork a simulation mid-run to explore "what if" branches. Split at any turn, change actor or settings, compare divergent futures from a single decision point. |
972
989
  | **Custom Scenario Forms** | Visual form-based scenario editor instead of raw JSON. Drag-and-drop departments, metric configuration, event category builder. |
973
990
  | **Persistent Agents** | Agent chat that persists across sessions with durable memory. Resume conversations days later with full recall. |
974
- | **Multi-Scenario Comparison** | Run the same leaders across different scenarios and compare how personality adapts to different domains. |
991
+ | **Multi-Scenario Comparison** | Run the same actors across different scenarios and compare how personality adapts to different domains. |
975
992
  | **Private Deployment** | Self-hosted or cloud-managed deployment for organizations that need data sovereignty, audit trails, and compliance controls. |
976
993
 
977
994
  ## License
package/dist/cli/init.js CHANGED
@@ -26,7 +26,7 @@ const USAGE = `paracosm init [dir] --domain <text|url> [--mode <m>] [--actors <n
26
26
  dir output directory (default: ./paracosm-app)
27
27
  --domain required: seed text describing the scenario, OR a URL
28
28
  --mode turn-loop | batch-trajectory | batch-point (default: turn-loop)
29
- --actors number of HEXACO leaders, 2-6 (default: 3)
29
+ --actors number of HEXACO actors, 2-6 (default: 3)
30
30
  --name project name, default: derived from --domain
31
31
  --force overwrite non-empty target dir
32
32
 
package/dist/cli/run.js CHANGED
File without changes
package/dist/cli/serve.js CHANGED
File without changes
@@ -1,6 +1,39 @@
1
+ /**
2
+ * SQL-backed implementation of {@link RunHistoryStore}, built on
3
+ * `@framers/sql-storage-adapter` so the same code works on SQLite,
4
+ * Postgres, sql.js, and IndexedDB without touching call sites. The
5
+ * default adapter is better-sqlite3 (or sql.js fallback when the
6
+ * native module isn't installable). Set `STORAGE_ADAPTER=postgres`
7
+ * with `DATABASE_URL` to switch backends; the resolver inside
8
+ * sql-storage-adapter handles the rest.
9
+ *
10
+ * Single `runs` table with composite per-filter indexes. Run records
11
+ * are tiny (~200 bytes); 100K rows fits in 20 MB. No retention cap;
12
+ * add `PARACOSM_RUN_HISTORY_MAX_ROWS` env var if traffic ever warrants it.
13
+ *
14
+ * @module paracosm/cli/server/sqlite-run-history-store
15
+ */
16
+ import { type DatabaseOptions } from '@framers/sql-storage-adapter';
1
17
  import type { RunHistoryStore } from './run-history-store.js';
2
18
  export interface SqliteRunHistoryStoreOptions {
19
+ /**
20
+ * SQLite database path. Used when the resolver picks better-sqlite3
21
+ * or sql.js. Ignored when STORAGE_ADAPTER selects a remote backend
22
+ * such as Postgres (DATABASE_URL takes precedence there).
23
+ */
3
24
  dbPath: string;
25
+ /**
26
+ * Optional override forwarded to `createDatabase`. Tests use this to
27
+ * pin `type: 'memory'` for hermetic isolation; production code
28
+ * leaves it undefined and lets the env-driven resolver pick.
29
+ */
30
+ databaseOptions?: DatabaseOptions;
4
31
  }
32
+ /**
33
+ * Build an SQL-backed run history store. Returns a sync handle whose
34
+ * methods are async; the underlying adapter is opened lazily on first
35
+ * call so this factory plugs into the existing sync `createMarsServer`
36
+ * boot path without forcing every caller to become async.
37
+ */
5
38
  export declare function createSqliteRunHistoryStore(options: SqliteRunHistoryStoreOptions): RunHistoryStore;
6
39
  //# sourceMappingURL=sqlite-run-history-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite-run-history-store.d.ts","sourceRoot":"","sources":["../../../src/cli/server/sqlite-run-history-store.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAmB,eAAe,EAAiB,MAAM,wBAAwB,CAAC;AAE9F,MAAM,WAAW,4BAA4B;IAC3C,MAAM,EAAE,MAAM,CAAC;CAChB;AAkGD,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,4BAA4B,GAAG,eAAe,CAkLlG"}
1
+ {"version":3,"file":"sqlite-run-history-store.d.ts","sourceRoot":"","sources":["../../../src/cli/server/sqlite-run-history-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAuC,KAAK,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAIzG,OAAO,KAAK,EAAmB,eAAe,EAAiB,MAAM,wBAAwB,CAAC;AAE9F,MAAM,WAAW,4BAA4B;IAC3C;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAuPD;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,4BAA4B,GAAG,eAAe,CAqGlG"}