@@ -0,0 +1,577 @@
4+aliases = ["/docs/learn/arvo/arvo/"]
8+Arvo, also called Urbit OS, is our operating system.
12+This article is intended to provide a thorough summary of all of the most
13+important aspects of the Arvo kernel and how this functionality gives life to
14+the ambitions of the Urbit platform. We work on two levels: a conceptual level
15+that should be useful to anybody interested in how Arvo works, and a more
16+technical level intended for those that intend to write software for Urbit.
18+The [Urbit white paper](https://media.urbit.org/whitepaper.pdf) is a good
19+companion to this document, and some segments are direct quotes or paraphrases, but it should be noted that some parts of it are now either out of date or not yet implemented.
23+The conceptual section titled [What is Arvo?](#what-is-arvo-) can be understood
24+without knowing Hoon, the Urbit programming language. The technical section
25+titled [The kernel](#the-kernel) will require Chapter One of the [Hoon
26+tutorial](/docs/hoon/hoon-school/) for full understanding, and some
27+material from Chapter Two will be helpful as well. At the bare minimum, we
28+presume that the reader has read through the [Technical
29+Overview](/docs/system-overview/).
31+We also suggest to the reader to peruse the [glossary](/docs/glossary/) before diving into this article. It will provide the initial scaffolding that you will be able to gradually fill in as you read this article and go deeper into the alternate universe of computing that is Urbit.
36+- [What is Arvo?](#what-is-arvo)
37+ * [An operating function](#an-operating-function)
38+ + [Determinism](#determinism)
39+ + [Event log](#event-log)
40+ * [Solid state interpreter](#solid-state-interpreter)
41+ + [Over-the-air updates](#over-the-air-updates)
42+ + [ACID Database](#acid-database)
43+ + [Single-level store](#single-level-store)
44+ + [Non-preemptive](#non-preemptive)
45+- [The kernel](#the-kernel)
46+ * [Overall structure](#overall-structure)
47+ + [Formal interface](#formal-interface)
49+ + [Arvo cores](#arvo-cores)
50+ * [The state](#the-state)
55+Arvo is a [non-preemptive](#non-preemptive)
56+operating system purposefully built to create a new, peer-to-peer internet
57+whereby users own and manage their own data. Despite being an operating system,
58+Arvo does not replace Windows, Mac OS, or Linux. It is better to think of the
59+user experience of Arvo as being closer to that of a web browser despite being a
60+fully fledged OS. As such, Arvo is generally run inside a virtual machine, though in theory it could be run on bare metal.
62+Urbit is a “browser for the server side”; it replaces multiple developer-hosted web services on multiple foreign servers, with multiple self-hosted applications on one personal server. Every architectural decision for Arvo (and indeed, the entire Urbit stack) was made with this singular goal in mind. Throughout this document, we connect the various concepts underlying Arvo with this overarching goal.
64+Arvo is designed to avoid the usual state of complex event networks: event spaghetti. We keep track of every event's cause so that we have a clear causal chain for every computation. At the bottom of every chain is a Unix I/O event, such as a network request, terminal input, file sync, or timer event. We push every step in the path the request takes onto the chain until we get to the terminal cause of the computation. Then we use this causal stack to route results back to the caller.
66+Unlike any other popular operating system, it is possible for a single human to understand every aspect of Arvo due to its compact size. The entire Urbit stack is around 30,000 lines of code, while the Arvo kernel is only about 1,000 lines of code. We strive for a small codebase because the difficulty in administering a system is roughly proportional to the size of its code base.
68+## An operating function
70+Arvo is the world's first _purely functional_ operating system, and as such it may reasonably be called an _operating function_. The importance of understanding this design choice and its relevance to the overarching goal cannot be understated. If you knew only a single thing about Arvo, let it be this.
72+This means two things: one is that the there is a notion of _state_ for the operating system, and that the current state is a pure function of the [event log](#event-log), which is a chronological record of every action the operating system has ever performed. A _pure function_ is a function that always produces the same output given the same input. Another way to put this is to say that Arvo is _deterministic_. Other operating systems are not deterministic for a number of reasons, but one simple reasons is because they allow programs to alter global variables that then affect the operation of other programs.
74+In mathematical terms, one may think of Arvo as being given by a transition function _T_:
77+T: (State, Input) -> (State, Output).
80+In practice, _T_ is implemented by the `+poke` [arm](/docs/glossary/arm/) of the Arvo kernel, which is described in more detail in the [kernel section](#the-kernel). In theoretical terms, it may be more practical to think of Arvo as being defined by a _lifecycle function_ we denote here by _L_:
86+Which perspective is more fruitful depends on the problem being considered.
90+We consider Arvo to be deterministic at a high level. By that we mean that it is
91+stacked on top of a frozen instruction set known as Nock. Frozen instruction
92+sets are a new idea for an operating system, but not for computing in general.
93+For instance, the CPU instruction sets such as
94+[x86-64](https://en.wikipedia.org/wiki/X86-64v) are frozen at the level of the
95+chip. A given operating system may be adapted to run on more than one CPU
96+instruction set, we merely freeze the instruction set at a higher level in order
97+to enable deterministic computation.
99+Arvo handles nondeterminism in an interesting way. Deciding whether or not to
100+halt a computation that could potentially last forever becomes a heuristic
101+decision that is akin to dropping a packet. Thus it behooves one to think of
102+Arvo as being a stateful packet transceiver rather than an ordinary computer - events
103+are never guaranteed to complete, even if one can prove that the computation
104+would eventually terminate. We elaborate on this in the [solid state
105+interpreter](#solid-state-intrepeter) section.
107+Because Arvo is run on a VM, nondeterministic information such as the stack
108+trace of an infinite loop that was entered into may be obtained. This is
109+possible because while Arvo may be unable to obtain that information, the
110+interpreter beneath does and can inject that information back into the event log.
112+Being deterministic at a high level enables many
113+things that are out of reach of any other operating system. For
114+instance, we are able to do [over-the-air](#over-the-air-updates) (OTA) updates,
115+which allows software updates to be implemented across the network without
116+needing to worry whether it won't work on someone's ship, since Arvo is an
117+[interpreter](#solid-state-intrepeter) that can accept source code to
118+update itself instead of requiring a pre-compiled binary. This essential
119+property is why Urbit is able to act as a personal server while having
120+a user experience as accessible as a browser.
124+The formal state of an Arvo instance is an event history, as a linked list of [nouns](/docs/glossary/noun/) 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. After booting, we break symmetry by delivering identity and entropy. The rest of the log is actual input.
126+The Arvo event log is a list of every action ever performed on your ship that
127+lead up to the current state. In principle, this event log is maintained by the
128+[Nock runtime environment](/docs/vere/), but in practice
129+event logs become too long over time to keep, as the event log has a size of
130+O(n) where n is the number of events. Thus it is our intention to
131+implement a feature whereby periodic snapshots of the state of Arvo are taken
132+and the log up to that state is pruned. This is currently unnecessary and thus
133+this feature has not been prioritized.
135+The beginning of the event log starting from the very first time a ship is
136+booted up until the kernel is compiled and identity and entropy are created is a
137+special portion of the Arvo lifecycle known as the _larval stage_. We describe
138+the larval stage in more detail in the [larval stage](#larval-stage-core) section.
140+More information on the structure of the Arvo event log and the Arvo state is given in the section on [the kernel](#the-kernel).
144+## Solid state interpreter
146+Arvo is a _solid state interpreter_. In this section we describe what is meant
147+by this new term, and how this behavior derives from the fact that Arvo is an [ACID database](#acid-database) and a [single-level store](#single-level-store).
149+In computer science, an _interpreter_ is a program that directly executes
150+instructions written in some human-understandable programming or scripting
151+language, rather than requiring the code to first be compiled into a machine
152+language. Arvo is an interpreter, which is important for us since it allows us
153+to perform deterministic [over-the-air updates](#over-the-air-updates) by the
154+direct transfer of raw source code.
156+To understand what we mean by _solid state_ interpreter, consider the operation of a solid state hard drive when a computer shuts down or loses power. Data written to an SSD is permanent unless otherwise deleted - loss of power may leave some partially written data, but nothing is ever lost. Thus, the state of an SDD can be considered to be equivalent to the data that it contains. That is to say, you do not need to know anything about the system which is utilizing the SSD to know everything there is to know about the SSD. There is no notion of "rebooting" a SSD - it simply stores data, and when power is restored to it, it is in exactly the same state as it was when power was lost.
158+Contrast this with other popular operating systems, such as Windows, Mac, or Linux. The state of the operating system is something that crucially depends on having a constant power supply because much of the state of the operating system is stored in RAM, which is volatile. When you reboot your computer or suddenly lose power, any information stored in RAM is lost. Modern operating systems do mitigate this loss of information to some extent. For instance, it may remember what applications you were running at the time power was lost and try to restore them. Particularly durable programs may go as far as writing their state to disk every few seconds so that only very minimal information can be lost in a power outage. However, this is not the default behavior, and indeed if it were then they would be so slow as to be unusable, as you would effectively be using your hard disk as the RAM.
160+How Arvo handles loss of power is closer to that of an SSD. Since it is an [ACID database](#acid-database) and a [single-level store](#single-level-store), a sudden loss of power have no effect on the state of the operating system. When you boot your ship back up it will be exactly as it was before the failure. Your information can never be lost, and because it was designed from the ground up to behave in this fashion, it does not suffer significant slowdown by persisting all data in this manner as would be the case if your typical operating system utilized its hard disk as RAM.
162+Another way to describe a solid state interpreter is to think of it as a
163+stateful packet transceiver. Imagine
164+it as a chip. Plug this chip into power and network; packets go in and
165+out, sometimes changing its state. The chip never loses data and has
166+no concept of a reboot; every packet is an [ACID transaction](#acid-database).
169+### Over-the-air updates
171+Arvo can hotpatch any other semantics at any layer in the system (apps, vanes, Arvo or Hoon itself) with automatic over-the-air updates.
173+Typically, updates to an operating system are given via a pre-compiled binary,
174+which is why some updates will work on some systems but not on others where the
175+hardware and environment may differ. This is not so on Arvo - because it is an
176+[interpreter](#solid-state-interpreter), Arvo may update itself by receiving
177+source code from your sponsor over [Ames](/docs/arvo/ames/ames), our
178+network. As Hoon compiles down to Nock, which is an axiomatic representation of
179+a deterministic computer, this code is guaranteed to run identically on your machine as it
180+would on anybody else's.
182+Some subtleties regarding types arise when handling OTA updates, since they can
183+potentially alter the type system. Put more concretely, the type of `type` may
184+be updated. In that case, the update is an untyped Nock formula from the
185+perspective of the old kernel, but ordinary typed Hoon code from the perspective of
186+the new kernel. Besides this one detail, the only functionality of the Arvo
187+kernel proper that is untyped are its interactions with the Unix runtime.
191+In the client-server model, data is stored on the server and thus reliable and efficient databases are an integral part of server architecture. This is not quite so true for the client - a user may be expected to reboot their machine in the middle of a computation, alter or destroy their data, never make backups or perform version control, etc. In other words, client systems like your personal computer or smart phone are not well suited to act as databases.
193+In order to dismantle the client-server model and build a peer-to-peer internet, we need the robustness of modern database servers in the hands of the users. Thus the Arvo operating system itself must have all of the properties of a reliable database.
195+Database theory studies in precise terms the possible properties of anything that could be considered to be a database. In this context, Arvo has the properties of an [ACID database](https://en.wikipedia.org/wiki/ACID), and the Ames network could be thought of as network of such databases. ACID stands for _atomicity_, _consistency_, _isolation_, and _durability_. We review here how Arvo satisfies these properties.
197+ - Atomicity: Events in Arvo are _atomic_, meaning that they either succeed completely or fail completely. In other words, there are no transient periods in which something like a power failure will leave the operating system in an invalid state. When an event occurs in Arvo, e.g. [the kernel](#the-kernel) is `poke`d, the effects of an event are computed, the event is [persisted](https://en.wikipedia.org/wiki/Persistence_(computer_science)) by writing it to the event log, and only then are the actual effects applied.
199+ - Consistency: Every possible update to the database puts it into another valid state. Given that Arvo is purely functional, this is easier to accomplish than it would be in an imperative setting.
201+ - Isolation: Transactions in databases often happen concurrently, and isolation
202+ ensures that the transactions occur as if they were performed sequentially,
203+ making it so that their effects are isolated from one another. Arvo ensures
204+ this simply by the fact that it only ever performs events sequentially. While
206+ transactions are sequential and performed by the daemon, persistence and effect application are performed
207+ in parallel by the worker; see [worker and
208+ daemon](/docs/vere/) for more detail.
210+ - Durability: Completed transactions will survive permanently. In other words,
211+ since the event log is stored on disk, if power is lost you are guaranteed
212+ that no transactions will be reversed.
214+It is easy to think that "completed transaction will survive permanently"
215+along with "the state of Arvo is pure function of its event log" implies that
216+nothing can ever be deleted. This is not quite true.
217+[Clay](/docs/arvo/clay/clay) is our [referentially
218+transparency](https://en.wikipedia.org/wiki/Referential_transparency)
219+file system, which could naively be thought to mean that since data must be
220+immutable, files cannot be deleted. However, Clay can replace a file with a
221+"tombstone" that causes Clay to crash whenever it is accessed. Referential
222+transparency only guarantees that there won't be new data at a previously
223+accessed location - not that it will still be available.
225+### Single-level store
227+A kernel which presents the abstraction of a single layer of permanent state is also called a _single-level store_. One way to describe a single-level store is that it never reboots; a formal model of the system does not contain an operation which unpredictably erases half its brain.
229+Today's operating systems utilize at least two types of memory: the hard disk and the RAM, and this split is responsible for the fact that data is lost whenever power is lost. Not every operating system in history was designed this way - in particular, [Multics](https://en.wikipedia.org/wiki/Multics) utilized only one store of memory. Arvo takes after Multics - all data is stored in one permanent location, and as a result no data is ever lost when power is lost.
233+Most operating systems are preemptive, meaning that they regularly interrupt
234+tasks being performed with the intention of resuming that task at a later time,
235+without the task explicitly yielding control.
236+Arvo does not do this - tasks run until they are complete or are cancelled due
237+to some heuristic, such as taking too long or because the user pressed Ctrl-C.
239+[non-preemptive](https://en.wikipedia.org/wiki/Cooperative_multitasking) or
240+cooperative multitasking.
243+> Parts of the remainder of this document are out of date as of 2020.07.20, please use information here with
244+> caution. This message will be removed once it is up to date.
249+The Arvo kernel, stored in `sys/arvo.hoon`, is about 1k lines of Hoon whose primary purpose is to implement the transition function, `+poke`. In this section we point out the most important parts of `arvo.hoon` and describe their role in the greater system. We also give brief descriptions of Arvo's kernel modules, known as vanes, and how Arvo interfaces with them.
251+This section requires an understanding of Hoon of at least the level of Chapter One of the [Hoon tutorial](/docs/hoon/hoon-school/).
253+After concluding this section, the reader is encouraged to follow along with the
254+[move trace tutorial](/docs/arvo/tutorials/move-trace),
255+which applies many of the concepts covered below.
259+`arvo.hoon` contains five top level cores as well as a "formal interface" consisting of a single [gate](/docs/glossary/gate/) that implements the transition function. They are nested with the `=<` and `=>` runes like so, where items lower on the list are contained within items higher on the list:
261+ + Section 3bE Arvo Core
262+ + Implementation core
263+ + Structural interface core, or adult core
267+See [Section 1.7](/docs/hoon/hoon-school/arms-and-cores) of the Hoon tutorial for further explanation of what is meant here by "nesting". We now describe the functionality of each of these components.
271+The formal interface is a single gate that takes in the current time and a noun that encodes the input. This input, referred to as an _event_, is then put into action by the `+poke` arm, and a new noun denoting the current [state of Arvo](#the-state) is returned. In reality, you cannot feed the gate just any noun - it will end up being an `ovum` described below - but as this is the outermost interface of the kernel the types defined in the type core are not visible to the formal interface.
274+ :: Arvo formal interface
276+ :: this lifecycle wrapper makes the arvo door (multi-armed core)
277+ :: look like a gate (function or single-armed core), to fit
278+ :: urbit's formal lifecycle function. a practical interpreter
283+ ~> %slog.[0 leaf+"arvo-event"]
284+ .(+> +:(poke now ovo))
289+This core contains the most basic types utilized in Arvo. We discuss a number of them here.
294+++ duct (list wire) :: causal history
297+Arvo is designed to avoid the usual state of complex event networks: event
298+spaghetti. We keep track of every event's cause so that we have a clear causal
299+chain for every computation. At the bottom of every chain is a Unix I/O event,
300+such as a network request, terminal input, file sync, or timer event. We push
301+every step in the path the request takes onto the chain until we get to the
302+terminal cause of the computation. Then we use this causal stack to route
303+results back to the caller.
305+The Arvo causal stack is called a `duct`. This is represented simply as a list of paths, where each path represents a step in the causal chain. The first element in the path is the first letter of whichever vane handled that step in the computation, or the empty span for Unix.
307+Here's a `duct` that was recently observed in the wild upon entering `-time ~s1`
308+into the dojo and pressing Enter, which sets a timer for one second that will
309+then produce a `@d` with the current time after the timer has elapsed:
313+ /g/a/~zod/4_shell_terminal/u/time
314+ /g/a/~zod/shell_terminal/u/child/4/main
315+ /g/a/~zod/terminal/u/txt
321+This is the `duct` that the timer vane, Behn, receives when the `time` sample app asks the Behn to set a timer. This is also the `duct` over which the response is produced at the specified time. Unix sent a terminal keystroke event (enter), and Arvo routed it to Dill (our terminal), which passed it on to the Gall app terminal, which sent it to shell, its child, which created a new child (with process id 4), which on startup asked Behn to set a timer.
323+Behn saves this `duct`, so that when the specified time arrives and Unix sends a
324+wakeup event to the timer vane, it can produce the response on the same `duct`.
325+This response is routed to the place we popped off the top of the `duct`, i.e. the
326+time app. This app returns a `@d` which denotes the current time, which falls down to the shell,
327+which drops it through to the terminal. Terminal drops this down to Dill, which
328+converts it into an effect that Unix will recognize as a request to print the
329+current time to the screen. When Dill produces this, the last path in the `duct` has an
330+initial element of the empty span, so this is routed to Unix, which applies the effects.
332+This is a call stack, with a crucial feature: the stack is a first-class citizen. You can respond over a `duct` zero, one, or many times. You can save `duct`s for later use. There are definitely parallels to Scheme-style continuations, but simpler and with more structure.
338+++ wire path :: event pretext
341+Synonym for `path`, used in `duct`s. These should be thought of as a list of symbols
342+representing a cause.
347+++ move [p=duct q=arvo] :: arvo move
350+If `duct`s are a call stack, then how do we make calls and produce results? Arvo
351+processes `move`s which are a combination of message data and metadata. There
352+are four types of `move`s: `%pass`, `%give`, `%slip`, and `%unix`.
354+A `%pass` `move` is analogous to a call:
357+[duct %pass return-path=path vane-name=@tD data=card]
360+Arvo pushes the return path (preceded by the first letter of the vane name) onto
361+the `duct` and sends the given data, a `card`, to the vane we specified. Any response will come along the same `duct` with the `wire` `return-path`.
363+A `%give` `move` is analogous to a return:
366+[duct %give data=card]
369+Arvo pops the top `wire` off the `duct` and sends the given `card` back to the caller.
371+A `%slip` `move` is a cousin of `%pass`. Any `card` that can be `%pass`ed can also be
372+`%slip`ed, but while a `%pass` says to "push this `wire` onto the `duct` and
373+transfer control to the receiving vane", a `%slip` transfers control to the
374+receiving vane without altering the `duct`. Therefore, a `%give` in response to
375+a `%slip` will go to the caller of the vane that sent the `%slip` rather than
376+the vane that actually sent the `%slip`. `%slip`s are much more rare than
377+`%pass`es and `%give`s. In general, `%slip` and `%pass` `move`s are
378+both referred to as "passes" and it should be clear from the context if one
379+means to refer only to `%pass`es and not `%slip`s or vice versa. Lastly, we note
380+that `%slip` is a code smell and should nearly always be avoided. It can result
381+in unexpected behavior like receiving a gift from a vane you never passed a note to.
383+Lastly, a `%unix` `move` is how Arvo represents communication from Unix, such as a
384+network request or terminal input.
386+#### `card`s and `curd`s
388+`card`s are the vane-specific portion of a `move`, while `curd`s are typeless
389+`card`s utilized at the level of the kernel. `card`s are not actually defined in
390+`arvo.hoon`, rather they are given by `+note-arvo` and `+sign-arvo` in the
391+standard library `zuse`
392+(which then refer to `+task` and `+gift` in each of the vane cores), but they are closely
393+connected to `curd`s so we speak of them in the same breath.
395+Each vane defines a protocol for interacting with other vanes (via Arvo) by defining four types of `card`s: `task`s, `gift`s, `note`s, and `sign`s.
397+When one vane is `%pass`ed a `card` in its `task` (defined in `zuse`), Arvo activates the `+call` gate with the `card` as its argument. To produce a result, the vane `%give`s one of the `card`s defined in its `gift`. If the vane needs to request something of another vane, it `%pass`es it a `note` `card`. When that other vane returns a result, Arvo activates the `+take` gate of the initial vane with one of the `card`s defined in its `sign`.
399+In other words, there are only four ways of seeing a `move`: (1) as a request seen by the caller, which is a `note`. (2) that same request as seen by the callee, a `task`. (3) the response to that first request as seen by the callee, a `gift`. (4) the response to the first request as seen by the caller, a `sign`.
401+When a `task` `card` is `%pass`ed to a vane, Arvo calls its `+call` gate,
402+passing it both the `card` and its `duct`. This gate must be defined in every vane.
403+It produces two things in the following order: a list of `move`s and a possibly
404+modified copy of its context. The `move`s are used to interact with other vanes,
405+while the new context allows the vane to save its state. The next time Arvo
406+activates the vane it will have this context as its subject.
408+This cycle of `%pass`ing a `note` to `%pass`ing a `task` to `%give`ing a `gift`
409+to `%give`ing a `%sign` is summarized in the following diagram:
411+<div style="text-align:center">
412+<img class="mv5 w-150" src="https://media.urbit.org/docs/arvo/cycle.png">
415+Note that `%pass`ing a `note` doesn't _always_ result in a return - this diagram
417+shows the complete cycle. However, `%give`ing a `gift` is always in response to being
418+`%pass`ed some `task`. Since the Arvo kernel acts as a middleman between all `move`s in Arvo, in diagrams we will
419+generally represent the intermediate steps of a vane `%pass`ing a `note` to the kernel addressed to
420+another vane followed by the kernel `%pass`ing a `task` to the
421+addressed vane as a single arrow from one vane to the other to make the diagrams
424+This overview has detailed how to pass a `card` to a particular vane. To see the `card`s each vane can be `%pass`ed as a `task` or return as a `gift` (as well as the semantics tied to them), each vane's public interface is explained in detail in its respective overview.
428+This mold is used to represent both steps and actions.
430+A pair of a `wire` and a `curd`, with a `curd` being like a typeless `card`. The
431+reason for a typeless `card` is that this is the data structure which Arvo uses
432+to communicate with the runtime, and Unix events have no type. Additionally,
433+upgrading the kernel may alter the type system and thus may not be able to be
434+described within the current type system. Then the `wire` here is the default Unix `wire`, namely `//`. In particular, it is not a `duct` because `ovum`s come from the runtime rather than from within Arvo.
438+`arvo.hoon` has four additional cores that encode the functionality of Arvo. The [larval core](#larval-stage-core), [structural interface core](#structural-interface-core), and [implementation core](#implementation-core) each have five arms, called `+come`, `+load`, `+peek`, `+poke`, and `+wish`. Of these five arms, only `+poke` affects the [Arvo state](#the-state), while the rest leave the state invariant. Thus `+poke` is the aforementioned transition function that sends Arvo from one state to the next.
440+A short summary of the purpose of each these arms are as follows:
442+ - `+poke` is the transition function that `move`s Arvo from one state to the
443+ next. It is the most fundamental arm in the entire system. It is a typed
444+ transactional message that is processed at most once. If the `+poke` causes
445+ Arvo to send an message over [Ames](/docs/arvo/ames/ames) Ames
446+ guarantees that the message will be delivered exactly once. This is sometimes said
447+ to be impossible, and it is for standard operating systems, but that is not the case for single-level stores engaged in
448+ a permanent session, as is the case among Arvo ships.
449+ - `+peek` is an arm used for inspecting things outside of the kernel. It grants
450+ read-only access to `scry` Arvo's global referentially transparent namespace.
451+ It takes in a `path` and returns a `unit (unit)`. If the product is `~`, the
452+ path is unknown and its value cannot be produced synchronously. If its
453+ product is `[~ ~]` the `path` is known to be unbound and can never become
454+ bound. Otherwise the product is a `mark` and a noun.
455+ - `+wish` is a function that takes in a core and then parses and compiles it
456+ with the standard library, `zuse`. It is useful from the outside if you ever
457+ want to run code within. One particular way in which it is used is by the
458+ runtime to read out the version of `zuse` so that it knows if it is
459+ compatible with this particular version of the kernel.
460+ - `+load` is used when upgrading the kernel. It is only ever called by Arvo
461+ itself, never by the runtime. If upgrading to a kernel where types are
462+ compatible, `+load` is used, otherwise `+come` is used.
463+ - `+come` is used when the new kernel has incompatible types, but ultimately
464+ reduces to a series of `+load` calls.
466+ The [Section 3bE core](#section-3be-core) does not follow this pattern.
468+#### Section 3bE core
470+This core defines helper functions that are called in the larval and adult cores. These helper functions are placed here for safety so that they do not have access to the entire [state of Arvo](#the-state), which is contained in the structural interface core. One reason this core is required is that the Arvo interface has only five arms and additional arms are required to perform everything the kernel needs to do in a clean manner, so they must be segregated from the other three cores that stick to the five-arm paradigm.
472+#### Implementation core
474+This core is where the real legwork of the Arvo kernel is performed during the adult stage. It does not communicate with Unix directly, rather it is called by the structural interface core.
476+#### Structural interface core
478+This core could be thought of as the primary "adult core" - the one that is in operation for the majority of its lifecycle and the one that contains the [Arvo state](#the-state). This core should be thought of as an interface - that is, the amount of work the code does here is minimal as its main purpose is to be the core that communicates with Unix, and Unix should not be able to access deeper functions stored in the implementation core and 3bE core on its own. Thus, arms in this core are there primarily to call arms in the implementation core and 3bE core.
480+#### Larval stage core
482+This core is in use only during the larval stage of Arvo, which is after the Arvo kernel has compiled itself but before it has "broken symmetry" by acquiring identity and entropy, the point at which the larval stage has concluded. We call this breaking symmetry because prior to this point, every Urbit is completely identical. The larval stage performs the following steps in order:
484+ + The standard library, `zuse`, is installed.
487+ + Metamorph into the next stage of Arvo
489+Once the larval stage has passed its functionality will never be used again.
493+As we follow functional programming paradigms, the state of Arvo is considered
494+to be the entire Arvo kernel core currently in operation (whether it be the larval
495+stage or adult stage). Thus when `+poke` is performed, a new core with the
496+updated state is produced, rather than modifying the existing core as would be
497+expected to happen in an imperative setting.
499+Thus besides the battery of the Arvo core, we have the [payload](/docs/glossary/payload/) which is as
503+:: persistent arvo state
505+=/ pit=vase !>(..is) ::
506+=/ vil=vile (viol p.pit) :: cached reflexives
507+=| $: lac=_& :: laconic bit
509+ our=ship :: identity
511+ vanes=(list [label=@tas =vane]) :: modules
515+Let's investigate the state piece by piece.
518+=/ pit=vase !>(..is) ::
520+This `vase` is part of the state but does not get directly migrated when `+poke`
521+is called. `!>(..is)` consists of the code in `arvo.hoon` written above this core contained in
522+a `vase`. Thus this part of the state changes only when that code changes in an
526+=/ vil=vile (viol p.pit) :: cached reflexives
529+This is a cache of specific types that are of fundamental importance to Arvo -
530+namely `type`s, `duct`s, `path`s, and `vase`s. This is kept because it is
531+unnecessarily wasteful to recompile these fundamental types on a regular basis.
532+Again, this part of the state is never updated directly by `+poke`.
535+=| $: lac=_& :: laconic bit
537+ our=ship :: identity
539+ vanes=(list [label=@tas =vane]) :: modules
542+This is where the real state of the Arvo kernel is kept. `lac` detemines whether
543+Arvo's output is verbose, which can be set using the `|verb` command in the
544+dojo. `eny` is the current entropy. `our` is the ship, which is permanently
545+frozen during the larval stage. `bud` is the standard library. Lastly, `vanes`
546+is of course the list of vanes, which have their own internal states.
548+As you can see, the state of Arvo itself is quite simple. Its primary role is that of
549+a traffic cop, and most of the interesting part of the state lies in `vanes`.
554+The Arvo kernel can do very little on its own. Its functionality is extended in a careful and controlled way with vanes, also known as kernel modules.
556+As described above, we use Arvo proper to route and control the flow of `move`s.
557+However, Arvo proper is rarely directly responsible for processing the event
558+data that directly causes the desired outcome of a `move`. This event data is contained within a `card`. Instead, Arvo proper passes the `card` off to one of its vanes, which each present an interface to clients for a particular well-defined, stable, and general-purpose piece of functionality.
560+As of this writing, we have nine vanes, which each provide the following services:
562+- [Ames](/docs/arvo/ames/ames): the name of both our network and the vane that communicates over it.
563+- [Behn](/docs/arvo/behn/behn): a simple timer.
564+- [Clay](/docs/arvo/clay/clay): our version-controlled, referentially- transparent, and global filesystem.
565+- [Dill](/docs/arvo/dill/dill): a terminal driver. Unix sends keyboard events to `%dill` from the console, and `%dill` produces terminal output.
566+- [Eyre](/docs/arvo/eyre/eyre): an http server. Unix sends http messages to `%eyre`, and `%eyre` produces http messages in response.
567+- [Ford](/docs/arvo/ford/ford): a build system also utilized for marks
568+ (file types) and debugging.
569+- [Gall](/docs/userspace/gall/gall): manages our userspace applications. `%gall` keeps state and manages subscribers.
570+- `Iris`: an http client.
571+- `Jael`: storage for Azimuth information.
573+#### Applying your knowledge
575+Now that you've learned about the nuts and bolts of the Arvo kernel, why not
576+check it out in action? An in-depth "move trace" tutorial for running a timer app
577+is available [here](/docs/arvo/tutorials/move-trace).