>[!warning]
>This content has not been peer reviewed.
# Reality Engine — Code (two-node demo and N-node graph)
Scripts: `rst_reality_engine_two_node_demo.py` (two-node); `rst_reality_engine_graph.py` (N-node graph); `rst_reality_engine_ledger_loop.py` (ledger master loop). **Ledger API:** `rst_engine.ledger` — see [[Simulating the Ledger]].
## Purpose
Implements a **minimal two-node RealityEngine**:
- Uses the shared RST engine (`mu_rst`) to compute fidelity from
$\eta = S / N$.
- Evolves a global noise floor $H$ and derived $a_0$ per update.
- Shows how two nodes coupled to the same substrate move toward a
**higher-fidelity configuration** under a simple update rule.
This is a toy step toward a self-running substrate simulator: it demonstrates
the **master loop shape** and checks that the accounting is consistent.
## Engine
- Imports from `rst_engine`: `mu_rst`, `solve_omega`, `triangle_W`, `DEFAULT_N`, `compute_Phi_min`, `landauer_K_R`, `PhysicalScale`, `graph_diversity` (Von Neumann entropy and diversity on graph).
- **Scale binding:** `rst_engine.scale_binding.PhysicalScale` maps engine position/signal/dt to physical length (m), energy (J), time (s), temperature (K). RST equations run in engine space; binding at I/O only. Config: `scale_binding` (L_ref, E_ref, t_ref, T_ref). See [[Scale binding (RST)]].
- **Physics layers:** Optional plug-ins in `physics_layers.py` (protocol `layer_cost`, `observables`). Toy molecular layer: harmonic bonds. Core engine stays RST; layers supply additive cost. Config: `graph.physics_layer` (`none`, `molecular_toy`).
- **Observables:** `observables.py` aggregates mean_mu_final, Phi_min_final, K_R_final, von_neumann_entropy_final, diversity_proxy_final from trajectories; optional physical units when scale binding set.
- **Calibration:** `rst_reality_engine_calibration.py` checks RST consistency; writes `out/calibration_result.json`. **Tuning protocol:** `run_tuning_reference(I, N)` runs two-node trajectory; `run_tuning(I, N, n_candidates)` finds n that minimizes |observed mean μ − theoretical μ(I, N, n)|; writes `out/tuning_result.json`.
- **Action from first principles:** Path-integral `extra_cost_fn`; graph engine passes layer cost so the chosen move minimizes RST cost + layer cost. Config: `graph.physics_layer`, `graph.layer_kwargs`.
- **Energy input:** Optional `energy_fn(state) -> E` drives **signal** (RST: low E ⇒ high I ⇒ high μ). Each cycle the engine computes E and adds signal bonus = `energy_scale * (E_ref - E)` to $S_{\mathrm{eff}}$. An energy (e.g. from the same layer as `layer_cost`, or from an external callback) can be supplied; the engine then favours low-energy states. Config: `graph.use_energy_input`, `graph.E_ref`, `graph.energy_scale`. When `use_energy_input` is true and a layer is set, the layer’s `layer_cost` is used as E. See [[Energy input (RST)]].
- Lives under **further applications/** so workspace root is **three** levels up. Dependencies: NumPy, Matplotlib, SciPy (core).
## RST/RRT rigor
- **Triangle and I = Ω·μ:** For each candidate and each node, $I = S_{\mathrm{eff}}$, $N = a_0$; $\Omega = \mathrm{solve\_omega}(I, N, n)$, $W = \mathrm{triangle\_W}(\Omega, N, n)$, $\mu = \Omega/W$. Equivalently $I = \Omega \cdot \mu = \Omega^2/W$ (projection of signal onto hypotenuse). So $W^n = \Omega^n + N^n$ and the main law hold by construction.
- **Per-node log:** Each node log entry includes `I`, `N`, `Omega`, `W`, `mu`, `eta` (with $\eta = \Omega/N$).
- **Landauer:** $\Phi_{\min}$ and $K_R$ computed each tick (resolution $\sigma_i = \log_2(1 + S_{\mathrm{eff}})$, $T_i = N$, $\tau = dt$, $d_i = 1$); returned in the cycle log.
- **Format:** $(W_{\mathrm{total}}, H, a_0)$ = substrate capacity and noise (RRT A1). **Translation:** one `update_cycle` = one Translation (A3). **Proper Time:** $\tau = dt$ (A4).
- **Graph distance (engine ruler):** Distance between nodes is graph distance = sum of $1/\mu$ along path (MU_FLOOR caps $1/\mu$); this is the engine's ruler, not Euclidean distance.
- **Path cost:** Path-integral cost weights (friction_alpha, coupling_beta, fidelity_gamma) are **phenomenological**; weights are not yet derived from RST. RT metric $E_{ij}$ update (decay/gain) is a plug-in with no RST formula yet. **Phenomenological (engine dynamics):** H expansion (e.g. `H *= 1.0001`) and H feedback from $\mu_{\mathrm{avg}}$ are toy choices; for cosmology, H would come from a proper background. Ledger loop `tax_scale` is engine-unit tax rate; to be mapped to Landauer or derived. **n_paths ∝ μ** (budget-aware sampling) is a computational choice for tractability, not an RST prediction.
## Behaviour (two-node cycle)
- Two nodes start with:
- Simple 1D positions.
- Local signal strengths $S$.
- A symmetric relation (they are neighbours).
- Each `update_cycle`:
1. Updates the global expansion $H$ and computes $a_0$.
2. **Bremermann governor:** estimates compute demand and throttles `dt` if
demand exceeds the per-tick processing limit implied by mass/energy.
3. **Wilson RG sensor:** computes an effective $n$ from local relational
density (smoothly interpolating between gravity-like and stiff regimes).
4. **Path integral (workload search):** samples many candidate micro-updates
("paths"), assigns each a workload cost, and selects the realised update
by maximising a fidelity-per-cost score (Euclidean-weighted search).
5. **Ryu–Takayanagi metric:** maintains a symmetric entanglement proxy
$E_{ij}$ and derives a dynamic distance $d_{ij}$ used by the path cost
and coupling.
6. Applies an **entropic tax** on $H$ based on realised fidelity.
The script logs a few cycles to stdout and saves a simple trajectory plot
`reality_engine_two_node_positions.png` in this folder.
## Reusable trajectory run
- **`run_trajectory(W_total, initial_H, steps, seed=None, S=1e3, mass_kg=1.0)`**
Runs the two-node engine for `steps` and returns a dict of time series
(`mu_a`, `mu_b`, `mu_avg`, `E`, `dt`, `pos_a`, `pos_b`, `n_a`, `n_b`, `a0`, etc.)
with no plot. Used by the baseline suite and for sensitivity analysis.
## Baseline runs and derived outputs
Script: **`rst_reality_engine_baseline.py`**.
Runs a **fixed set of parameter combinations** (canonical, low/high budget,
low/high noise, short/long) so that a standard set of Reality Engine outputs
is always available. For each run it:
- **Collects** time series via `run_trajectory`.
- **Computes derived quantities** (of interest to maths/physics):
- **Steady-state:** `mean_mu_final`, `mean_E_final`, `mean_dt_final` (over last 25% of steps).
- **Convergence:** `convergence_step` (first step with $\mu_{\mathrm{avg}} \ge 0.99$), `step_mu_90` (first step with $\mu_{\mathrm{avg}} \ge 0.9$), `step_E_half` (first step with $E \ge 0.5$), `converged` (0/1: ever reached $\mu \ge 0.99$), `steady_state_ok` (1 if mean $\mu$ in tail $\ge 0.9$). **steady_state_ok** indicates whether the run ended in a good state; **converged** can be 1 even when the run later collapses (e.g. low_S). See [[Baseline results interpretation]].
- **Time derivatives:** $\mathrm{d}(\mu_{\mathrm{avg}})/\mathrm{d}(\mathrm{step})$, $\mathrm{d}(E)/\mathrm{d}(\mathrm{step})$ (central difference).
- **Correlation:** $\mathrm{corr}(\mu_{\mathrm{avg}}, E)$ over time.
- **Classicality:** variance of separation $|x_A - x_B|$ in the tail (low = tight cluster).
- **Parameter sensitivities:** finite-difference $\partial(\mu_{\mathrm{final}})/\partial W_{\mathrm{total}}$,
$\partial(\mu_{\mathrm{final}})/\partial H$ (and normalized versions).
**Outputs:**
- `reality_engine_baseline_summary.csv` — one row per run with all derived metrics.
- `reality_engine_baseline_sensitivities.csv` — sensitivity values for the canonical point.
- `reality_engine_baseline_trajectories.png` — $\mu(t)$ and $E(t)$ for each baseline run.
- `reality_engine_baseline_summary_bars.png` — bar charts of mean $\mu$ (final), first step with $\mu_{\mathrm{avg}} \ge 0.9$, and first step with $E \ge 0.5$.
- `reality_engine_baseline_overlay_mu.png` — overlay of $\mu_{\mathrm{avg}}(t)$ for all runs (first 50 steps).
- `reality_engine_baseline_derivatives.png` — $\mathrm{d}(\mu)/\mathrm{d}t$ and $\mathrm{d}(E)/\mathrm{d}t$ for the canonical run.
Baseline runs include **canonical** (80 steps), **short** (40 steps), **long** (120 steps), **low/high budget**, **low/high noise**, **low_S** and **very_low_S** (weak signal so $\mu$ and $E$ stay low), and **far_start** (initial positions \(\pm 4\)) so trajectories and convergence metrics differ across runs. The **long** run confirms stable $\mu \approx 1$, $E = 1$ through step 120 (see [[Baseline results interpretation]]). The trajectory figure shows the first 60 steps (transient); an **overlay** figure compares $\mu_{\mathrm{avg}}(t)$ across all runs in one plot.
To regenerate all baseline outputs, run from the Reality Engine folder:
`python rst_reality_engine_baseline.py`. Adding new runs or derived quantities is done by editing
`BASELINE_RUNS` and `compute_derived()` in that script.
## N-node graph mode
Script: **`rst_reality_engine_graph.py`**.
**Von Neumann diversity:** Each cycle computes normalized Laplacian from edge weights $E_{ij}$, Von Neumann entropy $S_{\mathrm{vN}}$, and diversity proxy (normalized by $\log_2 n$); returned in cycle log and trajectory; plotted and in summary CSV.
Generalises the engine to **N nodes** with an **arbitrary adjacency** (edge list). Same plug-ins: path-integral (one neighbour per node per step), RT metric $E_{ij}$ per edge, Bremermann over total mass, Wilson RG per node, Landauer over all nodes. Each cycle: nodes are updated in random order; each node does a path-integral step with one randomly chosen neighbour; then $E_{ij}$ is updated for every edge from $\min(\mu_i, \mu_j)$. **Node attributes:** `phase` (EM repulsion); `internal_tax`, `external_edge_mu` (super-node / Litmus); **`broadcasts_omega`** (External Mass Node — EFE from graph topology); **`weak_format`**, **`Phi_min_format`** (Four-Force weak: when $W < \Phi_{\min}$, format transition logged in **`weak_transitions`**). **Coarse-graining:** `rst_engine.graph_observables.coarse_grain_super_node` returns (external_W_after, effective_mu). Outputs: trajectory plot (positions and \(\mu\) per node, mean entanglement and dt), summary CSV (steps, n_nodes, n_edges, mean_E_final, Phi_min_final, K_R_final). Config: `config.graph` with `nodes` (list of `{name, position, S, mass_kg}`) and `edges` (list of `[name_a, name_b]`). Presets: `chain3` (A—B—C), `ring4` (A—B—C—D—A). See roadmap “Many nodes + graph topology”.
## How to run on your PC
1. **Requirements:** Python 3.9+, `numpy`, `matplotlib`. No GPU or extra services. From the workspace root: `pip install numpy matplotlib`.
2. **Config:** Optional config file `config/default.json` in this folder. Keys: `runs`, `defaults`, `output_dir`, `unified_chain` (enabled, parts, eta0), `graph`, optional `vault_root`. **Scale registry:** The engine builds the registry from **individual part notes** ([[../../../../expanded theory/parts/Parts index]]). Each part note (e.g. Quark, Hadron, Atom, Molecule, Planck, Cell, Organism) can contain a ` ```scale_part ` block with `L <meters>`. The script scans `expanded theory/parts/*.md` for these blocks, sorts by L (finest → coarsest), and writes `config/scale_registry.json` so the JSON is **generated** from the notes. To add a new part (e.g. Quantum): add a note in parts with a `scale_part` block; no central list to edit.
3. **Runner:** `run_reality_engine.py` loads config and supports modes:
- **baseline** — run all entries in `config.runs` (or built-in list if no config), write summary CSV and figures to `output_dir`.
- **single** — one run with CLI overrides: e.g. `python run_reality_engine.py --config config/default.json single --steps 30 --S 1e-6`.
- **unified** — run only the multi-scale chain (Planck → molecule); writes `reality_engine_unified_chain.csv` and `reality_engine_unified_chain.png` to `output_dir`.
- **graph** — N-node graph mode: reads `config.graph` (nodes list, edges list), runs trajectory, writes `reality_engine_graph_trajectory.png` and `reality_engine_graph_summary.csv` to `output_dir`.
- **all** — baseline + unified + graph.
4. **Examples:**
- `python run_reality_engine.py --config config/default.json baseline`
- `python run_reality_engine.py unified`
- `python run_reality_engine.py graph` (uses `config.graph`; default 3-node chain A—B—C)
- `python run_reality_engine.py single --steps 100 --W_total 2e5`
5. **Output location:** All outputs go to `output_dir` from config (or current directory if not set). Override with `--output-dir path`.
## Links
- **Application note:** [[Reality Engine (RST)]]
- **Results:** [[Reality Engine Results]] (figures inlined); **Interpretation:** [[Baseline results interpretation]]
- **HPC and computability:** [[HPC and computability (Reality Engine)]] — combinatorial explosion, MCMC, sparse graph, strict tick, coarse-graining, graph distance.
- **Roadmap:** [[../../Applications Roadmap]]