Merge branch 'test'

This commit is contained in:
Anton Dyudin 2015-10-22 10:17:39 -07:00
commit 3c01a8a5d4
260 changed files with 7713 additions and 9668 deletions

View File

@ -86,6 +86,7 @@
++ peer-drum (wrap peer):from-drum
++ poke-dill-belt (wrap poke-dill-belt):from-drum
++ poke-drum-link (wrap poke-link):from-drum
++ poke-drum-unlink (wrap poke-unlink):from-drum
::++ poke-drum-exit (wrap poke-exit):from-drum
++ poke-drum-start (wrap poke-start):from-drum
++ poke-helm-hi (wrap poke-hi):from-helm

View File

@ -1430,8 +1430,8 @@
^- (bolt type)
%+ (clef %slit) (fine cof gat sam)
|= [cof=cafe gat=type sam=type]
%+ cool |.(>sam<)
%+ cool |.(>(~(peek ut gat) %free 6)<)
%+ cool |.(%.(%have ~(dunk ut sam)))
%+ cool |.(%.(%want ~(dunk ut (~(peek ut gat) %free 6))))
=+ top=(mule |.((slit gat sam)))
?- -.top
| (flaw cof p.top)

View File

@ -1,2 +0,0 @@
/: /%%%/tree/pub/blog /% /hymn/
-<

View File

@ -1,2 +0,0 @@
/: /%%%/tree/pub/blog /% /json/
-<

2
docs/hymn.hook Normal file
View File

@ -0,0 +1,2 @@
/: /%%%/tree/pub/docs /% /hymn/
-<

2
docs/json.hook Normal file
View File

@ -0,0 +1,2 @@
/: /%%%/tree/pub/docs /% /json/
-<

2
front/hymn.hook Normal file
View File

@ -0,0 +1,2 @@
/: /%%%/tree/pub/front /% /hymn/
-<

2
front/json.hook Normal file
View File

@ -0,0 +1,2 @@
/: /%%%/tree/pub/front /% /json/
-<

15
gen/hood/unlink.hoon Normal file
View File

@ -0,0 +1,15 @@
::
:::: /hoon/link/hood/gen
::
/? 314
::
::::
!:
:- %say
|= $: [now=@da eny=@uvI byk=beak]
[arg=$?([dap=term ~] [who=ship dap=term ~]) ~]
==
:- %drum-unlink
?~ +.arg
[p.byk dap.arg]
[who.arg dap.arg]

16
gen/moon.hoon Normal file
View File

@ -0,0 +1,16 @@
::
:::: /hoon/ticket/gen
::
/? 314
::
::::
!:
:- %say
|= $: [now=@da eny=@uvI bec=beak]
[~ ~]
==
:- %noun
?> =(1 (met 5 p.bec))
=+ mon=(mix (lsh 5 1 (end 5 1 eny)) p.bec)
=+ tic=((hard ,@p) .^(/a/(scot %p p.bec)/tick/(scot %da now)/(scot %p mon)))
"moon: {<`@p`mon>}; ticket: {<tic>}"

View File

@ -178,6 +178,11 @@
=< se-abet =< se-view
(se-link gyl)
::
++ poke-unlink ::
|= gyl=gill
=< se-abet =< se-view
(se-klin gyl)
::
:: ++ poke-exit ::
:: |=(~ se-abet:(se-blit `dill-blit`[%qit ~])) :: XX find bone
:: ::
@ -407,6 +412,10 @@
?~ t.yal i.yal
:(welp i.yal ", " $(yal t.yal))
::
++ se-klin :: disconnect app
|= gyl=gill
+>(eel (~(del in eel) gyl))
::
++ se-link :: connect to app
|= gyl=gill
+>(eel (~(put in eel) gyl))

View File

@ -275,6 +275,7 @@ window.urb.util = {
},
basepath: function(spur, pathname){
spur = spur || ''
if(spur === '/') spur = ''
pathname = pathname || window.location.pathname
if(pathname[0] == '/') pathname = pathname.slice(1)
pathname = pathname.split("/")

View File

@ -1,150 +0,0 @@
---
sort: 2
---
arvo
====
Our operating system.
arvo is composed of modules called vanes:
<list dataPreview="true"></list>
<hr></hr>
At a high level `%arvo` takes a mess of unix io events and turns them
into something clean and structured for the programmer.
`%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 io 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.
`++ducts`
---------
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.
Here's a duct that was recently observed in the wild:
~[
/g/a/~zod/4_shell_terminal/u/time
/g/a/~zod/shell_terminal/u/child/4/main
/g/a/~zod/terminal/u/txt
/d/term-mess
//term/1
]
This is the duct the timer vane receives when "timer" sample app asks
the timer vane 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 the timer vane to set a timer.
The timer vane saves this duct, so that when the specified time arrives
and unix sends a wakeup event to the timer vane, it can produce the
response on the same duct. This response is routed to the place we
popped off the top of the duct, i.e. the time app. This app produces the
text "ding", which falls down to the shell, which drops it through to
the terminal. Terminal drops this down to dill, which converts it into
an effect that unix will recognize as a request to print "ding" to the
screen. When dill produces this, the last path in the duct has an
initial element of the empty span, so this is routed to unix, which
applies the effects.
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 ducts for later use. There are definitely parallels to Scheme-style
continuations, but simpler and with more structure.
Making Moves
------------
If ducts are a call stack, then how do we make calls and produce
results? Arvo processes "moves" which are a combination of message data
and metadata. There are two types of moves. A `%pass` move is analogous
to a call:
[duct %pass return-path=path vane-name=@tD data=card]
Arvo pushes the return path (preceded by the first letter of the vane
name) onto the duct and sends the given data, a card, to the vane we
specified. Any response will come along the same duct with the path
`return-path`.
A `%give` move is analogous to a return:
[duct %give data=card]
Arvo pops the top path off the duct and sends the given card back to the
caller.
Vanes
-----
As shown above, we use arvo proper to route and control the flow of
moves. However, arvo proper is rarely directly responsible for
processing the event data that directly causes the desired outcome of a
move. This event data is contained within a card, which is simply a
`(pair term noun)`. 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.
As of this writing, we have seven vanes, which each provide the
following services:
- `%ames` name of both our network and the vane that communicates over
it
- `%clay` version-controlled, referentially- transparent, and global
filesystem
- `%dill` terminal driver. Unix sends keyboard events to `%dill` from
either the console or telnet, and `%dill` produces terminal output.
- `%eyre` http server. Unix sends http messages to `%eyre`, and
`%eyre` produces http messages in response
- `%ford` handles resources and publishing
- `%gall` manages our userspace applications.. `%gall` keeps state and
manages subscribers
- `%time` a simple timer
Cards
-----
Cards are the vane-specific portion of a move. Each vane defines a
protocol for interacting with other vanes (via arvo) by defining four
types of cards: kisses, gifts, notes, and signs.
When one vane is `%pass`ed a card in its `++kiss`, arvo activates the
`++call` gate with the card as its argument. To produce a result, the
vane `%give`s one of the cards 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 cards defined in its `++sign`.
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 `++kiss`. (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`.
When a `++kiss` card is passed to a vane, arvo calls its `++call` gate,
passing it both the card and its duct. This gate must be defined in
every vane. It produces two things in the following order: a list of
moves and a possibly-modified copy of its context. The moves are used to
interact with other vanes, while the new context allows the vane to save
its state. The next time arvo activates the vane it will have this
context as its subject.
This overview has detailed how to pass a card to a particular vane. To
see the cards each vane can be `%pass`ed as a `++kiss` 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.

View File

@ -1,29 +0,0 @@
<div class="short">
`%ames`
=======
Our networking protocol.
`%ames` is the name of both our network and the vane that communicates
over it. When Unix receives a packet over the correct UDP port, it pipes
it straight into `%ames` for handling. Also, all packets sent over the
`%ames` network are sent by the `%ames` vane. Apps and vanes may use
`%ames` to directly send messages to other ships. In general, apps use
gall and clay to communicate with other ships rather than using `%ames`
directly, but this isn't a requirement. Of course, gall and clay use
`%ames` behind the scenes to communicate across the network. These are
the only two vanes that use `%ames`.
`%ames` includes several significant components. Although the actual
crypto algorithms are defined in zuse, they're used extensively in
`%ames` for encrypting and decrypting packets. Congestion control and
routing is handled entirely in `%ames`. Finally, the actual `%ames`
protocol itself, including how to route incoming packets to the correct
vane or app, is defined in `%ames`.
</div>
<hr>
</hr>
<list></list>

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +0,0 @@
<div class="short">
`%arvo`
=======
Our operating system.
</div>

View File

@ -1,4 +0,0 @@
`%arvo` commentary
==================
`%arvo` is our operating system.

View File

@ -1,27 +0,0 @@
<div class="short">
`%clay`
=======
Our filesystem.
`%clay` is version-controlled, referentially-transparent, and global.
While this filesystem is stored in `%clay`, it is mirrored to Unix for
convenience. Unix tells `%clay`s whenever a file changes in the Unix
copy of the filesystem so that the change may be applied. `%clay` tells
unix whenever an app or vane changes the filesystem so that the change
can be effected in Unix. Apps and vanes may use `%clay` to write to the
filesystem, query it, and subscribe to changes in it. Ford and gall use
`%clay` to serve up apps and web pages.
`%clay` includes three components. First is the filesystem/version
control algorithms, which are mostly defined in `++ze` and `++zu` in
zuse. Second is the write, query, and subscription logic. Finally, there
is the logic for communicating requests to, and receiving requests from,
foreign ships.
</div>
------------------------------------------------------------------------
<list></list>

View File

@ -1,415 +0,0 @@
# clay
## high-level
clay is the primary filesystem for the arvo operating system,
which is the core of an urbit. The architecture of clay is
intrinsically connected with arvo, but we assume no knowledge of
either arvo or urbit. We will point out only those features of
arvo that are necessary for an understanding of clay, and we will
do so only when they arise.
The first relevant feature of arvo is that it is a deterministic
system where input and output are defined as a series of events
and effects. The state of arvo is simply a function of its event
log. None of the effects from an event are emitted until the
event is entered in the log and persisted, either to disk or
another trusted source of persistence, such as a Kafka cluster.
Consequently, arvo is a single-level store: everything in its
state is persistent.
In a more traditional OS, everything in RAM can be erased at any
time by power failure, and is always erased on reboot. Thus, a
primary purpose of a filesystem is to ensure files persist across
power failures and reboots. In arvo, both power failures and
reboots are special cases of suspending computation, which is
done safely since our event log is already persistent. Therefore,
clay is not needed in arvo for persistence. Why, then, do we have a
filesystem? There are two answers to this question.
First, clay provides a filesystem tree, which is a convenient
user interface for some applications. Unix has the useful concept
of virtual filesystems, which are used for everything from direct
access to devices, to random number generators, to the /proc
tree. It is easy and intuitive to read from and write to a
filesystem tree.
Second, clay has a distributed revision control system baked into
it. Traditional filesystems are not revision controlled, so
userspace software -- such as git -- is written on top of them to
do so. clay natively provides the same functionality as modern
DVCSes, and more.
clay has two other unique properties that we'll cover later on:
it supports typed data and is referentially transparent.
### Revision Control
Every urbit has one or more "desks", which are independently
revision-controlled branches. Each desk contains its own mark
definitions, apps, doc, and so forth.
Traditionally, an urbit has at least a base and a home desk. The
base desk has all the system software from the distribution. the
home desk is a fork of base with all the stuff specific to the
user of the urbit.
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.
Most commits have exactly one parent, but the initial commit on a
desk may have zero parents, and merge commits have more than one
parent.
The non-meta data is stored in the map of paths to data. It's
worth noting that no constraints are put on this map, so, for
example, both /a/b and /a/b/c could have data. This is impossible
in a traditional Unix filesystem since it means that /a/b is both
a file and a directory. Conventionally, the final element in the
path is its mark -- much like a filename extension in Unix. Thus,
/doc/readme.md in Unix is stored as /doc/readme/md in urbit.
The data is not stored directly in the map; rather, a hash of the
data is stored, and we maintain a master blob store. Thus, if the
same data is referred to in multiple commits (as, for example,
when a file doesn't change between commits), only the hash is
duplicated.
In the master blob store, we either store the data directly, or
else we store a diff against another blob. The hash is dependent
only on the data within and not on whether or not it's stored
directly, so we may on occasion rearrange the contents of the
blob store for performance reasons.
Recall that a desk is a series of numbered commits. Not every
commit in a desk must be numbered. For example, if the base desk
has had 50 commits since home was forked from it, then a merge
from base to home will only add a single revision number to home,
although the full commit history will be accessible by traversing
the parentage of the individual commits.
We do guarantee that the first commit is numbered 1, commits are
numbered consecutively after that (i.e. there are no "holes"),
the topmost commit is always numbered, and every numbered commit
is an ancestor of every later numbered commit.
There are three ways to refer to particular commits in the
revision history. Firstly, one can use the revision number.
Secondly, one can use any absolute time between the one numbered
commit and the next (inclusive of the first, exclusive of the
second). Thirdly, every desk has a map of labels to revision
numbers. These labels may be used to refer to specific commits.
Additionally, clay is a global filesystem, so data on other urbit
is easily accessible the same way as data on our local urbit. In
general, the path to a particular revision of a desk is
/~urbit-name/desk-name/revision. Thus, to get /try/readme/md
from revision 5 of the home desk on ~sampel-sipnym, we refer to
/~sampel-sipnym/home/5/try/readme/md. Clay's namespace is thus
global and referentially transparent.
XXX reactivity here?
### A Typed Filesystem
Since clay is a general filesystem for storing data of arbitrary
types, in order to revision control correctly it needs to be
aware of types all the way through. Traditional revision control
does an excellent job of handling source code, so for source code
we act very similar to traditional revision control. The
challenge is to handle other data similarly well.
For example, modern VCSs generally support "binary files", which
are files for which the standard textual diffing, patching, and
merging algorithms are not helpful. A "diff" of two binary files
is just a pair of the files, "patching" this diff is just
replacing the old file with the new one, and "merging"
non-identical diffs is always a conflict, which can't even be
helpfully annotated. Without knowing anything about the structure
of a blob of data, this is the best we can do.
Often, though, "binary" files have some internal structure, and
it is possible to create diff, patch, and merge algorithms that
take advantage of this structure. An image may be the result of a
base image with some set of operations applied. With algorithms
aware of this set of operations, not only can revision control
software save space by not having to save every revision of the
image individually, these transformations can be made on parallel
branches and merged at will.
Suppose Alice is tasked with touching up a picture, improving the
color balance, adjusting the contrast, and so forth, while Bob
has the job of cropping the picture to fit where it's needed and
adding textual overlay. Without type-aware revision control,
these changes must be made serially, requiring Alice and Bob to
explicitly coordinate their efforts. With type-aware revision
control, these operations may be performed in parallel, and then
the two changesets can be merged programmatically.
Of course, even some kinds of text files may be better served by
diff, patch, and merge algorithms aware of the structure of the
files. Consider a file containing a pretty-printed JSON object.
Small changes in the JSON object may result in rather significant
changes in how the object is pretty-printed (for example, by
addding an indentation level, splitting a single line into
multiple lines).
A text file wrapped at 80 columns also reacts suboptimally with
unadorned Hunt-McIlroy diffs. A single word inserted in a
paragraph may push the final word or two of the line onto the
next line, and the entire rest of the paragraph may be flagged as
a change. Two diffs consisting of a single added word to
different sentences may be flagged as a conflict. In general,
prose should be diffed by sentence, not by line.
As far as the author is aware, clay is the first generalized,
type-aware revision control system. We'll go into the workings
of this system in some detail.
### Marks
Central to a typed filesystem is the idea of types. In clay, we
call these "marks". A mark is a file that defines a type,
conversion routines to and from the mark, and diff, patch, and
merge routines.
For example, a `%txt` mark may be a list of lines of text, and it
may include conversions to `%mime` to allow it to be serialized
and sent to a browswer or to the unix filesystem. It will also
include Hunt-McIlroy diff, patch, and merge algorithms.
A `%json` mark would be defined as a json object in the code, and
it would have a parser to convert from `%txt` and a printer to
convert back to `%txt`. The diff, patch, and merge algorithms are
fairly straightforward for json, though they're very different
from the text ones.
More formally, a mark is a core with three arms, `++grab`,
`++grow`, and `++grad`. In `++grab` is a series of functions to
convert from other marks to the given mark. In `++grow` is a
series of functions to convert from the given mark to other
marks. In `++grad` is `++diff`, `++pact`, `++join`, and `++mash`.
The types are as follows, in an informal pseudocode:
++ grab:
++ mime: <mime> -> <mark-type>
++ txt: <txt> -> <mark-type>
...
++ grow:
++ mime: <mark-type> -> <mime>
++ txt: <mark-type> -> <txt>
...
++ grad
++ diff: (<mark-type>, <mark-type>) -> <diff-type>
++ pact: (<mark-type>, <diff-type>) -> <mark-type>
++ join: (<diff-type>, <diff-type>) -> <diff-type> or NULL
++ mash: (<diff-type>, <diff-type>) -> <diff-type>
These types are basically what you would expect. Not every mark
has each of these functions defined -- all of them are optional
in the general case.
In general, for a particular mark, the `++grab` and `++grow` entries
(if they exist) should be inverses of each other.
In `++grad`, `++diff` takes two instances of a mark and produces
a diff of them. `++pact` takes an instance of a mark and patches
it with the given diff. `++join` takes two diffs and attempts to
merge them into a single diff. If there are conflicts, it
produces null. `++mash` takes two diffs and forces a merge,
annotating any conflicts.
In general, if `++diff` called with A and B produces diff D, then
`++pact` called with A and D should produce B. Also, if `++join`
of two diffs does not produce null, then `++mash` of the same
diffs should produce the same result.
Alternately, instead of `++diff`, `++pact`, `++join`, and
`++mash`, a mark can provide the same functionality by defining
`++sted` to be the name of another mark to which we wish to
delegate the revision control responsibilities. Then, before
running any of those functions, clay will convert to the other
mark, and convert back afterward. For example, the `%hoon` mark
is revision-controlled in the same way as `%txt`, so its `++grad`
is simply `++sted %txt`. Of course, `++txt` must be defined in
`++grow` and `++grab` as well.
Every file in clay has a mark, and that mark must have a
fully-functioning `++grad`. Marks are used for more than just
clay, and other marks don't need a `++grad`, but if a piece of
data is to be saved to clay, we must know how to revision-control
it.
Additionally, if a file is to be synced out to unix, then it must
have conversion routines to and from the `%mime` mark.
##Using clay
### Reading and Subscribing
When reading from Clay, there are three types of requests. A
`%sing` request asks for data at single revsion. A `%next`
request asks to be notified the next time there's a change to
given file. A `%many` request asks to be notified on every
change in a desk for a range of changes.
For `%sing` and `%next`, there are generally three things to be
queried. A `%u` request simply checks for the existence of a
file at a path. A `%x` request gets the data in the file at a
path. A `%y` request gets a hash of the data in the file at the
path combined with all its children and their data. Thus, `%y`
of a node changes if it or any of its children change.
A `%sing` request is fulfilled immediately if possible. If the
requested revision is in the future, or is on another ship for
which we don't have the result cached, we don't respond
immediately. If the requested revision is in the future, we wait
until the revision happens before we respond to the request. If
the request is for data on another ship, we pass on the request
to the other ship. In general, Clay subscriptions, like most
things in Urbit, aren't guaranteed to return immediately.
They'll return when they can, and they'll do so in a
referentially transparent manner.
A `%next` request checks query at the given revision, and it
produces the result of the query the next time it changes, along
with the revsion number when it changes. Thus, a `%next` of a
`%u` is triggered when a file is added or deleted, a `%next` of a
`%x` is triggered when a file is added, deleted, or changed, and
a `%next` of a `%y` is triggered when a file or any of its
children is added, deleted, or changed.
A `%many` request is triggered every time the given desk has a
new revision. Unlike a `%next`, a `%many` has both a start and
an end revsion, after which it stops returning. For `%next`, a
single change is reported, and if the caller wishes to hear of
the next change, it must resubscribe. For `%many`, every revsion
from the start to the end triggers a response. Since a `%many`
request doesn't ask for any particular data, there aren't `%u`,
`%x`, and `%y` versions for it.
### Unix sync
One of the primary functions of clay is as a convenient user
interface. While tools exist to use clay from within urbit, it's
often useful to be able to treat clay like any other filesystem
from the Unix perspective -- to "mount" it, as it were.
From urbit, you can run `|mount /path/to/directory %mount-point`,
and this will mount the given clay directory to the mount-point
directory in Unix. Every file is converted to `%mime` before it's
written to Unix, and converted back when read from Unix. The
entire directory is watched (a la Dropbox), and every change is
auto-committed to clay.
### Merging
Merging is a fundamental operation for a distributed revision
control system. At their root, clay's merges are similar to
git's, but with some additions to accomodate typed data. There
are seven different merge strategies.
Throughout our discussion, we'll say that the merge is from
Alice's desk to Bob's. Recall that a commit is a date (for all
new commits this will be the current date), a list of parents,
and the data itself.
A `%init` merge should be used iff it's the first commit to a
desk. The head of Alice's desk is used as the number 1 commit to
Bob's desk. Obviously, the ancestry remains intact through
traversing the parentage of the commit even though previous
commits are not numbered for Bob's desk.
A `%this` merge means to keep what's in Bob's desk, but join the
ancestry. Thus, the new commit has the head of each desk as
parents, but the data is exactly what's in Bob's desk. For those
following along in git, this is the 'ours' merge strategy, not
the '--ours' option to the 'recursive' merge strategy. In other
words, even if Alice makes a change that does not conflict with
Bob, we throw it away. It's Bob's way or the highway.
A `%that` merge means to take what's in Alice's desk, but join
the ancestry. This is the reverse of `%this`.
A `%fine` merge is a "fast-forward" merge. This succeeds iff one
head is in the ancestry of the other. In this case, we use the
descendant as our new head.
For `%meet`, `%mate`, and `%meld` merges, we first find the most
recent common ancestor to use as our merge base. If we have no
common ancestors, then we fail. If we have more than one most
recent common ancestor, then we have a criss-cross situation,
which should be handled delicately. At present, we delicately
throw up our hands and give up, but something akin to git's
'recursive' strategy should be implemented in the future.
There's a functional inclusion ordering on `%fine`, `%meet`,
`%mate`, and `%meld` such that if an earlier strategy would have
succeeded, then every later strategy will produce the same
result. Put another way, every earlier strategy is the same as
every later strategy except with a restricted domain.
A `%meet` merge only succeeds if the changes from the merge base
to Alice's head (hereafter, "Alice's changes") are in different
files than Bob's changes. In this case, the parents are both
Alice's and Bob's heads, and the data is the merge base plus
Alice's changed files plus Bob's changed files.
A `%mate` merge attempts to merge changes to the same file when
both Alice and bob change it. If the merge is clean, we use it;
otherwise, we fail. A merge between different types of changes --
for example, deleting a file vs changing it -- is always a
conflict. If we succeed, the parents are both Alice's and Bob's
heads, and the data is the merge base plus Alice's changed files
plus Bob's changed files plus the merged files.
A `%meld` merge will succeed even if there are conflicts. If
there are conflicts in a file, then we use the merge base's
version of that file, and we produce a set of files with
conflicts. The parents are both Alice's and Bob's heads, and the
data is the merge base plus Alice's changed files plus Bob's
changed files plus the successfully merged files plus the merge
base's version of the conflicting files.
That's the extent of the merge options in clay proper. In
userspace there's a final option `%auto`, which is the most
common. `%auto` checks to see if Bob's desk exists, and if it
doesn't we use a `%init` merge. Otherwise, we progressively try
`%fine`, `%meet`, and `%mate` until one succeeds.
If none succeed, we merge Bob's desk into a scratch desk. Then,
we merge Alice's desk into the scratch desk with the `%meld`
option to force the merge. For each file in the produced set of
conflicting files, we call the `++mash` function for the
appropriate mark, which annotates the conflicts if we know how.
Finally, we display a message to the user informing them of the
scratch desk's existence, which files have annotated conflicts,
and which files have unannotated conflicts. When the user has
resolved the conflicts, they can merge the scratch desk back into
Bob's desk. This will be a `%fine` merge since Bob's head is in
the ancestry of the scratch desk.
### Autosync
Tracking and staying in sync with another desk is another
fundamental operation. We call this "autosync". This doesn't mean
simply mirroring a desk, since that wouldn't allow local changes.
We simply want to apply changes as they are made upstream, as
long as there are no conflicts with local changes.
This is implemented by watching the other desk, and, when it has
changes, merging these changes into our desk with the usual merge
strategies.
Note that it's quite reasonable for two desks to be autosynced to
each other. This results in any change on one desk being mirrored
to the other and vice versa.
Additionally, it's fine to set up an autosync even if one desk,
the other desk, or both desks do not exist. The sync will be
activated when the upstream desk comes into existence and will
create the downstream desk if needed.

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +0,0 @@
<div class="short">
`%dill`
=======
Our terminal driver.
Unix sends keyboard events to `%dill` from either the console or telnet,
and `%dill` produces terminal output. The only app that should directly
talk to `%dill` is the terminal app. Command-line apps are run by,
receive input from, and produce output to, the `%shell` app, which is
controlled by `%terminal`, which talks to `%dill`, which talks to unix.
Clay also uses `%dill` directly to print out the filesystem change
events, but this is questionable behavior.
`%dill` has two main components. First, it controls the terminal on a
very basic, event-by-event level. This includes keeping track of things
like the dimensions of the terminal, the prompt type (plain text or
password), which duct to produce effects on, and so forth. Second, it
handles terminal events, keystroke by keystroke. Most characters are
simply pushed onto the buffer and blitted to the screen, but some
characters, including control-modified keys, arrow keys, etc. require
special handling. Most of the readline functionality is in `%dill`.
</div>
------------------------------------------------------------------------

View File

@ -1,5 +0,0 @@
Dill: Reference
===============
Dill: Commentary
================

View File

@ -1,63 +0,0 @@
<div class="short">
`%eyre`
=======
Our http server.
Unix sends http messages to `%eyre`, and `%eyre` produces http messages
in response. In general, apps and vanes do not call `%eyre`; rather,
`%eyre` calls apps and vanes. `%eyre` uses `%ford` and `%gall` to
functionally publish pages and facilitate communication with apps.
`%eyre` primarily parses web requests and handles them in a variety of
ways, depending on the control string. Nearly all of these are
essentially stateless, like functional publishing with `%ford`.
Additionally, there's a fairly significant component that handles
`%gall` messaging and subscriptions, which must be stateful.
</div>
------------------------------------------------------------------------
HTTP Methods
============
`GET` `gog` `https://[ship-name].urbit.org/gog/[service]` Owner
requesting a page on her own Urbit. `gig`
`https://[ship-name].urbit.org/gig/[user-name]/[service]` Another user
requesting a page on a foreign Urbit.
`goe`
`https://[ship-name].urbit.org/goe/[service]/[port]/[stream]/[sequence]`
`https://[ship-name].urbit.org/goe/[service]/[port]/[stream]/[sequence].json`
Pulls a specific response to her subscription on her own Urbit. `gie`
`https://[ship-name].urbit.org/gie/[user-name]/[service]/[port]/[stream]/[sequence]`
`https://[ship-name].urbit.org/gie/[user-name]/[service]/[port]/[stream]/[sequence].json`
Pulls a specific response to her subscription on a foreign Urbit.
`PUT` `tos`
`https://[ship-name].urbit.org/tos/[service]/[port]/[stream]/[path]`
`{oryx: [string]}` Initiate a subscription on her own Urbit. `tis`
`https://[ship-name].urbit.org/tis/[user-name]/[service]/[port]/[stream]/[path]`
`{oryx: [string]}` Initiate a subscription on a foreign Urbit.
`tom` `https://[ship-name].urbit.org/tom/[service]/[port]/[sequence]`
`{oryx: [string], xyro: [json]}` Send a message to her Urbit with
sequence number `[sequence]`. `tim`
`https://[ship-name].urbit.org/tim/[user-name]/[service]/[port]/[sequence]`
`{oryx: [string], xyro: [json]}` Send a message to a foreign Urbit with
sequence number `[sequence]`.
`tou` `https://[ship-name].urbit.org/tou/[service]/[port]/[stream]`
Unsubscribe from stream `[stream]` on her Urbit. `tiu`
`https://[ship-name].urbit.org/tiu/[user-name]/[service]/[port]/[stream]`
Unsubscribe from stream `[stream]` on a foreign Urbit.
urb.js
======
<hr>
</hr>
<list></list>

View File

@ -1,273 +0,0 @@
Eyre: Reference
===============
## State
Stored
- `++bolo`
- `++cyst`
- `++stem`
Runtime
- `perk`
+ `perk-auth`
- `pest`
- `even`
## Cores
- `++handle`
+ `++parse`
- `++as...`
- `++ya`
- `++ix`
Eyre: Commentary
================
Let us follow the loading of a simple cli app, as it bounces from
browser to server to browser and back.
## Initial request[#init]
An http request for `http://sampel-sipnym.urbit.org/cli` will be [redirected](dns)
to the `%eyre` on ~sampel-sipnym, and come in as a `%this` kiss.
From arvo, requests enter `++call`, which after some type reification are passed
along to `++apex:ye`. In the case of a `%this` kiss, its components are
parsed(see `++zest:epur`, `++eat-headers`) and handed off to `++handle`, wrapped
in `++emule` to produce a `++fail` page in case of error. `++apex:handle` will
`++process` the request to a `pest` or a `++done` core, and in the former case
`++resolve` the pest into an outgoing card.
XX it also seems to affect the current ship, test that serving ship name is consistently correct
The pest is produced by `++process`, which will first further `++parse` the
request, and if this does not make the response immediately obvious,
`++process-parsed` the resulting `perk`.
`++parse` produces the `perk`, by attempting to interpret the `pork`(url path)
[`++as-magic-filename`](#mage), `++as-beam`, and `++as-aux-request`. In this
case, `/cli` is parsed by the second case as a `%beam` query to `/=cli=`: a path
which starts with a valid ship name is expected to be a full clay(well, ford)
path, and one starting with a term implies the current serving ship and a case
of `0`, the current revision.
XX spur: when the desks are merged, `/cli` shall point to `/=main=/pub/cli`
The parsed `perk` generates a `%f %boil` note, `mark`ed as its extension(here
defaulting to `%urb`) and `wire`d with `~` to return unaltered to the client. It
goes on to `++resolve` by being passed to `++ford-get-beam`, which translates
the perk it into a `%boil` `++ford-req`, adding an `++fcgi` path-segment
containing query string and `++fcgi-cred:for-client` auth information.
`%ford`s translation of `/=cli=/hymn/hook` to a self-refreshing `%urb` html page
[deserves its own commentary](../ford/commentary), but we resume in `%eyre`
when the `%made` sign arrives in `++take`, and soon after `++axon:ye`. There the
`wire`, or rather the `whir` it has been verified to be, determines that the
response should be served immediately. However, as the mark is not `%mime`,
another trip to `%ford` is required to encode it, on the same wire; afterwards,
the value of the `%mime` cage is verified to be of the correct type, and finally
delivered back up the requesting duct as a succesful `%thou` HTTP response.
XX `%cast %mime` used to be in ford-get-beam, is there a reason it was removed?
## Back into the breach, or: auxilary requests
Now, it was mentioned that this result is self-refreshing: the `%urb`
translation door injects a `;script@"/~/on/{deps}.js"` into every page, `deps`
is a ford-readable hash of the set of resources that page construction depended
on.
This triggers another `%this` request. Its handling is identical to that of
`/cli` up until `++parse`, where it is seen not `++as-beam` but
`++as-aux-request`(auxillary requests starting with `/~/` or `/~~/`).
`/on/[hash]` is a long-`%poll`, which `++process-parsed`, for a `.js` mark,
answers with a direct `%js`. Its contents are the static `++poll:js`, which
initiates the long-polling loop, run against an injected `urb.js` of
`{poll:[hash]}`.
A `%js` `pest` is `resolve`d as a `text/javascript` success `%this`.
When `poll.js` is recieved by the client, it opens an `XMLHttpRequest` for
`/~/on/{window.urb.poll}.json`, bringing us back to `%poll:process`.
In the case of a non-`%js` `/~/on/`, `%poll:process-parsed` turns into a
`++new-dependency`, which stores the listening duct, and `pass-note`s a `%wasp`
with the deps-hash back to `%ford` whence it came. While this occured, the page
has loaded.
Some indeterminate amount of time afterwards, with dropped `/~/on/{...}.json`s
being retried upon expiring and also being stored, a `%news` sign arrives in
`++axon`, and the hash in question is retrieved from the wire, and the listening
long-polls retrieved by the hash. Each receives a 205 "Reload parent view" HTTP
response, which `poll.js` dutifully executes, and a fixed typo of markdown is
rendered.
## Authentication.
Now, while this accurately reflects the presentation of e.g. a markdown file,
`/cli` is an application front-end, and one that permits only owner access. Its
second script is `@"/~~/~/at/main/lib/urb.js"`, semantically equivalent to
`/~/as/own/~/at/main/lib/urb.js`, and handled as follows.
In `++as-aux-request`, `%as %own` becomes `%auth %get our` perk, which
`++process` passes to `++process-parsed` passes to `++process-auth`. There, a
`yac` "ya" core is built `++for-client`: a `++cookie-prefix`, which is just the
serving ship name, is used to get a `++session-from-cookies`, here nil as the
client has no cookie set. In lieu of a cookie, a `++new-ya` is constructed, with
a random token `hole` and a `++new-cyst` which fills out `cyst` session state
from request data.
Returning to `++process-auth`, `%get` checks if the yac is authenticated with
the requested credentials(`anon` requests are always granted), which for the
fresh new `cyst` is not the case (more on success [later](#auth-ok)). Unless
authentiacting as a [foreign ship](#xeno), the only thing left is to
`++show-login-page`, which detects that the requested resource is not `%html`,
and produces a `%red` pest. For `%js`, `%red`irections `++resolve` to
`++auth-redir:js`, a line of javascript which prepends `/~~` to the url path.
The owner-authenticated main page request similarly ends in `++show-login-page`,
which for the empty session is an `[%htme ++login-page:xml]`, `resolve`d to
`++give-html` with a 401 "unathorized".
The login page shows a simple prompt, and requests `/~/at/auth.js` to handle the
submission. And so we are, once again, attempting to divine if what we're doing
makes sense `++as-aux-request`.
To understand `/~/at`, there will first be a brief diversion to `~/auth.json`.
`auth.json`, perk `[%auth %json]`, in `++process-auth` serves `++stat-json:ya`,
containing such information as the serving ship, which identities are associated
with this session, and `oryx`, a CSRF token. An oryx must be present on all
stateful requests, in this case executing a log in. It also saves the new/old
session using `abet`.
XX explain `ixor` here and not [later](#ixor)?
`/~/at` is an alternate interface, which injects `auth.json` data into the
requested file. `/~/at/auth.js`, then, is a request for the built-in `auth:js`
(parsed to and processed from an `[%auth %js ~]` perk), with session data added
as `window.urb`. And indeed, ``[`%js /~/at/auth]`` is parsed to
``[%auth at [`%js /auth]``, which in `++process-auth` is re-`process`ed to
`[%js ++auth:js]`, which is `++resolve`d after an `++add-json` of
the relevant data. The yac cookies are also passed to `resolve`, which
`++add-cookies` injects into the `httr`.
It is at this point that there is first occasion for user input, namely the password.
The `auth:js` script sends a `PUT` request, also to `/~/auth.json`. In `parse`,
the first nontrivial `++check-oryx` occurs, `++grab-body` the request oryx and
ensuring it is recorded for the session. The request parsed with `++need-body`
to a `[%auth %try {password}]` perk. `%get:process-auth` checks it against
`++load-secret`, upon success updates the session with `++logon:ya`, and
serves a fresh `auth.json` which reflects the changed `user`. Upon recieving
this, the page is refreshed to retry the original request.
## Post-authentication: app communication. [#auth-ok]
Upon refresh, `/~~/cli` brings us for the third time to `%get:process-auth`, but
this time the cookie is set, and the `yac` fetched contains the serving ship as
authenticated. The `++handle` sample is updated to reflect the requesting ship,
and the `process` continues for the rest of the pork, once again serving the
ford page.
The `/~/on/[deps].json` poll starts anew, and `/~~/~/at/main/lib/urb.js` we now
know to serve the window.urb necessary to make requests, and the `urb.js`
standard library which extends it with a number of wrappers to them and other
useful functions.
---
One of those functions is `urb.bind`, which is used to subscribe to application
data. Userspace javascript sets `urb.appl` to `/tic`, and binds `lines` to a
`;pre;` text display, using a callback.
This triggers a `PUT` to `/~/is/{ixor}/cli/lines.json`, where `ixor` is a hash
of `oryx` that identifies the connection. `++as-aux-request`, an `%is` is a
`%subs` subscription update update, which for `%put` forwards to
`++add-subs:ix`, the ix core fetched `++for-view` by hashing the request
`++oryx-to-ixor`.
[#ixor] A view has all the state associated with a client that must be
remembered between events. In this case, this is what app/path the request duct
is associated with; but mainly, `++add-subs:ix` will `pass-note` to `%gall` so
it `%show`s the data on the path, current and future.
This will immediately(assuming the ship is local) result in a `%nice` by the
`/cli` app, returning `{ok:true}` `++nice-json` to `urb.bind`'s second callback
as `{ok:true}`. The initial `%rush` results also arrive, and in `++axon` are
converted to json using `++back`(ford `%cast` wrapper), and when `%made` get
passed to `++get-rush:ix`. There the source application/path are decoded by
duct, and then the full event goes to `++get-even`; `++add-even` inserts it to
the queue, and as there is no long poll it simply stays there.
Upon receipt, the client realizes the long-poll isn't actually running, so that
is started using `urb.poll`. At `/~/of/{ixor}`, perk
`[%view ixor ~ {sequence-number}]`, it is `process`ed by `++poll:ix` (the cyst
is retrieved by `++ire-ix` form global state, using the perk `ixor`): the
sequence number is in the past, so the previously recieved `%rush` is
`++give-even`. After deleting the previous message in the queue and invoking
`++pass-took` to signal `%gall` of this occurrence, the data is annotated with
the source app+path `++subs-to-json`, and returned to the polling duct.
On the client, the user callback receives the `/cli` history, and displays it on
the page. The `/~/of` long poll is continued, this time reaching `++poll:ix`
with the "pending" sequence number, and being stored in the `cyst` for its troubles.
---
Its next update proceeds idenitcally, but first it must be triggered, which
happens when the user enters "(add 2 2)\n", firing an `urb.send` from the event
handler. This sends a `POST` request to `/~/to/cli/json.json`, perk `%mess`,
`++process`ed to a `%g %mess`. Were the mark not `%json`, a `%ford` conversion
would occur first, and `%made:axon` would send the gall message proper. In
either case, eventually a `%mean` or `%nice` arrives, is encoded as json, and
sent to the client callback.
## A path not taken: magic filenames [#mage]
The `/robots.txt` and `/favicon.(ico|png)` files are static, and served
immediately when caught by a `++parse`.
XX index.html?
## A path not taken: foreign auth [#xeno]
While this example details a login `/~/as/own`, it is possible to be
authenticated as any ship on the network. A request for such seen in
`%get:process-auth` is passed to `++foreign-auth:ya`, which sends an
`%ames /lon` message to the ship in question. The foreign ship stores the
inquiry, calculates(the local) `++our-host` and responds with a `/hat`,
containing the redirection host, which is stored by `++foreign-hat`; it is later
used to send the client to a `/~/am` url on the foreign client, which acts as a
normal login page but later sends the client back. XX expand, basically the
status quo is you're logged in and `/~/as/foo` is ignored, just setting your
`urb.user` XX
## A path not taken: deauthentication
`/~/away`, perk `[%away ~]`, produces a static `++logout-page:xml`, which also
uses `/~/at/auth.js`, to send a `DELETE /~/auth.json`, perk `[%auth %del]`. This
executes `++logoff:ya` for the cookie session, resolving to `++abut` to wipe it
from memory.
## A path not taken: unsubscription
`DELETE /~/is/app/path/within` works much like `PUT /~/is/app/path/within`,
`++del-subs:ix` acting as reverse of `++add-subs` by deleting the duct binding
and sending `%g %nuke`.
XX unmentioned arms: abet, add-poll, adit, ames-gram, anon, ares-to-json, bolo, cyst, doze, even, ford-kill, get-mean, gift, give-json, give-thou, gram, hapt, hasp, host-to-ship, ix, ixor, js, kiss, load, mean-json, move, note, pass-note, perk, perk-auth, pest, poke-test, print-subs, render-tang, resp, root-beak, scry, ses-authed, ses-ya, sign, silk, sine, stay, stem, teba, titl, to-oryx, urb, wait-era, wake, whir, wush, xml, ya, ye
## Appendix A: DNS [#dns]
The `*.urbit.org` domain can be used to access destroyers and cruisers. In the
common case oh hosted ships, this is done by dynamic DNS directly to the hosting
instance. We do not speak of the uncommon case. When ports are blocked and
infrastructure crumbles around you, only imported martian networking can be
trusted: the `%get` and `%got` [gram]()s are used to proxy [`%this` requests]() and
[`%thou` responses]() respectively.

View File

@ -1,128 +0,0 @@
<div class="short">
`%ford`
=======
Our typed and marked computation engine.
A variety of different services are provided by `%ford`, but they mostly
involve compiling hook files, slapping/slammming code with marked data,
and converting data between marks, including validating data to a mark.
Throughout every computation, `%ford` keeps track of which resources are
dependencies so that the client may be aware when one or more
dependencies are updated.
`%ford` neither accepts unix events nor produces effects. It exists
entirely for the benefit of applications and other vanes, in particular
`%gall`. `%eyre` exposes the functional publishing aspects of `%ford`
while `%gall` uses `%ford` to control the execution of applications.
`%clay` is intended to use `%ford` to managed marked data, but this is
not yet reality.
</div>
------------------------------------------------------------------------
<list></list>
------------------------------------------------------------------------
Cards
=====
`%ford` accepts just one card, `%exec`. This is misleading, however,
since there are fourteen different `silk`s that may be used with it. In
every case, the expected response to a `%exec` card is a `%made` gift
with either an error or the produced result along with its set of
dependencies.
Silks may autocons, so that the product of a cell of silks is a cell of
the product of the two silks.
`%bake`
================
Tries to functionally produce the file at a given beam with the given
mark and heel. It fails if there is no way to translate at this level.
`%boil`
================
Functionally produces the file at a given beam with the given mark and
heel. If there is no way to translate at this beam, we pop levels off
the stack and attempt to bake there until we find a level we can bake.
This should almost always be called instead of `%bake`.
`%call`
================
Slams the result of one silk against the result of another.
`%cast`
================
Translates the given silk to the given mark, if possible. This is one of
the critical and fundamental operations of ford.
`%diff`
================
Diffs the two given silks (which must be of the same mark), producing a
cage of the mark specified in `++mark` in `++grad` for the mark of the
two silks.
`%done`
================
Produces exactly its input. This is rarely used on its own, but many
silks are recursively defined in terms of other silks, so we often need
a silk that simply produces its input. A monadic return, if you will.
`%dude`
================
Computes the given silk with the given tank as part of the stack trace
if there is an error.
`%dune`
================
Produces an error if the cage is empty. Otherwise, it produces the value
in the unit.
`%mute`
================
Takes a silk and a list of changes to make to the silk. At each wing in
the list we put the value of the associated silk.
`%pact`
================
Applies the second silk as a patch to the first silk. The second silk
must be of the mark specified in `++mark` in `++grad` for the mark of
the first silk.
`%plan`
================
Performs a structured assembly directly. This is not generally directly
useful because several other silks perform supersets of this
functionality. We don't usually have naked hoods outside ford.
`%reef`
================
Produces a core containing the entirety of zuse and hoon, suitable for
running arbitrary code against. The mark is `%noun`.
`%ride`
================
Slaps a twig against a subject silk. The mark of the result is `%noun`.
`%vale`
================
Validates untyped data from a ship against a given mark. This is an
extremely useful function.

File diff suppressed because it is too large Load Diff

View File

@ -1,161 +0,0 @@
<div class="short">
`%gall`
=======
Our application server manager.
It allows applications and vanes to send messages to applications and
subscribe to data streams. This requires `%gall` to be a sort of a
hypervisor. 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, `%gall` will behind-the-scenes route
it through ames to the other ship to run. This provides an abstraction
where all apps on all ships are communicated with over the same
interface.
`%gall` neither accepts events from unix nor produces effects. It exists
entirely for the benefit of other vanes and, in particular,
applications. Eyre exposes `%gall`'s interface over http, and ames does
the same over the ames network. `%gall` uses ford to compile and run the
applications.
</div>
------------------------------------------------------------------------
Cards
=====
`%gall` accepts the following cards. The first three are the most
commonly used, while the others are primarily used internally.
`%mess`
================
Sends a message to an app. This will result in a call to the app's
`++poke` arm. The response is exactly one of a `%nice` if the action
succeeded or a `%mean` if not.
------------------------------------------------------------------------
`%show`
================
Subscribes to a stream from an app. This will result in a call to the
app's either `++peek` or `++peer` arm. The first response will always be
either a `%nice` or a `%mean`, indicating whether or not the
subscription was successful. After the first response, there will be
zero or more responses of either `%rush` or `%rust`, which communicate
either a differntial or full update to the data stream. There may be a
`%mean`, which indicates that the subscription has been canceled and no
more responses will be received along this stream.
------------------------------------------------------------------------
`%nuke`
================
Unsubscribes the current duct from its stream. This receives a response
of either a `%nice` or a `%mean`. Note that a response of `%nice` does
not imply that the current duct was in fact subscribed to any stream.
------------------------------------------------------------------------
`%init`
================
Initializes a ship's apps. This should be called exactly once for each
ship on the pier. This produces no moves in response.
------------------------------------------------------------------------
`%sire`
================
Instantiates a child app. The app will be at path `[p parent-path]`, and
it will be an instance of the `q` app. The only response will be `%gone`
when the child dies.
------------------------------------------------------------------------
`%rote`
================
Signifies a remote request from ames. `r` should be of type `rook`. This
how an app on a foreign ship may send a `%mess`, `%show`, or `%nuke`
card. Note that `%gall` automatically converts `%mess`, `%show`, and
`%nuke` into ames messages behind the scenes, so the only entity that
should use `%rote` and `%roth` is ames. Formally, the response is either
a `%nice` or a `%mean`, which ames uses to give a positive or negative
ack. A logical response comes by passing a `%roth` card.
------------------------------------------------------------------------
`%roth`
================
Gives the response received from a remote request. `r` should be of type
`roon`. This is how an app responds to a foreign request with a `%rush`,
`%rust`, `%nice`, or `%mean`. The response is either a `%nice` or a
`%mean`. Even though we, as the proverb goes, "never ack an ack", we do
need to acknowledge these responses since they're really independent
one-way messages.
------------------------------------------------------------------------
`%wipe`
================
Wipes the given app from memory. This is generally considered a hack,
but it is sometimes useful during development to wipe the state of an
app. We don't guarantee that this actually completely wipes the app.
Generally, you want to use a `%cide` card if you actually want to kill
an app. This gives no response.
------------------------------------------------------------------------
`%cide`
================
Kills an app and all its children. Even though it's not technically a
part of `%gall`'s interface since it's not in `++kiss` and can't be
called from the outside, it's worth mentioning `%cide`, which may be
called from within `%gall` apps. It should call `++part` to allow the
app any last words. This gives no response.
------------------------------------------------------------------------
Service Gates
=============
[`++poke`]()
============
Handles incoming messages. Most commonly with an associated `%logo`. For
example `++poke-json` handles an incoming JSON request from `%eyre`.
[`++peer`]()
============
Handles incoming subscriptions.
[`++pull`]()
============
Handles dropping subscribers.
[`++pour`]()
============
Handles responses to `%pass` moves.
[`++park`]()
============
Save state on update.
[`++prep`]()
============
Load state on update.

View File

@ -1,5 +0,0 @@
Gall: Reference
===============
Gall: Commentary
================

View File

@ -1,21 +0,0 @@
<div class="short">
`%time`
=======
Our simple timer.
It allows vanes and applications to set and timer events, which are
managed in a simple priority queue. `%time` produces effects to start
the unix timer, and when the requested `%time` passes, unix sends wake
events to `%time`, which time routes back to original sender. We don't
guarantee that a timer event will happen at exactly the `%time` it was
set for, or even that it'll be particularly close. A timer event is a
request to not be woken until after the given time.
`%eyre` uses `%time` for timing out sessions, and `%clay` uses `%time`
for keeping track of time-specified file requests. `%ames` should
probably use `%time` to keep track of things like network timeouts and
retry timing, but it currently uses its own alarm system.
</div>

View File

@ -1,344 +0,0 @@
<div class="short">
CLI Apps
========
Our simple command-line applications.
You can find them in `/main/app`.
</div>
------------------------------------------------------------------------
### `:?begin`
`~zod:dojo> :?begin [~ship-name [~valid-ticket-for-ship]]`
Start a ship. `:?begin` collects all of the necessary information to
start an Urbit ship. Takes an option `[~ship-name]` or
`[~ship-name [~valid-ticket-for-ship]]` pair.
------------------------------------------------------------------------
### `+cat`
`~zod:dojo> +cat /path/to/file [...]`
"cat" a file. `+cat` either prints a file, or concatenates and then
prints multiple files to the terminal.
~zod:dojo> +cat %/spec/nock/5/txt
> +cat %/spec/nock/5/txt
/~zod/home/~2015.6.29..22.33.04..fc76/spec/nock/5/txt
A noun is an atom or a cell.
------------------------------------------------------------------------
### `|cp`
`~zod:dojo> |cp /path/to/source /path/to/destination`
Copy a file to a given location.
~zod:dojo> |cp %/spec/nock/5/txt %/try/6/txt
> |cp %/spec/nock/5/txt %/try/6/txt
+ /~zod/home/2/try/6/txt
>=
------------------------------------------------------------------------
### `grep`
<mark>GONE</mark>
`~zod:dojo> :grep 'literal'`
"grep" a file or standard input. Currently only supports a literal cord,
but will eventuall support regular expressions.
------------------------------------------------------------------------
### `|hi`
`~zod:dojo> |hi ~ship ["message"]`
Send a ship a message which is empty by default, becoming their neighbor
in the process. Often used to ping ships to check connectivity.
~zod:dojo> |hi ~doznec
> |hi ~doznec
ames: czar zod.urbit.org: ip .192.241.195.84
>=
hi ~doznec succesful
; ~doznec is your neighbor
; ~doznec is your neighbor
and on ~doznec
~doznec:dojo>
< ~zod:
; ~zod is your neighbor
send a message
~zod:dojo> |hi ~doznec "say something"
>=
hi ~doznec succesful
and on ~doznec
< ~zod: say something
------------------------------------------------------------------------
### `:into`
<mark>GONE</mark>
`~zod:dojo> :into /path/to/file 'contents'`
Write text to a file. If the specified file does not exist, create a
file by that name. If it does exist, replace its contents.
------------------------------------------------------------------------
### `|label`
<mark>GONE? returns file not found</mark>
`~zod:dojo> |label %path %label`
"label". Add a label to a change number.
~zod:dojo> |label %try %zebra
= new /~zod/try/3
~zod:dojo> :ls /=try/zebra
readme
Note that adding a label is part of the delta stream and creates a new
change number, `3`.
------------------------------------------------------------------------
### `+ls`
`~zod:dojo> :+ls path/to/directory`
"ls". List files at a path. Unlike "ls" in Unix, the current path `%`
must be explicitly given (you cannot call `+ls` with no arguments to
display the files at the current path).
~zod:dojo> +ls %try
> +ls %/try/
readme/md
------------------------------------------------------------------------
### `|mount`
`~zod:dojo> |mount /path/to/directory/version %mount-point`
Your files are not synced to unix by default.
To sync a subtree to unix, run `|mount /path/to/directory %mount-point`.
This will sync it into `<pier>/<mount-point>.`
If you want to sync your whole home desk into f0/home, for example,
run `|mount % %home` You can also [`|unmount`]().
~zod:dojo> |mount /~zod/base/0 %base
> |mount /~zod/base %base
>=
------------------------------------------------------------------------
### `|mv`
`~zod:dojo> |mv /path/to/source /path/to/destination`
Move a file to a given location, creating a new revision of the source
that omits the moved file.
~zod:dojo> |mv %/try/6/txt %/try/7/txt
> |mv %/try/6/txt %/try/7/txt
+ /~zod/home/3/try/7/txt
>=
------------------------------------------------------------------------
### `|reload`
`~zod:dojo> |reload %vane-name [...]`
Reload the standard library (zuse) and/or arvo vanes. If zuse is
reloaded, vanes depending on the changes must be reloaded as well. For
example `|reload %zuse %ford` is necessary to make use of changes in
application code or the REPL.
Possible values for %vane-name see [Overview](overview "overview"):
~zod:dojo> |reload %zuse
[%tang /~zod/home/~2015.6.29..23.50.29..134d/arvo/zuse ~hillyx-salhet]
> |reload %zuse
>=
------------------------------------------------------------------------
### `|reset`
`~zod:dojo> |reset`
Reloads all vanes. See [`|reload`]() for reloading only or a specific vane.
~zod:dojo> |reset
[%vega-start /~zod/home/~2015.6.29..23.51.42..f335/arvo/hoon]
%vega-parsed
[%vega-compiled %163 163]
%hoon-load
[%tang /~zod/home/~2015.6.29..23.51.42..f335/arvo/zuse ~hillyx-salhet]
[%vane %a /~zod/home/~2015.6.29..23.51.42..f335/arvo/ames ~tilwyl-talren]
%ames-reload
[%vane %c /~zod/home/~2015.6.29..23.51.42..f335/arvo/clay ~molmur-panlus]
[%vane %d /~zod/home/~2015.6.29..23.51.42..f335/arvo/dill ~sicbet-miphes]
[%vane %e /~zod/home/~2015.6.29..23.51.42..f335/arvo/eyre ~solrux-sibnep]
[gub=30 hov=19 ged=18 ded=1 pox=1 ask=1 kes=1 ney=35 dop=1 liz=1 wup=1 sop=1 wix=1]
[%vane %f /~zod/home/~2015.6.29..23.51.42..f335/arvo/ford ~librem-sopseg]
[%vane %g /~zod/home/~2015.6.29..23.51.42..f335/arvo/gall ~sidsub-fasrev]
[%vane %t /~zod/home/~2015.6.29..23.51.42..f335/arvo/time ~ritwyn-lanrev]
> |reset
<<<reset>>>
>=
------------------------------------------------------------------------
### `|rm`
`~zod:dojo> |rm /path/to/source`
Remove a file.
~zod:dojo> |rm %/try/7/txt
>=
------------------------------------------------------------------------
### `+solid`
`~zod:dojo> +solid`
compiles a kernel into a new full urbit.pill
------------------------------------------------------------------------
### `|sync`
`~zod:dojo> |sync %source-desk ~hidduc-posmeg %target-desk`
Sets up a subscription to the source desk on the target ship name to the
target desk on your ship.
------------------------------------------------------------------------
### `+ticket`
`~zod:dojo> +ticket ~ship-name`
Creates a will for a ship. `+ticket` outputs the ticket for a Urbit
ship. Takes an option `[~ship-name]`. On destroyes this command creates
a yacht and takes the option \`[\~yacht-name-destroyer-name]
------------------------------------------------------------------------
### `:thumb`
<mark>GONE</mark>
`~zod:dojo> :thumb ~ship-name`
Show the ships information. Only works if you issued a [`:hi`]
[\`\~ship-name] beforehand.
This command is not avaible since the switch from batz to `%gall`!
Use this for the time beeing: - will:
`~zod/try=> ((hard (unit gcos)) .^(%a /=gcos=/~ship-name))` - raw will:
`~zod/try=> ((hard will) .^(%a /=will=/~ship-name))`
------------------------------------------------------------------------
### `|unmount`
`~zod:dojo> |unmount /path/to/directory`
Your files are not synced to unix by default.
To sync a subtree to unix, run `|mount`.
You can unmount with either `|unmount /path/to/directory`
or `|unmount %mount-point`.
~zod:dojo> |unmount %base
> |unmount %base
>=
------------------------------------------------------------------------
### `|unsync`
`~zod:dojo> |unsync %source-desk ~hidduc-posmeg %target-desk`
Cancels the subscription to the source desk on the target ship name to
the target desk on your ship.
------------------------------------------------------------------------
### `|verb`
`~zod:dojo> |verb`
Turn verbose arvo mode on/off.
You'll see events, internal cards, and effects.
[%unix p=%wake //temp]
[ %give
%t
%wake
~[
/c/tyme
/g/a/~zod/._~~.58_~~.shell_~~.terminal__/w/drug/~zod/main
/g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/began/u
/g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/._~~.2_~~.shell_~~.terminal__/u/to-gan
/g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/._~~.shell_~~.terminal__/u/child/2/main
/g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/terminal/u/txt
/d/term-mess
//term/1
]
]
[ %give
%c
%writ
~[
/g/a/~zod/._~~.58_~~.shell_~~.terminal__/w/drug/~zod
/g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/began/u
/g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/._~~.2_~~.shell_~~.terminal__/u/to-gan
/g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/._~~.shell_~~.terminal__/u/child/2/main
/g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/terminal/u/txt
/d/term-mess
//term/1
]
]
...
------------------------------------------------------------------------
### `|ye`
`~zod:dojo> |ye ["message"]`
Send a message to all ships. Often used to announce a continuity breach.
------------------------------------------------------------------------

View File

@ -1,28 +0,0 @@
---
sort: 1
---
<div class="short">
hoon
====
hoon is our programming language.
hoon is a strict, typed, functional language that compiles itself to
nock. The hoon compiler is 4000 lines of hoon. Adding standard
libraries, the self-compiling kernel is 8000 lines. The hoon compiler is
located towards the bottom of `/=main=/arvo/hoon.hoon`. The standard
library is split between `/=main=/arvo/hoon.hoon` and
`/=main=/arvo/zuse.hoon`.
hoon has no particular familial relationship to other languages you may
know. It uses its own type inference algorithm and is as different from
Haskell as from Lisp. hoon syntax is also completely unfamiliar. hoon
uses ascii digraphs, which we call 'runes', instead of reserved words.
</div>
------------------------------------------------------------------------
<list></list>

View File

@ -1,16 +0,0 @@
---
sort: 3
---
<div class="short">
Interpreter
==========
The urbit interpreter and C code.
</div>
------------------------------------------------------------------------
<list></list>

View File

@ -1,345 +0,0 @@
<div class="short">
Glossary
========
### arm
A key-value pair of a name ([++term]()) to an expression ([++foot()]).
Used primarily in [core]() construction. Arms can contain either
functions or data. You can think of them like named properties inside an
object.
------------------------------------------------------------------------
### atom
An atom is a natural number. More here..?
------------------------------------------------------------------------
### axil
An `[%axil p=base]` is a simple [`++tile`]() for a few basic icons: an
atom of any odor, a noun (`*`) , a cell of nouns (`^`), a loobean (`?`),
and null (`~`).
------------------------------------------------------------------------
### battery
[Cores], at the most basic level, are of the structure [battery
payload]. The battery consists of the code contained within a core.
------------------------------------------------------------------------
### `%bark`
A `[%bark p=term q=tile]` is a [`++tile`]() with a name wrapped around
it. Its [icon]() is a [`++face`](). The rune associated with a
[`%bark`]() is [`$=`]().
------------------------------------------------------------------------
### bunt
The bunt of a [`++tile`]() produces a [`++twig`]() that creates a blank
default example its [icon](). Bunting is like explicitly asking for the
default value of a type. Unlike in other languages, this always exists
in Hoon. See also [`$*`]().
------------------------------------------------------------------------
### `%bush`
a [`[%bush p=tile q=tile]`]() is a [`++tile`]() in which there are two
kinds of [nouns](): cells whose head is a cell (`++tile` p) and cells
whose head is an atom (`++tile` q). Its default value is the value of
`q`, and its icon is a [`++fork`]()
------------------------------------------------------------------------
### cell
A cell is an ordered pair of nouns.
------------------------------------------------------------------------
### clam
The clam of a [`++tile`]() is a [gate]() that accepts an arbitrary
[noun]() and always produces a member of the [icon]() of the `++tile`.
If the gate is passed a [sample]() that is a member of the icon, it will
produce that sample. If the gate is passed a noun outside of the domain
of the icon, it will produced the [bunt]() of the icon. You can think of
a clam as a validator function for an icon. To clam a `++tile` is to
produce its clam. See also: [`$,`](). SEE ALSO!!
------------------------------------------------------------------------
### context
In [gate]() construction, an arm is pulled from a [core]() and pushed
onto the subject creating a structure of [formula [sample context]],
where the context is the previous subject, commonly a core. In Hoon, the
whole kernel is typically included in your subject, so you can think of
context in hoon in a similar way to context in the traditional
functional programming sense.
------------------------------------------------------------------------
### cons
Cell constructor, similar to [cons in other functional
languages](http://en.wikipedia.org/wiki/Cons). Constructs a cell
containing two [`++twigs`]() into a twig that produces a cell of the
results of the two original sub-twigs.
------------------------------------------------------------------------
### core
At the Nock level, a core is any [subject]() that contains both code and
data, named battery and payload respectively. At the Hoon level, a core
is very similar to an object with named properties that can be either
functions or data. For more information, see the [`|` rune section]() of
the Hoon library.
------------------------------------------------------------------------
### `%cube`
------------------------------------------------------------------------
### door
A door is a [core]() with a sample. Door are used.../you can think of
doors...
------------------------------------------------------------------------
### dry
In a dry computation, typechecking occurs at compile-time to ensure that
all inputs match its [sample]() [++tile](). The formal term for dry is
`%ash`.
------------------------------------------------------------------------
### engine
Engines are [core]()s that contain several [arm]()s that each perform
one of a related set of operations on the core's sample. For example,
there is a container engine for all of the set operations. You can think
of engines as objects with methods that modify its data.
------------------------------------------------------------------------
### `%face`
------------------------------------------------------------------------
### fern
A `[%fern p=[i=tile t=(list tile)]]` is a [`++tile`]() for a non-empty
list of cases. Its icon is naturally a [`%fork`](). The programmer is
responsible for ensuring that the cases are actually orthogonal (unlike
with the structured `%fork`s, [`%bush`](), [`%kelp`]() and [`%reed`]).
------------------------------------------------------------------------
### fishing
To fish is to test if a [noun]() matches a specific `++tile`, using the
natural rune [`?=`](). Some languages call fishing "pattern matching".
------------------------------------------------------------------------
### frond
A frond is a case of a [kelp](), which is a [discriminated (or tagged)
union](http://en.wikipedia.org/wiki/Tagged_union).
------------------------------------------------------------------------
### gate
A [gate]() is a [core]() with one arm [`$`]() with a [payload]() that is
a cell of the form [[sample]() [context]()]. Gates are the closest thing
Hoon has to functions in the traditional sense.
------------------------------------------------------------------------
### `%gold`
------------------------------------------------------------------------
### herb
An `[%herb p=twig]`....
------------------------------------------------------------------------
### icon
The icon of a [`++tile`]() is the type associated with that `++tile`. A
`++tile` is a convenient way of specifying a type, which is its icon.
`++tile`s are used in a similar way to [type signatures]() for their
icons.
------------------------------------------------------------------------
### `%iron`
`%iron` is a variance type for [cores]() where their [sample]()s cannot
be read. You can think of can be thought of as similar to a private
function.
Not quite sure about this one.
------------------------------------------------------------------------
### `%kelp`
a [`%kelp p=[i=line t=(list line)]`] is a [discriminated, or tagged,
union](http://en.wikipedia.org/wiki/Tagged_union). In Hoon, the head,
which is called the stem, must be a [`%leaf`](). The tail, which can be
anything, is the bulb. Cases of a kelp are known as [fronds]().
------------------------------------------------------------------------
### kick
To pull the empty name `$` on a core is to kick it. You can think of
kicking like calling a function with its default arguments.
------------------------------------------------------------------------
### noun
A noun is an [atom]() or a [cell](). Everything in Hoon is a noun.
------------------------------------------------------------------------
### `%$` buc
`%$`, or `$` for short, is the empty name in Hoon.
------------------------------------------------------------------------
### leg
If the result of [pulling]() something from `x` is a subtree, then it is
a leg.
More here? Existing doc isn't quite clear here..
------------------------------------------------------------------------
### `%lead`
------------------------------------------------------------------------
### `%leaf`
A `%leaf` is a [`++tile`]() consisting of an atomic constant of value
`q` and odor `p`. Its icon is a [`%cube`](). The syntax for a leaf is
the same as the syntax for a [`++twig`](), except that % is never
required to generate a cube. For instance, as a twig, 7 has a type of
[%atom %ud]; %7 has a type of [%cube 7 [%atom %ud]]. But the icon of the
leaf 7 is, again, [%cube 7 [%atom %ud]].
Copied the bottom half from existing doc. Not sure about this one...
------------------------------------------------------------------------
### loobean
------------------------------------------------------------------------
### payload
[Cores](), at the most basic level, are of the structure [battery
payload]. The payload consists of the data contained within a core. You
can think of the payload as similar to the data of an object.
------------------------------------------------------------------------
### pull
To access a [wing]() or [limb]() in a [core]() is to pull it. For
instance, when we write `a.b.x` (a within b from x), we are pulling the
wing `a.b` from `x`.
------------------------------------------------------------------------
### `%reed`
A `[%reed p=tile q=tile]` is a [`++tile`]() whose [icon]() contains two
kinds of nouns: atoms of `++tile` `p` and cells of `++tile` `q`. The
rune associated with reeds is [`$|`]().
------------------------------------------------------------------------
### sample
In [gate]() construction, an arm is pulled from a [core]() and pushed
onto the subject creating a structure of [formula [sample context]],
where the sample represents the gate's inputs. All gates are constructed
with a default sample value. Thus, when we call a gate with arguments,
we are actually replacing its sample.
------------------------------------------------------------------------
### slam
To pull the empty name `$` on a [gate]() `g` with its [sample]()
replaced by a given input `a` is to slam `g` with `a`. You can think of
slamming like passing input parameters to a function that's being
called.
------------------------------------------------------------------------
### subject
All Hoon expressions a parsed into abstract syntax trees, which in Hoon
are called [++twig]()s. Twigs are [nouns]() that are converted into Nock
expressions, which are all of the basic form [subject formula], where
the subject is the data and the formula is the program. Thus, in both
Hoon and Nock, subject can refer to any piece of data that is being
operated on by a formula.
------------------------------------------------------------------------
### `++tile`
A `++tile` is a convenient way of specifying a type, which is its icon.
`++tile`s are used in a similar way to [type signatures]() for their
icons.
SOMETHING ABOUT THE DIFFERENCE BETWEEN TWIG AND TILE AUTOCONS.
------------------------------------------------------------------------
### weed
A `[%weed p=twig]`
------------------------------------------------------------------------
### wet
In wet computations, the product type is checked to be the same as the
input type, rather than the [sample]() [tile](). The formal term for wet
is `%elm`.
------------------------------------------------------------------------
### wing
A wing is a list of limbs. For example, when we [pull] `a.b` from `x`,
`a.b` is a wing. `a` and `b` individually are both [limbs]().
------------------------------------------------------------------------
</div>

View File

@ -1,183 +0,0 @@
<div class="short">
vere
====
vere is the Urbit virtual machine.
bin/vere -c ship
------------------------------------------------------------------------
Options
-------
### `-b`
Batch create
------------------------------------------------------------------------
### `-c`
Create
Creates a new pier. Takes a folder name, such as `pier`.
bin/vere -c pier
------------------------------------------------------------------------
### `-d`
Daemon
------------------------------------------------------------------------
### `-D`
Dry compute
dry compute the north and/or south events
------------------------------------------------------------------------
### `-f`
Fuzz testing
------------------------------------------------------------------------
### `-k`
Kernel version
------------------------------------------------------------------------
### `-l`
Raft port
------------------------------------------------------------------------
### `-L`
Localhost.
Routes all networking over `0.0.0.0` and checks the keys.
bin/vere -L -I ~del -c fz
------------------------------------------------------------------------
### `-M`
Memory madness
------------------------------------------------------------------------
### `-n`
Unix hostname
------------------------------------------------------------------------
### `-p`
Specify the [`%ames`](/doc/arvo/ames) udp listening port.
bin/vere -p 42665
It can sometimes help if you get a port pointed at you and run vere with
`-p` to specify the [`%ames`](/doc/arvo/ames) udp listening port. VMs
and [docker](http://www.docker.com/) containers and the like tend to put
up some pretty effective barriers to
[NAT](http://en.wikipedia.org/wiki/Network_address_translation) [hole
punching](http://en.wikipedia.org/wiki/TCP_hole_punching).
------------------------------------------------------------------------
### `-P`
Profile
------------------------------------------------------------------------
### `-q`
Quite
Inverse of [`-v`](#-v)
See also: [`:verb`](/doc/arvo/util#verb))
------------------------------------------------------------------------
### `-r`
Raft flotilla
Also needs the [`-l`](#-l) option set.
------------------------------------------------------------------------
### `-F`
Fake
Routes all networking over `0.0.0.0` and doesn't check any keys. This
allows you to start any carrier.
bin/vere -F -I ~zod -c zod
You get an isolated network with just yourself but you can [`:ticket`]()
other ships or start other ships or start other carriers.
------------------------------------------------------------------------
### `-I`
Imperial
Takes a carrier name, such as `~zod`.
bin/vere -F -I ~zod -c zod
------------------------------------------------------------------------
### `-v`
Verbose
Inverse of [`-q`](#-q)
See also: [`:verb`](reference/arvo/util.md#verb).
bin/vere -v mypier
------------------------------------------------------------------------
### `-X`
Skip last event
bin/vere -Xwtf mypier
------------------------------------------------------------------------
Tips
====
Inability to mmap 2Gb with `MAP_FIXED`
--------------------------------------
It's probably because of
[ASLR](http://en.wikipedia.org/wiki/Address_space_layout_randomization)
(some shared library got its data mapped in the middle of your address
space). If so, applying
bash setarch `uname -m` -R ./bin/vere
should help.
</div>

View File

@ -1,41 +0,0 @@
---
sort: 0
---
<div class="short">
nock
====
nock is our machine code.
nock is a homoiconic combinator algebra, not much fancier than SKI
combinators. The spec fits on a T-shirt and gzips to 340 bytes.
Think of nock as a kind of functional assembly language. It's not like
assembly language in that it's directly executed by the hardware. It is
like assembly language in that:
- Everything in Urbit executes as nock.
- You wouldn't want to program directly in nock.
- Learning to program directly in nock is a great way to start
understanding urbit from the ground up.
Just as Unix runs C programs by compiling them to assembler, Urbit runs
Hoon programs by compiling them to nock. You could try to learn Hoon
without learning nock. But just as C is a thin wrapper over the physical
CPU, Hoon is a thin wrapper over the nock virtual machine. It's a tall
stack made of thin layers, which is much easier to learn a layer at a
time.
And unlike most fundamental theories of computing, there's really
nothing smart or interesting about nock. Of course, in a strictly formal
sense, all of computing is math. But that doesn't mean it needs to feel
like math. nock is a simple mechanical device and it's meant to feel
that way.
</div>
------------------------------------------------------------------------
<list></list>

View File

@ -1,10 +0,0 @@
---
sort: 4
---
Tools
====
User-level tools and utilities.
<list dataPreview="true"></list>

View File

@ -1,209 +0,0 @@
`%clay`
========
`%clay` filesystem utilities.
## Paths
### Structure
Urbit paths have a very specific structure. First, since the clay
filesystem has a global namespace, the first element in any path
is the particular urbit whose filesystem you are trying to
access.
The second element specifies which desk you wish to access on
that urbit. Desks are independent branches (in the
revision-control sense) of their filesystem.
The third element specifies the revision number for that
desk. The remainder of the path is the path to the file.
Thus, a path in clay is:
`/urbit/desk/revision/path`.
For example, to get revision 5 of `/try/readme/md` off the `home`
desk on `~sampel-sipnym`, use:
`/~sampel-sipnym/home/5/try/readme/md`.
### Shortcuts
`%` refers to the current working
directory. `%%` refers to our parent, `%%%` refers to our
grandparent, and so forth.
For example:
XX TBD
From the other direction, inserting a `=` into a path copies the
corresponding element from the current path into the path that
you're trying to access.
For example, if the current path is referencing our ship at the
current time, to reference `/try/readme`, use:
`/===try/readme`.
### Accessing commits
There are three ways to refer to particular commits in the
revision history. First, one can use the revision number.
Second, one can use any absolute time between the one numbered
commit and the next (inclusive of the first, exclusive of the
second). Thirdly, every desk has a map of labels to revision
numbers. These labels may be used to refer to specific commits.
## `ls`
`+ls /path` gives a directory listing at a path
## `cat`
`+cat /path`
prints out the file at the given path.
## `mount`
It's often useful to "mount" the clay filesystem to unix, so that
you can interact with it with the traditional unix tools. The
syntax to do this is as follows:
|mount /path [%mount-point]
This mirrors the desk out to unix in at the path
`<pier-directory> <mount-point>`. If you don't supply a
`%mount-point`, we use the last element in the path. Thus, if
you mount `%/pub/doc`, it'll by default put it in `doc`.
*The mount point is monitored Dropbox-style, so every change you
make to the file in unix is automatically commited to clay.*
You can unmount by specifying either the path or the mount point.
|unmount /path
|unmount %mount-point
## `merge`
Often, it's useful to be able to merge a desk into another desk.
The other desk does not, of course, need to be on the same urbit:
for example, the standard way to distribute an app is to put it
on a desk and let other people merge it into their own urbit.
The syntax is as follows:
|merge %to-desk ~from-urbit %from-desk [%strategy]
There are seven different merge strategies. Throughout our
discussion, we'll say that the merge is from Alice's desk to
Bob's.
### Native strategies
A `%init` merge should be used iff it's the first commit to a
desk. The head of Alice's desk is used as the number 1 commit to
Bob's desk. Obviously, the ancestry remains intact when
traversing the parentage of the commit, even though previous
commits are not numbered for Bob's desk.
A `%this` merge means to keep what's in Bob's desk, but join the
ancestry. Thus, the new commit has the head of each desk as
parents, but the data is exactly what's in Bob's desk. For those
following along in git, this is the 'ours' merge strategy, not
the '--ours' option to the 'recursive' merge strategy. In other
words, even if Alice makes a change that does not conflict with
Bob, we throw it away.
A `%that` merge means to take what's in Alice's desk, but join
the ancestry. This is the reverse of `%this`.
A `%fine` merge is a "fast-forward" merge. This succeeds iff one
head is in the ancestry of the other. In this case, we use the
descendant as our new head.
For `%meet`, `%mate`, and `%meld` merges, we first find the most
recent common ancestor to use as our merge base. If we have no
common ancestors, then we fail. If we have multiple most
recent common ancestors, then we have a criss-cross situation,
which should be handled delicately. At present, we don't handle
this kind of situation, but something akin to git's 'recursive'
strategy should be implemented in the future.
There's a functional inclusion ordering on `%fine`, `%meet`,
`%mate`, and `%meld` such that if an earlier strategy would have
succeeded, then every later strategy will produce the same
result. Put another way, every earlier strategy is the same as
every later strategy except with a restricted domain.
A `%meet` merge only succeeds if the changes from the merge base
to Alice's head (hereafter, "Alice's changes") are in different
files than Bob's changes. In this case, the parents are both
Alice's and Bob's heads, and the data is the merge base plus
Alice's changed files plus Bob's changed files.
A `%mate` merge attempts to merge changes to the same file when
both Alice and Bob change it. If the merge is clean, we use it;
otherwise, we fail. A merge between different types of changes --
for example, deleting a file vs changing it -- is always a
conflict. If we succeed, the parents are both Alice's and Bob's
heads, and the data is the merge base plus Alice's changed files
plus Bob's changed files plus the merged files.
A `%meld` merge will succeed even if there are conflicts. If
there are conflicts in a file, then we use the merge base's
version of that file, and we produce a set of files with
conflicts. The parents are both Alice's and Bob's heads, and the
data is the merge base plus Alice's changed files plus Bob's
changed files plus the successfully merged files plus the merge
base's version of the conflicting files.
### Metastrategies
There's also a meta-strategy `%auto`, which is the most common.
If no strategy is supplied, then `%auto` is assumed. `%auto`
checks to see if Bob's desk exists, and if it doesn't we use a
`%init` merge. Otherwise, we progressively try `%fine`,
`%meet`, and `%mate` until one succeeds.
If none succeed, we merge Bob's desk into a scratch desk. Then,
we merge Alice's desk into the scratch desk with the `%meld`
option to force the merge. For each file in the produced set of
conflicting files, we call the `++mash` function for the
appropriate mark, which annotates the conflicts if we know how.
Finally, we display a message to the user informing them of the
scratch desk's existence, which files have annotated conflicts,
and which files have unannotated conflicts. When the user has
resolved the conflicts, they can merge the scratch desk back into
Bob's desk. This will be a `%fine` merge since Bob's head is in
the ancestry of the scratch desk.
## Autosync
Since clay is reactive, it's possible for changes to the
filesystem to cause various actions. An important use of this is
in enabling "autosync". When a desk is synced to another, any
changes to the first desk are automatically applied to the
second.
This isn't simply mirroring, since the local desk might have
changes of its own. We use the full merge capabilities of clay
to try to make the merge clean. If there are conflicts, it'll
notify you and let you resolve them.
There can be complex sync flows, some of which are useful.
Often, many urbits will be synced to some upstream desk that is
trusted to provide updates. Sometimes, it's useful to sync two
desks to each other, so that changes to one or the other are
mirrored.
The syntax for syncing and unsyncing desks is as follows:
|sync %to-desk ~from-urbit %from-desk
|unsync %to-desk ~from-urbit %from-desk

View File

@ -1,95 +0,0 @@
`+ticket`
===================
Connecting your planet to moons.
The Urbit namespace is designed for you to have a planet in the
cloud and your other devices (pc, laptop, phone) are moons. Once you
have a moon, you can setup 2 way sync of various desks, much like
Dropbox or a reactive git. If you `|mount` the desks, you can
have synchronization between directories on your moon and planet's
systems.
Creating your moon
------------------
Each planet can issue 2^32 moons. Moon names look like two planet
names glued together and always end with the signing planet name. So
for the planet `~matfeb-sablud` one could generate a moon `~talsur-
todres-matfeb-sablud`.
### On your planet
All of your moons will sync from your `%kids` desk. Your planet
should come with one by default, but let's check to see:
```
> +ls /=kids=
```
You should get a list of directories. If you just get `~` you can
set one up with the following command:
```
>|sync %kids our %base
```
To generate a random moon you can run the following in the `dojo`:
```
+ticket =+(`@p`(cat 5 our (mod eny (pow 2 32))) ~&(- -))
```
The output will print your moon name above the line with the
command. It will look something like this:
```
~some-moon-some-planet
> +ticket =+(`@p`(cat 5 our (mod eny (pow 2 32))) ~&(- -))
~some-ticket
```
You'll use both of these values to create your moon in the next
step.
### On your PC/laptop
```
> bin/urbit -w some-moon-some-planet -t some-ticket
```
Wait for it to boot up and there you have it. You've created your
moon which is tied to your planet.
When you first boot your moon you will have a shell that is connected
to your planet. This might or might not be what you want. To get a
local shell, type `^d` at the dojo prompt, which should drop you into
the task manager. Then type `*dojo` to get a shell connected to your
moon.
Setting up 2-way sync
---------------------
To create a 2 way syncronized desk between your moon and your
planet, simply do the following:
On the moon:
```
> |sync %home ~matfeb-sablud %home
> |mount /=home= %home :: So you can see the files from Unix
```
On the planet:
```
> |sync %home ~hobdyl-pontyr-matfeb-sablud %home
```
The initial sync takes a little while, but after that you should be
able to create and edit files and have them sync up on the paired
system, much like your own personal Dropbox.
---
[This guide brought to you by `~matfeb-sablud`]

24
pub/docs.mdy Normal file
View File

@ -0,0 +1,24 @@
---
logo: black
anchor: none
layout: no-anchor
---
<div class="short">
# Urbit documentation
The Urbit doc is divided into three parts: [user doc](docs/user),
[developer doc](docs/dev), and [theory](docs/theory) (whitepaper, essays,
videos, etc).
If you want to try Urbit, start with the user doc. If you want
to learn about Urbit, try the theory. Or just start with the
user doc; it doesn't assume any prior knowledge.
The most fun thing to do with Urbit is code, but the developer
doc remains under construction. Sorry. We'll have more soon.
<list dataSort="true"></list>
</div>

27
pub/docs/dev.mdy Normal file
View File

@ -0,0 +1,27 @@
---
logo: black
title: Developer doc
sort: 2
---
<div class="short">
# Developer documentation
Urbit has three programming layers: Nock (combinator nano-VM),
Hoon (strict functional language), and Arvo (functional OS).
To code in Urbit, the least you need to learn is Hoon, plus a
little bit of Arvo. Nock is a sort of functional assembly
language -- you don't need to know it, but it's useful to.
Nock is also the easiest thing in the world to learn.
You can program for Arvo without knowing much about Arvo
internals, but again it helps. But you need to know Hoon.
Don't worry, it's easier than it looks.
Alas, the developer doc is still under construction. We'll have
more soon.
<list></list>
</div>

14
pub/docs/dev/arvo.mdy Normal file
View File

@ -0,0 +1,14 @@
---
logo: black
title: Arvo
sort: 3
---
<div class="short">
# Arvo
Arvo is a functional operating system.
Watch this space for actual documentation.
</div>

11
pub/docs/dev/client.mdy Normal file
View File

@ -0,0 +1,11 @@
---
logo: black
title: Frontend tools
sort: 4
hide: true
---
Frontend tools
==============
<list></list>

View File

@ -1,8 +1,12 @@
# `:tree`
`:tree` static file hosting internals.
`:tree` is the web filesystem interface. Odds are this file has been rendered for you by `:tree`.
`:tree` is a single-page app that uses a backend in `/home/tree` to load contents from `%clay` as the user navigates around as `%json`. The frontend lives in `/home/pub/tree` and is a fairly straightforward [React](https://facebook.github.io/react/) / [Flux](https://facebook.github.io/flux/) app.
`:tree` is a single-page app that uses a backend in `/home/tree` to load
contents from `%clay` as the user navigates around as `%json`. The frontend
lives in `/home/pub/tree` and is a fairly straightforward
[React](https://facebook.github.io/react/) /
[Flux](https://facebook.github.io/flux/) app.
## Frontend
@ -14,9 +18,14 @@ The CSS is written in [Stylus](https://learnboost.github.io/stylus/). The main e
### JS
The JS is written in [CoffeeScript](http://coffeescript.org/) and packaged with [Browserify](http://browserify.org/). The main entry point is `main.coffee` and is compiled with `browserify -t coffeeify main.coffee > main.js`. You'll need to `npm install` first.
The JS is written in [CoffeeScript](http://coffeescript.org/) and packaged with
[Browserify](http://browserify.org/). The main entry point is `main.coffee` and
is compiled with `browserify -t coffeeify main.coffee > main.js`. You'll need
to `npm install` first.
Each page is loaded as JSON and then rendered using React on the page. This allows us to write JSX in our markdown to implement simple components. Check out `/home/pub/tree/src/js/components` to see the component library.
Each page is loaded as JSON and then rendered using React on the page. This
allows us to write JSX in our markdown to implement simple components. Check
out `/home/pub/tree/src/js/components` to see the component library.
You'll notice that some of these doc pages use things like `<list>` in the raw markdown files.

View File

@ -0,0 +1,213 @@
---
title: Contributing
sort: 6
---
# Contributing to urbit
Thank you for your interest in contributing to urbit.
## Development practice
You may have an identity on the live network, but doing all your
development on the live network would be cumbersome and unnecessary.
Standard practice in urbit development is to work on a fake `~zod`. A
fake `~zod` will get its initial files from the `urb/zod/` directory
rather than trying to sync them over the network, which is invaluable
for working in Hoon. Also, a fake `~zod` or any fake urbit instances you
start do not talk to the live network, but to a fake network that exists
only on your computer.
To start a fake `~zod`, the command is:
bin/urbit -F -I zod -c [pier directory]
To resume one that was already created, just as on the live network,
remove `-c` (but leave the rest of the options there). `-F` uses the
fake network, and `-I` starts an "imperial" instance - that is, an 8-bit
galaxy.
## Kernel development
Working on either C or non-kernel Hoon should not bring any surprises,
but the Hoon kernel (anything under `urb/zod/arvo/`) is bootstrapped
from `urbit.pill` in `urb/`, and must be manually recompiled if any
changes are made. The command to manually recompile the kernel and
install the new kernel is `|reset` in `dojo`. This rebuilds from the
`arvo` directory in the `home` desk in `%clay`. Currently, `|reset`
does not reload apps like `dojo` itself, which will still reference the
old kernel. To force them to reload, make a trivial edit to their main
source file (under the `ape` directory) in `%clay`.
If you do any kernel development, be sure to read the section below about
pills.
## Git practice
Since we use the GitHub issue tracker, it is helpful to contribute via a
GitHub pull request. If you already know what you are doing, skip down
to the Style section.
Start by cloning the repository on your work machine:
git clone https://github.com/urbit/urbit
And, additionally, fork the repository on GitHub by clicking the "Fork"
button. Add your fork as a remote:
git remote add [username] https://github.com/[username]/urbit
and set it as the default remote to push to:
git config --local remote.pushDefault [username]
This is good practice for any project that uses git. You will pull
upstream branches from urbit/urbit and push to your personal urbit fork
by default.
Next, check out `test`, which is the mainline development branch, and
base a new branch on it to do your work on:
git checkout test
git checkout -b [branch name]
Now you are free to do your work on this branch. When finished, you may
want to clean up your commits:
git rebase -i test
Then you can push to your public fork with `git push` and make a pull
request via the GitHub UI. Make sure you request to merge your branch
into `test`, not `master`.
After your changes are merged upstream, you can delete your branch (via
github UI or `git push :[branch]` remotely, and with `git branch -d`
locally).
## Style
The urbit project uses two-space indentation and avoids tab characters.
In C code, it should not be too difficult to mimic the style of the code
around you, which is just fairly standard K&R with braces on every
compound statement. One thing to watch out for is top-level sections in
source files that are denoted by comments and are actually indented one
level.
Hoon will be a less familiar language to many contributors. Some of our
less obvious stylistic rules are:
- Keep your source files 80 characters or less wide. Many urbit
developers use 80 character terminals/tmux panes/&c.
- Tab characters are actually a syntax error, so be extra sure your
editor is not inserting any. Trailing whitespace is *usually* not a
syntax error, but avoiding it is encouraged.
- The kernel convention is that line comments start at column 57 with
the `::` followed by 2 spaces. This leaves 20 characters for the
comment. Outside the kernel, things are less strict.
- Tall arms within a core are conventionally separated by empty comments
(just `::`) at the same indentation level as the initial `++` or `+-`.
The last arm in a core is not followed by an empty comment, because it
is visually closed by the `--` that closes the core. The empty comment
is also sometimes omitted in data structure definitions.
## The kernel and pills
urbit bootstraps itself using a binary blob called `urbit.pill`, which
we do indeed keep in version control. This creates some special
requirements. If you are not changing anything in the kernel (everything
under `urb/zod/arvo/`) then you can skim this section (please do not
skip it entirely, though). If you *are* working there, then this
section is critically important!
The procedure for creating `urbit.pill` is often called "soliding". It
is somewhat similar to `|reset`, but instead of replacing your running
kernel, it writes the compiled kernel to a file. The command to solid
is, on a fakezod:
.urbit/pill +solid
When the compilation finishes, your `urbit.pill` will be found in the
`[pier]/.urb/put/` directory. Copy it into `urb/` and add it to your
commit.
The requirement here is that every commit that changes the kernel must
come with an `urbit.pill` built from the same code in `urb/zod/arvo/`
for that commit. (Only changing the actual Hoon code counts, so a change
to a jet with no corresponding Hoon change does not require a new pill.)
This is so that checking out an arbitrary revision and starting up a
fakezod actually works as expected. However you do this is fine, but I
like to do it as part of my committing process - just before `git
commit`, I fire up a new fakezod. This will use the previous
`urbit.pill`, but the kernel code in `%clay` will be copied from
`urb/zod/arvo/`, so `+solid` will compile it. Then I copy `urbit.pill`
into `urb/` and make my commit.
If you rebase or interactive rebase your commits, be sure to preserve
this property on all the commits you end up with. If multiple people
were collaborating on your branch, you may end up with conflicts in
`urbit.pill` and have to merge the branch into itself to resolve them.
Just do the same procedure to create a new, merged pill before
committing the merge. Otherwise, just make sure to use the correct
`urbit.pill` for each commit.
## Debug urbit with `gdb`
Follow the build instructions in README.md but run `make` with argument `DEBUG=yes`:
(If you've already built urbit first run `make clean`.)
make DEBUG=yes
Run `gdb`, while loading `bin/urbit` and its symbol table:
gdb bin/urbit
Set a breakpoint on `main()` (optional):
break main
Run your urbit comet `mycomet`:
run mycomet
Continue from the breakpoint on `main()`:
continue
## What to work on
If you are not thinking of contributing with a specific goal in mind,
the GitHub issue tracker is the first place you should look for ideas.
Issues are tagged with a priority and a difficulty. A good place to
start is on either a low-difficulty issue or a low-priority issue.
Higher priority issues are likely to be assigned to someone - if this is
the case, then contacting that person to coordinate before starting to
work is probably a good idea.
There is also a "help wanted" tag for things that we are especially
eager to have outside contributions on. Check here first!
## Staying in touch
The urbit developers communicate on urbit itself. Joining the
`~doznec/urbit-meta` channel on `talk` is highly recommended.
Subscribing to `urbit-dev` on Google Groups is also recommended, since
this is where continuity breach notifications are sent.
You can also contact one of the following people:
- Philip Monk
email: philip.monk@tlon.io
urbit: `~wictuc-folrex`
GitHub: [@philipcmonk](https://github.com/philipcmonk/)
- Raymond Pasco
email: ray@the.ug
urbit: `~ramtev-wisbyt`
GitHub: [@juped](https://github.com/juped/)

15
pub/docs/dev/hoon.mdy Normal file
View File

@ -0,0 +1,15 @@
---
logo: black
title: Hoon
sort: 2
---
<div class="short">
# Hoon
Hoon is a strict, typed, pure functional language.
Watch this space for actual documentation.
</div>

Some files were not shown because too many files have changed in this diff Show More