1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
|
---
description: "Core Academy lesson on Arvo's boot sequence covering pill creation and loading, larval and adult phases, vane initialization, userspace bootstrapping, and the complete boot process."
layout:
title:
visible: true
description:
visible: false
tableOfContents:
visible: true
outline:
visible: true
pagination:
visible: true
---
# 5. Arvo II: The Boot Sequence
*This lesson covers Arvo's boot sequence: pills, the larval phase, initializing vanes, initializing userspace.*
> The formal state of an Arvo instance is an event history, as a linked list of nouns from first to last. The history starts with a bootstrap sequence that delivers Arvo itself, first as an inscrutable kernel, then as the self-compiling source for that kernel. (Whitepaper)
When Arvo starts for the first time, how does it work? It tells you something of that process; as of Vere 2.12/Arvo 412 K, the boot sequence output looks like this:
Fake ship ~fes:
```hoon
~
urbit 2.12
boot: home is fes
loom: mapped 2048MB
lite: arvo formula 2a2274c9
lite: core 4bb376f0
lite: final state 4bb376f0
boot: downloading pill https://bootstrap.urbit.org/urbit-v2.12.pill
boot: parsing %solid pill
dock: pace (live): configured at fes/.bin/pace
vere: binary copy succeeded
loom: mapped 2048MB
boot: protected loom
live: logical boot
boot: installed 661 jets
---------------- playback starting ----------------
pier: replaying events 1-14
arvo: metamorphosis
clay: kernel updated
clay: rebuilding %base after kernel update
gall: installing %acme
gall: installing %azimuth
gall: installing %dbug
gall: installing %dojo
gall: installing %eth-watcher
gall: installing %hood
drum: link [~fes %dojo]
kiln: boot
gall: installing %herm
gall: installing %lens
gall: installing %ping
gall: installing %spider
gall: installing %talk-ui
Not running %settings-store yet, got %poke
gall: installing %docket
gall: installing %treaty
gall: installing %hark-store
gall: installing %hark-system-hook
gall: installing %settings
gall: installing %settings-store
gall: installing %storage
gall: installing %reel
gall: installing %bait
gall: installing %vitals
gall: installing %growl
docket: fetching %http glob for %talk desk
docket: fetching %http glob for %garden desk
docket: fetching %http glob for %talk desk
docket: fetching %http glob for %garden desk
docket: fetching %http glob for %webterm desk
docket: fetching %http glob for %landscape desk
gall: installing %metadata-store
gall: installing %contact-store
gall: installing %chat-store
gall: installing %graph-store
gall: installing %group-store
%group-store: on-init
gall: installing %invite-store
gall: installing %s3-store
gall: installing %chat-hook
gall: installing %chat-view
gall: installing %clock
gall: installing %contact-hook
gall: installing %contact-pull-hook
gall: installing %contact-push-hook
gall: installing %contact-view
gall: installing %dm-hook
gall: installing %graph-pull-hook
gall: installing %graph-push-hook
gall: installing %group-pull-hook
gall: installing %group-push-hook
gall: installing %group-view
gall: installing %hark-chat-hook
gall: installing %hark-graph-hook
gall: installing %hark-group-hook
gall: installing %hark-invite-hook
gall: installing %invite-hook
gall: installing %invite-view
gall: installing %launch
gall: installing %metadata-hook
gall: installing %metadata-pull-hook
gall: installing %metadata-push-hook
gall: installing %observe-hook
gall: installing %sane
gall: installing %weather
gall: not running %file-server yet, got %poke
%group-store: on-peek on path /y/groups
%group-store: on-watch on path /groups
%group-store: on-watch on path /groups
%group-store: on-watch on path /groups
%group-store: on-watch on path /groups
%group-store: on-watch on path /groups
docket: fetching %http glob for %groups desk
gall: installing %groups
gall: installing %chat
gall: installing %contacts
%contacts: on-init
gall: installing %heap
gall: installing %diary
gall: installing %hark
gall: installing %notify
gall: installing %groups-ui
gall: installing %grouper
%contacts: on-poke with mark %noun
%contacts: on-agent on wire /migrate, %poke-ack
[%agent-giving-on-system-duct %diary %fact]
pier: (14): play: done
---------------- playback complete ----------------
vere: checking version compatibility
loom: image backup complete
lick init mkdir fes/.urb/dev
ames: live on 31592 (localhost only)
conn: listening on fes/.urb/conn.sock
lick: %born failure;
http: web interface live on http://localhost:8080
http: loopback live on http://localhost:12321
pier (25): live
docket: fetching %http glob for %garden desk
ames: metamorphosis
; ~zod is your neighbor
~fes:dojo>
```
Live ship comet:
```
~
urbit 2.12
boot: home is /home/neal/comet-412
loom: mapped 2048MB
lite: arvo formula 2a2274c9
lite: core 4bb376f0
lite: final state 4bb376f0
Downloading pill https://bootstrap.urbit.org/urbit-v2.12.pill
Mining a comet. May take up to an hour.
If you want to boot faster, get an Urbit identity.
Found comet ~mipped-pinlug-loshec-tastun--tabfen-bitwex-norsul-wanzod
boot: verifying keys
Getting sponsor
boot: retrieving galaxy table
boot: retrieving network domains
boot: retrieving keys for sponsor ~wanzod
boot: retrieving keys for sponsor ~zod
boot: parsing %solid pill
pace (live): configured at /home/neal/comet-412/.bin/pace
vere: binary copy succeeded
loom: mapped 2048MB
boot: protected loom
logical boot
boot: installed 661 jets
---------------- playback starting ----------------
pier: replaying events 1-14
arvo: metamorphosis
gall: not running %azimuth yet, got %poke
arvo: kernel updated
clay: rebuilding %base after kernel update
gall: installing %acme
gall: installing %azimuth
gall: installing %dbug
gall: installing %dojo
gall: installing %eth-watcher
gall: installing %hood
link [~mipped-pinlug-loshec-tastun--tabfen-bitwex-norsul-wanzod %dojo]
kiln: boot
gall: installing %herm
gall: installing %lens
gall: nstalling %ping
gall: installing %spider
gall: installing %talk-ui
gall: not running %settings-store yet, got %poke
gall: installing %docket
gall: installing %treaty
gall: installing %hark-store
gall: installing %hark-system-hook
gall: installing %settings
gall: installing %settings-store
gall: installing %storage
gall: installing %reel
gall: installing %bait
gall: installing %vitals
gall: installing %growl
docket: fetching %http glob for %talk desk
docket: fetching %http glob for %garden desk
docket: fetching %http glob for %talk desk
docket: fetching %http glob for %garden desk
docket: fetching %http glob for %webterm desk
docket: fetching %http glob for %landscape desk
gall: installing %metadata-store
gall: installing %contact-store
gall: installing %chat-store
gall: installing %graph-store
gall: installing %group-store
%group-store: on-init
gall: installing %invite-store
gall: installing %s3-store
gall: installing %chat-hook
gall: installing %chat-view
gall: installing %clock
gall: installing %contact-hook
gall: installing %contact-pull-hook
gall: installing %contact-push-hook
gall: installing %contact-view
gall: installing %dm-hook
gall: installing %graph-pull-hook
gall: installing %graph-push-hook
gall: installing %group-pull-hook
gall: installing %group-push-hook
gall: installing %group-view
gall: installing %hark-chat-hook
gall: installing %hark-graph-hook
gall: installing %hark-group-hook
gall: installing %hark-invite-hook
gall: installing %invite-hook
gall: installing %invite-view
gall: installing %launch
gall: installing %metadata-hook
gall: installing %metadata-pull-hook
gall: installing %metadata-push-hook
gall: installing %observe-hook
gall: installing %sane
gall: installing %weather
gall: not running %file-server yet, got %poke
|«play»store: on-peek on path /y/groups
%group-store: on-watch on path /groups
%group-store: on-watch on path /groups
%group-store: on-watch on path /groups
%group-store: on-watch on path /groups
%group-store: on-watch on path /groups
docket: fetching %http glob for %groups desk
gall: installing %groups
gall: installing %chat
gall: installing %contacts
%contacts: on-init
gall: installing %heap
gall: installing %diary
gall: installing %hark
gall: installing %notify
gall: installing %groups-ui
gall: installing %grouper
%contacts: on-poke with mark %noun
%contacts: on-agent on wire /migrate, %poke-ack
[%agent-giving-on-system-duct %diary %fact]
pier: (14): play: done
---------------- playback complete ----------------
vere: checking version compatibility
loom: image backup complete
lick init mkdir /home/neal/comet-412/.urb/dev
ames: live on 52253
conn: listening on /home/neal/comet-412/.urb/conn.sock
lick: %born failure;
http: web interface live on http://localhost:8081
http: loopback live on http://localhost:12322
pier (25): live
docket: fetching %http glob for %garden desk
ames: czar zod.urbit.org: ip .35.247.119.159
ames: metamorphosis
; ~zod is your neighbor
ames: czar at zod.ur
~mipped_wanzod:dojo>
```
At the 10,000' level, we can read the current boot process into a few discrete stages:
1. Runtime startup
2. Boot sequence (pill)
1. Arvo larval phase
2. Arvo main sequence
3. Userspace startup (a lot of that output results from userspace slogs)
In this lesson, we will examine each of these steps.
## Runtime Startup {#runtime-startup}
To start an Urbit ship for the first time, you have to provide a ship name and the corresponding private key. It's easiest to demonstrate this with a moon using the values obtained from `|moon`. After allocating memory, the logical boot process proceeds.
The runtime spawns the king (`king.c`) and indirectly the serf (`serf.c`) processes. These will both run for the lifetime of the Urbit process.
- The serf is the Nock runtime. It tracks the current state of Arvo as a noun, updating the state by poking it with nouns. It informs the king of the new state.
- Vere provides a standard serf, what was known formerly as the `urbit-worker` process.
- Sword (née Ares) can be used as a serf in its Nock interpreter capacity, but requires I/O driver support to function this way entirely for Urbit.
- The king manages snapshots of Arvo's state and interfaces with Unix.
- Vere is the only Urbit king currently.
- King Haskell was an alternative king process that was dropped for maintenance reasons.
> The serf only ever talks to the king, while the king talks with both the serf and Unix.
When the runtime begins, it drops into `vere/main.c` and checks the command-line options and commands. `main()` has to decide what it needs to do (i.e. the command) and then it accordingly sets global flags. If this is a first-time boot or a restart of a pier, then `main()` starts the king with `u3_king_commence()`. (In general, `main.c` isn't very Urbit-y, it's a fairly orthodox C startup file.)
The first thing the king does is use `vere/dawn.c` to retrieve the state of Ethereum and the claimed ship's identity. If this can be verified, then the sponsor chain is retrieved and preparation for the Arvo bootstrap sequence is made.
```
boot: verifying keys
Getting sponsor
boot: retrieving galaxy table
boot: retrieving network domains
boot: retrieving keys for sponsor ~wanzod
boot: retrieving keys for sponsor ~zod
```
- See how a comet is mined in `vere/dawn.c:u3_dawn_come`.
You can see `u3v_wish` present at several places, demonstrating the Arvo `+wish` evaluation arm.
The boot sequence is set up in `vere/pier.c:u3_pier_boot()`, triggered by the king immediately after the `dawn.c` call. There are some runtime boilerplate issues to resolve, such as creating the `/.urb` folder for the event log and the loom. Snapshots are made and replays are checked, &c.
Finally, the king hooks up the bootstrap from the supplied pill (`vere/king.c:_king_boot_ivory` → `noun/serial.c:u3s_cue_xeno`) and starts the main event loop (`uv_run`). `uv_run` is actually a loop handler from `libuv`, not a part of Urbit proper. It provides asynchronous I/O, which makes sense since every event in Urbit either comes from or results in a Unix system call.
Regarding [`libuv`](https://github.com/libuv/libuv):
> libuv's name and logo stand for "Unicorn Velociraptor", where:
> * U or Unicorn is a reference to universal and multi-platform.
> * V or Velociraptor is a reference to velocity and high-performance.
## Pill I {#pill-i}
When you boot a ship, you need all the parts of the boot sequence that are not unique, as well as your private keys and up-to-date information about the PKI, and some entropy etc. The runtime provides some of this information. The pill is then the recipe for the bootstrap sequence. The bootstrap sequence is how you get to an Arvo kernel. Once you have an Arvo kernel, you can compute in the normal event timeline.
A big part of the practical complexity is obtaining identity and keys from Azimuth. You need your own keys of course, but you need the public keys of anyone you need to talk to. So you start with the galaxy table (hard-coded) and can build the sponsorship chain by construction. Then you can get the rest from an Ethereum node.
We also want to avoid booting into an invalid state.
The pill contains:
1. A list of Nock events to create an Arvo kernel.
2. A list of Arvo events to follow once the Arvo kernel has been created.
3. A list of userspace events to follow that setup.
There are three main pill types:
- An [**ivory pill**](https://github.com/urbit/urbit/blob/develop/pkg/arvo/gen/pill/ivory.hoon) is a runtime support pill compiled into the binary. It produces just the `%zuse` core for use by Vere's I/O process. (This prevents needing to redefine certain parts of the Hoon stdlib functionality in Vere.)
```hoon
.ivory/pill +ivory %base
```
- A [**brass pill**](https://github.com/urbit/urbit/blob/develop/pkg/arvo/gen/pill/brass.hoon) is a complete bootstrap sequence including the vanes being recompiled against a target `%base` desk (the first argument).
```hoon
.brass/pill +pill/brass %base
```
> A brass pill is a recipe for a complete bootstrap sequence, starting with a bootstrap Hoon compiler as a Nock formula. It compiles a Hoon compiler from source, then uses it to compile everything else in the kernel. (`~master-morzod`)
For instance, the [developer pill](/blog/dev-pill) is produced as a brass pill.
- A [**solid pill**](https://github.com/urbit/urbit/blob/develop/pkg/arvo/gen/pill/solid.hoon) is a kernel developer expedient, which doesn't recompile the vanes the way a brass pill does.
- A **baby pill** is a minimalist pill, like the one you produced for [*Arvo II: The Boot Sequence*](ca04.md)'s homework. (~wicdev-wisryt walks through the process of creating a baby pill [here](https://www.youtube.com/watch?v=fOVhCx1a-9A).)
## Bootstrapping {#bootstrapping}
> Before we plug the newborn node into the network, we feed it a series of bootstrap or ``larval'' packets that prepare it for adult life as a packet transceiver on the public network. The larval sequence is private, solving the secret delivery problem, and can contain as much code as we like. (Whitepaper)
If Nock is a frozen function from nouns, then we can define an OS. That OS, Arvo, guarantees that the state of your ship is a pure function of the things that have happened to it. The event log is a linked list of events, operated on by what the whitepaper calls a “functional BIOS”: `[2 [0 3] [0 2]]`.
So the formula starts with the first event. What's in the first event? It performs the bootstrap of Arvo itself then loops to take the events off one at a time.
When we boot a ship, the runtime implements this directly using `u3v_boot`, which is given a list and runs the formula from a solid pill.
An `$ovum` is a pair of `wire` (routing data) and `card`. A `$card` is raw event datum, a pair of a `term` tag and an arbitrary noun.
### The First Five Events {#the-first-five-events}
The `+eden` core supplies the first five events to create the event series that will result in Arvo and its lifecycle function.
- Event One, `+aeon`. Start the event loop.
- Event Two, `+boot`. Bootstrap an `arvo` kernel from source.
- Event Three, `+fate`. Produce the Hoon bootstrap compiler.
- Event Four, `+hoon`. Produce the compiler source.
- Event Five, `+arvo`. Produce the kernel source.
#### Event One: `+aeon`
```hoon
++ aeon
^- *
=> *log=[boot=* tale=*]
!=
=+ [arvo epic]=.*(tale.log boot.log)
|- ^- *
?@ epic arvo
%= $
epic +.epic
arvo .*([arvo -.epic] [%9 2 %10 [6 %0 3] %0 2])
==
```
`+aeon` is the first function run on any ship. The gate on the outer edge of Arvo is retrieved, then all of the events are run in a list processing loop, invoking Arvo in each one. This is Hoon code to just produce raw Nock using `!=` zaptis. The `=>` tisgar asserts that we expect the subject (outside the Nock) to look like the first thing in the event log and the rest of the log. This is the first event of the log. The subject that it expects is the rest of the log (which will be evaluated using `[2 [0 3] [0 2]]`.) So `boot.log` is Event Two and `tale.log` is Events Three through Infinity.
This produces `arvo`, the stateless kernel, and `epic`, the rest of the log. The formula in Event Two can take as many events as it needs from the sequence to construct `arvo`, then the incremental process can continue. If `epic` is an atom `~` sig (the null terminator), then `arvo` is ready. Arvo is the result of calling `arvo` on `-.epic`, the next event.
#### Event Two: `+boot`
```hoon
++ boot
^- *
=> *log=[fate=* hoon=@ arvo=@ epic=*]
!=
::
:: activate the compiler gate. the product of this formula
:: is smaller than the formula. so you might think we should
:: save the gate itself rather than the formula producing it.
:: but we have to run the formula at runtime, to register jets.
::
:: as always, we have to use raw nock as we have no type.
:: the gate is in fact ++ride.
::
~> %slog.[0 leaf+"1-b"]
=/ compiler-gate .*(0 fate.log)
::
:: compile the compiler source, producing (pair span nock).
:: the compiler ignores its input so we use a trivial type.
::
~> %slog.[0 leaf+"1-c (compiling compiler, wait a few minutes)"]
=/ compiler-tool
~> %bout
.*([compiler-gate noun/hoon.log] [%9 2 %10 [6 %0 3] %0 2])
::
:: switch to the second-generation compiler. we want to be
:: able to generate matching reflection nouns even if the
:: language changes -- the first-generation formula will
:: generate last-generation spans for `!>`, etc.
::
~> %slog.[0 leaf+"1-d"]
=. compiler-gate ~>(%bout .*(0 +.compiler-tool))
::
:: get the span (type) of the kernel core, which is the context
:: of the compiler gate. we just compiled the compiler,
:: so we know the span (type) of the compiler gate. its
:: context is at tree address `+>` (ie, `+7` or Lisp `cddr`).
:: we use the compiler again to infer this trivial program.
::
~> %slog.[0 leaf+"1-e"]
=/ kernel-span
~> %bout
-:.*([compiler-gate -.compiler-tool '+>'] [%9 2 %10 [6 %0 3] %0 2])
::
:: compile the arvo source against the kernel core.
::
~> %slog.[0 leaf+"1-f"]
=/ kernel-tool
~> %bout
.*([compiler-gate kernel-span arvo.log] [%9 2 %10 [6 %0 3] %0 2])
::
:: create the arvo kernel, whose subject is the kernel core.
::
~> %slog.[0 leaf+"1-g"]
~> %bout
[.*(+>.compiler-gate +.kernel-tool) epic.log]
--
```
The next event noun bootstraps a kernel from its source (`arvo`).
#### Event Three: `+fate`
The next noun (event) is the Hoon bootstrap compiler as source.
Details of this process are supplied in [`/lib/pill`](https://github.com/urbit/urbit/blob/develop/pkg/base-dev/lib/pill.hoon).
#### Event Four: `+hoon`
Next we produce the compiler source.
Details of this process are supplied in [`/lib/pill`](https://github.com/urbit/urbit/blob/develop/pkg/base-dev/lib/pill.hoon).
#### Event Five: `+arvo`
Then we produce the kernel source.
Details of this process are supplied in [`/lib/pill`](https://github.com/urbit/urbit/blob/develop/pkg/base-dev/lib/pill.hoon).
#### `/lib/pill`
- To see how the events are created, let's take a look at the `+brass` arm in `/lib/pill`. This uses vase mode (see e.g. the `swat` which is a delayed `slap` in a trap) to produce the cores and events.
### Lifecycle {#lifecycle}
Once you have all of this, you have completed the lifecycle evaluation of the bootstrap sequence and can run the rest of the event log.
Arvo enters the larval phase during the boot sequence and during certain OTAs. An OTA can just change `%lull`/`%zuse`/a vane, which doesn't touch Arvo; or it can changes `/sys/hoon` or `/sys/arvo`, in which case it needs to handle an Arvo upgrade. From the big picture, we build the new Arvo, compile Hoon and Arvo, gather all persistent and ephemeral state plus any new upgrade state, and hand that to the new Arvo (new world).
The larval core is the outermost core in `/sys/arvo`. When you first bootstrap, the core that the runtime talks to is the larval phase. The larval core is designed to accumulate preconditions and then metamorphose into the adult Arvo. It needs the current time, entropy, the identity, and the standard library.
> Symmetry breaking---the event that defines the identity of the com\-pu\-ter---is exempt from this requirement. Once identity is established, it can't be updated. If you want a new identity, create a new instance. (Whitepaper)
The larval stage was introduced into the boot and upgrade sequence as a way to solve a practical problem in self-reference. If the ship is not known, then what should happen? If you bunt, then everything is ~zod. If you have a `(unit @p)`, then all code using `our` becomes cumbersome. So while identity is injected early into the kernel, it hasn't happened yet. Specifically, it takes place when it acquires identity and entropy and sheds the larval core. This is called “breaking symmetry” because prior to this point every Urbit is identical. (This was not always true, as Joe Bryan notes [in this talk](https://youtu.be/V7XPSvVs5TQ?t=681) at 10:21ff.) The larval stage performs the following steps in order:
- The standard library, `zuse`, is installed.
- Entropy is added
- Identity is added
- Metamorphosis into the next stage of Arvo
```hoon
|%
++ load :: +4
|= hir=heir
?: ?=(%grub -.hir)
~>(%mean.'arvo: larval reboot' !!) :: XX support
(^load hir)
::
++ peek _~ :: +22
++ poke :: +23
|= [now=@da ovo=ovum]
^- ^
~| poke/p.card.ovo
=/ wip
~> %mean.'arvo: bad wisp'
;;(wisp card.ovo)
::
=. ..poke
?- -.wip
%verb ..poke(lac ?~(p.wip !lac u.p.wip))
%wack ..poke(eny `p.wip)
%what ..poke(gub (what gub p.wip))
%whom ..poke(who ~|(%whom-once ?>(?=(~ who) `p.wip)))
::
%wyrd ?. (sane:wyrd kel.p.wip)
~>(%mean.'wyrd: insane' !!)
%- %+ need:wyrd kel.p.wip
^- wynn
:* hoon/hoon-version
arvo/arvo
?~ lul ~
:- lull/;;(@ud q:(slap $:u.lul limb/%lull))
?~ zus ~
[zuse/;;(@ud q:(slap $:u.zus limb/%zuse)) ~]
==
..poke(ver `p.wip)
==
::
:: upgrade once we've accumulated necessary state
::
?~ hir=(molt now gub)
[~ ..poke]
~> %slog.[0 leaf+"arvo: metamorphosis"]
(load u.hir)
::
++ wish :: +10
|= txt=*
q:(slap ?~(zus pit $:u.zus) (ream ;;(@t txt)))
--
```
- `+load`/`+4` passes through to the new world Arvo, because the larval stage is a trivial core wrapped around the mature core.
- `+wish`/`+10` evaluates as normal.
- `+peek`/`+22` produces the type of `~`; i.e., every scry blocks.
- `+poke`/`+23` handles the upgrade-related events. Larval events are actually quite simple:
```hoon
+$ wisp
$% $>(?(%verb %what) waif) :: update from files (event from anywhere)
$>(?(%wack %wyrd) wasp) :: iterate entropy (event from runtime)
[%whom p=ship] :: acquire identity (frozen after boot)
==
```
#### `+le`
`+le` is the Arvo event-loop engine. It provides an `+abet`-pattern-driven core for building worklists.
- `+peek` handles any reads into the larval stage block.
- `+poke` is how you compute an event, as normal.
- `+load` is how Arvo transfers state to a future version of itself.
- `+wish` is of course the `urbit eval` wrapper and generates no events.
See also:
- `+what`, the update engine, which handles a kernel update and continuation from the worklist.
#### Metamorphosis
Metamorphosis means producing the parent core, the mature Arvo. This takes place through `+load`, which hands itself forward.
The larval stage upgrade mechanism is just a pass-through or it crashes.
`+molt` takes care of the process in a practical way by gathering the known system information and packaging it for `+load`.
When bootstrapping is done, the runtime strips off the gate to access the real Arvo core. (This is something of a manual trick.) This is how the structural interface Arvo is accessed, through the hardcoded arm addresses.
- [~master-morzod, “Annotation on the Boot Process”](https://groups.google.com/a/urbit.org/g/dev/c/ESrqJb3Ol54/m/bns0S1QkBAAJ)
- [~master-morzod, ~lagrev-nocfep “Dev Chat: Joe Bryan on the Boot Sequence”](https://www.youtube.com/watch?v=V7XPSvVs5TQ)
### Main Sequence (Mature Arvo) {#main-sequence-mature-arvo}
Once the outer larval core has been shed, the system is back in the Arvo main sequence ([*Arvo II: The Boot Sequence*](ca04.md)).
### Vanes & Userspace {#vanes-userspace}
`%lull` is compiled against `..part`, the first half of Arvo.
## Shutdown {#shutdown}
In a general sense, Urbit is only aware of the world while it lives. But of course on a real machine, the ship will be shut down, migrated, and execute on different runtimes.
- What happens when you run `|exit`? Trace out that process and back into the king for graceful shutdown.
|