on master help sign in
content: remove docs
commitf53628474cdef2feca9a52245d27aabd0566397d authorMatilde Park <matilde.park@urbit.org> dateTue 28 Jun 2022, 14:38 (4 years ago) parent46297c7
355 files changed−104205
content/docs/_index.md−56 content/docs/arvo/_index.md−53 content/docs/arvo/ames/_index.md−27 content/docs/arvo/ames/ames.md−462 content/docs/arvo/ames/cryptography.md−145 content/docs/arvo/ames/data-types.md−389 content/docs/arvo/ames/scry.md−126 content/docs/arvo/ames/tasks.md−193 content/docs/arvo/behn/_index.md−23 content/docs/arvo/behn/behn.md−19 content/docs/arvo/behn/examples.md−95 content/docs/arvo/behn/scry.md−46 content/docs/arvo/behn/tasks.md−155 content/docs/arvo/clay/_index.md−36 content/docs/arvo/clay/architecture.md−177 content/docs/arvo/clay/clay.md−61 content/docs/arvo/clay/data-types.md−681 content/docs/arvo/clay/examples.md−789 content/docs/arvo/clay/marks/_index.md−23 content/docs/arvo/clay/marks/examples.md−248 content/docs/arvo/clay/marks/marks.md−59 content/docs/arvo/clay/marks/using-marks.md−240 content/docs/arvo/clay/marks/writing-marks.md−333 content/docs/arvo/clay/scry.md−399 content/docs/arvo/clay/tasks.md−503 content/docs/arvo/clay/using.md−223 content/docs/arvo/concepts/_index.md−17 content/docs/arvo/concepts/scry.md−77 content/docs/arvo/concepts/subscriptions.md−162 content/docs/arvo/dill/_index.md−23 content/docs/arvo/dill/data-types.md−187 content/docs/arvo/dill/dill.md−41 content/docs/arvo/dill/scry.md−45 content/docs/arvo/dill/tasks.md−342 content/docs/arvo/eyre/_index.md−31 content/docs/arvo/eyre/data-types.md−289 content/docs/arvo/eyre/external-api-ref.md−359 content/docs/arvo/eyre/eyre.md−61 content/docs/arvo/eyre/guide.md−619 content/docs/arvo/eyre/scry.md−195 content/docs/arvo/eyre/tasks.md−213 content/docs/arvo/ford/_index.md−7 content/docs/arvo/ford/ford.md−223 content/docs/arvo/gall/_index.md−7 content/docs/arvo/gall/data-types.md−492 content/docs/arvo/gall/gall-api.md−958 content/docs/arvo/gall/gall.md−558 content/docs/arvo/iris/_index.md−23 content/docs/arvo/iris/data-types.md−54 content/docs/arvo/iris/example.md−87 content/docs/arvo/iris/iris.md−17 content/docs/arvo/iris/tasks.md−61 content/docs/arvo/jael/_index.md−27 content/docs/arvo/jael/data-types.md−243 content/docs/arvo/jael/examples.md−251 content/docs/arvo/jael/jael.md−25 content/docs/arvo/jael/scry.md−204 content/docs/arvo/jael/tasks.md−225 content/docs/arvo/overview.md−552 content/docs/arvo/reference/_index.md−11 content/docs/arvo/reference/cryptography.md−222 content/docs/arvo/reference/filesystem.md−103 content/docs/arvo/tutorials/_index.md−9 content/docs/arvo/tutorials/move-trace.md−380 content/docs/azimuth/_index.md−41 content/docs/azimuth/advanced-azimuth-tools.md−124 content/docs/azimuth/azimuth-eth.md−157 content/docs/azimuth/azimuth.md−137 content/docs/azimuth/ecliptic.md−446 content/docs/azimuth/flow.md−232 content/docs/azimuth/hd-wallet.md−137 content/docs/azimuth/l2/_index.md−39 content/docs/azimuth/l2/bytestring.md−201 content/docs/azimuth/l2/l2-actions.md−183 content/docs/azimuth/l2/layer2-api.md−14 content/docs/azimuth/l2/layer2.md−403 content/docs/azimuth/l2/roller-tutorial.md−172 content/docs/azimuth/l2/roller.md−66 content/docs/azimuth/life-and-rift.md−60 content/docs/development/_index.md−33 content/docs/development/develop.md−113 content/docs/development/environment.md−331 content/docs/development/grants.md−84 content/docs/development/precepts.md−326 content/docs/development/project-repositories.md−47 content/docs/glossary/_index.md−10 content/docs/glossary/ames.md−21 content/docs/glossary/aqua.md−12 content/docs/glossary/arm.md−14 content/docs/glossary/arvo.md−44 content/docs/glossary/atom.md−20 content/docs/glossary/azimuth.md−39 content/docs/glossary/battery.md−14 content/docs/glossary/behn.md−14 content/docs/glossary/bridge.md−32 content/docs/glossary/censure.md−14 content/docs/glossary/ceremony.md−8 content/docs/glossary/chat.md−32 content/docs/glossary/claims.md−21 content/docs/glossary/clay.md−18 content/docs/glossary/comet.md−32 content/docs/glossary/core.md−14 content/docs/glossary/delegated-sending.md−9 content/docs/glossary/desk.md−15 content/docs/glossary/dill.md−22 content/docs/glossary/docvote.md−9 content/docs/glossary/dojo.md−15 content/docs/glossary/door.md−14 content/docs/glossary/ecliptic.md−12 content/docs/glossary/eventlog.md−23 content/docs/glossary/eyre.md−17 content/docs/glossary/ford.md−17 content/docs/glossary/galaxy.md−15 content/docs/glossary/gall.md−18 content/docs/glossary/gate.md−14 content/docs/glossary/hdwallet.md−18 content/docs/glossary/hoon.md−15 content/docs/glossary/invite-tree.md−9 content/docs/glossary/iris.md−11 content/docs/glossary/jael.md−11 content/docs/glossary/jaque.md−15 content/docs/glossary/keyfile.md−15 content/docs/glossary/landscape.md−11 content/docs/glossary/mark.md−17 content/docs/glossary/moon.md−35 content/docs/glossary/nock.md−17 content/docs/glossary/noun.md−15 content/docs/glossary/ota-updates.md−9 content/docs/glossary/payload.md−14 content/docs/glossary/ph.md−9 content/docs/glossary/pier.md−28 content/docs/glossary/pill.md−14 content/docs/glossary/planet.md−15 content/docs/glossary/proxies.md−34 content/docs/glossary/replay.md−13 content/docs/glossary/reset.md−32 content/docs/glossary/rollups.md−33 content/docs/glossary/sailudon.md−14 content/docs/glossary/senate.md−14 content/docs/glossary/ship.md−26 content/docs/glossary/shiparvonetwork.md−9 content/docs/glossary/star.md−17 content/docs/glossary/sync.md−16 content/docs/glossary/trap.md−14 content/docs/glossary/upgrade.md−13 content/docs/glossary/vane.md−24 content/docs/glossary/vere.md−18 content/docs/glossary/voting.md−27 content/docs/glossary/wallet-generator.md−11 content/docs/hoon/_index.md−27 content/docs/hoon/guides/_index.md−21 content/docs/hoon/guides/aqua.md−80 content/docs/hoon/guides/cli-tutorial.md−440 content/docs/hoon/guides/json-guide.md−513 content/docs/hoon/guides/parsing.md−709 content/docs/hoon/guides/sail.md−566 content/docs/hoon/guides/strings.md−531 content/docs/hoon/guides/unit-tests.md−115 content/docs/hoon/hoon-school/_index.md−37 content/docs/hoon/hoon-school/ackermann.md−29 content/docs/hoon/hoon-school/arms-and-cores.md−652 content/docs/hoon/hoon-school/atoms-auras-and-simple-cell-types.md−779 content/docs/hoon/hoon-school/bank-account.md−80 content/docs/hoon/hoon-school/behn.md−110 content/docs/hoon/hoon-school/caesar.md−394 content/docs/hoon/hoon-school/conditionals.md−105 content/docs/hoon/hoon-school/doors.md−518 content/docs/hoon/hoon-school/egg-timer.md−164 content/docs/hoon/hoon-school/fibonacci.md−61 content/docs/hoon/hoon-school/gall.md−129 content/docs/hoon/hoon-school/gates.md−272 content/docs/hoon/hoon-school/generators.md−460 content/docs/hoon/hoon-school/hoon-syntax.md−356 content/docs/hoon/hoon-school/intro.md−121 content/docs/hoon/hoon-school/iron-polymorphism.md−88 content/docs/hoon/hoon-school/lead-polymorphism.md−155 content/docs/hoon/hoon-school/libraries.md−191 content/docs/hoon/hoon-school/list-of-numbers.md−138 content/docs/hoon/hoon-school/lists.md−497 content/docs/hoon/hoon-school/molds.md−98 content/docs/hoon/hoon-school/nouns.md−563 content/docs/hoon/hoon-school/recursion.md−194 content/docs/hoon/hoon-school/structures-and-complex-types.md−356 content/docs/hoon/hoon-school/the-subject-and-its-legs.md−726 content/docs/hoon/hoon-school/trees-sets-and-maps.md−321 content/docs/hoon/hoon-school/type-checking-and-type-inference.md−643 content/docs/hoon/hoon-school/type-polymorphism.md−584 content/docs/hoon/overview.md−274 content/docs/hoon/reference/_index.md−53 content/docs/hoon/reference/advanced.md−206 content/docs/hoon/reference/auras.md−107 content/docs/hoon/reference/basic.md−177 content/docs/hoon/reference/cheat-sheet.md−18 content/docs/hoon/reference/hoon-errors.md−187 content/docs/hoon/reference/irregular.md−332 content/docs/hoon/reference/limbs/_index.md−18 content/docs/hoon/reference/limbs/limb.md−71 content/docs/hoon/reference/limbs/wing.md−44 content/docs/hoon/reference/rune/_index.md−78 content/docs/hoon/reference/rune/bar.md−1030 content/docs/hoon/reference/rune/buc.md−1046 content/docs/hoon/reference/rune/cen.md−744 content/docs/hoon/reference/rune/col.md−461 content/docs/hoon/reference/rune/constants.md−212 content/docs/hoon/reference/rune/dot.md−394 content/docs/hoon/reference/rune/fas.md−257 content/docs/hoon/reference/rune/ket.md−720 content/docs/hoon/reference/rune/lus.md−332 content/docs/hoon/reference/rune/mic.md−730 content/docs/hoon/reference/rune/sig.md−887 content/docs/hoon/reference/rune/terminators.md−89 content/docs/hoon/reference/rune/tis.md−1055 content/docs/hoon/reference/rune/wut.md−1058 content/docs/hoon/reference/rune/zap.md−642 content/docs/hoon/reference/stdlib/1a.md−799 content/docs/hoon/reference/stdlib/1b.md−309 content/docs/hoon/reference/stdlib/1c.md−538 content/docs/hoon/reference/stdlib/2a.md−616 content/docs/hoon/reference/stdlib/2b.md−1649 content/docs/hoon/reference/stdlib/2c.md−1518 content/docs/hoon/reference/stdlib/2d.md−374 content/docs/hoon/reference/stdlib/2e.md−188 content/docs/hoon/reference/stdlib/2f.md−315 content/docs/hoon/reference/stdlib/2g.md−105 content/docs/hoon/reference/stdlib/2h.md−826 content/docs/hoon/reference/stdlib/2i.md−1418 content/docs/hoon/reference/stdlib/2j.md−397 content/docs/hoon/reference/stdlib/2k.md−456 content/docs/hoon/reference/stdlib/2l.md−110 content/docs/hoon/reference/stdlib/2m.md−316 content/docs/hoon/reference/stdlib/2n.md−458 content/docs/hoon/reference/stdlib/2o.md−200 content/docs/hoon/reference/stdlib/2p.md−248 content/docs/hoon/reference/stdlib/2q.md−586 content/docs/hoon/reference/stdlib/3a.md−882 content/docs/hoon/reference/stdlib/3b.md−6054 content/docs/hoon/reference/stdlib/3c.md−664 content/docs/hoon/reference/stdlib/3d.md−820 content/docs/hoon/reference/stdlib/3e.md−8 content/docs/hoon/reference/stdlib/3f.md−868 content/docs/hoon/reference/stdlib/3g.md−355 content/docs/hoon/reference/stdlib/4a.md−424 content/docs/hoon/reference/stdlib/4b.md−1320 content/docs/hoon/reference/stdlib/4c.md−396 content/docs/hoon/reference/stdlib/4d.md−100 content/docs/hoon/reference/stdlib/4e.md−466 content/docs/hoon/reference/stdlib/4f.md−1380 content/docs/hoon/reference/stdlib/4g.md−229 content/docs/hoon/reference/stdlib/4h.md−703 content/docs/hoon/reference/stdlib/4i.md−1086 content/docs/hoon/reference/stdlib/4j.md−1796 content/docs/hoon/reference/stdlib/4k.md−841 content/docs/hoon/reference/stdlib/4l.md−618 content/docs/hoon/reference/stdlib/4m.md−486 content/docs/hoon/reference/stdlib/4n.md−723 content/docs/hoon/reference/stdlib/4o.md−1473 content/docs/hoon/reference/stdlib/5a.md−504 content/docs/hoon/reference/stdlib/5b.md−87 content/docs/hoon/reference/stdlib/5c.md−925 content/docs/hoon/reference/stdlib/5d.md−323 content/docs/hoon/reference/stdlib/5e.md−332 content/docs/hoon/reference/stdlib/5f.md−194 content/docs/hoon/reference/stdlib/_index.md−2065 content/docs/hoon/reference/stdlib/table-of-contents.md−2064 content/docs/hoon/reference/style.md−476 content/docs/hoon/reference/zuse/2d_1-5.md−587 content/docs/hoon/reference/zuse/2d_6.md−1551 content/docs/hoon/reference/zuse/2d_7.md−1307 content/docs/hoon/reference/zuse/2e_2-3.md−67 content/docs/hoon/reference/zuse/_index.md−31 content/docs/hoon/reference/zuse/table-of-contents.md−247 content/docs/nock/_index.md−27 content/docs/nock/definition.md−186 content/docs/nock/example.md−362 content/docs/nock/explanation.md−605 content/docs/nock/implementations.md−2879 content/docs/system-overview/_index.md−77 content/docs/system-overview/arvo.md−32 content/docs/system-overview/azimuth.md−34 content/docs/system-overview/cryptography.md−124 content/docs/system-overview/hoon.md−28 content/docs/system-overview/nock.md−34 content/docs/system-overview/vere.md−45 content/docs/userspace/_index.md−33 content/docs/userspace/dist/_index.md−29 content/docs/userspace/dist/dist.md−105 content/docs/userspace/dist/docket.md−296 content/docs/userspace/dist/glob.md−102 content/docs/userspace/dist/guide.md−282 content/docs/userspace/dist/tools.md−342 content/docs/userspace/full-stack/1-intro.md−89 content/docs/userspace/full-stack/10-final.md−118 content/docs/userspace/full-stack/2-types.md−215 content/docs/userspace/full-stack/3-agent.md−338 content/docs/userspace/full-stack/4-json.md−357 content/docs/userspace/full-stack/5-marks.md−97 content/docs/userspace/full-stack/6-eyre.md−79 content/docs/userspace/full-stack/7-react-setup.md−214 content/docs/userspace/full-stack/8-app-logic.md−406 content/docs/userspace/full-stack/9-desk.md−226 content/docs/userspace/full-stack/_index.md−52 content/docs/userspace/gall-guide/1-arvo.md−305 content/docs/userspace/gall-guide/10-scry.md−363 content/docs/userspace/gall-guide/11-fail.md−146 content/docs/userspace/gall-guide/12-next-steps.md−50 content/docs/userspace/gall-guide/2-agent.md−305 content/docs/userspace/gall-guide/3-imports-and-aliases.md−285 content/docs/userspace/gall-guide/4-lifecycle.md−499 content/docs/userspace/gall-guide/5-cards.md−244 content/docs/userspace/gall-guide/6-pokes.md−538 content/docs/userspace/gall-guide/7-sur-and-marks.md−408 content/docs/userspace/gall-guide/8-subscriptions.md−911 content/docs/userspace/gall-guide/9-vanes.md−284 content/docs/userspace/gall-guide/_index.md−45 content/docs/userspace/gall-guide/intro.md−83 content/docs/userspace/gall-guide/types.md−228 content/docs/userspace/graph-store/_index.md−23 content/docs/userspace/graph-store/advanced-info.md−64 content/docs/userspace/graph-store/data-structure-overview.md−350 content/docs/userspace/graph-store/graph-store-reference.md−244 content/docs/userspace/graph-store/overview.md−103 content/docs/userspace/graph-store/sample-application-overview.md−369 content/docs/userspace/graph-store/validator-walkthrough.md−476 content/docs/userspace/http-api-guide.md−698 content/docs/userspace/overview.md−24 content/docs/userspace/threads/_index.md−27 content/docs/userspace/threads/basics/_index.md−29 content/docs/userspace/threads/basics/bind.md−97 content/docs/userspace/threads/basics/fundamentals.md−168 content/docs/userspace/threads/basics/input.md−145 content/docs/userspace/threads/basics/output.md−119 content/docs/userspace/threads/basics/summary.md−81 content/docs/userspace/threads/examples/_index.md−33 content/docs/userspace/threads/examples/child-thread.md−241 content/docs/userspace/threads/examples/get-json.md−114 content/docs/userspace/threads/examples/main-loop.md−178 content/docs/userspace/threads/examples/poke-agent.md−60 content/docs/userspace/threads/examples/scry.md−70 content/docs/userspace/threads/examples/take-fact.md−65 content/docs/userspace/threads/gall/_index.md−29 content/docs/userspace/threads/gall/poke-thread.md−115 content/docs/userspace/threads/gall/start-thread.md−145 content/docs/userspace/threads/gall/stop-thread.md−152 content/docs/userspace/threads/gall/take-facts.md−184 content/docs/userspace/threads/gall/take-result.md−132 content/docs/userspace/threads/http-api.md−73 content/docs/userspace/threads/overview.md−82 content/docs/userspace/threads/reference.md−87 content/docs/vere/_index.md−42 content/docs/vere/api.md−1040 content/docs/vere/c.md−114 content/docs/vere/cryptography.md−43 content/docs/vere/jetting.md−779 content/docs/vere/nouns.md−477 content/docs/vere/runtime.md−44
content/docs/_index.mddeleted−56
@@ -1,56 +0,0 @@
1−+++
2−title = "Development Docs"
3−weight = 1
4−template = "sections/docs.html"
5−+++
6−
7−Welcome to the developer documentation for the Urbit project. This documentation
8−is maintained by [Tlon](https://tlon.io) and the Urbit community in a public
9−[Github repository](https://github.com/urbit/urbit.org/tree/master/content/docs). Issues and contributions are
10−welcome.
11−
12−This documentation provides a series of explainers, guides, tutorials and
13−reference material for assisting you in developing on the Urbit platform, or
14−contributing to the Urbit project. If you're looking for documentation on how to
15−_use_ your Urbit ship, see our [usage docs](/using/).
16−
17−### [Development](/docs/development/)
18−
19−The Development section is recommended reading for developers interested in
20−contributing to Urbit itself, or building apps on top of Urbit. It serves as a
21−high-level orientation to how to set up a development environment, the various
22−codebases the project comprises, our grants program, and the precepts that
23−drive the development of Urbit.
24−
25−### [System Overview](/docs/system-overview/)
26−
27−This section gives a high-level overview to all the major components of the
28−Urbit tech stack - namely, the operating system Arvo, the programming languages
29−Nock and Hoon, the runtime Vere, and the decentralized ID system Azimuth.
30−
31−### [Arvo (Urbit OS)](/docs/arvo/)
32−
33−This section covers the kernel of Urbit OS, called Arvo, as well as its kernel modules.
34−
35−### [Hoon (High-level Language)](/docs/hoon/)
36−
37−Here is contained all official documentation on Hoon, the high-level purely
38−functional programming language in which Arvo and much of userspace is written.
39−
40−### [Nock (Low-level Language)](/docs/nock/)
41−
42−Official guidance on Nock, the functional assembly-level language which serves
43−as the basis for Hoon.
44−
45−### [Vere (Interpreter)](/docs/vere/)
46−
47−Documentation on Vere, the Nock virtual machine which serves as the interface
48−between Urbit and Unix.
49−
50−### [Azimuth (Urbit ID)](/docs/azimuth/)
51−
52−The workings of Azimuth, the decentralized ID system utilized by Urbit.
53−
54−### [Userspace](/docs/userspace/)
55−
56−Developer guides for Gall (the vane for controlling userspace apps), Landscape (the web client by which most users interact with their ship), and Threads (transient apps for IO).
content/docs/arvo/_index.mddeleted−53
@@ -1,53 +0,0 @@
1−+++
2−title = "Arvo"
3−weight = 300
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−aliases = ["/docs/learn/arvo/"]
7−+++
8−
9−Resources about the Urbit OS.
10−
11−## [Overview](/docs/arvo/overview)
12−
13−Arvo is Urbit's functional operating system, written in [Hoon](/docs/hoon/hoon-school/). It's composed of modules called _vanes_, each of which has its own folder:
14−
15−## [Ames](/docs/arvo/ames/ames)
16−
17−Ames is the name of our network and the vane that communicates over it. It's an encrypted P2P network composed of instances of the Arvo operating system.
18−
19−## [Behn](/docs/arvo/behn/behn)
20−
21−Behn is our timer. It allows vanes and applications to set and timer events, which are managed in a simple priority queue.
22−
23−## [Clay](/docs/arvo/clay/clay)
24−
25−Clay is our filesystem and revision-control system.
26−
27−## [Dill](/docs/arvo/dill/dill)
28−
29−Dill is our terminal driver. Unix sends keyboard events to dill from the terminal, and dill produces terminal output.
30−
31−## [Eyre](/docs/arvo/eyre/eyre)
32−
33−Eyre is our HTTP server. Unix sends HTTP messages to `%eyre`, and `%eyre` produces HTTP messages in response.
34−
35−## [Ford](/docs/arvo/ford/ford)
36−
37−Ford is our build system. It handles resources and publishing.
38−
39−## [Gall](/docs/arvo/gall/gall)
40−
41−Gall is the vane for controlling userspace apps.
42−
43−## [Iris](/docs/arvo/iris/iris)
44−
45−Iris is our HTTP client.
46−
47−## [Concepts](/docs/arvo/concepts/)
48−
49−Explanations of design decisions that are pervasive throughout Arvo.
50−
51−## [Tutorials](/docs/arvo/tutorials/)
52−
53−Walkthroughs that teach you more about how Arvo works.
content/docs/arvo/ames/_index.mddeleted−27
@@ -1,27 +0,0 @@
1−+++
2−title = "Ames"
3−weight = 10
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−insert_anchor_links = "right"
7−+++
8−
9−## [Overview](/docs/arvo/ames/ames)
10−
11−An overview of Ames and its capabilities.
12−
13−## [Cryptography](/docs/arvo/ames/cryptography)
14−
15−A technical overview of how Ames implements cryptography.
16−
17−## [API Reference](/docs/arvo/ames/tasks)
18−
19−The `task`s Ames takes and the `gift`s it returns.
20−
21−## [Scry Reference](/docs/arvo/ames/scry)
22−
23−The scry endpoints of Ames.
24−
25−## [Data Types](/docs/arvo/ames/data-types)
26−
27−Reference documentation of the various data types used by Ames.
content/docs/arvo/ames/ames.mddeleted−462
@@ -1,462 +0,0 @@
1−+++
2−title = "Overview"
3−weight = 1
4−template = "doc.html"
5−aliases = ["/docs/learn/arvo/ames/"]
6−+++
7−
8−Our networking protocol.
9−
10−Ames is the name of both our network and the vane that communicates
11−over it. When Unix receives a packet over the correct UDP port, it pipes
12−it straight into Ames for handling. Also, all packets sent over the
13−Ames network are sent by the Ames vane. Apps and vanes may use
14−Ames to directly send messages to other ships. In general, apps use
15−[Gall](/docs/arvo/gall/gall) and [Clay](/docs/arvo/clay/clay)
16−to communicate with other ships rather than using Ames
17−directly, but this isn't a requirement. Of course, Gall and Clay use
18−Ames behind the scenes to communicate across the network. Jael is the only other
19−vane to utilize Ames.
20−
21−Ames includes several significant components. Although the actual
22−crypto algorithms are defined in `zuse`, they're used extensively in
23−Ames for encrypting and decrypting packets. Congestion control and
24−routing is handled entirely in Ames. Finally, the actual Ames
25−protocol itself, including how to route incoming packets to the correct
26−vane or app, is defined in Ames.
27−
28−## Technical Overview
29−
30−This section summarizes the design of Ames. Beyond this section are deeper
31−elaborations on the concepts presented here.
32−
33−Ames extends [Arvo's](/docs/arvo/overview) `%pass`/`%give` `move` semantics across the network.
34−
35−Ames receives packets as Arvo events and emits packets as Arvo
36−effects. The runtime is responsible for transferring the bytes in
37−an Ames packet across a physical network to another ship.
38−
39−The runtime tells Ames which physical address a packet came from,
40−represented as an opaque atom. Ames can emit a packet effect to
41−one of those opaque atoms or to the Urbit address of a galaxy
42−(root node), which the runtime is responsible for translating to a
43−physical address. One runtime implementation sends UDP packets
44−using IPv4 addresses for ships and DNS lookups for galaxies, but
45−other implementations may overlay over other kinds of networks.
46−
47−A local vane can pass Ames a `%plea` request message. Ames
48−transmits the message over the wire to the peer ship's Ames, which
49−passes the message to the destination vane.
50−
51−Once the peer has processed the `%plea` message, it sends a
52−message-acknowledgment packet over the wire back to the local
53−Ames. This "ack" can either be positive to indicate the request was
54−processed, or negative to indicate the request failed, in which
55−case it's called a "nack". (Don't confuse Ames nacks with TCP
56−nacks, which are a different concept).
57−
58−When the local Ames receives either a positive message-ack or a
59−combination of a nack and "naxplanation" (explained in more detail
60−below), it gives an `%done` `move` to the local vane that had
61−requested the original `%plea` message be sent.
62−
63−A local vane can give Ames zero or more `%boon` response messages in
64−response to a `%plea`, on the same duct that Ames used to pass the
65−`%plea` to the vane. Ames transmits a `%boon` over the wire to the
66−peer's Ames, which gives it to the destination vane on the same
67−duct the vane had used to pass the original `%plea` to Ames.
68−
69−`%boon` messages are acked automatically by the receiver Ames. They
70−cannot be nacked, and Ames only uses the ack internally, without
71−notifying the client vane that gave Ames the `%boon`.
72−
73−If the Arvo event that completed receipt of a `%boon` message
74−crashes, Ames instead sends the client vane a `%lost` message
75−indicating the `%boon` was missed.
76−
77−`%plea` messages can be nacked, in which case the peer will send
78−both a message-nack packet and a naxplanation message, which is
79−sent in a way that does not interfere with normal operation. The
80−naxplanation is sent as a full Ames message, instead of just a
81−packet, because the contained error information can be arbitrarily
82−large. A naxplanation can only give rise to a positive ack --
83−never ack an ack, and never nack a naxplanation.
84−
85−Ames guarantees a total ordering of messages within a "flow",
86−identified in other vanes by a duct and over the wire by a `bone`:
87−an opaque number. Each flow has a FIFO (first-in-first-out) queue of `%plea` requests
88−from the requesting ship to the responding ship and a FIFO queue
89−of `%boon`'s in the other direction.
90−
91−Message order across flows is not specified and may vary based on
92−network conditions.
93−
94−Ames guarantees that a message will only be delivered once to the
95−destination vane.
96−
97−Ames encrypts every message using symmetric-key encryption by
98−performing an elliptic curve Diffie-Hellman using our private key
99−and the public key of the peer. For ships in the Jael PKI
100−(public-key infrastructure), Ames looks up the peer's public key
101−from Jael. Comets (128-bit ephemeral addresses) are not
102−cryptographic assets and must self-attest over Ames by sending a
103−single self-signed packet containing their public key.
104−
105−When a peer suffers a continuity breach, Ames removes all
106−messaging state related to it. Ames does not guarantee that all
107−messages will be fully delivered to the now-stale peer. From
108−Ames's perspective, the newly restarted peer is a new ship.
109−Ames's guarantees are not maintained across a breach.
110−
111−A vane can pass Ames a `%heed` `$task` to request Ames track a peer's
112−responsiveness. If our `%boon`'s to it start backing up locally,
113−Ames will give a `%clog` back to the requesting vane containing the
114−unresponsive peer's urbit address. This interaction does not use
115−ducts as unique keys. Stop tracking a peer by sending Ames a
116−`%jilt` `$task`.
117−
118−Debug output can be adjusted using `%sift` and `%spew` `$task`'s.
119−
120−## Packets
121−
122−Ames datagram packets are handled as nouns internally by Arvo but as serial data
123−by Unix. In this section we describe how packets are formed, serialized, and relayed.
124−
125−### Packet format
126−
127−There is a 32-bit header followed by a variable width body.
128−
129−#### Header
130−
131−The 32-bit header is given by the following data, presented in order:
132−
133−- 3 bits: reserved
134−- 1 bit: is this Ames? (i.e. not using a different protocol, such as the
135− planned remote scry protocol)
136−- 3 bits: Ames protocol version (currently 0)
137−- 2 bits: sender address size
138−- 2 bits: receiver address size
139−- 20 bits: checksum (truncated insecure hash of the body, done with
140− [`+mug`](/docs/hoon/reference/stdlib/2e#mug)
141−- 1 bit: is this relayed? (if set, `origin` will be present in the body)
142−
143−Every packet sent between ships is encrypted except for self-signed attestation packets from 128-bit comets.
144−
145−#### Body
146−
147−The body is of variable length and consists of the following parts in this
148−order:
149−
150−- 4 bits: sender life (mod 16)
151−- 4 bits: receiver life (mod 16)
152−- variable: sender address
153−- variable: receiver address
154−- 48 bits: (optional) 48-bit `origin`
155−- 128 bits: `SIV`
156−- 16 bits: ciphertext size
157−- variable: ciphertext
158−
159−`origin` is the IP and port of the original sender if the packet was proxied
160−through a relay.
161−
162−`SIV` is a "synthetic initialization vector" as defined in AES-256 SIV, the encryption
163−algorithm utilized to encrypt Ames packets (see the page on [Ames
164−cryptography](/docs/arvo/ames/cryptography)). It is formed from the
165−following noun: `~[sender=@p receiver=@p sender-life=@ receiver-life=@]` (see
166−[Life and Rift](/docs/azimuth/life-and-rift) for information on what `life`
167−is). As this data is in Azimuth, it is not explicitly sent over the wire. Thus
168−the mod 16 sender and receiver life in the first 8 bits are only for quick
169−filtering of honest packets sent to or from a stale life.
170−
171−The ciphertext is formed by `+jam`ming a `$shut-packet` and then encrypting
172−using [`+en:sivc:aes:crypto`](/docs/arvo/reference/cryptography#en).
173−
174−### Packeting
175−
176−When Ames has a message to be sent it must first determine how many packets are
177−required to send the message. To do this, it first `+jam`s the
178−message, producing an atom. Ames checks how large the atom is, and if it is
179−bigger than a kilobyte it will split it into packets whose payloads are 1 kB or
180−less. It then numbers each one - this is message 17, packet 12, this is message
181−17, packet 13, etc., so that when the receiver receives these packets it knows
182−which number they are. Finally it encrypts each individual packet and enqueues
183−them to be sent along their stated flow.
184−
185−Network packets aren't always received in order, so this numbering is important
186−for reconstruction, and also packets may get lost. So Ames does transmission
187−control (the TC in TCP) to solve this problem. It makes sure that all packets
188−eventually get through, and when the other side gets them it can put them in the
189−correct order. If Ames doesn't get an ack on a packet then it will resend it
190−until it does. The logic for determining how many packets to send or re-send at what time is performed by an Ames-specific variant of TCP's "NewReno" congestion control algorithm.
191−
192−As each packet in a message is received, Ames decrypts it and stores the message fragment. Once it's received every packet for a message, Ames concatenates the fragments back into a single large atom and uses `+cue` to deserialize that back into the original message noun.
193−
194−### Acks and Nacks
195−
196−In this section we discuss acks and nacks. In Ames, an "ack", short for "acknowledgment", is a small packet attesting that a piece of information (either a packet or a whole message) was received. Ames makes use of
197−acks to maintain synchronization between two communicating parties. Nacks are 'negative
198−acknowledgments' and are used when something goes wrong.
199−
200−#### Acks
201−
202−Every message (i.e. a `%plea` or `%boon`) is split up by Ames into some number
203−of _fragments_ that are 1kB in size or less. The fragments are then encrypted
204−and encapsulated into
205−packets and sent along a flow. The message will be considered successfully
206−received once the sender has received the appropriate set of acks in response,
207−defined as follows.
208−
209−There are two types of acks: fragment acks and message acks. Acks are
210−not considered messages, and thus are not `%plea`s or `%boon`s. Given a message split into N
211−fragments, the sender of the message will expect N-1 fragment acks followed
212−by exactly one message ack (ignoring any duplicate packets, which are idempotent
213−from the perspective of the application). This is because the receiver
214−will send a fragment ack for the first N-1 packets it received, and what
215−would have been the final fragment ack will instead be a message ack.
216−
217−Acks are considered to be part of the flow in which that `%plea` or
218−`%boon` lives, as the packets containing their fragments and packets acking the
219−receipt of those packets are considered to be what makes up a given message.
220−Thus a message-level ack must be received before the next message on the flow
221−can begin. The full story is more complicated than this; see the section on
222−[flows](#flows).
223−
224−#### Nacks {% #nacks %}
225−
226−A nack indicates a negative acknowledgement to a `%plea`, meaning that the
227−requested action was not performed.
228−
229−`%boon`s and naxplanations are never nacked.
230−Individual packets are also never nacked, only complete `%plea` messages are.
231−Whether a malformed packet causes a `%plea` to be nacked depends on its content.
232−In the case of an incorrect checksum or a failure to decrypt then Ames drops the
233−packet and it is as though it never happened. However, if the packet does
234−decrypt and has invalid ciphertext (i.e. something other than a jammed
235−`$shutpacket` data structure), then Ames will nack the whole `%plea` since that
236−indicates that the peer is misbehaving. Eventually Ames should also present a
237−warning to the user that the peer is untrustworthy.
238−
239−A nack will be accompanied by a naxplanation, which is a special type of`%boon`
240−that uses its own `bone` (see [flows](#flows)). Ames won't give the vane that requested the
241−initial `%plea` a nack until it also receives the naxplanation, which it will send to
242−the vane as a `%done` gift. Naxplanations may only be acked, never nacked.
243−Furthermore, naxplanations can only ever be sent as a rejection of a `%plea` -
244−the receiver will never both perform a `%plea` and return a naxplanation.
245−
246−#### (N)ack packets
247−
248−A fragment ack's contents (before encryption) are a pure function of the
249−following noun:
250−
251−```hoon
252−[our-life her-life bone message-num fragment-num]
253−```
254−
255−This means all re-sends of an ack packet will be bitwise identical to each other, unless one of the peers changes its encryption keys.
256−
257−Each datum in this noun is an atom with the aura `@ud` or an aura that nests
258−under `@ud`.
259−
260−Here, `our-life` refers to the [`life`](/docs/glossary/breach), or revision
261−number, of the acking ship's networking keys, and `her-life` is the `life` of
262−the ack-receiving ship's networking keys. `bone` is an opaque number identifying
263−the flow. `message-num` denotes the number of the
264−message in the flow identified by `bone`. `fragment-num` denotes the number of
265−the fragment of the message identified by `message-num` that is being acked.
266−
267−A message (n)ack is a different kind of ack that is obtained by encrypting the
268−`+jam` of the following noun:
269−
270−```hoon
271−[our-life her-life bone message-num ok=? lag=@dr]
272−```
273−
274−`ok` is a flag that is set to `%.y` for a message ack and `%.n` for a message
275−nack. In the future, `lag` will be used to
276−describe the time it took to process a message, but for now it is always zero.
277−
278−### Flows
279−
280−Flows are asymmetric communication channels along which two ships send and
281−receive packets, and all Ames packets are part of some flow.
282−
283−To create a new flow, a ship sends a
284−`%plea` to another ship. Only the creator of the flow may send `%plea`s, and the
285−other party may only send `%boon`s. In this sense flows are asymmetric.
286−
287−The sequence of `%plea`s in a flow is totally ordered, though
288−the packets which make them up need not be. `%boon`s are totally ordered in the
289−same fashion, but there is not a coordinated ordering between `%plea`s and
290−`%boon`s in a given flow beyond the implicit one arising from the fact that a
291−`%boon` is always a response to a `%plea`. A `%plea` can give rise to zero, one,
292−or many `%boon`s.
293−
294−Inside of Ames, each flow has four sequential opaque `@ud`s
295−called bones that are unique to that flow. Thus the flow itself is often
296−referred to by its first bone. Each bone is a one-way street
297−for packets to travel along, so e.g. acks to packets making up a `%plea` are
298−sent along a different bone than the `%plea`.
299−
300−We give an example of such a partition. Let flow 12 be a flow between `~bacbel-tagfeg` and `~worwel-sipnum` with
301−`~bacbel-tagfeg` as the `%plea` sender. Then bones 12-15 are associated with the
302−flow, and the types of packets for each bone are:
303−
304−- bone 12, `%plea`s and acks to `~worwel-sipnum`,
305−- bone 13, `%boon`s and (n)acks to `~bacbel-tagfeg`,
306−- bone 14, acks of naxplanations to `~worwel-sipnum`,
307−- bone 15, naxplanations to `~bacbel-tagfeg`.
308−
309−Each bone is handled separately by congestion control, and this is one reason
310−for their segregation. For example, say a two-packet `%plea` is sent on bone 12,
311−with `~bacbel-tagfeg` requesting to join a group on `~worwel-sipnum`.
312−Then `~worwel-sipnum` can ack the first packet on bone 13, and then send a nack
313−on bone 13 as well. A nack by itself contains no information as to why the nack
314−happened. Then `~worwel-sipnum` can also send a naxplanation on bone 15 saying
315−to `~bacbel-tagfeg` that they cannot join the group, to which an ack is received
316−on bone 14.
317−
318−Another reason to separate bones is to avoid race conditions. If
319−`~worwel-sipnum` and `~bacbel-tagfeg` attempt to start a flow with each other at
320−the same time we do not wish there to be a conflict when they receive each
321−others' packets. Flipping the last bit of the bone based on whether a packet is
322−an ack or a message fragment allows for `~worwel-sipnum` to create flow 8 with
323−`~bacbel-tagfeg` without coming into conflict with the flow 8 `~bacbel-tagfeg`
324−created for `~worwel-sipnum`.
325−
326−`%plea`s and `%boon`s are handled on separate bones so that e.g. sending a large
327−`%boon` doesn't stop an additional `%plea` from being received. It is also
328−simply cleaner to make each bone one-way. Acks and nacks are very small packets
329−as well as integral to controlling the total orderings on `%plea`s and `%boon`s
330−and so they are included on these bones as well.
331−
332−Naxplanations can potentially be very large, as they often contain things like stack
333−traces or other crash reports. Thus it is undesirable to have them share a bone
334−with `%boon`s and create congestion there. So naxplanations have their own bone,
335−and so do acks to packets that make up a naxplanation, as well as the
336−message-level naxplanation ack.
337−
338−### Packet relaying and peer discovery
339−
340−Here we describes how the Ames network relays packets and does peer discovery.
341−We ignore all details about UDP, which occurs at a lower layer than Ames.
342−
343−When a ship first contacts another ship, it may only know its `@p`, but an IP
344−address and port are necessary for peer-to-peer communication to occur.
345−Thus the initial correspondence between two ships, or additional correspondence
346−following a change in IP or port of one of the parties, will need to be relayed
347−by an intermediary that knows the IP and port of the receiving ship.
348−
349−For now, peer discovery is handled entirely by galaxies. Every galaxy is
350−responsible for knowing the IP and port of every planet underneath it. In the
351−future, galaxies will only need to know the IP and port of the star sponsoring a
352−planet, and stars will be responsible for knowing the IP and port of their sponsored planets.
353−
354−Galaxies are also utilized for packet relaying in the case where two ships
355−cannot communicate directly with one another, as is often the case when one or
356−both are behind a
357−[NAT](https://en.wikipedia.org/wiki/Network_address_translation) or certain
358−firewalls. We remark that packet relaying is a necessary component of peer
359−discovery. Thus stars will also assist with packet relaying in the future.
360−
361−In the case of a moon, its parent ship is responsible for packet relaying and peer
362−discovery, analagous to the role that galaxies currently play for stars and planets.
363−
364−The following diagram summarizes the packet creation and forwarding process.
365−
366−![](https://media.urbit.org/docs/arvo/datagram-updated-2021-06-09.png)
367−
368−We elaborate on the above diagram.
369−
370−A typical relay will look something like this: `~bacbel-tagfeb` wishes to
371−contact `~worwel-sipnum` but does not know the IP address and port at which
372−`~worwel-sipnum` resides. Both planets are sponsored by a star sponsored by
373−`~zod`, which knows both of their IP addresses and port numbers by virtue of
374−being the galaxy that both live under.
375−
376−To prepare, `~bacbel-tagfeb` forms a Diffie-Hellman symmetric key with their own
377−private key and the public key of `~worwel-sipnum`, obtained via Jael. Then
378−`~bacbel-tagfeb` sends a packet addressed to `~worwel-sipnum` to `~zod`.
379−
380−The packet has the following format:
381−
382−- The standard Ames header described in [header](#header), where the checksum
383− is the `+mug` of the body, and the sender and receiver ship types are `01`,
384− denoting that the sender and receiver are planets. The "is this relayed?" bit
385− is set to 0 since this is the first hop on the packet route.
386−- The body of this packet will be the life of `~bacbel-tagfeg` mod 16, followed
387− by the life of `~worwel-sipnum` mod 16, followed by `~bacbel-tagfeg`,
388− followed by the receiver `~worwel-sipnum`, followed by the origin `~`
389− (denoting that the ship sending the packet is the origin). After this comes
390− the payload.
391−- The payload of this packet will be the `+jam` of the `content`, which is an encrypted fragment of the message `%watch /path/to/recipes`.
392−
393−`~zod` receives the packet and reads the body. It sees that it is not the
394−intended recipient of the packet, and so gets ready to forward it to
395−`~worwel-sipnum`. First, it replaces the origin field with the IP and port of
396−`~bacbel-tagfeb`, then computes the `+mug` of the body and replaces the checksum
397−with the new mug. Since the packet is being relayed, `~zod` flips the "is it
398−relayed?" bit to `%.y`. `~zod` then forwards the packet to `~worwel-sipnum`.
399−
400−In order to decrypt the packet, `~worwel-sipnum` will need to calculate the
401−associated data vector utilized by SIV, which consists of `~[sender=@p receiver=@p sender-life=@ receiver-life=@]`. It then passes that along with the
402−SIV and ciphertext to the decryption function, and receives the unencrypted
403−packet as a return.
404−
405−Once `~worwel-sipnum` processes the packet, it will know the IP and port of
406−`~bacbel-tagfeb` since `~zod` included it when it forwarded the packet. Thus
407−`~worwel-sipnum` will send an ack packet directly to `~bacbel-tagfeb`, unless a
408−NAT and/or firewall prevents a direct peer-to-peer connection, in which case
409−`~zod` will continue to relay packets. Absent these factors preventing a
410−peer-to-peer connection, communication between the two ships will now be direct
411−until one of them changes their IP address, port, or networking keys.
412−
413−In this scenario, of course, the message is so short that a single packet would
414−be sufficient to send the message, so the `+cue` of the payload would contain
415−the complete message `%watch /path/to/recipes`. At this point, `~worwel-sipnum`
416−would ack (or nack) the packet, which would perform double duty as a message
417−ack. Assuming that a direct peer-to-peer connection is possible, the ack would
418−be sent directly to `~bacbel-tagfeb` using the IP and port found in the origin
419−field of the received packet rather than being relayed via `~zod`.
420−
421−But if the message were not short enough to be contained in a single packet,
422−each packet would need to be decrypted and `+cue`d to obtain the message
423−fragments that are then put together and `+cue`d again to obtain the complete
424−message.
425−
426−## The Serf and the King
427−
428−Urbit's functionality is split between the two binaries `urbit-worker` (sometimes
429−called the Serf) and `urbit-king` (sometimes called the King). This division of
430−labor is currently not well-documented outside of the [Vere documents](/docs/vere/), but we summarize it here.
431−
432−In short, the Serf is the Nock runtime and so keeps track of the current state
433−of Arvo as a Nock noun and updates the state by `%poke`ing it with nouns, and
434−then informs the King of the new state. The King manages snapshots of the Arvo
435−state and handles I/O with Unix, among other things. The Serf only ever talks to
436−the King, while the King talks with both the Serf and Unix.
437−
438−### Ames I/O submodule
439−
440−The King has several submodules, one of them being an Ames I/O submodule. This
441−submodule is responsible for wrapping outgoing Ames packets as UDP packets, and
442−unwrapping incoming UDP packets into Ames packets and forwarding them to the
443−worker. It also maintains an incoming packet queue.
444−
445−This division is summarized in the following diagram, describing how
446−`~bacbel-tagfeb` requests a subscription to the `recipes` notebook of
447−`~worwel-sipnum` in the Publish app.
448−
449−![](https://media.urbit.org/docs/arvo/packet.png)
450−
451−Ames, as a part of Arvo, handles `+jam`ming, packetizing, encryption, and
452−forming Ames packets. Once it is ready to send an Ames packet, it `%give`s to
453−Unix a `%send` `gift` containing that packet. This will be a Nock noun
454−containing the `@tas` `%send` as well as the serialized packet.
455−
456−"Unix", in this case, is actually the King. The King receives the `%send`
457−instruction, wraps the packet contained within as a UDP packet, and immediately
458−hands it off the the Unix network interface to be sent.
459−
460−Now the receiving King is handed a UDP packet by Unix. The King removes the UDP
461−wrapper, `+jam`s the `lane` on which it heard the packet, and delivers the packet
462−to the Ames vane as an atom by copying the bytes it heard on the UDP port.
content/docs/arvo/ames/cryptography.mddeleted−145
@@ -1,145 +0,0 @@
1−+++
2−title = "Cryptography"
3−weight = 2
4−template = "doc.html"
5−+++
6−
7−Here we give a technical overview of how Ames implements cryptography.
8−
9−## Summary
10−
11−By default, all [packets are encrypted](#packets) with 256-bit
12−[AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) symmetric key
13−encryption, whose key is obtained by [Diffie-Hellman key exchange](#key-exchange),
14−with public/private keys generated using elliptic curve
15−[Curve25519](https://en.wikipedia.org/wiki/Curve25519). The only exception to
16−this are comet [self-attestation packets](#comets), which are unencrypted.
17−
18−All packets are also [signed](#packets) using [Elliptic Curve Digital Signature
19−Algorithm](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm).
20−
21−The `$ames-state` includes a [`+acru:ames`](#crypto-core) core, an interface
22−core into which one of the cryptosuites in `zuse` may be implemented. Some, but
23−not all, of the calls to cryptography-related tasks (encryption, signing,
24−decrypting, and authenticating) are peformed utilizing the `+acru` core.
25−
26−## Packet encryption and authentication {% #packets %}
27−
28−Each Urbit ship possesses two networking keypairs: one for encryption, and one
29−for authentication. We often refer to these two keypairs as though they were a
30−single keypair because they are stored as a single atom. [Elliptic Curve
31−Diffie-Hellman](https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman)
32−is used for encryption, while [Elliptic Curve Digital Signature
33−Algorithm](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm)
34−is used for authentication
35−
36−The encrypted payload of each packet is a `$shut-packet`, which is the `+jam` of
37−a cell with the [$bone](/docs/arvo/ames/data-types#bone), message number, and message fragment or ack (see
38−[Ames](/docs/arvo/ames/ames) for more information on packet structure). The
39−message fragment is signed using the authentication key. It is encrypted using
40−[`+en:crub:crypto`](/docs/arvo/reference/cryptography#en) found in
41−`sys/zuse.hoon`, which utilizes the 256-bit AES-SIV algorithm.
42−
43−## Diffie-Hellman key exchange {% #key-exchange %}
44−
45−For each foreign ship a given ship has communicated with, `$ames-state` contains a
46−[$peer-state](/docs/arvo/ames/data-types#peer-state), inside which the [$symmetric-key](/docs/arvo/ames/data-types#symmetric-key) (an atom which nests under
47−`@uw`) is utilized for encrypting all Ames packets shared between the two ships.
48−The `symmetric-key` is derived using [`+shar:ed:crypto`](/docs/arvo/reference/cryptography#ed) found in `sys/zuse.hoon`,
49−which is an arm utilized for generating the symmetric key for elliptic curve
50−[Diffie-Hellman key
51−exchange](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange)
52−with [curve25519](https://en.wikipedia.org/wiki/Curve25519). Briefly, each ship
53−in a two-way conversation computes the shared symmetric key for that
54−conversation by computing the product of their own private key and the public
55−key of the other party.
56−
57−## Comet self-attestation {% #comets %}
58−
59−Recall that the `@p` of a comet is the hash of their 128-bit public key cast as
60−a `@p`. Since the public key of a comet is not stored on Azimuth, a comet proves
61−its identity with an "attestation packet". This is an unencrypted packet whose
62−payload is the comet's signature created with its private key. This is the only
63−circumstance under which a ship will send an unencrypted packet. The signature
64−is generated with
65−[`+sign:as:crub`](/docs/arvo/reference/cryptography#sign-as) found in
66−`sys/zuse.hoon`.
67−
68−Upon hearing an attestation packet, the receiving ship will generate a symmetric
69−key for communications with the comet, according to the [key
70−exchange](#key-exchange) protocol.
71−
72−The fact that the first packet exchanged between a comet and another ship must
73−be an attestation packet is why comets are unable to initiate communication with
74−one another, and also why comets must be the first to initiate communication
75−with a non-comet. This is a technical limitation with a planned workaround.
76−
77−## `+acru:ames` {% #crypto-core %}
78−
79−The `+crypto-core` in `$ames-state` is an `+acru:ames` core, a
80−[lead](/docs/hoon/reference/advanced#dry-polymorphism-and-core-nesting-rules)
81−interface core for asymmetric cryptosuites found in `sys/lull.hoon` which
82−handles encryption, decryption, signing, and verifying. In practice, the only
83−cryptosuite in use is [`+crub:crypto`](#crub), which implements [Suite B
84−Cryptography](https://en.wikipedia.org/wiki/NSA_Suite_B_Cryptography).
85−
86−```hoon
87− ++ acru $_ ^? :: asym cryptosuite
88− |% :: opaque object
89− ++ as ^? :: asym ops
90− |% ++ seal |~([a=pass b=@] *@) :: encrypt to a
91− ++ sign |~(a=@ *@) :: certify as us
92− ++ sure |~(a=@ *(unit @)) :: authenticate from us
93− ++ tear |~([a=pass b=@] *(unit @)) :: accept from a
94− -- ::as ::
95− ++ de |~([a=@ b=@] *(unit @)) :: symmetric de, soft
96− ++ dy |~([a=@ b=@] *@) :: symmetric de, hard
97− ++ en |~([a=@ b=@] *@) :: symmetric en
98− ++ ex ^? :: export
99− |% ++ fig *@uvH :: fingerprint
100− ++ pac *@uvG :: default passcode
101− ++ pub *pass :: public key
102− ++ sec *ring :: private key
103− -- ::ex ::
104− ++ nu ^? :: reconstructors
105− |% ++ pit |~([a=@ b=@] ^?(..nu)) :: from [width seed]
106− ++ nol |~(a=ring ^?(..nu)) :: from ring
107− ++ com |~(a=pass ^?(..nu)) :: from pass
108− -- ::nu ::
109− -- ::acru ::
110−```
111−
112−As the `+acru` core is merely an interface, the details on how it is implemented
113−may vary according to the cryptosuite. We summarize what each
114−core is utilized for here, but see
115−[`crub:crypto`](/docs/arvo/reference/cryptography#crub) for more details on
116−how the specific cryptosuite utilized by Ames is implemented.
117−
118−#### `+as:acru`
119−
120−This core is used for the standard asymmetric cryptographic operations: encrypting
121−(`+seal`), signing (`+sign`), authenticating (`+sure`), and decrypting (`+tear`).
122−
123−#### `+ex:acru`
124−
125−This core is used to extract keys and their fingerprints. `+sec` is the secret key (which
126−may be empty), `+pub` is the public key associated to the secret key, `+pac` is
127−the fingerprint associated to the secret key, and `+fig` is the fingerprint
128−associated to the public key. We note that when the core contains both
129−encryption and authentication keys, they are typically concatenated to be
130−returned as a single atom.
131−
132−#### `+nu:acru`
133−
134−This core contains constructors for the `+acru` core. `+pit:nu` is used to
135−construct an `+acru` core with both a private and public key (i.e. both
136−`+sec:ex` and `+pub:ex` are set) from a bitlength and seed. `+nol:nu` can then be
137−called from an `+acru` core created with `+pit:nu` to get an `+acru` core with
138−only the secret key, while `+com:nu` can be called to get an `+acru` core with
139−only the public key.
140−
141−#### `+en:acru`, `+de:acru`, and `+dy:acru`
142−
143−These arms are for symmetric encryption (`+en`) and decryption (`+de` and
144−`+dy`). The difference between the decryption arms is that `+de` returns null
145−and `+dy` crashes upon failure.
content/docs/arvo/ames/data-types.mddeleted−389
@@ -1,389 +0,0 @@
1−+++
2−title = "Data Types"
3−weight = 5
4−template = "doc.html"
5−+++
6−
7−Here are the data types used by Ames, as defined in `lull.hoon`.
8−
9−## `$address`
10−
11−```hoon
12−+$ address @uxaddress
13−```
14−
15−Opaque atomic transport address to or from Unix. For Ames over UDP, it will encode the IP address and port.
16−
17−## `$verb`
18−
19−```hoon
20−+$ verb ?(%snd %rcv %odd %msg %ges %for %rot)
21−```
22−
23−Verbosity flag for Ames. Use with `|ames-verb %flag1 %flag2 ...` and turn off with `|ames-verb`.
24−
25−- `%snd` - Sending packets.
26−- `%rcv` - Receiving packets.
27−- `%odd` - Unusual events.
28−- `%msg` - Message-level events.
29−- `%ges` - Congestion control.
30−- `%for` - Packet forwarding.
31−- `%rot` - Routing attempts.
32−
33−## `$blob`
34−
35−```hoon
36−+$ blob @uxblob
37−```
38−
39−Raw atom to or from Unix, representing a packet.
40−
41−## `$error`
42−
43−```hoon
44−+$ error [tag=@tas =tang]
45−```
46−
47−Tagged diagnostic trace.
48−
49−## `$lane`
50−
51−```hoon
52−+$ lane (each @pC address)
53−```
54−
55−Ship transport address; either opaque [$address](#address) or galaxy. The runtime knows how to look up galaxies, so we don't need to know their transport addresses.
56−
57−## `$plea`
58−
59−```hoon
60−+$ plea [vane=@tas =path payload=*]
61−```
62−
63−Application-level message, as a `%pass`.
64−
65−- `vane` - Destination vane on remote ship.
66−- `path` - Internal route on the receiving ship.
67−- `payload` - Semantic message contents.
68−
69−## `$bone`
70−
71−```hoon
72−+$ bone @udbone
73−```
74−
75−Message flow index - mapped to `duct`s in the [$ossuary](#ossuary).
76−
77−The first `bone` is 0. They increment by 4, since each flow includes a bit for each message determining forward vs. backward and a second bit for whether the message is on the normal flow or the associated diagnostic flow (for naxplanations).
78−
79−The least significant bit of a `bone` is:
80−
81−- 1 if "forward", i.e. we send `%plea`s on this flow.
82−- 0 if "backward", i.e. we receive `%plea`s on this flow.
83−
84−The second-least significant bit is 1 if the `bone` is a naxplanation `bone`, and 0 otherwise. Only naxplanation messages can be sent on a naxplanation `bone`, as `%boon`s.
85−
86−## `$fragment`
87−
88−```hoon
89−+$ fragment @uwfragment
90−```
91−
92−A message fragment.
93−
94−## `$fragment-num`
95−
96−```hoon
97−+$ fragment-num @udfragmentnum
98−```
99−
100−Message fragment count.
101−
102−## `$message-blob`
103−
104−```hoon
105−+$ message-blob @udmessageblob
106−```
107−
108−Unfragmented message blob.
109−
110−## `$message-num`
111−
112−```hoon
113−+$ message-num @udmessagenum
114−```
115−
116−Message count.
117−
118−## `$public-key`
119−
120−```hoon
121−+$ public-key @uwpublickey
122−```
123−
124−A peer's public key.
125−
126−## `$symmetric-key`
127−
128−```hoon
129−+$ symmetric-key @uwsymmetrickey
130−```
131−
132−A symmetric key for encrypting messages to a peer. This is produced by performing an elliptic curve Diffie-Hellman using our private key and the peer's public key.
133−
134−## `$ack`
135−
136−```hoon
137−+$ ack
138− $% [%ok ~]
139− [%nack ~]
140− [%naxplanation =error]
141− ==
142−```
143−
144−A message acknowledgement.
145−
146−- `%ok` - Positive acknowledgement.
147−- `%nack` - Negative acknowledgement.
148−- `%naxplanation` - Nack trace.
149−
150−## `$ship-state`
151−
152−```hoon
153−+$ ship-state
154− $% [%alien alien-agenda]
155− [%known peer-state]
156− ==
157−```
158−
159−All Ames knows about a peer.
160−
161−- `%alien` - No PKI data, so enqueue actions to perform once we learn it.
162−- `%known` - We know their `life` and public keys, so we have a channel.
163−
164−## `$alien-agenda`
165−
166−```hoon
167−+$ alien-agenda
168− $: messages=(list [=duct =plea])
169− packets=(set =blob)
170− heeds=(set duct)
171− ==
172−```
173−
174−What to do when Ames learns a peer's life and keys.
175−
176−- `messages` - [$plea](#plea)s local vanes have asked Ames to send.
177−- `packets` - Packets we've tried to send.
178−- `heeds` - Local tracking requests; passed through into [$peer-state](#peer-state).
179−
180−## `$peer-state`
181−
182−```hoon
183−+$ peer-state
184− $: $: =symmetric-key
185− =life
186− =public-key
187− sponsor=ship
188− ==
189− route=(unit [direct=? =lane])
190− =qos
191− =ossuary
192− snd=(map bone message-pump-state)
193− rcv=(map bone message-sink-state)
194− nax=(set [=bone =message-num])
195− heeds=(set duct)
196− ==
197−```
198−
199−State for a peer with known life and keys.
200−
201−- `route` - Transport-layer destination for packets to the peer.
202−- `qos` - Quality of service; connection status to the peer.
203−- `ossuary` - [$bone](#bone) to `duct` mapper.
204−- `snd` - Per-`bone` message pumps to send messages as fragments.
205−- `rcv` - Per-`bone` message sinks to assemble messages from fragments.
206−- `nax` - Unprocessed nacks (negative acknowledgments).
207−- `heeds` - Listeners for `%clog` notifications.
208−
209−## `$qos`
210−
211−```hoon
212−+$ qos
213− $~ [%unborn *@da]
214− [?(%live %dead %unborn) last-contact=@da]
215−```
216−
217−Quality of service; how is the connection to a peer doing?
218−
219−- `%live` - Peer is ok.
220−- `%dead` - Peer is not responding.
221−- `%unborn` - Peer is sunken.
222−- `last-contact` - Last time Ames heard from the peer, or if `%unborn`, the time when we first started tracking then.
223−
224−## `$ossuary`
225−
226−```hoon
227−+$ ossuary
228− $: =next=bone
229− by-duct=(map duct bone)
230− by-bone=(map bone duct)
231− ==
232−```
233−
234−[$bone](#bone) to `duct` mapping, `next` is the next `bone` to map to a `duct`.
235−
236−## `$message-pump-state`
237−
238−```hoon
239−+$ message-pump-state
240− $: current=_`message-num`1
241− next=_`message-num`1
242− unsent-messages=(qeu message-blob)
243− unsent-fragments=(list static-fragment)
244− queued-message-acks=(map message-num ack)
245− =packet-pump-state
246− ==
247−```
248−
249−Persistent state for a `|message-pump`.
250−
251−- `current`- Sequence number of earliest message sent or being sent.
252−- `next` - Sequence number of next message to send.
253−- `unsent-messages` - Messages to be sent after current message.
254−- `unsent-fragments` - Fragments of current message waiting for sending.
255−- `queued-message-acks` - Future message acks to be applied after current.
256−- `packet-pump-state` - State of corresponding `|packet-pump`.
257−
258−## `$static-fragment`
259−
260−```hoon
261−+$ static-fragment
262− $: =message-num
263− num-fragments=fragment-num
264− =fragment-num
265− =fragment
266− ==
267−```
268−
269−A packet; a fragment of a message and metadata.
270−
271−## `$packet-pump-state`
272−
273−```hoon
274−+$ packet-pump-state
275− $: next-wake=(unit @da)
276− live=(tree [live-packet-key live-packet-val])
277− metrics=pump-metrics
278− ==
279−```
280−
281−Persistent state for a `|packet-pump`.
282−
283−- `next-wake` - Last timer we've set, or null.
284−- `live` - Packets in flight; sent but not yet acked.
285−- `metrics` - Congestion control information.
286−
287−## `$pump-metrics`
288−
289−```hoon
290−+$ pump-metrics
291− $: rto=_~s1
292− rtt=_~s1
293− rttvar=_~s1
294− ssthresh=_10.000
295− cwnd=_1
296− num-live=@ud
297− counter=@ud
298− ==
299−```
300−
301−Congestion control state for a `|packet-pump`.
302−
303−- `rto` - Retransmission timeout.
304−- `rtt` - Roundtrip time estimate, low-passed using EWMA.
305−- `rttvar` - Mean deviation of `rtt`, also low-passed with EWMA.
306−- `num-live` - How many packets sent, awaiting ack.
307−- `ssthresh` - Slow-start threshold.
308−- `cwnd` - Congestion window; max unacked packets.
309−
310−## `$live-packet`
311−
312−```hoon
313−+$ live-packet
314− $: key=live-packet-key
315− val=live-packet-val
316− ==
317−```
318−
319−A packet in flight, as tracked in the [$packet-pump-state](#packet-pump-state).
320−
321−## `$live-packet-key`
322−
323−```hoon
324−+$ live-packet-key
325− $: =message-num
326− =fragment-num
327− ==
328−```
329−
330−Identifier of a packet in flight.
331−
332−## `$live-packet-val`
333−
334−```hoon
335−+$ live-packet-val
336− $: packet-state
337− num-fragments=fragment-num
338− =fragment
339− ==
340−```
341−
342−Content and metadata about a packet in flight.
343−
344−## `$packet-state`
345−
346−```hoon
347−+$ packet-state
348− $: last-sent=@da
349− retries=@ud
350− skips=@ud
351− ==
352−```
353−
354−Sending statistics about a packet in flight.
355−
356−## `$message-sink-state`
357−
358−```hoon
359−+$ message-sink-state
360− $: last-acked=message-num
361− last-heard=message-num
362− pending-vane-ack=(qeu [=message-num message=*])
363− live-messages=(map message-num partial-rcv-message)
364− nax=(set message-num)
365− ==
366−```
367−
368−State of a `|message-sink` to assemble received messages.
369−
370−- `last-acked` - Highest [$message-num](#message-num) Ames has fully acknowledged.
371−- `last-heard` - Highest `message-num` Ames has heard all fragments for.
372−- `pending-vane-ack` - Heard but not processed by local vane.
373−- `live-messages` - Partially received messages.
374−
375−## `$partial-rcv-message`
376−
377−```hoon
378−+$ partial-rcv-message
379− $: num-fragments=fragment-num
380− num-received=fragment-num
381− fragments=(map fragment-num fragment)
382− ==
383−```
384−
385−A message for which Ames has received some fragments.
386−
387−- `num-fragments` - Total number of fragments in the message.
388−- `num-received` - How many fragments Ames has received so far.
389−- `fragments` - The received fragments themselves.
content/docs/arvo/ames/scry.mddeleted−126
@@ -1,126 +0,0 @@
1−+++
2−title = "Scry Reference"
3−weight = 4
4−template = "doc.html"
5−+++
6−
7−Here are the scry endpoints of Ames. All of them take a `%x` `care` and require the `desk` in the path prefix be empty, so the general format is `.^([type] %ax /=//=/[some-path])`.
8−
9−## /protocol/version
10−
11−A scry with a `%x` `care` and a `path` of `/protocol/version` will return the current Ames protocol version as a `@`.
12−
13−#### Example
14−
15−```
16−> .^(@ %ax /=//=/protocol/version)
17−0
18−```
19−
20−## /peers
21−
22−A scry with a `%x` `care` and a `path` of `/peers` will return all ships that Ames is aware of. The type returned is a `(map ship ?(%alien %known))`, where `%known` means we have PKI data for them and `%alien` means we don't.
23−
24−#### Example
25−
26−```
27−> .^((map ship ?(%alien %known)) %ax /=//=/peers)
28−{[p=~wet q=%known] [p=~nes q=%known]}
29−```
30−
31−## /peers/[ship]
32−
33−A scry with a `%x` `care` and a `path` of `/peers/[ship]` where `[ship]` is a ship name like `~dopzod` will return everything Ames knows about that ship, or crash if the ship is unknown to Ames. The type returned is a [$ship-state](/docs/arvo/ames/data-types#ship-state).
34−
35−#### Example
36−
37−```
38−> .^(ship-state:ames %ax /=//=/peers/~nes)
39−[ %known
40− [ symmetric-key=0wEF.5-Mp4.ehBxk.a-ktl.CAUHq.~XNVq.AfPFk.TwBbj.rc7MS
41− life=1
42− public-key=0w9R.IG6Km.CQfuL.lP9Da.l~kh1.lOHzV.xactk.1ybiB.hekW~.VC2d0.DDRsU.h6GHl.PKmRX.p3u2-.vO4Hg.QTOlp.A4AI0.uGPVy
43− sponsor=~nes
44− ]
45− route=[~ [direct=%.y lane=[%.y p=~nes]]]
46− qos=[%dead last-contact=~2021.8.9..16.11.36..fdbc]
47− ossuary
48− [ next-bone=4
49− by-duct={[p=~[/gall/sys/way/~nes/hood /gall/use/hood/0w2.4d7EV/out/~nes/hood/helm/hi/~nes /dill //term/1] q=0]}
50− by-bone={[p=0 q=~[/gall/sys/way/~nes/hood /gall/use/hood/0w2.4d7EV/out/~nes/hood/helm/hi/~nes /dill //term/1]]}
51− ]
52− snd
53− { [ p=0
54− q
55− [ current=2
56− next=3
57− unsent-messages={}
58− unsent-fragments=~
59− queued-message-acks={}
60− packet-pump-state
61− [ next-wake=[~ ~2021.8.17..02.21.14..3d23]
62− live={[[message-num=2 fragment-num=0] [last-sent=~2021.8.17..02.19.14..3d23 retries=2.255 skips=0] num-fragments=1 fragment=0w2.QJ1qS.JzaQn.w7rMp.IzuTJ.7M7aP.-1s~1]}
63− metrics=[rto=~m2 rtt=~s1 rttvar=~s1 ssthresh=1 cwnd=1 num-live=1 counter=1]
64− ]
65− ]
66− ]
67− }
68− rcv={}
69− nax={}
70− heeds={~[/gall/sys/lag /dill //term/1]}
71−]
72−```
73−
74−## /peers/[ship]/forward-lane
75−
76−A scry with a `%x` `care` and a `path` of `/peers/[ship]/forward-lane` where `[ship]` is a ship name like `~dopzod` will return outbound routes to the given ship, or `~` if there are none. The type returned is a `(list lane:ames)`, see [$lane](/docs/arvo/ames/data-types#lane) for type details.
77−
78−#### Examples
79−
80−```
81−> .^((list lane:ames) %ax /=//=/peers/~nes/forward-lane)
82−~[[%.y p=~nes]]
83−```
84−
85−```
86−> .^((list lane:ames) %ax /=//=/peers/~nec/forward-lane)
87−~
88−```
89−
90−## /bones/[ship]
91−
92−A scry with a `%x` `care` and a `path` of `/bones/[ship]` where `[ship]` is a ship name like `~dopzod` will return inbound and outbound [$bone](/docs/arvo/ames/data-types#bone)s, which index message flows. If the ship in question is unknown to Ames, the scry will fail. The type returned is `[snd=(set bone) rcv=(set bone)]`.
93−
94−#### Example
95−
96−```
97−> .^([snd=(set bone) rcv=(set bone)] %ax /=//=/bones/~nes)
98−[snd={0} rcv={}]
99−```
100−
101−## /snd-bones/[ship]/[bone]
102−
103−A scry with a `%x` `care` and a `path` of `/snd-bones/[ship]/[bone]`, where `[ship]` is a ship name like `~dopzod` and `[bone]` is an outbound [$bone](/docs/arvo/ames/data-types#bone), will return message flow details for that `bone`. If the ship in question is unknown to Ames or the `bone` does not exist, the scry will fail. The type returned is a [$message-pump-state](/docs/arvo/ames/data-types#message-pump-state) wrapped in a `vase`.
104−
105−#### Example
106−
107−```
108−> !< message-pump-state:ames .^(vase %ax /=//=/snd-bones/~nes/0)
109−[ current=2
110− next=3
111− unsent-messages={}
112− unsent-fragments=~
113− queued-message-acks={}
114− packet-pump-state
115− [ next-wake=[~ ~2021.8.17..02.27.14..aaff]
116− live
117− { [ [message-num=2 fragment-num=0]
118− [last-sent=~2021.8.17..02.25.14..aaff retries=2.258 skips=0]
119− num-fragments=1
120− fragment=0w2.QJ1qS.JzaQn.w7rMp.IzuTJ.7M7aP.-1s~1
121− ]
122− }
123− metrics=[rto=~m2 rtt=~s1 rttvar=~s1 ssthresh=1 cwnd=1 num-live=1 counter=1]
124− ]
125−]
126−```
content/docs/arvo/ames/tasks.mddeleted−193
@@ -1,193 +0,0 @@
1−+++
2−title = "API Reference"
3−weight = 3
4−template = "doc.html"
5−+++
6−
7−In this document we describe the public interface for Ames. Namely, we describe
8−each `task` that Ames can be `%pass`ed, and which `gift`(s) Ames can `%give` in return.
9−
10−Some `task`s appear to have more than one arm associated to them, e.g. there are
11−four `+on-hear` arms. We denote this where it occurs, but always refer to the
12−`+on-hear:event-core` arm.
13−
14−Ames `task`s can be naturally divided into two categories: messaging tasks and
15−system/lifecycle tasks.
16−
17−## Messaging Tasks
18−
19−### `%hear`
20−
21−```hoon
22−[%hear =lane =blob]
23−```
24−
25−`%hear` handles raw packet receipt.
26−
27−This `task` only ever originates from Unix. It does the initial processing of a packet, namely by passing the raw packet information to `+decode-packet` which deserializes the packet and giving that data and the origin of the packet to `+on-hear-packet`, which begins the transformation of the packet into a new event in the form of a `+event-core`.
28−
29−There are multiple `+on-hear` arms in `ames.hoon`. Here we refer to `+on-hear:event-core`, as that is the one called by a `%hear` `task`. The other ones are used primarily for ack and nack processing, or receiving message fragments.
30−
31−`%hear` takes in a [$blob](/docs/arvo/ames/data-types#blob), which is essentially a large atom (around 1kB or less) that is the raw data of the message, and a [$lane](/docs/arvo/ames/data-types#lane), which is the origin of the message (typically an IP address).
32−
33−#### Returns
34−
35−`%hear` can trigger a number of possible returns. It can trigger the release of zero or more additional packets via `%send` `gift`s. It may also trigger a `%boon` or `%plea` `gift` (collectively referred to as a `%memo` within Ames) to a local vane in the case of a completed message.
36−
37−### `%heed`
38−
39−```hoon
40−[%heed =ship]
41−```
42−
43−A vane can pass Ames a `%heed` `task` to request Ames track a peer's responsiveness. If our `%boon`s to it start backing up locally, Ames will `give` a `%clog` back to the requesting vane containing the unresponsive peer's Urbit address.
44−
45−Stop tracking a peer by sending Ames a [%jilt](#jilt) `task`.
46−
47−The `ship` field specifies the peer to be tracked.
48−
49−#### Returns
50−
51−If the `ship` is indeed being unresponsive, as measured by backed up `%boon`s,
52−Ames will `give` a `%clog` `gift` to the requesting vane containing the
53−unresponsive peer's urbit address.
54−
55−### `%jilt`
56−
57−```hoon
58−[%jilt =ship]
59−```
60−
61−`%jilt` stops tracking a potentially unresponsive peer that was previously being
62−tracked as a result of the [%heed](#heed) `task`.
63−
64−There are two `+on-jilt` arms, this `task` utilizes `+on-hear:event-core`.
65−
66−The `ship` field specifies the peer we want to stop tracking.
67−
68−#### Returns
69−
70−This `task` returns no `gift`s.
71−
72−### `%plea`
73−
74−```hoon
75−[%plea =ship =plea:ames]
76−```
77−
78−`%plea` is the `task` used to instruct Ames to send a message. It extends the
79−`%pass`/`%give` semantics across the network. As such, it is the most
80−fundamental `task` in Ames and the primary reason for its existence.
81−
82−Ames also `pass`es a `%plea` `note` to another vane when it receives a message on a
83−"forward flow" from a peer, originally passed from one of the peer's vanes to the
84−peer's Ames.
85−
86−Ultimately `%plea` causes `%send` `gift`(s) to be sent to Unix, which tells
87−Unix to send packets. In terms of `%pass`/`%give` semantics, this is in
88−response to the `%born` `task`, which came along the Unix `duct`, rather than a
89−response to the `%plea`.
90−
91−A `%plea` `task` takes in the `ship` the `plea` is addressed to, and a [$plea](/docs/arvo/ames/data-types.md#plea).
92−
93−#### Returns
94−
95−This `task` returns no `gift`s.
96−
97−## System Tasks
98−
99−### `%born`
100−
101−```hoon
102−[%born ~]
103−```
104−
105−Each time you start your Urbit, the Arvo kernel calls the `%born` `task` for Ames.
106−
107−#### Returns
108−
109−In response to a `%born` `task`, Ames `%give`s Jael a `%turf` `gift`.
110−
111−The `duct` along which `%born` comes is Ames' only duct to Unix, so `%send`
112−`gift`s (which are instructions for Unix to send a packet) are also returned in
113−response to `%born`.
114−
115−### `%init`
116−
117−```hoon
118−[%init ~]
119−```
120−
121−`%init` is called a single time during the very first boot process, immediately
122−after the [larval stage](/docs/arvo/overview#larval-stage-core)
123−is completed. This initializes the vane. Jael is initialized first, followed by
124−other vanes such as Ames.
125−
126−In response to receiving the `%init` `task`, Ames subscribes to the information
127−contained by Jael.
128−
129−#### Returns
130−
131−```hoon
132−=~ (emit duct %pass /turf %j %turf ~)
133− (emit duct %pass /private-keys %j %private-keys ~)
134−```
135−
136−`%init` sends two moves that subscribe to `%turf` and `%private-keys` in Jael.
137−
138−### `%sift`
139−
140−```hoon
141−[%sift ships=(list ship)]
142−```
143−
144−This `task` filters debug output by ship. This `task` is used internally when the `|ames-sift` `hood` generator is run from the dojo.
145−
146−The `ships` field specifies the ships for which debug output is desired.
147−
148−#### Returns
149−
150−This `task` returns no `gift`s.
151−
152−### `%spew`
153−
154−```hoon
155−[%spew veb=(list verb)]
156−```
157−
158−Sets verbosity toggles on debug output. This `task` is used internally when the `|ames-verb` `hood` generator is run from the dojo.
159−
160−`%spew` takes in a `list` of [$verb](/docs/arvo/ames/data-types#verb), which are verbosity flags for Ames.
161−
162−`%spew` flips each toggle given in `veb`.
163−
164−#### Returns
165−
166−This `task` returns no `gift`s.
167−
168−### `%stir`
169−
170−```hoon
171−[%stir arg=@t]
172−```
173−
174−A `%stir` `task` starts timers for any flows that lack them.
175−
176−The `arg` field is unused.
177−
178−#### Returns
179−
180−This `task` returns no `gift`s.
181−
182−### `%vega`
183−
184−```hoon
185−[%vega ~]
186−```
187−
188−`%vega` is called whenever the kernel is updated. Ames currently does not do
189−anything in response to this.
190−
191−#### Returns
192−
193−This `task` returns no `gift`s.
content/docs/arvo/behn/_index.mddeleted−23
@@ -1,23 +0,0 @@
1−+++
2−title = "Behn"
3−weight = 20
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−insert_anchor_links = "right"
7−+++
8−
9−## [Overview](/docs/arvo/behn/behn)
10−
11−An overview of Behn, Urbit's timer vane.
12−
13−## [API Reference](/docs/arvo/behn/tasks)
14−
15−The `task`s Behn takes and the `gift`s it returns.
16−
17−## [Scry Reference](/docs/arvo/behn/scry)
18−
19−The scry endpoints of Behn.
20−
21−## [Examples](/docs/arvo/behn/examples)
22−
23−Practical examples of using Behn's `task`s.
content/docs/arvo/behn/behn.mddeleted−19
@@ -1,19 +0,0 @@
1−+++
2−title = "Overview"
3−weight = 1
4−template = "doc.html"
5−+++
6−
7−Urbit's timer vane.
8−
9−Behn manages timers in a simple priority queue. Other vanes and applications ask Behn to set a timer to go off at the given time, and Behn produces effects that start the timers on Unix. When the timer goes off, Unix sends an event to Behn, which then notifies the original requester. We don't gurantee that a timer event will happen at exactly the time it was set for, or even that it'll be particularly close. A timer event is a request to not be woken until after the given time.
10−
11−Additional information about Behn is included in [Lesson 2.6 - Behn](/docs/hoon/hoon-school/behn) of the Hoon tutorial.
12−
13−## Sections
14−
15−[API Reference](/docs/arvo/behn/tasks) - The `task`s Behn takes and the `gift`s it returns.
16−
17−[Scry Reference](/docs/arvo/behn/scry) - The scry endpoints of Behn.
18−
19−[Examples](/docs/arvo/behn/examples) - Practical examples of using Behn's `task`s.
content/docs/arvo/behn/examples.mddeleted−95
@@ -1,95 +0,0 @@
1−+++
2−title = "Examples"
3−weight = 4
4−template = "doc.html"
5−+++
6−
7−Here are a couple of practical examples of using Behn's `%wait` and `%rest` `task`s.
8−
9−## %wait
10−
11−Here we'll look at setting a timer by passing Behn a `%wait` `task` and taking the `%wake` `gift` it returns when the timer fires.
12−
13−Below is a thread which will take a `@dr` as its argument and `%pass`es Behn a `%wait` `task` to fire `@dr` in the future. When the timer fires, it'll then take the `%wake` `gift` and print it to the terminal along with the time that has elapsed.
14−
15−`wait.hoon`
16−
17−```hoon
18−/- spider
19−/+ *strandio
20−=, strand=strand:spider
21−^- thread:spider
22−|= arg=vase
23−=/ m (strand ,vase)
24−^- form:m
25−=/ delay=@dr (need !<((unit @dr) arg))
26−;< t1=@da bind:m get-time
27−=/ =task:behn [%wait (add delay t1)]
28−=/ =card:agent:gall [%pass /timer %arvo %b task]
29−;< ~ bind:m (send-raw-card card)
30−;< res=(pair wire sign-arvo) bind:m take-sign-arvo
31−?> ?=([%timer ~] p.res)
32−?> ?=([%behn %wake *] q.res)
33−%- (slog ~[leaf+"Gift: {<+.q.res>}"])
34−?~ error.q.res
35− ;< t2=@da bind:m get-time
36− %- (slog ~[leaf+"Time elapsed: {<`@dr`(sub t2 t1)>}"])
37− (pure:m !>(~))
38−%- (slog u.error.q.res)
39−(pure:m !>(~))
40−```
41−
42−Save the thread to `/ted/wait.hoon` and `|commit %base`. Then we can try running the thread with a `@dr` of `~s2`:
43−
44−```
45−> -wait ~s2
46−Gift: [%wake error=~]
47−Time elapsed: ~s2..0154
48−```
49−
50−As you can see, the timer has fired successfully after `~s2` and Behn has given us a `%wake` `gift`.
51−
52−## %rest
53−
54−Here we'll look at cancelling a previously set timer by passing Behn a `%rest` `task`.
55−
56−Below is a variation on the [%wake](#wake) thread. It takes a `@dr` as its argument and sets a timer that far in the future, as before. However, it also sets a second timer twice the `@dr` in the future, and then cancels the first with a `%rest` `task`. If the `%rest` `task` succeeds in cancelling the first timer, the `%wake` `gift` will arrive after double the specified delay.
57−
58−`rest.hoon`
59−
60−```hoon
61−/- spider
62−/+ *strandio
63−=, strand=strand:spider
64−^- thread:spider
65−|= arg=vase
66−=/ m (strand ,vase)
67−^- form:m
68−=/ delay=@dr (need !<((unit @dr) arg))
69−;< t1=@da bind:m get-time
70−=/ timer1=@da (add t1 delay)
71−=/ timer2=@da (add t1 (mul delay 2))
72−;< ~ bind:m (send-raw-card [%pass /timer %arvo %b %wait timer1])
73−;< ~ bind:m (send-raw-card [%pass /timer %arvo %b %wait timer2])
74−;< ~ bind:m (send-raw-card [%pass /timer %arvo %b %rest timer1])
75−;< res=(pair wire sign-arvo) bind:m take-sign-arvo
76−?> ?=([%timer ~] p.res)
77−?> ?=([%behn %wake *] q.res)
78−%- (slog ~[leaf+"Gift: {<+.q.res>}"])
79−?~ error.q.res
80− ;< t2=@da bind:m get-time
81− %- (slog ~[leaf+"Time elapsed: {<`@dr`(sub t2 t1)>}"])
82− (pure:m !>(~))
83−%- (slog u.error.q.res)
84−(pure:m !>(~))
85−```
86−
87−Save the above thread to `/ted/rest.hoon`, and `|commit %base`. Let's try run it with an argument of `~s2`:
88−
89−```
90−> -rest ~s2
91−Gift: [%wake error=~]
92−Time elapsed: ~s4..00d4
93−```
94−
95−As you can see, the timer fired after four seconds, which means the two second timer was successfully cancelled by the `%rest` `task`.
content/docs/arvo/behn/scry.mddeleted−46
@@ -1,46 +0,0 @@
1−+++
2−title = "Scry Reference"
3−weight = 3
4−template = "doc.html"
5−+++
6−
7−Here are Behn's scry endpoints. There's only a few and they're mostly just useful for debugging. All of Behn's scries take a `%x` `care` and require the `desk` in the path prefix be empty, so the general format is `.^([type] %bx /=//=/[some-path])`.
8−
9−## /debug/timers
10−
11−A scry with a `%x` `care` and a `path` of `/debug/timers` will return the timestamp and `duct` of all timers which are currently set. The type returned is a `(list [@da duct])`.
12−
13−```
14−> .^((list [@da duct]) %bx /=//=/debug/timers)
15−~[
16− [~2021.8.9..16.16.30..9d49 ~[/ames/pump/~wet/0 /ames]]
17− [~2021.8.9..16.17.58..597d ~[/ames/pump/~nes/0 /ames]]
18−]
19−```
20−
21−## /timers
22−
23−A scry with a `%x` `care` and a `path` of `/timers` will return the timestamps of all timers currently set. The type returned is a `(list @da)`.
24−
25−```
26−> .^((list @da) %bx /=//=/timers)
27−~[~2021.8.9..16.17.02..9de6 ~2021.8.9..16.17.58..597d]
28−```
29−
30−## /timers/next
31−
32−A scry with a `%x` `care` and a `path` of `/timers/next` will return the timestamp of the timer set to fire next, or null if there's none. The type returned is a `(unit @da)`.
33−
34−```
35−> .^((unit @da) %bx /=//=/timers/next)
36−[~ ~2021.8.9..16.17.58..597d]
37−```
38−
39−## /timers/[da]
40−
41−A scry with a `%x` `care` and a `path` of `/timers/[da]` (where `[da]` is an absolute date) will return all timers which are scheduled to fire between now and the specified date (inclusive). The type returned is a `(list @da)`.
42−
43−```
44−> .^((list @da) %bx /=//=/timers/(scot %da (add now ~d1)))
45−~[~2021.8.9..16.17.58..597d ~2021.8.9..16.18.06..a24b]
46−```
content/docs/arvo/behn/tasks.mddeleted−155
@@ -1,155 +0,0 @@
1−+++
2−title = "API Reference"
3−weight = 2
4−template = "doc.html"
5−+++
6−
7−In this document we describe the public interface for Behn. Namely, we describe each `task` that Behn can be `pass`ed, and which `gift`(s) Behn can `give` in return.
8−
9−Most of Behn's `task`s are only used by the kernel or runtime. The two `task`s you're likely to use from userspace are [%wait](#wait) for setting a timer and [%rest](#rest) for cancelling a timer.
10−
11−## `%born`
12−
13−```hoon
14−[%born ~]
15−```
16−
17−Each time you start your urbit, the Arvo kernel calls the `%born` task for Behn. When called, Behn gets the current time from Unix and updates its list of timers accordingly.
18−
19−You would not use this `task` from userspace.
20−
21−#### Returns
22−
23−Behn does not return any `gift` in response to a `%born` `task`.
24−
25−## `%rest`
26−
27−```hoon
28−[%rest p=@da]
29−```
30−
31−Cancel a timer.
32−
33−Behn takes in a `@da` and cancels the timer at that time if it exists, then adjusts the next wakeup call from Unix if necessary.
34−
35−#### Returns
36−
37−Behn does not return any `gift` in response to a `%rest` `task`.
38−
39−#### Example
40−
41−See the [%rest](/docs/arvo/behn/examples#rest) section of the Examples document.
42−
43−## `%drip`
44−
45−```hoon
46−[%drip p=vase]
47−```
48−
49−`%drip` allows one to delay a `gift` until a timer set for `now` fires.
50−
51−A Client `%slip`s Behn a `%drip` task wrapping a `gift` to be `give`n to a Target. This launches a sequence of `move`s as written here:
52−
53−```
54−Client -- %slip %drip --> Behn -- %pass %wait --> Behn -- %give %wake --> Behn -- %give %meta --> Target
55−```
56−
57−Here the `%meta` `move` is a wrapper for the `%gift` inside of the initial `%drip` wrapper.
58−
59−`%drip` only handles `gift`s, and can only schedule `gift`s for as soon as possible after the prescribed timer fires.
60−
61−`%drip` takes in a `%give` `move` in a `vase`.
62−
63−A `%drip` `task` is not likely to be used from userspace.
64−
65−#### Returns
66−
67−In response to a `%drip` `task`, Behn will `%pass` a `%wait` to itself, which then triggers a `%wake` `gift` to itself, which then causes Behn to `%give` a `%meta` `gift` containing the `gift` originally `%give`n to Behn when `%drip` was first called. That makes Behn its own client for `%drip`.
68−
69−#### Example
70−
71−Say an app (the Target) is subscribed to updates from Clay (the Client). If Clay `%give`s updates to the app directly and the app crashes, this may cause Clay to crash as well. If instead Clay `%pass`es Behn a `%drip` `task` wrapping the update `gift`, Behn will set a timer for `now` that, when fired, will cause the update `gift` to be given. If it causes a crash then it will have been in response to the `%drip` move, thereby isolating Clay from the crash. Thus `%drip` acts as a sort of buffer against cascading sequences of crashes.
72−
73−## `%huck`
74−
75−```hoon
76−[%huck syn=sign-arvo]
77−```
78−
79−Immediately gives back a `sign-arvo`.
80−
81−You would not use this `task` from userspace.
82−
83−#### Returns
84−
85−Behn returns the input `sign-arvo` as a `%heck` `gift`:
86−
87−```hoon
88−[%heck syn=sign-arvo]
89−```
90−
91−## `%trim`
92−
93−```hoon
94−[%trim p=@ud]
95−```
96−
97−This `task` is sent by the interpreter in order to free up memory. Behn does not do anything with this `task`, since it is not a good idea to forget your timers.
98−
99−You would not use this `task` from userspace.
100−
101−#### Returns
102−
103−Behn does not return any `gift` in response to a `%trim` `task`.
104−
105−## `%vega`
106−
107−```hoon
108−[%vega ~]
109−```
110−
111−This `task` informs the vane that the kernel has been upgraded. Behn does not do anything in response to this.
112−
113−You would not use this `task` from userspace.
114−
115−#### Returns
116−
117−Behn does not return any `gift` in response to a `%vega` `task`.
118−
119−## `%wait`
120−
121−```hoon
122−[%wait p=@da]
123−```
124−
125−Set timer.
126−
127−This `task` sets a timer to fire at the `@da` specified in `p`.
128−
129−#### Returns
130−
131−Behn returns a `%wake` `gift` in response to a `%wait` `task`, once the timer has fired. A `%wake` `gift` looks like:
132−
133−```hoon
134−[%wake error=(unit tang)]
135−```
136−
137−The `error` `unit` will be `~` if successful, or contain a traceback in the `tang` if the timer failed for some reason.
138−
139−#### Example
140−
141−See the [%wait](/docs/arvo/behn/tasks#wait) section of the Examples document.
142−
143−## `%wake`
144−
145−```hoon
146−[%wake ~]
147−```
148−
149−This `task` is sent by the kernel when the Unix timer tells the kernel that it is time for Behn to wake up. This is often caused by a `%doze` `gift` that Behn originally sent to the kernel that is then forwarded to Unix, which is where the real timekeeping occurs.
150−
151−You would not use this `task` from userspace.
152−
153−#### Returns
154−
155−In response to receiving this `task`, Behn may `%give` a `%doze` `gift` containing the `@da` of the next timer to elapse. Behn may also `%give` a `%wake` `gift` to itself.
content/docs/arvo/clay/_index.mddeleted−36
@@ -1,36 +0,0 @@
1−+++
2−title = "Clay"
3−weight = 30
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−insert_anchor_links = "right"
7−+++
8−
9−[Overview](/docs/arvo/clay/clay)
10−
11−High-level overview of Clay.
12−
13−[Architecture](/docs/arvo/clay/architecture)
14−
15−A conceptual overview of how Clay was designed.
16−
17−[Using Clay](/docs/arvo/clay/using)
18−
19−A quick overview of how the most common tasks involving Clay are performed:
20−reading and subscribing, syncing to Unix, and merging.
21−
22−[Data Types](/docs/arvo/clay/data-types)
23−
24−Explanations of the many data types found throughout Clay.
25−
26−[Scry Reference](/docs/arvo/clay/scry)
27−
28−Reference for Clay's various scry endpoints.
29−
30−[API Reference](/docs/arvo/clay/tasks)
31−
32−Details of the various `task`s you can use to interact with Clay.
33−
34−[Examples](/docs/arvo/clay/examples)
35−
36−Example usage of the various Clay `task`s.
content/docs/arvo/clay/architecture.mddeleted−177
@@ -1,177 +0,0 @@
1−+++
2−title = "Architecture"
3−weight = 2
4−template = "doc.html"
5−+++
6−
7−Clay is the primary filesystem for the [Arvo](/docs/arvo/overview)
8−operating system, which is the [core](/docs/glossary/core/) of an
9−urbit. The architecture of Clay is intrinsically connected with Arvo,
10−but for this section we assume no knowledge of either Arvo or Urbit.
11−We will point out only those features of Arvo that are necessary for
12−an understanding of Clay, and we will do so only when they arise.
13−
14−The first relevant feature of Arvo is that it is a deterministic
15−system where input and output are defined as a series of events and
16−effects. The state of Arvo is simply a pure function of its event log.
17−None of the effects from an event are emitted until the event is
18−entered in the log and persisted, either to disk or another trusted
19−source of persistence, such as a Kafka cluster. Consequently, Arvo is
20−a single-level store: everything in its state is persistent.
21−
22−In a more traditional OS, everything in RAM can be erased at any
23−time by power failure, and is always erased on reboot. Thus, a
24−primary purpose of a filesystem is to ensure files persist across
25−power failures and reboots. In Arvo, both power failures and
26−reboots are special cases of suspending computation, which is
27−done safely since our event log is already persistent. Therefore,
28−Clay is not needed in Arvo for persistence. Why, then, do we have a
29−filesystem? There are two answers to this question.
30−
31−First, Clay provides a filesystem tree, which is a convenient
32−user interface for some applications. Unix has the useful concept
33−of virtual filesystems, which are used for everything from direct
34−access to devices, to random number generators, to the /proc
35−tree. It is easy and intuitive to read from and write to a
36−filesystem tree.
37−
38−Second, Clay has a distributed revision-control system baked into
39−it. Traditional filesystems are not revision controlled, so
40−userspace software -- such as git -- is written on top of them to
41−do so. Clay natively provides the same functionality as modern
42−DVCSes, and more.
43−
44−Clay has two other unique properties that we'll cover later on:
45−it supports typed data and is referentially transparent.
46−
47−### Revision Control
48−
49−Every urbit has one or more desks, which are independently
50−revision-controlled branches. Each desk contains its own `mark`
51−definitions, apps, and so forth.
52−
53−Traditionally, an Urbit ship has at least a `%base` desk, and usually
54−`%garden` and `%landscape` desks. The `%base` desk has the kernel and
55−base system software. The `%garden` desk has software pertaining to
56−the home screen. The `%landscape` desk contains software for the
57−Groups app. The `%base` desk is a fork of the `%base` desk of
58−whichever ship you download system updates from - typically your
59−sponsor, but theoretically may be any ship.
60−
61−A desk is a series of numbered commits, the most recent of which
62−represents the current state of the desk. A commit is composed of
63−(1) an absolute time when it was created, (2) a list of zero or
64−more parents, and (3) a map from paths to data.
65−
66−Most commits have exactly one parent, but the initial commit on a
67−desk may have zero parents, and merge commits have more than one
68−parent.
69−
70−The non-metadata is stored as a `map` of `path`s to data. It's
71−worth noting that no constraints are put on this `map`, so, for
72−example, both `/a/b` and `/a/b/c` could have data. This is impossible
73−in a traditional Unix filesystem since it means that `/a/b` is both
74−a file and a directory. Conventionally, the final element in the
75−path is its `mark` -- much like a filename extension in Unix. Thus,
76−`/doc/readme.md` in Unix is stored as `/doc/readme/md` in urbit.
77−
78−The data is not stored directly in the `map`; rather, a hash of the
79−data is stored, and we maintain a master blob store. Thus, if the
80−same data is referred to in multiple commits (as, for example,
81−when a file doesn't change between commits), only the hash is
82−duplicated.
83−
84−In the master blob store, we either store the data directly, or
85−else we store a diff against another blob. The hash is dependent
86−only on the data within and not on whether or not it's stored
87−directly, so we may on occasion rearrange the contents of the
88−blob store for performance reasons.
89−
90−Recall that a desk is a series of numbered commits. Not every
91−commit in a desk must be numbered. For example, if the `%base` desk
92−has had 50 commits since `%foo` was forked from it, then a merge
93−from `%base` to `%foo` will only add a single revision number,
94−although the full commit history will be accessible by traversing
95−the parentage of the individual commits.
96−
97−We do guarantee that the first commit is numbered 1, commits are
98−numbered consecutively after that (i.e. there are no "holes"),
99−the topmost commit is always numbered, and every numbered commit
100−is an ancestor of every later numbered commit.
101−
102−There are three ways to refer to particular commits in the
103−revision history. Firstly, one can use the revision number.
104−Secondly, one can use any absolute time between the one numbered
105−commit and the next (inclusive of the first, exclusive of the
106−second). Thirdly, every desk has a `map` of labels to revision
107−numbers. These labels may be used to refer to specific commits.
108−
109−Additionally, Clay is a global filesystem, so data on other urbits
110−is easily accessible the same way as data on our local urbit. In
111−general, the path to a particular revision of a desk is
112−`/~urbit-name/desk-name/revision`. Thus, to get `/try/readme/md`
113−from revision 5 of the `%base` desk on `~sampel-sipnym`, we refer to
114−`/~sampel-sipnym/base/5/try/readme/md`. Clay's namespace is thus
115−global and referentially transparent.
116−
117−### A Typed Filesystem
118−
119−Since Clay is a general filesystem for storing data of arbitrary
120−types, in order to revision control correctly it needs to be
121−aware of types all the way through. Traditional revision control
122−does an excellent job of handling source code, so for source code
123−we act very similar to traditional revision control. The
124−challenge is to handle other data similarly well.
125−
126−For example, modern VCSs generally support "binary files", which
127−are files for which the standard textual diffing, patching, and
128−merging algorithms are not helpful. A "diff" of two binary files
129−is just a pair of the files, "patching" this diff is just
130−replacing the old file with the new one, and "merging"
131−non-identical diffs is always a conflict, which can't even be
132−helpfully annotated. Without knowing anything about the structure
133−of a blob of data, this is the best we can do.
134−
135−Often, though, "binary" files have some internal structure, and
136−it is possible to create diff, patch, and merge algorithms that
137−take advantage of this structure. An image may be the result of a
138−base image with some set of operations applied. With algorithms
139−aware of this set of operations, not only can revision control
140−software save space by not having to save every revision of the
141−image individually, these transformations can be made on parallel
142−branches and merged at will.
143−
144−Suppose Alice is tasked with touching up a picture, improving the
145−color balance, adjusting the contrast, and so forth, while Bob
146−has the job of cropping the picture to fit where it's needed and
147−adding textual overlay. Without type-aware revision control,
148−these changes must be made serially, requiring Alice and Bob to
149−explicitly coordinate their efforts. With type-aware revision
150−control, these operations may be performed in parallel, and then
151−the two changesets can be merged programmatically.
152−
153−Of course, even some kinds of text files may be better served by
154−diff, patch, and merge algorithms aware of the structure of the
155−files. Consider a file containing a pretty-printed JSON object.
156−Small changes in the JSON object may result in rather significant
157−changes in how the object is pretty-printed (for example, by
158−addding an indentation level, splitting a single line into
159−multiple lines).
160−
161−A text file wrapped at 80 columns also reacts suboptimally with
162−unadorned Hunt-McIlroy diffs. A single word inserted in a
163−paragraph may push the final word or two of the line onto the
164−next line, and the entire rest of the paragraph may be flagged as
165−a change. Two diffs consisting of a single added word to
166−different sentences may be flagged as a conflict. In general,
167−prose should be diffed by sentence, not by line.
168−
169−As far as we are aware, Clay is the first generalized,
170−type-aware revision control system. We'll go into the workings
171−of this system in some detail.
172−
173−### Marks
174−
175−Central to a typed filesystem is the idea of file types. In Clay, we
176−call these `mark`s. See the [Marks](/docs/arvo/clay/marks/marks)
177−section for more details.
content/docs/arvo/clay/clay.mddeleted−61
@@ -1,61 +0,0 @@
1−+++
2−title = "Overview"
3−weight = 1
4−template = "doc.html"
5−aliases = ["/docs/learn/arvo/clay/"]
6−+++
7−
8−Our filesystem.
9−
10−`%clay` is version-controlled, referentially-transparent, and global.
11−While this filesystem is stored in `%clay`, it is mirrored to Unix for
12−convenience. Unix tells `%clay` whenever a file changes in the Unix
13−copy of the filesystem so that the change may be applied. `%clay` tells
14−unix whenever an app or vane changes the filesystem so that the change
15−can be effected in Unix. Apps and vanes may use `%clay` to write to the
16−filesystem, query it, and subscribe to changes in it. Ford and gall use
17−`%clay` to serve up apps and web pages.
18−
19−`%clay` includes three components. First is the filesystem/version
20−control algorithms, which are mostly defined in `++ze` and `++zu` in
21−zuse. Second is the write, query, and subscription logic. Finally, there
22−is the logic for communicating requests to, and receiving requests from,
23−foreign ships.
24−
25−### User documentation
26−
27−[Filesystem](/using/os/filesystem)
28−
29−How to interact with the Clay filesystem via Dojo. This includes basics such as
30−mounting to Unix, changing directory, merging, and listing files.
31−
32−### Developer Documentation
33−
34−[Architecture](/docs/arvo/clay/architecture)
35−
36−A conceptual overview of how Clay was designed.
37−
38−[Using Clay](/docs/arvo/clay/using)
39−
40−A quick overview of how the most common tasks involving Clay are performed:
41−reading and subscribing, syncing to Unix, and merging.
42−
43−[Data Types](/docs/arvo/clay/data-types)
44−
45−Explanations of the many data types found throughout Clay.
46−
47−[Scry Reference](/docs/arvo/clay/scry)
48−
49−Reference for Clay's various scry endpoints.
50−
51−[API Reference](/docs/arvo/clay/tasks)
52−
53−Details of the various `task`s you can use to interact with Clay.
54−
55−[Examples](/docs/arvo/clay/examples)
56−
57−Example usage of the various Clay `task`s.
58−
59−[Marks](/docs/arvo/clay/marks/marks)
60−
61−Details of `mark`s as well as a guide to writing them and their usage.
content/docs/arvo/clay/data-types.mddeleted−681
@@ -1,681 +0,0 @@
1−+++
2−title = "Data Types"
3−weight = 4
4−template = "doc.html"
5−+++
6−
7−This section will be reference documentation for the data types used by our
8−filesystem.
9−
10−As a general guide, we recommend reading and attempting to understand the data
11−structures used in any Hoon code before you try to read the code itself.
12−Although complete understanding of the data structures is impossible without
13−seeing them used in the code, an 80% understanding greatly clarifies the code.
14−As another general guide, when reading Hoon, it rarely pays off to understand
15−every line of code when it appears. Try to get the gist of it, and then move on.
16−The next time you come back to it, it'll likely make a lot more sense.
17−
18−### Data Models
19−
20−As you're reading through this section, remember you can always come
21−back to this when you run into these types later on. You're not going to
22−remember everything the first time through, but it is worth reading, or
23−at least skimming, this so that you get a rough idea of how our state is
24−organized.
25−
26−The types that are certainly worth reading are `++raft`, `++room`,
27−`++dome:clay`, `++ankh:clay`, `++rung:clay`, `++rang:clay`, `++blob:clay`,
28−`++yaki:clay`, and `++nori:clay` (possibly in that order). All in all, though,
29−this section isn't too long, so many readers may wish to quickly read through
30−all of it. If you get bored, though, just skip to the next section. You can
31−always come back when you need to.
32−
33−### `$raft`, formal state
34−
35−```hoon
36−+$ raft :: filesystem
37− $: rom=room :: domestic
38− hoy=(map ship rung) :: foreign
39− ran=rang :: hashes
40− mon=(map term beam) :: mount points
41− hez=(unit duct) :: sync duct
42− cez=(map @ta crew) :: permission groups
43− pud=(unit [=desk =yoki]) :: pending update
44− == ::
45−```
46−
47−This is the state of the vane. Anything that must be remembered between
48−calls to Clay is stored in this state.
49−
50−`ran` is the store of all commits and deltas, keyed by hash. The is
51−where all the "real" data we know is stored; the rest is "just
52−bookkeeping".
53−
54−`rom` is the state for all local desks. It consists of a `duct` to
55−[Dill](/docs/arvo/dill/dill) and a collection of `desk`s.
56−
57−`hoy` is the state for all foreign desks.
58−
59−`ran` is the global, hash-addressed object store. It has maps of commit hashes
60−to commits and content hashes to content.
61−
62−`mon` is a collection of Unix mount points. `term` is the mount point (relative
63−to th pier) and `beam` is a domestic Clay directory.
64−
65−`hez` is the duct used to sync with Unix.
66−
67−`cez` is a collection of named permission groups.
68−
69−`pud` is an update that's waiting on a kernel upgrade.
70−
71−#### `$room`, filesystem per domestic ship
72−
73−```hoon
74−+$ room :: fs per ship
75− $: hun=duct :: terminal duct
76− dos=(map desk dojo) :: native desk
77− == ::
78−```
79−
80−This is the representation of the filesystem of a ship on our pier.
81−
82−`hun` is the duct we use to send messages to [Dill](/docs/arvo/dill/dill) to
83−display notifications of filesystem changes. Only `%note` `%gift`s should be
84−produced along this `duct`. This is set by the `%init` `move`.
85−
86−`dos` is a well-known operating system released in 1981. It is also the
87−set of `desk`s on this ship, mapped to their `desk` state.
88−
89−#### `$desk`, filesystem branch
90−
91−```hoon
92−+$ desk @tas
93−```
94−
95−This is the name of a branch of the filesystem. The default `desk`s are `%base`, `%garden`, `%landscape`, `%webterm` and `%bitcoin`. Desks have
96−independent histories and states, and they may be
97−[merged](/docs/arvo/clay/using#merging) into each other.
98−
99−### `$dojo`, domestic desk state
100−
101−```hoon
102−+$ dojo
103− $: qyx=cult :: subscribers
104− dom=dome :: desk state
105− per=regs :: read perms per path
106− pew=regs :: write perms per path
107− ==
108−```
109−
110−This is the all the data that is specific to a particular `desk` on a domestic
111−ship. `qyx` is the set of subscribers to this `desk`, and `dom` is the data in
112−the `desk`. `regs` are `(map path rule)`, and so `per` is a `map` of read
113−permissions by `path` and `pew` is a `map` of write permissions by `path`.
114−
115−#### `$cult`, subscriptions
116−
117−```hoon
118−+$ cult (jug wove duct)
119−```
120−
121−`cult`s keep track of subscribers. `wove`s are associated to requests, and each
122−`wove` is mapped to a set of `duct`s associated to subscribers who should be
123−notified when the request is filled/updated.
124−
125−#### `$rave:clay`, general subscription request
126−
127−```hoon
128− +$ rave :: general request
129− $% [%sing =mood] :: single request
130− [%next =mood] :: await next version
131− [%mult =mool] :: next version of any
132− [%many track=? =moat] :: track range
133− == ::
134−```
135−
136−This represents a subscription request for a `desk`.
137−
138−A `%sing` request asks for data at single revision.
139−
140−A `%next` request asks to be notified the next time there’s a change to the
141−specified file.
142−
143−A `%mult` request asks to be notified the next time there's a change to a
144−specified set of files.
145−
146−A `%many` request asks to be notified on every change in a `desk` for a range of changes (including into the future).
147−
148−### `$rove`, stored general subscription request
149−
150−```hoon
151− +$ rove :: stored request
152− $% [%sing =mood] :: single request
153− [%next =mood aeon=(unit aeon) =cach] :: next version of one
154− $: %mult :: next version of any
155− =mool :: original request
156− aeon=(unit aeon) :: checking for change
157− old-cach=(map [=care =path] cach) :: old version
158− new-cach=(map [=care =path] cach) :: new version
159− == ::
160− [%many track=? =moat lobes=(map path lobe)] :: change range
161− == ::
162−```
163−
164−Like a `rave` but with provisions to store current versions for `%next` and `%many`.
165−Generally used when we store a request in our state somewhere. This is so that
166−we can determine whether new versions actually affect the path we're subscribed to.
167−
168−#### `$mood:clay`, single subscription request
169−
170−```hoon
171− +$ mood [=care =case =path] :: request in desk
172−```
173−
174−This represents a request for data related to the state of the `desk` at a
175−particular commit, specfied by `case`. `care` specifies what kind of information
176−is desired, and `path` specifies the path we are requesting.
177−
178−#### `$moat:clay`, range subscription request
179−
180−```hoon
181− +$ moat [from=case to=case =path] :: change range
182−```
183−
184−This represents a request for all changes between `from` and `to` on `path`. You
185−will be notified when a change is made to the node referenced by the `path` or to
186−any of its children.
187−
188−### `$care:clay`, Clay submode
189−
190−```hoon
191− +$ care ?(%a %b %c %d %e %f %p %r %s %t %u %v %w %x %y %z) :: clay submode
192−```
193−
194−This specifies what type of information is requested in a subscription
195−or a scry.
196−
197−`%a` build a Hoon file at a `path`.
198−
199−`%b` build a dynamically typed `mark` by name (a `$dais` mark-interface core).
200−
201−`%c` build a dynamically typed `mark` conversion gate (a `$tube`) by "from" and
202−"to" `mark` names.
203−
204−`%d` returns a `(set desk)` of the `desk`s that exist on your ship.
205−
206−`%e` builds a statically typed `mark` by name (a `$nave` mark-interface core).
207−
208−`%f` builds a statically typed mark converstion gate.
209−
210−`%p` produces the permissions for a directory, returned as a `[dict:clay dict:clay]`.
211−
212−`%r` requests the file in the same fashion as `%x`, but wraps the result in a `vase`.
213−
214−`%s` has miscellaneous debug endpoints.
215−
216−`%t` produces a `(list path)` of descendent `path`s for a directory within a `yaki`.
217−
218−`%u` produces a `?` depending on whether or not the specified file exists. It
219−does not check any of its children.
220−
221−`%v` requests the entire `dome` for a specified `desk` at a particular `aeon`.
222−When used on a foreign `desk`, this get us up-to-date to the requested version.
223−
224−`%w` requests the revision number and date of the specified path, returned as a `cass:clay`.
225−
226−`%x` requests the file at a specified path at the specified commit, returned as
227−an `@`. If there is no node at that path or if the node has no contents (that
228−is, if `fil:ankh` is null), then this crashes.
229−
230−`%y` requests an `arch` of the specfied commit at the specified path. It will
231−return the bunt of an `arch` if the file or directory is not found.
232−
233−`%z` requests a recursive hash of a node and all its children, returned as a `@uxI`.
234−
235−#### `$ankh`, filesystem node
236−
237−```hoon
238−+$ ankh :: expanded node
239− $~ [~ ~]
240− $: fil=(unit [p=lobe q=cage]) :: file
241− dir=(map @ta ankh) :: folders
242− == ::
243−```
244−
245−This is a recursive filesystem node type that can describe a whole tree of
246−folders and files, with subtrees organized by path prefix. In Earth filesystems,
247−a node is a file xor a directory. On Mars, we're inclusive, so a node is a file
248−ior a directory.
249−
250−`fil` is the contents of this file, if any. `p.fil` is a hash of the
251−contents while `q.fil` is the data itself.
252−
253−`dir` is the set of children of this node. In the case of a pure file,
254−this is empty. The keys are the names of the children and the values
255−are, recursively, the nodes themselves.
256−
257−### `$arch`, shallow filesystem node
258−
259−```hoon
260−+$ arch (axil @uvI)
261−++ axil
262− |$ [item]
263− [fil=(unit item) dir=(map @ta ~)]
264−```
265−
266−An `arch` is a lightweight version of an `ankh` that only contains the hash
267−of the associated file and a `map` of child directories, but not the children of
268−those directories.
269−
270−The child directories are given by a `map` to null rather than a `set` so that the
271−ordering of the `map` will be the same as it is for an `axal`, allowing
272−efficient conversion for when the heavier node is needed.
273−
274−```hoon
275−++ axal
276− |$ [item]
277− [fil=(unit item) dir=(map @ta $)]
278−```
279−
280−#### `$case`, specifying a commit
281−
282−```hoon
283−+$ case
284− $% :: %da: date
285− :: %tas: label
286− :: %ud: sequence
287− ::
288− [%da p=@da]
289− [%tas p=@tas]
290− [%ud p=@ud]
291− ==
292−```
293−
294−A commit can be referred to in three ways: `%da` refers to the commit
295−that was at the head on date `p`, `%tas` refers to the commit labeled
296−`p`, and `%ud` refers to the commit numbered `p`. Note that since these
297−all can be reduced down to a `%ud`, only numbered commits may be
298−referenced with a `++case:clay`.
299−
300−#### `$dome`, desk data
301−
302−```hoon
303−+$ dome
304− $: ank=ankh :: state
305− let=aeon :: top id
306− hit=(map aeon tako) :: versions by id
307− lab=(map @tas aeon) :: labels
308− mim=(map path mime) :: mime cache
309− fod=ford-cache :: ford cache
310− fer=(unit reef-cache) :: reef cache
311− == ::
312−```
313−
314−A `dome` is the state of a `desk` and associated data.
315−
316−`ank` is the current state of the desk. Thus, it is the state of the
317−filesystem at revison `let`. The head of a `desk` is always a numbered
318−commit.
319−
320−`let` is the number of the most recently numbered commit. This is also
321−the total number of numbered commits.
322−
323−`hit` is a map of numerical ids to commit hashes. These hashes are mapped into
324−their associated commits in `hut.rang` in the `raft` of Clay. In general, the
325−keys of this map are exactly the numbers from 1 to `let`, with no gaps. Of
326−course, when there are no numbered commits, `let` is 0, so `hit` is null.
327−Additionally, each of the commits is an ancestor of every commit numbered
328−greater than this one. Thus, each is a descendant of every commit numbered less
329−than this one. Since it is true that the date in each commit (`t:yaki`) is no
330−earlier than that of each of its parents, the numbered commits are totally
331−ordered in the same way by both pedigree and date. Of course, not every commit
332−is numbered. If that sounds too complicated to you, don't worry about it. It
333−basically behaves exactly as you would expect.
334−
335−`lab` is a map of textual labels to numbered commits. Note that labels
336−can only be applied to numbered commits. Labels must be unique across a
337−desk.
338−
339−`mim` is a cache of the content in the directories that are mounted to Unix.
340−
341−`fod` is the Ford cache, which keeps a cache of the results of builds performed
342−at this `desk`'s current revision, including a full transitive closure of
343−dependencies for each completed build.
344−
345−`fer` is the system file cache, which consists of `vase`s for `hoon.hoon`,
346−`arvo.hoon`, `lull.hoon`, and `zuse.hoon`.
347−
348−#### `++rung`, filesystem per neighbor ship
349−
350−```hoon
351−+$ rung
352− $: rus=(map desk rede) :: neighbor desks
353− ==
354−```
355−
356−This is the filesystem of a neighbor ship. The keys to this `map` are all
357−the `desk`s we know about on their ship.
358−
359−#### `++rede`, generic desk state
360−
361−```hoon
362− ++ rede :: universal project
363− $: lim=@da :: complete to
364− qyx=cult :: subscribers
365− ref=(unit rind) :: outgoing requests
366− dom=dome :: revision state
367− == ::
368−+$ rede :: universal project
369− $: lim=@da :: complete to
370− ref=(unit rind) :: outgoing requests
371− qyx=cult :: subscribers
372− dom=dome :: revision state
373− per=regs :: read perms per path
374− pew=regs :: write perms per path
375− == ::
376−```
377−
378−This is our knowledge of the state of a desk, either foreign or
379−domestic.
380−
381−`lim` is the most recent `@da` for which we're confident we have all the
382−information for. For local `desk`s, this is always `now`. For foriegn `desk`s,
383−this is the last time we got a full update from the foreign ship.
384−
385−`ref` is the request manager for the desk. For domestic `desk`s, this is
386−null since we handle requests ourselves. For foreign `desk`s, this keeps track
387−of all pending foriegn requests plus a cache of the responses to previous requests.
388−
389−`qyx` is the `set` of subscriptions to this desk, with listening `duct`s. These
390−subscriptions exist only until they've been filled. For domestic `desk`s, this
391−is simply `qyx:dojo` - all subscribers to the `desk`. For foreign `desk`s this
392−is all the subscribers from our ship to the foreign `desk`.
393−
394−`dom` is the data in the `desk`.
395−
396−`regs` are `(map path rule)`, and so `per` is a `map` of read permissions by
397−`path` and `pew` is a `map` of write permissions by `path`.
398−
399−#### `$rind`, foreign request manager
400−
401−```hoon
402−+$ rind :: request manager
403− $: nix=@ud :: request index
404− bom=(map @ud update-state) :: outstanding
405− fod=(map duct @ud) :: current requests
406− haw=(map mood (unit cage)) :: simple cache
407− == ::
408−```
409−
410−This is the request manager for a foreign `desk`. When we send a request to a
411−foreign ship, we keep track of it in here.
412−
413−`nix` is one more than the index of the most recent request. Thus, it is the
414−next available request number.
415−
416−`bom` is the set of outstanding requests. The keys of this `map` are some subset
417−of the numbers between 0 and one less than `nix`. The members of the `map` are
418−exactly those requests that have not yet been fully satisfied.
419−
420−`fod` is the same set as `bom`, but from a different perspective. In particular,
421−the values of `fod` are the same as the keys of `bom`, and the `duct` of the
422−values of `bom` are the same as the keys of `fod`. Thus, we can map `duct`s to
423−their associated request number and `update-state`, and we can map request
424−numbers to their associated `duct`.
425−
426−`haw` is a map from `%sing` requests to their values. This acts as a cache for
427−requests that have already been filled.
428−
429−#### `$update-state`, status of outstanding foreign request
430−
431−```hoon
432−+$ update-state
433− $: =duct
434− =rave
435− have=(map lobe blob)
436− need=(list lobe)
437− nako=(qeu (unit nako))
438− busy=_|
439− ==
440−```
441−
442−An `update-state` is used to represent the status of an outstanding request to a
443−foreign `desk`.
444−
445−`duct` and `rave` are the `duct` along which the request was made and the
446−request itself.
447−
448−`have` is a map of hashes thus far acquired in the request to the data
449−associated with those hashes.
450−
451−`need` is a list of hashes yet to be acquired.
452−
453−`nako` is a queue of data yet to be validated.
454−
455−`busy` tracks whether or not the request is currently being fulfilled.
456−
457−#### `$rang:clay`, data repository
458−
459−```hoon
460− +$ rang :: repository
461− $: hut=(map tako yaki) :: changes
462− lat=(map lobe blob) :: data
463− == ::
464−```
465−
466−This is a data repository keyed by hash. Thus, this is where the "real" data
467−is stored, but it is only meaningful if we know the hash of what we're
468−looking for.
469−
470−`hut` is a `map` from commit hashes (`tako`s) to commits (`yaki`s). We often get
471−the hashes from `hit:dome`, which keys them by numerical id. Not every commit
472−has an numerical id.
473−
474−`lat` is a `map` from content hashes (`lobe`s) to the actual content (`blob`s).
475−We often get the hashes from a `yaki`, which references this `map` to get the
476−data. There is no `blob` in `yaki:clay`. They are only accessible through
477−`lat`.
478−
479−#### `$tako:clay`, commit reference
480−
481−```hoon
482− +$ tako @ :: yaki ref
483−```
484−
485−This is a hash of a `yaki:clay`, a commit. These are most notably used as the
486−keys in `hut:rang:clay`, where they are associated with the actual `yaki:clay`,
487−and as the values in `hit:dome:clay`, where sequential numerical ids are
488−associated with these.
489−
490−#### `$yaki:clay`, commit
491−
492−```hoon
493− +$ yaki :: commit
494− $: p=(list tako) :: parents
495− q=(map path lobe) :: namespace
496− r=tako :: self-reference
497− t=@da :: date
498− == ::
499−```
500−
501−This is a single commit.
502−
503−`p` is a `list` of the hashes of the parents of this commit. In most
504−cases, this will be a single commit, but in a merge there may be more
505−parents. In theory, there may be an arbitrary number of parents, but in
506−practice merges have exactly two parents. This may change in the future.
507−For commit 1, there is no parent.
508−
509−`q` is a `map` of the `path`s on a desk to the content hashes at that location.
510−If you understand what a `lobe:clay` and a `blob:clay` is, then the type
511−signature here tells the whole story.
512−
513−`r` is the hash associated with this commit.
514−
515−`t` is the date at which this commit was made.
516−
517−#### `$lobe:clay`, data reference
518−
519−```hoon
520− +$ lobe @uvI :: blob ref
521−```
522−
523−This is a hash of a `blob:clay`. These are most notably used in `lat:rang:clay`,
524−where they are associated with the actual `blob:clay`, and as the values in
525−`q:yaki:clay`, where `path`s are associated with their content hashes in a commit.
526−
527−#### `$blob:clay`, data
528−
529−```hoon
530− +$ blob :: fs blob
531− $% [%delta p=lobe q=[p=mark q=lobe] r=page] :: delta on q
532− [%direct p=lobe q=page] :: immediate
533−```
534−
535−This is a node of data. In both cases, `p` is the hash of the blob.
536−
537−`%delta` is the case where we define the data by a delta on other data. In
538−practice, the other data is always the previous commit, but nothing depends on
539−this. `p.q` is the `mark` of the parent blob, `q.q` is the hash of the parent
540−blob, and `r` is the delta.
541−
542−`%direct` is the case where we simply have the data directly. `q` is the data.
543−These almost always come from the creation of a file.
544−
545−#### `+urge`, list change
546−
547−```hoon
548− ++ urge |*(a=mold (list (unce a))) :: list change
549−```
550−
551−This is a parametrized type for list changes. For example, `(urge @t)`
552−is a list change for lines of text.
553−
554−#### `+unce`, change part of a list.
555−
556−```hoon
557− ++ unce :: change part
558− |* a=mold ::
559− $% [%& p=@ud] :: skip[copy]
560− [%| p=(list a) q=(list a)] :: p -> q[chunk]
561− == ::
562−```
563−
564−This is a single change in a list of elements of type `a`. For example,
565−`(unce @t)` is a single change in lines of text.
566−
567−`%&` means the next `p` lines are unchanged.
568−
569−`%|` means the lines `p` have changed to `q`.
570−
571−#### `$nori:clay`, repository action
572−
573−```hoon
574− +$ nori :: repository action
575− $% [%& p=soba] :: delta
576− [%| p=@tas] :: label
577− == ::
578−```
579−
580−This describes a change that we are asking Clay to make to the `desk`.
581−There are two kinds of changes that may be made: we can modify files or
582−we can apply a label to a commit.
583−
584−In the `|` case, we will simply label the current commit with the given
585−label. In the `&` case, we will apply the given changes.
586−
587−#### `$soba:clay`, delta
588−
589−```hoon
590− +$ soba (list [p=path q=miso]) :: delta
591−```
592−
593−This describes a `list` of changes to make to a `desk`. The `path`s are `path`s
594−to files to be changed, and the corresponding `miso` value is a description of
595−the change itself.
596−
597−#### `$miso:clay`, ankh delta
598−
599−```hoon
600− +$ miso :: ankh delta
601− $% [%del ~] :: delete
602− [%ins p=cage] :: insert
603− [%dif p=cage] :: mutate from diff
604− [%mut p=cage] :: mutate from raw
605− == ::
606−```
607−
608−There are four kinds of changes that may be made to a node in a `desk`.
609−
610−`%del` deletes the node.
611−
612−`%ins` inserts a file given by `p`.
613−
614−`%dif` is currently unimplemented. This may seem strange, so we remark that
615−diffs for individual files are implemented using `+diff` and `+pact` in `mark`s.
616−So for an `ankh`, which may include both files and directories, `%dif` being
617−unimplemented really just means that we do not yet have a formal concept of
618−changes in directory structure.
619−
620−`%mut` mutates the file using raw data given by `p`.
621−
622−#### `$riff:clay`, request/desist
623−
624−```hoon
625− +$ riff [p=desk q=(unit rave)] :: request+desist
626−```
627−
628−This represents a request for data about a particular `desk`. If `q`
629−contains a `rave`, then this opens a subscription to the `desk` for that
630−data. If `q` is null, then this tells Clay to cancel the subscription
631−along this duct.
632−
633−#### `$riot:clay`, response
634−
635−```hoon
636− +$ riot (unit rant) :: response+complete
637−```
638−
639−A `riot` is a response to a subscription. If null, the subscription has
640−been completed, and no more responses will be sent. Otherwise, the
641−`rant` is the produced data.
642−
643−#### `$rant:clay`, response data
644−
645−```hoon
646− +$ rant :: response to request
647− $: p=[p=care q=case r=desk] :: clade release book
648− q=path :: spur
649− r=cage :: data
650− == ::
651−```
652−
653−This is the data associated to the response to a request. `p.p` specifies
654−the type of data that was requested (and is produced). `q.p` gives the
655−specific version reported (since a range of versions may be requested in
656−a subscription). `r.p` is the `desk`. `q` is the path to the filesystem
657−node. `r` is the data itself (in the format specified by `p.p`).
658−
659−### `$nako`, subscription response data
660−
661−```hoon
662−+$ nako :: subscription state
663− $: gar=(map aeon tako) :: new ids
664− let=aeon :: next id
665− lar=(set yaki) :: new commits
666− bar=(set plop) :: new content
667− == ::
668−```
669−
670−This is the data that is produced by a request for a range of revisions
671−of a `desk`. This allows us to easily keep track of a remote repository --
672−all the new information we need is contained in the `nako`.
673−
674−`gar` is a map of the revisions in the range to the hash of the commit
675−at that revision. These hashes can be used with `hut:rang:clay` to find the
676−commit itself.
677−
678−`let` is either the last revision number in the range or the most recent
679−revision number, whichever is smaller.
680−
681−`lar` is the set of new commits, and `bar` is the set of new content.
content/docs/arvo/clay/examples.mddeleted−789
@@ -1,789 +0,0 @@
1−+++
2−title = "Examples"
3−weight = 7
4−template = "doc.html"
5−+++
6−
7−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) document.
8−
9−Most examples will either use `|pass` to just send a `task` or the following thread to send a `task` and take the resulting `gift`. You can save the following thread to the `ted` directory of the `%base` `desk` on a fake ship:
10−
11−`send-task-take-gift.hoon`
12−
13−```hoon
14−/- spider
15−/+ strandio
16−=, strand=strand:spider
17−^- thread:spider
18−|= arg=vase
19−=/ m (strand ,vase)
20−^- form:m
21−=/ uarg !< (unit task:clay) arg
22−?~ uarg
23− (strand-fail:strand %no-arg ~)
24−=/ =task:clay u.uarg
25−=/ =card:agent:gall [%pass /foo %arvo %c task]
26−;< ~ bind:m (send-raw-card:strandio card)
27−;< res=[wire sign-arvo] bind:m take-sign-arvo:strandio
28−~& +>:res
29−(pure:m !>(~))
30−```
31−
32−## `%warp`
33−
34−See the [Read and Subscribe](/docs/arvo/clay/tasks#warp---read-and-track) section of the [API Reference](/docs/arvo/clay/tasks) document for general details.
35−
36−### `%sing`
37−
38−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.
39−
40−Using the `send-task-take-gift.hoon` thread, let's try reading `gen/hood/hi.hoon`:
41−
42−```
43−> -send-task-take-gift [%warp our %base ~ %sing %x da+now /gen/hood/hi/hoon]
44−```
45−
46−You should see something like this as the output:
47−
48−```
49−[ %writ
50− p
51− [ ~
52− [ p=[p=%x q=[%da p=~2021.5.20..23.37.50..e79b] r=%base]
53− q=/gen/hood/hi/hoon
54− r
55− [ p=%hoon
56− q
57− [ #t/@
58− q
59− 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
60− ]
61− ]
62− ]
63− ]
64−]
65−```
66−
67−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:
68−
69−```
70−> -send-task-take-gift [%warp our %base ~ %sing %u da+now /gen/hood/hi/hoon]
71−[ %writ
72− p
73− [ ~
74− [ p=[p=%u q=[%da p=~2021.5.20..23.42.21..bb33] r=%base]
75− q=/gen/hood/hi/hoon
76− r=[p=%flag q=[#t/?(%.y %.n) q=0]]
77− ]
78− ]
79−]
80−```
81−
82−Here's a breakdown of the `task` we sent:
83−
84−![%sing diagram](https://media.urbit.org/docs/arvo/clay/sing.png "%sing diagram")
85−
86−### `%next`
87−
88−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.
89−
90−Using the `send-task-take-gift.hoon` thread, let's subscribe to the next version of `foo.txt`:
91−
92−```
93−> -send-task-take-gift [%warp our %base ~ %next %x da+now /foo/txt]
94−```
95−
96−Now, in unix, create a file called `foo.txt` in the root of the `base` directory of your ship. In the dojo, hit backspace to disconnect the thread from the dojo prompt and run `|commit %base`. You should see something like:
97−
98−```
99−> |commit %base
100−>=
101−[%writ p=[~ [p=[p=%x q=[%ud p=3] r=%base] q=/foo/txt r=[p=%txt q=[#t/*'' q=0]]]]]
102−+ /~zod/base/3/foo/txt
103−```
104−
105−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`.
106−
107−Now run the thread again, and this time delete the file in unix and again `|commit %base` in the dojo. You should see:
108−
109−```
110−> |commit %base
111−>=
112−[%writ p=~]
113−- /~zod/base/4/foo/txt
114−```
115−
116−You can see the `riot` is just `~` due to the file being deleted.
117−
118−Here's a breakdown of the task we sent:
119−
120−![%next diagram](https://media.urbit.org/docs/arvo/clay/next.png "%next diagram")
121−
122−### `%mult`
123−
124−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.
125−
126−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.
127−
128−`sub-mult.hoon`
129−
130−```hoon
131−/- spider
132−/+ strandio
133−=, strand=strand:spider
134−^- thread:spider
135−|= arg=vase
136−=/ m (strand ,vase)
137−^- form:m
138−=/ files=(set (pair care:clay path))
139− %- sy :~
140− [%x /foo/txt]
141− [%u /bar/txt]
142− ==
143−;< =bowl:strand bind:m get-bowl:strandio
144−=/ =task:clay [%warp our.bowl %base ~ %mult da+now.bowl files]
145−=/ =card:agent:gall [%pass /mult %arvo %c task]
146−;< ~ bind:m (send-raw-card:strandio card)
147−;< response=(pair wire sign-arvo) bind:m take-sign-arvo:strandio
148−~& +.q.response
149−(pure:m !>(~))
150−```
151−
152−Save the above to `ted/sub-mult.hoon`, `|commit %base` and run with `-sub-mult`. Now, create `foo.txt` and `bar.txt` in your base directory, hit backspace in the dojo to disconnect the thread and run `|commit %base`. You should see something like:
153−
154−```
155−> |commit %base
156−>=
157−[%wris p=[%da p=~2021.4.27..06.07.08..5ec4] q={[p=%u q=/bar/txt] [p=%x q=/foo/txt]}]
158−+ /~zod/base/151/foo/txt
159−+ /~zod/base/151/bar/txt
160−```
161−
162−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.
163−
164−Now, run the thread again, open `bar.txt` in an editor, modify its contents, save it and `|commit %base`. 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.
165−
166−Lastly, delete `foo.txt` and `|commit %base`. You should see something like:
167−
168−```
169−> |commit %base
170−>=
171−[%wris p=[%da p=~2021.4.27..06.15.03..0da4] q={[p=%x q=/foo/txt]}]
172−- /~zod/base/153/foo/txt
173−```
174−
175−As you can see, a relevant change to any of the subscribed files will trigger a response, not just when all of them change.
176−
177−Here's a breakdown of the `task` we sent:
178−
179−![subscribe mult diagram](https://media.urbit.org/docs/arvo/clay/sub-mult.png "subscribe mult diagram")
180−
181−### `%many`
182−
183−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.
184−
185−This thread will subscribe to changes to your `%base` `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.
186−
187−`sub-many.hoon`
188−
189−```hoon
190−/- spider
191−/+ strandio
192−=, strand=strand:spider
193−|%
194−++ take-sign-loop
195− =/ m (strand ,~)
196− ^- form:m
197− %- (main-loop:strandio ,~)
198− :~ |= ~
199− ^- form:m
200− ;< res=(pair wire sign-arvo)
201− bind:m
202− ((handle:strandio ,(pair wire sign-arvo)) take-sign-arvo:strandio)
203− ~& res
204− (pure:m ~)
205− ==
206−--
207−^- thread:spider
208−|= arg=vase
209−=/ m (strand ,vase)
210−^- form:m
211−=/ uarg !< (unit path) arg
212−?~ uarg
213− (strand-fail:strand %no-arg ~)
214−=/ =path u.uarg
215−;< =bowl:strand bind:m get-bowl:strandio
216−=/ =task:clay [%warp our.bowl %base ~ %many %.y da+now.bowl da+(add ~m3 now.bowl) path]
217−=/ =card:agent:gall [%pass /many %arvo %c task]
218−;< ~ bind:m (send-raw-card:strandio card)
219−;< ~ bind:m take-sign-loop
220−(pure:m !>(~))
221−```
222−
223−Make sure `foo.txt` doesn't exist in the root of your `%base` `desk`. Save this to `ted/sub-many.hoon`, `|commit %base`, 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 %base`. You should see something like:
224−
225−```
226−> |commit %base
227−>=
228−+ /~zod/base/260/bar/txt
229−```
230−
231−Notice you've received no `%writ` from Clay. This is because `/foo/txt` doesn't exist. Now, create `foo.txt` and `|commit %base` again. You should see:
232−
233−```
234−> |commit %base
235−>=
236−[ p=/many
237− q=[%clay [%writ p=[~ [p=[p=%w q=[%ud p=261] r=%base] q=/ r=[p=%null q=[#t/@n q=0]]]]]]
238−]
239−+ /~zod/base/261/foo/txt
240−```
241−
242−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.
243−
244−Now try adding `baz.txt`:
245−
246−```
247−> |commit %base
248−>=
249−[ p=/many
250− q=[%clay [%writ p=[~ [p=[p=%w q=[%ud p=262] r=%base] q=/ r=[p=%null q=[#t/@n q=0]]]]]]
251−]
252−+ /~zod/base/262/baz/txt
253−```
254−
255−Now wait until the three minutes is up and try making a change, for example deleting `baz.txt`:
256−
257−```
258−> |commit %base
259−>=
260−[ p=/many
261− q=[%clay [%writ p=[~ [p=[p=%w q=[%ud p=264] r=%base] q=/ r=[p=%null q=[#t/@n q=0]]]]]]
262−]
263−[p=/many q=[%clay [%writ p=~]]]
264−- /~zod/base/263/baz/txt
265−```
266−
267−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.
268−
269−Run `:spider|kill` to stop the thread.
270−
271−Here's a breakdown of the `task` we sent:
272−
273−![subscribe many diagram](https://media.urbit.org/docs/arvo/clay/sub-many.png "subscribe many diagram")
274−
275−### Cancel Subscription
276−
277−Here we'll look at cancelling a subscription by sending Clay a `%warp` `task` with a null `(unit rave)` in the `riff`.
278−
279−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).
280−
281−`stop-sub.hoon`
282−
283−```hoon
284−/- spider
285−/+ strandio
286−=, strand=strand:spider
287−^- thread:spider
288−|= arg=vase
289−=/ m (strand ,vase)
290−^- form:m
291−;< =bowl:strand bind:m get-bowl:strandio
292−=/ =task:clay [%warp our.bowl %base ~ %next %x da+now.bowl /foo/txt]
293−=/ =card:agent:gall [%pass /next %arvo %c task]
294−;< ~ bind:m (send-raw-card:strandio card)
295−=. task [%warp our.bowl %base ~]
296−=. card [%pass /next %arvo %c task]
297−;< ~ bind:m (send-raw-card:strandio card)
298−;< =riot:clay bind:m (take-writ:strandio /next)
299−~& riot
300−(pure:m !>(~))
301−```
302−
303−Save the above to `ted/stop-sub.hoon`, `|commit %base`, run it with `-stop-sub` and hit backspace to detach it from the dojo prompt. Now, add `foo.txt` to the root of your `%base` `desk` and `|commit %base`. You should see:
304−
305−```
306−> |commit %base
307−>=
308−+ /~zod/base/266/foo/txt
309−```
310−
311−As you can see we've received no `%writ`. We can thus conclude the subscription has successfully been cancelled.
312−
313−Run `:spider|kill` to stop the thread.
314−
315−Here's a breakdown of the `task` we sent:
316−
317−![cancel subscription diagram](https://media.urbit.org/docs/arvo/clay/stop-sub.png "cancel subscription diagram")
318−
319−## `%info`
320−
321−See the [Write and Modify](/docs/arvo/clay/tasks#write-and-modify) section of the [API Reference](/docs/arvo/clay/tasks) document for general details.
322−
323−### `%ins`
324−
325−Here we'll look at adding a file by sending Clay a `%info` `task` containing a `%ins` `miso`.
326−
327−Let's try adding a `foo.txt` file with 'foo' as its contents:
328−
329−```
330−> |pass [%c [%info %base %& [/foo/txt %ins %txt !>(~['foo'])]~]]
331−+ /~zod/base/5/foo/txt
332−```
333−
334−If you have a look in the base of your pier you'll see there's now a file called `foo.txt` with the text `foo` in it.
335−
336−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`.
337−
338−Here's a breakdown of the `task` we sent:
339−
340−![%ins diagram](https://media.urbit.org/docs/arvo/clay/ins.png)
341−
342−### `%del`
343−
344−Here we'll look at deleting a file by sending Clay a `%info` `task` containing a `%del` `miso`.
345−
346−Let's try deleting the `foo.txt` file created in the [previous example](#ins):
347−
348−```
349−> |pass [%c [%info %base %& [/foo/txt %del ~]~]]
350−- /~zod/base/6/foo/txt
351−```
352−
353−If you have a look in the base of your pier you'll see the `foo.txt` file is now gone.
354−
355−Here's a breakdown of the `task` we sent:
356−
357−![%del diagram](https://media.urbit.org/docs/arvo/clay/del.png)
358−
359−### `%mut`
360−
361−Identical to the [%ins](#ins) example, just replace `%ins` with `%mut`.
362−
363−### Multiple Changes
364−
365−Here we'll look at changing multiple files in one request by sending Clay a `%info` `task` containing multiple `miso` in the `soba`.
366−
367−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.
368−
369−`multi-change.hoon`
370−
371−```hoon
372−/- spider
373−/+ strandio
374−=, strand=strand:spider
375−^- thread:spider
376−|= arg=vase
377−=/ m (strand ,vase)
378−^- form:m
379−=/ soba-a :~ [/foo/txt %ins %txt !>(['foo' ~])]
380− [/bar/txt %ins %txt !>(['bar' ~])]
381− [/baz/txt %ins %txt !>(['baz' ~])]
382− ==
383−=/ soba-b :~ [/foo/txt %del ~]
384− [/bar/txt %del ~]
385− [/baz/txt %del ~]
386− ==
387−;< ~ bind:m (send-raw-card:strandio [%pass /info %arvo %c %info %base %& soba-a])
388−;< ~ bind:m (send-raw-card:strandio [%pass /info %arvo %c %info %base %& soba-b])
389−(pure:m !>(~))
390−```
391−
392−Save to `ted/multi-change.hoon`, `|commit %base`, and run:
393−
394−```
395−> -multi-change
396−+ /~zod/base/37/foo/txt
397−+ /~zod/base/37/bar/txt
398−+ /~zod/base/37/baz/txt
399−- /~zod/base/38/foo/txt
400−- /~zod/base/38/bar/txt
401−- /~zod/base/38/baz/txt
402−```
403−
404−## Manage Mounts
405−
406−See the [Manage Mounts](/docs/arvo/clay/tasks#manage-mounts) section of the [API Reference](/docs/arvo/clay/tasks) document for general details.
407−
408−### `%boat`
409−
410−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`.
411−
412−Using the `send-task-take-gift.hoon` thread, let's make such a request:
413−
414−```
415−> -send-task-take-gift [%boat ~]
416−[%hill p=~[%base]]
417−```
418−
419−### `%mont`
420−
421−Here we'll look at mounting `desk`s, directories and files to unix by sending Clay a `%mont` `task`.
422−
423−Let's first try mounting our `%garden` desk:
424−
425−```
426−> |pass [%c [%mont %garden [our %garden da+now] /]]
427−```
428−
429−If you look in your pier, you should now see a `garden` folder which contains the contents of that `desk`.
430−
431−If we make a `%boat` request as detailed in the [%boat](#boat) section, we'll now see the mount point listed:
432−
433−```
434−> -send-task-take-gift [%boat ~]
435−[%hill p=~[%garden %base]]
436−```
437−
438−Note the mount point doesn't need to match a `desk`, file or directory. We can also do:
439−
440−```
441−> |pass [%c [%mont %wibbly-wobbly [our %base da+now] /]]
442−```
443−
444−And you'll now see that there's a `wibbly-wobbly` folder with the contents of the `%base` `desk`. You'll also notice we can mount the same file or directory more than once. There's no problem having `%base` mounted to both `base` and `wibbly-wobbly`. The only requirement is that their mount points be unique.
445−
446−Let's try mounting a subdirectory and a single folder:
447−
448−```
449−> |pass [%c [%mont %gen [our %base da+now] /gen]]
450−> |pass [%c [%mont %hi [our %base da+now] /gen/hood/hi]]
451−```
452−
453−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.
454−
455−### `%ogre`
456−
457−Here we'll look at unmounting `desk`s, directories and files by sending Clay a `%ogre` `task`.
458−
459−Let's unmount what we mounted in the [%mont](#mont) section. First we'll unmount the `%garden` desk:
460−
461−```
462−|pass [%c [%ogre %garden]]
463−```
464−
465−Our custom mount point `%wibbly-wobbly`:
466−
467−```
468−|pass [%c [%ogre %wibbly-wobbly]]
469−```
470−
471−And the single `hi.hoon` we previously mounted by specifying its mount point `%hi`:
472−
473−```
474−|pass [%c [%ogre %hi]]
475−```
476−
477−If we specify a non-existent mount point it will fail with an error printed to the dojo like:
478−
479−```
480−> |pass [%c [%ogre %foo]]
481−[%not-mounted %foo]
482−```
483−
484−If we give it an unmounted `beam` it will not print an error but still won't work.
485−
486−### `%dirk`
487−
488−Here we'll look at committing changed files by sending Clay a `%dirk` `task`.
489−
490−This `task` performs the same function as the `|commit` dojo command.
491−
492−With your `%base` `desk` mounted, try adding a file and send a `%dirk` to commit the change:
493−
494−```
495−> |pass [%c [%dirk %base]]
496−+ /~zod/base/12/foo/txt
497−```
498−
499−Clay will print the changed files to the dojo with a leading `+`, `-` or `:` to indicate a new file, deleted file and changed file respectively.
500−
501−If you have the same `desk` mounted to multiple points, a committed change in one mount will also update the others.
502−
503−## Merge Desks
504−
505−See the [Merge Desks](/docs/arvo/clay/tasks#merge-desks) section of the [API Reference](/docs/arvo/clay/tasks) document for general details.
506−
507−### `%merg`
508−
509−Here we'll look at merging `desk`s by sending Clay a `%merg` `task` and receiving a `%mere` `gift` in response.
510−
511−First, using the `send-task-take-gift.hoon` thread, let's try creating a new `desk`:
512−
513−```
514−> -send-task-take-gift [%merg %foo our %base da+now %init]
515−[%mere p=[%.y p={}]]
516−```
517−
518−Now if we scry for our `desk`s we'll see `%foo` is there:
519−
520−{% customFence %}
521−
522−> .^((set desk) %cd /===)
523−> &#x7B;&#x25;bitcoin %base %landscape %webterm %garden %foo}
524−> {% /customFence %}
525−
526−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.
527−
528−Now we'll try merging `%base` into `%foo` with a `%mate` strategy:
529−
530−```
531−> -send-task-take-gift [%merg %foo our %base da+now %mate]
532−[ /foo
533− [ %clay
534− [ %mere
535− p
536− [ %.n
537− p
538− [ p=%mate-conflict
539− q=~[[%rose p=[p="/" q="/" r=""] q=[i=[%leaf p="foo"] t=[i=[%leaf p="txt"] t=~]]]]
540− ]
541− ]
542− ]
543− ]
544−]
545−```
546−
547−As you can see, the merge has failed. Let's try again with a `%meld` strategy:
548−
549−```
550−> -send-task-take-gift [%merg %foo our %base da+now %meld]
551−[/foo [%clay [%mere p=[%.y p={/foo/txt}]]]]
552−```
553−
554−Now the merge has succeeded and the `%mere` notes the file with a merge conflict. If we try with a `%only-that` strategy:
555−
556−```
557−> -send-task-take-gift [%merg %foo our %base da+now %only-that]
558−[/foo [%clay [%mere p=[%.y p={}]]]]
559−: /~zod/foo/6/foo/txt
560−```
561−
562−...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.
563−
564−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:
565−
566−```
567−> -send-task-take-gift [%merg %foo our %base da+(add ~m2 now) %only-that]
568−```
569−
570−Now change the text in the `foo.txt` in the `%base` `desk`, hit backspace to detach the thread and `|commit %base`. After the two minutes pass you should see:
571−
572−```
573−[/foo [%clay [%mere p=[%.y p={}]]]]
574−: /~zod/foo/7/foo/txt
575−```
576−
577−You can also specify it by revision number or label.
578−
579−## Permissions
580−
581−See the [Permissions](/docs/arvo/clay/tasks#permissions) section of the [API Reference](/docs/arvo/clay/tasks) document for general details.
582−
583−### `%perm`
584−
585−Here we'll look at setting permissions by sending Clay a `%perm` `task`.
586−
587−First, let's allow `~nes` to read `/gen/hood/hi/hoon`:
588−
589−```
590−> |pass [%c [%perm %base /gen/hood/hi/hoon %r ~ %white (sy [%.y ~nes]~)]]
591−```
592−
593−...and we'll do a `%p` scry to see that the permission was set:
594−
595−```
596−> .^([r=dict:clay w=dict:clay] %cp /===/gen/hood/hi/hoon)
597−[r=[src=/gen/hood/hi/hoon rul=[mod=%white who=[p={~nes} q={}]]] w=[src=/ rul=[mod=%white who=[p={} q={}]]]]
598−```
599−
600−You can see that `~nes` is now in the read whitelist. Next, let's try a write permission:
601−
602−```
603−> |pass [%c [%perm %base /ted %w ~ %white (sy [%.y ~nes]~)]]
604−```
605−
606−You can see `~nes` can now write to `/ted`:
607−
608−```
609−> .^([r=dict:clay w=dict:clay] %cp /===/ted)
610−[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/ted rul=[mod=%white who=[p={~nes} q={}]]]]
611−```
612−
613−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:
614−
615−```
616−> .^([r=dict:clay w=dict:clay] %cp /===/ted/aqua/ames/hoon)
617−[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/ted rul=[mod=%white who=[p={~nes} q={}]]]]
618−```
619−
620−...and you'll notice that `src` tells us it's inherited the rule from `/ted`.
621−
622−Now let's try setting both read and write permissions:
623−
624−```
625−> |pass [%c [%perm %base /gen/help/hoon %rw `[%black (sy [%.y ~nes]~)] `[%white (sy [%.y ~nes]~)]]]
626−```
627−
628−```
629− .^([r=dict:clay w=dict:clay] %cp /===/gen/help/hoon)
630−[r=[src=/gen/help/hoon rul=[mod=%black who=[p={~nes} q={}]]] w=[src=/gen/help/hoon rul=[mod=%white who=[p={~nes} q={}]]]]
631−```
632−
633−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`.
634−
635−For example, to remove a read permission (or write if you specify `%w`):
636−
637−```
638−> |pass [%c [%perm %base /gen/help/hoon %r ~]]
639−```
640−
641−```
642−> .^([r=dict:clay w=dict:clay] %cp /===/gen/help/hoon)
643−[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/gen/help/hoon rul=[mod=%white who=[p={~nes} q={}]]]]
644−```
645−
646−...and to remove both read and write at the same time:
647−
648−```
649−> |pass [%c [%perm %base /gen/help/hoon %rw ~ ~]]
650−```
651−
652−```
653−> .^([r=dict:clay w=dict:clay] %cp /===/gen/help/hoon)
654−[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/ rul=[mod=%white who=[p={} q={}]]]]
655−```
656−
657−As you can see it's back to the default inherited from `/`.
658−
659−Here's a breakdown of a `%perm` task:
660−
661−![perm diagram](https://media.urbit.org/docs/arvo/clay/perm-diagram.png)
662−
663−### `%cred`
664−
665−Here we'll look at creating a permission group by sending Clay a `%cred` `task`.
666−
667−Let's create a group called `'foo'` with a few ships:
668−
669−```
670−|pass [%c [%crew 'foo' (sy ~[~zod ~nec ~bud ~wes ~sev])]]
671−```
672−
673−We'll check it with the next kind of `task`: [%crew](#crew).
674−
675−### `%crew`
676−
677−Here we'll look at retrieving permission groups by sending Clay a `%crew` `task` and receiving a `%cruz` `gift` in response.
678−
679−Let's check, using the `send-task-take-gift.hoon` thread, for the permission group created in the [%cred](#cred) example:
680−
681−```
682−> -send-task-take-gift [%crew ~]
683−[%cruz cez={[p=~.foo q={~nec ~bud ~wes ~zod ~sev}]}]
684−```
685−
686−### `%crow`
687−
688−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.
689−
690−First we'll set a couple of permissions for the `foo` group we created in the [%cred](#cred) section:
691−
692−```
693−> |pass [%c [%perm %base /gen/hood/hi/hoon %w ~ %white (sy [%.n 'foo']~)]]
694−> |pass [%c [%perm %base /ted %w ~ %white (sy [%.n 'foo']~)]]
695−```
696−
697−Notice we use a `%.n` in the `whom` to indicate a group rather than the `%.y` of a ship.
698−
699−Now we'll use the `send-task-take-gift.hoon` thread to try `%crow`:
700−
701−```
702−> -send-task-take-gift [%crow 'foo']
703−[ %croz
704− rus
705− { [ p=%base
706− q
707− [ r={}
708− w
709− { [p=/gen/hood/hi/hoon q=[mod=%white who={[%.n p=~.foo]}]]
710− [p=/ted q=[mod=%white who={[%.n p=~.foo]}]]
711− }
712− ]
713− ]
714− }
715−]
716−```
717−
718−## Foreign Ships
719−
720−See the [Foreign Ships](/docs/arvo/clay/tasks#foreign-ships) section of the [API Reference](/docs/arvo/clay/tasks) document for general details.
721−
722−### `%warp` - Remote
723−
724−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.
725−
726−We'll use a fake `~nes` as the the foreign ship and a fake `~zod` as the local ship.
727−
728−First we'll set permissions on the foreign ship. Create a file called `foo.txt` in the `%base` of ~nes, then send a `%perm` request to allow ~zod to read and write the file:
729−
730−```
731−> |pass [%c [%perm %base /foo/txt %rw `[%white (sy [%.y ~zod]~)] `[%white (sy [%.y ~zod]~)]]]
732−```
733−
734−If we scry the file for its permissions with a `%p` `care`, we'll see `~zod` is now whitelisted:
735−
736−```
737−> .^([r=dict:clay w=dict:clay] %cp /===/foo/txt)
738−[r=[src=/foo/txt rul=[mod=%white who=[p={~zod} q={}]]] w=[src=/foo/txt rul=[mod=%white who=[p={~zod} q={}]]]]
739−```
740−
741−Back on `~zod`: Using the `send-task-take-gift.hoon` thread, send a `%x` read request for `/foo/txt` on ~nes like:
742−
743−```
744−> -send-task-take-gift [%warp ~nes %base ~ %sing %x da+now /foo/txt]
745−[ %writ
746− p
747− [ ~
748− [ p=[p=%x q=[%da p=~2021.5.3..08.24.22..9ce7] r=%base]
749− q=/foo/txt
750− r=[p=%txt q=[#t/txt=*'' q=[7.303.014 0]]]
751− ]
752− ]
753−]
754−```
755−
756−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`:
757−
758−```
759−> -send-task-take-gift [%warp ~nes %base ~ %sing %u da+now /foo/txt]
760−[ %writ
761− p
762− [ ~
763− [ p=[p=%u q=[%da p=~2021.5.3..08.26.32..88cf] r=%base]
764− q=/foo/txt
765− r=[p=%flag q=[#t/?(%.y %.n) q=0]]
766− ]
767− ]
768−]
769−```
770−
771−If we send a `%d` request however, it will crash:
772−
773−```
774−> -send-task-take-gift [%warp ~nes %base ~ %sing %d da+now /foo/txt]
775−call: failed
776−/sys/vane/clay/hoon:<[4.085 3].[4.314 5]>
777−...
778−/sys/vane/clay/hoon:<[1.365 7].[1.365 51]>
779−[ %clay-bad-foreign-request-care
780− [%sing mood=[care=%d case=[%da p=~2021.5.3..20.04.57..1092] path=/foo/txt]]
781−]
782−/sys/vane/clay/hoon:<[1.365 48].[1.365 50]>
783−```
784−
785−### `%merg` - Remote
786−
787−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.
788−
789−The foreign ship will respond only if correct permissions have been set. See the [%perm](#perm) section for an example.
content/docs/arvo/clay/marks/_index.mddeleted−23
@@ -1,23 +0,0 @@
1−+++
2−title = "Marks"
3−weight = 10
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−insert_anchor_links = "right"
7−+++
8−
9−[Overview](/docs/arvo/clay/marks/marks)
10−
11−Overview of `mark`s.
12−
13−[Writing Marks](/docs/arvo/clay/marks/writing-marks)
14−
15−A practical walkthrough of writing a `mark` file.
16−
17−[Using Marks](/docs/arvo/clay/marks/using-marks)
18−
19−Details of using `mark` conversion gates and `mark` cores in your own code.
20−
21−[Examples](/docs/arvo/clay/marks/examples)
22−
23−The example code used in the Writing Marks guide.
content/docs/arvo/clay/marks/examples.mddeleted−248
@@ -1,248 +0,0 @@
1−+++
2−title = "Examples"
3−weight = 4
4−template = "doc.html"
5−+++
6−
7−These are the files used in the [Writing Marks](/docs/arvo/clay/marks/writing-marks) guide.
8−
9−## `/lib/csv/hoon`
10−
11−```hoon
12−|%
13−++ validate :: All rows same length?
14− |= csv=(list (list @t))
15− ^- ?
16− =/ result
17− %+ roll csv
18− |= [row=(list @t) =flag ref=(unit @ud)]
19− ?. flag
20− [flag ref]
21− ?~ ref
22− [flag `(lent row)]
23− ?. =(u.ref (lent row))
24− [%.n ref]
25− [flag ref]
26− flag.result
27−++ en-csv :: csv -> atom (to mime)
28− |= csv=(list (list @t))
29− |^ ^- @t
30− (cat 3 (crip (join '\0a' (turn csv en-row))) '\0a')
31− ++ en-row :: encode row
32− |= row=(list @t)
33− ^- @t
34− (crip (join ',' (turn row en-field)))
35− ++ en-field :: encode field
36− |= field=@t
37− ^- @t
38− %+ rash
39− field
40− %+ cook
41− |= =tape
42− ^- @t
43− ?~ tape ''
44− ?: =('"' i.tape)
45− (cat 3 (crip tape) '"')
46− (crip tape)
47− ;~ pose
48− (full (star ;~(less (mask "\",\0a\0d") next)))
49− ;~ plug
50− (easy '"')
51− (star ;~(pose (cold '""' doq) next))
52− ==
53− ==
54− --
55−++ de-csv :: atom -> csv (from mime)
56− |= dat=@t
57− |^ ^- (list (list @t))
58− =/ parsed (parse dat)
59− ?. (validate parsed)
60− ~|(%mixed-col-count !!)
61− parsed
62− ++ parse :: parse cord
63− |= dat=@t
64− |^ ^- (list (list @t))
65− %+ rash
66− dat
67− %+ most
68− ;~(pose (jest '\0d\0a') (mask "\0a\0d"))
69− (most com parse-field)
70− ++ parse-field :: parse field from cord
71− |^
72− %+ cook
73− |=(a=tape (crip a))
74− ;~(pose unenclosed enclosed)
75− ++ unenclosed :: unquoted field
76− ;~ sfix
77− (star ;~(less (mask "\",\0a\0d") next))
78− ;~ pose
79− ;~ plug
80− ;~(pose (jest '\0d\0a') (mask "\0a\0d"))
81− ;~(less next (easy ~))
82− ==
83− ;~(less doq (easy ~))
84− ==
85− ==
86− ++ enclosed :: quoted field
87− |^
88− ;~ sfix
89− (ifix [prefix suffix] content)
90− ;~ pose
91− ;~(simu (mask ",\0a\0d") (easy ~))
92− ;~ plug
93− ;~(pose (jest '\0d\0a') (mask "\0a\0d"))
94− ;~(less next (easy ~))
95− ==
96− ;~(less next (easy ~))
97− ==
98− ==
99− ++ content :: quoted field contents
100− %- star
101− ;~ pose
102− (cold '"' (jest '""'))
103− %+ cold '\0a'
104− ;~(pose (jest '\0d\0a') (just '\0d'))
105− ;~(less doq next)
106− ==
107− ++ prefix ;~(pose ;~(plug (star ace) doq) doq) :: quoted field prefix
108− ++ suffix ;~(pose ;~(plug doq (star ace)) doq) :: quoted field suffix
109− --
110− --
111− --
112− --
113−++ csv-join
114− |= [ali=(urge:clay (list @t)) bob=(urge:clay (list @t))]
115− ^- (unit (urge:clay (list @t)))
116− |^
117− =. ali (clean ali)
118− =. bob (clean bob)
119− |- ^- (unit (urge:clay (list @t)))
120− ?~ ali `bob
121− ?~ bob `ali
122− ?- -.i.ali
123− %&
124− ?- -.i.bob
125− %&
126− ?: =(p.i.ali p.i.bob)
127− %+ bind $(ali t.ali, bob t.bob)
128− |=(cud=(urge:clay (list @t)) [i.ali cud])
129− ?: (gth p.i.ali p.i.bob)
130− %+ bind $(p.i.ali (sub p.i.ali p.i.bob), bob t.bob)
131− |=(cud=(urge:clay (list @t)) [i.bob cud])
132− %+ bind $(ali t.ali, p.i.bob (sub p.i.bob p.i.ali))
133− |=(cud=(urge:clay (list @t)) [i.ali cud])
134− ::
135− %|
136− ?: =(p.i.ali (lent p.i.bob))
137− %+ bind $(ali t.ali, bob t.bob)
138− |=(cud=(urge:clay (list @t)) [i.bob cud])
139− ?: (gth p.i.ali (lent p.i.bob))
140− %+ bind $(p.i.ali (sub p.i.ali (lent p.i.bob)), bob t.bob)
141− |=(cud=(urge:clay (list @t)) [i.bob cud])
142− ~
143− ==
144− ::
145− %|
146− ?- -.i.bob
147− %|
148− ?. =(i.ali i.bob)
149− ~
150− %+ bind $(ali t.ali, bob t.bob)
151− |=(cud=(urge:clay (list @t)) [i.ali cud])
152− ::
153− %&
154− ?: =(p.i.bob (lent p.i.ali))
155− %+ bind $(ali t.ali, bob t.bob)
156− |=(cud=(urge:clay (list @t)) [i.ali cud])
157− ?: (gth p.i.bob (lent p.i.ali))
158− %+ bind $(ali t.ali, p.i.bob (sub p.i.bob (lent p.i.ali)))
159− |=(cud=(urge:clay (list @t)) [i.ali cud])
160− ~
161− ==
162− ==
163− ++ clean :: clean
164− |= wig=(urge:clay (list @t))
165− ^- (urge:clay (list @t))
166− ?~ wig ~
167− ?~ t.wig wig
168− ?: ?=(%& -.i.wig)
169− ?: ?=(%& -.i.t.wig)
170− $(wig [[%& (add p.i.wig p.i.t.wig)] t.t.wig])
171− [i.wig $(wig t.wig)]
172− ?: ?=(%| -.i.t.wig)
173− $(wig [[%| (welp p.i.wig p.i.t.wig) (welp q.i.wig q.i.t.wig)] t.t.wig])
174− [i.wig $(wig t.wig)]
175− --
176−--
177−```
178−
179−## `/mar/csv/hoon`
180−
181−```hoon
182−/+ *csv
183−|_ csv=(list (list @t))
184−++ grab
185− |%
186− ++ mime |=((pair mite octs) (de-csv q.q))
187− ++ noun
188− |= n=*
189− ^- (list (list @t))
190− =/ result ((list (list @t)) n)
191− ?> (validate result)
192− result
193− --
194−++ grow
195− |%
196− ++ mime
197− ?> (validate csv)
198− [/text/csv (as-octs:mimes:html (en-csv csv))]
199− ++ noun
200− ?> (validate csv)
201− csv
202− --
203−++ grad
204− |%
205− ++ form %csv-diff
206− ++ diff
207− |= bob=(list (list @t))
208− ^- (urge:clay (list @t))
209− ?> (validate csv)
210− ?> (validate bob)
211− (lusk:differ csv bob (loss:differ csv bob))
212− ++ pact
213− |= dif=(urge:clay (list @t))
214− ^- (list (list @t))
215− =/ result (lurk:differ csv dif)
216− ?> (validate result)
217− result
218− ++ join
219− |= $: ali=(urge:clay (list @t))
220− bob=(urge:clay (list @t))
221− ==
222− ^- (unit (urge:clay (list @t)))
223− (csv-join ali bob)
224− ++ mash
225− |= $: [ship desk (urge:clay (list @t))]
226− [ship desk (urge:clay (list @t))]
227− ==
228− ^- (urge:clay (list @t))
229− ~|(%csv-mash !!)
230− --
231−--
232−```
233−
234−## `/mar/csv-diff/hoon`
235−
236−```hoon
237−|_ dif=(urge:clay (list @t))
238−++ grab
239− |%
240− ++ noun (urge:clay (list @t))
241− --
242−++ grow
243− |%
244− ++ noun dif
245− --
246−++ grad %noun
247−--
248−```
content/docs/arvo/clay/marks/marks.mddeleted−59
@@ -1,59 +0,0 @@
1−+++
2−title = "Overview"
3−weight = 1
4−template = "doc.html"
5−+++
6−
7−Clay is a typed filesystem, and we call these file types `mark`s. When talking about Hoon and Arvo we'll often talk of types like `@ud`, `(list @t)`, etc. A `mark` will specify such a type for its files, but it does more than just that - it also defines conversion routines to and from other `mark`s, as well as diff, patch, and merge routines.
8−
9−For example, a `%txt` `mark` defines the type of a `%txt` file as a `wain` (a `(list @t)`). It defines a conversion function to a `%mime` `mark` to allow it to be serialized and sent to a browser or to the Unix filesystem. It also includes Hunt-McIlroy diff, patch, and merge algorithms. Conversion functions will be different for different `mark`s, as will things like diff algorithms. An image file like a `%png`, for example, just replaces the old blob of data with the new one rather than implementing a complex binary diff and patch algorithm, so how these functions are implemented depends on the file type and use case.
10−
11−`mark` files are stored in the `/mar` directory. The `path` of the `%txt` `mark`, for example, is `/mar/txt/hoon`.
12−
13−A `mark` is a door (a core with a sample) with three arms: `+grab`, `+grow`, and `+grad`. The door's sample defines its type. In `+grab` is a series of functions to convert from other `mark`s to the given `mark`. In `+grow` is a series of functions to convert from the given `mark` to other `mark`s. In `+grad` is `+diff`, `+pact`, `+join`, `+mash`, and `+form`.
14−
15−Here's its basic structure in an informal pseudocode:
16−
17−```
18−|_ <mark-type>
19−++ grab:
20− ++ noun: <noun> -> <mark-type>
21− ++ mime: <mime> -> <mark-type>
22− ++ txt: <txt> -> <mark-type>
23− ...
24−++ grow:
25− ++ noun: <mark-type> -> <noun>
26− ++ mime: <mark-type> -> <mime>
27− ++ txt: <mark-type> -> <txt>
28− ...
29−++ grad
30− ++ form: <diff-mark>
31− ++ diff: (<mark-type>, <mark-type>) -> <diff-type>
32− ++ pact: (<mark-type>, <diff-type>) -> <mark-type>
33− ++ join: (<diff-type>, <diff-type>) -> <diff-type> or NULL
34− ++ mash: (<diff-type>, <diff-type>) -> <diff-type>
35−```
36−
37−These types are basically what you would expect. In `+grab`, only a `+noun` arm is mandatory, the rest are optional. The `+grow` arm itself is optional, as are any arms within it. In `+grad`, all arms are mandatory unless revision control is delegated to another `mark`, which we'll discuss later.
38−
39−In general, for a particular `mark`, the `+grab` and `+grow` entries should be inverses of each other. They needn't be symmetrical though - you may want to be able to convert from your `mark` to `%json` but not from `%json` to your `mark`, for example.
40−
41−In `+grad`, `+diff` takes two instances of a `mark` and produces a diff of them whose `mark` is given by `+form`. `+pact` takes an instance of a `mark` and patches it with the given diff. In general, if `+diff` called with A and B produces diff D, then `+pact` called with A and D should produce B.
42−
43−`+join` takes two diffs and attempts to merge them into a single diff. If there are conflicts, it produces null. `+mash` takes two diffs and forces a merge, even if there are conflicts. How your `+mash` function force-merges conflicting diffs is up to you. The `%txt` `mark` annotates any conflicts, for example, but there may be other ways. If `+join` of two diffs does not produce null, then `+mash` of the same diffs should produce the same result. Note that `+mash` is not used by Clay in its ordinary filesystem operations, so you may wish to leave it as a dummy arm that crashes if called.
44−
45−Alternately, instead of `+form`, `+diff`, `+pact`, `+join`, and `+mash`, a `mark` can provide the same functionality by defining `+grad` to be the name of another `mark` to which we wish to delegate the revision control responsibilities. Then, before running any of those functions, Clay will convert to the other `mark`, and convert back afterward. For example, the `%hoon` `mark` is revision-controlled in the same way as `%txt`, so its `+grad` is simply `++ grad %txt`. Of course, `+txt` must be defined in `+grow` and `+grab` as well.
46−
47−We mentioned that `+noun` is the only mandatory arm in `+grab`, but there are a couple of others that, while not mandatory, are of particular interest.
48−
49−The first is a `+mime` arm for converting to and from the `%mime` `mark`. When you `|commit` a file to a `desk` mounted to Unix, Clay will receive the data as a `%mime` `mark`, and then convert it to the `mark` matching the file extension. It will perform the same operation in reverse when mounting a `desk` to Unix. For this reason, any `mark` you wish to be able to access from the Unix filesystem should have `%mime` conversion routines. In certain cases (such as the scry interface), Eyre will also need to convert your `mark` to a `%mime` in order to encode it in an HTTP response, so you may require a `+mime` arm for that reason as well.
50−
51−The second case of interest is the `+json` arm for converting to and from a `%json` `mark`. If, for example, you want to write a Gall agent to which you can subscribe through Eyre's channel system, it must produce data with a `mark` containing `%json` conversion routines. If it doesn't, Eyre will not be able to deliver the data to the subscribed HTTP client in the SSE stream.
52−
53−## Sections
54−
55−[Writing Marks](/docs/arvo/clay/marks/writing-marks) - A practical walkthrough of writing a `mark` file.
56−
57−[Using Marks](/docs/arvo/clay/marks/using-marks) - Details of using `mark` conversion gates and `mark` cores in your own code.
58−
59−[Examples](/docs/arvo/clay/marks/examples) - The example code used in the Writing Marks guide.
content/docs/arvo/clay/marks/using-marks.mddeleted−240
@@ -1,240 +0,0 @@
1−+++
2−title = "Using Marks"
3−weight = 3
4−template = "doc.html"
5−+++
6−
7−In the last document, [Writing Marks](/docs/arvo/clay/marks/writing-marks), we walked through writing `mark` files and touched on how Clay handles them. They needn't just be left to background vane processes though, you can also use them yourself in your code.
8−
9−There are two kinds of cores that Clay can build for you: A `mark` conversion gate and a `mark` core. Each has two kinds: Statically typed and dynamically typed. Clay has a `care` for producing each of these:
10−
11−- `%b` - Build a dynamically typed `mark` core.
12−- `%c` - Build a dynamically typed `mark` conversion gate.
13−- `%e` - Build a statically typed `mark` core.
14−- `%f` - Build a statically typed `mark` conversion gate.
15−
16−You can either use these by `%pass`ing Clay a [%warp task](/docs/arvo/clay/tasks#warp) with the appropriate `care`, or else with a [Clay scry](/docs/arvo/clay/scry). In the examples here we've used the latter.
17−
18−## mark conversion gates
19−
20−`mark` conversion gates simply convert from one `mark` to another.
21−
22−### Static
23−
24−A static `mark` conversion gate looks like `$-(a b)`, where `a` is the type of the `mark` you're converting _from_, and `b` is type of the `mark` you're converting _to_. For example, a `mark` conversion gate from `%txt` to `%mime` would look like `$-(wain mime)`. You'd simply feed it a `wain` and get a `$mime` in return.
25−
26−#### Example
27−
28−We get our `%txt` to `%mime` `mark` conversion gate with a `%f` scry like so:
29−
30−```
31−> =txt-to-mime .^($-(wain mime) %cf /===/txt/mime)
32−```
33−
34−Note we had to specify the type of the gate as `$-(wain mime)` in the scry - if the type returned by the scry doesn't match that specification it'll fail. This is where a statically typed `mark` conversion gate differs from the dynamically typed gate, which we'll discuss later.
35−
36−Now that we have our conversion gate, we can just call it with a valid `wain` and we'll get our `$mime` in return:
37−
38−```
39−> (txt-to-mime ~['foo'])
40−[p=/text/plain q=[p=3 q=7.303.014]]
41−```
42−
43−### Dynamic
44−
45−A dynamically typed `mark` conversion gate is called a `$tube:clay`, and looks like:
46−
47−```hoon
48−+$ tube $-(vase vase)
49−```
50−
51−As you can see from the type definition, it takes and returns a `vase` rather than needing the types explicitly defined. Rather than failing on a type mismatch when the scry is performed, it'll instead fail when it's actually run and fed a `vase` of the wrong type. Apart from handling `vase`s, it otherwise behaves the same as a statically typed `mark` conversion gate.
52−
53−#### Example
54−
55−We get our `%txt` to `%mime` `$tube` with a `%c` scry like so:
56−
57−```
58−> =txt-mime-tube .^(tube:clay %cc /===/txt/mime)
59−```
60−
61−And then we can again feed it the `wain` that a `%txt` `mark` wants, only this time it's wrapped in a `vase`:
62−
63−```
64−> !< mime (txt-mime-tube !>(~['foo']))
65−[p=/text/plain q=[p=3 q=7.303.014]]
66−```
67−
68−We then get our `$mime` back, but also in a `vase`.
69−
70−## mark cores
71−
72−While a `mark` conversion gate is built from functions defined in `+grab` and `+grow`, a `mark` core gives you everything in `+grad` so you can create diffs, merge diffs, patch files, etc. An extra arm `+vale` is also included that lets you convert a `noun` to the type the `%mark` takes by running the `+noun` arm of `+grab` in the original `mark` file.
73−
74−### Static
75−
76−A statically typed `mark` core is a `(nave:clay a b)` where `a` is the type of the `mark` and `b` is the type for diffs (which is the type of the `mark` specified in `+form:grad`). For example, a static `mark` core for a `%txt` `mark` looks like `(nave:clay wain (urge:clay cord))`.
77−
78−`+nave:clay` looks like this in full:
79−
80−```hoon
81−++ nave
82− |$ [typ dif]
83− $_
84− ^?
85− |%
86− ++ diff |~([old=typ new=typ] *dif)
87− ++ form *mark
88− ++ join |~([a=dif b=dif] *(unit (unit dif)))
89− ++ mash
90− |~ [a=[ship desk dif] b=[ship desk dif]]
91− *(unit dif)
92− ++ pact |~([typ dif] *typ)
93− ++ vale |~(noun *typ)
94− --
95−```
96−
97−In brief, the arms of the core do the following:
98−
99−- `+form` - `mark` for diffs.
100−- `+vale` - Clam `noun` to the `mark`'s type.
101−- `+diff` - Create diff of two files.
102−- `+pact` - Patch a file with a diff.
103−- `+join` - Merge two diffs, returning `~` if there's a conflict.
104−- `+mash` - Force merge of two diffs.
105−
106−#### Examples
107−
108−First we get the `%txt` `mark` core with a `%e` scry:
109−
110−```
111−> =txt-nave .^((nave:clay wain (urge:clay cord)) %ce /===/txt)
112−```
113−
114−Note we specified the `mark` type `wain` and diff type `(urge:clay cord)` in the `nave` returned by the scry.
115−
116−We can see the `mark` for diffs with `+form`:
117−
118−```
119−> form.txt-nave
120−%txt-diff
121−```
122−
123−To clam a noun to the type of the `mark` (a `wain` in the case of a `%txt` `mark`), we can call `+vale` with a `noun`:
124−
125−```
126−> (vale:txt-nave ~['foo' 'bar'])
127−<|foo bar|>
128−```
129−
130−We can create a diff of two files with `+diff`:
131−
132−```
133−> (diff:txt-nave ~['foo' 'bar' 'baz'] ~['foo' 'zoo' 'baz'])
134−~[[%.y p=1] [%.n p=<|bar|> q=<|zoo|>] [%.y p=1]]
135−```
136−
137−Let's create some more diffs for experimentation:
138−
139−```
140−> =diff-a (diff:txt-nave ~['foo' 'bar' 'baz'] ~['foo' 'zoo' 'baz'])
141−> =diff-b (diff:txt-nave ~['foo' 'bar' 'baz'] ~['zap' 'bar' 'baz'])
142−> =diff-c (diff:txt-nave ~['foo' 'bar' 'baz'] ~['foo' 'bla' 'baz'])
143−```
144−
145−If we try merging diffs `a` and `b` with `+join`, we get a new merged diff back in a `unit`:
146−
147−```
148−> (join:txt-nave diff-a diff-b)
149−[~ [~ ~[[%.n p=<|foo|> q=<|zap|>] [%.n p=<|bar|> q=<|zoo|>] [%.y p=1]]]]
150−```
151−
152−If we try merging diffs `a` and `c` however, we get `~` because of a conflict:
153−
154−```
155−> (join:txt-nave diff-a diff-c)
156−[~ ~]
157−```
158−
159−If we run `+mash` on `a` and `b` we get the same diff as with `+join` (sans the `unit`):
160−
161−```
162−> (mash:txt-nave [our %base diff-a] [our %blah diff-b])
163−[~ ~[[%.n p=<|foo|> q=<|zap|>] [%.n p=<|bar|> q=<|zoo|>] [%.y p=1]]]
164−```
165−
166−If we `+mash` `a` and `c`, however, we get a diff with the conflict annotated rather than just `~`:
167−
168−```
169−> (mash:txt-nave [our %base diff-a] [our %blah diff-c])
170−[ ~
171− ~[
172− [%.y p=1]
173− [ %.n
174− p=<|bar|>
175− q
176− <|>>>>>>>>>>>> ~zod/base zoo ++++++++++++ bar ------------ bla <<<<<<<<<<<< ~zod/blah|>
177− ]
178− [%.y p=1]
179− ]
180−]
181−```
182−
183−Note that the `%txt` `mark` annotates conflicts, but there are no specific rules around how the `+mash` arm should force-merge conflicting diffs apart from that it must return a valid diff, however the `mark` specified in `+form` defines that.
184−
185−Finally, we can patch our `wain` with diff `a` and get a new, modified `wain`:
186−
187−```
188−> (pact:txt-nave ~['foo' 'bar' 'baz'] diff-a)
189−<|foo zoo baz|>
190−```
191−
192−### Dynamic
193−
194−A dynamically typed `mark` core is a `$dais:clay`, which looks like:
195−
196−```hoon
197−+$ dais
198− $_ ^|
199− |_ sam=vase
200− ++ diff |~(new=_sam *vase)
201− ++ form *mark
202− ++ join |~([a=vase b=vase] *(unit (unit vase)))
203− ++ mash
204− |~ [a=[ship desk diff=vase] b=[ship desk diff=vase]]
205− *(unit vase)
206− ++ pact |~(diff=vase sam)
207− ++ vale |~(noun sam)
208− --
209−```
210−
211−It has the same arms as the statically typed `mark` core, the difference is that it takes and returns `vase`s rather than the data directly. Additionally, it's a door rather than an ordinary core, and takes the type of the `mark` wrapped in a `vase` as its argument.
212−
213−#### Examples
214−
215−We can get a `%txt` `mark` `dais` with a `%b` scry:
216−
217−```
218−> =txt-dais .^(dais:clay %cb /===/txt)
219−```
220−
221−Its `+form` arm functions the same as a static core:
222−
223−```
224−> form.txt-dais
225−%txt-diff
226−```
227−
228−So does `+vale` except it returns a `vase`:
229−
230−```
231−> !< wain (vale:txt-dais ~['foo' 'bar'])
232−<|foo bar|>
233−```
234−
235−All the other arms also deal in `vase`s. Because it's a door, the `+pact` and `+diff` arms take the original file in a `vase` as the door sample rather than being given directly to the arm. Calling `+diff` arm, for example, works like so:
236−
237−```
238−> !< (urge:clay cord) (~(diff txt-dais !>(~['foo' 'bar'])) !>(~['foo' 'baz']))
239−~[[%.y p=1] [%.n p=<|bar|> q=<|baz|>]]
240−```
content/docs/arvo/clay/marks/writing-marks.mddeleted−333
@@ -1,333 +0,0 @@
1−+++
2−title = "Writing Marks"
3−weight = 2
4−template = "doc.html"
5−+++
6−
7−Here we'll walk through a practical example of writing a `mark` file.
8−
9−We'll create a `mark` for CSV (comma separated values) files, a simple format for storing tabular data in a text file. Note that there's already a `csv.hoon` `mark` and library, but we'll create new ones for demonstrative purposes. It shouldn't be an issue to overwrite the existing ones on a fakezod.
10−
11−CSV files separate fields with commas and rows with line breaks. They look something like:
12−
13−```
14−foo,bar,baz
15−blah,blah,blah
16−1,2,3
17−```
18−
19−There is a little complexity surrounding special characters in fields and line endings, but otherwise the only other rule is that all rows must have the same number of fields. You can refer to [RFC4180 on the IETF website](https://datatracker.ietf.org/doc/html/rfc4180) for more details.
20−
21−We'll represent such a structure in Hoon as a `(list (list @t))` like:
22−
23−```hoon
24−[['foo' 'bar' 'baz' ~] ['blah' 'blah' 'blah' ~] ['1' '2' '3' ~] ~]
25−```
26−
27−We could perhaps create the type with a `$|` rune to include row-length validation in the mold itself, but a `(list (list @t))` is simpler for demonstrative purposes.
28−
29−## A simple mark
30−
31−Let's begin with the simplest `mark` file:
32−
33−```hoon
34−|_ csv=(list (list @t))
35−++ grab
36− |%
37− ++ noun (list (list @t))
38− --
39−++ grow
40− |%
41− ++ noun csv
42− --
43−++ grad %noun
44−--
45−```
46−
47−The door takes a `(list (list @t))` as its sample, and we've given it a face of `csv` so we can easily reference it. Note its face could be anything, it needn't be the name of our `mark`. When we're doing something with data that has a `%csv` `mark` like converting it to another `mark` or creating a diff, this is where our data will reside.
48−
49−Next we have the `+grab` arm of our door, which contains a core with arms for converting _to_ our `mark` _from_ other `mark`s. We've given it one arm for the `%noun` `mark` - the most generic `mark` which will take any `noun`. Our `+noun` arm will simply clam whatever it's given with the `(list (list @t))` `mold`.
50−
51−Next is the `+grow` arm which does the inverse of `+grab`, converting _from_ our `mark` _to_ another `mark`. We've also given it a `+noun` arm, this time it will simply return the door's sample named `csv`, which is of course already a `noun`.
52−
53−Note that the `+noun` arm is _mandatory_ in `+grab`. Clay cannot build a `mark` core without it. Conversion arms for any other `mark`s apart from `%noun` are optional.
54−
55−Finally we have the `+grad` arm. This arm specifies functions for revision control like creating diffs, patching files and so on. In our case, rather than writing all those functions, we've just delegated those tasks to the `%noun` `mark`. We can do this because we've specified conversion routines to and from the `%noun` `mark` in our `+grow` and `+grab` arms. When we modify a file with a `%csv` `mark`, Clay will convert our data to a `%noun` `mark`, execute the necessary `+grad` functions from the `%noun` `mark` file, and then convert it back to a `%csv` `mark` again.
56−
57−So now we have a valid `%csv` `mark` file. If we save this as `csv.hoon` in the `/mar` directory we could store `%csv` data in Clay. This may be sufficient for some applications, but what if we want to import a CSV file from Unix or elsewhere? In the next section, we'll look at conversions to and from a `%mime` `mark` to address this.
58−
59−## `%mime` conversions
60−
61−The `$mime` type represents raw data from Unix or elsewhere. For example, if a text file from Unix containing the word `foo` were converted to a `$mime` type in Urbit, it would look something like:
62−
63−```hoon
64−[/text/plain q=[p=3 q=7.303.014]]
65−```
66−
67−`/text/plain` is its [MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) and `p.q` is the byte-length of `q.q`, which is the data itself as an `atom`.
68−
69−The `%mime` `mark` is used by Clay to store and convert `$mime` data. It's an important `mark` for moving files from Unix to Urbit and vice versa. When you add a file to a `desk` you have mounted to Unix and `|commit` the change, Clay will first receive the file as a `%mime` `mark`, then convert from a `%mime` to whatever `mark` matches the file extension. For example, `foo.txt` will be converted from `%mime` to `%txt`. Additionally, data fetched by Iris over HTTP will come in as a `$mime-data:http`, which is an unvalidated form of `$mime` that you may wish to convert to a `%mime` `mark` and then to another `mark`. Likewise with Eyre, some of the lower-level interfaces receive HTTP requests with `$mime-data:http` in them.
70−
71−So with the nature of the `%mime` `mark` hopefully now clear, the reason we want conversion methods to and from `%mime` in our `%csv` `mark` is so we can import CSV files from Unix and vice versa.
72−
73−Since a CSV file on Unix will just be a long string with ASCII or UTF-8 encoding, we can treat `q.q` in the `$mime` as a `cord`, and thus write a parser to convert it to a `(list (list @t))`. For this purpose, here's a library: `csv.hoon`, which you can view in full on the [Examples](/docs/arvo/clay/marks/examples#libcsvhoon) page.
74−
75−The library contains four functions:
76−
77−- `+de-csv` - Parse a CSV `cord` to a `(list (list @t))`.
78−- `+en-csv` - Encode a `(list (list @t))` as a CSV `cord`.
79−- `+validate` - Check all rows of `(list (list @t))` are the same length.
80−- `+csv-join` - Ignore this for now, we'll use it later on.
81−
82−The decoding and encoding arms use parsing functions from the Hoon standard library. It's not important to be familiar with parsing in Hoon for our purposes here, but you can have a look at the [Parsing Guide](/docs/hoon/guides/parsing) in the Hoon documentation if you're interested. The important thing to note is that `+de-csv` takes a valid CSV-format `@t` and returns a `(list (list @t))`, and `+en-csv` does the reverse - it takes a `(list (list @t))` and returns a CSV-format `@t`.
83−
84−Let's try the library in the dojo. After we've added it to `/lib` and run `|commit`, we can build the file:
85−
86−```
87−> =csv -build-file %/lib/csv/hoon
88−```
89−
90−...try decode a CSV-format `@t`:
91−
92−```
93−> (de-csv:csv 'foo,bar,baz\0ablah,blah,blah\0a1,2,3')
94−~[<|foo bar baz|> <|blah blah blah|> <|1 2 3|>]
95−```
96−
97−...and try encode a `(list (list @t))` as a CSV-format `@t`:
98−
99−```
100−> (en-csv:csv [['foo' 'bar' 'baz' ~] ['blah' 'blah' 'blah' ~] ['1' '2' '3' ~] ~])
101−'foo,bar,baz\0ablah,blah,blah\0a1,2,3\0a'
102−```
103−
104−With that working, we can add an import for our library to our `%csv` `mark` defintion and add a `+mime` arm to both our `+grab` and `+grow` arms:
105−
106−```hoon
107−/+ *csv
108−|_ csv=(list (list @t))
109−++ grab
110− |%
111− ++ mime |=((pair mite octs) (de-csv q.q))
112− ++ noun
113− |= n=*
114− ^- (list (list @t))
115− =/ result ((list (list @t)) n)
116− ?> (validate result)
117− result
118− --
119−++ grow
120− |%
121− ++ mime
122− ?> (validate csv)
123− [/text/csv (as-octs:mimes:html (en-csv csv))]
124− ++ noun
125− ?> (validate csv)
126− csv
127− --
128−++ grad %noun
129−--
130−```
131−
132−In `+grab` we've added a `+mime` arm to convert _from_ a `%mime` `mark` _to_ our `%csv` `mark`. It's a simple gate that takes a `$mime` (specified as `(pair mite octs)` to avoid conflict with the arm name), runs the data through the `+de-csv` function and returns a `(list (list @t))` of the CSV data.
133−
134−We've also added a `+mime` arm to `+grow` for converting _from_ our `%csv` `mark` _to_ a `%mime` `mark`. We encode our `(list (list @t))` `csv` sample with our `+en-csv` function and then run that through `as-octs:mimes:html` to get a `$octs` (so it has the byte-length). We also add the `/text/csv` MIME type so it's a valid `$mime`.
135−
136−Additionally, we've used the `+validate` function in a few places to make sure our CSV data has consistent row lengths.
137−
138−If we save the above mark file as `csv.hoon` in `/mar` and `|commit %base`, we should now be able to import CSV files into Urbit. Let's give it a go. In the root of our `%base` `desk`, let's add a file named `foo.csv` with the following contents:
139−
140−```
141−foo,bar,baz
142−blah,blah,blah
143−1,2,3
144−```
145−
146−If we now `|commit %base`, we should see it's been successfully added:
147−
148−```
149−> |commit %base
150−>=
151−+ /~zod/base/4/foo/csv
152−```
153−
154−And if we try reading the file with the `-read` thread:
155−
156−```
157−> -read [%x our %base da+now /foo/csv]
158−~[<|foo bar baz|> <|blah blah blah|> <|1 2 3|>]
159−```
160−
161−We can see our `%csv` `mark` has successfully converted our `foo.csv` file to a `(list (list @t))` when it was imported.
162−
163−Let's try the other direction now. We can create a new `bar.csv` files in the root of `%base` from the dojo like so:
164−
165−```
166−> */bar/csv ~[['abc' 'def' ~] ['ghi' 'jkl' ~]]
167−+ /~zod/base/5/bar/csv
168−```
169−
170−And if we check it in the terminal on the Unix side we can see it's been correctly encoded:
171−
172−```
173−> cat zod/base/bar.csv
174−abc,def
175−ghi,jkl
176−```
177−
178−So now our `%csv` `mark` lets us move data in and out of Urbit. In the next section, we'll look at the `+grad` arm in more detail.
179−
180−## `+grad`
181−
182−So far we've just delegated `+grad` functions to the `%noun` `mark`, but now we'll look at writing our own.
183−
184−For demonstrative purposes, we can just poach the algorithms used in the `+grad` arm of the `%txt` `mark` and modify them to take our `(list (list @t))` type instead of a `wain`. It's not the most efficient algorithm for a CSV file but it'll do the job.
185−
186−Our diff format will be a `(urge:clay (list @t))`, and we'll use some `differ` functions from `zuse.hoon` like `+loss`, `+lusk` and `+lurk` to produce diffs and apply patches.
187−
188−The [csv.hoon library](/docs/arvo/clay/marks/examples#libcsvhoon) we imported also contains a `+csv-join` function which we'll use in the `+join` arm, just to save space here.
189−
190−Here's the new `%csv` `mark` defintion:
191−
192−```hoon
193−/+ *csv
194−|_ csv=(list (list @t))
195−++ grab
196− |%
197− ++ mime |=((pair mite octs) (de-csv q.q))
198− ++ noun
199− |= n=*
200− ^- (list (list @t))
201− =/ result ((list (list @t)) n)
202− ?> (validate result)
203− result
204− --
205−++ grow
206− |%
207− ++ mime
208− ?> (validate csv)
209− [/text/csv (as-octs:mimes:html (en-csv csv))]
210− ++ noun
211− ?> (validate csv)
212− csv
213− --
214−++ grad
215− |%
216− ++ form %csv-diff
217− ++ diff
218− |= bob=(list (list @t))
219− ^- (urge:clay (list @t))
220− ?> (validate csv)
221− ?> (validate bob)
222− (lusk:differ csv bob (loss:differ csv bob))
223− ++ pact
224− |= dif=(urge:clay (list @t))
225− ^- (list (list @t))
226− =/ result (lurk:differ csv dif)
227− ?> (validate result)
228− result
229− ++ join
230− |= $: ali=(urge:clay (list @t))
231− bob=(urge:clay (list @t))
232− ==
233− ^- (unit (urge:clay (list @t)))
234− (csv-join ali bob)
235− ++ mash
236− |= $: [ship desk (urge:clay (list @t))]
237− [ship desk (urge:clay (list @t))]
238− ==
239− ^- (urge:clay (list @t))
240− ~|(%csv-mash !!)
241− --
242−--
243−```
244−
245−In our modified `+grad` arm, we've replaced the `%noun` delegation with a core containing five arms: `+form`, `+diff`, `+pact`, `+join`, and `+mash`. These arms are all required for a valid `+grad` if it's not delegated to another `mark`. We'll now look at each in detail.
246−
247−### `+form`
248−
249−```hoon
250−++ form %csv-diff
251−```
252−
253−`+form` simply specifies the `mark` of the diff file that may be produced by other `+grad` functions. If your diff is the same type as your `mark`, it could just specify itself like `%csv`. In our case our diff is a `(urge:clay (list @t))` rather than a `(list (list @t))`, so we need a separate mark file for the diff itself.
254−
255−Here's another `mark` file which can be saved as `csv-diff.hoon` in `/mar`:
256−
257−```hoon
258−|_ dif=(urge:clay (list @t))
259−++ grab
260− |%
261− ++ noun (urge:clay (list @t))
262− --
263−++ grow
264− |%
265− ++ noun dif
266− --
267−++ grad %noun
268−--
269−```
270−
271−It's very bare-bones, we just need it for our `%csv` `mark` to work. In our `%csv` `mark`, we've specified it as `%csv-diff` in `+form`.
272−
273−### `+diff`
274−
275−```hoon
276−++ diff
277− |= bob=(list (list @t))
278− ^- (urge:clay (list @t))
279− ?> (validate csv)
280− ?> (validate bob)
281− (lusk:differ csv bob (loss:differ csv bob))
282−```
283−
284−This arm produces the diff of two `%csv` files. The first `%csv` file will be given as the sample of the parent door, which if you'll recall we gave a face of `csv`. The second `%csv` file will be given as the sample of the gate in `+diff`, which we've named `bob` here. We then just produce the diff of these two files and return it as the type of the mark specified in `+form`, which in our case is `(urge:clay (list @t))` for a `%csv-diff`. Clay will use `+diff` when a file is revised, so it doesn't have to store a whole new copy of the file each time it's modified.
285−
286−### `+pact`
287−
288−```hoon
289−++ pact
290− |= dif=(urge:clay (list @t))
291− ^- (list (list @t))
292− =/ result (lurk:differ csv dif)
293− ?> (validate result)
294− result
295−```
296−
297−`+pact` patches a `%csv` file with the given diff. Its gate takes a diff and applies it to the `%csv` given as the sample of the parent door (which we gave a face of `csv`). If the patch succeeds, it will return a new `%csv` file - a valid `(list (list @t))`. When we read a file that's been modified in Clay, Clay will apply all the diffs it has with `+pact` and return the resulting file.
298−
299−### `+join`
300−
301−```hoon
302−++ join
303− |= $: ali=(urge:clay (list @t))
304− bob=(urge:clay (list @t))
305− ==
306− ^- (unit (urge:clay (list @t)))
307− (csv-join ali bob)
308−```
309−
310−The `+join` arm merges two different diffs. It takes them both as the sample of its gate (which we've named `ali` and `bob`), and returns a new diff wrapped in a `unit` like `(unit (urge:clay (list @t)))`. The `unit` will be `~` if the merge failed due to a conflict. This is used by Clay in some cases when `desk`s are merged. If diff merges are not possible for your use case, you could just have it always return `~`.
311−
312−### `+mash`
313−
314−```hoon
315−++ mash
316− |= $: [ship desk (urge:clay (list @t))]
317− [ship desk (urge:clay (list @t))]
318− ==
319− ^- (urge:clay (list @t))
320− ~|(%csv-mash !!)
321−```
322−
323−This is like `+join` except it forces a diff merge even if there's a conflict. Rather than returning a `unit`, it just returns the diff - a `(urge:clay (list @t))` in our case. Also unlike `+join`, it takes the `ship` and `desk` each diff came from as well as the diff itself.
324−
325−The `+mash` arm is not used by Clay in its file revision operations, so it's safe to just make it a dummy arm that crashes as we've done here. If you were to use it, it would likely just be used manually in an agent, thread or generator.
326−
327−An example of its use would be the `%txt` `mark`, which includes a proper `+mash` function that produces a diff with any conflicts annotated, though how you have `+mash` handle conficts would depend on your use case. If there were no conflicts between the two diffs, it should produce the same diff as the `+join` arm.
328−
329−## Conclusion
330−
331−So there you have it, a fully functional `mark` for CSV files. A `mark` file can be as complex or as simple as you'd like, they're very flexible depending on your use case. Additional conversion methods can always be added as they're needed. For example, with just a few lines of code we could add arms for converting CSV files to `%json` or `%txt` and vice versa.
332−
333−In the next document, we'll look at building and using `mark` cores and `mark` conversion gates in our own code.
content/docs/arvo/clay/scry.mddeleted−399
@@ -1,399 +0,0 @@
1−+++
2−title = "Scry Reference"
3−weight = 5
4−template = "doc.html"
5−+++
6−
7−The 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−
9−```
10−> /===
11−[~.~zod ~.base ~.~2021.4.26..02.29.03..d31b ~]
12−```
13−
14−## %a - Build hoon.
15−
16−A scry with a `care` of `%a` will build a `hoon` file and return it as a `vase`.
17−
18−Example:
19−
20−```
21−.^(vase %ca /===/lib/strandio/hoon)
22−```
23−
24−## %b - Dyn. mark core.
25−
26−A 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`.
27−
28−Example:
29−
30−```
31−.^(dais:clay %cb /===/txt)
32−```
33−
34−## %c - Dyn. mark convert.
35−
36−A 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`.
37−
38−Example:
39−
40−```
41−> =a .^(tube:clay %cc /===/txt/mime)
42−> !< mime (a !>(~['foo']))
43−[p=/text/plain q=[p=3 q=7.303.014]]
44−```
45−
46−## %d - List desks.
47−
48−A scry with a `care` of `%d` will return a `(set desk)` of the `desk`s that exist on your ship.
49−
50−Example:
51−
52−{% customFence %}
53−
54−\> .^((set desk) %cd /===)
55−&#x7B;&#x25;bitcoin %base %landscape %webterm %garden}
56−{% /customFence %}
57−
58−## %e - Static mark core.
59−
60−A scry with a `care` of `%e` will return a statically typed `nave:clay` `mark` core. The `path` in the scry specifies the `mark`. The type returned is a `(nave:clay {type} {diff})`, where `{type}` is the type the `mark` takes and `{diff}` is the type taken by the `mark` specified in `+form:grad`.
61−
62−Example:
63−
64−```
65−.^((nave:clay noun noun) %ce /===/noun)
66−```
67−
68−## %f - Stat. mark convert.
69−
70−A 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`.
71−
72−```
73−> =a .^($-(text mime) %cf /===/txt/mime)
74−> (a ~['foo'])
75−[p=/text/plain q=[p=3 q=7.303.014]]
76−```
77−
78−## %p - File permissions.
79−
80−A 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.
81−
82−If 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.
83−
84−Example:
85−
86−```
87−> .^([dict:clay dict:clay] %cp /===/gen)
88−[[src=/ rul=[mod=%white who=[p={} q={}]]] src=/ rul=[mod=%white who=[p={} q={}]]]
89−```
90−
91−## %r - File as vase.
92−
93−A 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.
94−
95−Examples:
96−
97−```
98−> .^(vase %cr /===/gen/hood/hi/hoon)
99−[ #t/@
100− q
101− 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
102−]
103−```
104−
105−```
106−> !< @t .^(vase %cr /===/gen/hood/hi/hoon)
107−':: 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'
108−```
109−
110−```
111−> .^(vase %cr /===/gen)
112−Crash!
113−```
114−
115−## %s - Misc. scries.
116−
117−A scry with a `care` of `%s` is for miscellaneous internal and debug functions and is liable to change in the future.
118−
119−Rather 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.
120−
121−### %yaki - Commit.
122−
123−This will return the [yaki:clay](/docs/arvo/clay/data-types#yaki-clay-commit) of the specified commit. It takes a [tako:clay](/docs/arvo/clay/data-types#tako-clay-commit-reference).
124−
125−Example:
126−
127−Here we scry the [dome:clay](/docs/arvo/clay/data-types#dome-desk-data) for `/===`, get the latest `tako:clay` and the do a `%s` scry for the `yaki:clay` in question.
128−
129−```
130−> =/ =dome:clay .^(dome:clay %cv /===)
131− =/ =tako:clay (~(got by hit.dome) let.dome)
132− .^(yaki:clay %cs /===/yaki/(scot %uv tako))
133−[ p=~[80.174.473.756.485.530.520.259.753.935.584.637.641.665.425.899.348.092.348.244.635.557.986.495.151.006]
134− q
135− { [p=/mar/hark/graph-hook-update/hoon q=0v5.ea0bj.21s5c.mjrop.ishic.fpkvl.e5bbs.91kc9.tdo41.ifi06.60v41]
136− [p=/gen/hood/autocommit/hoon q=0v19.rh7jv.sa67o.t3jrb.4sdvs.7c45f.pv2u0.ragik.psp20.agqd8.8srkj]
137− ...
138− [p=/tests/lib/primitive-rsa/hoon q=0v1g.3qmq3.6i15q.arh6h.lfsqu.gvc9m.ql6m5.e2rdr.vnnt9.tptc6.mv9u7]
139− [p=/tests/sys/vane/gall/hoon q=0va.alspc.qptqn.7tuj0.bgecg.1093t.gtsjs.up03k.d1fmk.4jrh8.2tdfa]
140− }
141− r=88.666.797.531.755.181.802.690.473.856.185.443.710.929.766.582.249.039.904.824.278.074.149.777.897.099
142− t=~2021.4.16..10.41.57..3565
143−]
144−```
145−
146−### %blob - File blob.
147−
148−This will return the [blob:clay](/docs/arvo/clay/data-types#blob-clay-data) of some file. It takes a [lobe:clay](/docs/arvo/clay/data-types#lobe-clay-data-reference).
149−
150−Example:
151−
152−Here 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.
153−
154−```
155−> =/ =arch .^(arch %cy /===/gen/hood/hi/hoon)
156− ?~ fil.arch
157− ~
158− .^(blob:clay %cs /===/blob/(scot %uv u.fil.arch))
159−[ %direct
160− p=0vp.k7nsm.qkdr3.t17rp.33bae.8gajg.v27gi.40itr.2u9qa.nppbt.7k255
161− q
162− [ p=%hoon
163− q
164−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
165− ]
166−]
167−```
168−
169−### %hash - Commit hash.
170−
171−This will return the `@uvI` content hash of the specified commit. It takes a `tako:clay`.
172−
173−Example:
174−
175−Here we grab the `dome:clay` for `/===` with a `%v` scry, get the latest `tako:clay` and then do a `%s` `%hash` scry for it.
176−
177−```
178−> =/ =dome:clay .^(dome:clay %cv /===)
179− =/ =tako:clay (~(got by hit.dome) let.dome)
180− .^(tako:clay %cs /===/hash/(scot %uv tako))
181−0v16.er7uq.oke4u.cru7u.nglu9.q3su7.6ub1o.bh4qk.r5uav.ut12d.5rdl5
182−```
183−
184−### %cage - File as cage.
185−
186−This will return a `cage` of the data of some file. It takes a `lobe:clay`.
187−
188−Example:
189−
190−Here 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.
191−
192−```
193−> =/ =arch .^(arch %cy /===/gen/hood/hi/hoon)
194− ?~ fil.arch
195− ~
196− .^(cage %cs /===/cage/(scot %uv u.fil.arch))
197−[ p=%hoon
198− q
199− [ #t/@t
200− q
201−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
202− ]
203−]
204−```
205−
206−### %open - Build prelude.
207−
208−This 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.
209−
210−### %late - Latest case.
211−
212−This 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]`.
213−
214−Example:
215−
216−```
217−> .^(=cass:clay %cs /(scot %p (sein:title our now our))/base/1/late)
218−cass=[ud=50 da=~2021.4.22..10.38.50..57a8]
219−```
220−
221−```
222−> .^(=cass:clay %cs /~sampel/base/1/late)
223−cass=[ud=0 da=~2000.1.1]
224−```
225−
226−### %base - Merge-base.
227−
228−This 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`.
229−
230−Examples:
231−
232−```
233−> .^((list tako:clay) %cs /===/base/(scot %p (sein:title our now our))/base)
234−~[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]
235−```
236−
237−```
238−> .^((list tako:clay) %cs /===/base/~sampel/base)
239−~
240−```
241−
242−## %t - List files.
243−
244−A 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`.
245−
246−Examples:
247−
248−```
249−> .^((list path) %ct /===/app/landscape)
250−~[
251− /app/landscape/css/index/css
252− /app/landscape/img/favicon/png
253− /app/landscape/img/imageupload/png
254− /app/landscape/img/touch_icon/png
255− /app/landscape/index/html
256− /app/landscape/js/channel/js
257−]
258−```
259−
260−```
261−> .^((list path) %ct /===/gen/group-store/add/hoon)
262−~[/gen/group-store/add/hoon]
263−```
264−
265−```
266−> .^((list path) %ct /===/foobar)
267−~
268−```
269−
270−## %u - Check exists.
271−
272−A 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.
273−
274−Examples:
275−
276−```
277−> .^(? %cu /===/app)
278−%.n
279−```
280−
281−```
282−> .^(? %cu /===/gen/code/hoon)
283−%.y
284−```
285−
286−```
287−> .^(? %cu /===/foobar)
288−%.n
289−```
290−
291−## %v - Desk state.
292−
293−A scry with a care of `%v` will return the entire state of a `desk` as a `dome:clay`.
294−
295−Example:
296−
297−```
298−> =a .^(dome:clay %cv /===)
299−> let.a
300−1
301−```
302−
303−Note: If you try printing this it will take forever and probably OOM your ship.
304−
305−## %w - Revision number.
306−
307−A 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.
308−
309−Example:
310−
311−```
312−> .^(cass:clay %cw /===)
313−[ud=2 da=~2021.4.13..19.12.49..3389]
314−```
315−
316−## %x - Read file.
317−
318−A scry with a `care` of `%x` will return the raw data of a file as an `@` or crash if it's a directory.
319−
320−Examples:
321−
322−```
323−> .^(@ %cx /===/gen/hood/hi/hoon)
324−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
325−```
326−
327−```
328−> .^(@t %cx /===/gen/hood/hi/hoon)
329−':: 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'
330−```
331−
332−```
333−> .^(@ %cx /===/gen/hood)
334−Crash!
335−```
336−
337−## %y - Read arch.
338−
339−A scry with a `care` of `%y` will return the `arch` of a file or directory.
340−
341−An `arch` is a `[fil=(unit lobe:clay) dir=(map @ta ~)]`. The `fil` will contain the `lobe:clay` hash if it's a file, otherwise it will be null. The `dir` will contain a map of the files and directories it contains, otherwise it will be null.
342−
343−It will return the bunt of an `arch` if the file or directory is not found.
344−
345−Examples:
346−
347−```
348−> .^(arch %cy /===/gen/group-store)
349−[ fil=~
350− dir
351− { [p=~.allow-ships q=~]
352− [p=~.add q=~]
353− [p=~.ban-ranks q=~]
354− [p=~.remove q=~]
355− [p=~.create q=~]
356− [p=~.join q=~]
357− [p=~.allow-ranks q=~]
358− [p=~.ban-ships q=~]
359− }
360−]
361−```
362−
363−```
364−> .^(arch %cy /===/gen/group-store/allow-ships)
365−[fil=~ dir={[p=~.hoon q=~]}]
366−```
367−
368−```
369−> .^(arch %cy /===/gen/group-store/allow-ships/hoon)
370−[fil=[~ 0vb.g8sqs.7gjm9.bl3vu.nk677.h5be1.g9eg3.4v1jo.00ivf.g8ndu.48a53] dir={}]
371−```
372−
373−```
374−> .^(arch %cy /===/foobar)
375−[fil=~ dir={}]
376−```
377−
378−## %z - Content hash.
379−
380−A 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.
381−
382−The type returned is a `@uxI`.
383−
384−Examples:
385−
386−```
387−> .^(@uvI %cz /===/gen)
388−0v5.itmhj.lt7ak.lgr1k.dr7vu.u7u9s.ko5rf.idfcr.ukrd2.t088n.3ml1k
389−```
390−
391−```
392−> .^(@uvI %cz /===/gen/code/hoon)
393−0v1t.vi1pf.3ba4n.87g6h.dcc1p.4t4l8.rm6a9.b4de4.v77qc.p9dc0.p8289
394−```
395−
396−```
397−> .^(@uvI %cz /===/foobar)
398−0v0
399−```
content/docs/arvo/clay/tasks.mddeleted−503
@@ -1,503 +0,0 @@
1−+++
2−title = "API Reference"
3−weight = 6
4−template = "doc.html"
5−+++
6−
7−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) document. Many of the types referenced are detailed in the [Data Types](/docs/arvo/clay/data-types) 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.
8−
9−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.
10−
11−## `%warp` - Read and track
12−
13−```hoon
14−[%warp wer=ship rif=riff]
15−```
16−
17−A `%warp` `task` is for reading and subscribing to files and directories.
18−
19−The `wer` field is the target ship. The `(unit rave)` of the [riff](/docs/arvo/clay/data-types#riff-clay-request-desist) is null to cancel an existing subscription, otherwise the [rave](/docs/arvo/clay/data-types#rave-clay-general-subscription-request) is tagged with one of:
20−
21−- `%sing` - Read a single file or directory.
22−- `%next` - Subscribe for the next change to a file or directory.
23−- `%mult` - Subscribe for the next change to a set of files and/or directories.
24−- `%many` - Track changes to a desk for the specified range of revisions.
25−
26−We'll look at each of these in more detail below.
27−
28−#### Returns
29−
30−Clay responds to a `%mult` request with a `%wris` `gift`, and the rest with a `%writ` `gift`.
31−
32−A `%wris` `gift` looks like:
33−
34−```hoon
35−[%wris p=[%da p=@da] q=(set (pair care path))] :: many changes
36−```
37−
38−...and a `%writ` `gift` looks like:
39−
40−```hoon
41−[%writ p=riot] :: response
42−```
43−
44−The `unit` of the [riot](/docs/arvo/clay/data-types#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#rant-clay-response-data) with a `cage` containing the data you requested. Its contents will vary depending on the kind of request and `care`.
45−
46−Now we'll look at each of the `rave` request types in turn.
47−
48−### `%sing` - Read
49−
50−```hoon
51−[%sing =mood]
52−```
53−
54−This `rave` is for reading a single file or directory immediately.
55−
56−The `care` of the [mood](/docs/arvo/clay/data-types#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#care-clay-clay-submode) documentation and [scry](/docs/arvo/clay/scry) documentation for details on the various `care`s.
57−
58−The [case](/docs/arvo/clay/data-types#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`.
59−
60−#### Example
61−
62−[See here for an example of using %sing.](/docs/arvo/clay/examples#sing)
63−
64−### `%next` - Await next
65−
66−```hoon
67−[%next =mood] :: await next version
68−```
69−
70−This subscribes to the next version of the specified file. See [here](/docs/arvo/clay/data-types#mood-clay-single-subscription-request) for details of the `mood` structure.
71−
72−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`.
73−
74−#### Example
75−
76−[See here for an example of using %next.](/docs/arvo/clay/examples#next)
77−
78−### `%mult` - Next of any
79−
80−```hoon
81−[%mult =mool]
82−```
83−
84−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.
85−
86−The behaviour with respect to requesting old `case`s is the same as explained in the [`%next`](#next---await-next) section above.
87−
88−The `mool` specified in the request is this structure:
89−
90−```hoon
91−+$ mool [=case paths=(set (pair care path))] :: requests in desk
92−```
93−
94−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.
95−
96−#### Example
97−
98−[See here for an example of using %mult.](/docs/arvo/clay/examples#mult)
99−
100−### `%many` - Track range
101−
102−```hoon
103−[%many track=? =moat]
104−```
105−
106−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.
107−
108−If the `track` is `%.y` it will just return a `%writ` like:
109−
110−```hoon
111−[%writ p=[~ [p=[p=%w q=[%ud p=256] r=%base] q=/ r=[p=%null q=[#t/@n q=0]]]]]
112−```
113−
114−...that merely informs you of a change. If you want the actual data you'll have to request it separately.
115−
116−If the `track` is `%.n`, the `cage` of the `%writ` will contain a [nako](/docs/arvo/clay/data-types#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.
117−
118−The `from` and `to` fields of the [moat](/docs/arvo/clay/data-types#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.
119−
120−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.
121−
122−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:
123−
124−```hoon
125−[%writ p=~]
126−```
127−
128−#### Example
129−
130−[See here for an example of using %many.](/docs/arvo/clay/examples#many)
131−
132−### Cancel Subscription
133−
134−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.
135−
136−#### Example
137−
138−[See here for an example of cancelling a subscription.](/docs/arvo/clay/examples#cancel-subscription)
139−
140−## Write and Modify
141−
142−### `%info` - Write
143−
144−```hoon
145−[%info des=desk dit=nori]
146−```
147−
148−To write or modify a file, we send Clay a `%info` `task`.
149−
150−The `%|` tag in the [nori](/docs/arvo/clay/data-types#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#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#miso-clay-ankh-delta) is one of these types of requests:
151−
152−- `%del` - Delete a file.
153−- `%ins` - Insert file. This will also replace an existing file.
154−- `%dif` - This has not yet been implemented so will crash with a `%dif-not-implemented` error.
155−- `%mut` - Change a file. At the time of writing this behaves identically to `%ins` so its use merely informs the reader.
156−
157−#### Returns
158−
159−Clay does not give any response to an `%info` `task` so don't expect a `sign` back.
160−
161−#### Example
162−
163−Here are examples of using each of these as well as making multiple changes in one request:
164−
165−- [%del](/docs/arvo/clay/examples#del)
166−- [%ins](/docs/arvo/clay/examples#ins)
167−- [%mut](/docs/arvo/clay/examples#mut)
168−- [Multiple Changes](/docs/arvo/clay/examples#multiple-changes)
169−
170−## Manage Mounts
171−
172−Here we'll look at managing Clay unix mounts programmatically.
173−
174−There are four Clay `task`s relevant to mounts:
175−
176−- [%boat](#boat---list-mounts) - List mounts.
177−- [%mont](#mont---mount) - Mount something.
178−- [%ogre](#ogre---unmount) - Unmount something.
179−- [%dirk](#dirk---commit) - Commit changes.
180−
181−### `%boat` - List mounts
182−
183−```hoon
184−[%boat ~]
185−```
186−
187−A `%boat` `task` requests the list of existing mounts and does not take any arguments.
188−
189−#### Returns
190−
191−The type it returns is a `%hill` `gift`, which looks like:
192−
193−```hoon
194−[%hill p=(list @tas)]
195−```
196−
197−...where the `@tas` is the name of the mount point.
198−
199−#### Example
200−
201−[See here for an example of using %boat.](/docs/arvo/clay/examples#boat)
202−
203−### `%mont` - Mount
204−
205−```hoon
206−[%mont pot=term bem=beam]
207−```
208−
209−A `%mont` `task` mounts the specified `beam` to the specified `term` mount point.
210−
211−A `beam:clay` is the following structure:
212−
213−```hoon
214−+$ beam [[p=ship q=desk r=case] s=path] :: global name
215−```
216−
217−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).
218−
219−#### Returns
220−
221−Clay does not return a `gift` in response to a `%mont` `%task`.
222−
223−#### Example
224−
225−[See here for an example of using %mont.](/docs/arvo/clay/examples#mont)
226−
227−### `%ogre` - Unmount
228−
229−```hoon
230−[%ogre pot=$@(desk beam)]
231−```
232−
233−A `%ogre` `task` unmounts the specified mount.
234−
235−It's defined in `lull.hoon` as taking `$@(desk beam)` 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.
236−
237−#### Returns
238−
239−Clay does not return a `gift` in response to a `%ogre` `task`.
240−
241−#### Example
242−
243−[See here for an example of using %ogre.](/docs/arvo/clay/examples#ogre)
244−
245−### `%dirk` - Commit
246−
247−```hoon
248−[%dirk des=desk]
249−```
250−
251−A `%dirk` `task` commits changes in the target mount.
252−
253−It's defined in `lull.hoon` as taking a `desk` but like [%ogre](#ogre---unmount), it actually takes the name of a mount point rather than a `desk` as is specified.
254−
255−#### Returns
256−
257−Clay does not return a `gift` in response to a `%dirk` `task`.
258−
259−#### Example
260−
261−[See here for an example of using %dirk.](/docs/arvo/clay/examples#dirk)
262−
263−## Merge Desks
264−
265−### `%merg` - Merge
266−
267−```hoon
268−$: %merg
269− des=desk :: target
270− her=@p dem=desk cas=case :: source
271− how=germ :: method
272−==
273−```
274−
275−A `%merg` `task` will merge the specified source `desk` into the target local `desk`.
276−
277−The `germ` specifies the merge strategy. You can refer to the [Strategies](/docs/arvo/clay/using#strategies) section of the [Using Clay](/docs/arvo/clay/using) document for details of each `germ`.
278−
279−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.
280−
281−#### Returns
282−
283−Clay will respond to the request with a `%mere` `gift` which looks like:
284−
285−```hoon
286−[%mere p=(each (set path) (pair term tang))] :: merge result
287−```
288−
289−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.
290−
291−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:
292−
293−```hoon
294−[ %mere
295− p
296− [ %.n
297− p=[p=%mate-conflict q=~[[%rose p=[p="/" q="/" r=""] q=~[[%leaf p="foo"] [%leaf p="txt"]]]]]
298− ]
299−]
300−```
301−
302−#### Example
303−
304−[See here for an example of using %merg.](/docs/arvo/clay/examples#merg)
305−
306−## Permissions
307−
308−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.
309−
310−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".
311−
312−A group is called a `crew` and is just a `set` of ships with a `@ta` name.
313−
314−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.
315−
316−A `dict:clay` is this structure:
317−
318−```hoon
319−+$ dict [src=path rul=real] :: effective permission
320−```
321−
322−The `src` path is where the permissions were inherited from and the `real` is this structure:
323−
324−```hoon
325− +$ real :: resolved permissions
326− $: mod=?(%black %white) ::
327− who=(pair (set ship) (map @ta crew)) ::
328− == ::
329−```
330−
331−So if we scry for permissions with a `%p` `care`, it'll look like:
332−
333−```hoon
334−> .^([r=dict:clay w=dict:clay] %cp /===/lib/strandio/hoon)
335−[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/ rul=[mod=%white who=[p={} q={}]]]]
336−```
337−
338−There are four permission-related `task`s which you can pass to Clay.
339−
340−A `%perm` `task` is for setting permissions, and the other three are for managing groups:
341−
342−- `%cred` - Add permission group.
343−- `%crew` - Get permission groups.
344−- `%crow` - Get group usage.
345−
346−We'll look at each of these in turn.
347−
348−### `%perm` - Set perms
349−
350−```hoon
351−[%perm des=desk pax=path rit=rite]
352−```
353−
354−A `%perm` `task` sets permissions for the target file or directory.
355−
356−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.
357−
358−The `pax` path is the file or directory whose permissions you want to change, and the `rite` is this structure:
359−
360−```hoon
361−+$ rite :: new permissions
362− $% [%r red=(unit rule)] :: for read
363− [%w wit=(unit rule)] :: for write
364− [%rw red=(unit rule) wit=(unit rule)] :: for read and write
365− ==
366−```
367−
368−Where a `rule` is this structure:
369−
370−```hoon
371−+$ rule [mod=?(%black %white) who=(set whom)] :: node permission
372−```
373−
374−...and finally `whom` is this:
375−
376−```hoon
377−+$ whom (each ship @ta) :: ship or named crew
378−```
379−
380−As the comment suggests, the `@ta` is the name of a `crew` (group).
381−
382−#### Returns
383−
384−Clay does not return a `gift` in response to a `%perm` `task`.
385−
386−#### Example
387−
388−[See here for an example of using %perm.](/docs/arvo/clay/examples#perm)
389−
390−### `%cred` - Add group
391−
392−```hoon
393−[%cred nom=@ta cew=crew]
394−```
395−
396−This simply creates a permission group.
397−
398−The `nom` is a name for the group and the `crew` is just a `(set ship)`:
399−
400−```hoon
401−+$ crew (set ship) :: permissions group
402−```
403−
404−#### Returns
405−
406−Clay does not return a `gift` in response to a `%cred` `task`.
407−
408−#### Example
409−
410−[See here for an example of using %cred.](/docs/arvo/clay/examples#cred)
411−
412−### `%crew` - Get groups
413−
414−```hoon
415−[%crew ~]
416−```
417−
418−This retrieves all permission groups.
419−
420−A `%crew` `task` takes no arguments.
421−
422−#### Returns
423−
424−Clay wil return a `%cruz` `gift`. It looks like:
425−
426−```hoon
427−[%cruz cez=(map @ta crew)] :: permission groups
428−```
429−
430−The `cez` is just a map from group name to `crew` which is just a `(set ship)`.
431−
432−#### Example
433−
434−[See here for an example of using %crew.](/docs/arvo/clay/examples#crew)
435−
436−### `%crow` - Group files
437−
438−```hoon
439−[%crow nom=@ta]
440−```
441−
442−A `%crow` `task` 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.
443−
444−The `nom` is the name of a `crew`.
445−
446−#### Returns
447−
448−The `gift` you get back is a `%croz` which looks like:
449−
450−```hoon
451−[%croz rus=(map desk [r=regs w=regs])] :: rules for group
452−```
453−
454−...where `regs` is this structure:
455−
456−```hoon
457−+$ regs (map path rule) :: rules for paths
458−```
459−
460−#### Example
461−
462−[See here for an example of using %crow.](/docs/arvo/clay/examples#crow)
463−
464−## Foreign Ships
465−
466−Here we'll looking at making Clay requests to a foreign ship.
467−
468−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.
469−
470−### `%warp` - Remote
471−
472−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](#warp---read-and-track) section.
473−
474−Clay only allows a subset of `care`s to be used remotely. They are:
475−
476−- `%u` - Check for existence of file.
477−- `%v` - Get entire `dome:clay` state of a desk.
478−- `%w` - Get revision number.
479−- `%x` - Get data of file.
480−- `%y` - Get `arch` of file or directory.
481−- `%z` - Get content hash of file or directory.
482−
483−Any other `care` will crash with a `%clay-bad-foreign-request-care` error.
484−
485−The foreign ship will respond only if correct permissions have been set. See the [Permissions](#permissions) section for details.
486−
487−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.
488−
489−#### Example
490−
491−[See here for examples of requests to foreign ships.](/docs/arvo/clay/examples#foreign-ships)
492−
493−### `%merg` - Remote
494−
495−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.
496−
497−The foreign ship will respond only if correct permissions have been set. See the [Permissions](#permissions) section for details.
498−
499−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.
500−
501−#### Example
502−
503−[See here for examples of requests to foreign ships.](/docs/arvo/clay/examples#foreign-ships)
content/docs/arvo/clay/using.mddeleted−223
@@ -1,223 +0,0 @@
1−+++
2−title = "Using Clay"
3−weight = 3
4−template = "doc.html"
5−+++
6−
7−### Reading and Subscribing
8−
9−When reading from Clay, there are three types of requests. A
10−`%sing` request asks for data at single revsion. A `%next`
11−request asks to be notified the next time there's a change to
12−given file. A `%many` request asks to be notified on every
13−change in a `desk` for a range of changes.
14−
15−For `%sing` and `%next`, there are generally three things to be
16−queried. A `%u` request simply checks for the existence of a
17−file at a path. A `%x` request gets the data in the file at a
18−path. A `%y` request gets a hash of the data in the file at the
19−path combined with all its children and their data. Thus, `%y`
20−of a node changes if it or any of its children change.
21−
22−A `%sing` request is fulfilled immediately if possible. If the
23−requested revision is in the future, or is on another ship for
24−which we don't have the result cached, we don't respond
25−immediately. If the requested revision is in the future, we wait
26−until the revision happens before we respond to the request. If
27−the request is for data on another ship, we pass on the request
28−to the other ship. In general, Clay subscriptions, like most
29−things in Urbit, aren't guaranteed to return immediately.
30−They'll return when they can, and they'll do so in a
31−referentially transparent manner.
32−
33−A `%next` request checks the query at the given revision, and it
34−produces the result of the query the next time it changes, along
35−with the revision number when it changes. Thus, a `%next` of a
36−`%u` is triggered when a file is added or deleted, a `%next` of a
37−`%x` is triggered when a file is added, deleted, or changed, and
38−a `%next` of a `%y` is triggered when a file or any of its
39−children is added, deleted, or changed.
40−
41−A `%many` request is triggered every time the given `desk` has a
42−new revision. Unlike a `%next`, a `%many` has both a start and
43−an end revision, after which it stops returning. For `%next`, a
44−single change is reported, and if the caller wishes to hear of
45−the next change, it must resubscribe. For `%many`, every revision
46−from the start to the end triggers a response. Since a `%many`
47−request doesn't ask for any particular data, there aren't `%u`,
48−`%x`, and `%y` versions for it.
49−
50−### Unix sync
51−
52−Usage:
53−
54−```
55−|mount %/path/to/directory %mount-point
56−|commit %mount-point
57−|autocommit %mount-point
58−```
59−
60−One of the primary functions of Clay is as a convenient user
61−interface. While tools exist to use Clay from within Urbit, it's
62−often useful to be able to treat Clay like any other filesystem
63−from the Unix perspective -- to "mount" it, as it were.
64−
65−From the dojo, you can run `|mount %/path/to/directory %mount-point`, and this
66−will mount the given Clay directory to the mount-point directory in Unix, with
67−your pier as the root directory. For example `|mount %/gen %generators` will
68−create a `/generators` directory in your pier, and mount the `/gen` folder at
69−that point. If you'd like to use the directory name as the mount point, you can
70−elide the last argument, e.g. `|mount %/gen` mounts `/gen` to `/gen`.
71−
72−Every file is converted to `%mime` before it's written to Unix, and converted
73−back when read from Unix. The entire directory is watched (a la Dropbox), and
74−every change is committed once you run `|commit %mount-point`. Every change can
75−be automatically committed with `|autocommit %mount-point`.
76−
77−### Merging
78−
79−Usage:
80−
81−```
82−|merge %target-desk ~source-ship %source-desk
83−|merge %target-desk ~source-ship %source-desk, =gem %strategy
84−|merge %target-desk ~source-ship %source-desk, =cas ud+5
85−```
86−
87−Clay supports various merge strategies. A "commit" is a snapshot of
88−the files with a list of parents plus a date. Most commits have
89−one parent; a "merge" commit is a commit with two parents. The
90−`%base` `desk` starts with an initial commit with no parents; commits
91−with several parents ("octopus merges") are possible but we don't
92−generate them right now.
93−
94−Unless otherwise specified, all of the following create a new commit
95−with the source and destination commits as parents.
96−
97−Several strategies need a "merge-base". They find it by identifying
98−the most recent common ancestor of the two `desk`s. If none, fail
99−with `%merge-no-merge-base`; if there are two or more, pick one.
100−
101−#### Strategies
102−
103−**`%init`**: the only way to create a `desk`. Not a true merge, since it
104−simply assigns the source commit to the destination.
105−
106−**`%fine`**: if source or destination are in the ancestry of each other,
107−use the newer one; else abort. If the destination is ahead of the
108−source, succeed but do nothing. If the source is ahead of the
109−destination, assign the next revision number to the source commit.
110−Some call this "fast-forward".
111−
112−**`%meet`**: combine changes, failing if both sides changed the same file.
113−Specifically, take diff(merge-base,source) and
114−diff(merge-base,destination) and combine them as long as those diffs
115−touch different files.
116−
117−**`%mate`**: combine changes, failing if both sides changed the same part
118−of a file. Identical to `%meet`, except that some marks, like `%hoon`,
119−allow intelligent merge of changes to different parts of a file.
120−
121−**`%meld`**: combine changes; if both sides changed the same part of a
122−file, use the version of the file in the merge-base.
123−
124−**`%only-this`**: create a merge commit with exactly the contents of the
125−destination `desk`.
126−
127−**`%only-that`**: create a merge commit with exactly the contents of the
128−source commit.
129−
130−**`%take-this`**: create a merge commit with exactly the contents of the
131−destination `desk` except take any files from the source commit which
132−are not in the destination `desk`.
133−
134−**`%take-that`**: create a merge commit with exactly the contents of the
135−source commit except preserve any files from the destination `desk`
136−which are not in the source commit.
137−
138−**`%meet-this`**: merge as in `%meet`, except if both sides changed the same
139−file, use the version in the destination `desk`.
140−
141−**`%meet-that`**: merge as in `%meet`, except if both sides changed the same
142−file, use the version in the source commit.
143−
144−#### Examples and notes:
145−
146−The most common merge strategy is `%mate`, which is a normal 3-way
147−merge which aborts on conflict.
148−
149−`%take-that` is useful to "force" an OTA. After running `%take-that`,
150−you're guaranteed to have exactly the files in the source commit plus
151−any files you separately added.
152−
153−We speak of merging into a destination _`desk`_ from a source _commit_
154−because while you can only merge on top of a `desk`, you can merge from
155−historical commits. For example,
156−
157−```
158−|merge %old our %base, =cas ud+5, =gem %init
159−```
160−
161−will create a new `desk` called `%old` with the 5th commit in `%base`.
162−You can revert the contents of a `desk` to what they were yesterday
163−with
164−
165−```
166−|merge %base our %base, =cas da+(sub now ~d1), =gem %only-that
167−```
168−
169−Note this is a normal `%only-that merge`, which means you're creating a
170−_new_ commit with the old _contents_.
171−
172−`%meld` is rarely used on its own, however if you specify `%auto` or
173−omit the merge strategy, `%kiln` will run a `%meld` merge into a scratch
174−`desk` and then annotate the conflicts there.
175−
176−If you resolve merge conflicts manually, for example by mounting the
177−`desk`s, copying the files in Unix and then running `|commit`, you
178−should usually run an `%only-this merge`. This will not change the
179−newly-fixed contents of your `desk`, but it will record that the merge
180−happened so that those conflicts don't reappear in later merges.
181−
182−If you get a `%merge-no-merge-base` error, this means you're trying to
183−merge two `desk`s which have no common ancestors. You need to give
184−them a common ancestor by choosing a merge strategy which doesn't
185−need a merge-base, like `%only-this`, `%only-that`, `%take-this`, or
186−`%take-that`.
187−
188−`%take-this` could be useful to install 3rd party software, but you
189−couldn't get subsequent updates this way, since the files would
190−already exist in the destination `desk`. Something like "take only
191−the files which aren't in my OTA source or any other 3rd party app"
192−would be basically correct. This would require a parameter listing
193−the `desk`s to not conflict with.
194−
195−`%meet-this` and `%meet-that` imply the existence of `%mate-this` and
196−`%mate-that`, but those don't exist yet.
197−
198−### Autosync
199−
200−Usage:
201−
202−```
203−|sync %target-desk ~source-ship %source-desk
204−```
205−
206−Tracking and staying in sync with another `desk` is another
207−fundamental operation. We call this "autosync". This doesn't mean
208−simply mirroring a `desk`, since that wouldn't allow local changes.
209−We simply want to apply changes as they are made upstream, as
210−long as there are no conflicts with local changes.
211−
212−This is implemented by subscribing to changes to the other `desk`, with a
213−`%many` request and, when it has changes, merging these changes into our `desk`
214−with the usual merge strategies.
215−
216−Note that it's quite reasonable for two `desk`s to be autosynced to
217−each other. This results in any change on one `desk` being mirrored
218−to the other and vice versa.
219−
220−Additionally, it's fine to set up an autosync even if one `desk`,
221−the other `desk`, or both `desk`s do not exist. The sync will be
222−activated when the upstream `desk` comes into existence and will
223−create the downstream `desk` if needed.
content/docs/arvo/concepts/_index.mddeleted−17
@@ -1,17 +0,0 @@
1−+++
2−title = "Concepts"
3−weight = 100
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−insert_anchor_links = "right"
7−+++
8−
9−Other concepts related to the way Arvo works.
10−
11−## [Scries](/docs/arvo/concepts/scries)
12−
13−Details of performing scries.
14−
15−## [Subscriptions](/docs/arvo/concepts/subscriptions)
16−
17−Urbit relies heavily on subscriptions throughout the stack. We strongly prefer reactive data flow compared to querying or polling, which is why for example our equivalent to git natively supports subscriptions to its data.
content/docs/arvo/concepts/scry.mddeleted−77
@@ -1,77 +0,0 @@
1−+++
2−title = "Scries"
3−weight = 40
4−template = "doc.html"
5−+++
6−
7−### What is a scry?
8−
9−A scry is a read-only request to Arvo's global namespace.
10−
11−Vanes and agents define _scry endpoints_ which allow one to request data from their respective states. The endpoints can process the data in any way before returning it, but they cannot alter the actual state - scries can _only_ read, not modify.
12−
13−### Why scry?
14−
15−The subject available in something like a Gall agent or thread contains a great many functions and structures from the standard library as well as `zuse` and `lull`, but it does not include any of the actual data stored elsewhere in the ship. All it has is its own state, a `bowl` and any `card`s it has been passed. Ordinarily, in order to access such data, one would need to `%poke` or `%watch` other agents, or `%pass` `task`s to vanes, then wait for a response. Arvo's scry system is the one exception to this; it allows direct retrieval of data from other vanes or agents in situ, from any context, without any of the normal messaging rigmarole.
16−
17−### How do I scry?
18−
19−Scries are performed exclusively with the dotket rune: `.^`
20−
21−For details of its usage, see the [dotket](/docs/hoon/reference/rune/dot#-dotket) section of the Nock rune documentation. In addition to the dotket documentation, below is a colour-coded diagram breaking down the structure of a dotket scry expression with some additional notes.
22−
23−![Scry diagram](https://media.urbit.org/docs/arvo/scry-diagram-v2.svg)
24−
25−One further note on `care`s (which can sometimes be confusing): While `care`s are part of the global namespace, they're most extensively used by Clay in particular. In Clay, `care`s specify Clay submodules with specific behaviour, and are used both in scries as well as `task`s and `gift`s. For example, a `%x` `care` reads the data of a file, a `%p` `care` reads file permissions, and so forth. To see all of Clay's `care`s and what they do, you can refer to Clay's [Scry Reference](/docs/arvo/clay/scry).
26−
27−Most other vanes also make use of `care`s in their scry endpoints. While such vanes don't have corresponding submodules with strictly defined behaviour like Clay, the `care`s still confer the general nature of the endpoint. The most widely used `care` is `%x`, which implies reading data in a general sense. Gall has special handling of `%x` scries as described in the [Gall agents](#gall-agents) section below, but otherwise `care`s have no special behaviour for non-Clay vanes (though they must still be included if the endpoint specifies it).
28−
29−### What can I scry?
30−
31−There are two places where scry endpoints are defined:
32−
33−#### Vanes
34−
35−Each of Arvo's eight vanes (kernel modules) include a `+scry` arm which defines that vane's scry endpoints. The number of endpoints and extent of data available varies between vanes. For example, Clay has a very extensive set of scry endpoints which provide read access to all files in all desks across all revisions, as well as the ability to build files, perform `mark` conversions, and various other functions. Jael provides access to a great deal of PKI data. On the other hand, Dill has only a couple of endpoints which are mostly useful for debugging, and Iris has none at all (apart from standard memory reporting endpoints you'd not typically use in your applications).
36−
37−To explore what scry endpoints are available for vanes, you can refer to the Scry Reference section of each vane in the [Arvo](/docs/arvo/overview) section of the documents.
38−
39−#### Gall agents
40−
41−Gall has a single scry endpoint of its own to check for the existence of an agent, but otherwise all Gall scries are passed through to one of the agents it manages. The target agent to scry is specified in place of the `desk` as described in the diagram above. Each Gall agent includes a `+on-peek` arm that defines its own scry endpoints. For example, `%graph-store` has a number of scry endpoints to access the data it stores, such as chat messages and the like.
42−
43−Gall agents can expose scry endpoints with any `care`, but most commonly they'll take a `%x` `care`. Gall handles `%x` scries specially - it expects an extra field at the end of the `path` that specifies a `mark`. Gall will attempt to perform a `mark` conversion from the `mark` returned by the scry endpoint to the `mark` specified. Note the trailing `mark` in the `path` will not be passed through to the agent itself.
44−
45−### What is an endpoint?
46−
47−"Endpoint" refers to a specific scry path in a vane or agent. They will sometimes informally be noted in documentation or source comments like `/x/foo/bar/baz` or maybe just `/foo/bar/baz`. The first part of the former example is the `care`, then the rest is the `path` portion as noted in the diagram earlier.
48−
49−If an agent's scry endpoints don't have formal documentation, you may need to refer to the `+on-peek` arm in its source code to determine its endpoints. While there's no exact pattern that's consistent across different agents, the general pattern will be some initial tests and conversions followed by a `?+` rune, whose cases will typically correspond to the endpoints. The `+on-peek` arm always return a `(unit (unit cage))` (a `cage` is a cell of `[mark vase]`), so each endpoint will typically finish by composing such a structure.
50−
51−Here's an example from the `+on-peek` arm of `%graph-store`:
52−
53−```hoon
54− [%x %keys ~]
55−:- ~ :- ~ :- %graph-update-2
56−!>(`update:store`[now.bowl [%keys ~(key by graphs)]])
57−```
58−
59−The case in the beginning says it takes a `%x` `care` and has a `path` of `/keys`. Additionally, it returns data with a `mark` of `%graph-update-2`. Assuming we wanted the `%graph-update-2` `mark` converted to a `%json` `mark`, our scry would be composed along the lines of:
60−
61−```hoon
62−.^(json %gx /(scot %p our)/graph-store/(scot %da now)/keys/json)
63−```
64−
65−### Web scries
66−
67−The webserver vane Eyre has a system which allows clients like web browsers to perform scries over HTTP. For details, refer to the [Scry section of Eyre's External API Reference](/docs/arvo/eyre/external-api-ref#scry).
68−
69−### Further reading
70−
71−[dotket](/docs/hoon/reference/rune/dot#-dotket) - Documentation of the `.^` rune which performs scries.
72−
73−[Arvo](/docs/arvo/overview) - Each vane has a Scry Reference section with details of their endpoints as well as examples.
74−
75−[Eyre's External API Reference](/docs/arvo/eyre/external-api-ref#scry) - Documentation of Eyre's scry system which allows web clients to perform scries over HTTP.
76−
77−[The Gall Guide](/docs/userspace/gall-guide/intro) - The Gall tutorial includes a section about `+on-peek` and writing scry endpoints.
content/docs/arvo/concepts/subscriptions.mddeleted−162
@@ -1,162 +0,0 @@
1−+++
2−title = "Subscriptions"
3−weight = 50
4−template = "doc.html"
5−+++
6−
7−Urbit relies heavily on subscriptions throughout the stack. We strongly
8−prefer reactive data flow compared to querying or polling, which is why
9−for example our equivalent to git natively supports subscriptions to its
10−data.
11−
12−We have many application-level styles of subscription, but we only have
13−three true subscription types in Arvo, named for the vane they're
14−implemented in: Clay subscriptions (filesystem), Gall subscriptions
15−(applications), and Jael subscriptions (Urbit ID info). They're at
16−three different points in the idea maze of subscriptions, and we'll
17−encounter each of them here.
18−
19−For our purposes, a subscription is a stream of events from a publisher
20−to a subscriber, where (1) the subscriber has indicated interest in that
21−stream, (2) any update sent to one subscriber is sent to all subscribers
22−on the same stream, and (3) when the publisher has a new update ready,
23−they send it immediately to their subscribers instead of waiting for a
24−later request.
25−
26−## Basic properties
27−
28−### Exactly-once updates
29−
30−Some subscriptions need the subscriber to receive each update separately
31−instead of collapsing them into a single diff. Sometimes a subscription
32−is really a sequence of commands, in which case there's no meaningful
33−way to collapse them. Similarly, software updates may be expected to be
34−applied in order.
35−
36−### Syncing data
37−
38−Other times, it's more natural to think of a subscription as
39−communicating a data structure, where the only goal is to keep the data
40−structure on the subscriber's side up-to-date with what's on the
41−publisher's side. In this case, it's perfectly fine to collapse several
42−updates into one large update, or even to resend the entire data
43−structure. Partial updates exist only as an optimization.
44−
45−For this sort of subscription, we commonly use terms like "diff" instead
46−of "message" or "update", and we say that we "apply a diff" instead of
47−"process an update". We also often identify the subscription with the
48−data structure itself.
49−
50−## Memory pressure
51−
52−Naively implemented, subscriptions pose a memory leak risk if the
53−subscriber can't receive updates as fast as the publisher wants to send
54−them. This commonly happens when the subscriber goes offline for an
55−extended period of time (possibly forever; especially for comets). It's
56−sufficient to bound the amount of memory dedicated to any particular
57−subscriber.
58−
59−In a synchronous system, you don't have to worry about what happens if
60−one side or the other ceases to be available. All of our subscriptions,
61−though, can happen between ships.
62−
63−### Small data
64−
65−For particularly low-volume subscriptions, it may be acceptable to
66−ignore the problem. Jael uses this approach, since the only time it's
67−used across ships is to update moon keys, which is very low-volume and
68−less than 1KB per update. If these subscriptions are used for more,
69−this strategy will have to be revisited.
70−
71−### Buffers
72−
73−A common solution to this problem is the venerable buffer. If more than
74−N updates need to be sent, start dropping updates. There are several
75−options for what to do when the buffer is full and the publisher wishes
76−to send another message:
77−
78−- Drop the oldest message. Particularly suitable for systems where new
79− messages obsolete old ones. For example, if you just need the latest
80− ticker price for an asset, you could use a buffer size of one and
81− replaced it any time you have a new price.
82−
83−- Don't add the new message to the buffer. Semantically this is usually
84− less helpful, but mechanically it can be simpler and reduce memory
85− churn, since the buffer stops changing and new messages are simply
86− ignored.
87−
88−- Drop the newest message and close the subscription. Unlike the
89− previous two, this is compatible with the principle of exactly-once
90− messaging. Specifically, it preserves the guarantee that you won't
91− receive two non-consecutive subscription updates, at the cost of making
92− you resubscribe if you fall behind.
93−
94−Gall subscriptions use the last of these. The buffer is bounded by a
95−simple heuristic, and when a subscription exceeds that buffer, it is
96−closed and the app is expected to resubscribe when they come back
97−online. Note that even though the subscription is closed, messages in
98−flight cannot be removed until they've been acknowledged since Ames
99−guarantees exactly-once messaging, so those last few messages will be
100−stuck in memory until the subscriber comes back online.
101−
102−Buffers are commonly bounded by size, but this puts constraints on the
103−types of messages may be sent. They may also be bounded in time: if the
104−subscriber stops taking messages for at least X time, the buffer is
105−full. Gall takes a hybrid approach; currently the heuristic is that the
106−buffer counts as full if it has at least five messages and it has been
107−30 seconds since a message was acknowledged.
108−
109−### One at a time
110−
111−Another scheme is to avoid multi-message subscriptions. Instead of
112−allowing the subscriber to subscribe to all future updates on a path,
113−allow them to "subscribe" to the _next_ update only. When they get that
114−update, they subscribe to the new next update, so that they ultimately
115−get every message.
116−
117−Commonly this is implemented where each update is given a version
118−number, and every time you hear update N you request update N+1 (even
119−though you won't get an answer for an indeterminate period of time).
120−
121−This is near the theoretical ideal for memory usage, since you'll never
122−queue up several messages to send to the subscriber.
123−
124−It also encourages processing each update in order rather than zooming
125−forward from time to time. It's possible (if a little awkward) to
126−simulate this with buffers though, and it's possible to allow zooming
127−forward in the one-at-a-time scheme by having the requests be "most
128−recent after update N" instead of "next after update N".
129−
130−This scheme is at its strongest, then, when you're already storing
131−intermediate states or updates, or when you don't care about
132−intermediate states and always send the most recent one. Otherwise,
133−buffers are a convenient place to temporarily store updates that you
134−don't want to store internally. Of course, if it's semantically
135−important that you give each update separately, buffers won't save you
136−from having to store the intermediate updates, since they may fill up.
137−
138−Another conceptual advantage is that it has no notion of "connectivity".
139−It operates forever in a single mode. By contrast, buffer-based
140−solutions must keep track of whether the buffer is full and react to
141−that. This increases complexity in the system, and complexity is the
142−great evil.
143−
144−The biggest disadvantage of this system is that it takes much longer to
145−process many small updates. With buffers, the publisher could have a
146−dozen small updates in flight at the same time, while in this scheme
147−they would only send one at a time, waiting for a response between each
148−one. Losing this pipelining can be quite significant for some
149−applications, but for low-volume subscriptions (certainly anything that
150−updates less than once per minute) this will have no noticeable effect.
151−
152−Clay uses this scheme. It's low-volume, it stores all previous states
153−anyway (since it's a revision-control system), and it's sometimes
154−important to get updates one at a time (for example when downloading OTA
155−software updates). Ships that send OTA updates often have many ships
156−subscribed to them, and the updates themselves may be large, so it's
157−important they don't queue up when ships inevitably disappear.
158−
159−I tend to think most Gall subscriptions should follow this pattern as
160−well. Our most latency-sensitive subscriptions are chat messages, and
161−while I haven't tested it, I would guess that even those wouldn't be
162−affected by this scheme.
content/docs/arvo/dill/_index.mddeleted−23
@@ -1,23 +0,0 @@
1−+++
2−title = "Dill"
3−weight = 40
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−insert_anchor_links = "right"
7−+++
8−
9−[Overview](/docs/avro/dill/dill)
10−
11−A brief overview of the Dill vane.
12−
13−[API Reference](/docs/arvo/dill/tasks)
14−
15−The `task`s Dill takes and the `gift`s it returns.
16−
17−[Scry Reference](/docs/arvo/dill/scry)
18−
19−The scry endpoints of Dill.
20−
21−[Data Types](/docs/arvo/dill/data-types)
22−
23−Reference documentation of the data types used by Dill.
content/docs/arvo/dill/data-types.mddeleted−187
@@ -1,187 +0,0 @@
1−+++
2−title = "Data Types"
3−weight = 4
4−template = "doc.html"
5−+++
6−
7−Here are the data types used by Dill, as defined in `/sys/lull.hoon`.
8−
9−## `$blew`
10−
11−```hoon
12− +$ blew [p=@ud q=@ud]
13−```
14−
15−Terminal dimension; `p` is columns, `q` is rows. This structure is passed to Dill by the runtime in a [%blew](/docs/arvo/dill/tasks#blew) `task` whenever the dimensions of the terminal changes.
16−
17−## `$belt`
18−
19−```hoon
20−+$ belt
21− $? bolt
22− $% [%mod mod=?(%ctl %met %hyp) key=bolt]
23− [%txt p=(list @c)]
24− [%ctl p=@c]
25− [%met p=@c]
26− == ==
27−```
28−
29−Terminal client input.
30−
31−A `$belt` is passed to Dill in a [%belt](/docs/arvo/dill/tasks#belt) `task` by the runtime whenever there is input, such as a user typing in the console. This is only used between the terminal client and Dill, a [$dill-belt](#dill-belt) is used between Dill and Arvo.
32−
33−May either be a [$bolt](#bolt) or one of:
34−
35−- `%mod` - Modifier (Ctrl, Meta or Hyper) plus [key].
36−- `%txt` - A series of characters
37−- `%ctl` - Ctrl+[key], deprecated in favour of `%mod`.
38−- `%met` - Meta+[key], deprecated in favour of `%mod`.
39−
40−## `$bolt`
41−
42−```hoon
43−+$ bolt
44− $@ @c
45− $% [%aro p=?(%d %l %r %u)]
46− [%bac ~]
47− [%del ~]
48− [%hit r=@ud c=@ud]
49− [%ret ~]
50− ==
51−```
52−
53−Simple input.
54−
55−Either a single simple character or one of:
56−
57−- `%aro` - Arrow keys.
58−- `%bac` - Backspace key.
59−- `%del` - Delete key.
60−- `%hit` - Mouse click - `r` is row and `c` is column. Note these are zero-indexed, with `[0 0]` being the _bottom left_ corner.
61−- `%ret` - Return (Enter) key.
62−
63−## `$blit`
64−
65−```hoon
66−+$ blit
67− $% [%bel ~]
68− [%clr ~]
69− [%hop p=@ud]
70− [%klr p=stub]
71− [%lin p=(list @c)]
72− [%mor ~]
73− [%sag p=path q=*]
74− [%sav p=path q=@]
75− [%url p=@t]
76− ==
77−```
78−
79−Terminal client output.
80−
81−A `$blit` is given to the terminal client by Dill in a `%blit` `gift` when it wants to print some text, clear the screen, go _ding_ or what have you.
82−
83−This is only used between Dill and the terminal client, a [$dill-blit](#dill-blit) is used instead between Arvo and Dill.
84−
85−A `$blit` is one of:
86−
87−- `%bel` - Ring the terminal bell.
88−- `%clr` - Clear the screen.
89−- `%hop` - Set cursor position, `p` specifies its position on the prompt line.
90−- `%klr` - Set styled line, the `$stub` specifies the text and style.
91−- `%lin` - Set current line, `p` contains the text.
92−- `%mor` - Newline.
93−- `%sag` - Save to jamfile, typically in `/[pier]/.urb/put/`. `p` is `/[path]/[filename]/[extension]`. For example, `/foo/bar` will save it in `/[pier]/.urb/put/foo.bar`, `/a/b/c/foo/bar` will save it in `/[pier]/.urb/put/a/b/c/foo.bar`, and `/foo` will save it in `/[pier]/.urb/put.foo`. `q` is the `noun` to `jam` and save in the file.
94−- `%sav` - Save to file. Same behaviour as `%sag` except `q` is an `atom` rather than a `noun` and therefore doesn't need to be `jam`med. The `atom` is written to disk as if it were the bytestring in the tail of an `$octs`. That is, `%sav`ing the `cord` `'abcdef'`, whose `@ux` value is `0x6665.6463.6261`, results in a unix file whose hex dump renders as `61 62 63 64 65 66`.
95−- `%url` - Activate URL, `p` is the URL.
96−
97−## `$dill-belt`
98−
99−```hoon
100−+$ dill-belt
101− $% [%aro p=?(%d %l %r %u)]
102− [%bac ~]
103− [%cru p=@tas q=(list tank)]
104− [%ctl p=@]
105− [%del ~]
106− [%hey ~]
107− [%met p=@]
108− [%ret ~]
109− [%rez p=@ud q=@ud]
110− [%txt p=(list @c)]
111− [%yow p=gill:gall]
112− ==
113−```
114−
115−Terminal input for Arvo.
116−
117−While [$belt](#belt) is used between the terminal client and Dill, `$dill-belt` is used between Dill and Arvo.
118−
119−a `$dill-belt` is one of:
120−
121−- `%aro` - Arrow keys.
122−- `%bac` - Backspace key.
123−- `%cru` - Echo error, `p` is an error `@tas` and `q` is a traceback.
124−- `%ctl` - Ctrl+[key].
125−- `%del` - Delete key.
126−- `%hey` - Refresh.
127−- `%met` - Meta+[key].
128−- `%ret` - Return key (Enter).
129−- `%rez` - Terminal resized, `p` is columns and `q` is rows.
130−- `%txt` - Text input.
131−- `%yow` - Connect to app.
132−
133−## `$dill-blit`
134−
135−```hoon
136−+$ dill-blit
137− $% [%bel ~]
138− [%clr ~]
139− [%hop p=@ud]
140− [%klr p=stub]
141− [%mor p=(list dill-blit)]
142− [%pom p=stub]
143− [%pro p=(list @c)]
144− [%qit ~]
145− [%out p=(list @c)]
146− [%sag p=path q=*]
147− [%sav p=path q=@]
148− [%url p=@t]
149− ==
150−```
151−
152−Terminal output from Arvo.
153−
154−While [$blit](#blit) is used between Dill and the terminal client, `$dill-blit` is used between Arvo and Dill.
155−
156−A `$dill-blit` is one of:
157−
158−- `%bel` - Terminal bell.
159−- `%clr` - Clear screen.
160−- `%hop` - Set cursor position, `p` is its horizontal position on the prompt line.
161−- `%klr` - Styled text, the `$stub` specifies both the text and style.
162−- `%mor` - Multiple `$dill-blit`.
163−- `%pom` - Styled prompt, the `$stub` specifies both the text and style.
164−- `%pro` - Set prompt, `p` is the text for the prompt.
165−- `%qit` - Close console.
166−- `%out` - Print text.
167−- `%sag` - Save `noun` to jamfile. See [$blit](#blit) section for further details.
168−- `%sav` - Save `atom` to file. See [$blit](#blit) section for further details.
169−- `%url` - Activate URL.
170−
171−## `$flog`
172−
173−```hoon
174−+$ flog
175− $% [%crop p=@ud]
176− [%crud p=@tas q=(list tank)]
177− [%heft ~]
178− [%meld ~]
179− [%pack ~]
180− [%text p=tape]
181− [%verb ~]
182− ==
183−```
184−
185−Wrapped Dill `task`s.
186−
187−These are a subset of Dill's `task`s which can be wrapped in a `%flog` `task`. See the [API Reference](/docs/arvo/dill/tasks) document for details of each of these `task`s.
content/docs/arvo/dill/dill.mddeleted−41
@@ -1,41 +0,0 @@
1−+++
2−title = "Overview"
3−weight = 1
4−template = "doc.html"
5−aliases = ["/docs/learn/arvo/dill/"]
6−+++
7−
8−The terminal driver vane.
9−
10−Keyboard events and the like from Unix are received by Dill as [%belt](/docs/arvo/dill/tasks#belt) `task`s, and Dill sends `%blit` `gift`s containing [$blit](/docs/arvo/dill/data-types#blit)s back to the runtime to be displayed in the Unix terminal. The manner of interacting with Dill differs depending on whether you're in userspace or kernelspace, as we'll explore below.
11−
12−## Kernelspace
13−
14−For technical reasons, Dill performs a handful of system tasks related to booting a ship and some memory operations. Aside from those, other Vanes mostly just pass Dill [tasks](/docs/arvo/dill/tasks) to print error messages and the like to the terminal.
15−
16−## Userspace
17−
18−Unlike in kernelspace, userspace applications are unlikely to `%pass` Dill `task`s directly. Instead, Dill looks at things in terms of sessions. A session is a pipeline between a client and a handler, where:
19−
20−- The client is an external input source and output sink; a terminal with with dimensions and so forth.
21−- The handler is an application in Urbit that interprets input, maybe does something with it, maybe produces output to be displayed in the client, etc.
22−
23−There are plans for Dill to support multiple independent sessions (i.e. independent terminal clients displaying and processing different information at the same time), but at this stage Dill only supports a single session. The client for this default session is just the Unix terminal via the Urbit runtime. The handler for the default session is the `%hood` app, whose `drum` module does the heavy lifting.
24−
25−`drum` is the CLI app manager. By default you'll have a couple of CLI applications running—`%dojo` and `%chat-cli`—which you can switch between with `ctrl+x`. You may also have additional CLI apps which you have attached with the `|link` command. It's `drum` that keeps track of which one is active, which one input should be routed to, which one should be displayed, what each prompt should look like, and so forth. Dill itself is oblivious to the distinction between these CLI apps. It only sees the default session with `drum`, so it just passes all input to `drum` and display whatever `drum` gives it.
26−
27−While `drum` talks with Dill in `$dill-belt`s and `$dill-blit`s, it talks to CLI apps with `$sole-action`s and `$sole-event`s, which are defined in the `sole` library. For more information on the `sole` library and the related `shoe` library, and for information on how to build CLI apps, you can refer to the [CLI app tutorial](/docs/hoon/guides/cli-tutorial).
28−
29−To give a basic idea of how keyboard events flow through these systems and produce terminal output, here's a diagram showing the messages in pseudo-Hoon:
30−
31−![Dill userspace diagram](https://media.urbit.org/docs/arvo/dill/dill-userspace.svg)
32−
33−You can use a [move trace](/docs/arvo/tutorials/move-trace) to get a hands-on feel for this data flow.
34−
35−## Sections
36−
37−[API Reference](/docs/arvo/dill/tasks) - The `task`s Dill takes and the `gift`s it returns.
38−
39−[Scry Reference](/docs/arvo/dill/scry) - The scry endpoints of Dill.
40−
41−[Data Types](/docs/arvo/dill/data-types) - Reference documentation of the data types used by Dill.
content/docs/arvo/dill/scry.mddeleted−45
@@ -1,45 +0,0 @@
1−+++
2−title = "Scry Reference"
3−weight = 3
4−template = "doc.html"
5−+++
6−
7−Here are the scry endpoints of Dill. They take a `%x` `care` and require the `desk` in the path prefix be empty, so the general format is `.^([type] %dx /=//=/[some-path])`.
8−
9−Dill only has a couple of scry endpoints, both of which begin with `/session//`. The empty `//` would be where the target session would be specified, but at this stage Dill can only return a result for the default session, so it's always empty.
10−
11−## /sessions//line
12−
13−A scry with a `care` of `%x` and a `path` of `/sessions//line` returns the current text of the prompt line of the default session. The type returned is a [$blit](/docs/arvo/dill/data-types#blit).
14−
15−#### Example
16−
17−```
18−> .^(blit:dill %dx /=//=/sessions//line)
19−[ %lin
20− p
21− ~[
22− ~-~~
23− ~-z
24− ~-o
25− ~-d
26− ~-~3a.
27− ~-d
28− ~-o
29− ~-j
30− ~-o
31− ...truncated for brevity...
32− ]
33−]
34−```
35−
36−## /sessions//cursor
37−
38−A scry with a `care` of `%x` and a `path` of `/sessions//cursor` returns the current horizontal position of the cursor in the default session. The type returned is a `@ud`.
39−
40−#### Example
41−
42−```
43−> .^(@ud %dx /=//=/sessions//cursor)
44−44
45−```
content/docs/arvo/dill/tasks.mddeleted−342
@@ -1,342 +0,0 @@
1−+++
2−title = "API Reference"
3−weight = 2
4−template = "doc.html"
5−+++
6−
7−In this document we describe the public interface for Dill. Namely, we describe each `task` that Dill can be `pass`ed, and which `gift`(s) Dill can `give` in return.
8−
9−## `%belt`
10−
11−```hoon
12−[%belt p=belt]
13−```
14−
15−Terminal input.
16−
17−The runtime sends a `%belt` `task` to Dill whenever there is input in the terminal, such as a keystroke.
18−
19−The [$belt](/docs/arvo/dill/data-types#belt) in `p` contains the input such as which key was pressed.
20−
21−Dill will convert the `$belt` into a [$dill-belt](/docs/arvo/dill/data-types#dill-belt) and `%poke` the session handler (typically `drum`) with it.
22−
23−This `task` would not typically be used from userspace.
24−
25−#### Returns
26−
27−Dill returns no `gift` in response to a `%belt` `task`.
28−
29−## `%blew`
30−
31−```hoon
32−[%blew p=blew]
33−```
34−
35−Terminal resized.
36−
37−The runtime passes Dill a `%blew` `task` whenever the terminal is resized.
38−
39−The [$blew](/docs/arvo/dill/data-types#blew) specifies the new dimensions.
40−
41−Dill will convert the `$blew` into a `%rez` [$dill-belt](/docs/arvo/dill/data-types#dill-belt) and `%poke`s the session handler (typically `drum`) with it.
42−
43−This `task` would not typically be used from userspace.
44−
45−#### Returns
46−
47−Dill returns no `gift` in response to a `%blew` `task`.
48−
49−## `%boot`
50−
51−```hoon
52−[%boot lit=? p=*]
53−```
54−
55−This `task` is used only once, when Arvo first enters the [adult stage](/docs/arvo/overview#structural-interface-core). Dill is technically the first vane to be activated, via the `%boot` `task`, which then sends Jael (considered the "true" first vane) the `%dawn` or `%fake` `task` wrapped in the `%boot` `task`. Jael then goes on to call `%init` `task`s for other vanes (including Dill).
56−
57−`lit` specifies whether to boot in lite mode. `p` is either a [%dawn](/docs/arvo/jael/data-types#dawn) or [%fake](/docs/arvo/jael/tasks#fake) `task:jael`. `%dawn` is for an ordinary boot and `%fake` is for booting a fake ship.
58−
59−This `task` would not be used from userspace.
60−
61−#### Returns
62−
63−Dill returns no `gift` in response to a `%boot` `task`, but it will `%pass` the wrapped `%dawn` or `%fake` `task` to Jael.
64−
65−## `%crop`
66−
67−```hoon
68−[%crop p=@ud]
69−```
70−
71−Trim kernel state.
72−
73−This `task` is the same as the [%trim](#trim) `task`. Like `%trim`, Dill does nothing with it.
74−
75−#### Returns
76−
77−Dill returns no `gift` in response to a `%crop` `task`.
78−
79−## `%crud`
80−
81−```hoon
82−[%crud p=@tas q=(list tank)]
83−```
84−
85−Print error.
86−
87−Dill prints the given error to the terminal. The verbosity for the particular `@tas` error tag specified in `p` is determined by the `level` set by a [%knob](#knob) `task` - either `%hush`, `%soft` or `%loud`. The default is `%loud`, where it will print the full `(list tank)` specified in `q`. See [%knob](#knob) for details of verbosity levels.
88−
89−#### Returns
90−
91−Dill does not return a `gift` in response to a `%crud` `task`.
92−
93−## `%flee`
94−
95−```hoon
96−[%flee session=~]
97−```
98−
99−Unwatch a session to which you've previously subscribed with [%view](#view).
100−
101−The ability to specify a session is not yet implemented in Dill, so `session` is always `~`, the default session.
102−
103−#### Returns
104−
105−Dill does not return a `gift` in response to a `%flee` `task`.
106−
107−## `%flog`
108−
109−```hoon
110−[%flog p=flog]
111−```
112−
113−A `%flog` `task` is a wrapper over a `task` sent by another vane. Dill removes the wrapper and sends the bare `task` to itself over the default `duct`.
114−
115−A `%flog` `task` takes a [$flog](/docs/arvo/dill/data-types#flog) as its argument. A `$flog` is a subset of Dill's `task`s.
116−
117−#### Returns
118−
119−Dill does not return a `gift` in response to a `%flog` `task`.
120−
121−## `%flow`
122−
123−```hoon
124−[%flow p=@tas q=(list gill:gall)]
125−```
126−
127−Terminal config.
128−
129−This `task` is not used.
130−
131−## `%hail`
132−
133−```hoon
134−[%hail ~]
135−```
136−
137−Refresh.
138−
139−Dill converts a `%hail` `task` into a `%hey` [$dill-belt](/docs/arvo/dill/data-types#dill-belt) and `%poke`s the session handler (typically `drum`) with it to handle the refresh.
140−
141−This `task` would not be used from userspace.
142−
143−#### Returns
144−
145−Dill returns no `gift` in response to a `%hail` `task`.
146−
147−## `%heft`
148−
149−```hoon
150−[%heft ~]
151−```
152−
153−Produce memory report.
154−
155−When Dill receives a `%heft` `task` it passes Arvo a `%whey` `waif` to obtain a memory report and prints it to the terminal.
156−
157−#### Returns
158−
159−Dill does not return a `gift` in response to a `%heft` `task`.
160−
161−## `%hook`
162−
163−```hoon
164−[%hook ~]
165−```
166−
167−This terminal hung up.
168−
169−This task is not used.
170−
171−## `%harm`
172−
173−```hoon
174−[%harm ~]
175−```
176−
177−All terminals hung up.
178−
179−This `task` is not used.
180−
181−## `%init`
182−
183−```hoon
184−[%init ~]
185−```
186−
187−This `task` is called only once, when Arvo first enters the [adult stage](/docs/arvo/overview#structural-interface-core). It performs initial setup for Dill, such as setting the width of the console.
188−
189−Note that this is not actually the first `task` passed to Dill - see [%boot](#%boot).
190−
191−This `task` would not be used from userspace.
192−
193−#### Returns
194−
195−Dill does not return a `gift` in response to a `%init` `task`.
196−
197−## `%meld`
198−
199−```
200−[%meld ~]
201−```
202−
203−Deduplicate persistent state.
204−
205−Dill asks the runtime to perform the memory deduplication.
206−
207−#### Returns
208−
209−Dill does not return a `gift` in response to a `%meld` `task`.
210−
211−## `%noop`
212−
213−```hoon
214−[%noop ~]
215−```
216−
217−No operation.
218−
219−A `%noop` `task` does nothing, as the name implies.
220−
221−#### Returns
222−
223−Dill does not return a `gift` in response to a `%noop` `task`.
224−
225−## `%pack`
226−
227−```hoon
228−[%pack ~]
229−```
230−
231−Defragment persistent state.
232−
233−Dill asks the runtime to perform the defragmentation.
234−
235−#### Returns
236−
237−Dill does not return a `gift` in response to a `%meld` `task`.
238−
239−## `%talk`
240−
241−```hoon
242−[%talk p=tank]
243−```
244−
245−This `task` is not used.
246−
247−## `%text`
248−
249−```hoon
250−[%text p=tape]
251−```
252−
253−Print `tape` to terminal.
254−
255−Upon receiving a `%text` `task`, Dill will convert the `tape` given in `p` to a `(list @c)` and give it to the runtime in a `%blit` `gift` including a `%lin` [$blit](/docs/arvo/dill/data-types#blit).
256−
257−#### Returns
258−
259−Dill does not return a `gift` in response to a `%text` `task`, but it does give a `%blit` `gift` to the runtime which looks like:
260−
261−```hoon
262−[%blit p=(list blit)]
263−```
264−
265−## `%view`
266−
267−```hoon
268−[%view session=~]
269−```
270−
271−Watch session.
272−
273−A `%view` `task` subscribes for a copy of all `%blit` `gift`s which Dill `%give`s for the default session. This `task` is used by the `%herm` app so it can convert the `$blit`s to JSON and render them in the web terminal.
274−
275−The ability to specify a session is not yet implemented in Dill, so `session` is always `~`, the default session.
276−
277−#### Returns
278−
279−Dill will `%give` a copy of all `%blit`s for the default session. A `%blit` `gift` is:
280−
281−```hoon
282−[%blit p=(list blit)]
283−```
284−
285−## `%trim`
286−
287−```hoon
288−[%trim p=@ud]
289−```
290−
291−`%trim` is a common vane `task` used to reduce memory usage. It does nothing for Dill because Dill only keeps a minimal necessary state.
292−
293−#### Returns
294−
295−Dill does not return a `gift` in response to a `%trim` `task`.
296−
297−## `%vega`
298−
299−```hoon
300−[%vega ~]
301−```
302−
303−This is a common vane `task` used to inform the vane that the kernel has been
304−upgraded. Dill does not do anything in response to this.
305−
306−This `task` would not be used from userspace.
307−
308−#### Returns
309−
310−Dill returns no `gift` in response to a `%vega` `task`.
311−
312−## `%verb`
313−
314−```hoon
315−[%verb ~]
316−```
317−
318−This `task` toggles verbose mode for all of Arvo, which is located here since
319−Dill is the vane that prints errors. To be precise, `%verb` toggles the laconic
320−bit `lac` in the [Arvo state](/docs/arvo/overview#the-state) by passing a `%verb` `waif` to Arvo.
321−
322−#### Returns
323−
324−Dill does not return a `gift` in response to a `%verb` `task`.
325−
326−## `%knob`
327−
328−```hoon
329−[%knob tag=term level=?(%hush %soft %loud)]
330−```
331−
332−`%knob` sets the verbosity level for each error tag. The error `tag` can be any `@tas`. The given `tag` and `level` will be added to Dill's `veb` which maps tags to levels. Subsequent [%crud](#crud) `task`s will then print with the specified verbosity.
333−
334−The `level`s behave like so:
335−
336−- `%hush` - Completely silent, print nothing.
337−- `%soft` - Just print `crud: %error-tag event failed`, ignore any `tang` given in the `%crud`.
338−- `%loud` - Print the `%soft` message as well as the full `tang` given in the `%crud` `task`.
339−
340−#### Returns
341−
342−Dill does not return a `gift` in response to a `%knob` `task`.
content/docs/arvo/eyre/_index.mddeleted−31
@@ -1,31 +0,0 @@
1−+++
2−title = "Eyre"
3−weight = 50
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−insert_anchor_links = "right"
7−+++
8−
9−## [Overview](/docs/arvo/eyre/eyre)
10−
11−An overview of Eyre and its capabilities.
12−
13−## [External API Reference](/docs/arvo/eyre/external-api-ref)
14−
15−Details of Eyre's external API including the channel system's JSON API.
16−
17−## [Internal API Reference](/docs/arvo/eyre/tasks)
18−
19−The `task`s Eyre takes and the `gift`s it returns.
20−
21−## [Scry Reference](/docs/arvo/eyre/scry)
22−
23−The scry endpoints of Eyre.
24−
25−## [Data Types](/docs/arvo/eyre/data-types)
26−
27−Reference documentation of the various data types used by Eyre.
28−
29−## [Guide](/docs/arvo/eyre/guide)
30−
31−Practical examples of the different ways of using Eyre.
content/docs/arvo/eyre/data-types.mddeleted−289
@@ -1,289 +0,0 @@
1−+++
2−title = "Data Types"
3−weight = 5
4−template = "doc.html"
5−+++
6−
7−This document describes the data types used by Eyre as defined in `/sys/lull.hoon`. It's separated into two sections:
8−
9−[Eyre](#eyre) - Eyre-specific data types.
10−
11−[HTTP](#http) - HTTP data types shared between Eyre and Iris.
12−
13−## Eyre
14−
15−### `$origin`
16−
17−```hoon
18−+$ origin @torigin
19−```
20−
21−A single CORS origin as used in an HTTP Origin header and the [$cors-registry](#cors-registry).
22−
23−### `$cors-registry`
24−
25−```hoon
26−+$ cors-registry
27− $: requests=(set origin)
28− approved=(set origin)
29− rejected=(set origin)
30− ==
31−```
32−
33−CORS origins categorised by approval status. The `requests` `set` contains all [$origin](#origin)s Eyre has received in the headers of HTTP requests that have not been explicitly approved or rejected. The `approved` and `rejected` `set`s are those that have been explicitly approved or rejected.
34−
35−### `$outstanding-connection`
36−
37−```hoon
38−+$ outstanding-connection
39− $: =action
40− =inbound-request
41− response-header=(unit response-header:http)
42− bytes-sent=@ud
43− ==
44−```
45−
46−An HTTP connection that is currently open. The [$action](#action) is how it's being handled (e.g. by a Gall app, the channel system, etc). The [$inbound-request](#inbound-request) is the original request which opened the connection. The `response-header` contains the status code and headers. The `bytes-sent` is the total bytes sent so far in response.
47−
48−### `$authentication-state`
49−
50−```hoon
51−+$ authentication-state sessions=(map @uv session)
52−```
53−
54−This represents the authentication state of all sessions. It maps session cookies (without the `urbauth-{SHIP}=` prefix) to [$session](#session)s.
55−
56−### `$session`
57−
58−```hoon
59−+$ session
60− $: expiry-time=@da
61− channels=(set @t)
62− ==
63−```
64−
65−This represents server-side data about a session. The `expiry-time` is when the `session` expires and `channels` is the `set` of [$channel](#channel) names opened by the session.
66−
67−### `$channel-state`
68−
69−```hoon
70−+$ channel-state
71− $: session=(map @t channel)
72− duct-to-key=(map duct @t)
73− ==
74−```
75−
76−The state used by the channel system. The `session` is a `map` between channel names and [$channel](#channel)s and the `duct-to-key` `map`s `duct`s to `channel` names.
77−
78−### `$timer`
79−
80−```hoon
81−+$ timer
82− $: date=@da
83− =duct
84− ==
85−```
86−
87−A reference to a timer so it can be cancelled or updated. The `date` is when it will fire and the `duct` is what set the timer.
88−
89−### `$channel-event`
90−
91−```hoon
92−+$ channel-event
93− $% $>(%poke-ack sign:agent:gall)
94− $>(%watch-ack sign:agent:gall)
95− $>(%kick sign:agent:gall)
96− [%fact =mark =noun]
97− ==
98−```
99−
100−An unacknowledged event in the channel system.
101−
102−### `$channel`
103−
104−```hoon
105−+$ channel
106− $: state=(each timer duct)
107− next-id=@ud
108− last-ack=@da
109− events=(qeu [id=@ud request-id=@ud =channel-event])
110− unacked=(map @ud @ud)
111− subscriptions=(map @ud [ship=@p app=term =path duc=duct])
112− heartbeat=(unit timer)
113− ==
114−```
115−
116−This is the state of a particular channel in the channel system. The `state` is either the expiration time or the duct currently listening. The `next-id` is the next event ID to be used in the event stream. The `last-ack` is the date of the last client ack and is used for clog calculations in combination with `unacked`. The `events` queue contains all unacked events - `id` is the server-set event ID, `request-id` is the client-set request ID and the [$channel-event](#channel-event) is the event itself. The `unacked` `map` contains the unacked event count per `request-id` and is used for clog calculations. The `subscriptions` `map` contains gall subscriptions by `request-id`. The `heartbeat` is the SSE heartbeat [$timer](#timer).
117−
118−### `$binding`
119−
120−```hoon
121−+$ binding
122− $: site=(unit @t)
123− path=(list @t)
124− ==
125−```
126−
127−A `binding` is a rule to match a URL `path` and optional `site` domain which can then be tied to an [$action](#action). A `path` of `/foo` will also match `/foo/bar`, `/foo/bar/baz`, etc. If the `site` is `~` it will be determined implicitly. A binding must be unique.
128−
129−### `$action`
130−
131−```hoon
132−+$ action
133− $% [%gen =generator] :: dispatch to a generator
134− [%app app=term] :: dispatch to an application
135− [%authentication ~] :: internal authentication page
136− [%logout ~] :: internal logout page
137− [%channel ~] :: gall channel system
138− [%scry ~] :: gall scry endpoint
139− [%four-oh-four ~] :: respond with the default file not found page
140− ==
141−```
142−
143−The action to take when a [$binding](#binding) matches an incoming HTTP request.
144−
145−### `$generator`
146−
147−```hoon
148−+$ generator
149− $: =desk :: desk on current ship that contains the generator
150− path=(list @t) :: path on :desk to the generator's hoon file
151− args=* :: args: arguments passed to the gate
152− ==
153−```
154−
155−This refers to a generator on a local ship that can handle requests. Note that serving generators via Eyre is not fully implmented and should not be used.
156−
157−### `$http-config`
158−
159−```hoon
160−+$ http-config
161− $: secure=(unit [key=wain cert=wain])
162− proxy=_|
163− log=?
164− redirect=?
165− ==
166−```
167−
168−The configuration of the runtime HTTP server itself. The `secure` field contains the PEM-encoded RSA private key and certificate or certificate chain when using HTTPS, and otherwise is `~` when using plain HTTP. The `proxy` field is not currently used. The `log` field turns on HTTP(S) access logs but is not currently implemented. The `redirect` field turns on 301 redirects to upgrade HTTP to HTTPS if the `key` and `cert` are set in `secure`.
169−
170−### `$http-rule`
171−
172−```hoon
173−+$ http-rule
174− $% [%cert cert=(unit [key=wain cert=wain])]
175− [%turf action=?(%put %del) =turf]
176− ==
177−```
178−
179−This is for updating the server configuration. In the case of `%cert`, a `cert` of `~` clears the HTTPS cert & key, otherwise `cert` contains the PEM-encoded RSA private key and certificate or certificate chain. In the case of `%turf`, a `%put` `action` sets a domain name and a `%del` `action` removes it. The [$turf](#turf) contains the domain name.
180−
181−### `$address`
182−
183−```hoon
184−+$ address
185− $% [%ipv4 @if]
186− [%ipv6 @is]
187− ==
188−```
189−
190−A client IP address.
191−
192−### `$inbound-request`
193−
194−```hoon
195−+$ inbound-request
196− $: authenticated=?
197− secure=?
198− =address
199− =request:http
200− ==
201−```
202−
203−An inbound HTTP request and metadata. The `authenticated` field says whether the request was made with a valid session cookie. The `secure` field says whether it was made with HTTPS. The [$address](#address) is the IP address from which the request originated, except if it came from localhost and included a `Forwarded` header, in which case it's the address specified in that header. The [$request:http](#requesthttp) contains the HTTP request itself.
204−
205−## HTTP
206−
207−### `$header-list:http`
208−
209−```hoon
210−+$ header-list (list [key=@t value=@t])
211−```
212−
213−An ordered list of HTTP headers. The `key` is the header name e.g `'Content-Type'` and the `value` is the value e.g. `text/html`.
214−
215−### `$method:http`
216−
217−```hoon
218−+$ method
219− $? %'CONNECT'
220− %'DELETE'
221− %'GET'
222− %'HEAD'
223− %'OPTIONS'
224− %'POST'
225− %'PUT'
226− %'TRACE'
227− ==
228−```
229−
230−An HTTP method.
231−
232−### `$request:http`
233−
234−```hoon
235−+$ request
236− $: method=method
237− url=@t
238− =header-list
239− body=(unit octs)
240− ==
241−```
242−
243−A single HTTP request. The [$method:http](#methodhttp) is the HTTP method, the `url` is the unescaped URL, the [$header-list:http](#header-listhttp) contains the HTTP headers of the request and the `body` is the actual data. An `octs` is just `[p=@ud q=@]` where `p` is the byte-length of `q`, the data.
244−
245−### `$response-header:http`
246−
247−```hoon
248−+$ response-header
249− $: status-code=@ud
250− headers=header-list
251− ==
252−```
253−
254−The status code and [$header-list:http](#header-listhttp) of an HTTP response.
255−
256−### `$http-event:http`
257−
258−```hoon
259−+$ http-event
260− $% $: %start
261− =response-header
262− data=(unit octs)
263− complete=?
264− ==
265− $: %continue
266− data=(unit octs)
267− complete=?
268− ==
269− [%cancel ~]
270− ==
271−```
272−
273−Packetized HTTP.
274−
275−Urbit treats Earth's HTTP servers as pipes, where Urbit sends or receives one or more `http-event`s. The first of these will be a `%start`, and the last will always be `%cancel` or will have `complete` set to `%.y` to finish the connection.
276−
277−Calculation of control headers such as `'Content-Length'` or `'Transfer-Encoding'` should be performed at a higher level; this structure is merely for what gets sent to or received from Earth.
278−
279−### `$simple-payload:http`
280−
281−```hoon
282−+$ simple-payload
283− $: =response-header
284− data=(unit octs)
285− ==
286−--
287−```
288−
289−A simple, one-event response used for generators. The [$reponse-header:http](#response-headerhttp) contains the status code and HTTP headers. The `octs` in the `data` contains the body of the response and is a `[p=@ud q=@]` where `p` is the byte-length of `q`, the data.
content/docs/arvo/eyre/external-api-ref.mddeleted−359
@@ -1,359 +0,0 @@
1−+++
2−title = "External API Reference"
3−weight = 2
4−template = "doc.html"
5−+++
6−
7−This document contains reference information about Eyre's external APIs including [the channel system](#channels) and [scries](#scry). Each section will also have practical examples in the [Guide](/docs/arvo/eyre/guide) document.
8−
9−## Authentication
10−
11−To use Eyre's channel system, run threads or perform scries you must first obtain a session cookie by authenticating with the following HTTP request:
12−
13−| HTTP Method | Data | URL Path | Notes |
14−| ----------- | -------------------------------------- | ---------- | ----------------------------------------------------------------------------------- |
15−| `POST` | `password=lidlut-tabwed-pillex-ridrup` | `/~/login` | The password is your web login code which can be obtained with `+code` in the dojo. |
16−
17−See the [Guide](/docs/arvo/eyre/guide#authenticating) for an example of how to do this using the curl.
18−
19−Eyre's response will include a `set-cookie` header like:
20−
21−```
22−set-cookie: urbauth-~zod=0v4.ilskp.psv00.t09r0.l8rps.3n97v; Path=/; Max-Age=604800
23−```
24−
25−The `urbauth-{...}` cookie provided must be included in a `cookie` header with all subsequent requests like:
26−
27−```
28−cookie: urbauth-~zod=0v4.ilskp.psv00.t09r0.l8rps.3n97v
29−```
30−
31−## Channels
32−
33−Eyre's channel system is the primary way of interacting with Gall agents from outside of Urbit.
34−
35−Data from an external HTTP client is sent to Eyre as an [HTTP PUT request](#http-requests) containing one or more [action](#actions) JSON objects. Clients must obtain a session cookie by [authenticating](#authentication) with Eyre in order to make such requests.
36−
37−Data from Eyre is sent back to the external HTTP client on a channel as SSEs ([Server Sent Events](https://html.spec.whatwg.org/#server-sent-events)) containing a [response](#responses) JSON object.
38−
39−A new channel is automatically created whenever a client sends an [action](#action) in an [HTTP PUT request](#http-requests) to `http{s}://{host}{port}/~/channel/{uid}` with a new `uid`. To connect to the channel and receive any pending events, you just send an HTTP GET request with a valid session cookie to that URL.
40−
41−The response you'll get to the GET request will be an event stream. Events will come in like:
42−
43−```
44−id: 0
45−data: {"ok":"ok","id":1,"response":"poke"}
46−```
47−
48−If you're working with Javascript in the browser context you'll handle these with an EventSource object or by using fetch and ReadableStream. If you're using another language, there'll likely be a library available to handle SSEs.
49−
50−All the events that Eyre sends you on a channel must be [ack](#ack)ed so that Eyre can forget about them and clear them from the channel state. If `fact`s (as [diff](#diff)s) from Gall agents to which you've subscribed are left un`ack`ed long enough, Eyre will consider the particular subscription clogged and automatically unsubscribe you. Note that `ack`ing one event will implicitly `ack` all previous events.
51−
52−When you're finished with a channel, you can send Eyre a [delete action](#delete-channel) to close it.
53−
54−See the [Using the Channel System](/docs/arvo/eyre/guide#using-channels) section of the [Guide](/docs/arvo/eyre/guide) document for a practical example.
55−
56−### HTTP Requests
57−
58−[Actions](#actions) are sent to Eyre in HTTP PUT requests:
59−
60−| HTTP Method | Required Headers | Data | URL Path |
61−| ----------- | ------------------------- | -------------------------------------------------------------- | ------------------ |
62−| `PUT` | `Content-Type` & `Cookie` | One or more [actions](#actions) wrapped in a JSON array (`[]`) | `/~/channel/{uid}` |
63−
64−The `cookie` header contains the session cookie obtained by [authenticating](#authentication). The data is a JSON array containing one or more JSON [action](#actions) objects. The channel `uid` is a unique name of your choosing. Typically you'd use the current unix time and a hash but there's no specific requirements. If you're opening a new channel you'd choose a new `uid` and if you already have a channel open you'd just use that.
65−
66−If successful, Eyre will respond with a status code of 204. Note the HTTP response will have no content, any [responses](#responses) will be sent as SSEs on the channel event stream.
67−
68−## Actions
69−
70−### Poke
71−
72−This is for poking a Gall agent.
73−
74−| Key | JSON Type | Example Value | Description |
75−| -------- | --------- | ------------- | ------------------------------------------------------------- |
76−| `id` | Number | `1` | ID for keeping track of sent messages. |
77−| `action` | String | `'poke'` | The kind of action. |
78−| `ship` | String | `'zod'` | Target ship name, excluding leading `~`. |
79−| `app` | String | `'hood'` | Name of the gall agent you're poking. |
80−| `mark` | String | `'helm-hi'` | Type of data. Must correspond to a mark definition in `/mar`. |
81−| `json` | Any | `'hello'` | Actual payload. Any JSON type, determined by app. |
82−
83−#### Example
84−
85−```json
86−{
87− "id": 1,
88− "action": "poke",
89− "ship": "zod",
90− "app": "hood",
91− "mark": "helm-hi",
92− "json": "hello"
93−}
94−```
95−
96−#### Response
97−
98−Eyre will send a [poke ack](#poke-ack) as an SSE event on the channel event stream.
99−
100−### Subscribe
101−
102−This is for subscribing to a watch `path` of a Gall agent.
103−
104−| Key | JSON Type | Example Value | Description |
105−| -------- | --------- | --------------- | --------------------------------------------------- |
106−| `id` | Number | `2` | ID for keeping track of sent messages. |
107−| `action` | String | `'subscribe'` | The kind of action. |
108−| `ship` | String | `'zod'` | Target ship name, excluding leading `~`. |
109−| `app` | String | `'graph-store'` | Name of the gall agent to which you're subscribing. |
110−| `path` | String | `'/updates'` | The path to watch. Depends on the app. |
111−
112−#### Example
113−
114−```json
115−{
116− "id": 2,
117− "action": "subscribe",
118− "ship": "zod",
119− "app": "graph-store",
120− "path": "/updates"
121−}
122−```
123−
124−#### Response
125−
126−Eyre will send back a [watch ack](#watch-ack). If subscribing was successful, you will also begin receiving any [diff](#diff)s sent by the Gall agent on the specified `path`.
127−
128−### Ack
129−
130−This is for acknowledging an SSE event. If you `ack` one event, you also implicitly `ack` all previous events. Events _must_ be `ack`ed so that Eyre can forget them. If you leave `fact`s (as [diff](#diff)s) un`ack`ed long enough, Eyre will consider the subscription clogged and automatically unsubscribe you.
131−
132−| Key | JSON Type | Example Value | Description |
133−| ---------- | --------- | ------------- | -------------------------------------------------------- |
134−| `id` | Number | `3` | ID for keeping track of sent messages. |
135−| `action` | String | `'ack'` | The kind of action. |
136−| `event-id` | Number | `7` | ID of SSE event up to which you're acknowledging receipt |
137−
138−#### Example
139−
140−```json
141−{
142− "id": 3,
143− "action": "ack",
144− "event-id": 7
145−}
146−```
147−
148−#### Response
149−
150−Eyre will not respond to an `ack` action.
151−
152−### Unsubscribe
153−
154−This is for unsubscribing from a Gall agent watch `path` to which you've previously subscribed.
155−
156−| Key | JSON Type | Example Value | Description |
157−| -------------- | --------- | ------------- | ---------------------------------------------------------- |
158−| `id` | Number | `4` | ID for keeping track of sent messages. |
159−| `action` | String | `unsubscribe` | The kind of action. |
160−| `subscription` | Number | `2` | Request ID of the initial `subscribe` action from earlier. |
161−
162−#### Example
163−
164−```json
165−{
166− "id": 4,
167− "action": "unsubscribe",
168− "subscription": 2
169−}
170−```
171−
172−#### Response
173−
174−Eyre will not respond to an `unsubscribe` action.
175−
176−### Delete Channel
177−
178−This is for deleting the channel itself.
179−
180−| Key | JSON Type | Example Value | Description |
181−| -------- | --------- | ------------- | -------------------------------------- |
182−| `id` | Number | `5` | ID for keeping track of sent messages. |
183−| `action` | String | `'delete'` | The kind of action. |
184−
185−#### Example
186−
187−```json
188−{
189− "id": 5,
190− "action": "delete"
191−}
192−```
193−
194−#### Response
195−
196−Eyre will not respond to a `delete` action.
197−
198−## Responses
199−
200−### Poke Ack
201−
202−This acknowledgement comes in response to a [poke](#poke) action. A poke ack with an `ok` key means the poke succeeded. A poke ack with an `err` key means the poke failed.
203−
204−#### Positive Poke Ack
205−
206−| Key | JSON Type | Example Value | Description |
207−| ---------- | --------- | ------------- | -------------------------------------------- |
208−| `ok` | String | `'ok'` | Positive acknowledgement. |
209−| `id` | Number | `1` | Request ID of the `poke` being acknowledged. |
210−| `response` | String | `'poke'` | The kind of action being acknowledged. |
211−
212−#### Example
213−
214−```json
215−{
216− "ok": "ok",
217− "id": 1,
218− "response": "poke"
219−}
220−```
221−
222−#### Negative Poke Ack
223−
224−| Key | JSON Type | Example Value | Description |
225−| ---------- | --------- | ---------------- | --------------------------------------------------------------------- |
226−| `err` | String | `'some text...'` | Negative acknowledgement. Contains an error message and/or traceback. |
227−| `id` | Number | `1` | Request ID of the `poke` being acknowledged. |
228−| `response` | String | `'poke'` | The kind of action being acknowledged. |
229−
230−#### Example
231−
232−```json
233−{
234− "err": "<error message and traceback>",
235− "id": 1,
236− "response": "poke"
237−}
238−```
239−
240−#### Action Required
241−
242−You must ack the event.
243−
244−### Watch Ack
245−
246−This acknowledgement comes in response to a [subscribe](#subscribe) action. A watch ack with an `ok` key means the subscription was successful. A watch ack with an `err` key means the subscription failed.
247−
248−#### Positive Watch Ack
249−
250−| Key | JSON Type | Example Value | Description |
251−| ---------- | --------- | ------------- | --------------------------------------------- |
252−| `ok` | String | `'ok'` | Positive acknowledgement. |
253−| `id` | Number | `2` | Request ID of the initial `subscribe` action. |
254−| `response` | String | `'subscribe'` | The kind of action being acknowledged. |
255−
256−#### Example
257−
258−```json
259−{
260− "ok": "ok",
261− "id": 2,
262− "response": "subscribe"
263−}
264−```
265−
266−#### Negative Watch Ack
267−
268−| Key | JSON Type | Example Value | Description |
269−| ---------- | --------- | ---------------- | --------------------------------------------------------------------- |
270−| `err` | String | `'some text...'` | Negative acknowledgement. Contains an error message and/or traceback. |
271−| `id` | Number | `2` | Request ID of the initial `subscribe` action. |
272−| `response` | String | `'subscribe'` | The kind of action being acknowledged. |
273−
274−#### Example
275−
276−```json
277−{
278− "err": "<error message and traceback>",
279− "id": 2,
280− "response": "subscribe"
281−}
282−```
283−
284−#### Action Required
285−
286−You must ack the event.
287−
288−### Diff
289−
290−All `fact`s sent by a Gall agent on the `path` to which you've subscribed are delivered as `diff`s. Note that Eyre makes a best effort to convert the `fact` to a `json` mark. If it can't, Eyre will crash and close the subscription, and you won't receive any `diff` for the `fact`.
291−
292−| Key | JSON Type | Example Value | Description |
293−| ---------- | --------- | ---------------- | ------------------------------------------------------------ |
294−| `json` | Any | `{'foo': 'bar'}` | The actual data from the agent, could be any JSON structure. |
295−| `id` | Number | `3` | Request ID of the initial `subscribe` action from earlier. |
296−| `response` | String | `'diff'` | The kind of response. All `fact`s are marked `'diff'`. |
297−
298−#### Example
299−
300−```json
301−{
302− "json": { "foo": "bar" },
303− "id": 3,
304− "response": "diff"
305−}
306−```
307−
308−#### Action Required
309−
310−You must [ack](#ack) each `diff` that comes in the event stream.
311−
312−### Quit
313−
314−A `quit` comes in when a subscription has been ended. You may be intentionally kicked by the Gall agent to which you're subscribed, but certain network conditions can also trigger a `quit`. As a result, it's best to try and re[subscribe](#subscribe) when you get a `quit`, and if the resulting [watch ack](#watch-ack) is negative you can then conclude the `quit` was intentional and give up.
315−
316−| Key | JSON Type | Example Value | Description |
317−| ---------- | --------- | ------------- | --------------------------------------------- |
318−| `id` | Number | `4` | Request ID of the initial `subscribe` action. |
319−| `response` | String | `'quit'` | The kind of response. |
320−
321−#### Example
322−
323−```json
324−{
325− "id": 4,
326− "response": "quit"
327−}
328−```
329−
330−#### Action Required
331−
332−You must ack the event and you may wish to try and re[subscribe](#subscribe).
333−
334−## Scry
335−
336−A scry is a read-only request for some data.
337−
338−A scry takes the form of an [authenticated](#authentication) HTTP GET request to a URL path with the following format:
339−
340−```
341−http{s}://{host}/~/scry/{app}{path}.{mark}
342−```
343−
344−The `{app}` is the name of the Gall agent you want to query, for example `graph-store`.
345−
346−The `{path}` is a scry endpoint of the Gall agent in question. Eyre will always scry with a care of `%x`, so the `{path}` needn't specify that. For example, the `/x/keys` scry endpoint of `graph-store` would just be specified as `keys`.
347−
348−The `{mark}` is the type you want returned. It needn't just be `json` as with the channel system, it can be any `mark`, with two conditions:
349−
350−1. It must be possible to convert the `mark` produced by the specified scry endpoint to the `mark` you want returned.
351−2. It must be possible to convert the `mark` you want returned to a `mime` `mark`, otherwise Eyre can't encode it in the HTTP response.
352−
353−If your session cookie is invalid or missing, Eyre will respond with a 403 Forbidden status. If the scry endpoint cannot be found, Eyre will respond with a 404 Missing status. If the `mark` conversions can't be done, Eyre will respond with a 500 Internal Server Error status. Otherwise, Eyre will respond with a 200 OK status with the requested data in the body of the HTTP response.
354−
355−See the [Scrying](/docs/arvo/eyre/guide#scrying) section of the [Guide](/docs/arvo/eyre/guide) document for a practical example.
356−
357−## Spider
358−
359−See the [HTTP API](/docs/userspace/threads/http-api) section of the [Threads](/docs/userspace/threads/overview) documentation.
content/docs/arvo/eyre/eyre.mddeleted−61
@@ -1,61 +0,0 @@
1−+++
2−title = "Overview"
3−weight = 1
4−template = "doc.html"
5−+++
6−
7−Eyre is the webserver vane.
8−
9−HTTP messages come in from outside and Eyre produces HTTP messages in response. In general, apps do not call Eyre; rather, Eyre calls apps. Eyre has a number of ways to handle such HTTP requests which we'll briefly describe.
10−
11−## Authentication
12−
13−Most types of requests require the client provide a valid session cookie which is obtained by authenticating with your ship's web login code. Authentication is documented in the [Authentication](/docs/arvo/eyre/external-api-ref#authentication) section of the [External API Reference](/docs/arvo/eyre/external-api-ref) documentation.
14−
15−## The Channel System
16−
17−Eyre's channel system is the primary way of interacting with Gall agents from outside of Urbit. It provides a simple JSON API that allows you to send data to apps and subscribe for updates from apps. Updates come back on a SSE ([Server Sent Event](https://html.spec.whatwg.org/#server-sent-events)) stream which you can easily handle with an EventSource object in Javascript or the equivalent in whichever language you prefer.
18−
19−The channel system is designed to be extremely simple with just a handful of `action` and `response` JSON objects to deal. Essentially it's a thin layer on top of the underlying Gall agent interface. You can poke agents, subscribe for updates, etc, just like you would from within Urbit.
20−
21−Detailed documentation of the channel system's JSON API is provided in the [External API Reference](/docs/arvo/eyre/external-api-ref) document with corresponding examples in the [Guide](/docs/arvo/eyre/guide#using-the-channel-system) document.
22−
23−## Scrying
24−
25−Along with the channel system, Eyre also provides a way to make read-only requests for data which are called scries. Eyre's scry interface is separate to the channel system but may be useful in conjunction with it.
26−
27−Details of Eyre's scry API are in the [Scry](/docs/arvo/eyre/external-api-ref#scry) section of the [External API Reference](/docs/arvo/eyre/external-api-ref) document.
28−
29−## Spider Threads
30−
31−Spider (the Gall agent that manages threads) has an Eyre binding that allows you to run threads through Eyre. Spider's [HTTP API](/docs/userspace/threads/http-api) is not part of Eyre proper, so is documented separately in the [Threads](/docs/userspace/threads/overview) documentation.
32−
33−## Generators
34−
35−Generators, which are like Hoon scripts, can also be used through Eyre. Rather than having a predefined JSON API, they instead handle HTTP requests and return HTTP responses directly, and are therefore a more complex case that you're less likely to use.
36−
37−Their usage is explained in the [%serve](/docs/arvo/eyre/tasks#serve) section of the [Internal API Reference](/docs/arvo/eyre/tasks) documentation and a practical example is provided in the [Generators](/docs/arvo/eyre/guide#generators) section of the [Guide](/docs/arvo/eyre/guide) document.
38−
39−## Direct HTTP Handling With Gall Agents
40−
41−As well as the [Channel System](#the-channel-system) and [Scries](#scrying), it's also possible for Gall agents to deal directly with HTTP requests. This method is much more complicated than the channel system so you're unlikely to use it unless you want to build a custom HTTP-based API or something like that.
42−
43−This method is explained in the [%connect](/docs/arvo/eyre/tasks#connect) section of the [Internal API Reference](/docs/arvo/eyre/tasks) document and a detailed example is provided in the [Agents: Direct HTTP](/docs/arvo/eyre/guide#agents-direct-http) section of the [Guide](/docs/arvo/eyre/guide) document.
44−
45−## Cross-Origin Resource Sharing
46−
47−Eyre supports both simple [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) requests and OPTIONS preflight requests. It has a CORS registry with three categories - `approved`, `rejected` and `requests`. Eyre will respond positively for origins in its `approved` list and negatively for all others. Eyre will add origins in requests that it doesn't have in either its `approved` or `rejected` lists to its `requests` list. Eyre always allows all methods and headers over CORS.
48−
49−There are three generators - `+cors-registry`, `|cors-approve`, and `|cors-reject` to view, approve, and deny origins respectively from the dojo. Eyre also has [tasks](/docs/arvo/eyre/tasks) to [approve](/docs/arvo/eyre/tasks#approve-origin) and [reject](/docs/arvo/eyre/tasks#reject-origin) origins programmatically, and a number of [scry endpoints](/docs/arvo/eyre/scry) to query them. Examples are also included in the [Managing CORS Origins](/docs/arvo/eyre/guide#managing-cors-origins) section of the Guide document.
50−
51−## Sections
52−
53−[External API Reference](/docs/arvo/eyre/external-api-ref) - Details of Eyre's external API including the channel system's JSON API.
54−
55−[Internal API Reference](/docs/arvo/eyre/tasks) - The `task`s Eyre takes and the `gift`s it returns.
56−
57−[Scry Reference](/docs/arvo/eyre/scry) - The scry endpoints of Eyre.
58−
59−[Data Types](/docs/arvo/eyre/data-types) - Reference documentation of the various data types used by Eyre.
60−
61−[Guide](/docs/arvo/eyre/guide) - Practical examples of the different ways of using Eyre.
content/docs/arvo/eyre/guide.mddeleted−619
@@ -1,619 +0,0 @@
1−+++
2−title = "Guide"
3−weight = 6
4−template = "doc.html"
5−+++
6−
7−This document walks through practical examples of the various ways of interacting with Eyre. The [Basic](#basic) sections goes over the common methods of interacting through Eyre from an HTTP client, and the [Advanced](#advanced) section explains how to handle HTTP directly with generators and Gall agents.
8−
9−General documentation of the `task`s and methods described here are available in the [External API Reference](/docs/arvo/eyre/external-api-ref) document and the [Internal API Reference](/docs/arvo/eyre/tasks) document.
10−
11−## Basic
12−
13−Eyre's channel system is the typical way of interacting with Gall agents from an HTTP client. It provides a simple JSON API for actions like pokes, watches, etc, and an SSE event stream for subscription updates. Additionally, Eyre has a scry interface so you can retrieve data in a more ad-hoc manner. These examples use `curl` to be more language agnostic and to show the nitty-gritty details. In practice you'd probably use an "airlock" library (like [http-api](https://github.com/urbit/urbit/tree/master/pkg/npm/http-api) for Javascript) which abstracts things like ack'ing events, incrementing event IDs, manually composing the JSON for actions, etc.
14−
15−It's advisable to have a read through the [External API Reference](/docs/arvo/eyre/external-api-ref) before going through these examples.
16−
17−### Authenticating
18−
19−You must have a valid session cookie in order to use Eyre's interfaces (such as the channel system or scry interface). If your HTTP client is served from your ship, your browser will automatically add the session cookie it obtained upon login, so there's no need to worry about authentication in practice. If your client does not run in the browser or is not served by your ship, [authenticating](/docs/arvo/eyre/external-api-ref#authentication) with your web login code (which can be obtained by running `+code` in the dojo) is necessary.
20−
21−Here we'll try authenticating with the default fakezod code.
22−
23−Using `curl` in the unix terminal, we'll make an HTTP POST request with `"password=CODE"` in the body:
24−
25−```
26−curl -i localhost:8080/~/login -X POST -d "password=lidlut-tabwed-pillex-ridrup"
27−```
28−
29−Eyre will respond with HTTP status 204, and a `set-cookie` header containing the session cookie.
30−
31−```
32−HTTP/1.1 204 ok
33−Date: Tue, 18 May 2021 01:38:48 GMT
34−Connection: keep-alive
35−Server: urbit/vere-1.5
36−set-cookie: urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm; Path=/; Max-Age=604800
37−```
38−
39−The `urbauth-....` cookie can be now be included in subsequent requests (e.g. to the channel system) by providing it in a Cookie HTTP header.
40−
41−### Using Channels
42−
43−Here we'll look at a practical example of Eyre's channel system. You can refer to the [Channels](/docs/arvo/eyre/external-api-ref#channels) section of the [External API Reference](/docs/arvo/eyre/external-api-ref) document for relevant details.
44−
45−First, we must obtain a session cookie by [authenticating](#authenticating). You will be copying the entry of the `set-cookie` field into the `--cookie` field in subsequent commands.
46−
47−Now that we have our cookie, we can try poking an app & simultaneously opening a new channel. In this case, we'll poke the `hood` app with a `mark` of `helm-hi` to print "Opening airlock" in the dojo.
48−
49−We'll do this with an HTTP PUT request, and we'll include the cookie we obtained when we authenticated in the `Cookie` header. The URL path we'll make the request to will be `http://localhost:8080/~/channel/mychannel`. The last part of the path is the channel `UID` - the name for our new channel. Normally you'd use the current unix time plus a hash to ensure uniqueness, but in this case we'll just use `mychannel` for simplicity.
50−
51−The data will be a JSON array containing a [poke](/docs/arvo/eyre/external-api-ref#poke) `action`:
52−
53−```
54−curl --header "Content-Type: application/json" \
55− --cookie "urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm" \
56− --request PUT \
57− --data '[{"id":1,"action":"poke","ship":"zod","app":"hood","mark":"helm-hi","json":"Opening airlock"}]' \
58− http://localhost:8080/~/channel/my-channel
59−```
60−
61−If we now have a look in the dojo we'll see it's printed our message, so the poke was successful:
62−
63−```
64−< ~zod: Opening airlock
65−```
66−
67−Now we can connect to the `mychannel` channel we opened. We do this with an HTTP GET request with our session cookie and the same path as the last request:
68−
69−```
70−curl -i --cookie "urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm" http://localhost:8080/~/channel/my-channel
71−```
72−
73−Eyre will respond with an HTTP status code of 200 and a `content-type` of `text/event-stream`, indicating an SSE (Server Sent Event) stream. It will also send us any pending events on the channel - in this case the poke ack as a [poke](/docs/arvo/eyre/external-api-ref#poke-ack) `response` for our original poke:
74−
75−```
76−HTTP/1.1 200 ok
77−Date: Tue, 18 May 2021 01:40:47 GMT
78−Connection: keep-alive
79−Server: urbit/vere-1.5
80−set-cookie: urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm; Path=/; Max-Age=604800
81−connection: keep-alive
82−cache-control: no-cache
83−content-type: text/event-stream
84−transfer-encoding: chunked
85−
86−id: 0
87−data: {"ok":"ok","id":1,"response":"poke"}
88−```
89−
90−Normally this event stream would be handled by an EventSource object or similar in Javascript or the equivalent in whatever other language you're using. Here, though, we'll continue using `curl` for simplicity.
91−
92−Leaving the event stream connection open, in another shell session on unix we'll try subscribing to the watch path of a Gall agent - the `/updates` watch path of `graph-store` in this case.
93−
94−We'll do this in the same way as the initial poke, except this time it will be a [subscribe](/docs/arvo/eyre/external-api-ref#subscribe) `action`:
95−
96−```
97−curl --header "Content-Type: application/json" \
98− --cookie "urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm" \
99− --request PUT \
100− --data '[{"id":2,"action":"subscribe","ship":"zod","app":"graph-store","path":"/updates"}]' \
101− http://localhost:8080/~/channel/my-channel
102−```
103−
104−Notice we've incremented the `id` to `2`. Eyre doesn't require IDs to be sequential, merely numerical and unique, but sequential IDs are typically the most practical.
105−
106−Back in the event stream, we'll see a positive watch ack as a [subscribe](/docs/arvo/eyre/external-api-ref#watch-ack) `response`, meaning the subscription has been successful:
107−
108−```
109−id: 1
110−data: {"ok":"ok","id":2,"response":"subscribe"}
111−```
112−
113−Now we'll try trigger an event on our event stream. In fakezod's Landscape, create a new chat channel named "test". You should see the `add-graph` `graph-update` come through on our channel in a [diff](/docs/arvo/eyre/external-api-ref#diff) `response`:
114−
115−```
116−id: 2
117−data: {"json":{"graph-update":{"add-graph":{"graph":{},"resource":{"name":"test-1183","ship":"zod"},"mark":"graph-validator-chat","overwrite":false}}},"id":2,"response":"diff"}
118−```
119−
120−All events we receive must be `ack`ed so Eyre knows we've successfully received them. To do this we'll send an [ack](/docs/arvo/eyre/external-api-ref#ack) `action` which specifies the `event-id` of the event in question - `2` in this case:
121−
122−```
123−curl --header "Content-Type: application/json" \
124− --cookie "urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm" \
125− --request PUT \
126− --data '[{"id":3,"action":"ack","event-id":2}]' \
127− http://localhost:8080/~/channel/my-channel
128−```
129−
130−This same pattern would be repeated for all subsequent events. Note that when you `ack` one event, you also implicitly `ack` all previous events, so in this case event `1` will also be `ack`ed.
131−
132−When we're finished, we can unsubscribe from `graph-store` `/update`. We do this by sending Eyre a [unsubscribe](/docs/arvo/eyre/external-api-ref#unsubscribe) `action`, and specify the request ID of the original `subscribe` `action` in the `subscription` field - `2` in our case:
133−
134−```
135−curl --header "Content-Type: application/json" \
136− --cookie "urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm" \
137− --request PUT \
138− --data '[{"id":4,"action":"unsubscribe","subscription":2}]' \
139− http://localhost:8080/~/channel/my-channel
140−```
141−
142−Unlike `poke` and `subscribe` actions, Eyre doesn't acknowledge `unsubscribe`s, but we'll now have stopped receiving updates from `graph-store`.
143−
144−Finally, let's close the channel itself. We can do this simply by sending Eyre a [delete](/docs/arvo/eyre/external-api-ref#delete-channel) `action`:
145−
146−```
147−curl --header "Content-Type: application/json" \
148− --cookie "urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm" \
149− --request PUT \
150− --data '[{"id":5,"action":"delete"}]' \
151− http://localhost:8080/~/channel/my-channel
152−```
153−
154−With our channel deleted, we can now close the connection on the client side.
155−
156−### Scrying
157−
158−Here we'll look at performing scries through Eyre. You can refer to the [Scry](/docs/arvo/eyre/external-api-ref#scry) section of the [External API Reference](/docs/arvo/eyre/external-api-ref) document for relevant details.
159−
160−First we must obtain a session cookie by [authenticating](#authenticating).
161−
162−Having obtained a cookie, we can now try a scry. We'll scry the `graph-store` Gall agent on the `/x/keys` scry path, which will return the list of channels it has. If you don't already have any chat channels on your fakezod, go ahead and create one via landscape so it'll have something to return.
163−
164−The url path will be `/~/scry/graph-store/keys.json`. The `/~/scry` part specifies a scry, the `/graph-store` part is the Gall agent, the `/keys` is the scry path without the `care`, and the `.json` file extension specifies the return `mark`.
165−
166−The request will be an HTTP GET request:
167−
168−```
169−curl -i --cookie "urbauth-~zod=0v1.1pseu.tq7hs.hps2t.ltaf1.tmqjm" \
170− --request GET \
171− http://localhost:8080/~/scry/graph-store/keys.json
172−```
173−
174−Eyre will respond with HTTP status 200 if it's successful and the body of the response will contain the data we requested:
175−
176−```
177−HTTP/1.1 200 ok
178−Date: Fri, 04 Jun 2021 10:16:32 GMT
179−Connection: keep-alive
180−Content-Length: 61
181−Server: urbit/vere-1.5
182−set-cookie: urbauth-~zod=0v1.1pseu.tq7hs.hps2t.ltaf1.tmqjm; Path=/; Max-Age=604800
183−content-type: application/json
184−
185−{"graph-update":{"keys":[{"name":"test-1183","ship":"zod"}]}}
186−```
187−
188−Now let's make a request to a non-existent scry endpoint:
189−
190−```
191−curl -i --cookie "urbauth-~zod=0v1.1pseu.tq7hs.hps2t.ltaf1.tmqjm" \
192− --request GET \
193− http://localhost:8080/~/scry/foo/bar/baz.json
194−```
195−
196−Eyre will respond with a 404 Missing status and an error message:
197−
198−```
199−HTTP/1.1 404 missing
200−Date: Fri, 04 Jun 2021 10:22:51 GMT
201−Connection: keep-alive
202−Content-Length: 187
203−Server: urbit/vere-1.5
204−set-cookie: urbauth-~zod=0v1.1pseu.tq7hs.hps2t.ltaf1.tmqjm; Path=/; Max-Age=604800
205−content-type: text/html
206−
207−<html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>There was an error while handling the request for /foo/bar/baz.json.</p><code>no scry result</code></body></html>
208−```
209−
210−## Advanced
211−
212−Rather than using things like Eyre's channel system described in the [Basic](#basic) section, it's possible to handle HTTP requests directly in Gall agents or generators. This is useful if you want to implement a custom API or work with `sail` to dynamically compose HTML inside an agent.
213−
214−### Agents: Direct HTTP
215−
216−Here we'll look at handling HTTP requests directly in Gall agents rather than using Eyre's channel system.
217−
218−You can refer to the [%connect](/docs/arvo/eyre/tasks#connect) section of the [Internal API Reference](/docs/arvo/eyre/tasks) document for relevant details.
219−
220−Here's a Gall agent that demonstrates this method. It binds the URL path `/foo`, serves `Hello, World!` for GET requests and a `405` error for all others. It also prints debug information to the terminal as various things happen.
221−
222−Note that this example does a lot of things manually for demonstrative purposes. In practice you'd likely want to use a library like `/lib/server.hoon` to cut down on boilerplate code.
223−
224−`eyre-agent.hoon`
225−
226−```hoon
227−/+ default-agent, dbug
228−=* card card:agent:gall
229−%- agent:dbug
230−^- agent:gall
231−|_ =bowl:gall
232−+* this .
233− def ~(. (default-agent this %|) bowl)
234−::
235−++ on-init on-init:def
236−++ on-save on-save:def
237−++ on-load on-load:def
238−++ on-poke
239− |= [=mark =vase]
240− ^- (quip card _this)
241− ?+ mark
242− (on-poke:def [mark vase])
243− ::
244− %noun
245− ?. =(q.vase %bind)
246− %- (slog leaf+"Bad argument." ~)
247− `this
248− %- (slog leaf+"Attempting to bind /foo." ~)
249− :_ this
250− [%pass /bind-foo %arvo %e %connect `/'foo' %eyre-agent]~
251− ::
252− %handle-http-request
253− =/ req !< (pair @ta inbound-request:eyre) vase
254− ~& [mark req]
255− ?+ method.request.q.req
256− =/ data=octs
257− (as-octs:mimes:html '<h1>405 Method Not Allowed</h1>')
258− =/ content-length=@t
259− (crip ((d-co:co 1) p.data))
260− =/ =response-header:http
261− :- 405
262− :~ ['Content-Length' content-length]
263− ['Content-Type' 'text/html']
264− ['Allow' 'GET']
265− ==
266− :_ this
267− :~
268− [%give %fact [/http-response/[p.req]]~ %http-response-header !>(response-header)]
269− [%give %fact [/http-response/[p.req]]~ %http-response-data !>(`data)]
270− [%give %kick [/http-response/[p.req]]~ ~]
271− ==
272− ::
273− %'GET'
274− =/ data=octs
275− (as-octs:mimes:html '<h1>Hello, World!</h1>')
276− =/ content-length=@t
277− (crip ((d-co:co 1) p.data))
278− =/ =response-header:http
279− :- 200
280− :~ ['Content-Length' content-length]
281− ['Content-Type' 'text/html']
282− ==
283− :_ this
284− :~
285− [%give %fact [/http-response/[p.req]]~ %http-response-header !>(response-header)]
286− [%give %fact [/http-response/[p.req]]~ %http-response-data !>(`data)]
287− [%give %kick [/http-response/[p.req]]~ ~]
288− ==
289− ==
290− ==
291−++ on-watch
292− |= =path
293− ^- (quip card _this)
294− ?+ path
295− (on-watch:def path)
296− ::
297− [%http-response *]
298− %- (slog leaf+"Eyre subscribed to {(spud path)}." ~)
299− `this
300− ==
301−++ on-leave on-leave:def
302−++ on-peek on-peek:def
303−++ on-agent on-agent:def
304−++ on-arvo
305− |= [=wire =sign-arvo]
306− ^- (quip card _this)
307− ?. ?=([%bind-foo ~] wire)
308− (on-arvo:def [wire sign-arvo])
309− ?> ?=([%eyre %bound *] sign-arvo)
310− ?: accepted.sign-arvo
311− %- (slog leaf+"/foo bound successfully!" ~)
312− `this
313− %- (slog leaf+"Binding /foo failed!" ~)
314− `this
315−++ on-fail on-fail:def
316−--
317−```
318−
319−Save the above to `/app/eyre-agent.hoon`. Commit it:
320−
321−```
322−> |commit %base
323−>=
324−+ /~zod/base/2/app/eyre-agent/hoon
325−```
326−
327−...and start it:
328−
329−```
330−> |rein %base [& %eyre-agent]
331−```
332−
333−Now, first we need to bind a URL to our app. In the `++ on-poke` arm, our agent will send a [%connect](/docs/arvo/eyre/tasks#connect) `task` to Eyre when poked with `%bind`:
334−
335−```hoon
336− %noun
337−?. =(q.vase %bind)
338− %- (slog leaf+"Bad argument." ~)
339− `this
340−%- (slog leaf+"Attempting to bind /foo." ~)
341−:_ this
342−[%pass /eyre %arvo %e %connect `/'foo' %eyre-agent]~
343−```
344−
345−...and when `%eyre` responds with a `%bound` `gift`, the `+on-agent` arm will print whether the bind succeeded:
346−
347−```hoon
348− [%eyre %bound *]
349−?: accepted.sign-arvo
350− %- (slog leaf+"/foo bound successfully!" ~)
351− `this
352−%- (slog leaf+"Binding /foo failed!" ~)
353−`this
354−```
355−
356−...so let's try:
357−
358−```
359−> :eyre-agent %bind
360−>=
361−Attempting to bind /foo.
362−/foo bound successfully!
363−```
364−
365−As you can see, we have successfully bound the `/foo` url path. Now we can try making an HTTP request. Over in the unix terminal, we can make a GET request using curl:
366−
367−```
368−> curl -i localhost:8080/foo
369−HTTP/1.1 200 ok
370−Date: Mon, 17 May 2021 04:39:40 GMT
371−Connection: keep-alive
372−Server: urbit/vere-1.5
373−Content-Type: text/html
374−Content-Length: 22
375−transfer-encoding: chunked
376−
377−<h1>Hello, World!</h1>%
378−```
379−
380−...which has succeed! This is because the `+on-poke` arm tests for http GET requests and responds with `Hello, World!` when it sees one:
381−
382−```hoon
383− %'GET'
384−=/ data=octs
385− (as-octs:mimes:html '<h1>Hello, World!</h1>')
386−=/ content-length=@t
387− (crip ((d-co:co 1) p.data))
388−=/ =response-header:http
389− :- 200
390− :~ ['Content-Length' content-length]
391− ['Content-Type' 'text/html']
392− ==
393−:_ this
394−:~
395− [%give %fact [/http-response/[p.req]]~ %http-response-header !>(response-header)]
396− [%give %fact [/http-response/[p.req]]~ %http-response-data !>(`data)]
397− [%give %kick [/http-response/[p.req]]~ ~]
398−==
399−```
400−
401−Back in the dojo, our app's `+on-watch` arm has printed the path on which Eyre has subscribed for the response:
402−
403−```
404−Eyre subscribed to /http-response/~.eyre_0v3.1knjk.l544e.5uds6.fn9l2.f8929.
405−```
406−
407−...and it's also printed the request so you can see how it looks when it comes in:
408−
409−```
410−[ %handle-http-request
411− p=~.~.eyre_0v3.1knjk.l544e.5uds6.fn9l2.f8929
412− q
413− [ authenticated=%.n
414− secure=%.n
415− address=[%ipv4 .127.0.0.1]
416− request
417− [ method=%'GET'
418− url='/foo'
419− header-list
420− ~[
421− [key='host' value='localhost:8080']
422− [key='user-agent' value='curl/7.76.1']
423− [key='accept' value='*/*']
424− ]
425− body=~
426− ]
427− ]
428−]
429−```
430−
431−This is a very rudimentary app but it demonstrates the basic mechanics of dealing with HTTP requests and serving responses.
432−
433−### Generators
434−
435−Here we'll look at running a generator via Eyre. Eyre doesn't have a mediated JSON API for generators, instead it just passes through the HTTP request and returns the HTTP response composed by the generator.
436−
437−You can refer to the [%serve](/docs/arvo/eyre/tasks#serve) section of the [Internal API Reference](/docs/arvo/eyre/tasks) document for relevant details.
438−
439−Here's a very simple generator that will just echo back the body of the request (if available) along with the current datetime. You can save it in the `/gen` directory and `|commit %base`.
440−
441−Note that this example does some things manually for demonstrative purposes. In practice you'd likely want to use a library like `/lib/server.hoon` to cut down on boilerplate code.
442−
443−`eyre-gen.hoon`
444−
445−```hoon
446−|= [[now=@da eny=@uvJ bec=beak] ~ ~]
447−|= [authenticated=? =request:http]
448−^- simple-payload:http
449−=/ msg=@t
450− ?~ body.request
451− (scot %da now)
452− (cat 3 (cat 3 (scot %da now) 10) q.u.body.request)
453−=/ data=octs
454− (as-octs:mimes:html msg)
455−=/ =response-header:http
456− [200 ['Content-Type' 'text/plain']~]
457−[response-header `data]
458−```
459−
460−Eyre requires generators to be a gate within a gate. The sample of the first gate must be:
461−
462−```hoon
463−[[now=@da eny=@uvJ bec=beak] ~ ~]
464−```
465−
466−The sample of the second nested gate must be:
467−
468−```hoon
469−[authenticated=? =request:http]
470−```
471−
472−The return type of the generator must be [$simple-payload:http](/docs/arvo/eyre/data-types#simple-payloadhttp). If you look at our example generator you'll see it meets these requirements.
473−
474−Because generators return the entire HTTP message as a single `simple-payload`, Eyre can calculate the `content-length` itself and automatically add the header.
475−
476−In order to make our generator available, we must bind it to a URL path. To do this, we send Eyre a `%serve` `task`, which looks like:
477−
478−```hoon
479−[%serve =binding =generator]
480−```
481−
482−The [$binding](/docs/arvo/eyre/data-types#binding) specifies the site and URL path, and the [$generator](/docs/arvo/eyre/data-types#generator) specifies the `desk`, the `path` to the generator, and arguments. Note that the passing of arguments to the generator by Eyre is not currently implemented, so you can just leave that as `~` since it won't do anything.
483−
484−Let's bind our generator to the `/mygen` URL path with the `|pass` command in the dojo:
485−
486−```
487−|pass [%e [%serve `/mygen %base /gen/eyre-gen/hoon ~]]
488−```
489−
490−Note that Eyre responds with a `%bound` `gift` to indicate whether the binding succeeded but `|pass` doesn't take such responses so it's not shown.
491−
492−Now let's try making an HTTP request using `curl` in the unix terminal:
493−
494−```
495−curl -i http://localhost:8080/mygen --data 'blah blah blah'
496−```
497−
498−We can see that the request has succeeded and our generator has responded with the datetime and request body:
499−
500−```
501−HTTP/1.1 200 ok
502−Date: Sat, 29 May 2021 09:19:45 GMT
503−Connection: keep-alive
504−Content-Length: 41
505−Server: urbit/vere-1.5
506−Content-Type: text/plain
507−Content-Length: 41
508−
509−~2021.5.29..09.19.45..e096
510−blah blah blah
511−```
512−
513−## Managing CORS Origins
514−
515−Here we'll look at approving and rejecting a CORS origin by passing Clay a [%approve-origin](/docs/arvo/eyre/tasks#approve-origin) `task` and [%reject-origin](/docs/arvo/eyre/tasks#reject-origin) `task` respectively.
516−
517−In this example we'll use more manual methods for demonstrative purposes but note there are also the `|cors-approve` and `|cors-reject` generators to approve/reject origins from the dojo, and the `+cors-registry` generator for viewing the CORS configuration.
518−
519−First, using `|pass` in the dojo, let's approve the origin `http://foo.example` by sending Eyre a `%approve-origin` `task`:
520−
521−```
522−|pass [%e [%approve-origin 'http://foo.example']]
523−```
524−
525−Now if we scry for the [approved](/docs/arvo/eyre/scry#cors-approved) CORS `set`:
526−
527−```
528−> .^(approved=(set @t) %ex /=//=/cors/approved)
529−approved={'http://foo.example'}
530−```
531−
532−...we can see that `http://foo.example` has been added.
533−
534−Next, let's test it by sending Eyre a CORS preflight request via `curl` in unix:
535−
536−```
537−curl -i -X OPTIONS \
538− -H "Access-Control-Request-Method: POST" \
539− -H "Access-Control-Request-Headers: X-Requested-With" \
540− -H "Origin: http://foo.example" \
541− http://localhost:8080
542−```
543−
544−We can see in the response that it has succeeded:
545−
546−```
547−HTTP/1.1 204 ok
548−Date: Fri, 28 May 2021 12:37:12 GMT
549−Connection: keep-alive
550−Server: urbit/vere-1.5
551−Access-Control-Allow-Origin: http://foo.example
552−Access-Control-Allow-Credentials: true
553−Access-Control-Allow-Headers: X-Requested-With
554−Access-Control-Allow-Methods: POST
555−```
556−
557−Now we'll try rejecting an `origin`. Back in the dojo, let's `|pass` Eyre a `%reject-origin` `task` for `http://bar.example`:
558−
559−```
560−|pass [%e [%reject-origin 'http://bar.example']]
561−```
562−
563−If we scry for the [rejected](/docs/arvo/eyre/scry#cors-rejected) CORS `set`:
564−
565−```
566−> .^(rejected=(set @t) %ex /=//=/cors/rejected)
567−rejected={'http://bar.example'}
568−```
569−
570−...we can see that `http://bar.example` has been added.
571−
572−If we again test it with `curl` in unix:
573−
574−```
575−curl -i -X OPTIONS \
576− -H "Access-Control-Request-Method: POST" \
577− -H "Access-Control-Request-Headers: X-Requested-With" \
578− -H "Origin: http://bar.example" \
579− http://localhost:8080
580−```
581−
582−...we can see that, as expected, it has not returned the access control headers:
583−
584−```
585−HTTP/1.1 404 missing
586−Date: Fri, 28 May 2021 12:38:47 GMT
587−Connection: close
588−Server: urbit/vere-1.5
589−```
590−
591−Finally, let's look at CORS requests that are neither approved nor rejected.
592−
593−If we make another request with `curl` on unix, this time for `http://baz.example` which we haven't added to a list:
594−
595−```
596−curl -i -X OPTIONS \
597− -H "Access-Control-Request-Method: POST" \
598− -H "Access-Control-Request-Headers: X-Requested-With" \
599− -H "Origin: http://baz.example" \
600− http://localhost:8080
601−```
602−
603−...we can see it also correctly fails to return the access control headers:
604−
605−```
606−HTTP/1.1 404 missing
607−Date: Fri, 28 May 2021 12:39:59 GMT
608−Connection: close
609−Server: urbit/vere-1.5
610−```
611−
612−Now if we scry for the [requests](/docs/arvo/eyre/scry#cors-requests) CORS `set`:
613−
614−```
615−> .^(requests=(set @t) %ex /=//=/cors/requests)
616−requests={'http://baz.example' 'http://localhost:8080'}
617−```
618−
619−... we can see it has automatically been added by the mere fact of the request being made.
content/docs/arvo/eyre/scry.mddeleted−195
@@ -1,195 +0,0 @@
1−+++
2−title = "Scry Reference"
3−weight = 4
4−template = "doc.html"
5−+++
6−
7−Here are all of Eyre's scry endpoints. There's not too many and they mostly deal with either CORS settings or aspects of the state of connections.
8−
9−The first few have a `care` of `x` and are a scry like `.^({TYPE} %ex /=//=/{SOME-PATH})` (note the empty `desk`). The rest have no `care` and the tag replaces the `desk` like `.^({TYPE} %e /={SOMETHING}=)`.
10−
11−All examples are run from the dojo.
12−
13−## `/cors`
14−
15−An `x` scry with a `path` of `/cors` will return Eyre's CORS origin registry. The type returned is a [cors-registry](/docs/arvo/eyre/data-types#cors-registry) which contains the `set`s of approved, rejected and requested origins.
16−
17−### Example {% #example-1 %}
18−
19−```
20−> .^(cors-registry:eyre %ex /=//=/cors)
21−[ requests={~~http~3a.~2f.~2f.baz~.example}
22− approved={~~http~3a.~2f.~2f.foo~.example}
23− rejected={~~http~3a.~2f.~2f.bar~.example}
24−]
25−```
26−
27−## `/cors/requests`
28−
29−An `x` scry with a `path` of `/cors/requests` will return the `set` of pending origin requests. These are origins that were in an `Origin: ...` HTTP header but weren't in the existing approved or rejected sets. The type returned is a `(set origin:eyre)`.
30−
31−### Example {% #example-2 %}
32−
33−```
34−> .^(requests=(set origin:eyre) %ex /=//=/cors/requests)
35−requests={~~http~3a.~2f.~2f.baz~.example}
36−```
37−
38−## `/cors/approved`
39−
40−An `x` scry with a `path` of `/cors/approved` will return the `set` of approved CORS origins. The type returned is a `(set origin:eyre)`.
41−
42−### Example {% #example-3 %}
43−
44−```
45−> .^(approved=(set origin:eyre) %ex /=//=/cors/approved)
46−approved={~~http~3a.~2f.~2f.foo~.example}
47−```
48−
49−## `/cors/approved/{ORIGIN}`
50−
51−An `x` scry whose `path` is `/cors/approved/{ORIGIN}` tests whether the given origin URL is in the `approved` set of the CORS registry. The type returned is a simple `?`.
52−
53−The origin URL is a `@t`, but since `@t` may not be valid in a path, it must be encoded in a `@ta` using `+scot` like `(scot %t 'foo')` rather than just `'foo'`.
54−
55−### Examples {% #examples-1 %}
56−
57−```
58−> .^(? %ex /=//=/cors/approved/(scot %t 'http://foo.example'))
59−%.y
60−```
61−
62−```
63−> .^(? %ex /=//=/cors/approved/(scot %t 'http://bar.example'))
64−%.n
65−```
66−
67−## `/cors/rejected`
68−
69−An `x` scry with a `path` of `/cors/rejected` will return the `set` of rejected CORS origins. The type returned is a `(set origin:eyre)`.
70−
71−### Example {% #example-4 %}
72−
73−```
74−> .^(rejected=(set origin:eyre) %ex /=//=/cors/rejected)
75−rejected={~~http~3a.~2f.~2f.bar~.example}
76−```
77−
78−## `/cors/rejected/{ORIGIN}`
79−
80−An `x` scry whose `path` is `/cors/rejected/{ORIGIN}` tests whether the given origin URL is in the `rejected` set of the CORS registry. The type returned is a simple `?`.
81−
82−The origin URL must be a cord-encoded `@t` rather than just the plain `@t`, so you'll have to do something like `(scot %t 'foo')` rather than just `'foo'`.
83−
84−### Examples {% #examples-2 %}
85−
86−```
87−> .^(? %ex /=//=/cors/rejected/(scot %t 'http://bar.example'))
88−%.y
89−```
90−
91−```
92−> .^(? %ex /=//=/cors/rejected/(scot %t 'http://foo.example'))
93−%.n
94−```
95−
96−## `/authenticated/cookie`
97−
98−An `x` scry whose `path` is `/authenticated/cookie/{COOKIE}` tests whether the given cookie is currently valid. The type returned is a `?`.
99−
100−The cookie must be the full cookie including the `urbauth-{SHIP}=` part. The cookie must be a cord-encoded `@t` rather than just a plain `@t`, so you'll have to do something like `(scot %t 'foo')` rather than just `'foo'`.
101−
102−### Examples {% #examples-3 %}
103−
104−```
105−> .^(? %ex /=//=/authenticated/cookie/(scot %t 'urbauth-~zod=0vvndn8.bfsjj.j3614.k40ha.8fomi'))
106−%.y
107−```
108−
109−```
110−> .^(? %ex /=//=/authenticated/cookie/(scot %t 'foo'))
111−%.n
112−```
113−
114−## `%bindings`
115−
116−A scry with `bindings` in place of the `desk` in the `beak` will return Eyre's URL path bindings. The type returned is a `(list [binding:eyre duct action:eyre])` (see the [$binding](/docs/arvo/eyre/data-types#binding) & [$action](/docs/arvo/eyre/data-types#action) sections of the Data Types document for details).
117−
118−### Example {% #example-5 %}
119−
120−```
121−> .^((list [binding:eyre duct action:eyre]) %e /=bindings=)
122−~[
123− [ [site=~ path=<|~landscape js bundle|>]
124− ~[/gall/use/file-server/0w2.EijQB/~zod/~landscape/js/bundle /dill //term/1]
125− [%app app=%file-server]
126− ]
127− [ [site=~ path=<|~landscape|>]
128− ~[/gall/use/file-server/0w2.EijQB/~zod/~landscape /dill //term/1]
129− [%app app=%file-server]
130− ]
131− ...(truncated for brevity)...
132−]
133−```
134−
135−## `%connections`
136−
137−A scry with `bindings` in place of the `desk` in the `beak` will return all open HTTP connections that aren't fully complete. The type returned is a `(map duct outstanding-connection:eyre)` (see the [$outstanding-connection](/docs/arvo/eyre/data-types#outstanding-connection) section of the Data Types document for details).
138−
139−### Example {% #example-6 %}
140−
141−```
142−> .^((map duct outstanding-connection:eyre) %e /=connections=)
143−{}
144−```
145−
146−## `%authentication-state`
147−
148−A scry with `authentication-state` in place of the `desk` in the `beak` will return authentication details of all current sessions. The type returned is a [$authentication-state](/docs/arvo/eyre/data-types#authentication-state). The `p` field is the cookie sans the `urbauth-{SHIP}=` part.
149−
150−### Example {% #example-7 %}
151−
152−```
153−> .^(authentication-state:eyre %e /=authentication-state=)
154− sessions
155−{ [ p=0v3.kags1.hj7hm.6llrl.cga2j.eh1r7
156− q=[expiry-time=~2021.5.20..08.44.27..39e0 channels={}]
157− ]
158−}
159−```
160−
161−## `%channel-state`
162−
163−A scry with `channel-state` in place of the `desk` in the `beak` will return details of the state of each channel. The type returned is a [channel-state](/docs/arvo/eyre/data-types#channel-state).
164−
165−### Example {% #example-8 %}
166−
167−```
168−> .^(channel-state:eyre %e /=channel-state=)
169−[ session
170− { [ p='1601844290-ae45b'
171− q
172− [ state=[%.y p=[date=~2021.5.13..20.44.27..39e0 duct=~[//http-server/0v2.kmj6q/26/1]]]
173− next-id=1
174− last-ack=~2021.5.13..08.44.27..39e0
175− events={[id=0 request-id=2 channel-event=[%poke-ack p=~]]}
176− unacked={}
177− subscriptions={}
178− heartbeat=~
179− ]
180− ]
181− }
182− duct-to-key={}
183−]
184−```
185−
186−## `%host`
187−
188−A scry with `host` in place of the `desk` in the `beak` will return host details of the ship. The type returned is a `hart:eyre`.
189−
190−### Example {% #example-9 %}
191−
192−```
193−> .^(hart:eyre %e /=host=)
194−[p=%.n q=[~ 8.080] r=[%.y p=<|localhost|>]]
195−```
content/docs/arvo/eyre/tasks.mddeleted−213
@@ -1,213 +0,0 @@
1−+++
2−title = "Internal API Reference"
3−weight = 3
4−template = "doc.html"
5−+++
6−
7−This document details all the `task`s you're likely to use to interact with Eyre, as well as the `gift`s you'll receive in response.
8−
9−The primary way of interacting with Eyre is from the outside with HTTP requests. As a result, most of its `task`s are only used internally and you're unlikely to need to deal with them directly. The ones you may want to use in certain cases are [%connect](#connect), [%serve](#serve), [%disconnect](#disconnect), [%approve-origin](#approve-origin) and [%reject-origin](#reject-origin), and they are also demonstrated in the [Guide](/docs/arvo/eyre/guide) document. The rest are just documented for completeness.
10−
11−Many of the types referenced are detailed in the [Data Types](/docs/arvo/eyre/data-types) document. It may also be useful to look at the `+eyre` section of `/sys/lull.hoon` in Arvo where these `task`s, `gift`s and data structures are defined.
12−
13−## `%live`
14−
15−```hoon
16−[%live insecure=@ud secure=(unit @ud)]
17−```
18−
19−This `task` notifies Eyre of the listening HTTPS and HTTP ports. It is automatically sent to Eyre by the runtime and should not be used manually.
20−
21−The `insecure` field is the HTTP port and `secure` is the optional HTTPS port.
22−
23−#### Returns
24−
25−Eyre returns no `gift` in response to a `%live` `task`.
26−
27−## `%rule`
28−
29−```hoon
30−[%rule =http-rule]
31−```
32−
33−This `task` either configures HTTPS with a certificate and keypair, or configures a DNS binding. This is typically done for you by the `%acme` app, rather than done manually.
34−
35−The [$http-rule](/docs/arvo/eyre/data-types#http-rule) is either tagged with `%cert` or `%turf`. A `%cert` `http-rule` sets an HTTPS certificate and keypair or removes it if null. A `%turf` `http-rule` either adds or removes a DNS binding depending on whether the `action` is `%put` or `%del`. Note that using `%turf` will automatically cause the system to try and obtain a certificate and keypair via Letsencrypt.
36−
37−#### Returns
38−
39−Eyre returns no `gift` in response to a `%rule` `task`.
40−
41−## `%request`
42−
43−```hoon
44−[%request secure=? =address =request:http]
45−```
46−
47−This `task` is how Eyre receives an inbound HTTP request. It will ordinarily be sent to Eyre by the runtime so you wouldn't use it except perhaps in tests.
48−
49−The `secure` field says whether it's over HTTPS. The `address` is the IP address from which the request originated. The [$request:http](/docs/arvo/eyre/data-types#requesthttp) is the HTTP request itself containing the method, URL, headers, and body.
50−
51−#### Returns
52−
53−Eyre may `pass` a `%response` `gift` on the appropriate `duct` depending on the contents of the `%request`, state of the connection, and other factors.
54−
55−## `%request-local`
56−
57−```hoon
58−[%request-local secure=? =address =request:http]
59−```
60−
61−This `task` is how Eyre receives an inbound HTTP request over the local loopback port. It behaves the same and takes the same arguments as in the [%request](#request) example except it skips any normally required authentication. Just like for a [%request](#request) `task`, you'd not normally use this manually.
62−
63−#### Returns
64−
65−Eyre may `pass` a `%response` `gift` on the appropriate `duct` depending on the contents of the `%request`, state of the connection, and other factors.
66−
67−## `%cancel-request`
68−
69−```hoon
70−[%cancel-request ~]
71−```
72−
73−This `task` is sent to Eyre by the runtime when an HTTP client closes its previously established connection. You would not normally use this manually.
74−
75−This `task` takes no arguments.
76−
77−#### Returns
78−
79−Eyre may `pass` a `%response` `gift` on the appropriate `duct` depending on the state of the connection and other factors.
80−
81−## `%connect`
82−
83−```hoon
84−[%connect =binding app=term]
85−```
86−
87−This `task` binds a Gall agent to a URL path so it can receive HTTP requests and return HTTP responses directly.
88−
89−The [$binding](/docs/arvo/eyre/data-types#binding) contains a URL path and optional domain through which the agent will be able to take HTTP requests. The `app` is just the name of the Gall agent to bind. Note that if you bind a URL path of `/foo`, Eyre will also match `/foo/bar`, `/foo/bar/baz`, etc.
90−
91−If an agent is bound in Eyre using this method, HTTP requests to the bound URL path are poked directly into the agent. The `cage` in the poke have a `%handle-http-request` `mark` and a `vase` of `[@ta inbound-request:eyre]` where the `@ta` is a unique `eyre-id` and the [$inbound-request](/docs/arvo/eyre/data-types#inbound-request) contains the HTTP request itself.
92−
93−Along with the poke, Eyre will also subscribe to the `/http-response/[eyre-id]` `path` of the agent and await a response, which it will pass on to the HTTP client who made the request. Eyre expects at least two `fact`s and a `kick` on this subscription path to complete the response and close the connection (though it can take more than two `fact`s).
94−
95−The first `fact`'s `cage` must have a `mark` of `%http-response-header` and a `vase` containing a [$response-header:http](/docs/arvo/eyre/data-types#response-headerhttp) with the HTTP status code and headers of the response.
96−
97−The `cage` of the second and subsequent `fact`s must have a `mark` of `%http-response-data` and a `vase` containing a `(unit octs)` with the actual data of the response. An `octs` is just `[p=@ud q=@]` where `p` is the byte-length of `q`, the data. You can send an arbitrary number of these.
98−
99−Finally, once you've sent all the `fact`s you want, you can `kick` Eyre's subscription and it will complete the response and close the connection to the HTTP client.
100−
101−#### Returns
102−
103−Eyre will respond with a `%bound` `gift` which says whether the binding was successful and looks like:
104−
105−```hoon
106−[%bound accepted=? =binding]
107−```
108−
109−The `accepted` field says whether the binding succeeded and the `binding` is the requested binding described above.
110−
111−#### Example
112−
113−See the [Agents: Direct HTTP](/docs/arvo/eyre/guide#agents-direct-http) section of the [Guide](/docs/arvo/eyre/guide) document for an example.
114−
115−## `%serve`
116−
117−```hoon
118−[%serve =binding =generator]
119−```
120−
121−This `task` binds a generator to a URL path so it can receive HTTP requests and return HTTP responses.
122−
123−The `binding` contains the URL path and optional domain through which the generator will take HTTP requests. The [$generator](/docs/arvo/eyre/data-types#generator) specifies the `desk`, the `path` to the generator in Clay, and also has a field for arguments. Note that the passing of specified arguments to the generator by Eyre is not currently implemented, so you can just leave it as `~`.
124−
125−The bound generator must be a gate within a gate and the type returned must be a [$simple-payload:http](/docs/arvo/eyre/data-types#simple-payloadhttp).
126−
127−The sample of the first gate must be:
128−
129−```hoon
130−[[now=@da eny=@uvJ bec=beak] ~ ~]
131−```
132−
133−...and the sample of the second, nested gate must be:
134−
135−```hoon
136−[authenticated=? =request:http]
137−```
138−
139−The `?` says whether the HTTP request contained a valid session cookie and the [$request:http](/docs/arvo/eyre/data-types#requesthttp) contains the request itself.
140−
141−The `simple-payload:http` returned by the generator is similar to the response described in the [%connect](#connect) section except the HTTP headers and body are all contained in the one response rather than staggered across several.
142−
143−#### Returns
144−
145−Eyre will return a `%bound` `gift` as described at the end of the [%connect](#connect) section.
146−
147−#### Example
148−
149−See the [Generators](/docs/arvo/eyre/guide#generators) section of the [Guide](/docs/arvo/eyre/guide) document for an example.
150−
151−## `%disconnect`
152−
153−```hoon
154−[%disconnect =binding]
155−```
156−
157−This `task` deletes a URL binding previously set by a `%connect` or `%serve` `task`.
158−
159−The [$binding](/docs/arvo/eyre/data-types#binding) is the URL path and domain of the binding you want to delete.
160−
161−#### Returns
162−
163−Eyre returns no `gift` in response to a `%disconnect` `task`.
164−
165−## `%code-changed`
166−
167−```hoon
168−[%code-changed ~]
169−```
170−
171−This `task` tells Eyre that the web login code has changed, causing Eyre to throw away all sessions and cookies. Typically it's automatically sent to Eyre by `hood` when you run `|code %reset`.
172−
173−This `task` takes no arguments.
174−
175−#### Returns
176−
177−Eyre returns no `gift` in response to a `%code-changed` `task`.
178−
179−## `%approve-origin`
180−
181−```hoon
182−[%approve-origin =origin]
183−```
184−
185−This `task` tells Eyre to start responding positively to CORS requests for the specified `origin`.
186−
187−The [$origin](/docs/arvo/eyre/data-types#origin) is a CORS origin like `http://foo.example` you want to approve.
188−
189−#### Returns
190−
191−Eyre returns no `gift` in response to a `%approve-origin` `task`.
192−
193−#### Example
194−
195−See the [Managing CORS Origins](/docs/arvo/eyre/guide#managing-cors-origins) section of the [Guide](/docs/arvo/eyre/guide) document for an example.
196−
197−## `%reject-origin`
198−
199−```hoon
200−[%reject-origin =origin]
201−```
202−
203−This `task` tells Eyre to start responding negatively to CORS requests for the specified `origin`.
204−
205−The [$origin](/docs/arvo/eyre/data-types#origin) is a CORS origin like `http://foo.example` you want want to reject.
206−
207−#### Returns
208−
209−Eyre returns no `gift` in response to a `%reject-origin` `task`.
210−
211−#### Example
212−
213−See the [Managing CORS Origins](/docs/arvo/eyre/guide#managing-cors-origins) section of the [Guide](/docs/arvo/eyre/guide) document for an example.
content/docs/arvo/ford/_index.mddeleted−7
@@ -1,7 +0,0 @@
1−+++
2−title = "Ford"
3−weight = 60
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−insert_anchor_links = "right"
7−+++
content/docs/arvo/ford/ford.mddeleted−223
@@ -1,223 +0,0 @@
1−+++
2−title = "Overview"
3−weight = 1
4−template = "doc.html"
5−aliases = ["/docs/learn/arvo/ford/"]
6−+++
7−
8−*The Ford vane was refactored so drastically in 2020 that it was completely
9− removed as a standalone vane, with its functionality merged into
10− [clay](/docs/arvo/clay/clay). The following is a reproduced [blog
11− post](https://urbit.org/blog/ford-fusion/) that documents this transformation,
12− which we called "Ford Fusion".*
13−
14−Ford Fusion was an overhaul of Urbit's over-the-air upgrade process and a rewrite of its build system. The new update system corrects a few long-standing bugs with the previous one, and the new build system is simpler, smaller (by around 5,000 lines), and easier to manage.
15−
16−Since deployment of Ford Fusion to the livenet in late June, over-the-air updates (OTAs) have been much smoother. Before Ford Fusion, it was common for an OTA to take several hours, use too much memory, and leave ships in inconsistent states. After Ford Fusion, multiple OTAs have been pushed out, including kernelspace changes, and most users didn't even notice.
17−
18−Urbit has always been able to update itself OTA, but this process has often been rocky. Updating an operating system kernel on-the-fly is a difficult problem in general, like performing heart replacement surgery on yourself while running a marathon. Code that allows Linux to update its kernel in this way became a startup called Ksplice, won multiple awards, and sold to Oracle. Even that, as impressive as it is, and as brilliant as its [programmers](https://nelhage.com) are, can only perform certain limited kinds of patches to the kernel.
19−
20−Urbit isn't exactly a traditional operating system, so the comparison is somewhat unfair, but the purpose of better architecture is to create unfair comparisons. In this case, because the Nock layer is frozen, upgrading everything above that layer is easier. Upgrades are also facilitated by pure-functional semantics, transactional event processing, a type system oriented toward concrete data, and orthogonal persistence. These features make it feasible for Urbit to upgrade
21−itself in the general case, not just some special cases.
22−
23−Ford Fusion has fixed the major upgrade issues of the past by guaranteeing three properties that in retrospect are obvious requirements, but, like much of Urbit, took many years and rewrites to identify as such:
24−- Atomic: the update should complete or fail in one transaction. If it
25− fails, the system shouldn't get stuck.
26−- Self-contained: there must be no implicit dependencies or hysteresis
27− (dependence on previous system states) when building the new software
28− from source.
29−- Ordered: updates must be monotonically sequenced from the system's
30− lowest layer to highest.
31−
32−Let’s walk through them one by one.
33−
34−### Atomic
35−
36−In previous versions of Urbit, updates failed atomicity by deferring parts of the update to later events, which are separate transactions that can fail independently. Generally, each deferral causes an exponential increase in the number of failure states that needed to be handled.
37−
38−We've learned that asynchronicity is an entropic state. A system will tend toward more asynchronicity over time unless effort is put into keeping it synchronous. [As Jonathan Blow has noted](https://youtu.be/pW-SOdj4Kkk?t=2547), the language server protocol has turned every editor plugin into a distributed system, since now it has to communicate asynchronously with the main editor process.
39−
40−Consider an update system that took multiple Arvo events to complete. An ad-hoc higher-level transaction system would need to be built to roll back the effects of the first few events in case of failure. It’s important for various parts of the system to be able to emit effects on upgrade; since those effects would need to be rolled back if a later event in this upgrade fails, the system would need to maintain a queue of those events and only apply them once all the other upgrade events have completed.
41−
42−Note that the asynchronicity has now spread. Some effects that would normally be guaranteed to be processed synchronously might now be asynchronous. Entropy has begun to take hold, chipping away at the set of invariants the system is capable of guaranteeing.
43−
44−This observation is not purely theoretical. False modularity was the cause of internal asynchronicity in Clay where it had to wait for responses in a complex dance with Ford, which was another vane (Arvo kernel module); moving Ford into Clay allowed function calls that were synchronous from Clay’s perspective, which allowed further simplifications, culminating in about a twenty percent reduction of source code size of the Arvo kernelspace.
45−
46−[Steve Yegge's "platform
47−rant"](https://gist.github.com/chitchcock/1281611) describes a Bezosian
48−edict prohibiting synchronous communication among modules through direct
49−linking. This can be seen as an acknowledgment of the difficulty Amazon
50−was going to have when it needed to turn internal services external. If
51−your software needs to run in hell, build it that way from the start.
52−
53−An Urbit ship is not an enterprise SaaS product and does not need to run in this hell; it exists for just one person, with natural pressure pushing it in the opposite direction from Amazon’s web services. Instead of needing a ship’s state and functionality sharded into microservices strewn across multiple clusters, an Urbit instance is easiest to manage as a single server with all its state unified into one data structure and its event log stored as one totally ordered sequence of state updates -- the antithesis of a distributed system.
54−
55−### Self-Contained
56−
57−Before Ford Fusion, each commit to the Clay filesystem validated its files using filetypes (called “marks”) defined by files in the previous commit. This could cause bugs if the filetype definitions had changed in a backward-incompatible manner. It also meant a commit could not add both a new filetype and new files of that type; instead, you needed two commits: one to define the filetypes, and a second to add files of that new type. More theoretically, it caused history-dependence. The validated contents of files in a commit could vary based on the history of commits that led to this one.
58−
59−Another way source code failed to be self-contained was that it had access to symmetry-breaking information at build-time, namely ship, desk (Urbit's answer to a git branch), and (faked) date. A build recipe should be able to shared, cached, and rerun without dependence on local conditions, so user code now no longer learns its ship, desk, or date until runtime.
60−
61−Source code also had build-time access to Urbit's immutable global namespace, called the “scry namespace”, which the kernel makes available as an implicit argument to userspace Hoon code. The scry namespace is immutable and referentially transparent, i.e. a request must always yield the same result for all time, but if an agent asks the kernel for a resource that’s from the future, hosted on another ship, or to which that agent doesn’t have permission, the kernel will deny the request.
62−
63−If the kernel denies a scry request that user code made during the build process, the build system has no choice but to treat it as a nondeterministic error. Nondeterministic errors can never be fully eradicated, if for no other reason than that the user always has the option to defenestrate the machine—there's nothing deterministic about that. But we try to minimize them, and especially to minimize uncertainty as to under what conditions they might occur.
64−
65−No build should be killed by the absence of files outside the desk, so as of this update, user code can no longer scry at build time. Once built, userspace programs can scry if run in a context with a scry handler; a Gall agent's runtime scry requests still work just fine.
66−
67−### Ordered
68−
69−The final kind of failure fixed by Ford Fusion was the lack of ordered layering during a software update. The most common form of this failure was that old Ford had a tendency to try to build userspace code using the previous version's standard library. This didn't work too well, unsurprisingly.
70−
71−Emerging from this underworld required making a number of changes to the Arvo kernel, Clay, Gall, and the procedure for kernel updates. To avoid turning into a pillar of salt, I'll skip the details of how the old system worked and instead describe the new update procedure.
72−
73−## How Updates Work Now
74−
75−These are the layers of the stack that update themselves on the fly, from lowest to highest:
76−
77−+ hoon: the hoon language definition and compiler, defined in `/sys/hoon/hoon`
78−+ arvo: the arvo kernel proper and related type definitions, in `/sys/arvo/hoon`
79−+ zuse: the standard library, in `/sys/zuse/hoon`
80−+ vanes: arvo kernel modules, including clay itself, in folder `/sys/vane`
81−+ userspace: apps, marks, ancillary source code like libraries, and user data
82−
83−An update to one layer necessitates a reload of all layers above it; e.g. a change to Zuse should trigger updates to the vanes and userspace. Conversely, an update to a higher layer should not cause a spurious reload of lower layers, which should not be affected by the change; for example, an update to just userspace should not cause any reloads of system code.
84−
85−Clay is responsible for enforcing the layering of updates. An update to a module is triggered when an attempt is made to commit a change to Clay that affects one or more files needed to build the module. For example, if the 'foo' agent's source, defined in `/app/foo/hoon`, imports the 'bar' library from `/lib/bar/hoon`, then a modification to `/lib/bar/hoon` triggers an update to the 'foo' agent. All vanes and userspace files depend on Zuse, which depends on the Arvo and Hoon sources, so a change to the Hoon, Arvo, or Zuse sources will trigger updates to all vanes and userspace files.
86−
87−When asked to perform a commit, Clay determines which layers need to be updated based on which files have changed and which modules depend on those files. For now, all running programs load their source from the `%home` desk, so only changes to `%home` trigger stateful updates. Files in other desks can be built, but not installed into the system. This might be relaxed in the future.
88−
89−The process of updating varies by layer. The Hoon and Zuse layers are stateless, so their newly rebuilt cores (Nock executables) must be stored (somewhere in the system’s Nock tree, in memory; remember, Urbit is a single-level store), but they have no state that would need to be migrated. The Arvo kernel, vanes, and userspace agents are all live, stateful programs, so in order to update one of those, the system must extract the state from the old program, pass that data into the newly built program, then discard the old program and store the new one. Arvo and agent state injection routines can emit effects, but vane updates cannot.
90−
91−To work around this limitation, Gall has a two-phase update process. First it enters a dormant “pupal” phase that stores not running agent cores, but only the agent states that the old Gall had extracted from its agents. When Clay notifies Gall that its agents have been rebuilt, Gall “molts” back into normal functionality by loading the agent cores from Clay and then running their `+on-load` routines to inject the old state.
92−
93−If there's a change to files in `/sys` on the `%home` desk, Clay asks Arvo to update kernelspace. Clay sends a sequence of moves (effects) to Arvo to ask Arvo to perform any necessary updates to hoon, the kernel, Zuse, and vanes. This sequence is terminated by an extra move back to Clay itself, which will be received by the updated version of Clay after migrating its state. The rebuilt Clay can then use the newly rebuilt version of Zuse to rebuild userspace and notify clients of the update. One client is Gall, which molts when Clay notifies it.
94−
95−Clay triggers updates, but the Arvo kernel is responsible for performing updates to all kernelspace layers, and Gall is responsible for updating userspace agents. Agents are stored in Gall's state, but all other layers are stored directly in the Arvo core's state, so the Arvo kernel contains the routines that reload Hoon, the kernel itself, Zuse, and the vanes.
96−
97−The Arvo kernel reloads itself by receiving its new source code as a `%lyra` move from Clay, compiling this source into a core with empty state, then calling the new core's `+load` routine with the relevant parts of the old state. The state passed to the new Arvo now includes not just the vane cores and their states, but also the Arvo "duct" call `stack`, which maintains a stack of queues of moves to be passed from one vane to another, and a list of effects to emit to Unix at the end of the current Arvo event. If needed, Arvo could migrate the outstanding moves themselves -- if, say, the duct datatype changes.
98−
99−Passing the Arvo call stack state to new Arvo allows a kernel update to happen in the middle of a more complex event without disturbing other sequences of processing steps happening concurrently in the vanes.
100−
101−This entire update process happens in one Arvo event and doesn’t break event-dispatching semantics. This not only provides atomic rollback, but allows the update to be combined with other actions into a larger transaction -- for example, to stage complex changes, user code could trigger two kernel updates in a row, both in the same event.
102−
103−Note that this is the opposite situation from the entropically leaking asynchronicity described earlier. Now the guarantees don’t deteriorate; they can be composed into stronger guarantees.
104−
105−## How Clay Validates a Desk
106−
107−A desk is Urbit's answer to a git branch. It's almost identical, except all files are typed and validated, and whenever a commit becomes the equivalent of git’s ‘HEAD’, it’s assigned a semantically meaningful revision number, and all files are typed and validated.
108−
109−If Clay has been asked to perform a commit, it needs to validate all the files in this desk and notify all subscribers to live queries of this desk's data. Gall, for example, maintains live queries on builds of its live agents. Validation uses the Ford build system, which as of this update is no longer a standalone vane but a core within Clay.
110−
111−A Clay commit, like a git commit, is specified as the current value of all its changed files (and, separately, references its parent commits by hash), not as the diff from a parent commit. Unlike git, Clay is typed, and every file must be validated according to its "mark". A mark is named like a file extension, e.g. `%txt`, `%png`, or `%noun`, and Clay maintains a mapping from that name to behaviors of values of that type under various operations. The last segment of any Clay path specifies the mark to use for operations on that file, including validation.
112−
113−Mark operations include conversion to and from other marks (such as converting `%json` to `%txt`), revision control operations (diff, patch, and merge), and validating an untyped noun. Operations for mark `%foo-bar` are defined by a core built using the source code at `/mar/foo-bar/hoon`, or if that doesn't exist, at `/mar/foo/bar/hoon`.
114−
115−Consider a file at `/web/foo/json`. In order to validate this file, Clay must load the mark definition core and use its validation routine to ensure the untyped value of `/web/foo/json` is in fact valid JSON. To obtain this core, Clay must build the file at `/mar/json/hoon` from source and then process the resulting raw mark core using some mild metaprogramming to get a standard interface core for dealing with marks, called a `$dais`, whose type is defined in Zuse.
116−
117−Since building a source file only makes sense if the file has been validated as a `%hoon` file, but mark definitions themselves must be built from source, there's a logical dependency cycle -- who validates the validators? To break this cycle, Clay hard-codes the validation of `%hoon` files. This allows mark definitions to be built from source, and in fact any file can depend on any other file of any mark as long as there are no cycles. As of Ford Fusion, Ford performs a cycle check to ensure acyclicity.
118−
119−Since building a file is a pure function, Clay memoizes the results of all builds, including builds of marks, mark conversions, and hoon source files. These memoization results are stored along with the desk and are used by later revisions of that desk. Future work should allow merge commits to pull memoized builds from all parents, but for now only the previous revision of the current desk is used. This is a major simplification of previous Ford architectures, which maintained much more complex caches with less clear eviction semantics. Now on every commit, we just throw away any unused memoized builds from the previous revision's Ford cache.
120−
121−Once Clay has validated every file in this new revision of a desk, it constructs and sends updates to any subscriptions that other vanes or agents have requested. More Ford builds may be run to fulfill these requests, including builds for any running agents whose dependencies changed in this commit.
122−
123−When Gall receives a newly rebuilt agent from Clay, it calls the gate produced by the `+on-load` arm of the new agent with the state extracted from the old agent. If there is a crash in any `+on-load` calls or in the handling of any effects they emit (which can include more agent activations), then the whole event crashes, canceling the commit. This effectively gives any agent the ability to abort a commit by crashing.
124−
125−It is a bit counterintuitive that an app reload failure could prevent a kernel update. The reason is that we don't want the system to update itself into a broken state. An Urbit can be rendered practically unusable by the presence of broken agents, even if the kernel hasn't lost integrity,
126−so it's kinder to the user not to break their agents by installing an incompatible kernel update. This also puts virtuous pressure on kernel developers not to "break userspace", the importance of which has been insisted on for decades by Linus Torvalds, among others.
127−
128−If an agent does crash a commit event that included a kernel update, the attempted commit is now trivially rolled back, and the system can deliver an error message to the user. This does not leave the system in an inconsistent or stuck state, so the user could modify the failing agent and try the kernel update again later. Supporting better workflows for keeping third-party agents up-to-date will be an important aspect of Urbit’s upcoming software distribution work.
129−
130−## Ford Build Semantics
131−
132−### The Three Types of Ford Builds: Files, Marks, and Casts
133−
134−The Ford build semantics have been simplified. There are now three kinds of builds that Ford can perform: files, marks, and casts, all of which happen synchronously as function calls inside Clay and are available (without memoization) as scry interfaces.
135−
136−#### File Builds
137−
138−A file build takes in a filepath containing Ford runes and Hoon source, runs the Ford runes to perform imports, and then compiles the source, producing a `$vase`, a noun tagged with its Hoon type.
139−
140−Clay exposes file builds into the scry namespace with `%ca`: as an example, `.^(vase %ca /~zod/home/3/lib/sole/hoon)` will build the `sole` library.
141−
142−#### Mark Builds
143−
144−A mark build produces a `$dais` mark-interface core. It first performs a file build on the Hoon file in `/mar` that defines the mark core, then it does some metaprogramming to make the operations more convenient to use. If the raw mark core delegated revision control operations to another mark core, the mark build will also load the delegate mark core and resolve the result into the `$dais`.
145−
146−Clay exposes mark builds into the scry namespace with `%cb`: as an example, `.^(dais:clay %cb /~zod/home/3/mar/foo/hoon)` builds a `$dais` for the `%foo` mark.
147−
148−#### Cast Builds
149−
150−A cast build produces a `$tube`: a gate that takes a value of one mark as input and converts it to a valid value of another mark or crashes. To convert from mark `%foo` to mark `%bar`, Clay tries the following operations, in order:
151−
152−+ direct grow from `%foo`
153−+ direct grab from `%bar`
154−+ indirect jump from `%foo` through `%qux`
155−+ indirect grab from `%bar` through `%qux`
156−
157−The `%foo` mark can “grow to” `%bar` by providing an arm in its `+grow` core named `+bar`. `%bar` can convert from `%foo` using a `+foo` arm in its `+grab` core. `%foo` can also chain a conversion through an intermediary using an arm in its `+jump` core, and `%bar` can specify an “indirect grab” by having a `+grab` arm produce a delegate mark instead of directly defining a conversion gate.
158−
159−Clay exposes cast builds into the scry namespace with `%cc`: as an example, `.^(tube:clay %cc
160−/~zod/home/3/foo/bar)` builds a `$tube` conversion gate from `%foo` to `%bar`.
161−
162−### Ford Runes
163−
164−There are now only four Ford runes. A file can contain zero, one, or many of each, but each Ford expression can only be one line, and they must be in the standard order of `/-`s, `/+`s, `/=`s, and then `/*`s.
165−
166−```
167−/- foo, *bar, baz=qux
168−```
169−
170−The `/-` rune imports a structures file from `/sur`. You can import it as just `foo`, in which case the build result of that file (usually a core with mold definitions) will be pinned into the compilation subject with the face `foo`. If you prefix it with a `*` as in `*bar`, the result will be pinned into the subject with no face; if the structures file compiled to a core, this exposes all the arms into the namespace of the compilation subject. Finally, if you import it as `baz=qux`, the `baz` face will be applied instead of `qux`. This is similar to "import as" in other languages.
171−
172−```
173−/+ foo, *bar, baz=qux
174−```
175−
176−The `/+` rune imports a library file from `/lib`. Aside from the different source folder, the syntax and semantics are the same as for `/-`.
177−
178−```
179−/= clay-raw /sys/vane/clay
180−```
181−
182−The `/=` rune imports the result of building a hoon file from a user-specified path (the second argument), wrapping it in a face specified by the first argument. The final `/hoon` at the end of the path must be omitted. This is mostly useful for importing a file for testing. The file at the specified path will be built as a normal userspace hoon file; i.e. its compilation subject will be Zuse augmented with the results of any Ford runes it has at the top of the file.
183−
184−```
185−/* hello-gen %hoon /gen/hello/hoon
186−```
187−
188−The `/*` rune imports the contents of a file in the desk, specified as the third argument with the full path including the trailing mark, converted to the mark specified by the second argument, and pinned into the compilation subject wrapped in the face specified by the first argument. This can be used to import static data at build-time, such as a data file, a media file, or, in the case of this example, a hoon file as source text rather than already built.
189−
190−A valid userspace hoon file must contain a nonempty list of hoons (hoon source expressions) below the Ford runes, separated by gap (more than one space, or at least one newline). The system wraps this list of hoons in a `=~` expression so that the result of the previous hoon is used as the subject of the next hoon. The result of the Ford runes is used as the compilation subject for this `=~` hoon; informally, the shape of the compilation subject can be thought of as:
191−
192−```
193−:* fastar-2 fastar-1
194− fastis-2 fastis-1
195− faslus-2 faslus-1
196− fashep-2 fashep-1
197− <zuse>
198−==
199−```
200−
201−## Future Work
202−
203−Urbit still needs to make better use of desks other than `%home` and the development process should be adjusted given the tighter coupling between source code and kernel and tighter criteria for accepting an update.
204−
205−This work also hopefully provides a good foundation of a package management and software distribution system for Urbit. As `~wicdev-wisryt` has said, a user should be able to run `|install
206−~norsyr-torryn/canvas` to load and build remote source. No one should experience dependency hell on Urbit, but we're not there yet.
207−
208−At least now, building a desk has no dependencies, other than a Ford with a compatible Hoon compiler. No decisions have been made on this yet, but
209−Ford might get moved to inside the desk, possibly by making Zuse callable. This could allow a desk to expose a Nock interface in addition to a typed Hoon interface, which could even let a desk be used as a "pill" bootloader.
210−
211−## Conclusion
212−
213−`~littel-ponnys` and I spent most of 2018 rewriting Ford with the intent of improving its performance. Compared to its predecessor, its result was better in some ways but worse in others. The caching system was labyrinthine and poorly factored, making the system difficult to debug or prove correct, even informally. Some things were faster, but the caching and dependency tracking were actually complex enough that a number of common operations, like mark conversion, were too slow.
214−
215−In early 2020, `~master-morzod` suggested moving Ford into Clay to reduce asynchronicity. It seemed absurd at first, but at some point I realized I could combine that idea with a simpler build-caching scheme and self-contained desk builds, and `~wicdev-wisryt` realized he could use that to further simplify Clay’s commit and merge code, which he did as part of this project.
216−
217−The first time I rewrote Ford, it took me six months, with help from `~littel-ponnys`, and it weighed in at 6,000 lines of code. The second time, in late 2018, took a few weeks. The third time, in January 2020, took a week. I wrote `+ford` in Ford Fusion in one long day, and it’s about 500 lines of synchronous, functional code.
218−
219−It has taken me two or three years to understand this problem as well as I do, and I expect there are parts of it I still don’t understand. The code itself isn’t the issue; it’s finding the right answer to ontological and teleological questions. What *is* Ford? What will it be in a hundred years? I’m confident Ford Fusion is more similar than its predecessor to the Ford of 2120, because it’s smaller, more functional, and easier to understand and administer.
220−
221−As an engineering discipline and organizational practice, working on a system intended to be frozen yields surprising simplifications like this every so often. Urbit is now reaching the point where we’re starting to see more of the obsidian edges of the frozen future system emerge from the lava.
222−
223−
content/docs/arvo/gall/_index.mddeleted−7
@@ -1,7 +0,0 @@
1−+++
2−title = "Gall"
3−weight = 70
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−insert_anchor_links = "right"
7−+++
content/docs/arvo/gall/data-types.mddeleted−492
@@ -1,492 +0,0 @@
1−+++
2−title = "Data Types"
3−weight = 5
4−template = "doc.html"
5−+++
6−
7−This document describes the data types for Gall defined in `lull.hoon`.
8−
9−## `bitt`
10−
11−```hoon
12−+$ bitt (map duct (pair ship path))
13−```
14−
15−Incoming subscriptions.
16−
17−This is the structure Gall uses to keep track of subscribers to our Gall agent.
18−The `sup` field of a [`bowl`](#bowl) contains the `bitt` for our agent.
19−
20−## `boat`
21−
22−```hoon
23−+$ boat
24− %+ map [=wire =ship =term]
25− [acked=? =path]
26−```
27−
28−Outgoing subscriptions.
29−
30−This is the structure Gall uses to keep track of subscriptions our agent has
31−initiated. The `wex` field of a [`bowl`](#bowl) contails the `boat` for that
32−agent.
33−
34−The `wire` field is the `wire` which [`sign:agent`](#signagent)s will come in on.
35−The `ship` and `term` fields are the ship and the name of the agent to which our
36−agent has subscribed.
37−
38−The `acked` field is `%.y` if they have acknowledged our subscription request,
39−and `%.n` if they have not. The `path` field is the `path` on the other agent to
40−which our agent has subscribed.
41−
42−## `bowl`
43−
44−```hoon
45−+$ bowl :: standard app state
46− $: $: our=ship :: host
47− src=ship :: guest
48− dap=term :: agent
49− == ::
50− $: wex=boat :: outgoing subs
51− sup=bitt :: incoming subs
52− == ::
53− $: act=@ud :: change number
54− eny=@uvJ :: entropy
55− now=@da :: current time
56− byk=beak :: load source
57− == == ::
58−```
59−
60−Additional agent state.
61−
62−A `bowl` is given to the agent core each time an event comes in. The fields are
63−as follows:
64−
65−- `our`: Our ship.
66−- `src`: The ship from which the current request originated.
67−- `dap`: The name of our agent.
68−- `wex`: Outgoing subscriptions. That is, subscriptions our agent has initiated.
69− See the [`boat`](#boat) section for details of the type.
70−- `sup`: Incoming subscriptions. That is, subscriptions others have made to our
71− agent. See the [`bitt`](#bitt) section for details of the type.
72−- `act`: The total number of [`move`](/docs/arvo/overview#move)s our agent has
73− processed so far.
74−- `eny`: 512 bits of entropy.
75−- `now`: The current date-time.
76−- `byk`: The ship, desk and `case` in Clay from which this agent was loaded. The
77− `case` will be `[%da @da]` where the `@da` is the when the agent was loaded. A
78− `beak` is a triple of `[ship desk case]`.
79−
80−## `dude`
81−
82−```hoon
83−+$ dude term
84−```
85−
86−Agent name.
87−
88−## `gill`
89−
90−```hoon
91−+$ gill (pair ship term)
92−```
93−
94−A general contact: A pair of the ship and agent name.
95−
96−## `scar`
97−
98−```hoon
99−+$ scar
100− $: p=@ud
101− q=(map duct bone)
102− r=(map bone duct)
103− ==
104−```
105−
106−Opaque duct - used internally.
107−
108−## `suss`
109−
110−```hoon
111−+$ suss (trel dude @tas @da)
112−```
113−
114−Configuration report.
115−
116−## `well`
117−
118−```hoon
119−+$ well (pair desk term)
120−```
121−
122−Desk and agent.
123−
124−## `neat`
125−
126−```hoon
127−+$ neat
128− $% [%arvo =note-arvo]
129− [%agent [=ship name=term] =deal]
130− [%pyre =tang]
131− ==
132−```
133−
134−Like a [`note:agent`](#noteagent), except the `%agent` case has a [`deal`](#deal) instead
135−of just a [`task:agent`](#taskagent). This is used for messages that come in over the
136−network and would not be used manually.
137−
138−## `deal`
139−
140−```hoon
141−+$ deal
142− $% [%raw-poke =mark =noun]
143− task:agent
144− ==
145−```
146−
147−Like a [`task:agent`](#taskagent) but with the additional case of a raw poke.
148−This is used for messages that come in over the network and would not be used
149−manually.
150−
151−## `unto`
152−
153−```hoon
154−+$ unto
155− $% [%raw-fact =mark =noun]
156− sign:agent
157− ==
158−```
159−
160−Like a [`sign:agent`](#signagent) but with the additional case of a raw fact.
161−This is used for messages that come in over the network and would not be used
162−manually.
163−
164−## `agent`
165−
166−```hoon
167−++ agent
168− =< form
169− |%
170−```
171−
172−Container for Gall agent types. The most significant arm is
173−[`form:agent`](#formagent), which specifies the structure of the agent itself.
174−There are also some additional structures defined here, mostly defining the
175−kinds of messages agents can send. The different arms of the core in `agent`
176−are considered separately below.
177−
178−### `step:agent`
179−
180−```hoon
181−+$ step (quip card form)
182−```
183−
184−A cell of [`card:agent`](#cardagent)s to be sent and a new agent state. This is the
185−type returned by most arms of an agent. A `(quip a b)` is the same as `[(list a) b]`, it's just a more convenient way to specify it.
186−
187−### `card:agent`
188−
189−```hoon
190−+$ card (wind note gift)
191−```
192−
193−An effect - typically a message to be sent to another agent or vane. A list of
194−these are returned by most agent arms along with a new state in a
195−[`step:agent`](#stepagent). A `wind` is the following:
196−
197−```hoon
198−++ wind
199− |$ [a b]
200− $% [%pass p=path q=a]
201− [%slip p=a]
202− [%give p=b]
203− ==
204−```
205−
206−Gall will not allow a `%slip`, so in practice a `card` will be one of:
207−
208−- `[%pass path note]`
209−- `[%give gift]`
210−
211−For `%pass`, `p` specifies the `wire` on which a response should be returned.
212−See [`note:agent`](#noteagent) and [`gift:agent`](#giftagent) below for details of their
213−types.
214−
215−### `note:agent`
216−
217−```hoon
218−+$ note
219− $% [%agent [=ship name=term] =task]
220− [%arvo note-arvo]
221− [%pyre =tang]
222− ==
223−```
224−
225−The type for messages initiated by our agent. This is opposed to
226−[`gift:agent`](#giftagent), which is the type for responding to other agents or
227−vanes, or for sending out updates to subscribers. The three cases are:
228−
229−- `%agent`: Poke another agent, subscribe to another agent, or cancel a
230− subscription to another agent. The `ship` and `name` fields are the ship and
231− agent to which the `task` should be sent. The `task` is the request itself,
232− see [`task:agent`](#taskagent) below for its possible types.
233−- `%arvo`: Pass a `task` to a vane. The type of a `note-arvo` is:
234− ```hoon
235− +$ note-arvo
236− $~ [%b %wake ~]
237− $% [%a task:ames]
238− [%b task:behn]
239− [%c task:clay]
240− [%d task:dill]
241− [%e task:eyre]
242− [%g task:gall]
243− [%i task:iris]
244− [%j task:jael]
245− [%$ %whiz ~]
246− [@tas %meta vase]
247− ==
248− ```
249− You can refer to the `/sys/lull.hoon` source code for all the possible vane
250− tasks, or see each vane's API Reference section in the [Arvo
251− documentation](/docs/arvo/overview)
252−- `%pyre`: This is for aborting side-effects initiated during agent
253− installation. The `tang` is an error message.
254−
255−A `note:agent` is always wrapped in a `%pass` [`card:agent`](#cardagent).
256−
257−### `task:agent`
258−
259−```hoon
260−+$ task
261− $% [%watch =path]
262− [%watch-as =mark =path]
263− [%leave ~]
264− [%poke =cage]
265− [%poke-as =mark =cage]
266− ==
267−```
268−
269−The types of messages initiated by our agent and sent to another agent. This is
270−in contrast to [`gift:agent`](#giftagent)s, which are responses to incoming
271−messages from agents or updates to agents already subscribed. The five kinds
272−are:
273−
274−- `%watch`: Subscribe to `path` on the target ship and agent.
275−- `%watch-as`: Same as `%watch`, except you ask the target's Gall to convert
276− subscription updates to the `mark` you specified rather than just giving you
277− the `mark` produced by the agent.
278−- `%leave`: Cancel subscription. The particular subscription to cancel will be
279− determined by the `wire` given in the `p` field of the containing `%pass`
280− [`card:agent`](#cardagent).
281−- `%poke`: Poke the target ship and agent with the given `cage`, which is a pair
282− of `[mark vase]`.
283−- `%poke-as`: Same as `%poke`, except the `cage` will be converted to the
284− specified `mark` before sending.
285−
286−A `task:agent` is always wrapped in a `%pass` [`card:agent`](#cardagent).
287−
288−### `gift:agent`
289−
290−```hoon
291−+$ gift
292− $% [%fact paths=(list path) =cage]
293− [%kick paths=(list path) ship=(unit ship)]
294− [%watch-ack p=(unit tang)]
295− [%poke-ack p=(unit tang)]
296− ==
297−```
298−
299−The types of messages our agent can either send in response to messages from
300−other agents, or send to subscribed agents. This is in contrast to
301−[`task:agent`](#taskagent)s, which are messages to other agents our agent
302−initiates rather than sends in response. The four kinds are:
303−
304−- `%fact`: An update to existing subscribers. The `paths` field specifies which
305− subscription paths the update should go out to. The `cage` is the data, and is
306− a `[mark vase]`.
307−- `%kick`: Kick subscriber, ending their subscription. The `paths` field
308− specifies which paths the subscriber should be kicked from, and the `ship`
309− field specifies the ship to kick. If the `ship` field is null, all subscribers
310− on the specified paths are kicked. Gall will automatically remove the
311− subscription from our agent's [`bitt`](#bitt) (inbound subscription `map`),
312− and subscriber will no longer receive updates on the `path`s in question.
313−- `%watch-ack`: Acknowledge a subscription request. If `p` is null, it's an ack
314− (positive acknowledgement), and if `p` is non-null, it's a nack (negative
315− acknowledgement). Simply crashing will caused Gall to nack a subscription
316− request, and not crashing but not explicitly producing a `%watch-ack` `gift`
317− will cause Gall to ack a subscription request. Therefore, you'd typically only
318− explicitly produce a `%watch-ack` `gift` if you wanted to nack a subscription
319− request with a custom error in the `tang`.
320−- `%poke-ack`: Acknowledge a poke. If `p` is null, it's an ack, and if `p` is
321− non-null, it's a nack. Simply crashing will cause Gall to nack a poke, and not
322− crashing but not explicitly producing a `%poke-ack` `gift` will cause Gall to
323− ack a poke. Therefore, you'd typically only explicitly produce a `%poke-ack`
324− `gift` if you wanted to nack a poke with a custom error in the `tang`.
325−
326−A `gift:agent` is always wrapped in a `%give` [`card:agent`](#cardagent).
327−
328−### `sign:agent`
329−
330−```hoon
331−+$ sign
332− $% [%poke-ack p=(unit tang)]
333− [%watch-ack p=(unit tang)]
334− [%fact =cage]
335− [%kick ~]
336− ==
337−```
338−
339−A `sign` is like a [`gift:agent`](#giftagent) but it's something that comes
340−_in_ to our agent from another agent rather than something we send out. The
341−possible types are:
342−
343−- `%poke-ack`: Another agent has acked (positively acknowledged) or nacked
344− (negatively acknowledged) a `%poke` [`task:agent`](#taskagent) we previously
345− sent. It's an ack if `p` is null and a nack if `p` is non-null. The `tang`
346− contains an error or traceback if it's a nack.
347−- `%watch-ack`: Another agent has acked or nacked a `%watch`
348− [`task:agent`](#taskagent) (subscription request) we previously sent. It's an
349− ack if `p` is null and a nack if `p` is non-null. The `tang` contains an error
350− or traceback if it's a nack. If it's a nack, Gall will automatically remove
351− the subscription from our agent's [`boat`](#boat) (outbound subscription
352− map).
353−- `%fact`: An update from another agent to which we've previously subscribed
354− with a `%watch` [`task:agent`](#taskagent) (subscription request). The `cage`
355− contains the data, and is a `[mark vase]`.
356−- `%kick`: Our subscription to another agent has been ended, and we'll no longer
357− receive updates. A `%kick` may be intentional, but it may also happen due to
358− certain network conditions or other factors. As a result, it's best to try and
359− resubscribe with another `%watch` [`task:agent`](#taskagent), and if they
360− nack the `%watch`, we can conclude it was intentional and give up.
361−
362−### `form:agent`
363−
364−```hoon
365−++ form
366− $_ ^|
367− |_ bowl
368− ++ on-init
369− *(quip card _^|(..on-init))
370− ::
371− ++ on-save
372− *vase
373− ::
374− ++ on-load
375− |~ old-state=vase
376− *(quip card _^|(..on-init))
377− ::
378− ++ on-poke
379− |~ [mark vase]
380− *(quip card _^|(..on-init))
381− ::
382− ++ on-watch
383− |~ path
384− *(quip card _^|(..on-init))
385− ::
386− ++ on-leave
387− |~ path
388− *(quip card _^|(..on-init))
389− ::
390− ++ on-peek
391− |~ path
392− *(unit (unit cage))
393− ::
394− ++ on-agent
395− |~ [wire sign]
396− *(quip card _^|(..on-init))
397− ::
398− ++ on-arvo
399− |~ [wire sign-arvo]
400− *(quip card _^|(..on-init))
401− ::
402− ++ on-fail
403− |~ [term tang]
404− *(quip card _^|(..on-init))
405− --
406−--
407−```
408−
409−This defines the structure of the agent itself. The agent is a door with a [`bowl`](#bowl) as its sample and exactly ten arms. Below we'll describe each arm briefly.
410−
411−#### `on-init`
412−
413−- Accepts: Nothing.
414−- Produces: [`step:agent`](#stepagent)
415−
416−This arm is called when the agent is initially installed.
417−
418−#### `on-poke`
419−
420−- Accepts: `cage`
421−- Produces: [`step:agent`](#stepagent)
422−
423−This arm is called when another agent pokes our agent.
424−
425−#### `on-watch`
426−
427−- Accepts: `path`
428−- Produces: [`step:agent`](#stepagent)
429−
430−This arm is called when another agent subscribes to our agent.
431−
432−#### `on-leave`
433−
434−- Accepts: `path`
435−- Produces: [`step:agent`](#stepagent)
436−
437−This arm is called when another agent unsubscribes from a subscription path on
438−our agent.
439−
440−#### `on-peek`
441−
442−- Accepts: `path`
443−- Produces: `(unit (unit cage))`
444−
445−This arm is called when a [scry](/docs/arvo/concepts/scry) is performed on our
446−agent.
447−
448−#### `on-agent`
449−
450−- Accepts: `[wire sign:agent]`
451−- Produces: [`step:agent`](#stepagent)
452−
453−This arm is called when another agent give our agent a
454−[`sign:agent`](#signagent).
455−
456−#### `on-arvo`
457−
458−- Accepts: `[wire sign-arvo]`
459−- Produces: [`step:agent`](#stepagent)
460−
461−This arm is called when a vane gives our agent a `gift`. A `sign-arvo` is:
462−
463−```hoon
464−+$ sign-arvo
465− $% [%ames gift:ames]
466− $: %behn
467− $% gift:behn
468− $>(%wris gift:clay)
469− $>(%writ gift:clay)
470− $>(%mere gift:clay)
471− $>(%unto gift:gall)
472− ==
473− ==
474− [%clay gift:clay]
475− [%dill gift:dill]
476− [%eyre gift:eyre]
477− [%gall gift:gall]
478− [%iris gift:iris]
479− [%jael gift:jael]
480− ==
481−```
482−
483−You can refer to the `/sys/lull.hoon` source code, or the API Reference of each
484−vane in the [Arvo documentation](/docs/arvo/overview).
485−
486−#### `on-fail`
487−
488−- Accepts: `[term tang]`
489−- Produces: [`step:agent`](#stepagent)
490−
491−This arm is called if certain errors occur in Gall, such as if our agent tries
492−to create a duplicate subscription.
content/docs/arvo/gall/gall-api.mddeleted−958
@@ -1,958 +0,0 @@
1−+++
2−title = "API Reference"
3−weight = 3
4−template = "doc.html"
5−+++
6−
7−## Reference Agent
8−
9−This app stores a number for each user. You can increment your number, increment
10−someone else's number, start tracking someone else's number by poking. It
11−exposes a scry namespace to inspect everyone's number.
12−
13−### `app/example-gall.hoon`
14−
15−```hoon
16−:: Import sur/example-gall
17−/- *example-gall
18−:: Import lib/default-agent
19−/+ default-agent
20−|%
21−+$ card card:agent:gall
22−+$ note
23− $%
24− [%arvo =note-arvo]
25− [%agent [=ship name=term] =task:agent:gall]
26− ==
27−+$ state-zero [%0 local=@ud]
28−+$ state-one [%1 local=@ud remote=(map @p @ud)]
29−+$ versioned-state
30− $%
31− state-zero
32− state-one
33− ==
34−--
35−=| state-one
36−=* state -
37−^- agent:gall
38−|_ =bowl:gall
39−+* this .
40− def ~(. (default-agent this %|) bowl)
41−::
42−:: Set local counter to 1 by default
43−++ on-init
44− ^- (quip card _this)
45− `this(local 1)
46−:: Expose state for saving
47−++ on-save
48− !>(state)
49−::
50−:: Load old state and upgrade if neccessary
51−++ on-load
52− |= old=vase
53− ^- (quip card _this)
54− =/ loaded=versioned-state
55− !<(versioned-state old)
56− ?- -.loaded
57− %0
58− `this(local local.loaded) :: Upgrade old state
59− %1
60− `this(state loaded)
61− ==
62−::
63−:: Respond to poke
64−:: App can be poked in the dojo by running the following commands
65−:: Increment local counter
66−:: :example-gall &example-gall-action [%increment ~]
67−:: Increment ~zod's counter
68−:: :example-gall &example-gall-action [%increment-remote ~zod]
69−:: Subscribe to ~zod's counter
70−:: :example-gall &example-gall-action [%view ~zod]
71−:: Unsubscribe from ~zod's counter
72−:: :example-gall &example-gall-action [%stop-view ~zod]
73−::
74−++ on-poke
75− |= [=mark =vase]
76− ^- (quip card _this)
77− :: Ensure poke is of mark %example-gall-action
78− ?> =(mark %example-gall-action)
79− =/ act=example-gall-action !<(example-gall-action vase)
80− ?- act
81− ::
82− :: Increment local counter and send new counter to subscribers
83− ::
84− [%increment ~]
85− :- [%give %fact ~[/local] %atom !>(+(local))]~
86− this(local +(local))
87− ::
88− :: Send remote %increment poke
89− ::
90− [%increment-remote who=@p]
91− :_ this
92− :~ :*
93− %pass
94− /inc/(scot %p who.act)
95− %agent
96− [who.act %example-gall]
97− %poke %example-gall-action !>([%increment ~])
98− == ==
99− ::
100− :: Subscribe to a remote counter
101− ::
102− [%view who=@p]
103− :_ this
104− [%pass /view/(scot %p who.act) %agent [who.act %example-gall] %watch /local]~
105− ::
106− :: Unsubscribe from remote counter and remove from state
107− ::
108− [%stop-view who=@p]
109− :_ this(remote (~(del by remote) who.act))
110− [%pass /view/(scot %p who.act) %agent [who.act %example-gall] %leave ~]~
111− ::
112− ==
113−::
114−:: Print on unsubscribe
115−::
116−++ on-leave
117− |= =path
118− ^- (quip card _this)
119− ~& "Unsubscribed by: {<src.bowl>} on: {<path>}"
120− `this
121−::
122−:: Handle new subscription
123−::
124−:: When another ship subscribes to our counter, give them the current state of
125−:: the counter immediately
126−::
127−++ on-watch
128− |= =path
129− ^- (quip card _this)
130− :_ this
131− :: Crash if we see a subscription we don't recognise
132− ?+ path ~|("unexpected subscription" !!)
133− ::
134− [%local ~]
135− [%give %fact ~ %atom !>(local)]~
136− ==
137−::
138−:: Expose scry namespace
139−::
140−:: .^(@ %gx /=example-gall=/local/atom) will produce the current local counter
141−:: .^(@ %gx /=example-gall=/remote/~zod/atom) will produce the counter for ~zod
142−:: .^(arch %gy /=example-gall=/remote) will produce a listing of the current
143−:: remote counters
144−++ on-peek
145− |= =path
146− ^- (unit (unit cage))
147− ?+ path [~ ~]
148− ::
149− :: Produce local counter
150− ::
151− [%x %local ~]
152− ``[%atom !>(local)]
153− ::
154− :: Produce remote counter
155− ::
156− [%x %remote who=@ta ~]
157− =* location i.t.t.path :: Ship name is third in the list
158− =/ res
159− (~(got by remote) (slav %p location))
160− ``[%atom !>(res)]
161− ::
162− :: Produce listing of remote counters
163− ::
164− [%y %remote ~]
165− =/ dir=(map @ta ~)
166− %- molt :: Map from list of k-v pairs
167− %+ turn :: iterate over list of k-v pairs
168− ~(tap by remote) :: list of k-v pairs from map
169− |= [who=@p *]
170− [(scot %p who) ~]
171− ``[%arch !>(`arch`[~ dir])]
172− ==
173−::
174−:: Handle sign from agent
175−::
176−++ on-agent
177− |= [=wire =sign:agent:gall]
178− ^- (quip card _this)
179− ?- -.sign
180− ::
181− :: Print error if poke failed
182− ::
183− %poke-ack
184− ?~ p.sign
185− `this
186− %- (slog u.p.sign)
187− `this
188− ::
189− :: Print error if subscription failed
190− ::
191− %watch-ack
192− ?~ p.sign
193− `this
194− =/ =tank leaf+"subscribe failed from {<dap.bowl>} on wire {<wire>}"
195− %- (slog tank u.p.sign)
196− `this
197− ::
198− :: Do nothing if unsubscribed
199− ::
200− %kick `this
201− ::
202− :: Update remote counter when we get a subscription update
203− ::
204− %fact
205− :- ~
206− ?. ?=(%atom p.cage.sign)
207− this
208− this(remote (~(put by remote) src.bowl !<(@ q.cage.sign)))
209− ==
210−::
211−:: Handle arvo signs
212−::
213−:: We never give any cards to arvo. Therefore we never need to handle any signs
214−:: from arvo. We use the default-agent library to avoid implementing this arm,
215−:: as gall apps must have all the arms.
216−::
217−++ on-arvo on-arvo:def
218−::
219−:: Handle error
220−::
221−:: Print errors when they happen
222−::
223−++ on-fail
224− |= [=term =tang]
225− ^- (quip card _this)
226− %- (slog leaf+"error in {<dap.bowl>}" >term< tang)
227− `this
228−--
229−
230−```
231−
232−### `sur/example-gall.hoon`
233−
234−```hoon
235−|%
236−+$ example-gall-action
237− $%
238− [%view who=@p]
239− [%stop-view who=@p]
240− [%increment-remote who=@p]
241− [%increment ~]
242− ==
243−--
244−```
245−
246−### `mar/example-gall/action.hoon`
247−
248−```hoon
249−/- *example-gall
250−|_ act=example-gall-action
251−++ grab
252− |%
253− ++ noun example-gall-action
254− --
255−--
256−```
257−
258−## Arms
259−
260−### `++on-init`
261−
262−Application initialisation
263−
264−`++on-init` is called when an application is first started. It is not a gate and
265−has no input.
266−
267−#### Returns
268−
269−```hoon
270−(quip card _this)
271−```
272−
273−List of cards and new agent
274−
275−#### Example
276−
277−```hoon
278−:: From reference agent.
279−:: Set local counter to 1 by default
280−::
281−++ on-init
282− ^- (quip card _this)
283− `this(local.sta 1)
284−:: From app/weather.hoon. This setup is typical of a landscape tile.
285−::
286−++ on-init
287− :_ this
288− :~ [%pass /bind/weather %arvo %e %connect [~ /'~weather'] %weather]
289− :* %pass /launch/weather %agent [our.bol %launch] %poke
290− %launch-action !>([%weather /weathertile '/~weather/js/tile.js'])
291− ==
292− ==
293−```
294−
295−### `++on-save`
296−
297−Expose state for saving.
298−
299−This arm is called immediately before the agent is upgraded. It packages the
300−permament state of the agent in a vase for the next version of the agent.
301−Unlike most handlers, this cannot produce effects. It is not a gate and has no input.
302−
303−#### Returns
304−
305−`vase` of permanent state.
306−
307−#### Example
308−
309−```hoon
310−:: From reference agent
311−::
312−:: Expose state for saving
313−::
314−++ on-save
315− !>(state)
316−```
317−
318−### `++on-load`
319−
320−Application upgrade.
321−
322−This arm is called immediately after the agent is upgraded. It receives
323−a vase of the state of the previously-running version of the agent, obtained
324−from `+on-save`, which allows it to cleanly upgrade from the old agent.
325−
326−#### Accepts
327−
328−```hoon
329−=vase
330−```
331−
332−`vase` of previous state, from `++on-save`
333−
334−#### Returns
335−
336−```hoon
337−(quip card _this)
338−```
339−
340−List of cards and new agent
341−
342−#### Examples
343−
344−```hoon
345−:: From reference agent
346−::
347−:: Load old state and upgrade if neccessary
348−++ on-load
349− |= old=vase
350− ^- (quip card _this)
351− =/ loaded=versioned-state
352− !<(versioned-state old)
353− ?- -.loaded
354− %0
355− `this(local local.loaded) :: Upgrade old state
356− %1
357− `this(state loaded)
358− ==
359−```
360−
361−### `++on-poke`
362−
363−Handle application poke.
364−
365−This arm is called when the agent is "poked". The input is a cage, so
366−it's a pair of a mark and a dynamic vase.
367−
368−#### Accepts
369−
370−```hoon
371−[=mark =vase]
372−```
373−
374−`mark` is the mark of the poked data.
375−
376−`vase` is a vase with the poked data inside.
377−
378−#### Returns
379−
380−```hoon
381−(quip card _this)
382−```
383−
384−List of cards and new agent.
385−
386−#### Example
387−
388−```hoon
389−:: From reference agent.
390−::
391−:: Respond to poke
392−:: App can be poked in the dojo by running the following commands
393−:: Increment local counter
394−:: :example-gall &example-gall-action [%increment ~]
395−:: Increment ~zod's counter
396−:: :example-gall &example-gall-action [%increment-remote ~zod]
397−:: Subscribe to ~zod's counter
398−:: :example-gall &example-gall-action [%view ~zod]
399−:: Unsubscribe from ~zod's counter
400−:: :example-gall &example-gall-action [%stop-view ~zod]
401−::
402−++ on-poke
403− |= [=mark =vase]
404− ^- (quip card _this)
405− :: Ensure poke is of mark %example-gall-action
406− ?> =(mark %example-gall-action)
407− =/ act=example-gall-action !<(example-gall-action vase)
408− ?- act
409− ::
410− :: Increment local counter and send new counter to subscribers
411− ::
412− [%increment ~]
413− :- [%give %fact ~[/local] %atom !>(+(local))]~
414− this(local +(local))
415− ::
416− :: Send remote %increment poke
417− ::
418− [%increment-remote who=@p]
419− :_ this
420− :~ :*
421− %pass
422− /inc/(scot %p who.act)
423− %agent
424− [who.act %example-gall]
425− %poke %example-gall-action !>([%increment ~])
426− == ==
427− ::
428− :: Subscribe to a remote counter
429− ::
430− [%view who=@p]
431− :_ this
432− [%pass /view/(scot %p who.act) %agent [who.act %example-gall] %watch /local]~
433− ::
434− :: Unsubscribe from remote counter and remove from state
435− ::
436− [%stop-view who=@p]
437− :_ this(remote (~(del by remote) who.act))
438− [%pass /view/(scot %p who.act) %agent [who.act %example-gall] %leave ~]~
439− ::
440− ==
441−```
442−
443−### `++on-watch`
444−
445−Handle new subscriber.
446−
447−This arm is called when a program wants to subscribe to the agent on a
448−particular path. The agent may or may not need to perform setup steps
449−to intialize the subscription. It may produce a `%give`
450−`%subscription-result` to the subscriber to get it up to date, but after
451−this event is complete, it cannot give further updates to a specific
452−subscriber. It must give all further updates to all subscribers on a
453−specific path.
454−
455−If this arm crashes, then the subscription is immediately terminated.
456−More specifcally, it never started -- the subscriber will receive a
457−negative `%watch-ack`. You may also produce an explicit `%kick` to
458−close the subscription without crashing -- for example, you could
459−produce a single update followed by a `%kick`.
460−
461−#### Accepts
462−
463−```hoon
464−=path
465−```
466−
467−Path of new subscription.
468−
469−#### Returns
470−
471−```hoon
472−(quip card _this)
473−```
474−
475−List of cards and new agent.
476−
477−#### Example
478−
479−```hoon
480−:: From reference agent
481−::
482−:: Handle new subscription
483−::
484−:: When another ship subscribes to our counter, give them the current state of
485−:: the counter immediately
486−::
487−++ on-watch
488− |= =path
489− ^- (quip card _this)
490− :_ this
491− ?+ path on-watch:def
492− ::
493− [%local ~]
494− [%give %fact ~ %atom !>(local)]~
495− ==
496−```
497−
498−### `++on-leave`
499−
500−Handle unsubscribe.
501−
502−This arm is called when a program becomes unsubscribed to you.
503−Subscriptions may close because the subscriber intentionally
504−unsubscribed, but they also could be closed by an intermediary. For
505−example, if a subscription is from another ship which is currently
506−unreachable, Ames may choose to close the subscription to avoid queueing
507−updates indefinitely. If the program crashes while processing an
508−update, this may also generate an unsubscription. You should consider
509−subscriptions to be closable at any time.
510−
511−#### Accepts
512−
513−```hoon
514−=path
515−```
516−
517−Path of the closed subscription.
518−
519−#### Returns
520−
521−```hoon
522−(quip card _this)
523−```
524−
525−List of cards and new agent.
526−
527−#### Example
528−
529−```hoon
530−:: From reference agent. Prints a message when programs become unsubscribed.
531−++ on-leave
532− |= =path
533− ^- (quip card _this)
534− ~& "Unsubscribe by: {<src.bowl>} on: {<path>}"
535− `this
536−```
537−
538−### `++on-peek`
539−
540−Handle scry request.
541−
542−This arm is called when a program reads from the agent's "scry"
543−namespace, which should be referentially transparent. Unlike most
544−handlers, this cannot perform IO, and it cannot change the state. All
545−it can do is produce a piece of data to the caller, or not.
546−
547−#### Accepts
548−
549−```hoon
550−=path
551−```
552−
553−The path being scryed for.
554−
555−```hoon
556−:: Example scry to path mappings
557−::
558−.^(arch %gy /=example-gall=/remote)
559−:: Path will be /y/remote
560−.^(@ %gx /=example-gall=/local/atom)
561−:: Path will be /x/local
562−```
563−
564−#### Returns
565−
566−```hoon
567−(unit (unit cage))
568−```
569−
570−If this arm produces `[~ ~ data]`, then `data` is the value at the the
571−given path. If it produces `[~ ~]`, then there is no data at the given
572−path and never will be. If it produces `~`, then we don't know yet whether
573−there is or will be data at the given path. The head of the path is known as the
574−`care`. Requests with a care of `%x` should return a vase that matches or is
575−convertible to the mark at the end of the scry request. This mark is not
576−included in the path passed to `++on-peek`. Requests with a care of `%y` should
577−return a cage with a mark of `%arch` and a vase of `arch`.
578−
579−#### Example
580−
581−```hoon
582−:: From reference agent
583−::
584−:: Expose scry namespace
585−::
586−:: .^(@ %gx /=example-gall=/local/atom) will produce the current local counter
587−:: .^(@ %gx /=example-gall=/remote/~zod/atom) will produce the counter for ~zod
588−:: .^(arch %gy /=example-gall=/remote) will produce a listing of the current
589−:: remote counters
590−++ on-peek
591− |= =path
592− ^- (unit (unit cage))
593− ?+ path [~ ~]
594− ::
595− :: Produce local counter
596− ::
597− [%x %local ~]
598− ``[%atom !>(local)]
599− ::
600− :: Produce remote counter
601− ::
602− [%x %remote who=@ta ~]
603− =* location i.t.t.path :: Ship name is third in the list
604− =/ res
605− (~(got by remote) (slav %p location))
606− ``[%atom !>(res)]
607− ::
608− :: Produce listing of remote counters
609− ::
610− [%y %remote ~]
611− =/ dir=(map @ta ~)
612− %- molt :: Map from list of k-v pairs
613− %+ turn :: iterate over list of k-v pairs
614− ~(tap by remote) :: list of k-v pairs from map
615− |= [who=@p *]
616− [(scot %p who) ~]
617− ``[%arch !>(`arch`[~ dir])]
618− ==
619−```
620−
621−### `++on-agent`
622−
623−Handle `%pass` card
624−
625−This arm is called to handle responses to `%pass` cards to other agents.
626−It will be one of the following types of response:
627−
628−- `%poke-ack`: acknowledgment (positive or negative) of a poke. If the
629− value is `~`, then the poke succeeded. If the value is `[~ tang]`,
630− then the poke failed, and a printable explanation (eg a stack trace)
631− is given in the `tang`.
632−
633−- `%watch-ack`: acknowledgment (positive or negative) of a subscription.
634− If negative, the subscription is already ended (technically, it never
635− started).
636−
637−- `%fact`: update from the publisher.
638−
639−- `%kick`: notification that the subscription has ended. This happens because
640− either the target app passed a `%leave` note, or ames killed the subscription
641− due to backpressure. Most of the time you will want to resubscribe. If you can
642− no longer access the subscription you will get a negative `%watch-ack` and end
643− your flow there.
644−
645−#### Accepts
646−
647−```hoon
648−[=wire =sign:agent:gall]
649−```
650−
651−`wire` is the wire from the `+gift` that triggered `++on-agent`
652−
653−`sign` is response for the gift.
654−
655−#### Returns
656−
657−```hoon
658−(quip card _this)
659−```
660−
661−#### Example
662−
663−```hoon
664−:: From reference agent
665−::
666−:: Handle sign from agent
667−::
668−++ on-agent
669− |= [=wire =sign:agent:gall]
670− ^- (quip card _this)
671− ?- -.sign
672− ::
673− :: Print error if poke failed
674− ::
675− %poke-ack
676− ?~ p.sign
677− `this
678− %- (slog u.p.sign)
679− `this
680− ::
681− :: Print error if subscription failed
682− ::
683− %watch-ack
684− ?~ p.sign
685− `this
686− =/ =tank leaf+"subscribe failed from {<dap.bowl>} on wire {<wire>}"
687− %- (slog tank u.p.sign)
688− `this
689− ::
690− :: Do nothing if unsubscribed
691− ::
692− %kick `this
693− ::
694− :: Update remote counter when we get a subscription update
695− ::
696− %fact
697− :- ~
698− ?. ?=(%atom p.cage.sign)
699− this
700− this(remote (~(put by remote) src.bowl !<(@ q.cage.sign)))
701− ==
702−```
703−
704−### `++on-arvo`
705−
706−Handle vane response
707−
708−This arm is called to handle responses for `%pass` cards to vanes.
709−
710−#### Accepts
711−
712−```hoon
713− [=wire =sign:agent:gall]
714−```
715−
716−`wire` is the wire from the `++gift` that triggered `++on-arvo`.
717−
718−`sign` is the response from the vane. The list of possible responses from the
719−vanes is statically defined in sys/zuse.hoon (grep for `++ sign-arvo`).
720−
721−#### Returns
722−
723−```hoon
724−(quip card _this)
725−```
726−
727−List of cards and new agent.
728−
729−#### Example
730−
731−```hoon
732−:: From app/weather.hoon. Handles %bound, %wake and %http-response signs
733−++ on-arvo
734− |= [=wire =sign-arvo]
735− ^- (quip card:agent:gall _this)
736− ?: ?=(%bound +<.sign-arvo)
737− [~ this]
738− ?: ?=(%wake +<.sign-arvo)
739− =^ cards state
740− (wake:wc wire error.sign-arvo)
741− [cards this]
742− ?: ?=(%http-response +<.sign-arvo)
743− =^ cards state
744− (http-response:wc wire client-response.sign-arvo)
745− [cards this]
746− (on-arvo:def wire sign-arvo)
747−::
748−:: From reference agent
749−::
750−:: Handle arvo signs
751−::
752−:: We never give any cards to arvo. Therefore we never need to handle any signs
753−:: from arvo. We use the default-agent library to avoid implementing this arm,
754−:: as gall apps must have all the arms specified in the agent:gall definition.
755−::
756−++ on-arvo on-arvo:def
757−```
758−
759−### `++on-fail`
760−
761−Handle error.
762−
763−If an error happens in `+on-poke`, the crash report goes into the
764−`%poke-ack` response. Similarly, if an error happens in
765−`+on-subscription`, the crash report goes into the `%watch-ack`
766−response. If a crash happens in any of the other handlers, the report
767−is passed into this arm.
768−
769−#### Accepts
770−
771−```hoon
772−[=term =tang]
773−```
774−
775−`term` is a cord describing the error.
776−
777−`tang` is a stack trace for the error.
778−
779−#### Returns
780−
781−```hoon
782−(quip card _this)
783−```
784−
785−List of cards and new agent
786−
787−#### Example
788−
789−```hoon
790−::
791−:: Handle error
792−::
793−:: Print errors when they happen
794−::
795−++ on-fail
796− |= [=term =tang]
797− ^- (quip card _this)
798− %- (slog leaf+"error in {<dap.bowl>}" >term< tang)
799− `this
800−```
801−
802−## Agent Gifts
803−
804−Giving a gift takes the general form of
805−
806−```hoon
807−[%give =gift]
808−```
809−
810−### `%fact`
811−
812−Produce a subscription update.
813−
814−Produces a subscription update. A subscription update is a new piece of
815−subscription content for all subscribers on a given path.
816−
817−#### Structure
818−
819−```hoon
820−[%fact (list path) =cage]
821−```
822−
823−`(list path)` is a list of the paths to send the update on. If no path is
824−given, then the update is only given to the program that instigated the
825−request. Typical use of this mode is in `+on-watch` to give an initial update
826−to a new subscriber to get them up to date.
827−
828−`cage` is a cage of the subscription update.
829−
830−#### Example
831−
832−```hoon
833−:: From ++on-watch in reference agent.
834−::
835−:: Gives current local state to new subscribers.
836−[%give %fact ~ %atom !>(local.sta)]
837−
838−
839−:: From ++on-poke in reference agent
840−::
841−:: Gives incremented local state to any subscribers on /local
842−[%give %fact ~[/local] %atom !>(+(local))]
843−```
844−
845−### `%kick`
846−
847−Close subscription.
848−
849−Closes a subscription. A subscription close closes the subscription for all or
850−one subscribers on a given path.
851−
852−#### Structure
853−
854−```hoon
855−[%kick (unit path) (unit ship)]
856−```
857−
858−`(unit path)` is the path of the subscription being updated. If no path is
859−given, then the update is only given to the program that instigated the request.
860−Typical use of this mode would be in `+on-watch` to produce a single update to a
861−subscription then close the subscription.
862−
863−`(unit ship)` is the ship to close the subscription for. If no path is given,
864−then the subscription is closed for all subscribers.
865−
866−## Agent Notes
867−
868−Passing a agent note (a 'task') along a wire looks like so.
869−
870−```hoon
871−[%pass =wire %agent [=ship name=term] =task]
872−```
873−
874−`wire` is used to identify the response to the note.
875−
876−`ship` is the ship to pass the note to.
877−
878−`name` is the name of the agent that should receive the note.
879−
880−`task` is the task itself, described below.
881−
882−### `%poke`
883−
884−Poke an application.
885−
886−This note is passed to poke an application with a cage, a marked vase.
887−
888−#### Structure
889−
890−```hoon
891−[%poke =cage]
892−```
893−
894−`cage` is the marked data to poke the application with. It is a pair of a mark
895−and vase.
896−
897−#### Example
898−
899−```hoon
900−:: From ++on-poke in reference agent.
901−::
902−:: Sends an increment poke to the example-gall agent
903−:: on who.act.
904−:*
905− %pass
906− /inc/(scot %p who.act)
907− %agent
908− [who.act %example-gall]
909− %poke %example-gall-action !>([%increment ~])
910−==
911−```
912−
913−### `%watch`
914−
915−Subscribe to an application.
916−
917−This note is given to subscribe to an application at a path
918−
919−#### Structure
920−
921−```hoon
922−[%watch =path]
923−```
924−
925−`path` is the path to be subscribed to.
926−
927−#### Example
928−
929−```hoon
930−:: From ++on-poke in reference agent.
931−::
932−:: Subscribes to the example-gall agent on who.act on the path /local
933−::
934−[%pass /view/(scot %p who.act) %agent [who.act %example-gall] %watch /local]
935−```
936−
937−### `%leave`
938−
939−Unsubscribe from an application.
940−
941−This note is passed to unsubscribe from an application. It should be passed on
942−the same wire that the corresponding `%watch` note for the subscription was
943−passed on.
944−
945−#### Structure
946−
947−```hoon
948−[%leave ~]
949−```
950−
951−#### Example
952−
953−```hoon
954−:: From ++on-poke in reference agent.
955−::
956−:: Unsubscribes from the example-gall agent on who.act
957−[%pass /view/(scot %p who.act) %agent [who.act %example-gall] %leave ~]
958−```
content/docs/arvo/gall/gall.mddeleted−558
@@ -1,558 +0,0 @@
1−+++
2−title = "Overview"
3−weight = 1
4−template = "doc.html"
5−aliases = ["/docs/learn/arvo/gall/"]
6−+++
7−
8−This document describes Gall, the Arvo userspace vane.
9−
10−# Agents
11−
12−Urbit code lives in the following basic categories:
13−
14−- Runtime (Nock interpreter, persistence engine, IO drivers, jets)
15−- Kernel vanes (managed by Arvo)
16−- Userspace agents (managed by Gall, permanent state)
17−- Userspace threads (managed by Spider, transient state)
18−
19−This lays out the framework for the third category: Agents.
20−
21−An agent is a piece of software that is primarily focused on maintaining
22−and distributing a piece of state with a defined structure. It exposes
23−an interface that lets programs read, subscribe to, and manipulate the
24−state. Every event happens in an atomic transaction, so the state is
25−never inconsistent. Since the state is permanent, when the agent is
26−upgraded with a change to the structure of the state, the developer
27−provides a migration function from the old state type to the new state
28−type.
29−
30−It's not too far off to think of an agent as simply a database with
31−developer-defined logic. But an agent is significantly less constrained
32−than a database. Databases are usually tightly constrained in one or
33−more ways because they need to provide certain guarantees (like
34−atomicity) or optimizations (like indexes). Urbit is a single-level
35−store, so atomicity comes for free. Many applications don't use
36−databases because they need relational indices; rather, they use them
37−for their guarantees around persistence. Some do need the indices,
38−though, and it's not hard to imagine an agent which provides a SQL-like
39−interface.
40−
41−On the other hand, an agent is also a lot like what many systems call a
42−"service". An agent is permanent and addressable -- a running program
43−can talk to an agent just by naming it. An agent can perform IO, unlike
44−most databases. This is a critical part of an agent: it performs IO
45−along the same transaction boundaries as changes to its state, so if an
46−effect happens, you know that the associated state change has happened.
47−You should be careful, though, to avoid creating implicit non-atomicity
48−-- eg if it comes into an inconsistent state pending a response to an IO
49−action.
50−
51−But the best way to think about an agent is as a state machine. Like a
52−state machine, any input could happen at any time, and it must react
53−coherently to that input. Ouput (effects) and the next state of the
54−machine are both pure functions of the previous state and the input
55−event. Of course, it's important to ensure there isn't an order of
56−events that could cause your agent to enter an inconsistent state.
57−
58−We often think of state machines as finite state machines, but of course
59−in this instance, the state is not actually finite (though it should be
60−definable in a regular recursive data type).
61−
62−## Specification
63−
64−An agent is defined as a [core](/docs/glossary/core/) with a set of [arms](/docs/glossary/arm/) to handle various
65−events. These handlers usually produce a list of effects and the next
66−state of the agent. The interface definition can be found in
67−`sys/lull.hoon`, which at the time of writing is:
68−
69−```hoon
70−++ agent
71− =< form
72− |%
73− +$ step (quip card form)
74− +$ card (wind note gift)
75− +$ note
76− $% [%arvo =note-arvo]
77− [%agent [=ship name=term] =task]
78− ==
79− +$ task
80− $% [%watch =path]
81− [%watch-as =mark =path]
82− [%leave ~]
83− [%poke =cage]
84− [%poke-as =mark =cage]
85− ==
86− +$ gift
87− $% [%fact path=(unit path) =cage]
88− [%kick path=(unit path) ship=(unit ship)]
89− [%watch-ack p=(unit tang)]
90− [%poke-ack p=(unit tang)]
91− ==
92− +$ sign
93− $% [%poke-ack p=(unit tang)]
94− [%watch-ack p=(unit tang)]
95− [%fact =cage]
96− [%kick ~]
97− ==
98− ++ form
99− $_ ^|
100− |_ bowl
101− ++ on-init
102− *(quip card _^|(..on-init))
103− ::
104− ++ on-save
105− *vase
106− ::
107− ++ on-load
108− |~ old-state=vase
109− *(quip card _^|(..on-init))
110− ::
111− ++ on-poke
112− |~ [mark vase]
113− *(quip card _^|(..on-init))
114− ::
115− ++ on-watch
116− |~ path
117− *(quip card _^|(..on-init))
118− ::
119− ++ on-leave
120− |~ path
121− *(quip card _^|(..on-init))
122− ::
123− ++ on-peek
124− |~ path
125− *(unit (unit cage))
126− ::
127− ++ on-agent
128− |~ [wire sign]
129− *(quip card _^|(..on-init))
130− ::
131− ++ on-arvo
132− |~ [wire sign-arvo]
133− *(quip card _^|(..on-init))
134− ::
135− ++ on-fail
136− |~ [term tang]
137− *(quip card _^|(..on-init))
138− --
139−```
140−
141−Here's a skeleton example of an implementation:
142−
143−```hoon
144−^- agent:gall
145−=| state=@
146−|_ bowl:gall
147−+* this .
148−++ on-init
149− `this
150−::
151−++ on-save
152− !>(state)
153−::
154−++ on-load
155− |= =old-state=vase
156− `this(state !<(@ old-state-vase))
157−::
158−++ on-poke
159− |= [=mark =vase]
160− ~& > state=state
161− ~& got-poked-with-data=mark
162− =. state +(state)
163− `this
164−::
165−++ on-watch
166− |= path
167− `this
168−::
169−++ on-leave
170− |= path
171− `this
172−::
173−++ on-peek
174− |= path
175− *(unit (unit cage))
176−::
177−++ on-agent
178− |= [wire sign:agent:gall]
179− `this
180−::
181−++ on-arvo
182− |= [wire sign-arvo]
183− `this
184−::
185−++ on-fail
186− |= [term tang]
187− `this
188−--
189−```
190−
191−We also supply a `default-agent` library, which is useful if you don't
192−want to handle some of the arms. Most of the above could also be
193−implemented as:
194−
195−```hoon
196−/+ default-agent
197−^- agent:gall
198−=| state=@
199−|_ =bowl:gall
200−+* this .
201− default ~(. (default-agent this %|) bowl)
202−::
203−++ on-init on-init:default
204−++ on-save on-save:default
205−++ on-load on-load:default
206−++ on-poke
207− |= [=mark =vase]
208− ~& > state=state
209− ~& got-poked-with-data=mark
210− =. state +(state)
211− `this
212−::
213−++ on-watch on-watch:default
214−++ on-leave on-leave:default
215−++ on-peek on-peek:default
216−++ on-agent on-agent:default
217−++ on-arvo on-arvo:default
218−++ on-fail on-fail:default
219−--
220−```
221−
222−So, an agent is a core with 10 arms. The handlers correspond to
223−different sorts of input. We'll discuss each of these in detail, but
224−first a few general concepts.
225−
226−## Basic concepts
227−
228−### Interacting with an agent
229−
230−There are two basic ways programs can interact with an agent: you may
231−subscribe to data as described above, or you may "poke" an agent to send
232−it a command. Suppose there is an agent for a calendar service; then,
233−pokes would likely include `%create-event`, `%modify-event`,
234−`%delete-event`, and `%change-time-zone` (along with assocated data).
235−Subscription paths could include `/next-event` and `/all-events`.
236−
237−Agents generally conform to CQRS -- pokes may change state, but
238−subscriptions generally shouldn't. In practice, there may be state
239−changes required to properly initialize the subscription, but these
240−shouldn't change the essential state of the agent.
241−
242−### Cards
243−
244−Most of the handlers produce a `(quip card agent:gall)`, which is just
245−`[(list card) agent:gall]`. The first allows us to produce effects, and
246−the second allows us to maintain state.
247−
248−A card is one of two things: a `note` or a `gift`. You `%pass` `note`s
249−and you `%give` `gift`s. When you pass a `note`, you expect zero or more
250−responses; when you give a `gift`, you will not get a response. Since you
251−may get a response to a `note`, you tag it with a `wire` so that you can
252−identify the response.
253−
254−Thus, we say you "pass a `note` along a `wire`", or you "give a `gift`".
255−These phrases correspond to producing a card that looks like:
256−
257−```hoon
258−[%pass /my/wire a-note]
259−```
260−
261−or
262−
263−```hoon
264−[%give a-gift]
265−```
266−
267−When you give a `gift`, that's the end of the story, but when you pass a
268−`note`, you may get a response. If you do, then the response will come
269−tagged with the `wire` that you used to pass the `note`. It's generally
270−good practice to make your `wire`s fairly unique within your agent, since
271−otherwise you may not be able to distinguish the responses.
272−
273−#### Notes
274−
275−An agent may pass `note`s to either Arvo or another agent. If the `note` is
276−to another agent, then it should usually be one of these:
277−
278−```hoon
279−[%pass /my/wire %agent [our.bowl agent-name] %watch /a/path]
280−[%pass /my/wire %agent [our.bowl agent-name] %leave ~]
281−[%pass /my/wire %agent [our.bowl agent-name] %poke %foo-mark !>(poke-data)]
282−```
283−
284−Note that to unsubscribe to a `path`, you must send the unsubscription on
285−the same `wire` that sent for the original subscription. Don't subscribe
286−to separate `path`s along the same `wire`, because then you can't properly
287−distinguish them for cancelling (besides not being able to distinguish
288−the subscription updates). In other words, besides letting _you_
289−distinguish your `card`s, the `wire` also identifies requests for the system.
290−
291−If the `note` is not to another agent but to Arvo itself, then it is a
292−request to one of the vanes, which are kernel modules that provide
293−various system services, including IO. Here are some examples:
294−
295−```hoon
296−[%pass /my/wire %arvo %b %wait (add now.hid ~s10)]
297−```
298−
299−This is a request to the `%b` vane (Behn, the timer vane) to set a timer
300−for 10 seconds in the future. After 10 seconds, Behn will respond with
301−a `%wake` card, which you will recieve in `+on-arvo`. It will come back
302−on `/my/wire`.
303−
304−```hoon
305−=/ =path /(scot %p our.hid)/base/(scot %da now.hid)/my-file/txt
306−=/ contents=cage [%txt !>(~['text file line 1' 'line 2'])]
307−[%pass /my/wire %arvo %c %info (foal:space:userlib path contents)]
308−```
309−
310−This is a request to the `%c` vane (Clay, the filesystem vane) to write
311−a file to `/my-file/txt` in the base desk. You will not receive a
312−response to this `note`.
313−
314−```hoon
315−=/ =path /my-file/txt
316−=/ =moat [da+now.hid da+(add now.hid ~h1) path]
317−[%pass /my/wire %arvo %c %warp our.hid %base ~ %many & moat]
318−```
319−
320−This is a request to the `%c` vane to send us a `%writ` `card` whenever
321−`/my-file/txt` changes in the next hour. There may be many responses to
322−this note if the file changes many times.
323−
324−```hoon
325−=/ =request:http
326− [%'GET' 'https://example.com' ~ ~]
327−[%pass /my/wire %arvo %i %request request *outbound-config:iris]
328−```
329−
330−This is a request to the `%i` vane (Iris, the HTTP client vane) to make
331−a GET HTTP request to example.com. The response will come as an
332−`%http-response` card.
333−
334−#### Gifts
335−
336−In contrast to the many possible `note`s, there are only two types of
337−`gift`s that an agent may give:
338−
339−```hoon
340−[%give %fact (unit path) =cage]
341−[%give %kick (unit path)]
342−```
343−
344−A subscription update is a new piece of subscription content for all
345−subscribers on a given `path`. If no `path` is given, then the update is
346−only given to the program that instigated this request. Typical use of
347−this mode is in `+on-watch` to give an initial update to a new
348−subscriber to get them up to date.
349−
350−A subscription close closes the subscription for all subscribers on a
351−given `path`. If no `path` is given, then the update is only given to the
352−program that instigated this request. Typical use of this mode would be
353−in `+on-watch` to produce a single update to a subscription then close
354−the subscription.
355−
356−### Vases and cages
357−
358−A `vase` is a piece of dynamic data. Structurally, it's a pair of an
359−explicit reification of a type and an untyped [noun](/docs/glossary/noun/). This lets us
360−represent a value which has a type that isn't known at compile time. A
361−vase has three operations:
362−
363−- `!>` is a unary rune that lifts a statically typed value to a
364− dynamically-typed `vase`. For example, `!>('hi')` gives `[#t/@t q=26.984]`.
365−
366−- `!<` is a binary rune that takes a mold and a dynamically typed `vase`
367− and reduces it to a statically typed value. If the `vase` does not in
368− fact have the type of the mold you give it, then it nest-fails, else
369− it produces `value`. For example, `!<(@t !>('hi'))` produces `'hi'` while `!<(^ !>('hi'))` causes a nest fail..
370−
371−- The compiler takes text and converts it to a `vase` of the compiled
372− code. Agents shouldn't need this directly, but Gall uses this to
373− compile agents to `vase`s, on which it calls `!<(agent:gall compiled-agent-vase)`.
374−
375−A `cage` is simply a pair of a mark and a vase. A mark is a textual tag
376−that should correspond to the particular dynamic type in the vase.
377−
378−In agents, we use vases to represent types which Gall doesn't know about
379−when it was compiled, but which nevertheless need to go outside the
380−agent. In practice, there are three common cases:
381−
382−- The data in a "poke" request is of a type that is defined by each
383− agent, so it must by dynamic. This is the input to `++on-poke` as well
384− as the cage in the `%poke` case of the `%agent` note.
385−
386−- The data in a subscription update is defined by each agent, so it must
387− be dynamic. This is the cage in `%fact`, both when giving the update
388− and in the input to `+on-agent`.
389−
390−- The state of an agent is also unique to each agent. Most of the time,
391− Gall doesn't interact directly with agent's state, but when upgrading
392− an agent, it must pass the state of the old version of the agent to
393− the new version of the agent. This is the output of `+on-save` and
394− the input to `+on-load`.
395−
396−### State
397−
398−In the definition of an agent, the entire core is wrapped with the `^|`
399−rune, which corresponds to the "iron" variance mode. This means it's
400−"contravariant" in the input, which allows Gall to write to the new bowl
401−on every event. It also means that the context of the core is opaque to
402−Gall, which means you can store state in your context in whatever
403−structure you want.
404−
405−This is why most of the handler arms produce not just a list of cards
406−but also a new `agent:gall`. Usually, this will be the "same" agent in
407−the sense that the code will be the same, but you may have changed the
408−state that's stored in its (opaque to Gall) context.
409−
410−The skeleton example above gives an example of keeping an atom as your
411−state. Define the state in the context of your agent core, then you can
412−change it with `=.` or `%=`, as long as you produce the new version of
413−the agent core.
414−
415−When you upgrade an agent, you need to extract the state from your
416−opaque context and produce it to Gall as a dynamically typed vase.
417−Usually, this will be easy: just call `!>` on whatever state you wish
418−to preserve. This is `+on-save`.
419−
420−When the new agent is about to be started, Gall will call it with
421−`+on-load` with the vase just produced above. This allows you to ingest
422−your old state and continue right where you left off.
423−
424−If the type of your state hasn't changed, you can just
425−
426−```hoon
427−=. state !<(state-type old-state-vase)
428−```
429−
430−If it has changed, then it should look more like:
431−
432−```hoon
433−=. state (upgrade-state !<(old-state-type old-state-vase))
434−```
435−
436−It's useful to tag your state with a version number so that the
437−`+upgrade-state` function can take a tagged union of all your old state
438−types and upgrade from any of them to the current state type. For
439−example, it may have the following structure:
440−
441−```hoon
442−+$ old-state-types
443− $% [%0 s=state-0]
444− [%1 s=state-1]
445− [%2 s=state-2]
446− ==
447−++ upgrade-state
448− |= old=old-state-types
449− =? old ?=(%0 -.old)
450− (state-0-to-1 s.old)
451− =? old ?=(%1 -.old)
452− (state-1-to-2 s.old)
453− ?> ?=(%2 -.old)
454− s.old
455−```
456−
457−### Bowl
458−
459−The core takes as input a `bowl`, which includes useful info like the
460−current ship, the current time, and a renewable source of entropy. This
461−information is available to any of the handlers.
462−
463−## Arms
464−
465−A description of each of the handler arms follows.
466−
467−### +on-init
468−
469−This arm is called once when the agent is started. It has no input and
470−lets you perform any initial IO.
471−
472−### +on-save
473−
474−This arm is called immediately before the agent is upgraded. It
475−packages the permament state of the agent in a `vase` for the next version
476−of the agent. Unlike most handlers, this cannot produce effects.
477−
478−### +on-load
479−
480−This arm is called immediately after the agent is upgraded. It receives
481−a `vase` of the state of the previously-running version of the agent,
482−which allows it to cleanly upgrade from the old agent.
483−
484−### +on-poke
485−
486−This arm is called when the agent is "poked". The input is a `cage`, so
487−it's a pair of a mark and a dynamic `vase`.
488−
489−### +on-watch
490−
491−This arm is called when a program wants to subscribe to the agent on a
492−particular `path`. The agent may or may not need to perform setup steps
493−to intialize the subscription. It may produce a `%give`
494−`%subscription-result` to the subscriber to get it up to date, but after
495−this event is complete, it cannot give further updates to a specific
496−subscriber. It must give all further updates to all subscribers on a
497−specific `path`.
498−
499−If this arm crashes, then the subscription is immediately terminated.
500−More specifcally, it never started -- the subscriber will receive a
501−negative `%watch-ack`. You may also produce an explicit `%kick` to
502−close the subscription without crashing -- for example, you could
503−produce a single update followed by a `%kick`.
504−
505−### +on-leave
506−
507−This arm is called when a program becomes unsubscribed to you.
508−Subscriptions may close because the subscriber intentionally
509−unsubscribed, but they also could be closed by an intermediary. For
510−example, if a subscription is from another ship which is currently
511−unreachable, Ames may choose to close the subscription to avoid queueing
512−updates indefinitely. If the program crashes while processing an
513−update, this may also generate an unsubscription. You should consider
514−subscriptions to be closable at any time.
515−
516−### +on-peek
517−
518−This arm is called when a program reads from the agent's "scry"
519−namespace, which should be referentially transparent. Unlike most
520−handlers, this cannot perform IO, and it cannot change the state. All
521−it can do is produce a piece of data to the caller, or not.
522−
523−If this arm produces `[~ ~ data]`, then `data` is the value at the the
524−given `path`. If it produces `[~ ~]`, then there is no data at the given
525−`path` and never will be. If it produces `~`, then we don't know yet
526−whether there is or will be data at the given `path`.
527−
528−### +on-agent
529−
530−This arm is called to handle responses to `%give` moves to other agents.
531−It will be one of the following types of response:
532−
533−- `%poke-ack`: acknowledgment (positive or negative) of a poke. If the
534− value is `~`, then the poke succeeded. If the value is `[~ tang]`,
535− then the poke failed, and a printable explanation (e.g. a stack trace)
536− is given in the `tang`.
537−
538−- `%watch-ack`: acknowledgment (positive or negative) of a subscription.
539− If negative, the subscription is already ended (technically, it never
540− started).
541−
542−- `%fact`: update from the publisher.
543−
544−- `%kick`: notification that the subscription has ended.
545−
546−### +on-arvo
547−
548−This arm is called to handle responses to `%pass` `move`s to vanes. The
549−list of possible responses from the system is statically defined in
550−`sys/lull.hoon` (grep for `+$ sign-arvo`).
551−
552−### +on-fail
553−
554−If an error happens in `+on-poke`, the crash report goes into the
555−`%poke-ack` response. Similarly, if an error happens in
556−`+on-subscription`, the crash report goes into the `%watch-ack`
557−response. If a crash happens in any of the other handlers, the report
558−is passed into this arm.
content/docs/arvo/iris/_index.mddeleted−23
@@ -1,23 +0,0 @@
1−+++
2−title = "Iris"
3−weight = 80
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−insert_anchor_links = "right"
7−+++
8−
9−## [Overview](/docs/arvo/iris/iris)
10−
11−A brief overbview of Iris, Urbit's HTTP client vane.
12−
13−## [API Reference](/docs/arvo/eyre/tasks)
14−
15−The `task`s Iris takes and the `gift`s it returns.
16−
17−## [Data Types](/docs/arvo/iris/data-types)
18−
19−Reference documentation of the data types used by Iris.
20−
21−## [Example](/docs/arvo/iris/example)
22−
23−An example of using Iris to fetch a remote HTTP resource.
content/docs/arvo/iris/data-types.mddeleted−54
@@ -1,54 +0,0 @@
1−+++
2−title = "Data Types"
3−weight = 3
4−template = "doc.html"
5−+++
6−
7−Iris itself only has three structures defined in `lull.hoon`, but it also uses `$http` structures which are shared between Iris and Eyre. The `$http` structures are detailed in the [Eyre](/docs/arvo/eyre/data-types#http) Data Types documentation.
8−
9−## `$client-response`
10−
11−```hoon
12−+$ client-response
13− $%
14− $: %progress
15− =response-header:http
16− bytes-read=@ud
17− expected-size=(unit @ud)
18− incremental=(unit octs)
19− ==
20− [%finished =response-header:http full-file=(unit mime-data)]
21− [%cancel ~]
22− ==
23−```
24−
25−This structure represents data which Iris has fetched from a remote HTTP resource, and is what's returned in a `%http-response` `gift` (see the [%request](/docs/arvo/iris/tasks#request) documentation for details) by Iris to the app or thread which requested it. There are three kinds of `client-response` - `%progress`, `%finished` and `%cancel`. A `%progress` `client-response` is a partial response, such as when an HTTP response is split into multiple separate chunks. A `%finished` `client-response` is the final complete, assembled and parsed HTTP response. A `%cancel` `client-response` is sent when the runtime cancels the request for some reason.
26−
27−Note that at the time of writing, **neither `%progress` nor `%cancel` `client-response`s are implemented**, so in practice you'll only ever get a single `%finished` `client-response`.
28−
29−In a `%progress` `client-response`, the [$response-header:http](/docs/arvo/eyre/data-types#response-headerhttp) contains the HTTP status code and headers. The `bytes-read` field is the total number of bytes fetched so far. The `expected-size` field is the total size specified in the content-length header if it has one. The `incremental` field is the data received since the last `%http-response`.
30−
31−In a `%finished` `client-response`, the `full-file` is the complete body of the HTTP message as a (maybe) [$mime-data](#mime-data).
32−
33−## `$mime-data`
34−
35−```hoon
36−+$ mime-data
37− [type=@t data=octs]
38−```
39−
40−Unvalidated mime data that has been fetched from a remote HTTP resource.
41−
42−## `$outbound-config`
43−
44−```hoon
45−+$ outbound-config
46− $:
47− redirects=_5
48− retries=_3
49− ==
50−```
51−
52−This structure is used in a [%request task](/docs/arvo/iris/tasks#request) to specify settings for an HTTP request. The `redirects` field specifies the number of redirects to automatically follow before failing, and defaults to 5. The `retries` field specifies the number of times to retry a failed request before giving up, and defaults to 3.
53−
54−Note that at the time of writing, **neither redirects nor retries have been implemented**, so these settings will not do anything and you can just use the bunt value in all cases.
content/docs/arvo/iris/example.mddeleted−87
@@ -1,87 +0,0 @@
1−+++
2−title = "Example"
3−weight = 4
4−template = "doc.html"
5−+++
6−
7−Here we'll look at a simple example of fetching a remote HTTP resource with Iris. We'll use the following thread, which you can save in the `/ted` directory of your `%base` desk:
8−
9−`iris-thread.hoon`
10−
11−```hoon
12−/- spider
13−/+ strandio
14−=, strand=strand:spider
15−^- thread:spider
16−|= arg=vase
17−=/ m (strand ,vase)
18−^- form:m
19−=/ url=@t (need !<((unit @t) arg))
20−=/ =request:http [%'GET' url ~ ~]
21−=/ =task:iris [%request request *outbound-config:iris]
22−=/ =card:agent:gall [%pass /http-req %arvo %i task]
23−;< ~ bind:m (send-raw-card:strandio card)
24−;< res=(pair wire sign-arvo) bind:m take-sign-arvo:strandio
25−?. ?=([%iris %http-response %finished *] q.res)
26− (strand-fail:strand %bad-sign ~)
27−~& +.q.res
28−?~ full-file.client-response.q.res
29− (strand-fail:strand %no-body ~)
30−(pure:m !>(`@t`q.data.u.full-file.client-response.q.res))
31−```
32−
33−This thread takes a fully qualified URL in a `@t` as an argument. It will ask Iris to fetch the HTTP resource at the given URL by passing it a [%request task](/docs/arvo/iris/tasks#request) containing an HTTP GET [$request:http](/docs/arvo/eyre/data-types#requesthttp):
34−
35−```hoon
36−=/ url=@t (need !<((unit @t) arg))
37−=/ =request:http [%'GET' url ~ ~]
38−=/ =task:iris [%request request *outbound-config:iris]
39−=/ =card:agent:gall [%pass /http-req %arvo %i task]
40−```
41−
42−In this example, our `request:http` specifies no additional headers and has no body so it has a `~` for each of those fields. Of course in practice if you have headers or data you want to send you would include those.
43−
44−Our thread will take the `%http-response` `gift` that comes back from Iris and debug print it to the terminal so you can have a look at the structure, and then it will cast the body of the HTTP message to a `@t` and print it.
45−
46−Let's try it out:
47−
48−```
49−> -iris-thread 'http://example.com'
50−[ %http-response
51− client-response
52− [ %finished
53− response-header
54− [ status-code=200
55− headers
56− ~[
57− [key='age' value='212909']
58− [key='cache-control' value='max-age=604800']
59− [key='content-type' value='text/html; charset=UTF-8']
60− [key='date' value='Thu, 24 Jun 2021 04:12:13 GMT']
61− [key='expires' value='Thu, 01 Jul 2021 04:12:13 GMT']
62− [key='last-modified' value='Thu, 17 Oct 2019 07:18:26 GMT']
63− [key='server' value='ECS (oxr/8328)']
64− [key='vary' value='Accept-Encoding']
65− [key='x-cache' value='HIT']
66− [key='content-length' value='1256']
67− ]
68− ]
69− full-file
70− [ ~
71− [ type='text/html; charset=UTF-8'
72− data
73− [ p=1.256
74− q
75− 224.708.415.080.409.844.273.808.970.700.472.455.882.111.359.8(...truncated for brevity)
76− ]
77− ]
78− ]
79− ]
80−]
81−```
82−
83−...and here's the data from the HTTP response cast to a `@t`:
84−
85−```
86−'<!doctype html>\0a<html>\0a<head>\0a <title>Example Domain</title>\0a\0a (...truncated for brevity)'
87−```
content/docs/arvo/iris/iris.mddeleted−17
@@ -1,17 +0,0 @@
1−+++
2−title = "Overview"
3−weight = 1
4−template = "doc.html"
5−+++
6−
7−Iris is the HTTP client vane.
8−
9−Iris gets passed HTTP requests, makes the request to the specified URL, and returns the HTTP response.
10−
11−## Sections
12−
13−[Data Types](/docs/arvo/iris/data-types) - Reference documentation of the data types used by Iris.
14−
15−[API Reference](/docs/arvo/eyre/tasks) - The `task`s Iris takes and the `gift`s it returns.
16−
17−[Example](/docs/arvo/iris/example) - An example of using Iris to fetch a remote HTTP resource.
content/docs/arvo/iris/tasks.mddeleted−61
@@ -1,61 +0,0 @@
1−+++
2−title = "API Reference"
3−weight = 2
4−template = "doc.html"
5−+++
6−
7−This document details the `task`s used by Iris. Iris only has three `task`s besides the standard vane `task`s: [%request](#request), [%cancel-request](#cancel-request), and [%receive](#receive). The `%receive` `task` is only sent to Iris by the runtime, so you're likely to only use `%request` and `%cancel-request`.
8−
9−## `%request`
10−
11−```hoon
12−[%request =request:http =outbound-config]
13−```
14−
15−Fetch a remote HTTP resource.
16−
17−The [$request:http](/docs/arvo/eyre/data-types#requesthttp) is the request itself and contains the HTTP method, the fully qualified target URL, a list of HTTP headers to be included and maybe the data for the body of the request.
18−
19−The [$outbound-config](/docs/arvo/iris/data-types#outbound-config) specifies the number of redirects to follow before failing and the number of retries to attempt before giving up. The default values are `5` and `3` respectively. As of writing, **retries and auto-following redirects are not implemented**, so what you specify here is irrelevant and you can just use the bunt value of `outbound-config`.
20−
21−#### Returns
22−
23−Iris returns a `%http-response` `gift` in response to a `%request` task. A `%response` `gift` looks like:
24−
25−```hoon
26−[%http-response =client-response]
27−```
28−
29−The [$client-response](/docs/arvo/iris/data-types#client-response) contains the HTTP response from the server including the status code, HTTP headers and any data along with its mime type.
30−
31−The `client-response` structure specifies three kinds of responses - `%progress`, `%finished` and `%cancel`. The `%progress` response would contain each chunk of the message as it came in, `%finished` would contain the final assembled message from Vere's buffer, and `%cancel` would be sent if the runtime cancels the request.
32−
33−Note that neither `%progress` partial messages nor `%cancel` responses have been implemented in Vere at the time of writing, so **you will only ever receive a single `%http-response` `gift` with a `%finished` `client-response`**. If the request fails for some reason, you'll still get an empty `%finished` `client-response` with a `504` status code.
34−
35−#### Example
36−
37−See the [Example](/docs/arvo/iris/example) document.
38−
39−## `%cancel-request`
40−
41−```hoon
42−[%cancel-request ~]
43−```
44−
45−Cancel a previous request to fetch a remote HTTP resource.
46−
47−A `%cancel-request` `task` does not take any arguments, the [request](#request) to cancel is determined implicitly.
48−
49−#### Returns
50−
51−Iris does not return any `gift` in response to a `%cancel-request` `task`. You will also not receive any `gift` back from the original `%request` `task` you've cancelled.
52−
53−## `%receive`
54−
55−```hoon
56−[%receive id=@ud =http-event:http]
57−```
58−
59−Receives HTTP data from outside. This `task` is sent to Iris by the runtime, you would not use it manually.
60−
61−The `id` is a sequential ID for the event and the [$http-event:http](/docs/arvo/eyre/data-types#http-eventhttp) contains the HTTP headers and data.
content/docs/arvo/jael/_index.mddeleted−27
@@ -1,27 +0,0 @@
1−+++
2−title = "Jael"
3−weight = 90
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−insert_anchor_links = "right"
7−+++
8−
9−## [Overview](/docs/arvo/jael/jael)
10−
11−An overview of Jael, Urbit's security and encryption vane.
12−
13−## [API Reference](/docs/arvo/jael/tasks)
14−
15−The `task`s Jael takes and the `gift`s it returns.
16−
17−## [Scry Reference](/docs/arvo/jael/scry)
18−
19−The scry endpoints of Jael.
20−
21−## [Data Types](/docs/arvo/jael/data-types)
22−
23−Reference documentation of the various data types used by Jael.
24−
25−## [Examples](/docs/arvo/jael/examples)
26−
27−Practical examples of using Jael's `task`s.
content/docs/arvo/jael/data-types.mddeleted−243
@@ -1,243 +0,0 @@
1−+++
2−title = "Data Types"
3−weight = 4
4−template = "doc.html"
5−+++
6−
7−Jael's section in `lull.hoon` contains three ancillary cores with their own type definitions as well as Jael's general types.
8−
9−### `$public-keys-result`
10−
11−```hoon
12−+$ public-keys-result
13− $% [%full points=(map ship point)]
14− [%diff who=ship =diff:point]
15− [%breach who=ship]
16− ==
17−```
18−
19−This is what Jael gives (in a [%public-keys](/docs/arvo/jael/tasks#public-keys) `gift`) to subcribers who are tracking public key information for a `set` of `ship`s.
20−
21−Typically the `%full` kind with a `map` of `ship`s to [$point:point](#pointpoint)s is given immediately upon subscription and contains all public key records for the ships in question. After the `%full`, a `%diff` (including a [$diff:point](#diffpoint)) will be given whenever a change (such as the sponsor or pubkey) has occurred for one of the ships being tracked, and a `%breach` will be given whenever a continuity breach for a tracked ship occurs.
22−
23−### `$seed`
24−
25−```hoon
26−+$ seed [who=ship lyf=life key=ring sig=(unit oath:pki)]
27−```
28−
29−Private boot parameters. The `who` field is the name of the ship, `lyf` is the `life` (key revision number), `key` is the private key and `sig` is the signature of the parent ship if it's a moon, and `~` otherwise.
30−
31−### `$dawn-event`
32−
33−```hoon
34−+$ dawn-event
35− $: =seed
36− spon=(list [=ship point:azimuth-types])
37− czar=(map ship [=rift =life =pass])
38− turf=(list turf)
39− bloq=@ud
40− node=(unit purl:eyre)
41− ==
42−```
43−
44−Ship initialisation parameters.
45−
46−- [$seed](#seed) contains the private boot parameters.
47−- `spon` is a `list` of ships and their [$point](#pointpoint)s in the ship's sponsorship chain, all the way to the galaxy level.
48−- `czar` is a map from each galaxy's `@p` to its `rift`, `life`, and public key (`pass`).
49−- `turf` is a `list` of DNS suffixes used for galaxies, which is `urbit.org` by default.
50−- `bloq` is the number of the Ethereum block in which the ship registered its keys with the Azimuth smart contract.
51−- `node` is the URL of the Ethereum node used to monitor Azimuth.
52−
53−### `$source`
54−
55−```hoon
56−+$ source (each ship term)
57−```
58−
59−Source of public key updates for Jael. If it's a `term` it's a Gall agent e.g `%azimuth-tracker`. If it's a `ship`, Jael will subscribe to that ship's Jael for updates - e.g. Jael will subscribe to the parent planet of moons for updates about the moons.
60−
61−### `$source-id`
62−
63−```hoon
64−+$ source-id @udsourceid
65−```
66−
67−Numerical index for Jael to organise its `source`s. Jael assigns its `source-id`s sequentially, starting from `0`.
68−
69−### `$state-eth-node`
70−
71−```hoon
72−+$ state-eth-node :: node config + meta
73− $: top-source-id=source-id
74− sources=(map source-id source)
75− sources-reverse=(map source source-id)
76− default-source=source-id
77− ship-sources=(map ship source-id)
78− ship-sources-reverse=(jug source-id ship)
79− ==
80−```
81−
82−Jael's data about `source`s for PKI updates about ships.
83−
84−- `top-source-id` tracks the highest `source-id` so Jael can easily determine what the next `source-id` should be.
85−- `sources` is a `map` of [$source-id](#source-id)s to [$source](#source)s.
86−- `sources-reverse` the same as `sources` but in reverse.
87−- `default-source` is the default `source` to use (typically `0` - `%azimuth-tracker`).
88−- `ship-sources` is a `map` from `ship`s to `source-id`s and records where to get updates from for the ships in question. Typically these will map moons to their parent ships.
89−- `ship-sources-reverse` is the same as `ship-sources` but in reverse.
90−
91−## block
92−
93−Structures for Ethereum blocks.
94−
95−### `$hash:block`
96−
97−```hoon
98−+$ hash @uxblockhash
99−```
100−
101−Ethereum block hash.
102−
103−### `$number:block`
104−
105−```hoon
106−+$ number @udblocknumber
107−```
108−
109−Ethereum block number.
110−
111−### `$id:block`
112−
113−```hoon
114−+$ id [=hash =number]
115−```
116−
117−Ethereum block identifier - contains both the [$hash:block](#hashblock) and [$number:block](#numberblock).
118−
119−### `$block:block`
120−
121−```hoon
122−+$ block [=id =parent=hash]
123−```
124−
125−A reference to an Ethereum block - contains the [$id:block](#idblock) and the [$hash:block](#hashblock) of its parent for ordering purposes.
126−
127−## point
128−
129−Structures for points (Ship IDs in Azimuth).
130−
131−### `$point:point`
132−
133−```hoon
134−+$ point
135− $: =rift
136− =life
137− keys=(map life [crypto-suite=@ud =pass])
138− sponsor=(unit @p)
139− ==
140−```
141−
142−Public key data for a particular ship. The `rift` is the current continuity breach number and `life` is the current key revision number. The `keys` `map` contains the public key (`pass`) for each `life` up to the current one. The `sponsor` is the current sponsor of the ship in question, if it has one.
143−
144−### `$key-update:point`
145−
146−```hoon
147−+$ key-update [=life crypto-suite=@ud =pass]
148−```
149−
150−An update to a ship's keys. The `life` is the key revision number, `crypt-suite` is a version number for the cryptographic suite used for keys in Azimuth, and `pass` is the public key itself.
151−
152−### `$diffs:point`
153−
154−```hoon
155−+$ diffs (list diff)
156−```
157−
158−A list of invertible [$diff:point](#diffpoint)s.
159−
160−### `$diff:point`
161−
162−```hoon
163−+$ diff
164− $% [%rift from=rift to=rift]
165− [%keys from=key-update to=key-update]
166− [%spon from=(unit @p) to=(unit @p)]
167− ==
168−```
169−
170−An invertible diff for public key (and related) changes to the state of an Azimuth point (ship ID).
171−
172−- `%rift` is a change to the `rift` (continuity breach number) that occurs when a ship undergoes a continuity breach.
173−- `%keys` is a change to a ship's `life` and public key, specified in the [$key-update:point](#key-updatepoint).
174−- `%spon` is a change to a ship's sponsor.
175−
176−The `from` and `to` field specify the old a new values respectively.
177−
178−### `$udiffs:point`
179−
180−```hoon
181−+$ udiffs (list [=ship =udiff])
182−```
183−
184−A list of non-invertible [$udiff:point](#udiffpoint)s.
185−
186−### `$udiff:point`
187−
188−```hoon
189−+$ udiff
190− $: =id:block
191− $% [%rift =rift]
192− [%keys key-update]
193− [%spon sponsor=(unit @p)]
194− [%disavow ~]
195− == ==
196−```
197−
198−A non-invertible diff for public key (and related) changes to the state of an Azimuth point (ship ID).
199−
200−The [$id:block](#idblock) contains the block number and block hash of the Ethereum block in which the change occurred. The next part specifies what changed, where:
201−
202−- `%rift` means the ship has undergone a continuity breach and therefore the `rift` (continuity revision number) has changed.
203−- `%keys` means the ship's `life` (key revision number) has changed, the [$key-update:point](#key-updatepoint) contains the new `life` and pubkeys.
204−- `%spon` means the ship's sponsor has changed.
205−- `%disavow` means a previous Ethereum block has been disavowed.
206−
207−A `udiff:point` can be converted to a [$diff:point](#diffpoint) with the `+udiff-to-diff:point` function.
208−
209−## pki
210−
211−This structure is mostly a holdover from prior versions of Jael and is unused apart from [$oath:pki](#oathpki).
212−
213−### `$hand:pki`
214−
215−```hoon
216−+$ hand @uvH
217−```
218−
219−128-bit Hash.
220−
221−### `$mind:pki`
222−
223−```hoon
224−+$ mind [who=ship lyf=life]
225−```
226−
227−Key identifier.
228−
229−### `$name:pki`
230−
231−```hoon
232−+$ name (pair @ta @t)
233−```
234−
235−Name in both ASCII and Unicode.
236−
237−### `$oath:pki`
238−
239−```hoon
240−+$ oath @
241−```
242−
243−Signature. This type is used in the [$seed](#seed) for moons as a signature from the moon's parent.
content/docs/arvo/jael/examples.mddeleted−251
@@ -1,251 +0,0 @@
1−+++
2−title = "Examples"
3−weight = 5
4−template = "doc.html"
5−+++
6−
7−This documents contains practical examples of a number of Jael's `task`s.
8−
9−General documentation of the `task`s demonstrated here can be found in the [API Reference](/docs/arvo/jael/tasks) document, and details of the data types mentioned can be found in the [Data Types](/docs/arvo/jael/data-types) document.
10−
11−## `%private-keys`
12−
13−Here we'll look at subscribing to private key updates from Jael. We'll use a thread to pass Jael a `%private-keys` `task`, take the `%private-keys` `gift` it returns, debug print it to the terminal and finally unsubscribe with a `%nuke` `task`.
14−
15−`sub-priv.hoon`
16−
17−```hoon
18−/- spider
19−/+ strandio
20−=, strand=strand:spider
21−=, card=card:agent:gall
22−^- thread:spider
23−|= arg=vase
24−=/ m (strand ,vase)
25−^- form:m
26−;< ~ bind:m (send-raw-card:strandio %pass /sub-priv %arvo %j %private-keys ~)
27−;< res=[=wire =sign-arvo] bind:m take-sign-arvo:strandio
28−?> ?=([%sub-priv ~] wire.res)
29−?> ?=([%jael *] sign-arvo.res)
30−~& +.sign-arvo.res
31−;< ~ bind:m (send-raw-card:strandio %pass /sub-priv %arvo %j %nuke ~)
32−(pure:m !>(~))
33−```
34−
35−Save the above thread in the `/ted` directory of your `%base` desk and `|commit %base`.
36−
37−Now let's run the thread:
38−
39−```
40−> -sub-priv
41−```
42−
43−You should see the `%private-key` `gift` it returns in the Dojo:
44−
45−```
46−[ %private-keys
47− life=1
48− vein
49− { [ p=1
50− q
51− 1.729.646.917.183.337.[...truncated for brevity]
52− ]
53− }
54−]
55−```
56−
57−At this point our thread unsubscribes again with a `%nuke` `task` but without that it would send a new `%private-key` `gift` each time the private keys were changed.
58−
59−## `%public-keys` and `%nuke`
60−
61−Here we'll look at both subscribing and unsubscribing to updates of a ship's public keys in Jael. We'll subscribe by sending Jael a `%public-keys` `task`, take the `%public-keys` `gift` it responds with, print it to the terminal, scry for the `set` of `duct`s subscribed to the ship in question, print them to the terminal, and finally send Jael a `%nuke` `task` to unsubscribe.
62−
63−Here's a thread that performs these actions:
64−
65−`sub-pub.hoon`
66−
67−```hoon
68−/- spider
69−/+ strandio
70−=, strand=strand:spider
71−=, card=card:agent:gall
72−=>
73−|%
74−+$ subs
75− $: yen=(jug duct ship)
76− ney=(jug ship duct)
77− nel=(set duct)
78− ==
79−--
80−^- thread:spider
81−|= arg=vase
82−=/ m (strand ,vase)
83−^- form:m
84−=/ =@p (need !<((unit @p) arg))
85−::
86−:: sub to public updates for specified ship
87−=/ c1=card [%pass /sub-pubkeys %arvo %j %public-keys (silt ~[p])]
88−;< ~ bind:m (send-raw-card:strandio c1)
89−::
90−:: take response from jael & print it
91−;< res=[=wire =sign-arvo] bind:m take-sign-arvo:strandio
92−?> ?=([%sub-pubkeys ~] wire.res)
93−?> ?=([%jael %public-keys *] sign-arvo.res)
94−~& +.sign-arvo.res
95−::
96−:: scry for tracking subs for specified ship in jael & print
97−;< =subs bind:m (scry:strandio ,subs /j/subscriptions/1)
98−=/ ducts=(set duct) (~(get ju ney.subs) p)
99−~& ducts
100−::
101−:: unsub from public updates for specified ships
102−=/ c2=card [%pass /sub-pubkeys %arvo %j %nuke (silt ~[p])]
103−;< ~ bind:m (send-raw-card:strandio c2)
104−(pure:m !>(~))
105−```
106−
107−Note this example was performed on a comet as a fake ship won't have the required information in Jael.
108−
109−Save the above thread in the `/ted` directory and `|commit %base`. The thread takes a `ship` as an argument, so we'll try to subscribe to pubkey updates for `~dopzod`. Let's run the thread:
110−
111−```
112−> -sub-pub ~dopzod
113−```
114−
115−It first passes a `%public-keys` `task` to Jael that looks like `[%public-keys (silt ~[~dopzod])]` in order to subscribe. Jael will immediately respond with a `%public-keys` `gift` that contains a `%full` [$public-keys-result](/docs/arvo/jael/data-types#public-keys-result). The `(map ship point)` contained will (for each ship specified in the `task`) include the current pubkeys for the ship's current life as well as previous keys for previous `life`s. It thus contains a complete record of keys up to the present for each ship. Our thread will print these out to the terminal like so:
116−
117−```
118−[ %public-keys
119− public-keys-result
120− [ %full
121− points
122− { [ p=~dopzod
123− q
124− [ rift=2
125− life=3
126− keys
127− { [ p=1
128− q
129− [ crypto-suite=1
130− pass
131− 939.529.329.928[...truncated for brevity...]
132− ]
133− ]
134− [ p=2
135− q
136− [ crypto-suite=1
137− pass
138− 2.215.774.809.906.200.376.0[...truncated for brevity...]
139− ]
140− ]
141− [ p=3
142− q
143− [ crypto-suite=1
144− pass
145− 707.070.568.606.374.[...truncated for brevity...]
146− ]
147− ]
148− }
149− sponsor=~
150− ]
151− ]
152− }
153− ]
154−]
155−```
156−
157−Along with giving us the current information, Jael will also subscribe us to any future updates for the ships in question. Such updates will come as additional `%public-keys` `gift`s, but rather than a `%full` `public-keys-result`, they'll instead contain either a `%diff` or `%breach` `public-keys-result`, depending on what's happened to the ship in question. It's difficult to simulate such events for demonstrative purposes so an example is not included, but you can look at the [$public-keys-result](/docs/arvo/jael/data-types#public-keys-result) to get an idea.
158−
159−Jael maintains a `(jug duct ship)` and its reverse `(jug ship duct)` in its state to track subscriptions. If we do a [subscriptions](/docs/arvo/jael/scry#subscriptions) scry and filter the result for `~dopzod`, we can see the duct of our thread has now been added to the `~dopzod` `set`. Our thread does this, and will output something like:
160−
161−```
162−{~[/gall/use/spider/0w1.vGVi-/~sampel-palnet/thread/~.dojo_0v6.0hlak.dam1b.bcdou.ai7gq.19fi8/sub-pubkeys /dill //term/1]}
163−```
164−
165−At this point our thread will send a `%nuke` `task` like `[%nuke (silt ~[~dopzod])]` to cancel our subscription. Jael doesn't respond to it, but now, with our thread having finished and exited, we can again scry & filter for subscriptions to `~dopzod`:
166−
167−```
168−> =/(a .^([yen=(jug duct ship) ney=(jug ship duct) nel=(set duct)] %j /=subscriptions=/1) (~(get ju ney.a) ~dopzod))
169−~
170−```
171−
172−As you can see the `set` is now empty, so we know the `%nuke` succeeded and Jael will no longer send us pubkey updates for `~dopzod`. One thing to note about `%nuke` is that it _must_ come from the same `duct` as the original subscription. You can't unsubscribe another app, ship, thread or what have you, so if we'd tried `%nuke`ing the subscription from a separate thread it wouldn't have worked.
173−
174−## `%turf`
175−
176−Here we'll look at using a `%turf` `task` to get Jael's list of domains. Note on a fake ship the list will be empty, so you may with to run it on a comet or moon.
177−
178−Here's a simple thread that'll pass Jael a `%turf` `task`, take the `%turf` `gift` it sends back and print it to the terminal:
179−
180−`turf.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−=/ =task:jael [%turf ~]
191−=/ =card:agent:gall [%pass /get-domains %arvo %j task]
192−;< ~ bind:m (send-raw-card:strandio card)
193−;< resp=[=wire =sign-arvo] bind:m take-sign-arvo:strandio
194−?> ?=([%get-domains ~] wire.resp)
195−?> ?=([%jael %turf *] sign-arvo.resp)
196−~& +.sign-arvo.resp
197−(pure:m !>(~))
198−```
199−
200−Save in in the `/ted` directory of your ship and `|commit %base`. Next, let's try running it:
201−
202−```
203−> -turf
204−[%turf turf=~[<|org urbit|>]]
205−```
206−
207−As you see, the `%turf` `gift` contains `urbit.org` as `~['org' 'urbit']`.
208−
209−## `%step`
210−
211−Here we'll look at changing the web login code with a `%step` task.
212−
213−First, let's see the current `step` with a `%step` scry:
214−
215−```
216−> .^(@ud %j /=step=/(scot %p our))
217−0
218−```
219−
220−...and the current code with the `+code` generator:
221−
222−```
223−> +code
224−lidlut-tabwed-pillex-ridrup
225−```
226−
227−Now, let's pass Jael a `%step` task by using `|pass` in the dojo:
228−
229−```
230−> |pass [%j %step ~]
231−```
232−
233−Jael will `pass` Eyre a `%code-changed` `task:eyre` to let Eyre know the code's changed so you'll see a message from Eyre in the terminal:
234−
235−```
236−eyre: code-changed: throwing away cookies and sessions
237−```
238−
239−Now let's again scry for the `step` and see that it's been incremented:
240−
241−```
242−> .^(@ud %j /=step=/(scot %p our))
243−1
244−```
245−
246−And finally, let's again run `+code` and see there's now a new web login code:
247−
248−```
249−> +code
250−raldev-topnul-mirnut-lablut
251−```
content/docs/arvo/jael/jael.mddeleted−25
@@ -1,25 +0,0 @@
1−+++
2−title = "Overview"
3−weight = 1
4−template = "doc.html"
5−+++
6−
7−Jael is the networking key infrastructure vane.
8−
9−The main purpose of Jael is keeping track of [Azimuth](/docs/azimuth/azimuth) related information. For each ship, this consists of its public keys, its key revision number (or `life`), its continuity breach number (or `rift`) (see [Life and Rift](/docs/azimuth/life-and-rift)), and who the sponsor of the ship is. It also handles the local ship's private keys, keeps track of galaxy domain prefixes, and performs some boot-related tasks.
10−
11−By default, Jael's primary source of information is the Gall agent `%azimuth-tracker`, which (using `%eth-watcher`) runs a thread that polls an Ethereum node for transactions in the Azimuth contract. It can also get updates from other ships on the network. This is always the case for moons, where it subscribes to the moon's parent's Jael for updates.
12−
13−The database of PKI information that Jael maintains is used by other vanes and agents for identity validation, encryption, decryption, and other cryptographic functions. In particular, Ames (the network vane) uses the information stored in Jael to encrypt packets it sends to other ships, and to decrypt & validate packets it receives from other ships.
14−
15−Jael has a few `task`s you can use to interact with it. In particular, its [%public-keys task](/docs/arvo/jael/tasks#public-keys) allows an agent or thread to subscribe for PKI updates for a `set` of `ship`s.
16−
17−## Sections
18−
19−[API Reference](/docs/arvo/jael/tasks) - The `task`s Jael takes and the `gift`s it returns.
20−
21−[Scry Reference](/docs/arvo/jael/scry) - The scry endpoints of Jael.
22−
23−[Data Types](/docs/arvo/jael/data-types) - Reference documentation of the various data types used by Jael.
24−
25−[Examples](/docs/arvo/jael/examples) - Practical examples of using Jael's `task`s.
content/docs/arvo/jael/scry.mddeleted−204
@@ -1,204 +0,0 @@
1−+++
2−title = "Scry Reference"
3−weight = 3
4−template = "doc.html"
5−+++
6−
7−Jael's scry endpoints never take a `care`. The particular endpoints are specified in the place of the desk in the path prefix, then additional arguments are specified in the path. Note this style of scry path is considered outdated, and may be changed in the future.
8−
9−## `%step`
10−
11−A `%step` scry gets the current web login code revision number. It takes your ship name as its `path` and the type returned is a `@ud`.
12−
13−#### Example
14−
15−```
16−> .^(@ud %j /=step=/(scot %p our))
17−0
18−```
19−
20−## `%code`
21−
22−A `%code` scry gets the current web login code. It takes your ship name as its `path` and the type returned is a `@p`.
23−
24−#### Example
25−
26−```
27−> .^(@p %j /=code=/(scot %p our))
28−~lidlut-tabwed-pillex-ridrup
29−```
30−
31−## `%life`
32−
33−A `%life` scry gets the current `life` (key revision number) of a ship if known, otherwise it crashes. It takes a ship as its `path` and the type returned is a `@ud`.
34−
35−#### Example
36−
37−```
38−> .^(@ud %j /=life=/(scot %p our))
39−1
40−```
41−
42−## `%lyfe`
43−
44−A `%lyfe` scry gets the current unitized `life` (key revision number) of a ship if known, otherwise returns `~`. It takes a ship as its `path` and the type returned is a `(unit @ud)`.
45−
46−#### Example
47−
48−```
49−> .^((unit @ud) %j /=lyfe=/(scot %p our))
50−[~ 1]
51−```
52−
53−## `%rift`
54−
55−A `%rift` scry gets the current `rift` (continuity number) of a ship if known, otherwise it crashes. It takes a ship as its `path` and the type returned is a `@ud`.
56−
57−#### Example
58−
59−```
60−.^(@ud %j /=rift=/(scot %p our))
61−1
62−```
63−
64−## `%ryft`
65−
66−A `%ryft` scry gets the current unitized `rift` (continuity number) of a ship if known, otherwise it returns `~`. It takes a ship as its `path` and the type returned is a `(unit @ud)`.
67−
68−#### Example
69−
70−```
71−> .^((unit @ud) %j /=ryft=/(scot %p our))
72−[~ 1]
73−```
74−
75−## `%vein`
76−
77−A `%vein` scry gets your ship's private key for the specified `life`. It takes a `life` `@ud` as its `path` and the type returned is a `ring`.
78−
79−#### Example
80−
81−```
82−> .^(@uw %j /=vein=/1)
83−0w84.0MwlQ.y2Ly9.6HVmH.8SYwo.EvuLC.f5YRw.T2NzD.EHtjZ.gpHZb.J0Pu5.aTGVL.UugSA.EZ~E9.~PODC.cohVD.B1zWj.ZWnJ2
84−```
85−
86−## `%vile`
87−
88−A `%vile` scry gets your `jam`mmed private boot parameters at your ship's current `life`. It takes no additional arguments in its `path`. The type returned is a `@` which is a `jam`med [$seed](/docs/arvo/jael/data-types#seed).
89−
90−#### Examples
91−
92−```
93−> .^(@ %j /=vile=)
94−73.825.716.773.695.891.582.219.653.213.376.682.408.892.852.624.025.387.720.465.884.094.267.975.202.807.896.467.150.282.384.122.104.470.678.155.055.914.950.319.747.613.107.324.566.157.366.237.078.063.363.527.599.682.750.233
95−```
96−
97−```
98−> ;;(seed:jael (cue .^(@ %j /=vile=)))
99−[ who=~zod
100− lyf=1
101− key
102− 1.729.646.917.183.337.262.068.568.133.450.460.269.618.308.934.734.494.661.340.450.478.360.301.077.532.415.587.141.242.844.893.269.500.211.196.916.184.768.225.437.577.083.064.475.012.067.992.317.942.521.494.338
103− sig=~
104−]
105−```
106−
107−## `%deed`
108−
109−A `%deed` scry gets the `life`, pubkey and maybe a signature if the ship in question is a comet. It takes the target ship and life as its `path` like `/~sampel-palnet/1` and the type returned is a `[life pass (unit @ux)]`.
110−
111−#### Example
112−
113−```
114−> .^([life pass (unit @ux)] %j /=deed=/(scot %p our)/1)
115−[ 1
116− 2.649.818.598.466.464.524.534.996.841.661.372.043.001.125.438.577.869.575.450.096.229.472.239.369.342.882.589.479.483.389.735.480.760.982.635.242.955.515.616.049.650.771.700.602.823.946.406.713.457.849.302.626
117− ~
118−]
119−```
120−
121−## `%earl`
122−
123−A `%earl` scry deterministically derives a private key for a moon. Note this is a holdover from an old version of moon infrastructure, the current `|moon` generator doesn't use this and instead generates moon private keys non-deterministically. It takes the moon name and your ship's current `life` (not the moon's `life`) as its `path` like `/~doznec-dozzod-dozzod-dozzod/1`. The type returned is a [$seed](/docs/arvo/jael/data-types#seed), the `life` of the moon in the `lyf` field of the `seed` will always be `1`.
124−
125−#### Example
126−
127−```
128−> .^(seed:jael %j /=earl=/~doznec-dozzod-dozzod-dozzod/1)
129−[ who=~doznec-dozzod-dozzod-dozzod
130− lyf=1
131− key
132− 1.055.418.877.440.612.330.077.014.834.463.499.863.663.523.990.336.436.220.536.921.445.512.367.957.276.250.223.724.881.932.188.751.226.308.505.496.234.256.625.462.295.144.257.529.749.880.805.247.600.674.018.370
133− sig=~
134−]
135−```
136−
137−## `%sein`
138−
139−A `%sein` scry gets the sponsor for the specified ship. This scry is used implicitly by `sein:title`. It takes the target ship as its `path` and the type returned is a `@p`.
140−
141−#### Example
142−
143−```
144−> .^(@p %j /=sein=/~sampel-palnet)
145−~talpur
146−```
147−
148−## `%saxo`
149−
150−A `%saxo` scry gets the sponsorship chain for the target ship (including the target ship itself). For example, a `%saxo` scry for a planet will return the planet, its star and the star's galaxy. This scry is used implicitly by `saxo:title`. It takes the target ship as its `path` and the type returned is a `(list @p)`.
151−
152−#### Example
153−
154−```
155−> .^((list @p) %j /=saxo=/~sampel-palnet)
156−~[~sampel-palnet ~talpur ~pur]
157−```
158−
159−## `%subscriptions`
160−
161−A `%subscriptions` scry gets the current state of subscriptions to public key updates (typically initiated with a [%public-keys task](/docs/arvo/jael/tasks#public-keys)). It takes a `life` as its `path` and returns a triple consisting of the following:
162−
163−```hoon
164−yen=(jug duct ship) :: trackers
165−ney=(jug ship duct) :: reverse trackers
166−nel=(set duct) :: trackers of all
167−```
168−
169−The `yen` `jug` maps subscribed `duct`s to the `ship`s they're tracking, and `ney` is just the inverse, mapping tracked `ship`s to subscribed `duct`s. The `nel` set contains `duct`s track all public key updates.
170−
171−#### Example
172−
173−```
174−.^([yen=(jug duct ship) ney=(jug ship duct) nel=(set duct)] %j /=subscriptions=/1)
175−[yen={} ney={} nel={}]
176−```
177−
178−## `%sources`
179−
180−A `%sources` scry gets the current state of Jael's sources for PKI updates. It takes no additional arguments in its `path` and returns a [$state-eth-node](/docs/arvo/jael/data-types#state-eth-node).
181−
182−#### Example
183−
184−```
185−> .^(state-eth-node:jael %j /=sources=)
186−[ top-source-id=0
187− sources={}
188− sources-reverse={}
189− default-source=0
190− ship-sources={}
191− ship-sources-reverse={}
192−]
193−```
194−
195−## `%turf`
196−
197−A `%turf` scry gets the list of domain prefixes for galaxies. It takes no additional arguments in its `path`. It returns a `(list turf)`, where a `turf` is a TLD-first `(list @t)`, so `urbit.org` as a `turf` is `~['org' 'urbit']`.
198−
199−#### Example
200−
201−```
202−> .^((list turf) %j /=turf=)
203−~[<|org urbit|>]
204−```
content/docs/arvo/jael/tasks.mddeleted−225
@@ -1,225 +0,0 @@
1−+++
2−title = "API Reference"
3−weight = 2
4−template = "doc.html"
5−+++
6−
7−This document details all the `task`s you may wish to send Jael, as well as the `gift`s you'll receive in response.
8−
9−You may also wish to reference the [Data Types](/docs/arvo/jael/data-types) document for details of the types referenced here, and the [Examples](/docs/arvo/jael/examples) document for practical examples of using these `task`s.
10−
11−## `%dawn`
12−
13−```hoon
14−[%dawn dawn-event]
15−```
16−
17−Boot from keys.
18−
19−This `task` is called once per ship during the vane initialization phase immediately following the beginning of the [adult stage](/docs/arvo/overview#structural-interface-core). This `task` is `%pass`ed to Jael by Dill, as Dill is the first vane to be loaded for technical reasons, though we consider Jael to be the true "first" vane. This `task` is only used for ships that will join the Ames network - fake ships (i.e. made with `./urbit -F zod`) use the [%fake](#fake) `task` instead.
20−
21−`%dawn` is used to perform a sequence of initialization tasks related to saving information about Azimuth and the Ames network and booting other vanes for the first time. Upon receipt of a `%dawn` `task`, Jael will:
22−
23−- record the Ethereum block the public key is registered to,
24−- record the URL of the Ethereum node used,
25−- save the signature of the parent planet (if the ship is a moon),
26−- load the initial public and private keys for the ship,
27−- set the DNS suffix(es) used by the network (currently just `urbit.org`),
28−- save the public keys of all galaxies,
29−- set Jael to subscribe to `%azimuth-tracker`,
30−- `%slip` a `%init` `task` to Ames, Clay, Gall, Dill, and Eyre, and `%give` an `%init`
31− `gift` to Arvo, which then informs Unix that the initialization process has concluded.
32−
33−This `task` takes a [$dawn-event](/docs/arvo/jael/data-types#dawn-event) as its argument.
34−
35−You would not use this `task` manually.
36−
37−#### Returns
38−
39−Jael `%give`s an `%init` `gift` to Unix. This occurs after the Dill `%slip` init.
40−
41−## `%fake`
42−
43−```hoon
44−[%fake =ship]
45−```
46−
47−Boot fake ship.
48−
49−This `task` is used instead of [%dawn](#dawn) when creating a fake ship via the `-F` flag when calling the Urbit binary. It performs a subset of the actions that `%dawn` performs, modified to accommodate the fake ship.
50−
51−`%fake` endows the ship with a private key and a public key deterministically derived from the ship's `@p`. It sets `fak.own.pki` to `%.y`, which is the bit that determines whether or not a ship is fake. Other parts of the Jael state, such as the sponsorship chain and galaxy public keys are left at their bunted values.
52−
53−The `ship` field specifies the `@p` of the fake ship being created.
54−
55−You would not use this `task` manually.
56−
57−#### Returns
58−
59−Jael `%give`s a `%init` `gift` to Unix.
60−
61−## `%listen`
62−
63−```hoon
64−[%listen whos=(set ship) =source]
65−```
66−
67−Set Ethereum source.
68−
69−Sets the source that the public keys for a set of `ship`s should be obtained from. This can either be a Gall app that communicates with an Ethereum node such as `%azimuth-tracker`, as in the case of galaxies, stars, and planets, or a ship, as in the case of moons.
70−
71−`whos` is the set of ships whose key data source is to be monitored. The [$source](/docs/arvo/jael/data-types#source) is either a ship or the name of a Gall app to use as a source. A `%listen` `task` with empty `whos` will set the default source. When the `source` is a ship, Jael will obtain public keys for ships in `(set ship)` from the given ship. By default, the `source` for a moon will be the planet that spawned that moon.
72−
73−You are unlikely to use this `task` manually.
74−
75−#### Returns
76−
77−Jael will not return any `gift`s in response to a `%listen` `task`.
78−
79−## `%meet`
80−
81−```hoon
82−[%meet =ship =life =pass]
83−```
84−
85−This `task` is deprecated and does not perform any actions.
86−
87−## `%moon`
88−
89−```hoon
90−[%moon =ship =udiff:point]
91−```
92−
93−Register moon keys or otherwise administer a moon.
94−
95−This is what is sent to Jael by `%hood` behind the scenes when you run `|moon`, `|moon-breach` or `|moon-cycle-keys`. The `ship` field is the moon's `@p`. The [$udiff:point](/docs/arvo/jael/data-types#udiffpoint) will contain the bunt of an [$id:block](/docs/arvo/jael/data-types#idblock) (since moons aren't registered in Azimuth) and one of the `udiff` actions depending on what you want to do.
96−
97−#### Returns
98−
99−Jael does not return any `gift`s in response to a `%moon` `task`.
100−
101−## `%nuke`
102−
103−```hoon
104−[%nuke whos=(set ship)]
105−```
106−
107−Cancel subscription to public or private key updates.
108−
109−If you've subscribed to public or private key updates from Jael with a [%private-keys](#private-keys) or [%public-keys](#public-keys) `task`, you can unsubscribe and stop receiving updates with a `%nuke` `task`. The `(set ship)` is the `set` of `ship`s which you want to stop tracking. Jael organises subscriptions based on `duct`s, and will determine which subscription to cancel implicitly based on the `duct` the `%nuke` `task` came from. This means a `%nuke` `task` only works from the same thread or agent and on the same `path` as the original subscription request.
110−
111−To cancel a subscription to the ship's private keys you must leave `whos` empty like `[%nuke ~]`.
112−
113−#### Returns
114−
115−Jael does not return a `gift` in response to a `%nuke` `task`.
116−
117−#### Examples
118−
119−See the [%public-keys and %nuke](/docs/arvo/jael/examples#public-keys-and-nuke) section of the Examples document for an example of using `%nuke` to cancel a `%public-keys` subscription. See the thread in the [%private-keys](/docs/arvo/jael/examples#private-keys) example for cancelling a `%private-keys` subscription.
120−
121−## `%private-keys`
122−
123−```hoon
124−[%private-keys ~]
125−```
126−
127−Subscribe to private key updates.
128−
129−Subscribe to be notified of private key updates for the local ship. The subscription will continue until Jael receives a [%nuke](#nuke) `task` to cancel it.
130−
131−#### Returns
132−
133−Jael responds to a `%private-keys` `task` with a `%private-keys` `gift` which looks like:
134−
135−```hoon
136−[%private-keys =life vein=(map life ring)]
137−```
138−
139−The `life` is the current life of the ship and the `vein` `map` contains the private key for each life up to (and including) the current one. Upon first subscribing, Jael will immediately respond with a `%private-keys` `gift`. Then, whenever the ship's private keys are changed, it'll send a new and updated `%private-keys` `gift`.
140−
141−#### Example
142−
143−See the [%private-keys](/docs/arvo/jael/examples#private-keys) section of the Examples document for a practical example.
144−
145−## `%public-keys`
146−
147−```hoon
148−[%public-keys ships=(set ship)]
149−```
150−
151−Subscribe to public key (and related) updates from Jael.
152−
153−An agent or thread can subscribe to be notified of public key updates, sponsorship changes and continuity breaches for the `set` of `ship`s specified in the `ships` field. The subscription will continue until Jael receives a [%nuke](#nuke) `task` to cancel it.
154−
155−#### Returns
156−
157−Jael responds to a `%public-keys` `task` with `%public-keys` `gift`s which look like:
158−
159−```hoon
160−[%public-keys =public-keys-result]
161−```
162−
163−The [$public-keys-result](/docs/arvo/jael/data-types#public-keys-result) contains whatever changes have occurred.
164−
165−Upon subscription, Jael will immeditely respond with a `%public-keys` `gift` containing a `%full` `public-keys-result` with the public key for each `life` up until the current one for each `ship` specified in the original `task`. After than, Jael will send a `%public-keys` `gift` with either a `%diff` or `%breach` `public-keys-result` each time a change occurs for any of the `ship`s to which you're subscribed.
166−
167−#### Example
168−
169−See the [%public-keys and %nuke](/docs/arvo/jael/examples#public-keys-and-nuke) section of the Examples document for a practical example.
170−
171−## `%rekey`
172−
173−```hoon
174−[%rekey =life =ring]
175−```
176−
177−Update private keys.
178−
179−This is what is sent to Jael by `%hood` when you run `|rekey`, as you must after setting new Azimuth keys or running `|cycle-moon-keys` on a moon's parent. It will update your `life` (key revision number) and private keys. The `life` field is the new `life` (typically an increment of the current `life`) and the `ring` is a private key `@`.
180−
181−#### Returns
182−
183−Jael does not return any `gift` in response to a `%rekey` `task`.
184−
185−## `%turf`
186−
187−```hoon
188−[%turf ~]
189−```
190−
191−View domains.
192−
193−The domains returned by a `%turf` `task` are used as the base for individual galaxy domain names (e.g. from `urbit.org` you get `zod.urbit.org`, `bus.urbit.org`, etc). Jael gets these from Azimuth, then Ames gets them from Jael and passes them to the runtime, which will perform the DNS lookups and give Ames back the galaxy IP addresses. A `%turf` task takes no additional arguments. You're unlikely to use this manually - if you want the current `turf`s you'd likely want to do a [turf scry](/docs/arvo/jael/scry#turf) instead.
194−
195−#### Returns
196−
197−Jael will respond to a `%turf` `task` with a `%turf` `gift`, which looks like:
198−
199−```hoon
200−[%turf turf=(list turf)]
201−```
202−
203−The `turf` in the `(list turf)` is a domain as a `(list @t)`, TLD-first. The current default is `[['org' 'urbit' ~] ~]`.
204−
205−#### Example
206−
207−See the [%turf section of the Examples document](/docs/arvo/jael/examples#turf) for a practical example.
208−
209−## `%step`
210−
211−```hoon
212−[%step ~]
213−```
214−
215−Reset web login code.
216−
217−Jael maintains a `step` value that represents the web login code revision number, and uses it to derive the code itself. It begins at `0` and is incremented each time the code is changed. When Jael updates the web login code, it sends Eyre a `%code-changed` `task:eyre` so that Eyre can throw away all of its current cookies and sessions. A `%step` task takes no additional argument.
218−
219−#### Returns
220−
221−Jael does not return a `gift` in response to a `%step` `task`.
222−
223−#### Example
224−
225−See the [%step](/docs/arvo/jael/examples#step) section of the Examples document for a practical example.
content/docs/arvo/overview.mddeleted−552
@@ -1,552 +0,0 @@
1−+++
2−title = "Overview"
3−weight = 1
4−aliases = ["/docs/learn/arvo/arvo/"]
5−template = "doc.html"
6−+++
7−
8−Arvo, also called Urbit OS, is our operating system.
9−
10−# Introduction
11−
12−This article is intended to provide a thorough summary of all of the most
13−important aspects of the Arvo kernel and how this functionality gives life to
14−the ambitions of the Urbit platform. We work on two levels: a conceptual level
15−that should be useful to anybody interested in how Arvo works, and a more
16−technical level intended for those that intend to write software for Urbit.
17−
18−The [Urbit white paper](https://media.urbit.org/whitepaper.pdf) is a good
19−companion to this document, and some segments are direct quotes or paraphrases, but it should be noted that some parts of it are now either out of date or not yet implemented.
20−
21−## Prerequisites
22−
23−The conceptual section titled [What is Arvo?](#what-is-arvo) can be understood
24−without knowing Hoon, the Urbit programming language. The technical section
25−titled [The kernel](#the-kernel) will require Chapter One of the [Hoon
26−tutorial](/docs/hoon/hoon-school/) for full understanding, and some
27−material from Chapter Two will be helpful as well. At the bare minimum, we
28−presume that the reader has read through the [Technical
29−Overview](/docs/system-overview/).
30−
31−We also suggest to the reader to peruse the [glossary](/docs/glossary/) before diving into this article. It will provide the initial scaffolding that you will be able to gradually fill in as you read this article and go deeper into the alternate universe of computing that is Urbit.
32−
33−# What is Arvo?
34−
35−Arvo is a [non-preemptive](#non-preemptive)
36−operating system purposefully built to create a new, peer-to-peer internet
37−whereby users own and manage their own data. Despite being an operating system,
38−Arvo does not replace Windows, Mac OS, or Linux. It is better to think of the
39−user experience of Arvo as being closer to that of a web browser despite being a
40−fully fledged OS. As such, Arvo is generally run inside a virtual machine, though in theory it could be run on bare metal.
41−
42−Urbit is a “browser for the server side”; it replaces multiple developer-hosted web services on multiple foreign servers, with multiple self-hosted applications on one personal server. Every architectural decision for Arvo (and indeed, the entire Urbit stack) was made with this singular goal in mind. Throughout this document, we connect the various concepts underlying Arvo with this overarching goal.
43−
44−Arvo is designed to avoid the usual state of complex event networks: event spaghetti. We keep track of every event's cause so that we have a clear causal chain for every computation. At the bottom of every chain is a Unix I/O event, such as a network request, terminal input, file sync, or timer event. We push every step in the path the request takes onto the chain until we get to the terminal cause of the computation. Then we use this causal stack to route results back to the caller.
45−
46−Unlike any other popular operating system, it is possible for a single human to understand every aspect of Arvo due to its compact size. The entire Urbit stack is around 30,000 lines of code, while the Arvo kernel is only about 1,000 lines of code. We strive for a small codebase because the difficulty in administering a system is roughly proportional to the size of its code base.
47−
48−## An operating function {% #operating-function %}
49−
50−Arvo is the world's first _purely functional_ operating system, and as such it may reasonably be called an _operating function_. The importance of understanding this design choice and its relevance to the overarching goal cannot be understated. If you knew only a single thing about Arvo, let it be this.
51−
52−This means two things: one is that the there is a notion of _state_ for the operating system, and that the current state is a pure function of the [event log](#event-log), which is a chronological record of every action the operating system has ever performed. A _pure function_ is a function that always produces the same output given the same input. Another way to put this is to say that Arvo is _deterministic_. Other operating systems are not deterministic for a number of reasons, but one simple reasons is because they allow programs to alter global variables that then affect the operation of other programs.
53−
54−In mathematical terms, one may think of Arvo as being given by a transition function _T_:
55−
56−```
57−T: (State, Input) -> (State, Output).
58−```
59−
60−In practice, _T_ is implemented by the `+poke` [arm](/docs/glossary/arm/) of the Arvo kernel, which is described in more detail in the [kernel section](#the-kernel). In theoretical terms, it may be more practical to think of Arvo as being defined by a _lifecycle function_ we denote here by _L_:
61−
62−```
63−L: History -> State.
64−```
65−
66−Which perspective is more fruitful depends on the problem being considered.
67−
68−### Determinism
69−
70−We consider Arvo to be deterministic at a high level. By that we mean that it is
71−stacked on top of a frozen instruction set known as Nock. Frozen instruction
72−sets are a new idea for an operating system, but not for computing in general.
73−For instance, the CPU instruction sets such as
74−[x86-64](https://en.wikipedia.org/wiki/X86-64v) are frozen at the level of the
75−chip. A given operating system may be adapted to run on more than one CPU
76−instruction set, we merely freeze the instruction set at a higher level in order
77−to enable deterministic computation.
78−
79−Arvo handles nondeterminism in an interesting way. Deciding whether or not to
80−halt a computation that could potentially last forever becomes a heuristic
81−decision that is akin to dropping a packet. Thus it behooves one to think of
82−Arvo as being a stateful packet transceiver rather than an ordinary computer - events
83−are never guaranteed to complete, even if one can prove that the computation
84−would eventually terminate. We elaborate on this in the [solid state
85−interpreter](#solid-state-intrepeter) section.
86−
87−Because Arvo is run on a VM, nondeterministic information such as the stack
88−trace of an infinite loop that was entered into may be obtained. This is
89−possible because while Arvo may be unable to obtain that information, the
90−interpreter beneath does and can inject that information back into the event log.
91−
92−Being deterministic at a high level enables many
93−things that are out of reach of any other operating system. For
94−instance, we are able to do [over-the-air](#over-the-air-updates) (OTA) updates,
95−which allows software updates to be implemented across the network without
96−needing to worry whether it won't work on someone's ship, since Arvo is an
97−[interpreter](#solid-state-intrepeter) that can accept source code to
98−update itself instead of requiring a pre-compiled binary. This essential
99−property is why Urbit is able to act as a personal server while having
100−a user experience as accessible as a browser.
101−
102−### Event log
103−
104−The formal state of an Arvo instance is an event history, as a linked list of [nouns](/docs/glossary/noun/) from first to last. The history starts with a bootstrap sequence that delivers Arvo itself, first as an inscrutable kernel, then as the self-compiling source for that kernel. After booting, we break symmetry by delivering identity and entropy. The rest of the log is actual input.
105−
106−The Arvo event log is a list of every action ever performed on your ship that
107−lead up to the current state. In principle, this event log is maintained by the
108−[Nock runtime environment](/docs/vere/), but in practice
109−event logs become too long over time to keep, as the event log has a size of
110−O(n) where n is the number of events. Thus it is our intention to
111−implement a feature whereby periodic snapshots of the state of Arvo are taken
112−and the log up to that state is pruned. This is currently unnecessary and thus
113−this feature has not been prioritized.
114−
115−The beginning of the event log starting from the very first time a ship is
116−booted up until the kernel is compiled and identity and entropy are created is a
117−special portion of the Arvo lifecycle known as the _larval stage_. We describe
118−the larval stage in more detail in the [larval stage](#larval-stage-core) section.
119−
120−More information on the structure of the Arvo event log and the Arvo state is given in the section on [the kernel](#the-kernel).
121−
122−## Solid state interpreter
123−
124−Arvo is a _solid state interpreter_. In this section we describe what is meant
125−by this new term, and how this behavior derives from the fact that Arvo is an [ACID database](#acid-database) and a [single-level store](#single-level-store).
126−
127−In computer science, an _interpreter_ is a program that directly executes
128−instructions written in some human-understandable programming or scripting
129−language, rather than requiring the code to first be compiled into a machine
130−language. Arvo is an interpreter, which is important for us since it allows us
131−to perform deterministic [over-the-air updates](#over-the-air-updates) by the
132−direct transfer of raw source code.
133−
134−To understand what we mean by _solid state_ interpreter, consider the operation of a solid state hard drive when a computer shuts down or loses power. Data written to an SSD is permanent unless otherwise deleted - loss of power may leave some partially written data, but nothing is ever lost. Thus, the state of an SDD can be considered to be equivalent to the data that it contains. That is to say, you do not need to know anything about the system which is utilizing the SSD to know everything there is to know about the SSD. There is no notion of "rebooting" a SSD - it simply stores data, and when power is restored to it, it is in exactly the same state as it was when power was lost.
135−
136−Contrast this with other popular operating systems, such as Windows, Mac, or Linux. The state of the operating system is something that crucially depends on having a constant power supply because much of the state of the operating system is stored in RAM, which is volatile. When you reboot your computer or suddenly lose power, any information stored in RAM is lost. Modern operating systems do mitigate this loss of information to some extent. For instance, it may remember what applications you were running at the time power was lost and try to restore them. Particularly durable programs may go as far as writing their state to disk every few seconds so that only very minimal information can be lost in a power outage. However, this is not the default behavior, and indeed if it were then they would be so slow as to be unusable, as you would effectively be using your hard disk as the RAM.
137−
138−How Arvo handles loss of power is closer to that of an SSD. Since it is an [ACID database](#acid-database) and a [single-level store](#single-level-store), a sudden loss of power have no effect on the state of the operating system. When you boot your ship back up it will be exactly as it was before the failure. Your information can never be lost, and because it was designed from the ground up to behave in this fashion, it does not suffer significant slowdown by persisting all data in this manner as would be the case if your typical operating system utilized its hard disk as RAM.
139−
140−Another way to describe a solid state interpreter is to think of it as a
141−stateful packet transceiver. Imagine
142−it as a chip. Plug this chip into power and network; packets go in and
143−out, sometimes changing its state. The chip never loses data and has
144−no concept of a reboot; every packet is an [ACID transaction](#acid-database).
145−
146−### Over-the-air updates
147−
148−Arvo can hotpatch any other semantics at any layer in the system (apps, vanes, Arvo or Hoon itself) with automatic over-the-air updates.
149−
150−Typically, updates to an operating system are given via a pre-compiled binary,
151−which is why some updates will work on some systems but not on others where the
152−hardware and environment may differ. This is not so on Arvo - because it is an
153−[interpreter](#solid-state-interpreter), Arvo may update itself by receiving
154−source code from your sponsor over [Ames](/docs/arvo/ames/ames), our
155−network. As Hoon compiles down to Nock, which is an axiomatic representation of
156−a deterministic computer, this code is guaranteed to run identically on your machine as it
157−would on anybody else's.
158−
159−Some subtleties regarding types arise when handling OTA updates, since they can
160−potentially alter the type system. Put more concretely, the type of `type` may
161−be updated. In that case, the update is an untyped Nock formula from the
162−perspective of the old kernel, but ordinary typed Hoon code from the perspective of
163−the new kernel. Besides this one detail, the only functionality of the Arvo
164−kernel proper that is untyped are its interactions with the Unix runtime.
165−
166−### ACID Database
167−
168−In the client-server model, data is stored on the server and thus reliable and efficient databases are an integral part of server architecture. This is not quite so true for the client - a user may be expected to reboot their machine in the middle of a computation, alter or destroy their data, never make backups or perform version control, etc. In other words, client systems like your personal computer or smart phone are not well suited to act as databases.
169−
170−In order to dismantle the client-server model and build a peer-to-peer internet, we need the robustness of modern database servers in the hands of the users. Thus the Arvo operating system itself must have all of the properties of a reliable database.
171−
172−Database theory studies in precise terms the possible properties of anything that could be considered to be a database. In this context, Arvo has the properties of an [ACID database](https://en.wikipedia.org/wiki/ACID), and the Ames network could be thought of as network of such databases. ACID stands for _atomicity_, _consistency_, _isolation_, and _durability_. We review here how Arvo satisfies these properties.
173−
174−- Atomicity: Events in Arvo are _atomic_, meaning that they either succeed completely or fail completely. In other words, there are no transient periods in which something like a power failure will leave the operating system in an invalid state. When an event occurs in Arvo, e.g. [the kernel](#the-kernel) is `poke`d, the effects of an event are computed, the event is [persisted](<https://en.wikipedia.org/wiki/Persistence_(computer_science)>) by writing it to the event log, and only then are the actual effects applied.
175−
176−- Consistency: Every possible update to the database puts it into another valid state. Given that Arvo is purely functional, this is easier to accomplish than it would be in an imperative setting.
177−
178−- Isolation: Transactions in databases often happen concurrently, and isolation
179− ensures that the transactions occur as if they were performed sequentially,
180− making it so that their effects are isolated from one another. Arvo ensures
181− this simply by the fact that it only ever performs events sequentially. While
182− Arvo
183− transactions are sequential and performed by the daemon, persistence and effect application are performed
184− in parallel by the worker; see [worker and
185− daemon](/docs/vere/) for more detail.
186−
187−- Durability: Completed transactions will survive permanently. In other words,
188− since the event log is stored on disk, if power is lost you are guaranteed
189− that no transactions will be reversed.
190−
191−It is easy to think that "completed transaction will survive permanently"
192−along with "the state of Arvo is pure function of its event log" implies that
193−nothing can ever be deleted. This is not quite true.
194−[Clay](/docs/arvo/clay/clay) is our [referentially
195−transparency](https://en.wikipedia.org/wiki/Referential_transparency)
196−file system, which could naively be thought to mean that since data must be
197−immutable, files cannot be deleted. However, Clay can replace a file with a
198−"tombstone" that causes Clay to crash whenever it is accessed. Referential
199−transparency only guarantees that there won't be new data at a previously
200−accessed location - not that it will still be available.
201−
202−### Single-level store
203−
204−A kernel which presents the abstraction of a single layer of permanent state is also called a _single-level store_. One way to describe a single-level store is that it never reboots; a formal model of the system does not contain an operation which unpredictably erases half its brain.
205−
206−Today's operating systems utilize at least two types of memory: the hard disk and the RAM, and this split is responsible for the fact that data is lost whenever power is lost. Not every operating system in history was designed this way - in particular, [Multics](https://en.wikipedia.org/wiki/Multics) utilized only one store of memory. Arvo takes after Multics - all data is stored in one permanent location, and as a result no data is ever lost when power is lost.
207−
208−### Non-preemptive
209−
210−Most operating systems are preemptive, meaning that they regularly interrupt
211−tasks being performed with the intention of resuming that task at a later time,
212−without the task explicitly yielding control.
213−Arvo does not do this - tasks run until they are complete or are cancelled due
214−to some heuristic, such as taking too long or because the user pressed Ctrl-C.
215−This is known as
216−[non-preemptive](https://en.wikipedia.org/wiki/Cooperative_multitasking) or
217−cooperative multitasking.
218−
219−> Parts of the remainder of this document are out of date as of 2020.07.20, please use information here with
220−> caution. This message will be removed once it is up to date.
221−
222−# The kernel
223−
224−The Arvo kernel, stored in `sys/arvo.hoon`, is about 1k lines of Hoon whose primary purpose is to implement the transition function, `+poke`. In this section we point out the most important parts of `arvo.hoon` and describe their role in the greater system. We also give brief descriptions of Arvo's kernel modules, known as vanes, and how Arvo interfaces with them.
225−
226−This section requires an understanding of Hoon of at least the level of Chapter One of the [Hoon tutorial](/docs/hoon/hoon-school/).
227−
228−After concluding this section, the reader is encouraged to follow along with the
229−[move trace tutorial](/docs/arvo/tutorials/move-trace),
230−which applies many of the concepts covered below.
231−
232−## Overall structure
233−
234−`arvo.hoon` contains five top level cores as well as a "formal interface" consisting of a single [gate](/docs/glossary/gate/) that implements the transition function. They are nested with the `=<` and `=>` runes like so, where items lower on the list are contained within items higher on the list:
235−
236−- Types
237−- Section 3bE Arvo Core
238−- Implementation core
239−- Structural interface core, or adult core
240−- Larval stage core
241−- Formal interface
242−
243−See [Section 1.7](/docs/hoon/hoon-school/arms-and-cores) of the Hoon tutorial for further explanation of what is meant here by "nesting". We now describe the functionality of each of these components.
244−
245−### Formal interface
246−
247−The formal interface is a single gate that takes in the current time and a noun that encodes the input. This input, referred to as an _event_, is then put into action by the `+poke` arm, and a new noun denoting the current [state of Arvo](#the-state) is returned. In reality, you cannot feed the gate just any noun - it will end up being an `ovum` described below - but as this is the outermost interface of the kernel the types defined in the type core are not visible to the formal interface.
248−
249−```hoon
250− :: Arvo formal interface
251− ::
252− :: this lifecycle wrapper makes the arvo door (multi-armed core)
253− :: look like a gate (function or single-armed core), to fit
254− :: urbit's formal lifecycle function. a practical interpreter
255− :: can ignore it.
256− ::
257− |= [now=@da ovo=*]
258− ^- *
259− ~> %slog.[0 leaf+"arvo-event"]
260− .(+> +:(poke now ovo))
261−```
262−
263−### Types
264−
265−This core contains the most basic types utilized in Arvo. We discuss a number of them here.
266−
267−#### `+duct`
268−
269−```hoon
270−++ duct (list wire) :: causal history
271−```
272−
273−Arvo is designed to avoid the usual state of complex event networks: event
274−spaghetti. We keep track of every event's cause so that we have a clear causal
275−chain for every computation. At the bottom of every chain is a Unix I/O event,
276−such as a network request, terminal input, file sync, or timer event. We push
277−every step in the path the request takes onto the chain until we get to the
278−terminal cause of the computation. Then we use this causal stack to route
279−results back to the caller.
280−
281−The Arvo causal stack is called a `duct`. This is represented simply as a list of paths, where each path represents a step in the causal chain. The first element in the path is the first letter of whichever vane handled that step in the computation, or the empty span for Unix.
282−
283−Here's a `duct` that was recently observed in the wild upon entering `-time ~s1`
284−into the dojo and pressing Enter, which sets a timer for one second that will
285−then produce a `@d` with the current time after the timer has elapsed:
286−
287−```
288−~[
289− /g/a/~zod/4_shell_terminal/u/time
290− /g/a/~zod/shell_terminal/u/child/4/main
291− /g/a/~zod/terminal/u/txt
292− /d/term-mess
293− //term/1
294−]
295−```
296−
297−This is the `duct` that the timer vane, Behn, receives when the `time` sample app asks the Behn to set a timer. This is also the `duct` over which the response is produced at the specified time. Unix sent a terminal keystroke event (enter), and Arvo routed it to Dill (our terminal), which passed it on to the Gall app terminal, which sent it to shell, its child, which created a new child (with process id 4), which on startup asked Behn to set a timer.
298−
299−Behn saves this `duct`, so that when the specified time arrives and Unix sends a
300−wakeup event to the timer vane, it can produce the response on the same `duct`.
301−This response is routed to the place we popped off the top of the `duct`, i.e. the
302−time app. This app returns a `@d` which denotes the current time, which falls down to the shell,
303−which drops it through to the terminal. Terminal drops this down to Dill, which
304−converts it into an effect that Unix will recognize as a request to print the
305−current time to the screen. When Dill produces this, the last path in the `duct` has an
306−initial element of the empty span, so this is routed to Unix, which applies the effects.
307−
308−This is a call stack, with a crucial feature: the stack is a first-class citizen. You can respond over a `duct` zero, one, or many times. You can save `duct`s for later use. There are definitely parallels to Scheme-style continuations, but simpler and with more structure.
309−
310−#### `wire`
311−
312−```hoon
313−++ wire path :: event pretext
314−```
315−
316−Synonym for `path`, used in `duct`s. These should be thought of as a list of symbols
317−representing a cause.
318−
319−#### `move`
320−
321−```hoon
322−++ move [p=duct q=arvo] :: arvo move
323−```
324−
325−If `duct`s are a call stack, then how do we make calls and produce results? Arvo
326−processes `move`s which are a combination of message data and metadata. There
327−are four types of `move`s: `%pass`, `%give`, `%slip`, and `%unix`.
328−
329−A `%pass` `move` is analogous to a call:
330−
331−```
332−[duct %pass return-path=path vane-name=@tD data=card]
333−```
334−
335−Arvo pushes the return path (preceded by the first letter of the vane name) onto
336−the `duct` and sends the given data, a `card`, to the vane we specified. Any response will come along the same `duct` with the `wire` `return-path`.
337−
338−A `%give` `move` is analogous to a return:
339−
340−```
341−[duct %give data=card]
342−```
343−
344−Arvo pops the top `wire` off the `duct` and sends the given `card` back to the caller.
345−
346−A `%slip` `move` is a cousin of `%pass`. Any `card` that can be `%pass`ed can also be
347−`%slip`ed, but while a `%pass` says to "push this `wire` onto the `duct` and
348−transfer control to the receiving vane", a `%slip` transfers control to the
349−receiving vane without altering the `duct`. Therefore, a `%give` in response to
350−a `%slip` will go to the caller of the vane that sent the `%slip` rather than
351−the vane that actually sent the `%slip`. `%slip`s are much more rare than
352−`%pass`es and `%give`s. In general, `%slip` and `%pass` `move`s are
353−both referred to as "passes" and it should be clear from the context if one
354−means to refer only to `%pass`es and not `%slip`s or vice versa. Lastly, we note
355−that `%slip` is a code smell and should nearly always be avoided. It can result
356−in unexpected behavior like receiving a gift from a vane you never passed a note to.
357−
358−Lastly, a `%unix` `move` is how Arvo represents communication from Unix, such as a
359−network request or terminal input.
360−
361−#### `card`s and `curd`s
362−
363−`card`s are the vane-specific portion of a `move`, while `curd`s are typeless
364−`card`s utilized at the level of the kernel. `card`s are not actually defined in
365−`arvo.hoon`, rather they are given by `+note-arvo` and `+sign-arvo` in the
366−standard library `zuse`
367−(which then refer to `+task` and `+gift` in each of the vane cores), but they are closely
368−connected to `curd`s so we speak of them in the same breath.
369−
370−Each vane defines a protocol for interacting with other vanes (via Arvo) by defining four types of `card`s: `task`s, `gift`s, `note`s, and `sign`s.
371−
372−When one vane is `%pass`ed a `card` in its `task` (defined in `zuse`), Arvo activates the `+call` gate with the `card` as its argument. To produce a result, the vane `%give`s one of the `card`s defined in its `gift`. If the vane needs to request something of another vane, it `%pass`es it a `note` `card`. When that other vane returns a result, Arvo activates the `+take` gate of the initial vane with one of the `card`s defined in its `sign`.
373−
374−In other words, there are only four ways of seeing a `move`: (1) as a request seen by the caller, which is a `note`. (2) that same request as seen by the callee, a `task`. (3) the response to that first request as seen by the callee, a `gift`. (4) the response to the first request as seen by the caller, a `sign`.
375−
376−When a `task` `card` is `%pass`ed to a vane, Arvo calls its `+call` gate,
377−passing it both the `card` and its `duct`. This gate must be defined in every vane.
378−It produces two things in the following order: a list of `move`s and a possibly
379−modified copy of its context. The `move`s are used to interact with other vanes,
380−while the new context allows the vane to save its state. The next time Arvo
381−activates the vane it will have this context as its subject.
382−
383−This cycle of `%pass`ing a `note` to `%pass`ing a `task` to `%give`ing a `gift`
384−to `%give`ing a `%sign` is summarized in the following diagram:
385−
386−![](https://media.urbit.org/docs/arvo/cycle.png)
387−
388−Note that `%pass`ing a `note` doesn't _always_ result in a return - this diagram
389−just
390−shows the complete cycle. However, `%give`ing a `gift` is always in response to being
391−`%pass`ed some `task`. Since the Arvo kernel acts as a middleman between all `move`s in Arvo, in diagrams we will
392−generally represent the intermediate steps of a vane `%pass`ing a `note` to the kernel addressed to
393−another vane followed by the kernel `%pass`ing a `task` to the
394−addressed vane as a single arrow from one vane to the other to make the diagrams
395−less cluttered.
396−
397−This overview has detailed how to pass a `card` to a particular vane. To see the `card`s each vane can be `%pass`ed as a `task` or return as a `gift` (as well as the semantics tied to them), each vane's public interface is explained in detail in its respective overview.
398−
399−#### `ovum`
400−
401−This mold is used to represent both steps and actions.
402−
403−A pair of a `wire` and a `curd`, with a `curd` being like a typeless `card`. The
404−reason for a typeless `card` is that this is the data structure which Arvo uses
405−to communicate with the runtime, and Unix events have no type. Additionally,
406−upgrading the kernel may alter the type system and thus may not be able to be
407−described within the current type system. Then the `wire` here is the default Unix `wire`, namely `//`. In particular, it is not a `duct` because `ovum`s come from the runtime rather than from within Arvo.
408−
409−### Arvo cores
410−
411−`arvo.hoon` has four additional cores that encode the functionality of Arvo. The [larval core](#larval-stage-core), [structural interface core](#structural-interface-core), and [implementation core](#implementation-core) each have five arms, called `+come`, `+load`, `+peek`, `+poke`, and `+wish`. Of these five arms, only `+poke` affects the [Arvo state](#the-state), while the rest leave the state invariant. Thus `+poke` is the aforementioned transition function that sends Arvo from one state to the next.
412−
413−A short summary of the purpose of each these arms are as follows:
414−
415−- `+poke` is the transition function that `move`s Arvo from one state to the
416− next. It is the most fundamental arm in the entire system. It is a typed
417− transactional message that is processed at most once. If the `+poke` causes
418− Arvo to send an message over [Ames](/docs/arvo/ames/ames) Ames
419− guarantees that the message will be delivered exactly once. This is sometimes said
420− to be impossible, and it is for standard operating systems, but that is not the case for single-level stores engaged in
421− a permanent session, as is the case among Arvo ships.
422−- `+peek` is an arm used for inspecting things outside of the kernel. It grants
423− read-only access to `scry` Arvo's global referentially transparent namespace.
424− It takes in a `path` and returns a `unit (unit)`. If the product is `~`, the
425− path is unknown and its value cannot be produced synchronously. If its
426− product is `[~ ~]` the `path` is known to be unbound and can never become
427− bound. Otherwise the product is a `mark` and a noun.
428−- `+wish` is a function that takes in a core and then parses and compiles it
429− with the standard library, `zuse`. It is useful from the outside if you ever
430− want to run code within. One particular way in which it is used is by the
431− runtime to read out the version of `zuse` so that it knows if it is
432− compatible with this particular version of the kernel.
433−- `+load` is used when upgrading the kernel. It is only ever called by Arvo
434− itself, never by the runtime. If upgrading to a kernel where types are
435− compatible, `+load` is used, otherwise `+come` is used.
436−- `+come` is used when the new kernel has incompatible types, but ultimately
437− reduces to a series of `+load` calls.
438−
439−The [Section 3bE core](#section-3be-core) does not follow this pattern.
440−
441−#### Section 3bE core
442−
443−This core defines helper functions that are called in the larval and adult cores. These helper functions are placed here for safety so that they do not have access to the entire [state of Arvo](#the-state), which is contained in the structural interface core. One reason this core is required is that the Arvo interface has only five arms and additional arms are required to perform everything the kernel needs to do in a clean manner, so they must be segregated from the other three cores that stick to the five-arm paradigm.
444−
445−#### Implementation core
446−
447−This core is where the real legwork of the Arvo kernel is performed during the adult stage. It does not communicate with Unix directly, rather it is called by the structural interface core.
448−
449−#### Structural interface core
450−
451−This core could be thought of as the primary "adult core" - the one that is in operation for the majority of its lifecycle and the one that contains the [Arvo state](#the-state). This core should be thought of as an interface - that is, the amount of work the code does here is minimal as its main purpose is to be the core that communicates with Unix, and Unix should not be able to access deeper functions stored in the implementation core and 3bE core on its own. Thus, arms in this core are there primarily to call arms in the implementation core and 3bE core.
452−
453−#### Larval stage core
454−
455−This core is in use only during the larval stage of Arvo, which is after the Arvo kernel has compiled itself but before it has "broken symmetry" by acquiring identity and entropy, the point at which the larval stage has concluded. We call this breaking symmetry because prior to this point, every Urbit is completely identical. The larval stage performs the following steps in order:
456−
457−- The standard library, `zuse`, is installed.
458−- Entropy is added
459−- Identity is added
460−- Metamorph into the next stage of Arvo
461−
462−Once the larval stage has passed its functionality will never be used again.
463−
464−## The state
465−
466−As we follow functional programming paradigms, the state of Arvo is considered
467−to be the entire Arvo kernel core currently in operation (whether it be the larval
468−stage or adult stage). Thus when `+poke` is performed, a new core with the
469−updated state is produced, rather than modifying the existing core as would be
470−expected to happen in an imperative setting.
471−
472−Thus besides the battery of the Arvo core, we have the [payload](/docs/glossary/payload/) which is as
473−follows.
474−
475−```hoon
476−:: persistent arvo state
477−::
478−=/ pit=vase !>(..is) ::
479−=/ vil=vile (viol p.pit) :: cached reflexives
480−=| $: lac=_& :: laconic bit
481− eny=@ :: entropy
482− our=ship :: identity
483− bud=vase :: %zuse
484− vanes=(list [label=@tas =vane]) :: modules
485− == ::
486−```
487−
488−Let's investigate the state piece by piece.
489−
490−```hoon
491−=/ pit=vase !>(..is) ::
492−```
493−
494−This `vase` is part of the state but does not get directly migrated when `+poke`
495−is called. `!>(..is)` consists of the code in `arvo.hoon` written above this core contained in
496−a `vase`. Thus this part of the state changes only when that code changes in an
497−update.
498−
499−```hoon
500−=/ vil=vile (viol p.pit) :: cached reflexives
501−
502−```
503−
504−This is a cache of specific types that are of fundamental importance to Arvo -
505−namely `type`s, `duct`s, `path`s, and `vase`s. This is kept because it is
506−unnecessarily wasteful to recompile these fundamental types on a regular basis.
507−Again, this part of the state is never updated directly by `+poke`.
508−
509−```hoon
510−=| $: lac=_& :: laconic bit
511− eny=@ :: entropy
512− our=ship :: identity
513− bud=vase :: %zuse
514− vanes=(list [label=@tas =vane]) :: modules
515− ==
516−```
517−
518−This is where the real state of the Arvo kernel is kept. `lac` detemines whether
519−Arvo's output is verbose, which can be set using the `|verb` command in the
520−dojo. `eny` is the current entropy. `our` is the ship, which is permanently
521−frozen during the larval stage. `bud` is the standard library. Lastly, `vanes`
522−is of course the list of vanes, which have their own internal states.
523−
524−As you can see, the state of Arvo itself is quite simple. Its primary role is that of
525−a traffic cop, and most of the interesting part of the state lies in `vanes`.
526−
527−## Vanes
528−
529−The Arvo kernel can do very little on its own. Its functionality is extended in a careful and controlled way with vanes, also known as kernel modules.
530−
531−As described above, we use Arvo proper to route and control the flow of `move`s.
532−However, Arvo proper is rarely directly responsible for processing the event
533−data that directly causes the desired outcome of a `move`. This event data is contained within a `card`. Instead, Arvo proper passes the `card` off to one of its vanes, which each present an interface to clients for a particular well-defined, stable, and general-purpose piece of functionality.
534−
535−As of this writing, we have nine vanes, which each provide the following services:
536−
537−- [Ames](/docs/arvo/ames/ames): the name of both our network and the vane that communicates over it.
538−- [Behn](/docs/arvo/behn/behn): a simple timer.
539−- [Clay](/docs/arvo/clay/clay): our version-controlled, referentially- transparent, and global filesystem.
540−- [Dill](/docs/arvo/dill/dill): a terminal driver. Unix sends keyboard events to `%dill` from the console, and `%dill` produces terminal output.
541−- [Eyre](/docs/arvo/eyre/eyre): an http server. Unix sends http messages to `%eyre`, and `%eyre` produces http messages in response.
542−- [Ford](/docs/arvo/ford/ford): a build system also utilized for marks
543− (file types) and debugging.
544−- [Gall](/docs/arvo/gall/gall): manages our userspace applications. `%gall` keeps state and manages subscribers.
545−- [Iris](/docs/arvo/iris/iris): an http client.
546−- [Jael](/docs/arvo/jael/jael): storage for Azimuth information.
547−
548−#### Applying your knowledge
549−
550−Now that you've learned about the nuts and bolts of the Arvo kernel, why not
551−check it out in action? An in-depth "move trace" tutorial for running a timer app
552−is available [here](/docs/arvo/tutorials/move-trace).
content/docs/arvo/reference/_index.mddeleted−11
@@ -1,11 +0,0 @@
1−+++
2−title = "Reference"
3−weight = 300
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−+++
7−
8−[Cryptography](/docs/arvo/reference/cryptography)
9−
10−An overview of where Arvo uses cryptography, what algorithms are used, and how
11−they are implemented.
content/docs/arvo/reference/cryptography.mddeleted−222
@@ -1,222 +0,0 @@
1−+++
2−title = "Cryptography"
3−weight = 10
4−template = "doc.html"
5−+++
6−
7−This is a summary of the cryptography functions found in `sys/zuse.hoon`, Arvo's
8−standard library. This page currently only documents cryptographic functions
9−directly utilized by [Ames](/docs/arvo/ames/ames). `zuse` also contains
10−cryptographic functions relevant to Ethereum such as the `+keccak:crypto` core,
11−but they are currently undocumented.
12−
13−Documentation for [Insecure Hashing](/docs/hoon/reference/stdlib/2e) and the
14−[SHA Hash Family](/docs/hoon/reference/stdlib/3d) is found in the Hoon standard
15−library reference.
16−
17−## Summary
18−
19−`zuse` contains several cryptosuites. The ones utilized by Ames are
20−[`+ed:crypto`](#ed), [`+aes:crypto`](#aes), and [`+crub:crypto`](#crub), with
21−the latter being the only one which is implemented as an [`+acru:ames`](/docs/arvo/ames/cryptography#crypto-core)-shaped core.
22−
23−## `+crub:crypto` {% #crub %}
24−
25−`+crub:crypto` implements an
26−[`+acru:ames`](/docs/arvo/ames/cryptography#crypto-core) core that implements
27−[Suite B Cryptography](https://en.wikipedia.org/wiki/NSA_Suite_B_Cryptography).
28−
29−It utilizes AES symmetric key encryption and decryption from [`+aes:crypto`](#aes)
30−implemented using the Diffie-Hellman key exchange protocol, elliptic curve
31−digital signature algorithm (ECDSA) signing and verification with [`+ed:crypto`](#ed),
32−and generates public/private key pairs using elliptic curve cryptography with
33−`+ed:crypto`.
34−
35−A `+crub:crypto` core's payload contains public encryption and authentication
36−keys and optional secret encryption and authentication keys.
37−
38−```hoon
39− ++ crub !:
40− ^- acru
41− =| [pub=[cry=@ sgn=@] sek=(unit [cry=@ sgn=@])]
42− |%
43− ...
44−```
45−
46−`+crub` cores (because they follow the `+acru` interface) are typically created using one of the constructors in [`+nu:crub`](#nu).
47−
48−### `+seal:as`
49−
50−```hoon
51− ++ seal ::
52− |= [bpk=pass msg=@]
53− ...
54−```
55−
56−Forms a symmetric key using Diffie-Hellman key exchange with the secret key
57−stored at `sgn.u.sek` and a public key `bpk`. Then `+sign`s `msg`, encrypts the
58−signed message using `+en:siva:aes` with the symmetric key, and then `+jam`s it.
59−
60−Crashes if `sek` is null.
61−
62−### `+sign:as` {% #sign-as %}
63−
64−```hoon
65− ++ sign ::
66− |= msg=@
67− ...
68−```
69−
70−Signs message `msg=@` using the secret authentication key `sgn.u.sek`, then forms a
71−cell `[signed-message msg]` and `+jam`s it.
72−
73−Crashes if `sek` is null.
74−
75−### `+sure:as`
76−
77−```hoon
78− ++ sure ::
79− |= txt=@
80− ...
81−```
82−
83−`+cue`s `txt` to get a signature `sig=@` and message `msg=@`. Verifies that
84−`sig` was `msg` signed using the secret key associated to the public key stored
85−at `sgn.pub`. Returns `(unit msg)` if so, null otherwise.
86−
87−### `+tear:as`
88−
89−```hoon
90− ++ tear ::
91− |= [bpk=pass txt=@]
92− ...
93−```
94−
95−Forms a secret symmetric key using Diffie-Hellman key exchange using the secret
96−key `cry.u.sek` and encryption key part of the public key `bpk` (which here is a
97−concatenation of both the encryption and authentication public keys). `+cue`s
98−`txt` and decrypts it using `+de:siva:aes` with the symmetric key. If decryption
99−is successful, verifies the decrypted message using authentication key part of
100−`bpk`, and returns it if so. Returns null otherwise.
101−
102−Crashes if `sek` is null.
103−
104−### `+de`
105−
106−```hoon
107− ++ de :: decrypt
108− |= [key=@J txt=@]
109− ...
110−```
111−
112−`+cue`s `txt` then decrypts with the symmetric key `key` using `+de:sivc:aes`.
113−Returns null in case of failure.
114−
115−### `+dy`
116−
117−```hoon
118− ++ dy :: need decrypt
119− |= [key=@J cph=@]
120− ...
121−```
122−
123−Same as `+dy`, but crashes in case of failure.
124−
125−### `+en` {% #en %}
126−
127−```hoon
128− ++ en :: encrypt
129− |= [key=@J msg=@]
130−```
131−
132−Encrypts `msg` with the symmetric key `key` using `en:sivc:aes`, then `+jam`s
133−it.
134−
135−### `+fig:ex`
136−
137−Returns the fingerprint (SHA-256) of `+pub:ex`.
138−
139−### `+pac:ex`
140−
141−Returns the fingerprint (SHA-256) of `+sec:ex`. Crashes if `sek` is null.
142−
143−### `+pub:ex`
144−
145−Returns the concatenation of `sgn.pub` and `cry.pub`.
146−
147−### `+sec:ex`
148−
149−Returns the concatenation of `sgn.u.sek` and `cry.u.sek`.
150−
151−### `+pit:nu` {% #nu %}
152−
153−```hoon
154− ++ pit :: create keypair
155− |= [w=@ seed=@]
156− ...
157−```
158−
159−Creates a `+crub` core with encryption and authentication public/private keypairs
160−generated from a bitwidth `w` and `seed`. The private keys are generated with
161−SHA-512, while `+puck:ed:crypto` is used to derive the public keys from the
162−private keys.
163−
164−This is how one typically generates a brand new `+crub` core for signing and
165−encrypting your own messages.
166−
167−### `+nol:nu`
168−
169−```hoon
170− ++ nol :: activate secret
171− |= a=ring
172− ...
173−```
174−
175−Takes in a `ring` from a `+sec:ex:crub` and generates a new `+crub` core with
176−`sek` taken from `+sec:ex` and `pub` generated with `+puck:ed:crypto`. Crashes
177−if `+sec:ex` is not a `+crub` secret key.
178−
179−### `+com:nu`
180−
181−```hoon
182− ++ com :: activate public
183− |= a=pass
184− ...
185−```
186−
187−Takes in a `pass` from a `+pub:ex:crub` and generates a new `+crub` core with
188−`pub` taken from `+pub:ex` and null `sek`.
189−
190−## `+ed:crypto` {% #ed %}
191−
192−This core contains cryptographic primitives and helper functions for elliptic
193−curve cryptography with [Curve25519](https://en.wikipedia.org/wiki/Curve25519).
194−
195−`+ed:crypto` is primarily used to generate public/private keypairs from a seed
196−for use with [elliptic curve
197−Diffie-Hellman](https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman)
198−key agreements as well as [Elliptic Curve Digital Signature
199−Algorithm](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm).
200−These functionalities are ultimately utilized by [`+crub:crypto`](#crub), the
201−only cryptosuite which [Ames](/docs/arvo/ames/ames) makes use of.
202−
203−Most gates in `+ed:crypto` are [jetted](/docs/vere/jetting), meaning that an
204−external reference library is utilized whenever these functions are called,
205−rather than running in Nock natively. See the [Vere
206−documentation](/docs/vere/cryptography#ed) for more information about the
207−library utilized by jets.
208−
209−## `+aes:crypto` {% #aes %}
210−
211−This core contains cryptographic primitives and helper functions for
212−[AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) symmetric key
213−encryption and decryption. As is the case with `ed:crypto`, these
214−functionalities are utilized by [`+crub:crypto`](#crub), and most gates are
215−jetted. See also the Vere documentation on [AES
216−SIV](/docs/vere/cryptography#aes) for more information about the library
217−utilized by jets.
218−
219−This core contains several doors, each one used for a different variation of AES
220−according to key size and mode. The only ones currently in use are
221−`+siva:aes:crypto` and `+sivc:aes:crypto`, which are 128-bit and
222−256-bit modes of [`AES-SIV`](https://www.aes-siv.com) respectively.
content/docs/arvo/reference/filesystem.mddeleted−103
@@ -1,103 +0,0 @@
1−+++
2−title = "Filesystem Hierarchy"
3−weight = 20
4−template = "doc.html"
5−+++
6−
7−Here we describe what each of the primary folders present in a Clay desk. This
8−organization is merely a convention, and the exact location of any file does not
9−affect its operation. That being said, some [Ford runes](/docs/arvo/ford/ford)
10−are designed with this structure in mind, and applications such as dojo and
11−spider look in specific folders for code to run. Furthermore, this organization
12−is not perfectly adhered to - sometimes you may find structure definitions in
13−`/lib`, for example.
14−
15−- `/app` contains userspace applications, i.e. [Gall
16− agents](/docs/arvo/gall/gall).
17−- `/gen` contains generators. Many applications make use of generators, but also
18− each generator in this folder may be run from dojo using `+`. For example,
19− `/gen/foo/hoon` in the `%base` desk is run with `+foo`. Generators on desks
20− other than `%base` can be run with `+desk!generator` like `+garden!foo`.
21−- `/lib` contains libraries that may be shared by multiple agents, threads,
22− generators, etc. However, this is not the location of the standard libraries
23− (see `/sys`). Libraries are imported from `/lib` with `/+`.
24−- `/mar` contains [mark](/docs/arvo/clay/marks/marks) definitions.
25−- `/sur` contains shared [structure](/docs/hoon/reference/rune/) definitions.
26− Whenever you expect structures to be used by code across multiple files, it is
27− recommended to place their shared structures in `/sur`. Structures are
28− imported from `/sur` with `/-`.
29−- `/sys` contains the code that defines the kernel and standard libraries. Note
30− that only the `%base` desk should contain these `/sys` files, other desks
31− omit the directory and instead just depend on `%base`. `/sys/vane` contains
32− the code for the vanes, aka kernel modules. `/sys` is the exception to the
33− rule - structures and functions that are central to Hoon, Arvo, and its vanes,
34− are all located within this folder rather than in `/lib` and `/sur`. See
35− [below](#sys) for more information on `/sys`.
36−- `/ted` contains [threads](/docs/userspace/threads/overview). These may be run
37− from dojo using `-`. For example, `/ted/foo/hoon` on the `%base` desk is run
38− with `-foo`. Threads on desks other than the `%base` desk can be run with
39− `-desk!thread` like `-garden!foo`.
40−- `/tests` contains unit tests intended to be run using the `test` thread. To
41− run a particular test `+test-bar` in `/tests/foo.hoon` in dojo, enter `-test %/tests/foo/test-bar ~`. If a file is specified, every test in that file will
42− run. If a folder is specified, every test in that folder will run.
43−
44−## `/sys` {% #sys %}
45−
46−`/sys` contains four files: `hoon.hoon`, `arvo.hoon`, `lull.hoon`, and
47−`zuse.hoon`. These are the files used to construct kernelspace. Only the `%base`
48−desk contains these files, other desks omit the `/sys` directory and instead
49−just depend on `%base`. The chain of dependencies is `hoon.hoon` -> `arvo.hoon`
50−-> `lull.hoon` -> `zuse.hoon`. We give a brief description of each of them.
51−
52−- `hoon.hoon` contains the Hoon compiler and the [Hoon standard
53− library](/docs/hoon/reference/stdlib/table-of-contents). The Hoon
54− compiler is self-hosted. This is the first file loaded by the Nock virtual
55− machine, [Vere](/docs/vere/runtime), in order for it to learn how to
56− interpret Hoon. The kelvin version number is the subject of `hoon.hoon`,
57− currently at 140. One may see this from dojo by inspecting the subject with
58− `.` and noting that `%140` is the final entry of the subject.
59−- `arvo.hoon` contains the [Arvo kernel](/docs/arvo/overview) and
60− additional structures and functions directly relevant to the kernel. This is
61− Urbit's "traffic cop", and as such contains the structure definitions for
62− call stacks such as `duct`s and `bone`s. Once Vere understands Hoon, it loads
63− and interprets `arvo.hoon` to create the kernel. `hoon.hoon` is the subject
64− of `arvo.hoon`.
65−- `lull.hoon` primarily contains structures shared among the kernel and its
66− vanes, as well as a few functions. In particular, this includes the
67− definitions of the `task`s and `gift`s utilized by each vane, each of which
68− are documented in their respective documentation. `lull.hoon` is loaded by the
69− kernel during the [larval stage](/docs/arvo/overview#larval-stage-core) in
70− order to prepare to create the vanes. `arvo.hoon` is the subject of
71− `lull.hoon`.
72−- `zuse.hoon` is the Arvo standard library. It consists primarily of functions
73− shared by the kernel and vanes, such as the ones related to
74− [cryptography](/docs/arvo/reference/cryptography). `zuse.hoon` is loaded by
75− the larval kernel following `lull.hoon`. `lull.hoon` is the subject of
76− `zuse.hoon`. Then `zuse` is the subject of the vanes. Some of the functions in
77− Zuse are documented [here](/docs/hoon/reference/zuse/table-of-contents).
78−
79−## Desks
80−
81−A desk is an independently revision-controlled branch of a ship that uses the
82−Clay filesystem. Each desk contains its own apps, mark definitions, files, and
83−so forth. The basic filesystem structure is the same for all desks, with the
84−exception that only the `%base` desk contains a [`/sys`](#sys) directory.
85−Additionally, there are a handful of special files related to the management of
86−desks and their Gall agents:
87−
88−- `sys.kelvin` - This specifies the version of Arvo the desk is compatible with.
89− This file is mandatory in all desks.
90−- `desk.bill` - This file specifies the Gall agents on a desk which should be
91− automatically started when it's installed. This file may be omitted if there
92− are no agents to start.
93−- `desk.docket-0` - This file configures the tile,
94− [glob](/docs/userspace/dist/glob) and other metadata for apps with a
95− front-end. This file may be omitted if the desk does not have a tile or
96− front-end to be installed. This file is versioned so the number appended may
97− change in the future as changes to its specification are made. See the [Docket
98− File](/docs/userspace/dist/docket) documentation for more details.
99−- `desk.ship` - This specifies the original publisher of the desk and is useful
100− if a desk is being republished. It is optional and may be omitted.
101−
102−For more details of creating and distributing desks, see the
103−[Distribution](/docs/userspace/dist/dist) documentation.
content/docs/arvo/tutorials/_index.mddeleted−9
@@ -1,9 +0,0 @@
1−+++
2−title = "Tutorials"
3−weight = 200
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−insert_anchor_links = "right"
7−+++
8−
9−Tutorials aimed at broadening understanding of Arvo.
content/docs/arvo/tutorials/move-trace.mddeleted−380
@@ -1,380 +0,0 @@
1−+++
2−title = "Move Trace"
3−weight = 12
4−template = "doc.html"
5−+++
6−
7−In this tutorial we will run a simple "move trace" and use the output to get a
8−picture of what the Arvo kernel proper does during the routine task of setting a
9−timer. Some level of familiarity with the kernel is required for this section,
10−which can be obtained in our [Arvo kernel tutorial](/docs/arvo/overview#the-kernel).
11−
12−## Running a move trace
13−
14−Ultimately, everything that happens in Arvo is reduced to Unix events, and the
15−Arvo kernel acts as a sort of traffic cop for vanes and apps to talk to one
16−another. Here we look at how a simple command, `-time ~s1`, goes from pressing
17−Enter on your keyboard in Dojo towards returning a notification that one second
18−has elapsed.
19−
20−To follow along yourself, boot up a fake `~zod` and enter `|verb` into the dojo
21−and press Enter to enable verbose mode (this is tracked by the laconic bit
22−introduced in the section on [the
23−state](/docs/arvo/overview#the-state)) in the kernel documentation, followed by `-time ~s1`
24−followed by Enter. Your terminal should pretty print a series of `move`s that looks something like this:
25−
26−```
27−["" %unix p=%belt //term/1 ~2020.1.14..19.01.25..7556]
28−["|" %pass [%d %g] [[%deal [~zod ~zod] %hood %poke] /] [i=//term/1 t=~]]
29−["||" %pass [%g %g] [[%deal [~zod ~zod] %dojo %poke] /use/hood/~zod/out/~zod/dojo/drum/phat/~zod/dojo] [i=/d t=~[//term/1]]]
30−["|||" %give %g [%unto %fact] [i=/g/use/hood/~zod/out/~zod/dojo/drum/phat/~zod/dojo t=~[/d //term/1]]]
31−["||||" %give %g [%unto %fact] [i=/d t=~[//term/1]]]
32−["|||||" %give %d %blit [i=//term/1 t=~]]
33−["|||" %pass [%g %f] [%build /use/dojo/~zod/drum/hand] [i=/d t=~[//term/1]]]
34−["||||" %give %f %made [i=/g/use/dojo/~zod/drum/hand t=~[/d //term/1]]]
35−["|||||" %pass [%g %g] [[%deal [~zod ~zod] %spider %watch] /use/dojo/~zod/out/~zod/spider/drum/wool] [i=/d t=~[//term/1]]]
36−["||||||" %give %g [%unto %watch-ack] [i=/g/use/dojo/~zod/out/~zod/spider/drum/wool t=~[/d //term/1]]]
37−["|||||" %pass [%g %g] [[%deal [~zod ~zod] %spider %poke] /use/dojo/~zod/out/~zod/spider/drum/wool] [i=/d t=~[//term/1]]]
38−//term/1]]]
39−["||||||" %pass [%g %f] [%build /use/spider/~zod/find/~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u] [i=/d t=~[//term/1]]]
40−["|||||||" %give %f %made [i=/g/use/spider/~zod/find/~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u t=~[/d //term/1]]]
41−["||||||||" %pass [%g %f] [%build /use/spider/~zod/build/~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u] [i=/d t=~[//term/1]]]
42−["|||||||||" %give %f %made [i=/g/use/spider/~zod/build/~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u t=~[/d //term/1]]]
43−["||||||||||" %pass [%g %b] [%wait /use/spider/~zod/thread/~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u/wait/~2020.1.14..19.01.26..7556] [i=/d t=~[//term/1]]]
44−["|||||||||||" %give %b %doze [i=//behn/0v1p.sn2s7 t=~]]
45−> -time ~s1
46−```
47−
48−followed by a pause of one second, then
49−
50−```
51−["" %unix p=%wake //behn ~2020.1.14..19.01.26..755d]
52−["|" %give %b %doze [i=//behn/0v1p.sn2s7 t=~]]
53−["|" %give %b %wake [i=/g/use/spider/~zod/thread/~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u/wait/~2020.1.14..19.01.26..7556 t=~[/d //term/1]]]
54−["||" %give %g [%unto %fact] [i=/g/use/dojo/~zod/out/~zod/spider/drum/wool t=~[/d //term/1]]]
55−["|||" %give %g [%unto %fact] [i=/g/use/hood/~zod/out/~zod/dojo/drum/phat/~zod/dojo t=~[/d //term/1]]]
56−["||||" %give %g [%unto %fact] [i=/d t=~[//term/1]]]
57−["|||||" %give %d %blit [i=//term/1 t=~]]
58−["||" %give %g [%unto %kick] [i=/g/use/dojo/~zod/out/~zod/spider/drum/wool t=~[/d //term/1]]]
59−~s1..0007
60−```
61−
62−This gives us a move trace that is a list of `move`s and some
63−associated metadata. Some of the `move`s are a bit of a distraction from what's
64−going on overall such as acknowledgements that a `poke` was received
65−(`%poke-ack`s), so we've omitted them for clarity. Furthermore, two `move`s (the
66−`%blit` `card`s) is not printed even in verbose mode because it occurs so
67−frequently, but there are only two of them here and so we have added it in.
68−
69−The main process that is occurring here is a sequence of `%pass` `move`s initiated
70−by pressing Enter in the terminal that goes on to be handled by Dill, then Gall,
71−and finally Behn. After the timer has elapsed, a sequence of `%give` `move`s is
72−begun by Behn, which then passes through Gall and ultimately ends up back at the
73−terminal. Any `move`s besides `%pass` in the first segment of the move trace is a
74−secondary process utilized for book-keeping, spawning processes, interpreting
75−commands, etc. All of this will be explained in detail below.
76−
77−It is important to note that this move trace should be thought of
78−as being from the "point of view" of the kernel - each line represents the
79−kernel taking in a message from one source and passing it along to its
80−destination. It is then processed at that destination (which could be a vane or
81−an app), and the return of that process is sent back to Arvo in the form of
82−another `move` to perform and the loop begins again. Thus this move trace does
83−not display information about what is going on inside of the vane or app such as
84−private function calls, only what the kernel itself sees.
85−
86−## Interpreting the move trace
87−
88−In this section we will go over the move trace line-by-line, explaining how the
89−move trace is printed, what each line means (including some things not found in
90−the move trace), and a particular focus on what code is being activated in the
91−first few lines that should equip you well enough to unravel the rest of the
92−move trace in as much detail as you desire.
93−
94−### The call
95−
96−Let's put the first part of the move trace into a diagram to make following
97−along a little easier.
98−
99−![](https://media.urbit.org/docs/arvo/move-trace-with-key.png)
100−
101−Here, each arrow represents the passing of some information, with most of it
102−being from vane to vane. Here, when Vane A has an arrow to a card and then an
103−arrow to Vane B, this represents either a `%pass` `note/task` sequence or a
104−`%give` `gift/sign` sequence that actually has the Arvo kernel in the middle.
105−That is to say, Vane A `%pass`es a `note` to the Arvo kernel addressed to Vane
106−B, and the Arvo kernel then `%pass`es a `task` to Vane B. For more information,
107−see the [Arvo kernel tutorial](/docs/arvo/overview#the-kernel).
108−
109−This simple action ends up involving four vanes - Dill, Gall, Behn, and Ford -
110−as well as four applications - hood, spider, dojo, and time.
111−
112−Now let's go through each line one by one.
113−
114−```
115−["" %unix p=%belt //term/1 ~2020.1.14..19.01.25..7556]
116−```
117−
118−This tells us that Unix has sent a `%belt` `card`, which corresponds to
119−terminal input (the Enter keystroke) at time `~2020.1.14..19.01.25..7556`
120−
121−Here is the line of code in `arvo.hoon`, found in the [section
122−3bE core](/docs/arvo/overview#section-3be-core), that generated the output:
123−
124−```hoon
125− ~? !lac ["" %unix -.q.ovo p.ovo now]
126−```
127−
128−First we note that this line is executed only if the laconic bit is set to true,
129−as we did when we input `|verb`. Here, `ovo` is the input `ovum`. Knowing that an `ovum` is a `[p=wire q=curd]`,
130−we can then say that this is a `%unix` `move` tagged with `%belt` whose cause is a `wire` given by `//term/1`,
131−where the empty span `//` represents Unix and `term/1` represents the terminal
132−in Unix. Here we have a `wire` instead of a `duct` (i.e. a list of `wire`s)
133−since Unix I/O events are always the beginning and end of the Arvo event loop,
134−thus only a single `wire` is ever required at this initial stage.
135−
136−The `""` here is a metadatum that keeps track of how many steps deep in the
137−causal chain the event is. An event
138−with `n` `|`'s was caused by the most recent previous event with `n-1` `|`'s. In
139−this case, Unix events are an "original cause" and thus represented by an empty
140−string.
141−
142−At this point in time, Dill has received the `move` and then processes it. The
143−`%belt` `task` in `dill.hoon` is `+call`ed, which is processed using the `+send`
144−arm:
145−
146−```hoon
147− ++ send :: send action
148− |= bet/dill-belt
149− ^+ +>
150− ?^ tem
151− +>(tem `[bet u.tem])
152− (deal / [%poke [%dill-belt -:!>(bet) bet]])
153−```
154−
155−Dill has taken in the command and in response it `%pass`es a `task` `card` with
156−instructions to `%poke` hood, which is a Gall app
157−primarily used for interfacing with Dill. Here, `+deal` is an arm for
158−`%pass`ing a `card` to Gall to ask it to create a `%deal` `task`:
159−
160−```hoon
161− ++ deal :: pass to %gall
162− |= [=wire =deal:gall]
163− (pass wire [%g %deal [our our] ram deal])
164−```
165−
166−Next in our move trace we have this:
167−
168−```
169−["|" %pass [%d %g] [[%deal [~zod ~zod] %hood %poke] /] [i=//term/1 t=~]]
170−```
171−
172−Here, Dill `%pass`es a `task` `card` saying to `%poke` Gall's hood app (with the
173−Enter keystroke).
174−
175−Let's glance at part of the `+jack` arm in `arvo.hoon`, located in the [section 3bE
176−core](/docs/arvo/overview#section-3be-core). This arm is what the Arvo kernel uses to send `card`s,
177−and here we look at the segment that includes `%pass` `move`s.
178−
179−```hoon
180− ++ jack :: dispatch card
181− |= [lac=? gum=muse]
182− ^- [[p=(list ovum) q=(list muse)] _vanes]
183− ~| %failed-jack
184− :: =. lac |(lac ?=(?(%g %f) p.gum))
185− :: =. lac &(lac !?=($b p.gum))
186− %^ fire
187− p.gum
188− s.gum
189− ?- -.r.gum
190− $pass
191− ~? &(!lac !=(%$ p.gum))
192− :- (runt [s.gum '|'] "")
193− :^ %pass [p.gum p.q.r.gum]
194− ?: ?=(?(%deal %deal-gall) +>-.q.q.r.gum)
195− :- :- +>-.q.q.r.gum
196− (,[[ship ship] term term] [+>+< +>+>- +>+>+<]:q.q.r.gum)
197− p.r.gum
198− [(symp +>-.q.q.r.gum) p.r.gum]
199− q.gum
200− [p.q.r.gum ~ [[p.gum p.r.gum] q.gum] q.q.r.gum]
201−```
202−
203−Code for writing traces can be a bit tricky, but let's try not to get too
204−distracted by the lark expressions and such. By paying attention to the lines
205−concerning the laconic bit (following `!lac`) we can mostly determine what is being told to us.
206−
207−From the initial input event, Arvo has generated a `card` that it is now
208−`%pass`ing from Dill (represented by `%d`) to Gall (represented by `%g`). The
209−`card` is a `%deal` `task`, asking Gall to `%poke` hood using data that has
210−originated from the terminal `//term/1`, namely that the Enter key was pressed. The line `:- (runt [s.gum '|'] "")`
211−displays the causal chain length metadatum mentioned above. Lastly, `[~zod ~zod]` tells us that
212−`~zod` is both the sending and receiving ship.
213−
214−From here on our explanations will be more brief. We include some information
215−that cannot be directly read from the move trace in [brackets]. Onto the next line:
216−
217−```
218−["||" %pass [%g %g] [[%deal [~zod ~zod] %dojo %poke] /use/hood/~zod/out/~zod/dojo/drum/phat/~zod/dojo] [i=/d t=~[//term/1]]]
219−```
220−
221−Here is another `%pass` `move`, this time from Gall to iself as denoted by `[%g %g]`. Gall's hood has received the `%deal` `card` from Dill, and in response it is
222−`%poke`ing dojo with the information [that Enter was pressed].
223−
224−```
225−["|||" %give %g [%unto %fact] [i=/g/use/hood/~zod/out/~zod/dojo/drum/phat/~zod/dojo t=~[/d //term/1]]]
226−```
227−
228−Gall's dojo `%give`s a `gift` with a `%fact` (subscription update) to Gall's hood, [saying to clear
229−the terminal prompt].
230−
231−```
232−["||||" %give %g [%unto %fact] [i=/d t=~[//term/1]]]
233−```
234−
235−Gall's hood `%give`s a `gift` with a `%fact` to Dill [saying to replace the current terminal line with `~zod:dojo>`]
236−
237−Next is the `move` that is not actually printed in the move trace mentioned
238−above:
239−
240−```
241−["|||||" %give %d %blit [i=//term/1 t=~]]
242−```
243−
244−Dill `%give`s a `%blit` (terminal output) event to Unix [saying to replace the current terminal line with `~zod:dojo>`].
245−
246−```
247−["|||" %pass [%g %f] [%build /use/dojo/~zod/drum/hand] [i=/d t=~[//term/1]]]
248−```
249−
250−Gall's dojo also `%pass`es a `%build` request to Ford [asking to run "~s1" against the subject we use in the dojo].
251−
252−```
253−["||||" %give %f %made [i=/g/use/dojo/~zod/drum/hand t=~[/d //term/1]]]
254−```
255−
256−Ford `%give`s a result back to dojo [with the value `~s1`]
257−
258−```
259−["|||||" %pass [%g %g] [[%deal [~zod ~zod] %spider %watch] /use/dojo/~zod/out/~zod/spider/drum/wool] [i=/d t=~[//term/1]]]
260−```
261−
262−Gall's dojo `%pass`es a `%watch` to Gall's spider app [to start listening for the result of the thread it's about to start].
263−
264−```
265−["||||||" %give %g [%unto %watch-ack] [i=/g/use/dojo/~zod/out/~zod/spider/drum/wool t=~[/d //term/1]]]
266−```
267−
268−Gall's spider acknowledges the subscription from dojo.
269−
270−```
271−["|||||" %pass [%g %g] [[%deal [~zod ~zod] %spider %poke] /use/dojo/~zod/out/~zod/spider/drum/wool] [i=/d t=~[//term/1]]]
272−```
273−
274−Gall's dojo also `%pass`es a `%poke` to Gall's spider [asking it start the thread "-time" with argument `~s1`].
275−
276−```
277−["||||||" %pass [%g %f] [%build /use/spider/~zod/find/~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u] [i=/d t=~[//term/1]]]
278−```
279−
280−Gall's spider `%pass`es a `%build` request to Ford [asking it to find the path in `/ted` where the "time" thread is].
281−
282−```
283−["|||||||" %give %f %made [i=/g/use/spider/~zod/find/~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u t=~[/d //term/1]]]
284−```
285−
286−Ford `%give`s a result back to Gall's spider [saying it's in `/ted/time.hoon`].
287−
288−```
289−["||||||||" %pass [%g %f] [%build /use/spider/~zod/build/~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u] [i=/d t=~[//term/1]]]
290−```
291−
292−Gall's spider `%pass`es a `%build` request to Ford [asking it to compile the file `/ted/time.hoon`].
293−
294−```
295−["|||||||||" %give %f %made [i=/g/use/spider/~zod/build/~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u t=~[/d //term/1]]]
296−```
297−
298−Ford `%give`s a result back to Gall's spider [with the compiled thread].
299−
300−```
301−["||||||||||" %pass [%g %b] [%wait /use/spider/~zod/thread/~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u/wait/~2020.1.14..19.01.26..7556] [i=/d t=~[//term/1]]]
302−```
303−
304−Gall's spider's thread with id `~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u` asks Behn to set a timer [for one second].
305−
306−```
307−["|||||||||||" %give %b %doze [i=//behn/0v1p.sn2s7 t=~]]
308−```
309−
310−Behn `%give`s a `%doze` `card` to Unix, asking it to set a timer [for one second from
311−now]. At this point Arvo may rest.
312−
313−### The return
314−
315−Now Unix sets a timer for one second, waits one second, and then informs Behn that a second has
316−passed, leading to a chain of `%give` `move`s that ultimately prints
317−`~s1..0007`.
318−
319−Let's throw the move trace into a table:
320−
321−| length | move | vane(s) | card | duct |
322−| ------ | ------- | ------- | --------------- | ---------------------------------------------------------------------------------------------------------------- |
323−| 0 | `%unix` | | `%wake` | `//behn` |
324−| 1 | `%give` | `%b` | `%doze` | `//behn/0v1p.sn2s7` |
325−| 1 | `%give` | `%b` | `%wake` | `/g/use/spider/~zod/thread/~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u/wait/~2020.1.14..19.01.26..7556 /d //term/1` |
326−| 2 | `%give` | `%g` | `[%unto %fact]` | `/g/use/dojo/~zod/out/~zod/spider/drum/wool /d //term/1` |
327−| 3 | `%give` | `%g` | `[%unto %fact]` | `/g/use/hood/~zod/out/~zod/dojo/drum/phat/~zod/dojo /d //term/1` |
328−| 4 | `%give` | `%g` | `[%unto %fact]` | `/d //term/1` |
329−| 5 | `%give` | `%d` | `%blit` | `//term/1` |
330−| 2 | `%give` | `%g` | `[%unto %kick]` | `/g/use/dojo/~zod/out/~zod/spider/drum/wool /d //term/1` |
331−
332−Now we follow it line-by-line:
333−
334−```
335−["" %unix p=%wake //behn ~2020.1.14..19.01.26..755d]
336−```
337−
338−Unix sends a `%wake` (timer fire) `card` at time `~2020.1.14..19.01.26..755d`.
339−
340−```
341−["|" %give %b %doze [i=//behn/0v1p.sn2s7 t=~]]
342−```
343−
344−Behn `%give`s a `%doze` `card` to Unix, asking it to set a timer [for whatever next timer it has in its queue].
345−
346−```
347−["|" %give %b %wake [i=/g/use/spider/~zod/thread/~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u/wait/~2020.1.14..19.01.26..7556 t=~[/d //term/1]]]
348−```
349−
350−Behn `%give`s a `%wake` to Gall's spider's thread with id `~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u`.
351−
352−```
353−["||" %give %g [%unto %fact] [i=/g/use/dojo/~zod/out/~zod/spider/drum/wool t=~[/d //term/1]]]
354−```
355−
356−Gall's spider `%give`s a `%fact` (subscription update) to dojo [saying that the thread completed successfully and produced value `~s1.0007`].
357−
358−```
359−["|||" %give %g [%unto %fact] [i=/g/use/hood/~zod/out/~zod/dojo/drum/phat/~zod/dojo t=~[/d //term/1]]]
360−```
361−
362−Gall's dojo `%give`s a `%fact` to hood [saying to output `~s1..0007`].
363−
364−```
365−["||||" %give %g [%unto %fact] [i=/d t=~[//term/1]]]
366−```
367−
368−Gall's hood `%give`s a `%fact` to Dill [saying to output `~s1..0007`].
369−
370−```
371−["|||||" %give %d %blit [i=//term/1 t=~]]
372−```
373−
374−Dill `%give`s a `%blit` (terminal output) event to Unix [saying to print a new line with output `~s1..0007`].
375−
376−```
377−["||" %give %g [%unto %kick] [i=/g/use/dojo/~zod/out/~zod/spider/drum/wool t=~[/d //term/1]]]
378−```
379−
380−Gall's spider also closes the subscription from dojo [since the thread has completed].
content/docs/azimuth/_index.mddeleted−41
@@ -1,41 +0,0 @@
1−+++
2−title = "Azimuth"
3−weight = 700
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−insert_anchor_links = "right"
7−+++
8−
9−### [Azimuth](/docs/azimuth/azimuth)
10−
11−An overview of the Ethereum-based public key infrastructure utilized by Urbit.
12−
13−### [Urbit HD Wallet](/docs/azimuth/hd-wallet)
14−
15−Azimuth has its own optional hierarchical deterministic wallet system, often
16−referred to as a "master ticket".
17−
18−### [Data Flow](/docs/azimuth/flow)
19−
20−Diagrams and explanations of how data flows between Bridge and the various
21−components inside Urbit involved with layer 2.
22−
23−### [Azimuth.eth](/docs/azimuth/azimuth-eth)
24−
25−A description of the `azimuth.eth` smart contract, which is the data store for
26−Azimuth.
27−
28−### [Ecliptic.eth](/docs/azimuth/ecliptic)
29−
30−A description of the `ecliptic.eth` smart contract, which is the business logic
31−for `azimuth.eth`. This includes an overview of all function calls available.
32−
33−### [Advanced Azimuth Tools](/docs/azimuth/advanced-azimuth-tools)
34−
35−Expert-level tooling for generating, signing, and sending layer 1 Azimuth-related
36−transactions from within Urbit itself.
37−
38−### [Life and Rift](/docs/azimuth/azimuth)
39−
40−An explanation of how Azimuth indexes networking keys and breaches to keep track
41−of the most recent set of networking keys necessary to communicate with a ship.
content/docs/azimuth/advanced-azimuth-tools.mddeleted−124
@@ -1,124 +0,0 @@
1−+++
2−title = "Advanced Azimuth Tools"
3−weight = 7
4−template = "doc.html"
5−+++
6−
7−This document outlines some advanced techniques for generating, signing, and
8−sending Azimuth-related transactions from within Urbit itself. It's strongly
9−discouraged to do this unless you're very confident as Azimuth transactions are
10−permanent and will cost ETH to complete. However, until you upload a signed
11−transaction to the blockchain no transaction will take place so it's safe to
12−explore these tools. It will also be very helpful to have at least a rudimentary
13−understanding of Hoon in order to read and modify parts of the code.
14−
15−These tools are currently only available for layer 1 transactions. Tooling for
16−layer 2 transactions is forthcoming.
17−
18−First you will want to [boot a
19−fakezod](https://urbit.org/using/develop/#creating-a-development-ship). You can
20−do this with your live running ship but at this time this will need you to
21−modify the code so it's best to do this on a ship you can make mistakes on.
22−
23−Be sure to have mounted your base desk so you can easily edit files on it. The
24−first edit that will probably need to be made is in
25−[`app/claz.hoon`](https://github.com/urbit/urbit/blob/85435e9a81e105809d5d381b5d34fae1d4daa3b8/pkg/arvo/app/claz.hoon#L14).
26−The listed url will need to be changed to a valid Ethereum endpoint. infura.io
27−provides an Ethereum API that you can use.
28−
29−The second change that may potentially be needed is to modify the [gas
30−limit](https://github.com/urbit/urbit/blob/85435e9a81e105809d5d381b5d34fae1d4daa3b8/pkg/arvo/app/claz.hoon#L179).
31−This number here is the maximum number of gas units that will be used. In future
32−this will be configurable but for now you may need to change this manually. For
33−a guide to what to set it to you can use the [constants in
34−bridge](https://github.com/urbit/bridge/blob/29f4a14869489481a950a1af53f583d751897444/src/lib/constants.js#L23)
35−as a guide based on what action you are going to be performing. The maximum cost
36−of your transaction will be the maximum gas units multiplied by the gwei you're
37−going to set later. You'll need at least this much in your account.
38−
39−Once you have made these changes be sure to run `|commit %base` to get them into
40−your ship.
41−
42−Next run `|start %claz` after which you'll be able to generate transactions.
43−
44−```
45−:claz [%generate %/spawn/eth-txs %mainnet author %single %spawn ~ship to]
46−```
47−
48−Here we have an example of generating a transaction to spawn a ship. Something
49−to note is that for this to be successful you'll need to actually have the right
50−to spawn the ship in question. Let's break down the command.
51−
52−`%generate` is how all commands to `claz` are going to start.
53−
54−`%/spawn/eth-txs` is simply the path for the output file
55−
56−`%mainnet` specifies which network this is going to sent out on. Other options
57−are possible including the test-net `%ropsten`.
58−
59−`author` here is an Ethereum address that is issuing the transaction. It will
60−need to be written in `@ux` notation, e.g.
61−`0x3b17.d097.d9dd.711e.4ef8.517a.bbf1.8b2b.a643.81fe`.
62−
63−`%single` specifies what kind of batch that will be created. If you are going to
64−do multiple transactions you will need to either set this to `%more` followed by
65−a _list_ of batches, or generate the next transaction after having submitted the
66−previous one to the blockchain.
67−
68−`[%spawn ~ship to]` is the transaction we want to issue. The arguments are will
69−vary based on the transaction. `~ship` will be the ship to be spawned. `to` is
70−the Ethereum address to spawn the ship to.
71−
72−You will want to read
73−[`/sur/claz.hoon`](https://github.com/urbit/urbit/blob/85435e9a81e105809d5d381b5d34fae1d4daa3b8/pkg/arvo/sur/claz.hoon).
74−This will contain more details about the various kinds of transactions you can
75−perform particularly `++call`
76−
77−After running this command you should find a csv file at the output path you
78−specified. You can examine this file to learn how they are constructed. You are
79−able to modify the nonces, gas limit and price without changing the
80−functionality of the transaction but it's not important for this guide.
81−
82−This file can now be signed and uploaded. At this point, you can transfer this
83−file to an airgapped machine which has your keys, if you want. If you choose to
84−do that you will need to download the `urbit` binary as well as the most recent
85−pill file or a copy of the fakezod pier you have already booted.
86−
87−For this guide, we'll continue on the same ship.
88−
89−Run `|start %eth-sender` and then you can use it to sign the transaction file.
90−
91−```
92−:eth-sender [%sign %/spawn-signed/txt %/spawn/eth-txs %/mykey/txt ~[40 80]]
93−```
94−
95−Let's break this down again.
96−
97−`%sign` is the action we are going to perform here. `eth-sender` can also be
98−used to submit batches of transactions to the network in various ways, but
99−details on that are outside of the scope of this guide.
100−
101−`%/spawn-signed/txt` is the path to the output file.
102−
103−`%/spawn/eth-txs` is the path to the transaction file we generated earlier. It
104−will need to be accessible so don't forget to `|commit %base` if you moved it to
105−a different pier.
106−
107−`%/mykey/txt` is the path to your private key file. It should contain your
108−private key beginning with 0x and followed by a hex string with no dots, and
109−where capital letters are fine. This file is most likely the reason you will
110−want to use an airgapped machine so that your private key never touches a
111−networked computer. Opsec is left to the reader.
112−
113−`~[40 80]` is a list of gas prices, in gwei; a signed transaction file will be
114−created for each one listed. Here we just specify 40 and 80 gwei. You may want
115−to adjust this list based on current Ethereum network traffic and your time
116−preference for the transactions.
117−
118−Now you should have one file in your pier for each gwei costs.
119−
120−To actually transmit the transaction, paste the contents of one of these files
121−into https://etherscan.io/pushTx or whatever other transmission system you would
122−like to use. **This is the action that will actually cost you ETH and perform
123−the transaction on the network. Only do this step if you want to actually
124−perform the action.**
content/docs/azimuth/azimuth-eth.mddeleted−157
@@ -1,157 +0,0 @@
1−+++
2−title = "Azimuth.eth"
3−weight = 5
4−template = "doc.html"
5−+++
6−
7−[Azimuth.eth](https://etherscan.io/address/azimuth.eth) is used for storing all
8−data related to Azimuth points and their ownership, and should be considered to
9−be the ledger for Azimuth. This contract is just a data store - it only contains
10−the bare minimum of business logic. See [Ecliptic.eth](/docs/azimuth/ecliptic)
11−for the contract containing the business logic for this ledger. `Azimuth.eth`
12−cannot be modified directly by [galaxy vote](/docs/glossary/upgrade) - they are
13−only eligible to modify the Ecliptic.
14−
15−## Global state {% #global %}
16−
17−The global state of `Azimuth.eth` is given by the following.
18−
19−```solidity
20− // points: per point, general network-relevant point state
21− //
22− mapping(uint32 => Point) public points;
23−
24− // rights: per point, on-chain ownership and permissions
25− //
26− mapping(uint32 => Deed) public rights;
27−
28− // operators: per owner, per address, has the right to transfer ownership
29− // of all the owner's points (ERC721)
30− //
31− mapping(address => mapping(address => bool)) public operators;
32−
33− // dnsDomains: base domains for contacting galaxies
34− //
35− // dnsDomains[0] is primary, the others are used as fallbacks
36− //
37− string[3] public dnsDomains;
38−```
39−
40−Urbit ID's are formalized as [ERC-721 non-fungible
41−tokens](https://eips.ethereum.org/EIPS/eip-721) and are indexed by a number
42−between `0` and `2^32-1`, e.g. a `uint32`. There are two data structures
43−associated to a given `uint32`: a `Point` and a `Deed`.
44−
45−## `Point`s {% #points %}
46−
47−A `Point` contains data about networking keys and sponsorship status, arranged
48−in the following `struct`:
49−
50−```solidity
51− struct Point
52− {
53− // encryptionKey: (curve25519) encryption public key, or 0 for none
54− //
55− bytes32 encryptionKey;
56− //
57− // authenticationKey: (ed25519) authentication public key, or 0 for none
58− //
59− bytes32 authenticationKey;
60− //
61− // spawned: for stars and galaxies, all :active children
62− //
63− uint32[] spawned;
64− //
65− // hasSponsor: true if the sponsor still supports the point
66− //
67− bool hasSponsor;
68−
69− // active: whether point can be linked
70− //
71− // false: point belongs to prefix, cannot be configured or linked
72− // true: point no longer belongs to prefix, can be configured and linked
73− //
74− bool active;
75−
76− // escapeRequested: true if the point has requested to change sponsors
77− //
78− bool escapeRequested;
79−
80− // sponsor: the point that supports this one on the network, or,
81− // if :hasSponsor is false, the last point that supported it.
82− // (by default, the point's half-width prefix)
83− //
84− uint32 sponsor;
85−
86− // escapeRequestedTo: if :escapeRequested is true, new sponsor requested
87− //
88− uint32 escapeRequestedTo;
89−
90− // cryptoSuiteVersion: version of the crypto suite used for the pubkeys
91− //
92− uint32 cryptoSuiteVersion;
93−
94− // keyRevisionNumber: incremented every time the public keys change
95− //
96− uint32 keyRevisionNumber;
97−
98− // continuityNumber: incremented to indicate network-side state loss
99− //
100− uint32 continuityNumber;
101− }
102−```
103−
104−## `Deed`s {% #deeds %}
105−
106−A `Deed` says which Ethereum address owns a given `Point` as well as several
107−[proxies](/docs/using/id/proxies) for that `Point`.
108−
109−```solidity
110−struct Deed
111− {
112− // owner: address that owns this point
113− //
114− address owner;
115−
116− // managementProxy: 0, or another address with the right to perform
117− // low-impact, managerial operations on this point
118− //
119− address managementProxy;
120−
121− // spawnProxy: 0, or another address with the right to spawn children
122− // of this point
123− //
124− address spawnProxy;
125−
126− // votingProxy: 0, or another address with the right to vote as this point
127− //
128− address votingProxy;
129−
130− // transferProxy: 0, or another address with the right to transfer
131− // ownership of this point
132− //
133− address transferProxy;
134− }
135−```
136−
137−## Other state {% #other %}
138−
139−Finally, each Ethereum address may set for itself a number of `operators`, as
140−defined and required by the [ERC-721
141−standard](https://ethereum.org/en/developers/docs/standards/tokens/erc-721/).
142−These are for third party brokers/wallets/auctioneers/etc such as
143−[OpenSea](http://opensea.io), which facilitate exchange of ERC-721 tokens.
144−
145−`Azimuth.eth` also contains some other state—`dnsDomains`—which are domain names by
146−which the IP address of a galaxy may be looked up, e.g. `zod.urbit.org` resolves
147−to `35.247.119.159`. This is used for bootstrapping the network from DNS. Three
148−domains may be listed here, but as of today they are all `urbit.org`. This may
149−only be updated by the owner of Ecliptic, but arguably each galaxy ought to be
150−able to set its own domain name and so we do not expect this to remain the case
151−forever.
152−
153−All data in this ledger is stored and processed locally on your ship by the
154−[`%azimuth` Gall agent](/docs/azimuth/flow#azimuth), including [layer
155−2](/docs/azimuth/l2/layer2) data. Because state transitions resulting from layer 2
156−transactions are not included in this ledger, in general the local store will
157−differ from what is kept in `Azimuth.eth`.
content/docs/azimuth/azimuth.mddeleted−137
@@ -1,137 +0,0 @@
1−+++
2−title = "Overview"
3−weight = 2
4−template = "doc.html"
5−aliases = ["/docs/learn/azimuth"]
6−+++
7−
8−Azimuth is a general-purpose public-key infrastructure (PKI) on the Ethereum
9−blockchain, used as a platform for _Urbit identities_. You need such an identity
10−to use the Arvo network.
11−
12−The primary way to interact with Azimuth is through
13−[Bridge](https://github.com/urbit/bridge) and the node libraries that it depends
14−on, [azimuth-js](https://github.com/urbit/azimuth-js) and
15−[urbit-key-generation](https://github.com/urbit/urbit-key-generation). Take a
16−look at the source and play around, or see [Getting Started](/getting-started/).
17−
18−## Arvo vs. Azimuth
19−
20−Urbit is a project, not a single computer system. It has multiple components:
21−Arvo, the operating system, and Azimuth, the identity system. Let's compare
22−them.
23−
24−**Arvo** is an operating system that provides the software for a personal
25−server. These personal servers together constitute the peer-to-peer Arvo
26−network. To make this network work on the social level, Arvo is built to work
27−with a system of scarce and immutable identities.
28−
29−**Azimuth** is the public-key infrastructure built to be a system of scarce and
30−immutable identities. It consists of a suite of [smart contracts on the Ethereum
31−blockchain](https://github.com/urbit/azimuth) as well as [several
32−apps](/docs/azimuth/flow) run locally on your urbit. Togeter, they determine
33−which Ethereum addresses own which Urbit ID's as well as the public keys needed
34−to communicate with those ID's. All identity-related operations, such as
35−transfers, are governed by Azimuth. Azimuth isn't built strictly for Arvo -- the
36−smart contracts on Ethereum are sufficient to be used as a generalized identity
37−system for other projects. Azimuth is considered to be the technical
38−nomenclature for the PKI, while Urbit ID is the common nomenclature.
39−
40−These otherwise-parallel systems meet when you want to connect to the Arvo
41−network. Your Arvo personal server, called your _ship_, needs to be able to
42−prove cryptographically that it is who it says it is. This proof comes in the
43−form of a keyfile, derived from your identity, that you use to start your ship.
44−
45−A metaphor might help illustrate the relationship between these two systems: the
46−Arvo network is the neighborhood that you live in; Azimuth is the bank vault
47−that stores the deed to your house.
48−
49−## Smart contracts
50−
51−Azimuth consists of the following smart contracts:
52−
53−- [Azimuth.eth](https://etherscan.io/address/azimuth.eth)
54− `0x223c067f8cf28ae173ee5cafea60ca44c335fecb`: contains all on-chain state for
55− Azimuth. Most notably, ownership and public keys. Can't be modified directly,
56− you must use the Ecliptic.
57−- [Ecliptic.eth](https://etherscan.io/address/ecliptic.eth):
58− `0x9ef27de616154FF8B38893C59522b69c7Ba8A81c ` is used as an interface for
59− interacting with your points on-chain. Allows you to configure keys, transfer
60− ownership, etc.
61−- [Polls](https://etherscan.io/address/0x7fecab617c868bb5996d99d95200d2fa708218e4):
62− `0x7fecab617c868bb5996d99d95200d2fa708218e4` registers votes by the Galactic
63− Senate on proposals. These can be either static documents or Ecliptic
64− upgrades.
65−- [Linear Star
66− Release](https://etherscan.io/address/0x86cd9cd0992f04231751e3761de45cecea5d1801):
67− facilitates the release of blocks of stars to their owners over a period of
68− time.
69−- [Conditional Star
70− Release](https://etherscan.io/address/0x8c241098c3d3498fe1261421633fd57986d74aea):
71− `0x8c241098c3d3498fe1261421633fd57986d74aea` facilitates the release of
72− blocks of stars to their owners based on milestones.
73−- [Claims](https://etherscan.io/address/0xe7e7f69b34d7d9bd8d61fb22c33b22708947971a):
74− `0xe7e7f69b34d7d9bd8d61fb22c33b22708947971a` allows point owners to make
75− claims about (for example) their identity, and associate that with their
76− point.
77−- [Censures](https://etherscan.io/address/0x325f68d32bdee6ed86e7235ff2480e2a433d6189):
78− `0x325f68d32bdee6ed86e7235ff2480e2a433d6189` simple reputation management,
79− allowing galaxies and stars to flag points for negative reputation.
80−- [Delegated
81− Sending](https://etherscan.io/address/0xf6b461fe1ad4bd2ce25b23fe0aff2ac19b3dfa76):
82− enables network-effect like distributing of planets.
83−
84−Walkthroughs of some of the smart contracts are linked to [below](#other).
85−
86−## Naive rollups
87−
88−In 2021, Tlon introduced a new system to Azimuth intended to reduce gas costs
89−for working with Urbit ID and friction associated with using cryptocurrency in
90−general called **naive rollups**, often referred to as **layer 2** or L2. This system
91−allows batches of Azimuth transactions to be submitted together as a single
92−transaction using an Urbit node known as a "roller". The PKI state transitions
93−resulting from these transactions are computed locally by your urbit rather than
94−by the [Ethereum Virtual Machine](https://ethereum.org/en/developers/docs/evm/).
95−
96−Due to the dramatically reduced cost, Tlon offers their own roller that is free
97−for ordinary public use. This enables new users to get started with a permanent
98−Azimuth identity without any prior knowledge of Ethereum, cryptocurrency, or
99−blockchains. However, anybody can run a roller, and even using your own ship as
100−a roller to submit single transactions results in significant savings.
101−
102−A casual overview of the naive rollups system can be found on the
103−[blog](/blog/rollups). Developers are encouraged to read our Layer 2
104−documentation, starting with the [Layer 2 Overview](/docs/azimuth/l2/layer2).
105−
106−## Other resources {% #other %}
107−
108−### [Urbit HD Wallet](/docs/azimuth/hd-wallet)
109−
110−Azimuth has its own optional hierarchical deterministic wallet system, often
111−referred to as a "master ticket".
112−
113−### [Data Flow](/docs/azimuth/flow)
114−
115−Diagrams and explanations of how data flows between Bridge and the various
116−components inside Urbit involved with Azimuth and L2.
117−
118−### [Azimuth.eth](/docs/azimuth/azimuth-eth)
119−
120−A description of the `azimuth.eth` smart contract, which is the data store for
121−Azimuth.
122−
123−### [Ecliptic.eth](/docs/azimuth/ecliptic)
124−
125−A description of the `ecliptic.eth` smart contract, which is the business logic
126−for `azimuth.eth`. This includes an overview of all function calls available.
127−
128−### [Advanced Azimuth Tools](/docs/azimuth/advanced-azimuth-tools)
129−
130−Expert-level tooling for generating, signing, and sending layer 1 Azimuth
131−transactions from within Urbit itself.
132−
133−### [Life and Rift](/docs/azimuth/azimuth)
134−
135−An explanation of how Azimuth indexes networking keys revisions and breaches to
136−keep track of the most recent set of networking keys necessary to communicate
137−with a ship.
content/docs/azimuth/ecliptic.mddeleted−446
@@ -1,446 +0,0 @@
1−+++
2−title = "Ecliptic.eth"
3−weight = 6
4−template = "doc.html"
5−+++
6−
7−[Ecliptic.eth](https://etherscan.io/address/ecliptic.eth) holds the business
8−logic for the ledger kept by `Azimuth.eth`. It may be modified by [galaxy
9−vote](/docs/glossary/upgrade). This determines things such as what the various
10−proxies are capable of, how keys are changed, or verifying that a request is
11−valid.
12−
13−`Ecliptic.eth` uses external contracts such as
14−[Azimuth.eth](/docs/azimuth/azimuth-eth) and
15−[Polls](https://github.com/urbit/azimuth/blob/master/contracts/Polls.sol) for
16−data storage so that it can easily be replaced in case the logic needs to be
17−changed without affecting the data. These data contracts are owned by
18−`Ecliptic.eth`, and this ownership is passed to the new Ecliptic contract
19−whenever it is replaced. Thus it is advised for clients to not store Ecliptic's
20−contract address directly, but instead ask the `Azimuth.eth` contract for its
21−`owner` attribute to ensure that transactions are sent to the latest Ecliptic
22−contract. Alternatively, the [ENS](https://ens.domains/) name `Ecliptic.eth`
23−will always resolve to the latest Ecliptic.
24−
25−You can read about [Urbit's first
26−upgrade](https://github.com/urbit/azimuth/pull/35) to Ecliptic, which occurred
27−in the summer of 2021, [here](https://urbit.org/blog/first-contract). The
28−[second](https://github.com/urbit/azimuth/pull/43) occurred later in the year
29−and consisted of several small modifications to ready the PKI for the
30−introduction of [naive rollups](/docs/azimuth/l2/layer2).
31−
32−`Ecliptic.eth` implements the [ERC-721](https://eips.ethereum.org/EIPS/eip-721)
33−interface for non-fungible tokens, as well as the
34−[ERC-165](https://eips.ethereum.org/EIPS/eip-165) standard for interface
35−detection.
36−
37−There are currently [28 functions](#write) which may be called to write to
38−the Ecliptic, and [17 functions](#read) to read data from the Ecliptic. Many of these
39−have a corresponding [layer 2 action](/docs/azimuth/l2/l2-actions), and/or can be
40−performed using [Bridge](/using/id/using-bridge). We note these facts where
41−applicable.
42−
43−## Write functions {% #write %}
44−
45−Here we briefly describe each function in `Ecliptic.eth` which allows one to write
46−data to Ethereum. These can be called using
47−[Etherscan](https://etherscan.io/address/ecliptic.eth#writeContract), but
48−the most common functions may be called from within Bridge.
49−
50−We only document here the write functions specific to `Ecliptic.eth` and not the
51−standard functions that are part of the ERC-721 or ERC-165 interfaces.
52−
53−### `Point`s interface
54−
55−These functions are available to each owner of a
56−[`Point`](/docs/azimuth/azimuth-eth#points), and a subset of them are available
57−to its [proxies](#proxies). All of these actions may be performed from Bridge.
58−
59−#### `configureKeys`
60−
61−```solidity
62− function configureKeys(uint32 _point,
63− bytes32 _encryptionKey,
64− bytes32 _authenticationKey,
65− uint32 _cryptoSuiteVersion,
66− bool _discontinuous)
67−```
68−
69−Configure `_point` with network public keys `_encryptionKey`,
70−`_authenticationKey`, and corresponding `_cryptoSuiteVersion`, incrementing the
71−`Point`'s [`keyRevisionNumber`](/docs/azimuth/azimuth-eth#points) if the keys
72−have changed and `continuityNumber` number if `_discontinuous` is set to true
73−(see [Life and Rift](/docs/azimuth/life-and-rift)).
74−
75−Corresponds to the layer 2 `%configure-keys` action.
76−
77−#### `spawn`
78−
79−```solidity
80− function spawn(uint32 _point, address _target)
81−```
82−
83−Spawn `_point`, then either give, or allow `_target` to take, ownership of `_point`.
84−
85−If `_target` is the `:msg.sender`, `_target` owns the `_point` right away.
86−otherwise, `_target` becomes the transfer proxy of `_point`.
87−
88−Requirements:
89−
90−- `_point` must not be active
91−- `_point` must not be a planet with a galaxy prefix
92−- `_point`'s prefix must be linked and under its spawn limit
93−- `:msg.sender` must be either the owner of `_point`'s prefix, or an authorized spawn proxy for it
94−
95−Corresponds to the layer 2 `%spawn` action.
96−
97−#### `transferPoint`
98−
99−```solidity
100− function transferPoint(uint32 _point, address _target, bool _reset)
101−```
102−
103−Transfer `_point` to `_target`, clearing all permissions data and keys if
104−`_reset` is true. `_reset` set to makes this transaction a
105−[breach](/using/id/guide-to-resets), and thus this action increments the
106−[`continuityNumber`](/docs/azimuth/azimuth-eth#points) of `_point`, and usually
107−the `keyRevisionNumber` as well (see [Life and
108−Rift](/docs/azimuth/life-and-rift)).
109−
110−Requirements:
111−
112−- `:msg.sender` must be either `_point`'s current owner, authorized to transfer
113− `_point`, or authorized to transfer the current owner's points (i.e. is
114− listed as an ERC-721 operator in [`operators`](/docs/azimuth/azimuth-eth#other)).
115−- `_target` must not be the zero address.
116−
117−Corresponds to the layer 2 `%transfer-point` action.
118−
119−#### `escape`
120−
121−```solidity
122− function escape(uint32 _point, uint32 _sponsor)
123−```
124−
125−Request escape as `_point` to `_sponsor`.
126−
127−If an escape request is already active, this overwrites the existing request.
128−
129−Requirements:
130−
131−- `:msg.sender` must be the owner or manager of `_point`,
132−- `_point` must be able to escape to `_sponsor` as per to `canEscapeTo()`
133−
134−Corresponds to the layer 2 `%escape` action.
135−
136−#### `cancelEscape`
137−
138−```solidity
139− function cancelEscape(uint32 _point)
140−```
141−
142−Cancel the currently set escape for `_point`.
143−
144−Corresponds to the layer 2 `%cancel-escape` action.
145−
146−#### `adopt`
147−
148−```solidity
149− function adopt(uint32 _point)
150−```
151−
152−As the relevant sponsor, accept the `_point`.
153−
154−Requirements:
155−
156−- `:msg.sender` must be the owner or management proxy
157− of `_point`'s requested sponsor
158−
159−Corresponds to the layer 2 `%adopt` action.
160−
161−#### `reject`
162−
163−```solidity
164− function reject(uint32 _point)
165−```
166−
167−As the relevant sponsor, deny the `_point`'s `%adopt` request.
168−
169−Requirements:
170−
171−- `:msg.sender` must be the owner or management proxy
172− of `_point`'s requested sponsor
173−
174−Corresponds to the layer 2 `%reject` action.
175−
176−#### `detach`
177−
178−```solidity
179− function detach(uint32 _point)
180−```
181−
182−As the `_sponsor`, stop sponsoring the `_point`.
183−
184−Requirements:
185−
186−- `:msg.sender` must be the owner or management proxy
187− of `_point`'s current sponsor
188−
189−Corresponds to the layer 2 `%detach` action.
190−
191−Unlike all other layer 1 actions, layer 1 sponsors may use a layer 1 `%detach` on
192−a layer 2 sponsee. See the [Layer 2](/docs/azimuth/l2/layer2#sponsorship)
193−section for more detail. The detach action available in Bridge is a layer 2
194−action, so a layer 1 detach must be done
195−[manually](https://etherscan.io/address/ecliptic.eth#writeContract).
196−
197−### Proxy management {% #proxies %}
198−
199−These functions are used to manage the various
200−[proxies](/docs/using/id/proxies). All of these actions may be performed from Bridge.
201−
202−#### `setManagementProxy`
203−
204−```solidity
205− function setManagementProxy(uint32 _point, address _manager)
206−```
207−
208−Configure the management proxy for `_point`.
209−
210−The management proxy may perform "reversible" operations on
211−behalf of the owner. This includes public key configuration and
212−operations relating to sponsorship.
213−
214−Requirements:
215−
216−- `:msg.sender` must be either `_point`'s current owner or the management proxy.
217−
218−Corresponds to the layer 2 `%set-management-proxy` action.
219−
220−#### `setSpawnProxy`
221−
222−```solidity
223− function setSpawnProxy(uint16 _prefix, address _spawnProxy)
224−```
225−
226−Give `_spawnProxy` the right to spawn points with the prefix `_prefix` using the
227−`spawn` function.
228−
229−Requirements:
230−
231−- `:msg.sender` must be either `_point`'s current owner or the spawn proxy.
232−
233−Corresponds to the layer 2 `%set-spawn-proxy` action.
234−
235−#### `setVotingProxy`
236−
237−```solidity
238− function setVotingProxy(uint8 _galaxy, address _voter)
239−```
240−
241−Configure the voting proxy for `_galaxy`.
242−
243−The voting proxy is allowed to start polls and cast votes on the point's behalf.
244−
245−Requirements:
246−
247−- `:msg.sender` must be either `_point`'s current owner or the voting proxy.
248−
249−There is no corresponding layer 2 action since voting must occur on layer 1.
250−
251−#### `setTransferProxy`
252−
253−```solidity
254− function setTransferProxy(uint32 _point, address _transferProxy)
255−```
256−
257−Give `_transferProxy` the right to transfer `_point`.
258−
259−Requirements:
260−
261−- `:msg.sender` must be either `_point`'s current owner, an operator for the
262− current owner, or the transfer proxy.
263−
264−Corresponds to the layer 2 `%set-transfer-proxy` action.
265−
266−### Poll actions
267−
268−Most of these are functions only available to galaxies. They are related to
269−[voting](/docs/glossary/voting). As voting does not occur on layer 2, there are
270−no corresponding layer 2 actions for poll actions.
271−
272−Upgrade and document polls last for 30 days, or once a majority is achieved,
273−whichever comes first. If a majority (129) of yes or no votes is achieved, the
274−final vote cast in favor of the winning option also triggers `updateUpgradePoll`
275−or `updateDocumentPoll` as appropriate. Otherwise, if a quorum of 64 votes is
276−achieved, with a majority voting for yes, and the 30 day voting period has
277−expired, then _any_ Ethereum address may call `updateUpgradePoll` or
278−`updateDocumentPoll` as appropriate.
279−
280−#### `startUpgradePoll`
281−
282−```solidity
283− function startUpgradePoll(uint8 _galaxy, EclipticBase _proposal)
284−```
285−
286−As `_galaxy`, start a poll for the Ecliptic upgrade `_proposal`.
287−
288−Requirements:
289−
290−- `:msg.sender` must be the owner or voting proxy of `_galaxy`,
291−- the `_proposal` must expect to be upgraded from this specific
292− contract, as indicated by its `previousEcliptic` attribute.
293−
294−This action must be performed manually - it is not available in Bridge.
295−
296−#### `startDocumentPoll`
297−
298−```solidity
299− function startDocumentPoll(uint8 _galaxy, bytes32 _proposal)
300−```
301−
302−As `_galaxy`, start a poll for the `_proposal`. Document polls last for 30 days,
303−or once a majority is achieved, whichever comes first.
304−
305−The `_proposal` argument is the keccak-256 hash of any arbitrary
306−document or string of text.
307−
308−This action must be performed manually - it is not available in Bridge.
309−
310−#### `castUpgradeVote`
311−
312−```solidity
313− function castUpgradeVote(uint8 _galaxy,
314− EclipticBase _proposal,
315− bool _vote)
316−```
317−
318−As `_galaxy`, cast a `_vote` on the Ecliptic upgrade `_proposal`.
319−
320−`_vote` is true when in favor of the proposal, false otherwise.
321−
322−This action may be performed from Bridge.
323−
324−#### `castDocumentVote`
325−
326−```solidity
327− function castDocumentVote(uint8 _galaxy, bytes32 _proposal, bool _vote)
328−```
329−
330−As `_galaxy`, cast a `_vote` on the `_proposal`.
331−
332−`_vote` is true when in favor of the proposal, false otherwise.
333−
334−This action may be performed from Bridge.
335−
336−#### `updateUpgradePoll`
337−
338−```solidity
339− function updateUpgradePoll(EclipticBase _proposal)
340−```
341−
342−Check whether the `_proposal` has achieved majority, upgrading to it if it has.
343−Any Ethereum address may call this function.
344−
345−This action eiher occurs as part of a vote that achieves a majority, or must be
346−performed manually. It is not available in Bridge.
347−
348−#### `updateDocumentPoll`
349−
350−```solidity
351− function updateDocumentPoll(bytes32 _proposal)
352−```
353−
354−Check whether the `_proposal` has achieved majority. Any Ethereum address may
355−call this function.
356−
357−This action eiher occurs as part of a vote that achieves a majority, or must be
358−performed manually. It is not available in Bridge.
359−
360−### Contract owner operations
361−
362−The following functions may only be performed by the owner of the contract.
363−There are only two such functions, one of which is to spawn galaxies. As all
364−galaxies have already been spawned, it is no longer of any use. Thus only
365−`setDnsDomains` is relevant today.
366−
367−#### `createGalaxy`
368−
369−```solidity
370− function createGalaxy(uint8 _galaxy, address _target)
371−```
372−
373−Grant `_target` ownership of the `_galaxy` and register it for voting. Galaxies
374−are given by a `uint8`, and since all 256 galaxies have already been spawned,
375−this function has no valid arguments.
376−
377−#### `setDnsDomains`
378−
379−```solidity
380− function setDnsDomains(string _primary, string _secondary, string _tertiary)
381−```
382−
383−Sets 3 DNS domains by which galaxy IP addresses may be looked up as part of the
384−bootstrap process to get on the network. Currently, all three domains are `urbit.org`.
385−
386−## Read functions {% #read %}
387−
388−Here we briefly describe each function in the Ecliptic which allows one to read
389−data from the contract. These can be called using
390−[Etherscan](https://etherscan.io/address/ecliptic.eth#readContract).
391−
392−We only document here the read functions specific to Ecliptic and not the
393−standard functions that are part of the ERC-721 or ERC-165 interfaces.
394−
395−#### `depositAddress`
396−
397−This returns the deposit address for [layer 2](/docs/azimuth/l2/layer2), which is
398−`0x1111111111111111111111111111111111111111`. Ships sent to this address are
399−controlled on layer 2 instead of via Ecliptic.
400−
401−#### `canEscapeTo`
402−
403−```solidity
404− function canEscapeTo(uint32 _point, uint32 _sponsor)
405−```
406−
407−Returns a `bool` that is true if `_point` could try to escape to `_sponsor`.
408−
409−#### `azimuth`
410−
411−Returns the address of the [Azimuth.eth](/docs/azimuth/azimuth-eth) contract: `0x223c067f8cf28ae173ee5cafea60ca44c335fecb`.
412−
413−#### `claims`
414−
415−Returns the address of the
416−[Claims](https://etherscan.io/address/0xe7e7f69b34d7d9bd8d61fb22c33b22708947971a)
417−contract: `0x1df4ea30e0b1359c9692a161c5f30cd1a6b64ebf`.
418−
419−#### `polls`
420−
421−Returns the address of the
422−[Polls](https://etherscan.io/address/0x7fecab617c868bb5996d99d95200d2fa708218e4)
423−contract: `0x7fecab617c868bb5996d99d95200d2fa708218e4`.
424−
425−#### `previousEcliptic`
426−
427−Returns the address of the previous Ecliptic address.
428−
429−#### `getSpawnLimit`
430−
431−```solidity
432− function getSpawnLimit(uint32 _point, uint256 _time)
433−```
434−
435−Returns a `uint32` that is the total number of children the `_point` is allowed
436−to spawn at `_time`.
437−
438−There is no limit for galaxies. Instead, for most galaxies, all stars have
439−already been spawned and placed into one of the lockup contracts: [Linear Star
440−Release](https://etherscan.io/address/0x86cd9cd0992f04231751e3761de45cecea5d1801)
441−and [Conditional Star
442−Release](https://etherscan.io/address/0x8c241098c3d3498fe1261421633fd57986d74aea).
443−
444−Beginning in 2019, stars may spawn at most 1024 planets. This limit doubles
445−every subsequent year until the maximum is reached. However, this limit is not
446−currently implemented on [Layer 2](/docs/azimuth/l2/layer2).
content/docs/azimuth/flow.mddeleted−232
@@ -1,232 +0,0 @@
1−+++
2−title = "Azimuth Data Flow"
3−weight = 4
4−template = "doc.html"
5−+++
6−
7−This document summarizes the various components involved with Azimuth and
8−how they communicate with each other. This also constitutes an explanation for
9−how Urbit implements the data flow of naive rollups.
10−
11−## Bridge
12−
13−The primary way in which users interact with Azimuth is via
14−[Bridge](https://bridge.urbit.org). Bridge is responsible for collecting
15−transactions from users, signing them, and forwarding them to a roller via an
16−HTTP API.
17−
18−## Azimuth
19−
20−Azimuth was originally defined as a set of smart contracts on Ethereum that
21−defines the [state](/docs/azimuth/azimuth-eth) and [business
22−logic](/docs/azimuth/ecliptic) of the PKI for layer 1. With the introduction of
23−naive rollups, this has also come to include the set of components used for
24−dealing with the PKI within Urbit, as now the complete PKI state is stored
25−offchain (though this state is derived entirely from on-chain data). The
26−following sections outline what each component is responsible for and how it
27−communicates with the others.
28−
29−The Gall agents involved with Azimuth are summarized as follows:
30−
31−- [`%azimuth`](#azimuth) - obtains and holds PKI state.
32−- [`%azimuth-rpc`](#azimuth-rpc) - JSON RPC-API for `%azimuth`.
33−- [`%eth-watcher`](#eth-watcher) - Ethereum event log collector.
34−- [`%roller`](#roller) - submits batches of L2 transactions to Ethereum.
35−- [`%roller-rpc`](#roller-rpc) - JSON RPC-API for `%roller`.
36−
37−The transaction processing library is [`/lib/naive.hoon`](#naive).
38−
39−### Gall agents
40−
41−#### `%azimuth` {% #azimuth %}
42−
43−`%azimuth`, located at `/app/azimuth.hoon`, is a Gall agent and thread handler
44−responsible for finding Azimuth transactions gathered by `%eth-watcher`,
45−keeping track of the PKI state, and exposing that data via scries.
46−
47−The following diagram illustrates `%azimuth`'s and `%eth-watcher`'s role in the system.
48−
49−![Azimuth components](https://media.urbit.org/docs/layer2/l2-azimuth-azimuth.svg)
50−
51−The state held by `%azimuth` is the following.
52−
53−```hoon
54−++ app-state
55− $: %3
56− url=@ta
57− whos=(set ship)
58− nas=^state:naive
59− own=owners
60− logs=(list =event-log:rpc:ethereum)
61− ==
62−```
63−
64−`whos` is the set of ships currently known by Azimuth. `nas` is the PKI state,
65−as defined in [`naive.hoon`](#naive). `own` is a `jug` of Ethereum addresses and
66−the set of ships owned by that address. `logs` is a list of all Azimuth-related
67−Ethereum event logs known by the ship.
68−
69−Scries can be inferred from the `+on-peek` arm:
70−
71−```hoon
72−++ on-peek
73− |= =path
74− ^- (unit (unit cage))
75− ?+ path (on-peek:def path)
76− [%x %logs ~] ``noun+!>(logs.state)
77− [%x %nas ~] ``noun+!>(nas.state)
78− [%x %dns ~] ``noun+!>(dns.nas.state)
79− [%x %own ~] ``noun+!>(own.state)
80− ==
81−```
82−
83−#### `%azimuth-rpc` {% #azimuth-rpc %}
84−
85−`%azimuth-rpc`, located at `app/azimuth-rpc.hoon`, is a JSON RPC-API for getting
86−`point` and `dns` data from the Azimuth PKI state kept by `%azimuth`.
87−
88−#### `%eth-watcher` {% #eth-watcher %}
89−
90−`%eth-watcher`, located at `/app/eth-watcher.hoon`, is responsible for listening
91−to an Ethereum node and collecting event logs from it. It is general-purpose and
92−not particular to Azimuth. It sends collected transactions to `+on-agent` in
93−`%azimuth`, which then obtains the resulting PKI state transitions by passing them to
94−[`naive.hoon`](#naive).
95−
96−[![Eth-watcher](https://media.urbit.org/docs/layer2/roller-agents.png)](https://media.urbit.org/docs/layer2/roller-agents.png)
97−
98−#### `%roller` {% #roller %}
99−
100−`%roller`, stored at `/app/roller.hoon`, is a Gall agent responsible for
101−collecting and submitting batches of layer 2 transactions to the Ethereum
102−blockchain. Among other things, it keeps
103−track of a list of pending transactions to be sent, transactions it has sent
104−that are awaiting confirmation, history of transactions sent organized by
105−Ethereum address, and when the next batch of transactions will be sent. See also
106−[Rollers](/docs/azimuth/l2/roller) for more information on the roller.
107−
108−The following diagram illustrates how the roller interacts with Bridge and
109−Ethereum at a high level.
110−
111−[![High level overview](https://media.urbit.org/docs/layer2/l2-high.png)](https://media.urbit.org/docs/layer2/l2-high.png)
112−
113−The relationship between the roller and other agents is outlined in the
114−following diagram.
115−
116−[![Roller](https://media.urbit.org/docs/layer2/roller-agents.png)](https://media.urbit.org/docs/layer2/roller-agents.png)
117−
118−`%roller` has a number of scries available, intended primarily to
119−display data to the end user in Bridge. They can be inferred from the `+on-peek`
120−arm:
121−
122−```hoon
123− ++ on-peek
124− |= =path
125− ^- (unit (unit cage))
126− |^
127− ?+ path ~
128− [%x %pending ~] ``noun+!>(pending)
129− [%x %pending @ ~] (pending-by i.t.t.path)
130− [%x %tx @ %status ~] (status i.t.t.path)
131− [%x %history @ ~] (history i.t.t.path)
132− [%x %nonce @ @ ~] (nonce i.t.t.path i.t.t.t.path)
133− [%x %spawned @ ~] (spawned i.t.t.path)
134− [%x %next-batch ~] ``atom+!>(next-batch)
135− [%x %point @ ~] (point i.t.t.path)
136− [%x %points @ ~] (points i.t.t.path)
137− [%x %config ~] config
138− [%x %chain-id ~] ``atom+!>(chain-id)
139− ==
140−```
141−
142−This app is not responsible for communicating with Bridge via HTTP. Instead, that is
143−handled by `%roller-rpc`. The scries are also communicated to Bridge via
144−`%roller-rpc`.
145−
146−#### `%roller-rpc`
147−
148−`%roller-rpc`, stored at `/app/roller-rpc.hoon`, is a very simple Gall app responsible for receiving HTTP RPC-API
149−calls, typically sent from other Urbit ID users via Bridge. It then translates
150−these API calls from JSON to a format understood by `%roller` and
151−forwards them to `%roller`. This app
152−does not keep any state - its only purpose is to act as an intermediary between
153−Bridge and `%roller`. See [here](/docs/azimuth/l2/layer2-api) for more
154−information on the JSON RPC-API.
155−
156−### `naive.hoon` {% #naive %}
157−
158−`/lib/naive.hoon` consists of a gate whose sample is a `verifier`, `chain-id=@ud`,
159−`state`, and `input`, which outputs a cell of `[effects state]`. This is the
160−transition function which updates the state of the PKI stored in `%azimuth`
161−which handles state transitions caused by both layer 1 and layer 2 transactions.
162−A high-level overview of how `naive.hoon` functions can be found
163−[here](/docs/azimuth/l2/layer2#layer-2).
164−
165−A `verifier` is a gate whose sample is of the form `[dat=octs v=@ r=@ s=@]` and
166−which returns `(unit address)`:
167−
168−```hoon
169−+$ verifier $-([dat=octs v=@ r=@ s=@] (unit address))
170−```
171−
172−The `verifier` in use by `naive.hoon` runs the keccak hash function on `dat` to
173−verify that `dat` is data signed by the ECDSA signature given by the `[v r s]`
174−tuple, according to the format for signed transactions outlined in the
175−[bytestring format](/docs/azimuth/l2/bytestring) documentation.
176−
177−`chain-id` is the ID used by the Ethereum blockchain, which is `1337`. See [bytestring
178−format](/docs/azimuth/l2/bytestring) for more information. This is used so that
179−e.g. transactions on the Ropsten test network cannot be replayed on the mainnet.
180−
181−`state` is the current state of the PKI. This is structured similarly to the
182−state held in [Azimuth.eth](/docs/azimuth/azimuth-eth), but will differ in
183−general since `state` takes into account layer 2 transactions as well. See the
184−[Layer 2 Overview](/docs/azimuth/l2/layer2#state) for more on how PKI state is handled.
185−
186−```hoon
187−+$ state
188− $: =points
189− =operators
190− dns=(list @t)
191− ==
192−+$ points (tree [ship point])
193−++ point
194− $: :: domain
195− ::
196− =dominion
197− ::
198− :: ownership
199− ::
200− $= own
201− $: owner=[=address =nonce]
202− spawn-proxy=[=address =nonce]
203− management-proxy=[=address =nonce]
204− voting-proxy=[=address =nonce]
205− transfer-proxy=[=address =nonce]
206− ==
207− ::
208− :: networking
209− ::
210− $= net
211− $: rift=@ud
212− =keys
213− sponsor=[has=? who=@p]
214− escape=(unit @p)
215− ==
216− ==
217−+$ dominion ?(%l1 %l2 %spawn)
218−+$ operators (jug address address)
219−```
220−
221−`points` should be self-explanatory if you are already familiar with the
222−structure of [Azimuth.eth](/docs/azimuth/azimuth-eth). The only new addition is
223−`dominion`, whose value says
224−whether a ship is on layer 1, layer 2, or layer 1 with a layer 2 spawn proxy.
225−See [Layer 2 actions](/docs/azimuth/l2/l2-actions) for an overview of how
226−`dominion` determines the PKI actions available to a ship.
227−
228−`operators` already existed on layer 1 and are defined as a part of the [ERC-721
229−standard](https://eips.ethereum.org/EIPS/eip-721).
230−
231−`dns` is a list of DNS entries by which galaxy IP addresses may be looked up. At
232−present, this is always `~['urbit.org' 'urbit.org' 'urbit.org']`.
content/docs/azimuth/hd-wallet.mddeleted−137
@@ -1,137 +0,0 @@
1−+++
2−title = "Urbit HD Wallet"
3−weight = 3
4−template = "doc.html"
5−+++
6−
7−Owners of Urbit identities need safeguards that allow for the use of Urbit
8−without jeopardizing cryptographic ownership of their assets. Toward this end,
9−we created the **Urbit Hierarchical Deterministic (HD) Wallet** for the storage
10−of identities. The Urbit HD Wallet is not one key-pair, but a system of related
11−key-pairs that each have distinct powers, from setting networking keys for
12−communicating in the Arvo network to transferring ownership of identities.
13−
14−The Urbit HD Wallet's derivation paths have a hierarchical structure, so that
15−keys with different powers can be physically separated. A "master ticket" can
16−[re-derive the entire wallet](#hd-wallet-generation) in case of loss. The
17−encryption and authentication keys that identities ships use to sign messages
18−within the network are also derived from the wallet.
19−
20−Another HD wallet option you may wish to utilize to store your Urbit are
21−hardware wallets such as Trezor or Ledger. We compare this method to the Urbit
22−HD wallet [below](#hardware-hd-wallet).
23−
24−Urbit HD wallets are composed of the following items, which are each assigned to
25−their own individual Ethereum key-pairs.
26−
27−### Master Ticket
28−
29−Think of your master ticket like a very high-value password. The master ticket
30−is the secret code from which all of your other keys are derived. Technically,
31−your master ticket is a cryptographic seed. You should never share it with anyone, and
32−store it very securely. This ticket can derive all of your other keys: your
33−ownership key and all of the related proxies.
34−
35−### Ownership Address
36−
37−An ownership address has all rights over the assets deeded to it. These rights
38−are on-chain actions described and implemented in
39−[Ecliptic](/docs/glossary/ecliptic), Azimuth's suite of governing
40−smart-contracts.
41−
42−### Proxies
43−
44−Each permanent Urbit ID can designate one or more
45−[proxies](/docs/using/id/proxies), which are Ethereum addresses capable of a
46−limited subset of Urbit ID transactions, such as spawning planets or rotating
47−keys. The HD wallet automatically generates additional addresses utilized as
48−proxies according to what is appropriate for your Urbit ID.
49−
50−### HD wallet generation
51−
52−Your Urbit HD wallet is generated from a `@q` seed called `T`, which looks
53−something like `~sampel-ticket-bucbel-sipnem`. This is the string known as your
54−"Master Ticket" that you input into Bridge to sign in. This is put through a
55−series of algorithms that ultimately generate your keys and the Ethereum
56−addresses at which they are stored.
57−
58−![](https://media.urbit.org/fora/proposals/UP-8.jpg)
59−
60−First, your `@q` is converted into a numeric value `E` as an intermediary step
61−by adding [salt](<https://en.wikipedia.org/wiki/Salt_(cryptography)>). Then by
62−adding additional salts, `E` is converted into a set of BIP39 seed phrases -
63−these are 24 word mnemonic sequences used to generate Ethereum wallets. You end
64−up with one seed phrase for each proxy associated with your ship, and these seed
65−phrases are then used to generate Ethereum wallets.
66−
67−One of the wallets will store your Azimuth point, an [ERC-721](#erc-721) token,
68−which will be known as your ownership address. Bridge then automatically uses
69−your ownership address to assign the other proxies to the other wallets
70−generated.
71−
72−### ERC-721
73−
74−Most Ethereum tokens use the ERC-20 standard for smart contracts. Urbit
75−identities are, however, essentially different from most Ethereum tokens, due to
76−identities not being fungible. Since any two stars will handle social-networking
77−realities in a different way, they will carry a different reputation.
78−
79−The ERC-721 standard, having been made specifically to provide a smart-contract
80−interface for non-fungible assets, serves our needs well. This is the standard
81−that we use for deeding Urbit identities.
82−
83−Identities, and all of their blockchain operations, are governed by Ecliptic.
84−Ecliptic is an Ethereum smart-contract that governs identity state and the
85−ownership, spawn, management, and voting rights affiliated with your identities.
86−
87−For the technical implementation details, take a look at Azimuth's [Github
88−repository](https://github.com/urbit/azimuth).
89−
90−## Hardware HD wallet
91−
92−You may also store your Urbit using a hardware HD wallet such as a Trezor or
93−Ledger. This option is used instead of a master ticket - it is a totally
94−separate process from that outlined above. How hardware wallets work are outside
95−of the scope of this document, but here we explain how you may utilize your
96−hardware wallet in a similar fashion to the Urbit HD wallet.
97−
98−A hardware HD wallet is generated from a seed phrase that should be thought of
99−as analogous to the `@q` `T` used to generate the Urbit HD wallet in the above
100−diagram. This seed phrase is a human readable sequence of words that may be used
101−to generate private keys to a near-limitless number of wallets created by adding
102−salt. Some hardware wallets also allow an additional passphrase to go into the
103−generation of these wallets. The seed phrase and passphrase should be considered
104−equal in value to the master ticket `T`- never share these with anyone!
105−
106−In order to use your hardware wallet as your Urbit wallet, you first need to
107−generate a set of addresses on which you would like to store your Azimuth point
108−and proxies. Consult your wallet vendor on how to do this. Then login to Bridge
109−using your current method (likely a master ticket) and transfer ownership to the
110−wallet address you generated on your hardware wallet for ownership.
111−
112−Next, login to Bridge using your hardware wallet. While Bridge supports Trezor
113−and Ledger natively, this may require using Metamask as an intermediary anyways,
114−depending on which firmware you are running. Then [accept the
115−transfer](/using/id/using-bridge#accept-your-transfer). Your Azimuth point is
116−now stored on your hardware wallet.
117−
118−To finish the process, use Bridge to set your management, voting, and spawn
119−proxies to the other addresses you generated as applicable. You are now using
120−your hardware HD wallet in an analogous fashion to the Urbit HD wallet.
121−
122−## Heightened security practices
123−
124−A common security pattern is to have "hot" and "cold" wallets. For higher value
125−points such as stars and galaxies, you may consider having your ownership
126−address live on a "cold" wallet that never touches an internet-connected
127−computer, and the various proxies on a "hot" wallet that is permitted to connect
128−to internet-connected devices. This could be accomplished with multiple hardware
129−wallets, a combination of paper and hardware wallet, a hardware cold wallet and
130−Metamask hot wallet, etc. See the [User Manual](/using/id/hd-wallet) for
131−concrete suggestions on security practices.
132−
133−One tool useful for this setup is `claz`, located at `app/claz.hoon`. `claz` is
134−used for making and signing Bridge transactions from an offline computer. A
135−guide to using `claz` is available [here](/docs/azimuth/advanced-azimuth-tools).
136−
137−
content/docs/azimuth/l2/_index.mddeleted−39
@@ -1,39 +0,0 @@
1−+++
2−title = "Layer 2"
3−weight = 800
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−insert_anchor_links = "right"
7−+++
8−
9−Documentation of the technical details of naive rollups, our Layer 2 solution
10−for the reduction of Urbit ID gas prices and friction associated with the usage
11−of cryptocurrency.
12−
13−### [Layer 2 Overview](/docs/azimuth/l2/layer2)
14−
15−A high-level technical description of the functionality of the naive rollups
16−"Hoon smart contract" and associated apps, such as Bridge and the roller.
17−
18−### [Layer 2 Actions](/docs/azimuth/l2/l2-actions)
19−
20−An exhaustive list of what Azimuth actions can be performed for any given tuple
21−`(ship rank, layer 2 status)`.
22−
23−### [Transaction Format](/docs/azimuth/l2/bytestring)
24−
25−The bytestring format for layer 2 transactions and batches.
26−
27−### [Rollers](/docs/azimuth/l2/roller)
28−
29−How rollers work.
30−
31−### [Roller HTTP RPC API](/docs/azimuth/l2/layer2-api)
32−
33−Documentation on the HTTP RPC API used for Urbit to communicate with Bridge to
34−manage layer 2 transactions.
35−
36−### [Custom Roller Tutorial](/docs/azimuth/l2/roller-tutorial)
37−
38−How to set up your own roller.
39−
content/docs/azimuth/l2/bytestring.mddeleted−201
@@ -1,201 +0,0 @@
1−+++
2−title = "Transaction Format"
3−weight = 8
4−template = "doc.html"
5−+++
6−
7−This document gives the bytestring format for layer 2 transactions and batches.
8−
9−[Recall](/docs/azimuth/l2/layer2.md) that a layer 2 transaction is a compact
10−representation of an Azimuth action (format given below), along with a 65-byte
11−ECDSA signature. A `batch` is an atom that is a concatenation of one or more
12−layer 2 transactions and associated signatures. This atom is what is posted on
13−the Ethereum blockchain by a roller.
14−
15−We remark that each transaction from a given ship in a batch needs a separate
16−signature, since data such as the nonce are not included in the transaction but
17−are used in the signature. Thus a ship cannot submit multiple transactions with
18−a single signature for all of them - a different signature is needed for each
19−transaction.
20−
21−## Byte format
22−
23−We describe the byte format of a `batch` and its components in the following.
24−All atoms described here are read by the parser as little-endian - i.e. it reads
25−the last digit first and proceeds backwards.
26−
27−For the purposes of concatenation, all atoms are encoded using `octs=(pair @ud @)`, which is a way to represent atoms with a fixed width in order to account
28−for leading zeroes. Here `@ud` will be the length of the atom in bytes, while
29−the `@` is actual atom.
30−
31−### Batches {% #batch %}
32−
33−A `batch` is an atom that is the concatenation of several raw transactions,
34−which are themselves atoms. `naive.hoon` starts reading the `batch` from the end
35−and working backwards (little-endian). A `batch` looks like:
36−
37−```
38−action-n
39−signature-n
40−action-(n-1)
41−signature-(n-1)
42−...
43−action-2
44−signature-2
45−action-1
46−signature-1
47−```
48−
49−Be careful to distinguish between an "action" and an "unsigned transaction". An
50−action is a short bytestring that describes an Azimuth action as given in the
51−[following section](#actions), while an unsigned transaction is an action plus
52−the nonce, chain ID, header. Actions are what are submitted to Ethereum, while
53−unsigned transactions are what are signed and used as the signatures in the
54−above `batch` format. When `naive.hoon` parses a batch it adds the appropriate
55−nonce, chain ID, and header to a given action and uses that to verify the
56−corresponding signature, rather than just the action itself. This reduces the
57−number of bytes in the batch, making transactions cheaper.
58−
59−### Actions {% #actions %}
60−
61−The byte format of an action as they appear in a `batch` is as
62−follows. They are parsed by the `+parse-tx` arm in `naive.hoon`.
63−
64−```
65−remainder: arguments
66−7 bits: operation
67−4 bytes: ship sending the transaction
68−5 bits: padding
69−3 bits: proxy
70−```
71−
72−The `proxy` is an atom between `0` and `4`, which corresponds as follows:
73−
74−```
75−%0 %own
76−%1 %spawn
77−%2 %manage
78−%3 %vote
79−%4 %transfer
80−```
81−
82−Note that `%vote` proxies are not supported by layer 2.
83−
84−The ship is its `@p` encoded as an `@`. As we are working with fixed width
85−atoms, the full 4 bytes is used, even if the bit length of the `@p` is shorter.
86−
87−The operation is an atom between `0` and `10` corresponding as follows:
88−
89−```
90−%0 %transfer-point
91−%1 %spawn
92−%2 %configure-keys
93−%3 %escape
94−%4 %cancel-escape
95−%5 %adopt
96−%6 %reject
97−%7 %detach
98−%8 %set-management-proxy
99−%9 %set-spawn-proxy
100−%10 %set-transfer-proxy
101−```
102−
103−Since the operation is represented with 7 bits, to complete the byte the
104−arguments either use the remaining bit as a binary flag or as padding.
105−
106−#### `%transfer-point`
107−
108−```
109−20 bytes: address to transfer to
110−1 bit: breach?
111−```
112−
113−#### `%spawn`
114−
115−As before, the length of the ship argument is always 4 bytes.
116−
117−```
118−20 bytes: address to set transfer proxy of spawned ship to
119−4 bytes: ship to spawn
120−1 bit: padding
121−```
122−
123−#### `%configure-keys`
124−
125−```
126−4 bytes: crypto suite
127−32 bytes: encryption public key
128−32 bytes: authentication public key
129−1 bit: breach?
130−```
131−
132−#### `%escape`, `%cancel-escape`, `%adopt`, `%reject`, `%detach`
133−
134−Each of these actions have the same argument - a single ship. Again, the length
135−of the ship argument is always 4 bytes.
136−
137−```
138−4 bytes: ship
139−1 bit: padding
140−```
141−
142−#### `%set-management-proxy`, `%set-spawn-proxy`, `%set-transfer-proxy`
143−
144−Each of these actions have the same argument - an Ethereum address:
145−
146−```
147−20 bytes: address
148−1 bit: padding
149−```
150−
151−### Unsigned transactions {% #unsigned %}
152−
153−An unsigned transaction is an atom consisting of the concatentation of an Ethereum signed
154−message header, an Urbit ID header, a chain ID, a nonce, and an action. This has the following format:
155−
156−```hoon
157−%: cad 3
158− 26^'\19Ethereum Signed Message:\0a'
159− (met 3 len)^len
160− 14^'UrbitIDV1Chain'
161− (met 3 chain-t)^chain-t
162− 1^':'
163− 4^nonce
164− action
165− ~
166−==
167−```
168−
169−Here `+cad` is a gate in `/lib/tiny.hoon` that concatenates atoms given in `octs` format. The
170−argument `3` is a `bloq` size meaning `2^3=8` bits (one byte), and the head of
171−each cell (which are `octs`) in the arguments that follow is the number of blocks (number of bytes
172−in this scenario) of each entry, with the tail being the actual data.
173−
174−`len` is the length measured in bytes of everything following it except the
175−signature. `chain-t` is the chain ID, which is to distinguish between e.g. the
176−Ethereum test net and main net, to ensure that transaction used in one cannot be
177−rebroadcast on the other (see
178−[EIP-155](https://eips.ethereum.org/EIPS/eip-155)). We note that `len` and
179−`chain-t` are both ASCII decimals (`@t` in Hoon), while `nonce` and `action` are
180−`@ud`s.
181−
182−Again we emphasize that unsigned transactions are _not_ what is submitted in a
183−batch - an [action](#actions) and a [signature](#signatures) are. A ship
184−submitting a layer 2 transaction to a roller signs an unsigned transaction and
185−this signature is included along with the action, which does not include the
186−additional data listed above. When a ship determines whether or not a given
187−layer 2 action is valid, it adds the additional data to the action to form an
188−unsigned transaction and verifies the signature against that.
189−
190−### Signatures {% #signatures %}
191−
192−The signature is a 65-byte ECDSA signature as described in
193−[EIP-191](https://eips.ethereum.org/EIPS/eip-191) and is compatible with
194−`personal_sign`. The precise format of the signature depends on which wallet was
195−used to sign it. Layer 2 supports all major signature formats, including
196−Metamask, Trezor, Ledger, and others. Signatures in batches are obtained by signing
197−an [unsigned transaction](#unsigned).
198−
199−Because of the format of signatures, it may have leading zeroes resulting in a
200−64-byte signature, and so it is important to use `octs` to ensure that it is
201−interpreted as being 65 bytes.
content/docs/azimuth/l2/l2-actions.mddeleted−183
@@ -1,183 +0,0 @@
1−+++
2−title = "Layer 2 Actions"
3−weight = 6
4−template = "doc.html"
5−+++
6−
7−There are a total of eleven layer 2 actions, each corresponding to a familiar
8−[layer 1 action](/docs/azimuth/ecliptic): `%transfer-point`, `%spawn`,
9−`%configure-keys`, `%escape`, `%cancel-escape`, `%adopt`, `%reject`, `%detach`,
10−`%set-management-proxy`, `%set-spawn-proxy`, and `%set-transfer-proxy`.
11−Descriptions of what these actions do may be found by searching for them at
12−[Azimuth.eth](/docs/azimuth/azimuth-eth).
13−
14−Once a ship moves to layer 2, the owner will still utilize the same private keys
15−they used before the transfer to perform Azimuth actions. This includes the ownership
16−key as well as proxies. Stars and galaxies may move their spawn proxy to layer 2
17−while otherwise remaining on layer 1, but it is not possible to transfer only
18−the management proxy to layer 2; it may only happen as a side-effect of
19−transferring ownership to layer 2.
20−
21−### Moving a pre-existing ship to L2
22−
23−In order to move your ship from layer 1 to layer 2, transfer ownership of your
24−ship to the address `0x1111111111111111111111111111111111111111`. The easiest
25−way to accomplish this is using [Bridge](/docs/glossary/bridge). The Azimuth
26−smart contracts interpret any ship at this address as being on layer 2.
27−
28−### Dominion
29−
30−Layer 2 Azimuth data for a given ship includes which layer that ship is on. We
31−call this the ship's _dominion_. There are three dominions: `%l1`, `l2`, and
32−`%spawn`. Planets may exist in dominion `%l1` or `%l2`, stars may exist in any
33−of the three dominions, and galaxies may exist in dominion `%l1` or `%spawn`. We
34−detail what this means in each case in the following.
35−
36−### Planets
37−
38−*Permitted dominions:* `%l1`, `%l2`.
39−
40−#### `%l1` planets
41−
42−*Permitted layer 2 actions:*
43− - owner: `%escape`, `%cancel-escape`
44− - management proxy: `%escape`, `%cancel-escape`
45− - transfer proxy: none
46−
47−A planet in dominion `%l1` is said to exist on layer 1, which is the default
48−state for all planets prior to the introduction of naive rollups. In addition to
49−the ordinary layer 1 Azimuth actions a planet can perform, they may also choose to
50−`%escape` or `%cancel-escape` on layer 2 using either their ownership key or
51−[management proxy](/docs/glossary/proxies). See the [layer 2 sponsorship](/docs/azimuth/l2/layer2#sponsorship)
52−section for more information on layer 1 ships performing layer 2
53−sponsorship actions.
54−
55−Layer 1 planets may also move to dominion `%l2` by depositing their ownership to
56−the layer 2 deposit address.
57−
58−#### `%l2` planets
59−
60−*Permitted layer 2 actions:*
61− - owner: `%transfer-point`, `%configure-keys`,
62−`%escape`, `%cancel-escape`, `%set-management-proxy`, `%set-transfer-proxy`
63− - management proxy: `%configure-keys`, `%escape`, `%cancel-escape`,
64−`%set-management-proxy`
65− - transfer proxy: `%transfer-point`, `%set-transfer-proxy`
66−
67−A planet in dominion `%l2` is said to exist on layer 2. A planet may be on layer
68−2 either by previously being a layer 1 planet deposited to the layer 2 address,
69−or by being spawned by a star in dominion `%spawn` or `%l2`, in which case it
70−will always be on layer 2.
71−
72−A layer 2 planet is no longer capable of performing any layer 1 actions, and
73−cannot move to layer 1.
74−
75−### Stars
76−
77−*Permitted dominions:* `%l1`, `%spawn`, `%l2`.
78−
79−#### `%l1` stars
80−
81−*Permitted layer 2 actions:*
82− - owner: `%escape`, `%cancel-escape`, `%adopt`,
83−`%reject`, `%detach`
84− - management proxy: `%escape`, `%cancel-escape`, `%adopt`,
85−`%reject`, `%detach`
86− - spawn proxy: none
87− - transfer proxy: none
88−
89−A star in dominion `%l1` is said to exist on layer 1, which is the default state
90−for all stars prior to the introduction of naive rollups. In addition to the
91−ordinary Azimuth actions a star can perform, they may also perform any
92−sponsorship-related actions on layer 2.
93−
94−A `%l1` dominion star may move to dominion `%spawn` by depositing its spawn proxy to the
95−layer 2 deposit address, or may move to dominion `%l2` by depositing its ownership
96−to the layer 2 deposit address. Both actions are irreversible.
97−
98−#### `%spawn` stars
99−
100−*Permitted layer 2 actions:*
101− - owner: `%escape`, `%cancel-escape`, `%adopt`,
102−`%reject`, `%detach`, `%spawn`, `%set-spawn-proxy`
103− - management proxy: `%escape`,
104−`%cancel-escape`, `%adopt`, `%reject`, `%detach`
105− - spawn proxy: `%spawn`,
106−`%set-spawn-proxy`
107− - transfer proxy: none
108−
109−A star in dominion `%spawn` is said to exist on layer 1.
110−
111−A star in dominion `%spawn` may spawn planets directly on layer 2, but will no
112−longer be able to spawn layer 1 planets and will no longer be able to set its
113−spawn proxy on layer 1. All other layer 1 Azimuth actions may still be performed
114−by the star.
115−
116−A star moving from `%l1` to `%spawn` has no effect on sponsorship status of any
117−of its sponsored planets. Moving to `%spawn` from `%l1` is currently
118−irreversible - the only further change to dominion permitted is moving to `%l2`.
119−
120−#### `%l2` stars
121−
122−*Permitted layer 2 actions:*
123− - owner: `%transfer-point`, `%spawn`, `%configure-keys`, `%escape`,
124−`%cancel-escape`, `%adopt`, `%reject`, `%detach`, `%set-management-proxy`,
125−`%set-spawn-proxy`,`%set-transfer-proxy`
126− - management proxy: `%escape`,
127−`%cancel-escape`, `%adopt`, `%reject`, `%detach`, `%configure-keys`,
128−`%set-management-proxy`
129− - spawn proxy: `%spawn`, `%set-spawn-proxy`
130− - transfer proxy: `%transfer-point`, `%set-transfer-proxy`
131−
132−A star in dominion `%l2` is said to exist on layer 2. A star may exist on layer
133−2 by being deposited to the layer 2 deposit address from layer 1, or by being
134−spawned by a `%spawn` dominion galaxy.
135−
136−A star in dominion `%l2` cannot perform any layer 1 actions.
137−
138−### Galaxies
139−
140−*Permitted dominions:* `%l1`, `%spawn`.
141−
142−#### `%l1` galaxies
143−
144−*Permitted layer 2 actions:*
145− - owner: `%adopt`, `%reject`, `%detach`
146− - management proxy: `%adopt`, `%reject`, `%detach`
147− - spawn proxy: none
148− - transfer proxy: none
149− - voting proxy: none.
150−
151−A galaxy in dominion `%l1` is said to exist on layer 1, which is the default state
152−for all galaxies prior to the introduction of naive rollups. In addition to the
153−ordinary Azimuth actions a galaxy can perform, they may also perform any
154−sponsorship-related actions on layer 2. `%l1` galaxies can perform all the usual
155−layer 1 Azimuth actions, and may also perform layer 2 sponsorship actions.
156−
157−A `%l1` dominion galaxy may move to dominion `%spawn` by depositing its spawn proxy to the
158−layer 2 deposit address. This action is irreversible. Note, however that the
159−majority of galaxies already have all of their stars spawned in the [Linear
160−Star Release
161−Contract](https://etherscan.io/address/0x86cd9cd0992f04231751e3761de45cecea5d1801).
162−Layer 2 has no interactions with this contract - all stars released in this
163−manner are `%l1` dominion stars. Moving to the `%spawn` dominion has no effect
164−on sponsorship status.
165−
166−#### `%spawn` galaxies
167−
168−*Permitted layer 2 actions:*
169− - owner: `%adopt`, `%reject`, `%detach`, `%spawn`,
170−`%set-spawn-proxy`
171− - management proxy: `%adopt`, `%reject`, `%detach`
172− - spawn proxy: `%spawn`, `%set-spawn-proxy`
173− - transfer proxy: none
174− - voting proxy: none
175−
176−Galaxies may either remain on layer 1, or, similar to stars, they may
177−deposit their spawn proxy to layer 2. They cannot move their ownership,
178−management proxy, or voting proxy to layer 2. However, as with stars,
179−sponsorship actions may be performed on layer 2 using the ownership or
180−management proxies regardless of the dominion status of the galaxy.
181−
182−
183−
content/docs/azimuth/l2/layer2-api.mddeleted−14
@@ -1,14 +0,0 @@
1−+++
2−title = "Roller HTTP RPC-API"
3−weight = 10
4−template = "doc.html"
5−+++
6−
7−With the introduction of Layer 2 arrived a new set of Gall agents equipped with
8−an HTTP RPC-API primarily intended for interacting with Bridge. The
9−documentation for this API is coming soon.
10−
11−The set of API calls available is summarized in the following diagram.
12−
13−[![JSON RPC-API](https://media.urbit.org/docs/layer2/l2-json-rpc.svg)](https://media.urbit.org/docs/layer2/l2-json-rpc.svg)
14−
content/docs/azimuth/l2/layer2.mddeleted−403
@@ -1,403 +0,0 @@
1−+++
2−title = "Layer 2 Overview"
3−weight = 5
4−template = "doc.html"
5−+++
6−
7−This document provides technical details on Azimuth's "Layer 2" scaling solution
8−for Azimuth, known more formally as "naive rollups". We focus here primarily on the
9−"Hoon smart contract" located at `/lib/naive.hoon` in your ship's pier, as well
10−as other proximal topics.
11−
12−This is intended for developers that desire a deeper understanding of how this
13−protocol works, how secure it is, and how to extract data from layer 2 to obtain
14−a complete picture of the Arvo network.
15−
16−This is not intended for everyday users who only wish to know how
17−to either transfer their ship to layer 2 or perform layer 2 actions. This is a
18−functionality of [Bridge](https://bridge.urbit.org) for which documentation will
19−soon be available. For a casual overview of the
20−rationale and functionality of layer 2, please see this [blog
21−post](/blog/rollups). For more information on how Azimuth works more generally,
22−including interactions with Bridge and Ethereum, see the page on [Azimuth data flow](/docs/azimuth/flow).
23−
24−This page is also not where to find instruction on how to run your own
25−"aggregator"/"roller". Documentation for this process is found
26−[here](/docs/azimuth/l2/roller-tutorial). However, this page does contain
27−essential background information for anybody in this category.
28−
29−## Summary
30−
31−Naive rollups were developed in response to rising gas costs for performing
32−Azimuth actions. They also serve the dual purpose of making onboarding easier,
33−as it is now possible to acquire a planet and get on Urbit without any knowledge
34−of Ethereum or cryptocurrency.
35−
36−In this section we give a high-level summary of how naive rollups function and
37−how they affect the end user. Later sections elaborate on this summary.
38−
39−### Layer 1
40−
41−We briefly review how "Layer 1", i.e. the [Azimuth](/docs/glossary/azimuth) smart
42−contract suite, functions. An update to the Azimuth PKI data stored on your urbit
43−occurs with four steps:
44−
45−1. A transaction is posted to the Ethereum blockchain.
46−2. The [Ethereum Virtual Machine](https://ethereum.org/en/developers/docs/evm/)
47− calculates the resulting state transition and checks its validity, then
48− updates the state if it is a valid transition.
49−3. Your urbit downloads the new state from an Ethereum node.
50−4. Your urbit makes the final decision on whether the new state is valid.
51−
52−By default, step four always succeeds. It has always been possible in theory for
53−your urbit to dispute what it read on Ethereum, but there has never been any
54−reason to do so.
55−
56−### Layer 2 {% #layer-2 %}
57−
58−Layer 1 still functions identically today as it did before naive rollups. Naive
59−rollups work via the following process.
60−
61−1. A batch of one or more transactions is posted to the Ethereum blockchain by
62− an urbit node called a roller or aggregator.
63−2. Your urbit downloads the transactions from an Ethereum node.
64−3. Your urbit computes the resulting state transitions from the transactions
65− and checks them for validity.
66−4. Your urbit updates its locally stored Azimuth state using state transitions
67− from the batch that have been deemed valid.
68−
69−In comparison with Layer 1, the EVM no longer checks the validity or computes
70−the state transitions for any given transaction. It is now being used solely as
71−a database of submitted transactions, and the business logic of computing what
72−these transactions mean has been offloaded to your urbit. Thus we think of
73−`naive.hoon` as being the first "Hoon smart contract". You could also consider
74−steps 3 and 4 of the Layer 2 process as being a fattening of the trivial step 4
75−of the layer 1 process.
76−
77−Here we briefly elaborate on the layer 2 steps, but see below for more technical
78−detail.
79−
80−A roller is any urbit node - even a moon, comet, or fakezod will do - to which
81−batches of transactions are submitted. You could use your own ship as a roller
82−if you wanted. The roller collects batches of transactions from whichever
83−parties they choose and submits them to the Ethereum blockchain all at once.
84−We expect this to either happen on a regular interval, or once some minimum
85−threshold of transactions is reached, but the decision on when to submit is
86−ultimately up to the roller.
87−
88−Computing the resulting state transitions obtained from downloaded Ethereum
89−transactions is done using `/lib/naive.hoon`, which is a gate that accepts both layer
90−1 transaction logs and layer 2 batches, and then computes the resulting state
91−transitions and updates the ship's internal Azimuth data held in
92−the Gall agent `/app/azimuth.hoon` accordingly.
93−
94−### Savings in gas costs
95−
96−There are several dimensions by which naive rollups saves on gas over layer 1.
97−They are:
98−
99−1. Gas is not spent on instructing the EVM to compute state transitions and
100− confirm validity.
101−2. Layer 2 Azimuth state is not stored on Ethereum, so the only data storage
102− gas costs is for the transactions themselves.
103−3. Layer 2 transactions are written in a highly compressed form. E.g., instead
104− of calling the spawn action by name, it is simply referred to as action `%1`.
105−4. By collecting multiple layer 2 transactions and submitting them as a single
106− "batch transaction", additional gas savings are achieved by not needing to
107− duplicate information such as which smart contract the transactions are
108− intended for.
109−
110−Put together, these create a reduction in gas costs of at least 65x when adding
111−a transaction to a sufficiently large batch (approximately 30 or more
112−transactions). A single transaction submitted as a batch is approximately 5x
113−cheaper, while 10 transaction submitted as a batch is approximately 30x cheaper.
114−Thus using one's own ship to submit a single-transaction batch is still a
115−cost-saving measure.
116−
117−### One way trip
118−
119−Moving to layer 2 is a one-way trip for now. This means that once a ship moves
120−to layer 2, it cannot be moved back to layer 1. We believe it to be technically
121−possible to engineer a return trip, and expect that someday this will be the
122−case, but there are no plans to implement this in the near future.
123−
124−## Interacting with L2
125−
126−Layer 2 ships can perform the same actions on layer 2 that they could on
127−layer 1, but are no longer able to perform any layer 1 actions. Layer 1 ships
128−can also perform a subset of layer 2 actions - namely the ones related to
129−sponsorship.
130−
131−For a complete list of what layer 2 actions each ship rank, layer, and proxy can
132−perform, see [Layer 2 Actions](/docs/azimuth/l2/l2-actions). For an explicit
133−description of the byte format of Layer 2 Ethereum transaction, see [Bytestring format](/docs/azimuth/l2/bytestring).
134−
135−### Sponsorship {% #sponsorship %}
136−
137−Due to the possibility of sponsors and sponsees existing on different layers,
138−the precise logic of how sponsorship works is complex. However, under common
139−circumstances it is simple.
140−
141−If either the sponsor or sponsee are on layer 2, then sponsorship actions must
142−occur on layer 2. The only exception to this is detaching. A sponsor on layer 1
143−may perform a layer 1 detach action on a layer 2 sponsee, and this will result
144−in the sponsee having no sponsor on layer 1, and layer 2 as well if they were
145−the sponsor on layer 2. This is necessary to simplify the logic, but it also
146−guarantees that there is no hard requirement to ever utilize layer 2. Without
147−this exception, sponsors with sponsees that move to layer 2 would be forced to
148−detach them as a layer 2 action if they wanted to cease sponsorship. This would
149−also have an unacceptable impact on ships owned by [smart contracts](#smart-contracts).
150−
151−If both sponsor and sponsee are on layer 1 then sponsorship actions may occur on
152−either layer. As long as all sponsorship actions betweeen the two parties occur
153−on a single layer, behavior will be as expected.
154−
155−In most cases this is sufficient to understand how sponsorship works. However
156−there are a number of edge cases that make this more complicated that developers
157−may need to concern themselves with in scenarios where layer 1 sponsor and
158−sponsees are mixing layer 1 and layer 2 actions. In the [Sponsorship state
159−transitions](#sponsorship-state-transitions) section below, we give a table that
160−shows how the sponsor and escape status of a ship changes according to which
161−actions are taken.
162−
163−### Smart contracts {% #smart-contracts %}
164−
165−Smart contracts are unable to own layer 2 ships, and thus cannot sign layer 2
166−transactions. This creates a hard requirement that layer 1 ships be allowed to
167−perform a layer 1 detach operation on a layer 2 ships.
168−
169−## Azimuth state {% #state %}
170−
171−The introduction of layer 2 presents additional complication in understanding
172−Azimuth state. In order to be precise we define the following terminology:
173−
174−- _Layer 1 Azimuth state_ refers to the state of Azimuth as reflected on the
175− Ethereum blockchain. This excludes all layer 2 transactions. Depositing to
176− layer 2 is considered a layer 1 action, so the layer 1 Azimuth state is aware
177− of which ships are on layer 2, but is blind to everything that happens to
178− them afterward.
179−- _Layer 2 Azimuth state_ refers to the state of Azimuth as stored in
180− `/app/azimuth.hoon` on your ship. The state here takes into account
181− transactions that occur on both layers. No distinction between the
182− layers is made in the state here - e.g. a ship only has one sponsor in Layer 2
183− Azimuth state, not a layer 1 sponsor and a layer 2 sponsor. This is the state
184− actually in use by Urbit. Layer 1 Azimuth state is now only an input for
185− generating Layer 2 Azimuth state, so any time a ship needs to check e.g. the
186− public key of a ship (regardless of which layer it is on), it will check the
187− Layer 2 Azimuth state, not the Layer 1 Azimuth state.
188−- _Layer-2-Only Azimuth state_ refers to the state of Azimuth as reflected
189− solely by layer 2 transactions. This state is not explicitly stored anywhere,
190− but is computed as part of the process to create the Layer 2 Azimuth state.
191− We do not make any further references to this state, but it is important to
192− keep in mind conceptually.
193−
194−Layer 1 Azimuth state is computed by the Ethereum Virtual Machine. Layer 2
195−Azimuth state is computed by taking in the Layer 1 Azimuth state and modifying
196−it according to layer 2 transactions using `/lib/naive.hoon`. When we are being
197−precise about which state we are referring to we will utilize capitalization as above.
198−
199−Layer 2 Azimuth state is held by the Azimuth Gall app located at
200−`/lib/azimuth.hoon`. Layer 1 and layer 2 state are not held separately - your
201−ship holds only one canonical Azimuth state, generated by parsing both layer 1
202−and layer 2 Ethereum transactions using `/lib/naive.hoon`. It is important to
203−keep in mind that Layer 1 Azimuth state is entirely unaware of Layer 2 Azimuth
204−state. Thus, for instance, the Azimuth PKI on Ethereum (Layer 1 Azimuth state)
205−may claim that the sponsor of `~sampel-palnet` is `~marzod`, while the Azimuth
206−state held on your ship (Layer 2 Azimuth state) claims that the sponsor of
207−`~sampel-palnet` is `~dopzod`. Under this circumstance, this would mean that the
208−sponsor of `~sampel-palnet` was `~marzod` before `~sampel-palnet` was deposited
209−to layer 2, and thus the Azimuth PKI on Ethereum will forever reflect this.
210−
211−For more information on how Azimuth state is handled, including how this
212−integrates with Bridge and Ethereum, see [Azimuth data flow](/docs/azimuth/flow).
213−
214−### Sponsorship state transitions
215−
216−When either a sponsor or sponsee is on layer 2, then all sponsorship actions
217−occur on layer 2 and layer 1 Azimuth state is ignored. The exception to this, as
218−noted [above](#sponsorship), is when a layer 1 sponsor performs a layer 1 detach
219−action on a layer 2 sponsee. Furthermore, any time a ship moves from layer 1 to
220−layer 2, its sponsorship status is automatically maintained in layer 2.
221−
222−The only potentially complicated scenario is when both sponsee and (potential)
223−sponsor exist on layer 1. Then because layer 1 actions can modify layer 2 state,
224−careful consideration is required for interactions that mix the two. If you
225−and your sponsor/sponsee are not mixing layer 1 and layer 2 sponsorship actions
226−between yourselves, then you have nothing to worry about and may safely ignore this
227−section.
228−
229−But, for instance, if both `~sampel-palnet` and `~dopzod` are on layer 1, it is
230−technically possible for `~sampel-palnet` to escape to `~dopzod` on layer 1, and
231−then `~dopzod` can accept the escape on layer 2. This will result in `~dopzod`
232−appearing as the sponsor in the Layer 2 Azimuth state (and thus be
233−`~sampel-palnet`'s "true" sponsor), and the sponsor in the Layer 1 Azimuth state
234−will remain unchanged. While it is difficult to imagine a good reason to do
235−this, developers working with layer 2 need to keep in mind these edge cases and
236−ought to read on.
237−
238−In the following table, columns `E_1` and `S_1` represent the escape status and
239−sponsor of a given ship as reflected by the Layer 1 Azimuth state. Columns `E_2`
240−and `S_2` represent the escape status and sponsor of a given ship as reflected
241−in the Layer 2 Azimuth State. The "true" escape status and sponsor of a ship is
242−always what is listed in the Layer 2 Azimuth state. In other words, at the end
243−of the day, `S_2` is always the sponsor that matters, but layer 1 actions can
244−affect the values of `E_2` and `S_2`.
245−
246−A tar `*` entry represents any value and if an event shows a transition
247−from `*` to `*` that means that value is not altered by the transition. The
248−transitions marked with `!!` are prohibited by the layer 1 Azimuth smart
249−contract and thus never occur. `A1` and `A2` represent two distinct ships.
250−
251−```
252−Event | E_1 | E_2 | S_1 | S_2 | -> | E_1 | E_2 | S_1 | S_2
253−L1-escape A1 | * | * | * | * | -> | A1 | A1 | * | *
254−L1-cancel A1 | ~ | * | * | * | -> !! :: no cancel if not escaping
255−L1-cancel A1 | A1 | * | * | * | -> | ~ | ~ | * | *
256−L1-adopt A1 | A1 | * | * | * | -> | ~ | ~ | A1 | A2
257−L1-adopt A1 | ~ | * | * | * | -> !! :: no adopt if not escaping
258−L1-adopt A1 | A2 | * | * | * | -> !! :: no adopt if not escaping
259−L1-detach A1 | * | * | A1 | A1 | -> | * | * | ~ | ~
260−L1-detach A1 | * | * | A1 | A2 | -> | * | * | ~ | A2
261−L1-detach A1 | * | * | A1 | ~ | -> | * | * | ~ | ~
262−L2-escape A1 | * | * | * | * | -> | * | A1 | * | *
263−L2-cancel A1 | * | * | * | * | -> | * | ~ | * | *
264−L2-adopt A1 | * | A1 | * | * | -> | * | ~ | * | A1
265−L2-adopt A1 | * | A2 | * | * | -> | * | A2 | * | *
266−L2-adopt A1 | * | ~ | * | * | -> | * | ~ | * | *
267−L2-reject A1 | * | A1 | * | * | -> | * | ~ | * | *
268−L2-reject A1 | * | A2 | * | * | -> | * | A2 | * | *
269−L2-reject A1 | * | ~ | * | * | -> | * | ~ | * | *
270−L2-detach A1 | * | * | * | A1 | -> | * | * | * | ~
271−L2-detach A1 | * | * | * | A2 | -> | * | * | * | A2
272−L2-detach A1 | * | * | * | ~ | -> | * | * | * | ~
273−```
274−
275−## Aggregators
276−
277−An "aggregator" or "roller" is any Urbit node that collects signed layer 2
278−transactions (typically via `/app/azimuth-rpc.hoon`), combines them into a
279−"batch", and then submits the batch as an Ethereum transaction. Any urbit can be
280−a roller, including moons, comets, and even fakezods. You can also use your own
281−ship as a roller.
282−
283−Tlon has set up our own roller that is free to use by the community. Using
284−Bridge, a ship may submit X transactions to Tlon's roller per Y period free of
285−charge. Tlon's roller submits on a regular schedule: a submission occurs when a
286−total of A layer 2 transactions have been submitted to it since the the previous
287−submitted Ethereum transaction, or every Z time, whichever occurs first.
288−
289−There are no security risks in utilizing an aggregator. The transactions you
290−submit to it are signed with your private key, and so if an aggregator alters
291−them the signature will no longer match and `naive.hoon` will reject it as an
292−invalid transaction. The worst an aggregator can do is not submit your transaction.
293−
294−## Multi-keyfiles
295−
296−As part of the layer 2 upgrade, Tlon has expanded the role of
297−[keyfiles](/docs/glossary/keyfile). One of our goals with layer 2 was to reduce
298−the amount of friction experienced when getting onto Urbit. The enormous
299−reduction in fees has made a new boot method which allows instantaneous sale of
300−layer 2 planets or stars to be cost effective.
301−
302−The ideal situation would be for the end user to be able to buy or receive a
303−planet and immediately boot it without having to wait for an aggregator to
304−submit a transaction that spawns the planet. In order to bring about this
305−circumstance, "multi-keyfiles" have been introduced.
306−
307−Multi-keyfiles are keyfiles used to boot an urbit for first time that contains
308−more than one set of keys, the purpose of which is to initially utilize one set
309−of keys on a temporary basis, and then the other set of keys soon after. This
310−works as follows. A star owner prespawns a number of layer 2 planets ready to be
311−sold at any time for which they posess the initial key. When a user acquires a
312−planet from a star owner, the star owner immediately hands the initial keys to
313−boot the planet to the buyer. The buyer then queues a transaction at a roller to
314−rotate the keys to a new value only known by the buyer (this step is performed
315−automatically by Bridge). The buyer then downloads a keyfile from Bridge
316−containing both keys and uses that to boot their planet for the first time.
317−After the transaction setting the new keys is submitted by the roller to
318−Ethereum, the purchased planet will automatically switch to them once it reads
319−the corresponding transaction from Ethereum.
320−
321−This process introduces a short period of time in which both the buyer and
322−seller are in possession of the keys of a planet. A malicious seller could
323−theoretically sell a planet to more than one party in this time period. However,
324−they would quickly be found out as two identical ships on the network
325−immediately creates problems, and the seller's reputation would be tarnished.
326−Due to the expense or effort needed to acquire a star, this seems an unlikely
327−scenario as the reward is much less than the cost. Nonetheless, buyers should
328−always make an effort to purchase from a reputable star, as is the case with all
329−transactions in life. If you want to be absolutely sure that you've received the
330−planet, just wait for the batch to be sent and confirmed.
331−
332−Multi-keyfiles were possible before layer 2, but as the cost of configuring keys
333−was comparable to the cost of buying a planet, they were not practical.
334−
335−## Security measures
336−
337−In the process of designing naive rollups, we felt it to be of the utmost
338−importance that there not be any loss in the security of a layer 2 ship over a
339−layer 1 ship. In this section we outline several relevant facets of Urbit as
340−well as particular measures that were taken to ensure that naive rollups were
341−free of bugs and exploits. We think of `naive.hoon` as being the first "Hoon
342−smart contract", and thus its functionality needs to be as rock-solid and
343−guaranteed as the Azimuth Ethereum smart contracts.
344−
345−### Arvo is deterministic
346−
347−Crucial to the functionality of Ethereum smart contracts is that they work the
348−same way every time since the Ethereum Virtual Machine is deterministic.
349−Similarly, as the state of Arvo is evolved via [a single pure
350−function](/docs/arvo/overview#an-operating-function), Arvo is deterministic as
351−well. This property makes it well-suited for cases where side effects are
352−unacceptable such as smart contracts, and thus `naive.hoon` is worthy of the
353−name "Hoon smart contract".
354−
355−### Restricted standard library
356−
357−A standard security practice is to reduce the surface area of attack to be as
358−minimal as possible. One common source of exploits among all programming
359−languages are issues with the standard library of functions, and this is one factor
360−that leads to the existence of multiple implementations of standard library functions for
361−a given programming language. For instance, `glibc` is the most widely used
362−standard library for the C programming language, but sheer size gives a large
363−surface area in which to find exploits. Thus, other standard libraries have been
364−written such as `musl` that are much smaller, and some argue to be more secure
365−at least partially due to fewer lines of code. Hoon is not yet popular enough to have
366−multiple standard library implementations, but `naive.hoon` shucks the usual
367−standard library and so its subject contains only the exact standard library
368−functions needed for it to function. This library is known as `tiny` and is
369−found at `/lib/tiny.hoon`.
370−
371−### Unit tests
372−
373−`naive.hoon` is among the most well-tested software in Urbit. The test suite,
374−which may be run with `-test %/lib/tests/naive ~` from dojo, is larger than any
375−other test suite both in number of lines of code and number of tests. We believe
376−branch coverage to be at or very close to 100%
377−
378−### Nonces
379−
380−In the Layer 2 Azimuth state, each proxy belonging to a given ship (including
381−the ownership "proxy") has a non-negative integer associated to it called a
382−"nonce". Each transaction submitted by a given proxy also have a nonce value. If
383−the current nonce of a proxy in the Layer 2 Azimuth state is `n`, then only a
384−transaction from that proxy with a nonce of `n+1` will be considered valid.
385−Otherwise the transaction is discarded. A valid transaction, by which we
386−mean one in which the nonce and signature are correct, will increment the nonce
387−of the proxy in the Layer 2 Azimuth state by one once processed by `naive.hoon`.
388−Note that "valid transactions" also include ones where the action will fail,
389−such as a planet attempting to `%spawn` another planet. For the purposes of
390−incrementing the nonce, only the nonce and signature matter.
391−
392−The use of nonces prevents "replay attacks", which is when a malicious party collects
393−valid transactions and attempts to resubmit them in order to perform the action
394−again. Since a valid transaction increments the nonce associated to the proxy
395−that submitted it, it is only ever possible for a given transaction to alter the
396−Layer 2 Azimuth state once.
397−
398−The use of nonces also eliminates potential issues caused by submitting a
399−transaction to more than one roller. This might happen if the first roller
400−submitted to is taking too long for your liking, and you want to try again with
401−another. If both rollers end up submitting the transaction, only the first one
402−will succeed, as the second one will be ignored by `naive.hoon` for having the
403−wrong nonce.
content/docs/azimuth/l2/roller-tutorial.mddeleted−172
@@ -1,172 +0,0 @@
1−+++
2−title = "Custom Roller Tutorial"
3−weight = 11
4−template = "doc.html"
5−+++
6−
7−This tutorial is an outline for how to set up your own L2 roller for Urbit. Some
8−familiarity with how L2 works in general, as well as the role of the roller, is
9−expected. See [Layer 2 Overview](/docs/azimuth/l2/layer2) for a technical
10−overview of L2, [Azimuth Data Flow](/docs/azimuth/flow) to gain an understanding
11−of how Azimuth data handling and processing is done on Urbit, and
12−[Rollers](docs/azimuth/l2/roller) for a short summary of what the different Gall
13−agents involved for rollers are. This tutorial is focused on setting up a roller
14−to work on the main Ethereum network, but only minor changes are needed to
15−utilize the Ropsten Ethereum network. We also explain how to set up a front end
16−(Bridge) from which transactions to be batched by the roller are sent, but use
17−of a front end is not mandatory.
18−
19−Note that this process involves giving the private key of an Ethereum wallet to
20−the ship running the roller so that it may spend ETH to submit transactions. If you
21−do not fully understand what this entails, we recommend against running your own
22−roller on the Ethereum mainnet. See [below](#step2) for more information on
23−this.
24−
25−Henceforth, by "roller" we are referring to the ship used as the transaction
26−aggregator and batch submitter, `%roller` refers to the Gall agent running on
27−the roller that performs these actions, and "front-end" refers to the optional
28−web GUI most users will use to interact with your roller (probably Bridge).
29−
30−There are three main steps involved with setting up a roller:
31−
32−- ensuring that the data in `%azimuth` is up to date,
33−- starting and configuring `%roller`,
34−- aiming your front-end at the roller
35−
36−### 1. Make sure `%azimuth` state is up to date
37−
38−If you are using an ordinary live ship on the network as the roller, you should
39−already have the latest `%azimuth` state and this step should not be necessary
40−and you may move to step 2.
41−
42−If your roller is a fakezod, you will need to configure `%azimuth` to pull the
43−latest [Azimuth](/docs/azimuth/azimuth-eth) data from Ethereum. The most common
44−way to do this is via an Infura node, but you could instead use e.g. your own
45−Ethereum node. A free tier Infura node ought to be sufficient for most people
46−and is easy to set up using their tutorials.
47−
48−To set up your fakezod to automatically receive Azimuth updates from the Infura
49−node, enter the following commands in dojo: `:azimuth %resub` followed by
50−`:azimuth|watch 'https://MAINNET_INFURA_URL' %default`. Here, the url can be
51−found under the Setting page for the node on infura.io listed under `ENDPOINTS`.
52−
53−If you do not perform this step, you'll later see an error "roller not ready"
54−when the first roller batch is about to be submitted.
55−
56−### 2. Starting and configuring `%roller` {% #step2 %}
57−
58−This step must be performed whether you're using a fakezod or a live ship.
59−
60−First we need to start `%roller` and `%roller-rpc` (the agent used to send
61−commands to `%roller` via HTTP). If you are not making use of a front-end, and
62−instead will be accepting transactions to batch entirely from within Urbit,
63−`%roller-rpc` is not necessary. We assume you will be using Bridge as a
64−front-end.
65−
66−To start the agents, enter the following command in dojo: `|rein %base [& %roller] [& %roller-rpc]`. You should see the following response:
67−
68−```
69−gall: installing %roller-rpc
70−> 'init'
71−gall: installing %roller
72−> %received-azimuth-state
73−```
74−
75−Note that `%received-azimuth-state` only indicates that `%roller` successfully
76−subscribed to `%azimuth`; it does not indicate that you successfully completed
77−step 1.
78−
79−Next we need to configure `%roller`. `%roller` has several parameters that can
80−be tweaked, such as how many transactions it will accept from a given ship in a
81−given time period, how long the time period is, how much gas to use, exceptions
82−to these rules for particular ships, etc. We will cover these in a moment, but
83−first there are two mandatory settings that must be configured: the Ethereum
84−node to submit batches to, and the private key for the wallet that will submit
85−the transactions.
86−
87−First let's set the Ethereum node to which batches will be submitted, which we
88−will presume is an Infura node. This does not need to be the same node given in
89−step 1, but it is fine for them to be the same (assuming it is configured to
90−accept transactions - some Infura nodes are set up only to make blockchain data
91−available but do not participate in propagating transactions). Enter
92−`:roller|endpoint 'https://MAINNET_INFURA_URL' %mainnet` into dojo.
93−
94−Next we set the private key for the Ethereum wallet from which batches built by
95−`%roller` will be submitted. We _strongly emphasize_ that this step has serious
96−security implications. _`%roller` will be able to spend ETH in this wallet._
97−This is mandatory, of course, as the primary function of `%roller` is to submit
98−batches of transactions to Ethereum, which requires ETH. If you downloaded
99−`%roller` from someone other than Tlon and have not personally audited their
100−code, you are putting the assets in this wallet at risk. Also keep in mind that
101−while Urbit has undergone several security audits, some components such as the
102−runtime have never been audited by a third party. We maintain a list of these
103−audits [here](/audits), as well as an
104−[FAQ](https://urbit.org/faq#how-secure-is-urbit) on the state of security in
105−Urbit. Thus we recommend a fresh wallet generated specifically to be used by
106−`%roller` and to only put the amount of ETH in it that you expect to need in the
107−near future. We also recommend that you only use this address for sending L2
108−batches, since otherwise the nonce will get out of sync. `%roller` can detect
109−this and handle it, but it could cause a delay in batch submission.
110−
111−With that being said, the command to set the private key for the wallet to be
112−utilized by the roller is `:roller|setkey '0x1234567890abcdef'`, where `0x...`
113−is the private key.
114−
115−The `:roller|endpoint` and `:roller|setkey` commands are the only mandatory
116−commands to set up the roller. At this point, if your roller is live on the
117−network (as opposed to a fakezod) and everything has been performed correctly,
118−it would be possible for others to submit transactions to it manually. All other
119−settings are sensible defaults at time of writing. However, to utilize a
120−front-end, one more command is needed: `|cors-approve 'https://YOUR_FRONTEND'`,
121−where the url is the address of the front end you're using - probably a modified
122−Bridge that you're hosting somewhere which you'll set up in the next step.
123−fakezods can only accept transactions from other ships it can talk to, namely
124−other fake ships running on the same machine, so you will need to set it up to
125−work with a front-end if you want to use it on livenet.
126−
127−We cover the additional settings for `%roller` at the end.
128−
129−### 3. Aiming Bridge at the roller
130−
131−The last step is to set up the web interface by which users can submit
132−transactions to be batched by the roller, which we refer to as the front-end. We
133−presume here that you'll be using [Bridge](https://github.com/urbit/bridge), by
134−which we mean you'll be hosting a custom version of Bridge modified to use the
135−roller you set up above instead of Tlon's roller.
136−
137−First you'll need to make the urbit running `%roller` accessible to the web.
138−This is outside the scope of the tutorial, but we suggest using a tool like
139−`caddy` or `nginx`. You'll want to set up a URL such as
140−`https://myroller.sampel-pal.net` and use the port you'd ordinarily use to
141−access Landscape, probably `80` or `8080`. To be clear, this is the same process
142−you'd use if you set up a custom URL to access your urbit hosted in the cloud.
143−
144−To point Bridge at your roller we [launch
145−Bridge](https://github.com/urbit/bridge/blob/master/DEVELOPMENT.md) with a
146−custom command that modifies an environment variable called
147−`REACT_APP_ROLLER_HOST`:
148−
149−```
150−REACT_APP_ROLLER_HOST=https://myroller.sampel-pal.net npm run pilot-mainnet
151−```
152−
153−This will launch a server running Bridge that utilizes the mainnet roller you
154−set up at `https://myroller.sampel-pal.net`.
155−
156−### Additional `%roller` commmands
157−
158−`%roller` has a few other settings and commands for managing things like the
159−rate at which transactions are submitted and manually submitting batches. These
160−can be modified using the following generators:
161−
162−| Dojo Command | Description | Argument |
163−| -------------------- | --------------------------------------------------------------------- | ---------------------------------- |
164−| `:roller\|commit` | Submits a new L2 batch with all pending transactions. | None. |
165−| `:roller\|config` | General configuration command. | `$config` (see `/sur/dice.hoon`) |
166−| `:roller\|endpoint` | Set the Infura endpoint. | `[@t ?(%mainnet %ropsten %local)]` |
167−| `:roller\|frequency` | Sets the frequency at which batches are submitted. | `@dr` |
168−| `:roller\|local` | Configures `%roller` to listen to a local Ethereum node at port 8545. | None. |
169−| `:roller\|quota` | Modified the number of txs a ship is allowed to send per unit time. | `@ud` |
170−| `:roller\|ropsten` | Configure `%roller` to listen to a preset Ropsten Infura node. | None. |
171−| `:roller\|setkey` | Load a private key into the roller and retrieves its L1 nonce. | `@t` |
172−| `:roller\|slice` | Modified the unit of time for each ship's quota. | `@dr` |
content/docs/azimuth/l2/roller.mddeleted−66
@@ -1,66 +0,0 @@
1−+++
2−title = "Rollers"
3−weight = 9
4−template = "doc.html"
5−+++
6−
7−Here we outline how the naive rollup rollers work. This page is only a quick
8−summary - the full documentation of the API is coming soon.
9−
10−## Overview
11−
12−The following diagram illustrates the most important parts of the plumbing
13−present in the roller.
14−
15−[![Roller internals](https://media.urbit.org/docs/layer2/roller-internal.png)](https://media.urbit.org/docs/layer2/roller-internal.png)
16−
17−We elaborate on the components of this diagram below.
18−
19−## `%roller-rpc`
20−
21−The roller communicates with the outside world via a JSON-RPC API, which is
22−implemented with a Gall agent `%roller-rpc`. This is how Bridge communicates
23−with a roller. See the [RPC
24−documentation](https://documenter.getpostman.com/view/16338962/Tzm3nx7x#5a698656-8e7e-433f-9eff-1c6047b9eace)
25−for detailed information on the API.
26−
27−## `%roller`
28−
29−`%roller` is the Gall agent which collects layer 2 Azimuth **transactions**, which
30−are a concatenation of an
31−[action](/docs/azimuth/l2/bytestrings#actions) and a
32−[signature](/docs/azimuth/l2/bytestrings#signatures) and forms them into
33−[batches](/docs/azimuth/l2/bytestrings#batch) to be submitted periodically to the
34−Ethereum blockchain.
35−
36−### Transaction format
37−
38−See [Bytestring Format](/docs/azimuth/l2/bytestring) for a technical description of
39−how layer 2 transactions are formatted.
40−
41−### Pending transactions
42−
43−`%roller` maintains in its state a list of transactions that have been submitted
44−to it since the most recent roll it submitted to Ethereum. These are referred to as
45−**pending transactions**.
46−
47−### Signing the batch
48−
49−Each pending transaction already includes a signature from its sender, but the roller
50−itself must also sign the entire batch of transactions with its private key to
51−submit it as a single Ethereum transaction. This signed batch is known as a **roll**.
52−
53−### Predicted state
54−
55−Once a roll has been submitted to an Ethereum node, there is a waiting period
56−before a miner includes it in a block.
57−
58−During this waiting period, the roller applies the submitted batch to the
59−locally held Azimuth state to get a predicted state. This predicted state is
60−presented to the user in Bridge, such as to show which points a given address owns.
61−
62−### Timer
63−
64−Each roller may choose to submit rolls on a regular basis, periodically
65−and/or whenever a certain number of pending transactions is reached.
66−
content/docs/azimuth/life-and-rift.mddeleted−60
@@ -1,60 +0,0 @@
1−+++
2−title = "Life and Rift"
3−weight = 8
4−template = "doc.html"
5−+++
6−
7−Associated to every Azimuth point are two non-negative integers known as _life_
8−and _rift_. This numbering system partition messages according to the quantity
9−of networking key changes and quantity of
10−[breaches](/using/id/guide-to-resets), respectively. This is explained in
11−more detail below. These values are utilized by [Ames](/docs/arvo/ames/ames)
12−and [Jael](/docs/arvo/jael/jael-api) to ensure that communication between
13−ships is always done with the most recent set of networking keys, and that
14−networking state is appropriately reset when a breach has occurred.
15−
16−Every ship begins with a `life` and `rift` of 0. For galaxies, stars, and
17−planets, these values are stored in the [Azimuth
18−PKI](/docs/azimuth/azimuth-eth#points) as `keyRevisionNumber` and
19−`continuityNumber`, while for moons, these values are stored by their parent.
20−Comets cannot change their networking keys, nor can they breach, and so their
21−`life` and `rift` are always 0.
22−
23−You can check your current `life` and `rift` number by running the `+keys our`
24−generator in dojo. You can inspect another ship's `life` and `rift` by running
25−`+keys ~sampel-palnet`.
26−
27−## Life
28−
29−A ship's `life`, or _key revision number_, is a count of the number of times which
30−a ship's networking keys have been altered. The initial value of each key is
31−always zero, and the initial `life` is always 0.
32−
33−Thus, setting the keys of a ship to a nonzero value for the first time will
34−increment the `life` from 0 to 1. Rotating to a new set of keys will then
35−increment the `life` to 2. Setting the keys back to zero would increment the
36−`life` once more, to 3.
37−
38−## Rift
39−
40−A ship's `rift`, or _continuity number_, is a count of the number of times that
41−a ship has breached, also known as broken continuity.
42−
43−In other words, a ship's `rift` will remain at 0 until the first time it is
44−breached.
45−
46−Network-wide breaches do not affect the `rift` of any ship. They are only used to
47−count the number of personal breaches.
48−
49−## Edge cases
50−
51−Configuring the keys to the same value they already were (i.e. a no-op) is
52−possible, but has no effect on the `life`. Thus `life` is actually a measure of
53−networking key _revisions_, and not the number of times they've been set.
54−
55−Thus under ordinary circumstances, a breach will increment both `life` and
56−`rift` since a breach typically also involves changing the networking keys.
57−However, it is possible to breach without changing the networking keys.
58−If the new keys specified
59−as part of a breach are the same as the old, `rift` will increment while
60−`life` will not.
content/docs/development/_index.mddeleted−33
@@ -1,33 +0,0 @@
1−+++
2−title = "Development"
3−weight = 100
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−insert_anchor_links = "right"
7−+++
8−
9−This section covers the development process in general.
10−
11−## [Getting Started](/docs/development/develop)
12−
13−An orientation to the various development paths within the Urbit ecosystem
14−
15−## [Environment Setup](/docs/development/environment)
16−
17−How to get your development environment ready for Urbit development.
18−
19−## [Grants Program](/docs/development/grants)
20−
21−An introduction to our grants program, where you can earn address space for
22−contributing to the project.
23−
24−## [Project Repositories](/docs/development/project-repositories)
25−
26−A directory of official code repositories, and unofficial community-maintained
27−ones.
28−
29−## [Precepts](/docs/development/precepts)
30−
31−The principles behind Urbit's architecture and continued development.
32−
33−
content/docs/development/develop.mddeleted−113
@@ -1,113 +0,0 @@
1−+++
2−title = "Getting Started"
3−description = "How to get started developing on Urbit."
4−weight = 10
5−template = "doc.html"
6−aliases = ["/docs/using/creating-a-development-ship/", "/docs/getting-started/contributing"]
7−+++
8−
9−There are many ways to get involved as a developer. This guide serves to give
10−you a "lay of the land" for developing on Urbit. Let's start with what you can
11−contribute to. At a high level, you can:
12−
13−- [Build clients](#clients), which use Urbit as their back-end to store data and
14− interact with the network
15−- [Develop agents](#agents), or more precisely [_gall_
16− agents](/docs/arvo/gall/gall), which are written in [Hoon](/docs/hoon/)
17− and can best be thought of as microservices
18−- [Contribute to Urbit's core](#core), which involves contributing to Urbit
19− itself &mdash; either the operating system
20− ([Arvo](https://github.com/urbit/urbit/tree/master/pkg/arvo)), runtime
21− ([Vere](https://github.com/urbit/urbit/tree/master/pkg/urbit)), or public key
22− infrastructure ([Azimuth](https://github.com/urbit/azimuth))
23−
24−Below we'll go into more detail about each of these options and do our best to
25−point you towards a number of additional helpful resources that can be found
26−throughout the docs.
27−
28−### Build Clients {% #clients %}
29−
30−Urbit ships with [Landscape](/docs/glossary/landscape), which can be thought
31−of as its flagship client. Landscape can be broken into two different technical
32−components: there's the collection of [agents](#agents) that utilize the
33−Urbit for networking and data persistence, and the JavaScript client, which is
34−an [interface](https://github.com/urbit/urbit/tree/master/pkg/interface) built
35−with [React](https://reactjs.org).
36−
37−Additionally, you can [contribute to
38−Landscape](https://github.com/urbit/urbit/blob/master/pkg/interface/CONTRIBUTING)
39−by tackling issues in its [issue
40−tracker](https://github.com/urbit/landscape/issues) and/or running the
41−[development stream](https://groups.google.com/a/urbit.org/g/dev/c/r2hv4ajCLwk).
42−
43−You can create your own clients that uses Urbit to store data and interact with
44−other Urbit ships without writing any Hoon code thanks to Urbit's HTTP APIs.
45−This could be a chat client, a writing app, a game, or anything else that can
46−communicate over HTTP.
47−
48−To get started quickly with the language of your choice, see the list
49−libraries that provide HTTP interfaces to Urbit [here](https://github.com/urbit/awesome-urbit#http-apis-airlock).
50−
51−To learn more about how to work with Urbit's HTTP interface, follow [this
52−guide](/docs/arvo/eyre/external-api-ref).
53−
54−Alternatively, command-line interface (CLI) applications can be built using a
55−library called `shoe`, which you can learn more about
56−[here](/docs/hoon/guides/cli-tutorial). This does require Hoon knowledge.
57−
58−### Develop Agents {% #agents %}
59−
60−Gall agents can be best thought of as individual services with a
61−statically-typed interface and built-in database. They're written in
62−[Hoon](/docs/hoon/overview) and all conform to a specific
63−[interface](/docs/arvo/gall/gall-api) that's defined by the kernel vane
64−called [Gall](/docs/arvo/gall/gall).
65−
66−Applications built on Urbit utilize a collection of different agents, each of
67−which handle specific functionality.
68−
69−If you want to learn how to build gall agents, your best bet is to first [learn
70−the Hoon programming language](/docs/hoon/hoon-school/), and then follow that
71−up with the [Gall guide](/docs/userspace/gall-guide/intro).
72−
73−### Contribute to Urbit Core {% #core %}
74−
75−Working on the core means improving the Urbit project itself, working with the
76−existing community of Urbit developers. The kernel is much more stable, but
77−generally more challenging from an engineering standpoint.
78−
79−Just arrived and unsure what to work on? An ideal way to get started is by
80−experimenting with the system, talking to other developers, and reading (or
81−[contributing to](https://github.com/urbit/docs)) the [documentation](/docs/).
82−
83−Prefer learning with an instructor? Our community runs an online course that
84−covers the basics of Urbit development called
85−[Hooniversity](https://hooniversity.org/). If course-based learning works well
86−for you, we recommend you sign up.
87−
88−The Urbit developer community congregates around [the urbit-dev mailing
89−list](https://groups.google.com/a/urbit.org/forum/#!forum/dev), the
90−`~bitbet-bolbel/urbit-community` group on Landscape, and [Urbit’s GitHub
91−repository](https://github.com/urbit/urbit). It’s a good idea to sign up, see
92−what people are talking about, and introduce yourself.
93−
94−Once you’re comfortable working with Urbit, check out the [project’s issues on
95−GitHub](https://github.com/urbit/urbit/issues) or some of our [contribution
96−bounties](https://grants.urbit.org/).
97−
98−If you’re looking for some guidance, need help, or would prefer direct
99−communication for your ideas, you can also always reach out to us directly at
100−[support@urbit.org](mailto:support@urbit.org).
101−
102−## Next Steps
103−
104−From here, you'll probably want to learn more about:
105−
106−- How to set up a [development environment](/docs/development/environment)
107−- Our [grants program](/docs/development/grants), where you can earn address
108− space for helping the project grow
109−- The different [project
110− repositories](/docs/development/project-repositories), both official and
111− community-maintained
112−- Our development [Precepts](/docs/development/precepts), which outline the
113− philosophies that drive Urbit development
content/docs/development/environment.mddeleted−331
@@ -1,331 +0,0 @@
1−+++
2−title = "Environment Setup"
3−description = "How to set up an environment for Urbit development."
4−weight = 11
5−template = "doc.html"
6−+++
7−
8−This guide covers best practices for preparing your environment to develop
9−within the Urbit ecosystem.
10−
11−## Text editors
12−
13−A variety of plugins have been built to provide support for the Hoon language in
14−different text editors. These are listed below.
15−
16−**Note:** The hoon compiler expects Unix-style line endings (LF) and will
17−fail to parse Windows-style line endings (CRLF). Make sure your editor is set
18−to use LF for line endings, especially if you're developing on Windows.
19−
20−#### Atom
21−
22−Atom is free and open-source and runs on all major operating systems. It is
23−available [here](https://atom.io/). A package for Hoon support is maintained by
24−Tlon and may be obtained using the package manager within the editor by
25−searching for `Hoon`.
26−
27−#### Sublime Text
28−
29−Sublime Text is closed-source, but may be downloaded for free and there is no
30−enforced time limit for evaluation. It runs on all major operating systems. It
31−is available [here](https://www.sublimetext.com/).
32−
33−#### Visual Studio Code
34−
35−Visual Studio Code is free and open-source and runs on all major operating
36−systems. It is available [here](https://code.visualstudio.com/). Hoon support
37−may be acquired in the Extensions menu within the editor by searching for
38−`Hoon`.
39−
40−#### Emacs
41−
42−Emacs is free and open-source and runs on all major operating systems. It is
43−available [here](https://www.gnu.org/software/emacs/). Hoon support is available
44−with [hoon-mode.el](https://github.com/urbit/hoon-mode.el).
45−
46−#### Vim
47−
48−Vim is free and open-source and runs on all major operating systems. It is
49−available [here](https://www.vim.org/). Hoon support is available with
50−[hoon.vim](https://github.com/urbit/hoon.vim).
51−
52−## Development ships
53−
54−### Creating a fake ship
55−
56−To do work with Hoon, we recommended using a "fake" ship — one that's not
57−connected to the network.
58−
59−Because such a ship has no presence on the network, you don't need an Azimuth
60−identity. You just need to have [installed the Urbit binary](/getting-started/cli).
61−
62−To create a fake ship named `~zod`, run the command below. You can replace `zod`
63−with any valid Urbit ship-name.
64−
65−```
66−./urbit -F zod
67−```
68−
69−This should take a couple of minutes, during which you should see a block of boot
70−messages, starting with the Urbit version number.
71−
72−### Fake ship networking
73−
74−Fake ships on the same machine can automatically talk to one another. Having
75−created a fakezod, you can create a fake `~bus` the same way:
76−
77−```
78−./urbit -F bus
79−```
80−
81−Now in the fakezod's dojo, try:
82−
83−```
84−> |hi ~bus
85−>=
86−hi ~bus successful
87−```
88−
89−### Faster fake ship booting
90−
91−While working with Hoon, you'll often want to delete an old fake ship and
92−recreate a fresh one. Rather than having to wait a few minutes for the fresh
93−ship to be initialised, you can instead create a backup copy of a fake ship.
94−That way you can just delete the current copy, replace it with the backup, and
95−reboot in a matter of seconds.
96−
97−To do this, boot a fresh fake ship like usual, but with a different name:
98−
99−```
100−./urbit -F zod -c zod.new
101−```
102−
103−Once it's finished booting, it's a good idea to mount its desks so you don't
104−have to do it again each time. In the dojo:
105−
106−```
107−> |mount %base
108−>=
109−> |mount %garden
110−>=
111−> |mount %landscape
112−>=
113−> |mount %bitcoin
114−>=
115−> |mount %webterm
116−>=
117−```
118−
119−Next, shut the ship down with `ctrl+D`. Then, copy the pier and start using the
120−copy instead:
121−
122−```
123−cp -r zod.new zod
124−./urbit zod
125−```
126−
127−Now whenever you want a fresh fakezod, you can just shut it down and do:
128−
129−```
130−rm -r zod
131−cp -r zod.new zod
132−./urbit zod
133−```
134−
135−## Working with desks
136−
137−If you're just working in the dojo or experimenting with generators, committing
138−to the `%base` desk on a fake ship is fine. If you're working on a Gall agent or
139−developing a desk for distribution, you'll most likely want to work on a
140−separate desk and it's slightly more complicated.
141−
142−### Mount a desk
143−
144−To mount a desk to Unix so you can add files, you just need to run the `|mount`
145−command in the dojo and specify the name of the desk to mount:
146−
147−```
148−|mount %base
149−```
150−
151−The desk will now appear in the root of your pier (zod in this case):
152−
153−```
154−zod
155−└── base
156−```
157−
158−You can unmount it again by running the `|unmount` command in the dojo:
159−
160−```
161−|unmount %base
162−```
163−
164−### Create a new desk
165−
166−To create a new desk, you'll need to merge from an existing one, typically
167−`%base`. In the dojo, run the following (you can change `%mydesk` to your
168−preferred name):
169−
170−```
171−|merge %mydesk our %base
172−```
173−
174−If you now mount it, you'll have `/mydesk` directory in your pier with all the
175−files of the `%base` desk inside. You can then delete the contents, copy in your
176−own files and `|commit` it.
177−
178−Desks must contain all the `mark` files, libraries, etc, that they need. A
179−`sys.kelvin` file is mandatory, and there are a few `mark` files necessary as
180−well. In the next couple of sections we'll look at different ways to populate a
181−new desk with the necessary files.
182−
183−### Minimal desk
184−
185−This is the absolute minimal desk you'll be able to commit:
186−
187−```
188−skeleton
189−├── mar
190−│ ├── hoon.hoon
191−│ ├── kelvin.hoon
192−│ ├── mime.hoon
193−│ ├── noun.hoon
194−│ ├── txt-diff.hoon
195−│ └── txt.hoon
196−└── sys.kelvin
197−```
198−
199−`sys.kelvin` specifies the kernel kelvin version with which the desk is
200−compatible. You can copy it across from the `%base` desk, or just run the
201−following in the terminal from within the desk directory:
202−
203−```sh
204−echo "[%zuse 418]" > sys.kelvin
205−```
206−
207−The other `mark` files can just be copied across from the `%base` desk.
208−
209−### Using dev desks
210−
211−If you're working on something more complex, for example a desk with agents and
212−a front-end, there will be a number of `mark` files, libraries, etc, that will
213−be necessary. Rather than having to manually copy all the files from the
214−relevant default desks, the [urbit git repo](https://github.com/urbit/urbit)
215−includes some dev desks which can be used as a base. To get these, make sure you
216−have git installed and then clone the repo:
217−
218−```
219−git clone https://github.com/urbit/urbit ~/git/urbit
220−```
221−
222−If you now change to the `~/git/urbit/pkg` directory, you'll see the source for
223−the default desks, among other things:
224−
225−```
226−cd ~/git/urbit/pkg
227−```
228−
229−The desks ending in `-dev`, like `base-dev` and `garden-dev`, contain files for
230−interfacing with those respective desks. If you're creating a new desk that has
231−a tile and front-end, for example, you might like to use `base-dev` and
232−`garden-dev` as a base. To create such a base, there's a `symbolic-merge.sh`
233−script included in the directory. You can use it like so:
234−
235−```
236−./symbolic-merge base-dev mydesk
237−./symbolic-merge garden-dev mydesk
238−```
239−
240−After running that, you'll have a `mydesk` desk in the `pkg` directory that
241−contains the symlinked files from both those dev desks. To copy the files into
242−your pier, you can create and mount a mydesk desk in the dojo:
243−
244−```
245−|merge %mydesk our %base
246−|mount %mydesk
247−```
248−
249−Then, you can go into your pier:
250−
251−```
252−cd /path/to/fake/zod
253−```
254−
255−Delete the contents of `mydesk`:
256−
257−```
258−rm -r mydesk/*
259−```
260−
261−And then copy in the contents of the desk you created:
262−
263−```
264−cp -rL ~/git/urbit/pkg/mydesk/* mydesk
265−```
266−
267−Note you have to use `cp -rL` rather than just `cp -r` because the
268−`symbolic-merge.sh` script creates symlinks, so the `L` flag is to resolve them
269−and copy the actual files.
270−
271−Now you can just add a `sys.kelvin` file:
272−
273−```
274−echo "[%zuse 418]" > mydesk/sys.kelvin
275−```
276−
277−And you'll be able to mount the desk with `|commit %mydesk`.
278−
279−## Project organization
280−
281−When you're developing a desk, it's best to structure your working directory
282−with the same hierarchy as a real desk. For example, `~/project/mydesk` might
283−look like:
284−
285−```
286−mydesk
287−├── app
288−│ └── foo.hoon
289−├── desk.bill
290−├── desk.docket-0
291−├── lib
292−│ └── foo.hoon
293−├── mar
294−│ └── foo
295−│ ├── action.hoon
296−│ └── update.hoon
297−├── sur
298−│ └── foo.hoon
299−└── sys.kelvin
300−
301−```
302−
303−That way, whenever you want to test your changes, you can just copy it across to
304−your pier like:
305−
306−```
307−cp -ruv mydesk/* /path/to/fake/zod/mydesk
308−```
309−
310−And then just commit it in the dojo:
311−
312−```
313−|commit %mydesk
314−```
315−
316−If you're [using dev desks](#using-dev-desks) as a base, it's best to keep those
317−files separate from your own code.
318−
319−### Syncing repos
320−
321−A useful pattern is to work from a git repo and sync your work with the pier of
322−a fake ship. An easy way to do this is with the following command:
323−
324−```
325−watch rsync -zr --delete /working/repo/desk/* /path/to/fake/zod/mydesk
326−```
327−
328−Here `/working/repo/desk` is the folder that has the proper desk structure
329−outlined above, and `/path/to/fake/zod/mydesk` is the desk you wish to copy the
330−contents of the working repo to. From here, you can edit from the working repo
331−and perform git commands there, while testing your changes on the fake ship.
content/docs/development/grants.mddeleted−84
@@ -1,84 +0,0 @@
1−+++
2−title = "Grants Program"
3−weight = 20
4−template = "doc.html"
5−+++
6−
7−The [Urbit Foundation](https://urbit.org/blog/first-steps-towards-urbit-org/)
8−runs a [Grants program](https://grants.urbit.org), where you can earn address
9−space ([stars](/docs/glossary/star)) in exchange for contributing to the
10−project.
11−
12−Grants come in four different flavors at present: [bounties](#bounties),
13−[proposals](#proposals), [scholarships](#scholarships) and [gifts](#gifts).
14−
15−If you're curious about grants, join the conversation in Landscape at
16−`~wolref-podlex/foundation` or book some time to [talk with
17−us](https://calendly.com/wolref/30min).
18−
19−### Bounties {% #bounties %}
20−
21−[Bounties](https://grants.urbit.org/bounties) are specific, tightly-scoped
22−pieces of work that we at the Urbit Foundation think are of high value to the
23−ecosystem at large. They're frequently development-focused, but also often
24−relate to marketing, community-building or technical writing.
25−
26−Bounties are usually competitive&mdash;worker requests should provide plenty of
27−information about why the requester is right candidate for the job.
28−
29−### Proposals {% #proposals %}
30−
31−Where Bounties are put forward by the Foundation,
32−[Proposals](https://grants.urbit.org/proposals) come from the community. These
33−are things that our community thinks Urbit needs, and span a wide range of
34−topics: we've got [books being
35−written](https://grants.urbit.org/proposals/1590647060-a-book-about-urbit),
36−[videos being
37−produced](https://grants.urbit.org/proposals/1350087489-urbit-explainer-video),
38−help with [production of
39−events](https://grants.urbit.org/proposals/1751024973-urbit-event-series),
40−[marketing](https://grants.urbit.org/proposals/1395578140-smol-future-sustained-knowledge-sharing-and-marketing)
41−and
42−[documentation](https://grants.urbit.org/proposals/1888977136-graph-store-documenation-guide),
43−and
44−[ambitious](https://grants.urbit.org/proposals/21131866-webrtc-gall-agent-and-external-app)
45−[development](https://grants.urbit.org/proposals/1760204192-urbit-lfs)
46−[projects](https://grants.urbit.org/proposals/337545546-urbian-a-customized-linux-distribution-for-urbit-appliances)
47−all happening. If you've got skills and time to put into Urbit, we'll put you to
48−work.
49−
50−Proposals are more likely to be approved if their relevance to the project is
51−made clear, their scope is clearly defined, the proposer is qualified, and it's
52−obvious that a lot of thought has gone into the idea.
53−
54−If you've got an idea and want some help turning it into a proposal, book some
55−time with us [here](https://calendly.com/wolref/30min).
56−
57−### Scholarships {% #scholarships %}
58−
59−Scholarships are the newest addition to the grants program that pairs
60−contributors with core Urbit developers to tackle infrastructure projects. These
61−generally take the form of contributions to
62−[Arvo](/docs/system-overview/arvo) or
63−[Vere](/docs/system-overview/vere).
64−
65−Tackling a scholarship requires an advanced understanding of Urbit. It's
66−expected that you've got a demonstrated command of the Hoon language or other
67−part of Urbit through existing contributions on our repositories or successfully
68−completed grants.
69−
70−New scholarships are posted within the Foundation group in Landscape
71−(`~wolref-podlex/foundation`), and you can sign up for the waitlist using [this
72−form](https://airtable.com/shr6Xmo55h8dZ0O46).
73−
74−### Gifts {% #gifts %}
75−
76−Not every contribution is made with a plan or according to a specification.
77−Sometimes people just fix issues, help newcomers, or promote the project because
78−they want to.
79−
80−Roughly every six months we [give
81−out](https://urbit.org/blog/urbit-grants-and-mid-2019-gifts/) a [bunch of
82−address space](https://urbit.org/blog/gifts-q3-2020/) to those that have helped
83−the project without asking for anything in return, just because we want to. It
84−just feels good, man.
content/docs/development/precepts.mddeleted−326
@@ -1,326 +0,0 @@
1−+++
2−title = "Precepts"
3−weight = 40
4−template = "doc.html"
5−+++
6−
7−![](https://media.urbit.org/site/posts/essays/pre-01.jpg)
8−
9−Urbit is a principled approach to system design and programming, but it's often not obvious what those principles are. We have many specific terms for the different parts of the project: Arvo is the OS, Hoon is the language, Tlon is the company, Azimuth is the identity system, Ames is the network. But the word most associated with the project is "Urbit", and it's not clear what technically it refers to. It's only a small stretch to say that "Urbit" _is_ this set of principles, and that if anybody follows these principles strictly they will create a system that is isomorphic to the Urbit.
10−
11−Some of these are commonly held among many software projects, and some are not. Some are only debatably better than the alternatives, but Urbit exclusively chooses them.
12−
13−We’ll start with a brief description of many principles, then we’ll go into a long-form justification.
14−
15−### A: General Design
16−
17−1. Data is better than code.
18−
19− Store data in your state, send data over the wire, dispatch based
20− on data.
21−
22−2. Everything should be CQRS.
23−
24−3. (Almost) Everything should be pubsub.
25−
26−4. A subscriber shouldn't affect a publisher.
27−
28−5. Communication between nodes should be communication between
29− independent actors.
30−
31− Each message should do one complete thing, and there shouldn't
32− need to be a sequence of coupled messages.
33−
34−6. Represent your data as closely as possible to the essential structure
35− of the problem.
36−
37−7. A client's representation of data should be as close as possible to
38− that of the server.
39−
40− This blurs the distinction between client and server. It allows
41− offline-mode, reduces communication to syncing, and decentralizes.
42−
43−8. When mating different paradigms, build one cleanly on top of the
44− other.
45−
46− Never try to make them work on some of the same primitives. Never
47− abuse one to make the other work. For example, ducts in
48− themselves are very general - if you want to do pubsub, that can
49− easily be built on top of ducts, but don't pretend that pubsub is
50− a _part_ of the duct system.
51−
52−9. Never misuse an abstraction.
53−
54− An abstraction provides a certain set of tools; use them and only
55− them.
56−
57−10. Correctness is more important than performance.
58−
59−11. Be simple and uncompromising in defining what's correct; go crazy
60− with optimizations.
61−
62− Nock is a great example of this. It contains the character of the
63− virtual machine, but its asymptotics are bad. Add jets to fix the
64− asymptotics.
65−
66− Another example is the ACID nature of Arvo. Arvo is a pure
67− function f(logs) of its event log, so formally Arvo is just a
68− function run against an event log. A naive implementation has
69− very bad asymptotics; processing each new event is O(n) in the
70− number of historical events. Choose the function g(state,log)
71− such that f(logs ++ log) = g(f(logs),log). Then, as long as you
72− keep the state in memory, processing each new event is constant in
73− the number of previous events. This still requires O(n) restart
74− from disk, but you can also periodically (and non-blockingly)
75− write a checkpoint of the state to disk, so that restart from disk
76− is only linear in the number of events since the last checkpoint.
77−
78−12. Correctness is more important than optimality.
79−
80−13. If you don't completely understand your code and the semantics of
81− all the code it depends on, your code is wrong.
82−
83−14. Deterministic beats heuristic.
84−
85− Heuristics are evil and should only be used where determinism is
86− infeasible, such as in cache reclamation.
87−
88−15. Stateless is better than stateful.
89−
90−16. Explicit state is better than implicit state.
91−
92−17. Referential transparency is honesty and stability.
93−
94− Lack of referential transparency and other forms of
95− disingenuousness are some of the world's big problems. Only
96− deviate from referential transparency if absolutely necessary.
97−
98−18. Responsibilities should be clearly separated.
99−
100− This applies from kernel modules through network citizens.
101−
102−19. Dualities must be faced head-on and analyzed differently at
103− different layers.
104−
105− Statically typed vs. dynamically typed, imperative vs. functional,
106− code vs. data, and effectful vs. pure can all be a matter of
107− perspective, and all relevant perspectives must have coherent
108− answers.
109−
110−20. One hundred lines of simplicity is better than twenty lines of
111− complexity.
112−
113− It's not enough for an abstraction to reduce code duplication; it
114− must actually make the code simpler.
115−
116−21. Prefer mechanical simplicity to mathematical simplicity.
117−
118− Often mechanical simplicity and mathematical simplicity go
119− together.
120−
121−22. The Law of Leaky Abstractions is a lie; abstract airtightly.
122−
123− If your abstractions are leaking, it's not due to some law of the
124− universe; you just suck at abstracting. Usually, you didn't
125− specify the abstraction narrowly enough.
126−
127−23. Some cliches are repeated because they are true; others must be
128− repeated because they are not.
129−
130−![](https://media.urbit.org/site/posts/essays/pre-03.jpg)
131−
132−### B: Specific Design {% #specific %}
133−
134−1. Always ack a dupe; never ack an ack.
135−
136− It's okay to ack a nack as long as you never nack a nack.
137−
138−2. Never construct or deconstruct a duct.
139−
140−3. Route on wire before sign, never sign before wire.
141−
142−4. Only go from statically typed to dynamically typed if you must.
143−
144− Once you go into a dynamically typed world, it's hard to go back.
145− Statically typed is better than dynamically typed, so if something
146− can be made static, it should be.
147−
148− Each timeless data structure is a brick in the foundation of
149− digital civilization.
150−
151−5. Anything with business logic speaks one paradigm; anything that
152− translates paradigms has no business logic.
153−
154−6. Functionally enforced semantic rules are better security primitives
155− than memory access restrictions.
156−
157− A compiler can use type safety as an effective tool to enforce
158− some classes of security guarantees.
159−
160−### C: Attitude
161−
162−1. Code courageously.
163−
164− If you avoid changing a section of code for fear of awakening the
165− demons therein, you are living in fear. If you stay in the
166− comfortable confines of the small section of the code you wrote or
167− know well, you will never write legendary code. All code was
168− written by humans and can be mastered by humans.
169−
170− It's natural to feel fear of code; however, you must act as though
171− you are able to master and change any part of it. To code
172− courageously is to walk into any abyss, bring light, and make it
173− right.
174−
175−2. No time for lazy people.
176−
177− If there's clearly a right way to do something and a wrong way, do
178− it the right way. Coding requires incredible discipline. Always
179− follow conventions, and fire anyone who won't. Anything that can
180− be solved by discipline is not a real problem.
181−
182− > "To him who knows to do good and does not do it, to him it is
183− > sin."
184−
185−3. When a smart person makes an obviously stupid suggestion, before
186− responding take a full 60 seconds to envision how you would implement
187− it and what the effects would be.
188−
189−### D: Theory
190−
191−1. Academia is a succubus.
192−
193− Academia has a really high ratio of smart people to useful
194− products. Academia has many genuinely smart and interesting
195− ideas, but always remember that pursuing them whole-heartedly will
196− never result in a useful product.
197−
198−2. Never fear math.
199−
200− Academia is inefficient, but it's also correct. Those people
201− wasted a lot of time finding the right answer, but now that
202− they've done it, you must exploit it. If you don't know the
203− theory, learn it. No excuse for being "bad at math". Most who
204− are "bad at math" are simply lazy or fearful. Be strong and of
205− good courage. If you're truly so bad at math that you cannot
206− learn it, you should not design systems.
207−
208−3. Not being qualified to solve a problem is no reason not to solve it.
209−
210− If you don't know how to do it, do it anyway. "We are too young
211− to realize that certain things are impossible. So, we will do
212− them anyway."
213−
214−4. The best way to get the right answer is to try it the wrong way.
215−
216− You cannot design a good system without spending most of your time
217− in contact with the problem. The bad parts about systems are
218− rarely obvious in theory, but often in practice.
219−
220−5. Practice tells you that things are good or bad; theory tells you why.
221−
222− Never use theory to design a good system from scratch; only
223− practice can tell whether the system is good.
224−
225−6. Everyone must regularly alternate between theory and practice.
226−
227− There is an eternal wheel of system design. Given a system, use
228− practice to discover what is bad, missing, or unnecessary. Then,
229− use theory to fix the bad, add the missing, and remove the
230− unnecessary. Repeat.
231−
232−### E: Text Style
233−
234−1. No code should extend beyond 80 characters, most within 55.
235−
236−2. Tabs aren't real.
237−
238−3. A text file is a series of lines, each ending with a newline
239− character.
240−
241− Corollary: all non-empty text files end with a newline (often
242− hidden by editors). An empty text file does not end with a
243− newline.
244−
245−4. One block comment is better than interleaved comments on every line.
246−
247−5. Don't name anything you don't have to.
248−
249− This includes conventional names for variables of particular
250− types. For example, the conventional name for a variable of type
251− `path` is `pax`. You should have a good reason for using any
252− other name for a `path`.
253−
254− A more recent convention that follows the same principle is to
255− give the variable the same name as its type.
256−
257−6. If it's the same thing, give it the same name.
258−
259−7. Humans are good at memorizing.
260−
261−8. Abbreviations aren't worth it.
262−
263−### F: Real Software
264−
265−1. If it's not deterministic, it isn't real.
266−
267−2. If it's centralized, it isn't real.
268−
269−3. If it's owned by someone else, it isn't yours.
270−
271−4. If it's managed by someone else and you can't change who that is, it
272− isn't yours.
273−
274−5. If it's not yours, it isn't permanent.
275−
276−6. If it's not permanent, it isn't real.
277−
278−7. The way it is isn't always the way it ought to be.
279−
280− If you can make it the way it ought to be, do so.
281−
282−8. The way it ought to be isn't always the way it is.
283−
284− Some things can't be made more elegant.
285−
286− For every ailment under the sun
287− There is a remedy, or there is none;
288− If there be one, try to find it;
289− If there be none, never mind it.
290−
291−9. Timeless software is good software.
292−
293−10. System modules should be designed to be frozen permanently;
294− conversely, Urbit consists of that system software which admits of a
295− Kelvin version.
296−
297−11. The two procedures for achieving timelessness are distillation and
298− generalization.
299−
300− Every temporary or contingent feature in a system module should
301− eventually either be removed (distillation) or relaxed into
302− timelessness (generalization). For an example of the result of
303− both procedures, consider the abstraction of the core in Nock and
304− Hoon.
305−
306−12. Standardization is better than perfection.
307−
308− Kelvin versioning stops when we run out of versions, not when
309− every defect has been rectified.
310−
311−13. That which cannot be Kelvin-versioned should update fluidly and
312− automatically.
313−
314− All incompatible upgrades should provide permanent and automatic
315− upgrade paths. This is principled permanent backward
316− compatibility.
317−
318−14. Humans are interactive and temporal; technology is permanent and
319− exhaustive.
320−
321−15. Communities are autonomous.
322−
323−16. Sovereignty necessitates understanding.
324−
325− If you don't understand a system you're using, you don't control
326− it. If nobody understands the system, the system is in control.
content/docs/development/project-repositories.mddeleted−47
@@ -1,47 +0,0 @@
1−+++
2−title = "Project Repositories"
3−weight = 30
4−template = "doc.html"
5−+++
6−
7−Here's a breakdown of the various repositories the project comprises. All of
8−our code is hosted on GitHub, so you can of course peruse it there at
9−[https://github.com/urbit](https://github.com/urbit).
10−
11−### Urbit
12−
13−Urbit OS, the Landscape interface and Vere are all contained in one monolithic
14−repository that can be found [here](https://github.com/urbit/urbit). The repo is
15−large, so here's some links to its various high-level components
16−
17−- [Arvo](https://github.com/urbit/urbit/tree/master/pkg/arvo): the part of the
18− urbit repo that contains Arvo, the Urbit OS.
19−- [Vere](https://github.com/urbit/urbit/tree/master/pkg/urbit): the part of the
20− urbit repo that contains the C and Haskell interpreters.
21−- [Landscape
22− interface](https://github.com/urbit/urbit/tree/master/pkg/interface): the part
23− of the urbit repo that contains the interface code for Landscape.
24− - [Issue Tracker](https://github.com/urbit/landscape/issues): the Landscape issue
25− tracker is a separate repository.
26−
27−### Urbit ID
28−
29−- [azimuth](https://github.com/urbit/azimuth): the public-key infrastructure
30− (PKI) that implements Urbit ID, live on the Ethereum blockchain.
31−- [bridge](https://github.com/urbit/bridge): an application for interacting with
32− Azimuth that can be accessed at [bridge.urbit.org](https://bridge.urbit.org).
33−- [urbit-key-generation](https://github.com/urbit/urbit-key-generation): a javascript library for key derivation and HD
34− wallet generation functions.
35−- [sigil-js](https://github.com/urbit/sigil-js): a javascript library for
36− generating sigils.
37−
38−### Content
39−
40−- [urbit.org](https://github.com/urbit/urbit.org): the source for the urbit.org
41− website and documentation.
42−
43−
44−### Community
45−
46−The best way to keep track of the various community projects is via our
47−[**awesome-urbit**](https://github.com/urbit/awesome-urbit) repository.
content/docs/glossary/_index.mddeleted−10
@@ -1,10 +0,0 @@
1−+++
2−title = "Glossary"
3−sort_by = "none"
4−weight = 900
5−template = "sections/docs/glossary.html"
6−[extra]
7−nav = "link"
8−+++
9−
10−Short articles about key concepts in the Urbit project. Each definition connects you with more specific information within the documentation and on [urbit.org](https://urbit.org), so you can learn more about the project at your own pace.
content/docs/glossary/ames.mddeleted−21
@@ -1,21 +0,0 @@
1−+++
2−title = "Ames"
3−template = "doc.html"
4−[extra]
5−category = "arvo"
6−+++
7−
8−**Ames** is the name of the Urbit network and the [vane](/docs/glossary/vane) that communicates over it. It's an encrypted peer-to-peer network composed of instances of the [Arvo](/docs/glossary/arvo) operating system. Each [galaxy](/docs/glossary/galaxy), [star](/docs/glossary/star), [planet](/docs/glossary/planet), [moon](/docs/glossary/moon), and [comet](/docs/glossary/comet) communicates over the network utilizing the Ames protocol.
9−
10−Your ship upgrades itself with [OTA updates](/docs/glossary/ota-updates) via communication over Ames. The web interface, [Landscape](/docs/glossary/landscape), of ships can be accessed by typing `sampel-palnet.arvo.network` into a browser, where `sampel-palnet` is the name of your ship.
11−
12−Network continuity occasionally needs to be broken, either at an individual
13−level to fix networking issues or at a network-wide level to update Arvo beyond
14−what OTA updates are capable of doing. These events are called [factory resets](/docs/glossary/reset).
15−
16−### Further Reading
17−
18−- [The Ames tutorial](/docs/arvo/ames/ames): An in-depth technical guide to the Ames protocol.
19−- [A Guide to Factory Reset](/using/id/guide-to-resets): Instructions on
20− performing factory resets.
21−- [Ship Troubleshooting](/using/os/ship-troubleshooting): General instructions on getting your ship to work, which includes network connectivity issues.
content/docs/glossary/aqua.mddeleted−12
@@ -1,12 +0,0 @@
1−+++
2−title = "Aqua"
3−template = "doc.html"
4−[extra]
5−category = "arvo"
6−+++
7−
8−**Aqua** is something like Docker but for Urbit; it is a virtualization tool whose primary purpose is testing and development.
9−
10−Aqua is a [Gall](/docs/glossary/gall) app that runs an [Arvo](/docs/glossary/arvo) instance or instances in userspace. It pretends to be [Vere](/docs/glossary/vere), and as such it loads [Pills](/docs/glossary/pill) to boot up a virtual ship or fleet of ships and then manages them from within the parent Arvo instance. Running tests for a virtual fleet of Aqua ships is done using [pH](/docs/glossary/ph).
11−
12−Aqua is jetted with the usual [Nock](/docs/glossary/nock) interpreter and thus virtual ships do not run any slower than the parent ship.
content/docs/glossary/arm.mddeleted−14
@@ -1,14 +0,0 @@
1−+++
2−title = "Arm"
3−
4−template = "doc.html"
5−[extra]
6−category = "hoon-nock"
7−+++
8−
9−An **arm** is a Hoon expression encoded as a noun. You can find them as part of a [core](/docs/glossary/core)
10−
11−### Further Reading
12−
13−- [The Hoon Tutorial](/docs/hoon/hoon-school/): Our guide to learning the Hoon programming language.
14− - [Lesson 1.7: Arms and Cores](/docs/hoon/hoon-school/arms-and-cores): A Hoon Tutorial lesson that discusses cores.
content/docs/glossary/arvo.mddeleted−44
@@ -1,44 +0,0 @@
1−+++
2−title = "Arvo"
3−template = "doc.html"
4−+++
5−
6−**Arvo** is the Urbit operating system and kernel. Arvo's state is a pure
7−function of its [event log](/docs/glossary/eventlog), and it serves as the Urbit event
8−manager. It contains [vanes](/docs/glossary/vane), which are kernel modules that perform
9−essential system operations.
10−
11−Arvo being purely functional means that the state of the operating system at a given moment is completely determined by the sequence of events in the event log. In other words, the state of an Arvo instance is given by a lifecycle function
12−
13−```
14−L: History ➜ State
15−```
16−
17−where `History` consists of the set of all possible sequences of events in an Arvo event log.
18−
19−Arvo coordinates and reloads vanes. It can be thought of as a traffic-director. Any vane needs to go through Arvo before reaching another vane. Events and their effects happen like so:
20−
21−```
22−Unix event -> Vere -> Arvo -> vane -> Arvo
23−```
24−
25−Here, [Vere](/docs/glossary/vere) is the virtual machine running Urbit.
26−
27−Arvo is located in `/base/sys/arvo.hoon` within your urbit.
28−
29−Arvo vanes include [Ames](/docs/glossary/ames) for networking, [Behn](/docs/glossary/behn) for timing,
30−[Clay](/docs/glossary/clay) for filesystem and typed revision control, [Dill](/docs/glossary/dill) for
31−terminal driving, [Eyre](/docs/glossary/eyre) for web services, [Ford](/docs/glossary/ford) for
32−building, and [Gall](/docs/glossary/gall) for application management.
33−
34−Vanes and other programs for Arvo are written in [Hoon](/docs/glossary/hoon).
35−
36−A ship creates its own copy of Arvo via a bootstrap sequence known as a
37−[Pill](/docs/glossary/pill).
38−
39−### Further Reading
40−
41−- [The Arvo tutorial](/docs/arvo/overview): An in-depth technical
42− guide to Arvo and its vanes.
43−- [The Technical Overview](/docs/system-overview/): An
44− overview of all of Urbit.
content/docs/glossary/atom.mddeleted−20
@@ -1,20 +0,0 @@
1−+++
2−title = "Atom"
3−template = "doc.html"
4−[extra]
5−category = "hoon-nock"
6−+++
7−
8−An **atom** is any non-negative integer of any size. The atom is the most basic data type in [Nock](/docs/glossary/nock) and [Hoon](/docs/glossary/hoon).
9−
10−A Hoon atom type consists of a Nock atom with two additional pieces of metadata:
11−an _aura_, which is a soft type that declares if an atom is a date, a ship name, a
12−number, etc, and an optional constant. A Hoon atom type is _warm_ or _cold_ based on whether or not the constant exists:
13−* A Hoon atom type is **warm** if the constant is `~` (null), any atom is in the type.
14−* A Hoon atom type is **cold** if the constant is `[~ atom]`, its only legal value is atom.
15−
16−### Further Reading
17−
18−- [The Hoon Tutorial](/docs/hoon/hoon-school/): Our guide to learning the Hoon programming language.
19− - [Lesson 1.2: Nouns](/docs/hoon/hoon-school/nouns): A Hoon Tutoral lesson that explains how atoms work.
20−- [The Nock explanation](/docs/nock/explanation): Includes an explanation of atoms.
content/docs/glossary/azimuth.mddeleted−39
@@ -1,39 +0,0 @@
1−+++
2−title = "Azimuth"
3−template = "doc.html"
4−+++
5−
6−**Azimuth** is Urbit's identity layer, built as a suite of smart contracts on
7−the Ethereum blockchain and several apps run locally on your
8−[ship](/docs/glossary/ship). It is Urbit's method of securing digital identities
9−that are required to use the [Arvo](/docs/glossary/arvo) peer-to-peer network,
10−without the need for a central authority. Azimuth identities exist as
11−non-fungible tokens, which are owned by Ethereum addresses and can be
12−transferred between such addresses. Identities can use the
13−[claims](/docs/glossary/claims) contract to make assertions – real-world or
14−otherwise – about their owner.
15−
16−The primary way to interact with Azimuth and to manage your identities is
17−through our [Bridge](https://bridge.urbit.org) application. Bridge is a
18−front-end for [Ecliptic](/docs/glossary/ecliptic), the Azimuth contract that's
19−used to perform actions on the blockchain.
20−
21−There are a limited number of Azimuth identities which results in identities
22−having value. This allows for identities to function as reputation primitives,
23−since such scarcity creates an economic incentive for identities to remain
24−static and to keep the network friendly. Undesirable behavior – spamming,
25−scamming, and malware-spreading - will generally result in a
26−[censure](/docs/glossary/censure) from [galaxies](/docs/glossary/galaxy) and
27−[stars](/docs/glossary/star), marking the bad actor.
28−
29−It should be noted that Azimuth isn't built just for Arvo. It can be used as an
30−identity system for other projects.
31−
32−### Further Reading
33−
34−- [The Azimuth concepts page](/docs/azimuth/azimuth): A more in-depth
35− explanation of Azimuth.
36−- [Install instructions](/getting-started/): Guide to installing Urbit, which
37− includes instructions on booting with your Urbit identity.
38−- [Understanding Urbit ID](/understanding-urbit/urbit-id)
39−
content/docs/glossary/battery.mddeleted−14
@@ -1,14 +0,0 @@
1−+++
2−title = "Battery"
3−
4−template = "doc.html"
5−[extra]
6−category = "hoon-nock"
7−+++
8−
9−A **battery** is a collection of Hoon expressions and the head of a [core](/docs/glossary/core).
10−
11−### Further Reading
12−
13−- [The Hoon Tutorial](/docs/hoon/hoon-school/): Our guide to learning the Hoon programming language.
14− - [Lesson 1.7: Arms and Cores](/docs/hoon/hoon-school/arms-and-cores): A Hoon Tutorial lesson that discusses cores.
content/docs/glossary/behn.mddeleted−14
@@ -1,14 +0,0 @@
1−+++
2−title = "Behn"
3−template = "doc.html"
4−[extra]
5−category = "arvo"
6−+++
7−
8−**Behn** is the timing [vane](/docs/glossary/filesystem). It allows for applications to schedule events, which are managed in a simple priority queue. For example, [Clay](/docs/glossary/clay), the Urbit filesystem, uses Behn to keep track of time-specific file requests. [Eyre](/docs/glossary/eyre), the Urbit web vane, uses Behn for timing-out HTTP sessions.
9−
10−Behn is located in `/base/sys/vane/behn.hoon` within [Arvo](/docs/glossary/arvo).
11−
12−### Further Reading
13−
14−- [The Behn tutorial](/docs/arvo/behn/behn): A technical guide to the Behn vane.
content/docs/glossary/bridge.mddeleted−32
@@ -1,32 +0,0 @@
1−+++
2−title = "Bridge"
3−template = "doc.html"
4−[extra]
5−category = "azimuth"
6−+++
7−
8−**Bridge** is a client made for interacting with [Azimuth](/docs/glossary/azimuth). It's the recommended way to receive, send, and manage your Urbit identity, and it's by far the easiest way to generate the [keyfile](/docs/glossary/keyfile) required to get your [ship](/docs/glossary/ship) onto the [Arvo](/docs/glossary/arvo) network. Most Bridge functions are accessed by "logging in" to an identity's ownership address or one of its [proxy addresses](/docs/glossary/proxies). It's accessed at [bridge.urbit.org](https://bridge.urbit.org/).
9−
10−Below are some important functions of Bridge.
11−
12−#### View a Point
13−
14−This function allows you to view the public information of any Urbit identity, such as its ownership and proxy public keys. If you are viewing an identity that's controlled by the Ethereum address that you've accessed with Bridge, then at least some of the actions below will be available to you depending on the type of identity and what address you accessed it with.
15−
16−#### Actions
17−
18−- **Issue child:** Spawn a child from a [galaxy](/docs/glossary/galaxy) or a [star](/docs/glossary/star).
19−- **Transfer:** Send the Urbit identity to another Ethereum address.
20−- **Accept incoming transfer:** If someone is trying to send you an Urbit identity, you must use this action to receive it.
21−- **Cancel outgoing transfer:** Cancel a transfer that you initiated before the recipient has accepted it.
22−- **Generate Arvo keyfile:** Generate the keyfile to boot a ship with your Urbit identity.
23−- **Change spawn proxy:** Assign your spawn proxy to a new Ethereum address.
24−- **Change management proxy:** Assign your transfer proxy to a new Ethereum address.
25−- **Set network keys:** Set new authentication and encryption keys used on your Arvo ship. Will change your Arvo keyfile.
26−- **Generate Arvo keyfile:** Gets the file you need to get your ship on the Arvo network with your Urbit identity.
27−
28−### Further Reading
29−
30−- [bridge.urbit.org](https://bridge.urbit.org/): The Bridge website.
31−- [Using Bridge](/using/id/using-bridge): A guide to starting out with Bridge.
32−- [The Azimuth concepts page](/docs/azimuth/advanced-azimuth-tools): A more in-depth explanation of our identity layer.
content/docs/glossary/censure.mddeleted−14
@@ -1,14 +0,0 @@
1−+++
2−title = "Censures"
3−template = "doc.html"
4−[extra]
5−category = "azimuth"
6−+++
7−
8−The **Censures** [Azimuth](/docs/glossary/azimuth) contract allows [stars](/docs/glossary/star) and [galaxies](/docs/glossary/galaxy) to assign negative reputation information to other points of equal or lower rank. This information is publicly visible and is intended to create an economic deterrent to bad behavior.
9−
10−Positive reputation information cannot be similarly assigned to Urbit identities but it may be inferred from a lack of censures.
11−
12−### Further Reading
13−
14−- [The Censures contract](https://github.com/urbit/azimuth/blob/master/contracts/Censures.sol): The code on GitHub.
content/docs/glossary/ceremony.mddeleted−8
@@ -1,8 +0,0 @@
1−+++
2−title = "Ceremony"
3−template = "doc.html"
4−[extra]
5−category = "azimuth"
6−+++
7−
8−The **ceremony** or **launch ceremony** was the event that transferred custody of [Azimuth](/docs/glossary/azimuth) identities from a centralized ledger to the Ethereum blockchain. Before the ceremony, the Tlon Corporation kept track of ownership in a spreadsheet. The ceremony created Ethereum tokens for those entries and transferred them to the appropriate [HD Wallets](/docs/glossary/hdwallet).
content/docs/glossary/chat.mddeleted−32
@@ -1,32 +0,0 @@
1−+++
2−title = "chat"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−**Chat** is a suite of [Gall](/docs/glossary/gall) applications that handle "instant
10−messaging"-style communication between [ships](/docs/glossary/ship).
11−
12−A chat is a named collection of messages created by and hosted in a ship's
13−`chat-store`. Most of Chat revolves around doing things with these chats.
14−
15−Chats are subscribed to by some number of ships which are permitted to post and
16−retrieve messages from the chat.
17−
18−There are two "kinds" of chats:
19−
20− * A `channel` is a chat that exists as part of a group that is readable and writable by
21− members of the group. Messages are sent to the chat's host ship, and the host
22− ship distributes those messages to members of the chat. Therefore, if you
23− plan to host a chat, you should ensure that your ship has high uptime.
24− * A `DM` is a direct message from one ship to another, visible to no other
25− ship, and not part of a group. Messages may be sent while offline, but the
26− other party will not receive them until both ships are online simultaneously.
27−
28−### Further Reading
29−
30−- [Landscape](/docs/glossary/landscape) includes a web interface for using Chat.
31−- [Messaging guide](/using/os/messaging): A guide to
32− using Chat from the command line.
content/docs/glossary/claims.mddeleted−21
@@ -1,21 +0,0 @@
1−+++
2−title = "Claims"
3−
4−template = "doc.html"
5−[extra]
6−category = "azimuth"
7−+++
8−
9−The **Claims** [Azimuth](/docs/glossary/azimuth) contract allows Urbit identities to make publicly visible assertions about their owner. Such assertions are most commonly about the owner's identity, real-world or otherwise. A claim has three fields: the claim itself, the _protocol_, and the _dossier_.
10−
11−The claim itself is what you're attempting to assert the identity of, as in `@JohnDoe` for a Twitter account, or `1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa`
12−
13−The _dossier_ is the proof of a claim. It could be something like a link to a tweet from a known Twitter account saying, "Hi! I'm ~lodleb-ritrul on Azimuth," or, in the case of cryptocurrency, claim itself signed with the relevant private key.
14−
15−The _protocol_ indicates what kind of thing of the claim is. `Twitter` for a Twitter account, and `Bitcoin` for a Bitcoin address.
16−
17−Points are limited to a maximum of 16 claims. It's good practice to remove any claims associated with a ship when it is about to be transferred to a new owner.
18−
19−### Further Reading
20−
21−- [The Claims contract](https://github.com/urbit/azimuth/blob/master/contracts/Claims.sol): The code on GitHub.
content/docs/glossary/clay.mddeleted−18
@@ -1,18 +0,0 @@
1−+++
2−title = "Clay"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−**Clay** is the filesystem and typed revision-control [vane](/docs/glossary/vane). It can be thought of as a continuously synced git. Clay handles file-change events and maps them from [Arvo](/docs/glossary/arvo) to Unix and vice versa.
10−
11−A common way to use Clay is to create a pier, a directory that exists in and is visible in Unix. Changes are automatically recorded from Urbit to the Unix directory and vice versa. Just set it and forget it!
12−
13−Clay is located at `/base/sys/vane/clay.hoon` within Arvo.
14−
15−### Further Reading
16−
17−- [Using Your Ship](/using/os/filesystem): A user guide that includes instructions on using Clay.
18−- [The Clay tutorial](/docs/arvo/clay/clay): A technical guide to the Clay vane.
content/docs/glossary/comet.mddeleted−32
@@ -1,32 +0,0 @@
1−+++
2−title = "Comet"
3−template = "doc.html"
4−[extra]
5−category = "arvo"
6−+++
7−
8−A **comet** is a kind of [ship](/docs/glossary/ship) on the [Ames](/docs/glossary/ames) network which
9−may be quickly generated by anyone and which are virtually unlimited. They have
10−many uses, including but not limited to:
11−- free identities for new users to try things out before deciding to purchase a [planet](/docs/glossary/planet).
12−- bots
13−- remaining anonymous
14−- testing software
15−
16−Comets have nearly all the same capabilities as a planet. The restrictions they
17−do possess are technical constraints of the system due primarily to the fact that they
18−have no presence on [Azimuth](/docs/glossary/azimuth), rather than purposefully placed
19−blockades.
20− - They may not [change their networking keys](/docs/glossary/bridge).
21− - They may not spawn [moons](/docs/glossary/moon).
22− - They must initiate all direct messages with other ships.
23−The last constraint has a workaround slated. If you wish to change your
24−networking keys, we suggest generating a new comet. Moons are impossible for
25−comets due to the structure of the address space.
26−
27−Some groups on [Landscape](/docs/glossary/landscape) may not allow comet membership, but this is rare.
28−
29−
30−### Further reading
31−
32−- [Creating a Comet](/getting-started/): A guide to spinning up a comet of your own.
content/docs/glossary/core.mddeleted−14
@@ -1,14 +0,0 @@
1−+++
2−title = "Core"
3−
4−template = "doc.html"
5−[extra]
6−category = "hoon-nock"
7−+++
8−
9−A **core** is a cell of a [battery](/docs/glossary/battery) and a [payload](/docs/glossary/payload). It is a Hoon construct similar in use to Objects in Object Oriented programming languages.
10−
11−### Further Reading
12−
13−- [The Hoon Tutorial](/docs/hoon/hoon-school/): Our guide to learning the Hoon programming language.
14− - [Lesson 1.7: Arms and Cores](/docs/hoon/hoon-school/arms-and-cores): A Hoon Tutorial lesson that discusses cores.
content/docs/glossary/delegated-sending.mddeleted−9
@@ -1,9 +0,0 @@
1−+++
2−title = "Delegated Sending"
3−
4−template = "doc.html"
5−[extra]
6−category = "azimuth"
7−+++
8−
9−The **Delegated Sending** [Azimuth](/docs/glossary/azimuth) contract is a way that a [star](/docs/glossary/star ) distributes [planets](/docs/glossary/planet). After a star configures the Delegated Sending contract as its [spawn proxy](/docs/glossary/proxies) it can give invites to planets, and those invitees can subsequently send additional planets from that star to their friends, and pass on this invite power indefinitely. This contract keeps track of those operations in the form of the [Invite Tree](/docs/glossary/invite-tree), so the relationship between inviters and invitees is publicly known.
content/docs/glossary/desk.mddeleted−15
@@ -1,15 +0,0 @@
1−+++
2−title = "Desk"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−A **desk** is an independently revision-controlled branch of a [ship](/docs/glossary/ship) that uses the [Clay](/docs/glossary/clay) filesystem. Each desk contains its own apps, [mark](/docs/glossary/mark) definitions, files, and so forth.
10−
11−Traditionally a ship has at least a `%base` desk, and typically `%garden` and `%landscape` desk among others. The `%base` desk has the kernel and base system software, while other desks are usually each for different apps. A desk is a series of numbered commits, the most recent of which represents the current state of the desk. A commit is composed of `1` an absolute time when it was created, `2` a list of zero or more parents, and `3` a map from paths to data.
12−
13−### Further Reading
14−
15−- [Using Your Ship](/using/os/filesystem): A user guide that includes instructions for using desks.
content/docs/glossary/dill.mddeleted−22
@@ -1,22 +0,0 @@
1−+++
2−title = "Dill"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−**Dill** is the terminal-driver [vane](/docs/glossary/filesystem). You run your urbit in your Unix terminal, and Unix sends every event –⁠
10−such as a keystroke or a change in the dimensions of the terminal window –⁠ to be handled by Dill. Dill acts as an intermediary for anything that uses keyboard events, which results in a slight input lag in Urbit’s command-line interface.
11−
12−A keyboard event's journey from Unix to Dojo, the Urbit shell, can be imagined as diagrammed below:
13−
14−```
15−Keystroke in Unix -> Vere (virtual machine) -> Arvo -> Dill -> the Dojo
16−```
17−
18−Dill is located at `/base/sys/vane/dill.hoon` within [Arvo](/docs/glossary/arvo).
19−
20−### Further Reading
21−
22−- [The Dill tutorial](/docs/arvo/dill/dill): A technical guide to the Dill vane.
content/docs/glossary/docvote.mddeleted−9
@@ -1,9 +0,0 @@
1−+++
2−title = "Document Proposal"
3−
4−template = "doc.html"
5−[extra]
6−category = "azimuth"
7−+++
8−
9−A **document proposal** is a type of [vote](/docs/glossary/voting) action taken by the [Galactic Senate](/docs/glossary/senate) over [Azimuth](/docs/glossary/azimuth). By passing a document proposal, [Galaxies](/docs/glossary/galaxy) in the Senate agree legitimize a document with arbitrary content. Such a document might make claims about the state of the world; an example document that would be subject to this type of vote might be a file that says, "@urbit_senate is the official Twitter account of the senate, and is to be managed by John Doe until further notice."
content/docs/glossary/dojo.mddeleted−15
@@ -1,15 +0,0 @@
1−+++
2−title = "Dojo"
3−
4−[extra]
5−category = "arvo"
6−+++
7−
8−The **Dojo** is Urbit's command-line application that processes system commands and returns output. It also runs [Hoon](/docs/glossary/hoon) and [Nock](/docs/glossary/nock) code, making it a good place to play around with those languages.
9−
10−The other default command-line app is [Chat](/docs/glossary/chat). To switch between Dojo
11−and [Chat](/docs/glossary/chat) press Ctrl-X. The Dojo is the first thing you encounter after successfully booting your [ship](/docs/glossary/ship).
12−
13−### Further Reading
14−
15−- [Hoon Tutorial Lesson 1.1: Introduction](/docs/hoon/hoon-school/intro): A great way to get started with using Hoon in the Dojo.
content/docs/glossary/door.mddeleted−14
@@ -1,14 +0,0 @@
1−+++
2−title = "Door"
3−
4−template = "doc.html"
5−[extra]
6−category = "hoon-nock"
7−+++
8−
9−A **door** is a [core](/docs/glossary/core) the payload of which is a cell of sample and context.
10−
11−### Further Reading
12−
13−- [The Hoon Tutorial](/docs/hoon/hoon-school/): Our guide to learning the Hoon programming language.
14− - [Lesson 1.8: Doors](/docs/hoon/hoon-school/doors): A Hoon Tutorial lesson that discusses doors.
content/docs/glossary/ecliptic.mddeleted−12
@@ -1,12 +0,0 @@
1−+++
2−title = "Ecliptic"
3−
4−template = "doc.html"
5−[extra]
6−category = "azimuth"
7−+++
8−
9−The **Ecliptic** contract sets the rules for what is and is not possible on Azimuth. It's the point of entry for interacting with the [Azimuth](/docs/glossary/azimuth) ledger data; the Azimuth contract itself is just data, and the Ecliptic contract is the logic for controlling that data. Examples of such logic include verifying permissions of the person asking to access their data, and ensuring a requested change is actually valid.
10−
11−The Senate (the voting body of [galaxies](/docs/glossary/galaxy)) has the power to replace
12−Ecliptic via an [upgrade proposal](/docs/glossary/upgrade).
content/docs/glossary/eventlog.mddeleted−23
@@ -1,23 +0,0 @@
1−+++
2−title = "Event Log"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−The **event log** of a [ship](/docs/glossary/ship) is a totally ordered list of every single [Arvo](/docs/glossary/arvo) event that ship has undergone. The state of a ship is a pure function of the event log.
10−
11−The event log is maintained by [Vere](/docs/glossary/vere).
12−
13−If the physical machine loses power and your urbit's state is 'lost' from memory, when your urbit restarts it will replay its entire event log and recover its last valid state from scratch.
14−
15−In practice, event logs become large and unwieldy over time. Periodically a snapshot of the permanent state is taken and the logs are pruned. You're still able to rebuild your state in case of power outage down to the last keystroke. This is due to the practice of persistence.
16−
17−Persistence, in the context of storing data in a computer system, means that data is stored in a non-volatile manner and that input must be recorded before the output result is performed. Thus, every event must be written to disk - or must be _persisted_ - before the event effects actually take place.
18−
19−The initial entries of the event log are created during the bootstrap sequence contained in a [Pill](/docs/glossary/pill).
20−
21−### Further Reading
22−
23−- [Pier](/docs/glossary/pier): The directory on disk which contains the ship's state.
content/docs/glossary/eyre.mddeleted−17
@@ -1,17 +0,0 @@
1−+++
2−title = "Eyre"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−**Eyre** is the web-server [vane](/docs/glossary/vane) that handles client-facing HTTP operations. Unix sends HTTP messages though to Eyre and Eyre produces HTTP messages in response. It is the counterpart to [Iris](/docs/glossary/iris), which is the server-facing HTTP vane.
10−
11−In general, apps and vanes do not call Eyre; rather, Eyre calls apps and vanes. Eyre uses [Ford](/docs/glossary/ford) and [Gall](/docs/glossary/gall) to functionally publish pages and facilitate communication with apps.
12−
13−Eyre is located at `/base/sys/vane/eyre.hoon` within [Arvo](/docs/glossary/arvo).
14−
15−### Further Reading
16−
17−- [The Eyre tutorial](/docs/arvo/eyre/eyre): A technical guide to the Eyre vane.
content/docs/glossary/ford.mddeleted−17
@@ -1,17 +0,0 @@
1−+++
2−title = "Ford"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−**Ford** is the build-system [vane](/docs/glossary/vane). Ford is capable of sequencing generic asynchronous computations. Its uses include linking source files into programs, assembling live-updating websites, and performing file-type conversions.
10−
11−Ford neither accepts Unix events nor produces Unix effects. It exists entirely for the benefit of [Arvo](/docs/glossary/arvo) applications and other vanes, specifically [Clay](/docs/glossary/clay) and [Gall](/docs/glossary/gall).
12−
13−Ford is located at `/base/sys/vane/ford.hoon` within [Arvo](/docs/glossary/arvo).
14−
15−### Further Reading
16−
17−- [The Ford tutorial](/docs/arvo/ford/ford): A technical guide to the Ford vane.
content/docs/glossary/galaxy.mddeleted−15
@@ -1,15 +0,0 @@
1−+++
2−title = "Galaxy"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−A **galaxy** can be one of two related things:
10−
11−- A kind of [Azimuth](/docs/glossary/azimuth) Urbit identity that sits at the top of the identity hierarchy. Galaxies, in this sense, have the power to issue [stars](/docs/glossary/star), meaning that all other kinds of identities ultimate derive from galaxies. Galaxies also form a [Senate](/docs/glossary/senate), the governing body of Azimuth. The Senate has the power to update the logic of Azimuth by [majority vote](/docs/glossary/voting).
12−
13−- A [ship](/docs/glossary/ship) on the Arvo network whose identity is a planet in the former definition. In this sense, galaxies act as infrastructure for the [Arvo](/docs/glossary/arvo) network, providing [Ames](/docs/glossary/ames)-related services, such as peer-to-peer routing and distributing [over-the-air software updates](/docs/glossary/ota-updates). Stars rely on galaxies for these services in the way that planets rely on stars.
14−
15−Galaxies are 8-bit, representable by numbers 0 to 255. This means that there are 256 possible galaxies; each of these galaxies is able to issue 255 [stars](/docs/glossary/star). Galaxies have one-syllable names like `~mul` or `~lux`.
content/docs/glossary/gall.mddeleted−18
@@ -1,18 +0,0 @@
1−+++
2−title = "Gall"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−**Gall** is the application-management [vane](/docs/glossary/vane). Userspace apps –⁠ daemons, really –⁠ are started, stopped, and sandboxed by Gall. Gall provides developers with a consistent interface for connecting their app to [Arvo](/docs/glossary/arvo). It allows applications and other vanes to send messages to applications and subscribe to data streams. Messages coming into Gall are routed to the intended application, and the response comes back along the same route. If the intended target is on another [ship](/docs/glossary/ship), Gall will route it behind the scenes through [Ames](/docs/glossary/ames) to the other ship.
10−
11−Gall is located at `/base/sys/vane/gall.hoon` within Arvo.
12−
13−### Further Reading
14−
15−- [The Hoon Tutorial](/docs/hoon/hoon-school/): Our guide to learning the Hoon programming language that will give you the foundation necessary for app development.
16− - [Lesson 2.7: Gall](/docs/hoon/hoon-school/gall): A Hoon Tutorial lesson that explains how to write a simple Gall app.
17−- [Gall vane documentation](/docs/arvo/gall/gall): Documentation of the Gall vane.
18−- [Gall Guide](/docs/userspace/gall-guide): A tutorial for writing Gall agents.
content/docs/glossary/gate.mddeleted−14
@@ -1,14 +0,0 @@
1−+++
2−title = "Gate"
3−
4−template = "doc.html"
5−[extra]
6−category = "hoon-nock"
7−+++
8−
9−A **gate** is [core](/docs/glossary/core) with one [arm](/docs/glossary/arm) named $. They are often called Hoon Functions because they have many of the same properties of functions from other programming languages.
10−
11−### Further Reading
12−
13−- [The Hoon Tutorial](/docs/hoon/hoon-school/): Our guide to learning the Hoon programming language.
14−- [Lesson 1.4 Gates](/docs/hoon/hoon-school/gates): A Hoon tutorial lesson about gates.
content/docs/glossary/hdwallet.mddeleted−18
@@ -1,18 +0,0 @@
1−+++
2−title = "HD Wallet"
3−
4−template = "doc.html"
5−[extra]
6−category = "azimuth"
7−+++
8−
9−The **Urbit HD Wallet** (_Hierarchical Deterministic_ Wallet) is a system of related Ethereum addresses that's used to store and manage an Urbit identity. Each of these Ethereum addresses have different powers over the same identity, from setting networking keys for communicating in the [Arvo](/docs/glossary/arvo) network to transferring ownership of identities. HD Wallets are created with the [Wallet Generator](/docs/glossary/wallet-generator) software.
10−
11−The Ethereum address that has full powers over a given Urbit identity, including the ability to transfer ownership of the identity, is called the ownership address. Ethereum addresses with fewer powers – the ability to transfer ownership being notably absent – are known as [proxies](/docs/glossary/proxies). This scheme of compartmentalized powers allows wallet holders to only handle less valuable keys when they want to perform operations on an Urbit identity without risking their entire asset.
12−
13−If a proxy or ownership address is compromised or has its keys lost, it can always be rederived using the master ticket, which is the piece of entropy that was initially used to derive the HD wallet.
14−
15−### Further Reading
16−
17−- [The Azimuth concepts page](/docs/azimuth/azimuth): A more in-depth explanation of Azimuth.
18−- [Urbit HD Wallet](/docs/azimuth/hd-wallet): An in-depth explanation of the HD wallet.
content/docs/glossary/hoon.mddeleted−15
@@ -1,15 +0,0 @@
1−+++
2−title = "Hoon"
3−
4−template = "doc.html"
5−+++
6−
7−Hoon is a strict, higher-order typed functional programming language that compiles itself to [Nock](/docs/glossary/nock). As a result Hoon code is effectively implemented by the interpreter [Vere](/docs/glossary/vere). Programs for the Urbit operating system and kernel, [Arvo](/docs/glossary/arvo), are written in Hoon.
8−
9−The Hoon source file is located in `/base/sys/hoon.hoon` within your Urbit.
10−
11−### Further Reading
12−
13−- [The Hoon Tutorial](/docs/hoon/hoon-school/): Our guide to learning the Hoon programming language.
14− - [Lesson 1.1: Setup](/docs/hoon/hoon-school/nouns): How to set up an environment for programming in Hoon.
15−- [Why Hoon?](/blog/why-hoon): A blog post that explains why Urbit uses its own programming language.
content/docs/glossary/invite-tree.mddeleted−9
@@ -1,9 +0,0 @@
1−+++
2−title = "Invite Tree"
3−
4−template = "doc.html"
5−[extra]
6−category = "azimuth"
7−+++
8−
9−The **Invite Tree** is the state stored by the [Delegated Sending](/docs/glossary/delegated-sending) contract on [Azimuth](/docs/glossary/azimuth), and is a record of who gave a [planet](/docs/glossary/planet) to whom. This allows for community applications, such as a chat channel for all distantly related planets.
content/docs/glossary/iris.mddeleted−11
@@ -1,11 +0,0 @@
1−+++
2−title = "Iris"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−**Iris** is the web-server [vane](/docs/glossary/vane) that handles everything HTTP-related on the server side. It is the counterpart to [Eyre](/docs/glossary/eyre), which is the client-facing HTTP vane.
10−
11−Iris is located at `/base/sys/vane/iris.hoon` within [Arvo](/docs/glossary/arvo).
content/docs/glossary/jael.mddeleted−11
@@ -1,11 +0,0 @@
1−+++
2−title = "Jael"
3−template = "doc.html"
4−[extra]
5−category = "arvo"
6−+++
7−
8−**Jael** is the [vane](/docs/glossary/vane) that keeps track of
9−[Azimuth](/docs/glossary/azimuth) related information. For each
10−[ship](/docs/glossary/ship), this consists of its networking keys, its revision
11−number (or _life_), its factory reset number (or _rift_), and who the sponsor of the ship is.
content/docs/glossary/jaque.mddeleted−15
@@ -1,15 +0,0 @@
1−+++
2−title = "Jaque"
3−
4−template = "doc.html"
5−[extra]
6−category = "hoon-nock"
7−+++
8−
9−**Jaque** is a new [Nock](/docs/glossary/nock) interpreter under development that is intended to replace the current worker process for [Vere](/docs/glossary/vere).
10−
11−The current worker utilized by Vere is written in C, while Jaque is written using Java. The primary benefits of switching to Java are the ecosystem benefits and the fact that Java is more memory safe than C.
12−
13−### Further Reading
14−
15−- [The Vere tutorial](/docs/vere/): Learning information for Vere.
content/docs/glossary/keyfile.mddeleted−15
@@ -1,15 +0,0 @@
1−+++
2−title = "Keyfile"
3−
4−template = "doc.html"
5−[extra]
6−category = "azimuth"
7−+++
8−
9−A **keyfile** is a piece of information used to associate a [ship](/docs/glossary/ship) with an Urbit identity so that the ship can use the [Arvo](/docs/glossary/arvo) network. A keyfile is dependent upon the [networking keys](/docs/glossary/bridge) that have been set for the identity; we recommend using [Bridge](/docs/glossary/bridge) to set the networking keys and to generate the corresponding keyfile.
10−
11−The keyfile is used as an argument in the command line when booting a ship. During the boot process, [Vere](/docs/glossary/vere) passes the keyfile into the Arvo state.
12−
13−### Further Reading
14−
15−- [Installation Guide](/getting-started/): Instructions on using a keyfile to boot a ship.
content/docs/glossary/landscape.mddeleted−11
@@ -1,11 +0,0 @@
1−+++
2−title = "Landscape"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−**Landscape** is a graphical web interface for your [ship](/docs/glossary/ship). Right now, Landscape allows for social networking functions, such as to participating in IRC-like chats such as `~/~dopzod/urbit-help`, subscribing to forum-like pages of other ships called Notebooks, and message other ships directly. It also has weather and clock apps. Landscape is an alternative messaging interface to the command-line app [Chat](/docs/glossary/chat).
10−
11−Landscape can be accessed with a browser via [ship.arvo.network](/docs/glossary/shiparvonetwork) or by `localhost:80`. You'll be greeted with a login prompt; type `+code` into your [Dojo](/docs/glossary/dojo), and use the output as your password.
content/docs/glossary/mark.mddeleted−17
@@ -1,17 +0,0 @@
1−+++
2−title = "Mark"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−A **mark** is a file-type in the [Clay](/docs/glossary/clay) filesystem. A mark is a file that defines filesystem information such as type, merge routines, diff routines, and patch algorithms.
10−
11−The [Ford](/docs/glossary/ford) [vane](/docs/glossary/vane) converts data between marks and validates data into marks.
12−
13−
14−### Further Reading
15−
16−- [The Clay tutorial](/docs/arvo/clay/clay): A technical guide to the Clay vane.
17−- [The Ford tutorial](/docs/arvo/ford/ford): A technical guide to the Ford vane.
content/docs/glossary/moon.mddeleted−35
@@ -1,35 +0,0 @@
1−+++
2−title = "Moon"
3−template = "doc.html"
4−[extra]
5−category = "arvo"
6−+++
7−
8−A **moon** is a kind of [ship](/docs/glossary/ship) on the [Arvo](/docs/glossary/arvo) network. Moons
9−are child identities issued by [planets](/docs/glossary/planet), [stars](/docs/glossary/stars), and
10−[galaxies](/docs/glossary/galaxy). A moon is not independent; it is always subordinate to
11−the ship that issued it. By this we mean that the networking keys for the moon
12−are controlled by the parent, and may be altered or revoked at any time by that parent.
13−
14−Moons may be utilized for many purposes, including but not limited to:
15− - vanity identities
16− - backup identities incase the parent identity cannot be accessed
17− - identities for children
18− - testing software
19− - bots
20−
21−Looking towards the future, we expect moons to also be utilized as identities
22−for devices, such as such as phones, desktops, smart TVs, and digital thermostats
23−
24−Unlike planets, stars, and galaxies, moons have no presence on
25−[Azimuth](/docs/glossary/azimuth). Moons are representable with 64 bits and have long names
26−like `~doznec-salfun-naptul-habrys`, the latter half of which is inherited from
27−their parent planet.
28−
29−### Further Reading
30−
31−- [Using Your Ship](/using/os/getting-started#moons): The "Moons" section contains instructions for creating and managing moons.
32−
33−- [Lunar Urbit and the Internet of Things](/blog/iot): Blog post on the
34− past, present, and future of moons
35−
content/docs/glossary/nock.mddeleted−17
@@ -1,17 +0,0 @@
1−+++
2−title = "Nock"
3−
4−template = "doc.html"
5−+++
6−
7−**Nock** is a purely functional typeless programming language and acts as Urbit's lowest-level language. To be more precise, it is a Turing complete combinator interpreter not based on the lambda calculus. It could be thought of as the assembly-level language of Urbit, and is implemented by the runtime system [Vere](/docs/glossary/vere).
8−
9−[comment]: # ("combinator interpreter" is from the old glossary, but I don't know what is meant by this and there only seems to be a few uses of it online according to google, so maybe there is a better term we can use here, or give more of an explanation of what is meant by this? but maybe that is not appropriate for a glossary)
10−
11−The only basic data type in Nock is the [atom](/docs/glossary/atom), which is a non-negative integer. Computation in Nock occurs through the use of [nouns](/docs/glossary/noun) (e.g. binary trees whose leaves are atoms) utilized in three different manners: formulas, subjects, and products. A _formula_ is a noun utilized as a function that takes in a noun, its _subject_, and returns a noun, its _product_.
12−
13−Code written in [Hoon](/docs/glossary/hoon) is compiled to Nock, though it is unnecessary to learn Nock to write code in Hoon.
14−
15−### Further Reading
16−
17−- [The Nock Tutorial](/docs/nock/): An-in depth technical guide.
content/docs/glossary/noun.mddeleted−15
@@ -1,15 +0,0 @@
1−+++
2−title = "Noun"
3−
4−template = "doc.html"
5−[extra]
6−category = "hoon-nock"
7−+++
8−
9−A **noun** is an [atom](/docs/glossary/atom) or a cell, which is an ordered pair of nouns. This definition is recursive and ultimately means that a noun is a finite size binary tree whose leaves are atoms. A noun is the basic data structure in [Nock](/docs/glossary/nock).
10−
11−### Further Reading
12−
13−- [The Hoon Tutorial](/docs/hoon/hoon-school/): Our guide to learning the Hoon programming language.
14− - [Lesson 1.2: Nouns](/docs/hoon/hoon-school/nouns): A Hoon Tutoral lesson that explains how nouns work.
15−- [The Nock explanation](/docs/nock/): Includes a low-level explanation of nouns.
content/docs/glossary/ota-updates.mddeleted−9
@@ -1,9 +0,0 @@
1−+++
2−title = "OTA Updates"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−[Ships](/docs/glossary/ship) have the ability to upgrade themselves **over the air**. They receive updates from a sponsor [star](/docs/glossary/star) or [galaxy](/docs/glossary/galaxy).
content/docs/glossary/payload.mddeleted−14
@@ -1,14 +0,0 @@
1−+++
2−title = "Payload"
3−
4−template = "doc.html"
5−[extra]
6−category = "hoon-nock"
7−+++
8−
9−A **payload** is the set of data needed to run computations in a [core](/docs/glossary/core)
10−
11−### Further Reading
12−
13−- [The Hoon Tutorial](/docs/hoon/hoon-school/): Our guide to learning the Hoon programming language.
14− - [Lesson 1.7: Arms and Cores](/docs/hoon/hoon-school/arms-and-cores): A Hoon Tutorial lesson that discusses cores.
content/docs/glossary/ph.mddeleted−9
@@ -1,9 +0,0 @@
1−+++
2−title = "pH"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−**pH** is a [Gall](/docs/glossary/gall) app that is a framework for fleet testing using [Aqua](/docs/glossary/aqua). pH comes with a number of default tests, as well as tools for building and executing custom tests.
content/docs/glossary/pier.mddeleted−28
@@ -1,28 +0,0 @@
1−+++
2−title = "Pier"
3−template = "doc.html"
4−[extra]
5−category = "arvo"
6−+++
7−
8−A **pier** is the directory which contains the state of an Urbit
9−[ship](/docs/glossary/ship). It is automatically created in the current
10−directory when booting a ship for the first time.
11−
12−Your pier should be kept safe - if it's deleted, you will need to perform a
13−[factory reset](/docs/glossary/reset) in order to inform the rest of the network
14−that your ship's state has been lost.
15−
16−Note that a backup should usually _not_ be taken of your pier as a means of
17−keeping it safe - once the ship is run on the network, the backup will be
18−outdated and running from it will necessitate a factory reset. A running ship
19−automatically backs up its own state within the pier directory for recovery
20−purposes, so as long as the pier is preserved, recovery from most problems is
21−possible.
22−
23−### Further Reading
24−
25−- [Event Log](/docs/glossary/eventlog): The main important content of the pier directory.
26−- [Guide to Factory Resets](/using/id/guide-to-resets): Instructions on
27− performing a factory reset.
28−- [Ship Troubleshooting](/using/os/ship-troubleshooting): General instructions on getting your ship to work, which includes network connectivity issues.
content/docs/glossary/pill.mddeleted−14
@@ -1,14 +0,0 @@
1−+++
2−title = "Pill"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−A **Pill** is a bootstrap sequence to launch an Urbit ship for the first time. The [event log](/docs/glossary/eventlog) begins with the bootstrap sequence of a Pill.
10−
11−A Pill consists of three ordered lists:
12− * A list of events which are interpreted by Nock to create an [Arvo](/docs/glossary/arvo) kernel.
13− * A list of Arvo events to run once the Arvo kernel is created.
14− * A list of userspace events to run once the Arvo events have been run. Currently, this consists of setting up the [Clay](/docs/glossary/clay) file system.
content/docs/glossary/planet.mddeleted−15
@@ -1,15 +0,0 @@
1−+++
2−title = "Planet"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−A **planet** is can be one of two related things:
10−
11−- A kind of [Azimuth](/docs/glossary/azimuth) Urbit identity that sits at the bottom of the identity hierarchy. Planets act as independent identities for use by individual humans as peers on the [Arvo](/docs/glossary/arvo) network. Planets are issued by [stars](/docs/glossary/star), and receive services such as peer-to-peer routing and [over-the-air software updates](/docs/glossary/ota-updates) from the star that sponsors them.
12−
13−- A [ship](/docs/glossary/ship) on the Arvo network whose identity is a planet in the former definition. Planets, in the second sense, have the power to issue [moons](/docs/glossary/moon). Moons are Arvo ships that are meant for use with devices, are completely subordinated from their parent planet, and have no Azimuth presence.
14−
15−Planets have addresses that are representable by 32 bits. This means that there are nearly 4.3 billion possible planets. Planets have four-syllable names like `~morzod-ballet` or `~rovnys-ricfer`.
content/docs/glossary/proxies.mddeleted−34
@@ -1,34 +0,0 @@
1−+++
2−title = "Proxies"
3−
4−template = "doc.html"
5−[extra]
6−category = "azimuth"
7−+++
8−
9−**Proxies** are Ethereum addresses in the [Urbit ID](/docs/glossary/azimuth)
10−system that have limited powers. They are lower-powered "siblings" of the
11−ownership key, which has the sole power to transfer the assigned Urbit identity.
12−Using [Bridge](/docs/glossary/bridge), you can change the Ethereum addresses
13−used for your proxies. If you use the [Urbit HD
14−wallet](/docs/glossary/hdwallet), your proxies have already been set.
15−
16−There are three types of proxy.
17−
18−- **Management Proxy**
19−
20−The management proxy can configure or set Arvo networking keys and conduct sponsorship-related operations.
21−
22−- **Voting Proxy**
23−
24−The voting proxy can cast votes on behalf of its assigned point on new proposals, including changes to [Ecliptic](/docs/glossary/ecliptic). The voting proxy is unique to [galaxies](/docs/glossary/galaxy), since only power galaxies have seats in the Senate.
25−
26−- **Spawn Proxy**
27−
28−Creates new child points given Ethereum address. For [stars](/docs/glossary/stars) and [galaxies](/docs/glossary/galaxy) only.
29−
30−
31−### Further Reading
32−
33−- [Azimuth glossary page](/docs/glossary/azimuth): The glossary entry for Azimuth.
34−- [The Azimuth concepts page](/docs/azimuth/advanced-azimuth-tools): A more in-depth explanation of Azimuth, including information the storage of Urbit identities.
content/docs/glossary/replay.mddeleted−13
@@ -1,13 +0,0 @@
1−+++
2−title = "Replay"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−**Replay** is how [Vere](/docs/glossary/vere) computes the state of a ship's [Arvo](/docs/glossary/arvo) instance from the [event log](/docs/glossary/eventlog) after a ship reboots. In order to avoid replaying the entire event log, Replay takes a snapshot of the current state of the ship approximately once every ten minutes. Then when a ship reboots, Replay loads the most recent snapshot and replays events from the event log up to the most recent event.
10−
11−### Further Reading
12−
13−- [The Vere tutorial](/docs/vere/): An in-depth technical guide to Vere.
content/docs/glossary/reset.mddeleted−32
@@ -1,32 +0,0 @@
1−+++
2−title = "Factory Reset"
3−template = "doc.html"
4−[extra]
5−category = "arvo"
6−+++
7−
8−Continuity on the [Ames](/docs/glossary/ames) network occasionally needs to be
9−broken in order to correct a networking error. These infrequent events are known
10−as **factory resets**, which causes an individual ship to forget its network
11−message history and restores it to the state in which you booted it for the
12−first time.
13−
14−Factory resets are always initiated by the user, frequently in response to a
15−connectivity error. The easiest way to do this is with [Bridge](/docs/glossary/bridge).
16−The option to perform a factory reset is given when changing the networking keys,
17−and when transferring the Urbit ID to a new ownership address.
18−
19−Historically, there were also "network resets", which happened when a major
20−Arvo revision that could not be implemented via an [OTA update](/docs/glossary/ota-updates)
21−occured. Network resets were effectively factory resetting every ship on the network
22−at once. The most recent network reset occurred in December 2020, and we expect
23−it to be the final one.
24−
25−Factory resets used to be called "breaches", and you may still see this language
26−used in some places. The notion is identical, only the name differs.
27−
28−### Further Reading
29−
30−- [Guide to Factory Resets](/using/id/guide-to-resets): A more in-depth
31− explanation of factory resets, including how to perform one.
32−- [Ship Troubleshooting](/using/os/ship-troubleshooting): General instructions on getting your ship to work, which includes network connectivity issues.
content/docs/glossary/rollups.mddeleted−33
@@ -1,33 +0,0 @@
1−+++
2−title = "Naive rollups"
3−template = "doc.html"
4−[extra]
5−category = "azimuth"
6−+++
7−
8−**Naive rollups**, also referred to as **layer 2**, is an upgrade to
9−[Azimuth](/docs/glossary/azimuth) implemented in 2021 that reduces Ethereum gas
10−costs associated with Urbit ID transactions and friction associated with using
11−cryptocurrency in general.
12−
13−This system allows batches of Urbit ID transactions to be submitted together as
14−a single transaction using an urbit node known as a "roller". The PKI state
15−transitions resulting from these transactions are computed locally by your
16−[ship](/docs/glossary/ship) rather than by the [Ethereum Virtual
17−Machine](https://ethereum.org/en/developers/docs/evm/).
18−
19−Due to the dramatically reduced cost, Tlon offers their own roller that is free
20−for ordinary public use. This enables new users to get started with a permanent
21−Urbit ID without any prior knowledge of Ethereum, cryptocurrency, or
22−blockchains.
23−
24−### Further reading
25−
26−- [Layer 2 for planets](/getting-started/layer-2-for-planets): Essential
27− information for planet owners on layer 2 or considering a move to layer 2
28−- [The Gang Solves the Gas Crisis](/blog/rollups): A casual overview of how
29−naive rollups works.
30−- [Layer 2 Overview](/docs/azimuth/l2/layer2): where developers should go to learn
31−about the technical details of naive rollups.
32−- [Custom Roller Tutorial](/docs/azimuth/l2/roller-tutorial): tutorial on how to
33− set up your own L2 roller.
content/docs/glossary/sailudon.mddeleted−14
@@ -1,14 +0,0 @@
1−+++
2−title = "Sail/Udon"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−**Sail** and **Udon** are domain specific languages for Hoon.
10−
11−Sail is used to express XML data structures, which are commonly used for rendering HTML
12−webpages. See the [Sail Guide](/docs/hoon/guides/sail) for more details.
13−
14−Udon is similar to Markdown, a simple language for writing documents.
content/docs/glossary/senate.mddeleted−14
@@ -1,14 +0,0 @@
1−+++
2−title = "Senate"
3−
4−template = "doc.html"
5−[extra]
6−category = "azimuth"
7−+++
8−
9−The **Galactic Senate** is the body of all [galaxies](/docs/glossary/galaxy) that governs
10−[Azimuth](/docs/glossary/azimuth) by [majority vote](/docs/glossary/voting). There are two types of
11−votes: an [upgrade proposal](/docs/glossary/upgrade), which is a motion to update the logic
12−of Azimuth (i.e. [Ecliptic](/docs/glossary/ecliptic)), and a [document
13−proposal](/docs/glossary/docvote), which is a motion to legitimize or approve the content of an
14−arbitrary document.
content/docs/glossary/ship.mddeleted−26
@@ -1,26 +0,0 @@
1−+++
2−title = "Ship"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−A **ship** is an instance of an Urbit computer that is a peer on the [Arvo](/docs/glossary/arvo) network.
10−
11−A ship can be one of five classes:
12−
13−- [comets](/docs/glossary/comet), disposable identities.
14−- [moons](/docs/glossary/moon), connected devices subordinated to a ship.
15−- [planets](/docs/glossary/planet), individual users.
16−- [stars](/docs/glossary/star), network infrastructure nodes.
17−- [galaxy](/docs/glossary/galaxy), also network infrastructure nodes.
18−
19−To be able to use the Arvo network, planets, stars, and galaxies must be combined with an [Azimuth](/docs/glossary/azimuth)-based Urbit identity in the form of a [keyfile](/docs/glossary/keyfile).
20−
21−### Further Reading
22−
23−- [Using Bridge](/getting-started/): A guide to installing Urbit and booting a ship.
24−- [Ship Troubleshooting](/using/os/ship-troubleshooting): General instructions on getting your ship to work, which includes network connectivity issues.
25−- [Understanding Urbit ID](/understanding-urbit/urbit-id)
26−- [Pier](/docs/glossary/pier): The directory containing a ship's state.
content/docs/glossary/shiparvonetwork.mddeleted−9
@@ -1,9 +0,0 @@
1−+++
2−title = "ship.arvo.network"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−**ship.arvo.network** is a way to connect to [ships](/docs/glossary/ship) via HTTP utilizing DNS lookup. For example, the address for `~zod` would be `zod.arvo.network`.
content/docs/glossary/star.mddeleted−17
@@ -1,17 +0,0 @@
1−+++
2−title = "Star"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−A **star** is the kind of Urbit identity that sits between the [galaxy](/docs/glossary/galaxy) and [planets](/docs/glossary/planet) in the identity hierarchy. Stars act as infrastructure for the [Arvo](/docs/glossary/arvo) network, providing planets with [Ames](/docs/glossary/ames)-related services, such as peer-to-peer routing and distributing [over-the-air software updates](/docs/glossary/ota-updates). Stars rely on galaxies for these services in the way that planets rely on stars.
10−
11−A **star** can be one of two related things:
12−
13−- A kind of [Azimuth](/docs/glossary/azimuth) Urbit identity that sits between the [galaxy](/docs/glossary/galaxy) and [planets](/docs/glossary/planet) in the identity hierarchy. Stars, in this sense, have the power to issue [planets](/docs/glossary/planet), and are themselves are issued by galaxies.
14−
15−- A [ship](/docs/glossary/ship) on the Arvo network whose identity is a star in the former definition. In this sense, stars act as infrastructure for the [Arvo](/docs/glossary/arvo) network, providing planets with [Ames](/docs/glossary/ames)-related services, such as peer-to-peer routing and distributing [over-the-air software updates](/docs/glossary/ota-updates). Stars rely on galaxies for these services in the way that planets rely on stars.
16−
17−Stars have addresses that are representable by 16 bits. This means that there are 65,280 possible stars, and each of these stars is able to issue 65,535 planets. Stars have two-syllable names like `~taglux` or `~hallet`.
content/docs/glossary/sync.mddeleted−16
@@ -1,16 +0,0 @@
1−+++
2−title = "|sync"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−**|sync** sets up a sychronization between two [Clay](/docs/glossary/clay) [desks](/docs/glossary/desk). It is mostly used to distribute kernel updates.
10−
11−By default, in the [galaxy](/docs/glossary/galaxy)/[star](/docs/glossary/star)/[planet](/docs/glossary/planet)/[moon](/docs/glossary/moon) hierachy, the kids desk of the parent is synchronized with the base desk of the child.
12−
13−
14−### Further Reading
15−
16−- [Using Your Ship](/using/os/filesystem): A user guide that includes instructions on using Clay commands, including `|sync`.
content/docs/glossary/trap.mddeleted−14
@@ -1,14 +0,0 @@
1−+++
2−title = "Trap"
3−
4−template = "doc.html"
5−[extra]
6−category = "hoon-nock"
7−+++
8−
9−A **trap** is a [core](/docs/glossary/core) with one arm named $ and no sample. They are often used in similar ways to looping structures in other programming languages.
10−
11−### Further Reading
12−
13−- [The Hoon Tutorial](/docs/hoon/hoon-school/): Our guide to learning the Hoon programming language.
14− - [Lesson 1.4.1: Walkthrough: Recursion](/docs/hoon/hoon-school/recursion): A Hoon Tutorial lesson that uses traps to build recursive functions.
content/docs/glossary/upgrade.mddeleted−13
@@ -1,13 +0,0 @@
1−+++
2−title = "Upgrade Proposal"
3−
4−template = "doc.html"
5−[extra]
6−category = "azimuth"
7−+++
8−
9−An **upgrade proposal** is a type of [vote](/docs/glossary/voting) action taken by the
10−[Galactic Senate](/docs/glossary/senate) over [Azimuth](/docs/glossary/azimuth). By passing an upgrade
11−proposal, [Galaxies](/docs/glossary/galaxy) in the Senate agree to change the
12−[Ecliptic](/docs/glossary/ecliptic) smart contracts.
13−
content/docs/glossary/vane.mddeleted−24
@@ -1,24 +0,0 @@
1−+++
2−title = "Vane"
3−
4−template = "doc.html"
5−[extra]
6−category = "arvo"
7−+++
8−
9−A **vane** is an [Arvo](/docs/glossary/arvo) kernel module that performs essential system operations. The vanes are:
10−
11−
12−- [Ames](/docs/glossary/ames), the peer-to-peer networking vane.
13−- [Behn](/docs/glossary/behn), the timer vane.
14−- [Clay](/docs/glossary/clay), the filesystem and revision-control vane.
15−- [Dill](/docs/glossary/dill), the terminal-driver vane.
16−- [Eyre](/docs/glossary/eyre), the HTTP vane.
17−- [Ford](/docs/glossary/ford), the build-system vane.
18−- [Gall](/docs/glossary/gall), the application vane.
19−- [Iris](/docs/glossary/iris), the server HTTP vane.
20−- [Jael](/docs/glossary/jael), the security vane.
21−
22−### Further Reading
23−
24−- [The Arvo tutorial](/docs/arvo/overview): An in-depth technical guide to Arvo and its vanes.
content/docs/glossary/vere.mddeleted−18
@@ -1,18 +0,0 @@
1−+++
2−title = "Vere"
3−
4−template = "doc.html"
5−[extra]
6−category = "hoon-nock"
7−+++
8−
9−**Vere**, pronounced "Vair", is the [Nock](/docs/glossary/nock) runtime environment and Urbit virtual machine. Vere is written in C, runs on Unix, and is the intermediate layer between your urbit and Unix. Unix system calls are made by Vere, not Arvo; Vere must also encode and deliver relevant external events to [Arvo](/docs/glossary/arvo). Vere is also responsible for implementing jets and maintaining the persistent state of each urbit (computed as a pure function of its [event log](/docs/glossary/eventlog) with [Replay](/docs/glossary/replay)). It also contains the I/O drivers for Urbit’s vanes, which are responsible for generating events from Unix and applying effects to Unix.
10−
11−When you boot your [ship](/docs/glossary/ship), Vere passes your [Azimuth](/docs/glossary/azimuth) [keyfile](/docs/glossary/keyfile) into the Arvo state, allowing a connection to the [Ames](/docs/glossary/ames) network.
12−
13−Vere consists of two processes that communicate via a socket: a daemon process in charge of managing I/O channels, and a worker process that acts as a Nock interpreter that is instructed by the daemon process. Currently the worker is written in C, but a new worker written in Java, called [Jacque](/docs/glossary/jacque), is under development.
14−
15−### Further Reading
16−
17−- [The Technical Overview](/docs/system-overview/)
18−- [The Vere tutorial](/docs/vere/): An in-depth technical guide to Vere.
content/docs/glossary/voting.mddeleted−27
@@ -1,27 +0,0 @@
1−+++
2−title = "Voting"
3−
4−template = "doc.html"
5−[extra]
6−category = "azimuth"
7−+++
8−
9−**Voting** is a power available to [galaxies](/docs/glossary/galaxy), in their capacities as
10−members of the [Galactic Senate](/docs/glossary/senate), through an [Azimuth](/docs/glossary/azimuth)
11−smart contract. Galaxies collectively make decisions about the governance of
12−Azimuth and the [Arvo](/docs/glossary/arvo) network by voting. There are two types of proposals that can be voted on:
13−an [upgrade proposal](/docs/glossary/upgrade) and a [document proposal](/docs/glossary/docvote).
14−
15−A proposal is always a Yes/No vote. The vote concludes at the end of 30 days,
16−or whenever an absolute majority is reached, whichever comes first. Assuming a
17−quorum of at least 64 galaxies (1/4 of the Senate) has been achieved, at the end
18−of 30 days the option that has received the most votes is chosen. If a quorum
19−is not achieved then no action is taken.
20−
21−In the case of an absolute majority (129 galaxies), the vote transaction that
22−achieves that majority triggers the upgrade or document ratification. If 30 days
23−passes without an absolute majority being reached, an explicit "update vote
24−status/check result" transaction will need to be made. This can be performed by
25−anyone at any time. Any effects from doing so will only take place if there was a
26−majority vote in favor.
27−
content/docs/glossary/wallet-generator.mddeleted−11
@@ -1,11 +0,0 @@
1−+++
2−title = "Wallet-Generator"
3−
4−template = "doc.html"
5−[extra]
6−category = "azimuth"
7−+++
8−
9−The **Wallet Generator** is a planned open-source app developed for generating an [Urbit HD Wallet](/docs/glossary/hdwallet) to secure your [Azimuth](/docs/glossary/azimuth) identities. Wallet Generator will be part of the [Bridge](/docs/glossary/bridge) software, and it's a graphical user interface that handles the entire process of creating a new [Urbit HD Wallet](/docs/glossary/hdwallet), starting with the entropy-creation step.
10−
11−The Wallet Generator must be used offline for security reasons. If an internet connection is detected at any time, the program will end, forcing the user to start from the beginning. As a final step, Wallet Generator will produce PDF files containing all of the aforementioned seeds, as well as a PDF that contains ownership Ethereum public addresses for receiving ships.
content/docs/hoon/_index.mddeleted−27
@@ -1,27 +0,0 @@
1−+++
2−title = "Hoon"
3−weight = 400
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−insert_anchor_links = "right"
7−+++
8−
9−Hoon is Urbit's high-level general-purpose programming language.
10−
11−### [Overview](/docs/hoon/overview)
12−
13−An overview of why [Arvo](/docs/arvo/overview) was written using Hoon.
14−
15−### [Hoon School](/docs/hoon/hoon-school/)
16−
17−A series of lessons designed to get the beginner started with Hoon. This is our
18−recommended starting point for anyone who wishes to learn Hoon.
19−
20−### [Guides](/docs/hoon/guides/)
21−
22−Tutorials on how to do specific tasks with Hoon.
23−
24−### [Reference](/docs/hoon/reference/)
25−
26−Technical reference material on Hoon, including runes, the type system, and the
27−standard library.
content/docs/hoon/guides/_index.mddeleted−21
@@ -1,21 +0,0 @@
1−+++
2−title = "Guides"
3−weight = 20
4−sort_by = "weight"
5−template = "sections/docs/chapters.html"
6−insert_anchor_links = "right"
7−+++
8−
9−## [Writing Aqua Tests](/docs/hoon/guides/aqua)
10−
11−## [CLI Apps](/docs/hoon/guides/cli-tutorial)
12−
13−## [Parsing](/docs/hoon/guides/parsing)
14−
15−## [Strings](/docs/hoon/guides/strings)
16−
17−## [JSON](/docs/hoon/guides/json-guide)
18−
19−## [Sail](/docs/hoon/guides/sail)
20−
21−## [Unit tests](/docs/hoon/guides/unit-tests)
content/docs/hoon/guides/aqua.mddeleted−80
@@ -1,80 +0,0 @@
1−+++
2−title = "Writing Aqua Tests"
3−weight = 37
4−template = "doc.html"
5−+++
6−
7−# Concepts
8−
9−Aqua (short for "aquarium", alluding to the idea that you're running
10−multiple ships in a safe, artificial environment and watching them
11−carefully) is an app that lets you run one or more virtual ships from
12−within a single host.
13−
14−pH is a library of functions designed to make it easy to write
15−integration tests using Aqua.
16−
17−# First test
18−
19−To run your first pH test, run the following commands:
20−
21−```
22−|start %aqua
23−:aqua +solid
24−-ph-add
25−```
26−
27−This will start Aqua, compile a new kernel for it, and then compile and
28−run /ted/ph/add.hoon. Here are the contents of that file:
29−
30−```
31−/- spider
32−/+ *ph-io
33−=, strand=strand:spider
34−^- thread:spider
35−|= args=vase
36−=/ m (strand ,vase)
37−;< ~ bind:m start-simple
38−;< ~ bind:m (raw-ship ~bud ~)
39−;< ~ bind:m (dojo ~bud "[%test-result (add 2 3)]")
40−;< ~ bind:m (wait-for-output ~bud "[%test-result 5]")
41−;< ~ bind:m end-simple
42−(pure:m *vase)
43−```
44−
45−There's a few lines of boilerplate, with three important lines defining
46−the test.
47−
48−```
49−;< ~ bind:m (raw-ship ~bud ~)
50−;< ~ bind:m (dojo ~bud "[%test-result (add 2 3)]")
51−;< ~ bind:m (wait-for-output ~bud "[%test-result 5]")
52−```
53−
54−We boot a ship with `+raw-ship`. In this case the ship we are booting will be `~bud`. These ships exist in a virtual environment so you could use any valid `@p`.
55−
56−Next we enter some commands with `+dojo`, and then we wait until we get a line that includes some expected output. Each of these commands we need to specify the ship we want to run on.
57−
58−Many tests can be created with nothing more than these simple tools.
59−Try starting two ships and having one send a `|hi` to the other, and
60−check that it arrives.
61−
62−Many more complex tests can be created, including file changes, personal
63−breaches, mock http clients or servers, or anything you can imagine.
64−Check out `/lib/ph/io.hoon` for other available functions, and look at
65−other tests in `/ted/ph/` for inspiration.
66−
67−# Reference
68−
69−Aqua has the following commands:
70−
71−`:aqua +solid` Compiles a "pill" (kernel) for the guest ships and loads it into Aqua.
72−
73−`:aqua [%swap-files ~]` modifies the pill to use the files you have in
74−your filesystem without rebuilding the whole pill. For example, if you
75−change an app and you want to test the new version, you must install it
76−in the pill. This command will do that.
77−
78−`:aqua [%swap-vanes ~[%a]]` Modifies the pill to load a new version of a
79−vane (`%a` == Ames in this example, but it can be any list of vanes).
80−This is faster than running `:aqua +solid`.
content/docs/hoon/guides/cli-tutorial.mddeleted−440
@@ -1,440 +0,0 @@
1−+++
2−title = "CLI apps"
3−weight = 2
4−template = "doc.html"
5−+++
6−
7−## Introduction
8−
9−In this walkthrough we will go in-depth on how to build command line interface (CLI)
10−applications in Urbit using the `shoe` library.
11−
12−There are three CLI apps that currently ship with urbit - `%dojo`, `%chat-cli`,
13−and `%shoe`. You should be familiar with the former two, the latter is an
14−example app that shows off how the `shoe` library works that we will be looking
15−at closely. These are all Gall apps, and their source can be found in the `app/`
16−folder of your `%base` desk.
17−
18−In [the `shoe` library](#the-shoe-library) we take a closer look at the `shoe` library and its
19−cores and how they are utilized in CLI apps. Then in [the `sole`
20−library](#the-sole-library) we look at what `shoe` effects ultimately break down
21−into. Finally in [`%shoe` app walkthrough](#shoe-app-walkthrough) we explore
22−the functionality of the `%shoe` app and then go through the code line-by-line.
23−
24−This tutorial can be
25−considered to be an application equivalent of the [Hoon school
26−lesson](/docs/hoon/hoon-school/generators#ask) on `sole` and `%ask`
27−generators, which only covers the bare minimum necessary to write generators
28−that take user input.
29−
30−## The `shoe` library {% #the-shoe-library %}
31−
32−Here we describe how sessions are identified, the specialized `card`s that Gall agents
33−with the `shoe` library are able to utilize, and the different cores of `/lib/shoe.hoon` and their purpose.
34−
35−### Session identifiers
36−
37−An app using the `shoe` library will automatically track sessions by their `sole-id=@ta`.
38−These are opaque identifiers generated by the connecting client. An app using the `shoe`
39−library may be connected to by a local or remote ship in order to send commands,
40−and each of these connections is assigned a unique `@ta` that identifies the
41−ship and which session on that ship if there are multiple.
42−
43−### `%shoe` `card`s
44−
45−Gall agents with the `shoe` library are able to utilize `%shoe` `card`s. These
46−additions to the standard set of `cards` have the following shape:
47−
48−```hoon
49−[%shoe sole-ids=(list @ta) effect=shoe-effect]`
50−```
51−
52−`sole-ids` is the `list` of session ids that the following `effect` is
53−emitted to. An empty `sole-ids` sends the effect to all connected sessions.
54−`shoe-effect`s, for now, are always of the shape `[%sole effect=sole-effect]`, where
55−`sole-effect`s are basic console events such as displaying text, changing the
56−prompt, beeping, etc. These are described in the section on the [`sole` library](#the-sole-library).
57−
58−For example, a `%shoe` `card` that causes all connected sessions to beep would
59−be `[%shoe ~ %sole %bel ~]`.
60−
61−### `shoe` core
62−
63−An iron (contravariant) door that defines an interface for Gall agents utilizing
64−the `shoe` library. Use this core whenever you want to receive input from the user and run a command. The input will get
65−put through the parser (`+command-parser`) and results in a noun of
66−`command-type` that the underlying application specifies, which shoe then feeds back into the underlying app as an `+on-command` callback.
67−
68−In addition to the ten arms that all Gall core apps possess, `+shoe` defines and expects a few
69−more, tailored to common CLI logic. Thus you will need to wrap the `shoe:shoe` core using the `agent:shoe` function to obtain a standard
70−10-arm Gall agent core. See the [shoe example app
71−walkthrough](#shoe-example-app-walkthrough) for how to do this.
72−
73−The additional arms are described below. The Hoon code shows their expected type signature. As we'll see [later](#shoe-app-walkthrough), the `command-type` can differ per application. Note also that most of these take a session identifier as an argument. This lets applications provide different users (at potentially different "places" within the application) with different affordances.
74−
75−#### `+command-parser`
76−
77−```hoon
78− ++ command-parser
79− |~ sole-id=@ta
80− |~(nail *(like [? command-type]))
81−```
82−
83−Input parser for a specific command-line session. Will be run on whatever the user tries to input into the command prompt, and won't let them type anything that doesn't parse. If the head of the result is true,
84−instantly run the command. If it's false, require the user to press return.
85−
86−#### `+tab-list`
87−
88−```hoon
89− ++ tab-list
90− |~ sole-id=@ta
91− *(list (option:auto tank))
92−```
93−
94−Autocomplete options for the command-line session (to match `+command-parser`).
95−
96−#### `+on-command`
97−
98−```hoon
99− ++ on-command
100− |~ [sole-id=@ta command=command-type]
101− *(quip card _this)
102−```
103−
104−Called when a valid command is run.
105−
106−#### `+can-connect`
107−
108−```hoon
109− ++ can-connect
110− |~ sole-id=@ta
111− *?
112−```
113−
114−Called to determine whether a session may be opened or connected to. For example, you
115−may only want the local ship to be able to connect.
116−
117−#### `+on-connect`
118−
119−```hoon
120− ++ on-connect
121− |~ sole-id=@ta
122− *(quip card _^|(..on-init))
123−```
124−
125−Called when a session is opened or connected to.
126−
127−#### `+on-disconnect`
128−
129−```hoon
130− ++ on-disconnect
131− |~ sole-id=@ta
132− *(quip card _^|(..on-init))
133−```
134−
135−Called when a previously made session gets disconnected from.
136−
137−### `default` core
138−
139−This core contains the bare minimum implementation of the additional `shoe` arms
140−beyond the 10 standard Gall app ams. It is used
141−analogously to how the `default-agent` core is used for regular Gall apps.
142−
143−### `agent` core
144−
145−This is a function for wrapping a `shoe` core, which has too many
146−arms to be a valid Gall agent core. This turns it into a standard Gall agent core by
147−integrating the additional arms into the standard ones.
148−
149−## The `sole` library {% #the-sole-library %}
150−
151−`shoe` apps may create specialized `card`s of the `[%shoe (list @ta) shoe-effect]` shape, where `shoe-effect` currently just wrap `sole-effect`s, i.e. instructions for displaying text and producing other effects in the console.
152−
153−The list of possible `sole-effects` can be found in `/sur/sole.hoon`. A few
154−commonly used ones are as follows.
155−
156−- `[%txt tape]` is used to display a line of text.
157−- `[%bel ~]` is used to emit a beep.
158−- `[%pro sole-prompt]` is used to set the prompt.
159−- `[%mor (list sole-effect)]` is used to emit multiple effects.
160−
161−For example, a `sole-effect` that beeps and displays `This is some text.` would
162−be structured as
163−
164−```hoon
165−[%mor [%txt "This is some text."] [%bel ~] ~]
166−```
167−
168−## `%shoe` app walkthrough {% #shoe-app-walkthrough %}
169−
170−Here we explore the capabilities of the `%shoe` example app and then go through
171−the code, explaining what each line does.
172−
173−### Playing with `%shoe`
174−
175−First let's test the functionality of `%shoe` so we know what we're getting
176−into.
177−
178−Start two fake ships, one named `~zod` and the other can have any name - we will
179−go with `~nus`. Fake ships run locally are able to see each other, and our
180−intention is to connect their `%shoe` apps.
181−
182−On each fake ship start `%shoe` by entering `|start %shoe` into dojo. This will
183−automatically
184−change the prompt to `~zod:shoe>` and `~nus:shoe>`. Type `demo` and watch the following appear:
185−
186−```
187−~zod ran the command
188−~zod:shoe>
189−```
190−
191−`~zod ran the command` should be displayed in bold green text, signifying that
192−the command originated locally.
193−
194−Now we will connect the sessions. Switch `~zod` back to dojo with `Ctrl-X` and enter `|link ~nus %shoe`. If this succeeds you will see the following.
195−
196−```
197−>=
198−; ~nus is your neighbor
199−[linked to [p=~nus q=%shoe]]
200−```
201−
202−Now `~zod` will have two `%shoe` sessions running - one local one on `~zod` and
203−one remote one on `~nus`, which you can access by pressing `Ctrl-X` until you see
204−`~nus:shoe>` from `~zod`'s console. On the other hand, you should not see
205−`~zod:shoe>` on `~nus`'s side, since you have not connected `~nus` to `~zod`'s
206−`%shoe` app. When you enter `demo` from `~nus:shoe>` on
207−`~zod`'s console you will again see `~zod ran the command`, but this time it
208−should be in the ordinary font used by the console, signifying that the command
209−is originating from a remote session. Contrast this with entering `demo` from
210−`~nus:shoe>` in `~nus`'s console, which will display `~nus ran the command` in
211−bold green text.
212−
213−Now try to link to `~zod`'s `%shoe` session from `~nus` by switching to the dojo
214−on `~nus` and entering `|link ~zod %shoe`. You should see
215−
216−```
217−>=
218−[unlinked from [p=~zod q=%shoe]]
219−```
220−
221−and if you press `Ctrl-X` you will not get a `~zod:shoe>` prompt. This is
222−because the example app is set up to always allow `~zod` to connect (as well as
223−subject moons if the ship happens to be a planet) but not `~nus`, so this
224−message means that `~nus` failed to connect to `~zod`'s `%shoe` session.
225−
226−### `%shoe`'s code
227−
228−```hoon
229−:: shoe: example usage of /lib/shoe
230−::
231−:: the app supports one command: "demo".
232−:: running this command renders some text on all sole clients.
233−::
234−/+ shoe, verb, dbug, default-agent
235−```
236−
237−`/+` is the Ford rune which imports libraries from the `/lib` directory into
238−the subject.
239−
240−- `shoe` is the `shoe` library.
241−- `verb` is a library used to print what a Gall agent is doing.
242−- `dbug` is a library of debugging tools.
243−- `default-agent` contains a Gall agent core with minimal implementations of
244− required Gall arms.
245−
246−```hoon
247−|%
248−+$ state-0 [%0 ~]
249−+$ command ~
250−::
251−+$ card card:shoe
252−--
253−```
254−
255−The types used by the app.
256−
257−`state-0` stores the state of the app, which is null as there is no state to
258−keep track of. It is good practice to include a version number anyways,
259−in case the app is made stateful at a later time.
260−
261−`command` is typically a set of tagged union types that represent the possible
262−commands that can be entered by the user. Since this app only supports one
263−command, it is unnecessary for it to have any associated data, thus the command
264−is represented by `~`.
265−
266−In a non-trivial context, a `command` is commonly given by `[%name data]`, where `%name` is the identifier for the type of command and `data` is
267−a type or list of types that contain data needed to execute the command. See
268−`app/chat-cli.hoon` for examples of commands, such as `[%say letter:store]` and
269−`[%delete path]`. This is not required though, and you could use something like
270−`[chat-room=@t =action]`.
271−
272−`card` is either an ordinary Gall agent `card` or a `%shoe` `card`, which takes
273−the shape `[%shoe sole-ids=(list @ta) effect=shoe-effect]`. A `%shoe` `card` is
274−sent to all `sole`s listed in `sole-ids`, imaking them run the `sole-effect`
275−specified by `effect` (i.e. printing some text). Here we can
276−reference `card:shoe` because of `/+ shoe` at the beginning of the app.
277−
278−```hoon
279−=| state-0
280−=* state -
281−::
282−```
283−
284−Add the bunt value of `state-0` to the head of the subject, then give it the
285−macro `state`. The `-` here is a lark expression referring to the head of the
286−subject. This allows us to use `state` to refer to the state elsewhere in the
287−code no matter what version we're using, while also getting direct access to the
288−contents of `state` (if it had any).
289−
290−```hoon
291−%+ verb |
292−%- agent:dbug
293−^- agent:gall
294−%- (agent:shoe command)
295−^- (shoe:shoe command)
296−```
297−
298−The casts here are just reminders of what is being produced. So let's focus on
299−what the `%` runes are doing, from bottom to top. We call `(agent:shoe command)`
300−on what follows (i.e. the rest of the app),
301−producing a standard Gall agent core. Then we call wrap the Gall agent core with
302−`agent:dbug`, endowing it with additional arms useful for debugging, and then
303−wrap again with `verb`.
304−
305−```hoon
306−|_ =bowl:gall
307−+* this .
308− def ~(. (default-agent this %|) bowl)
309− des ~(. (default:shoe this command) bowl)
310−```
311−
312−This is boilerplate Gall agent core code. We set `this` to be a macro for the
313−subject, which is the Gall agent core itself. We set `def` and `des` to be
314−macros for initialized `default-agent` and `default:shoe` doors respectively.
315−
316−Next we implement all of the arms required for a `shoe` agent. Starting with
317−the standard Gall arms:
318−
319−```hoon
320−++ on-init on-init:def
321−++ on-save !>(state)
322−++ on-load
323− |= old=vase
324− ^- (quip card _this)
325− [~ this]
326−::
327−++ on-poke on-poke:def
328−++ on-watch on-watch:def
329−++ on-leave on-leave:def
330−++ on-peek on-peek:def
331−++ on-agent on-agent:def
332−++ on-arvo on-arvo:def
333−++ on-fail on-fail:def
334−```
335−
336−These are minimalist Gall app arm implementations using the default behavior found in `def`.
337−
338−Here begins the implementation of the additional arms required by the
339−`(shoe:shoe command)` interface.
340−
341−```hoon
342−++ command-parser
343− |= sole-id=@ta
344− ^+ |~(nail *(like [? command]))
345− (cold [& ~] (jest 'demo'))
346−```
347−
348−`+command-parser` is of central importance - it is what is used to parse user
349−input and transform it into `command`s for the app to execute. Writing a proper
350−command parser requires understanding of the Hoon parsing functions found in the
351−standard library. How to do so may be found in the [parsing tutorial](/docs/hoon/guides/parsing). For now, it is sufficient to know that this arm matches the text "demo" and
352−produces a `[? command]`-shaped noun in response. Note how the `&` signifies that the command will be run as soon as it has been entered, without waiting for the user to press return.
353−
354−```hoon
355−++ tab-list
356− |= sole-id=@ta
357− ^- (list [@t tank])
358− :~ ['demo' leaf+"run example command"]
359− ==
360−```
361−
362−`+tab-list` is pretty much plug-n-play. For each command you want to be tab
363−completed, add an entry to the `list` begun by `:~` of the form `[%command leaf+"description"]`. Now whenever the user types a partial command and presses
364−tab, the console will display the list of commmands that match the partial
365−command as well as the descriptions given here.
366−
367−Thus here we have that starting to type `demo` and pressing tab will result in
368−the following output in the console:
369−
370−```
371−demo run example command
372−~zod:shoe> demo
373−```
374−
375−with the remainder of `demo` now added to the input line.
376−
377−Next we have `+on-command`, which is called whenever `+command-parser`
378−recognizes that `demo` has been entered by a user.
379−
380−```hoon
381−++ on-command
382− |= [sole-id=@ta =command]
383− ^- (quip card _this)
384−```
385−
386−This is a gate that takes in the `sole-id` corresponding to the session and the
387−`command` noun parsed by `+command-parser` and returns a `list` of `card`s and
388−`_this`, which is our shoe agent core including its state.
389−
390−```hoon
391− =- [[%shoe ~ %sole -]~ this]
392−```
393−
394−This creates a cell of a `%shoe` card that triggers a `sole-effect` given by the head of
395−the subject `-`, then the Gall agent core `this` - i.e. the return result of
396−this gate. The use of the `=-` rune means that what follows this
397−expression is actually run first, which puts the desired `sole-effect` into the
398−head of the subject.
399−
400−```hoon
401− =/ =tape "{(scow %p src.bowl)} ran the command"
402−```
403−
404−We define the `tape` that we want to be printed.
405−
406−```hoon
407− ?. =(src our):bowl
408− [%txt tape]
409− [%klr [[`%br ~ `%g] [(crip tape)]~]~]
410−```
411−
412−We cannot just produce the `tape` we want printed, - it needs to fit the
413−`sole-effect` type. This tells us that if the
414−origin of the command is not our ship to just print it normally with the `%txt`
415−`sole-effect`. Otherwise we use `%klr`, which prints it stylistically (here it
416−makes the text green and bold).
417−
418−The following allows either `~zod`, or the host ship and its moons, to connect to
419−this app's command line interface using `|link`.
420−
421−```hoon
422−++ can-connect
423− |= sole-id=@ta
424− ^- ?
425− ?| =(~zod src.bowl)
426− (team:title [our src]:bowl)
427− ==
428−```
429−
430−We use the minimal implementations for the final two `shoe` arms, since we don't
431−want to do anything special when users connect or disconnect.
432−
433−```hoon
434−++ on-connect on-connect:des
435−++ on-disconnect on-disconnect:des
436−--
437−```
438−
439−This concludes our review of the code of the `%shoe` app. To continue learning
440−how to build your own CLI app, we recommend checking out `/app/chat-cli.hoon`.
content/docs/hoon/guides/json-guide.mddeleted−513
@@ -1,513 +0,0 @@
1−+++
2−title = "JSON"
3−weight = 4
4−template = "doc.html"
5−+++
6−
7−If you are working on a Gall agent with any kind of web interface, it's likely you will encounter the problem of converting Hoon data structures to JSON and vice versa. This is what we'll look at in this document.
8−
9−Urbit represents JSON data with the `$json` structure (defined in `lull.hoon`). You can refer to the [json type](#the-json-type) section below for details.
10−
11−JSON data on the web is encoded in text, so Urbit has two functions in `zuse.hoon` for dealing with this:
12−
13−- [`+en-json:html`](/docs/hoon/reference/zuse/2e_2-3#en-jsonhtml) - For printing `$json` to a text-encoded form.
14−- [`+de-json:html`](/docs/hoon/reference/zuse/2e_2-3#de-jsonhtml) - For parsing text-encoded JSON to a `$json` structure.
15−
16−You typically want `$json` data converted to some other `noun` structure or vice versa, so Urbit has three collections of functions for this purpose, also in `zuse.hoon`:
17−
18−- [`+enjs:format`](/docs/hoon/reference/zuse/2d_1-5#enjsformat) - Functions for converting various atoms and structures to `$json`.
19−- [`+dejs:format`](/docs/hoon/reference/zuse/2d_6#dejsformat) - Many "reparsers" for converting `$json` data to atoms and other structures.
20−- [`+dejs-soft:format`](/docs/hoon/reference/zuse/2d_7#dejs-softformat) - Largely the same as `+dejs:format` except its reparsers produce `unit`s which are null upon failure rather than simply crashing.
21−
22−The relationship between these types and functions look like this:
23−
24−![json diagram](https://media.urbit.org/docs/json-diagram.svg)
25−
26−Note this diagram is a simplification - the `+dejs:format` and `+enjs:format` collections in particular are tools to be used in writing conversion functions rather than simply being used by themselves, but it demonstrates the basic relationships. Additionally, it is less common to do printing/parsing manually - this would typically be handled automatically by Eyre, though it may be necessary if you're retrieving JSON data via the web client vane Iris.
27−
28−### In practice
29−
30−A typical Gall agent will have a number of structures defined in a file in the `/sur` directory. These will define the type of data it expects to be `%poke`ed with, the type of data it will `%give` to subscribers, and the type of data its scry endpoints produce.
31−
32−If the agent only interacts with other agents inside Urbit, it may just use a `%noun` `mark`. If, however, it needs to talk to a web interface of some kind, it usually must handle `$json` data with a `%json` mark.
33−
34−Sometimes an agent's interactions with a web interface are totally distinct from its interactions with other agents. If so, the agent could just have separate scry endpoints, poke handlers, etc, that directly deal with `$json` data with a `%json` mark. In such a case, you can include `$json` encoding/decoding functions directly in the agent or associated libraries, using the general techniques demonstrated in the [$json encoding and decoding example](#json-encoding-and-decoding-example) section below.
35−
36−If, on the other hand, you want a unified interface (whether interacting with a web client or within Urbit), a different approach is necessary. Rather than taking or producing either `%noun` or `%json` marked data, custom `mark` files can be created which specify conversion methods for both `%noun` and `%json` marked data.
37−
38−With this approach, an agent would take and/or produce data with some `mark` like `%my-custom-mark`. Then, when the agent must interact with a web client, the webserver vane Eyre can automatically convert `%my-custom-mark` to `%json` or vice versa. This way the agent only ever has to handle the `%my-custom-mark` data. This approach is used by `%graph-store` with its `%graph-update-2` mark, for example, and a number of other agents.
39−
40−For details of creating a `mark` file for this purpose, the [mark file example](#mark-file-example) section below walks through a practical example.
41−
42−## The `$json` type
43−
44−Urbit represents JSON data with the `$json` structure (defined in `/sys/lull.hoon`):
45−
46−```hoon
47−+$ json :: normal json value
48− $@ ~ :: null
49− $% [%a p=(list json)] :: array
50− [%b p=?] :: boolean
51− [%o p=(map @t json)] :: object
52− [%n p=@ta] :: number
53− [%s p=@t] :: string
54− == ::
55−```
56−
57−The correspondence of `$json` to JSON types is fairly self-evident, but here's a table comparing the two for additional clarity:
58−
59−| JSON Type | `$json` Type | JSON Example | `$json` Example |
60−| :-------- | :--------------------- | ------------------------- | :----------------------------------------------------------- |
61−| Null | `~` | `null` | `~` |
62−| Boolean | `[%b p=?]` | `true` | `[%b p=%.y]` |
63−| Number | `[%n p=@ta]` | `123` | `[%n p=~.123]` |
64−| String | `[%s p=@t]` | `"foo"` | `[%s p='foo']` |
65−| Array | `[%a p=(list json)]` | `["foo",123]` | `[%a p=~[[%s p='foo'] [%n p=~.123]]]` |
66−| Object | `[%o p=(map @t json)]` | `{"foo":"xyz","bar":123}` | `[%o p={[p='bar' q=[%n p=~.123]] [p='foo' q=[%s p='xyz']]}]` |
67−
68−Since the `$json` `%o` object and `%a` array types may themselves contain any `$json`, you can see how JSON structures of arbitrary complexity can be represented. Note the `%n` number type is a `@ta` rather than something like a `@ud` that you might expect. This is because JSON's number type may be either an integer or floating point, so it's left as a `knot` which can then be parsed to a `@ud` or `@rd` with the appropriate [`+dejs:format`](/docs/hoon/reference/zuse/2d_6) function.
69−
70−## `$json` encoding and decoding example
71−
72−Let's have a look at a practical example. Here's a core with three arms. It has the structure arm `$user`, and then two more: `+to-js` converts a `$user` structure to `$json`, and `+from-js` does the opposite. Usually we'd define the structure in a separate `/sur` file, but for simplicity it's all in the one core.
73−
74−#### `json-test.hoon`
75−
76−```hoon
77−|%
78−+$ user
79− $: username=@t
80− name=[first=@t mid=@t last=@t]
81− joined=@da
82− email=@t
83− ==
84−++ to-js
85− |= usr=user
86− |^ ^- json
87− %- pairs:enjs:format
88− :~
89− ['username' s+username.usr]
90− ['name' name]
91− ['joined' (sect:enjs:format joined.usr)]
92− ['email' s+email.usr]
93− ==
94− ++ name
95− :- %a
96− :~
97− [%s first.name.usr]
98− [%s mid.name.usr]
99− [%s last.name.usr]
100− ==
101− --
102−++ from-js
103− =, dejs:format
104− ^- $-(json user)
105− %- ot
106− :~
107− [%username so]
108− [%name (at ~[so so so])]
109− [%joined du]
110− [%email so]
111− ==
112−--
113−```
114−
115−**Note**: This example (and a couple of others in this guide) sometimes use a syntax of `foo+bar`. This is just syntactic sugar to tag the head of `bar` with the `term` constant `%foo`, and is equivalent to `[%foo bar]`. Since `json` data is a union with head tags of `%b`, `%n`, `%s`, `%a`, or `%o`, it's sometimes convenient to do `s+'some string'`, `b+&`, etc.
116−
117−### Try it out
118−
119−First we'll try using our `$json` encoding/decoding library, and afterwards we'll take a closer look at its construction. To begin, save the code above in `/lib/json-test.hoon` of the `%base` desk on a fake ship and `|commit` it:
120−
121−```
122−> |commit %base
123−>=
124−+ /~zod/base/5/lib/json-test/hoon
125−```
126−
127−Then we need to build it so we can use it. We'll give it a face of `user-lib`:
128−
129−```
130−> =user-lib -build-file %/lib/json-test/hoon
131−```
132−
133−Let's now create an example of a `$user` structure:
134−
135−```
136−> =usr `user:user-lib`['john456' ['John' 'William' 'Smith'] now 'john.smith@example.com']
137−> usr
138−[ username='john456'
139− name=[first='John' mid='William' last='Smith']
140− joined=~2021.9.12..09.47.58..1b65
141− email='john.smith@example.com'
142−]
143−```
144−
145−Now we can try calling the `+to-js` function with our data to convert it to `$json`:
146−
147−```
148−> =usr-json (to-js:user-lib usr)
149−> usr-json
150−[ %o
151− p
152− { [p='email' q=[%s p='john.smith@example.com']]
153− [p='name' q=[%a p=~[[%s p='John'] [%s p='William'] [%s p='Smith']]]]
154− [p='username' q=[%s p='john456']]
155− [p='joined' q=[%n p=~.1631440078]]
156− }
157−]
158−```
159−
160−Let's also see how that `$json` would look as real JSON encoded in text. We can do that with `+en-json:html`:
161−
162−```
163−> (crip (en-json:html (to-js:user-lib usr)))
164−'{"joined":1631440078,"username":"john456","name":["John","William","Smith"],"email":"john.smith@example.com"}'
165−```
166−
167−Finally, let's try converting the `$json` back to a `$user` again with our `+from-js` arm:
168−
169−```
170−> (from-js:user-lib usr-json)
171−[ username='john456'
172− name=[first='John' mid='William' last='Smith']
173− joined=~2021.9.12..09.47.58
174− email='john.smith@example.com'
175−]
176−```
177−
178−### Analysis
179−
180−#### Converting to `$json`
181−
182−Here's our arm that converts a `$user` structure to `$json`:
183−
184−```hoon
185−++ to-js
186− |= usr=user
187− |^ ^- json
188− %- pairs:enjs:format
189− :~
190− ['username' s+username.usr]
191− ['name' name]
192− ['joined' (sect:enjs:format joined.usr)]
193− ['email' s+email.usr]
194− ==
195− ++ name
196− :- %a
197− :~
198− [%s first.name.usr]
199− [%s mid.name.usr]
200− [%s last.name.usr]
201− ==
202− --
203−```
204−
205−There are different ways we could represent our `$user` structure as JSON, but in this case we've opted to encapsulate it in an object and have the `name` as an array (since JSON arrays preserve order).
206−
207−[`+enjs:format`](/docs/hoon/reference/zuse/2d_1-5#enjsformat)includes the convenient [`+pairs`](/docs/hoon/reference/zuse/2d_1-5#pairsenjsformat) function, which converts a list of `[@t json]` to an object containing those key-value pairs. We've used this to assemble the final object. Note that if you happen to have only a single key-value pair rather than a list, you can use [`+frond`](/docs/hoon/reference/zuse/2d_1-5#frondenjsformat) instead of `+pairs`.
208−
209−For the `joined` field, we've used the [`+sect`](/docs/hoon/reference/zuse/2d_1-5#sectenjsformat) function from `+enjs` to convert the `@da` to a Unix seconds timestamp in a `$json` number. The `+sect` function, like others in `+enjs`, takes in a noun (in this case a `@da`) and produces `$json` (in this case a `[%n @ta]` number). `+enjs` contains a handful of useful functions like this, but for the rest we've just hand-made the `$json` structure. This is fairly typical when encoding `$json`, it's usually [decoding](#converting-from-json) that makes more extensive use of the `$json` utility functions in `+format`.
210−
211−For the `name` field we've just formed a cell of `%a` and a list of `$json` strings, since a `$json` array is `[%a p=(list json)]`. Note we've separated this part into its own arm and wrapped the whole thing in a `|^` - a core with a `$` arm that's computed immediately. This is simply for readability - our structure here is quite simple but when dealing with deeply-nested `$json` structures or complex logic, having a single giant function can quickly become unwieldy.
212−
213−#### Converting from `$json`
214−
215−Here's our arm that converts `$json` to our `$user` structure:
216−
217−```hoon
218−++ from-js
219− =, dejs:format
220− ^- $-(json user)
221− %- ot
222− :~
223− [%username so]
224− [%name (at ~[so so so])]
225− [%joined du]
226− [%email so]
227− ==
228−```
229−
230−This is the inverse of the [encoding](#converting-to-json) function described in the previous section.
231−
232−We make extensive use of [`+dejs:format`](/docs/hoon/reference/zuse/2d_6) functions here, so we've used `=,` to expose the namespace and allow succinct `+dejs` function calls.
233−
234−We use the [`+ot`](/docs/hoon/reference/zuse/2d_6#otdejsformat) function from `+dejs:format` to decode the `$json` object to a n-tuple. It's a wet gate that takes a list of pairs of keys and other `+dejs` functions and produces a new gate that takes the `$json` to be decoded (which we've given it in `jon`).
235−
236−The [`+so`](/docs/hoon/reference/zuse/2d_6#sodejsformat) functions just decode `$json` strings to `cord`s. The [`+at`](/docs/hoon/reference/zuse/2d_6#atdejsformat) function converts a `$json` array to a tuple, decoding each element with the respective function given in its argument list. Like `+ot`, `+at` is also a wet gate that produces a gate that takes `$json`. In our case we've used `+so` for each element, since they're all strings.
237−
238−For `joined`, we've used the [`+du`](/docs/hoon/reference/zuse/2d_6#dudejsformat) function, which converts a Unix seconds timestamp in a `$json` number to a `@da` (it's basically the inverse of the `+sect:enjs:format` we used earlier).
239−
240−Notice how `+ot` takes in other `+dejs` functions in its argument. One of its arguments includes the `+at` function which itself takes in other `+dejs` functions. There are several `+dejs` functions like this that allow complex nested JSON structures to be decoded. For other examples of common `+dejs` functions like this, see the [More `+dejs`](#more-dejs) section below.
241−
242−There are dozens of different functions in [`+dejs:format`](/docs/hoon/reference/zuse/2d_6) that will cover a great many use cases. If there isn't a `+dejs` function for a particular case, you can also just write a custom function - it just has to take `$json`. Note there's also the [`+dejs-soft:format`](/docs/hoon/reference/zuse/2d_7) functions - these are similar to `+dejs` functions except they produce `unit`s rather than simply crashing if decoding fails.
243−
244−## More `+dejs`
245−
246−We looked at the commonly used `+ot` function in the [first example](#converting-from-json), now let's look at a couple more common `+dejs` functions.
247−
248−### `+of`
249−
250−The [`+of`](/docs/hoon/reference/zuse/2d_6#ofdejsformat) function takes an object containing a single key-value pair, decodes the value with the corresponding `+dejs` function in a key-function list, and produces a key-value tuple. This is useful when there are multiple possible objects you might receive, and tagged unions are a common data structure in hoon.
251−
252−Let's look at an example. Here's a gate that takes in some `$json`, decodes it with an `+of` function that can handle three possible objects, casts the result to a tagged union, switches against its head with `?-`, performs some transformation and finally returns the result. You can save it as `gen/of-test.hoon` in the `%base` desk of a fake ship and `|commit %base`.
253−
254−#### `of-test.hoon`
255−
256−```hoon
257−|= jon=json
258−|^ ^- @t
259−=/ =fbb
260− (to-fbb jon)
261−?- -.fbb
262− %foo (cat 3 +.fbb '!!!')
263− %bar ?:(+.fbb 'Yes' 'No')
264− %baz :((cury cat 3) p.fbb q.fbb r.fbb)
265−==
266−+$ fbb
267− $% [%foo @t]
268− [%bar ?]
269− [%baz p=@t q=@t r=@t]
270− ==
271−++ to-fbb
272−=, dejs:format
273−%- of
274−:~ foo+so
275− bar+bo
276− baz+(at ~[so so so])
277−==
278−--
279−```
280−
281−Let's try it:
282−
283−```
284−> +of-test (need (de-json:html '{"foo":"Hello"}'))
285−'Hello!!!'
286−
287−> +of-test (need (de-json:html '{"bar":true}'))
288−'Yes'
289−
290−> +of-test (need (de-json:html '{"baz":["a","b","c"]}'))
291−'abc'
292−```
293−
294−### `+ou`
295−
296−The [`+ou`](/docs/hoon/reference/zuse/2d_6#oudejsformat) function decodes a `$json` object to an n-tuple using the matching functions in a key-function list. Additionally, it lets you set some key-value pairs in an object as optional and others as mandatory. The mandatory ones crash if they're missing and the optional ones are replaced with a given noun.
297−
298−`+ou` is different to other `+dejs` functions - the functions it takes are `$-((unit json) grub)` rather than the usual `$-(json grub)` of most `+dejs` functions. There are only two `+dejs` functions that fit this - [`+un`](/docs/hoon/reference/zuse/2d_6#undejsformat) and [`+uf`](/docs/hoon/reference/zuse/2d_6#ufdejsformat). These are intended to be used with `+ou` - you would wrap each function in the key-function list of `+ou` with either `+un` or `+uf`.
299−
300−`+un` crashes if its argument is `~`. `+ou` gives functions a `~` if the matching key-value pair is missing in the `$json` object, so `+un` crashes if the key-value pair is missing. Therefore, `+un` lets you set key-value pairs as mandatory.
301−
302−`+uf` takes two arguments - a noun and a `+dejs` function. If the `(unit json)` it's given by `+ou` is `~`, it produces the noun it was given rather than the product of the `+dejs` function. This lets you specify key-value pairs as optional, replacing missing ones with whatever you want.
303−
304−Let's look at a practical example. Here's a generator you can save in the `%base` desk of a fake ship in `gen/ou-test.hoon` and `|commit %base`. It takes in a `$json` object and produces a triple. The `+ou` in `+decode` has three key-function pairs - the first two are mandatory and the last is optional, producing the bunt of a set if the `%baz` key is missing.
305−
306−#### `ou-test.hoon`
307−
308−```hoon
309−|= jon=json
310−|^ ^- [@t ? (set @ud)]
311−(decode jon)
312−++ decode
313−=, dejs:format
314−%- ou
315−:~ foo+(un so)
316− bar+(un bo)
317− baz+(uf *(set @ud) (as ni))
318−==
319−--
320−```
321−
322−Let's try it:
323−
324−```
325−> +ou-test (need (de-json:html '{"foo":"hello","bar":true,"baz":[1,2,3,4]}'))
326−['hello' %.y {1 2 3 4}]
327−
328−> +ou-test (need (de-json:html '{"foo":"hello","bar":true}'))
329−['hello' %.y {}]
330−
331−> +ou-test (need (de-json:html '{"foo":"hello"}'))
332−[%key 'bar']
333−dojo: hoon expression failed
334−```
335−
336−### `+su`
337−
338−The [`+su`](/docs/hoon/reference/zuse/2d_6#sudejsformat) function parses a string with the given parsing `rule`. Hoon's functional parsing library is very powerful and lets you create arbitrarily complex parsers. JSON will often have data types encoded in strings, so this function can be very useful. The writing of parsers is outside the scope of this guide, but you can see the [Parsing Guide](/docs/hoon/guides/parsing) and sections 4e to 4j of the standard library documentation for details.
339−
340−Here are some simple examples of using `+su` to parse strings:
341−
342−```
343−> `@ux`((su:dejs:format hex) s+'deadbeef1337f00D')
344−0xdead.beef.1337.f00d
345−
346−> `(list @)`((su:dejs:format (most lus dem)) s+'1+2+3+4')
347−~[1 2 3 4]
348−
349−> `@ub`((su:dejs:format ven) s+'+>-<->+<+')
350−0b11.1000.1101
351−```
352−
353−Here's a more complex parser that will parse a GUID like `824e7749-4eac-9c00-db16-4cb816cd6f19` to a `@ux`:
354−
355−#### `su-test.hoon`
356−
357−```hoon
358−|= jon=json
359−^- @ux
360−%. jon
361−%- su:dejs:format
362−%+ cook
363−|= parts=(list [step @])
364−^- @ux
365−(can 3 (flop parts))
366−;~ plug
367− (stag 4 ;~(sfix (bass 16 (stun 8^8 six:ab)) hep))
368− (stag 2 ;~(sfix qix:ab hep))
369− (stag 2 ;~(sfix qix:ab hep))
370− (stag 2 ;~(sfix qix:ab hep))
371− (stag 6 (bass 16 (stun 12^12 six:ab)))
372− (easy ~)
373−==
374−```
375−
376−Save it in the `/gen` directory of the `%base` desk and `|commit` it. We can then try it with:
377−
378−```
379−> +su-test s+'5323a61d-0c26-d8fa-2b73-18cdca805fd8'
380−0x5323.a61d.0c26.d8fa.2b73.18cd.ca80.5fd8
381−```
382−
383−If we delete the last character it'll no longer be a valid GUID and the parsing will fail:
384−
385−```
386−> +su-test s+'5323a61d-0c26-d8fa-2b73-18cdca805fd'
387−/gen/su-test/hoon:<[2 1].[16 3]>
388−/gen/su-test/hoon:<[3 1].[16 3]>
389−{1 36}
390−syntax error
391−dojo: naked generator failure
392−```
393−
394−## `mark` file example
395−
396−Here's a simple `mark` file for the `$user` structure we created in the [first example](#json-encoding-and-decoding-example). It imports the [json-test.hoon](#json-testhoon) library we created and saved in our `%base` desk's `/lib` directory.
397−
398−#### `user.hoon`
399−
400−```hoon
401−/+ *json-test
402−|_ usr=user
403−++ grab
404− |%
405− ++ noun user
406− ++ json from-js
407− --
408−++ grow
409− |%
410− ++ noun usr
411− ++ json (to-js usr)
412− --
413−++ grad %noun
414−--
415−```
416−
417−The [Marks section](/docs/arvo/clay/marks/marks) of the Clay documentation covers `mark` files comprehensively and is worth reading through if you want to write a mark file.
418−
419−In brief, a mark file contains a `door` with three arms. The door's sample type is the type of the data in question - in our case the `$user` structure. The `+grab` arm contains methods for converting _to_ our mark, and the `+grow` arm contains methods for converting _from_ our mark. The `+noun` arms are mandatory, and then we've added `+json` arms which respectively call the `+from-js` and `+to-js` functions from our `json-test.hoon` library. The final `+grad` arm defines various revision control functions, in our case we've delegated these to the `%noun` mark.
420−
421−From this mark file, Clay can build mark conversion gates between the `%json` mark and our `%user` mark, allowing the conversion of `$json` data to a `$user` structure and vice versa.
422−
423−### Try it out
424−
425−First, we'll save the code above as `user.hoon` in the `/mar` directory our of `%base` desk:
426−
427−```
428−> |commit %base
429−>=
430−+ /~zod/base/9/mar/user/hoon
431−```
432−
433−Let's quickly create a `$json` object to work with:
434−
435−```
436−> =jon (need (de-json:html '{"joined":1631440078,"username":"john456","name":["John","William","Smith"],"email":"john.smith@example.com"}'))
437−> jon
438−[ %o
439− p
440− { [p='email' q=[%s p='john.smith@example.com']]
441− [p='name' q=[%a p=~[[%s p='John'] [%s p='William'] [%s p='Smith']]]]
442− [p='username' q=[%s p='john456']]
443− [p='joined' q=[%n p=~.1631440078]]
444− }
445−]
446−```
447−
448−We'll also build our library so we can use its types from the dojo:
449−
450−```
451−> =user-lib -build-file %/lib/json-test/hoon
452−```
453−
454−Now we can ask Clay to build a mark conversion gate from a `%json` mark to our `%user` mark. We'll use a scry with a `%f` `care` which produces a static mark conversion gate:
455−
456−```
457−> =json-to-user .^($-(json user:user-lib) %cf /===/json/user)
458−```
459−
460−Let's try converting our `$json` to a `$user` structure with our new mark conversion gate:
461−
462−```
463−> =usr (json-to-user jon)
464−> usr
465−[ username='john456'
466− name=[first='John' mid='William' last='Smith']
467− joined=~2021.9.12..09.47.58
468− email='john.smith@example.com'
469−]
470−```
471−
472−Now let's try the other direction. We'll again scry Clay to build a static mark conversion gate, this time _from_ `%user` _to_ `%json` rather than the reverse:
473−
474−```
475−> =user-to-json .^($-(user:user-lib json) %cf /===/user/json)
476−```
477−
478−Let's test it out by giving it our `$user` data:
479−
480−```
481−> (user-to-json usr)
482−[ %o
483− p
484− { [p='email' q=[%s p='john.smith@example.com']]
485− [p='name' q=[%a p=~[[%s p='John'] [%s p='William'] [%s p='Smith']]]]
486− [p='username' q=[%s p='john456']]
487− [p='joined' q=[%n p=~.1631440078]]
488− }
489−]
490−```
491−
492−Finally, let's see how that looks as JSON encoded in text:
493−
494−```
495−> (crip (en-json:html (user-to-json usr)))
496−'{"joined":1631440078,"username":"john456","name":["John","William","Smith"],"email":"john.smith@example.com"}'
497−```
498−
499−Usually (though not in all cases) these mark conversions will be performed implicitly by Gall or Eyre and you'd not deal with the mark conversion gates directly, but it's still informative to see them work explicitly.
500−
501−## Further reading
502−
503−[The Zuse library reference](/docs/hoon/reference/zuse/table-of-contents) - This includes documentation of the JSON parsing, printing, encoding and decoding functions.
504−
505−[The Marks section of the Clay documentation](/docs/arvo/clay/marks/marks) - Comprehensive documentation of `mark`s.
506−
507−[The External API Reference section of the Eyre documentation](/docs/arvo/eyre/external-api-ref) - Details of the webserver vane Eyre's external API.
508−
509−[The Iris documentation](/docs/arvo/iris/iris) - Details of the web client vane Iris, which may be used to fetch external JSON data among other things.
510−
511−[Strings Guide](/docs/hoon/guides/strings) - Atom printing functions like `+scot` will often be useful for JSON encoding - see the [Encoding in Text](/docs/hoon/guides/strings#encoding-in-text) section for usage.
512−
513−[Parsing Guide](/docs/hoon/guides/parsing) - Learn how to write functional parsers in hoon which can be used with `+su`.
content/docs/hoon/guides/parsing.mddeleted−709
@@ -1,709 +0,0 @@
1−+++
2−title = "Parsing"
3−weight = 3
4−template = "doc.html"
5−+++
6−
7−This document serves as an introduction to parsing text with Hoon. No prior
8−knowledge of parsing is required, and we will explain the basic structure of how
9−parsing works in a purely functional language such as Hoon before moving on to
10−how it is implemented in Hoon.
11−
12−**Note:** For JSON printing/parsing and encoding/decoding, see the [JSON Guide](/docs/hoon/guides/json-guide).
13−
14−## What is parsing? {% #what-is-parsing %}
15−
16−A program which takes a raw sequence of characters as an input and produces a data
17−structure as an output is known as a _parser_. The data structure produced
18−depends on the use case, but often it may be represented as a tree and the
19−output is thought of as a structural representation of the input. Parsers are ubiquitous in
20−computing, commonly used for to perform tasks such as reading files, compiling
21−source code, or understanding commands input in a command line interface.
22−
23−Parsing a string is rarely done all at once. Instead, it is usually done
24−character-by-character, and the return contains the data structure representing
25−what has been parsed thus far as well as the remainder of the string to be
26−parsed. They also need to be able to fail in case the input is improperly
27−formed. We will see each of these standard practices implemented in [Hoon below](#parsing-in-hoon).
28−
29−## Functional parsers
30−
31−How parsers are built varies substantially depending on what sort of programming
32−language it is written in. As Hoon is a functional programming language, we will
33−be focused on understanding _functional parsers_, also known as _combinator
34−parsers_. In this section we will make light use of pseudocode, as introducing
35−the Hoon to describe functional parsers here creates a chicken-and-egg problem.
36−
37−Complex functional parsers are built piece by piece from simpler parsers
38−that are plugged into one another in various ways to perform the desired task.
39−
40−The basic building blocks, or primitives, are parsers that read only a
41−single character. There are frequently a few types of possible input characters,
42−such as letters, numbers, and symbols. For example, `(parse "1" integer)` calls
43−the parsing routine on the string `"1"` and looks for an integer, and so it
44−returns the integer `1`. However, taking into account what was said above about
45−parsers returning the unparsed portion of the string as well, we should
46−represent this return as a tuple. So we should expect something like this:
47−
48−```
49−> (parse "1" integer)
50−[1 ""]
51−> (parse "123" integer)
52−[1 "23"]
53−```
54−
55−What if we wish to parse the rest of the string? We would need to apply the
56−`parse` function again:
57−
58−```
59−> (parse (parse "123" integer) integer)
60−[12 "3"]
61−> (parse (parse (parse "123" integer) integer) integer)
62−[123 ""]
63−```
64−
65−So we see that we can parse strings larger than one character by stringing
66−together parsing functions for single characters. Thus in addition to parsing
67−functions for single input characters, we want _parser combinators_ that
68−allow you to combine two or more parsers to form a more complex one.
69−Combinators come in a few shapes and sizes, and typical operations they may
70−perform would be to repeat the same parsing operation until the string is
71−consumed, try a few different parsing operations until one of them works,
72−or perform a sequence of parsing operations. We will see how all of this is done
73−with Hoon in the next section.
74−
75−# Parsing in Hoon
76−
77−In this section we will cover the basic types, parser functions, and parser
78−combinators that are utilized for parsing in Hoon. This is not a complete guide
79−to every parsing-related functionality in the standard library (of which there
80−are quite a few), but ought to be
81−sufficient to get started with parsing in Hoon and be equipped to discover the
82−remainder yourself.
83−
84−## Basic types
85−
86−In this section we discuss the types most commonly used for Hoon parsers. In short:
87−
88−- A `hair` is the position in the text the parser is at,
89−- A `nail` is parser input,
90−- An `edge` is parser output,
91−- A `rule` is a parser.
92−
93−### `hair`
94−
95−```hoon
96−++ hair [p=@ud q=@ud]
97−```
98−
99−A `hair` is a pair of `@ud` used to keep track of what has already been parsed
100−for stack tracing purposes. This allows the parser to reveal where the problem
101−is in case it hits something unexpected during parsing.
102−
103−`p` represents the column and `q` represents the line.
104−
105−### `nail`
106−
107−```hoon
108−++ nail [p=hair q=tape]
109−```
110−
111−We recall from our [discussion above](#what-is-parsing) that parsing functions must keep
112−track of both what has been parsed and what has yet to be parsed. Thus a `nail`
113−consists of both a `hair`, giving the line and column up to which the input
114−sequence has already been parsed, and a `tape`, consisting of what remains of
115−the original input string (i.e. everything after the location indicated by the
116−`nail`, including the character at that `nail`).
117−
118−For example, if you wish to feed the entire `tape` `"abc"` into a parser, you
119−would pass it as the `nail` `[[1 1] "abc"]`. If the parser successfully parses the first
120−character, the `nail` it returns will be `[[1 2] "bc"]` (though we note that
121−parser outputs are actually `edge`s which contain a `nail`, see the following).
122−The `nail` only matters for book-keeping reasons - it could be any value here
123−since it doesn't refer to a specific portion of the string being input, but only
124−what has theoretically already been parsed up to that point.
125−
126−### `edge`
127−
128−```hoon
129−++ edge [p=hair q=(unit [p=* q=nail])]
130−```
131−
132−An `edge` is the output of a parser. If parsing succeeded, `p` is the location
133−of the original input `tape `up to which the text has been parsed. If parsing
134−failed, `p` will be the first `hair` at which parsing failed.
135−
136−`q` may be `~`, indicating that parsing has failed .
137−If parsing did not fail, `p.q` is the data structure that is the result of the
138−parse up to this point, while `q.q` is the `nail` which contains the remainder
139−of what is to be parsed. If `q` is not null, `p` and `p.q.q` are identical.
140−
141−### `rule`
142−
143−```hoon
144−++ rule _|:($:nail $:edge)
145−```
146−
147−A `rule` is a gate which takes in a `nail` and returns an `edge` - in other
148−words, a parser.
149−
150−## Parser builders
151−
152−These functions are used to build `rule`s (i.e. parsers), and thus are often
153−called rule-builders. For a complete list of parser builders, see [4f: Parsing
154−(Rule-Builders)](/docs/hoon/reference/stdlib/4f), but also the more specific
155−functions in [4h: Parsing (ASCII
156−Glyphs)](/docs/hoon/reference/stdlib/4h), [4i: Parsing (Useful
157−Idioms)](/docs/hoon/reference/stdlib/4i), [4j: Parsing (Bases and Base
158−Digits)](/docs/hoon/reference/stdlib/4j), [4l: Atom Parsing](/docs/hoon/reference/stdlib/4l).
159−
160−### [`+just`](/docs/hoon/reference/stdlib/4f/#just)
161−
162−The most basic rule builder, `+just` takes in a single `char` and produces a
163−`rule` that attempts to match that `char` to the first character in the `tape`
164−of the input `nail`.
165−
166−```
167−> =edg ((just 'a') [[1 1] "abc"])
168−> edg
169−[p=[p=1 q=2] q=[~ [p='a' q=[p=[p=1 q=2] q="bc"]]]]
170−```
171−
172−We note that `p.edg` is `[p=1 q=2]`, indicating that the next character to be
173−parsed is in line 1, column 2. `q.edg` is not null, indicating that parsing
174−succeeded. `p.q.edg` is `'a'`, which is the result of the parse. `p.q.q.edg` is the same as `p.edg`, which is always the case for
175−`rule`s built using standard library functions when parsing succeeds. Lastly,
176−`q.q.edg` is `"bc"`, which is the part of the input `tape` that has yet to be parsed.
177−
178−Now let's see what happens when parsing fails.
179−
180−```
181−> =edg ((just 'b') [[1 1] "abc"])
182−> edg
183−[p=[p=1 q=1] q=~]
184−```
185−
186−Now we have that `p.edg` is the same as the input `hair`, `[1 1]`, meaning the
187−parser has not advanced since parsing failed. `q.edg` is null, indicating that
188−parsing has failed.
189−
190−Later we will use [+star](#star) to string together a sequence of `+just`s in
191−order to parse multiple characters at once.
192−
193−### [`+jest`](/docs/hoon/reference/stdlib/4f/#jest)
194−
195−`+jest` is a `rule` builder used to match a `cord`. It takes an input `cord` and
196−produces a `rule` that attempts to match that `cord` against the beginning of
197−the input.
198−
199−Let's see what happens when we successfully parse the entire input `tape`.
200−
201−```
202−> =edg ((jest 'abc') [[1 1] "abc"])
203−> edg
204−[p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=""]]]]
205−```
206−
207−`p.edg` is `[p=1 q=4]`, indicating that the next character to be parsed is at
208−line 1, column 4. Of course, this does not exist since the input `tape` was only
209−3 characters long, so this actually indicates that the entire `tape` has been
210−successfully parsed (since the `hair` does not advance in the case of failure).
211−`p.q.edg` is `'abc'`, as expected. `q.q.edg` is `""`, indicating that nothing
212−remains to be parsed.
213−
214−What happens if we only match some of the input `tape`?
215−
216−```
217−> =edg ((jest 'ab') [[1 1] "abc"])
218−> edg
219−[p=[p=1 q=3] q=[~ [p='ab' q=[p=[p=1 q=3] q="c"]]]]
220−```
221−
222−Now we have that the result, `p.q.edg`, is `'ab'`, while the remainder `q.q.q.edg`
223−is `"c"`. So `+jest` has successfully parsed the first two characters, while the
224−last character remains. Furthermore, we still have the information that the
225−remaining character was in line 1 column 3 from `p.edg` and `p.q.q.edg`.
226−
227−What happens when `+jest` fails?
228−
229−```
230−> ((jest 'bc') [[1 1] "abc"])
231−[p=[p=1 q=1] q=~]
232−```
233−
234−Despite the fact that `'bc'` appears in `"abc"`, because it was not at the
235−beginning the parse failed. We will see in [parser
236−combinators](#parser-combinators) how to modify this `rule` so that it
237−finds `bc` successfully.
238−
239−### [`+shim`](/docs/hoon/reference/stdlib/4f/#shim)
240−
241−`+shim` is used to parse characters within a given range. It takes in two atoms
242−and returns a `rule`.
243−
244−```
245−> ((shim 'a' 'z') [[1 1] "abc"])
246−[p=[p=1 q=2] q=[~ [p='a' q=[p=[p=1 q=2] q="bc"]]]]
247−```
248−
249−### [`+next`](/docs/hoon/reference/stdlib/4f/#next)
250−
251−`+next` is a simple `rule` that takes in the next character and returns it as the
252−parsing result.
253−
254−```
255−> (next [[1 1] "abc"])
256−[p=[p=1 q=2] q=[~ [p='a' q=[p=[p=1 q=2] q="bc"]]]]
257−```
258−
259−### [`+cold`](/docs/hoon/reference/stdlib/4f/#cold)
260−
261−`+cold` is a `rule` builder that takes in a constant noun we'll call `cus` and a
262−`rule` we'll call `sef`. It returns a `rule` identical to the `sef` except it
263−replaces the parsing result with `cus`.
264−
265−Here we see that `p.q` of the `edge` returned by the `rule` created with `+cold`
266−is `%foo`.
267−
268−```
269−> ((cold %foo (just 'a')) [[1 1] "abc"])
270−[p=[p=1 q=2] q=[~ u=[p=%foo q=[p=[p=1 q=2] q="bc"]]]]
271−```
272−
273−One common scenario where `+cold` sees play is when writing [command line
274−interface (CLI) apps](/docs/hoon/guides/cli-tutorial). We usher the
275−reader there to find an example where `+cold` is used.
276−
277−### [`+knee`](/docs/hoon/reference/stdlib/4f/#knee)
278−
279−Another important function in the parser builder library is `+knee`, used for building
280−recursive parsers. We delay discussion of `+knee` to the
281−[section below](#recursive-parsers) as more context is needed to explain it
282−properly.
283−
284−## Outside callers
285−
286−Since `hair`s, `nail`s, etc. are only utilized within the context of writing
287−parsers, we'd like to hide them from the rest of the code of a program that
288−utilizes parsers. That is to say, you'd like the programmer to only worry about
289−passing `tape`s to the parser, and not have to dress up the `tape` as a `nail`
290−themselves. Thus we have several functions for exactly this purpose.
291−
292−These functions take in either a `tape` or a `cord`,
293−alongside a `rule`, and attempt to parse the input with the `rule`. If the
294−parse succeeds, it returns the result. There are crashing and unitized versions
295−of each caller, corresponding to what happens when a parse fails.
296−
297−For additional information including examples see [4g: Parsing (Outside Caller)](/docs/hoon/reference/stdlib/4g).
298−
299−### Parsing `tape`s
300−
301−[`+scan`](/docs/hoon/reference/stdlib/4g/#scan) takes in a `tape` and a `rule` and attempts to parse the `tape` with the
302−`rule`.
303−
304−```
305−> (scan "hello" (jest 'hello'))
306−'hello'
307−> (scan "hello zod" (jest 'hello'))
308−{1 6}
309−'syntax-error'
310−```
311−
312−[`+rust`](/docs/hoon/reference/stdlib/4g/#rust) is the unitized version of `+scan`.
313−
314−```
315−> (rust "a" (just 'a'))
316−[~ 'a']
317−> (rust "a" (just 'b'))
318−~
319−```
320−
321−For the remainder of this tutorial we will make use of `+scan` so that we do not
322−need to deal directly with `nail`s except where it is illustrative to do so.
323−
324−### Parsing atoms
325−
326−[Recall](/docs/hoon/hoon-school/lists) that `cord`s are atoms with the aura
327−`@t` and are typically used to represent strings internally as data, as atoms
328−are faster for the computer to work with than `tape`s, which are `list`s of
329−`@tD` atoms. [`+rash`](/docs/hoon/reference/stdlib/4g/#rash) and [`+rush`](/docs/hoon/reference/stdlib/4g/#rush) are for parsing atoms, with `+rash` being
330−analogous to `+scan` and `+rush` being analogous to `+rust`. Under the hood, `+rash`
331−calls `+scan` after converting the input atom to a `tape`, and `+rush` does
332−similary for `+rust`.
333−
334−## Parser modifiers
335−
336−The standard library provides a number of gates that take a `rule` and produce a
337−new modified `rule` according to some process. We call these _parser modifiers_.
338−These are documented among the [parser
339−builders](/docs/hoon/reference/stdlib/4f).
340−
341−### [`+ifix`](/docs/hoon/reference/stdlib/4f/#ifix)
342−
343−`+ifix` modifies a `rule` so that it matches that `rule` only when it is
344−surrounded on both sides by text that matches a pair of `rule`s, which is discarded.
345−
346−```
347−> (scan "(42)" (ifix [pal par] (jest '42')))
348−'42'
349−```
350−
351−`+pal` and `+par` are shorthand for `(just '(')` and `(just ')')`, respectively. All
352−ASCII glyphs have counterparts of this sort, documented
353−[here](/docs/hoon/reference/stdlib/4h).
354−
355−### [`+star`](/docs/hoon/reference/stdlib/4f/#star) {% #star %}
356−
357−`+star` is used to apply a `rule` repeatedly. Recall that `+just` only parses
358−the first character in the input `tape.`
359−
360−```
361−> ((just 'a') [[1 1] "aaaa"])
362−[p=[p=1 q=2] q=[~ [p='a' q=[p=[p=1 q=2] q="aaa"]]]]
363−```
364−
365−We can use `+star` to get the rest of the `tape`:
366−
367−```
368−> ((star (just 'a')) [[1 1] "aaa"])
369−[p=[p=1 q=4] q=[~ [p=[i='a' t=<|a a|>] q=[p=[p=1 q=4] q=""]]]]
370−```
371−
372−and we note that the parsing ceases when it fails.
373−
374−```
375−> ((star (just 'a')) [[1 1] "aaab"])
376−[p=[p=1 q=4] q=[~ [p=[i='a' t=<|a a|>] q=[p=[p=1 q=4] q="b"]]]]
377−```
378−
379−We can combine `+star` with `+next` to just return the whole input:
380−
381−```
382−> ((star next) [[1 1] "aaabc"])
383−[p=[p=1 q=6] q=[~ [p=[i='a' t=<|a a b c|>] q=[p=[p=1 q=6] q=""]]]]
384−```
385−
386−### [`+cook`](/docs/hoon/reference/stdlib/4f/#cook)
387−
388−`+cook` takes a `rule` and a gate and produces a modified version of the `rule`
389−that passes the result of a successful parse through the given gate.
390−
391−Let's modify the rule `(just 'a')` so that it when it successfully parses `a`,
392−it returns the following letter `b` as the result.
393−
394−```
395−((cook |=(a=@ `@t`+(a)) (just 'a')) [[1 1] "abc"])
396−[p=[p=1 q=2] q=[~ u=[p='b' q=[p=[p=1 q=2] q="bc"]]]]
397−```
398−
399−## Parser combinators
400−
401−Building complex parsers from simpler parsers is accomplished in Hoon with the
402−use of two tools: the monadic applicator rune
403−[`;~`](/docs/hoon/reference/rune/mic/#-micsig) and [parsing
404−combinators](/docs/hoon/reference/stdlib/4e). First we introduce a few
405−combinators, then we examine more closely how `;~` is used to chain them together.
406−
407−The syntax to combine `rule`s is
408−
409−```hoon
410−;~(combinator rule1 rule2 ... ruleN)
411−```
412−
413−The `rule`s are composed together using the combinator as an
414−intermediate function, which takes the product of a `rule` (an `edge`) and a `rule` and turns
415−it into a sample (a `nail`) for the next `rule` to handle. We elaborate on this
416−behavior [below](#micsig).
417−
418−### [`+plug`](/docs/hoon/reference/stdlib/4e/#plug)
419−
420−`+plug` simply takes the `nail` in the `edge` produced by one rule and passes it
421−to the next `rule`, forming a cell of the results as it proceeds.
422−
423−```
424−> (scan "starship" ;~(plug (jest 'star') (jest 'ship')))
425−['star' 'ship']
426−```
427−
428−### [`+pose`](/docs/hoon/reference/stdlib/4e/#pose)
429−
430−`+pose` tries each `rule` you hand it successively until it finds one that
431−works.
432−
433−```
434−> (scan "a" ;~(pose (just 'a') (just 'b')))
435−'a'
436−> (scan "b" ;~(pose (just 'a') (just 'b')))
437−'b'
438−```
439−
440−### [`+glue`](/docs/hoon/reference/stdlib/4e/#glue)
441−
442−`+glue` parses a delimiter in between each `rule` and forms a cell of the
443−results of each `rule`.
444−
445−```
446−> (scan "a,b" ;~((glue com) (just 'a') (just 'b')))
447−['a' 'b']
448−> (scan "a,b,a" ;~((glue com) (just 'a') (just 'b')))
449−{1 4}
450−syntax error
451−> (scan "a,b,a" ;~((glue com) (just 'a') (just 'b') (just 'a')))
452−['a' 'b' 'a']
453−```
454−
455−### [`;~`](/docs/hoon/reference/rune/mic/#-micsig) {% #micsig %}
456−
457−Understanding the rune `;~` is essential to building parsers with Hoon. Let's
458−take this opportunity to think about it carefully.
459−
460−The `rule` created by `;~(combinator (list rule))` may be understood
461−inductively. To do this, let's consider the base case where our `(list rule)` has only a
462−single entry.
463−
464−```
465−> (scan "star" ;~(plug (jest 'star')))
466−'star'
467−```
468−
469−Our output is identical to that given by `(scan "star" (jest 'star'))`. This is to
470−be expected. The combinator `+plug` is specifically used for chaining together
471−`rule`s in the `(list rule)`, but if there is only one `rule`, there is nothing
472−to chain. Thus, swapping out `+plug` for another combinator makes no difference here:
473−
474−```
475−> (scan "star" ;~(pose (jest 'star')))
476−'star'
477−> (scan "star" ;~((glue com) (jest 'star')))
478−'star'
479−```
480−
481−`;~` and the combinator only begin to play a role once the `(list rule)` has at
482−least two elements. So let's look at an example done with `+plug`, the simplest
483−combinator.
484−
485−```
486−> (scan "star" ;~(plug (jest 'st') (jest 'ar')))
487−['st' 'ar']
488−```
489−
490−Our return suggests that we first parsed `"star"` with the `rule` `(jest 'st')` and passed
491−the resulting `edge` to `(jest 'ar')` - in other words, we called `+plug` on `(jest 'st')` and the `edge` returned once it had been used to parse `"star"`. Thus
492−`+plug` was the glue that allowed us to join the two `rule`s, and `;~` performed
493−the gluing operation. And so, swapping `+plug` for `+pose` results in a crash,
494−which clues us into the fact that the combinator now has an effect since there
495−is more than one `rule`.
496−
497−```
498−> (scan "star" ;~(pose (jest 'st') (jest 'ar')))
499−{1 3}
500−syntax error
501−```
502−
503−## Parsing numbers
504−
505−Functions for parsing numbers are documented in [4j: Parsing (Bases and Base
506−Digits)](/docs/hoon/reference/stdlib/4j). In particular,
507−[`dem`](/docs/hoon/reference/stdlib/4i/#dem) is a `rule` for parsing decimal
508−numbers.
509−
510−```
511−> (scan "42" dem)
512−42
513−> (add 1 (scan "42" dem))
514−43
515−```
516−
517−## Recursive parsers
518−
519−Naively attempting to write a recursive `rule`, i.e. like
520−
521−```
522−> |-(;~(plug prn ;~(pose $ (easy ~))))
523−```
524−
525−results in an error:
526−
527−```
528−-find.,.+6
529−-find.,.+6
530−rest-loop
531−```
532−
533−Here, [`+prn`](/docs/hoon/reference/stdlib/4i/#prn) is a `rule` used
534−to parse any printable character, and
535−[`+easy`](/docs/hoon/reference/stdlib/4f/#easy) is a `rule` that always returns a
536−constant (`~` in this case) regardless of the input.
537−
538−Thus some special sauce is required, the
539−[`+knee`](/docs/hoon/reference/stdlib/4f/#knee) function.
540−
541−`+knee` takes in a noun that is the default value of the parser, typically given
542−as the bunt value of the type that the `rule` produces, as well as a gate that
543−accepts a `rule`. `+knee` produces a `rule` that implements any recursive calls
544−in the `rule` in a manner acceptable to the compiler. Thus the preferred manner
545−to write the above `rule` is as follows:
546−
547−```hoon
548−|-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~))))
549−```
550−
551−You may want to utilize the `~+` rune when writing recursive parsers to cache
552−the parser to improve performance. In the following section, we will be writing a recursive
553−parser making use of `+knee` and `~+` throughout.
554−
555−# Parsing arithmetic expressions
556−
557−In this section we will be applying what we have learned to write a parser for
558−arithmetic expressions in Hoon. That is, we will make a `rule` that takes in
559−`tape`s of the form `"(2+3)*4"` and returns `20` as a `@ud`.
560−
561−We call a `tape` consisting of some consistent arithmetic string of numbers,
562−`+`, `*`, `(`, and `)` an _expression_. We wish to build a `rule` that takes in an
563−expression and returns the result of the arithmetic computation described by the
564−expression as a `@ud`.
565−
566−To build a parser it is a helpful exercise to first describe its
567−[grammar](https://en.wikipedia.org/wiki/Parsing_expression_grammar). This has a
568−formal mathematical definition, but we will manage to get by here describing the grammar
569−for arithmetic expressions informally.
570−
571−First let's look at the code we're going to use, and then dive into explaining
572−it. If you'd like to follow along, save the following as `expr-parse.hoon` in
573−your `gen/` folder.
574−
575−```hoon
576−:: expr-parse: parse arithmetic expressions
577−::
578−|= math=tape
579−|^ (scan math expr)
580−++ factor
581− %+ knee *@ud
582− |. ~+
583− ;~ pose
584− dem
585− (ifix [pal par] expr)
586− ==
587−++ term
588− %+ knee *@ud
589− |. ~+
590− ;~ pose
591− ((slug mul) tar ;~(pose factor term))
592− factor
593− ==
594−++ expr
595− %+ knee *@ud
596− |. ~+
597− ;~ pose
598− ((slug add) lus ;~(pose term expr))
599− term
600− ==
601−--
602−```
603−
604−Informally, the grammar here is:
605−
606−- A factor is either an integer or an expression surrounded by parentheses.
607−- A term is either a factor or a factor times a term.
608−- An expression is either a term or a term plus an expression.
609−
610−### Factors, terms, and expressions
611−
612−Our grammar consists of three `rule`s: one for factors, one for terms, and one
613−for expressions.
614−
615−#### Factors
616−
617−```hoon
618−++ factor
619− %+ knee *@ud
620− |. ~+
621− ;~ pose
622− dem
623− (ifix [pal par] expr)
624− ==
625−```
626−
627−A _factor_ is either a decimal number or an expression surrounded by parentheses. Put
628−into Hoon terms, a decimal number is parsed by the `rule` `+dem` and an
629−expression is parsed by removing the surrounding parentheses and then passing
630−the result to the expression parser arm `+expr`, given by the `rule` `(ifix [pal par] expr)`. Since we want to parse our expression with one or the other, we
631−chain these two `rule`s together using the monadic applicator rune `;~` along
632−with `+pose`, which says to try each rule in succession until one of them works.
633−
634−Since expressions ultimately reduce to factors, we are actually building a
635−recursive rule. Thus we need to make use of `+knee`. The first argument for
636−`+knee` is `*@ud`, since our final answer should be a `@ud`.
637−
638−Then follows the definition of the gate utilized by `+knee`:
639−
640−```hoon
641− |. ~+
642− ;~ pose
643− dem
644− (ifix [pal par] expr)
645− ==
646−```
647−
648−`~+` is used to cache the parser, so that it does not need to be computed over
649−and over again. Then it follows the `rule` we described above.
650−
651−#### Parsing expressions
652−
653−An _expression_ is either a term plus an expression or a term.
654−
655−In the case of a term plus an expression, we actually must compute what that equals. Thus we will
656−make use of [`+slug`](/docs/hoon/reference/stdlib/4f#slug), which parses a
657−delimited list into `tape`s separated by a given delimiter and then composes
658−them by folding with a binary gate. In this case, our delimiter is `+` and our
659−binary gate is `+add`. That is to say, we will split the input string into terms
660−and expressions separated by luses, parse each term and expression until they
661−reduce to a `@ud`, and then add them together. This is accomplished with the
662−`rule` `((slug add) lus ;~(pose term expr))`.
663−
664−If the above `rule` does not parse the expression, it must be a `term`, so the
665−`tape` is automatically passed to `+term` to be evaluated. Again we use `;~` and `pose` to
666−accomplish this:
667−
668−```hoon
669−;~ pose
670− ((slug add) lus ;~(pose term expr))
671− term
672−==
673−```
674−
675−The rest of the `+expr` arm is structured just like how `+factor` is, and for
676−the same reasons.
677−
678−#### Parsing terms
679−
680−A _term_ is either a factor times a term or a factor. This is handled similarly
681−for expressions, we just need to swap `lus` for `tar`, `add` for `mul`, and
682−`;~(pose factor term)` instead of `;~(pose term expr)`.
683−
684−```hoon
685−++ expr
686− %+ knee *@ud
687− |. ~+
688− ;~ pose
689− ((slug add) lus ;~(pose term expr))
690− term
691− ==
692−```
693−
694−### Try it out
695−
696−Let's feed some expressions to `+expr-parse` and see how it does.
697−
698−```
699−> +expr-parse "3"
700−3
701−> +expr-parse "3+3"
702−6
703−> +expr-parse "3+3+(2*3)+(4+2)*(4+1)"
704−42
705−> +expr-parse "3+3+2*3"
706−12
707−```
708−
709−As an exercise, add exponentiation (e.g. `2^3 = 8`) to `+expr-parse`.
content/docs/hoon/guides/sail.mddeleted−566
@@ -1,566 +0,0 @@
1−+++
2−title = "Sail (HTML)"
3−weight = 6
4−template = "doc.html"
5−+++
6−
7−Sail is a domain-specific language for composing HTML (and XML) structures in
8−Hoon. Like everything else in Hoon, a Sail document is a noun, just one produced
9−by a specialized markup language within Hoon.
10−
11−Front-ends for Urbit apps are often created and uploaded separately to the
12−rest of the code in the desk. Sail provides an alternative approach, where
13−front-ends can be composed directly inside agents.
14−
15−This document will walk through the basics of Sail and its syntax.
16−
17−## Basic example
18−
19−It’s easy to see how Sail can directly translate to HTML:
20−
21−{% table %}
22−
23−- Sail
24−- HTML
25−
26−---
27−
28−- ```
29− ;html
30− ;head
31− ;title: My page
32− ;meta(charset "utf-8");
33− ==
34− ;body
35− ;h1: Welcome!
36− ;p
37− ; Hello, world!
38− ; Welcome to my page.
39− ; Here is an image:
40− ;br;
41− ;img@"/foo.png";
42− ==
43− ==
44− ==
45− ```
46−- ```
47− <html>
48− <head>
49− <title>My page</title>
50− <meta charset="utf-8" />
51− </head>
52− <body>
53− <h1>Welcome!</h1>
54− <p>Hello, world! Welcome to my
55− page. Here is an image:
56− <br />
57− <img src="/foo.png" />
58− </p>
59− </body>
60− </html>
61− ```
62−{% /table %}
63−
64−## Tags and Closing
65−
66−In Sail, tag heads are written with the tag name prepended by `;`. Unlike in
67−HTML, there are different ways of closing tags, depending on the needs of the
68−tag. One of the nice things about Hoon is that you don’t have to constantly
69−close expressions; Sail inherits this convenience.
70−
71−### Empty
72−
73−Empty tags are closed with a `;` following the tag. For example, `;div;` will be
74−rendered as `<div></div>`. Non-container tags `;br;` and `;img@"some-url";` in
75−particular will be rendered as a single tag like `<br />` and `<img src="some-url" />`.
76−
77−### Filled
78−
79−Filled tags are closed via line-break. To fill text inside, add `:` after the
80−tag name, then insert your plain text following a space. Example:
81−
82−| Sail | HTML |
83−| ---------------- | -------------------- |
84−| `;h1: The title` | `<h1>The title</h1>` |
85−
86−### Nested
87−
88−To nest tags, simply create a new line. Nested tags need to be closed with `==`,
89−because they expect a list of sub-tags.
90−
91−If we nest lines of plain text with no tag, the text will be wrapped in a
92−`<p>` tag. Additionally, any text with atom auras or `++arm:syntax` in such
93−plain text lines will be wrapped in `<code>` tags.
94−
95−Example:
96−
97−{% table %}
98−
99−- Sail
100−- HTML
101−
102−---
103−
104−- ```
105− ;body
106− ;h1: Blog title
107− This is some good content.
108− ==
109− ```
110−- ```
111− <body>
112− <h1>Blog title</h1>
113− <p>This is some good content.</p>
114− </body>
115− ```
116−{% /table %}
117−
118−If we want to write a string with no tag at all, then we can prepend
119−those untagged lines with `;` and then a space:
120−
121−{% table %}
122−
123−- Sail
124−- HTML
125−
126−---
127−
128−- ```
129− ;body
130− ;h1: Welcome!
131− ; Hello, world!
132− ; We’re on the web.
133− ==
134− ```
135−- ```
136− <body>
137− <h1>Welcome!</h1>
138− Hello, world!
139− We’re on the web.
140− </body>
141− ```
142−{% /table %}
143−
144−## Attributes
145−
146−Adding attributes is simple: just add the desired attribute between parentheses,
147−right after the tag name without a space. We separate different attributes of
148−the same node by using `,`.
149−
150−Attributes can also be specified in tall form, with each key prefixed by `=`,
151−followed by two spaces, and then a tape with its value. These two styles are
152−shown below.
153−
154−### Generic
155−
156−{% table %}
157−
158−- Form
159−- Example
160−
161−---
162−
163−- Wide
164−- ```
165− ;div(title "a tooltip", style "color:red")
166− ;h1: Foo
167− foo bar baz
168− ==
169− ```
170−
171−---
172−
173−- Tall
174−- ```
175− ;div
176− =title "a tooltip"
177− =style "color:red"
178− ;h1: Foo
179− foo bar baz
180− ==
181− ```
182−
183−---
184−
185−- HTML
186−- ```
187− <div title="a tooltip" style="color:red">
188− <h1>Foo</h1>
189− <p>foo bar baz </p>
190− </div>
191− ```
192−{% /table %}
193−
194−### IDs
195−
196−Add `#` after tag name to add an ID:
197−
198−| Sail | HTML |
199−| ------------------- | ----------------------------- |
200−| `;nav#header: Menu` | `<nav id="header">Menu</nav>` |
201−
202−### Classes
203−
204−Add `.` after tag name to add a class:
205−
206−| Sail | HTML |
207−| ---------------------- | ---------------------------------- |
208−| `;h1.text-blue: Title` | `<h1 class="text-blue">Title</h1>` |
209−
210−For class values containing spaces, you can add additional `.`s like so:
211−
212−| Sail | HTML |
213−| ------------------- | --------------------------------- |
214−| `;div.foo.bar.baz;` | `<div class="foo bar baz"></div>` |
215−
216−Otherwise, if your class value does not conform to the allowed `@tas`
217−characters, you must use the generic attribute syntax:
218−
219−| Sail | HTML |
220−| ------------------------ | ----------------------------- |
221−| `;div(class "!!! !!!");` | `<div class="!!! !!!"></div>` |
222−
223−### Images
224−
225−Add `@` after the tag name to link your source:
226−
227−| Sail | HTML |
228−| --------------------- | -------------------------- |
229−| `;img@"example.png";` | `<img src="example.png"/>` |
230−
231−To add attributes to the image, like size specifications, add the desired
232−attribute after the `"` of the image name and before the final `;` of the `img`
233−tag like `;img@"example.png"(width "100%");`.
234−
235−### Links
236−
237−Add `/` after tag name to start an `href`.
238−
239−{% table %}
240−
241−- Sail
242−- HTML
243−
244−---
245−
246−- ```
247− ;a/"urbit.org": A link to Urbit.org
248− ```
249−- ```
250− <a href="urbit.org">A link to Urbit.org</a>
251− ```
252−{% /table %}
253−
254−## Interpolation
255−
256−The textual content of tags, despite not being enclosed in double-quotes, are
257−actually tapes. This means they support interpolated Hoon expressions in the
258−usual manner. For example:
259−
260−{% table %}
261−
262−- Sail
263−- HTML
264−
265−---
266−
267−- ```
268− =| =time
269− ;p: foo {<time>} bar
270− ```
271−- ```
272− <p>foo ~2000.1.1 baz</p>
273− ```
274−{% /table %}
275−
276−Likewise:
277−
278−{% table .w-full %}
279−
280−- Sail
281−
282−---
283−
284−- ```
285− =/ txt=tape " bananas"
286− ;article
287− ;b: {(a-co:co (mul 42 789))}
288− ; {txt}
289− {<our>} {<now>} {<`@ux`(end 6 eny)>}
290− ==
291− ```
292−{% /table %}
293−
294−{% table .w-full %}
295−
296−- HTML
297−
298−---
299−
300−- ```
301− <article>
302− <b>33138</b> bananas
303− <p>~zod ~2022.2.21..09.54.21..5b63 0x9827.99c7.06f4.8ef9</p>
304− </article>
305− ```
306−{% /table %}
307−
308−## A note on CSS
309−
310−The CSS for a page is usually quite large. The typical approach is to include a
311−separate arm in your agent (`++style` or the like) and write out the CSS in a
312−fenced cord block. You can then call `++trip` on it and include it in a style
313−tag. For example:
314−
315−```hoon
316−++ style
317− ^~
318− %- trip
319− '''
320− main {
321− width: 100%;
322− color: red;
323− }
324− header {
325− color: blue;
326− font-family: monospace;
327− }
328− '''
329−```
330−
331−And then your style tag might look like:
332−
333−```hoon
334−;style: {style}
335−```
336−
337−A cord is used rather than a tape so you don't need to escape braces. The
338−[ketsig](/docs/hoon/reference/rune/ket#-ketsig) (`^~`) rune means `++trip` will
339−be run at compile time rather than call time.
340−
341−## Types and marks
342−
343−So far we've shown rendered HTML for demonstrative purposes, but Sail syntax
344−doesn't directly produce HTML text. Instead, it produces a
345−[$manx](/docs/hoon/reference/stdlib/5e#manx). This is a Hoon type used to
346−represent an XML hierarchical structure with a single root node. There are six
347−XML-related types defined in the standard library:
348−
349−```hoon
350−+$ mane $@(@tas [@tas @tas]) :: XML name+space
351−+$ manx $~([[%$ ~] ~] [g=marx c=marl]) :: dynamic XML node
352−+$ marl (list manx) :: XML node list
353−+$ mars [t=[n=%$ a=[i=[n=%$ v=tape] t=~]] c=~] :: XML cdata
354−+$ mart (list [n=mane v=tape]) :: XML attributes
355−+$ marx $~([%$ ~] [n=mane a=mart]) :: dynamic XML tag
356−```
357−
358−More information about these can be found in [section 5e of the standard library
359−reference](/docs/hoon/reference/stdlib/5e).
360−
361−You don't need to understand these types in order to write Sail. The main thing
362−to note is that a `$manx` is a node (a single tag) and its contents is a
363−[$marl](/docs/hoon/reference/stdlib/5e#marl), which is just a `(list manx)`.
364−
365−### Rendering
366−
367−A `$manx` can be rendered as HTML in a tape with the `++en-xml:html` function in
368−`zuse.hoon`. For example:
369−
370−```
371−> ;p: foobar
372−[[%p ~] [[%$ [%$ "foobar"] ~] ~] ~]
373−
374−> =x ;p: foobar
375−
376−> (en-xml:html x)
377−"<p>foobar</p>"
378−
379−> (crip (en-xml:html x))
380−'<p>foobar</p>'
381−```
382−
383−### Sanitization
384−
385−The `++en-xml:html` function will sanitize the contents of both attributes and
386−elements, converting characters such as `>` to HTML entities. For example:
387−
388−```
389−> =z ;p(class "\"><script src=\"example.com/xxx.js"): <h1>FOO</h1>
390−
391−> (crip (en-xml:html z))
392−'<p class="&quot;&gt;<script src=&quot;example.com/xxx.js"><h1&gt;FOO</h1&gt;</p>'
393−```
394−
395−### Marks
396−
397−There are a few different HTML and XML related marks, so it can be a bit
398−confusing. We'll look at the ones you're most likely to use.
399−
400−#### `%html`
401−
402−- Type: `@t`
403−
404−This mark is used for HTML that has been printed as text in a cord. You may wish
405−to return this mark when serving pages to the web. To do so, you must run the
406−`$manx` produced by your Sail expressions through `++en-xml:html`, and then run
407−the resulting `tape` through `++crip`.
408−
409−#### `%hymn`
410−
411−- Type: `$manx`
412−
413−The `%hymn` mark is intended to be used for complete HTML documents - having an
414−`<html>` root element, `<head>`, `<body>`, etc. This isn't enforced on
415−the type level but it is assumed in certain mark conversion pathways. Eyre can
416−automatically convert a `%hymn` to printed `%html` if it was requested through
417−Eyre's scry interface.
418−
419−#### `%elem`
420−
421−- Type: `$manx`
422−
423−The type of the `%elem` mark is a `$manx`, just like a `%hymn`. While `%hymn`s
424−are intended for complete HTML documents, `%elem`s are intended for more general
425−XML structures. You may wish to use an `%elem` mark if you're producing smaller
426−fragments of XML or HTML rather than whole documents. Like a `%hymn`, Eyre can
427−automatically convert it to `%html` if requested through its scry interface.
428−
429−#### Summary
430−
431−In general, if you're going to be composing web pages and serving them to web
432−clients, running the result of your Sail through `++en-xml:html`, `++crip`ping
433−it and producing `%html` is the most straight-forward approach. If you might
434−want to pass around a `$manx` to other agents or ships which may wish to
435−manipulate it futher, a `%hymn` or `%elem` is better.
436−
437−## Sail Runes
438−
439−In addition to the syntax so far described, there are also a few Sail-specific
440−runes:
441−
442−### `;+` Miclus
443−
444−The [miclus rune](/docs/hoon/reference/rune/mic#-miclus) makes a `$marl` from a
445−complex hoon expression that produces a single `$manx`. Its main use is nesting
446−tall-form hoon logic in another Sail element. For example:
447−
448−```hoon
449−;p
450− ;b: {(a-co:co number)}
451− ; is an
452− ;+ ?: =(0 (mod number 2))
453− ;b: even
454− ;b: odd
455− ; number.
456−==
457−```
458−
459−Produces one of these depending on the value of `number`:
460−
461−```
462−<p><b>2 </b>is an <b>even </b>number.</p>
463−```
464−
465−```
466−<p><b>12345 </b>is an <b>odd </b>number.</p>
467−```
468−
469−### `;*` Mictar
470−
471−The [mictar rune](/docs/hoon/reference/rune/mic#-mictar) makes a `$marl` (a list
472−of XML nodes) from a complex hoon expression. This rune lets you add many
473−elements inside another Sail element. For example:
474−
475−{% table %}
476−
477−- Sail
478−- HTML
479−
480−---
481−
482−- ```
483− =/ nums=(list @ud) (gulf 1 9)
484− ;p
485− ;* %+ turn nums
486− |= n=@ud
487− ?: =(0 (mod n 2))
488− ;sup: {(a-co:co n)}
489− ;sub: {(a-co:co n)}
490− ==
491− ```
492−- ```
493− <p>
494− <sub>1</sub><sup>2</sup>
495− <sub>3</sub><sup>4</sup>
496− <sub>5</sub><sup>6</sup>
497− <sub>7</sub><sup>8</sup>
498− <sub>9</sub>
499− </p>
500− ```
501−{% /table %}
502−
503−### `;=` Mictis
504−
505−The [mictis rune](/docs/hoon/reference/rune/mic#-mictis) makes a `$marl` (a list
506−of XML nodes) from a series of `$manx`es. This is mostly useful if you want to
507−make the list outside of an element and then be able to insert it afterwards.
508−For example:
509−
510−{% table %}
511−
512−- Sail
513−- HTML
514−
515−---
516−
517−- ```
518− =/ paras=marl
519− ;= ;p: First node.
520− ;p: Second node.
521− ;p: Third node.
522− ==
523− ;main
524− ;* paras
525− ==
526− ```
527−- ```
528− <main>
529− <p>First node.</p>
530− <p>Second node.</p>
531− <p>Third node.</p>
532− </main>
533− ```
534−{% /table %}
535−
536−### `;/` Micfas
537−
538−The [micfas rune](/docs/hoon/reference/rune/mic#-micfas) turns an ordinary tape
539−into a `$manx`. For example:
540−
541−```
542−> %- en-xml:html ;/ "foobar"
543−"foobar"
544−```
545−
546−In order to nest it inside another Sail element, it must be preceeded with a
547−`;+` rune or similar, it cannot be used directly. For example:
548−
549−```hoon
550−;p
551− ;+ ;/ ?: =(0 (mod eny 2))
552− "even"
553− "odd"
554−==
555−```
556−
557−## Good examples
558−
559−Here's a couple of agents that make use of Sail, which you can use as a
560−reference:
561−
562−- [Pals by ~palfun-foslup][pals]
563−- [Gora by ~rabsef-bicrym][gora]
564−
565−[pals]: https://github.com/Fang-/suite/blob/master/app/pals/webui/index.hoon
566−[gora]: https://github.com/dalten-collective/gora/blob/master/sail/app/gora/goraui/index.hoon
content/docs/hoon/guides/strings.mddeleted−531

This diff is too big to show here.

content/docs/hoon/guides/unit-tests.mddeleted−115

This diff is too big to show here.

content/docs/hoon/hoon-school/_index.mddeleted−37

This diff is too big to show here.

content/docs/hoon/hoon-school/ackermann.mddeleted−29

This diff is too big to show here.

content/docs/hoon/hoon-school/arms-and-cores.mddeleted−652

This diff is too big to show here.

content/docs/hoon/hoon-school/atoms-auras-and-simple-cell-types.mddeleted−779

This diff is too big to show here.

content/docs/hoon/hoon-school/bank-account.mddeleted−80

This diff is too big to show here.

content/docs/hoon/hoon-school/behn.mddeleted−110

This diff is too big to show here.

content/docs/hoon/hoon-school/caesar.mddeleted−394

This diff is too big to show here.

content/docs/hoon/hoon-school/conditionals.mddeleted−105

This diff is too big to show here.

content/docs/hoon/hoon-school/doors.mddeleted−518

This diff is too big to show here.

content/docs/hoon/hoon-school/egg-timer.mddeleted−164

This diff is too big to show here.

content/docs/hoon/hoon-school/fibonacci.mddeleted−61

This diff is too big to show here.

content/docs/hoon/hoon-school/gall.mddeleted−129

This diff is too big to show here.

content/docs/hoon/hoon-school/gates.mddeleted−272

This diff is too big to show here.

content/docs/hoon/hoon-school/generators.mddeleted−460

This diff is too big to show here.

content/docs/hoon/hoon-school/hoon-syntax.mddeleted−356

This diff is too big to show here.

content/docs/hoon/hoon-school/intro.mddeleted−121

This diff is too big to show here.

content/docs/hoon/hoon-school/iron-polymorphism.mddeleted−88

This diff is too big to show here.

content/docs/hoon/hoon-school/lead-polymorphism.mddeleted−155

This diff is too big to show here.

content/docs/hoon/hoon-school/libraries.mddeleted−191

This diff is too big to show here.

content/docs/hoon/hoon-school/list-of-numbers.mddeleted−138

This diff is too big to show here.

content/docs/hoon/hoon-school/lists.mddeleted−497

This diff is too big to show here.

content/docs/hoon/hoon-school/molds.mddeleted−98

This diff is too big to show here.

content/docs/hoon/hoon-school/nouns.mddeleted−563

This diff is too big to show here.

content/docs/hoon/hoon-school/recursion.mddeleted−194

This diff is too big to show here.

content/docs/hoon/hoon-school/structures-and-complex-types.mddeleted−356

This diff is too big to show here.

content/docs/hoon/hoon-school/the-subject-and-its-legs.mddeleted−726

This diff is too big to show here.

content/docs/hoon/hoon-school/trees-sets-and-maps.mddeleted−321

This diff is too big to show here.

content/docs/hoon/hoon-school/type-checking-and-type-inference.mddeleted−643

This diff is too big to show here.

content/docs/hoon/hoon-school/type-polymorphism.mddeleted−584

This diff is too big to show here.

content/docs/hoon/overview.mddeleted−274

This diff is too big to show here.

content/docs/hoon/reference/_index.mddeleted−53

This diff is too big to show here.

content/docs/hoon/reference/advanced.mddeleted−206

This diff is too big to show here.

content/docs/hoon/reference/auras.mddeleted−107

This diff is too big to show here.

content/docs/hoon/reference/basic.mddeleted−177

This diff is too big to show here.

content/docs/hoon/reference/cheat-sheet.mddeleted−18

This diff is too big to show here.

content/docs/hoon/reference/hoon-errors.mddeleted−187

This diff is too big to show here.

content/docs/hoon/reference/irregular.mddeleted−332

This diff is too big to show here.

content/docs/hoon/reference/limbs/_index.mddeleted−18

This diff is too big to show here.

content/docs/hoon/reference/limbs/limb.mddeleted−71

This diff is too big to show here.

content/docs/hoon/reference/limbs/wing.mddeleted−44

This diff is too big to show here.

content/docs/hoon/reference/rune/_index.mddeleted−78

This diff is too big to show here.

content/docs/hoon/reference/rune/bar.mddeleted−1030

This diff is too big to show here.

content/docs/hoon/reference/rune/buc.mddeleted−1046

This diff is too big to show here.

content/docs/hoon/reference/rune/cen.mddeleted−744

This diff is too big to show here.

content/docs/hoon/reference/rune/col.mddeleted−461

This diff is too big to show here.

content/docs/hoon/reference/rune/constants.mddeleted−212

This diff is too big to show here.

content/docs/hoon/reference/rune/dot.mddeleted−394

This diff is too big to show here.

content/docs/hoon/reference/rune/fas.mddeleted−257

This diff is too big to show here.

content/docs/hoon/reference/rune/ket.mddeleted−720

This diff is too big to show here.

content/docs/hoon/reference/rune/lus.mddeleted−332

This diff is too big to show here.

content/docs/hoon/reference/rune/mic.mddeleted−730

This diff is too big to show here.

content/docs/hoon/reference/rune/sig.mddeleted−887

This diff is too big to show here.

content/docs/hoon/reference/rune/terminators.mddeleted−89

This diff is too big to show here.

content/docs/hoon/reference/rune/tis.mddeleted−1055

This diff is too big to show here.

content/docs/hoon/reference/rune/wut.mddeleted−1058

This diff is too big to show here.

content/docs/hoon/reference/rune/zap.mddeleted−642

This diff is too big to show here.

content/docs/hoon/reference/stdlib/1a.mddeleted−799

This diff is too big to show here.

content/docs/hoon/reference/stdlib/1b.mddeleted−309

This diff is too big to show here.

content/docs/hoon/reference/stdlib/1c.mddeleted−538

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2a.mddeleted−616

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2b.mddeleted−1649

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2c.mddeleted−1518

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2d.mddeleted−374

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2e.mddeleted−188

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2f.mddeleted−315

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2g.mddeleted−105

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2h.mddeleted−826

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2i.mddeleted−1418

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2j.mddeleted−397

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2k.mddeleted−456

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2l.mddeleted−110

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2m.mddeleted−316

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2n.mddeleted−458

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2o.mddeleted−200

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2p.mddeleted−248

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2q.mddeleted−586

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3a.mddeleted−882

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3b.mddeleted−6054

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3c.mddeleted−664

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3d.mddeleted−820

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3e.mddeleted−8

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3f.mddeleted−868

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3g.mddeleted−355

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4a.mddeleted−424

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4b.mddeleted−1320

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4c.mddeleted−396

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4d.mddeleted−100

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4e.mddeleted−466

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4f.mddeleted−1380

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4g.mddeleted−229

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4h.mddeleted−703

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4i.mddeleted−1086

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4j.mddeleted−1796

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4k.mddeleted−841

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4l.mddeleted−618

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4m.mddeleted−486

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4n.mddeleted−723

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4o.mddeleted−1473

This diff is too big to show here.

content/docs/hoon/reference/stdlib/5a.mddeleted−504

This diff is too big to show here.

content/docs/hoon/reference/stdlib/5b.mddeleted−87

This diff is too big to show here.

content/docs/hoon/reference/stdlib/5c.mddeleted−925

This diff is too big to show here.

content/docs/hoon/reference/stdlib/5d.mddeleted−323

This diff is too big to show here.

content/docs/hoon/reference/stdlib/5e.mddeleted−332

This diff is too big to show here.

content/docs/hoon/reference/stdlib/5f.mddeleted−194

This diff is too big to show here.

content/docs/hoon/reference/stdlib/_index.mddeleted−2065

This diff is too big to show here.

content/docs/hoon/reference/stdlib/table-of-contents.mddeleted−2064

This diff is too big to show here.

content/docs/hoon/reference/style.mddeleted−476

This diff is too big to show here.

content/docs/hoon/reference/zuse/2d_1-5.mddeleted−587

This diff is too big to show here.

content/docs/hoon/reference/zuse/2d_6.mddeleted−1551

This diff is too big to show here.

content/docs/hoon/reference/zuse/2d_7.mddeleted−1307

This diff is too big to show here.

content/docs/hoon/reference/zuse/2e_2-3.mddeleted−67

This diff is too big to show here.

content/docs/hoon/reference/zuse/_index.mddeleted−31

This diff is too big to show here.

content/docs/hoon/reference/zuse/table-of-contents.mddeleted−247

This diff is too big to show here.

content/docs/nock/_index.mddeleted−27

This diff is too big to show here.

content/docs/nock/definition.mddeleted−186

This diff is too big to show here.

content/docs/nock/example.mddeleted−362

This diff is too big to show here.

content/docs/nock/explanation.mddeleted−605

This diff is too big to show here.

content/docs/nock/implementations.mddeleted−2879

This diff is too big to show here.

content/docs/system-overview/_index.mddeleted−77

This diff is too big to show here.

content/docs/system-overview/arvo.mddeleted−32

This diff is too big to show here.

content/docs/system-overview/azimuth.mddeleted−34

This diff is too big to show here.

content/docs/system-overview/cryptography.mddeleted−124

This diff is too big to show here.

content/docs/system-overview/hoon.mddeleted−28

This diff is too big to show here.

content/docs/system-overview/nock.mddeleted−34

This diff is too big to show here.

content/docs/system-overview/vere.mddeleted−45

This diff is too big to show here.

content/docs/userspace/_index.mddeleted−33

This diff is too big to show here.

content/docs/userspace/dist/_index.mddeleted−29

This diff is too big to show here.

content/docs/userspace/dist/dist.mddeleted−105

This diff is too big to show here.

content/docs/userspace/dist/docket.mddeleted−296

This diff is too big to show here.

content/docs/userspace/dist/glob.mddeleted−102

This diff is too big to show here.

content/docs/userspace/dist/guide.mddeleted−282

This diff is too big to show here.

content/docs/userspace/dist/tools.mddeleted−342

This diff is too big to show here.

content/docs/userspace/full-stack/1-intro.mddeleted−89

This diff is too big to show here.

content/docs/userspace/full-stack/10-final.mddeleted−118

This diff is too big to show here.

content/docs/userspace/full-stack/2-types.mddeleted−215

This diff is too big to show here.

content/docs/userspace/full-stack/3-agent.mddeleted−338

This diff is too big to show here.

content/docs/userspace/full-stack/4-json.mddeleted−357

This diff is too big to show here.

content/docs/userspace/full-stack/5-marks.mddeleted−97

This diff is too big to show here.

content/docs/userspace/full-stack/6-eyre.mddeleted−79

This diff is too big to show here.

content/docs/userspace/full-stack/7-react-setup.mddeleted−214

This diff is too big to show here.

content/docs/userspace/full-stack/8-app-logic.mddeleted−406

This diff is too big to show here.

content/docs/userspace/full-stack/9-desk.mddeleted−226

This diff is too big to show here.

content/docs/userspace/full-stack/_index.mddeleted−52

This diff is too big to show here.

content/docs/userspace/gall-guide/1-arvo.mddeleted−305

This diff is too big to show here.

content/docs/userspace/gall-guide/10-scry.mddeleted−363

This diff is too big to show here.

content/docs/userspace/gall-guide/11-fail.mddeleted−146

This diff is too big to show here.

content/docs/userspace/gall-guide/12-next-steps.mddeleted−50

This diff is too big to show here.

content/docs/userspace/gall-guide/2-agent.mddeleted−305

This diff is too big to show here.

content/docs/userspace/gall-guide/3-imports-and-aliases.mddeleted−285

This diff is too big to show here.

content/docs/userspace/gall-guide/4-lifecycle.mddeleted−499

This diff is too big to show here.

content/docs/userspace/gall-guide/5-cards.mddeleted−244

This diff is too big to show here.

content/docs/userspace/gall-guide/6-pokes.mddeleted−538

This diff is too big to show here.

content/docs/userspace/gall-guide/7-sur-and-marks.mddeleted−408

This diff is too big to show here.

content/docs/userspace/gall-guide/8-subscriptions.mddeleted−911

This diff is too big to show here.

content/docs/userspace/gall-guide/9-vanes.mddeleted−284

This diff is too big to show here.

content/docs/userspace/gall-guide/_index.mddeleted−45

This diff is too big to show here.

content/docs/userspace/gall-guide/intro.mddeleted−83

This diff is too big to show here.

content/docs/userspace/gall-guide/types.mddeleted−228

This diff is too big to show here.

content/docs/userspace/graph-store/_index.mddeleted−23

This diff is too big to show here.

content/docs/userspace/graph-store/advanced-info.mddeleted−64

This diff is too big to show here.

content/docs/userspace/graph-store/data-structure-overview.mddeleted−350

This diff is too big to show here.

content/docs/userspace/graph-store/graph-store-reference.mddeleted−244

This diff is too big to show here.

content/docs/userspace/graph-store/overview.mddeleted−103

This diff is too big to show here.

content/docs/userspace/graph-store/sample-application-overview.mddeleted−369

This diff is too big to show here.

content/docs/userspace/graph-store/validator-walkthrough.mddeleted−476

This diff is too big to show here.

content/docs/userspace/http-api-guide.mddeleted−698

This diff is too big to show here.

content/docs/userspace/overview.mddeleted−24

This diff is too big to show here.

content/docs/userspace/threads/_index.mddeleted−27

This diff is too big to show here.

content/docs/userspace/threads/basics/_index.mddeleted−29

This diff is too big to show here.

content/docs/userspace/threads/basics/bind.mddeleted−97

This diff is too big to show here.

content/docs/userspace/threads/basics/fundamentals.mddeleted−168

This diff is too big to show here.

content/docs/userspace/threads/basics/input.mddeleted−145

This diff is too big to show here.

content/docs/userspace/threads/basics/output.mddeleted−119

This diff is too big to show here.

content/docs/userspace/threads/basics/summary.mddeleted−81

This diff is too big to show here.

content/docs/userspace/threads/examples/_index.mddeleted−33

This diff is too big to show here.

content/docs/userspace/threads/examples/child-thread.mddeleted−241

This diff is too big to show here.

content/docs/userspace/threads/examples/get-json.mddeleted−114

This diff is too big to show here.

content/docs/userspace/threads/examples/main-loop.mddeleted−178

This diff is too big to show here.

content/docs/userspace/threads/examples/poke-agent.mddeleted−60

This diff is too big to show here.

content/docs/userspace/threads/examples/scry.mddeleted−70

This diff is too big to show here.

content/docs/userspace/threads/examples/take-fact.mddeleted−65

This diff is too big to show here.

content/docs/userspace/threads/gall/_index.mddeleted−29

This diff is too big to show here.

content/docs/userspace/threads/gall/poke-thread.mddeleted−115

This diff is too big to show here.

content/docs/userspace/threads/gall/start-thread.mddeleted−145

This diff is too big to show here.

content/docs/userspace/threads/gall/stop-thread.mddeleted−152

This diff is too big to show here.

content/docs/userspace/threads/gall/take-facts.mddeleted−184

This diff is too big to show here.

content/docs/userspace/threads/gall/take-result.mddeleted−132

This diff is too big to show here.

content/docs/userspace/threads/http-api.mddeleted−73

This diff is too big to show here.

content/docs/userspace/threads/overview.mddeleted−82

This diff is too big to show here.

content/docs/userspace/threads/reference.mddeleted−87

This diff is too big to show here.

content/docs/vere/_index.mddeleted−42

This diff is too big to show here.

content/docs/vere/api.mddeleted−1040

This diff is too big to show here.

content/docs/vere/c.mddeleted−114

This diff is too big to show here.

content/docs/vere/cryptography.mddeleted−43

This diff is too big to show here.

content/docs/vere/jetting.mddeleted−779

This diff is too big to show here.

content/docs/vere/nouns.mddeleted−477

This diff is too big to show here.

content/docs/vere/runtime.mddeleted−44

This diff is too big to show here.