on master help sign in
first reorg
commit3e0b55a777bc8f846dc89dd8bd8dd51baa031572 authorGalen Wolfe-Pauly <root@office-for.com> dateFri 12 Feb 2016, 12:32 (11 years ago) parentbdfaba4
224 files changed+8154−4558
docs.md+6−18 docs/cookbooks.md+9 docs/dev/hoon/leap-in/basic.md → docs/cookbooks/basic.md docs/dev/hoon/leap-in/generators.md → docs/cookbooks/generators.md docs/dev/hoon/leap-in/http.md → docs/cookbooks/http.md docs/dev/hoon/leap-in/marks.md → docs/cookbooks/marks.md docs/dev/hoon/leap-in/network.md → docs/cookbooks/network.md docs/dev/hoon/leap-in/state.md → docs/cookbooks/state.md docs/dev/hoon/leap-in/subscriptions.md → docs/cookbooks/subscriptions.md docs/dev/hoon/leap-in/web-apps.md → docs/cookbooks/web-apps.md docs/deep-dives.md+9 docs/deep-dives/principles.md+3 docs/dev/hoon/principles/0-nouns.md → docs/deep-dives/principles/0-nouns.md docs/dev/hoon/principles/1-twigs.md → docs/deep-dives/principles/1-twigs.md docs/dev/hoon/principles/2-syntax.md → docs/deep-dives/principles/2-syntax.md docs/dev/hoon/principles/3-program.md → docs/deep-dives/principles/3-program.md docs/dev/hoon/principles/4-functions.md → docs/deep-dives/principles/4-functions.md docs/dev/nock/tutorial.md → docs/deep-dives/tutorial.md+3−3 docs/dev.md−28 docs/dev/arvo.md−13 docs/dev/client.md−11 docs/dev/client/tree.md−59 docs/dev/contributing.md−213 docs/dev/hoon.md−24 docs/dev/hoon/leap-in.md−8 docs/dev/hoon/principles.md−18 docs/dev/hoon/runes/index.hook−13 docs/dev/interpreter.md−12 docs/dev/nock.md−52 docs/orientation.md+9 docs/orientation/repo-guide.md+106 docs/orientation/system-overview.md+63 docs/user/intro.md → docs/orientation/what-is-urbit.md+2−2 docs/setup.md+9 docs/user/basic.md → docs/setup/getting-started.md+3−3 docs/user/install.md → docs/setup/install.md+1−1 docs/system.md+9 docs/system/arvo/ames.md+29 docs/system/arvo/ames/commentary.md+1815 docs/system/arvo/arvo.md+8 docs/system/arvo/arvo/commentary.md+4 docs/system/arvo/clay.md+27 docs/system/arvo/clay/architecture.md+415 docs/system/arvo/clay/commentary.md+2007 docs/system/arvo/dill.md+27 docs/system/arvo/dill/commentary.md+5 docs/system/arvo/eyre.md+63 docs/system/arvo/eyre/commentary.md+273 docs/system/arvo/ford.md+128 docs/system/arvo/ford/commentary.md+2571 docs/system/arvo/gall.md+161 docs/system/arvo/gall/gall.md+5 docs/system/arvo/time.md+21 docs/system/arvo/util.md+344 docs/dev/hoon/reference/cheat-sheet.md → docs/system/hoon/cheat-sheets/hoon.md docs/dev/hoon/reference/odors.md → docs/system/hoon/cheat-sheets/odors.md docs/dev/hoon/reference/pronunciation.md → docs/system/hoon/cheat-sheets/pronunciation.md docs/dev/hoon/reference.md → docs/system/hoon/cheet-sheets.md docs/dev/hoon/library.md → docs/system/hoon/library.md docs/dev/hoon/library/0.md → docs/system/hoon/library/0.md docs/dev/hoon/library/1.md → docs/system/hoon/library/1.md docs/dev/hoon/library/2a.md → docs/system/hoon/library/2a.md docs/dev/hoon/library/2b.md → docs/system/hoon/library/2b.md docs/dev/hoon/library/2c.md → docs/system/hoon/library/2c.md docs/dev/hoon/library/2da.md → docs/system/hoon/library/2da.md docs/dev/hoon/library/2db.md → docs/system/hoon/library/2db.md docs/dev/hoon/library/2dc.md → docs/system/hoon/library/2dc.md docs/dev/hoon/library/2dd.md → docs/system/hoon/library/2dd.md docs/dev/hoon/library/2ea.md → docs/system/hoon/library/2ea.md docs/dev/hoon/library/2eb.md → docs/system/hoon/library/2eb.md docs/dev/hoon/library/2ec.md → docs/system/hoon/library/2ec.md docs/dev/hoon/library/2ed.md → docs/system/hoon/library/2ed.md docs/dev/hoon/library/2ee.md → docs/system/hoon/library/2ee.md docs/dev/hoon/library/2ef.md → docs/system/hoon/library/2ef.md docs/dev/hoon/library/2eg.md → docs/system/hoon/library/2eg.md docs/dev/hoon/library/2eh.md → docs/system/hoon/library/2eh.md docs/dev/hoon/library/2ei.md → docs/system/hoon/library/2ei.md docs/dev/hoon/library/2ej.md → docs/system/hoon/library/2ej.md docs/dev/hoon/library/2ek.md → docs/system/hoon/library/2ek.md docs/dev/hoon/library/2el.md → docs/system/hoon/library/2el.md docs/dev/hoon/library/2em.md → docs/system/hoon/library/2em.md docs/dev/hoon/library/2en.md → docs/system/hoon/library/2en.md docs/dev/hoon/library/2eo.md → docs/system/hoon/library/2eo.md docs/dev/hoon/library/2ep.md → docs/system/hoon/library/2ep.md docs/dev/hoon/library/2ew.md → docs/system/hoon/library/2ew.md docs/dev/hoon/library/2ex.md → docs/system/hoon/library/2ex.md docs/dev/hoon/library/2ey.md → docs/system/hoon/library/2ey.md docs/dev/hoon/library/2ez.md → docs/system/hoon/library/2ez.md docs/dev/hoon/library/3ba.md → docs/system/hoon/library/3ba.md docs/dev/hoon/library/3bb.md → docs/system/hoon/library/3bb.md docs/dev/hoon/library/3bc.md → docs/system/hoon/library/3bc.md docs/dev/hoon/library/3bd.md → docs/system/hoon/library/3bd.md docs/dev/hoon/library/3be.md → docs/system/hoon/library/3be.md docs/dev/hoon/library/3bf.md → docs/system/hoon/library/3bf.md docs/dev/hoon/library/3bg.md → docs/system/hoon/library/3bg.md docs/dev/hoon/library/3bh.md → docs/system/hoon/library/3bh.md docs/dev/hoon/library/3bi.md → docs/system/hoon/library/3bi.md docs/dev/hoon/runes.md → docs/system/hoon/runes.md docs/dev/hoon/runes/bc/bcbr.md → docs/system/hoon/runes/bc/bcbr.md docs/dev/hoon/runes/bc/bccb.md → docs/system/hoon/runes/bc/bccb.md docs/dev/hoon/runes/bc/bccl.md → docs/system/hoon/runes/bc/bccl.md docs/dev/hoon/runes/bc/bccn.md → docs/system/hoon/runes/bc/bccn.md docs/dev/hoon/runes/bc/bcls.md → docs/system/hoon/runes/bc/bcls.md docs/dev/hoon/runes/bc/bcpm.md → docs/system/hoon/runes/bc/bcpm.md docs/dev/hoon/runes/bc/bctr.md → docs/system/hoon/runes/bc/bctr.md docs/dev/hoon/runes/bc/bcts.md → docs/system/hoon/runes/bc/bcts.md docs/dev/hoon/runes/bc/bcwt.md → docs/system/hoon/runes/bc/bcwt.md docs/dev/hoon/runes/br/brcb.md → docs/system/hoon/runes/br/brcb.md docs/dev/hoon/runes/br/brcn.md → docs/system/hoon/runes/br/brcn.md docs/dev/hoon/runes/br/brdt.md → docs/system/hoon/runes/br/brdt.md docs/dev/hoon/runes/br/brfs.md → docs/system/hoon/runes/br/brfs.md docs/dev/hoon/runes/br/brhp.md → docs/system/hoon/runes/br/brhp.md docs/dev/hoon/runes/br/brkt.md → docs/system/hoon/runes/br/brkt.md docs/dev/hoon/runes/br/brls.md → docs/system/hoon/runes/br/brls.md docs/dev/hoon/runes/br/brtr.md → docs/system/hoon/runes/br/brtr.md docs/dev/hoon/runes/br/brts.md → docs/system/hoon/runes/br/brts.md docs/dev/hoon/runes/br/brwt.md → docs/system/hoon/runes/br/brwt.md docs/dev/hoon/runes/cl/clcb.md → docs/system/hoon/runes/cl/clcb.md docs/dev/hoon/runes/cl/clfs.md → docs/system/hoon/runes/cl/clfs.md docs/dev/hoon/runes/cl/clhp.md → docs/system/hoon/runes/cl/clhp.md docs/dev/hoon/runes/cl/clkt.md → docs/system/hoon/runes/cl/clkt.md docs/dev/hoon/runes/cl/clls.md → docs/system/hoon/runes/cl/clls.md docs/dev/hoon/runes/cl/clsg.md → docs/system/hoon/runes/cl/clsg.md docs/dev/hoon/runes/cl/cltr.md → docs/system/hoon/runes/cl/cltr.md docs/dev/hoon/runes/cn/cncb.md → docs/system/hoon/runes/cn/cncb.md docs/dev/hoon/runes/cn/cndt.md → docs/system/hoon/runes/cn/cndt.md docs/dev/hoon/runes/cn/cnhp.md → docs/system/hoon/runes/cn/cnhp.md docs/dev/hoon/runes/cn/cnkt.md → docs/system/hoon/runes/cn/cnkt.md docs/dev/hoon/runes/cn/cnls.md → docs/system/hoon/runes/cn/cnls.md docs/dev/hoon/runes/cn/cnsg.md → docs/system/hoon/runes/cn/cnsg.md docs/dev/hoon/runes/cn/cntr.md → docs/system/hoon/runes/cn/cntr.md docs/dev/hoon/runes/cn/cnts.md → docs/system/hoon/runes/cn/cnts.md docs/dev/hoon/runes/dt/dtkt.md → docs/system/hoon/runes/dt/dtkt.md docs/dev/hoon/runes/dt/dtls.md → docs/system/hoon/runes/dt/dtls.md docs/dev/hoon/runes/dt/dttr.md → docs/system/hoon/runes/dt/dttr.md docs/dev/hoon/runes/dt/dtts.md → docs/system/hoon/runes/dt/dtts.md docs/dev/hoon/runes/dt/dtwt.md → docs/system/hoon/runes/dt/dtwt.md docs/dev/hoon/runes/dt/dtzy.md → docs/system/hoon/runes/dt/dtzy.md docs/dev/hoon/runes/dt/dtzz.md → docs/system/hoon/runes/dt/dtzz.md docs/dev/hoon/runes/hx/hxgl.md → docs/system/hoon/runes/hx/hxgl.md docs/dev/hoon/runes/hx/hxgr.md → docs/system/hoon/runes/hx/hxgr.md docs/dev/hoon/runes/kt/ktbr.md → docs/system/hoon/runes/kt/ktbr.md docs/dev/hoon/runes/kt/ktdt.md → docs/system/hoon/runes/kt/ktdt.md docs/dev/hoon/runes/kt/kthp.md → docs/system/hoon/runes/kt/kthp.md docs/dev/hoon/runes/kt/ktls.md → docs/system/hoon/runes/kt/ktls.md docs/dev/hoon/runes/kt/ktpm.md → docs/system/hoon/runes/kt/ktpm.md docs/dev/hoon/runes/kt/ktsg.md → docs/system/hoon/runes/kt/ktsg.md docs/dev/hoon/runes/kt/ktts.md → docs/system/hoon/runes/kt/ktts.md docs/dev/hoon/runes/kt/ktwt.md → docs/system/hoon/runes/kt/ktwt.md docs/dev/hoon/runes/sg/sgbc.md → docs/system/hoon/runes/sg/sgbc.md docs/dev/hoon/runes/sg/sgbr.md → docs/system/hoon/runes/sg/sgbr.md docs/dev/hoon/runes/sg/sgcb.md → docs/system/hoon/runes/sg/sgcb.md docs/dev/hoon/runes/sg/sgcn.md → docs/system/hoon/runes/sg/sgcn.md docs/dev/hoon/runes/sg/sgfs.md → docs/system/hoon/runes/sg/sgfs.md docs/dev/hoon/runes/sg/sggl.md → docs/system/hoon/runes/sg/sggl.md docs/dev/hoon/runes/sg/sggr.md → docs/system/hoon/runes/sg/sggr.md docs/dev/hoon/runes/sg/sgls.md → docs/system/hoon/runes/sg/sgls.md docs/dev/hoon/runes/sg/sgpm.md → docs/system/hoon/runes/sg/sgpm.md docs/dev/hoon/runes/sg/sgts.md → docs/system/hoon/runes/sg/sgts.md docs/dev/hoon/runes/sg/sgwt.md → docs/system/hoon/runes/sg/sgwt.md docs/dev/hoon/runes/sg/sgzp.md → docs/system/hoon/runes/sg/sgzp.md docs/dev/hoon/runes/sm.md → docs/system/hoon/runes/sm.md docs/dev/hoon/runes/sm/smcl.md → docs/system/hoon/runes/sm/smcl.md docs/dev/hoon/runes/sm/smcn.md → docs/system/hoon/runes/sm/smcn.md docs/dev/hoon/runes/sm/smdq.md → docs/system/hoon/runes/sm/smdq.md docs/dev/hoon/runes/sm/smhp.md → docs/system/hoon/runes/sm/smhp.md docs/dev/hoon/runes/sm/smls.md → docs/system/hoon/runes/sm/smls.md docs/dev/hoon/runes/sm/smsg.md → docs/system/hoon/runes/sm/smsg.md docs/dev/hoon/runes/sm/smsm.md → docs/system/hoon/runes/sm/smsm.md docs/dev/hoon/runes/sm/smtr.md → docs/system/hoon/runes/sm/smtr.md docs/dev/hoon/runes/sm/smzz.md → docs/system/hoon/runes/sm/smzz.md docs/dev/hoon/runes/ts/tsbr.md → docs/system/hoon/runes/ts/tsbr.md docs/dev/hoon/runes/ts/tscl.md → docs/system/hoon/runes/ts/tscl.md docs/dev/hoon/runes/ts/tsdt.md → docs/system/hoon/runes/ts/tsdt.md docs/dev/hoon/runes/ts/tsgl.md → docs/system/hoon/runes/ts/tsgl.md docs/dev/hoon/runes/ts/tsgr.md → docs/system/hoon/runes/ts/tsgr.md docs/dev/hoon/runes/ts/tshp.md → docs/system/hoon/runes/ts/tshp.md docs/dev/hoon/runes/ts/tskt.md → docs/system/hoon/runes/ts/tskt.md docs/dev/hoon/runes/ts/tsls.md → docs/system/hoon/runes/ts/tsls.md docs/dev/hoon/runes/ts/tssg.md → docs/system/hoon/runes/ts/tssg.md docs/dev/hoon/runes/ts/tstr.md → docs/system/hoon/runes/ts/tstr.md docs/dev/hoon/runes/wt/wtbr.md → docs/system/hoon/runes/wt/wtbr.md docs/dev/hoon/runes/wt/wtcl.md → docs/system/hoon/runes/wt/wtcl.md docs/dev/hoon/runes/wt/wtdt.md → docs/system/hoon/runes/wt/wtdt.md docs/dev/hoon/runes/wt/wtgl.md → docs/system/hoon/runes/wt/wtgl.md docs/dev/hoon/runes/wt/wtgr.md → docs/system/hoon/runes/wt/wtgr.md docs/dev/hoon/runes/wt/wthp.md → docs/system/hoon/runes/wt/wthp.md docs/dev/hoon/runes/wt/wthz.md → docs/system/hoon/runes/wt/wthz.md docs/dev/hoon/runes/wt/wtkt.md → docs/system/hoon/runes/wt/wtkt.md docs/dev/hoon/runes/wt/wtkz.md → docs/system/hoon/runes/wt/wtkz.md docs/dev/hoon/runes/wt/wtls.md → docs/system/hoon/runes/wt/wtls.md docs/dev/hoon/runes/wt/wtlz.md → docs/system/hoon/runes/wt/wtlz.md docs/dev/hoon/runes/wt/wtpm.md → docs/system/hoon/runes/wt/wtpm.md docs/dev/hoon/runes/wt/wtpt.md → docs/system/hoon/runes/wt/wtpt.md docs/dev/hoon/runes/wt/wtpz.md → docs/system/hoon/runes/wt/wtpz.md docs/dev/hoon/runes/wt/wtsg.md → docs/system/hoon/runes/wt/wtsg.md docs/dev/hoon/runes/wt/wtsz.md → docs/system/hoon/runes/wt/wtsz.md docs/dev/hoon/runes/wt/wtts.md → docs/system/hoon/runes/wt/wtts.md docs/dev/hoon/runes/wt/wttz.md → docs/system/hoon/runes/wt/wttz.md docs/dev/hoon/runes/wt/wtzp.md → docs/system/hoon/runes/wt/wtzp.md docs/dev/hoon/runes/zp/zpcb.md → docs/system/hoon/runes/zp/zpcb.md docs/dev/hoon/runes/zp/zpcm.md → docs/system/hoon/runes/zp/zpcm.md docs/dev/hoon/runes/zp/zpfs.md → docs/system/hoon/runes/zp/zpfs.md docs/dev/hoon/runes/zp/zpgr.md → docs/system/hoon/runes/zp/zpgr.md docs/dev/hoon/runes/zp/zpsm.md → docs/system/hoon/runes/zp/zpsm.md docs/dev/hoon/runes/zp/zpts.md → docs/system/hoon/runes/zp/zpts.md docs/dev/hoon/runes/zp/zpwt.md → docs/system/hoon/runes/zp/zpwt.md docs/dev/hoon/runes/zp/zpzp.md → docs/system/hoon/runes/zp/zpzp.md docs/dev/interpreter/u3.md → docs/system/interpreter/u3.md docs/dev/nock/reference.md → docs/system/nock/reference.md docs/theory.md−26 docs/theory/network-goals.md−565 docs/theory/old.md−21 docs/theory/part-i.md−512 docs/theory/part-ii.md−462 docs/theory/whitepaper.md−2347 docs/user.md−25 docs/user/launch.md−112 docs/walkthroughs.md+9 docs/user/appliance.md → docs/walkthroughs/appliance.md+3−3 docs/user/clay.md → docs/walkthroughs/clay.md+2−2 docs/user/dojo.md → docs/walkthroughs/dojo.md+1−1 docs/user/talk.md → docs/walkthroughs/talk.md+1−1 docs/user/tour.md → docs/walkthroughs/tour.md+3−3
docs.md+6−18
@@ -1,24 +1,12 @@
11---
22anchor: none
3−layout: no-anchor
4−logo: black
53---
64
7−<div class="short">
8−
9−# Urbit documentation
10−
11−The Urbit doc is divided into three parts: [user doc](docs/user),
12−[developer doc](docs/dev), and [theory](docs/theory) (whitepaper, essays,
13−videos, etc).
14−
15−If you want to try Urbit, start with the user doc. If you want
16−to learn about Urbit, try the theory. Or just start with the
17−user doc; it doesn't assume any prior knowledge.
18−
19−The most fun thing to do with Urbit is code, but the developer
20−doc remains under construction. Sorry. We'll have more soon.
21−
22−<list dataSort="true"></list>
5+<div class="lead">
6+ <div class="logo inverse blue">~</div>
7+ <h1 class="blue i-b">Urbit documentation</h1>
8+</div>
239
10+<div class="sections col-md-offset-2">
11+ <kids></kids>
2412</div>
docs/cookbooks.mdnew file+9
@@ -0,0 +1,9 @@
1+---
2+sort: 5
3+---
4+
5+# Cookbooks
6+
7+Short, example-based tutorials of specific features.
8+
9+<list dataPath="docs/cookbooks"></list>
docs/dev/hoon/leap-in/basic.md → docs/cookbooks/basic.mdrenamed

The content is the same.

docs/dev/hoon/leap-in/generators.md → docs/cookbooks/generators.mdrenamed

The content is the same.

docs/dev/hoon/leap-in/http.md → docs/cookbooks/http.mdrenamed

The content is the same.

docs/dev/hoon/leap-in/marks.md → docs/cookbooks/marks.mdrenamed

The content is the same.

docs/dev/hoon/leap-in/network.md → docs/cookbooks/network.mdrenamed

The content is the same.

docs/dev/hoon/leap-in/state.md → docs/cookbooks/state.mdrenamed

The content is the same.

docs/dev/hoon/leap-in/subscriptions.md → docs/cookbooks/subscriptions.mdrenamed

The content is the same.

docs/dev/hoon/leap-in/web-apps.md → docs/cookbooks/web-apps.mdrenamed

The content is the same.

docs/deep-dives.mdnew file+9
@@ -0,0 +1,9 @@
1+---
2+sort: 4
3+---
4+
5+# Deep dives
6+
7+Bottom-up tutorials of how our language and VM work.
8+
9+<list dataPath="docs/deep-dives"></list>
docs/deep-dives/principles.mdnew file+3
@@ -0,0 +1,3 @@
1+# Principles of Hoon
2+
3+<list></list>
docs/dev/hoon/principles/0-nouns.md → docs/deep-dives/principles/0-nouns.mdrenamed

The content is the same.

docs/dev/hoon/principles/1-twigs.md → docs/deep-dives/principles/1-twigs.mdrenamed

The content is the same.

docs/dev/hoon/principles/2-syntax.md → docs/deep-dives/principles/2-syntax.mdrenamed

The content is the same.

docs/dev/hoon/principles/3-program.md → docs/deep-dives/principles/3-program.mdrenamed

The content is the same.

docs/dev/hoon/principles/4-functions.md → docs/deep-dives/principles/4-functions.mdrenamed

The content is the same.

docs/dev/nock/tutorial.md → docs/deep-dives/tutorial.mdrenamed+3−3
@@ -1,9 +1,9 @@
11---
2−layout: post
3−category: doc
4−title: Chapter 2 &#58; Crash course in Nock
2+title: Nock tutorial
53---
64
5+# Nock tutorial
6+
77So let's learn Nock! But wait - why learn Nock? After all,
88we're going to be programming in Hoon, not Nock.
99
docs/dev.mddeleted−28
@@ -1,28 +0,0 @@
1−---
2−logo: black
3−sort: 2
4−title: Developer doc
5−---
6−<div class="short">
7−
8−# Developer documentation
9−
10−Urbit has three programming layers: [Nock](dev/nock) (combinator nano-VM),
11−[Hoon](dev/hoon) (strict functional language), and [Arvo](dev/arvo) (functional
12−OS).
13−
14−To code in Urbit, the least you need to learn is Hoon, plus a
15−little bit of Arvo. Nock is a sort of functional assembly
16−language -- you don't need to know it, but it's useful to.
17−Nock is also the easiest thing in the world to learn.
18−
19−You can program for Arvo without knowing much about Arvo
20−internals, but again it helps. But you need to know Hoon.
21−Don't worry, it's easier than it looks.
22−
23−Alas, the developer doc is still under construction. We'll have
24−more soon.
25−
26−<list></list>
27−
28−</div>
docs/dev/arvo.mddeleted−13
@@ -1,13 +0,0 @@
1−---
2−logo: black
3−sort: 3
4−title: Arvo
5−---
6−<div class="short">
7−
8−# Arvo
9−
10−Arvo is a functional operating system. But hopefully you knew that! Sorry,
11−please watch this space for actual documentation.
12−
13−</div>
docs/dev/client.mddeleted−11
@@ -1,11 +0,0 @@
1−---
2−hide: true
3−logo: black
4−sort: 4
5−title: Frontend tools
6−---
7−
8−Frontend tools
9−==============
10−
11−<list></list>
docs/dev/client/tree.mddeleted−59
@@ -1,59 +0,0 @@
1−# `:tree`
2−
3−`:tree` is the web filesystem interface. Odds are this file has been rendered for you by `:tree`.
4−
5−`:tree` is a single-page app that uses a backend in `/home/tree` to load
6−contents from `%clay` as the user navigates around as `%json`. The frontend
7−lives in `/home/pub/tree` and is a fairly straightforward
8−[React](https://facebook.github.io/react/) /
9−[Flux](https://facebook.github.io/flux/) app.
10−
11−## Frontend
12−
13−The frontend code for `:tree` can be found in `/home/pub/tree/src/`.
14−
15−### CSS
16−
17−The CSS is written in [Stylus](https://learnboost.github.io/stylus/). The main entry point is `main.styl` and can be compiled with `stylus main.styl` which should output a `main.css`
18−
19−### JS
20−
21−The JS is written in [CoffeeScript](http://coffeescript.org/) and packaged with
22−[Browserify](http://browserify.org/). The main entry point is `main.coffee` and
23−is compiled with `browserify -t coffeeify main.coffee > main.js`. You'll need
24−to `npm install` first.
25−
26−Each page is loaded as JSON and then rendered using React on the page. This
27−allows us to write JSX in our markdown to implement simple components. Check
28−out `/home/pub/tree/src/js/components` to see the component library.
29−
30−You'll notice that some of these doc pages use things like `<list>` in the raw markdown files.
31−
32−## JSON API
33−Async provides loading by schema
34−
35−`{path name sein sibs next prev}` are all immediately accesible from the store
36−
37−a `getPath` method, if present (defaulting to current url), is used to determine the query root node.
38−
39−## JSON Internals
40−
41−### `/[desk]/tree/{path}.json`
42−`tree/json.hook` accepts a query string schema `q` in light noun encoding
43−
44− ++ schema (dict ,[term $|(mark schema)])
45− ++ dict |*(a=_,* $&([a (dict a)] a))
46−
47−which is normalized and type-checked to a `query` list of
48−- `[%kids query]`, the only recursive value, which executes for all subpaths
49− XX descent is only currently supported to a single level as a performance optimization
50−- `[%name %t]`, the node name
51−- `[%path %t]`, the current path
52−- `[%snip %r]`, a snippet, extracted via `react-snip-json`
53−- `[%head %r]`, the first `<h1/>`, extracted via `react-head-json`
54−- `[%body %r]`, the `react-json` body
55−- `[%meta %j]`, json frontmatter per the `mdy` mark definition
56−
57−The request types above are `%t` text, `%r` html-derived tree, and `%j`
58−arbitrary json; an example query, used by the main content renderer, is
59−`"q=body.r__kids_name.t"` (`body:'r' kids:{name:'t'}` )
docs/dev/contributing.mddeleted−213
@@ -1,213 +0,0 @@
1−---
2−sort: 6
3−title: Contributing
4−---
5−
6−# Contributing to urbit
7−
8−Thank you for your interest in contributing to urbit.
9−
10−## Development practice
11−
12−You may have an identity on the live network, but doing all your
13−development on the live network would be cumbersome and unnecessary.
14−Standard practice in urbit development is to work on a fake `~zod`. A
15−fake `~zod` will get its initial files from the `urb/zod/` directory
16−rather than trying to sync them over the network, which is invaluable
17−for working in Hoon. Also, a fake `~zod` or any fake urbit instances you
18−start do not talk to the live network, but to a fake network that exists
19−only on your computer.
20−
21−To start a fake `~zod`, the command is:
22−
23− bin/urbit -F -I zod -c [pier directory]
24−
25−To resume one that was already created, just as on the live network,
26−remove `-c` (but leave the rest of the options there). `-F` uses the
27−fake network, and `-I` starts an "imperial" instance - that is, an 8-bit
28−galaxy.
29−
30−## Kernel development
31−
32−Working on either C or non-kernel Hoon should not bring any surprises,
33−but the Hoon kernel (anything under `urb/zod/arvo/`) is bootstrapped
34−from `urbit.pill` in `urb/`, and must be manually recompiled if any
35−changes are made. The command to manually recompile the kernel and
36−install the new kernel is `|reset` in `dojo`. This rebuilds from the
37−`arvo` directory in the `home` desk in `%clay`. Currently, `|reset`
38−does not reload apps like `dojo` itself, which will still reference the
39−old kernel. To force them to reload, make a trivial edit to their main
40−source file (under the `ape` directory) in `%clay`.
41−
42−If you do any kernel development, be sure to read the section below about
43−pills.
44−
45−## Git practice
46−
47−Since we use the GitHub issue tracker, it is helpful to contribute via a
48−GitHub pull request. If you already know what you are doing, skip down
49−to the Style section.
50−
51−Start by cloning the repository on your work machine:
52−
53− git clone https://github.com/urbit/urbit
54−
55−And, additionally, fork the repository on GitHub by clicking the "Fork"
56−button. Add your fork as a remote:
57−
58− git remote add [username] https://github.com/[username]/urbit
59−
60−and set it as the default remote to push to:
61−
62− git config --local remote.pushDefault [username]
63−
64−This is good practice for any project that uses git. You will pull
65−upstream branches from urbit/urbit and push to your personal urbit fork
66−by default.
67−
68−Next, check out `test`, which is the mainline development branch, and
69−base a new branch on it to do your work on:
70−
71− git checkout test
72− git checkout -b [branch name]
73−
74−Now you are free to do your work on this branch. When finished, you may
75−want to clean up your commits:
76−
77− git rebase -i test
78−
79−Then you can push to your public fork with `git push` and make a pull
80−request via the GitHub UI. Make sure you request to merge your branch
81−into `test`, not `master`.
82−
83−After your changes are merged upstream, you can delete your branch (via
84−github UI or `git push :[branch]` remotely, and with `git branch -d`
85−locally).
86−
87−## Style
88−
89−The urbit project uses two-space indentation and avoids tab characters.
90−In C code, it should not be too difficult to mimic the style of the code
91−around you, which is just fairly standard K&R with braces on every
92−compound statement. One thing to watch out for is top-level sections in
93−source files that are denoted by comments and are actually indented one
94−level.
95−
96−Hoon will be a less familiar language to many contributors. Some of our
97−less obvious stylistic rules are:
98−
99−- Keep your source files 80 characters or less wide. Many urbit
100− developers use 80 character terminals/tmux panes/&c.
101−- Tab characters are actually a syntax error, so be extra sure your
102− editor is not inserting any. Trailing whitespace is *usually* not a
103− syntax error, but avoiding it is encouraged.
104−- The kernel convention is that line comments start at column 57 with
105− the `::` followed by 2 spaces. This leaves 20 characters for the
106− comment. Outside the kernel, things are less strict.
107−- Tall arms within a core are conventionally separated by empty comments
108− (just `::`) at the same indentation level as the initial `++` or `+-`.
109− The last arm in a core is not followed by an empty comment, because it
110− is visually closed by the `--` that closes the core. The empty comment
111− is also sometimes omitted in data structure definitions.
112−
113−## The kernel and pills
114−
115−urbit bootstraps itself using a binary blob called `urbit.pill`, which
116−we do indeed keep in version control. This creates some special
117−requirements. If you are not changing anything in the kernel (everything
118−under `urb/zod/arvo/`) then you can skim this section (please do not
119−skip it entirely, though). If you *are* working there, then this
120−section is critically important!
121−
122−The procedure for creating `urbit.pill` is often called "soliding". It
123−is somewhat similar to `|reset`, but instead of replacing your running
124−kernel, it writes the compiled kernel to a file. The command to solid
125−is, on a fakezod:
126−
127− .urbit/pill +solid
128−
129−When the compilation finishes, your `urbit.pill` will be found in the
130−`[pier]/.urb/put/` directory. Copy it into `urb/` and add it to your
131−commit.
132−
133−The requirement here is that every commit that changes the kernel must
134−come with an `urbit.pill` built from the same code in `urb/zod/arvo/`
135−for that commit. (Only changing the actual Hoon code counts, so a change
136−to a jet with no corresponding Hoon change does not require a new pill.)
137−This is so that checking out an arbitrary revision and starting up a
138−fakezod actually works as expected. However you do this is fine, but I
139−like to do it as part of my committing process - just before `git
140−commit`, I fire up a new fakezod. This will use the previous
141−`urbit.pill`, but the kernel code in `%clay` will be copied from
142−`urb/zod/arvo/`, so `+solid` will compile it. Then I copy `urbit.pill`
143−into `urb/` and make my commit.
144−
145−If you rebase or interactive rebase your commits, be sure to preserve
146−this property on all the commits you end up with. If multiple people
147−were collaborating on your branch, you may end up with conflicts in
148−`urbit.pill` and have to merge the branch into itself to resolve them.
149−Just do the same procedure to create a new, merged pill before
150−committing the merge. Otherwise, just make sure to use the correct
151−`urbit.pill` for each commit.
152−
153−## Debug urbit with `gdb`
154−
155−Follow the build instructions in README.md but run `make` with argument `DEBUG=yes`:
156−
157−(If you've already built urbit first run `make clean`.)
158−
159− make DEBUG=yes
160−
161−Run `gdb`, while loading `bin/urbit` and its symbol table:
162−
163− gdb bin/urbit
164−
165−Set a breakpoint on `main()` (optional):
166−
167− break main
168−
169−Run your urbit comet `mycomet`:
170−
171− run mycomet
172−
173−Continue from the breakpoint on `main()`:
174−
175− continue
176−
177−## What to work on
178−
179−If you are not thinking of contributing with a specific goal in mind,
180−the GitHub issue tracker is the first place you should look for ideas.
181−Issues are tagged with a priority and a difficulty. A good place to
182−start is on either a low-difficulty issue or a low-priority issue.
183−Higher priority issues are likely to be assigned to someone - if this is
184−the case, then contacting that person to coordinate before starting to
185−work is probably a good idea.
186−
187−There is also a "help wanted" tag for things that we are especially
188−eager to have outside contributions on. Check here first!
189−
190−## Staying in touch
191−
192−The urbit developers communicate on urbit itself. Joining the
193−`~doznec/urbit-meta` channel on `talk` is highly recommended.
194−Subscribing to `urbit-dev` on Google Groups is also recommended, since
195−this is where continuity breach notifications are sent.
196−
197−You can also contact one of the following people:
198−
199−- Philip Monk
200−
201− email: philip.monk@tlon.io
202−
203− urbit: `~wictuc-folrex`
204−
205− GitHub: [@philipcmonk](https://github.com/philipcmonk/)
206−
207−- Raymond Pasco
208−
209− email: ray@the.ug
210−
211− urbit: `~ramtev-wisbyt`
212−
213− GitHub: [@juped](https://github.com/juped/)
docs/dev/hoon.mddeleted−24
@@ -1,24 +0,0 @@
1−---
2−logo: black
3−sort: 2
4−title: Hoon
5−---
6−
7−<div class="short">
8−
9−# Hoon
10−
11−Hoon is a strict, typed, pure functional language. This site is
12−served by an urbit written in Hoon.
13−
14−If you're interested in learning the fundamentals of Hoon from
15−the bottom up, start with [Principles of
16−Hoon](hoon/principles).
17−
18−If you want to jump into building things right away and prefer to
19−learn from the top down, check out [Leap into
20−Hoon](hoon/leap-in/basic).
21−
22−Both of these are under active development.
23−
24−</div>
docs/dev/hoon/leap-in.mddeleted−8
@@ -1,8 +0,0 @@
1−---
2−hide: false
3−next: false
4−sort: 1
5−title: Leap into Hoon
6−---
7−
8−<list></list>
docs/dev/hoon/principles.mddeleted−18
@@ -1,18 +0,0 @@
1−---
2−logo: black
3−sort: 2
4−title: Hoon 101
5−---
6−
7−Welcome to Hoon 101!
8−
9−Ideally, you've installed an Urbit planet (if you have a ticket)
10−or comet (if you don't). See the [user doc](../../user). We
11−recommend opening up the dojo and just typing the examples; you
12−don't know a language until you know it in your fingers.
13−
14−Hoon 101 is still under construction; new chapters are posted
15−roughly once a week. So far:
16−
17−<list></list>
18−
docs/dev/hoon/runes/index.hookdeleted−13
@@ -1,13 +0,0 @@
1−/+ tree
2−/: /%%/ /%
3− /^ [tip=marl sub=(map span marl) ~]
4− /. /; (getall:tree %h1 ~) /elem/
5− /_ /; (getall:tree %h1 ~) /elem/
6− ==
7−!:
8−::::
9− ::
10−^- (map path marl)
11−=- [[/ (zing -)] ~ ~]
12−^- (list marl)
13−[tip (turn (~(tap by sub)) tail)]
docs/dev/interpreter.mddeleted−12
@@ -1,12 +0,0 @@
1−---
2−hide: true
3−logo: black
4−sort: 5
5−title: Interpreter
6−---
7−
8−# Interpreter
9−
10−The Urbit interpreter is written in C.
11−
12−Watch this space for actual documentation.
docs/dev/nock.mddeleted−52
@@ -1,52 +0,0 @@
1−---
2−logo: black
3−sort: 1
4−title: Nock
5−---
6−
7−# Nock
8−
9−Nock is a homoiconic combinator algebra, not much fancier than SKI
10−combinators. We'll have some tutorials soon. The spec:
11−
12−```
13−A noun is an atom or a cell.
14−An atom is a natural number.
15−A cell is an ordered pair of nouns.
16−
17−nock(a) *a
18−[a b c] [a [b c]]
19−
20−?[a b] 0
21−?a 1
22−+[a b] +[a b]
23−+a 1 + a
24−=[a a] 0
25−=[a b] 1
26−=a =a
27−
28−/[1 a] a
29−/[2 a b] a
30−/[3 a b] b
31−/[(a + a) b] /[2 /[a b]]
32−/[(a + a + 1) b] /[3 /[a b]]
33−/a /a
34−
35−*[a [b c] d] [*[a b c] *[a d]]
36−
37−*[a 0 b] /[b a]
38−*[a 1 b] b
39−*[a 2 b c] *[*[a b] *[a c]]
40−*[a 3 b] ?*[a b]
41−*[a 4 b] +*[a b]
42−*[a 5 b] =*[a b]
43−
44−*[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
45−*[a 7 b c] *[a 2 b 1 c]
46−*[a 8 b c] *[a 7 [[7 [0 1] b] 0 1] c]
47−*[a 9 b c] *[a 7 c 2 [0 1] 0 b]
48−*[a 10 [b c] d] *[a 8 c 7 [0 3] d]
49−*[a 10 b c] *[a c]
50−
51−*a *a
52−```
docs/orientation.mdnew file+9
@@ -0,0 +1,9 @@
1+---
2+sort: 1
3+---
4+
5+# Orientation
6+
7+Want to know how the system fits together? Start here.
8+
9+<list dataPath="docs/orientation"></list>
docs/orientation/repo-guide.mdnew file+106
@@ -0,0 +1,106 @@
1+---
2+next: true
3+sort: 3
4+title: What's in the repo
5+---
6+
7+# What's in the repo
8+
9+The `urbit` repo can look a little confusing at first. Here we'll take a look at the files that live on your `/=home=` desk by default.
10+
11+If you `ls urb/zod` from inside the urbit repo you should see something like:
12+
13+ app
14+ arvo
15+ gen
16+ lib
17+ mar
18+ ren
19+ sur
20+ web
21+ web.md
22+
23+Let's step through directory by directory.
24+
25+## `app/`
26+
27+This is where `%gall` apps live. `%gall` apps are stateful servants. Sort of like unix daemons. One very familiar one is `app/talk.hoon` which is the source code for `:talk` the urbit messaging transport layer. And there's also `app/dojo.hoon` — that's your shell.
28+
29+## `arvo/`
30+
31+This is where the `%arvo` vanes live. Vanes are sort of like kernel modules. These are worth listing one by one:
32+
33+### `arvo/ames.hoon`
34+
35+`%ames` is our network protocol.
36+
37+### `arvo/behn.hoon`
38+
39+`%behn` is a simple timer.
40+
41+### `arvo/clay.hoon`
42+
43+`%clay` is our filesystem.
44+
45+### `arvo/dill.hoon`
46+
47+`%dill` is our terminal driver.
48+
49+### `arvo/eyre.hoon`
50+
51+`%eyre` is our webserver.
52+
53+### `arvo/ford.hoon`
54+
55+`%ford` is our build system.
56+
57+### `arvo/gall.hoon`
58+
59+`%gall` is our application model.
60+
61+### `arvo/hoon.hoon`
62+
63+`%hoon` is our programming langauge.
64+
65+### `arvo/jael.hoon`
66+
67+`%jael` handles secret storage.
68+
69+### `arvo/kahn.hoon`
70+
71+`%kahn` stores your contacts / trust graph.
72+
73+### `arvo/zuse.hoon`
74+
75+`%zuse` is our standard library.
76+
77+That's it. That's the whole system.
78+
79+## `gen/`
80+
81+`gen/` holds generators. Generators are short command-line scripts.
82+
83+## `lib/`
84+
85+`lib/` holds shared libraries for programs. `lib/sole` is a good example — that's the console library that's shared by both `:dojo` in the command line, and the `dojo` web client.
86+
87+## `mar/`
88+
89+This is where marks live. Marks are data type definitions used by `%ford` and `%clay`.
90+
91+Marks define how diffs are performed on a particular data type and how they can be translated to different types. Sort of like file extensions, but much more powerful.
92+
93+## `ren/`
94+
95+These are web renderers. A renderer handles web requests of a particular type.
96+
97+Default web requets in urbit are handled as a `.urb`, which is caught by the `urb.hoon` renderer. This wraps the request in our default `css` and `js` and adds some routing magic for certain paths.
98+
99+## `sur/`
100+
101+`sur/` contains shared data structures.
102+
103+## `web/`
104+
105+There are the files publicly accessible to the web, as made possible by `%eyre`.
106+
docs/orientation/system-overview.mdnew file+63
@@ -0,0 +1,63 @@
1+---
2+next: true
3+sort: 2
4+title: System overview
5+---
6+
7+# System Overview
8+
9+### Nock
10+
11+Nock is a sort of nano-Lisp without syntax, symbols or lambdas.
12+Most Lisps are one-layer: they create a practical language by
13+extending a theoretically simple interpreter. The abstraction is
14+simple and the implementation is practical; there is no actual
15+codebase both simple and practical. Hoon and Nock are two
16+layers: Hoon compiles itself to pure Nock. Since Urbit is
17+defined in Nock, not Hoon, we can upgrade Hoon over the air.
18+
19+The Nock data model is especially trivial. A *noun* is an atom
20+or a cell. An atom is any unsigned integer. A cell is an
21+ordered pair of nouns. Nouns are acyclic and expose no pointer
22+equality test.
23+
24+### Hoon
25+
26+Hoon is a strict combinator language that avoids mathematical
27+theory and notation. It aims at a mechanical, imperative feel.
28+Hoon uses ASCII digraphs instead of keywords; there are no
29+user-level macros. The type system infers only forward and does
30+not use unification, but is not much weaker than Haskell's. The
31+compiler and inference engine is about 2000 lines of Hoon.
32+
33+### Arvo
34+
35+Arvo is an event-driven OS written in Hoon. It can upgrade
36+itself and everything inside it over the network. The Arvo
37+kernel proper is 500 lines of Hoon, which implements a typed
38+event system with explicit call-stack structure. Arvo ships
39+with modules that provide P2P networking (`%ames`), a revision-
40+control system (`%clay`), a web client/server (`%eyre`), a
41+functional build system (`%ford`), and an application engine
42+`(%gall)`.
43+
44+### `%ames`
45+
46+`%ames`, the Urbit network, is an encrypted P2P protocol over
47+UDP. Its address space is semi-decentralized; 64-bit addresses
48+are hierarchically distributed, 128-bit addresses are
49+self-created. Addresses (or *plots*) are rendered in a phonemic
50+syntax for memorability. The scarcity of short plots helps
51+control spam and other Sybil attacks. The short plot hierarchy
52+is also reused as a supernode routing system for NAT traversal.
53+
54+### Apps
55+
56+Urbit ships with two default applications: a REPL or shell
57+`:dojo`, and a distributed user-level message-bus `:talk`.
58+`:talk` under the hood resembles NNTP; to the user, it looks like
59+a self-hosted Slack or persistent IRC.
60+
61+The full Urbit stack (compiler, standard library, kernel,
62+modules, and applications) is about 25,000 lines of Hoon.
63+Urbit is patent-free and MIT licensed.
docs/user/intro.md → docs/orientation/what-is-urbit.mdrenamed+2−2
@@ -1,10 +1,10 @@
11---
22next: true
33sort: 1
4−title: Introduction
4+title: What is Urbit?
55---
66
7−# Introduction
7+# What is Urbit?
88
99Urbit is a clean-slate system software stack defined as a
1010deterministic computer. An encrypted P2P network, `%ames`, runs
docs/setup.mdnew file+9
@@ -0,0 +1,9 @@
1+---
2+sort: 2
3+---
4+
5+# Setup
6+
7+Get an Urbit installed and running.
8+
9+<list dataPath="docs/setup"></list>
docs/user/basic.md → docs/setup/getting-started.mdrenamed+3−3
@@ -1,10 +1,10 @@
11---
22next: true
3−sort: 3
4−title: Basic Operation
3+sort: 2
4+title: Getting started
55---
66
7−# Basic Operation
7+# Getting started
88
99Once urbit is installed, if you have an invitation, it's a planet
1010like `~fintud-macrep` and a ticket like
docs/user/install.md → docs/setup/install.mdrenamed+1−1
@@ -1,6 +1,6 @@
11---
22next: true
3−sort: 2
3+sort: 1
44title: Install
55---
66
docs/system.mdnew file+9
@@ -0,0 +1,9 @@
1+---
2+sort: 6
3+---
4+
5+# System Reference
6+
7+`nock` fundamentals, `hoon` reference documentation and `arvo` APIs are in here.
8+
9+<list dataPath="docs/system"></list>
docs/system/arvo/ames.mdnew file+29
@@ -0,0 +1,29 @@
1+<div class="short">
2+
3+`%ames`
4+=======
5+
6+Our networking protocol.
7+
8+`%ames` is the name of both our network and the vane that communicates
9+over it. When Unix receives a packet over the correct UDP port, it pipes
10+it straight into `%ames` for handling. Also, all packets sent over the
11+`%ames` network are sent by the `%ames` vane. Apps and vanes may use
12+`%ames` to directly send messages to other ships. In general, apps use
13+gall and clay to communicate with other ships rather than using `%ames`
14+directly, but this isn't a requirement. Of course, gall and clay use
15+`%ames` behind the scenes to communicate across the network. These are
16+the only two vanes that use `%ames`.
17+
18+`%ames` includes several significant components. Although the actual
19+crypto algorithms are defined in zuse, they're used extensively in
20+`%ames` for encrypting and decrypting packets. Congestion control and
21+routing is handled entirely in `%ames`. Finally, the actual `%ames`
22+protocol itself, including how to route incoming packets to the correct
23+vane or app, is defined in `%ames`.
24+
25+</div>
26+
27+<hr>
28+</hr>
29+<list></list>
docs/system/arvo/ames/commentary.mdnew file+1815
@@ -0,0 +1,1815 @@
1+`%ames` commentary
2+==================
3+
4+`%ames` is our networking protocol.
5+
6+First we give commentary on the code, the algorithms involved, and the
7+protocol. We trace through the code touched when a packet is sent,
8+received, acknowledged, and that acknowledgment applied. This is fairly
9+comprehensive, and contains many implementation details, but if you
10+understand this, then you understand `%ames`.
11+
12+If you've scrolled down this page, you may be intimidated by the amount
13+of Hoon code, especially if you are new to the language. Don't be afraid
14+of it, you don't have to read any of it if you don't want to -- every
15+interesting action the code takes is explained in plain English. In
16+fact, if you are new to the language, this may be a good learning
17+opportunity. Even if you don't understand every line of Hoon code,
18+you'll hopefully be able to follow most lines. By the time you've worked
19+through this, you'll have seen many common patterns and best practices.
20+Hoon, much more than other languages, is best learned by reading and
21+understanding large quantities of existing code. In this way, it is
22+similar to learning a natural language. All of this code is in
23+`arvo/ames.hoon`.
24+
25+After the commentary, we have reference documentation for all the data
26+structures that are specific to `%ames`. If you see a data structure or
27+a variable used that you don't recognize, search for it in the code, and
28+it's very likely defined in one of these data structures. We recommend
29+that another tab is kept open for easy access to the data structure
30+reference documentation. The code for these is split between
31+`arvo/ames.hoon` and `arvo/zuse.hoon`.
32+
33+The Lifecycle of a Packet (or, How a Packet Becomes Law)
34+--------------------------------------------------------
35+
36+Here, we will trace a packet as it makes its way through ames. There are
37+actually two pathways through ames: the legacy path through `%want`, and
38+the modern way, entered through `%wont`, with full end-to-end
39+acknowledgments. Here we will only trace the modern way, though much of
40+the path is the same for both.
41+
42+When an app (or a vane) wishes to send a packet to another ship, it must
43+send a `%wont` card:
44+
45+ [%wont p=sock q=path r=*] :: e2e send message
46+
47+This card takes three arguments. The `p` is a `sock`, that is, a pair of
48+two ships, the first of which is the sender and the second is the
49+receiver. But wait, you ask, why do I get to decide who is the sender?
50+Can I fake like I'm someone else? The reason is that there are
51+potentially multiple ships on the same pier, and the kernel can send a
52+message from any of them. If you attempt to send a message from a ship
53+not on your pier, then ames will refuse to send it. If you hack around
54+in your own copy of ames to go ahead and send it anyway, then the other
55+ship will reject it because your key is bad. Only send messages from
56+yourself.
57+
58+The `q` is a path, representing the place on the other side that you
59+want to receive your message. It is approximately equivalent to a port
60+number. Messages on the same path are guaranteed to arrive in the same
61+order as they were sent. No such guarantees are made across paths.
62+
63+The `r` is the actual data that you are sending. As the type implies,
64+this can be an arbitrary noun, and it will be transferred to the
65+receiver exactly as-is, in a well-typed way. Of course, this is data
66+that is sent over the wire, so be careful not to send anything too
67+massive unless you're willing to wait.
68+
69+But enough about the interface. Grepping in ames.hoon for `%wont`, we
70+find that it appears in exactly two places: at its definition in
71+`++kiss`, and in `++knob`, where it is handled. We see that we go
72+directly into `++wise:am`.
73+
74+ ++ wise :: wise:am
75+ |= [soq=sock hen=duct cha=path val=* ete=?] :: send a statement
76+ ^- [p=(list boon) q=fort]
77+ zork:zank:(wool:(ho:(um p.soq) q.soq) hen cha val ete)
78+
79+The inputs to this gate are exactly the sort of thing you'd expect. In
80+particular, everything in the `%wont` gate is here plus the calling duct
81+so that we know where to send the acknowledgment and `ete` to determine
82+if we're going to do the modern end-to-end acknowledgments.
83+
84+The actual line of code looks intimidating, but it's really not all that
85+bad. Working from the inside out, the call to `++um` sets up our
86+domestic server, and the call to `++ho` sets up our knowledge about the
87+neighbor we're sending to. From the outside, `++zork` and `++zank` just
88+apply the changes made to our `++um` and `++am` cores, respectively. If
89+you're familiar with the common idiom of `++abet`, that's all this is.
90+The code predates the widespread usage of that name.
91+
92+The interesting part, then, is in `++wool:ho:um:am`. Let's look at the
93+code.
94+
95+ ++ wool :: wool:ho:um:am
96+ |= [hen=duct cha=path val=* ete=?] :: send a statement
97+ ^+ +>
98+ =+ ^= rol ^- rill
99+ =+ rol=(~(get by ryl.bah) cha)
100+ ?~(rol *rill u.rol)
101+ =+ sex=sed.rol
102+ :: ~& [%tx [our her] cha sex]
103+ =. ryl.bah
104+ %+ ~(put by ryl.bah) cha
105+ rol(sed +(sed.rol), san (~(put by san.rol) sex hen))
106+ =+ cov=[p=p:sen:gus q=clon:diz]
107+ %+ wind [cha sex]
108+ ?: ete
109+ [%bund q.cov cha sex val]
110+ [%bond q.cov cha sex val]
111+
112+This is slightly more complicated, but it's still not all that bad. Our
113+inputs, at least, are fairly obvious.
114+
115+If you glance at the code for a second, you'll see that
116+`++wind:ho:um:am` seems to be able to send a message, or `++meal`, given
117+a `++soup`. This gate, then, just sets up the things we need to for
118+`++wind` to do its job.
119+
120+We first get `rol`, which is a `++rill`, that is, a particular outbound
121+stream. This stream is specific to the path on which we're sending. If
122+the path hasn't been used before, then we create it. We let `sex` be the
123+number of messages we've already sent on this path.
124+
125+Then, we update the outbound stream by incrementing the number of
126+messages sent and placing an entry in `san.rol` that associates the
127+message number with the `duct` that sent the message. This allows us to
128+give the acknowledgment to the one who sent the message.
129+
130+We let `cov` be the current life of our crypto and our neighbor's
131+crypto. At the moment, we only need our neighbor's life, which we put
132+into the meal.
133+
134+Finally, we call `++wind:ho:um:am` with the `++soup` of the path and
135+message number and the `++meal` of the payload itself. For end-to-end
136+acknowledged messages, we use `%bund`.
137+
138+ [%bund p=life q=path r=@ud s=*] :: e2e message
139+
140+Looking at how we create the `%bund`, we can easily see what each field
141+is for.
142+
143+Following the trail a little further, we go to `++wind:ho:um:am`.
144+
145+ ++ wind :: wind:ho:um:am
146+ |= [gom=soup ham=meal]
147+ :: ~& [%wind her gom]
148+ ^+ +>
149+ =^ wyv diz (zuul:diz now ham)
150+ =^ feh puz (whap:puz now gom wyv)
151+ (busk xong:diz feh)
152+
153+`++wind` does three things: it (1) encodes the message into a list of
154+possibly-encrypted packets, (2) puts the message into the packet pump,
155+and (3) sends any packets that are ready to be sent. Yes, our nice
156+little linear run of each gate calling exactly one other interesting
157+gate is over. We'll go in order here.
158+
159+`++zuul:lax:as:go` is the what converts a `++meal` into a list of
160+actual, 1KB packets.
161+
162+ ++ zuul :: zuul:lax:as:go
163+ |= [now=@da ham=meal] :: encode message
164+ ^- [p=(list rock) q=_+>]
165+ =< weft
166+ ++ wasp :: null security
167+ ++ weft :: fragment message
168+ ++ wisp :: generate message
169+
170+For organizational purposes, `++zuul` constructs an internal core with
171+three arms. `++wasp` encodes the meal into an atom with no encryption.
172+`++wisp` encodes a meal with possible encryption (else it simply calls
173+`++wasp`). `++weft` takes the result of `++wisp` and splits it into
174+actual packets.
175+
176+ ++ wasp :: null security
177+ ^-([p=skin q=@] [%none (jam ham)])
178+
179+This simply jams the meal, wrapping it with the `skin` of `%none`,
180+meaning no encryption.
181+
182+Since `++wisp` is a little long, we'll go through it line-by-line.
183+
184+ ++ wisp :: generate message
185+ ^- [[p=skin q=@] q=_..wisp]
186+
187+`++wisp` produces a pair of a `skin` and an atom, which is the meal
188+encoded as a single atom and possibly encrypted.
189+
190+ ?: =(%carp -.ham)
191+ [wasp ..wisp]
192+
193+If the meal that we're encoding is a `%carp`, then we don't encrypt it.
194+A `%carp` meal is a partial meal, used when a message is more than 1KB.
195+Since the entire message is already encrypted, we don't need to encrypt
196+each packet individually again.
197+
198+ ?: !=(~ yed.caq.dur)
199+ ?> ?=(^ yed.caq.dur)
200+ :_ ..wisp
201+ :- %fast
202+ %^ cat 7
203+ p.u.yed.caq.dur
204+ (en:r:cluy q.u.yed.caq.dur (jam ham))
205+
206+If we have a symmetric key set up with this neighbor, then we simply use
207+it. The skin `%fast` is used to indicate a symmetric key.
208+
209+ ?: &(=(~ lew.wod.dur) |(=(%back -.ham) =(%buck -.ham)))
210+ [wasp ..wisp]
211+
212+If we do not yet have our neighbor's will, then there is no way that we
213+can seal the message so that only they may read it. If what we're
214+sending is an acknowledgment, then we go ahead and just send it in the
215+clear.
216+
217+ =^ tuy +>.$
218+ ?:(=(~ lew.wod.dur) [*code +>.$] (griz now))
219+
220+If we don't have our neighbor's will, then we "encrypt" with a key of 0.
221+If we do have their will, then we generate a new symmetric key that we
222+will propose.
223+
224+ :_ ..wisp
225+ =+ yig=sen
226+ =+ bil=law.saf :: XX send whole will
227+ =+ hom=(jam ham)
228+
229+`yig` will be the life and engine for our current crypto. `bil` is our
230+will. `hom` is the meal encoded as a single atom.
231+
232+ ?: =(~ lew.wod.dur)
233+ :- %open
234+ %^ jam
235+ [~ `life`p.yig]
236+ bil
237+ (sign:as:q.yig tuy hom)
238+
239+If we do not have our neighbor's will, then we send our current life
240+along with our will and the message. The message itself is "signed" with
241+a key of 0.
242+
243+ :- %full
244+ =+ cay=cluy
245+ %^ jam
246+ [`life`p.cay `life`p.yig]
247+ bil
248+ (seal:as:q.yig pub:ex:r.cay tuy hom)
249+ -- :: --zuul:lax:as:go
250+
251+If we do have our neighbor's will, then we send our perception of their
252+current life, our current life, our will, and the message. The message
253+is sealed with their public key so that only they can read our message.
254+
255+Once we have the message encoded as an atom, `++weft` goes to work.
256+
257+ ++ weft :: fragment message
258+ ^- [p=(list rock) q=_+>.$]
259+ =^ gim ..weft wisp
260+ :_ +>.$
261+ ^- (list rock)
262+
263+We're going to produce a list of the packets to send. First, we use the
264+aforementioned `++wisp` to get the message as an atom.
265+
266+ =+ wit=(met 13 q.gim)
267+ ?< =(0 wit)
268+
269+`wit` is the number of 1KB (2\^13 bit) blocks in the message. We assert
270+that there is at least one block.
271+
272+ ?: =(1 wit)
273+ =+ yup=(spit [our her] p.gim q.gim)
274+ [yup ~]
275+
276+If there is exactly one block, then we just call `++spit` to turn the
277+message into a packet. We'll explain what `++spit` does momentarily.
278+
279+ =+ ruv=(rip 13 q.gim)
280+ =+ gom=(shaf %thug q.gim)
281+ =+ inx=0
282+
283+If there is more than one block, then we rip it into blocks in `ruv`.
284+`gom` is a hash of the message, used as an id. `inx` is the number of
285+packets we've already made.
286+
287+ |- ^- (list rock)
288+ ?~ ruv ~
289+ =+ ^= vie
290+ %+ spit
291+ [our her]
292+ wasp(ham [%carp (ksin p.gim) inx wit gom i.ruv])
293+ :- vie
294+ $(ruv t.ruv, inx +(inx))
295+
296+Here we package each block into a packet with `++spit` and produce the
297+list of packets.
298+
299+ ++ spit :: cake to packet
300+ |= kec=cake ^- @
301+ =+ wim=(met 3 p.p.kec)
302+ =+ dum=(met 3 q.p.kec)
303+ =+ yax=?:((lte wim 2) 0 ?:((lte wim 4) 1 ?:((lte wim 8) 2 3)))
304+ =+ qax=?:((lte dum 2) 0 ?:((lte dum 4) 1 ?:((lte dum 8) 2 3)))
305+ =+ wix=(bex +(yax))
306+ =+ vix=(bex +(qax))
307+ =+ bod=:(mix p.p.kec (lsh 3 wix q.p.kec) (lsh 3 (add wix vix) r.kec))
308+ =+ tay=(ksin q.kec)
309+ %+ mix
310+ %+ can 0
311+ :~ [3 1]
312+ [20 (mug bod)]
313+ [2 yax]
314+ [2 qax]
315+ [5 tay]
316+ ==
317+ (lsh 5 1 bod)
318+
319+This is how we turn a message into a real packet. This has the
320+definition of the packet format.
321+
322+`wim` is the length of the sending ship, and `dum` is the length of the
323+receiving ship. There are only five possibilities for each of those,
324+corresponding to carriers, cruisers, destroyers, yachts, and submarines.
325+These are encoded in `yax` and `qax` as 0, 0, 1, 2, and 3, respectively.
326+Thus, `wix` and `vix` are the number of bytes that must be reserved for
327+the ship names in a packet.
328+
329+Next, we construct `bod` by simply concatenating the sending ship, the
330+receiving ship, and the body of the message. Then, we get the encryption
331+mechanism from `++skin`, which may be a 0, 1, 2, or 3, and put it in
332+`tay`.
333+
334+Next, we concatenate together, bit by bit, some final metadata. We use
335+three bits for our protocol number, which is incremented modulo eight
336+when there is a continuity breach or the protocol changes. We use the
337+final twenty bits of a hash of the body (which, we suppose, makes it a
338+twenty bit hash) for error-checking. We use two bits to tell how much
339+room is used in the body for the sending ship, and another two bits for
340+the receiving ship. Finally, we use five bits to store the encryption
341+type. Note that since there are only two bits worth of encryption types,
342+there are three unused bits here. This adds up to 32 bits of header
343+data. Finally, we concatenate this onto the front of the packet. Thus,
344+we can summarize the packet header format as follows.
345+
346+ 0 1 2 3
347+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
348+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
349+ |Proto| Hash of Body |yax|qax| Crypto |
350+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
351+
352+After this, there are `yax` bits of the sender name, `qax` bits of the
353+receiver name, and up to 8192 bits of data. Thus, the maximum size of a
354+packet is achieved in a message between two submarines with 8192 bits of
355+data. This will require 32+128+128+8192 = 8480 bits, or 1060 bytes.
356+
357+This concludes our discussion of `++zuul:lax:as:go`. If you recall from
358+`++wind:ho:um:am`, the list of packets from `++zuul` is passed into
359+`++whap:pu` to update the packet pump and get any packets that can be
360+sent immediately.
361+
362+ ++ whap :: whap:pu
363+ |= [now=@da gom=soup wyv=(list rock)] :: send a message
364+ ^- [(list rock) _+>]
365+ =. pyz (~(put by pyz) gom (lent wyv))
366+ =. +>
367+ |- ^+ +>.^$
368+ ?~ wyv +>.^$
369+ %= $
370+ wyv t.wyv
371+ nus +(nus)
372+ diq (~(put by diq) (shaf %flap i.wyv) nus)
373+ puq (~(put to puq) [nus `soul`[gom 0 | ~2000.1.1 i.wyv]])
374+ ==
375+ (harv now)
376+
377+First, we put into `pyz` the id for this message and the number of its
378+packets that have not yet been acknowledged, which is of course the
379+total number of packets since we haven't even sent the packets.
380+
381+For every packet, we change three things in the state (`++shed`) of our
382+packet pump: (1) we increment `nus`, the number of packets sent; (2) we
383+put the packet number into `diq` keyed by a hash of the packet; and (3)
384+we put the packet into the packet queue, with the basic metadata of its
385+id `gom`, 0 transmissions, not live yet, last sent in the year 2000, and
386+the packet itself.
387+
388+Finally, we harvest the packet pump.
389+
390+ ++ harv :: harv:pu
391+ |= now=@da :: harvest queue
392+ ^- [(list rock) _+>]
393+ ?: =(~ puq) [~ +>(rtn ~)]
394+ ?. (gth caw nif) [~ +>]
395+ =+ wid=(sub caw nif)
396+ =| rub=(list rock)
397+ =< abet =< apse
398+ |%
399+
400+`++harv` contains a core for most of its work. The meat is in `++apse`.
401+First, though, it sets itself up. If there aren't any packets in the
402+queue, then we simply do nothing except set `rtn`, our next timeout, to
403+nil because we don't have any packets that may need to be retransmitted.
404+If we have more live (that is, sent and unacknowledged) packets than our
405+window size, then we don't do anything.
406+
407+Otherwise, we let `wid` be the width of our remaining packet window, and
408+we initialize `rub` to nil. `rub` will be the list of packets that are
409+ready to be sent. We then call `++apse` and pass the result to `++abet`.
410+`++apse` decides which packets are ready to be sent.
411+
412+ ++ apse
413+ ^+ .
414+ ?~ puq .
415+ ?: =(0 wid) .
416+ => rigt =< left
417+ ?> ?=(^ puq)
418+ ?: =(0 wid) .
419+ ?. =(| liv.q.n.puq) .
420+ :: ~& [%harv nux.q.n.puq p.n.puq]
421+ %_ .
422+ wid (dec wid)
423+ rub [pac.q.n.puq rub]
424+ nif +(nif)
425+ liv.q.n.puq &
426+ nux.q.n.puq +(nux.q.n.puq)
427+ lys.q.n.puq now
428+ ==
429+
430+If there are no remaining packets to send, or if we've filled the packet
431+window, do nothing. We call `++rigt` and `++left` to process the left
432+and right branches of the packet queue.
433+
434+Now we assert that the queue is not empty, and we again check that we
435+haven't filled the packet window. We will operate on the head of the
436+queue. If the packet is live, then do nothing. Otherwise, we go ahead
437+and send it.
438+
439+To send, we (1) decrement `wid`, our packet window width; (2) cons the
440+packet onto the `rub`, which will be returned as the list of packets to
441+send; (3) increment `nif`, the number of live packets; (4) set the
442+packet to be live; (5) increment the number of transmissions of the
443+packet; and (6) set the last sent time of the packet to now.
444+
445+ ++ left
446+ ?> ?=(^ puq)
447+ ^+(. =+(lef=apse(puq l.puq) lef(puq [n.puq puq.lef r.puq])))
448+ ++ rigt
449+ ?> ?=(^ puq)
450+ ^+(. =+(rig=apse(puq r.puq) rig(puq [n.puq l.puq puq.rig])))
451+
452+These do exactly what you would expect: they traverse the packet queue
453+so that `++apse` gets called recursively through it.
454+
455+Finally, `++abet` gets called, which resolves the changes.
456+
457+ ++ abet
458+ ?~ rub [~ +>.$]
459+ [(flop rub) +>.$(rtn [~ (add rto now)])]
460+
461+This returns the packets that we wish to send, and it updates the
462+timeout so that we know when to try resending unacknowledged packets.
463+
464+This concludes our discussion of `++whap:pu`. To finish
465+`++wind:ho:um:am`, we just need to delve into `++busk:ho:um:am`. But
466+wait, in the call to `++busk`, the first argument is `xong:diz`. What is
467+this? This, my dear reader, is one more detour, this time into
468+`++xong:lax:as:go`.
469+
470+ ++ xong :: xong:lax:as:go
471+ ^- (list ship) :: route unto
472+ =+ [fro=xen too=xeno]
473+ =+ ^= oot ^- (list ship)
474+ =| oot=(list ship)
475+ |- ^+ oot
476+ ?~ too ~
477+ ?: (lien fro |=(a=ship =(a i.too))) ~
478+ [i.too $(too t.too)]
479+ :: ~& [%xong-to [our her] (weld oot ?>(?=(^ fro) t.fro))]
480+ (weld oot ?>(?=(^ fro) t.fro))
481+
482+This gets the list of intermediate ships needed to get a packet from us
483+to our neighbor. First, we get `fro` and `too`, the "canons" of ourself
484+and our neighbor, respectively.
485+
486+What is this "canon", you ask? A canon is simply a ship plus its
487+"ancestors", as defined by `++sein`. For example, the canon of
488+`~hoclur-bicrel` is:
489+
490+ ~hoclur-bicrel/try=> (saxo ~hoclur-bicrel)
491+ ~[~hoclur-bicrel ~tasruc ~tug]
492+
493+If we follow the algorithm in `++xong`, we see that we are simply
494+creating a list of ships that form a path from our neighbor to ourself.
495+Essentially, we look through the canon of our neighbor until we find
496+something in our own cannon -- a common ancestor. Or, if we are from
497+different carriers, then there is no common ancestor. We then weld this
498+onto the tail of our own canon. In the end, this is simply a list of
499+possible ships to try to route via to get to our neighbor, ordered by
500+preferability (that is, closeness to our neighbor). We will end up
501+trying, in order, to find a lane to these.
502+
503+Now, we can finally get to `++busk:ho:um:am`.
504+
505+ ++ busk :: busk:ho:um:am
506+ |= [waz=(list ship) pax=(list rock)] :: send packets
507+ %_ +>
508+ bin
509+ |- ^+ bin
510+ ?~ pax bin
511+ $(pax t.pax, bin (weld (flop (wist:diz now waz ~ i.pax)) bin))
512+ ==
513+
514+Thankfully, `++busk` is fairly simple. We go through the list of packets
515+and convert them to `++boon`s with `++wist:lax:as:go`. These boons are
516+placed into `bin`, and they end up getting processed by `++clop` (this
517+happens in `++knob`).
518+
519+ ++ wist :: wist:lax:as:go
520+ |= $: now=@da :: route via
521+ waz=(list ,@p)
522+ ryn=(unit lane)
523+ pac=rock
524+ ==
525+ ^- (list boon)
526+ ?: =(our her) [[%ouzo *lane pac] ~]
527+ ?~ waz ~
528+ =+ dyr=?:(=(her i.waz) dur (gur i.waz))
529+ ?. ?& !=(our i.waz)
530+ ?=(^ lun.wod.dyr)
531+ ==
532+ $(waz t.waz)
533+ :_ ?: ?=(%ix -.u.lun.wod.dyr)
534+ $(waz t.waz)
535+ ~
536+ :+ %ouzo u.lun.wod.dyr
537+ ?: &(=(i.waz her) =(~ ryn)) pac
538+ =+ mal=(jam `meal`[%fore her ryn pac])
539+ %- spit
540+ ^- cake
541+ :* [our i.waz]
542+ ?~ yed.caq.dyr [%none mal]
543+ :- %fast
544+ %^ cat 7
545+ p.u.yed.caq.dyr
546+ (en:crua q.u.yed.caq.dyr mal)
547+ ==
548+
549+This takes a sample of the current time, the list of ships that we just
550+generated, a lane if we already know it, and the packet itself.
551+
552+First, if we are sending a message to ourself, then we simply create a
553+`%ouzo` boon with a bunted lane. Otherwise, if there are no routing
554+candidates, there is nothing we can do, so we return nil.
555+
556+Next, we get the `dore` of the first routing candidate. If we're looking
557+at the neighbor to whom we're trying to send the message, then we simply
558+use the `dore` that we already have. Otherwise, we get a default `dore`.
559+
560+If we're the first routing candidate, or if we have don't have a lane to
561+this candidate, then we skip this candidate and move on to the next one.
562+
563+If we have only a provisional ip address, then we try to send on it, but
564+we also try to send on later routing candidates as well. Otherwise, we
565+only send on this one candidate.
566+
567+Finally, we create the actual `%ouzo` boon. The lane is the one from our
568+`dore`. If we're sending it directly to our intended recipient, and we
569+haven't been told to use a specific lane, then we just send the packet
570+directly. Otherwise, we wrap it in a little `%fore` meal, telling the
571+intermediary to whom we wish it to be sent. If we have already set up a
572+symmetric key with the intermediary, then we encrypt it with that.
573+Otherwise, we send it in the clear.
574+
575+Now, if you recall, we have traced all the way through from the
576+beginning when, in `++knob`, the `%wont` card was handled by a call to
577+`++wise`. There is only one more step before the packet is finally sent.
578+Looking in `++knob`, we see that the resultant list of boons is passed
579+into `++clop`, which will execute the correct actions and return a list
580+of moves. In `++clop`, we see the handling of each specific boon. The
581+one we are interested in is `%ouzo`, since that is the only one we have
582+sent thus far.
583+
584+ %ouzo
585+ :: ~& [%send now p.bon `@p`(mug (shaf %flap q.bon))]
586+ :_ fox
587+ [[gad.fox [%give %send p.bon q.bon]] ~]
588+
589+Very simply, we give a `%send` gift along the special duct that goes
590+straight into the bowels of unix. This is the last stop before we drop
591+into vere, and later libuv. And then... the world.
592+
593+The packet, after its creation, embarks on a journey across physical
594+time and space into the great unknown. Hurtling through fiber-optic
595+cables at hundreds of thousands of kilometers per second, it finally
596+arrives at our neighbor's network adapter. The adapter tells unix, unix
597+tells libuv, libuv tells vere, and vere sends a `%hear` kiss to ames.
598+And now we reenter the kernel.
599+
600+The `%hear` kiss goes straight to `++knob`, just as did the `%wont` kiss
601+earlier.
602+
603+ %hear
604+ (~(gnaw am [now fox]) %good p.kyz q.kyz)
605+
606+Here, though, we call `++gnaw:am` to process the packet. The arguments
607+to `++gnaw` are the same as those to the `%hear` kiss: the lane on which
608+the packet was received and the packet itself. The other argument is
609+just `%good`, which is a `++cape` saying that we expect the packet to
610+succeed. If a formal error occurs, then since we have a transactional
611+event system, the `%hear` event will never be considered to have
612+actually happened, and unix will send a `%hole` kiss so that we may send
613+a negative acknowledgment.
614+
615+ ++ gnaw :: gnaw:am
616+ |= [kay=cape ryn=lane pac=rock] :: process packet
617+ ^- [p=(list boon) q=fort]
618+ ?. =(2 (end 0 3 pac)) [~ fox]
619+ =+ kec=(bite pac)
620+ ?: (goop p.p.kec) [~ fox]
621+ ?. (~(has by urb.ton.fox) q.p.kec)
622+ [~ fox]
623+ =< zork
624+ =< zank
625+ %- ~(chew la:(ho:(um q.p.kec) p.p.kec) kay ryn %none (shaf %flap pac))
626+ [q.kec r.kec]
627+
628+First, we check the protocol number. If it is not correct, then we
629+simply ignore the packet entirely. Otherwise, we parse the packet with
630+`++bite`, which converts a packet atom into a `cake`, that is, a triple
631+of the `sock` (pair of sender and receiver), the `skin` (encryption
632+type), and the data.
633+
634+ ++ bite :: packet to cake
635+ |= pac=rock ^- cake
636+ =+ [mag=(end 5 1 pac) bod=(rsh 5 1 pac)]
637+ =+ :* vez=(end 0 3 mag) :: protocol version
638+ chk=(cut 0 [3 20] mag) :: checksum
639+ wix=(bex +((cut 0 [23 2] mag))) :: width of receiver
640+ vix=(bex +((cut 0 [25 2] mag))) :: width of sender
641+ tay=(cut 0 [27 5] mag) :: message type
642+ ==
643+ ?> =(2 vez)
644+ ?> =(chk (end 0 20 (mug bod)))
645+ :+ [(end 3 wix bod) (cut 3 [wix vix] bod)]
646+ (kins tay)
647+ (rsh 3 (add wix vix) bod)
648+
649+This is exactly the inverse of `++spit`. Note that here we check both
650+the protocol number and the hash, crashing on error. Remember that a
651+crash will result in a negative acknowledgment being sent.
652+
653+Continuing in `++gnaw`, we see that if the intended recipient is not on
654+our pier, then we drop the packet.
655+
656+If we've gotten this far, then we wish to process the packet. Recall
657+that `++ho` and `++um` set up the domestic server and foreign client
658+cores, respectively, and that `++zork` and `++zank` resolve any changes
659+to these cores.
660+
661+The new stuff here, then, is the `++la` core and the `++chew` arm. The
662+`++la` sets up a core for this particular packet, containing the current
663+success/failure `cape`, the lane it was sent on, the encryption type,
664+and a hash of the packet, used as an id.
665+
666+`++chew` is called with the encryption type and the message itself. It
667+contains a little helper core inside of it, which starts immediately
668+with `++apse`.
669+
670+ ++ apse
671+ ^+ +>.$
672+ =+ oub=bust:puz
673+ =+ neg==(~ yed.caq.dur.diz)
674+ =. +>.$ east
675+ =+ eng==(~ yed.caq.dur.diz)
676+ =+ bou=bust:puz
677+ =. bin
678+ ?. &(oub !bou) bin
679+ :_(bin [%wine [our her] " is ok"])
680+ =. bin
681+ ?. &(neg !eng) bin
682+ :_(bin [%wine [our her] " is your neighbor"])
683+ +>.$
684+
685+First, we let `oub` be true if our neighbor hasn't been responding to us
686+for more than sixteen seconds. Let `neg` be true if we haven't yet
687+proposed a symmetric key, meaning that we haven't yet corresponded with
688+this ship, so they are not our neighbor. Next, we run `++east`, which
689+we'll go into in just a minute.
690+
691+We now do the same two checks and store the results in `eng` and `bou`.
692+If our neighbor has, like the prodigal son, returned after an extended
693+absense, then we send a `%wine` boon as the proverbial fatted calf,
694+which is simply printed out to the console. Likewise, if we are meeting
695+one with whom we have never had the pleasure of acquainting ourselves,
696+we send a message to the console to that effect.
697+
698+We skipped over `++east`, which contains the meat of the processing. It
699+first decrypts the message, then calls `++chow:la:ho:um:am` with the
700+resultant meal. We'll go through each of the four cases in turn, but
701+first since each one calls `++bilk:pu`, we'll take a brief detour.
702+
703+ ++ bilk :: bilk:pu
704+ |= now=@da :: inbound packet
705+ ^+ +>
706+ =+ trt=(mul 2 rtt)
707+ %= +>.$
708+ rue [~ now]
709+ rto trt
710+ rtn ?~(puq ~ [~ (add now trt)])
711+ ==
712+
713+This updates the timing information in our packet pump. `rue`, the last
714+time we have heard from this neighbor, is set to now. `rto`, the
715+retransmit timeout is set to twice the current ping time, and if there
716+is anything in the packet queue, then we reset the next timeout, since
717+we've just heard a message.
718+
719+Back to `++east`.
720+
721+ %none
722+ =. puz (bilk:puz now)
723+ (chow ((hard meal) (cue msg)))
724+
725+The simplest case is when the encryption type is `%none`. We first call
726+`++bilk` to update the packet pump, then we cue (unjam) the message into
727+a meal. We hard cast it into a meal -- if the cast fails, then we do
728+want to crash since someone is sending us malformed data. Finally, we
729+send the result to `++chow` for interpretation and handling.
730+
731+ %fast
732+ =+ [mag=`hand`(end 7 1 msg) bod=(rsh 7 1 msg)]
733+ =+ dey=(kuch:diz mag)
734+ ?~ dey
735+ ~& [%bad-key her mag]
736+ +>.$ :: ignore unknown key
737+ =. puz (bilk:puz now)
738+ =^ key diz u.dey
739+ (chow(aut sin) ((hard meal) (cue (dy:q:sen:gus key bod))))
740+
741+For symmetric encryption, we first get the `hand`, which is the hash of
742+the symmetric key. We pass it to `++kuch:lax:as:go`, which returns the
743+key if we either have used it before or we have proposed it. If we have
744+proposed it, then we change its status from proposed to real. If
745+`++kuch` fails, then we drop the packet and print out a `%bad-key`
746+message.
747+
748+Otherwise, we call `++bilk` as before to update the packet pump and pass
749+into `++chow` the decrypted data.
750+
751+ %full
752+ =+ mex=((hard ,[p=[p=life q=life] q=will r=@]) (cue msg))
753+ =. diz (deng:diz q.mex)
754+ =+ wug=cluy:diz
755+ ?> =(q.p.mex p.wug)
756+ =+ gey=(sev:gus p.p.mex)
757+ =+ mes=(need (tear:as:q.gey pub:ex:r.wug r.mex))
758+ =. diz (wasc:diz p.mes)
759+ =. puz (bilk:puz now)
760+ (west(msg q.mes))
761+
762+For sealed asymmetric encryption, we first take off the the layer of
763+data that gives us the life and will of our neighbor, and we apply try
764+to extend their former will with the new data. `++deng` will fail if
765+this is impossible.
766+
767+Next, we get our most current understanding of our neighbor's crypto,
768+and we verify that it's the same life as what they're sending. Then, we
769+get our own crypto from `++sev` and decrypt the message with the public
770+key from our neighbor's crypto. We register the proposed symmetric key,
771+update the packet pump, and call `++west`, which simply casts the
772+message to a meal and calls `++chow`, reporting any error.
773+
774+ %open
775+ =+ mex=((hard ,[p=[~ q=life] q=will r=@]) (cue msg))
776+ =. diz (deng:diz q.mex)
777+ =+ wug=cluy:diz
778+ ?> =(q.p.mex p.wug)
779+ =+ mes=(need (sure:as:r.wug *code r.mex))
780+ =. puz (bilk:puz now)
781+ (west(msg mes))
782+
783+Finally, for signed asymmetric encryption, we, as before, take off the
784+layer of data that gives us the life and will of our neighbor. This
785+time, of course, we do not get our own crypto -- only that of our
786+neighbor.
787+
788+The rest you have seen. We call `++deng` to extend the will, we verify
789+that their crypto life is what we think it ought to be, we "decrypt" the
790+data, we update the packet pump, and we call `++west` to call `++chow`.
791+
792+ ++ chow :: chow:la:ho:um:am
793+ |= fud=meal :: interpret meal
794+ ^+ +>
795+ =. diz ?:(=(%none aut) diz (wast:diz ryn))
796+ (dine fud)
797+
798+Here, if the message was encrypted at all, then we call
799+`++wast:lax:as:go`, which simply updates the lane (route) to our
800+neighbor (unless we're given a provisional route). This ensures that we
801+always have the most direct possible path to them.
802+
803+We've been handling this meal for so long, we've almost forgotten what
804+we want to do with it. The telos is of any meal to be dined on. We will
805+choose out the cases here that are important to our current
806+investigation.
807+
808+ %fore
809+ =+ ^= lyn ^- lane
810+ ?~ q.fud ryn
811+ ?. ?=(%if -.u.q.fud) u.q.fud
812+ [%ix +.u.q.fud]
813+ :: u.q.fud
814+ ?: =(our p.fud)
815+ (emit %mead lyn r.fud)
816+ =+ zid=(myx:gus p.fud)
817+ (emir (wist:zid now xong:zid [~ lyn] r.fud))
818+
819+Forwarding is the simplest case, since we've seen all the arms before,
820+except perhaps `++emit` and `++emir`, which simply take a boon or list
821+of boons respectively and queue them up to be handled when the core
822+resolves. If we're told to forward a packet to ourselves, then we emit a
823+`%mead` boon which simply sends another `%hear` kiss to ourselves with
824+the data. Otherwise, we try to find a route to the recipient, as before.
825+
826+ %carp
827+ =+ zol=(~(get by olz.weg) s.fud)
828+ ?^ zol cock(kay u.zol)
829+ =^ neb nys.weg
830+ =+ neb=(~(get by nys.weg) s.fud)
831+ ?^ neb [u.neb nys.weg]
832+ =+ neb=`bait`[(kins p.fud) 0 r.fud ~]
833+ [neb (~(put by nys.weg) s.fud neb)]
834+ ?> (lth q.fud p.r.neb)
835+ ?> =((kins p.fud) p.neb)
836+ ?> =(r.fud p.r.neb)
837+ =+ doy=`(unit ,@)`(~(get by q.r.neb) q.fud)
838+ ?^ doy cock
839+ => ^+ . %= .
840+ q.r.neb (~(put by q.r.neb) q.fud t.fud)
841+ q.neb +(q.neb)
842+ ==
843+ :: ~& [%carp q.fud s.fud q.neb p.r.neb]
844+ ?: =(q.neb p.r.neb)
845+ =: nys.weg (~(del by nys.weg) s.fud)
846+ olz.weg (~(put by olz.weg) s.fud kay)
847+ ==
848+ (golf p.neb r.neb)
849+ =. +>.$ cock
850+ +>.$(nys.weg (~(put by nys.weg) s.fud neb))
851+
852+Here, we have received a partial message, and we're just assembling the
853+individual packets into a message. Most of this code is fairly
854+algorithmic, so we'll just hit the high points. In the beginning, we
855+check if we've already received this message, and if so, we resend the
856+acknowledgment. Remember, "always ack a dupe, never ack an ack".
857+
858+In `nys.weg` we keep track of an incoming set of partial packets,
859+indexed by the `flap` hash that comes with every packet. We check to see
860+if we have already received this partial message, and if so we
861+acknowledge it. Otherwise, we put it in `nys.weg` unless this is the
862+last message, in which case we ack the last partial message, move the
863+complete message into `olz.weg`, and call `++golf`, which assembles the
864+message and calls `++chew`, to start the dance again with the complete
865+message.
866+
867+ %bund
868+ :: ~& [%bund q.fud r.fud]
869+ ?> =(p:sen:gus p.fud)
870+ (deer q.fud r.fud ?-(kay %dead ~, %good [~ s.fud]))
871+
872+What if we're just receiving a regular old, garden variety message? We
873+call `++deer` with the data from the message. If we already know that
874+the message processing will fail (that is, if we got a `%hole` card from
875+unix rather than a `%hear` card), then we don't even send the data at
876+all. Remember, if a packet fails to process, it's as if it never even
877+arrived, except that we send a negative acknowledgment.
878+
879+ ++ deer :: deer:la:ho:um:am
880+ |= [cha=path num=@ud dut=(unit)] :: interpret message
881+ ^+ +>
882+ =+ rum=(fall (~(get by raz.bah) cha) *race)
883+ %= +>.$
884+ +>
885+ ?. (gte num did.rum) :: always ack a dup
886+ (cook (~(get by bum.rum) num) cha ~ ryn dam)
887+ ?: dod.rum
888+ (coat cha rum(mis (~(put by mis.rum) num [kay ryn dam dut])))
889+ %= +>.+>.$
890+ raz.bah
891+ %+ ~(put by raz.bah) cha
892+ rum(mis (~(put by mis.rum) num [kay ryn dam dut]))
893+ ==
894+ ==
895+
896+First, we get the race for this particular triple of sender, receiver,
897+and path, creating it if it doesn't exist. If we've already acked the
898+message, then we resend the ack. Note that `did.rum` is the number of
899+packets we acknowledged, positively or negatively while `bum.rum` is a
900+map of message numbers to negative acknowledgments. Thus, if a message
901+number is less than `did.rum`, then if it's in `bum.rum` then it was
902+negatively acknowledged, otherwise it's postively acknowledged. Thus, we
903+are constant in space with the number of successful messages and linear
904+in the number of failed messages. We'll document `++cook` later on, but
905+suffice it to say that it sends an acknowledgment. It is to end-to-end
906+acknowledgments what `++cock` is to packet-level acknowledgments.
907+
908+If we are still processing a message (that is, `dod.rum` is false), then
909+we simply put this message in the map of misordered packets to be
910+processed when their time comes. "Processing a message" in this case
911+means that we've received the message and notified the correct
912+application, but we're still waiting for the application-level
913+acknowledgment.
914+
915+Otherwise, we're ready for a packet, so we process it.
916+
917+ ++ coat :: coat:ho:um:am
918+ |= [cha=path rum=race] :: update input race
919+ ^+ +>
920+ =+ cun=(~(get by mis.rum) did.rum)
921+ ?~ cun
922+ +>.$(raz.bah (~(put by raz.bah) cha rum))
923+ ?. =(%good p.u.cun) +>.$
924+ ?> ?=(^ s.u.cun)
925+ %= +>.$
926+ raz.bah (~(put by raz.bah) cha rum(dod |))
927+ bin
928+ :_ bin
929+ :^ %mulk
930+ [our her]
931+ `soap`[[p:sen:gus clon:diz] cha did.rum]
932+ u.s.u.cun
933+ ==
934+
935+First, we grab the message we want to process and store it in `cun`. If
936+it's a good packet, then we change `dod.rum` to false, meaning that
937+we're in the middle of processing a packet and should not start
938+processing another one. We also put a `%mulk` boon into the queue so
939+that, when it all resolves, we send a mesage to the intended recipient
940+application. The boon contains the sender, the receiver, the identity of
941+the message, and the message itself.
942+
943+This bubbles up all the way back to `++knob`, where we were handling the
944+`%hear` card. Following the logic in `++knob`, we can see that the boons
945+get sent into `++clop` to be turned into actual arvo-level moves. We've
946+been here before, if you recall, when we handled the `%cake` boon to
947+send a message. Now, we're handling the `%mulk` boon, which is
948+unfortunately slightly more complicated.
949+
950+ %mulk
951+ :: ~& [%mulk p.bon q.bon]
952+ ?> ?=([@ @ *] q.q.bon)
953+ ?> ?=(%q i.q.q.bon)
954+ ?+ i.t.q.q.bon
955+ ~& %mulk-bad
956+ :_ fox
957+ :~ :- (claw p.p.bon)
958+ [%sick %wart p.bon i.t.q.q.bon t.t.q.q.bon r.bon]
959+ ==
960+ %ge :: %gall request
961+ ?> ?=([@ ~] t.t.q.q.bon)
962+ =+ app=`term`(need ((sand %tas) i.t.t.q.q.bon))
963+ =+ ^= pax
964+ :+ (scot %p p.p.bon)
965+ (scot %p q.p.bon)
966+ q.q.bon
967+ :_ fox [hen %pass pax %g %rote p.bon app r.bon]~
968+ %gh :: %gall response
969+ ?> ?=([@ ~] t.t.q.q.bon)
970+ =+ app=`term`(need ((sand %tas) i.t.t.q.q.bon))
971+ =+ ^= pax
972+ :+ (scot %p p.p.bon)
973+ (scot %p q.p.bon)
974+ q.q.bon
975+ :_ fox [hen %pass pax %g %roth p.bon app r.bon]~
976+ ==
977+
978+We're dispatching messages based on the prefix of their path. Since only
979+`%gall` apps use end-to-end acknowledgments at the moment, every path
980+must have at least two elements, and the first one must be `%q`. Beyond
981+that, we handle the `/q/ge` and `/q/gh` cases for gall requests and
982+responses, respectively.
983+
984+In both cases, we require the next term in the path to be the name of
985+the intended recipient `%gall` app. Thus, a message to `/q/ge/talk` for
986+example, will send a message to the talk app.
987+
988+We then send a message to the app itself. The message is either a
989+`%rote` or a `%roth` for a request and a response, respectively. The
990+content is the `rook` or `roon` that was sent (stored in `r.bon`), but
991+we don't actually handle that at all here. That's completely a
992+`%gall`-level thing. We're just the messenger.
993+
994+Notice the path we send this over. We encode the sender, the receiver,
995+and the path over which it was sent. This fully specifies the `race` so
996+that when the app gives us the acknowledgment we know where to send it.
997+
998+We now have another interlude. We have entrusted our precious data, so
999+carefully guarded and guided from the app on that far-away ship, to our
1000+local app. It has the ability to do whatever it pleases with it. It may
1001+take a significant amount of time to process. When the message has been
1002+handled by this app, though, it must produce an acknowledgment. Our
1003+final task is to deliver this acknowledgment to the sending app.
1004+
1005+We should describe here what exactly these oft-mentioned acknowledgments
1006+actually consist of. There are two kinds of acknowledgments: positive
1007+and negative. A positive acknowledgment contains no data other than its
1008+existence. A negative acknowledgment may optionally include a reason for
1009+said negativity. Formally, a negative acknowledgment is an `ares`, which
1010+is a unit pair of a term and a list of tanks. If this is null, this is
1011+simply a failure with no associated information. If the pair exists, the
1012+term is a short error code that is usually both human and computer
1013+readable. For example, if you try to send a message to a valid `%gall`
1014+app that doesn't have any `++poke` to handle it, then `%gall` will give
1015+a negative acknowledgment with error term `%poke-find-fail`. The list of
1016+tanks is a human-readable description of the error. This often contains
1017+a stack trace. At any rate, all this information is returned to the
1018+sending app on the other end of the wire.
1019+
1020+After this brief interlude, our story resumes in `++knap`, where we
1021+receive responses. In particular, a `%mean` indicates a negative
1022+acknowledgment while a `%nice` indicates a positive acknowledgment.
1023+
1024+ ?(%mean %nice)
1025+ ?> ?=([@ @ @ *] tea)
1026+ =+ soq=[(slav %p i.tea) (slav %p i.t.tea)]
1027+ =+ pax=t.t.tea
1028+ =+ ^= fuy
1029+ =< zork =< zank
1030+ %^ ~(rack am [now fox]) soq pax
1031+ ?-(+<.sih %mean `p.+.sih, %nice ~)
1032+ => %_(. fox q.fuy)
1033+ =| out=(list move)
1034+ |- ^- [p=(list move) q=_+>.^$]
1035+ ?~ p.fuy
1036+ [(flop out) +>.^$]
1037+ =^ toe fox (clop now hen i.p.fuy)
1038+ $(p.fuy t.p.fuy, out (weld (flop toe) out))
1039+
1040+Recall the format of the path we sent the message on, and you'll
1041+understand why `soq` and `pax` are the sender/receiver pair and path on
1042+which the message was sent. The rest of this is structured much like
1043+`++knob`, so we call `++rack:am` and send the resulting boons to
1044+`++clop`. Business as usual.
1045+
1046+ ++ rack :: rack:am
1047+ |= [soq=sock cha=path cop=coop] :: e2e ack
1048+ =+ oh=(ho:(um p.soq) q.soq)
1049+ =. oh (cook:oh cop cha ~)
1050+ (cans:oh cha)
1051+
1052+First, we set up `++um` and `++ho`, as we've done twice before, for our
1053+domestic and foreign servers, respectively. The other two things are
1054+new, though. Well, `++cook` is not actually new, but we delayed the
1055+explanation saying only that it sends an acknowledgment. The time has
1056+come.
1057+
1058+ ++ cook :: cook:ho:um:am
1059+ |= [cop=coop cha=path ram=(unit ,[ryn=lane dam=flap])]
1060+ ^+ +> :: acknowledgment
1061+ =+ rum=(need (~(get by raz.bah) cha))
1062+ =+ lat=(~(get by mis.rum) did.rum)
1063+ ?: &(?=(~ lat) ?=(~ ram)) ~&(%ack-late-or-redundant +>.$)
1064+ =+ ^- [ryn=lane dam=flap]
1065+ ?^ ram [ryn.u.ram dam.u.ram]
1066+ ?< ?=(~ lat)
1067+ [q r]:u.lat
1068+ =. raz.bah
1069+ ?^ ram raz.bah
1070+ %+ ~(put by raz.bah) cha
1071+ rum(dod &, bum ?~(cop bum.rum (~(put by bum.rum) did.rum u.cop)))
1072+ =^ roc diz (zuul:diz now [%buck cop dam ~s0])
1073+ (busk(diz (wast:diz ryn)) xong:diz roc)
1074+
1075+If we are acknowledging a message that we have already acked, the `ram`
1076+will contain the new lane and flap to send the duplicate ack to. This
1077+happens if we call `++cook` in `++deer`, but it doesn't happen from
1078+`++rack`. If there is no message waiting to be acknowledged and we're
1079+not given an explicit lane and flap (that is, we're not sending a
1080+duplicate ack), then the app must have sent us multiple acknowledgments.
1081+We do the only sensible thing we can do and drop all acknowledgments
1082+after the first, printing a message. This is, in fact, an error, so it
1083+could be argued that we ought to crash. Whatever you do, don't depend on
1084+this not crashing.
1085+
1086+First, we grab the race specified by the given path, and we get the most
1087+recent in-order message, which must be the one which is being
1088+acknowledged.
1089+
1090+Then, we decide which lane/flap to respond on/to. Basically, in the
1091+usual case we respond on the lane through which the initial message was
1092+sent, which is stored along with the other packet information in
1093+`mis.rum`, since it has to be remembered across calls to ames. However,
1094+if we receive a duplicate message, then we must respond to the new
1095+message. It's quite possible the reason the other acknowledgment didn't
1096+get returned was that the lane between the ships was broken.
1097+
1098+At any rate, we update the race by saying that we've finished processing
1099+this packet (unless we're sending a duplicate ack) and, if we're sending
1100+a negative acknowledgment, putting the negative ack into `bum.rum` so
1101+that we can resend it if necessary.
1102+
1103+We encode our new message, updating the packet pump, with `++zuul`, as
1104+before, and we send it off with `++busk`, routed via `++wast` to one of
1105+the ships in `++xong`. Of course, in practice, we don't even look at the
1106+ships in `++xong` because we already have a lane directly to our
1107+neighbor (the one over which they sent their message to us).
1108+
1109+We glossed over the actual message we're sending back. We're sending a
1110+`%buck` meal, which is an acknowledgment. The `cop` specifies whether
1111+this is a positive or a negative ack, `dam` specifies the message we're
1112+acknowledging, and the `~s0` is a placeholder for the processing time
1113+required. This time is neither calculated (though it is hopefully
1114+obvious how to do so) nor used at present, but this information may be
1115+used in the future for improved congestion control. Since the round-trip
1116+time for an end-to-end acknowledged packet includes the processing time
1117+on the other end, most common congestion control algorithms will stumble
1118+when some messages take much longer to process than others. As noted,
1119+though, this is simply an opportunity for improvement -- our congestion
1120+control algorithms are relatively naive at the moment.
1121+
1122+Recall that `++busk` calls `++wist` to put the actual `%ouzo` boon in
1123+the queue, which gets handled by `++clop` to actually send the message.
1124+This is the same pipeline as sending any other message, so we'll refer
1125+you to the explanation above if you've forgotten it.
1126+
1127+The last thing we need to do on this ship is move on to the next packet
1128+in the queue if there is one. If you recall, in `++rack` after the call
1129+to `++cook` there was a call to `++cans:ho:um:am`.
1130+
1131+ ++ cans :: cans:ho:um:am
1132+ |= cha=path
1133+ =+ rum=(need (~(get by raz.bah) cha))
1134+ =. rum
1135+ %= rum
1136+ did +(did.rum)
1137+ mis (~(del by mis.rum) did.rum)
1138+ ==
1139+ (coat cha rum)
1140+
1141+This is very simple. We increment the number of packets that we've
1142+acknowledged on this race and we delete the packet that we just
1143+acknowledged from the set of misordered packets.
1144+
1145+Then, we call `++coat` again to process the next packet if we've already
1146+received it. And that's it for this.
1147+
1148+The acknowledgment now travels the same path that its forebearer, the
1149+original message, once tread, but this time not into the great unknown.
1150+The weary traveler is seeking out its familial roots, finding the app
1151+from whom sprung forth the original message way back in paragraph three.
1152+When it arrives at the network adapter of its ancestors, the adapter
1153+tells unix, unix tells libuv, libuv tells vere, and vere sends a `%hear`
1154+kiss to ames. Once more into the kernel.
1155+
1156+The `%hear` kiss is handled in `++knob` as before, leading to `++gnaw`,
1157+going over to `++chew`, `++apse`, `++chow`, and eventualy to `++dine`.
1158+We've seen most of the cases in `++dine`, but we haven't yet looked at
1159+the handling of this `%buck` meal.
1160+
1161+ %buck
1162+ =. +> ?.(=(%full aut) +> cock) :: finish key exch
1163+ +>(..la (tock p.fud q.fud r.fud))
1164+
1165+We send a packet level acknowledgment if we're finishing a key exchange,
1166+else we call `++tock` to process the acknowledgment.
1167+
1168+This will get a little involved, so if you don't much care about how
1169+exactly an acknowledgment happens, just know that the result gets gifted
1170+as a `%woot` card back to the app who sent it. For those brave souls who
1171+wish to see this thing through to the end, it's once more into the
1172+breach.
1173+
1174+ ++ tock :: tock:ho:um:am
1175+ |= [cop=coop fap=flap cot=@dr] :: e2e ack by hash
1176+ ^+ +>
1177+ =^ yoh puz (bick:puz now fap)
1178+ =. +>.$
1179+ ?~ p.yoh +>.$
1180+ =^ hud +>.$
1181+ (done p.u.p.yoh q.u.p.yoh)
1182+ ?~ hud +>.$
1183+ %= +>.$
1184+ bin
1185+ :_ bin
1186+ `boon`[%cake [our her] [[p:sen:gus clon:diz] u.p.yoh] cop u.hud]
1187+ ==
1188+ (busk xong:diz q.yoh)
1189+
1190+We're going to work through this one a little backwards since it's
1191+mostly fairly simple except the call to `++bick:pu`. In fact, we'll just
1192+skip `++bick` for the moment and finish the rest.
1193+
1194+If `++bick` succesfully acks the message, then we call `++done`.
1195+
1196+ ++ done :: done:ho:um:am
1197+ |= [cha=path num=@ud] :: complete outgoing
1198+ ^- [(unit duct) _+>]
1199+ =+ rol=(need (~(get by ryl.bah) cha))
1200+ =+ rix=(~(get by san.rol) num)
1201+ ?~ rix [~ +>.$]
1202+ :- rix
1203+ %_ +>.$
1204+ ryl.bah
1205+ (~(put by ryl.bah) cha rol(san (~(del by san.rol) num)))
1206+ ==
1207+
1208+This very simply gets the rill (the outgoing counterpart to a race, if
1209+you recall), pulls out of the map of outstanding messages the duct over
1210+which the original message was sent, and produces this duct while
1211+deleting that entry from the map of outstanding messages.
1212+
1213+Going back to `++tock`, we now have the duct we need to return the
1214+result over. We do the very sensible thing and put a `%cake` boon in the
1215+queue to be processed later by `++clop`.
1216+
1217+In `q.yoh` we have a list of messages that may need to be sent, which we
1218+pass to `++busk` to send, as usual. When an acknowledgment arrives, that
1219+may trigger other messages immediately. This often happens when sending
1220+more messages than the width of the logical window since for congestion
1221+control reasons another message cannot be sent until some of the earlier
1222+ones have been acknowledged.
1223+
1224+We'll look at the processing of the `%cake` boon in `++clop` before we
1225+get back to talking about `++bick`.
1226+
1227+ %cake
1228+ :_ fox
1229+ :~ [s.bon %give %woot q.p.bon r.bon]
1230+ ==
1231+
1232+We very simply give, along the duct we found above, a `%woot` card with
1233+the ship who sent us the ack and the ack itself. This allows the
1234+application to decide what to do about the result. In case of a failure,
1235+we usually either resend the message or display it to the user.
1236+Sometimes, we recognize the error term and handle it internally. In any
1237+case, the decision of how to handle the acknowledgment is entirely up to
1238+the application. Our job is done.
1239+
1240+Well, except that we skipped `++bick:pu`. Let's go back to that.
1241+
1242+ ++ bick :: bick:pu
1243+ |= [now=@da fap=flap] :: ack by hash
1244+ ^- [[p=(unit soup) q=(list rock)] _+>]
1245+ =+ sun=(~(get by diq) fap)
1246+ ?~ sun
1247+ [[~ ~] +>.$]
1248+ =. diq (~(del by diq) fap)
1249+ =^ gub +>.$ (bock now u.sun)
1250+ =^ yop +>.$ (harv now)
1251+ [[gub yop] +>.$]
1252+
1253+If you recall, in `++whap:pu` we created the packet pump's
1254+representation of the message, which included putting the message into
1255+`diq`, which maps from packet hashes to packet sequence numbers. Thus,
1256+`u.sun` is the sequence number of this particular message.
1257+
1258+We delete this message from `diq` since we have now received an ack for
1259+it. We call `++bock` to perform the ack by sequence number. We call
1260+`++harv` to harvest the packet queue, sending any messages that are now
1261+able to be sent.
1262+
1263+In `++bock`, there are three arms we haven't seen before: `++bine`,
1264+`+wept`, and `++beet`. We'll describe each of these before we get to
1265+`++bock`. `++bine` looks scariest.
1266+
1267+ ++ bine :: bine:pu
1268+ |= [now=@da num=@ud] :: apply ack
1269+ ^- [(unit soup) _+>]
1270+ ?~ puq !!
1271+ ?. =(num p.n.puq)
1272+ ?: (gth num p.n.puq)
1273+ =+ lef=$(puq l.puq)
1274+ [-.lef +.lef(puq [n.puq puq.lef r.puq])]
1275+ =+ rig=$(puq r.puq)
1276+ [-.rig +.rig(puq [n.puq l.puq puq.rig])]
1277+ =: rtt ?. &(liv.q.n.puq =(1 nux.q.n.puq)) rtt
1278+ =+ gap=(sub now lys.q.n.puq)
1279+ :: ~& [%bock-trip num (div gap (div ~s1 1.000))]
1280+ (div (add (mul 2 rtt) gap) 3)
1281+ nif (sub nif !liv.q.n.puq)
1282+ ==
1283+ =+ lez=(dec (need (~(get by pyz) gom.q.n.puq)))
1284+ =^ gub pyz
1285+ ?: =(0 lez)
1286+ [[~ gom.q.n.puq] (~(del by pyz) gom.q.n.puq)]
1287+ [~ (~(put by pyz) gom.q.n.puq lez)]
1288+ :- gub
1289+ +>.$(puq ~(nap to puq))
1290+
1291+The first few lines are simply looking through the packet queue until we
1292+find the correct packet to ack. This is basic queue manipulation that
1293+operates directly on the treap structure of the queue. If you understand
1294+treap queues, the logic is easy to follow. Otherwise, just trust us that
1295+by the time we get to the `=:`, the packet with sequence number `num` is
1296+on the top of the packet queue (that is, at `n.puq`).
1297+
1298+We first update the round-trip time. If the packet is either not alive
1299+or had to be transmitted more than once, then we don't have any reliable
1300+way of calculating the round-trip time since we're unsure of exactly
1301+which transmission was acknowledged. Otherwise, the round-trip time is
1302+the difference between now and when the packet was last sent. We set
1303+`rtt` by a little weighted average where the previous smoothed RTT is
1304+weighted twice as much as the RTT of the current packet. Thus,
1305+`(2*rtt+gap)/3`. This gives us a nice smooth RTT that is somewhat
1306+resilient to outlier data while still being responsive to our
1307+ever-changing world.
1308+
1309+If the packet wasn't already dead, then we decrement the number of live
1310+packets, which may allow more packets to be sent.
1311+
1312+We decrement the number of unacknowledged packets in our `pyz` for this
1313+particular message. If you recall, this was set in `++whap` to the
1314+number of packets required to send a message.
1315+
1316+If that was the last packet in the messge that needed to be acked, then
1317+we delete the messgae reference from `pyz` and produce the id of the
1318+message. Otherwise, we simply update `pyz` with the new number of
1319+unacked messages. In either case, we remove the packet from the packet
1320+queue.
1321+
1322+ ++ wept :: wept:pu
1323+ |= [fip=@ud lap=@ud] :: fip thru lap-1
1324+ =< abet =< apse
1325+ |%
1326+ ++ abet +>.$
1327+ ++ apse
1328+ ^+ .
1329+ ?~ puq .
1330+ ?: (lth p.n.puq fip) ?~(l.puq . left)
1331+ ?: (gte p.n.puq lap) ?~(r.puq . rigt)
1332+ => rigt =< left
1333+ ?> ?=(^ puq)
1334+ ?.(liv.q.n.puq . .(nif (dec nif), liv.q.n.puq |))
1335+ ::
1336+ ++ left
1337+ ?> ?=(^ puq)
1338+ ^+(. =+(lef=apse(puq l.puq) lef(puq [n.puq puq.lef r.puq])))
1339+ ++ rigt
1340+ ?> ?=(^ puq)
1341+ ^+(. =+(rig=apse(puq r.puq) rig(puq [n.puq l.puq puq.rig])))
1342+ --
1343+
1344+The algorithm is a simple case of traversing the packet queue.
1345+Essentialy, we mark as dead all packets in the queue between `fip` and
1346+`(dec lap)`. We also update `nif`, the number of live packets. Lest you
1347+mourn too much the passing of these packets, know that they shall soon
1348+rise again. Recall that in `++bick` after the call to `++bock` we call
1349+`++harv`. This will resend the packets that have just been labeled dead.
1350+
1351+ ++ beet :: beet:pu
1352+ ^+ . :: advance unacked
1353+ =- +(nep ?~(foh nus u.foh))
1354+ ^= foh
1355+ |- ^- (unit ,@ud)
1356+ ?~ puq ~
1357+ ?: (lte p.n.puq nep) $(puq l.puq)
1358+ =+ rig=$(puq r.puq)
1359+ ?^(rig rig [~ p.n.puq])
1360+
1361+Here we search for the next expected packet number. Basically, we search
1362+the queue for the leftmost packet whose number is greater than the
1363+current `nep`. If we don't find any such packet, we just use the total
1364+number of packets sent.
1365+
1366+We can now dive into `++bock`, our last arm.
1367+
1368+ ++ bock :: bock:pu
1369+ |= [now=@da num=@ud] :: ack by sequence
1370+ ^- [(unit soup) _+>]
1371+ =^ gym +> (bine now num)
1372+ :- gym
1373+ ?: (gth num nep)
1374+ =+ cam=(max 2 (div caw 2))
1375+ :: ~& [%bock-hole num nep cam]
1376+ beet:(wept(nep num, cag cam, caw cam) nep num)
1377+ =. caw ?: (lth caw cag) +(caw)
1378+ (add caw !=(0 (mod (mug now) caw)))
1379+ ?: =(num nep)
1380+ :: ~& [%bock-fine num nif caw cag]
1381+ beet
1382+ :: ~& [%bock-fill num nif caw cag]
1383+ +>.$
1384+
1385+First, we call `++bine` to apply the ack to the packet pump information.
1386+We produce `gym`, which, if it exists, is the id of the packet that was
1387+acked. If we received an ack for a packet later than the one we
1388+expected, then we halve the logical packet window and kill all the
1389+earlier packets so that they may be resent.
1390+
1391+Otherwise, we possibly increase the congestion window. If the window is
1392+less than the congestion threshold, then we increment the size of the
1393+window. Otherwise, we only increment one out of every `caw` times.
1394+
1395+If we received an ack for the packet we expected, then we simply advance
1396+`nep` with `++beet`. If we received an ack for a packet earlier than we
1397+expected, we do nothing.
1398+
1399+It may be hard to believe, but we are, in fact, done. The message has
1400+been sent, received, acknowledged, and the acknowledgment has been
1401+returned to the original sender. We hope it's clear that, while the
1402+process has been somewhat involved, the algorithms are not all that
1403+complicated. If you've read this far, you know `%ames`. The only other
1404+code involves initialization, timeouts, and the like.
1405+
1406+Below, we give detailed reference documentation for the data models
1407+involved.
1408+
1409+Data Models
1410+-----------
1411+
1412+### `++fort`, formal state
1413+
1414+ ++ fort :: formal state
1415+ $: %0 :: version
1416+ gad=duct :: client interface
1417+ hop=@da :: network boot date
1418+ ton=town :: security
1419+ zac=(map ship corn) :: flows by server
1420+ == ::
1421+
1422+This is the state of our vane. Anything that must be remembered between
1423+calls to ames must be stored in this state.
1424+
1425+`%0` is the version of the ames state model itself. If the data model
1426+`++fort` changes, then this number needs to be incremented, and an
1427+adapter must be written to upgrade the old state into the new state.
1428+Note that this is the version number of the model itself, not the
1429+contents. When the data changes, there is of course no need to change
1430+this.
1431+
1432+`gad` is a `duct` over which we send `%send` cards to unix. This card is
1433+initialized when unix sends a `%barn` card as vere starts up. Vere
1434+treats this duct specially -- don't send anything weird over it.
1435+
1436+`hop` is the network boot date. This is set when the `%kick` card is
1437+sent by vere on start up.
1438+
1439+`ton` is a `++town`, where we store all of our security/encryption
1440+state. Note that this is shared across all ships on a pier.
1441+
1442+`zac` is a map of ships to `++corn`. This stores all the per-ship state.
1443+The keys to this map are the ships on the current pier.
1444+
1445+### `++town`, all security state
1446+
1447+ ++ town :: all security state
1448+ $: lit=@ud :: imperial modulus
1449+ any=@ :: entropy
1450+ urb=(map ship sufi) :: all keys and routes
1451+ fak=? ::
1452+ == ::
1453+
1454+This is the security state of our pier.
1455+
1456+`lit` is unused.
1457+
1458+`any` is 256 bits of entropy. This entropy is used and updated in
1459+exactly two places: when we send a `%junk` card, and when we generate a
1460+new symmetric key in `++griz:lax:as:go`. When it is updated, it is
1461+updated by a SHA-256 hash of the current time and the old value of the
1462+entropy.
1463+
1464+`urb` is a map of ships to `++sufi`. This is where we store all the
1465+per-ship state for the pier. The keys to this map are the ships on the
1466+current pier.
1467+
1468+`fak` is true if we are on a fake network. This disables certain
1469+security checks so that anyone may run a fake `~zod`. This is used only
1470+for development. To use, run vere with the `-F` option (and the
1471+`-I ~zod` option for a fake `~zod`).
1472+
1473+### `++sufi`, domestic host
1474+
1475+ ++ sufi :: domestic host
1476+ $: hoy=(list ship) :: hierarchy
1477+ val=wund :: private keys
1478+ law=will :: server will
1479+ seh=(map hand ,[p=ship q=@da]) :: key cache
1480+ hoc=(map ship dore) :: neighborhood
1481+ == ::
1482+
1483+This is the security state of a domestic server.
1484+
1485+`hoy` is a list of the ships directly above us in the hierarchy of
1486+ships. For example, for `~hoclur-bicrel`, this would be `~tasruc` and
1487+`~tug`. See `++sein`.
1488+
1489+`val` is a list of our private keys.
1490+
1491+`law` is our certificate, which is a list of the XXX
1492+
1493+`seh`
1494+
1495+`hoc` is a map of ships to `++dore`. The stores all the security
1496+informatoin about foreign ships. The keys to this map are the neighbors
1497+(ships we have been in contact with) of this domestic server.
1498+
1499+### `++wund`, private keys
1500+
1501+ ++ wund (list ,[p=life q=ring r=acru]) :: mace in action
1502+
1503+This is a list of our own private keys, indexed by life. The key itself
1504+is the `++ring`, and the `++acru` is the encryption engine. We generate
1505+the `++acru` from the private key by calling `++weur`. Thus, we can at
1506+any time regenerate our `++wund` from a `++mace`. The current crypto is
1507+at the head of the list and can be accessed with `++sen:as:go`.
1508+
1509+### `++ring`, private key
1510+
1511+ ++ ring ,@ :: private key
1512+
1513+This is a private key. The first byte is reserved to identify the type
1514+of cryptography. Lower-case means public key, upper-case means public
1515+key, and the letter identifies which `++acru` to use.
1516+
1517+### `++pass`, public key
1518+
1519+ ++ pass ,@ :: public key
1520+
1521+This is a public key. The first byte is reserved to identify the type of
1522+cryptography. Lower-case means public key, upper-case means public key,
1523+and the letter identifies which `++acru` to use.
1524+
1525+### `++mace`, private secrets
1526+
1527+ ++ mace (list ,[p=life q=ring]) :: private secrets
1528+
1529+This is a list of the our private keys, indexed by life. From this we
1530+can generate a `++wund` for actual use.
1531+
1532+### `++skin`, encoding stem
1533+
1534+ ++ skin ?(%none %open %fast %full) :: encoding stem
1535+
1536+This defines the type of encryption used for each message. `%none`
1537+refers to messages sent in the clear, `%open` refers to signed messages,
1538+`%full` refers to sealed messages, and `%fast` refers to symmetrically
1539+encrypted messages. See `++acru` for details.
1540+
1541+### `++acru`, asymmetric cryptosuite
1542+
1543+ ++ acru :: asym cryptosuite
1544+ $_ ^? |% :: opaque object
1545+ ++ as ^? :: asym ops
1546+ |% ++ seal |=([a=pass b=@ c=@] _@) :: encrypt to a
1547+ ++ sign |=([a=@ b=@] _@) :: certify as us
1548+ ++ sure |=([a=@ b=@] *(unit ,@)) :: authenticate from us
1549+ ++ tear |= [a=pass b=@] :: accept from a
1550+ *(unit ,[p=@ q=@]) ::
1551+ -- ::
1552+ ++ de |+([a=@ b=@] *(unit ,@)) :: symmetric de, soft
1553+ ++ dy |+([a=@ b=@] _@) :: symmetric de, hard
1554+ ++ en |+([a=@ b=@] _@) :: symmetric en
1555+ ++ ex ^? :: export
1556+ |% ++ fig _@uvH :: fingerprint
1557+ ++ pac _@uvG :: default passcode
1558+ ++ pub *pass :: public key
1559+ ++ sec *ring :: private key
1560+ --
1561+ ++ nu ^? :: reconstructors
1562+ |% ++ pit |=([a=@ b=@] ^?(..nu)) :: from [width seed]
1563+ ++ nol |=(a=@ ^?(..nu)) :: from naked ring
1564+ ++ com |=(a=@ ^?(..nu)) :: from naked pass
1565+ --
1566+ --
1567+
1568+This is an opaque interface for a general asymmetric cryptosuite. Any
1569+form of asymmetric cryptography can be dropped in to be used instead of
1570+the default. Right now, there are two cryptosuites, `++crua`, which is
1571+your standard RSA, and `++crub`, which is elliptic curve crypto but is
1572+mostly stubbed out at the moment.
1573+
1574+#### `++as:acru`, asymmetric operations
1575+
1576+ ++ as ^? :: asym ops
1577+ |% ++ seal |=([a=pass b=@ c=@] _@) :: encrypt to a
1578+ ++ sign |=([a=@ b=@] _@) :: certify as us
1579+ ++ sure |=([a=@ b=@] *(unit ,@)) :: authenticate from us
1580+ ++ tear |= [a=pass b=@] :: accept from a
1581+ *(unit ,[p=@ q=@]) ::
1582+ -- ::
1583+
1584+This is the core that defines the standard asymmetric cryptography
1585+operations.
1586+
1587+`++seal:as:acru` allows us to send a message encrypted with someone's
1588+public key so that only they may read it. If Alice seals a message with
1589+Bob's public key, then she can be sure that Bob is the only one who can
1590+read it. This is associated with the `++skin` `%full`.
1591+
1592+`++sign:as:acru` allows us to sign a message with our private key so
1593+that others can verify that we sent the message. If Alice signs a
1594+message with her private key, then Bob can verify with her public key
1595+that it was indeed Alice who sent it. This is associated with the
1596+`++skin` `%open`.
1597+
1598+`++sure:as:acru` is the dual to `++sign:as:acru`. It allows us to verify
1599+that a message we have received is indeed from the claimed sender. If
1600+Alice sends a message with her private key, then Bob can use this arm to
1601+verify that it was indeed Alice who sent it. This is associated with the
1602+`++skin` `%open`.
1603+
1604+`++tear:as:acru` is the dual to `++seal:as:acru`. It allows us to read a
1605+message that we can be sure is only read by us. If Alice seals a message
1606+with Bob's public key, then Bob can use this arm to read it. This is
1607+associated with the `++skin` `%full`.
1608+
1609+#### `++de:acru`, `++dy:acru`, and `++en:acru`, symmetric encryption/decryption
1610+
1611+ ++ de |+([a=@ b=@] *(unit ,@)) :: symmetric de, soft
1612+ ++ dy |+([a=@ b=@] _@) :: symmetric de, hard
1613+ ++ en |+([a=@ b=@] _@) :: symmetric en
1614+
1615+Symmetric encryption is associated with the `++skin` `%fast`.
1616+
1617+`++de:acru` decrypts a message with a symmetric key, returning `~` on
1618+failure and `[~ u=data]` on success.
1619+
1620+`++dy:acru` decrypts a message with a symmetric key, crashing on
1621+failure. This should almost always be defined as, and should always be
1622+semantically equivalent to, `(need (de a b))`.
1623+
1624+`++en:acru` encrypts a message with a symmetric key.
1625+
1626+#### `++ex:acru`, exporting data
1627+
1628+ ++ ex ^? :: export
1629+ |% ++ fig _@uvH :: fingerprint
1630+ ++ pac _@uvG :: default passcode
1631+ ++ pub *pass :: public key
1632+ ++ sec *ring :: private key
1633+ --
1634+
1635+`++fig:ex:acru` is our fingerprint, usually a hash of our public key.
1636+This is used, for example, in `++zeno`, where every carrier owner's
1637+fingerprint is stored so that we can ensure that carriers are indeed
1638+owned by their owners
1639+
1640+`++pac:ex:acru` is our default passcode, which is unused at present.
1641+
1642+`++pub:ex:acru` is the `++pass` form of our public key.
1643+
1644+`++sec:ex:acru` is the `++ring` form of our private key.
1645+
1646+#### `++nu:acru`, reconstructors
1647+
1648+ ++ nu ^? :: reconstructors
1649+ |% ++ pit |=([a=@ b=@] ^?(..nu)) :: from [width seed]
1650+ ++ nol |=(a=@ ^?(..nu)) :: from naked ring
1651+ ++ com |=(a=@ ^?(..nu)) :: from naked pass
1652+ --
1653+
1654+These arms allow us to reconstruct a `++acru` from basic data.
1655+
1656+`++pit:nu:acru` constructs a `++acru` from the width of our intended key
1657+and seed entropy. This is usually used in the initial construction of
1658+the `++acru`.
1659+
1660+`++nol:nu:acru` constructs a `++acru` from a "naked ring", meaning a
1661+`++ring` without the initial byte identifying the type of crypto. There
1662+is often a helper arm that that wraps this; see `++weur` for `++crua`
1663+and `++wear` for `++crub`.
1664+
1665+`++com:nu:acru` constructs a `++acru` from a "naked pass", meaning a
1666+`++ring` without the initial byte identifying the type of crypto. There
1667+is often a helper arm that that wraps this; see `++haul` for `++crua`
1668+and `++hail` for `++crub`.
1669+
1670+### `++will`, certificate
1671+
1672+ ++ will (list deed) :: certificate
1673+
1674+This is a list of deeds associated with the current ship. There should
1675+be an item in this list for every ship from this point up in the
1676+hierarchy times the number of lives that each ship has had. For example,
1677+\~hoclur-bicrel may have a will with three items: one for itself, one
1678+for \~tasruc (who issued \~hoclur-bicrel's deed) and one for \~tug (who
1679+issued \~tasruc's deed).
1680+
1681+### `++deed`, identity
1682+
1683+ ++ deed ,[p=@ q=step r=?] :: sig, stage, fake?
1684+
1685+`p` is the signature of a particular deed, which is a signed copy of
1686+`q`.
1687+
1688+`q` is the stage in the identity.
1689+
1690+`r` is true if we're working on a fake network, where we don't check
1691+that the carrier fingerprints are correct. This allows us to create fake
1692+networks for development without interfering with the real network.
1693+
1694+### `++step`, identity stage
1695+
1696+ ++ step ,[p=bray q=gens r=pass] :: identity stage
1697+
1698+This is a single stage in our identity. Thus, this is specific to a
1699+single life in a single ship. Everything in here may change between
1700+lives.
1701+
1702+`p`
1703+
1704+`q`
1705+
1706+`r` is the public key for this stage in the identity.
1707+
1708+### `++bray`
1709+
1710+ ++ bray ,[p=life q=(unit life) r=ship s=@da] :: our parent us now
1711+
1712+XXX
1713+
1714+### `++gens`, general identity
1715+
1716+ ++ gens ,[p=lang q=gcos] :: general identity
1717+
1718+`p` is the IETF language code for the preferred language of this
1719+identity. This is unused at the moment, but in the future text should be
1720+localized based on this.
1721+
1722+`q` is the description of the ship.
1723+
1724+### `++gcos`, identity description
1725+
1726+ ++ gcos :: id description
1727+ $% [%czar ~] :: 8-bit ship
1728+ [%duke p=what] :: 32-bit ship
1729+ [%earl p=@t] :: 64-bit ship
1730+ [%king p=@t] :: 16-bit ship
1731+ [%pawn p=(unit ,@t)] :: 128-bit ship
1732+ == ::
1733+
1734+This is the description of the identity of a ship. Most types of
1735+identity have a `@t` field, which is their human-readable name. The
1736+identity of a `%duke` is more involved.
1737+
1738+A `%czar`, a carrier, is a ship with an 8-bit address. Thus, there are
1739+only 256 carriers. These are at the top of the namespace hierarchy, and
1740+the fingerprint of each carrier is stored in `++zeno`. These are the
1741+"senators" of Urbit.
1742+
1743+A `%king`, a cruiser, is a ship with a 16-bit address. Thus, there are
1744+65,536 cruisers. Each carrier may issue 256 cruisers. These are the
1745+infrastructure of Urbit.
1746+
1747+A `%duke`, a destroyer, is a ship with a 32-bit address. Thus, there are
1748+4,294,967,296 destroyers. Each cruiser may issue 65,536 cruisers. These
1749+are the individuals of Urbit.
1750+
1751+A `%earl`, a yacht, is a ship with a 64-bit address. Thus, there are
1752+18,446,744,073,709,551,616 yachts. Each destroyer may issue
1753+4,294,967,296 yachts. These are the devices of Urbit.
1754+
1755+A `%pawn`, a submarine, is a ship with a 128-bit address. Thus, there
1756+are a lot of submarines. The chance of random name collision is
1757+negligible, so submarines are not issued by any ship. They must simply
1758+assert their presence, and they are all considered children of \~zod.
1759+This is the underworld of Urbit, where anonymity reigns supreme.
1760+
1761+### `++what`, logical destroyer identity
1762+
1763+ ++ what :: logical identity
1764+ $% [%anon ~] :: anonymous
1765+ [%lady p=whom] :: female person ()
1766+ [%lord p=whom] :: male person []
1767+ [%punk p=sect q=@t] :: opaque handle ""
1768+ == ::
1769+
1770+This is the logical identity of a destroyer.
1771+
1772+A `%anon` is a completely anonymous destroyer. The difference between
1773+this and a submarine is that a submarine is ephemeral while a `%anon`
1774+destroyer is not. Thus, we may not know who \~hoclur-bicrel is, but we
1775+do know that it's always the same person.
1776+
1777+A `%lady` is a female person. The name used here should be a real name.
1778+
1779+A `%lord` is a male person. The name used here should be a real name.
1780+
1781+A `%punk` is a person who is identified only by a handle.
1782+
1783+### `++whom`, real person
1784+
1785+ ++ whom ,[p=@ud q=govt r=sect s=name] :: year/govt/id
1786+
1787+Ths is the information associated with a real person. It is mostly
1788+information that could be observed with the briefest of interactions.
1789+
1790+`p` is the birth year.
1791+
1792+`q` is the location of a user, usually of the form "country/zip".
1793+
1794+`r` is the sect of the user.
1795+
1796+`s` is the real name of the person.
1797+
1798+### `++govt`
1799+
1800+ ++ govt path :: country/postcode
1801+
1802+This is the location of the user, usually of the form "country/zip".
1803+
1804+### `++sect`
1805+
1806+ ++ sect ?(%black %blue %red %orange %white) :: banner
1807+
1808+XXX
1809+
1810+### `++name`
1811+
1812+ ++ name ,[p=@t q=(unit ,@t) r=(unit ,@t) s=@t] :: first mid/nick last
1813+
1814+This is the given name, possible middle name/initial, possible nickname,
1815+and surname of a user.
docs/system/arvo/arvo.mdnew file+8
@@ -0,0 +1,8 @@
1+<div class="short">
2+
3+`%arvo`
4+=======
5+
6+Our operating system.
7+
8+</div>
docs/system/arvo/arvo/commentary.mdnew file+4
@@ -0,0 +1,4 @@
1+`%arvo` commentary
2+==================
3+
4+`%arvo` is our operating system.
docs/system/arvo/clay.mdnew file+27
@@ -0,0 +1,27 @@
1+<div class="short">
2+
3+`%clay`
4+=======
5+
6+Our filesystem.
7+
8+`%clay` is version-controlled, referentially-transparent, and global.
9+While this filesystem is stored in `%clay`, it is mirrored to Unix for
10+convenience. Unix tells `%clay`s whenever a file changes in the Unix
11+copy of the filesystem so that the change may be applied. `%clay` tells
12+unix whenever an app or vane changes the filesystem so that the change
13+can be effected in Unix. Apps and vanes may use `%clay` to write to the
14+filesystem, query it, and subscribe to changes in it. Ford and gall use
15+`%clay` to serve up apps and web pages.
16+
17+`%clay` includes three components. First is the filesystem/version
18+control algorithms, which are mostly defined in `++ze` and `++zu` in
19+zuse. Second is the write, query, and subscription logic. Finally, there
20+is the logic for communicating requests to, and receiving requests from,
21+foreign ships.
22+
23+</div>
24+
25+------------------------------------------------------------------------
26+
27+<list></list>
docs/system/arvo/clay/architecture.mdnew file+415
@@ -0,0 +1,415 @@
1+# clay
2+
3+## high-level
4+
5+clay is the primary filesystem for the arvo operating system,
6+which is the core of an urbit. The architecture of clay is
7+intrinsically connected with arvo, but we assume no knowledge of
8+either arvo or urbit. We will point out only those features of
9+arvo that are necessary for an understanding of clay, and we will
10+do so only when they arise.
11+
12+The first relevant feature of arvo is that it is a deterministic
13+system where input and output are defined as a series of events
14+and effects. The state of arvo is simply a function of its event
15+log. None of the effects from an event are emitted until the
16+event is entered in the log and persisted, either to disk or
17+another trusted source of persistence, such as a Kafka cluster.
18+Consequently, arvo is a single-level store: everything in its
19+state is persistent.
20+
21+In a more traditional OS, everything in RAM can be erased at any
22+time by power failure, and is always erased on reboot. Thus, a
23+primary purpose of a filesystem is to ensure files persist across
24+power failures and reboots. In arvo, both power failures and
25+reboots are special cases of suspending computation, which is
26+done safely since our event log is already persistent. Therefore,
27+clay is not needed in arvo for persistence. Why, then, do we have a
28+filesystem? There are two answers to this question.
29+
30+First, clay provides a filesystem tree, which is a convenient
31+user interface for some applications. Unix has the useful concept
32+of virtual filesystems, which are used for everything from direct
33+access to devices, to random number generators, to the /proc
34+tree. It is easy and intuitive to read from and write to a
35+filesystem tree.
36+
37+Second, clay has a distributed revision control system baked into
38+it. Traditional filesystems are not revision controlled, so
39+userspace software -- such as git -- is written on top of them to
40+do so. clay natively provides the same functionality as modern
41+DVCSes, and more.
42+
43+clay has two other unique properties that we'll cover later on:
44+it supports typed data and is referentially transparent.
45+
46+### Revision Control
47+
48+Every urbit has one or more "desks", which are independently
49+revision-controlled branches. Each desk contains its own mark
50+definitions, apps, doc, and so forth.
51+
52+Traditionally, an urbit has at least a base and a home desk. The
53+base desk has all the system software from the distribution. the
54+home desk is a fork of base with all the stuff specific to the
55+user of the urbit.
56+
57+A desk is a series of numbered commits, the most recent of which
58+represents the current state of the desk. A commit is composed of
59+(1) an absolute time when it was created, (2) a list of zero or
60+more parents, and (3) a map from paths to data.
61+
62+Most commits have exactly one parent, but the initial commit on a
63+desk may have zero parents, and merge commits have more than one
64+parent.
65+
66+The non-meta data is stored in the map of paths to data. It's
67+worth noting that no constraints are put on this map, so, for
68+example, both /a/b and /a/b/c could have data. This is impossible
69+in a traditional Unix filesystem since it means that /a/b is both
70+a file and a directory. Conventionally, the final element in the
71+path is its mark -- much like a filename extension in Unix. Thus,
72+/doc/readme.md in Unix is stored as /doc/readme/md in urbit.
73+
74+The data is not stored directly in the map; rather, a hash of the
75+data is stored, and we maintain a master blob store. Thus, if the
76+same data is referred to in multiple commits (as, for example,
77+when a file doesn't change between commits), only the hash is
78+duplicated.
79+
80+In the master blob store, we either store the data directly, or
81+else we store a diff against another blob. The hash is dependent
82+only on the data within and not on whether or not it's stored
83+directly, so we may on occasion rearrange the contents of the
84+blob store for performance reasons.
85+
86+Recall that a desk is a series of numbered commits. Not every
87+commit in a desk must be numbered. For example, if the base desk
88+has had 50 commits since home was forked from it, then a merge
89+from base to home will only add a single revision number to home,
90+although the full commit history will be accessible by traversing
91+the parentage of the individual commits.
92+
93+We do guarantee that the first commit is numbered 1, commits are
94+numbered consecutively after that (i.e. there are no "holes"),
95+the topmost commit is always numbered, and every numbered commit
96+is an ancestor of every later numbered commit.
97+
98+There are three ways to refer to particular commits in the
99+revision history. Firstly, one can use the revision number.
100+Secondly, one can use any absolute time between the one numbered
101+commit and the next (inclusive of the first, exclusive of the
102+second). Thirdly, every desk has a map of labels to revision
103+numbers. These labels may be used to refer to specific commits.
104+
105+Additionally, clay is a global filesystem, so data on other urbit
106+is easily accessible the same way as data on our local urbit. In
107+general, the path to a particular revision of a desk is
108+/~urbit-name/desk-name/revision. Thus, to get /try/readme/md
109+from revision 5 of the home desk on ~sampel-sipnym, we refer to
110+/~sampel-sipnym/home/5/try/readme/md. Clay's namespace is thus
111+global and referentially transparent.
112+
113+XXX reactivity here?
114+
115+### A Typed Filesystem
116+
117+Since clay is a general filesystem for storing data of arbitrary
118+types, in order to revision control correctly it needs to be
119+aware of types all the way through. Traditional revision control
120+does an excellent job of handling source code, so for source code
121+we act very similar to traditional revision control. The
122+challenge is to handle other data similarly well.
123+
124+For example, modern VCSs generally support "binary files", which
125+are files for which the standard textual diffing, patching, and
126+merging algorithms are not helpful. A "diff" of two binary files
127+is just a pair of the files, "patching" this diff is just
128+replacing the old file with the new one, and "merging"
129+non-identical diffs is always a conflict, which can't even be
130+helpfully annotated. Without knowing anything about the structure
131+of a blob of data, this is the best we can do.
132+
133+Often, though, "binary" files have some internal structure, and
134+it is possible to create diff, patch, and merge algorithms that
135+take advantage of this structure. An image may be the result of a
136+base image with some set of operations applied. With algorithms
137+aware of this set of operations, not only can revision control
138+software save space by not having to save every revision of the
139+image individually, these transformations can be made on parallel
140+branches and merged at will.
141+
142+Suppose Alice is tasked with touching up a picture, improving the
143+color balance, adjusting the contrast, and so forth, while Bob
144+has the job of cropping the picture to fit where it's needed and
145+adding textual overlay. Without type-aware revision control,
146+these changes must be made serially, requiring Alice and Bob to
147+explicitly coordinate their efforts. With type-aware revision
148+control, these operations may be performed in parallel, and then
149+the two changesets can be merged programmatically.
150+
151+Of course, even some kinds of text files may be better served by
152+diff, patch, and merge algorithms aware of the structure of the
153+files. Consider a file containing a pretty-printed JSON object.
154+Small changes in the JSON object may result in rather significant
155+changes in how the object is pretty-printed (for example, by
156+addding an indentation level, splitting a single line into
157+multiple lines).
158+
159+A text file wrapped at 80 columns also reacts suboptimally with
160+unadorned Hunt-McIlroy diffs. A single word inserted in a
161+paragraph may push the final word or two of the line onto the
162+next line, and the entire rest of the paragraph may be flagged as
163+a change. Two diffs consisting of a single added word to
164+different sentences may be flagged as a conflict. In general,
165+prose should be diffed by sentence, not by line.
166+
167+As far as the author is aware, clay is the first generalized,
168+type-aware revision control system. We'll go into the workings
169+of this system in some detail.
170+
171+### Marks
172+
173+Central to a typed filesystem is the idea of types. In clay, we
174+call these "marks". A mark is a file that defines a type,
175+conversion routines to and from the mark, and diff, patch, and
176+merge routines.
177+
178+For example, a `%txt` mark may be a list of lines of text, and it
179+may include conversions to `%mime` to allow it to be serialized
180+and sent to a browswer or to the unix filesystem. It will also
181+include Hunt-McIlroy diff, patch, and merge algorithms.
182+
183+A `%json` mark would be defined as a json object in the code, and
184+it would have a parser to convert from `%txt` and a printer to
185+convert back to `%txt`. The diff, patch, and merge algorithms are
186+fairly straightforward for json, though they're very different
187+from the text ones.
188+
189+More formally, a mark is a core with three arms, `++grab`,
190+`++grow`, and `++grad`. In `++grab` is a series of functions to
191+convert from other marks to the given mark. In `++grow` is a
192+series of functions to convert from the given mark to other
193+marks. In `++grad` is `++diff`, `++pact`, `++join`, and `++mash`.
194+
195+The types are as follows, in an informal pseudocode:
196+
197+ ++ grab:
198+ ++ mime: <mime> -> <mark-type>
199+ ++ txt: <txt> -> <mark-type>
200+ ...
201+ ++ grow:
202+ ++ mime: <mark-type> -> <mime>
203+ ++ txt: <mark-type> -> <txt>
204+ ...
205+ ++ grad
206+ ++ diff: (<mark-type>, <mark-type>) -> <diff-type>
207+ ++ pact: (<mark-type>, <diff-type>) -> <mark-type>
208+ ++ join: (<diff-type>, <diff-type>) -> <diff-type> or NULL
209+ ++ mash: (<diff-type>, <diff-type>) -> <diff-type>
210+
211+These types are basically what you would expect. Not every mark
212+has each of these functions defined -- all of them are optional
213+in the general case.
214+
215+In general, for a particular mark, the `++grab` and `++grow` entries
216+(if they exist) should be inverses of each other.
217+
218+In `++grad`, `++diff` takes two instances of a mark and produces
219+a diff of them. `++pact` takes an instance of a mark and patches
220+it with the given diff. `++join` takes two diffs and attempts to
221+merge them into a single diff. If there are conflicts, it
222+produces null. `++mash` takes two diffs and forces a merge,
223+annotating any conflicts.
224+
225+In general, if `++diff` called with A and B produces diff D, then
226+`++pact` called with A and D should produce B. Also, if `++join`
227+of two diffs does not produce null, then `++mash` of the same
228+diffs should produce the same result.
229+
230+Alternately, instead of `++diff`, `++pact`, `++join`, and
231+`++mash`, a mark can provide the same functionality by defining
232+`++sted` to be the name of another mark to which we wish to
233+delegate the revision control responsibilities. Then, before
234+running any of those functions, clay will convert to the other
235+mark, and convert back afterward. For example, the `%hoon` mark
236+is revision-controlled in the same way as `%txt`, so its `++grad`
237+is simply `++sted %txt`. Of course, `++txt` must be defined in
238+`++grow` and `++grab` as well.
239+
240+Every file in clay has a mark, and that mark must have a
241+fully-functioning `++grad`. Marks are used for more than just
242+clay, and other marks don't need a `++grad`, but if a piece of
243+data is to be saved to clay, we must know how to revision-control
244+it.
245+
246+Additionally, if a file is to be synced out to unix, then it must
247+have conversion routines to and from the `%mime` mark.
248+
249+##Using clay
250+
251+### Reading and Subscribing
252+
253+When reading from Clay, there are three types of requests. A
254+`%sing` request asks for data at single revsion. A `%next`
255+request asks to be notified the next time there's a change to
256+given file. A `%many` request asks to be notified on every
257+change in a desk for a range of changes.
258+
259+For `%sing` and `%next`, there are generally three things to be
260+queried. A `%u` request simply checks for the existence of a
261+file at a path. A `%x` request gets the data in the file at a
262+path. A `%y` request gets a hash of the data in the file at the
263+path combined with all its children and their data. Thus, `%y`
264+of a node changes if it or any of its children change.
265+
266+A `%sing` request is fulfilled immediately if possible. If the
267+requested revision is in the future, or is on another ship for
268+which we don't have the result cached, we don't respond
269+immediately. If the requested revision is in the future, we wait
270+until the revision happens before we respond to the request. If
271+the request is for data on another ship, we pass on the request
272+to the other ship. In general, Clay subscriptions, like most
273+things in Urbit, aren't guaranteed to return immediately.
274+They'll return when they can, and they'll do so in a
275+referentially transparent manner.
276+
277+A `%next` request checks query at the given revision, and it
278+produces the result of the query the next time it changes, along
279+with the revsion number when it changes. Thus, a `%next` of a
280+`%u` is triggered when a file is added or deleted, a `%next` of a
281+`%x` is triggered when a file is added, deleted, or changed, and
282+a `%next` of a `%y` is triggered when a file or any of its
283+children is added, deleted, or changed.
284+
285+A `%many` request is triggered every time the given desk has a
286+new revision. Unlike a `%next`, a `%many` has both a start and
287+an end revsion, after which it stops returning. For `%next`, a
288+single change is reported, and if the caller wishes to hear of
289+the next change, it must resubscribe. For `%many`, every revsion
290+from the start to the end triggers a response. Since a `%many`
291+request doesn't ask for any particular data, there aren't `%u`,
292+`%x`, and `%y` versions for it.
293+
294+### Unix sync
295+
296+One of the primary functions of clay is as a convenient user
297+interface. While tools exist to use clay from within urbit, it's
298+often useful to be able to treat clay like any other filesystem
299+from the Unix perspective -- to "mount" it, as it were.
300+
301+From urbit, you can run `|mount /path/to/directory %mount-point`,
302+and this will mount the given clay directory to the mount-point
303+directory in Unix. Every file is converted to `%mime` before it's
304+written to Unix, and converted back when read from Unix. The
305+entire directory is watched (a la Dropbox), and every change is
306+auto-committed to clay.
307+
308+### Merging
309+
310+Merging is a fundamental operation for a distributed revision
311+control system. At their root, clay's merges are similar to
312+git's, but with some additions to accomodate typed data. There
313+are seven different merge strategies.
314+
315+Throughout our discussion, we'll say that the merge is from
316+Alice's desk to Bob's. Recall that a commit is a date (for all
317+new commits this will be the current date), a list of parents,
318+and the data itself.
319+
320+A `%init` merge should be used iff it's the first commit to a
321+desk. The head of Alice's desk is used as the number 1 commit to
322+Bob's desk. Obviously, the ancestry remains intact through
323+traversing the parentage of the commit even though previous
324+commits are not numbered for Bob's desk.
325+
326+A `%this` merge means to keep what's in Bob's desk, but join the
327+ancestry. Thus, the new commit has the head of each desk as
328+parents, but the data is exactly what's in Bob's desk. For those
329+following along in git, this is the 'ours' merge strategy, not
330+the '--ours' option to the 'recursive' merge strategy. In other
331+words, even if Alice makes a change that does not conflict with
332+Bob, we throw it away. It's Bob's way or the highway.
333+
334+A `%that` merge means to take what's in Alice's desk, but join
335+the ancestry. This is the reverse of `%this`.
336+
337+A `%fine` merge is a "fast-forward" merge. This succeeds iff one
338+head is in the ancestry of the other. In this case, we use the
339+descendant as our new head.
340+
341+For `%meet`, `%mate`, and `%meld` merges, we first find the most
342+recent common ancestor to use as our merge base. If we have no
343+common ancestors, then we fail. If we have more than one most
344+recent common ancestor, then we have a criss-cross situation,
345+which should be handled delicately. At present, we delicately
346+throw up our hands and give up, but something akin to git's
347+'recursive' strategy should be implemented in the future.
348+
349+There's a functional inclusion ordering on `%fine`, `%meet`,
350+`%mate`, and `%meld` such that if an earlier strategy would have
351+succeeded, then every later strategy will produce the same
352+result. Put another way, every earlier strategy is the same as
353+every later strategy except with a restricted domain.
354+
355+A `%meet` merge only succeeds if the changes from the merge base
356+to Alice's head (hereafter, "Alice's changes") are in different
357+files than Bob's changes. In this case, the parents are both
358+Alice's and Bob's heads, and the data is the merge base plus
359+Alice's changed files plus Bob's changed files.
360+
361+A `%mate` merge attempts to merge changes to the same file when
362+both Alice and bob change it. If the merge is clean, we use it;
363+otherwise, we fail. A merge between different types of changes --
364+for example, deleting a file vs changing it -- is always a
365+conflict. If we succeed, the parents are both Alice's and Bob's
366+heads, and the data is the merge base plus Alice's changed files
367+plus Bob's changed files plus the merged files.
368+
369+A `%meld` merge will succeed even if there are conflicts. If
370+there are conflicts in a file, then we use the merge base's
371+version of that file, and we produce a set of files with
372+conflicts. The parents are both Alice's and Bob's heads, and the
373+data is the merge base plus Alice's changed files plus Bob's
374+changed files plus the successfully merged files plus the merge
375+base's version of the conflicting files.
376+
377+That's the extent of the merge options in clay proper. In
378+userspace there's a final option `%auto`, which is the most
379+common. `%auto` checks to see if Bob's desk exists, and if it
380+doesn't we use a `%init` merge. Otherwise, we progressively try
381+`%fine`, `%meet`, and `%mate` until one succeeds.
382+
383+If none succeed, we merge Bob's desk into a scratch desk. Then,
384+we merge Alice's desk into the scratch desk with the `%meld`
385+option to force the merge. For each file in the produced set of
386+conflicting files, we call the `++mash` function for the
387+appropriate mark, which annotates the conflicts if we know how.
388+
389+Finally, we display a message to the user informing them of the
390+scratch desk's existence, which files have annotated conflicts,
391+and which files have unannotated conflicts. When the user has
392+resolved the conflicts, they can merge the scratch desk back into
393+Bob's desk. This will be a `%fine` merge since Bob's head is in
394+the ancestry of the scratch desk.
395+
396+### Autosync
397+
398+Tracking and staying in sync with another desk is another
399+fundamental operation. We call this "autosync". This doesn't mean
400+simply mirroring a desk, since that wouldn't allow local changes.
401+We simply want to apply changes as they are made upstream, as
402+long as there are no conflicts with local changes.
403+
404+This is implemented by watching the other desk, and, when it has
405+changes, merging these changes into our desk with the usual merge
406+strategies.
407+
408+Note that it's quite reasonable for two desks to be autosynced to
409+each other. This results in any change on one desk being mirrored
410+to the other and vice versa.
411+
412+Additionally, it's fine to set up an autosync even if one desk,
413+the other desk, or both desks do not exist. The sync will be
414+activated when the upstream desk comes into existence and will
415+create the downstream desk if needed.
docs/system/arvo/clay/commentary.mdnew file+2007
@@ -0,0 +1,2007 @@
1+`%clay` commentary
2+==================
3+
4+`%clay` is our filesystem.
5+
6+The first part of this will be reference documentation for the data
7+types used by our filesystem. In fact, as a general guide, we recommend
8+reading and attempting to understand the data structures used in any
9+Hoon code before you try to read the code itself. Although complete
10+understanding of the data structures is impossible without seeing them
11+used in the code, an 80% understanding greatly clarifies the code. As
12+another general guide, when reading Hoon, it rarely pays off to
13+understand every line of code when it appears. Try to get the gist of
14+it, and then move on. The next time you come back to it, it'll likely
15+make a lot more sense.
16+
17+After a description of the data models, we'll give an overview of the
18+interface that vanes and applications can use to interact with the
19+filesystem.
20+
21+Finally, we'll dive into the code and the algorithms themselves. You
22+know, the fun part.
23+
24+Data Models
25+-----------
26+
27+As you're reading through this section, remember you can always come
28+back to this when you run into these types later on. You're not going to
29+remember everything the first time through, but it is worth reading, or
30+at least skimming, this so that you get a rough idea of how our state is
31+organized.
32+
33+The types that are certainly worth reading are `++raft`, `++room`,
34+`++dome`, `++ankh`, `++rung`, `++rang`, `++blob`, `++yaki`, and `++nori`
35+(possibly in that order). All in all, though, this section isn't too
36+long, so many readers may wish to quickly read through all of it. If you
37+get bored, though, just skip to the next section. You can always come
38+back when you need to.
39+
40+### `++raft`, formal state
41+
42+ ++ raft :: filesystem
43+ $: fat=(map ship room) :: domestic
44+ hoy=(map ship rung) :: foreign
45+ ran=rang :: hashes
46+ == ::
47+
48+This is the state of our vane. Anything that must be remembered between
49+calls to clay is stored in this state.
50+
51+`fat` is the set of domestic servers. This stores all the information
52+that is specfic to a particular ship on this pier. The keys to this map
53+are the ships on the current pier. all the information that is specific
54+to a particular foreign ship. The keys to this map are all the ships
55+whose filesystems we have attempted to access through clay.
56+
57+`ran` is the store of all commits and deltas, keyed by hash. The is
58+where all the "real" data we know is stored; the rest is "just
59+bookkeeping".
60+
61+### `++room`, filesystem per domestic ship
62+
63+ ++ room :: fs per ship
64+ $: hun=duct :: terminal duct
65+ hez=(unit duct) :: sync duch
66+ dos=(map desk dojo) :: native desk
67+ == ::
68+
69+This is the representation of the filesystem of a ship on our pier.
70+
71+`hun` is the duct we use to send messages to dill to display
72+notifications of filesystem changes. Only `%note` gifts should be
73+produced along this duct. This is set by the `%init` kiss.
74+
75+`hez`, if present, is the duct we use to send sync messages to unix so
76+that they end up in the pier unix directory. Only `%ergo` gifts should
77+be producd along this duct. This is set by `%into` and `%invo` kisses.
78+
79+`dos` is a well-known operating system released in 1981. It is also the
80+set of desks on this ship, mapped to their data.
81+
82+### `++desk`, filesystem branch
83+
84+ ++ desk ,@tas :: ship desk case spur
85+
86+This is the name of a branch of the filesystem. The default desks are
87+"arvo", "main", and "try". More may be created by simply referencing
88+them. Desks have independent histories and states, and they may be
89+merged into each other.
90+
91+### `++dojo`, domestic desk state
92+
93+ ++ dojo ,[p=cult q=dome] :: domestic desk state
94+
95+This is the all the data that is specific to a particular desk on a
96+domestic ship. `p` is the set of subscribers to this desk and `q` is the
97+data in the desk.
98+
99+### `++cult`, subscriptions
100+
101+ ++ cult (map duct rave) :: subscriptions
102+
103+This is the set of subscriptions to a particular desk. The keys are the
104+ducts from where the subscriptions requests came. The results will be
105+produced along these ducts. The values are a description of the
106+requested information.
107+
108+### `++rave`, general subscription request
109+
110+ ++ rave :: general request
111+ $% [& p=mood] :: single request
112+ [| p=moat] :: change range
113+ == ::
114+
115+This represents a subscription request for a desk. The request can be
116+for either a single item in the desk or else for a range of changes on
117+the desk.
118+
119+### `++rove`, stored general subscription request
120+
121+ ++ rove (each mood moot) :: stored request
122+
123+When we store a request, we store subscriptions with a little extra
124+information so that we can determine whether new versions actually
125+affect the path we're subscribed to.
126+
127+### `++mood`, single subscription request
128+
129+ ++ mood ,[p=care q=case r=path] :: request in desk
130+
131+This represents a request for the state of the desk at a particular
132+commit, specfied by `q`. `p` specifies what kind of information is
133+desired, and `r` specifies the path we are requesting.
134+
135+### `++moat`, range subscription request
136+
137+ ++ moat ,[p=case q=case r=path] :: change range
138+
139+This represents a request for all changes between `p` and `q` on path
140+`r`. You will be notified when a change is made to the node referenced
141+by the path or to any of its children.
142+
143+### `++moot`, stored range subscription request
144+
145+ ++ moot ,[p=case q=case r=path s=(map path lobe)] ::
146+
147+This is just a `++moat` plus a map of paths to lobes. This map
148+represents the data at the node referenced by the path at case `p`, if
149+we've gotten to that case (else null). We only send a notification along
150+the subscription if the data at a new revision is different than it was.
151+
152+### `++care`, clay submode
153+
154+ ++ care ?(%u %v %w %x %y %z) :: clay submode
155+
156+This specifies what type of information is requested in a subscription
157+or a scry.
158+
159+`%u` requests the `++rang` at the current moment. Because this
160+information is not stored for any moment other than the present, we
161+crash if the `++case` is not a `%da` for now.
162+
163+`%v` requests the `++dome` at the specified commit.
164+
165+`%w` requests the revsion number of the desk.
166+
167+`%x` requests the file at a specified path at the specified commit. If
168+there is no node at that path or if the node has no contents (that is,
169+if `q:ankh` is null), then this produces null.
170+
171+`%y` requests a `++arch` of the specfied commit at the specified path.
172+
173+`%z` requests the `++ankh` of the specified commit at the specfied path.
174+
175+### `++arch`, shallow filesystem node
176+
177+ ++ arch ,[p=@uvI q=(unit ,@uvI) r=(map ,@ta ,~)] :: fundamental node
178+
179+This is analogous to `++ankh` except that the we have neither our
180+contents nor the ankhs of our children. The other fields are exactly the
181+same, so `p` is a hash of the associated ankh, `u.q`, if it exists, is a
182+hash of the contents of this node, and the keys of `r` are the names of
183+our children. `r` is a map to null rather than a set so that the
184+ordering of the map will be equivalent to that of `r:ankh`, allowing
185+efficient conversion.
186+
187+### `++case`, specifying a commit
188+
189+ ++ case :: ship desk case spur
190+ $% [%da p=@da] :: date
191+ [%tas p=@tas] :: label
192+ [%ud p=@ud] :: number
193+ == ::
194+
195+A commit can be referred to in three ways: `%da` refers to the commit
196+that was at the head on date `p`, `%tas` refers to the commit labeled
197+`p`, and `%ud` refers to the commit numbered `p`. Note that since these
198+all can be reduced down to a `%ud`, only numbered commits may be
199+referenced with a `++case`.
200+
201+### `++dome`, desk data
202+
203+ ++ dome :: project state
204+ $: ang=agon :: pedigree
205+ ank=ankh :: state
206+ let=@ud :: top id
207+ hit=(map ,@ud tako) :: changes by id
208+ lab=(map ,@tas ,@ud) :: labels
209+ == ::
210+
211+This is the data that is actually stored in a desk.
212+
213+`ang` is unused and should be removed.
214+
215+`ank` is the current state of the desk. Thus, it is the state of the
216+filesystem at revison `let`. The head of a desk is always a numbered
217+commit.
218+
219+`let` is the number of the most recently numbered commit. This is also
220+the total number of numbered commits.
221+
222+`hit` is a map of numerical ids to hashes of commits. These hashes are
223+mapped into their associated commits in `hut:rang`. In general, the keys
224+of this map are exactly the numbers from 1 to `let`, with no gaps. Of
225+course, when there are no numbered commits, `let` is 0, so `hit` is
226+null. Additionally, each of the commits is an ancestor of every commit
227+numbered greater than this one. Thus, each is a descendant of every
228+commit numbered less than this one. Since it is true that the date in
229+each commit (`t:yaki`) is no earlier than that of each of its parents,
230+the numbered commits are totally ordered in the same way by both
231+pedigree and date. Of course, not every commit is numbered. If that
232+sounds too complicated to you, don't worry about it. It basically
233+behaves exactly as you would expect.
234+
235+`lab` is a map of textual labels to numbered commits. Note that labels
236+can only be applied to numbered commits. Labels must be unique across a
237+desk.
238+
239+### `++ankh`, filesystem node
240+
241+ ++ ankh :: fs node (new)
242+ $: p=cash :: recursive hash
243+ q=(unit ,[p=cash q=*]) :: file
244+ r=(map ,@ta ankh) :: folders
245+ == ::
246+
247+This is a single node in the filesystem. This may be file or a directory
248+or both. In earth filesystems, a node is a file xor a directory. On
249+mars, we're inclusive, so a node is a file ior a directory.
250+
251+`p` is a recursive hash that depends on the contents of the this file or
252+directory and on any children.
253+
254+`q` is the contents of this file, if any. `p.q` is a hash of the
255+contents while `q.q` is the data itself.
256+
257+`r` is the set of children of this node. In the case of a pure file,
258+this is empty. The keys are the names of the children and the values
259+are, recursively, the nodes themselves.
260+
261+### `++cash`, ankh hash
262+
263+ ++ cash ,@uvH :: ankh hash
264+
265+This is a 128-bit hash of an ankh. These are mostly stored within ankhs
266+themselves, and they are used to check for changes in possibly-deep
267+hierarchies.
268+
269+### `++rung`, filesystem per neighbor ship
270+
271+ ++ rung $: rus=(map desk rede) :: neighbor desks
272+ == ::
273+
274+This is the filesystem of a neighbor ship. The keys to this map are all
275+the desks we know about on their ship.
276+
277+### `++rede`, desk state
278+
279+ ++ rede :: universal project
280+ $: lim=@da :: complete to
281+ qyx=cult :: subscribers
282+ ref=(unit rind) :: outgoing requests
283+ dom=dome :: revision state
284+ == ::
285+
286+This is our knowledge of the state of a desk, either foreign or
287+domestic.
288+
289+`lim` is the date of the last full update. We only respond to requests
290+for stuff before this time.
291+
292+`qyx` is the list of subscribers to this desk. For domestic desks, this
293+is simply `p:dojo`, all subscribers to the desk, while in foreign desks
294+this is all the subscribers from our ship to the foreign desk.
295+
296+`ref` is the request manager for the desk. For domestic desks, this is
297+null since we handle requests ourselves.
298+
299+`dom` is the actual data in the desk.
300+
301+### `++rind`, request manager
302+
303+ ++ rind :: request manager
304+ $: nix=@ud :: request index
305+ bom=(map ,@ud ,[p=duct q=rave]) :: outstanding
306+ fod=(map duct ,@ud) :: current requests
307+ haw=(map mood (unit)) :: simple cache
308+ == ::
309+
310+This is the request manager for a foreign desk.
311+
312+`nix` is one more than the index of the most recent request. Thus, it is
313+the next available request number.
314+
315+`bom` is the set of outstanding requests. The keys of this map are some
316+subset of the numbers between 0 and one less than `nix`. The members of
317+the map are exactly those requests that have not yet been fully
318+satisfied.
319+
320+`fod` is the same set as `bom`, but from a different perspective. In
321+particular, the values of `fod` are the same as the values of `bom`, and
322+the `p` out of the values of `bom` are the same as the keys of `fod`.
323+Thus, we can map ducts to their associated request number and `++rave`,
324+and we can map numbers to their associated duct and `++rave`.
325+
326+`haw` is a map from simple requests to their values. This acts as a
327+cache for requests that have already been made. Thus, the second request
328+for a particular `++mood` is nearly instantaneous.
329+
330+### `++rang`, data store
331+
332+ ++ rang $: hut=(map tako yaki) ::
333+ lat=(map lobe blob) ::
334+ == ::
335+
336+This is a set of data keyed by hash. Thus, this is where the "real" data
337+is stored, but it is only meaningful if we know the hash of what we're
338+looking for.
339+
340+`hut` is a map from hashes to commits. We often get the hashes from
341+`hit:dome`, which keys them by logical id. Not every commit has an id.
342+
343+`lat` is a map from hashes to the actual data. We often get the hashes
344+from a `++yaki`, a commit, which references this map to get the data.
345+There is no `++blob` in any `++yaki`. They are only accessible through
346+this map.
347+
348+### `++tako`, commit reference
349+
350+ ++ tako ,@ :: yaki ref
351+
352+This is a hash of a `++yaki`, a commit. These are most notably used as
353+the keys in `hut:rang`, where they are associated with the actual
354+`++yaki`, and as the values in `hit:dome`, where sequential ids are
355+associated with these.
356+
357+### `++yaki`, commit
358+
359+ ++ yaki ,[p=(list tako) q=(map path lobe) r=tako t=@da] :: commit
360+
361+This is a single commit.
362+
363+`p` is a list of the hashes of the parents of this commit. In most
364+cases, this will be a single commit, but in a merge there may be more
365+parents. In theory, there may be an arbitrary number of parents, but in
366+practice merges have exactly two parents. This may change in the future.
367+For commit 1, there is no parent.
368+
369+`q` is a map of the paths on a desk to the data at that location. If you
370+understand what a `++lobe` and a `++blob` is, then the type signature
371+here tells the whole story.
372+
373+`r` is the hash associated with this commit.
374+
375+`t` is the date at which this commit was made.
376+
377+### `++lobe`, data reference
378+
379+ ++ lobe ,@ :: blob ref
380+
381+This is a hash of a `++blob`. These are most notably used in `lat:rang`,
382+where they are associated with the actual `++blob`, and as the values in
383+`q:yaki`, where paths are associated with their data in a commit.
384+
385+### `++blob`, data
386+
387+ ++ blob $% [%delta p=lobe q=lobe r=udon] :: delta on q
388+ [%direct p=lobe q=* r=umph] ::
389+ [%indirect p=lobe q=* r=udon s=lobe] ::
390+ == ::
391+
392+This is a node of data. In every case, `p` is the hash of the blob.
393+
394+`%delta` is the case where we define the data by a delta on other data.
395+In practice, the other data is always the previous commit, but nothing
396+depends on this. `q` is the hash of the parent blob, and `r` is the
397+delta.
398+
399+`%direct` is the case where we simply have the data directly. `q` is the
400+data itself, and `r` is any preprocessing instructions. These almost
401+always come from the creation of a file.
402+
403+`%indirect` is both of the preceding cases at once. `q` is the direct
404+data, `r` is the delta, and `s` is the parent blob. It should always be
405+the case that applying `r` to `s` gives the same data as `q` directly
406+(with the prepreprocessor instructions in `p.r`). This exists purely for
407+performance reasons. This is unused, at the moment, but in general these
408+should be created when there are a long line of changes so that we do
409+not have to traverse the delta chain back to the creation of the file.
410+
411+### `++udon`, abstract delta
412+
413+ ++ udon :: abstract delta
414+ $: p=umph :: preprocessor
415+ $= q :: patch
416+ $% [%a p=* q=*] :: trivial replace
417+ [%b p=udal] :: atomic indel
418+ [%c p=(urge)] :: list indel
419+ [%d p=upas q=upas] :: tree edit
420+ == ::
421+ == ::
422+
423+This is an abstract change to a file. This is a superset of what would
424+normally be called diffs. Diffs usually refer to changes in lines of
425+text while we have the ability to do more interesting deltas on
426+arbitrary data structures.
427+
428+`p` is any preprocessor instructions.
429+
430+`%a` refers to the trival delta of a complete replace of old data with
431+new data.
432+
433+`%b` refers to changes in an opaque atom on the block level. This has
434+very limited usefulness, and is not used at the moment.
435+
436+`%c` refers to changes in a list of data. This is often lines of text,
437+which is your classic diff. We, however, will work on any list of data.
438+
439+`%d` refers to changes in a tree of data. This is general enough to
440+describe changes to any hoon noun, but often more special-purpose delta
441+should be created for different content types. This is not used at the
442+moment, and may in fact be unimplemented.
443+
444+### `++urge`, list change
445+
446+ ++ urge |*(a=_,* (list (unce a))) :: list change
447+
448+This is a parametrized type for list changes. For example, `(urge ,@t)`
449+is a list change for lines of text.
450+
451+### `++unce`, change part of a list.
452+
453+ ++ unce |* a=_,* :: change part
454+ $% [%& p=@ud] :: skip[copy]
455+ [%| p=(list a) q=(list a)] :: p -> q[chunk]
456+ == ::
457+
458+This is a single change in a list of elements of type `a`. For example,
459+`(unce ,@t)` is a single change in a lines of text.
460+
461+`%&` means the next `p` lines are unchanged.
462+
463+`%|` means the lines `p` have changed to `q`.
464+
465+### `++umph`, preprocessing information
466+
467+ ++ umph :: change filter
468+ $| $? %a :: no filter
469+ %b :: jamfile
470+ %c :: LF text
471+ == ::
472+ $% [%d p=@ud] :: blocklist
473+ == ::
474+
475+This space intentionally left undocumented. This stuff will change once
476+we get a well-typed clay.
477+
478+### `++upas`, tree change
479+
480+ ++ upas :: tree change (%d)
481+ $& [p=upas q=upas] :: cell
482+ $% [%0 p=axis] :: copy old
483+ [%1 p=*] :: insert new
484+ [%2 p=axis q=udon] :: mutate!
485+ == ::
486+
487+This space intentionally left undocumented. This stuff is not known to
488+work, and will likely change when we get a well-typed clay. Also, this
489+is not a complicated type; it is not difficult to work out the meaning.
490+
491+### `++nori`, repository action
492+
493+ ++ nori :: repository action
494+ $% [& q=soba] :: delta
495+ [| p=@tas] :: label
496+ == ::
497+
498+This describes a change that we are asking clay to make to the desk.
499+There are two kinds of changes that may be made: we can modify files or
500+we can apply a label to a commit.
501+
502+In the `|` case, we will simply label the current commit with the given
503+label. In the `&` case, we will apply the given changes.
504+
505+### `++soba`, delta
506+
507+ ++ soba ,[p=cart q=(list ,[p=path q=miso])] :: delta
508+
509+This describes a set of changes to make to a desk. The `cart` is simply
510+a pair of the old hash and the new hash of the desk. The list is a list
511+of changes keyed by the file they're changing. Thus, the paths are paths
512+to files to be changed while `miso` is a description of the change
513+itself.
514+
515+### `++miso`, ankh delta
516+
517+ ++ miso :: ankh delta
518+ $% [%del p=*] :: delete
519+ [%ins p=*] :: insert
520+ [%mut p=udon] :: mutate
521+ == ::
522+
523+There are three kinds of changes that may be made to a node in a desk.
524+We can insert a file, in which case `p` is the contents of the new file.
525+We can delete a file, in which case `p` is the contents of the old file.
526+Finally, we can mutate that file, in which case the `udon` describes the
527+changes we are applying to the file.
528+
529+### `++mizu`, merged state
530+
531+ ++ mizu ,[p=@u q=(map ,@ud tako) r=rang] :: new state
532+
533+This is the input to the `%merg` kiss, which allows us to perform a
534+merge. The `p` is the number of the new head commit. The `q` is a map
535+from numbers to commit hashes. This is all the new numbered commits that
536+are to be inserted. The keys to this should always be the numbers from
537+`let.dom` plus one to `p`, inclusive. The `r` is the maps of all the new
538+commits and data. Since these are merged into the current state, no old
539+commits or data need be here.
540+
541+### `++riff`, request/desist
542+
543+ ++ riff ,[p=desk q=(unit rave)] :: request/desist
544+
545+This represents a request for data about a particular desk. If `q`
546+contains a `rave`, then this opens a subscription to the desk for that
547+data. If `q` is null, then this tells clay to cancel the subscription
548+along this duct.
549+
550+### `++riot`, response
551+
552+ ++ riot (unit rant) :: response/complete
553+
554+A riot is a response to a subscription. If null, the subscription has
555+been completed, and no more responses will be sent. Otherwise, the
556+`rant` is the produced data.
557+
558+### `++rant`, response data
559+
560+ ++ rant :: namespace binding
561+ $: p=[p=care q=case r=@tas] :: clade release book
562+ q=path :: spur
563+ r=* :: data
564+ == ::
565+
566+This is the data at a particular node in the filesystem. `p.p` specifies
567+the type of data that was requested (and is produced). `q.p` gives the
568+specific version reported (since a range of versions may be requested in
569+a subscription). `r.p` is the desk. `q` is the path to the filesystem
570+node. `r` is the data itself (in the format specified by `p.p`).
571+
572+### `++nako`, subscription response data
573+
574+ ++ nako $: gar=(map ,@ud tako) :: new ids
575+ let=@ud :: next id
576+ lar=(set yaki) :: new commits
577+ bar=(set blob) :: new content
578+ == ::
579+
580+This is the data that is produced by a request for a range of revisions
581+of a desk. This allows us to easily keep track of a remote repository --
582+all the new information we need is contained in the `nako`.
583+
584+`gar` is a map of the revisions in the range to the hash of the commit
585+at that revision. These hashes can be used with `hut:rang` to find the
586+commit itself.
587+
588+`let` is either the last revision number in the range or the most recent
589+revision number, whichever is smaller.
590+
591+`lar` is the set of new commits, and `bar` is the set of new content.
592+
593+Public Interface
594+----------------
595+
596+As with all vanes, there are exactly two ways to interact with clay.
597+`%clay` exports a namespace accessible through `.^`, which is described
598+above under `++care`. The primary way of interacting with clay, though,
599+is by sending kisses and receiving gifts.
600+
601+ ++ gift :: out result <-$
602+ $% [%ergo p=@p q=@tas r=@ud] :: version update
603+ [%note p=@tD q=tank] :: debug message
604+ [%writ p=riot] :: response
605+ == ::
606+ ++ kiss :: in request ->$
607+ $% [%info p=@p q=@tas r=nori] :: internal edit
608+ [%ingo p=@p q=@tas r=nori] :: internal noun edit
609+ [%init p=@p] :: report install
610+ [%into p=@p q=@tas r=nori] :: external edit
611+ [%invo p=@p q=@tas r=nori] :: external noun edit
612+ [%merg p=@p q=@tas r=mizu] :: internal change
613+ [%wart p=sock q=@tas r=path s=*] :: network request
614+ [%warp p=sock q=riff] :: file request
615+ == ::
616+
617+There are only a small number of possible kisses, so it behooves us to
618+describe each in detail.
619+
620+ $% [%info p=@p q=@tas r=nori] :: internal edit
621+
622+ [%into p=@p q=@tas r=nori] :: external edit
623+
624+These two kisses are nearly identical. At a high level, they apply
625+changes to the filesystem. Whenever we add, remove, or edit a file, one
626+of these cards is sent. The `p` is the ship whose filesystem we're
627+trying to change, the `q` is the desk we're changing, and the `r` is the
628+request change. For the format of the requested change, see the
629+documentation for `++nori` above.
630+
631+When a file is changed in the unix filesystem, vere will send a `%into`
632+kiss. This tells clay that the duct over which the kiss was sent is the
633+duct that unix is listening on for changes. From within Arvo, though, we
634+should never send a `%into` kiss. The `%info` kiss is exactly identical
635+except it does not reset the duct.
636+
637+ [%ingo p=@p q=@tas r=nori] :: internal noun edit
638+
639+ [%invo p=@p q=@tas r=nori] :: external noun edit
640+
641+These kisses are currently identical to `%info` and `%into`, though this
642+will not always be the case. The intent is for these kisses to allow
643+typed changes to clay so that we may store typed data. This is currently
644+unimplemented.
645+
646+ [%init p=@p] :: report install
647+
648+Init is called when a ship is started on our pier. This simply creates a
649+default `room` to go into our `raft`. Essentially, this initializes the
650+filesystem for a ship.
651+
652+ [%merg p=@p q=@tas r=mizu] :: internal change
653+
654+This is called to perform a merge. This is most visibly called by
655+:update to update the filesystem of the current ship to that of its
656+sein. The `p` and `q` are as in `%info`, and the `r` is the description
657+of the merge. See `++mizu` above.
658+
659+XX
660+`XX [%wake ~] :: timer activate XX`
661+XX\
662+XX This card is sent by unix at the time specified by `++doze`. This
663+time is XX usually the closest time specified in a subscription request.
664+When `%wake` is XX called, we update our subscribers if there have been
665+any changes.
666+
667+ [%wart p=sock q=@tas r=path s=*] :: network request
668+
669+This is a request that has come across the network for a particular
670+file. When another ship asks for a file from us, that request comes to
671+us in the form of a `%wart` kiss. This is handled by trivially turning
672+it into a `%warp`.
673+
674+ [%warp p=sock q=riff] :: file request
675+
676+This is a request for information about a particular desk. This is, in
677+its most general form, a subscription, though in many cases it is the
678+trivial case of a subscription -- a read. See `++riff` for the format of
679+the request.
680+
681+Lifecycle of a Local Read
682+-------------------------
683+
684+There are two real types of interaction with a filesystem: you can read,
685+and you can write. We'll describe each process, detailing both the flow
686+of control followed by the kernel and the algorithms involved. The
687+simpler case is that of the read, so we'll begin with that.
688+
689+When a vane or an application wishes to read a file from the filesystem,
690+it sends a `%warp` kiss, as described above. Of course, you may request
691+a file on another ship and, being a global filesystem, clay will happily
692+produce it for you. That code pathway will be described in another
693+section; here, we will restrict ourselves to examining the case of a
694+read from a ship on our own pier.
695+
696+The kiss can request either a single version of a file node or a range
697+of versions of a desk. Here, we'll deal only with a request for a single
698+version.
699+
700+As in all vanes, a kiss enters clay via a call to `++call`. Scanning
701+through the arm, we quickly see where `%warp` is handled.
702+
703+ ?: =(p.p.q.hic q.p.q.hic)
704+ =+ une=(un p.p.q.hic now ruf)
705+ =+ wex=(di:une p.q.q.hic)
706+ =+ ^= wao
707+ ?~ q.q.q.hic
708+ (ease:wex hen)
709+ (eave:wex hen u.q.q.q.hic)
710+ =+ ^= woo
711+ abet:wao
712+ [-.woo abet:(pish:une p.q.q.hic +.woo ran.wao)]
713+
714+We're following the familar patern of producing a list of moves and an
715+updated state. In this case, the state is `++raft`.
716+
717+We first check to see if the sending and receiving ships are the same.
718+If they're not, then this is a request for data on another ship. We
719+describe that process later. Here, we discuss only the case of a local
720+read.
721+
722+At a high level, the call to `++un` sets up the core for the domestic
723+ship that contains the files we're looking for. The call to `++di` sets
724+up the core for the particular desk we're referring to.
725+
726+After this, we perform the actual request. If there is no rave in the
727+riff, then that means we are cancelling a request, so we call
728+`++ease:de`. Otherwise, we start a subscription with `++eave:de`. We
729+call `++abet:de` to resolve our various types of output into actual
730+moves. We produce the moves we found above and the `++un` core resolved
731+with `++pish:un` (putting the modified desk in the room) and `++abet:un`
732+(putting the modified room in the raft).
733+
734+Much of this is fairly straightforward, so we'll only describe `++ease`,
735+`++eave`, and `++abet:de`. Feel free to look up the code to the other
736+steps -- it should be easy to follow.
737+
738+Although it's called last, it's usually worth examining `++abet` first,
739+since it defines in what ways we can cause side effects. Let's do that,
740+and also a few of the lines at the beginning of `++de`.
741+
742+ =| yel=(list ,[p=duct q=gift])
743+ =| byn=(list ,[p=duct q=riot])
744+ =| vag=(list ,[p=duct q=gift])
745+ =| say=(list ,[p=duct q=path r=ship s=[p=@ud q=riff]])
746+ =| tag=(list ,[p=duct q=path c=note])
747+ |%
748+ ++ abet
749+ ^- [(list move) rede]
750+ :_ red
751+ ;: weld
752+ %+ turn (flop yel)
753+ |=([a=duct b=gift] [hun %give b])
754+ ::
755+ %+ turn (flop byn)
756+ |=([a=duct b=riot] [a %give [%writ b]])
757+ ::
758+ %+ turn (flop vag)
759+ |=([a=duct b=gift] [a %give b])
760+ ::
761+ %+ turn (flop say)
762+ |= [a=duct b=path c=ship d=[p=@ud q=riff]]
763+ :- a
764+ [%pass b %a %want [who c] [%q %re p.q.d (scot %ud p.d) ~] q.d]
765+ ::
766+ %+ turn (flop tag)
767+ |=([a=duct b=path c=note] [a %pass b c])
768+ ==
769+
770+This is very simple code. We see there are exactly five different kinds
771+of side effects we can generate.
772+
773+In `yel` we put gifts that we wish to be sent along the `hun:room` duct
774+to dill. See the documentation for `++room` above. This is how we
775+display messages to the terminal.
776+
777+In `byn` we put riots that we wish returned to subscribers. Recall that
778+a riot is a response to a subscription. These are returned to our
779+subscribers in the form of a `%writ` gift.
780+
781+In `vag` we put gifts along with the ducts on which to send them. This
782+allows us to produce arbitrary gifts, but in practice this is only used
783+to produce `%ergo` gifts.
784+
785+In `say` we put messages we wish to pass to ames. These messages are
786+used to request information from clay on other piers. We must provide
787+not only the duct and the request (the riff), but also the return path,
788+the other ship to talk to, and the sequence number of the request.
789+
790+In `tag` we put arbitrary notes we wish to pass to other vanes. For now,
791+the only notes we pass here are `%wait` and `%rest` to the timer vane.
792+
793+Now that we know what kinds of side effects we may have, we can jump
794+into the handling of requests.
795+
796+ ++ ease :: release request
797+ |= hen=duct
798+ ^+ +>
799+ ?~ ref +>
800+ =+ rov=(~(got by qyx) hen)
801+ =. qyx (~(del by qyx) hen)
802+ (mabe rov (cury best hen))
803+ =. qyx (~(del by qyx) hen)
804+ |- ^+ +>+.$
805+ =+ nux=(~(get by fod.u.ref) hen)
806+ ?~ nux +>+.$
807+ %= +>+.$
808+ say [[hen [(scot %ud u.nux) ~] for [u.nux syd ~]] say]
809+ fod.u.ref (~(del by fod.u.ref) hen)
810+ bom.u.ref (~(del by bom.u.ref) u.nux)
811+ ==
812+
813+This is called when we're cancelling a subscription. For domestic desks,
814+`ref` is null, so we're going to cancel any timer we might have created.
815+We first delete the duct from our map of requests, and then we call
816+`++mabe` with `++best` to send a `%rest` kiss to the timer vane if we
817+have started a timer. We'll describe `++best` and `++mabe` momentarily.
818+
819+Although we said we're not going to talk about foreign requests yet,
820+it's easy to see that for foreign desks, we cancel any outstanding
821+requests for this duct and send a message over ames to the other ship
822+telling them to cancel the subscription.
823+
824+ ++ best
825+ |= [hen=duct tym=@da]
826+ %_(+> tag :_(tag [hen /tyme %t %rest tym]))
827+
828+This simply pushes a `%rest` note onto `tag`, from where it will be
829+passed back to arvo to be handled. This cancels the timer at the given
830+duct (with the given time).
831+
832+ ++ mabe :: maybe fire function
833+ |* [rov=rove fun=$+(@da _+>.^$)]
834+ ^+ +>.$
835+ %- fall :_ +>.$
836+ %- bind :_ fun
837+ ^- (unit ,@da)
838+ ?- -.rov
839+ %&
840+ ?. ?=(%da -.q.p.rov) ~
841+ `p.q.p.rov
842+ %|
843+ =* mot p.rov
844+ %+ hunt
845+ ?. ?=(%da -.p.mot) ~
846+ ?.((lth now p.p.mot) ~ [~ p.p.mot])
847+ ?. ?=(%da -.q.mot) ~
848+ ?.((lth now p.q.mot) [~ now] [~ p.q.mot])
849+ ==
850+
851+This decides whether the given request can only be satsified in the
852+future. In that case, we call the given function with the time in the
853+future when we expect to have an update to give to this request. This is
854+called with `++best` to cancel timers and with `++bait` to start them.
855+
856+For single requests, we have a time if the request is for a particular
857+time (which is assumed to be in the future). For ranges of requests, we
858+check both the start and end cases to see if they are time cases. If so,
859+we choose the earlier time.
860+
861+If any of those give us a time, then we call the given funciton with the
862+smallest time.
863+
864+The more interesting case is, of course, when we're not cancelling a
865+subscription but starting one.
866+
867+ ++ eave :: subscribe
868+ |= [hen=duct rav=rave]
869+ ^+ +>
870+ ?- -.rav
871+ &
872+ ?: &(=(p.p.rav %u) !=(p.q.p.rav now))
873+ ~& [%clay-fail p.q.p.rav %now now]
874+ !!
875+ =+ ver=(aver p.rav)
876+ ?~ ver
877+ (duce hen rav)
878+ ?~ u.ver
879+ (blub hen)
880+ (blab hen p.rav u.u.ver)
881+
882+There are two types of subscriptions -- either we're requesting a single
883+file or we're requesting a range of versions of a desk. We'll dicuss the
884+simpler case first.
885+
886+First, we check that we're not requesting the `rang` from any time other
887+than the present. Since we don't store that information for any other
888+time, we can't produce it in a referentially transparent manner for any
889+time other than the present.
890+
891+Then, we try to read the requested `mood` `p.rav`. If we can't access
892+the request data right now, we call `++duce` to put the request in our
893+queue to be satisfied when the information becomes available.
894+
895+This case occurs when we make a request for a case whose (1) date is
896+after the current date, (2) number is after the current number, or (3)
897+label is not yet used.
898+
899+ ++ duce :: produce request
900+ |= [hen=duct rov=rove]
901+ ^+ +>
902+ =. qyx (~(put by qyx) hen rov)
903+ ?~ ref
904+ (mabe rov (cury bait hen))
905+ |- ^+ +>+.$ :: XX why?
906+ =+ rav=(reve rov)
907+ =+ ^= vaw ^- rave
908+ ?. ?=([%& %v *] rav) rav
909+ [%| [%ud let.dom] `case`q.p.rav r.p.rav]
910+ =+ inx=nix.u.ref
911+ %= +>+.$
912+ say [[hen [(scot %ud inx) ~] for [inx syd ~ vaw]] say]
913+ nix.u.ref +(nix.u.ref)
914+ bom.u.ref (~(put by bom.u.ref) inx [hen vaw])
915+ fod.u.ref (~(put by fod.u.ref) hen inx)
916+ ==
917+
918+The code for `++duce` is nearly the exact inverse of `++ease`, which in
919+the case of a domestic desk is very simple -- we simply put the duct and
920+rave into `qyx` and possibly start a timer with `++mabe` and `++bait`.
921+Recall that `ref` is null for domestic desks and that `++mabe` fires the
922+given function with the time we need to be woken up at, if we need to be
923+woken up at a particular time.
924+
925+ ++ bait
926+ |= [hen=duct tym=@da]
927+ %_(+> tag :_(tag [hen /tyme %t %wait tym]))
928+
929+This sets an alarm by sending a `%wait` card with the given time to the
930+timer vane.
931+
932+Back in `++eave`, if `++aver` returned `[~ ~]`, then we cancel the
933+subscription. This occurs when we make (1) a `%x` request for a file
934+that does not exist, (2) a `%w` request with a case that is not a
935+number, or (3) a `%w` request with a nonempty path. The `++blub` is
936+exactly what you would expect it to be.
937+
938+ ++ blub :: ship stop
939+ |= hen=duct
940+ %_(+> byn [[hen ~] byn])
941+
942+We notify the duct that we're cancelling their subscription since it
943+isn't satisfiable.
944+
945+Otherwise, we have received the desired information, so we send it on to
946+the subscriber with `++blab`.
947+
948+ ++ blab :: ship result
949+ |= [hen=duct mun=mood dat=*]
950+ ^+ +>
951+ +>(byn [[hen ~ [p.mun q.mun syd] r.mun dat] byn])
952+
953+The most interesting arm called in `++eave` is, of course, `++aver`,
954+where we actually try to read the data.
955+
956+ ++ aver :: read
957+ |= mun=mood
958+ ^- (unit (unit ,*))
959+ ?: &(=(p.mun %u) !=(p.q.mun now)) :: prevent bad things
960+ ~& [%clay-fail p.q.mun %now now]
961+ !!
962+ =+ ezy=?~(ref ~ (~(get by haw.u.ref) mun))
963+ ?^ ezy ezy
964+ =+ nao=(~(case-to-aeon ze lim dom ran) q.mun)
965+ ?~(nao ~ [~ (~(read-at-aeon ze lim dom ran) u.nao mun)])
966+
967+We check immediately that we're not requesting the `rang` for any time
968+other than the present.
969+
970+If this is a foreign desk, then we check our cache for the specific
971+request. If either this is a domestic desk or we don't have the request
972+in our cache, then we have to actually go read the data from our dome.
973+
974+We need to do two things. First, we try to find the number of the commit
975+specified by the given case, and then we try to get the data there.
976+
977+Here, we jump into `arvo/zuse.hoon`, which is where much of the
978+algorithmic code is stored, as opposed to the clay interface, which is
979+stored in `arvo/clay.hoon`. We examine `++case-to-aeon:ze`.
980+
981+ ++ case-to-aeon :: case-to-aeon:ze
982+ |= lok=case :: act count through
983+ ^- (unit aeon)
984+ ?- -.lok
985+ %da
986+ ?: (gth p.lok lim) ~
987+ |- ^- (unit aeon)
988+ ?: =(0 let) [~ 0] :: avoid underflow
989+ ?: %+ gte p.lok
990+ =< t
991+ %- tako-to-yaki
992+ %- aeon-to-tako
993+ let
994+ [~ let]
995+ $(let (dec let))
996+ ::
997+ %tas (~(get by lab) p.lok)
998+ %ud ?:((gth p.lok let) ~ [~ p.lok])
999+ ==
1000+
1001+We handle each type of `case` differently. The latter two types are
1002+easy.
1003+
1004+If we're requesting a revision by label, then we simply look up the
1005+requested label in `lab` from the given dome. If it exists, that is our
1006+aeon; else we produce null, indicating the requested revision does not
1007+yet exist.
1008+
1009+If we're requesting a revision by number, we check if we've yet reached
1010+that number. If so, we produce the number; else we produce null.
1011+
1012+If we're requesting a revision by date, we check first if the date is in
1013+the future, returning null if so. Else we start from the most recent
1014+revision and scan backwards until we find the first revision committed
1015+before that date, and we produce that. If we requested a date before any
1016+revisions were committed, we produce `0`.
1017+
1018+The definitions of `++aeon-to-tako` and `++tako-to-yaki` are trivial.
1019+
1020+ ++ aeon-to-tako ~(got by hit)
1021+
1022+ ++ tako-to-yaki ~(got by hut) :: grab yaki
1023+
1024+We simply look up the aeon or tako in their respective maps (`hit` and
1025+`hut`).
1026+
1027+Assuming we got a valid version number, `++aver` calls
1028+`++read-at-aeon:ze`, which reads the requested data at the given
1029+revision.
1030+
1031+ ++ read-at-aeon :: read-at-aeon:ze
1032+ |= [oan=aeon mun=mood] :: seek and read
1033+ ^- (unit)
1034+ ?: &(?=(%w p.mun) !?=(%ud -.q.mun)) :: NB only for speed
1035+ ?^(r.mun ~ [~ oan])
1036+ (read:(rewind oan) mun)
1037+
1038+If we're requesting the revision number with a case other than by
1039+number, then we go ahead and just produce the number we were given.
1040+Otherwise, we call `++rewind` to rewind our state to the given revision,
1041+and then we call `++read` to get the requested information.
1042+
1043+ ++ rewind :: rewind:ze
1044+ |= oan=aeon :: rewind to aeon
1045+ ^+ +>
1046+ ?: =(let oan) +>
1047+ ?: (gth oan let) !! :: don't have version
1048+ +>(ank (checkout-ankh q:(tako-to-yaki (aeon-to-tako oan))), let oan)
1049+
1050+If we're already at the requested version, we do nothing. If we're
1051+requesting a version later than our head, we are unable to comply.
1052+
1053+Otherwise, we get the hash of the commit at the number, and from that we
1054+get the commit itself (the yaki), which has the map of path to lobe that
1055+represents a version of the filesystem. We call `++checkout-ankh` to
1056+checkout the commit, and we replace `ank` in our context with the
1057+result.
1058+
1059+ ++ checkout-ankh :: checkout-ankh:ze
1060+ |= hat=(map path lobe) :: checkout commit
1061+ ^- ankh
1062+ %- cosh
1063+ %+ roll (~(tap by hat) ~)
1064+ |= [[pat=path bar=lobe] ank=ankh]
1065+ ^- ankh
1066+ %- cosh
1067+ ?~ pat
1068+ =+ zar=(lobe-to-noun bar)
1069+ ank(q [~ (sham zar) zar])
1070+ =+ nak=(~(get by r.ank) i.pat)
1071+ %= ank
1072+ r %+ ~(put by r.ank) i.pat
1073+ $(pat t.pat, ank (fall nak _ankh))
1074+ ==
1075+
1076+Twice we call `++cosh`, which hashes a commit, updating `p` in an
1077+`ankh`. Let's jump into that algorithm before we describe
1078+`++checkout-ankh`.
1079+
1080+ ++ cosh :: locally rehash
1081+ |= ank=ankh :: NB v/unix.c
1082+ ank(p rehash:(zu ank))
1083+
1084+We simply replace `p` in the hash with the `cash` we get from a call to
1085+`++rehash:zu`.
1086+
1087+ ++ zu !: :: filesystem
1088+ |= ank=ankh :: filesystem state
1089+ =| myz=(list ,[p=path q=miso]) :: changes in reverse
1090+ =| ram=path :: reverse path into
1091+ |%
1092+ ++ rehash :: local rehash
1093+ ^- cash
1094+ %+ mix ?~(q.ank 0 p.u.q.ank)
1095+ =+ axe=1
1096+ |- ^- cash
1097+ ?~ r.ank _@
1098+ ;: mix
1099+ (shaf %dash (mix axe (shaf %dush (mix p.n.r.ank p.q.n.r.ank))))
1100+ $(r.ank l.r.ank, axe (peg axe 2))
1101+ $(r.ank r.r.ank, axe (peg axe 3))
1102+ ==
1103+
1104+`++zu` is a core we set up with a particular filesystem node to traverse
1105+a checkout of the filesystem and access the actual data inside it. One
1106+of the things we can do with it is to create a recursive hash of the
1107+node.
1108+
1109+In `++rehash`, if this node is a file, then we xor the remainder of the
1110+hash with the hash of the contents of the file. The remainder of the
1111+hash is `0` if we have no children, else we descend into our children.
1112+Basically, we do a half SHA-256 of the xor of the axis of this child and
1113+the half SHA-256 of the xor of the name of the child and the hash of the
1114+child. This is done for each child and all the results are xored
1115+together.
1116+
1117+Now we return to our discussion of `++checkout-ankh`.
1118+
1119+We fold over every path in this version of the filesystem and create a
1120+great ankh out of them. First, we call `++lobe-to-noun` to get the raw
1121+data referred to be each lobe.
1122+
1123+ ++ lobe-to-noun :: grab blob
1124+ |= p=lobe :: ^- *
1125+ %- blob-to-noun
1126+ (lobe-to-blob p)
1127+
1128+This converts a lobe into the raw data it refers to by first getting the
1129+blob with `++lobe-to-blob` and converting that into data with
1130+`++blob-to-noun`.
1131+
1132+ ++ lobe-to-blob ~(got by lat) :: grab blob
1133+
1134+This just grabs the blob that the lobe refers to.
1135+
1136+ ++ blob-to-noun :: grab blob
1137+ |= p=blob
1138+ ?- -.p
1139+ %delta (lump r.p (lobe-to-noun q.p))
1140+ %direct q.p
1141+ %indirect q.p
1142+ ==
1143+
1144+If we have either a direct or an indirect blob, then the data is stored
1145+right in the blob. Otherwise, we have to reconstruct it from the diffs.
1146+We do this by calling `++lump` on the diff in the blob with the data
1147+obtained by recursively calling the parent of this blob.
1148+
1149+ ++ lump :: apply patch
1150+ |= [don=udon src=*]
1151+ ^- *
1152+ ?+ p.don ~|(%unsupported !!)
1153+ %a
1154+ ?+ -.q.don ~|(%unsupported !!)
1155+ %a q.q.don
1156+ %c (lurk ((hard (list)) src) p.q.don)
1157+ %d (lure src p.q.don)
1158+ ==
1159+ ::
1160+ %c
1161+ =+ dst=(lore ((hard ,@) src))
1162+ %- roly
1163+ ?+ -.q.don ~|(%unsupported !!)
1164+ %a ((hard (list ,@t)) q.q.don)
1165+ %c (lurk dst p.q.don)
1166+ ==
1167+ ==
1168+
1169+This is defined in `arvo/hoon.hoon` for historical reasons which are
1170+likely no longer applicable. Since the `++umph` structure will likely
1171+change we convert clay to be a typed filesystem, we'll only give a
1172+high-level description of this process. If we have a `%a` udon, then
1173+we're performing a trivial replace, so we produce simply `q.q.don`. If
1174+we have a `%c` udon, then we're performing a list merge (as in, for
1175+example, lines of text). The merge is performed by `++lurk`.
1176+
1177+ ++ lurk :: apply list patch
1178+ |* [hel=(list) rug=(urge)]
1179+ ^+ hel
1180+ =+ war=`_hel`~
1181+ |- ^+ hel
1182+ ?~ rug (flop war)
1183+ ?- -.i.rug
1184+ &
1185+ %= $
1186+ rug t.rug
1187+ hel (slag p.i.rug hel)
1188+ war (weld (flop (scag p.i.rug hel)) war)
1189+ ==
1190+ ::
1191+ |
1192+ %= $
1193+ rug t.rug
1194+ hel =+ gur=(flop p.i.rug)
1195+ |- ^+ hel
1196+ ?~ gur hel
1197+ ?>(&(?=(^ hel) =(i.gur i.hel)) $(hel t.hel, gur t.gur))
1198+ war (weld q.i.rug war)
1199+ ==
1200+ ==
1201+
1202+We accumulate our final result in `war`. If there's nothing more in our
1203+list of merge instructions (unces), we just reverse `war` and produce
1204+it. Otherwise, we process another unce. If the unce is of type `&`, then
1205+we have `p.i.rug` lines of no changes, so we just copy them over from
1206+`hel` to `war`. If the unice is of type `|`, then we verify that the
1207+source lines (in `hel`) are what we expect them to be (`p.i.rug`),
1208+crashing on failure. If they're good, then we append the new lines in
1209+`q.i.rug` onto `war`.
1210+
1211+And that's really it. List merges are pretty easy. Anyway, if you
1212+recall, we were discussing `++checkout-ankh`.
1213+
1214+ ++ checkout-ankh :: checkout-ankh:ze
1215+ |= hat=(map path lobe) :: checkout commit
1216+ ^- ankh
1217+ %- cosh
1218+ %+ roll (~(tap by hat) ~)
1219+ |= [[pat=path bar=lobe] ank=ankh]
1220+ ^- ankh
1221+ %- cosh
1222+ ?~ pat
1223+ =+ zar=(lobe-to-noun bar)
1224+ ank(q [~ (sham zar) zar])
1225+ =+ nak=(~(get by r.ank) i.pat)
1226+ %= ank
1227+ r %+ ~(put by r.ank) i.pat
1228+ $(pat t.pat, ank (fall nak _ankh))
1229+ ==
1230+
1231+If the path is null, then we calculate `zar`, the raw data at the path
1232+`pat` in this version. We produce the given ankh with the correct data.
1233+
1234+Otherwise, we try to get the child we're looking at from our parent
1235+ankh. If it's already been created, this succeeds; otherwise, we simply
1236+create a default blank ankh. We place ourselves in our parent after
1237+recursively computing our children.
1238+
1239+This algorithm really isn't that complicated, but it may not be
1240+immediately obvious why it works. An example should clear everything up.
1241+
1242+Suppose `hat` is a map of the following information.
1243+
1244+ /greeting --> "customary upon meeting"
1245+ /greeting/english --> "hello"
1246+ /greeting/spanish --> "hola"
1247+ /greeting/russian/short --> "привет"
1248+ /greeting/russian/long --> "Здравствуйте"
1249+ /farewell/russian --> "до свидания"
1250+
1251+Furthermore, let's say that we process them in this order:
1252+
1253+ /greeting/english
1254+ /greeting/russian/short
1255+ /greeting/russian/long
1256+ /greeting
1257+ /greeting/spanish
1258+ /farewell/russian
1259+
1260+Then, the first path we process is `/greeting/english` . Since our path
1261+is not null, we try to get `nak`, but because our ankh is blank at this
1262+point it doesn't find anything. Thus, update our blank top-level ankh
1263+with a child `%greeting`. and recurse with the blank `nak` to create the
1264+ankh of the new child.
1265+
1266+In the recursion, we our path is `/english` and our ankh is again blank.
1267+We try to get the `english` child of our ankh, but this of course fails.
1268+Thus, we update our blank `/greeting` ankh with a child `english`
1269+produced by recursing.
1270+
1271+Now our path is null, so we call `++lobe-to-noun` to get the actual
1272+data, and we place it in the brand-new ankh.
1273+
1274+Next, we process `/greeting/russian/short`. Since our path is not null,
1275+we try to get the child named `%greeting`, which does exist since we
1276+created it earlier. We put modify this child by recursing on it. Our
1277+path is now `/russian/short`, so we look for a `%russian` child in our
1278+`/greeting` ankh. This doesn't exist, so we add it by recursing. Our
1279+path is now `/short`, so we look for a `%short` child in our
1280+`/greeting/russian` ankh. This doesn't exist, so we add it by recursing.
1281+Now our path is null, so we set the contents of this node to `"привет"`,
1282+and we're done processing this path.
1283+
1284+Next, we process `/greeting/russian/long`. This proceeds similarly to
1285+the previous except that now the ankh for `/greeting/russian` already
1286+exists, so we simply reuse it rather than creating a new one. Of course,
1287+we still must create a new `/greeting/russian/long` ankh.
1288+
1289+Next, we process `/greeting`. This ankh already exists, so after we've
1290+recursed once, our path is null, and our ankh is not blank -- it already
1291+has two children (and two grandchildren). We don't touch those, though,
1292+since a node may be both a file and a directory. We just add the
1293+contents of the file -- "customary upon meeting" -- to the existing
1294+ankh.
1295+
1296+Next, we process `/greeting/spanish`. Of course, the `/greeting` ankh
1297+already exists, but it doesn't have a `%spanish` child, so we create
1298+that, taking care not to disturb the contents of the `/greeting` file.
1299+We put "hola" into the ankh and call it good.
1300+
1301+Finally, we process `/farewell/russian`. Here, the `/farewell` ankh
1302+doesn't exist, so we create it. Clearly the newly-created ankh doesn't
1303+have any children, so we have to add a `%russian` child, and in this
1304+child we put our last content -- "до свидания".
1305+
1306+We hope it's fairly obvious that the order we process the paths doesn't
1307+affect the final ankh tree. The tree will be constructed in a very
1308+different order depending on what order the paths come in, but the
1309+resulting tree is independent of order.
1310+
1311+At any rate, we were talking about something important, weren't we? If
1312+you recall, that concludes our discussion of `++rewind`, which was
1313+called from `++read-at-aeon`. In summary, `++rewind` returns a context
1314+in which our current state is (very nearly) as it was when the specified
1315+version of the desk was the head. This allows `++read-at-aeon` to call
1316+`++read` to read the requested information.
1317+
1318+ ++ read :: read:ze
1319+ |= mun=mood :: read at point
1320+ ^- (unit)
1321+ ?: ?=(%v p.mun)
1322+ [~ `dome`+<+<.read]
1323+ ?: &(?=(%w p.mun) !?=(%ud -.q.mun))
1324+ ?^(r.mun ~ [~ let])
1325+ ?: ?=(%w p.mun)
1326+ =+ ^= yak
1327+ %- tako-to-yaki
1328+ %- aeon-to-tako
1329+ let
1330+ ?^(r.mun ~ [~ [t.yak (forge-nori yak)]])
1331+ ::?> ?=(^ hit) ?^(r.mun ~ [~ i.hit]) :: what do?? need [@da nori]
1332+ (query(ank ank:(descend-path:(zu ank) r.mun)) p.mun)
1333+
1334+If we're requesting the dome, then we just return that immediately.
1335+
1336+If we're requesting the revision number of the desk and we're not
1337+requesting it by number, then we just return the current number of this
1338+desk. Note of course that this was really already handled in
1339+`++read-at-aeon`.
1340+
1341+If we're requesting a `%w` with a specific revision number, then we do
1342+something or other with the commit there. It's kind of weird, and it
1343+doesn't seem to work, so we'll ignore this case.
1344+
1345+Otherwise, we descend into the ankh tree to the given path with
1346+`++descend-path:zu`, and then we handle specific request in `++query`.
1347+
1348+ ++ descend-path :: descend recursively
1349+ |= way=path
1350+ ^+ +>
1351+ ?~(way +> $(way t.way, +> (descend i.way)))
1352+
1353+This is simple recursion down into the ankh tree. `++descend` descends
1354+one level, so this will eventually get us down to the path we want.
1355+
1356+ ++ descend :: descend
1357+ |= lol=@ta
1358+ ^+ +>
1359+ =+ you=(~(get by r.ank) lol)
1360+ +>.$(ram [lol ram], ank ?~(you [*cash ~ ~] u.you))
1361+
1362+`ram` is the path that we're at, so to descend one level we push the
1363+name of this level onto that path. We update the ankh with the correct
1364+one at that path if it exists; else we create a blank one.
1365+
1366+Once we've decscended to the correct level, we need to actually deal
1367+with the request.
1368+
1369+ ++ query :: query:ze
1370+ |= ren=?(%u %v %x %y %z) :: endpoint query
1371+ ^- (unit ,*)
1372+ ?- ren
1373+ %u [~ `rang`+<+>.query]
1374+ %v [~ `dome`+<+<.query]
1375+ %x ?~(q.ank ~ [~ q.u.q.ank])
1376+ %y [~ as-arch]
1377+ %z [~ ank]
1378+ ==
1379+
1380+Now that everything's set up, it's really easy. If they're requesting
1381+the rang, dome, or ankh, we give it to them. If the contents of a file,
1382+we give it to them if it is in fact a file. If the `arch`, then we
1383+calculate it with `++as-arch`.
1384+
1385+ ++ as-arch :: as-arch:ze
1386+ ^- arch :: arch report
1387+ :+ p.ank
1388+ ?~(q.ank ~ [~ p.u.q.ank])
1389+ |- ^- (map ,@ta ,~)
1390+ ?~ r.ank ~
1391+ [[p.n.r.ank ~] $(r.ank l.r.ank) $(r.ank r.r.ank)]
1392+
1393+This very simply strips out all the "real" data and returns just our own
1394+hash, the hash of the file contents (if we're a file), and a map of the
1395+names of our immediate children.
1396+
1397+Lifecycle of a Local Subscription
1398+---------------------------------
1399+
1400+A subscription to a range of revisions of a desk initially follows the
1401+same path that a single read does. In `++aver`, we checked the head of
1402+the given rave. If the head was `&`, then it was a single request, so we
1403+handled it above. If `|`, then we handle it with the following code.
1404+
1405+ =+ nab=(~(case-to-aeon ze lim dom ran) p.p.rav)
1406+ ?~ nab
1407+ ?> =(~ (~(case-to-aeon ze lim dom ran) q.p.rav))
1408+ (duce hen (rive rav))
1409+ =+ huy=(~(case-to-aeon ze lim dom ran) q.p.rav)
1410+ ?: &(?=(^ huy) |((lth u.huy u.nab) &(=(0 u.huy) =(0 u.nab))))
1411+ (blub hen)
1412+ =+ top=?~(huy let.dom u.huy)
1413+ =+ sar=(~(lobes-at-path ze lim dom ran) u.nab r.p.rav)
1414+ =+ ear=(~(lobes-at-path ze lim dom ran) top r.p.rav)
1415+ =. +>.$
1416+ ?: =(sar ear) +>.$
1417+ =+ fud=(~(make-nako ze lim dom ran) u.nab top)
1418+ (bleb hen u.nab fud)
1419+ ?^ huy
1420+ (blub hen)
1421+ =+ ^= ptr ^- case
1422+ [%ud +(let.dom)]
1423+ (duce hen `rove`[%| ptr q.p.rav r.p.rav ear])
1424+ ==
1425+
1426+Recall that `++case-to-aeon:ze` produces the revision number that a case
1427+corresponds to, if it corresponds to any. If it doesn't yet correspond
1428+to a revision, then it produces null.
1429+
1430+Thus, we first check to see if we've even gotten to the beginning of the
1431+range of revisions requested. If not, then we assert that we haven't yet
1432+gotten to the end of the range either, because that would be really
1433+strange. If not, then we immediately call `++duce`, which, if you
1434+recall, for a local request, simply puts this duct and rove into our
1435+cult `qyx`, so that we know who to respond to when the revision does
1436+appear.
1437+
1438+If we've already gotten to the first revision, then we can produce some
1439+content immediately. If we've also gotten to the final revision, and
1440+that revision is earlier than the start revision, then it's a bad
1441+request and we call `++blub`, which tells the subscriber that his
1442+subscription will not be satisfied.
1443+
1444+Otherwise, we find the data at the given path at the beginning of the
1445+subscription and at the last available revision in the subscription. If
1446+they're the same, then we don't send a notification. Otherwise, we call
1447+`++gack`, which creates the `++nako` we need to produce. We call
1448+`++bleb` to actually produce the information.
1449+
1450+If we already have the last requested revision, then we also tell the
1451+subscriber with `++blub` that the subscription will receive no further
1452+updates.
1453+
1454+If there will be more revisions in the subscription, then we call
1455+`++duce`, adding the duct to our subscribers. We modify the rove to
1456+start at the next revision since we've already handled all the revisions
1457+up to the present.
1458+
1459+We glossed over the calls to `++lobes-at-path`, `++make-nako`, and
1460+`++bleb`, so we'll get back to those right now. `++bleb` is simple, so
1461+we'll start with that.
1462+
1463+ ++ bleb :: ship sequence
1464+ |= [hen=duct ins=@ud hip=nako]
1465+ ^+ +>
1466+ (blab hen [%w [%ud ins] ~] hip)
1467+
1468+We're given a duct, the beginning revision number, and the nako that
1469+contains the updates since that revision. We use `++blab` to produce
1470+this result to the subscriber. The case is `%w` with a revision number
1471+of the beginning of the subscription, and the data is the nako itself.
1472+
1473+We call `++lobes-at-path:ze` to get the data at the particular path.
1474+
1475+ ++ lobes-at-path :: lobes-at-path:ze
1476+ |= [oan=aeon pax=path] :: data at path
1477+ ^- (map path lobe)
1478+ ?: =(0 oan) ~
1479+ %- mo
1480+ %+ skim
1481+ %. ~
1482+ %~ tap by
1483+ =< q
1484+ %- tako-to-yaki
1485+ %- aeon-to-tako
1486+ oan
1487+ |= [p=path q=lobe]
1488+ ?| ?=(~ pax)
1489+ ?& !?=(~ p)
1490+ =(-.pax -.p)
1491+ $(p +.p, pax +.pax)
1492+ == ==
1493+
1494+At revision zero, the theoretical common revision between all
1495+repositories, there is no data, so we produce null.
1496+
1497+We get the list of paths (paired with their lobe) in the revision
1498+referred to by the given number and we keep only those paths which begin
1499+with `pax`. Converting to a map, we now have a map from the subpaths at
1500+the given path to the hash of their data. This is simple and efficient
1501+to calculate and compare to later revisions. This allows us to easily
1502+tell if a node or its children have changed.
1503+
1504+Finally, we will describe `++make-nako:ze`.
1505+
1506+ ++ make-nako :: gack a through b
1507+ |= [a=aeon b=aeon]
1508+ ^- [(map aeon tako) aeon (set yaki) (set blob)]
1509+ :_ :- b
1510+ =- [(takos-to-yakis -<) (lobes-to-blobs ->)]
1511+ %+ reachable-between-takos
1512+ (~(get by hit) a) :: if a not found, a=0
1513+ (aeon-to-tako b)
1514+ ^- (map aeon tako)
1515+ %- mo %+ skim (~(tap by hit) ~)
1516+ |= [p=aeon *]
1517+ &((gth p a) (lte p b))
1518+
1519+We need to produce four things -- the numbers of the new commits, the
1520+number of the latest commit, the new commits themselves, and the new
1521+data itself.
1522+
1523+The first is fairly easy to produce. We simply go over our map of
1524+numbered commits and produce all those numbered greater than `a` and not
1525+greater than `b`.
1526+
1527+The second is even easier to produce -- `b` is clearly our most recent
1528+commit.
1529+
1530+The third and fourth are slightly more interesting, though not too
1531+terribly difficult. First, we call `++reachable-between-takos`.
1532+
1533+ ++ reachable-between-takos
1534+ |= [a=(unit tako) b=tako] :: pack a through b
1535+ ^- [(set tako) (set lobe)]
1536+ =+ ^= sar
1537+ ?~ a ~
1538+ (reachable-takos r:(tako-to-yaki u.a))
1539+ =+ yak=`yaki`(tako-to-yaki b)
1540+ %+ new-lobes-takos (new-lobes ~ sar) :: get lobes
1541+ |- ^- (set tako) :: walk onto sar
1542+ ?: (~(has in sar) r.yak)
1543+ ~
1544+ =+ ber=`(set tako)`(~(put in `(set tako)`~) `tako`r.yak)
1545+ %- ~(uni in ber)
1546+ ^- (set tako)
1547+ %+ roll p.yak
1548+ |= [yek=tako bar=(set tako)]
1549+ ^- (set tako)
1550+ ?: (~(has in bar) yek) :: save some time
1551+ bar
1552+ %- ~(uni in bar)
1553+ ^$(yak (tako-to-yaki yek))
1554+
1555+We take a possible starting commit and a definite ending commit, and we
1556+produce the set of commits and the set of data between them.
1557+
1558+We let `sar` be the set of commits reachable from `a`. If `a` is null,
1559+then obviously no commits are reachable. Otherwise, we call
1560+`++reachable-takos` to calculate this.
1561+
1562+ ++ reachable-takos :: reachable
1563+ |= p=tako :: XX slow
1564+ ^- (set tako)
1565+ =+ y=(tako-to-yaki p)
1566+ =+ t=(~(put in _(set tako)) p)
1567+ %+ roll p.y
1568+ |= [q=tako s=_t]
1569+ ?: (~(has in s) q) :: already done
1570+ s :: hence skip
1571+ (~(uni in s) ^$(p q)) :: otherwise traverse
1572+
1573+We very simply produce the set of the given tako plus its parents,
1574+recursively.
1575+
1576+Back in `++reachable-between-takos`, we let `yak` be the yaki of `b`,
1577+the ending commit. With this, we create a set that is the union of `sar`
1578+and all takos reachable from `b`.
1579+
1580+We pass `sar` into `++new-lobes` to get all the lobes referenced by any
1581+tako referenced by `a`. The result is passed into `++new-lobes-takos` to
1582+do the same, but not recomputing those in already calculated last
1583+sentence. This produces the sets of takos and lobes we need.
1584+
1585+ ++ new-lobes :: object hash set
1586+ |= [b=(set lobe) a=(set tako)] :: that aren't in b
1587+ ^- (set lobe)
1588+ %+ roll (~(tap in a) ~)
1589+ |= [tak=tako bar=(set lobe)]
1590+ ^- (set lobe)
1591+ =+ yak=(tako-to-yaki tak)
1592+ %+ roll (~(tap by q.yak) ~)
1593+ |= [[path lob=lobe] far=_bar]
1594+ ^- (set lobe)
1595+ ?~ (~(has in b) lob) :: don't need
1596+ far
1597+ =+ gar=(lobe-to-blob lob)
1598+ ?- -.gar
1599+ %direct (~(put in far) lob)
1600+ %delta (~(put in $(lob q.gar)) lob)
1601+ %indirect (~(put in $(lob s.gar)) lob)
1602+ ==
1603+
1604+Here, we're creating a set of lobes referenced in a commit in `a`. We
1605+start out with `b` as the initial set of lobes, so we don't need to
1606+recompute any of the lobes referenced in there.
1607+
1608+The algorithm is pretty simple, so we won't bore you with the details.
1609+We simply traverse every commit in `a`, looking at every blob referenced
1610+there, and, if it's not already in `b`, we add it to `b`. In the case of
1611+a direct blob, we're done. For a delta or an indirect blob, we
1612+recursively add every blob referenced within the blob.
1613+
1614+ ++ new-lobes-takos :: garg & repack
1615+ |= [b=(set lobe) a=(set tako)]
1616+ ^- [(set tako) (set lobe)]
1617+ [a (new-lobes b a)]
1618+
1619+Here, we just update the set of lobes we're given with the commits we're
1620+given and produce both sets.
1621+
1622+This concludes our discussion of a local subscription.
1623+
1624+Lifecycle of a Foreign Read or Subscription
1625+-------------------------------------------
1626+
1627+Foreign reads and subscriptions are handled in much the same way as
1628+local ones. The interface is the same -- a vane or app sends a `%warp`
1629+kiss with the request. The difference is simply that the `sock` refers
1630+to the foreign ship.
1631+
1632+Thus, we start in the same place -- in `++call`, handling `%warp`.
1633+However, since the two side of the `sock` are different, we follow a
1634+different path.
1635+
1636+ =+ wex=(do now p.q.hic p.q.q.hic ruf)
1637+ =+ ^= woo
1638+ ?~ q.q.q.hic
1639+ abet:(ease:wex hen)
1640+ abet:(eave:wex hen u.q.q.q.hic)
1641+ [-.woo (posh q.p.q.hic p.q.q.hic +.woo ruf)]
1642+
1643+If we compare this to how the local case was handled, we see that it's
1644+not all that different. We use `++do` rather than `++un` and `++de` to
1645+set up the core for the foreign ship. This gives us a `++de` core, so we
1646+either cancel or begin the request by calling `++ease` or `++eave`,
1647+exactly as in the local case. In either case, we call `++abet:de` to
1648+resolve our various types of output into actual moves, as described in
1649+the local case. Finally, we call `++posh` to update our raft, putting
1650+the modified rung into the raft.
1651+
1652+We'll first trace through `++do`.
1653+
1654+ ++ do
1655+ |= [now=@da [who=ship him=ship] syd=@tas ruf=raft]
1656+ =+ ^= rug ^- rung
1657+ =+ rug=(~(get by hoy.ruf) him)
1658+ ?^(rug u.rug *rung)
1659+ =+ ^= red ^- rede
1660+ =+ yit=(~(get by rus.rug) syd)
1661+ ?^(yit u.yit `rede`[~2000.1.1 ~ [~ *rind] *dome])
1662+ ((de now ~ ~) [who him] syd red ran.ruf)
1663+
1664+If we already have a rung for this foreign ship, then we use that.
1665+Otherwise, we create a new blank one. If we already have a rede in this
1666+rung, then we use that, otherwise we create a blank one. An important
1667+point to note here is that we let `ref` in the rede be `[~ *rind]`.
1668+Recall, for domestic desks `ref` is null. We use this to distinguish
1669+between foreign and domestic desks in `++de`.
1670+
1671+With this information, we create a `++de` core as usual.
1672+
1673+Although we've already covered `++ease` and `++eave`, we'll go through
1674+them quickly again, highlighting the case of foreign request.
1675+
1676+ ++ ease :: release request
1677+ |= hen=duct
1678+ ^+ +>
1679+ ?~ ref +>
1680+ =+ rov=(~(got by qyx) hen)
1681+ =. qyx (~(del by qyx) hen)
1682+ (mabe rov (cury best hen))
1683+ =. qyx (~(del by qyx) hen)
1684+ |- ^+ +>+.$
1685+ =+ nux=(~(get by fod.u.ref) hen)
1686+ ?~ nux +>+.$
1687+ %= +>+.$
1688+ say [[hen [(scot %ud u.nux) ~] for [u.nux syd ~]] say]
1689+ fod.u.ref (~(del by fod.u.ref) hen)
1690+ bom.u.ref (~(del by bom.u.ref) u.nux)
1691+ ==
1692+
1693+Here, we still remove the duct from our cult (we maintain a cult even
1694+for foreign desks), but we also need to tell the foreign desk to cancel
1695+our subscription. We do this by sending a request (by appending to
1696+`say`, which gets resolved in `++abet:de` to a `%want` kiss to ames) to
1697+the foreign ship to cancel the subscription. Since we don't anymore
1698+expect a response on this duct, we remove it from `fod` and `bom`, which
1699+are the maps between ducts, raves, and request sequence numbers.
1700+Basically, we remove every trace of the subscription from our request
1701+manager.
1702+
1703+In the case of `++eave`, where we're creating a new request, everything
1704+is exactly identical to the case of the local request except `++duce`.
1705+We said that `++duce` simply puts the request into our cult. This is
1706+true for a domestic request, but distinctly untrue for foreign requests.
1707+
1708+ ++ duce :: produce request
1709+ |= [hen=duct rov=rove]
1710+ ^+ +>
1711+ =. qyx (~(put by qyx) hen rov)
1712+ ?~ ref +>.$
1713+ |- ^+ +>+.$ :: XX why?
1714+ =+ rav=(reve rov)
1715+ =+ ^= vaw ^- rave
1716+ ?. ?=([%& %v *] rav) rav
1717+ [%| [%ud let.dom] `case`q.p.rav r.p.rav]
1718+ =+ inx=nix.u.ref
1719+ %= +>+.$
1720+ say [[hen [(scot %ud inx) ~] for [inx syd ~ vaw]] say]
1721+ nix.u.ref +(nix.u.ref)
1722+ bom.u.ref (~(put by bom.u.ref) inx [hen vaw])
1723+ fod.u.ref (~(put by fod.u.ref) hen inx)
1724+ ==
1725+
1726+If we have a request manager (i.e. this is a foreign desk), then we do
1727+the approximate inverse of `++ease`. We create a rave out of the given
1728+request and send it off to the foreign desk by putting it in `say`. Note
1729+that the rave is created to request the information starting at the next
1730+revision number. Since this is a new request, we put it into `fod` and
1731+`bom` to associate the request with its duct and its sequence number.
1732+Since we're using another sequence number, we must increment `nix`,
1733+which represents the next available sequence number.
1734+
1735+And that's really it for this side of the request. Requesting foreign
1736+information isn't that hard. Let's see what it looks like on the other
1737+side. When we get a request from another ship for information on our
1738+ship, that comes to us in the form of a `%wart` from ames.
1739+
1740+We handle a `%wart` in `++call`, right next to where we handle the
1741+`%warp` case.
1742+
1743+ %wart
1744+ ?> ?=(%re q.q.hic)
1745+ =+ ryf=((hard riff) s.q.hic)
1746+ :_ ..^$
1747+ :~ :- hen
1748+ :^ %pass [(scot %p p.p.q.hic) (scot %p q.p.q.hic) r.q.hic]
1749+ %c
1750+ [%warp [p.p.q.hic p.p.q.hic] ryf]
1751+ ==
1752+
1753+Every request we receive should be of type `riff`, so we coerce it into
1754+that type. We just convert this into a new `%warp` kiss that we pass to
1755+ourself. This gets handled like normal, as a local request. When the
1756+request produces a value, it does so like normal as a `%writ`, which is
1757+returned to `++take` along the path we just sent it on.
1758+
1759+ %writ
1760+ ?> ?=([@ @ *] tea)
1761+ =+ our=(need (slaw %p i.tea))
1762+ =+ him=(need (slaw %p i.t.tea))
1763+ :_ ..^$
1764+ :~ :- hen
1765+ [%pass ~ %a [%want [our him] [%r %re %c t.t.tea] p.+.q.hin]]
1766+ ==
1767+
1768+Since we encoded the ship we need to respond to in the path, we can just
1769+pass our `%want` back to ames, so that we tell the requesting ship about
1770+the new data.
1771+
1772+This comes back to the original ship as a `%waft` from ames, which comes
1773+into `++take`, right next to where we handled `%writ`.
1774+
1775+ %waft
1776+ ?> ?=([@ @ ~] tea)
1777+ =+ syd=(need (slaw %tas i.tea))
1778+ =+ inx=(need (slaw %ud i.t.tea))
1779+ =+ ^= zat
1780+ =< wake
1781+ (knit:(do now p.+.q.hin syd ruf) [inx ((hard riot) q.+.q.hin)])
1782+ =^ mos ruf
1783+ =+ zot=abet.zat
1784+ [-.zot (posh q.p.+.q.hin syd +.zot ruf)]
1785+ [mos ..^$(ran.ruf ran.zat)] :: merge in new obj
1786+
1787+This gets the desk and sequence number from the path the request was
1788+sent over. This determines exactly which request is being responded to.
1789+We call `++knit:de` to apply the changes to our local desk, and we call
1790+`++wake` to update our subscribers. Then we call `++abet:de` and
1791+`++posh` as normal (like in `++eave`).
1792+
1793+We'll examine `++knit` and `++wake`, in that order.
1794+
1795+ ++ knit :: external change
1796+ |= [inx=@ud rot=riot]
1797+ ^+ +>
1798+ ?> ?=(^ ref)
1799+ |- ^+ +>+.$
1800+ =+ ruv=(~(get by bom.u.ref) inx)
1801+ ?~ ruv +>+.$
1802+ => ?. |(?=(~ rot) ?=(& -.q.u.ruv)) .
1803+ %_ .
1804+ bom.u.ref (~(del by bom.u.ref) inx)
1805+ fod.u.ref (~(del by fod.u.ref) p.u.ruv)
1806+ ==
1807+ ?~ rot
1808+ =+ rav=`rave`q.u.ruv
1809+ %= +>+.$
1810+ lim
1811+ ?.(&(?=(| -.rav) ?=(%da -.q.p.rav)) lim `@da`p.q.p.rav)
1812+ ::
1813+ haw.u.ref
1814+ ?. ?=(& -.rav) haw.u.ref
1815+ (~(put by haw.u.ref) p.rav ~)
1816+ ==
1817+ ?< ?=(%v p.p.u.rot)
1818+ =. haw.u.ref
1819+ (~(put by haw.u.ref) [p.p.u.rot q.p.u.rot q.u.rot] ~ r.u.rot)
1820+ ?. ?=(%w p.p.u.rot) +>+.$
1821+ |- ^+ +>+.^$
1822+ =+ nez=[%w [%ud let.dom] ~]
1823+ =+ nex=(~(get by haw.u.ref) nez)
1824+ ?~ nex +>+.^$
1825+ ?~ u.nex +>+.^$ :: should never happen
1826+ =. +>+.^$ =+ roo=(edis ((hard nako) u.u.nex))
1827+ ?>(?=(^ ref.roo) roo)
1828+ %= $
1829+ haw.u.ref (~(del by haw.u.ref) nez)
1830+ ==
1831+
1832+This is kind of a long gate, but don't worry, it's not bad at all.
1833+
1834+First, we assert that we're not a domestic desk. That wouldn't make any
1835+sense at all.
1836+
1837+Since we have the sequence number of the request, we can get the duct
1838+and rave from `bom` in our request manager. If we didn't actually
1839+request this data (or the request was canceled before we got it), then
1840+we do nothing.
1841+
1842+Else, we remove the request from `bom` and `fod` unless this was a
1843+subscription request and we didn't receive a null riot (which would
1844+indicate the last message on the subscription).
1845+
1846+Now, if we received a null riot, then if this was a subscription request
1847+by date, then we update `lim` in our request manager (representing the
1848+latest time at which we have complete information for this desk) to the
1849+date that was requested. If this was a single read request, then we put
1850+the result in our simple cache `haw` to make future requests faster.
1851+Then we're done.
1852+
1853+If we received actual data, then we put it into our cache `haw`. Unless
1854+it's a `%w` request, we're done.
1855+
1856+If it is a `%w` request, then we try to get the `%w` at our current head
1857+from the cache. In general, that should be the thing we just put in a
1858+moment ago, but that is not guaranteed. The most common case where this
1859+is different is when we receive desk updates out of order. At any rate,
1860+since we now have new information, we need to apply it to our local copy
1861+of the desk. We do so in `++edis`, and then we remove the stuff we just
1862+applied from the cache, since it's not really a true "single read", like
1863+what should really be in the cache.
1864+
1865+ ++ edis :: apply subscription
1866+ |= nak=nako
1867+ ^+ +>
1868+ %= +>
1869+ hit.dom (~(uni by hit.dom) gar.nak)
1870+ let.dom let.nak
1871+ lat.ran %+ roll (~(tap in bar.nak) ~)
1872+ =< .(yeb lat.ran)
1873+ |= [sar=blob yeb=(map lobe blob)]
1874+ =+ zax=(blob-to-lobe sar)
1875+ %+ ~(put by yeb) zax sar
1876+ hut.ran %+ roll (~(tap in lar.nak) ~)
1877+ =< .(yeb hut.ran)
1878+ |= [sar=yaki yeb=(map tako yaki)]
1879+ %+ ~(put by yeb) r.sar sar
1880+ ==
1881+
1882+This shows, of course, exactly why nako is defined the way it is. To
1883+become completely up to date with the foreign desk, we need to merge
1884+`hit` with the foreign one so that we have all the revision numbers. We
1885+update `let` so that we know which revision is the head.
1886+
1887+We merge the new blobs in `lat`, keying them by their hash, which we get
1888+from a call to `++blob-to-lobe`. Recall that the hash is stored in the
1889+actual blob itself. We do the same thing to the new yakis, putting them
1890+in `hut`, keyed by their hash.
1891+
1892+Now, our local dome should be exactly the same as the foreign one.
1893+
1894+This concludes our discussion of `++knit`. Now the changes have been
1895+applied to our local copy of the desk, and we just need to update our
1896+subscribers. We do so in `++wake:de`.
1897+
1898+ ++ wake :: update subscribers
1899+ ^+ .
1900+ =+ xiq=(~(tap by qyx) ~)
1901+ =| xaq=(list ,[p=duct q=rove])
1902+ |- ^+ ..wake
1903+ ?~ xiq
1904+ ..wake(qyx (~(gas by *cult) xaq))
1905+ ?- -.q.i.xiq
1906+ &
1907+ =+ cas=?~(ref ~ (~(get by haw.u.ref) `mood`p.q.i.xiq))
1908+ ?^ cas
1909+ %= $
1910+ xiq t.xiq
1911+ ..wake ?~ u.cas (blub p.i.xiq)
1912+ (blab p.i.xiq p.q.i.xiq u.u.cas)
1913+ ==
1914+ =+ nao=(~(case-to-aeon ze lim dom ran) q.p.q.i.xiq)
1915+ ?~ nao $(xiq t.xiq, xaq [i.xiq xaq])
1916+ $(xiq t.xiq, ..wake (balk p.i.xiq u.nao p.q.i.xiq))
1917+ ::
1918+ |
1919+ =+ mot=`moot`p.q.i.xiq
1920+ =+ nab=(~(case-to-aeon ze lim dom ran) p.mot)
1921+ ?~ nab
1922+ $(xiq t.xiq, xaq [i.xiq xaq])
1923+ =+ huy=(~(case-to-aeon ze lim dom ran) q.mot)
1924+ ?~ huy
1925+ =+ ptr=[%ud +(let.dom)]
1926+ %= $
1927+ xiq t.xiq
1928+ xaq [[p.i.xiq [%| ptr q.mot r.mot s.mot]] xaq]
1929+ ..wake =+ ^= ear
1930+ (~(lobes-at-path ze lim dom ran) let.dom r.p.q.i.xiq)
1931+ ?: =(s.p.q.i.xiq ear) ..wake
1932+ =+ fud=(~(make-nako ze lim dom ran) u.nab let.dom)
1933+ (bleb p.i.xiq let.dom fud)
1934+ ==
1935+ %= $
1936+ xiq t.xiq
1937+ ..wake =- (blub:- p.i.xiq)
1938+ =+ ^= ear
1939+ (~(lobes-at-path ze lim dom ran) u.huy r.p.q.i.xiq)
1940+ ?: =(s.p.q.i.xiq ear) (blub p.i.xiq)
1941+ =+ fud=(~(make-nako ze lim dom ran) u.nab u.huy)
1942+ (bleb p.i.xiq +(u.nab) fud)
1943+ ==
1944+ ==
1945+ --
1946+
1947+This is even longer than `++knit`, but it's pretty similar to `++eave`.
1948+We loop through each of our subscribers `xiq`, processing each in turn.
1949+When we're done, we just put the remaining subscribers back in our
1950+subscriber list.
1951+
1952+If the subscriber is a single read, then, if this is a foreign desk
1953+(note that `++wake` is called from other arms, and not only on foreign
1954+desks). Obviously, if we find an identical request there, then we can
1955+produce the result immediately. Referential transparency for the win. We
1956+produce the result with a call to `++blab`. If this is a foreign desk
1957+but the result is not in the cache, then we produce `++blub` (canceled
1958+subscription with no data) for reasons entirely opaque to me. Seriously,
1959+it seems like we should wait until we get an actual response to the
1960+request. If someone figures out why this is, let me know. At any rate,
1961+it seems to work.
1962+
1963+If this is a domestic desk, then we check to see if the case exists yet.
1964+If it doesn't, then we simply move on to the next subscriber, consing
1965+this one onto `xaq` so that we can check again the next time around. If
1966+it does exist, then we call `++balk` to fulfill the request and produce
1967+it.
1968+
1969+`++balk` is very simple, so we'll describe it here before we get to the
1970+subscription case.
1971+
1972+ ++ balk :: read and send
1973+ |= [hen=duct oan=@ud mun=mood]
1974+ ^+ +>
1975+ =+ vid=(~(read-at-aeon ze lim dom ran) oan mun)
1976+ ?~ vid (blub hen) (blab hen mun u.vid)
1977+
1978+We call `++read-at-aeon` on the given request and aeon. If you recall,
1979+this processes a `mood` at a particular aeon and produces the result, if
1980+there is one. If there is data at the requested location, then we
1981+produce it with `++blab`. Else, we call `++blub` to notify the
1982+subscriber that no data can ever come over this subscriptioin since it
1983+is now impossible for there to ever be data for the given request.
1984+Because referential transparency.
1985+
1986+At any rate, back to `++wake`. If the given rave is a subscription
1987+request, then we proceed similarly to how we do in `++eave`. We first
1988+try to get the aeon referred to by the starting case. If it doesn't
1989+exist yet, then we can't do anything interesting with this subscription,
1990+so we move on to the next one.
1991+
1992+Otherwise, we try to get the aeon referred to by the ending case. If it
1993+doesn't exist yet, then we produce all the information we can. We call
1994+`++lobes-at-path` at the given aeon and path to see if the requested
1995+path has actually changed. If it hasn't, then we don't produce anything;
1996+else, we produce the correct nako by calling `++bleb` on the result of
1997+`++make-nako`, as in `++eave`. At any rate, we move on to the next
1998+subscription, putting back into our cult the current subscription with a
1999+new start case of the next aeon after the present.
2000+
2001+If the aeon referred to by the ending case does exist, then we drop this
2002+subscriber from our cult and satisfy its request immediately. This is
2003+the same as before -- we check to see if the data at the path has
2004+actually changed, producing it if it has; else, we call `++blub` since
2005+no more data can be produced over this subscription.
2006+
2007+This concludes our discussion of foreign requests.
docs/system/arvo/dill.mdnew file+27
@@ -0,0 +1,27 @@
1+<div class="short">
2+
3+`%dill`
4+=======
5+
6+Our terminal driver.
7+
8+Unix sends keyboard events to `%dill` from either the console or telnet,
9+and `%dill` produces terminal output. The only app that should directly
10+talk to `%dill` is the terminal app. Command-line apps are run by,
11+receive input from, and produce output to, the `%shell` app, which is
12+controlled by `%terminal`, which talks to `%dill`, which talks to unix.
13+Clay also uses `%dill` directly to print out the filesystem change
14+events, but this is questionable behavior.
15+
16+`%dill` has two main components. First, it controls the terminal on a
17+very basic, event-by-event level. This includes keeping track of things
18+like the dimensions of the terminal, the prompt type (plain text or
19+password), which duct to produce effects on, and so forth. Second, it
20+handles terminal events, keystroke by keystroke. Most characters are
21+simply pushed onto the buffer and blitted to the screen, but some
22+characters, including control-modified keys, arrow keys, etc. require
23+special handling. Most of the readline functionality is in `%dill`.
24+
25+</div>
26+
27+------------------------------------------------------------------------
docs/system/arvo/dill/commentary.mdnew file+5
@@ -0,0 +1,5 @@
1+Dill: Reference
2+===============
3+
4+Dill: Commentary
5+================
docs/system/arvo/eyre.mdnew file+63
@@ -0,0 +1,63 @@
1+<div class="short">
2+
3+`%eyre`
4+=======
5+
6+Our http server.
7+
8+Unix sends http messages to `%eyre`, and `%eyre` produces http messages
9+in response. In general, apps and vanes do not call `%eyre`; rather,
10+`%eyre` calls apps and vanes. `%eyre` uses `%ford` and `%gall` to
11+functionally publish pages and facilitate communication with apps.
12+
13+`%eyre` primarily parses web requests and handles them in a variety of
14+ways, depending on the control string. Nearly all of these are
15+essentially stateless, like functional publishing with `%ford`.
16+Additionally, there's a fairly significant component that handles
17+`%gall` messaging and subscriptions, which must be stateful.
18+
19+</div>
20+
21+------------------------------------------------------------------------
22+
23+HTTP Methods
24+============
25+
26+`GET` `gog` `https://[ship-name].urbit.org/gog/[service]` Owner
27+requesting a page on her own Urbit. `gig`
28+`https://[ship-name].urbit.org/gig/[user-name]/[service]` Another user
29+requesting a page on a foreign Urbit.
30+
31+`goe`
32+`https://[ship-name].urbit.org/goe/[service]/[port]/[stream]/[sequence]`
33+`https://[ship-name].urbit.org/goe/[service]/[port]/[stream]/[sequence].json`
34+Pulls a specific response to her subscription on her own Urbit. `gie`
35+`https://[ship-name].urbit.org/gie/[user-name]/[service]/[port]/[stream]/[sequence]`
36+`https://[ship-name].urbit.org/gie/[user-name]/[service]/[port]/[stream]/[sequence].json`
37+Pulls a specific response to her subscription on a foreign Urbit.
38+
39+`PUT` `tos`
40+`https://[ship-name].urbit.org/tos/[service]/[port]/[stream]/[path]`
41+`{oryx: [string]}` Initiate a subscription on her own Urbit. `tis`
42+`https://[ship-name].urbit.org/tis/[user-name]/[service]/[port]/[stream]/[path]`
43+`{oryx: [string]}` Initiate a subscription on a foreign Urbit.
44+
45+`tom` `https://[ship-name].urbit.org/tom/[service]/[port]/[sequence]`
46+`{oryx: [string], xyro: [json]}` Send a message to her Urbit with
47+sequence number `[sequence]`. `tim`
48+`https://[ship-name].urbit.org/tim/[user-name]/[service]/[port]/[sequence]`
49+`{oryx: [string], xyro: [json]}` Send a message to a foreign Urbit with
50+sequence number `[sequence]`.
51+
52+`tou` `https://[ship-name].urbit.org/tou/[service]/[port]/[stream]`
53+Unsubscribe from stream `[stream]` on her Urbit. `tiu`
54+`https://[ship-name].urbit.org/tiu/[user-name]/[service]/[port]/[stream]`
55+Unsubscribe from stream `[stream]` on a foreign Urbit.
56+
57+urb.js
58+======
59+
60+
61+<hr>
62+</hr>
63+<list></list>
docs/system/arvo/eyre/commentary.mdnew file+273
@@ -0,0 +1,273 @@
1+Eyre: Reference
2+===============
3+
4+## State
5+
6+Stored
7+
8+- `++bolo`
9+- `++cyst`
10+- `++stem`
11+
12+Runtime
13+
14+- `perk`
15+ + `perk-auth`
16+- `pest`
17+- `even`
18+
19+## Cores
20+
21+- `++handle`
22+ + `++parse`
23+ - `++as...`
24+- `++ya`
25+- `++ix`
26+
27+Eyre: Commentary
28+================
29+
30+Let us follow the loading of a simple cli app, as it bounces from
31+browser to server to browser and back.
32+
33+## Initial request[#init]
34+
35+An http request for `http://sampel-sipnym.urbit.org/cli` will be [redirected](dns)
36+to the `%eyre` on ~sampel-sipnym, and come in as a `%this` kiss.
37+
38+From arvo, requests enter `++call`, which after some type reification are passed
39+along to `++apex:ye`. In the case of a `%this` kiss, its components are
40+parsed(see `++zest:epur`, `++eat-headers`) and handed off to `++handle`, wrapped
41+in `++emule` to produce a `++fail` page in case of error. `++apex:handle` will
42+`++process` the request to a `pest` or a `++done` core, and in the former case
43+`++resolve` the pest into an outgoing card.
44+
45+XX it also seems to affect the current ship, test that serving ship name is consistently correct
46+
47+The pest is produced by `++process`, which will first further `++parse` the
48+request, and if this does not make the response immediately obvious,
49+`++process-parsed` the resulting `perk`.
50+
51+`++parse` produces the `perk`, by attempting to interpret the `pork`(url path)
52+[`++as-magic-filename`](#mage), `++as-beam`, and `++as-aux-request`. In this
53+case, `/cli` is parsed by the second case as a `%beam` query to `/=cli=`: a path
54+which starts with a valid ship name is expected to be a full clay(well, ford)
55+path, and one starting with a term implies the current serving ship and a case
56+of `0`, the current revision.
57+
58+XX spur: when the desks are merged, `/cli` shall point to `/=main=/pub/cli`
59+
60+The parsed `perk` generates a `%f %boil` note, `mark`ed as its extension(here
61+defaulting to `%urb`) and `wire`d with `~` to return unaltered to the client. It
62+goes on to `++resolve` by being passed to `++ford-get-beam`, which translates
63+the perk it into a `%boil` `++ford-req`, adding an `++fcgi` path-segment
64+containing query string and `++fcgi-cred:for-client` auth information.
65+
66+`%ford`s translation of `/=cli=/hymn/hook` to a self-refreshing `%urb` html page
67+[deserves its own commentary](../ford/commentary), but we resume in `%eyre`
68+when the `%made` sign arrives in `++take`, and soon after `++axon:ye`. There the
69+`wire`, or rather the `whir` it has been verified to be, determines that the
70+response should be served immediately. However, as the mark is not `%mime`,
71+another trip to `%ford` is required to encode it, on the same wire; afterwards,
72+the value of the `%mime` cage is verified to be of the correct type, and finally
73+delivered back up the requesting duct as a succesful `%thou` HTTP response.
74+
75+XX `%cast %mime` used to be in ford-get-beam, is there a reason it was removed?
76+
77+## Back into the breach, or: auxilary requests
78+
79+Now, it was mentioned that this result is self-refreshing: the `%urb`
80+translation door injects a `;script@"/~/on/{deps}.js"` into every page, `deps`
81+is a ford-readable hash of the set of resources that page construction depended
82+on.
83+
84+This triggers another `%this` request. Its handling is identical to that of
85+`/cli` up until `++parse`, where it is seen not `++as-beam` but
86+`++as-aux-request`(auxillary requests starting with `/~/` or `/~~/`).
87+`/on/[hash]` is a long-`%poll`, which `++process-parsed`, for a `.js` mark,
88+answers with a direct `%js`. Its contents are the static `++poll:js`, which
89+initiates the long-polling loop, run against an injected `urb.js` of
90+`{poll:[hash]}`.
91+
92+A `%js` `pest` is `resolve`d as a `text/javascript` success `%this`.
93+
94+When `poll.js` is recieved by the client, it opens an `XMLHttpRequest` for
95+`/~/on/{window.urb.poll}.json`, bringing us back to `%poll:process`.
96+
97+In the case of a non-`%js` `/~/on/`, `%poll:process-parsed` turns into a
98+`++new-dependency`, which stores the listening duct, and `pass-note`s a `%wasp`
99+with the deps-hash back to `%ford` whence it came. While this occured, the page
100+has loaded.
101+
102+Some indeterminate amount of time afterwards, with dropped `/~/on/{...}.json`s
103+being retried upon expiring and also being stored, a `%news` sign arrives in
104+`++axon`, and the hash in question is retrieved from the wire, and the listening
105+long-polls retrieved by the hash. Each receives a 205 "Reload parent view" HTTP
106+response, which `poll.js` dutifully executes, and a fixed typo of markdown is
107+rendered.
108+
109+## Authentication.
110+
111+Now, while this accurately reflects the presentation of e.g. a markdown file,
112+`/cli` is an application front-end, and one that permits only owner access. Its
113+second script is `@"/~~/~/at/main/lib/urb.js"`, semantically equivalent to
114+`/~/as/own/~/at/main/lib/urb.js`, and handled as follows.
115+
116+In `++as-aux-request`, `%as %own` becomes `%auth %get our` perk, which
117+`++process` passes to `++process-parsed` passes to `++process-auth`. There, a
118+`yac` "ya" core is built `++for-client`: a `++cookie-prefix`, which is just the
119+serving ship name, is used to get a `++session-from-cookies`, here nil as the
120+client has no cookie set. In lieu of a cookie, a `++new-ya` is constructed, with
121+a random token `hole` and a `++new-cyst` which fills out `cyst` session state
122+from request data.
123+
124+Returning to `++process-auth`, `%get` checks if the yac is authenticated with
125+the requested credentials(`anon` requests are always granted), which for the
126+fresh new `cyst` is not the case (more on success [later](#auth-ok)). Unless
127+authentiacting as a [foreign ship](#xeno), the only thing left is to
128+`++show-login-page`, which detects that the requested resource is not `%html`,
129+and produces a `%red` pest. For `%js`, `%red`irections `++resolve` to
130+`++auth-redir:js`, a line of javascript which prepends `/~~` to the url path.
131+
132+The owner-authenticated main page request similarly ends in `++show-login-page`,
133+which for the empty session is an `[%htme ++login-page:xml]`, `resolve`d to
134+`++give-html` with a 401 "unathorized".
135+
136+The login page shows a simple prompt, and requests `/~/at/auth.js` to handle the
137+submission. And so we are, once again, attempting to divine if what we're doing
138+makes sense `++as-aux-request`.
139+
140+To understand `/~/at`, there will first be a brief diversion to `~/auth.json`.
141+`auth.json`, perk `[%auth %json]`, in `++process-auth` serves `++stat-json:ya`,
142+containing such information as the serving ship, which identities are associated
143+with this session, and `oryx`, a CSRF token. An oryx must be present on all
144+stateful requests, in this case executing a log in. It also saves the new/old
145+session using `abet`.
146+
147+XX explain `ixor` here and not [later](#ixor)?
148+
149+`/~/at` is an alternate interface, which injects `auth.json` data into the
150+requested file. `/~/at/auth.js`, then, is a request for the built-in `auth:js`
151+(parsed to and processed from an `[%auth %js ~]` perk), with session data added
152+as `window.urb`. And indeed, ``[`%js /~/at/auth]`` is parsed to
153+``[%auth at [`%js /auth]``, which in `++process-auth` is re-`process`ed to
154+`[%js ++auth:js]`, which is `++resolve`d after an `++add-json` of
155+the relevant data. The yac cookies are also passed to `resolve`, which
156+`++add-cookies` injects into the `httr`.
157+
158+It is at this point that there is first occasion for user input, namely the password.
159+
160+The `auth:js` script sends a `PUT` request, also to `/~/auth.json`. In `parse`,
161+the first nontrivial `++check-oryx` occurs, `++grab-body` the request oryx and
162+ensuring it is recorded for the session. The request parsed with `++need-body`
163+to a `[%auth %try {password}]` perk. `%get:process-auth` checks it against
164+`++load-secret`, upon success updates the session with `++logon:ya`, and
165+serves a fresh `auth.json` which reflects the changed `user`. Upon recieving
166+this, the page is refreshed to retry the original request.
167+
168+## Post-authentication: app communication. [#auth-ok]
169+
170+Upon refresh, `/~~/cli` brings us for the third time to `%get:process-auth`, but
171+this time the cookie is set, and the `yac` fetched contains the serving ship as
172+authenticated. The `++handle` sample is updated to reflect the requesting ship,
173+and the `process` continues for the rest of the pork, once again serving the
174+ford page.
175+
176+The `/~/on/[deps].json` poll starts anew, and `/~~/~/at/main/lib/urb.js` we now
177+know to serve the window.urb necessary to make requests, and the `urb.js`
178+standard library which extends it with a number of wrappers to them and other
179+useful functions.
180+
181+---
182+
183+One of those functions is `urb.bind`, which is used to subscribe to application
184+data. Userspace javascript sets `urb.appl` to `/tic`, and binds `lines` to a
185+`;pre;` text display, using a callback.
186+
187+This triggers a `PUT` to `/~/is/{ixor}/cli/lines.json`, where `ixor` is a hash
188+of `oryx` that identifies the connection. `++as-aux-request`, an `%is` is a
189+`%subs` subscription update update, which for `%put` forwards to
190+`++add-subs:ix`, the ix core fetched `++for-view` by hashing the request
191+`++oryx-to-ixor`.
192+
193+[#ixor] A view has all the state associated with a client that must be
194+remembered between events. In this case, this is what app/path the request duct
195+is associated with; but mainly, `++add-subs:ix` will `pass-note` to `%gall` so
196+it `%show`s the data on the path, current and future.
197+
198+This will immediately(assuming the ship is local) result in a `%nice` by the
199+`/cli` app, returning `{ok:true}` `++nice-json` to `urb.bind`'s second callback
200+as `{ok:true}`. The initial `%rush` results also arrive, and in `++axon` are
201+converted to json using `++back`(ford `%cast` wrapper), and when `%made` get
202+passed to `++get-rush:ix`. There the source application/path are decoded by
203+duct, and then the full event goes to `++get-even`; `++add-even` inserts it to
204+the queue, and as there is no long poll it simply stays there.
205+
206+Upon receipt, the client realizes the long-poll isn't actually running, so that
207+is started using `urb.poll`. At `/~/of/{ixor}`, perk
208+`[%view ixor ~ {sequence-number}]`, it is `process`ed by `++poll:ix` (the cyst
209+is retrieved by `++ire-ix` form global state, using the perk `ixor`): the
210+sequence number is in the past, so the previously recieved `%rush` is
211+`++give-even`. After deleting the previous message in the queue and invoking
212+`++pass-took` to signal `%gall` of this occurrence, the data is annotated with
213+the source app+path `++subs-to-json`, and returned to the polling duct.
214+
215+On the client, the user callback receives the `/cli` history, and displays it on
216+the page. The `/~/of` long poll is continued, this time reaching `++poll:ix`
217+with the "pending" sequence number, and being stored in the `cyst` for its troubles.
218+
219+---
220+
221+Its next update proceeds idenitcally, but first it must be triggered, which
222+happens when the user enters "(add 2 2)\n", firing an `urb.send` from the event
223+handler. This sends a `POST` request to `/~/to/cli/json.json`, perk `%mess`,
224+`++process`ed to a `%g %mess`. Were the mark not `%json`, a `%ford` conversion
225+would occur first, and `%made:axon` would send the gall message proper. In
226+either case, eventually a `%mean` or `%nice` arrives, is encoded as json, and
227+sent to the client callback.
228+
229+## A path not taken: magic filenames [#mage]
230+
231+The `/robots.txt` and `/favicon.(ico|png)` files are static, and served
232+immediately when caught by a `++parse`.
233+
234+XX index.html?
235+
236+## A path not taken: foreign auth [#xeno]
237+
238+While this example details a login `/~/as/own`, it is possible to be
239+authenticated as any ship on the network. A request for such seen in
240+`%get:process-auth` is passed to `++foreign-auth:ya`, which sends an
241+`%ames /lon` message to the ship in question. The foreign ship stores the
242+inquiry, calculates(the local) `++our-host` and responds with a `/hat`,
243+containing the redirection host, which is stored by `++foreign-hat`; it is later
244+used to send the client to a `/~/am` url on the foreign client, which acts as a
245+normal login page but later sends the client back. XX expand, basically the
246+status quo is you're logged in and `/~/as/foo` is ignored, just setting your
247+`urb.user` XX
248+
249+
250+## A path not taken: deauthentication
251+
252+`/~/away`, perk `[%away ~]`, produces a static `++logout-page:xml`, which also
253+uses `/~/at/auth.js`, to send a `DELETE /~/auth.json`, perk `[%auth %del]`. This
254+executes `++logoff:ya` for the cookie session, resolving to `++abut` to wipe it
255+from memory.
256+
257+## A path not taken: unsubscription
258+
259+`DELETE /~/is/app/path/within` works much like `PUT /~/is/app/path/within`,
260+`++del-subs:ix` acting as reverse of `++add-subs` by deleting the duct binding
261+and sending `%g %nuke`.
262+
263+
264+XX unmentioned arms: abet, add-poll, adit, ames-gram, anon, ares-to-json, bolo, cyst, doze, even, ford-kill, get-mean, gift, give-json, give-thou, gram, hapt, hasp, host-to-ship, ix, ixor, js, kiss, load, mean-json, move, note, pass-note, perk, perk-auth, pest, poke-test, print-subs, render-tang, resp, root-beak, scry, ses-authed, ses-ya, sign, silk, sine, stay, stem, teba, titl, to-oryx, urb, wait-era, wake, whir, wush, xml, ya, ye
265+
266+## Appendix A: DNS [#dns]
267+
268+The `*.urbit.org` domain can be used to access destroyers and cruisers. In the
269+common case oh hosted ships, this is done by dynamic DNS directly to the hosting
270+instance. We do not speak of the uncommon case. When ports are blocked and
271+infrastructure crumbles around you, only imported martian networking can be
272+trusted: the `%get` and `%got` [gram]()s are used to proxy [`%this` requests]() and
273+[`%thou` responses]() respectively.
docs/system/arvo/ford.mdnew file+128
@@ -0,0 +1,128 @@
1+<div class="short">
2+
3+`%ford`
4+=======
5+
6+Our typed and marked computation engine.
7+
8+A variety of different services are provided by `%ford`, but they mostly
9+involve compiling hook files, slapping/slammming code with marked data,
10+and converting data between marks, including validating data to a mark.
11+Throughout every computation, `%ford` keeps track of which resources are
12+dependencies so that the client may be aware when one or more
13+dependencies are updated.
14+
15+`%ford` neither accepts unix events nor produces effects. It exists
16+entirely for the benefit of applications and other vanes, in particular
17+`%gall`. `%eyre` exposes the functional publishing aspects of `%ford`
18+while `%gall` uses `%ford` to control the execution of applications.
19+`%clay` is intended to use `%ford` to managed marked data, but this is
20+not yet reality.
21+
22+</div>
23+
24+------------------------------------------------------------------------
25+
26+<list></list>
27+
28+------------------------------------------------------------------------
29+
30+Cards
31+=====
32+
33+`%ford` accepts just one card, `%exec`. This is misleading, however,
34+since there are fourteen different `silk`s that may be used with it. In
35+every case, the expected response to a `%exec` card is a `%made` gift
36+with either an error or the produced result along with its set of
37+dependencies.
38+
39+Silks may autocons, so that the product of a cell of silks is a cell of
40+the product of the two silks.
41+
42+`%bake`
43+================
44+
45+Tries to functionally produce the file at a given beam with the given
46+mark and heel. It fails if there is no way to translate at this level.
47+
48+`%boil`
49+================
50+
51+Functionally produces the file at a given beam with the given mark and
52+heel. If there is no way to translate at this beam, we pop levels off
53+the stack and attempt to bake there until we find a level we can bake.
54+This should almost always be called instead of `%bake`.
55+
56+`%call`
57+================
58+
59+Slams the result of one silk against the result of another.
60+
61+`%cast`
62+================
63+
64+Translates the given silk to the given mark, if possible. This is one of
65+the critical and fundamental operations of ford.
66+
67+`%diff`
68+================
69+
70+Diffs the two given silks (which must be of the same mark), producing a
71+cage of the mark specified in `++mark` in `++grad` for the mark of the
72+two silks.
73+
74+`%done`
75+================
76+
77+Produces exactly its input. This is rarely used on its own, but many
78+silks are recursively defined in terms of other silks, so we often need
79+a silk that simply produces its input. A monadic return, if you will.
80+
81+`%dude`
82+================
83+
84+Computes the given silk with the given tank as part of the stack trace
85+if there is an error.
86+
87+`%dune`
88+================
89+
90+Produces an error if the cage is empty. Otherwise, it produces the value
91+in the unit.
92+
93+`%mute`
94+================
95+
96+Takes a silk and a list of changes to make to the silk. At each wing in
97+the list we put the value of the associated silk.
98+
99+`%pact`
100+================
101+
102+Applies the second silk as a patch to the first silk. The second silk
103+must be of the mark specified in `++mark` in `++grad` for the mark of
104+the first silk.
105+
106+`%plan`
107+================
108+
109+Performs a structured assembly directly. This is not generally directly
110+useful because several other silks perform supersets of this
111+functionality. We don't usually have naked hoods outside ford.
112+
113+`%reef`
114+================
115+
116+Produces a core containing the entirety of zuse and hoon, suitable for
117+running arbitrary code against. The mark is `%noun`.
118+
119+`%ride`
120+================
121+
122+Slaps a twig against a subject silk. The mark of the result is `%noun`.
123+
124+`%vale`
125+================
126+
127+Validates untyped data from a ship against a given mark. This is an
128+extremely useful function.
docs/system/arvo/ford/commentary.mdnew file+2571
@@ -0,0 +1,2571 @@
1+Reference
2+=========
3+
4+Data Models
5+-----------
6+
7+### `++axle`, formal state
8+
9+ ++ axle :: all %ford state
10+ $: %1 :: version for update
11+ pol=(map ship baby) ::
12+ == ::
13+
14+This is the formal state of our vane. Anything that must be remembered
15+between calls to ford must be stored here. The number `%1` is a version
16+number for our state that allows us to upgrade the structure of our
17+state in the future if we wish.
18+
19+`pol` is the a map from every ship on our pier to their individual ford
20+state. There is no shared ford state -- every ship is entirely separate.
21+
22+### `++baby`, state by ship
23+
24+ ++ baby :: state by ship
25+ $: tad=[p=@ud q=(map ,@ud task)] :: tasks by number
26+ dym=(map duct ,@ud) :: duct to task number
27+ jav=(map ,* calx) :: cache
28+ == ::
29+
30+This is the state specific to each ship.
31+
32+`tad` and `dym` keep track of the tasks we're currently working on.
33+`dym` is a map from ducts to task numbers, and `q.tad` is a map from
34+task number to the task itself. `p.tad` is the next available task
35+number. Thus, the keys of `q.tad` are a subset of the numbers less than
36+`p.tad`, and ford has attempted exactly `p.tad` tasks so far.
37+
38+`jav` is the cache of previously-solved problems. The keys are a pair of
39+a term (either `%hood`, `%slap`, or `%slam`) and a noun that represents
40+the exact problem solved. In the case of a `%hood`, then, the key is of
41+the form `[%hood beam cage]`. For `%slap`, there is `[%slap vase twig]`.
42+For `%slam`, there is `[%slam vase vase]`. The values are the result of
43+solving the problem. Note that this cache is wiped in `++stay` when ford
44+is reloaded.
45+
46+### `++task`, problem in progress
47+
48+ ++ task :: problem in progress
49+ $: nah=duct :: cause
50+ kas=silk :: problem
51+ kig=[p=@ud q=(map ,@ud beam)] :: blocks
52+ == ::
53+
54+This is all the state we keep regarding a particular task. `nah` is the
55+duct which asked us to solve the problem, and `kas` is the most recent
56+statement of the problem.
57+
58+`kig` keeps track of which resources we are blocked on. Our blocks are
59+stored by index in `q.kig`, and the next available index is `p.kig`.
60+
61+### `++silk`, problem
62+
63+ ++ silk :: construction layer
64+ $& [p=silk q=silk] :: cons
65+ $% [%bake p=mark q=beam r=path] :: local synthesis
66+ [%boil p=mark q=beam r=path] :: general synthesis
67+ [%call p=silk q=silk] :: slam
68+ [%cast p=mark q=silk] :: translate
69+ [%diff p=silk q=silk] :: diff
70+ [%done p=(set beam) q=cage] :: literal
71+ [%dude p=tank q=silk] :: error wrap
72+ [%dune p=(set beam) q=(unit cage)] :: unit literal
73+ [%mute p=silk q=(list (pair wing silk))] :: mutant
74+ [%pact p=silk q=silk] :: patch
75+ [%plan p=beam q=spur r=hood] :: structured assembly
76+ [%reef ~] :: kernel reef
77+ [%ride p=twig q=silk] :: silk thru twig
78+ [%vale p=mark q=ship r=*] :: validate [our his]
79+ == ::
80+
81+This is the every type of problem we can solve. Every `%exec` kiss that
82+requests us to solve a problem must choose one of these problems to
83+solve.
84+
85+Because this is both an internal structure used in ford and the public
86+interface to ford, we choose to document this structure in our
87+discussion of the public interface to ford below.
88+
89+### `++calx`, cache line
90+
91+ ++ calx :: concrete cache line
92+ $% [%hood p=calm q=(pair beam cage) r=hood] :: compile
93+ [%slap p=calm q=[p=vase q=twig] r=vase] :: compute
94+ [%slam p=calm q=[p=vase q=vase] r=vase] :: compute
95+ == ::
96+
97+There are three kinds of cache entries. Every entry includes some
98+metadata in `p` and is the combination of an input and its output.
99+
100+The input to a `%hood` is the location of the resource and a cage
101+representing the data at that location. The output is the hood found by
102+compiling the given cage at the given location.
103+
104+The input to a `%slap` is the vase of the subject and the twig of the
105+formula against which we are slapping the subject. The output is the
106+vase produced by slapping them.
107+
108+The input to a `%slam` is the vase of the subject and the vase of the
109+gate which we are slapping. The output is the vase produced by slamming
110+them.
111+
112+### `++calm`, cache line metadata
113+
114+ ++ calm :: cache metadata
115+ $: laz=@da :: last accessed
116+ dep=(set beam) :: dependencies
117+ == ::
118+
119+Every line in the cache needs to have two pieces of metadata. We must
120+know the last time this line in the cache was accessed, and we must know
121+what are the dependencies of this line.
122+
123+### `++hood`, assembly components
124+
125+ ++ hood :: assembly plan
126+ $: zus=@ud :: zuse kelvin
127+ sur=(list hoot) :: structures
128+ lib=(list hoof) :: libraries
129+ fan=(list horn) :: resources
130+ src=(list hoop) :: program
131+ == ::
132+
133+When assembling a hook file, we split it into several sections.
134+
135+`zus` is the kelvin version of the required zuse. In general, we assume
136+that any newer (lower-numbered) zuse will retain backward compatibility,
137+so any newer zuse is also permissible. This number is set with a `/?` at
138+the beginning of the file.
139+
140+`sur` is the set of structures included. These are included with the
141+`/-` rune. When a structure is included, we look in `/=main=/sur` for
142+the given structure and we load the gate there. When compiling, all the
143+included structures are collected into a single core placed in the
144+subject of the body with a `=>`.
145+
146+`lib` is the set of librarires included. These are included with the
147+`/+` rune. When a library is included, we look in `/=main=/lib` for the
148+given library and we load the library there. As with structures, all the
149+included libraries are collected into a single core placed in the
150+subject of the body with a `=>`.
151+
152+`fan` is the set of resources included. These are loaded in many
153+different ways and may load resources from any location. These are
154+placed in the subject of the body with a `=~`.
155+
156+`src` is the set of twigs or references to twigs in the body of the
157+program. Generally, each of these will represent a core, but this is not
158+required. When compiling, these are strung together in a `=~`.
159+
160+### `++hoot`
161+
162+ ++ hoot (pair bean hoof) :: structure gate/core
163+
164+A structures may be either a direct gate or a core. These are
165+syntactically distinguished by adding a `*` to the beginning of the
166+structure name for a core. The structure itself is a `hoof`.
167+
168+### `++hoof`
169+
170+ ++ hoof (pair term (unit (pair case ship))) :: resource reference
171+
172+A hoof, which is either a structure or a library, has a name, and it may
173+also specify which version of the resource to use and which ship to
174+retrieve it from.
175+
176+### `++horn`
177+
178+ ++ horn :: resource tree
179+ $% [%ape p=twig] :: /~ twig by hand
180+ [%arg p=twig] :: /$ argument
181+ [%day p=horn] :: /| list by @dr
182+ [%dub p=term q=horn] :: /= apply face
183+ [%fan p=(list horn)] :: /. list
184+ [%for p=path q=horn] :: /, descend
185+ [%hub p=horn] :: /@ list by @ud
186+ [%man p=(map span horn)] :: /* hetero map
187+ [%nap p=horn] :: /% homo map
188+ [%now p=horn] :: /& list by @da
189+ [%saw p=twig q=horn] :: /; operate on
190+ [%see p=beam q=horn] :: /: relative to
191+ [%sic p=tile q=horn] :: /^ cast
192+ [%toy p=mark] :: /mark/ static
193+ == ::
194+
195+This is how we represent the static resources hook files can load. The
196+discussion of their use from a user's perspective is documented
197+elsewhere (link), so we will here only give a description of the data
198+structure itself.
199+
200+A `%ape` horn is simply a twig that gets evaluated and placed in the
201+subject.
202+
203+A `%arg` is a gate that gets evaluated with a sample of our location and
204+our heel.
205+
206+A `%day` is a horn that applies to each of a list of `@dr`-named files
207+in the directory.
208+
209+A `%dub` is a term and horn, where the result of a horn is given the
210+face of the term.
211+
212+A `%fan` is a list of horns, all at the current directory level.
213+
214+A `%for` is a path and a horn, where the horn is evaluated relative to
215+the given path, where the given path is relative to the current
216+location.
217+
218+A `%hub` is a horn that applies to each of a list of `@ud`-named files
219+in the directory.
220+
221+A `%man` is a map of spans to horns where the result is a set of each
222+horn applied to the current directory given the associated face.
223+
224+A `%nap` is a homogenous map where each entry in a directory is handled
225+with the same horn and is given a face according to its name.
226+
227+A `%now` is a horn that applies to each of a list of `@da`-named files
228+in the directory.
229+
230+A `%saw` is a twig and a horn, where the twig operates on the result of
231+the horn.
232+
233+A `%see` is a beam and a horn, where the horn is evaluated at a location
234+of the given beam.
235+
236+A `%sic` is a tile and a horn, where the horn is evaluated and cast to
237+the type associated with the tile.
238+
239+A `%toy` is simply a mark to be baked.
240+
241+### `++hoop`, body
242+
243+ ++ hoop :: source in hood
244+ $% [%& p=twig] :: direct twig
245+ [%| p=beam] :: resource location
246+ == ::
247+
248+This is an entry in the body of the hook file. The hoop can either be
249+defined directly in the given file or it can be a reference to another
250+file. The second is specified with a `//` rune.
251+
252+### `++bolt`, monadic edge
253+
254+ ++ bolt :: gonadic edge
255+ |* a=$+(* *) :: product clam
256+ $: p=cafe :: cache
257+ $= q ::
258+ $% [%0 p=(set beam) q=a] :: depends/product
259+ [%1 p=(set ,[p=beam q=(list tank)])] :: blocks
260+ [%2 p=(list tank)] :: error
261+ == ::
262+ == ::
263+
264+Throughout our computation, we let our result flow through with the set
265+of dependencies of the value. At various times, we may wish to either
266+throw an error or declare that the actual result cannot be found until a
267+particular resource is retrieved. This is a perfect case for a monad, so
268+here we define a data structure for it.
269+
270+At every step, we have a cache, so we store that in `p`. In `q` we store
271+the data.
272+
273+In the case of `%0`, we have the result in `q` and the set of
274+dependencies in `p`.
275+
276+In the case of `%1`, we have a set of dependencies on which we are
277+blocking. When this happens, we make a call to clay to get the
278+dependencies, and we proceed with the computation when we receive them.
279+Technically, we restart the computation, but since every expensive step
280+is cached, there is no significant performance penalty to doing this.
281+Referential transparency has its uses.
282+
283+In the case of `%2`, we have a hit an error. This gets passed all the
284+way through to the calling duct. The list of tanks is some description
285+of what went wrong, often including a stack trace.
286+
287+### `++burg`, monadic rule
288+
289+ ++ burg :: gonadic rule
290+ |* [a=$+(* *) b=$+(* *)] :: from and to
291+ $+([c=cafe d=a] (bolt b)) ::
292+ :: ::
293+
294+To operate on bolts, we use `++cope` as our bind operator, and the
295+functions it works on are of type `burg`. Our functions that operate on
296+bolts should have a sample of the cache and a value. Their output should
297+be a bolt of the output value. Then, `++cope` will only call the
298+function when necessary (in the `%0` case), and it will do so without
299+the wrapping of a bolt.
300+
301+If you understand monads, this is probably fairly obvious. Otherwise,
302+see the discussion on `++cope` (link).
303+
304+Public Interface
305+----------------
306+
307+Ford does not export a scry interface, so the only way to interact with
308+ford is by sending kisses and receiving gifts. In fact, ford only sends
309+accepts one kiss and gives one gift. This is, of course, misleading
310+because ford actually does many different things. It does, however, only
311+produce one type of thing -- a result of a computation, which is either
312+an error or the value produced along with the set of dependencies
313+referenced by it.
314+
315+ ++ kiss :: in request ->$
316+ $% [%exec p=@p q=(unit silk)] :: make / kill
317+ == ::
318+
319+The `%exec` gift requests ford to perform a computation on behalf of a
320+particular ship. `p` is the ship, and `q` is the computation. If `q` is
321+null, then we are requesting that ford cancel the computation that it is
322+currently being run along this duct. Thus, if you wish to cancel a
323+computation, you must send the kiss along the same duct as the original
324+request.
325+
326+Otherwise, we ask ford to perform a certain computation, as defined in
327+`++silk`. Since all computations produce the same type of result, we
328+will discuss that result before we jump into `++silk`.
329+
330+ ++ gift :: out result <-$
331+ $% [%made p=(each bead (list tank))] :: computed result
332+ == ::
333+
334+We give either a `bead`, which is a result, or a list of tanks, which is
335+an error messge, often including a stack trace.
336+
337+ ++ bead ,[p=(set beam) q=cage] :: computed result
338+
339+This is a set of dependencies required to compute this value and a cage
340+of the result with its associated mark.
341+
342+There are twelve possible computations defined in `++silk`.
343+
344+ ++ silk :: construction layer
345+ $& [p=silk q=silk] :: cons
346+ $% [%bake p=mark q=beam r=path] :: local synthesis
347+ [%boil p=mark q=beam r=path] :: general synthesis
348+ [%call p=silk q=silk] :: slam
349+ [%cast p=mark q=silk] :: translate
350+ [%done p=(set beam) q=cage] :: literal
351+ [%dude p=tank q=silk] :: error wrap
352+ [%dune p=(set beam) q=(unit cage)] :: unit literal
353+ [%mute p=silk q=(list (pair wing silk))] :: mutant
354+ [%plan p=beam q=spur r=hood] :: structured assembly
355+ [%reef ~] :: kernel reef
356+ [%ride p=twig q=silk] :: silk thru twig
357+ [%vale p=mark q=ship r=*] :: validate [our his]
358+ == ::
359+
360+First, we allow silks to autocons. A cell of silks is also a silk, and
361+the product vase is a cell of the two silks. This obviously extends to
362+an arbitrary number of silks.
363+
364+`%bake` tries to functionally produce the file at a given beam with the
365+given mark and heel. It fails if there is no way to translate at this
366+level.
367+
368+`%boil` functionally produces the file at a given beam with the given
369+mark and heel. If there is no way to translate at this beam, we pop
370+levels off the stack and attempt to bake there until we find a level we
371+can bake. This should almost always be called instead of `%bake`.
372+
373+`%call` slams the result of one silk against the result of another.
374+
375+`%cast` translates the given silk to the given mark, if possible. This
376+is one of the critical and fundamental operations of ford.
377+
378+`%done` produces exactly its input. This is rarely used on its own, but
379+many silks are recursively defined in terms of other silks, so we often
380+need a silk that simply produces its input. A monadic return, if you
381+will.
382+
383+`%diff` diffs the two given silks (which must be of the same mark),
384+producing a cage of the mark specified in `++mark` in `++grad` for the
385+mark of the two silks.
386+
387+`%dude` computes the given silk with the given tank as part of the stack
388+trace if there is an error.
389+
390+`%dune` produces an error if the cage is empty. Otherwise, it produces
391+the value in the unit.
392+
393+`%mute` takes a silk and a list of changes to make to the silk. At each
394+wing in the list we put the value of the associated silk.
395+
396+`%pact` applies the second silk as a patch to the first silk. The second
397+silk must be of the mark specified in `++mark` in `++grad` for the mark
398+of the first silk.
399+
400+`%plan` performs a structured assembly directly. This is not generally
401+directly useful because several other silks perform supersets of this
402+functionality. We don't usually have naked hoods outside ford.
403+
404+`%reef` produces a core containing the entirety of zuse and hoon,
405+suitable for running arbitrary code against. The mark is `%noun`.
406+
407+`%ride` slaps a twig against a subject silk. The mark of the result is
408+`%noun`.
409+
410+`%vale` validates untyped data from a ship against a given mark. This is
411+an extremely useful function.
412+
413+Commentary
414+==========
415+
416+Parsing Hook Files
417+------------------
418+
419+In the commentary on other vanes, we have traced through the lifecycle
420+of various external requests. This is generally a very reasonable order
421+to examine vanes since it will eventually cover the entire vane, and we
422+are never left wondering why we are doing something.
423+
424+For ford, however, it makes more sense to begin by discussing the
425+parsing and assembliing of hook files. Many of the possible requests
426+require us to assemble hook files, so we may as well examine this
427+immediately.
428+
429+First, we will examine the parsing. We parse a file at a beam to a hood
430+in `++fade:zo:za`. The top-level parsing rule is `++fair`, which takes a
431+beam and produces a rule to parse an entire hood file.
432+
433+A note on the naming scheme: the parsing the combinators that parse into
434+a particular structure are conventionally given the same name as the
435+structure. Although this locally clobbers the type names, this pattern
436+makes obvious the intent of the parsing combinators.
437+
438+We kick off with `++hood:fair`.
439+
440+ ++ hood
441+ %+ ifix [gay gay]
442+ ;~ plug
443+ ;~ pose
444+ (ifix [;~(plug fas wut gap) gap] dem)
445+ (easy zuse)
446+ ==
447+ ::
448+ ;~ pose
449+ (ifix [;~(plug fas hep gap) gap] (most ;~(plug com gaw) hoot))
450+ (easy ~)
451+ ==
452+ ::
453+ ;~ pose
454+ (ifix [;~(plug fas lus gap) gap] (most ;~(plug com gaw) hoof))
455+ (easy ~)
456+ ==
457+ ::
458+ (star ;~(sfix horn gap))
459+ (most gap hoop)
460+ ==
461+
462+There are five sections to a hood: system version, structures,
463+libraries, resources, and body.
464+
465+First, we parse the requested version number of the system. This is
466+specified with a unary `/?` rune. If not present, then we default to the
467+current version.
468+
469+Second, we may have zero or more `/-` runes followed by a parsing of a
470+`++hoot`, which represents a shared structure.
471+
472+Third, we may have zero or more `/+` runes followed by a parsing of a
473+`++hoof`, which represents a shared library.
474+
475+Fourth, we may have zero or more other `/` runes (as described in
476+`++horn`), which represent program-specific resources to be loaded.
477+
478+Fifth and finally, we must have one or more body statements (hoops),
479+which are either direct twigs or `//` runes.
480+
481+ ++ hoot
482+ ;~ pose
483+ (stag %| ;~(pfix tar hoof))
484+ (stag %& hoof)
485+ ==
486+
487+A structure can either be a direct gate, or it can be a simple core.
488+Either one is parsed with `++hoof`, so we distinguish the two cases by
489+requireing core references to be prefixed by a `*`.
490+
491+ ++ hoof
492+ %+ cook |=(a=^hoof a)
493+ ;~ plug
494+ sym
495+ ;~ pose
496+ %+ stag ~
497+ ;~(plug ;~(pfix fas case) ;~(pfix ;~(plug fas sig) fed:ag))
498+ (easy ~)
499+ ==
500+ ==
501+
502+A hoof must have a name, which is a term. Optionally, we also include a
503+case and a ship. This is marked by appending a `/` followed by a case to
504+denote the requested version of the resource and a `/` followed by a
505+ship name to denote the requested source of the resource. For example,
506+`resource/1/~zod` requests the first version of `resource` on `~zod`.
507+
508+ ++ case
509+ %- sear
510+ :_ nuck:so
511+ |= a=coin
512+ ?. ?=([%$ ?(%da %ud %tas) *] a) ~
513+ [~ u=(^case a)]
514+
515+Here, we parse a literal with `++nuck:so`, and we accept the input if it
516+is either an absolute date, an unsigned decimal, or a label.
517+
518+This leaves only horns and hoops to parse. Hoops are much simple to
519+parse, so we'll discuss those first.
520+
521+ ++ hoop
522+ ;~ pose
523+ (stag %| ;~(pfix ;~(plug fas fas gap) have))
524+ (stag %& tall:vez)
525+ ==
526+
527+There are two types of hoops. Direct twigs are parsed with
528+`++tall:vast`, which is the just the hoon parser for a tall-form twig.
529+
530+References to external twigs are marked with a `//` rune followed by a
531+beam, which is parsed with `++have`.
532+
533+ ++ hath (sear plex:voz (stag %clsg poor:voz)) :: hood path
534+ ++ have (sear tome ;~(pfix fas hath)) :: hood beam
535+
536+`++have` parses a path with `++hath`, and then it converts the path into
537+a beam with `++tome`.
538+
539+`++hath` parses a `/`-separated list with `++poor:vast`, then converts
540+it to an actual path with `++plex:vast`.
541+
542+This leaves only horns to parse.
543+
544+ ++ horn
545+ =< apex
546+ =| tol=?
547+ |%
548+ ++ apex
549+ %+ knee *^horn |. ~+
550+ ;~ pfix fas
551+ ;~ pose
552+ (stag %toy ;~(sfix sym fas))
553+ (stag %ape ;~(pfix sig ape:read))
554+ (stag %arg ;~(pfix buc ape:read))
555+ (stag %day ;~(pfix bar day:read))
556+ (stag %dub ;~(pfix tis dub:read))
557+ (stag %fan ;~(pfix dot fan:read))
558+ (stag %for ;~(pfix com for:read))
559+ (stag %hub ;~(pfix pat day:read))
560+ (stag %man ;~(pfix tar man:read))
561+ (stag %nap ;~(pfix cen day:read))
562+ (stag %now ;~(pfix pam day:read))
563+ (stag %saw ;~(pfix sem saw:read))
564+ (stag %see ;~(pfix col see:read))
565+ (stag %sic ;~(pfix ket sic:read))
566+ ==
567+ ==
568+
569+Horn parsing is slightly complex, so we create an internal core to
570+organize our code. Our core has a global variable of `tol`, which is
571+true if tall form is permissible and false if we're already in wide
572+form. We kick off the parsing with `++apex`.
573+
574+`++apex` specifies how each rune is parsed. This allows us to offload
575+the different ways of parsing the arguments to these runes into separate
576+arms. The exception here is that the `%toy` horn is simply of the form
577+`/mark/`.
578+
579+We'll examine each of the horn parsing arms right after we discuss
580+`++rail`, which is used in each one.
581+
582+ ++ rail
583+ |* [wid=_rule tal=_rule]
584+ ?. tol wid
585+ ;~(pose wid tal)
586+
587+This takes a wide-form and a tall-form parsing rule. If tall form is
588+permissible, then it allows either rule to match; else, it allows only
589+the wide form rule.
590+
591+ ++ read
592+ |% ++ ape
593+ %+ rail
594+ (ifix [sel ser] (stag %cltr (most ace wide:vez)))
595+ ;~(pfix gap tall:vez)
596+
597+`++ape:read` parses for both the `/~` and the `/$` runes. It produces a
598+twig. The wide form is a tuple of one or more ace-separated wide-form
599+twigs parsed with `++wide:vast` and surrounded by `[` and `]`. The tall
600+form is a single tall form twig parsed by `++tall:vast`
601+
602+ ++ day
603+ %+ rail
604+ apex(tol |)
605+ ;~(pfix gap apex)
606+
607+This parses for the `/|`, `/@`, `/%`, and `/&` runes. It produces a
608+horn. The wide form is, recursively, the entire horn parser with tall
609+form disabled. The tall form is a gap followed by, recursively, the
610+entire horn parser.
611+
612+ ++ dub
613+ %+ rail
614+ ;~(plug sym ;~(pfix tis apex(tol |)))
615+ ;~(pfix gap ;~(plug sym ;~(pfix gap apex)))
616+
617+This parses for the `/=` rune. It produces a term followed by a horn.
618+The wide form is a symbol name followed by a `=` and, recursively, the
619+entire horn parser with tall form disabled. The tall form is a gap
620+followed by a symbol name, another gap, and, recursively, the entire
621+horn parser.
622+
623+ ++ fan
624+ %+ rail fail
625+ ;~(sfix (star ;~(pfix gap apex)) ;~(plug gap duz))
626+
627+This parses for the `/.` rune. It produces a list of horns. There is no
628+wide form. The tall form is a stet-terminated series of gap-separated
629+recursive calls to the entire horn parser.
630+
631+ ++ for
632+ %+ rail
633+ ;~(plug (ifix [sel ser] hath) apex(tol |))
634+ ;~(pfix gap ;~(plug hath ;~(pfix gap apex)))
635+
636+This parses for the `/,` rune. It produces a path and a horn. The wide
637+form is a `[`-`]`-surrounded path followed by, recursively, the entire
638+horn parser with tall form disabled. The tall form is a gap followed by
639+a path, another gap, and, recursively, the entire horn parser.
640+
641+ ++ man
642+ %+ rail fail
643+ %- sear
644+ :_ ;~(sfix (star ;~(pfix gap apex)) ;~(plug gap duz))
645+ |= fan=(list ^horn)
646+ =| naf=(list (pair term ^horn))
647+ |- ^- (unit (map term ^horn))
648+ ?~ fan (some (~(gas by *(map term ^horn)) naf))
649+ ?. ?=(%dub -.i.fan) ~
650+ $(fan t.fan, naf [[p.i.fan q.i.fan] naf])
651+
652+This parses for the `/*` rune. It produces a map of spans to horns.
653+There is no wide form. The tall form is a stet-terminated series of
654+gap-separated recursive calls to the entire horn parser. All produced
655+horns are expected to be from `/=` runes. The term and horn in each `/=`
656+horn is inserted into the produced map as a key-value pair.
657+
658+ ++ saw
659+ %+ rail
660+ ;~(plug ;~(sfix wide:vez sem) apex(tol |))
661+ ;~(pfix gap ;~(plug tall:vez ;~(pfix gap apex)))
662+
663+This parses for the `/;` rune. It produces a twig and a horn. The wide
664+form is a wide-form twig followed by a `;` and, recursively, the entire
665+horn parser with tall form disabled. The tall form is a gap followed by
666+a tall-form twig, another gap, and, recursively, the entire horn parser.
667+
668+ ++ see
669+ %+ rail
670+ ;~(plug ;~(sfix have col) apex(tol |))
671+ ;~(pfix gap ;~(plug have ;~(pfix gap apex)))
672+
673+This parses for the `/:` rune. It produces a beam and a horn. The wide
674+form is a beam followed by a `;` and, recursively, the entire horn
675+parser with tall form disabled. The tall form is a gap followed by a
676+beam, another gap, and, recursively, the entire horn parser.
677+
678+ ++ sic
679+ %+ rail
680+ ;~(plug ;~(sfix toil:vez ket) apex(tol |))
681+ ;~(pfix gap ;~(plug howl:vez ;~(pfix gap apex)))
682+ --
683+
684+This parses for the `/^` rune. It produces a tile and a horn. The wide
685+form is a wide-form tile, parsed with `++toil:vast`, followed by a `^`
686+and, recursively, the entire horn parser with tall form disabled. The
687+tall form is a gap followed by a tall-form tile, parsed with
688+`++howl:vast`, another gap, and, recursively, the entire horn parser.
689+
690+Assembling Hook Files
691+---------------------
692+
693+At this point, we've parsed a hook file into a hood. We will now
694+describe exactly how this hood is assembled into a vase. The problem of
695+assembling is handled entirely within the `++meow:zo:za` core.
696+
697+ ++ meow :: assemble
698+ |= [how=beam arg=heel]
699+ =| $: rop=(map term (pair hoof twig)) :: structure/complex
700+ zog=(set term) :: structure guard
701+ bil=(map term (pair hoof twig)) :: libraries known
702+ lot=(list term) :: library stack
703+ zeg=(set term) :: library guard
704+ boy=(list twig) :: body stack
705+ hol=? :: horns allowed?
706+ ==
707+ |%
708+
709+We take two arguments and keep seven pieces of state. `how` is the
710+location of the hook file we're assembling, and `arg` is the heel, or
711+virtual path extension, of the file.
712+
713+In `rop`, we maintain a map of terms to pairs of hooves and twigs to
714+represent the structures we've encountered that we will put together in
715+a core at the top of the file.
716+
717+In `zog`, we maintain the set of structures we're in the middle of
718+loading. If we try to load a structure already in our dependency
719+ancestry, then we fail because we do not allow circular dependencies.
720+This enforces that our structure dependency graph is a DAG.
721+
722+In `bil`, we maintain a map of terms to pairs of hooves and twigs to
723+represent the libraries we've encountered that we will put together in a
724+series of cores after the structure core.
725+
726+In `lot`, we maintain a stack of library names as they are encountered
727+during a depth-first search. More precisely, we push a library onto the
728+stack after we've processed all its children. Thus, every library
729+depends only on things deeper in the list. The libraries must be loaded
730+in the reverse of this order. Concisely, this is a topological sort of
731+the library dependency partial ordering.
732+
733+In `zeg`, we maintain the set of libraries we're in the middle of
734+loading. If we try to load a library already in our dependency ancestry,
735+then we fail because we do not allow circular dependencies. This
736+enforces that our library dependency graph is a DAG.
737+
738+In `boy`, we maintain a stack of body twigs, which we'll put together in
739+a series of cores at the end of the file.
740+
741+In `hol`, we decide if we're allowed to contain horns. Libraries and
742+structures are not allowed to contain horns.
743+
744+We in every case enter `++meow` through `++abut`. You'll notice that
745+there are four (count 'em, four!) calls to `++cope` in `++abut`. If
746+you've glanced at the ford code in general, you've probably seen cope
747+over and over. It is called in 79 different places. We need to discuss
748+the use of this critical function in detail, so we may as well do it
749+here.
750+
751+ ++ cope :: bolt along
752+ |* [hoc=(bolt) fun=(burg)]
753+ ?- -.q.hoc
754+ %2 hoc
755+ %1 hoc
756+ %0 =+ nuf=(fun p.hoc q.q.hoc)
757+ :- p=p.nuf
758+ ^= q
759+ ?- -.q.nuf
760+ %2 q.nuf
761+ %1 q.nuf
762+ %0 [%0 p=(grom `_p.q.nuf`p.q.hoc p.q.nuf) q=q.q.nuf]
763+ == ==
764+
765+In monad-speak, this is the bind operator for the bolt monad. If monads
766+aren't your thing, don't worry, we're going to explain the use of cope
767+without further reference to them.
768+
769+Recall that there are three different types of bolt. A `%2` error bolt
770+contains a list of tanks describing the error, a `%1` block bolt
771+contains a set of resources we're blocked on, and a `%0` value bolt
772+contains an actual value and the set of its dependencies.
773+
774+We most commonly want to perform an operation on the value in a bolt if
775+it is a `%0` bolt. If it's not a `%0` bolt, we want to leave it alone.
776+This requires us to write a certain amount of boilerplate between each
777+of our operations to see if any of them produced a `%1` or a `%2` bolt.
778+This gets tiresome, so we pull it out into a separate arm and call it
779+`++cope`.
780+
781+Intuitively, we're calling the function `fun` with the value in `hoc`,
782+where `fun` takes an argument of type whatever is the value in a `%0`
783+case of `hoc`, and it produces a bolt of some (possibly different) type.
784+For brevity, we will refer to the type of the of the value in the `%0`
785+case of a bolt as the "type of the bolt".
786+
787+If the `hoc` bolt we're given as input to `fun` is already a `%1` or a
788+`%2` bolt, then we simply produce that. We don't even try to run `fun`
789+on it.
790+
791+Otherwise, we run `fun` with the arguments from the bolt and, if it
792+produces a `%1` or a `%2` bolt, we simply produce that. If it produces a
793+`%0` bolt, then we produce that with the old set of dependencies merged
794+in with the new set.
795+
796+We'll see more about how the bolt monad works as we run into more
797+interesting uses of it. For now, this is sufficient to move on with
798+`++abut`.
799+
800+ ++ abut :: generate
801+ |= [cof=cafe hyd=hood]
802+ ^- (bolt vase)
803+ %+ cope (apex cof hyd)
804+ |= [cof=cafe sel=_..abut]
805+ =. ..abut sel
806+ %+ cope (maim cof pit able)
807+ |= [cof=cafe bax=vase]
808+ %+ cope (chap cof bax [%fan fan.hyd])
809+ |= [cof=cafe gox=vase]
810+ %+ cope (maim cof (slop gox bax) [%tssg (flop boy)])
811+ |= [cof=cafe fin=vase]
812+ (fine cof fin)
813+
814+Our job is simple: we must assemble a hood file into a vase. Hopefully,
815+the usage of `++cope` is fairly understandable. The correct way to read
816+this is that it does essentially five things.
817+
818+First, we call `++apex` to process the structures, libraries, and body.
819+This changes our state, so we set our context to the produced context.
820+Second, we call `++able` to assemble the strucutres and libraries into a
821+twig, which we slap against zuse with `++maim`. Third, we call `++chap`
822+to process the resources in the context of the already-loaded structures
823+and libraries. Fourth, we slap the body against the structures,
824+libraries, and resources. Fifth and finally, we produce the resultant
825+vase.
826+
827+ ++ apex :: build to body
828+ |= [cof=cafe hyd=hood]
829+ ^- (bolt ,_..apex)
830+ ?. |(hol ?=(~ fan.hyd))
831+ %+ flaw cof :_ ~ :- %leaf
832+ "horns not allowed in structures and libraries: {<[how arg]>}"
833+ %+ cope (body cof src.hyd)
834+ |= [cof=cafe sel=_..apex]
835+ =. ..apex sel
836+ %+ cope (neck cof lib.hyd)
837+ |= [cof=cafe sel=_..apex]
838+ =. ..apex sel(boy boy)
839+ %+ cope (head cof sur.hyd)
840+ |= [cof=cafe sel=_..apex]
841+ (fine cof sel)
842+
843+First, we make sure that if we're not allowed to have horns, we don't.
844+Otherwise, we produce and error with `++flaw`.
845+
846+ ++ flaw |=([a=cafe b=(list tank)] [p=a q=[%2 p=b]]) :: bolt from error
847+
848+This produces a `%2` error bolt from a list of tanks. Fairly trivial.
849+
850+We should be starting to get used to the cope syntax, so we can see that
851+we really only do three things here. We process the body with `++body`,
852+the libraries with `++neck`, and the structures with `++head`.
853+
854+ ++ body :: produce functions
855+ |= [cof=cafe src=(list hoop)]
856+ ^- (bolt _..body)
857+ ?~ src (fine cof ..body)
858+ %+ cope (wilt cof i.src)
859+ |= [cof=cafe sel=_..body]
860+ ^$(cof cof, src t.src, ..body sel)
861+
862+We must process a list of hoops that represent our body. If there are no
863+more hoops, we just produce our context in a `%0` bolt with `++fine`.
864+
865+ ++ fine |* [a=cafe b=*] :: bolt from data
866+ [p=`cafe`a q=[%0 p=*(set beam) q=b]] ::
867+
868+In monad-speak, this is the return operator. For us, this just means
869+that we're producing a `%0` bolt, which contains a path and a set of
870+dependencies. We assume there are no dependencies for the given data, or
871+that they will be added later.
872+
873+If there are more hoops in `++body`, we call `++wilt` to process an
874+individual hoop and recurse.
875+
876+ ++ wilt :: process body entry
877+ |= [cof=cafe hop=hoop]
878+ ^- (bolt _..wilt)
879+ ?- -.hop
880+ %& (fine cof ..wilt(boy [p.hop boy]))
881+ %|
882+ %+ cool |.(leaf/"ford: wilt {<[(tope p.hop)]>}")
883+ %+ cope (lend cof p.hop)
884+ |= [cof=cafe arc=arch]
885+ ?: (~(has by r.arc) %hoon)
886+ %+ cope (fade cof %hoon p.hop)
887+ |= [cof=cafe hyd=hood]
888+ %+ cope (apex(boy ~) cof hyd)
889+ |= [cof=cafe sel=_..wilt]
890+ (fine cof sel(boy [[%tssg boy.sel] boy]))
891+ =+ [all=(lark (slat %tas) arc) sel=..wilt]
892+ %+ cope
893+ |- ^- (bolt (pair (map term foot) _..wilt))
894+ ?~ all (fine cof ~ ..wilt)
895+ %+ cope $(all l.all)
896+ |= [cof=cafe lef=(map term foot) sel=_..wilt]
897+ %+ cope ^$(all r.all, cof cof, sel sel)
898+ |= [cof=cafe rig=(map term foot) sel=_..wilt]
899+ %+ cope
900+ %= ^^^^$
901+ cof cof
902+ ..wilt sel(boy ~)
903+ s.p.hop [p.n.all s.p.hop]
904+ ==
905+ |= [cof=cafe sel=_..wilt]
906+ %+ fine cof
907+ [`(map term foot)`[[p.n.all [%ash [%tssg boy.sel]]] lef rig] sel]
908+ |= [cof=cafe mav=(map term foot) sel=_..wilt]
909+ ?~ mav
910+ (flaw cof [%leaf "source missing: {<(tope p.hop)>}"]~)
911+ (fine cof sel(boy [[%brcn mav] boy]))
912+ ==
913+
914+In the case of a direct twig hoop, we just push it onto `boy` and we're
915+done. In the case of an indirect hoop, we must compile the referenced
916+file.
917+
918+First, we push onto the stack trace a message indicating which file
919+exactly we're compiling at the moment with `++cool`.
920+
921+ ++ cool :: error caption
922+ |* [cyt=trap hoc=(bolt)]
923+ ?. ?=(%2 -.q.hoc) hoc
924+ [p.hoc [%2 *cyt p.q.hoc]]
925+
926+If an error occurred in computing `hoc`, we put the bunt of `cyt` onto
927+the stack trace. Thus, `cyt` is not evaluated at all unless an error
928+occurred.
929+
930+Next in `++wilt`, we load the information about the filesystem node
931+referenced by the hoop with `++lend`.
932+
933+ ++ lend :: load arch
934+ |= [cof=cafe bem=beam]
935+ ^- (bolt arch)
936+ =+ von=(ska %cy (tope bem))
937+ ?~ von [p=cof q=[%1 [bem ~] ~ ~]]
938+ (fine cof ((hard arch) (need u.von)))
939+
940+This is a simple call to the namespace. If the resource does not yet
941+exist, we block on it by producing a `%1` bolt. Otherwise, we cast it to
942+an arch and produce this.
943+
944+Continuing in `++wilt`, we examine the produced arch. If the referenced
945+filesystem node has a `hoon` child node, then we've found the required
946+source, so we parse it with `++fade`. Recall that we referred earlier to
947+`++fade`. The salient point there is that it takes a beam, reads in the
948+hook file there, and parses it into a hood file with `++fair`.
949+
950+Now, we simply recurse on `++apex` to compile the new hood. Note that,
951+while we do clear the `boy` list, we do not clear the other lists. Thus,
952+we are accumulating all the structures and libraries referenced in all
953+the referenced hook files in one group, which we will put at the top of
954+the product.
955+
956+After this, we put the new list of body twigs into a `=~`, push this
957+onto our old list of body twigs, and produce the result.
958+
959+If there is no hoon file here, then we descend into each of our children
960+until we find a hoon file. First, we produce a list of all our children
961+whose names are terms with `++lark`.
962+
963+ ++ lark :: filter arch names
964+ |= [wox=$+(span (unit ,@)) arc=arch]
965+ ^- (map ,@ span)
966+ %- ~(gas by *(map ,@ span))
967+ =| rac=(list (pair ,@ span))
968+ |- ^+ rac
969+ ?~ r.arc rac
970+ =. rac $(r.arc l.r.arc, rac $(r.arc r.r.arc))
971+ =+ gib=(wox p.n.r.arc)
972+ ?~(gib rac [[u.gib p.n.r.arc] rac])
973+
974+We traverse the children map of `arc` to filter out those children whose
975+names aren't accepted by `wox` and produce a map from the product of
976+`wox` to the original name. `++lark` is used in many cases to parse
977+names into other types, like numbers or dates, ignoring those which do
978+not fit the format. In `++wilt`, though, we simply want to filter out
979+those children whose names are not terms.
980+
981+Next, we will produce a map from terms to feet. Each of these feet will
982+be placed in a core named by the child name, and it will contain arms
983+according to its children. Thus, if the indirect hoop references
984+`/path`, then to access the twig defined in `/path/to/twig/hoon`, our
985+body must refer to `twig:to`.
986+
987+If there are no more children, then we are done, so we produce our
988+current context.
989+
990+Else, we recurse into the left and right sides of our map. Finally, we
991+process our current entry in the map. We first recurse by calling
992+`++wilt` one level down. Thus, in the previous example, the first time
993+we get to this point we are processing `/path`, so we recurse on
994+`++wilt` with path `/path/to`. We also remove our current body from the
995+recursion, so that we may add it back in later the way we want to.
996+
997+After recursing, we push the new body onto our map, keyed by its name.
998+We also produce the new context so that all external structures,
999+libraries, and resources are collected into the same place.
1000+
1001+Finally, we have a map of names to feet. If this map is empty, then
1002+there were no twigs at the requested path, so we give an error with
1003+`++flaw`.
1004+
1005+If the map is nonempty, then we finally produce our context with with
1006+one thing pushed onto the front: a core made out of the map we just
1007+produced.
1008+
1009+This concludes our discussion of `++wilt` and `++body`. Thus, it remains
1010+in `++apex` to discuss `++neck` and `++head`.
1011+
1012+ ++ neck :: consume libraries
1013+ |= [cof=cafe bir=(list hoof)]
1014+ ^- (bolt ,_..neck)
1015+ ?~ bir (fine cof ..neck)
1016+ ?: (~(has in zeg) p.i.bir)
1017+ (flaw cof [%leaf "circular library dependency: {<i.bir>}"]~)
1018+ =+ gez=(~(put in zeg) p.i.bir)
1019+ =+ byf=(~(get by bil) p.i.bir)
1020+ ?^ byf
1021+ ?. =(`hoof`i.bir `hoof`p.u.byf)
1022+ (flaw cof [%leaf "library mismatch: {<~[p.u.byf i.bir]>}"]~)
1023+ $(bir t.bir)
1024+ =+ bem=(hone %core %lib i.bir)
1025+ %+ cope (fade cof %hook bem)
1026+ |= [cof=cafe hyd=hood]
1027+ %+ cope (apex(zeg gez, hol |, boy ~) cof hyd)
1028+ |= [cof=cafe sel=_..neck]
1029+ =. ..neck
1030+ %= sel
1031+ zeg zeg
1032+ hol hol
1033+ lot [p.i.bir lot]
1034+ bil (~(put by bil) p.i.bir [i.bir [%tssg (flop boy.sel)]])
1035+ ==
1036+ ^^$(cof cof, bir t.bir)
1037+
1038+Here, we're going to consume the list of libraries and place them in
1039+`bil`. If there are no more libraries, we're done, so we just produce
1040+our current context.
1041+
1042+Otherwise, we check to see if the next library in the list is in `zeg`.
1043+If so, then this library is one of the libraries that we're already in
1044+the middle of compiling. There is a circular dependency, so we fail.
1045+
1046+Otherwise, we let `gez` be `zeg` plus the current library so that while
1047+compiling the dependencies of this library we don't later create a
1048+circular dependency. We check next to see if this library is alredy in
1049+`bil`. If so, then we have already included this library earlier, so we
1050+check to see if this is the same version of the library as we included
1051+earlier. If so, we skip it. Else, we fail since we can't include two
1052+different versions of a library. We really should allow for newer
1053+versions of a library since in kelvin versioning we assume backwards
1054+compatibility, but for now we require an exact match.
1055+
1056+If we haven't already included this library, then we're going to do
1057+that. First, we get the location of the library with `++hone`.
1058+
1059+ ++ hone :: plant hoof
1060+ |= [for=@tas way=@tas huf=hoof]
1061+ ^- beam
1062+ ?~ q.huf
1063+ how(s ~[for p.huf way])
1064+ [[q.u.q.huf %main p.u.q.huf] ~[for p.huf way]]
1065+
1066+If we haven't specified the version of the library, we use the current
1067+ship, desk, and case. Otherwise, we use the given ship and case on desk
1068+`%main`. In either case, the path is `/way/p.huf/for`. In the case of
1069+`++neck`, this means `/lib/core/[library name]`.
1070+
1071+In `++neck`, we next compile the hook file at that location with
1072+`++fade`. Again, we will delay the discussion of `++fade`, noting only
1073+that it takes a beam and parses the hook file there into a hood.
1074+
1075+We recurse on this to compile the library. During the compilation, we
1076+let `zeg` be `gez` to avoid circular dependencies, we let `hol` be false
1077+since we don't allow horns in libraries, and we let `boy` be null so
1078+that we can isolate the new body twigs.
1079+
1080+Next, we reintegrate the new data into our context. We use the context
1081+created by the recursion with four changes. First, we reset `zeg` to our
1082+old `zeg`. Second, we reset `hol` to our old `hol`. Third, we put the
1083+name of our library onto the stack of libraries. This means all of a
1084+libraries dependencies will be earlier in `lot` than the library itself,
1085+making `lot` a topological ordering on the dependency graph. Fourth, we
1086+put in `bil` the library hoof and body (with all body twigs collected in
1087+a `=~`), keyed by the library name.
1088+
1089+Finally, we recurse, processing the next library in our list.
1090+
1091+To complete our disucssion of `++apex`, we must process our structures.
1092+
1093+ ++ head :: consume structures
1094+ |= [cof=cafe bir=(list hoot)]
1095+ |- ^- (bolt ,_..head)
1096+ ?~ bir
1097+ (fine cof ..head)
1098+ ?: (~(has in zog) p.q.i.bir)
1099+ (flaw cof [%leaf "circular structure dependency: {<i.bir>}"]~)
1100+ =+ goz=(~(put in zog) p.q.i.bir)
1101+ =+ byf=(~(get by rop) p.q.i.bir)
1102+ ?^ byf
1103+ ?. =(`hoof`q.i.bir `hoof`p.u.byf)
1104+ (flaw cof [%leaf "structure mismatch: {<~[p.u.byf q.i.bir]>}"]~)
1105+ $(bir t.bir)
1106+ =+ bem=(hone ?:(p.i.bir %gate %core) %sur q.i.bir)
1107+ %+ cope (fade cof %hook bem)
1108+ |= [cof=cafe hyd=hood]
1109+ %+ cope (apex(zog goz, hol |, boy ~) cof hyd)
1110+ |= [cof=cafe sel=_..head]
1111+ ?. =(bil bil.sel)
1112+ (flaw cof [%leaf "structures cannot include libraries: {<i.bir>}"]~)
1113+ =. ..head
1114+ %= sel
1115+ boy ?: p.i.bir
1116+ boy
1117+ (welp boy [[[%cnzy p.q.i.bir] [%$ 1]] ~])
1118+ zog zog
1119+ hol hol
1120+ rop %+ ~(put by (~(uni by rop) rop.sel))
1121+ p.q.i.bir
1122+ [q.i.bir [%tssg (flop boy.sel)]]
1123+ ==
1124+ ^^$(cof cof, bir t.bir)
1125+
1126+The processing of our structures is very similar to that of our
1127+libraries. For clarity, we'll use many of the same phrases in describing
1128+the parallel natures. First, we check to see if there are more
1129+structures to process. If not, we're done, so we produce our context.
1130+
1131+Otherwise, we let `goz` be `zog` plus the current structure so that
1132+while compiling the dependencies of this structure we don't later create
1133+a circular dependency. We check next to see if this structure is alredy
1134+in `rop`. If so, then we have already included this structure earlier,
1135+so we check to see if this is the same version of the structure as we
1136+included earlier. If so, we skip it. Else, we fail since we can't
1137+include two different versions of a structure.
1138+
1139+If we haven't loaded this structure, then we call `++hone` to get the
1140+beam where the file structure should be. If the loobean in the hoot is
1141+true, then we're looking for a gate; otherwise, we're looking for a
1142+core. We parse this file with `++fade`.
1143+
1144+Now, we recurse on this to compile the structure. During the recursion,
1145+there we have threee changes. Frist, we let `zog` be `goz` so that we
1146+don't create a circular dependency. Second, we let `hol` be false since
1147+we do not allow horns in structures. Third, we let `boy` be null so that
1148+we can isolate the new body twigs.
1149+
1150+Next, we reintegrate the new data into our context. We use the context
1151+cretaed by the recursion with four changes. First, if we're including a
1152+gate structure, then we reset the body to its original body. Else we put
1153+on the top of our list of body twigs what is essentially a
1154+`=+ structure-name` to take off the face of the structure. Second, we
1155+reset `zog` to our old `zog`. Third, we reset `hol` to our old `hol`.
1156+Finally, we put in `rop` the structure hoof and body (with all body
1157+twiggs collected in a `=~`), keyed by the structure name.
1158+
1159+Finally, we recurse, processing the next structure in our list.
1160+
1161+This concludes our discussion of `++apex`.
1162+
1163+ ++ abut :: generate
1164+ |= [cof=cafe hyd=hood]
1165+ ^- (bolt vase)
1166+ %+ cope (apex cof hyd)
1167+ |= [cof=cafe sel=_..abut]
1168+ =. ..abut sel
1169+ %+ cope (maim cof pit able)
1170+ |= [cof=cafe bax=vase]
1171+ %+ cope (chap cof bax [%fan fan.hyd])
1172+ |= [cof=cafe gox=vase]
1173+ %+ cope (maim cof (slop gox bax) [%tssg (flop boy)])
1174+ |= [cof=cafe fin=vase]
1175+ (fine cof fin)
1176+
1177+Returning to `++abut`, we have now processed the structures, libraries
1178+and body twigs. Next, we slap our preamble (structures and libraries)
1179+against zuse. First, we construct our preamble in `++able`.
1180+
1181+ ++ able :: assemble preamble
1182+ ^- twig
1183+ :+ %tsgr
1184+ ?:(=(~ rop) [%$ 1] [%brcn (~(run by rop) |=([* a=twig] [%ash a]))])
1185+ [%tssg (turn (flop lot) |=(a=term q:(need (~(get by bil) a))))]
1186+
1187+We first put the structures in `rop` into a single `|%` at the top and
1188+`=>` it onto a `=~` of our libraries, in the reverse order that they
1189+appear in `lot`. Thus, the structures are in a single core while the
1190+libraries are in consecutive cores.
1191+
1192+We slap the preamble against zuse with `++maim`.
1193+
1194+ ++ maim :: slap
1195+ |= [cof=cafe vax=vase gen=twig]
1196+ ^- (bolt vase)
1197+ %+ (clef %slap) (fine cof vax gen)
1198+ |= [cof=cafe vax=vase gen=twig]
1199+ =+ puz=(mule |.((~(mint ut p.vax) [%noun gen])))
1200+ ?- -.puz
1201+ | (flaw cof p.puz)
1202+ & %+ (coup cof) (mock [q.vax q.p.puz] (mole ska))
1203+ |= val=*
1204+ `vase`[p.p.puz val]
1205+ ==
1206+
1207+Here we start to get into ford's caching system. We wrap our computation
1208+in a call to `++clef` so that we only actually compute it if the result
1209+is not already in our cache. First we'll discuss the computation, then
1210+we'll discuss the caching system.
1211+
1212+We call `++mule` with a call to `++mint:ut` on the type of our subject
1213+vase against the given twig. In other words, we're compiling the twig
1214+with against the subject type in the given subject vase.
1215+
1216+If compilation fails, then we produce an error bolt with the produced
1217+stack trace. Otherwise, we run the produced nock with `++mock` and our
1218+sky function. We convert the produced toon to a bolt with `++coup` and
1219+use the type from `puz` combined with the value from `mock` to produce
1220+our vase.
1221+
1222+If this process seems harder than just calling `++slap`, it's because it
1223+is. We have two requirements that `++slap` doesn't satisfy. First, we
1224+want the to use an explicit sky function for use with `.^`. With
1225+`++slap`, you get whatever sky function is available in the calling
1226+context, which in ford is none. Second, we want to explicitly handle the
1227+stack trace on failure. `++slap` would cause crash on failure.
1228+
1229+We haven't yet discussed either `++clef` or `++coup`. We'll start with
1230+`++coup` to finish the discussion of the computation.
1231+
1232+\``++ coup :: toon to bolt |= cof=cafe |* [ton=toon fun=$+(* *)] :- p=cof ^= q ?- -.ton %2 [%2 p=p.ton] %0 [%0 p=*(set beam) q=(fun p.ton)] %1 ~& [%coup-need ((list path) p.ton)] =- ?- -.faw & [%1 p=(sa (turn p.faw |=(a=beam [a *(list tank)])))] | [%2 p=p.faw] == ^= faw |- ^- (each (list beam) (list tank)) ?~ p.ton [%& ~] =+ nex=$(p.ton t.p.ton) =+ pax=(path i.p.ton) ?~ pax [%| (smyt pax) ?:(?=(& -.nex) ~ p.nex)] =+ zis=(tome t.pax) ?~ zis [%| (smyt pax) ?:(?=(& -.nex) ~ p.nex)] ?- -.nex & [%& u.zis p.nex] | nex == ==`
1233+
1234+Recall that a toon is either a `%0` value, a `%1` block, or a `%2`
1235+failure. Converting a `%2` toon failure into a `%2` bolt failure is
1236+trivial. Converting a `%0` toon value into a `%0` bolt value is easy
1237+since we assume there were no dependencies. Converting the blocks is
1238+rather more difficult.
1239+
1240+To compute `faw`, we recurse through the list of paths in the `%1` toon.
1241+At each one, we make sure with `++tome` that it is, in fact, a beam. If
1242+so, then we check to see if the later paths succeed as well. If so, we
1243+append the current path to the list of other paths. If not, we produce
1244+the error message we got from processing the rest of the paths. If this
1245+path is not a beam, then we fail, producing a list of tanks including
1246+this path and, if later paths fail too, those paths as well.
1247+
1248+If some paths were not beams, then we produce a `%2` error bolt. If all
1249+paths were correct, then we produce a `%1` blocking bolt.
1250+
1251+We will now discuss `++clef`. This is where the cache magic happens.
1252+
1253+ ++ clef :: cache a result
1254+ |* sem=*
1255+ |* [hoc=(bolt) fun=(burg)]
1256+ ?- -.q.hoc
1257+ %2 hoc
1258+ %1 hoc
1259+ %0
1260+ =^ cux p.hoc ((calk p.hoc) sem q.q.hoc)
1261+ ?~ cux
1262+ =+ nuf=(cope hoc fun)
1263+ ?- -.q.nuf
1264+ %2 nuf
1265+ %1 nuf
1266+ %0
1267+ :- p=(came p.nuf `calx`[sem `calm`[now p.q.nuf] q.q.hoc q.q.nuf])
1268+ q=q.nuf
1269+ ==
1270+ [p=p.hoc q=[%0 p=p.q.hoc q=((calf sem) u.cux)]]
1271+ ==
1272+
1273+If the value is already an error or a block, we just pass that through.
1274+Otherwise, we look up the request in the cache with `++calk`.
1275+
1276+ ++ calk :: cache lookup
1277+ |= a=cafe ::
1278+ |= [b=@tas c=*] ::
1279+ ^- [(unit calx) cafe] ::
1280+ =+ d=(~(get by q.a) [b c]) ::
1281+ ?~ d [~ a] ::
1282+ [d a(p (~(put in p.a) u.d))] ::
1283+
1284+When looking up something in the cache, we mark it if we find it. This
1285+way, we have in our cache the set of all cache entries that have been
1286+referenced. While we do not at present do anything with this data, it
1287+should be used to clear out old and unused entries in the cache.
1288+
1289+Moving on in `++clef`, we check to see if we actually found anything. If
1290+we didn't find a cache entry, then we run the computation in `fun`, and
1291+examine its result. If it produced a `%2` error or `%1` block bolt, we
1292+just pass that through. Otherwise, we produce both the value and an
1293+updated cache with this new entry. We add the entry with `++came`.
1294+
1295+ ++ came ::
1296+ |= [a=cafe b=calx] :: cache install
1297+ ^- cafe ::
1298+ a(q (~(put by q.a) [-.b q.b] b)) ::
1299+
1300+We key cache entries by the type of computation (`-:calx`) and the
1301+inputs to the computation (`q:calc`). This just puts the cache line in
1302+the cache at the correct key.
1303+
1304+Back in `++clef`, if we did find a cache entry, then we just produce the
1305+value at that cache line. We convert the cache line into a value with
1306+`++calf`.
1307+
1308+ ++ calf :: reduce calx
1309+ |* sem=* :: a typesystem hack
1310+ |= cax=calx
1311+ ?+ sem !!
1312+ %hood ?>(?=(%hood -.cax) r.cax)
1313+ %slap ?>(?=(%slap -.cax) r.cax)
1314+ %slam ?>(?=(%slam -.cax) r.cax)
1315+ ==
1316+
1317+This is simply a typesystem hack. Because the `sem` is passed in through
1318+a wet gate, we know at type time which of the three cases will be
1319+chosen. Thus, the correct type of the value in the cache line gets
1320+passed through to the caller. This also depends on the fact that
1321+`++clef` is wet. The type stuff here is mathematically interesting, but
1322+the action is simple: we get the value from the cache line.
1323+
1324+This concludes our discussion of `++clef` and `++maim`.
1325+
1326+Back in `++abut`, recall that we processed the structures, libraries,
1327+and body with `++apex`. Then, we slapped our preamble (structures and
1328+libraries) against zuse with `++maim`. Next, we process our resources
1329+with `++chap`. Note that we pass in the preamble so that we may refer to
1330+anything in there in our resources.
1331+
1332+`++chap` is broken up into a different case for each horn. We'll go
1333+through them one by one.
1334+
1335+ ++ chap :: produce resources
1336+ |= [cof=cafe bax=vase hon=horn]
1337+ ^- (bolt vase)
1338+ ?- -.hon
1339+ %ape (maim cof bax p.hon)
1340+
1341+This is `/~`. We slap the twig against our context.
1342+
1343+ %arg
1344+ %+ cope (maim cof bax p.hon)
1345+ |= [cof=cafe gat=vase]
1346+ (maul cof gat !>([how arg]))
1347+
1348+This is `/$`. We slap the twig against our context, which we expect to
1349+produce a gate. We slam this gate with a sample of `how` and `arg`,
1350+which is our location and the heel (virtual path extension).
1351+
1352+`++maul` is similar to `++maim`, but it slams instead of slaps.
1353+
1354+ ++ maul :: slam
1355+ |= [cof=cafe gat=vase sam=vase]
1356+ ^- (bolt vase)
1357+ %+ (clef %slam) (fine cof gat sam)
1358+ |= [cof=cafe gat=vase sam=vase]
1359+ =+ top=(mule |.((slit p.gat p.sam)))
1360+ ?- -.top
1361+ | (flaw cof p.top)
1362+ & %+ (coup cof) (mong [q.gat q.sam] (mole ska))
1363+ |= val=*
1364+ `vase`[p.top val]
1365+ ==
1366+
1367+We cache slams exactly as we cache slaps. We use `++slit` to find the
1368+type of the product of the slam given the types of the gate and the
1369+sample.
1370+
1371+If this type fails, we produce the given stack trace as a `%2` error
1372+bolt. Otherwise, we produce the top produced above combined with the
1373+value we get from slamming the values in the vases with `++mong`.
1374+
1375+Back to `++chap`.
1376+
1377+ %day (chad cof bax %dr p.hon)
1378+
1379+This is `/|`. We call `++chad` to convert textual names to relative
1380+dates and process the next horn against each of the discovered paths.
1381+
1382+ ++ chad :: atomic list
1383+ |= [cof=cafe bax=vase doe=term hon=horn]
1384+ ^- (bolt vase)
1385+ %+ cope ((lash (slat doe)) cof how)
1386+ |= [cof=cafe yep=(map ,@ span)]
1387+ =+ ^= poy ^- (list (pair ,@ span))
1388+ %+ sort (~(tap by yep) ~)
1389+ |=([a=[@ *] b=[@ *]] (lth -.a -.b))
1390+ %+ cope
1391+ |- ^- (bolt (list (pair ,@ vase)))
1392+ ?~ poy (fine cof ~)
1393+ %+ cope $(poy t.poy)
1394+ |= [cof=cafe nex=(list (pair ,@ vase))]
1395+ %+ cope (chap(s.how [q.i.poy s.how]) cof bax hon)
1396+ |= [cof=cafe elt=vase]
1397+ (fine cof [[p.i.poy elt] nex])
1398+ |= [cof=cafe yal=(list (pair ,@ vase))]
1399+ %+ fine cof
1400+ |- ^- vase
1401+ ?~ yal [[%cube 0 [%atom %n]] 0]
1402+ (slop (slop [[%atom doe] p.i.yal] q.i.yal) $(yal t.yal))
1403+
1404+First, we call `++lash` to parse the children of the current beam and
1405+pick out those ones that are of the requested format.
1406+
1407+ ++ lash :: atomic sequence
1408+ |= wox=$+(span (unit ,@))
1409+ |= [cof=cafe bem=beam]
1410+ ^- (bolt (map ,@ span))
1411+ %+ cope (lend cof bem)
1412+ |= [cof=cafe arc=arch]
1413+ (fine cof (lark wox arc))
1414+
1415+First, we get the arch with `++lend`, as described above. We filter and
1416+parse the child names with `++lark` according to the given parser
1417+function.
1418+
1419+In `++chad`, this parser function is `(slat doe)`, which will parse a
1420+cord into an atom of the requested odor. For `%day` the odor is for
1421+relative dates.
1422+
1423+Thus, we now have a map from atoms of the given odor to the actual child
1424+names. We next turn this map into a list and sort it in increasing order
1425+by the atom.
1426+
1427+We next convert this list of pairs of atoms and spans to a list of pairs
1428+of atoms and vases. We process the given horn once at every child beam,
1429+producing the resource at that location.
1430+
1431+Finally, we convert this list of pairs of atoms and vases to a vase of a
1432+list of pairs of atoms to (well-typed) values. Each entry in the list is
1433+of type atom with the given odor combined with the type of the produced
1434+vase.
1435+
1436+Back in `++chap`, we continue parsing resources.
1437+
1438+ %dub
1439+ %+ cope $(hon q.hon)
1440+ |= [cof=cafe vax=vase]
1441+ (fine cof [[%face p.hon p.vax] q.vax])
1442+
1443+This is `/=`. We process the given horn, giving us a vase. We put as a
1444+face on the vase so that it may be referred to later by name.
1445+
1446+ %fan
1447+ %+ cope
1448+ |- ^- (bolt (list vase))
1449+ ?~ p.hon (fine cof ~)
1450+ %+ cope ^$(hon i.p.hon)
1451+ |= [cof=cafe vax=vase]
1452+ %+ cope ^$(cof cof, p.hon t.p.hon)
1453+ |= [cof=cafe tev=(list vase)]
1454+ (fine cof [vax tev])
1455+ |= [cof=cafe tev=(list vase)]
1456+ %+ fine cof
1457+ |- ^- vase
1458+ ?~ tev [[%cube 0 [%atom %n]] 0]
1459+ (slop i.tev $(tev t.tev))
1460+
1461+This is `/.`. We first process each of the child horns, producing a list
1462+of vases. This is done by just recursing on `++chap`. Then, we simply
1463+fold over this list to create a vase of the list of values.
1464+
1465+ %for $(hon q.hon, s.how (weld (flop p.hon) s.how))
1466+
1467+This is `/,`. We simply recurse on the horn with the given path welded
1468+onto our current beam.
1469+
1470+ %hub (chad cof bax %ud p.hon)
1471+
1472+This is `/@`. This is exactly like the processing of `%day` except we
1473+expect the children to be named as unsigned integers rather than
1474+relative dates. We process the horn at each of the children's locations
1475+and produce a list of pairs of absolute dates and values.
1476+
1477+ %man
1478+ |- ^- (bolt vase)
1479+ ?~ p.hon (fine cof [[%cube 0 [%atom %n]] 0])
1480+ %+ cope $(p.hon l.p.hon)
1481+ |= [cof=cafe lef=vase]
1482+ %+ cope ^$(cof cof, p.hon r.p.hon)
1483+ |= [cof=cafe rig=vase]
1484+ %+ cope ^^^$(cof cof, hon q.n.p.hon)
1485+ |= [cof=cafe vax=vase]
1486+ %+ fine cof
1487+ %+ slop
1488+ (slop [[%atom %tas] p.n.p.hon] vax)
1489+ (slop lef rig)
1490+
1491+This is `/*`. We process each of the horns in the given map by recursion
1492+through `++chap`. Once we have these vases, we create a vase of a map
1493+from the given textual names to the produced values.
1494+
1495+ %now (chad cof bax %da p.hon)
1496+
1497+This is `/&`. This is exactly like the processing of `%now` except we
1498+expect the children to be names as absolute dates rather than relative
1499+dates. We process the horn at each of the children's locations and
1500+produce a list of pairs of absolute dates and values.
1501+
1502+ %nap (chai cof bax p.hon)
1503+
1504+This is `/%`. Here, we process the horn at each of our children with
1505+`++chai`.
1506+
1507+ ++ chai :: atomic map
1508+ |= [cof=cafe bax=vase hon=horn]
1509+ ^- (bolt vase)
1510+ %+ cope (lend cof how)
1511+ |= [cof=cafe arc=arch]
1512+ %+ cope
1513+ |- ^- (bolt (map ,@ vase))
1514+ ?~ r.arc (fine cof ~)
1515+ %+ cope $(r.arc l.r.arc)
1516+ |= [cof=cafe lef=(map ,@ vase)]
1517+ %+ cope `(bolt (map ,@ vase))`^$(cof cof, r.arc r.r.arc)
1518+ |= [cof=cafe rig=(map ,@ vase)]
1519+ %+ cope (chap(s.how [p.n.r.arc s.how]) cof bax hon)
1520+ |= [cof=cafe nod=vase]
1521+ (fine cof [[p.n.r.arc nod] lef rig])
1522+ |= [cof=cafe doy=(map ,@ vase)]
1523+ %+ fine cof
1524+ |- ^- vase
1525+ ?~ doy [[%cube 0 [%atom %n]] 0]
1526+ %+ slop
1527+ (slop [[%atom %a] p.n.doy] q.n.doy)
1528+ (slop $(doy l.doy) $(doy r.doy))
1529+
1530+We get the arch at our current beam with `++lend`. Then, we process the
1531+horn at each of our children to give us a map of atoms to vases.
1532+Finally, we convert that into a vase of a map of these atoms to the
1533+values. This is very similar to `++chad` and the handling of `%man`.
1534+
1535+ %see $(hon q.hon, how p.hon)
1536+
1537+This is `/:`. We process the given horn at the given beam.
1538+
1539+ %saw
1540+ %+ cope $(hon q.hon)
1541+ |= [cof=cafe sam=vase]
1542+ %+ cope (maim cof bax p.hon)
1543+ |= [cof=cafe gat=vase]
1544+ (maul cof gat sam)
1545+
1546+This is `/;`. First, we process the given horn. Then, we slap the given
1547+twig against our context to produce (hopefully) a gate. Finally, we slam
1548+the vase we got from processing the horn against the gate.
1549+
1550+ %sic
1551+ %+ cope $(hon q.hon)
1552+ |= [cof=cafe vax=vase]
1553+ %+ cope (maim cof bax [%bctr p.hon])
1554+ |= [cof=cafe tug=vase]
1555+ ?. (~(nest ut p.tug) | p.vax)
1556+ (flaw cof [%leaf "type error: {<p.hon>} {<q.hon>}"]~)
1557+ (fine cof [p.tug q.vax])
1558+
1559+This is `/^`. First, we process the given horn. Then, we slap the the
1560+bunt of the given tile against our context. This will produce a vase
1561+with the correct type. We test to see if this type nests within the type
1562+of the vase we got from processing the horn. If so, we produce the value
1563+from the horn along with the type from the tile. Otherwise, we produce a
1564+`%2` error bolt.
1565+
1566+ %toy (cope (make cof %bake p.hon how ~) feel)
1567+ ==
1568+
1569+This is `/mark/`. Here, we simply run the `%bake` silk on the given
1570+mark, producing a cage. We convert this cage into a vase with `++feel`,
1571+which is exactly as simple as it sounds like it should be.
1572+
1573+ ++ feel |=([a=cafe b=cage] (fine a q.b)) :: cage to vase
1574+
1575+This is trivial.
1576+
1577+We will discuss later `++make` and how `%bake` is processed. Suffice it
1578+to say that baking a resource with a given mark gets the resource and
1579+converts it, if necessary, to the requested mark.
1580+
1581+This concludes our discussion of `++chap`.
1582+
1583+We return once more to `++abut`.
1584+
1585+ ++ abut :: generate
1586+ |= [cof=cafe hyd=hood]
1587+ ^- (bolt vase)
1588+ %+ cope (apex cof hyd)
1589+ |= [cof=cafe sel=_..abut]
1590+ =. ..abut sel
1591+ %+ cope (maim cof pit able)
1592+ |= [cof=cafe bax=vase]
1593+ %+ cope (chap cof bax [%fan fan.hyd])
1594+ |= [cof=cafe gox=vase]
1595+ %+ cope (maim cof (slop gox bax) [%tssg (flop boy)])
1596+ |= [cof=cafe fin=vase]
1597+ (fine cof fin)
1598+
1599+Recall that we processed our structures, libraries and body with
1600+`++apex`. We slapped our structures and libraries against zuse with
1601+`++maim`. We processed our resources with `++chap`. Now, all our body
1602+twigs are collected in a `=~` and slapped against our structures,
1603+libraries, and resources. This produces our final result.
1604+
1605+The hook file has been assembled. And there was great rejoicing.
1606+
1607+Lifecycle of a Kiss
1608+-------------------
1609+
1610+We're now going to go through a series of lifecycle descriptions. When a
1611+user of ford sends a kiss, it is one of a dozen different types of silk.
1612+We'll go through each one, tracing through the flow of control of each
1613+of these.
1614+
1615+First, though, we'll describe the common handling to all kisses.
1616+
1617+The silk in a `%exec` kiss to ford ends up in `++apex`, so we'll enter
1618+the narrative here.
1619+
1620+ ++ apex :: call
1621+ |= kus=(unit silk)
1622+ ^+ +>
1623+ ?~ kus
1624+ =+ nym=(~(get by dym.bay) hen)
1625+ ?~ nym :: XX should never
1626+ ~& [%ford-mystery hen]
1627+ +>.$
1628+ =+ tas=(need (~(get by q.tad.bay) u.nym))
1629+ amok:~(camo zo [u.nym tas])
1630+ =+ num=p.tad.bay
1631+ ?< (~(has by dym.bay) hen)
1632+ =: p.tad.bay +(p.tad.bay)
1633+ dym.bay (~(put by dym.bay) hen num)
1634+ ==
1635+ ~(exec zo [num `task`[hen u.kus 0 ~]])
1636+
1637+Recall that a `%exec` kiss actually sends a unit silk. If it's null,
1638+we're trying to cancel the request. We first look up the task number
1639+keyed by duct. If we don't find it, then we're trying to cancel a
1640+request that either was never started or has already completed. We print
1641+out `%ford-mystery` and do nothing. If we do find the task number, then
1642+we look up the task from it, call `++camo:zo` to cancel pending
1643+requests, and call `++amok:zo` to remove the task from our task lists.
1644+
1645+ ++ camo :: stop requests
1646+ ^+ .
1647+ =+ kiz=(~(tap by q.kig) *(list ,[p=@ud q=beam]))
1648+ |- ^+ +>
1649+ ?~ kiz +>
1650+ %= $
1651+ kiz t.kiz
1652+ mow :_ mow
1653+ :- hen
1654+ :^ %pass [(scot %p our) (scot %ud num) (scot %ud p.i.kiz) ~]
1655+ %c
1656+ [%warp [our p.q.i.kiz] q.q.i.kiz ~]
1657+ ==
1658+
1659+Our list of blocks is in `q.kig`, so we iterate over it, cancelling our
1660+pending requests for each block. Our requests are all to clay, so we
1661+need only to send `%warp` kisses with a null instead of a rave.
1662+
1663+ ++ amok
1664+ %_ ..zo
1665+ q.tad.bay (~(del by q.tad.bay) num)
1666+ dym.bay (~(del by dym.bay) nah)
1667+ ==
1668+
1669+We remove the task number from the map of numbers to tasks and the duct
1670+from the map of ducts to task numbers.
1671+
1672+Back in `++apex`, if we were given a silk, we need to process it. We add
1673+the task to our maps, increment the next task number, and call
1674+`++exec:zo` on the new task.
1675+
1676+ ++ exec :: execute app
1677+ ^+ ..zo
1678+ ?: !=(~ q.kig) ..zo
1679+ |- ^+ ..zo
1680+ =+ bot=(make [~ jav.bay] kas)
1681+ =. ..exec (dash p.bot)
1682+ ?- -.q.bot
1683+ %0 amok:(expo [%made %& p.q.bot q.q.bot])
1684+ %2 amok:(expo [%made %| p.q.bot])
1685+ %1 =+ zuk=(~(tap by p.q.bot) ~)
1686+ =< abet
1687+ |- ^+ ..exec
1688+ ?~ zuk ..exec
1689+ =+ foo=`_..exec`(camp %x `beam`p.i.zuk)
1690+ $(zuk t.zuk, ..exec foo)
1691+ ==
1692+
1693+If we're still blocked on something in `q.kig`, we don't do anything.
1694+
1695+Otherwise, we try to process the silk with `++make`. `++make` handles
1696+each individual request and will be the entire focus of the remainder of
1697+this doc after this section. It produces a bolt of a cage.
1698+
1699+We put the new cache in our state with `++dash`.
1700+
1701+ ++ dash :: process cache
1702+ |= cof=cafe
1703+ ^+ +>
1704+ %_(+> jav.bay q.cof)
1705+
1706+The cache is put in the baby so that it gets stored across calls to
1707+ford.
1708+
1709+In `++exec`, we process the bolt in three different ways according to
1710+the type of bolt produced. If we produced a `%0` value bolt, we use
1711+`++expo` to give the produced value and set of dependencies as a `%made`
1712+gift, and we remove ourselves from the task list with `++amok`.
1713+
1714+ ++ expo :: return gift
1715+ |= gef=gift
1716+ %_(+> mow :_(mow [hen %give gef]))
1717+
1718+We simply push the gift onto our list of moves.
1719+
1720+In `++exec`, if we produced a `%2` error bolt, we produce a `%made` gift
1721+with the stack trace.
1722+
1723+If we produced a `%1` block bolt, we iterate through each of the blocks
1724+and call `++camp` to produce a clay request for the resource.
1725+
1726+ ++ camp :: request a file
1727+ |= [ren=care bem=beam]
1728+ ^+ +>
1729+ %= +>
1730+ kig [+(p.kig) (~(put by q.kig) p.kig bem)]
1731+ mow :_ mow
1732+ :- hen
1733+ :^ %pass [(scot %p our) (scot %ud num) (scot %ud p.kig) ~]
1734+ %c
1735+ [%warp [our p.bem] q.bem [~ %& %x r.bem s.bem]]
1736+ ==
1737+
1738+We put the resource in our block list in `q.kig` so that we save the
1739+fact that we're blocked. We then produce the `%warp` request to clay for
1740+the resource. Our request path has the format
1741+\`/[our-ship]/[task-number]/[block-number]'.
1742+
1743+We'll now describe how each of the individual silks are processed in
1744+`++make`.
1745+
1746+Lifecycle of a Cell
1747+-------------------
1748+
1749+ ^
1750+ %. [cof p.kas q.kas]
1751+ ;~ cope
1752+ ;~ coax
1753+ |=([cof=cafe p=silk q=silk] ^$(cof cof, kas p.kas))
1754+ |=([cof=cafe p=silk q=silk] ^$(cof cof, kas q.kas))
1755+ ==
1756+ ::
1757+ |= [cof=cafe bor=cage heg=cage] ^- (bolt cage)
1758+ [p=cof q=[%0 ~ [%$ (slop q.bor q.heg)]]]
1759+ ==
1760+
1761+Silks autocons. The product of a cell of silks is a cell of the products
1762+of the silks, so we evaluate the two silks in parallel with `++coax` and
1763+slop together the results in a cell vase. We mark the product with `%$`,
1764+which means we know no more mark information than that it is a noun.
1765+
1766+ ++ coax :: bolt across
1767+ |* [hoc=(bolt) fun=(burg)]
1768+ ?- -.q.hoc
1769+ %0 =+ nuf=$:fun(..+<- p.hoc)
1770+ :- p=p.nuf
1771+ ^= q
1772+ ?- -.q.nuf
1773+ %0 [%0 p=(grom p.q.hoc p.q.nuf) q=[q.q.hoc q.q.nuf]]
1774+ %1 q.nuf
1775+ %2 q.nuf
1776+ ==
1777+ %1 =+ nuf=$:fun(..+<- p.hoc)
1778+ :- p=p.nuf
1779+ ^= q
1780+ ?- -.q.nuf
1781+ %0 q.hoc
1782+ %1 [%1 p=(grom p.q.nuf p.q.hoc)]
1783+ %2 q.nuf
1784+ ==
1785+ %2 hoc
1786+ ==
1787+
1788+If the first bolt is a value, we evaluate the burg to get the next bolt.
1789+If that also produces a value, we merge the dependency sets and produce
1790+a cell of the two values. Otherwise, we produce the block or error of
1791+the second bolt.
1792+
1793+If the first bolt is a block, we evaluate the burg to get the next bolt.
1794+If that produces a value, we just produce the block. If it produces a
1795+block, we merge the two block sets. If it produces an error, we produce
1796+that error.
1797+
1798+If the first bolt is already an error, we just pass that through.
1799+
1800+Note that `++coax` (and, indeed, `++cope`) is reasonable to use with
1801+`;~`.
1802+
1803+Lifecycle of a `%bake`
1804+----------------------
1805+
1806+ %bake
1807+ %+ cool |.(leaf/"ford: bake {<p.kas>} {<(tope q.kas)>}")
1808+ %+ cope (lima cof p.kas q.kas r.kas)
1809+ |= [cof=cafe vux=(unit vase)]
1810+ ?~ vux
1811+ (flaw cof (smyt (tope q.kas)) ~)
1812+ (fine cof [p.kas u.vux])
1813+
1814+This is one of the most critical silks. We are going to functionally
1815+produce the hook file at the given beam with the given heel. The result
1816+will be of the correct mark, even if we need to run conversion
1817+functions. The functionality is encapsulated in `++lime`. If it produces
1818+null, then we produce an error. Otherwise, we take the vase produced and
1819+give it the correct mark.
1820+
1821+ ++ lima :: load at depth
1822+ |= [cof=cafe for=mark bem=beam arg=heel]
1823+ ^- (bolt (unit vase))
1824+ %+ cope (lend cof bem)
1825+ |= [cof=cafe arc=arch]
1826+ ^- (bolt (unit vase))
1827+ ?: (~(has by r.arc) for)
1828+ (lace cof for bem(s [for s.bem]) arg)
1829+ =+ haz=(turn (~(tap by r.arc) ~) |=([a=@tas b=~] a))
1830+ ?~ haz (fine cof ~)
1831+ %+ cope (lion cof for -.bem haz)
1832+ |= [cof=cafe wuy=(unit (list ,@tas))]
1833+ ?~ wuy (fine cof ~)
1834+ ?> ?=(^ u.wuy)
1835+ %+ cope (make cof %bake i.u.wuy bem arg)
1836+ |= [cof=cafe hoc=cage]
1837+ %+ cope (lope cof i.u.wuy t.u.wuy -.bem q.hoc)
1838+ |= [cof=cafe vax=vase]
1839+ (fine cof ~ vax)
1840+
1841+First, we load the arch at the given beam with `++lend`. If we have a
1842+child named the mark, our job is straightforward, so we go ahead and
1843+load that with `++lace`.
1844+
1845+Otherwise, we iterate through our children. If we have no children, we
1846+produce null, signifying that we didn't find any way to convert to the
1847+requested mark. Otherwise, we call `++lion` to find a translation path
1848+from one of the available marks into the target mark. We recursively
1849+bake the child that has a path to the target mark, and then we call
1850+`++lope` to translate this mark into the target mark.
1851+
1852+We'll first discuss the direct case of when one of our children is of
1853+the correct mark.
1854+
1855+ ++ lace :: load and check
1856+ |= [cof=cafe for=mark bem=beam arg=heel]
1857+ ^- (bolt (unit vase))
1858+ =+ bek=`beak`[p.bem q.bem r.bem]
1859+ %+ cope (lend cof bem)
1860+ |= [cof=cafe arc=arch]
1861+ ?^ q.arc
1862+ (cope (cope (liar cof bem) (lake for bek)) fest)
1863+ ?: (~(has by r.arc) %hook)
1864+ %+ cope (fade cof %hook bem)
1865+ |= [cof=cafe hyd=hood]
1866+ (cope (cope (abut:(meow bem arg) cof hyd) (lake for bek)) fest)
1867+ (fine cof ~)
1868+
1869+First, we get the arch at the given beam with `++lend`. If this is a
1870+file, we load the file with `++liar` and coerce the type with `++lake`.
1871+Otherwise, we check to see if we have a hook file here. If so, we parse
1872+it with `++fade`, compile it with `++abut:meow`, and coerce the type
1873+with `++lake`.
1874+
1875+Otherwise, there is no way to translate this, so we produce null.
1876+
1877+`++fest` is one line, so we'll get that one out of the way first.
1878+
1879+ ++ fest |*([a=cafe b=*] (fine a [~ u=b])) :: bolt to unit
1880+
1881+This is just `++some` for bolts.
1882+
1883+We've delayed the discussion of `++fade` far too many times. It's not
1884+complicated, we just wanted to spare a premature discussion of `++make`
1885+and the `%bake` silk. We 're now able to discuss everything in `++fade`
1886+with ease.
1887+
1888+ ++ fade :: compile to hood
1889+ |= [cof=cafe for=mark bem=beam]
1890+ ^- (bolt hood)
1891+ %+ cool |.(leaf/"ford: fade {<[(tope bem)]>}")
1892+ %+ cope (make cof [%bake for bem ~])
1893+ |= [cof=cafe cay=cage]
1894+ %+ (clef %hood) (fine cof bem cay)
1895+ ^- (burg (pair beam cage) hood)
1896+ |= [cof=cafe bum=beam cay=cage]
1897+ =+ rul=(fair bem)
1898+ ?. ?=(@ q.q.cay)
1899+ (flaw cof ~)
1900+ =+ vex=((full rul) [[1 1] (trip q.q.cay)])
1901+ ?~ q.vex
1902+ (flaw cof [%leaf "syntax error: {<p.p.vex>} {<q.p.vex>}"] ~)
1903+ (fine cof p.u.q.vex)
1904+
1905+We first push a line onto a stack trace to say that we're parsing into a
1906+hood file.
1907+
1908+We bake the given beam with the given mark and no heel. Recall that
1909+baking gate, core, door, hoon, and hook files produces simply an atom of
1910+the text. We check to make sure that our value is an atom, failing
1911+otherwise.
1912+
1913+The parsing step is run within `++clef` so that the result is cached. We
1914+call `++fair` with the current beam to generate the parsing rule, and we
1915+parse the file. If parsing fails, we fail giving a syntax error with the
1916+line and column number. Otherwise, we produce the value.
1917+
1918+ ++ liar :: load vase
1919+ |= [cof=cafe bem=beam]
1920+ ^- (bolt vase)
1921+ =+ von=(ska %cx (tope bem))
1922+ ?~ von
1923+ [p=*cafe q=[%1 [[bem ~] ~ ~]]]
1924+ ?~ u.von
1925+ (flaw cof (smyt (tope bem)) ~)
1926+ (fine cof ?^(u.u.von [%cell %noun %noun] [%atom %$]) u.u.von)
1927+
1928+This takes a beam and loads the file at that location. If our sky
1929+function produces null, that means the resource is currently
1930+unavailable, so we block on it. If it produces `[~ ~]`, that means our
1931+resource is permanently unavailable, so we produce an error. Otherwise,
1932+we produce the value there with a type of either a cell of two nouns or
1933+an atom, depending on whether the value is a cell or not.
1934+
1935+Back in `++lima`, recall that we call `++lion` to find a translation
1936+path.
1937+
1938+ ++ lion :: translation search
1939+ |= [cof=cafe too=@tas bek=beak fro=(list ,@tas)]
1940+ ^- (bolt (unit (list ,@tas)))
1941+ =| war=(set ,@tas)
1942+ =< -:(apex (fine cof fro))
1943+ |%
1944+ ++ apex
1945+ |= rof=(bolt (list ,@tas))
1946+ ^- [(bolt (unit (list ,@tas))) _+>]
1947+ ?. ?=(%0 -.q.rof) [rof +>.$]
1948+ ?~ q.q.rof
1949+ [[p.rof [%0 p.q.rof ~]] +>.$]
1950+ =^ orf +>.$ (apse cof i.q.q.rof)
1951+ ?. ?=(%0 -.q.orf)
1952+ [orf +>.$]
1953+ ?~ q.q.orf
1954+ $(cof p.orf, q.q.rof t.q.q.rof)
1955+ [[p.orf [%0 (grom p.q.rof p.q.orf) q.q.orf]] +>.$]
1956+ ::
1957+ ++ apse
1958+ |= [cof=cafe for=@tas]
1959+ ^- [(bolt (unit (list ,@tas))) _+>]
1960+ ?: =(for too)
1961+ [(fine cof [~ too ~]) +>.$]
1962+ ?: (~(has in war) for) [(fine cof ~) +>]
1963+ =. war (~(put in war) for)
1964+ =^ hoc +>.$ (apex (lily cof for bek))
1965+ :_ +>.$
1966+ %+ cope hoc
1967+ |= [cof=cafe ked=(unit (list ,@tas))]
1968+ (fine cof ?~(ked ~ [~ for u.ked]))
1969+ --
1970+
1971+At a high level, we have `++apex` and `++apse`. `++apex` takes a list of
1972+marks to try in succession until we find one that can be translated into
1973+the target mark. On each one, it calls `++apse`, which takes a single
1974+mark and tries to find a translation path from this mark to the target.
1975+To do this, it sees which marks we know how to directly translate to,
1976+and calls `++apex` on this list. The result of this mututal recursion is
1977+a depth-first search of the translation graph to find the target mark.
1978+Since the translation graph is not necessarily acyclic, we maintain a
1979+set of marks that we've already tried.
1980+
1981+We kick off our search in `++apex`, starting with the given initial list
1982+of marks that we know how to get to.
1983+
1984+If `++apex` is called with a bolt other than a `%0` value bolt, we
1985+simply produce it. Otherwise, we check to see if the list of available
1986+marks to investigate is null. If so, then we're done, so we produce a
1987+`%0` bolt with a null list of accessible marks.
1988+
1989+Otherwise, we process this next mark with `++apse`, which will produce a
1990+possible list of marks from this one to the target mark. If it fails to
1991+produce a `%0` bolt, we just produce that. Otherwise, if it produces
1992+null, we can't get to our target through this mark, so we move on to the
1993+next one.
1994+
1995+If it doesn't produce null, then we have successfully found a
1996+translation path, so we produce it.
1997+
1998+In `++apse`, we first test to see if we've arrived at the target path.
1999+If so, we're done, so we produce a list including just ourself.
2000+Otherwise, we check to see if we've already tried this mark. If so, we
2001+know we can't succeed here, so we produce null. Otherwise, we put
2002+ourselves in the set of already-tried marks, and we move on.
2003+
2004+We call `++lily` to get the list of marks we can translate this one
2005+into.
2006+
2007+ ++ lily :: translation targets
2008+ |= [cof=cafe for=mark bek=beak]
2009+ ^- (bolt (list ,@tas))
2010+ =+ raf=(fang cof for bek)
2011+ ?: =(%2 -.q.raf) (fine p.raf ~)
2012+ %+ cope raf
2013+ |= [cof=cafe vax=vase]
2014+ %+ fine cof
2015+ %+ weld
2016+ ^- (list ,@tas)
2017+ ?. (slab %garb p.vax) ~
2018+ =+ gav=((soft (list ,@tas)) q:(slap vax [%cnzy %garb]))
2019+ ?~(gav ~ u.gav)
2020+ ?. (slab %grow p.vax) ~
2021+ =+ gow=(slap vax [%cnzy %grow])
2022+ (sloe p.gow)
2023+
2024+We call `++fang` to get the mark definition door. This is documented
2025+under `%vale`. If getting the mark fails, we produce null because we
2026+can't translate a non-existent mark into anything.
2027+
2028+Otherwise, we examine the door. The door may have a `++garb`, which is
2029+simply a list of marks which know how to translate from the current one.
2030+There must be a corresponding `++grab` in the definition of the other
2031+mark, though we don't check that here.
2032+
2033+The door may also have a `++grow`, which defines how to translate this
2034+mark into another one. Each arm in `++grow` is the name of a mark we can
2035+translate into. The call to `++sloe` simply produces a list of arm names
2036+in `++grow`.
2037+
2038+Back in `++apse:lion`, we take the list of translation targets we just
2039+found and call `++apex` on it. If we got back a null, we produce a null;
2040+otherwise, we produce the list of marks we got back plus the current
2041+mark.
2042+
2043+This concludes our discussion of `++lion`.
2044+
2045+The final piece of `++lima` is `++lope`, which performs the actual
2046+translation along the path we just computed.
2047+
2048+ ++ lope :: translation pipe
2049+ |= [cof=cafe for=mark yaw=(list mark) bek=beak vax=vase]
2050+ ^- (bolt vase)
2051+ ?~ yaw (fine cof vax)
2052+ %+ cope (link cof i.yaw for bek vax)
2053+ |= [cof=cafe yed=vase]
2054+ ^$(cof cof, for i.yaw, yaw t.yaw, vax yed)
2055+
2056+We iterate through our list, calling `++link` on every adjacent pair of
2057+marks, translating from one mark to the next until we finish the list of
2058+marks. A call to `++link` is equivalent to a `%cast` silk, so we
2059+document it there. After we've called performed every step in the
2060+translation pipeline, we're done.
2061+
2062+Lifecycle of a `%boil`
2063+----------------------
2064+
2065+ %boil
2066+ %+ cool |.(leaf/"ford: boil {<p.kas>} {<(tope q.kas)>} {<r.kas>}")
2067+ %+ cope (lamp cof q.kas)
2068+ |= [cof=cafe bem=beam]
2069+ %+ cope (lime cof p.kas bem r.kas)
2070+ |= [cof=cafe vax=vase]
2071+ (fine cof `cage`[p.kas vax])
2072+
2073+At a high level, we try to bake at the given beam, and if it fails, we
2074+go up a level and try again. This is the usual semantics of ford, and
2075+this should nearly always be preferred over directly baking.
2076+
2077+First, we normalize the version case to a number with `++lamp`. This
2078+allows caching to be based on revision number rather than something more
2079+ephemeral like a particular time.
2080+
2081+ ++ lamp :: normalize version
2082+ |= [cof=cafe bem=beam]
2083+ ^- (bolt beam)
2084+ =+ von=(ska %cw (tope bem(s ~)))
2085+ ?~ von [p=cof q=[%1 [bem ~] ~ ~]]
2086+ (fine cof bem(r [%ud ((hard ,@) (need u.von))]))
2087+
2088+We call the sky function with `%cw`, asking clay for the revision number
2089+at this case. If the case refers to a revision that isn't there yet, we
2090+produce a `%1` blocking bolt. Otherwise, we require that the value exist
2091+and that it's a number, both of which are guaranteed by clay. We produce
2092+this number.
2093+
2094+Next for `%boil` we call `++lime` to try to load the beam.
2095+
2096+ ++ lime :: load beam
2097+ |= [cof=cafe for=mark bem=beam arg=heel]
2098+ =+ [mob=bem mer=(flop arg)]
2099+ |- ^- (bolt vase)
2100+ %+ cope (lima cof for mob (flop mer))
2101+ |= [cof=cafe vux=(unit vase)]
2102+ ?^ vux (fine cof u.vux)
2103+ ?~ s.mob
2104+ (flaw cof (smyt (tope bem)) ~)
2105+ ^$(s.mob t.s.mob, mer [i.s.mob mer])
2106+
2107+We start at the given beam and try to bake it. If it succeeds, we're
2108+good. Otherwise, we pop off the top level of the path and put it in our
2109+heel (virtual path extension). We do this recursively until either we
2110+find something we can bake or we've gone all the way up to the root path
2111+of the desk, in which case we fail.
2112+
2113+Lifecycle of a `%call`
2114+----------------------
2115+
2116+ %call
2117+ %+ cool |.(leaf/"ford: call {<`@p`(mug kas)>}")
2118+ %. [cof p.kas q.kas]
2119+ ;~ cope
2120+ ;~ coax
2121+ |=([cof=cafe p=silk q=silk] ^$(cof cof, kas p))
2122+ |=([cof=cafe p=silk q=silk] ^$(cof cof, kas q))
2123+ ==
2124+ ::
2125+ |= [cof=cafe gat=cage sam=cage]
2126+ (maul cof q.gat q.sam)
2127+ ::
2128+ |= [cof=cafe vax=vase]
2129+ (fine cof %noun vax)
2130+ ==
2131+
2132+This is slam for silks. We process both of the given silks in parallel
2133+with `++coax`. We then slam the two produced vases together with
2134+`++maul` and mark the produced vase with `%noun` since we don't know any
2135+more specific mark.
2136+
2137+`++coax` is documented under Lifecycle of a Cell.
2138+
2139+Lifecycle of a `%cast`
2140+----------------------
2141+
2142+ %cast
2143+ %+ cool |.(leaf/"ford: cast {<p.kas>}")
2144+ %+ cope $(kas q.kas)
2145+ |= [cof=cafe cay=cage]
2146+ %+ cope (link cof p.kas p.cay [our %main %da now] q.cay)
2147+ |= [cof=cafe vax=vase]
2148+ (fine cof [p.kas vax])
2149+
2150+This is a request to convert data of one mark to another mark directly.
2151+We evaluate the given silk and pass the result into `++link`, which
2152+performs the actual translation. Note that this will not search for
2153+indirect conversion paths, so the conversion must be defined either in
2154+the `++grow` of the given mark or the `++grab` of the target mark.
2155+
2156+ ++ link :: translate
2157+ |= [cof=cafe too=mark for=mark bek=beak vax=vase]
2158+ ^- (bolt vase)
2159+ ?: =(too for) (fine cof vax)
2160+ ?: |(=(%noun for) =(%$ for))
2161+ ((lake too bek) cof vax)
2162+ %+ cope (fang cof for bek)
2163+ |= [cof=cafe pro=vase]
2164+ ?: &((slab %grow p.pro) (slab too p:(slap pro [%cnzy %grow])))
2165+ %+ cope (keel cof pro [[%& 6]~ vax]~)
2166+ |= [cof=cafe pox=vase]
2167+ (maim cof pox [%tsgr [%cnzy %grow] [%cnzy too]])
2168+ %+ cope (fang cof too bek)
2169+ |= [cof=cafe pro=vase]
2170+ =+ ^= zat ^- (unit vase)
2171+ ?. (slab %grab p.pro) ~
2172+ =+ gab=(slap pro [%cnzy %grab])
2173+ ?. (slab for p.gab) ~
2174+ `(slap gab [%cnzy for])
2175+ ?~ zat
2176+ (flaw cof [%leaf "ford: no link: {<[for too]>}"]~)
2177+ (maul cof u.zat vax)
2178+
2179+This performs one step in the translation pipeline. If the given and
2180+target marks are the same, we're done. If we're translating from a noun
2181+or the empty mark, we coerce with `++lake` (documented in `%vale`).
2182+Otherwise, we're translating from a user-defined mark.
2183+
2184+We load the definition of the given mark with `++fang`, and we check to
2185+see if it has an arm in `++grow` named the target mark. If so, we place
2186+our data in the sample of the door with `++keel` and slap the arm.
2187+`++keel` is equivalent to a `%mute` silk, so we document it there.
2188+
2189+If there is no arm in `++grow` of the given mark named the target mark,
2190+we suppose there must be an arm in `++grab` of the target mark named the
2191+given mark. We get the definition of the target mark and check to see if
2192+it has the required arm, failing if it doesn't. Finally, we slam the
2193+data against the correct arm, producing the translated data.
2194+
2195+If you're confused as to why the handling of `++grow` and `++grab` look
2196+superficially so different, remember that the correct arm in `++grow`
2197+does not have a sample while the one in `++grab` does. This means they
2198+must be called rather differently.
2199+
2200+Lifecycle of a `%diff`
2201+----------------------
2202+
2203+ %diff
2204+ %+ cool |.(leaf/"ford: diff {<`@p`(mug p.kas)>} {<`@p`(mug q.kas)>}")
2205+ (diff cof p.kas q.kas)
2206+
2207+We push debug information onto the trace and go right to `++diff`.
2208+
2209+ ++ diff
2210+ |= [cof=cafe kas=silk kos=silk]
2211+ ^- (bolt cage)
2212+ %. [cof kas kos]
2213+ ;~ cope
2214+ ;~ coax
2215+ |=([cof=cafe p=silk q=silk] (make cof p))
2216+ |=([cof=cafe p=silk q=silk] (make cof q))
2217+ ==
2218+ |= [cof=cafe cay=cage coy=cage]
2219+
2220+First, we process the two given silks to get our arguments.
2221+
2222+ ?. =(p.cay p.coy)
2223+ %+ flaw cof :_ ~
2224+ leaf/"diff on data of different marks: {(trip p.cay)} {(trip p.coy)}"
2225+
2226+If the two cages have different marks, then we can't diff them, so we
2227+complain.
2228+
2229+ %+ cope (fang cof p.cay [our %main %da now])
2230+ |= [cof=cafe pro=vase]
2231+
2232+We pull in the relevant mark's definition.
2233+
2234+ ?. (slab %grad p.pro)
2235+ (flaw cof leaf/"no ++grad" ~)
2236+ =+ gar=(slap pro [%cnzy %grad])
2237+ ?. (slab %form p.gar)
2238+ ?. (slab %sted p.gar)
2239+ (flaw cof leaf/"no ++form:grad nor ++sted:grad" ~)
2240+ =+ for=((soft ,@tas) q:(slap gar [%cnzy %sted]))
2241+ ?~ for
2242+ (flaw cof leaf/"bad ++sted:grad" ~)
2243+ (make cof %diff [%cast u.for kas] [%cast u.for kos])
2244+
2245+If there's no `++grad`, we complain. If there's no `++form:grad`, then
2246+we look for a `++sted:grad`. If we can't find either, or if
2247+`++sted:grad` isn't a term, then we complain. If `++sted:grad` exists
2248+and is a term, then it represents the mark we should use as a proxy to
2249+get our diff. So, we cast both our given cages to the new mark and start
2250+the dance again.
2251+
2252+ ?. (slab %diff p.gar)
2253+ (flaw cof leaf/"no ++diff:grad" ~)
2254+
2255+Otherwise, we expect a `++diff:grad`.
2256+
2257+ %+ cope (keel cof pro [[%& 6]~ q.cay]~)
2258+ |= [cof=cafe pox=vase]
2259+
2260+We put the first cage's data into the sample of the given mark's
2261+definition.
2262+
2263+ %+ cope
2264+ %^ maul cof
2265+ (slap (slap pox [%cnzy %grad]) [%cnzy %diff])
2266+ q.coy
2267+ |= [cof=cafe dif=vase]
2268+
2269+We run `++diff:grad` with a sample of the second cage's data.
2270+
2271+ =+ for=((soft ,@tas) q:(slap gar [%cnzy %form]))
2272+ ?~ for
2273+ (flaw cof leaf/"bad ++form:grad" ~)
2274+ (fine cof u.for dif)
2275+ ==
2276+
2277+We check that `++form:grad` exists, and we tag the result with it to
2278+give the final cage.
2279+
2280+Lifecycle of a `%done`
2281+----------------------
2282+
2283+ %done [cof %0 p.kas q.kas]
2284+
2285+This is trivial. We simply produce the given cage with the given set of
2286+dependencies. This is used when we already have a cage that we want to
2287+insert into another silk that requires a silk argument. It's analogous
2288+to the return operator in a monad -- which makes it sound way more
2289+complicated than it is.
2290+
2291+Lifecycle of a `%dude`
2292+----------------------
2293+
2294+ %dude (cool |.(p.kas) $(kas q.kas))
2295+
2296+This simply puts a given tank on the stack trace if the given silk
2297+produces an error. This is implemented as a simple call to `++cool`.
2298+
2299+Lifecycle of a `%dune`
2300+----------------------
2301+
2302+ %dune
2303+ ?~ q.kas [cof [%2 [%leaf "no data"]~]]
2304+ $(kas [%done p.kas u.q.kas])
2305+
2306+This is a sort of a `++need` for silks. If there is no data in the unit
2307+cage, we produce an error. Else, we simply produce the data in the cage.
2308+
2309+Lifcycle of a `%mute`
2310+---------------------
2311+
2312+ %mute (kale cof p.kas q.kas)
2313+
2314+This mutates a silk by putting the values of other silks at particular
2315+axes. This is useful in, for example, replacing the sample of the door
2316+in a mark definition.
2317+
2318+ ++ kale :: mutate
2319+ |= [cof=cafe kas=silk muy=(list (pair wing silk))]
2320+ ^- (bolt cage)
2321+ %+ cope
2322+ |- ^- (bolt (list (pair wing vase)))
2323+ ?~ muy (fine cof ~)
2324+ %+ cope (make cof q.i.muy)
2325+ |= [cof=cafe cay=cage]
2326+ %+ cope ^$(muy t.muy)
2327+ |= [cof=cafe rex=(list (pair wing vase))]
2328+ (fine cof [[p.i.muy q.cay] rex])
2329+ |= [cof=cafe yom=(list (pair wing vase))]
2330+ %+ cope (make cof kas)
2331+ |= [cof=cafe cay=cage]
2332+ %+ cope (keel cof q.cay yom)
2333+ |= [cof=cafe vax=vase]
2334+ (fine cof p.cay vax)
2335+
2336+First, we process each of the silks by calling `++make` on them. We pass
2337+the resultant vase and list of pairs of wings and silks to `++keel` to
2338+do the actual mutation. We assume the mutation doesn't change the mark
2339+of the main silk, so we mark the produced vase with the original mark.
2340+
2341+ ++ keel :: apply mutations
2342+ |= [cof=cafe suh=vase yom=(list (pair wing vase))]
2343+ ^- (bolt vase)
2344+ %^ maim cof
2345+ %+ slop suh
2346+ |- ^- vase
2347+ ?~ yom [[%atom %n] ~]
2348+ (slop q.i.yom $(yom t.yom))
2349+ ^- twig
2350+ :+ %cncb [%& 2]~
2351+ =+ axe=3
2352+ |- ^- (list (pair wing twig))
2353+ ?~ yom ~
2354+ :- [p.i.yom [%$ (peg axe 2)]]
2355+ $(yom t.yom, axe (peg axe 3))
2356+
2357+We first put the vases together in one big tuple starting with the
2358+subject and going through the mutations. We slap against this tuple a
2359+`%_` twig we directly construct. Since a `%_` twig takes a list of pairs
2360+of wings and twigs, we simply have to generate twigs referring to the
2361+correct axes in the subject. This is very easy since we just recur on
2362+axis 3 of whatever axis we were already at.
2363+
2364+Note the use of `%_` instead of `%=` enforces that our mutations don't
2365+change the type of the subject, which justifies our use of the original
2366+mark.
2367+
2368+Lifecycle of a `%pact`
2369+----------------------
2370+
2371+ %pact
2372+ %+ cool |.(leaf/"ford: pact {<`@p`(mug p.kas)>} {<`@p`(mug q.kas)>}")
2373+ (pact cof p.kas q.kas)
2374+
2375+We push debug information onto the trace and go right to `++pact`.
2376+
2377+ ++ pact :: patch
2378+ |= [cof=cafe kas=silk kos=silk]
2379+ ^- (bolt cage)
2380+ %. [cof kas kos]
2381+ ;~ cope
2382+ ;~ coax
2383+ |=([cof=cafe p=silk q=silk] (make cof p))
2384+ |=([cof=cafe p=silk q=silk] (make cof q))
2385+ ==
2386+ |= [cof=cafe cay=cage coy=cage]
2387+
2388+First, we process the two given silks to get our arguments.
2389+
2390+ %+ cope (fang cof p.cay [our %main %da now])
2391+ |= [cof=cafe pro=vase]
2392+
2393+We pull in the relevant mark's definition.
2394+
2395+ ?. (slab %grad p.pro)
2396+ (flaw cof leaf/"no ++grad" ~)
2397+ =+ gar=(slap pro [%cnzy %grad])
2398+ ?. (slab %form p.gar)
2399+ ?. (slab %sted p.gar)
2400+ (flaw cof leaf/"no ++form:grad nor ++sted:grad" ~)
2401+ =+ for=((soft ,@tas) q:(slap gar [%cnzy %sted]))
2402+ ?~ for
2403+ (flaw cof leaf/"bad ++sted:grad" ~)
2404+ (make cof %cast p.cay %pact [%cast u.for kas] kos)
2405+
2406+If there's no `++grad`, we complain. If there's no `++form:grad`, then
2407+we look for a `++sted:grad`. If we can't find either, or if
2408+`++sted:grad` isn't a term, then we complain. If `++sted:grad` exists
2409+and is a term, then it represents the mark we should use as a proxy to
2410+get our diff. So, we cast the first argument to the new mark, then try
2411+to patch. Afterward, we cast the result back to the original mark.
2412+
2413+ =+ for=((soft ,@tas) q:(slap gar [%cnzy %form]))
2414+ ?~ for
2415+ (flaw cof leaf/"bad ++form:grad" ~)
2416+ ?. =(u.for p.coy)
2417+ %+ flaw cof :_ ~
2418+ =< leaf/"pact on data with wrong form: {-} {+<} {+>}"
2419+ [(trip p.cay) (trip u.for) (trip p.coy)]
2420+
2421+If `++form:grad` isn't a term, or else our second argument isn't of that
2422+mark, we complain.
2423+
2424+ ?. (slab %pact p.gar)
2425+ (flaw cof leaf/"no ++pact:grad" ~)
2426+
2427+If we don't have a `++pact:grad`, we complain.
2428+
2429+ %+ cope (keel cof pro [[%& 6]~ q.cay]~)
2430+ |= [cof=cafe pox=vase]
2431+
2432+We put the first cage's data into the sample of the given mark's
2433+definition.
2434+
2435+ %+ cope
2436+ %^ maul cof
2437+ (slap (slap pox [%cnzy %grad]) [%cnzy %pact])
2438+ q.coy
2439+ |= [cof=cafe pat=vase]
2440+
2441+We run `++pact:grad` with a sample of the second cage's data, which is
2442+the diff.
2443+
2444+ (fine cof p.cay pat)
2445+ ==
2446+
2447+We tag the result with the mark of our first argument.
2448+
2449+Lifecycle of a `%plan`
2450+----------------------
2451+
2452+ %plan
2453+ %+ cope (abut:(meow p.kas q.kas) cof r.kas)
2454+ |= [cof=cafe vax=vase]
2455+ (fine cof %noun vax)
2456+
2457+This is a direct request to compile a hood at a given beam with a heel
2458+of the given path. We comply by calling `++abut` with the given
2459+arguments and producing the vase with a mark of `%noun`.
2460+
2461+Lifecycle of a `%reef`
2462+----------------------
2463+
2464+ %reef (fine cof %noun pit)
2465+
2466+This is one of the simplest silks. We simply produce our context, which
2467+is zuse compiled against hoon. The mark is a `%noun`.
2468+
2469+Lifcycle of a `%ride`
2470+---------------------
2471+
2472+ %ride
2473+ %+ cool |.(leaf/"ford: ride {<`@p`(mug kas)>}")
2474+ %+ cope $(kas q.kas)
2475+ |= [cof=cafe cay=cage]
2476+ %+ cope (maim cof q.cay p.kas)
2477+ |= [cof=cafe vax=vase]
2478+ (fine cof %noun vax)
2479+
2480+This slaps evaluates the given silk, then it slaps the result against
2481+the given twig. Since we don't know what of what mark (if any) is the
2482+result, we give it a mark of `%noun`.
2483+
2484+Lifecycle of a `%vale`
2485+----------------------
2486+
2487+ %vale
2488+ %+ cool |.(leaf/"ford: vale {<p.kas>} {<q.kas>} {<`@p`(mug r.kas)>}")
2489+ %+ cope (lave cof p.kas q.kas r.kas)
2490+ |= [cof=cafe vax=vase]
2491+ (fine cof `cage`[p.kas vax])
2492+
2493+This checks whether given data is of the given mark. If we don't have
2494+the definition of the mark, we check the given ship for it.
2495+
2496+We call `++lave` to perform the check, producing a vase. We produce this
2497+vase tagged with the given mark.
2498+
2499+ ++ lave :: validate
2500+ |= [cof=cafe for=mark his=ship som=*]
2501+ ^- (bolt vase)
2502+ ((lake for [our %main [%da now]]) cof [%noun som])
2503+
2504+This is a thinly-veiled wrapper over `++lake`. Note that, contrary to
2505+documented opinion, we do not in fact check the other ship's definition
2506+of a mark. This is likely a bug.
2507+
2508+At any rate, `++lake` coerces a noun into the correct type for a mark.
2509+
2510+ ++ lake :: check/coerce
2511+ |= [for=mark bek=beak]
2512+ |= [cof=cafe sam=vase]
2513+ ^- (bolt vase)
2514+ %+ cool |.(leaf/"ford: check {<[for bek `@p`(mug q.sam)]>}")
2515+ ?: ?=(?(%gate %core %door %hoon %hook) for)
2516+ :: ~& [%lake-easy for bek]
2517+ (fine cof sam)
2518+ %+ cope (fang cof for bek)
2519+ |= [cof=cafe tux=vase]
2520+ =+ bob=(slot 6 tux)
2521+ ?: (~(nest ut p.bob) | p.sam)
2522+ (fine cof sam)
2523+ ?. (slab %grab p.tux)
2524+ (flaw cof [%leaf "ford: no grab: {<[for bek]>}"]~)
2525+ =+ gab=(slap tux [%cnzy %grab])
2526+ ?. (slab %noun p.gab)
2527+ (flaw cof [%leaf "ford: no noun: {<[for bek]>}"]~)
2528+ %+ cope (maul cof (slap gab [%cnzy %noun]) [%noun q.sam])
2529+ |= [cof=cafe pro=vase]
2530+ ?: =(+<.q.pro q.sam)
2531+ (fine cof (slot 6 pro))
2532+ (flaw cof [%leaf "ford: invalid content: {<[for bek]>}"]~)
2533+
2534+This is going to coerce the sample into the correct type for the mark.
2535+First, we push a line onto the stack trace saying that we're checking
2536+the type. If the requested mark is a gate, core, door, hoon, or hook,
2537+then we don't do any more type information than just saying it's a noun,
2538+so we're done.
2539+
2540+Otherwise, we get the mark definition from our `/=main=/mar` directory
2541+with `++fang`, which we'll describe below.
2542+
2543+We check to see if our sample type nests within the type of the sample
2544+to the door. If so, then we're already of the correct type, so we're
2545+done.
2546+
2547+Otherwise, we check to see if there's a `++grab` in the door, and a
2548+`++noun` in the `++grab`. If not, there's no way we can translate to
2549+this mark, so we fail.
2550+
2551+If we have everything we need, we slam our sample (typed as a noun)
2552+against the `++noun` in `++grab`. If the sample of the door is the same
2553+as our sample, then the check succeeded, so we produce the well-typed
2554+sample of the door. Otherwise, we fail.
2555+
2556+ ++ fang :: protocol door
2557+ |= [cof=cafe for=mark bek=beak]
2558+ ^- (bolt vase)
2559+ =+ pax=/door/[for]/mar
2560+ =+ ^= bem ^- beam
2561+ :_ pax
2562+ ?: =(p.bek our) bek
2563+ =+ oak=[our %main %da now]
2564+ ?. =(~ (ska %cy (tope [oak pax]))) oak
2565+ bek
2566+ (cope (fade cof %hook bem) abut:(meow bem ~))
2567+
2568+A mark's definition is generally in
2569+`/=main=/mar/[mark-name]/door/hook'. If we don't find it there, we look in`/[given-beak]/mar/[mark-name]/door/hook'.
2570+We parse the mark definition with `++fade` and assemble it with
2571+`++abut:meow`. `++fade` is defined under the `%bake` silk.
docs/system/arvo/gall.mdnew file+161
@@ -0,0 +1,161 @@
1+<div class="short">
2+
3+`%gall`
4+=======
5+
6+Our application server manager.
7+
8+It allows applications and vanes to send messages to applications and
9+subscribe to data streams. This requires `%gall` to be a sort of a
10+hypervisor. Messages coming into `%gall` are routed to the intended
11+application, and the response comes back along the same route. If the
12+intended target is on another ship, `%gall` will behind-the-scenes route
13+it through ames to the other ship to run. This provides an abstraction
14+where all apps on all ships are communicated with over the same
15+interface.
16+
17+`%gall` neither accepts events from unix nor produces effects. It exists
18+entirely for the benefit of other vanes and, in particular,
19+applications. Eyre exposes `%gall`'s interface over http, and ames does
20+the same over the ames network. `%gall` uses ford to compile and run the
21+applications.
22+
23+</div>
24+
25+------------------------------------------------------------------------
26+
27+Cards
28+=====
29+
30+`%gall` accepts the following cards. The first three are the most
31+commonly used, while the others are primarily used internally.
32+
33+`%mess`
34+================
35+
36+Sends a message to an app. This will result in a call to the app's
37+`++poke` arm. The response is exactly one of a `%nice` if the action
38+succeeded or a `%mean` if not.
39+
40+------------------------------------------------------------------------
41+
42+`%show`
43+================
44+
45+Subscribes to a stream from an app. This will result in a call to the
46+app's either `++peek` or `++peer` arm. The first response will always be
47+either a `%nice` or a `%mean`, indicating whether or not the
48+subscription was successful. After the first response, there will be
49+zero or more responses of either `%rush` or `%rust`, which communicate
50+either a differntial or full update to the data stream. There may be a
51+`%mean`, which indicates that the subscription has been canceled and no
52+more responses will be received along this stream.
53+
54+------------------------------------------------------------------------
55+
56+`%nuke`
57+================
58+
59+Unsubscribes the current duct from its stream. This receives a response
60+of either a `%nice` or a `%mean`. Note that a response of `%nice` does
61+not imply that the current duct was in fact subscribed to any stream.
62+
63+------------------------------------------------------------------------
64+
65+`%init`
66+================
67+
68+Initializes a ship's apps. This should be called exactly once for each
69+ship on the pier. This produces no moves in response.
70+
71+------------------------------------------------------------------------
72+
73+`%sire`
74+================
75+
76+Instantiates a child app. The app will be at path `[p parent-path]`, and
77+it will be an instance of the `q` app. The only response will be `%gone`
78+when the child dies.
79+
80+------------------------------------------------------------------------
81+
82+`%rote`
83+================
84+
85+Signifies a remote request from ames. `r` should be of type `rook`. This
86+how an app on a foreign ship may send a `%mess`, `%show`, or `%nuke`
87+card. Note that `%gall` automatically converts `%mess`, `%show`, and
88+`%nuke` into ames messages behind the scenes, so the only entity that
89+should use `%rote` and `%roth` is ames. Formally, the response is either
90+a `%nice` or a `%mean`, which ames uses to give a positive or negative
91+ack. A logical response comes by passing a `%roth` card.
92+
93+------------------------------------------------------------------------
94+
95+`%roth`
96+================
97+
98+Gives the response received from a remote request. `r` should be of type
99+`roon`. This is how an app responds to a foreign request with a `%rush`,
100+`%rust`, `%nice`, or `%mean`. The response is either a `%nice` or a
101+`%mean`. Even though we, as the proverb goes, "never ack an ack", we do
102+need to acknowledge these responses since they're really independent
103+one-way messages.
104+
105+------------------------------------------------------------------------
106+
107+`%wipe`
108+================
109+
110+Wipes the given app from memory. This is generally considered a hack,
111+but it is sometimes useful during development to wipe the state of an
112+app. We don't guarantee that this actually completely wipes the app.
113+Generally, you want to use a `%cide` card if you actually want to kill
114+an app. This gives no response.
115+
116+------------------------------------------------------------------------
117+
118+`%cide`
119+================
120+
121+Kills an app and all its children. Even though it's not technically a
122+part of `%gall`'s interface since it's not in `++kiss` and can't be
123+called from the outside, it's worth mentioning `%cide`, which may be
124+called from within `%gall` apps. It should call `++part` to allow the
125+app any last words. This gives no response.
126+
127+------------------------------------------------------------------------
128+
129+Service Gates
130+=============
131+
132+[`++poke`]()
133+============
134+
135+Handles incoming messages. Most commonly with an associated `%logo`. For
136+example `++poke-json` handles an incoming JSON request from `%eyre`.
137+
138+[`++peer`]()
139+============
140+
141+Handles incoming subscriptions.
142+
143+[`++pull`]()
144+============
145+
146+Handles dropping subscribers.
147+
148+[`++pour`]()
149+============
150+
151+Handles responses to `%pass` moves.
152+
153+[`++park`]()
154+============
155+
156+Save state on update.
157+
158+[`++prep`]()
159+============
160+
161+Load state on update.
docs/system/arvo/gall/gall.mdnew file+5
@@ -0,0 +1,5 @@
1+Gall: Reference
2+===============
3+
4+Gall: Commentary
5+================
docs/system/arvo/time.mdnew file+21
@@ -0,0 +1,21 @@
1+<div class="short">
2+
3+`%time`
4+=======
5+
6+Our simple timer.
7+
8+It allows vanes and applications to set and timer events, which are
9+managed in a simple priority queue. `%time` produces effects to start
10+the unix timer, and when the requested `%time` passes, unix sends wake
11+events to `%time`, which time routes back to original sender. We don't
12+guarantee that a timer event will happen at exactly the `%time` it was
13+set for, or even that it'll be particularly close. A timer event is a
14+request to not be woken until after the given time.
15+
16+`%eyre` uses `%time` for timing out sessions, and `%clay` uses `%time`
17+for keeping track of time-specified file requests. `%ames` should
18+probably use `%time` to keep track of things like network timeouts and
19+retry timing, but it currently uses its own alarm system.
20+
21+</div>
docs/system/arvo/util.mdnew file+344
@@ -0,0 +1,344 @@
1+<div class="short">
2+
3+CLI Apps
4+========
5+
6+Our simple command-line applications.
7+
8+You can find them in `/main/app`.
9+
10+</div>
11+
12+------------------------------------------------------------------------
13+
14+### `:?begin`
15+
16+`~zod:dojo> :?begin [~ship-name [~valid-ticket-for-ship]]`
17+
18+Start a ship. `:?begin` collects all of the necessary information to
19+start an Urbit ship. Takes an option `[~ship-name]` or
20+`[~ship-name [~valid-ticket-for-ship]]` pair.
21+
22+------------------------------------------------------------------------
23+
24+### `+cat`
25+
26+`~zod:dojo> +cat /path/to/file [...]`
27+
28+"cat" a file. `+cat` either prints a file, or concatenates and then
29+prints multiple files to the terminal.
30+
31+ ~zod:dojo> +cat %/spec/nock/5/txt
32+ > +cat %/spec/nock/5/txt
33+ /~zod/home/~2015.6.29..22.33.04..fc76/spec/nock/5/txt
34+ A noun is an atom or a cell.
35+ …
36+
37+------------------------------------------------------------------------
38+
39+### `|cp`
40+
41+`~zod:dojo> |cp /path/to/source /path/to/destination`
42+
43+Copy a file to a given location.
44+
45+ ~zod:dojo> |cp %/spec/nock/5/txt %/try/6/txt
46+ > |cp %/spec/nock/5/txt %/try/6/txt
47+ + /~zod/home/2/try/6/txt
48+ >=
49+
50+------------------------------------------------------------------------
51+
52+### `grep`
53+
54+<mark>GONE</mark>
55+
56+`~zod:dojo> :grep 'literal'`
57+"grep" a file or standard input. Currently only supports a literal cord,
58+but will eventuall support regular expressions.
59+
60+------------------------------------------------------------------------
61+
62+### `|hi`
63+
64+`~zod:dojo> |hi ~ship ["message"]`
65+
66+Send a ship a message which is empty by default, becoming their neighbor
67+in the process. Often used to ping ships to check connectivity.
68+
69+
70+ ~zod:dojo> |hi ~doznec
71+ > |hi ~doznec
72+ ames: czar zod.urbit.org: ip .192.241.195.84
73+ >=
74+ hi ~doznec succesful
75+ ; ~doznec is your neighbor
76+ ; ~doznec is your neighbor
77+
78+and on ~doznec
79+
80+ ~doznec:dojo>
81+ < ~zod:
82+ ; ~zod is your neighbor
83+
84+
85+send a message
86+
87+ ~zod:dojo> |hi ~doznec "say something"
88+ >=
89+ hi ~doznec succesful
90+
91+and on ~doznec
92+
93+ < ~zod: say something
94+
95+
96+------------------------------------------------------------------------
97+
98+### `:into`
99+
100+<mark>GONE</mark>
101+
102+`~zod:dojo> :into /path/to/file 'contents'`
103+
104+Write text to a file. If the specified file does not exist, create a
105+file by that name. If it does exist, replace its contents.
106+
107+
108+------------------------------------------------------------------------
109+
110+### `|label`
111+
112+<mark>GONE? returns file not found</mark>
113+
114+`~zod:dojo> |label %path %label`
115+
116+"label". Add a label to a change number.
117+
118+ ~zod:dojo> |label %try %zebra
119+ = new /~zod/try/3
120+ ~zod:dojo> :ls /=try/zebra
121+ readme
122+
123+Note that adding a label is part of the delta stream and creates a new
124+change number, `3`.
125+
126+
127+------------------------------------------------------------------------
128+
129+### `+ls`
130+
131+`~zod:dojo> :+ls path/to/directory`
132+
133+"ls". List files at a path. Unlike "ls" in Unix, the current path `%`
134+must be explicitly given (you cannot call `+ls` with no arguments to
135+display the files at the current path).
136+
137+ ~zod:dojo> +ls %try
138+ > +ls %/try/
139+ readme/md
140+
141+------------------------------------------------------------------------
142+
143+### `|mount`
144+
145+`~zod:dojo> |mount /path/to/directory/version %mount-point`
146+
147+Your files are not synced to unix by default.
148+To sync a subtree to unix, run `|mount /path/to/directory %mount-point`.
149+This will sync it into `<pier>/<mount-point>.`
150+If you want to sync your whole home desk into f0/home, for example,
151+run `|mount % %home` You can also [`|unmount`]().
152+
153+ ~zod:dojo> |mount /~zod/base/0 %base
154+ > |mount /~zod/base %base
155+ >=
156+
157+------------------------------------------------------------------------
158+
159+### `|mv`
160+
161+`~zod:dojo> |mv /path/to/source /path/to/destination`
162+
163+Move a file to a given location, creating a new revision of the source
164+that omits the moved file.
165+
166+ ~zod:dojo> |mv %/try/6/txt %/try/7/txt
167+ > |mv %/try/6/txt %/try/7/txt
168+ + /~zod/home/3/try/7/txt
169+ >=
170+
171+------------------------------------------------------------------------
172+
173+### `|reload`
174+
175+`~zod:dojo> |reload %vane-name [...]`
176+
177+Reload the standard library (zuse) and/or arvo vanes. If zuse is
178+reloaded, vanes depending on the changes must be reloaded as well. For
179+example `|reload %zuse %ford` is necessary to make use of changes in
180+application code or the REPL.
181+
182+Possible values for %vane-name see [Overview](overview "overview"):
183+
184+ ~zod:dojo> |reload %zuse
185+ [%tang /~zod/home/~2015.6.29..23.50.29..134d/arvo/zuse ~hillyx-salhet]
186+ > |reload %zuse
187+ >=
188+
189+------------------------------------------------------------------------
190+
191+### `|reset`
192+
193+`~zod:dojo> |reset`
194+
195+Reloads all vanes. See [`|reload`]() for reloading only or a specific vane.
196+
197+ ~zod:dojo> |reset
198+ [%vega-start /~zod/home/~2015.6.29..23.51.42..f335/arvo/hoon]
199+ %vega-parsed
200+ [%vega-compiled %163 163]
201+ %hoon-load
202+ [%tang /~zod/home/~2015.6.29..23.51.42..f335/arvo/zuse ~hillyx-salhet]
203+ [%vane %a /~zod/home/~2015.6.29..23.51.42..f335/arvo/ames ~tilwyl-talren]
204+ %ames-reload
205+ [%vane %c /~zod/home/~2015.6.29..23.51.42..f335/arvo/clay ~molmur-panlus]
206+ [%vane %d /~zod/home/~2015.6.29..23.51.42..f335/arvo/dill ~sicbet-miphes]
207+ [%vane %e /~zod/home/~2015.6.29..23.51.42..f335/arvo/eyre ~solrux-sibnep]
208+ [gub=30 hov=19 ged=18 ded=1 pox=1 ask=1 kes=1 ney=35 dop=1 liz=1 wup=1 sop=1 wix=1]
209+ [%vane %f /~zod/home/~2015.6.29..23.51.42..f335/arvo/ford ~librem-sopseg]
210+ [%vane %g /~zod/home/~2015.6.29..23.51.42..f335/arvo/gall ~sidsub-fasrev]
211+ [%vane %t /~zod/home/~2015.6.29..23.51.42..f335/arvo/time ~ritwyn-lanrev]
212+ > |reset
213+ <<<reset>>>
214+ >=
215+
216+------------------------------------------------------------------------
217+
218+### `|rm`
219+
220+`~zod:dojo> |rm /path/to/source`
221+
222+Remove a file.
223+
224+ ~zod:dojo> |rm %/try/7/txt
225+ >=
226+
227+------------------------------------------------------------------------
228+
229+### `+solid`
230+
231+`~zod:dojo> +solid`
232+
233+compiles a kernel into a new full urbit.pill
234+
235+------------------------------------------------------------------------
236+
237+### `|sync`
238+
239+`~zod:dojo> |sync %source-desk ~hidduc-posmeg %target-desk`
240+
241+Sets up a subscription to the source desk on the target ship name to the
242+target desk on your ship.
243+
244+------------------------------------------------------------------------
245+
246+### `+ticket`
247+
248+`~zod:dojo> +ticket ~ship-name`
249+
250+Creates a will for a ship. `+ticket` outputs the ticket for a Urbit
251+ship. Takes an option `[~ship-name]`. On destroyes this command creates
252+a yacht and takes the option \`[\~yacht-name-destroyer-name]
253+
254+------------------------------------------------------------------------
255+
256+### `:thumb`
257+
258+<mark>GONE</mark>
259+
260+`~zod:dojo> :thumb ~ship-name`
261+
262+Show the ships information. Only works if you issued a [`:hi`]
263+[\`\~ship-name] beforehand.
264+
265+This command is not avaible since the switch from batz to `%gall`!
266+
267+Use this for the time beeing: - will:
268+`~zod/try=> ((hard (unit gcos)) .^(%a /=gcos=/~ship-name))` - raw will:
269+`~zod/try=> ((hard will) .^(%a /=will=/~ship-name))`
270+
271+
272+------------------------------------------------------------------------
273+
274+### `|unmount`
275+
276+`~zod:dojo> |unmount /path/to/directory`
277+
278+Your files are not synced to unix by default.
279+To sync a subtree to unix, run `|mount`.
280+You can unmount with either `|unmount /path/to/directory`
281+or `|unmount %mount-point`.
282+
283+ ~zod:dojo> |unmount %base
284+ > |unmount %base
285+ >=
286+
287+------------------------------------------------------------------------
288+
289+### `|unsync`
290+
291+`~zod:dojo> |unsync %source-desk ~hidduc-posmeg %target-desk`
292+
293+Cancels the subscription to the source desk on the target ship name to
294+the target desk on your ship.
295+
296+------------------------------------------------------------------------
297+
298+### `|verb`
299+
300+`~zod:dojo> |verb`
301+
302+Turn verbose arvo mode on/off.
303+
304+You'll see events, internal cards, and effects.
305+
306+ [%unix p=%wake //temp]
307+ [ %give
308+ %t
309+ %wake
310+ ~[
311+ /c/tyme
312+ /g/a/~zod/._~~.58_~~.shell_~~.terminal__/w/drug/~zod/main
313+ /g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/began/u
314+ /g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/._~~.2_~~.shell_~~.terminal__/u/to-gan
315+ /g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/._~~.shell_~~.terminal__/u/child/2/main
316+ /g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/terminal/u/txt
317+ /d/term-mess
318+ //term/1
319+ ]
320+ ]
321+ [ %give
322+ %c
323+ %writ
324+ ~[
325+ /g/a/~zod/._~~.58_~~.shell_~~.terminal__/w/drug/~zod
326+ /g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/began/u
327+ /g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/._~~.2_~~.shell_~~.terminal__/u/to-gan
328+ /g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/._~~.shell_~~.terminal__/u/child/2/main
329+ /g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/terminal/u/txt
330+ /d/term-mess
331+ //term/1
332+ ]
333+ ]
334+ ...
335+
336+------------------------------------------------------------------------
337+
338+### `|ye`
339+
340+`~zod:dojo> |ye ["message"]`
341+
342+Send a message to all ships. Often used to announce a continuity breach.
343+
344+------------------------------------------------------------------------
docs/dev/hoon/reference/cheat-sheet.md → docs/system/hoon/cheat-sheets/hoon.mdrenamed

The content is the same.

docs/dev/hoon/reference/odors.md → docs/system/hoon/cheat-sheets/odors.mdrenamed

The content is the same.

docs/dev/hoon/reference/pronunciation.md → docs/system/hoon/cheat-sheets/pronunciation.mdrenamed

The content is the same.

docs/dev/hoon/reference.md → docs/system/hoon/cheet-sheets.mdrenamed

The content is the same.

docs/dev/hoon/library.md → docs/system/hoon/library.mdrenamed

The content is the same.

docs/dev/hoon/library/0.md → docs/system/hoon/library/0.mdrenamed

The content is the same.

docs/dev/hoon/library/1.md → docs/system/hoon/library/1.mdrenamed

The content is the same.

docs/dev/hoon/library/2a.md → docs/system/hoon/library/2a.mdrenamed

The content is the same.

docs/dev/hoon/library/2b.md → docs/system/hoon/library/2b.mdrenamed

The content is the same.

docs/dev/hoon/library/2c.md → docs/system/hoon/library/2c.mdrenamed

The content is the same.

docs/dev/hoon/library/2da.md → docs/system/hoon/library/2da.mdrenamed

The content is the same.

docs/dev/hoon/library/2db.md → docs/system/hoon/library/2db.mdrenamed

The content is the same.

docs/dev/hoon/library/2dc.md → docs/system/hoon/library/2dc.mdrenamed

The content is the same.

docs/dev/hoon/library/2dd.md → docs/system/hoon/library/2dd.mdrenamed

The content is the same.

docs/dev/hoon/library/2ea.md → docs/system/hoon/library/2ea.mdrenamed

The content is the same.

docs/dev/hoon/library/2eb.md → docs/system/hoon/library/2eb.mdrenamed

The content is the same.

docs/dev/hoon/library/2ec.md → docs/system/hoon/library/2ec.mdrenamed

The content is the same.

docs/dev/hoon/library/2ed.md → docs/system/hoon/library/2ed.mdrenamed

The content is the same.

docs/dev/hoon/library/2ee.md → docs/system/hoon/library/2ee.mdrenamed

The content is the same.

docs/dev/hoon/library/2ef.md → docs/system/hoon/library/2ef.mdrenamed

The content is the same.

docs/dev/hoon/library/2eg.md → docs/system/hoon/library/2eg.mdrenamed

The content is the same.

docs/dev/hoon/library/2eh.md → docs/system/hoon/library/2eh.mdrenamed

The content is the same.

docs/dev/hoon/library/2ei.md → docs/system/hoon/library/2ei.mdrenamed

The content is the same.

docs/dev/hoon/library/2ej.md → docs/system/hoon/library/2ej.mdrenamed

The content is the same.

docs/dev/hoon/library/2ek.md → docs/system/hoon/library/2ek.mdrenamed

The content is the same.

docs/dev/hoon/library/2el.md → docs/system/hoon/library/2el.mdrenamed

The content is the same.

docs/dev/hoon/library/2em.md → docs/system/hoon/library/2em.mdrenamed

The content is the same.

docs/dev/hoon/library/2en.md → docs/system/hoon/library/2en.mdrenamed

The content is the same.

docs/dev/hoon/library/2eo.md → docs/system/hoon/library/2eo.mdrenamed

The content is the same.

docs/dev/hoon/library/2ep.md → docs/system/hoon/library/2ep.mdrenamed

The content is the same.

docs/dev/hoon/library/2ew.md → docs/system/hoon/library/2ew.mdrenamed

The content is the same.

docs/dev/hoon/library/2ex.md → docs/system/hoon/library/2ex.mdrenamed

The content is the same.

docs/dev/hoon/library/2ey.md → docs/system/hoon/library/2ey.mdrenamed

The content is the same.

docs/dev/hoon/library/2ez.md → docs/system/hoon/library/2ez.mdrenamed

The content is the same.

docs/dev/hoon/library/3ba.md → docs/system/hoon/library/3ba.mdrenamed

The content is the same.

docs/dev/hoon/library/3bb.md → docs/system/hoon/library/3bb.mdrenamed

The content is the same.

docs/dev/hoon/library/3bc.md → docs/system/hoon/library/3bc.mdrenamed

The content is the same.

docs/dev/hoon/library/3bd.md → docs/system/hoon/library/3bd.mdrenamed

The content is the same.

docs/dev/hoon/library/3be.md → docs/system/hoon/library/3be.mdrenamed

The content is the same.

docs/dev/hoon/library/3bf.md → docs/system/hoon/library/3bf.mdrenamed

The content is the same.

docs/dev/hoon/library/3bg.md → docs/system/hoon/library/3bg.mdrenamed

The content is the same.

docs/dev/hoon/library/3bh.md → docs/system/hoon/library/3bh.mdrenamed

The content is the same.

docs/dev/hoon/library/3bi.md → docs/system/hoon/library/3bi.mdrenamed

The content is the same.

docs/dev/hoon/runes.md → docs/system/hoon/runes.mdrenamed

The content is the same.

docs/dev/hoon/runes/bc/bcbr.md → docs/system/hoon/runes/bc/bcbr.mdrenamed

The content is the same.

docs/dev/hoon/runes/bc/bccb.md → docs/system/hoon/runes/bc/bccb.mdrenamed

The content is the same.

docs/dev/hoon/runes/bc/bccl.md → docs/system/hoon/runes/bc/bccl.mdrenamed

The content is the same.

docs/dev/hoon/runes/bc/bccn.md → docs/system/hoon/runes/bc/bccn.mdrenamed

The content is the same.

docs/dev/hoon/runes/bc/bcls.md → docs/system/hoon/runes/bc/bcls.mdrenamed

The content is the same.

docs/dev/hoon/runes/bc/bcpm.md → docs/system/hoon/runes/bc/bcpm.mdrenamed

The content is the same.

docs/dev/hoon/runes/bc/bctr.md → docs/system/hoon/runes/bc/bctr.mdrenamed

The content is the same.

docs/dev/hoon/runes/bc/bcts.md → docs/system/hoon/runes/bc/bcts.mdrenamed

The content is the same.

docs/dev/hoon/runes/bc/bcwt.md → docs/system/hoon/runes/bc/bcwt.mdrenamed

The content is the same.

docs/dev/hoon/runes/br/brcb.md → docs/system/hoon/runes/br/brcb.mdrenamed

The content is the same.

docs/dev/hoon/runes/br/brcn.md → docs/system/hoon/runes/br/brcn.mdrenamed

The content is the same.

docs/dev/hoon/runes/br/brdt.md → docs/system/hoon/runes/br/brdt.mdrenamed

The content is the same.

docs/dev/hoon/runes/br/brfs.md → docs/system/hoon/runes/br/brfs.mdrenamed

The content is the same.

docs/dev/hoon/runes/br/brhp.md → docs/system/hoon/runes/br/brhp.mdrenamed

The content is the same.

docs/dev/hoon/runes/br/brkt.md → docs/system/hoon/runes/br/brkt.mdrenamed

The content is the same.

docs/dev/hoon/runes/br/brls.md → docs/system/hoon/runes/br/brls.mdrenamed

The content is the same.

docs/dev/hoon/runes/br/brtr.md → docs/system/hoon/runes/br/brtr.mdrenamed

The content is the same.

docs/dev/hoon/runes/br/brts.md → docs/system/hoon/runes/br/brts.mdrenamed

The content is the same.

docs/dev/hoon/runes/br/brwt.md → docs/system/hoon/runes/br/brwt.mdrenamed

The content is the same.

docs/dev/hoon/runes/cl/clcb.md → docs/system/hoon/runes/cl/clcb.mdrenamed

The content is the same.

docs/dev/hoon/runes/cl/clfs.md → docs/system/hoon/runes/cl/clfs.mdrenamed

The content is the same.

docs/dev/hoon/runes/cl/clhp.md → docs/system/hoon/runes/cl/clhp.mdrenamed

The content is the same.

docs/dev/hoon/runes/cl/clkt.md → docs/system/hoon/runes/cl/clkt.mdrenamed

The content is the same.

docs/dev/hoon/runes/cl/clls.md → docs/system/hoon/runes/cl/clls.mdrenamed

The content is the same.

docs/dev/hoon/runes/cl/clsg.md → docs/system/hoon/runes/cl/clsg.mdrenamed

The content is the same.

docs/dev/hoon/runes/cl/cltr.md → docs/system/hoon/runes/cl/cltr.mdrenamed

The content is the same.

docs/dev/hoon/runes/cn/cncb.md → docs/system/hoon/runes/cn/cncb.mdrenamed

The content is the same.

docs/dev/hoon/runes/cn/cndt.md → docs/system/hoon/runes/cn/cndt.mdrenamed

The content is the same.

docs/dev/hoon/runes/cn/cnhp.md → docs/system/hoon/runes/cn/cnhp.mdrenamed

The content is the same.

docs/dev/hoon/runes/cn/cnkt.md → docs/system/hoon/runes/cn/cnkt.mdrenamed

The content is the same.

docs/dev/hoon/runes/cn/cnls.md → docs/system/hoon/runes/cn/cnls.mdrenamed

The content is the same.

docs/dev/hoon/runes/cn/cnsg.md → docs/system/hoon/runes/cn/cnsg.mdrenamed

The content is the same.

docs/dev/hoon/runes/cn/cntr.md → docs/system/hoon/runes/cn/cntr.mdrenamed

The content is the same.

docs/dev/hoon/runes/cn/cnts.md → docs/system/hoon/runes/cn/cnts.mdrenamed

The content is the same.

docs/dev/hoon/runes/dt/dtkt.md → docs/system/hoon/runes/dt/dtkt.mdrenamed

The content is the same.

docs/dev/hoon/runes/dt/dtls.md → docs/system/hoon/runes/dt/dtls.mdrenamed

The content is the same.

docs/dev/hoon/runes/dt/dttr.md → docs/system/hoon/runes/dt/dttr.mdrenamed

The content is the same.

docs/dev/hoon/runes/dt/dtts.md → docs/system/hoon/runes/dt/dtts.mdrenamed

The content is the same.

docs/dev/hoon/runes/dt/dtwt.md → docs/system/hoon/runes/dt/dtwt.mdrenamed

The content is the same.

docs/dev/hoon/runes/dt/dtzy.md → docs/system/hoon/runes/dt/dtzy.mdrenamed

The content is the same.

docs/dev/hoon/runes/dt/dtzz.md → docs/system/hoon/runes/dt/dtzz.mdrenamed

The content is the same.

docs/dev/hoon/runes/hx/hxgl.md → docs/system/hoon/runes/hx/hxgl.mdrenamed

The content is the same.

docs/dev/hoon/runes/hx/hxgr.md → docs/system/hoon/runes/hx/hxgr.mdrenamed

The content is the same.

docs/dev/hoon/runes/kt/ktbr.md → docs/system/hoon/runes/kt/ktbr.mdrenamed

The content is the same.

docs/dev/hoon/runes/kt/ktdt.md → docs/system/hoon/runes/kt/ktdt.mdrenamed

The content is the same.

docs/dev/hoon/runes/kt/kthp.md → docs/system/hoon/runes/kt/kthp.mdrenamed

The content is the same.

docs/dev/hoon/runes/kt/ktls.md → docs/system/hoon/runes/kt/ktls.mdrenamed

The content is the same.

docs/dev/hoon/runes/kt/ktpm.md → docs/system/hoon/runes/kt/ktpm.mdrenamed

The content is the same.

docs/dev/hoon/runes/kt/ktsg.md → docs/system/hoon/runes/kt/ktsg.mdrenamed

The content is the same.

docs/dev/hoon/runes/kt/ktts.md → docs/system/hoon/runes/kt/ktts.mdrenamed

The content is the same.

docs/dev/hoon/runes/kt/ktwt.md → docs/system/hoon/runes/kt/ktwt.mdrenamed

The content is the same.

docs/dev/hoon/runes/sg/sgbc.md → docs/system/hoon/runes/sg/sgbc.mdrenamed

The content is the same.

docs/dev/hoon/runes/sg/sgbr.md → docs/system/hoon/runes/sg/sgbr.mdrenamed

The content is the same.

docs/dev/hoon/runes/sg/sgcb.md → docs/system/hoon/runes/sg/sgcb.mdrenamed

The content is the same.

docs/dev/hoon/runes/sg/sgcn.md → docs/system/hoon/runes/sg/sgcn.mdrenamed

The content is the same.

docs/dev/hoon/runes/sg/sgfs.md → docs/system/hoon/runes/sg/sgfs.mdrenamed

The content is the same.

docs/dev/hoon/runes/sg/sggl.md → docs/system/hoon/runes/sg/sggl.mdrenamed

The content is the same.

docs/dev/hoon/runes/sg/sggr.md → docs/system/hoon/runes/sg/sggr.mdrenamed

The content is the same.

docs/dev/hoon/runes/sg/sgls.md → docs/system/hoon/runes/sg/sgls.mdrenamed

The content is the same.

docs/dev/hoon/runes/sg/sgpm.md → docs/system/hoon/runes/sg/sgpm.mdrenamed

The content is the same.

docs/dev/hoon/runes/sg/sgts.md → docs/system/hoon/runes/sg/sgts.mdrenamed

The content is the same.

docs/dev/hoon/runes/sg/sgwt.md → docs/system/hoon/runes/sg/sgwt.mdrenamed

The content is the same.

docs/dev/hoon/runes/sg/sgzp.md → docs/system/hoon/runes/sg/sgzp.mdrenamed

The content is the same.

docs/dev/hoon/runes/sm.md → docs/system/hoon/runes/sm.mdrenamed

The content is the same.

docs/dev/hoon/runes/sm/smcl.md → docs/system/hoon/runes/sm/smcl.mdrenamed

The content is the same.

docs/dev/hoon/runes/sm/smcn.md → docs/system/hoon/runes/sm/smcn.mdrenamed

The content is the same.

docs/dev/hoon/runes/sm/smdq.md → docs/system/hoon/runes/sm/smdq.mdrenamed

The content is the same.

docs/dev/hoon/runes/sm/smhp.md → docs/system/hoon/runes/sm/smhp.mdrenamed

The content is the same.

docs/dev/hoon/runes/sm/smls.md → docs/system/hoon/runes/sm/smls.mdrenamed

The content is the same.

docs/dev/hoon/runes/sm/smsg.md → docs/system/hoon/runes/sm/smsg.mdrenamed

The content is the same.

docs/dev/hoon/runes/sm/smsm.md → docs/system/hoon/runes/sm/smsm.mdrenamed

The content is the same.

docs/dev/hoon/runes/sm/smtr.md → docs/system/hoon/runes/sm/smtr.mdrenamed

The content is the same.

docs/dev/hoon/runes/sm/smzz.md → docs/system/hoon/runes/sm/smzz.mdrenamed

The content is the same.

docs/dev/hoon/runes/ts/tsbr.md → docs/system/hoon/runes/ts/tsbr.mdrenamed

The content is the same.

docs/dev/hoon/runes/ts/tscl.md → docs/system/hoon/runes/ts/tscl.mdrenamed

The content is the same.

docs/dev/hoon/runes/ts/tsdt.md → docs/system/hoon/runes/ts/tsdt.mdrenamed

The content is the same.

docs/dev/hoon/runes/ts/tsgl.md → docs/system/hoon/runes/ts/tsgl.mdrenamed

The content is the same.

docs/dev/hoon/runes/ts/tsgr.md → docs/system/hoon/runes/ts/tsgr.mdrenamed

The content is the same.

docs/dev/hoon/runes/ts/tshp.md → docs/system/hoon/runes/ts/tshp.mdrenamed

The content is the same.

docs/dev/hoon/runes/ts/tskt.md → docs/system/hoon/runes/ts/tskt.mdrenamed

The content is the same.

docs/dev/hoon/runes/ts/tsls.md → docs/system/hoon/runes/ts/tsls.mdrenamed

The content is the same.

docs/dev/hoon/runes/ts/tssg.md → docs/system/hoon/runes/ts/tssg.mdrenamed

The content is the same.

docs/dev/hoon/runes/ts/tstr.md → docs/system/hoon/runes/ts/tstr.mdrenamed

The content is the same.

docs/dev/hoon/runes/wt/wtbr.md → docs/system/hoon/runes/wt/wtbr.mdrenamed

The content is the same.

docs/dev/hoon/runes/wt/wtcl.md → docs/system/hoon/runes/wt/wtcl.mdrenamed

The content is the same.

docs/dev/hoon/runes/wt/wtdt.md → docs/system/hoon/runes/wt/wtdt.mdrenamed

The content is the same.

docs/dev/hoon/runes/wt/wtgl.md → docs/system/hoon/runes/wt/wtgl.mdrenamed

The content is the same.

docs/dev/hoon/runes/wt/wtgr.md → docs/system/hoon/runes/wt/wtgr.mdrenamed

The content is the same.

docs/dev/hoon/runes/wt/wthp.md → docs/system/hoon/runes/wt/wthp.mdrenamed

The content is the same.

docs/dev/hoon/runes/wt/wthz.md → docs/system/hoon/runes/wt/wthz.mdrenamed

The content is the same.

docs/dev/hoon/runes/wt/wtkt.md → docs/system/hoon/runes/wt/wtkt.mdrenamed

The content is the same.

docs/dev/hoon/runes/wt/wtkz.md → docs/system/hoon/runes/wt/wtkz.mdrenamed

The content is the same.

docs/dev/hoon/runes/wt/wtls.md → docs/system/hoon/runes/wt/wtls.mdrenamed

The content is the same.

docs/dev/hoon/runes/wt/wtlz.md → docs/system/hoon/runes/wt/wtlz.mdrenamed

The content is the same.

docs/dev/hoon/runes/wt/wtpm.md → docs/system/hoon/runes/wt/wtpm.mdrenamed

The content is the same.

docs/dev/hoon/runes/wt/wtpt.md → docs/system/hoon/runes/wt/wtpt.mdrenamed

The content is the same.

docs/dev/hoon/runes/wt/wtpz.md → docs/system/hoon/runes/wt/wtpz.mdrenamed

The content is the same.

docs/dev/hoon/runes/wt/wtsg.md → docs/system/hoon/runes/wt/wtsg.mdrenamed

The content is the same.

docs/dev/hoon/runes/wt/wtsz.md → docs/system/hoon/runes/wt/wtsz.mdrenamed

The content is the same.

docs/dev/hoon/runes/wt/wtts.md → docs/system/hoon/runes/wt/wtts.mdrenamed

The content is the same.

docs/dev/hoon/runes/wt/wttz.md → docs/system/hoon/runes/wt/wttz.mdrenamed

The content is the same.

docs/dev/hoon/runes/wt/wtzp.md → docs/system/hoon/runes/wt/wtzp.mdrenamed

The content is the same.

docs/dev/hoon/runes/zp/zpcb.md → docs/system/hoon/runes/zp/zpcb.mdrenamed

The content is the same.

docs/dev/hoon/runes/zp/zpcm.md → docs/system/hoon/runes/zp/zpcm.mdrenamed

The content is the same.

docs/dev/hoon/runes/zp/zpfs.md → docs/system/hoon/runes/zp/zpfs.mdrenamed

The content is the same.

docs/dev/hoon/runes/zp/zpgr.md → docs/system/hoon/runes/zp/zpgr.mdrenamed

The content is the same.

docs/dev/hoon/runes/zp/zpsm.md → docs/system/hoon/runes/zp/zpsm.mdrenamed

The content is the same.

docs/dev/hoon/runes/zp/zpts.md → docs/system/hoon/runes/zp/zpts.mdrenamed

The content is the same.

docs/dev/hoon/runes/zp/zpwt.md → docs/system/hoon/runes/zp/zpwt.mdrenamed

The content is the same.

docs/dev/hoon/runes/zp/zpzp.md → docs/system/hoon/runes/zp/zpzp.mdrenamed

The content is the same.

docs/dev/interpreter/u3.md → docs/system/interpreter/u3.mdrenamed

The content is the same.

docs/dev/nock/reference.md → docs/system/nock/reference.mdrenamed

The content is the same.

docs/theory.mddeleted−26
@@ -1,26 +0,0 @@
1−---
2−logo: black
3−sort: 3
4−title: Theory
5−---
6−
7−<div class="short">
8−
9−# Theory
10−
11−The only single document with a general overview of Urbit is our
12−ginormous [whitepaper](theory/whitepaper). The whitepaper has been
13−described as "sort of like a PhD thesis, but maybe more like
14−three PhD theses jammed into a single 40-page document." Like
15−Everest, it's there.
16−
17−Some critics experience doubt that Urbit is actually a real
18−thing. This is forgivable. Sometimes, visual evidence will
19−correct these disturbed minds. See our 2015 demo
20−[(part 1)](theory/part-i), [(part 2)](theory/part-ii), or our original
21−[2013 demo](theory/old). But if the aliens could fake the moon
22−landings, they could certainly fake Urbit.
23−
24−<list dataSort="true"></list>
25−
26−</div>
docs/theory/network-goals.mddeleted−565
@@ -1,565 +0,0 @@
1−---
2−sort: 4
3−title: Network architecture: goals
4−---
5−
6−# Design of a digital republic: part 1, goals
7−
8−Some of us remember when the Internet was a social network.
9−Today, the Internet is a modem.
10−
11−It's a wonderful modem. It connects you to all kinds of great
12−online services. Some of which are social "networks," but only
13−networks in the MBA sense. Really they're social *servers*:
14−giant virtual mainframes running one hardcoded program. 1976
15−called — it wants its acoustic coupler back.
16−
17−So, you prefer 1996. So, you wish you had your decentralized
18−Internet back. So, you don't seem alone in this. So, we know
19−one thing: wishing hasn't made it happen.
20−
21−## John Perry Barlow
22−
23−It's interesting to go back and read John Perry Barlow's 1996
24−manifesto, the [Cyberspace Declaration of
25−Independence](https://projects.eff.org/~barlow/Declaration-Final.html),
26−Some parts of the *Declaration* are dated. Many parts seem
27−fresh, even urgent.
28−
29−But in 2015, what stands out most about this document is its
30−incredible confidence that the Internet is inherently free, and
31−easily strong enough to announce and defend its own freedom,
32−against "Governments of the Industrial World, you weary giants of
33−flesh and steel."
34−
35−Well... hindsight is 20/20. But in hindsight, even in 1996
36−things were starting to head south. Usenet — the brain of the
37−Internet, when the Internet had a brain — was already
38−disintegrating under the barbarian invasions. And where is the
39−WELL these days? (John Perry Barlow is probably still on it.)
40−
41−While the Net has certainly scored a point or two against the
42−State, the State has scored a lot more points against the Net.
43−If the State wants your domain name, it takes it. If that's
44−independence, what does utter defeat and submission look like?
45−
46−Worse: whatever state tyranny exists, it's obviously dwarfed by
47−the private, free-market, *corporate* tyrannosaurs that stalk the
48−cloud today. We can see this clearly by imagining all these
49−thunder-lizards were *actually part of the government*. "Private"
50−and "public" are just labels, after all.
51−
52−Imagine a world in which LinkedIn, Facebook, Twitter, Apple and
53−the NSA were all in one big org chart. Is there anyone, of any
54−political stripe, who doesn't find this outcome creepy? It's
55−probably going to happen, in fact if not in form. While formal
56−nationalization is out of fashion, regulation easily achieves the
57−same result, while keeping the sacred words "private enteprise."
58−
59−Reading Barlow's _Declaration_ is a lot like reading the real
60−Declaration, in an alternate history where Jefferson lost. In
61−2015, do we still believe in these goals? Arguably, we believe
62−in them more than ever. We basically live in 1996's nightmare.
63−We know exactly what to be afraid of. It's already here.
64−
65−But we've lost the ability to believe we can *achieve* these
66−goals. 20 years ago, digital freedom seemed inevitable. Now it
67−seems impossible.
68−
69−## Engineering digital freedom
70−
71−Don't panic! This is a simple case of cause and effect. Digital
72−freedom isn't inevitable. It's also not impossible. It's quite
73−possible. It just requires *actual engineering work*.
74−
75−If you think a result is inevitable, but it's not, you won't do
76−the work and you won't get the result. So, let's do the work.
77−Dealing is way better than worrying. 1996 worried about the
78−problem; 2016 ought to deal with it.
79−
80−A constitution is not a declaration. It's not a list of ideals.
81−It's more like a bridge — an actual structure, that fails unless
82−it stands up to genuine load. A bridge isn't a bridge unless it
83−works. If you want a bridge, you have to build a bridge. It
84−doesn't typically happen that you set out to build something
85−else, but at the end it turns out you've built a bridge.
86−
87−The designers of the Internet did not, of course, intend to
88−implement any of John Perry Barlow's ideals. How close they came
89−is in a way remarkable. Perhaps it was possible for the
90−designers of the Internet to build a global, decentralized social
91−network. They weren't trying to, and they didn't.
92−
93−If we want a decentralized social network, we can't do it without
94−rigorous engineering work. And we can't limit our work to the
95−world of code. A decentralized network has to work not just
96−technically — but politically, economically, and socially.
97−
98−Where do we go from here? How do we get back to 1996? Admit
99−we've failed, and try again. How else?
100−
101−## Two axioms
102−
103−It's rarely worth arguing over an ugly truth. Either you know
104−it, or you can't be argued into it. Or it's not true. So it's
105−better to just give it as an axiom. Two axioms:
106−
107−One: the Internet can't be fixed. We *can't* redecentralize the
108−Internet. It has too many accumulated administrative and
109−technical misfeatures.
110−
111−Two: there is no practical, completely decentralized network.
112−Government is a human invariant, in the digital world as in the
113−real world. Even Bitcoin has a central government.
114−
115−We can't force you to accept these axioms. We'll just assume
116−they're true for the rest of this document. This means we're
117−designing a new, self-governing network on top of the Internet.
118−
119−## On digital republics
120−
121−The English word *republic* is from the Latin *res publica* -
122−"public thing." A republic is a government run as a public
123−trust, without any single point of failure - person or
124−institution.
125−
126−Every (real) democracy is a republic, but not every republic is a
127−democracy. The distribution of both formal and actual authority
128−within a republic need not be in any way uniform. (Arguably, it
129−never is.)
130−
131−The design goal of a republic is effective, durable and stable
132−governance. Humans and servers are inherently fallible.
133−Therefore this goal cannot be achieved without what humans call
134−*pluralism* and programmers *redundancy*. Or in other words,
135−decentralized governance.
136−
137−Both the old Internet of the '80s and the distributed social
138−network built on top of it - Usenet - were very much digital
139−republics. ICANN still thinks of itself as a republic, but to
140−some it looks more like a corporation. In previous decades,
141−influence over collective decisions was more about personal
142−reputation than corporate authority - the way IETF still works.
143−
144−A republic needs a constitution - a set of formal processes that
145−guides and shapes the real questions of governance, which are
146−always informal.
147−
148−The republic is in a healthy state if its actual power structures
149−match this constitution. The Soviet Union had a fine
150−constitution. Its actual authority structures had little to do
151−with its official structures.
152−
153−Again, the digital republic is a machine - if it's not
154−well-engineered, it won't work. There are three categories of
155−engineering we have to get right: political, economic, social.
156−
157−## Political engineering
158−
159−Our ideal network is actually not designed to *be* a digital
160−republic. It's designed to *become* a digital republic.
161−
162−The most basic principle of political engineering is that there
163−is no one true constitution; the constitution has to fit the
164−polity. And our polity cannot succeed without changing. And we
165−care what it ends up as, much more than how it gets there.
166−
167−### On young networks
168−
169−In a young, small network, digital freedom is irrelevant. There
170−is no structural conflict of interest between the government and
171−the users. Everyone in the network is a pioneer, and all
172−pioneers have the same goal: found the republic. Anyone who
173−stops believing in the network just leaves.
174−
175−The young network is a high-trust society in two ways: trust
176−between users, and trust in government. The main purpose
177−of decentralization is to prevent conflict among the distrusting.
178−Decentralization is superfluous in a high-trust society.
179−
180−A young network can't be decentralized *even if it wants to be*.
181−Consider the early days of Bitcoin. Somewhere between the
182−initial release and now, there's a point in time T such that
183−before but not after T, Satoshi himself could have rebooted the
184−blockchain.
185−
186−Not even with a 51% attack - but *just with an email*. He could
187−have said: I screwed something up, here's a new genesis block.
188−And everyone would have switched to the new blockchain, at the
189−mere verbal whim of Emperor Satoshi.
190−
191−When Bitcoin was young, it was a centralized network, even though
192−it had a decentralized constitution. In practice, Satoshi was
193−above the constitution. Even if he didn't use it, he had an
194−authority above cryptography.
195−
196−### Political engineering in Bitcoin
197−
198−There are two layers of sovereignty in Bitcoin. The highest
199−layer is the choice of blockchain itself - the rule that the
200−longest chain is best is completely informal. Or to put it
201−differently, it's the principle that makes Bitcoin Bitcoin and
202−everything else an altcoin. No math is involved here - just the
203−agreement of human beings. Or in other words, politics.
204−
205−Even the cryptographic layer rests on informal foundations.
206−The 51% attack on Bitcoin is well-known; any coalition that can
207−construct one is sovereign. But no such coup has happened, or
208−will - why?
209−
210−Because the coalition is plural. Since each coup supporter would
211−be acting against its own self-interest by damaging the
212−reputation of the currency as a whole, the coup requires
213−self-destructive folly from multiple serious actors. Suicidal
214−collusion is never a realistic risk - or if it is, nothing can
215−mitigate it.
216−
217−Even if one miner controlled 51%, their incentive against an
218−attack would be enormous, because they would destroy the
219−blockchain they captured. On the other hand, not everyone
220−responds sensibly to incentives. The purpose of a republican
221−constitution is to eliminate single points of incentive failure.
222−
223−Bitcoin is a stable, mature republic - but it is *not* secured
224−just by cryptography, but also by political engineering.
225−
226−### Political engineering in Reddit
227−
228−Compare to an unstable, mature non-republic: Reddit.
229−
230−2015's Reddit civil war is a dead ringer for one past conflict:
231−the English Civil War. As Marx and Pareto agree, all major civic
232−conflict arises when a new social class develops a collective
233−sense of its right to govern. The danger is most acute when a
234−governed class senses that the governors do not live up to the
235−standards of the governed.
236−
237−Much as the Puritans looked down on the Cavaliers as immoral,
238−atheistic fops, the Reddit moderators looked down on the Reddit
239−staff - or certain parts of it - as faceless corporate drones.
240−When you've attained real political status in a community,
241−through hard work and genuine talent, it's contemptible to let
242−yourself be governed by people without the basic skills to even
243−pass as competent, much less exceptional, in this community. As
244−Napoleon said: every regime is safe so long as it is ruled by its
245−most talented citizens. And if it's not, it isn't.
246−
247−But technically, Reddit couldn't just have a French Revolution.
248−Reddit is an inherently centralized site. It looks like a bunch
249−of different places, but that's an illusion. It's actually one
250−big mainframe. The Reddit staff is stuck running this mainframe.
251−The users have a lot of social capital invested in it.
252−
253−If there was a technical mechanism that let the users of Reddit,
254−collectively and coherently, fork Reddit and take ownership with
255−a Tennis Court Oath, they certainly would have done so long ago.
256−The result could only be a digital republic. But they can't, so
257−Reddit's future is unclear. Man may be born free, but mainframe
258−guest accounts certainly aren't born free.
259−
260−### From monarchy to republic
261−
262−In real-world history we see a curious pattern: not only are
263−republics fairly rare, but every successful republic (from Athens
264−to Rome to England) started out as a successful monarchy.
265−Perhaps this is also the right way to build a digital republic?
266−
267−Another way to state the political engineering problem that our
268−new network has to solve: maximize the chance of producing a
269−mature digital republic. There are two failure cases: failure,
270−and a mature non-republic. We should prefer the former - "range
271−safety," as a rocket scientist would say.
272−
273−Our conclusion is that a young network is a monarchy (whether
274−under a BDFL or a faceless corporation), whether it likes it or
275−not. But the network must be technically designed to *evolve*
276−into a mature republic.
277−
278−And - most critically - the republican evolution *cannot* be
279−prevented by the monarchical admins. When the evolution has to
280−happen, the monarchy has every incentive to help it succeed. If
281−it chooses to interfere instead, it will just get run over.
282−
283−Reddit couldn't have a revolution; its code wasn't designed for a
284−revolution. A new network can and should be designed for just
285−that. Revolution may not be the ideal way to give birth to a
286−republic, but it certainly works and it's better than nothing.
287−
288−Thus what seems like an optimal political design: the ugly,
289−centralized, young larva that's designed to molt into a
290−beautiful, mature, decentralized butterfly. And once mature, the
291−larva must molt or die — not keep growing into a gigantic,
292−man-eating caterpillar of death.
293−
294−## Economic engineering
295−
296−Economically, a new network should bootstrap. It should be
297−designed to generate revenue that funds its own development.
298−Ideally, its operators accept no traditional investment at all.
299−
300−A digital-token business is no novelty in the age of Bitcoin.
301−But a network address space is not at all the same thing as a
302−digital currency. When we look at current address spaces of
303−meaningful economic weight - DNS domains, IPv4 addresses, even
304−Twitter handles - we see not digital money, but digital *land*.
305−
306−### On digital land
307−
308−Digital land is very different from digital money. People mine
309−gold, but nobody mines land. Transactions in money are common,
310−fungible, and should involve minimal friction. Transactions in
311−land are rare, unique, and involve significant friction. And
312−most important, land has intrinsic utility; money does not.
313−
314−For example, Bitcoin needs a blockchain to solve the double spend
315−problem. A blockchain is very expensive. If we consider mining
316−dilution as a cost, a Bitcoin transaction costs multiple dollars.
317−That cost is exacted as a dilution tax on all holders (arguably,
318−correct accounting in BTC uses a "normalized BTC" unit which is
319−the fraction of all BTC outstanding), but it remains a cost.
320−
321−For certain values of "solved," the double spend problem is also
322−solved by a trusted escrow agent. For digital money, escrow is
323−not a workable general solution. For digital land, it may be.
324−Escrow is certainly orders of magnitude cheaper than a blockchain.
325−
326−Digital land in a decentralized system still needs to be owned
327−cryptographically, like Bitcoin. But as with real property,
328−it doesn't need to be mathematically impossible to steal digital
329−property. It just needs to be realistically impractical. If we
330−can ensure that those with the power to steal lack the motive,
331−and those with the motive lack the power, our design works.
332−
333−For digital land, a blockchain is an unnecessary expense. So
334−digital land has no mining. But from the Bitcoin purist's
335−perspective, any altcoin without mining is "100% premined" - ie,
336−probably a scam. Digital land is not digital currency, but it's
337−silly to argue over definitions.
338−
339−### A moral theory of digital land
340−
341−The libertarian philosophy of Murray Rothbard is the normative
342−belief system of Bitcoin. It's easy to explain digital land in
343−Rothbardian terms: ownership is on the homesteading principle.
344−
345−Property in land, as anything, is owned by those who create it -
346−which in real land means enclosing and cultivating it. Digital
347−land is just the same, but creation is a simpler process - and
348−it never involves conquest and/or genocide of previous owners.
349−All this is precisely according to Dr. Rothbard.
350−
351−Intuitively: if you didn't do any real work to create your
352−premined altcoin, it's a scam. If not, not. It's not necessary
353−to appeal to Rothbard to see why this makes sense.
354−
355−### Economic dynamics
356−
357−Any bootstrapping address space can define a metric which is the
358−fraction of namespace value recycled into development cost: the
359−erecycle rate*. In a sense, if the recycle rate is 100%, the
360−network does not leak economic energy.
361−
362−(In a scam, this non-leaked economic energy non-leaks into the
363−scammer's pocket. In a non-scam, it goes back into the engine.
364−It's expensive to settle any new America; if that America has
365−positive general utility, its value when settled should subsidize
366−the cost of settling it. Or at least, a design that doesn't work
367−this way is like Newcomen's steam engine, not Watt's.)
368−
369−One tradeoff against perfect recycling is the importance of
370−ownership decentralization. If you own an entire network because
371−you created it, you can increase the value of the whole address
372−space by giving blocks away. You may even increase the value of
373−your own position.
374−
375−A monopolized network is not politically healthy. So its
376−economic value is lower. So — if the network is properly
377−designed and structured — it can be stably demonopolized. The
378−monopoly power achieved by combining large positions is smaller
379−than the reputation cost of remonopolization, so centrifugal
380−force dominates and the system stays decentralized.
381−
382−Mining is one way to create initial demonopoly. But if it's not
383−actually necessary, mining has a recycle rate of zero. In a
384−blockchain network, mining is a necessary service and pays for
385−itself. In digital real estate, it would be a bad design.
386−
387−The objective of demonopolization isn't necessarily a *fair*
388−distribution of real estate. Fairness is nice - but from an
389−engineering perspective, to create the incentive structure of a
390−true republic, all that's needed is nontrivial decentralization.
391−Not much is needed to maintain the stabilizing incentives.
392−
393−## Regulatory engineering
394−
395−There's another kind of "political engineering." Our new network
396−is a sort of second-level political entity; but it exists within
397−a first-level entity, the real government.
398−
399−Minimizing bad interactions with the real government involves
400−three simple steps. First, don't look like you're breaking the
401−law. Second, don't break the law. Third, *really* don't break
402−the spirit of the law.
403−
404−Fortunately, digital land (such as DNS domains or IPv4 blocks)
405−already exists and is largely unregulated. Or rather, it's
406−regulated perfectly well by standard property law.
407−
408−This isn't just an accident of history. If DNS domains became a
409−useful way to launder money, or any kind of sink of financial
410−skulduggery, carders, pedobears, etc - the baleful eye of the
411−real government would rapidly fall on them.
412−
413−It's incumbent on anyone creating a new network of any kind not
414−just to avoid using it *yourself* for criminal purposes, but to
415−design it so that *it's not useful* for criminal purposes. A
416−darknet is not a machine for producing digital freedom. It's the
417−opposite - an excuse for installing digital tyranny.
418−
419−## Social engineering
420−
421−Bringing people together is an easy problem for any social
422−network. The hard problem is keeping them apart. In other
423−words, the hard problem is *filtering*. Society is filtering.
424−
425−A society without filters is a whirling, beige mess of atoms in a
426−blender. Beigeworld is an inhuman antisociety. A digital
427−republic is a garden; not only does a garden smell good, but
428−every flower smells good. An unfiltered network is a sewer. All
429−sewers have exactly the same smell.
430−
431−There are four orthogonal classes of filtering: topic, community,
432−flavor and quality. Filtering should be orthogonal to content
433−type: the topic filter "sci.physics" can be a chatroom, a
434−preprint archive and a streaming video channel.
435−
436−### Filtering: topic
437−
438−Users themselves want to keep themselves apart in structured
439−ways. Topic filtering is the most basic. Imagine a Reddit or a
440−Usenet with only one group. It would consist only of noise.
441−
442−For topic filtering, the ideal network has a single, organized
443−global topic tree (ontology). Call it half Usenet, half
444−Wikipedia and half the Dewey Decimal System.
445−
446−### Filtering: community
447−
448−Every topic deserves a community. But not every community is a
449−topic - a node in the ontology. To put it differently, not every
450−community should have a global name. The existence of small,
451−informal, private communities - tribes and microtribes - is
452−essential to a healthy network.
453−
454−The most inhuman form of community filtering is the form in which
455−"communities" are inferred algorithmically from an unstructured
456−social graph on a social server. A community is a tribe, not a
457−proximity cluster. Humans are a tribal species and have
458−exquisite instincts for interactions in medium-sized groups.
459−
460−### Filtering: flavor
461−
462−Flavor filtering is the only major filtering class that's poorly
463−developed in presently deployed systems.
464−
465−Suppose you're building an online grocery store. Suppose one
466−feature of your store is a profile setting where users can mark
467−that they're vegetarians.
468−
469−There is no use in asking vegetarians to shop for meat. At best,
470−you're trolling them; at worst, you're boring them. A cooking
471−site should not show them recipes for rack of lamb. Etc.
472−
473−More broadly, many forms of discourse have vibrant flavors which
474−other users are inherently uninterested in tasting. Like topics,
475−these flavors naturally form trees - some users may naturally
476−block all sexual content, others just a subset.
477−
478−But flavors are not topics. Topic can imply flavor - the bondage
479−board will have bondage-flavored content. Not all communities
480−are topical. Not all all topical communities stick to the point
481−in every single communication.
482−
483−A key component of flavor-oriented filtering is the principle
484−that flavor is marked by the content author, and enforced by
485−social convention in the community. A well-run community - and
486−not all communities will be well-run - enforces flavor marking
487−even among the locally dominant majority.
488−
489−Anyone reading this has been subject to speech codes, of one sort
490−or another, since they were old enough to talk. There's a reason
491−for this: blasphemy and/or heresy is disruptive and antisocial,
492−absolutely regardless of its actual intellectual merit.
493−
494−If we have a technical way to filter out blasphemy, we don't need
495−to suppress it with coercive force. Imagine a world in which,
496−not just in theory but also in practice, you could say anything
497−you wanted - so long as you marked it as what it was.
498−
499−### Filtering: quality
500−
501−All other filtering problems are unimportant next to quality.
502−Any successful digital republic must be in some sense a successor
503−of Usenet, whose defeat by the barbarians is a matter of history.
504−Alas, no one really knows how to do decentralized quality
505−filtering. (Even centralized filtering doesn't work well.)
506−
507−Fortunately, a young network is inherently high-quality.
508−Low-quality content is parasitic. It develops only as a network
509−matures. There's plenty of time to work on the outer walls while
510−the network boots up.
511−
512−And we can state one social-engineering goal which is not
513−*sufficient* for barbarian resistance, but perhaps almost
514−*necessary*. This is *expansion resistance*: the difficulty of
515−creating a new identity.
516−
517−If expansion resistance is zero, anyone can create infinite
518−numbers of identities; Sybil attacks become trivial. Expansion
519−resistance is negligible in email; spam filtering works, kind of;
520−it can save SMTP, it certainly couldn't *create* SMTP. Email has
521−a lot in common with 14th-century Constantinople.
522−
523−Metafilter (which anyone can join for $5) has solid expansion
524−resistance; it may not be perfect, but it's certainly spamless.
525−And the grand champion is certainly the '80s Arpanet, where where
526−creating an identity involved applying to a university or getting
527−a tech job - effectively, infinite expansion resistance.
528−
529−Imagine a genuinely abuse-free global, decentralized network,
530−where no one had ever heard of a firewall. Usenet was a fragile
531−flower that could only exist under this glass bell. We can't
532−go back to the Arpanet, but we have to understand why it worked.
533−
534−Broadly, disposable identities and sockpuppets are the enemy of
535−Internet civilization. The principle of one identity per person,
536−persona or corporation is an absolute principle of netiquette.
537−Genuine multiple personas exist - it's one thing to split your
538−own identity between person and persona, name and *nom de plume*
539−or *nom de drag* - but they're rare, and an easy exception.
540−
541−One of the most praised texts in 20th-century political science
542−is s James Scott's _Seeing Like A State_. Scott points out that
543−successful governments encourage social structures which are
544−structurally governable, like a forester planting rows of trees
545−in straight lines. People today have names like "Carter" because
546−medieval English barons made their peasants take surnames, just
547−so their tax databases would have valid primary keys.
548−
549−A naive libertarian might call this a bad thing. Simplicity is
550−not tyranny; simple government is good government, which is the
551−opposite of tyranny. The simpler its task, the less energy the
552−government must exert to achieve the same output. Anarchy and
553−tyranny are cousins; so are liberty and order.
554−
555−# Conclusion
556−
557−Goals and ideals are different things. An ideal is something you
558−want. A goal is an ideal, plus a realistic plan to get it.
559−Goals are more interesting than ideals, don't you think?
560−
561−Goals and features are also different things. What are the
562−features of a network that attempts to achieve these design
563−goals? In the next installment, we'll look at how our own
564−network — [Urbit](http://urbit.org) — measures up to these
565−yardsticks.
docs/theory/old.mddeleted−21
@@ -1,21 +0,0 @@
1−---
2−layout: video
3−sort: 3
4−title: demo.2013
5−---
6−
7−# demo.2013
8−
9−<iframe src="https://player.vimeo.com/video/75312418?color=fff&amp;title=0&amp;byline=0&amp;portrait=0" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
10−
11−## DVD commentary
12−
13−<div class='short'>
14−
15−#### CY
16−This is what Urbit looked like two years ago. Yes, we can still do all this stuff. But...
17−
18−Urbit in 2013 had the same Nock and pretty much the same Hoon, but Arvo was a prototype. For instance: you'll see a shell and a messenger in this video. The shell is built into the kernel, and so is the talk protocol. We've learned a lot about purely functional operating systems since then...
19−
20−</div>
21−
docs/theory/part-i.mddeleted−512
@@ -1,512 +0,0 @@
1−---
2−layout: video
3−sort: 1
4−title: demo.2015.a
5−---
6−
7−# demo.2015.a
8−
9−<iframe src="https://player.vimeo.com/video/131710210?color=fff&amp;title=0&amp;byline=0&amp;portrait=0" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>
10−
11−## DVD commentary
12−
13−<div class='short'>
14−
15−#### CY
16−Hi! This is Curtis Yarvin, writer and director. I also played `~tasfyn-partyv`. I'm here with Galen Wolfe-Pauly - dramaturge, producer, editor, `~firput-miplex`. Hi, Galen!
17−
18−#### GWP
19−Hi! We definitely didn't do this alone. Philip Monk (`~wictuc-folrex`), Anton Dyudin (`~sondel-forsut`) and Henry Ault all helped a lot. Not to mention everyone who has committed to the repo...
20−
21−#### CY
22−This is the urbit demo known officially as ~2015.6.26. Or informally, as "Russian Nock."
23−
24−In this commentary track, we'll step you through the film line by line and show you the awesome that is urbit. And of course we'll exchange snarky remarks about the shoot.
25−
26−Galen, why "Russian Nock?"
27−
28−#### GWP
29−(laughs). Well, nock is urbit's VM, of course. But it's from a movie, "Russian Ark," which was shot in one take.
30−
31−#### CY
32−Nontrivial for a 13-minute demo of alpha software.
33−
34−#### GWP
35−We actually gave up. We put in a screen clear.
36−
37−#### CY
38−One. At the act break.
39−
40−Also, truth in advertising! urbit is alpha and still pretty slow. A lot of the footage is sped up. But almost nothing is actually *faked*.
41−
42−And we never used the reload button. Everything that looks reactive is.
43−
44−#### GWP
45−It looks like the input lines are pasted in, but we actually typed them. Then I took the footage and
46−
47−#### CY
48−And edited the keystrokes together. One cut per line. Yes, this workflow was my brilliant idea, thank you.
49−
50−#### GWP
51−Next time, actual tools!
52−
53−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/01.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/01.png)
54−
55−##### 00.03
56−
57−#### CY
58−I'm in my urbit, `~tasfyn-partyv`. This is of course a VM running on my laptop.
59−
60−I have an urbit ticket for another planet, `~firput-miplex`. I want to send it to my friend Aldo van Eyck.
61−
62−#### GWP
63−Actually, he's a '50s Dutch architect from Team 10. Maybe we'll start getting email for him!
64−
65−#### CY
66−From my `:dojo` agent, basically the urbit shell, I'm going to run the `|invite` command, which tells `~tasfyn-partyv` to email Aldo the secret he needs to create `~firput-miplex`.
67−
68−Via an HTTP API to a mail delivery service, of course. But - the invite is actually the one fake thing in this video.
69−
70−#### GWP
71−The Mailgun API connector wasn't quite together yet.
72−
73−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/02.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/02.png)
74−
75−##### 00.07
76−
77−#### CY
78−Via `:talk`, I get a success message from `|invite` - the 55th message `~tasfyn-partyv` got in its lifetime.
79−
80−#### GWP
81−Obviously this isn't the real `~tasfyn-partyv`, we're on
82−
83−#### CY
84−A test network. Because we're still alpha.
85−
86−Then I typed `^X` to switch from `:dojo` to `:talk`.
87−
88−#### GWP
89−These two applications are sharing your command line.
90−
91−#### CY
92−You multiplex the command line with ^X. It's like switching windows. But everyone's output
93−
94−#### GWP
95−Gets mixed together and scrolls up.
96−
97−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/03.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/03.png)
98−
99−##### 00.14
100−
101−#### CY
102−In `:talk`, I set my target base to `~firput-miplex`.
103−
104−Then send you a `@` message, like irc /me.
105−
106−#### GWP
107−Bear in mind, `~firput-miplex` doesn't *exist* yet.
108−
109−#### CY
110−That's right. Suppose you sent someone email, but to an account they haven't created, on a server whose domain isn't registered.
111−
112−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/04.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/04.png)
113−
114−##### 00.17
115−
116−#### CY
117−Obviously I stole this great error message from NFS.
118−
119−#### GWP
120−Obviously.
121−
122−#### CY
123−In urbit your name, or *base*, is your network address.
124−
125−We're sending `~firput-miplex` packets but not hearing back.
126−
127−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/05-a.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/05-a.png)
128−
129−##### 00.22
130−
131−#### GWP
132−Aldo gets the email with his urbit ticket. He can't resist.
133−
134−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/05.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/05.png)
135−
136−##### 00.37
137−
138−#### GWP
139−He builds urbit on his macbook and runs it.
140−
141−#### CY
142−He probably should get that secret out of his bash history.
143−
144−#### GWP
145−That's what Sergey Aleynikov said to himself!
146−
147−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/06.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/06.png)
148−
149−##### 00.43
150−
151−#### CY
152−Ignore the boot messages behind the curtain. But look -
153−
154−#### GWP
155−I got your message. Definitely not how email works.
156−
157−#### CY
158−It's the way urbit networking works. The transport layer has no concept of connectivity state. it just waits.
159−
160−#### GWP
161−Nobody who watches our film notices this. Nobody.
162−
163−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/07.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/07.png)
164−
165−##### 00.45
166−
167−#### CY
168−"Is your neighbor" means you've exchanged keys, basically.
169−
170−#### GWP
171−Why do we see it twice?
172−
173−#### CY
174−I have no idea.
175−
176−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/08.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/08.png)
177−
178−##### 01.26
179−
180−#### GWP
181−I go to your `tasfyn-partyv.urbit.org` url. But there's nothing there. Error page. What?
182−
183−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/09.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/09.png)
184−
185−##### 01.48
186−
187−#### CY
188−I use a shell terminal to create the markdown file, edit it in vim, save it, and -
189−
190−#### GWP
191−And my browser immediately loads it as a web page.
192−
193−#### CY
194−Your error page is long-polling my server, which tracks dependencies for every page, good or bad.
195−
196−When I saved the markdown file, my urbit was watching the unix directory and committed my save as a change. That change event goes to the filesystem, `%clay`.
197−
198−`%clay` applies it and sees that the build system, `%ford`, is watching this subtree. `%ford` gets the notification and reports a dependency change to the web server `%eyre`, which returns 200 on the long-poll.
199−
200−Your browser then requests the new version of this url. `%eyre` forwards the request to `%ford`, which figures out that it can build an appropriate response by converting the markdown file to an HTML tree, then injecting the reload script, then printing the HTML.
201−
202−#### GWP
203−This isn't even a dev tool. It works in production.
204−
205−#### CY
206−Not that it scales! But it works fine behind an nginx cache.
207−
208−#### GWP
209−If we edit this commentary transcript right now, it'll change on the reader's screen.
210−
211−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/10.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/10.png)
212−
213−##### 02.14
214−
215−#### CY
216−Here I go and edit the same file again, and we see your refresh script do its work. Ho hum, boring already.
217−
218−#### GWP
219−Imagine living in a world where everyone assumed it should just work this way - why wouldn't the browser update? Why would you not track dependencies on the page build?
220−
221−#### CY
222−Of course it's not just the page content we're tracking. If I changed the markdown parser, you'd reload again. It's everything local and time-versioned used in the build.
223−
224−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/11.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/11.png)
225−
226−##### 02.34
227−
228−#### CY
229−Here I send you the magic long-form url that lets you specify version numbers directly. So you can see the old version of the poem.
230−
231−#### CY
232−There are two schools of web server url handling. There's the open-minded school that let you parse a path your own way, and the closed-minded school that hardcodes its own semantics into the url. urbit's -
233−
234−#### GWP
235−urbit's is the closed-minded school.
236−
237−#### CY
238−Exactly. Your url goes mostly undigested to the `%ford` build system. If these aren't the urls you want the user to see, wrap it in an nginx rewrite rule.
239−
240−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/12.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/12.png)
241−
242−##### 02.49
243−
244−#### CY
245−Now the same thing but one directory up.
246−
247−#### GWP
248−Or `++arch` as we say in urbit.
249−
250−#### CY
251−Imagine a unix inode, except if every inode was a directory plus an optional file. But also, if unix was git.
252−
253−#### GWP
254−Or `%clay` as we say in urbit.
255−
256−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/13.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/13.png)
257−
258−##### 02.53
259−
260−#### GWP
261−And the arch autoupdates too. Okay, we get it!
262−
263−#### CY
264−What's really going on here is that the whole subtree of urls under `/home/tree` is being rendered by one `tree.hoon` file, which defines a function that maps the url suffix to an HTML document.
265−
266−This `tree` function is pretty simple - it just uses the url suffix, `/pub/verse/bunting`, as a path in the filesystem `%clay`.
267−
268−Since there's no file on that arch, we just show the list of children. Just like Apache `public_html`.
269−
270−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/14.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/14.png)
271−
272−##### 03.15
273−
274−#### CY
275−Here we're in the root of the urbit doc tree.
276−
277−#### GWP
278−Don't look too hard at the fine print!
279−
280−#### CY
281−Knuth was wrong about the root of all evil. It's actually premature documentation.
282−
283−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/15.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/15.png)
284−
285−##### 03.36
286−
287−#### GWP
288−Definitely don't throw away your Wordpress just yet.
289−
290−#### CY
291−Galen wrote and designed this tree renderer. It's actually not bad for the amount of work he put in.
292−
293−#### GWP
294−Well, me and Anton mostly. It's a good start.
295−
296−#### CY
297−We should have demoed the navigation controls at the top, which let you move up or to the next sibling. There's no excuse for tree-structured content without uniform tree navigation affordances.
298−
299−#### GWP
300−Jakob Nielsen is shaking his head somewhere.
301−
302−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/16.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/16.png)
303−
304−##### 03.47
305−
306−#### CY
307−Note that you're now surfing `firput-miplex.urbit.org`. That's your own urbit, of course.
308−
309−You're using an application, not just a functional renderer. So you need to log in with an identity. The default is you. And your password is that secret you got in the email - your ticket.
310−
311−#### GWP
312−We're not demoing single sign-on here, but we do it.
313−
314−#### CY
315−If I logged into `~firput-miplex` as `~tasfyn-partyv`, it would redirect me to `tasfyn-partyv.urbit.org` with a challenge. If I was already logged into my own urbit, logging in to yours would be automatic.
316−
317−We set a cleartext `*.urbit.org` cookie with your urbit base, so within `urbit.org` login is generally automatic.
318−
319−#### GWP
320−Obviously this login system is application-independent. It's a part of urbit, not a part of `:talk.`
321−
322−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/17.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/17.png)
323−
324−##### 03.49
325−
326−#### CY
327−Isn't that pretty?
328−
329−#### GWP
330−Ugh. Alpha is the name of the game around here. It's a start.
331−
332−#### CY
333−Galen went to art school or something. He has high standards.
334−
335−Notice of course that we see the same message backlog in the web ui and the console. Obviously it's the same app.
336−
337−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/17-a.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/17-a.png)
338−
339−##### 04.15
340−
341−#### GWP
342−Nice little recovery there. Of course, in "Russian Ark"
343−
344−#### CY
345−They'd have reshot the whole movie. They had standards.
346−
347−Anyway, `:talk` is really our flagship app. It weighs in at almost 2000 lines of code counting the protocols. It's a genuine distributed system and it's being used right now.
348−
349−To make a long story short, `:talk` is basically Usenet slumming as a chat server. Well, it could use a few more bells and whistles. But the bones of NNTP are there. A chat line is just one type of message...
350−
351−#### GWP
352−Next on our agenda, animated cat gifs.
353−
354−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/18.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/18.png)
355−
356−##### 04.20
357−
358−#### CY
359−We actually do support more than four urbits in a chatroom.
360−
361−#### AD
362−If there's no clock skew.
363−
364−#### GWP
365−The clock skew bug! That had to happen when we were filming.
366−
367−#### CY
368−NTP works, except when it doesn't. Fortunately Philip was up to the challenge.
369−
370−#### PM
371−The bug was in my code. On the other hand, you put it there.
372−
373−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/19.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/19.png)
374−
375−##### 04.34
376−
377−#### GWP
378−This whole bitcoin sequence is a rendering disaster. On console and browser alike.
379−
380−#### CY
381−Also it makes no sense. Who types in their bitcoin address? More thinking, comrade, will have to go into this exercise.
382−
383−#### GWP
384−Who else has a language with syntax for a bitcoin address?
385−
386−#### CY
387−We need a syntax for bitcoin amounts, too. That argument is a string. Lame.
388−
389−#### GWP
390−At least the example isn't faked. Well, unless you count using the coinbase sandbox as "fake."
391−
392−#### CY
393−Arguably an exchange API is a silly way to send a payment. We should run a bitcoin core daemon with an urbit gateway.
394−
395−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/20.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/20.png)
396−
397−##### 04.55
398−
399−#### CY
400−Yes, we actually tweeted to the real twitters here.
401−
402−#### GWP
403−Maybe there should be a twitter sandbox.
404−
405−#### CY
406−I know a lot of people who could use a twitter sandbox!
407−
408−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/21.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/21.png)
409−
410−##### 05.14
411−
412−#### CY
413−Here I start lecturing you a bunch. Anyway, this argument is a little cryptic. Of course an evil or compromised host can look at any of your data on the service, barring some kind of breakthrough in efficient homomorphic encryption. And this is true whether you're a VM or a database row. The Linode hack, for instance, was an attack on cloud VMs.
414−
415−But it still makes a lot more sense to keep valuable secrets in a cloud-hosted VM than a cloud-hosted application database - because there are all sorts of ways that database can be queried. Nobody queries a VM.
416−
417−When the line between hosting provider and hosted computer is drawn at the edge of the VM, it's a very precise line. It would be outrageous if amazon was peeking into AWS VMs, stealing their data and using it to sell more ads. So logically you're not safer, but in practice you are.
418−
419−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/22.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/22.png)
420−
421−##### 05.33
422−
423−#### CY
424−Of course it looks better if you unlimit coredumpsize. So you actually, uh, dump core. Like the script says.
425−
426−#### GWP
427−Curtis went to unix school or something.
428−
429−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/23.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/23.png)
430−
431−##### 05.41
432−
433−#### CY
434−Too many printfs! But you see that there's only one level of storage in urbit. At least logically, all data persists.
435−
436−#### GWP
437−My iPhone pretends to work this way. But I'm not sure it does.
438−
439−#### CY
440−Practically, the way we create this abstraction is the way all databases work: a checkpoint and a log. Logging is easy - there are all kinds of great cloud tools for it.
441−
442−If you look at the printfs, you have a checkpoint at event 9616. but the log goes up to 9624. You load this checkpoint, then rerun the last 8 events.
443−
444−The only rule is that you can't execute the actions caused by an event until you've logged the event. For example, if an incoming packet causes an outgoing packet, you can't send the outgoing packet until you've logged the incoming.
445−
446−#### GWP
447−So every event is a transaction. Watch out, Oracle!
448−
449−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/24.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/24.png)
450−
451−##### 05.52
452−
453−#### GWP
454−I'm not sure we can get away with this "NoDB" meme. Didn't you just say urbit *is* a database?
455−
456−#### CY
457−A foolish consistency is the hobgoblin of little minds.
458−
459−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/25.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/25.png)
460−
461−##### 06.41
462−
463−#### CY
464−A lot of this demo is sped up. But that part is *really* sped up. Anyway, in case it's not obvious what you did,
465−
466−#### GWP
467−I deleted my checkpoint, than restarted from just the log.
468−
469−#### CY
470−And arrived at exactly the same bit-for-bit state.
471−
472−#### GWP
473−You know, cosmic rays could cause big problems with urbit.
474−
475−#### CY
476−I'm aware of that. It's a real issue with any kind of repeatable computing. You depend on perfect execution. Certainly, ECC memory is a must.
477−
478−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/26.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/26.png)
479−
480−##### 06.54
481−
482−#### GWP
483−And... here we see a massive demo fail.
484−
485−#### CY
486−Oh, hardly. First, the nock spec was somehow not in `%clay`. So we had to add it back in from another window. Second, you said `+cat` in `:talk`, so you `:talk`ed the cat command rather than `:dojo`ing it.
487−
488−And third, your browser hung up and reconnected. Just typical printf noise from alpha code.
489−
490−#### GWP
491−I wonder if anyone actually noticed that.
492−
493−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/27.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/i/27.png)
494−
495−##### 06.56
496−
497−#### GWP
498−And... there's nock. How did you come up with that, anyway, Curtis?
499−
500−#### CY
501−Gosh, I barely even remember. I started with something much bigger and kept pulling things out. I guess.
502−
503−#### GWP
504−Sort of the Kevin Herbert strategy?
505−
506−#### CY
507−(laughs.) Kids, definitely don't try this at home.
508−
509−#### GWP
510−Thanks for watching our film! Or the first half, anyway...
511−
512−</div>
docs/theory/part-ii.mddeleted−462
@@ -1,462 +0,0 @@
1−---
2−layout: video
3−sort: 2
4−title: demo.2015.b
5−---
6−
7−# demo.2015.b
8−
9−<iframe src="https://player.vimeo.com/video/131715710?color=fff&amp;title=0&amp;byline=0&amp;portrait=0" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
10−
11−## DVD commentary
12−
13−<div class='short'>
14−
15−#### CY
16−Hi, DVD viewers! Once again, it's Curtis Yarvin and Galen Wolfe-Pauly with the second half of "Russian Nock."
17−
18−#### GWP
19−Would you like to play a game of global thermonuclear war?
20−
21−#### CY
22−Not today! But I'm always up for tictactoe.
23−
24−In this section of our epic major motion picture, we build a simple Urbit appliance: tictactoe. The point of the exercise is just that it's easy to build distributed social applications in Hoon and Arvo, our language and OS. At least, it's easy once you know Hoon.
25−
26−#### GWP
27−Hoon is actually much easier to learn than it looks. But why, Curtis, is it easy to build social distributed apps in Urbit?
28−
29−#### CY
30−Because Urbit solves all the hard problems for you. Identity, of course. But also idempotence, transactionality, protocol definition and validation, publish/subscribe...
31−
32−#### GWP
33−Urbit certainly sounds like something that would work for idempotence.
34−
35−#### CY
36−It does! Urbit. It's what plants crave.
37−
38−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/01.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/01.png)
39−
40−##### 00.56
41−
42−#### CY
43−So we cleared the screen, which means we got to annihilate the universe.
44−
45−#### GWP
46−We shot this second chapter in a new test universe.
47−
48−#### CY
49−That's why we become neighbors again. We just made these urbits.
50−
51−#### GWP
52−I hated the text on screen at the end of the last take. Very marketing.
53−
54−#### CY
55−But it does include the instructions for what you just did.
56−
57−First, you synced my `%demo` desk - desk is Urbitese for "branch" - into your `%demo` desk. That both copies over the current `%demo` state, and subscribes to any future changes.
58−
59−Second, you started the `%taco` app from your `%demo` desk.
60−
61−#### GWP
62−But it didn't work.
63−
64−#### CY
65−Neither of us has a `%demo` desk. And I haven't written `%taco` yet. But (spoiler) it will work.
66−
67−Here's why "it doesn't matter what order you do things in" (for certain values of "order" and "thing"). In a distributed system, state changes whenever possible should be knowledge events. If you learn A and B, it matters not whether you learn A before B or B before A: what you know is AB. Any data model that works this way is inherently a CRDT. If you know what that is.
68−
69−#### GWP
70−I don't.
71−
72−#### CY
73−A conflict-free replicated data type. It's what plants crave.
74−
75−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/02.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/02.png)
76−
77−##### 01.01
78−
79−#### CY
80−In `%clay`, Urbit's revision-control system, your working tree is actually a desk (again, Urbitese for "branch").
81−
82−From Urbit you can mount synced Unix directories that work like Dropbox. Urbit monitors your directory tree with `inotify()`, catches any changes, and commits them as Urbit events. So you don't need some new Urbit editor to develop for Urbit. You can keep using the best editor in the world, which is obviously vim.
83−
84−#### GWP
85−Or Emacs. We also have an Emacs mode for Hoon. Is that what it's called? A mode?
86−
87−#### CY
88−Is it? I wouldn't know. Anyway, you definitely want syntax highlighting in Hoon, though I eschew it to keep my hand strong.
89−
90−#### GWP
91−Thank you for that, Curtis.
92−
93−#### CY
94−Anyway, to make changes in `%demo`, the general practice is to make a `%demo-work` desk whose history is an unstructured series of edits. Your merges from `%demo-work` to `%demo` are the equivalent of git commits.
95−
96−(Note that we don't explicitly mount Urbit folders to Unix directories here. Not that we don't need to, just that we shot this with an older version of Urbit that automounted.)
97−
98−#### GWP
99−What's the equivalent of a commit message?
100−
101−#### CY
102−As part of your merge change, prepend a line to a commit log on the target. Why should the log be a built-in feature of the filesystem? That's so git.
103−
104−#### GWP
105−Does the `|merge` command actually do that?
106−
107−#### CY
108−No, but it should!
109−
110−Speaking of commands, we did a `|merge` here and a `|sync` before. Again, `|sync` sets up a flow, `|merge` is a one-time copy. So future updates of my `%demo` won't flow into `%demo-work`, but they will flow into *your* `%demo`. Because I merged and you synced.
111−
112−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/03.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/03.png)
113−
114−##### 01.11
115−
116−#### CY
117−It looks like I'm quitting Urbit and going into an editor. I'm actually just switching windows. I could quit Urbit, of course -- it's a database, after all. But I don't have to.
118−
119−#### GWP
120−I think that's just bad direction.
121−
122−#### CY
123−It's actually bad editing. Anyway, here we build the basic state model of a simple tictactoe app. This is a structure file, so it goes in `/~tasfyn-partyv/demo-work=/sur/taco/hoon` (in Urbit) and `demo-work/sur/taco.hoon` (in Unix).
124−
125−I honestly think anyone could stare at this file for a couple of minutes and realize what it's doing. The state of a tictactoe game is: the board, and whose turn it is. The turn `who` is a boolean. The board we store in two bitmaps, `box` for X and `boo` for O. Hoon is very good at bit fiddling and its arrays are just lists, so our boards are just atoms (unsigned integers).
126−
127−#### GWP
128−I still think `,[x=@ y=@]` is a really ugly syntax.
129−
130−#### CY
131−I think you're right.
132−
133−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/04.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/04.png)
134−
135−##### 01.23
136−
137−#### CY
138−Then we type in `/===/lib/taco/hoon`. This is the "business logic" of tictactoe. I feel it compares well to the same problem solved in other languages.
139−
140−I won't go into super deep detail about this code, but you see a couple of cores `++bo` (for board bitmaps) and `++go` (for the `++play` structure we just defined). If Hoon had C++ classes, these would be classes. You can see the getters and setters getting and setting. There's also a nice nested core within `++go`, `++at`. Hard to find anything quite like a nested core in normal Earth languages.
141−
142−I actually typed in these files, by the way. By hand. Isn't that lame? I think there are a couple of errors. Of course, to not break the take, I switched to a different window and copied them in by hand.
143−
144−#### GWP
145−Then I created the illusion of superhuman flowing code. In the editing room. Have I told you how many edits that took?
146−
147−#### CY
148−At least once. Anyway, I want to emphasize something else, which is that although (as someone who reads Hoon) this is perfectly readable Hoon, it's not quite what real code looks like. The formatting in particular has been pretty seriously golfed. This looks like good Hoon to me, but it's insanely overgroomed like a French poodle. You'd never do this much formatting work if it wasn't a demo.
149−
150−#### GWP
151−Honestly, I think normal Hoon looks better.
152−
153−#### CY
154−Honestly, it's all about the line count.
155−
156−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/05.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/05.png)
157−
158−##### 01.41
159−
160−#### CY
161−Then it takes us 82 lines of code to create the actual application core. This seems like a lot. Actually, there's a lot of code here that other multi-console apps could duplicate, so maybe there should be a library.
162−
163−This version of `%taco` is a multiplayer game, of course, but kind of a trivial one. It doesn't have its own network protocol. Imagine if you were writing a Unix tictactoe server, and it just worked by running the telnet protocol and letting clients telnet into it.
164−
165−The Urbit equivalent of the telnet protocol is the `%sole` system, which the console driver (the `%hood` appliance) uses to talk to command-line appliances foreign and domestic. `%sole-action` messages get poked forward; `%sole-effect` messages come back in a subscription.
166−
167−`%sole` is actually quite a fancy command-line model. It treats the input line as multi-writer shared state and manages edits with OT. So the app can reject invalid input as it's being typed, do tab completion, etc.
168−
169−#### GWP
170−Overtime?
171−
172−#### CY
173−Operational transformation. It has electrolytes. Anyway, what the code in this file is doing: parsing the command line (Hoon has pretty good combinator parsers), applying updates, detecting changes, updating subscribers.
174−
175−Tictactoe is a two-player game, of course, but any number of people could log into `%taco`. One player is the server; everyone else can play the other side.
176−
177−#### GWP
178−But are the parsers monadic? Does Hoon have monads?
179−
180−#### CY
181−Shh! We try not to use that word. If it helps you to think in category theory, great. Category theory is a theory of everything, including Hoon. For most people it's easier to just learn Hoon.
182−
183−#### GWP
184−Sometimes I wonder if it's just that you're not smart enough to learn category theory, Curtis.
185−
186−#### CY
187−(in Maryland accent) I'm just a country boy but I'm sure I could figure it out real good if I had the need.
188−
189−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/06.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/06.png)
190−
191−##### 02.03
192−
193−#### CY
194−So what happened here is that when I merged my `%demo-work` desk into my `%demo` desk, your `%demo` desk was synced to it and got a subscription update. Then, your urbit was already configured to be running the `%taco` appliance from your `%demo` desk. So when it noticed that the source code existed, your urbit started the app with its default state.
195−
196−#### GWP
197−Why am I not responding, still trying?
198−
199−#### CY
200−That's the old network layer. There's still a bunch of 2013 code in there.
201−
202−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/07.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/07.png)
203−
204−##### 02.14
205−
206−#### CY
207−Here I telnet into your `%taco` appliance. Or more like ssh, because it's secure.
208−
209−#### GWP
210−Secure? Really?
211−
212−#### CY
213−Well, it's encrypted. That means it's probably secure. It's certainly *designed* to be secure.
214−
215−#### GWP
216−I'm sure the NSA is very worried.
217−
218−#### 02.43
219−
220−#### CY
221−Now this is a total party trick. Instead of editing through `%demo-work` like a responsible developer, I edit `%demo` directly. When I save the file, without any other command, the effect cascades all the way through and hot-reloads your `%taco` on your urbit, changing the 'X' icon to 'Z' and back again.
222−
223−Moreover, if you notice, I'm not even editing the `%taco` app core. I'm editing a library it depends on. Because dependencies.
224−
225−#### GWP
226−Would it be a good idea to do this in production? Also, what happens if you make a change that doesn't compile?
227−
228−#### CY
229−No. If only because it leaves a gnarly edit history. Also -- we'll see that in a little bit.
230−
231−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/08.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/08.png)
232−
233−##### 03.08
234−
235−#### GWP
236−Marketing copy in a demo really isn't appropriate.
237−
238−#### CY
239−I know. It is kind of true, though.
240−
241−
242−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/09.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/09.png)
243−
244−##### 03.11
245−
246−#### CY
247−Because I made those edits directly in `%demo`, I need to merge back into `%demo-work`. Or...
248−
249−#### GWP
250−Can't the filesystem handle a trivial three-way merge like that?
251−
252−#### CY
253−I think so!
254−
255−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/10.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/10.png)
256−
257−##### 03.19
258−
259−#### CY
260−For the new version our game state gets more sophisticated. (I don't know why I said "protocol.") Now it knows the players and the audience.
261−
262−Of course we need to be able to upgrade without losing our state. So we'll have to write an adapter. Which is pretty easy, because we just added a couple fields.
263−
264−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/11.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/11.png)
265−
266−##### 03.28
267−
268−#### CY
269−Now we need to be able to print the new information for the prompt. Some of this code is getting pretty golfy -- I really can't endorse the style of `++vew`.
270−
271−Also, you probably missed it above, but we added a board-to-JSON translator in `++bo`. We can turn a Hoon bitfield into a JSON array in one line of code. It's not even a golfy line.
272−
273−#### GWP
274−`a/(turn (gulf 0 9) |=(@ b/(bit +<)))`. Now that's not printing the JSON, just making the noun that we'll print.
275−
276−#### CY
277−I assert that anyone who can learn JS can learn Hoon. On the other hand, I don't know JS.
278−
279−#### GWP
280−Just don't use the word "monkey" in the same sentence as "front-end," and we'll be fine.
281−
282−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/12.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/12.png)
283−
284−##### 03.35
285−
286−#### CY
287−This is an actual protocol structure - a "mark." It's like a MIME type, except it's actually a type.
288−
289−`%taco-move` is just a coordinate `point`, a pair of integers (defined in `sur/taco.hoon`).
290−
291−#### GWP
292−It's actually really nice to have your network messages auto-validated and stuff.
293−
294−#### CY
295−Also auto-translated -- as you see, there's an arm for turning `%json` into `%taco-move`.
296−
297−#### GWP
298−That's convenient for making moves from a browser client, obviously.
299−
300−#### CY
301−Not that the app knows it's dealing with a browser. It thinks the browser is another urbit. The HTTP server translates automagically.
302−
303−#### GWP
304−Because the mark has that translator arm. Good times!
305−
306−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/13.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/13.png)
307−
308−##### 03.43
309−
310−#### CY
311−Another mark: moves go forward, updates go backward. So we have to translate `%taco-update` (the whole game state) into `%json`.
312−
313−#### GWP
314−Again we're just building a JSON-shaped noun. The web server, `%eyre`, will actually print as text.
315−
316−#### CY
317−Because that's a great thing to send over the network. Text.
318−
319−#### GWP
320−We should eventually have a socket driver that doesn't do this. Right now it's all long-poll / Comet.
321−
322−#### CY
323−Please don't say "socket" when you mean "websocket." It reminds me of how old I am.
324−
325−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/14.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/14.png)
326−
327−##### 03.51
328−
329−#### CY
330−Is this a special template language? No, it's actually Hoon. It has custom syntax for building XML-shaped nouns. So we don't need a template language.
331−
332−#### GWP
333−You're so old, you still believe in XHTML.
334−
335−#### CY
336−HTML5 was a terrible blow. But at least I'm not so old, I believe in SGML.
337−
338−#### GWP
339−Obviously this "HTML" file is just a shell for a JS app. As you see, it loads jQuery from a CDN and a bunch of resources from its own urbit. Including my own `urb.js`.
340−
341−#### CY
342−Front-end frameworks are important. We're all quadrumana at heart.
343−
344−#### GWP
345−I'll ignore that remark. In any case, an `urb.js` client application POSTs commands to the server and gets back a stream of state diffs (Comet, basically). I used jQuery here but this design works very well with React.
346−
347−#### CY
348−It's also exactly the way an urbit client works, so the server doesn't have to know it's talking over JSON to a browser. Basically the web app doesn't even know it's a web app.
349−
350−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/15.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/15.png)
351−
352−##### 04.02
353−
354−#### GWP
355−Sometimes a client is just a client.
356−
357−#### CY
358−I don't think there's any need to code-golf our JS. Any front-end --
359−
360−#### GWP
361−Any front-end *engineer* will have no problem programming for `urb.js`.
362−
363−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/16.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/16.png)
364−
365−##### 04.07
366−
367−#### CY
368−If I edit this CSS, will the browser get a change event and reload it?
369−
370−#### GWP
371−If the JS page is written right, I think so. We normally listen to the page source and its dependencies and refresh on any change. More long-polling.
372−
373−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/17.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/17.png)
374−
375−##### 04.25
376−
377−#### CY
378−We really screwed up the shoot here. We were going to do a retake.
379−
380−I did two things wrong: I merged in the wrong direction (nothing the system can't handle). And I upgraded every `%taco` file *except the app itself*.
381−
382−#### GWP
383−But then we thought: why not show how resilient the system is? Also it was getting pretty late.
384−
385−#### CY
386−So this is what happens when you get an update and it doesn't compile. It's what should happen. You see an error message and nothing else happens. Your app is fine.
387−
388−#### GWP
389−As easy as that!
390−
391−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/18.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/18.png)
392−
393−##### 04.34
394−
395−#### CY
396−This sequence moves a little fast. But as you see, we're not changing much about the application file proper when we give it its own network protocol and make it a web app.
397−
398−After all, translating generic console effects into application state changes is a fairly interesting problem. From our own protocol, no parsing is needed. Likewise, the web app is just pushing raw commands and subscribing to state changes.
399−
400−Now, this version of tictactoe is still really a client-server system, not peer-to-peer. Asymmetric, not symmetric. But the complexity of distributed state coupling isn't much different.
401−
402−#### GWP
403−Now, you sound like you work for Oracle. Or maybe the Defense Department. Whatever, does the game actually work?
404−
405−#### CY
406−It works for the take we recorded!
407−
408−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/19.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/19.png)
409−
410−##### 04.40
411−
412−#### CY
413−I think I had to kick it with an event to get it to change the prompt after the reload. That's supposed to be automatic.
414−
415−Note that the reason *my* prompt changes is that the new app file, on my urbit, has propagated to your urbit and reloaded the app, which then has streamed the new prompts to all subscribing clients, including both my urbit and yours.
416−
417−Of course, our state adapter worked and our game hasn't been interrupted.
418−
419−#### GWP
420−Is this schema evolution? Is it typed? Is it ACID? How long can application state live this way?
421−
422−#### CY
423−Yes, yes, yes, and as long as it wants. Generally you do want to export core data to the filesystem so that other apps can see it. The filesystem is not just revision-controlled but also typed, so this isn't too awful.
424−
425−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/20.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/20.png)
426−
427−##### 04.57
428−
429−#### GWP
430−So you're playing against me on my own urbit. You're talking to my `:taco` appliance from your urbit (which also is upstream of my installation), through the console protocol. I'm logged into the same appliance as a web client, authenticated as myself.
431−
432−#### CY
433−Pretty much. Also, this is a really nice-looking tictatoe board and it's a shame our game is so short. We even grey out the board when it's not your turn.
434−
435−Note that the client UI even has a presence widget. This isn't just tictactoe. It's *social* tictactoe.
436−
437−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/21.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/21.png)
438−
439−##### 05.19
440−
441−#### CY
442−Did you have to just win like that?
443−
444−#### GWP
445−I think I panicked. Does it have to clear the board that fast? Shouldn't it show my move?
446−
447−#### CY
448−It's true. This isn't the world's most polished tictactoe app. On the other hand, we do have an operating system to finish.
449−
450−[![](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/22.png)](https://storage.googleapis.com/urbit-extra/preview-1/screenshots/ii/22.png)
451−
452−##### 05.22
453−
454−#### GWP
455−We should have credits here.
456−
457−#### CY
458−We should! But since we don't, I'd like to thank Joan Torres for this awesome soundtrack, which he put together on like two days' notice. In regular life Joan is actually a world-class jazz bassist. He also writes Urbit jets in C. Not sure how that's possible, but there you go.
459−
460−Unfortunately we borrowed the audio for part I (it's Ulrich Schnauss, _Knuddelmaus_), but we'll fix that as soon as possible!
461−
462−</div>
docs/theory/whitepaper.mddeleted−2347
@@ -1,2347 +0,0 @@
1−---
2−sort: 0
3−title: Urbit whitepaper
4−---
5−
6−Urbit: an operating function
7−============================
8−
9−<div class="warning">This is Urbit whitepaper DRAFT 40K. Some small details
10−remain at variance with the codebase.</div>
11−
12−Abstract
13−========
14−
15−Urbit is a clean-slate, full-stack redesign of system software.
16−In 25K lines of code, it's a packet protocol, a pure functional
17−language, a deterministic OS, an ACID database, a versioned
18−filesystem, a web server and a global PKI. Urbit runs on a frozen
19−combinator interpreter specified in 200 words; the rest of the
20−stack upgrades itself over its own network.
21−
22−Architecturally, Urbit is an opaque computing and communication
23−layer above Unix and the Internet. To the user, it's a new
24−decentralized network where you own and control your own
25−general-purpose personal server, or "planet." A planet is not a
26−new way to host your old apps; it's a different experience.
27−
28−Download
29−--------
30−[As `.md`](https://storage.googleapis.com/urbit-extra/preview-1/whitepaper.md)
31−[As `.pdf`](https://storage.googleapis.com/urbit-extra/preview-1/whitepaper.pdf)
32−
33−<toc></toc>
34−
35−<div id="toc">
36−
37−Objective
38−=========
39−
40−How can we put users back in control of their own computing?
41−
42−Most people still have a general-purpose home computer, but it's
43−atrophying into a client. Their critical data is all in the
44−cloud. Technically, of course, that's ideal. Data centers are
45−pretty good at being data centers.
46−
47−But in the cloud, all users have is a herd of special-purpose
48−appliances, not one of which is a general-purpose computer. Do
49−users want their own general-purpose personal cloud computer? If
50−so, why don't they have one now? How might we change this?
51−
52−Conventional cloud computing, the way the cloud works now, is
53−"1:n". One application, hosted on one logical server by its own
54−developer, serves "n" users. Each account on each application is
55−one "personal appliance" - a special-purpose computer, completely
56−under the developer's control.
57−
58−Personal cloud computing, the way we wish the cloud worked, is
59−"n:1": each user has one logical server, which runs "n"
60−independent applications. This general-purpose computer is a
61−"personal server," completely under the user's control.
62−
63−"Personal server" is a phrase only a marketing department could
64−love. We prefer to say: your *planet*. Your planet is your
65−digital identity, your network address, your filesystem and your
66−application server. Every byte on it is yours; every instruction
67−it runs is under your control.
68−
69−Most people should park their planets in the cloud, because the
70−cloud works better. But a planet is not a planet unless it's
71−independent. A host without contractual guarantees of absolute
72−privacy and unconditional migration is not a host, but a trap.
73−The paranoid and those with global adversaries should migrate to
74−their own closets while home computing remains legal.
75−
76−But wait: isn't "planet" just a fancy word for a self-hosted
77−server? Who wants to self-host? Why would anyone want to be their
78−own sysadmin?
79−
80−*Managing* your own computing is a cost, not a benefit. Your
81−planet should be as easy as possible to manage. (It certainly
82−should be easier than herding your "n" personal appliances.) But
83−the benefit of "n:1" is *controlling* your own computing.
84−
85−The "n:1" cloud is not a better way to implement your existing
86−user experience. It's a different relationship between human and
87−computer. An owner is not just another customer. A single-family
88−home is not just another motel room. Control matters. A lot.
89−
90−Perhaps this seems abstract. It's hard to imagine the "n:1" world
91−before it exists. Let's try a thought-experiment: adding
92−impossible levels of ownership to today's "1:n" ecosystem.
93−
94−Take the web apps you use today. Imagine you trust them
95−completely. Imagine any app can use any data from any other app,
96−just because both accounts are you. Imagine you can "sidegrade"
97−any app by moving its data safely to a compatible competitor.
98−Imagine all your data is organized into a personal namespace, and
99−you can compute your own functions on that namespace.
100−
101−In this world, no app developer has any way to hold your data
102−hostage. Forget how this works technically (it doesn't). How does
103−it change the apps?
104−
105−Actually, the rules of this thought-experiment world are so
106−different that *few of the same apps exist*. Other people's apps
107−are fundamentally different from your own apps. They're not
108−"yours" because you developed them -- they're your apps because
109−you can fire the developer without any pain point. You are not a
110−hostage, so the power dynamic changes. Which changes the app.
111−
112−For example: with other people's apps, when you want to shop on
113−the Internets, you point your browser at amazon.com or use the
114−Google bar as a full-text store. With your own apps, you're more
115−likely to point your browser at your own shopping assistant. This
116−program, which *works entirely for you and is not slipping anyone
117−else a cut*, uses APIs to sync inventory data and send purchase
118−orders.
119−
120−Could you write this web app today? Sure. It would be a store.
121−The difference between apps you control and apps you don't is the
122−difference between a shopping assistant and a store. It would be
123−absurd if a shopping assistant paid its developer a percentage of
124−all transactions. It would be absurd if a store didn't. The
125−general task is the same, but every detail is different.
126−
127−Ultimately, the planet is a different user experience because you
128−trust the computer more. A program running on someone else's
129−computer can promise it's working only for you. This promise is
130−generally false and you can't enforce it. When a program on your
131−computer makes the same promise, it's generally true and you can
132−enforce it. Control changes the solution because control produces
133−trust and trust changes the problem.
134−
135−Could we actually add this level of user sovereignty to the "1:n"
136−cloud? It'd take a lot of engineers, a lot of lawyers, and a
137−whole lot of standards conferences. Or we could just build
138−ourselves some planets.
139−
140−Obstacles
141−=========
142−
143−If this is such a great product, why can't you already buy it?
144−
145−In 2015, general-purpose cloud servers are easily available. But
146−they are industrial tools, not personal computers. Most users
147−(consumer and enterprise) use personal appliances. They choose
148−"1:n" over "n:1". Why does "1:n" beat "n:1" in the real world?
149−
150−Perhaps "1:n" is just better. Your herd of developer-hosted
151−appliances is just a better product than a self-hosted planet. Or
152−at least, this is what the market seems to be telling us.
153−
154−Actually, the market is telling us something more specific. It's
155−saying: the appliance herd is a better product than a self-hosted
156−*Unix server on the Internet*.
157−
158−The market hasn't invalidated the abstract idea of the planet.
159−It's invalidated the concrete product of the planet *we can
160−actually build on the system software we actually have*.
161−
162−In 1978, a computer was a VAX. A VAX cost \$50K and was the size
163−of a fridge. By 1988, it would cost \$5K and fit on your desk.
164−But if a computer is a VAX, however small or cheap, there is no
165−such thing as a PC. And if a planet is an AWS box, there is no
166−such thing as a planet.
167−
168−The system software stack that 2015 inherited -- two '70s
169−designs, Unix and the Internet -- remains a viable platform for
170−"1:n" industrial servers. Maybe it's not a viable platform for
171−"n:1" personal servers? Just as VAX/VMS was not a viable
172−operating system for the PC?
173−
174−But what would a viable platform for a personal server look like?
175−What exactly is this stack? If it's not a Unix server on the
176−Internet, it's an X server on network Y. What are X and Y? Do
177−they exist?
178−
179−Clearly not. So all we have to replace is Unix and the Internet.
180−In other words, all we have to replace is everything. Is this an
181−obstacle, or an opportunity?
182−
183−A clean-slate redesign seems like the obvious path to the levels
184−of simplicity we'll need in a viable planet. Moreover, it's
185−actually easier to redesign Unix and the Internet than Unix *or*
186−the Internet. Computing and communication are not separate
187−concerns; if we design the network and OS as one system, we avoid
188−all kinds of duplications and impedance mismatches.
189−
190−And if not now, when? Will there ever be a clean-slate redesign
191−of '70s system software? A significant problem demands an
192−ambitious solution. Intuitively, clean-slate computing and the
193−personal cloud feel like a fit. Let's see if we can make the
194−details work. We may never get another chance to do it right.
195−
196−Principles of platform reform
197−-----------------------------
198−
199−To review: we don't have planets because our antique system
200−software stack, Unix and the Internet, is a lousy platform on
201−which to build a planet. If we care about the product, we need to
202−start with a new platform.
203−
204−How can we replace Unix and the Internet? We can't. But we can
205−tile over them, like cheap bathroom contractors. We can use the
206−Unix/Internet, or "classical layer," as an implementation
207−substrate for our new layer. A platform on top of a platform.
208−Under your Brazilian slate, there's pink Color Tile from 1976.
209−
210−"Tiling over" is the normal way we replace system software. The
211−Internet originally ran over phone circuits; under your
212−transatlantic TCP packets, there's an ATM switch from 1996. And
213−of course, under your browser there's an OS from 1976.
214−
215−After a good job of tiling over, the obsolete layer can sometimes
216−be removed. In some cases it's useless, but would cost too much
217−to rip out. In some cases it's still used -- a Mac doesn't (yet)
218−boot to Safari. But arguably, that's because the browser platform
219−is anything but a perfect tiling job.
220−
221−One property the browser got right was total opacity. The old
222−platform implements the new platform, but can't be visible
223−through it. If web apps could make Unix system calls or use Unix
224−libraries, there would be no such thing as web apps.
225−
226−(In fact, one easy way to think of a planet is as "the browser
227−for the server side." The browser is one universal client that
228−hosts "n" independent client applications; the planet is one
229−universal server that hosts "n" independent server applications.)
230−
231−And the bathroom remains a bathroom. The new platform does the
232−same *general* job as the old one. So to justify the reform, it
233−has to be *much* better at its new, specific job. For instance,
234−the browser is easily two orders of magnitude better than Unix at
235−installing untrusted transient applications (ie, web pages).
236−
237−Abstract targets
238−----------------
239−
240−Again, we have two problems: Unix and the Internet. What about
241−each do we need to fix? What exactly is wrong with the classical
242−layer? What qualities should our replacement have?
243−
244−Since we're doing a clean-slate design, it's a mistake to focus
245−too much on fixing the flaws of the old platform. The correct
246−question is: what is the right way to build a system software
247−stack? Besides cosmetic details like character sets, this
248−exercise should yield the same results on Mars as Earth.
249−
250−But we come from Earth and will probably find ourselves making
251−normal Earth mistakes. So we can at least express our abstract
252−design goals in normal Earth terms.
253−
254−### A simpler OS
255−
256−One common reaction to the personal-server proposition: "my
257−mother is not a Linux system administrator." Neither is mine. She
258−does own an iPhone, however. Which is also a general-purpose
259−computer. A usability target: a planet should be as easy to
260−manage as an iPhone.
261−
262−(To go into way too much detail: on a planet with the usability
263−of iOS, the user as administrator has four system configuration
264−tasks for the casual or newbie user: (a) deciding which
265−applications to run; (b) checking resource usage; (c) configuring
266−API authentication to your existing Web apps (your planet wants
267−to access, rip or even sync your silo data); and (d) maintaining
268−a reputation database (your friends, enemies, etc). (a) and (b)
269−exist even on iOS; (c) and (d) are inherent in any planet; (d) is
270−common on the Web, and (c) not that rare.)
271−
272−Could a planet just run iOS? The complexity of managing a
273−computer approximates the complexity of its state. iOS is a
274−client OS. Its apps are not much more than webpages. There is
275−much more state on a server; it is much more valuable, and much
276−more intricate, and much more durable.
277−
278−(Moreover, an iOS app is a black box. It's running on your
279−physical hardware, but you don't have much more control over it
280−than if it was remote. iOS apps are not designed to share data
281−with each other or with user-level computing tools; there is no
282−visible filesystem, shell, etc. This is not quite the ownership
283−experience -- it's easy to get locked in to a black box.)
284−
285−And while an Apple product is a good benchmark for any usability
286−goal, it's the exception that proves the rule for architecture.
287−iOS is Unix, after all -- Unix with a billion-dollar makeover.
288−Unix is not a turd, and Cupertino could probably polish it even
289−if it was.
290−
291−Simplicity is the only viable path to usability for a new
292−platform. It's not sufficient, but it is necessary. The computer
293−feels simple to the user not because it's presenting an illusion
294−of simplicity, but because it really is simple.
295−
296−While there is no precise way to measure simplicity, a good proxy
297−is lines of code -- or, to be slightly more sophisticated,
298−compressed code size. Technical simplicity is not actually
299−usability, just a force multiplier in the fight for usability.
300−But usability proper can only be assessed once the UI is
301−complete, and the UI is the top layer by definition. So we assume
302−this equation and target simplicity.
303−
304−### A sane network
305−
306−When we look at the reasons we can't have a nice planet, Unix is
307−a small part of the problem. The main problem is the Internet.
308−
309−There's a reason what we call "social networks" on the Internet
310−are actually centralized systems -- social *servers*. For a "1:n"
311−application, social integration - communication between two users
312−of the same application - is trivial. Two users are two rows in
313−the same database.
314−
315−When we shift to a "n:1" model, this same integration becomes a
316−distributed systems problem. If we're building a tictactoe app in
317−a "1:n" design, our game is a single data structure in which
318−moves are side effects. If we're building the same app on a
319−network of "n:1" model, our game is a distributed system in which
320−moves are network messages.
321−
322−Building and managing distributed Internet systems is not easy.
323−It's nontrivial to build and manage a centralized API. Deploying
324−a new global peer-to-peer protocol is a serious endeavor.
325−
326−But this is what we have to do for our tictactoe app. We have to
327−build, for instance, some kind of identity model - because who
328−are you playing against, an IP address? To play tictactoe, you
329−find yourself building your own distributed social network.
330−
331−While there are certainly asocial apps that a planet can run,
332−it's not clear that an asocial planet is a viable product. If the
333−cost of building a distributed social service isn't close to the
334−cost of a building its centralized equivalent, the design isn't
335−really successful.
336−
337−Fortunately, while there are problems in "n:1" services that no
338−platform can solve for you (mostly around consistency) there are
339−set of problems with "1:n" services that no platform can solve
340−for you (mostly around scaling). Scaling problems in "n:1" social
341−services only arise when you're Justin Bieber and have a million
342−friends, ie, a rare case even in a mature network. Mr. Bieber can
343−probably afford a very nice computer.
344−
345−### Concrete requirements
346−
347−Here are some major features we think any adequate planet needs.
348−They're obviously all features of Urbit.
349−
350−#### Repeatablе computing
351−
352−Any non-portable planet is locked in to its host. That's bad. You
353−can have all the legal guarantees you like of unconditional
354−migration. Freedom means nothing if there's nowhere to run to.
355−Some of today's silos are happy to give you a tarball of your own
356−data, but what would you do with it?
357−
358−The strongest way to ensure portability is a deterministic,
359−frozen, non-extensible execution model. Every host runs exactly
360−the same computation on the same image and input, for all time.
361−When you move that image, the only thing it notices is that its
362−IP address has changed.
363−
364−We could imagine a planet with an unfrozen spec, which had some
365−kind of backward-compatible upgrade process. But with a frozen
366−spec, there is no state outside the planet itself, no input not
367−input to the planet itself, and no way of building a planet on
368−one host that another host can't compute correctly.
369−
370−Of course every computer is deterministic at the CPU level, but
371−CPU-level determinism can't in practice record and replay its
372−computation history. A computer which is deterministic at the
373−semantic level can. Call it "repeatable computing."
374−
375−#### Orthogonal persistence
376−
377−It's unclear why we'd expose the transience semantics of the
378−hardware memory hierarchy to either the programmer or the user.
379−When we do so, we develop two different models for managing data:
380−"programming languages" and "databases." Mapping between these
381−models, eg "ORM," is the quintessence of boilerplate.
382−
383−A simple pattern for orthogonal persistence without a separate
384−database is "prevalence": a checkpoint plus a log of events since
385−the checkpoint. Every event is an ACID transaction. In fact, most
386−databases use this pattern internally, but their state transition
387−function is not a general-purpose interpreter.
388−
389−#### Identity
390−
391−In the classical layer, hosts, usernames, IP addresses, domain
392−names and public keys are all separate concepts. A planet has one
393−routable, memorable, cryptographically independent identity which
394−serves all these purposes.
395−
396−The "Zooko's triangle" impossibility result tells us we can't
397−build a secure, meaningful, decentralized identity system. Rather
398−than surrendering one of these three goals, the planet can
399−retreat a little bit on two of them. It can be memorable, but not
400−meaningful; it can start as a centralized system, but
401−decentralize itself over time. 100-80-70 is often preferable to
402−100-100-0.
403−
404−#### A simple typed functional language
405−
406−Given the level of integration we're expecting in this design,
407−it's silly to think we could get away without a new language.
408−There's no room in the case for glue. Every part has to fit.
409−
410−The main obstacle to functional language adoption is that
411−functional programming is math, and most human beings are really
412−bad at math. Even most programmers are bad at math. Their
413−intuition of computation is mechanical, not mathematical.
414−
415−A pure, higher-order, typed, strict language with mechanical
416−intuition and no mathematical roots seems best positioned to
417−defeat this obstacle. Its inference algorithm should be almost
418−but not quite as strong as Hindley-Milner unification, perhaps
419−inferring "forward but not backward."
420−
421−We'd also like two other features from our types. One, a type
422−should define a subset of values against a generic data model,
423−the way a DTD defines a set of XML values. Two, defining a type
424−should mean defining an executable function, whose range is the
425−type, that verifies or normalizes a generic value. Why these
426−features? See the next section...
427−
428−#### High-level communication
429−
430−A planet could certainly use a network type descriptor that was
431−like a MIME type, if a MIME type was an executable specification
432−and could validate incoming content automatically. After ORM,
433−manual data validation must be the second leading cause of
434−boilerplate. If we have a language in which a type is also a
435−validator, the automatic validation problem seems solvable. We
436−can get to something very like a typed RPC.
437−
438−Exactly-once message delivery semantics are impossible unless the
439−endpoints have orthogonal persistence. Then they're easy: use a
440−single persistent session with monotonically increasing sequence
441−numbers. It's nice not worrying about idempotence.
442−
443−With an integrated OS and protocol, it's possible to fully
444−implement the end-to-end principle, and unify the application
445−result code with the packet acknowledgment -- rather than having
446−three different layers of error code. Not only is every packet a
447−transaction at the system level; every message is a transaction
448−at the application level. Applications can even withhold an
449−acknowledgment to signal internal congestion, sending the other
450−end into exponential backoff.
451−
452−It's also nice to support simple higher-level protocol patterns
453−like publish/subscribe. We don't want every application to have
454−to implement its own subscription queue backpressure. Also, if we
455−can automatically validate content types, perhaps we can also
456−also diff and patch them, making remote syncing practical.
457−
458−The web will be around for a while. It would be great to have a
459−web server that let a browser page with an SSO login authenticate
460−itself as another planet, translating messages into JSON. This
461−way, any distributed application is also a web application.
462−
463−Finally, a planet is also a great web *client*. There is lots of
464−interesting data behind HTTP APIs. A core mission of a planet is
465−collecting and maintaining the secrets the user needs to manage
466−any off-planet data. (Of course, eventually this data should come
467−home, but it may take a while.) The planet's operating system
468−should serve as client-side middleware that mediates the API
469−authentication process, letting the programmer program against
470−the private web as if it was public, using site-specific auth
471−drivers with user-configured secrets.
472−
473−#### Global namespace
474−
475−The URL taught us that any global identity scheme is the root of
476−a global namespace. But the URL also made a big mistake:
477−mutability.
478−
479−A global namespace is cool. An immutable (referentially
480−transparent) global namespace, which can use any data in the
481−universe as if it was a constant, is really cool. It's even
482−cooler if, in case your data hasn't been created yet, your
483−calculation can block waiting for it. Coolest of all is when the
484−data you get back is typed, and you can use it in your typed
485−functional language just like dereferencing a pointer.
486−
487−Of course, an immutable namespace should be a distributed version
488−control system. If we want typed data, it needs to be a typed
489−DVCS, clearly again with type-specific diff and patch. Also, our
490−DVCS (which already needs a subscription mechanism to support
491−blocking) should be very good at reactive syncing and mirroring.
492−
493−#### Semantic drivers
494−
495−One unattractive feature of a pure interpreter is that it exacts
496−an inescapable performance tax -- since an interpreter is always
497−slower than native code. This violates the prime directive of OS
498−architecture: the programmer must never pay for any service that
499−doesn't get used. Impure interpreters partly solve this problem
500−with a foreign-function interface, which lets programmers move
501−inner loops into native code and also make system calls. An FFI
502−is obviously unacceptable in a deterministic computer.
503−
504−A pure alternative to the FFI is a semantic registry in which
505−functions, system or application, can declare their semantics in
506−a global namespace. A smart interpreter can recognize these
507−hints, match them to a checksum of known good code, and run a
508−native driver that executes the function efficiently. This
509−separates policy (pure algorithm as executable specification)
510−from mechanism (native code or even hardware).
511−
512−#### Repository-driven updates
513−
514−A planet owner is far too busy to manually update applications.
515−They have to update themselves.
516−
517−Clearly the right way to execute an application is to run it
518−directly from the version-control system, and reload it when a
519−new version triggers any build dependencies. But in a planet, the
520−user is not normally the developer. To install an app is to
521−mirror the developer's repository. The developer's commit starts
522−the global update process by updating mirror subscriptions.
523−
524−Of course, data structures may change, requiring the developer to
525−include an adapter function that converts the old state. (Given
526−orthogonal persistence, rebooting the app is not an option.)
527−
528−Added fun is provided by the fact that apps use the content types
529−defined in their own repository, and these types may change.
530−Ideally these changes are backward compatible, but an updated
531−planet can still find itself sending an un-updated planet
532−messages that don't validate. This race condition should block
533−until the update has fully propagated, but not throw an error up
534−to the user level -- because no user has done anything wrong.
535−
536−### Why not a planet built on JS or JVM?
537−
538−Many programmers might accept our reasoning at the OS level, but
539−get stuck on Urbit's decision not to reuse existing languages or
540−interpreters. Why not JS, JVM, Scheme, Haskell...? The planet is
541−isolated from the old layer, but can't it reuse mature designs?
542−
543−One easy answer is that, if we're going to be replacing Unix and
544−the Internet, or at least tiling over them, rewriting a bit of
545−code is a small price to pay for doing it right. Even learning a
546−new programming language is a small price to pay. And an
547−essential aspect of "doing it right" is a system of components
548−that fit together perfectly; we need all the simplicity wins we
549−can get.
550−
551−But these are big, hand-waving arguments. It takes more than this
552−kind of rhetoric to justify reinventing the wheel. Let's look at
553−a few details, trying not to get ahead of ourselves.
554−
555−In the list above, only JS and the JVM were ever designed to be
556−isolated. The others are tools for making POSIX system calls.
557−Isolation in JS and the JVM is a client thing. It is quite far
558−from clear what "node.js with browser-style isolation" would even
559−mean. And who still uses Java applets?
560−
561−Let's take a closer look at the JS/JVM options - not as the only
562−interpreters in the world, just as good examples. Here are some
563−problems we'd need them to solve, but they don't solve - not, at
564−least, out of the box.
565−
566−First: repeatability. JS and the JVM are not frozen, but warm;
567−they release new versions with backward compatibility. This means
568−they have "current version" state outside the planet proper. Not
569−lethal but not good, either.
570−
571−When pure, JS and then JVM are at least nominally deterministic,
572−but they are also used mainly on transient data. It's not clear
573−that the the actual implementations and specifications are built
574−for the lifecycle of a planet - which must never miscompute a
575−single bit. (ECC servers are definitely recommended.)
576−
577−Second: orthogonal persistence. Historically, successful OP
578−systems are very rare. Designing the language and OS as one unit
579−seems intuitively required.
580−
581−One design decision that helps enormously with OP is an acyclic
582−data model. Acyclic data structures are enormously easier to
583−serialize, to specify and validate, and of course to
584−garbage-collect. Acyclic databases are far more common than
585−cyclic ("network" or "object") databases. Cyclic languages are
586−more common than acyclic languages -- but pure functional
587−languages are acyclic, so we know acyclic programming can work.
588−
589−(It's worth mentioning existing image-oriented execution
590−environments - like Smalltalk and its descendants, or even the
591−Lisp machine family. These architectures (surely Urbit's closest
592−relatives) could in theory be adapted to use as orthogonally
593−persistent databases, but in practice are not designed for it.
594−For one thing, they're all cyclic. More broadly, the assumption
595−that the image is a GUI client in RAM is deeply ingrained.)
596−
597−Third: since a planet is a server and a server is a real OS, its
598−interpreter should be able to efficiently virtualize itself.
599−There are two kinds of interpreter: the kind that can run an
600−instance of itself as a VM, and the kind that can't.
601−
602−JS can almost virtualize itself with `eval`, but `eval` is a toy.
603−(One of those fun but dangerous toys -- like lawn darts.) And
604−while it's not at all the same thing, the JVM can load applets --
605−or at least, in 1997 it could...
606−
607−(To use some Urbit concepts we haven't met yet: with semantic
608−drivers (which don't exist in JS or the JVM, although asm.js is a
609−sort of substitute), we don't even abandon all the world's JS or
610−JVM code by using Urbit. Rather, we can implement the JS or JVM
611−specifications in Hoon, then jet-propel them with practical Unix
612−JS or JVM engines, letting us run JS or Java libraries.)
613−
614−Could we address any or all of these problems in the context of
615−JS, the JVM or any other existing interpreter? We could. This
616−does not seem likely to produce results either better or sooner
617−than building the right thing from scratch.
618−
619−Definition
620−==========
621−
622−An operating function (OF) is a logical computer whose state is a
623−fixed function of its input history:
624−
625− V(I) => T
626−
627−where `T` is the state, `V` is the fixed function, `I` is the
628−list of input events from first to last.
629−
630−Intuitively, what the computer knows is a function of what it's
631−heard. If the `V` function is identical on every computer for all
632−time forever, all computers which hear the same events will learn
633−the same state from them.
634−
635−Is this function a protocol, an OS, or a database? All three.
636−Like an OS, `V` specifies the semantics of a computer. Like a
637−protocol, `V` specifies the semantics of its input stream. And
638−like a database, `V` interprets a store of persistent state.
639−
640−Advantages
641−----------
642−
643−This is a very abstract description, which doesn't make it easy
644−to see what an OF is useful for.
645−
646−Two concrete advantages of any practical OF (not just Urbit):
647−
648−### Orthogonal persistencе
649−
650−An OF is inherently a single-level store. `V(I) => T` is an
651−equation for the lifecycle of a computer. It doesn't make any
652−distinction between transient RAM and persistent disk.
653−
654−The word "database" has always conflated two concepts: data that
655−isn't transient; structures specialized for search. A substantial
656−percentage of global programmer-hours are spent on translating
657−data between memory and disk formats.
658−
659−Every practical modern database computes something like
660−`V(I) => T`. `I` is the transaction log. An OF is an ACID
661−database whose history function (log to state) is a
662−general-purpose computer. A transaction is an event, an event is
663−a transaction.
664−
665−(Obviously a practical OF, though still defined as `V(I) => T`,
666−does not recompute its entire event history on every event.
667−Rather, it computes some incremental iterator `U` that can
668−compute `U(E T0) => T1`, where `E` is each event in `I`.
669−
670−In plain English, the next state `T1` is a function `U` of the
671−latest event `E` and the current state `T0`. We can assume that
672−some kind of incrementality will fall out of any reasonable `V`.)
673−
674−In any reasonable OF, you can write a persistent application by
675−leaving your data in the structures you use it from. Of course,
676−if you want to use specialized search structures, no one is
677−stopping you.
678−
679−### Repeatable computing
680−
681−Every computer is deterministic at the CPU level, in the sense
682−that the CPU has a manual which is exactly right. But it is not
683−actually practical to check the CPU's work.
684−
685−"Repeatable computing" is high-level determinism. It's actually
686−practical to audit the validity of a repeatable computer by
687−re-executing its computation history. For an OF, the history is
688−the event log.
689−
690−Not every urbit is a bank; not every urbit has to store its full
691−log. Still, the precision of a repeatable computer also affects
692−the user experience. (It's appalling, for instance, how
693−comfortable the modern user is with browser hangs and crashes.)
694−
695−Requirements
696−------------
697−
698−`V` can't be updated for the lifecycle of the computer. Or, since
699−`V` is also a protocol, for the lifetime of the network.
700−
701−So `V` needs to be perfect, which means it needs to be small.
702−It's also easier to eradicate ambiguity in a small definition.
703−
704−But we're designing a general-purpose computer which is
705−programmed by humans. Thus `V` is a programming language in some
706−sense. Few practical languages are small, simple or perfect.
707−
708−`V` is a practical interpreter and should be reasonably fast. But
709−`V` is also a (nonpreemptive) operating system. One universal
710−feature of an OS is the power to virtualize user-level code. So
711−we need a small, simple, perfect interpreter which can
712−efficiently virtualize itself.
713−
714−`V` is also a system of axioms in the mathematical sense. Axioms
715−are always stated informally. This statement succeeds iff it
716−accurately communicates the same axioms to every competent
717−reader. Compressing the document produces a rough metric of
718−information content: the complexity of `V`.
719−
720−(It's possible to cheat on this test. For instance, we could
721−design a simple `V` that only executes another interpreter, `W`.
722−`W`, the only program written in V's language, is simply encoded
723−in the first event. Which could be quite a large event.
724−
725−This design achieves the precision of `V`, but not its stability.
726−For stability, the true extent of `V` is the semantic kernel that
727−the computer can't replace during its lifetime from events in the
728−input history. Thus `V` properly includes `W`.)
729−
730−There are no existing interpreters that ace all these tests, so
731−Urbit uses its own. Our `V` is defined in 350 bytes gzipped.
732−
733−Nouns
734−-----
735−
736−A value in Urbit is a *noun*. A noun is an *atom* or a *cell*. An
737−atom is an unsigned integer of any size. A cell is an ordered
738−pair of nouns.
739−
740−In the system equation `V(I) => T`, `T` is a noun, `I` is a list
741−of nouns - where a list is either `0` or a cell `[item list]`.
742−The `V` function is defined below.
743−
744−Nock
745−----
746−
747−Nock or `N` is a combinator interpreter on nouns. It's specified
748−by these pseudocode reduction rules:
749−
750− Nock(a) *a
751− [a b c] [a [b c]]
752−
753− ?[a b] 0
754− ?a 1
755− +[a b] +[a b]
756− +a 1 + a
757− =[a a] 0
758− =[a b] 1
759− =a =a
760−
761− /[1 a] a
762− /[2 a b] a
763− /[3 a b] b
764− /[(a + a) b] /[2 /[a b]]
765− /[(a + a + 1) b] /[3 /[a b]]
766− /a /a
767−
768− *[a [b c] d] [*[a b c] *[a d]]
769−
770− *[a 0 b] /[b a]
771− *[a 1 b] b
772− *[a 2 b c] *[*[a b] *[a c]]
773− *[a 3 b] ?*[a b]
774− *[a 4 b] +*[a b]
775− *[a 5 b] =*[a b]
776−
777− *[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
778− *[a 7 b c] *[a 2 b 1 c]
779− *[a 8 b c] *[a 7 [[7 [0 1] b] 0 1] c]
780− *[a 9 b c] *[a 7 c 2 [0 1] 0 b]
781− *[a 10 [b c] d] *[a 8 c 7 [0 3] d]
782− *[a 10 b c] *[a c]
783−
784− *a *a
785−
786−Note that operators 6-10 are macros and not formally essential.
787−Note also that Nock reduces invalid reductions to self, thus
788−specifying nontermination (bottom).
789−
790−A valid Nock reduction takes a cell `[subject formula]`. The
791−formula defines a function that operates on the subject.
792−
793−A valid formula is always a cell. If the head of the formula is a
794−cell, Nock reduces head and tail separately and produces the cell
795−of their products ("autocons"). If the head is an atom, it's an
796−operator from `0` to `10`.
797−
798−In operators `3`, `4`, and `5`, the formula's tail is another
799−formula, whose product is the input to an axiomatic function. `3`
800−tests atom/cell, `4` increments, `5` tests equality.
801−
802−In operator `0`, the tail is a "leg" (subtree) address in the
803−subject. Leg `1` is the root, `2n` the left child of `n`, `2n+1`
804−the right child.
805−
806−In operator `1`, the tail is produced as a constant. In operator
807−`2`, the tail is a formula, producing a `[subject formula]` cell
808−which Nock reduces again (rendering the system Turing complete).
809−
810−In the macro department, `6` is if-then-else; `7` is function
811−composition; `8` is a stack push; `9` is a function call; `10` is
812−a hint.
813−
814−Surprisingly, Nock is quite a practical interpreter, although it
815−poses unusual implementation challenges. For instance, the only
816−arithmetic operation is increment (see the implementation issues
817−section for how this is practical). Another atypical feature is
818−that Nock can neither test pointer equality, nor create cycles.
819−
820−The fixed function
821−------------------
822−
823−So is `V` just Nock? Almost. Where `N` is Nock, `V` is:
824−
825− V(I) == N(I [2 [0 3] [0 2]])
826−
827−If Nock was not `[subject formula]` but `[formula subject]`, not
828−`N(S F)` but `N(F S)`, V would be Nock.
829−
830−In either case, the head `I0` of `I` is the boot formula; the
831−tail is the boot subject. Intuitively: to interpret the event
832−history, treat the first event as a program; run that program on
833−the rest of history.
834−
835−More abstractly: the event sequence `I` begins with a *boot
836−sequence* of non-uniform events, which do strange things like
837−executing each other. Once this sequence completes, we end up in
838−a *main sequence* of uniform events (starting at `I5`), which
839−actually look and act like actual input.
840−
841−`I0`: The lifecycle formula
842−---------------------------
843−
844−`I0` is special because we run it in theory but not in practice.
845−Urbit is both a logical definition and a practical interpreter.
846−Sometimes there's tension between these goals. But even in
847−practice, we check that `I0` is present and correct.
848−
849−`I0` is a nontrivial Nock formula. Let's skip ahead and write it
850−in our high-level language, Hoon:
851−
852− => [load rest]=.
853− =+ [main step]=.*(rest load)
854− |- ?~ main step
855− $(main +.main, step (step -.main))
856−
857−Or in pseudocode:
858−
859− from pair $load and $rest
860− let pair $main and $step be:
861− the result of Nock $load run on $rest
862− loop
863− if $main is empty
864− return $step
865− else
866− continue with
867− $main set to tail of $main,
868− $step set to:
869− call function $step on the head of $main
870−
871−In actual Nock (functional machine code, essentially):
872−
873− [8 [2 [0 3] [0 2]] 8 [ 1 6 [5 [1 0] 0 12] [0 13] 9 2
874− [0 2] [[0 25] 8 [0 13] 9 2 [0 4] [0 56] 0 11] 0 7] 9 2 0 1]
875−
876−`I0` is given the sequence of events from `I1` on. It takes `I1`,
877−the boot loader, and runs it against the rest of the sequence.
878−`I1` consumes `I2`, `I3`, and `I4`, and then it produces the true
879−initial state function `step` and the rest of the events from
880−`I5` on.
881−
882−`I0` then continues on to the main sequence, iteratively
883−computing `V(I)` by calling the `step` function over and over on
884−each event. Each call to `step` produces the next state,
885−incorporating the changes resulting from the current event.
886−
887−`I1`: the language formula
888−--------------------------
889−
890−The language formula, `I1`, is another nontrivial Nock formula.
891−Its job is to compile `I3`, the Hoon compiler as source, with
892−`I2`, the Hoon compiler as a Nock formula.
893−
894−If `I3`, compiled with `I2`, equals `I2`, `I1` then uses `I2` to
895−load `I4`, the Arvo source. The main event sequence begins with
896−`I5`. The only events which are Nock formulas are `I0`, `I1`, and
897−`I2`; the only events which are Hoon source are `I3` and `I4`.
898−
899−`I1`, in pseudo-Hoon:
900−
901− => [fab=- src=+< arv=+>- seq=+>+]
902− =+ ken=(fab [[%atom %ud] 164] src)
903− ?> =(+>.fab +.ken)
904− [seq (fab ken arv)]
905−
906−In pseudocode:
907−
908− with tuple as [$fab, $src, $arv, $seq], // these are I2 I3 I4 and I5...
909− let $ken be:
910− call $fab on type-and-value "uint 164" and Hoon $src
911− assert environment from $fab is equal to the value from $ken
912− return pair of the remaining $seq and:
913− call $fab on environment $ken and Hoon $arv
914−
915−In actual Nock:
916−
917− [7 [0 2] 8 [8 [0 2] 9 2 [0 4] [7 [0 3] [1 [1.836.020.833
918− 25.717] 164] 0 6] 0 11] 6 [5 [0 27] 0 5] [[0 31] 8 [0 6]
919− 9 2 [0 4] [7 [0 3] [0 2] 0 30] 0 11] 0 0]
920−
921−(`25.717`? Urbit uses the German dot notation for large atoms.)
922−
923−We compile the compiler source, check that it produces the same
924−compiler formula, and then compile the OS with it.
925−
926−Besides `I0` and `I1`, there's no Nock code in the boot sequence
927−that doesn't ship with Hoon source.
928−
929−`I2` and `I3`: the Hoon compiler
930−--------------------------------
931−
932−Again, `I2` is the Hoon compiler (including basic libraries) as a
933−Nock formula. `I3` is the same compiler as source.
934−
935−Hoon is a strict, typed, higher-order pure functional language
936−which compiles itself to Nock. It avoids category theory and
937−aspires to a relatively mechanical, concrete style.
938−
939−The Hoon compiler works with three kinds of noun: `nock`, a Nock
940−formula; `twig`, a Hoon AST; and `span`, a Hoon type, which
941−defines semantics and constraints on some set of nouns.
942−
943−There are two major parts of the compiler: the front end, which
944−parses a source file (as a text atom) to a twig; and the back
945−end, `ut`, which accepts a subject span and a twig, and compiles
946−them down to a product span and a Nock formula.
947−
948−### Back end and type system
949−
950−The Hoon back end, (`ut`), about 1700 lines of Hoon, performs
951−type inference and (Nock) code generation. The main method of
952−`ut` is `mint`, with signature `$+([span twig] [span Nock])`
953−(i.e., in pseudocode, `mint(span, twig) -> [span Nock]`).
954−
955−Just as a Nock formula executes against a subject noun, a Hoon
956−expression is always compiled against a subject span. From this
957−`[span twig]`, `mint` produces a cell `[span Nock]` . The Nock
958−formula generates a useful product from any noun in the subject
959−span. The span describes the set of product nouns.
960−
961−Type inference in Hoon uses only forward tracing, not unification
962−(tracing backward) as in Hindley-Milner (Haskell, ML). Hoon needs
963−more user annotation than a unification language, but it's easier
964−for the programmer to follow what the algorithm is doing - just
965−because Hoon's algorithm isn't as smart.
966−
967−But the Hoon type system can solve most of the same problems as
968−Haskell's, notably including typeclasses / genericity. For
969−instance, it can infer the type of an AST by compiling a grammar
970−in the form of an LL combinator parser (like Hoon's own grammar).
971−
972−The Hoon type system, slightly simplified for this overview:
973−
974− ++ span $| $? %noun
975− %void
976− ==
977− $% [%atom p=cord]
978− [%cell p=span q=span]
979− [%core p=span q=(map term twig)]
980− [%cube p=noun q=span]
981− [%face p=term q=span]
982− [%fork p=span q=span]
983− [%hold p=span q=twig]
984− ==
985−
986−In pseudocode:
987−
988− define $span as one of:
989− 'noun'
990− 'void'
991− 'atom' with text aura
992− 'cell' of $span and $span
993− 'core' of environment $span and map of name to code AST
994− 'cube' of constant value and $span
995− 'face' of name wrapping $span
996− 'fork' of $span and alternate $span
997− 'hold' of subject $span and continuation AST
998−
999−(The syntax `%string` means a *cord*, or atom with ASCII bytes in
1000−LSB first order. Eg, `%foo` is also 0x6f.6f66 or 7.303.014.)
1001−
1002−The simplest spans are `%noun`, the set of all nouns, and
1003−`%void`, the empty set.
1004−
1005−Otherwise, a span is one of `%atom`, `%cell`, `%core`, `%cube`,
1006−`%face`, `%fork` or `%hold`, each of which is parameterized with
1007−additional data.
1008−
1009−An `%atom` is any atom, plus an *aura* cord that describes both
1010−what logical units the atom represents, and how to print it. For
1011−instance, `%ud` is an unsigned decimal, `%ta` is ASCII text,
1012−`%da` is a 128-bit Urbit date. `%n` is nil (`~`).
1013−
1014−A `%cell` is a recursively typed cell. `%cube` is a constant.
1015−`%face` wraps another span in a name for symbolic access. `%fork`
1016−is the union of two spans.
1017−
1018−A `%core` is a combination of code and data - Hoon's version of
1019−an object. It's a cell `[(map term formula) payload]`, i.e. a set
1020−of named formulas (essentially "computed attributes") and a
1021−"payload", which includes the context the core is defined in.
1022−Each arm uses the whole core as its subject.
1023−
1024−One common core pattern is the *gate*, Hoon's version of a
1025−lambda. A gate is a core with a single formula, and whose payload
1026−is a cell `[arguments context]`. To call the function, replace
1027−the formal arguments with your actual argument, then apply. The
1028−context contains any data or code the function may need.
1029−
1030−(A core is not exactly an object, nor a map of names to formulas
1031−a vtable. The formulas are computed attributes. Only a formula
1032−that produces a gate is the equivalent of a method.)
1033−
1034−### Syntax, text
1035−
1036−Hoon's front end (`vast`) is, at 1100 lines, quite a gnarly
1037−grammar. It's probably the most inelegant section of Urbit.
1038−
1039−Hoon is a keyword-free, ideographic language. All alphabetic
1040−strings are user text; all punctuation is combinator syntax. The
1041−*content* of your code is always alphabetic; the *structure* is
1042−always punctuation. And there are only 80 columns per line.
1043−
1044−A programming language is a UI for programmers. UIs should be
1045−actually usable, not apparently usable. Some UI tasks are harder
1046−than they appear; others are easier. Forming associative memories
1047−is easier than it looks.
1048−
1049−Languages do need to be read out loud, and the conventional names
1050−for punctuation are clumsy. So Hoon replaces them:
1051−
1052− ace [1 space] gal < pel (
1053− bar | gap [>1 space, nl] per )
1054− bas \ gar > sel [
1055− buc $ hax # sem ;
1056− cab _ hep - ser ]
1057− cen % kel { soq '
1058− col : ker } tar *
1059− com , ket ^ tec `
1060− doq " lus + tis =
1061− dot . pam & wut ?
1062− fas / pat @ zap !
1063− sig ~
1064−
1065−For example, `%=` sounds like "centis" rather than "percent
1066−equals." Since even a silent reader will subvocalize, the length
1067−and complexity of the sound is a tax on reading the code.
1068−
1069−A few digraphs also have irregular sounds:
1070−
1071− == stet
1072− -- shed
1073− ++ slus
1074− -> lark
1075− -< lush
1076− +> dark
1077− +< dush
1078−
1079−Hoon defines over 100 digraph ideograms (like `|=`). Ideograms
1080−(or *runes*) have consistent internal structure; for instance,
1081−every rune with the `|` prefix produces a core. There are no
1082−user-defined runes. These facts considerably mitigate the
1083−memorization task.
1084−
1085−Finally, although it's not syntax, style merits a few words.
1086−While names in Hoon code can have any internal convention the
1087−programmer wants (as long as it's lowercase ASCII plus hyphen),
1088−one convention we use a lot: face names which are random
1089−three-letter syllables, arm names which are four-letter random
1090−Scrabble words.
1091−
1092−Again, forming associative memories is easier than it looks.
1093−Random names quickly associate to their meanings, even without
1094−any mnemonic. A good example is the use of Greek letters in math.
1095−As with math variables, consistency helps too - use the same name
1096−for the same concept everywhere.
1097−
1098−This "lapidary" convention is appropriate for code that's
1099−nontrivial, but still clean and relatively short. But code can't
1100−be clean unless it's solving a clean problem. For dirty problems,
1101−long informative names and/or kebab-case are better. For trivial
1102−problems (like defining `add`), we use an even more austere
1103−"hyperlapidary" style with one-letter names.
1104−
1105−### Twig structure
1106−
1107−A Hoon expression compiles to a `twig`, or AST node. A twig is
1108−always a cell.
1109−
1110−Like Nock formulas, Hoon twigs "autocons." A twig whose head is a
1111−cell is a pair of twigs, which compiles to a pair of formulas,
1112−which is a formula producing a pair. ("autocons" is an homage to
1113−Lisp, whose `(cons a (cons b c))` becomes Urbit's `[a b c]`.)
1114−
1115−Otherwise, a twig is a tagged union. Its tag is always a rune,
1116−stored by its phonetic name as a cord. Because it's normal for
1117−31-bit numbers to be direct (thus, somewhat more efficient), we
1118−drop the vowels. So `=+` is not `%tislus`, but `%tsls`.
1119−
1120−There are too many kinds of twig to enumerate here. Most are
1121−implemented as macros; only about 25 are directly translated to
1122−Nock. There is nothing sophisticated about twigs - given the
1123−syntax and type system, probably anyone would design the same
1124−twig system.
1125−
1126−### Syntax geometry
1127−
1128−Just visually, one nice feature of imperative languages is the
1129−distinction between statements, which want to grow vertically
1130−down the page, and expressions, which prefer to grow
1131−horizontally.
1132−
1133−Most functional languages, inherently lacking the concept of
1134−statements, have a visual problem: their expressions grow best
1135−horizontally, and often besiege the right margin.
1136−
1137−Hoon has two syntax modes: "tall," which grows vertically, and
1138−"wide," which grows horizontally. Tall code can contain wide
1139−code, but not vice versa. In general, any twig can be written in
1140−either mode.
1141−
1142−Consider the twig `[%tsls a b]`, where `a` and `b` are twigs.
1143−`=+` defines a variables, roughly equivalent to Lisp's `let`. `a`
1144−defines the variable for use in `b`. In wide mode it looks like
1145−an expression: `=+(a b)`. In tall mode, the separator is two
1146−spaces or a newline, without parentheses:
1147−
1148− =+ a
1149− b
1150−
1151−which is the same code, but looks like a "statement." The
1152−deindentation is reasonable because even though `b` is, according
1153−to the AST, "inside" the `=+`, it's more natural to see it
1154−separated out.
1155−
1156−For twigs with a constant number of components, like
1157−`[%tsls a b]`, tall mode relies on the parser to stop itself.
1158−With a variable fanout we need a `==` terminator:
1159−
1160− :* a
1161− b
1162− ==
1163−
1164−The indentation rules of constant-fanout twigs are unusual.
1165−Consider the stem `?:`, which happens to have the exact same
1166−semantics as C `?:` (if-then-else). Where in wide form we'd write
1167−`?:(a b c)`, in tall form the convention is
1168−
1169− ?: a
1170− b
1171− c
1172−
1173−This is *backstep* indentation. Its motivation: defend the right
1174−margin. Ideally, `c` above is a longer code block than `a` or
1175−`b`. And in `c`, we have not lost any margin at all. Ideally, we
1176−can write an arbitrarily tall and complex twig that always grows
1177−vertically and never has a margin problem. Backstep indentation
1178−is tail call optimization for syntax.
1179−
1180−Finally, the wide form with rune and parentheses (like `=+(a b)`)
1181−is the *normal* wide form. Hoon has a healthy variety of
1182−*irregular* wide forms, for which no principles at all apply. But
1183−using normal forms everywhere would get quite cumbersome.
1184−
1185−`I4`: Arvo
1186−----------
1187−
1188−`I4` is the source code for Arvo: about 600 lines of Hoon. This
1189−is excessive for what Arvo does and can probably be tightened. Of
1190−course, it does not include the kernel modules (or *vanes*).
1191−
1192−`I4` formally produces the kernel step function, `step` for `I0`.
1193−But in a practical computer, we don't run `I0`, and there are
1194−other things we want to do besides `step` it. Inside `step` is
1195−the Arvo core (leg 7, context), which does the actual work.
1196−
1197−Arvo's arms are `keep`, `peek`, `poke`, `wish`, `load`.
1198−
1199−`wish` compiles a Hoon string. `keep` asks Arvo when it wants to
1200−be woken up next. `peek` exposes the Arvo namespace. These three
1201−are formally unnecessary, but useful in practice for the Unix
1202−process that runs Arvo.
1203−
1204−The essential Arvo arm is `poke`, which produces a gate which
1205−takes as arguments the current time and an event. (Urbit time is
1206−a 128-bit atom, starting before the universe and ending after it,
1207−with 64 bits for subseconds and 64 bits for seconds, ignoring any
1208−post-2015 leap seconds.)
1209−
1210−The product of the `poke` gate is a cell `[action-list Arvo]`. So
1211−Arvo, poked with the time and an event, produces a list of
1212−actions and a new Arvo state.
1213−
1214−Finally, `load` is used to replace the Arvo core. When we want to
1215−change Hoon or Arvo proper, we build a new core with our new
1216−tools, then start it by passing `load` the old core's state.
1217−(State structures in the new core need not match the old, so the
1218−new core may need adapter functions.) `load` produces its new
1219−core wrapped in the canonical outer `step` function.
1220−
1221−Since the language certainly needs to be able to change, the
1222−calling convention to the next generation is a Nock convention.
1223−`load` is leg `54` of the core battery, producing a gate whose
1224−formal argument at leg `6` is replaced with the Arvo state, then
1225−applied to the formula at leg `2`. Of course, future cores can
1226−use a different upgrade convention. Nothing in Arvo or Urbit is
1227−technically frozen, except for Nock.
1228−
1229−State
1230−-----
1231−
1232−Arvo has three pieces of dynamic state: its network address, or
1233−*plot*; an entropy pool; the kernel modules, or *vanes*.
1234−
1235−Configuration overview
1236−----------------------
1237−
1238−The first main-sequence event, `I5`, is `[%init plot]`, with some
1239−unique Urbit address (*plot*) whose secrets this urbit controls.
1240−The plot, an atom under 2\^128, is both a routing address and a
1241−cryptographic name. Every Urbit event log starts by setting its
1242−own unique and permanent plot.
1243−
1244−From `I6` we begin to install the vanes: kernel modules. Vanes
1245−are installed (or reloaded) by a `[%veer label code]` event. Vane
1246−labels by convention are cords with zero or one letter.
1247−
1248−The vane named `%$` (zero, the empty string) is the standard
1249−library. This contains library functions that aren't needed in
1250−the Hoon kernel, but are commonly useful at a higher level.
1251−
1252−The standard library is compiled with the Hoon kernel (`I2`) as
1253−subject. The other vanes are compiled with the standard library
1254−(which now includes the kernel) as subject. Vane `%a` handles
1255−networking; `%c`, storage; `%f`, build logic; `%g`, application
1256−lifecycle; `%e`, http interface; `%d`, terminal interface; `%b`,
1257−timers; and `%j`, storage of secrets.
1258−
1259−Mechanics
1260−---------
1261−
1262−Vanes are stored as a cell of a noun with its span. At least in
1263−Urbit, there is no such thing as a dynamic type system - only a
1264−static type system executed at runtime.
1265−
1266−Storing vanes with their spans has two benefits. One, it lets us
1267−type-check internal event dispatch. Two, it lets us do typed
1268−upgrades when we replace a vane. It makes routine dispatch
1269−operations incur compiler cost, but this caches well.
1270−
1271−Input and output
1272−----------------
1273−
1274−From the Unix process's perspective, Arvo consumes events (which
1275−Unix generates) and produces actions (which Unix executes). The
1276−most common event is hearing a UDP packet; the most common action
1277−is sending a UDP packet. But Arvo also interacts (still in an
1278−event-driven pattern) with other Unix services, including HTTP,
1279−the console, and the filesystem.
1280−
1281−Events and actions share the `ovum` structure. An ovum is a cell
1282−`[wire card]`. A wire is a path - a list of cords, like
1283−`[%foo %bar %baz ~]`, usually written with the irregular syntax
1284−`/foo/bar/baz`. A card is a tagged union of all the possible
1285−types of events and effects.
1286−
1287−A wire is a *cause*. For example, if the event is an HTTP request
1288−`%thus`, the wire will contain (printed to cords) the server port
1289−that received the request, the IP and port of the caller, and the
1290−socket file descriptor.
1291−
1292−The data in the wire is opaque to Urbit. But an Urbit `poke`, in
1293−response to this event or to a later one, can answer the request
1294−with an action `%this` - an HTTP response. Unix parses the action
1295−wire it sent originally and responds on the right socket file
1296−descriptor.
1297−
1298−Moves and ducts
1299−---------------
1300−
1301−Event systems are renowned for "callback hell". As a purely
1302−functional environment, Arvo can't use callbacks with shared
1303−state mutation, a la node. But this is not the only common
1304−pitfall in the event landscape.
1305−
1306−A single-threaded, nonpreemptive event dispatcher, like node or
1307−Arvo, is analogous to a multithreaded preemptive scheduler in
1308−many ways. In particular, there's a well-known duality between
1309−event flow and control flow.
1310−
1311−One disadvantage of many event systems is unstructured event
1312−flow, often amounting to "event spaghetti". Indeed, the
1313−control-flow dual of an unstructured event system is `goto`.
1314−
1315−Arvo is a structured event system whose dual is a call stack. An
1316−internal Arvo event is called a "move". A move has a duct, which
1317−is a list a wires, each of which is analagous to a stack frame.
1318−Moves come in two kinds: a `%pass` move calls upward, pushing a
1319−frame to the duct, while a `%give` move returns a result
1320−downward, popping a frame off the duct.
1321−
1322−`%pass` contains a target vane name; a wire, which is a return
1323−pointer that defines this move's cause within the source vane;
1324−and a card, the event data. `%give` contains just the card.
1325−
1326−The product of a vane event handler is a cell
1327−`[moves new-state]`, a list of moves and the vane's new state.
1328−
1329−On receiving a Unix event, Arvo turns it into a `%pass` by
1330−picking a vane from the Unix wire (which is otherwise opaque),
1331−then pushes it on a move stack.
1332−
1333−The Arvo main loop pops a move off the move stack, dispatches it,
1334−replaces the result vane state, and pushes the new moves on the
1335−stack. The Unix event terminates when the stack is empty.
1336−
1337−To dispatch a `%pass` move sent by vane `%x`, to vane `%y`, with
1338−wire `/foo/bar`, duct `old-duct`, and card `new-card`, we pass
1339−`[[/x/foo/bar old-duct] new-card]`, a `[duct card]` cell, to the
1340−`call` method on vane `%y`. In other words, we push the given
1341−wire (adding the vane name onto the front) on to the old duct to
1342−create the new duct, and then pass that along with the card to
1343−the other vane.
1344−
1345−To dispatch a `%give` move returned by vane `%x`, we check if the
1346−duct is only one wire deep. If so, return the card as an action
1347−to Unix. If not, pull the original calling vane from the top wire
1348−on the duct (by destructuring the duct as
1349−`[[vane wire] plot-duct]`), and call the `take` method on `vane`
1350−with `[plot-duct wire card]`.
1351−
1352−Intuitively, a pass is a service request and a give is a service
1353−response. The wire contains the information (normalized to a list
1354−of strings) that the caller needs to route and process the
1355−service result. The effect always gets back to its cause.
1356−
1357−A good example of this mechanism is any internal service which is
1358−asynchronous, responding to a request in a different *system*
1359−event than its cause - perhaps many seconds later. For instance,
1360−the `%c` vane can subscribe to future versions of a file.
1361−
1362−When `%c` gets its service request, it saves it with the duct in
1363−a table keyed by the subscription path. When the future version
1364−is saved on this path, the response is sent on the duct it was
1365−received from. Again, the effect gets back to its cause.
1366−Depending on the request, there may even be multiple responses to
1367−the same request, on the same duct.
1368−
1369−In practice, the structures above are slightly simplified - Arvo
1370−manages both vanes and moves as vases, `[span noun]` cells. Every
1371−dispatch is type-checked.
1372−
1373−One card structure that Arvo detects and automatically unwraps is
1374−`[%meta vase]` - where the vase is the vase of a card. `%meta`
1375−can be stacked up indefinitely. The result is that vanes
1376−themselves can operate internally at the vase level - dynamically
1377−executing code just as Arvo itself does.
1378−
1379−The `%g` vane uses `%meta` to expose the vane mechanism to
1380−user-level applications. The same pattern, a core which is an
1381−event transceiver, is repeated across four layers: Unix, Arvo,
1382−the `%g` vane, and the `:dojo` shell application.
1383−
1384−Event security
1385−--------------
1386−
1387−Arvo is a "single-homed" OS which defines one plot, usually with
1388−the label `our`, as its identity for life. All vanes are fully
1389−trusted by `our`. But internal security still becomes an issue
1390−when we execute user-level code which is not fully trusted, or
1391−work with data which is not trusted.
1392−
1393−Our security model is causal, like our event system. Every event
1394−is a cause and an effect. Event security is all about *who/whom*:
1395−*who* (other than us) caused this event; *whom* (other than us)
1396−it will affect. `our` is always authorized to do everything and
1397−hear anything, so strangers alone are tracked.
1398−
1399−Every event has a security `mask` with two fields `who` and
1400−`hum`, each a `(unit (set plot))`. (A `unit` is the equivalent of
1401−Haskell's `Maybe` - `(unit x`) is either `[~ x]` or `~`, where
1402−`~` is nil.)
1403−
1404−If `who` is `~`, nil, anyone else could have caused this move --
1405−in other words, it's completely untrusted. If `who` is `[~ ~]`,
1406−the empty set, no one else caused this move -- it's completely
1407−trusted. Otherwise, the move is "tainted" by anyone in the set.
1408−
1409−If `hum` is `~`, nil, anyone else can be affected by this move --
1410−in other words, it's completely unfiltered. If `hum` is `[~ ~]`,
1411−the empty set, no one else can hear the move -- it's completely
1412−private. Otherwise, the move is permitted to "leak" to anyone in
1413−the set.
1414−
1415−Obviously, in most moves the security mask is propagated from
1416−cause to effect without changes. It's the exceptions that keep
1417−security exciting.
1418−
1419−Namespace
1420−---------
1421−
1422−Besides `call` and `take`, each vane exports a `scry` gate whose
1423−argument is a `path` - a list of strings, like a wire.
1424−
1425−`scry` implements a global monotonic namespace - one that (a)
1426−never changes its mind, for the lifetime of the urbit; and (b)
1427−never conflicts across well-behaved urbits.
1428−
1429−This invariant is semantic - it's not enforced by the type
1430−system. Getting it right is up to the vane's developer.
1431−Installing kernel modules is always a high-trust operation.
1432−
1433−The product of the `scry` gate is `(unit (unit value))`.
1434−
1435−So `scry` can produce `~`, meaning the path is not yet bound;
1436−`[~ ~]`, meaning the path is bound to empty; or `[~ ~ value]`, an
1437−actual value is bound. This value is of the form
1438−`[mark span noun]`, where `span` is the type of the noun and
1439−`mark` is a higher-level "type" label best compared to a MIME
1440−type or filename extension. Marks are discussed under the `%f`
1441−vane.
1442−
1443−Vane activation and namespace invariant
1444−---------------------------------------
1445−
1446−The vane that Arvo stores is not the core that exports `call`
1447−etc, but a gate that produces the core. The argument to this gate
1448−is a cell `[@da $+(path (unit (unit value)))]`. Note that
1449−`$+(path (unit (unit value)))` is just the function signature of
1450−the `scry` namespace.
1451−
1452−So, the head of the argument is the current time; the tail is the
1453−system namespace. The general namespace is constructed from the
1454−`scry` method of the vanes. The first letter of the head of the
1455−path identifies the vane; the rest of the head, with the rest of
1456−the path, is passed to the vane. The vane core is activated just
1457−this way for all its methods, including `scry` itself.
1458−
1459−This answers the question of how to expose dynamic state without
1460−violating our referential transparency invariants. If we require
1461−the query to include exactly the current time (which is
1462−guaranteed to change between events) in the path, then we are
1463−able to respond with the current state of the dynamic data. If
1464−the path doesn't contain the current time, then fail with
1465−`[~ ~]`. This technique is only needed, of course, when you don't
1466−know what the state was in the past.
1467−
1468−Additionally, since each vane knows the plot it's on, a `scry`
1469−query with the plot in the path is guaranteed to be globally
1470−unique.
1471−
1472−But vanes do not have to rely on these safe methods to maintain
1473−monotonicity - for instance, the `%c` revision-control vane binds
1474−paths around the network and across history.
1475−
1476−### A tour of the vanes
1477−
1478−The vanes are separately documented, because that's the entire
1479−point of vanes. Let's take a quick tour through the system as it
1480−currently stands, however.
1481−
1482−### `%a` `%ames`: networking
1483−
1484−`%a` is the network vane, currently `%ames` (2000 lines). `%ames`
1485−implements an encrypted P2P network over UDP packets.
1486−
1487−As a vane, `%ames` provides a simple `%pass` service: send a
1488−message to another plot. The message is an arbitrary
1489−`[wire noun]` cell: a message channel and a message body. `%ames`
1490−will respond with a `%give` that returns either success or
1491−failure and an error dump.
1492−
1493−`%ames` messages maintain causal integrity across the network.
1494−The sender does not send the actual duct that caused the message,
1495−of course, but an opaque atom mapped to it. This opaque `bone`,
1496−plus the channel itself, are the "socket" in the RFC sense.
1497−
1498−Messages are ordered within this socket and delivered exactly
1499−once. (Yes, as normally defined this is impossible. Urbit can do
1500−exactly-once because `%ames` messaging is not a tool to build a
1501−consistency layer, but a tool built on the consistency layer.
1502−Thus, peers can have sequence numbers that are never reset.)
1503−
1504−More subtly, local and remote causes treated are exactly the same
1505−way, improving the sense of network abstraction. CORBA taught us
1506−that it's not possible to abstract RPC over local function calls
1507−without producing a leaky abstraction. The Arvo structured event
1508−model is designed to abstract over messages.
1509−
1510−One unusual feature is that `%ames` sends end-to-end acks.
1511−Acknowledging the last packet received in a message acknowledges
1512−that the message itself has been fully accepted. There is no
1513−separate message-level result code. Like its vane interface,
1514−`%ames` acks are binary: a positive ack has no data, a negative
1515−ack has a dump. Thus, Arvo is transactional at the message level
1516−as well as the packet/event level.
1517−
1518−Another `%ames` technique is dropping packets. For instance, it
1519−is always a mistake to respond to a packet with bad encryption:
1520−it enables timing attacks. Any packet the receiver doesn't
1521−understand should be dropped. Either the sender is deranged or
1522−malicious, or the receiver will receive a future upgrade that
1523−makes a later retransmission of this packet make sense.
1524−
1525−Messages are encrypted in a simple PKI (currently RSA, soon
1526−curve/ed25519) and AES keys are exchanged. Certificate transfer
1527−and key exchange are aggressively piggybacked, so the first
1528−packet to a stranger is always signed but not encrypted. The idea
1529−is that if you've never talked to someone before, probably the
1530−first thing you say is "hello." Which is not interesting for any
1531−realistic attacker. In the rare cases where this isn't true, it's
1532−trivial for the application to work around. (See the network
1533−architecture section for more about the PKI approach.)
1534−
1535−(For packet geeks only: `%ames` implements both "STUN" and "TURN"
1536−styles of peer-to-peer NAT traversal, using parent plots (see
1537−below) as supernodes. If the sending plot lacks a current IP/port
1538−(Urbit uses random ports) for the destination, it forwards across
1539−the parent hierarchy. As we forward a packet, we attach the
1540−sender's address, in case we have a full-cone NAT that can do
1541−STUN.
1542−
1543−When these indirect addresses are received, they are regarded
1544−with suspicion, and duplicate packets are sent - one forwarded,
1545−one direct. Once a direct packet is received, the indirect
1546−address is dropped. Forwarding up the hierarchy always succeeds,
1547−because galaxies (again, see below) are bound into the DNS at
1548−`galaxy.urbit.org`.)
1549−
1550−### `%c` `%clay`: filesystem
1551−
1552−`%c` is the filesystem, currently `%clay` (3000 lines). `%clay`
1553−is a sort of simplified, reactive, typed `git`.
1554−
1555−The `%clay` filesystem uses a uniform inode structure, `ankh`. An
1556−ankh contains: a Merkle hash of this subtree, a set of named
1557−children, and possibly file data. If present, the file data is
1558−typed and marked (again, see the `%f` vane for more about marked
1559−data).
1560−
1561−A path within the tree always contains the plot and desk
1562−(lightweight branch) where the file is located, which version of
1563−the file to use, and what path within the desk the file is at.
1564−
1565−Paths can be versioned in three ways: by change number (for
1566−changes within this desk); by date; or by label.
1567−
1568−Where `git` has multiple parallel states, `%clay` uses separate
1569−desks. For instance, where `git` creates a special merge state,
1570−`%clay` just uses a normal scratch desk. Don't detach your head,
1571−merge an old version to a scratch desk. Don't have explicit
1572−commit messages, edit a log file. `%clay` is a RISC `git`.
1573−
1574−`%clay` is a typed filesystem; not only does it save a type with
1575−each file, but it uses `mark` services from `%f` to perform typed
1576−diff and patch operations that match the mark types. Obviously,
1577−Hunt-McIlroy line diff only works for text files. `%clay` can
1578−store and revise arbitrary custom data structures, not a
1579−traditional revision-control feature.
1580−
1581−The `scry` namespace exported by clay uses the mode feature to
1582−export different views of the filesystem. For instance,
1583−`[%cx plot desk version path]`, which passes `%x` as the mode to
1584−clay's `scry`, produces the file (if any) at that path. `%y`
1585−produces the directory, essentially - the whole ankh with its
1586−subtrees trimmed. `%z` produces the whole ankh.
1587−
1588−`%clay` is reactive; it exports a subscription interface, with
1589−both local and network access. A simple use is waiting for a file
1590−or version which has not yet been committed.
1591−
1592−A more complex use of `%clay` subscription is synchronization,
1593−which is actually managed at the user level within a `%gall`
1594−application (`:hood`). It's straightforward to set up complex,
1595−multistep or even cyclical chains of change propagation.
1596−Intuitively, `git` only pulls; `%clay` both pulls and pushes.
1597−
1598−Finally, the easiest way to use `%clay` is to edit files directly
1599−from Unix. `%clay` can mount and synchronize subtrees in the
1600−Urbit home directory. There are two kinds of mount: export and
1601−sync. While an export mount marks the Unix files read-only, sync
1602−mounts support "dropbox" style direct manipulation. The Unix
1603−process watches the subtree with `inotify()` or equivalent, and
1604−generates filesystem change events automagically. A desk which is
1605−synced with Unix is like your `git` working tree; a merge from
1606−this working desk to a more stable desk is like a `git` commit.
1607−
1608−Access control in `%clay` is an attribute of the desk, and is
1609−either a blacklist or whitelist of plots. Creating and
1610−synchronizing desks is easy enough that the right way to create
1611−complex access patterns is to make a desk for the access pattern,
1612−and sync only what you want to share into it.
1613−
1614−### `%f` `%ford`: builder
1615−
1616−`%f` is the functional build system, currently `%ford` (1800
1617−lines). It might be compared to `make` et al, but loosely.
1618−
1619−`%ford` builds things. It builds applications, resources, content
1620−type conversions, filter pipelines, more or less any functional
1621−computation specified at a high level. Also, it caches repeated
1622−computations and exports a dependency tracker, so that `%ford`
1623−users know when they need to rebuild.
1624−
1625−`%ford` does all its building and execution in the virtual Nock
1626−interpreter, `mock`. `mock` is a Nock interpreter written in
1627−Hoon, and of course executed in Nock. (See the implementation
1628−issues section for how this is practical.)
1629−
1630−`mock` gives us two extra affordances. One, when code compiled
1631−with tracing hints crashes deterministically, we get a
1632−deterministic stack trace. Two, we add a magic operator `11`
1633−(`.^` in Hoon) which dereferences the global namespace. This is
1634−of course referentially transparent, and `mock` remains a
1635−functional superset of Nock.
1636−
1637−`%ford` is passed one card, `[%exec silk]`, which specifies a
1638−computation - essentially, a makefile as a noun. The `silk`
1639−structure is too large to enumerate here, but some highlights:
1640−
1641−The simplest task of `%ford` is building code, by loading sources
1642−and resources from `%clay`. For kernel components, a source file
1643−is just parsed directly into a `twig`. `%ford` can do a lot of
1644−work before it gets to the `twig`.
1645−
1646−The Hoon parser for a `%ford` build actually parses an extended
1647−build language wrapped around Hoon. Keeping the build
1648−instructions and the source in one file precludes a variety of
1649−exciting build mishaps.
1650−
1651−For any interesting piece of code, we want to include structures,
1652−libraries, and data resources. Some of these requests should be
1653−in the same `beak` (plot/desk/version) as the code we're
1654−building; some are external code, locked to an external version.
1655−
1656−`%ford` loads code from `%clay` with a *role* string that
1657−specifies its use, and becomes the head of the spur. (Ie, the
1658−first path item after plot, desk and version.) Roles: structures
1659−are in `/sur`, libraries in `/lib`, marks in `/mar`, applications
1660−in `/app`, generators in `/gen`, fabricators in `/fab`, filters
1661−in `/tip`, and anything not a Hoon file in `/doc`.
1662−
1663−Data resources are especially interesting, because we often want
1664−to compile whole directory trees of resources into a single noun,
1665−a typed constant from the point of view of the programmer. Also,
1666−requests to `%clay` may block - `%ford` will have to delay giving
1667−its result, and wait until a subscription for the result returns.
1668−
1669−Moreover, for any interesting build, the builder needs to track
1670−dependencies. With every build, `%ford` exports a dependency key
1671−that its customers can subscribe to, so that they get a
1672−notification when a dependency changes. For example, `%gall` uses
1673−this feature to auto-reload applications.
1674−
1675−Finally, both for loading internal resources in a build and as a
1676−vane service (notably used by the web vane `%eyre`), `%ford`
1677−defines a functional namespace which is mapped over the static
1678−document space in `/doc`.
1679−
1680−If we request a resource from `%ford` that does not correspond to
1681−a file in `/doc`, we search in `/fab` for the longest matching
1682−prefix of the path. The fabricator receives as its sole argument
1683−that part of the path not part of the matching prefix.
1684−
1685−Thus, if we search for `/a/b/c/d`, and there's no `/doc/a/b/c/d`,
1686−then we first check for `/fab/a/b/c/d`, then `/fab/a/b/c`, and so
1687−on. If we find, for example, a `/fab/a/b`, then we run that
1688−fabricator with the argument `/c/d`. Thus, a fabricator can
1689−present an arbitrary virtual document tree.
1690−
1691−The `%ford` vane also exports its namespace through `scry`, but
1692−`scry` has no way to block if a computation waits. It will just
1693−produce `~`, binding unknown.
1694−
1695−Another major `%ford` feature is the mark system. While the Hoon
1696−type system works very well, it does not fill the niche that MIME
1697−types fill on the Internets. Marks are like MIME types, if MIME
1698−types came with with executable specifications which defined how
1699−to validate, convert, diff, and patch content objects.
1700−
1701−The mark `%foo` is simply the core built from `/mar/foo`. If
1702−there is no `/mar/foo`, all semantics are defaulted - `%foo` is
1703−treated as `%noun`. If there is a core, it can tell `%ford` how
1704−to validate/convert from other marks (validation is always
1705−equivalent to a conversion from `%noun`, and seldom difficult,
1706−since every Hoon structure is defined as a fixpoint normalizer);
1707−convert *to* other marks; patch, diff, and merge. Obviously
1708−`%clay` uses these revision control operations, but anyone can.
1709−
1710−For complex conversions, `%ford` has a simple graph analyzer that
1711−can convert, or at least try to convert, any source mark to any
1712−target mark.
1713−
1714−There are two ford request modes, `%c` and `%r` - cooked and raw.
1715−A cooked request, `%fc` in `scry`, has a target mark and converts
1716−the result to it. A raw request, `%fr`, returns whatever `%ford`
1717−finds easiest to make.
1718−
1719−Generators and filters, `/gen` and `/tip`, are actually not used
1720−by any other vane at present, but only by the user-level `:dojo`
1721−app, which constructs dataflow calculations in Unix pipe style.
1722−Applications, `/app`, are used only by the `%g` vane.
1723−
1724−### `%g` `%gall`: application driver
1725−
1726−`%g` is the application system, currently `%gall` (1300 lines)
1727−`%gall` is half process table and half systemd, sort of.
1728−
1729−`%gall` runs user-level applications much as Arvo runs vanes. Why
1730−this extra layer? Vanes are kernel components written by kernel
1731−hackers, for whom expressiveness matters more than convenience. A
1732−bad kernel module can disable the OS; a bad application has to be
1733−firewalled.
1734−
1735−But the basic design of an application and a vane is the same: a
1736−stateful core that's called with events and produces moves. Only
1737−the details differ, and there are too many to cover here.
1738−
1739−One example is that `%gall` apps don't work with Arvo ducts
1740−directly, but opaque integers that `%gall` maps to ducts; the
1741−consequences of a bad app making a bad duct would be odd and
1742−potentially debilitating, so we don't let them touch ducts
1743−directly. Also, `%gall` does not like to crash, so to execute
1744−user-level code it uses the virtual interpeter `mock`. At the
1745−user level, the right way to signal an error is to crash and let
1746−`%gall` pick up the pieces - in a message handler, for instance,
1747−this returns the crash dump in a negative ack.
1748−
1749−`%gall` uses `%ford` to build cores and track dependencies. Like
1750−vanes, `%gall` applications update when new code is available,
1751−sometimes using adapter functions to translate old state types to
1752−new ones. Unlike Arvo, `%gall` triggers updates automatically
1753−when a dependency changes.
1754−
1755−Other than convenience and sanity checks, the principal value add
1756−of `%gall` is its inter-application messaging protocol. `%gall`
1757−messaging supports two communication patterns: a one-way message
1758−with a success/error result (`%poke`), and classic publish and
1759−subscribe (`%peer`).
1760−
1761−`%peer` is designed for synchronizing state. The subscriber
1762−specifies a path which defines an application resource, and
1763−receives a stream of `%full` and `%diff` cards, total and
1764−incremental updates. (A simple "get" request is a special case in
1765−which there is a single full and no diffs.) Backpressure breaks
1766−the subscription if the queue of undelivered updates grows too
1767−deep. Broken subscriptions should not cause user-level errors;
1768−the user should see an error only if the subscription can't be
1769−reopened.
1770−
1771−Recall that `%ames` routes messages which are arbitrary nouns
1772−between vanes on different urbits. `%gall` uses these `%ames`
1773−messages for remote urbits, and direct moves for local IPC. Thus,
1774−from the app's perspective, messaging an app on another Urbit is
1775−the same as messaging another app on the same Urbit. The
1776−abstraction does not leak.
1777−
1778−Messages are untyped at the `%ames` level, but all `%gall`
1779−messages carry a mark and are validated by the receiver. Marks
1780−are not absolute and timeless - `%ford` needs a `beak` (plot,
1781−desk, version) to load the mark source.
1782−
1783−When a message fails to validate, the packet is dropped silently.
1784−This puts the sender into exponential backoff retransmission. The
1785−general cause of a message that doesn't validate is that the
1786−sender's mark has received a backward-compatible update (mark
1787−updates that aren't backward compatible are a bad idea - use a
1788−new name), and the receiver doesn't have this update yet. The
1789−retransmitted packet will be processed correctly once the update
1790−has propagated.
1791−
1792−With this mechanism, Urbit can update a distributed system (such
1793−as our own `:talk` network), upgrading both applications and
1794−protocols, silently without user intervention or notification.
1795−The general pattern of application distribution is that the app
1796−executes from a local desk autosynced to a remote urbit, which
1797−performs the function of an app store or distro. As this server
1798−fills its subscriptions, a period of network heterogeneity is
1799−inevitable; and so is transient unavailability, as new versions
1800−try to talk to old ones. But it resolves without hard errors as
1801−all clients are updated.
1802−
1803−### `%e` `%eyre`: web server/client
1804−
1805−`%e` is the web system, currently `%eyre` (1600 lines).
1806−
1807−`%eyre` has three purposes. First, it is an HTTP and HTTPS
1808−client - or rather, it interfaces via actions/events to HTTP
1809−client handlers in the Unix layer.
1810−
1811−Second, `%eyre` serves the `%ford` namespace over HTTP. The URL
1812−extension is parsed as a mark, but the default mark for requests
1813−is `urb`, which creates HTML and injects an autoupdate script
1814−that long-polls on the dependencies, reloading the page in the
1815−background when they change.
1816−
1817−The normal way of publishing static or functional content in
1818−Urbit is to rely on `%ford` for format translation. Most static
1819−content is in markdown, the `%md` mark. Dynamic content is best
1820−generated with the `sail` syntax subsystem in Hoon, which is is
1821−essentially an integrated template language that reduces to XML.
1822−
1823−Third, `%eyre` acts as a client for `%gall` apps, translating the
1824−`%gall` message flow into JSON over HTTP. `%poke` requests become
1825−POST requests, `%peer` becomes a long-poll stream. Our `urb.js`
1826−framework is a client-side wrapper for these requests.
1827−
1828−The abstraction does not leak. On the server side, all it takes
1829−to support web clients is ensuring that outbound marks print to
1830−`%json` and inbound marks parse from `%json`. (The standard
1831−library includes JSON tools.) The `%gall` application does not
1832−even know it's dealing with a web client, all it sees are
1833−messages and subscriptions, just like it would receive from
1834−another Urbit app.
1835−
1836−The dataflow pattern of `%gall` subscriptions is ideal for React
1837−and similar "one-way data binding" client frameworks.
1838−
1839−Of course, `%gall` apps expect to be talking to an urbit plot, so
1840−web clients need to (a) identify themselves and (b) talk over
1841−HTTPS. `%eyre` contains a single sign-on (SSO) flow that
1842−authenticates an urbit user either to her own server or her
1843−friends'.
1844−
1845−Ideally, an urbit named `~plot` is DNSed to `plot.urbit.org`. If
1846−you use your urbit through the web, you'll have an insecure
1847−cookie on `*.urbit.org`. Other urbits read this and drive the SSO
1848−flow; if you're `~tasfyn-partyv`, you can log in as yourself to
1849−`~talsur-todres.urbit.org`. The SSO confirmation message is sent
1850−directly as an `%ames` message between the `%eyre` vanes on the
1851−respective urbits.
1852−
1853−Urbit also has an nginx configuration and node cache server,
1854−which (a) let a relatively slow Urbit server drive reasonably
1855−high request bandwidth, and (b) serve HTTPS by proxy.
1856−
1857−Note that while external caching helps `%ford` style functional
1858−publishing, it does not help `%gall` style clients, which use
1859−server resources directly. Urbit is a personal server; it can
1860−handle an HN avalanche on your blog, but it's not designed to
1861−power your new viral startup.
1862−
1863−### `%j` `%jael`: secret storage
1864−
1865−`%j`, currently `%jael` (200 lines), saves secrets in a tree.
1866−Types of secrets that belong in `%jael`: Urbit private keys,
1867−Urbit symmetric keys, web API user keys and/or passwords, web API
1868−consumer (application) keys.
1869−
1870−`%jael` has no fixed schema and is simply a classic tree
1871−registry. Besides a simpler security and type model, the main
1872−difference between secrets and ordinary `%clay` data is that
1873−secrets expire - sometimes automatically, sometimes manually.
1874−When another vane uses a `%jael` secret, it must register to
1875−receive an expiration notice.
1876−
1877−### `%d` `%dill`: console and Unix
1878−
1879−`%d`, currently `%dill` (450 lines) handles the terminal and
1880−miscellaneous Unix interfaces, mainly for initialization and
1881−debugging.
1882−
1883−The console terminal abstraction, implemented directly with
1884−`terminfo` in raw mode, gives Urbit random-access control over
1885−the input line. Keystrokes are not echoed automatically. Output
1886−lines are write-only and appear above the input line.
1887−
1888−`%dill` also starts default applications, measures system memory
1889−consumption, dumps error traces, etc.
1890−
1891−### `%b` `%behn`: timers
1892−
1893−`%b`, currently `%behn` (250 lines), is a timer vane that
1894−provides a simple subscription service to other vanes.
1895−
1896−Base applications
1897−-----------------
1898−
1899−Arvo ships with three major default applications: `:hood` (1600
1900−lines), `:dojo` (700 lines), and `:talk` (1600 lines).
1901−
1902−### `:dojo`: a shell
1903−
1904−`:dojo` is a shell for ad-hoc computation. A dojo command is a
1905−classic filter pipeline, with sources, filters, and sinks.
1906−
1907−Sources can be shell variables, `%clay` files, immediate
1908−expressions, source files in `/gen`, or uploads (Unix files in
1909−`~/urbit/$plot/.urb/get`). There are three kinds of generator:
1910−simple expressions, dialog cores, and web scrapers. Generators
1911−are executed by `%ford` through `mock`, and can read the Urbit
1912−namespace via virtual operator `11`.
1913−
1914−Urbit does not use short-lived applications like Unix commands. A
1915−`%gall` application is a Unix daemon. A generator is not like a
1916−Unix process at all; it cannot send moves. A dialog generator,
1917−waiting for user input, does not talk to the console; it tells
1918−`:dojo` what to say to the console. A web scraper does not talk
1919−to `%eyre`; it tells `:dojo` what resources it needs (GET only).
1920−This is POLA (principle of least authority); it makes the command
1921−line less powerful and thus less scary.
1922−
1923−`:dojo` filters are immediate expressions or `/tip` source files.
1924−Sinks are console output, shell variables, `%clay`, or downloads
1925−(Unix files in `~/urbit/$plot/.urb/put`). (The upload/download
1926−mechanism is a console feature, not related to `%clay` sync -
1927−think of browser uploading and downloading.)
1928−
1929−### `:talk`: a communication bus
1930−
1931−`:talk` is a distributed application for sharing *telegrams*, or
1932−typed social messages. Currently we use `:talk` as a simple chat
1933−service, but telegram distribution is independent of type.
1934−
1935−Every urbit running `:talk` can create any number of "stations."
1936−Every telegram has a unique id and a target audience, to which
1937−its sender uploads it. But `:talk` stations also subscribe to
1938−each other to construct feeds.
1939−
1940−Mutually subscribing stations will mirror, though not preserving
1941−message order. A `:talk` station is not a decentralized entity;
1942−but urbits can use subscription patterns to federate into
1943−"global" stations - very much as in NNTP (Usenet).
1944−
1945−Stations have a flexible admission control model, with a blanket
1946−policy mode and an exception list, that lets them serve as
1947−"mailboxes" (public write), "journals" (public read), "channels"
1948−(public read/write), or "chambers" (private read/write).
1949−
1950−Subscribers are also notified of presence and configuration
1951−changes, typing indicator, etc. Also, telegrams contain a
1952−"flavor", which senders can use to indicate categories of content
1953−that other readers may prefer not to see.
1954−
1955−`:talk` is usable both a command-line application and a reactive
1956−web client.
1957−
1958−### `:hood`: a system daemon
1959−
1960−`:hood` is a classic userspace system daemon, like Unix `init`.
1961−It's a system component, but it's in userspace because it can be.
1962−
1963−`:hood` is actually a compound application made of three
1964−libraries, `/helm`, `/drum`, and `/kiln`. `/helm` manages the
1965−PKI; `/drum` multiplexes the console; `/kiln` controls `%clay`
1966−sync.
1967−
1968−`/drum` routes console activity over `%gall` messages, and can
1969−connect to both local and foreign command-line interfaces - ssh,
1970−essentially.
1971−
1972−One pattern in Urbit console input is that an application doesn't
1973−just parse its input after a line is is entered, but on each
1974−character. This way, we can reject or correct syntax errors as
1975−they happen. It's a much more pleasant user experience.
1976−
1977−But since both sides of a conversation (the user and the
1978−application) are making changes to a single shared state (the
1979−input line), we have a reconciliation problem. The Urbit console
1980−protocol uses operational transformation (like Google Wave or
1981−`git replot`) for eventual consistency.
1982−
1983−`/helm` manages public keys and (in future) hosted urbits. See
1984−the network architecture section below.
1985−
1986−`/kiln` implements mirroring and synchronization. Any desk can
1987−mirror any other desk (given permission). Mirrors can form
1988−cycles -- a two-way mirror is synchronization.
1989−
1990−Implementation issues
1991−---------------------
1992−
1993−We've left a couple of knotty implementation issues unresolved up
1994−until now. Let's resolve them.
1995−
1996−### Jets
1997−
1998−How can an interpreter whose only arithmetic operator is
1999−increment compute efficiently? For instance, the only way to
2000−decrement `n` is to count up to `n - 1`, which is O(n).
2001−
2002−Obviously, the solution is: a sufficiently smart optimizer.
2003−
2004−A sufficiently smart optimizer doesn't need to optimize every
2005−Nock formula that could calculate a decrement function. It only
2006−needs to optimize one: the one we actually run.
2007−
2008−The only one we run is the one compiled from the decrement
2009−function `dec` in the Hoon standard library. So there's no sense
2010−in which our sufficiently smart optimizer needs to *analyze* Nock
2011−formulas to see if they're decrement formulas. It only needs to
2012−*recognize* the standard `dec`.
2013−
2014−The easiest way to do this is for the standard `dec` to declare,
2015−with a hint (Nock `10`), in some formalized way, that it is a
2016−decrement formula. The interpreter implementation can check this
2017−assertion by simple comparison - it knows what formula the
2018−standard `dec` compiles to. Our sufficiently smart optimizer
2019−isn't very smart at all!
2020−
2021−The C module that implements the efficient decrement is called a
2022−"jet." The jet system should not be confused with an FFI: a jet
2023−has *no* reason to make system calls, and should never be used to
2024−produce side effects. Additionally, a jet is incorrect unless it
2025−accurately duplicates an executable specification (the Hoon
2026−code). Achieving jet correctness is difficult, but we can
2027−spot-check it easily by running both soft and hard versions.
2028−
2029−Jets separate mechanism and policy in Nock execution. Except for
2030−perceived performance, neither programmer nor user has any
2031−control over whether any formula is jet-propelled. A jet can be
2032−seen as a sort of "software device driver," although invisible
2033−integration of exotic hardware (like FPGAs) is another use case.
2034−And jets do not have to be correlated with built-in or low-level
2035−functionality; for instance, Urbit has a markdown parser jet.
2036−
2037−Jets are of course the main fail vector for both computational
2038−correctness and security intrusion. Fortunately, jets don't make
2039−system calls, so sandboxing policy issues are trivial, but the
2040−sandbox transition needs to be very low-latency. Another approach
2041−would be a safe systems language, such as Rust.
2042−
2043−The correctness issue is more interesting, because errors happen.
2044−They are especially likely to happen early in Urbit's history. A
2045−common scenario will be that the host audits an urbit by
2046−re-executing all the events, and produces a different state. In
2047−this case, the urbit must become a "bastard" - logically
2048−instantiated at the current state. The event log is logically
2049−discarded as meaningless. Hosting a bastard urbit is not a huge
2050−problem, but if you have one you want to know.
2051−
2052−In the long run, jet correctness is an excellent target problem
2053−for fuzz testers. A sophisticated implementation might even put
2054−10% of runtime into automatic jet testing. While it's always hard
2055−for implementors to match a specification perfectly, it's much
2056−easier with an executable specification that's only one or two
2057−orders of magnitude slower.
2058−
2059−### Event planning
2060−
2061−How do we actually process Urbit events? If Urbit is a database,
2062−how does our database execute and maintain consistency in
2063−practice, either on a personal computer or a normal cloud server?
2064−How does orthogonal persistence work? Can we use multiple cores?
2065−
2066−An event is a transaction. A transaction either completes or
2067−doesn't, and we can't execute its side effects until we have
2068−committed it. For instance, if an incoming packet causes an
2069−outgoing packet, we can't send the outgoing packet until we've
2070−committed the incoming one to durable storage.
2071−
2072−Unfortunately, saving even a kilobyte of durable storage on a
2073−modern PC, with full write-through sync, can take 50 to 100ms.
2074−Solid-state storage improves this, but the whole machine is just
2075−not designed for low-latency persistence.
2076−
2077−In the cloud the situation is better. We can treat consensus on a
2078−nontrivial Raft cluster in a data center as persistence, even
2079−though the data never leaves RAM. Urbit is highly intolerant of
2080−computation error, for obvious reasons, and should be run in an
2081−EMP shielded data center on ECC memory.
2082−
2083−There are a number of open-source reliable log processors that
2084−work quite well. We use Apache Kafka.
2085−
2086−With either logging approach, the physical architecture of an
2087−Urbit implementation is clear. The urbit is stored in two forms:
2088−an event log, and a checkpoint image (saved periodically, always
2089−between events). The log can be pruned at the last reliably
2090−recorded checkpoint, or not. This design (sometimes called
2091−"prevalence") is widely used and supported by common tools.
2092−
2093−The checkpointing process is much easier because Urbit has no
2094−cycles and needs no tracing garbage collector. Without careful
2095−tuning, a tracing GC tends to turn all memory available to it
2096−into randomly allocated memory soup. The Urbit interpreter uses a
2097−region system with a copy step to deallocate the whole region
2098−used for processing each event.
2099−
2100−Events don't always succeed. How does a functional operating
2101−system deal with an infinite loop? The loop has to be
2102−interrupted, as always. How this happens depends on the event. If
2103−the user causes an infinite loop from a local console event, it's
2104−up to the user to interrupt it with \^C. Network packets have a
2105−timeout, currently a minute.
2106−
2107−When execution fails, we want a stack trace. But Urbit is a
2108−deterministic computer and the stack trace of an interrupt is
2109−inherently nondeterministic. How do we square this circle?
2110−
2111−Urbit is deterministic, but it's a function of its input. If an
2112−event crashes, we don't record the event in `I`. Instead, we
2113−record a `%crud` card that contains the stack trace and the
2114−failed event. To Urbit, this is simply another external event.
2115−
2116−Processing of `%crud` depends on the event that caused it. For
2117−keyboard input, we print the error to the screen. For a packet,
2118−we send a negative ack on the packet, with the trace. For
2119−instance, if you're at the console of urbit `A` and logged in
2120−over the network to `B`, and you run an infinite loop, the `B`
2121−event loop will time out; the network console message that `A`
2122−sent to `B` will return a negative ack; the console application
2123−on `A` will learn that its message failed, and print the trace.
2124−
2125−Finally, the possibilities of aggressive optimization in event
2126−execution haven't been explored. Formally, Urbit is a serial
2127−computer - but it's probable that a sophisticated, mature
2128−implementation would find a lot of ways to cheat. As always, a
2129−logically simple system is the easiest system to hack for speed.
2130−
2131−Network and PKI architecture
2132−----------------------------
2133−
2134−Two more questions we've left unanswered: how you get your urbit
2135−plot, and how packets get from one plot to another.
2136−
2137−Again, a plot is both a digital identity and a routing address.
2138−Imagine IPv4 if you owned your own address, converted it to a
2139−string that sounded like a foreign name, and used it as your
2140−Internet handle.
2141−
2142−Bases are parsed and printed with the `%p` aura, which is
2143−designed to make them as human-memorable as possible. `%p` uses
2144−phonemic plot-256 and renders smaller plots as shorter strings:
2145−
2146− 8 bits galaxy ~syd
2147− 16 bits star ~delsym
2148− 32 bits planet ~mighex-forfem
2149− 64 bits moon ~dabnev-nisseb-nomlec-sormug
2150− 128 bits comet ~satnet-rinsyr-silsec-navhut--bacnec-todmeb-sarseb-pagmul
2151−
2152−Of course, not everyone who thinks he's Napoleon is. For the
2153−urbit to actually send and receive messages under the plot it
2154−assigns itself in the `%init` event (`I5`), later events must
2155−convey the secrets that authenticate it. In most cases this means
2156−a public key, though some urbits are booted with a symmetric
2157−session key that only works with the parent plot.
2158−
2159−How do you get a plot? Comets are hashes of a random public key.
2160−"Civil" non-comets are issued by their parent plot - the
2161−numerical prefix in the next rank up: moons by planet, planets by
2162−star, stars by galaxy. The fingerprints of the initial galactic
2163−public keys (currently test keys) are hardcoded in `%ames`.
2164−
2165−The comet network is fully decentralized and "free as in beer,"
2166−so unlikely to be useful. Any network with disposable identities
2167−can only be an antisocial network, because disposable identities
2168−cannot be assigned default positive reputation. Perhaps comets
2169−with nontrivial hashcash in their plots could be an exception,
2170−but nonmemorable plots remain a serious handicap.
2171−
2172−The civil network is "semi-decentralized" - a centralized system
2173−designed to evolve into a decentralized one. Urbit does not use a
2174−blockchain - address space is digital land, not digital money.
2175−
2176−The initial public key of a civil plot is signed by its parent.
2177−But galaxies, stars and planets are independent once they've been
2178−created - they sign their own updates. (Moons are dependent;
2179−their planet signs updates.)
2180−
2181−The certificate or `will` is a signing chain; only the last key
2182−is valid; longer wills displace their prefixes. Thus update is
2183−revocation, and revocation is a pinning race. To securely update
2184−a key is to ensure that the new will reaches any peer before any
2185−messages signed by an attacker who has stolen the old key.
2186−
2187−The engineering details of this race depend on the actual threat
2188−model, which is hard to anticipate. If two competing parties have
2189−the same secret, no algorithm can tell who is in the right. Who
2190−pins first should win, and there will always be a time window
2191−during which the loser can cause problems. Aggressively flooding
2192−and expiring certificates reduces this window; caching and lazy
2193−distribution expands it. There is no tradeoff-free solution.
2194−
2195−Broadly, the design difference between Urbit and a blockchain
2196−network is that blockchains are "trust superconductors" - they
2197−eliminate any dependency on social, political or economic trust.
2198−Urbit is a "trust conductor" - engineered to minimize, but not
2199−eliminate, dependencies on trust.
2200−
2201−For instance, bitcoin prevents double-spending with global mining
2202−costs in multiple dollars per transaction (as of 2015). Trusted
2203−transaction intermediation is an easily implemented service whose
2204−cost is a tiny fraction of this. And the transaction velocity of
2205−money is high; transactions in land are far more rare.
2206−
2207−Another trust engineering problem in Urbit is the relationship
2208−between a plot and its parent hierarchy. The hierarchy provides a
2209−variety of services, starting with peer-to-peer routing. But
2210−children need a way to escape from bad parents.
2211−
2212−Urbit's escape principle: (a) any planet can depend on either its
2213−star's services, or its galaxy's; (b) any star can migrate to any
2214−galaxy; (c) stars and galaxies should be independently and
2215−transparently owned.
2216−
2217−Intuitively, an ordinary user is a planet, whose governor is its
2218−star, and whose appeals court is its galaxy. Since a star or
2219−galaxy should have significant reputation capital, it has an
2220−economic incentive to follow the rules. The escape system is a
2221−backup. And the comet network is a backup to the backup.
2222−
2223−From a privacy perspective, a planet is a personal server; a star
2224−or galaxy is a public service. Planet ownership should be private
2225−and secret; star or galaxy ownership should be public and
2226−transparent. Since, for the foreseeable future, individual
2227−planets have negligible economic value, Urbit is not a practical
2228−money-laundering tool. This is a feature, not a bug.
2229−
2230−Finally, a general principle of both repositories and republics
2231−is that the easier it is (technically) to fork the system, the
2232−harder it is (politically) to fork. Anyone could copy Urbit and
2233−replace the galactic fingerprint block. Anyone can also fork the
2234−DNS. If the DNS was mismanaged badly enough, someone could and
2235−would; since it's competently managed, everyone can't and won't.
2236−Forkability is an automatic governance corrector.
2237−
2238−From personal server to digital republic
2239−----------------------------------------
2240−
2241−Republics? Any global system needs a political design. Urbit is
2242−designed as a *digital republic*.
2243−
2244−The word *republic* is from Latin, "res publica" or "public
2245−thing." The essence of republican goverment is its
2246−*constitutional* quality - government by law, not people.
2247−
2248−A decentralized network defined by a deterministic interpreter
2249−comes as close to a digital constitution as we can imagine. Urbit
2250−is not the only member of this set - bitcoin is another; ethereum
2251−is even a general-purpose computer.
2252−
2253−The "law" of bitcoin and ethereum is self-enforcing; the "law" of
2254−Urbit is not. Urbit is not a blockchain, and no urbit can assume
2255−that any other urbit is computing the Nock function correctly.
2256−
2257−But at least the distinction between correct and incorrect
2258−computing is defined. In this sense, Nock is Urbit's
2259−constitution. It's not self-enforcing like Ethereum, but it's
2260−exponentially more efficient.
2261−
2262−Non-self-verifying rules are useful, too. Defining correctness is
2263−not enforcing correctness. But Urbit doesn't seek to eliminate
2264−its dependency on conventional trust. Correctness precisely
2265−defined is easily enforced with social tools: either the
2266−computation is tampered with or it isn't.
2267−
2268−Conclusion
2269−==========
2270−
2271−On the bottom, Urbit is an equation. In the middle it's an
2272−operating system. On the top it's a civilization -- or at least,
2273−a design for one.
2274−
2275−When we step back and look at that civilization, what we see
2276−isn't that surprising. It's the present that the past expected.
2277−The Internet is what the Arpanet of 1985 became; Urbit is what
2278−the Arpanet of 1985 wanted to become.
2279−
2280−In 1985 it seemed completely natural and inevitable that, by
2281−2015, everyone in the world would have a network computer. Our
2282−files, our programs, our communication would all go through it.
2283−
2284−When we got a video call, our computer would pick up. When we had
2285−to pay a bill, our computer would pay it. When we wanted to
2286−listen to a song, we'd play a music file on our computer. When we
2287−wanted to share a spreadsheet, our computer would talk to someone
2288−else's computer. What could be more obvious? How else would it
2289−work?
2290−
2291−(We didn't anticipate that this computer would live in a data
2292−center, not on our desk. But we didn't appreciate how easily a
2293−fast network can separate the server from its UI.)
2294−
2295−2015 has better chips, better wires, better screens. We know what
2296−the personal cloud appliance does with this infrastructure. We
2297−can imagine our 1985 future ported to it. But the most
2298−interesting thing about our planets: we don't know what the world
2299−will do with them.
2300−
2301−There's a qualitative difference between a personal appliance and
2302−a personal server; it's the difference between a social "network"
2303−and a social network. A true planet needs to work very hard to
2304−make social programming easier. Still, distributed social
2305−applications and centralized social applications are just
2306−different. A car is not a horseless carriage.
2307−
2308−We know one thing about the whole network: by default, a social
2309−"network" is a monarchy. It has one corporate dictator, its
2310−developer. By default, a true network is a republic; its users
2311−govern it. And more important: a distributed community cannot
2312−coerce its users. Perhaps there are cases where monarchy is more
2313−efficient and effective -- but freedom is a product people want.
2314−
2315−But no product is inevitable. Will we even get there? Will Urbit,
2316−or any planet, or any personal cloud server, actually happen?
2317−
2318−It depends. The future doesn't just happen. It happens,
2319−sometimes. When people work together to make it happen.
2320−Otherwise, it doesn't.
2321−
2322−The Internet didn't scale into an open, high-trust network of
2323−personal servers. It scaled into a low-trust network that we use
2324−as a better modem -- to talk to walled-garden servers that are
2325−better AOLs. We wish it wasn't this way. It is this way.
2326−
2327−If we want the network of the future, even the future of 1985,
2328−someone has to build it. Once someone's built it, someone else
2329−has to move there. Otherwise, it won't happen.
2330−
2331−And for those early explorers, the facilities will be rustic. Not
2332−at all what you're used to. More 1985 than 2015, even. These
2333−"better AOLs", the modern online services that are our personal
2334−appliances, are pretty plush in the feature department.
2335−
2336−Could they just win? Easily. Quite easily. It's a little painful
2337−herding multiple appliances, but the problem is easily solved by
2338−a few more corporate mergers. We could all just have one big
2339−appliance. If nothing changes, we will.
2340−
2341−To build a new world, we need the right equation and the right
2342−pioneers. Is Urbit the right equation? We think so. Check our
2343−work, please. Are you the right pioneer? History isn't over --
2344−it's barely gotten started.
2345−
2346−</div>
2347−
docs/user.mddeleted−25
@@ -1,25 +0,0 @@
1−---
2−logo: black
3−sort: 1
4−title: User doc
5−---
6−
7−<div class="short">
8−
9−# User documentation
10−
11−Read the [introduction](user/intro) for a summary of Urbit.
12−The [installation guide](user/install) gets you ready to run.
13−Launch with [basic operation](user/basic) and get a feel for the
14−system. Once your urbit is live, the [walking tour](user/tour)
15−shows how to do some common tasks.
16−
17−For power users, the [appliance handbook](user/appliance) explains
18−your apps and how to control them. The [filesystem handbook](user/clay)
19−explains the Urbit filesystem and how to sync it with Unix.
20−Finally, the [:dojo manual](user/dojo) and [:talk manual](user/talk)
21−explore the fine points of our shell and messenger respectively.
22−
23−<list dataSort="true"></list>
24−
25−</div>
docs/user/launch.mddeleted−112
@@ -1,112 +0,0 @@
1−---
2−hide: true
3−next: true
4−sort: 10
5−title: Launch
6−---
7−
8−# Launch procedure
9−
10−An urbit is a persistent server on the Urbit P2P network.
11−You'll create one of these servers now. To understand what
12−you're building, you need to know a little about the network.
13−
14−## Launch instructions
15−
16−If you have an invitation, it's a planet like `~fintud-macrep`
17−and a ticket like `~fortyv-tombyt-tabsen-sonres`. Run
18−
19− urbit -w fintud-macrep -t fortyv-tombyt-tabsen-sonres
20−
21−(You can leave the `~` on, but it annoys some Unix shells.)
22−
23−If you don't have an invitation, pick a nickname for your comet,
24−like `mycomet`. Urbit will randomly generate a 128-bit plot:
25−
26− urbit -c mycomet
27−
28−Either way, creating your urbit will take some time. Some of
29−this time involves creating keys; some of it involves downloading
30−code over Urbit itself. Go get a cup of coffee, and/or absorb
31−the miscellaneous true facts below:
32−
33−## Network architecture
34−
35−An Urbit address is a number, or *plot*, under 2^128. Every
36−server on the Urbit network has one unique plot.
37−
38−Since Urbit is designed as a personal server, a plot is both a
39−network address and a digital identity. There is no additional
40−human-meaningful name layer like the DNS. Plots will never be
41−meaningful; but to make them as memorable as possible, we type
42−them in a phonemic syntax with one byte per syllable, like
43−`~harlyx-rocsev` for `0x510b.9441`.
44−
45−Urbit address space is cryptographic property, like Bitcoin, but
46−Urbit doesn't use a blockchain. Plots are digital land, not
47−digital currency; you own your urbit cryptographically, but you
48−don't get it by mining. In land, transfers are infrequent and
49−not frictionless. (Right now, all keys are test keys, and there
50−are no transfers, only initial invitations.)
51−
52−Urbit is semi-decentralized: it overlays a 64-bit hierarchical
53−structure on the low end of a 128-bit fingerprint namespace. If
54−you have an invitation, it's a *ticket* that lets you create a
55−32-bit plot, aka *planet*. If you don't have an invitation, you
56−have to create a 128-bit plot, aka *comet*.
57−
58−As a comet, you're not necessarily a bad person. But you could
59−be anyone, so you have zero reputation. You have no official
60−access to any Urbit services. Any connectivity you may enjoy
61−could be shut off at any time, and it probably will be. If the
62−Internet has proven one thing, it's that positive default
63−reputation and effectively infinite number of identities don't mix.
64−
65−## Substrate interactions
66−
67−Urbit doesn't run on bare chips and wires, at least not at
68−present. It runs as a Unix process and sends UDP packets.
69−
70−Since Urbit is a P2P network that runs over random UDP ports,
71−some firewalls may not like it. Urbit without connectivity still
72−works as an interpreter, but it can't launch without the network.
73−
74−If run as `root`, the `urbit` process can only read and write
75−inside the `fintud-macrep` or `mycomet` directory, which we call
76−your *pier*. A pier is portable; any Urbit install on any OS can
77−execute the same pier. (But don't *ever* run the same pier or
78−plot on two computers at once.)
79−
80−In the pier directory is a set of user-level mount points. Mount
81−points are synced Dropbox style, with Unix file changes
82−autocommitted to the Urbit revision control system (`%clay`) and
83−vice versa. (Urbit does not have its own editor -- you edit
84−Urbit code either with an Unix editor on a mounted file, or with
85−a Web editor from your browser.)
86−
87−Also within the pier is a system directory, `.urb/`, which
88−contains an event log (`egz.hope`), a checkpoint (`.chk`), and
89−I/O directories for uploads and downloads (`put` and `get`).
90−You can compact the pier by deleting the checkpoint, although
91−that means Urbit needs to re-execute its entire event history.
92−This will take some time. Go have a beer.
93−
94−Also in `.urb` is a file like `code.~rosrev-dinnul`. This is
95−your passcode; all data in the pier [XX: not yet the checkpoint]
96−is encrypted with it. For extra security, print out or memorize
97−the contents of this file, then delete it; Urbit will prompt for
98−the passcode on startup. Please be warned that Urbit is not at
99−present secure in any way!
100−
101−## Complete launch procedure
102−
103−Wait until you see a prompt, either
104−
105− ~fintud-macrep:talk()
106−or
107−
108− ~fintud-macrep:dojo>
109−
110−and then press ^D to quit.
111−
112−Your urbit is launched! Ladies and gentlemen, we are floating in space.
docs/walkthroughs.mdnew file+9
@@ -0,0 +1,9 @@
1+---
2+sort: 3
3+---
4+
5+# Walkthroughs
6+
7+Short walking-tour style guides that show you around your Urbit.
8+
9+<list dataPath="docs/walkthroughs"></list>
docs/user/appliance.md → docs/walkthroughs/appliance.mdrenamed+3−3
@@ -1,10 +1,10 @@
11---
22next: true
3−sort: 5
4−title: Appliance handbook
3+sort: 2
4+title: Appliances
55---
66
7−# Appliance handbook
7+# Appliances
88
99You've built and launched your urbit. How do you control it
1010securely? Three ways: through the Unix console, over the Web,
docs/user/clay.md → docs/walkthroughs/clay.mdrenamed+2−2
@@ -1,7 +1,7 @@
11---
22next: true
3−sort: 6
4−title: Filesystem handbook
3+sort: 3
4+title: Filesystem
55---
66
77# Filesystem handbook
docs/user/dojo.md → docs/walkthroughs/dojo.mdrenamed+1−1
@@ -1,5 +1,5 @@
11---
2−sort: 8
2+sort: 4
33title: Dojo manual
44---
55
docs/user/talk.md → docs/walkthroughs/talk.mdrenamed+1−1
@@ -1,6 +1,6 @@
11---
22next: true
3−sort: 7
3+sort: 4
44title: Talk manual
55---
66
docs/user/tour.md → docs/walkthroughs/tour.mdrenamed+3−3
@@ -1,10 +1,10 @@
11---
22next: true
3−sort: 4
4−title: Walking Tour
3+sort: 1
4+title: Tour
55---
66
7−# Walking Tour
7+# Tour
88
99Piers are portable. You can move a pier anywhere. But never,
1010*ever* run the same urbit in two places at once. (If you try to