@@ -0,0 +1,958 @@
1++++
2+title = "API Reference"
3+weight = 3
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+```