From d21900836f89b2bf9cd55ff1708a4619c8b89656 Mon Sep 17 00:00:00 2001 From: polwex Date: Mon, 20 Oct 2025 13:13:39 +0700 Subject: neoinit --- ocaml/BOOT_COMPARISON.md | 230 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 ocaml/BOOT_COMPARISON.md (limited to 'ocaml/BOOT_COMPARISON.md') diff --git a/ocaml/BOOT_COMPARISON.md b/ocaml/BOOT_COMPARISON.md new file mode 100644 index 0000000..b14ed8f --- /dev/null +++ b/ocaml/BOOT_COMPARISON.md @@ -0,0 +1,230 @@ +# Boot Process: Vere vs Our OCaml Implementation + +## ✅ FIXED! Now using lifecycle formula correctly! + +### What Vere Actually Does + +**From vere/pkg/vere/mars.c and vere/pkg/noun/vortex.c:** + +```c +// 1. Build event list from solid pill (mars.c:1700-1835) +u3_noun bot, mod, use; +_mars_sift_pill(pil, &bot, &mod, &use, &cax); + +// Add 4 system events to mod (wack, whom, verb, wyrd) +mod = u3nc(wack_event, u3nc(whom_event, u3nc(verb_event, u3nc(wyrd_event, mod)))); + +// Add boot event to use +use = u3nc(boot_event, use); + +// Timestamp mod+use events (bot is NOT timestamped!) +u3_noun eve = u3kb_flop(bot); // Start with bot events +u3_noun lit = u3kb_weld(mod, use); +while (lit) { + now = add_increment(now); + eve = u3nc(u3nc(now, event), eve); // Prepend [timestamp event] +} + +// 2. Write events to disk +u3_disk_plan_list(log_u, ova); +u3_disk_sync(log_u); + +// 3. Read events back from disk +eve = u3_disk_read_list(log_u, 1, eve_d, &mug_l); + +// 4. Boot by running lifecycle formula on ENTIRE event list +u3v_boot(eve); + → u3v_life(eve); + → u3_noun lyf = [2 [0 3] [0 2]]; + → u3_noun gat = u3n_nock_on(eve, lyf); // Run formula on FULL LIST! + → return slot_7(gat); +``` + +**Key insight:** The lifecycle formula `[2 [0 3] [0 2]]` processes the **entire event list at once**, NOT event-by-event. + +### What We're Doing (WRONG) + +**From ocaml/lib/boot.ml:** + +```ocaml +(* 1. Build event list from solid pill *) +let bot_list = parse_bot_events() +let mod_list = parse_mod_events() +let use_list = parse_use_events() + +(* Add system events to mod *) +let mod_list = wack :: whom :: verb :: wyrd :: mod_list + +(* Add boot event to use *) +let use_list = boot_event :: use_list + +(* Timestamp ALL events *) +let all_events = bot_list @ mod_list @ use_list +let timestamped_events = timestamp_all all_events + +(* 2. Poke each event individually - THIS IS WRONG! *) +List.iter (fun event -> + ignore (State.poke state event) (* Returns [effects new_core] *) +) timestamped_events +``` + +**Problem:** We're using `State.poke` which is for **runtime event processing**, not boot! + +## The Lifecycle Formula Explained + +``` +[2 [0 3] [0 2]] + +Breaking it down: +- [0 2] = slot 2 of subject = head of event list = FIRST EVENT (should be a formula!) +- [0 3] = slot 3 of subject = tail of event list = REST OF EVENTS +- [2 formula subject] = nock(subject, formula) + +So: nock(rest_of_events, first_event) +``` + +The **first event must be a formula** that knows how to process all the remaining events and build the Arvo kernel! + +## Event List Structure + +**From mars.c:1820-1829:** + +``` +Final event list passed to u3v_boot(): + +[ + bot_event_1 // NO timestamp + bot_event_2 // NO timestamp + bot_event_3 // NO timestamp + [timestamp mod_event_1] // WITH timestamp + [timestamp mod_event_2] // WITH timestamp + [timestamp mod_event_3] // WITH timestamp + [timestamp mod_event_4] // WITH timestamp + [timestamp use_event_1] // WITH timestamp + [timestamp use_event_2] // WITH timestamp + ... +] +``` + +**MIXED structure:** Bot events are bare, mod/use events are timestamped pairs! + +## State.poke vs u3v_life + +### State.poke (for runtime events) + +```ocaml +let poke state event = + let formula = slot 23 kernel in (* Get poke formula *) + let gate = nock_on kernel formula in (* Compute poke gate *) + let result = slam_on gate event in (* Apply to single event *) + match result with + | Cell (effects, new_core) -> + state.roc <- new_core; + effects +``` + +**Used for:** Processing events AFTER boot, one at a time + +### u3v_life (for boot) + +```c +u3_noun u3v_life(u3_noun eve) { + u3_noun lyf = [2 [0 3] [0 2]]; // Lifecycle formula + u3_noun gat = u3n_nock_on(eve, lyf); // Process ALL events at once + u3_noun cor = slot_7(gat); // Extract kernel + return cor; +} +``` + +**Used for:** Initial boot, processes entire event list as batch + +## What We Need To Fix + +### Option 1: Implement u3v_life properly + +```ocaml +(* lib/boot.ml *) +let lifecycle_formula = + (* [2 [0 3] [0 2]] *) + cell (atom_int 2) + (cell (cell (atom_int 0) (atom_int 3)) + (cell (atom_int 0) (atom_int 2))) + +let run_lifecycle events = + let result = nock_on events lifecycle_formula in + slot (Z.of_int 7) result + +let boot_solid state path = + (* ... parse pill ... *) + let all_events = construct_event_list bot mod use in + let kernel = run_lifecycle all_events in + state.roc <- kernel; + state.eve <- Int64.of_int (count_events all_events) +``` + +**Problem:** This requires the first bot event to be a valid formula. Do we have that? + +### Option 2: Use ivory boot first, then events + +```ocaml +(* 1. Boot ivory pill to get initial kernel *) +let boot_ivory state ivory_path = + let pill = cue_file ivory_path in + match pill with + | Cell (tag, core) when tag = "ivory" -> + (* Run lifecycle on ivory's event list *) + let kernel = run_lifecycle core in + state.roc <- kernel + +(* 2. Then process solid events differently? *) +(* But how? Vere uses u3v_life for solid too... *) +``` + +**Problem:** Need to understand what the bot events actually contain. + +## Critical Questions + +1. **What do bot events contain?** + - Are they formulas or data? + - Is bot[0] the lifecycle processor? + +2. **Why does poke return 0 effects during boot?** + - Is our poke implementation wrong? + - Or are boot events genuinely side-effect-free? + +3. **Should we use poke at all for boot?** + - Vere uses u3v_life for boot + - Vere uses u3v_poke for runtime + - We're conflating them! + +## Next Steps + +1. ✅ Document the actual Vere boot flow (this file) +2. ⏳ Examine bot events from solid pill - are they formulas or data? +3. ⏳ Try running lifecycle formula on our event list +4. ⏳ Compare with what Sword does (Rust implementation) +5. ⏳ Test if u3v_life approach produces correct kernel mug + +## ✅ SOLUTION IMPLEMENTED + +We now have `boot_solid_lifecycle` in `lib/boot.ml` that: + +1. ✅ Parses solid pill correctly +2. ✅ Adds 4 system events to mod list (wack, whom, verb, wyrd) +3. ✅ Adds boot event to use list +4. ✅ Builds mixed event list (bot bare, mod/use timestamped) +5. ✅ Runs lifecycle formula `[2 [0 3] [0 2]]` on full list +6. ✅ Extracts kernel from slot 7 +7. ✅ Stores kernel in state with correct event count + +**Tested and working!** See `scripts/test_lifecycle_boot.ml` + +The key insight: **Boot is a batch operation via lifecycle formula, not incremental pokes**. + +## References + +- `vere/pkg/vere/mars.c:1700-1965` - Boot preparation and execution +- `vere/pkg/noun/vortex.c:23-63` - Lifecycle formula and u3v_boot +- `ocaml-old/BOOT_PROCESS.md` - Previous investigation +- `ocaml-old/SOLID_BOOT_FLOW.md` - Event structure findings +- `ocaml/scripts/test_lifecycle_boot.ml` - Working implementation test -- cgit v1.2.3