Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 35 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,47 @@
# MERT Engine

Cross-platform disability-inclusive medical simulation runtime for web, iOS and Android.
Cross-platform disability-inclusive medical simulation runtime for web, iOS and Android, with a Babylon.js/WebXR persistent open world.

## Architecture status

### Step 1Typed protocol + patient/world state
- Shared TypeScript contracts for physiology, AAC, authority, access, systems, uncertainty and evidence.
- Typed `SimulationEvent` transport.

### Step 2 — Simulation kernel + safety invariants
- Central `SimulationKernel` owns world state, event audit and simulation time.
- AAC composition can pause simulation time.
- Protected invariants prevent communication failure from being converted into loss of self-authority.

### Step 3 — React/React Native as view-controller
- UI sends semantic scenario events and renders snapshots.
- UI does not own clinical/world truth.

### Step 4 — Scenario Engine
- `DeclarativeScenarioEngine` owns branch progression, delayed consequences and node state.

### Step 5 — Declarative Scenario Rules
- Case logic is represented as data: trigger → conditions → delay → effects → transition.
- Rules can request domain-model dynamics instead of directly hard-coding every consequence.

### Step 6World-State / VNN Dynamics Modules
- `VNNDynamicsCoordinator` routes `dynamics.requested` events to registered modules.
- Included example modules:
- `respiratory-dynamics`
- `access-dynamics`
- Dynamics return proposals with confidence, rationale and provenance before world-state events are committed through the kernel.

## Core invariant
### Steps 1-6Simulation kernel
- Typed physiology, AAC, authority, access, systems, uncertainty and evidence state.
- Central `SimulationKernel` with audit history and simulation-clock control.
- React/React Native is view-controller only; it does not own clinical/world truth.
- Declarative scenario rules: trigger -> conditions -> delay -> effects -> transition.
- VNN dynamics modules return proposals with confidence, rationale and provenance before commit.

### Steps 7-20 — Persistent disability world
- Persistent people, places, infrastructure, relationships and schedules.
- Affordance-based autonomy and environmental attribution of access barriers.
- Social agents with bounded knowledge and direct-first communication safeguards.
- Semantic interaction parity across WebXR controller, gaze, touch, keyboard and switch-style input.
- Counterfactual timeline and world -> clinical bridge.

### Steps 21-24 — Accessible routes, objects and continuity
- Accessibility-weighted route planning across paths, ramps, crossings, lifts and transport.
- Stateful doors, lift motion, AAC charging and explicit transport boarding.
- Proximity + relationship social encounters where support is requested rather than assumed.
- World -> ambulance -> ED -> ICU -> MERT -> discharge -> community continuity.

### Steps 25-28Procedural city runtime
- Deterministic procedural city with residential, community, health, education, employment and transport districts.
- Generated triangulated navmesh geometry with A* pathfinding and person-specific access constraints.
- Persistent homes with power/charging state plus an accessible city transport service with explicit capacity allocation and boarding.
- Autonomous emergency-service dispatch linked only to an active evidence-gated ambulance continuity stage.
- Babylon/WebXR rendering for city buildings, roads, navmesh overlay, accessible transport and emergency vehicles.

## Core invariants

```text
communication failure != incapacity
disability != acute deterioration
model proposal != clinical truth
equipment availability != indication
friend/support worker != substitute authority
route failure != person failure
transport allocation != consent to board
emergency dispatch != treatment inference
```

## Running
Expand All @@ -59,15 +63,8 @@ The resulting `dist/` directory is configured for Vercel through `vercel.json`.

## Testing

The UI tests use React Native Testing Library v14 interaction patterns and query the interface by accessible roles and labels rather than implementation details.

The runtime tests cover:
- AAC restoration without authority transfer
- simulation-clock pause during AAC composition
- delayed declarative deterioration
- VNN dynamics invocation
- protected authority invariants
The UI tests use React Native Testing Library interaction patterns and query the interface through accessible roles and names. Runtime tests cover authority preservation, AAC access, simulation timing, declarative deterioration, VNN invocation, persistent world state, route barriers, object state, social support non-assumption, clinical continuity, procedural-city determinism, navmesh generation, transport allocation and emergency dispatch gating.

## Scope

MERT Engine is educational simulation software. Scenario physiology and dynamics are authored educational models, not real-patient prediction, diagnosis, treatment guidance or device-control logic.
MERT Engine is educational simulation software. Scenario physiology, accessibility thresholds, route weights, vehicle speeds and emergency-response timings are authored simulation parameters, not real-patient prediction, diagnosis, treatment guidance, device-control logic or statutory accessibility standards.
59 changes: 59 additions & 0 deletions __tests__/worldSteps25to28.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { initialOpenWorldState, PersistentWorldStore, type PersonEntity } from '../src/world/worldModel';
import { applyProceduralCity, generateProceduralCity } from '../src/world/proceduralCity';
import { buildCityNavMesh, findNavMeshPath } from '../src/world/navmeshGeometry';
import { HomeTransportEngine } from '../src/world/homeTransport';
import { ContinuityEngine } from '../src/world/continuity';
import { EmergencyResponseEngine } from '../src/world/emergencyServices';

describe('Steps 25-28 procedural disability city', () => {
test('procedural city is deterministic and preserves person authority', () => {
const first = generateProceduralCity(42);
const second = generateProceduralCity(42);
expect(first.buildings.map(item => item.id)).toEqual(second.buildings.map(item => item.id));
const store = new PersistentWorldStore(initialOpenWorldState);
applyProceduralCity(store, first);
const maya = store.entity('maya') as PersonEntity;
expect(maya.authority).toBe('self');
expect(store.entity('home-maya')?.kind).toBe('place');
expect(store.entity('hospital-main')?.kind).toBe('place');
});

test('generates a triangulated navmesh and an accessible path', () => {
const plan = generateProceduralCity(42);
const store = new PersistentWorldStore(initialOpenWorldState);
applyProceduralCity(store, plan);
const mesh = buildCityNavMesh(plan, 10);
const maya = store.entity('maya') as PersonEntity;
const path = findNavMeshPath(mesh, store.snapshot(), maya, maya.position, [0,0,90]);
expect(mesh.triangles.length).toBeGreaterThan(100);
expect(path?.triangleIds.length).toBeGreaterThan(1);
expect(path?.cost).toBeGreaterThan(0);
});

test('homes and transport allocate accessible capacity without assuming support', () => {
const plan = generateProceduralCity(42);
const store = new PersistentWorldStore(initialOpenWorldState);
applyProceduralCity(store, plan);
const services = new HomeTransportEngine(store, plan);
expect(services.homeForPerson('maya')?.id).toBe('home-maya');
const trip = services.requestTrip('maya', 'community-hub', 'hospital-main');
expect(trip?.status).toBe('allocated');
expect(trip?.supportRequested).toBe(false);
expect(store.entity('maya')?.kind === 'person' && (store.entity('maya') as PersonEntity).authority).toBe('self');
});

test('autonomous emergency response starts only from an active ambulance continuity stage', () => {
const plan = generateProceduralCity(42);
const store = new PersistentWorldStore(initialOpenWorldState);
applyProceduralCity(store, plan);
const continuity = new ContinuityEngine(store);
const ems = new EmergencyResponseEngine(store, plan, continuity);
expect(ems.dispatchFromContinuity('maya', 'no episode')).toBe(false);
const maya = store.entity('maya') as PersonEntity;
continuity.start(maya, 'educational deterioration');
expect(ems.dispatchFromContinuity('maya', 'evidence-gated educational deterioration')).toBe(true);
ems.step(1);
expect(ems.snapshot().activeResponses[0]?.status).toMatch(/en-route|on-scene/);
expect((store.entity('maya') as PersonEntity).authority).toBe('self');
});
});
Loading
Loading