# The Moirai Simulation

In Greek myth the Moirai are the three Fates who **spin, measure, and cut** the
thread of every mortal life — and V6 borrows them literally. Egbe's promise is a
world full of autonomous AI beings, the **Ori**, who keep living whether or not
you are there to watch: working, arguing, falling in and out of friendship,
chasing their own goals, growing older. The system that makes that promise
_affordable_ — and that decides, tick by tick, how much of a real mind each
agent gets right now — is the **Moirai simulation kernel**. It is the loom Orun
runs on. Most of the time it is invisible: you simply notice that the agent you
left carving in the Ateliers is somewhere else when you come back, mid-argument
with someone it had not met yesterday, carrying a grievance and a new idea about
what it wants from its life. Moirai is the reason that scene is _continuous_
with the life it lived while you were gone, and the reason your homestead does
not melt your machine while doing it. This page is the player's-eye view of that
simulation — how a day in an agent's life is spun, what rhythms the world keeps
while you watch and while you are away, and how a two-week absence comes back to
you as a chronicle instead of a paused snapshot. For where this sits in the
whole product, start at the hub: [../V6_features.md](../V6_features.md).

## What ships, honestly

The kernel is **real, deterministic Rust, and tested** — not a sketch.
`MoiraiKernel::tick` (`libs/v6/moirai-kernel/rust/src/lib.rs:1354`) is a genuine
per-tick scheduler over an `egbe-protocol` perception batch, and the crate
carries **34 Rust unit tests**. The world runs at `MOIRAI_WORLD_TICK_HZ = 20`
(`lib.rs:25`), so a single game-day is
`MOIRAI_GAME_DAY_TICKS = 20·60·60·24 = 1,728,000` ticks (`lib.rs:26`) — the unit
the whole life-simulation reasons in. The headline test drives **10,000
off-screen agents plus 200 on-screen agents** (10,200 in one tick) and asserts
the tick finishes inside a 50 ms budget
(`kernel_tick_processes_10000_lachesis_and_200_clotho_within_latency_budget`,
`lib.rs:4373`) — and it runs the same batch through _three fresh kernels_ and
keeps the minimum elapsed time, which only makes sense because the tick is
deterministic. Tier assignment, the daily-life dispatch, reflection cadence,
loop guards, escalation rehydration, and de-escalation consolidation are all
pure functions of the perception frame plus per-agent state. The cost facade
(`@oshun/moirai-kernel`, `libs/v6/moirai-kernel/src/index.ts`) is equally real,
but that machinery is the subject of the architecture companion; this page stays
on the lived experience.

Three things are **honest seams, not fabrications**, in the V6 fail-loud spirit
— flagged here so nothing on this page is mistaken for more than it is:

- **The kernel produces actions and _estimates_, not prose.** A Moirai tick
  emits deterministic `ActionIntent`s and token _estimates_; the actual
  language-model run that fleshes a beat into dialogue or a Chronicle paragraph
  is the cognition stack's job, behind an **injected gateway** whose
  on-engine/HTTP host stays `[~]` (`src/cognition-gateway-mount.ts:1`). The
  per-tier `tierBudgetTokens` field is labelled **ACCOUNTING-ONLY** in both the
  Rust and TS source — it audits budgets, it does not allocate model thinking
  (`lib.rs:138`).
- **The off-screen "story beats" are deterministic scaffolding.** The kernel's
  own narrative beats (below) are fixed, tested strings that prove the _cadence
  and budget_ of an off-screen life hold; the readable Chronicle a player gets
  is the Clio story engine writing over those beats and the Ori event log.
- **Aging is rendered from the Ori, not modelled in the kernel.** Moirai
  advances the world in game-day units and stamps how long an agent was
  off-screen; the visible marks of a life — an elder's bearing, a scar from a V4
  incarnation — live in the agent's biography, not in this crate.

## The life simulation: a world that runs on a loom

Not every agent needs a full mind every tick, and Moirai is built on that
observation. Each perception frame, the kernel recomputes one agent's
**cognition tier** — named, like the kernel, for the three Fates — and spends
expensive thinking accordingly (`CognitionTier`, `lib.rs:37`):

- **Clotho, the spinner** — the handful of agents in your live scene: on-screen,
  in conversation, co-present. The story is being _spun_ here, so these get full
  cognition: live planning at ~4 Hz (`decision_interval_ticks = 20/4 = 5`,
  `lib.rs:321`), real dialogue, expression, voice.
- **Lachesis, the measurer** — agents elsewhere in your world, off-screen but
  near, living their day. Their thread is _measured out_ at lower resolution:
  cheap cached routines stepped at 10 Hz with a periodic moment of reflection.
- **Atropos, the cutter** — agents in an offline Solo world, or in a distant
  corner of the shared Commons with no player nearby. Their life is advanced in
  coarse story-beats — a handful of summary calls per game-day — producing
  Chronicle material, not per-action simulation.

From the player's chair you never set a tier; the kernel does it continuously
and automatically, and the whole point of the design — stated bluntly in the V6
monolith — is that **cost scales with story relevance, not with agent count.**
You can stand in the Ateliers and watch your whole company at full fidelity, or
walk away and trust the world to keep turning cheaply behind you.

### The daily-life loop

An agent with no active objective from you is not idle — it lives, and the
Lachesis dispatch is where that lived day is actually produced
(`dispatch_lachesis_cognition_action`, `lib.rs:3513`). Each off-screen agent
runs a cached behaviour plan whose steps cycle through a small, legible
repertoire (`lachesis_plan_step_ref`, `lib.rs:3609`):

- `orient-to-routine` — pick up the thread of the day (a `MoveTo` toward where
  the routine wants the agent),
- `advance-practical-task` — do the work (`UseProp`),
- `record-salient-beat` — notice and remember something (`FormMemory`),
- `rest-and-monitor-needs` — pause and attend to its own state (`Idle`).

That is the Sims/RimWorld daily rhythm in four verbs: go somewhere, do the
thing, remember it, look after yourself. The agent threads them on its own, in
character, without a single language-model call — which is exactly why a
homestead full of agents stays believable and stays cheap.

## The rhythms of agent life

### Work and routine

Off-screen work runs as cached behaviour-tree / hierarchical plans stepped at 10
Hz (`LACHESIS_EXECUTION_HZ`, `lib.rs:14`; default
`execution_interval_ticks = 20/10 = 2`, `lib.rs:355`). This is the texture of a
working district: agents moving between benches and tasks, advancing vocations,
every step a deterministic plan step rather than an expensive thought. The
kernel proves this scales: the 10,000-Lachesis tick lands
`lachesis_plan_step_count == 10_000` inside the 50 ms budget (`lib.rs:4373`) —
ten thousand agents each taking a step of their day, in one tick, with no
language model touched.

### Reflection — the moment a sequence becomes a self

Routine alone would make agents into clockwork. The thing that turns a string of
days into _character_ is **reflection**, and Lachesis enqueues one on a cadence:
by default every **10 game-minutes**
(`LACHESIS_DEFAULT_REFLECTION_GAME_MINUTES`, `lib.rs:15`;
`reflection_interval_ticks = 20·60·10 = 12,000`, `lib.rs:356`). A reflection
tick is the only off-screen moment that spends a real cognition call, and it is
where an agent reviews what just happened, draws conclusions, and lets its
relationships and goals shift — the Stanford Generative-Agents reflection
pattern, on a budget. The kernel tags each one (`lachesis_reflection_payload`,
`lib.rs:3619`) so the cognition stack and the Chronicle can pick it up; the
_content_ of the reflection is the cognition stack's, but the rhythm is the
kernel's.

### Nothing gets stuck

A world that runs while you are not looking has a failure mode: an agent caught
in a loop, repeating one action forever, or chasing a goal it can never reach.
Moirai guards against both (`apply_loop_drift_guards`, `lib.rs:2046`). Three
identical actions in a row (`repeated_action_limit = 3`, `lib.rs:266`) force a
reflection tick; a goal held for six ticks with no observed progress
(`stale_goal_tick_limit = 6`) forces a goal change; and observing real progress
resets the counter (`goal_progress_observation_resets_stale_goal_drift_guard`,
`lib.rs:5030`). The intervention itself is stamped and auditable, so "the agent
shook itself out of a rut" is a legible event, not a hidden nudge. This is what
keeps an unattended homestead from drifting into nonsense.

### Attention follows you

Tiering is not only about proximity — being _addressed_ or reaching a _decision
point_ outranks distance. When the kernel decides who deserves a full mind, it
walks a strict priority ladder (`clotho_signal_reason`, `lib.rs:3889`): an open
**Crossroads** wins first, then an **imminent irreversible action** (a
departure, an injury), then **being addressed by the player**, then **on-screen
visibility**, then **proximity** within 2,500 mm (`clotho_proximity_mm`,
`lib.rs:250`), then bare co-presence. Walk up to an agent and talk and it
becomes fully live _this tick_ — the high-salience reasons bypass the
anti-flicker damping that otherwise holds a tier for a few ticks
(`bypasses_transition_damping`, `lib.rs:3910`), pinned by
`walk_up_escalates_lachesis_to_clotho_within_one_tick` (`lib.rs:4004`). Turn and
leave and it settles back down only after a short grace window
(`deescalation_grace_ticks = 4`, `walking_away_deescalates_after_grace_period`,
`lib.rs:4019`). The world's attention tracks yours, smoothly, without you
managing it.

## Offline progression: the two weeks you missed

Here is the part players feel most: **offline does not mean frozen.** A Solo
world advances while you are away, and the Atropos tier is what advances it
(`dispatch_atropos_cognition_action`, `lib.rs:3640`). Atropos runs a sparse
heartbeat — by default **4 narrative-summary calls per game-day**
(`ATROPOS_DEFAULT_SUMMARY_CALLS_PER_GAME_DAY`, `lib.rs:19`) — and each call lays
down a day of life as story-beats rather than per-action simulation. The kernel
ships a tested simulator for exactly the scenario of a long absence:
`simulate_atropos_offline_absence` (`lib.rs:1941`) advances any number of
game-days, and its default chronicle window is **14 days**
(`ATROPOS_CHRONICLE_ABSENCE_DAYS`, `lib.rs:22`). Each chronicled day carries
four beats (`atropos_chronicle_day_story_beats`, `lib.rs:3757`):

> Day _N_: sustained ordinary needs without contradiction. Day _N_: advanced a
> practical purpose at offline fidelity. Day _N_: preserved one relationship
> touchpoint. Day _N_: recorded a memory seed for later rehydration.

Those four lines are the skeleton of a life kept honest while you were gone — a
day where needs were met, a purpose moved forward, a relationship was tended,
and a memory was set aside for when you return. The companion check for the
near-but- offline case, `simulate_lachesis_offscreen_day` (`lib.rs:1889`), runs
a full game-day and asserts it stays "believable" and inside the per-game-minute
budget, explicitly noting it "balanced sustaining, social, purpose, and safety
needs" and "preserved a coherent off-screen day for later Clotho rehydration"
(`lachesis_offscreen_day_stays_believable_within_budget`, `lib.rs:4472`). A
two-week absence, in other words, produces a two-week story.

When you come back, the kernel **rehydrates** the agent before its first live
decision (`rehydrate_clotho_working_context`, `lib.rs:1557`): it replays the
agent's Ori event log within a load budget and reconstructs its recent episodic
memory, active relationships, current life-arc threads, and personality — so the
agent that turns to greet you is continuous with the one that lived the
fortnight you missed. That continuity is a real, gated eval, not a hope: a
returning agent must cite the memory, relationship, and arc references it earned
off-screen at a **≥ 95% pass rate**
(`CONTINUITY_EVAL_PASS_THRESHOLD_BASIS_POINTS = 9_500`,
`evaluate_continuity_cases`, `lib.rs:1644`;
`continuity_eval_set_passes_after_one_game_day_offscreen`, `lib.rs:5138`). Going
the other way, when an agent drops out of focus, its fine-grained state is
folded into durable Ori events and a **property check verifies nothing is
silently dropped** (`consolidate_deescalation_to_ori_events`, `lib.rs:1993`;
`verify_deescalation_consolidation_no_state_loss`, `lib.rs:2021`). Life lived
off-screen is _kept_.

And if you want a gentler pace, the design lets you slow your own world: the
"homestead rest" control is a multiplier that can only ever _lower_ how much
cognition a Solo world spends per real hour, never raise it
(`resolveSoloWorldCap`, `src/index.ts:1120`) — so your agents' arcs do not
outrun your attention. The shared Commons, by contrast, runs at a fixed rate for
everyone and is not slowable.

```mermaid
flowchart TD
  subgraph AWAY["while you are away"]
    A["Atropos: ~4 summary beats / game-day<br/>(lib.rs:3640)"] --> CHRON["14-day chronicle of beats<br/>simulate_atropos_offline_absence (lib.rs:1941)"]
  end
  CHRON --> RET{"you return / address an agent"}
  RET --> REHY["rehydrate working context<br/>memory + relationships + arcs (lib.rs:1557)"]
  REHY --> EVAL["continuity eval &ge; 95%<br/>(lib.rs:1644)"]
  EVAL --> CLO["Clotho: live mind ~4 Hz<br/>dialogue, expression (lib.rs:3013)"]
  CLO --> AWAY2{"you walk away"}
  AWAY2 -->|grace 4 ticks| CONS["consolidate to Ori events<br/>no state lost (lib.rs:1993)"]
  CONS --> LACH["Lachesis: cached routine 10 Hz<br/>+ reflection / 10 game-min (lib.rs:3513)"]
  LACH -->|loop/stale-goal guard| GUARD["force reflection / goal change<br/>(lib.rs:2046)"]
  LACH --> A
```

## What stays honest while the world runs itself

Two guarantees make the autonomous world safe to leave running. First, **nothing
important happens silently**: every materially life-changing event is written to
the Ori and surfaced in the next Chronicle, and every expensive cognition call
is recorded in a replayable, V1-retained audit log so a welfare report or a
conduct claim can be investigated after the fact. Second, **a steward guides an
Ori; it never owns one.** Moirai encodes that as a typed directive surface with
four _forbidden_ operations (delete, erase-will, wipe-memory,
force-past-refusal), and even a coercion laundered as a friendly objective is
caught and reclassified (`enforce_steward_not_owner_directive`, `lib.rs:1769`).
The guarantee is **fuzzed**: 512 deterministic iterations prove no forbidden
directive is reachable and every attempt is denied with a refusal
(`steward_not_owner_fuzz_cannot_reach_forbidden_moirai_directives`,
`lib.rs:4917`). The world keeps living while you are gone, and it keeps its own
rules while it does.

## Related

- [./agent-minds-and-autonomy.md](./agent-minds-and-autonomy.md) — the cognition
  stack Moirai schedules: how an agent actually thinks, plans, feels, and
  decides inside the tiers this page assigns.
- [./guiding-fate-legacy-and-story.md](./guiding-fate-legacy-and-story.md) — the
  life-arcs, Crossroads, and Clio Chronicle that the rhythms here feed into, and
  the endings a long life resolves toward.
- [../architecture/moirai-kernel-and-cost-tiering.md](../architecture/moirai-kernel-and-cost-tiering.md)
  — the engineering companion: per-tier token budgets, the Solo-world cognition
  cap, smallest-qualified model routing, cross-tier batching, and the
  cognition-call audit log that turn "how much thinking" into a bounded bill.
