diff options
Diffstat (limited to 'ocaml/BOOT_FLOW.md')
-rw-r--r-- | ocaml/BOOT_FLOW.md | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/ocaml/BOOT_FLOW.md b/ocaml/BOOT_FLOW.md new file mode 100644 index 0000000..7f9d417 --- /dev/null +++ b/ocaml/BOOT_FLOW.md @@ -0,0 +1,172 @@ +# Complete Boot Flow in C Vere (`-B solid.pill`) + +## The Simple Truth + +When you run `vere -B solid.pill`, here's exactly what happens: + +### Step 0: Command Line Processing + +**Location**: `main.c:418` +```c +case 'B': + u3_Host.ops_u.pil_c = _main_repath(optarg); // Store pill filepath +``` + +### Step 1: Load Pill File (`_boothack_pill`) + +**Location**: `king.c:611-613` +```c +if ( 0 != u3_Host.ops_u.pil_c ) { + u3l_log("boot: loading pill %s", u3_Host.ops_u.pil_c); + pil = u3m_file(u3_Host.ops_u.pil_c); // Load raw bytes into memory +} +``` + +Returns: `[pil arv]` where `pil` is raw pill bytes, `arv` is optional filesystem + +### Step 2: Cue the Pill Bytes (`u3_mars_boot`) + +**Location**: `mars.c:1958` +```c +u3_weak jar = u3s_cue_xeno(len_d, hun_y); // Cue the pill bytes +if ( (u3_none == jar) || (c3n == u3r_p(jar, c3__boot, &com)) ) { + fprintf(stderr, "boot: parse fail\r\n"); + exit(1); +} +``` + +Expects pill structure: `[%boot com]` + +### Step 3: Extract Events from Pill (`_mars_boot_make`) + +**Location**: `mars.c:1971` +```c +_mars_sift_pill(u3k(pil), &bot, &mod, &use, &cax) +``` + +Pill structure: `[%pill %solid [bot mod use]]` +- `bot`: Lifecycle events (boot sequence) +- `mod`: Module/vane events +- `use`: Userspace/app events + +### Step 4: Write Events to Disk + +**Location**: `mars.c:1985-1987` +```c +u3_disk_plan_list(log_u, ova); // Write events to LMDB +u3_disk_sync(log_u); // Sync to disk +``` + +### Step 5: Read Events Back and Boot + +**Location**: `mars.c:1993` +```c +_mars_do_boot(log_u, log_u->dun_d, cax); // Boot from disk +``` + +Inside `_mars_do_boot` (line 1107): +```c +eve = u3_disk_read_list(log_u, 1, eve_d, &mug_l); // Read from disk +``` + +Then (line 1160): +```c +u3v_boot(eve); // Boot with event list! +``` + +## Event Structure Details + +### Event Creation in `_mars_boot_make` (`mars.c:1814-1836`) +```c +u3_noun now = u3_time_in_tv(&inp_u->tim_u); +u3_noun eve = u3kb_flop(bot); // Start with bot events (NO TIMESTAMP!) + +u3_noun lit = u3kb_weld(mod, use); +while ( u3_nul != t ) { + u3x_cell(t, &i, &t); + now = u3ka_add(now, u3k(bit)); + eve = u3nc(u3nc(u3k(now), u3k(i)), eve); // Add timestamped event [now i] +} + +*ova = u3kb_flop(eve); // Final event list +``` + +**KEY**: Bot events are **NOT timestamped**, mod/use events ARE timestamped as `[timestamp event]` + +### Step 4: Write Events to Disk + +**Location**: `mars.c:1955` +```c +u3_disk_plan_list(log_u, ova); // Write events to LMDB +u3_disk_sync(log_u); // Sync to disk +``` + +### Step 5: Read Events Back and Boot (`_mars_do_boot`) + +**Location**: `mars.c:1107` +```c +eve = u3_disk_read_list(log_u, 1, eve_d, &mug_l); // Read from disk +``` + +Each event is cued from disk: +```c +// disk.c: +*job = u3ke_cue(u3i_bytes(len_i - 4, dat_y + 4)); +ven_u->eve = u3nc(job, ven_u->eve); // Cons onto list +return u3kb_flop(ven_u->eve); // Return flipped list +``` + +## Summary: The Complete `-B` Flow + +1. **Load**: `u3m_file()` loads pill bytes from filepath +2. **Cue**: `u3s_cue_xeno()` deserializes to `[%boot com]` structure +3. **Parse**: `_mars_boot_make()` extracts bot/mod/use events and timestamps them +4. **Persist**: `u3_disk_plan_list()` writes to LMDB, `u3_disk_sync()` commits +5. **Read**: `u3_disk_read_list()` reads events back from disk +6. **Boot**: `u3v_boot(eve)` boots with the event list + +## What We Need to Implement in OCaml + +Just follow the same pattern: + +```ocaml +(* Load pill file *) +let pill_bytes = load_file pill_path in + +(* Cue the pill *) +let pill_noun = Serial.cue pill_bytes in + +(* Extract [%boot com] *) +let com = extract_boot_structure pill_noun in + +(* Parse into bot/mod/use events *) +let (bot, mod_, use_) = parse_pill_structure com in + +(* Timestamp mod/use events (bot events stay bare) *) +let event_list = build_event_list bot mod_ use_ in + +(* For now, skip disk persistence and boot directly *) +Boot.boot event_list +``` + +**Key Insight**: Bot events are **NOT timestamped** (they're bare nouns), while mod/use events **ARE timestamped** as `[timestamp event]` pairs. + +## The "eve=null" Mystery Solved + +From the actual boot log: +``` +lite: arvo formula 4ce68411 +u3v_life: eve=null (atom=yes cell=no) ← First call (ivory pill) +u3v_life: completed successfully +lite: core 641296f + +_mars_do_boot: first event is atom ← Bot events are atoms! +u3v_boot: processing 10 events +u3v_life: eve=null (atom=yes cell=no) ← Second call (from vortex.c) +``` + +There are **TWO** `u3v_life` calls: +1. First: Ivory pill bootstrap (eve=null creates initial kernel) +2. Second: Inside `u3v_boot()` which processes the 10 events + +The `eve=null` log in the second call is likely referring to the **original** `eve` parameter before it's been processed, NOT the actual subject passed to the lifecycle formula! |