@nervur-org/dock 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/GETTING_STARTED.md +128 -0
- package/LICENSE +202 -0
- package/NOTICE +6 -0
- package/README.md +37 -0
- package/api/quo-api.md +196 -0
- package/api/route.ts +227 -0
- package/beings/GLOSSARY.md +118 -0
- package/beings/WORLDS.md +567 -0
- package/beings/avatar.ts +101 -0
- package/beings/carry.ts +159 -0
- package/beings/clock.ts +552 -0
- package/beings/courier.ts +107 -0
- package/beings/desk.ts +128 -0
- package/beings/doorbell.ts +129 -0
- package/beings/envoy.ts +218 -0
- package/beings/index.ts +16 -0
- package/beings/join.ts +51 -0
- package/beings/link.ts +104 -0
- package/beings/look.ts +139 -0
- package/beings/porter.ts +43 -0
- package/beings/presence.ts +39 -0
- package/beings/quo-app-bells.md +280 -0
- package/beings/quo-dock.md +1942 -0
- package/beings/setup.ts +45 -0
- package/beings/side.ts +60 -0
- package/beings/user.ts +459 -0
- package/beings/way.ts +65 -0
- package/cli/bundles.ts +20 -0
- package/cli/client.ts +73 -0
- package/cli/daemon.ts +581 -0
- package/cli/estate/Caddyfile +33 -0
- package/cli/estate/quo.service +35 -0
- package/cli/estate/systems.quo.plist +44 -0
- package/cli/estate.ts +48 -0
- package/cli/folder.ts +27 -0
- package/cli/oauth.ts +32 -0
- package/cli/pilot.ts +38 -0
- package/cli/quo-dock.md +1942 -0
- package/cli/quo.ts +203 -0
- package/cli/stand.ts +160 -0
- package/dist/api/route.d.ts +21 -0
- package/dist/api/route.js +193 -0
- package/dist/beings/avatar.d.ts +32 -0
- package/dist/beings/avatar.js +100 -0
- package/dist/beings/carry.d.ts +12 -0
- package/dist/beings/carry.js +174 -0
- package/dist/beings/clock.d.ts +161 -0
- package/dist/beings/clock.js +528 -0
- package/dist/beings/courier.d.ts +50 -0
- package/dist/beings/courier.js +96 -0
- package/dist/beings/desk.d.ts +53 -0
- package/dist/beings/desk.js +135 -0
- package/dist/beings/doorbell.d.ts +78 -0
- package/dist/beings/doorbell.js +133 -0
- package/dist/beings/envoy.d.ts +54 -0
- package/dist/beings/envoy.js +211 -0
- package/dist/beings/index.d.ts +14 -0
- package/dist/beings/index.js +16 -0
- package/dist/beings/join.d.ts +15 -0
- package/dist/beings/join.js +42 -0
- package/dist/beings/link.d.ts +14 -0
- package/dist/beings/link.js +91 -0
- package/dist/beings/look.d.ts +30 -0
- package/dist/beings/look.js +104 -0
- package/dist/beings/porter.d.ts +14 -0
- package/dist/beings/porter.js +41 -0
- package/dist/beings/presence.d.ts +8 -0
- package/dist/beings/presence.js +21 -0
- package/dist/beings/setup.d.ts +3 -0
- package/dist/beings/setup.js +39 -0
- package/dist/beings/side.d.ts +32 -0
- package/dist/beings/side.js +37 -0
- package/dist/beings/user.d.ts +315 -0
- package/dist/beings/user.js +462 -0
- package/dist/beings/way.d.ts +19 -0
- package/dist/beings/way.js +28 -0
- package/dist/cli/bundles.d.ts +5 -0
- package/dist/cli/bundles.js +17 -0
- package/dist/cli/client.d.ts +15 -0
- package/dist/cli/client.js +58 -0
- package/dist/cli/daemon.d.ts +50 -0
- package/dist/cli/daemon.js +584 -0
- package/dist/cli/estate/Caddyfile +33 -0
- package/dist/cli/estate/quo.service +35 -0
- package/dist/cli/estate/systems.quo.plist +44 -0
- package/dist/cli/estate.d.ts +5 -0
- package/dist/cli/estate.js +50 -0
- package/dist/cli/folder.d.ts +2 -0
- package/dist/cli/folder.js +25 -0
- package/dist/cli/oauth.d.ts +2 -0
- package/dist/cli/oauth.js +32 -0
- package/dist/cli/pilot.d.ts +5 -0
- package/dist/cli/pilot.js +22 -0
- package/dist/cli/quo.d.ts +2 -0
- package/dist/cli/quo.js +201 -0
- package/dist/cli/stand.d.ts +37 -0
- package/dist/cli/stand.js +110 -0
- package/dist/dock/agents.d.ts +102 -0
- package/dist/dock/agents.js +105 -0
- package/dist/dock/apns.d.ts +27 -0
- package/dist/dock/apns.js +98 -0
- package/dist/dock/console.d.ts +6 -0
- package/dist/dock/console.js +20 -0
- package/dist/dock/dialers.d.ts +56 -0
- package/dist/dock/dialers.js +75 -0
- package/dist/dock/faculty.d.ts +24 -0
- package/dist/dock/faculty.js +142 -0
- package/dist/dock/fcm.d.ts +13 -0
- package/dist/dock/fcm.js +77 -0
- package/dist/dock/grants.d.ts +41 -0
- package/dist/dock/grants.js +99 -0
- package/dist/dock/http2.d.ts +4 -0
- package/dist/dock/http2.js +68 -0
- package/dist/dock/index.d.ts +41 -0
- package/dist/dock/index.js +113 -0
- package/dist/dock/local.d.ts +13 -0
- package/dist/dock/local.js +44 -0
- package/dist/dock/location.d.ts +19 -0
- package/dist/dock/location.js +11 -0
- package/dist/dock/notifications.d.ts +38 -0
- package/dist/dock/notifications.js +60 -0
- package/dist/dock/push.d.ts +79 -0
- package/dist/dock/push.js +132 -0
- package/dist/dock/service.d.ts +4 -0
- package/dist/dock/service.js +107 -0
- package/dist/dock/timer.d.ts +52 -0
- package/dist/dock/timer.js +149 -0
- package/dist/dock/webpush.d.ts +12 -0
- package/dist/dock/webpush.js +144 -0
- package/dist/harbor/browser.d.ts +15 -0
- package/dist/harbor/browser.js +82 -0
- package/dist/harbor/capacitor.d.ts +28 -0
- package/dist/harbor/capacitor.js +218 -0
- package/dist/harbor/disk.d.ts +27 -0
- package/dist/harbor/disk.js +249 -0
- package/dist/harbor/edge/alarm.d.ts +10 -0
- package/dist/harbor/edge/alarm.js +38 -0
- package/dist/harbor/edge/edge.d.ts +54 -0
- package/dist/harbor/edge/edge.js +370 -0
- package/dist/harbor/edge/exercise.d.ts +7 -0
- package/dist/harbor/edge/exercise.js +232 -0
- package/dist/harbor/edge/given.d.ts +26 -0
- package/dist/harbor/edge/given.js +42 -0
- package/dist/harbor/edge/platform.d.ts +39 -0
- package/dist/harbor/edge/storage.d.ts +30 -0
- package/dist/harbor/edge/storage.js +180 -0
- package/dist/harbor/edge/worker.d.ts +17 -0
- package/dist/harbor/edge/worker.js +67 -0
- package/dist/harbor/files.d.ts +15 -0
- package/dist/harbor/files.js +220 -0
- package/dist/harbor/http.d.ts +19 -0
- package/dist/harbor/http.js +177 -0
- package/dist/harbor/idb.d.ts +15 -0
- package/dist/harbor/idb.js +0 -0
- package/dist/harbor/quo.d.ts +10 -0
- package/dist/harbor/quo.js +42 -0
- package/dist/harbor/resolve.d.ts +16 -0
- package/dist/harbor/resolve.js +17 -0
- package/dist/harbor/seal.d.ts +3 -0
- package/dist/harbor/seal.js +25 -0
- package/dist/harbor/sealed.d.ts +35 -0
- package/dist/harbor/sealed.js +162 -0
- package/dist/harbor/tauri.d.ts +16 -0
- package/dist/harbor/tauri.js +59 -0
- package/dist/harbor/ward.d.ts +9 -0
- package/dist/harbor/ward.js +15 -0
- package/dist/human/app.d.ts +32 -0
- package/dist/human/app.js +527 -0
- package/dist/human/apps.d.ts +10 -0
- package/dist/human/apps.js +29 -0
- package/dist/human/dom.d.ts +2 -0
- package/dist/human/dom.js +15 -0
- package/dist/human/door.d.ts +19 -0
- package/dist/human/door.js +92 -0
- package/dist/human/guest.d.ts +3 -0
- package/dist/human/guest.js +33 -0
- package/dist/human/html.d.ts +55 -0
- package/dist/human/html.js +451 -0
- package/dist/human/local.d.ts +7 -0
- package/dist/human/local.js +10 -0
- package/dist/human/mark.d.ts +8 -0
- package/dist/human/mark.js +47 -0
- package/dist/human/move.d.ts +17 -0
- package/dist/human/move.js +90 -0
- package/dist/human/screen.d.ts +19 -0
- package/dist/human/screen.js +119 -0
- package/dist/human/style.d.ts +2 -0
- package/dist/human/style.js +60 -0
- package/dist/human/tab.bundle.txt +4775 -0
- package/dist/human/tab.d.ts +15 -0
- package/dist/human/tab.js +409 -0
- package/dist/human/tree.d.ts +50 -0
- package/dist/human/tree.js +157 -0
- package/dist/human/wake.d.ts +34 -0
- package/dist/human/wake.js +179 -0
- package/dist/human/web.d.ts +33 -0
- package/dist/human/web.js +184 -0
- package/dist/human/worker.bundle.txt +3868 -0
- package/dist/human/worker.d.ts +1 -0
- package/dist/human/worker.js +81 -0
- package/dist/human/worlds.d.ts +24 -0
- package/dist/human/worlds.js +99 -0
- package/dist/mcp/agent.d.ts +10 -0
- package/dist/mcp/agent.js +78 -0
- package/dist/mcp/allow.d.ts +20 -0
- package/dist/mcp/allow.js +88 -0
- package/dist/mcp/http.d.ts +27 -0
- package/dist/mcp/http.js +92 -0
- package/dist/mcp/oauth.d.ts +91 -0
- package/dist/mcp/oauth.js +241 -0
- package/dist/mcp/route.d.ts +15 -0
- package/dist/mcp/route.js +42 -0
- package/dist/mcp/runner.d.ts +45 -0
- package/dist/mcp/runner.js +99 -0
- package/dist/mcp/server.d.ts +11 -0
- package/dist/mcp/server.js +102 -0
- package/dock/agents.ts +121 -0
- package/dock/apns.ts +138 -0
- package/dock/console.ts +23 -0
- package/dock/dialers.ts +85 -0
- package/dock/faculty.ts +148 -0
- package/dock/fcm.ts +103 -0
- package/dock/grants.ts +111 -0
- package/dock/http2.ts +70 -0
- package/dock/index.ts +133 -0
- package/dock/local.ts +48 -0
- package/dock/location.ts +22 -0
- package/dock/notifications.ts +67 -0
- package/dock/push.ts +161 -0
- package/dock/quo-app-bells.md +280 -0
- package/dock/quo-dock.md +1942 -0
- package/dock/service.ts +100 -0
- package/dock/timer.ts +174 -0
- package/dock/webpush.ts +182 -0
- package/harbor/browser.ts +97 -0
- package/harbor/capacitor.ts +223 -0
- package/harbor/disk.ts +237 -0
- package/harbor/edge/alarm.ts +48 -0
- package/harbor/edge/edge.ts +407 -0
- package/harbor/edge/exercise.ts +241 -0
- package/harbor/edge/given.ts +106 -0
- package/harbor/edge/platform.d.ts +39 -0
- package/harbor/edge/storage.ts +179 -0
- package/harbor/edge/text.d.ts +15 -0
- package/harbor/edge/worker.ts +70 -0
- package/harbor/edge/wrangler.toml +30 -0
- package/harbor/files.ts +221 -0
- package/harbor/http.ts +188 -0
- package/harbor/idb.ts +0 -0
- package/harbor/quo-harbor.md +850 -0
- package/harbor/quo.ts +44 -0
- package/harbor/resolve.ts +31 -0
- package/harbor/seal.ts +26 -0
- package/harbor/sealed.ts +183 -0
- package/harbor/tauri.ts +79 -0
- package/harbor/ward.ts +28 -0
- package/human/app.ts +580 -0
- package/human/apps.ts +47 -0
- package/human/dom.ts +21 -0
- package/human/door.ts +113 -0
- package/human/guest.ts +34 -0
- package/human/html.ts +490 -0
- package/human/local.ts +30 -0
- package/human/mark.ts +53 -0
- package/human/move.ts +122 -0
- package/human/quo-human.md +1042 -0
- package/human/screen.ts +136 -0
- package/human/style.ts +63 -0
- package/human/tab.bundle.txt +4775 -0
- package/human/tab.ts +446 -0
- package/human/tree.ts +217 -0
- package/human/wake.ts +191 -0
- package/human/web.ts +259 -0
- package/human/worker.bundle.txt +3868 -0
- package/human/worker.ts +124 -0
- package/human/worlds.ts +127 -0
- package/mcp/agent.ts +94 -0
- package/mcp/allow.ts +131 -0
- package/mcp/http.ts +92 -0
- package/mcp/oauth.ts +270 -0
- package/mcp/quo-mcp.md +343 -0
- package/mcp/route.ts +45 -0
- package/mcp/runner.ts +136 -0
- package/mcp/server.ts +101 -0
- package/package.json +121 -0
|
@@ -0,0 +1,1042 @@
|
|
|
1
|
+
# The human side
|
|
2
|
+
|
|
3
|
+
This is how a Quo world speaks to a human, and how a human speaks back. It
|
|
4
|
+
is one side of the avatar described in `papers/quo-dock.md`,
|
|
5
|
+
which owns the avatar, the front desk, the credential exchange, carrying,
|
|
6
|
+
the look and the shared invariants; this document assumes all of that and
|
|
7
|
+
adds only what a screen needs. It names no transport and no model. A tab is
|
|
8
|
+
a device with a harbor of its own, and where its bytes go is
|
|
9
|
+
`papers/quo-harbor.md`.
|
|
10
|
+
|
|
11
|
+
The claim, made good on: a human needs no page written for them. A screen
|
|
12
|
+
is a blueprint spoken as HTML. A being's describe for this asker becomes the
|
|
13
|
+
forms the human sees, a submitted form becomes a named ask, an answer
|
|
14
|
+
becomes a view, a push becomes a notification, and the three words for "no
|
|
15
|
+
object" each have a face. Nothing the screen shows exists anywhere but in a
|
|
16
|
+
blueprint and a look, so every world gets a screen for free and no world
|
|
17
|
+
gets a screen it did not describe.
|
|
18
|
+
|
|
19
|
+
Three sides, one describe. The CLI, the model side and the screen are three
|
|
20
|
+
views of the same beings, and the screen adds no vocabulary of its own:
|
|
21
|
+
what a being can be asked is her blueprint, how she wants to be shown is
|
|
22
|
+
her `look`, and both are values that travel through the relation. A being
|
|
23
|
+
who wants more than forms answers `page`, her page as a tree of values in
|
|
24
|
+
one closed grammar, and the screen paints it; a being who answers nothing
|
|
25
|
+
gets the forms. A world that wants a page of its own writes any HTML, CSS
|
|
26
|
+
and JavaScript it likes on its own origin, against the avatar's handles and
|
|
27
|
+
nothing else; a world that writes none gets this screen.
|
|
28
|
+
|
|
29
|
+
## What a human meets
|
|
30
|
+
|
|
31
|
+
This side answers for every moment a human has with a world, and the set is
|
|
32
|
+
closed. It is fixed by what Quo already decides: four rungs, stranger,
|
|
33
|
+
occupant, owner and root; an org's three things, home, presence and
|
|
34
|
+
membership, and the state of holding none; four surfaces, a public front,
|
|
35
|
+
the `web.` route, an app and the doorbell; and eight acts, arrive, join,
|
|
36
|
+
ask, be answered, be woken, authorize, move and leave. A moment outside
|
|
37
|
+
that set is either not a human moment or one of those four is wrong, and
|
|
38
|
+
the second is worth knowing.
|
|
39
|
+
|
|
40
|
+
**Arriving.** A stranger reaches a world's page carrying nothing and meets
|
|
41
|
+
the door page, which asks for nothing, because there is nothing a stranger
|
|
42
|
+
could type that would let them in. A stranger who has never heard of Quo
|
|
43
|
+
meets a public front instead, which is a website and not a route into any
|
|
44
|
+
box.
|
|
45
|
+
|
|
46
|
+
**Joining**, and there are three ways and no fourth. An invitation in a
|
|
47
|
+
link's fragment, joined in the ward it names. A proof a world handed out
|
|
48
|
+
itself, which names no ward and is knocked at the public being of the
|
|
49
|
+
world whose page it was opened on. A form on that public being's page
|
|
50
|
+
whose answer is an invitation. Nothing is typed to get in on any of them.
|
|
51
|
+
How a world hands out the second is the world's own business and never
|
|
52
|
+
this side's: what a kind of proof is, and what carries it, is decided by
|
|
53
|
+
the org and named nowhere here.
|
|
54
|
+
|
|
55
|
+
**Asking and being answered.** Her describe for this asker is forms, her
|
|
56
|
+
answer is a view, her `look` says how her section is painted, and her
|
|
57
|
+
`page` is a tree of values she designs and the screen paints. An answer
|
|
58
|
+
that is an invitation is a way in and reads as one. An answer that is a
|
|
59
|
+
link reads as a link, and the side is what composes it, since a being
|
|
60
|
+
knows no routes.
|
|
61
|
+
|
|
62
|
+
**Holding more than one relation.** One local ward per far world, one
|
|
63
|
+
avatar per relation. Two people sharing one device are two relations in
|
|
64
|
+
one world, and one person may hold several in the same world.
|
|
65
|
+
|
|
66
|
+
**Being woken.** With a page open, on a page that is closed, and in an
|
|
67
|
+
app. What the human reads is composed on her own device from objects that
|
|
68
|
+
crossed sealed, and never by whatever carried the ring.
|
|
69
|
+
|
|
70
|
+
**Authorizing.** A model or a program asks to be let into a world, and a
|
|
71
|
+
human is the only one who can say yes. No other way in answers this.
|
|
72
|
+
|
|
73
|
+
**Placing an account.** An envoy stands in for a thing that speaks no Quo,
|
|
74
|
+
and the key that account was given is placed from a form on the owner's own
|
|
75
|
+
page, by the ordinary screen and never at a shell. The screen never paints
|
|
76
|
+
it back, because the envoy answers that she kept it and answers nothing
|
|
77
|
+
else, ever.
|
|
78
|
+
|
|
79
|
+
**Lending.** What a device can do, it offers as forms on that device's own
|
|
80
|
+
page, and the platform's prompt belongs to the first ask rather than to the
|
|
81
|
+
install. A refusal is the error object every ask after it answers.
|
|
82
|
+
|
|
83
|
+
**Moving.** A world goes from one device to another whole, and the far
|
|
84
|
+
world is never asked and never told.
|
|
85
|
+
|
|
86
|
+
**Gaining a home.** An org whose whole existence was standings in other
|
|
87
|
+
orgs' worlds boots a home, and joins each of those worlds from it. Her
|
|
88
|
+
device at each mints an invitation as it would for any device of hers, and
|
|
89
|
+
her home knocks with it, so from the far side a home is one more thing of
|
|
90
|
+
hers holding a standing. Nothing is converted and no id changes, because
|
|
91
|
+
there is nothing to convert.
|
|
92
|
+
|
|
93
|
+
**Leaving, and losing.** A relation ends when either side removes a
|
|
94
|
+
standing, and the screen tells the two apart from a world that is merely
|
|
95
|
+
away. A device is lost or its store is cleared, and a presence is a seed,
|
|
96
|
+
so what that costs is said plainly.
|
|
97
|
+
|
|
98
|
+
## The page
|
|
99
|
+
|
|
100
|
+
The front end is a ward, and the first move towards it: a page is a tree of
|
|
101
|
+
values in a closed grammar the dock owns, `tree.ts`, and a far being
|
|
102
|
+
answers it from `page` the way she answers `look`, values only. One
|
|
103
|
+
grammar, two sources: the same tree will be computed in the tab by a being
|
|
104
|
+
running there, from her cells, and painted by the same painter.
|
|
105
|
+
|
|
106
|
+
- **The grammar.** `stack` and `row` hold children, one under another or
|
|
107
|
+
side by side; `text` is words with a role, `title`, `lead`, `body`,
|
|
108
|
+
`quiet` or `label`; `image` is a picture as a data URI, never a URL;
|
|
109
|
+
`form` is one of her asks by name, painted as the form the schema gives;
|
|
110
|
+
`answer` is one of her asks' last answer, shown as `auto`, `text`,
|
|
111
|
+
`table`, `cards`, `list`, `people` or `feed`; `standing` is one standing
|
|
112
|
+
she carries, painted as its section; `standings` is every one of them;
|
|
113
|
+
`link` is somewhere to go. No selector, no stylesheet, no script, and no
|
|
114
|
+
node beyond these: a node that fails its shape is dropped, not fixed, and
|
|
115
|
+
a container with nothing left is kept empty, since an empty region is a
|
|
116
|
+
design and not a fault.
|
|
117
|
+
- **A being says what, and never how.** A container may name the kind of
|
|
118
|
+
thing it holds, `as`: a stack is a `list`, several of one thing as rows
|
|
119
|
+
on one surface; a `grid` of cards; a `hero`, one thing on a lot of air;
|
|
120
|
+
a `feed`, what happened in order; and a row is a `person`, a face and
|
|
121
|
+
the words beside it. A standing may be a `door`: named, with the way to
|
|
122
|
+
her own page, and nothing of hers on this one, which is how the user
|
|
123
|
+
being carries her own world's door, seven owner asks that are a page of
|
|
124
|
+
their own and not a section among her worlds. An answer names its kind
|
|
125
|
+
the same way: `people` are
|
|
126
|
+
rows of `{ name, line?, picture? }`, a `feed` rows of `{ at, text }`, and
|
|
127
|
+
a value not of that shape is shown by its own. That is the whole
|
|
128
|
+
vocabulary an estate gets. What each kind is on a screen, where it sits,
|
|
129
|
+
how it reflows, is the painter's opinion and the kit's piece, one for
|
|
130
|
+
every world, so a family's members and a shop's customers are one shape
|
|
131
|
+
on every device and no class carries a layout. A kind an estate wants and
|
|
132
|
+
the grammar lacks is asked for here, and never written around.
|
|
133
|
+
- **The painter emits the kit and nothing else.** Every node paints as a
|
|
134
|
+
piece of `papers/quo-ui.md`'s catalogue, a `stack` as `.nv-stack`, a
|
|
135
|
+
`list` as `.nv-list` of `.nv-item`, a `person` as `.nv-person` with an
|
|
136
|
+
`.nv-avatar`, a title as `.nv-t-title`, a form as the kit's fieldset and
|
|
137
|
+
fields and one `.nv-button`, an answer as `.nv-answer` with the word it
|
|
138
|
+
came back as on it, a standing as `.nv-standing` under her own look. The
|
|
139
|
+
screen's own stylesheet is what the shells alone have and holds no
|
|
140
|
+
piece of its own; a piece it needs is the kit's or is asked for there.
|
|
141
|
+
- **A name is said once.** The bar names the world and where the human
|
|
142
|
+
stands, as a chip whose tone is her standing; a page that opens with a
|
|
143
|
+
title of its own is the name, and the bar keeps only the chip. A being
|
|
144
|
+
painted as forms has no page to say it, so the bar says her name. A
|
|
145
|
+
standing painted inside another's page keeps her own title inside her
|
|
146
|
+
section, and the section that is the whole page is the page's title.
|
|
147
|
+
- **A link is named by a being and vouched for by the side.** A human who
|
|
148
|
+
must pay, sign or come back from a vendor has to be able to go there, so
|
|
149
|
+
a being may name a place. She names it and no more: the grammar takes an
|
|
150
|
+
absolute `http` or `https` address, parsed rather than matched, so a
|
|
151
|
+
scheme that runs code or carries its own content is nothing at all. What
|
|
152
|
+
the side then does with it is the rule. Two origins are vouched for and
|
|
153
|
+
no third. The origin of the page she is standing on, so a being may move
|
|
154
|
+
a human around inside the world she already chose. And the origins that
|
|
155
|
+
being declared in her look as the ones she stands in for, `stands`,
|
|
156
|
+
which is how an envoy speaking for a payment or a booking vendor sends a
|
|
157
|
+
human to that vendor's own checkout. A carried standing vouches by her
|
|
158
|
+
own look and never her carrier's. Any other address is painted as its
|
|
159
|
+
own words, in full, and the human goes there by her own hand or not at
|
|
160
|
+
all. An address is never dropped in silence, because a page that quietly
|
|
161
|
+
deletes what a being said is a page that lies about her.
|
|
162
|
+
- **A link that leaves the world says so.** An anchor to an origin the
|
|
163
|
+
being stands in for carries that origin in the page, and the screen
|
|
164
|
+
paints it after the words, so where a human is going is read on the page
|
|
165
|
+
rather than in a status bar she may never look at. An anchor is handed
|
|
166
|
+
no window and no referer, `noopener` and `noreferrer`, since the page it
|
|
167
|
+
opens is the vendor's and not ours.
|
|
168
|
+
- **An answer that is an invitation is a way in.** The side recognises one
|
|
169
|
+
and composes the link itself, on the world's page address, because a
|
|
170
|
+
being knows no routes and a side does. This holds for every ask on every
|
|
171
|
+
shell, a tab and an app alike, and it is why the grammar carries no
|
|
172
|
+
address for it.
|
|
173
|
+
- **A page adds no right.** Every name a tree uses, an ask or a standing,
|
|
174
|
+
is looked up in her describe for this asker; a name that is not there
|
|
175
|
+
paints as nothing. Her page says what is shown and where, and her gate
|
|
176
|
+
says what may be asked; a device that may not wake sees no `push` form
|
|
177
|
+
however her page names it, and an ask her describe holds but her page
|
|
178
|
+
does not name has no form. `hello` and `report` are wiring, a device's
|
|
179
|
+
first word and an agent's callback, and stay under the gate and off her
|
|
180
|
+
page.
|
|
181
|
+
- **What opens with the page.** The answers a tree shows are run on open
|
|
182
|
+
when the ask needs nothing typed, beside the read-only asks her look
|
|
183
|
+
marks, so the page opens with what it shows.
|
|
184
|
+
- **The page is presentation.** `page` is asked after every call, and it is
|
|
185
|
+
never a form and never a tool, hers or a carried one. The user being
|
|
186
|
+
answers one: her name as the title, who this device is as
|
|
187
|
+
an answer, her standings as sections, and the three things a human does
|
|
188
|
+
here by hand, bringing her next device in, waking one and calling her by
|
|
189
|
+
a name, as forms.
|
|
190
|
+
A being does not know her own key, so her name is given: by the desk's
|
|
191
|
+
first hello at the root's setup, or by a device the root minted, through
|
|
192
|
+
her `name` ask, the trunk's rule.
|
|
193
|
+
- **The door is the first page in the grammar**, painted with nobody behind
|
|
194
|
+
it: no ask, no answer, no standing, only the mark, a word and a sentence.
|
|
195
|
+
|
|
196
|
+
## The tab ward
|
|
197
|
+
|
|
198
|
+
A world's code runs in the tab, as beings. The second source of the one
|
|
199
|
+
grammar: a being booted in the tab's local ward for a world answers `page`
|
|
200
|
+
from her cells, and the same side paints her with the same painter. No
|
|
201
|
+
second verb, no framework, no script of the world's on the page: only
|
|
202
|
+
classes, and the ward runs them.
|
|
203
|
+
|
|
204
|
+
- **The world's code is a module the harbor folder holds**, `tab/index.ts`,
|
|
205
|
+
the twin of `classes/index.ts`: the classes meant for the tab, exported
|
|
206
|
+
by name. The estate that deploys the harbor bundles it into
|
|
207
|
+
`tab/index.js` beside the source, because the route runs no compiler, and
|
|
208
|
+
the web route serves that built file as `beings.js` on the world's origin
|
|
209
|
+
and tells the page it exists. A folder with neither has no such path; a
|
|
210
|
+
folder with the source and no built file is a build that did not run, and
|
|
211
|
+
the path says so instead of serving a page with no classes in it. Code
|
|
212
|
+
crosses the origin, never a relation, and one origin is one world's code.
|
|
213
|
+
- **A world wears a design, and the harbor folder holds it.** `design/`
|
|
214
|
+
beside the wards is one design's compiled face, `tokens.css`, and the
|
|
215
|
+
faces it speaks in, `fonts.css` and `fonts/`, copied there from the
|
|
216
|
+
design the estate wears. The route reads no file: it asks the terrain for
|
|
217
|
+
those three things by name, and a name it does not know it never asks
|
|
218
|
+
for, so nothing else in the folder is reachable. Every page it writes
|
|
219
|
+
links them
|
|
220
|
+
after the kit without the kit's own face, since a surface loads the
|
|
221
|
+
default face or a design's and never both; the page's policy admits its
|
|
222
|
+
own origin for styles and fonts and no other. A harbor with no `design/`
|
|
223
|
+
wears the kit's own face. The app wears the kit's face and a world's
|
|
224
|
+
look tints its section, since the app is one bundle for every world.
|
|
225
|
+
- **The boot at join.** The tab loads the world's classes before its harbor
|
|
226
|
+
boots, since a being kept from the last visit is booted by her class
|
|
227
|
+
name. When a relation goes on screen, the tab boots one being of each
|
|
228
|
+
class under that relation's key, `r1-Notes`, the first time, and finds
|
|
229
|
+
her there after: her cells are in the ward, kept in the tab's store after
|
|
230
|
+
every ask and migrating with the ward. Two relations in one world are two
|
|
231
|
+
of each, since what she keeps is one person's.
|
|
232
|
+
- **A subject with no standing.** The tab holds that ward's ask pointer, so
|
|
233
|
+
the tab is its root, and `local.ts` is the owner's `ask` and nothing else:
|
|
234
|
+
no relation, no key rotation and no asker of its own making, since the
|
|
235
|
+
local ward is the human's and she is on it. The ward names the asker,
|
|
236
|
+
bounds the wait, judges her answer and saves before the pointer returns.
|
|
237
|
+
Her describe is what she shows the tab, her
|
|
238
|
+
forms are her asks, and a push never reaches her, since nothing outside
|
|
239
|
+
the tab holds her.
|
|
240
|
+
- **Her page follows every ask.** `page` is asked again after each call
|
|
241
|
+
and the answers it shows are run again with it, so a cell moved is a page
|
|
242
|
+
moved whether or not her describe moved. The describe, the look and the
|
|
243
|
+
read-only asks off the page stay once per digest. A far being pays the
|
|
244
|
+
same: her page is never more than one ask behind her.
|
|
245
|
+
- **One section each.** Under the far being's page, each being of the world
|
|
246
|
+
has her own section and her own side; the shell's own heading is dropped
|
|
247
|
+
wherever a page carries its title.
|
|
248
|
+
- **A carried page is painted in her section.** The third source of the one
|
|
249
|
+
grammar, and no new grammar: a standing the user being carries answers
|
|
250
|
+
`page` like anyone, the carrier carries it as `<id>-page` and names it in
|
|
251
|
+
her notes, and the side asks it after every call like her own. The
|
|
252
|
+
section that was her forms under her name becomes her page under her
|
|
253
|
+
look, painted through a painter of her own: a form or an answer it names
|
|
254
|
+
is one of her asks by its bare name, carried, and a name that is not hers,
|
|
255
|
+
or a `standing` inside a page, paints as nothing. So a far page reaches
|
|
256
|
+
nothing outside its section, by construction and not by a shadow root:
|
|
257
|
+
the grammar carries no selector, no script and no stylesheet, the one
|
|
258
|
+
stylesheet is the shell's, and a root of her own would keep the shell's
|
|
259
|
+
stylesheet out of her section for no gain. The section is the root a page
|
|
260
|
+
owns.
|
|
261
|
+
|
|
262
|
+
## How a screen is made
|
|
263
|
+
|
|
264
|
+
Read with the trunk's "Carrying" and "The look", which this applies.
|
|
265
|
+
|
|
266
|
+
- **A form from a schema, without a designer.** An input schema is a form
|
|
267
|
+
with one field per property by type: a string is a text input, and
|
|
268
|
+
`password`, `date`, `email` and `time` are the input's type; a number is a
|
|
269
|
+
number input; a boolean a checkbox; an enum a select; an object or an
|
|
270
|
+
array a box for JSON. The submitted strings come back as arguments typed by
|
|
271
|
+
the schema, an empty optional field left out. A hint from her look puts a
|
|
272
|
+
title and an icon on the button and marks a destructive ask.
|
|
273
|
+
- **What the screen can answer, the screen answers.** A property whose schema
|
|
274
|
+
says `format: "moment"` gets no field: a being may not read a clock, and a
|
|
275
|
+
screen is not a being, so it fills the moment from the device it runs on,
|
|
276
|
+
at the moment the form is sent rather than the moment the page was drawn.
|
|
277
|
+
A read-only ask with nothing left for a human to type then runs itself on
|
|
278
|
+
open and draws its answer where its form would have been. So a clock's page
|
|
279
|
+
opens as three tables, and nobody is ever asked to type milliseconds. It is
|
|
280
|
+
read off the input schema and never off a look, because a look is what a
|
|
281
|
+
being says about being drawn and this is not: the ask says what the argument
|
|
282
|
+
is, and each side does what it can with that.
|
|
283
|
+
- **A view from an answer.** A primitive is text, an object a table of its
|
|
284
|
+
keys in the output schema's order when she declared one, a list of objects
|
|
285
|
+
one table, null the word nothing. An error object is marked; silence and
|
|
286
|
+
each of the ward's words say what the side says of them.
|
|
287
|
+
- **A standing is a section.** The user being carries her standings, and
|
|
288
|
+
her notes say which asks are whose. The page draws her own asks first,
|
|
289
|
+
then one section per standing, headed by that being's name and logo and
|
|
290
|
+
painted with her tokens as CSS variables on that section and nowhere
|
|
291
|
+
else. A form in acme's section is an ask on the human's standing at acme,
|
|
292
|
+
and acme sees the human, never the device. The same section appears on
|
|
293
|
+
acme's own web, under the same look: one component, two relations.
|
|
294
|
+
- **The page follows the digest.** The side asks the describe again after
|
|
295
|
+
every call, asks `look` once per digest and `page` after every call; a
|
|
296
|
+
digest that moved is a page that moved, and so is a cell that moved
|
|
297
|
+
behind a page. A read-only ask with nothing to type is run on open,
|
|
298
|
+
so a page can open with what it shows and not only with buttons. Every one
|
|
299
|
+
of those asks rotates her keys, so the side saves after each, not only
|
|
300
|
+
after a form: a relation brought back from a reload with a stale count is
|
|
301
|
+
refused at the far door and hears silence.
|
|
302
|
+
- **What a look may carry, and never.** The trunk's table is the whole
|
|
303
|
+
list: a name, a logo as a data URI, three colours, a font, a radius, an
|
|
304
|
+
order, a hint per ask. No CSS, no URL, no script, ever. A token that fails
|
|
305
|
+
its shape is dropped. Her tokens become the kit's slots on her section and
|
|
306
|
+
nowhere else, her accent the accent there, her ground the raised ground,
|
|
307
|
+
her font the sans, her radius the large corner, and the slots that follow
|
|
308
|
+
from those follow in the stylesheet; so one colour of hers recolours her
|
|
309
|
+
whole section and nothing outside it. The page owns layout and typography;
|
|
310
|
+
a far being paints inside her section and cannot reach out of it.
|
|
311
|
+
- **The shells wear the kit.** One stylesheet, the kit's and then the few
|
|
312
|
+
things only a shell has, served by the daemon beside the bundle and
|
|
313
|
+
carried by the app. A shell's own elements are the kit's pieces too: the
|
|
314
|
+
worlds a device is in are chips on a strip that stays at the top, a
|
|
315
|
+
relation is a chip, leaving and moving are buttons in the kit's variants,
|
|
316
|
+
and the door, the held page and the landing page are one thing on air.
|
|
317
|
+
Nothing a shell paints is a bare element with a rule of its own.
|
|
318
|
+
- **A world is a ward with a public being, and the guest page is her
|
|
319
|
+
describe.** Whatever class she is. The tab knocks the ward's public
|
|
320
|
+
invitation, its pk alone, with the empty ask, and renders what she shows
|
|
321
|
+
strangers with this same screen: the desk shows `hello` and `device`, a
|
|
322
|
+
shop could show its availability, a garden its `enter`. A form on that
|
|
323
|
+
page is a knock on the public invitation, and an answer that is an
|
|
324
|
+
invitation is the way in: the side hands it to `admit`, the avatar joins,
|
|
325
|
+
and the page becomes hers. Nothing in the screen knows the word desk.
|
|
326
|
+
- **Worlds have addresses, and so do the beings one holds.** `web./<ward>`
|
|
327
|
+
is that world's page, `web./` lists the worlds shown, and a hostname per
|
|
328
|
+
world is one proxy line, the estate's choice. Shown is the ward's own
|
|
329
|
+
mark, `quo show` and `quo hide`, hidden at `init`: a hidden ward is not
|
|
330
|
+
listed and a stranger at its page meets the plain door, while a link
|
|
331
|
+
still knocks with its invitation and the desk still answers a proof, so
|
|
332
|
+
an estate shows its face and leaves every home hidden. `quo.` stays one per harbor,
|
|
333
|
+
since bytes route by pk. `web./<ward>/<being>` is the page of one
|
|
334
|
+
standing the user being carries, by its id, as the whole page: her
|
|
335
|
+
section is the page, her title the page's, the shell's own asks and the
|
|
336
|
+
world's tab beings stay on the world's page, and a line at the top leads
|
|
337
|
+
back. No router: the path is a key, the server hands it to the tab as it
|
|
338
|
+
hands the ward's name, and a key her describe does not carry for this
|
|
339
|
+
device paints as nothing, since an address adds no right. Every section
|
|
340
|
+
on the world's page says where its own page is.
|
|
341
|
+
- **A link is the page with the invitation in the fragment**, under the one
|
|
342
|
+
reserved key `quo`, the invitation compact as `ward.heir.secret` or
|
|
343
|
+
`ward` alone: `web.acme.com/shop#quo=...`. The fragment never leaves the
|
|
344
|
+
browser, where a query string would reach the server, its logs and every
|
|
345
|
+
referer. The tab reads it, strips it from the address bar before anything
|
|
346
|
+
else runs, and joins. A page's own routing keeps the query, the path and
|
|
347
|
+
the rest of the fragment; only `quo` is taken. `beings/link.ts`.
|
|
348
|
+
- **An answer that is an invitation paints as the link it is.** The only
|
|
349
|
+
thing to do with one is to open it, and a being does not know where her
|
|
350
|
+
page lives while the side does: the side builds the link on the world's
|
|
351
|
+
page address, which is why the grammar carries no URL and this is not a
|
|
352
|
+
node. It is how devices beget devices on a page: a human asks her user
|
|
353
|
+
being's `device` for the next one and gets back a link to send, the same
|
|
354
|
+
link `quo invite` prints on the box. A side with an `admit` shows a guest
|
|
355
|
+
the door instead, and that is the door alone.
|
|
356
|
+
- **An invitation is self-addressing.** It names its ward by pk, so the
|
|
357
|
+
path of the page it was opened on is a hint for humans and nothing more:
|
|
358
|
+
the tab joins in the local ward of the ward the invitation names, and
|
|
359
|
+
the address follows. `web./#quo=...` is a complete way in for anyone
|
|
360
|
+
holding an invitation to any ward the harbor hosts, and every ward has a
|
|
361
|
+
page, whether or not anyone is at its door, so that a link into one has
|
|
362
|
+
somewhere to land; a ward with no public being says it admits by
|
|
363
|
+
invitation only.
|
|
364
|
+
- **The tab is a browser of worlds, and of the relations in each.** One
|
|
365
|
+
harbor per origin, one local ward per world joined, and inside it one
|
|
366
|
+
avatar per relation, since an avatar is one standing: a fresh invitation
|
|
367
|
+
is always a fresh avatar, never a join on one that already holds hers. A
|
|
368
|
+
link opened while in is one more relation; two humans on one family
|
|
369
|
+
tablet are two relations in one world; a switcher over worlds and
|
|
370
|
+
another over relations, and a switch is a switch of avatar and nothing
|
|
371
|
+
more. A world on another origin is another page, and the switcher links
|
|
372
|
+
there. `worlds.ts` is this without a document, and the memory harbor
|
|
373
|
+
proves it.
|
|
374
|
+
- **The policy.** The page carries a content security policy: scripts from
|
|
375
|
+
its origin only and never inline, connections to its origin and the `quo.`
|
|
376
|
+
route it dials, images from data URIs and its origin, no frames, no base.
|
|
377
|
+
The config crosses in a JSON script, which the policy allows. A bug in a
|
|
378
|
+
renderer cannot become a script, and no look can reach a server.
|
|
379
|
+
|
|
380
|
+
## The pieces
|
|
381
|
+
|
|
382
|
+
Seventeen files under `packages/dock/human/`:
|
|
383
|
+
|
|
384
|
+
- `local.ts` is a being of the world in the tab's own ward as a subject:
|
|
385
|
+
her door spoken to in-process under the tab's asker, no standing.
|
|
386
|
+
|
|
387
|
+
- `tree.ts` is the page grammar and its painter, pure: `sanitiseTree`
|
|
388
|
+
holds a value to the grammar or drops it, `answersIn` names what a tree
|
|
389
|
+
shows the answers of, `paint` writes a tree as HTML through a painter,
|
|
390
|
+
and `nobody` is the painter with nothing behind it.
|
|
391
|
+
- `html.ts` is pure, strings in and strings out, and is the screen's whole
|
|
392
|
+
vocabulary: `form`, `values`, `view`, `face`, `look`, `page`. It reads the
|
|
393
|
+
look's vocabulary from `beings/look.ts` and the grammar from `tree.ts`
|
|
394
|
+
and adds none; its painter looks every name a tree uses up in her
|
|
395
|
+
describe.
|
|
396
|
+
- `screen.ts` is the side: one avatar and one surface, where a surface can
|
|
397
|
+
only show a page and hand back a submitted form. It keeps the model,
|
|
398
|
+
speaks it as a page after every change, calls her when a form comes back,
|
|
399
|
+
re-asks her describe after every call, asks her look once per digest and
|
|
400
|
+
her page after every call, and runs her read-only asks once per digest
|
|
401
|
+
and the ones her page shows the answers of after every call. A push is
|
|
402
|
+
appended and shown as it lands. A
|
|
403
|
+
describe that fails leaves the last page standing and says so in the
|
|
404
|
+
notice.
|
|
405
|
+
- `dom.ts` is the surface on an element, the one file that touches one.
|
|
406
|
+
- `guest.ts` is a world's public being as a subject the screen renders:
|
|
407
|
+
her describe for a stranger, a form as a knock on the public invitation.
|
|
408
|
+
- `worlds.ts` is the worlds and relations of a device with no document in
|
|
409
|
+
sight: the local ward for a far pk, the relations in it, a fresh avatar
|
|
410
|
+
for the next way in, and the list of worlds joined, kept by pk with the
|
|
411
|
+
address each was reached at. A world met again at a new address is the
|
|
412
|
+
same world and keeps its ward, since the pk is what an invitation names.
|
|
413
|
+
- `move.ts` is a world moving from one device to another, the shell half of
|
|
414
|
+
the courier in `beings/courier.ts`: the offer a device makes of a world it
|
|
415
|
+
holds, the invitation and the reach note as one link, and the taking on
|
|
416
|
+
the other side, the ward adopted and the word back that let the first one
|
|
417
|
+
delete it. It is the only place a shell hands a ward over or puts one
|
|
418
|
+
down, and both shells wear it, since a move is a move on any device.
|
|
419
|
+
- `wake.ts` is the device's half of the doorbell, worn by every shell: the
|
|
420
|
+
doorbell this device holds at its bell, what a world is told of it, the
|
|
421
|
+
ear subscribed, what each relation missed drained and landed on its
|
|
422
|
+
avatar, and what the human reads composed from those objects.
|
|
423
|
+
- `worker.ts` is the ear itself, the service worker on a world's origin and
|
|
424
|
+
the one piece of a tab that runs when nothing of the tab is open.
|
|
425
|
+
- `app.ts` is the app's shell, what `tab.ts` is for a page. A tab is on a
|
|
426
|
+
world's own origin and is handed that world by the page it was served; an
|
|
427
|
+
app is one origin of its own, every world is somewhere else, and it
|
|
428
|
+
learns each by one fetch of its address and keeps the list itself. One
|
|
429
|
+
harbor, whichever the terrain has, a ward per world by pk, a switcher
|
|
430
|
+
over them, one world's page at a time, and every world dialed and not
|
|
431
|
+
only the one on screen, since a world reaches a device by the socket the
|
|
432
|
+
device opened. No world's code ever runs in it: an app is a published
|
|
433
|
+
bundle on somebody's phone, and a world that could put code in it would
|
|
434
|
+
be a world that owns the phone. It is the same shell on the phone and on
|
|
435
|
+
the desk, the one screen every Quo app has. What it boots when a world is
|
|
436
|
+
joined is the Presence, the being of that world who lives on this device,
|
|
437
|
+
holding at her birth a standing at every faculty the box lends, so the
|
|
438
|
+
first page a world shows carries them and a world reaches the device by
|
|
439
|
+
asking her.
|
|
440
|
+
|
|
441
|
+
The switcher lists the wards she is in, home first, her memberships
|
|
442
|
+
behind it, and a direct membership she has no home for beside it, each
|
|
443
|
+
by the name the world gave; with one entry there is no switcher. A world
|
|
444
|
+
is a home when the being reached there is her user being, who says so
|
|
445
|
+
with `home` in her describe's notes, and no other being does; the shell
|
|
446
|
+
keeps that beside the address and the name. Its
|
|
447
|
+
last entry is never a world: it is this device, the harbor's dock ward
|
|
448
|
+
with an avatar its root booted there holding a standing at every
|
|
449
|
+
faculty, shown by the ordinary screen where a world's user being would
|
|
450
|
+
stand. That page is where a human sees what the box lends, as forms that
|
|
451
|
+
ask each faculty and show what it answers, a refusal included, the
|
|
452
|
+
worlds this device is in with a way out of each, which drops that local
|
|
453
|
+
ward whole and tells the far world nothing, a way to another device for
|
|
454
|
+
each, which is the Courier's offer, and the one sentence that a reinstall
|
|
455
|
+
starts fresh; a device that has joined no world sees it first.
|
|
456
|
+
It is there because a fresh install otherwise asks for location and
|
|
457
|
+
notifications in its manifest and shows nothing that ever asks for them,
|
|
458
|
+
which is a store reviewer's first question and a human's second.
|
|
459
|
+
|
|
460
|
+
It wears the device's half of the doorbell, `wake.ts`, as the tab does.
|
|
461
|
+
Two things are handed to it beside the harbor, and both are the build's:
|
|
462
|
+
the ear, which answers the token this device is reachable at or null, and
|
|
463
|
+
the bell, its ward's pk and the rendezvous it is reached over. It knows
|
|
464
|
+
there is an ear and never what kind, and where a bell stands is a build's
|
|
465
|
+
business and never a being's.
|
|
466
|
+
|
|
467
|
+
The token goes to a doorbell of this device's own at that bell, and to
|
|
468
|
+
nobody else: a store's token is the same at every world, so a world that
|
|
469
|
+
held one could wake her forever and a rotation would be one write per
|
|
470
|
+
world. What a world is handed is a standing at that doorbell and the
|
|
471
|
+
banner key it seals to, said once, because a standing does not rotate.
|
|
472
|
+
A shell handed no bell holds no doorbell and hands a world nothing, which
|
|
473
|
+
works in every other way. A tab keeps its own endpoint and is untouched:
|
|
474
|
+
a browser endpoint is rung only by whoever holds the VAPID secret the
|
|
475
|
+
subscription was made under, and that secret is the world's own, so it is
|
|
476
|
+
not a credential that travels. Waking asks
|
|
477
|
+
every world what it missed and not only the one on screen: a device is
|
|
478
|
+
woken for whichever world had something to say, and one that drained
|
|
479
|
+
only what it was looking at would leave the rest waiting for a second
|
|
480
|
+
wake that may never come. What the human reads is composed here from the
|
|
481
|
+
objects and never from the ring, which carried nothing, and only when
|
|
482
|
+
nobody was looking, because a page that is open already shows every one
|
|
483
|
+
of them where the push would have landed; showing it is an ask on the
|
|
484
|
+
dock ward's notifications being through the harbor's own pointer, the
|
|
485
|
+
same act on every terrain and no second body for it.
|
|
486
|
+
- `style.ts` is the stylesheet, one for every screen there is: the web
|
|
487
|
+
route serves it beside the tab's bundle and the desk app's window carries
|
|
488
|
+
it in its own. A screen that looked like another product on another
|
|
489
|
+
terrain would be two designs to keep and one of them always behind. It is
|
|
490
|
+
`@nervur-org/ui` and then what the screen alone has, as one string,
|
|
491
|
+
because a screen builds its own page and has nowhere to put a link. The
|
|
492
|
+
kit brings the tokens, a face, the reset and the bare controls, layered;
|
|
493
|
+
the screen's own rules are unlayered and win. Nothing in it names a
|
|
494
|
+
colour: every one is a slot, so a face swapped for another swaps the
|
|
495
|
+
screen with it. A far being's look still sets `--accent`, `--bg`, `--fg`,
|
|
496
|
+
`--font` and `--radius` on her own section, and those five stay her
|
|
497
|
+
vocabulary; the root only defaults each one out of the kit. The page's
|
|
498
|
+
one column is padded by the device's safe-area insets as well as the
|
|
499
|
+
gutter, since an app fills the screen it is on, corners and camera and
|
|
500
|
+
all, and `env()` is zero in a tab and a window.
|
|
501
|
+
- `mark.ts` is the mark, a ring with a gap and a point at its centre, one
|
|
502
|
+
being's voice reaching another's door. The door page wears it, and so
|
|
503
|
+
does every Quo app: `app/icon/build.ts` renders the app icons
|
|
504
|
+
from this one glyph, so a hand-drawn icon can never drift from it.
|
|
505
|
+
- `door.ts` is the door page, pure: what a stranger sees where nothing
|
|
506
|
+
lets them in, Quo's page and not the estate's, asking for nothing,
|
|
507
|
+
written as a tree and painted with nobody behind it.
|
|
508
|
+
- `tab.ts` is the shell: the harbor in the tab, the config, the two
|
|
509
|
+
switchers and the two ways in, and hands one avatar at a time to the
|
|
510
|
+
side.
|
|
511
|
+
- `web.ts` is the web route, mounted under `/web` by every terrain that has
|
|
512
|
+
a front door: the daemon and the edge worker both. It serves the list of
|
|
513
|
+
worlds or the door page at the root, a world's page with its config, the
|
|
514
|
+
bundle of `tab.ts` it is handed, the policy header and the stylesheet. The
|
|
515
|
+
bundle and the service worker's arrive as strings, built once by the dock's
|
|
516
|
+
own build, which emits both beside their source and into `dist/human/` so
|
|
517
|
+
that one path resolves in either tree. The daemon reads the file off its
|
|
518
|
+
disk; a deploy at the edge carries the same bundle as a text module. No
|
|
519
|
+
compiler runs in a server either way. What the
|
|
520
|
+
world keeps beside its wards arrives the same way, through a `Folder` the
|
|
521
|
+
terrain answers: the design it wears, by file name, and its own code for
|
|
522
|
+
the tab, a folder on a disk and rows in an object's storage at the edge.
|
|
523
|
+
It takes a `Request` and answers a `Response`, and a path that
|
|
524
|
+
is not its own it answers nothing to, which is how it declines. So the
|
|
525
|
+
route reads no file, names nothing of Node, and runs wherever a harbor
|
|
526
|
+
does. It
|
|
527
|
+
authenticates nothing and admits nobody; the knock is the tab's. Paths
|
|
528
|
+
it does not take fall through to the exchange pages. The same config
|
|
529
|
+
crosses as JSON to an app, which is not a tab: an app asks a world's
|
|
530
|
+
address for JSON from its own origin and learns the world by that one
|
|
531
|
+
fetch, never the bundle, since its code is its own and a world's code
|
|
532
|
+
never runs on a phone. Only the origins a Quo app's webview speaks from
|
|
533
|
+
are answered, `tauri://localhost` on the desk and Capacitor's two on the
|
|
534
|
+
phone, and only with the config; every other origin asking the same way
|
|
535
|
+
is served the page, because a world's config is not a thing to hand a
|
|
536
|
+
stranger's browser. The fetch is a plain GET asking for JSON, which no
|
|
537
|
+
browser preflights, and the answer says `vary: origin` so that no cache
|
|
538
|
+
hands one origin what another was told. It also serves the two
|
|
539
|
+
association files, `/.well-known/apple-app-site-association` and
|
|
540
|
+
`/.well-known/assetlinks.json`, from `app.json` in the harbor folder: the
|
|
541
|
+
estate names its apps, the file is the hostname's claim that those apps
|
|
542
|
+
may open its links, and a platform verifies it over TLS before it hands
|
|
543
|
+
one over. Every page of the world is claimed but the credential exchange,
|
|
544
|
+
which belongs in the browser that started it. An estate that names no app
|
|
545
|
+
serves neither file, and its links open the tab. The words of the claim
|
|
546
|
+
are `apps.ts`, beside this route and not inside it, because a world's
|
|
547
|
+
route is not the only hostname that says them: an app's own domain says
|
|
548
|
+
the same thing and serves no world at all. Apple's format and Google's
|
|
549
|
+
belong to the platforms and move on the platforms' schedule, so they are
|
|
550
|
+
written once. A claim with nothing in it is no file rather than an empty
|
|
551
|
+
one, since a phone reads the two the same way and only one is honest.
|
|
552
|
+
|
|
553
|
+
Proven in `packages/dock/test/human.test.ts` on the memory harbor with a fake
|
|
554
|
+
surface and no browser, and the DOM surface in the browser terrain: the
|
|
555
|
+
grammar held and painted, the
|
|
556
|
+
user being's page
|
|
557
|
+
with what her gate hides painted as nothing, a being of the world in the
|
|
558
|
+
tab's ward paged from her cells and kept with them, the user being
|
|
559
|
+
carrying a shop with a look, a guest
|
|
560
|
+
at a door that is not a desk let in by a form, the link read, stripped and
|
|
561
|
+
refused, and the worlds and relations on a harbor core over the memory
|
|
562
|
+
store, two invitations into one world being two avatars; and in
|
|
563
|
+
`packages/dock/test/terrain/browser.test.ts` in a real Chromium against a
|
|
564
|
+
daemon on loopback, behind `npm run deep:dock`: the guest page, the
|
|
565
|
+
way in by a link the root minted, a push, a reload, the policy header, a
|
|
566
|
+
link while in as a second relation and the switch back, a link into another
|
|
567
|
+
ward landing on that ward's page, the door page where nobody is at the
|
|
568
|
+
door, and a link at the root; and the app shell in that same browser, two
|
|
569
|
+
worlds on one device with a ward each by pk, a switcher between them, one
|
|
570
|
+
screen, and a push landing while the other world is up, and that same shell
|
|
571
|
+
cold, on a device that has joined nothing, showing the box's own ward with
|
|
572
|
+
a form per faculty and each one answering. The config there
|
|
573
|
+
is handed to the shell rather than fetched, since a world answers its
|
|
574
|
+
config to the app origins alone and a test page is on none of them, which
|
|
575
|
+
is the rule working and is proven where it lives.
|
|
576
|
+
|
|
577
|
+
## Security, by structure
|
|
578
|
+
|
|
579
|
+
- Nothing executable crosses. What a screen receives is I-JSON, by the
|
|
580
|
+
spec: asks, args, answers, the three words, a look and a page. Every string is
|
|
581
|
+
escaped before it is written into the page; a JSON box is parsed and never
|
|
582
|
+
evaluated.
|
|
583
|
+
- A look is a closed vocabulary held to shapes. A logo is a data URI, so no
|
|
584
|
+
request leaves the page towards a far being's server; a colour is a hex
|
|
585
|
+
colour; there is no token for a stylesheet, a URL or a script.
|
|
586
|
+
- The gate is the permission. What a page can ask is what the being shows
|
|
587
|
+
that device, already. No page adds a right, and a form for an ask she does
|
|
588
|
+
not show is nothing.
|
|
589
|
+
- Origin is the boundary. A world's own page runs only on that world's
|
|
590
|
+
origin; on the human's own web only the dock's bundle and the estate's
|
|
591
|
+
classes run. A world can only ever damage itself.
|
|
592
|
+
|
|
593
|
+
## The tab
|
|
594
|
+
|
|
595
|
+
The tab is a device. The page at `web./<ward>` boots a browser harbor on a
|
|
596
|
+
seed minted into the tab's store the first time, one local ward for this
|
|
597
|
+
world with an avatar per relation in it, and dials the world's `quo.`
|
|
598
|
+
route. **Three ways in and there is no fourth**, one act each, each a fresh
|
|
599
|
+
avatar: a link's invitation, joined at once in the ward it names; a proof
|
|
600
|
+
the world sent out itself, `#proof=<kind>.<token>`, which names no ward and
|
|
601
|
+
so is for the world whose page it was opened on, knocked at that world's
|
|
602
|
+
public being and traded there for an invitation; and a guest form on the
|
|
603
|
+
public being's page whose answer is an invitation. Both fragments are read
|
|
604
|
+
and stripped before any other code runs, and for the same reason: a query
|
|
605
|
+
string is in every log and every referer, and one read of either is one way
|
|
606
|
+
in taken.
|
|
607
|
+
|
|
608
|
+
**What a proof is worth is the way in's word and never the desk's.** The
|
|
609
|
+
desk routes a proof by its kind to the being who verifies that kind, and
|
|
610
|
+
she says who it is for, how far she may go, whether a user being is made
|
|
611
|
+
for her, and whether the same proof may be spent again. So a refusal here
|
|
612
|
+
is hers: a token she will not take, or a kind she holds no way in for, and
|
|
613
|
+
either leaves the human at the door with nothing taken and one line saying
|
|
614
|
+
so. A proof that names a client already in the world is refused by that,
|
|
615
|
+
so opening the same handed-out link twice is not a second relation.
|
|
616
|
+
|
|
617
|
+
**A public being is any class, and two of the three ways in ask nothing of
|
|
618
|
+
it.** A ward's public being is an ordinary being the owner marked, and the
|
|
619
|
+
screen renders whatever asks she has: a guest form is the way in when its
|
|
620
|
+
answer is an invitation, and she may call that ask anything, since what
|
|
621
|
+
makes it a way in is the answer and not the name. A link's invitation names
|
|
622
|
+
its own ward and needs her not at all.
|
|
623
|
+
|
|
624
|
+
The proof is the exception, and the reason is that a proof arrives in a
|
|
625
|
+
fragment rather than typed. There is no form to answer, so the shell hands
|
|
626
|
+
it to a named ask, and that name is `device`: a convention of the dock's
|
|
627
|
+
like `hello`, `look` and `page`. A public being of any class takes proofs by
|
|
628
|
+
writing that ask, and one that writes none has no proof way in and loses
|
|
629
|
+
nothing else.
|
|
630
|
+
|
|
631
|
+
**What a kind is, and what carries it, is the org's and never the dock's.**
|
|
632
|
+
A kind is a word an org chose, and a way in is a being it wrote or took
|
|
633
|
+
from somewhere. Mail, a message, a code on a screen, a letter, a voice on
|
|
634
|
+
a call, a sign-in a person already holds elsewhere: each of them is one
|
|
635
|
+
kind, and the dock knows the name of none of them. A way in that hands its
|
|
636
|
+
proof out itself says so, and one that only verifies a proof arriving from
|
|
637
|
+
elsewhere says nothing and stands at no door. Nothing in the dock, in the
|
|
638
|
+
screen or in the app is written for a channel, and an org that builds a
|
|
639
|
+
way in nobody here imagined adds a being and a knock and changes no other
|
|
640
|
+
line.
|
|
641
|
+
|
|
642
|
+
Nothing is typed to get in, no password and no account, the root included:
|
|
643
|
+
the root mints its own first invitation on the box and opens the link. A
|
|
644
|
+
ward with nobody at its door shows the door page, `door.ts`, and a link is
|
|
645
|
+
the only way. From then on there is no
|
|
646
|
+
cookie and no token anywhere, and a reload asks nothing: the seed and the
|
|
647
|
+
standings are in the tab's store, and the relation last on screen is the
|
|
648
|
+
one shown.
|
|
649
|
+
|
|
650
|
+
## Leaving a world, and being let go
|
|
651
|
+
|
|
652
|
+
A relation ends from either side, and the two ends are not the same act.
|
|
653
|
+
|
|
654
|
+
- **A human leaves, and it is one press.** What a device holds of a world
|
|
655
|
+
is one local ward, and every standing won there is in it, so leaving is
|
|
656
|
+
that ward dropped whole, seed and all, and the world forgotten from the
|
|
657
|
+
list. The far world is never asked and never told: it sees one device
|
|
658
|
+
gone, exactly as it sees a phone that fell in a river. Every shell has
|
|
659
|
+
this, a tab and an app alike, because a device a human cannot leave is
|
|
660
|
+
not a device.
|
|
661
|
+
- **A world lets her go**, by removing the standing at its own side. Her
|
|
662
|
+
next describe says so, and the screen reads the words apart rather than
|
|
663
|
+
painting one line for every failure. `removed` and `dropped`, and
|
|
664
|
+
holding no standing at all, are the relation ended: nothing this device
|
|
665
|
+
does brings it back and the only act left is leaving. `unreached`,
|
|
666
|
+
`silence`, `late` and `absent` are the world being away: the standing is
|
|
667
|
+
untouched and the next ask may well answer. Anything else she said is
|
|
668
|
+
her own error, shown as her words. The notice carries which of the four
|
|
669
|
+
it is, so a design and a reader tell them apart without parsing a
|
|
670
|
+
sentence.
|
|
671
|
+
- **A device never drops a world by itself.** An ended relation is one
|
|
672
|
+
answer from one ask at one moment, and there is nothing to confirm it
|
|
673
|
+
against, because the far world is never told and never asked. A device
|
|
674
|
+
that forgot a world on that alone would delete a ward holding a seed and
|
|
675
|
+
every standing in it on the strength of one reply. So the side tells the
|
|
676
|
+
shell, on every describe that says it, the shell puts the way out in
|
|
677
|
+
front of the human, and she presses it or does not. It is said again
|
|
678
|
+
rather than once because the shell decides what to do with it and a
|
|
679
|
+
shell that missed the first one would never hear another. Keeping a dead
|
|
680
|
+
world costs a stale row; dropping a live one costs a ward nothing can
|
|
681
|
+
recover.
|
|
682
|
+
|
|
683
|
+
## A tab and an app are one screen and two devices
|
|
684
|
+
|
|
685
|
+
Everything a human sees is the same screen over the same surface, and
|
|
686
|
+
whichever she opened it in is a harbor of the org's holding presence wards.
|
|
687
|
+
Four things differ, none of them cosmetic, and a human meets all four.
|
|
688
|
+
|
|
689
|
+
- **A tab runs a world's own code, and an app never does.** A tab is a
|
|
690
|
+
page on that world's origin, already running the bundle that world
|
|
691
|
+
serves, so a world may ship beings that live in the tab's own ward,
|
|
692
|
+
`local.ts`: her cells are in the tab's store, her asks are the forms,
|
|
693
|
+
her page is computed at every digest by the same painter a far being
|
|
694
|
+
gets. An app is a published bundle on somebody's phone, and a world that
|
|
695
|
+
could put code in it would be a world that owns the phone, so every
|
|
696
|
+
world it meets is a local ward of built-in classes and nothing else. The
|
|
697
|
+
consequence is a human's: **the same link can show more in a tab than in
|
|
698
|
+
the app**, and the difference is the world's doing, not the device's.
|
|
699
|
+
- **An app lends, and a bare tab lends nothing.** The app's harbor stands
|
|
700
|
+
a ward of its own with the box's faculties in it, and the being of each
|
|
701
|
+
world on that device holds a standing at every one from her birth. A tab
|
|
702
|
+
stands none, because what a page may ask a browser for is the browser's
|
|
703
|
+
to gate and there is nothing of its own to lend. Which of a presence
|
|
704
|
+
being's asks a shell draws as forms is which standings she holds, so the
|
|
705
|
+
same being shows two forms on a phone and none in a tab, and neither is
|
|
706
|
+
a lie.
|
|
707
|
+
- **A tab's harbor is one origin's, and an app's is the device's.** A tab
|
|
708
|
+
boots its harbor on a seed in that origin's store, so worlds served from
|
|
709
|
+
one `web.` host share a device and worlds on another host are a
|
|
710
|
+
different device with a different seed. An app is one harbor for the
|
|
711
|
+
whole device. So a person with a shop, a club and a friend on three
|
|
712
|
+
origins is three devices in a browser and one device in the app, and
|
|
713
|
+
seeing all her worlds in one place is the app's sentence and cannot be
|
|
714
|
+
borrowed by a tab.
|
|
715
|
+
- **A seed in a tab is shorter-lived**, and that is the whole of the rest
|
|
716
|
+
of the difference. Cleared site data ends a presence exactly as a lost
|
|
717
|
+
phone does.
|
|
718
|
+
|
|
719
|
+
So a phone without the app opens the tab, which is the rented room and says
|
|
720
|
+
so. A tab is how a human arrives, since it costs nothing and needs no
|
|
721
|
+
store; the app is how she stays.
|
|
722
|
+
|
|
723
|
+
## The pages Quo writes itself
|
|
724
|
+
|
|
725
|
+
Almost every page here is a being's: her describe becomes the forms, her
|
|
726
|
+
`page` becomes the tree, and no world writes HTML. Two pages are nobody's
|
|
727
|
+
being, and they are written out by hand.
|
|
728
|
+
|
|
729
|
+
**A page with no being cannot be a blueprint, and that is what decides
|
|
730
|
+
it.** The screen paints a describe through a standing. At the door there is
|
|
731
|
+
no standing, and at the credential exchange there is neither: the human is
|
|
732
|
+
a stranger holding nothing, and the world she is about to let something
|
|
733
|
+
into is named by an invitation she has not typed yet. The grammar cannot
|
|
734
|
+
say either page either, because its `form` node is one of a being's asks by
|
|
735
|
+
name, and these forms are nobody's ask. So the rule is not a preference for
|
|
736
|
+
hand-writing. It is that the claim "no world writes a page" is about
|
|
737
|
+
**worlds**, and these two pages are Quo's own.
|
|
738
|
+
|
|
739
|
+
- **The door page** is written in the grammar and painted with nobody
|
|
740
|
+
behind it, since inside a tab the painter is already there. So is the
|
|
741
|
+
held page, which is what a human sees where this browser holds the
|
|
742
|
+
harbor in another tab: a device is one harbor, two over one seed would
|
|
743
|
+
be two devices each writing the other's wards, and the second tab is a
|
|
744
|
+
page rather than a device. It says which of the two it is, and that
|
|
745
|
+
nothing is lost either way, because what a device is in every world is
|
|
746
|
+
kept in the browser and not in a tab. It offers nothing that takes the
|
|
747
|
+
lock, since the tab holding it may be the one she is working in.
|
|
748
|
+
- **The allow page** is written out, since it is served on the web route by
|
|
749
|
+
whichever terrain mounts it, with no harbor and no ward anywhere near it.
|
|
750
|
+
- **The landing page** is in the grammar, and it is where a redirect comes
|
|
751
|
+
back. A vendor a world sent a human to returns her by opening a URL in
|
|
752
|
+
her browser, and that URL is the envoy's own door: the same ask in the
|
|
753
|
+
envoy always had, with an empty body and the code in the query. So the
|
|
754
|
+
api road, which is a road for programs, has exactly one human arrival,
|
|
755
|
+
and it is a person who has just paid for something. She is told which of
|
|
756
|
+
the two happened and offered the world's own page, since a tab a vendor
|
|
757
|
+
opened has no history to go back through. What the envoy answered is
|
|
758
|
+
never shown, because `{ ok }` is a sentence for a machine. A vendor
|
|
759
|
+
asking that same path for JSON is answered in JSON as it always was: the
|
|
760
|
+
page is for whoever asked for a page.
|
|
761
|
+
|
|
762
|
+
**Neither dresses itself.** Both wear the one stylesheet every screen
|
|
763
|
+
wears, so a design that swaps the face swaps them too, and there is no
|
|
764
|
+
second look in the tree to drift from the first. A page of Quo's that
|
|
765
|
+
minted its own colours would be the one page an adopter could not make
|
|
766
|
+
theirs.
|
|
767
|
+
|
|
768
|
+
**What the allow page says is what a human needs in order to decide**, and
|
|
769
|
+
nothing that merely reassures her. Who is asking. That it will be an
|
|
770
|
+
occupant under a name she gives it. That it sees exactly what that world
|
|
771
|
+
shows that name, decided by the gate and by nothing it can ask for. That it
|
|
772
|
+
cannot become something else later and can be taken out at any time. That
|
|
773
|
+
the invitation is the whole credential, spent once, with nothing stored
|
|
774
|
+
afterwards: no password, no cookie, no session. Where it returns to when
|
|
775
|
+
she is done. And the sentence that matters most to the human this page will
|
|
776
|
+
one day fail: if she did not mint that invitation for that client herself,
|
|
777
|
+
she should close the page.
|
|
778
|
+
|
|
779
|
+
**All four are served under one policy**, wherever they are served from,
|
|
780
|
+
and it is as tight as they are. They run no script and want none, so
|
|
781
|
+
nothing but their own form is allowed anywhere, an image is the mark and
|
|
782
|
+
therefore data, and no referer carries what brought a human there off the
|
|
783
|
+
page. They also print no address a caller gave them: what a page says about
|
|
784
|
+
where it is comes from what the daemon was configured with, since a `Host`
|
|
785
|
+
header is the caller's to write and a page that printed one would print
|
|
786
|
+
whatever a caller wanted a human to read.
|
|
787
|
+
|
|
788
|
+
## A device is lost
|
|
789
|
+
|
|
790
|
+
A presence is a seed. The seed is in that device's store and nowhere else,
|
|
791
|
+
so a phone that is stolen, a laptop that dies and a tab whose site data was
|
|
792
|
+
cleared are one event, and what it costs is the same each time: that
|
|
793
|
+
device's local ward, the avatars in it, and every standing they held. There
|
|
794
|
+
is no copy anywhere, because a copy of a seed is a second device holding the
|
|
795
|
+
org's standings, which is the thing the whole shape exists to prevent. So
|
|
796
|
+
this is said plainly rather than softened: **a lost device is not
|
|
797
|
+
recovered. It is replaced.**
|
|
798
|
+
|
|
799
|
+
What survives is everything else. Nothing of the org is at risk, because
|
|
800
|
+
the org is at home and this was one of its devices. Every world the lost
|
|
801
|
+
device was in still knows her, since a membership is an id in that world's
|
|
802
|
+
ward and lives there. The standings the device held at those worlds are
|
|
803
|
+
still standing at their far ends: what is gone is the key on this side.
|
|
804
|
+
|
|
805
|
+
So coming back is two acts, and the order does not matter.
|
|
806
|
+
|
|
807
|
+
- **The lost device is taken out.** That is one standing removed, exactly
|
|
808
|
+
as it is for a device simply stopped being used, and it is the only
|
|
809
|
+
thing that makes the lost device's key useless to whoever holds it.
|
|
810
|
+
Until it happens the world cannot tell a stolen phone from a quiet one.
|
|
811
|
+
A device the world granted `revoke` does it in one act, and the screen
|
|
812
|
+
shows her the form because her gate does; `revoke` is its own word and
|
|
813
|
+
never `mint`'s, so a device that brings in the next device does not by
|
|
814
|
+
that fact take one out. Where the world granted it to nobody, the root
|
|
815
|
+
removes the two relations a device is, and a human whose home is on a
|
|
816
|
+
box she does not run asks whoever runs it.
|
|
817
|
+
- **She comes back as a new device.** Either by an invitation minted from
|
|
818
|
+
a device she still holds, which is the ordinary way one device brings in
|
|
819
|
+
the next, or by that world's own way in again, which is what she has
|
|
820
|
+
when the lost device was her only one there. Whether that returns her to
|
|
821
|
+
the being she was is the world's answer and not hers: a way in that
|
|
822
|
+
identifies a person hands her the same user being, and one that
|
|
823
|
+
identifies a device hands her a new one.
|
|
824
|
+
|
|
825
|
+
**A device is named, and a name is taken.** The world holds the lost
|
|
826
|
+
device's standing under the name that device was given, so coming back
|
|
827
|
+
under that same name is refused while it stands, `id taken`. That refusal
|
|
828
|
+
is what a human actually meets after losing her only device, and a screen
|
|
829
|
+
must say what it is rather than that the way in was spent: the two send her
|
|
830
|
+
looking for different things, and only one of them has an answer. An org
|
|
831
|
+
building a way in that hands every person a single fixed device name gives
|
|
832
|
+
each of them exactly one device for life, and this is the paragraph that
|
|
833
|
+
says so before the first person loses a phone.
|
|
834
|
+
|
|
835
|
+
## The tab's ear
|
|
836
|
+
|
|
837
|
+
A tab that is closed hears nothing, and that is what the doorbell in
|
|
838
|
+
`papers/quo-dock.md` is for. Its ear here is a service worker, `worker.ts`,
|
|
839
|
+
served by the web route at the root of this route so its scope covers every
|
|
840
|
+
world page on that origin, with the world's config written above the bundle
|
|
841
|
+
since a worker has no page to be handed a JSON script in. A world that
|
|
842
|
+
holds no bell key serves no worker and its pages register none, and the
|
|
843
|
+
page's policy names `worker-src 'self'`, which otherwise falls back to
|
|
844
|
+
`default-src` and is none.
|
|
845
|
+
|
|
846
|
+
A device is one harbor and the lock says who holds it, so the worker is one
|
|
847
|
+
more claimant of the same lock. With a page open the page holds it: the
|
|
848
|
+
worker hands that page a port, the page tells its dialers it is back,
|
|
849
|
+
drains and answers, and the worker shows what came. With no page open the
|
|
850
|
+
worker boots the harbor over the same database for the length of the wake,
|
|
851
|
+
dials the world, drains and closes both behind itself. A boot that meets
|
|
852
|
+
the lock is a page that holds it and did not answer, and the worker leaves
|
|
853
|
+
it alone rather than opening a second harbor over one seed.
|
|
854
|
+
|
|
855
|
+
`wake.ts` is the device's half and every shell wears it: `subscribe`
|
|
856
|
+
registers the ear and asks the browser's push service for an endpoint,
|
|
857
|
+
`drained` is the ask on each relation and the objects landing on each
|
|
858
|
+
avatar where a push would have landed, and `notice` composes what the human
|
|
859
|
+
reads from those objects and from nothing else. A tab drains on entry too,
|
|
860
|
+
since a device coming back is a device that missed something. Being woken
|
|
861
|
+
is asked for and never sprung: a page that asks a browser for notifications
|
|
862
|
+
the moment it opens is a page every browser punishes, so a human who has
|
|
863
|
+
not been asked is offered a button.
|
|
864
|
+
|
|
865
|
+
Two things a browser terrain teaches, held here because a reader would
|
|
866
|
+
otherwise spend an afternoon on them. A Chromium driven for a test can
|
|
867
|
+
never subscribe: its contexts are private ones, and Chrome disables the
|
|
868
|
+
Push API in a private context outright, with no way to feature-detect it.
|
|
869
|
+
And that build shows no notification either, `showNotification` answering
|
|
870
|
+
neither way. So the terrain proves the ring, the wake, the dial and the
|
|
871
|
+
drain, `notice` is proven as a unit, and the platform call is the one line
|
|
872
|
+
no Chromium there runs. Every step of a wake is bounded for the same
|
|
873
|
+
reason: a platform that answers neither way must not hold a worker open.
|
|
874
|
+
|
|
875
|
+
## The same link, and the app
|
|
876
|
+
|
|
877
|
+
One link does both. A join link is a world's page with the invitation in
|
|
878
|
+
its fragment, and where the app is installed the platform opens it there
|
|
879
|
+
instead of the browser, on the same address and with the same fragment.
|
|
880
|
+
Nothing of the invitation reaches any server on the way: a fragment is not
|
|
881
|
+
sent, so the world's own host never sees it either, and the app reads it
|
|
882
|
+
from the URL the platform hands over, once as the URL it was launched by
|
|
883
|
+
and again for every link opened while it runs. A phone without the app
|
|
884
|
+
opens the tab, which is the rented room and says so.
|
|
885
|
+
|
|
886
|
+
What makes the platform open the app is the association file the world's
|
|
887
|
+
own hostname serves, `web.ts` above, naming the app that may claim it, and
|
|
888
|
+
the app naming that hostname back, in the iOS entitlements and in the
|
|
889
|
+
Android manifest. Both halves are verified by the platform and neither is
|
|
890
|
+
Quo's word for anything. So the domain in a join link is the world's, never
|
|
891
|
+
an app publisher's, and no third party stands between a world and the
|
|
892
|
+
device it invited: whoever wants their own name on the store builds the
|
|
893
|
+
same shell with their own app id and their own hostname, one line on each
|
|
894
|
+
side. A custom scheme is claimed by nobody here, since any app may claim
|
|
895
|
+
any scheme and a link on one would hand an invitation to whoever squats it.
|
|
896
|
+
|
|
897
|
+
## What binds, and what we merely chose
|
|
898
|
+
|
|
899
|
+
Everything above is written as though it were one thing, and it is two. Some
|
|
900
|
+
of it a human side must do or it is not speaking Quo, and the protocol or
|
|
901
|
+
the world Quo proposes is what makes it so. The rest is this kit's answer,
|
|
902
|
+
worked out here, and another front end may throw it away and be no less
|
|
903
|
+
Quo for it. A reader who cannot tell those apart is holding a cage rather
|
|
904
|
+
than a kit, so here is the line.
|
|
905
|
+
|
|
906
|
+
### The rules
|
|
907
|
+
|
|
908
|
+
Break one of these and the thing stops being a Quo world's human side,
|
|
909
|
+
whatever else it does well.
|
|
910
|
+
|
|
911
|
+
- **Three ways in and no fourth**, and nothing is typed on any of them: an
|
|
912
|
+
invitation in a link's fragment, a proof the world handed out, or a form
|
|
913
|
+
whose answer is an invitation. No password, no account, no cookie.
|
|
914
|
+
- **A capability rides in a fragment, never a query.** A query string is in
|
|
915
|
+
every log and every referer, and one read of an invitation or a proof is
|
|
916
|
+
one way in taken.
|
|
917
|
+
- **A page adds no right.** Every name a page uses is looked up in the
|
|
918
|
+
describe for this asker; a name the gate hid paints as nothing. The gate
|
|
919
|
+
is the whole of permission and there is no second list.
|
|
920
|
+
- **A far being cannot reach out of her page.** No script, no stylesheet,
|
|
921
|
+
no selector, an image that is data and not a fetch, and an address only
|
|
922
|
+
where she already stands.
|
|
923
|
+
- **A being knows no routes.** Where her pages live is the side's, so an
|
|
924
|
+
invitation she answers becomes a link on the side and never in her.
|
|
925
|
+
- **A device is one harbor.** Two over one seed would be two devices each
|
|
926
|
+
writing the other's wards, so the second is a page and says so.
|
|
927
|
+
- **A presence is a seed.** A device is replaced and never recovered, and a
|
|
928
|
+
human is told that plainly rather than promised a recovery there is not.
|
|
929
|
+
- **A relation ends from either side**, and a device never drops a world on
|
|
930
|
+
one answer at one moment, since the far world is never told and can never
|
|
931
|
+
confirm it.
|
|
932
|
+
- **A world moves whole between devices**, seed and standings, and the far
|
|
933
|
+
world is never asked and never told.
|
|
934
|
+
- **Consent is a human act.** A model or a program asking to be let into a
|
|
935
|
+
world is answered by a person and by nothing else.
|
|
936
|
+
- **A published app never runs a world's code.** A world that could put
|
|
937
|
+
code in somebody's app would be a world that owns their phone.
|
|
938
|
+
- **The screen adds no vocabulary.** What a being can be asked is her
|
|
939
|
+
blueprint, how she is shown is her look and her page, and there is no
|
|
940
|
+
third thing.
|
|
941
|
+
- **A route says the grammar and never the rung.** The same identity sees
|
|
942
|
+
the same describe whether it arrived as forms, as tools or as JSON.
|
|
943
|
+
|
|
944
|
+
### The offers
|
|
945
|
+
|
|
946
|
+
Every one of these is a decision made here. An adopter building on this kit
|
|
947
|
+
follows them because they are how this kit is shaped; an adopter writing
|
|
948
|
+
their own front end may answer differently at every line and interoperate
|
|
949
|
+
with us at every door, because a door judges keys and not opinions.
|
|
950
|
+
|
|
951
|
+
- **The page grammar**, its node kinds and their names. The property it
|
|
952
|
+
protects is a rule; these eight words are ours.
|
|
953
|
+
- **Forms from an input schema**, a view from an output schema, and what
|
|
954
|
+
each type is drawn as.
|
|
955
|
+
- **The door page and the held page**, their words and their shape. A world
|
|
956
|
+
that wants a face of its own has a public being with a page and a look,
|
|
957
|
+
or its own page on its own origin.
|
|
958
|
+
- **The allow page being written out rather than painted**, and every
|
|
959
|
+
sentence on it.
|
|
960
|
+
- **`device` as the ask a proof is handed to.** A name is needed because a
|
|
961
|
+
proof arrives carried rather than typed, and this is the name we chose.
|
|
962
|
+
- **The words a device may be granted**, `wake`, `reach`, `mint` and
|
|
963
|
+
`revoke`, and the notes that carry them.
|
|
964
|
+
- **`stands`**, and vouching for an address by the origins a being
|
|
965
|
+
declared.
|
|
966
|
+
- **One stylesheet for every screen**, and a design that swaps the face
|
|
967
|
+
swapping all of them.
|
|
968
|
+
- **The shell**, Capacitor on a phone and Tauri on a desk, and the app
|
|
969
|
+
being a browser of worlds with no account of its own.
|
|
970
|
+
|
|
971
|
+
## Where the tree stands
|
|
972
|
+
|
|
973
|
+
The chapters above say what this side answers for. Some of it stands with
|
|
974
|
+
code, a proof and these words behind it, and some of it stands with less.
|
|
975
|
+
This chapter is where the difference is admitted, so that a reader building
|
|
976
|
+
against this paper knows which sentences are load-bearing.
|
|
977
|
+
|
|
978
|
+
**The shells' own ways in.** Each of the three is proven as the act it is,
|
|
979
|
+
from the fragment a world handed out to the standing taken. What has no
|
|
980
|
+
assertion of its own is the tab reading its own address on the first paint
|
|
981
|
+
and the app reading the URL the platform handed it, which the browser
|
|
982
|
+
terrain suite exercises through a link and not through a proof.
|
|
983
|
+
|
|
984
|
+
**A link a human is shown before she goes.** A being's `stands` is a
|
|
985
|
+
standing claim, and the screen paints the origin on the anchor, so the
|
|
986
|
+
address is on the page. Whether a human should also be told the first time
|
|
987
|
+
a world sends her somewhere it does not serve, rather than only shown, is
|
|
988
|
+
undecided.
|
|
989
|
+
|
|
990
|
+
**Authorizing.** The exchange is proven and so is what the page says. What
|
|
991
|
+
no assertion holds is the page in a real browser: it is served by the
|
|
992
|
+
daemon and read by no terrain suite, so its layout under the kit's
|
|
993
|
+
stylesheet is unproven at every width.
|
|
994
|
+
|
|
995
|
+
**The pages Quo writes itself.** Each holds to the grammar and says what it
|
|
996
|
+
says, proven with no browser, and the landing page is proven over real HTTP
|
|
997
|
+
besides. None of the four is ever loaded in one: the held page in
|
|
998
|
+
particular is reached only by a second tab meeting the lock, and what the
|
|
999
|
+
terrain suite proves there is the harbor refusing to boot rather than the
|
|
1000
|
+
page that refusal puts up.
|
|
1001
|
+
|
|
1002
|
+
**Leaving.** A human leaving and a world letting her go are both moments
|
|
1003
|
+
here, and the browser terrain suite exercises neither: the words told apart
|
|
1004
|
+
and the side telling the shell are proven with no browser, and the button
|
|
1005
|
+
each shell puts up is not.
|
|
1006
|
+
|
|
1007
|
+
**A device lost.** What it costs and how she comes back are written above.
|
|
1008
|
+
The act, the list and the form are all here, so a device the world granted
|
|
1009
|
+
`revoke` sees her devices by name, which one she is on, and the form that
|
|
1010
|
+
takes one out. What is unproven is the shell: the user being's page carries
|
|
1011
|
+
all three and no terrain suite presses them in a browser.
|
|
1012
|
+
|
|
1013
|
+
**The public front.** A website is not a route into any box: it reaches its
|
|
1014
|
+
world by origins it names once, and what it needs to speak Quo is a browser
|
|
1015
|
+
harbor in the page taking a stranger's standing at that world's public
|
|
1016
|
+
being, which is this package's shape rather than a website's. Nothing here
|
|
1017
|
+
offers it, because one site has written it and a piece with one user stays
|
|
1018
|
+
with that user until the second arrives.
|
|
1019
|
+
|
|
1020
|
+
**A home arriving.** The act is two halves of an ordinary knock and both
|
|
1021
|
+
are here, so the day costs a human two forms and no migration. What no
|
|
1022
|
+
screen does is walk her through it: she meets `join` as one form among
|
|
1023
|
+
others, and nothing offers to take her memberships one at a time from the
|
|
1024
|
+
device that holds them.
|
|
1025
|
+
|
|
1026
|
+
**One device, two people.** Two people sharing a device are two relations
|
|
1027
|
+
in one world, one avatar each, since an invitation is self-addressing and a
|
|
1028
|
+
fresh one is always a fresh avatar. It runs, it is proven, and no screen
|
|
1029
|
+
names the second person: the relations switcher shows keys, so a household
|
|
1030
|
+
tablet says `r1` and `r2` where it should say who.
|
|
1031
|
+
|
|
1032
|
+
**What a device lends** is one form away and proven once in a real browser.
|
|
1033
|
+
What no assertion holds is the phone's own refusal path: that a faculty
|
|
1034
|
+
whose permission was declined answers the same error object at every ask
|
|
1035
|
+
after, rather than prompting again, is written and exercised by nobody,
|
|
1036
|
+
since a driven simulator grants and declines nothing.
|
|
1037
|
+
|
|
1038
|
+
**A world's own code** is a rule above, and it is proven from the app's
|
|
1039
|
+
side: the app learns a world by one fetch of its config and never loads its
|
|
1040
|
+
bundle. What nothing holds is the tab's side of the same rule, that a
|
|
1041
|
+
world's beings run only in a ward of the tab's own and reach nothing of
|
|
1042
|
+
another world's.
|