on master help sign in
Restructure clay docs into api ref and examples
981aeddtinnus-napbus
arvo/clay/_index.md+4−20
@@ -27,26 +27,10 @@ Explanations of the many data types found throughout Clay.
27
27
28Reference for Clay's various scry endpoints.
28Reference for Clay's various scry endpoints.
29
29
30−[Read and Subscribe](@/docs/arvo/clay/read.md)
30+[API Reference](@/docs/arvo/clay/tasks.md)
31
31
32−How to read files and subscribe for changes.
32+Details of the various `task`s you can use to interact with Clay.
33
33
34−[Write and Modify](@/docs/arvo/clay/write.md)
34+[Examples](@/docs/arvo/clay/examples.md)
35
35
36−How to add, delete and modify files.
36+Example usage of the various Clay `task`s.
37−
38−[Manage Mounts](@/docs/arvo/clay/mounts.md)
39−
40−How to manage clay unix mounts programmatically.
41−
42−[Merge Desks](@/docs/arvo/clay/merge.md)
43−
44−How to merge desks programmatically.
45−
46−[Permissions](@/docs/arvo/clay/permissions.md)
47−
48−How to manage file permissions in clay.
49−
50−[Foreign Ships](@/docs/arvo/clay/foreign-requests.md)
51−
52−How to make requests to foreign ships.
arvo/clay/clay.md+4−20
@@ -56,26 +56,10 @@ Explanations of the many data types found throughout Clay. (Up to date as of Apr
56
56
57Reference for Clay's various scry endpoints.
57Reference for Clay's various scry endpoints.
58
58
59−[Read and Subscribe](@/docs/arvo/clay/read.md)
59+[API Reference](@/docs/arvo/clay/tasks.md)
60
60
61−How to read files and subscribe for changes.
61+Details of the various `task`s you can use to interact with Clay.
62
62
63−[Write and Modify](@/docs/arvo/clay/write.md)
63+[Examples](@/docs/arvo/clay/examples.md)
64
64
65−How to add, delete and modify files.
65+Example usage of the various Clay `task`s.
66−
67−[Manage Mounts](@/docs/arvo/clay/mounts.md)
68−
69−How to manage clay unix mounts programmatically.
70−
71−[Merge Desks](@/docs/arvo/clay/merge.md)
72−
73−How to merge desks programmatically.
74−
75−[Permissions](@/docs/arvo/clay/permissions.md)
76−
77−How to manage file permissions in clay.
78−
79−[Foreign Ships](@/docs/arvo/clay/foreign-requests.md)
80−
81−How to make requests to foreign ships.
arvo/clay/examples.mdnew file+841
@@ -0,0 +1,841 @@
1++++
2+title = "Examples"
3+weight = 7
4+template = "doc.html"
5++++
6+
7+# Contents
8+
9+- [Introduction](#introduction)
10+- [Read and Subscribe](#read-and-subscribe)
11+ - [%sing](#sing) - Read a file or directory.
12+ - [%next](#next) - Subscribe for the next change to a file or directory.
13+ - [%mult](#mult) - Subscribe for the next change to a set of files and/or directories.
14+ - [%many](#many) - Track changes to a `desk` for the specified range of revisions.
15+ - [Cancel Subscription](#cancel-subscription)
16+- [Write and Modify](#write-and-modify)
17+ - [%ins](#ins) - Add a file.
18+ - [%del](#del) - Delete a file.
19+ - [%mut](#mut) - Change a file.
20+ - [Multiple Changes](#multiple-changes) - Change multiple files.
21+- [Manage Mounts](#manage-mounts)
22+ - [%boat](#boat) - List mounts.
23+ - [%mont](#mont) - Mount something.
24+ - [%ogre](#ogre) - Unmount something.
25+ - [%dirk](#dirk) - Commit changes.
26+- [Merge Desks](#merge-desks)
27+ - [%merg](#merg)
28+- [Permissions](#permissions)
29+ - [%perm](#perm) - Set file permissions.
30+ - [%cred](#cred) - Add permission group.
31+ - [%crew](#crew) - Get permission groups.
32+ - [%crow](#crow) - Get group usage.
33+- [Foreign Ships](#foreign-ships)
34+ - [%warp](#warp) - Read a file on a foreign ship.
35+ - [%merg](#merg) - Merge from a foreign `desk`.
36+
37+# Introduction
38+
39+This document contains a number of examples of interacting with Clay using its various `task`s. Sections correspond to the general details in the [API Reference](@/docs/arvo/clay/tasks.md) document.
40+
41+Most examples use one of these two threads which you can save to the `ted` directory of your `%home` `desk`:
42+
43+`send-task.hoon`
44+
45+```hoon
46+/- spider
47+/+ strandio
48+=, strand=strand:spider
49+^- thread:spider
50+|= arg=vase
51+=/ m (strand ,vase)
52+^- form:m
53+=/ uarg !< (unit task:clay) arg
54+?~ uarg
55+ (strand-fail:strand %no-arg ~)
56+=/ =task:clay u.uarg
57+=/ =card:agent:gall [%pass /foo %arvo %c task]
58+;< ~ bind:m (send-raw-card:strandio card)
59+(pure:m !>(~))
60+```
61+
62+`send-task-take-gift.hoon`
63+
64+```hoon
65+/- spider
66+/+ strandio
67+=, strand=strand:spider
68+^- thread:spider
69+|= arg=vase
70+=/ m (strand ,vase)
71+^- form:m
72+=/ uarg !< (unit task:clay) arg
73+?~ uarg
74+ (strand-fail:strand %no-arg ~)
75+=/ =task:clay u.uarg
76+=/ =card:agent:gall [%pass /foo %arvo %c task]
77+;< ~ bind:m (send-raw-card:strandio card)
78+;< res=[wire sign-arvo] bind:m take-sign-arvo:strandio
79+~& +>:res
80+(pure:m !>(~))
81+```
82+
83+# Read and Subscribe
84+
85+See the [Read and Subscribe](@/docs/arvo/clay/tasks.md#read-and-subscribe) section of the [API Reference](@/docs/arvo/clay/tasks.md) document for general details.
86+
87+## %sing
88+
89+Here we'll look at reading files by passing Clay a `%warp` `task` with a `%sing` `rave` and receiving a `%writ` `gift` containing the data in response.
90+
91+
92+Using the `send-task-take-gift.hoon` thread, let's try reading `gen/hood/hi.hoon`:
93+
94+```
95+> -send-task-take-gift [%warp our %home ~ %sing %x da+now /gen/hood/hi/hoon]
96+```
97+
98+You should see something like this as the output:
99+
100+```
101+[ %writ
102+ p
103+ [ ~
104+ [ p=[p=%x q=[%da p=~2021.5.20..23.37.50..e79b] r=%home]
105+ q=/gen/hood/hi/hoon
106+ r
107+ [ p=%hoon
108+ q
109+ [ #t/@
110+ q
111+ 3.548.750.706.400.251.607.252.023.288.575.526.190.856.734.474.077.821.289.791.377.301.707.878.697.553.411.219.689.905.949.957.893.633.811.025.757.107.990.477.902.858.170.125.439.223.250.551.937.540.468.638.902.955.378.837.954.792.031.592.462.617.422.136.386.332.469.076.584.061.249.923.938.374.214.925.312.954.606.277.212.923.859.309.330.556.730.410.200.952.056.760.727.611.447.500.996.168.035.027.753.417.869.213.425.113.257.514.474.700.810.203.348.784.547.006.707.150.406.298.809.062.567.217.447.347.357.039.994.339.342.906
112+ ]
113+ ]
114+ ]
115+ ]
116+]
117+```
118+
119+The `cage` in the `riot` of the `%writ` contains the file's data due to our use of an `%x` `care`. It needn't be `%x` though. If we change it to `%u`, for example, we'll get a `?` `cage` instead:
120+
121+```
122+> -send-task-take-gift [%warp our %home ~ %sing %x da+now /gen/hood/hi/hoon]
123+[ %writ
124+ p
125+ [ ~
126+ [ p=[p=%u q=[%da p=~2021.5.20..23.42.21..bb33] r=%home]
127+ q=/gen/hood/hi/hoon
128+ r=[p=%flag q=[#t/?(%.y %.n) q=0]]
129+ ]
130+ ]
131+]
132+```
133+
134+Here's a breakdown of the `task` we sent:
135+
136+![%sing diagram](https://pub.m.tinnus-napbus.xyz/sing.png "%sing diagram")
137+
138+## %next
139+
140+Here we'll look at subscribing to the next version of a file by passing Clay a `%warp` `task` with a `%next` `rave` and receiving a `%writ` `gift` when the file changes.
141+
142+Using the `send-task-take-gift.hoon` thread, let's subscribe to the next version of `foo.txt`:
143+
144+```
145+> -send-task-take-gift [%warp our %home ~ %next %x da+now /foo/txt]
146+```
147+
148+Now, in unix, create a file called `foo.txt` in the root of the `home` directory of your ship. In the dojo, hit backspace to disconnect the thread from the dojo prompt and run `|commit %home`. You should see something like:
149+
150+```
151+> |commit %home
152+>=
153+[%writ p=[~ [p=[p=%x q=[%ud p=3] r=%home] q=/foo/txt r=[p=%txt q=[#t/*'' q=0]]]]]
154++ /~zod/home/3/foo/txt
155+```
156+
157+As you can see, the `riot` in the `%writ` includes a `cage` with the data of `/foo/txt` due to our use of an `%x` `care`.
158+
159+Now run the thread again, and this time delete the file in unix and again `|commit %home` in the dojo. You should see:
160+
161+```
162+> |commit %home
163+>=
164+[%writ p=~]
165+- /~zod/home/4/foo/txt
166+```
167+
168+You can see the `riot` is just `~` due to the file being deleted.
169+
170+Here's a breakdown of the task we sent:
171+
172+![%next diagram](https://pub.m.tinnus-napbus.xyz/next.png "%next diagram")
173+
174+## %mult
175+
176+Here we'll look at subscribing to the next version of multiple files by passing Clay a `%warp` `task` with a `%mult` `rave` and receiving a `%wris` `gift` when any of the files change.
177+
178+This thread will subscribe to `/foo/txt` with an `%x` `care` and `/bar/txt` with a `%u` `care`. It will print out the `%wris` it gets back from Clay.
179+
180+`sub-mult.hoon`
181+
182+```hoon
183+/- spider
184+/+ strandio
185+=, strand=strand:spider
186+^- thread:spider
187+|= arg=vase
188+=/ m (strand ,vase)
189+^- form:m
190+=/ files=(set (pair care:clay path))
191+ %- sy :~
192+ [%x /foo/txt]
193+ [%u /bar/txt]
194+ ==
195+;< =bowl:strand bind:m get-bowl:strandio
196+=/ =task:clay [%warp our.bowl %home ~ %mult da+now.bowl files]
197+=/ =card:agent:gall [%pass /mult %arvo %c task]
198+;< ~ bind:m (send-raw-card:strandio card)
199+;< response=(pair wire sign-arvo) bind:m take-sign-arvo:strandio
200+~& +.q.response
201+(pure:m !>(~))
202+```
203+
204+Save the above to `ted/sub-mult.hoon`, `|commit %home` and run with `-sub-mult`. Now, create `foo.txt` and `bar.txt` in your home directory, hit backspace in the dojo to disconnect the thread and run `|commit %home`. You should see something like:
205+
206+```hoon
207+> |commit %home
208+>=
209+[%wris p=[%da p=~2021.4.27..06.07.08..5ec4] q={[p=%u q=/bar/txt] [p=%x q=/foo/txt]}]
210++ /~zod/home/151/foo/txt
211++ /~zod/home/151/bar/txt
212+```
213+
214+You'll notice that, unlike a `%writ`, the `%wris` doesn't give you the data. It merely tells you the `care`s and `path`s of the files that changed. If you need to actually get the data, you can just scry or send a request for the files in question.
215+
216+Now, run the thread again, open `bar.txt` in an editor, modify its contents, save it and `|commit %home`. You'll notice you didn't receive a `%wris`. This is because we subscribed to `/bar/txt` with `%u` care and its existence didn't change.
217+
218+Lastly, delete `foo.txt` and `|commit %home`. You should see something like:
219+
220+```hoon
221+> |commit %home
222+>=
223+[%wris p=[%da p=~2021.4.27..06.15.03..0da4] q={[p=%x q=/foo/txt]}]
224+- /~zod/home/153/foo/txt
225+```
226+
227+As you can see, a relevant change to any of the subscribed files will trigger a response, not just when all of them change.
228+
229+Here's a breakdown of the `task` we sent:
230+
231+![subscribe mult diagram](https://pub.m.tinnus-napbus.xyz/sub-mult.png "subscribe mult diagram")
232+
233+## %many
234+
235+Here we'll look at subscribing to a range of changes to a `desk` by passing Clay a `%warp` `task` with a `%many` `rave` and receiving `%writ` `gift`s when changes occur.
236+
237+This thread will subscribe to changes to your `%home` `desk` for the next three minutes. The `track` is `%.y` so it will only inform you of changes, not send the full `nako`. It will only get updates if the specified file exists. It contains a `main-loop` that will take an arbitrary number of `sign`s and print them out in the dojo. Since it never ends, you'll need to stop it with the `:spider|kill` command in the dojo.
238+
239+`sub-many.hoon`
240+
241+```hoon
242+/- spider
243+/+ strandio
244+=, strand=strand:spider
245+|%
246+++ take-sign-loop
247+ =/ m (strand ,~)
248+ ^- form:m
249+ %- (main-loop:strandio ,~)
250+ :~ |= ~
251+ ^- form:m
252+ ;< res=(pair wire sign-arvo)
253+ bind:m
254+ ((handle:strandio ,(pair wire sign-arvo)) take-sign-arvo:strandio)
255+ ~& res
256+ (pure:m ~)
257+ ==
258+--
259+^- thread:spider
260+|= arg=vase
261+=/ m (strand ,vase)
262+^- form:m
263+=/ uarg !< (unit path) arg
264+?~ uarg
265+ (strand-fail:strand %no-arg ~)
266+=/ =path u.uarg
267+;< =bowl:strand bind:m get-bowl:strandio
268+=/ =task:clay [%warp our.bowl %home ~ %many %.y da+now.bowl da+(add ~m3 now.bowl) path]
269+=/ =card:agent:gall [%pass /many %arvo %c task]
270+;< ~ bind:m (send-raw-card:strandio card)
271+;< ~ bind:m take-sign-loop
272+(pure:m !>(~))
273+```
274+
275+Make sure `foo.txt` doesn't exist in the root of your `%home` `desk`. Save this to `ted/sub-many.hoon`, `|commit %home`, run it like `-sub-many /foo/txt`, and hit backspace in the dojo to free up the dojo prompt. Now, add a file called `bar.txt` to your `desk` and `|commit %home`. You should see something like:
276+
277+```hoon
278+> |commit %home
279+>=
280++ /~zod/home/260/bar/txt
281+```
282+
283+Notice you've received no `%writ` from Clay. This is because `/foo/txt` doesn't exist. Now, create `foo.txt` and `|commit %home` again. You should see:
284+
285+```hoon
286+> |commit %home
287+>=
288+[ p=/many
289+ q=[%clay [%writ p=[~ [p=[p=%w q=[%ud p=261] r=%home] q=/ r=[p=%null q=[#t/@n q=0]]]]]]
290+]
291++ /~zod/home/261/foo/txt
292+```
293+
294+Now that `/foo/txt` exists it will inform you of updates. Note that if you delete `/foo/txt` again it will again stop sending updates.
295+
296+Now try adding `baz.txt`:
297+
298+```hoon
299+> |commit %home
300+>=
301+[ p=/many
302+ q=[%clay [%writ p=[~ [p=[p=%w q=[%ud p=262] r=%home] q=/ r=[p=%null q=[#t/@n q=0]]]]]]
303+]
304++ /~zod/home/262/baz/txt
305+```
306+
307+Now wait until the three minutes is up and try making a change, for example deleting `baz.txt`:
308+
309+```hoon
310+> |commit %home
311+>=
312+[ p=/many
313+ q=[%clay [%writ p=[~ [p=[p=%w q=[%ud p=264] r=%home] q=/ r=[p=%null q=[#t/@n q=0]]]]]]
314+]
315+[p=/many q=[%clay [%writ p=~]]]
316+- /~zod/home/263/baz/txt
317+```
318+
319+You can see that along with the normal `%writ` it's also sent a second `%writ` with a null `riot` to indicate the subscription has ended. This is because it has now passed the end of the range of `case`s to which you subscribed.
320+
321+Run `:spider|kill` to stop the thread.
322+
323+Here's a breakdown of the `task` we sent:
324+
325+![subscribe many diagram](https://pub.m.tinnus-napbus.xyz/sub-many.png "subscribe many diagram")
326+
327+## Cancel Subscription
328+
329+Here we'll look at cancelling a subscription by sending Clay a `%warp` `task` with a null `(unit rave)` in the `riff`.
330+
331+This thread will subscribe to the `%next` version of `/foo/txt`, then immediately cancel the subscription and wait for a response to print (which it will never receive).
332+
333+`stop-sub.hoon`
334+
335+```hoon
336+/- spider
337+/+ strandio
338+=, strand=strand:spider
339+^- thread:spider
340+|= arg=vase
341+=/ m (strand ,vase)
342+^- form:m
343+;< =bowl:strand bind:m get-bowl:strandio
344+=/ =task:clay [%warp our.bowl %home ~ %next %x da+now.bowl /foo/txt]
345+=/ =card:agent:gall [%pass /next %arvo %c task]
346+;< ~ bind:m (send-raw-card:strandio card)
347+=. task [%warp our.bowl %home ~]
348+=. card [%pass /next %arvo %c task]
349+;< ~ bind:m (send-raw-card:strandio card)
350+;< =riot:clay bind:m (take-writ:strandio /next)
351+~& riot
352+(pure:m !>(~))
353+```
354+
355+Save the above to `ted/stop-sub.hoon`, `|commit %home`, run it with `-stop-sub` and hit backspace to detach it from the dojo prompt. Now, add `foo.txt` to the root of your `%home` `desk` and `|commit %home`. You should see:
356+
357+```
358+> |commit %home
359+>=
360++ /~zod/home/266/foo/txt
361+```
362+
363+As you can see we've received no `%writ`. We can thus conclude the subscription has successfully been cancelled.
364+
365+Run `:spider|kill` to stop the thread.
366+
367+Here's a breakdown of the `task` we sent:
368+
369+![cancel subscription diagram](https://pub.m.tinnus-napbus.xyz/stop-sub.png "cancel subscription diagram")
370+
371+# Write and Modify
372+
373+See the [Write and Modify](@/docs/arvo/clay/tasks.md#write-and-modify) section of the [API Reference](@/docs/arvo/clay/tasks.md) document for general details.
374+
375+## %ins
376+
377+Here we'll look at adding a file by sending Clay a `%info` `task` containing a `%ins` `miso`.
378+
379+Using the `send-task.hoon` thread, let's try adding a `foo.txt` file with 'foo' as its contents:
380+
381+```
382+> -send-task [%info %home %& [/foo/txt %ins %txt !>(~['foo'])]~]
383++ /~zod/home/5/foo/txt
384+```
385+
386+If you have a look in the home of your pier you'll see there's now a file called `foo.txt` with the text `foo` in it.
387+
388+We've created the `cage` of the content like `[%txt !>(~['foo'])]`, if you want to write something besides a text file you'd just give it the appropriate `mark` and `vase`.
389+
390+Here's a breakdown of the `task` we sent:
391+
392+![%ins diagram](https://pub.m.tinnus-napbus.xyz/ins.png)
393+
394+## %del
395+
396+Here we'll look at deleting a file by sending Clay a `%info` `task` containing a `%del` `miso`.
397+
398+Using the `send-task.hoon` thread, let's try deleting the `foo.txt` file created in the [previous example](#ins):
399+
400+```
401+> -send-task [%info %home %& [/foo/txt %del ~]~]
402+- /~zod/home/6/foo/txt
403+```
404+
405+If you have a look in the home of your pier you'll see the `foo.txt` file is now gone.
406+
407+Here's a breakdown of the `task` we sent:
408+
409+![%del diagram](https://pub.m.tinnus-napbus.xyz/del.png)
410+
411+## %mut
412+
413+Identical to the [%ins](#ins) example, just replace `%ins` with `%mut`.
414+
415+## Multiple Changes
416+
417+Here we'll look at changing multiple files in one request by sending Clay a `%info` `task` containing multiple `miso` in the `soba`.
418+
419+Since `soba` is just a `list` of `miso`, you can add a bunch of `miso` and they'll all be applied. This thread adds three files and then deletes them. Here there's only one type of `miso` in each request but you could mix different types together too.
420+
421+`multi-change.hoon`
422+
423+```hoon
424+/- spider
425+/+ strandio
426+=, strand=strand:spider
427+^- thread:spider
428+|= arg=vase
429+=/ m (strand ,vase)
430+^- form:m
431+=/ soba-a :~ [/foo/txt %ins %txt !>(['foo' ~])]
432+ [/bar/txt %ins %txt !>(['bar' ~])]
433+ [/baz/txt %ins %txt !>(['baz' ~])]
434+ ==
435+=/ soba-b :~ [/foo/txt %del ~]
436+ [/bar/txt %del ~]
437+ [/baz/txt %del ~]
438+ ==
439+;< ~ bind:m (send-raw-card:strandio [%pass /info %arvo %c %info %home %& soba-a])
440+;< ~ bind:m (send-raw-card:strandio [%pass /info %arvo %c %info %home %& soba-b])
441+(pure:m !>(~))
442+```
443+
444+Save to `ted/multi-change.hoon`, `|commit %home`, and run:
445+
446+```hoon
447+> -multi-change
448++ /~zod/home/37/foo/txt
449++ /~zod/home/37/bar/txt
450++ /~zod/home/37/baz/txt
451+- /~zod/home/38/foo/txt
452+- /~zod/home/38/bar/txt
453+- /~zod/home/38/baz/txt
454+```
455+
456+# Manage Mounts
457+
458+See the [Manage Mounts](@/docs/arvo/clay/tasks.md#manage-mounts) section of the [API Reference](@/docs/arvo/clay/tasks.md) document for general details.
459+
460+## %boat
461+
462+Here we'll look at requesting the list of existing mount points on a ship by sending Clay a `%boat` `task` and receiving a `%hill` `gift`.
463+
464+Using the `send-task-take-gift.hoon` thread, let's make such a request:
465+
466+```
467+> -send-task-take-gift [%boat ~]
468+[%hill p=~[%home]]
469+```
470+
471+## %mont
472+
473+Here we'll look at mounting `desk`s, directories and files to unix by sending Clay a `%mont` `task`.
474+
475+Using the `send-task.hoon` thread, let's first try mounting our `%kids` desk:
476+
477+```
478+> -send-task [%mont %kids [our %kids da+now] /]
479+```
480+
481+If you look in your pier, you should now see a `kids` folder which contains the contents of that `desk`.
482+
483+If we make a `%boat` request as detailed in the [%boat](#boat) section, we'll now see the mount point listed:
484+
485+```
486+> -send-task-take-gift [%boat ~]
487+[%hill p=~[%kids %home]]cruz gift. It looks like:
488+
489+[%cruz cez=(map @ta crew)] :: permission groups
490+The cez is just a map from group name to crew
491+```
492+
493+Note the mount point doesn't need to match a `desk`, file or directory. We can also do:
494+
495+```
496+> -send-task [%mont %wibbly-wobbly [our %home da+now] /]
497+```
498+
499+And you'll now see that there's a `wibbly-wobbly` folder with the contents of the `%home` `desk`. You'll also notice we can mount the same file or directory more than once. There's no problem having `%home` mounted to both `home` and `wibbly-wobbly`. The only requirement is that their mount points be unique.
500+
501+Let's try mounting a subdirectory and a single folder:
502+
503+```
504+> -send-task [%mont %gen [our %home da+now] /gen]
505+> -send-task [%mont %hi [our %home da+now] /gen/hood/hi]
506+```
507+
508+If you look in your pier you'll now see a `gen` folder with the contents of `/gen` and a `hi.hoon` file by itself. Notice how the file extension has been automatically added.
509+
510+## %ogre
511+
512+Here we'll look at unmounting `desk`s, directories and files by sending Clay a `%ogre` `task`.
513+
514+Using the `send-task.hoon` thread, let's unmount what we mounted in the [%mont](#mont) section. First we'll unmount the `%kids` desk:
515+
516+```
517+-send-task [%ogre %kids]
518+```
519+
520+Our custom mount point `%wibbly-wobbly`:
521+
522+```
523+-send-task [%ogre %wibbly-wobbly]
524+```
525+
526+And the single `hi.hoon` we previously mounted by specifying its mount point `%hi`:
527+
528+```
529+-send-task [%ogre %hi]
530+```
531+
532+If we specify a non-existent mount point it will fail with an error printed to the dojo like:
533+
534+```
535+> -send-task [%ogre %kids]
536+[%not-mounted %kids]
537+```
538+
539+If we give it an unmounted `beam` it will not print an error but still won't work.
540+
541+## %dirk
542+
543+Here we'll look at committing changed files by sending Clay a `%dirk` `task`.
544+
545+With your `%home` `desk` mounted, try adding a file and, using the `send-task.hoon` thread, send a `%dirk` to commit the change:
546+
547+```hoon
548+> -send-task [%dirk %home]
549++ /~zod/home/12/foo/txt
550+```
551+
552+Clay will print the changed files to the dojo with a leading `+`, `-` or `:` to indicate a new file, deleted file and changed file respectively.
553+
554+If you have the same `desk` mounted to multiple points, a committed change in one mount will also update the others.
555+
556+# Merge Desks
557+
558+See the [Merge Desks](@/docs/arvo/clay/tasks.md#merge-desks) section of the [API Reference](@/docs/arvo/clay/tasks.md) document for general details.
559+
560+## %merg
561+
562+Here we'll look at merging `desk`s by sending Clay a `%merg` `task` and receiving a `%mere` `gift` in response.
563+
564+First, using the `send-task-take-gift.hoon` thread, let's try creating a new `desk`:
565+
566+```
567+> -send-task-take-gift [%merg %foo our %home da+now %init]
568+[%mere p=[%.y p={}]]
569+```
570+
571+Now if we scry for our `desk`s we'll see `%foo` is there:
572+
573+```
574+> .^((set desk) %cd /===)
575+{%home %foo %kids}
576+```
577+
578+Next, we'll create a merge conflict and try a couple of things. Mount `%foo` with `|mount /=foo=`, then add a `foo.txt` to both `desk`s but with different text in each and `|commit` them.
579+
580+Now we'll try merging `%home` into `%foo` with a `%mate` strategy:
581+
582+```
583+> -send-task-take-gift [%merg %foo our %home da+now %mate]
584+[ /foo
585+ [ %clay
586+ [ %mere
587+ p
588+ [ %.n
589+ p
590+ [ p=%mate-conflict
591+ q=~[[%rose p=[p="/" q="/" r=""] q=[i=[%leaf p="foo"] t=[i=[%leaf p="txt"] t=~]]]]
592+ ]
593+ ]
594+ ]
595+ ]
596+]
597+```
598+
599+As you can see, the merge has failed. Let's try again with a `%meld` strategy:
600+
601+```
602+> -send-task-take-gift [%merg %foo our %home da+now %meld]
603+[/foo [%clay [%mere p=[%.y p={/foo/txt}]]]]
604+```
605+
606+Now the merge has succeeded and the `%mere` notes the file with a merge conflict. If we try with a `%only-that` strategy:
607+
608+```
609+> -send-task-take-gift [%merg %foo our %home da+now %only-that]
610+[/foo [%clay [%mere p=[%.y p={}]]]]
611+: /~zod/foo/6/foo/txt
612+```
613+
614+...you can see it's overwritten the `foo/txt` in the `%foo` `desk` and the `%mere` now has an empty `set`, indicating no merge conflicts.
615+
616+Next, let's look at subscribing for future changes. Since the `case` is specified explicitly in the `%merge` `task`, we can set it in the future:
617+
618+```
619+> -send-task-take-gift [%merg %foo our %home da+(add ~m2 now) %only-that]
620+```
621+
622+Now change the text in the `foo.txt` in the `%home` `desk`, hit backspace to detach the thread and `|commit %home`. After the two minutes pass you should see:
623+
624+```
625+[/foo [%clay [%mere p=[%.y p={}]]]]
626+: /~zod/foo/7/foo/txt
627+```
628+
629+You can also specify it by revision number or label.
630+
631+# Permissions
632+
633+See the [Permissions](@/docs/arvo/clay/tasks.md#permissions) section of the [API Reference](@/docs/arvo/clay/tasks.md) document for general details.
634+
635+## %perm
636+
637+Here we'll look at setting permissions by sending Clay a `%perm` `task`.
638+
639+First, using the `send-task.hoon` thread, let's try allow `~nes` to read `/gen/hood/hi/hoon`:
640+
641+```
642+> -send-task [%perm %home /gen/hood/hi/hoon %r ~ %white (sy [%.y ~nes]~)]
643+```
644+
645+...and we'll do a `%p` scry to see that the permission was set:
646+
647+```
648+> .^([r=dict:clay w=dict:clay] %cp /===/gen/hood/hi/hoon)
649+[r=[src=/gen/hood/hi/hoon rul=[mod=%white who=[p={~nes} q={}]]] w=[src=/ rul=[mod=%white who=[p={} q={}]]]]
650+```
651+
652+You can see that `~nes` is now in the read whitelist. Next, let's try a write permission:
653+
654+```
655+> -send-task [%perm %home /ted %w ~ %white (sy [%.y ~nes]~)]
656+```
657+
658+You can see `~nes` can now write to `/ted`:
659+
660+```
661+> .^([r=dict:clay w=dict:clay] %cp /===/ted)
662+[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/ted rul=[mod=%white who=[p={~nes} q={}]]]]
663+```
664+
665+Since we've set it for the whole `/ted` directory, if we check a file inside it we'll see it also has this permission:
666+
667+```
668+> .^([r=dict:clay w=dict:clay] %cp /===/ted/aqua/ames/hoon)
669+[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/ted rul=[mod=%white who=[p={~nes} q={}]]]]
670+```
671+
672+...and you'll notice that `src` tells us it's inherited the rule from `/ted`.
673+
674+Now let's try setting both read and write permissions:
675+
676+```
677+> -send-task [%perm %home /gen/help/hoon %rw `[%black (sy [%.y ~nes]~)] `[%white (sy [%.y ~nes]~)]]
678+```
679+
680+```
681+ .^([r=dict:clay w=dict:clay] %cp /===/gen/help/hoon)
682+[r=[src=/gen/help/hoon rul=[mod=%black who=[p={~nes} q={}]]] w=[src=/gen/help/hoon rul=[mod=%white who=[p={~nes} q={}]]]]
683+```
684+
685+Lastly, let's look at deleting a permission rule we've previously set. To do that, we just send a null `(unit rule)` in the `rite`.
686+
687+For example, to remove a read permission (or write if you specify `%w`):
688+
689+```
690+> -send-task [%perm %home /gen/help/hoon %r ~]
691+```
692+
693+```
694+> .^([r=dict:clay w=dict:clay] %cp /===/gen/help/hoon)
695+[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/gen/help/hoon rul=[mod=%white who=[p={~nes} q={}]]]]
696+```
697+
698+...and to remove both read and write at the same time:
699+
700+```
701+> -send-task [%perm %home /gen/help/hoon %rw ~ ~]
702+```
703+
704+```
705+> .^([r=dict:clay w=dict:clay] %cp /===/gen/help/hoon)
706+[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/ rul=[mod=%white who=[p={} q={}]]]]
707+```
708+
709+As you can see it's back to the default inherited from `/`.
710+
711+Here's a breakdown of a `%perm` task:
712+
713+![perm diagram](https://pub.m.tinnus-napbus.xyz/perm-diagram.png)
714+
715+## %cred
716+
717+Here we'll look at creating a permission group by sending Clay a `%cred` `task`.
718+
719+Using the `send-task.hoon` thread, try:
720+
721+```
722+-send-task [%crew 'foo' (sy ~[~zod ~nec ~bud ~wes ~sev])]
723+```
724+
725+We'll check it with the next kind of `task`: [%crew](#crew).
726+
727+## %crew
728+
729+Here we'll look at retrieving permission groups by sending Clay a `%crew` `task` and receiving a `%cruz` `gift` in response.
730+
731+Let's check, using the `send-task-take-gift.hoon` thread, for the permission group created in the [%cred](#cred) example:
732+
733+```
734+> -send-task-take-gift [%crew ~]
735+[%cruz cez={[p=~.foo q={~nec ~bud ~wes ~zod ~sev}]}]
736+```
737+
738+## %crow
739+
740+Here we'll look at retrieving a list of all files and directories in all `desk`s which have permissions set for a group by sending Clay a `%crow` `task` and receiving a `%croz` `gift` in response.
741+
742+First we'll set a couple of permissions for the `foo` group we created in the [%cred](#cred) section using the `send-task.hoon` thread:
743+
744+```
745+> -send-task [%perm %home /gen/hood/hi/hoon %w ~ %white (sy [%.n 'foo']~)]
746+> -send-task [%perm %home /ted %w ~ %white (sy [%.n 'foo']~)]
747+```
748+
749+Notice we use a `%.n` in the `whom` to indicate a group rather than the `%.y` of a ship.
750+
751+Now we'll use the `send-task-take-gift.hoon` thread to try `%crow`:
752+
753+```
754+> -send-task-take-gift [%crow 'foo']
755+[ %croz
756+ rus
757+ { [ p=%home
758+ q
759+ [ r={}
760+ w
761+ { [p=/gen/hood/hi/hoon q=[mod=%white who={[%.n p=~.foo]}]]
762+ [p=/ted q=[mod=%white who={[%.n p=~.foo]}]]
763+ }
764+ ]
765+ ]
766+ }
767+]
768+```
769+
770+# Foreign Ships
771+
772+See the [Foreign Ships](@/docs/arvo/clay/tasks.md#foreign-ships) section of the [API Reference](@/docs/arvo/clay/tasks.md) document for general details.
773+
774+## %warp
775+
776+Here we'll look at reading files on a foreign ship by sending Clay a `%warp` `task` with a foreign ship in the `wer` field and receiving a `%writ` `gift` in response.
777+
778+We'll use a fake ~nes as the the foreign ship and a fake ~zod as the local ship.
779+
780+First we'll set permissions on the foreign ship. Create a file called `foo.txt` in the `%home` of ~nes. Using the `send-task.hoon` thread, send a `%perm` request to allow ~zod to read and write the file:
781+
782+```
783+> -send-task [%perm %home /foo/txt %rw `[%white (sy [%.y ~zod]~)] `[%white (sy [%.y ~zod]~)]]
784+```
785+
786+If we scry the file for its permissions with a `%p` `care`, we'll see ~zod is now whitelisted:
787+
788+```
789+> .^([r=dict:clay w=dict:clay] %cp /===/foo/txt)
790+[r=[src=/foo/txt rul=[mod=%white who=[p={~zod} q={}]]] w=[src=/foo/txt rul=[mod=%white who=[p={~zod} q={}]]]]
791+```
792+
793+Back on ~zod: Using the `send-task-take-gift.hoon` thread, send a `%x` read request for `/foo/txt` on ~nes like:
794+
795+```
796+> -send-task-take-gift [%warp ~nes %home ~ %sing %x da+now /foo/txt]
797+[ %writ
798+ p
799+ [ ~
800+ [ p=[p=%x q=[%da p=~2021.5.3..08.24.22..9ce7] r=%home]
801+ q=/foo/txt
802+ r=[p=%txt q=[#t/txt=*'' q=[7.303.014 0]]]
803+ ]
804+ ]
805+]
806+```
807+
808+As you can see, we've received a `%writ` containing the requested data just as we would with a local request. Let's try a `%u`:
809+
810+```
811+> -send-task-take-gift [%warp ~nes %home ~ %sing %u da+now /foo/txt]
812+[ %writ
813+ p
814+ [ ~
815+ [ p=[p=%u q=[%da p=~2021.5.3..08.26.32..88cf] r=%home]
816+ q=/foo/txt
817+ r=[p=%flag q=[#t/?(%.y %.n) q=0]]
818+ ]
819+ ]
820+]
821+```
822+
823+If we send a `%d` request however, it will crash:
824+
825+```
826+> -send-receive-task [%warp ~nes %home ~ %sing %d da+now /foo/txt]
827+call: failed
828+/sys/vane/clay/hoon:<[4.085 3].[4.314 5]>
829+...
830+/sys/vane/clay/hoon:<[1.365 7].[1.365 51]>
831+[ %clay-bad-foreign-request-care
832+ [%sing mood=[care=%d case=[%da p=~2021.5.3..20.04.57..1092] path=/foo/txt]]
833+]
834+/sys/vane/clay/hoon:<[1.365 48].[1.365 50]>
835+```
836+
837+## %merg
838+
839+To merge a foreign `desk` into a local one, you just send Clay a `%merg` `task` (as you would for a local merge) and specify the foreign ship in the `her` field. For an example, see the [%merg](#merg) section.
840+
841+The foreign ship will respond only if correct permissions have been set. See the [%perm](#perm) section for an example.
arvo/clay/foreign-requests.mddeleted−146
@@ -1,146 +0,0 @@
1−+++
2−title = "Foreign Ships"
3−weight = 11
4−template = "doc.html"
5−+++
6−
7−Here we'll looking at making Clay requests to a foreign ship.
8−
9−As it currently stands, it's not possible to write to a foreign `desk`. Additionally, remote scries are not implemented. That leaves requests to read files (`%warp`) and merge desks (`%merg`).
10−
11−## Contents
12−
13−- [%warp](#warp) - Read files and directories.
14−- [%merg](#merg) - Merge a foreign desk into a local one.
15−
16−## %warp
17−
18−To read files on a foreign `desk`, you just send Clay a `%warp` `task` (as you would for a local read) and specify the target ship in the `wer` field. For details on making such requests, see the [Read and Subscribe](@/docs/arvo/clay/read.md) document.
19−
20−Clay only allows a subset of `care`s to be used remotely. They are:
21−
22−- `%u` - Check for existence of file.
23−- `%v` - Get entire `dome:clay` state of a desk.
24−- `%w` - Get revision number.
25−- `%x` - Get data of file.
26−- `%y` - Get `arch` of file or directory.
27−- `%z` - Get content hash of file or directory.
28−
29−Any other `care` will crash with a `%clay-bad-foreign-request-care` error.
30−
31−The foreign ship will respond only if correct permissions have been set. See the [Permissions](@/docs/arvo/clay/permissions.md) document for details.
32−
33−Note that if you're reading a whole `desk` or directory, all subfolders and files must also permit reading. If even a single file does not permit you reading it, the foreign ship will not respond to the request.
34−
35−Example:
36−
37−We'll use a fake ~nes as the the foreign ship and a fake ~zod as the local ship.
38−
39−First we'll set permissions on the foreign ship. Here's a simple thread that just sends a `task` to Clay:
40−
41−`send-clay-task.hoon`
42−
43−```hoon
44−/- spider
45−/+ strandio
46−=, strand=strand:spider
47−^- thread:spider
48−|= arg=vase
49−=/ m (strand ,vase)
50−^- form:m
51−=/ uarg !< (unit task:clay) arg
52−?~ uarg
53− (strand-fail:strand %no-arg ~)
54−=/ =task:clay u.uarg
55−=/ =card:agent:gall [%pass /foo %arvo %c task]
56−;< ~ bind:m (send-raw-card:strandio card)
57−(pure:m !>(~))
58−```
59−
60−Create a file called `foo.txt` in the `%home` of ~nes. Save the above thread to `ted/send-clay/task.hoon`, `|commit %home`, and then send a `%perm` request to allow ~zod to read and write the file:
61−
62−```hoon
63−> -send-clay-task [%perm %home /foo/txt %rw `[%white (sy [%.y ~zod]~)] `[%white (sy [%.y ~zod]~)]]
64−```
65−
66−If we scry the file for its permissions with a `%p` `care`, we'll see ~zod is now whitelisted:
67−
68−```hoon
69−> .^([r=dict:clay w=dict:clay] %cp /===/foo/txt)
70−[r=[src=/foo/txt rul=[mod=%white who=[p={~zod} q={}]]] w=[src=/foo/txt rul=[mod=%white who=[p={~zod} q={}]]]]
71−```
72−
73−Next, save the following thread to `ted/send-task-take-gift.hoon` on ~zod:
74−
75−`send-task-take-gift.hoon`
76−
77−```hoon
78−/- spider
79−/+ strandio
80−=, strand=strand:spider
81−^- thread:spider
82−|= arg=vase
83−=/ m (strand ,vase)
84−^- form:m
85−=/ uarg !< (unit task:clay) arg
86−?~ uarg
87− (strand-fail:strand %no-arg ~)
88−=/ =task:clay u.uarg
89−=/ =card:agent:gall [%pass /foo %arvo %c task]
90−;< ~ bind:m (send-raw-card:strandio card)
91−;< res=[wire sign-arvo] bind:m take-sign-arvo:strandio
92−~& +>:res
93−(pure:m !>(~))
94−```
95−
96−`|commit %home`, and send a `%x` read request for `/foo/txt` on ~nes like:
97−
98−```hoon
99−> -send-task-take-gift [%warp ~nes %home ~ %sing %x da+now /foo/txt]
100−[ %writ
101− p
102− [ ~
103− [ p=[p=%x q=[%da p=~2021.5.3..08.24.22..9ce7] r=%home]
104− q=/foo/txt
105− r=[p=%txt q=[#t/txt=*'' q=[7.303.014 0]]]
106− ]
107− ]
108−]
109−```
110−
111−As you can see, we've received a `%writ` containing the requested data just as we would with a local request. Let's try a `%u`:
112−
113−```hoon
114−> -send-task-take-gift [%warp ~nes %home ~ %sing %u da+now /foo/txt]
115−[ %writ
116− p
117− [ ~
118− [ p=[p=%u q=[%da p=~2021.5.3..08.26.32..88cf] r=%home]
119− q=/foo/txt
120− r=[p=%flag q=[#t/?(%.y %.n) q=0]]
121− ]
122− ]
123−]
124−```
125−
126−If we send a `%d` request however, it will crash:
127−
128−```hoon
129−> -send-receive-task [%warp ~nes %home ~ %sing %d da+now /foo/txt]
130−call: failed
131−/sys/vane/clay/hoon:<[4.085 3].[4.314 5]>
132−...
133−/sys/vane/clay/hoon:<[1.365 7].[1.365 51]>
134−[ %clay-bad-foreign-request-care
135− [%sing mood=[care=%d case=[%da p=~2021.5.3..20.04.57..1092] path=/foo/txt]]
136−]
137−/sys/vane/clay/hoon:<[1.365 48].[1.365 50]>
138−```
139−
140−## %merg
141−
142−To merge a foreign `desk` into a local one, you just send Clay a `%merg` `task` (as you would for a local merge) and specify the foreign ship in the `her` field. For details on making such requests, see the [Merge Desks](@/docs/arvo/clay/merge.md) document.
143−
144−The foreign ship will respond only if correct permissions have been set. See the [Permissions](@/docs/arvo/clay/permissions.md) document for details. By default, a ship's `%kids` desk is set to be publicly readable, so unless permissions have been manually modified, you should be able to merge from any `%kids` `desk`.
145−
146−Note that all subfolders and individual files within the `desk` must permit your reading in order for the merge to succeed. If even one file does not permit you reading it, the remote ship will not respond to the request at all.
arvo/clay/merge.mddeleted−150
@@ -1,150 +0,0 @@
1−+++
2−title = "Merge Desks"
3−weight = 9
4−template = "doc.html"
5−+++
6−
7−Here we'll look at merging `desk`s programmatically.
8−
9−A `%merg` `task` will merge the specified source `desk` into the target local `desk`. It looks like:
10−
11−```hoon
12−$: %merg :: merge desks
13− des=desk :: target
14− her=@p dem=desk cas=case :: source
15− how=germ :: method
16−== ::
17−```
18−
19−The `germ` specifies the merge strategy and looks like:
20−
21−```hoon
22−+$ germ :: merge style
23− $? %init :: new desk
24− %fine :: fast forward
25− %meet :: orthogonal files
26− %mate :: orthogonal changes
27− %meld :: force merge
28− %only-this :: ours with parents
29− %only-that :: hers with parents
30− %take-this :: ours unless absent
31− %take-that :: hers unless absent
32− %meet-this :: ours if conflict
33− %meet-that :: hers if conflict
34− == ::
35−```
36−
37−You can refer to the [Strategies](@/docs/arvo/clay/using.md#strategies) section of the [Using Clay](@/docs/arvo/clay/using.md) document for details of each `germ`.
38−
39−If you're merging into a new `desk` you must use `%init`, all other strategies will fail. If the desk already exists, you cannot use `%init`. Otherwise, you're free to use whichever you'd like.
40−
41−Clay will respond to the request with a `%mere` `gift` which looks like:
42−
43−```hoon
44−[%mere p=(each (set path) (pair term tang))] :: merge result
45−```
46−
47−If the merge succeeded, `p` will look like `[%mere p=[%.y p={}]]` where `p.p` is the set of files which had a merge conflict. For example, `[%mere p=[%.y p={/foo/txt}]]` means there was a conflict with `/foo/txt`. An empty set means there were no conflicts.
48−
49−If the merge failed, `p` will have a head of `%.n` and then a `[term tang]` where the `term` is an error message and the `tang` contains additional details, for example:
50−
51−```hoon
52−[ %mere
53− p
54− [ %.n
55− p=[p=%mate-conflict q=~[[%rose p=[p="/" q="/" r=""] q=~[[%leaf p="foo"] [%leaf p="txt"]]]]]
56− ]
57−]
58−```
59−
60−Example:
61−
62−Here's a thread that sends the given `task` to Clay and prints the `gift` response:
63−
64−`send-task.hoon`
65−
66−```hoon
67−/- spider
68−/+ strandio
69−=, strand=strand:spider
70−^- thread:spider
71−|= arg=vase
72−=/ m (strand ,vase)
73−^- form:m
74−=/ uarg !< (unit task:clay) arg
75−?~ uarg
76− (strand-fail:strand %no-arg ~)
77−=/ =task:clay u.uarg
78−=/ =card:agent:gall [%pass /foo %arvo %c task]
79−;< ~ bind:m (send-raw-card:strandio card)
80−(pure:m !>(~))
81−```
82−
83−Save it to `ted/send-task.hoon` and `|commit %home`.
84−
85−First, let's try creating a new `desk`:
86−
87−```hoon
88−> -send-task-take-gift [%merg %foo our %home da+now %init]
89−[%mere p=[%.y p={}]]
90−```
91−
92−Now if we scry for our `desk`s we'll see `%foo` is there:
93−
94−```hoon
95−> .^((set desk) %cd /===)
96−{%home %foo %kids}
97−```
98−
99−Next, we'll create a merge conflict and try a couple of things. Mount `%foo` with `|mount /=foo=`, then add a `foo.txt` to both `desk`s but with different text in each and `|commit` them.
100−
101−Now we'll try merging `%home` into `%foo` with a `%mate` strategy:
102−
103−```hoon
104−> -send-task-take-gift [%merg %foo our %home da+now %mate]
105−[ /foo
106− [ %clay
107− [ %mere
108− p
109− [ %.n
110− p
111− [ p=%mate-conflict
112− q=~[[%rose p=[p="/" q="/" r=""] q=[i=[%leaf p="foo"] t=[i=[%leaf p="txt"] t=~]]]]
113− ]
114− ]
115− ]
116− ]
117−]
118−```
119−
120−As you can see, the merge has failed. Let's try again with a `%meld` strategy:
121−
122−```hoon
123−> -send-task-take-gift [%merg %foo our %home da+now %meld]
124−[/foo [%clay [%mere p=[%.y p={/foo/txt}]]]]
125−```
126−
127−Now the merge has succeeded and the `%mere` notes the file with a merge conflict. If we try with a `%only-that` strategy:
128−
129−```hoon
130−> -send-task-take-gift [%merg %foo our %home da+now %only-that]
131−[/foo [%clay [%mere p=[%.y p={}]]]]
132−: /~zod/foo/6/foo/txt
133−```
134−
135−...you can see it's overwritten the `foo/txt` in the `%foo` `desk` and the `%mere` now has an empty `set`, indicating no merge conflicts.
136−
137−Next, let's look at subscribing for future changes. Since the `case` is specified explicitly in the `%merge` `task`, we can set it in the future:
138−
139−```hoon
140−> -send-task-take-gift [%merg %foo our %home da+(add ~m2 now) %only-that]
141−```
142−
143−Now change the text in the `foo.txt` in the `%home` `desk`, hit backspace to detach the thread and `|commit %home`. After the two minutes pass you should see:
144−
145−```hoon
146−[/foo [%clay [%mere p=[%.y p={}]]]]
147−: /~zod/foo/7/foo/txt
148−```
149−
150−You can also specify it by revision number or label.
arvo/clay/mounts.mddeleted−195
@@ -1,195 +0,0 @@
1−+++
2−title = "Manage Mounts"
3−weight = 8
4−template = "doc.html"
5−+++
6−
7−Here we'll look at managing Clay unix mounts programmatically.
8−
9−## Contents
10−
11−There are four Clay `task`s relevant to mounts:
12−
13−- [%boat](#boat) - List mounts.
14−- [%mont](#mont) - Mount something.
15−- [%ogre](#ogre) - Unmount something.
16−- [%dirk](#dirk) - Commit changes.
17−
18−## %boat
19−
20−This type of `task` will request the list of existing mounts. It looks like:
21−
22−```hoon
23−[%boat ~]
24−```
25−
26−Pretty simple. The type it returns is a `%hill` `gift`, which looks like:
27−
28−```hoon
29−[%hill p=(list @tas)]
30−```
31−
32−...where the `@tas` is the name of the mount point.
33−
34−Example:
35−
36−Here's a thread that sends a `task` and takes a `gift` in response:
37−
38−`send-task-take-gift.hoon`
39−
40−```hoon
41−/- spider
42−/+ strandio
43−=, strand=strand:spider
44−^- thread:spider
45−|= arg=vase
46−=/ m (strand ,vase)
47−^- form:m
48−=/ uarg !< (unit task:clay) arg
49−?~ uarg
50− (strand-fail:strand %no-arg ~)
51−=/ =task:clay u.uarg
52−=/ =card:agent:gall [%pass /foo %arvo %c task]
53−;< ~ bind:m (send-raw-card:strandio card)
54−;< res=[wire sign-arvo] bind:m take-sign-arvo:strandio
55−~& +>:res
56−(pure:m !>(~))
57−```
58−
59−Save it to `ted/send-task-take-gift.hoon`, `|commit %home`, and run it like:
60−
61−```hoon
62−> -send-task-take-gift [%boat ~]
63−[%hill p=~[%home]]
64−```
65−
66−## %mont
67−
68−This type of `task` mounts the specified `beam:clay` to the specified `term` mount point. It looks like:
69−
70−```hoon
71−[%mont pot=term bem=beam]
72−```
73−
74−A `beam:clay` is the following structure:
75−
76−```hoon
77−+$ beam [[p=ship q=desk r=case] s=path] :: global name
78−```
79−
80−You can mount the whole desk with a `path` of `/`, and you can also mount subdirectories or even individual files. If you want to mount an individual file, you must exclude its `mark` from the path. For example, if you want to mount `/gen/hood/hi/hoon`, you'd specify `/gen/hood/hi`. It will automatically be given the correct file extension when mounted. If you include the `hoon` mark it will crash (and currently crash your ship).
81−
82−Example:
83−
84−Here's a thread which will send the given `task` to Clay.
85−
86−`send-task.hoon`
87−
88−```hoon
89−/- spider
90−/+ strandio
91−=, strand=strand:spider
92−^- thread:spider
93−|= arg=vase
94−=/ m (strand ,vase)
95−^- form:m
96−=/ uarg !< (unit task:clay) arg
97−?~ uarg
98− (strand-fail:strand %no-arg ~)
99−=/ =task:clay u.uarg
100−=/ =card:agent:gall [%pass /foo %arvo %c task]
101−;< ~ bind:m (send-raw-card:strandio card)
102−(pure:m !>(~))
103−```
104−
105−Save it to `ted/send-task.hoon`, `|commit %home` and run it like:
106−
107−```hoon
108−> -send-task [%mont %kids [our %kids da+now] /]
109−```
110−
111−If you look in your pier, you should now see a `kids` folder which contains the contents of that `desk`.
112−
113−If we make a `%boat` request as detailed in the [%boat](#boat) section, we'll now see the mount point listed:
114−
115−```hoon
116−> -send-task-take-gift [%boat ~]
117−[%hill p=~[%kids %home]]
118−```
119−
120−Note the mount point doesn't need to match a `desk`, file or directory. We can also do:
121−
122−```hoon
123−> -send-task [%mont %wibbly-wobbly [our %home da+now] /]
124−```
125−
126−And you'll now see that there's a `wibbly-wobbly` folder with the contents of the `%home` `desk`. You'll also notice we can mount the same file or directory more than once. There's no problem having `%home` mounted to both `home` and `wibbly-wobbly`. The only requirement is that their mount points be unique.
127−
128−Let's try mounting a subdirectory and a single folder:
129−
130−```hoon
131−> -send-task [%mont %gen [our %home da+now] /gen]
132−> -send-task [%mont %hi [our %home da+now] /gen/hood/hi]
133−```
134−
135−If you look in your pier you'll now see a `gen` folder with the contents of `/gen` and a `hi.hoon` file by itself. Notice how the file extension has been automatically added.
136−
137−## %ogre
138−
139−This type of `task` unmounts the specified mount. It's defined in `lull.hoon` as:
140−
141−```hoon
142−[%ogre pot=$@(desk beam)]
143−```
144−
145−But in fact it will only unmount the target when specified as a `term` mount name. Passing it a `desk` will incidentally work if the mount is named the same as the `desk` but otherwise it won't work. Passing it a `beam:clay` will simply not work.
146−
147−Using the thread from the [%mont](#mont) section, we can unmount `%kids` like:
148−
149−```hoon
150−-send-task [%ogre %kids]
151−```
152−
153−Our custom mount point `%wibbly-wobbly` like:
154−
155−```hoon
156−-send-task [%ogre %wibbly-wobbly]
157−```
158−
159−And the single `hi.hoon` we previously mounted by specifying its mount point `%hi`:
160−
161−```hoon
162−-send-task [%ogre %hi]
163−```
164−
165−If we specify a non-existent mount point it will fail with an error printed to the dojo like:
166−
167−```hoon
168−> -send-task [%ogre %kids]
169−[%not-mounted %kids]
170−```
171−
172−If we give it an unmounted `beam:clay` it will not print an error but still won't work.
173−
174−## %dirk
175−
176−This type of `task:clay` commits changes in the target mount. It's defined in `lull.hoon` as:
177−
178−```hoon
179−[%dirk des=desk]
180−```
181−
182−... but like [%ogre](#ogre), it actually takes the name of a mount point rather than a `desk` as is specified.
183−
184−Example:
185−
186−With your `%home` `desk` mounted, try adding a file and, using the thread from the [%mont](#mont) section, send a `%dirk` to commit the change:
187−
188−```hoon
189−> -send-task [%dirk %home]
190−+ /~zod/home/12/foo/txt
191−```
192−
193−Clay will print the changed files to the dojo with a leading `+`, `-` or `:` to indicate a new file, deleted file and changed file respectively.
194−
195−If you have the same `desk` mounted to multiple points, a committed change in one mount will also update the others.
arvo/clay/permissions.mddeleted−312
@@ -1,312 +0,0 @@
1−+++
2−title = "Permissions"
3−weight = 10
4−template = "doc.html"
5−+++
6−
7−Here we'll look at file permissions.
8−
9−## Contents
10−- [Introduction](#introduction)
11−- [%perm](#perm) - Set file permissions.
12−- [%cred](#cred) - Add permission group.
13−- [%crew](#crew) - Get permission groups.
14−- [%crow](#crow) - Get group usage.
15−
16−## Introduction
17−
18−For each file or directory, there is both a read permission and a write permission. Each may be set separately and is either a whitelist or a blacklist (but not both). The whitelist/blacklist contains a `set` of ships and/or groups which are allowed or banned respectively. If it's an empty whitelist it means all foreign ships are denied. If it's an empty blacklist it means all foreign ships are allowed.
19−
20−If permissions are not set for a particular file, they will be inherited from the directory in which it resides. If *that* directory has no permissions set, they will be inherited from another level up, and so on to the `desk`'s root directory. If the root directory has no permissions set, it will have the default permissions of an empty whitelist, meaning "deny all".
21−
22−A group is called a `crew` and is just a `set` of ships with a `@ta` name.
23−
24−The permissions for each file or directory are a pair of `dict:clay` where the head is read permissions and the tail is write permissions.
25−
26−A `dict:clay` is this structure:
27−
28−```hoon
29−+$ dict [src=path rul=real] :: effective permission
30−```
31−
32−The `src` path is where the permissions were inherited from and the `real` is this structure:
33−
34−```hoon
35− +$ real :: resolved permissions
36− $: mod=?(%black %white) ::
37− who=(pair (set ship) (map @ta crew)) ::
38− == ::
39−```
40−
41−So if we scry for permissions with a `%p` `care`, it'll look like:
42−
43−```hoon
44−> .^([r=dict:clay w=dict:clay] %cp /===/lib/strandio/hoon)
45−[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/ rul=[mod=%white who=[p={} q={}]]]]
46−```
47−
48−There are four permission-related `task`s which you can pass to Clay.
49−
50−A `%perm` `task` is for setting permissions, and the other three are for managing groups:
51−
52−- `%cred` - Add permission group.
53−- `%crew` - Get permission groups.
54−- `%crow` - Get group usage.
55−
56−We'll look at each of these in turn.
57−
58−## %perm
59−
60−This sets permissions for the target file or directory.
61−
62−Note this will replace existing permissions rather than add to them, so if you want to add a ship to an existing whitelist or whatever you'll have to first read the existing permissions, add the ship, then send the whole lot back.
63−
64−A `%perm` `task` looks like:
65−
66−```hoon
67−[%perm des=desk pax=path rit=rite] :: change permissions
68−```
69−
70−The `pax` path is the file or directory whose permissions you want to change, and the `rite` is this structure:
71−
72−```hoon
73−+$ rite :: new permissions
74− $% [%r red=(unit rule)] :: for read
75− [%w wit=(unit rule)] :: for write
76− [%rw red=(unit rule) wit=(unit rule)] :: for read and write
77−```
78−
79−Where a `rule` is this structure:
80−
81−```hoon
82−+$ rule [mod=?(%black %white) who=(set whom)] :: node permission
83−```
84−
85−...and finally `whom` is this:
86−
87−```hoon
88−+$ whom (each ship @ta) :: ship or named crew
89−```
90−
91−As the comment suggests, the `@ta` is the name of a `crew` (group).
92−
93−Example:
94−
95−Here's a generic thread that just sends the given `task` to Clay so we can try a few different things:
96−
97−`send-clay-task.hoon`
98−
99−```hoon
100−/- spider
101−/+ strandio
102−=, strand=strand:spider
103−^- thread:spider
104−|= arg=vase
105−=/ m (strand ,vase)
106−^- form:m
107−=/ uarg !< (unit task:clay) arg
108−?~ uarg
109− (strand-fail:strand %no-arg ~)
110−=/ =task:clay u.uarg
111−=/ =card:agent:gall [%pass /foo %arvo %c task]
112−;< ~ bind:m (send-raw-card:strandio card)
113−(pure:m !>(~))
114−```
115−
116−Save it to `ted/send-clay-task.hoon` and `|commit %home`. Now, let's allow `~nes` to read `/gen/hood/hi/hoon`:
117−
118−```hoon
119−> -send-clay-task [%perm %home /gen/hood/hi/hoon %r ~ %white (sy [%.y ~nes]~)]
120−```
121−
122−...and we'll do a `%p` scry to see that the permission was set:
123−
124−```hoon
125−> .^([r=dict:clay w=dict:clay] %cp /===/gen/hood/hi/hoon)
126−[r=[src=/gen/hood/hi/hoon rul=[mod=%white who=[p={~nes} q={}]]] w=[src=/ rul=[mod=%white who=[p={} q={}]]]]
127−```
128−
129−You can see that `~nes` is now in the read whitelist. Next, let's try a write permission:
130−
131−```hoon
132−> -send-clay-task [%perm %home /ted %w ~ %white (sy [%.y ~nes]~)]
133−```
134−
135−You can see `~nes` can now write to `/ted`:
136−
137−```hoon
138−> .^([r=dict:clay w=dict:clay] %cp /===/ted)
139−[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/ted rul=[mod=%white who=[p={~nes} q={}]]]]
140−```
141−
142−Since we've set it for the whole `/ted` directory, if we check a file inside it we'll see it also has this permission:
143−
144−```hoon
145−> .^([r=dict:clay w=dict:clay] %cp /===/ted/aqua/ames/hoon)
146−[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/ted rul=[mod=%white who=[p={~nes} q={}]]]]
147−```
148−
149−...and you'll notice that `src` tells us it's inherited the rule from `/ted`.
150−
151−Now let's try setting both read and write permissions:
152−
153−```hoon
154−> -send-clay-task [%perm %home /gen/help/hoon %rw `[%black (sy [%.y ~nes]~)] `[%white (sy [%.y ~nes]~)]]
155−```
156−
157−```hoon
158− .^([r=dict:clay w=dict:clay] %cp /===/gen/help/hoon)
159−[r=[src=/gen/help/hoon rul=[mod=%black who=[p={~nes} q={}]]] w=[src=/gen/help/hoon rul=[mod=%white who=[p={~nes} q={}]]]]
160−```
161−
162−Lastly, let's look at deleting a permission rule we've previously set. To do that, we just send a null `(unit rule)` in the `rite`.
163−
164−For example, to remove a read permission (or write if you specify `%w`):
165−
166−```hoon
167−> -send-clay-task [%perm %home /gen/help/hoon %r ~]
168−```
169−
170−```hoon
171−> .^([r=dict:clay w=dict:clay] %cp /===/gen/help/hoon)
172−[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/gen/help/hoon rul=[mod=%white who=[p={~nes} q={}]]]]
173−```
174−
175−...and to remove both read and write at the same time:
176−
177−```hoon
178−> -send-clay-task [%perm %home /gen/help/hoon %rw ~ ~]
179−```
180−
181−```hoon
182−> .^([r=dict:clay w=dict:clay] %cp /===/gen/help/hoon)
183−[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/ rul=[mod=%white who=[p={} q={}]]]]
184−```
185−
186−As you can see it's back to the default inherited from `/`.
187−
188−Here's a breakdown of a `%perm` task:
189−
190−![perm diagram](https://pub.m.tinnus-napbus.xyz/perm-diagram.png)
191−
192−## %cred
193−
194−This simply creates a permission group. The task looks like this:
195−
196−```hoon
197−[%cred nom=@ta cew=crew] :: set permission group
198−```
199−
200−The `nom` is a name for the group and the `crew` is just a `(set ship)`:
201−
202−```hoon
203−+$ crew (set ship) :: permissions group
204−```
205−
206−Example:
207−
208−We'll use the same thread from the [%perm](#perm) example. Try:
209−
210−```hoon
211−-send-clay-task [%crew 'foo' (sy ~[~zod ~nec ~bud ~wes ~sev])]
212−```
213−
214−We'll check it with the next kind of `task`: [%crew](#crew).
215−
216−## %crew
217−
218−This retrieves all permission groups. It looks like:
219−
220−```hoon
221−[%crew ~] :: permission groups
222−```
223−
224−Clay wil return a sign containing a `%cruz` `gift`. It looks like:
225−
226−```hoon
227−[%cruz cez=(map @ta crew)] :: permission groups
228−```
229−
230−The `cez` is just a map from group name to `crew` which is just a `(set ship)`.
231−
232−Example:
233−
234−Here's a generic thread that sends the given `task` and receives a `gift` which it just prints to the dojo.
235−
236−`send-task-take-gift.hoon`
237−
238−```hoon
239−/- spider
240−/+ strandio
241−=, strand=strand:spider
242−^- thread:spider
243−|= arg=vase
244−=/ m (strand ,vase)
245−^- form:m
246−=/ uarg !< (unit task:clay) arg
247−?~ uarg
248− (strand-fail:strand %no-arg ~)
249−=/ =task:clay u.uarg
250−=/ =card:agent:gall [%pass /foo %arvo %c task]
251−;< ~ bind:m (send-raw-card:strandio card)
252−;< res=[wire sign-arvo] bind:m take-sign-arvo:strandio
253−~& +>:res
254−(pure:m !>(~))
255−```
256−
257−Save the above to `ted/send-task-take-gift.hoon` and `|commit %home`. Now we'll check for the permission group we created in the [%cred](#cred) example:
258−
259−```hoon
260−> -send-task-take-gift [%crew ~]
261−[%cruz cez={[p=~.foo q={~nec ~bud ~wes ~zod ~sev}]}]
262−```
263−
264−## %crow
265−
266−This is the last group `task`. It retrieves all files and directories in all `desk`s which have permissions set for the group in question. It will not return inherited permissions, only those explicitly set. It looks like:
267−
268−```hoon
269−[%crow nom=@ta] :: group usage
270−```
271−
272−The `gift` you get back is a `%croz` which looks like:
273−
274−```hoon
275−[%croz rus=(map desk [r=regs w=regs])] :: rules for group
276−```
277−
278−...where `regs` is this structure:
279−
280−```hoon
281−+$ regs (map path rule) :: rules for paths
282−```
283−
284−Example:
285−
286−First we'll set a couple of permissions for the `foo` group we created in the [%cred](#cred) section using the `send-clay-task.hoon` thread from the [%perm](#perm) section:
287−
288−```hoon
289−> -send-clay-task [%perm %home /gen/hood/hi/hoon %w ~ %white (sy [%.n 'foo']~)]
290−> -send-clay-task [%perm %home /ted %w ~ %white (sy [%.n 'foo']~)]
291−```
292−
293−Notice we use a `%.n` in the `whom:clay` to indicate a group rather than the `%.y` of a group.
294−
295−Now we'll use the `send-task-take-gift.hoon` thread from the [%crew](#crew) section to try `%crow`:
296−
297−```hoon
298−> -send-receive-task [%crow 'foo']
299−[ %croz
300− rus
301− { [ p=%home
302− q
303− [ r={}
304− w
305− { [p=/gen/hood/hi/hoon q=[mod=%white who={[%.n p=~.foo]}]]
306− [p=/ted q=[mod=%white who={[%.n p=~.foo]}]]
307− }
308− ]
309− ]
310− }
311−]
312−```
arvo/clay/read.mddeleted−514
@@ -1,514 +0,0 @@
1−+++
2−title = "Read and Subscribe"
3−weight = 6
4−template = "doc.html"
5−+++
6−
7−Here we'll look at reading files and subscribing to changes. We'll do this by sending Clay a `card` containing a `%warp` `task`.
8−
9−## Contents
10−
11−- [Introduction](#introduction)
12−- [%sing](#sing) - Read a single file or directory.
13−- [%next](#next) - Subscribe for the next change to a file or directory.
14−- [%mult](#mult) - Subscribe for the next change to a set of files and/or directories.
15−- [%many](#many) - Track changes to a `desk` for the specified range of revisions.
16−- [Cancel Subsciption](#cancel-subscription)
17−
18−## Introduction
19−
20−A `%warp` `task` looks like:
21−
22−```hoon
23−[%warp wer=ship rif=riff] :: internal file req
24−```
25−
26−The `riff` part is the following structure:
27−
28−```hoon
29−+$ riff [p=desk q=(unit rave)] :: request+desist
30−```
31−
32− The `(unit rave)` is null to cancel a subscription, otherwise the `rave` is:
33−
34−```hoon
35−+$ rave :: general request
36− $% [%sing =mood] :: single request
37− [%next =mood] :: await next version
38− [%mult =mool] :: next version of any
39− [%many track=? =moat] :: track range
40− == ::
41−```
42−
43−- `%sing` - Read a single file or directory.
44−- `%next` - Subscribe for the next change to a file or directory.
45−- `%mult` - Subscribe for the next change to a set of files and/or directories.
46−- `%many` - Track changes to a desk for the specified range of revisions.
47−
48−We'll look at each of these in more detail later.
49−
50−Clay responds to a `%mult` request with a `sign` containing a `%wris` `gift`, and the rest with a `%writ` `gift`.
51−
52−A `%wris` `gift` looks like:
53−
54−```hoon
55−[%wris p=[%da p=@da] q=(set (pair care path))] :: many changes
56−```
57−
58−A `%writ` `gift` looks like:
59−
60−```hoon
61−[%writ p=riot] :: response
62−```
63−
64−The `riot` is just:
65−
66−```hoon
67−+$ riot (unit rant) :: response+complete
68−```
69−
70−And the `rant` has the following structure:
71−
72−```hoon
73−+$ rant :: response to request
74− $: p=[p=care q=case r=desk] :: clade release book
75− q=path :: spur
76− r=cage :: data
77− == ::
78−```
79−
80−The `cage` will contain the data you requested and its contents will vary depending on the kind of request and `care`.
81−
82−Now we'll look at each of the `rave` request types in turn.
83−
84−## %sing
85−
86−```hoon
87−[%sing =mood]
88−```
89−
90−This is for reading a single file or directory immediately. The `mood` structure is:
91−
92−```hoon
93−+$ mood [=care =case =path] :: request in desk
94−```
95−
96−The `care` is `%x`, `%y` or whatever else. This will determine what you can read and what type of data will be returned. See the type documentation and scry documentation for details on the various `care`s.
97−
98−The `case` specifies the `desk` revision and looks like:
99−
100−```hoon
101−+$ case :: ship desk case spur
102− $% [%da p=@da] :: date
103− [%tas p=@tas] :: label
104− [%ud p=@ud] :: number
105− == ::
106−```
107−
108−You can use whichever you prefer. The `path` will usually be a path to a file or directory like `/gen/hood/hi/hoon` but may be something else depending on the `care`.
109−
110−Example:
111−
112−`read-file.hoon`
113−
114−```hoon
115−/- spider
116−/+ strandio
117−=, strand=strand:spider
118−^- thread:spider
119−|= arg=vase
120−=/ m (strand ,vase)
121−^- form:m
122−=/ uarg !< (unit path) arg
123−?~ uarg
124− (strand-fail:strand %no-arg ~)
125−=/ =path u.uarg
126−;< =bowl:strand bind:m get-bowl:strandio
127−=/ =task:clay [%warp our.bowl %home ~ %sing %x da+now.bowl path]
128−=/ =card:agent:gall [%pass /sing %arvo %c task]
129−;< ~ bind:m (send-raw-card:strandio card)
130−;< =riot:clay bind:m (take-writ:strandio /sing)
131−(pure:m !>(riot))
132−```
133−
134−Save this thread to `/ted/read-file.hoon`, `|commit %home` and run it like:
135−
136−```hoon
137−> -read-file /gen/hood/hi/hoon
138−```
139−
140−You should see something like this as the output:
141−
142−```hoon
143−[ ~
144− [ p=[p=%x q=[%da p=~2021.4.17..10.55.30..ed01] r=%home]
145− q=/gen/hood/hi/hoon
146− r
147− [ p=%hoon
148− q
149− [ #t/@
150− q
151−3.548.750.706.400.251.607.252.023.288.575.526.190.856.734.474.077.821.289.791.377.301.707.878.697.553.411.219.689.905.949.957.893.633.811.025.757.107.990.477.902.858.170.125.439.223.250.551.937.540.468.638.902.955.378.837.954.792.031.592.462.617.422.136.386.332.469.076.584.061.249.923.938.374.214.925.312.954.606.277.212.923.859.309.330.556.730.410.200.952.056.760.727.611.447.500.996.168.035.027.753.417.869.213.425.113.257.514.474.700.810.203.348.784.547.006.707.150.406.298.809.062.567.217.447.347.357.039.994.339.342.906
152− ]
153− ]
154− ]
155−]
156−```
157−
158−The `cage` in the `riot` contains the file's data due to our use of an `%x` `care`. It needn't be an `%x` though. If we change it to `%u`, for example, we'll get a `?` `cage` instead:
159−
160−```hoon
161−> -read-file /gen/hood/hi/hoon
162−[ ~
163− [ p=[p=%u q=[%da p=~2021.4.26..06.51.32..56a7] r=%home]
164− q=/gen/hood/hi/hoon
165− r=[p=%flag q=[#t/?(%.y %.n) q=0]]
166− ]
167−]
168−```
169−
170−Here's a breakdown of the `task` we sent:
171−
172−![read file diagram](https://pub.m.tinnus-napbus.xyz/read-file.png "read file diagram")
173−
174−## %next
175−
176−```hoon
177−[%next =mood] :: await next version
178−```
179−
180−This subscribes to the next version of the specified file. The `mood` structure is the same as described in the `%sing` example.
181−
182−If you subscribe to the current `case` of the `desk`, Clay will not respond until the file changes. If you subscribe to a previous `case` of the `desk` and the file has changed in between then and now, it will immediately return the first change it comes across in that range. For example, if you're currently at `case` `100`, subscribe to case `50` and the file in question has been modified at both `60` and `80`, clay will immediately return the version of the file at `case` `60`.
183−
184−`sub-next.hoon`
185−
186−```hoon
187−/- spider
188−/+ strandio
189−=, strand=strand:spider
190−^- thread:spider
191−|= arg=vase
192−=/ m (strand ,vase)
193−^- form:m
194−=/ uarg !< (unit path) arg
195−?~ uarg
196− (strand-fail:strand %no-arg ~)
197−=/ =path u.uarg
198−;< =bowl:strand bind:m get-bowl:strandio
199−=/ =task:clay [%warp our.bowl %home ~ %next %x da+now.bowl path]
200−=/ =card:agent:gall [%pass /next %arvo %c task]
201−;< ~ bind:m (send-raw-card:strandio card)
202−;< =riot:clay bind:m (take-writ:strandio /next)
203−~& riot
204−?~ riot
205− %- (slog leaf+"{(spud path)} deleted!" ~)
206− (pure:m !>(~))
207−%- (slog leaf+"{(spud q.u.riot)} changed!" ~)
208−(pure:m !>(~))
209−```
210−
211−This thread will subscribe to the next version of the file given as an argument. It will print the `riot` it gets back from Clay and will also print a message saying whether the file's been deleted or changed.
212−
213−Save this in `ted/sub-next.hoon`, `|commit %home` and run like:
214−
215−```hoon
216−> -sub-next /foo/txt
217−```
218−
219−Now, in unix, create a file called `foo.txt` in the `ted` directory of your ship. In the dojo, hit backspace to disconnect the thread from the dojo prompt and run `|commit %home`. You should see something like:
220−
221−```hoon
222−> |commit %home
223−>=
224−[ ~
225− [ p=[p=%x q=[%ud p=106] r=%home]
226− q=/foo/txt
227− r=[p=%txt q=[#t/*'' q=[7.303.014 0]]]
228− ]
229−]
230−/foo/txt changed!
231−+ /~zod/home/106/foo/txt
232−```
233−
234−As you can see, the `riot` includes a `cage` with the data of `/foo/txt` due to our use of an `%x` care.
235−
236−Now run the thread again, and this time delete the file in unix and again `|commit %home` in the dojo. You should see:
237−
238−```hoon
239−> |commit %home
240−>=
241−~
242−/foo/txt deleted!
243−- /~zod/home/107/foo/txt
244−```
245−
246−You can see the `riot` is just `~` due to the file being deleted.
247−
248−Here's a breakdown of the task we sent:
249−
250−![subscribe next diagram](https://pub.m.tinnus-napbus.xyz/sub-next.png "subscribe next diagram")
251−
252−## %mult
253−
254−```hoon
255−[%mult =mool] :: next version of any
256−```
257−
258−This subscribes to the next version of a `set` of files or directories. Clay will only send a single response, and it will send it when *any* of the specified files change. For example, if you subscribe to both `/foo/txt` and `/bar/txt`, and only `/foo/txt` changes, Clay will send a response indicating a change to `/foo/txt`. If `/bar/txt` changes subsequently, it will not tell you. If more than one file changes at once, it will tell you about each of the changes in the one response.
259−
260−The behaviour with respect to requesting old `case`s is the same as explained in the [`%next`](#next) section above.
261−
262−The `mool` specified in the request is this structure:
263−
264−```hoon
265−+$ mool [=case paths=(set (pair care path))] :: requests in desk
266−```
267−
268−You can use a different `care` for each of the files specified by the `path` if you like. Significantly, the `care` will determine whether Clay sends a response for a given change. For example, if you subscribe to an existing `/foo/txt` with a `%u` `care` and `/foo/txt` is modified but isn't deleted, Clay will *not* tell you. However, if you subscribe with an `%x` `care`, it *will* tell you.
269−
270−Example:
271−
272−This thread will subscribe to `/foo/txt` with an `%x` `care` and `/bar/txt` with a `%u` `care`. It will print out the `%wris` it gets back from Clay.
273−
274−`sub-mult.hoon`
275−
276−```hoon
277−/- spider
278−/+ strandio
279−=, strand=strand:spider
280−^- thread:spider
281−|= arg=vase
282−=/ m (strand ,vase)
283−^- form:m
284−=/ files=(set (pair care:clay path))
285− %- sy :~
286− [%x /foo/txt]
287− [%u /bar/txt]
288− ==
289−;< =bowl:strand bind:m get-bowl:strandio
290−=/ =task:clay [%warp our.bowl %home ~ %mult da+now.bowl files]
291−=/ =card:agent:gall [%pass /mult %arvo %c task]
292−;< ~ bind:m (send-raw-card:strandio card)
293−;< response=(pair wire sign-arvo) bind:m take-sign-arvo:strandio
294−~& +.q.response
295−(pure:m !>(~))
296−```
297−
298−Save the above to `ted/sub-mult.hoon`, `|commit %home` and run with `-sub-mult`. Now, create `foo.txt` and `bar.txt` in your home directory, hit backspace in the dojo to disconnect the thread and run `|commit %home`. You should see something like:
299−
300−```hoon
301−> |commit %home
302−>=
303−[%wris p=[%da p=~2021.4.27..06.07.08..5ec4] q={[p=%u q=/bar/txt] [p=%x q=/foo/txt]}]
304−+ /~zod/home/151/foo/txt
305−+ /~zod/home/151/bar/txt
306−```
307−
308−You'll notice that, unlike a `%writ`, the `%wris` doesn't give you the data. It merely tells you the `care`s and `path`s of the files that changed. If you need to actually get the data, you can just scry or send a request for the files in question.
309−
310−Now, run the thread again, open `bar.txt` in an editor, modify its contents, save it and `|commit %home`. You'll notice you didn't receive a `%wris`. This is because we subscribed to `/bar/txt` with `%u` care and its existence didn't change.
311−
312−Lastly, delete `foo.txt` and `|commit %home`. You should see something like:
313−
314−```hoon
315−> |commit %home
316−>=
317−[%wris p=[%da p=~2021.4.27..06.15.03..0da4] q={[p=%x q=/foo/txt]}]
318−- /~zod/home/153/foo/txt
319−```
320−
321−As you can see, a relevant change to any of the subscribed files will trigger a response, not just when all of them change.
322−
323−Here's a breakdown of the `task` we sent:
324−
325−![subscribe mult diagram](https://pub.m.tinnus-napbus.xyz/sub-mult.png "subscribe mult diagram")
326−
327−## %many
328−
329−```hoon
330−[%many track=? =moat] :: track range
331−```
332−
333−This subscribes to all changes to a `desk` for the specified range of `case`s. Note that you're unlikely to use this directly, it's mostly used implicitly if you make a `%sing` or `%next` request with a `%v` `care` to a foreign `desk`. Regardless, we'll have a look at it for completeness.
334−
335−If the `track` is `%.y` it will just return a `%writ` like:
336−
337−```hoon
338−[%writ p=[~ [p=[p=%w q=[%ud p=256] r=%home] q=/ r=[p=%null q=[#t/@n q=0]]]]]
339−```
340−
341−...that merely informs you of a change. If you want the actual data you'll have to request it separately.
342−
343−If the `track` is `%.n`, the `cage` of the `%writ` will contain a `nako`, which looks like:
344−
345−```hoon
346−:: New desk data.
347−::
348−:: Sent to other ships to update them about a particular desk. Includes a map
349−:: of all new aeons to hashes of their commits, the most recent aeon, and sets
350−:: of all new commits and data.
351−::
352−+$ nako :: subscription state
353− $: gar=(map aeon tako) :: new ids
354− let=aeon :: next id
355− lar=(set yaki) :: new commits
356− bar=(set plop) :: new content
357− == ::
358−```
359−
360−As the comment explains, it contains all relevant data for a changes to a desk between what you have and the `case` requested. It is very large and fairly complicated. The `nako` structure is defined in the `clay.hoon` source file itself rather than in `lull.hoon` or elsewhere since you're unlikely to work with it yourself.
361−
362−The `moat` in the `%many` is the following structure:
363−
364−```hoon
365− +$ moat [from=case to=case =path] :: change range
366−```
367−
368−The `from` and `to` fields specify the range of `case`s for which to subscribe. The range is *inclusive*. It can be specified by date or by revision number, whichever you prefer.
369−
370−The `path` is a path to a file or directory. If it's `~` it refers to the root of the `desk` in question. This lets you say "only inform me of changes to the `desk` if the specified file or directory exists". If it doesn't exist, Clay will not send you anything.
371−
372−When you reach the end of the subscribed range of `case`s, Clay will send you a `%writ` with a null `riot` to inform you the subscription has ended like:
373−
374−```hoon
375−[%writ p=~]
376−```
377−
378−Example:
379−
380−This thread will subscribe to changes to your `%home` `desk` for the next three minutes. The `track` is `%.y` so it will only inform you of changes, not send the full `nako`. It will only get updates if the specified file exists. It contains a `main-loop` that will take an arbitrary number of `sign`s and print them out in the dojo. Since it never ends, you'll need to stop it with the `:spider|kill` command in the dojo.
381−
382−`sub-many.hoon`
383−
384−```hoon
385−/- spider
386−/+ strandio
387−=, strand=strand:spider
388−|%
389−++ take-sign-loop
390− =/ m (strand ,~)
391− ^- form:m
392− %- (main-loop:strandio ,~)
393− :~ |= ~
394− ^- form:m
395− ;< res=(pair wire sign-arvo)
396− bind:m
397− ((handle:strandio ,(pair wire sign-arvo)) take-sign-arvo:strandio)
398− ~& res
399− (pure:m ~)
400− ==
401−--
402−^- thread:spider
403−|= arg=vase
404−=/ m (strand ,vase)
405−^- form:m
406−=/ uarg !< (unit path) arg
407−?~ uarg
408− (strand-fail:strand %no-arg ~)
409−=/ =path u.uarg
410−;< =bowl:strand bind:m get-bowl:strandio
411−=/ =task:clay [%warp our.bowl %home ~ %many %.y da+now.bowl da+(add ~m3 now.bowl) path]
412−=/ =card:agent:gall [%pass /many %arvo %c task]
413−;< ~ bind:m (send-raw-card:strandio card)
414−;< ~ bind:m take-sign-loop
415−(pure:m !>(~))
416−```
417−
418−Make sure `foo.txt` doesn't exist in the root of your `%home` `desk`. Save this to `ted/sub-many.hoon`, `|commit %home`, run it like `-sub-many /foo/txt`, and hit backspace in the dojo to free up the dojo prompt. Now, add a file called `bar.txt` to your `desk` and `|commit %home`. You should see something like:
419−
420−```hoon
421−> |commit %home
422−>=
423−+ /~zod/home/260/bar/txt
424−```
425−
426−Notice you've received no `%writ` from Clay. This is because `/foo/txt` doesn't exist. Now, create `foo.txt` and `|commit %home` again. You should see:
427−
428−```hoon
429−> |commit %home
430−>=
431−[ p=/many
432− q=[%clay [%writ p=[~ [p=[p=%w q=[%ud p=261] r=%home] q=/ r=[p=%null q=[#t/@n q=0]]]]]]
433−]
434−+ /~zod/home/261/foo/txt
435−```
436−
437−Now that `/foo/txt` exists it will inform you of updates. Note that if you delete `/foo/txt` again it will again stop sending updates.
438−
439−Now try adding `baz.txt`:
440−
441−```hoon
442−> |commit %home
443−>=
444−[ p=/many
445− q=[%clay [%writ p=[~ [p=[p=%w q=[%ud p=262] r=%home] q=/ r=[p=%null q=[#t/@n q=0]]]]]]
446−]
447−+ /~zod/home/262/baz/txt
448−```
449−
450−Now wait until the three minutes is up and try making a change, for example deleting `baz.txt`:
451−
452−```hoon
453−> |commit %home
454−>=
455−[ p=/many
456− q=[%clay [%writ p=[~ [p=[p=%w q=[%ud p=264] r=%home] q=/ r=[p=%null q=[#t/@n q=0]]]]]]
457−]
458−[p=/many q=[%clay [%writ p=~]]]
459−- /~zod/home/263/baz/txt
460−```
461−
462−You can see that along with the normal `%writ` it's also sent a second `%writ` with a null `riot` to indicate the subscription has ended. This is because it has now passed the end of the range of `case`s to which you subscribed.
463−
464−Run `:spider|kill` to stop the thread.
465−
466−Here's a breakdown of the task we sent:
467−
468−![subscribe many diagram](https://pub.m.tinnus-napbus.xyz/sub-many.png "subscribe many diagram")
469−
470−## Cancel Subscription
471−
472−Here we'll look at cancelling a subscription. It's very simple, you just send a `%warp` with a null `(unit rave)` in the `riff`. Clay will cancel the subscription based on the `wire`. The request is exactly the same regardless of which type of `rave` you subscribed with originally.
473−
474−Example:
475−
476−This thread will subscribe to the `%next` version of `/foo/txt`, then immediately cancel the subscription and wait for a response to print (which it will never receive).
477−
478−`stop-sub.hoon`
479−
480−```hoon
481−/- spider
482−/+ strandio
483−=, strand=strand:spider
484−^- thread:spider
485−|= arg=vase
486−=/ m (strand ,vase)
487−^- form:m
488−;< =bowl:strand bind:m get-bowl:strandio
489−=/ =task:clay [%warp our.bowl %home ~ %next %x da+now.bowl /foo/txt]
490−=/ =card:agent:gall [%pass /next %arvo %c task]
491−;< ~ bind:m (send-raw-card:strandio card)
492−=. task [%warp our.bowl %home ~]
493−=. card [%pass /next %arvo %c task]
494−;< ~ bind:m (send-raw-card:strandio card)
495−;< =riot:clay bind:m (take-writ:strandio /next)
496−~& riot
497−(pure:m !>(~))
498−```
499−
500−Save the above to `ted/stop-sub.hoon`, `|commit %home`, run it with `-stop-sub` and hit backspace to detach it from the dojo prompt. Now, add `foo.txt` to the root of your `%home` `desk` and `|commit %home`. You should see:
501−
502−```hoon
503−> |commit %home
504−>=
505−+ /~zod/home/266/foo/txt
506−```
507−
508−As you can see we've received no `%writ`. We can thus conclude the subscription has successfully been cancelled.
509−
510−Run `:spider|kill` to stop the thread.
511−
512−Here's a breakdown of the `task` we sent:
513−
514−![cancel subscription diagram](https://pub.m.tinnus-napbus.xyz/stop-sub.png "cancel subscription diagram")
arvo/clay/scry.md+87−109
@@ -6,142 +6,120 @@ template = "doc.html"
6
6
7The various Clay scries are specified by a `care`, which is a single character corresponding with a Clay submodule. Apart from `%s` they just take a `path` to a `desk`, file or directory. All examples are dojo commands, the ='s in the path are automatically populated by the dojo like:
7The various Clay scries are specified by a `care`, which is a single character corresponding with a Clay submodule. Apart from `%s` they just take a `path` to a `desk`, file or directory. All examples are dojo commands, the ='s in the path are automatically populated by the dojo like:
8
8
9−```hoon
9+```
10> /===
10> /===
11[~.~zod ~.home ~.~2021.4.26..02.29.03..d31b ~]
11[~.~zod ~.home ~.~2021.4.26..02.29.03..d31b ~]
12```
12```
13
13
14## Contents
14## Contents
15
15
16−- [a](#a) - Build a hoon file.
16+- [%a](#a) - Build a `hoon` file.
17−- [b](#b) - Dynamic mark.
17+- [%b](#b) - Dynamic `mark`.
18−- [c](#c) - Dynamic mark conversion.
18+- [%c](#c) - Dynamic `mark` conversion.
19−- [d](#d) - List desks.
19+- [%d](#d) - List `desk`s.
20−- [e](#e) - Static mark.
20+- [%e](#e) - Static `mark`.
21−- [f](#f) - Static mark conversion.
21+- [%f](#f) - Static `mark` conversion.
22−- [p](#p) - File permissions.
22+- [%p](#p) - File permissions.
23−- [r](#r) - Vase-wrapped file data.
23+- [%r](#r) - Vase-wrapped file data.
24−- [s](#s) - Miscellaneous scries:
24+- [%s](#s) - Miscellaneous scries:
25− - [yaki](#yaki) - `yaki:clay` of the specified commit.
25+ - [%yaki](#yaki) - `yaki:clay` of the specified commit.
26− - [blob](#blob) - `blob:clay` of file.
26+ - [%blob](#blob) - `blob:clay` of file.
27− - [hash](#hash) - Content hash of the specified commit.
27+ - [%hash](#hash) - Content hash of the specified commit.
28− - [cage](#cage) - `cage` of the data of a file.
28+ - [%cage](#cage) - `cage` of the data of a file.
29− - [open](#open) - Compile prelude of file.
29+ - [%open](#open) - Compile prelude of file.
30− - [late](#late) - Most recent case of desk.
30+ - [%late](#late) - Most recent `case` of `desk`.
31− - [base](#base) - Mergebase of two desks.
31+ - [%base](#base) - Mergebase of two `desk`s.
32−- [t](#t) - List files in directory.
32+- [%t](#t) - List files in directory.
33−- [u](#u) - Check for existence of file.
33+- [%u](#u) - Check for existence of file.
34−- [v](#v) - Desk state.
34+- [%v](#v) - Desk state.
35−- [w](#w) - Revision number of the given desk case.
35+- [%w](#w) - Revision number of the given `desk` `case`.
36−- [x](#x) - Raw data of file.
36+- [%x](#x) - Raw data of file.
37−- [y](#y) - `arch` of a file or directory.
37+- [%y](#y) - `arch` of a file or directory.
38−- [z](#z) - Content hash of a file or directory.
38+- [%z](#z) - Content hash of a file or directory.
39−
39+
40−## a
40+## %a
41
41
42A scry with a `care` of `%a` will build a `hoon` file and return it as a `vase`.
42A scry with a `care` of `%a` will build a `hoon` file and return it as a `vase`.
43
43
44Example:
44Example:
45
45
46−```hoon
46+```
47.^(vase %ca /===/lib/strandio/hoon)
47.^(vase %ca /===/lib/strandio/hoon)
48```
48```
49
49
50−## b
50+## %b
51
51
52A scry with a `care` of `%b` will produce a `dais:clay` processed `mark` core for the specified `mark`. The `path` in the scry is a `mark`.
52A scry with a `care` of `%b` will produce a `dais:clay` processed `mark` core for the specified `mark`. The `path` in the scry is a `mark`.
53
53
54Example:
54Example:
55
55
56−```hoon
56+```
57.^(dais:clay %cb /===/txt)
57.^(dais:clay %cb /===/txt)
58```
58```
59
59
60−## c
60+## %c
61
61
62A scry with a `care` of `%c` will produce a `tube:clay` dynamically typed `mark` conversion gate. The `path` specifies two `mark`s - *from* and *to*, like `/txt/noun`.
62A scry with a `care` of `%c` will produce a `tube:clay` dynamically typed `mark` conversion gate. The `path` specifies two `mark`s - *from* and *to*, like `/txt/noun`.
63
63
64Example:
64Example:
65
65
66−```hoon
66+```
67> =a .^(tube:clay %cc /===/txt/mime)
67> =a .^(tube:clay %cc /===/txt/mime)
68> !< mime (a !>(~['foo']))
68> !< mime (a !>(~['foo']))
69[p=/text/plain q=[p=3 q=7.303.014]]
69[p=/text/plain q=[p=3 q=7.303.014]]
70```
70```
71
71
72−## d
72+## %d
73
73
74A scry with a `care` of `%d` will return a `(set desk)` of the `desk`s that exist on your ship.
74A scry with a `care` of `%d` will return a `(set desk)` of the `desk`s that exist on your ship.
75
75
76Example:
76Example:
77
77
78−```hoon
78+```
79> .^((set desk) %cd /===)
79> .^((set desk) %cd /===)
80{%home %kids}
80{%home %kids}
81```
81```
82
82
83−## e
83+## %e
84
84
85A scry with a `care` of `%e` will return a statically typed `nave:clay` `mark` core in a `vase`. The `path` in the scry specifies the `mark`.
85A scry with a `care` of `%e` will return a statically typed `nave:clay` `mark` core in a `vase`. The `path` in the scry specifies the `mark`.
86
86
87Example:
87Example:
88
88
89−```hoon
89+```
90.^(vase %ce /===/noun)
90.^(vase %ce /===/noun)
91```
91```
92
92
93−## f
93+## %f
94
94
95A scry with a `care` of `%f` will return a static `mark` conversion gate. The `path` specifies two `mark`s - *from* and *to*, like `/txt/mime`.
95A scry with a `care` of `%f` will return a static `mark` conversion gate. The `path` specifies two `mark`s - *from* and *to*, like `/txt/mime`.
96
96
97−```hoon
97+```
98> =a .^($-(text mime) %cf /===/txt/mime)
98> =a .^($-(text mime) %cf /===/txt/mime)
99> (a ~['foo'])
99> (a ~['foo'])
100[p=/text/plain q=[p=3 q=7.303.014]]
100[p=/text/plain q=[p=3 q=7.303.014]]
101```
101```
102
102
103−## p
103+## %p
104
104
105A scry with a `care` of `%p` will return the permissions of the file or directory in question. The type returned is a `[dict:clay dict:clay]` where the head is read permissions and the tail is write permissions.
105A scry with a `care` of `%p` will return the permissions of the file or directory in question. The type returned is a `[dict:clay dict:clay]` where the head is read permissions and the tail is write permissions.
106
106
107−A `dict` is:
108−
109−```hoon
110−+$ dict [src=path rul=real]
111−```
112−
113−...and a `real` is:
114−
115−```hoon
116−+$ real
117− $: mod=?(%black %white)
118− who=(pair (set ship) (map @ta crew))
119− ==
120−```
121−
122−...where:
123−
124−- `mod` specifies either a **black**list or a **white**list.
125−- `who` specifies:
126− - the set of allowed/disallowed ships.
127− - allowed/disallowed named `crew`s (a `crew` is just a `set` of ships) - basically groups.
128−
129If the specified file or directory has no permissions set, it will default to the permissions of its parent. If nothing above it has permissions set, it will default to empty whitelists. If the specified file or directory doesn't exist, it will also return the default empty whitelist.
107If the specified file or directory has no permissions set, it will default to the permissions of its parent. If nothing above it has permissions set, it will default to empty whitelists. If the specified file or directory doesn't exist, it will also return the default empty whitelist.
130
108
131Example:
109Example:
132
110
133−```hoon
111+```
134> .^([dict:clay dict:clay] %cp /===/gen)
112> .^([dict:clay dict:clay] %cp /===/gen)
135[[src=/ rul=[mod=%white who=[p={} q={}]]] src=/ rul=[mod=%white who=[p={} q={}]]]
113[[src=/ rul=[mod=%white who=[p={} q={}]]] src=/ rul=[mod=%white who=[p={} q={}]]]
136```
114```
137
115
138−## r
116+## %r
139
117
140A scry with a `care` of `%r` will return the data of the given file wrapped in a `vase` or crash if it's a directory. It's basically just a vase-wrapped `%x` scry.
118A scry with a `care` of `%r` will return the data of the given file wrapped in a `vase` or crash if it's a directory. It's basically just a vase-wrapped `%x` scry.
141
119
142Examples:
120Examples:
143
121
144−```hoon
122+```
145> .^(vase %cr /===/gen/hood/hi/hoon)
123> .^(vase %cr /===/gen/hood/hi/hoon)
146[ #t/@
124[ #t/@
147 q
125 q
@@ -149,31 +127,31 @@ Examples:
149]
127]
150```
128```
151
129
152−```hoon
130+```
153> !< @t .^(vase %cr /===/gen/hood/hi/hoon)
131> !< @t .^(vase %cr /===/gen/hood/hi/hoon)
154':: Helm: send message to an urbit\0a::\0a:::: /hoon/hi/hood/gen\0a ::\0a/? 310\0a:- %say\0a|=([^ [who=ship mez=$@(~ [a=tape ~])] ~] helm-send-hi+[who ?~(mez ~ `a.mez)])\0a'
132':: Helm: send message to an urbit\0a::\0a:::: /hoon/hi/hood/gen\0a ::\0a/? 310\0a:- %say\0a|=([^ [who=ship mez=$@(~ [a=tape ~])] ~] helm-send-hi+[who ?~(mez ~ `a.mez)])\0a'
155```
133```
156
134
157−```hoon
135+```
158> .^(vase %cr /===/gen)
136> .^(vase %cr /===/gen)
159Crash!
137Crash!
160```
138```
161
139
162−## s
140+## %s
163
141
164A scry with a `care` of `%s` is for miscellaneous internal and debug functions and is liable to change in the future.
142A scry with a `care` of `%s` is for miscellaneous internal and debug functions and is liable to change in the future.
165
143
166Rather than just a `path` to a file, the head of the `path` is tagged with one of `%yaki %blob %hash %cage %open %late %base` and the tail depends on which tag you use. We'll look at each in turn.
144Rather than just a `path` to a file, the head of the `path` is tagged with one of `%yaki %blob %hash %cage %open %late %base` and the tail depends on which tag you use. We'll look at each in turn.
167
145
168−### yaki
146+### %yaki
169
147
170−This will return the `yaki:clay` of the specified commit. It takes a `tako:clay`.
148+This will return the [yaki:clay](@/docs/arvo/clay/data-types.md#yaki-clay-commit) of the specified commit. It takes a [tako:clay](@/docs/arvo/clay/data-types.md#tako-clay-commit-reference).
171
149
172Example:
150Example:
173
151
174−Here we scry the `dome:clay` for `/===`, get the latest `tako:clay` and the do a `%s` scry for the `yaki:clay` in question.
152+Here we scry the [dome:clay](@/docs/arvo/clay/data-types.md#dome-desk-data) for `/===`, get the latest `tako:clay` and the do a `%s` scry for the `yaki:clay` in question.
175
153
176−```hoon
154+```
177> =/ =dome:clay .^(dome:clay %cv /===)
155> =/ =dome:clay .^(dome:clay %cv /===)
178 =/ =tako:clay (~(got by hit.dome) let.dome)
156 =/ =tako:clay (~(got by hit.dome) let.dome)
179 .^(yaki:clay %cs /===/yaki/(scot %uv tako))
157 .^(yaki:clay %cs /===/yaki/(scot %uv tako))
@@ -190,15 +168,15 @@ Here we scry the `dome:clay` for `/===`, get the latest `tako:clay` and the do a
190]
168]
191```
169```
192
170
193−### blob
171+### %blob
194
172
195−This will return the `blob:clay` of some file. It takes a `lobe:clay`.
173+This will return the [blob:clay](@/docs/arvo/clay/data-types.md#blob-clay-data) of some file. It takes a [lobe:clay](@/docs/arvo/clay/data-types.md#lobe-clay-data-reference).
196
174
197Example:
175Example:
198
176
199Here we grab the `lobe:clay` of `/gen/hood/hi/hoon` with a `%y` scry, then use it to do a `%s` scry for the `blob:clay` of the file.
177Here we grab the `lobe:clay` of `/gen/hood/hi/hoon` with a `%y` scry, then use it to do a `%s` scry for the `blob:clay` of the file.
200
178
201−```hoon
179+```
202> =/ =arch .^(arch %cy /===/gen/hood/hi/hoon)
180> =/ =arch .^(arch %cy /===/gen/hood/hi/hoon)
203 ?~ fil.arch
181 ?~ fil.arch
204 ~
182 ~
@@ -213,7 +191,7 @@ Here we grab the `lobe:clay` of `/gen/hood/hi/hoon` with a `%y` scry, then use i
213]
191]
214```
192```
215
193
216−### hash
194+### %hash
217
195
218This will return the `@uvI` content hash of the specified commit. It takes a `tako:clay`.
196This will return the `@uvI` content hash of the specified commit. It takes a `tako:clay`.
219
197
@@ -221,14 +199,14 @@ Example:
221
199
222Here we grab the `dome:clay` for `/===` with a `%v` scry, get the latest `tako:clay` and then do a `%s` `%hash` scry for it.
200Here we grab the `dome:clay` for `/===` with a `%v` scry, get the latest `tako:clay` and then do a `%s` `%hash` scry for it.
223
201
224−```hoon
202+```
225> =/ =dome:clay .^(dome:clay %cv /===)
203> =/ =dome:clay .^(dome:clay %cv /===)
226 =/ =tako:clay (~(got by hit.dome) let.dome)
204 =/ =tako:clay (~(got by hit.dome) let.dome)
227 .^(tako:clay %cs /===/hash/(scot %uv tako))
205 .^(tako:clay %cs /===/hash/(scot %uv tako))
2280v16.er7uq.oke4u.cru7u.nglu9.q3su7.6ub1o.bh4qk.r5uav.ut12d.5rdl5
2060v16.er7uq.oke4u.cru7u.nglu9.q3su7.6ub1o.bh4qk.r5uav.ut12d.5rdl5
229```
207```
230
208
231−### cage
209+### %cage
232
210
233This will return a `cage` of the data of some file. It takes a `lobe:clay`.
211This will return a `cage` of the data of some file. It takes a `lobe:clay`.
234
212
@@ -236,7 +214,7 @@ Example:
236
214
237Here we grab the `lobe:clay` of `/gen/hood/hi/hoon` with a `%y` scry, then use it to do a `%s` scry for the `cage` of the data.
215Here we grab the `lobe:clay` of `/gen/hood/hi/hoon` with a `%y` scry, then use it to do a `%s` scry for the `cage` of the data.
238
216
239−```hoon
217+```
240> =/ =arch .^(arch %cy /===/gen/hood/hi/hoon)
218> =/ =arch .^(arch %cy /===/gen/hood/hi/hoon)
241 ?~ fil.arch
219 ?~ fil.arch
242 ~
220 ~
@@ -250,49 +228,49 @@ Here we grab the `lobe:clay` of `/gen/hood/hi/hoon` with a `%y` scry, then use i
250]
228]
251```
229```
252
230
253−### open
231+### %open
254
232
255This is like a `%a` scry but it only compiles the prelude to the file, e.g. the Ford rune imports. Proper documentation for this will be done as part of Ford documentaton at a later date.
233This is like a `%a` scry but it only compiles the prelude to the file, e.g. the Ford rune imports. Proper documentation for this will be done as part of Ford documentaton at a later date.
256
234
257−### late
235+### %late
258
236
259This will return the most recent revision number of a `desk` that has been fully downloaded. The type it returns is a `cass:clay`. The `case` in the `beak` must be a revision number rather than a date. You can just provide a case of `1` since it returns the latest regardless. If we have nothing for the specified `desk`, this will just return the bunt of a `cass:clay` like `cass=[ud=0 da=~2000.1.1]`.
237This will return the most recent revision number of a `desk` that has been fully downloaded. The type it returns is a `cass:clay`. The `case` in the `beak` must be a revision number rather than a date. You can just provide a case of `1` since it returns the latest regardless. If we have nothing for the specified `desk`, this will just return the bunt of a `cass:clay` like `cass=[ud=0 da=~2000.1.1]`.
260
238
261Example:
239Example:
262
240
263−```hoon
241+```
264> .^(=cass:clay %cs /(scot %p (sein:title our now our))/kids/1/late)
242> .^(=cass:clay %cs /(scot %p (sein:title our now our))/kids/1/late)
265cass=[ud=50 da=~2021.4.22..10.38.50..57a8]
243cass=[ud=50 da=~2021.4.22..10.38.50..57a8]
266```
244```
267
245
268−```hoon
246+```
269> .^(=cass:clay %cs /~sampel/kids/1/late)
247> .^(=cass:clay %cs /~sampel/kids/1/late)
270cass=[ud=0 da=~2000.1.1]
248cass=[ud=0 da=~2000.1.1]
271```
249```
272
250
273−### base
251+### %base
274
252
275This will return the mergebase (i.e. most recent common ancestor) between two `desk`s. The type it returns is a `(list tako:clay)`. The first `desk` will just be the one in the `beak` `path` prefix and the second will be specified like `/ship/desk` at the end of the scry `path`. If there is no common ancestor between the two `desk`s, this will just produce an empty `list`.
253This will return the mergebase (i.e. most recent common ancestor) between two `desk`s. The type it returns is a `(list tako:clay)`. The first `desk` will just be the one in the `beak` `path` prefix and the second will be specified like `/ship/desk` at the end of the scry `path`. If there is no common ancestor between the two `desk`s, this will just produce an empty `list`.
276
254
277Examples:
255Examples:
278
256
279−```hoon
257+```
280> .^((list tako:clay) %cs /===/base/(scot %p (sein:title our now our))/kids)
258> .^((list tako:clay) %cs /===/base/(scot %p (sein:title our now our))/kids)
281~[102.787.244.596.033.419.950.995.540.301.493.841.569.518.772.322.508.085.465.561.801.703.148.627.263.473]
259~[102.787.244.596.033.419.950.995.540.301.493.841.569.518.772.322.508.085.465.561.801.703.148.627.263.473]
282```
260```
283
261
284−```hoon
262+```
285> .^((list tako:clay) %cs /===/base/~sampel/kids)
263> .^((list tako:clay) %cs /===/base/~sampel/kids)
286~
264~
287```
265```
288
266
289−## t
267+## %t
290
268
291A scry with a `care` of `%t` will return a `(list path)` of all files in the given directory, or just a `(list path)` of the single file if it's a file. This is done recursively so will provide files in subdirectories as well. The paths will be fully qualified except for the `ship`, `desk` and `case`. If the directory or file specified does not exist, it will return an empty `list`.
269A scry with a `care` of `%t` will return a `(list path)` of all files in the given directory, or just a `(list path)` of the single file if it's a file. This is done recursively so will provide files in subdirectories as well. The paths will be fully qualified except for the `ship`, `desk` and `case`. If the directory or file specified does not exist, it will return an empty `list`.
292
270
293Examples:
271Examples:
294
272
295−```hoon
273+```
296> .^((list path) %ct /===/app/landscape)
274> .^((list path) %ct /===/app/landscape)
297~[
275~[
298 /app/landscape/css/index/css
276 /app/landscape/css/index/css
@@ -304,44 +282,44 @@ Examples:
304]
282]
305```
283```
306
284
307−```hoon
285+```
308> .^((list path) %ct /===/gen/group-store/add/hoon)
286> .^((list path) %ct /===/gen/group-store/add/hoon)
309~[/gen/group-store/add/hoon]
287~[/gen/group-store/add/hoon]
310```
288```
311
289
312−```hoon
290+```
313> .^((list path) %ct /===/foobar)
291> .^((list path) %ct /===/foobar)
314~
292~
315```
293```
316
294
317−## u
295+## %u
318
296
319A scry with a `care` of `%u` will return a `?` depending on whether the file exists. It will produce `%.n` if it's a directory or doesn't exist and will produce `%.y` if it's a file and exists.
297A scry with a `care` of `%u` will return a `?` depending on whether the file exists. It will produce `%.n` if it's a directory or doesn't exist and will produce `%.y` if it's a file and exists.
320
298
321Examples:
299Examples:
322
300
323−```hoon
301+```
324> .^(? %cu /===/app)
302> .^(? %cu /===/app)
325%.n
303%.n
326```
304```
327
305
328−```hoon
306+```
329> .^(? %cu /===/gen/code/hoon)
307> .^(? %cu /===/gen/code/hoon)
330%.y
308%.y
331```
309```
332
310
333−```hoon
311+```
334> .^(? %cu /===/foobar)
312> .^(? %cu /===/foobar)
335%.n
313%.n
336```
314```
337
315
338−## v
316+## %v
339
317
340A scry with a care of `%v` will return the entire state of a `desk` as a `dome:clay`.
318A scry with a care of `%v` will return the entire state of a `desk` as a `dome:clay`.
341
319
342Example:
320Example:
343
321
344−```hoon
322+```
345> =a .^(dome:clay %cv /===)
323> =a .^(dome:clay %cv /===)
346> let.a
324> let.a
3471
3251
@@ -349,40 +327,40 @@ Example:
349
327
350Note: If you try printing this it will take forever and probably OOM your ship.
328Note: If you try printing this it will take forever and probably OOM your ship.
351
329
352−## w
330+## %w
353
331
354A scry with a `care` of `%w` will return the revision number and date of a given `case`. The type returned is a `cass:clay` like `[ud=@ud da=@da]` where `ud` is the revision number and `da` is the date.
332A scry with a `care` of `%w` will return the revision number and date of a given `case`. The type returned is a `cass:clay` like `[ud=@ud da=@da]` where `ud` is the revision number and `da` is the date.
355
333
356Example:
334Example:
357
335
358−```hoon
336+```
359> .^(cass:clay %cw /===)
337> .^(cass:clay %cw /===)
360[ud=2 da=~2021.4.13..19.12.49..3389]
338[ud=2 da=~2021.4.13..19.12.49..3389]
361```
339```
362
340
363−## x
341+## %x
364
342
365A scry with a `care` of `%x` will return the raw data of a file as an `@` or crash if it's a directory.
343A scry with a `care` of `%x` will return the raw data of a file as an `@` or crash if it's a directory.
366
344
367
345
368Examples:
346Examples:
369
347
370−```hoon
348+```
371> .^(@ %cx /===/gen/hood/hi/hoon)
349> .^(@ %cx /===/gen/hood/hi/hoon)
3723.548.750.706.400.251.607.252.023.288.575.526.190.856.734.474.077.821.289.791.377.301.707.878.697.553.411.219.689.905.949.957.893.633.811.025.757.107.990.477.902.858.170.125.439.223.250.551.937.540.468.638.902.955.378.837.954.792.031.592.462.617.422.136.386.332.469.076.584.061.249.923.938.374.214.925.312.954.606.277.212.923.859.309.330.556.730.410.200.952.056.760.727.611.447.500.996.168.035.027.753.417.869.213.425.113.257.514.474.700.810.203.348.784.547.006.707.150.406.298.809.062.567.217.447.347.357.039.994.339.342.906
3503.548.750.706.400.251.607.252.023.288.575.526.190.856.734.474.077.821.289.791.377.301.707.878.697.553.411.219.689.905.949.957.893.633.811.025.757.107.990.477.902.858.170.125.439.223.250.551.937.540.468.638.902.955.378.837.954.792.031.592.462.617.422.136.386.332.469.076.584.061.249.923.938.374.214.925.312.954.606.277.212.923.859.309.330.556.730.410.200.952.056.760.727.611.447.500.996.168.035.027.753.417.869.213.425.113.257.514.474.700.810.203.348.784.547.006.707.150.406.298.809.062.567.217.447.347.357.039.994.339.342.906
373```
351```
374
352
375−```hoon
353+```
376> .^(@t %cx /===/gen/hood/hi/hoon)
354> .^(@t %cx /===/gen/hood/hi/hoon)
377':: Helm: send message to an urbit\0a::\0a:::: /hoon/hi/hood/gen\0a ::\0a/? 310\0a:- %say\0a|=([^ [who=ship mez=$@(~ [a=tape ~])] ~] helm-send-hi+[who ?~(mez ~ `a.mez)])\0a'
355':: Helm: send message to an urbit\0a::\0a:::: /hoon/hi/hood/gen\0a ::\0a/? 310\0a:- %say\0a|=([^ [who=ship mez=$@(~ [a=tape ~])] ~] helm-send-hi+[who ?~(mez ~ `a.mez)])\0a'
378```
356```
379
357
380−```hoon
358+```
381> .^(@ %cx /===/gen/hood)
359> .^(@ %cx /===/gen/hood)
382Crash!
360Crash!
383```
361```
384
362
385−## y
363+## %y
386
364
387A scry with a `care` of `%y` will return the `arch` of a file or directory.
365A scry with a `care` of `%y` will return the `arch` of a file or directory.
388
366
@@ -392,7 +370,7 @@ It will return the bunt of an `arch` if the file or directory is not found.
392
370
393Examples:
371Examples:
394
372
395−```hoon
373+```
396> .^(arch %cy /===/gen/group-store)
374> .^(arch %cy /===/gen/group-store)
397[ fil=~
375[ fil=~
398 dir
376 dir
@@ -408,22 +386,22 @@ Examples:
408]
386]
409```
387```
410
388
411−```hoon
389+```
412> .^(arch %cy /===/gen/group-store/allow-ships)
390> .^(arch %cy /===/gen/group-store/allow-ships)
413[fil=~ dir={[p=~.hoon q=~]}]
391[fil=~ dir={[p=~.hoon q=~]}]
414```
392```
415
393
416−```hoon
394+```
417> .^(arch %cy /===/gen/group-store/allow-ships/hoon)
395> .^(arch %cy /===/gen/group-store/allow-ships/hoon)
418[fil=[~ 0vb.g8sqs.7gjm9.bl3vu.nk677.h5be1.g9eg3.4v1jo.00ivf.g8ndu.48a53] dir={}]
396[fil=[~ 0vb.g8sqs.7gjm9.bl3vu.nk677.h5be1.g9eg3.4v1jo.00ivf.g8ndu.48a53] dir={}]
419```
397```
420
398
421−```hoon
399+```
422> .^(arch %cy /===/foobar)
400> .^(arch %cy /===/foobar)
423[fil=~ dir={}]
401[fil=~ dir={}]
424```
402```
425
403
426−## z
404+## %z
427
405
428A scry with a `care` of `%z` will return the hash of a file or the recursive hash of a directory. If the file or directory doesn't exist it will return a null value.
406A scry with a `care` of `%z` will return the hash of a file or the recursive hash of a directory. If the file or directory doesn't exist it will return a null value.
429
407
@@ -431,17 +409,17 @@ The type returned is a `@uxI`.
431
409
432Examples:
410Examples:
433
411
434−```hoon
412+```
435> .^(@uvI %cz /===/gen)
413> .^(@uvI %cz /===/gen)
4360v5.itmhj.lt7ak.lgr1k.dr7vu.u7u9s.ko5rf.idfcr.ukrd2.t088n.3ml1k
4140v5.itmhj.lt7ak.lgr1k.dr7vu.u7u9s.ko5rf.idfcr.ukrd2.t088n.3ml1k
437```
415```
438
416
439−```hoon
417+```
440> .^(@uvI %cz /===/gen/code/hoon)
418> .^(@uvI %cz /===/gen/code/hoon)
4410v1t.vi1pf.3ba4n.87g6h.dcc1p.4t4l8.rm6a9.b4de4.v77qc.p9dc0.p8289
4190v1t.vi1pf.3ba4n.87g6h.dcc1p.4t4l8.rm6a9.b4de4.v77qc.p9dc0.p8289
442```
420```
443
421
444−```hoon
422+```
445> .^(@uvI %cz /===/foobar)
423> .^(@uvI %cz /===/foobar)
4460v0
4240v0
447```
425```
arvo/clay/tasks.mdnew file+462
@@ -0,0 +1,462 @@
1++++
2+title = "API Reference"
3+weight = 6
4+template = "doc.html"
5++++
6+
7+# Contents
8+
9+- [Introduction](#introduction)
10+- [Read and Subscribe](#read-and-subscribe)
11+ - [%sing](#sing) - Read a file or directory.
12+ - [%next](#next) - Subscribe for the next change to a file or directory.
13+ - [%mult](#mult) - Subscribe for the next change to a set of files and/or directories.
14+ - [%many](#many) - Track changes to a `desk` for the specified range of revisions.
15+ - [Cancel Subscription](#cancel-subscription)
16+- [Write and Modify](#write-and-modify)
17+ - [%info](#info)
18+- [Manage Mounts](#manage-mounts)
19+ - [%boat](#boat) - List mounts.
20+ - [%mont](#mont) - Mount something.
21+ - [%ogre](#ogre) - Unmount something.
22+ - [%dirk](#dirk) - Commit changes.
23+- [Merge Desks](#merge-desks)
24+ - [%merg](#merg)
25+- [Permissions](#permissions)
26+ - [%perm](#perm) - Set file permissions.
27+ - [%cred](#cred) - Add permission group.
28+ - [%crew](#crew) - Get permission groups.
29+ - [%crow](#crow) - Get group usage.
30+- [Foreign Ships](#foreign-ships)
31+ - [%warp](#warp) - Read a file on a foreign ship.
32+ - [%merg](#merg) - Merge from a foreign `desk`.
33+
34+# Introduction
35+
36+This document details all the `task`s you're likely to use to interact with Clay, as well as the `gift`s you'll receive in response. Each section has a corresponding practical example in the [Examples](@/docs/arvo/clay/examples.md) document. Many of the types referenced are detailed in the [Data Types](@/docs/arvo/clay/data-types.md) document. It may also be useful to look at the `++ clay` section of `/sys/lull.hoon` in Arvo where these `task`s, `gift`s and data structures are defined.
37+
38+The focus of this document is on interacting with Clay from userspace applications and threads, so it doesn't delve into the internal mechanics of Clay from a kernel development perspective.
39+
40+# Read and Subscribe
41+
42+Here we'll look at reading files and subscribing to changes. This is done by sending Clay a `%warp` `task`:
43+
44+```hoon
45+[%warp wer=ship rif=riff] :: internal file req
46+```
47+
48+The `wer` field is the target ship. The `(unit rave)` of the [riff](@/docs/arvo/clay/data-types.md#riff-clay-request-desist) is null to cancel an existing subscription, otherwise the [rave](@/docs/arvo/clay/data-types.md#rave-clay-general-subscription-request) is tagged with one of:
49+
50+- `%sing` - Read a single file or directory.
51+- `%next` - Subscribe for the next change to a file or directory.
52+- `%mult` - Subscribe for the next change to a set of files and/or directories.
53+- `%many` - Track changes to a desk for the specified range of revisions.
54+
55+We'll look at each of these in more detail below.
56+
57+Clay responds to a `%mult` request with a `%wris` `gift`, and the rest with a `%writ` `gift`.
58+
59+A `%wris` `gift` looks like:
60+
61+```hoon
62+[%wris p=[%da p=@da] q=(set (pair care path))] :: many changes
63+```
64+
65+...and a `%writ` `gift` looks like:
66+
67+```hoon
68+[%writ p=riot] :: response
69+```
70+
71+The `unit` of the [riot](@/docs/arvo/clay/data-types.md#riot-clay-response) will be null if the target file cannot be found or if a subscription has ended (depending on context). Otherwise it will have a [rant](@/docs/arvo/clay/data-types.md#rant-clay-response-data) with a `cage` containing the data you requested. Its contents will vary depending on the kind of request and `care`.
72+
73+Now we'll look at each of the `rave` request types in turn.
74+
75+## %sing
76+
77+```hoon
78+[%sing =mood]
79+```
80+
81+This is for reading a single file or directory immediately. The `care` of the [mood](@/docs/arvo/clay/data-types.md#mood-clay-single-subscription-request) will determine what you can read and what type of data will be returned. See the [care](@/docs/arvo/clay/data-types.md#care-clay-clay-submode) documentation and [scry](@/docs/arvo/clay/scry.md) documentation for details on the various `care`s.
82+
83+The [case](@/docs/arvo/clay/data-types.md#case-specifying-a-commit) specifies the `desk` revision and you can use whichever kind you prefer. The `path` will usually be a path to a file or directory like `/gen/hood/hi/hoon` but may be something else depending on the `care`.
84+
85+[See here for an example of using %sing.](@/docs/arvo/clay/examples.md#sing)
86+
87+## %next
88+
89+```hoon
90+[%next =mood] :: await next version
91+```
92+
93+This subscribes to the next version of the specified file. See [here](@/docs/arvo/clay/data-types.md#mood-clay-single-subscription-request) for details of the `mood` structure.
94+
95+If you subscribe to the current `case` of the `desk`, Clay will not respond until the file changes. If you subscribe to a previous `case` of the `desk` and the file has changed in between then and now, it will immediately return the first change it comes across in that range. For example, if you're currently at `case` `100`, subscribe to case `50` and the file in question has been modified at both `60` and `80`, clay will immediately return the version of the file at `case` `60`.
96+
97+[See here for an example of using %next.](@/docs/arvo/clay/examples.md#next)
98+
99+## %mult
100+
101+```hoon
102+[%mult =mool] :: next version of any
103+```
104+
105+This subscribes to the next version of a `set` of files or directories. Clay will only send a single response, and it will send it when *any* of the specified files change. For example, if you subscribe to both `/foo/txt` and `/bar/txt`, and only `/foo/txt` changes, Clay will send a response indicating a change to `/foo/txt`. If `/bar/txt` changes subsequently, it will not tell you. If more than one file changes at once, it will tell you about each of the changes in the one response.
106+
107+The behaviour with respect to requesting old `case`s is the same as explained in the [`%next`](#next) section above.
108+
109+The `mool` specified in the request is this structure:
110+
111+```hoon
112++$ mool [=case paths=(set (pair care path))] :: requests in desk
113+```
114+
115+You can use a different `care` for each of the files specified by the `path` if you like. Significantly, the `care` will determine whether Clay sends a response for a given change. For example, if you subscribe to an existing `/foo/txt` with a `%u` `care` and `/foo/txt` is modified but isn't deleted, Clay will *not* tell you. However, if you subscribe with an `%x` `care`, it *will* tell you.
116+
117+[See here for an example of using %mult.](@/docs/arvo/clay/examples.md#mult)
118+
119+## %many
120+
121+```hoon
122+[%many track=? =moat] :: track range
123+```
124+
125+This subscribes to all changes to a `desk` for the specified range of `case`s. Note that you're unlikely to use this directly, it's mostly used implicitly if you make a `%sing` or `%next` request with a `%v` `care` to a foreign `desk`. Regardless, we'll have a look at it for completeness.
126+
127+If the `track` is `%.y` it will just return a `%writ` like:
128+
129+```hoon
130+[%writ p=[~ [p=[p=%w q=[%ud p=256] r=%home] q=/ r=[p=%null q=[#t/@n q=0]]]]]
131+```
132+
133+...that merely informs you of a change. If you want the actual data you'll have to request it separately.
134+
135+If the `track` is `%.n`, the `cage` of the `%writ` will contain a [nako](@/docs/arvo/clay/data-types.md#nako-subscription-response-data) with the relevant data for all changes to a desk between what you have and the `case` requested. It is very large and fairly complicated. The `nako` structure is defined in the `clay.hoon` source file itself rather than in `lull.hoon` or elsewhere since you're unlikely to work with it yourself.
136+
137+The `from` and `to` fields of the [moat](@/docs/arvo/clay/data-types.md#moat-clay-range-subscription-request) specify the range of `case`s for which to subscribe. The range is *inclusive*. It can be specified by date or by revision number, whichever you prefer.
138+
139+The `path` in the `moat` is a path to a file or directory. If it's `~` it refers to the root of the `desk` in question. This lets you say "only inform me of changes to the `desk` if the specified file or directory exists". If it doesn't exist, Clay will not send you anything.
140+
141+When you reach the end of the subscribed range of `case`s, Clay will send you a `%writ` with a null `riot` to inform you the subscription has ended like:
142+
143+```hoon
144+[%writ p=~]
145+```
146+
147+[See here for an example of using %many.](@/docs/arvo/clay/examples.md#many)
148+
149+## Cancel Subscription
150+
151+To cancel a subscription, you just send a `%warp` with a null `(unit rave)` in the `riff`. Clay will cancel the subscription based on the `wire`. The request is exactly the same regardless of which type of `rave` you subscribed with originally.
152+
153+[See here for an example of cancelling a subscription.](@/docs/arvo/clay/examples.md#cancel-subscription)
154+
155+# Write and Modify
156+
157+## %info
158+
159+To write or modify a file, we send Clay a `%info` `task`:
160+
161+```hoon
162+[%info des=desk dit=nori] :: internal edit
163+```
164+
165+The `%|` tag in the [nori](@/docs/arvo/clay/data-types.md#nori-clay-repository-action) is not currently supported and will crash with a `%labelling-not-implemented` if used, so you can focus on the `%&` part. The [soba](@/docs/arvo/clay/data-types.md#soba-clay-delta) in the `nori` is just a list of changes so you can make more than one change in one request. Its `path` is just the path to a file like `/gen/hood/hi/hoon` and the [miso](@/docs/arvo/clay/data-types.md#miso-clay-ankh-delta) is one of these types of requests:
166+
167+- `%del` - Delete a file.
168+- `%ins` - Insert file. This will also replace an existing file.
169+- `%dif` - This has not yet been implemented so will crash with a `%dif-not-implemented` error.
170+- `%mut` - Change a file. At the time of writing this behaves identically to `%ins` so its use merely informs the reader.
171+
172+Clay does not give any response to an `%info` `task` so don't expect a `sign` back.
173+
174+Here are examples of using each of these as well as making multiple changes in one request:
175+
176+- [%del](@/docs/arvo/clay/examples.md#del)
177+- [%ins](@/docs/arvo/clay/examples.md#ins)
178+- [%mut](@/docs/arvo/clay/examples.md#mut)
179+- [Multiple Changes](@/docs/arvo/clay/examples.md#multiple-changes)
180+
181+
182+# Manage Mounts
183+
184+Here we'll look at managing Clay unix mounts programmatically.
185+
186+There are four Clay `task`s relevant to mounts:
187+
188+- [%boat](#boat) - List mounts.
189+- [%mont](#mont) - Mount something.
190+- [%ogre](#ogre) - Unmount something.
191+- [%dirk](#dirk) - Commit changes.
192+
193+## %boat
194+
195+This type of `task` will request the list of existing mounts. It looks like:
196+
197+```hoon
198+[%boat ~]
199+```
200+
201+Pretty simple. The type it returns is a `%hill` `gift`, which looks like:
202+
203+```hoon
204+[%hill p=(list @tas)]
205+```
206+
207+...where the `@tas` is the name of the mount point.
208+
209+[See here for an example of using %boat.](@/docs/arvo/clay/examples.md#boat)
210+
211+## %mont
212+
213+This type of `task` mounts the specified `beam` to the specified `term` mount point. It looks like:
214+
215+```hoon
216+[%mont pot=term bem=beam]
217+```
218+
219+A `beam:clay` is the following structure:
220+
221+```hoon
222++$ beam [[p=ship q=desk r=case] s=path] :: global name
223+```
224+
225+You can mount the whole desk with a `path` of `/`, and you can also mount subdirectories or even individual files. If you want to mount an individual file, you must exclude its `mark` from the path. For example, if you want to mount `/gen/hood/hi/hoon`, you'd specify `/gen/hood/hi`. It will automatically be given the correct file extension when mounted. If you include the `hoon` mark it will crash (and currently crash your ship).
226+
227+[See here for an example of using %mont.](@/docs/arvo/clay/examples.md#mont)
228+
229+## %ogre
230+
231+This type of `task` unmounts the specified mount. It's defined in `lull.hoon` as:
232+
233+```hoon
234+[%ogre pot=$@(desk beam)]
235+```
236+
237+But in fact it will only unmount the target when specified as a `term` mount name. Passing it a `desk` will incidentally work if the mount is named the same as the `desk` but otherwise it won't work. Passing it a `beam:clay` will simply not work.
238+
239+[See here for an example of using %ogre.](@/docs/arvo/clay/examples.md#ogre)
240+
241+## %dirk
242+
243+This type of `task` commits changes in the target mount. It's defined in `lull.hoon` as:
244+
245+```hoon
246+[%dirk des=desk]
247+```
248+
249+... but like [%ogre](#ogre), it actually takes the name of a mount point rather than a `desk` as is specified.
250+
251+[See here for an example of using %dirk.](@/docs/arvo/clay/examples.md#dirk)
252+
253+# Merge Desks
254+
255+## %merg
256+
257+A `%merg` `task` will merge the specified source `desk` into the target local `desk`. It looks like:
258+
259+```hoon
260+$: %merg :: merge desks
261+ des=desk :: target
262+ her=@p dem=desk cas=case :: source
263+ how=germ :: method
264+== ::
265+```
266+
267+The `germ` specifies the merge strategy. You can refer to the [Strategies](@/docs/arvo/clay/using.md#strategies) section of the [Using Clay](@/docs/arvo/clay/using.md) document for details of each `germ`.
268+
269+If you're merging into a new `desk` you must use `%init`, all other strategies will fail. If the desk already exists, you cannot use `%init`. Otherwise, you're free to use whichever you'd like.
270+
271+Clay will respond to the request with a `%mere` `gift` which looks like:
272+
273+```hoon
274+[%mere p=(each (set path) (pair term tang))] :: merge result
275+```
276+
277+If the merge succeeded, `p` will look like `[%mere p=[%.y p={}]]` where `p.p` is the set of files which had a merge conflict. For example, `[%mere p=[%.y p={/foo/txt}]]` means there was a conflict with `/foo/txt`. An empty set means there were no conflicts.
278+
279+If the merge failed, `p` will have a head of `%.n` and then a `[term tang]` where the `term` is an error message and the `tang` contains additional details, for example:
280+
281+```hoon
282+[ %mere
283+ p
284+ [ %.n
285+ p=[p=%mate-conflict q=~[[%rose p=[p="/" q="/" r=""] q=~[[%leaf p="foo"] [%leaf p="txt"]]]]]
286+ ]
287+]
288+```
289+
290+[See here for an example of using %merg.](@/docs/arvo/clay/examples.md#merg)
291+
292+# Permissions
293+
294+For each file or directory, there is both a read permission and a write permission. Each may be set separately and is either a whitelist or a blacklist (but not both). The whitelist/blacklist contains a `set` of ships and/or groups which are allowed or banned respectively. If it's an empty whitelist it means all foreign ships are denied. If it's an empty blacklist it means all foreign ships are allowed.
295+
296+If permissions are not set for a particular file, they will be inherited from the directory in which it resides. If *that* directory has no permissions set, they will be inherited from another level up, and so on to the `desk`'s root directory. If the root directory has no permissions set, it will have the default permissions of an empty whitelist, meaning "deny all".
297+
298+A group is called a `crew` and is just a `set` of ships with a `@ta` name.
299+
300+The permissions for each file or directory are a pair of `dict:clay` where the head is read permissions and the tail is write permissions.
301+
302+A `dict:clay` is this structure:
303+
304+```hoon
305++$ dict [src=path rul=real] :: effective permission
306+```
307+
308+The `src` path is where the permissions were inherited from and the `real` is this structure:
309+
310+```hoon
311+ +$ real :: resolved permissions
312+ $: mod=?(%black %white) ::
313+ who=(pair (set ship) (map @ta crew)) ::
314+ == ::
315+```
316+
317+So if we scry for permissions with a `%p` `care`, it'll look like:
318+
319+```hoon
320+> .^([r=dict:clay w=dict:clay] %cp /===/lib/strandio/hoon)
321+[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/ rul=[mod=%white who=[p={} q={}]]]]
322+```
323+
324+There are four permission-related `task`s which you can pass to Clay.
325+
326+A `%perm` `task` is for setting permissions, and the other three are for managing groups:
327+
328+- `%cred` - Add permission group.
329+- `%crew` - Get permission groups.
330+- `%crow` - Get group usage.
331+
332+We'll look at each of these in turn.
333+
334+## %perm
335+
336+This sets permissions for the target file or directory.
337+
338+Note this will replace existing permissions rather than add to them, so if you want to add a ship to an existing whitelist or whatever you'll have to first read the existing permissions, add the ship, then send the whole lot back.
339+
340+A `%perm` `task` looks like:
341+
342+```hoon
343+[%perm des=desk pax=path rit=rite] :: change permissions
344+```
345+
346+The `pax` path is the file or directory whose permissions you want to change, and the `rite` is this structure:
347+
348+```hoon
349++$ rite :: new permissions
350+ $% [%r red=(unit rule)] :: for read
351+ [%w wit=(unit rule)] :: for write
352+ [%rw red=(unit rule) wit=(unit rule)] :: for read and write
353+```
354+
355+Where a `rule` is this structure:
356+
357+```hoon
358++$ rule [mod=?(%black %white) who=(set whom)] :: node permission
359+```
360+
361+...and finally `whom` is this:
362+
363+```hoon
364++$ whom (each ship @ta) :: ship or named crew
365+```
366+
367+As the comment suggests, the `@ta` is the name of a `crew` (group).
368+
369+[See here for an example of using %perm.](@/docs/arvo/clay/examples.md#perm)
370+
371+## %cred
372+
373+This simply creates a permission group. The task looks like this:
374+
375+```hoon
376+[%cred nom=@ta cew=crew] :: set permission group
377+```
378+
379+The `nom` is a name for the group and the `crew` is just a `(set ship)`:
380+
381+```hoon
382++$ crew (set ship) :: permissions group
383+```
384+
385+[See here for an example of using %cred.](@/docs/arvo/clay/examples.md#cred)
386+
387+## %crew
388+
389+This retrieves all permission groups. It looks like:
390+
391+```hoon
392+[%crew ~] :: permission groups
393+```
394+
395+Clay wil return a sign containing a `%cruz` `gift`. It looks like:
396+
397+```hoon
398+[%cruz cez=(map @ta crew)] :: permission groups
399+```
400+
401+The `cez` is just a map from group name to `crew` which is just a `(set ship)`.
402+
403+[See here for an example of using %crew.](@/docs/arvo/clay/examples.md#crew)
404+
405+## %crow
406+
407+This is the last group `task`. It retrieves all files and directories in all `desk`s which have permissions set for the group in question. It will not return inherited permissions, only those explicitly set. It looks like:
408+
409+```hoon
410+[%crow nom=@ta] :: group usage
411+```
412+
413+The `gift` you get back is a `%croz` which looks like:
414+
415+```hoon
416+[%croz rus=(map desk [r=regs w=regs])] :: rules for group
417+```
418+
419+...where `regs` is this structure:
420+
421+```hoon
422++$ regs (map path rule) :: rules for paths
423+```
424+
425+[See here for an example of using %crow.](@/docs/arvo/clay/examples.md#crow)
426+
427+# Foreign Ships
428+
429+Here we'll looking at making Clay requests to a foreign ship.
430+
431+As it currently stands, it's not possible to write to a foreign `desk`. Additionally, remote scries are not implemented. That leaves requests to read files (`%warp`) and merge desks (`%merg`), which we'll look at next.
432+
433+## %warp
434+
435+To read files on a foreign `desk`, you just send Clay a `%warp` `task` (as you would for a local read) and specify the target ship in the `wer` field. For details on making such requests, see the [Read and Subscribe](#read-and-subscribe) section.
436+
437+Clay only allows a subset of `care`s to be used remotely. They are:
438+
439+- `%u` - Check for existence of file.
440+- `%v` - Get entire `dome:clay` state of a desk.
441+- `%w` - Get revision number.
442+- `%x` - Get data of file.
443+- `%y` - Get `arch` of file or directory.
444+- `%z` - Get content hash of file or directory.
445+
446+Any other `care` will crash with a `%clay-bad-foreign-request-care` error.
447+
448+The foreign ship will respond only if correct permissions have been set. See the [Permissions](#permissions) section for details.
449+
450+Note that if you're reading a whole `desk` or directory, all subfolders and files must also permit reading. If even a single file does not permit you reading it, the foreign ship will not respond to the request.
451+
452+[See here for examples of requests to foreign ships.](@/docs/arvo/clay/examples.md#foreign-ships)
453+
454+## %merg
455+
456+To merge a foreign `desk` into a local one, you just send Clay a `%merg` `task` (as you would for a local merge) and specify the foreign ship in the `her` field. For details on making such requests, see the [Merge Desks](#merge-desks) section.
457+
458+The foreign ship will respond only if correct permissions have been set. See the [Permissions](#permissions) section for details. By default, a ship's `%kids` desk is set to be publicly readable, so unless permissions have been manually modified, you should be able to merge from any `%kids` `desk`.
459+
460+Note that all subfolders and individual files within the `desk` must permit your reading in order for the merge to succeed. If even one file does not permit you reading it, the remote ship will not respond to the request at all.
461+
462+[See here for examples of requests to foreign ships.](@/docs/arvo/clay/examples.md#foreign-ships)
arvo/clay/write.mddeleted−172
@@ -1,172 +0,0 @@
1−+++
2−title = "Write and Modify"
3−weight = 7
4−template = "doc.html"
5−+++
6−
7−Here we'll look at creating, changing and deleting files by passing Clay an `%info` `task`.
8−
9−## Contents
10−
11−- [Introduction](#introduction)
12−- [Add File](#add-file)
13−- [Delete File](#delete-file)
14−- [Mutate File](#mutate-file)
15−- [Multiple Changes](#multiple-changes)
16−
17−## Introduction
18−
19−An `%info` `task` looks like:
20−
21−```hoon
22−[%info des=desk dit=nori] :: internal edit
23−```
24−
25−While the `desk` part is self-evident, the `nori` part is the following structure:
26−
27−```hoon
28−+$ nori :: repository action
29− $% [%& p=soba] :: delta
30− [%| p=@tas] :: label
31−```
32−
33−The `%|` tag is not currently supported and will crash with a `%labelling-not-implemented` if used, so we can focus on the `%&` part. A `soba` is the following structure:
34−
35−```hoon
36−+$ soba (list [p=path q=miso]) :: delta
37−```
38−
39−This is just a list of changes so you can make more than one change in one request. The `path` is just the path to a file like `/gen/hood/hi/hoon` and the `miso` is the following structure:
40−
41−```hoon
42−+$ miso :: ankh delta
43− $% [%del ~] :: delete
44− [%ins p=cage] :: insert
45− [%dif p=cage] :: mutate from diff
46− [%mut p=cage] :: mutate from raw
47−```
48−
49−- `%del` - Delete a file.
50−- `%ins` - Insert file. This will also replace an existing file.
51−- `%dif` - This has not yet been implemented so will crash with a `%dif-not-implemented` error.
52−- `%mut` - Change a file. At the time of writing this behaves identically to `%ins` so its use merely informs the reader.
53−
54−Clay does not give any response to an `%info` `task` so don't expect a `sign` back.
55−
56−Now we'll look at some example threads:
57−
58−## Add File
59−
60−`add-file.hoon`
61−
62−```hoon
63−/- spider
64−/+ strandio
65−=, strand=strand:spider
66−^- thread:spider
67−|= arg=vase
68−=/ m (strand ,vase)
69−^- form:m
70−=/ uarg !< (unit (pair path @t)) arg
71−?~ uarg
72− (strand-fail:strand %no-arg ~)
73−=/ =path p.u.uarg
74−=/ =wain [q.u.uarg ~]
75−=/ =task:clay [%info %home %& [[path %ins %txt !>(wain)] ~]]
76−=/ =card:agent:gall [%pass /info %arvo %c task]
77−;< ~ bind:m (send-raw-card:strandio card)
78−(pure:m !>(~))
79−```
80−
81−Save it in `/ted/add-file.hoon`, `|commit %home` and run it like:
82−
83−```hoon
84−> -add-file /foo/txt 'foo'
85−+ /~zod/home/22/foo/txt
86−```
87−
88−If you have a look in the home of your pier you'll see there's now a file called `foo.txt` with the text `foo` in it.
89−
90−We've created the `cage` of the content like `[%txt !>(wain)]`, if you want to write something besides a text file you'd just give it the appropriate `mark` and `vase`.
91−
92−Here's a breakdown of the `task` we sent:
93−
94−![write file diagram](https://pub.m.tinnus-napbus.xyz/write-file-diagram.png)
95−
96−## Delete File
97−
98−`delete-file.hoon`
99−
100−```hoon
101−/- spider
102−/+ strandio
103−=, strand=strand:spider
104−^- thread:spider
105−|= arg=vase
106−=/ m (strand ,vase)
107−^- form:m
108−=/ uarg !< (unit path) arg
109−?~ uarg
110− (strand-fail:strand %no-arg ~)
111−=/ =path u.uarg
112−=/ =task:clay [%info %home %& [path %del ~] ~]
113−=/ =card:agent:gall [%pass /info %arvo %c task]
114−;< ~ bind:m (send-raw-card:strandio card)
115−(pure:m !>(~))
116−```
117−
118−Save the above code in `ted/delete-file.hoon`, `|commit %home` and run it like:
119−
120−```hoon
121−> -delete-file /foo/txt
122−- /~zod/home/24/foo/txt
123−```
124−
125−If you have a look in the home of your pier you'll see the `foo.txt` file you created is now gone.
126−
127−Here's a breakdown of the `task` we sent:
128−
129−![delete file diagram](https://pub.m.tinnus-napbus.xyz/delete-file-diagram.png)
130−
131−## Mutate File
132−
133−Identical to the [Add File](#add-file) example, just replace `%ins` with `%mut`.
134−
135−## Multiple Changes
136−
137−Since `soba` is just a `list` of `miso`, you can add a bunch of `miso` and they'll all be applied. This thread adds three files and then deletes them. Here there's only one type of `miso` in each request but you could mix different types together too.
138−
139−`multi-change.hoon`
140−
141−```hoon
142−/- spider
143−/+ strandio
144−=, strand=strand:spider
145−^- thread:spider
146−|= arg=vase
147−=/ m (strand ,vase)
148−^- form:m
149−=/ soba-a :~ [/foo/txt %ins %txt !>(['foo' ~])]
150− [/bar/txt %ins %txt !>(['bar' ~])]
151− [/baz/txt %ins %txt !>(['baz' ~])]
152− ==
153−=/ soba-b :~ [/foo/txt %del ~]
154− [/bar/txt %del ~]
155− [/baz/txt %del ~]
156− ==
157−;< ~ bind:m (send-raw-card:strandio [%pass /info %arvo %c %info %home %& soba-a])
158−;< ~ bind:m (send-raw-card:strandio [%pass /info %arvo %c %info %home %& soba-b])
159−(pure:m !>(~))
160−```
161−
162−Save to `ted/multi-change.hoon`, `|commit %home`, and run:
163−
164−```hoon
165−> -multi-change
166−+ /~zod/home/37/foo/txt
167−+ /~zod/home/37/bar/txt
168−+ /~zod/home/37/baz/txt
169−- /~zod/home/38/foo/txt
170−- /~zod/home/38/bar/txt
171−- /~zod/home/38/baz/txt
172−```