on master help sign in
add gall data types section and restructure

- Gall vane documentation is moved out of userspace and back into arvo/gall - add data types document to gall vane docs - move gall guide to top level of userspace docs - fix all links It's cleaner if actual Gall vane documentation follows the same structure as other vanes, rather than being nested under userspace. Ultimately the api doc should be redone to specifically cover gall vane tasks like the other vanes, at the moment it duplicates a lot of info with the data types section and the overview section. Will do at some stage but not done for now. The data types section is so there's a canonical gall types reference that the new gall guide can link out to.

commit005a8e928f5a65c4942d5a3730ccfad22fcd1470 authorTinnus Napbus <admin@tinnus-napbus.xyz> dateSat 30 Oct 2021, 03:46 (5 years ago) parent376e970
18 files changed+108−1683
content/docs/arvo/_index.md+2−4 content/docs/arvo/ames/ames.md+74−74 content/docs/arvo/concepts/scry.md+1−1 content/docs/arvo/gall/overview.md−11 content/docs/arvo/overview.md+1−1 content/docs/arvo/reference/filesystem.md+1−1 content/docs/development/develop.md+4−4 content/docs/glossary/aqua.md−4 content/docs/glossary/gall.md+2−1 content/docs/system-overview/arvo.md+1−1 content/docs/userspace/_index.md+2−2 content/docs/userspace/gall/_index.md−21 content/docs/userspace/gall/gall-api.md−958 content/docs/userspace/gall/gall.md−558 content/docs/userspace/gall/tutorial.md−14 content/docs/userspace/landscape/overview.md+5−14 content/docs/userspace/overview.md+2−2 content/docs/userspace/threads/overview.md+13−12
content/docs/arvo/_index.md+2−4
@@ -36,11 +36,11 @@ Eyre is our HTTP server. Unix sends HTTP messages to `%eyre`, and `%eyre` produc
3636
3737Ford is our build system. It handles resources and publishing.
3838
39−## [Gall](/docs/arvo/gall/overview)
39+## [Gall](/docs/arvo/gall/gall)
4040
4141Gall is the vane for controlling userspace apps.
4242
43−## [Iris](/docs/arvo/iris/iris-api)
43+## [Iris](/docs/arvo/iris/iris)
4444
4545Iris is our HTTP client.
4646
@@ -51,5 +51,3 @@ Explanations of design decisions that are pervasive throughout Arvo.
5151## [Tutorials](/docs/arvo/tutorials/)
5252
5353Walkthroughs that teach you more about how Arvo works.
54−
55−
content/docs/arvo/ames/ames.md+74−74
@@ -4,6 +4,7 @@ weight = 1
44template = "doc.html"
55aliases = ["/docs/learn/arvo/ames/"]
66+++
7+
78Our networking protocol.
89
910Ames is the name of both our network and the vane that communicates
@@ -11,7 +12,7 @@ over it. When Unix receives a packet over the correct UDP port, it pipes
1112it straight into Ames for handling. Also, all packets sent over the
1213Ames network are sent by the Ames vane. Apps and vanes may use
1314Ames to directly send messages to other ships. In general, apps use
14−[Gall](/docs/userspace/gall/gall) and [Clay](/docs/arvo/clay/clay)
15+[Gall](/docs/arvo/gall/gall) and [Clay](/docs/arvo/clay/clay)
1516to communicate with other ships rather than using Ames
1617directly, but this isn't a requirement. Of course, Gall and Clay use
1718Ames behind the scenes to communicate across the network. Jael is the only other
@@ -25,32 +26,33 @@ protocol itself, including how to route incoming packets to the correct
2526vane or app, is defined in Ames.
2627
2728## Technical Overview
29+
2830This section summarizes the design of Ames. Beyond this section are deeper
2931elaborations on the concepts presented here.
3032
3133Ames extends [Arvo's](/docs/arvo/overview) `%pass`/`%give` `move` semantics across the network.
3234
3335Ames receives packets as Arvo events and emits packets as Arvo
34−effects. The runtime is responsible for transferring the bytes in
36+effects. The runtime is responsible for transferring the bytes in
3537an Ames packet across a physical network to another ship.
3638
3739The runtime tells Ames which physical address a packet came from,
38−represented as an opaque atom. Ames can emit a packet effect to
40+represented as an opaque atom. Ames can emit a packet effect to
3941one of those opaque atoms or to the Urbit address of a galaxy
4042(root node), which the runtime is responsible for translating to a
41−physical address. One runtime implementation sends UDP packets
43+physical address. One runtime implementation sends UDP packets
4244using IPv4 addresses for ships and DNS lookups for galaxies, but
4345other implementations may overlay over other kinds of networks.
4446
45−A local vane can pass Ames a `%plea` request message. Ames
47+A local vane can pass Ames a `%plea` request message. Ames
4648transmits the message over the wire to the peer ship's Ames, which
4749passes the message to the destination vane.
4850
4951Once the peer has processed the `%plea` message, it sends a
5052message-acknowledgment packet over the wire back to the local
51−Ames. This "ack" can either be positive to indicate the request was
53+Ames. This "ack" can either be positive to indicate the request was
5254processed, or negative to indicate the request failed, in which
53−case it's called a "nack". (Don't confuse Ames nacks with TCP
55+case it's called a "nack". (Don't confuse Ames nacks with TCP
5456nacks, which are a different concept).
5557
5658When the local Ames receives either a positive message-ack or a
@@ -60,11 +62,11 @@ requested the original `%plea` message be sent.
6062
6163A local vane can give Ames zero or more `%boon` response messages in
6264response to a `%plea`, on the same duct that Ames used to pass the
63−`%plea` to the vane. Ames transmits a `%boon` over the wire to the
65+`%plea` to the vane. Ames transmits a `%boon` over the wire to the
6466peer's Ames, which gives it to the destination vane on the same
6567duct the vane had used to pass the original `%plea` to Ames.
6668
67−`%boon` messages are acked automatically by the receiver Ames. They
69+`%boon` messages are acked automatically by the receiver Ames. They
6870cannot be nacked, and Ames only uses the ack internally, without
6971notifying the client vane that gave Ames the `%boon`.
7072
@@ -74,15 +76,15 @@ indicating the `%boon` was missed.
7476
7577`%plea` messages can be nacked, in which case the peer will send
7678both a message-nack packet and a naxplanation message, which is
77−sent in a way that does not interfere with normal operation. The
79+sent in a way that does not interfere with normal operation. The
7880naxplanation is sent as a full Ames message, instead of just a
7981packet, because the contained error information can be arbitrarily
80−large. A naxplanation can only give rise to a positive ack --
82+large. A naxplanation can only give rise to a positive ack --
8183never ack an ack, and never nack a naxplanation.
8284
8385Ames guarantees a total ordering of messages within a "flow",
8486identified in other vanes by a duct and over the wire by a `bone`:
85−an opaque number. Each flow has a FIFO (first-in-first-out) queue of `%plea` requests
87+an opaque number. Each flow has a FIFO (first-in-first-out) queue of `%plea` requests
8688from the requesting ship to the responding ship and a FIFO queue
8789of `%boon`'s in the other direction.
8890
@@ -94,23 +96,23 @@ destination vane.
9496
9597Ames encrypts every message using symmetric-key encryption by
9698performing an elliptic curve Diffie-Hellman using our private key
97−and the public key of the peer. For ships in the Jael PKI
99+and the public key of the peer. For ships in the Jael PKI
98100(public-key infrastructure), Ames looks up the peer's public key
99−from Jael. Comets (128-bit ephemeral addresses) are not
101+from Jael. Comets (128-bit ephemeral addresses) are not
100102cryptographic assets and must self-attest over Ames by sending a
101103single self-signed packet containing their public key.
102104
103105When a peer suffers a continuity breach, Ames removes all
104−messaging state related to it. Ames does not guarantee that all
105−messages will be fully delivered to the now-stale peer. From
106+messaging state related to it. Ames does not guarantee that all
107+messages will be fully delivered to the now-stale peer. From
106108Ames's perspective, the newly restarted peer is a new ship.
107109Ames's guarantees are not maintained across a breach.
108110
109111A vane can pass Ames a `%heed` `$task` to request Ames track a peer's
110−responsiveness. If our `%boon`'s to it start backing up locally,
112+responsiveness. If our `%boon`'s to it start backing up locally,
111113Ames will give a `%clog` back to the requesting vane containing the
112−unresponsive peer's urbit address. This interaction does not use
113−ducts as unique keys. Stop tracking a peer by sending Ames a
114+unresponsive peer's urbit address. This interaction does not use
115+ducts as unique keys. Stop tracking a peer by sending Ames a
114116`%jilt` `$task`.
115117
116118Debug output can be adjusted using `%sift` and `%spew` `$task`'s.
@@ -128,46 +130,46 @@ There is a 32-bit header followed by a variable width body.
128130
129131The 32-bit header is given by the following data, presented in order:
130132
131− - 3 bits: reserved
132− - 1 bit: is this Ames? (i.e. not using a different protocol, such as the
133− planned remote scry protocol)
134− - 3 bits: Ames protocol version (currently 0)
135− - 2 bits: sender address size
136− - 2 bits: receiver address size
137− - 20 bits: checksum (truncated insecure hash of the body, done with
138− [`+mug`](/docs/hoon/reference/stdlib/2e#mug)
139− - 1 bit: is this relayed? (if set, `origin` will be present in the body)
133+- 3 bits: reserved
134+- 1 bit: is this Ames? (i.e. not using a different protocol, such as the
135+ planned remote scry protocol)
136+- 3 bits: Ames protocol version (currently 0)
137+- 2 bits: sender address size
138+- 2 bits: receiver address size
139+- 20 bits: checksum (truncated insecure hash of the body, done with
140+ [`+mug`](/docs/hoon/reference/stdlib/2e#mug)
141+- 1 bit: is this relayed? (if set, `origin` will be present in the body)
140142
141− Every packet sent between ships is encrypted except for self-signed attestation packets from 128-bit comets.
143+Every packet sent between ships is encrypted except for self-signed attestation packets from 128-bit comets.
142144
143145#### Body
144146
145147The body is of variable length and consists of the following parts in this
146148order:
147149
148− - 4 bits: sender life (mod 16)
149− - 4 bits: receiver life (mod 16)
150− - variable: sender address
151− - variable: receiver address
152− - 48 bits: (optional) 48-bit `origin`
153− - 128 bits: `SIV`
154− - 16 bits: ciphertext size
155− - variable: ciphertext
156−
157− `origin` is the IP and port of the original sender if the packet was proxied
158− through a relay.
159−
160− `SIV` is a "synthetic initialization vector" as defined in AES-256 SIV, the encryption
161− algorithm utilized to encrypt Ames packets (see the page on [Ames
162− cryptography](/docs/arvo/ames/cryptography)). It is formed from the
163− following noun: `~[sender=@p receiver=@p sender-life=@ receiver-life=@]` (see
164− [Life and Rift](/docs/azimuth/life-and-rift) for information on what `life`
165− is). As this data is in Azimuth, it is not explicitly sent over the wire. Thus
166− the mod 16 sender and receiver life in the first 8 bits are only for quick
167− filtering of honest packets sent to or from a stale life.
168−
169− The ciphertext is formed by `+jam`ming a `$shut-packet` and then encrypting
170− using [`+en:sivc:aes:crypto`](/docs/arvo/reference/cryptography#en).
150+- 4 bits: sender life (mod 16)
151+- 4 bits: receiver life (mod 16)
152+- variable: sender address
153+- variable: receiver address
154+- 48 bits: (optional) 48-bit `origin`
155+- 128 bits: `SIV`
156+- 16 bits: ciphertext size
157+- variable: ciphertext
158+
159+`origin` is the IP and port of the original sender if the packet was proxied
160+through a relay.
161+
162+`SIV` is a "synthetic initialization vector" as defined in AES-256 SIV, the encryption
163+algorithm utilized to encrypt Ames packets (see the page on [Ames
164+cryptography](/docs/arvo/ames/cryptography)). It is formed from the
165+following noun: `~[sender=@p receiver=@p sender-life=@ receiver-life=@]` (see
166+[Life and Rift](/docs/azimuth/life-and-rift) for information on what `life`
167+is). As this data is in Azimuth, it is not explicitly sent over the wire. Thus
168+the mod 16 sender and receiver life in the first 8 bits are only for quick
169+filtering of honest packets sent to or from a stale life.
170+
171+The ciphertext is formed by `+jam`ming a `$shut-packet` and then encrypting
172+using [`+en:sivc:aes:crypto`](/docs/arvo/reference/cryptography#en).
171173
172174### Packeting
173175
@@ -187,9 +189,7 @@ eventually get through, and when the other side gets them it can put them in the
187189correct order. If Ames doesn't get an ack on a packet then it will resend it
188190until it does. The logic for determining how many packets to send or re-send at what time is performed by an Ames-specific variant of TCP's "NewReno" congestion control algorithm.
189191
190−As each packet in a message is received, Ames decrypts it and stores the message fragment. Once it's received every packet for a message, Ames concatenates the fragments back into a single large atom and uses `+cue` to deserialize that back into the original message noun.
191−
192−
192+As each packet in a message is received, Ames decrypts it and stores the message fragment. Once it's received every packet for a message, Ames concatenates the fragments back into a single large atom and uses `+cue` to deserialize that back into the original message noun.
193193
194194### Acks and Nacks
195195
@@ -221,7 +221,6 @@ Thus a message-level ack must be received before the next message on the flow
221221can begin. The full story is more complicated than this; see the section on
222222[flows](#flows).
223223
224−
225224#### Nacks
226225
227226A nack indicates a negative acknowledgement to a `%plea`, meaning that the
@@ -248,9 +247,11 @@ the receiver will never both perform a `%plea` and return a naxplanation.
248247
249248A fragment ack's contents (before encryption) are a pure function of the
250249following noun:
250+
251251```hoon
252252[our-life her-life bone message-num fragment-num]
253253```
254+
254255This means all re-sends of an ack packet will be bitwise identical to each other, unless one of the peers changes its encryption keys.
255256
256257Each datum in this noun is an atom with the aura `@ud` or an aura that nests
@@ -269,11 +270,11 @@ A message (n)ack is a different kind of ack that is obtained by encrypting the
269270```hoon
270271[our-life her-life bone message-num ok=? lag=@dr]
271272```
273+
272274`ok` is a flag that is set to `%.y` for a message ack and `%.n` for a message
273275nack. In the future, `lag` will be used to
274276describe the time it took to process a message, but for now it is always zero.
275277
276−
277278### Flows
278279
279280Flows are asymmetric communication channels along which two ships send and
@@ -300,10 +301,10 @@ We give an example of such a partition. Let flow 12 be a flow between `~bacbel-t
300301`~bacbel-tagfeg` as the `%plea` sender. Then bones 12-15 are associated with the
301302flow, and the types of packets for each bone are:
302303
303− - bone 12, `%plea`s and acks to `~worwel-sipnum`,
304− - bone 13, `%boon`s and (n)acks to `~bacbel-tagfeg`,
305− - bone 14, acks of naxplanations to `~worwel-sipnum`,
306− - bone 15, naxplanations to `~bacbel-tagfeg`.
304+- bone 12, `%plea`s and acks to `~worwel-sipnum`,
305+- bone 13, `%boon`s and (n)acks to `~bacbel-tagfeg`,
306+- bone 14, acks of naxplanations to `~worwel-sipnum`,
307+- bone 15, naxplanations to `~bacbel-tagfeg`.
307308
308309Each bone is handled separately by congestion control, and this is one reason
309310for their segregation. For example, say a two-packet `%plea` is sent on bone 12,
@@ -379,16 +380,17 @@ private key and the public key of `~worwel-sipnum`, obtained via Jael. Then
379380`~bacbel-tagfeb` sends a packet addressed to `~worwel-sipnum` to `~zod`.
380381
381382The packet has the following format:
382− - The standard Ames header described in [header](#header), where the checksum
383− is the `+mug` of the body, and the sender and receiver ship types are `01`,
384− denoting that the sender and receiver are planets. The "is this relayed?" bit
385− is set to 0 since this is the first hop on the packet route.
386− - The body of this packet will be the life of `~bacbel-tagfeg` mod 16, followed
387− by the life of `~worwel-sipnum` mod 16, followed by `~bacbel-tagfeg`,
388− followed by the receiver `~worwel-sipnum`, followed by the origin `~`
389− (denoting that the ship sending the packet is the origin). After this comes
390− the payload.
391− - The payload of this packet will be the `+jam` of the `content`, which is an encrypted fragment of the message `%watch /path/to/recipes`.
383+
384+- The standard Ames header described in [header](#header), where the checksum
385+ is the `+mug` of the body, and the sender and receiver ship types are `01`,
386+ denoting that the sender and receiver are planets. The "is this relayed?" bit
387+ is set to 0 since this is the first hop on the packet route.
388+- The body of this packet will be the life of `~bacbel-tagfeg` mod 16, followed
389+ by the life of `~worwel-sipnum` mod 16, followed by `~bacbel-tagfeg`,
390+ followed by the receiver `~worwel-sipnum`, followed by the origin `~`
391+ (denoting that the ship sending the packet is the origin). After this comes
392+ the payload.
393+- The payload of this packet will be the `+jam` of the `content`, which is an encrypted fragment of the message `%watch /path/to/recipes`.
392394
393395`~zod` receives the packet and reads the body. It sees that it is not the
394396intended recipient of the packet, and so gets ready to forward it to
@@ -398,8 +400,7 @@ with the new mug. Since the packet is being relayed, `~zod` flips the "is it
398400relayed?" bit to `%.y`. `~zod` then forwards the packet to `~worwel-sipnum`.
399401
400402In order to decrypt the packet, `~worwel-sipnum` will need to calculate the
401−associated data vector utilized by SIV, which consists of `~[sender=@p
402−receiver=@p sender-life=@ receiver-life=@]`. It then passes that along with the
403+associated data vector utilized by SIV, which consists of `~[sender=@p receiver=@p sender-life=@ receiver-life=@]`. It then passes that along with the
403404SIV and ciphertext to the decryption function, and receives the unencrypted
404405packet as a return.
405406
@@ -463,4 +464,3 @@ hands it off the the Unix network interface to be sent.
463464Now the receiving King is handed a UDP packet by Unix. The King removes the UDP
464465wrapper, `+jam`s the `lane` on which it heard the packet, and delivers the packet
465466to the Ames vane as an atom by copying the bytes it heard on the UDP port.
466−
content/docs/arvo/concepts/scry.md+1−1
@@ -74,4 +74,4 @@ The webserver vane Eyre has a system which allows clients like web browsers to p
7474
7575[Eyre's External API Reference](/docs/arvo/eyre/external-api-ref#scry) - Documentation of Eyre's scry system which allows web clients to perform scries over HTTP.
7676
77−[The Gall Guide](/docs/userspace/gall/tutorial) - The Gall tutorial includes a section about `+on-peek` and writing scry endpoints.
77+[The Gall Guide](/docs/userspace/gall-guide) - The Gall tutorial includes a section about `+on-peek` and writing scry endpoints.
content/docs/arvo/gall/overview.mddeleted−11
@@ -1,11 +0,0 @@
1−+++
2−title = "Overview"
3−weight = 1
4−template = "doc.html"
5−+++
6−
7−**Gall** is the application-management [vane](/docs/glossary/vane). Userspace apps –⁠ daemons, really –⁠ are started, stopped, and sandboxed by Gall. Gall provides developers with a consistent interface for connecting their app to [Arvo](/docs/arvo/arvo). It allows applications and other vanes to send messages to applications and subscribe to data streams. Messages coming into Gall are routed to the intended application, and the response comes back along the same route. If the intended target is on another [ship](/docs/glossary/ship), Gall will route it behind the scenes through [Ames](/docs/arvo/ames/ames) to the other ship.
8−
9−Gall is located at `/home/sys/vane/gall.hoon` within Arvo.
10−
11−For more details, see the [userspace](/docs/userspace/gall/gall) section.
content/docs/arvo/overview.md+1−1
@@ -543,7 +543,7 @@ As of this writing, we have nine vanes, which each provide the following service
543543- [Eyre](/docs/arvo/eyre/eyre): an http server. Unix sends http messages to `%eyre`, and `%eyre` produces http messages in response.
544544- [Ford](/docs/arvo/ford/ford): a build system also utilized for marks
545545 (file types) and debugging.
546−- [Gall](/docs/userspace/gall/gall): manages our userspace applications. `%gall` keeps state and manages subscribers.
546+- [Gall](/docs/arvo/gall/gall): manages our userspace applications. `%gall` keeps state and manages subscribers.
547547- [Iris](/docs/arvo/iris/iris): an http client.
548548- [Jael](/docs/arvo/jael/jael): storage for Azimuth information.
549549
content/docs/arvo/reference/filesystem.md+1−1
@@ -13,7 +13,7 @@ is not perfectly adhered to - sometimes you may find structure definitions in
1313`/lib`, for example.
1414
1515- `/app` contains userspace applications, i.e. [Gall
16− agents](/docs/userspace/gall/gall).
16+ agents](/docs/arvo/gall/gall).
1717- `/gen` contains generators. Many applications make use of generators, but also
1818 each generator in this folder may be run from dojo using `+`. For example,
1919 `/gen/foo/hoon` in the `%base` desk is run with `+foo`. Generators on desks
content/docs/development/develop.md+4−4
@@ -13,7 +13,7 @@ contribute to. At a high level, you can:
1313- [Build clients](#clients), which use Urbit as their back-end to store data and
1414 interact with the network
1515- [Develop agents](#agents), or more precisely [_gall_
16− agents](/docs/userspace/gall/gall), which are written in [Hoon](/docs/hoon/)
16+ agents](/docs/arvo/gall/gall), which are written in [Hoon](/docs/hoon/)
1717 and can best be thought of as microservices
1818- [Contribute to Urbit's core](#core), which involves contributing to Urbit
1919 itself &mdash; either the operating system
@@ -60,8 +60,8 @@ library called `shoe`, which you can learn more about
6060Gall agents can be best thought of as individual services with a
6161statically-typed interface and built-in database. They're written in
6262[Hoon](/docs/hoon/overview) and all conform to a specific
63−[interface](/docs/userspace/gall/gall-api) that's defined by the kernel vane
64−called [Gall](/docs/userspace/gall/gall).
63+[interface](/docs/arvo/gall/gall-api) that's defined by the kernel vane
64+called [Gall](/docs/arvo/gall/gall).
6565
6666Applications built on Urbit utilize a collection of different agents, each of
6767which handle specific functionality. The [Landscape
@@ -70,7 +70,7 @@ to see how this pattern works in practice.
7070
7171If you want to learn how to build gall agents, your best bet is to first [learn
7272the Hoon programming language](/docs/hoon/hoon-school/), and then follow that
73−up with the [Gall guide](/docs/userspace/gall/tutorial).
73+up with the [Gall guide](/docs/userspace/gall-guide).
7474
7575### Contribute to Urbit Core {#core}
7676
content/docs/glossary/aqua.md−4
@@ -10,7 +10,3 @@ category = "arvo"
1010Aqua is a [Gall](/docs/glossary/gall) app that runs an [Arvo](/docs/glossary/arvo) instance or instances in userspace. It pretends to be [Vere](/docs/glossary/vere), and as such it loads [Pills](/docs/glossary/pill) to boot up a virtual ship or fleet of ships and then manages them from within the parent Arvo instance. Running tests for a virtual fleet of Aqua ships is done using [pH](/docs/glossary/ph).
1111
1212Aqua is jetted with the usual [Nock](/docs/glossary/nock) interpreter and thus virtual ships do not run any slower than the parent ship.
13−
14−### Further Reading
15−
16−- [The Gall tutorial](/docs/userspace/gall/gall): A technical guide to the Gall vane.
content/docs/glossary/gall.md+2−1
@@ -14,4 +14,5 @@ Gall is located at `/home/sys/vane/gall.hoon` within Arvo.
1414
1515- [The Hoon Tutorial](/docs/hoon/hoon-school/): Our guide to learning the Hoon programming language that will give you the foundation necessary for app development.
1616 - [Lesson 2.7: Gall](/docs/hoon/hoon-school/gall): A Hoon Tutorial lesson that explains how to write a simple Gall app.
17−- [The Gall tutorial](/docs/userspace/gall/gall): A technical guide to the Gall vane.
17+- [Gall vane documentation](/docs/arvo/gall/gall): Documentation of the Gall vane.
18+- [Gall Guide](/docs/userspace/gall-guide): A tutorial for writing Gall agents.
content/docs/system-overview/arvo.md+1−1
@@ -27,6 +27,6 @@ Arvo modules are also called 'vanes'. Arvo's vanes are:
2727 Also includes our typed functional build system.
2828- [Dill](/docs/arvo/dill/dill): terminal driver.
2929- [Eyre](/docs/arvo/eyre/eyre): HTTP server.
30−- [Gall](/docs/userspace/gall/gall): application sandbox and manager.
30+- [Gall](/docs/arvo/gall/gall): application sandbox and manager.
3131- [Iris](/docs/arvo/iris/iris-api): HTTP client.
3232- [Jael](/docs/arvo/jael/jael-api): Public and private key storage.
content/docs/userspace/_index.md+2−2
@@ -12,9 +12,9 @@ Urbit's userspace is managed by Arvo's Gall vane.
1212
1313An overview of userspace in Urbit.
1414
15−## [Gall](/docs/userspace/gall/gall)
15+## [Gall Guide](/docs/userspace/gall-guide)
1616
17−Resources on Gall which manages userspace applications.
17+Learn how to develop Gall agents.
1818
1919## [Landscape](/docs/userspace/landscape/)
2020
content/docs/userspace/gall/_index.mddeleted−21
@@ -1,21 +0,0 @@
1−+++
2−title = "Gall"
3−weight = 40
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−insert_anchor_links = "right"
7−+++
8−
9−Gall is the Arvo vane that manages userspace applications.
10−
11−## [Overview](/docs/userspace/gall/gall)
12−
13−Overview of the Gall vane.
14−
15−## [Tutorial](/docs/userspace/gall/tutorial)
16−
17−Tutorial for writing Gall agents.
18−
19−## [API Reference](/docs/userspace/gall/gall-api)
20−
21−Reference information.
content/docs/userspace/gall/gall-api.mddeleted−958
@@ -1,958 +0,0 @@
1−+++
2−title = "API Reference"
3−weight = 10
4−template = "doc.html"
5−+++
6−
7−## Reference Agent
8−
9−This app stores a number for each user. You can increment your number, increment
10−someone else's number, start tracking someone else's number by poking. It
11−exposes a scry namespace to inspect everyone's number.
12−
13−### `app/example-gall.hoon`
14−
15−```hoon
16−:: Import sur/example-gall
17−/- *example-gall
18−:: Import lib/default-agent
19−/+ default-agent
20−|%
21−+$ card card:agent:gall
22−+$ note
23− $%
24− [%arvo =note-arvo]
25− [%agent [=ship name=term] =task:agent:gall]
26− ==
27−+$ state-zero [%0 local=@ud]
28−+$ state-one [%1 local=@ud remote=(map @p @ud)]
29−+$ versioned-state
30− $%
31− state-zero
32− state-one
33− ==
34−--
35−=| state-one
36−=* state -
37−^- agent:gall
38−|_ =bowl:gall
39−+* this .
40− def ~(. (default-agent this %|) bowl)
41−::
42−:: Set local counter to 1 by default
43−++ on-init
44− ^- (quip card _this)
45− `this(local 1)
46−:: Expose state for saving
47−++ on-save
48− !>(state)
49−::
50−:: Load old state and upgrade if neccessary
51−++ on-load
52− |= old=vase
53− ^- (quip card _this)
54− =/ loaded=versioned-state
55− !<(versioned-state old)
56− ?- -.loaded
57− %0
58− `this(local local.loaded) :: Upgrade old state
59− %1
60− `this(state loaded)
61− ==
62−::
63−:: Respond to poke
64−:: App can be poked in the dojo by running the following commands
65−:: Increment local counter
66−:: :example-gall &example-gall-action [%increment ~]
67−:: Increment ~zod's counter
68−:: :example-gall &example-gall-action [%increment-remote ~zod]
69−:: Subscribe to ~zod's counter
70−:: :example-gall &example-gall-action [%view ~zod]
71−:: Unsubscribe from ~zod's counter
72−:: :example-gall &example-gall-action [%stop-view ~zod]
73−::
74−++ on-poke
75− |= [=mark =vase]
76− ^- (quip card _this)
77− :: Ensure poke is of mark %example-gall-action
78− ?> =(mark %example-gall-action)
79− =/ act=example-gall-action !<(example-gall-action vase)
80− ?- act
81− ::
82− :: Increment local counter and send new counter to subscribers
83− ::
84− [%increment ~]
85− :- [%give %fact ~[/local] %atom !>(+(local))]~
86− this(local +(local))
87− ::
88− :: Send remote %increment poke
89− ::
90− [%increment-remote who=@p]
91− :_ this
92− :~ :*
93− %pass
94− /inc/(scot %p who.act)
95− %agent
96− [who.act %example-gall]
97− %poke %example-gall-action !>([%increment ~])
98− == ==
99− ::
100− :: Subscribe to a remote counter
101− ::
102− [%view who=@p]
103− :_ this
104− [%pass /view/(scot %p who.act) %agent [who.act %example-gall] %watch /local]~
105− ::
106− :: Unsubscribe from remote counter and remove from state
107− ::
108− [%stop-view who=@p]
109− :_ this(remote (~(del by remote) who.act))
110− [%pass /view/(scot %p who.act) %agent [who.act %example-gall] %leave ~]~
111− ::
112− ==
113−::
114−:: Print on unsubscribe
115−::
116−++ on-leave
117− |= =path
118− ^- (quip card _this)
119− ~& "Unsubscribed by: {<src.bowl>} on: {<path>}"
120− `this
121−::
122−:: Handle new subscription
123−::
124−:: When another ship subscribes to our counter, give them the current state of
125−:: the counter immediately
126−::
127−++ on-watch
128− |= =path
129− ^- (quip card _this)
130− :_ this
131− :: Crash if we see a subscription we don't recognise
132− ?+ path ~|("unexpected subscription" !!)
133− ::
134− [%local ~]
135− [%give %fact ~ %atom !>(local)]~
136− ==
137−::
138−:: Expose scry namespace
139−::
140−:: .^(@ %gx /=example-gall=/local/atom) will produce the current local counter
141−:: .^(@ %gx /=example-gall=/remote/~zod/atom) will produce the counter for ~zod
142−:: .^(arch %gy /=example-gall=/remote) will produce a listing of the current
143−:: remote counters
144−++ on-peek
145− |= =path
146− ^- (unit (unit cage))
147− ?+ path [~ ~]
148− ::
149− :: Produce local counter
150− ::
151− [%x %local ~]
152− ``[%atom !>(local)]
153− ::
154− :: Produce remote counter
155− ::
156− [%x %remote who=@ta ~]
157− =* location i.t.t.path :: Ship name is third in the list
158− =/ res
159− (~(got by remote) (slav %p location))
160− ``[%atom !>(res)]
161− ::
162− :: Produce listing of remote counters
163− ::
164− [%y %remote ~]
165− =/ dir=(map @ta ~)
166− %- molt :: Map from list of k-v pairs
167− %+ turn :: iterate over list of k-v pairs
168− ~(tap by remote) :: list of k-v pairs from map
169− |= [who=@p *]
170− [(scot %p who) ~]
171− ``[%arch !>(`arch`[~ dir])]
172− ==
173−::
174−:: Handle sign from agent
175−::
176−++ on-agent
177− |= [=wire =sign:agent:gall]
178− ^- (quip card _this)
179− ?- -.sign
180− ::
181− :: Print error if poke failed
182− ::
183− %poke-ack
184− ?~ p.sign
185− `this
186− %- (slog u.p.sign)
187− `this
188− ::
189− :: Print error if subscription failed
190− ::
191− %watch-ack
192− ?~ p.sign
193− `this
194− =/ =tank leaf+"subscribe failed from {<dap.bowl>} on wire {<wire>}"
195− %- (slog tank u.p.sign)
196− `this
197− ::
198− :: Do nothing if unsubscribed
199− ::
200− %kick `this
201− ::
202− :: Update remote counter when we get a subscription update
203− ::
204− %fact
205− :- ~
206− ?. ?=(%atom p.cage.sign)
207− this
208− this(remote (~(put by remote) src.bowl !<(@ q.cage.sign)))
209− ==
210−::
211−:: Handle arvo signs
212−::
213−:: We never give any cards to arvo. Therefore we never need to handle any signs
214−:: from arvo. We use the default-agent library to avoid implementing this arm,
215−:: as gall apps must have all the arms.
216−::
217−++ on-arvo on-arvo:def
218−::
219−:: Handle error
220−::
221−:: Print errors when they happen
222−::
223−++ on-fail
224− |= [=term =tang]
225− ^- (quip card _this)
226− %- (slog leaf+"error in {<dap.bowl>}" >term< tang)
227− `this
228−--
229−
230−```
231−
232−### `sur/example-gall.hoon`
233−
234−```hoon
235−|%
236−+$ example-gall-action
237− $%
238− [%view who=@p]
239− [%stop-view who=@p]
240− [%increment-remote who=@p]
241− [%increment ~]
242− ==
243−--
244−```
245−
246−### `mar/example-gall/action.hoon`
247−
248−```hoon
249−/- *example-gall
250−|_ act=example-gall-action
251−++ grab
252− |%
253− ++ noun example-gall-action
254− --
255−--
256−```
257−
258−## Arms
259−
260−### `++on-init`
261−
262−Application initialisation
263−
264−`++on-init` is called when an application is first started. It is not a gate and
265−has no input.
266−
267−#### Returns
268−
269−```hoon
270−(quip card _this)
271−```
272−
273−List of cards and new agent
274−
275−#### Example
276−
277−```hoon
278−:: From reference agent.
279−:: Set local counter to 1 by default
280−::
281−++ on-init
282− ^- (quip card _this)
283− `this(local.sta 1)
284−:: From app/weather.hoon. This setup is typical of a landscape tile.
285−::
286−++ on-init
287− :_ this
288− :~ [%pass /bind/weather %arvo %e %connect [~ /'~weather'] %weather]
289− :* %pass /launch/weather %agent [our.bol %launch] %poke
290− %launch-action !>([%weather /weathertile '/~weather/js/tile.js'])
291− ==
292− ==
293−```
294−
295−### `++on-save`
296−
297−Expose state for saving.
298−
299−This arm is called immediately before the agent is upgraded. It packages the
300−permament state of the agent in a vase for the next version of the agent.
301−Unlike most handlers, this cannot produce effects. It is not a gate and has no input.
302−
303−#### Returns
304−
305−`vase` of permanent state.
306−
307−#### Example
308−
309−```hoon
310−:: From reference agent
311−::
312−:: Expose state for saving
313−::
314−++ on-save
315− !>(state)
316−```
317−
318−### `++on-load`
319−
320−Application upgrade.
321−
322−This arm is called immediately after the agent is upgraded. It receives
323−a vase of the state of the previously-running version of the agent, obtained
324−from `+on-save`, which allows it to cleanly upgrade from the old agent.
325−
326−#### Accepts
327−
328−```hoon
329−=vase
330−```
331−
332−`vase` of previous state, from `++on-save`
333−
334−#### Returns
335−
336−```hoon
337−(quip card _this)
338−```
339−
340−List of cards and new agent
341−
342−#### Examples
343−
344−```hoon
345−:: From reference agent
346−::
347−:: Load old state and upgrade if neccessary
348−++ on-load
349− |= old=vase
350− ^- (quip card _this)
351− =/ loaded=versioned-state
352− !<(versioned-state old)
353− ?- -.loaded
354− %0
355− `this(local local.loaded) :: Upgrade old state
356− %1
357− `this(state loaded)
358− ==
359−```
360−
361−### `++on-poke`
362−
363−Handle application poke.
364−
365−This arm is called when the agent is "poked". The input is a cage, so
366−it's a pair of a mark and a dynamic vase.
367−
368−#### Accepts
369−
370−```hoon
371−[=mark =vase]
372−```
373−
374−`mark` is the mark of the poked data.
375−
376−`vase` is a vase with the poked data inside.
377−
378−#### Returns
379−
380−```hoon
381−(quip card _this)
382−```
383−
384−List of cards and new agent.
385−
386−#### Example
387−
388−```hoon
389−:: From reference agent.
390−::
391−:: Respond to poke
392−:: App can be poked in the dojo by running the following commands
393−:: Increment local counter
394−:: :example-gall &example-gall-action [%increment ~]
395−:: Increment ~zod's counter
396−:: :example-gall &example-gall-action [%increment-remote ~zod]
397−:: Subscribe to ~zod's counter
398−:: :example-gall &example-gall-action [%view ~zod]
399−:: Unsubscribe from ~zod's counter
400−:: :example-gall &example-gall-action [%stop-view ~zod]
401−::
402−++ on-poke
403− |= [=mark =vase]
404− ^- (quip card _this)
405− :: Ensure poke is of mark %example-gall-action
406− ?> =(mark %example-gall-action)
407− =/ act=example-gall-action !<(example-gall-action vase)
408− ?- act
409− ::
410− :: Increment local counter and send new counter to subscribers
411− ::
412− [%increment ~]
413− :- [%give %fact ~[/local] %atom !>(+(local))]~
414− this(local +(local))
415− ::
416− :: Send remote %increment poke
417− ::
418− [%increment-remote who=@p]
419− :_ this
420− :~ :*
421− %pass
422− /inc/(scot %p who.act)
423− %agent
424− [who.act %example-gall]
425− %poke %example-gall-action !>([%increment ~])
426− == ==
427− ::
428− :: Subscribe to a remote counter
429− ::
430− [%view who=@p]
431− :_ this
432− [%pass /view/(scot %p who.act) %agent [who.act %example-gall] %watch /local]~
433− ::
434− :: Unsubscribe from remote counter and remove from state
435− ::
436− [%stop-view who=@p]
437− :_ this(remote (~(del by remote) who.act))
438− [%pass /view/(scot %p who.act) %agent [who.act %example-gall] %leave ~]~
439− ::
440− ==
441−```
442−
443−### `++on-watch`
444−
445−Handle new subscriber.
446−
447−This arm is called when a program wants to subscribe to the agent on a
448−particular path. The agent may or may not need to perform setup steps
449−to intialize the subscription. It may produce a `%give`
450−`%subscription-result` to the subscriber to get it up to date, but after
451−this event is complete, it cannot give further updates to a specific
452−subscriber. It must give all further updates to all subscribers on a
453−specific path.
454−
455−If this arm crashes, then the subscription is immediately terminated.
456−More specifcally, it never started -- the subscriber will receive a
457−negative `%watch-ack`. You may also produce an explicit `%kick` to
458−close the subscription without crashing -- for example, you could
459−produce a single update followed by a `%kick`.
460−
461−#### Accepts
462−
463−```hoon
464−=path
465−```
466−
467−Path of new subscription.
468−
469−#### Returns
470−
471−```hoon
472−(quip card _this)
473−```
474−
475−List of cards and new agent.
476−
477−#### Example
478−
479−```hoon
480−:: From reference agent
481−::
482−:: Handle new subscription
483−::
484−:: When another ship subscribes to our counter, give them the current state of
485−:: the counter immediately
486−::
487−++ on-watch
488− |= =path
489− ^- (quip card _this)
490− :_ this
491− ?+ path on-watch:def
492− ::
493− [%local ~]
494− [%give %fact ~ %atom !>(local)]~
495− ==
496−```
497−
498−### `++on-leave`
499−
500−Handle unsubscribe.
501−
502−This arm is called when a program becomes unsubscribed to you.
503−Subscriptions may close because the subscriber intentionally
504−unsubscribed, but they also could be closed by an intermediary. For
505−example, if a subscription is from another ship which is currently
506−unreachable, Ames may choose to close the subscription to avoid queueing
507−updates indefinitely. If the program crashes while processing an
508−update, this may also generate an unsubscription. You should consider
509−subscriptions to be closable at any time.
510−
511−#### Accepts
512−
513−```hoon
514−=path
515−```
516−
517−Path of the closed subscription.
518−
519−#### Returns
520−
521−```hoon
522−(quip card _this)
523−```
524−
525−List of cards and new agent.
526−
527−#### Example
528−
529−```hoon
530−:: From reference agent. Prints a message when programs become unsubscribed.
531−++ on-leave
532− |= =path
533− ^- (quip card _this)
534− ~& "Unsubscribe by: {<src.bowl>} on: {<path>}"
535− `this
536−```
537−
538−### `++on-peek`
539−
540−Handle scry request.
541−
542−This arm is called when a program reads from the agent's "scry"
543−namespace, which should be referentially transparent. Unlike most
544−handlers, this cannot perform IO, and it cannot change the state. All
545−it can do is produce a piece of data to the caller, or not.
546−
547−#### Accepts
548−
549−```hoon
550−=path
551−```
552−
553−The path being scryed for.
554−
555−```hoon
556−:: Example scry to path mappings
557−::
558−.^(arch %gy /=example-gall=/remote)
559−:: Path will be /y/remote
560−.^(@ %gx /=example-gall=/local/atom)
561−:: Path will be /x/local
562−```
563−
564−#### Returns
565−
566−```hoon
567−(unit (unit cage))
568−```
569−
570−If this arm produces `[~ ~ data]`, then `data` is the value at the the
571−given path. If it produces `[~ ~]`, then there is no data at the given
572−path and never will be. If it produces `~`, then we don't know yet whether
573−there is or will be data at the given path. The head of the path is known as the
574−`care`. Requests with a care of `%x` should return a vase that matches or is
575−convertible to the mark at the end of the scry request. This mark is not
576−included in the path passed to `++on-peek`. Requests with a care of `%y` should
577−return a cage with a mark of `%arch` and a vase of `arch`.
578−
579−#### Example
580−
581−```hoon
582−:: From reference agent
583−::
584−:: Expose scry namespace
585−::
586−:: .^(@ %gx /=example-gall=/local/atom) will produce the current local counter
587−:: .^(@ %gx /=example-gall=/remote/~zod/atom) will produce the counter for ~zod
588−:: .^(arch %gy /=example-gall=/remote) will produce a listing of the current
589−:: remote counters
590−++ on-peek
591− |= =path
592− ^- (unit (unit cage))
593− ?+ path [~ ~]
594− ::
595− :: Produce local counter
596− ::
597− [%x %local ~]
598− ``[%atom !>(local)]
599− ::
600− :: Produce remote counter
601− ::
602− [%x %remote who=@ta ~]
603− =* location i.t.t.path :: Ship name is third in the list
604− =/ res
605− (~(got by remote) (slav %p location))
606− ``[%atom !>(res)]
607− ::
608− :: Produce listing of remote counters
609− ::
610− [%y %remote ~]
611− =/ dir=(map @ta ~)
612− %- molt :: Map from list of k-v pairs
613− %+ turn :: iterate over list of k-v pairs
614− ~(tap by remote) :: list of k-v pairs from map
615− |= [who=@p *]
616− [(scot %p who) ~]
617− ``[%arch !>(`arch`[~ dir])]
618− ==
619−```
620−
621−### `++on-agent`
622−
623−Handle `%pass` card
624−
625−This arm is called to handle responses to `%pass` cards to other agents.
626−It will be one of the following types of response:
627−
628−- `%poke-ack`: acknowledgment (positive or negative) of a poke. If the
629− value is `~`, then the poke succeeded. If the value is `[~ tang]`,
630− then the poke failed, and a printable explanation (eg a stack trace)
631− is given in the `tang`.
632−
633−- `%watch-ack`: acknowledgment (positive or negative) of a subscription.
634− If negative, the subscription is already ended (technically, it never
635− started).
636−
637−- `%fact`: update from the publisher.
638−
639−- `%kick`: notification that the subscription has ended. This happens because
640− either the target app passed a `%leave` note, or ames killed the subscription
641− due to backpressure. Most of the time you will want to resubscribe. If you can
642− no longer access the subscription you will get a negative `%watch-ack` and end
643− your flow there.
644−
645−#### Accepts
646−
647−```hoon
648−[=wire =sign:agent:gall]
649−```
650−
651−`wire` is the wire from the `+gift` that triggered `++on-agent`
652−
653−`sign` is response for the gift.
654−
655−#### Returns
656−
657−```hoon
658−(quip card _this)
659−```
660−
661−#### Example
662−
663−```hoon
664−:: From reference agent
665−::
666−:: Handle sign from agent
667−::
668−++ on-agent
669− |= [=wire =sign:agent:gall]
670− ^- (quip card _this)
671− ?- -.sign
672− ::
673− :: Print error if poke failed
674− ::
675− %poke-ack
676− ?~ p.sign
677− `this
678− %- (slog u.p.sign)
679− `this
680− ::
681− :: Print error if subscription failed
682− ::
683− %watch-ack
684− ?~ p.sign
685− `this
686− =/ =tank leaf+"subscribe failed from {<dap.bowl>} on wire {<wire>}"
687− %- (slog tank u.p.sign)
688− `this
689− ::
690− :: Do nothing if unsubscribed
691− ::
692− %kick `this
693− ::
694− :: Update remote counter when we get a subscription update
695− ::
696− %fact
697− :- ~
698− ?. ?=(%atom p.cage.sign)
699− this
700− this(remote (~(put by remote) src.bowl !<(@ q.cage.sign)))
701− ==
702−```
703−
704−### `++on-arvo`
705−
706−Handle vane response
707−
708−This arm is called to handle responses for `%pass` cards to vanes.
709−
710−#### Accepts
711−
712−```hoon
713− [=wire =sign:agent:gall]
714−```
715−
716−`wire` is the wire from the `++gift` that triggered `++on-arvo`.
717−
718−`sign` is the response from the vane. The list of possible responses from the
719−vanes is statically defined in sys/zuse.hoon (grep for `++ sign-arvo`).
720−
721−#### Returns
722−
723−```hoon
724−(quip card _this)
725−```
726−
727−List of cards and new agent.
728−
729−#### Example
730−
731−```hoon
732−:: From app/weather.hoon. Handles %bound, %wake and %http-response signs
733−++ on-arvo
734− |= [=wire =sign-arvo]
735− ^- (quip card:agent:gall _this)
736− ?: ?=(%bound +<.sign-arvo)
737− [~ this]
738− ?: ?=(%wake +<.sign-arvo)
739− =^ cards state
740− (wake:wc wire error.sign-arvo)
741− [cards this]
742− ?: ?=(%http-response +<.sign-arvo)
743− =^ cards state
744− (http-response:wc wire client-response.sign-arvo)
745− [cards this]
746− (on-arvo:def wire sign-arvo)
747−::
748−:: From reference agent
749−::
750−:: Handle arvo signs
751−::
752−:: We never give any cards to arvo. Therefore we never need to handle any signs
753−:: from arvo. We use the default-agent library to avoid implementing this arm,
754−:: as gall apps must have all the arms specified in the agent:gall definition.
755−::
756−++ on-arvo on-arvo:def
757−```
758−
759−### `++on-fail`
760−
761−Handle error.
762−
763−If an error happens in `+on-poke`, the crash report goes into the
764−`%poke-ack` response. Similarly, if an error happens in
765−`+on-subscription`, the crash report goes into the `%watch-ack`
766−response. If a crash happens in any of the other handlers, the report
767−is passed into this arm.
768−
769−#### Accepts
770−
771−```hoon
772−[=term =tang]
773−```
774−
775−`term` is a cord describing the error.
776−
777−`tang` is a stack trace for the error.
778−
779−#### Returns
780−
781−```hoon
782−(quip card _this)
783−```
784−
785−List of cards and new agent
786−
787−#### Example
788−
789−```hoon
790−::
791−:: Handle error
792−::
793−:: Print errors when they happen
794−::
795−++ on-fail
796− |= [=term =tang]
797− ^- (quip card _this)
798− %- (slog leaf+"error in {<dap.bowl>}" >term< tang)
799− `this
800−```
801−
802−## Agent Gifts
803−
804−Giving a gift takes the general form of
805−
806−```hoon
807−[%give =gift]
808−```
809−
810−### `%fact`
811−
812−Produce a subscription update.
813−
814−Produces a subscription update. A subscription update is a new piece of
815−subscription content for all subscribers on a given path.
816−
817−#### Structure
818−
819−```hoon
820−[%fact (list path) =cage]
821−```
822−
823−`(list path)` is a list of the paths to send the update on. If no path is
824− given, then the update is only given to the program that instigated the
825− request. Typical use of this mode is in `+on-watch` to give an initial update
826− to a new subscriber to get them up to date.
827−
828−`cage` is a cage of the subscription update.
829−
830−#### Example
831−
832−```hoon
833−:: From ++on-watch in reference agent.
834−::
835−:: Gives current local state to new subscribers.
836−[%give %fact ~ %atom !>(local.sta)]
837−
838−
839−:: From ++on-poke in reference agent
840−::
841−:: Gives incremented local state to any subscribers on /local
842−[%give %fact ~[/local] %atom !>(+(local))]
843−```
844−
845−### `%kick`
846−
847−Close subscription.
848−
849−Closes a subscription. A subscription close closes the subscription for all or
850−one subscribers on a given path.
851−
852−#### Structure
853−
854−```hoon
855−[%kick (unit path) (unit ship)]
856−```
857−
858−`(unit path)` is the path of the subscription being updated. If no path is
859−given, then the update is only given to the program that instigated the request.
860−Typical use of this mode would be in `+on-watch` to produce a single update to a
861−subscription then close the subscription.
862−
863−`(unit ship)` is the ship to close the subscription for. If no path is given,
864−then the subscription is closed for all subscribers.
865−
866−## Agent Notes
867−
868−Passing a agent note (a 'task') along a wire looks like so.
869−
870−```hoon
871−[%pass =wire %agent [=ship name=term] =task]
872−```
873−
874−`wire` is used to identify the response to the note.
875−
876−`ship` is the ship to pass the note to.
877−
878−`name` is the name of the agent that should receive the note.
879−
880−`task` is the task itself, described below.
881−
882−### `%poke`
883−
884−Poke an application.
885−
886−This note is passed to poke an application with a cage, a marked vase.
887−
888−#### Structure
889−
890−```hoon
891−[%poke =cage]
892−```
893−
894−`cage` is the marked data to poke the application with. It is a pair of a mark
895−and vase.
896−
897−#### Example
898−
899−```hoon
900−:: From ++on-poke in reference agent.
901−::
902−:: Sends an increment poke to the example-gall agent
903−:: on who.act.
904−:*
905− %pass
906− /inc/(scot %p who.act)
907− %agent
908− [who.act %example-gall]
909− %poke %example-gall-action !>([%increment ~])
910−==
911−```
912−
913−### `%watch`
914−
915−Subscribe to an application.
916−
917−This note is given to subscribe to an application at a path
918−
919−#### Structure
920−
921−```hoon
922−[%watch =path]
923−```
924−
925−`path` is the path to be subscribed to.
926−
927−#### Example
928−
929−```hoon
930−:: From ++on-poke in reference agent.
931−::
932−:: Subscribes to the example-gall agent on who.act on the path /local
933−::
934−[%pass /view/(scot %p who.act) %agent [who.act %example-gall] %watch /local]
935−```
936−
937−### `%leave`
938−
939−Unsubscribe from an application.
940−
941− This note is passed to unsubscribe from an application. It should be passed on
942−the same wire that the corresponding `%watch` note for the subscription was
943−passed on.
944−
945−#### Structure
946−
947−```hoon
948−[%leave ~]
949−```
950−
951−#### Example
952−
953−```hoon
954−:: From ++on-poke in reference agent.
955−::
956−:: Unsubscribes from the example-gall agent on who.act
957−[%pass /view/(scot %p who.act) %agent [who.act %example-gall] %leave ~]
958−```
content/docs/userspace/gall/gall.mddeleted−558
@@ -1,558 +0,0 @@
1−+++
2−title = "Overview"
3−weight = 1
4−template = "doc.html"
5−aliases = ["/docs/learn/arvo/gall/"]
6−+++
7−
8−This document describes Gall, the Arvo userspace vane.
9−
10−# Agents
11−
12−Urbit code lives in the following basic categories:
13−
14−- Runtime (Nock interpreter, persistence engine, IO drivers, jets)
15−- Kernel vanes (managed by Arvo)
16−- Userspace agents (managed by Gall, permanent state)
17−- Userspace threads (managed by Spider, transient state)
18−
19−This lays out the framework for the third category: Agents.
20−
21−An agent is a piece of software that is primarily focused on maintaining
22−and distributing a piece of state with a defined structure. It exposes
23−an interface that lets programs read, subscribe to, and manipulate the
24−state. Every event happens in an atomic transaction, so the state is
25−never inconsistent. Since the state is permanent, when the agent is
26−upgraded with a change to the structure of the state, the developer
27−provides a migration function from the old state type to the new state
28−type.
29−
30−It's not too far off to think of an agent as simply a database with
31−developer-defined logic. But an agent is significantly less constrained
32−than a database. Databases are usually tightly constrained in one or
33−more ways because they need to provide certain guarantees (like
34−atomicity) or optimizations (like indexes). Urbit is a single-level
35−store, so atomicity comes for free. Many applications don't use
36−databases because they need relational indices; rather, they use them
37−for their guarantees around persistence. Some do need the indices,
38−though, and it's not hard to imagine an agent which provides a SQL-like
39−interface.
40−
41−On the other hand, an agent is also a lot like what many systems call a
42−"service". An agent is permanent and addressable -- a running program
43−can talk to an agent just by naming it. An agent can perform IO, unlike
44−most databases. This is a critical part of an agent: it performs IO
45−along the same transaction boundaries as changes to its state, so if an
46−effect happens, you know that the associated state change has happened.
47−You should be careful, though, to avoid creating implicit non-atomicity
48−-- eg if it comes into an inconsistent state pending a response to an IO
49−action.
50−
51−But the best way to think about an agent is as a state machine. Like a
52−state machine, any input could happen at any time, and it must react
53−coherently to that input. Ouput (effects) and the next state of the
54−machine are both pure functions of the previous state and the input
55−event. Of course, it's important to ensure there isn't an order of
56−events that could cause your agent to enter an inconsistent state.
57−
58−We often think of state machines as finite state machines, but of course
59−in this instance, the state is not actually finite (though it should be
60−definable in a regular recursive data type).
61−
62−## Specification
63−
64−An agent is defined as a [core](/docs/glossary/core/) with a set of [arms](/docs/glossary/arm/) to handle various
65−events. These handlers usually produce a list of effects and the next
66−state of the agent. The interface definition can be found in
67−`sys/lull.hoon`, which at the time of writing is:
68−
69−```hoon
70−++ agent
71− =< form
72− |%
73− +$ step (quip card form)
74− +$ card (wind note gift)
75− +$ note
76− $% [%arvo =note-arvo]
77− [%agent [=ship name=term] =task]
78− ==
79− +$ task
80− $% [%watch =path]
81− [%watch-as =mark =path]
82− [%leave ~]
83− [%poke =cage]
84− [%poke-as =mark =cage]
85− ==
86− +$ gift
87− $% [%fact path=(unit path) =cage]
88− [%kick path=(unit path) ship=(unit ship)]
89− [%watch-ack p=(unit tang)]
90− [%poke-ack p=(unit tang)]
91− ==
92− +$ sign
93− $% [%poke-ack p=(unit tang)]
94− [%watch-ack p=(unit tang)]
95− [%fact =cage]
96− [%kick ~]
97− ==
98− ++ form
99− $_ ^|
100− |_ bowl
101− ++ on-init
102− *(quip card _^|(..on-init))
103− ::
104− ++ on-save
105− *vase
106− ::
107− ++ on-load
108− |~ old-state=vase
109− *(quip card _^|(..on-init))
110− ::
111− ++ on-poke
112− |~ [mark vase]
113− *(quip card _^|(..on-init))
114− ::
115− ++ on-watch
116− |~ path
117− *(quip card _^|(..on-init))
118− ::
119− ++ on-leave
120− |~ path
121− *(quip card _^|(..on-init))
122− ::
123− ++ on-peek
124− |~ path
125− *(unit (unit cage))
126− ::
127− ++ on-agent
128− |~ [wire sign]
129− *(quip card _^|(..on-init))
130− ::
131− ++ on-arvo
132− |~ [wire sign-arvo]
133− *(quip card _^|(..on-init))
134− ::
135− ++ on-fail
136− |~ [term tang]
137− *(quip card _^|(..on-init))
138− --
139−```
140−
141−Here's a skeleton example of an implementation:
142−
143−```hoon
144−^- agent:gall
145−=| state=@
146−|_ bowl:gall
147−+* this .
148−++ on-init
149− `this
150−::
151−++ on-save
152− !>(state)
153−::
154−++ on-load
155− |= =old-state=vase
156− `this(state !<(@ old-state-vase))
157−::
158−++ on-poke
159− |= [=mark =vase]
160− ~& > state=state
161− ~& got-poked-with-data=mark
162− =. state +(state)
163− `this
164−::
165−++ on-watch
166− |= path
167− `this
168−::
169−++ on-leave
170− |= path
171− `this
172−::
173−++ on-peek
174− |= path
175− *(unit (unit cage))
176−::
177−++ on-agent
178− |= [wire sign:agent:gall]
179− `this
180−::
181−++ on-arvo
182− |= [wire sign-arvo]
183− `this
184−::
185−++ on-fail
186− |= [term tang]
187− `this
188−--
189−```
190−
191−We also supply a `default-agent` library, which is useful if you don't
192−want to handle some of the arms. Most of the above could also be
193−implemented as:
194−
195−```hoon
196−/+ default-agent
197−^- agent:gall
198−=| state=@
199−|_ =bowl:gall
200−+* this .
201− default ~(. (default-agent this %|) bowl)
202−::
203−++ on-init on-init:default
204−++ on-save on-save:default
205−++ on-load on-load:default
206−++ on-poke
207− |= [=mark =vase]
208− ~& > state=state
209− ~& got-poked-with-data=mark
210− =. state +(state)
211− `this
212−::
213−++ on-watch on-watch:default
214−++ on-leave on-leave:default
215−++ on-peek on-peek:default
216−++ on-agent on-agent:default
217−++ on-arvo on-arvo:default
218−++ on-fail on-fail:default
219−--
220−```
221−
222−So, an agent is a core with 10 arms. The handlers correspond to
223−different sorts of input. We'll discuss each of these in detail, but
224−first a few general concepts.
225−
226−## Basic concepts
227−
228−### Interacting with an agent
229−
230−There are two basic ways programs can interact with an agent: you may
231−subscribe to data as described above, or you may "poke" an agent to send
232−it a command. Suppose there is an agent for a calendar service; then,
233−pokes would likely include `%create-event`, `%modify-event`,
234−`%delete-event`, and `%change-time-zone` (along with assocated data).
235−Subscription paths could include `/next-event` and `/all-events`.
236−
237−Agents generally conform to CQRS -- pokes may change state, but
238−subscriptions generally shouldn't. In practice, there may be state
239−changes required to properly initialize the subscription, but these
240−shouldn't change the essential state of the agent.
241−
242−### Cards
243−
244−Most of the handlers produce a `(quip card agent:gall)`, which is just
245−`[(list card) agent:gall]`. The first allows us to produce effects, and
246−the second allows us to maintain state.
247−
248−A card is one of two things: a `note` or a `gift`. You `%pass` `note`s
249−and you `%give` `gift`s. When you pass a `note`, you expect zero or more
250−responses; when you give a `gift`, you will not get a response. Since you
251−may get a response to a `note`, you tag it with a `wire` so that you can
252−identify the response.
253−
254−Thus, we say you "pass a `note` along a `wire`", or you "give a `gift`".
255−These phrases correspond to producing a card that looks like:
256−
257−```hoon
258−[%pass /my/wire a-note]
259−```
260−
261−or
262−
263−```hoon
264−[%give a-gift]
265−```
266−
267−When you give a `gift`, that's the end of the story, but when you pass a
268−`note`, you may get a response. If you do, then the response will come
269−tagged with the `wire` that you used to pass the `note`. It's generally
270−good practice to make your `wire`s fairly unique within your agent, since
271−otherwise you may not be able to distinguish the responses.
272−
273−#### Notes
274−
275−An agent may pass `note`s to either Arvo or another agent. If the `note` is
276−to another agent, then it should usually be one of these:
277−
278−```hoon
279−[%pass /my/wire %agent [our.bowl agent-name] %watch /a/path]
280−[%pass /my/wire %agent [our.bowl agent-name] %leave ~]
281−[%pass /my/wire %agent [our.bowl agent-name] %poke %foo-mark !>(poke-data)]
282−```
283−
284−Note that to unsubscribe to a `path`, you must send the unsubscription on
285−the same `wire` that sent for the original subscription. Don't subscribe
286−to separate `path`s along the same `wire`, because then you can't properly
287−distinguish them for cancelling (besides not being able to distinguish
288−the subscription updates). In other words, besides letting _you_
289−distinguish your `card`s, the `wire` also identifies requests for the system.
290−
291−If the `note` is not to another agent but to Arvo itself, then it is a
292−request to one of the vanes, which are kernel modules that provide
293−various system services, including IO. Here are some examples:
294−
295−```hoon
296−[%pass /my/wire %arvo %b %wait (add now.hid ~s10)]
297−```
298−
299−This is a request to the `%b` vane (Behn, the timer vane) to set a timer
300−for 10 seconds in the future. After 10 seconds, Behn will respond with
301−a `%wake` card, which you will recieve in `+on-arvo`. It will come back
302−on `/my/wire`.
303−
304−```hoon
305−=/ =path /(scot %p our.hid)/home/(scot %da now.hid)/my-file/txt
306−=/ contents=cage [%txt !>(~['text file line 1' 'line 2'])]
307−[%pass /my/wire %arvo %c %info (foal:space:userlib path contents)]
308−```
309−
310−This is a request to the `%c` vane (Clay, the filesystem vane) to write
311−a file to `/my-file/txt` in the home desk. You will not receive a
312−response to this `note`.
313−
314−```hoon
315−=/ =path /my-file/txt
316−=/ =moat [da+now.hid da+(add now.hid ~h1) path]
317−[%pass /my/wire %arvo %c %warp our.hid %home ~ %many & moat]
318−```
319−
320−This is a request to the `%c` vane to send us a `%writ` `card` whenever
321−`/my-file/txt` changes in the next hour. There may be many responses to
322−this note if the file changes many times.
323−
324−```hoon
325−=/ =request:http
326− [%'GET' 'https://example.com' ~ ~]
327−[%pass /my/wire %arvo %i %request request *outbound-config:iris]
328−```
329−
330−This is a request to the `%i` vane (Iris, the HTTP client vane) to make
331−a GET HTTP request to example.com. The response will come as an
332−`%http-response` card.
333−
334−#### Gifts
335−
336−In contrast to the many possible `note`s, there are only two types of
337−`gift`s that an agent may give:
338−
339−```hoon
340−[%give %fact (unit path) =cage]
341−[%give %kick (unit path)]
342−```
343−
344−A subscription update is a new piece of subscription content for all
345−subscribers on a given `path`. If no `path` is given, then the update is
346−only given to the program that instigated this request. Typical use of
347−this mode is in `+on-watch` to give an initial update to a new
348−subscriber to get them up to date.
349−
350−A subscription close closes the subscription for all subscribers on a
351−given `path`. If no `path` is given, then the update is only given to the
352−program that instigated this request. Typical use of this mode would be
353−in `+on-watch` to produce a single update to a subscription then close
354−the subscription.
355−
356−### Vases and cages
357−
358−A `vase` is a piece of dynamic data. Structurally, it's a pair of an
359−explicit reification of a type and an untyped [noun](/docs/glossary/noun/). This lets us
360−represent a value which has a type that isn't known at compile time. A
361−vase has three operations:
362−
363−- `!>` is a unary rune that lifts a statically typed value to a
364− dynamically-typed `vase`. For example, `!>('hi')` gives `[#t/@t q=26.984]`.
365−
366−- `!<` is a binary rune that takes a mold and a dynamically typed `vase`
367− and reduces it to a statically typed value. If the `vase` does not in
368− fact have the type of the mold you give it, then it nest-fails, else
369− it produces `value`. For example, `!<(@t !>('hi'))` produces `'hi'` while `!<(^ !>('hi'))` causes a nest fail..
370−
371−- The compiler takes text and converts it to a `vase` of the compiled
372− code. Agents shouldn't need this directly, but Gall uses this to
373− compile agents to `vase`s, on which it calls `!<(agent:gall compiled-agent-vase)`.
374−
375−A `cage` is simply a pair of a mark and a vase. A mark is a textual tag
376−that should correspond to the particular dynamic type in the vase.
377−
378−In agents, we use vases to represent types which Gall doesn't know about
379−when it was compiled, but which nevertheless need to go outside the
380−agent. In practice, there are three common cases:
381−
382−- The data in a "poke" request is of a type that is defined by each
383− agent, so it must by dynamic. This is the input to `++on-poke` as well
384− as the cage in the `%poke` case of the `%agent` note.
385−
386−- The data in a subscription update is defined by each agent, so it must
387− be dynamic. This is the cage in `%fact`, both when giving the update
388− and in the input to `+on-agent`.
389−
390−- The state of an agent is also unique to each agent. Most of the time,
391− Gall doesn't interact directly with agent's state, but when upgrading
392− an agent, it must pass the state of the old version of the agent to
393− the new version of the agent. This is the output of `+on-save` and
394− the input to `+on-load`.
395−
396−### State
397−
398−In the definition of an agent, the entire core is wrapped with the `^|`
399−rune, which corresponds to the "iron" variance mode. This means it's
400−"contravariant" in the input, which allows Gall to write to the new bowl
401−on every event. It also means that the context of the core is opaque to
402−Gall, which means you can store state in your context in whatever
403−structure you want.
404−
405−This is why most of the handler arms produce not just a list of cards
406−but also a new `agent:gall`. Usually, this will be the "same" agent in
407−the sense that the code will be the same, but you may have changed the
408−state that's stored in its (opaque to Gall) context.
409−
410−The skeleton example above gives an example of keeping an atom as your
411−state. Define the state in the context of your agent core, then you can
412−change it with `=.` or `%=`, as long as you produce the new version of
413−the agent core.
414−
415−When you upgrade an agent, you need to extract the state from your
416−opaque context and produce it to Gall as a dynamically typed vase.
417−Usually, this will be easy: just call `!>` on whatever state you wish
418−to preserve. This is `+on-save`.
419−
420−When the new agent is about to be started, Gall will call it with
421−`+on-load` with the vase just produced above. This allows you to ingest
422−your old state and continue right where you left off.
423−
424−If the type of your state hasn't changed, you can just
425−
426−```hoon
427−=. state !<(state-type old-state-vase)
428−```
429−
430−If it has changed, then it should look more like:
431−
432−```hoon
433−=. state (upgrade-state !<(old-state-type old-state-vase))
434−```
435−
436−It's useful to tag your state with a version number so that the
437−`+upgrade-state` function can take a tagged union of all your old state
438−types and upgrade from any of them to the current state type. For
439−example, it may have the following structure:
440−
441−```hoon
442−+$ old-state-types
443− $% [%0 s=state-0]
444− [%1 s=state-1]
445− [%2 s=state-2]
446− ==
447−++ upgrade-state
448− |= old=old-state-types
449− =? old ?=(%0 -.old)
450− (state-0-to-1 s.old)
451− =? old ?=(%1 -.old)
452− (state-1-to-2 s.old)
453− ?> ?=(%2 -.old)
454− s.old
455−```
456−
457−### Bowl
458−
459−The core takes as input a `bowl`, which includes useful info like the
460−current ship, the current time, and a renewable source of entropy. This
461−information is available to any of the handlers.
462−
463−## Arms
464−
465−A description of each of the handler arms follows.
466−
467−### +on-init
468−
469−This arm is called once when the agent is started. It has no input and
470−lets you perform any initial IO.
471−
472−### +on-save
473−
474−This arm is called immediately before the agent is upgraded. It
475−packages the permament state of the agent in a `vase` for the next version
476−of the agent. Unlike most handlers, this cannot produce effects.
477−
478−### +on-load
479−
480−This arm is called immediately after the agent is upgraded. It receives
481−a `vase` of the state of the previously-running version of the agent,
482−which allows it to cleanly upgrade from the old agent.
483−
484−### +on-poke
485−
486−This arm is called when the agent is "poked". The input is a `cage`, so
487−it's a pair of a mark and a dynamic `vase`.
488−
489−### +on-watch
490−
491−This arm is called when a program wants to subscribe to the agent on a
492−particular `path`. The agent may or may not need to perform setup steps
493−to intialize the subscription. It may produce a `%give`
494−`%subscription-result` to the subscriber to get it up to date, but after
495−this event is complete, it cannot give further updates to a specific
496−subscriber. It must give all further updates to all subscribers on a
497−specific `path`.
498−
499−If this arm crashes, then the subscription is immediately terminated.
500−More specifcally, it never started -- the subscriber will receive a
501−negative `%watch-ack`. You may also produce an explicit `%kick` to
502−close the subscription without crashing -- for example, you could
503−produce a single update followed by a `%kick`.
504−
505−### +on-leave
506−
507−This arm is called when a program becomes unsubscribed to you.
508−Subscriptions may close because the subscriber intentionally
509−unsubscribed, but they also could be closed by an intermediary. For
510−example, if a subscription is from another ship which is currently
511−unreachable, Ames may choose to close the subscription to avoid queueing
512−updates indefinitely. If the program crashes while processing an
513−update, this may also generate an unsubscription. You should consider
514−subscriptions to be closable at any time.
515−
516−### +on-peek
517−
518−This arm is called when a program reads from the agent's "scry"
519−namespace, which should be referentially transparent. Unlike most
520−handlers, this cannot perform IO, and it cannot change the state. All
521−it can do is produce a piece of data to the caller, or not.
522−
523−If this arm produces `[~ ~ data]`, then `data` is the value at the the
524−given `path`. If it produces `[~ ~]`, then there is no data at the given
525−`path` and never will be. If it produces `~`, then we don't know yet
526−whether there is or will be data at the given `path`.
527−
528−### +on-agent
529−
530−This arm is called to handle responses to `%give` moves to other agents.
531−It will be one of the following types of response:
532−
533−- `%poke-ack`: acknowledgment (positive or negative) of a poke. If the
534− value is `~`, then the poke succeeded. If the value is `[~ tang]`,
535− then the poke failed, and a printable explanation (e.g. a stack trace)
536− is given in the `tang`.
537−
538−- `%watch-ack`: acknowledgment (positive or negative) of a subscription.
539− If negative, the subscription is already ended (technically, it never
540− started).
541−
542−- `%fact`: update from the publisher.
543−
544−- `%kick`: notification that the subscription has ended.
545−
546−### +on-arvo
547−
548−This arm is called to handle responses to `%pass` `move`s to vanes. The
549−list of possible responses from the system is statically defined in
550−`sys/lull.hoon` (grep for `+$ sign-arvo`).
551−
552−### +on-fail
553−
554−If an error happens in `+on-poke`, the crash report goes into the
555−`%poke-ack` response. Similarly, if an error happens in
556−`+on-subscription`, the crash report goes into the `%watch-ack`
557−response. If a crash happens in any of the other handlers, the report
558−is passed into this arm.
content/docs/userspace/gall/tutorial.mddeleted−14
@@ -1,14 +0,0 @@
1−+++
2−title = "Tutorial"
3−weight = 5
4−template = "doc.html"
5−+++
6−
7−[**The Complete Guide to Gall and Userspace Apps on
8−Urbit**](https://github.com/timlucmiptev/gall-guide), or more colloquially
9−referred to as just "the Gall Guide," was contributed by a member of our
10−community named `~timluc-miptev`.
11−
12−Our plan is ultimately to make this part of the official documentation found
13−here, but for now, know that it has our official seal of approval and is
14−actively maintained.
content/docs/userspace/landscape/overview.md+5−14
@@ -16,7 +16,6 @@ As of this year, this application suite has arrived at a point where we’re
1616confident both in how all the parts fit together, and confident in the
1717individual parts.
1818
19−
2019## What is Landscape Intended to Be?
2120
2221Landscape is a single suite of userspace applications built to run on top of
@@ -28,16 +27,14 @@ making Landscape itself more extensible for user-developers in late 2021.
2827Landscape is specifically a social suite of applications, meant to enable
2928communication and socializing in many forms.
3029
31−
3230## What is Landscape technically composed of?
3331
3432Landscape is composed of two primary parts: its backend, which runs as a suite of userspace applications (also known as Gall agents), and its frontend interface, which runs as a single-page web application. Both the backend and the frontend may be decomposed into their constituent parts for further understanding.
3533
36−
3734### Backend
3835
3936The Landscape backend is implemented as a collection of long-running
40−microservices known as [Gall agents](/docs/userspace/gall/gall). They can be divided into the following,
37+microservices known as [Gall agents](/docs/arvo/gall/gall). They can be divided into the following,
4138though this is a simplification:
4239
4340- **Graph**: handles storing messages / posts in a non-relational database
@@ -55,7 +52,6 @@ two main categories: [stores](#stores) and [hooks](#hooks). To simply describe
5552the separation of responsibilities, stores are dumb databases (models in MVC)
5653and hooks are for processing data (controllers in MVC).
5754
58−
5955### Stores {#stores}
6056
6157Concisely defined, a store is a dumb database. It does not send outgoing pokes,
@@ -71,11 +67,10 @@ modules. Examples include:
7167and
7268[invite-store](https://github.com/urbit/urbit/blob/ac096d85ae847fcfe8786b51039c92c69abc006e/pkg/arvo/app/invite-store.hoon).
7369
74−
7570### Hooks {#hooks}
7671
7772A hook is a more loosely-defined agent that performs business logic. It should
78−only keep track of a minimal amount of state (*e.g.* active subscriptions). Hooks
73+only keep track of a minimal amount of state (_e.g._ active subscriptions). Hooks
7974are used for a variety of purposes in the system, but there are a few important
8075hook patterns to be aware of:
8176
@@ -106,7 +101,6 @@ received.
106101The poke-proxy-hook conditionally forwards a poke from a foreign ship to a store
107102on the local ship if the foreign ship has permission to do so.
108103
109−
110104### Major Components
111105
112106#### Groups
@@ -170,24 +164,21 @@ be thought of as a database join between the `%group-store` and the
170164`%graph-store`, as it provides bidirectional indices for querying all of the
171165graphs that a group has, or which group a particular graph is associated with.
172166
173−
174167#### Contacts
175168
176169Contacts are your address book. Individual ships (people) you talk to may have a
177− nickname, a profile picture, or a colored sigil background that helps you
178− identify them in groups, chatrooms, blogs, and collections.
179−
170+nickname, a profile picture, or a colored sigil background that helps you
171+identify them in groups, chatrooms, blogs, and collections.
180172
181173#### Invites
182174
183175Invites is a simple subsystem that allows you to send all the details of a given
184−resource (*e.g.* graph or group) to some other ship so that they may join it if
176+resource (_e.g._ graph or group) to some other ship so that they may join it if
185177they desire to. Invite acceptance is handled with threads that listen to the
186178`%invite-store` using the `%observe-hook` and invite sending is handled with the
187179`%invite-hook`, which allows any ship to send you an invite without any
188180permissions involved.
189181
190−
191182#### Hark
192183
193184Hark is a generic notification and unread-tracking subsystem that currently
content/docs/userspace/overview.md+2−2
@@ -6,9 +6,9 @@ template = "doc.html"
66
77Urbit's userspace is managed by Arvo's Gall vane.
88
9−## [Gall](/docs/userspace/gall/gall)
9+## [Gall Guide](/docs/userspace/gall-guide)
1010
11−Resources on Gall which manages userspace applications.
11+Learn how to develop Gall agents.
1212
1313## [Graph Store](/docs/userspace/graph-store)
1414
content/docs/userspace/threads/overview.md+13−12
@@ -4,27 +4,26 @@ weight = 1
44template = "doc.html"
55+++
66
7−As discussed in the [Gall](/docs/userspace/gall/gall) section, Urbit code lives in the following basic
8−categories:
7+Urbit code lives in the following basic categories:
98
109- Runtime (Nock interpreter, persistence engine, IO drivers, jets)
1110- Kernel vanes (managed by Arvo)
1211- Userspace agents (managed by Gall, permanent state)
1312- Userspace threads (managed by Spider, transient state)
1413
15−This describes the last category: Threads.
14+This describes the last category: Threads.
1615
1716A thread is a monadic function that takes arguments and produces a
18−result. It may perform input and output while running, so it is not a
19−pure function. It may fail.
17+result. It may perform input and output while running, so it is not a
18+pure function. It may fail.
2019
21−An agent's strength is that it's permanent and bulletproof. All state
20+An agent's strength is that it's permanent and bulletproof. All state
2221transitions are defined, and each action it performs is a transaction.
2322Code upgrades preserve existing state.
2423
25−An agent's weakness is complex input and output. Since each state
24+An agent's weakness is complex input and output. Since each state
2625transition must be explicitly handled, the complexity of an agent
27−explodes with the amount of IO it handles. At best, this results in
26+explodes with the amount of IO it handles. At best, this results in
2827long and complex code; at worst, unexpected states are mishandled,
2928corrupting permanent state.
3029
@@ -35,17 +34,17 @@ provide a natural framework for IO.
3534A thread's weakness is that it's impermanent and may fail unexpectedly.
3635In most of its intermediate states, it expects only a small number of
3736events (usually one), so if it receives anything it didn't expect, it
38−fails. When code is upgraded, it's impossible to upgrade a running
37+fails. When code is upgraded, it's impossible to upgrade a running
3938thread, so it fails.
4039
41−Thus, for anything that needs to be permament, use an agent. When you
40+Thus, for anything that needs to be permament, use an agent. When you
4241need to do a long or complex sequence of IO operations, reduce that to a
43−single logical IO operation by spinning it out into a thread. If you
42+single logical IO operation by spinning it out into a thread. If you
4443only change your agent's state in response to success of the thread, an
4544IO failure will never result in partially applied state changes.
4645
4746A thread may also be run from the dojo by prefixing its name with `-`
48−and giving it any arguments it requires. If alone, any result will be
47+and giving it any arguments it requires. If alone, any result will be
4948printed to the screen; else the output may be piped into an agent or
5049other sinks.
5150
@@ -60,6 +59,7 @@ These docs walk through the fundamental things you need to know to write threads
60595. [Summary](/docs/userspace/threads/basics/summary)
6160
6261## Gall
62+
6363These docs walk through the basics of interacting with threads from gall agents.
6464
65651. [Start a thread](/docs/userspace/threads/gall/start-thread)
@@ -78,4 +78,5 @@ These docs walk through the basics of interacting with threads from gall agents.
7878- [Take a fact](/docs/userspace/threads/examples/take-fact) - Subscribe to an agent and receive a fact.
7979
8080## [Reference](/docs/userspace/threads/reference)
81+
8182Basic reference information. For usage of particular `strandio` functions just refer directly to `/lib/strandio/hoon` since they're largely self-explanatory.