nervur 0.23.0 → 0.24.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/CONTRIBUTING.md +13 -0
- package/LICENSE +55 -202
- package/NOTICE +3 -8
- package/README.md +14 -156
- package/RELEASING.md +15 -0
- package/SECURITY.md +9 -0
- package/bin/nervur.js +6 -0
- package/package.json +26 -81
- package/AUTHORING.md +0 -935
- package/COMMAND.md +0 -179
- package/FACES.md +0 -280
- package/FACULTIES.md +0 -578
- package/GROUNDS.md +0 -315
- package/KIT-SPEC.md +0 -304
- package/WORLD.md +0 -195
- package/dist/app/app-ground.d.ts +0 -18
- package/dist/app/app-ground.js +0 -23
- package/dist/app/index.d.ts +0 -2
- package/dist/app/index.js +0 -5
- package/dist/app/native.d.ts +0 -11
- package/dist/app/native.js +0 -13
- package/dist/being/being.d.ts +0 -306
- package/dist/being/being.js +0 -20
- package/dist/being/covers.d.ts +0 -9
- package/dist/being/covers.js +0 -21
- package/dist/being/index.d.ts +0 -4
- package/dist/being/index.js +0 -6
- package/dist/being/need.d.ts +0 -49
- package/dist/being/need.js +0 -33
- package/dist/being/schema.d.ts +0 -100
- package/dist/being/schema.js +0 -132
- package/dist/being/table.d.ts +0 -48
- package/dist/being/table.js +0 -344
- package/dist/bench/bench-ground.d.ts +0 -73
- package/dist/bench/bench-ground.js +0 -153
- package/dist/bench/bench.d.ts +0 -101
- package/dist/bench/bench.js +0 -368
- package/dist/bench/fake-clock.d.ts +0 -17
- package/dist/bench/fake-clock.js +0 -34
- package/dist/bench/fake-memory.d.ts +0 -16
- package/dist/bench/fake-memory.js +0 -46
- package/dist/bench/fake-network.d.ts +0 -66
- package/dist/bench/fake-network.js +0 -222
- package/dist/bench/fake-unlock.d.ts +0 -6
- package/dist/bench/fake-unlock.js +0 -10
- package/dist/bench/index.d.ts +0 -3
- package/dist/bench/index.js +0 -5
- package/dist/bench/seeded.d.ts +0 -11
- package/dist/bench/seeded.js +0 -37
- package/dist/bench/settle.d.ts +0 -2
- package/dist/bench/settle.js +0 -49
- package/dist/bench/stewards.d.ts +0 -169
- package/dist/bench/stewards.js +0 -128
- package/dist/bodies/class-list.d.ts +0 -14
- package/dist/bodies/class-list.js +0 -33
- package/dist/bodies/joined-carry.d.ts +0 -29
- package/dist/bodies/joined-carry.js +0 -48
- package/dist/bodies/kept.d.ts +0 -44
- package/dist/bodies/kept.js +0 -91
- package/dist/bodies/noble-crypto.d.ts +0 -22
- package/dist/bodies/noble-crypto.js +0 -88
- package/dist/bodies/seed-keys.d.ts +0 -10
- package/dist/bodies/seed-keys.js +0 -42
- package/dist/bodies/strict-tools.d.ts +0 -10
- package/dist/bodies/strict-tools.js +0 -306
- package/dist/bodies/vouch.d.ts +0 -20
- package/dist/bodies/vouch.js +0 -71
- package/dist/bodies/web-carry.d.ts +0 -72
- package/dist/bodies/web-carry.js +0 -245
- package/dist/bodies/web-clock.d.ts +0 -12
- package/dist/bodies/web-clock.js +0 -33
- package/dist/browser/browser-ground.d.ts +0 -76
- package/dist/browser/browser-ground.js +0 -294
- package/dist/browser/index.d.ts +0 -4
- package/dist/browser/index.js +0 -7
- package/dist/browser/indexeddb-memory.d.ts +0 -17
- package/dist/browser/indexeddb-memory.js +0 -97
- package/dist/browser/locked-unlock.d.ts +0 -24
- package/dist/browser/locked-unlock.js +0 -85
- package/dist/browser/origin-classes.d.ts +0 -7
- package/dist/browser/origin-classes.js +0 -31
- package/dist/edge/durable-clock.d.ts +0 -19
- package/dist/edge/durable-clock.js +0 -61
- package/dist/edge/durable-memory.d.ts +0 -5
- package/dist/edge/durable-memory.js +0 -11
- package/dist/edge/durable.d.ts +0 -18
- package/dist/edge/durable.js +0 -24
- package/dist/edge/edge-ground.d.ts +0 -49
- package/dist/edge/edge-ground.js +0 -223
- package/dist/edge/index.d.ts +0 -7
- package/dist/edge/index.js +0 -9
- package/dist/edge/native-crypto.d.ts +0 -8
- package/dist/edge/native-crypto.js +0 -102
- package/dist/edge/secret-unlock.d.ts +0 -7
- package/dist/edge/secret-unlock.js +0 -13
- package/dist/edge/socket-carry.d.ts +0 -39
- package/dist/edge/socket-carry.js +0 -111
- package/dist/foundation.d.ts +0 -162
- package/dist/foundation.js +0 -4
- package/dist/ground/dock.d.ts +0 -1460
- package/dist/ground/dock.js +0 -1159
- package/dist/ground/ground.d.ts +0 -239
- package/dist/ground/ground.js +0 -787
- package/dist/ground/views.d.ts +0 -76
- package/dist/ground/views.js +0 -208
- package/dist/house/crossing.d.ts +0 -50
- package/dist/house/crossing.js +0 -153
- package/dist/house/house.d.ts +0 -88
- package/dist/house/house.js +0 -2069
- package/dist/house/rows-shape.d.ts +0 -110
- package/dist/house/rows-shape.js +0 -12
- package/dist/house/rows.d.ts +0 -27
- package/dist/house/rows.js +0 -185
- package/dist/index.d.ts +0 -33
- package/dist/index.js +0 -29
- package/dist/node/bridge.d.ts +0 -20
- package/dist/node/bridge.js +0 -284
- package/dist/node/cli.d.ts +0 -2
- package/dist/node/cli.js +0 -225
- package/dist/node/file-memory.d.ts +0 -13
- package/dist/node/file-memory.js +0 -86
- package/dist/node/folder-classes.d.ts +0 -5
- package/dist/node/folder-classes.js +0 -40
- package/dist/node/gone.d.ts +0 -2
- package/dist/node/gone.js +0 -7
- package/dist/node/hand.d.ts +0 -39
- package/dist/node/hand.js +0 -107
- package/dist/node/http.d.ts +0 -11
- package/dist/node/http.js +0 -90
- package/dist/node/index.d.ts +0 -11
- package/dist/node/index.js +0 -13
- package/dist/node/ledger-memory.d.ts +0 -17
- package/dist/node/ledger-memory.js +0 -152
- package/dist/node/lock.d.ts +0 -10
- package/dist/node/lock.js +0 -78
- package/dist/node/node-ground.d.ts +0 -26
- package/dist/node/node-ground.js +0 -228
- package/dist/node/notify.d.ts +0 -1
- package/dist/node/notify.js +0 -18
- package/dist/node/shell.d.ts +0 -11
- package/dist/node/shell.js +0 -35
- package/dist/node/sync-folder.d.ts +0 -6
- package/dist/node/sync-folder.js +0 -18
- package/dist/node/tcp-carry.d.ts +0 -42
- package/dist/node/tcp-carry.js +0 -193
- package/dist/node/unlock.d.ts +0 -17
- package/dist/node/unlock.js +0 -86
- package/dist/node/websocket.d.ts +0 -12
- package/dist/node/websocket.js +0 -134
- package/dist/quo/frame.d.ts +0 -33
- package/dist/quo/frame.js +0 -92
- package/dist/quo/index.d.ts +0 -1
- package/dist/quo/index.js +0 -5
- package/dist/quo/room.d.ts +0 -154
- package/dist/quo/room.js +0 -362
- package/dist/serve/index.d.ts +0 -45
- package/dist/serve/index.js +0 -71
package/GROUNDS.md
DELETED
|
@@ -1,315 +0,0 @@
|
|
|
1
|
-
# Grounds
|
|
2
|
-
|
|
3
|
-
A ground is the process houses run in. The library ships one for each
|
|
4
|
-
terrain, and you write none. You give it one key, and through its hand
|
|
5
|
-
you tell it which faculties to stand and which houses to open. This
|
|
6
|
-
guide says what every ground does, then what each one adds. [Writing
|
|
7
|
-
for nervur](AUTHORING.md) builds the shop this guide runs, and [the
|
|
8
|
-
command](COMMAND.md) drives a ground on your machine.
|
|
9
|
-
|
|
10
|
-
## What every ground does
|
|
11
|
-
|
|
12
|
-
**It holds one key outside itself.** The key is sixty-four hex digits,
|
|
13
|
-
kept by what the ground stands on: a file, a keychain, a Worker's
|
|
14
|
-
secret. The part of a ground that answers it is its unlock. Everything
|
|
15
|
-
else the ground keeps is sealed under that key.
|
|
16
|
-
|
|
17
|
-
**It unpacks in layers, each a faculty.** Every faculty has one
|
|
18
|
-
lifecycle. A registry holds faculties by name, each an object `{ takes?,
|
|
19
|
-
up, install? }`. Standing one raises it by its `up` into a body, the
|
|
20
|
-
living instance houses and other bodies use. `install` does the slow
|
|
21
|
-
work once for each entry, and a body's `down` lets go of what its `up`
|
|
22
|
-
opened.
|
|
23
|
-
|
|
24
|
-
| Layer | Its faculties | What they are |
|
|
25
|
-
| --- | --- | --- |
|
|
26
|
-
| primordial | the memory, the unlock, crypto, tools, the clock | the host's, read from the environment alone |
|
|
27
|
-
| the ground's work | `ground` | the library's, offered to the dock alone |
|
|
28
|
-
| the dock | a house of the library's beings | the drawer, and the hand's one road |
|
|
29
|
-
| the ladder | the terrain's defaults and your entries | carries, code, and every custom faculty |
|
|
30
|
-
| the hand | a socket, a key, a channel | the owner's reach, up last and down first |
|
|
31
|
-
|
|
32
|
-
**It keeps its drawer as cells of the dock's beings.** The dock is a
|
|
33
|
-
house every ground stands, and its beings are the library's. A twin
|
|
34
|
-
stands for each faculty entry, a being for each house, and one for each
|
|
35
|
-
secret. Their cells hold every entry, what each faculty installed, each
|
|
36
|
-
house's seed and ward, every secret, and the ground's bound on every
|
|
37
|
-
ask. No row of the ground's stands beside them.
|
|
38
|
-
|
|
39
|
-
**Every name an entry gives is a standing.** A house's code, its memory
|
|
40
|
-
and the faculties it uses, and a faculty's registry, its callees and its
|
|
41
|
-
secrets, are relations between those beings. The dock's steward
|
|
42
|
-
introduces each, and her notes name the grant. An entry that names a
|
|
43
|
-
faculty or a secret the dock does not hold is refused, and nothing
|
|
44
|
-
lands.
|
|
45
|
-
|
|
46
|
-
**Its houses keep their places in the same memory.** The dock, each
|
|
47
|
-
house and each faculty sees a view of the ground's memory under a prefix
|
|
48
|
-
of its own. A house seals its own rows, and the ground seals each
|
|
49
|
-
faculty's. So what rests on the disk is ciphertext, and copying the key,
|
|
50
|
-
the memory and the code moves the whole ground. A memory the key opens
|
|
51
|
-
no dock in is refused.
|
|
52
|
-
|
|
53
|
-
**It stands its bodies on a ladder.** The ground's own registry is its
|
|
54
|
-
terrain's. A body may carry a registry of its own, and the faculties an
|
|
55
|
-
entry raises `from` it stand after it. A body stands after each body its
|
|
56
|
-
entry names in `faculties`, whose objects its `up` receives. A body that
|
|
57
|
-
fails to stand stays down and says why, and the ground boots beside it.
|
|
58
|
-
|
|
59
|
-
**Its terrain names default entries, and yours win.** Each ground stands
|
|
60
|
-
its carries and its bodies of code from entries of its own. Its one
|
|
61
|
-
clock is primordial, which the dock and every house receive.
|
|
62
|
-
An entry you land under the same name stands in its place.
|
|
63
|
-
|
|
64
|
-
```text
|
|
65
|
-
recipe { from: 'folder', make: 'module', args: { at: 'recipe.ts' } }
|
|
66
|
-
payments { from: 'recipe', make: 'payments', secrets: ['stripe-key'], kinds: ['com.acme.order'] }
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
**It opens each house on its entry.** An entry names the body that
|
|
70
|
-
serves the house's code, the custom faculties it may use, and the
|
|
71
|
-
longest any of its asks may run. It names a body serving memory only
|
|
72
|
-
where the house keeps its places apart from the ground's memory. Beside
|
|
73
|
-
each body's name, it holds the args that body hands this house.
|
|
74
|
-
|
|
75
|
-
```text
|
|
76
|
-
shop { classes: { faculty: 'folder', at: 'shop' }, faculties: ['payments'], wait: 60000 }
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
**A change answers what stands, and an error means nothing landed.**
|
|
80
|
-
Adding or updating a faculty answers why its body is down, where it is.
|
|
81
|
-
Adding or updating a house answers its ward, or why it stays closed.
|
|
82
|
-
The entry lands either way, and the hand mends it later.
|
|
83
|
-
|
|
84
|
-
**It updates an entry in one write.** `update` lands the new entry over
|
|
85
|
-
the old. A house closes and opens again on it, as the same ward. A body
|
|
86
|
-
goes down, installs where its entry moved, and goes up, and each house
|
|
87
|
-
naming it opens again. `restart` takes a body down and up on its entry.
|
|
88
|
-
|
|
89
|
-
**It grants a faculty in two steps.** A house uses only the faculties its
|
|
90
|
-
entry names. Inside it, a being holds one only where the faculty's entry
|
|
91
|
-
names her class in `kinds`, or where it names none. So a raw program
|
|
92
|
-
reaches one house and one class inside it.
|
|
93
|
-
|
|
94
|
-
**It hands each faculty its secrets.** A secret is set through the hand
|
|
95
|
-
and kept in a being's cells. A faculty's entry names the secrets its
|
|
96
|
-
`up` receives, and no other code reads one. The hand lists their names
|
|
97
|
-
and the entries that name each, and never a value. A secret's cells are
|
|
98
|
-
shown to no one, and a changed secret reaches a body when it goes up
|
|
99
|
-
again.
|
|
100
|
-
|
|
101
|
-
**It holds each entry to what its faculty takes.** A faculty declares
|
|
102
|
-
`takes`: a schema its args meet, and the secrets its entry must name.
|
|
103
|
-
The hand refuses an entry that fails it, or that names a secret not
|
|
104
|
-
kept, and says what failed. `facultiesCatalog` shows every faculty the
|
|
105
|
-
ground can raise, and what each takes.
|
|
106
|
-
|
|
107
|
-
**It hooks every door and runs one listener.** Each house's door goes to
|
|
108
|
-
the ground's carry, which also delivers between the ground's own houses
|
|
109
|
-
without touching the network. Everything that speaks HTTP, Quo over the
|
|
110
|
-
web and every face, is a handler on one listener. A faculty stood while
|
|
111
|
-
the ground runs is served at once.
|
|
112
|
-
|
|
113
|
-
**The dock's steward reaches the ground through two faculties.** The
|
|
114
|
-
`ground` faculty raises and lowers bodies, opens and closes houses,
|
|
115
|
-
shows the catalogue and moves a house's places. It is offered to the
|
|
116
|
-
dock's beings alone. The `shell` runs a command on the ground's machine,
|
|
117
|
-
where the terrain has one. The dock is offered it as any house is
|
|
118
|
-
offered a body. Its steward stands on the shell's twin, and the twin's
|
|
119
|
-
entry grants it to the dock's shell being alone. No entry names, makes
|
|
120
|
-
or grants either.
|
|
121
|
-
|
|
122
|
-
**A boot writes only what moved.** Each twin raises its body by a read,
|
|
123
|
-
and her cells are written only where what came of it differs. So a wake
|
|
124
|
-
that finds nothing changed writes nothing.
|
|
125
|
-
|
|
126
|
-
**It serves its owner's hand, and the hand has one road.** The hand
|
|
127
|
-
answers `describe`, and otherwise asks a being of the dock or of a house
|
|
128
|
-
as `root`. A request that names a house asks a being there. One that
|
|
129
|
-
names none asks the dock's steward. `describe` shows her asks, every
|
|
130
|
-
faculty with its methods or why it is down, and every house.
|
|
131
|
-
|
|
132
|
-
| The dock's asks | What they do | Who asks them |
|
|
133
|
-
| --- | --- | --- |
|
|
134
|
-
| `housesAdd`, `housesUpdate`, `housesRemove`, `housesList` | the houses | `root`, and a pilot |
|
|
135
|
-
| `facultiesAdd`, `facultiesUpdate`, `facultiesRestart`, `facultiesRemove`, `facultiesList` | the faculties | `root`, and a pilot |
|
|
136
|
-
| `facultiesCatalog` | every faculty the ground can raise, and what it takes | `root`, and a pilot |
|
|
137
|
-
| `waitSet`, `waitShow` | the ground's bound on every ask | `root`, and a pilot |
|
|
138
|
-
| `secretsSet`, `secretsRemove`, `secretsList` | the secrets | `root` alone |
|
|
139
|
-
| `movesOut`, `movesIn` | a house moved between grounds | `root` alone |
|
|
140
|
-
| `callFaculty` | a faculty's method, called by name | `root` alone |
|
|
141
|
-
| `shellRun` | a command on the ground's machine | `root` alone |
|
|
142
|
-
| `pilotsInvite`, `pilotsDismiss`, `pilotsList` | who pilots the ground | `root` alone |
|
|
143
|
-
| `boot` | the ladder stood and every house opened, as each boot asks | `root` alone |
|
|
144
|
-
|
|
145
|
-
**An ask of the dock is safe to send twice.** A request may carry
|
|
146
|
-
`call`, its call id. The same id sent again answers what the first
|
|
147
|
-
answered, and runs nothing twice.
|
|
148
|
-
|
|
149
|
-
**It lets a pilot possess it from afar.** `pilotsInvite` mints an
|
|
150
|
-
invitation to the dock's steward, and the owner hands it to one being.
|
|
151
|
-
That being then holds a standing on the dock, and asks the houses and
|
|
152
|
-
faculties asks through it. Her class reaches them typed with
|
|
153
|
-
`this.held(id, DockPilot)`, the need `nervur` exports. Secrets, moves,
|
|
154
|
-
the shell and faculties' methods stay the hand's alone. A secret passes
|
|
155
|
-
through `secretsSet`, which answers nothing, so no answer holds one.
|
|
156
|
-
|
|
157
|
-
**It moves a house by its seed and its memory.** `movesOut` takes a
|
|
158
|
-
house out as its seed and every place of its memory, and another ground
|
|
159
|
-
takes them in with `movesIn`. The house keeps its identity, so every
|
|
160
|
-
relation still answers and no far house notices.
|
|
161
|
-
|
|
162
|
-
## The five grounds
|
|
163
|
-
|
|
164
|
-
| Ground | Where it runs | When it wakes | Its unlock | Its memory | Its hand |
|
|
165
|
-
| --- | --- | --- | --- | --- | --- |
|
|
166
|
-
| NodeGround | a server, a desktop, a Pi | always on | a key file, or the macOS keychain | a ledger in its folder | a socket in its folder |
|
|
167
|
-
| EdgeGround | a Cloudflare Worker and its Durable Object | per request, per message, per alarm | the Worker's secret | the object's storage | a key the Worker holds |
|
|
168
|
-
| BrowserGround | a page or its service worker | while a tab is open, and by push | a key sealed under one the browser never hands out | IndexedDB | a channel between the origin's tabs |
|
|
169
|
-
| AppGround | an iOS or Android app's web view | per launch, and by push | the Keychain or the Keystore | the app's native store | a channel, as in a page |
|
|
170
|
-
| BenchGround | memory, in a test | as the test moves its clock | a key drawn from the bench's seed | memory in the process | the test's own |
|
|
171
|
-
|
|
172
|
-
The same class runs unchanged on every row. What differs is the bodies
|
|
173
|
-
each ground hands its houses.
|
|
174
|
-
|
|
175
|
-
## NodeGround
|
|
176
|
-
|
|
177
|
-
**`nervur up <folder>` runs one.** The folder holds your code: a folder
|
|
178
|
-
for each house, and each module or program your entries name. Its
|
|
179
|
-
`state/` holds the key, the ground's ledger and the hand's socket. A
|
|
180
|
-
house's folder has an `index` that exports its `steward`, and `public`
|
|
181
|
-
and `beings` where it has them, as [Writing for nervur](AUTHORING.md)
|
|
182
|
-
shows. The ground's folder is an ES module package, so its
|
|
183
|
-
`package.json` says `"type": "module"`. It listens on TCP and, where a
|
|
184
|
-
port is set, on the web. [The command](COMMAND.md) lists its settings
|
|
185
|
-
and runs its hand.
|
|
186
|
-
|
|
187
|
-
**Its registry holds its terrain's faculties.** `folder` serves each
|
|
188
|
-
house its classes from a folder inside the code folder its args name.
|
|
189
|
-
Its body carries a registry of two more, rooted there. `module` imports
|
|
190
|
-
a module as a registry, whose `faculties` export holds `{ up, install?
|
|
191
|
-
}` by name. `bridge` starts a program, in any language, and hands it the
|
|
192
|
-
secrets its entry names as its environment. An entry stands either with
|
|
193
|
-
`from: 'folder'`. `tcp` and `web` are its carries, `listener` its one
|
|
194
|
-
listener, and `shell` its shell. Its clock is the library's, and
|
|
195
|
-
primordial.
|
|
196
|
-
|
|
197
|
-
**Its code gives the default entries.** `folder`, `listener`, `tcp`,
|
|
198
|
-
`web` and `shell` stand from entries the library fixes. TCP
|
|
199
|
-
listens on the loopback at 9110, so nothing beyond the machine reaches
|
|
200
|
-
a new ground. A server names its bind through the hand. The web names
|
|
201
|
-
`listener` in its `faculties` and listens on no port. An entry of the
|
|
202
|
-
same name you land stands in their place, so a port changes through the
|
|
203
|
-
hand. Name
|
|
204
|
-
`listener` there too, since the web serves the listener it calls.
|
|
205
|
-
|
|
206
|
-
**A port another process holds keeps that carry down with why.** The
|
|
207
|
-
ground boots beside it until the hand moves the port. A `tcp` entry
|
|
208
|
-
whose args name no port only dials, and its invitations name no TCP
|
|
209
|
-
address. Its environment names only `NERVUR_STATE`, `NERVUR_UNLOCK` and
|
|
210
|
-
`NERVUR_HAND`.
|
|
211
|
-
|
|
212
|
-
**Its key rests in `state/key`, its owner's alone.** A key file others
|
|
213
|
-
may read is refused, as ssh refuses a key. On macOS,
|
|
214
|
-
`NERVUR_UNLOCK=keychain:<account>` keeps the key in the keychain
|
|
215
|
-
instead. Keep `state/` as you keep an ssh key: whoever holds the key and
|
|
216
|
-
the ledger holds the ground.
|
|
217
|
-
|
|
218
|
-
**It keeps its memory as a ledger, which holds the folder's lock.** Every
|
|
219
|
-
write is one line, chained to the line before it and synced before it
|
|
220
|
-
counts. A ledger edited anywhere but its end is refused. A witness file
|
|
221
|
-
kept on another disk refuses a restored copy that is behind. While the
|
|
222
|
-
ledger stands, a second ground on the same state is refused.
|
|
223
|
-
|
|
224
|
-
**Its shell runs a command for the hand alone.** `nervur shell run --
|
|
225
|
-
<command>` runs it in the code folder, and answers its exit code and
|
|
226
|
-
what it printed. Its environment holds `PATH`, `HOME` and a few more of
|
|
227
|
-
the process's, and never a secret or a `NERVUR_` variable. No pilot and
|
|
228
|
-
no being reaches it.
|
|
229
|
-
|
|
230
|
-
**It runs a program as a faculty, in any language.** The bridge starts a
|
|
231
|
-
program and speaks one JSON value a line on its standard streams. The
|
|
232
|
-
program keeps what it must in the faculty's sealed memory, through lines
|
|
233
|
-
of its own. [Writing a faculty](FACULTIES.md) teaches it.
|
|
234
|
-
|
|
235
|
-
## EdgeGround
|
|
236
|
-
|
|
237
|
-
**An edge is one Durable Object, woken per event.** The Worker hands
|
|
238
|
-
every request to the one object its ground's name gives. At each wake
|
|
239
|
-
the ground boots again, and a house opens only when a box for it arrives
|
|
240
|
-
or the hand names it.
|
|
241
|
-
|
|
242
|
-
**Its Worker's module is two lines over your code.**
|
|
243
|
-
|
|
244
|
-
```ts
|
|
245
|
-
// worker.ts
|
|
246
|
-
import { EdgeGround } from 'nervur/edge';
|
|
247
|
-
import * as shop from './classes/index.ts';
|
|
248
|
-
import * as recipe from './recipe.ts';
|
|
249
|
-
|
|
250
|
-
export const Ground = EdgeGround.object({ registry: recipe, code: { shop } });
|
|
251
|
-
|
|
252
|
-
export default EdgeGround.worker();
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
The Worker binds the object's class as `GROUND`, with SQLite storage.
|
|
256
|
-
`registry` joins the terrain's own, so an entry raises `payments` with
|
|
257
|
-
no `from`. A house's entry names its code with `classes: { faculty:
|
|
258
|
-
'bundle', at: 'shop' }`.
|
|
259
|
-
|
|
260
|
-
**Its Worker holds two secrets and nothing else.**
|
|
261
|
-
|
|
262
|
-
| Variable | What it names |
|
|
263
|
-
| --- | --- |
|
|
264
|
-
| `NERVUR_SECRET` | the ground's key, sixty-four hex digits; set as a secret |
|
|
265
|
-
| `NERVUR_HAND` | the key its hand answers; set as a secret |
|
|
266
|
-
|
|
267
|
-
A Worker learns no name it is reached by, so it writes only the
|
|
268
|
-
addresses its `web` entry names, the held line first. Name them through
|
|
269
|
-
the hand with `facultiesUpdate`, as `addresses` in the args of `web`,
|
|
270
|
-
beside its `origins` and `allowPrivate`, and the dock keeps them.
|
|
271
|
-
Every ask runs a minute at most, and `waitSet` keeps a shorter bound.
|
|
272
|
-
Its faculties take their secrets from the dock, as on every ground. It
|
|
273
|
-
has no shell.
|
|
274
|
-
|
|
275
|
-
**Its hand answers its key alone.** The hand is `POST /nervur/hand`, with
|
|
276
|
-
the key as a bearer token and one request as the body. Every other
|
|
277
|
-
request there, and every request to an edge that sets no key, finds
|
|
278
|
-
nothing.
|
|
279
|
-
|
|
280
|
-
**It is deployed by a faculty, never by hand.** A faculty on your
|
|
281
|
-
NodeGround holds the account. It builds the module, uploads it with the
|
|
282
|
-
two secrets, keeps them, and reaches the hand. The library ships none,
|
|
283
|
-
since a deploy is a choice of yours. The first deploy is that faculty
|
|
284
|
-
called through your NodeGround's hand, and every later one is your pilot
|
|
285
|
-
being's.
|
|
286
|
-
|
|
287
|
-
**Its held lines hibernate.** A page or a device holds a WebSocket on the
|
|
288
|
-
edge, the platform keeps it while the object sleeps, and a message wakes
|
|
289
|
-
the object. A watch held on that line answers the moment the change lands.
|
|
290
|
-
|
|
291
|
-
## BrowserGround and AppGround
|
|
292
|
-
|
|
293
|
-
**A BrowserGround is one ground for its origin.** Every tab and the
|
|
294
|
-
service worker of an origin share it. The tab holding a Web Lock runs
|
|
295
|
-
the ground, and its hand answers every other tab over a channel. It
|
|
296
|
-
only dials, so it answers no face. Whoever serves the origin's script
|
|
297
|
-
possesses the ground, so its origin serves nothing else.
|
|
298
|
-
[The package's start](README.md) opens one in a page.
|
|
299
|
-
|
|
300
|
-
**Its registry is the one the page hands.** `BrowserGround.open({
|
|
301
|
-
registry })` joins it to the terrain's own, whose faculty `origin`
|
|
302
|
-
serves each house its classes from the origin.
|
|
303
|
-
|
|
304
|
-
**An AppGround is a BrowserGround with the shell's bodies.** The app's
|
|
305
|
-
native shell hands in two small interfaces, one for secrets and one for
|
|
306
|
-
a store, and the library holds the rest. The ground's key rests in the
|
|
307
|
-
secret store.
|
|
308
|
-
|
|
309
|
-
## BenchGround
|
|
310
|
-
|
|
311
|
-
**A BenchGround runs a world in memory.** A `FakeNetwork` joins several,
|
|
312
|
-
gives them names as DNS does, and carries every box between them on one
|
|
313
|
-
clock the test moves. It cuts, slows, drops and repeats boxes, and turns
|
|
314
|
-
a ground off and on. So one test proves the same classes at every
|
|
315
|
-
distance. [Writing for nervur](AUTHORING.md) tests the shop on it.
|
package/KIT-SPEC.md
DELETED
|
@@ -1,304 +0,0 @@
|
|
|
1
|
-
# nervur's answers to KIT-SPEC
|
|
2
|
-
|
|
3
|
-
This document answers, for `nervur`, every question that Quo's `KIT-SPEC.md`
|
|
4
|
-
asks of a kit. Quo's spec, `SPEC.md`, and `KIT-SPEC.md` stand in
|
|
5
|
-
[razvangherghina/quo](https://github.com/razvangherghina/quo), and every
|
|
6
|
-
term below is the term they define. Quo's verifier judges nervur's Quo
|
|
7
|
-
layer as a door, an asker, a TCP listener and a TCP dialer. It passes all
|
|
8
|
-
four. Each answer states what the code of this version does.
|
|
9
|
-
|
|
10
|
-
## What stands behind a door
|
|
11
|
-
|
|
12
|
-
**Question 1.** A house stands behind each door, and holds one ward. A
|
|
13
|
-
house holds beings. A being is an instance of a class a developer writes,
|
|
14
|
-
with JSON cells and named asks. A ground is the script that opens a house.
|
|
15
|
-
It hands each arrival to the house's `door(box)` function. The door finds
|
|
16
|
-
the relation by its heir, and the heir names one being and one of her
|
|
17
|
-
occupants. An occupant is a being's name for the door's end of a relation.
|
|
18
|
-
Asks to one being run one at a time, in the order they arrive. An ask
|
|
19
|
-
marked `readOnly`, and the empty ask, run beside them. Asks to two beings
|
|
20
|
-
run side by side.
|
|
21
|
-
|
|
22
|
-
**Question 2.** The ground that runs the house holds its seed, sealed in
|
|
23
|
-
the ground's drawer under the one key the ground holds outside itself. A
|
|
24
|
-
keys body gives signatures and agreements from the seed, and never the
|
|
25
|
-
seed itself. `House.open`
|
|
26
|
-
hands the ground a hand, `ask({ id, method, args })`, which asks the being
|
|
27
|
-
`id`, or the steward where none is named, as the occupant `root`. The
|
|
28
|
-
steward places and removes every other being. Every other being holds the
|
|
29
|
-
standing `steward`, which she cannot drop. The steward cannot dismiss
|
|
30
|
-
`root`. So no path inside a house removes the edge back to what made it.
|
|
31
|
-
`root` never arrives through a door. The ground serves the hands of all
|
|
32
|
-
its houses in one place. On Node, that is a local socket only the
|
|
33
|
-
ground's user may open.
|
|
34
|
-
|
|
35
|
-
**Question 3.** The public being answers the zero head, where the ground's
|
|
36
|
-
classes name one. A house with no public being answers every ask on the
|
|
37
|
-
zero head with silence, as case 4. The public being reads each such asker
|
|
38
|
-
as the occupant `stranger`, with the key its ask was signed by. A stranger
|
|
39
|
-
reaches only her asks that are safe to repeat. The house keeps each
|
|
40
|
-
zero-head choice by the box's signature for ten minutes. The same sealed
|
|
41
|
-
bytes arriving again within that window hear the same choice, and nothing
|
|
42
|
-
runs twice. That cache lives in the process, so a restart empties it.
|
|
43
|
-
|
|
44
|
-
**Question 4.** The door opens any number of boxes at once, and judges
|
|
45
|
-
one at a time on each relation. A box whose relation has another box in
|
|
46
|
-
flight waits for it, and is judged again on the record it left. A box
|
|
47
|
-
opened on a record that moved meanwhile is judged again too. So each box
|
|
48
|
-
is admitted by what holds when the door chooses, and the highest number
|
|
49
|
-
honoured never goes down. An admitted ask waits its turn among its
|
|
50
|
-
being's asks, and its move lands in the ask's own write.
|
|
51
|
-
|
|
52
|
-
**Question 5.** nervur calls what stands behind a door a house, and what
|
|
53
|
-
it holds beings. The door's end of a relation is an occupant, named by an
|
|
54
|
-
id its being chooses. The asking end keeps Quo's name, a standing. A
|
|
55
|
-
standing that arrives by invitation is named `standing:` and sixteen hex
|
|
56
|
-
digits drawn from its heir, so the same invitation taken again gives the
|
|
57
|
-
same standing. The ids `root`, `stranger` and `steward` are reserved, with every
|
|
58
|
-
id beginning `handle:` or `being:`. The process that opens a house is its
|
|
59
|
-
ground. None of these names crosses a door.
|
|
60
|
-
|
|
61
|
-
## What a kit keeps
|
|
62
|
-
|
|
63
|
-
**Question 6.** A ward's seed is sixty-four lowercase hex digits, and
|
|
64
|
-
anything else opens no house. `SeedKeys` takes it as a string. A ground
|
|
65
|
-
draws a fresh seed when a house is first added, and keeps it sealed in
|
|
66
|
-
its drawer. The drawer's key rests outside the ground, in a file only
|
|
67
|
-
its owner may read, the macOS keychain, a Worker's secret, or the
|
|
68
|
-
platform's keystore. The house never holds the seed, and asks its keys
|
|
69
|
-
body for operations alone. The lock is
|
|
70
|
-
derived, not drawn. It is the ML-KEM-768 key pair from 64 bytes of
|
|
71
|
-
HKDF-SHA-256 over the seed, under the label `nervur-lock`. It is made on
|
|
72
|
-
first use and is the same every time. So a ward holds one lock, and its
|
|
73
|
-
seed alone restores it whole. The ward keeps no heir's secret after it
|
|
74
|
-
gives the invitation.
|
|
75
|
-
|
|
76
|
-
**Question 7.** Every drawn byte comes from `crypto.getRandomValues`, the
|
|
77
|
-
platform's Web Crypto source. The default crypto body, `NobleCrypto`, draws
|
|
78
|
-
there for heir secrets, ephemeral secrets, announced keys and ids. Its
|
|
79
|
-
ML-KEM encapsulation, from the noble library, draws from the same source.
|
|
80
|
-
The lock draws nothing, since it derives from the seed. A ground may hand
|
|
81
|
-
its own crypto body, and then the source is that body's.
|
|
82
|
-
|
|
83
|
-
**Question 8.** For each heir, the door keeps whether it is spent, the key
|
|
84
|
-
it holds, the key it vouches for, and the open and offered edge keys. It
|
|
85
|
-
keeps the highest number it honoured as well. That record sits in the
|
|
86
|
-
place of the being the heir reaches, beside her other relations. The house
|
|
87
|
-
keeps it in the memory its ground hands it, sealed under a key derived
|
|
88
|
-
from the seed. `FileMemory` and `LedgerMemory` write to disk, and the
|
|
89
|
-
record survives a restart with them. A standing's record is kept the same
|
|
90
|
-
way. Its number and its knock are written before a box leaves.
|
|
91
|
-
|
|
92
|
-
**Question 9.** A door stops holding an heir when its being dismisses the
|
|
93
|
-
occupant the heir reaches. It stops when a handle made for one use has its
|
|
94
|
-
first ask land. It stops when the steward removes the being. An invitation
|
|
95
|
-
taken by a standing of the same house binds inside the house, and its heir
|
|
96
|
-
leaves the door then. An heir minted with a time to be spent in, and
|
|
97
|
-
still unspent past it, is one the door never held. The door lets it go
|
|
98
|
-
at the next mint or binding knock. A spent heir never expires, nor one
|
|
99
|
-
minted without a time.
|
|
100
|
-
|
|
101
|
-
**Question 10.** The door keeps no keys at removal, for any time.
|
|
102
|
-
Dismissal deletes the heir from the door's index. So an ask signed by any
|
|
103
|
-
of the relation's keys hears silence at once, and the door never answers
|
|
104
|
-
`removed` in this version.
|
|
105
|
-
|
|
106
|
-
**Question 11.** None. A door honours no number below the highest it
|
|
107
|
-
honoured on a relation, and a number at or below it hears `repeated`. A
|
|
108
|
-
nervur standing numbers each ask above every number it sent. So a retry
|
|
109
|
-
never meets `repeated` for a box that arrived.
|
|
110
|
-
|
|
111
|
-
## What a kit answers
|
|
112
|
-
|
|
113
|
-
**Question 12.** The door answers every box it refuses with silence or
|
|
114
|
-
with one of Quo's words. It answers every admitted ask with a choice. The
|
|
115
|
-
choice is the being's object, or silence where the being is absent or does
|
|
116
|
-
not hold that asker. The door gives nothing where the memory refuses the
|
|
117
|
-
write that holds the ask's move. Over TCP, the listener also answers
|
|
118
|
-
nothing for a ward it does not hold, and for a door that fails with an
|
|
119
|
-
error.
|
|
120
|
-
|
|
121
|
-
**Question 13.** `seen` is sixteen lowercase hex digits. They are the first
|
|
122
|
-
eight bytes of the SHA-256 of the canonical JSON of the describe that asker
|
|
123
|
-
would hear. So `seen` changes exactly when that describe changes: the
|
|
124
|
-
being's state, the asks shown to that asker, or their entries. Every
|
|
125
|
-
object carries it, an answer and a describe alike, a refusal of `args`
|
|
126
|
-
that repeat a key among them.
|
|
127
|
-
|
|
128
|
-
**Question 14.** The empty ask answers a describe to any asker the door
|
|
129
|
-
admits, a stranger on the zero head among them. A being that is absent
|
|
130
|
-
answers silence instead. A describe holds the being's current state and
|
|
131
|
-
every entry shown to the roles its asker holds, in every state. So two
|
|
132
|
-
askers with different roles hear two describes. Its `lang` is
|
|
133
|
-
`org.nervur.asks/1`, nervur's language above Quo, whose shapes are below.
|
|
134
|
-
An entry's `description` is the class author's text. Its `args` and
|
|
135
|
-
`result` are JSON Schema 2020-12, in a closed subset. A named ask that no
|
|
136
|
-
entry shown to that asker names hears `{"error":{"message":"no such ask"}}`.
|
|
137
|
-
|
|
138
|
-
```text
|
|
139
|
-
describe = { lang: "org.nervur.asks/1", kind?, description?, view?, state, asks }
|
|
140
|
-
entry = { method, in, to, description?, args, result?, hints, wait }
|
|
141
|
-
answer = { result } | { error: { message } }
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
A stranger's describe names no `kind` and no `description`. A `view` is
|
|
145
|
-
the being's markup as text, which a screen renders, and every asker is
|
|
146
|
-
shown it.
|
|
147
|
-
|
|
148
|
-
**Question 15.** A reply text holds no whitespace between tokens. An
|
|
149
|
-
object reply writes `object` first and `seen` second. Its object is
|
|
150
|
-
canonical JSON, with every object's keys sorted by UTF-16 code units. A
|
|
151
|
-
word is written `{"quo":"removed"}`, and silence `{"silence":true}`.
|
|
152
|
-
|
|
153
|
-
**Question 16.** No. nervur seals every payload and every reply text with
|
|
154
|
-
no padding. It reads padding wherever padding arrives.
|
|
155
|
-
|
|
156
|
-
**Question 17.** No. Each refusal returns as soon as its case is found.
|
|
157
|
-
So a box refused at its head returns sooner than one refused at its
|
|
158
|
-
signature.
|
|
159
|
-
|
|
160
|
-
**Question 18.** The Quo layer names the case that refused each arrival,
|
|
161
|
-
and the house discards it. Nothing in this version logs a refusal, or a
|
|
162
|
-
reply that breaks a rule. A standing reads a reply that breaks a rule as
|
|
163
|
-
silence, and keeps no record of why.
|
|
164
|
-
|
|
165
|
-
## What a kit asks
|
|
166
|
-
|
|
167
|
-
**Question 19.** An invitation leaves a house as a handle. A being puts a
|
|
168
|
-
handle in her answer, or in the `args` of a call outward. The house writes
|
|
169
|
-
it as the hex of the invitation's canonical JSON. From there it travels
|
|
170
|
-
however its receiver carries it. The minting house keeps no copy. It keeps
|
|
171
|
-
the heir's public key and the record of the relation, never the heir's
|
|
172
|
-
secret.
|
|
173
|
-
|
|
174
|
-
**Question 20.** A standing whose knock surely reached no door sends the
|
|
175
|
-
knock again, as the same bytes, until it may have. Its carry says so: no
|
|
176
|
-
address took the box. A standing whose knock may have been heard, and
|
|
177
|
-
brought no object back, recovers it in turns. Its next send is an ask
|
|
178
|
-
with a new number, under the key its knock announced and the knock's edge
|
|
179
|
-
key. The send after that is the knock again, as the same bytes. The two
|
|
180
|
-
take turns until an object comes back, or a word to an ask. An awaited
|
|
181
|
-
call makes one send within its wait, and the next call on the relation
|
|
182
|
-
takes the next turn. An effect is sent again after a wait that starts at
|
|
183
|
-
one second and doubles, never past five minutes. It stops at its
|
|
184
|
-
deadline, which is seven days for a standing.
|
|
185
|
-
|
|
186
|
-
**Question 21.** Over TCP and the web, a dialer waits thirty seconds for
|
|
187
|
-
each address, unless the ground sets `wait` on its carry. An awaited call
|
|
188
|
-
waits as long as the method it calls names. That is thirty seconds by
|
|
189
|
-
default, never past five minutes, and never past the ground's `wait` on
|
|
190
|
-
the house. It never waits past what is left of the ask that makes it. An
|
|
191
|
-
awaited call to a far ward carries that time in the payload field
|
|
192
|
-
`within`, in milliseconds. The ask it starts waits that long at most, and
|
|
193
|
-
an ask whose time is spent runs nothing and hears silence. A being waits
|
|
194
|
-
on no effect, and an effect's answer returns to her as an ask.
|
|
195
|
-
|
|
196
|
-
**Question 22.** A standing numbers its asks from 1, each one above the
|
|
197
|
-
last it sent. Every ask announces a fresh random key in `next`. The house
|
|
198
|
-
sends one ask at a time on each relation, and the next waits for the reply
|
|
199
|
-
to the last. The number and any knock are written before a box leaves.
|
|
200
|
-
The standing moves only on an object answering an ask above every ask it
|
|
201
|
-
has moved on. It then signs with the key that ask announced, and keeps no
|
|
202
|
-
key it moved from. After a move, an ask that meets silence moves nothing.
|
|
203
|
-
The next ask signs with the same key under the same edge key, with a new
|
|
204
|
-
number and a new announced key.
|
|
205
|
-
|
|
206
|
-
**Question 23.** The Quo layer reads a reply as one of four: an object
|
|
207
|
-
with its `seen`, silence, one of Quo's three words, or nothing. The house
|
|
208
|
-
treats silence, a word and nothing alike, as transient, and names no
|
|
209
|
-
cause for any of them. An address that never answered, a spent heir and
|
|
210
|
-
a reply that came late read the same. An awaited call fails with the
|
|
211
|
-
method's name followed by `answered nothing`. An effect is sent again.
|
|
212
|
-
Past its deadline, its reply ask reads `the call gave up at its
|
|
213
|
-
deadline`. A being never reads silence, a word or nothing as such.
|
|
214
|
-
|
|
215
|
-
## What a kit carries
|
|
216
|
-
|
|
217
|
-
**Question 24.** nervur stands Quo over TCP, as a listener and as a
|
|
218
|
-
dialer, in `TcpCarry` from `nervur/node`. It carries plain TCP, with no TLS
|
|
219
|
-
and no check beyond Quo's own. The listener binds `0.0.0.0` by default, on
|
|
220
|
-
the port the ground names or one the system picks. One listener answers
|
|
221
|
-
for every ward whose house listens on it, routed by the ward each ask
|
|
222
|
-
names.
|
|
223
|
-
|
|
224
|
-
nervur stands Quo over the web in `WebCarry`, both its post and its held
|
|
225
|
-
line, as a listener and as a dialer. The listener is a handler on the
|
|
226
|
-
ground's own HTTP listener, at the path `/quo` unless the ground names
|
|
227
|
-
another. It answers a reply with status 200 and nothing with 204. It
|
|
228
|
-
answers a request that is not a `POST` with 405, a body of the wrong size
|
|
229
|
-
with 400, and a ward pk it holds no door for with 404. It answers the
|
|
230
|
-
CORS protocol only for the origins its ground names, and no origin
|
|
231
|
-
otherwise. A held line that does not offer the subprotocol `quo` is
|
|
232
|
-
refused at its handshake with 400. TLS is the ground's listener's, and
|
|
233
|
-
this carry adds none.
|
|
234
|
-
|
|
235
|
-
**Question 25.** A standing learns where a ward is reached from the `at` of
|
|
236
|
-
its invitation, and from which address answered. A house writes `at` in
|
|
237
|
-
every invitation it mints. It writes the addresses the ground hands its
|
|
238
|
-
carry, the same toward every holder. A carry that joins several lists
|
|
239
|
-
every one's addresses. Where the ground hands none, `TcpCarry` writes the
|
|
240
|
-
listener's own address, with `0.0.0.0` written as `127.0.0.1`.
|
|
241
|
-
|
|
242
|
-
A carry keeps the door of every ward it listens for. A box to one of those
|
|
243
|
-
wards goes to its door in the same process, before any address, and no
|
|
244
|
-
connection is made. So the houses of one ground reach each other by the
|
|
245
|
-
carry they share, whatever their invitations' `at` holds.
|
|
246
|
-
|
|
247
|
-
A standing keeps its route: the address that last answered with an
|
|
248
|
-
object or a word, which only a reply that opened as the ward's carries.
|
|
249
|
-
Silence pins nothing. Each ask tries the route first, then the addresses
|
|
250
|
-
of `at` in their order, one after another. The route is kept with the
|
|
251
|
-
standing's record and survives a restart.
|
|
252
|
-
|
|
253
|
-
A door writes `at` in an object reply when the ground's addresses differ
|
|
254
|
-
from the ones that holder last heard, in its invitation or in a reply.
|
|
255
|
-
It writes them once, and a later reply carries none until they change
|
|
256
|
-
again. A reply lost after it carried them leaves that holder with the
|
|
257
|
-
old addresses until the next change. A standing takes `at` from an
|
|
258
|
-
object reply alone. It replaces the addresses it held, and a later reply
|
|
259
|
-
with none leaves them as they stand. The dialer skips an
|
|
260
|
-
address its carry does not speak. It looks a name up and takes its first
|
|
261
|
-
address. One connection to each address carries many asks at once.
|
|
262
|
-
|
|
263
|
-
The dialer refuses a loopback, private, link-local, shared or unspecified
|
|
264
|
-
address, unless the ground sets `allowPrivate`. Over the web it reads
|
|
265
|
-
the host as the URL writes it, and refuses `localhost` too. It moves to
|
|
266
|
-
the next address after a refused address, a failed connection, a
|
|
267
|
-
nothing frame, or a post answered with any status but 200 and a body. It
|
|
268
|
-
carries the box no further after a wait that runs out, a connection that
|
|
269
|
-
closes with the ask in flight, or a post that failed after it was sent.
|
|
270
|
-
That ask may have been heard, and the send answers nothing.
|
|
271
|
-
|
|
272
|
-
## What is not the kit's either
|
|
273
|
-
|
|
274
|
-
**Question 26.** `method` names an entry of the being's describe, and
|
|
275
|
-
`args` are that entry's arguments. The house holds `args` to the entry's
|
|
276
|
-
schema before the method runs, and answers a mismatch as an error. The
|
|
277
|
-
`lang` `org.nervur.asks/1` names nervur's language, whose shapes Question
|
|
278
|
-
14 gives. A field `call` beside `method` carries a call id, and a field
|
|
279
|
-
`within` the milliseconds its chain has left, as Question 21 gives. An ask whose
|
|
280
|
-
call id that occupant already used hears the stored answer, and runs
|
|
281
|
-
nothing. A call id is kept seven days.
|
|
282
|
-
|
|
283
|
-
## What a kit reads
|
|
284
|
-
|
|
285
|
-
**Question 27.** nervur's JSON reader is iterative. It reads any nesting
|
|
286
|
-
depth that a box of at most 1 MiB holds, and sets no length below that
|
|
287
|
-
size. It takes lone surrogates written as escapes, and noncharacters, as
|
|
288
|
-
they stand. Repeated keys anywhere inside `args` are answered
|
|
289
|
-
`{"error":{"message":"the args repeat a key"}}`, and the method never runs.
|
|
290
|
-
Numbers are read as IEEE 754 doubles. So an integer beyond 2^53 loses
|
|
291
|
-
precision before the schema holds it. Fields of the payload that the spec
|
|
292
|
-
does not name, `call` and `within` apart, are ignored. Inside a reply's
|
|
293
|
-
`object`, a standing takes a repeated key and keeps its last value.
|
|
294
|
-
|
|
295
|
-
## What a kit shows
|
|
296
|
-
|
|
297
|
-
**Question 28.** nervur reads a domain's vouch for every standing on a
|
|
298
|
-
far ward. The domains it checks are the hosts of the invitation's
|
|
299
|
-
`https` and `wss` addresses, so a domain that serves no web is never
|
|
300
|
-
asked. It reads the file once the ask that takes the invitation lands, and
|
|
301
|
-
again when the ward names new addresses in a reply. A being sees the
|
|
302
|
-
domains that vouched beside each standing she holds, and shows them to
|
|
303
|
-
the person as her class chooses. A domain that lists the ward is shown,
|
|
304
|
-
and one that does not is not.
|