on master help sign in
Merge pull request #723 from urbit/urbit.org2

urbit.org2: re-implementation in next.js

commit94c876d2988f5d45c391a6cb429b78c6468248a5 authormatildepark <matilde@tlon.io> dateTue 27 Jul 2021, 22:54 (5 years ago) parent0e5d7214e37a94
667 files changed+97027−17433
.gitignore+38−11 .gitmodules−3 .husky/.gitignore+1 .husky/pre-commit+4 .nova/Configuration.json+3 README.md+19−80 bin/build−1 bin/start−1 components/BackgroundImage.js+9 components/BasicPage.js+38 components/Contact.js+102 components/Container.js+8 components/ContentArea.js+54 components/EventPreview.js+33 components/Footer.js+173 components/GrantPreview.js+60 components/Header.js+129 components/Lorem.js+106 components/Markdown.js+47 components/MenuTray.js+104 components/Meta.js+31 components/NewletterSignup.js+38 components/PageWithIndex.js+43 components/Pagination.js+24 components/PostPreview.js+30 components/Search.js+191 components/Section.js+21 components/Sidebar.js+32 components/SingleColumn.js+8 components/TabCarousel.js+9 components/TableOfContents.js+114 config.toml−35 content/Bitcoin-wallet.md+8−11 content/_index.md−3 content/blog/_index.md−6 content/blog/a-topiary.md−49 content/blog/community-spotlight-the-portico.md+6−6 content/blog/first-contract.md+10−11 content/blog/gifts-q3-2020.md+13−7 content/blog/iot.md+14−14 content/blog/metaphase.md+9−9 content/blog/on-christopher-alexander.md+11−11 content/blog/rollups.md+17−17 content/blog/urbit-grants-and-mid-2019-gifts.md+4−4 content/community/community-grants.md+1−1 content/community/governance.md+1−1 content/docs−1 content/docs/_index.md+56 content/docs/arvo/_index.md+55 content/docs/arvo/ames/_index.md+7 content/docs/arvo/ames/ames-api.md+292 content/docs/arvo/ames/ames.md+423 content/docs/arvo/ames/cryptography.md+145 content/docs/arvo/behn/_index.md+7 content/docs/arvo/behn/behn-api.md+246 content/docs/arvo/behn/behn.md+21 content/docs/arvo/clay/_index.md+36 content/docs/arvo/clay/architecture.md+254 content/docs/arvo/clay/clay.md+58 content/docs/arvo/clay/data-types.md+688 content/docs/arvo/clay/examples.md+824 content/docs/arvo/clay/scry.md+425 content/docs/arvo/clay/tasks.md+555 content/docs/arvo/clay/using.md+217 content/docs/arvo/concepts/_index.md+13 content/docs/arvo/concepts/subscriptions.md+162 content/docs/arvo/dill/_index.md+7 content/docs/arvo/dill/dill-api.md+366 content/docs/arvo/dill/dill.md+24 content/docs/arvo/eyre/_index.md+31 content/docs/arvo/eyre/data-types.md+290 content/docs/arvo/eyre/examples.md+625 content/docs/arvo/eyre/external-api-ref.md+381 content/docs/arvo/eyre/eyre.md+61 content/docs/arvo/eyre/scry.md+213 content/docs/arvo/eyre/tasks.md+230 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/overview.md+11 content/docs/arvo/iris/_index.md+7 content/docs/arvo/iris/iris-api.md+191 content/docs/arvo/jael/_index.md+7 content/docs/arvo/jael/jael-api.md+393 content/docs/arvo/overview.md+577 content/docs/arvo/reference/_index.md+11 content/docs/arvo/reference/cryptography.md+222 content/docs/arvo/reference/filesystem.md+69 content/docs/arvo/tutorials/_index.md+9 content/docs/arvo/tutorials/move-trace.md+378 content/docs/azimuth/_index.md+22 content/docs/azimuth/advanced-azimuth-tools.md+68 content/docs/azimuth/azimuth.md+149 content/docs/azimuth/life-and-rift.md+58 content/docs/development/_index.md+33 content/docs/development/develop.md+115 content/docs/development/environment.md+64 content/docs/development/grants.md+84 content/docs/development/precepts.md+336 content/docs/development/project-repositories.md+50 content/docs/glossary/_index.md+10 content/docs/glossary/ames.md+19 content/docs/glossary/aqua.md+16 content/docs/glossary/arm.md+14 content/docs/glossary/arvo.md+40 content/docs/glossary/atom.md+20 content/docs/glossary/azimuth.md+18 content/docs/glossary/battery.md+14 content/docs/glossary/behn.md+14 content/docs/glossary/breach.md+28 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+14 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+17 content/docs/glossary/gate.md+14 content/docs/glossary/hdwallet.md+17 content/docs/glossary/hoon.md+15 content/docs/glossary/invite-tree.md+9 content/docs/glossary/iris.md+11 content/docs/glossary/jael.md+8 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+34 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+18 content/docs/glossary/pill.md+14 content/docs/glossary/planet.md+15 content/docs/glossary/proxies.md+29 content/docs/glossary/replay.md+13 content/docs/glossary/sailudon.md+13 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+13 content/docs/hoon/guides/aqua.md+80 content/docs/hoon/guides/cli-tutorial.md+417 content/docs/hoon/guides/parsing.md+650 content/docs/hoon/hoon-school/_index.md+42 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+516 content/docs/hoon/hoon-school/egg-timer.md+159 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+461 content/docs/hoon/hoon-school/hoon-syntax.md+356 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+132 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+195 content/docs/hoon/hoon-school/setup.md+105 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+276 content/docs/hoon/reference/_index.md+50 content/docs/hoon/reference/advanced.md+206 content/docs/hoon/reference/auras.md+98 content/docs/hoon/reference/basic.md+177 content/docs/hoon/reference/cheat-sheet.md+28 content/docs/hoon/reference/hoon-errors.md+189 content/docs/hoon/reference/irregular.md+308 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+73 content/docs/hoon/reference/rune/bar.md+708 content/docs/hoon/reference/rune/buc.md+606 content/docs/hoon/reference/rune/cen.md+466 content/docs/hoon/reference/rune/col.md+245 content/docs/hoon/reference/rune/constants.md+193 content/docs/hoon/reference/rune/dot.md+223 content/docs/hoon/reference/rune/ket.md+387 content/docs/hoon/reference/rune/lus.md+225 content/docs/hoon/reference/rune/mic.md+462 content/docs/hoon/reference/rune/sig.md+452 content/docs/hoon/reference/rune/terminators.md+78 content/docs/hoon/reference/rune/tis.md+490 content/docs/hoon/reference/rune/wut.md+551 content/docs/hoon/reference/rune/zap.md+239 content/docs/hoon/reference/stdlib/1a.md+680 content/docs/hoon/reference/stdlib/1b.md+273 content/docs/hoon/reference/stdlib/1c.md+459 content/docs/hoon/reference/stdlib/2a.md+449 content/docs/hoon/reference/stdlib/2b.md+1412 content/docs/hoon/reference/stdlib/2c.md+1364 content/docs/hoon/reference/stdlib/2d.md+373 content/docs/hoon/reference/stdlib/2e.md+268 content/docs/hoon/reference/stdlib/2f.md+437 content/docs/hoon/reference/stdlib/2g.md+105 content/docs/hoon/reference/stdlib/2h.md+826 content/docs/hoon/reference/stdlib/2i.md+1133 content/docs/hoon/reference/stdlib/2j.md+269 content/docs/hoon/reference/stdlib/2k.md+400 content/docs/hoon/reference/stdlib/2l.md+108 content/docs/hoon/reference/stdlib/2m.md+308 content/docs/hoon/reference/stdlib/2n.md+427 content/docs/hoon/reference/stdlib/2o.md+187 content/docs/hoon/reference/stdlib/2p.md+242 content/docs/hoon/reference/stdlib/2q.md+375 content/docs/hoon/reference/stdlib/3a.md+859 content/docs/hoon/reference/stdlib/3b.md+5889 content/docs/hoon/reference/stdlib/3c.md+649 content/docs/hoon/reference/stdlib/3d.md+821 content/docs/hoon/reference/stdlib/3e.md+8 content/docs/hoon/reference/stdlib/3f.md+722 content/docs/hoon/reference/stdlib/3g.md+384 content/docs/hoon/reference/stdlib/4a.md+217 content/docs/hoon/reference/stdlib/4b.md+994 content/docs/hoon/reference/stdlib/4c.md+364 content/docs/hoon/reference/stdlib/4d.md+100 content/docs/hoon/reference/stdlib/4e.md+471 content/docs/hoon/reference/stdlib/4f.md+1195 content/docs/hoon/reference/stdlib/4g.md+179 content/docs/hoon/reference/stdlib/4h.md+962 content/docs/hoon/reference/stdlib/4i.md+1054 content/docs/hoon/reference/stdlib/4j.md+1656 content/docs/hoon/reference/stdlib/4k.md+276 content/docs/hoon/reference/stdlib/4l.md+608 content/docs/hoon/reference/stdlib/4m.md+434 content/docs/hoon/reference/stdlib/4n.md+447 content/docs/hoon/reference/stdlib/4o.md+782 content/docs/hoon/reference/stdlib/5a.md+7 content/docs/hoon/reference/stdlib/5b.md+7 content/docs/hoon/reference/stdlib/5c.md+7 content/docs/hoon/reference/stdlib/5d.md+7 content/docs/hoon/reference/stdlib/5e.md+7 content/docs/hoon/reference/stdlib/5f.md+176 content/docs/hoon/reference/stdlib/5g.md+7 content/docs/hoon/reference/stdlib/_index.md+1733 content/docs/hoon/reference/stdlib/table-of-contents.md+1731 content/docs/hoon/reference/style.md+476 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+2322 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+30 content/docs/userspace/gall/_index.md+21 content/docs/userspace/gall/gall-api.md+958 content/docs/userspace/gall/gall.md+558 content/docs/userspace/gall/tutorial.md+14 content/docs/userspace/graph-store/_index.md+23 content/docs/userspace/graph-store/advanced-info.md+64 content/docs/userspace/graph-store/data-structure-overview.md+338 content/docs/userspace/graph-store/overview.md+109 content/docs/userspace/graph-store/validator-walkthrough.md+487 content/docs/userspace/landscape/_index.md+18 content/docs/userspace/landscape/overview.md+195 content/docs/userspace/landscape/reference/_index.md+11 content/docs/userspace/landscape/reference/graph-store.md+160 content/docs/userspace/overview.md+19 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+169 content/docs/userspace/threads/basics/input.md+145 content/docs/userspace/threads/basics/output.md+119 content/docs/userspace/threads/basics/summary.md+75 content/docs/userspace/threads/examples/_index.md+33 content/docs/userspace/threads/examples/child-thread.md+237 content/docs/userspace/threads/examples/get-json.md+126 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+116 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+81 content/docs/userspace/threads/reference.md+86 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/events/2017-08-11-after-hours-bootstrapping-urbit-from-the-ethereum-blockchain.md−1 content/events/2017-09-22-after-hours-fun-with-arvo-the-urbit-os.md−1 content/events/2017-10-26-after-hours-designing-robust-human-systems.md−1 content/events/2017-11-16-after-hours-visiting-contributors.md−1 content/events/2018-01-26-urbit-irl-20181.md−1 content/events/2018-02-23-urbit-irl-20182.md−1 content/events/2018-03-11-20183-hoon-school.md−1 content/events/2018-03-23-urbit-irl-20183.md−1 content/events/2018-04-08-20184-hoon-school.md−1 content/events/2018-05-25-urbit-irl-20185.md−1 content/events/2018-08-03-after-hours-decentralized-web-summit.md−1 content/events/2018-08-17-urbit-irl-20188.md−1 content/events/2018-09-21-urbit-irl-20189.md−1 content/events/2018-10-10-urbit-zcash-blockchain-week.md−1 content/events/2018-12-20-after-hours-its-just-a-party-man.md−1 content/events/2019-03-01-after-hours-ask-galen-anything.md−1 content/events/2019-03-08-urbit-irl-austin-tx.md−1 content/events/2019-04-19-urbit-irl-20194.md−1 content/events/2019-05-17-urbit-irl-20195.md−1 content/events/2019-06-21-urbit-irl-20196.md−1 content/events/2019-07-19-urbit-irl-20197.md+3−2 content/events/2019-08-29-urbit-austin-20198.md+3−2 content/events/2019-10-04-urbit-irl-201910.md+3−2 content/events/2019-11-15-urbit-irl-201911.md+3−2 content/events/2019-12-13-urbit-irl-201912.md+3−2 content/events/2020-01-24-urbit-irl-20201.md+3−2 content/events/2020-02-28-urbit-irl-20202.md+3−2 content/events/2020-04-03-urbit-os1-launch-party.md+4−3 content/events/2020-10-09-urbit-hosting-launch-event.md+4−4 content/events/2020-11-05-developer-call-graph-store.md−1 content/events/2020-11-19-developer-call-bittorrent-tracking-on-urbit.md−1 content/events/2020-12-10-developer-call-injecting-external-services-into-urbit.md−1 content/events/2021-02-04-developer-call-architectural-idea-maze.md−1 content/events/2021-03-04-developer-call-scaling-azimuth.md−1 content/events/2021-03-18-developer-call-pressure-and-protolith.md+4−4 content/events/2021-04-01-developer-call-javascript-apps-on-urbit.md+1−1 content/events/2021-04-27-bitcoin-launch.md+2−1 content/events/2021-04-29-developer-call-real-time-communications-on-urbit.md+1−3 content/events/2021-05-27-town-hall.md+10−5 content/events/2021-06-17-developer-workshop-bitcoin-lightning.md−22 content/events/2021-07-01-developer-call-runtime-future.md+1 content/events/2021-07-15-developer-call-yakshaving.md−2 content/events/_index.md−6 content/faq.md+52−41 content/getting-started/_index.md+6−11 content/getting-started/cli.md+20−23 content/getting-started/planet.md+12−14 content/gifts/sample.md+6 content/grant-submission-guide.md+64 content/grants/-smol-future-sustained-knowledge-sharing-and-marketing.md+94 content/grants/_index.md−7 content/grants/proposals/a-book-about-urbit.md → content/grants/a-book-about-urbit.md+12−15 content/grants/a-collaborative-web-mapping-system-for-urbit.md+90 content/grants/bounties/analytics-script.md → content/grants/analytics-script.md+6−8 content/grants/bounties/antechamber.md → content/grants/antechamber.md+13−13 content/grants/apprenticeships/_index.md−4 content/grants/apprenticeships/ua-3rd-party-software-distribution.md−50 content/grants/apprenticeships/ua-filesharer.md−26 content/grants/proposals/art-by-urbit.md → content/grants/art-by-urbit.md+3−7 content/grants/bounties/bart-train-tracker-landscape-tile.md → content/grants/bart-train-tracker-landscape-tile.md+8−10 content/grants/bounties/bitcoin-full-node-provider-and-wallet.md → content/grants/bitcoin-full-node-provider-and-wallet.md+39−32 content/grants/bounties/bitcoin-key-derivation.md → content/grants/bitcoin-key-derivation.md+17−15 content/grants/bounties/bitcoin-node-json-rpc-api-part-1.md → content/grants/bitcoin-node-json-rpc-api-part-1.md+21−18 content/grants/bounties/bitcoin-node-json-rpc-api-part-2.md → content/grants/bitcoin-node-json-rpc-api-part-2.md+21−18 content/grants/bounties/bitcoin-node-json-rpc-api-part-3.md → content/grants/bitcoin-node-json-rpc-api-part-3.md+20−18 content/grants/bounties/bitcoin-node-json-rpc-api-part-4.md → content/grants/bitcoin-node-json-rpc-api-part-4.md+21−18 content/grants/bounties/bitcoin-wallet-maintenance.md → content/grants/bitcoin-wallet-maintenance.md+12−12 content/grants/bounties/bitcoin-wallet-on-bridge.md → content/grants/bitcoin-wallet-on-bridge.md+10−10 content/grants/bounties/boston-t-train-tracker-landscape-tile.md → content/grants/boston-t-train-tracker-landscape-tile.md+8−12 content/grants/bounties/_index.md−4 content/grants/bounties/bounty-vane-documentation.md−95 content/grants/bounties/bridge-l2-revamp.md → content/grants/bridge-l2-revamp.md+7−8 content/grants/calendar-ui.md+52 content/grants/proposals/calendar.md → content/grants/calendar.md+9−11 content/grants/proposals/comprehensive-local-server-and-mum-explanation-video.md → content/grants/comprehensive-local-server-and-mum-explanation-video.md+5−4 content/grants/apprenticeships/contacts.md → content/grants/contacts.md+10−9 content/grants/proposals/content-producer.md → content/grants/content-producer.md+2−4 content/grants/bounties/content-saver.md → content/grants/content-saver.md+4−7 content/grants/proposals/cross-platform-desktop-urbit-app.md → content/grants/cross-platform-desktop-urbit-app.md+21−13 content/grants/bounties/cta-train-tracker-landscape-tile.md → content/grants/cta-train-tracker-landscape-tile.md+11−11 content/grants/bounties/display-eth-data.md → content/grants/display-eth-data.md+4−7 content/grants/proposals/docker-image-for-cloud-container-orchestration.md → content/grants/docker-image-for-cloud-container-orchestration.md+9−8 content/grants/bounties/educational-guide-todomvc-urbit-edition.md → content/grants/educational-guide-todomvc-urbit-edition.md+21−23 content/grants/proposals/escape.md → content/grants/escape.md+6−8 content/grants/bounties/ethereum-abi-parser.md → content/grants/ethereum-abi-parser.md+4−6 content/grants/proposals/feed-aggregator.md → content/grants/feed-aggregator.md+18−23 content/grants/bounties/gall-api-documentation.md → content/grants/gall-api-documentation.md+14−17 content/grants/gifts/_index.md−4 content/grants/bounties/go-airlock-library.md → content/grants/go-airlock-library.md+4−7 content/grants/proposals/graph-store-documentation-guide.md → content/grants/graph-store-documentation-guide.md+47−35 content/grants/proposals/guide-to-s3.md → content/grants/guide-to-s3.md+2−2 content/grants/bounties/haskell-airlock-library.md → content/grants/haskell-airlock-library.md+3−7 content/grants/proposals/hoon-001-learner-efficiency-and-early-learner-resources.md → content/grants/hoon-001-learner-efficiency-and-early-learner-resources.md+10−15 content/grants/bounties/host-three-college-university-urbit-meetups-1.md → content/grants/host-three-college-university-urbit-meetups-1.md+11−6 content/grants/bounties/host-three-college-university-urbit-meetups-2.md → content/grants/host-three-college-university-urbit-meetups-2.md+11−6 content/grants/bounties/host-three-college-university-urbit-meetups-3.md → content/grants/host-three-college-university-urbit-meetups-3.md+12−6 content/grants/bounties/host-three-virtual-urbit-meetups.md → content/grants/host-three-virtual-urbit-meetups.md+5−7 content/grants/bounties/host-two-urbit-meetups-1.md → content/grants/host-two-urbit-meetups-1.md+12−7 content/grants/bounties/host-two-urbit-meetups-10.md → content/grants/host-two-urbit-meetups-10.md+12−7 content/grants/bounties/host-two-urbit-meetups-11.md → content/grants/host-two-urbit-meetups-11.md+11−6 content/grants/bounties/host-two-urbit-meetups-12.md → content/grants/host-two-urbit-meetups-12.md+6−7 content/grants/bounties/host-two-urbit-meetups-2.md → content/grants/host-two-urbit-meetups-2.md+12−7 content/grants/bounties/host-two-urbit-meetups-3.md → content/grants/host-two-urbit-meetups-3.md+12−7 content/grants/bounties/host-two-urbit-meetups-4.md → content/grants/host-two-urbit-meetups-4.md+12−7 content/grants/bounties/host-two-urbit-meetups-5.md → content/grants/host-two-urbit-meetups-5.md+12−7 content/grants/bounties/host-two-urbit-meetups-6.md → content/grants/host-two-urbit-meetups-6.md+12−7 content/grants/bounties/host-two-urbit-meetups-7.md → content/grants/host-two-urbit-meetups-7.md+12−7 content/grants/bounties/host-two-urbit-meetups-8.md → content/grants/host-two-urbit-meetups-8.md+12−7 content/grants/bounties/host-two-urbit-meetups-9.md → content/grants/host-two-urbit-meetups-9.md+12−7 content/grants/bounties/json-jet.md → content/grants/json-jet.md+13−14 content/grants/proposals/links-in-urbit-reference-docs.md → content/grants/links-in-urbit-reference-docs.md+2−4 content/grants/proposals/llelogram.md → content/grants/llelogram.md+16−19 content/grants/proposals/login-with-urbit.md → content/grants/login-with-urbit.md+17−12 content/grants/bounties/matrices-in-hoon.md → content/grants/matrices-in-hoon.md+9−10 content/grants/proposals/matrixriotim-bridge-bot.md → content/grants/matrixriotim-bridge-bot.md+8−7 content/grants/proposals/minimal-urbit-os.md → content/grants/minimal-urbit-os.md+6−7 content/grants/bounties/network-explorer-data-pipeline-http-api.md → content/grants/network-explorer-data-pipeline-http-api.md+21−19 content/grants/bounties/network-explorer.md → content/grants/network-explorer.md+20−16 content/grants/bounties/nuck-jet.md → content/grants/nuck-jet.md+17−9 content/grants/bounties/open-street-maps-data-importation.md → content/grants/open-street-maps-data-importation.md+6−9 content/grants/bounties/overhaul-the-urbitorg-website.md → content/grants/overhaul-the-urbitorg-website.md+7−9 content/grants/proposals/_index.md−4 content/grants/proposals/a-collaborative-web-mapping-system-for-urbit.md−99 content/grants/proposals/calendar-ui.md−54 content/grants/proposals/smol-future-sustained-knowledge-sharing-and-marketing.md−92 content/grants/proposals/star-documentation-proposal.md−37 content/grants/apprenticeships/ra-page-tracking.md → content/grants/ra-page-tracking.md+5−4 content/grants/apprenticeships/ra-segfaults.md → content/grants/ra-segfaults.md+6−4 content/grants/apprenticeships/ra-stack-overflow.md → content/grants/ra-stack-overflow.md+5−4 content/grants/proposals/ragnarok-online-on-urbit.md → content/grants/ragnarok-online-on-urbit.md+5−8 content/grants/proposals/search-in-groups.md → content/grants/search-in-groups.md+6−7 content/grants/bounties/slaw-scot-jets.md → content/grants/slaw-scot-jets.md+14−10 content/grants/bounties/staff-the-urbit-help-desk-1.md → content/grants/staff-the-urbit-help-desk-1.md+15−14 content/grants/bounties/staff-the-urbit-help-desk-2.md → content/grants/staff-the-urbit-help-desk-2.md+15−14 content/grants/bounties/staff-the-urbit-helpdesk-east.md → content/grants/staff-the-urbit-helpdesk-east.md+5−9 content/grants/bounties/staff-the-urbit-helpdesk-west.md → content/grants/staff-the-urbit-helpdesk-west.md+5−6 content/grants/submit-proposal.md−68 content/grants/proposals/the-complete-guide-to-gall-and-landscape.md → content/grants/the-complete-guide-to-gall-and-landscape.md+32−26 content/grants/bounties/thread-documentation.md → content/grants/thread-documentation.md+34−26 content/grants/bounties/tor-nodes-relay-search-tile.md → content/grants/tor-nodes-relay-search-tile.md+5−9 content/grants/proposals/translate-key-parts-of-urbitorg-into-german.md → content/grants/translate-key-parts-of-urbitorg-into-german.md+2−4 content/grants/proposals/translate-key-parts-of-urbitorg-into-korean.md → content/grants/translate-key-parts-of-urbitorg-into-korean.md+2−5 content/grants/proposals/translate-key-parts-of-urbitorg-into-norwegian.md → content/grants/translate-key-parts-of-urbitorg-into-norwegian.md+2−4 content/grants/proposals/translate-key-parts-of-urbitorg-into-spanish.md → content/grants/translate-key-parts-of-urbitorg-into-spanish.md+2−4 content/grants/proposals/try-urbit-website.md → content/grants/try-urbit-website.md+5−7 content/grants/bounties/typescript-airlock-library.md → content/grants/typescript-airlock-library.md+3−6 content/grants/apprenticeships/ua-collaborative-text-editor.md → content/grants/ua-collaborative-text-editor.md+8−6 content/grants/ua-filesharer.md+28 content/grants/apprenticeships/ua-heads-up-poker.md → content/grants/ua-heads-up-poker.md+12−9 content/grants/apprenticeships/ua-invoice-system.md → content/grants/ua-invoice-system.md+12−9 content/grants/apprenticeships/ua-marketplace.md → content/grants/ua-marketplace.md+2−4 content/grants/bounties/ucal-google-and-outlook-integration.md → content/grants/ucal-google-and-outlook-integration.md+24−26 content/grants/bounties/udon-syntax-highlighter.md → content/grants/udon-syntax-highlighter.md+6−8 content/grants/bounties/unit-tests-for-json-parsing.md → content/grants/unit-tests-for-json-parsing.md+9−11 content/grants/bounties/unit-tests-for-pure-algorithms.md → content/grants/unit-tests-for-pure-algorithms.md+18−21 content/grants/bounties/unit-tests-for-sha-functions.md → content/grants/unit-tests-for-sha-functions.md+10−12 content/grants/bounties/unit-tests-for-zuse-cryptographic-functions.md → content/grants/unit-tests-for-zuse-cryptographic-functions.md+10−12 content/grants/proposals/up-to-date-hoon-reference-card.md → content/grants/up-to-date-hoon-reference-card.md+5−7 content/grants/proposals/urbian-a-customized-linux-distribution-for-urbit-appliances.md → content/grants/urbian-a-customized-linux-distribution-for-urbit-appliances.md+7−8 content/grants/proposals/urbit-api-for-elixir.md → content/grants/urbit-api-for-elixir.md+5−7 content/grants/bounties/urbit-community-concierge-east-coast-2q2021.md → content/grants/urbit-community-concierge-east-coast-2q2021.md+2−4 content/grants/bounties/urbit-community-concierge-east-coast.md → content/grants/urbit-community-concierge-east-coast.md+4−5 content/grants/bounties/urbit-community-concierge-west-coast-2q2021.md → content/grants/urbit-community-concierge-west-coast-2q2021.md+2−4 content/grants/bounties/urbit-community-concierge-west-coast.md → content/grants/urbit-community-concierge-west-coast.md+4−5 content/grants/proposals/urbit-event-series.md → content/grants/urbit-event-series.md+5−6 content/grants/proposals/urbit-explainer-video.md → content/grants/urbit-explainer-video.md+3−5 content/grants/proposals/urbit-http-api-for-emacs-elisp.md → content/grants/urbit-http-api-for-emacs-elisp.md+5−7 content/grants/proposals/urbit-http-api-for-kotlin.md → content/grants/urbit-http-api-for-kotlin.md+5−8 content/grants/proposals/urbit-http-api-for-rust.md → content/grants/urbit-http-api-for-rust.md+5−9 content/grants/proposals/urbit-http-interface-java-edition.md → content/grants/urbit-http-interface-java-edition.md+8−14 content/grants/proposals/urbit-http-library-for-ruby.md → content/grants/urbit-http-library-for-ruby.md+5−7 content/grants/proposals/urbit-irc-bridge.md → content/grants/urbit-irc-bridge.md+5−7 content/grants/proposals/urbit-lfs-filehosting.md → content/grants/urbit-lfs-filehosting.md+10−13 content/grants/proposals/urbit-online-meetup.md → content/grants/urbit-online-meetup.md+2−4 content/grants/proposals/urbit-react-cookbook.md → content/grants/urbit-react-cookbook.md+6−8 content/grants/proposals/urbit-ship-and-star-hosting-and-troubleshooting-docs.md → content/grants/urbit-ship-and-star-hosting-and-troubleshooting-docs.md+3−5 content/grants/bounties/verifying-urbit-id-on-keybase.md → content/grants/verifying-urbit-id-on-keybase.md+14−15 content/grants/bounties/video-content-manager.md → content/grants/video-content-manager.md+10−11 content/grants/bounties/volt-lightning-on-urbit.md → content/grants/volt-lightning-on-urbit.md+135−87 content/grants/bounties/web-scraper.md → content/grants/web-scraper.md+3−5 content/grants/proposals/webrtc-gall-agent-and-external-app.md → content/grants/webrtc-gall-agent-and-external-app.md+15−11 content/grants/proposals/webrtc.md → content/grants/webrtc.md+6−5 content/media/_index.md−7 content/media/blueprint-2017-galen-wolfe-pauly-on-the-distributed-web.md−1 content/media/epicenter-episode-205-urbit-a-digital-republic-reinventing-the-internet.md−1 content/media/lambdaconf-2016-curtis-yarvin-urbit-a-clean-slate-functional-operating-stack.md−1 content/media/lambdaconf-2018-ted-blackman-ford-urbits-build-system.md−1 content/media/the-ether-review-46-curtis-yarvin-and-galen-wolfe-pauly-on-urbit.md−1 content/media/what-is-urbit.md−1 content/privacy.md+22−22 content/reset.md+3−3 content/terms-of-use.md+24−25 content/understanding-urbit/_index.md+66−7 content/understanding-urbit/interface.md+7−8 content/understanding-urbit/people-history.md+7−10 content/understanding-urbit/roadmap.md+11−12 content/understanding-urbit/urbit-id.md+7−7 content/understanding-urbit/urbit-os.md+16−16 content/updates/2018-2-17-update.md+14−13 content/updates/2019-11-06-update.md+1−3 content/updates/2019-12-06-update.md+6−8 content/updates/2020-02-06-update.md+14−11 content/updates/2020-04-04-update.md+5−6 content/updates/2020-06-15-update.md+17−24 content/updates/2020-07-27-update.md+3−4 content/updates/2020-09-30-update.md+64 content/updates/2020-10-29-update.md+48 content/updates/2020-12-01-update.md+67 content/updates/2021-01-15-update.md+59 content/updates/2021-02-19-update.md+80 content/updates/2021-04-01-update.md+88 content/updates/2021-05-05-update.md+69 content/updates/2021-06-16-update.md+77 content/updates/_index.md−6 content/using/_index.md+6−6 content/using/id/_index.md+7−7 content/using/id/creating-an-invite-pool.md+2−2 content/using/id/guide-to-breaches.md+11−11 content/using/id/using-bridge.md+5−5 content/using/os/_index.md+6−6 content/using/os/filesystem.md+4−4 content/using/os/getting-started.md+9−11 content/using/os/shell.md+2−2 content/using/os/ship-troubleshooting.md+3−3 content/using/os/stars-and-galaxies.md+3−3 content/using/running/_index.md+2−2 content/using/running/hosting.md+10−10 static/images/favicon.ico → images/favicon.ico lib/cache.js+73 lib/constants.js+10 lib/glossary.js+6396 lib/hooks.js+37 lib/lib.js+354 lib/rss.js+97 netlify.toml−9 next.config.js+26 package-lock.json+6883 package.json+47 pages/404.js+29 pages/_app.js+71 pages/api/search.js+10 pages/blog.js+96 pages/blog/[slug].js+132 pages/bounties.js+17 pages/community/[[...slug]].js+130 pages/docs/[[...slug]].js+233 pages/events.js+127 pages/events/[slug].js+141 pages/faq.js+17 pages/getting-started/[[...slug]].js+153 pages/grant-submission-guide.js+21 pages/grants.js+372 pages/grants/[slug].js+127 pages/index.js+298 pages/media.js+54 pages/media/[slug].js+109 pages/privacy.js+17 pages/terms-of-service.js+21 pages/understanding-urbit/[[...slug]].js+193 pages/updates.js+79 pages/updates/[slug].js+133 pages/using/[[...slug]].js+163 pages/voting-instructions.js+21 patches/prismjs+1.24.1.patch+42 postcss.config.js+6 sass/_events.scss−82 sass/_main.scss−721 sass/_responsive.scss−33 sass/grid.scss−1542 sass/indigo.scss−2408 sass/styles.scss−3 static/_redirects−165 static/detect.js−26 static/glossary.js−5681 static/scripts.js−469 static/viewport-units-buggyfill.js−472 styles/globals.css+205 styles/markdown.module.css+103 styles/prism.css+170 syntaxes/hoon.sublime-syntax−66 syntaxes/scheme.sublime-syntax−566 tailwind.config.js+52 templates/.gitignore−2 templates/404.html−29 templates/anchor-link.html−2 templates/base.html−73 templates/doc.html−28 templates/essays/list.html−49 templates/essays/post.html−71 templates/events/event-landing.html−26 templates/events/event.html−94 templates/events/list.html−157 templates/getting-started/index.html−41 templates/grant_category/list.html−1 templates/grant_category/single.html−36 templates/grant_type/apprenticeships.html−81 templates/grant_type/bounties.html−47 templates/grant_type/gifts.html−56 templates/grant_type/list.html−1 templates/grant_type/proposals.html−91 templates/grant_type/single.html−23 templates/grants/grant.html−71 templates/grants/list.html−101 templates/index.html−207 templates/list.html−49 templates/macros/macros.html−65 templates/media/list.html−81 templates/media/post.html−68 templates/page.html−78 templates/page_indiced.html−86 templates/partials/footer.html−54 templates/partials/navigation-docs.html−225 templates/partials/navigation-search.html−29 templates/partials/pagination-docs.html−10 templates/partials/pagination.html−79 templates/partials/search-overlay.html−25 templates/partials/subscribe-form.html−34 templates/post_type/list.html−1 templates/post_type/single.html−1 templates/robots.txt−1 templates/rss.xml−21 templates/sections/docs.html−26 templates/sections/docs/chapters.html−26 templates/sections/docs/glossary.html−57 templates/sections/docs/hoon.html−52 templates/sections/index.html templates/shortcodes/soundcloud.html−8 templates/shortcodes/youtube.html−8 templates/taxonomy/list.html−33 templates/taxonomy/single.html−44 templates/understanding-urbit/list.html−84 templates/understanding-urbit/post.html−80 templates/updates/list.html−69 vercel.json+831−4 yarn.lock+1865
.gitignore+38−11
@@ -1,13 +1,40 @@
1−# intermediate
2−*.swo
3−*.swp
4−*~undo-tree~
5−*.o
6−/outside/**/*.a
7−/outside/re2/obj
8−# build
9−public/
1+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
103# dependencies
11−.sass-cache
12−# OS
4+/node_modules
5+/.pnp
6+.pnp.js
7+
8+/public
9+
10+# testing
11+/coverage
12+
13+# next.js
14+/.next/
15+/out/
16+
17+# production
18+/build
19+/cache
20+
21+# misc
1322.DS_Store
23+*.pem
24+
25+# debug
26+npm-debug.log*
27+yarn-debug.log*
28+yarn-error.log*
29+
30+# local env files
31+.env.local
32+.env.development.local
33+.env.test.local
34+.env.production.local
35+
36+# vercel
37+.vercel
38+
39+# editors
40+.nova
.gitmodulesdeleted−3
@@ -1,3 +0,0 @@
1−[submodule "content/docs"]
2− path = content/docs
3− url = https://github.com/urbit/docs.git
.husky/.gitignorenew file+1
@@ -0,0 +1 @@
1+_
.husky/pre-commitnew file+4
@@ -0,0 +1,4 @@
1+#!/bin/sh
2+. "$(dirname "$0")/_/husky.sh"
3+
4+npx pretty-quick --staged
.nova/Configuration.jsonnew file+3
@@ -0,0 +1,3 @@
1+{
2+ "workspace.name": "urbit.org"
3+}
README.md+19−80
@@ -1,93 +1,32 @@
1−# urbit.org
1+The website for Urbit.
22
3−[![Netlify Status](https://api.netlify.com/api/v1/badges/71f99a93-7b2e-4e10-b74d-7cbbb2e6dacd/deploy-status)](https://app.netlify.com/sites/urbit-org/deploys)
4−
5−The website for the Urbit project.
6−
7−## Build
8−
9−1. git clone this repository
10−2. Install [zola@0.13.0](https://github.com/getzola/zola/releases/tag/v0.13.0) (see [Installation](https://www.getzola.org/documentation/getting-started/installation/))
11−3. `git submodule init`
12−4. `git submodule update`
13−5. In the root directory of `urbit.org`, run `zola serve`
14−
15−## Deploy
16−
17−Commits to master are automatically deployed with Netlify.
18−
19−## Post Template and Settings
20−
21−If you're adding content to the site, add a `.md` file to the /content/ directory. Predictably, Updates go in /updates/, Blog posts into /blog/, and Media in /media/.
22−
23−Different templates have different optional configuration settings. All the options used on the site, used in a post template, looks like this:
3+## Getting Started
244
5+```bash
6+npm install
257```
26−+++
27−<!-- Title: Post title. Mandatory. -->
28−title = "Title for Post"
29−
30−<!-- Date: Used in Updates, Media, Blog posts only. -->
31−date = 2020-01-01
32−
33−<!-- Weight: Used when your post directories are being sorted in manual order, not by date. Understanding Urbit and the Docs use weight. -->
34−weight = 0
358
36−<!-- Description: A snippet used in post directory pages. -->
37−description = "A post."
9+Run the development server:
3810
39−<!-- Aliases are used when a post was at another location, and redirects that location to the current post location. If you're moving a page, create an alias. -->
40−aliases = ["/updates/2020.01.01"]
41−
42−<!-- template: Only really needed if you're creating a non-post page with sidebar navigation of its content, in which case you want "page_indiced.html". -->
43−template = "page_indiced.html"
44−
45−<!-- This [extra] is needed above any of the configuration options that follow. -->
46−[extra]
47−
48−<!-- Author: For updates, blog, media. -->
49−author = "Matilde Park"
50−
51−<!-- Ship: The author's ship. Used on post directory pages. -->
52−ship = "~haddef-sigwen"
53−
54−<!-- Image: The URL to the article's main image. Used on Twitter cards and link previews to the site. -->
55−image = "https://media.urbit.org/site/posts/updates/~2019.11.06-update.jpg"
11+```bash
12+npm run dev
13+# or
14+yarn dev
15+```
5616
57−<!-- hidetitle: For non-post pages on the site, the title is automatically inserted as an <h1> at the top. If the title of the page is already displayed in the nav (this occurs in root content pages, like /governance, /privacy), then this just removes that <h1>. -->
58−hidetitle = "true"
17+Finally, open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
5918
60−<!-- soundcloud: Used in /media to embed its link on the post directory page. -->
61−soundcloud = "https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/318017856&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true"
19+## Framework and Library Documentation
6220
63−<!-- youtube: Used in /media to embed its link on the post directory page. Uses just the ID. -->
64−youtube = "5ZAFEylHdiU"
21+To learn more about Next.js, take a look at the following resources:
6522
66−<!-- Pagination settings: Flatten pagination makes all the text regular body size. hideprevious removes the "previous" pagination nav entirely, and hidenext removes the "next" pagination nav entirely. hide_previous_title removes the "Previous Post:" title above the previous post's title, and hide_next_title removes the "Next Post:" title above the next post's title.
67−flatten_pagination = "true"
68−hide_next_title = "true"
69−hide_previous_title = "true"
70−hideprevious = "true"
71−hidenext = "true"
23+- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
24+- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
7225
73−<!-- classes: Blog posts can add any Indigo class to the template. For example, bg-red4 and yellow0 would make the background deep red and the text light yellow. -->
74−classes = "bg-red4 yellow0"
75−+++
76−```
26+To learn more about Tailwind CSS, take a look at the docs:
7727
78−An average blog post just looks like this:
28+- [Tailwind CSS Docs](https://tailwindcss.com/docs) - Docs
7929
80−```
81−+++
82−title = "~2019.10 Roadmap"
83−date = 2019-10-03
84−description = "Galen Wolfe-Pauly on the road ahead for the identity/OS/interface/community stack."
85−[extra]
86−author = "Galen Wolfe-Pauly"
87−ship = "~ravmel-ropdyl"
88−+++
30+## Deployment
8931
90−The daily work of building a new OS from scratch is so engaging and exciting that we habitually forget to even take stock of what we’ve accomplished. We’re fixated on the prospect of moving the world on to Urbit, starting with ourselves.
91−
92−[...]
93−```
32+WIP
bin/builddeleted−1
@@ -1 +0,0 @@
1−zola build
bin/startdeleted−1
@@ -1 +0,0 @@
1−zola serve
components/BackgroundImage.jsnew file+9
@@ -0,0 +1,9 @@
1+// Easily crops images
2+export default function BackgroundImage(props) {
3+ return (
4+ <div
5+ className={`bg-img bg-cover ${props.className || ""}`}
6+ style={{ backgroundImage: `url(${props.src})`, ...props.style }}
7+ />
8+ );
9+}
components/BasicPage.jsnew file+38
@@ -0,0 +1,38 @@
1+import { useRouter } from "next/router";
2+import Head from "next/head";
3+import Meta from "../components/Meta";
4+import ErrorPage from "../pages/404";
5+import Container from "./Container";
6+import Header from "./Header";
7+import Footer from "./Footer";
8+import SingleColumn from "./SingleColumn";
9+import Section from "./Section";
10+import markdownStyles from "../styles/markdown.module.css";
11+import { decode } from "html-entities";
12+
13+export default function BasicPage({ post, markdown, search }) {
14+ const router = useRouter();
15+ if (!router.isFallback && !post?.slug) {
16+ return <ErrorPage />;
17+ }
18+ return (
19+ <Container>
20+ <Head>
21+ <title>Urbit • {post.title}</title>
22+ {Meta(post)}
23+ </Head>
24+ <SingleColumn>
25+ <Header search={search} />
26+ <Section narrow>
27+ <h1>{post.title}</h1>
28+ </Section>
29+ <Section narrow className={markdownStyles["markdown"]}>
30+ <article
31+ dangerouslySetInnerHTML={{ __html: decode(markdown) }}
32+ ></article>
33+ </Section>
34+ </SingleColumn>
35+ <Footer />
36+ </Container>
37+ );
38+}
components/Contact.jsnew file+102
@@ -0,0 +1,102 @@
1+import NewsletterSignup from "./NewletterSignup";
2+import { name, contact } from "../lib/constants";
3+import { useCopyToClipboard } from "../lib/hooks";
4+
5+export default function Contact({ emphasize }) {
6+ const [copyStatus, copy] = useCopyToClipboard(contact.urbitCommunity);
7+
8+ const buttonIcon =
9+ copyStatus === "inactive" ? (
10+ <svg
11+ width="16"
12+ height="16"
13+ viewBox="0 0 16 16"
14+ fill="none"
15+ xmlns="http://www.w3.org/2000/svg"
16+ >
17+ <path
18+ fillRule="evenodd"
19+ clipRule="evenodd"
20+ d="M3.2 1.6C3.2 0.716344 3.91634 0 4.8 0H11.3615L14.9333 2.38124V12.2667C14.9333 13.1503 14.217 13.8667 13.3333 13.8667H12.8V14.4C12.8 15.2837 12.0837 16 11.2 16H2.66667C1.78301 16 1.06667 15.2837 1.06667 14.4V3.73333C1.06667 2.84968 1.78301 2.13333 2.66667 2.13333H3.2V1.6ZM3.2 3.2H2.66667C2.37211 3.2 2.13333 3.43878 2.13333 3.73333V14.4C2.13333 14.6946 2.37211 14.9333 2.66667 14.9333H11.2C11.4946 14.9333 11.7333 14.6946 11.7333 14.4V13.8667H4.8C3.91634 13.8667 3.2 13.1503 3.2 12.2667V3.2Z"
21+ fill="#32302D"
22+ />
23+ </svg>
24+ ) : copyStatus === "copied" ? (
25+ <svg
26+ width="16"
27+ height="16"
28+ viewBox="0 0 16 16"
29+ fill="none"
30+ xmlns="http://www.w3.org/2000/svg"
31+ >
32+ <path
33+ fillRule="evenodd"
34+ clipRule="evenodd"
35+ d="M0 8C0 3.58172 3.58172 0 8 0C12.4183 0 16 3.58172 16 8C16 12.4183 12.4183 16 8 16C3.58172 16 0 12.4183 0 8ZM7.54325 11.4247L12.1498 5.66647L11.3169 5.00013L7.39013 9.90859L4.60812 7.59025L3.92526 8.40969L7.54325 11.4247Z"
36+ fill="#32302D"
37+ />
38+ </svg>
39+ ) : (
40+ <svg
41+ width="16"
42+ height="16"
43+ viewBox="0 0 16 16"
44+ fill="none"
45+ xmlns="http://www.w3.org/2000/svg"
46+ >
47+ <path
48+ fillRule="evenodd"
49+ clipRule="evenodd"
50+ d="M0 8C0 3.58172 3.58172 0 8 0C12.4183 0 16 3.58172 16 8C16 12.4183 12.4183 16 8 16C3.58172 16 0 12.4183 0 8ZM10.8229 11.5772L8.00004 8.75429L5.17716 11.5772L4.42292 10.8229L7.24579 8.00004L4.42292 5.17716L5.17716 4.42292L8.00004 7.24579L10.8229 4.42292L11.5772 5.17716L8.75429 8.00004L11.5772 10.8229L10.8229 11.5772Z"
51+ fill="#32302D"
52+ />
53+ </svg>
54+ );
55+
56+ const linkText = emphasize ? "text-green" : "text-black";
57+ const border = emphasize ? "green" : "black";
58+
59+ return (
60+ <div>
61+ <div className="measure">
62+ <h4 className="pb-6">
63+ If you’d like to follow our progress, we send monthly updates via
64+ email:
65+ </h4>
66+ </div>
67+ <NewsletterSignup color={border} />
68+ <h4 className="mt-12 text-gray">
69+ Follow us on{" "}
70+ <a className={linkText} href={contact.twitter}>
71+ Twitter
72+ </a>
73+ </h4>
74+ <h4 className="mt-6 text-gray">
75+ Explore code on{" "}
76+ <a className={linkText} href={contact.github}>
77+ Github
78+ </a>
79+ </h4>
80+ <h4 className="mt-6 text-gray">
81+ Ask questions in our{" "}
82+ <a className={linkText} href={contact.discord}>
83+ Discord
84+ </a>
85+ </h4>
86+ <h4 className="mt-6 text-gray flex items-baseline flex-wrap">
87+ Boot Urbit and join{" "}
88+ <div className="md:ml-2 rounded-lg flex items-stretch">
89+ <code className="rounded-l-lg px-2 md:px-4 py-2 bg-wall flex items-center h-full">
90+ {contact.urbitCommunity}
91+ </code>
92+ <button
93+ className="rounded-r-lg px-4 bg-wall ml-0.5 flex-1 flex justify-center items-center"
94+ onClick={() => copy()}
95+ >
96+ {buttonIcon}
97+ </button>
98+ </div>
99+ </h4>
100+ </div>
101+ );
102+}
components/Container.jsnew file+8
@@ -0,0 +1,8 @@
1+// Ensures the root container is always 100vw, min 100vh, and centers all children along the y-axis
2+export default function Container({ children }) {
3+ return (
4+ <div className="flex flex-col min-h-screen w-screen items-center">
5+ {children}
6+ </div>
7+ );
8+}
components/ContentArea.jsnew file+54
@@ -0,0 +1,54 @@
1+import Section from "./Section";
2+
3+export default function ContentArea(props) {
4+ return (
5+ <div className="w-full min-w-0 flex flex-col">
6+ <div className="px-4 md:px-12 lg:px-24 pb-24 pt-8 md:pt-10 lg:pt-16 flex flex-col w-full max-h-screen h-screen overflow-y-scroll">
7+ <div className="flex justify-between w-full items-center flex-shrink-0">
8+ <div className="type-ui text-gray">{props.breadcrumbs}</div>
9+ <div className="hidden md:block">
10+ <button
11+ onClick={(e) => {
12+ e.stopPropagation();
13+ props.search.toggleSearch();
14+ }}
15+ className="button-sm bg-wall text-gray"
16+ >
17+ Search<div className="ml-4 text-lightGray">⌘K</div>
18+ </button>
19+ </div>
20+ </div>
21+ <div className="w-full flex justify-center">
22+ {props.narrow ? (
23+ <Section narrow className={""}>
24+ <h2 className="mb-16 mt-24">{props.title}</h2>
25+ {props.children}
26+ <div className="pb-32" />
27+ </Section>
28+ ) : (
29+ <div className="min-w-0">
30+ <h2 className="mb-16 mt-24">{props.title}</h2>
31+ {props.children}
32+ <div className="pb-32" />
33+ </div>
34+ )}
35+ </div>
36+ </div>
37+ </div>
38+ );
39+}
40+
41+// <header className="w-full px-4 md:px-8 md:w-10/12 flex flex-row justify-between items-center pt-8 md:pt-10 lg:pt-12 pb-12">
42+// <div className="type-ui">{props.section}</div>
43+// {
44+// // <button
45+// // onClick={(e) => {
46+// // e.stopPropagation();
47+// // props.search.toggleSearch();
48+// // }}
49+// // className="button-sm bg-wall text-gray"
50+// // >
51+// // Search<div className="ml-4 text-lightGray">⌘K</div>
52+// // </button>
53+// }
54+// </header>
components/EventPreview.jsnew file+33
@@ -0,0 +1,33 @@
1+import Link from "next/link";
2+
3+export default function EventPreview({ event, className, title }) {
4+ // Event tiles have a 'dark mode' used when their background images are dark and white text is needed for legibility.
5+ const grayText = event.extra?.dark ? "text-midWhite" : "text-gray";
6+ const blackText = event.extra?.dark ? "text-white" : "text-black";
7+
8+ return (
9+ <div className={`cursor-pointer ${className}`}>
10+ {title ? <h3 className="mb-2">{title}</h3> : null}
11+ <div
12+ key={event.slug}
13+ className={`bg-wall rounded-xl h-96 bg-cover bg-center bg-no-repeat`}
14+ style={{ backgroundImage: `url(${event.extra?.image})` || "" }}
15+ >
16+ <Link href={`/events/${event.slug}`}>
17+ <div className="flex flex-col p-4 justify-between items-between h-full relative">
18+ <div className="flex-grow-1 flex flex-col justify-center h-full">
19+ <h4 className={`mb-4 ${blackText}`}>{event.title}</h4>
20+ <p className={grayText}>{event?.type}</p>
21+ </div>
22+ <div className="absolute p-4 left-0 bottom-0 w-full">
23+ <p className={`${grayText} type-ui-small`}>{event.extra.host}</p>
24+ <p className={`${grayText} type-ui-small`}>
25+ {event.extra.guests}
26+ </p>
27+ </div>
28+ </div>
29+ </Link>
30+ </div>
31+ </div>
32+ );
33+}
components/Footer.jsnew file+173
@@ -0,0 +1,173 @@
1+import Link from "next/link";
2+import SingleColumn from "./SingleColumn";
3+import Section from "./Section";
4+import { contact } from "../lib/constants";
5+
6+export default function Footer() {
7+ return (
8+ <footer className="bg-wall w-full mt-48 flex justify-center">
9+ <SingleColumn>
10+ <Section short className="flex flex-row flex-wrap">
11+ <div className="w-1/2 md:w-1/3 flex flex-col flex-shrink">
12+ <h4 className="mt-16 mb-8">Use Urbit</h4>
13+ <Link href="/getting-started">
14+ <div>
15+ <a className="type-sub text-gray">Getting Started</a>
16+ </div>
17+ </Link>
18+ <Link href="/using">
19+ <div>
20+ <a className="type-sub text-gray">Operator's Manual</a>
21+ </div>
22+ </Link>
23+ <Link href="https://github.com/urbit/port/releases">
24+ <div>
25+ <a className="type-sub text-gray">Urbit Client</a>
26+ </div>
27+ </Link>
28+ <Link href="https://github.com/urbit/urbit/releases">
29+ <div>
30+ <a className="mt-2 type-sub text-gray">Urbit Binaries</a>
31+ </div>
32+ </Link>
33+ {
34+ // <Link href="">
35+ // <div>
36+ // <a className="mt-2 type-sub text-gray">Urbit Apps</a>
37+ // </div>
38+ // </Link>
39+ }
40+ <Link href="/getting-started/planet/#hosting-providers">
41+ <div>
42+ <a className="mt-2 type-sub text-gray">Hosting Providers</a>
43+ </div>
44+ </Link>
45+ </div>
46+ <div className="w-1/2 md:w-1/3 flex flex-col flex-shrink">
47+ <h4 className="mt-16 mb-8">About</h4>
48+ <Link href="/understanding-urbit">
49+ <div>
50+ <a className="type-sub text-gray">What's Urbit?</a>
51+ </div>
52+ </Link>
53+ <Link href="/understanding-urbit/urbit-id">
54+ <div>
55+ <a className="mt-2 type-sub text-gray">Urbit ID</a>
56+ </div>
57+ </Link>
58+ <Link href="/understanding-urbit/urbit-os">
59+ <div>
60+ <a className="mt-2 type-sub text-gray">Urbit OS</a>
61+ </div>
62+ </Link>
63+ <Link href="/faq">
64+ <div>
65+ <a className="mt-2 type-sub text-gray">FAQ</a>
66+ </div>
67+ </Link>
68+ </div>
69+ <div className="w-1/2 md:w-1/3 flex flex-col flex-shrink">
70+ <h4 className="mt-16 mb-8">News</h4>
71+ <Link href="/blog">
72+ <div>
73+ <a className="type-sub text-gray">Blog</a>
74+ </div>
75+ </Link>
76+ <Link href="/events">
77+ <div>
78+ <a className="mt-2 type-sub text-gray">Events</a>
79+ </div>
80+ </Link>
81+ <Link href="/updates">
82+ <div>
83+ <a className="mt-2 type-sub text-gray">Updates</a>
84+ </div>
85+ </Link>
86+ </div>
87+
88+ <div className="w-1/2 md:w-1/3 flex flex-col">
89+ <h4 className="mt-16 mb-8">Develop</h4>
90+ <Link href="/docs">
91+ <div>
92+ <a className="type-sub text-gray">Documentation</a>
93+ </div>
94+ </Link>
95+ <Link href="https://github.com/urbit">
96+ <div>
97+ <a className="mt-2 type-sub text-gray">Github</a>
98+ </div>
99+ </Link>
100+ <Link href="https://github.com/urbit/awesome-urbit#http-apis-airlock">
101+ <div>
102+ <a className="mt-2 type-sub text-gray">Airlock APIs</a>
103+ </div>
104+ </Link>
105+ </div>
106+ <div className="w-1/2 md:w-1/3 flex flex-col">
107+ <h4 className="mt-16 mb-8">Contribute</h4>
108+ <Link href="https://github.com/urbit/urbit/issues">
109+ <div>
110+ <a className="type-sub text-gray">Issue Tracker</a>
111+ </div>
112+ </Link>
113+ <Link href="/grants">
114+ <div>
115+ <a className="mt-2 type-sub text-gray">Urbit Grants</a>
116+ </div>
117+ </Link>
118+ </div>
119+
120+ <div className="w-1/2 md:w-1/3 flex flex-col">
121+ <h4 className="mt-16 mb-8">Community</h4>
122+ <Link href="https://groups.google.com/a/urbit.org/g/dev?pli=1">
123+ <div>
124+ <a className="type-sub text-gray">Dev Mailing List</a>
125+ </div>
126+ </Link>
127+ <Link href="https://discord.gg/CfSKKaB2ep">
128+ <div>
129+ <a className="mt-2 type-sub text-gray">Support Discord</a>
130+ </div>
131+ </Link>
132+ <Link href="https://github.com/urbit/azimuth">
133+ <div>
134+ <a className="mt-2 type-sub text-gray">Governance</a>
135+ </div>
136+ </Link>
137+ <Link href="https://twitter.com/urbit">
138+ <div>
139+ <a className="mt-2 type-sub text-gray">Twitter</a>
140+ </div>
141+ </Link>
142+ </div>
143+ </Section>
144+ <Section className="flex flex-col md:flex-row">
145+ <div className="md:w-1/3">
146+ <Link href="/privacy">
147+ <div>
148+ <a className="type-sub text-gray">Privacy Policy</a>
149+ </div>
150+ </Link>
151+ </div>
152+ <div className="md:w-1/3">
153+ <Link href="/terms-of-service">
154+ <div>
155+ <a className="type-sub text-gray">Terms of Service</a>
156+ </div>
157+ </Link>
158+ </div>
159+ <div className="md:w-1/3">
160+ <div>
161+ <a
162+ href={"mailto:" + contact.email}
163+ className="type-sub text-gray"
164+ >
165+ {contact.email}
166+ </a>
167+ </div>
168+ </div>
169+ </Section>
170+ </SingleColumn>
171+ </footer>
172+ );
173+}
components/GrantPreview.jsnew file+60
@@ -0,0 +1,60 @@
1+import classnames from "classnames";
2+import Link from "next/link";
3+
4+export default function GrantPreview({ grant }) {
5+ const isOpen = !grant.extra.completed && grant.extra.assignee === "";
6+ const type = grant.taxonomies.grant_type;
7+
8+ const className = classnames({
9+ "bg-lightBlue": type.includes("Proposal") && isOpen,
10+ "bg-lightGreen": type.includes("Apprenticeship") && isOpen,
11+ "bg-lightYellow": type.includes("Bounty") && isOpen,
12+ });
13+
14+ return (
15+ <div
16+ key={grant.slug}
17+ className={`mb-4 cursor-pointer bg-wall rounded-lg ${className}`}
18+ >
19+ <Link href={`/grants/${grant.slug}`}>
20+ <div className="p-8">
21+ <div className="flex items-center mb-4">
22+ <h3 className="type-ui" id={grant.slug}>
23+ {grant.title}
24+ </h3>
25+ <div className={`bg-gray text-wall badge-sm ml-2`}>
26+ {isOpen ? "Open" : "Completed"}
27+ </div>
28+ </div>
29+ <p className="mb-4">{grant.extra.description}</p>
30+ <div className="flex w-full flex-col md:flex-row md:items-center justify-between">
31+ <p className="text-gray">
32+ <strong>Reward: </strong>
33+ {grant.extra.reward} star
34+ {grant.extra.reward === 1 ? "" : "s"}
35+ </p>
36+ <div className="flex items-center flex-wrap md:mt-0 mt-4">
37+ {grant.taxonomies.grant_type.map((category) => {
38+ const className = classnames({
39+ "bg-blue text-white": category === "Proposal",
40+ "bg-green text-white": category === "Apprenticeship",
41+ "bg-yellow": category === "Bounty",
42+ });
43+ return (
44+ <div className={`${className} badge-sm mr-1 my-1`}>
45+ {category}
46+ </div>
47+ );
48+ })}
49+ {grant.taxonomies.grant_category.map((category) => (
50+ <div className="bg-gray text-wall badge-sm mr-1 my-1">
51+ {category}
52+ </div>
53+ ))}
54+ </div>
55+ </div>
56+ </div>
57+ </Link>
58+ </div>
59+ );
60+}
components/Header.jsnew file+129
@@ -0,0 +1,129 @@
1+import Link from "next/link";
2+import { useRouter } from "next/router";
3+import { useState } from "react";
4+import classnames from "classnames";
5+import path from "path";
6+import MenuTray from "../components/MenuTray";
7+import Section from "../components/Section";
8+import { capitalize } from "../lib/lib";
9+
10+function ActiveLink({ children, href, className, currentPath }) {
11+ const firstCrumb = currentPath.split("/")[1];
12+
13+ const activeClassName = classnames({
14+ "text-black": "/" + firstCrumb === href,
15+ "text-gray": "/" + firstCrumb !== href,
16+ });
17+
18+ return (
19+ <Link href={href}>
20+ <a className={`${className} ${activeClassName}`}>{children}</a>
21+ </Link>
22+ );
23+}
24+
25+export default function Header(props) {
26+ const [isOpen, setTray] = useState(false);
27+
28+ const currentPath = useRouter().asPath;
29+
30+ const routeDepth = currentPath.split("/").length;
31+
32+ const firstCrumb = currentPath.split("/")[1];
33+
34+ return (
35+ <header className="w-full px-4 md:px-8 md:w-10/12 flex flex-row justify-between items-center pt-8 md:pt-10 lg:pt-12 pb-10 md:pb-12 lg:pb-24">
36+ <div>
37+ <Link href="/">
38+ <a className="type-ui">Urbit</a>
39+ </Link>
40+ {routeDepth > 2 ? (
41+ <Link href={`/${firstCrumb}`}>
42+ <a className="inline md:hidden type-ui text-gray ml-2">
43+ {capitalize(firstCrumb)}
44+ </a>
45+ </Link>
46+ ) : null}
47+ </div>
48+ {
49+ // Large screen header
50+ }
51+ <nav className="items-center hidden md:flex">
52+ <ActiveLink
53+ currentPath={currentPath}
54+ className="mr-5 type-ui"
55+ href="/docs"
56+ >
57+ Docs
58+ </ActiveLink>
59+ <ActiveLink
60+ currentPath={currentPath}
61+ className="mr-5 type-ui"
62+ href="/blog"
63+ >
64+ Blog
65+ </ActiveLink>
66+ <ActiveLink
67+ currentPath={currentPath}
68+ className="mr-5 type-ui"
69+ href="/events"
70+ >
71+ Events
72+ </ActiveLink>
73+ <ActiveLink
74+ currentPath={currentPath}
75+ className="mr-5 text-green type-ui button-text"
76+ href="/getting-started"
77+ >
78+ Get Started
79+ </ActiveLink>
80+ <button
81+ onClick={(e) => {
82+ e.stopPropagation();
83+ props.search.toggleSearch(e);
84+ }}
85+ className="button-sm bg-wall text-gray"
86+ >
87+ Search<div className="ml-4 text-lightGray">⌘K</div>
88+ </button>
89+ </nav>
90+
91+ {
92+ // Small screen header
93+ }
94+ <MenuTray isOpen={isOpen} setTray={setTray} search={props.search}>
95+ <Link href="/">
96+ <a className="type-ui mb-12">Urbit</a>
97+ </Link>
98+ <ActiveLink
99+ currentPath={currentPath}
100+ className="mr-5 mb-4 type-h3"
101+ href="/docs"
102+ >
103+ Docs
104+ </ActiveLink>
105+ <ActiveLink
106+ currentPath={currentPath}
107+ className="mr-5 mb-4 type-h3"
108+ href="/blog"
109+ >
110+ Blog
111+ </ActiveLink>
112+ <ActiveLink
113+ currentPath={currentPath}
114+ className="mr-5 mb-4 type-h3"
115+ href="/events"
116+ >
117+ Events
118+ </ActiveLink>
119+ <ActiveLink
120+ currentPath={currentPath}
121+ className="mr-5 mb-4 type-h3"
122+ href="/grants"
123+ >
124+ Grants
125+ </ActiveLink>
126+ </MenuTray>
127+ </header>
128+ );
129+}
components/Lorem.jsnew file+106
@@ -0,0 +1,106 @@
1+// Giant lorem ipsum for tests
2+export default function Lorem(props) {
3+ return (
4+ <div className={props.className || ''}>
5+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus sagittis posuere purus vitae auctor. Duis consequat commodo metus vel pellentesque. Nulla massa neque, commodo sed placerat vel, mattis sed felis. Proin et felis auctor, tristique ante at, mollis nisi. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; In tempus blandit volutpat. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
6+
7+ Praesent egestas at metus ac pharetra. Pellentesque tempus elit ex, vel scelerisque magna ornare ac. Vestibulum vitae est nibh. Nullam posuere, libero ac aliquet congue, urna tortor faucibus leo, eu bibendum quam nulla id metus. Vivamus eget feugiat ex. Sed purus nulla, ultricies eget dui fermentum, pellentesque posuere lectus. Maecenas vel orci dignissim ligula luctus varius. Quisque convallis massa in lectus aliquet, varius varius risus scelerisque. Suspendisse et interdum turpis. Sed ac fermentum nulla. Donec nunc est, tincidunt ac fermentum luctus, auctor vel dui. Vivamus hendrerit, libero sed pellentesque viverra, est massa pretium tellus, vel ultrices turpis ante at orci.
8+
9+ Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer sit amet dui sed purus accumsan tempor. Aenean posuere lacus mollis mattis maximus. Integer hendrerit pulvinar tempus. Nam aliquet ipsum et arcu convallis placerat. Donec facilisis odio sed dolor ultricies, nec rhoncus lacus fringilla. Cras luctus odio ipsum, in pretium eros volutpat sit amet. Integer fringilla ipsum at bibendum imperdiet. Maecenas auctor magna non arcu varius rhoncus. Nunc dictum elementum suscipit. Proin rhoncus lacus in massa eleifend blandit.
10+
11+ Maecenas eu tellus dignissim, venenatis turpis eu, tempus odio. Praesent viverra vitae neque in dapibus. Donec fermentum neque at augue volutpat bibendum. Integer blandit tristique sodales. Vestibulum ultrices nulla ac est vulputate imperdiet. Vivamus venenatis cursus tellus quis faucibus. Curabitur non fringilla felis. Sed blandit tellus quis dictum cursus. In quam ex, euismod at ipsum quis, porta tempor nisl. In id scelerisque diam, quis gravida mi.
12+
13+ Nullam lacinia quis nibh vitae fermentum. Sed in libero vitae massa pulvinar feugiat nec non sem. Donec tristique ac felis vel feugiat. Suspendisse tempus ante metus, non porttitor arcu tincidunt nec. Vestibulum iaculis dolor ut quam lobortis, quis mollis purus imperdiet. Vivamus faucibus interdum nibh vel lacinia. Pellentesque at tempus mi. In hac habitasse platea dictumst. Phasellus ultricies tincidunt elementum. Mauris mollis mollis auctor.
14+
15+ Suspendisse potenti. Pellentesque egestas leo ut arcu imperdiet vehicula. Fusce dapibus volutpat leo, tempus sodales risus ultricies et. Nullam gravida massa ac aliquam egestas. In facilisis vitae eros vitae posuere. Duis enim enim, commodo vel dapibus et, consequat sed purus. Morbi ornare vitae tellus nec ultricies. Curabitur egestas lacus ut dictum laoreet. Praesent bibendum cursus pellentesque. Maecenas fringilla tempor lacus id feugiat. Praesent non imperdiet velit. Nulla facilisi. Vestibulum elementum, velit sed ultricies porta, odio eros porta libero, a tempor turpis arcu malesuada ipsum. Phasellus eu mauris elit.
16+
17+ Curabitur id justo a eros tristique semper sodales non ipsum. Mauris aliquam felis sed orci pretium, at placerat urna posuere. Suspendisse potenti. In ac ipsum lorem. Maecenas in semper tortor, ac consectetur enim. Nullam sit amet nulla ante. Aliquam viverra risus et mauris suscipit, at gravida risus dignissim. Proin tincidunt metus eros. Donec tempus finibus nulla quis ullamcorper. Etiam ut nulla nisl. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vivamus lacinia ornare mauris ac fringilla. Maecenas ac faucibus ipsum.
18+
19+ Nulla finibus fringilla lacus, id venenatis dolor pulvinar vitae. Vestibulum vulputate luctus eros, sed commodo justo consectetur fermentum. Suspendisse potenti. Morbi ex diam, dapibus vel faucibus id, mattis et felis. Ut a interdum augue, euismod fringilla ex. Nullam fermentum, eros sed congue vestibulum, tortor neque tempus sapien, in ultricies erat nulla in eros. Aliquam non velit semper, ullamcorper augue nec, auctor purus. Duis enim felis, viverra nec nisi vel, sodales bibendum ante. Etiam sollicitudin ornare cursus.
20+
21+ Donec iaculis bibendum viverra. Mauris mattis consectetur suscipit. Proin at cursus risus. Vivamus eu felis condimentum, tempus enim id, vestibulum odio. Praesent pretium massa vitae turpis aliquet posuere. Nunc egestas, libero eu vestibulum iaculis, leo sapien consequat dolor, ut feugiat nisl metus vel eros. Suspendisse faucibus felis a est porta tincidunt. Sed diam orci, sodales non orci nec, pharetra dapibus ipsum.
22+
23+ Quisque rutrum, urna non vehicula porta, tellus dolor maximus quam, et pharetra justo diam quis neque. Suspendisse at lorem rhoncus, maximus tortor nec, sodales leo. Vivamus eu condimentum mauris. Pellentesque varius, velit nec maximus volutpat, dui purus porta lorem, eu dapibus metus risus non sem. Vestibulum id libero tellus. Quisque tortor turpis, laoreet eu est et, mollis volutpat elit. Nunc posuere enim sit amet vulputate fringilla. Curabitur pretium arcu in sem mattis pellentesque. Quisque vulputate ex leo, at accumsan tellus fermentum sit amet. Fusce ac velit vel dolor lacinia gravida. Proin ac faucibus felis.
24+
25+ Aliquam semper massa et cursus laoreet. Praesent nec ante auctor, dapibus sem id, pellentesque justo. Maecenas iaculis ex sapien, in tempor erat dapibus a. Vivamus varius ut turpis eget vehicula. Sed condimentum enim non consectetur sagittis. Donec eu ipsum eros. Pellentesque convallis tellus id finibus rutrum. Fusce et facilisis metus. Proin quis orci iaculis enim iaculis ultrices a et ipsum. Vivamus blandit a diam at condimentum.
26+
27+ Donec et vestibulum purus. Ut at est pulvinar mauris ultrices facilisis. Duis lacus quam, euismod maximus venenatis at, consectetur id nunc. Suspendisse elementum risus vitae eros laoreet gravida. Fusce aliquam, justo eu auctor iaculis, purus justo molestie metus, in tincidunt metus magna nec orci. Proin lacus libero, maximus eu laoreet nec, egestas et lorem. Nunc condimentum, arcu ac elementum facilisis, purus ligula maximus est, sit amet hendrerit dui ante eu elit. Aenean tempor rutrum massa eget efficitur. Donec tempor metus diam, in gravida nunc lobortis at. Nam elementum sollicitudin aliquam. Proin sit amet quam eros. Vivamus ut ante nisi. Pellentesque vitae felis consectetur erat ultrices ultrices ut a ante. Duis interdum, ante id accumsan maximus, nisi sem euismod sem, vitae facilisis ex nunc a quam. Pellentesque libero sem, tempus sit amet blandit sed, interdum sed ante. Maecenas vitae rhoncus augue, eu molestie erat.
28+
29+ Nullam bibendum, lacus vel tincidunt tristique, ligula sapien interdum velit, non pretium dolor tortor sollicitudin leo. Aliquam vel lorem ut ligula mattis auctor. Proin ullamcorper molestie augue, eget pulvinar justo placerat eu. Sed euismod vehicula enim. In semper faucibus consectetur. Pellentesque interdum varius varius. Cras laoreet felis vitae eros iaculis sollicitudin. Aenean eu mattis felis. Proin mattis nunc sodales hendrerit fringilla. Aliquam velit mauris, feugiat eu felis a, ullamcorper tempus velit. Fusce non pulvinar quam, commodo imperdiet mi. Nam rhoncus turpis neque, in eleifend purus cursus vel. Quisque lobortis, nulla ut auctor finibus, ex nunc tristique nisl, in tincidunt est massa ut sem.
30+
31+ Vestibulum eu urna elit. Aliquam tempor cursus faucibus. Praesent scelerisque dui eu lorem auctor, eu lacinia nibh porttitor. Ut et eros eget felis tristique volutpat a ac tortor. Praesent quis lorem a mauris ultrices imperdiet quis a odio. In cursus maximus orci sed dignissim. Donec semper, orci id consectetur pulvinar, turpis lorem eleifend quam, eu fringilla libero mauris vel ante. Nunc id tellus elit. Etiam facilisis vitae lorem vel fermentum.
32+
33+ Sed bibendum maximus nulla a egestas. Cras commodo ipsum quis magna viverra, quis tempus eros gravida. Donec et dictum dui. Etiam vel orci quis mi molestie eleifend. Vivamus vel tincidunt augue. Fusce vel tortor sagittis, viverra velit nec, consequat elit. Maecenas sem metus, dignissim non mauris ac, elementum tempor lectus. Suspendisse vel sapien tincidunt elit posuere mattis vel id mauris. Nam vitae imperdiet orci. Sed bibendum justo eu bibendum consequat. Mauris mauris sapien, blandit eget semper nec, pulvinar at lorem.
34+
35+ Pellentesque vitae nunc sed nibh condimentum tempor eget sed est. Quisque bibendum eu odio vitae pharetra. Cras ut condimentum purus. Nullam ipsum dui, efficitur tempus tincidunt et, condimentum a ipsum. Curabitur malesuada nibh id massa imperdiet porttitor. Duis quis lobortis dui. Mauris aliquam lectus arcu, vel euismod ante dignissim quis.
36+
37+ In ut vulputate nisi. Vivamus felis est, vestibulum vitae scelerisque non, blandit sit amet purus. Nullam dictum, turpis sed rutrum lacinia, sapien enim dictum lectus, ut molestie lorem enim id mi. Donec vestibulum dui urna, ut viverra purus mattis sit amet. In maximus metus ipsum. Sed bibendum scelerisque mattis. Nunc sed dolor at metus euismod semper. Cras libero purus, porttitor nec sapien eu, pellentesque malesuada magna. Etiam euismod purus ut leo pharetra, sollicitudin hendrerit nibh dignissim. Nam accumsan lacus in velit commodo, non mollis urna ornare. Vivamus ligula metus, ultrices a iaculis quis, venenatis pellentesque nisl. Proin vestibulum pellentesque tortor vel tempor.
38+
39+ Pellentesque id orci tincidunt, egestas erat eu, fermentum ipsum. Nunc efficitur nulla vitae nunc feugiat porttitor. Fusce risus est, dignissim in fermentum vel, finibus eu sapien. Maecenas mollis lorem nec dolor ornare, vel vestibulum nunc fringilla. Quisque at ante nunc. Nam blandit nisi quis blandit auctor. Cras ac sem lorem. Interdum et malesuada fames ac ante ipsum primis in faucibus. Fusce nulla tellus, porttitor id aliquet iaculis, auctor a quam. Aenean sodales pulvinar vehicula.
40+
41+ Etiam non diam tortor. Ut posuere dolor id placerat posuere. Aliquam erat volutpat. Morbi tempor volutpat venenatis. Sed id iaculis mi, in commodo dui. Aliquam eleifend urna sagittis lorem porta malesuada. Praesent placerat justo sed luctus finibus. Vivamus commodo porttitor metus, vulputate sagittis ipsum finibus non. Vestibulum porttitor varius metus eu fermentum. Morbi eleifend augue sit amet velit aliquam facilisis.
42+
43+ Donec et lorem lectus. Integer ex neque, lobortis vitae posuere eu, tincidunt id enim. Vivamus consectetur elit porttitor mi viverra, in sodales velit finibus. Fusce auctor felis a ipsum mollis, nec ornare metus tempus. Fusce nulla felis, semper vitae lorem non, tincidunt feugiat tellus. Vivamus eu pulvinar elit. Proin leo odio, laoreet eu purus ut, luctus laoreet ante. Ut commodo lacus odio, in scelerisque tortor pharetra in. Aenean rhoncus augue non egestas condimentum. Donec maximus placerat facilisis. Praesent aliquam augue non purus volutpat blandit. Pellentesque id mollis enim.
44+
45+ In ut eros posuere, imperdiet sapien a, dapibus velit. Nam at blandit neque. Nam euismod leo et venenatis mattis. Praesent consectetur, risus consequat condimentum tincidunt, ante nibh aliquam ligula, condimentum egestas augue tortor non risus. Nulla accumsan diam a sapien tempus hendrerit. Fusce fringilla mi quis blandit sodales. Quisque finibus mi vel nisi efficitur imperdiet. Cras luctus dapibus mauris non feugiat. Aliquam eu rutrum ipsum. Aliquam elementum luctus molestie. Maecenas molestie nisi molestie, sollicitudin arcu vel, condimentum diam. Mauris eu quam ac lacus accumsan vestibulum. Etiam et mi imperdiet sem convallis dapibus vel eget nisl. In vel faucibus risus. Curabitur luctus pellentesque eros, ac condimentum tellus placerat nec. Nam gravida consequat tincidunt.
46+
47+ Vestibulum consectetur vitae erat non ultrices. Nullam eu diam dictum ante vehicula tempor sit amet et est. Donec ipsum justo, facilisis lobortis vehicula eleifend, viverra a leo. Donec hendrerit, lorem et congue dictum, ipsum nunc facilisis nunc, non ornare nulla augue eu nibh. Ut condimentum in mauris eget blandit. Donec sed est mi. Nunc gravida sodales vestibulum. In hac habitasse platea dictumst.
48+
49+ Aliquam interdum mauris turpis, a efficitur eros molestie suscipit. Donec elementum ultrices augue, in facilisis sapien vestibulum ac. Sed sit amet dictum augue. Nullam posuere ante sit amet cursus molestie. Praesent odio dolor, molestie ac eleifend vitae, tempor quis ligula. Cras a volutpat sem, a varius sapien. Curabitur finibus nisl quis porttitor luctus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque dignissim lacus a neque ultricies blandit. Donec a imperdiet est. Phasellus a tristique lectus. Mauris in augue in metus euismod fringilla.
50+
51+ Praesent congue tincidunt hendrerit. Vivamus efficitur neque est, vel ultricies lectus tempor et. Fusce sit amet lorem sit amet enim eleifend faucibus. Pellentesque mattis malesuada scelerisque. Aliquam quam elit, commodo a commodo nec, vestibulum eget neque. Suspendisse et nibh vestibulum massa placerat maximus rutrum non felis. Donec non nisi rhoncus ipsum luctus ultrices sit amet vel ligula.
52+
53+ In dictum vitae neque vehicula faucibus. Curabitur elementum nibh turpis, a pellentesque nunc viverra eu. Morbi dapibus justo dolor, nec fringilla turpis condimentum eu. Donec nec nibh eu erat tincidunt semper a ut erat. Duis accumsan mattis convallis. Aenean lacus elit, ultrices vitae nibh sit amet, consectetur vulputate risus. Morbi blandit lacus et condimentum mollis. Maecenas id massa ut massa interdum viverra a nec nisl. Pellentesque ullamcorper fringilla eros et volutpat.
54+
55+ Suspendisse egestas, purus sit amet condimentum tincidunt, nunc nibh pulvinar turpis, vel eleifend lacus elit nec ligula. In viverra et ipsum a faucibus. In dictum turpis nec lectus hendrerit, vitae imperdiet orci tincidunt. Aliquam felis risus, aliquam vel ornare vel, molestie vehicula tortor. Etiam ullamcorper sit amet tellus in mollis. Proin ut rhoncus enim. In sit amet blandit est. Quisque ultricies tortor a felis ultricies, in auctor ex feugiat. Integer tempus auctor nunc id molestie. Praesent eget placerat odio. Maecenas feugiat justo a odio blandit venenatis.
56+
57+ Nunc sit amet justo eu sapien efficitur porta. Pellentesque aliquet elementum odio. Donec est diam, vehicula quis scelerisque eget, gravida non arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Ut vehicula vestibulum commodo. Integer sed nunc sit amet augue hendrerit aliquam id quis elit. Donec congue risus non mauris condimentum luctus.
58+
59+ Sed dapibus nulla id feugiat eleifend. Vestibulum cursus malesuada nunc quis porta. Curabitur sodales justo augue, ac semper arcu gravida in. Nunc eu ex rutrum, viverra ipsum in, interdum leo. Nunc erat leo, consectetur vitae magna eget, lacinia auctor dolor. Etiam consequat eros sit amet lorem mollis malesuada. Suspendisse sit amet aliquet libero. Cras ut nisl aliquet, pulvinar odio nec, porttitor nisl. Aenean feugiat diam eget sapien rhoncus placerat. Etiam tincidunt blandit dui at venenatis. Nullam viverra tincidunt diam eget lacinia. Fusce hendrerit arcu nisi, euismod tincidunt eros blandit non. Fusce vehicula est a lorem ornare, id ultrices metus tempor. Aenean in sollicitudin felis.
60+
61+ Nunc euismod dolor erat, sit amet maximus quam blandit nec. Sed mollis placerat facilisis. Donec placerat eget lectus non egestas. In hac habitasse platea dictumst. Nullam vitae molestie justo, vitae convallis massa. Pellentesque quis magna sit amet est consequat vestibulum sed vestibulum tellus. Cras pharetra mi efficitur libero rutrum blandit. Vivamus eu orci ut diam pellentesque scelerisque. In dignissim malesuada risus. Phasellus eu scelerisque justo. Morbi nunc mi, tempus eu tempor sit amet, feugiat quis elit.
62+
63+ Nunc iaculis consectetur lectus, non placerat eros. Praesent sed tellus magna. Fusce in dui mattis, auctor turpis ut, condimentum metus. Duis nibh elit, euismod nec tellus quis, pulvinar consectetur nisl. Quisque laoreet, urna ut pharetra vehicula, erat dolor molestie lorem, ornare porta enim lacus ac massa. Donec volutpat dignissim mi. Nam in imperdiet lectus. Morbi quis varius risus. In ut fermentum elit. In hac habitasse platea dictumst. Duis gravida, nisl at consectetur hendrerit, risus diam porta nisi, dignissim gravida libero urna sit amet diam. Nunc orci felis, tincidunt in turpis quis, varius molestie ex. Praesent dapibus ipsum quis velit cursus, a vehicula orci mattis. In bibendum convallis lorem nec maximus. Praesent erat libero, accumsan vitae semper at, ultrices ornare urna. Sed interdum ex vitae lectus tempus, sit amet imperdiet elit blandit.
64+
65+ Nulla rhoncus dolor in ex porttitor, sit amet scelerisque risus sollicitudin. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed a orci quis diam vehicula pellentesque at molestie risus. Vivamus sollicitudin urna ex, at porta elit blandit sed. Pellentesque malesuada hendrerit diam porttitor ultricies. Suspendisse lobortis, diam non dapibus pulvinar, dui mi sodales quam, in vulputate nibh urna sit amet felis. Mauris sit amet tempor tortor. Ut viverra varius erat, pretium efficitur enim tempor vel.
66+
67+ Sed et mi at neque ornare aliquet ac id risus. Pellentesque auctor varius hendrerit. Vestibulum rhoncus, magna id dapibus dapibus, eros nisl blandit lacus, id suscipit odio leo eget lorem. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas mauris mi, volutpat id felis sit amet, condimentum venenatis ligula. Vivamus vitae ligula aliquet diam viverra dignissim eget vitae dolor. Fusce gravida tincidunt volutpat. Nulla hendrerit lectus in justo tincidunt, ac scelerisque lorem ultricies. Sed varius iaculis ipsum at maximus.
68+
69+ Nulla facilisi. Curabitur et ullamcorper turpis, vitae venenatis tortor. Fusce elementum in nulla vitae tempus. Nam malesuada, nulla quis molestie fermentum, quam sapien vestibulum neque, nec posuere metus nisl semper turpis. Vestibulum semper euismod pretium. Aenean mattis scelerisque pulvinar. Duis pharetra ex ut sem pretium, ut tempus ipsum bibendum. Ut id ligula eu neque suscipit accumsan et non libero. Nulla non ante ligula. Vivamus a posuere justo. Interdum et malesuada fames ac ante ipsum primis in faucibus. Donec ut sollicitudin lectus, in finibus libero. Morbi tempor turpis at metus porta pulvinar.
70+
71+ Donec sollicitudin posuere turpis, sagittis finibus sapien vestibulum finibus. Suspendisse gravida, quam non faucibus dictum, risus ex vulputate nunc, non viverra ipsum leo ut orci. Pellentesque pellentesque vehicula vulputate. Nullam sagittis quis justo et dignissim. Nulla sodales erat nec malesuada malesuada. Phasellus tincidunt tincidunt tincidunt. Nunc malesuada sem ut lectus elementum, non pulvinar augue porta. Proin ultrices sem ut maximus ultricies.
72+
73+ Sed id luctus massa. Ut elementum erat sed sem euismod viverra. Aenean a libero suscipit, facilisis tellus vitae, egestas lectus. Nunc eget maximus purus, vel varius leo. Suspendisse dui felis, aliquet ut ullamcorper sed, ultrices at purus. Pellentesque luctus odio feugiat hendrerit consectetur. Quisque auctor lobortis sem. Sed arcu odio, fringilla sit amet ipsum et, dapibus maximus risus. Aenean malesuada turpis nec aliquet commodo. Morbi mauris nisi, porttitor et sapien vitae, interdum sollicitudin purus. Aliquam at magna ac quam viverra venenatis sit amet ut velit. Aenean accumsan lorem vel nisi tempor condimentum. Nunc elementum ligula ac placerat viverra. Cras et quam in ligula vestibulum finibus sed nec purus. In a accumsan dui. Donec urna neque, venenatis nec nibh mattis, semper convallis orci.
74+
75+ Maecenas luctus pretium ultrices. Donec rutrum nisi vel augue placerat, vitae laoreet velit vehicula. Suspendisse potenti. Quisque posuere congue metus eu viverra. Etiam lacus ante, ullamcorper vitae consectetur sit amet, elementum sit amet risus. Nulla tempus nisi in arcu eleifend rhoncus. Proin elit risus, ultrices eu dui sit amet, dictum finibus dolor. Nunc faucibus sagittis est, eget tempor dui congue ac. Mauris dictum mollis dolor eget gravida. Duis pharetra sed quam non tempor. Ut elementum nisl vel commodo dictum. Quisque velit urna, eleifend sit amet interdum at, interdum in ante. Duis sed elit mauris. In finibus ipsum nec aliquam venenatis. Sed enim mi, gravida et fringilla vel, viverra ut mi. Maecenas est leo, viverra ut interdum ac, viverra ut est.
76+
77+ Cras faucibus tempor consequat. Donec bibendum magna augue, sed faucibus ex semper vel. Nullam sit amet sem enim. Nunc tincidunt, lectus nec blandit rutrum, mi dui mattis ligula, et interdum massa libero in urna. Curabitur in elit viverra, hendrerit enim quis, finibus turpis. Ut euismod efficitur iaculis. Nunc mauris metus, condimentum ac posuere ac, vehicula eget est. Maecenas tincidunt eget leo vel tempus.
78+
79+ Nam porta nulla et sapien ultricies facilisis. Fusce sed rutrum ligula, scelerisque interdum mauris. Sed feugiat venenatis nibh, vitae interdum purus sodales pharetra. Praesent commodo ultricies laoreet. Donec efficitur porta massa sit amet ullamcorper. Nulla consequat ante nec consequat aliquet. Ut vel rutrum turpis, eu mattis lacus. Donec dapibus fringilla nunc, dictum porttitor risus scelerisque et. Vivamus vitae lorem commodo, laoreet risus a, cursus diam. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
80+
81+ Vivamus consequat libero venenatis, aliquet felis nec, gravida arcu. Donec iaculis elit massa, in mattis leo lobortis quis. Nunc id tellus egestas, posuere felis nec, dapibus massa. Integer sagittis sem et nulla sagittis, non dapibus odio aliquam. Proin vitae dolor lacus. Maecenas porttitor nisl ut leo eleifend, sed fermentum lorem iaculis. Donec diam lectus, aliquam in commodo et, sodales nec nunc. Vivamus imperdiet ante non porttitor ullamcorper. Donec vestibulum velit ut sapien pharetra porta.
82+
83+ Ut tempus, enim vel aliquet convallis, eros magna interdum nisi, vel fermentum sem lorem eget magna. Nulla eu sapien id augue ornare vestibulum. Curabitur a mollis turpis, eu fringilla quam. Cras congue lorem eget mauris finibus cursus eu sit amet nisi. Sed ante tellus, molestie id velit ut, congue aliquam lacus. Mauris ultrices leo a enim porttitor, ut rutrum mauris feugiat. Vivamus volutpat, quam eget accumsan cursus, diam ante luctus nibh, ut aliquet nisl mauris at enim. Phasellus purus ex, scelerisque vel quam in, facilisis sollicitudin augue.
84+
85+ Morbi faucibus ut nisi eu facilisis. Donec congue sapien eget felis interdum fringilla. Duis eget magna hendrerit, varius velit eu, accumsan augue. Vestibulum massa nibh, pulvinar ac facilisis a, ultrices ac arcu. Suspendisse fermentum et lorem et euismod. Sed auctor purus justo, id malesuada lacus vehicula nec. Phasellus venenatis nulla eu lacus finibus, sed auctor dolor dapibus. Mauris sollicitudin augue mi, sed viverra dolor imperdiet sed. Nulla facilisi. Pellentesque placerat aliquet erat nec pellentesque. Curabitur accumsan ultricies pharetra.
86+
87+ Aliquam eget lobortis velit, a sollicitudin urna. Etiam eget nunc fermentum, pellentesque velit non, commodo nulla. Cras ultrices sapien purus, ut sagittis orci viverra at. Nulla sed auctor neque, quis pulvinar leo. Nulla ut tempus nunc, in condimentum justo. Morbi pretium fermentum quam ac luctus. Duis eu faucibus enim. Duis imperdiet eleifend ante, nec egestas elit posuere vel. Morbi varius porttitor urna quis ullamcorper. In sapien velit, sagittis eu vestibulum sed, faucibus a elit. Praesent eros mi, vestibulum vel est eget, egestas luctus mauris. Morbi fringilla sapien ut purus auctor laoreet.
88+
89+ Mauris dapibus nisl lacus, sit amet malesuada enim molestie non. Pellentesque feugiat tempor nisi vel vehicula. Sed congue ultrices condimentum. Nulla eget urna laoreet, dictum mauris ac, consequat nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur tempus ante et ex elementum vestibulum. In sit amet nunc quis dui gravida auctor congue non dui. Vestibulum varius vehicula risus sit amet posuere. Morbi a urna volutpat, varius augue sed, sollicitudin diam. In pulvinar felis quis tellus scelerisque, ut dictum turpis placerat. Nunc nunc ligula, cursus a sagittis at, tristique vel ligula. Ut lorem arcu, fringilla vitae molestie nec, dignissim et elit. Praesent commodo, nibh ut semper dapibus, ligula velit maximus lorem, at dapibus ante turpis viverra felis. Etiam mollis mi enim, ac cursus tortor feugiat eu. Phasellus ut augue sit amet nunc vehicula varius.
90+
91+ Ut purus libero, tempor in diam quis, fringilla euismod dolor. Nullam vitae leo magna. Donec elementum eget ex non vestibulum. Praesent vitae consequat urna. Aenean sit amet vehicula lorem. Aliquam malesuada auctor suscipit. Phasellus rhoncus auctor erat. Nam cursus consectetur lacus.
92+
93+ Morbi velit nulla, maximus ac urna ut, finibus tincidunt orci. Sed blandit, nisi sit amet eleifend ultricies, sem justo rhoncus ipsum, eget lobortis enim sem a ante. Vestibulum faucibus sapien magna, nec eleifend eros fermentum sed. Praesent ante lacus, ornare non elementum egestas, porta eget mi. Aenean sit amet luctus erat. Sed dapibus, tortor feugiat viverra luctus, enim sem vestibulum quam, quis elementum nunc velit a nunc. Morbi faucibus pulvinar placerat. Cras vehicula tempor lobortis. Nulla sagittis lorem quis odio eleifend, nec ultricies odio rhoncus. Nunc euismod interdum leo in dignissim. Nullam a metus erat. Phasellus commodo tellus lacus, aliquet faucibus mi accumsan sed. Mauris ultrices sit amet libero in rhoncus. Duis at lectus non est blandit finibus eu id libero.
94+
95+ Donec iaculis ante ut neque dictum, id malesuada orci iaculis. Nunc semper venenatis arcu non consequat. Etiam consectetur arcu ac felis gravida elementum. Suspendisse potenti. Curabitur tortor libero, aliquam nec sem eu, maximus rhoncus augue. Phasellus placerat rhoncus ex, cursus tristique ex efficitur et. Mauris sagittis convallis mollis. Duis tristique vulputate felis, vel accumsan tellus hendrerit vel. Quisque sit amet justo vitae dui pellentesque ullamcorper. Morbi consectetur elit dolor, quis consequat tortor fringilla sit amet.
96+
97+ Praesent molestie ligula non euismod congue. Maecenas semper orci turpis, consectetur varius nisi fringilla a. Donec eget iaculis est, in fermentum augue. Nulla facilisi. In dapibus, nulla non aliquam placerat, tellus nulla commodo neque, eu fermentum augue nulla et magna. Proin auctor nunc fringilla ultricies efficitur. Suspendisse et eros a dolor pharetra semper. Donec sed elit vel odio sollicitudin dapibus vitae at felis. Aliquam sit amet aliquet elit.
98+
99+ Aliquam id quam id felis gravida facilisis quis et velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nullam ultricies mauris ut erat sodales dignissim. Vivamus molestie justo et ante congue interdum. Pellentesque id dolor sagittis ex sollicitudin interdum. Donec dictum, quam in tristique volutpat, libero nibh commodo erat, id porttitor diam ante vitae nunc. Donec ut finibus turpis, a luctus lorem.
100+
101+ Donec et elit ut lorem tincidunt maximus id porttitor arcu. Mauris pharetra lacinia dignissim. Aliquam vel rutrum libero. Nam vehicula, nibh et ullamcorper pulvinar, leo nunc dapibus quam, et mattis purus lorem id diam. In ut venenatis felis. Suspendisse et tempor nulla. Sed finibus pretium nisi quis molestie. In hac habitasse platea dictumst. Nunc accumsan egestas dui, nec suscipit turpis efficitur sed. Mauris dapibus nisl nec eros maximus sollicitudin. Curabitur eget tincidunt ligula. Vivamus in maximus odio.
102+
103+ Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam erat volutpat. Donec et auctor ante. Fusce et ullamcorper risus, nec ullamcorper risus. Vestibulum id iaculis tellus. Quisque a ultricies neque, id viverra quam. Ut est nunc, finibus id leo sed, sodales viverra magna. Proin sit amet purus tellus. Nullam at viverra massa, in gravida justo. In hac habitasse platea dictumst. Mauris orci ligula, porta sit amet est vel, faucibus ullamcorper magna. Nunc eget convallis dui, et faucibus mi. Aliquam erat volutpat. Maecenas mattis mollis mauris in dictum. Suspendisse potenti.
104+ </div>
105+ )
106+}
components/Markdown.jsnew file+47
@@ -0,0 +1,47 @@
1+import remark from "remark";
2+import gfm from "remark-gfm";
3+import slug from "remark-slug";
4+import heading from "remark-heading-id";
5+import html from "remark-html";
6+import remarkprism from "remark-prism";
7+import normalize from "mdurl/encode";
8+
9+// img is wrapped in figure so that images can be extra wide in the blog posts
10+function Img(h, node) {
11+ var props = { src: normalize(node.url), alt: node.alt };
12+ if (node.title !== null && node.title !== undefined) {
13+ props.title = node.title;
14+ }
15+ return {
16+ type: "element",
17+ tagName: "figure",
18+ properties: {},
19+ children: [
20+ {
21+ type: "element",
22+ tagName: "img",
23+ properties: props,
24+ },
25+ ],
26+ };
27+}
28+
29+const options = {
30+ handlers: {
31+ image: Img,
32+ },
33+ entities: "numbers",
34+};
35+
36+// Converts markdown strings into markdown HTML/React components
37+export default async function Markdown({ post }) {
38+ const result = await remark()
39+ .use(html, options)
40+ .use(gfm)
41+ .use(remarkprism)
42+ .use(slug)
43+ .use(heading)
44+ .process(post.content);
45+
46+ return result.toString();
47+}
components/MenuTray.jsnew file+104
@@ -0,0 +1,104 @@
1+import classnames from "classnames";
2+import { useSwipeable } from "react-swipeable";
3+
4+export default function MenuTray({ isOpen, setTray, search, children }) {
5+ // Locks document scrolling when menu is open
6+ if (typeof document !== "undefined") {
7+ if (isOpen) {
8+ document.body.style.overflow = "hidden";
9+ } else {
10+ document.body.style.overflow = "visible";
11+ }
12+ }
13+
14+ const handlers = useSwipeable({
15+ onSwipedLeft: (e) => setTray(false),
16+ });
17+
18+ // Slides the tray in or out from the left
19+ const trayClasses = classnames({
20+ "tray-menu-open": isOpen,
21+ "tray-menu-closed": !isOpen,
22+ });
23+
24+ // Fades the background overlay in or out
25+ const overlayClasses = classnames({
26+ "tray-overlay-open": isOpen,
27+ "tray-overlay-closed": !isOpen,
28+ });
29+
30+ // Hides or shows the menu
31+ const menuClasses = classnames({
32+ "menu-open": isOpen,
33+ "menu-closed": !isOpen,
34+ });
35+
36+ return (
37+ <>
38+ <nav
39+ {...handlers}
40+ className={`z-10 w-screen h-screen top-0 left-0 fixed block md:hidden ${menuClasses}`}
41+ >
42+ <div
43+ onClick={() => setTray(!isOpen)}
44+ className={`bg-washedWhite w-screen h-screen ${overlayClasses}`}
45+ />
46+ <div
47+ className={`absolute bg-wall h-screen top-0 left-0 tray-menu-width overflow-y-scroll mb-24 ${trayClasses}`}
48+ >
49+ <div
50+ {...handlers}
51+ className="flex flex-col px-4 md:px-8 pt-8 md:pt-10 lg:pt-12"
52+ >
53+ {children}
54+ </div>
55+ </div>
56+
57+ <button
58+ onClick={(e) => {
59+ e.stopPropagation();
60+ search.toggleSearch(e);
61+ }}
62+ className={`z-10 fixed px-4 items-center justify-center type-ui rounded-xl h-16 bg-white text-gray left-4 right-4 bottom-4 mobile-search-button-width ${
63+ isOpen ? "flex" : "hidden"
64+ }`}
65+ >
66+ Search
67+ </button>
68+ </nav>
69+ <button
70+ onClick={() => setTray(!isOpen)}
71+ className="z-10 fixed bottom-4 right-4 w-16 h-16 bg-ultraDeepWall flex items-center justify-center rounded-full md:hidden"
72+ >
73+ {isOpen ? (
74+ <svg
75+ width="16"
76+ height="16"
77+ viewBox="0 0 16 16"
78+ fill="none"
79+ xmlns="http://www.w3.org/2000/svg"
80+ >
81+ <path
82+ fillRule="evenodd"
83+ clipRule="evenodd"
84+ d="M0.39382 13.7045C-0.131273 14.2296 -0.131274 15.081 0.39382 15.6061C0.918913 16.1312 1.77026 16.1312 2.29535 15.6061L7.99999 9.90142L13.7047 15.6061C14.2297 16.1312 15.0811 16.1312 15.6062 15.6061C16.1313 15.081 16.1313 14.2296 15.6062 13.7046L9.90152 7.99989L15.6061 2.29535C16.1312 1.77026 16.1312 0.918913 15.6061 0.39382C15.081 -0.131273 14.2296 -0.131273 13.7045 0.39382L7.99999 6.09836L2.29548 0.393844C1.77038 -0.131249 0.919038 -0.13125 0.393945 0.393844C-0.131148 0.918937 -0.131148 1.77028 0.393945 2.29537L6.09846 7.99989L0.39382 13.7045Z"
85+ fill="white"
86+ />
87+ </svg>
88+ ) : (
89+ <svg
90+ width="16"
91+ height="16"
92+ viewBox="0 0 16 17"
93+ fill="none"
94+ xmlns="http://www.w3.org/2000/svg"
95+ >
96+ <rect width="16" height="3" rx="1.5" fill="white" />
97+ <rect y="7" width="16" height="3" rx="1.5" fill="white" />
98+ <rect y="14" width="16" height="3" rx="1.5" fill="white" />
99+ </svg>
100+ )}
101+ </button>
102+ </>
103+ );
104+}
components/Meta.jsnew file+31
@@ -0,0 +1,31 @@
1+export default function Meta(post) {
2+ const author = post?.extra?.author || "Urbit";
3+ const title = `${post?.title} - ` || "";
4+ const description =
5+ post?.description || "Urbit is a personal server built from scratch.";
6+ const image =
7+ post?.extra?.image || "https://media.urbit.org/logo/urbit-logo-card.png";
8+ return (
9+ <>
10+ <link rel="icon" type="image/png" href="/images/favicon.ico" />
11+ <meta
12+ name="twitter:card"
13+ content="summary_large_image"
14+ key="twitter-card"
15+ />
16+ <meta name="twitter:site" content="@urbit" key="twitter-site" />
17+ <meta name="twitter:creator" content="@urbit" key="twitter-creator" />
18+ <meta name="og:title" content={`${title}urbit.org`} key="title" />
19+ <meta name="og:description" content={description} key="description" />
20+ <meta name="description" content={description} />
21+ <meta name="author" content={author} key="author" />
22+ <meta name="twitter:image" content={image} key="image" />
23+ <link
24+ rel="alternative"
25+ type="application/rss+xml"
26+ title="RSS"
27+ href="/rss.xml"
28+ />
29+ </>
30+ );
31+}
components/NewletterSignup.jsnew file+38
@@ -0,0 +1,38 @@
1+export default function NewsletterSignup(props) {
2+ return (
3+ <form
4+ action="https://urbit.us11.list-manage.com/subscribe/post?u=972a03db9e0c6c25bb58de8c8&amp;amp;id=be143888d2"
5+ method="post"
6+ id="mc-embedded-subscribe-form"
7+ name="mc-embedded-subscribe-form"
8+ className="validate form max-w-screen-sm"
9+ target="_blank"
10+ noValidate
11+ >
12+ <div className="input-group" id="mc_embed_signup_scroll">
13+ <div className="mc-field-group w-full relative">
14+ <input
15+ className={`appearance-none outline-none text-gray type-ui black border-${
16+ props.color || "black"
17+ } border-4 px-3 w-full mb-2 h-16 rounded-xl`}
18+ type="email"
19+ name="EMAIL"
20+ id="mce-EMAIL"
21+ placeholder="your@email.com"
22+ />
23+ <div className="flex h-16 items-center justify-center absolute top-0 right-6">
24+ <button
25+ id="mc-embedded-subscribe"
26+ className="type-ui text-gray bg-transparent"
27+ type="submit"
28+ name="subscribe"
29+ >
30+ {/* onClick={() => _paq.push(['trackEvent', 'Mailing List', 'Subscribe'])}> */}
31+ Sign Up
32+ </button>
33+ </div>
34+ </div>
35+ </div>
36+ </form>
37+ );
38+}
components/PageWithIndex.jsnew file+43
@@ -0,0 +1,43 @@
1+import { useRouter } from "next/router";
2+import Head from "next/head";
3+import Meta from "../components/Meta";
4+import ErrorPage from "../pages/404";
5+import Container from "./Container";
6+import Header from "./Header";
7+import Footer from "./Footer";
8+import SingleColumn from "./SingleColumn";
9+import Section from "./Section";
10+import markdownStyles from "../styles/markdown.module.css";
11+import { decode } from "html-entities";
12+import { TableOfContents } from "./TableOfContents";
13+
14+export default function PageWithIndex({ post, markdown, search }) {
15+ const router = useRouter();
16+ if (!router.isFallback && !post?.slug) {
17+ return <ErrorPage />;
18+ }
19+ return (
20+ <Container>
21+ <Head>
22+ <title>Urbit • {post.title}</title>
23+ {Meta(post)}
24+ </Head>
25+ <SingleColumn>
26+ <Header search={search} />
27+ <Section narrow>
28+ <h1>{post.title}</h1>
29+ </Section>
30+ <Section narrow>
31+ <div className="flex sidebar">
32+ <article
33+ className={markdownStyles["markdown"] + " pr-0 lg:pr-16"}
34+ dangerouslySetInnerHTML={{ __html: decode(markdown) }}
35+ ></article>
36+ <TableOfContents />
37+ </div>
38+ </Section>
39+ </SingleColumn>
40+ <Footer />
41+ </Container>
42+ );
43+}
components/Pagination.jsnew file+24
@@ -0,0 +1,24 @@
1+import Link from "next/link";
2+import { formatDate } from "../lib/lib";
3+
4+export default function Pagination(props) {
5+ return (
6+ <Link
7+ href={`/${props.section}/${props.post.slug}`}
8+ key={`post-${props.post.slug}`}
9+ >
10+ <div
11+ className="bg-wall cursor-pointer font-semibold p-2 px-4 rounded-xl flex"
12+ style={{ maxWidth: "45%" }}
13+ >
14+ <p className="flex-shrink-0 pr-1">{props.previous ? "<- " : ""}</p>
15+ <p className="text-black truncate">{props.post.title}</p>
16+ <p className="flex-shrink-0 pl-1">{props.next ? " ->" : ""}</p>
17+ </div>
18+ </Link>
19+ );
20+}
21+
22+Pagination.defaultProps = {
23+ className: "",
24+};
components/PostPreview.jsnew file+30
@@ -0,0 +1,30 @@
1+import Link from "next/link";
2+import BackgroundImage from "./BackgroundImage";
3+import { formatDate } from "../lib/lib";
4+
5+export default function PostPreview(props) {
6+ const section = props?.section ? props.section : "blog";
7+ return (
8+ <div className={`cursor-pointer ${props.className}`}>
9+ {props.title ? <h3 className="mb-2">{props.title}</h3> : null}
10+
11+ <Link
12+ href={`/${section}/${props.post.slug}`}
13+ key={`post-${props.post.slug}`}
14+ >
15+ <div>
16+ <BackgroundImage
17+ className="w-full h-96 rounded-lg"
18+ src={props.post.extra.image || ""}
19+ />
20+ <p className="text-black mt-2">{props.post.title}</p>
21+ <p className="text-gray">{formatDate(new Date(props.post.date))}</p>
22+ </div>
23+ </Link>
24+ </div>
25+ );
26+}
27+
28+PostPreview.defaultProps = {
29+ className: "",
30+};
components/Search.jsnew file+191
@@ -0,0 +1,191 @@
1+import { useCallback, useRef, useState, useEffect } from "react";
2+import { glossary } from "../lib/glossary";
3+import Link from "next/link";
4+import { useRouter } from "next/router";
5+
6+const glossarySearch = (query) => {
7+ return glossary.filter((entry) => {
8+ return query.toLowerCase() === entry.name || entry.symbol === query;
9+ });
10+};
11+
12+export default function Search(props) {
13+ const searchRef = useRef(null);
14+ const [query, setQuery] = useState("");
15+ const [active, setActive] = useState(false);
16+ const [results, setResults] = useState([]);
17+ const searchEndpoint = (query) => `/api/search?q=${query}`;
18+
19+ const router = useRouter();
20+
21+ useEffect(() => {
22+ router.events.on("routeChangeComplete", handleRouteChange);
23+ return () => {
24+ router.events.off("routeChangeComplete", handleRouteChange);
25+ };
26+ }, [router.events]);
27+
28+ const handleRouteChange = () => {
29+ setQuery("");
30+ setResults([]);
31+ setActive(false);
32+ props.closeSearch();
33+ };
34+
35+ const onChange = useCallback((event) => {
36+ const query = event.target.value;
37+
38+ setQuery(query);
39+ if (query.length) {
40+ fetch(searchEndpoint(query))
41+ .then((res) => res.json())
42+ .then((res) => {
43+ setResults(res.results);
44+ });
45+ } else {
46+ setResults([]);
47+ }
48+ }, []);
49+
50+ const onFocus = useCallback(() => {
51+ setActive(true);
52+ window.addEventListener("click", onClick);
53+ }, []);
54+
55+ const onClick = useCallback((event) => {
56+ if (searchRef.current && !searchRef.current.contains(event.target)) {
57+ setActive(false);
58+ window.removeEventListener("click", onClick);
59+ props.toggleSearch();
60+ }
61+ }, []);
62+
63+ let glossaryResults = [];
64+ if (query.length) {
65+ glossaryResults = glossarySearch(query);
66+ }
67+
68+ const clear = useCallback((e) => {
69+ e.stopPropagation();
70+ setQuery("");
71+ }, []);
72+
73+ // Locks document scrolling when search is open
74+ if (typeof document !== "undefined") {
75+ if (props.showSearch) {
76+ document.body.style.overflow = "hidden";
77+ } else {
78+ document.body.style.overflow = "visible";
79+ }
80+ }
81+
82+ if (props.showSearch) {
83+ return (
84+ <div
85+ onClick={props.closeSearch}
86+ className="fixed w-screen h-screen bg-washedWall z-50 flex flex-col items-center p-4"
87+ >
88+ <div
89+ className="relative flex flex-col max-w-screen-lg md:my-32 w-full md:w-10/12 lg:w-8/12 xl:w-6/12 rounded-xl bg-white min-h-0"
90+ ref={searchRef}
91+ >
92+ <div className="relative">
93+ <input
94+ className="text-lg md:text-xl lg:text-2xl font-medium text-green bg-transparent py-2 px-4 outline-none relative w-full"
95+ onChange={onChange}
96+ onFocus={onFocus}
97+ placeholder="Search..."
98+ type="text"
99+ value={query}
100+ onClick={(e) => e.stopPropagation()}
101+ autoFocus={true}
102+ />
103+
104+ <span
105+ onClick={props.toggleSearch}
106+ className="absolute cursor-pointer right-1.5 top-1.5 md:right-2 md:top-2 lg:right-2.5 lg:top-2.5"
107+ >
108+ <p className="px-2 h-8 bg-wall flex items-center justify-center text-sm rounded">
109+ ESC
110+ </p>
111+ </span>
112+ </div>
113+
114+ <div
115+ className={"overflow-y-scroll" + (query.length > 0 ? "" : "hidden")}
116+ >
117+ <div>
118+ {active &&
119+ results.length === 0 &&
120+ glossaryResults.length === 0 &&
121+ query !== "" ? (
122+ <div className="flex font-semibold text-sm p-3 py-8 w-full">
123+ <p className="mr-2 text-gray">No Results found for</p>
124+ <p className="font-semibold">"{query}"</p>
125+ </div>
126+ ) : null}
127+ {active && glossaryResults.length > 0 ? (
128+ <>
129+ <div className="sticky top-0 flex font-semibold text-sm p-3 py-1 w-full bg-ultraDeepWall text-white">
130+ <p className="font-semibold text-sm">Glossary</p>
131+ </div>
132+
133+ {glossaryResults.map(({ name, link, desc, symbol }) => {
134+ return (
135+ <Link href={link} as={link} key={link}>
136+ <div className="cursor-pointer hover:bg-wall">
137+ <div className="font-semibold p-3">
138+ {symbol.length > 0 && (
139+ <code className="mr-1 bg-wall rounded px-1 py-0.5">
140+ {symbol}
141+ </code>
142+ )}
143+ {name}
144+ <p className="font-normal text-base mt-1">{desc}</p>
145+ </div>
146+ </div>
147+ </Link>
148+ );
149+ })}
150+ </>
151+ ) : null}
152+ {active && results.length > 0 && (
153+ <>
154+ <div className="sticky top-0 flex font-semibold text-sm p-3 py-1 w-full bg-ultraDeepWall text-white">
155+ <p className="font-semibold text-sm">
156+ {results.length} results for "{query}"
157+ </p>
158+ </div>
159+
160+ {results
161+ .filter((e) => e.parent !== "Glossary")
162+ .map(({ title, slug, content, parent }) => {
163+ return (
164+ <div
165+ key={slug}
166+ className="cursor-pointer hover:bg-wall p-3"
167+ >
168+ <Link href={slug} as={slug}>
169+ <div>
170+ <p className="font-medium text-base">
171+ {parent !== "Content" ? `${parent} /` : ""}{" "}
172+ {title}
173+ </p>
174+ <p className="text-base font-regular text-small text-gray">
175+ {content}
176+ </p>
177+ </div>
178+ </Link>
179+ </div>
180+ );
181+ })}
182+ </>
183+ )}
184+ </div>
185+ </div>
186+ </div>
187+ </div>
188+ );
189+ }
190+ return null;
191+}
components/Section.jsnew file+21
@@ -0,0 +1,21 @@
1+import classnames from "classnames";
2+
3+// Provides a flexible layout building block
4+export default function Section({
5+ children,
6+ className = "",
7+ short = false,
8+ narrow = false,
9+}) {
10+ const spacing = classnames({
11+ "py-6 md:py-8 lg:py-10": short,
12+ "py-10 md:py-12 lg:py-24": !short,
13+ "md:w-8/12": narrow,
14+ "md:w-10/12": !narrow,
15+ });
16+ return (
17+ <section className={`w-full px-4 md:px-8 ${spacing} ${className}`}>
18+ {children}
19+ </section>
20+ );
21+}
components/Sidebar.jsnew file+32
@@ -0,0 +1,32 @@
1+import Link from "next/link";
2+import { useState } from "react";
3+import MenuTray from "./MenuTray";
4+
5+export default function Sidebar(props) {
6+ const [isOpen, setTray] = useState(false);
7+ return (
8+ <>
9+ <div className="hidden md:flex flex-col w-96 bg-wall max-h-screen h-screen">
10+ <header className="flex flex-shrink-0 justify-between items-center pl-6 pt-12 mt-5 pb-8">
11+ <Link href="/">
12+ <a className="type-ui text-gray">Urbit</a>
13+ </Link>
14+ </header>
15+ <div className="overflow-y-auto p-6 pt-16">
16+ {props.children}
17+ <div className="pb-32" />
18+ </div>
19+ </div>
20+
21+ <MenuTray isOpen={isOpen} setTray={setTray} search={props.search}>
22+ <header className="flex flex-shrink-0 justify-between items-center pb-8">
23+ <Link href="/">
24+ <a className="type-ui text-gray">Urbit</a>
25+ </Link>
26+ </header>
27+ {props.children}
28+ <div className="pt-64" />
29+ </MenuTray>
30+ </>
31+ );
32+}
components/SingleColumn.jsnew file+8
@@ -0,0 +1,8 @@
1+// Provides a limited-width column with all children center-aligned along the vertical axis
2+export default function SingleColumn({ children }) {
3+ return (
4+ <div className="flex flex-col w-full items-center max-w-screen-2xl">
5+ {children}
6+ </div>
7+ );
8+}
components/TabCarousel.jsnew file+9
@@ -0,0 +1,9 @@
1+// Given multiple children, returns only 1 to be rendered based on props.index
2+export default function TabCarousel(props) {
3+ if (props.children) {
4+ if (props.children[props.index]) {
5+ return props.children[props.index]
6+ }
7+ }
8+ return null
9+}
components/TableOfContents.jsnew file+114
@@ -0,0 +1,114 @@
1+import { useState, useEffect, useRef } from "react";
2+
3+export const TableOfContents = ({ staticPosition }) => {
4+ const { nestedHeadings } = useHeadingsData();
5+ const [activeId, setActiveId] = useState();
6+ useIntersectionObserver(setActiveId);
7+ return (
8+ <nav
9+ className={
10+ (staticPosition ? "static" : "sticky") +
11+ " min-h-0 overflow-y-auto w-52 flex-shrink-0 pb-24 hidden lg:block"
12+ }
13+ style={{ top: "8rem", height: "calc(100vh - 16rem)" }}
14+ >
15+ <Headings headings={nestedHeadings} activeId={activeId} />
16+ </nav>
17+ );
18+};
19+
20+const getNestedHeadings = (headingElements) => {
21+ const nestedHeadings = [];
22+
23+ headingElements.forEach((heading, index) => {
24+ const { innerText: title, id } = heading;
25+
26+ if (heading.nodeName === "H2") {
27+ nestedHeadings.push({ id, title, items: [] });
28+ } else if (heading.nodeName === "H3" && nestedHeadings.length > 0) {
29+ nestedHeadings[nestedHeadings.length - 1].items.push({
30+ id,
31+ title,
32+ });
33+ }
34+ });
35+
36+ return nestedHeadings;
37+};
38+
39+const useHeadingsData = () => {
40+ const [nestedHeadings, setNestedHeadings] = useState([]);
41+
42+ useEffect(() => {
43+ const headingElements = Array.from(document.querySelectorAll("h2, h3"));
44+
45+ const newNestedHeadings = getNestedHeadings(headingElements);
46+ setNestedHeadings(newNestedHeadings);
47+ }, []);
48+
49+ return { nestedHeadings };
50+};
51+
52+const Headings = ({ headings, activeId }) => (
53+ <ul>
54+ {headings.map((heading) => (
55+ <li key={heading.id}>
56+ <a className="font-semibold" href={`#${heading.id}`}>
57+ {heading.title}
58+ </a>
59+ {heading.items.length > 0 && (
60+ <ul className="pl-2">
61+ {heading.items.map((child) => (
62+ <li
63+ key={child.id}
64+ className={child.id === activeId ? "text-green" : "text-gray"}
65+ >
66+ <a href={`#${child.id}`}>{child.title}</a>
67+ </li>
68+ ))}
69+ </ul>
70+ )}
71+ </li>
72+ ))}
73+ </ul>
74+);
75+
76+const useIntersectionObserver = (setActiveId) => {
77+ const headingElementsRef = useRef({});
78+ useEffect(() => {
79+ const callback = (headings) => {
80+ headingElementsRef.current = headings.reduce((map, headingElement) => {
81+ map[headingElement.target.id] = headingElement;
82+ return map;
83+ }, headingElementsRef.current);
84+
85+ const visibleHeadings = [];
86+ Object.keys(headingElementsRef.current).forEach((key) => {
87+ const headingElement = headingElementsRef.current[key];
88+ if (headingElement.isIntersecting) visibleHeadings.push(headingElement);
89+ });
90+
91+ const getIndexFromId = (id) =>
92+ headingElements.findIndex((heading) => heading.id === id);
93+
94+ if (visibleHeadings.length === 1) {
95+ setActiveId(visibleHeadings[0].target.id);
96+ } else if (visibleHeadings.length > 1) {
97+ const sortedVisibleHeadings = visibleHeadings.sort(
98+ (a, b) => getIndexFromId(a.target.id) > getIndexFromId(b.target.id)
99+ );
100+ setActiveId(sortedVisibleHeadings[0].target.id);
101+ }
102+ };
103+
104+ const observer = new IntersectionObserver(callback, {
105+ rootMargin: "0px 0px -50% 0px",
106+ });
107+
108+ const headingElements = Array.from(document.querySelectorAll("h2, h3"));
109+
110+ headingElements.forEach((element) => observer.observe(element));
111+
112+ return () => observer.disconnect();
113+ }, [setActiveId]);
114+};
config.tomldeleted−35
@@ -1,35 +0,0 @@
1−# See: https://www.getzola.org/documentation/getting-started/configuration/
2−# Used in RSS by default
3−title = "Urbit"
4−description = "Urbit is a personal server built from scratch."
5−# The default language, used in RSS
6−default_language = "en"
7−# The URL the site will be built for
8−base_url = "https://urbit.org"
9−# Whether to automatically compile all Sass files in the sass directory
10−compile_sass = true
11−# Whether to generate a RSS feed automatically
12−generate_feed = true
13−build_search_index = true
14−taxonomies = [
15− { name = "grant_type" },
16− { name = "grant_category" },
17− { name = "post_type" }
18−]
19−feed_filename = "rss.xml"
20−
21−[markdown]
22−# A list of directories used to search for additional `.sublime-syntax` files.
23−# TODO: syntax highlighting is currently broken on 0.13.0, but works on zola@next
24−# see: https://github.com/getzola/zola/issues/1309
25−extra_syntaxes = ["syntaxes"]
26−# Whether to do syntax highlighting
27−highlight_code = true
28−# Theme can be customised by setting the `highlight_theme` variable to a theme supported by Zola
29−highlight_theme = "demain"
30−
31−# You can put any kind of data here. The data
32−# will be accessible in all templates
33−[extra]
34−author = "urbit.org"
35−docs_number_chapters = true
content/Bitcoin-wallet.md+8−11
@@ -2,8 +2,6 @@
22title = "Bitcoin Wallet"
33+++
44
5−
6−
75The latest Urbit release includes a native Bitcoin wallet. Please read the following security recommendations and disclaimers carefully. Urbit.org cannot recover any lost keys.
86
97### Instructions
@@ -12,7 +10,7 @@ Run `|start %btc-wallet` in the dojo. After refreshing Landscape you should see
1210
13111. Enter a provider who is connected to a full-node (such as `~zod`). The provider will maintain a synced Bitcoin ledger, index your public addresses to determine your balance, and process your transactions.
1412
15−2. The next step is to provide an extended public key (or xpub). Providing your xpub allows the Bitcoin Wallet to automatically generate new public addresses (called *child public keys*—you can learn more about this [here](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)) when bitcoin is sent to your ship. To provide an xpub you can either enter your master ticket (which can be downloaded from [Bridge](https://bridge.urbit.org)), or directly import your xpub (such as from a hardware wallet like [Ledger](https://support.ledger.com/hc/en-us/articles/360011069619-Extended-public-key) or [Trezor](https://wiki.trezor.io/User_manual:Displaying_account_public_key_(XPUB))).
13+2. The next step is to provide an extended public key (or xpub). Providing your xpub allows the Bitcoin Wallet to automatically generate new public addresses (called _child public keys_—you can learn more about this [here](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)) when bitcoin is sent to your ship. To provide an xpub you can either enter your master ticket (which can be downloaded from [Bridge](https://bridge.urbit.org)), or directly import your xpub (such as from a hardware wallet like [Ledger](https://support.ledger.com/hc/en-us/articles/360011069619-Extended-public-key) or [Trezor](<https://wiki.trezor.io/User_manual:Displaying_account_public_key_(XPUB)>)).
1614
1715Clicking on the Landscape tile will take you to the Bitcoin Wallet application, where you can view your balance and send bitcoin. All that you'll need to do is enter the recipient's Urbit ID (if they have configured the wallet using the above steps) or a Bitcoin address.
1816
@@ -20,28 +18,27 @@ If you are interested in [being a provider](https://subject.network/posts/btc-wa
2018
2119### Verify
2220
23−You should verify your version of this Bitcoin wallet. To do so, follow the instructions in the README in our [Github](https://github.com/urbit/urbit/blob/master/pkg/btc-wallet/README.md) repo.
21+You should verify your version of this Bitcoin wallet. To do so, follow the instructions in the README in our [Github](https://github.com/urbit/urbit/blob/master/pkg/btc-wallet/README.md) repo.
2422
25−Instructions reproduced here:
23+Instructions reproduced here:
2624
2725To verify your version of the bitcoin wallet, run the following command in the dojo:
2826`> +btc-wallet-check`
2927It should return with the following hash:
3028`0v9t022.n8kv1.5emkt.s2p9i.hvsa9`
3129
32−
3330### Disclaimer Statement
3431
35−The Urbit Bitcoin Wallet and its related components are experimental pieces of software. You are free to review the open-source code before using:
36−- [Wallet](https://github.com/urbit/urbit/tree/master/pkg/btc-wallet)
32+The Urbit Bitcoin Wallet and its related components are experimental pieces of software. You are free to review the open-source code before using:
33+
34+- [Wallet](https://github.com/urbit/urbit/tree/master/pkg/btc-wallet)
3735- [Full Node Provider Agents](https://github.com/timlucmiptev/btc-agents)
3836
39−No guarantees are made about the security of this software. It may contain vulnerabilities that could lead to loss of funds. This wallet software has not had a formal security audit. 
37+No guarantees are made about the security of this software. It may contain vulnerabilities that could lead to loss of funds. This wallet software has not had a formal security audit.
4038
4139You can read about the security audit for Urbit's networking protocol in this [post](https://urbit.org/blog/security-audit/). This audit does not encompass the wallet, except to the extent that the wallet operates on Urbit's networking architecture.
4240
43−If you decide to use this wallet, please store responsible amounts of Bitcoin, and use best security practices. The developers of this software cannot help you recover your keys / funds, if lost. 
44−
41+If you decide to use this wallet, please store responsible amounts of Bitcoin, and use best security practices. The developers of this software cannot help you recover your keys / funds, if lost.
4542
4643### License
4744
content/_index.mddeleted−3
@@ -1,3 +0,0 @@
1−+++
2−title = "Home"
3−+++
content/blog/_index.mddeleted−6
@@ -1,6 +0,0 @@
1−+++
2−title = "Blog"
3−sort_by = "date"
4−template = "essays/list.html"
5−page_template = "essays/post.html"
6−+++
content/blog/a-topiary.mddeleted−49
@@ -1,49 +0,0 @@
1−+++
2−title = "A Topiary: Hypertext and Urbit"
3−date = 2021-06-14
4−description = "A brief history of hypertext and Urbit networking"
5−[extra]
6−author = "Reid Scoggin"
7−ship = "~sitful-hatred"
8−image = "https://media.urbit.org/site/posts/essays/treebranches.jpeg"
9−+++
10−
11−![](https://media.urbit.org/site/posts/essays/treebranches.jpeg)
12−
13−
14−> Under the trees of England I meditated on this lost and perhaps mythical labyrinth. I imagined it untouched and perfect on the secret summit of some mountain; I imagined it drowned under rice paddies or beneath the sea; I imagined it infinite, made not only of eight-sided pavilions and of twisting paths but also of rivers, provinces and kingdoms... I thought of a maze of mazes, of a sinuous, ever growing maze which would take in both past and future and would somehow involve the stars.
15−
16−
17−-- *The Garden of Forking Paths*, Jorge Luis Borges
18−
19−
20−The pre-technological world was already [networked](https://en.wikipedia.org/wiki/Indra%27s_net). No material object and no idea has ever stood alone—"no man is an island". Language itself is a network of associations shared between a group of people. The question of technology is: how do we bring our web of associations into the realm of computers? The legacy internet has focused on social networks almost exclusively—our mammalian brains readily took to this, we all love to [signal](https://conversationswithtyler.com/episodes/robin-hanson/). But before “social media” there was something called hypertext: a seemingly modest way to connect documents shared between computers.
21−
22−A footnote in a book used to require a library, locating the referenced book, and finding the cited page (which might have footnotes itself)! Hypertext allows one to traverse a network quickly and easily with just mouse clicks, making information accessible to those without the time and resources to hunt down physical artifacts. Urbit’s “%graph-store” is not the same as hypertext but it does bear some familial resemblances. Fundamentally, %graph-store is a data structure that can accommodate disparate data types within a single edifice. It is based on [graph databases](https://en.wikipedia.org/wiki/Graph_database) and recent implementations such as [GraphQL](https://graphql.org/). To understand this data structure it is worth diving into the origins of hypertext—the original linked network.
23−
24−The story of hypertext begins at the end of WWII with an article in *The Atlantic* that proposed to extend the human mind via machine. Vannevar Bush had seen first-hand the explosion of electronics manufacturing and scientific knowledge, recognizing the great peril and opportunity of such a revolution. His [description](https://www.theatlantic.com/magazine/archive/1945/07/as-we-may-think/303881/) of the Memex presaged the technological world of today, envisioning a personal device that would allow the user to draw upon a vast library of information, and link documents together arbitrarily—what he called "associative indexing"—a deliberate recreation of how the mind connects thoughts.
25−
26−
27−The 1960s saw the first implementations of these ideas. Ted Nelson's [writing](https://archive.org/details/SelectedPapers1977/page/n15/mode/2up) around *Project Xanadu* elaborated this linking between documents into what Nelson called *hypertext*. Nelson imagined "a text arranged in a graph structure", centered around a corpus arranged in nonlinear sequence, manipulable by author or audience. The concept was first demonstrated in 1968, at Douglas Engelbart's 'Mother of all Demos', where a vision of computers as a collaborative social environment was revealed to the world. "[The Journal](https://www.dougengelbart.org/content/view/137/#7)", presented alongside other revolutionary demos, exhibited collaboratively edited documents with hyperlinked connections. Any time-travellers in the audience would have immediately recognized the first webpage. From here, the idea of a linked network of documents would be developed through successive phases of computing, from the mainframe to the PC.
28−
29−
30−Experimentation with these ideas continued through the 1970s and 80s. A team directed by Andy Lippman at MIT extended the concept to threaded visual hypermedia with the *Aspen Movie Map*, a user-directed virtual tour of Aspen, Colorado. Hypertext and hypermedia gained a mass audience for the first time with HyperCard, a program that shipped with Mac computers. Users were able to collect or create '[stacks](https://archive.org/details/hypercardstacks
31−)' of interlinked cards; a personal body of text, art, and knowledge could be accrued and modified, or shared with others—though not yet with native networking capabilities.
32−
33−
34−With the World Wide Web, hypertext achieved escape velocity. Initially a one-man [project](http://info.cern.ch/hypertext/WWW/TheProject.html), the world wide web was similar to Bush’s vision of the Memex—a way to share, index, and connect information between individuals and groups. The web succeeded by utilizing the physical infrastructure already available: PCs with graphical interfaces, DNS, and the internet. Critically, its method of transmitting and traversing texts was a standardized protocol, allowing a free body of information to assemble atop the new infrastructure by anyone willing to learn the tools. A new frontier was cleared and cultivated with open standards, but it would gradually face enclosure.
35−
36−
37−In the following decade, after the first wave of social networking sites had crested but before phones became the primary web clients, Twitter was launched. Originally an awkward bridge between SMS and the web, its design eventually coalesced around static identity, posts with chronological sorting, and interlinked post threads. These simple primitives spawned a vast corpus of information, a graph-of-graphs intertwined and overlapped, mapping an entire platonic world. Twitter is fundamentally constrained by its very nature: it is the walled garden of an advertising company. The financial incentives of the server operators demanded seizure of the commons and the replacement of standardized protocols with proprietary databases.
38−
39−
40−As the first networked services withered, a new critique was implicitly articulated in the construction of a [new kind of abstract machine](https://moronlab.blogspot.com/2010/01/urbit-functional-programming-from.html). Urbit learned from the past: tightly defined protocols, baked-in cryptography, and decentralization were key. If power over the network was determined by those who ran the servers, then we would run the servers ourselves.
41−
42−
43−Urbit is not fundamentally a hypertext system; it is a new kind of computer, designed to participate in a peer-to-peer network that rejects the client-server model. All Urbit software takes its networking model for granted, it is not an ad-hoc layering of mismatched abstractions. Fundamental design decisions determine the trajectory of the future.
44−
45−
46−Early [implementations](https://en.wikipedia.org/wiki/Neo4j) of graph databases and projects like [RDF](https://en.wikipedia.org/wiki/Resource_Description_Framework) hit on the same core idea: linked data needs its own data structure. In 2020 Urbit OS adopted an application called %graph-store that made use of a new, native [data structure](https://docs.google.com/document/d/1-Gwfg442kV3cdfG7NnWPEf2TMa3uLUTAKkZD70ALZkE/edit) which would act as a database service for social applications. Chats, long-form text, and other types of data produced in the course of social computing now share the same tent, a single structure extensible to new types of content. Each item added to it is a node in a personal graph—a tree that grows branches as your computer communicates. These nodes can be linked arbitrarily to other graphs—Urbit's global immutable namespace grants both permanence and ownership and allows the graph’s branches to intertwine with others. Graphs can accommodate a variety of content, from simple text, to code and media yet to be conceived. You own your graph, and it is a record of your digital journey with others.
47−
48−
49−Personal hypertext graphs are leaving behind proprietary platforms and gaining independence. Graphs until now have been used as tools of surveillance and marketing, but they are being reclaimed and sewn back into the network, each bound to the cryptographic identity of an individual, permanent computer. Where the map of your life was once splintered across a thousand systems and held in the custody of strangers, it is now possessed only by you and shared only as you see fit. On Urbit, an infinite forest of digital lives can take root, nesting their boughs and stalks.
content/blog/community-spotlight-the-portico.md+6−6
@@ -10,7 +10,7 @@ image = "https://media.urbit.org/site/posts/essays/orthodoxchurch.jpg"
1010
1111![](https://media.urbit.org/site/posts/essays/orthodoxchurch.jpg)
1212
13−*One of the most striking things about Urbit is the ideological diversity between communities. The Community Spotlight blog series will focus on various Urbit communities via interviews with founding members.*
13+_One of the most striking things about Urbit is the ideological diversity between communities. The Community Spotlight blog series will focus on various Urbit communities via interviews with founding members._
1414
1515For the first week of the Community Spotlight series, I (~tirwyd-sarmes) will be speaking with Josh Reagan (~taglux-nidsep). Josh is the founder of The Portico, an Urbit community of Eastern Orthodox Christians.
1616
@@ -26,13 +26,13 @@ I encourage you to take a look. Find The Portico at ~topnup-firber/the-portico.
2626
2727\-\-\-\-
2828
29−**Do you see any connection between Rod Dreher’s *The Benedict Option* and your community on Urbit? Dreher sees a need for American Christians to create self-sustaining communities outside of the mainstream to protect the Christian religion and culture.**
29+**Do you see any connection between Rod Dreher’s _The Benedict Option_ and your community on Urbit? Dreher sees a need for American Christians to create self-sustaining communities outside of the mainstream to protect the Christian religion and culture.**
3030
31−It’s tough to say with certainty—I’ve never read *The Benedict Option*.
31+It’s tough to say with certainty—I’ve never read _The Benedict Option_.
3232
3333A few years ago, while he was writing the book, I was a regular reader of Dreher’s blog. From his descriptions there, I was never clear about what exactly he was proposing. Much of his “clarification” came by way of metaphor: don’t “run for the hills”, but stop “shoring up the American imperium”. I didn’t read his book because I didn’t have much confidence that he would be especially precise or insightful.
3434
35−[There is an interesting review I’d recommend](https://handleshaus.wordpress.com/2020/10/06/review-of-rod-drehers-live-not-by-lies/), however, of his later book, *Live Not By Lies*. I believe it accurately characterizes the scale of the threat Christians will soon face in this country.
35+[There is an interesting review I’d recommend](https://handleshaus.wordpress.com/2020/10/06/review-of-rod-drehers-live-not-by-lies/), however, of his later book, _Live Not By Lies_. I believe it accurately characterizes the scale of the threat Christians will soon face in this country.
3636
3737My upbringing was conservative Christian and self-consciously counter-cultural. I've inherited that understanding of what it means to be a Christian in an increasingly secular world. It comes naturally to me, so I find it obvious that Christians should form self-sustaining communities. But the details matter. What do such communities look like? How do we secure the freedom to pursue such communities? How do we sustain them, when myriad external forces seek to undermine them? How do we solve the long-term problem of the declining cultural importance of Christianity (which surely erodes the plausibility of our religion to many, even to some of those with sympathies toward it)?
3838
@@ -62,7 +62,7 @@ None of these options is appealing. Tarski came up with a solution that mostly s
6262
6363Is Tarski’s definition of truth in a language the definitive solution for preserving truth, math, and logic? Perhaps not many philosophers think so, and there’s a massive literature in which logicians have attempted to improve on or extend his results.
6464
65−Sometimes people seem to think formal logic is an infallible gift from heaven that must always be right. Kant said in the *Critique of Pure Reason* that formal logic is essentially a completed field. In fact, [the logic of his day](https://en.wikipedia.org/wiki/Port-Royal_Logic) was an early-modern Cartesian variation of a medieval scholastic synthesis of ancient Stoic and Aristotelian logics. Roughly 100 years after Kant’s first critique was published, C. S. Peirce and Gottlob Frege independently discovered first-order mathematical logic as we know it today, inaugurating the greatest advance of logic since Aristotle. Kant was wrong.
65+Sometimes people seem to think formal logic is an infallible gift from heaven that must always be right. Kant said in the _Critique of Pure Reason_ that formal logic is essentially a completed field. In fact, [the logic of his day](https://en.wikipedia.org/wiki/Port-Royal_Logic) was an early-modern Cartesian variation of a medieval scholastic synthesis of ancient Stoic and Aristotelian logics. Roughly 100 years after Kant’s first critique was published, C. S. Peirce and Gottlob Frege independently discovered first-order mathematical logic as we know it today, inaugurating the greatest advance of logic since Aristotle. Kant was wrong.
6666
6767Mathematical logic is a convenient, generally reliable, man-made tool that, when used carelessly in certain untamed domains, can lead one astray. Probably most people reading this are familiar with such puzzles as the Liar paradox. When one understands that logic is not a completed science, and perhaps never will be, there is less reason to worry about whether it can be used to nuke entire disciplines, like theology.
6868
@@ -82,7 +82,7 @@ For many ancients, the term “λόγος” meant something like “divine prin
8282
8383We are told that all things come into being through the Logos (John 1:3), giving Him an intimate relationship to the whole of creation. He gives structure and order to all created things, and in His divinity He understands them as so structured and ordered. He is also sinless, perfectly holy, and good. In Christ we have a perfect unity of the knowledge of all truth and righteousness.
8484
85−Man was created in the image of God, which means that we bear a likeness to Christ. And we are commanded to realize that likeness with ever greater fidelity (Romans 8:29). The Church calls the pursuit of this likeness [“theosis”](https://en.wikipedia.org/wiki/Theosis_(Eastern_Christian_theology)).
85+Man was created in the image of God, which means that we bear a likeness to Christ. And we are commanded to realize that likeness with ever greater fidelity (Romans 8:29). The Church calls the pursuit of this likeness [“theosis”](<https://en.wikipedia.org/wiki/Theosis_(Eastern_Christian_theology)>).
8686
8787Thus we have the explanation of all normativity, according to Orthodox Christianity. In moral matters we must take on the holiness of Christ. In epistemic matters we aspire to the wisdom and knowledge of Christ, which includes an understanding of the whole created order. Socially we (the community of believers, i.e. the Church) are called to be in ever greater communion with God, cooperating with His work just as the Son cooperates with the Father.
8888
content/blog/first-contract.md+10−11
@@ -41,10 +41,10 @@ according to the governance rules we [detail below](#senate).
4141
4242## Changelist {#changelist}
4343
44−The Galactic Senate is voting on the following changes to Ecliptic:
44+The Galactic Senate is voting on the following changes to Ecliptic:
4545
46−- Fixed ERC721 compatibility
47−- Self-modifying proxies
46+- Fixed ERC721 compatibility
47+- Self-modifying proxies
4848- Upgraded Claims contract
4949
5050### Fixed ERC721 compatibility
@@ -116,16 +116,16 @@ driving force behind its development. We’d like to take this opportunity to
116116spell out our perspective on where we’re at in that process. Here are some previous posts that are relevant, but please note that
117117some of them are several years old and as such may not accurately reflect our
118118current position, but still serve as useful historical markers. We hope to
119−revisit and refresh these documents soon.
119+revisit and refresh these documents soon.
120120
121121- [2016.5.16 - Interim
122−Constitution](@/blog/interim-constitution.md)
122+ Constitution](@/blog/interim-constitution.md)
123123- [2016.5.16 - The
124−Urbit Address Space](@/blog/the-urbit-address-space.md)
124+ Urbit Address Space](@/blog/the-urbit-address-space.md)
125125- [2016.6.24 - The DAO as a Lesson in Decentralized
126−Governance](@/blog/the-dao-as-a-lesson-in-decentralized-governance.md)
126+ Governance](@/blog/the-dao-as-a-lesson-in-decentralized-governance.md)
127127- [2019.1.11 - Governance of
128−urbit.org](@/blog/governance-of-urbit.md)
128+ urbit.org](@/blog/governance-of-urbit.md)
129129
130130### Galactic Senate
131131
@@ -144,7 +144,7 @@ were to declare that [Azimuth is live](https://github.com/urbit/azimuth/pull/25)
144144and that [Arvo is stable](https://github.com/urbit/azimuth/pull/24).
145145
146146### Address space distribution
147−
147+
148148Perhaps the most informative measure of how decentralized Urbit is in terms of
149149how many independent parties hold address space. By the very nature of Urbit, it
150150is impossible to know this with great accuracy (a common feature of
@@ -201,7 +201,7 @@ the only corporation actively updating Urbit’s MIT-licensed open source
201201software, namely [Vere](@/docs/glossary/vere.md) (the runtime),
202202[Arvo](@/docs/glossary/arvo.md) (the kernel),
203203[Landscape](@/docs/glossary/landscape.md) (the client), and
204−[Bridge](@/docs/glossary/bridge.md) (the ID manager), unaffiliated individuals have been making enormous contributions to Urbit over the past couple of years via the [grants program](https://grants.urbit.org/history). Recent examples include the [Bitcoin node and wallet integration](https://github.com/urbit/urbit/pull/4940), [WebRTC integration](https://grants.urbit.org/proposals/21131866-webrtc-gall-agent-and-external-app), [Port, an Urbit installer and ship manager](https://github.com/arthyn/port), and [`|fuse`, an important primitive for 3rd party software distribution](https://github.com/urbit/urbit/pull/4820).
204+[Bridge](@/docs/glossary/bridge.md) (the ID manager), unaffiliated individuals have been making enormous contributions to Urbit over the past couple of years via the [grants program](https://grants.urbit.org/history). Recent examples include the [Bitcoin node and wallet integration](https://github.com/urbit/urbit/pull/4940), [WebRTC integration](https://grants.urbit.org/proposals/21131866-webrtc-gall-agent-and-external-app), [Port, an Urbit installer and ship manager](https://github.com/arthyn/port), and [`|fuse`, an important primitive for 3rd party software distribution](https://github.com/urbit/urbit/pull/4820).
205205
206206The only real power Tlon holds over Urbit is the ability to push [OTA
207207updates](@/docs/glossary/ota-updates.md) via `~zod`, and suggest that people
@@ -290,4 +290,3 @@ governance in the future, so there is ample opportunity for the system to evolve
290290in response to the will of the users. As always, it is important to keep in mind
291291the unfinished nature of the Urbit of today and the still moldable clay of the
292292Urbit of tomorrow⁠—nothing yet is set in stone.
293−
content/blog/gifts-q3-2020.md+13−7
@@ -3,7 +3,8 @@ title = "Gifts Q3 2020"
33date = 2020-09-23
44description = "Twice a year we distribute address space to those that have made valuable contributions to Urbit. Now called our Gifts program, the gifting of address space has been part of Urbit long before we had a grants program."
55[taxonomies]
6−post_type = ["gifts"]
6+grant_type = ["Gift"]
7+grant_category = []
78[extra]
89author = "Josh Lehman"
910ship = "~wolref-podlex"
@@ -16,14 +17,15 @@ image ="https://media.urbit.org/site/posts/essays/gifts.png"
1617
1718<br>
1819
19−Twice a year we distribute address space to those that have made valuable contributions to Urbit. Now called our *Gifts* program, the gifting of address space has been part of Urbit long before we had a grants program.
20+Twice a year we distribute address space to those that have made valuable contributions to Urbit. Now called our _Gifts_ program, the gifting of address space has been part of Urbit long before we had a grants program.
2021
2122I'm happy to announce that urbit.org has a record number of gifts to distribute to community contributors for the period from February to August of 2020. Because the gifting of address space is an old tradition, and the last several months have seen an unprecedented amount of user growth, let’s talk about why we do this.
2223
2324## Why gifts?
24−One way to think about Urbit is as *infrastructure for powering digital communities.* We’ve talked about this before in [some detail](https://urbit.org/blog/urbit-is-for-communities/), so while I won’t rehash the “why” of that here, I’ll reiterate that what we really want is a digital world that's generated by the communities that inhabit it.
2525
26−We know that digital communities need better technology with which to generate their world; just as importantly though, they need *people* to inhabit and develop them.
26+One way to think about Urbit is as _infrastructure for powering digital communities._ We’ve talked about this before in [some detail](https://urbit.org/blog/urbit-is-for-communities/), so while I won’t rehash the “why” of that here, I’ll reiterate that what we really want is a digital world that's generated by the communities that inhabit it.
27+
28+We know that digital communities need better technology with which to generate their world; just as importantly though, they need _people_ to inhabit and develop them.
2729
2830Tlon and urbit.org can’t bring the world into Urbit alone—we need community members to help us. By distributing address space to a variety of people that can invite their friends and families, the network can grow faster, more organically, and with a wider range of diversity.
2931
@@ -32,9 +34,10 @@ Currently, the majority of available address space is owned by Tlon and urbit.or
3234Gifts are one of the ways we invest in the future of the network. We look for others that see Urbit’s value and engage in building the digital home that they want to live in. They ease the learning curve for people new to Urbit, contribute to the technology, and create thriving communities.
3335
3436## Recipients
37+
3538Gifts are being awarded for a variety of reasons this quarter. As usual, there have been plenty of code and documentation contributions, but this time around we’re also recognizing those who have evangelized Urbit, been active in guiding newcomers to the system, and developed thriving communities within Landscape.
3639
37−Gifts are being awarded using the following criteria:
40+Gifts are being awarded using the following criteria:
3841
3942**Bronze**: one star for continuous contributions over the last six months in at least one of the above areas.
4043
@@ -45,21 +48,24 @@ Gifts are being awarded using the following criteria:
4548Without further ado, here are the recipients:
4649
4750### Gold
51+
4852[`~radbur-sivmus`](https://github.com/tylershuster) has more or less become an unofficial member of the interface team by tackling an absolutely [immense](https://github.com/urbit/urbit/pulls?q=is%3Apr+author%3Atylershuster+) amount of Landscape-related work.
4953
5054### Silver
55+
5156- [`~littel-wolfur`](https://github.com/ryjm): Jake maintains the premier development group in Urbit, The Forge, and has led the way for other developers by authoring [srrs](https://github.com/ryjm/srrs), one of the more popular community-developed applications on Urbit.
5257- [`~botter-nidnul`](https://github.com/botter-nidnul): `~botter` has been instrumental in furthering [Urbit on ARM](https://botter-nidnul.github.io/), has made contributions across Vere and our documentation, and been highly active in onboarding newcomers on our Discord server.
5358- [`~timluc-miptev`](https://github.com/timlucmiptev): `~timluc` is highly engaged in many groups and the maintainer of some, wrote the [Nock for Everyday Coders](https://blog.timlucmiptev.space/part1.html) guide, and has gone far above and beyond in teaching the community about developing Landscape applications.
5459- [`~lanrus-rinfep`](https://github.com/dclelland): Daniel has done extensive development on iOS by writing Swift libraries for interacting with Urbit, and employed all of these towards the development of an [iOS client for chat](https://github.com/dclelland/UrsusChat).
55−- [`~minder-folden`](https://twitter.com/the_pritchard): Jonathan is a prolific member of the community. His group *The Sanctorium* is always active, he's always around to help newcomers to the system, is an active evangelist on Twitter, and a creator of much excellent content.
60+- [`~minder-folden`](https://twitter.com/the_pritchard): Jonathan is a prolific member of the community. His group _The Sanctorium_ is always active, he's always around to help newcomers to the system, is an active evangelist on Twitter, and a creator of much excellent content.
5661
5762### Bronze
63+
5864- [`~watter-parter`](https://github.com/lukechampine): Luke has made a number of [contributions](https://github.com/urbit/urbit/pulls?q=is%3Apr+is%3Aclosed+author%3Alukechampine) to Arvo, and wrote a great [introductory guide](https://github.com/lukechampine/rote) to developing Gall agents.
5965- [`~naltyc-wornes`](https://github.com/JohnELester): `~naltyc` runs the popular group “Smol Computers” both inside and outside of Urbit where discussions ensue about various forms of computing on small devices like Android and ARM, and actively evangelizes the project.
6066- [`~nartes-fasrum`](https://twitter.com/nartesfasrum): `~nartes` evangelizes Urbit on Twitter by creating artwork, and maintains the popular food-centric group “Urbytes.”
6167- [`~fonnyx-nopmer`](https://twitter.com/fonnyx_nopmer): `~fonnyx` maintains an active presence throughout many groups on Urbit and runs the first Urbit-centric podcast, [Hooked on fonnyx](https://www.twitch.tv/fonnyx).
62−- `~libhut-samwes`: `~libhut` started and maintains one of the most popular groups on Urbit centered on crypto and investing, and contributes to conversations throughout Urbit.
68+- `~libhut-samwes`: `~libhut` started and maintains one of the most popular groups on Urbit centered on crypto and investing, and contributes to conversations throughout Urbit.
6369- `~salmus-master`: In addition to embodying the quality of high-level, respectful debate we like to see, `~salmus` created the group: “The Tribal Network,” where he maintains one of the most active long-form notebooks on Urbit.
6470- [`~fostyr-solfyr`](https://github.com/cmarcelo): `~fostyr` has submitted a number of PRs against Arvo, including a much-requested feature to reset the web login code.
6571- [`~sarpen-laplux`](https://github.com/xiphiness): `~sarpen` has done a significant amount of research and work on Ethereum ABI parsing and other Ethereum-related topics in addition to being an active participant in dialogues throughout Urbit.
content/blog/iot.md+14−14
@@ -14,10 +14,10 @@ image = "https://media.urbit.org/site/posts/essays/phobos.jpeg"
1414
1515<br>
1616
17−Each of the ~4B 32-or-fewer-bit or [Azimuth](@/docs/glossary/azimuth.md)
18−identities, namely [planets](@/docs/glossary/planet.md),
19−[stars](@/docs/glossary/star.md), and [galaxies](@/docs/glossary/galaxy.md), may
20−spawn ~4B 64-bit child identities known as [moons](@/docs/glossary/moon.md).
17+Each of the ~4B 32-or-fewer-bit or [Azimuth](/docs/glossary/azimuth)
18+identities, namely [planets](/docs/glossary/planet),
19+[stars](/docs/glossary/star), and [galaxies](/docs/glossary/galaxy), may
20+spawn ~4B 64-bit child identities known as [moons](/docs/glossary/moon).
2121Moons are the undeveloped wild outback of Urbit, with a story waiting to be told
2222that promises to be as enormous in scale as the cloud personal computing story
2323told by planets, and possibly even more so.
@@ -37,7 +37,7 @@ settings, especially with respect to agriculture, and how they may manifest as
3737the workhorse collection unit of decentralized data markets.
3838
3939For those unfamiliar, moons differ from all other
40−[ships](@/docs/glossary/ship.md) in that they are not independent identities
40+[ships](/docs/glossary/ship) in that they are not independent identities
4141with total sovereignty over their data and keys. Instead, their cryptographic
4242keys are issued and controlled by their parent identity. The relationship
4343between the keys of a parent ship and its moons are analogous to the
@@ -114,7 +114,7 @@ In 2021, moons are mostly unused on Urbit. There's a smattering of minor use
114114cases which we'll describe here, but they represent only a tiny fraction of
115115their ultimate potential.
116116
117−Tlon recently launched a survey bot called [Eliza](@/blog/eliza.md), which was
117+Tlon recently launched a survey bot called [Eliza](/blog/eliza), which was
118118initially a comet. We frequently got questions on whether Eliza was actually
119119Tlon's bot, because it could just as easily be a malicious actor posing as Tlon.
120120We soon plan to relaunch Eliza as a moon of `~zod`, which is the most
@@ -143,7 +143,7 @@ to maintain a more performant planet.
143143As we currently lack a real system for 3rd party software distribution (though
144144see this recent [developer call](https://youtu.be/XwICC6Its1E) on a solution in
145145progress), one stopgap has been to download software by syncing a foreign
146−[desk](@/docs/glossary/desk.md) to your ship. This is risky, as buggy software
146+[desk](/docs/glossary/desk) to your ship. This is risky, as buggy software
147147may make break your ship and make it difficult to get running properly again.
148148For this reason, testing new software on the livenet is frequently performed on
149149moons, so as not to risk the parent ship if something were to go wrong.
@@ -228,8 +228,8 @@ Here, the hub or controller referred to would be your planet.
228228Urbit has many other features that make it well-suited for IoT, above and beyond
229229eliminating the SaaS model and providing self-authenticating identities. Many of
230230these additional advantages derive from the fact that Urbit is a [solid state
231−interpreter](@/docs/arvo/overview.md#solid-state-interpreter) and that
232−[Ames](@/docs/glossary/ames.md) is a network of solid-state interpreters
231+interpreter](/docs/arvo/overview#solid-state-interpreter) and that
232+[Ames](/docs/glossary/ames) is a network of solid-state interpreters
233233equipped with cryptographic identity. We explore this in the next section.
234234
235235### Future lunar cosmotechnics
@@ -253,7 +253,7 @@ In order to respect the reader's time, I'm narrowing our scope to a particular
253253topic: the agriculture industry. I'm also assuming a future with specialized and
254254increasingly small hardware to run Urbit. Right now, a 4 GB Raspberry Pi is the
255255standard for "small Urbit". If someday there are CPUs specifically designed for
256−running [Nock](@/docs/glossary/nock.md), one could imagine going much smaller.
256+running [Nock](/docs/glossary/nock), one could imagine going much smaller.
257257Ultimately, I'm going to assume that there will someday be [solid-state
258258interpreter](#ssi) microcontrollers - so the inclusion of Urbit on a device may
259259require nothing more than a couple [surface-mount
@@ -272,7 +272,7 @@ industrial scale, and show how computerized and mechanized workflows add to the
272272amazing productivity of modern farms and demonstrate that individual-sized
273273inputs are able to create industrial-sized outputs. I predict that the set of
274274trades for which this dynamic holds will only increase over time.
275−
275+
276276Agricultural automation has been a primary engine for the growth of
277277civilization, but it has been hampered by the downsides of IoT elaborated in the
278278previous section. One bellwether of this dynamic is the right to repair one's
@@ -325,8 +325,8 @@ properties are of great benefit in an industrial IoT context such as
325325agriculture. We'd also like to predict that Urbit will not be the only SSI.
326326Other sorts of SSI's specialized to various tasks may one day roam the planet,
327327and these may be better suited for particular IoT tasks than
328−[Arvo](@/docs/glossary/arvo.md). However, this article will be couched in terms
329−of SSIs communicating with an [Ames](@/docs/glossary/ames.md)-like networking
328+[Arvo](/docs/glossary/arvo). However, this article will be couched in terms
329+of SSIs communicating with an [Ames](/docs/glossary/ames)-like networking
330330protocol and Urbit ID-style cryptographic identity, rather than Urbit in
331331particular.
332332
@@ -350,7 +350,7 @@ deterministic at the CPU level, interruptions to power can result in an
350350undefined semantic state and result in the random erasure of half of its brain.
351351This determinism is what begets ease of maintainability of Urbit—problems
352352generally only need to be solved once by experts and the solution propagates to
353−the rest of the network via [OTA updates](@/docs/glossary/ota-updates.md). We
353+the rest of the network via [OTA updates](/docs/glossary/ota-updates). We
354354addressed this maintenance issue previously—we only remark now that this
355355property is derived from being a SSI, rather than something particular only to
356356Arvo or Urbit. When one has hundreds or thousands of devices to manage, the
content/blog/metaphase.md+9−9
@@ -14,15 +14,15 @@ image = "https://media.urbit.org/site/posts/essays/metaphase.jpg"
1414
1515<br>
1616
17−*Previous versions of this essay specified the stream deploy date as December 11, 2020; then December 18, 2020. This has been amended to the actual date of release, with our sincere apologies. For new readers, you can opt into the dev stream by running:*
17+_Previous versions of this essay specified the stream deploy date as December 11, 2020; then December 18, 2020. This has been amended to the actual date of release, with our sincere apologies. For new readers, you can opt into the dev stream by running:_
1818
1919```
20−|ota ~hanruc-nalfus-nidsut-tomdun %kids
20+|ota ~hanruc-nalfus-nidsut-tomdun %kids
2121|merge %home ~hanruc-nalfus-nidsut-tomdun %kids, =gem %take-that
2222|merge %kids ~hanruc-nalfus-nidsut-tomdun %kids, =gem %take-that
2323```
2424
25−*We will surface this option more broadly in a future settings overhaul.*
25+_We will surface this option more broadly in a future settings overhaul._
2626
2727A few weeks ago, the Landscape team — those of us building Tlon’s suite of userspace applications on top of Urbit— deployed our first over-the-air update for notifications. This is a big leap forward for us. Of course, getting notifications inside Landscape itself is a big deal, but getting a push notification on your phone, or an email digest based on activity inside Urbit is now just one step away, a weekend project for a hobby developer, not an indeterminate number of steps away.
2828
@@ -30,7 +30,7 @@ After release, we received some feedback from users on the behaviour and design
3030
3131As I’ll describe, we haven’t just been iterating Landscape, but the way we develop Landscape, and the way we consider Landscape in relation to Arvo. Finally, we’ll discuss our upcoming two-stream release process: a “stable” release stream with updates every six weeks and a development stream, with ongoing changes continuously deployed on an opt-in basis.
3232
33−To someone coming to Landscape for the first time, it is starting to look mature; and it is indeed maturing quickly. After all, these mismatches in expectations are pangs calling out for growth. Landscape truly has *users*, not just explorers, who are developing the same expectations they have with the other tools they use: predictability, reliability, and iterative improvements, not just leaps forward. So to meet those expectations, we’ve been working on the prerequisite work for a mature release schedule, with two different release streams for users and explorers: a lifecycle, with the cells, interlinked, dividing into a coherent higher being.
33+To someone coming to Landscape for the first time, it is starting to look mature; and it is indeed maturing quickly. After all, these mismatches in expectations are pangs calling out for growth. Landscape truly has _users_, not just explorers, who are developing the same expectations they have with the other tools they use: predictability, reliability, and iterative improvements, not just leaps forward. So to meet those expectations, we’ve been working on the prerequisite work for a mature release schedule, with two different release streams for users and explorers: a lifecycle, with the cells, interlinked, dividing into a coherent higher being.
3434
3535## Landscapers and lifecycles
3636
@@ -46,9 +46,9 @@ We traditionally tended toward solving those problems by writing the simplest po
4646
4747For most of its history, Landscape’s userspace suite had to be up-to-date on all ships to function at all, so multiple staging streams added quite a few complications. Since incompatible versions of applications on different ships would produce mutual fail states if they attempted to interact –and since each application had no sense of how to negotiate compatibility with older applications, each user had to keep up-to-date. Landscape was moving too fast, constantly reconfiguring (to give you a sense of this: we still refer to a month ago as “old”).
4848
49−Historically, Arvo and Landscape were also considered just one object; changes in Landscape would often require refining the layers underneath it as well. We often aimed to use our interface’s requirements to refine Arvo in turn. But as Landscape’s cells continued to split, as it became a proper client *for* Arvo rather than a subsection *of* Arvo, it required its own planning and execution cycle that only came to fruition around April of this year.
49+Historically, Arvo and Landscape were also considered just one object; changes in Landscape would often require refining the layers underneath it as well. We often aimed to use our interface’s requirements to refine Arvo in turn. But as Landscape’s cells continued to split, as it became a proper client _for_ Arvo rather than a subsection _of_ Arvo, it required its own planning and execution cycle that only came to fruition around April of this year.
5050
51−The first thing we did was start recurring, six-week product backlogs with designers and engineers to occasionally reassess short-term priorities with a larger roadmap. Once we did that, we began working on opening our process to the public, migrating all tasks, priorities, and current decisions to a [product board](https://github.com/urbit/landscape). By doing this, community members could both suggest features *and* contribute features, with a centralised, transparent process for getting designer input and Tlon engineer priorities. This has also been a successful effort.
51+The first thing we did was start recurring, six-week product backlogs with designers and engineers to occasionally reassess short-term priorities with a larger roadmap. Once we did that, we began working on opening our process to the public, migrating all tasks, priorities, and current decisions to a [product board](https://github.com/urbit/landscape). By doing this, community members could both suggest features _and_ contribute features, with a centralised, transparent process for getting designer input and Tlon engineer priorities. This has also been a successful effort.
5252
5353By adjusting ourselves to a six week rhythm for execution, it’s clearly time to slow down our release schedule and dedicate design and QA time to each release.
5454
@@ -59,7 +59,7 @@ That said, our userspace infrastructure is maturing, so we could at least organi
5959So now, before we could launch a stable stream, we had some things to do first:
6060
6161- **We wanted to provide assurance that the userspace suite is relatively stable.** All our remaining stores (invite-store, metadata-store, and contact-store) needed to be modernised to use the same libraries and utilities inside Arvo as newer userspace applications.
62−- **We wanted all our applications to be using graph-store.** If we were going to migrate the entire network to a new userspace model, we shouldn’t undermine the new release cycle process and make it more difficult to test and deploy to meet higher user expectations. We needed to migrate everything first.
62+- **We wanted all our applications to be using graph-store.** If we were going to migrate the entire network to a new userspace model, we shouldn’t undermine the new release cycle process and make it more difficult to test and deploy to meet higher user expectations. We needed to migrate everything first.
6363- **We wanted to release the notification-store**. After the October 2020 groups release, Landscape simply wouldn’t be complete without it.
6464- Finally, **we wanted all of Landscape to use the [Indigo component library](https://github.com/urbit/indigo-react).** Landscape shipped with each application using its own build with handwritten, bespoke DOM components. Once we moved to a single-page application architecture in June 2020, we wanted the same guaranteed consistency for both back-end and front-end code.
6565
@@ -71,12 +71,12 @@ And for intrepid users, you can opt-in to a development stream and help us find
7171
7272## Mitosis
7373
74−Describing our progress so candidly can feel strange — after all, it sounds so *early*. But to me, it’s exciting. It’s mitosis.
74+Describing our progress so candidly can feel strange — after all, it sounds so _early_. But to me, it’s exciting. It’s mitosis.
7575
7676Take another example. For all of Urbit’s history — all until now — Tlon was playing the role of both parents to the project when it was really just an embryonic corporate vehicle itself, fated to become twins. But in the past few months the burgeoning Urbit Foundation’s interim Director, Josh Lehman (`~wolref-podlex`), has begun to ramp up responsibility, taking increasing stewardship over urbit.org and giving it a physical voice, an Otherness, apart from Tlon’s own goals.
7777
7878Now, each day, we stray a little closer to these entities splitting apart, a step closer to the Urbit Foundation and the Tlon Corporation being completely different entities with completely different concerns.
7979
80−The same has occurred with Landscape. Previously Landscape was “*the* interface to Urbit,” the proof that there was more to the project than a Unix executable. And slowly to those of us at Tlon, it became obvious what it was destined to become: a flagship client for an entire network, a tree branch rooting a world beneath clearnet, the first cell by which other clients might be born. Mitosis can be clumsy to watch; it can be nauseating to experience; it can be difficult to make out what will arrive where.
80+The same has occurred with Landscape. Previously Landscape was “_the_ interface to Urbit,” the proof that there was more to the project than a Unix executable. And slowly to those of us at Tlon, it became obvious what it was destined to become: a flagship client for an entire network, a tree branch rooting a world beneath clearnet, the first cell by which other clients might be born. Mitosis can be clumsy to watch; it can be nauseating to experience; it can be difficult to make out what will arrive where.
8181
8282But this is, after all, how a body forms.
content/blog/on-christopher-alexander.md+11−11
@@ -42,28 +42,28 @@ That depends on who you ask.
4242
4343**Galen (~ravmel-ropdyl)**
4444
45−>I suppose the main thing is that most designers tend to become fixated on the mechanics of what they&#39;re building. Most design theory is about how things are made, not what it&#39;s like to live inside of them or actually rely on them on a daily basis. Alexander is much more concerned with the first-person experience of inhabiting a place or a building. I guess his approach is just much more empathetic which means it&#39;s also more practical. He&#39;s concerned with _how people actually live_ and how their environment evolves alongside them.
45+> I suppose the main thing is that most designers tend to become fixated on the mechanics of what they&#39;re building. Most design theory is about how things are made, not what it&#39;s like to live inside of them or actually rely on them on a daily basis. Alexander is much more concerned with the first-person experience of inhabiting a place or a building. I guess his approach is just much more empathetic which means it&#39;s also more practical. He&#39;s concerned with _how people actually live_ and how their environment evolves alongside them.
4646>
47−>We live, work, and develop on Urbit. We&#39;re often the first people to notice bugs because we are the end users ourselves. Alexander makes the point that old buildings were responsive to feedback because the architect was also the inhabitant. This tight feedback means that the system as a whole is dynamic and alive. We want Urbit to be a house that you live in and make yours, because unlike all the other software you use, your Urbit is actually _yours_.
47+> We live, work, and develop on Urbit. We&#39;re often the first people to notice bugs because we are the end users ourselves. Alexander makes the point that old buildings were responsive to feedback because the architect was also the inhabitant. This tight feedback means that the system as a whole is dynamic and alive. We want Urbit to be a house that you live in and make yours, because unlike all the other software you use, your Urbit is actually _yours_.
4848
4949**Josh (~wolref-podlex)**
5050
51−>_The Nature of Order_ has had a big influence on my thinking. At first, the idea of all physical structures being alive sounded like something out of a new age bookstore. But not only do I think that Alexander justifies this claim; it started to make intuitive sense when I looked closely at my experience.
51+> _The Nature of Order_ has had a big influence on my thinking. At first, the idea of all physical structures being alive sounded like something out of a new age bookstore. But not only do I think that Alexander justifies this claim; it started to make intuitive sense when I looked closely at my experience.
5252>
53−>When I first read _The Nature of Order_ I was living in an industrial neighborhood of San Francisco—the scale of the buildings and streets felt inhuman and everything was made of metal, glass, and concrete. I chose to leave. I moved into a 100+ year-old flat and the difference was immediate and visceral. The space felt like it was designed from experience rather than _ex nihilo_. The apartment was meant to be lived in, surrounded by public spaces where strangers could safely spend time outdoors together.
53+> When I first read _The Nature of Order_ I was living in an industrial neighborhood of San Francisco—the scale of the buildings and streets felt inhuman and everything was made of metal, glass, and concrete. I chose to leave. I moved into a 100+ year-old flat and the difference was immediate and visceral. The space felt like it was designed from experience rather than _ex nihilo_. The apartment was meant to be lived in, surrounded by public spaces where strangers could safely spend time outdoors together.
5454>
55−>If physical objects can have the quality of &quot;aliveness&quot; so too can information objects. Alexander&#39;s book is alive. Many of the software projects I&#39;ve worked on have been cold fish. Keeping this quality in mind is an important part of my decision making. I want Urbit to be a living structure.
55+> If physical objects can have the quality of &quot;aliveness&quot; so too can information objects. Alexander&#39;s book is alive. Many of the software projects I&#39;ve worked on have been cold fish. Keeping this quality in mind is an important part of my decision making. I want Urbit to be a living structure.
5656
5757**Édouard (~fabled-faster)**
5858
59−>I enjoy telling people unfamiliar with Urbitand interface design with respect to Urbit, that the object of our work is essentially that of designing an environment &quot;like a piece of paper&quot;.
59+> I enjoy telling people unfamiliar with Urbitand interface design with respect to Urbit, that the object of our work is essentially that of designing an environment &quot;like a piece of paper&quot;.
6060>
61−>Consider how paper as a constrained environment is one that yet can bear nearly any visual expression imaginable—apart from containing drawings or human-made marks, paper can be used to display photographs, paper can be multiplexed to form lenticular holograms, paper can be folded into a crane, etc.
61+> Consider how paper as a constrained environment is one that yet can bear nearly any visual expression imaginable—apart from containing drawings or human-made marks, paper can be used to display photographs, paper can be multiplexed to form lenticular holograms, paper can be folded into a crane, etc.
6262>
63−>The &quot;sheet of paper and its resulting forms&quot; I manifest as a design ideal here is what Alexander might refer to as a &quot;semilattice&quot;. A mathematical term he co-opted to describe an ideal structural relationship between elements in a system, as opposed to a &quot;tree&quot;, which is a top-down structural system that forces elements into rigid categorical constraints. [In his own words](https://www.patternlanguage.com/archive/cityisnotatree.html):
63+> The &quot;sheet of paper and its resulting forms&quot; I manifest as a design ideal here is what Alexander might refer to as a &quot;semilattice&quot;. A mathematical term he co-opted to describe an ideal structural relationship between elements in a system, as opposed to a &quot;tree&quot;, which is a top-down structural system that forces elements into rigid categorical constraints. [In his own words](https://www.patternlanguage.com/archive/cityisnotatree.html):
6464>
65−>>_For the human mind, the tree is the easiest vehicle for complex thoughts. But the city is not, cannot and must not be a tree. The city is a receptacle for life. If the receptacle severs the overlap of the strands of life within it, because it is a tree, it will be like a bowl full of razor blades on edge, ready to cut up whatever is entrusted to it. In such a receptacle life will be cut to pieces. If we make cities which are trees, they will cut our life within to pieces._
65+> > _For the human mind, the tree is the easiest vehicle for complex thoughts. But the city is not, cannot and must not be a tree. The city is a receptacle for life. If the receptacle severs the overlap of the strands of life within it, because it is a tree, it will be like a bowl full of razor blades on edge, ready to cut up whatever is entrusted to it. In such a receptacle life will be cut to pieces. If we make cities which are trees, they will cut our life within to pieces._
6666>
67−>A city is a good ideal to maintain for the construction of a new internet and notion of personal computing, but I&#39;ve tended towards my own interpretation of a piece of paper as a semilattice-embodying object due to its accessibility and ability to be imagined by anyone, designer or not. Our object of design is that of a receptacle of life, of deep expression, of multiplexed possibilities. When I imagine an Urbit in the not-so-distant future, I imagine it as a _method_ (to contrast against those who pin software&#39;s expression down to &quot;tools&quot; or &quot;functions&quot;) by which I can become &quot;whole&quot; again in a digital context, in all my complexity.
67+> A city is a good ideal to maintain for the construction of a new internet and notion of personal computing, but I&#39;ve tended towards my own interpretation of a piece of paper as a semilattice-embodying object due to its accessibility and ability to be imagined by anyone, designer or not. Our object of design is that of a receptacle of life, of deep expression, of multiplexed possibilities. When I imagine an Urbit in the not-so-distant future, I imagine it as a _method_ (to contrast against those who pin software&#39;s expression down to &quot;tools&quot; or &quot;functions&quot;) by which I can become &quot;whole&quot; again in a digital context, in all my complexity.
6868
69−Christopher Alexander wanted to collapse the distinction between those who live in buildings and those who design them. Urbit wants to do the same thing with software—in order to not produce ugliness, we should live in what we build. Although we have personal computers now, all of our data is housed in enormous warehouses that make the industrial computers of the 1950s look tiny. What we think of as “our information” actually belongs to someone else and, more often than not, is weaponized against us. Alexander’s moral imperative can be taken and applied to our digital structures. We need to become close with our software again.
69+Christopher Alexander wanted to collapse the distinction between those who live in buildings and those who design them. Urbit wants to do the same thing with software—in order to not produce ugliness, we should live in what we build. Although we have personal computers now, all of our data is housed in enormous warehouses that make the industrial computers of the 1950s look tiny. What we think of as “our information” actually belongs to someone else and, more often than not, is weaponized against us. Alexander’s moral imperative can be taken and applied to our digital structures. We need to become close with our software again.
content/blog/rollups.md+17−17
@@ -15,14 +15,14 @@ gotten _expensive_. There are a large quantity of
1515complicated and clever techniques each with their own trade-offs
1616that are collectively referred to as "layer 2 solutions" (see [further
1717resources](#resources) for more information about these). This is in contrast to
18−the base computational layer of Ethereum called "layer 1", which is what constitutes most Ethereum usage and where [Urbit ID](@/docs/glossary/azimuth.md)’s smart contracts currently exist.
18+the base computational layer of Ethereum called "layer 1", which is what constitutes most Ethereum usage and where [Urbit ID](/docs/glossary/azimuth)’s smart contracts currently exist.
1919
20−Tlon has always covered gas costs for Urbit ID up to a set limit, and this was easy a couple of years ago when the cost of transactions required to get a [planet](@/docs/glossary/planet.md) up and running came out to less than a dollar. Unfortunately the ongoing Ethereum gas crisis, along with the rising price of Ethereum itself, has made this impossible. We’ve seen gas costs to set up a planet as high as several hundred US dollars at time of writing!
20+Tlon has always covered gas costs for Urbit ID up to a set limit, and this was easy a couple of years ago when the cost of transactions required to get a [planet](/docs/glossary/planet) up and running came out to less than a dollar. Unfortunately the ongoing Ethereum gas crisis, along with the rising price of Ethereum itself, has made this impossible. We’ve seen gas costs to set up a planet as high as several hundred US dollars at time of writing!
2121
2222In response to the gas crisis, Tlon has spent the last several months developing
2323a simple, in-house layer 2 solution which we anticipate will reduce typical gas costs by 65x or more.
2424
25−This post is primarily a short non-technical explainer of the end-user experience of our solution aimed at planet and [star](@/docs/glossary/star.md) owners and those in the market for one, as well as a status update on where we're at in development. At [the end](#technical) we give some minimal technical details and resources to help you dig deeper should you wish.
25+This post is primarily a short non-technical explainer of the end-user experience of our solution aimed at planet and [star](/docs/glossary/star) owners and those in the market for one, as well as a status update on where we're at in development. At [the end](#technical) we give some minimal technical details and resources to help you dig deeper should you wish.
2626This is also primarily aimed at those who currently self-host or plan to self-host their
2727urbit. For anybody utilizing a hosted service, this matter will all be handled
2828by your provider. There is a [separate section](#stars) addressed specifically at star owners, and another [section](#rollers) for those who wish to set up their urbit to accept and submit layer 2 transactions. We’d like to emphasize that this system is 100% opt-in—if you are satisfied with the current experience of Urbit ID, then nothing changes for you whatsoever.
@@ -37,7 +37,7 @@ of the back-end is approaching completion, and we are confident in a release bef
3737Our layer 2 solution, designed primarily by Tlon lead engineer `~wicdev-wisryt`,
3838is known as "naive rollups" and we will be using this term interchangeably with
3939"layer 2"—though it is important to note that there are many layer 2 solutions
40−utilized by projects other than Urbit. As we're avoiding technicality here, we’re focusing primarily on the advantages and disadvantages of utilizing our layer 2 solution, and how that affects the management of your [ship](@/docs/glossary/ship.md).
40+utilized by projects other than Urbit. As we're avoiding technicality here, we’re focusing primarily on the advantages and disadvantages of utilizing our layer 2 solution, and how that affects the management of your [ship](/docs/glossary/ship).
4141
4242Very briefly, a rollup is a way to combine many transactions into one, and we
4343are building infrastructure so that any Urbit ship may be utilized as a "roller". A
@@ -69,7 +69,7 @@ hours or even days for your transaction to clear. But the way we are saving on
6969gas is essentially by "bundling" or "rolling up" many transactions into one, and
7070submitting them as a single transaction. The more transactions in the rollup,
7171the better the savings. This bundling is not the only factor at play here
72−though—costs are reduced other ways, but this is a technical detail
72+though—costs are reduced other ways, but this is a technical detail
7373[discussed later in this post](#technical). It is possible to use layer 2 to submit single
7474transactions (and this will still save on gas costs!), so utilization of layer 2
7575should not incur any delay over layer 1 when utilized in this fashion.
@@ -82,7 +82,7 @@ view Urbit ID as "digital land", and a few hours to acquire land, or waiting for
8282your new personal computer to be delivered, is still lightning fast in
8383comparison to the real world. We also have ideas on methods that will allow you to get on the network before the transfer has been confirmed, but that is outside of the scope of this article.
8484
85−Our layer 2 preserves the main value proposition of Urbit ID, which is that your ship
85+Our layer 2 preserves the main value proposition of Urbit ID, which is that your ship
8686belongs to you forever, and that this is assured by very strong cryptographic methods and
8787game-theoretic arguments comparable to the ones that exist on layer 1. We
8888consider this principle to be uncompromisable, and maintaining ultimate
@@ -94,8 +94,8 @@ goes into greater detail in the [resources](#resources).
9494
9595The primary way one manages their Urbit ID, namely performing tasks such as
9696transferring ships, setting networking keys, or setting
97−[proxies](@/docs/glossary/proxies.md), is with a web interface called
98−[Bridge](@/docs/glossary/bridge.md) found at
97+[proxies](/docs/glossary/proxies), is with a web interface called
98+[Bridge](/docs/glossary/bridge) found at
9999[bridge.urbit.org](https://bridge.urbit.org). If you already own a planet,
100100you've probably used Bridge before - perhaps only a single time.
101101
@@ -109,7 +109,7 @@ choice of a roller to submit transactions to. Tlon's will be free for ordinary,
109109You could use your own ship for a fast single transaction for a little more gas. We expect that planet markets and stars may wish to set up their own rollers as well.
110110
111111Every planet has a sponsor star, which distributes [OTA
112−updates](@/docs/glossary/ota-updates.md) to their sponsored planets and assists with peer discovery. Both layer 1 and layer 2 planets will be able to be
112+updates](/docs/glossary/ota-updates) to their sponsored planets and assists with peer discovery. Both layer 1 and layer 2 planets will be able to be
113113sponsored by either layer 1 or layer 2 stars, meaning that nothing will change
114114in terms of how sponsorship works.
115115
@@ -123,9 +123,9 @@ And that's it! If you'd like to know how things will be changing for
123123### Changes to stars {#stars}
124124
125125Both planets and stars will be able to move to layer 2.
126−[Galaxies](@/docs/glossary/galaxy.md) must remain on layer 1 for technical
127−reasons, and [moons](@/docs/glossary/moon.md) and
128−[comets](@/docs/glossary/comet.md) never interacted with Ethereum anyways, so
126+[Galaxies](/docs/glossary/galaxy) must remain on layer 1 for technical
127+reasons, and [moons](/docs/glossary/moon) and
128+[comets](/docs/glossary/comet) never interacted with Ethereum anyways, so
129129they are completely out of the picture.
130130
131131Stars will be able to remain on layer 1 with no action required. For star owners
@@ -171,7 +171,7 @@ these factors to be included in the roller documentation.
171171
172172### Changes to Azimuth
173173
174−[Azimuth](@/docs/glossary/azimuth.md) is the set of Ethereum smart contracts
174+[Azimuth](/docs/glossary/azimuth) is the set of Ethereum smart contracts
175175governing Urbit ID. They will require a few changes to accommodate the new
176176system. Some of this has been implicit above, but to be clear, we will only be
177177making a couple minor alterations:
@@ -191,20 +191,20 @@ Changes to the state of Urbit ID on layer 1 works as follows:
191191 2. The EVM calculates the resulting state transition and checks its validity, then updates the state.
192192 3. Your urbit downloads the new state from an Ethereum node.
193193 4. Your urbit makes the final decision on whether the new state is valid.
194−
194+
195195In practice, the fourth step is never used in layer 1. The primary change to our
196196security model is that we are cutting out step 2 and beefing up step 4. Your
197197ship will now perform validation of the transactions posted to the Ethereum
198198blockchain, rather than the EVM.
199199
200−Since [Urbit OS](@/docs/glossary/arvo.md) is deterministic, and Hoon has some nice formal
201−properties, it turns out to be a great language for writing smart contracts. Thus we are effectively swapping the Ethereum smart contract with a “Hoon smart contract” run locally on your ship.
200+Since [Urbit OS](/docs/glossary/arvo) is deterministic, and Hoon has some nice formal
201+properties, it turns out to be a great language for writing smart contracts. Thus we are effectively swapping the Ethereum smart contract with a “Hoon smart contract” run locally on your ship.
202202
203203#### Further Resources {#resources}
204204
205205We want to keep this post brief and non-technical, so that's all we'll say about
206206it for now. To find out more, you have a few directions to go on. We held a
207−[Developer Call](@/events/2021-03-04-developer-call-scaling-azimuth.md) where
207+[Developer Call](/events/2021-03-04-developer-call-scaling-azimuth) where
208208`~wicdev-wisryt` outlines the design in much more technical detail, and also
209209explains why we decided to utilize our own design rather than other known layer
2102102 solutions such as [Optimistic
content/blog/urbit-grants-and-mid-2019-gifts.md+4−4
@@ -4,7 +4,8 @@ date = 2019-06-10
44description = "Announcing an upcoming Urbit grants program and star gifts for Mid-2019."
55aliases = ["/posts/essays/urbit-grants-and-mid-2019-gifts", "/posts/urbit-grants-and-mid-2019-gifts"]
66[taxonomies]
7−post_type = ["gifts"]
7+grant_type = ["Gift"]
8+grant_category = []
89[extra]
910author = "Galen Wolfe-Pauly + Alex Matzner"
1011ship = "~ravmel-ropdyl + ~mignyt-mogseb"
@@ -30,15 +31,14 @@ That is, our winners from the past nine months:
3031- John `~dirwex-dosrev` [@jfranklin9000](https://github.com/jfranklin9000)
3132- Assaf `~rophex-hashes` [@asssaf](https://github.com/asssaf)
3233
33−**Pyry** has been a [regular contributor](https://github.com/urbit/bridge/pulls?utf8=%E2%9C%93&q=author%3Apkova) to Bridge over the past few months, **John** has been consistently picking up changes [all](https://github.com/urbit/urbit/pulls?utf8=%E2%9C%93&q=author%3Ajfranklin9000) [over](https://github.com/urbit/arvo/pulls?utf8=%E2%9C%93&q=author%3Ajfranklin9000) [the place](https://github.com/urbit/docs/pulls?utf8=%E2%9C%93&q=author%3Ajfranklin9000), and **Assaf** found a [security issue](https://github.com/urbit/urbit-key-generation/issues/55) with our hierarchical wallet.
34+**Pyry** has been a [regular contributor](https://github.com/urbit/bridge/pulls?utf8=%E2%9C%93&q=author%3Apkova) to Bridge over the past few months, **John** has been consistently picking up changes [all](https://github.com/urbit/urbit/pulls?utf8=%E2%9C%93&q=author%3Ajfranklin9000) [over](https://github.com/urbit/arvo/pulls?utf8=%E2%9C%93&q=author%3Ajfranklin9000) [the place](https://github.com/urbit/docs/pulls?utf8=%E2%9C%93&q=author%3Ajfranklin9000), and **Assaf** found a [security issue](https://github.com/urbit/urbit-key-generation/issues/55) with our hierarchical wallet.
3435
3536Thanks to all of you for helping bring Urbit to life. We don’t make it nearly easy enough to contribute, but all of you clawed your way in and made the system better. Thank you!
3637
3738## Coming soon: Our new grant program
3839
39−As always, we much prefer to talk about working code as opposed to unfinished work – however:
40+As always, we much prefer to talk about working code as opposed to unfinished work – however:
4041
4142Making the process of rewarding contributors is something we’ve thought a lot about over the past few months. We’ve come up with a system that we like, and are hoping to put it up later this summer. It’s probably not perfect, but it’s a step in the right direction. We’ll be able to properly engage in a grant proposal process, post bounties as well as reward people directly with prizes.
4243
4344Please [subscribe to our newsletter](http://eepurl.com/b7x7hj) to make sure you receive future announcements.
44−
content/community/community-grants.md+1−1
@@ -7,7 +7,7 @@ hideprevious = "true"
77hidenext = "true"
88+++
99
10−Interested in getting your community on Urbit? We are currently accepting applications for select groups to get started on Urbit together using an [invite pool](@/using/id/creating-an-invite-pool.md).
10+Interested in getting your community on Urbit? We are currently accepting applications for select groups to get started on Urbit together using an [invite pool](/using/id/creating-an-invite-pool).
1111
1212To get started, fill out the application below. Any information you share will be held privately, and only for the purpose of consideration for the grant.
1313
content/community/governance.md+1−1
@@ -20,6 +20,6 @@ For off-chain process around proposals, as suggested by core developers, please
2020
2121The group of core developers manages Urbit’s [GitHub repository](https://github.com/urbit/), which controls Arvo, Urbit’s operating system. Changes and upgrades are decided upon by consensus.
2222
23−You can participate in the governance of the senate by acquiring a galaxy. If you would like to be involved with the governance of Arvo, check out our [developer guide](@/docs/development/develop.md) to learn how you can contribute to core development.
23+You can participate in the governance of the senate by acquiring a galaxy. If you would like to be involved with the governance of Arvo, check out our [developer guide](/docs/development/develop) to learn how you can contribute to core development.
2424
2525
content/docsdeleted−1

Submodule changed.

content/docs/_index.mdnew file+56
@@ -0,0 +1,56 @@
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/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.mdnew file+55
@@ -0,0 +1,55 @@
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/overview)
40+
41+Gall is the vane for controlling userspace apps.
42+
43+## [Iris](/docs/arvo/iris/iris-api)
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.
54+
55+
content/docs/arvo/ames/_index.mdnew file+7
@@ -0,0 +1,7 @@
1++++
2+title = "Ames"
3+weight = 10
4+sort_by = "weight"
5+template = "sections/docs/chapters.html"
6+insert_anchor_links = "right"
7++++
content/docs/arvo/ames/ames-api.mdnew file+292
@@ -0,0 +1,292 @@
1++++
2+title = "API Reference"
3+weight = 10
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+`%hear` handles raw packet receipt. This `task` only ever originates from Unix.
22+It does the initial processing of a packet, namely by passing the raw packet
23+information to `+decode-packet` which deserializes the packet and giving that data and the origin of the
24+packet to `+on-hear-packet`, which begins the transformation of the packet into
25+a new event in the form of a `+event-core`.
26+
27+There are multiple `+on-hear` arms in `ames.hoon`. Here we refer to
28+`on-hear:event-core`, as that is the one called by a `%hear` `task`. The other ones are used
29+primarily for ack and nack processing, or receiving message fragments.
30+
31+#### Accepts
32+
33+```hoon
34+[=lane =blob]
35+```
36+
37+`%hear` takes in a `blob`, which is essentially a large atom (around 1kB or less)
38+that is the raw data of the message, and a `lane`, which is the origin of the
39+message (typically an IP address).
40+
41+#### Returns
42+
43+`%hear` can trigger a number of possible returns. It can trigger the release of
44+zero or more additional packets via `%send` `gift`s. It may also trigger a `%boon`
45+or `%plea` `gift` (collectively referred to as a `%memo` within Ames) to a local vane in the case of a completed message.
46+
47+
48+### `%heed`
49+
50+A vane can pass Ames a `%heed` `task` to request Ames track a peer's
51+responsiveness. If our `%boon`s to it start backing up locally,
52+Ames will `give` a `%clog` back to the requesting vane containing the
53+unresponsive peer's Urbit address.
54+
55+Stop tracking a peer by sending Ames a
56+`%jilt` `task`.
57+
58+
59+#### Accepts
60+
61+```hoon
62+=ship
63+```
64+
65+The ship to be tracked.
66+
67+#### Returns
68+
69+If the `ship` is indeed being unresponsive, as measured by backed up `%boon`s,
70+Ames will `give` a `%clog` `gift` to the requesting vane containing the
71+unresponsive peer's urbit address.
72+
73+
74+### `%hole`
75+
76+`%hole` handles packet crash notification. `%hole` works much like `%hear`, in
77+that it passes an incoming raw packet to `+decode-packet` to be deserialized,
78+and then passes that data along with the source of the packet to
79+`+on-hear-packet` along with a `?` set to `%.n` denoting that there is something wrong with
80+the packet.
81+
82+#### Accepts
83+
84+```hoon
85+[=lane =blob]
86+```
87+`%hole` takes in a `blob`, which is essentially a large atom (around 1kB or less)
88+that is the raw data of the message, and a `lane`, which is the origin of the
89+message (typically an IP address).
90+
91+#### Returns
92+
93+Like `%hear`, `%hole` can trigger additional packets in the form of `%send`
94+`gift`s, and may also yield a `%boon` or `%plea` `gift` to a local vane.
95+
96+
97+### `%jilt`
98+
99+`%jilt` stops tracking a potentially unresponsive peer that was previously being
100+tracked as a result of the `%heed` `task`.
101+
102+There are two `+on-jilt` arms, this `task` utilizes `on-hear:event-core`.
103+
104+#### Accepts
105+
106+```hoon
107+=ship
108+```
109+
110+The `ship` we no longer wish to track.
111+
112+#### Returns
113+
114+This `task` returns no `gift`s.
115+
116+
117+### `%plea`
118+
119+`%plea` is the `task` used to instruct Ames to send a message. It extends the
120+`%pass`/`%give` semantics across the network. As such, it is the most
121+fundamental `task` in Ames and the primary reason for its existence.
122+
123+Ames also `pass`es a `%plea` `note` to another vane when it receives a message on a
124+"forward flow" from a peer, originally passed from one of the peer's vanes to the
125+peer's Ames.
126+
127+Ultimately `%plea` causes `%send` `gift`(s) to be sent to Unix, which tells
128+Unix to send packets. In terms of `%pass`/`%give` semantics, this is in
129+response to the `%born` `task`, which came along the Unix `duct`, rather than a
130+response to the `%plea`.
131+
132+#### Accepts
133+
134+```hoon
135+[=ship =plea]
136+```
137+
138+A `%plea` `task` takes in the `ship` the `plea` is addressed to, and a `$plea`,
139+which is
140+
141+```hoon
142+ +$ plea [vane=@tas =path payload=*]
143+```
144+Here, `vane` is the destination vane on the remote ship, `path` is the internal
145+route on the receiving ship, and `payload` is the semantic message content.
146+
147+#### Returns
148+
149+This `task` returns no `gift`s.
150+
151+## System and Lifecycle Tasks
152+
153+### `%born`
154+
155+Each time you start your Urbit, the Arvo kernel calls the `%born` task for Ames.
156+
157+#### Accepts
158+
159+`%born` takes no arguments.
160+
161+#### Returns
162+
163+In response to a `%born` `task`, Ames `%give`s Jael a `%turf` `gift`.
164+
165+The `duct` along which `%born` comes is Ames' only duct to Unix, so `%send`
166+`gift`s (which are instructions for Unix to send a packet) are also returned in
167+response to `%born`.
168+
169+
170+### `%crud`
171+
172+`%crud` is called whenever an error involving Ames occurs. It produces a crash
173+report in response.
174+
175+#### Accepts
176+
177+```hoon
178+=error
179+```
180+
181+A `$error` is a `[tag=@tas =tang]`.
182+
183+#### Returns
184+
185+Ames does not `give` a `gift` in response to a `%crud` `task`, but it does
186+`%pass` Dill a `%flog` `task` instructing it to print `error`.
187+
188+
189+## `%init`
190+
191+`%init` is called a single time during the very first boot process, immediately
192+after the [larval stage](/docs/arvo/overview#larval-stage-core)
193+is completed. This initializes the vane. Jael is initialized first, followed by
194+other vanes such as Ames.
195+
196+In response to receiving the `%init` `task`, Ames subscribes to the information
197+contained by Jael.
198+
199+#### Accepts
200+
201+```hoon
202+our=ship
203+```
204+
205+`%init` takes in the name of our ship, which is a `@p`.
206+
207+#### Returns
208+
209+```hoon
210+ =~ (emit duct %pass /turf %j %turf ~)
211+ (emit duct %pass /private-keys %j %private-keys ~)
212+```
213+
214+`%init` sends two moves that subscribe to `%turf` and `%private-keys` in Jael.
215+
216+
217+### `%sift`
218+
219+This `task` filters debug output by ship.
220+
221+#### Accepts
222+
223+```hoon
224+ships=(list ship)
225+```
226+
227+The list of ships for which debug output is desired.
228+
229+#### Returns
230+
231+This `task` returns no `gift`s.
232+
233+
234+### `%spew`
235+
236+Sets verbosity toggles on debug output. These toggles are as follows.
237+
238+* `%snd` - sending packets
239+* `%rcv` - receiving packets
240+* `%odd` - unusual events
241+* `%msg` - message-level events
242+* `%ges` - congestion control
243+* `%for` - packet forwarding
244+* `%rot` - routing attempts
245+
246+Each toggle is a flag set to `%.n` by default.
247+
248+#### Accepts
249+
250+```hoon
251+verbs=(list verb)
252+```
253+
254+`%spew` takes in a `list` of `verb`, which are verbosity flags for Ames.
255+
256+```hoon
257++$ verb ?(%snd %rcv %odd %msg %ges %for %rot)
258+```
259+
260+`%spew` flips each toggle given in `verbs`.
261+
262+#### Returns
263+
264+This `task` returns no `gift`s.
265+
266+
267+### `%vega`
268+
269+`%vega` is called whenever the kernel is updated. Ames currently does not do
270+anything in response to this.
271+
272+#### Accepts
273+
274+`%vega` takes no arguments.
275+
276+#### Returns
277+
278+This `task` returns no `gift`s.
279+
280+
281+### `%wegh`
282+
283+This `task` is a request to Ames to produce a memory usage report.
284+
285+#### Accepts
286+
287+This `task` has no arguments.
288+
289+#### Returns
290+
291+In response to this `task,` Ames `%give`s a `%mass` `gift` containing Ames'
292+current memory usage.
content/docs/arvo/ames/ames.mdnew file+423
@@ -0,0 +1,423 @@
1++++
2+title = "Overview"
3+weight = 1
4+template = "doc.html"
5+aliases = ["/docs/learn/arvo/ames/"]
6++++
7+Our networking protocol.
8+
9+Ames is the name of both our network and the vane that communicates
10+over it. When Unix receives a packet over the correct UDP port, it pipes
11+it straight into Ames for handling. Also, all packets sent over the
12+Ames network are sent by the Ames vane. Apps and vanes may use
13+Ames to directly send messages to other ships. In general, apps use
14+[Gall](/docs/userspace/gall/gall) and [Clay](/docs/arvo/clay/clay)
15+to communicate with other ships rather than using Ames
16+directly, but this isn't a requirement. Of course, Gall and Clay use
17+Ames behind the scenes to communicate across the network. Jael is the only other
18+vane to utilize Ames.
19+
20+Ames includes several significant components. Although the actual
21+crypto algorithms are defined in `zuse`, they're used extensively in
22+Ames for encrypting and decrypting packets. Congestion control and
23+routing is handled entirely in Ames. Finally, the actual Ames
24+protocol itself, including how to route incoming packets to the correct
25+vane or app, is defined in Ames.
26+
27+## Technical Overview
28+This section summarizes the design of Ames. Beyond this section are deeper
29+elaborations on the concepts presented here.
30+
31+Ames extends [Arvo's](/docs/arvo/overview) `%pass`/`%give` `move` semantics across the network.
32+
33+Ames receives packets as Arvo events and emits packets as Arvo
34+effects. The runtime is responsible for transferring the bytes in
35+an Ames packet across a physical network to another ship.
36+
37+The runtime tells Ames which physical address a packet came from,
38+represented as an opaque atom. Ames can emit a packet effect to
39+one of those opaque atoms or to the Urbit address of a galaxy
40+(root node), which the runtime is responsible for translating to a
41+physical address. One runtime implementation sends UDP packets
42+using IPv4 addresses for ships and DNS lookups for galaxies, but
43+other implementations may overlay over other kinds of networks.
44+
45+A local vane can pass Ames a `%plea` request message. Ames
46+transmits the message over the wire to the peer ship's Ames, which
47+passes the message to the destination vane.
48+
49+Once the peer has processed the `%plea` message, it sends a
50+message-acknowledgment packet over the wire back to the local
51+Ames. This "ack" can either be positive to indicate the request was
52+processed, or negative to indicate the request failed, in which
53+case it's called a "nack". (Don't confuse Ames nacks with TCP
54+nacks, which are a different concept).
55+
56+When the local Ames receives either a positive message-ack or a
57+combination of a nack and "naxplanation" (explained in more detail
58+below), it gives an `%done` `move` to the local vane that had
59+requested the original `%plea` message be sent.
60+
61+A local vane can give Ames zero or more `%boon` response messages in
62+response to a `%plea`, on the same duct that Ames used to pass the
63+`%plea` to the vane. Ames transmits a `%boon` over the wire to the
64+peer's Ames, which gives it to the destination vane on the same
65+duct the vane had used to pass the original `%plea` to Ames.
66+
67+`%boon` messages are acked automatically by the receiver Ames. They
68+cannot be nacked, and Ames only uses the ack internally, without
69+notifying the client vane that gave Ames the `%boon`.
70+
71+If the Arvo event that completed receipt of a `%boon` message
72+crashes, Ames instead sends the client vane a `%lost` message
73+indicating the `%boon` was missed.
74+
75+`%plea` messages can be nacked, in which case the peer will send
76+both a message-nack packet and a naxplanation message, which is
77+sent in a way that does not interfere with normal operation. The
78+naxplanation is sent as a full Ames message, instead of just a
79+packet, because the contained error information can be arbitrarily
80+large. A naxplanation can only give rise to a positive ack --
81+never ack an ack, and never nack a naxplanation.
82+
83+Ames guarantees a total ordering of messages within a "flow",
84+identified in other vanes by a duct and over the wire by a `bone`:
85+an opaque number. Each flow has a FIFO (first-in-first-out) queue of `%plea` requests
86+from the requesting ship to the responding ship and a FIFO queue
87+of `%boon`'s in the other direction.
88+
89+Message order across flows is not specified and may vary based on
90+network conditions.
91+
92+Ames guarantees that a message will only be delivered once to the
93+destination vane.
94+
95+Ames encrypts every message using symmetric-key encryption by
96+performing an elliptic curve Diffie-Hellman using our private key
97+and the public key of the peer. For ships in the Jael PKI
98+(public-key infrastructure), Ames looks up the peer's public key
99+from Jael. Comets (128-bit ephemeral addresses) are not
100+cryptographic assets and must self-attest over Ames by sending a
101+single self-signed packet containing their public key.
102+
103+When a peer suffers a continuity breach, Ames removes all
104+messaging state related to it. Ames does not guarantee that all
105+messages will be fully delivered to the now-stale peer. From
106+Ames's perspective, the newly restarted peer is a new ship.
107+Ames's guarantees are not maintained across a breach.
108+
109+A vane can pass Ames a `%heed` `$task` to request Ames track a peer's
110+responsiveness. If our `%boon`'s to it start backing up locally,
111+Ames will give a `%clog` back to the requesting vane containing the
112+unresponsive peer's urbit address. This interaction does not use
113+ducts as unique keys. Stop tracking a peer by sending Ames a
114+`%jilt` `$task`.
115+
116+Debug output can be adjusted using `%sift` and `%spew` `$task`'s.
117+
118+## Packets
119+
120+Ames datagram packets are handled as nouns internally by Arvo but as serial data
121+by Unix. In this section we describe how packets are formed, serialized, and relayed.
122+
123+### Packet format
124+
125+There is a 32-bit header followed by a variable width body.
126+
127+#### Header
128+
129+The 32-bit header is given by the following data, presented in order:
130+
131+ - 3 bits: Ames `protocol-version`,
132+ - 20 bits: a checksum as a truncated insecure hash of the body, done with
133+ [`+mug`](/docs/hoon/reference/stdlib/2e#mug),
134+ - 2 bits: the bit width of the sender address encoded as a 2-bit enum,
135+ - 2 bits: the bit width of the receiver address encoded as a 2-bit enum,
136+ - 1 bit: whether the packet is encrypted or not,
137+ - 4 bits: unused.
138+
139+ Every packet sent between ships is encrypted except for self-signed attestation packets from 128-bit comets.
140+
141+#### Body
142+
143+The body is of variable length and consists of three parts in this order:
144+
145+ - The `@p` of the sending ship,
146+ - The `@p` of the receiving ship,
147+ - The payload, which is the [`+jam`](/docs/hoon/reference/stdlib/2p#jam) (i.e. serialization) of the noun `[origin content]`.
148+
149+ `origin` is the IP and port of the original sender if the packet was proxied
150+ through a relay and null otherwise. `content` is a noun that is either an encrypted ack or an
151+ encrypted message fragment, unless it is a comet attestation packet in which
152+ case it is unencrypted. `content` is always 1kB in size or less.
153+
154+ The sender and receiver live outside of the jammed data section to simplify
155+ packet filtering for the interpreter.
156+
157+### Packeting
158+
159+When Ames has a message to be sent it must first determine how many packets are
160+required to send the message. To do this, it first `+jam`s the
161+message, producing an atom. Ames checks how large the atom is, and if it is
162+bigger than a kilobyte it will split it into packets whose payloads are 1 kB or
163+less. It then numbers each one - this is message 17, packet 12, this is message
164+17, packet 13, etc., so that when the receiver receives these packets it knows
165+which number they are. Finally it encrypts each individual packet and enqueues
166+them to be sent along their stated flow.
167+
168+Network packets aren't always received in order, so this numbering is important
169+for reconstruction, and also packets may get lost. So Ames does transmission
170+control (the TC in TCP) to solve this problem. It makes sure that all packets
171+eventually get through, and when the other side gets them it can put them in the
172+correct order. If Ames doesn't get an ack on a packet then it will resend it
173+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.
174+
175+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.
176+
177+
178+
179+### Acks and Nacks
180+
181+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
182+acks to maintain synchronization between two communicating parties. Nacks are 'negative
183+acknowledgments' and are used when something goes wrong.
184+
185+#### Acks
186+
187+Every message (i.e. a `%plea` or `%boon`) is split up by Ames into some number
188+of _fragments_ that are 1kB in size or less. The fragments are then encrypted
189+and encapsulated into
190+packets and sent along a flow. The message will be considered successfully
191+received once the sender has received the appropriate set of acks in response,
192+defined as follows.
193+
194+There are two types of acks: fragment acks and message acks. Acks are
195+not considered messages, and thus are not `%plea`s or `%boon`s. Given a message split into N
196+fragments, the sender of the message will expect N-1 fragment acks followed
197+by exactly one message ack (ignoring any duplicate packets, which are idempotent
198+from the perspective of the application). This is because the receiver
199+will send a fragment ack for the first N-1 packets it received, and what
200+would have been the final fragment ack will instead be a message ack.
201+
202+Acks are considered to be part of the flow in which that `%plea` or
203+`%boon` lives, as the packets containing their fragments and packets acking the
204+receipt of those packets are considered to be what makes up a given message.
205+Thus a message-level ack must be received before the next message on the flow
206+can begin. The full story is more complicated than this; see the section on
207+[flows](#flows).
208+
209+
210+#### Nacks
211+
212+A nack indicates a negative acknowledgement to a `%plea`, meaning that the
213+requested action was not performed.
214+
215+`%boon`s and naxplanations are never nacked.
216+Individual packets are also never nacked, only complete `%plea` messages are.
217+Whether a malformed packet causes a `%plea` to be nacked depends on its content.
218+In the case of an incorrect checksum or a failure to decrypt then Ames drops the
219+packet and it is as though it never happened. However, if the packet does
220+decrypt and has invalid ciphertext (i.e. something other than a jammed
221+`$shutpacket` data structure), then Ames will nack the whole `%plea` since that
222+indicates that the peer is misbehaving. Eventually Ames should also present a
223+warning to the user that the peer is untrustworthy.
224+
225+A nack will be accompanied by a naxplanation, which is a special type of`%boon`
226+that uses its own `bone` (see [flows](#flows)). Ames won't give the vane that requested the
227+initial `%plea` a nack until it also receives the naxplanation, which it will send to
228+the vane as a `%done` gift. Naxplanations may only be acked, never nacked.
229+Furthermore, naxplanations can only ever be sent as a rejection of a `%plea` -
230+the receiver will never both perform a `%plea` and return a naxplanation.
231+
232+#### (N)ack packets
233+
234+A fragment ack's contents (before encryption) are a pure function of the
235+following noun:
236+```hoon
237+[our-life her-life bone message-num fragment-num]
238+```
239+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.
240+
241+Each datum in this noun is an atom with the aura `@ud` or an aura that nests
242+under `@ud`.
243+
244+Here, `our-life` refers to the [`life`](/docs/glossary/breach), or revision
245+number, of the acking ship's networking keys, and `her-life` is the `life` of
246+the ack-receiving ship's networking keys. `bone` is an opaque number identifying
247+the flow. `message-num` denotes the number of the
248+message in the flow identified by `bone`. `fragment-num` denotes the number of
249+the fragment of the message identified by `message-num` that is being acked.
250+
251+A message (n)ack is a different kind of ack that is obtained by encrypting the
252+`+jam` of the following noun:
253+
254+```hoon
255+[our-life her-life bone message-num ok=? lag=@dr]
256+```
257+`ok` is a flag that is set to `%.y` for a message ack and `%.n` for a message
258+nack. In the future, `lag` will be used to
259+describe the time it took to process a message, but for now it is always zero.
260+
261+
262+### Flows
263+
264+Flows are asymmetric communication channels along which two ships send and
265+receive packets, and all Ames packets are part of some flow.
266+
267+To create a new flow, a ship sends a
268+`%plea` to another ship. Only the creator of the flow may send `%plea`s, and the
269+other party may only send `%boon`s. In this sense flows are asymmetric.
270+
271+The sequence of `%plea`s in a flow is totally ordered, though
272+the packets which make them up need not be. `%boon`s are totally ordered in the
273+same fashion, but there is not a coordinated ordering between `%plea`s and
274+`%boon`s in a given flow beyond the implicit one arising from the fact that a
275+`%boon` is always a response to a `%plea`. A `%plea` can give rise to zero, one,
276+or many `%boon`s.
277+
278+Inside of Ames, each flow has four sequential opaque `@ud`s
279+called bones that are unique to that flow. Thus the flow itself is often
280+referred to by its first bone. Each bone is a one-way street
281+for packets to travel along, so e.g. acks to packets making up a `%plea` are
282+sent along a different bone than the `%plea`.
283+
284+We give an example of such a partition. Let flow 12 be a flow between `~bacbel-tagfeg` and `~worwel-sipnum` with
285+`~bacbel-tagfeg` as the `%plea` sender. Then bones 12-15 are associated with the
286+flow, and the types of packets for each bone are:
287+
288+ - bone 12, `%plea`s and acks to `~worwel-sipnum`,
289+ - bone 13, `%boon`s and (n)acks to `~bacbel-tagfeg`,
290+ - bone 14, acks of naxplanations to `~worwel-sipnum`,
291+ - bone 15, naxplanations to `~bacbel-tagfeg`.
292+
293+Each bone is handled separately by congestion control, and this is one reason
294+for their segregation. For example, say a two-packet `%plea` is sent on bone 12,
295+with `~bacbel-tagfeg` requesting to join a group on `~worwel-sipnum`.
296+Then `~worwel-sipnum` can ack the first packet on bone 13, and then send a nack
297+on bone 13 as well. A nack by itself contains no information as to why the nack
298+happened. Then `~worwel-sipnum` can also send a naxplanation on bone 15 saying
299+to `~bacbel-tagfeg` that they cannot join the group, to which an ack is received
300+on bone 14.
301+
302+Another reason to separate bones is to avoid race conditions. If
303+`~worwel-sipnum` and `~bacbel-tagfeg` attempt to start a flow with each other at
304+the same time we do not wish there to be a conflict when they receive each
305+others' packets. Flipping the last bit of the bone based on whether a packet is
306+an ack or a message fragment allows for `~worwel-sipnum` to create flow 8 with
307+`~bacbel-tagfeg` without coming into conflict with the flow 8 `~bacbel-tagfeg`
308+created for `~worwel-sipnum`.
309+
310+`%plea`s and `%boon`s are handled on separate bones so that e.g. sending a large
311+`%boon` doesn't stop an additional `%plea` from being received. It is also
312+simply cleaner to make each bone one-way. Acks and nacks are very small packets
313+as well as integral to controlling the total orderings on `%plea`s and `%boon`s
314+and so they are included on these bones as well.
315+
316+Naxplanations can potentially be very large, as they often contain things like stack
317+traces or other crash reports. Thus it is undesirable to have them share a bone
318+with `%boon`s and create congestion there. So naxplanations have their own bone,
319+and so do acks to packets that make up a naxplanation, as well as the
320+message-level naxplanation ack.
321+
322+### Packet relaying
323+
324+Here we describes how the Ames network relays packets. We ignore all details
325+about UDP, which occurs at a lower layer than Ames.
326+
327+When a ship first contacts another ship, it may only know its `@p`, but an IP
328+address and port are necessary for peer-to-peer communication to occur.
329+Thus the initial correspondence between two ships, or additional correspondence
330+following a change in IP or port of one of the parties, will need to be relayed
331+by an intermediary that knows the IP and port of the receiving ship.
332+
333+For now packet relaying is handled entirely by galaxies. Every galaxy is
334+responsible for knowing the IP and port of every planet underneath it. In the
335+future, galaxies will only need to know the star sponsoring a planet, and stars
336+will be responsible for the final step of the relay.
337+
338+The following diagram summarizes the packet creation and forwarding process.
339+
340+<div style="text-align:center">
341+<img src="https://media.urbit.org/docs/arvo/datagram-long.png">
342+</div>
343+
344+We elaborate on the above diagram.
345+
346+A typical relay will look something like this: `~bacbel-tagfeb` wishes to
347+contact `~worwel-sipnum` but does not know the IP address and port at which
348+`~worwel-sipnum` resides. Both planets live under `~zod`, which knows both of
349+their IP and port numbers by virtue of being the galaxy that both live under.
350+
351+To prepare, `~bacbel-tagfeb` forms a Diffie-Hellman symmetric key with their own
352+private key and the public key of `~worwel-sipnum`, obtained via Jael. Then
353+`~bacbel-tagfeb` sends a packet addressed to `~worwel-sipnum` to `~zod`.
354+
355+The packet has the following format:
356+ - The standard Ames header described in [header](#header), where the checksum
357+ is the `+mug` of the body, and the sender and receiver ship types are `01`,
358+ denoting that the sender and receiver are planets. The remainder of the
359+ packet is the body.
360+ - The body of this packet will be the `@p` of the
361+sender `~bacbel-tagfeb`, followed by the `@p` of the receiver `~worwel-sipnum`,
362+followed by the payload.
363+ - The payload of this packet will be the `+jam` of `[origin content]`. `origin`
364+for this initial packet will be `~`, which implies that the packet is
365+originating from the sender. `content` is the `+jam` of the message, encrypted
366+using the Diffie-Hellman symmetric key that was previously computed.
367+
368+`~zod` receives the packet and reads the body. It sees that it is not the
369+intended recipient of the packet, and so gets ready to forward it to
370+`~worwel-sipnum`. First, it [`+cue`s](/docs/hoon/reference/stdlib/2p#cue)
371+(deserializes) the payload and changes the `origin` to the IP and port of
372+`~bacbel-tagfeb`. Then it `+jam`s `[origin content]` to form a new payload, and
373+`+mug`s that payload to get a new checksum. It replaces the old payload and
374+checksum with the new, and then sends the packet along to `~worwel-sipnum`.
375+
376+Once `~worwel-sipnum` processes the packet, it will know the IP and port of
377+`~bacbel-tagfeb` since `~zod` included it when it forwarded the packet. Thus
378+`~worwel-sipnum` will send an ack packet directly to `~bacbel-tagfeb`, unless a
379+NAT and/or firewall prevents a direct peer-to-peer connection, in which case
380+`~zod` will continue to relay packets. Absent these factors preventing a
381+peer-to-peer connection, communication between the two ships will now be direct
382+until one of them changes their IP address, port, or networking keys.
383+
384+
385+## The Serf and the King
386+
387+Urbit's functionality is split between the two binaries `urbit-worker` (sometimes
388+called the Serf) and `urbit-king` (sometimes called the King). This division of
389+labor is currently not well-documented outside of the [Vere documents](/docs/vere/), but we summarize it here.
390+
391+In short, the Serf is the Nock runtime and so keeps track of the current state
392+of Arvo as a Nock noun and updates the state by `%poke`ing it with nouns, and
393+then informs the King of the new state. The King manages snapshots of the Arvo
394+state and handles I/O with Unix, among other things. The Serf only ever talks to
395+the King, while the King talks with both the Serf and Unix.
396+
397+### Ames I/O submodule
398+
399+The King has several submodules, one of them being an Ames I/O submodule. This
400+submodule is responsible for wrapping outgoing Ames packets as UDP packets, and
401+unwrapping incoming UDP packets into Ames packets and forwarding them to the
402+worker. It also maintains an incoming packet queue.
403+
404+This division is summarized in the following diagram, describing how
405+`~bacbel-tagfeb` requests a subscription to the `recipes` notebook of
406+`~worwel-sipnum` in the Publish app.
407+
408+<div style="text-align:center">
409+<img src="https://media.urbit.org/docs/arvo/packet.png">
410+</div>
411+
412+Ames, as a part of Arvo, handles `+jam`ming, packetizing, encryption, and
413+forming Ames packets. Once it is ready to send an Ames packet, it `%give`s to
414+Unix a `%send` `gift` containing that packet. This will be a Nock noun
415+containing the `@tas` `%send` as well as the serialized packet.
416+
417+"Unix", in this case, is actually the King. The King receives the `%send`
418+instruction, wraps the packet contained within as a UDP packet, and immediately
419+hands it off the the Unix network interface to be sent.
420+
421+Now the receiving King is handed a UDP packet by Unix. The King removes the UDP
422+wrapper, `+jam`s the `lane` on which it heard the packet, and delivers the packet
423+to the Ames vane as an atom by copying the bytes it heard on the UDP port.
content/docs/arvo/ames/cryptography.mdnew file+145
@@ -0,0 +1,145 @@
1++++
2+title = "Cryptography"
3+weight = 5
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`, message number, and message fragment or ack (see
38+[Ames](@/docs/arvo/ames/ames.md) 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.md#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`, inside which the `$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.md#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.md#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.md#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.md#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/behn/_index.mdnew file+7
@@ -0,0 +1,7 @@
1++++
2+title = "Behn"
3+weight = 20
4+sort_by = "weight"
5+template = "sections/docs/chapters.html"
6+insert_anchor_links = "right"
7++++
content/docs/arvo/behn/behn-api.mdnew file+246
@@ -0,0 +1,246 @@
1++++
2+title = "API Reference"
3+weight = 10
4+template = "doc.html"
5++++
6+
7+In this document we describe the public interface for Behn. Namely, we describe
8+each `task` that Behn can be `pass`ed, and which `gift`(s) Behn can `give` in return.
9+
10+
11+## Tasks
12+
13+### `%born`
14+
15+Each time you start your Urbit, the Arvo kernel calls the `%born` task for Behn. When
16+called, Behn gets the current time from Unix and updates its list of timers
17+accordingly.
18+
19+#### Accepts
20+
21+```hoon
22+[~]
23+```
24+
25+#### Returns
26+
27+`%born` does not return a `gift`.
28+
29+
30+### `%crud`
31+
32+`%crud` is called whenever an error involving Behn occurs, such as trying to
33+`%wake` a program that has crashed.
34+
35+When called, it checks to see if the set of timers is empty. If so, it prints
36+an error report containing `error`, otherwise it passes the error to `+wake`.
37+
38+#### Accepts
39+
40+```hoon
41+[tag=@tas error=tang]
42+```
43+Here, `tag` is a `@tas` denoting the type of error, and `error` is an error message.
44+
45+#### Returns
46+
47+```hoon
48+[%wake %behn-crud-no-timer tag error]
49+```
50+
51+If the set of timers is nonempty when Behn is `%pass`ed a `%crud` `task`, Behn
52+`%give`s a `%wake` `card` containing the error to the next client in the set of timers.
53+
54+
55+#### Example
56+
57+The most common error that occurs is when Behn tries to `%wake` up a program that has crashed. When this happens
58+the entire event (i.e. sequence of `move`s) that led up to the `%wake` is thrown
59+away, and Vere then causes the kernel to `pass` Behn a `%crud` `task` containing
60+the stack trace.
61+
62+
63+### `%drip`
64+
65+`%drip` allows one to delay a `gift` until a timer set for `now` fires.
66+
67+A Client `%slip`s Behn a `%drip` task wrapping a `gift` to be `give`n to a Target.
68+This launches a sequence of `move`s as written here:
69+
70+```
71+Client -- %slip %drip --> Behn -- %pass %wait --> Behn -- %give %wake --> Behn -- %give %meta --> Target
72+```
73+Here the `%meta` `move` is a wrapper for the `%gift` inside of the initial `%drip` wrapper.
74+
75+`%drip` only handles `gift`s, and can only schedule `gift`s for as soon as
76+possible after the prescribed timer fires.
77+
78+
79+#### Accepts
80+
81+```hoon
82+mov=vase
83+```
84+
85+`%drip` takes in a `%give` `move` in a `vase`.
86+
87+#### Returns
88+
89+In response to a `%drip` `task`, Behn will `%pass` a `%wait` to itself, which
90+then triggers a `%wake` `gift` to itself, which then causes Behn to `%give` a `%meta` `gift` containing
91+the `gift` originally `%give`n to Behn when `%drip` was first called. That makes
92+Behn its own client for `%drip`.
93+
94+#### Example
95+
96+
97+Say an app (the Target) is subscribed to updates from Clay (the Client). If Clay `%give`s
98+updates to the app directly and the app crashes, this may cause Clay to crash as
99+well. If instead Clay `%pass`es Behn a `%drip` `task` wrapping the update
100+`gift`, Behn will set a timer for `now` that, when fired, will cause the update
101+`gift` to be given. If it causes a crash then it will have been in response to
102+the `%drip` move, thereby isolating Clay from the crash. Thus `%drip` acts as a sort of buffer against cascading
103+sequences of crashes.
104+
105+
106+
107+### `%huck`
108+
109+Immediately gives back an input move.
110+
111+#### Accepts
112+
113+```hoon
114+mov=vase
115+```
116+
117+Behn takes in a `move` contained in a `vase`.
118+
119+#### Returns
120+
121+```hoon
122+[%give %meta mov]
123+```
124+
125+Behn returns the input `move` as a `%meta` `gift`.
126+
127+
128+
129+### `%rest`
130+
131+Cancels a timer that was previously set.
132+
133+Behn takes in a `@da` and cancels the timer at that time if it exists, then
134+adjusts the next wakeup call from Unix if necessary.
135+
136+#### Task
137+
138+```hoon
139+@da
140+```
141+
142+
143+#### Gift
144+
145+This `task` returns no `gift`s.
146+
147+
148+
149+### `%trim`
150+
151+This `task` is sent by the interpreter in order to free up memory.
152+ This `task` is empty for Behn, since it is not a good idea to forget your timers.
153+
154+#### Accepts
155+
156+This `task` has no arguments.
157+
158+#### Returns
159+
160+This task returns nothing.
161+
162+### `%vega`
163+
164+This `task` informs the vane that the kernel has been upgraded. Behn does not do
165+anything in response to this.
166+
167+#### Accepts
168+
169+This `task` has no arguments.
170+
171+#### Returns
172+
173+This `task` returns nothing.
174+
175+
176+
177+### `%wait`
178+
179+This `task` takes in a `@da` which Behn then adds to `timers.state`, the list of timers.
180+
181+#### Accepts
182+
183+```hoon
184+@da
185+```
186+
187+#### Returns
188+
189+This `task` returns a `%wake` `gift` once the timer has fired.
190+
191+
192+### `%wake`
193+
194+This `task` is sent by the kernel when the Unix timer tells the kernel that it
195+is time for Behn to wake up. This is often caused by a `%doze` `gift` that
196+Behn originally sent to the kernel that is then forwarded to Unix, which is
197+where the real timekeeping occurs.
198+
199+Upon receiving this `task`, Behn processes the elapsed timer and then sets
200+`:next-wake`.
201+
202+`%wake` is also a `gift` that Behn can `%give`. This is done to inform other
203+vanes or apps that a timer has expired, and may include an error message.
204+
205+#### Accepts
206+
207+As a `task`, `%wake` takes in `~`.
208+
209+As a `gift`, `%wake` may include an error message.
210+
211+```hoon
212+error=(unit tang)
213+```
214+
215+
216+#### Returns
217+
218+In response to receiving this `task`, Behn may `%give` a `%doze` `gift`
219+containing the `@da` of the next timer to elapse. Behn may also `%give` a
220+`%wake` `gift` to itself.
221+
222+
223+
224+### `%wegh`
225+
226+This `task` asks Behn to product a memory usage report.
227+
228+#### Accepts
229+
230+This `task` has no arguments.
231+
232+#### Returns
233+
234+```hoon
235+:_ state :_ ~
236+ :^ duct %give %mass
237+ :+ %behn %|
238+ :~ timers+&+timers.state
239+ dot+&+state
240+```
241+
242+When Behn is `%pass`ed this `task`, it will `%give` a `%mass` `gift` in response
243+containing Behn's current memory usage.
244+
245+
246+
content/docs/arvo/behn/behn.mdnew file+21
@@ -0,0 +1,21 @@
1++++
2+title = "Overview"
3+weight = 1
4+template = "doc.html"
5++++
6+Our simple timer.
7+
8+It allows vanes and applications to set and timer events, which are
9+managed in a simple priority queue. `%behn` produces effects to start
10+the unix timer, and when the requested `%behn` passes, unix sends wake
11+events to `%behn`, which time routes back to original sender. We don't
12+guarantee that a timer event will happen at exactly the `%behn` it was
13+set for, or even that it'll be particularly close. A timer event is a
14+request to not be woken until after the given time.
15+
16+`%eyre` uses `%behn` for timing out sessions, and `%clay` uses `%behn`
17+for keeping track of time-specified file requests. `%ames` should
18+probably use `%behn` to keep track of things like network timeouts and
19+retry timing, but it currently uses its own alarm system.
20+
21+This article is a stub. For more information, see either `behn.hoon` or [Lesson 2.6 - Behn](/docs/hoon/hoon-school/behn) of the Hoon tutorial.
content/docs/arvo/clay/_index.mdnew file+36
@@ -0,0 +1,36 @@
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.mdnew file+254
@@ -0,0 +1,254 @@
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) operating system,
8+which is the [core](/docs/glossary/core/) of an urbit. The architecture of Clay is
9+intrinsically connected with Arvo, but for this section we assume no knowledge of
10+either Arvo or Urbit. We will point out only those features of
11+Arvo that are necessary for an understanding of Clay, and we will
12+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
16+and effects. The state of Arvo is simply a pure function of its event
17+log. None of the effects from an event are emitted until the
18+event is entered in the log and persisted, either to disk or
19+another trusted source of persistence, such as a Kafka cluster.
20+Consequently, Arvo is a single-level store: everything in its
21+state is persistent.
22+
23+In a more traditional OS, everything in RAM can be erased at any
24+time by power failure, and is always erased on reboot. Thus, a
25+primary purpose of a filesystem is to ensure files persist across
26+power failures and reboots. In Arvo, both power failures and
27+reboots are special cases of suspending computation, which is
28+done safely since our event log is already persistent. Therefore,
29+Clay is not needed in Arvo for persistence. Why, then, do we have a
30+filesystem? There are two answers to this question.
31+
32+First, Clay provides a filesystem tree, which is a convenient
33+user interface for some applications. Unix has the useful concept
34+of virtual filesystems, which are used for everything from direct
35+access to devices, to random number generators, to the /proc
36+tree. It is easy and intuitive to read from and write to a
37+filesystem tree.
38+
39+Second, Clay has a distributed revision-control system baked into
40+it. Traditional filesystems are not revision controlled, so
41+userspace software -- such as git -- is written on top of them to
42+do so. Clay natively provides the same functionality as modern
43+DVCSes, and more.
44+
45+Clay has two other unique properties that we'll cover later on:
46+it supports typed data and is referentially transparent.
47+
48+### Revision Control
49+
50+Every urbit has one or more `desk`s, which are independently
51+revision-controlled branches. Each `desk` contains its own `mark`
52+definitions, apps, and so forth.
53+
54+Traditionally, an urbit has at least a `%home` `desk` and `%kids` `desk`. The
55+`%home` `desk` has all the system software from the distribution, along with your
56+personal files. The `%home` `desk` is a fork of the `%kids` desk of whichever ship
57+you download [OTAs](/docs/glossary/ota-updates) from - typically your sponsor,
58+but theoretically may be any ship. You will also find references to a `%base`
59+`desk` - which is not a real `desk`, rather it just a hash associated to the
60+`desk` from which your `%home` `desk` was forked.
61+
62+A `desk` is a series of numbered commits, the most recent of which
63+represents the current state of the `desk`. A commit is composed of
64+(1) an absolute time when it was created, (2) a list of zero or
65+more parents, and (3) a map from paths to data.
66+
67+Most commits have exactly one parent, but the initial commit on a
68+`desk` may have zero parents, and merge commits have more than one
69+parent.
70+
71+The non-metadata is stored as a `map` of `path`s to data. It's
72+worth noting that no constraints are put on this `map`, so, for
73+example, both `/a/b` and `/a/b/c` could have data. This is impossible
74+in a traditional Unix filesystem since it means that `/a/b` is both
75+a file and a directory. Conventionally, the final element in the
76+path is its `mark` -- much like a filename extension in Unix. Thus,
77+`/doc/readme.md` in Unix is stored as `/doc/readme/md` in urbit.
78+
79+The data is not stored directly in the `map`; rather, a hash of the
80+data is stored, and we maintain a master blob store. Thus, if the
81+same data is referred to in multiple commits (as, for example,
82+when a file doesn't change between commits), only the hash is
83+duplicated.
84+
85+In the master blob store, we either store the data directly, or
86+else we store a diff against another blob. The hash is dependent
87+only on the data within and not on whether or not it's stored
88+directly, so we may on occasion rearrange the contents of the
89+blob store for performance reasons.
90+
91+Recall that a `desk` is a series of numbered commits. Not every
92+commit in a `desk` must be numbered. For example, if the base `desk`
93+has had 50 commits since home was forked from it, then a merge
94+from base to home will only add a single revision number to home,
95+although the full commit history will be accessible by traversing
96+the parentage of the individual commits.
97+
98+We do guarantee that the first commit is numbered 1, commits are
99+numbered consecutively after that (i.e. there are no "holes"),
100+the topmost commit is always numbered, and every numbered commit
101+is an ancestor of every later numbered commit.
102+
103+There are three ways to refer to particular commits in the
104+revision history. Firstly, one can use the revision number.
105+Secondly, one can use any absolute time between the one numbered
106+commit and the next (inclusive of the first, exclusive of the
107+second). Thirdly, every `desk` has a `map` of labels to revision
108+numbers. These labels may be used to refer to specific commits.
109+
110+Additionally, Clay is a global filesystem, so data on other urbits
111+is easily accessible the same way as data on our local urbit. In
112+general, the path to a particular revision of a `desk` is
113+`/~urbit-name/desk-name/revision`. Thus, to get `/try/readme/md`
114+from revision 5 of the home `desk` on `~sampel-sipnym`, we refer to
115+`/~sampel-sipnym/home/5/try/readme/md`. Clay's namespace is thus
116+global and referentially transparent.
117+
118+### A Typed Filesystem
119+
120+Since Clay is a general filesystem for storing data of arbitrary
121+types, in order to revision control correctly it needs to be
122+aware of types all the way through. Traditional revision control
123+does an excellent job of handling source code, so for source code
124+we act very similar to traditional revision control. The
125+challenge is to handle other data similarly well.
126+
127+For example, modern VCSs generally support "binary files", which
128+are files for which the standard textual diffing, patching, and
129+merging algorithms are not helpful. A "diff" of two binary files
130+is just a pair of the files, "patching" this diff is just
131+replacing the old file with the new one, and "merging"
132+non-identical diffs is always a conflict, which can't even be
133+helpfully annotated. Without knowing anything about the structure
134+of a blob of data, this is the best we can do.
135+
136+Often, though, "binary" files have some internal structure, and
137+it is possible to create diff, patch, and merge algorithms that
138+take advantage of this structure. An image may be the result of a
139+base image with some set of operations applied. With algorithms
140+aware of this set of operations, not only can revision control
141+software save space by not having to save every revision of the
142+image individually, these transformations can be made on parallel
143+branches and merged at will.
144+
145+Suppose Alice is tasked with touching up a picture, improving the
146+color balance, adjusting the contrast, and so forth, while Bob
147+has the job of cropping the picture to fit where it's needed and
148+adding textual overlay. Without type-aware revision control,
149+these changes must be made serially, requiring Alice and Bob to
150+explicitly coordinate their efforts. With type-aware revision
151+control, these operations may be performed in parallel, and then
152+the two changesets can be merged programmatically.
153+
154+Of course, even some kinds of text files may be better served by
155+diff, patch, and merge algorithms aware of the structure of the
156+files. Consider a file containing a pretty-printed JSON object.
157+Small changes in the JSON object may result in rather significant
158+changes in how the object is pretty-printed (for example, by
159+addding an indentation level, splitting a single line into
160+multiple lines).
161+
162+A text file wrapped at 80 columns also reacts suboptimally with
163+unadorned Hunt-McIlroy diffs. A single word inserted in a
164+paragraph may push the final word or two of the line onto the
165+next line, and the entire rest of the paragraph may be flagged as
166+a change. Two diffs consisting of a single added word to
167+different sentences may be flagged as a conflict. In general,
168+prose should be diffed by sentence, not by line.
169+
170+As far as we are aware, Clay is the first generalized,
171+type-aware revision control system. We'll go into the workings
172+of this system in some detail.
173+
174+### Marks
175+
176+Central to a typed filesystem is the idea of types. In Clay, we
177+call these `mark`s. A `mark` is a file that defines a type,
178+conversion routines to and from the `mark`, and diff, patch, and
179+merge routines.
180+
181+For example, a `%txt` mark may be a list of lines of text, and it
182+may include conversions to `%mime` to allow it to be serialized
183+and sent to a browser or to the Unix filesystem. It will also
184+include Hunt-McIlroy diff, patch, and merge algorithms.
185+
186+A `%json` `mark` would be defined as a JSON object in the code, and
187+it would have a parser to convert from `%txt` and a printer to
188+convert back to `%txt`. The diff, patch, and merge algorithms are
189+fairly straightforward for JSON, though they're very different
190+from the text ones.
191+
192+More formally, a `mark` is a core with three [arms](/docs/glossary/arm/): `+grab`,
193+`+grow`, and `+grad`. In `+grab` is a series of functions to
194+convert from other `mark`s to the given `mark`. In `+grow` is a
195+series of functions to convert from the given `mark` to other
196+`mark`s. In `+grad` is `+diff`, `+pact`, `+join`, and `+mash`, and
197+`+form`.
198+
199+The types are as follows, in an informal pseudocode:
200+
201+```
202+ ++ grab:
203+ ++ mime: <mime> -> <mark-type>
204+ ++ txt: <txt> -> <mark-type>
205+ ...
206+ ++ grow:
207+ ++ mime: <mark-type> -> <mime>
208+ ++ txt: <mark-type> -> <txt>
209+ ...
210+ ++ grad
211+ ++ form: <mark-type>
212+ ++ diff: (<mark-type>, <mark-type>) -> <diff-type>
213+ ++ pact: (<mark-type>, <diff-type>) -> <mark-type>
214+ ++ join: (<diff-type>, <diff-type>) -> <diff-type> or NULL
215+ ++ mash: (<diff-type>, <diff-type>) -> <diff-type>
216+```
217+
218+These types are basically what you would expect. Not every `mark`
219+has each of these functions defined -- all of them are optional
220+in the general case.
221+
222+In general, for a particular `mark`, the `+grab` and `+grow` entries
223+(if they exist) should be inverses of each other.
224+
225+In `+grad`, `+diff` takes two instances of a `mark` and produces a diff of them
226+whose `mark` is given by `+form`. `+pact` takes an instance of a `mark` and
227+patches it with the given diff. `+join` takes two diffs and attempts to merge
228+them into a single diff. If there are conflicts, it produces null. `+mash` takes
229+two diffs and forces a merge, annotating any conflicts.
230+
231+In general, if `+diff` called with A and B produces diff D, then
232+`+pact` called with A and D should produce B. Also, if `+join`
233+of two diffs does not produce null, then `+mash` of the same
234+diffs should produce the same result.
235+
236+Alternately, instead of `+diff`, `+pact`, `+join`, and
237+`+mash`, a `mark` can provide the same functionality by defining
238+`+grad` to be the name of another `mark` to which we wish to
239+delegate the revision control responsibilities. Then, before
240+running any of those functions, Clay will convert to the other
241+`mark`, and convert back afterward. For example, the `%hoon` `mark`
242+is revision-controlled in the same way as `%txt`, so its `+grad`
243+is simply `++ grad %txt`. Of course, `+txt` must be defined in
244+`+grow` and `+grab` as well.
245+
246+Every file in Clay has a `mark`, and that `mark` must have a
247+fully-functioning `+grad`. `Mark`s are used for more than just
248+Clay, and other `mark`s don't need a `+grad`, but if a piece of
249+data is to be saved to Clay, we must know how to revision-control
250+it.
251+
252+Additionally, if a file is to be synced out to Unix, then it must
253+have conversion routines to and from the `%mime` `mark`.
254+
content/docs/arvo/clay/clay.mdnew file+58
@@ -0,0 +1,58 @@
1++++
2+title = "Overview"
3+weight = 1
4+template = "doc.html"
5+aliases = ["/docs/learn/arvo/clay/"]
6++++
7+
8+
9+Our filesystem.
10+
11+`%clay` is version-controlled, referentially-transparent, and global.
12+While this filesystem is stored in `%clay`, it is mirrored to Unix for
13+convenience. Unix tells `%clay`s whenever a file changes in the Unix
14+copy of the filesystem so that the change may be applied. `%clay` tells
15+unix whenever an app or vane changes the filesystem so that the change
16+can be effected in Unix. Apps and vanes may use `%clay` to write to the
17+filesystem, query it, and subscribe to changes in it. Ford and gall use
18+`%clay` to serve up apps and web pages.
19+
20+`%clay` includes three components. First is the filesystem/version
21+control algorithms, which are mostly defined in `++ze` and `++zu` in
22+zuse. Second is the write, query, and subscription logic. Finally, there
23+is the logic for communicating requests to, and receiving requests from,
24+foreign ships.
25+
26+### User documentation
27+
28+[Filesystem](/using/os/filesystem)
29+
30+How to interact with the Clay filesystem via Dojo. This includes basics such as
31+mounting to Unix, changing directory, merging, and listing files.
32+
33+### Developer Documentation
34+
35+[Architecture](/docs/arvo/clay/architecture)
36+
37+A conceptual overview of how Clay was designed.
38+
39+[Using Clay](/docs/arvo/clay/using)
40+
41+A quick overview of how the most common tasks involving Clay are performed:
42+reading and subscribing, syncing to Unix, and merging.
43+
44+[Data Types](/docs/arvo/clay/data-types)
45+
46+Explanations of the many data types found throughout Clay.
47+
48+[Scry Reference](/docs/arvo/clay/scry)
49+
50+Reference for Clay's various scry endpoints.
51+
52+[API Reference](/docs/arvo/clay/tasks)
53+
54+Details of the various `task`s you can use to interact with Clay.
55+
56+[Examples](/docs/arvo/clay/examples)
57+
58+Example usage of the various Clay `task`s.
content/docs/arvo/clay/data-types.mdnew file+688
@@ -0,0 +1,688 @@
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+
72+#### `$room`, filesystem per domestic ship
73+
74+```hoon
75++$ room :: fs per ship
76+ $: hun=duct :: terminal duct
77+ dos=(map desk dojo) :: native desk
78+ == ::
79+```
80+
81+This is the representation of the filesystem of a ship on our pier.
82+
83+`hun` is the duct we use to send messages to [Dill](/docs/arvo/dill/dill) to
84+display notifications of filesystem changes. Only `%note` `%gift`s should be
85+produced along this `duct`. This is set by the `%init` `move`.
86+
87+`dos` is a well-known operating system released in 1981. It is also the
88+set of `desk`s on this ship, mapped to their `desk` state.
89+
90+#### `$desk`, filesystem branch
91+
92+```hoon
93++$ desk @tas
94+```
95+
96+This is the name of a branch of the filesystem. The default `desk`s are `%home`
97+and `%kids`. More may be created by simply referencing them. `desk`s have
98+independent histories and states, and they may be
99+[merged](/docs/arvo/clay/using#merging) into each other.
100+
101+### `$dojo`, domestic desk state
102+
103+```hoon
104++$ dojo
105+ $: qyx=cult :: subscribers
106+ dom=dome :: desk state
107+ per=regs :: read perms per path
108+ pew=regs :: write perms per path
109+ ==
110+```
111+
112+This is the all the data that is specific to a particular `desk` on a domestic
113+ship. `qyx` is the set of subscribers to this `desk`, and `dom` is the data in
114+the `desk`. `regs` are `(map path rule)`, and so `per` is a `map` of read
115+permissions by `path` and `pew` is a `map` of write permissions by `path`.
116+
117+#### `$cult`, subscriptions
118+
119+```hoon
120++$ cult (jug wove duct)
121+```
122+
123+`cult`s keep track of subscribers. `wove`s are associated to requests, and each
124+`wove` is mapped to a set of `duct`s associated to subscribers who should be
125+notified when the request is filled/updated.
126+
127+#### `$rave:clay`, general subscription request
128+
129+```hoon
130+ +$ rave :: general request
131+ $% [%sing =mood] :: single request
132+ [%next =mood] :: await next version
133+ [%mult =mool] :: next version of any
134+ [%many track=? =moat] :: track range
135+ == ::
136+```
137+
138+This represents a subscription request for a `desk`.
139+
140+A `%sing` request asks for data at single revision.
141+
142+A `%next` request asks to be notified the next time there’s a change to the
143+specified file.
144+
145+A `%mult` request asks to be notified the next time there's a change to a
146+specified set of files.
147+
148+A `%many` request asks to be notified on every change in a `desk` for a range of changes (including into the future).
149+
150+### `$rove`, stored general subscription request
151+
152+```hoon
153+ +$ rove :: stored request
154+ $% [%sing =mood] :: single request
155+ [%next =mood aeon=(unit aeon) =cach] :: next version of one
156+ $: %mult :: next version of any
157+ =mool :: original request
158+ aeon=(unit aeon) :: checking for change
159+ old-cach=(map [=care =path] cach) :: old version
160+ new-cach=(map [=care =path] cach) :: new version
161+ == ::
162+ [%many track=? =moat lobes=(map path lobe)] :: change range
163+ == ::
164+```
165+
166+Like a `rave` but with provisions to store current versions for `%next` and `%many`.
167+Generally used when we store a request in our state somewhere. This is so that
168+we can determine whether new versions actually affect the path we're subscribed to.
169+
170+
171+#### `$mood:clay`, single subscription request
172+
173+```hoon
174+ +$ mood [=care =case =path] :: request in desk
175+```
176+
177+This represents a request for data related to the state of the `desk` at a
178+particular commit, specfied by `case`. `care` specifies what kind of information
179+is desired, and `path` specifies the path we are requesting.
180+
181+#### `$moat:clay`, range subscription request
182+
183+```hoon
184+ +$ moat [from=case to=case =path] :: change range
185+```
186+
187+This represents a request for all changes between `from` and `to` on `path`. You
188+will be notified when a change is made to the node referenced by the `path` or to
189+any of its children.
190+
191+### `$care:clay`, Clay submode
192+
193+```hoon
194+ +$ care ?(%a %b %c %d %e %f %p %r %s %t %u %v %w %x %y %z) :: clay submode
195+```
196+
197+
198+This specifies what type of information is requested in a subscription
199+or a scry.
200+
201+`%a` build a Hoon file at a `path`.
202+
203+`%b` build a dynamically typed `mark` by name (a `$dais` mark-interface core).
204+
205+`%c` build a dynamically typed `mark` conversion gate (a `$tube`) by "from" and
206+"to" `mark` names.
207+
208+`%d` returns a `(set desk)` of the `desk`s that exist on your ship.
209+
210+`%e` builds a statically typed `mark` by name (a `$nave` mark-interface core).
211+
212+`%f` builds a statically typed mark converstion gate.
213+
214+`%p` produces the permissions for a directory, returned as a `[dict:clay dict:clay]`.
215+
216+`%r` requests the file in the same fashion as `%x`, but wraps the result in a `vase`.
217+
218+`%s` has miscellaneous debug endpoints.
219+
220+`%t` produces a `(list path)` of descendent `path`s for a directory within a `yaki`.
221+
222+`%u` produces a `?` depending on whether or not the specified file exists. It
223+does not check any of its children.
224+
225+`%v` requests the entire `dome` for a specified `desk` at a particular `aeon`.
226+When used on a foreign `desk`, this get us up-to-date to the requested version.
227+
228+`%w` requests the revision number and date of the specified path, returned as a `cass:clay`.
229+
230+`%x` requests the file at a specified path at the specified commit, returned as
231+an `@`. If there is no node at that path or if the node has no contents (that
232+is, if `fil:ankh` is null), then this crashes.
233+
234+`%y` requests an `arch` of the specfied commit at the specified path. It will
235+return the bunt of an `arch` if the file or directory is not found.
236+
237+`%z` requests a recursive hash of a node and all its children, returned as a `@uxI`.
238+
239+#### `$ankh`, filesystem node
240+
241+```hoon
242++$ ankh :: expanded node
243+ $~ [~ ~]
244+ $: fil=(unit [p=lobe q=cage]) :: file
245+ dir=(map @ta ankh) :: folders
246+ == ::
247+```
248+
249+This is a recursive filesystem node type that can describe a whole tree of
250+folders and files, with subtrees organized by path prefix. In Earth filesystems,
251+a node is a file xor a directory. On Mars, we're inclusive, so a node is a file
252+ior a directory.
253+
254+`fil` is the contents of this file, if any. `p.fil` is a hash of the
255+contents while `q.fil` is the data itself.
256+
257+`dir` is the set of children of this node. In the case of a pure file,
258+this is empty. The keys are the names of the children and the values
259+are, recursively, the nodes themselves.
260+
261+
262+### `$arch`, shallow filesystem node
263+
264+```hoon
265++$ arch (axil @uvI)
266+++ axil
267+ |$ [item]
268+ [fil=(unit item) dir=(map @ta ~)]
269+```
270+
271+An `arch` is a lightweight version of an `ankh` that only contains the hash
272+of the associated file and a `map` of child directories, but not the children of
273+those directories.
274+
275+The child directories are given by a `map` to null rather than a `set` so that the
276+ordering of the `map` will be the same as it is for an `axal`, allowing
277+efficient conversion for when the heavier node is needed.
278+```hoon
279+++ axal
280+ |$ [item]
281+ [fil=(unit item) dir=(map @ta $)]
282+```
283+
284+#### `$case`, specifying a commit
285+
286+```hoon
287++$ case
288+ $% :: %da: date
289+ :: %tas: label
290+ :: %ud: sequence
291+ ::
292+ [%da p=@da]
293+ [%tas p=@tas]
294+ [%ud p=@ud]
295+ ==
296+```
297+
298+A commit can be referred to in three ways: `%da` refers to the commit
299+that was at the head on date `p`, `%tas` refers to the commit labeled
300+`p`, and `%ud` refers to the commit numbered `p`. Note that since these
301+all can be reduced down to a `%ud`, only numbered commits may be
302+referenced with a `++case:clay`.
303+
304+#### `$dome`, desk data
305+
306+```hoon
307++$ dome
308+ $: ank=ankh :: state
309+ let=aeon :: top id
310+ hit=(map aeon tako) :: versions by id
311+ lab=(map @tas aeon) :: labels
312+ mim=(map path mime) :: mime cache
313+ fod=ford-cache :: ford cache
314+ fer=(unit reef-cache) :: reef cache
315+ == ::
316+```
317+
318+A `dome` is the state of a `desk` and associated data.
319+
320+`ank` is the current state of the desk. Thus, it is the state of the
321+filesystem at revison `let`. The head of a `desk` is always a numbered
322+commit.
323+
324+`let` is the number of the most recently numbered commit. This is also
325+the total number of numbered commits.
326+
327+`hit` is a map of numerical ids to commit hashes. These hashes are mapped into
328+their associated commits in `hut.rang` in the `raft` of Clay. In general, the
329+keys of this map are exactly the numbers from 1 to `let`, with no gaps. Of
330+course, when there are no numbered commits, `let` is 0, so `hit` is null.
331+Additionally, each of the commits is an ancestor of every commit numbered
332+greater than this one. Thus, each is a descendant of every commit numbered less
333+than this one. Since it is true that the date in each commit (`t:yaki`) is no
334+earlier than that of each of its parents, the numbered commits are totally
335+ordered in the same way by both pedigree and date. Of course, not every commit
336+is numbered. If that sounds too complicated to you, don't worry about it. It
337+basically behaves exactly as you would expect.
338+
339+`lab` is a map of textual labels to numbered commits. Note that labels
340+can only be applied to numbered commits. Labels must be unique across a
341+desk.
342+
343+`mim` is a cache of the content in the directories that are mounted to Unix.
344+
345+`fod` is the Ford cache, which keeps a cache of the results of builds performed
346+at this `desk`'s current revision, including a full transitive closure of
347+dependencies for each completed build.
348+
349+`fer` is the system file cache, which consists of `vase`s for `hoon.hoon`,
350+`arvo.hoon`, `lull.hoon`, and `zuse.hoon`.
351+
352+#### `++rung`, filesystem per neighbor ship
353+
354+```hoon
355++$ rung
356+ $: rus=(map desk rede) :: neighbor desks
357+ ==
358+```
359+
360+This is the filesystem of a neighbor ship. The keys to this `map` are all
361+the `desk`s we know about on their ship.
362+
363+#### `++rede`, generic desk state
364+
365+```hoon
366+ ++ rede :: universal project
367+ $: lim=@da :: complete to
368+ qyx=cult :: subscribers
369+ ref=(unit rind) :: outgoing requests
370+ dom=dome :: revision state
371+ == ::
372++$ rede :: universal project
373+ $: lim=@da :: complete to
374+ ref=(unit rind) :: outgoing requests
375+ qyx=cult :: subscribers
376+ dom=dome :: revision state
377+ per=regs :: read perms per path
378+ pew=regs :: write perms per path
379+ == ::
380+```
381+
382+This is our knowledge of the state of a desk, either foreign or
383+domestic.
384+
385+`lim` is the most recent `@da` for which we're confident we have all the
386+information for. For local `desk`s, this is always `now`. For foriegn `desk`s,
387+this is the last time we got a full update from the foreign ship.
388+
389+`ref` is the request manager for the desk. For domestic `desk`s, this is
390+null since we handle requests ourselves. For foreign `desk`s, this keeps track
391+of all pending foriegn requests plus a cache of the responses to previous requests.
392+
393+`qyx` is the `set` of subscriptions to this desk, with listening `duct`s. These
394+subscriptions exist only until they've been filled. For domestic `desk`s, this
395+is simply `qyx:dojo` - all subscribers to the `desk`. For foreign `desk`s this
396+is all the subscribers from our ship to the foreign `desk`.
397+
398+`dom` is the data in the `desk`.
399+
400+`regs` are `(map path rule)`, and so `per` is a `map` of read permissions by
401+`path` and `pew` is a `map` of write permissions by `path`.
402+
403+
404+#### `$rind`, foreign request manager
405+
406+```hoon
407++$ rind :: request manager
408+ $: nix=@ud :: request index
409+ bom=(map @ud update-state) :: outstanding
410+ fod=(map duct @ud) :: current requests
411+ haw=(map mood (unit cage)) :: simple cache
412+ == ::
413+```
414+
415+This is the request manager for a foreign `desk`. When we send a request to a
416+foreign ship, we keep track of it in here.
417+
418+`nix` is one more than the index of the most recent request. Thus, it is the
419+next available request number.
420+
421+`bom` is the set of outstanding requests. The keys of this `map` are some subset
422+of the numbers between 0 and one less than `nix`. The members of the `map` are
423+exactly those requests that have not yet been fully satisfied.
424+
425+`fod` is the same set as `bom`, but from a different perspective. In particular,
426+the values of `fod` are the same as the keys of `bom`, and the `duct` of the
427+values of `bom` are the same as the keys of `fod`. Thus, we can map `duct`s to
428+their associated request number and `update-state`, and we can map request
429+numbers to their associated `duct`.
430+
431+`haw` is a map from `%sing` requests to their values. This acts as a cache for
432+requests that have already been filled.
433+
434+#### `$update-state`, status of outstanding foreign request
435+
436+```hoon
437++$ update-state
438+ $: =duct
439+ =rave
440+ have=(map lobe blob)
441+ need=(list lobe)
442+ nako=(qeu (unit nako))
443+ busy=_|
444+ ==
445+```
446+
447+An `update-state` is used to represent the status of an outstanding request to a
448+foreign `desk`.
449+
450+`duct` and `rave` are the `duct` along which the request was made and the
451+request itself.
452+
453+`have` is a map of hashes thus far acquired in the request to the data
454+associated with those hashes.
455+
456+`need` is a list of hashes yet to be acquired.
457+
458+`nako` is a queue of data yet to be validated.
459+
460+`busy` tracks whether or not the request is currently being fulfilled.
461+
462+#### `$rang:clay`, data repository
463+
464+```hoon
465+ +$ rang :: repository
466+ $: hut=(map tako yaki) :: changes
467+ lat=(map lobe blob) :: data
468+ == ::
469+```
470+
471+This is a data repository keyed by hash. Thus, this is where the "real" data
472+is stored, but it is only meaningful if we know the hash of what we're
473+looking for.
474+
475+`hut` is a `map` from commit hashes (`tako`s) to commits (`yaki`s). We often get
476+the hashes from `hit:dome`, which keys them by numerical id. Not every commit
477+has an numerical id.
478+
479+`lat` is a `map` from content hashes (`lobe`s) to the actual content (`blob`s).
480+We often get the hashes from a `yaki`, which references this `map` to get the
481+data. There is no `blob` in `yaki:clay`. They are only accessible through
482+`lat`.
483+
484+#### `$tako:clay`, commit reference
485+
486+```hoon
487+ +$ tako @ :: yaki ref
488+```
489+
490+This is a hash of a `yaki:clay`, a commit. These are most notably used as the
491+keys in `hut:rang:clay`, where they are associated with the actual `yaki:clay`,
492+and as the values in `hit:dome:clay`, where sequential numerical ids are
493+associated with these.
494+
495+#### `$yaki:clay`, commit
496+
497+```hoon
498+ +$ yaki :: commit
499+ $: p=(list tako) :: parents
500+ q=(map path lobe) :: namespace
501+ r=tako :: self-reference
502+ t=@da :: date
503+ == ::
504+```
505+
506+This is a single commit.
507+
508+`p` is a `list` of the hashes of the parents of this commit. In most
509+cases, this will be a single commit, but in a merge there may be more
510+parents. In theory, there may be an arbitrary number of parents, but in
511+practice merges have exactly two parents. This may change in the future.
512+For commit 1, there is no parent.
513+
514+`q` is a `map` of the `path`s on a desk to the content hashes at that location.
515+If you understand what a `lobe:clay` and a `blob:clay` is, then the type
516+signature here tells the whole story.
517+
518+`r` is the hash associated with this commit.
519+
520+`t` is the date at which this commit was made.
521+
522+#### `$lobe:clay`, data reference
523+
524+```hoon
525+ +$ lobe @uvI :: blob ref
526+```
527+
528+This is a hash of a `blob:clay`. These are most notably used in `lat:rang:clay`,
529+where they are associated with the actual `blob:clay`, and as the values in
530+`q:yaki:clay`, where `path`s are associated with their content hashes in a commit.
531+
532+#### `$blob:clay`, data
533+
534+```hoon
535+ +$ blob :: fs blob
536+ $% [%delta p=lobe q=[p=mark q=lobe] r=page] :: delta on q
537+ [%direct p=lobe q=page] :: immediate
538+```
539+
540+This is a node of data. In both cases, `p` is the hash of the blob.
541+
542+`%delta` is the case where we define the data by a delta on other data. In
543+practice, the other data is always the previous commit, but nothing depends on
544+this. `p.q` is the `mark` of the parent blob, `q.q` is the hash of the parent
545+blob, and `r` is the delta.
546+
547+`%direct` is the case where we simply have the data directly. `q` is the data.
548+These almost always come from the creation of a file.
549+
550+
551+#### `+urge`, list change
552+
553+```hoon
554+ ++ urge |*(a=mold (list (unce a))) :: list change
555+```
556+
557+This is a parametrized type for list changes. For example, `(urge @t)`
558+is a list change for lines of text.
559+
560+#### `+unce`, change part of a list.
561+
562+```hoon
563+ ++ unce :: change part
564+ |* a=mold ::
565+ $% [%& p=@ud] :: skip[copy]
566+ [%| p=(list a) q=(list a)] :: p -> q[chunk]
567+ == ::
568+```
569+
570+This is a single change in a list of elements of type `a`. For example,
571+`(unce @t)` is a single change in lines of text.
572+
573+`%&` means the next `p` lines are unchanged.
574+
575+`%|` means the lines `p` have changed to `q`.
576+
577+#### `$nori:clay`, repository action
578+
579+```hoon
580+ +$ nori :: repository action
581+ $% [%& p=soba] :: delta
582+ [%| p=@tas] :: label
583+ == ::
584+```
585+
586+This describes a change that we are asking Clay to make to the `desk`.
587+There are two kinds of changes that may be made: we can modify files or
588+we can apply a label to a commit.
589+
590+In the `|` case, we will simply label the current commit with the given
591+label. In the `&` case, we will apply the given changes.
592+
593+#### `$soba:clay`, delta
594+
595+```hoon
596+ +$ soba (list [p=path q=miso]) :: delta
597+```
598+
599+This describes a `list` of changes to make to a `desk`. The `path`s are `path`s
600+to files to be changed, and the corresponding `miso` value is a description of
601+the change itself.
602+
603+#### `$miso:clay`, ankh delta
604+
605+```hoon
606+ +$ miso :: ankh delta
607+ $% [%del ~] :: delete
608+ [%ins p=cage] :: insert
609+ [%dif p=cage] :: mutate from diff
610+ [%mut p=cage] :: mutate from raw
611+ == ::
612+```
613+
614+There are four kinds of changes that may be made to a node in a `desk`.
615+
616+`%del` deletes the node.
617+
618+`%ins` inserts a file given by `p`.
619+
620+`%dif` is currently unimplemented. This may seem strange, so we remark that
621+diffs for individual files are implemented using `+diff` and `+pact` in `mark`s.
622+So for an `ankh`, which may include both files and directories, `%dif` being
623+unimplemented really just means that we do not yet have a formal concept of
624+changes in directory structure.
625+
626+`%mut` mutates the file using raw data given by `p`.
627+
628+#### `$riff:clay`, request/desist
629+
630+```hoon
631+ +$ riff [p=desk q=(unit rave)] :: request+desist
632+```
633+
634+This represents a request for data about a particular `desk`. If `q`
635+contains a `rave`, then this opens a subscription to the `desk` for that
636+data. If `q` is null, then this tells Clay to cancel the subscription
637+along this duct.
638+
639+#### `$riot:clay`, response
640+
641+```hoon
642+ +$ riot (unit rant) :: response+complete
643+```
644+
645+A `riot` is a response to a subscription. If null, the subscription has
646+been completed, and no more responses will be sent. Otherwise, the
647+`rant` is the produced data.
648+
649+#### `$rant:clay`, response data
650+
651+```hoon
652+ +$ rant :: response to request
653+ $: p=[p=care q=case r=desk] :: clade release book
654+ q=path :: spur
655+ r=cage :: data
656+ == ::
657+```
658+
659+This is the data associated to the response to a request. `p.p` specifies
660+the type of data that was requested (and is produced). `q.p` gives the
661+specific version reported (since a range of versions may be requested in
662+a subscription). `r.p` is the `desk`. `q` is the path to the filesystem
663+node. `r` is the data itself (in the format specified by `p.p`).
664+
665+### `$nako`, subscription response data
666+
667+```hoon
668++$ nako :: subscription state
669+ $: gar=(map aeon tako) :: new ids
670+ let=aeon :: next id
671+ lar=(set yaki) :: new commits
672+ bar=(set plop) :: new content
673+ == ::
674+```
675+
676+This is the data that is produced by a request for a range of revisions
677+of a `desk`. This allows us to easily keep track of a remote repository --
678+all the new information we need is contained in the `nako`.
679+
680+`gar` is a map of the revisions in the range to the hash of the commit
681+at that revision. These hashes can be used with `hut:rang:clay` to find the
682+commit itself.
683+
684+`let` is either the last revision number in the range or the most recent
685+revision number, whichever is smaller.
686+
687+`lar` is the set of new commits, and `bar` is the set of new content.
688+
content/docs/arvo/clay/examples.mdnew file+824
@@ -0,0 +1,824 @@
1++++
2+title = "Examples"
3+weight = 7
4+template = "doc.html"
5++++
6+
7+# Contents
8+
9+- [Introduction](#introduction)
10+- [%warp](#warp) - Read and Subscribe.
11+ - [%sing](#sing) - Read a file or directory.
12+ - [%next](#next) - Subscribe for the next change to a file or directory.
13+ - [%mult](#mult) - Subscribe for the next change to a set of files and/or directories.
14+ - [%many](#many) - Track changes to a `desk` for the specified range of revisions.
15+ - [Cancel Subscription](#cancel-subscription)
16+- [%info](#info) - Write and Modify.
17+ - [%ins](#ins) - Add a file.
18+ - [%del](#del) - Delete a file.
19+ - [%mut](#mut) - Change a file.
20+ - [Multiple Changes](#multiple-changes) - Change multiple files.
21+- [Manage Mounts](#manage-mounts)
22+ - [%boat](#boat) - List mounts.
23+ - [%mont](#mont) - Mount something.
24+ - [%ogre](#ogre) - Unmount something.
25+ - [%dirk](#dirk) - Commit changes.
26+- [Merge Desks](#merge-desks)
27+ - [%merg](#merg)
28+- [Permissions](#permissions)
29+ - [%perm](#perm) - Set file permissions.
30+ - [%cred](#cred) - Add permission group.
31+ - [%crew](#crew) - Get permission groups.
32+ - [%crow](#crow) - Get group usage.
33+- [Foreign Ships](#foreign-ships)
34+ - [%warp](#warp-remote) - Read a file on a foreign ship.
35+ - [%merg](#merg-remote) - Merge from a foreign `desk`.
36+
37+# Introduction
38+
39+This document contains a number of examples of interacting with Clay using its various `task`s. Sections correspond to the general details in the [API Reference](/docs/arvo/clay/tasks) document.
40+
41+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 your `%home` `desk`:
42+
43+`send-task-take-gift.hoon`
44+
45+```hoon
46+/- spider
47+/+ strandio
48+=, strand=strand:spider
49+^- thread:spider
50+|= arg=vase
51+=/ m (strand ,vase)
52+^- form:m
53+=/ uarg !< (unit task:clay) arg
54+?~ uarg
55+ (strand-fail:strand %no-arg ~)
56+=/ =task:clay u.uarg
57+=/ =card:agent:gall [%pass /foo %arvo %c task]
58+;< ~ bind:m (send-raw-card:strandio card)
59+;< res=[wire sign-arvo] bind:m take-sign-arvo:strandio
60+~& +>:res
61+(pure:m !>(~))
62+```
63+
64+# `%warp`
65+
66+See the [Read and Subscribe](/docs/arvo/clay/tasks#warp) section of the [API Reference](/docs/arvo/clay/tasks) document for general details.
67+
68+## `%sing`
69+
70+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.
71+
72+
73+Using the `send-task-take-gift.hoon` thread, let's try reading `gen/hood/hi.hoon`:
74+
75+```
76+> -send-task-take-gift [%warp our %home ~ %sing %x da+now /gen/hood/hi/hoon]
77+```
78+
79+You should see something like this as the output:
80+
81+```
82+[ %writ
83+ p
84+ [ ~
85+ [ p=[p=%x q=[%da p=~2021.5.20..23.37.50..e79b] r=%home]
86+ q=/gen/hood/hi/hoon
87+ r
88+ [ p=%hoon
89+ q
90+ [ #t/@
91+ q
92+ 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
93+ ]
94+ ]
95+ ]
96+ ]
97+]
98+```
99+
100+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:
101+
102+```
103+> -send-task-take-gift [%warp our %home ~ %sing %x da+now /gen/hood/hi/hoon]
104+[ %writ
105+ p
106+ [ ~
107+ [ p=[p=%u q=[%da p=~2021.5.20..23.42.21..bb33] r=%home]
108+ q=/gen/hood/hi/hoon
109+ r=[p=%flag q=[#t/?(%.y %.n) q=0]]
110+ ]
111+ ]
112+]
113+```
114+
115+Here's a breakdown of the `task` we sent:
116+
117+![%sing diagram](https://media.urbit.org/docs/arvo/clay/sing.png "%sing diagram")
118+
119+## `%next`
120+
121+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.
122+
123+Using the `send-task-take-gift.hoon` thread, let's subscribe to the next version of `foo.txt`:
124+
125+```
126+> -send-task-take-gift [%warp our %home ~ %next %x da+now /foo/txt]
127+```
128+
129+Now, in unix, create a file called `foo.txt` in the root of the `home` directory of your ship. In the dojo, hit backspace to disconnect the thread from the dojo prompt and run `|commit %home`. You should see something like:
130+
131+```
132+> |commit %home
133+>=
134+[%writ p=[~ [p=[p=%x q=[%ud p=3] r=%home] q=/foo/txt r=[p=%txt q=[#t/*'' q=0]]]]]
135++ /~zod/home/3/foo/txt
136+```
137+
138+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`.
139+
140+Now run the thread again, and this time delete the file in unix and again `|commit %home` in the dojo. You should see:
141+
142+```
143+> |commit %home
144+>=
145+[%writ p=~]
146+- /~zod/home/4/foo/txt
147+```
148+
149+You can see the `riot` is just `~` due to the file being deleted.
150+
151+Here's a breakdown of the task we sent:
152+
153+![%next diagram](https://media.urbit.org/docs/arvo/clay/next.png "%next diagram")
154+
155+## `%mult`
156+
157+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.
158+
159+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.
160+
161+`sub-mult.hoon`
162+
163+```hoon
164+/- spider
165+/+ strandio
166+=, strand=strand:spider
167+^- thread:spider
168+|= arg=vase
169+=/ m (strand ,vase)
170+^- form:m
171+=/ files=(set (pair care:clay path))
172+ %- sy :~
173+ [%x /foo/txt]
174+ [%u /bar/txt]
175+ ==
176+;< =bowl:strand bind:m get-bowl:strandio
177+=/ =task:clay [%warp our.bowl %home ~ %mult da+now.bowl files]
178+=/ =card:agent:gall [%pass /mult %arvo %c task]
179+;< ~ bind:m (send-raw-card:strandio card)
180+;< response=(pair wire sign-arvo) bind:m take-sign-arvo:strandio
181+~& +.q.response
182+(pure:m !>(~))
183+```
184+
185+Save the above to `ted/sub-mult.hoon`, `|commit %home` and run with `-sub-mult`. Now, create `foo.txt` and `bar.txt` in your home directory, hit backspace in the dojo to disconnect the thread and run `|commit %home`. You should see something like:
186+
187+```
188+> |commit %home
189+>=
190+[%wris p=[%da p=~2021.4.27..06.07.08..5ec4] q={[p=%u q=/bar/txt] [p=%x q=/foo/txt]}]
191++ /~zod/home/151/foo/txt
192++ /~zod/home/151/bar/txt
193+```
194+
195+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.
196+
197+Now, run the thread again, open `bar.txt` in an editor, modify its contents, save it and `|commit %home`. You'll notice you didn't receive a `%wris`. This is because we subscribed to `/bar/txt` with `%u` care and its existence didn't change.
198+
199+Lastly, delete `foo.txt` and `|commit %home`. You should see something like:
200+
201+```
202+> |commit %home
203+>=
204+[%wris p=[%da p=~2021.4.27..06.15.03..0da4] q={[p=%x q=/foo/txt]}]
205+- /~zod/home/153/foo/txt
206+```
207+
208+As you can see, a relevant change to any of the subscribed files will trigger a response, not just when all of them change.
209+
210+Here's a breakdown of the `task` we sent:
211+
212+![subscribe mult diagram](https://media.urbit.org/docs/arvo/clay/sub-mult.png "subscribe mult diagram")
213+
214+## `%many`
215+
216+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.
217+
218+This thread will subscribe to changes to your `%home` `desk` for the next three minutes. The `track` is `%.y` so it will only inform you of changes, not send the full `nako`. It will only get updates if the specified file exists. It contains a `main-loop` that will take an arbitrary number of `sign`s and print them out in the dojo. Since it never ends, you'll need to stop it with the `:spider|kill` command in the dojo.
219+
220+`sub-many.hoon`
221+
222+```hoon
223+/- spider
224+/+ strandio
225+=, strand=strand:spider
226+|%
227+++ take-sign-loop
228+ =/ m (strand ,~)
229+ ^- form:m
230+ %- (main-loop:strandio ,~)
231+ :~ |= ~
232+ ^- form:m
233+ ;< res=(pair wire sign-arvo)
234+ bind:m
235+ ((handle:strandio ,(pair wire sign-arvo)) take-sign-arvo:strandio)
236+ ~& res
237+ (pure:m ~)
238+ ==
239+--
240+^- thread:spider
241+|= arg=vase
242+=/ m (strand ,vase)
243+^- form:m
244+=/ uarg !< (unit path) arg
245+?~ uarg
246+ (strand-fail:strand %no-arg ~)
247+=/ =path u.uarg
248+;< =bowl:strand bind:m get-bowl:strandio
249+=/ =task:clay [%warp our.bowl %home ~ %many %.y da+now.bowl da+(add ~m3 now.bowl) path]
250+=/ =card:agent:gall [%pass /many %arvo %c task]
251+;< ~ bind:m (send-raw-card:strandio card)
252+;< ~ bind:m take-sign-loop
253+(pure:m !>(~))
254+```
255+
256+Make sure `foo.txt` doesn't exist in the root of your `%home` `desk`. Save this to `ted/sub-many.hoon`, `|commit %home`, run it like `-sub-many /foo/txt`, and hit backspace in the dojo to free up the dojo prompt. Now, add a file called `bar.txt` to your `desk` and `|commit %home`. You should see something like:
257+
258+```
259+> |commit %home
260+>=
261++ /~zod/home/260/bar/txt
262+```
263+
264+Notice you've received no `%writ` from Clay. This is because `/foo/txt` doesn't exist. Now, create `foo.txt` and `|commit %home` again. You should see:
265+
266+```
267+> |commit %home
268+>=
269+[ p=/many
270+ q=[%clay [%writ p=[~ [p=[p=%w q=[%ud p=261] r=%home] q=/ r=[p=%null q=[#t/@n q=0]]]]]]
271+]
272++ /~zod/home/261/foo/txt
273+```
274+
275+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.
276+
277+Now try adding `baz.txt`:
278+
279+```
280+> |commit %home
281+>=
282+[ p=/many
283+ q=[%clay [%writ p=[~ [p=[p=%w q=[%ud p=262] r=%home] q=/ r=[p=%null q=[#t/@n q=0]]]]]]
284+]
285++ /~zod/home/262/baz/txt
286+```
287+
288+Now wait until the three minutes is up and try making a change, for example deleting `baz.txt`:
289+
290+```
291+> |commit %home
292+>=
293+[ p=/many
294+ q=[%clay [%writ p=[~ [p=[p=%w q=[%ud p=264] r=%home] q=/ r=[p=%null q=[#t/@n q=0]]]]]]
295+]
296+[p=/many q=[%clay [%writ p=~]]]
297+- /~zod/home/263/baz/txt
298+```
299+
300+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.
301+
302+Run `:spider|kill` to stop the thread.
303+
304+Here's a breakdown of the `task` we sent:
305+
306+![subscribe many diagram](https://media.urbit.org/docs/arvo/clay/sub-many.png "subscribe many diagram")
307+
308+## Cancel Subscription
309+
310+Here we'll look at cancelling a subscription by sending Clay a `%warp` `task` with a null `(unit rave)` in the `riff`.
311+
312+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).
313+
314+`stop-sub.hoon`
315+
316+```hoon
317+/- spider
318+/+ strandio
319+=, strand=strand:spider
320+^- thread:spider
321+|= arg=vase
322+=/ m (strand ,vase)
323+^- form:m
324+;< =bowl:strand bind:m get-bowl:strandio
325+=/ =task:clay [%warp our.bowl %home ~ %next %x da+now.bowl /foo/txt]
326+=/ =card:agent:gall [%pass /next %arvo %c task]
327+;< ~ bind:m (send-raw-card:strandio card)
328+=. task [%warp our.bowl %home ~]
329+=. card [%pass /next %arvo %c task]
330+;< ~ bind:m (send-raw-card:strandio card)
331+;< =riot:clay bind:m (take-writ:strandio /next)
332+~& riot
333+(pure:m !>(~))
334+```
335+
336+Save the above to `ted/stop-sub.hoon`, `|commit %home`, run it with `-stop-sub` and hit backspace to detach it from the dojo prompt. Now, add `foo.txt` to the root of your `%home` `desk` and `|commit %home`. You should see:
337+
338+```
339+> |commit %home
340+>=
341++ /~zod/home/266/foo/txt
342+```
343+
344+As you can see we've received no `%writ`. We can thus conclude the subscription has successfully been cancelled.
345+
346+Run `:spider|kill` to stop the thread.
347+
348+Here's a breakdown of the `task` we sent:
349+
350+![cancel subscription diagram](https://media.urbit.org/docs/arvo/clay/stop-sub.png "cancel subscription diagram")
351+
352+# `%info`
353+
354+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.
355+
356+## `%ins`
357+
358+Here we'll look at adding a file by sending Clay a `%info` `task` containing a `%ins` `miso`.
359+
360+Let's try adding a `foo.txt` file with 'foo' as its contents:
361+
362+```
363+> |pass [%c [%info %home %& [/foo/txt %ins %txt !>(~['foo'])]~]]
364++ /~zod/home/5/foo/txt
365+```
366+
367+If you have a look in the home of your pier you'll see there's now a file called `foo.txt` with the text `foo` in it.
368+
369+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`.
370+
371+Here's a breakdown of the `task` we sent:
372+
373+![%ins diagram](https://media.urbit.org/docs/arvo/clay/ins.png)
374+
375+## `%del`
376+
377+Here we'll look at deleting a file by sending Clay a `%info` `task` containing a `%del` `miso`.
378+
379+Let's try deleting the `foo.txt` file created in the [previous example](#ins):
380+
381+```
382+> |pass [%c [%info %home %& [/foo/txt %del ~]~]]
383+- /~zod/home/6/foo/txt
384+```
385+
386+If you have a look in the home of your pier you'll see the `foo.txt` file is now gone.
387+
388+Here's a breakdown of the `task` we sent:
389+
390+![%del diagram](https://media.urbit.org/docs/arvo/clay/del.png)
391+
392+## `%mut`
393+
394+Identical to the [%ins](#ins) example, just replace `%ins` with `%mut`.
395+
396+## Multiple Changes
397+
398+Here we'll look at changing multiple files in one request by sending Clay a `%info` `task` containing multiple `miso` in the `soba`.
399+
400+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.
401+
402+`multi-change.hoon`
403+
404+```hoon
405+/- spider
406+/+ strandio
407+=, strand=strand:spider
408+^- thread:spider
409+|= arg=vase
410+=/ m (strand ,vase)
411+^- form:m
412+=/ soba-a :~ [/foo/txt %ins %txt !>(['foo' ~])]
413+ [/bar/txt %ins %txt !>(['bar' ~])]
414+ [/baz/txt %ins %txt !>(['baz' ~])]
415+ ==
416+=/ soba-b :~ [/foo/txt %del ~]
417+ [/bar/txt %del ~]
418+ [/baz/txt %del ~]
419+ ==
420+;< ~ bind:m (send-raw-card:strandio [%pass /info %arvo %c %info %home %& soba-a])
421+;< ~ bind:m (send-raw-card:strandio [%pass /info %arvo %c %info %home %& soba-b])
422+(pure:m !>(~))
423+```
424+
425+Save to `ted/multi-change.hoon`, `|commit %home`, and run:
426+
427+```
428+> -multi-change
429++ /~zod/home/37/foo/txt
430++ /~zod/home/37/bar/txt
431++ /~zod/home/37/baz/txt
432+- /~zod/home/38/foo/txt
433+- /~zod/home/38/bar/txt
434+- /~zod/home/38/baz/txt
435+```
436+
437+# Manage Mounts
438+
439+See the [Manage Mounts](/docs/arvo/clay/tasks#manage-mounts) section of the [API Reference](/docs/arvo/clay/tasks) document for general details.
440+
441+## `%boat`
442+
443+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`.
444+
445+Using the `send-task-take-gift.hoon` thread, let's make such a request:
446+
447+```
448+> -send-task-take-gift [%boat ~]
449+[%hill p=~[%home]]
450+```
451+
452+## `%mont`
453+
454+Here we'll look at mounting `desk`s, directories and files to unix by sending Clay a `%mont` `task`.
455+
456+Let's first try mounting our `%kids` desk:
457+
458+```
459+> |pass [%c [%mont %kids [our %kids da+now] /]]
460+```
461+
462+If you look in your pier, you should now see a `kids` folder which contains the contents of that `desk`.
463+
464+If we make a `%boat` request as detailed in the [%boat](#boat) section, we'll now see the mount point listed:
465+
466+```
467+> -send-task-take-gift [%boat ~]
468+[%hill p=~[%kids %home]]cruz gift. It looks like:
469+
470+[%cruz cez=(map @ta crew)] :: permission groups
471+The cez is just a map from group name to crew
472+```
473+
474+Note the mount point doesn't need to match a `desk`, file or directory. We can also do:
475+
476+```
477+> |pass [%c [%mont %wibbly-wobbly [our %home da+now] /]]
478+```
479+
480+And you'll now see that there's a `wibbly-wobbly` folder with the contents of the `%home` `desk`. You'll also notice we can mount the same file or directory more than once. There's no problem having `%home` mounted to both `home` and `wibbly-wobbly`. The only requirement is that their mount points be unique.
481+
482+Let's try mounting a subdirectory and a single folder:
483+
484+```
485+> |pass [%c [%mont %gen [our %home da+now] /gen]]
486+> |pass [%c [%mont %hi [our %home da+now] /gen/hood/hi]]
487+```
488+
489+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.
490+
491+## `%ogre`
492+
493+Here we'll look at unmounting `desk`s, directories and files by sending Clay a `%ogre` `task`.
494+
495+Let's unmount what we mounted in the [%mont](#mont) section. First we'll unmount the `%kids` desk:
496+
497+```
498+|pass [%c [%ogre %kids]]
499+```
500+
501+Our custom mount point `%wibbly-wobbly`:
502+
503+```
504+|pass [%c [%ogre %wibbly-wobbly]]
505+```
506+
507+And the single `hi.hoon` we previously mounted by specifying its mount point `%hi`:
508+
509+```
510+|pass [%c [%ogre %hi]]
511+```
512+
513+If we specify a non-existent mount point it will fail with an error printed to the dojo like:
514+
515+```
516+> |pass [%c [%ogre %kids]]
517+[%not-mounted %kids]
518+```
519+
520+If we give it an unmounted `beam` it will not print an error but still won't work.
521+
522+## `%dirk`
523+
524+Here we'll look at committing changed files by sending Clay a `%dirk` `task`.
525+
526+This `task` performs the same function as the `|commit` dojo command.
527+
528+With your `%home` `desk` mounted, try adding a file and send a `%dirk` to commit the change:
529+
530+```
531+> |pass [%c [%dirk %home]]
532++ /~zod/home/12/foo/txt
533+```
534+
535+Clay will print the changed files to the dojo with a leading `+`, `-` or `:` to indicate a new file, deleted file and changed file respectively.
536+
537+If you have the same `desk` mounted to multiple points, a committed change in one mount will also update the others.
538+
539+# Merge Desks
540+
541+See the [Merge Desks](/docs/arvo/clay/tasks#merge-desks) section of the [API Reference](/docs/arvo/clay/tasks) document for general details.
542+
543+## `%merg`
544+
545+Here we'll look at merging `desk`s by sending Clay a `%merg` `task` and receiving a `%mere` `gift` in response.
546+
547+First, using the `send-task-take-gift.hoon` thread, let's try creating a new `desk`:
548+
549+```
550+> -send-task-take-gift [%merg %foo our %home da+now %init]
551+[%mere p=[%.y p={}]]
552+```
553+
554+Now if we scry for our `desk`s we'll see `%foo` is there:
555+
556+```
557+> .^((set desk) %cd /===)
558+{%home %foo %kids}
559+```
560+
561+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.
562+
563+Now we'll try merging `%home` into `%foo` with a `%mate` strategy:
564+
565+```
566+> -send-task-take-gift [%merg %foo our %home da+now %mate]
567+[ /foo
568+ [ %clay
569+ [ %mere
570+ p
571+ [ %.n
572+ p
573+ [ p=%mate-conflict
574+ q=~[[%rose p=[p="/" q="/" r=""] q=[i=[%leaf p="foo"] t=[i=[%leaf p="txt"] t=~]]]]
575+ ]
576+ ]
577+ ]
578+ ]
579+]
580+```
581+
582+As you can see, the merge has failed. Let's try again with a `%meld` strategy:
583+
584+```
585+> -send-task-take-gift [%merg %foo our %home da+now %meld]
586+[/foo [%clay [%mere p=[%.y p={/foo/txt}]]]]
587+```
588+
589+Now the merge has succeeded and the `%mere` notes the file with a merge conflict. If we try with a `%only-that` strategy:
590+
591+```
592+> -send-task-take-gift [%merg %foo our %home da+now %only-that]
593+[/foo [%clay [%mere p=[%.y p={}]]]]
594+: /~zod/foo/6/foo/txt
595+```
596+
597+...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.
598+
599+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:
600+
601+```
602+> -send-task-take-gift [%merg %foo our %home da+(add ~m2 now) %only-that]
603+```
604+
605+Now change the text in the `foo.txt` in the `%home` `desk`, hit backspace to detach the thread and `|commit %home`. After the two minutes pass you should see:
606+
607+```
608+[/foo [%clay [%mere p=[%.y p={}]]]]
609+: /~zod/foo/7/foo/txt
610+```
611+
612+You can also specify it by revision number or label.
613+
614+# Permissions
615+
616+See the [Permissions](/docs/arvo/clay/tasks#permissions) section of the [API Reference](/docs/arvo/clay/tasks) document for general details.
617+
618+## `%perm`
619+
620+Here we'll look at setting permissions by sending Clay a `%perm` `task`.
621+
622+First, let's allow `~nes` to read `/gen/hood/hi/hoon`:
623+
624+```
625+> |pass [%c [%perm %home /gen/hood/hi/hoon %r ~ %white (sy [%.y ~nes]~)]]
626+```
627+
628+...and we'll do a `%p` scry to see that the permission was set:
629+
630+```
631+> .^([r=dict:clay w=dict:clay] %cp /===/gen/hood/hi/hoon)
632+[r=[src=/gen/hood/hi/hoon rul=[mod=%white who=[p={~nes} q={}]]] w=[src=/ rul=[mod=%white who=[p={} q={}]]]]
633+```
634+
635+You can see that `~nes` is now in the read whitelist. Next, let's try a write permission:
636+
637+```
638+> |pass [%c [%perm %home /ted %w ~ %white (sy [%.y ~nes]~)]]
639+```
640+
641+You can see `~nes` can now write to `/ted`:
642+
643+```
644+> .^([r=dict:clay w=dict:clay] %cp /===/ted)
645+[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/ted rul=[mod=%white who=[p={~nes} q={}]]]]
646+```
647+
648+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:
649+
650+```
651+> .^([r=dict:clay w=dict:clay] %cp /===/ted/aqua/ames/hoon)
652+[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/ted rul=[mod=%white who=[p={~nes} q={}]]]]
653+```
654+
655+...and you'll notice that `src` tells us it's inherited the rule from `/ted`.
656+
657+Now let's try setting both read and write permissions:
658+
659+```
660+> |pass [%c [%perm %home /gen/help/hoon %rw `[%black (sy [%.y ~nes]~)] `[%white (sy [%.y ~nes]~)]]]
661+```
662+
663+```
664+ .^([r=dict:clay w=dict:clay] %cp /===/gen/help/hoon)
665+[r=[src=/gen/help/hoon rul=[mod=%black who=[p={~nes} q={}]]] w=[src=/gen/help/hoon rul=[mod=%white who=[p={~nes} q={}]]]]
666+```
667+
668+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`.
669+
670+For example, to remove a read permission (or write if you specify `%w`):
671+
672+```
673+> |pass [%c [%perm %home /gen/help/hoon %r ~]]
674+```
675+
676+```
677+> .^([r=dict:clay w=dict:clay] %cp /===/gen/help/hoon)
678+[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/gen/help/hoon rul=[mod=%white who=[p={~nes} q={}]]]]
679+```
680+
681+...and to remove both read and write at the same time:
682+
683+```
684+> |pass [%c [%perm %home /gen/help/hoon %rw ~ ~]]
685+```
686+
687+```
688+> .^([r=dict:clay w=dict:clay] %cp /===/gen/help/hoon)
689+[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/ rul=[mod=%white who=[p={} q={}]]]]
690+```
691+
692+As you can see it's back to the default inherited from `/`.
693+
694+Here's a breakdown of a `%perm` task:
695+
696+![perm diagram](https://media.urbit.org/docs/arvo/clay/perm-diagram.png)
697+
698+## `%cred`
699+
700+Here we'll look at creating a permission group by sending Clay a `%cred` `task`.
701+
702+Let's create a group called `'foo'` with a few ships:
703+
704+```
705+|pass [%c [%crew 'foo' (sy ~[~zod ~nec ~bud ~wes ~sev])]]
706+```
707+
708+We'll check it with the next kind of `task`: [%crew](#crew).
709+
710+## `%crew`
711+
712+Here we'll look at retrieving permission groups by sending Clay a `%crew` `task` and receiving a `%cruz` `gift` in response.
713+
714+Let's check, using the `send-task-take-gift.hoon` thread, for the permission group created in the [%cred](#cred) example:
715+
716+```
717+> -send-task-take-gift [%crew ~]
718+[%cruz cez={[p=~.foo q={~nec ~bud ~wes ~zod ~sev}]}]
719+```
720+
721+## `%crow`
722+
723+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.
724+
725+First we'll set a couple of permissions for the `foo` group we created in the [%cred](#cred) section:
726+
727+```
728+> |pass [%c [%perm %home /gen/hood/hi/hoon %w ~ %white (sy [%.n 'foo']~)]]
729+> |pass [%c [%perm %home /ted %w ~ %white (sy [%.n 'foo']~)]]
730+```
731+
732+Notice we use a `%.n` in the `whom` to indicate a group rather than the `%.y` of a ship.
733+
734+Now we'll use the `send-task-take-gift.hoon` thread to try `%crow`:
735+
736+```
737+> -send-task-take-gift [%crow 'foo']
738+[ %croz
739+ rus
740+ { [ p=%home
741+ q
742+ [ r={}
743+ w
744+ { [p=/gen/hood/hi/hoon q=[mod=%white who={[%.n p=~.foo]}]]
745+ [p=/ted q=[mod=%white who={[%.n p=~.foo]}]]
746+ }
747+ ]
748+ ]
749+ }
750+]
751+```
752+
753+# Foreign Ships
754+
755+See the [Foreign Ships](/docs/arvo/clay/tasks#foreign-ships) section of the [API Reference](/docs/arvo/clay/tasks) document for general details.
756+
757+## `%warp` - Remote
758+
759+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.
760+
761+We'll use a fake ~nes as the the foreign ship and a fake ~zod as the local ship.
762+
763+First we'll set permissions on the foreign ship. Create a file called `foo.txt` in the `%home` of ~nes, then send a `%perm` request to allow ~zod to read and write the file:
764+
765+```
766+> |pass [%c [%perm %home /foo/txt %rw `[%white (sy [%.y ~zod]~)] `[%white (sy [%.y ~zod]~)]]]
767+```
768+
769+If we scry the file for its permissions with a `%p` `care`, we'll see ~zod is now whitelisted:
770+
771+```
772+> .^([r=dict:clay w=dict:clay] %cp /===/foo/txt)
773+[r=[src=/foo/txt rul=[mod=%white who=[p={~zod} q={}]]] w=[src=/foo/txt rul=[mod=%white who=[p={~zod} q={}]]]]
774+```
775+
776+Back on ~zod: Using the `send-task-take-gift.hoon` thread, send a `%x` read request for `/foo/txt` on ~nes like:
777+
778+```
779+> -send-task-take-gift [%warp ~nes %home ~ %sing %x da+now /foo/txt]
780+[ %writ
781+ p
782+ [ ~
783+ [ p=[p=%x q=[%da p=~2021.5.3..08.24.22..9ce7] r=%home]
784+ q=/foo/txt
785+ r=[p=%txt q=[#t/txt=*'' q=[7.303.014 0]]]
786+ ]
787+ ]
788+]
789+```
790+
791+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`:
792+
793+```
794+> -send-task-take-gift [%warp ~nes %home ~ %sing %u da+now /foo/txt]
795+[ %writ
796+ p
797+ [ ~
798+ [ p=[p=%u q=[%da p=~2021.5.3..08.26.32..88cf] r=%home]
799+ q=/foo/txt
800+ r=[p=%flag q=[#t/?(%.y %.n) q=0]]
801+ ]
802+ ]
803+]
804+```
805+
806+If we send a `%d` request however, it will crash:
807+
808+```
809+> -send-task-take-gift [%warp ~nes %home ~ %sing %d da+now /foo/txt]
810+call: failed
811+/sys/vane/clay/hoon:<[4.085 3].[4.314 5]>
812+...
813+/sys/vane/clay/hoon:<[1.365 7].[1.365 51]>
814+[ %clay-bad-foreign-request-care
815+ [%sing mood=[care=%d case=[%da p=~2021.5.3..20.04.57..1092] path=/foo/txt]]
816+]
817+/sys/vane/clay/hoon:<[1.365 48].[1.365 50]>
818+```
819+
820+## `%merg` - Remote
821+
822+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.
823+
824+The foreign ship will respond only if correct permissions have been set. See the [%perm](#perm) section for an example.
content/docs/arvo/clay/scry.mdnew file+425
@@ -0,0 +1,425 @@
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 ~.home ~.~2021.4.26..02.29.03..d31b ~]
12+```
13+
14+## Contents
15+
16+- [%a](#a) - Build a `hoon` file.
17+- [%b](#b) - Dynamic `mark`.
18+- [%c](#c) - Dynamic `mark` conversion.
19+- [%d](#d) - List `desk`s.
20+- [%e](#e) - Static `mark`.
21+- [%f](#f) - Static `mark` conversion.
22+- [%p](#p) - File permissions.
23+- [%r](#r) - Vase-wrapped file data.
24+- [%s](#s) - Miscellaneous scries:
25+ - [%yaki](#yaki) - `yaki:clay` of the specified commit.
26+ - [%blob](#blob) - `blob:clay` of file.
27+ - [%hash](#hash) - Content hash of the specified commit.
28+ - [%cage](#cage) - `cage` of the data of a file.
29+ - [%open](#open) - Compile prelude of file.
30+ - [%late](#late) - Most recent `case` of `desk`.
31+ - [%base](#base) - Mergebase of two `desk`s.
32+- [%t](#t) - List files in directory.
33+- [%u](#u) - Check for existence of file.
34+- [%v](#v) - Desk state.
35+- [%w](#w) - Revision number of the given `desk` `case`.
36+- [%x](#x) - Raw data of file.
37+- [%y](#y) - `arch` of a file or directory.
38+- [%z](#z) - Content hash of a file or directory.
39+
40+## %a
41+
42+A scry with a `care` of `%a` will build a `hoon` file and return it as a `vase`.
43+
44+Example:
45+
46+```
47+.^(vase %ca /===/lib/strandio/hoon)
48+```
49+
50+## %b
51+
52+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`.
53+
54+Example:
55+
56+```
57+.^(dais:clay %cb /===/txt)
58+```
59+
60+## %c
61+
62+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`.
63+
64+Example:
65+
66+```
67+> =a .^(tube:clay %cc /===/txt/mime)
68+> !< mime (a !>(~['foo']))
69+[p=/text/plain q=[p=3 q=7.303.014]]
70+```
71+
72+## %d
73+
74+A scry with a `care` of `%d` will return a `(set desk)` of the `desk`s that exist on your ship.
75+
76+Example:
77+
78+```
79+> .^((set desk) %cd /===)
80+{%home %kids}
81+```
82+
83+## %e
84+
85+A scry with a `care` of `%e` will return a statically typed `nave:clay` `mark` core in a `vase`. The `path` in the scry specifies the `mark`.
86+
87+Example:
88+
89+```
90+.^(vase %ce /===/noun)
91+```
92+
93+## %f
94+
95+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`.
96+
97+```
98+> =a .^($-(text mime) %cf /===/txt/mime)
99+> (a ~['foo'])
100+[p=/text/plain q=[p=3 q=7.303.014]]
101+```
102+
103+## %p
104+
105+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.
106+
107+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.
108+
109+Example:
110+
111+```
112+> .^([dict:clay dict:clay] %cp /===/gen)
113+[[src=/ rul=[mod=%white who=[p={} q={}]]] src=/ rul=[mod=%white who=[p={} q={}]]]
114+```
115+
116+## %r
117+
118+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.
119+
120+Examples:
121+
122+```
123+> .^(vase %cr /===/gen/hood/hi/hoon)
124+[ #t/@
125+ q
126+ 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
127+]
128+```
129+
130+```
131+> !< @t .^(vase %cr /===/gen/hood/hi/hoon)
132+':: Helm: send message to an urbit\0a::\0a:::: /hoon/hi/hood/gen\0a ::\0a/? 310\0a:- %say\0a|=([^ [who=ship mez=$@(~ [a=tape ~])] ~] helm-send-hi+[who ?~(mez ~ `a.mez)])\0a'
133+```
134+
135+```
136+> .^(vase %cr /===/gen)
137+Crash!
138+```
139+
140+## %s
141+
142+A scry with a `care` of `%s` is for miscellaneous internal and debug functions and is liable to change in the future.
143+
144+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.
145+
146+### %yaki
147+
148+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).
149+
150+Example:
151+
152+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.
153+
154+```
155+> =/ =dome:clay .^(dome:clay %cv /===)
156+ =/ =tako:clay (~(got by hit.dome) let.dome)
157+ .^(yaki:clay %cs /===/yaki/(scot %uv tako))
158+[ 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]
159+ q
160+ { [p=/mar/hark/graph-hook-update/hoon q=0v5.ea0bj.21s5c.mjrop.ishic.fpkvl.e5bbs.91kc9.tdo41.ifi06.60v41]
161+ [p=/gen/hood/autocommit/hoon q=0v19.rh7jv.sa67o.t3jrb.4sdvs.7c45f.pv2u0.ragik.psp20.agqd8.8srkj]
162+ ...
163+ [p=/tests/lib/primitive-rsa/hoon q=0v1g.3qmq3.6i15q.arh6h.lfsqu.gvc9m.ql6m5.e2rdr.vnnt9.tptc6.mv9u7]
164+ [p=/tests/sys/vane/gall/hoon q=0va.alspc.qptqn.7tuj0.bgecg.1093t.gtsjs.up03k.d1fmk.4jrh8.2tdfa]
165+ }
166+ 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
167+ t=~2021.4.16..10.41.57..3565
168+]
169+```
170+
171+### %blob
172+
173+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).
174+
175+Example:
176+
177+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.
178+
179+```
180+> =/ =arch .^(arch %cy /===/gen/hood/hi/hoon)
181+ ?~ fil.arch
182+ ~
183+ .^(blob:clay %cs /===/blob/(scot %uv u.fil.arch))
184+[ %direct
185+ p=0vp.k7nsm.qkdr3.t17rp.33bae.8gajg.v27gi.40itr.2u9qa.nppbt.7k255
186+ q
187+ [ p=%hoon
188+ q
189+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
190+ ]
191+]
192+```
193+
194+### %hash
195+
196+This will return the `@uvI` content hash of the specified commit. It takes a `tako:clay`.
197+
198+Example:
199+
200+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.
201+
202+```
203+> =/ =dome:clay .^(dome:clay %cv /===)
204+ =/ =tako:clay (~(got by hit.dome) let.dome)
205+ .^(tako:clay %cs /===/hash/(scot %uv tako))
206+0v16.er7uq.oke4u.cru7u.nglu9.q3su7.6ub1o.bh4qk.r5uav.ut12d.5rdl5
207+```
208+
209+### %cage
210+
211+This will return a `cage` of the data of some file. It takes a `lobe:clay`.
212+
213+Example:
214+
215+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.
216+
217+```
218+> =/ =arch .^(arch %cy /===/gen/hood/hi/hoon)
219+ ?~ fil.arch
220+ ~
221+ .^(cage %cs /===/cage/(scot %uv u.fil.arch))
222+[ p=%hoon
223+ q
224+ [ #t/@t
225+ q
226+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
227+ ]
228+]
229+```
230+
231+### %open
232+
233+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.
234+
235+### %late
236+
237+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]`.
238+
239+Example:
240+
241+```
242+> .^(=cass:clay %cs /(scot %p (sein:title our now our))/kids/1/late)
243+cass=[ud=50 da=~2021.4.22..10.38.50..57a8]
244+```
245+
246+```
247+> .^(=cass:clay %cs /~sampel/kids/1/late)
248+cass=[ud=0 da=~2000.1.1]
249+```
250+
251+### %base
252+
253+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`.
254+
255+Examples:
256+
257+```
258+> .^((list tako:clay) %cs /===/base/(scot %p (sein:title our now our))/kids)
259+~[102.787.244.596.033.419.950.995.540.301.493.841.569.518.772.322.508.085.465.561.801.703.148.627.263.473]
260+```
261+
262+```
263+> .^((list tako:clay) %cs /===/base/~sampel/kids)
264+~
265+```
266+
267+## %t
268+
269+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`.
270+
271+Examples:
272+
273+```
274+> .^((list path) %ct /===/app/landscape)
275+~[
276+ /app/landscape/css/index/css
277+ /app/landscape/img/favicon/png
278+ /app/landscape/img/imageupload/png
279+ /app/landscape/img/touch_icon/png
280+ /app/landscape/index/html
281+ /app/landscape/js/channel/js
282+]
283+```
284+
285+```
286+> .^((list path) %ct /===/gen/group-store/add/hoon)
287+~[/gen/group-store/add/hoon]
288+```
289+
290+```
291+> .^((list path) %ct /===/foobar)
292+~
293+```
294+
295+## %u
296+
297+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.
298+
299+Examples:
300+
301+```
302+> .^(? %cu /===/app)
303+%.n
304+```
305+
306+```
307+> .^(? %cu /===/gen/code/hoon)
308+%.y
309+```
310+
311+```
312+> .^(? %cu /===/foobar)
313+%.n
314+```
315+
316+## %v
317+
318+A scry with a care of `%v` will return the entire state of a `desk` as a `dome:clay`.
319+
320+Example:
321+
322+```
323+> =a .^(dome:clay %cv /===)
324+> let.a
325+1
326+```
327+
328+Note: If you try printing this it will take forever and probably OOM your ship.
329+
330+## %w
331+
332+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.
333+
334+Example:
335+
336+```
337+> .^(cass:clay %cw /===)
338+[ud=2 da=~2021.4.13..19.12.49..3389]
339+```
340+
341+## %x
342+
343+A scry with a `care` of `%x` will return the raw data of a file as an `@` or crash if it's a directory.
344+
345+
346+Examples:
347+
348+```
349+> .^(@ %cx /===/gen/hood/hi/hoon)
350+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
351+```
352+
353+```
354+> .^(@t %cx /===/gen/hood/hi/hoon)
355+':: Helm: send message to an urbit\0a::\0a:::: /hoon/hi/hood/gen\0a ::\0a/? 310\0a:- %say\0a|=([^ [who=ship mez=$@(~ [a=tape ~])] ~] helm-send-hi+[who ?~(mez ~ `a.mez)])\0a'
356+```
357+
358+```
359+> .^(@ %cx /===/gen/hood)
360+Crash!
361+```
362+
363+## %y
364+
365+A scry with a `care` of `%y` will return the `arch` of a file or directory.
366+
367+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.
368+
369+It will return the bunt of an `arch` if the file or directory is not found.
370+
371+Examples:
372+
373+```
374+> .^(arch %cy /===/gen/group-store)
375+[ fil=~
376+ dir
377+ { [p=~.allow-ships q=~]
378+ [p=~.add q=~]
379+ [p=~.ban-ranks q=~]
380+ [p=~.remove q=~]
381+ [p=~.create q=~]
382+ [p=~.join q=~]
383+ [p=~.allow-ranks q=~]
384+ [p=~.ban-ships q=~]
385+ }
386+]
387+```
388+
389+```
390+> .^(arch %cy /===/gen/group-store/allow-ships)
391+[fil=~ dir={[p=~.hoon q=~]}]
392+```
393+
394+```
395+> .^(arch %cy /===/gen/group-store/allow-ships/hoon)
396+[fil=[~ 0vb.g8sqs.7gjm9.bl3vu.nk677.h5be1.g9eg3.4v1jo.00ivf.g8ndu.48a53] dir={}]
397+```
398+
399+```
400+> .^(arch %cy /===/foobar)
401+[fil=~ dir={}]
402+```
403+
404+## %z
405+
406+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.
407+
408+The type returned is a `@uxI`.
409+
410+Examples:
411+
412+```
413+> .^(@uvI %cz /===/gen)
414+0v5.itmhj.lt7ak.lgr1k.dr7vu.u7u9s.ko5rf.idfcr.ukrd2.t088n.3ml1k
415+```
416+
417+```
418+> .^(@uvI %cz /===/gen/code/hoon)
419+0v1t.vi1pf.3ba4n.87g6h.dcc1p.4t4l8.rm6a9.b4de4.v77qc.p9dc0.p8289
420+```
421+
422+```
423+> .^(@uvI %cz /===/foobar)
424+0v0
425+```
content/docs/arvo/clay/tasks.mdnew file+555
@@ -0,0 +1,555 @@
1++++
2+title = "API Reference"
3+weight = 6
4+template = "doc.html"
5++++
6+
7+# Contents
8+
9+- [Introduction](#introduction)
10+- [%warp](#warp) - Read and Subscribe.
11+ - [%sing](#sing) - Read a file or directory.
12+ - [%next](#next) - Subscribe for the next change to a file or directory.
13+ - [%mult](#mult) - Subscribe for the next change to a set of files and/or directories.
14+ - [%many](#many) - Track changes to a `desk` for the specified range of revisions.
15+ - [Cancel Subscription](#cancel-subscription)
16+- [Write and Modify](#write-and-modify)
17+ - [%info](#info)
18+- [Manage Mounts](#manage-mounts)
19+ - [%boat](#boat) - List mounts.
20+ - [%mont](#mont) - Mount something.
21+ - [%ogre](#ogre) - Unmount something.
22+ - [%dirk](#dirk) - Commit changes.
23+- [Merge Desks](#merge-desks)
24+ - [%merg](#merg)
25+- [Permissions](#permissions)
26+ - [%perm](#perm) - Set file permissions.
27+ - [%cred](#cred) - Add permission group.
28+ - [%crew](#crew) - Get permission groups.
29+ - [%crow](#crow) - Get group usage.
30+- [Foreign Ships](#foreign-ships)
31+ - [%warp](#warp-remote) - Read a file on a foreign ship.
32+ - [%merg](#merg-remote) - Merge from a foreign `desk`.
33+
34+# Introduction
35+
36+This document details all the `task`s you're likely to use to interact with Clay, as well as the `gift`s you'll receive in response. Each section has a corresponding practical example in the [Examples](/docs/arvo/clay/examples) 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.
37+
38+The focus of this document is on interacting with Clay from userspace applications and threads, so it doesn't delve into the internal mechanics of Clay from a kernel development perspective.
39+
40+# `%warp`
41+
42+A `%warp` `task` is for reading a subscribing to files and directories.
43+
44+### Accepts
45+
46+```hoon
47+[wer=ship rif=riff]
48+```
49+
50+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:
51+
52+- `%sing` - Read a single file or directory.
53+- `%next` - Subscribe for the next change to a file or directory.
54+- `%mult` - Subscribe for the next change to a set of files and/or directories.
55+- `%many` - Track changes to a desk for the specified range of revisions.
56+
57+We'll look at each of these in more detail below.
58+
59+### Returns
60+
61+Clay responds to a `%mult` request with a `%wris` `gift`, and the rest with a `%writ` `gift`.
62+
63+A `%wris` `gift` looks like:
64+
65+```hoon
66+[%wris p=[%da p=@da] q=(set (pair care path))] :: many changes
67+```
68+
69+...and a `%writ` `gift` looks like:
70+
71+```hoon
72+[%writ p=riot] :: response
73+```
74+
75+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`.
76+
77+Now we'll look at each of the `rave` request types in turn.
78+
79+## `%sing`
80+
81+```hoon
82+[%sing =mood]
83+```
84+
85+This `rave` is for reading a single file or directory immediately.
86+
87+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.
88+
89+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`.
90+
91+### Example
92+
93+[See here for an example of using %sing.](/docs/arvo/clay/examples#sing)
94+
95+## `%next`
96+
97+```hoon
98+[%next =mood] :: await next version
99+```
100+
101+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.
102+
103+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`.
104+
105+### Example
106+
107+[See here for an example of using %next.](/docs/arvo/clay/examples#next)
108+
109+## `%mult`
110+
111+```hoon
112+[%mult =mool] :: next version of any
113+```
114+
115+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.
116+
117+The behaviour with respect to requesting old `case`s is the same as explained in the [`%next`](#next) section above.
118+
119+The `mool` specified in the request is this structure:
120+
121+```hoon
122++$ mool [=case paths=(set (pair care path))] :: requests in desk
123+```
124+
125+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.
126+
127+### Example
128+
129+[See here for an example of using %mult.](/docs/arvo/clay/examples#mult)
130+
131+## `%many`
132+
133+```hoon
134+[%many track=? =moat] :: track range
135+```
136+
137+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.
138+
139+If the `track` is `%.y` it will just return a `%writ` like:
140+
141+```hoon
142+[%writ p=[~ [p=[p=%w q=[%ud p=256] r=%home] q=/ r=[p=%null q=[#t/@n q=0]]]]]
143+```
144+
145+...that merely informs you of a change. If you want the actual data you'll have to request it separately.
146+
147+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.
148+
149+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.
150+
151+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.
152+
153+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:
154+
155+```hoon
156+[%writ p=~]
157+```
158+
159+### Example
160+
161+[See here for an example of using %many.](/docs/arvo/clay/examples#many)
162+
163+## Cancel Subscription
164+
165+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.
166+
167+### Example
168+
169+[See here for an example of cancelling a subscription.](/docs/arvo/clay/examples#cancel-subscription)
170+
171+# Write and Modify
172+
173+## `%info`
174+
175+To write or modify a file, we send Clay a `%info` `task`.
176+
177+### Accepts
178+
179+```hoon
180+[des=desk dit=nori]
181+```
182+
183+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:
184+
185+- `%del` - Delete a file.
186+- `%ins` - Insert file. This will also replace an existing file.
187+- `%dif` - This has not yet been implemented so will crash with a `%dif-not-implemented` error.
188+- `%mut` - Change a file. At the time of writing this behaves identically to `%ins` so its use merely informs the reader.
189+
190+### Returns
191+
192+Clay does not give any response to an `%info` `task` so don't expect a `sign` back.
193+
194+### Example
195+
196+Here are examples of using each of these as well as making multiple changes in one request:
197+
198+- [%del](/docs/arvo/clay/examples#del)
199+- [%ins](/docs/arvo/clay/examples#ins)
200+- [%mut](/docs/arvo/clay/examples#mut)
201+- [Multiple Changes](/docs/arvo/clay/examples#multiple-changes)
202+
203+
204+# Manage Mounts
205+
206+Here we'll look at managing Clay unix mounts programmatically.
207+
208+There are four Clay `task`s relevant to mounts:
209+
210+- [%boat](#boat) - List mounts.
211+- [%mont](#mont) - Mount something.
212+- [%ogre](#ogre) - Unmount something.
213+- [%dirk](#dirk) - Commit changes.
214+
215+## `%boat`
216+
217+A `%boat` `task` requests the list of existing mounts.
218+
219+### Accepts
220+
221+```hoon
222+~
223+```
224+
225+A `%boat` `task` does not take any arguments.
226+
227+### Returns
228+
229+The type it returns is a `%hill` `gift`, which looks like:
230+
231+```hoon
232+[%hill p=(list @tas)]
233+```
234+
235+...where the `@tas` is the name of the mount point.
236+
237+### Example
238+
239+[See here for an example of using %boat.](/docs/arvo/clay/examples#boat)
240+
241+## `%mont`
242+
243+
244+A `%mont` `task` mounts the specified `beam` to the specified `term` mount point.
245+
246+### Accepts
247+
248+```hoon
249+[pot=term bem=beam]
250+```
251+
252+A `beam:clay` is the following structure:
253+
254+```hoon
255++$ beam [[p=ship q=desk r=case] s=path] :: global name
256+```
257+
258+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).
259+
260+### Returns
261+
262+Clay does not return a `gift` in response to a `%mont` `%task`.
263+
264+### Example
265+
266+[See here for an example of using %mont.](/docs/arvo/clay/examples#mont)
267+
268+## `%ogre`
269+
270+A `%ogre` `task` unmounts the specified mount.
271+
272+### Accepts
273+
274+```hoon
275+[pot=$@(desk beam)]
276+```
277+
278+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.
279+
280+### Returns
281+
282+Clay does not return a `gift` in response to a `%ogre` `task`.
283+
284+### Example
285+
286+[See here for an example of using %ogre.](/docs/arvo/clay/examples#ogre)
287+
288+## `%dirk`
289+
290+A `%dirk` `task` commits changes in the target mount.
291+
292+### Accepts
293+
294+```hoon
295+des=desk
296+```
297+
298+It's defined in `lull.hoon` as taking a `desk` but like [%ogre](#ogre), it actually takes the name of a mount point rather than a `desk` as is specified.
299+
300+### Returns
301+
302+Clay does not return a `gift` in response to a `%dirk` `task`.
303+
304+### Example
305+
306+[See here for an example of using %dirk.](/docs/arvo/clay/examples#dirk)
307+
308+# Merge Desks
309+
310+## `%merg`
311+
312+A `%merg` `task` will merge the specified source `desk` into the target local `desk`.
313+
314+### Accepts
315+
316+```hoon
317+$: des=desk :: target
318+ her=@p dem=desk cas=case :: source
319+ how=germ :: method
320+==
321+```
322+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`.
323+
324+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.
325+
326+### Returns
327+
328+Clay will respond to the request with a `%mere` `gift` which looks like:
329+
330+```hoon
331+[%mere p=(each (set path) (pair term tang))] :: merge result
332+```
333+
334+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.
335+
336+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:
337+
338+```hoon
339+[ %mere
340+ p
341+ [ %.n
342+ p=[p=%mate-conflict q=~[[%rose p=[p="/" q="/" r=""] q=~[[%leaf p="foo"] [%leaf p="txt"]]]]]
343+ ]
344+]
345+```
346+
347+### Example
348+
349+[See here for an example of using %merg.](/docs/arvo/clay/examples#merg)
350+
351+# Permissions
352+
353+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.
354+
355+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".
356+
357+A group is called a `crew` and is just a `set` of ships with a `@ta` name.
358+
359+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.
360+
361+A `dict:clay` is this structure:
362+
363+```hoon
364++$ dict [src=path rul=real] :: effective permission
365+```
366+
367+The `src` path is where the permissions were inherited from and the `real` is this structure:
368+
369+```hoon
370+ +$ real :: resolved permissions
371+ $: mod=?(%black %white) ::
372+ who=(pair (set ship) (map @ta crew)) ::
373+ == ::
374+```
375+
376+So if we scry for permissions with a `%p` `care`, it'll look like:
377+
378+```hoon
379+> .^([r=dict:clay w=dict:clay] %cp /===/lib/strandio/hoon)
380+[r=[src=/ rul=[mod=%white who=[p={} q={}]]] w=[src=/ rul=[mod=%white who=[p={} q={}]]]]
381+```
382+
383+There are four permission-related `task`s which you can pass to Clay.
384+
385+A `%perm` `task` is for setting permissions, and the other three are for managing groups:
386+
387+- `%cred` - Add permission group.
388+- `%crew` - Get permission groups.
389+- `%crow` - Get group usage.
390+
391+We'll look at each of these in turn.
392+
393+## `%perm`
394+
395+A `%perm` `task` sets permissions for the target file or directory.
396+
397+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.
398+
399+### Accepts
400+
401+```hoon
402+[des=desk pax=path rit=rite]
403+```
404+
405+The `pax` path is the file or directory whose permissions you want to change, and the `rite` is this structure:
406+
407+```hoon
408++$ rite :: new permissions
409+ $% [%r red=(unit rule)] :: for read
410+ [%w wit=(unit rule)] :: for write
411+ [%rw red=(unit rule) wit=(unit rule)] :: for read and write
412+```
413+
414+Where a `rule` is this structure:
415+
416+```hoon
417++$ rule [mod=?(%black %white) who=(set whom)] :: node permission
418+```
419+
420+...and finally `whom` is this:
421+
422+```hoon
423++$ whom (each ship @ta) :: ship or named crew
424+```
425+
426+As the comment suggests, the `@ta` is the name of a `crew` (group).
427+
428+### Returns
429+
430+Clay does not return a `gift` in response to a `%perm` `task`.
431+
432+### Example
433+
434+[See here for an example of using %perm.](/docs/arvo/clay/examples#perm)
435+
436+## `%cred`
437+
438+This simply creates a permission group.
439+
440+### Accepts
441+
442+```hoon
443+[nom=@ta cew=crew]
444+```
445+
446+The `nom` is a name for the group and the `crew` is just a `(set ship)`:
447+
448+```hoon
449++$ crew (set ship) :: permissions group
450+```
451+
452+### Returns
453+
454+Clay does not return a `gift` in response to a `%cred` `task`.
455+
456+### Example
457+
458+[See here for an example of using %cred.](/docs/arvo/clay/examples#cred)
459+
460+## `%crew`
461+
462+This retrieves all permission groups.
463+
464+### Accepts
465+
466+```hoon
467+~
468+```
469+
470+A `%crew` `task` takes no arguments.
471+
472+### Returns
473+
474+Clay wil return a `%cruz` `gift`. It looks like:
475+
476+```hoon
477+[%cruz cez=(map @ta crew)] :: permission groups
478+```
479+
480+The `cez` is just a map from group name to `crew` which is just a `(set ship)`.
481+
482+### Example
483+
484+[See here for an example of using %crew.](/docs/arvo/clay/examples#crew)
485+
486+## `%crow`
487+
488+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.
489+
490+### Accepts
491+
492+```hoon
493+nom=@ta
494+```
495+
496+The `nom` is the name of a `crew`.
497+
498+### Returns
499+
500+The `gift` you get back is a `%croz` which looks like:
501+
502+```hoon
503+[%croz rus=(map desk [r=regs w=regs])] :: rules for group
504+```
505+
506+...where `regs` is this structure:
507+
508+```hoon
509++$ regs (map path rule) :: rules for paths
510+```
511+
512+### Example
513+
514+[See here for an example of using %crow.](/docs/arvo/clay/examples#crow)
515+
516+# Foreign Ships
517+
518+Here we'll looking at making Clay requests to a foreign ship.
519+
520+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.
521+
522+## `%warp` - Remote
523+
524+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) section.
525+
526+Clay only allows a subset of `care`s to be used remotely. They are:
527+
528+- `%u` - Check for existence of file.
529+- `%v` - Get entire `dome:clay` state of a desk.
530+- `%w` - Get revision number.
531+- `%x` - Get data of file.
532+- `%y` - Get `arch` of file or directory.
533+- `%z` - Get content hash of file or directory.
534+
535+Any other `care` will crash with a `%clay-bad-foreign-request-care` error.
536+
537+The foreign ship will respond only if correct permissions have been set. See the [Permissions](#permissions) section for details.
538+
539+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.
540+
541+### Example
542+
543+[See here for examples of requests to foreign ships.](/docs/arvo/clay/examples#foreign-ships)
544+
545+## `%merg` - Remote
546+
547+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.
548+
549+The foreign ship will respond only if correct permissions have been set. See the [Permissions](#permissions) section for details. By default, a ship's `%kids` desk is set to be publicly readable, so unless permissions have been manually modified, you should be able to merge from any `%kids` `desk`.
550+
551+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.
552+
553+### Example
554+
555+[See here for examples of requests to foreign ships.](/docs/arvo/clay/examples#foreign-ships)
content/docs/arvo/clay/using.mdnew file+217
@@ -0,0 +1,217 @@
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+|mount %/path/to/directory %mount-point
55+|commit %mount-point
56+|autocommit %mount-point
57+```
58+
59+One of the primary functions of Clay is as a convenient user
60+interface. While tools exist to use Clay from within Urbit, it's
61+often useful to be able to treat Clay like any other filesystem
62+from the Unix perspective -- to "mount" it, as it were.
63+
64+From the dojo, you can run `|mount %/path/to/directory %mount-point`, and this
65+will mount the given Clay directory to the mount-point directory in Unix, with
66+your pier as the root directory. For example `|mount %/gen %generators` will
67+create a `/generators` directory in your pier, and mount the `/gen` folder at
68+that point. If you'd like to use the directory name as the mount point, you can
69+elide the last argument, e.g. `|mount %/gen` mounts `/gen` to `/gen`.
70+
71+Every file is converted to `%mime` before it's written to Unix, and converted
72+back when read from Unix. The entire directory is watched (a la Dropbox), and
73+every change is committed once you run `|commit %mount-point`. Every change can
74+be automatically committed with `|autocommit %mount-point`.
75+
76+### Merging
77+
78+Usage:
79+```
80+|merge %target-desk ~source-ship %source-desk
81+|merge %target-desk ~source-ship %source-desk, =gem %strategy
82+|merge %target-desk ~source-ship %source-desk, =cas ud+5
83+```
84+
85+Clay supports various merge strategies. A "commit" is a snapshot of
86+the files with a list of parents plus a date. Most commits have
87+one parent; a "merge" commit is a commit with two parents. The
88+%home `desk` starts with an initial commit with no parents; commits
89+with several parents ("octopus merges") are possible but we don't
90+generate them right now.
91+
92+Unless otherwise specified, all of the following create a new commit
93+with the source and destination commits as parents.
94+
95+Several strategies need a "merge-base". They find it by identifying
96+the most recent common ancestor of the two `desk`s. If none, fail
97+with `%merge-no-merge-base`; if there are two or more, pick one.
98+
99+#### Strategies
100+
101+**`%init`**: the only way to create a `desk`. Not a true merge, since it
102+simply assigns the source commit to the destination.
103+
104+**`%fine`**: if source or destination are in the ancestry of each other,
105+use the newer one; else abort. If the destination is ahead of the
106+source, succeed but do nothing. If the source is ahead of the
107+destination, assign the next revision number to the source commit.
108+Some call this "fast-forward".
109+
110+**`%meet`**: combine changes, failing if both sides changed the same file.
111+Specifically, take diff(merge-base,source) and
112+diff(merge-base,destination) and combine them as long as those diffs
113+touch different files.
114+
115+**`%mate`**: combine changes, failing if both sides changed the same part
116+of a file. Identical to `%meet`, except that some marks, like `%hoon`,
117+allow intelligent merge of changes to different parts of a file.
118+
119+**`%meld`**: combine changes; if both sides changed the same part of a
120+file, use the version of the file in the merge-base.
121+
122+**`%only-this`**: create a merge commit with exactly the contents of the
123+destination `desk`.
124+
125+**`%only-that`**: create a merge commit with exactly the contents of the
126+source commit.
127+
128+**`%take-this`**: create a merge commit with exactly the contents of the
129+destination `desk` except take any files from the source commit which
130+are not in the destination `desk`.
131+
132+**`%take-that`**: create a merge commit with exactly the contents of the
133+source commit except preserve any files from the destination `desk`
134+which are not in the source commit.
135+
136+**`%meet-this`**: merge as in `%meet`, except if both sides changed the same
137+file, use the version in the destination `desk`.
138+
139+**`%meet-that`**: merge as in `%meet`, except if both sides changed the same
140+file, use the version in the source commit.
141+
142+#### Examples and notes:
143+
144+The most common merge strategy is `%mate`, which is a normal 3-way
145+merge which aborts on conflict.
146+
147+`%take-that` is useful to "force" an OTA. After running `%take-that`,
148+you're guaranteed to have exactly the files in the source commit plus
149+any files you separately added.
150+
151+We speak of merging into a destination *`desk`* from a source *commit*
152+because while you can only merge on top of a `desk`, you can merge from
153+historical commits. For example,
154+```
155+|merge %old our %home, =cas ud+5, =gem %init
156+```
157+will create a new `desk` called `%old` with the 5th commit in `%home`.
158+You can revert the contents of a `desk` to what they were yesterday
159+with
160+```
161+|merge %home our %home, =cas da+(sub now ~d1), =gem %only-that
162+```
163+
164+Note this is a normal `%only-that merge`, which means you're creating a
165+*new* commit with the old *contents*.
166+
167+`%meld` is rarely used on its own, however if you specify `%auto` or
168+omit the merge strategy, `%kiln` will run a `%meld` merge into a scratch
169+`desk` and then annotate the conflicts there.
170+
171+If you resolve merge conflicts manually, for example by mounting the
172+`desk`s, copying the files in Unix and then running `|commit`, you
173+should usually run an `%only-this merge`. This will not change the
174+newly-fixed contents of your `desk`, but it will record that the merge
175+happened so that those conflicts don't reappear in later merges.
176+
177+If you get a `%merge-no-merge-base` error, this means you're trying to
178+merge two `desk`s which have no common ancestors. You need to give
179+them a common ancestor by choosing a merge strategy which doesn't
180+need a merge-base, like `%only-this`, `%only-that`, `%take-this`, or
181+`%take-that`.
182+
183+`%take-this` could be useful to install 3rd party software, but you
184+couldn't get subsequent updates this way, since the files would
185+already exist in the destination `desk`. Something like "take only
186+the files which aren't in my OTA source or any other 3rd party app"
187+would be basically correct. This would require a parameter listing
188+the `desk`s to not conflict with.
189+
190+`%meet-this` and `%meet-that` imply the existence of `%mate-this` and
191+`%mate-that`, but those don't exist yet.
192+
193+### Autosync
194+
195+Usage:
196+```
197+|sync %target-desk ~source-ship %source-desk
198+```
199+
200+Tracking and staying in sync with another `desk` is another
201+fundamental operation. We call this "autosync". This doesn't mean
202+simply mirroring a `desk`, since that wouldn't allow local changes.
203+We simply want to apply changes as they are made upstream, as
204+long as there are no conflicts with local changes.
205+
206+This is implemented by subscribing to changes to the other `desk`, with a
207+`%many` request and, when it has changes, merging these changes into our `desk`
208+with the usual merge strategies.
209+
210+Note that it's quite reasonable for two `desk`s to be autosynced to
211+each other. This results in any change on one `desk` being mirrored
212+to the other and vice versa.
213+
214+Additionally, it's fine to set up an autosync even if one `desk`,
215+the other `desk`, or both `desk`s do not exist. The sync will be
216+activated when the upstream `desk` comes into existence and will
217+create the downstream `desk` if needed.
content/docs/arvo/concepts/_index.mdnew file+13
@@ -0,0 +1,13 @@
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+## [Subscriptions](/docs/arvo/concepts/subscriptions)
12+
13+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/subscriptions.mdnew file+162
@@ -0,0 +1,162 @@
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 publisher 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 taks 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.mdnew file+7
@@ -0,0 +1,7 @@
1++++
2+title = "Dill"
3+weight = 40
4+sort_by = "weight"
5+template = "sections/docs/chapters.html"
6+insert_anchor_links = "right"
7++++
content/docs/arvo/dill/dill-api.mdnew file+366
@@ -0,0 +1,366 @@
1++++
2+title = "API Reference"
3+weight = 10
4+template = "doc.html"
5++++
6+
7+In this document we describe the public interface for Dill. Namely, we describe
8+each `task` that Dill can be `pass`ed, and which `gift`(s) Dill can `give` in return.
9+
10+Dill is unique among vanes since it is technically the first vane to be booted (though we
11+regard Jael as the "true" first vane). As a result, there are four `task`s in
12+`task:able:dill` for which Dill acts only as a middleman that passes the `task`s
13+directly to the Arvo kernel. Thus we have split this document into a [Dill
14+tasks](#dill-tasks) section and an [Arvo tasks](#arvo-tasks) section.
15+
16+## Dill Tasks
17+
18+
19+### `%belt`
20+
21+Every keystroke entered into the console triggers a `%belt` `task` for Dill which contains information about the keystroke, such as which key was pressed
22+and from which terminal.
23+
24+#### Accepts
25+
26+`%belt` `task`s come in a number of different types, corresponding to different
27+keystrokes. You can find this list in `+dill-belt` in `zuse.hoon`.
28+
29+```hoon
30+++ dill-belt :: new belt
31+ $% {$aro p/?($d $l $r $u)} :: arrow key
32+ {$bac ~} :: true backspace
33+ {$cru p/@tas q/(list tank)} :: echo error
34+ {$ctl p/@} :: control-key
35+ {$del ~} :: true delete
36+ {$hey ~} :: refresh
37+ {$met p/@} :: meta-key
38+ {$ret ~} :: return
39+ {$rez p/@ud q/@ud} :: resize, cols, rows
40+ {$txt p/(list @c)} :: utf32 text
41+ {$yow p/gill:gall} :: connect to app
42+ == ::
43+```
44+
45+#### Returns
46+
47+Dill returns no `gift` in response to a `%belt` `task`.
48+
49+
50+### `%blew`
51+
52+This `task` is called whenever the terminal emulator is resized, so that Dill can adjust
53+the text output to fit the new window size.
54+
55+#### Accepts
56+
57+```hoon
58+[p=@ud q=@ud]
59+```
60+
61+`p` is the number of columns and `q` is the number of rows.
62+
63+#### Returns
64+
65+Dill returns no `gift` in response to a `%blew` `task`.
66+
67+
68+### `%boot`
69+
70+This `task` is used only once, when Arvo first enters the [adult
71+stage](/docs/arvo/overview#structural-interface-core). Dill is
72+technically the first vane to be activated, via the `%boot` `task`, which then
73+send Jael (considered the the "true" first vane) an `%init` `task`, which then goes on to
74+call `%init` `task`s for other vanes (including Dill).
75+
76+#### Accepts
77+
78+`%boot` takes an argument that is either `%dawn` or `%fake`. `%dawn` is the one
79+used in any typical scenario and activates the ordinary vane initialization
80+process outlined above, while `%fake` is a debugging tool.
81+
82+#### Returns
83+
84+`%boot` does not return a `gift`.
85+
86+
87+
88+### `%crud`
89+
90+This `task` is used by Dill to produce error reports. It prints the received
91+error message(s) (a `(list tank)`) to the terminal. The level of detail of the
92+error message is set by `$log-level`, which is either `%hush`, `%soft`, or `%loud`.
93+
94+#### Accepts
95+
96+```hoon
97+[err=@tas tac=(list tank)]
98+```
99+
100+`err` is the type of error and `tac` is the associated error message.
101+
102+#### Returns
103+
104+`%crud` does not return a `gift`.
105+
106+
107+### `%flog`
108+
109+A `%flog` `task` is a wrapper over a `task` sent by another vane. Dill removes the wrapper
110+and sends the bare `task` to itself over the default `duct`.
111+
112+#### Accepts
113+
114+`%flog` `task`s can take any valid Dill `task` as an argument.
115+
116+#### Returns
117+
118+`%flog` never returns a `gift` on its own, but the wrapped `task` might.
119+
120+#### Example
121+
122+`%crud` `task`s from other vanes are typically passed to Dill wrapped in a
123+`%flog` `task` to print errors to the terminal.
124+
125+
126+
127+### `%flow`
128+
129+This `task` is not used.
130+
131+
132+### `%hail`
133+
134+`%hail` refreshes the terminal by sending an empty message to the default duct
135+for Dill,
136+causing the terminal to redraw itself (?)
137+
138+#### Accepts
139+
140+```hoon
141+[ ~ ]
142+```
143+
144+#### Returns
145+
146+`%hail` returns no `gift`s.
147+
148+
149+### `%heft`
150+
151+`%heft` causes Dill to `pass` a `%wegh` `task` to all other vanes (but not to
152+itself), thus obtaining a complete digest of Arvo's memory usage.
153+
154+#### Accepts
155+
156+```hoon
157+[ ~ ]
158+```
159+
160+#### Returns
161+
162+`%heft` does not directly return any `gift`s, but each `%wegh` `task` sent will
163+return a `%mass` `gift`.
164+
165+
166+### `%hook`
167+
168+This task is not used.
169+
170+
171+### `%harm`
172+
173+This `task` is not used.
174+
175+
176+### `%init`
177+
178+This `task` is called only once, when Arvo first enters the [adult
179+stage](/docs/arvo/overview#structural-interface-core). It performs
180+initial setup for Dill, such as setting the width of the console.
181+
182+Note that this is not actually the first `task` passed to Dill - see [%boot](#%boot).
183+
184+#### Accepts
185+
186+`%init` takes no arguments.
187+
188+#### Returns
189+
190+`%init` returns no `gift`s.
191+
192+
193+### `%knob`
194+
195+`%knob` sets the verbosity level for each error tag.
196+
197+#### Accepts
198+
199+```hoon
200+[tag=@tas level=log-level]
201+```
202+
203+`tag` is the error tag. `level` is the verbosity, set to either `%hush`,
204+`%soft`, or `%loud`.
205+
206+#### Returns
207+
208+`%knob` does not return a gift.
209+
210+
211+
212+
213+### `%noop`
214+
215+`%noop` does nothing - it stands for "no operation".
216+
217+#### Accepts
218+
219+```hoon
220+[ ~ ]
221+```
222+
223+#### Returns
224+
225+This `task`, predictably, returns nothing.
226+
227+#### Example
228+
229+This can be useful if a shell command requires a Dill `task` but you don't want
230+Dill to do anything.
231+
232+
233+
234+### `%talk`
235+
236+This `task` is not used.
237+
238+### `%text`
239+
240+This `task` prints a `tape` to the dojo by first converting it from a UTF8
241+`tape` to a `list` of UTF32 codepoints (`@c`'s) and then recursively popping off a character from the
242+`tape` and sending it to to Unix to be printed into the terminal via a `%blit` event.
243+
244+#### Accepts
245+
246+```hoon
247+[p=tape]
248+```
249+
250+#### Returns
251+
252+This `task` returns zero or more `%blit` `gift`s, each containing a .
253+
254+
255+### `%trim`
256+
257+`%trim` is a common vane `task` used to reduce memory usage. However, it does
258+nothing for Dill.
259+
260+#### Accepts
261+
262+```hoon
263+[p=@ud]
264+```
265+
266+This is a common parameter for `%trim` `task`s across all vanes but does nothing
267+for Dill.
268+
269+#### Returns
270+
271+This `task` returns no `gift`s.
272+
273+
274+
275+### `%vega`
276+
277+This is a common vane `task` used to inform the vane that the kernel has been
278+upgraded. Dill does not do anything in response to this.
279+
280+#### Accepts
281+
282+```hoon
283+[ ~ ]
284+```
285+
286+#### Returns
287+
288+This `task` returns no `gift`s.
289+
290+
291+
292+## Arvo tasks
293+
294+These `task`s live in `task:able:dill` but are passed directly to the Arvo
295+kernel for processing.
296+
297+### `%lyra`
298+
299+This `task` updates the kernel.
300+
301+#### Accepts
302+
303+```hoon
304+[p=@t q=@t]
305+```
306+
307+`p` is the contents of the new `hoon.hoon` and `q` is the contents of the new `arvo.hoon`.
308+
309+#### Returns
310+
311+This `task` returns no `gift`s.
312+
313+
314+### `%pack`
315+
316+This `task` defragments and deduplicates Arvo's memory. This is ultimately
317+performed by the interpreter so you won't find the code in `arvo.hoon` but
318+rather under `c3__pack` in `urbit/worker/main.c`.
319+
320+#### Accepts
321+
322+```hoon
323+[ ~ ]
324+```
325+
326+#### Returns
327+
328+This `task` returns no `gift`s.
329+
330+
331+### `%veer`
332+
333+This `task` is used to install `zuse` and vanes. It is handled by `+veer` in
334+`arvo.hoon`.
335+
336+#### Accepts
337+
338+```hoon
339+[p=@ta q=path r=@t]
340+```
341+
342+`p` is the vane letter, `q` is the formal `path` to the
343+vane, and `r` is the source code for the vane. The vane letter is `%` followed
344+by the first letter of the vane in lowercase, such as `%d` for Dill. `p=%$` in
345+the case of `zuse`.
346+
347+#### Returns
348+
349+This `task` returns no `gift`s.
350+
351+
352+### `%verb`
353+
354+This `task` toggles verbose mode for all of Arvo, which is located here since
355+Dill is the vane that prints errors. To be precise, `%verb` toggles the laconic
356+bit `lac` in the [Arvo state](/docs/arvo/overview#the-state).
357+
358+#### Accepts
359+
360+```hoon
361+[ ~ ]
362+```
363+
364+#### Returns
365+
366+This `task` returns no `gift`s.
content/docs/arvo/dill/dill.mdnew file+24
@@ -0,0 +1,24 @@
1++++
2+title = "Overview"
3+weight = 1
4+template = "doc.html"
5+aliases = ["/docs/learn/arvo/dill/"]
6++++
7+Our terminal driver.
8+
9+Unix sends keyboard events to `%dill` from either the console or telnet,
10+and `%dill` produces terminal output. The only app that should directly
11+talk to `%dill` is the terminal app. Command-line apps are run by,
12+receive input from, and produce output to, the `%shell` app, which is
13+controlled by `%terminal`, which talks to `%dill`, which talks to unix.
14+Clay also uses `%dill` directly to print out the filesystem change
15+events, but this is questionable behavior.
16+
17+`%dill` has two main components. First, it controls the terminal on a
18+very basic, event-by-event level. This includes keeping track of things
19+like the dimensions of the terminal, the prompt type (plain text or
20+password), which duct to produce effects on, and so forth. Second, it
21+handles terminal events, keystroke by keystroke. Most characters are
22+simply pushed onto the buffer and blitted to the screen, but some
23+characters, including control-modified keys, arrow keys, etc. require
24+special handling. Most of the readline functionality is in `%dill`.
content/docs/arvo/eyre/_index.mdnew file+31
@@ -0,0 +1,31 @@
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.md)
18+
19+The `task`s Eyre takes and the `gift`s it returns.
20+
21+## [Scry Reference](@/docs/arvo/eyre/scry.md)
22+
23+The scry endpoints of Eyre.
24+
25+## [Data Types](@/docs/arvo/eyre/data-types.md)
26+
27+Reference documentation of the various data types used by Eyre.
28+
29+## [Examples](@/docs/arvo/eyre/examples.md)
30+
31+Practical examples of the different ways of using Eyre.
content/docs/arvo/eyre/data-types.mdnew file+290
@@ -0,0 +1,290 @@
1++++
2+title = "Data Types"
3+weight = 5
4+template = "doc.html"
5++++
6+
7+# Introduction
8+
9+This document describes the data types used by Eyre as defined in `/sys/lull.hoon`. It's separated into two sections:
10+
11+- [Eyre](#eyre) - Eyre-specific data types.
12+- [HTTP](#http) - HTTP data types shared between Eyre and Iris.
13+
14+# Eyre
15+
16+## `$origin`
17+
18+```hoon
19++$ origin @torigin
20+```
21+
22+A single CORS origin as used in an HTTP Origin header and the [$cors-registry](#cors-registry).
23+
24+## `$cors-registry`
25+
26+```hoon
27++$ cors-registry
28+ $: requests=(set origin)
29+ approved=(set origin)
30+ rejected=(set origin)
31+ ==
32+```
33+
34+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.
35+
36+## `$outstanding-connection`
37+
38+```hoon
39++$ outstanding-connection
40+ $: =action
41+ =inbound-request
42+ response-header=(unit response-header:http)
43+ bytes-sent=@ud
44+ ==
45+```
46+
47+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.
48+
49+## `$authentication-state`
50+
51+```hoon
52++$ authentication-state sessions=(map @uv session)
53+```
54+
55+This represents the authentication state of all sessions. It maps session cookies (without the `urbauth-<ship>=` prefix) to [$session](#session)s.
56+
57+## `$session`
58+
59+```hoon
60++$ session
61+ $: expiry-time=@da
62+ channels=(set @t)
63+ ==
64+```
65+
66+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.
67+
68+## `$channel-state`
69+
70+```hoon
71++$ channel-state
72+ $: session=(map @t channel)
73+ duct-to-key=(map duct @t)
74+ ==
75+```
76+
77+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.
78+
79+## `$timer`
80+
81+```hoon
82++$ timer
83+ $: date=@da
84+ =duct
85+ ==
86+```
87+
88+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.
89+
90+## `$channel-event`
91+
92+```hoon
93++$ channel-event
94+ $% $>(%poke-ack sign:agent:gall)
95+ $>(%watch-ack sign:agent:gall)
96+ $>(%kick sign:agent:gall)
97+ [%fact =mark =noun]
98+ ==
99+```
100+
101+An unacknowledged event in the channel system.
102+
103+## `$channel`
104+
105+```hoon
106++$ channel
107+ $: state=(each timer duct)
108+ next-id=@ud
109+ last-ack=@da
110+ events=(qeu [id=@ud request-id=@ud =channel-event])
111+ unacked=(map @ud @ud)
112+ subscriptions=(map @ud [ship=@p app=term =path duc=duct])
113+ heartbeat=(unit timer)
114+ ==
115+```
116+
117+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).
118+
119+## `$binding`
120+
121+```hoon
122++$ binding
123+ $: site=(unit @t)
124+ path=(list @t)
125+ ==
126+```
127+
128+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.
129+
130+## `$action`
131+
132+```hoon
133++$ action
134+ $% [%gen =generator] :: dispatch to a generator
135+ [%app app=term] :: dispatch to an application
136+ [%authentication ~] :: internal authentication page
137+ [%logout ~] :: internal logout page
138+ [%channel ~] :: gall channel system
139+ [%scry ~] :: gall scry endpoint
140+ [%four-oh-four ~] :: respond with the default file not found page
141+ ==
142+```
143+
144+The action to take when a [$binding](#binding) matches an incoming HTTP request.
145+
146+## `$generator`
147+
148+```hoon
149++$ generator
150+ $: =desk :: desk on current ship that contains the generator
151+ path=(list @t) :: path on :desk to the generator's hoon file
152+ args=* :: args: arguments passed to the gate
153+ ==
154+```
155+
156+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.
157+
158+## `$http-config`
159+
160+```hoon
161++$ http-config
162+ $: secure=(unit [key=wain cert=wain])
163+ proxy=_|
164+ log=?
165+ redirect=?
166+ ==
167+```
168+
169+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`.
170+
171+## `$http-rule`
172+
173+```hoon
174++$ http-rule
175+ $% [%cert cert=(unit [key=wain cert=wain])]
176+ [%turf action=?(%put %del) =turf]
177+ ==
178+```
179+
180+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.
181+
182+## `$address`
183+
184+```hoon
185++$ address
186+ $% [%ipv4 @if]
187+ [%ipv6 @is]
188+ ==
189+```
190+
191+A client IP address.
192+
193+## `$inbound-request`
194+
195+```hoon
196++$ inbound-request
197+ $: authenticated=?
198+ secure=?
199+ =address
200+ =request:http
201+ ==
202+```
203+
204+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](#request-http) contains the HTTP request itself.
205+
206+# HTTP
207+
208+## `$header-list:http`
209+
210+```hoon
211++$ header-list (list [key=@t value=@t])
212+```
213+
214+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`.
215+
216+## `$method:http`
217+
218+```hoon
219++$ method
220+ $? %'CONNECT'
221+ %'DELETE'
222+ %'GET'
223+ %'HEAD'
224+ %'OPTIONS'
225+ %'POST'
226+ %'PUT'
227+ %'TRACE'
228+ ==
229+```
230+
231+An HTTP method.
232+
233+## `$request:http`
234+
235+```hoon
236++$ request
237+ $: method=method
238+ url=@t
239+ =header-list
240+ body=(unit octs)
241+ ==
242+```
243+
244+A single HTTP request. The [$method:http](#method-http) is the HTTP method, the `url` is the unescaped URL, the [$header-list:http](#header-list-http) 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.
245+
246+## `$response-header:http`
247+
248+```hoon
249++$ response-header
250+ $: status-code=@ud
251+ headers=header-list
252+ ==
253+```
254+
255+The status code and [$header-list:http](#header-list-http) of an HTTP response.
256+
257+## `$http-event:http`
258+
259+```hoon
260++$ http-event
261+ $% $: %start
262+ =response-header
263+ data=(unit octs)
264+ complete=?
265+ ==
266+ $: %continue
267+ data=(unit octs)
268+ complete=?
269+ ==
270+ [%cancel ~]
271+ ==
272+```
273+
274+Packetized HTTP.
275+
276+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.
277+
278+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.
279+
280+## `$simple-payload:http`
281+
282+```hoon
283++$ simple-payload
284+ $: =response-header
285+ data=(unit octs)
286+ ==
287+--
288+```
289+
290+A simple, one-event response used for generators. The [$reponse-header:http](#response-header-http) 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/examples.mdnew file+625
@@ -0,0 +1,625 @@
1++++
2+title = "Examples"
3+weight = 6
4+template = "doc.html"
5++++
6+
7+# Contents
8+
9+- [Introduction](#introduction)
10+- [Authenticating](#authenticating)
11+- [Using the Channel System](#using-the-channel-system)
12+- [Scrying](#scrying)
13+- [Direct HTTP Handling With Gall Agents](#direct-http-handling-with-gall-agents)
14+- [Generators](#generators)
15+- [Managing CORS Origins](#managing-cors-origins)
16+
17+# Introduction
18+
19+This documents contains practical examples of the various ways of interacting with Eyre.
20+
21+General documentation of the `task`s and methods described here are available in the [External API Reference](@/docs/arvo/eyre/external-api-ref.md) document and the [Internal API Reference](@/docs/arvo/eyre/tasks.md) document.
22+
23+# Authenticating
24+
25+In most cases we must obtain a valid session cookie by [authenticating](@/docs/arvo/eyre/external-api-ref.md#authentication) with our web login code (which can be obtained by running `+code` in the dojo) before we can use Eyre's interfaces (such as the channel system or scry interface).
26+
27+Here we'll try authenticating with the default fakezod code.
28+
29+Using `curl` in the unix terminal, we'll make an HTTP POST request with `"password=<code>"` in the body:
30+
31+```
32+curl -i localhost:8080/~/login -X POST -d "password=lidlut-tabwed-pillex-ridrup"
33+```
34+
35+Eyre will respond with HTTP status 204, and a `set-cookie` header containing the session cookie.
36+
37+```
38+HTTP/1.1 204 ok
39+Date: Tue, 18 May 2021 01:38:48 GMT
40+Connection: keep-alive
41+Server: urbit/vere-1.5
42+set-cookie: urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm; Path=/; Max-Age=604800
43+```
44+
45+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.
46+
47+# Using The Channel System
48+
49+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.md#channels) section of the [External API Reference](@/docs/arvo/eyre/external-api-ref.md) document for relevant details.
50+
51+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.
52+
53+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.
54+
55+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.
56+
57+The data will be a JSON array containing a [poke](@/docs/arvo/eyre/external-api-ref.md#poke) `action`:
58+
59+```
60+curl --header "Content-Type: application/json" \
61+ --cookie "urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm" \
62+ --request PUT \
63+ --data '[{"id":1,"action":"poke","ship":"zod","app":"hood","mark":"helm-hi","json":"Opening airlock"}]' \
64+ http://localhost:8080/~/channel/my-channel
65+```
66+
67+If we now have a look in the dojo we'll see it's printed our message, so the poke was successful:
68+
69+```
70+< ~zod: Opening airlock
71+```
72+
73+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:
74+
75+```
76+curl -i --cookie "urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm" http://localhost:8080/~/channel/my-channel
77+```
78+
79+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.md#poke-ack) `response` for our original poke:
80+
81+```
82+HTTP/1.1 200 ok
83+Date: Tue, 18 May 2021 01:40:47 GMT
84+Connection: keep-alive
85+Server: urbit/vere-1.5
86+set-cookie: urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm; Path=/; Max-Age=604800
87+connection: keep-alive
88+cache-control: no-cache
89+content-type: text/event-stream
90+transfer-encoding: chunked
91+
92+id: 0
93+data: {"ok":"ok","id":1,"response":"poke"}
94+```
95+
96+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.
97+
98+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.
99+
100+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.md#subscribe) `action`:
101+
102+```
103+curl --header "Content-Type: application/json" \
104+ --cookie "urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm" \
105+ --request PUT \
106+ --data '[{"id":2,"action":"subscribe","ship":"zod","app":"graph-store","path":"/updates"}]' \
107+ http://localhost:8080/~/channel/my-channel
108+```
109+
110+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.
111+
112+Back in the event stream, we'll see a positive watch ack as a [subscribe](@/docs/arvo/eyre/external-api-ref.md#watch-ack) `response`, meaning the subscription has been successful:
113+
114+```
115+id: 1
116+data: {"ok":"ok","id":2,"response":"subscribe"}
117+```
118+
119+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.md#diff) `response`:
120+
121+```
122+id: 2
123+data: {"json":{"graph-update":{"add-graph":{"graph":{},"resource":{"name":"test-1183","ship":"zod"},"mark":"graph-validator-chat","overwrite":false}}},"id":2,"response":"diff"}
124+```
125+
126+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.md#ack) `action` which specifies the `event-id` of the event in question - `2` in this case:
127+
128+```
129+curl --header "Content-Type: application/json" \
130+ --cookie "urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm" \
131+ --request PUT \
132+ --data '[{"id":3,"action":"ack","event-id":2}]' \
133+ http://localhost:8080/~/channel/my-channel
134+```
135+
136+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.
137+
138+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.md#unsubscribe) `action`, and specify the request ID of the original `subscribe` `action` in the `subscription` field - `2` in our case:
139+
140+```
141+curl --header "Content-Type: application/json" \
142+ --cookie "urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm" \
143+ --request PUT \
144+ --data '[{"id":4,"action":"unsubscribe","subscription":2}]' \
145+ http://localhost:8080/~/channel/my-channel
146+```
147+
148+Unlike `poke` and `subscribe` actions, Eyre doesn't acknowledge `unsubscribe`s, but we'll now have stopped receiving updates from `graph-store`.
149+
150+Finally, let's close the channel itself. We can do this simply by sending Eyre a [delete](@/docs/arvo/eyre/external-api-ref.md#delete-channel) `action`:
151+
152+```
153+curl --header "Content-Type: application/json" \
154+ --cookie "urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm" \
155+ --request PUT \
156+ --data '[{"id":5,"action":"delete"}]' \
157+ http://localhost:8080/~/channel/my-channel
158+```
159+
160+With our channel deleted, we can now close the connection on the client side.
161+
162+# Scrying
163+
164+Here we'll look at performing scries through Eyre. You can refer to the [Scry](@/docs/arvo/eyre/external-api-ref.md#scry) section of the [External API Reference](@/docs/arvo/eyre/external-api-ref.md) document for relevant details.
165+
166+First we must obtain a session cookie by [authenticating](#authenticating).
167+
168+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.
169+
170+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`.
171+
172+The request will be an HTTP GET request:
173+
174+```
175+curl -i --cookie "urbauth-~zod=0v1.1pseu.tq7hs.hps2t.ltaf1.tmqjm" \
176+ --request GET \
177+ http://localhost:8080/~/scry/graph-store/keys.json
178+```
179+
180+Eyre will respond with HTTP status 200 if it's successful and the body of the response will contain the data we requested:
181+
182+```
183+HTTP/1.1 200 ok
184+Date: Fri, 04 Jun 2021 10:16:32 GMT
185+Connection: keep-alive
186+Content-Length: 61
187+Server: urbit/vere-1.5
188+set-cookie: urbauth-~zod=0v1.1pseu.tq7hs.hps2t.ltaf1.tmqjm; Path=/; Max-Age=604800
189+content-type: application/json
190+
191+{"graph-update":{"keys":[{"name":"test-1183","ship":"zod"}]}}
192+```
193+
194+Now let's make a request to a non-existent scry endpoint:
195+
196+```
197+curl -i --cookie "urbauth-~zod=0v1.1pseu.tq7hs.hps2t.ltaf1.tmqjm" \
198+ --request GET \
199+ http://localhost:8080/~/scry/foo/bar/baz.json
200+```
201+
202+Eyre will respond with a 404 Missing status and an error message:
203+
204+```
205+HTTP/1.1 404 missing
206+Date: Fri, 04 Jun 2021 10:22:51 GMT
207+Connection: keep-alive
208+Content-Length: 187
209+Server: urbit/vere-1.5
210+set-cookie: urbauth-~zod=0v1.1pseu.tq7hs.hps2t.ltaf1.tmqjm; Path=/; Max-Age=604800
211+content-type: text/html
212+
213+<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>
214+```
215+
216+# Direct HTTP Handling With Gall Agents
217+
218+In many cases you'll just want to interact with Gall agents through the JSON API of the channel system, but it's also possible to bypass all that and just deal with HTTP requests directly. Here we'll take a look at how that practically works.
219+
220+You can refer to the [%connect](@/docs/arvo/eyre/tasks.md#connect) section of the [Internal API Reference](@/docs/arvo/eyre/tasks.md) document for relevant details.
221+
222+Here's a Gall agent that demonstrates this method. It binds the URL path `/foo`, serves `<h1>Hello, World!</h1>` for GET requests and a `405` error for all others. It also prints debug information to the terminal as various things happen.
223+
224+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.
225+
226+`eyre-agent.hoon`
227+
228+```hoon
229+/+ default-agent, dbug
230+=* card card:agent:gall
231+%- agent:dbug
232+^- agent:gall
233+|_ =bowl:gall
234++* this .
235+ def ~(. (default-agent this %|) bowl)
236+::
237+++ on-init on-init:def
238+++ on-save on-save:def
239+++ on-load on-load:def
240+++ on-poke
241+ |= [=mark =vase]
242+ ^- (quip card _this)
243+ ?+ mark
244+ (on-poke:def [mark vase])
245+ ::
246+ %noun
247+ ?. =(q.vase %bind)
248+ %- (slog leaf+"Bad argument." ~)
249+ `this
250+ %- (slog leaf+"Attempting to bind /foo." ~)
251+ :_ this
252+ [%pass /bind-foo %arvo %e %connect `/'foo' %eyre-agent]~
253+ ::
254+ %handle-http-request
255+ =/ req !< (pair @ta inbound-request:eyre) vase
256+ ~& [mark req]
257+ ?+ method.request.q.req
258+ =/ data=octs
259+ (as-octs:mimes:html '<h1>405 Method Not Allowed</h1>')
260+ =/ content-length=@t
261+ (crip ((d-co:co 1) p.data))
262+ =/ =response-header:http
263+ :- 405
264+ :~ ['Content-Length' content-length]
265+ ['Content-Type' 'text/html']
266+ ['Allow' 'GET']
267+ ==
268+ :_ this
269+ :~
270+ [%give %fact [/http-response/[p.req]]~ %http-response-header !>(response-header)]
271+ [%give %fact [/http-response/[p.req]]~ %http-response-data !>(`data)]
272+ [%give %kick [/http-response/[p.req]]~ ~]
273+ ==
274+ ::
275+ %'GET'
276+ =/ data=octs
277+ (as-octs:mimes:html '<h1>Hello, World!</h1>')
278+ =/ content-length=@t
279+ (crip ((d-co:co 1) p.data))
280+ =/ =response-header:http
281+ :- 200
282+ :~ ['Content-Length' content-length]
283+ ['Content-Type' 'text/html']
284+ ==
285+ :_ this
286+ :~
287+ [%give %fact [/http-response/[p.req]]~ %http-response-header !>(response-header)]
288+ [%give %fact [/http-response/[p.req]]~ %http-response-data !>(`data)]
289+ [%give %kick [/http-response/[p.req]]~ ~]
290+ ==
291+ ==
292+ ==
293+++ on-watch
294+ |= =path
295+ ^- (quip card _this)
296+ ?+ path
297+ (on-watch:def path)
298+ ::
299+ [%http-response *]
300+ %- (slog leaf+"Eyre subscribed to {(spud path)}." ~)
301+ `this
302+ ==
303+++ on-leave on-leave:def
304+++ on-peek on-peek:def
305+++ on-agent on-agent:def
306+++ on-arvo
307+ |= [=wire =sign-arvo]
308+ ^- (quip card _this)
309+ ?. ?=([%bind-foo ~] wire)
310+ (on-arvo:def [wire sign-arvo])
311+ ?> ?=([%eyre %bound *] sign-arvo)
312+ ?: accepted.sign-arvo
313+ %- (slog leaf+"/foo bound successfully!" ~)
314+ `this
315+ %- (slog leaf+"Binding /foo failed!" ~)
316+ `this
317+++ on-fail on-fail:def
318+--
319+```
320+
321+Save the above to `/app/eyre-agent.hoon`. Commit it:
322+
323+```
324+> |commit %home
325+>=
326++ /~zod/home/2/app/eyre-agent/hoon
327+```
328+
329+...and start it:
330+
331+```
332+> |start %eyre-agent
333+>=
334+gall: loading %eyre-agent
335+activated app home/eyre-agent
336+[unlinked from [p=~zod q=%eyre-agent]]
337+```
338+
339+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.md#connect) `task` to Eyre when poked with `%bind`:
340+
341+```hoon
342+ %noun
343+?. =(q.vase %bind)
344+ %- (slog leaf+"Bad argument." ~)
345+ `this
346+%- (slog leaf+"Attempting to bind /foo." ~)
347+:_ this
348+[%pass /eyre %arvo %e %connect `/'foo' %eyre-agent]~
349+```
350+
351+...and when `%eyre` responds with a `%bound` `gift`, the `+on-agent` arm will print whether the bind succeeded:
352+
353+```hoon
354+ [%eyre %bound *]
355+?: accepted.sign-arvo
356+ %- (slog leaf+"/foo bound successfully!" ~)
357+ `this
358+%- (slog leaf+"Binding /foo failed!" ~)
359+`this
360+```
361+
362+...so let's try:
363+
364+```
365+> :eyre-agent %bind
366+>=
367+Attempting to bind /foo.
368+/foo bound successfully!
369+```
370+
371+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:
372+
373+```
374+> curl -i localhost:8080/foo
375+HTTP/1.1 200 ok
376+Date: Mon, 17 May 2021 04:39:40 GMT
377+Connection: keep-alive
378+Server: urbit/vere-1.5
379+Content-Type: text/html
380+Content-Length: 22
381+transfer-encoding: chunked
382+
383+<h1>Hello, World!</h1>%
384+```
385+
386+...which has succeed! This is because the `+on-poke` arm tests for http GET requests and responds with `Hello, World!` when it sees one:
387+
388+```hoon
389+ %'GET'
390+=/ data=octs
391+ (as-octs:mimes:html '<h1>Hello, World!</h1>')
392+=/ content-length=@t
393+ (crip ((d-co:co 1) p.data))
394+=/ =response-header:http
395+ :- 200
396+ :~ ['Content-Length' content-length]
397+ ['Content-Type' 'text/html']
398+ ==
399+:_ this
400+:~
401+ [%give %fact [/http-response/[p.req]]~ %http-response-header !>(response-header)]
402+ [%give %fact [/http-response/[p.req]]~ %http-response-data !>(`data)]
403+ [%give %kick [/http-response/[p.req]]~ ~]
404+==
405+```
406+
407+Back in the dojo, our app's `+on-watch` arm has printed the path on which Eyre has subscribed for the response:
408+
409+```
410+Eyre subscribed to /http-response/~.eyre_0v3.1knjk.l544e.5uds6.fn9l2.f8929.
411+```
412+
413+...and it's also printed the request so you can see how it looks when it comes in:
414+
415+```
416+[ %handle-http-request
417+ p=~.~.eyre_0v3.1knjk.l544e.5uds6.fn9l2.f8929
418+ q
419+ [ authenticated=%.n
420+ secure=%.n
421+ address=[%ipv4 .127.0.0.1]
422+ request
423+ [ method=%'GET'
424+ url='/foo'
425+ header-list
426+ ~[
427+ [key='host' value='localhost:8080']
428+ [key='user-agent' value='curl/7.76.1']
429+ [key='accept' value='*/*']
430+ ]
431+ body=~
432+ ]
433+ ]
434+]
435+```
436+
437+This is a very rudimentary app but it demonstrates the basic mechanics of dealing with HTTP requests and serving responses.
438+
439+# Generators
440+
441+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.
442+
443+You can refer to the [%serve](@/docs/arvo/eyre/tasks.md#serve) section of the [Internal API Reference](@/docs/arvo/eyre/tasks.md) document for relevant details.
444+
445+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 %home`.
446+
447+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.
448+
449+`eyre-gen.hoon`
450+
451+```hoon
452+|= [[now=@da eny=@uvJ bec=beak] ~ ~]
453+|= [authenticated=? =request:http]
454+^- simple-payload:http
455+=/ msg=@t
456+ ?~ body.request
457+ (scot %da now)
458+ (cat 3 (cat 3 (scot %da now) 10) q.u.body.request)
459+=/ data=octs
460+ (as-octs:mimes:html msg)
461+=/ =response-header:http
462+ [200 ['Content-Type' 'text/plain']~]
463+[response-header `data]
464+```
465+
466+Eyre requires generators to be a gate within a gate. The sample of the first gate must be:
467+
468+```hoon
469+[[now=@da eny=@uvJ bec=beak] ~ ~]
470+```
471+
472+The sample of the second nested gate must be:
473+
474+```hoon
475+[authenticated=? =request:http]
476+```
477+
478+The return type of the generator must be [simple-payload:http](@/docs/arvo/eyre/data-types.md#simple-payload-http). If you look at our example generator you'll see it meets these requirements.
479+
480+Because generators return the entire HTTP message as a single `simple-payload`, Eyre can calculate the `content-length` itself and automatically add the header.
481+
482+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:
483+
484+```hoon
485+[%serve =binding =generator]
486+```
487+
488+The [binding](@/docs/arvo/eyre/data-types.md#binding) specifies the site and URL path, and the [generator](@/docs/arvo/eyre/data-types.md#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.
489+
490+Let's bind our generator to the `/mygen` URL path with the `|pass` command in the dojo:
491+
492+```
493+|pass [%e [%serve `/mygen %home /gen/eyre-gen/hoon ~]]
494+```
495+
496+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.
497+
498+Now let's try making an HTTP request using `curl` in the unix terminal:
499+
500+```
501+curl -i http://localhost:8080/mygen --data 'blah blah blah'
502+```
503+
504+We can see that the request has succeeded and our generator has responded with the datetime and request body:
505+
506+```
507+HTTP/1.1 200 ok
508+Date: Sat, 29 May 2021 09:19:45 GMT
509+Connection: keep-alive
510+Content-Length: 41
511+Server: urbit/vere-1.5
512+Content-Type: text/plain
513+Content-Length: 41
514+
515+~2021.5.29..09.19.45..e096
516+blah blah blah
517+```
518+
519+# Managing CORS Origins
520+
521+Here we'll look at approving and rejecting a CORS origin by passing Clay a [%approve-origin](@/docs/arvo/eyre/tasks.md#approve-origin) `task` and [%reject-origin](@/docs/arvo/eyre/tasks.md#reject-origin) `task` respectively.
522+
523+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.
524+
525+First, using `|pass` in the dojo, let's approve the origin `http://foo.example` by sending Eyre a `%approve-origin` `task`:
526+
527+```
528+|pass [%e [%approve-origin 'http://foo.example']]
529+```
530+
531+Now if we scry for the [approved](@/docs/arvo/eyre/scry.md#cors-approved) CORS `set`:
532+
533+```
534+> .^(approved=(set @t) %ex /=//=/cors/approved)
535+approved={'http://foo.example'}
536+```
537+
538+...we can see that `http://foo.example` has been added.
539+
540+Next, let's test it by sending Eyre a CORS preflight request via `curl` in unix:
541+
542+```
543+curl -i -X OPTIONS \
544+ -H "Access-Control-Request-Method: POST" \
545+ -H "Access-Control-Request-Headers: X-Requested-With" \
546+ -H "Origin: http://foo.example" \
547+ http://localhost:8080
548+```
549+
550+We can see in the response that it has succeeded:
551+
552+```
553+HTTP/1.1 204 ok
554+Date: Fri, 28 May 2021 12:37:12 GMT
555+Connection: keep-alive
556+Server: urbit/vere-1.5
557+Access-Control-Allow-Origin: http://foo.example
558+Access-Control-Allow-Credentials: true
559+Access-Control-Allow-Headers: X-Requested-With
560+Access-Control-Allow-Methods: POST
561+```
562+
563+Now we'll try rejecting an `origin`. Back in the dojo, let's `|pass` Eyre a `%reject-origin` `task` for `http://bar.example`:
564+
565+```
566+|pass [%e [%reject-origin 'http://bar.example']]
567+```
568+
569+If we scry for the [rejected](@/docs/arvo/eyre/scry.md#cors-rejected) CORS `set`:
570+
571+```
572+> .^(rejected=(set @t) %ex /=//=/cors/rejected)
573+rejected={'http://bar.example'}
574+```
575+
576+...we can see that `http://bar.example` has been added.
577+
578+If we again test it with `curl` in unix:
579+
580+```
581+curl -i -X OPTIONS \
582+ -H "Access-Control-Request-Method: POST" \
583+ -H "Access-Control-Request-Headers: X-Requested-With" \
584+ -H "Origin: http://bar.example" \
585+ http://localhost:8080
586+```
587+
588+...we can see that, as expected, it has not returned the access control headers:
589+
590+```
591+HTTP/1.1 404 missing
592+Date: Fri, 28 May 2021 12:38:47 GMT
593+Connection: close
594+Server: urbit/vere-1.5
595+```
596+
597+Finally, let's look at CORS requests that are neither approved nor rejected.
598+
599+If we make another request with `curl` on unix, this time for `http://baz.example` which we haven't added to a list:
600+
601+```
602+curl -i -X OPTIONS \
603+ -H "Access-Control-Request-Method: POST" \
604+ -H "Access-Control-Request-Headers: X-Requested-With" \
605+ -H "Origin: http://baz.example" \
606+ http://localhost:8080
607+```
608+
609+...we can see it also correctly fails to return the access control headers:
610+
611+```
612+HTTP/1.1 404 missing
613+Date: Fri, 28 May 2021 12:39:59 GMT
614+Connection: close
615+Server: urbit/vere-1.5
616+```
617+
618+Now if we scry for the [requests](@/docs/arvo/eyre/scry.md#cors-requests) CORS `set`:
619+
620+```
621+> .^(requests=(set @t) %ex /=//=/cors/requests)
622+requests={'http://baz.example' 'http://localhost:8080'}
623+```
624+
625+... we can see it has automatically been added by the mere fact of the request being made.
content/docs/arvo/eyre/external-api-ref.mdnew file+381
@@ -0,0 +1,381 @@
1++++
2+title = "External API Reference"
3+weight = 2
4+template = "doc.html"
5++++
6+
7+# Contents
8+
9+- [Introduction](#introduction)
10+- [Authentication](#authentication)
11+- [Channels](#channels)
12+ - [HTTP Requests](#http-requests)
13+ - [Actions](#actions)
14+ - [Poke](#poke)
15+ - [Subscribe](#subscribe)
16+ - [Ack](#ack)
17+ - [Unsubscribe](#unsubscribe)
18+ - [Delete Channel](#delete-channel)
19+ - [Responses](#responses)
20+ - [Poke Ack](#poke-ack)
21+ - [Watch Ack](#watch-ack)
22+ - [Diff](#diff)
23+ - [Quit](#quit)
24+- [Scry](#scry)
25+- [Spider](#spider)
26+
27+# Introduction
28+
29+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 [Examples](@/docs/arvo/eyre/examples.md) document.
30+
31+# Authentication
32+
33+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:
34+
35+| HTTP Method | Data | URL Path | Notes |
36+| ----------- | -------------------------------------- | ---------- | ----------------------------------------------------------------------------------- |
37+| `POST` | `password=lidlut-tabwed-pillex-ridrup` | `/~/login` | The password is your web login code which can be obtained with `+code` in the dojo. |
38+
39+See the [examples](@/docs/arvo/eyre/examples.md#authenticating) for an example of how to do this using the curl.
40+
41+Eyre's response will include a `set-cookie` header like:
42+
43+```
44+set-cookie: urbauth-~zod=0v4.ilskp.psv00.t09r0.l8rps.3n97v; Path=/; Max-Age=604800
45+```
46+
47+The `urbauth-{...}` cookie provided must be included in a `cookie` header with all subsequent requests like:
48+
49+```
50+cookie: urbauth-~zod=0v4.ilskp.psv00.t09r0.l8rps.3n97v
51+```
52+
53+# Channels
54+
55+Eyre's channel system is the primary way of interacting with Gall agents from outside of Urbit.
56+
57+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.
58+
59+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.
60+
61+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.
62+
63+The response you'll get to the GET request will be an event stream. Events will come in like:
64+
65+```
66+id: 0
67+data: {"ok":"ok","id":1,"response":"poke"}
68+```
69+
70+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.
71+
72+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.
73+
74+When you're finished with a channel, you can send Eyre a [delete action](#delete-channel) to close it.
75+
76+See the [Using the Channel System](@/docs/arvo/eyre/examples.md#using-the-channel-system) section of the [Examples](@/docs/arvo/eyre/examples.md) document for a practical example.
77+
78+## HTTP Requests
79+
80+[Actions](#actions) are sent to Eyre in HTTP PUT requests:
81+
82+| HTTP Method | Required Headers | Data | URL Path |
83+| ----------- | ------------------------- | -------------------------------------------------------------- | ------------------ |
84+| `PUT` | `Content-Type` & `Cookie` | One or more [actions](#actions) wrapped in a JSON array (`[]`) | `/~/channel/{uid}` |
85+
86+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.
87+
88+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.
89+
90+## Actions
91+
92+### Poke
93+
94+This is for poking a Gall agent.
95+
96+| Key | JSON Type | Example Value | Description |
97+| -------- | --------- | ------------- | ------------------------------------------------------------- |
98+| `id` | Number | `1` | ID for keeping track of sent messages. |
99+| `action` | String | `'poke'` | The kind of action. |
100+| `ship` | String | `'zod'` | Target ship name, excluding leading `~`. |
101+| `app` | String | `'hood'` | Name of the gall agent you're poking. |
102+| `mark` | String | `'helm-hi'` | Type of data. Must correspond to a mark definition in `/mar`. |
103+| `json` | Any | `'hello'` | Actual payload. Any JSON type, determined by app. |
104+
105+**Example**
106+
107+```json
108+{
109+ "id": 1,
110+ "action": "poke",
111+ "ship": "zod",
112+ "app": "hood",
113+ "mark": "helm-hi",
114+ "json": "hello"
115+}
116+```
117+
118+**Response**
119+
120+Eyre will send a [poke ack](#poke-ack) as an SSE event on the channel event stream.
121+
122+### Subscribe
123+
124+This is for subscribing to a watch `path` of a Gall agent.
125+
126+| Key | JSON Type | Example Value | Description |
127+| -------- | --------- | --------------- | --------------------------------------------------- |
128+| `id` | Number | `2` | ID for keeping track of sent messages. |
129+| `action` | String | `'subscribe'` | The kind of action. |
130+| `ship` | String | `'zod'` | Target ship name, excluding leading `~`. |
131+| `app` | String | `'graph-store'` | Name of the gall agent to which you're subscribing. |
132+| `path` | String | `'/updates'` | The path to watch. Depends on the app. |
133+
134+**Example**
135+
136+```json
137+{
138+ "id": 2,
139+ "action": "subscribe",
140+ "ship": "zod",
141+ "app": "graph-store",
142+ "path": "/updates"
143+}
144+```
145+
146+**Response**
147+
148+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`.
149+
150+### Ack
151+
152+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.
153+
154+| Key | JSON Type | Example Value | Description |
155+| ---------- | --------- | ------------- | -------------------------------------------------------- |
156+| `id` | Number | `3` | ID for keeping track of sent messages. |
157+| `action` | String | `'ack'` | The kind of action. |
158+| `event-id` | Number | `7` | ID of SSE event up to which you're acknowledging receipt |
159+
160+**Example**
161+
162+```json
163+{
164+ "id": 3,
165+ "action": "ack",
166+ "event-id": 7
167+}
168+```
169+
170+**Response**
171+
172+Eyre will not respond to an `ack` action.
173+
174+### Unsubscribe
175+
176+This is for unsubscribing from a Gall agent watch `path` to which you've previously subscribed.
177+
178+| Key | JSON Type | Example Value | Description |
179+| -------------- | --------- | ------------- | ---------------------------------------------------------- |
180+| `id` | Number | `4` | ID for keeping track of sent messages. |
181+| `action` | String | `unsubscribe` | The kind of action. |
182+| `subscription` | Number | `2` | Request ID of the initial `subscribe` action from earlier. |
183+
184+**Example**
185+
186+```json
187+{
188+ "id": 4,
189+ "action": "unsubscribe",
190+ "subscription": 2
191+}
192+```
193+
194+**Response**
195+
196+Eyre will not respond to an `unsubscribe` action.
197+
198+### Delete Channel
199+
200+This is for deleting the channel itself.
201+
202+| Key | JSON Type | Example Value | Description |
203+| -------- | --------- | ------------- | -------------------------------------- |
204+| `id` | Number | `5` | ID for keeping track of sent messages. |
205+| `action` | String | `'delete'` | The kind of action. |
206+
207+**Example**
208+
209+```json
210+{
211+ "id": 5,
212+ "action": "delete"
213+}
214+```
215+
216+**Response**
217+
218+Eyre will not respond to a `delete` action.
219+
220+## Responses
221+
222+### Poke Ack
223+
224+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.
225+
226+**Positive Poke Ack**
227+
228+| Key | JSON Type | Example Value | Description |
229+| ---------- | --------- | ------------- | -------------------------------------------- |
230+| `ok` | String | `'ok'` | Positive acknowledgement. |
231+| `id` | Number | `1` | Request ID of the `poke` being acknowledged. |
232+| `response` | String | `'poke'` | The kind of action being acknowledged. |
233+
234+**Example**
235+
236+```json
237+{
238+ "ok": "ok",
239+ "id": 1,
240+ "response": "poke"
241+}
242+```
243+
244+**Negative Poke Ack**
245+
246+| Key | JSON Type | Example Value | Description |
247+| ---------- | --------- | ---------------- | --------------------------------------------------------------------- |
248+| `err` | String | `'some text...'` | Negative acknowledgement. Contains an error message and/or traceback. |
249+| `id` | Number | `1` | Request ID of the `poke` being acknowledged. |
250+| `response` | String | `'poke'` | The kind of action being acknowledged. |
251+
252+**Example**
253+
254+```json
255+{
256+ "err": "<error message and traceback>",
257+ "id": 1,
258+ "response": "poke"
259+}
260+```
261+
262+**Action Required**
263+
264+You must ack the event.
265+
266+### Watch Ack
267+
268+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.
269+
270+**Positive Watch Ack**
271+
272+| Key | JSON Type | Example Value | Description |
273+| ---------- | --------- | ------------- | --------------------------------------------- |
274+| `ok` | String | `'ok'` | Positive acknowledgement. |
275+| `id` | Number | `2` | Request ID of the initial `subscribe` action. |
276+| `response` | String | `'subscribe'` | The kind of action being acknowledged. |
277+
278+**Example**
279+
280+```json
281+{
282+ "ok": "ok",
283+ "id": 2,
284+ "response": "subscribe"
285+}
286+```
287+
288+**Negative Watch Ack**
289+
290+| Key | JSON Type | Example Value | Description |
291+| ---------- | --------- | ---------------- | --------------------------------------------------------------------- |
292+| `err` | String | `'some text...'` | Negative acknowledgement. Contains an error message and/or traceback. |
293+| `id` | Number | `2` | Request ID of the initial `subscribe` action. |
294+| `response` | String | `'subscribe'` | The kind of action being acknowledged. |
295+
296+**Example**
297+
298+```json
299+{
300+ "err": "<error message and traceback>",
301+ "id": 2,
302+ "response": "subscribe"
303+}
304+```
305+
306+**Action Required**
307+
308+You must ack the event.
309+
310+### Diff
311+
312+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`.
313+
314+| Key | JSON Type | Example Value | Description |
315+| ---------- | --------- | ---------------- | ------------------------------------------------------------ |
316+| `json` | Any | `{'foo': 'bar'}` | The actual data from the agent, could be any JSON structure. |
317+| `id` | Number | `3` | Request ID of the initial `subscribe` action from earlier. |
318+| `response` | String | `'diff'` | The kind of response. All `fact`s are marked `'diff'`. |
319+
320+**Example**
321+
322+```json
323+{
324+ "json": { "foo": "bar" },
325+ "id": 3,
326+ "response": "diff"
327+}
328+```
329+
330+**Action Required**
331+
332+You must [ack](#ack) each `diff` that comes in the event stream.
333+
334+### Quit
335+
336+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.
337+
338+| Key | JSON Type | Example Value | Description |
339+| ---------- | --------- | ------------- | --------------------------------------------- |
340+| `id` | Number | `4` | Request ID of the initial `subscribe` action. |
341+| `response` | String | `'quit'` | The kind of response. |
342+
343+**Example**
344+
345+```json
346+{
347+ "id": 4,
348+ "response": "quit"
349+}
350+```
351+
352+**Action Required**
353+
354+You must ack the event and you may wish to try and re[subscribe](#subscribe).
355+
356+# Scry
357+
358+A scry is a read-only request for some data.
359+
360+A scry takes the form of an [authenticated](#authentication) HTTP GET request to a URL path with the following format:
361+
362+```
363+http{s}://{host}/~/scry/{app}{path}.{mark}
364+```
365+
366+The `{app}` is the name of the Gall agent you want to query, for example `graph-store`.
367+
368+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`.
369+
370+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:
371+
372+1. It must be possible to convert the `mark` produced by the specified scry endpoint to the `mark` you want returned.
373+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.
374+
375+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.
376+
377+See the [Scrying](@/docs/arvo/eyre/examples.md#scrying) section of the [Examples](@/docs/arvo/eyre/examples.md) document for a practical example.
378+
379+# Spider
380+
381+See the [HTTP API](@/docs/userspace/threads/http-api.md) section of the [Threads](@/docs/userspace/threads/overview.md) documentation.
content/docs/arvo/eyre/eyre.mdnew file+61
@@ -0,0 +1,61 @@
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.md#authentication) section of the [External API Reference](@/docs/arvo/eyre/external-api-ref.md) 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.md) document with corresponding examples in the [Examples](@/docs/arvo/eyre/examples.md#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.md#scry) section of the [External API Reference](@/docs/arvo/eyre/external-api-ref.md) 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.md) is not part of Eyre proper, so is documented separately in the [Threads](@/docs/userspace/threads/overview.md) 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.md#serve) section of the [Internal API Reference](@/docs/arvo/eyre/tasks.md) documentation and a practical example is provided in the [Generators](@/docs/arvo/eyre/examples.md#generators) section of the [Examples](@/docs/arvo/eyre/examples.md) 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.md#connect) section of the [Internal API Reference](@/docs/arvo/eyre/tasks.md) document and a detailed example is provided in the [Direct HTTP Handling With Gall Agents](@/docs/arvo/eyre/examples.md#direct-http-handling-with-gall-agents) section of the [Examples](@/docs/arvo/eyre/examples.md) 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.md) to [approve](@/docs/arvo/eyre/tasks.md#approve-origin) and [reject](@/docs/arvo/eyre/tasks.md#reject-origin) origins programmatically, and a number of [scry endpoints](@/docs/arvo/eyre/scry.md) to query them. Examples are also included in the [Managing CORS Origins](@/docs/arvo/eyre/examples.md#managing-cors-origins) section of the Examples document.
50+
51+# Eyre Documentation Sections
52+
53+- [External API Reference](@/docs/arvo/eyre/external-api-ref.md) - Details of Eyre's external API including the channel system's JSON API.
54+
55+- [Internal API Reference](@/docs/arvo/eyre/tasks.md) - The `task`s Eyre takes and the `gift`s it returns.
56+
57+- [Scry Reference](@/docs/arvo/eyre/scry.md) - The scry endpoints of Eyre.
58+
59+- [Data Types](@/docs/arvo/eyre/data-types.md) - Reference documentation of the various data types used by Eyre.
60+
61+- [Examples](@/docs/arvo/eyre/examples.md) - Practical examples of the different ways of using Eyre.
content/docs/arvo/eyre/scry.mdnew file+213
@@ -0,0 +1,213 @@
1++++
2+title = "Scry Reference"
3+weight = 4
4+template = "doc.html"
5++++
6+
7+## Contents
8+
9+- [Introduction](#introduction)
10+- [/cors](#cors) - CORS settings.
11+ - [/cors/requests](#cors-requests) - Requested origins.
12+ - [/cors/approved](#cors-approved) - Approved origins.
13+ - [/cors/approved/\<origin\>](#cors-approved-origin) - Check if origin approved.
14+ - [/cors/rejected](#cors-rejected) - Rejected origins.
15+ - [/cors/rejected/\<origin\>](#cors-rejected-origin) - Check if origin rejected.
16+- [/authenticated/cookie/\<cookie\>](#authenticated-cookie-cookie) - Check if cookie authenticated.
17+- [bindings](#bindings) - URL path bindings.
18+- [connections](#connections) - Open http connections.
19+- [authentication-state](#authentication-state) - Authentication details.
20+- [channel-state](#channel-state) - Details of each channel.
21+- [host](#host) - Host details.
22+
23+# Introduction
24+
25+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.
26+
27+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>=)`.
28+
29+All examples are run from the dojo.
30+
31+# `/cors`
32+
33+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.md#cors-registry) which contains the `set`s of approved, rejected and requested origins.
34+
35+Example:
36+
37+```
38+> .^(cors-registry:eyre %ex /=//=/cors)
39+[ requests={~~http~3a.~2f.~2f.baz~.example}
40+ approved={~~http~3a.~2f.~2f.foo~.example}
41+ rejected={~~http~3a.~2f.~2f.bar~.example}
42+]
43+```
44+
45+## `/cors/requests`
46+
47+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)`.
48+
49+Example:
50+
51+```
52+> .^(requests=(set origin:eyre) %ex /=//=/cors/requests)
53+requests={~~http~3a.~2f.~2f.baz~.example}
54+```
55+
56+## `/cors/approved`
57+
58+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)`.
59+
60+Example:
61+
62+```
63+> .^(approved=(set origin:eyre) %ex /=//=/cors/approved)
64+approved={~~http~3a.~2f.~2f.foo~.example}
65+```
66+
67+## `/cors/approved/<origin>`
68+
69+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 `?`.
70+
71+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'`.
72+
73+Examples:
74+
75+```
76+> .^(? %ex /=//=/cors/approved/(scot %t 'http://foo.example'))
77+%.y
78+```
79+
80+```
81+> .^(? %ex /=//=/cors/approved/(scot %t 'http://bar.example'))
82+%.n
83+```
84+
85+## `/cors/rejected`
86+
87+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)`.
88+
89+Example:
90+
91+```
92+> .^(rejected=(set origin:eyre) %ex /=//=/cors/rejected)
93+rejected={~~http~3a.~2f.~2f.bar~.example}
94+```
95+
96+## `/cors/rejected/<origin>`
97+
98+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 `?`.
99+
100+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'`.
101+
102+Examples:
103+
104+```
105+> .^(? %ex /=//=/cors/rejected/(scot %t 'http://bar.example'))
106+%.y
107+```
108+
109+```
110+> .^(? %ex /=//=/cors/rejected/(scot %t 'http://foo.example'))
111+%.n
112+```
113+
114+# `/authenticated/cookie/<cookie>`
115+
116+An `x` scry whose `path` is `/authenticated/cookies/<cookie>` tests whether the given cookie is currently valid. The type returned is a `?`.
117+
118+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'`.
119+
120+Examples:
121+
122+```
123+> .^(? %ex /=//=/authenticated/cookie/(scot %t 'urbauth-~zod=0vvndn8.bfsjj.j3614.k40ha.8fomi'))
124+%.y
125+```
126+
127+```
128+> .^(? %ex /=//=/authenticated/cookie/(scot %t 'foo'))
129+%.n
130+```
131+
132+# `bindings`
133+
134+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.md#binding) & [action](@/docs/arvo/eyre/data-types.md#action) sections of the Data Types document for details).
135+
136+Example:
137+
138+```
139+> .^((list [binding:eyre duct action:eyre]) %e /=bindings=)
140+~[
141+ [ [site=~ path=<|~landscape js bundle|>]
142+ ~[/gall/use/file-server/0w2.EijQB/~zod/~landscape/js/bundle /dill //term/1]
143+ [%app app=%file-server]
144+ ]
145+ [ [site=~ path=<|~landscape|>]
146+ ~[/gall/use/file-server/0w2.EijQB/~zod/~landscape /dill //term/1]
147+ [%app app=%file-server]
148+ ]
149+ ...(truncated for brevity)...
150+]
151+```
152+
153+# `connections`
154+
155+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.md#outstanding-connection) section of the Data Types document for details).
156+
157+Example:
158+
159+```
160+> .^((map duct outstanding-connection:eyre) %e /=connections=)
161+{}
162+```
163+
164+# `authentication-state`
165+
166+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.md#authentication-state). The `p` field is the cookie sans the `urbauth-<ship>=` part.
167+
168+Example:
169+
170+```
171+> .^(authentication-state:eyre %e /=authentication-state=)
172+ sessions
173+{ [ p=0v3.kags1.hj7hm.6llrl.cga2j.eh1r7
174+ q=[expiry-time=~2021.5.20..08.44.27..39e0 channels={}]
175+ ]
176+}
177+```
178+
179+# `channel-state`
180+
181+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.md#channel-state).
182+
183+Example:
184+
185+```
186+> .^(channel-state:eyre %e /=channel-state=)
187+[ session
188+ { [ p='1601844290-ae45b'
189+ q
190+ [ state=[%.y p=[date=~2021.5.13..20.44.27..39e0 duct=~[//http-server/0v2.kmj6q/26/1]]]
191+ next-id=1
192+ last-ack=~2021.5.13..08.44.27..39e0
193+ events={[id=0 request-id=2 channel-event=[%poke-ack p=~]]}
194+ unacked={}
195+ subscriptions={}
196+ heartbeat=~
197+ ]
198+ ]
199+ }
200+ duct-to-key={}
201+]
202+```
203+
204+# `host`
205+
206+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`.
207+
208+Example:
209+
210+```
211+> .^(hart:eyre %e /=host=)
212+[p=%.n q=[~ 8.080] r=[%.y p=<|localhost|>]]
213+```
content/docs/arvo/eyre/tasks.mdnew file+230
@@ -0,0 +1,230 @@
1++++
2+title = "Internal API Reference"
3+weight = 3
4+template = "doc.html"
5++++
6+
7+# Contents
8+
9+- [Introduction](#introduction)
10+- [%live](#live) - _(Internal only)_ - Notifies Eyre of HTTP(S) ports.
11+- [%rule](#rule) - _(Usually internal)_ - Sets TLS cert or DNS binding.
12+- [%request](#request) - _(Internal only)_ - Incoming HTTP request.
13+- [%request-local](#request-local) - _(Internal only)_ - Incoming HTTP request from the local loopback port.
14+- [%cancel-request](#cancel-request) - _(Internal only)_ - Notifies Eyre of a connection being closed externally.
15+- [%connect](#connect) - Bind a Gall agent to a URL.
16+- [%serve](#serve) - Bind a generator to a URL.
17+- [%disconnect](#disconnect) - Disconnect agent or generator from URL binding.
18+- [%code-changed](#code-changed) - _(Usually internal)_ - Notifies Eyre of the web login code changing.
19+- [%approve-origin](#approve-origin) - Approve a CORS origin.
20+- [%reject-origin](#reject-origin) - Reject a CORS origin.
21+
22+# Introduction
23+
24+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.
25+
26+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 [Examples](@/docs/arvo/eyre/examples.md) document. The rest are just documented for completeness.
27+
28+Many of the types referenced are detailed in the [Data Types](@/docs/arvo/eyre/data-types.md) 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.
29+
30+# `%live`
31+
32+```hoon
33+[%live insecure=@ud secure=(unit @ud)]
34+```
35+
36+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.
37+
38+The `insecure` field is the HTTP port and `secure` is the optional HTTPS port.
39+
40+## Returns
41+
42+Eyre returns no `gift` in response to a `%live` `task`.
43+
44+# `%rule`
45+
46+```hoon
47+[%rule =http-rule]
48+```
49+
50+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.
51+
52+The [http-rule](@/docs/arvo/eyre/data-types.md#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.
53+
54+## Returns
55+
56+Eyre returns no `gift` in response to a `%rule` `task`.
57+
58+# `%request`
59+
60+```hoon
61+[%request secure=? =address =request:http]
62+```
63+
64+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.
65+
66+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.md#request-http) is the HTTP request itself containing the method, URL, headers, and body.
67+
68+## Returns
69+
70+Eyre may `pass` a `%response` `gift` on the appropriate `duct` depending on the contents of the `%request`, state of the connection, and other factors.
71+
72+# `%request-local`
73+
74+```hoon
75+[%request-local secure=? =address =request:http]
76+```
77+
78+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.
79+
80+## Returns
81+
82+Eyre may `pass` a `%response` `gift` on the appropriate `duct` depending on the contents of the `%request`, state of the connection, and other factors.
83+
84+# `%cancel-request`
85+
86+```hoon
87+[%cancel-request ~]
88+```
89+
90+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.
91+
92+This `task` takes no arguments.
93+
94+## Returns
95+
96+Eyre may `pass` a `%response` `gift` on the appropriate `duct` depending on the state of the connection and other factors.
97+
98+# `%connect`
99+
100+```hoon
101+[%connect =binding app=term]
102+```
103+
104+This `task` binds a Gall agent to a URL path so it can receive HTTP requests and return HTTP responses directly.
105+
106+The [binding](@/docs/arvo/eyre/data-types.md#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.
107+
108+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.md#inbound-request) contains the HTTP request itself.
109+
110+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).
111+
112+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.md#response-header-http) with the HTTP status code and headers of the response.
113+
114+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.
115+
116+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.
117+
118+## Returns
119+
120+Eyre will respond with a `%bound` `gift` which says whether the binding was successful and looks like:
121+
122+```hoon
123+[%bound accepted=? =binding]
124+```
125+
126+The `accepted` field says whether the binding succeeded and the `binding` is the requested binding described above.
127+
128+## Example
129+
130+See the [Direct HTTP Handling With Gall Agents](@/docs/arvo/eyre/examples.md#direct-http-handling-with-gall-agents) section of the [Examples](@/docs/arvo/eyre/examples.md) document for an example.
131+
132+# `%serve`
133+
134+```hoon
135+[%serve =binding =generator]
136+```
137+
138+This `task` binds a generator to a URL path so it can receive HTTP requests and return HTTP responses.
139+
140+The `binding` contains the URL path and optional domain through which the generator will take HTTP requests. The [generator](@/docs/arvo/eyre/data-types.md#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 `~`.
141+
142+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.md#simple-payload-http).
143+
144+The sample of the first gate must be:
145+
146+```hoon
147+[[now=@da eny=@uvJ bec=beak] ~ ~]
148+```
149+
150+...and the sample of the second, nested gate must be:
151+
152+```hoon
153+[authenticated=? =request:http]
154+```
155+
156+The `?` says whether the HTTP request contained a valid session cookie and the [request:http](@/docs/arvo/eyre/data-types.md#request-http) contains the request itself.
157+
158+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.
159+
160+## Returns
161+
162+Eyre will return a `%bound` `gift` as described at the end of the [%connect](#connect) section.
163+
164+## Example
165+
166+See the [Generators](@/docs/arvo/eyre/examples.md#generators) section of the [Examples](@/docs/arvo/eyre/examples.md) document for an example.
167+
168+# `%disconnect`
169+
170+```hoon
171+[%disconnect =binding]
172+```
173+
174+This `task` deletes a URL binding previously set by a `%connect` or `%serve` `task`.
175+
176+The [binding](@/docs/arvo/eyre/data-types.md#binding) is the URL path and domain of the binding you want to delete.
177+
178+## Returns
179+
180+Eyre returns no `gift` in response to a `%disconnect` `task`.
181+
182+# `%code-changed`
183+
184+```hoon
185+[%code-changed ~]
186+```
187+
188+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`.
189+
190+This `task` takes no arguments.
191+
192+## Returns
193+
194+Eyre returns no `gift` in response to a `%code-changed` `task`.
195+
196+# `%approve-origin`
197+
198+```hoon
199+[%approve-origin =origin]
200+```
201+
202+This `task` tells Eyre to start responding positively to CORS requests for the specified `origin`.
203+
204+The [origin](@/docs/arvo/eyre/data-types.md#origin) is a CORS origin like `http://foo.example` you want to approve.
205+
206+## Returns
207+
208+Eyre returns no `gift` in response to a `%approve-origin` `task`.
209+
210+## Example
211+
212+See the [Managing CORS Origins](@/docs/arvo/eyre/examples.md#managing-cors-origins) section of the [Examples](@/docs/arvo/eyre/examples.md) document for an example.
213+
214+# `%reject-origin`
215+
216+```hoon
217+[%reject-origin =origin]
218+```
219+
220+This `task` tells Eyre to start responding negatively to CORS requests for the specified `origin`.
221+
222+The [origin](@/docs/arvo/eyre/data-types.md#origin) is a CORS origin like `http://foo.example` you want want to reject.
223+
224+## Returns
225+
226+Eyre returns no `gift` in response to a `%reject-origin` `task`.
227+
228+## Example
229+
230+See the [Managing CORS Origins](@/docs/arvo/eyre/examples.md#managing-cors-origins) section of the [Examples](@/docs/arvo/eyre/examples.md) document for an example.
content/docs/arvo/ford/_index.mdnew file+7
@@ -0,0 +1,7 @@
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.mdnew file+223
@@ -0,0 +1,223 @@
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.mdnew file+7
@@ -0,0 +1,7 @@
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/overview.mdnew file+11
@@ -0,0 +1,11 @@
1++++
2+title = "Overview"
3+weight = 1
4+template = "doc.html"
5++++
6+
7+**Gall** is the application-management [vane](../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](../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](../ship), Gall will route it behind the scenes through [Ames](../ames) to the other ship.
8+
9+Gall is located at `/home/sys/vane/gall.hoon` within Arvo.
10+
11+For more details, see the [userspace](/docs/userspace/gall/gall) section.
content/docs/arvo/iris/_index.mdnew file+7
@@ -0,0 +1,7 @@
1++++
2+title = "Iris"
3+weight = 80
4+sort_by = "weight"
5+template = "sections/docs/chapters.html"
6+insert_anchor_links = "right"
7++++
content/docs/arvo/iris/iris-api.mdnew file+191
@@ -0,0 +1,191 @@
1++++
2+title = "API Reference"
3+weight = 10
4+template = "doc.html"
5++++
6+
7+In this document we describe the public interface for Iris. Namely, we describe
8+each `task` that Iris can be `%pass`ed, and which `gift`(s) Iris can `%give` in
9+return.
10+
11+## Returns to Unix
12+
13+Much of what Iris does is translating `task`s from other vanes into `card`s
14+meant for Unix via the `%request` and `%cancel-request` `task`s. What this means in practice is that Iris may be `%pass`ed a
15+`task` via some `duct`, which in response Iris then `%give`s a `gift` to Unix
16+via another `duct`. This `gift` will actually be a response to the `%born`
17+`task` that Iris was `%pass`ed when the Urbit was resumed, which came along the
18+duct to Unix.
19+
20+
21+## Tasks
22+
23+### `%born`
24+
25+Each time you start your Urbit the Arvo kernel calls the `%born` `task` for
26+Iris. This causes Iris to cancel any outstanding http requests and resets all
27+connection states.
28+
29+#### Accepts
30+
31+```hoon
32+[ ~ ]
33+```
34+
35+#### Returns
36+
37+In response to a `%born` `task` Iris `give`s a `%http-response %cancel` `gift`
38+to each outstanding connection.
39+
40+
41+### `%cancel-request`
42+
43+This `task` cancels a previous fetch. Iris knows which request is meant based on the
44+`duct` that the `task` comes on.
45+
46+ We note that `%cancel-request` is also a `gift` that Iris can `%give`.
47+
48+#### Accepts
49+
50+```hoon
51+[ ~ ]
52+```
53+
54+#### Returns
55+
56+```hoon
57+[%cancel-request id=@ud]
58+```
59+Receiving this `task` causes Iris to `%give`s a `%cancel-request` `gift` to Unix,
60+which then cancels the request in the runtime. See [Returns to Unix](#returns-to-unix).
61+
62+`id` is obtained via a `(map duct @ud)`, with the `duct` corresponding to one along
63+which the `%cancel-request` `task` came with.
64+
65+
66+### `%crud`
67+
68+`%crud` is called whenever an error involving Iris occurs. It produces a crash
69+report in response.
70+
71+#### Accepts
72+
73+```hoon
74+[p=@tas q=(list tank)]
75+```
76+
77+`p` is the type of error, `q` is the error message.
78+
79+#### Returns
80+
81+Iris does not `%give` a `gift` in response to a `%crud` `task`, but it does
82+`%slip` Dill a `%flog` `task` instructing it to print the error.
83+
84+
85+### `%receive`
86+
87+The `%receive` `task` is used to receive a response from Unix to an `http-request` that
88+was made.
89+
90+#### Accepts
91+
92+```hoon
93+[id=@ud =http-event:http]
94+```
95+
96+`id` is the identification number assigned by Iris to the http connection under
97+consideration. `http-event` is a packet that contains a header and data.
98+
99+#### Returns
100+
101+The response depends on what kind of packet `http-event` is: `%start`,
102+`%continue`, or `%cancel` and whether the `complete` flag is `%.y` or `%.n`.
103+
104+If the packet says to `%start` or `%continue` and `complete=%.n`, Iris will `%give` a
105+`%http-response %progress` `gift`.
106+
107+If the packet says to `%start` or `%continue` and `complete=%.y`, Iris will
108+`%give` a `%http-response %finished` `gift`.
109+
110+If the packet says to `%cancel`, Iris will `%give` a `%http-response %cancel`
111+`gift` in return. The `complete` flag is unused here.
112+
113+
114+### `%request`
115+
116+`%request` is used to fetch a remote resource. `%request` is also a `gift` Iris
117+can `%give`.
118+
119+#### Accepts
120+
121+```hoon
122+[=request:http =outbound-config]
123+```
124+
125+A `$request` consists of the following:
126+ - `=method`, the http method, which is one of `CONNECT`, `DELETE`, `GET`,
127+ `HEAD`, `OPTIONS`, `POST`, `PUT`, and `TRACE`.
128+ - `url=@t`, the URL being requested
129+ - `=header-list`, a list of headers to pass with the request,
130+ - `body=(unit octs)`, optional data to include in the request.
131+
132+ A `$outbound-config` contains the number of redirects and retries that Iris
133+ will attempt. By default this is 5 redirects (the recommended limit for the
134+ http standard) and 3 retries.
135+
136+#### Returns
137+
138+```hoon
139+[id=@ud request=request:http]
140+```
141+Iris will `%give` a `%request` `gift` to Unix in response to a `%request`
142+`task`. See [Returns to Unix](#returns-to-unix). This `gift`
143+contains the `request` in the original `task` as well as the ID number assigned
144+by Iris for that particular http connection, which is extracted from the input `task`.
145+
146+
147+### `%trim`
148+
149+This `task` is sent by the interpreter to free up memory. It has no effect on Iris.
150+
151+#### Accepts
152+
153+```hoon
154+[ ~ ]
155+```
156+
157+#### Returns
158+
159+This `task` returns no `gift`s.
160+
161+
162+### `%vega`
163+
164+This `task` informs the vane that the kernel has been upgraded. Iris does not do
165+anything in response to this.
166+
167+#### Accepts
168+
169+```hoon
170+[ ~ ]
171+```
172+
173+#### Returns
174+
175+This `task` returns no `gift`s.
176+
177+
178+### `%wegh`
179+
180+This `task` asks Iris to product a memory usage report.
181+
182+#### Accepts
183+
184+This `task` has no arguments.
185+
186+#### Returns
187+
188+When Iris is `%pass`ed this `task`, it will `%give` a `%mass` `gift` in response
189+containing Iris' current memory usage.
190+
191+
content/docs/arvo/jael/_index.mdnew file+7
@@ -0,0 +1,7 @@
1++++
2+title = "Jael"
3+weight = 90
4+sort_by = "weight"
5+template = "sections/docs/chapters.html"
6+insert_anchor_links = "right"
7++++
content/docs/arvo/jael/jael-api.mdnew file+393
@@ -0,0 +1,393 @@
1++++
2+title = "API Reference"
3+weight = 10
4+template = "doc.html"
5++++
6+
7+In this document we describe the public interface for Jael. Namely, we describe
8+each `task` that Jael can be `%pass`ed, and which `gift`(s) Jael can `%give` in return.
9+
10+
11+## Tasks
12+
13+### `%dawn`
14+
15+This `task` is called once per ship during the vane initialization
16+phase immediately following the beginning of the [adult
17+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
18+technical reasons, though we consider Jael to be the true "first" vane. This
19+`task` is only used for ships that will join the Ames network - fake ships (i.e.
20+made with `./urbit -F zod`) use the `%fake` `task` instead.
21+
22+`%dawn` is used to perform a sequence of initialization tasks related to saving
23+information about Azimuth and the Ames network and booting other vanes for the first time. Upon
24+receipt of a `%dawn` `task`, Jael will:
25+ - record the Ethereum block the public key is registered to,
26+ - record the URL of the Ethereum node used,
27+ - save the signature of the parent planet (if the ship is a moon),
28+ - load the initial public and private keys for the ship,
29+ - set the DNS suffix(es) used by the network (currently just `arvo.network`),
30+ - save the public keys of all galaxies,
31+ - set Jael to subscribe to `%azimuth-tracker`,
32+ - `%slip` a `%init` `task` to Ames, Clay, Gall, Dill, and Eyre, and `%give` an `%init`
33+`gift` to Arvo, which then informs Unix that the initialization process has concluded.
34+
35+#### Accepts
36+
37+`%dawn` accepts a `dawn-event`:
38+
39+```hoon
40+ +$ dawn-event
41+ $: =seed
42+ spon=(list [=ship point:azimuth-types])
43+ czar=(map ship [=rift =life =pass])
44+ turf=(list turf)
45+ bloq=@ud
46+ node=(unit purl:eyre)
47+ ==
48+```
49+
50+The `seed` is `[who=ship lyf=life key=ring sig=(unit oath:pki)]`. `who` is the
51+`@p` of the ship running the `task`, `lyf` is the current ship key revision,
52+`key` is the ship's private key, and `sig` is the signature of the ship's parent
53+planet if the ship is moon and `[~]` otherwise.
54+
55+`spon` is a `list` of ships and their `point`s in the ship's sponsorship chain,
56+all the way to the galaxy level. `point:azimuth-types` contains all Azimuth
57+related data and can be found in `zuse.hoon`.
58+
59+`czar` is a map from each galaxy's `@p` to its `rift`, `life`, and public key (`pass`).
60+
61+`turf` is a `list` of DNS suffixes used by the Ames network, which for now is
62+just `arvo.network`.
63+
64+`bloq` is the number of the Ethereum block in which the ship registered its keys
65+with the Azimuth smart contract.
66+
67+`node` is the URL of the Ethereum node used to register the ship's keys with Azimuth.
68+
69+#### Returns
70+
71+Jael `%give`s an `%init` `gift` to Unix. This occurs after the Dill `%slip`
72+init.
73+
74+#### Slips
75+
76+Jael `%slip`s `%init` `task`s to each of Eyre, Dill, Gall, Clay, and Ames, in
77+that order.
78+
79+
80+### `%fake`
81+
82+This `task` is used instead of `%dawn` when creating a fake ship via the `-F`
83+flag when calling the Urbit binary. It performs a subset of the actions that
84+`%dawn` performs, modified to accommodate the fake ship.
85+
86+`%fake` endows the ship with a private key and a public key deterministically derived from the
87+ship's `@p`. It sets `fak.own.pki` to `%.y`, which is the bit that determines
88+whether or not a ship is fake. Other parts of the Jael state, such as the
89+sponsorship chain and galaxy public keys are left at their bunted values.
90+
91+#### Accepts
92+
93+```hoon
94+[=ship]
95+```
96+`ship` is the `@p` of the fake ship being created.
97+
98+#### Returns
99+
100+Jael `%give`s a `%init` `gift` to Unix.
101+
102+#### Slips
103+
104+In response to a `%fake` `task`, Jael `%slip`s a `%init` `task` to each of Eyre, Dill, Gall,
105+Clay, and Ames, in that order.
106+
107+
108+### `%listen`
109+
110+Sets the source that the public keys for a set of `ship`s should be obtained
111+from. This can either be a Gall app that communicates with an Ethereum node such
112+as `%azimuth-tracker`, as in the case for galaxies, stars,
113+and planets, or a ship, as in the case of a moon or comet.
114+
115+After setting the source, Jael will then subscribe to the source for updates on
116+public keys for the given ships.
117+
118+
119+#### Accepts
120+
121+```hoon
122+[whos=(set ship) =source]
123+```
124+
125+`whos` is the set of ships whose key data source is to be altered. `source` is
126+`(each ship term)`, where `term` will ultimately be treated as a handle for a
127+Gall app.
128+
129+A `%listen` `task` with empty `whos` will set the default source to `source`.
130+This is the source used for all ships unless otherwise specified.
131+
132+When the `source` is a `term`, Jael looks into its state to find what source has
133+been previously assigned to that `term` and will henceforth obtain public keys for
134+ships in `(set ship)` from there. In practice, this is always
135+`%azimuth-tracker`, but the ability to use other sources is present.
136+
137+When the `source` is a ship, Jael will obtain public keys for ships in `(set ship)` from
138+the given ship. By default, the `source` for a moon will be the planet that
139+spawned that moon, and the `source` for a comet will be the comet itself.
140+
141+#### Returns
142+
143+This `task` returns no `gift`s.
144+
145+#### Passes
146+
147+If the `source` is a `term`, Jael will `%pass` a `%deal` `task` to Gall asking to
148+`%watch` the app given by `source` at path `/`.
149+
150+If the `source` is a `ship`, Jael will `%pass` a `%plea` `task` to Ames wrapping
151+a `%public-keys` `task` intended for Jael on the `ship` specified by `source`.
152+
153+
154+### `%meet`
155+
156+This `task` is deprecated and does not perform any actions.
157+
158+#### Accepts
159+
160+```hoon
161+[=ship =life =pass]
162+```
163+
164+#### Returns
165+
166+This `task` returns no `gift`s.
167+
168+
169+### `%moon`
170+
171+This `task` sets the public keys of a moon.
172+
173+#### Accepts
174+
175+```hoon
176+[=ship =udiff:point]
177+```
178+
179+The `ship` is the `@p` of the moon. The `task` will be a no-op if the `@p` is not that
180+of a moon, or if the moon does not belong to the ship.
181+
182+`udiff:point` contains the new public keys to be stored for the moon.
183+
184+#### Returns
185+
186+This `task` returns no `gift`s.
187+
188+
189+### `%nuke`
190+
191+This `task` cancels subscriptions to Jael's state from a given set of `ship`s.
192+This `task` works differently depending on whether the `task` originated locally
193+or remotely.
194+
195+#### Accepts
196+
197+```hoon
198+[whos=(set ship)]
199+```
200+`whos` is the `set` of `ship`s from which subscriptions are to be canceled.
201+
202+#### Returns
203+
204+This `task` returns no `gift`s.
205+
206+
207+### `%plea`
208+
209+This `task` is `%pass`ed to Jael from Ames. `%plea`s are wrappers for `task`s
210+that originate from a remote source, as the `%plea` pattern
211+is used to extend the `%pass`/`%give` semantics over the Ames network. Jael
212+attempts to perform the `task` wrapped in the `%plea`.
213+
214+Jael accepts two kinds of `%plea`s: [`%nuke`](#nuke) and
215+[`%public-keys`](#public-keys) and will crash if passed anything else. See the
216+relevant entries to learn how Jael responds to these.
217+
218+#### Accepts
219+
220+```hoon
221+[=ship =plea:ames]
222+```
223+`ship` is the origin of the plea, and `plea:ames` is `[vane=@tas =path
224+payload=*]`. Here, `vane=%j`, `path` is the internal route on the receiving ship, and `payload` is either a `%nuke` or
225+a `%public-keys` `task`.
226+
227+#### Returns
228+
229+Jael `%give`s a `%done` `gift` in response to a `%plea` `task`.
230+
231+#### Passes
232+
233+Jael `%pass`es itself the wrapped `task`.
234+
235+
236+### `%private-keys`
237+
238+This `task` creates a subscription to the private keys kept by Jael.
239+
240+We note that there are two `+private-keys` arms in Jael - one located in the
241+`+feed` core and the other located in the `+feel` core. This `task` calls the
242+arm in the `+feed` core.
243+
244+#### Accepts
245+
246+```hoon
247+[~]
248+```
249+
250+#### Returns
251+
252+```hoon
253+[%private-keys =life vein=(map life ring)]
254+```
255+
256+In response to a `%private-keys` `task`, Jael `%give`s a `%private-keys` `gift`.
257+`life=@ud` is the current `life` of the ship, and `vein` is a `map` from
258+`life`s to `ring`s that keeps track of all `life`-`ring` pairs throughout the
259+history of the ship.
260+
261+
262+### `%public-keys`
263+
264+This `task` creates a subscription for the callee to a selection of the public
265+keys kept by Jael. This `task` can originate locally or remotely.
266+
267+#### Accepts
268+
269+```hoon
270+[ships=(set ship)]
271+```
272+`ships` is the `set` of `ship`s whos' public keys are being subscribed to.
273+
274+#### Returns
275+
276+```hoon
277+[%public-keys =public-keys-result]
278+```
279+If the `task` originated locally, Jael `%give`s a `%public-keys` `gift` in
280+response. If it originated remotely, Jael `%give`s a `%boon` `gift` to back
281+to Ames wrapping a `%public-keys` `gift`.
282+
283+A `$public-keys-result` is the following.
284+```hoon
285+ +$ public-keys-result
286+ $% [%full points=(map ship point)]
287+ [%diff who=ship =diff:point]
288+ [%breach who=ship]
289+```
290+The first time Jael receives a `%public-keys` `task` from a ship it will return
291+a `[%public-keys-result %full]` `gift`, which contains all information about ships and
292+their associated points that Jael knows. Subsequent updates will typically be
293+`[%public-keys-result %diff]`, which tells the caller what has changed
294+since last time they sent a `%public-keys` `task`, and `[%public-keys-result
295+%breach]`, which informs the caller of ship breaches.
296+
297+
298+### `%rekey`
299+
300+This `task` updates the ship's private keys.
301+
302+#### Accepts
303+
304+```hoon
305+[=life =ring]
306+```
307+
308+`life` is a `@ud` that is the new ship key revision number. `ring` is a `@` that is the new private key.
309+
310+#### Returns
311+
312+```hoon
313+[%private-keys =life vein=(map life ring)]
314+```
315+
316+In response to a `%rekey` `task`, Jael `%give`s a `%private-keys` `gift`. `life`
317+is the new `life` given in the original `task`, and `vein` is a `map` from
318+`life`s to `ring`s that keeps track of all `life`-`ring` pairs throughout the
319+history of the ship.
320+
321+
322+### `%trim`
323+
324+This `task` is sent by the interpreter in order to free up memory.
325+ This `task` is empty for Jael, since it is not a good idea to forget your
326+ private keys and other cryptographic data.
327+
328+#### Accepts
329+
330+```hoon
331+[p=@ud]
332+```
333+This argument is unused by Jael.
334+
335+#### Returns
336+
337+This task returns nothing.
338+
339+
340+
341+### `%turf`
342+
343+This `task` is a request for Jael to provide its list of `turf`s, e.g. DNS
344+suffixes for the Ames network. Currently `arvo.network` is the only `turf` in use.
345+
346+#### Accepts
347+
348+```hoon
349+[~]
350+```
351+
352+#### Returns
353+
354+```hoon
355+[%turn tuf.own.pki]
356+```
357+
358+Jael `%give`s a `%turf` `gift` in response to a `%turf` `task`. `tuf.own.pki` is
359+a `(list turf)`, which is Jael's list of `turf`s.
360+
361+
362+### `%vega`
363+
364+`%vega` is called whenever the kernel is updated. Jael currently does not do
365+anything in response to this.
366+
367+#### Accepts
368+
369+`%vega` takes no arguments.
370+
371+#### Returns
372+
373+This `task` returns no `gift`s.
374+
375+
376+
377+### `%wegh`
378+
379+This `task` is a request to Jael to produce a memory usage report.
380+
381+#### Accepts
382+
383+This `task` has no arguments.
384+
385+#### Returns
386+
387+In response to this `task,` Jael `%give`s a `%mass` `gift` containing Ames'
388+current memory usage.
389+
390+
391+
392+
393+
content/docs/arvo/overview.mdnew file+577
@@ -0,0 +1,577 @@
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+
34+# Table of Contents
35+
36+- [What is Arvo?](#what-is-arvo)
37+ * [An operating function](#an-operating-function)
38+ + [Determinism](#determinism)
39+ + [Event log](#event-log)
40+ * [Solid state interpreter](#solid-state-interpreter)
41+ + [Over-the-air updates](#over-the-air-updates)
42+ + [ACID Database](#acid-database)
43+ + [Single-level store](#single-level-store)
44+ + [Non-preemptive](#non-preemptive)
45+- [The kernel](#the-kernel)
46+ * [Overall structure](#overall-structure)
47+ + [Formal interface](#formal-interface)
48+ + [Types](#types)
49+ + [Arvo cores](#arvo-cores)
50+ * [The state](#the-state)
51+ * [Vanes](#vanes)
52+
53+# What is Arvo?
54+
55+Arvo is a [non-preemptive](#non-preemptive)
56+operating system purposefully built to create a new, peer-to-peer internet
57+whereby users own and manage their own data. Despite being an operating system,
58+Arvo does not replace Windows, Mac OS, or Linux. It is better to think of the
59+user experience of Arvo as being closer to that of a web browser despite being a
60+fully fledged OS. As such, Arvo is generally run inside a virtual machine, though in theory it could be run on bare metal.
61+
62+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.
63+
64+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.
65+
66+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.
67+
68+## An operating function
69+
70+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.
71+
72+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.
73+
74+In mathematical terms, one may think of Arvo as being given by a transition function _T_:
75+
76+```
77+T: (State, Input) -> (State, Output).
78+```
79+
80+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_:
81+
82+```
83+L: History -> State.
84+```
85+
86+Which perspective is more fruitful depends on the problem being considered.
87+
88+### Determinism
89+
90+We consider Arvo to be deterministic at a high level. By that we mean that it is
91+stacked on top of a frozen instruction set known as Nock. Frozen instruction
92+sets are a new idea for an operating system, but not for computing in general.
93+For instance, the CPU instruction sets such as
94+[x86-64](https://en.wikipedia.org/wiki/X86-64v) are frozen at the level of the
95+chip. A given operating system may be adapted to run on more than one CPU
96+instruction set, we merely freeze the instruction set at a higher level in order
97+to enable deterministic computation.
98+
99+Arvo handles nondeterminism in an interesting way. Deciding whether or not to
100+halt a computation that could potentially last forever becomes a heuristic
101+decision that is akin to dropping a packet. Thus it behooves one to think of
102+Arvo as being a stateful packet transceiver rather than an ordinary computer - events
103+are never guaranteed to complete, even if one can prove that the computation
104+would eventually terminate. We elaborate on this in the [solid state
105+interpreter](#solid-state-intrepeter) section.
106+
107+Because Arvo is run on a VM, nondeterministic information such as the stack
108+trace of an infinite loop that was entered into may be obtained. This is
109+possible because while Arvo may be unable to obtain that information, the
110+interpreter beneath does and can inject that information back into the event log.
111+
112+Being deterministic at a high level enables many
113+things that are out of reach of any other operating system. For
114+instance, we are able to do [over-the-air](#over-the-air-updates) (OTA) updates,
115+which allows software updates to be implemented across the network without
116+needing to worry whether it won't work on someone's ship, since Arvo is an
117+[interpreter](#solid-state-intrepeter) that can accept source code to
118+update itself instead of requiring a pre-compiled binary. This essential
119+property is why Urbit is able to act as a personal server while having
120+a user experience as accessible as a browser.
121+
122+### Event log
123+
124+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.
125+
126+The Arvo event log is a list of every action ever performed on your ship that
127+lead up to the current state. In principle, this event log is maintained by the
128+[Nock runtime environment](/docs/vere/), but in practice
129+event logs become too long over time to keep, as the event log has a size of
130+O(n) where n is the number of events. Thus it is our intention to
131+implement a feature whereby periodic snapshots of the state of Arvo are taken
132+and the log up to that state is pruned. This is currently unnecessary and thus
133+this feature has not been prioritized.
134+
135+The beginning of the event log starting from the very first time a ship is
136+booted up until the kernel is compiled and identity and entropy are created is a
137+special portion of the Arvo lifecycle known as the _larval stage_. We describe
138+the larval stage in more detail in the [larval stage](#larval-stage-core) section.
139+
140+More information on the structure of the Arvo event log and the Arvo state is given in the section on [the kernel](#the-kernel).
141+
142+
143+
144+## Solid state interpreter
145+
146+Arvo is a _solid state interpreter_. In this section we describe what is meant
147+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).
148+
149+In computer science, an _interpreter_ is a program that directly executes
150+instructions written in some human-understandable programming or scripting
151+language, rather than requiring the code to first be compiled into a machine
152+language. Arvo is an interpreter, which is important for us since it allows us
153+to perform deterministic [over-the-air updates](#over-the-air-updates) by the
154+direct transfer of raw source code.
155+
156+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.
157+
158+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.
159+
160+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.
161+
162+Another way to describe a solid state interpreter is to think of it as a
163+stateful packet transceiver. Imagine
164+it as a chip. Plug this chip into power and network; packets go in and
165+out, sometimes changing its state. The chip never loses data and has
166+no concept of a reboot; every packet is an [ACID transaction](#acid-database).
167+
168+
169+### Over-the-air updates
170+
171+Arvo can hotpatch any other semantics at any layer in the system (apps, vanes, Arvo or Hoon itself) with automatic over-the-air updates.
172+
173+Typically, updates to an operating system are given via a pre-compiled binary,
174+which is why some updates will work on some systems but not on others where the
175+hardware and environment may differ. This is not so on Arvo - because it is an
176+[interpreter](#solid-state-interpreter), Arvo may update itself by receiving
177+source code from your sponsor over [Ames](/docs/arvo/ames/ames), our
178+network. As Hoon compiles down to Nock, which is an axiomatic representation of
179+a deterministic computer, this code is guaranteed to run identically on your machine as it
180+would on anybody else's.
181+
182+Some subtleties regarding types arise when handling OTA updates, since they can
183+potentially alter the type system. Put more concretely, the type of `type` may
184+be updated. In that case, the update is an untyped Nock formula from the
185+perspective of the old kernel, but ordinary typed Hoon code from the perspective of
186+the new kernel. Besides this one detail, the only functionality of the Arvo
187+kernel proper that is untyped are its interactions with the Unix runtime.
188+
189+### ACID Database
190+
191+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.
192+
193+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.
194+
195+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.
196+
197+ - 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.
198+
199+ - 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.
200+
201+ - Isolation: Transactions in databases often happen concurrently, and isolation
202+ ensures that the transactions occur as if they were performed sequentially,
203+ making it so that their effects are isolated from one another. Arvo ensures
204+ this simply by the fact that it only ever performs events sequentially. While
205+ Arvo
206+ transactions are sequential and performed by the daemon, persistence and effect application are performed
207+ in parallel by the worker; see [worker and
208+ daemon](/docs/vere/) for more detail.
209+
210+ - Durability: Completed transactions will survive permanently. In other words,
211+ since the event log is stored on disk, if power is lost you are guaranteed
212+ that no transactions will be reversed.
213+
214+It is easy to think that "completed transaction will survive permanently"
215+along with "the state of Arvo is pure function of its event log" implies that
216+nothing can ever be deleted. This is not quite true.
217+[Clay](/docs/arvo/clay/clay) is our [referentially
218+transparency](https://en.wikipedia.org/wiki/Referential_transparency)
219+file system, which could naively be thought to mean that since data must be
220+immutable, files cannot be deleted. However, Clay can replace a file with a
221+"tombstone" that causes Clay to crash whenever it is accessed. Referential
222+transparency only guarantees that there won't be new data at a previously
223+accessed location - not that it will still be available.
224+
225+### Single-level store
226+
227+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.
228+
229+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.
230+
231+### Non-preemptive
232+
233+Most operating systems are preemptive, meaning that they regularly interrupt
234+tasks being performed with the intention of resuming that task at a later time,
235+without the task explicitly yielding control.
236+Arvo does not do this - tasks run until they are complete or are cancelled due
237+to some heuristic, such as taking too long or because the user pressed Ctrl-C.
238+This is known as
239+[non-preemptive](https://en.wikipedia.org/wiki/Cooperative_multitasking) or
240+cooperative multitasking.
241+
242+
243+> Parts of the remainder of this document are out of date as of 2020.07.20, please use information here with
244+> caution. This message will be removed once it is up to date.
245+
246+
247+# The kernel
248+
249+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.
250+
251+This section requires an understanding of Hoon of at least the level of Chapter One of the [Hoon tutorial](/docs/hoon/hoon-school/).
252+
253+After concluding this section, the reader is encouraged to follow along with the
254+[move trace tutorial](/docs/arvo/tutorials/move-trace),
255+which applies many of the concepts covered below.
256+
257+## Overall structure
258+
259+`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:
260+ + Types
261+ + Section 3bE Arvo Core
262+ + Implementation core
263+ + Structural interface core, or adult core
264+ + Larval stage core
265+ + Formal interface
266+
267+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.
268+
269+### Formal interface
270+
271+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.
272+
273+```hoon
274+ :: Arvo formal interface
275+ ::
276+ :: this lifecycle wrapper makes the arvo door (multi-armed core)
277+ :: look like a gate (function or single-armed core), to fit
278+ :: urbit's formal lifecycle function. a practical interpreter
279+ :: can ignore it.
280+ ::
281+ |= [now=@da ovo=*]
282+ ^- *
283+ ~> %slog.[0 leaf+"arvo-event"]
284+ .(+> +:(poke now ovo))
285+```
286+
287+### Types
288+
289+This core contains the most basic types utilized in Arvo. We discuss a number of them here.
290+
291+#### `+duct`
292+
293+```hoon
294+++ duct (list wire) :: causal history
295+```
296+
297+Arvo is designed to avoid the usual state of complex event networks: event
298+spaghetti. We keep track of every event's cause so that we have a clear causal
299+chain for every computation. At the bottom of every chain is a Unix I/O event,
300+such as a network request, terminal input, file sync, or timer event. We push
301+every step in the path the request takes onto the chain until we get to the
302+terminal cause of the computation. Then we use this causal stack to route
303+results back to the caller.
304+
305+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.
306+
307+Here's a `duct` that was recently observed in the wild upon entering `-time ~s1`
308+into the dojo and pressing Enter, which sets a timer for one second that will
309+then produce a `@d` with the current time after the timer has elapsed:
310+
311+```
312+~[
313+ /g/a/~zod/4_shell_terminal/u/time
314+ /g/a/~zod/shell_terminal/u/child/4/main
315+ /g/a/~zod/terminal/u/txt
316+ /d/term-mess
317+ //term/1
318+]
319+```
320+
321+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.
322+
323+Behn saves this `duct`, so that when the specified time arrives and Unix sends a
324+wakeup event to the timer vane, it can produce the response on the same `duct`.
325+This response is routed to the place we popped off the top of the `duct`, i.e. the
326+time app. This app returns a `@d` which denotes the current time, which falls down to the shell,
327+which drops it through to the terminal. Terminal drops this down to Dill, which
328+converts it into an effect that Unix will recognize as a request to print the
329+current time to the screen. When Dill produces this, the last path in the `duct` has an
330+initial element of the empty span, so this is routed to Unix, which applies the effects.
331+
332+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.
333+
334+
335+#### `wire`
336+
337+```hoon
338+++ wire path :: event pretext
339+```
340+
341+Synonym for `path`, used in `duct`s. These should be thought of as a list of symbols
342+representing a cause.
343+
344+#### `move`
345+
346+```hoon
347+++ move [p=duct q=arvo] :: arvo move
348+```
349+
350+If `duct`s are a call stack, then how do we make calls and produce results? Arvo
351+processes `move`s which are a combination of message data and metadata. There
352+are four types of `move`s: `%pass`, `%give`, `%slip`, and `%unix`.
353+
354+A `%pass` `move` is analogous to a call:
355+
356+```
357+[duct %pass return-path=path vane-name=@tD data=card]
358+```
359+
360+Arvo pushes the return path (preceded by the first letter of the vane name) onto
361+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`.
362+
363+A `%give` `move` is analogous to a return:
364+
365+```
366+[duct %give data=card]
367+```
368+
369+Arvo pops the top `wire` off the `duct` and sends the given `card` back to the caller.
370+
371+A `%slip` `move` is a cousin of `%pass`. Any `card` that can be `%pass`ed can also be
372+`%slip`ed, but while a `%pass` says to "push this `wire` onto the `duct` and
373+transfer control to the receiving vane", a `%slip` transfers control to the
374+receiving vane without altering the `duct`. Therefore, a `%give` in response to
375+a `%slip` will go to the caller of the vane that sent the `%slip` rather than
376+the vane that actually sent the `%slip`. `%slip`s are much more rare than
377+`%pass`es and `%give`s. In general, `%slip` and `%pass` `move`s are
378+both referred to as "passes" and it should be clear from the context if one
379+means to refer only to `%pass`es and not `%slip`s or vice versa. Lastly, we note
380+that `%slip` is a code smell and should nearly always be avoided. It can result
381+in unexpected behavior like receiving a gift from a vane you never passed a note to.
382+
383+Lastly, a `%unix` `move` is how Arvo represents communication from Unix, such as a
384+network request or terminal input.
385+
386+#### `card`s and `curd`s
387+
388+`card`s are the vane-specific portion of a `move`, while `curd`s are typeless
389+`card`s utilized at the level of the kernel. `card`s are not actually defined in
390+`arvo.hoon`, rather they are given by `+note-arvo` and `+sign-arvo` in the
391+standard library `zuse`
392+(which then refer to `+task` and `+gift` in each of the vane cores), but they are closely
393+connected to `curd`s so we speak of them in the same breath.
394+
395+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.
396+
397+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`.
398+
399+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`.
400+
401+When a `task` `card` is `%pass`ed to a vane, Arvo calls its `+call` gate,
402+passing it both the `card` and its `duct`. This gate must be defined in every vane.
403+It produces two things in the following order: a list of `move`s and a possibly
404+modified copy of its context. The `move`s are used to interact with other vanes,
405+while the new context allows the vane to save its state. The next time Arvo
406+activates the vane it will have this context as its subject.
407+
408+This cycle of `%pass`ing a `note` to `%pass`ing a `task` to `%give`ing a `gift`
409+to `%give`ing a `%sign` is summarized in the following diagram:
410+
411+<div style="text-align:center">
412+<img class="mv5 w-150" src="https://media.urbit.org/docs/arvo/cycle.png">
413+</div>
414+
415+Note that `%pass`ing a `note` doesn't _always_ result in a return - this diagram
416+just
417+shows the complete cycle. However, `%give`ing a `gift` is always in response to being
418+`%pass`ed some `task`. Since the Arvo kernel acts as a middleman between all `move`s in Arvo, in diagrams we will
419+generally represent the intermediate steps of a vane `%pass`ing a `note` to the kernel addressed to
420+another vane followed by the kernel `%pass`ing a `task` to the
421+addressed vane as a single arrow from one vane to the other to make the diagrams
422+less cluttered.
423+
424+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.
425+
426+#### `ovum`
427+
428+This mold is used to represent both steps and actions.
429+
430+A pair of a `wire` and a `curd`, with a `curd` being like a typeless `card`. The
431+reason for a typeless `card` is that this is the data structure which Arvo uses
432+to communicate with the runtime, and Unix events have no type. Additionally,
433+upgrading the kernel may alter the type system and thus may not be able to be
434+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.
435+
436+### Arvo cores
437+
438+`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.
439+
440+A short summary of the purpose of each these arms are as follows:
441+
442+ - `+poke` is the transition function that `move`s Arvo from one state to the
443+ next. It is the most fundamental arm in the entire system. It is a typed
444+ transactional message that is processed at most once. If the `+poke` causes
445+ Arvo to send an message over [Ames](/docs/arvo/ames/ames) Ames
446+ guarantees that the message will be delivered exactly once. This is sometimes said
447+ to be impossible, and it is for standard operating systems, but that is not the case for single-level stores engaged in
448+ a permanent session, as is the case among Arvo ships.
449+ - `+peek` is an arm used for inspecting things outside of the kernel. It grants
450+ read-only access to `scry` Arvo's global referentially transparent namespace.
451+ It takes in a `path` and returns a `unit (unit)`. If the product is `~`, the
452+ path is unknown and its value cannot be produced synchronously. If its
453+ product is `[~ ~]` the `path` is known to be unbound and can never become
454+ bound. Otherwise the product is a `mark` and a noun.
455+ - `+wish` is a function that takes in a core and then parses and compiles it
456+ with the standard library, `zuse`. It is useful from the outside if you ever
457+ want to run code within. One particular way in which it is used is by the
458+ runtime to read out the version of `zuse` so that it knows if it is
459+ compatible with this particular version of the kernel.
460+ - `+load` is used when upgrading the kernel. It is only ever called by Arvo
461+ itself, never by the runtime. If upgrading to a kernel where types are
462+ compatible, `+load` is used, otherwise `+come` is used.
463+ - `+come` is used when the new kernel has incompatible types, but ultimately
464+ reduces to a series of `+load` calls.
465+
466+ The [Section 3bE core](#section-3be-core) does not follow this pattern.
467+
468+#### Section 3bE core
469+
470+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.
471+
472+#### Implementation core
473+
474+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.
475+
476+#### Structural interface core
477+
478+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.
479+
480+#### Larval stage core
481+
482+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:
483+
484+ + The standard library, `zuse`, is installed.
485+ + Entropy is added
486+ + Identity is added
487+ + Metamorph into the next stage of Arvo
488+
489+Once the larval stage has passed its functionality will never be used again.
490+
491+## The state
492+
493+As we follow functional programming paradigms, the state of Arvo is considered
494+to be the entire Arvo kernel core currently in operation (whether it be the larval
495+stage or adult stage). Thus when `+poke` is performed, a new core with the
496+updated state is produced, rather than modifying the existing core as would be
497+expected to happen in an imperative setting.
498+
499+Thus besides the battery of the Arvo core, we have the [payload](/docs/glossary/payload/) which is as
500+follows.
501+
502+```hoon
503+:: persistent arvo state
504+::
505+=/ pit=vase !>(..is) ::
506+=/ vil=vile (viol p.pit) :: cached reflexives
507+=| $: lac=_& :: laconic bit
508+ eny=@ :: entropy
509+ our=ship :: identity
510+ bud=vase :: %zuse
511+ vanes=(list [label=@tas =vane]) :: modules
512+ == ::
513+```
514+
515+Let's investigate the state piece by piece.
516+
517+```hoon
518+=/ pit=vase !>(..is) ::
519+```
520+This `vase` is part of the state but does not get directly migrated when `+poke`
521+is called. `!>(..is)` consists of the code in `arvo.hoon` written above this core contained in
522+a `vase`. Thus this part of the state changes only when that code changes in an
523+update.
524+
525+```hoon
526+=/ vil=vile (viol p.pit) :: cached reflexives
527+
528+```
529+This is a cache of specific types that are of fundamental importance to Arvo -
530+namely `type`s, `duct`s, `path`s, and `vase`s. This is kept because it is
531+unnecessarily wasteful to recompile these fundamental types on a regular basis.
532+Again, this part of the state is never updated directly by `+poke`.
533+
534+```hoon
535+=| $: lac=_& :: laconic bit
536+ eny=@ :: entropy
537+ our=ship :: identity
538+ bud=vase :: %zuse
539+ vanes=(list [label=@tas =vane]) :: modules
540+ ==
541+```
542+This is where the real state of the Arvo kernel is kept. `lac` detemines whether
543+Arvo's output is verbose, which can be set using the `|verb` command in the
544+dojo. `eny` is the current entropy. `our` is the ship, which is permanently
545+frozen during the larval stage. `bud` is the standard library. Lastly, `vanes`
546+is of course the list of vanes, which have their own internal states.
547+
548+As you can see, the state of Arvo itself is quite simple. Its primary role is that of
549+a traffic cop, and most of the interesting part of the state lies in `vanes`.
550+
551+
552+## Vanes
553+
554+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.
555+
556+As described above, we use Arvo proper to route and control the flow of `move`s.
557+However, Arvo proper is rarely directly responsible for processing the event
558+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.
559+
560+As of this writing, we have nine vanes, which each provide the following services:
561+
562+- [Ames](/docs/arvo/ames/ames): the name of both our network and the vane that communicates over it.
563+- [Behn](/docs/arvo/behn/behn): a simple timer.
564+- [Clay](/docs/arvo/clay/clay): our version-controlled, referentially- transparent, and global filesystem.
565+- [Dill](/docs/arvo/dill/dill): a terminal driver. Unix sends keyboard events to `%dill` from the console, and `%dill` produces terminal output.
566+- [Eyre](/docs/arvo/eyre/eyre): an http server. Unix sends http messages to `%eyre`, and `%eyre` produces http messages in response.
567+- [Ford](/docs/arvo/ford/ford): a build system also utilized for marks
568+ (file types) and debugging.
569+- [Gall](/docs/userspace/gall/gall): manages our userspace applications. `%gall` keeps state and manages subscribers.
570+- `Iris`: an http client.
571+- `Jael`: storage for Azimuth information.
572+
573+#### Applying your knowledge
574+
575+Now that you've learned about the nuts and bolts of the Arvo kernel, why not
576+check it out in action? An in-depth "move trace" tutorial for running a timer app
577+is available [here](/docs/arvo/tutorials/move-trace).
content/docs/arvo/reference/_index.mdnew file+11
@@ -0,0 +1,11 @@
1++++
2+title = "Reference"
3+weight = 1
4+sort_by = "weight"
5+template = "sections/docs/chapters.html"
6++++
7+
8+[Cryptography](@/docs/arvo/reference/cryptography.md)
9+
10+An overview of where Arvo uses cryptography, what algorithms are used, and how
11+they are implemented.
content/docs/arvo/reference/cryptography.mdnew file+222
@@ -0,0 +1,222 @@
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.md). `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.md) and the
14+[SHA Hash Family](@/docs/hoon/reference/stdlib/3d.md) 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.md#crypto-core)-shaped core.
22+
23+## `+crub:crypto` {#crub}
24+
25+`+crub:crypto` implements an
26+[`+acru:ames`](@/docs/arvo/ames/cryptography.md#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.md) makes use of.
202+
203+Most gates in `+ed:crypto` are [jetted](@/docs/vere/jetting.md), 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.md#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.md#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.mdnew file+69
@@ -0,0 +1,69 @@
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 the `%home` `desk`
8+are used for. This organization is merely a convention, and the exact location
9+of any file does not affect its operation. That being said, some [Ford
10+runes](@/docs/arvo/ford/ford.md) are designed with this structure in mind, and
11+applications such as dojo look in specific folders for code to run. Furthermore,
12+this organization is not perfectly adhered to - sometimes you may find structure
13+definitions in `/lib`, for example.
14+
15+- `/app` contains userspace applications, i.e. [Gall
16+ agents](@/docs/userspace/gall/gall.md).
17+- `/gen` contains generators. Many applications make use of generators, but
18+ also each generator in this folder may be run from dojo using `+`. For
19+ example, `/gen/foo/hoon` is run with `+foo`.
20+- `/lib` contains libraries that may be shared by multiple agents, threads,
21+ generators, etc. However, this is not the location of the standard libraries
22+ (see `/sys`). Libraries are imported from `/lib` with `/+`.
23+- `/mar` contains [mark](@/docs/arvo/clay/architecture.md#marks) definitions.
24+- `/sur` contains shared [structure](@/docs/hoon/reference/rune/_index.md) definitions.
25+ Whenever you expect structures to be used by code across multiple files, it
26+ is recommended to place their shared structures in `/sur`. Structures are
27+ imported from `/sur` with `/-`.
28+- `/sys` contains the code that defines the kernel and standard libraries.
29+ `/sys/vane` contains the code for the vanes, aka kernel modules. `/sys` is
30+ the exception to the rule - structures and functions that are central to
31+ Hoon, Arvo, and its vanes, are all located within this folder rather than in
32+ `/lib` and `/sur`. See [below](#sys) for more information on `/sys`.
33+- `/ted` contains [threads](@/docs/userspace/threads/overview.md). These may be
34+ run from dojo using `-`. For example, `/ted/foo/hoon` is run with `-foo`.
35+- `/tests` contains unit tests intended to be run using the `test` thread. To
36+ 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
37+ run. If a folder is specified, every test in that folder will run.
38+
39+## `/sys` {#sys}
40+
41+`/sys` contains four files: `hoon.hoon`, `arvo.hoon`, `lull.hoon`, and
42+`zuse.hoon`. These are the files used to construct kernelspace. The chain of
43+dependencies is `hoon.hoon` -> `arvo.hoon` -> `lull.hoon` -> `zuse.hoon`. We
44+give a brief description of each of them.
45+
46+- `hoon.hoon` contains the Hoon compiler and the [Hoon standard
47+ library](@/docs/hoon/reference/stdlib/table-of-contents.md). The Hoon
48+ compiler is self-hosted. This is the first file loaded by the Nock virtual
49+ machine, [Vere](@/docs/vere/runtime.md), in order for it to learn how to
50+ interpret Hoon. The kelvin version number is the subject of `hoon.hoon`,
51+ currently at 140. One may see this from dojo by inspecting the subject with
52+ `.` and noting that `%140` is the final entry of the subject.
53+- `arvo.hoon` contains the [Arvo kernel](@/docs/arvo/overview.md) and
54+ additional structures and functions directly relevant to the kernel. This is
55+ Urbit's "traffic cop", and as such contains the structure definitions for
56+ call stacks such as `duct`s and `bone`s. Once Vere understands Hoon, it loads
57+ and interprets `arvo.hoon` to create the kernel. `hoon.hoon` is the subject
58+ of `arvo.hoon`.
59+- `lull.hoon` primarily contains structures shared among the kernel and its
60+ vanes, as well as a few functions. In particular, this includes the
61+ definitions of the `card`s utilized by each vane, each of which are
62+ documented in their respective documentation. `lull.hoon` is loaded by the
63+ kernel during the [larval stage](@/docs/arvo/overview.md#larval-stage-core)
64+ in order to prepare to create the vanes. `arvo.hoon` is the subject of `lull.hoon`.
65+- `zuse.hoon` is the Arvo standard library. It consists primarily of functions
66+ shared by the kernel and vanes, such as the ones related to
67+ [cryptography](@/docs/arvo/reference/cryptography.md). `zuse.hoon` is loaded
68+ by the larval kernel following `lull.hoon`. `lull.hoon` is the subject of
69+ `zuse.hoon`. Then `zuse` is the subject of the vanes.
content/docs/arvo/tutorials/_index.mdnew file+9
@@ -0,0 +1,9 @@
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.mdnew file+378
@@ -0,0 +1,378 @@
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+followed by a pause of one second, then
48+```
49+["" %unix p=%wake //behn ~2020.1.14..19.01.26..755d]
50+["|" %give %b %doze [i=//behn/0v1p.sn2s7 t=~]]
51+["|" %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]]]
52+["||" %give %g [%unto %fact] [i=/g/use/dojo/~zod/out/~zod/spider/drum/wool t=~[/d //term/1]]]
53+["|||" %give %g [%unto %fact] [i=/g/use/hood/~zod/out/~zod/dojo/drum/phat/~zod/dojo t=~[/d //term/1]]]
54+["||||" %give %g [%unto %fact] [i=/d t=~[//term/1]]]
55+["|||||" %give %d %blit [i=//term/1 t=~]]
56+["||" %give %g [%unto %kick] [i=/g/use/dojo/~zod/out/~zod/spider/drum/wool t=~[/d //term/1]]]
57+~s1..0007
58+```
59+This gives us a move trace that is a list of `move`s and some
60+associated metadata. Some of the `move`s are a bit of a distraction from what's
61+going on overall such as acknowledgements that a `poke` was received
62+(`%poke-ack`s), so we've omitted them for clarity. Furthermore, two `move`s (the
63+`%blit` `card`s) is not printed even in verbose mode because it occurs so
64+frequently, but there are only two of them here and so we have added it in.
65+
66+The main process that is occurring here is a sequence of `%pass` `move`s initiated
67+by pressing Enter in the terminal that goes on to be handled by Dill, then Gall,
68+and finally Behn. After the timer has elapsed, a sequence of `%give` `move`s is
69+begun by Behn, which then passes through Gall and ultimately ends up back at the
70+terminal. Any `move`s besides `%pass` in the first segment of the move trace is a
71+secondary process utilized for book-keeping, spawning processes, interpreting
72+commands, etc. All of this will be explained in detail below.
73+
74+
75+It is important to note that this move trace should be thought of
76+as being from the "point of view" of the kernel - each line represents the
77+kernel taking in a message from one source and passing it along to its
78+destination. It is then processed at that destination (which could be a vane or
79+an app), and the return of that process is sent back to Arvo in the form of
80+another `move` to perform and the loop begins again. Thus this move trace does
81+not display information about what is going on inside of the vane or app such as
82+private function calls, only what the kernel itself sees.
83+
84+## Interpreting the move trace
85+
86+In this section we will go over the move trace line-by-line, explaining how the
87+move trace is printed, what each line means (including some things not found in
88+the move trace), and a particular focus on what code is being activated in the
89+first few lines that should equip you well enough to unravel the rest of the
90+move trace in as much detail as you desire.
91+
92+
93+### The call
94+
95+Let's put the first part of the move trace into a diagram to make following
96+along a little easier.
97+
98+<div style="text-align:center">
99+<img src="https://media.urbit.org/docs/arvo/move-trace-with-key.png">
100+</div>
101+
102+Here, each arrow represents the passing of some information, with most of it
103+being from vane to vane. Here, when Vane A has an arrow to a card and then an
104+arrow to Vane B, this represents either a `%pass` `note/task` sequence or a
105+`%give` `gift/sign` sequence that actually has the Arvo kernel in the middle.
106+That is to say, Vane A `%pass`es a `note` to the Arvo kernel addressed to Vane
107+B, and the Arvo kernel then `%pass`es a `task` to Vane B. For more information,
108+see the [Arvo kernel tutorial](/docs/arvo/overview#the-kernel).
109+
110+This simple action ends up involving four vanes - Dill, Gall, Behn, and Ford -
111+as well as four applications - hood, spider, dojo, and time.
112+
113+Now let's go through each line one by one.
114+```
115+["" %unix p=%belt //term/1 ~2020.1.14..19.01.25..7556]
116+```
117+This tells us that Unix has sent a `%belt` `card`, which corresponds to
118+terminal input (the Enter keystroke) at time `~2020.1.14..19.01.25..7556`
119+
120+Here is the line of code in `arvo.hoon`, found in the [section
121+3bE core](/docs/arvo/overview#section-3be-core), that generated the output:
122+
123+```hoon
124+ ~? !lac ["" %unix -.q.ovo p.ovo now]
125+```
126+First we note that this line is executed only if the laconic bit is set to true,
127+as we did when we input `|verb`. Here, `ovo` is the input `ovum`. Knowing that an `ovum` is a `[p=wire q=curd]`,
128+we can then say that this is a `%unix` `move` tagged with `%belt` whose cause is a `wire` given by `//term/1`,
129+where the empty span `//` represents Unix and `term/1` represents the terminal
130+in Unix. Here we have a `wire` instead of a `duct` (i.e. a list of `wire`s)
131+since Unix I/O events are always the beginning and end of the Arvo event loop,
132+thus only a single `wire` is ever required at this initial stage.
133+
134+The `""` here is a metadatum that keeps track of how many steps deep in the
135+causal chain the event is. An event
136+with `n` `|`'s was caused by the most recent previous event with `n-1` `|`'s. In
137+this case, Unix events are an "original cause" and thus represented by an empty
138+string.
139+
140+At this point in time, Dill has received the `move` and then processes it. The
141+`%belt` `task` in `dill.hoon` is `+call`ed, which is processed using the `+send`
142+arm:
143+
144+```hoon
145+ ++ send :: send action
146+ |= bet/dill-belt
147+ ^+ +>
148+ ?^ tem
149+ +>(tem `[bet u.tem])
150+ (deal / [%poke [%dill-belt -:!>(bet) bet]])
151+```
152+
153+Dill has taken in the command and in response it `%pass`es a `task` `card` with
154+instructions to `%poke` hood, which is a Gall app
155+primarily used for interfacing with Dill. Here, `+deal` is an arm for
156+`%pass`ing a `card` to Gall to ask it to create a `%deal` `task`:
157+
158+
159+```hoon
160+ ++ deal :: pass to %gall
161+ |= [=wire =deal:gall]
162+ (pass wire [%g %deal [our our] ram deal])
163+```
164+
165+Next in our move trace we have this:
166+```
167+["|" %pass [%d %g] [[%deal [~zod ~zod] %hood %poke] /] [i=//term/1 t=~]]
168+```
169+Here, Dill `%pass`es a `task` `card` saying to `%poke` Gall's hood app (with the
170+Enter keystroke).
171+
172+Let's glance at part of the `+jack` arm in `arvo.hoon`, located in the [section 3bE
173+core](/docs/arvo/overview#section-3be-core). This arm is what the Arvo kernel uses to send `card`s,
174+and here we look at the segment that includes `%pass` `move`s.
175+
176+```hoon
177+ ++ jack :: dispatch card
178+ |= [lac=? gum=muse]
179+ ^- [[p=(list ovum) q=(list muse)] _vanes]
180+ ~| %failed-jack
181+ :: =. lac |(lac ?=(?(%g %f) p.gum))
182+ :: =. lac &(lac !?=($b p.gum))
183+ %^ fire
184+ p.gum
185+ s.gum
186+ ?- -.r.gum
187+ $pass
188+ ~? &(!lac !=(%$ p.gum))
189+ :- (runt [s.gum '|'] "")
190+ :^ %pass [p.gum p.q.r.gum]
191+ ?: ?=(?(%deal %deal-gall) +>-.q.q.r.gum)
192+ :- :- +>-.q.q.r.gum
193+ (,[[ship ship] term term] [+>+< +>+>- +>+>+<]:q.q.r.gum)
194+ p.r.gum
195+ [(symp +>-.q.q.r.gum) p.r.gum]
196+ q.gum
197+ [p.q.r.gum ~ [[p.gum p.r.gum] q.gum] q.q.r.gum]
198+```
199+
200+Code for writing traces can be a bit tricky, but let's try not to get too
201+distracted by the lark expressions and such. By paying attention to the lines
202+concerning the laconic bit (following `!lac`) we can mostly determine what is being told to us.
203+
204+From the initial input event, Arvo has generated a `card` that it is now
205+`%pass`ing from Dill (represented by `%d`) to Gall (represented by `%g`). The
206+`card` is a `%deal` `task`, asking Gall to `%poke` hood using data that has
207+originated from the terminal `//term/1`, namely that the Enter key was pressed. The line `:- (runt [s.gum '|'] "")`
208+displays the causal chain length metadatum mentioned above. Lastly, `[~zod ~zod]` tells us that
209+`~zod` is both the sending and receiving ship.
210+
211+From here on our explanations will be more brief. We include some information
212+that cannot be directly read from the move trace in [brackets]. Onto the next line:
213+
214+```
215+["||" %pass [%g %g] [[%deal [~zod ~zod] %dojo %poke] /use/hood/~zod/out/~zod/dojo/drum/phat/~zod/dojo] [i=/d t=~[//term/1]]]
216+```
217+
218+Here is another `%pass` `move`, this time from Gall to iself as denoted by `[%g
219+%g]`. Gall's hood has received the `%deal` `card` from Dill, and in response it is
220+`%poke`ing dojo with the information [that Enter was pressed].
221+
222+```
223+["|||" %give %g [%unto %fact] [i=/g/use/hood/~zod/out/~zod/dojo/drum/phat/~zod/dojo t=~[/d //term/1]]]
224+```
225+
226+Gall's dojo `%give`s a `gift` with a `%fact` (subscription update) to Gall's hood, [saying to clear
227+the terminal prompt].
228+
229+```
230+["||||" %give %g [%unto %fact] [i=/d t=~[//term/1]]]
231+```
232+Gall's hood `%give`s a `gift` with a `%fact` to Dill [saying to replace the current terminal line with `~zod:dojo>`]
233+
234+Next is the `move` that is not actually printed in the move trace mentioned
235+above:
236+
237+```
238+["|||||" %give %d %blit [i=//term/1 t=~]]
239+```
240+
241+Dill `%give`s a `%blit` (terminal output) event to Unix [saying to replace the current terminal line with `~zod:dojo>`].
242+
243+```
244+["|||" %pass [%g %f] [%build /use/dojo/~zod/drum/hand] [i=/d t=~[//term/1]]]
245+```
246+
247+Gall's dojo also `%pass`es a `%build` request to Ford [asking to run "~s1" against the subject we use in the dojo].
248+
249+```
250+["||||" %give %f %made [i=/g/use/dojo/~zod/drum/hand t=~[/d //term/1]]]
251+```
252+
253+Ford `%give`s a result back to dojo [with the value `~s1`]
254+
255+```
256+["|||||" %pass [%g %g] [[%deal [~zod ~zod] %spider %watch] /use/dojo/~zod/out/~zod/spider/drum/wool] [i=/d t=~[//term/1]]]
257+```
258+
259+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].
260+
261+```
262+["||||||" %give %g [%unto %watch-ack] [i=/g/use/dojo/~zod/out/~zod/spider/drum/wool t=~[/d //term/1]]]
263+```
264+
265+Gall's spider acknowledges the subscription from dojo.
266+
267+```
268+["|||||" %pass [%g %g] [[%deal [~zod ~zod] %spider %poke] /use/dojo/~zod/out/~zod/spider/drum/wool] [i=/d t=~[//term/1]]]
269+```
270+
271+Gall's dojo also `%pass`es a `%poke` to Gall's spider [asking it start the thread "-time" with argument `~s1`].
272+
273+```
274+["||||||" %pass [%g %f] [%build /use/spider/~zod/find/~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u] [i=/d t=~[//term/1]]]
275+```
276+
277+Gall's spider `%pass`es a `%build` request to Ford [asking it to find the path in `/ted` where the "time" thread is].
278+
279+```
280+["|||||||" %give %f %made [i=/g/use/spider/~zod/find/~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u t=~[/d //term/1]]]
281+```
282+
283+Ford `%give`s a result back to Gall's spider [saying it's in `/ted/time.hoon`].
284+
285+```
286+["||||||||" %pass [%g %f] [%build /use/spider/~zod/build/~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u] [i=/d t=~[//term/1]]]
287+```
288+
289+Gall's spider `%pass`es a `%build` request to Ford [asking it to compile the file `/ted/time.hoon`].
290+
291+```
292+["|||||||||" %give %f %made [i=/g/use/spider/~zod/build/~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u t=~[/d //term/1]]]
293+```
294+
295+Ford `%give`s a result back to Gall's spider [with the compiled thread].
296+
297+```
298+["||||||||||" %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]]]
299+```
300+
301+Gall's spider's thread with id `~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u` asks Behn to set a timer [for one second].
302+
303+```
304+["|||||||||||" %give %b %doze [i=//behn/0v1p.sn2s7 t=~]]
305+```
306+
307+Behn `%give`s a `%doze` `card` to Unix, asking it to set a timer [for one second from
308+now]. At this point Arvo may rest.
309+
310+### The return
311+
312+Now Unix sets a timer for one second, waits one second, and then informs Behn that a second has
313+passed, leading to a chain of `%give` `move`s that ultimately prints
314+`~s1..0007`.
315+
316+Let's throw the move trace into a table:
317+
318+| length | move | vane(s) | card | duct |
319+|--------|---------|---------|-----------------|------------------------------------------------------------------------------------------------------------------|
320+| 0 | `%unix` | | `%wake` | `//behn` |
321+| 1 | `%give` | `%b` | `%doze` | `//behn/0v1p.sn2s7` |
322+| 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` |
323+| 2 | `%give` | `%g` | `[%unto %fact]` | `/g/use/dojo/~zod/out/~zod/spider/drum/wool /d //term/1` |
324+| 3 | `%give` | `%g` | `[%unto %fact]` | `/g/use/hood/~zod/out/~zod/dojo/drum/phat/~zod/dojo /d //term/1` |
325+| 4 | `%give` | `%g` | `[%unto %fact]` | `/d //term/1` |
326+| 5 | `%give` | `%d` | `%blit` | `//term/1` |
327+| 2 | `%give` | `%g` | `[%unto %kick]` | `/g/use/dojo/~zod/out/~zod/spider/drum/wool /d //term/1` |
328+
329+Now we follow it line-by-line:
330+
331+```
332+["" %unix p=%wake //behn ~2020.1.14..19.01.26..755d]
333+```
334+
335+Unix sends a `%wake` (timer fire) `card` at time `~2020.1.14..19.01.26..755d`.
336+
337+```
338+["|" %give %b %doze [i=//behn/0v1p.sn2s7 t=~]]
339+```
340+
341+Behn `%give`s a `%doze` `card` to Unix, asking it to set a timer [for whatever next timer it has in its queue].
342+
343+```
344+["|" %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]]]
345+```
346+
347+Behn `%give`s a `%wake` to Gall's spider's thread with id `~.dojo_0v6.210tt.1sme1.ev3qm.qgv2e.a754u`.
348+
349+```
350+["||" %give %g [%unto %fact] [i=/g/use/dojo/~zod/out/~zod/spider/drum/wool t=~[/d //term/1]]]
351+```
352+
353+Gall's spider `%give`s a `%fact` (subscription update) to dojo [saying that the thread completed successfully and produced value `~s1.0007`].
354+
355+```
356+["|||" %give %g [%unto %fact] [i=/g/use/hood/~zod/out/~zod/dojo/drum/phat/~zod/dojo t=~[/d //term/1]]]
357+```
358+
359+Gall's dojo `%give`s a `%fact` to hood [saying to output `~s1..0007`].
360+
361+```
362+["||||" %give %g [%unto %fact] [i=/d t=~[//term/1]]]
363+```
364+
365+Gall's hood `%give`s a `%fact` to Dill [saying to output `~s1..0007`].
366+
367+```
368+["|||||" %give %d %blit [i=//term/1 t=~]]
369+```
370+
371+Dill `%give`s a `%blit` (terminal output) event to Unix [saying to print a new line with output `~s1..0007`].
372+
373+```
374+["||" %give %g [%unto %kick] [i=/g/use/dojo/~zod/out/~zod/spider/drum/wool t=~[/d //term/1]]]
375+```
376+
377+Gall's spider also closes the subscription from dojo [since the thread has completed].
378+
content/docs/azimuth/_index.mdnew file+22
@@ -0,0 +1,22 @@
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+
10+## [Azimuth](/docs/azimuth/azimuth)
11+
12+An overview of the Ethereum-based public key infrastructure utilized by Urbit.
13+
14+## [Life and Rift](/docs/azimuth/azimuth)
15+
16+An explanation of how Azimuth keeps track of the most recent set of networking
17+keys necessary to communicate with a ship.
18+
19+## [Advanced Azimuth Tools](/docs/azimuth/advanced-azimuth-tools)
20+
21+Expert-level tooling for generating, signing, and sending Azimuth-related
22+transactions from within Urbit itself.
content/docs/azimuth/advanced-azimuth-tools.mdnew file+68
@@ -0,0 +1,68 @@
1++++
2+title = "Advanced Azimuth Tools"
3+weight = 4
4+template = "doc.html"
5++++
6+
7+This document outlines some advanced techniques for generating, signing, and sending Azimuth-related transactions from within Urbit itself. It's strongly discouraged to do this unless you're very confident as Azimuth transactions are permanent and will cost ETH to complete. However, until you upload a signed transaction to the blockchain no transaction will take place so it's safe to explore these tools. It will also be very helpful to have at least a rudimentary understanding of Hoon in order to read and modify parts of the code.
8+
9+First you will want to [boot a fakezod](https://urbit.org/using/develop/#creating-a-development-ship). You can do this with your live running ship but at this time this will need you to modify the code so it's best to do this on a ship you can make mistakes on.
10+
11+Be sure to have mounted your home desk so you can easily edit files on it.
12+The first edit that will probably need to be made is in [`app/claz.hoon`](https://github.com/urbit/urbit/blob/85435e9a81e105809d5d381b5d34fae1d4daa3b8/pkg/arvo/app/claz.hoon#L14). The listed url will need to be changed to a valid Ethereum endpoint. infura.io provides an Ethereum API that you can use.
13+
14+The second change that may potentially be needed is to modify the [gas limit](https://github.com/urbit/urbit/blob/85435e9a81e105809d5d381b5d34fae1d4daa3b8/pkg/arvo/app/claz.hoon#L179). This number here is the maximum number of gas units that will be used. In future this will be configurable but for now you may need to change this manually. For a guide to what to set it to you can use the [constants in bridge](https://github.com/urbit/bridge/blob/29f4a14869489481a950a1af53f583d751897444/src/lib/constants.js#L23) as a guide based on what action you are going to be performing. The maximum cost of your transaction will be the maximum gas units multiplied by the gwei you're going to set later. You'll need at least this much in your account.
15+
16+Once you have made these changes be sure to run `|commit %home` to get them into your ship.
17+
18+Next run `|start %claz` after which you'll be able to generate transactions.
19+
20+```
21+:claz [%generate %/spawn/eth-txs %mainnet author %single %spawn ~ship to]
22+```
23+
24+Here we have an example of generating a transaction to spawn a ship. Something to note is that for this to be successful you'll need to actually have the right to spawn the ship in question. Let's break down the command.
25+
26+
27+`%generate` is how all commands to `claz` are going to start.
28+
29+`%/spawn/eth-txs` is simply the path for the output file
30+
31+`%mainnet` specifies which network this is going to sent out on. Other options are possible including the test-net `%ropsten`.
32+
33+`author` here is an Ethereum address that is issuing the transaction. It will need to be written in `@ux` notation, e.g. `0x3b17.d097.d9dd.711e.4ef8.517a.bbf1.8b2b.a643.81fe`.
34+
35+`%single` specifies what kind of batch that will be created. If you are going to do multiple transactions you will need to either set this to `%more` followed by a _list_ of batches, or generate the next transaction after having submitted the previous one to the blockchain.
36+
37+`[%spawn ~ship to]` is the transaction we want to issue. The arguments are will vary based on the transaction. `~ship` will be the ship to be spawned. `to` is the Ethereum address to spawn the ship to.
38+
39+You will want to read [`/sur/claz.hoon`](https://github.com/urbit/urbit/blob/85435e9a81e105809d5d381b5d34fae1d4daa3b8/pkg/arvo/sur/claz.hoon).
40+This will contain more details about the various kinds of transactions you can perform particularly `++call`
41+
42+After running this command you should find a csv file at the output path you specified. You can examine this file to learn how they are constructed. You are able to modify the nonces, gas limit and price without changing the functionality of the transaction but it's not important for this guide.
43+
44+This file can now be signed and uploaded. At this point, you can transfer this file to an airgapped machine which has your keys, if you want. If you choose to do that you will need to download the `urbit` binary as well as the most recent pill file or a copy of the fakezod pier you have already booted.
45+
46+For this guide, we'll continue on the same ship.
47+
48+Run `|start %eth-sender` and then you can use it to sign the transaction file.
49+
50+```
51+:eth-sender [%sign %/spawn-signed/txt %/spawn/eth-txs %/mykey/txt ~[40 80]]
52+```
53+
54+Let's break this down again.
55+
56+`%sign` is the action we are going to perform here. `eth-sender` can also be used to submit batches of transactions to the network in various ways, but details on that are outside of the scope of this guide.
57+
58+`%/spawn-signed/txt` is the path to the output file.
59+
60+`%/spawn/eth-txs` is the path to the transaction file we generated earlier. It will need to be accessible so don't forget to `|commit %home` if you moved it to a different pier.
61+
62+`%/mykey/txt` is the path to your private key file. It should contain your private key beginning with 0x and followed by a hex string with no dots, and where capital letters are fine. This file is most likely the reason you will want to use an airgapped machine so that your private key never touches a networked computer. Opsec is left to the reader.
63+
64+`~[40 80]` is a list of gas prices, in gwei; a signed transaction file will be created for each one listed. Here we just specify 40 and 80 gwei. You may want to adjust this list based on current Ethereum network traffic and your time preference for the transactions.
65+
66+Now you should have one file in your pier for each gwei costs.
67+
68+To actually transmit the transaction, paste the contents of one of these files into https://etherscan.io/pushTx or whatever other transmission system you would like to use. **This is the action that will actually cost you ETH and perform the transaction on the network. Only do this step if you want to actually perform the action.**
content/docs/azimuth/azimuth.mdnew file+149
@@ -0,0 +1,149 @@
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 blockchain, used as a platform for _Urbit identities_. You need such an identity to use the Arvo network.
9+
10+The primary way to interact with Azimuth is through our [Bridge](https://github.com/urbit/bridge) application and the node libraries that it depends on, [azimuth-js](https://github.com/urbit/azimuth-js) and [urbit-key-generation](https://github.com/urbit/urbit-key-generation). Take a look at the source and play around, or see [Getting Started](/getting-started/).
11+
12+## Arvo vs. Azimuth
13+
14+Urbit is a project, not a single computer system. It has multiple components: Arvo, the operating system; and Azimuth, the identity system. Let's compare them.
15+
16+**Arvo** is an operating system that provides the software for a personal server. These personal servers together constitute the peer-to-peer Arvo network. To make this network work on the social level, Arvo is built to work with a system of scarce and immutable identities.
17+
18+**Azimuth** is the public-key infrastructure built to be such a system. A suite of smart-contracts on the Ethereum blockchain, Azimuth determines which Ethereum addresses own which Azimuth identities, called _Urbit identities_, or just _identities_. All identity-related operations, such as transfers, are governed at this layer. But Azimuth isn't built strictly for Arvo -- it could be used as a generalized identity system for other projects.
19+
20+These otherwise-parallel systems meet when you want to connect to the Arvo network. Your Arvo personal server, called your _ship_, needs to be able to prove cryptographically that it is who it says it is. This proof comes in the form of a keyfile, derived from your identity, that you use to start your ship.
21+
22+A metaphor might help illustrate the relationship between these two systems: the Arvo network is the neighborhood that you live in; Azimuth is the bank vault that stores the deed to your house.
23+
24+## The Urbit HD Wallet
25+
26+Owners of Urbit identities need safeguards that allow for the use of Urbit without jeopardizing cryptographic ownership of their assets. Toward this end, we created the **Urbit Hierarchical Deterministic (HD) Wallet** for the storage of identities. The Urbit HD Wallet is not one key-pair, but a system of related key-pairs that each have distinct powers, from setting networking keys for communicating in the Arvo network to transferring ownership of identities.
27+
28+The Urbit HD Wallet's derivation paths have a hierarchical structure, so that
29+keys with different powers can be physically separated. A "master ticket" can
30+[re-derive the entire wallet](#hd-wallet-generation) in case of loss. The
31+encryption and authentication keys that identities ships use to sign messages
32+within the network are also derived from the wallet.
33+
34+Another HD wallet option you may wish to utilize to store your Urbit are hardware
35+wallets such as Trezor or Ledger. We compare this method to the Urbit HD wallet
36+[below](#hardware-hd-wallet).
37+
38+Urbit HD wallets are composed of the following items, which are each assigned to their own individual Ethereum key-pairs.
39+
40+### Master Ticket
41+
42+Think of your master ticket like a very high-value password. The master ticket is the secret code from which all of your other keys are derived. Technically, your master ticket is seed entropy. You should never share it with anyone, and store it very securely. This ticket can derive all of your other keys: your ownership key and all of the related proxies.
43+
44+### Ownership Address
45+
46+An ownership address has all rights over the assets deeded to it. These rights are on-chain actions described and implemented in [Ecliptic](@/docs/glossary/ecliptic.md), Azimuth's suite of governing smart-contracts.
47+
48+### Proxies
49+
50+Proxy addresses allow you to execute non-ownership related actions like spawning child identities, voting, and setting networking keys without jeopardizing the keys you've designated with ownership rights. Setting proxy rights is optional, but it is recommended for on-chain actions you will execute more frequently.
51+
52+- **Management Proxy**
53+
54+ Can configure or set Arvo networking keys and conduct sponsorship related
55+ operations.
56+
57+- **Voting Proxy**
58+
59+ Galaxies only. Galaxies are the part of the [Galactic Senate](@/docs/glossary/senate.md), and this means
60+ they can cast votes on new proposals including changes to Ecliptic.
61+
62+- **Spawn Proxy**
63+
64+ For stars and galaxies only. Can create new child identities.
65+
66+### HD wallet generation
67+
68+Your Urbit HD wallet is generated from a `@q` seed called `T`, which looks
69+something like `~sampel-ticket-bucbel-sipnem`. This is the string known as your
70+"Master Ticket" that you input into Bridge to sign in. This is put through a
71+series of algorithms that ultimately generate your keys and the Ethereum addresses at which they are stored.
72+
73+![](https://media.urbit.org/fora/proposals/UP-8.jpg)
74+
75+First, your `@q` is converted into a numeric value `E` as an intermediary step
76+by adding [salt](<https://en.wikipedia.org/wiki/Salt_(cryptography)>). Then by
77+adding additional salts, `E` is converted into a set of BIP39 seed phrases -
78+these are 24 word mnemonic sequences used to generate Ethereum wallets. You end up
79+with one seed phrase for each proxy associated with your ship, and these seed
80+phrases are then used to generate Ethereum wallets.
81+
82+One of the wallets will store your Azimuth point, an [ERC-721](#erc-721) token,
83+which will be known as your ownership address. Bridge then automatically uses
84+your ownership address to assign the other proxies to the other wallets
85+generated.
86+
87+### ERC-721
88+
89+Most Ethereum tokens use the ERC-20 standard for smart contracts. Urbit identities
90+are, however, essentially different from most Ethereum tokens, due to identities not
91+being fungible. Since any two stars will handle social-networking realities in a
92+different way, they will carry a different reputation.
93+
94+The ERC-721 standard, having been made specifically to provide a smart-contract
95+interface for non-fungible assets, serves our needs well. This is the standard
96+that we use for deeding Urbit identities.
97+
98+Identities, and all of their blockchain operations, are governed by Ecliptic. Ecliptic is an Ethereum smart-contract that governs identity state and the
99+ownership, spawn, management, and voting rights affiliated with your identities.
100+
101+For the technical implementation details, take a look at Azimuth's
102+[Github repository](https://github.com/urbit/azimuth).
103+
104+## Hardware HD wallet
105+
106+You may also store your Urbit using a hardware HD wallet such as a Trezor or
107+Ledger. This option is used instead of a master ticket - it is a totally
108+separate process from that outlined above. How hardware wallets work are
109+outside of the scope of this document, but here we explain how you may utilize
110+your hardware wallet in a similar fashion to the Urbit HD wallet.
111+
112+A hardware HD wallet is generated from a seed phrase that should be thought of
113+as analogous to the `@q` `T` used to generate the Urbit HD wallet in the above
114+diagram. This seed phrase is a human readable sequence of words that may be used
115+to generate private keys to a near-limitless number of wallets created by adding
116+salt. Some hardware
117+wallets also allow an additional passphrase to go into the generation of these
118+wallets. The seed phrase and passphrase should be considered equal in
119+value to the master ticket `T`- never share these with anyone!
120+
121+In order to use your hardware wallet as your Urbit wallet, you first need to
122+generate a set of addresses on which you would like to store your Azimuth point
123+and proxies. Consult your wallet vendor on how to do this. Then login to Bridge
124+using your current method (likely a master ticket) and transfer ownership to the
125+wallet address you generated on your hardware wallet for ownership.
126+
127+Next, login to Bridge using your hardware wallet. While Bridge supports Trezor
128+and Ledger natively, this may require using Metamask as an intermediary anyways,
129+depending on which firmware you are running. Then [accept the
130+transfer](/using/id/using-bridge#accept-your-transfer). Your Azimuth
131+point is now stored on your hardware wallet.
132+
133+To finish the process, use Bridge to set your management, voting, and spawn
134+proxies to the other addresses you generated as applicable. You are now using
135+your hardware HD wallet in an analogous fashion to the Urbit HD wallet.
136+
137+## Heightened security practices
138+
139+A common security pattern is to have "hot" and "cold" wallets. For higher value
140+points such as stars and galaxies, you may consider having your ownership
141+address live on a "cold" wallet that never touches an
142+internet-connected computer, and the various proxies on a "hot" wallet that is
143+permitted to connect to internet-connected devices. This could be accomplished
144+with multiple hardware wallets, a combination of paper and hardware wallet, a
145+hardware cold wallet and Metamask hot wallet, etc.
146+
147+One tool useful for this setup is `claz`, located at `app/claz.hoon`. `claz` is
148+used for making and signing Bridge transactions from an offline computer. A
149+guide to using `claz` is forthcoming.
content/docs/azimuth/life-and-rift.mdnew file+58
@@ -0,0 +1,58 @@
1++++
2+title = "Life and Rift"
3+weight = 3
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-breaches), 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
17+galaxies, stars, and planets, these values are stored in the Azimuth PKI, while
18+for moons, these values are stored by their parent. Comets cannot change their
19+networking keys, nor can they breach, and so their `life` and `rift` are always 0.
20+
21+You can check your current `life` and `rift` number by running the `+keys our`
22+generator in dojo. You can inspect another ship's `life` and `rift` by running
23+`+keys ~sampel-palnet`.
24+
25+## Life
26+
27+A ship's `life`, or _key revision number_, is a count of the number of times which
28+a ship's networking keys have been altered. The initial value of each key is
29+always zero, and the initial `life` is always 0.
30+
31+Thus, setting the keys of a ship to a nonzero value for the first time will
32+increment the `life` from 0 to 1. Rotating to a new set of keys will then
33+increment the `life` to 2. Setting the keys back to zero would increment the
34+`life` once more, to 3.
35+
36+## Rift
37+
38+A ship's `rift`, or _continuity number_, is a count of the number of times that
39+a ship has breached, also known as broken continuity.
40+
41+In other words, a ship's `rift` will remain at 0 until the first time it is
42+breached.
43+
44+Network-wide breaches do not affect the `rift` of any ship. They are only used to
45+count the number of personal breaches.
46+
47+## Edge cases
48+
49+Configuring the keys to the same value they already were (i.e. a no-op) is
50+possible, but has no effect on the `life`. Thus `life` is actually a measure of
51+networking key _revisions_, and not the number of times they've been set.
52+
53+Thus under ordinary circumstances, a breach will increment both `life` and
54+`rift` since a breach typically also involves changing the networking keys.
55+However, it is possible to breach without changing the networking keys.
56+If the new keys specified
57+as part of a breach are the same as the old, `rift` will increment while
58+`life` will not.
content/docs/development/_index.mdnew file+33
@@ -0,0 +1,33 @@
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.mdnew file+115
@@ -0,0 +1,115 @@
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/userspace/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/userspace/landscape/overview), 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.md)
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/userspace/gall/gall-api) that's defined by the kernel vane
64+called [Gall](/docs/userspace/gall/gall).
65+
66+Applications built on Urbit utilize a collection of different agents, each of
67+which handle specific functionality. The [Landscape
68+architecture](/docs/userspace/landscape/overview) is a good reference implementation
69+to see how this pattern works in practice.
70+
71+If you want to learn how to build gall agents, your best bet is to first [learn
72+the Hoon programming language](/docs/hoon/hoon-school/), and then follow that
73+up with the [Gall guide](/docs/userspace/gall/tutorial).
74+
75+### Contribute to Urbit Core {#core}
76+
77+Working on the core means improving the Urbit project itself, working with the
78+existing community of Urbit developers. The kernel is much more stable, but
79+generally more challenging from an engineering standpoint.
80+
81+Just arrived and unsure what to work on? An ideal way to get started is by
82+experimenting with the system, talking to other developers, and reading (or
83+[contributing to](https://github.com/urbit/docs)) the [documentation](/docs/).
84+
85+Prefer learning with an instructor? Our community runs an online course that
86+covers the basics of Urbit development called
87+[Hooniversity](https://hooniversity.org/). If course-based learning works well
88+for you, we recommend you sign up.
89+
90+The Urbit developer community congregates around [the urbit-dev mailing
91+list](https://groups.google.com/a/urbit.org/forum/#!forum/dev), the
92+`~bitbet-bolbel/urbit-community` group on Landscape, and [Urbit’s GitHub
93+repository](https://github.com/urbit/urbit). It’s a good idea to sign up, see
94+what people are talking about, and introduce yourself.
95+
96+Once you’re comfortable working with Urbit, check out the [project’s issues on
97+GitHub](https://github.com/urbit/urbit/issues) or some of our [contribution
98+bounties](https://grants.urbit.org/).
99+
100+If you’re looking for some guidance, need help, or would prefer direct
101+communication for your ideas, you can also always reach out to us directly at
102+[support@urbit.org](mailto:support@urbit.org).
103+
104+## Next Steps
105+
106+From here, you'll probably want to learn more about:
107+
108+- How to set up a [development environment](/docs/development/environment)
109+- Our [grants program](/docs/development/grants), where you can earn address
110+ space for helping the project grow
111+- The different [project
112+ repositories](/docs/development/project-repositories), both official and
113+ community-maintained
114+- Our development [Precepts](/docs/development/precepts), which outline the
115+ philosophies that drive Urbit development
content/docs/development/environment.mdnew file+64
@@ -0,0 +1,64 @@
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+## Creating a development ship
12+
13+To do work with Hoon, we recommended using a "fake" ship -- one that's not
14+connected to the network.
15+
16+Because such a ship has no presence on the network, you don't need an Azimuth
17+identity. You just need to have [installed the Urbit binary](/getting-started).
18+
19+To create a fake ship named `~zod`, run the command below. You can replace `zod`
20+with any valid Urbit ship-name.
21+
22+```
23+./urbit -F zod
24+```
25+
26+This should take a couple of minutes, during which you should see a block of boot
27+messages, starting with the Urbit version number.
28+
29+## Hoon support in text editors
30+
31+A variety of plugins have been built to provide support for the Hoon language in
32+different text editors:
33+
34+#### Atom
35+
36+Atom is free and open-source and runs on all major operating systems. It is
37+available [here](https://atom.io/). A package for Hoon support is maintained by
38+Tlon and may be obtained using the package manager within the editor by
39+searching for `Hoon`.
40+
41+#### Sublime Text
42+
43+Sublime Text is closed-source, but may be downloaded for free and there is no
44+enforced time limit for evaluation. It runs on all major operating systems. It
45+is available [here](https://www.sublimetext.com/).
46+
47+#### Visual Studio Code
48+
49+Visual Studio Code is free and open-source and runs on all major operating
50+systems. It is available [here](https://code.visualstudio.com/). Hoon support
51+may be acquired in the Extensions menu within the editor by searching for
52+`Hoon`.
53+
54+#### Emacs
55+
56+Emacs is free and open-source and runs on all major operating systems. It is
57+available [here](https://www.gnu.org/software/emacs/). Hoon support is available
58+with [hoon-mode.el](https://github.com/urbit/hoon-mode.el).
59+
60+#### Vim
61+
62+Vim is free and open-source and runs on all major operating systems. It is
63+available [here](https://www.vim.org/). Hoon support is available with
64+[hoon.vim](https://github.com/urbit/hoon.vim) and is maintained by Tlon.
content/docs/development/grants.mdnew file+84
@@ -0,0 +1,84 @@
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.mdnew file+336
@@ -0,0 +1,336 @@
1++++
2+title = "Precepts"
3+weight = 40
4+template = "doc.html"
5++++
6+
7+<br>
8+
9+<img class="ba" src="https://media.urbit.org/site/posts/essays/pre-01.jpg">
10+
11+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.
12+
13+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.
14+
15+We’ll start with a brief description of many principles, then we’ll go into a long-form justification.
16+
17+
18+
19+### A: General Design
20+
21+1) Data is better than code.
22+
23+ Store data in your state, send data over the wire, dispatch based
24+ on data.
25+
26+2) Everything should be CQRS.
27+
28+3) (Almost) Everything should be pubsub.
29+
30+4) A subscriber shouldn't affect a publisher.
31+
32+5) Communication between nodes should be communication between
33+ independent actors.
34+
35+ Each message should do one complete thing, and there shouldn't
36+ need to be a sequence of coupled messages.
37+
38+6) Represent your data as closely as possible to the essential structure
39+ of the problem.
40+
41+7) A client's representation of data should be as close as possible to
42+ that of the server.
43+
44+ This blurs the distinction between client and server. It allows
45+ offline-mode, reduces communication to syncing, and decentralizes.
46+
47+8) When mating different paradigms, build one cleanly on top of the
48+ other.
49+
50+ Never try to make them work on some of the same primitives. Never
51+ abuse one to make the other work. For example, ducts in
52+ themselves are very general - if you want to do pubsub, that can
53+ easily be built on top of ducts, but don't pretend that pubsub is
54+ a *part* of the duct system.
55+
56+9) Never misuse an abstraction.
57+
58+ An abstraction provides a certain set of tools; use them and only
59+ them.
60+
61+10) Correctness is more important than performance.
62+
63+11) Be simple and uncompromising in defining what's correct; go crazy
64+ with optimizations.
65+
66+ Nock is a great example of this. It contains the character of the
67+ virtual machine, but its asymptotics are bad. Add jets to fix the
68+ asymptotics.
69+
70+ Another example is the ACID nature of Arvo. Arvo is a pure
71+ function f(logs) of its event log, so formally Arvo is just a
72+ function run against an event log. A naive implementation has
73+ very bad asymptotics; processing each new event is O(n) in the
74+ number of historical events. Choose the function g(state,log)
75+ such that f(logs ++ log) = g(f(logs),log). Then, as long as you
76+ keep the state in memory, processing each new event is constant in
77+ the number of previous events. This still requires O(n) restart
78+ from disk, but you can also periodically (and non-blockingly)
79+ write a checkpoint of the state to disk, so that restart from disk
80+ is only linear in the number of events since the last checkpoint.
81+
82+12) Correctness is more important than optimality.
83+
84+13) If you don't completely understand your code and the semantics of
85+ all the code it depends on, your code is wrong.
86+
87+14) Deterministic beats heuristic.
88+
89+ Heuristics are evil and should only be used where determinism is
90+ infeasible, such as in cache reclamation.
91+
92+15) Stateless is better than stateful.
93+
94+16) Explicit state is better than implicit state.
95+
96+17) Referential transparency is honesty and stability.
97+
98+ Lack of referential transparency and other forms of
99+ disingenuousness are some of the world's big problems. Only
100+ deviate from referential transparency if absolutely necessary.
101+
102+18) Responsibilities should be clearly separated.
103+
104+ This applies from kernel modules through network citizens.
105+
106+19) Dualities must be faced head-on and analyzed differently at
107+ different layers.
108+
109+ Statically typed vs. dynamically typed, imperative vs. functional,
110+ code vs. data, and effectful vs. pure can all be a matter of
111+ perspective, and all relevant perspectives must have coherent
112+ answers.
113+
114+20) One hundred lines of simplicity is better than twenty lines of
115+ complexity.
116+
117+ It's not enough for an abstraction to reduce code duplication; it
118+ must actually make the code simpler.
119+
120+21) Prefer mechanical simplicity to mathematical simplicity.
121+
122+ Often mechanical simplicity and mathematical simplicity go
123+ together.
124+
125+22) The Law of Leaky Abstractions is a lie; abstract airtightly.
126+
127+ If your abstractions are leaking, it's not due to some law of the
128+ universe; you just suck at abstracting. Usually, you didn't
129+ specify the abstraction narrowly enough.
130+
131+23) Some cliches are repeated because they are true; others must be
132+ repeated because they are not.
133+
134+<br>
135+
136+<img class="ba" src="https://media.urbit.org/site/posts/essays/pre-03.jpg">
137+
138+### B: Specific Design
139+
140+1) Always ack a dupe; never ack an ack.
141+
142+ It's okay to ack a nack as long as you never nack a nack.
143+
144+2) Never construct or deconstruct a duct.
145+
146+3) Route on wire before sign, never sign before wire.
147+
148+4) Only go from statically typed to dynamically typed if you must.
149+
150+ Once you go into a dynamically typed world, it's hard to go back.
151+ Statically typed is better than dynamically typed, so if something
152+ can be made static, it should be.
153+
154+ Each timeless data structure is a brick in the foundation of
155+ digital civilization.
156+
157+5) Anything with business logic speaks one paradigm; anything that
158+ translates paradigms has no business logic.
159+
160+6) Functionally enforced semantic rules are better security primitives
161+ than memory access restrictions.
162+
163+ A compiler can use type safety as an effective tool to enforce
164+ some classes of security guarantees.
165+
166+
167+### C: Attitude
168+
169+1) Code courageously.
170+
171+ If you avoid changing a section of code for fear of awakening the
172+ demons therein, you are living in fear. If you stay in the
173+ comfortable confines of the small section of the code you wrote or
174+ know well, you will never write legendary code. All code was
175+ written by humans and can be mastered by humans.
176+
177+ It's natural to feel fear of code; however, you must act as though
178+ you are able to master and change any part of it. To code
179+ courageously is to walk into any abyss, bring light, and make it
180+ right.
181+
182+2) No time for lazy people.
183+
184+ If there's clearly a right way to do something and a wrong way, do
185+ it the right way. Coding requires incredible discipline. Always
186+ follow conventions, and fire anyone who won't. Anything that can
187+ be solved by discipline is not a real problem.
188+
189+ > "To him who knows to do good and does not do it, to him it is
190+ sin."
191+
192+3) When a smart person makes an obviously stupid suggestion, before
193+ responding take a full 60 seconds to envision how you would implement
194+ it and what the effects would be.
195+
196+
197+### D: Theory
198+
199+1) Academia is a succubus.
200+
201+ Academia has a really high ratio of smart people to useful
202+ products. Academia has many genuinely smart and interesting
203+ ideas, but always remember that pursuing them whole-heartedly will
204+ never result in a useful product.
205+
206+2) Never fear math.
207+
208+ Academia is inefficient, but it's also correct. Those people
209+ wasted a lot of time finding the right answer, but now that
210+ they've done it, you must exploit it. If you don't know the
211+ theory, learn it. No excuse for being "bad at math". Most who
212+ are "bad at math" are simply lazy or fearful. Be strong and of
213+ good courage. If you're truly so bad at math that you cannot
214+ learn it, you should not design systems.
215+
216+3) Not being qualified to solve a problem is no reason not to solve it.
217+
218+ If you don't know how to do it, do it anyway. "We are too young
219+ to realize that certain things are impossible. So, we will do
220+ them anyway."
221+
222+4) The best way to get the right answer is to try it the wrong way.
223+
224+ You cannot design a good system without spending most of your time
225+ in contact with the problem. The bad parts about systems are
226+ rarely obvious in theory, but often in practice.
227+
228+5) Practice tells you that things are good or bad; theory tells you why.
229+
230+ Never use theory to design a good system from scratch; only
231+ practice can tell whether the system is good.
232+
233+6) Everyone must regularly alternate between theory and practice.
234+
235+ There is an eternal wheel of system design. Given a system, use
236+ practice to discover what is bad, missing, or unnecessary. Then,
237+ use theory to fix the bad, add the missing, and remove the
238+ unnecessary. Repeat.
239+
240+
241+### E: Text Style
242+
243+1) No code should extend beyond 80 characters, most within 55.
244+
245+2) Tabs aren't real.
246+
247+3) A text file is a series of lines, each ending with a newline
248+ character.
249+
250+ Corollary: all non-empty text files end with a newline (often
251+ hidden by editors). An empty text file does not end with a
252+ newline.
253+
254+4) One block comment is better than interleaved comments on every line.
255+
256+5) Don't name anything you don't have to.
257+
258+ This includes conventional names for variables of particular
259+ types. For example, the conventional name for a variable of type
260+ `path` is `pax`. You should have a good reason for using any
261+ other name for a `path`.
262+
263+ A more recent convention that follows the same principle is to
264+ give the variable the same name as its type.
265+
266+6) If it's the same thing, give it the same name.
267+
268+7) Humans are good at memorizing.
269+
270+8) Abbreviations aren't worth it.
271+
272+
273+### F: Real Software
274+
275+1) If it's not deterministic, it isn't real.
276+
277+2) If it's centralized, it isn't real.
278+
279+3) If it's owned by someone else, it isn't yours.
280+
281+4) If it's managed by someone else and you can't change who that is, it
282+ isn't yours.
283+
284+5) If it's not yours, it isn't permanent.
285+
286+6) If it's not permanent, it isn't real.
287+
288+7) The way it is isn't always the way it ought to be.
289+
290+ If you can make it the way it ought to be, do so.
291+
292+8) The way it ought to be isn't always the way it is.
293+
294+ Some things can't be made more elegant.
295+
296+ For every ailment under the sun
297+ There is a remedy, or there is none;
298+ If there be one, try to find it;
299+ If there be none, never mind it.
300+
301+9) Timeless software is good software.
302+
303+10) System modules should be designed to be frozen permanently;
304+ conversely, Urbit consists of that system software which admits of a
305+ Kelvin version.
306+
307+11) The two procedures for achieving timelessness are distillation and
308+ generalization.
309+
310+ Every temporary or contingent feature in a system module should
311+ eventually either be removed (distillation) or relaxed into
312+ timelessness (generalization). For an example of the result of
313+ both procedures, consider the abstraction of the core in Nock and
314+ Hoon.
315+
316+12) Standardization is better than perfection.
317+
318+ Kelvin versioning stops when we run out of versions, not when
319+ every defect has been rectified.
320+
321+13) That which cannot be Kelvin-versioned should update fluidly and
322+ automatically.
323+
324+ All incompatible upgrades should provide permanent and automatic
325+ upgrade paths. This is principled permanent backward
326+ compatibility.
327+
328+14) Humans are interactive and temporal; technology is permanent and
329+ exhaustive.
330+
331+15) Communities are autonomous.
332+
333+16) Sovereignty necessitates understanding.
334+
335+ If you don't understand a system you're using, you don't control
336+ it. If nobody understands the system, the system is in control.
content/docs/development/project-repositories.mdnew file+50
@@ -0,0 +1,50 @@
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.
42+- [docs](https://github.com/urbit/docs): the source for the documentation that
43+ you're currently reading.
44+ - _Note:_ the documentation is loaded into the
45+ [urbit.org](https://github.com/urbit/urbit.org) repo as a submodule.
46+
47+### Community
48+
49+The best way to keep track of the various community projects is via our
50+[**awesome-urbit**](https://github.com/urbit/awesome-urbit) repository.
content/docs/glossary/_index.mdnew file+10
@@ -0,0 +1,10 @@
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.mdnew file+19
@@ -0,0 +1,19 @@
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](../vane) that communicates over it. It's an encrypted peer-to-peer network composed of instances of the [Arvo](../arvo) operating system. Each [galaxy](../galaxy), [star](../star), [planet](../planet), [moon](../moon), and [comet](../comet) communicates over the network utilizing the Ames protocol.
9+
10+Your ship upgrades itself with [OTA updates](../ota-updates) via communication over Ames. The web interface, [Landscape](../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 [breaches](../breach).
15+### Further Reading
16+
17+- [The Ames tutorial](/docs/arvo/ames/ames): An in-depth technical guide to the Ames protocol.
18+- [A Guide to Breaches](/using/id/guide-to-breaches): Instructions on handling continuity breaches (resets) on the Ames network.
19+- [Ship Troubleshooting](/using/os/ship-troubleshooting): General instructions on getting your ship to work, which includes network connectivity issues.
content/docs/glossary/aqua.mdnew file+16
@@ -0,0 +1,16 @@
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](../gall) app that runs an [Arvo](../arvo) instance or instances in userspace. It pretends to be [Vere](../vere), and as such it loads [Pills](../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](../ph).
11+
12+Aqua is jetted with the usual [Nock](../nock) interpreter and thus virtual ships do not run any slower than the parent ship.
13+
14+### Further Reading
15+
16+- [The Gall tutorial](/docs/userspace/gall/gall): A technical guide to the Gall vane.
content/docs/glossary/arm.mdnew file+14
@@ -0,0 +1,14 @@
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](../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.mdnew file+40
@@ -0,0 +1,40 @@
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](../eventlog), and it serves as the Urbit event
8+manager. It contains [vanes](../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+L: History ➜ State
14+```
15+where `History` consists of the set of all possible sequences of events in an Arvo event log.
16+
17+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:
18+```
19+Unix event -> Vere -> Arvo -> vane -> Arvo
20+```
21+Here, [Vere](../vere) is the virtual machine running Urbit.
22+
23+Arvo is located in `/home/sys/arvo.hoon` within your urbit.
24+
25+Arvo vanes include [Ames](../ames) for networking, [Behn](../behn) for timing,
26+[Clay](../clay) for filesystem and typed revision control, [Dill](../dill) for
27+terminal driving, [Eyre](../eyre) for web services, [Ford](../ford) for
28+building, and [Gall](../gall) for application management.
29+
30+Vanes and other programs for Arvo are written in [Hoon](../hoon).
31+
32+A ship creates its own copy of Arvo via a bootstrap sequence known as a
33+[Pill](../pill).
34+
35+### Further Reading
36+
37+- [The Arvo tutorial](/docs/arvo/overview): An in-depth technical
38+ guide to Arvo and its vanes.
39+- [The Technical Overview](/docs/system-overview/): An
40+ overview of all of Urbit.
content/docs/glossary/atom.mdnew file+20
@@ -0,0 +1,20 @@
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](../nock) and [Hoon](../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.mdnew file+18
@@ -0,0 +1,18 @@
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 the Ethereum blockchain. It is Urbit's method of securing digital identities that are required to use the [Arvo](../arvo) peer-to-peer network, without the need for a central authority. Azimuth identities exist as non-fungible tokens, which are owned by Ethereum addresses and can be transferred between such addresses. Identities can use the [claims](../claims) contract to make assertions – real-world or otherwise – about their owner.
7+
8+The primary way to interact with Azimuth and to manage your identities is through our [Bridge](https://bridge.urbit.org) application. Bridge is a front-end for [Ecliptic](../ecliptic), the Azimuth contract that's used to perform actions on the blockchain.
9+
10+There are a limited number of Azimuth identities which results in identities having value. This allows for identities to function as reputation primitives, since such scarcity creates an economic incentive for identities to remain static and to keep the network friendly. Undesirable behavior – spamming, scamming, and malware-spreading - will generally result in a [censure](../censure) from [galaxies](../galaxy) and [stars](../star), marking the bad actor.
11+
12+It should be noted that Azimuth isn't built just for Arvo. It can be used as an identity system for other projects.
13+
14+### Further Reading
15+
16+- [The Azimuth concepts page](/docs/azimuth/advanced-azimuth-tools): A more in-depth explanation of Azimuth, including information the storage of Urbit identities.
17+- [Install instructions](/getting-started/): Guide to installing Urbit, which includes instructions on booting with your Urbit identity.
18+- [Understanding Urbit ID](/understanding-urbit/urbit-id)
content/docs/glossary/battery.mdnew file+14
@@ -0,0 +1,14 @@
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](../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.mdnew file+14
@@ -0,0 +1,14 @@
1++++
2+title = "Behn"
3+template = "doc.html"
4+[extra]
5+category = "arvo"
6++++
7+
8+**Behn** is the timing [vane](../filesystem). It allows for applications to schedule events, which are managed in a simple priority queue. For example, [Clay](../clay), the Urbit filesystem, uses Behn to keep track of time-specific file requests. [Eyre](../eyre), the Urbit web vane, uses Behn for timing-out HTTP sessions.
9+
10+Behn is located in `/home/sys/vane/behn.hoon` within [Arvo](../arvo).
11+
12+### Further Reading
13+
14+- [The Behn tutorial](/docs/arvo/behn/behn): A technical guide to the Behn vane.
content/docs/glossary/breach.mdnew file+28
@@ -0,0 +1,28 @@
1++++
2+title = "Breach"
3+template = "doc.html"
4+[extra]
5+category = "arvo"
6++++
7+
8+Continuity on the [Ames](../ames) network occasionally needs to be broken
9+(though with increasing rarity) in order to correct a networking error. These
10+infrequent events are known as **breaches**, which cause an individual ship to
11+forget its network message history.
12+
13+Breaches are always initiated by the user, frequently in response to a
14+connectivity error. The easiest way to do this is with [Bridge](../bridge).
15+There are two types of personal breaches: changing networking keys, and changing
16+the Urbit ID ownership address.
17+
18+Historically, there were also "network breaches", which happened when a major
19+Arvo revision that could not be implemented via an [OTA update](../ota-updates)
20+occured. Network breaches were effectively breaching every ship on the network
21+at once. The most recent network breach occurred in December 2020, and we expect
22+it to be the final one.
23+
24+### Further Reading
25+
26+- [Guide to breaches](/using/id/guide-to-breaches): A more in-depth
27+ explanation of breaches, including how to perform a personal breach.
28+- [Ship Troubleshooting](/using/os/ship-troubleshooting): General instructions on getting your ship to work, which includes network connectivity issues.
content/docs/glossary/bridge.mdnew file+32
@@ -0,0 +1,32 @@
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](../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](../keyfile) required to get your [ship](../ship) onto the [Arvo](../arvo) network. Most Bridge functions are accessed by "logging in" to an identity's ownership address or one of its [proxy addresses](../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](../galaxy) or a [star](../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.mdnew file+14
@@ -0,0 +1,14 @@
1++++
2+title = "Censures"
3+template = "doc.html"
4+[extra]
5+category = "azimuth"
6++++
7+
8+The **Censures** [Azimuth](../azimuth) contract allows [stars](../star) and [galaxies](../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.mdnew file+8
@@ -0,0 +1,8 @@
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](../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](../hdwallet).
content/docs/glossary/chat.mdnew file+32
@@ -0,0 +1,32 @@
1++++
2+title = "chat"
3+
4+template = "doc.html"
5+[extra]
6+category = "arvo"
7++++
8+
9+**Chat** is a suite of [Gall](../gall) applications that handle "instant
10+messaging"-style communication between [ships](../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](../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.mdnew file+21
@@ -0,0 +1,21 @@
1++++
2+title = "Claims"
3+
4+template = "doc.html"
5+[extra]
6+category = "azimuth"
7++++
8+
9+The **Claims** [Azimuth](../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.mdnew file+18
@@ -0,0 +1,18 @@
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](../vane). It can be thought of as a continuously synced git. Clay handles file-change events and maps them from [Arvo](../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 `/home/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.mdnew file+32
@@ -0,0 +1,32 @@
1++++
2+title = "Comet"
3+template = "doc.html"
4+[extra]
5+category = "arvo"
6++++
7+
8+A **comet** is a kind of [ship](../ship) on the [Ames](../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](../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](../azimuth), rather than purposefully placed
19+blockades.
20+ - They may not [change their networking keys](../bridge).
21+ - They may not spawn [moons](../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](../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.mdnew file+14
@@ -0,0 +1,14 @@
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](../battery) and a [payload](../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.mdnew file+9
@@ -0,0 +1,9 @@
1++++
2+title = "Delegated Sending"
3+
4+template = "doc.html"
5+[extra]
6+category = "azimuth"
7++++
8+
9+The **Delegated Sending** [Azimuth](../azimuth) contract is a way that a [star](../star ) distributes [planets](../planet). After a star configures the Delegated Sending contract as its [spawn proxy](../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](../invite-tree), so the relationship between inviters and invitees is publicly known.
content/docs/glossary/desk.mdnew file+15
@@ -0,0 +1,15 @@
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](../ship) that uses the [Clay](../clay) filesystem. Each desk contains its own apps, [mark](../mark) definitions, files, and so forth.
10+
11+Traditionally a ship has at least a base desk and a home desk. The base desk has all the system software from the distribution, and the home desk is a fork of base with all the items specific to the user of the ship. 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.mdnew file+22
@@ -0,0 +1,22 @@
1++++
2+title = "Dill"
3+
4+template = "doc.html"
5+[extra]
6+category = "arvo"
7++++
8+
9+**Dill** is the terminal-driver [vane](../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 `/home/sys/vane/dill.hoon` within [Arvo](../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.mdnew file+9
@@ -0,0 +1,9 @@
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](../voting) action taken by the [Galactic Senate](../senate) over [Azimuth](../azimuth). By passing a document proposal, [Galaxies](../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.mdnew file+14
@@ -0,0 +1,14 @@
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](../hoon) and [Nock](../nock) code, making it a good place to play around with those languages.
9+
10+The other default command-line app is [Chat](../chat). To switch between Dojo
11+and [Chat](../chat) press Ctrl-X. The Dojo is the first thing you encounter after successfully booting your [ship](../ship).
12+
13+### Further Reading
14+- [Hoon Tutorial Lesson 1.1: Setup](/docs/hoon/hoon-school/setup): A great way to get started with using Hoon in the Dojo.
content/docs/glossary/door.mdnew file+14
@@ -0,0 +1,14 @@
1++++
2+title = "Door"
3+
4+template = "doc.html"
5+[extra]
6+category = "hoon-nock"
7++++
8+
9+A **door** is a [core](../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.mdnew file+12
@@ -0,0 +1,12 @@
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](../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](../galaxy)) has the power to replace
12+Ecliptic via an [upgrade proposal](../upgrade).
content/docs/glossary/eventlog.mdnew file+23
@@ -0,0 +1,23 @@
1++++
2+title = "Event Log"
3+
4+template = "doc.html"
5+[extra]
6+category = "arvo"
7++++
8+
9+The **event log** of a [ship](../ship) is a totally ordered list of every single [Arvo](../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](../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](../pill).
20+
21+### Further Reading
22+
23+- [Pier](../pier): The directory on disk which contains the ship's state.
content/docs/glossary/eyre.mdnew file+17
@@ -0,0 +1,17 @@
1++++
2+title = "Eyre"
3+
4+template = "doc.html"
5+[extra]
6+category = "arvo"
7++++
8+
9+**Eyre** is the web-server [vane](../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](../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](../ford) and [Gall](../gall) to functionally publish pages and facilitate communication with apps.
12+
13+Eyre is located at `/home/sys/vane/eyre.hoon` within [Arvo](../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.mdnew file+17
@@ -0,0 +1,17 @@
1++++
2+title = "Ford"
3+
4+template = "doc.html"
5+[extra]
6+category = "arvo"
7++++
8+
9+**Ford** is the build-system [vane](../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](../arvo) applications and other vanes, specifically [Clay](../clay) and [Gall](../gall).
12+
13+Ford is located at `/home/sys/vane/ford.hoon` within [Arvo](../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.mdnew file+15
@@ -0,0 +1,15 @@
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](../azimuth) Urbit identity that sits at the top of the identity hierarchy. Galaxies, in this sense, have the power to issue [stars](../star), meaning that all other kinds of identities ultimate derive from galaxies. Galaxies also form a [Senate](../senate), the governing body of Azimuth. The Senate has the power to update the logic of Azimuth by [majority vote](../voting).
12+
13+- A [ship](../ship) on the Arvo network whose identity is a planet in the former definition. In this sense, galaxies act as infrastructure for the [Arvo](../arvo) network, providing [Ames](../ames)-related services, such as peer-to-peer routing and distributing [over-the-air software updates](../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](../star). Galaxies have one-syllable names like `~mul` or `~lux`.
content/docs/glossary/gall.mdnew file+17
@@ -0,0 +1,17 @@
1++++
2+title = "Gall"
3+
4+template = "doc.html"
5+[extra]
6+category = "arvo"
7++++
8+
9+**Gall** is the application-management [vane](../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](../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](../ship), Gall will route it behind the scenes through [Ames](../ames) to the other ship.
10+
11+Gall is located at `/home/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+- [The Gall tutorial](/docs/userspace/gall/gall): A technical guide to the Gall vane.
content/docs/glossary/gate.mdnew file+14
@@ -0,0 +1,14 @@
1++++
2+title = "Gate"
3+
4+template = "doc.html"
5+[extra]
6+category = "hoon-nock"
7++++
8+
9+A **gate** is [core](../core) with one [arm](../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.mdnew file+17
@@ -0,0 +1,17 @@
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](../arvo) network to transferring ownership of identities. HD Wallets are created with the [Wallet Generator](../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](../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/advanced-azimuth-tools): A more in-depth explanation of Azimuth, including information about the HD wallet.
content/docs/glossary/hoon.mdnew file+15
@@ -0,0 +1,15 @@
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](../nock). As a result Hoon code is effectively implemented by the interpreter [Vere](../vere). Programs for the Urbit operating system and kernel, [Arvo](../arvo), are written in Hoon.
8+
9+The Hoon source file is located in `/home/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.mdnew file+9
@@ -0,0 +1,9 @@
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](../delegated-sending) contract on [Azimuth](../azimuth), and is a record of who gave a [planet](../planet) to whom. This allows for community applications, such as a chat channel for all distantly related planets.
content/docs/glossary/iris.mdnew file+11
@@ -0,0 +1,11 @@
1++++
2+title = "Iris"
3+
4+template = "doc.html"
5+[extra]
6+category = "arvo"
7++++
8+
9+**Iris** is the web-server [vane](../vane) that handles everything HTTP-related on the server side. It is the counterpart to [Eyre](../eyre), which is the client-facing HTTP vane.
10+
11+Iris is located at `/home/sys/vane/iris.hoon` within [Arvo](../arvo).
content/docs/glossary/jael.mdnew file+8
@@ -0,0 +1,8 @@
1++++
2+title = "Jael"
3+template = "doc.html"
4+[extra]
5+category = "arvo"
6++++
7+
8+**Jael** is the [vane](../vane) that keeps track of [Azimuth](../azimuth) related information. For each [ship](../ship), this consists of its networking keys, its revision number (or _life_), its breach number, and who the sponsor of the ship is.
content/docs/glossary/jaque.mdnew file+15
@@ -0,0 +1,15 @@
1++++
2+title = "Jaque"
3+
4+template = "doc.html"
5+[extra]
6+category = "hoon-nock"
7++++
8+
9+**Jaque** is a new [Nock](../nock) interpreter under development that is intended to replace the current worker process for [Vere](../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.mdnew file+15
@@ -0,0 +1,15 @@
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](../ship) with an Urbit identity so that the ship can use the [Arvo](../arvo) network. A keyfile is dependent upon the [networking keys](../bridge) that have been set for the identity; we recommend using [Bridge](../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](../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.mdnew file+11
@@ -0,0 +1,11 @@
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](../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](../chat).
10+
11+Landscape can be accessed with a browser via [ship.arvo.network](../shiparvonetwork) or by `localhost:80`. You'll be greeted with a login prompt; type `+code` into your [Dojo](../dojo), and use the output as your password.
content/docs/glossary/mark.mdnew file+17
@@ -0,0 +1,17 @@
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](../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](../ford) [vane](../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.mdnew file+34
@@ -0,0 +1,34 @@
1++++
2+title = "Moon"
3+template = "doc.html"
4+[extra]
5+category = "arvo"
6++++
7+
8+A **moon** is a kind of [ship](../ship) on the [Arvo](../arvo) network. Moons
9+are child identities issued by [planets](../planet), [stars](../stars), and
10+[galaxies](../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+Looking towards the future, we expect moons to also be utilized as identities
21+for devices, such as such as phones, desktops, smart TVs, and digital thermostats
22+
23+Unlike planets, stars, and galaxies, moons have no presence on
24+[Azimuth](../azimuth). Moons are representable with 64 bits and have long names
25+like `~doznec-salfun-naptul-habrys`, the latter half of which is inherited from
26+their parent planet.
27+
28+### Further Reading
29+
30+- [Using Your Ship](/using/os/getting-started#moons): The "Moons" section contains instructions for creating and managing moons.
31+
32+- [Lunar Urbit and the Internet of Things](/blog/iot): Blog post on the
33+ past, present, and future of moons
34+
content/docs/glossary/nock.mdnew file+17
@@ -0,0 +1,17 @@
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](../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](../atom), which is a non-negative integer. Computation in Nock occurs through the use of [nouns](../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](../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.mdnew file+15
@@ -0,0 +1,15 @@
1++++
2+title = "Noun"
3+
4+template = "doc.html"
5+[extra]
6+category = "hoon-nock"
7++++
8+
9+A **noun** is an [atom](../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](../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.mdnew file+9
@@ -0,0 +1,9 @@
1++++
2+title = "OTA Updates"
3+
4+template = "doc.html"
5+[extra]
6+category = "arvo"
7++++
8+
9+[Ships](../ship) have the ability to upgrade themselves **over the air**. They receive updates from a sponsor [star](../star) or [galaxy](../galaxy).
content/docs/glossary/payload.mdnew file+14
@@ -0,0 +1,14 @@
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](../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.mdnew file+9
@@ -0,0 +1,9 @@
1++++
2+title = "pH"
3+
4+template = "doc.html"
5+[extra]
6+category = "arvo"
7++++
8+
9+**pH** is a [Gall](../gall) app that is a framework for fleet testing using [Aqua](../aqua). pH comes with a number of default tests, as well as tools for building and executing custom tests.
content/docs/glossary/pier.mdnew file+18
@@ -0,0 +1,18 @@
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 [ship](../ship). It is automatically created in the current directory when booting a ship for the first time.
9+
10+Your pier should be kept safe - if it's deleted, you will need to perform a [breach](../breach) in order to advise the rest of the network that your ship's state has been lost.
11+
12+Note that a backup should usually _not_ be taken of your pier as a means of keeping it safe - once the ship is run on the network, the backup will be outdated and running from it will necessitate a breach. A running ship automatically backs up its own state within the pier directory for recovery purposes, so as long as the pier is preserved, recovery from most problems is possible.
13+
14+### Further Reading
15+
16+- [Event Log](../eventlog): The main important content of the pier directory.
17+- [A Guide to Breaches](/using/id/guide-to-breaches): Instructions on handling continuity breaches (resets) on the Ames network.
18+- [Ship Troubleshooting](/using/os/ship-troubleshooting): General instructions on getting your ship to work, which includes network connectivity issues.
content/docs/glossary/pill.mdnew file+14
@@ -0,0 +1,14 @@
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](../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](../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](../clay) file system.
content/docs/glossary/planet.mdnew file+15
@@ -0,0 +1,15 @@
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](../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](../arvo) network. Planets are issued by [stars](../star), and receive services such as peer-to-peer routing and [over-the-air software updates](../ota-updates) from the star that sponsors them.
12+
13+- A [ship](../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](../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.mdnew file+29
@@ -0,0 +1,29 @@
1++++
2+title = "Proxies"
3+
4+template = "doc.html"
5+[extra]
6+category = "azimuth"
7++++
8+
9+**Proxies** are Ethereum addresses in the [Urbit HD Wallet](../hdwallet) system that have limited powers. They are lower-powered "siblings" of the ownership key, which has the sole power to transfer the assigned Urbit identity. Using [Bridge](../bridge), you can change the Ethereum addresses used for your proxies.
10+
11+There are three types of proxy.
12+
13+- **Management Proxy**
14+
15+The management proxy can configure or set Arvo networking keys and conduct sponsorship-related operations.
16+
17+- **Voting Proxy**
18+
19+The voting proxy can cast votes on behalf of its assigned point on new proposals, including changes to [Ecliptic](../ecliptic). The voting proxy is unique to [galaxies](../galaxy), since only power galaxies have seats in the Senate.
20+
21+- **Spawn Proxy**
22+
23+Creates new child points given Ethereum address. For [stars](../stars) and [galaxies](../galaxy) only.
24+
25+
26+### Further Reading
27+
28+- [Azimuth glossary page](../azimuth): The glossary entry for Azimuth.
29+- [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.mdnew file+13
@@ -0,0 +1,13 @@
1++++
2+title = "Replay"
3+
4+template = "doc.html"
5+[extra]
6+category = "arvo"
7++++
8+
9+**Replay** is how [Vere](../vere) computes the state of a ship's [Arvo](../arvo) instance from the [event log](../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/sailudon.mdnew file+13
@@ -0,0 +1,13 @@
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 used for rendering webpages, such as when browsing [collections](../collection) in [Landscape](../landscape).
12+
13+Udon is similar to Markdown, a simple language for writing documents. Udon is stored in [Clay](../clay) and rendered using [Ford](../ford).
content/docs/glossary/senate.mdnew file+14
@@ -0,0 +1,14 @@
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](../galaxy) that governs
10+[Azimuth](../azimuth) by [majority vote](../voting). There are two types of
11+votes: an [upgrade proposal](../upgrade), which is a motion to update the logic
12+of Azimuth (i.e. [Ecliptic](../ecliptic)), and a [document
13+proposal](../docvote), which is a motion to legitimize or approve the content of an
14+arbitrary document.
content/docs/glossary/ship.mdnew file+26
@@ -0,0 +1,26 @@
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](../arvo) network.
10+
11+A ship can be one of five classes:
12+
13+- [comets](../comet), disposable identities.
14+- [moons](../moon), connected devices subordinated to a ship.
15+- [planets](../planet), individual users.
16+- [stars](../star), network infrastructure nodes.
17+- [galaxy](../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](../azimuth)-based Urbit identity in the form of a [keyfile](../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](../pier): The directory containing a ship's state.
content/docs/glossary/shiparvonetwork.mdnew file+9
@@ -0,0 +1,9 @@
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](../ship) via HTTP utilizing DNS lookup. For example, the address for `~zod` would be `zod.arvo.network`.
content/docs/glossary/star.mdnew file+17
@@ -0,0 +1,17 @@
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](../galaxy) and [planets](../planet) in the identity hierarchy. Stars act as infrastructure for the [Arvo](../arvo) network, providing planets with [Ames](../ames)-related services, such as peer-to-peer routing and distributing [over-the-air software updates](../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](../azimuth) Urbit identity that sits between the [galaxy](../galaxy) and [planets](../planet) in the identity hierarchy. Stars, in this sense, have the power to issue [planets](../planet), and are themselves are issued by galaxies.
14+
15+- A [ship](../ship) on the Arvo network whose identity is a star in the former definition. In this sense, stars act as infrastructure for the [Arvo](../arvo) network, providing planets with [Ames](../ames)-related services, such as peer-to-peer routing and distributing [over-the-air software updates](../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.mdnew file+16
@@ -0,0 +1,16 @@
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](../clay) [desks](../desk). It is mostly used to distribute kernel updates.
10+
11+By default, in the [galaxy](../galaxy)/[star](../star)/[planet](../planet)/[moon](../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.mdnew file+14
@@ -0,0 +1,14 @@
1++++
2+title = "Trap"
3+
4+template = "doc.html"
5+[extra]
6+category = "hoon-nock"
7++++
8+
9+A **trap** is a [core](../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.mdnew file+13
@@ -0,0 +1,13 @@
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](../voting) action taken by the
10+[Galactic Senate](../senate) over [Azimuth](../azimuth). By passing an upgrade
11+proposal, [Galaxies](../galaxy) in the Senate agree to change the
12+[Ecliptic](../ecliptic) smart contracts.
13+
content/docs/glossary/vane.mdnew file+24
@@ -0,0 +1,24 @@
1++++
2+title = "Vane"
3+
4+template = "doc.html"
5+[extra]
6+category = "arvo"
7++++
8+
9+A **vane** is an [Arvo](../arvo) kernel module that performs essential system operations. The vanes are:
10+
11+
12+- [Ames](../ames), the peer-to-peer networking vane.
13+- [Behn](../behn), the timer vane.
14+- [Clay](../clay), the filesystem and revision-control vane.
15+- [Dill](../dill), the terminal-driver vane.
16+- [Eyre](../eyre), the HTTP vane.
17+- [Ford](../ford), the build-system vane.
18+- [Gall](../gall), the application vane.
19+- [Iris](../iris), the server HTTP vane.
20+- [Jael](../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.mdnew file+18
@@ -0,0 +1,18 @@
1++++
2+title = "Vere"
3+
4+template = "doc.html"
5+[extra]
6+category = "hoon-nock"
7++++
8+
9+**Vere**, pronounced "Vair", is the [Nock](../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](../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](../eventlog) with [Replay](../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](../ship), Vere passes your [Azimuth](../azimuth) [keyfile](../keyfile) into the Arvo state, allowing a connection to the [Ames](../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](../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.mdnew file+27
@@ -0,0 +1,27 @@
1++++
2+title = "Voting"
3+
4+template = "doc.html"
5+[extra]
6+category = "azimuth"
7++++
8+
9+**Voting** is a power available to [galaxies](../galaxy), in their capacities as
10+members of the [Galactic Senate](../senate), through an [Azimuth](../azimuth)
11+smart contract. Galaxies collectively make decisions about the governance of
12+Azimuth and the [Arvo](../arvo) network by voting. There are two types of proposals that can be voted on:
13+an [upgrade proposal](../upgrade) and a [document proposal](../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.mdnew file+11
@@ -0,0 +1,11 @@
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](../hdwallet) to secure your [Azimuth](../Azimuth) identities. Wallet Generator will be part of the [Bridge](../bridge) software, and it's a graphical user interface that handles the entire process of creating a new [Urbit HD Wallet](../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.mdnew file+27
@@ -0,0 +1,27 @@
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.mdnew file+13
@@ -0,0 +1,13 @@
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)
content/docs/hoon/guides/aqua.mdnew file+80
@@ -0,0 +1,80 @@
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.mdnew file+417
@@ -0,0 +1,417 @@
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 example
14+app that shows off how the `shoe` library works that we will be looking at
15+closely. These are all Gall apps, and as such their source can be found in the `app/` folder of your `%home` desk.
16+
17+In [the `shoe` library](#the-shoe-library) we take a closer look at the `shoe` library and its
18+cores and how they are utilized in CLI apps. Then in [the `sole`
19+library](#the-sole-library) we look at what `shoe` effects ultimately break down
20+into. Finally in [`%shoe` app walkthrough](#shoe-app-walkthrough) we explore
21+the functionality of the `%shoe` app and then go through the code line-by-line.
22+
23+This tutorial can be
24+considered to be an application equivalent of the [Hoon school
25+lesson](/docs/hoon/hoon-school/generators#ask) on `sole` and `%ask`
26+generators, which only covers the bare minimum necessary to write generators
27+that take user input.
28+
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+```hoon
48+[%shoe sole-ids=(list @ta) effect=shoe-effect]`
49+```
50+`sole-ids` is the `list` of session ids that the following `effect` is
51+emitted to. An empty `sole-ids` sends the effect to all connected sessions.
52+`shoe-effect`s, for now, are always of the shape `[%sole effect=sole-effect]`, where
53+`sole-effect`s are basic console events such as displaying text, changing the
54+prompt, beeping, etc. These are described in the section on the [`sole` library](#the-sole-library).
55+
56+For example, a `%shoe` `card` that causes all connected sessions to beep would
57+be `[%shoe ~ %sole %bel ~]`.
58+
59+### `shoe` core
60+
61+An iron (contravariant) door that defines an interface for Gall agents utilizing
62+the `shoe` library. Use this core whenever you want to receive input from the user and run a command. The input will get
63+put through the parser (`+command-parser`) and results in a noun of
64+`command-type` that the underlying application specifies, which shoe then feeds back into the underlying app as an `+on-command` callback.
65+
66+In addition to the ten arms that all Gall core apps possess, `+shoe` defines and expects a few
67+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
68+10-arm Gall agent core. See the [shoe example app
69+walkthrough](#shoe-example-app-walkthrough) for how to do this.
70+
71+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.
72+
73+#### `+command-parser`
74+
75+```hoon
76+ ++ command-parser
77+ |~ sole-id=@ta
78+ |~(nail *(like [? command-type]))
79+```
80+
81+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,
82+instantly run the command. If it's false, require the user to press return.
83+
84+#### `+tab-list`
85+
86+```hoon
87+ ++ tab-list
88+ |~ sole-id=@ta
89+ *(list (option:auto tank))
90+```
91+
92+Autocomplete options for the command-line session (to match `+command-parser`).
93+
94+#### `+on-command`
95+
96+```hoon
97+ ++ on-command
98+ |~ [sole-id=@ta command=command-type]
99+ *(quip card _this)
100+```
101+
102+Called when a valid command is run.
103+
104+#### `+can-connect`
105+
106+```hoon
107+ ++ can-connect
108+ |~ sole-id=@ta
109+ *?
110+```
111+
112+Called to determine whether a session may be opened or connected to. For example, you
113+may only want the local ship to be able to connect.
114+
115+#### `+on-connect`
116+
117+```hoon
118+ ++ on-connect
119+ |~ sole-id=@ta
120+ *(quip card _^|(..on-init))
121+```
122+
123+Called when a session is opened or connected to.
124+
125+#### `+on-disconnect`
126+
127+```hoon
128+ ++ on-disconnect
129+ |~ sole-id=@ta
130+ *(quip card _^|(..on-init))
131+```
132+
133+Called when a previously made session gets disconnected from.
134+
135+### `default` core
136+
137+This core contains the bare minimum implementation of the additional `shoe` arms
138+beyond the 10 standard Gall app ams. It is used
139+analogously to how the `default-agent` core is used for regular Gall apps.
140+
141+### `agent` core
142+
143+This is a function for wrapping a `shoe` core, which has too many
144+arms to be a valid Gall agent core. This turns it into a standard Gall agent core by
145+integrating the additional arms into the standard ones.
146+
147+
148+## The `sole` library {#the-sole-library}
149+
150+`shoe` apps may create specialized `card`s of the `[%shoe
151+(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+- `[%txt tape]` is used to display a line of text.
156+- `[%bel ~]` is used to emit a beep.
157+- `[%pro sole-prompt]` is used to set the prompt.
158+- `[%mor (list sole-effect)]` is used to emit multiple effects.
159+
160+For example, a `sole-effect` that beeps and displays `This is some text.` would
161+be structured as
162+```hoon
163+[%mor [%txt "This is some text."] [%bel ~] ~]
164+```
165+
166+## `%shoe` app walkthrough {#shoe-app-walkthrough}
167+
168+Here we explore the capabilities of the `%shoe` example app and then go through
169+the code, explaining what each line does.
170+
171+### Playing with `%shoe`
172+
173+First let's test the functionality of `%shoe` so we know what we're getting
174+into.
175+
176+Start two fake ships, one named `~zod` and the other can have any name - we will
177+go with `~nus`. Fake ships run locally are able to see each other, and our
178+intention is to connect their `%shoe` apps.
179+
180+On each fake ship start `%shoe` by entering `|start %shoe` into dojo. This will
181+automatically
182+change the prompt to `~zod:shoe>` and `~nus:shoe>`. Type `demo` and watch the following appear:
183+```
184+~zod ran the command
185+~zod:shoe>
186+```
187+`~zod ran the command` should be displayed in bold green text, signifying that
188+the command originated locally.
189+
190+Now we will connect the sessions. Switch `~zod` back to dojo with `Ctrl-X` and enter `|link
191+~nus %shoe`. If this succeeds you will see the following.
192+```
193+>=
194+; ~nus is your neighbor
195+[linked to [p=~nus q=%shoe]]
196+```
197+Now `~zod` will have two `%shoe` sessions running - one local one on `~zod` and
198+one remote one on `~nus`, which you can access by pressing `Ctrl-X` until you see
199+`~nus:shoe>` from `~zod`'s console. On the other hand, you should not see
200+`~zod:shoe>` on `~nus`'s side, since you have not connected `~nus` to `~zod`'s
201+`%shoe` app. When you enter `demo` from `~nus:shoe>` on
202+`~zod`'s console you will again see `~zod ran the command`, but this time it
203+should be in the ordinary font used by the console, signifying that the command
204+is originating from a remote session. Contrast this with entering `demo` from
205+`~nus:shoe>` in `~nus`'s console, which will display `~nus ran the command` in
206+bold green text.
207+
208+Now try to link to `~zod`'s `%shoe` session from `~nus` by switching to the dojo
209+on `~nus` and entering `|link ~zod %shoe`. You should see
210+```
211+>=
212+[unlinked from [p=~zod q=%shoe]]
213+```
214+and if you press `Ctrl-X` you will not get a `~zod:shoe>` prompt. This is
215+because the example app is set up to always allow `~zod` to connect (as well as
216+subject moons if the ship happens to be a planet) but not `~nus`, so this
217+message means that `~nus` failed to connect to `~zod`'s `%shoe` session.
218+
219+### `%shoe`'s code
220+
221+```hoon
222+:: shoe: example usage of /lib/shoe
223+::
224+:: the app supports one command: "demo".
225+:: running this command renders some text on all sole clients.
226+::
227+/+ shoe, verb, dbug, default-agent
228+```
229+
230+`/+` is the Ford rune which imports libraries from the `/lib` directory into
231+the subject.
232+ * `shoe` is the `shoe` library.
233+ * `verb` is a library used to print what a Gall agent is doing.
234+ * `dbug` is a library of debugging tools.
235+ * `default-agent` contains a Gall agent core with minimal implementations of
236+ required Gall arms.
237+
238+```hoon
239+|%
240++$ state-0 [%0 ~]
241++$ command ~
242+::
243++$ card card:shoe
244+--
245+```
246+The types used by the app.
247+
248+`state-0` stores the state of the app, which is null as there is no state to
249+keep track of. It is good practice to include a version number anyways,
250+in case the app is made stateful at a later time.
251+
252+`command` is typically a set of tagged union types that represent the possible
253+commands that can be entered by the user. Since this app only supports one
254+command, it is unnecessary for it to have any associated data, thus the command
255+is represented by `~`.
256+
257+In a non-trivial context, a `command` is commonly given by `[%name
258+data]`, where `%name` is the identifier for the type of command and `data` is
259+a type or list of types that contain data needed to execute the command. See
260+`app/chat-cli.hoon` for examples of commands, such as `[%say letter:store]` and
261+`[%delete path]`. This is not required though, and you could use something like
262+`[chat-room=@t =action]`.
263+
264+`card` is either an ordinary Gall agent `card` or a `%shoe` `card`, which takes
265+the shape `[%shoe sole-ids=(list @ta) effect=shoe-effect]`. A `%shoe` `card` is
266+sent to all `sole`s listed in `sole-ids`, imaking them run the `sole-effect`
267+specified by `effect` (i.e. printing some text). Here we can
268+reference `card:shoe` because of `/+ shoe` at the beginning of the app.
269+
270+```hoon
271+=| state-0
272+=* state -
273+::
274+```
275+Add the bunt value of `state-0` to the head of the subject, then give it the
276+macro `state`. The `-` here is a lark expression referring to the head of the
277+subject. This allows us to use `state` to refer to the state elsewhere in the
278+code no matter what version we're using, while also getting direct access to the
279+contents of `state` (if it had any).
280+
281+```hoon
282+%+ verb |
283+%- agent:dbug
284+^- agent:gall
285+%- (agent:shoe command)
286+^- (shoe:shoe command)
287+```
288+
289+The casts here are just reminders of what is being produced. So let's focus on
290+what the `%` runes are doing, from bottom to top. We call `(agent:shoe command)`
291+on what follows (i.e. the rest of the app),
292+producing a standard Gall agent core. Then we call wrap the Gall agent core with
293+`agent:dbug`, endowing it with additional arms useful for debugging, and then
294+wrap again with `verb`.
295+
296+
297+```hoon
298+|_ =bowl:gall
299++* this .
300+ def ~(. (default-agent this %|) bowl)
301+ des ~(. (default:shoe this command) bowl)
302+```
303+This is boilerplate Gall agent core code. We set `this` to be a macro for the
304+subject, which is the Gall agent core itself. We set `def` and `des` to be
305+macros for initialized `default-agent` and `default:shoe` doors respectively.
306+
307+Next we implement all of the arms required for a `shoe` agent. Starting with
308+the standard Gall arms:
309+
310+```hoon
311+++ on-init on-init:def
312+++ on-save !>(state)
313+++ on-load
314+ |= old=vase
315+ ^- (quip card _this)
316+ [~ this]
317+::
318+++ on-poke on-poke:def
319+++ on-watch on-watch:def
320+++ on-leave on-leave:def
321+++ on-peek on-peek:def
322+++ on-agent on-agent:def
323+++ on-arvo on-arvo:def
324+++ on-fail on-fail:def
325+```
326+These are minimalist Gall app arm implementations using the default behavior found in `def`.
327+
328+Here begins the implementation of the additional arms required by the
329+`(shoe:shoe command)` interface.
330+```hoon
331+++ command-parser
332+ |= sole-id=@ta
333+ ^+ |~(nail *(like [? command]))
334+ (cold [& ~] (jest 'demo'))
335+```
336+`+command-parser` is of central importance - it is what is used to parse user
337+input and transform it into `command`s for the app to execute. Writing a proper
338+command parser requires understanding of the Hoon parsing functions found in the
339+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
340+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.
341+
342+
343+```hoon
344+++ tab-list
345+ |= sole-id=@ta
346+ ^- (list [@t tank])
347+ :~ ['demo' leaf+"run example command"]
348+ ==
349+```
350+`+tab-list` is pretty much plug-n-play. For each command you want to be tab
351+completed, add an entry to the `list` begun by `:~` of the form `[%command
352+leaf+"description"]`. Now whenever the user types a partial command and presses
353+tab, the console will display the list of commmands that match the partial
354+command as well as the descriptions given here.
355+
356+Thus here we have that starting to type `demo` and pressing tab will result in
357+the following output in the console:
358+```
359+demo run example command
360+~zod:shoe> demo
361+```
362+with the remainder of `demo` now added to the input line.
363+
364+Next we have `+on-command`, which is called whenever `+command-parser`
365+recognizes that `demo` has been entered by a user.
366+```hoon
367+++ on-command
368+ |= [sole-id=@ta =command]
369+ ^- (quip card _this)
370+```
371+This is a gate that takes in the `sole-id` corresponding to the session and the
372+`command` noun parsed by `+command-parser` and returns a `list` of `card`s and
373+`_this`, which is our shoe agent core including its state.
374+```hoon
375+ =- [[%shoe ~ %sole -]~ this]
376+```
377+This creates a cell of a `%shoe` card that triggers a `sole-effect` given by the head of
378+the subject `-`, then the Gall agent core `this` - i.e. the return result of
379+this gate. The use of the `=-` rune means that what follows this
380+expression is actually run first, which puts the desired `sole-effect` into the
381+head of the subject.
382+```hoon
383+ =/ =tape "{(scow %p src.bowl)} ran the command"
384+```
385+We define the `tape` that we want to be printed.
386+```hoon
387+ ?. =(src our):bowl
388+ [%txt tape]
389+ [%klr [[`%br ~ `%g] [(crip tape)]~]~]
390+```
391+We cannot just produce the `tape` we want printed, - it needs to fit the
392+`sole-effect` type. This tells us that if the
393+origin of the command is not our ship to just print it normally with the `%txt`
394+`sole-effect`. Otherwise we use `%klr`, which prints it stylistically (here it
395+makes the text green and bold).
396+
397+The following allows either `~zod`, or the host ship and its moons, to connect to
398+this app's command line interface using `|link`.
399+```hoon
400+++ can-connect
401+ |= sole-id=@ta
402+ ^- ?
403+ ?| =(~zod src.bowl)
404+ (team:title [our src]:bowl)
405+ ==
406+```
407+
408+We use the minimal implementations for the final two `shoe` arms, since we don't
409+want to do anything special when users connect or disconnect.
410+```hoon
411+++ on-connect on-connect:des
412+++ on-disconnect on-disconnect:des
413+--
414+```
415+
416+This concludes our review of the code of the `%shoe` app. To continue learning
417+how to build your own CLI app, we recommend checking out `/app/chat-cli.hoon`.
content/docs/hoon/guides/parsing.mdnew file+650
@@ -0,0 +1,650 @@
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+## What is parsing? {#what-is-parsing}
13+
14+A program which takes a raw sequence of characters as an input and produces a data
15+structure as an output is known as a _parser_. The data structure produced
16+depends on the use case, but often it may be represented as a tree and the
17+output is thought of as a structural representation of the input. Parsers are ubiquitous in
18+computing, commonly used for to perform tasks such as reading files, compiling
19+source code, or understanding commands input in a command line interface.
20+
21+Parsing a string is rarely done all at once. Instead, it is usually done
22+character-by-character, and the return contains the data structure representing
23+what has been parsed thus far as well as the remainder of the string to be
24+parsed. They also need to be able to fail in case the input is improperly
25+formed. We will see each of these standard practices implemented in [Hoon below](#parsing-in-hoon).
26+
27+## Functional parsers
28+
29+How parsers are built varies substantially depending on what sort of programming
30+language it is written in. As Hoon is a functional programming language, we will
31+be focused on understanding _functional parsers_, also known as _combinator
32+parsers_. In this section we will make light use of pseudocode, as introducing
33+the Hoon to describe functional parsers here creates a chicken-and-egg problem.
34+
35+Complex functional parsers are built piece by piece from simpler parsers
36+that are plugged into one another in various ways to perform the desired task.
37+
38+The basic building blocks, or primitives, are parsers that read only a
39+single character. There are frequently a few types of possible input characters,
40+such as letters, numbers, and symbols. For example, `(parse "1" integer)` calls
41+the parsing routine on the string `"1"` and looks for an integer, and so it
42+returns the integer `1`. However, taking into account what was said above about
43+parsers returning the unparsed portion of the string as well, we should
44+represent this return as a tuple. So we should expect something like this:
45+```
46+> (parse "1" integer)
47+[1 ""]
48+> (parse "123" integer)
49+[1 "23"]
50+```
51+What if we wish to parse the rest of the string? We would need to apply the
52+`parse` function again:
53+```
54+> (parse (parse "123" integer) integer)
55+[12 "3"]
56+> (parse (parse (parse "123" integer) integer) integer)
57+[123 ""]
58+```
59+So we see that we can parse strings larger than one character by stringing
60+together parsing functions for single characters. Thus in addition to parsing
61+functions for single input characters, we want _parser combinators_ that
62+allow you to combine two or more parsers to form a more complex one.
63+Combinators come in a few shapes and sizes, and typical operations they may
64+perform would be to repeat the same parsing operation until the string is
65+consumed, try a few different parsing operations until one of them works,
66+or perform a sequence of parsing operations. We will see how all of this is done
67+with Hoon in the [Parsing in Hoon](#parsing-in-hoon) section.
68+
69+# Parsing in Hoon
70+
71+In this section we will cover the basic types, parser functions, and parser
72+combinators that are utilized for parsing in Hoon. This is not a complete guide
73+to every parsing-related functionality in the standard library (of which there
74+are quite a few), but ought to be
75+sufficient to get started with parsing in Hoon and be equipped to discover the
76+remainder yourself.
77+
78+
79+## Basic types
80+
81+In this section we discuss the types most commonly used for Hoon parsers. In short:
82+
83+ - A `hair` is the position in the text the parser is at,
84+ - A `nail` is parser input,
85+ - An `edge` is parser output,
86+ - A `rule` is a parser.
87+
88+### `hair`
89+
90+```hoon
91+++ hair [p=@ud q=@ud]
92+```
93+
94+A `hair` is a pair of `@ud` used to keep track of what has already been parsed
95+for stack tracing purposes. This allows the parser to reveal where the problem
96+is in case it hits something unexpected during parsing.
97+
98+`p` represents the column and `q` represents the line.
99+
100+### `nail`
101+
102+```hoon
103+++ nail [p=hair q=tape]
104+```
105+We recall from our [discussion above](#what-is-parsing) that parsing functions must keep
106+track of both what has been parsed and what has yet to be parsed. Thus a `nail`
107+consists of both a `hair`, giving the line and column up to which the input
108+sequence has already been parsed, and a `tape`, consisting of what remains of
109+the original input string (i.e. everything after the location indicated by the
110+`nail`, including the character at that `nail`).
111+
112+For example, if you wish to feed the entire `tape` `"abc"` into a parser, you
113+would pass it as the `nail` `[[1 1] "abc"]`. If the parser successfully parses the first
114+character, the `nail` it returns will be `[[1 2] "bc"]` (though we note that
115+parser outputs are actually `edge`s which contain a `nail`, see the following).
116+The `nail` only matters for book-keeping reasons - it could be any value here
117+since it doesn't refer to a specific portion of the string being input, but only
118+what has theoretically already been parsed up to that point.
119+
120+### `edge`
121+
122+```hoon
123+++ edge [p=hair q=(unit [p=* q=nail])]
124+```
125+An `edge` is the output of a parser. If parsing succeeded, `p` is the location
126+of the original input `tape `up to which the text has been parsed. If parsing
127+failed, `p` will be the first `hair` at which parsing failed.
128+
129+`q` may be `~`, indicating that parsing has failed .
130+If parsing did not fail, `p.q` is the data structure that is the result of the
131+parse up to this point, while `q.q` is the `nail` which contains the remainder
132+of what is to be parsed. If `q` is not null, `p` and `p.q.q` are identical.
133+
134+### `rule`
135+
136+```hoon
137+++ rule _|:($:nail $:edge)
138+```
139+A `rule` is a gate which takes in a `nail` and returns an `edge` - in other
140+words, a parser.
141+
142+## Parser builders
143+
144+These functions are used to build `rule`s (i.e. parsers), and thus are often
145+called rule-builders. For a complete list of parser builders, see [4f: Parsing
146+(Rule-Builders)](/docs/hoon/reference/stdlib/4f), but also the more specific
147+functions in [4h: Parsing (ASCII
148+Glyphs)](/docs/hoon/reference/stdlib/4h), [4i: Parsing (Useful
149+Idioms)](/docs/hoon/reference/stdlib/4i), [4j: Parsing (Bases and Base
150+Digits)](/docs/hoon/reference/stdlib/4j), [4l: Atom Parsing](/docs/hoon/reference/stdlib/4l).
151+
152+### `+just`
153+
154+The most basic rule builder, `+just` takes in a single `char` and produces a
155+`rule` that attempts to match that `char` to the first character in the `tape`
156+of the input `nail`.
157+
158+```
159+> =edg ((just 'a') [[1 1] "abc"])
160+> edg
161+[p=[p=1 q=2] q=[~ [p='a' q=[p=[p=1 q=2] q="bc"]]]]
162+```
163+We note that `p.edg` is `[p=1 q=2]`, indicating that the next character to be
164+parsed is in line 1, column 2. `q.edg` is not null, indicating that parsing
165+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
166+`rule`s built using standard library functions when parsing succeeds. Lastly,
167+`q.q.edg` is `"bc"`, which is the part of the input `tape` that has yet to be parsed.
168+
169+Now let's see what happens when parsing fails.
170+```
171+> =edg ((just 'b') [[1 1] "abc"])
172+> edg
173+[p=[p=1 q=1] q=~]
174+```
175+Now we have that `p.edg` is the same as the input `hair`, `[1 1]`, meaning the
176+parser has not advanced since parsing failed. `q.edg` is null, indicating that
177+parsing has failed.
178+
179+Later we will use [+star](#star) to string together a sequence of `+just`s in
180+order to parse multiple characters at once.
181+
182+### `+jest`
183+
184+`+jest` is a `rule` builder used to match a `cord`. It takes an input `cord` and
185+produces a `rule` that attempts to match that `cord` against the beginning of
186+the input.
187+
188+Let's see what happens when we successfully parse the entire input `tape`.
189+```
190+> =edg ((jest 'abc') [[1 1] "abc"])
191+> edg
192+[p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=""]]]]
193+```
194+`p.edg` is `[p=1 q=4]`, indicating that the next character to be parsed is at
195+line 1, column 4. Of course, this does not exist since the input `tape` was only
196+3 characters long, so this actually indicates that the entire `tape` has been
197+successfully parsed (since the `hair` does not advance in the case of failure).
198+`p.q.edg` is `'abc'`, as expected. `q.q.edg` is `""`, indicating that nothing
199+remains to be parsed.
200+
201+What happens if we only match some of the input `tape`?
202+```
203+> =edg ((jest 'ab') [[1 1] "abc"])
204+> edg
205+[p=[p=1 q=3] q=[~ [p='ab' q=[p=[p=1 q=3] q="c"]]]]
206+```
207+Now we have that the result, `p.q.edg`, is `'ab'`, while the remainder `q.q.q.edg`
208+is `"c"`. So `+jest` has successfully parsed the first two characters, while the
209+last character remains. Furthermore, we still have the information that the
210+remaining character was in line 1 column 3 from `p.edg` and `p.q.q.edg`.
211+
212+What happens when `+jest` fails?
213+```
214+> ((jest 'bc') [[1 1] "abc"])
215+[p=[p=1 q=1] q=~]
216+```
217+Despite the fact that `'bc'` appears in `"abc"`, because it was not at the
218+beginning the parse failed. We will see in [parser
219+combinators](#parser-combinators) how to modify this `rule` so that it
220+finds `bc` successfully.
221+
222+### `+shim`
223+
224+`+shim` is used to parse characters within a given range. It takes in two atoms
225+and returns a `rule`.
226+
227+```
228+> ((shim 'a' 'z') [[1 1] "abc"])
229+[p=[p=1 q=2] q=[~ [p='a' q=[p=[p=1 q=2] q="bc"]]]]
230+```
231+
232+### `+cold`
233+
234+`+cold` is a `rule` builder that takes in a constant noun we'll call `cus` and a
235+`rule` we'll call `sef`. It returns a `rule` identical to the `sef` except it
236+replaces the parsing result with `cus`.
237+
238+Here we see that `p.q` of the `edge` returned by the `rule` created with `+cold`
239+is `%foo`.
240+```
241+> ((cold %foo (just 'a')) [[1 1] "abc"])
242+[p=[p=1 q=2] q=[~ u=[p=%foo q=[p=[p=1 q=2] q="bc"]]]]
243+```
244+
245+One common scenario where `+cold` sees play is when writing [command line
246+interface (CLI) apps](/docs/hoon/guides/cli-tutorial). We usher the
247+reader there to find an example where `+cold` is used.
248+
249+
250+### `+knee`
251+
252+Another important function in the parser builder library is `+knee`, used for building
253+recursive parsers. We delay discussion of `+knee` to the
254+[section below](#recursive-parsers) as more context is needed to explain it
255+properly.
256+
257+
258+## Outside callers
259+
260+Since `hair`s, `nail`s, etc. are only utilized within the context of writing
261+parsers, we'd like to hide them from the rest of the code of a program that
262+utilizes parsers. That is to say, you'd like the programmer to only worry about
263+passing `tape`s to the parser, and not have to dress up the `tape` as a `nail`
264+themselves. Thus we have several functions for exactly this purpose.
265+
266+These functions take in either a `tape` or a `cord`,
267+alongside a `rule`, and attempt to parse the input with the `rule`. If the
268+parse succeeds, it returns the result. There are crashing and unitized versions
269+of each caller, corresponding to what happens when a parse fails.
270+
271+For additional information including additional examples see [4g: Parsing (Outside Caller)](/docs/hoon/reference/stdlib/4g).
272+
273+### Parsing `tape`s
274+
275+`+scan` takes in a `tape` and a `rule` and attempts to parse the `tape` with the
276+`rule`.
277+
278+```
279+> (scan "hello" (jest 'hello'))
280+'hello'
281+> (scan "hello zod" (jest 'hello'))
282+{1 6}
283+'syntax-error'
284+```
285+
286+`+rust` is the unitized version of `+scan`.
287+
288+```
289+> (rust "a" (just 'a'))
290+[~ 'a']
291+> (rust "a" (just 'b'))
292+~
293+```
294+
295+For the remainder of this tutorial we will make use of `+scan` so that we do not
296+need to deal directly with `nail`s except where it is ilustrative to do so.
297+
298+
299+### Parsing atoms
300+
301+[Recall](/docs/hoon/hoon-school/lists) that `cord`s are atoms with the aura
302+`@t` and are typically used to represent strings internally as data, as atoms
303+are faster for the computer to work with than `tape`s, which are `list`s of
304+`@tD` atoms. `+rash` and `+rush` are for parsing atoms, with `+rash` being
305+analogous to `+scan` and `+rush` being analogous to `rust`. Under the hood, `+rash`
306+calls `+scan` after converting the input atom to a `tape`, and `+rush` does
307+similary for `+rust`.
308+
309+## Parser modifiers
310+
311+The standard library provides a number of gates that take a `rule` and
312+produce a new modified `rule` according to some process. We call these _parser modifiers_. These are
313+documented among the [parser builders](/docs/hoon/reference/stdlib/4f).
314+
315+
316+### `+ifix`
317+
318+`+ifix` modifies a `rule` so that it matches that `rule` only when it is
319+surrounded on both sides by text that matches a pair of `rule`s, which is discarded.
320+
321+```
322+> (scan "(42)" (ifix [pal par] (jest '42')))
323+'42'
324+```
325+`+pal` and `+par` are shorthand for `(just '(')` and `(just ')')`, respectively. All
326+ASCII glyphs have counterparts of this sort, documented
327+[here](/docs/hoon/reference/stdlib/4h).
328+
329+
330+### `+star` {#star}
331+
332+`+star` is used to apply a `rule` repeatedly. Recall that `+just` only parses
333+the first character in the input `tape.`
334+
335+```
336+> ((just 'a') [[1 1] "aaaa"])
337+[p=[p=1 q=2] q=[~ [p='a' q=[p=[p=1 q=2] q="aaa"]]]]
338+```
339+
340+We can use `+star` to get the rest of the `tape`:
341+
342+```
343+> ((star (just 'a')) [[1 1] "aaa"])
344+[p=[p=1 q=4] q=[~ [p=[i='a' t=<|a a|>] q=[p=[p=1 q=4] q=""]]]]
345+```
346+and we note that the parsing ceases when it fails.
347+```
348+> ((star (just 'a')) [[1 1] "aaab"])
349+[p=[p=1 q=4] q=[~ [p=[i='a' t=<|a a|>] q=[p=[p=1 q=4] q="b"]]]]
350+```
351+
352+## Parser combinators
353+
354+Building complex parsers from simpler parsers is accomplished in Hoon with the
355+use of two tools: the monadic applicator rune
356+[`;~`](/docs/hoon/reference/rune/mic#micsig) and [parsing
357+combinators](/docs/hoon/reference/stdlib/4e). First we introduce a few
358+combinators, then we examine more closely how `;~` is used to chain them together.
359+
360+The syntax to combine `rule`s is
361+```hoon
362+;~(combinator rule1 rule2 ... ruleN)
363+```
364+The `rule`s are composed together using the combinator as an
365+intermediate function, which takes product of a `rule` (an `edge`) and a `rule` and turns
366+it into a sample (a `nail`) for the next `rule` to handle. We elaborate on this
367+behavior [below](#micsig).
368+
369+### `+plug`
370+
371+`+plug` simply takes the `nail` in the `edge` produced by one rule and passes it
372+to the next `rule`, forming a cell of the results as it proceeds.
373+
374+```
375+> (scan "starship" ;~(plug (jest 'star') (jest 'ship')))
376+['star' 'ship']
377+```
378+
379+### `+pose`
380+
381+`+pose` tries each `rule` you hand it successively until it finds one that
382+works.
383+
384+```
385+> (scan "a" ;~(pose (just 'a') (just 'b')))
386+'a'
387+> (scan "b" ;~(pose (just 'a') (just 'b')))
388+'b'
389+```
390+
391+### `+glue`
392+
393+`+glue` parses a delimiter in between each `rule` and forms a cell of the
394+results of each `rule`.
395+
396+```
397+> (scan "a,b" ;~((glue com) (just 'a') (just 'b')))
398+['a' 'b']
399+> (scan "a,b,a" ;~((glue com) (just 'a') (just 'b')))
400+{1 4}
401+syntax error
402+```
403+
404+### `;~` {#micsig}
405+
406+Understanding the rune `;~` is essential to building parsers with Hoon. Let's
407+take this opportunity to think about it carefully.
408+
409+The `rule` created by `;~(combinator [list rule])` may be understood
410+inductively. To do this, let's consider the base case where our `[list rule]` has only a
411+single entry.
412+```
413+> (scan "star" ;~(plug (jest 'star')))
414+'star'
415+```
416+Our output is identical to that given by `scan "star" (jest 'star')`. This is to
417+be expected. The combinator `+plug` is specifically used for chaining together
418+`rule`s in the `[list rule]`, but if there is only one `rule`, there is nothing
419+to chain. Thus, swapping out `+plug` for another combinator makes no difference here:
420+```
421+> (scan "star" ;~(pose (jest 'star')))
422+'star'
423+> (scan "star" ;~((glue com) (jest 'star')))
424+'star'
425+```
426+`;~` and the combinator only begin to play a role once the `[list rule]` has at
427+least two elements. So let's look at an example done with `+plug`, the simplest
428+combinator.
429+```
430+> (scan "star" ;~(plug (jest 'st') (jest 'ar')))
431+['st' 'ar']
432+```
433+Our return suggests that we first parsed `"star"` with the `rule` `(jest 'st')` and passed
434+the resulting `edge` to `(jest 'ar')` - in other words, we called `+plug` on `(jest
435+'st')` and the `edge` returned once it had been used to parse `"star"`. Thus
436+`+plug` was the glue that allowed us to join the two `rule`s, and `;~` performed
437+the gluing operation. And so, swapping `+plug` for `+pose` results in a crash,
438+which clues us into the fact that the combinator now has an effect since there
439+is more than one `rule`.
440+```
441+> (scan "star" ;~(pose (jest 'st') (jest 'ar')))
442+{1 3}
443+syntax error
444+```
445+
446+
447+
448+## Parsing numbers
449+
450+Functions for parsing numbers are documented in [4j: Parsing (Bases and Base
451+Digits)](/docs/hoon/reference/stdlib/4j). In particular, `dem` is a `rule`
452+for parsing decimal numbers.
453+
454+```
455+> (scan "42" dem)
456+42
457+> (add 1 (scan "42" dem))
458+43
459+```
460+
461+## Recursive parsers
462+
463+Naively attempting to write a recursive `rule`, i.e. like
464+```
465+> |-(;~(pose den ;~(pose $ (easy ~))))
466+```
467+results in an error.
468+```
469+-find.,.+6
470+-find.,.+6
471+rest-loop
472+```
473+Thus some special sauce is required, the `+knee` function.
474+
475+`+knee` takes in a noun that is the default value of the parser, typically given
476+as the bunt value of the type that the `rule` produces, as well as a gate that
477+accepts a `rule`. `+knee` produces a `rule` that implements any recursive calls
478+in the `rule` in a manner acceptable to the compiler. Thus the preferred manner
479+to write the above `rule` is as follows:
480+
481+```hoon
482+++ pars
483+ |-
484+ ;~ plug prn
485+ ;~ pose
486+ (knee *tape |.(^$))
487+ (easy ~)
488+ ==
489+ ==
490+```
491+
492+You may want to utilize the `~+` rune when writing recursive parsers to cache
493+the parser to improve performance. In [parsing arithmetic
494+expressions](#parsing-arithmetic-expressions) we will be writing a recursive
495+parser making use of `+knee` and `~+` throughout.
496+
497+
498+# Parsing arithmetic expressions
499+
500+In this section we will be applying what we have learned to write a parser for
501+arithmetic expressions in Hoon. That is, we will make a `rule` that takes in
502+`tape`s of the form `"(2+3)*4"` and returns `20` as a `@ud`.
503+
504+We call a `tape` consisting of some consistent arithmetic string of numbers,
505+`+`, `*`, `(`, and `)` an _expression_. We wish to build a `rule` that takes in an
506+expression and returns the result of the arithmetic computation described by the
507+expression as a `@ud`.
508+
509+To build a parser it is a helpful exercise to first describe its
510+[grammar](https://en.wikipedia.org/wiki/Parsing_expression_grammar). This has a
511+formal mathematical definition, but we will manage to get by here describing the grammar
512+for arithmetic expressions informally.
513+
514+First lets look at the code we're going to use, and then dive into explaining
515+it. If you'd like to follow along, save the following as `expr-parse.hoon` in
516+your `gen/` folder.
517+```hoon
518+:: expr-parse: parse arithmetic expressions
519+::
520+|= xprs=tape
521+|^ (scan xprs expr)
522+++ factor
523+ %+ knee *@ud
524+ |. ~+
525+ ;~ pose
526+ dem
527+ (ifix [pal par] expr)
528+ ==
529+++ turm
530+ %+ knee *@ud
531+ |. ~+
532+ ;~ pose
533+ ((slug mul) tar ;~(pose factor turm))
534+ factor
535+ ==
536+++ expr
537+ %+ knee *@ud
538+ |. ~+
539+ ;~ pose
540+ ((slug add) lus ;~(pose turm expr))
541+ turm
542+ ==
543+--
544+```
545+
546+Informally, the grammar here is:
547+ - A factor is either an integer or an expression surrounded by parentheses.
548+ - A term is either a factor or a factor times a term.
549+ - An expression is either a term or a term plus an expression.
550+
551+### Factors, terms, and expressions
552+
553+Our grammar consists of three `rule`s: one for factors, one for terms, and one
554+for expressions.
555+
556+#### Factors
557+
558+```hoon
559+++ factor
560+ %+ knee *@ud
561+ |. ~+
562+ ;~ pose
563+ dem
564+ (ifix [pal par] expr)
565+ ==
566+```
567+
568+A _factor_ is either a decimal number or an expression surrounded by parentheses. Put
569+into Hoon terms, a decimal number is parsed by the `rule` `+dem` and an
570+expression is parsed by removing the surrounding parentheses and then passing
571+the result to the expression parser arm `+expr`, given by the `rule` `(ifix [pal
572+par] expr)`. Since we want to parse our expression with one or the other, we
573+chain these two `rule`s together using the monadic applicator rune `;~` along
574+with `+pose`, which says to try each rule in succession until one of them works.
575+
576+Since expressions ultimately reduce to factors, we are actually building a
577+recursive rule. Thus we need to make use of `+knee`. The first argument for
578+`+knee` is `*@ud`, since our final answer should be a `@ud`.
579+
580+Then follows the definition of the gate utilized by `+knee`:
581+```hoon
582+ |. ~+
583+ ;~ pose
584+ dem
585+ (ifix [pal par] expr)
586+ ==
587+```
588+`~+` is used to cache the parser, so that it does not need to be computed over
589+and over again. Then it follows the `rule` we described above.
590+
591+#### Parsing expressions
592+
593+An _expression_ is either a term plus an expression or a term.
594+
595+In the case of a term plus an expression, we actually must compute what that equals. Thus we will
596+make use of [`+slug`](/docs/hoon/reference/stdlib/4f#slug), which parses a
597+delimited list into `tape`s separated by a given delimiter and then composes
598+them by folding with a binary gate. In this case, our delimiter is `+` and our
599+binary gate is `+add`. That is to say, we will split the input string into terms
600+and expressions separated by luses, parse each term and expression until they
601+reduce to a `@ud`, and then add them together. This is accomplished with the
602+rule `((slug add) lus ;~(pose turm expr))`.
603+
604+If the above `rule` does not parse the expression, it must be a `turm`, so the
605+`tape` is automatically passed to `+turm` to be evaluated. Again we use `;~` and `pose` to
606+accomplish this:
607+
608+```hoon
609+;~ pose
610+ ((slug add) lus ;~(pose turm expr))
611+ turm
612+==
613+```
614+
615+The rest of the `+expr` arm is structured just like how `+factor` is, and for
616+the same reasons.
617+
618+
619+#### Parsing terms
620+
621+A _term_ is either a factor times a term or a factor. This is handled similarly
622+for expressions, we just need to swap `lus` for `tar`, `add` for `mul`, and
623+`;~(pose factor turm)` instead of `;~(pose turm expr)`.
624+
625+```hoon
626+++ expr
627+ %+ knee *@ud
628+ |. ~+
629+ ;~ pose
630+ ((slug add) lus ;~(pose turm expr))
631+ turm
632+ ==
633+```
634+
635+### Try it out
636+
637+Let's feed some expressions to `+expr-parse` and see how it does.
638+
639+```
640+> +expr-parse "3"
641+3
642+> +expr-parse "3+3"
643+6
644+> +expr-parse "3+3+(2*3)+(4+2)*(4+1)"
645+42
646+> +expr-parse "3+3+2*3"
647+12
648+```
649+
650+As an exercise, add exponentiation (e.g. `2^3 = 8`) to `+expr-parse`.
content/docs/hoon/hoon-school/_index.mdnew file+42
@@ -0,0 +1,42 @@
1++++
2+title = "Hoon School"
3+weight = 10
4+sort_by = "weight"
5+template = "sections/docs/hoon.html"
6+aliases = ["/docs/byte/0/", "/docs/byte", "/docs/learn/hoon/hoon-tutorial/"]
7+insert_anchor_links = "right"
8++++
9+
10+This series is designed to teach you Hoon without assuming you have an extensive
11+programming background. In fact, you should be able to follow much of it even if
12+you have no programming experience at all, though of course experience helps. We
13+strongly encourage you to try out all the examples of each lesson. These lessons
14+are meant for the beginner, but they aren't meant to be skimmed. Each lesson
15+falls into one of two categories: **readings**, which are prose-heavy
16+explanations of Hoon fundamentals, and **walkthroughs**, which are line-by-line
17+explanations of example programs. Walkthroughs are found between readings,
18+offering a practical implementation of the concepts taught in the reading
19+before.
20+
21+If you're curious about why Urbit is written in this new language, we recommend
22+reading the [Hoon overview](/docs/hoon/overview) that covers the high-level
23+design decisions behind the language.
24+
25+Chapter 1 introduces and explains the fundamental concepts you need in order to
26+understand Hoon's semantics.
27+
28+Hoon is a "subject-oriented" programming language &mdash; every expression of
29+Hoon is evaluated relative to a **subject**. The subject is a piece of data that
30+represents the environment, or the context, of an expression. After reading
31+Chapter 1 you should understand what the subject is and how to refer to its
32+various parts. In this chapter you'll also learn about
33+**[cores](/docs/glossary/core/)**, which are an important data structure in
34+Hoon. Once you get the hang of [cores](/docs/glossary/core/) you'll be able to
35+write your own functions in Hoon.
36+
37+Chapter 2 covers the type system, writing basic apps, and the workings of the
38+Arvo kernel.
39+
40+You should also consider enrolling in Hooniversity, a regularly held
41+community-run course which follows along the Hoon School curriculum and may be
42+found at [Hooniversity](https://hooniversity.org/).
content/docs/hoon/hoon-school/ackermann.mdnew file+29
@@ -0,0 +1,29 @@
1++++
2+title = "1.6.1 Walkthrough: Ackermann Function"
3+weight = 14
4+template = "doc.html"
5+aliases = ["docs/learn/hoon/hoon-tutorial/ackermann/"]
6++++
7+
8+The Ackermann function is one of the earliest examples of a function that is both totally computable -- meaning that it can be solved -- and not primitively recursive -- meaning it can not be rewritten in an iterative fashion.
9+
10+In this lesson, we will write a [gate](/docs/glossary/gate/) that computes the [Ackermann function](https://en.wikipedia.org/wiki/Ackermann_function)
11+
12+``` hoon
13+|= [m=@ n=@]
14+?: =(m 0) +(n)
15+?: =(n 0) $(m (dec m), n 1)
16+$(m (dec m), n $(n (dec n)))
17+```
18+
19+With the first line, `|= [m=@ n=@]`, we create a gate that takes two arguments, `m` and `n`, both of the `@` type.
20+
21+
22+
23+There are three cases.
24+
25+First, if `m` is zero, return the increment of `n`.
26+Second, if `n` is zero, decrement `m`, set `n` to 1 and recurse.
27+Else, decrement `m` and set `n` to be the value of the Ackermann function with `n` and the decrement of `n` as arguments.
28+
29+This is not a terribly useful function to compute but it has an interesting history in mathematics. When running this function the value grows rapidly even for very small input. The value of computing this where `m` is `4` and `n` is `2` is an integer with 19,729 digits.
content/docs/hoon/hoon-school/arms-and-cores.mdnew file+652
@@ -0,0 +1,652 @@
1++++
2+title = "1.7 Arms and Cores"
3+weight = 15
4+template = "doc.html"
5+aliases = ["/docs/learn/hoon/hoon-tutorial/arms-and-cores/"]
6++++
7+The Hoon subject is a [noun](/docs/glossary/noun/). Each fragment of this [noun](/docs/glossary/noun/) is either an [arm](/docs/glossary/arm/) or a leg. In the previous lesson you learned what a leg is, and how to return legs of the subject by various means. In this lesson you'll learn what an [arm](/docs/glossary/arm/) is. Arms are a bit more complex than legs -- a full understanding of them requires a bit more background knowledge. Accordingly, in this lesson we must also introduce an important Hoon data structure: a '[core](/docs/glossary/core/)'.
8+
9+After arms are defined and explained we review wing expressions, this time focusing on wing resolution to arms.
10+
11+## A Preliminary Explanation
12+
13+Arms and legs are limbs of the subject, i.e., noun fragments of the subject. In the last lesson we said that legs are for data and arms are for computations. But what _specifically_ is an arm, and how is it used for computation? Let's begin with a preliminary explanation that will be refined later in the lesson.
14+
15+An **arm** is some expression of Hoon encoded as a noun. (By 'encoded as a noun' we literally mean: 'compiled to a Nock formula'. But you don't need to know anything about Nock to understand Hoon.) You virtually never need to treat an arm as raw data, even though technically you can -- it's just a noun like any other. You virtually always want to think of an arm simply as a way of running some Hoon code.
16+
17+Every expression of Hoon is evaluated relative to a subject. What subject is the arm to be evaluated against? Answer: the parent [core](/docs/glossary/core/) of that arm.
18+
19+So in order to understand fully what an arm is, you must understand what a core is. Briefly, a **core** is a cell of `[battery payload]`. The **battery** is a collection of one or more arms, and the **payload** is the data needed by the arms to evaluate correctly. (The battery is code and the [payload](/docs/glossary/payload/) is data for that code.) A given core is the **parent core** of all of the arms in its battery.
20+
21+## Your First Core
22+
23+To clarify the basic idea, let's look at an example core.
24+
25+We'll make a core using a multi-line Hoon expression that is more complex than the other examples you've seen up to this point. The dojo can be used to input multi-line Hoon expressions; just type each line, hitting 'enter' or 'return' at the end. The expression will be evaluated at the appropriate line break, i.e., when the dojo recognizes it as a complete expression of Hoon.
26+
27+Use the following to bind `c` to a core. It begins with a **rune**, `|%`, which is used for creating a core. (A rune is just a pair of ASCII characters, and it usually indicates the beginning of a complex Hoon expression.) Take note of the expression spacing -- Hoon uses significant whitespace. Feel free to cut and paste the following expression into the dojo, starting with `=c`:
28+
29+```hoon
30+> =c |%
31+ ++ twenty 20
32+ ++ double-twenty (mul 2 twenty)
33+ --
34+```
35+
36+This core has two arms, `twenty` and `double-twenty`. Each arm definition begins with `++` followed by the name of that arm. After that is the Hoon expression associated with that arm. The first expression is the trivial `20` (guess what that does?), and the second is the slightly more interesting `(mul 2 twenty)`.
37+
38+You can run these arms using `twenty.c` and `double-twenty.c`:
39+
40+```
41+> twenty.c
42+20
43+
44+> double-twenty.c
45+40
46+```
47+
48+Notice that the second arm, `double-twenty`, makes use of the first arm, `twenty`. It's able to do so because each arm is evaluated with its parent core as the subject. Hence, each arm is able to use any other arm inside the parent core's battery.
49+
50+### `|%` Expressions
51+
52+Before moving on let's talk about what each part of the `|%` expression is for.
53+
54+The `|%` indicates the beginning of an expression that produces a core. The `++` rune is used to define each of the arms of the core's battery, and is followed by both an arm name and a Hoon expression. The `--` rune is used to indicate that there are no more arms to be defined, and indicates the end of the expression.
55+
56+The battery of the core to be produced is explicitly defined by the `|%` expression. The payload of the core to be produced is implicitly defined as the subject of the `|%` expression. Let's unbind `c` to keep the subject clean:
57+
58+```
59+> =c
60+```
61+
62+## Cores
63+
64+Let's go over what a core is a little more carefully and comprehensively. As stated before, a **core** is a cell of a **battery** and a **payload**.
65+
66+```
67+A core: [battery payload]
68+```
69+
70+### Battery
71+
72+A battery is a collection of arms. An arm is an encoded Hoon expression, to be used for running computations. Each arm has a name. Arm naming rules are the same kebab-case rules that faces have. When an arm is evaluated, it uses its parent core as the subject.
73+
74+That's all you really need to know about the battery. You can become a master Hoon programmer if you know what is stated above but otherwise think of the battery as a black box.
75+
76+If you'd really like to know, technically a battery is a tree of Nock formulas, one formula per each arm. Again, however, you don't need to understand the first thing about Nock to understand Hoon.
77+
78+### Payload
79+
80+The payload contains all the data needed for running the arms in the battery correctly. In principle, the payload of a core can have data arranged in any arbitrary configuration. In practice, the payload often has a predictable structure of its own.
81+
82+The payload may include other cores. Consequently, a core's payload can include other 'code' -- cores in the payload have their own battery arms.
83+
84+### Subject Organization for Arm Computation
85+
86+Why must an arm have its parent core as the subject, when it's computed? As stated previously, the payload of a core contains all the data needed for computing the arms of that core. Arms can only access data in the subject. By requiring that the parent core be the subject we guarantee that each arm has the appropriate data available to it. The tail of its subject contains the payload and thus all the values therein. The head of the subject is the battery, which allows for making reference to sibling arms of that same core.
87+
88+Let's look at an example in which the payload information is needed for correct arm evaluation.
89+
90+## Another Example Core
91+
92+First let's use the dojo to bind the face `a` to the value `12`, and the face `b` to the value `[22 24]`. These values will be used in the arms of the core we're going to make.
93+
94+```
95+> =a 12
96+
97+> =b [22 24]
98+```
99+
100+Now use the following multi-line expression to bind `c` to a core. As before, feel free to cut and paste the following expression into the dojo (starting at `=c`):
101+
102+```
103+> =c |%
104+ ++ two 2
105+ ++ inc (add 1 a)
106+ ++ double (mul 2 a)
107+ ++ sum (add -.b +.b)
108+ --
109+```
110+
111+Note: binding `c` to the core created by the `|%` expression will fail unless you have already bound `a` and `b` to the relevant values, as we did above. Our having already bound them is what lets us use them in the `|%` expression.
112+
113+The `|%` expression above creates a core with four arms. The first, named `two`, evaluates to the constant `2`. The second arm, `inc`, adds `1` to `a`. `double` returns double the value of `a`, and `sum` returns the sum of the two [atoms](/docs/glossary/atom/) in `b`. The computations defined by these arms are pretty simple (and in the case of `two`, trivial), but a good starting point for learning about cores.
114+
115+Let's run the arm names in the dojo:
116+
117+```
118+> two.c
119+2
120+
121+> inc.c
122+13
123+
124+> double.c
125+24
126+
127+> sum.c
128+46
129+```
130+
131+Ideally these wing expressions behave the way you expected!
132+
133+To reiterate a point made earlier: a wing resolution to a leg returns the value of that leg. A wing resolution to an arm returns the value produced by the arm computation.
134+
135+### Dissecting a Core
136+
137+Enter `c` in the dojo to look at this core as printed data:
138+
139+```
140+> c
141+< 4.cvq
142+ { {{a/@ud b/{@ud @ud}} our/@p now/@da eny/@uvJ}
143+ <19.anu 24.tmo 6.ipz 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
144+ }
145+>
146+```
147+
148+`c`, like all cores, is a cell of `[battery payload]`, and it's pretty-printed inside a set of angled brackets: `< >`. The battery of four arms is represented by the pretty-printer as `4.cvq`. The `4` represents the number of arms in the battery, and the `cvq` is a [hash](https://en.wikipedia.org/wiki/Hash_function) of the battery.
149+
150+The tail, i.e., the payload, might look suspiciously familiar. It looks an awful lot like the default dojo subject, which has `our`, `now`, and `eny` in the head, but it also has `a` and `b`, which we also bound in the dojo subject. That's exactly what the payload is. The tail is a copy of what the subject was for the `|%` expression. (It's pretty-printed in a slightly compressed way).
151+
152+(You'll notice that there are several other cores in the payload. For example, `19.anu` is a battery of `19` arms, `24.tmo` is a battery of `24` arms, etc.)
153+
154+This means, among other things, that we should be able to unbind `a` and `b` in the subject, but the arms of `c` should still work correctly:
155+
156+```
157+> =a
158+
159+> =b
160+
161+> a
162+-find.a
163+
164+> b
165+-find.b
166+
167+> double.c
168+24
169+
170+> sum.c
171+46
172+```
173+
174+This works because `a` and `b` were copied into the core payload when the core was initially created. Unbinding them in the dojo subject doesn't matter to the arms in `c`, which only look in `c`'s payload anyway.
175+
176+The payload stores all the data needed to compute the arms correctly. That also includes `add` and `mul`, which themselves are arms in a core of the Hoon standard library. This library core is available as part of the default dojo subject.
177+
178+## Wings that Resolve to Arms
179+
180+To reinforce your newfound understanding of arms and cores, let's go over the various ways that wings resolve to arms in cores. Remember that face resolution to a leg of the subject produces the leg value unchanged, but resolution to an arm produces the _computed_ value of that arm.
181+
182+### Address-Based Wings
183+
184+In the [previous lesson](/docs/hoon/hoon-school/the-subject-and-its-legs), you saw how the following expressions return legs based on an address in the subject: `+n`, `.`, `-`, `+`, `+>`, `+<`, `->`, `-<`, `&`, `|` etc. When these resolve to the part of the subject containing an arm, they **don't** evaluate the arm. They simply return the indicated noun fragment of the subject, as if it were a leg.
185+
186+Let's use `-.c` to look at the head of `c`, i.e., the battery of the core:
187+
188+```
189+> -.c
190+[ [1 2]
191+ [ [8 [9 702 0 2.047] 9 2 10 [6 [7 [0 3] 1 2] 0 56] 0 2]
192+ 8
193+ [9 20 0 2.047]
194+ 9
195+ 2
196+ 10
197+ [6 [7 [0 3] 1 1] 0 56]
198+ 0
199+ 2
200+ ]
201+ 8
202+ [9 20 0 2.047]
203+ 9
204+ 2
205+ 10
206+ [6 [0 114] 0 115]
207+ 0
208+ 2
209+]
210+```
211+
212+The result is a tree of uncomputed Nock formulas. But you virtually never need to see or use this raw data. Generally speaking, don't use address-based expressions to look at arms for any reason other than to satisfy your curiosity (and even then only if you've learned or plan to learn Nock). Use name-based expressions instead.
213+
214+### Name-based Wings
215+
216+To get the arm of a core to compute you must use its name. The arm names of `c` are in the expression used to create `c`:
217+
218+```
219+> =c |%
220+ ++ two 2
221+ ++ inc (add 1 a)
222+ ++ double (mul 2 a)
223+ ++ sum (add -.b +.b)
224+ --
225+```
226+
227+We evaluated the arms of `c` previously:
228+
229+```
230+> two.c
231+2
232+
233+> inc.c
234+13
235+
236+> double.c
237+24
238+
239+> sum.c
240+46
241+```
242+
243+You can also evaluate the arms of `c` using `:` instead:
244+
245+```
246+> two:c
247+2
248+
249+> inc:c
250+13
251+
252+> double:c
253+24
254+
255+> sum:c
256+46
257+```
258+
259+The difference between `two.c` and `two:c` is as follows. `two.c` is an instruction for finding `two` in `c` in the subject. `two:c` is an instruction for setting `c` as the subject, and then for finding `two`. In the examples above both versions amount to the same thing, and so return the same product. (There are other cases in which `two.c` and `two:c` _don't_ amount to the same thing. We'll address the difference in more detail later.)
260+
261+### Name Searches and Collisions
262+
263+It's possible to have 'name collisions' with faces and arm names. Nothing prevents one from using the name of some arm as a face too. For example:
264+
265+```
266+> double:c
267+24
268+
269+> double:[double=123 c]
270+123
271+```
272+
273+When `[double=123 c]` is the subject, the result is a cell of: (1) `double=123` and (2) the core `c`:
274+
275+```
276+> [double=123 c]
277+[ double=123
278+ < 4.cvq
279+ { {{a/@ud b/{@ud @ud}} our/@p now/@da eny/@uvJ}
280+ <19.anu 24.tmo 6.ipz 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
281+ }
282+ >
283+]
284+```
285+
286+Hoon doesn't know whether `double` is a face or an arm name until it conducts a search looking for name matches. If it finds a face first, the value of the face is returned. If it finds an arm first, the arm will be evaluated and the product returned. You may use `^` to indicate that you want to skip the first match, and multiple `^`s to indicate multiple skips:
287+
288+```
289+> double:[double=123 c]
290+123
291+
292+> ^double:[double=123 c]
293+24
294+
295+> ^double:[double=123 double=456 c]
296+456
297+
298+> ^^double:[double=123 double=456 c]
299+24
300+```
301+
302+### Modifying a Core's Payload
303+
304+We can produce a modified version of the core `c` in which `a` and `b` have different values. A core is just a noun in the subject, so we can modify it in the way we learned to modify legs in the last lesson. To change `a` to `99`, use `c(a 99)`:
305+
306+```
307+> c(a 99)
308+< 4.cvq
309+ { {{a/@ud b/{@ud @ud}} our/@p now/@da eny/@uvJ}
310+ <19.anu 24.tmo 6.ipz 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
311+ }
312+>
313+
314+> a.c
315+12
316+```
317+
318+The expression `c(a 99)` produces a core exactly like `c` except that the value of `a` in the payload is `99` instead of `12`. But when we evaluate `a.c` we still get the original value, `12`. Why? The value of `c` in the dojo is bound to the original core value, and will stay that way until we unbind `c` or bind it to something else. We can ask for a modified copy of `c` but that value doesn't automatically persist. It must be put into the subject if we're to find it there. So how do we know that `c(a 99)` successfully modified the value of `a`? We can check by setting the new version of the core as the subject and checking `a`:
319+
320+```
321+> a:c(a 99)
322+99
323+
324+> double:c(a 99)
325+198
326+```
327+
328+To make the modified core persist as `c`, we can rebind `c` to the new value:
329+
330+```
331+> =c c(a 99)
332+
333+> a:c
334+99
335+
336+> double:c
337+198
338+```
339+
340+We can make multiple changes to `c` at once:
341+
342+```
343+> =c c(a 123, b [44 55])
344+
345+> a:c
346+123
347+
348+> b:c
349+[44 55]
350+
351+> two:c
352+2
353+
354+> inc:c
355+124
356+
357+> double:c
358+246
359+
360+> sum:c
361+99
362+```
363+
364+### Arms on the Search Path
365+
366+A wing is a search path into the subject. We've looked at some examples of wings that resolve to arms; e.g., `double.c`, which resolves to `double` in `c` in the subject. In the latter example the arm `double` is the final limb in the resolution path. What if an arm name in a wing isn't the final limb? What if it's elsewhere in the wing path?
367+
368+Normally we might read a wing expression like `two.double.c` as '`two` in `double` in `c`'. Does that make sense when `double` is itself an arm? Try it:
369+
370+```
371+> two.double.c
372+2
373+```
374+
375+It produces the value of `two` in `c`. This is a fact in need of explanation.
376+
377+When arm names are included in the body of a wing, the resolution behavior is a little different from that of legs. Instead of indicating that the wing resolution should continue in the arm itself, an arm name indicates that the resolution should continue in the parent core of the arm.
378+
379+So the meaning of `two.double.c` is, roughly, '`two` in the parent core of `double` in `c`'. Of course, Hoon doesn't know that `double` is an arm until the search for it ends; but once the `double` arm is found, Hoon continues the resolution from _the parent core of_ `double`, not `double` itself. It turns out in this case that this is a redundant step. `c` is the parent core and was already in the wing path. We can illustrate redundancy more dramatically:
380+
381+```
382+> double.two.sum.two.double.inc.c
383+246
384+
385+> two.double.two.sum.two.double.inc.c
386+2
387+
388+> sum.two.double.two.sum.two.double.inc.c
389+99
390+```
391+
392+In each of the following examples, the only wings that matter are `c` and whichever arm name is left-most in the expression. The other arm names in the path simply resolve to their parent core, which is just `c`.
393+
394+### The `..arm` Syntax
395+
396+Let's say you have a wing that resolves to a leg of the subject. In this wing is an arm name, e.g., `a.b.arm`. As you learned in lesson 1.4, this should be read as '`a` in `b` in the parent core of `arm`'. Speaking more directly: the wing resolution path goes through the parent core of the arm, not the arm itself.
397+
398+Recall that using `.` by itself returns the whole subject. With that in mind, take a moment to answer the following question on your own. In general, what should the expression `..arm` produce?
399+
400+Do you have an answer? If not, consider going back and trying to figure it out before moving on.
401+
402+You may read `..arm` as '`.` of the parent core of `arm`'. This amounts to just the parent core of `arm`. Let's try this out with the arms of `c`:
403+
404+```
405+> ..inc:c
406+< 4.han
407+ { {our/@p now/@da eny/@uvJ}
408+ <19.anu 24.tmo 6.ipz 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
409+ }
410+>
411+
412+> c
413+< 4.han
414+ { {our/@p now/@da eny/@uvJ}
415+ <19.anu 24.tmo 6.ipz 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
416+ }
417+>
418+```
419+
420+Yes, they match. `..inc` of `c` is just the parent core of `inc`, `c` itself. But why would we ever use `..inc` to refer to `c`? It's much simpler to use `c`.
421+
422+Sometimes the `..arm` syntax is quite useful. Often there is a core in the subject without a face bound to it; i.e., the core might be nameless. In that case you can use an arm name in that core to refer to the whole core.
423+
424+For an example of this, consider the `add` arm of the Hoon standard library. This arm is in a nameless core. To see the parent core of `add`, try `..add`:
425+
426+```
427+> ..add
428+<74.dbd 1.qct $141>
429+```
430+
431+Here you see a core with a battery of 74 arms (!), and whose payload is another core with one arm.
432+
433+
434+### Evaluating an Arm Against a Modified Core
435+
436+Assume `this.is.a.wing` is a wing that resolves to an arm. You can use the `this.is.a.wing(face new-value)` syntax to compute the arm against a modified version of the parent core of `this.is.a.wing`.
437+
438+```
439+> double.c(a 55)
440+110
441+
442+> inc.c(a 55)
443+56
444+```
445+
446+This almost looks like a function call of sorts.
447+
448+
449+### Cores, Gates, and Traps
450+
451+Let's take a quick look at the battery of one core in the dojo to show that this is true by inputting one into the dojo.
452+
453+```
454+> =dec |%
455+ ++ dec
456+ |= a=@
457+ ?< =(0 a)
458+ =+ b=0
459+ |- ^- @
460+ ?: =(a +(b)) b
461+ $(b +(b))
462+ --
463+```
464+
465+This core has one arm `dec` which implements decrement. If we look at the head of the core we'll see the Nock.
466+
467+```
468+> -:dec
469+[ 8
470+ [1 0]
471+ [ 1
472+ 6
473+ [5 [1 0] 0 6]
474+ [0 0]
475+ 8
476+ [1 0]
477+ 8
478+ [1 6 [5 [0 30] 4 0 6] [0 6] 9 2 10 [6 4 0 6] 0 1]
479+ 9
480+ 2
481+ 0
482+ 1
483+ ]
484+ 0
485+ 1
486+]
487+```
488+
489+Again, being able to read Nock is not essential to understanding Hoon.
490+
491+### Cores and Contexts
492+
493+Let's take a quick look at how cores can be combined with `=>` to build up
494+larger structures. `=> p=hoon q=hoon` yields the product of `q` with the product of `p` taken as the subject.
495+
496+We can use this to set the context of cores. Recall that the payload of a gate
497+is a cell of `[sample context]`. For example:
498+```
499+~zod:dojo> =foo =>([1 2] |=(@ 15))
500+> +3:foo
501+[0 1 2]
502+```
503+Here we have created a gate with `[1 2]` as its context that takes in an `@` and
504+returns `15`. `+3:foo` shows the payload of the core to be `[0 [1 2]]`. Here `0`
505+is the default value of `@` and is the sample, while `[1 2]` is the context that
506+was given to `foo`.
507+
508+`=>` (and its reversed version `=<`) are used extensively to put cores into the
509+context of other cores.
510+```hoon
511+=>
512+|%
513+++ foo
514+ |= a=@
515+ (mul a 2)
516+--
517+|%
518+++ bar
519+ |= a=@
520+ (mul (foo a) 2)
521+--
522+```
523+At the level of arms, `+foo` is in the subject of `+bar`, and so `+bar` is able to call `+foo`. On the other hand, `+bar` is not in the subject of `+foo`, so `+foo` cannot call `+bar` - you will get a `-find.bar` error.
524+
525+At the level of cores, the `=>` sets the context of the core containing `+bar` to be the core
526+containing `+foo`. Recall that arms are evaluated with the parent core as the
527+subject. Thus `+bar` is evaluated with the core containing it as the subject,
528+which has the core containing `+foo` in its context. So this is why `+foo` is in
529+the scope of `+bar` but not vice versa.
530+
531+Let's look inside `hoon.hoon`, where the standard library is located, to see how this is being used.
532+
533+The first core listed here has just one arm.
534+```hoon
535+|%
536+++ hoon-version 141
537+--
538+```
539+This is reflected in the subject of `hoon-version`.
540+```
541+> ..hoon-version
542+<1.ane $141>
543+```
544+
545+After several lines that we'll ignore for pedagogical purposes, we see
546+```hoon
547+|%
548+:: # %math
549+:: unsigned arithmetic
550++| %math
551+++ add
552+ ~/ %add
553+ :: unsigned addition
554+ ::
555+ :: a: augend
556+ :: b: addend
557+ |= [a=@ b=@]
558+ :: sum
559+ ^- @
560+ ?: =(0 a) b
561+ $(a (dec a), b +(b))
562+::
563+++ dec
564+```
565+and so on, down to
566+```hoon
567+++ unit
568+ |$ [item]
569+ :: maybe
570+ ::
571+ :: mold generator: either `~` or `[~ u=a]` where `a` is the
572+ :: type that was passed in.
573+ ::
574+ $@(~ [~ u=item])
575+--
576+```
577+This core contains the arms in parts [1a-1c of the standard library documentation](/docs/hoon/reference/stdlib/1a). If you count them, there are 41 arms in the core from `++ add` down to `++ unit`. We again can see this fact reflected in the dojo by looking at the subject of `add`.
578+```
579+> ..add
580+<41.mac 1.ane $141>
581+```
582+Here we see that core containing `hoon-version` is in the subject of the
583+section one core.
584+
585+Next, [section two](/docs/hoon/reference/stdlib/2a) starts:
586+```
587+=>
588+:: ::
589+:::: 2: layer two ::
590+```
591+...
592+```
593+|%
594+:: ::
595+:::: 2a: unit logic ::
596+ :: ::
597+ :: biff, bind, bond, both, clap, drop, ::
598+ :: fall, flit, lift, mate, need, some ::
599+ ::
600+++ biff :: apply
601+ |* {a/(unit) b/$-(* (unit))}
602+ ?~ a ~
603+ (b u.a)
604+```
605+If you counted the arms in this core by hand, you'll come up with 126 arms. This is also reflected in the dojo:
606+```
607+> ..biff
608+<126.xjf 41.mac 1.ane $141>
609+```
610+and we also see the section 1 core and the core containing `hoon-version` in the subject.
611+
612+We can also confirm that `add` is in the subject of `biff`
613+```
614+> add:biff
615+<1.vwd {{a/@ b/@} <41.mac 1.ane $141>}>
616+```
617+and that `biff` is not in the subject of `add`.
618+```
619+> biff:add
620+-find.biff
621+```
622+
623+Lastly, let's check the subject of the last arm in `hoon.hoon` (as of November 2019)
624+```
625+> ..pi-tell
626+<92.nnn 247.tye 51.mvt 126.xjf 41.mac 1.ane $141>
627+```
628+This confirms for us, then, that `hoon.hoon` consists of six nested cores, with one
629+inside the payload of the next, with
630+the `hoon-version` core most deeply nested.
631+
632+#### Exercise 1.7a
633+Pick a couple of arms in `hoon.hoon` and check to make sure that they are only
634+referenced in its parent core or core(s) that have the parent core put in its
635+context via the `=>` or `=<` runes.
636+
637+## Casts
638+
639+Once again we remind you it's a good idea when writing your code to cast your data structures often. The Hoon type inferencer is quite naive and while it will often correctly understand what you mean, manually casting can be beneficial both for someone reading the code and for helping you debug problems.
640+
641+## Summary
642+
643+At this point you should have a pretty good understanding of what an arm is, and how wing resolution to an arm works. But so far the arms you've created have been fairly simple. In the next lesson you'll learn about Hoon functions, and how to create your own.
644+
645+You can now unbind `c` in the dojo -- this will help to keep your dojo subject tidy:
646+
647+```
648+> =c
649+
650+> c
651+-find.c
652+```
content/docs/hoon/hoon-school/atoms-auras-and-simple-cell-types.mdnew file+779
@@ -0,0 +1,779 @@
1++++
2+title = "2.1 Atoms, Auras, and Simple Cell Types"
3+weight = 24
4+template = "doc.html"
5+aliases = ["/docs/learn/hoon/hoon-tutorial/atoms-auras-and-simple-cell-types/"]
6++++
7+Like most modern high-level programming languages, Hoon has a type system. Because Hoon is a functional programming language, its type system differs somewhat from those of non-functional languages. In the next few lessons we'll go over Hoon's type system and point out some of its distinctive features. Certain advanced topics (e.g. type [polymorphism](https://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29)) won't be addressed until a later chapter.
8+
9+A type is ordinarily understood to be a set of values. Examples: the set of all [atoms](/docs/glossary/atom/) is a type, the set of all cells is a type, and so on.
10+
11+Type systems provide type safety, in part by making sure functions produce values of the correct type. When you write a function whose product is intended to be an atom, it would be nice to know that the function is guaranteed to produce an atom. Hoon's type system provides such guarantees with **type checking** and **type inference**.
12+
13+## Brief Overview of the Next Few Lessons
14+
15+In order to have a solid foundational knowledge of Hoon's type system, you must understand: (1) precisely what kind of information is tracked by Hoon's type system, (2) what a type check is and where they occur, (3) what type inference is and how it works, and (4) how to build your own custom types.
16+
17+In this lesson we'll cover (1)-(4) as they pertain to atoms and simple cell types. In the next lesson (2) and (3) will be addressed as they pertain to complex expressions of Hoon. In the lesson after that you'll learn more about (4), for building more complex types.
18+
19+## Atoms and Auras
20+
21+In [Lesson 1.2](/docs/hoon/hoon-school/nouns) we defined what an atom is: any unsigned integer. In this lesson we'll expand on that discussion, going over how Hoon's type system implements auras.
22+
23+In the most straightforward sense, atoms simply are unsigned integers. But they can also be interpreted as representing signed integers, ASCII symbols, floating-point values, dates, binary numbers, hexadecimal numbers, and more. Every atom is, in and of itself, just an unsigned integer; but Hoon keeps track of type information about each atom, and this info tells Hoon how to interpret the atom in question.
24+
25+The piece of type information that determines how Hoon interprets an atom is called an **aura**. The set of all atoms is indicated with the symbol `@`. An aura is indicated with `@` followed by some letters, e.g., `@ud` for unsigned decimal. Accordingly, the Hoon type system does more than track sets of values. It also tracks certain other relevant metadata about how those values are to be interpreted.
26+
27+How is aura information generated so that it can be tracked? One way involves **type inference**. In certain cases Hoon's type system can infer the type of an expression using syntactic clues. In the most straightforward case of type inference, the expression is simply data as a [literal](https://en.wikipedia.org/wiki/Literal_%28computer_programming%29). Hoon recognizes the aura literal syntax and infers that the data in question is an atom with the aura associated with that syntax.
28+
29+To see the inferred type of a literal expression in the dojo, use the `?` operator. (Note: this operator isn't part of the Hoon programming language; it's a dojo-only tool. It's a very useful tool for learning about types in Hoon, however.)
30+
31+The `?` dojo operator shows both the product and the inferred type of an expression. Let's try `?` on `15`:
32+
33+```
34+> 15
35+15
36+
37+> ? 15
38+ @ud
39+15
40+```
41+
42+The `@ud` is the inferred type of `15` (and of course `15` is the product). The `@` is for 'atom' and the `ud` is for 'unsigned decimal'. The letters after the `@` indicate the 'aura' of the atom.
43+
44+One important role played by the type system is to make sure that the output of an expression is of the intended data type. If the output is of the wrong type then the programmer did something wrong. But how does Hoon know what the intended data type is? The programmer must specify this explicitly by using a 'cast'. To cast for an unsigned decimal atom, you can use the `^-` rune along with the `@ud` from above.
45+
46+What exactly does the `^-` rune do? It compares the inferred type of some expression with the desired cast type. If the expression's inferred type 'nests' under the desired type, then the product of the expression is returned.
47+
48+Let's try one in the dojo. For the expression to be assessed we'll use `15` again:
49+
50+```
51+> ^-(@ud 15)
52+15
53+```
54+
55+Because `@ud` is the inferred type of `15`, the cast succeeds. Notice that the `^-` expression never does anything to modify the underlying [noun](/docs/glossary/noun/) of the second subexpression. It's used simply to mandate a type-check on that expression. This check occurs at compile-time (i.e., when the expression is compiled to Nock).
56+
57+What about when the inferred type doesn't fit under the cast type? You get a `nest-fail` crash at compile-time:
58+
59+```
60+> ^-(@ud [13 14])
61+nest-fail
62+[crash message]
63+```
64+
65+Why 'nest-fail'? The inferred type of `[13 14]` doesn't 'nest' under the cast type `@ud`. It's a cell, not an atom. But if we use the symbol for nouns, `*`, then the cast succeeds:
66+
67+```
68+> ^-(* [13 14])
69+[13 14]
70+```
71+
72+A cell of atoms is a noun, so the inferred type of `[13 14]` nests under `*`. Every product of a Hoon expression nests under `*` because every product is a noun.
73+
74+## What Auras are There?
75+
76+Hoon has a wide (but not extensible) variety of atom literal syntaxes. Each literal syntax indicates to the Hoon type checker which predefined aura is intended. Hoon can also pretty-print any aura literal it can parse. Because atoms make great path nodes and paths make great URLs, all regular atom literal syntaxes use only URL-safe characters.
77+
78+Here's a non-exhaustive list of auras, along with examples of corresponding literal syntax:
79+
80+```
81+Aura Meaning Example Literal Syntax
82+-------------------------------------------------------------------------
83+@d date
84+ @da absolute date ~2018.5.14..22.31.46..1435
85+ @dr relative date (ie, timespan) ~h5.m30.s12
86+@n nil ~
87+@p phonemic base (ship name) ~sorreg-namtyv
88+@r IEEE floating-point
89+ @rd double precision (64 bits) .~6.02214085774e23
90+ @rh half precision (16 bits) .~~3.14
91+ @rq quad precision (128 bits) .~~~6.02214085774e23
92+ @rs single precision (32 bits) .6.022141e23
93+@s signed integer, sign bit low
94+ @sb signed binary --0b11.1000
95+ @sd signed decimal --1.000.056
96+ @sv signed base32 -0v1df64.49beg
97+ @sw signed base64 --0wbnC.8haTg
98+ @sx signed hexadecimal -0x5f5.e138
99+@t UTF-8 text (cord) 'howdy'
100+ @ta ASCII text (knot) ~.howdy
101+ @tas ASCII text symbol (term) %howdy
102+@u unsigned integer
103+ @ub unsigned binary 0b11.1000
104+ @ud unsigned decimal 1.000.056
105+ @uv unsigned base32 0v1df64.49beg
106+ @uw unsigned base64 0wbnC.8haTg
107+ @ux unsigned hexadecimal 0x5f5.e138
108+```
109+
110+Some of these auras nest under others. For example, `@u` is for all unsigned auras. But there are other, more specific auras; `@ub` for unsigned binary numbers, `@ux` for unsigned hexadecimal numbers, etc.
111+
112+For a more complete list of auras, see [Auras](/docs/hoon/reference/auras).
113+
114+## Aura Inference in Hoon
115+
116+Let's do more examples in the Dojo using the `?` operator. We'll focus on just the unsigned auras for now:
117+
118+```
119+> 15
120+15
121+
122+> ? 15
123+ @ud
124+15
125+
126+> 0x15
127+0x15
128+
129+> ? 0x15
130+ @ux
131+0x15
132+```
133+
134+When you enter just `15`, the Hoon type checker infers from the syntax that its aura is `@ud` because you typed an unsigned integer in decimal notation. Hence, when you use `?` to check the aura, you get `@ud`.
135+
136+And when you enter `0x15` the type checker infers that its aura is `@ux`, because you used `0x` before the number to indicate the unsigned hexadecimal literal syntax. In both cases, Hoon pretty-prints the appropriate literal syntax by using inferred type information from the input expression; the Dojo isn't (just) echoing what you enter.
137+
138+More generally: for each atom expression in Hoon, you can use the literal syntax of an aura to force Hoon to interpret the atom as having that aura type. For example, when you type `~sorreg-namtyv` Hoon will interpret it as an atom with aura `@p` and treat it accordingly.
139+
140+Here's another example of type inference at work:
141+
142+```
143+> (add 15 15)
144+30
145+
146+> ? (add 15 15)
147+ @
148+30
149+
150+> (add 0x15 15)
151+36
152+
153+> ? (add 0x15 15)
154+ @
155+36
156+```
157+
158+The `add` function in the Hoon standard library operates on all atoms, regardless of aura, and returns atoms with no aura specified. Hoon isn't able to infer anything more specific than `@` for the product of `add`. This is by design, however. Notice that when you `add` a decimal and a hexadecimal above, the correct answer is returned (pretty-printed as a decimal). This works for all of the unsigned auras:
159+
160+```
161+> (add 100 0b101)
162+105
163+
164+> (add 100 0xf)
165+115
166+
167+> (add 0b1101 0x11)
168+30
169+```
170+
171+The reason these add up correctly is that unsigned auras all map directly to the 'correct' atom underneath. For example, `16`, `0b1.0000`, and `0x10` are all the exact same atom, just with different literal syntax. (This doesn't hold for signed versions of the auras!)
172+
173+## Auras as 'Soft' Types
174+
175+It's important to understand that Hoon's type system doesn't enforce auras as strictly as it does other types. Auras are 'soft' type information. To see how this works, we'll take you through the process of converting the aura of an atom to another aura.
176+
177+Hoon makes **some** effort to enforce that the correct aura is produced by an expression:
178+
179+```
180+> ^-(@ud 0x10)
181+nest-fail
182+
183+> ^-(@ud 0b10)
184+nest-fail
185+
186+> ^-(@ux 100)
187+nest-fail
188+```
189+
190+But there are ways around this. First, you can cast to a more general aura, as long as the current aura nests under the cast aura. E.g., `@ub` to `@u`, `@ux` to `@u`, `@u` to `@`, etc. By doing this you're essentially telling Hoon to throw away some aura information:
191+
192+```
193+> ^-(@u 0x10)
194+16
195+
196+> ? ^-(@u 0x10)
197+ @u
198+16
199+
200+> ^-(@u 0b10)
201+2
202+
203+> ? ^-(@u 0b10)
204+ @u
205+2
206+```
207+
208+In fact, you can cast any atom all the way to the most general case `@`:
209+
210+```
211+> ^-(@ 0x10)
212+16
213+
214+> ? ^-(@ 0x10)
215+ @
216+16
217+
218+> ^-(@ 0b10)
219+2
220+
221+> ? ^-(@ 0b10)
222+ @
223+2
224+```
225+
226+Anything of the general aura `@` can, in turn, be cast to more specific auras. We can show this by embedding a cast expression inside another cast:
227+
228+```
229+> ^-(@ud ^-(@ 0x10))
230+16
231+
232+> ^-(@ub ^-(@ 0x10))
233+0b1.0000
234+
235+> ^-(@ux ^-(@ 10))
236+0xa
237+```
238+
239+Hoon uses the outermost cast to infer the type:
240+
241+```
242+> ? ^-(@ub ^-(@ 0x10))
243+ @ub
244+0b1.0000
245+```
246+
247+As you can see, an atom with one aura can be converted to another aura. For a convenient shorthand, you can do this conversion with irregular cast syntax, e.g. `` `@ud` ``, rather than using the `^-` rune twice:
248+
249+```
250+> `@ud`0x10
251+16
252+
253+> `@ub`0x10
254+0b1.0000
255+
256+> `@ux`10
257+0xa
258+```
259+
260+This is what we mean when we call auras 'soft' types. The above examples show that the programmer can get around the type system for auras by casting up to `@` and then back down to the specific aura, say `@ub`; or by casting with `` `@ub` `` for short.
261+
262+## Examples
263+
264+So far you've only used the auras for unsigned integers. Let's try some others.
265+
266+### Signed integers
267+
268+```
269+> -7
270+-7
271+
272+> ? -7
273+ @sd
274+
275+> --7
276+--7
277+
278+> ? --7
279+ @sd
280+--7
281+```
282+
283+`--7` means "positive 7". `+7` might have been better but `+` is not URL-safe.
284+
285+Hoon needs `--` to distinguish positive signed numbers such as `--7` from the unsigned `7`. The latter is always understood by Hoon as an unsigned literal. If you want Hoon to infer that a literal is signed you must explicitly include the `--`.
286+
287+Whereas we could use the `add` function on different unsigned auras and still get the correct answer, this doesn't work for signed auras:
288+
289+```
290+> (add -7 --7)
291+27
292+```
293+
294+Why not? `add` is happy to operate on any atom, regardless of aura, but it's intended for auras whose literals map directly to numerically equivalent general atoms `@`. For example, the `@ud` `7`, the `@ub` `0b111`, and the `@ux` `0x7` all map to the same `@` `7`. Signed literals such as `--7` are different, because some underlying atoms are used for representing negative numbers. We can see how this works by forcibly converting `@sd` atoms to `@ud`:
295+
296+```
297+> `@ud`-1
298+1
299+
300+> `@ud`--1
301+2
302+
303+> `@ud`-7
304+13
305+
306+> `@ud`--7
307+14
308+```
309+
310+If you want to add signed atoms use the function `sum:si` instead of `add`:
311+
312+```
313+> (sum:si -7 --7)
314+--0
315+
316+> ? (sum:si -7 --7)
317+ @s
318+--0
319+
320+> (sum:si --7 --0b10)
321+--9
322+
323+> (sum:si --7 --0x10)
324+--23
325+```
326+
327+### Exercise 2.1a
328+
329+Does Hoon's `@s` aura make a distinction between positive and negative zero, e.g., `-0` and `--0`? Use what you've learned in this lesson so far to come up with a principled answer. (As always, exercise solutions are at the bottom of the lesson.)
330+
331+### Text and Symbols
332+
333+Atoms can also represent text. The `@t` aura is for UTF-8 text. We call `@t` strings 'cords' (to distinguish them from tapes, e.g., `"hello!"`):
334+
335+```
336+> ? 'Ürbit'
337+ @t
338+'Ürbit'
339+
340+> `@ud`'Ürbit'
341+127.995.972.066.499
342+
343+> `@ux`'Ürbit'
344+0x7469.6272.9cc3
345+
346+> `@ux`'Ürbitt'
347+0x74.7469.6272.9cc3
348+
349+> `@t`0x74
350+'t'
351+```
352+
353+As you can see by casting a cord to `@ux`, the first byte (here the `74` of `0x74`) represents the last character of the cord. The next byte is the next to last character, and so on.
354+
355+Hoon also has `@ta`, which is intended for ASCII text. In practice, the Hoon parser rejects `@ta` literals that aren't in so-called 'kebab case'. That is, lower-case letters, numerals, and hyphens. Each `@ta` atom is called a 'knot'.
356+
357+```
358+> ? ~.urbit
359+ @ta
360+~.urbit
361+
362+> `@ux`~.this-is-kebab-case-123
363+0x3332.312d.6573.6163.2d62.6162.656b.2d73.692d.7369.6874
364+```
365+
366+You can get around Hoon's parser restrictions for `@ta` atoms by casting to `@ta` from a cord:
367+
368+```
369+> `@ta`'The quick brown fox jumped over the lazy dog.'
370+~.The quick brown fox jumped over the lazy dog.
371+```
372+
373+The Hoon **parser** prevents you from typing the literal `~.The quick brown fox jumped over the lazy dog.` into the dojo. Try it!
374+
375+The `@tas` aura is intended for 'symbols', i.e., kebab case strings following a `%`:
376+
377+```
378+> %hello
379+%hello
380+
381+> ^-(@tas %hello)
382+%hello
383+
384+> ^-(@ %hello)
385+478.560.413.032
386+
387+> ^-(@ 'hello')
388+478.560.413.032
389+```
390+
391+### Dates
392+
393+You can think of `now` as being a dojo environment variable that tells you what time it is:
394+
395+```
396+> now
397+~2018.5.16..23.42.06..5da3
398+
399+> ? now
400+ @da
401+~2018.5.16..23.42.08..3455
402+```
403+
404+The `@da` aura is for 'absolute dates' represented with 128-bit atoms; 64 bits for the year, month, day, hour, minute, and second, 64 bits for fractions of a second. There is also `@dr` for relative date:
405+
406+```
407+> ~h6
408+~h6
409+
410+> ? ~h6
411+ @dr
412+~h6
413+
414+> ~h6.m32.s11
415+~h6.m32.s11
416+
417+> `@ux`~h6
418+ @ux
419+0x5460.0000.0000.0000.0000
420+```
421+
422+The literal `~h6.m32.s11` is for 6 hours, 32 minutes, and 11 seconds. You can add `@dr` atoms together, or add a `@dr` atom to a `@da` atom. Remember that the `add` function produces atoms with no aura, so you'll have to cast the the aura you want the dojo to pretty-print to:
423+
424+```
425+> (add ~h2 ~h3)
426+332.041.393.326.771.929.088.000
427+
428+> `@dr`(add ~h2 ~h3)
429+~h5
430+
431+> `@dr`(add ~d1.m33 ~h7.m15.s12)
432+~d1.h7.m48.s12
433+
434+> now
435+~2018.5.17..00.15.06..a0d0
436+
437+> `@da`(add ~d1 now)
438+~2018.5.18..00.15.31..2df6
439+```
440+
441+### Floats
442+
443+Here are the float auras from the aura chart above:
444+
445+```
446+Aura Meaning Example Literal
447+-------------------------------------------------------------------------
448+@r IEEE floating-point
449+ @rd double precision (64 bits) .~6.02214085774e23
450+ @rh half precision (16 bits) .~~3.14
451+ @rq quad precision (128 bits) .~~~6.02214085774e23
452+ @rs single precision (32 bits) .6.022141e23
453+```
454+
455+One thing needs to be pointed out for float auras. Atoms are fundamentally integers, and only when interpreted differently can they be understood as floats. Floats obviously can't all map to numerically equivalent atoms:
456+
457+```
458+> .6.022
459+.6.022
460+
461+> ? .6.022
462+ @rs
463+.6.022
464+
465+> `@`.6.022
466+1.086.370.873
467+```
468+
469+As a result, the standard mathematical functions for atoms won't work correctly for floats:
470+
471+```
472+> (add .6.022 .1.000)
473+2.151.724.089
474+
475+> `@rs`(add .6.022 .1.000)
476+.-5.942123e-39
477+```
478+
479+Instead, you'll have to call the variant function for that type of float: `add:rs` for adding `@rs` floats, `add:rd` for `@rd` floats, `add:rq` for `@rq` floats, and `add:rh` for `@rh` floats.
480+
481+```
482+> (add:rs .6.022 .1.000)
483+.7.022
484+
485+> (add:rd .~6.022 .~1.000)
486+.~7.022
487+```
488+
489+## Custom Auras
490+
491+Programmers can use their own auras if desired, keeping in mind however that Hoon won't support custom aura literals or pretty-printing. The set of literals Hoon knows how to parse and/or print is fixed. But there are plenty of good reasons to use your own user-defined auras.
492+
493+If your program uses both fortnights and furlongs, Hoon will not parse a user-defined fortnight syntax. It will not print furlongs in the dojo. But the type system can prevent you from accidentally passing a furlong to a function that expects a fortnight.
494+
495+Remember also that auras specialize to the right. For example, `@u` atoms are interpreted as unsigned integers; `@ux` atoms are interpreted as unsigned **hexadecimal** integers.
496+
497+```
498+> `@madeupaura`123
499+0x7b
500+
501+> ^-(@abc `@abc`123)
502+0x7b
503+
504+> ^-(@ab `@abc`123)
505+0x7b
506+
507+> ^-(@abcd `@abc`123)
508+0x7b
509+
510+> ^-(@abd `@abc`123)
511+nest-fail
512+```
513+
514+## General and Constant Atoms
515+
516+There's more to the type information of an atom than its aura. Another distinction is necessary. Some atoms are **general** in type, meaning that the type in question includes all atoms. For example, the type of the literal `17` is `@ud`; every atom can be of that type. Up to this point of this lesson every atom has been general.
517+
518+There are also atoms that are **constant** in type. Constant atom types contain just one atom. But that's not all. Constant atom types contain just one atom **with just one aura**.
519+
520+For atomic constant literal syntax simply put `%` in front of the atom literal:
521+
522+```
523+> ? 15
524+ @ud
525+15
526+
527+> ? %15
528+ $15
529+%15
530+
531+> ? %~h6
532+ $~h6
533+%~h6
534+
535+> ? %hello
536+ $hello
537+%hello
538+```
539+
540+The `$` on the type indicates the constant. You can use the same literal syntax to cast:
541+
542+```
543+> ^-(%15 %15)
544+%15
545+```
546+
547+Keep in mind that, underneath, `15` and `%15` are the same atom:
548+
549+```
550+> ^-(@ 15)
551+15
552+
553+> ^-(@ %15)
554+15
555+```
556+
557+But because they have different auras, `15` doesn't nest under the type for `%15`:
558+
559+```
560+> ^-(%15 15)
561+nest-fail
562+```
563+
564+When you cast using a constant as your type, you're asking for something very specific: one particular atom with one particular aura. If both conditions aren't met, the result of the cast will be a `nest-fail`.
565+
566+```
567+> `@`%0xf
568+15
569+
570+> `@`%15
571+15
572+
573+> ^-(%15 %0xf)
574+nest-fail
575+
576+> ^-(%0xf %15)
577+nest-fail
578+
579+> ^-(%0xf %0xf)
580+%0xf
581+```
582+
583+## Common irregulars
584+
585+There are a few special forms worth learning early. Null `@n`, a special constant type for `0`:
586+
587+```
588+> ~
589+~
590+
591+> `@`~
592+0
593+
594+> ^-(@n ~)
595+~
596+```
597+
598+Flag `?`, which is for boolean values:
599+
600+```
601+> |
602+%.n
603+
604+> &
605+%.y
606+
607+> ^-(? |)
608+%.n
609+
610+> ^-(? &)
611+%.y
612+```
613+
614+And ship names use `@p`:
615+
616+```
617+> ~zod
618+~zod
619+
620+> ~sorreg-namtyv
621+~sorreg-namtyv
622+
623+> `@`~zod
624+0
625+
626+> `@`~taglux-nidsep
627+6.095.360
628+
629+> ^-(@p ~taglux-nidsep)
630+~taglux-nidsep
631+```
632+
633+## Simple Cell Types
634+
635+Let's move on to cells. For now we'll limit ourselves to simple cell types made up of various atom types.
636+
637+## Generic Cells
638+
639+The `^` symbol is used to indicate the type for cells (i.e., the set of all cells). We can use it for casting as we did with, e.g., `@ux` and `@t`:
640+
641+```
642+> ^-(^ [12 13])
643+[12 13]
644+
645+> ^-(^ [[12 13] 14])
646+[[12 13] 14]
647+
648+> ^-(^ [[12 13] [14 15 16]])
649+[[12 13] [14 15 16]]
650+
651+> ^-(^ 123)
652+nest-fail
653+
654+> ^-(^ 0x10)
655+nest-fail
656+```
657+
658+If the expression to be evaluated produces a cell, the cast succeeds; if the expression evaluates produces an atom, the cast fails with a `nest-fail` crash.
659+
660+The downside of using `^` for casts is that Hoon will infer only that the product of the expression is a cell; it won't be known what _kind_ of cell is produced.
661+
662+```
663+> ? ^-(^ [12 13])
664+ {* *}
665+[12 13]
666+
667+> ? ^-(^ [[12 13] 14])
668+ {* *}
669+[[12 13] 14]
670+
671+> ? ^-(^ [[12 13] [14 15 16]])
672+ {* *}
673+[[12 13] [14 15 16]]
674+```
675+
676+When we use the `?` operator to see the type inferred by Hoon for the expression, in all three of the above cases the same thing is returned: `{* *}`. The `*` symbol indicates the type for any noun, and the curly braces `{ }` indicate a cell. Every cell in Hoon is a cell of nouns; remember that cells are defined as pairs of nouns.
677+
678+Yet the cell `[[12 13] [14 15 16]]` is a bit more complex than the cell `[12 13]`. Can we use the type system to distinguish them? Yes.
679+
680+## Getting More Specific
681+
682+What if you want to cast for a particular kind of cell? You can use square brackets when casting for a specific cell type. For example, if you want to cast for a cell in which the head and the tail must each be an atom, then simply cast using `[@ @]`:
683+
684+```
685+> ^-([@ @] [12 13])
686+[12 13]
687+
688+> ? ^-([@ @] [12 13])
689+ {@ @}
690+[12 13]
691+
692+> ^-([@ @] 12)
693+nest-fail
694+
695+> ^-([@ @] [[12 13] 14])
696+nest-fail
697+```
698+
699+The `[@ @]` cast accepts any expression that evaluates to a cell with exactly two atoms, and crashes with a `nest-fail` for any expression that evaluates to something different. The expression `12` doesn't evaluate to a cell; and while the expression `[[12 13] 14]` **does** evaluate to a cell, the left-hand side isn't an atom, but is instead another cell.
700+
701+You can get even more specific about the kind of cell you want by using atom auras:
702+
703+```
704+> ^-([@ud @ux] [12 0x10])
705+[12 0x10]
706+
707+> ^-([@ub @ux] [0b11 0x10])
708+[0b11 0x10]
709+
710+> ? ^-([@ub @ux] [0b11 0x10])
711+ {@ub @ux}
712+[0b11 0x10]
713+
714+> ^-([@ub @ux] [12 13])
715+nest-fail
716+```
717+
718+You are also free to embed more square brackets `[ ]` to indicate cells within cells:
719+
720+```
721+> ^-([[@ud @sb] @ux] [[12 --0b1101] 0xdead.beef])
722+[[12 --0b1101] 0xdead.beef]
723+
724+> ? ^-([[@ud @sb] @ux] [[12 --0b1101] 0xdead.beef])
725+ {{@ud @sb} @ux}
726+[[12 --0b1101] 0xdead.beef]
727+
728+> ^-([[@ @] @] [12 13])
729+nest-fail
730+```
731+
732+You can also be highly specific with certain parts of the type structure, leaving other parts more general. Keep in mind that when you do this, Hoon's type system will infer a general type from the general part of the cast. Type information may be thrown away:
733+
734+```
735+> ^-([^ @ux] [[12 --0b1101] 0xdead.beef])
736+[[12 26] 0xdead.beef]
737+
738+> ? ^-([^ @ux] [[12 --0b1101] 0xdead.beef])
739+ {{* *} @ux}
740+[[12 26] 0xdead.beef]
741+
742+> ^-(* [[12 --0b1101] 0xdead.beef])
743+[[12 26] 3.735.928.559]
744+
745+> ? ^-(* [[12 --0b1101] 0xdead.beef])
746+ *
747+[[12 26] 3.735.928.559]
748+```
749+
750+Because every piece of Hoon data is a noun, everything nests under `*`. When you cast to `*` you can see the raw noun with cells as brackets and atoms as unsigned integers.
751+
752+That's it for this lesson. Move on to the next one to learn more about when a type check occurs, and how type inference works for non-literal Hoon expressions.
753+
754+## Exercise Answer
755+
756+### 2.1a
757+
758+There is no distinction between positive and negative zero for `@s`. To see this, let's cast each of `--0` and `-0` to `@s`:
759+
760+```
761+> ^-(@s --0)
762+--0
763+
764+> ^-(@s -0)
765+--0
766+```
767+
768+Hoon pretty-prints them the same way, but can we be sure that they are the same thing? Let's check the atom underneath:
769+
770+```
771+> `@`--0
772+0
773+
774+> `@`-0
775+0
776+```
777+
778+They are indeed the same.
779+
content/docs/hoon/hoon-school/bank-account.mdnew file+80
@@ -0,0 +1,80 @@
1++++
2+title = "1.8.1 Bank Account"
3+weight = 17
4+template = "doc.html"
5+aliases = ["/docs/learn/hoon/hoon-tutorial/bank-account/"]
6++++
7+
8+In this lesson, we will write a [door](/docs/glossary/door/) that can act as a bank account with the ability to withdraw, deposit, and check the account's balance.
9+
10+```hoon
11+:- %say
12+|= *
13+:- %noun
14+=< =~ new-account
15+ (deposit 100)
16+ (deposit 100)
17+ (withdraw 50)
18+ balance
19+ ==
20+|%
21+++ new-account
22+ |_ balance=@ud
23+ ++ deposit
24+ |= amount=@ud
25+ +>.$(balance (add balance amount))
26+ ++ withdraw
27+ |= amount=@ud
28+ +>.$(balance (sub balance amount))
29+ --
30+--
31+```
32+
33+We start with the three lines we have in every `%say` generator:
34+
35+```hoon
36+:- %say
37+|= *
38+:- %noun
39+```
40+
41+In the above code chunk, we're creating a cell. The head of this cell is `%say`. The tail is a [gate](/docs/glossary/gate/) (`|= *`) that produces another cell (`:- %noun`) with a head of the mark of a the kind of data we are going to produce, a [noun](/docs/glossary/noun/); the tail of the second cell is the rest of the program.
42+
43+```hoon
44+=< =~ new-account
45+ (deposit 100)
46+ (deposit 100)
47+ (withdraw 50)
48+ balance
49+ ==
50+```
51+
52+In this code above, we're going to compose two runes using `=<`, which has inverted arguments. We use this rune to keep the heaviest twig to the bottom of the code.
53+
54+`=~` is a rune that composes multiple expressions. We take `new-account` and use that as the subject for the call to `deposit`. `deposit` and `withdraw` both produce a new version of the door that's used in subsequent calls, which is why we are able to chain them in this fashion. The final reference is to `balance`, which is the account balance contained in the [core](/docs/glossary/core/) that we examine below.
55+
56+```hoon
57+|%
58+++ new-account
59+ |_ balance=@ud
60+ ++ deposit
61+ |= amount=@ud
62+ +>.$(balance (add balance amount))
63+ ++ withdraw
64+ |= amount=@ud
65+ +>.$(balance (sub balance amount))
66+ --
67+--
68+```
69+
70+We've chosen here to wrap our door in its own core to emulate the style of programming that is used when creating libraries. `new-account` is the name of our door. Recall that a door is a core with one or more [arms](/docs/glossary/arm/) that has a sample. Here, our door has a sample of one `@ud` with the face `balance` and two arms `deposit` and `withdraw`.
71+
72+Each of these arms produces a gate which takes an `@ud` argument. Each of these gates has a similar bit of code inside:
73+
74+```hoon
75++>.$(balance (add balance amount))
76+```
77+
78+`+>` is [wing syntax](/docs/hoon/reference/limbs/wing). This particular wing construction looks for the tail of the tail (the third element) in `$`, the subject of the gate we are in. The `withdraw` and `deposit` arms create gates with the entire `new-account` door as the context in their cores' `[battery sample context]`, in the "tail of the tail" slot. We change `balance` to be the result of adding `balance` and `amount` and produce the door as the result. `withdraw` functions the same way only doing subtraction instead of addition.
79+
80+It's important to notice that the sample, `balance`, is stored as part of the door rather than existing outside of it.
content/docs/hoon/hoon-school/behn.mdnew file+110
@@ -0,0 +1,110 @@
1++++
2+title = "2.6 Behn"
3+weight = 34
4+template = "doc.html"
5++++
6+
7+In this lesson we introduce the notion of a vane, which should be thought of as a kernel module for Arvo (if you don't know what that means yet, just keep reading). We first present a primer on what vanes are and how they communicate, followed by an examination of the simplest vane, known as Behn (pronounced like "bane"), which is Arvo's timekeeper.
8+
9+Following this lesson, we will introduce Gall, a vane used to build user space apps. Then we have a walkthrough where we construct an [egg timer](/docs/hoon/hoon-school/egg-timer) as a Gall app that interacts with Behn.
10+
11+## Vanes
12+
13+In order to introduce vanes, we must first introduce the concept of a [kernel](https://en.wikipedia.org/wiki/Kernel_(operating_system)). The kernel is in some sense the "core" of an operating system, in that it has complete control over all events in the system and may perform any operation. It is the first part of the operating system to boot, and is responsible for spawning all other processes and routing their communication to one another. The tasks a kernel performs are very low level - managing memory, prioritizing processes, keeping track of time, managing hardware I/O, etc.
14+
15+Kernel code is generally kept to be as minimal as possible, and so almost anything non-trivial is put into an extension called a kernel module. **Vanes** are kernel modules for Arvo. Arvo currently has eight vanes known as Ames, Behn, Clay, Dill, Eyre, Ford, Gall, and Hall. You can read a short description of each one in [Arvo](/docs/arvo/), along with a more thorough explanation of how vanes communicate than the following.
16+
17+Vanes communicate with one another by exchanging chunks of data known as
18+`move`s. We will get into more detail above what a `move` is in our example of
19+Behn below, (and also see [move traces](/docs/arvo/tutorials/move-trace)) but at a high level one should think of a `move` as either a request from one vane to another or a response to a request. In our egg timer app, Gall and Behn will be exchanging `move`s.
20+
21+Notably, vanes are _not_ something that a user ever interacts with directly. They live in an area of the memory called "kernel space", while all user processes live in [user space](https://en.wikipedia.org/wiki/User_space). Applications in user space make _system calls_ to the kernel, which the kernel may or may not obey (for security and stability purposes). These requests could be things such as asking for the time, getting the input of a hardware device, making an http request, or moving a file. In our egg timer app, we will be making system calls to ask Behn to handle the timer aspect.
22+
23+## Behn
24+
25+In this section we introduce the simplest Arvo vane, Behn. This is not exhaustive, but just enough to know what is going on inside of Behn when we make a system call to it in the egg timer app. We discuss relevant types, some [arms](/docs/glossary/arm/) that are only called internally, and arms that may be called by another vane via a `move`.
26+
27+Behn is an Arvo vane that acts as a simple timer. It allows vanes and applications to set timer events, which are managed in a simple priority queue.
28+
29+An app or vane can make a request to Behn to be informed when a specified amount of time has elapsed. Behn then produces effects to begin a unix timer for that request. The unix timer informs Behn after the specified time has elapses, which then informs the requestee. There is no guarantee that the requestee will be informed of the elapsed timer at the precise moment it requested, or even that it will be close. The only guarantee is that the requester will be informed at some point after the allotted time has passed.
30+
31+### Types
32+
33+We review here some of the commonly used types in the Behn vane as found in `behn.hoon`.
34+
35+#### `timer`
36+```
37++$ timer [date=@da =duct]
38+```
39+A `timer` consists of a `@da` (an absolute date at which the timer will go off) and a `duct` (representing the causal stack that began the timer). As part of its state, `Behn` keeps track of a list of `timer`s:
40+#### `behn-state`
41+```hoon
42++$ behn-state
43+ $: timers=(list timer)
44+ unix-duct=duct
45+ next-wake=(unit @da)
46+ drips=drip-manager
47+ ==
48+```
49+We see that a `behn-state` is a list of all `timers` that `Behn` is currently keeping track of. `unix-duct` is Behn's link to the unix timer. `next-wake` is the next time that `Behn` is supposed to inform a requestee that the specified timer has elapsed. We will ignore `drips` for the purpose of this tutorial.
50+
51+#### `move`
52+
53+Arvo vanes communicate via `moves`:
54+```hoon
55++$ move [p=duct q=(wind note gift:able)]
56+```
57+A `duct` is a call stack, which is a list of `path`s that represent a step in a causal chain of events. A `wind` is a kernel action. See the following arm from `arvo.hoon`:
58+
59+```hoon
60+++ wind :: new kernel action
61+ |* [a=mold b=mold] :: forward+reverse
62+ $% [%pass p=path q=a] :: advance
63+ [%slip p=a] :: lateral
64+ [%give p=b] :: retreat
65+ ==
66+```
67+Here we see that `wind` produces a wet gate that takes in two molds, which for the `move` type for Behn are `note`s and `gift`s. When a vane needs to request something of another vane, it `%pass`es a `note`. When a vane produces a result that was requested, it `%gives` a `gift` to the callee.
68+
69+
70+### Internal arms
71+
72+The following arms are part of the `event-core` of Behn, which are essentially the internal functions of the Behn vane that are not directly accessible to other vanes and applications. We will not review all of them here, we only list some of most important ones.
73+
74+#### ++set-unix-wake
75+This arm is what Behn uses to tell the unix timer when to `%wake` Behn.
76+
77+#### ++set-timer
78+This arm is a dry gate that takes in a `timer` and adds it to the list of `timer`s in the `state`. ``++set-timer`` automatically places the new `timer` in chronological order, so that the timer at the front of the list of `timer`s is the `timer` that will expire the soonest.
79+
80+#### ++wait
81+```hoon
82+++ wait |=(date=@da set-unix-wake(timers.state (set-timer [date duct])))
83+```
84+This arm is called when Behn is `%pass`ed a `note` telling Behn to `%wait`. This adds a `timer` to the list of `timer`s in the `state` and correspondingly tells the unix timer to tell Behn when the specified time has passed.
85+
86+#### ++rest
87+```hoon
88+++ rest |=(date=@da set-unix-wake(timers.state (unset-timer [date duct])))
89+```
90+This undoes a `++wait` operation. That is, `++rest` removes a timer from the list of `timer`s.
91+
92+#### ++wake
93+This arm is ultimately called by the unix timer to let Behn know that a previously specified amount of time has elapsed.
94+
95+#### ++born
96+
97+```hoon
98+++ born set-unix-wake(next-wake.state ~, unix-duct.state duct)
99+```
100+This arm is called when Behn is first launched. It gives Behn a `duct` to the unix timer and initializes the `behn-state` with the face `state` with a null list of `timer`s.
101+
102+### External interface
103+
104+Arvo talks to Behn via four arms, `++call`, `++load`, `++scry`, `++stay`, and ``++take``, which ultimately call arms in the `event-core` of which we have listed a subset above. Here we will only look at `++call` and `++take`.
105+
106+#### ++call
107+When Behn is `%pass`ed a `note` from another vane, that is enacted upon by Arvo via the `++call` gate. The `note` specifies what action to take, which are references to the internal arms. This is done by including in the `note` a symbol such as `%born`, `%rest`, `%wait`, or `%wake`, which ultimately call the arms with those names in the `event-core`.
108+
109+#### ++take
110+When Behn is ready to inform another vane or application that a timer has elapsed, Arvo activates the `++take` gate. That is, Arvo `take`s a `gift` from Behn that includes the symbol `%wake`, and `%pass`es it to the the requestee. `%wake` is the only kind of `gift` that Behn can make, but other vanes may possess multiple responses.
content/docs/hoon/hoon-school/caesar.mdnew file+394
@@ -0,0 +1,394 @@
1++++
2+title = "1.7.1 Walkthrough: Caesar Cipher"
3+weight = 16
4+template = "doc.html"
5+aliases = ["/docs/learn/hoon/hoon-tutorial/caesar/"]
6++++
7+
8+A Caesar cipher is a very simple way to obfuscate a message. The technique
9+takes a string and swaps out each component letter with another letter that is
10+a specified number of positions up or down in the alphabet. For example, with a
11+"right-shift" of 1, `a` would become `b`, `j` would become `k`, and `z` would
12+wrap around back to `a`.
13+
14+Consider the message below, and the cipher that results when we Caesar-shift the
15+message to the right by 1.
16+
17+```
18+Plaintext message: "do not give way to anger"
19+Right-shifted cipher: "ep opu hjwf xbz up bohfs"
20+```
21+
22+Note that the Caesar cipher is completely unsuitable for actually securing
23+information. Implementing it in a program is just a fun exercise.
24+
25+## A Caesar Cipher In Hoon
26+
27+Below is a generator that performs a Caesar cipher on a tape. This example
28+isn't the most compact implementation of such a cipher in Hoon, but it
29+demonstrates important principles that more laconic code would not. Save it as
30+`caesar.hoon` in your `/gen` directory.
31+
32+```hoon
33+!:
34+|= [msg=tape steps=@ud]
35+=<
36+=. msg (cass msg)
37+:- (shift msg steps)
38+(unshift msg steps)
39+
40+|%
41+++ alpha "abcdefghijklmnopqrstuvwxyz"
42+++ shift
43+ |= [message=tape shift-steps=@ud]
44+ ^- tape
45+ (operate message (encoder shift-steps))
46+++ unshift
47+ |= [message=tape shift-steps=@ud]
48+ ^- tape
49+ (operate message (decoder shift-steps))
50+++ encoder
51+ |= [steps=@ud]
52+ ^- (map @t @t)
53+ =/ value-tape=tape (rotation alpha steps)
54+ (space-adder alpha value-tape)
55+++ decoder
56+ |= [steps=@ud]
57+ ^- (map @t @t)
58+ =/ value-tape=tape (rotation alpha steps)
59+ (space-adder value-tape alpha)
60+++ operate
61+ |= [message=tape shift-map=(map @t @t)]
62+ ^- tape
63+ %+ turn message
64+ |= a=@t
65+ (~(got by shift-map) a)
66+++ space-adder
67+ |= [key-position=tape value-result=tape]
68+ ^- (map @t @t)
69+ (~(put by (map-maker key-position value-result)) ' ' ' ')
70+++ map-maker
71+ |= [key-position=tape value-result=tape]
72+ ^- (map @t @t)
73+ =| chart=(map @t @t)
74+ ?. =((lent key-position) (lent value-result))
75+ ~| %uneven-lengths !!
76+ |-
77+ ?: |(?=(~ key-position) ?=(~ value-result))
78+ chart
79+ $(chart (~(put by chart) i.key-position i.value-result), key-position t.key-position, value-result t.value-result)
80+++ rotation
81+ |= [my-alphabet=tape my-steps=@ud]
82+ =/ length=@ud (lent my-alphabet)
83+ =+ (trim (mod my-steps length) my-alphabet)
84+ (weld q p)
85+--
86+```
87+
88+This generator takes two arguments: a `tape`, which is your plaintext message,
89+and an unsigned integer, which is the shift-value of the cipher. It produces
90+a cell of two `tapes`: one that has been shifted right by the value, and another
91+that has been shifted left. It also converts any uppercase input into lowercase.
92+
93+Try it out in the Dojo:
94+
95+```
96+> +caesar ["abcdef" 1]
97+["bcdefg" "zabcde"]
98+
99+> +caesar ["test" 2]
100+["vguv" "rcqr"]
101+
102+> +caesar ["test" 26]
103+["test" "test"]
104+
105+> +caesar ["test" 28]
106+["vguv" "rcqr"]
107+
108+> +caesar ["test" 104]
109+["test" "test"]
110+
111+> +caesar ["tESt" 2]
112+["vguv" "rcqr"]
113+
114+> +caesar ["test!" 2]
115+nest-fail
116+```
117+
118+### Examining Our Code
119+
120+Let's examine our `caesar.hoon` code piece by piece. We won't necessarily go
121+in written order; instead, we'll cover code in the intuitive order of the
122+program. For each chunk that we cover, try to read and understand the code
123+itself before reading the explanation.
124+
125+```hoon
126+!:
127+|= [msg=tape steps=@ud]
128+=<
129+```
130+
131+The `!:` in the first line of the above code enables a full stack trace in the
132+event of an error.
133+
134+`|= [msg=tape steps=@ud]` creates a [gate](/docs/glossary/gate/) that takes a cell. The head of this cell
135+is a `tape`, which is a string type that's a list of `cord`s. Tapes are represented
136+as text surrounded by double-quotes, such as this: `"a tape"`. We give this input
137+tape the face `msg`. The tail of our cell is a `@ud` -- an unsigned decimal [atom](/docs/glossary/atom/)
138+-- that we give the face `steps`.
139+
140+`=<` is the rune that evaluates its first child expression with respect to its
141+second child expression as the subject. In this case, we evaluate the
142+expressions in the code chunk below against the [core](/docs/glossary/core/) declared later, which
143+allows us reference the core's contained [arms](/docs/glossary/arm/) before they are defined. Without
144+`=<`, we would need to put the code chunk below at the bottom of our program. In Hoon, as previously
145+stated, we always want to keep the longer code towards the bottom of our programs - `=<` helps us do that.
146+
147+```hoon
148+=. msg (cass msg)
149+:- (shift msg steps)
150+(unshift msg steps)
151+```
152+
153+`=. msg (cass msg)` changes the input string `msg` to lowercases. `=.` changes
154+the leg of the subject to something else. In our case, the leg to be changed is
155+`msg`, and the thing to replace it is `(cass msg)`. `cass` is a standard-library
156+gate that converts uppercase letters to lowercase.
157+
158+`:- (shift msg steps)` and `(unshift msg steps)` simply composes a
159+cell of a right-shifted cipher and a left-shifted cipher of our original message.
160+We will see how this is done using the core described below, but this is the final
161+output of our generator.
162+
163+`|%` creates a `core`, the second child of `=<`. Everything after `|%` is part of that
164+second child `core`, and will be used as the subject of the first child of `=<`, described
165+above. The various parts, or `arm`s, of the `core` are denoted by `++` beneath it, for
166+instance:
167+
168+```hoon
169+ ++ rotation
170+ |= [my-alphabet=tape my-steps=@ud]
171+ =/ length=@ud (lent my-alphabet)
172+ =+ (trim (mod my-steps length) my-alphabet)
173+ (weld q p)
174+```
175+
176+The `rotation` arm takes takes a specified number of characters off of a tape and
177+puts them on the end of the tape. We're going to use this to create our shifted alphabet,
178+based on the number of `steps` given as an argument to our gate.
179+
180+`|= [my-alphabet=tape my-steps=@ud]` creates a gate that takes two arguments: `my-alphabet`, a `tape`,
181+and `my-steps`, a `@ud`.
182+
183+`=/ length=@ud (lent my-alphabet)` stores the length of `my-alphabet` to make the following
184+code a little clearer.
185+
186+`trim` is a a gate from the standard library that splits a tape at into two
187+parts at a specified position. So `=+ (trim (mod my-steps length) my-alphabet)` splits the
188+tape `my-alphabet` into two parts, `p` and `q`, which are now directly available in the subject.
189+We call the modulus operation `mod` to make sure that the point at which we split our `tape` is
190+a valid point inside of `my-alphabet` even if `my-steps` is greater than `length`, the length of
191+`my-alphabet`. Try trim in the dojo:
192+
193+```
194+> (trim 2 "abcdefg")
195+[p="ab" q="cdefg"]
196+
197+> (trim 4 "yourbeard")
198+[p="your" q="beard"]
199+```
200+
201+`(weld q p)` uses `weld`, which combines two strings into one. Remember that `trim` has given us
202+a split version of `my-alphabet` with `p` being the front half that was split off of `my-alphabet`
203+and `q` being the back half. Here we are welding the two parts back together, but in reverse order:
204+the second part `q` is welded to the front, and the first part `p` is welded to the back.
205+
206+```hoon
207+ ++ map-maker
208+ |= [key-position=tape value-result=tape]
209+ ^- (map @t @t)
210+ =| chart=(map @t @t)
211+ ?. =((lent key-position) (lent value-result))
212+ ~| %uneven-lengths !!
213+ |-
214+ ?: |(?=(~ key-position) ?=(~ value-result))
215+ chart
216+ $(chart (~(put by chart) i.key-position i.value-result), key-position t.key-position, value-result t.value-result)
217+```
218+
219+The `map-maker` arm, as the name implies, takes two tapes and creates a [`map`](/docs/hoon/reference/stdlib/2o/#map) out of them.
220+A `map` is a type equivalent to a dictionary in other languages: it's a data structure that
221+associates a key with a value. If, for example, we wanted to have an association
222+between `a` and 1 and `b` and 2, we could use a `map`.
223+
224+`|= [a=tape b=tape]` builds a gate that takes two tapes, `a` and `b`, as its
225+sample.
226+
227+`^- (map @t @t)` casts the gate to a `map` with a `cord` (or `@t`) key and a `cord`
228+value.
229+
230+You might wonder, if our gate in this arm takes `tape`s, why then are we producing
231+a map of `cord` keys and values?
232+
233+As we discussed earlier, a `tape` is a list of `cord`s. In this case what we are going to do
234+is map a single element of a `tape` (either our alphabet or shifted-alphabet) to an element of
235+a different `tape` (either our shifted-alphabet or our alphabet). This pair will therefore be
236+a pair of `cord`s. When we go to use this `map` to convert our incoming `msg`, we will take
237+each element (`cord`) of our `msg` `tape`, use it as a `key` when accessing our `map` and get
238+the corresponding `value` from that position in the `map`. This is how we're going to encode
239+or decode our `msg` `tape`.
240+
241+`=| chart=(map @t @t)` adds a [noun](/docs/glossary/noun/) to the subject with the default value of
242+the `(map @t @t)` type, and gives that noun the face `chart`.
243+
244+`?. =((lent key-position) (lent value-result))` checks if the two `tape`s are the same length. If not,
245+the program crashes with an error message of `%uneven-lengths`, using `|~ %uneven-lengths !!`.
246+
247+If the two `tape`s are of the same length, we continue on to create a trap.
248+`|-` creates a [trap](/docs/glossary/trap/), a gate that is called immediately.
249+
250+`?: |(?=(~ key-position) ?=(~ value-result))` checks if either `tape` is empty. If this is true, the
251+`map-maker` arm is finished and can return `chart`, the `map` that we have been
252+creating.
253+
254+If the above test finds that the `tape`s are not empty, we trigger a recursion
255+that constructs our `map`: `$(chart (~(put by chart) i.a i.b), a t.a, b t.b)`.
256+This code recursively adds an entry in our `map` where the head of the `tape` `a`
257+maps to the value of the head of `tape` `b` with `~(put by chart)`, our calling
258+of the `put` arm of the `by` map-engine core (note that `~(<wing> <door> <sample>`) is
259+a shorthand for `%~ <wing> <door> <sample>` (see the [Calls % ('cen')](/docs/hoon/reference/rune/cen#censig)
260+documentation for more information). The recursion also "consumes"
261+those heads with every iteration by changing `a` and `b` to their tails using `a t.a, b t.b`.
262+
263+We have three related arms to look at next, `decoder`, `encoder`, and
264+`space-adder`. `space-adder` is required for the other two, so we'll look at it
265+first.
266+
267+```hoon
268+ ++ space-adder
269+ |= [key-position=tape value-result=tape]
270+ ^- (map @t @t)
271+ (~(put by (map-maker key-position value-result)) ' ' ' ')
272+```
273+
274+`|= [key-position=tape value-result=tape]` creates a gate that takes two `tapes`.
275+
276+We use the `put` arm of the `by` core on the next line, giving it a `map` produced
277+by the `map-maker` arm that we created before as its sample. This adds an entry to the
278+map where the space character (called `ace`) simply maps to itself. This is done to
279+simplify the handling of spaces in `tapes` we want to encode, since we don't want to
280+shift them.
281+
282+```hoon
283+ ++ encoder
284+ |= [steps=@ud]
285+ ^- (map @t @t)
286+ =/ value-tape=tape (rotation alpha steps)
287+ (space-adder alpha value-tape)
288+ ++ decoder
289+ |= [steps=@ud]
290+ ^- (map @t @t)
291+ =/ key-tape=tape (rotation alpha steps)
292+ (space-adder key-tape alpha)
293+```
294+
295+`encoder` and `decoder` utilize the `rotation` and `space-adder` arms. These gates
296+are essentially identical, with the arguments passed to `space-adder` reversed. They
297+simplify the two common transactions you want to do in this program: producing `maps`
298+that we can use to encode and decode messages.
299+
300+In both cases, we create a gate that accepts a `@ud` named `steps`.
301+
302+In `encoder`:
303+`=/ value-tape=tape (rotation alpha steps)` creates a `value-tape` noun by calling `rotation`
304+on `alpha`. `alpha` is our arm which contains a `tape` of the entire alphabet. The
305+`value-tape` will be the list of `value`s in our `map`.
306+
307+In `decoder`:
308+`=/ key-tape (rotation alpha steps)` does the same work, but when passed to `space-adder`
309+it will be the list of `key`s in our `map`.
310+
311+`(space-adder alpha value-tape)`, for `encoder`, and `(space-adder key-tape alpha)`, for
312+`decoder`, produce a `map` that has the first argument as the keys and the
313+second as the values.
314+
315+If our two inputs to `space-adder` were `"abcdefghijklmnopqrstuvwxyz"` and
316+`"bcdefghijklmnopqrstuvwxyza"`, we would get a `map` where `'a'` maps to `'b'`,
317+`'b'` to `'c'` and so on. By doing this we can produce a `map` that gives us a
318+translation between the alphabet and our shifted alphabet, or vice versa.
319+
320+Still with us? Good. We are finally about to use all the stuff that we've
321+walked through.
322+
323+```hoon
324+ ++ shift
325+ |= [message=tape shift-steps=@ud]
326+ ^- tape
327+ (operate message (encoder shift-steps))
328+ ++ unshift
329+ |= [message=tape shift-steps=@ud]
330+ ^- tape
331+ (operate message (decoder shift-steps))
332+```
333+
334+Both `shift` and `unshift` take two arguments: our `message`, the `tape` that we
335+want to manipulate; and our `shift-steps`, the number of positions of the alphabet
336+by which we want to shift our message.
337+
338+`shift` is for encoding, and `unshift` is for decoding. Thus, `shift` calls the
339+`operate` arm with `(operate message (encoder shift-steps))`, and `unshift` makes
340+that call with `(operate message (decoder shift-steps))`. These both produce the
341+final output of the core, to be called in the form of `(shift msg steps)`
342+and `(unshift msg steps)` in the cell being created at the beginning of our code.
343+
344+```hoon
345+ ++ operate
346+ |= [message=tape shift-map=(map @t @t)]
347+ ^- tape
348+ %+ turn message
349+ |= a=@t
350+ (~(got by shift-map) a)
351+```
352+
353+`operate` produces a `tape`. The `%+` rune allows us to pull an arm
354+with a pair sample. The arm we are going to pull is `turn`. This arm
355+takes two arguments, a `list` and a `gate` to apply to each element of the
356+`list`.
357+
358+In this case, the `gate` we are applying to our `message` uses the `got` arm
359+of the `by` door with our `shift-map` as the sample (which is either the standard alphabet
360+for keys, and the shifted alphabet for values, or the other way, depending on
361+whether we are encoding or decoding) to look up each `cord` in our `message`, one by one
362+and replace it with the `value` from our `map` (either the encoded or decoded version).
363+
364+If we then give our arm Caesar's famous statement, and get our left- and
365+right-ciphers.
366+
367+```
368+> +caesar ["i came i saw i conquered" 4]
369+["m geqi m wea m gsruyivih" "e ywia e ows e ykjmqanaz"]
370+```
371+
372+Now, to decode, we can put either of our ciphers in with the appropriate key and
373+look for the legible result.
374+
375+```
376+> +caesar ["m geqi m wea m gsruyivih" 4]
377+["q kium q aie q kwvycmzml" "i came i saw i conquered"]
378+
379+> +caesar ["e ywia e ows e ykjmqanaz" 4]
380+["i came i saw i conquered" "a usew a kso a ugfimwjwv"]
381+```
382+
383+### Exercises
384+
385+1. Take the example generator and modify it to add a second layer of shifts.
386+
387+2. Extend the example generator to allow for use of characters other than a-z.
388+ Make it shift the new characters independently of the alpha characters, such
389+ that punctuation is only encoded as other punctuation marks.
390+
391+3. Build a gate that can take a Caesar shifted `tape` and produce all
392+ possible unshifted `tapes`.
393+
394+4. Modify the example generator into a `%say` generator.
content/docs/hoon/hoon-school/conditionals.mdnew file+105
@@ -0,0 +1,105 @@
1++++
2+title = "1.3.1 Walkthrough: Conditionals"
3+weight = 5
4+template = "doc.html"
5+aliases = ["/docs/learn/hoon/hoon-tutorial/conditionals/"]
6++++
7+
8+In this lesson, we will write a generator that takes an integer and checks if it is an even number between `1` and `100`. This will help demonstrate how boolean (`true` or `false`) conditional expressions work in Hoon.
9+
10+```hoon
11+:- %say
12+|= [* [n=@ud ~] ~]
13+:- %noun
14+^- ?
15+?& (gte n 1)
16+ (lte n 100)
17+ =(0 (mod n 2))
18+==
19+```
20+
21+On the very first line, with `:- %say` we are beginning to create a generator of the `%say` variety. The result of a `%say` generator is a cell with a head of `%say` and tail that is a [gate](/docs/glossary/gate/), itself producing a `cask`, a pair of a `mark` and some data. It's not important for understanding conditionals; this is just template code. For more information about `%say` generators, see the [Generators](/docs/hoon/hoon-school/generators) documentation.
22+
23+```hoon
24+|= [* [n=@ud ~] ~]
25+```
26+
27+The code above builds a gate. The gate's first argument is a cell provided by Dojo that contains some system information we're not going to use, so we use `*` to indicate "any [noun](/docs/glossary/noun/)". The next cell is our arguments provided to the generator upon invocation at the Dojo. Here we only want one `@ud` with the face `n`.
28+
29+```hoon
30+:- %noun
31+```
32+
33+This code is the third line of the `%say` "boilerplate", and it produces a `cask` with the head of `%noun`. We could use any `mark` here, but `%noun` is the most generic type, able to fit any data.
34+
35+```hoon
36+^- ?
37+```
38+
39+This line casts the output as a `flag`, which is a type whose values are `%.y` and `%.n` representing "yes" and "no". These behave as boolean values (`true` or `false`).
40+
41+Let's look at the conditional:
42+
43+```hoon
44+?& (gte n 1)
45+```
46+
47+`?&` (pronounced "wut-pam") takes in a list of Hoon expressions, terminated by `==`, that evaluate to a `flag` and returns the logical "AND" of these flags. Most runes take a fixed number of children, but the handful that do not (such as `?&`) end their list of children with a terminating rune. In our context, that means that if the product of each of the children of `?&` is `%.y`, then the product of the entire `?&` expression is `%.y` as well. Otherwise, the product of the conditional `?&` is `%.n`.
48+
49+The first child of `?&` is `(gte n 1)`. It is good practice to put the first boolean test of a conditional on the same line as the conditional, as we have done here. This utilizes the standard library function `gte` which stands for "greater than or equal to". `(gte a b)` returns `%.y` if `a` is greater than or equal to `b`, and `%.n` otherwise.
50+
51+Next we have:
52+
53+```hoon
54+ (lte n 100)
55+```
56+
57+`lte` is the standard library function for "less than or equal to". `(lte a b)`
58+returns `%.y` if `a` is less than or equal to `b`, and `%.n` otherwise.
59+
60+The last boolean test we have is:
61+
62+```hoon
63+ =(0 (mod n 2))
64+```
65+
66+This checks to see if `0` is equal to `(mod n 2)` -- in other words, checking if `n` is even. It produces `%.y` if `n` is even and `%.n` if `n` is odd.
67+
68+It is good practice in Hoon to put "lighter" lines at the top and "heavier" lines at the bottom, which is why we have put `=(0 (mod n 2))` last in the list of conditionals.
69+
70+Finally we have a terminator:
71+
72+```hoon
73+==
74+```
75+
76+This marks the end of the list of children of `?&`.
77+
78+### Other Runes
79+
80+We only utilized one "wut" rune in our walkthrough, but there are many others. Here are a few more examples:
81+
82+- `?:` (pronounced "wut-col") is the simplest "wut" rune. It takes three children, also called subexpressions. The first child is a boolean test, so it looks for a `%.y` or a `%.n`. The second child is a yes-branch, which is what we arrive at if the aforementioned boolean test evaluates to `%.y`. The third child is a no-branch, which we arrive at if the boolean test evaluates to `%.n`. These branches can contain any sort of Hoon expression, including further conditional expressions. Instead of the `?&` expression in our `%say` generator above, we could have written:
83+
84+```hoon
85+?: ?& (gte n 1)
86+ (lte n 100)
87+ =(0 (mod n 2))
88+ ==
89+ %.y
90+%.n
91+```
92+
93+Of course, doing so would be needlessly obfuscating -- we mention this only to illustrate that these two Hoon expressions have the same product.
94+
95+- `?!` ("wut-zap") is the logical "NOT" operator, which inverts the truth value of its single child. Instead of `(lte n 100)` in our `%say` generator above, we could have written `?! (gth n 100)`. Again, this would be bad practice, we only present this as an example.
96+
97+- `?@` takes three children. It branches on whether its first child is an [atom](/docs/glossary/atom/).
98+
99+- `?^` takes three children. It branches on whether its first child is a cell.
100+
101+- `?~` takes three children. It branches on whether its first child is null.
102+
103+- `?|` takes an indefinite number of children. It's the logical "or" operator. It checks if at least one of its children is true.
104+
105+To see an exhaustive list of "wut" runes, check out the [reference documentation on conditionals](/docs/hoon/reference/rune/wut).
content/docs/hoon/hoon-school/doors.mdnew file+516
@@ -0,0 +1,516 @@
1++++
2+title = "1.8 Doors"
3+weight = 16
4+template = "doc.html"
5+aliases = ["/docs/learn/hoon/hoon-tutorial/doors/"]
6++++
7+
8+It's useful to have [cores](/docs/glossary/core/) whose [arms](/docs/glossary/arm/) evaluate to make [gates](/docs/glossary/gate/). The use of such cores is common in Hoon; that's how the functions of the Hoon standard library are stored in the subject. Learning about such cores will also deepen the reader's understanding of Hoon semantics, and for that reason alone is worthwhile.
9+
10+In this lesson you'll also learn about a new kind of core, called a 'door'.
11+
12+## Two Kinds of Function Calls
13+
14+There are two ways of making a function call in Hoon. First, you can call a gate in the subject by name. This is what you did with `inc` in the last lesson; you bound `inc` to a gate that adds `1` to an input:
15+
16+```
17+> =inc |=(a=@ (add 1 a))
18+
19+> (inc 10)
20+11
21+
22+> =inc
23+```
24+
25+The second way of making a function call involves an expression that _produces_ a gate:
26+
27+```
28+> (|=(a=@ (add 1 a)) 123)
29+124
30+
31+> (|=(a=@ (mul 2 a)) 123)
32+246
33+```
34+
35+The difference is that `inc` is an already-created gate in the subject when we called it. The latter calls involve producing a gate that doesn't exist anywhere in the subject, and then calling it.
36+
37+Are calls to `add` and `mul` of the Hoon standard library of the first kind, or the second?
38+
39+```
40+> (add 12 23)
41+35
42+
43+> (mul 12 23)
44+276
45+```
46+
47+They're of the second kind. Neither `add` nor `mul` resolves to a gate directly; they're each arms that _produce_ gates.
48+
49+Often the difference doesn't matter much. Either way you can do a function call using the `(gate arg)` syntax.
50+
51+It's important to learn the difference, however, because for certain use cases you'll want the extra flexibility that comes with having an already produced core in the subject.
52+
53+## A Gate-Building Core
54+
55+Let's make a core with arms that build gates of various kinds. As we did in a previous lesson, we'll use the `|%` rune. Feel free to cut and paste the following into the dojo:
56+
57+```hoon
58+> =c |%
59+ ++ inc |=(a=@ (add 1 a))
60+ ++ add-two |=(a=@ (inc (inc a)))
61+ ++ double |=(a=@ (mul 2 a))
62+ ++ triple |=(a=@ (mul 3 a))
63+ --
64+```
65+
66+Let's try out these arms, using them for function calls:
67+
68+```
69+> (inc:c 10)
70+11
71+
72+> (add-two:c 10)
73+12
74+
75+> (double:c 10)
76+20
77+
78+> (triple:c 10)
79+30
80+```
81+
82+Notice that each arm in core `c` is able to call the other arms of `c` -- `add-two` uses the `inc` arm to increment a number twice. As a reminder, each arm is evaluated with its parent core as the subject. In the case of `add-two` the parent core is `c`, which has `inc` in it.
83+
84+### Mutating a Gate
85+
86+Let's say you want to modify the default sample of the gate for `double`. We can infer the default sample by calling `double` with no argument:
87+
88+```
89+> (double:c)
90+0
91+```
92+
93+Given that `a x 2 = 0`, `a` must be `0`. (Remember that `a` is the face for the `double` sample, as defined in the core we bound to `c` above.)
94+
95+Let's say we want to mutate the `double` gate so that the default sample is `25`. There is only one problem: `double` isn't a gate!
96+
97+```
98+> double.c(a 25)
99+-tack.a
100+-find.a
101+```
102+
103+It's an arm that produces a gate, and `a` cannot be found in `double` until the gate is created. Furthermore, every time the gate is created, it has the default sample, `0`. If you want to mutate the gate produced by `double`, you'll first have to put a copy of that gate into the subject:
104+
105+```
106+> =double-copy double:c
107+
108+> (double-copy 123)
109+246
110+```
111+
112+Now let's mutate the sample to `25`, and check that it worked with `+6`:
113+
114+```
115+> +6:double-copy(a 25)
116+a=25
117+```
118+
119+Good. Let's call it with no argument and see if it returns double the value of the modified sample.
120+
121+```
122+> (double-copy(a 25))
123+50
124+```
125+
126+It does indeed. Unbind `c` and `double-copy`:
127+
128+```
129+> =c
130+
131+> =double-copy
132+```
133+
134+Contrast this with the behavior of `add`. We can look at the sample of the gate for `add` with `+6:add`:
135+
136+```
137+> +6:add
138+[a=0 b=0]
139+```
140+
141+If you try to mutate the default sample of `add`, it won't work:
142+
143+```
144+> add(a 3)
145+-tack.a
146+-find.a
147+```
148+
149+As before with `double`, Hoon can't find an `a` to modify in a gate that doesn't exist yet.
150+
151+## Other Functions in the Hoon Standard Library
152+
153+Let's look once more at the parent core of the `add` arm in the Hoon standard library:
154+
155+```
156+> ..add
157+<74.dbd 1.qct $141>
158+```
159+
160+The battery of this core contains 74 arms, each of which evaluates to a gate in the standard library. This 'library' is nothing more than a core containing useful basic functions that Hoon often makes available as part of the subject. You can see the Hoon code defining these arms near the beginning of [hoon.hoon](https://github.com/urbit/urbit/blob/master/pkg/arvo/sys/hoon.hoon), starting with [`++ add`](https://github.com/urbit/urbit/blob/master/pkg/arvo/sys/hoon.hoon#L21). (Yes, the Hoon standard library is written in Hoon.)
161+
162+Here are some of the other gates that can be generated from this core in the Hoon standard library. It should be fairly obvious what they do:
163+
164+```
165+> (dec 18)
166+17
167+
168+> (dec 17)
169+16
170+
171+> (gth 11 7)
172+%.y
173+
174+> (gth 7 11)
175+%.n
176+
177+> (gth 11 11)
178+%.n
179+
180+> (lth 11 7)
181+%.n
182+
183+> (lth 7 11)
184+%.y
185+
186+> (lth 11 11)
187+%.n
188+
189+> (max 12 14)
190+14
191+
192+> (max 14 14)
193+14
194+
195+> (max 14 432)
196+432
197+
198+> (mod 11 7)
199+4
200+
201+> (mod 22 7)
202+1
203+
204+> (mod 33 7)
205+5
206+
207+> (sub 234 123)
208+111
209+```
210+
211+## Doors
212+
213+A brief review: A core is a cell of battery and [payload](/docs/glossary/payload/): `[battery payload]`. The battery is code and the payload is data. The battery contains a series of arms, and the payload contains all the data necessary to run those arms correctly.
214+
215+New material: A **door** is a core with a sample. That is, a [door](/docs/glossary/door/) is a core whose payload is a cell of sample and context: `[sample context]`.
216+
217+```
218+ Door
219+ / \
220+Battery .
221+ / \
222+ Sample Context
223+```
224+
225+It follows from this definition that a gate is a special case of a door. A gate is a door with exactly one arm, named `$`.
226+
227+Gates are useful for defining functions. But there are many-armed doors as well. How are they used? Doors are quite useful data structures. In Chapter 2 of the Hoon tutorial series you'll learn how to use doors to implement state machines, where the sample stores the relevant state data. For now let's talk about how to use doors for simpler purposes.
228+
229+### An Example Door {#example}
230+
231+Let's write an example door in order to illustrate its features. Each of the arms in the door will define a simple gate. Let's bind the door to `c` as we did with the last core. To make a door we use the `|_` rune:
232+
233+```
234+> =c |_ b=@
235+ ++ plus |=(a=@ (add a b))
236+ ++ times |=(a=@ (mul a b))
237+ ++ greater |=(a=@ (gth a b))
238+ --
239+```
240+
241+If you type this into the dojo manually, make sure you attend carefully to the spacing. Feel free to cut and paste the code, if desired.
242+
243+Before getting into what these arms do, let's cover how the `|_` rune works in general.
244+
245+#### The `|_` Rune
246+
247+The `|_` rune for making a door works exactly like the `|%` rune for making a core, except it takes one additional subexpression.
248+
249+The first subexpression after the `|_` rune defines the door's sample. (This is the subexpression the `|%` rune lacks.) Following that are a series of `++` runes, each of which defines an arm of the door. Finally, the expression is terminated with a `--` rune.
250+
251+We emphasize that a door really is, at bedrock level, the same thing as a core
252+with a sample. Let's ask dojo to pretty print a simple door.
253+
254+```
255+> =a => ~ |_ b=@ ++ foo b --
256+> a
257+<1.zgd [b=@ %~]>
258+```
259+
260+Dojo tells us that `a` is a core with one arm and a payload of `[b=@ %~]`. Since
261+a door's payload is `[sample context]`, this means that `b` is the sample and
262+the context is null. Setting the context is what the `=> ~` did. The reason we
263+did this was to avoid including the standard library that is included in the
264+context by default in dojo, which would have made the pretty printed core much
265+more verbose.
266+
267+Now let's try to define a core with a sample:
268+
269+```
270+> =a => ~ =| b=@ |% ++ foo b --
271+> a
272+<1.zgd [b=@ %~]>
273+```
274+
275+Dojo gives us the same result! But is the pretty printer hiding something from
276+us? Recall that Hoon compiles down to Nock, Urbit's purely-functional
277+assembly-level language. The `!=` rune returns the Nock of any Hoon expression.
278+Let's try it on these expressions:
279+
280+```
281+> != => ~ |_ b=@ ++ foo b --
282+[7 [1 0] 8 [1 0] [1 0 6] 0 1]
283+> != => ~ =| b=@ |% ++ foo b --
284+[7 [1 0] 8 [1 0] [1 0 6] 0 1]
285+```
286+
287+You don't need to know any Nock to see that these two expressions are identical.
288+Thus we have witnessed that doors really are just cores with samples.
289+
290+#### Back to the Example
291+
292+For the door defined [above](#example), `c`, the sample is defined as an [atom](/docs/glossary/atom/), `@`, and given the face `b`. The `plus` arm defines a gate that takes a single [atom](/docs/glossary/atom/) as its argument, `a`, and which returns the sum of `a` and `b`. The `times` arm defines a gate that takes a single [atom](/docs/glossary/atom/), `a`, and returns `a` times `b`. The `greater` arm defines a gate that takes a single [atom](/docs/glossary/atom/), `a`, and if `a` is greater than `b` returns `%.y`; otherwise `%.n`.
293+
294+Let's try out the arms of `c` with ordinary function calls:
295+
296+```
297+> (plus:c 10)
298+10
299+
300+> (times:c 10)
301+0
302+
303+> (greater:c 10)
304+%.y
305+```
306+
307+This works, but the results are not exciting. Passing `10` to the `plus` gate returns `10`, so it must be that the value of `b` is `0` (the bunt value of `@`). The products of the other function calls reinforce that assessment. Let's look directly at `+6` of `c`:
308+
309+```
310+> +6:c
311+b=0
312+```
313+
314+Having confirmed that `b` is `0`, let's mutate the `c` sample and then call its arms:
315+
316+```
317+> (plus:c(b 7) 10)
318+17
319+
320+> (times:c(b 7) 10)
321+70
322+
323+> (greater:c(b 7) 10)
324+%.y
325+
326+> (greater:c(b 17) 10)
327+%.n
328+```
329+
330+Doing the same mutation repeatedly can be tedious, so let's bind `c` to the modified version of the door, where `b` is `7`:
331+
332+```
333+> =c c(b 7)
334+
335+> (plus:c 10)
336+17
337+
338+> (times:c 10)
339+70
340+
341+> (greater:c 10)
342+%.y
343+```
344+
345+There's a more direct way of passing arguments for both the door sample and the gate sample simultaneously. We may use the `~(arm door arg)` syntax. This generates the `arm` product after modifying the `door`'s sample to be `arg`.
346+
347+```
348+> (~(plus c 7) 10)
349+17
350+
351+> (~(times c 7) 10)
352+70
353+
354+> (~(greater c 7) 10)
355+%.y
356+
357+> (~(greater c 17) 10)
358+%.n
359+```
360+
361+Readers with some mathematical background may notice that `~( )` expressions allow us to [curry](https://en.wikipedia.org/wiki/Currying). For each of the arms above, the `~( )` expression is used to create different versions of the same gate:
362+
363+```
364+> ~(plus c 7)
365+< 1.gxk
366+ { a/@
367+ < 3.iba
368+ { b/@
369+ {our/@p now/@da eny/@uvJ}
370+ < 19.anu
371+ 24.tmo
372+ 6.ipz
373+ 38.ard
374+ 119.spd
375+ 241.plj
376+ 51.zox
377+ 93.pqh
378+ 74.dbd
379+ 1.qct
380+ $141
381+ >
382+ }
383+ >
384+ }
385+>
386+
387+
388+> b:~(plus c 7)
389+7
390+
391+> b:~(plus c 17)
392+17
393+```
394+
395+Thus, you may think of the `c` door as a function for making functions. Use the `~(arm c arg)` syntax -- `arm` defines which kind of gate is produced (i.e., which arm of the door is used to create the gate), and `arg` defines the value of `b` in that gate, which in turn affects the product value of the gate produced.
396+
397+The standard library provides [currying
398+functionality](/docs/hoon/reference/stdlib/2n#curry) outside of the context of
399+doors - see `+curr` and `+cury`.
400+
401+#### Creating Doors with a Modified Sample
402+
403+In the above example we created a door `c` with sample `b=@` and found that the initial value of `b` was `0`, the bunt value of `@`. We then created new door from `c` by modifying the value of `b`. But what if we wish to define a door with a chosen sample value directly? We make use of the `$_` rune, whose irregular form is simply `_`. To create the door `c` with the sample `b=@` set to have the value `7` in the dojo, we would write
404+```
405+> =c |_ b=_7
406+ ++ plus |=(a=@ (add a b))
407+ ++ times |=(a=@ (mul a b))
408+ ++ greater |=(a=@ (gth a b))
409+ --
410+```
411+Here the type of `b` is inferred to be `@` based on the example value `7`, similar to how we've seen casting done by example. You will learn more about how types are inferred in [Lesson 2.2](@docs/hoon/hoon-school/type-checking-and-type-inference.md).
412+
413+### Doors in the Hoon Standard Library
414+
415+Back in lesson 1.2 you were introduced to atom auras, which are metadata used by Hoon that defines how that atom is interpreted and pretty-printed. Atoms are unsigned integers, but sometimes programmers want to work with fractions and decimal points. Accordingly, there are auras for [floating point numbers](https://en.wikipedia.org/wiki/Floating-point_arithmetic). Let's work with the aura for doing [single-precision](https://en.wikipedia.org/wiki/Single-precision_floating-point_format) floating point arithmetic: `@rs`.
416+
417+The `@rs` has its own literal syntax. These atoms are represented as a `.` followed by digits, and possibly another `.` (for the decimal point) and more digits. For example, the float 3.14159 can be represented as a single-precision (32 bit) float with the literal expression `.3.14159`.
418+
419+You can't use the ordinary `add` function to get the correct sum of two `@rs` atoms:
420+
421+```
422+> (add .3.14159 .2.22222)
423+2.153.203.882
424+```
425+
426+That's because the `add` gate is designed for use with raw atoms, not floating point values. You can add two `@rs` atoms as follows:
427+
428+```
429+> (add:rs .3.14159 .2.22222)
430+.5.36381
431+```
432+
433+It turns out that the `rs` in `add:rs` is a Hoon standard library arm that produces a door. Let's take a closer look:
434+
435+```
436+> rs
437+<21|fan {r/?($n $u $d $z) <51.zox 93.pqh 74.dbd 1.qct $141>}>
438+```
439+
440+The battery of this core, pretty-printed as `21|fan`, has 21 arms that define functions specifically for `@rs` atoms. One of these arms is named `add`; it's a different `add` from the standard one we've been using for vanilla atoms. So when you invoke `add:rs` instead of just `add` in a function call, (1) the `rs` door is produced, and then (2) the name search for `add` resolves to the special `add` arm in `rs`. This produces the gate for adding `@rs` atoms:
441+
442+```
443+> add:rs
444+< 1.hsu
445+ {{a/@rs b/@rs} <21.fan {r/?($n $u $d $z) <51.zox 93.pqh 74.dbd 1.qct $141>}>}
446+>
447+```
448+
449+What about the sample of the `rs` door? The pretty-printer shows `r/?($n $u $d $z)`. What does this mean? Without yet explaining this notation fully, we'll simply say that the `rs` sample can take one of four values: `%n`, `%u`, `%d`, and `%z`. These argument values represent four options for how to round `@rs` numbers:
450+
451+```
452+%n -- round to the nearest value
453+%u -- round up
454+%d -- round down
455+%z -- round to zero
456+```
457+
458+The default value is `%z` -- round to zero. When we invoke `add:rs` to call the addition function, there is no way to modify the `rs` door sample, so the default rounding option is used. How do we change it? We use the `~( )` notation: `~(arm door arg)`.
459+
460+Let's evaluate the `add` arm of `rs`, also modifying the door sample to `%u` for 'round up':
461+
462+```
463+> ~(add rs %u)
464+< 1.hsu
465+ {{a/@rs b/@rs} <21.fan {r/?($n $u $d $z) <51.zox 93.pqh 74.dbd 1.qct $141>}>}
466+>
467+```
468+
469+This is the gate produced by `add`, and you can see that its sample is a pair of `@rs` atoms. But if you look in the context you'll see the `rs` door. Let's look in the sample of that core to make sure that it changed to `%u`. We'll use the wing `+6.+7` to look at the sample of the gate's context:
470+
471+```
472+> +6.+7:~(add rs %u)
473+r=%u
474+```
475+
476+It did indeed change. We also see that the door sample uses the face `r`, so let's use that instead of the unwieldy `+6.+7`:
477+
478+```
479+> r:~(add rs %u)
480+%u
481+```
482+
483+We can do the same thing for rounding down, `%d`:
484+
485+```
486+> r:~(add rs %d)
487+%d
488+```
489+
490+Let's see the rounding differences in action. Because `~(add rs %u)` produces a gate, we can call it like we would any other gate:
491+
492+```
493+> (~(add rs %u) .3.14159265 .1.11111111)
494+.4.252704
495+
496+> (~(add rs %d) .3.14159265 .1.11111111)
497+.4.2527037
498+```
499+
500+This difference between rounding up and rounding down might seem strange at first. There is a difference of 0.0000003 between the two answers. Why does this gap exist? Single-precision floats are 32-bit and there's only so many distinctions that can be made in floats before you run out of bits.
501+
502+Just as there is a door for `@rs` functions, there is a Hoon standard library door for `@rd` functions (double-precision 64 bit floats), another for `@rq` functions (quad-precision 128 bit floats), and more.
503+
504+### Mutating the `rs` Door
505+
506+Can we mutate the `rs` door so that its sample is `%u`? Let's try it:
507+
508+```
509+> rs(r %u)
510+-tack.r
511+-find.r
512+```
513+
514+Oops! Why didn't this work? Remember, `rs` isn't itself a door; it's an arm that produces a door. The `rs` in `rs(r %u)` resolves to the nameless parent core of `rs`, and the search for `r` commences there. But that face can't be found in that parent core -- it's not where we want to look.
515+
516+It's better simply to use the `~(arm rs arg)` syntax to replace the value of the `rs` door sample with `arg`.
content/docs/hoon/hoon-school/egg-timer.mdnew file+159
@@ -0,0 +1,159 @@
1++++
2+title = "2.7.1 Gall Walkthrough: Egg Timer"
3+weight = 36
4+template = "doc.html"
5+aliases = ["/docs/learn/hoon/hoon-tutorial/egg-timer/"]
6++++
7+
8+The Arvo operating system is divided up into modules called vanes. Gall is the vane responsible for providing an API for building stateful applications in Urbit. Gall is a complex system that takes a lot of getting used to, so let's dip our toes in with a simple egg-timer app.
9+
10+The following code sample should be saved as `/home/app/egg-timer.hoon`
11+After committing: `|start %egg-timer` and poke with `:egg-timer ~s10`
12+
13+```hoon
14+/+ default-agent
15+|%
16++$ card card:agent:gall
17+--
18+::
19+^- agent:gall
20+|_ =bowl:gall
21++* this .
22+ def ~(. (default-agent this %.n) bowl)
23+::
24+++ on-poke
25+ |= [=mark =vase]
26+ ^- (quip card _this)
27+ =/ t !<(@dr vase)
28+ :_ this
29+ [%pass /egg-timer %arvo %b %wait (add now.bowl t)]~
30+::
31+++ on-arvo
32+ ^+ on-arvo:*agent:gall
33+ |= [=wire =sign-arvo]
34+ ^- (quip card _this)
35+ ~& "Timer went off!"
36+ [~ this]
37+::
38+++ on-init on-init:def
39+++ on-save on-save:def
40+++ on-load on-load:def
41+++ on-watch on-watch:def
42+++ on-leave on-leave:def
43+++ on-peek on-peek:def
44+++ on-agent on-agent:def
45+++ on-fail on-fail:def
46+--
47+```
48+
49+The first thing to notice is that we are creating a core (`|%`) and a door (`|_`). This is a typical style for Gall programming wherein types are defined in the first core and your application is defined in the following door.
50+Our door will have type `agent:gall` as specified in `sys/zuse.hoon`
51+
52+```hoon
53+|%
54++$ card card:agent:gall
55+--
56+```
57+
58+The core here defines only one type: `card`.
59+A `card` is a request to Arvo to do something for us. In this case, the only card used will be a `%wait` request to Behn which we'll discuss later.
60+
61+It's important to note that the name `card` is technically arbitrary. By convention, however, you will see it called `card` practically everywhere.
62+
63+The sample of the door(`|_`) is:
64+
65+```hoon
66+=bowl:gall
67+```
68+
69+You can find the full definition of `bowl` in `sys/zuse.hoon`, but for now it's enough to know that includes contextual data used by Gall with particular faces. Below are some important such faces:
70+
71+- `our` The ship this code is running on
72+- `src` The ship the current event originated from
73+- `eny` Guaranteed-fresh entropy
74+- `now` The current time
75+
76+We give `bowl:gall` the face `bowl`.
77+Additionally, we use `+*` to create two structures for future use:
78+
79+```hoon
80++* this .
81+ def ~(. (default-agent this %.n) bowl)
82+```
83+`this` is our current context(the door).
84+`def` uses `default-agent` to produce a standard `gall:agent` door, from which we will instance default definitions for our unused arms.
85+
86+All Gall agents have a fixed set of 10 arms. In this trivial case, we will specify only two and use the default definitions from `default-agent` for the remaining arms.
87+
88+```hoon
89+++ on-poke
90+ |= [=mark =vase]
91+ ^- (quip card _this)
92+ =/ t !<(@dr vase)
93+ :_ this
94+ [%pass /egg-timer %arvo %b %wait (add now.bowl t)]~
95+```
96+
97+The `++on-poke` arm evaluates to a gate which takes a sample `[mark vase]`. `mark` is a type specification and `vase` is a cell of `[specification value]`
98+Note: since `++on-poke` may take many different samples, it would be prudent to add a `%noun` mark check here.
99+In this example, we assume that our sample will contain a `@dr` and pull it from the `vase` with `=/ t !<(@dr vase)`
100+`@dr` is an aura for a 128-bit relative date. Here are a few examples.
101+
102+- `~s17` 17 seconds
103+- `~m20` 20 minutes
104+- `~m13s37` 13 minutes, 37 seconds
105+- `~d42` 42 days
106+
107+As a matter of good type hygiene, we explicitly cast the output of this gate with `^-` to ensure we are producing the correct structure for Gall to handle.
108+Our specification is `(quip card _this)` which produces a type, `[(list card) _this]`. Note that `_this` is irregular form of `$_(this)` which normalizes to the type of `this`, our door.
109+
110+Next we use the `:_` rune which is the inverted form of `:-`, the cell construction rune.
111+
112+```hoon
113+:_ this
114+ [%pass /egg-timer %arvo %b %wait (add now.bowl t)]~
115+```
116+Our card should follow the basic form `[%pass /my/wire a-note]`
117+In this case, our card will ask Arvo to `%pass` a note along the wire `/egg-timer` to Behn(`%b`) containing a `%wait` request.
118+Behn will start a timer for us, and will respond along our wire, `/egg-timer`.
119+
120+`now.bowl` is the current time of type `@da`, and `t` was declared as `@dr`. Because they are both atoms, we can add `now` and `t` to produce an atom that is `t` units of time into the future from `now`. That produced atom can be interpreted as a `@da`.
121+The calculated time will be passed via Arvo to Behn with instruction to `%wait @da`, i.e., to set a timer.
122+
123+That's all for our `++on-poke` arm. But what about when the timer goes off? Behn will create a `gift`, a similar construct to our `card` which will be dispatched back to us via Gall in the `++on-arvo` arm.
124+
125+```hoon
126+++ on-arvo
127+ ^+ on-arvo:*agent:gall
128+ |= [=wire =sign-arvo]
129+ ^- (quip card _this)
130+ ~& "Timer went off!"
131+ [~ this]
132+```
133+`++on-arvo` evaluates to a gate whose sample is a cell of `wire` and `sign-arvo` here given default faces. The syntax of `=wire` is a shortcut for `wire=wire`; it's a common pattern to shadow the name of a type when you only have one instance of the type and are not going to refer to the type itself.
134+A `wire` is an alias for a path. Our `wire` will be the path we provided in our `++on-poke` card. If we needed to do something particular depending on which request triggered this Arvo card, we could use the wire to do so.
135+
136+Note: since multiple vanes can send many sorts of cards via `++on-arvo`, it would be prudent to check if `sign-arvo` is `[%b %wake *]`. Since our trivial example assumes the card is `%wake` from Behn, we will forgo that better practice here.
137+
138+Next we have the same cast we used in `++on-poke` to make sure we produce the correct type for Gall. `(quip card _this)` resolves to a type `[(list card) _this]`
139+```
140+~& "Timer went off!"
141+```
142+
143+`~&` is the debugging printf rune. Here we're using it to output a message. We could, however, modify this line of code to do any other computation when `++on-arvo` is called.
144+
145+We need to produce a noun of type `(quip card _this)` i.e., `[(list card) _this]`.
146+In this case, we will not produce any card or change application state. Therefore we simply produce a cell of a null list and our original context, `[~ this]`.
147+
148+```hoon
149+++ on-init on-init:def
150+++ on-save on-save:def
151+++ on-load on-load:def
152+++ on-watch on-watch:def
153+++ on-leave on-leave:def
154+++ on-peek on-peek:def
155+++ on-agent on-agent:def
156+++ on-fail on-fail:def
157+--
158+```
159+Finally, we define the remaining 8 unused but required Gall Agent armsas instances of the default arms provided in `/lib/default-agent.hoon`.
content/docs/hoon/hoon-school/fibonacci.mdnew file+61
@@ -0,0 +1,61 @@
1++++
2+title = "1.5.1 Walkthrough: Fibonacci Sequence"
3+weight = 9
4+template = "doc.html"
5+aliases = ["/docs/learn/hoon/hoon-tutorial/fibonacci/"]
6++++
7+
8+In this example, we will write a generator that produces a list of [Fibonacci numbers](https://en.wikipedia.org/wiki/Fibonacci_number) up to `n`.
9+
10+```hoon
11+|= n=@ud
12+%- flop
13+=+ [i=0 p=0 q=1 r=*(list @ud)]
14+|- ^+ r
15+?: =(i n) r
16+%= $
17+ i +(i)
18+ p q
19+ q (add p q)
20+ r [q r]
21+==
22+```
23+
24+On the first line, we use `|=` to produce a [gate](/docs/glossary/gate/) which takes an `@ud` that's stored in the face `n`. This `n` sample that we give our [gate](/docs/glossary/gate/) determines how long our Fibonacci sequence is. When the list that our program builds has `n` items, the program ends.
25+
26+```hoon
27+%- flop
28+```
29+
30+In the line above, we use `flop` on the output of the rest of the program. `flop` is a [standard library](https://urbit.org/docs/hoon/reference/stdlib/) function to reverse a list.
31+
32+Why are we using this instead of just producing the list in the order we want it in the first place? Because with lists, adding an element to the end is a computationally expensive operation that gets more expensive the longer the list is, due to the fact that you need to traverse to the end of the tree. Adding an element to the front, however, is cheap. [In Big-O notation](https://en.wikipedia.org/wiki/Big_O_notation), adding to the end of a list is O(n) and the front is O(1).
33+
34+```hoon
35+=+ [i=0 p=0 q=1 r=*(list @ud)]
36+```
37+
38+Here we declare several values that we are going to use during the execution of our program. The only one that is noteworthy is `r`: we're using `*` to bunt, or get the default value for, the mold `(list @ud)`.
39+
40+```hoon
41+|- ^+ r
42+```
43+
44+With this code, we define `|-`, the _trap_ that acts as a recursion point and contains the rest of our program. We also use `^+` to cast the output by example. This will result in the output being the same type as `r`, a list of `@ud`.
45+
46+```hoon
47+?: =(i n) r
48+```
49+
50+In the code above, `?:` checks whether the first child, `=(i n)` (our terminating case), is `true` or `false`. If it is `true`, it branches to `r` and the program ends. If it is `false`, the program continues to the code below.
51+
52+```hoon
53+%= $
54+ i +(i)
55+ p q
56+ q (add p q)
57+ r [q r]
58+==
59+```
60+
61+The final expression in our program calls the `$` [arm](/docs/glossary/arm/) of the [trap](/docs/glossary/trap/) we are in but makes some changes: we increment `i`, set `p` to be `q` and `q` becomes the sum of `p` and `q`. `r` becomes a cell of `q` and whatever `r` was previously. The list built from this is the one that will get `flop`ped to produce the result at the end of the computation.
content/docs/hoon/hoon-school/gall.mdnew file+129
@@ -0,0 +1,129 @@
1++++
2+title = "2.7 Gall"
3+weight = 35
4+template = "doc.html"
5+aliases = ["/docs/learn/hoon/hoon-tutorial/gall/"]
6++++
7+
8+Gall is the Arvo vane responsible for handling user space applications. When writing a Gall application there are several things you will need to understand.
9+
10+For additional information on Gall, see the [Gall docs](/docs/arvo/gall/).
11+
12+## bowl and moves
13+
14+The [core](/docs/glossary/core/) of a gall app is a [door](/docs/glossary/door/) which has two parts of its subject, the first a `bowl:gall` which contains a lot of standard things used by gall apps, the second a type containing app state information.
15+
16+Vanes in Arvo communicate by means of `moves`. When a move is produced by an [arm](/docs/glossary/arm/) in a gall app, it's dispatched by Arvo to the correct handler for the request, be it another application or another vane. A `move` is pair of `bone` and `card`. These are essential components to understand when learning to use gall.
17+
18+A `bone` is an opaque cause that initiates a request. When constructing a `move` you can often use `ost.bowl` and when responding to an incoming `move` you can use the `bone` in that `move` to construct your response.
19+
20+A `card` is the effect or event that is being requested. Each application should define the set of `cards` it can produce. Here is an excerpt from `clock.hoon` showing its `cards`
21+
22+```hoon
23++$ card
24+ $% [%poke wire dock poke]
25+ [%http-response =http-event:http]
26+ [%connect wire binding:eyre term]
27+ [%diff %json json]
28+ ==
29+```
30+
31+Each `card` is a pair of a tag and a [noun](/docs/glossary/noun/). The tag indicates what the event being triggered is and the [noun](/docs/glossary/noun/) is any data required for that event.
32+
33+## Arms
34+
35+Gall applications can have a number of arms that get called depending on the information they are sent.
36+
37+### +on-init
38+
39+This arm is called when the app is initially started. It has no input and
40+lets you perform any initial IO.
41+
42+### +on-save
43+
44+This arm is called immediately before the agent is upgraded. It
45+packages the permament state of the agent in a `vase` for the next version
46+of the agent. Unlike most handlers, this cannot produce effects.
47+
48+### +on-load
49+
50+This arm is called immediately after the agent is upgraded. It receives
51+a `vase` of the state of the previously running version of the agent,
52+which allows it to cleanly upgrade from the old agent.
53+
54+### +on-poke
55+
56+This arm is called when the agent is "poked". The input is a `cage`, so
57+it's a pair of a mark and a dynamic `vase`.
58+
59+### +on-watch
60+
61+This arm is called when a program wants to subscribe to the agent on a
62+particular `path`. The agent may or may not need to perform setup steps
63+to intialize the subscription. It may produce a `%give`
64+`%subscription-result` to the subscriber to get it up to date, but after
65+this event is complete, it cannot give further updates to a specific
66+subscriber. It must give all further updates to all subscribers on a
67+specific `path`.
68+
69+If this arm crashes, then the subscription is immediately terminated.
70+More specifcally, it never started -- the subscriber will receive a
71+negative `%watch-ack`. You may also produce an explicit `%kick` to
72+close the subscription without crashing -- for example, you could
73+produce a single update followed by a `%kick`.
74+
75+### +on-leave
76+
77+This arm is called when a program becomes unsubscribed to you.
78+Subscriptions may close because the subscriber intentionally
79+unsubscribed, but they also could be closed by an intermediary. For
80+example, if a subscription is from another ship which is currently
81+unreachable, Ames may choose to close the subscription to avoid queueing
82+updates indefinitely. If the program crashes while processing an
83+update, this may also generate an unsubscription. You should consider
84+subscriptions to be closable at any time.
85+
86+### +on-peek
87+
88+This arm is called when a program reads from the agent's "scry"
89+namespace, which should be referentially transparent. Unlike most
90+handlers, this cannot perform IO, and it cannot change the state. All
91+it can do is produce a piece of data to the caller, or not.
92+
93+If this arm produces `[~ ~ data]`, then `data` is the value at the the
94+given `path`. If it produces `[~ ~]`, then there is no data at the given
95+`path` and never will be. If it produces `~`, then we don't know yet
96+whether there is or will be data at the given `path`.
97+
98+### +on-agent
99+
100+This arm is called to handle responses to `%give` moves to other agents.
101+It will be one of the following types of response:
102+
103+- `%poke-ack`: acknowledgment (positive or negative) of a poke. If the
104+ value is `~`, then the poke succeeded. If the value is `[~ tang]`,
105+ then the poke failed, and a printable explanation (e.g. a stack trace)
106+ is given in the `tang`.
107+
108+- `%watch-ack`: acknowledgment (positive or negative) of a subscription.
109+ If negative, the subscription is already ended (technically, it never
110+ started).
111+
112+- `%fact`: update from the publisher.
113+
114+- `%kick`: notification that the subscription has ended.
115+
116+### +on-arvo
117+
118+This arm is called to handle responses to `%pass` `move`s to vanes. The
119+list of possible responses from the system is statically defined in
120+sys/zuse.hoon (grep for `+ sign-arvo`).
121+
122+### +on-fail
123+
124+If an error happens in `+on-poke`, the crash report goes into the
125+`%poke-ack` response. Similarly, if an error happens in
126+`+on-subscription`, the crash report goes into the `%watch-ack`
127+response. If a crash happens in any of the other handlers, the report
128+is passed into this arm.
129+
content/docs/hoon/hoon-school/gates.mdnew file+272
@@ -0,0 +1,272 @@
1++++
2+title = "1.4 Gates (Hoon Functions)"
3+weight = 6
4+template = "doc.html"
5+aliases = ["/docs/learn/hoon/hoon-tutorial/gates/"]
6++++
7+
8+In this lesson you're going to learn about Hoon functions.
9+
10+## What is a Function?
11+
12+The word "function" is used in various ways, but let's start by talking about them in the [mathematical sense](https://en.wikipedia.org/wiki/Function_%28mathematics%29). Roughly put, a function takes one or more arguments (i.e., input values) and returns a value. The return value depends solely on the argument(s), and nothing else. For example, we can understand multiplication as a function: it takes two numbers and returns another number. It doesn't matter where you ask, when you ask, or what kind of hat you're wearing when you ask. If you pass the same two numbers (e.g., `3` and `4`), you get the same answer returned every time (`12`).
13+
14+That output value depends solely upon input value(s) is an important property of functions. This property is called [referential transparency](https://en.wikipedia.org/wiki/Referential_transparency), and we make use of it throughout the Urbit software stack.
15+
16+Functions are implemented in Hoon with a special kind of [core](/docs/glossary/core/) called a **gate**. In this lesson you'll learn what a [gate](/docs/glossary/gate/) is and how a gate represents a function. Along the way you'll build some example gates of your own.
17+
18+You've already used two functions from the Hoon standard library: `add` and `mul`. These are implemented with gates, and you call them from the Dojo in the following way:
19+
20+```
21+> (add 2 3)
22+5
23+
24+> (mul 2 3)
25+6
26+```
27+
28+## What is a Gate?
29+
30+A core is a cell: `[battery payload]`.
31+
32+A gate is a core with two distinctive properties: (1) the battery of a gate contains exactly one [arm](/docs/glossary/arm/), which has the special name `$`. The `$` [arm](/docs/glossary/arm/) contains the instructions for the function in question. And (2), the payload of a gate consists of a cell of `[sample context]`. The sample is the part of the payload that stores the "argument" (i.e., input value) of the function call. The context contains all other data that is needed for computing the `$` [arm](/docs/glossary/arm/) of the gate correctly.
33+
34+```
35+Gate: [$ [Sample Context]]
36+```
37+
38+As a tree, a gate looks like the following:
39+
40+```
41+ Gate
42+ / \
43+ $ .
44+ / \
45+ Sample Context
46+```
47+
48+Like all arms, `$` is computed with its parent core as the subject. When `$` is computed, the resulting value is called the "product" of the gate. No other data is used to calculate the product other than the data in the gate itself.
49+
50+## Creating Your First Gate
51+
52+Let's make a gate that takes any unsigned integer (i.e., an [atom](/docs/glossary/atom/)) as its sample and returns that value plus one as the product. To do this we'll use the `|=` rune. We'll bind this gate to the face `inc` for "increment":
53+
54+```
55+> =inc |=(a=@ (add 1 a))
56+
57+> (inc 1)
58+2
59+
60+> (inc 12)
61+13
62+
63+> (inc 123)
64+124
65+```
66+
67+The gate works as promised -- it takes any number `n` and returns `n+1`. Let's take a closer look at what the `|=` is doing.
68+
69+### The `|=` Rune
70+
71+We typically use the `|=` rune to create a gate. In the expression above the `|=` is immediately followed by a set of parentheses containing two subexpressions: `a=@` and `(add 1 a)`. The first defines the gate's sample (input value type), and the second defines the gate's product (value).
72+
73+In the example gate above, `inc`, the sample is defined by `a=@`. This means that the sample is defined as an atom, `@`, meaning that the gate will take as input anything of that type. The sample is given the face `a`. With the face it's easier to refer to the sample in later code, if desired.
74+
75+In `inc`, the product is defined by `(add 1 a)`. There's not much to it -- it returns the value of `a+1`!
76+
77+The second subexpression after the `|=` rune is used to build the gate's `$` arm. That's where all the computations go.
78+
79+## Anatomy of a Gate
80+
81+A gate is a one-armed core with a sample: `[$ [Sample Context]]`. Let's go over these parts a little more carefully, using `inc` as our example.
82+
83+```
84+> inc
85+< 1.jgn
86+ { a/@
87+ {our/@p now/@da eny/@uvJ}
88+ <19.anu 24.tmo 6.ipz 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
89+ }
90+>
91+```
92+
93+### The `$` Arm
94+
95+The arm of a gate encodes the instructions for the Hoon function in question.
96+
97+The pretty printer represents the `$` arm of `inc` as `1.jgn`. To see the actual [noun](/docs/glossary/noun/) of the `$` arm, enter `+2:inc` into the Dojo:
98+
99+```
100+> +2:inc
101+[8 [9 8 0 4.095] 9 2 [0 4] [[7 [0 3] 1 1] 0 14] 0 11]
102+```
103+
104+This is un-computed Nock. You don't need to understand any of this.
105+
106+It's worth pointing out that the arm name, `$`, can be used like any other name. We can compute `$` directly with `$:inc` in the Dojo:
107+
108+```
109+> $:inc
110+1
111+```
112+
113+This result may seem a bit strange. We didn't call `inc` or in any other way pass it a number. Yet using `$` to evaluate `inc`'s arm seems to work -- sort of, anyway. Why is it giving us `1` as the return value? We can answer this question after we understand gate samples a little better.
114+
115+### The Sample
116+
117+The sample of a gate is the address reserved for storing the argument(s) to the Hoon function. The sample is always at the head of the gate's tail, i.e., `+6`.
118+
119+Let's look at the gate for `inc` again, paying particular attention to its sample:
120+
121+```
122+> inc
123+< 1.jgn
124+ { a/@
125+ {our/@p now/@da eny/@uvJ}
126+ <19.anu 24.tmo 6.ipz 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
127+ }
128+>
129+```
130+
131+We see `a/@`. This may not be totally clear, but it should make _some_ sense. This is the pretty-printer's way of indicating an atom with the face `a`. Let's take a closer look:
132+
133+```
134+> +6:inc
135+a=0
136+```
137+
138+We see now that the sample of `inc` is the value `0`, and has `a` as a face. This is a placeholder value for the function argument. If you evaluate the `$` arm of `inc` without passing it an argument the placeholder value is used for the computation, and the return value will thus be `0+1`:
139+
140+```
141+> $:inc
142+1
143+```
144+
145+The placeholder value is sometimes called a **bunt** value. The bunt value is determined by the input type; for atoms, `@`, the bunt value is `0`.
146+
147+The face value of `a` comes from the way we defined the gate above: `|=(a=@ (add 1 a))`. It was so we could use `a` to refer to the sample to generate the product with `(add 1 a)`.
148+
149+### The Context
150+
151+The context of a gate contains other data that may be necessary for the `$` arm to evaluate correctly. The context is always located at the tail of the tail of the gate, i.e., `+7` of the gate. There is no requirement for the context to have any particular arrangement, though often it does.
152+
153+Let's look at the context of `inc`:
154+
155+```
156+> +7:inc
157+[ [ our=~zod
158+ now=~2018.12.12..18.55.06..df2b
159+ eny
160+ \/0v2g0.cmm6d.1igpo.llg7o.4921d.nov38.vjsgp.mdfln.8pt9f.n23hj.qc6q9.8p7bd\/
161+ .2eo59.qko43.1jgd2.rtc44.egooe.esvft.orohc.i9ufn.4rnur
162+ \/ \/
163+ ]
164+ <19.anu 24.tmo 6.ipz 38.ard 119.spd 241.plj 51.zox 93.pqh 74.dbd 1.qct $141>
165+]
166+```
167+
168+This is exactly the default Dojo subject, from before we put `inc` into the subject. The `|=` expression defines the context as whatever the subject is. This guarantees that the context has all the information it needs to have for the `$` arm to work correctly.
169+
170+### Exercise 1.4.1a
171+
172+Write a gate that takes an atom, `a=@`, and which returns double the value of `a`. Bind this gate to `double` and test it in the Dojo. A solution is given at the end of this lesson.
173+
174+## Gates Define Functions of the Sample
175+
176+The value of a function's output depends solely upon the input value. This is one of the features that make functions desirable in many programming contexts. It's worth going over how Hoon function calls implement this feature.
177+
178+In Hoon, one can use `(gate arg)` syntax to make a function call. For example:
179+
180+```
181+> (inc 234)
182+235
183+```
184+
185+The name of the gate is `inc`. How is the `$` arm of `inc` evaluated? When a function call occurs, a copy of the `inc` gate is created, but with one modification; the sample is replaced with the function argument. Then the `$` arm is computed against this modified version of the `inc` gate.
186+
187+Remember that the default or "bunt" value of the sample of `inc` is `0`. In the function call above, a copy of the `inc` gate is made but with a sample value of `234`. When `$` is computed against this modified core, the product is `235`.
188+
189+Notice that neither the arm nor the context is modified before the arm is evaluated. That means that the only part of the gate that changes before the arm evaluation is the sample. Hence, we may understand each gate as defining a function whose argument is the sample. If you call a gate with the same sample, you'll get the same value returned to you every time.
190+
191+Let's unbind `inc` to keep the subject tidy:
192+
193+```
194+> =inc
195+
196+> inc
197+-find.inc
198+```
199+
200+### Modifying the Context of a Gate
201+
202+It _is_ possible to modify the context of a gate when you make a function call; or, to be more precise, it's possible to call a mutant copy of the gate in which the context is modified. To illustrate this let's use another example gate. Let's write a gate which uses a value from the context to generate the product. Bind `b` to the value `10`:
203+
204+```
205+> =b 10
206+
207+> b
208+10
209+```
210+
211+Now let's write a gate called `ten` that adds `b` to the input value:
212+
213+```
214+> =ten |=(a=@ (add a b))
215+
216+> (ten 10)
217+20
218+
219+> (ten 20)
220+30
221+
222+> (ten 25)
223+35
224+```
225+
226+We can unbind `b` from the Dojo subject, and `ten` works just as well because it's using a copy of `b` stored its context:
227+
228+```
229+> =b
230+
231+> (ten 15)
232+25
233+
234+> (ten 35)
235+45
236+
237+> b.+14.ten
238+10
239+```
240+
241+We can use `ten(b 25)` to produce a variant of `ten`. Calling this mutant version of `ten` causes a different value to be returned than we'd get with a normal `ten` call:
242+
243+```
244+> (ten(b 25) 10)
245+35
246+
247+> (ten(b 1) 25)
248+26
249+
250+> (ten(b 75) 100)
251+175
252+```
253+
254+Before finishing the lesson let's unbind `ten`:
255+
256+```
257+> =ten
258+```
259+
260+## Exercise 1.4.1a: Answer
261+
262+Write a gate that takes an atom, `a=@`, and which returns double the value of `a`. Bind this gate to `double` and test it in the Dojo.
263+
264+```
265+> =double |=(a=@ (mul 2 a))
266+
267+> (double 10)
268+20
269+
270+> (double 25)
271+50
272+```
content/docs/hoon/hoon-school/generators.mdnew file+461
@@ -0,0 +1,461 @@
1++++
2+title = "1.9 Generators"
3+weight = 19
4+template = "doc.html"
5+aliases = ["/docs/learn/hoon/hoon-tutorial/generators/"]
6++++
7+
8+Generators are the most straightforward way to write programs for Urbit. They
9+are used for doing computations that do not require persistence: they take an
10+input and produce an output, then disappear. Generators might make sense for
11+listing directory contents, or running unit tests, or fetching the contents of a
12+URL.
13+
14+There are three kinds of generators: naked, `%say`, and `%ask`. There also used to be a fourth type of generator, `%get`, but this kind is no longer in use.
15+
16+### Naked Generators
17+
18+A naked generator is simply a `gate`; that is, it is an anonymous function that
19+takes a `sample` (argument) and produces a [noun](/docs/glossary/noun/). All you need to do is write a
20+`gate` and put it into a file in the `/gen` directory. Let's take a look at a
21+very simple one:
22+
23+```hoon
24+|= a=*
25+a
26+```
27+
28+This generator takes one argument of any noun and produces it without any
29+changes. Once you put this into a file named `echo.hoon` in the `/gen` directory, you must make your ship recognize the change by inputting `|commit %home` in the dojo. You can then run it from the dojo:
30+
31+```
32+> +echo 42
33+42
34+```
35+
36+This command just passes in 42 and gets 42 back. But what about when we pass in
37+`"asdf"`?
38+
39+```
40+> +echo "asdf"
41+[97 115 100 102 0]
42+```
43+
44+We just get a pile of numbers back in the form of a raw `noun`. The numbers that
45+compose that noun are called `atoms`, and how they are interpreted is a matter
46+of what `aura` is being applied to them. For the purposes of this lesson, an
47+`aura` tells the pretty-printer how to display an `atom`, but keep in mind that
48+an `aura` is type metadata and does other things, too.
49+
50+In the example above, we didn't specify an `aura`, leaving the printer to fend
51+for itself. `"asdf"` is a `tape`, a type that is simply a `list` of `cords`. A
52+`cord` is itself an [atom](/docs/glossary/atom/) represented as a string of UTF-8 characters. When used
53+as part of a `tape`, the `cord` is only a single character. So each atom in the
54+`[97 115 100 102 0]` output corresponds to a component of the `tape`: 97 is
55+`a`, 115 is `s`, 100 is `d`, 102 is `f`, and `0` is the "null" that every list
56+is terminated with.
57+
58+We can tell the Dojo to cast -- apply a specific type to -- the output of our
59+generator to see something more familiar:
60+
61+```
62+> _tape +echo "asdf"
63+"asdf"
64+```
65+
66+Now let's create a generator with two arguments instead of one. Save the code
67+below as `add.hoon` in the `/gen` directory.
68+
69+```hoon
70+|= [a=@ud b=@ud]
71+(add a b)
72+```
73+
74+Now, run the generator:
75+
76+```
77+> +add [3 4]
78+7
79+```
80+
81+You may notice our generator takes a cell containing two `@ud`. This is
82+actually one of the limitations of naked generators. We can only pass one
83+argument. We can get around this, of course, by passing a cell, but it's less
84+than ideal. Also, a naked generator cannot be called without an argument.
85+This brings us to `%say` generators.
86+
87+### `%say` Generators
88+
89+We use `%say` generators when we want to provide something else in Arvo, the
90+Urbit operating system, with metadata about the generator's output. This is
91+useful when a generator is needed to pipe data to another program, a frequent
92+occurrence.
93+
94+To that end, `%say` generators use `mark`s to make it clear, to other Arvo
95+computations, exactly what kind of data their output is. A `mark` is akin
96+to a MIME type on the Arvo level. A `mark` describes the data in
97+some way, indicating that it's an `%atom`, or that it's a standard such as
98+`%json`, or even that it's an application-specific data structure like
99+`%talk-command`. `mark`s are not specific to `%say` generators; whenever data
100+moves between programs in Arvo, that data is marked.
101+
102+So, more formally, a `%say` generator is a `cell`. The head of that cell is the
103+`%say` tag, and the tail is a `gate` that produces a `cask` -- a pair of the
104+output data and the `mark` describing that data.
105+
106+Below is an example of a `%say` generator. Save it to `add.hoon` in the `/gen`
107+directory.
108+
109+```hoon
110+:- %say
111+|= *
112+:- %noun
113+(add 40 2)
114+```
115+
116+Now run the generator as below:
117+
118+```
119+> +add
120+42
121+```
122+
123+Notice that we used no argument, something that is possible with `%say`
124+generators but impossible with naked generators. We'll explain that in a moment.
125+For now, let's focus on the code that is necessary to make something a `%say`
126+generator.
127+
128+```hoon
129+:- %say
130+```
131+
132+Recall that the rune `:-` produces a cell, with the first following expression
133+as its head and the second following expression as its tail.
134+
135+The expression above creates a cell with `%say` as the head. The tail is
136+the `|= *` expression on the line that follows.
137+
138+```hoon
139+|= *
140+:- %noun
141+(add 40 2)
142+```
143+
144+`|= *` constructs a [gate](/docs/glossary/gate/) that takes a noun. This [gate](/docs/glossary/gate/) will itself produce a
145+`cask`, which is cell formed by the prepending `:-`. The head of that `cask` is
146+`%noun` and the tail is the rest of the program, `(add 40 2)`. The tail of the
147+`cask` will be our actual data produced by the body of the program: in this
148+case, just adding 40 and 2 together.
149+
150+#### `%say` generators with arguments
151+
152+We can modify the boilerplate code to allow arguments to be passed into a `%say`
153+generator, but in a way that gives us more power than we would have if we just
154+used a naked generator.
155+
156+Naked generators are limited because they have no way of accessing data that
157+exists in Arvo, such as the date and time or pieces of fresh entropy. In `%say`
158+generators, however, we can access that kind of subject by identifying them
159+in the gate's sample, which we only specified as `*` in the previous few
160+examples. But we can do more with `%say` generators if we do more with that
161+sample. Any valid sample will follow this 3-tuple scheme:
162+
163+`[[now, eny, beak] [list of unnamed arguments] [list of named arguments]]`
164+
165+This entire structure is a noun, which is why `*` is a valid sample if we
166+wish to not use any of the information here in a generator. But let's look at
167+each of these three elements, piece by piece.
168+
169+The **first part** of the above 3-tuple is a noun that is composed of three
170+atoms:
171+
172+`now` is the current time.
173+`eny` is 512 bits of entropy for seeding random number generators.
174+`beak` contains the current ship, desk, and case.
175+
176+You can access each of those pieces of data by typing their names into the Dojo.
177+But in a generator, we need to put faces (variable names) onto that data so we
178+can easily use it in the program. We can do so like this:
179+
180+```hoon
181+|= [[now=@da eny=@uvJ bec=beak] ~ ~]
182+```
183+
184+Any of those pieces of data could be omitted by replacing part of the noun with
185+`*` rather than giving them faces. For example, `[now=@da * bec=beak]` if we
186+didn't want `eny`, or `[* * bec=beak]` if we only wanted `beak`.
187+
188+The **second part** of the sample is a `list` of arguments that _must_ be passed
189+to the generator as it is run. Because it's a `list`, this element needs to be
190+terminated with a `~`. In the example above, we used `~`, the empty list, to
191+represent this second part. But that would mean we don't want to use any new
192+faces for our generator. So a sample where we want to declare a single required
193+argument would look like this:
194+
195+```hoon
196+|= [* [n=@ud ~] ~]
197+```
198+
199+In the above code, we use a `*` to ignore any of the information that would go
200+in the first part of the sample, somewhat similar to how we use a `~` to say
201+"nothing here" for the second or third parts of the sample.
202+
203+But to use both parts together, our gate and sample would look like this:
204+
205+```hoon
206+|= [[now=@da eny=@uvJ bec=beak] [n=@ud ~] ~]
207+```
208+
209+The **third part** of the sample is a list of _optional_ arguments. These
210+arguments may be passed to the program as it's being run, but the program doesn't
211+require them. The syntax for the third part is just like the syntax for the
212+second part, besides its position:
213+
214+```hoon
215+|= [* ~ [bet=@ud ~]]
216+```
217+
218+Let's look at an example that uses all three parts. Save the code below in a
219+file called `dice.hoon` in your `/gen` directory.
220+
221+```hoon
222+:- %say
223+|= [[now=@da eny=@uvJ bec=beak] [n=@ud ~] [bet=@ud ~]]
224+:- %noun
225+[(~(rad og eny) n) bet]
226+```
227+
228+This is a very simple dice program with an optional betting functionality.
229+In the code, our sample specifies faces on all of the Arvo data, meaning that we
230+can easily access them. We also require the argument `[n=@ud ~]`, and allow the
231+_optional_ argument `[bet=@ud ~]`.
232+
233+But there's something new: `(~(rad og eny) n)`. This code pulls the `rad` [arm](/docs/glossary/arm/)
234+out of the `og` [core](/docs/glossary/core/) with the subject of `eny`. Recall that `eny` is our entropy
235+value, so this is used to seed the generator. The `rad` arm will give us a
236+pseudorandom number between 0 and `n`. Then we form a cell with the result and
237+`bet`, the optional named argument specified previously.
238+
239+We can run this generator like so:
240+
241+```
242+> +dice 6, =bet 2
243+[4 2]
244+
245+> +dice 6
246+[5 0]
247+
248+> +dice 6
249+[2 0]
250+
251+> +dice 6, =bet 200
252+[0 200]
253+
254+> +dice
255+nest-fail
256+```
257+
258+We get a different value from the same generator between runs, something that
259+isn't possible with a naked generator. Another novelty is the ability to choose
260+to not use the second argument.
261+
262+##### Arguments without a cell
263+
264+Also unlike a naked generator, we don't need to put our arguments together into
265+a cell. Swap the code below into your `add.hoon` file.
266+
267+```hoon
268+:- %say
269+|= [* [a=@ud b=@ud ~] ~]
270+:- %noun
271+(add a b)
272+```
273+
274+In the above code we're again creating a `%say` generator, but the sample of our
275+gate is a little different than before. We are using `*` for the first part of
276+the sample, because we don't use any Arvo data in this program. We are using a
277+`~` for the third part, because we aren't allowing optional arguments -- the
278+list of optional arguments is _empty_.
279+
280+Run a command like the one below in the Dojo. Notice that you can use two
281+arguments that aren't in the cells.
282+
283+```
284+> +add 40 2
285+42
286+```
287+
288+### `%ask` generators {#ask}
289+
290+We use the `%ask` generator when we want to create an interactive program
291+that prompts for inputs as it runs, rather than expecting arguments to be passed
292+in at the time of initiation.
293+
294+Code-wise, two things are needed to create a useful `%ask` generator.
295+
296+The first is **`sole-result`**, which lives in `/sur/sole.hoon`. It's a
297+mold-builder that's required by any part of Arvo, such as the Dojo, that wants
298+to understand the output of the `%ask` generator. Because it's the only type of
299+`%ask` data that is intelligible to the system, the ultimate output of an `%ask`
300+generator must be `sole-result`. You can think of it as a function that takes
301+molds and digests them into a type for the operating system. The simplest way to
302+use `sole-result` is by calling the `produce` gate from `/lib/generators.hoon`.
303+
304+The second is **`prompt`**, a gate that lives in `lib/generators.hoon`. `prompt`
305+allows you to get information back from the user, which is essential to the
306+typical desired operation of an `%ask` generator.
307+
308+Since this isn't easy to digest in the abstract, we'll use an example generator
309+to explain how this kind of generator works.
310+
311+##### `%ask` example
312+
313+The code below is an `%ask` generator that checks if the user inputs "blue" when
314+prompted. Save it as `axe.hoon` in `/gen`.
315+
316+```hoon
317+/- sole
318+/+ generators
319+=, [sole generators]
320+:- %ask
321+|= *
322+^- (sole-result (cask tang))
323+%+ print leaf+"What is your favorite color?"
324+%+ prompt [%& %prompt "color: "]
325+|= t=tape
326+%+ produce %tang
327+?: =(t "blue")
328+ :~ leaf+"Oh. Thank you very much."
329+ leaf+"Right. Off you go then."
330+ ==
331+:~ leaf+"Aaaaagh!"
332+ leaf+"Into the Gorge of Eternal Peril with you!"
333+==
334+```
335+
336+Run the generator from the Dojo:
337+
338+```
339+> +axe
340+What is your favorite color?
341+: color:
342+```
343+
344+Something new happened. Instead of simply returning something, your Dojo's
345+prompt changed from `~your-urbit:dojo>` to `~your-urbit:dojo: color:`, and
346+now expects additional input. Let's give it an input:
347+
348+```
349+: color: red
350+Into the Gorge of Eternal Peril with you!
351+Aaaaagh!
352+```
353+
354+Let's go over what exactly is happening in this code.
355+
356+```hoon
357+/- sole
358+/+ generators
359+=, [sole generators]
360+```
361+
362+Here we bring in some of the types we are going to need from `/sur/sole` and
363+gates we will use from `/lib/generators`. We use some special runes for this.
364+
365+`/-` is a Ford rune used to import types from `sur`.
366+
367+`/+` is a Ford rune used to import libraries from `lib`.
368+
369+`=,` is a rune that allows us to expose a namespace. We do this to avoid having
370+to write `sole-result:sole` instead of `sole-result` or `print:generators`
371+instead of `print`.
372+
373+```hoon
374+:- %ask
375+|= *
376+```
377+
378+This code might be familiar. Just as with their `%say` cousins, `%ask`
379+generators need to produce a `cell`, the head of which specifies what kind of
380+generator we are running.
381+
382+With `|= *`, we create a gate and ignore the standard arguments we are given,
383+because we're not using them.
384+
385+```hoon
386+^- (sole-result (cask tang))
387+```
388+
389+`%ask` generators need to have the second half of the cell be a gate that
390+produces a `sole-result`, one that in this case contains a `cask` of `tang`.
391+We use the `^-` rune to constrain the generator's output to such a
392+`sole-result`.
393+
394+A `cask` is a pair of a `mark` name and a noun. Recall that a `mark` can be
395+thought of as an Arvo-level MIME type for data.
396+
397+A `tang` is a `list` of `tank`, and a `tank` is a structure for printing data.
398+There are three types of `tank`: `leaf`, `palm`, and `rose`. A `leaf` is for
399+printing a single noun, a `rose` is for printing rows of data, and a `palm` is
400+for printing backstep-indented lists.
401+
402+```hoon
403+%+ print leaf+"What is your favorite color?"
404+%+ prompt [%& %prompt "color: "]
405+|= t=tape
406+%+ produce %tang
407+```
408+
409+Because we imported `generators`, we can access its contained gates, three of
410+which we use in `axe.hoon`: `print`, `prompt`, and `produce`.
411+
412+**`print`** is used for printing a `tank` to the console.
413+
414+In our example, `%+` is the rune to call a gate, and our gate `print` takes one
415+argument which is a `tank` to print. The `+` here is syntactic sugar for
416+`[%leaf "What is your favorite color?"]` that just makes it easier to write.
417+
418+**`prompt`** is used to construct a prompt for the user to provide input.
419+It takes a single argument that is a tuple. Most `%ask` generators will want to
420+use the `prompt` gate.
421+
422+The first element of the `prompt` sample is a flag that indicates whether what
423+the user typed should be echoed out to them or hidden. `%&` will produce echoed
424+output and `%|` will hide the output (for use in passwords or other secret
425+text).
426+
427+The second element of the `prompt` sample is intended to be information for use
428+in creating autocomplete options for the prompt. This functionality is not yet
429+implemented.
430+
431+The third element of the `prompt` sample is the `tape` that we would like to
432+use to prompt the user. In the case of our example, we use `"color: "`.
433+
434+**`produce`** is used to construct the output of the generator. In our example,
435+we produce a `tang`.
436+
437+
438+```hoon
439+|= t=tape
440+```
441+
442+Our gate here takes a `tape` that was produced by `prompt`. If we needed
443+another type of data we could use `parse` to obtain it.
444+
445+The rest of this generator should be intelligible to those with Hoon knowledge
446+at this point.
447+
448+One quirk that you should be aware of, though, is that `tang` prints in reverse
449+order from how it is created. The reason for this is that `tang` was originally
450+created to display stack trace information, which should be produced in reverse
451+order. This leads to an annoyance: we either have to specify our messages
452+backwards or construct them in the order we want and then `flop` the `list`.
453+This is a [known issue](https://github.com/urbit/arvo/issues/840) to be resolved.
454+
455+### `%get` generators
456+
457+`%get` generators no longer exist. They were once used for making HTTP requests through `eyre`. Such functionality is no longer supported with generators.
458+
459+## Conclusion
460+
461+You've now reached the end of Chapter 1 of the Hoon tutorial. Ideally you should have a fair understanding of the fundamental concepts of subject-oriented programming: limbs, legs, faces, wings, arms, cores, gates, and [doors](/docs/glossary/door/). If you can master these concepts you should have little or no trouble learning to write substantial Hoon programs.
content/docs/hoon/hoon-school/hoon-syntax.mdnew file+356
@@ -0,0 +1,356 @@
1++++
2+title = "1.3 Hoon Syntax"
3+weight = 4
4+template = "doc.html"
5+aliases = ["/docs/learn/hoon/hoon-tutorial/hoon-syntax/"]
6++++
7+
8+The study of Hoon can be divided into two parts: syntax and semantics.
9+
10+The [syntax](https://en.wikipedia.org/wiki/Syntax_%28programming_languages%29 ) of a programming language is the set of rules that determine what counts as admissible code in that language. It determines which characters may be used in the source, and also how these characters may be assembled to constitute a program. Attempting to run a program that doesn’t follow these rules will result in a syntax error.
11+
12+The [semantics](https://en.wikipedia.org/wiki/Semantics_%28computer_science%29 ) of a programming language concerns the meaning of the various parts of that language’s code.
13+
14+In this lesson we will give a general overview of Hoon’s syntax. By the end of it, you should be familiar with all the basic elements of Hoon code.
15+
16+## Hoon Characters
17+
18+Hoon source files are composed almost entirely of the [printable ASCII characters](https://en.wikipedia.org/wiki/ASCII%23Printable_characters). Hoon does not accept any other characters in source files except for [UTF-8](https://en.wikipedia.org/wiki/UTF-8) in quoted strings. Hard tab characters are illegal; use two spaces instead.
19+
20+```
21+> "You can put ½ in quotes, but not elsewhere!"
22+"You can put ½ in quotes, but not elsewhere!"
23+
24+> 'You can put ½ in single quotes, too.'
25+'You can put ½ in single quotes, too.'
26+
27+> "Some UTF-8: ἄλφα"
28+"Some UTF-8: ἄλφα"
29+```
30+
31+### Reading Hoon Aloud
32+
33+Hoon code makes heavy use of non-alphanumeric symbols. Reading off code aloud using the proper names of ASCII symbols is tedious, so we’ve mapped syllables to symbols:
34+
35+```
36+ace [1 space] gap [>1 space, nl] pat @
37+bar | gar > sel [
38+bas \ hax # ser ]
39+buc $ hep - sig ~
40+cab _ kel { soq '
41+cen % ker } tar *
42+col : ket ^ tic `
43+com , lus + tis =
44+doq " mic ; wut ?
45+dot . pal ( zap !
46+fas / pam &
47+gal < par )
48+```
49+
50+Learning and using these names of non-alphanumeric symbols is entirely optional; you can become an expert Hoon programmer without them. Many Hoon programmers find them helpful, however, particularly when talking to someone else who knows them.
51+
52+Note that the list includes two separate whitespace forms: `ace` for a single space; `gap` is either 2+ spaces or a newline. In Hoon, the only whitespace significance is the distinction between `ace` and `gap` -- i.e., the distinction between one space and more than one.
53+
54+## Expressions of Hoon
55+
56+An [expression](https://en.wikipedia.org/wiki/Expression_%28computer_science%29 ) is a combination of characters that the language interprets and evaluates as producing a value. Hoon programs are made up entirely of expressions.
57+
58+Hoon expressions can be either basic or complex. Basic expressions of Hoon are fundamental, meaning that they can’t be broken down into smaller expressions. Complex expressions are made up of smaller expressions (which are called **subexpressions**).
59+
60+There are many categories of Hoon expressions: [noun](/docs/glossary/noun/) literals, wing expressions, type expressions, and rune expressions. Let’s go over each.
61+
62+### Noun Literals
63+
64+A noun is either an [atom](/docs/glossary/atom/) or a cell. An [atom](/docs/glossary/atom/) is an unsigned integer and a cell is a pair of nouns.
65+
66+There are [literal](https://en.wikipedia.org/wiki/Literal_%28computer_programming%29 ) expressions for each kind of noun. A noun literal is just a notation for representing a fixed noun value.
67+
68+We start with atom literals. Each of these is a basic expression of Hoon that evaluates to itself. Examples:
69+
70+```
71+> 1
72+1
73+
74+> 123
75+123
76+
77+> 123.456
78+123.456
79+
80+> 'hello'
81+'hello'
82+
83+> ~zod
84+~zod
85+```
86+
87+Recall from [Lesson 1.2](/docs/hoon/hoon-school/nouns) that even though atoms are unsigned integers, they can be pretty-printed in different ways. The way an atom is to be represented depends on its aura. The literal syntax for each of the hard-coded auras will be explained further in [Lesson 2.1](/docs/hoon/hoon-school/atoms-auras-and-simple-cell-types).
88+
89+Cell literals can be written in Hoon using `[ ]`. Cell literals are complex, because other expressions are put inside the square brackets. Examples:
90+
91+```
92+> [6 7]
93+[6 7]
94+
95+> [[12 14] [654 123.456 980]]
96+[[12 14] 654 123.456 980]
97+
98+> ['hello' 0xdad]
99+['hello' 0xdad]
100+
101+> [123 [~zod ~ten] .1.2837]
102+[123 [~zod ~ten] .1.2837]
103+```
104+
105+You can also put complex expressions inside square brackets to make a cell. These are valid expressions but they aren’t cell literals, naturally:
106+
107+```
108+> [(add 22 33) (mul 22 33)]
109+[55 726]
110+```
111+
112+### Wings
113+
114+A wing expression is a series of limb expressions separated by `.`. A deeper explanation can be found on the [wing](/docs/hoon/reference/limbs/wing) and [limb](/docs/hoon/reference/limbs/limb) reference pages.
115+
116+Let’s start with the base case: a single limb. A limb expression is a trivial wing expression -- there is only one limb in the series. Some one-limb wings:
117+
118+- `+2`
119+- `-`
120+- `+>`
121+- `&4`
122+- `a`
123+- `b`
124+- `add`
125+- `mul`
126+
127+As a special limb we also have `$`. This is the name of the [arm](/docs/glossary/arm/) in special one-armed [cores](/docs/glossary/core/) called “gates”. (We’ll cover the role of `$` in [Lesson 1.4](/docs/hoon/hoon-school/gates).)
128+
129+Wing expressions with multiple limbs are complex expressions. Examples:
130+
131+- `+2.+3.+4`
132+- `-.+.+`
133+- `resolution.path.into.subject`
134+- `+>.$`
135+- `a.b.c`
136+- `-.b.+2`
137+- `-.add`
138+
139+
140+### Type Expressions
141+
142+Hoon is a statically typed language. You’ll learn more about the type system later in the chapter. For now, just know that Hoon’s type system uses special symbols to indicate certain fundamental types: `~` (null), `*` (noun), `@` (atom), `^` (cell), and `?` (flag). Each of these symbols can be used as a stand-alone expression of Hoon. In the case of `@` there may be a series of letters following it, to indicate an atom aura; e.g., `@s`, `@rs`, `@tas`, and `@tD`.
143+
144+They may also be put in brackets to indicate compound types, e.g., `[@ ^]`, `[@ud @sb]`, `[[? *] ^]`. (Technically these expressions don’t _always_ indicate compound types. In certain contexts they’re interpreted in a different way. We’ll address this variation of meaning in [Lesson 2.3](/docs/hoon/hoon-school/structures-and-complex-types).)
145+
146+### Rune Expressions
147+
148+A **rune** is just a pair of ASCII characters (a digraph). You’ve already seen some runes in Chapter 1: `|=`,`|%`, and `|_`. We usually pronounce runes by combining their characters’ names, e.g.: “ket-hep” for `^-`, “bar-tis” for `|=`, and “bar-cen” for `|%`. As stated previously, these names are entirely optional.
149+
150+Expressions with a rune at the beginning are rune expressions. Most runes are used at the beginning of a complex expression, but there are exceptions. For example, the runes `--` and `==` are used at the end of certain expressions.
151+
152+Runes are classified by family (with the exceptions of `--` and `==`). The first of the two symbols indicates the family -- e.g., the `^-` rune is in the `^` family of runes, and the `|=` and `|%` runes are in the `|` family. The runes of particular family usually have related meanings. Two simple examples: the runes in the `|` family are all used to create cores, and the runes in the `:` family are all used to create cells.
153+
154+Rune expressions are usually complex, which means they usually have one or more subexpressions. The appropriate syntax varies from rune to rune; after all, they’re used for different purposes. To see the syntax rules for a particular rune, consult the [rune reference](/docs/hoon/reference/rune/). Nevertheless, there are some general principles that hold of all rune expressions.
155+
156+Runes generally do not need to be closed. In other languages you’ll see an abundance of terminators, such as opening and closing parentheses, and this way of doing this is largely absent from Urbit. That’s because all runes take a fixed number of children. Children can themselves be runes (with more children), and Hoon programs work by chaining through these series of children until a value -- not another rune -- is arrived at. This makes Hoon code nice and neat to look at.
157+
158+#### Tall and Wide Forms
159+
160+There are two rune syntax forms: **tall** and **wide**. Tall form is usually used for multi-line expressions, and wide form is used for one-line expressions. Most runes can be used in either of tall or wide forms. Tall form expressions may contain wide form subexpressions, but wide form expressions may not contain tall form.
161+
162+The spacing rules differ in the two forms. In tall form, each rune and subexpression must be separated from the others by a `gap` -- that is, by two or more spaces, or a line break. In wide form the rune is immediately followed by parentheses `( )`, and the various subexpressions inside the parentheses must be separated from the others by an `ace` -- that is, by a single space.
163+
164+Seeing an example will help you understand the difference. The `:-` rune is used to produce a cell. Accordingly, it is followed by two subexpressions: the first defines the head of the cell, and the second defines the tail. Here are three different ways to write a `:-` expression in tall form:
165+
166+```
167+> :- 11 22
168+[11 22]
169+
170+> :- 11
171+ 22
172+[11 22]
173+
174+> :-
175+ 11
176+ 22
177+[11 22]
178+```
179+
180+These all do the same thing. The first example shows that, if you want to, you can write tall form code on a single line. Notice that there are two spaces between the `:-` rune and `11`, and also between `11` and `22`. This is the minimum spacing necessary between the various parts of a tall form expression -- any fewer will result in a syntax error.
181+
182+Usually one or more line breaks are used to break up a tall form expression. This is especially useful when the subexpressions are themselves long stretches of code. The same `:-` expression in wide form is:
183+
184+```
185+> :-(11 22)
186+[11 22]
187+```
188+
189+This is the preferred way to write an expression on a single line. The rune itself is followed by a set of parentheses, and the subexpressions inside are separated by a single space. Any more spacing than that results in a syntax error.
190+
191+Nearly all rune expressions can be written in either form, but there are exceptions. `|%` and `|_` expressions, for example, can only be written in tall form. (Those are a bit too complicated to fit comfortably on one line anyway.)
192+
193+#### Nesting Runes
194+
195+Since runes take a fixed number of children, one can visualize how Hoon expressions are built by thinking of each rune being followed by a series of boxes to be filled -- one for each of its children. Let us illustrate this with the `:-` rune.
196+
197+![](https://media.urbit.org/docs/hoon-syntax/cell1.png)
198+
199+Here we have drawn the `:-` rune followed by a box for each of its two children. We can fill these boxes with either a value or an additional rune. The following figure corresponds to the Hoon expression `:- 2 3`.
200+
201+![](https://media.urbit.org/docs/hoon-syntax/cell2.png)
202+
203+This, of course, evaluates to the cell `[2 3]`. This next figure corresponds to the Hoon expression `:- :- 2 3 4`.
204+
205+![](https://media.urbit.org/docs/hoon-syntax/cell3.png)
206+
207+This evaluates to `[[2 3] 4]`, and we can think of the second `:-` as being “nested” inside of the first `:-`.
208+
209+What Hoon expression does the following figure correspond to, and what does it evaluate to?
210+
211+![](https://media.urbit.org/docs/hoon-syntax/cell4.png)
212+
213+Right. This represents the Hoon expression `:- 2 :- 3 4`,
214+and evaluates to `[2 [3 4]]`. Remember, though, that if you input this into dojo it will print as `[2 3 4]`.
215+
216+Thinking in terms of these “LEGO block” diagrams, as well as the more literal binary tree diagrams utilized in [Lesson 1.2](/docs/hoon/hoon-school/nouns), can be a helpful learning and debugging tactic.
217+
218+##### Exercise 1.3a
219+
220+Draw binary trees corresponding to the above figures. Determine a one-to-one correspondence between linearly ordered nested boxes (i.e. what is depicted in the above figures) and binary trees. You will need to make use of the convention `[a [b c]] = [a b c]`.
221+
222+#### Irregular Forms
223+
224+Some runes are used so frequently that they have irregular counterparts that are easier to write and which mean precisely the same thing. Irregular rune syntax is hence a form of [syntactic sugar](https://en.wikipedia.org/wiki/Syntactic_sugar). All irregular rune syntax is wide. (It follows from this that all tall form expressions are regular.)
225+
226+Let’s look at another example. The `.=` rune takes two subexpressions, evaluates them, and tests the results for equality. If they’re equal it produces `%.y` for “yes”; otherwise `%.n` for “no”. In tall form:
227+
228+```
229+> .= 22 11
230+%.n
231+
232+> .= 22
233+ (add 11 11)
234+%.y
235+```
236+
237+And in wide form:
238+
239+```
240+> .=(22 11)
241+%.n
242+
243+> .=(22 (add 11 11))
244+%.y
245+```
246+
247+The irregular form of the `.=` rune is just `=( )`:
248+
249+```
250+> =(22 11)
251+%.n
252+
253+> =(22 (add 11 11))
254+%.y
255+```
256+
257+The examples above have another irregular form: `(add 11 11)`. This is the irregular form of `%+`, which calls a [gate](/docs/glossary/gate/) (i.e., a Hoon function) with two arguments for the sample.
258+
259+```
260+> %+ add 11 11
261+22
262+
263+> %+(add 11 11)
264+22
265+```
266+
267+The irregular `( )` gate-calling syntax is versatile -- it is also a shortcut for calling a gate with one argument, which is what the `%-` rune is for:
268+
269+```
270+> (dec 11)
271+10
272+
273+> %- dec 11
274+10
275+
276+> %-(dec 11)
277+10
278+```
279+
280+The `( )` gate-calling syntax can be used for gates with any number of arguments.
281+
282+You can find other irregular forms in the irregular expression [reference document](/docs/hoon/reference/irregular).
283+
284+### Expressions That Are Only Irregular
285+
286+There are certain irregular expressions that aren’t syntactic sugar for regular form equivalents -- they’re solely irregular. There isn’t much in general that can be said about these because they’re all different, but we can look at some examples.
287+
288+Below we use the `` ` `` symbol to create a cell whose head is null, `~`.
289+
290+```
291+> `12
292+[~ 12]
293+
294+> `[[12 14] 16]
295+[~ [12 14] 16]
296+```
297+
298+Putting `,.` in front of a wing expression removes a face, if there is one.
299+
300+```
301+> -:[a=[12 14] b=[16 18]]
302+a=[12 14]
303+
304+> ,.-:[a=[12 14] b=[16 18]]
305+[12 14]
306+
307+> ,.-:[[12 14] b=[16 18]]
308+[12 14]
309+
310+> +:[a=[12 14] b=[16 18]]
311+b=[16 18]
312+
313+> ,.+:[a=[12 14] b=[16 18]]
314+[16 18]
315+```
316+
317+To see other irregular expressions, check the irregular expression [reference document](/docs/hoon/reference/irregular).
318+
319+
320+## The Standard Library
321+
322+The Hoon standard library is a compilation of generally useful Hoon gates (functions). You’ve seen these already: in expressions like `(add 11 11)`, `add` is a function from the standard library.
323+
324+It’s important to know about standard library functions, because they make certain tasks much easier, and spare you from having to write the code itself. If you did not use the `add` library function, for example, you would have to write out code like this every time you wanted to find the sum of two numbers:
325+
326+```hoon
327+++ add
328+ ~/ %add
329+ |= [a=@ b=@]
330+ ^- @
331+ ?: =(0 a) b
332+ $(a (dec a), b +(b))
333+```
334+
335+Standard library functions are often built with other standard library functions, but ultimately those functions used are only built with runes. Notice how in the code above `add` is built with the `dec` function, which decrements a value by `1`.
336+
337+## Reference Materials
338+
339+The Hoon syntax can be intimidating for the uninitiated, so it’s good to remember where you can look up expressions. The [Reference](/docs/hoon/reference/) section itself is a good place to find the materials that you need. These children sections are likely to be useful:
340+
341+- The [Runes](/docs/hoon/reference/rune/) page will show you how to use any Hoon rune.
342+- The [Cheat Sheet](/docs/hoon/reference/cheat-sheet) is a more compact place to look up rune expressions.
343+- The [Standard Library](/docs/hoon/reference/stdlib/table-of-contents) section has its sub-pages arranged by category. So arithmetic functions, for example, are all found on the same page.
344+- The [Hoon Style Guide](/docs/hoon/reference/style) will show you how to write your Hoon code so that it’s idiomatic and easily understood by others.
345+
346+### Debugging
347+
348+When you have an error in your Hoon code, one of two things can happen. Either the code does not run at all and you get an error (such as `nest-fail`), or your code _does_ run but produces the wrong results. The [Troubleshooting](/docs/hoon/reference/hoon-errors) page is a good resource for figuring out how to debug your code.
349+
350+There are a couple useful runes associated with debugging:
351+
352+`!:` (zapcol), if written at the top of a Hoon file, turns on a full debugging stack-trace. It’s good practice to use whenever you’re learning.
353+
354+`~&` (sigpam) is used to print its argument every time that argument executes. So, if you wanted to see how many times your program executed `foo`, you would write `foo bar`. Then, when your program runs, it will print `foo` on a new line of output every time the program comes across it by recursion.
355+
356+But there are more. Check out the aforementioned [Troubleshooting](/docs/hoon/reference/hoon-errors) page to see other handy debugging runes and how to use them.
content/docs/hoon/hoon-school/iron-polymorphism.mdnew file+88
@@ -0,0 +1,88 @@
1++++
2+title = "2.5.1 Walkthrough: Iron Polymorphism and Wet Polymorphism"
3+weight = 32
4+template = "doc.html"
5+aliases = ["/docs/learn/hoon/hoon-tutorial/iron-polymorphism/"]
6++++
7+
8+Polymorphism is a programming concept that allows a piece of code to use different types at different times. It's a common technique in most languages to make code that can be reused for many different situations, and Hoon is no exception. Let's take a look at a [gate](/docs/glossary/gate/) from the Hoon standard library as an example; we'll be passing a few different types in. The code below is an excerpt from `hoon.hoon` and, as such, will not run as-is by itself.
9+
10+`fold` is a _wet_ gate that takes two arguments and produces a _dry_ gate. But what are wet and dry gates?
11+
12+A dry gate (also simply a _gate_) is the kind that you're already familiar with by now: a one-armed [core](/docs/glossary/core/) with a sample. A wet gate is also a one-armed [core](/docs/glossary/core/) with a sample, but there is a difference. With a dry gate, when you pass in an argument and the code gets compiled, the type system will try to cast to the type specified by the gate; if you pass something that does not fit in the specified type, for example a `cord` instead of a `cell` you will get a nest failure. On the other hand, when you pass arguments to a wet gate, their types are preserved and type analysis is done at the definition site of the gate -- in our case, `fold` in `hoon.hoon` -- rather than the call site.
13+
14+```hoon
15+++ fold
16+ |* [state=mold elem=mold]
17+ |= [[st=state xs=(list elem)] f=$-([state elem] state)]
18+ ^- state
19+ |-
20+ ?~ xs st
21+ $(xs t.xs, st (f st i.xs))
22+```
23+
24+On the first line of the [arm](/docs/glossary/arm/), we use `|*` to create a wet gate, with two arguments: `state` and `elem`. These arguments are both `mold`s; that is to say, they are type definitions. We use this to define the types used in the dry gate.
25+
26+```hoon
27+|= [[st=state xs=(list elem)] f=$-([state elem] state)]
28+```
29+
30+Here we begin to define our dry gate. The first thing the dry gate takes is a cell, `[st=state xs=(list elem)]`. `state` is the type we passed in first to our wet gate, and will be the type that is produced by the dry gate. `st` is a value of type `state` that will be used as an accumulator, and will be the final value returned when the dry gate is called.
31+
32+The second argument is `f=$-([state elem] state)`. `$-` is a rune that takes two type arguments, `[state elem]` and `state` in this case, and produces a `mold` of a gate that maps from the first type operand to the second. This will match a gate we provide `fold` for how to map from both the `state`.
33+
34+The rest of the dry gate is straightforward:
35+
36+```hoon
37+ ^- state
38+ |-
39+ ?~ xs st
40+ $(xs t.xs, st (f st i.xs))
41+```
42+
43+We ensure the output is of type `state`. Then we check if `xs`, the list, is empty. If it is, we return `st`. Otherwise, we call `f` on `i.xs`, the head of the list, and set `xs` to be the tail of the list and repeat.
44+
45+Lets look at two examples of using `fold`.
46+
47+```hoon
48+%+ (fold (list @) @)
49+ :- ~
50+ ~[1 2 3 4]
51+|= [s=(list @) e=@]
52+:_ s
53+(add 2 e)
54+```
55+
56+Here we have a call to `fold` that we can see will produce a `(list @)` from a list of `@`. The first argument is a cell of `~` and `~[1 2 3 4]`.
57+
58+
59+The gate will simply add two to each element `e` and append that to the front of `s`. Let's run this in the `dojo`:
60+
61+```hoon
62+> %+ (fold (list @) @)
63+ :- ~
64+ ~[1 2 3 4]
65+ |= [s=(list @) e=@]
66+ :_ s
67+ (add 2 e)
68+~[6 5 4 3]
69+
70+~zod:dojo>
71+```
72+
73+The list is in reverse order simply because it's easier to add to the front of a list than the end. If you needed it in the same order, you could just `flop` it.
74+
75+But `fold` does not have to produce a `list`. Let's look at another example:
76+
77+
78+```hoon
79+%+ (fold @ @)
80+ [0 ~[1 2 3 4]]
81+|= [s=@ e=@]
82+(add e s)
83+```
84+
85+
86+Here `fold` will produce a gate that takes an `atom` and applies a gate to a `list` of `atoms`. The difference here is that this call will produce a sum of the elements of the list, rather than the list itself.
87+
88+The key takeaway from both of these examples is that the gates provided are _iron polymorphic_ with respect to the definition of the type in `fold`. They are iron polymorphic because samples `s` and `e` nest under the types `state` and `elem`. In second case case, that's because when we provided those to `fold`, it was was stated they were `@` and `@`. In the first case, we stated that `state` was `(list @)` and `elem` was `@`. In both cases, the sample of each gate nest inside the types defined when we called the wet gate `fold`.
content/docs/hoon/hoon-school/lead-polymorphism.mdnew file+155
@@ -0,0 +1,155 @@
1++++
2+title = "2.5.2 Walkthrough: Lead Polymorphism"
3+weight = 33
4+template = "doc.html"
5+aliases = ["/docs/learn/hoon/hoon-tutorial/lead-polymorphism/"]
6++++
7+
8+There are four kinds of [cores](/docs/glossary/core/): gold, iron, zinc, and lead. You are able to use core-variance rules to create programs which take other programs as arguments. Which particular rules depends on which kind of core your program needs to complete.
9+
10+Lead cores have opaque [payloads](/docs/glossary/payload/). That is, the payload can not be written to or read from. Below is an example of using lead cores. The program produces a list populated by the first 10 elements of `fib`.
11+
12+```hoon
13+=< (to-list (take fib 10))
14+|%
15+++ stream
16+ |* of=mold
17+ $_ ^? |.
18+ ^- $@(~ [item=of more=^$])
19+ ~
20+++ stream-type
21+ |* s=(stream)
22+ $_ => (s)
23+ ?~ . !!
24+ item
25+++ to-list
26+ |* s=(stream)
27+ %- flop
28+ =| r=(list (stream-type s))
29+ |- ^+ r
30+ =+ (s)
31+ ?~ - r
32+ %= $
33+ r [item r]
34+ s more
35+ ==
36+++ take
37+ |* [s=(stream) n=@]
38+ =| i=@
39+ ^+ s
40+ |.
41+ ?: =(i n) ~
42+ =+ (s)
43+ ?~ - ~
44+ :- item
45+ %= ..$
46+ i +(i)
47+ s more
48+ ==
49+++ fib
50+ ^- (stream @ud)
51+ =+ [p=0 q=1]
52+ |. :- q
53+ %= .
54+ p q
55+ q (add p q)
56+ ==
57+--
58+```
59+
60+There are five [arms](/docs/glossary/arm/) in this core: `stream`, `stream-type`, `to-list`, `take`, and `fib`.
61+
62+
63+```hoon
64+++ stream
65+ |* of=mold
66+ $_ ^? |.
67+ ^- $@(~ [item=of more=^$])
68+ ~
69+```
70+
71+`stream` is a mold-builder. It's a wet gate that takes one argument, `of`, which is a `mold`, and produces a [trap](/docs/glossary/trap/) -- a function with no argument.
72+
73+`$_` is a rune that produces a type from an example; `^?` converts (casts) a core to lead; `|.` forms the trap. So to follow this sequence we read it backwards: we create a trap, convert it to a lead trap (making its payload inaccessible), and then use that lead trap as an example to produce a type from.
74+
75+With the line `^- $@(~ [item=of more=^$])`, the output of the trap will be cast into a new type. `$@` is the rune to describe a data structure that can either be an [atom](/docs/glossary/atom/) or a cell. The first part describes the [atom](/docs/glossary/atom/), which here is going to be `~`. The second part describes a cell, which we define to have the head of type `of` with the face `item`, and a tail with a face of `more`. The expression `^$` is not a rune, but rather a reference to the enclosing wet [gate](/docs/glossary/gate/), so the tail of this cell will be of the same type produced by this wet [gate](/docs/glossary/gate/).
76+
77+The final `~` here is used as the type produced when initially calling this wet gate. This is valid because it nests within the type we defined on the previous line.
78+
79+Now you can see that a `stream` is either `~` or a pair of a value of some type and a `stream`. This type represents an infinite series.
80+
81+```hoon
82+++ stream-type
83+ |* s=(stream)
84+ $_ => (s)
85+ ?~ . !!
86+ item
87+```
88+
89+`stream-type` is a wet gate that produces the type of items stored in the `stream` arm. The `(stream)` syntax is a shortcut for `(stream *)`; a stream of some type.
90+
91+Calling a `stream`, which is a trap, will either produce `item` and `more` or it will produce `~`. If it does produce `~`, the `stream` is empty and we can't find what type it is, so we simply crash with `!!`.
92+
93+```hoon
94+++ take
95+ |* [s=(stream) n=@]
96+ =| i=@
97+ ^+ s
98+ |.
99+ ?: =(i n) ~
100+ =+ (s)
101+ ?~ - ~
102+ :- item
103+ %= ..$
104+ i +(i)
105+ s more
106+ ==
107+```
108+
109+We're going to skip over `to-list` and examine `take` first. `take` is another wet gate. This time it takes a `stream` `s` and an atom `n`. We add an atom to the subject and then make sure that the trap we are creating is going to be of the same type as `s`, the `stream` we passed in.
110+
111+If `i` and `n` are equal, the trap will produce `~`. Otherwise, `s` is called and has its result put on the front of the subject. If its value is `~`, then the trap again produces `~`. Otherwise the trap produces a cell of `item`, the first part of the value of `s`, and a new trap that increments `i`, and sets `s` to be the `more` trap which produces the next value of the `stream`. The result here is a `stream` that will only ever produce `n` items, even if the stream otherwise would have been infinite.
112+
113+```hoon
114+++ to-list
115+ |* s=(stream)
116+ %- flop
117+ =| r=(list (stream-type s))
118+ |- ^+ r
119+ =+ (s)
120+ ?~ - r
121+ %= $
122+ r [item r]
123+ s more
124+ ==
125+```
126+
127+Now with that in hand, let's go back to `to-list`. It's also a wet gate that takes `s`, a `stream`, only here it will, as you might expect, produce a `list`. The rest of this wet gate is straightforward, but we can examine it quickly anyway. As is the proper style, this list that is produced will be reversed, so `flop` is used to put it in the order it is in the stream. Recall that adding to the front of a list is cheap, while adding to the back is expensive.
128+
129+`r` is added to the subject as an empty `list` of whatever type is produced by `s`. A new trap is formed and called, and it will produce the same type as `r`. Then `s` is called and has its value added to the subject. If the result is `~`, the trap produces `r`. Otherwise, we want to call the trap again, adding `item` to the front of `r` and changing `s` to `more`. Now the utility of `take` should be clear. We don't want to feed `to-list` an infinite stream as it would never terminate.
130+
131+```hoon
132+++ fib
133+ ^- (stream @ud)
134+ =+ [p=0 q=1]
135+ |. :- q
136+ %= .
137+ p q
138+ q (add p q)
139+ ==
140+```
141+
142+The final arm in our core is `fib`, which is a `stream` of `@ud` and therefore an iron core. It's subject contains `p` and `q`, which will not be accessible outside of this trap. The product of the trap is a pair of an `@ud` and the trap that will produce the next `@ud` in the Fibonacci series.
143+
144+
145+```hoon
146+=< (to-list (take fib 10))
147+```
148+
149+Finally, the first line of our program will take the first 10 elements of `fib` and produce them as a list.
150+
151+```
152+~[1 1 2 3 5 8 13 21 34 55]
153+```
154+
155+This example is a bit overkill for simply calculating the Fibonacci series, but it nicely illustrates how you might use iron cores. Instead of `fib`, you could have any `stream` that produces some stream of values and you'd still be able to use the `take`, `to-list`, and `stream-type` arms.
content/docs/hoon/hoon-school/libraries.mdnew file+191
@@ -0,0 +1,191 @@
1++++
2+title = "2.3.1 Walkthrough: Libraries"
3+weight = 28
4+template = "doc.html"
5+aliases = ["/docs/learn/hoon/hoon-tutorial/libraries/"]
6++++
7+
8+In Hoon, like in other languages, it's often useful to create a library for other code to access. In this example, we look at one example of a library that can be used to represent a deck of 52 playing cards. The [core](/docs/glossary/core/) below builds such a library, and can be accessed by programs.
9+
10+```hoon
11+|%
12++$ suit ?(%hearts %spades %clubs %diamonds)
13++$ darc [sut=suit val=@ud]
14++$ deck (list darc)
15+++ make-deck
16+ ^- deck
17+ =| mydeck=deck
18+ =/ i 1
19+ |-
20+ ?: (gth i 4)
21+ mydeck
22+ =/ j 2
23+ |-
24+ ?. (lte j 13)
25+ ^$(i +(i))
26+ %= $
27+ j +(j)
28+ mydeck [(num-to-suit i) j]^mydeck
29+ ==
30+++ num-to-suit
31+ |= val=@ud
32+ ^- suit
33+ ?+ val !!
34+ %1 %hearts
35+ %2 %spades
36+ %3 %clubs
37+ %4 %diamonds
38+ ==
39+++ shuffle-deck
40+ |= [unshuffled=deck entropy=@]
41+ ^- deck
42+ =| shuffled=deck
43+ =/ random ~(. og entropy)
44+ =/ remaining (lent unshuffled)
45+ |-
46+ ?: =(remaining 1)
47+ :_ shuffled
48+ (snag 0 unshuffled)
49+ =^ index random (rads:random remaining)
50+ %= $
51+ shuffled (snag index unshuffled)^shuffled
52+ remaining (dec remaining)
53+ unshuffled (oust [index 1] unshuffled)
54+ ==
55+++ draw
56+ |= [n=@ud d=deck]
57+ ^- [hand=deck rest=deck]
58+ :- (scag n d)
59+ (slag n d)
60+--
61+```
62+
63+On the very first line, we create a core with `|%`. This core contains all of our library code, and is closed by the `--` on the final line.
64+
65+To create three types we're going to need, we use `+$`, which is an [arm](/docs/glossary/arm/) used to define a type.
66+
67+
68+```hoon
69++$ suit ?(%hearts %spades %clubs %diamonds)
70++$ darc [sut=suit val=@ud]
71++$ deck (list darc)
72+```
73+
74+The first is `suit`, which can be either `%hearts`, `%spades`, `%clubs`, or `%diamonds`.
75+
76+Next is a `darc`, which which is a pair of `suit` and a `@ud`. By pairing a suit and a number, it forms a particular card, such as "nine of hearts." Why do we call it `darc` and not `card`? Because `card` already has a meaning in gall, the Arvo app module, where one would likely to use this (or any) library. It's worthwhile to avoid any confusion over names.
77+
78+Our final type is `deck`, which is simply a `list` of `darc`.
79+
80+One way to get a feel for how a library works is to skim the `++` arm-names before diving into any specific arm. In this library, the arms are `make-deck`, `num-to-suit`, `shuffle-deck`, and `draw`. These names should be very clear, with the exception of `num-to-suit` though you could probably hazard a guess at what it does. Let's take a closer look at that one first.
81+
82+```hoon
83+++ num-to-suit
84+ |= val=@ud
85+ ^- suit
86+ ?+ val !!
87+ %1 %hearts
88+ %2 %spades
89+ %3 %clubs
90+ %4 %diamonds
91+ ==
92+```
93+
94+We can see this is a [gate](/docs/glossary/gate/) that takes a single `@ud` and produces a `suit`.
95+
96+The `?+` rune is the rune to switch against a value with a default. The default here is to crash with `!!`. Then we have the four options of 1 through 4, based on the value of `val`, which each resulting in a different suit.
97+
98+```hoon
99+++ make-deck
100+ ^- deck
101+ =| mydeck=deck
102+ =/ i 1
103+ |-
104+ ?: (gth i 4)
105+ mydeck
106+ =/ j 2
107+ |-
108+ ?. (lte j 14)
109+ ^$(i +(i))
110+ %= $
111+ j +(j)
112+ mydeck [(num-to-suit i) j]^mydeck
113+ ==
114+```
115+
116+`num-to-suit` is used in the `make-deck` arm shown above. This arm should be quite readable to you at this point. Here we simply have two loops where we use counters to build up the full set of 52 cards, by cycling through every possible suit and number and combining them. Once we have reached the point where `j` is greater than 14, we're going to jump back out to the "suit" outer-loop and increment `i`. `?.` may be an unfamiliar rune; it is simply the inverted version of `?:`, so the first branch is actually the "no" branch and the second is the "yes" branch. This is done to keep the "heaviest" branch at the bottom.
117+
118+
119+```hoon
120+++ draw
121+ |= [n=@ud d=deck]
122+ ^- [hand=deck rest=deck]
123+ :- (scag n d)
124+ (slag n d)
125+```
126+
127+`draw` takes two arguments: `n`, a number; and `d`, a `deck`. It's going to
128+produce a cell of two `decks`. The cell is created using `scag` and `slag`.
129+[`scag`](/docs/hoon/reference/stdlib/2b#scag) is a
130+standard-library gate produces the first `n` elements from a list, and
131+[`slag`](/docs/hoon/reference/stdlib/2b#slag) is a
132+standard-library gate that produces the remaining elements of a list starting
133+after the `n`th element. So we use `scag` to produce the drawn hand of `n` cards
134+in the head of the cell as `hand`, and `slag` to produce the remaining deck in
135+the tail of the cell as `rest`.
136+
137+```hoon
138+++ shuffle-deck
139+ |= [unshuffled=deck entropy=@]
140+ ^- deck
141+ =| shuffled=deck
142+ =/ random ~(. og entropy)
143+ =/ remaining (lent unshuffled)
144+ |-
145+ ?: =(remaining 1)
146+ :_ shuffled
147+ (snag 0 unshuffled)
148+ =^ index random (rads:random remaining)
149+ %= $
150+ shuffled (snag index unshuffled)^shuffled
151+ remaining (dec remaining)
152+ unshuffled (oust [index 1] unshuffled)
153+ ==
154+```
155+
156+Finally, in the code above, we come to `shuffle-deck`. This gate takes two arguments: a `deck`, and a `@` as a bit of `entropy` to seed the `og` core. It's going to produce a `deck`.
157+
158+`=|` adds a default-valued `deck` to the subject.
159+
160+Next, with `=/ random ~(. og entropy)`, we feed the `og` core the entropy it needs in preparation for using it. Then, with `=/ remaining (lent unshuffled)`, we get the length of the unshuffled deck with `lent`.
161+
162+`?: =(remaining 1)` checks if we have only one card remaining. If that's true, we produce a cell of `shuffled` and the one card left in `unshuffled`. We use the `:_` rune here, so that the "heavier" hoon is at the bottom of the expression.
163+
164+If the above conditional evaluates to false, we are going to do a little work. `=^` is a rune that pins the head of a pair and changes a leg in the subject with the tail. It's useful for interacting with the `og` core arms, as many of them produce a pair of a random numbers and the next state of the core. We're going to put the random number in the subject with the face `index` and change `random` to be the next core.
165+
166+With that completed, we use `%=` to call `$` to recurse back up to `|-` with a few changes.
167+
168+`shuffled` gets the `darc` from `unshuffled` at `index` added to the front of it.
169+
170+`remaining` gets decremented. Why are we using a counter here instead of just checking the length of `unshuffled` on each loop? `lent` traverses the entire list every time it's called so maintaining a counter in this fashion is much faster.
171+
172+`unshuffled` becomes the result of using `oust` to remove 1 `darc` at `index` on `unshuffled`.
173+
174+This is a very naive shuffling algorithm, and you could imagine a better one. Implementation of a better algorithm is left as an exercise for the reader.
175+
176+## Using the Library
177+
178+
179+So now that we have this library, how do we actually use it? Let's look at a very simple `say` generator that takes advantage of what we built.
180+
181+```hoon
182+/+ playing-cards
183+:- %say
184+|= [[* eny=@uv *] *]
185+:- %noun
186+(shuffle-deck:playing-cards make-deck:playing-cards eny)
187+```
188+
189+If you save our the library as `playing-cards.hoon` in the `lib` directory, you can import the library with the `/+` rune. Our above `say` -- let's call it `cards.hoon` -- imports our library in this way. It should be noted that `/+` is not a Hoon rune, but instead a rune used by Ford, the Urbit build-system. When `cards.hoon` gets built, Ford will pull in the requested library and also build that. It will also create a dependency so that if `playing-cards.hoon` changes, this file will also get rebuilt.
190+
191+Below `/+ playing-cards`, you have the standard `say` generator boilerplate that allows us to get a bit of entropy from `arvo` when the generator is run. Then we feed the entropy and a `deck` created by `make-deck` into `shuffle-deck` to get back a shuffled `deck`.
content/docs/hoon/hoon-school/list-of-numbers.mdnew file+132
@@ -0,0 +1,132 @@
1++++
2+title = "1.1.1 Walkthrough: List of Numbers"
3+weight = 2
4+template = "doc.html"
5+aliases = ["/docs/learn/hoon/hoon-tutorial/list-of-numbers/"]
6++++
7+
8+This code-example is intended to familiarize you with the basics of Hoon syntax. It's okay if you don't understand everything immediately; some concepts may be beyond your grasp for now. What's important is that you become accustomed to the elements of the code and their look once combined into a valid program.
9+
10+Below is a simple Hoon program that takes a single number `n` from the user as input and produces a list of numbers from `1` up to (but not including) `n`. So, if the user gives the number `5`, the program will produce: `~[1 2 3 4]`.
11+
12+```hoon
13+|= end=@ :: 1
14+=/ count=@ 1 :: 2
15+|- :: 3
16+^- (list @) :: 4
17+?: =(end count) :: 5
18+ ~ :: 6
19+:- count :: 7
20+$(count (add 1 count)) :: 8
21+```
22+
23+As we mentioned in the previous lesson, the easiest way to use such a program is to run it as a _generator_. Mount your desk `|mount %` (if you didn't do it before), saving a file in the `/home/gen` directory of your ship and commiting these changes `|commit %home` allows you to run it from your ship's Dojo (command line) as a generator. Save the above code there as `list.hoon`. Now you can run it in the Dojo with the command below (remember, without the `>`):
24+
25+`> +list 5`
26+
27+Try it! You can choose any natural number to put after `+list`, but it can't be `0` or blank. The `+` lets the Dojo know that it's looking for a generator with the name that follows. You don't write out the `.hoon` part of the file name when running it in the Dojo.
28+
29+But what do all these squiggly symbols in the program _do_? It probably isn't immediately clear. Let's go through each component of this code.
30+
31+## The Code
32+
33+You probably noticed that there's a column of colons and numbers in our example. The `::` digraph tells the compiler to ignore the rest of the text on the line. Such text is referred to as a "comment" because, instead of performing a computation, it exists to explain things to human readers of the source code.
34+
35+In our example program, we use comments with line numbers for convenient reference, so that we can dig into the code line by line. Important Hoon concepts will be bolded when first mentioned.
36+
37+### Line 1
38+
39+```hoon
40+|= end=@
41+```
42+
43+There's a few things going on in our first line. The first part of it, `|=`, is a kind of **rune**. Runes are the building blocks of all Hoon code, represented as a pair of non-alphanumeric ASCII characters. Runes form expressions; runes are used how keywords are used in other languages. In other words, all computations in Hoon ultimately require runes. Runes and other Hoon expressions are all separated from one another by either two spaces or a line break.
44+
45+All runes take a fixed number of "children". Children can themselves be runes with children, and Hoon programs work by chaining through these until a value -- not another rune -- is arrived at. For this reason, we very rarely need to close expressions. Keep this scheme in mind when examining Hoon code.
46+
47+The specific purpose of the `|=` rune is to create a **gate**. A [gate](/docs/glossary/gate/) is what would be called a function in other languages: it takes an input, performs a specified computation, and then produces an output.
48+
49+Because we're only on line 1, all we're doing with the gate is creating it, and then specifying what kind of input the gate takes with that rune's first child: `end=@`. The `end` part of our code is simply a name that we give to the user's input so that we can use the number later. `=@` means that we restrict the kind of input that our gate accepts to the **atom** type, or `@` for short. An [atom](/docs/glossary/atom/) is a natural number.
50+
51+Our program is simple, so the _entire program_ is the gate that's being created here. The rest of our lines of code are part of the second child of our gate, and they determine how our gate produces an output.
52+
53+### Line 2
54+
55+```hoon
56+=/ count=@ 1
57+```
58+
59+This line begins with the `=/` rune, which stores a value with a name and specifies its type. It takes three children.
60+
61+`count=@` (the first child) stores `1` (the second child) as `count` and specifies that it has the `@` type.
62+
63+We're using `count` to keep track of what numbers we're including in the list we're building. We'll use it later in the program.
64+
65+### Line 3
66+
67+```hoon
68+|-
69+```
70+
71+The `|-` rune functions as a "restart" point for recursion that will be defined later. It takes one child.
72+
73+### Line 4
74+
75+```hoon
76+^- (list @)
77+```
78+
79+The `^-` rune constrains output to a certain type. It takes two children.
80+
81+In this case, the rune specifies that our gate's output must be `(list @)` -- that is, a list of atoms.
82+
83+### Lines 5 and 6
84+
85+```hoon
86+?: =(end count)
87+ ~
88+```
89+
90+`?:` is a rune that evaluates whether its first child is `true` or `false`. If that child is `true`, the program branches to the second child. If it's `false`, it branches to the third child. `?:` takes three children.
91+
92+`=(end count)` checks if the user's input equals to the `count` value that we're incrementing to build the list. If these values are equal, we want to end the program, because our list has been built out to where it needs to be. Note that this expression is, in fact, a rune expression, just written a different way than you've seen so far. `=(end count)` is an _irregular form_ of `.= end count`, different in looks but identical in operation. `.=` is a rune that checks for the equality of its two children, and produces a `true` or `false` based on what it finds.
93+
94+`~` simply represents the `null` value. The program branches here if on line 5 it finds that `end` equals `count`. Lists in Hoon always end with `~`, so we need this to be the last thing we put in our list.
95+
96+## Line 7
97+
98+`:-` is a rune that creates a **cell**, an ordered pair of two values, such as `[1 2]`. It takes two children.
99+
100+In our case, `:- count` creates a cell out of whatever value is stored in `count`, and then with the product of line 8.
101+
102+## Line 8
103+
104+```hoon
105+$(count (add 1 count))
106+```
107+
108+The above code is, once again, a compact way of writing a rune expression. All you need to know is that this line of code restarts the program at `|-`, except with the value stored in `count` incremented by `1`. The construction of `(count (add 1 count))` tells the computer, "replace the value of `count` with `count+1`".
109+
110+You'll notice that we use an unfamiliar word here: `add`. Unlike `count` and `end`, `add` is not defined anywhere in our program. That's because it's a gate that's predefined in the Hoon **standard library**. The standard library is filled with pre-defined gates that are generally useful, and these gates can be used just like something that you defined in your own program. You can see this gate, and other mathematical operators, in [section 1a](/docs/hoon/reference/stdlib/1a) of the standard library documentation.
111+
112+## Explanation
113+
114+If you aren't clear on how the program is building the list, that's okay.
115+
116+Our program works by having each iteration of the list creating a cell. In each of these cells, the head -- the cell's first position -- is filled with the current-iteration value of `count`. The tail of the cell, its second position, is filled with _the product of a new iteration of our code_ that starts at `|-`. This iteration will itself create another cell, the head of which will be filled by the incremented value of `count`, and the tail of which will start another iteration. This process continues until `?:` branches to `~` (`null`). When that happens, the list is terminated and the program doesn't have anything else to do, so it ends. So, a built-out list of nested cells can be visualized like this:
117+
118+```
119+ [1 [2 [3 [4 ~]]]]
120+
121+ .
122+ / \
123+ 1 .
124+ / \
125+ 2 .
126+ / \
127+ 3 .
128+ / \
129+ 4 ~
130+```
131+
132+If you still don't intuit how this is working, don't worry. We'll take a deeper look into recursion later with our [Recursion Walkthrough](../recursion).
content/docs/hoon/hoon-school/lists.mdnew file+497
@@ -0,0 +1,497 @@
1++++
2+title = "1.5 Lists"
3+weight = 8
4+template = "doc.html"
5+aliases = ["/docs/learn/hoon/hoon-tutorial/lists/"]
6++++
7+
8+A **list** is a type of [noun](/docs/glossary/noun/) that you'll frequently encounter when reading and writing Hoon. A list can be thought of as an ordered arrangement of zero or more elements terminated by a `~` (null).
9+
10+So a list can be either null or non-null. When the list contains only `~` and no items, it's the null list. Most lists are, however, non-null lists, which have items preceding the `~`. Non-null lists, called _lests_, are cells in which the head is the first list item, and the tail is the rest of the list. The tail is itself a list, and if such a list is also non-null, the head of this sublist is the second item in the greater list, and so on. To illustrate, let's look at a list `[1 2 3 4 ~]` with the cell-delineating brackets left in:
11+
12+`[1 [2 [3 [4 ~]]]]`
13+
14+It's easy to see where the heads are and where the nesting tails are. The head of the above list is the [atom](/docs/glossary/atom/) `1` and the tail is the list `[2 [3 [4 ~]]]`, (or `[2 3 4 ~]`). Recall that whenever cell brackets are omitted so that visually there appears to be more than two child nouns, it is implicitly understood that the right-most nouns constitute a cell.
15+
16+To make a list, let's cast nouns to the `(list @)` ("list of atoms") type.
17+
18+```
19+> `(list @)`~
20+~
21+
22+> `(list @)`[1 2 3 4 5 ~]
23+~[1 2 3 4 5]
24+
25+> `(list @)`[1 [2 [3 [4 [5 ~]]]]]
26+~[1 2 3 4 5]
27+
28+> `(list @)`~[1 2 3 4 5]
29+~[1 2 3 4 5]
30+```
31+
32+Notice how the last Dojo command has a different construction, with the `~` in front of the bracketed items. This is just another way of writing the same thing; `~[1 2]` is semantically identical to `[1 2 ~]`.
33+
34+## An aside about Casting
35+
36+The use of casts in this example is helpful to explain to the Hoon compiler exactly what it is we mean with these data structures. In this case, we are telling it they are all lists of atoms. Get in the habit of casting your data structures, as it will not only help anyone reading your code, but it will help you in hunting down bugs in your code.
37+
38+Let's make a list whose items are of the `@t` string type:
39+
40+```
41+> `(list @t)`['Urbit' 'will' 'rescue' 'the' 'internet' ~]
42+<|Urbit will rescue the internet|>
43+```
44+
45+The head of a list has the face `i` and the tail has the face `t`. (For the sake of neatness, these faces aren't shown by the Hoon pretty printer.) To use the `i` and `t` faces of a list, you must first prove that the list is non-null by using the conditional family of runes, `?`:
46+
47+```
48+> =>(b=`(list @)`[1 2 3 4 5 ~] i.b)
49+-find.i.b
50+find-fork-d
51+
52+> =>(b=`(list @)`[1 2 3 4 5 ~] ?~(b ~ i.b))
53+1
54+
55+> =>(b=`(list @)`[1 2 3 4 5 ~] ?~(b ~ t.b))
56+~[2 3 4 5]
57+```
58+
59+`=>` is a reversed form of the `:` operator we've been using, meaning that `=> a b` is the
60+same as `b:a`. Here, this means we're evaluation the `?~` expression with the
61+`b=...` expression as the subject. We explore this rune in more detail in a
62+[later lesson](/docs/hoon/hoon-school/arms-and-cores#cores-and-contexts).
63+
64+It's important to note that performing tests like `?~ mylist` will actually transform `mylist` into a `lest`, a non-null list. Because `lest` is a different type than `list`, performing such tests can come back to bite you later in non-obvious ways when you try to use some standard library functions meant for lists.
65+
66+You can construct lists of any type. `(list @)` indicates a list of atoms, `(list ^)` indicates a list of cells, `(list [@ ?])` indicates a list of cells whose head is an atom and whose tail is a flag, etc.
67+
68+## Tapes and Cords
69+
70+While a list can be of any type, there are some special types of lists that are built into Hoon. The `tape` is the most common example.
71+
72+Hoon has two kinds of strings: cords and tapes. Cords are atoms with aura `@t`, and they're pretty-printed between `''` marks.
73+
74+```
75+> 'this is a cord'
76+'this is a cord'
77+
78+> `@`'this is a cord'
79+2.037.307.443.564.446.887.986.503.990.470.772
80+```
81+
82+A tape is a list of `@tD` atoms (i.e., ASCII characters).
83+
84+```
85+> "this is a tape"
86+"this is a tape"
87+
88+> `(list @)`"this is a tape"
89+~[116 104 105 115 32 105 115 32 97 32 116 97 112 101]
90+```
91+
92+You can also use the words `cord` and `tape` for casting:
93+
94+```
95+> `tape`"this is a tape"
96+"this is a tape"
97+
98+> `cord`'this is a cord'
99+'this is a cord'
100+```
101+
102+## List Functions in the Hoon Standard Library
103+
104+Lists are a commonly used data structure. Accordingly, there are several functions in the [Hoon standard library](/docs/hoon/reference/stdlib/) intended to make lists easier to use.
105+
106+For a complete list of these functions, check out the standard library reference for lists [here](/docs/hoon/reference/stdlib/2b/). Here we'll look at a few of these functions.
107+
108+### `flop`
109+
110+The `flop` function takes a list and returns it in reverse order:
111+
112+```
113+> (flop ~[11 22 33])
114+~[33 22 11]
115+
116+> (flop "Hello!")
117+"!olleH"
118+
119+> (flop (flop "Hello!"))
120+"Hello!"
121+```
122+
123+#### `flop` Exercise 1.5a
124+
125+Without using `flop`, write a [gate](/docs/glossary/gate/) that takes a `(list @)` and returns it in reverse order. There is a solution at the bottom of this lesson.
126+
127+### `sort`
128+
129+The `sort` function uses the "quicksort" algorithm to sort a list. It takes a list to sort and a gate that serves as a comparator. For example, if you want to sort the list `~[37 62 49 921 123]` from least to greatest, you would pass that list along with the `lth` gate (for "less than"):
130+
131+```
132+> (sort ~[37 62 49 921 123] lth)
133+~[37 49 62 123 921]
134+```
135+
136+To sort the list from greatest to least, use the `gth` gate ("greater than") as the basis of comparison instead:
137+
138+```
139+> (sort ~[37 62 49 921 123] gth)
140+~[921 123 62 49 37]
141+```
142+
143+You can sort letters this way as well:
144+
145+```
146+> (sort ~['a' 'f' 'e' 'k' 'j'] lth)
147+<|a e f j k|>
148+```
149+
150+The function passed to `sort` must produce a `flag`, i.e., `?`.
151+
152+### `weld`
153+
154+The `weld` function takes two lists of the same type and concatenates them:
155+
156+```
157+> (weld ~[1 2 3] ~[4 5 6])
158+~[1 2 3 4 5 6]
159+
160+> (weld "Happy " "Birthday!")
161+"Happy Birthday!"
162+```
163+
164+#### `weld` Exercise 1.5b
165+
166+Without using `weld`, write a gate that takes a `[(list @) (list @)]` of which the product is the concatenation of these two lists. There is a solution at the bottom of this lesson.
167+
168+### `snag`
169+
170+The `snag` function takes an atom `n` and a list, and returns the `n`th item of the list, where `0` is the first item:
171+
172+```
173+> (snag 0 `(list @)`~[11 22 33 44])
174+11
175+
176+> (snag 1 `(list @)`~[11 22 33 44])
177+22
178+
179+> (snag 3 `(list @)`~[11 22 33 44])
180+44
181+
182+> (snag 3 "Hello!")
183+'l'
184+
185+> (snag 1 "Hello!")
186+'e'
187+
188+> (snag 5 "Hello!")
189+'!'
190+```
191+
192+Note: there is currently a type system issue that causes some of these functions to fail when passed a list `b` after some type inference has been performed on `b`. For an illustration of the bug, let's set `b` to be a `(list @)` of `~[11 22 33 44]` in the Dojo:
193+
194+```
195+> =b `(list @)`~[11 22 33 44]
196+
197+> b
198+~[11 22 33 44]
199+```
200+
201+Now let's use `?~` to prove that `b` isn't null, and then try to `snag` it:
202+
203+```
204+> ?~(b ~ (snag 0 b))
205+nest-fail
206+```
207+
208+The problem is that `snag` is expecting a raw list, not a list that is known to be non-null.
209+
210+You can cast `b` to `(list)` to work around this:
211+
212+```
213+> ?~(b ~ (snag 0 `(list)`b))
214+11
215+```
216+
217+#### `snag` Exercise 1.5c
218+
219+Without using `snag`, write a gate that returns the `n`th item of a list. There is a solution at the bottom of this lesson.
220+
221+### `oust`
222+
223+The `oust` function takes a pair of atoms `[a=@ b=@]` and a list, and returns the list with `b` items removed, starting at item `a`:
224+
225+```
226+> (oust [0 1] `(list @)`~[11 22 33 44])
227+~[22 33 44]
228+
229+> (oust [0 2] `(list @)`~[11 22 33 44])
230+~[33 44]
231+
232+> (oust [1 2] `(list @)`~[11 22 33 44])
233+~[11 44]
234+
235+> (oust [2 2] "Hello!")
236+"Heo!"
237+```
238+
239+### `lent`
240+
241+The `lent` function takes a list and returns the number of items in it:
242+
243+```
244+> (lent ~[11 22 33 44])
245+4
246+
247+> (lent "Hello!")
248+6
249+```
250+
251+#### `lent` Exercise 1.5d
252+
253+Without using `lent`, write a gate that takes a list and returns the number of item in it. There is a solution at the bottom of this lesson.
254+
255+### `roll`
256+
257+The `roll` function takes a list and a gate, and accumulates a value of the list items using that gate. For example, if you want to add or multiply all the items in a list of atoms, you would use `roll`:
258+
259+```
260+> (roll `(list @)`~[11 22 33 44 55] add)
261+165
262+
263+> (roll `(list @)`~[11 22 33 44 55] mul)
264+19.326.120
265+```
266+
267+### `turn`
268+
269+The `turn` function takes a list and a gate, and returns a list of the products of applying each item of the input list to the gate. For example, to add `1` to each item in a list of atoms:
270+
271+```
272+> (turn `(list @)`~[11 22 33 44] |=(a=@ +(a)))
273+~[12 23 34 45]
274+```
275+
276+Or to double each item in a list of atoms:
277+
278+```
279+> (turn `(list @)`~[11 22 33 44] |=(a=@ (mul 2 a)))
280+~[22 44 66 88]
281+```
282+
283+`turn` is Hoon's version of Haskell's `map`.
284+
285+We can rewrite the [Caesar cipher](https://en.wikipedia.org/wiki/Caesar_cipher) program using `turn`:
286+
287+```hoon
288+|= [a=@ b=tape]
289+^- tape
290+?: (gth a 25)
291+ $(a (sub a 26))
292+%+ turn b
293+|= c=@tD
294+?: &((gte c 'A') (lte c 'Z'))
295+ =. c (add c a)
296+ ?. (gth c 'Z') c
297+ (sub c 26)
298+?: &((gte c 'a') (lte c 'z'))
299+ =. c (add c a)
300+ ?. (gth c 'z') c
301+ (sub c 26)
302+c
303+```
304+
305+## Using `hoon.hoon` to Learn Hoon
306+
307+The Hoon standard library and compiler are written in Hoon. At this point, you know enough Hoon to be able to explore the standard library portions of `hoon.hoon` and find more functions relevant to lists. Look around in [section 2b](/docs/hoon/reference/stdlib/2b) (and elsewhere).
308+
309+## Additional Exercises
310+
311+#### Exercise 1.5e
312+
313+Without entering these expressions into the Dojo, what are the products of the following expressions?
314+
315+```
316+> (lent ~[1 2 3 4 5])
317+```
318+
319+```
320+> (lent ~[~[1 2] ~[1 2 3] ~[2 3 4]])
321+```
322+
323+```
324+> (lent ~[1 2 (weld ~[1 2 3] ~[4 5 6])])
325+```
326+
327+#### Exercise 1.5f
328+
329+First, bind these faces.
330+
331+```
332+> =b ~['moon' 'planet' 'star' 'galaxy']
333+> =c ~[1 2 3]
334+```
335+
336+Then determine whether the following Dojo expressions are valid, and if so, what they evaluate to.
337+
338+```
339+> (weld b b)
340+```
341+
342+```
343+> (weld b c)
344+```
345+
346+```
347+> (lent (weld b c))
348+```
349+
350+```
351+> (add (lent b) (lent c))
352+```
353+
354+#### Exercise 1.5g
355+
356+Write a gate that takes in a list `a` and returns `%.y` if `a` is a palindrome and `%.n` otherwise. You may make use of the `flop` function.
357+
358+## Exercise Solutions
359+
360+#### 1.5a `flop`
361+
362+```hoon
363+:: flop.hoon
364+::
365+|= a=(list @)
366+=| b=(list @)
367+|- ^- (list @)
368+?~ a b
369+$(b [i.a b], a t.a)
370+```
371+
372+Run in Dojo:
373+
374+```
375+> +flop ~[11 22 33 44]
376+~[44 33 22 11]
377+```
378+
379+#### 1.5b `weld`
380+
381+```hoon
382+:: weld.hoon
383+::
384+|= [a=(list @) b=(list @)]
385+|- ^- (list @)
386+?~ a b
387+[i.a $(a t.a)]
388+```
389+
390+Run in Dojo:
391+
392+```
393+> +weld [~[1 2 3] ~[3 4 5 6]]
394+~[1 2 3 3 4 5 6]
395+```
396+
397+#### 1.5c `snag`
398+
399+```hoon
400+:: snag.hoon
401+::
402+|= [a=@ b=(list @)]
403+?~ b !!
404+?: =(0 a) i.b
405+$(a (dec a), b t.b)
406+```
407+
408+Run in Dojo:
409+
410+```
411+> +snag [0 ~[11 22 33 44]]
412+11
413+
414+> +snag [2 ~[11 22 33 44]]
415+33
416+```
417+
418+#### 1.5d `lent`
419+
420+```hoon
421+:: lent.hoon
422+::
423+|= a=(list)
424+^- @
425+=/ b=@ 0
426+|-
427+?~ a b
428+$(a t.a, b +(b))
429+```
430+
431+Run in Dojo:
432+
433+```
434+> +lent ~[1 2 3 4 5]
435+5
436+> +lent "asdf"
437+4
438+```
439+
440+#### 1.5e
441+
442+Run in Dojo:
443+
444+```
445+> (lent ~[1 2 3 4 5])
446+5
447+> (lent ~[~[1 2] ~[1 2 3] ~[2 3 4]])
448+3
449+> (lent ~[1 2 (weld ~[1 2 3] ~[4 5 6])])
450+3
451+```
452+
453+#### 1.5f
454+
455+Run in Dojo:
456+
457+```
458+> (weld b b)
459+<|moon planet star galaxy moon planet star galaxy|>
460+```
461+
462+```
463+> (weld b c)
464+```
465+
466+This will not run because `weld` expects the elements of both lists to be of the same type.
467+
468+```
469+> (lent (weld b c))
470+```
471+
472+This also fails for the same reason, but it is important to note that in some languages that are more lazily evaluated, such an expression would still work since it would only look at the length of `b` and `c` and not worry about what the elements were. In that case, it would return `7`.
473+
474+```
475+> (add (lent b) (lent c))
476+7
477+```
478+
479+We see here the correct way to find the sum of the length of two lists of unknown type.
480+
481+#### 1.5g
482+
483+```hoon
484+:: palindrome.hoon
485+::
486+|= a=(list)
487+=(a (flop a))
488+```
489+
490+Run in Dojo:
491+
492+```
493+> +palindrome "urbit"
494+%.n
495+> +palindrome "racecar"
496+%.y
497+```
content/docs/hoon/hoon-school/molds.mdnew file+98
@@ -0,0 +1,98 @@
1++++
2+title = "2.3.2 Molds"
3+weight = 28
4+template = "doc.html"
5+aliases = ["/docs/learn/hoon/hoon-tutorial/molds/"]
6++++
7+
8+A mold is an idempotent function that coerces a [noun](/docs/glossary/noun/) to
9+be of a specific type or crashes.
10+
11+
12+The simplest molds to understand are arms of cores created with `+$`
13+
14+```
15++$ height [feet=@ud inches=@ud]
16+```
17+
18+A mold is compiled to a gate that takes in any noun and produces a typed value, or crashes:
19+
20+```
21+(height [5 11])
22+:: produces [feet=5 inches=11]
23+```
24+```
25+(height %wrong)
26+:: crashes
27+```
28+
29+To coerce using a gate, it's good practice to use the `;;` rune, which can parse inline molds.
30+
31+
32+```
33+;;(height [5 11])
34+:: produces [feet=5 inches=11]
35+```
36+```hoon
37+;;([feet=@ud inches=@ud] [5 11])
38+:: produces [feet=5 inches=11]
39+```
40+
41+
42+`|$` is the mold builder rune which takes a list of molds and produces a mold.
43+
44+`|$` implements [parametric
45+polymorphism](https://en.wikipedia.org/wiki/Parametric_polymorphism) in Hoon,
46+and as such we call gates produced with `|$` a **wet gate**. We discuss what this
47+means in further detail in the upcoming lesson on [polymorphism](/docs/hoon/hoon-school/type-polymorphism).
48+
49+Let's look at some examples from `hoon.hoon`.
50+```hoon
51+++ pair
52+ |$ [head tail]
53+ [p=head q=tail]
54+```
55+
56+
57+Here is a very simple mold builder. It takes two molds and produces a mold that is a pair of those with the faces `p` and `q`. An example of using this would be `(pair @ud @ud)` which would produce a mold for a cell of `@ud` and `@ud`.
58+
59+```hoon
60+++ each
61+ |$ [this that]
62+ $% [%| p=that]
63+ [%& p=this]
64+ ==
65+```
66+
67+`each` is very slightly more complicated than `pair`. `$%` is a rune that is a tagged union. The mold produced by this will match either `this` or `that`. An example of this would be `(each @ud @tas)` which will match either an `@ud` or a `@tas`.
68+
69+```hoon
70+++ list
71+ |$ [item]
72+ $@(~ [i=item t=(list item)])
73+```
74+Here is a mold builder you've used previously. `$@` is a rune that will match the first thing if its sample is an [atom](/docs/glossary/atom/) and the second if the sample is a cell. You should be familiar at this point that a `list` is either `~` or a pair of an item and a list of item.
75+
76+
77+```hoon
78+++ lest
79+ |$ [item]
80+ [i/item t/(list item)]
81+```
82+`lest` you may have heard of as a "non empty list." You can see that it lacks the `~` case that `list` has but it matches the second part of the `list` definition. Remember that Hoon types are defined by shape. `list` could also have been defined in terms of `lest` like this:
83+
84+```hoon
85+++ list
86+ |$ [item]
87+ $@(~ lest)
88+```
89+
90+Another possible way to write it could have been
91+
92+```hoon
93+++ list
94+ |$ [item]
95+ $@(~ [i=item t=$])
96+```
97+
98+Any of these would be equivalent.
content/docs/hoon/hoon-school/nouns.mdnew file+563

This diff is too big to show here.

content/docs/hoon/hoon-school/recursion.mdnew file+195

This diff is too big to show here.

content/docs/hoon/hoon-school/setup.mdnew file+105

This diff is too big to show here.

content/docs/hoon/hoon-school/structures-and-complex-types.mdnew file+356

This diff is too big to show here.

content/docs/hoon/hoon-school/the-subject-and-its-legs.mdnew file+726

This diff is too big to show here.

content/docs/hoon/hoon-school/trees-sets-and-maps.mdnew file+321

This diff is too big to show here.

content/docs/hoon/hoon-school/type-checking-and-type-inference.mdnew file+643

This diff is too big to show here.

content/docs/hoon/hoon-school/type-polymorphism.mdnew file+584

This diff is too big to show here.

content/docs/hoon/overview.mdnew file+276

This diff is too big to show here.

content/docs/hoon/reference/_index.mdnew file+50

This diff is too big to show here.

content/docs/hoon/reference/advanced.mdnew file+206

This diff is too big to show here.

content/docs/hoon/reference/auras.mdnew file+98

This diff is too big to show here.

content/docs/hoon/reference/basic.mdnew file+177

This diff is too big to show here.

content/docs/hoon/reference/cheat-sheet.mdnew file+28

This diff is too big to show here.

content/docs/hoon/reference/hoon-errors.mdnew file+189

This diff is too big to show here.

content/docs/hoon/reference/irregular.mdnew file+308

This diff is too big to show here.

content/docs/hoon/reference/limbs/_index.mdnew file+18

This diff is too big to show here.

content/docs/hoon/reference/limbs/limb.mdnew file+71

This diff is too big to show here.

content/docs/hoon/reference/limbs/wing.mdnew file+44

This diff is too big to show here.

content/docs/hoon/reference/rune/_index.mdnew file+73

This diff is too big to show here.

content/docs/hoon/reference/rune/bar.mdnew file+708

This diff is too big to show here.

content/docs/hoon/reference/rune/buc.mdnew file+606

This diff is too big to show here.

content/docs/hoon/reference/rune/cen.mdnew file+466

This diff is too big to show here.

content/docs/hoon/reference/rune/col.mdnew file+245

This diff is too big to show here.

content/docs/hoon/reference/rune/constants.mdnew file+193

This diff is too big to show here.

content/docs/hoon/reference/rune/dot.mdnew file+223

This diff is too big to show here.

content/docs/hoon/reference/rune/ket.mdnew file+387

This diff is too big to show here.

content/docs/hoon/reference/rune/lus.mdnew file+225

This diff is too big to show here.

content/docs/hoon/reference/rune/mic.mdnew file+462

This diff is too big to show here.

content/docs/hoon/reference/rune/sig.mdnew file+452

This diff is too big to show here.

content/docs/hoon/reference/rune/terminators.mdnew file+78

This diff is too big to show here.

content/docs/hoon/reference/rune/tis.mdnew file+490

This diff is too big to show here.

content/docs/hoon/reference/rune/wut.mdnew file+551

This diff is too big to show here.

content/docs/hoon/reference/rune/zap.mdnew file+239

This diff is too big to show here.

content/docs/hoon/reference/stdlib/1a.mdnew file+680

This diff is too big to show here.

content/docs/hoon/reference/stdlib/1b.mdnew file+273

This diff is too big to show here.

content/docs/hoon/reference/stdlib/1c.mdnew file+459

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2a.mdnew file+449

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2b.mdnew file+1412

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2c.mdnew file+1364

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2d.mdnew file+373

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2e.mdnew file+268

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2f.mdnew file+437

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2g.mdnew file+105

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2h.mdnew file+826

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2i.mdnew file+1133

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2j.mdnew file+269

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2k.mdnew file+400

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2l.mdnew file+108

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2m.mdnew file+308

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2n.mdnew file+427

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2o.mdnew file+187

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2p.mdnew file+242

This diff is too big to show here.

content/docs/hoon/reference/stdlib/2q.mdnew file+375

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3a.mdnew file+859

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3b.mdnew file+5889

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3c.mdnew file+649

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3d.mdnew file+821

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3e.mdnew file+8

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3f.mdnew file+722

This diff is too big to show here.

content/docs/hoon/reference/stdlib/3g.mdnew file+384

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4a.mdnew file+217

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4b.mdnew file+994

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4c.mdnew file+364

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4d.mdnew file+100

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4e.mdnew file+471

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4f.mdnew file+1195

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4g.mdnew file+179

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4h.mdnew file+962

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4i.mdnew file+1054

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4j.mdnew file+1656

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4k.mdnew file+276

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4l.mdnew file+608

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4m.mdnew file+434

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4n.mdnew file+447

This diff is too big to show here.

content/docs/hoon/reference/stdlib/4o.mdnew file+782

This diff is too big to show here.

content/docs/hoon/reference/stdlib/5a.mdnew file+7

This diff is too big to show here.

content/docs/hoon/reference/stdlib/5b.mdnew file+7

This diff is too big to show here.

content/docs/hoon/reference/stdlib/5c.mdnew file+7

This diff is too big to show here.

content/docs/hoon/reference/stdlib/5d.mdnew file+7

This diff is too big to show here.

content/docs/hoon/reference/stdlib/5e.mdnew file+7

This diff is too big to show here.

content/docs/hoon/reference/stdlib/5f.mdnew file+176

This diff is too big to show here.

content/docs/hoon/reference/stdlib/5g.mdnew file+7

This diff is too big to show here.

content/docs/hoon/reference/stdlib/_index.mdnew file+1733

This diff is too big to show here.

content/docs/hoon/reference/stdlib/table-of-contents.mdnew file+1731

This diff is too big to show here.

content/docs/hoon/reference/style.mdnew file+476

This diff is too big to show here.

content/docs/nock/_index.mdnew file+27

This diff is too big to show here.

content/docs/nock/definition.mdnew file+186

This diff is too big to show here.

content/docs/nock/example.mdnew file+362

This diff is too big to show here.

content/docs/nock/explanation.mdnew file+605

This diff is too big to show here.

content/docs/nock/implementations.mdnew file+2322

This diff is too big to show here.

content/docs/system-overview/_index.mdnew file+77

This diff is too big to show here.

content/docs/system-overview/arvo.mdnew file+32

This diff is too big to show here.

content/docs/system-overview/azimuth.mdnew file+34

This diff is too big to show here.

content/docs/system-overview/cryptography.mdnew file+124

This diff is too big to show here.

content/docs/system-overview/hoon.mdnew file+28

This diff is too big to show here.

content/docs/system-overview/nock.mdnew file+34

This diff is too big to show here.

content/docs/system-overview/vere.mdnew file+45

This diff is too big to show here.

content/docs/userspace/_index.mdnew file+30

This diff is too big to show here.

content/docs/userspace/gall/_index.mdnew file+21

This diff is too big to show here.

content/docs/userspace/gall/gall-api.mdnew file+958

This diff is too big to show here.

content/docs/userspace/gall/gall.mdnew file+558

This diff is too big to show here.

content/docs/userspace/gall/tutorial.mdnew file+14

This diff is too big to show here.

content/docs/userspace/graph-store/_index.mdnew file+23

This diff is too big to show here.

content/docs/userspace/graph-store/advanced-info.mdnew file+64

This diff is too big to show here.

content/docs/userspace/graph-store/data-structure-overview.mdnew file+338

This diff is too big to show here.

content/docs/userspace/graph-store/overview.mdnew file+109

This diff is too big to show here.

content/docs/userspace/graph-store/validator-walkthrough.mdnew file+487

This diff is too big to show here.

content/docs/userspace/landscape/_index.mdnew file+18

This diff is too big to show here.

content/docs/userspace/landscape/overview.mdnew file+195

This diff is too big to show here.

content/docs/userspace/landscape/reference/_index.mdnew file+11

This diff is too big to show here.

content/docs/userspace/landscape/reference/graph-store.mdnew file+160

This diff is too big to show here.

content/docs/userspace/overview.mdnew file+19

This diff is too big to show here.

content/docs/userspace/threads/_index.mdnew file+27

This diff is too big to show here.

content/docs/userspace/threads/basics/_index.mdnew file+29

This diff is too big to show here.

content/docs/userspace/threads/basics/bind.mdnew file+97

This diff is too big to show here.

content/docs/userspace/threads/basics/fundamentals.mdnew file+169

This diff is too big to show here.

content/docs/userspace/threads/basics/input.mdnew file+145

This diff is too big to show here.

content/docs/userspace/threads/basics/output.mdnew file+119

This diff is too big to show here.

content/docs/userspace/threads/basics/summary.mdnew file+75

This diff is too big to show here.

content/docs/userspace/threads/examples/_index.mdnew file+33

This diff is too big to show here.

content/docs/userspace/threads/examples/child-thread.mdnew file+237

This diff is too big to show here.

content/docs/userspace/threads/examples/get-json.mdnew file+126

This diff is too big to show here.

content/docs/userspace/threads/examples/main-loop.mdnew file+178

This diff is too big to show here.

content/docs/userspace/threads/examples/poke-agent.mdnew file+60

This diff is too big to show here.

content/docs/userspace/threads/examples/scry.mdnew file+70

This diff is too big to show here.

content/docs/userspace/threads/examples/take-fact.mdnew file+65

This diff is too big to show here.

content/docs/userspace/threads/gall/_index.mdnew file+29

This diff is too big to show here.

content/docs/userspace/threads/gall/poke-thread.mdnew file+116

This diff is too big to show here.

content/docs/userspace/threads/gall/start-thread.mdnew file+145

This diff is too big to show here.

content/docs/userspace/threads/gall/stop-thread.mdnew file+152

This diff is too big to show here.

content/docs/userspace/threads/gall/take-facts.mdnew file+184

This diff is too big to show here.

content/docs/userspace/threads/gall/take-result.mdnew file+132

This diff is too big to show here.

content/docs/userspace/threads/http-api.mdnew file+73

This diff is too big to show here.

content/docs/userspace/threads/overview.mdnew file+81

This diff is too big to show here.

content/docs/userspace/threads/reference.mdnew file+86

This diff is too big to show here.

content/docs/vere/_index.mdnew file+42

This diff is too big to show here.

content/docs/vere/api.mdnew file+1040

This diff is too big to show here.

content/docs/vere/c.mdnew file+114

This diff is too big to show here.

content/docs/vere/cryptography.mdnew file+43

This diff is too big to show here.

content/docs/vere/jetting.mdnew file+779

This diff is too big to show here.

content/docs/vere/nouns.mdnew file+477

This diff is too big to show here.

content/docs/vere/runtime.mdnew file+44

This diff is too big to show here.

content/events/2017-08-11-after-hours-bootstrapping-urbit-from-the-ethereum-blockchain.md−1

This diff is too big to show here.

content/events/2017-09-22-after-hours-fun-with-arvo-the-urbit-os.md−1

This diff is too big to show here.

content/events/2017-10-26-after-hours-designing-robust-human-systems.md−1

This diff is too big to show here.

content/events/2017-11-16-after-hours-visiting-contributors.md−1

This diff is too big to show here.

content/events/2018-01-26-urbit-irl-20181.md−1

This diff is too big to show here.

content/events/2018-02-23-urbit-irl-20182.md−1

This diff is too big to show here.

content/events/2018-03-11-20183-hoon-school.md−1

This diff is too big to show here.

content/events/2018-03-23-urbit-irl-20183.md−1

This diff is too big to show here.

content/events/2018-04-08-20184-hoon-school.md−1

This diff is too big to show here.

content/events/2018-05-25-urbit-irl-20185.md−1

This diff is too big to show here.

content/events/2018-08-03-after-hours-decentralized-web-summit.md−1

This diff is too big to show here.

content/events/2018-08-17-urbit-irl-20188.md−1

This diff is too big to show here.

content/events/2018-09-21-urbit-irl-20189.md−1

This diff is too big to show here.

content/events/2018-10-10-urbit-zcash-blockchain-week.md−1

This diff is too big to show here.

content/events/2018-12-20-after-hours-its-just-a-party-man.md−1

This diff is too big to show here.

content/events/2019-03-01-after-hours-ask-galen-anything.md−1

This diff is too big to show here.

content/events/2019-03-08-urbit-irl-austin-tx.md−1

This diff is too big to show here.

content/events/2019-04-19-urbit-irl-20194.md−1

This diff is too big to show here.

content/events/2019-05-17-urbit-irl-20195.md−1

This diff is too big to show here.

content/events/2019-06-21-urbit-irl-20196.md−1

This diff is too big to show here.

content/events/2019-07-19-urbit-irl-20197.md+3−2

This diff is too big to show here.

content/events/2019-08-29-urbit-austin-20198.md+3−2

This diff is too big to show here.

content/events/2019-10-04-urbit-irl-201910.md+3−2

This diff is too big to show here.

content/events/2019-11-15-urbit-irl-201911.md+3−2

This diff is too big to show here.

content/events/2019-12-13-urbit-irl-201912.md+3−2

This diff is too big to show here.

content/events/2020-01-24-urbit-irl-20201.md+3−2

This diff is too big to show here.

content/events/2020-02-28-urbit-irl-20202.md+3−2

This diff is too big to show here.

content/events/2020-04-03-urbit-os1-launch-party.md+4−3

This diff is too big to show here.

content/events/2020-10-09-urbit-hosting-launch-event.md+4−4

This diff is too big to show here.

content/events/2020-11-05-developer-call-graph-store.md−1

This diff is too big to show here.

content/events/2020-11-19-developer-call-bittorrent-tracking-on-urbit.md−1

This diff is too big to show here.

content/events/2020-12-10-developer-call-injecting-external-services-into-urbit.md−1

This diff is too big to show here.

content/events/2021-02-04-developer-call-architectural-idea-maze.md−1

This diff is too big to show here.

content/events/2021-03-04-developer-call-scaling-azimuth.md−1

This diff is too big to show here.

content/events/2021-03-18-developer-call-pressure-and-protolith.md+4−4

This diff is too big to show here.

content/events/2021-04-01-developer-call-javascript-apps-on-urbit.md+1−1

This diff is too big to show here.

content/events/2021-04-27-bitcoin-launch.md+2−1

This diff is too big to show here.

content/events/2021-04-29-developer-call-real-time-communications-on-urbit.md+1−3

This diff is too big to show here.

content/events/2021-05-27-town-hall.md+10−5

This diff is too big to show here.

content/events/2021-06-17-developer-workshop-bitcoin-lightning.mddeleted−22

This diff is too big to show here.

content/events/2021-07-01-developer-call-runtime-future.md+1

This diff is too big to show here.

content/events/2021-07-15-developer-call-yakshaving.md−2

This diff is too big to show here.

content/events/_index.mddeleted−6

This diff is too big to show here.

content/faq.md+52−41

This diff is too big to show here.

content/getting-started/_index.md+6−11

This diff is too big to show here.

content/getting-started/cli.md+20−23

This diff is too big to show here.

content/getting-started/planet.md+12−14

This diff is too big to show here.

content/gifts/sample.mdnew file+6

This diff is too big to show here.

content/grant-submission-guide.mdnew file+64

This diff is too big to show here.

content/grants/-smol-future-sustained-knowledge-sharing-and-marketing.mdnew file+94

This diff is too big to show here.

content/grants/_index.mddeleted−7

This diff is too big to show here.

content/grants/proposals/a-book-about-urbit.md → content/grants/a-book-about-urbit.mdrenamed+12−15

This diff is too big to show here.

content/grants/a-collaborative-web-mapping-system-for-urbit.mdnew file+90

This diff is too big to show here.

content/grants/bounties/analytics-script.md → content/grants/analytics-script.mdrenamed+6−8

This diff is too big to show here.

content/grants/bounties/antechamber.md → content/grants/antechamber.mdrenamed+13−13

This diff is too big to show here.

content/grants/apprenticeships/_index.mddeleted−4

This diff is too big to show here.

content/grants/apprenticeships/ua-3rd-party-software-distribution.mddeleted−50

This diff is too big to show here.

content/grants/apprenticeships/ua-filesharer.mddeleted−26

This diff is too big to show here.

content/grants/proposals/art-by-urbit.md → content/grants/art-by-urbit.mdrenamed+3−7

This diff is too big to show here.

content/grants/bounties/bart-train-tracker-landscape-tile.md → content/grants/bart-train-tracker-landscape-tile.mdrenamed+8−10

This diff is too big to show here.

content/grants/bounties/bitcoin-full-node-provider-and-wallet.md → content/grants/bitcoin-full-node-provider-and-wallet.mdrenamed+39−32

This diff is too big to show here.

content/grants/bounties/bitcoin-key-derivation.md → content/grants/bitcoin-key-derivation.mdrenamed+17−15

This diff is too big to show here.

content/grants/bounties/bitcoin-node-json-rpc-api-part-1.md → content/grants/bitcoin-node-json-rpc-api-part-1.mdrenamed+21−18

This diff is too big to show here.

content/grants/bounties/bitcoin-node-json-rpc-api-part-2.md → content/grants/bitcoin-node-json-rpc-api-part-2.mdrenamed+21−18

This diff is too big to show here.

content/grants/bounties/bitcoin-node-json-rpc-api-part-3.md → content/grants/bitcoin-node-json-rpc-api-part-3.mdrenamed+20−18

This diff is too big to show here.

content/grants/bounties/bitcoin-node-json-rpc-api-part-4.md → content/grants/bitcoin-node-json-rpc-api-part-4.mdrenamed+21−18

This diff is too big to show here.

content/grants/bounties/bitcoin-wallet-maintenance.md → content/grants/bitcoin-wallet-maintenance.mdrenamed+12−12

This diff is too big to show here.

content/grants/bounties/bitcoin-wallet-on-bridge.md → content/grants/bitcoin-wallet-on-bridge.mdrenamed+10−10

This diff is too big to show here.

content/grants/bounties/boston-t-train-tracker-landscape-tile.md → content/grants/boston-t-train-tracker-landscape-tile.mdrenamed+8−12

This diff is too big to show here.

content/grants/bounties/_index.mddeleted−4

This diff is too big to show here.

content/grants/bounties/bounty-vane-documentation.mddeleted−95

This diff is too big to show here.

content/grants/bounties/bridge-l2-revamp.md → content/grants/bridge-l2-revamp.mdrenamed+7−8

This diff is too big to show here.

content/grants/calendar-ui.mdnew file+52

This diff is too big to show here.

content/grants/proposals/calendar.md → content/grants/calendar.mdrenamed+9−11

This diff is too big to show here.

content/grants/proposals/comprehensive-local-server-and-mum-explanation-video.md → content/grants/comprehensive-local-server-and-mum-explanation-video.mdrenamed+5−4

This diff is too big to show here.

content/grants/apprenticeships/contacts.md → content/grants/contacts.mdrenamed+10−9

This diff is too big to show here.

content/grants/proposals/content-producer.md → content/grants/content-producer.mdrenamed+2−4

This diff is too big to show here.

content/grants/bounties/content-saver.md → content/grants/content-saver.mdrenamed+4−7

This diff is too big to show here.

content/grants/proposals/cross-platform-desktop-urbit-app.md → content/grants/cross-platform-desktop-urbit-app.mdrenamed+21−13

This diff is too big to show here.

content/grants/bounties/cta-train-tracker-landscape-tile.md → content/grants/cta-train-tracker-landscape-tile.mdrenamed+11−11

This diff is too big to show here.

content/grants/bounties/display-eth-data.md → content/grants/display-eth-data.mdrenamed+4−7

This diff is too big to show here.

content/grants/proposals/docker-image-for-cloud-container-orchestration.md → content/grants/docker-image-for-cloud-container-orchestration.mdrenamed+9−8

This diff is too big to show here.

content/grants/bounties/educational-guide-todomvc-urbit-edition.md → content/grants/educational-guide-todomvc-urbit-edition.mdrenamed+21−23

This diff is too big to show here.

content/grants/proposals/escape.md → content/grants/escape.mdrenamed+6−8

This diff is too big to show here.

content/grants/bounties/ethereum-abi-parser.md → content/grants/ethereum-abi-parser.mdrenamed+4−6

This diff is too big to show here.

content/grants/proposals/feed-aggregator.md → content/grants/feed-aggregator.mdrenamed+18−23

This diff is too big to show here.

content/grants/bounties/gall-api-documentation.md → content/grants/gall-api-documentation.mdrenamed+14−17

This diff is too big to show here.

content/grants/gifts/_index.mddeleted−4

This diff is too big to show here.

content/grants/bounties/go-airlock-library.md → content/grants/go-airlock-library.mdrenamed+4−7

This diff is too big to show here.

content/grants/proposals/graph-store-documentation-guide.md → content/grants/graph-store-documentation-guide.mdrenamed+47−35

This diff is too big to show here.

content/grants/proposals/guide-to-s3.md → content/grants/guide-to-s3.mdrenamed+2−2

This diff is too big to show here.

content/grants/bounties/haskell-airlock-library.md → content/grants/haskell-airlock-library.mdrenamed+3−7

This diff is too big to show here.

content/grants/proposals/hoon-001-learner-efficiency-and-early-learner-resources.md → content/grants/hoon-001-learner-efficiency-and-early-learner-resources.mdrenamed+10−15

This diff is too big to show here.

content/grants/bounties/host-three-college-university-urbit-meetups-1.md → content/grants/host-three-college-university-urbit-meetups-1.mdrenamed+11−6

This diff is too big to show here.

content/grants/bounties/host-three-college-university-urbit-meetups-2.md → content/grants/host-three-college-university-urbit-meetups-2.mdrenamed+11−6

This diff is too big to show here.

content/grants/bounties/host-three-college-university-urbit-meetups-3.md → content/grants/host-three-college-university-urbit-meetups-3.mdrenamed+12−6

This diff is too big to show here.

content/grants/bounties/host-three-virtual-urbit-meetups.md → content/grants/host-three-virtual-urbit-meetups.mdrenamed+5−7

This diff is too big to show here.

content/grants/bounties/host-two-urbit-meetups-1.md → content/grants/host-two-urbit-meetups-1.mdrenamed+12−7

This diff is too big to show here.

content/grants/bounties/host-two-urbit-meetups-10.md → content/grants/host-two-urbit-meetups-10.mdrenamed+12−7

This diff is too big to show here.

content/grants/bounties/host-two-urbit-meetups-11.md → content/grants/host-two-urbit-meetups-11.mdrenamed+11−6

This diff is too big to show here.

content/grants/bounties/host-two-urbit-meetups-12.md → content/grants/host-two-urbit-meetups-12.mdrenamed+6−7

This diff is too big to show here.

content/grants/bounties/host-two-urbit-meetups-2.md → content/grants/host-two-urbit-meetups-2.mdrenamed+12−7

This diff is too big to show here.

content/grants/bounties/host-two-urbit-meetups-3.md → content/grants/host-two-urbit-meetups-3.mdrenamed+12−7

This diff is too big to show here.

content/grants/bounties/host-two-urbit-meetups-4.md → content/grants/host-two-urbit-meetups-4.mdrenamed+12−7

This diff is too big to show here.

content/grants/bounties/host-two-urbit-meetups-5.md → content/grants/host-two-urbit-meetups-5.mdrenamed+12−7

This diff is too big to show here.

content/grants/bounties/host-two-urbit-meetups-6.md → content/grants/host-two-urbit-meetups-6.mdrenamed+12−7

This diff is too big to show here.

content/grants/bounties/host-two-urbit-meetups-7.md → content/grants/host-two-urbit-meetups-7.mdrenamed+12−7

This diff is too big to show here.

content/grants/bounties/host-two-urbit-meetups-8.md → content/grants/host-two-urbit-meetups-8.mdrenamed+12−7

This diff is too big to show here.

content/grants/bounties/host-two-urbit-meetups-9.md → content/grants/host-two-urbit-meetups-9.mdrenamed+12−7

This diff is too big to show here.

content/grants/bounties/json-jet.md → content/grants/json-jet.mdrenamed+13−14

This diff is too big to show here.

content/grants/proposals/links-in-urbit-reference-docs.md → content/grants/links-in-urbit-reference-docs.mdrenamed+2−4

This diff is too big to show here.

content/grants/proposals/llelogram.md → content/grants/llelogram.mdrenamed+16−19

This diff is too big to show here.

content/grants/proposals/login-with-urbit.md → content/grants/login-with-urbit.mdrenamed+17−12

This diff is too big to show here.

content/grants/bounties/matrices-in-hoon.md → content/grants/matrices-in-hoon.mdrenamed+9−10

This diff is too big to show here.

content/grants/proposals/matrixriotim-bridge-bot.md → content/grants/matrixriotim-bridge-bot.mdrenamed+8−7

This diff is too big to show here.

content/grants/proposals/minimal-urbit-os.md → content/grants/minimal-urbit-os.mdrenamed+6−7

This diff is too big to show here.

content/grants/bounties/network-explorer-data-pipeline-http-api.md → content/grants/network-explorer-data-pipeline-http-api.mdrenamed+21−19

This diff is too big to show here.

content/grants/bounties/network-explorer.md → content/grants/network-explorer.mdrenamed+20−16

This diff is too big to show here.

content/grants/bounties/nuck-jet.md → content/grants/nuck-jet.mdrenamed+17−9

This diff is too big to show here.

content/grants/bounties/open-street-maps-data-importation.md → content/grants/open-street-maps-data-importation.mdrenamed+6−9

This diff is too big to show here.

content/grants/bounties/overhaul-the-urbitorg-website.md → content/grants/overhaul-the-urbitorg-website.mdrenamed+7−9

This diff is too big to show here.

content/grants/proposals/_index.mddeleted−4

This diff is too big to show here.

content/grants/proposals/a-collaborative-web-mapping-system-for-urbit.mddeleted−99

This diff is too big to show here.

content/grants/proposals/calendar-ui.mddeleted−54

This diff is too big to show here.

content/grants/proposals/smol-future-sustained-knowledge-sharing-and-marketing.mddeleted−92

This diff is too big to show here.

content/grants/proposals/star-documentation-proposal.mddeleted−37

This diff is too big to show here.

content/grants/apprenticeships/ra-page-tracking.md → content/grants/ra-page-tracking.mdrenamed+5−4

This diff is too big to show here.

content/grants/apprenticeships/ra-segfaults.md → content/grants/ra-segfaults.mdrenamed+6−4

This diff is too big to show here.

content/grants/apprenticeships/ra-stack-overflow.md → content/grants/ra-stack-overflow.mdrenamed+5−4

This diff is too big to show here.

content/grants/proposals/ragnarok-online-on-urbit.md → content/grants/ragnarok-online-on-urbit.mdrenamed+5−8

This diff is too big to show here.

content/grants/proposals/search-in-groups.md → content/grants/search-in-groups.mdrenamed+6−7

This diff is too big to show here.

content/grants/bounties/slaw-scot-jets.md → content/grants/slaw-scot-jets.mdrenamed+14−10

This diff is too big to show here.

content/grants/bounties/staff-the-urbit-help-desk-1.md → content/grants/staff-the-urbit-help-desk-1.mdrenamed+15−14

This diff is too big to show here.

content/grants/bounties/staff-the-urbit-help-desk-2.md → content/grants/staff-the-urbit-help-desk-2.mdrenamed+15−14

This diff is too big to show here.

content/grants/bounties/staff-the-urbit-helpdesk-east.md → content/grants/staff-the-urbit-helpdesk-east.mdrenamed+5−9

This diff is too big to show here.

content/grants/bounties/staff-the-urbit-helpdesk-west.md → content/grants/staff-the-urbit-helpdesk-west.mdrenamed+5−6

This diff is too big to show here.

content/grants/submit-proposal.mddeleted−68

This diff is too big to show here.

content/grants/proposals/the-complete-guide-to-gall-and-landscape.md → content/grants/the-complete-guide-to-gall-and-landscape.mdrenamed+32−26

This diff is too big to show here.

content/grants/bounties/thread-documentation.md → content/grants/thread-documentation.mdrenamed+34−26

This diff is too big to show here.

content/grants/bounties/tor-nodes-relay-search-tile.md → content/grants/tor-nodes-relay-search-tile.mdrenamed+5−9

This diff is too big to show here.

content/grants/proposals/translate-key-parts-of-urbitorg-into-german.md → content/grants/translate-key-parts-of-urbitorg-into-german.mdrenamed+2−4

This diff is too big to show here.

content/grants/proposals/translate-key-parts-of-urbitorg-into-korean.md → content/grants/translate-key-parts-of-urbitorg-into-korean.mdrenamed+2−5

This diff is too big to show here.

content/grants/proposals/translate-key-parts-of-urbitorg-into-norwegian.md → content/grants/translate-key-parts-of-urbitorg-into-norwegian.mdrenamed+2−4

This diff is too big to show here.

content/grants/proposals/translate-key-parts-of-urbitorg-into-spanish.md → content/grants/translate-key-parts-of-urbitorg-into-spanish.mdrenamed+2−4

This diff is too big to show here.

content/grants/proposals/try-urbit-website.md → content/grants/try-urbit-website.mdrenamed+5−7

This diff is too big to show here.

content/grants/bounties/typescript-airlock-library.md → content/grants/typescript-airlock-library.mdrenamed+3−6

This diff is too big to show here.

content/grants/apprenticeships/ua-collaborative-text-editor.md → content/grants/ua-collaborative-text-editor.mdrenamed+8−6

This diff is too big to show here.

content/grants/ua-filesharer.mdnew file+28

This diff is too big to show here.

content/grants/apprenticeships/ua-heads-up-poker.md → content/grants/ua-heads-up-poker.mdrenamed+12−9

This diff is too big to show here.

content/grants/apprenticeships/ua-invoice-system.md → content/grants/ua-invoice-system.mdrenamed+12−9

This diff is too big to show here.

content/grants/apprenticeships/ua-marketplace.md → content/grants/ua-marketplace.mdrenamed+2−4

This diff is too big to show here.

content/grants/bounties/ucal-google-and-outlook-integration.md → content/grants/ucal-google-and-outlook-integration.mdrenamed+24−26

This diff is too big to show here.

content/grants/bounties/udon-syntax-highlighter.md → content/grants/udon-syntax-highlighter.mdrenamed+6−8

This diff is too big to show here.

content/grants/bounties/unit-tests-for-json-parsing.md → content/grants/unit-tests-for-json-parsing.mdrenamed+9−11

This diff is too big to show here.

content/grants/bounties/unit-tests-for-pure-algorithms.md → content/grants/unit-tests-for-pure-algorithms.mdrenamed+18−21

This diff is too big to show here.

content/grants/bounties/unit-tests-for-sha-functions.md → content/grants/unit-tests-for-sha-functions.mdrenamed+10−12

This diff is too big to show here.

content/grants/bounties/unit-tests-for-zuse-cryptographic-functions.md → content/grants/unit-tests-for-zuse-cryptographic-functions.mdrenamed+10−12

This diff is too big to show here.

content/grants/proposals/up-to-date-hoon-reference-card.md → content/grants/up-to-date-hoon-reference-card.mdrenamed+5−7

This diff is too big to show here.

content/grants/proposals/urbian-a-customized-linux-distribution-for-urbit-appliances.md → content/grants/urbian-a-customized-linux-distribution-for-urbit-appliances.mdrenamed+7−8

This diff is too big to show here.

content/grants/proposals/urbit-api-for-elixir.md → content/grants/urbit-api-for-elixir.mdrenamed+5−7

This diff is too big to show here.

content/grants/bounties/urbit-community-concierge-east-coast-2q2021.md → content/grants/urbit-community-concierge-east-coast-2q2021.mdrenamed+2−4

This diff is too big to show here.

content/grants/bounties/urbit-community-concierge-east-coast.md → content/grants/urbit-community-concierge-east-coast.mdrenamed+4−5

This diff is too big to show here.

content/grants/bounties/urbit-community-concierge-west-coast-2q2021.md → content/grants/urbit-community-concierge-west-coast-2q2021.mdrenamed+2−4

This diff is too big to show here.

content/grants/bounties/urbit-community-concierge-west-coast.md → content/grants/urbit-community-concierge-west-coast.mdrenamed+4−5

This diff is too big to show here.

content/grants/proposals/urbit-event-series.md → content/grants/urbit-event-series.mdrenamed+5−6

This diff is too big to show here.

content/grants/proposals/urbit-explainer-video.md → content/grants/urbit-explainer-video.mdrenamed+3−5

This diff is too big to show here.

content/grants/proposals/urbit-http-api-for-emacs-elisp.md → content/grants/urbit-http-api-for-emacs-elisp.mdrenamed+5−7

This diff is too big to show here.

content/grants/proposals/urbit-http-api-for-kotlin.md → content/grants/urbit-http-api-for-kotlin.mdrenamed+5−8

This diff is too big to show here.

content/grants/proposals/urbit-http-api-for-rust.md → content/grants/urbit-http-api-for-rust.mdrenamed+5−9

This diff is too big to show here.

content/grants/proposals/urbit-http-interface-java-edition.md → content/grants/urbit-http-interface-java-edition.mdrenamed+8−14

This diff is too big to show here.

content/grants/proposals/urbit-http-library-for-ruby.md → content/grants/urbit-http-library-for-ruby.mdrenamed+5−7

This diff is too big to show here.

content/grants/proposals/urbit-irc-bridge.md → content/grants/urbit-irc-bridge.mdrenamed+5−7

This diff is too big to show here.

content/grants/proposals/urbit-lfs-filehosting.md → content/grants/urbit-lfs-filehosting.mdrenamed+10−13

This diff is too big to show here.

content/grants/proposals/urbit-online-meetup.md → content/grants/urbit-online-meetup.mdrenamed+2−4

This diff is too big to show here.

content/grants/proposals/urbit-react-cookbook.md → content/grants/urbit-react-cookbook.mdrenamed+6−8

This diff is too big to show here.

content/grants/proposals/urbit-ship-and-star-hosting-and-troubleshooting-docs.md → content/grants/urbit-ship-and-star-hosting-and-troubleshooting-docs.mdrenamed+3−5

This diff is too big to show here.

content/grants/bounties/verifying-urbit-id-on-keybase.md → content/grants/verifying-urbit-id-on-keybase.mdrenamed+14−15

This diff is too big to show here.

content/grants/bounties/video-content-manager.md → content/grants/video-content-manager.mdrenamed+10−11

This diff is too big to show here.

content/grants/bounties/volt-lightning-on-urbit.md → content/grants/volt-lightning-on-urbit.mdrenamed+135−87

This diff is too big to show here.

content/grants/bounties/web-scraper.md → content/grants/web-scraper.mdrenamed+3−5

This diff is too big to show here.

content/grants/proposals/webrtc-gall-agent-and-external-app.md → content/grants/webrtc-gall-agent-and-external-app.mdrenamed+15−11

This diff is too big to show here.

content/grants/proposals/webrtc.md → content/grants/webrtc.mdrenamed+6−5

This diff is too big to show here.

content/media/_index.mddeleted−7

This diff is too big to show here.

content/media/blueprint-2017-galen-wolfe-pauly-on-the-distributed-web.md−1

This diff is too big to show here.

content/media/epicenter-episode-205-urbit-a-digital-republic-reinventing-the-internet.md−1

This diff is too big to show here.

content/media/lambdaconf-2016-curtis-yarvin-urbit-a-clean-slate-functional-operating-stack.md−1

This diff is too big to show here.

content/media/lambdaconf-2018-ted-blackman-ford-urbits-build-system.md−1

This diff is too big to show here.

content/media/the-ether-review-46-curtis-yarvin-and-galen-wolfe-pauly-on-urbit.md−1

This diff is too big to show here.

content/media/what-is-urbit.md−1

This diff is too big to show here.

content/privacy.md+22−22

This diff is too big to show here.

content/reset.md+3−3

This diff is too big to show here.

content/terms-of-use.md+24−25

This diff is too big to show here.

content/understanding-urbit/_index.md+66−7

This diff is too big to show here.

content/understanding-urbit/interface.md+7−8

This diff is too big to show here.

content/understanding-urbit/people-history.md+7−10

This diff is too big to show here.

content/understanding-urbit/roadmap.md+11−12

This diff is too big to show here.

content/understanding-urbit/urbit-id.md+7−7

This diff is too big to show here.

content/understanding-urbit/urbit-os.md+16−16

This diff is too big to show here.

content/updates/2018-2-17-update.md+14−13

This diff is too big to show here.

content/updates/2019-11-06-update.md+1−3

This diff is too big to show here.

content/updates/2019-12-06-update.md+6−8

This diff is too big to show here.

content/updates/2020-02-06-update.md+14−11

This diff is too big to show here.

content/updates/2020-04-04-update.md+5−6

This diff is too big to show here.

content/updates/2020-06-15-update.md+17−24

This diff is too big to show here.

content/updates/2020-07-27-update.md+3−4

This diff is too big to show here.

content/updates/2020-09-30-update.mdnew file+64

This diff is too big to show here.

content/updates/2020-10-29-update.mdnew file+48

This diff is too big to show here.

content/updates/2020-12-01-update.mdnew file+67

This diff is too big to show here.

content/updates/2021-01-15-update.mdnew file+59

This diff is too big to show here.

content/updates/2021-02-19-update.mdnew file+80

This diff is too big to show here.

content/updates/2021-04-01-update.mdnew file+88

This diff is too big to show here.

content/updates/2021-05-05-update.mdnew file+69

This diff is too big to show here.

content/updates/2021-06-16-update.mdnew file+77

This diff is too big to show here.

content/updates/_index.mddeleted−6

This diff is too big to show here.

content/using/_index.md+6−6

This diff is too big to show here.

content/using/id/_index.md+7−7

This diff is too big to show here.

content/using/id/creating-an-invite-pool.md+2−2

This diff is too big to show here.

content/using/id/guide-to-breaches.md+11−11

This diff is too big to show here.

content/using/id/using-bridge.md+5−5

This diff is too big to show here.

content/using/os/_index.md+6−6

This diff is too big to show here.

content/using/os/filesystem.md+4−4

This diff is too big to show here.

content/using/os/getting-started.md+9−11

This diff is too big to show here.

content/using/os/shell.md+2−2

This diff is too big to show here.

content/using/os/ship-troubleshooting.md+3−3

This diff is too big to show here.

content/using/os/stars-and-galaxies.md+3−3

This diff is too big to show here.

content/using/running/_index.md+2−2

This diff is too big to show here.

content/using/running/hosting.md+10−10

This diff is too big to show here.

static/images/favicon.ico → images/favicon.icorenamed

Binary file not shown.

lib/cache.jsnew file+73

This diff is too big to show here.

lib/constants.jsnew file+10

This diff is too big to show here.

lib/glossary.jsnew file+6396

This diff is too big to show here.

lib/hooks.jsnew file+37

This diff is too big to show here.

lib/lib.jsnew file+354

This diff is too big to show here.

lib/rss.jsnew file+97

This diff is too big to show here.

netlify.tomldeleted−9

This diff is too big to show here.

next.config.jsnew file+26

This diff is too big to show here.

package-lock.jsonnew file+6883

This diff is too big to show here.

package.jsonnew file+47

This diff is too big to show here.

pages/404.jsnew file+29

This diff is too big to show here.

pages/_app.jsnew file+71

This diff is too big to show here.

pages/api/search.jsnew file+10

This diff is too big to show here.

pages/blog.jsnew file+96

This diff is too big to show here.

pages/blog/[slug].jsnew file+132

This diff is too big to show here.

pages/bounties.jsnew file+17

This diff is too big to show here.

pages/community/[[...slug]].jsnew file+130

This diff is too big to show here.

pages/docs/[[...slug]].jsnew file+233

This diff is too big to show here.

pages/events.jsnew file+127

This diff is too big to show here.

pages/events/[slug].jsnew file+141

This diff is too big to show here.

pages/faq.jsnew file+17

This diff is too big to show here.

pages/getting-started/[[...slug]].jsnew file+153

This diff is too big to show here.

pages/grant-submission-guide.jsnew file+21

This diff is too big to show here.

pages/grants.jsnew file+372

This diff is too big to show here.

pages/grants/[slug].jsnew file+127

This diff is too big to show here.

pages/index.jsnew file+298

This diff is too big to show here.

pages/media.jsnew file+54

This diff is too big to show here.

pages/media/[slug].jsnew file+109

This diff is too big to show here.

pages/privacy.jsnew file+17

This diff is too big to show here.

pages/terms-of-service.jsnew file+21

This diff is too big to show here.

pages/understanding-urbit/[[...slug]].jsnew file+193

This diff is too big to show here.

pages/updates.jsnew file+79

This diff is too big to show here.

pages/updates/[slug].jsnew file+133

This diff is too big to show here.

pages/using/[[...slug]].jsnew file+163

This diff is too big to show here.

pages/voting-instructions.jsnew file+21

This diff is too big to show here.

patches/prismjs+1.24.1.patchnew file+42

This diff is too big to show here.

postcss.config.jsnew file+6

This diff is too big to show here.

sass/_events.scssdeleted−82

This diff is too big to show here.

sass/_main.scssdeleted−721

This diff is too big to show here.

sass/_responsive.scssdeleted−33

This diff is too big to show here.

sass/grid.scssdeleted−1542

This diff is too big to show here.

sass/indigo.scssdeleted−2408

This diff is too big to show here.

sass/styles.scssdeleted−3

This diff is too big to show here.

static/_redirectsdeleted−165

This diff is too big to show here.

static/detect.jsdeleted−26

This diff is too big to show here.

static/glossary.jsdeleted−5681

This diff is too big to show here.

static/scripts.jsdeleted−469

This diff is too big to show here.

static/viewport-units-buggyfill.jsdeleted−472

This diff is too big to show here.

styles/globals.cssnew file+205

This diff is too big to show here.

styles/markdown.module.cssnew file+103

This diff is too big to show here.

styles/prism.cssnew file+170

This diff is too big to show here.

syntaxes/hoon.sublime-syntaxdeleted−66

This diff is too big to show here.

syntaxes/scheme.sublime-syntaxdeleted−566

This diff is too big to show here.

tailwind.config.jsnew file+52

This diff is too big to show here.

templates/.gitignoredeleted−2

This diff is too big to show here.

templates/404.htmldeleted−29

This diff is too big to show here.

templates/anchor-link.htmldeleted−2

This diff is too big to show here.

templates/base.htmldeleted−73

This diff is too big to show here.

templates/doc.htmldeleted−28

This diff is too big to show here.

templates/essays/list.htmldeleted−49

This diff is too big to show here.

templates/essays/post.htmldeleted−71

This diff is too big to show here.

templates/events/event-landing.htmldeleted−26

This diff is too big to show here.

templates/events/event.htmldeleted−94

This diff is too big to show here.

templates/events/list.htmldeleted−157

This diff is too big to show here.

templates/getting-started/index.htmldeleted−41

This diff is too big to show here.

templates/grant_category/list.htmldeleted−1

This diff is too big to show here.

templates/grant_category/single.htmldeleted−36

This diff is too big to show here.

templates/grant_type/apprenticeships.htmldeleted−81

This diff is too big to show here.

templates/grant_type/bounties.htmldeleted−47

This diff is too big to show here.

templates/grant_type/gifts.htmldeleted−56

This diff is too big to show here.

templates/grant_type/list.htmldeleted−1

This diff is too big to show here.

templates/grant_type/proposals.htmldeleted−91

This diff is too big to show here.

templates/grant_type/single.htmldeleted−23

This diff is too big to show here.

templates/grants/grant.htmldeleted−71

This diff is too big to show here.

templates/grants/list.htmldeleted−101

This diff is too big to show here.

templates/index.htmldeleted−207

This diff is too big to show here.

templates/list.htmldeleted−49

This diff is too big to show here.

templates/macros/macros.htmldeleted−65

This diff is too big to show here.

templates/media/list.htmldeleted−81

This diff is too big to show here.

templates/media/post.htmldeleted−68

This diff is too big to show here.

templates/page.htmldeleted−78

This diff is too big to show here.

templates/page_indiced.htmldeleted−86

This diff is too big to show here.

templates/partials/footer.htmldeleted−54

This diff is too big to show here.

templates/partials/navigation-docs.htmldeleted−225

This diff is too big to show here.

templates/partials/navigation-search.htmldeleted−29

This diff is too big to show here.

templates/partials/pagination-docs.htmldeleted−10

This diff is too big to show here.

templates/partials/pagination.htmldeleted−79

This diff is too big to show here.

templates/partials/search-overlay.htmldeleted−25

This diff is too big to show here.

templates/partials/subscribe-form.htmldeleted−34

This diff is too big to show here.

templates/post_type/list.htmldeleted−1

This diff is too big to show here.

templates/post_type/single.htmldeleted−1

This diff is too big to show here.

templates/robots.txtdeleted−1

This diff is too big to show here.

templates/rss.xmldeleted−21

This diff is too big to show here.

templates/sections/docs.htmldeleted−26

This diff is too big to show here.

templates/sections/docs/chapters.htmldeleted−26

This diff is too big to show here.

templates/sections/docs/glossary.htmldeleted−57

This diff is too big to show here.

templates/sections/docs/hoon.htmldeleted−52

This diff is too big to show here.

templates/sections/index.htmldeleted

No changes to the content.

templates/shortcodes/soundcloud.htmldeleted−8

This diff is too big to show here.

templates/shortcodes/youtube.htmldeleted−8

This diff is too big to show here.

templates/taxonomy/list.htmldeleted−33

This diff is too big to show here.

templates/taxonomy/single.htmldeleted−44

This diff is too big to show here.

templates/understanding-urbit/list.htmldeleted−84

This diff is too big to show here.

templates/understanding-urbit/post.htmldeleted−80

This diff is too big to show here.

templates/updates/list.htmldeleted−69

This diff is too big to show here.

vercel.json+831−4

This diff is too big to show here.

yarn.locknew file+1865

This diff is too big to show here.