on master help sign in
gall-guide: various fang suggestions
ae02bf4tinnus-napbus
content/docs/userspace/gall-guide/10-scry.md+3−3
@@ -11,7 +11,7 @@ rune documentation](/docs/hoon/reference/rune/dot#-dotket).
11
11
12## Scrying
12## Scrying
13
13
14−Scries are purely read-only requests to vanes and agents which can be initiated
14+Scries are read-only requests to vanes and agents which can be initiated
15from anywhere in any code, during its evaluation. If successful, the requested
15from anywhere in any code, during its evaluation. If successful, the requested
16data is returned immediately to that point in the code, otherwise it crashes.
16data is returned immediately to that point in the code, otherwise it crashes.
17This is in contrast to passing around `card`s, which aren't read-only and which
17This is in contrast to passing around `card`s, which aren't read-only and which
@@ -26,7 +26,7 @@ their format:
26
26
27![scry summary diagram](https://media.urbit.org/docs/arvo/scry-diagram-v2.svg)
27![scry summary diagram](https://media.urbit.org/docs/arvo/scry-diagram-v2.svg)
28
28
29−A note on `care`s: Cares are most fully exploited by Clay, where they specify
29+A note on `care`s: Cares are most carefully implemented by Clay, where they specify
30submodules and have tightly defined behaviors. For Gall agents, most of these
30submodules and have tightly defined behaviors. For Gall agents, most of these
31don't have any special behavior, and are just used to indicate the general kind
31don't have any special behavior, and are just used to indicate the general kind
32of data produced by the endpoint. There are a handful of exceptions to this:
32of data produced by the endpoint. There are a handful of exceptions to this:
@@ -166,7 +166,7 @@ requested data. In such cases, you can just produce a cell of `[~ ~]` for the
166for the dotket expression which initiated the scry. In some cases you may want
166for the dotket expression which initiated the scry. In some cases you may want
167that, but in other cases you may not, so instead you could wrap the data inside
167that, but in other cases you may not, so instead you could wrap the data inside
168the `vase` in a `unit` and have _that_ be null instead. It all depends on the
168the `vase` in a `unit` and have _that_ be null instead. It all depends on the
169−needs of your particular application.
169+needs of your particular application and its clients.
170
170
171## Example
171## Example
172
172
content/docs/userspace/gall-guide/12-next-steps.md+1−1
@@ -7,7 +7,7 @@ template = "doc.html"
7We've now covered all the arms of a Gall agent, and everything you need to know
7We've now covered all the arms of a Gall agent, and everything you need to know
8to start writing your own agent.
8to start writing your own agent.
9
9
10−The one thing we haven't touched on is front-end development and integration,
10+The things haven't touched on yet are front-end development and integration,
11Eyre's HTTP API for communicating with agents from the web, and dealing with
11Eyre's HTTP API for communicating with agents from the web, and dealing with
12JSON data. A second part to the Gall Guide is coming soon, and will focus
12JSON data. A second part to the Gall Guide is coming soon, and will focus
13exclusively on those aspects. In the mean time, you can refer to the following
13exclusively on those aspects. In the mean time, you can refer to the following
content/docs/userspace/gall-guide/2-agent.md+3−3
@@ -34,14 +34,14 @@ HTTP requests from the front-end, etc.
34
34
35- `on-poke`: Handles any calls that aren't subscriptions, i.e. one-time actions.
35- `on-poke`: Handles any calls that aren't subscriptions, i.e. one-time actions.
36- `on-watch`: Handles subscription requests from other entities.
36- `on-watch`: Handles subscription requests from other entities.
37−- `on-leave`: Handles unsubscribe requests from other, currently subscribed
37+- `on-leave`: Handles unsubscribe notifications from other, previously subscribed
38 entities.
38 entities.
39
39
40### Response handlers
40### Response handlers
41
41
42These two arms handle responses to requests our agent previously initiated.
42These two arms handle responses to requests our agent previously initiated.
43
43
44−- `on-agent`: Handles subscription updates and request acknowledgements from
44+- `on-agent`: Handles request acknowledgements and subscription updates from
45 other agents.
45 other agents.
46- `on-arvo`: Handles subscription updates, request acknowledgements, and
46- `on-arvo`: Handles subscription updates, request acknowledgements, and
47 responses from vanes.
47 responses from vanes.
@@ -58,7 +58,7 @@ These two arms handle responses to requests our agent previously initiated.
58## Bowl
58## Bowl
59
59
60The sample of a Gall agent door is always a `bowl:gall`. Every time an event triggers the
60The sample of a Gall agent door is always a `bowl:gall`. Every time an event triggers the
61−agent, Gall populates the bowl with things like the current date-time, entropy,
61+agent, Gall populates the bowl with things like the current date-time, fresh entropy,
62subscription information, which ship the request came from, etc, so that all the
62subscription information, which ship the request came from, etc, so that all the
63arms of the agent have access to that data. For the exact structure and contents
63arms of the agent have access to that data. For the exact structure and contents
64of the bowl, have a read through [its entry in the Gall vane types
64of the bowl, have a read through [its entry in the Gall vane types
content/docs/userspace/gall-guide/3-imports-and-aliases.md+2−2
@@ -44,7 +44,7 @@ first is your agent core itself, and the second is a `?`. If `help` is `%.y` (eq
44will crash in all cases. If `help` is `%.n` (equivalently, `%|`), it will use its defaults. You would
44will crash in all cases. If `help` is `%.n` (equivalently, `%|`), it will use its defaults. You would
45almost always have `help` as `%.n`.
45almost always have `help` as `%.n`.
46
46
47−The wet gate returns a `agent:gall` door with a sample of `bowl:gall` - a
47+The wet gate returns an `agent:gall` door with a sample of `bowl:gall` - a
48typical agent core. Usually you would define an alias for it in a virtual arm
48typical agent core. Usually you would define an alias for it in a virtual arm
49([explained below](#virtual-arms)) so it's simple to call.
49([explained below](#virtual-arms)) so it's simple to call.
50
50
@@ -88,7 +88,7 @@ The generator also has a few useful optional arguments:
88 - `[outgoing %term %agent-name]`
88 - `[outgoing %term %agent-name]`
89
89
90By default it will retrieve your agent's state by using its `on-save` arm, but
90By default it will retrieve your agent's state by using its `on-save` arm, but
91−if you include a scry endpoint with a path of `/x/dbug/state`, it will use that
91+if your app implements a scry endpoint with a path of `/x/dbug/state`, it will use that
92instead.
92instead.
93
93
94We haven't yet covered some of the concepts described here, so don't worry if
94We haven't yet covered some of the concepts described here, so don't worry if
content/docs/userspace/gall-guide/4-lifecycle.md+7−7
@@ -4,7 +4,7 @@ weight = 20
4template = "doc.html"
4template = "doc.html"
5+++
5+++
6
6
7−In the last lesson we look at a couple of useful things used as boilerplate in
7+In the last lesson we looked at a couple of useful things used as boilerplate in
8most agents. Now we're going to get into the guts of how agents work, and start
8most agents. Now we're going to get into the guts of how agents work, and start
9looking at what the agent arms do. The first thing we'll look at is the agent's
9looking at what the agent arms do. The first thing we'll look at is the agent's
10state, and the three arms for managing it: `on-init`, `on-save`, and `on-load`.
10state, and the three arms for managing it: `on-init`, `on-save`, and `on-load`.
@@ -28,7 +28,7 @@ Once initialized, an agent will just go on doing its thing - processing events,
28updating its state, producing effects, etc. At some point, you'll likely want to
28updating its state, producing effects, etc. At some point, you'll likely want to
29push an update for your agent. Maybe it's a bug fix, maybe you want to add extra
29push an update for your agent. Maybe it's a bug fix, maybe you want to add extra
30features. Whatever the reason, you need to change the source code of your agent,
30features. Whatever the reason, you need to change the source code of your agent,
31−so you commit a modified version of the file to Clay. When this happens, three things happen:
31+so you commit a modified version of the file to Clay. When the commit completes, Gall updates the app as follows:
32
32
33- The agent's `on-save` arm is called, which packs the agent's state in a `vase`
33- The agent's `on-save` arm is called, which packs the agent's state in a `vase`
34 and exports it.
34 and exports it.
@@ -426,13 +426,13 @@ this new version of the agent, it would be, so we still need to update it.
426 ==
426 ==
427```
427```
428
428
429−We've updated the wuthep expression with a new case that handles our new state
429+We've updated the `?-` expression with a new case that handles our new state
430type, and for the old state type we've added a function that converts it to the
430type, and for the old state type we've added a function that converts it to the
431new type - in this case by duplicating `val` and changing the head-tag from `%0`
431new type - in this case by duplicating `val` and changing the head-tag from `%0`
432to `%1`. This is an extremely simple state type transition function - it would
432to `%1`. This is an extremely simple state type transition function - it would
433likely be more complicated for an agent with real functionality.
433likely be more complicated for an agent with real functionality.
434
434
435−Let's now use `dbug` to check our state has successfully been updated to the new
435+Let's now use `dbug` to confirm our state has successfully been updated to the new
436type:
436type:
437
437
438```
438```
@@ -447,10 +447,10 @@ type:
447 state import and state version transition.
447 state import and state version transition.
448- This is managed by three arms: `on-init`, `on-save` and `on-load`.
448- This is managed by three arms: `on-init`, `on-save` and `on-load`.
449- `on-init` initializes the agent and is called when it's first installed.
449- `on-init` initializes the agent and is called when it's first installed.
450−- `on-save` exports the agent's state and is usually called during upgrade or
450+- `on-save` exports the agent's state and is called during upgrade or
451 when an app is suspended.
451 when an app is suspended.
452−- `on-load` imports an agent's state and is usually called during upgrade or
452+- `on-load` imports an agent's state and is called during upgrade or
453− when an app is unsuspended. It typically also handles converting data from old
453+ when an app is unsuspended. It also handles converting data from old
454 state versions to new state versions.
454 state versions to new state versions.
455- The type of an agent's state is typically defined in a separate core.
455- The type of an agent's state is typically defined in a separate core.
456- The state type is typically versioned, with a new type definition for each
456- The state type is typically versioned, with a new type definition for each
content/docs/userspace/gall-guide/6-pokes.md+11−7
@@ -6,7 +6,7 @@ template = "doc.html"
6
6
7In this lesson we'll look at sending and receiving one-off messages called
7In this lesson we'll look at sending and receiving one-off messages called
8`%poke`s. We'll look at the `on-poke` agent arm which handles incoming pokes.
8`%poke`s. We'll look at the `on-poke` agent arm which handles incoming pokes.
9−We'll also introduce the `on-agent` arm, and look at one kind of response it can
9+We'll also introduce the `on-agent` arm, and look at the one kind of response it can
10take - a `%poke-ack`.
10take - a `%poke-ack`.
11
11
12## Receiving a poke
12## Receiving a poke
@@ -106,8 +106,8 @@ produce the `(quip card _this)` like so:
106
106
107The [colcab](/docs/hoon/reference/rune/col#_-colcab) (`:_`) rune makes an
107The [colcab](/docs/hoon/reference/rune/col#_-colcab) (`:_`) rune makes an
108inverted cell, it's just `:-` but with the head and tail swapped. We use colcab
108inverted cell, it's just `:-` but with the head and tail swapped. We use colcab
109−to produce the `(quip card _this)` because the list of cards is typically
109+to produce the `(quip card _this)` because the list of cards is "heavier"
110−"heavier" than the new agent core expression (`this`), so it makes it more
110+here than the new agent core expression (`this`), so it makes it more
111readable.
111readable.
112
112
113### Receiving the `%poke-ack`
113### Receiving the `%poke-ack`
@@ -144,7 +144,9 @@ The simplest way to handle a `%poke-ack` by passing it to `default-agent`'s
144`on-agent` arm, which will just print an error message to the terminal if it's a
144`on-agent` arm, which will just print an error message to the terminal if it's a
145nack, and otherwise do nothing. Sometimes you'll want your agent to do something
145nack, and otherwise do nothing. Sometimes you'll want your agent to do something
146different depending on whether the poke failed or succeeded (and therefore
146different depending on whether the poke failed or succeeded (and therefore
147+whether it's a nack or an ack).
148+
147−whether it's a nack or an ack). As stated in the [Precepts](/docs/development/precepts#specifics): "Route on wire before sign, never sign before wire.". Thus we first test the
149+As stated in the [Precepts](/docs/development/precepts#specifics): "Route on wire before sign, never sign before wire.". Thus we first test the
148`wire` so you can tell what the `%poke-ack` was for. You might do something
150`wire` so you can tell what the `%poke-ack` was for. You might do something
149like:
151like:
150
152
@@ -216,7 +218,8 @@ receiving pokes. Here's the first, an agent that receives pokes:
216 %noun
218 %noun
217 =/ action !<(?(%inc %dec) vase)
219 =/ action !<(?(%inc %dec) vase)
218 ?- action
220 ?- action
219− %inc `this(val +(val))
221+ %inc `this(val +(val))
222+ ::
220 %dec
223 %dec
221 ?: =(0 val)
224 ?: =(0 val)
222 ~| "Can't decrement - already zero!"
225 ~| "Can't decrement - already zero!"
@@ -324,7 +327,7 @@ dojo: app poke failed
324### `pokeit.hoon`
327### `pokeit.hoon`
325
328
326Here's a second agent. It takes a poke of `%inc` or `%dec` like before, but
329Here's a second agent. It takes a poke of `%inc` or `%dec` like before, but
327−rather that updating its own state, it sends two pokes to `%pokeme`, so
330+rather than updating its own state, it sends two pokes to `%pokeme`, so
328`%pokeme`'s state will be incremented or decremented by two.
331`%pokeme`'s state will be incremented or decremented by two.
329
332
330```hoon
333```hoon
@@ -368,6 +371,7 @@ rather that updating its own state, it sends two pokes to `%pokeme`, so
368 :~ [%pass /inc %agent [our.bowl %pokeme] %poke %noun !>(%inc)]
371 :~ [%pass /inc %agent [our.bowl %pokeme] %poke %noun !>(%inc)]
369 [%pass /inc %agent [our.bowl %pokeme] %poke %noun !>(%inc)]
372 [%pass /inc %agent [our.bowl %pokeme] %poke %noun !>(%inc)]
370 ==
373 ==
374+ ::
371 %dec
375 %dec
372 :_ this
376 :_ this
373 :~ [%pass /dec %agent [our.bowl %pokeme] %poke %noun !>(%dec)]
377 :~ [%pass /dec %agent [our.bowl %pokeme] %poke %noun !>(%dec)]
@@ -476,7 +480,7 @@ Let's try it out:
476
480
477`%pokeit` has received positive `%poke-ack`s, which means both pokes succeeded.
481`%pokeit` has received positive `%poke-ack`s, which means both pokes succeeded.
478It could tell they were increments because the `%poke-ack`s came back on the
482It could tell they were increments because the `%poke-ack`s came back on the
479−`/inc` path we specified. We can check the state of `%pokeme` to confirm:
483+`/inc` wire we specified. We can check the state of `%pokeme` to confirm:
480
484
481```
485```
482> 2
486> 2
content/docs/userspace/gall-guide/7-sur-and-marks.md+7−6
@@ -27,10 +27,10 @@ typically define them in a separate core saved in the `/sur` directory of the
27desk. The `/sur` directory is short for "**s**truct**ur**es", and is the
27desk. The `/sur` directory is short for "**s**truct**ur**es", and is the
28canonical location for userspace type definitions.
28canonical location for userspace type definitions.
29
29
30−With this approach, your agent can simply import the structure file and make use
30+With this approach, your agent can simply import the structures file and make use
31of its types. Additionally, if someone else wants to write an agent that
31of its types. Additionally, if someone else wants to write an agent that
32interfaces with yours, they can include your structure file in their own desk
32interfaces with yours, they can include your structure file in their own desk
33−and easily interact with your agent's API.
33+to interact with your agent's API in a type-safe way.
34
34
35#### Example
35#### Example
36
36
@@ -138,6 +138,7 @@ manner:
138 !>(`update:todo`action)
138 !>(`update:todo`action)
139 ==
139 ==
140 ==
140 ==
141+ ::
141 %allow
142 %allow
142 `state(friends (~(put in friends) who.action))
143 `state(friends (~(put in friends) who.action))
143 ::
144 ::
@@ -312,8 +313,8 @@ The Ames vane decrypts and verifies the messages using keys in the Jael vane,
312which are obtained from the [Azimuth Ethereum contract](/docs/azimuth/azimuth-eth) and [Layer 2 data](/docs/azimuth/l2/layer2) where Urbit ID ownership
313which are obtained from the [Azimuth Ethereum contract](/docs/azimuth/azimuth-eth) and [Layer 2 data](/docs/azimuth/l2/layer2) where Urbit ID ownership
313and keys are recorded. This means the originating `@p` of all messages are
314and keys are recorded. This means the originating `@p` of all messages are
314cryptographically validated before being passed on to Gall, so the `@p`
315cryptographically validated before being passed on to Gall, so the `@p`
315−specified in the `src` field of the `bowl` can be trusted to be correct, and
316+specified in the `src` field of the `bowl` can be trusted to be correct, which
316−checking permissions are very simple.
317+makes checking permissions very simple.
317
318
318You're free to use whatever logic you want for this, but the most common way is
319You're free to use whatever logic you want for this, but the most common way is
319to use [wutgar](/docs/hoon/reference/rune/wut#-wutgar) (`?>`) and
320to use [wutgar](/docs/hoon/reference/rune/wut#-wutgar) (`?>`) and
@@ -391,8 +392,8 @@ Permissions:
391 of the `bowl` with the `@p`.
392 of the `bowl` with the `@p`.
392- Permissions are most commonly enforced with wutgar (`?>`) and wutgal (`?<`)
393- Permissions are most commonly enforced with wutgar (`?>`) and wutgal (`?<`)
393 assertions in the relevant agent arms.
394 assertions in the relevant agent arms.
394−- Messages can be restricted to the local ship with `=(src.bowl our.bowl)` or to
395+- Messages can be restricted to the local ship with `?> =(src.bowl our.bowl)` or to
395− its moons as well with `(team:title our.bowl src.bowl)`.
396+ its moons as well with `?> (team:title our.bowl src.bowl)`.
396- There are many other ways to handle permissions, it just depends on the needs
397- There are many other ways to handle permissions, it just depends on the needs
397 of the particular agent.
398 of the particular agent.
398
399
content/docs/userspace/gall-guide/8-subscriptions.md+5−7
@@ -18,10 +18,8 @@ target its paths. An agent can kick subscribers from its paths, and subscribers
18can unsubscribe from any paths.
18can unsubscribe from any paths.
19
19
20The subscription paths an agent defines can be simple and fixed like
20The subscription paths an agent defines can be simple and fixed like
21−`/foo/bar/baz`. They can also be dynamic, taking data of a particular atom aura
21+`/foo/bar/baz`. They can also be dynamic, containing data of a particular atom aura
22−encoded in certain elements of the path, and then decoding it to an atom of that
23−aura. These paths can therefore be as simple or complex as you need for your
22+encoded in certain elements of the path. These paths can therefore be as simple or complex as you need for your particular application.
24−particular application.
25
23
26For a deeper explanation of subscription mechanics in Arvo, you can refer to
24For a deeper explanation of subscription mechanics in Arvo, you can refer to
27Arvo's [Subscriptions](/docs/arvo/concepts/subscriptions) section.
25Arvo's [Subscriptions](/docs/arvo/concepts/subscriptions) section.
@@ -101,7 +99,7 @@ Updates to subscribers would usually be sent from other arms, but there's one
101special case for `on-watch` which is very useful. Normally updates can only be
99special case for `on-watch` which is very useful. Normally updates can only be
102sent to all subscribers of a particular path - you can't target a specific
100sent to all subscribers of a particular path - you can't target a specific
103subscriber. There's one exception to this: In `on-watch`, when there's a new
101subscriber. There's one exception to this: In `on-watch`, when there's a new
104−subscription, you can send a `%fact` back with a null `(list path)`, and it'll
102+subscription, you can send a `%fact` back with an empty `(list path)`, and it'll
105only go to the new subscriber. This is most useful when you want to give the
103only go to the new subscriber. This is most useful when you want to give the
106subscriber some initial state, which you otherwise couldn't do without sending
104subscriber some initial state, which you otherwise couldn't do without sending
107it to everyone. It might look something like this:
105it to everyone. It might look something like this:
@@ -169,7 +167,7 @@ it: Subscribing to other agents. This is done by `%pass`ing the target agent a
169If your agent's subscription request is successful, updates will come in to your
167If your agent's subscription request is successful, updates will come in to your
170agent's `on-agent` arm on the `wire` specified (`/some/wire` in this example).
168agent's `on-agent` arm on the `wire` specified (`/some/wire` in this example).
171The `wire` can be anything you like - its purpose is for your agent to figure
169The `wire` can be anything you like - its purpose is for your agent to figure
172−out which subscription the updates are for. The `[ship term]` pair specifies the
170+out which subscription the updates came from. The `[ship term]` pair specifies the
173ship and agent you're trying to subscribe to, and the final `path` (`/some/path`
171ship and agent you're trying to subscribe to, and the final `path` (`/some/path`
174in this example) is the path you want to subscribe to - a `path` the target
172in this example) is the path you want to subscribe to - a `path` the target
175agent has defined in its `on-watch` arm.
173agent has defined in its `on-watch` arm.
@@ -241,7 +239,7 @@ the initial `%watch-ack`. The `%fact` `sign` will have the following format:
241
239
242You would typically handle such `%fact`s in the following manner: Test the
240You would typically handle such `%fact`s in the following manner: Test the
243`wire`, test whether the `sign` is a `%fact`, test the `mark` in the `cage`,
241`wire`, test whether the `sign` is a `%fact`, test the `mark` in the `cage`,
244−extract the data from the `vase` in the `cage`, and apply your logic. Again, route on `wire` before `sign` is one of the [Precepts](/docs/development/precepts#specifics). For example:
242+extract the data from the `vase` in the `cage`, and apply your logic. Again, routing on `wire` before `sign` is one of the [Precepts](/docs/development/precepts#specifics). For example:
245
243
246```hoon
244```hoon
247++ on-agent
245++ on-agent
content/docs/userspace/gall-guide/intro.md+2−2
@@ -43,8 +43,8 @@ associated state change has happened.
43
43
44But the best way to think about an agent is as a state machine. Like a state
44But the best way to think about an agent is as a state machine. Like a state
45machine, any input could happen at any time, and it must react coherently to
45machine, any input could happen at any time, and it must react coherently to
46−that input. Output (effects) and the next state of the machine are both pure
46+that input. Output (effects) and the next state of the machine are a pure
47−functions of the previous state and the input event.
47+function of the previous state and the input event.
48
48
49## Table of Contents
49## Table of Contents
50
50
content/docs/userspace/gall-guide/types.md+2−2
@@ -159,7 +159,7 @@ most commonly a subscription path - you might subscribe for updates to
159agent.
159agent.
160
160
161A `path` might just be a series of fixed `@ta` like `/foo/bar`, but some
161A `path` might just be a series of fixed `@ta` like `/foo/bar`, but some
162−elements might also be variable and encode atom auras, or some other format. For
162+elements might also be variable and include encoded atoms, or some other datum. For
163example, you might like to include a date in the path like
163example, you might like to include a date in the path like
164`/updates/~2021.10.31..07.24.27..db68`. Other agents might create the path by
164`/updates/~2021.10.31..07.24.27..db68`. Other agents might create the path by
165doing something like:
165doing something like:
@@ -171,7 +171,7 @@ doing something like:
171Then, when you get a subscription request, you might do something like:
171Then, when you get a subscription request, you might do something like:
172
172
173```hoon
173```hoon
174−?+ path (on-watch:def path)
174+?+ path !!
175 [%updates @ ~]
175 [%updates @ ~]
176 =/ date=@da (slav %da i.t.path)
176 =/ date=@da (slav %da i.t.path)
177 ...(rest of code)...
177 ...(rest of code)...