summaryrefslogtreecommitdiff
path: root/ocaml/BOOT_FLOW.md
diff options
context:
space:
mode:
Diffstat (limited to 'ocaml/BOOT_FLOW.md')
-rw-r--r--ocaml/BOOT_FLOW.md172
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!