// Moved from docs/src/internal/MAMA_FORTH_SUPERVISOR_ARCHITECTURE.adoc to docs/working/scratch/src/internal/MAMA_FORTH_SUPERVISOR_ARCHITECTURE.adoc on 2026-06-16 (docs reorg Phase 2) = Mama Forth: Multi-VM Supervisor Architecture :toc: left :toclevels: 2 xref:../README.adoc[← Back to Documentation Index] == Executive Summary **Mama Forth** is the governing FORTH VM that orchestrates a multi-VM ecosystem. Unlike traditional supervisors, Mama Forth is itself a FORTH VM—a first-class citizen with full physics instrumentation. The architecture is: ``` ┌─────────────────┐ │ Mama Forth │ │ (Supervisor) │ │ + Physics │ └────────┬────────┘ │ ┌────────┴────────┐ │ │ ┌─────▼────┐ ┌─────▼────┐ │ Child VM1 │ │ Child VM2 │ │+ Physics │ │+ Physics │ └─────┬────┘ └─────┬────┘ │ │ ┌────────┴─────┐ ┌────────┴─────┐ │ │ │ │ ┌────▼──┐ ┌────▼──┐ ┌────▼──┐ │Block │ │Block │ ... │Block │ │Device1│ │Device2│ │DeviceN│ │Physics│ │Physics│ │Physics│ └────────┘ └────────┘ └────────┘ ``` **Key insight**: Physics metadata is now a three-tier hierarchy: 1. **Word-level**: Per-word metrics (entropy, temperature, latency) 2. **VM-level**: Per-VM aggregate metrics (child health, resource usage) 3. **Block-level**: Per-block device metrics (I/O patterns, thermal distribution) Mama Forth observes all three tiers and makes system-level decisions: - When to spawn/kill child VMs - How to allocate block devices to children - How to enforce governance across the ecosystem - How to respond to emergencies (thermal runaway, memory pressure, etc.) --- == Part 1: VM-LEVEL PHYSICS METADATA === Current State (Word-Level Only) Today's physics model tracks per-word metrics: ```c typedef struct { uint16_t temperature_q8; // Thermal state [0x0000, 0xFFFF] uint64_t last_active_ns; // Last execution timestamp uint32_t entropy; // Execution randomness int16_t entropy_slope; // Rate of entropy change uint32_t avg_latency_ns; // P50 latency // ... more fields } DictPhysics; ``` This is attached to each `DictEntry` (word). === New: VM-Level Aggregation Each VM now has its own physics metadata reflecting aggregate state: ```c typedef struct { // Thermal state (aggregate across all words) uint16_t vm_temperature_q8; // Warmest word temperature uint16_t vm_avg_temperature_q8; // Average across all words uint32_t vm_hot_word_count; // Words with temp > 0x8000 // Execution load (how busy is this VM?) uint64_t total_word_executions; // Cumulative execution count uint64_t execution_rate_per_sec; // Words/sec this VM is executing uint64_t last_execution_ns; // Most recent word execution // Memory pressure uint32_t dictionary_used_bytes; // Current dict heap usage uint32_t dictionary_max_bytes; // Capacity float dictionary_pressure_pct; // Used / max // Error/reliability metrics uint32_t error_count; // Total errors encountered uint32_t error_rate_per_sec; // Errors/sec uint32_t recovery_count; // Successful recoveries // Child VM health (for Mama Forth) uint32_t child_vm_count; // How many children spawned uint32_t active_child_vm_count; // Currently alive uint16_t hottest_child_temp; // Hottest child's temperature uint32_t total_child_latency_ns; // Sum of all children's latencies // Block device affinity uint32_t blocks_allocated; // Total blocks in use uint32_t blocks_hot; // Hot blocks (temp > 0x8000) uint32_t blocks_cold; // Cold blocks (temp < 0x2000) // Lifecycle state uint32_t vm_uptime_ns; // Time since VM started uint32_t vm_age_ns; // For time-based decisions uint8_t vm_state; // RUNNING, PAUSED, DRAINING, DEAD uint8_t vm_criticality; // System, critical, normal, background } VMPhysics; ``` === Where This Attaches ```c typedef struct VM { // ... existing VM fields ... Cell *data_stack; Cell *return_stack; DictEntry *dictionary; // NEW: Physics state for this VM VMPhysics physics; // ... rest of VM struct ... } VM; ``` === How It's Maintained Every physics event updates VM-level metrics: ```c // In physics_metadata_touch() (src/physics_metadata.c) void physics_metadata_touch(DictEntry *word, uint32_t entropy, uint64_t now) { // Update word metrics (existing) word->physics.temperature_q8 = ...; word->physics.last_active_ns = now; // NEW: Update VM metrics VM *vm = get_current_vm(); // Thread-local or context-aware vm->physics.total_word_executions++; if (word->physics.temperature_q8 > vm->physics.vm_temperature_q8) { vm->physics.vm_temperature_q8 = word->physics.temperature_q8; } // Recalculate running aggregates physics_update_vm_aggregates(vm); } void physics_update_vm_aggregates(VM *vm) { uint32_t total_temp = 0; uint32_t hot_count = 0; for (DictEntry *w = vm->dictionary; w; w = w->link) { total_temp += w->physics.temperature_q8; if (w->physics.temperature_q8 > 0x8000) hot_count++; } vm->physics.vm_avg_temperature_q8 = total_temp / dict_entry_count; vm->physics.vm_hot_word_count = hot_count; vm->physics.execution_rate_per_sec = calculate_rate(vm->physics.total_word_executions, vm->physics.vm_uptime_ns); } ``` --- == Part 2: BLOCK DEVICE PHYSICS METADATA === Current State Block storage (1024 blocks × 1024 bytes) is managed by: - `src/block_subsystem.c` - Logical → physical mapping - `blkio_factory.c` - Backend pluggability (RAM, file, L4Re) - No observability beyond capacity tracking === New: Per-Block Metrics Each block device gets physics metadata: ```c typedef struct { // Thermal state (access frequency) uint16_t block_temperature_q8; // Hot = frequently accessed uint64_t last_read_ns; // Last read timestamp uint64_t last_write_ns; // Last write timestamp // Access patterns uint64_t read_count; // Total reads uint64_t write_count; // Total writes uint32_t read_avg_latency_ns; // P50 read latency uint32_t write_avg_latency_ns; // P50 write latency uint32_t read_p99_latency_ns; // P99 read latency // Ownership uint32_t owner_vm_id; // Which VM owns this block uint32_t owner_word_id; // Which word uses it (if any) // Content type (hints for optimization) uint8_t block_type; // BLOCK_TYPE_CODE, DATA, HEAP, SPILLED uint8_t access_pattern; // PATTERN_SEQUENTIAL, RANDOM, CACHED // Corruption/health uint32_t crc32; // Current block checksum uint8_t is_dirty; // Unflushed writes? uint8_t is_corrupted; // Detection flag uint32_t error_count; // Read/write errors } BlockPhysics; ``` === Where This Attaches ```c // In include/block_subsystem.h typedef struct { uint32_t block_num; uint8_t *data; // 1024 bytes // NEW: Physics metadata for this block BlockPhysics physics; // Lifecycle time_t last_modified; uint8_t is_locked; // Currently in use? } Block; typedef struct { Block blocks[MAX_BLOCKS]; // Array of 1024 blocks uint32_t block_count; // NEW: Aggregate block device stats struct { uint64_t total_reads; uint64_t total_writes; uint32_t hottest_block_temp; uint32_t coldest_block_temp; uint32_t avg_block_temp; uint32_t fragmentation_pct; // How scattered are active blocks? } device_physics; } BlockDevice; ``` === How It's Maintained When accessing blocks: ```c // In block_subsystem.c Block *block_read(uint32_t block_num) { uint64_t start = sf_monotonic_ns(); Block *blk = &g_block_device.blocks[block_num]; uint8_t *data = blkio_read(block_num); // Actual I/O uint64_t latency = sf_monotonic_ns() - start; // Update block physics blk->physics.last_read_ns = sf_monotonic_ns(); blk->physics.read_count++; blk->physics.read_avg_latency_ns = (blk->physics.read_avg_latency_ns + latency) / 2; // EMA // Thermal update (read activity indicates heat) blk->physics.block_temperature_q8 = update_temperature_from_read_frequency(blk->physics.read_count); // Check for corruption uint32_t crc = crc32_calc(data, BLOCK_SIZE); if (crc != blk->physics.crc32) { blk->physics.is_corrupted = 1; blk->physics.error_count++; log_error("Block %u corruption detected!", block_num); } return blk; } Block *block_write(uint32_t block_num, const uint8_t *data) { uint64_t start = sf_monotonic_ns(); Block *blk = &g_block_device.blocks[block_num]; blkio_write(block_num, data); // Actual I/O uint64_t latency = sf_monotonic_ns() - start; // Update block physics blk->physics.last_write_ns = sf_monotonic_ns(); blk->physics.write_count++; blk->physics.write_avg_latency_ns = (blk->physics.write_avg_latency_ns + latency) / 2; // EMA blk->physics.is_dirty = 0; // Now clean blk->physics.crc32 = crc32_calc(data, BLOCK_SIZE); // Thermal update (write activity = heat) blk->physics.block_temperature_q8 = update_temperature_from_write_frequency(blk->physics.write_count); return blk; } ``` --- == Part 3: MAMA FORTH ARCHITECTURE === Mama's Responsibilities Mama Forth is a special FORTH VM with elevated privileges: ``` ┌──────────────────────────────────────┐ │ Mama Forth VM │ │ (Privileged Supervisor) │ ├──────────────────────────────────────┤ │ OBSERVE: │ │ • All word executions in children │ │ • All block device I/O │ │ • All child VM lifecycle events │ │ • All errors and anomalies │ ├──────────────────────────────────────┤ │ CONTROL: │ │ • Spawn/kill child VMs │ │ • Allocate blocks to children │ │ • Enforce governance policies │ │ • Redirect critical work │ │ • Scale up/down based on load │ ├──────────────────────────────────────┤ │ COORDINATE: │ │ • Resource sharing (blocks) │ │ • Deadlock prevention │ │ • Load balancing across children │ │ • Graceful degradation under stress │ └──────────────────────────────────────┘ ``` === Mama's Own Physics Mama Forth itself is instrumented: ```c typedef struct { // Mama's execution load uint64_t supervision_cycles; // How often Mama checks state uint64_t decision_count; // Decisions made uint32_t decision_latency_ns; // Decision time // Child management uint32_t child_vm_created_total; // Lifetime creations uint32_t child_vm_killed_total; // Lifetime terminations uint32_t child_spawn_rate_per_sec; // Block device management uint32_t block_realloc_count; // How many rebalancings uint32_t block_fragmentation_pct; uint32_t block_compaction_latency_ns; // Emergency events uint32_t thermal_warnings; // Hot child warnings issued uint32_t memory_pressure_events; // High pressure detected uint32_t orphan_recovery_count; // Recovered dead children's blocks // Governance uint32_t governance_violations_detected; uint32_t policy_enforcement_count; uint32_t audit_events_logged; } MamaPhysics; ``` === Mama's Control Loop Mama Forth runs a supervision loop: ```c // In src/mama_forth.c (new) void mama_supervision_loop(void) { while (mama_vm.running) { // Step 1: Observe all child VMs for (int i = 0; i < child_vm_count; i++) { VM *child = child_vms[i]; // Collect child's VM-level physics VMPhysics child_physics = child->physics; // Check for anomalies if (child_physics.vm_temperature_q8 > THERMAL_WARNING) { mama_handle_hot_child(child); } if (child_physics.dictionary_pressure_pct > 90) { mama_handle_memory_pressure(child); } if (child_physics.error_rate_per_sec > ERROR_THRESHOLD) { mama_handle_error_surge(child); } } // Step 2: Observe all block devices BlockDevice *dev = &g_block_device; if (dev->device_physics.hottest_block_temp > THERMAL_WARNING) { mama_cool_hot_blocks(dev); } if (dev->device_physics.fragmentation_pct > 70) { mama_defragment_blocks(dev); } // Step 3: Make load-balancing decisions mama_balance_load_across_children(); // Step 4: Enforce governance mama_check_governance_compliance(); // Step 5: Sleep until next supervision cycle uint64_t supervision_interval = mama_vm.physics.decision_latency_ns * 2; // Adaptive sf_sleep_ns(supervision_interval); } } ``` === Key Mama Decisions **When to spawn a child VM**: ```c void mama_maybe_spawn_child(void) { // Conditions for spawning: // 1. Current child VMs are too hot (temperature > 0xD000) // 2. Block device fragmentation > 50% // 3. Incoming work queue depth > threshold // 4. Have spare blocks available int current_children = count_active_children(); float avg_temp = calculate_avg_child_temp(); if (avg_temp > 0xD000 && current_children < MAX_CHILDREN) { VM *new_child = create_child_vm(); child_vms[current_children] = new_child; // Allocate blocks to child allocate_blocks_to_child(new_child, BLOCKS_PER_CHILD); // Load-balance work rebalance_work_queue(); mama_vm.physics.child_spawn_rate_per_sec++; } } ``` **When to kill a child VM**: ```c void mama_maybe_kill_child(VM *child) { // Conditions for killing: // 1. Child VM is dead (error_flag set and can't recover) // 2. Child is idle (no executions in last N seconds) // 3. Child's memory pressure unrecoverable // 4. System needs to shed load if (child->physics.error_count > ERROR_TOLERANCE && !child->physics.recovery_count) { // Dead child, can't recover // Orphan recovery: reassign child's blocks mama_recover_orphan_blocks(child); // Kill child vm_cleanup(child); mama_vm.physics.child_vm_killed_total++; } } ``` **When to rebalance blocks**: ```c void mama_rebalance_block_allocation(void) { // Mama observes: // - Which blocks each child is using (owner_vm_id) // - Which blocks are hot (high temperature) // - Which blocks are cold (low temperature) // Strategy: // - Hot blocks should be near child that uses them most // - Cold blocks can be shared/archived // - Fragmented allocation should be compacted // For each child: for (int i = 0; i < child_vm_count; i++) { VM *child = child_vms[i]; // Find hottest blocks owned by this child Block *hottest = find_hottest_child_blocks(child, 10); // Group them together (reduce fragmentation) compact_block_range(hottest); // Update child's block allocation pointer child->block_start = hottest[0].block_num; child->block_end = hottest[9].block_num; } mama_vm.physics.block_realloc_count++; } ``` --- == Part 4: THREE-TIER FEEDBACK LOOP === How Metrics Flow Upward ``` TIER 1: Word Execution word.physics.temperature_q8 ← entropy update word.physics.latency_ns ← measured execution time │ ↓ aggregated by VM TIER 2: VM State vm.physics.vm_avg_temperature_q8 ← aggregate of words vm.physics.dictionary_pressure_pct ← heap usage vm.physics.execution_rate_per_sec ← word executions │ ↓ aggregated by Mama Forth TIER 3: System State mama.physics.decision_latency_ns ← how fast Mama responds mama.physics.child_spawn_rate_per_sec ← how many created mama.physics.block_fragmentation_pct ← block disorder │ ↓ logged to analytics heap (all three tiers) ``` === How Decisions Flow Downward ``` MAMA FORTH Decision "Child 2 is too hot, spawn Child 3" │ ↓ Create new VM, allocate blocks │ ↓ CHILD VM Adjustment "New work assigned, need to optimize" - Adjust word batch groups - Increase sampling rate - Monitor for overload │ ↓ WORD-LEVEL Optimization "This word is hot, boost priority" - Increase temperature target - Reduce stack depth limit - Monitor latency SLO │ ↓ BLOCK DEVICE Response "Child 2's blocks are hot" - Move cold blocks to Child 3 - Compact fragmented allocation - Pre-fetch predicted accesses ``` --- == Part 5: CONCRETE EXAMPLE: THERMAL EMERGENCY === Scenario: Child VM Goes Critical ``` T=0s: Child VM1 executing normally All blocks allocated to Child1 Mama monitoring periodically T=5s: Word BLOCK_WRITE becomes very hot word.physics.temperature_q8 = 0xC000 Word passes temperature to VM1 T=5.5s: VM1.physics.vm_temperature_q8 = 0xC000 VM1.physics.hot_word_count = 15 Mama's next supervision cycle detects this T=6s: MAMA OBSERVES: Child1.vm_temperature_q8 > THERMAL_WARNING (0xC000) Child1.dictionary_pressure_pct > 70% Child1.error_rate_per_sec = 100 errors/sec (anomaly!) MAMA DECISIONS: 1. Spawn Child VM2 (load shedding) 2. Reassign cold work from Child1 to Child2 3. Mark Child1's hot blocks as protected (no eviction) 4. Increase Child1's heap size (temporary override) 5. Log thermal emergency to governance MAMA ACTIONS: vm2 = create_child_vm(); allocate_blocks_to_child(vm2, 100); rebalance_work_queue(); set_child_priority(vm1, PRIORITY_CRITICAL); T=6.5s: Child1 starts recovering vm_temperature_q8 stabilizing at 0xB000 error_rate_per_sec dropping (was 100, now 80) T=7s: Child2 now executing cold work Child1 focusing on hot critical path Load distributed T=10s: System stabilized Mama decides: keep Child2 (now has useful work) Will kill only if Child1 cools below THERMAL_OK ``` --- == Part 6: IMPLEMENTATION PHASES === Phase 1: Foundation (Current) - ✅ Word-level physics metadata (existing) - ✅ Execution hooks wired - ⏳ VM-level aggregation (add VMPhysics struct) - ⏳ Block device physics (add BlockPhysics struct) === Phase 2: Single-VM Control - ✅ Word-level scheduling hints - ✅ Word-level memory management - ⏳ VM-level health monitoring - ⏳ Mama Forth basic supervision (observe only) === Phase 3: Multi-VM Orchestration - ⏳ Child VM spawning/killing - ⏳ Block reallocation - ⏳ Load balancing across children - ⏳ Emergency response (thermal, memory, error) === Phase 4: Mama Optimization - ⏳ Mama's own physics optimization - ⏳ Predictive spawning (before threshold) - ⏳ ML-guided load balancing - ⏳ Governance enforcement at scale --- == Data Structures Summary === New in vm.h ```c // Attach to VM struct typedef struct { // ... 20+ fields as described above ... } VMPhysics; typedef struct VM { // ... existing ... VMPhysics physics; // NEW // ... existing ... } VM; ``` === New in block_subsystem.h ```c // Attach to each Block typedef struct { // ... 15+ fields as described above ... } BlockPhysics; typedef struct { uint32_t block_num; uint8_t *data; BlockPhysics physics; // NEW } Block; // Attach to BlockDevice typedef struct { Block blocks[MAX_BLOCKS]; struct { // ... device-level aggregate fields ... } device_physics; // NEW } BlockDevice; ``` === New: mama_forth.h (new file) ```c typedef struct { // ... 10+ fields as described above ... } MamaPhysics; typedef struct { VM vm; // Mama is a VM MamaPhysics physics; VM **child_vms; // Array of children uint32_t child_count; } MamaForth; extern MamaForth mama_forth; // Supervision functions void mama_supervision_loop(void); void mama_maybe_spawn_child(void); void mama_maybe_kill_child(VM *child); void mama_rebalance_block_allocation(void); void mama_check_governance_compliance(void); ``` --- == Integration Points === In src/physics_metadata.c Update `physics_metadata_touch()` to also update VM-level metrics: ```c void physics_metadata_touch(DictEntry *word, uint32_t entropy, uint64_t now) { // ... update word metrics ... // NEW: Update parent VM metrics VM *vm = get_current_vm(); vm->physics.total_word_executions++; if (word->physics.temperature_q8 > vm->physics.vm_temperature_q8) { vm->physics.vm_temperature_q8 = word->physics.temperature_q8; } physics_update_vm_aggregates(vm); } ``` === In src/block_subsystem.c Update `block_read()` and `block_write()` to track block physics: ```c Block *block_read(uint32_t block_num) { // ... existing read logic ... uint64_t latency = sf_monotonic_ns() - start; // NEW: Update block physics Block *blk = get_block(block_num); blk->physics.last_read_ns = now; blk->physics.read_count++; blk->physics.read_avg_latency_ns = (blk->physics.read_avg_latency_ns + latency) / 2; blk->physics.block_temperature_q8 = compute_temperature_from_frequency(blk->physics.read_count); } ``` === In src/main.c Spawn Mama Forth as separate thread or coroutine: ```c int main(int argc, char *argv[]) { // Initialize Mama Forth VM mama_forth_init(); // Start Mama's supervision loop (in background or main loop) mama_supervision_loop(); // Start child VMs as needed // ... } ``` --- == References - Physics Implementation Status: xref:./PHYSICS_IMPLEMENTATION_STATUS.adoc[PHYSICS_IMPLEMENTATION_STATUS.adoc] - Physics Control System: xref:./PHYSICS_CONTROL_SYSTEM_DESIGN.adoc[PHYSICS_CONTROL_SYSTEM_DESIGN.adoc] - Physics Implementation Options: xref:./PHYSICS_IMPLEMENTATION_OPTIONS.adoc[PHYSICS_IMPLEMENTATION_OPTIONS.adoc] - Block Subsystem: `src/block_subsystem.c`, `include/block_subsystem.h` - VM Core: `src/vm.c`, `include/vm.h` - Governance: `docs/src/governance/` (compliance framework)