@quo-systems/quo 0.2.13 → 0.2.15
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/README.md +10 -4
- package/SPEC.md +354 -536
- package/dist/being/being.d.ts +1 -0
- package/dist/being/being.js +8 -3
- package/dist/being/index.d.ts +1 -1
- package/dist/being/index.js +1 -1
- package/dist/being/types.d.ts +2 -0
- package/dist/being/types.js +17 -0
- package/dist/conformance/beings.d.ts +41 -0
- package/dist/conformance/beings.js +28 -2
- package/dist/conformance/index.d.ts +10 -1
- package/dist/conformance/index.js +162 -6
- package/dist/harbor/core.d.ts +4 -2
- package/dist/harbor/core.js +25 -4
- package/dist/harbor/index.d.ts +1 -1
- package/dist/harbor/memory.d.ts +3 -3
- package/dist/harbor/memory.js +6 -3
- package/dist/harbor/reach.js +1 -1
- package/dist/ward/cells.d.ts +2 -0
- package/dist/ward/cells.js +60 -11
- package/dist/ward/door.d.ts +1 -0
- package/dist/ward/door.js +29 -10
- package/dist/ward/ground.d.ts +3 -1
- package/dist/ward/ground.js +1 -1
- package/dist/ward/heirs.js +8 -1
- package/dist/ward/index.d.ts +2 -2
- package/dist/ward/index.js +3 -3
- package/dist/ward/owner.js +49 -8
- package/dist/ward/seal.d.ts +1 -0
- package/dist/ward/seal.js +10 -2
- package/dist/ward/stance.d.ts +1 -0
- package/dist/ward/stance.js +62 -4
- package/dist/ward/ward.js +5 -0
- package/package.json +5 -3
- package/quo-kit.md +523 -0
- package/src/being/being.ts +8 -3
- package/src/being/index.ts +1 -1
- package/src/being/types.ts +34 -0
- package/src/conformance/beings.ts +25 -2
- package/src/conformance/estate.ts +9 -9
- package/src/conformance/index.ts +204 -7
- package/src/conformance/reach.ts +1 -1
- package/src/harbor/core.ts +26 -5
- package/src/harbor/index.ts +1 -1
- package/src/harbor/memory.ts +7 -4
- package/src/harbor/reach.ts +1 -1
- package/src/ward/cells.ts +59 -10
- package/src/ward/door.ts +27 -9
- package/src/ward/ground.ts +39 -11
- package/src/ward/heirs.ts +7 -1
- package/src/ward/index.ts +4 -4
- package/src/ward/owner.ts +45 -10
- package/src/ward/seal.ts +11 -2
- package/src/ward/stance.ts +60 -4
- package/src/ward/ward.ts +6 -1
package/SPEC.md
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# SPEC
|
|
2
2
|
|
|
3
3
|
This is the truth of Quo, and the whole context. It assumes nothing from any
|
|
4
|
-
other document. It is
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
other document. It is the protocol and nothing else: what any ward anywhere
|
|
5
|
+
must do, in any language, for its bytes to be Quo. A sentence is here only
|
|
6
|
+
because a ward written in another language needs it to interoperate with
|
|
7
|
+
ours. What one kit chose, and another kit may refuse, is that kit's paper and
|
|
8
|
+
never this one.
|
|
7
9
|
|
|
8
10
|
It carries no version and keeps no history. There is no 1.0.0 yet, so there
|
|
9
11
|
is nobody holding an older Quo to be compatible with, and no changelog to
|
|
@@ -11,7 +13,6 @@ write. This file is rewritten in place to say what the tree says, and when
|
|
|
11
13
|
the two disagree the fix is to move one of them, the same day. Where the tree
|
|
12
14
|
is behind a decision, the chapter "Where the tree stands" says so; that
|
|
13
15
|
chapter is the one place a gap is allowed to be named instead of closed.
|
|
14
|
-
`test/repo.test.ts` holds this document to the tree where a test can.
|
|
15
16
|
The package is published from 0.1.0 with no compatibility promise: this
|
|
16
17
|
document may still move under anyone holding it. At 1.0.0 it is frozen
|
|
17
18
|
once, and versioning starts to mean something.
|
|
@@ -76,30 +77,45 @@ Nothing crosses either of them but what is written here.
|
|
|
76
77
|
|
|
77
78
|
### Harbor to ward
|
|
78
79
|
|
|
79
|
-
The harbor passes
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
80
|
+
The harbor passes the **ground**, once, at birth, and receives two pointers.
|
|
81
|
+
The ground is seven capabilities, and a kit gathers them however its
|
|
82
|
+
language gathers things. What each one is, is Quo's; how they are held
|
|
83
|
+
together is not.
|
|
84
|
+
|
|
85
|
+
1. **The seed.** The ward derives its pk from it and from nothing else.
|
|
86
|
+
Thirty-two bytes are the seed; anything else, text or bytes of another
|
|
87
|
+
length, is SHA-256'd to thirty-two bytes first.
|
|
88
|
+
2. **The partition.** The ward's files, as values, opaque to the harbor.
|
|
89
|
+
3. **Instantiate.** A class name and a stance in, the being or nothing out.
|
|
90
|
+
A name the harbor does not hold is nothing, and the boot that named it
|
|
91
|
+
fails.
|
|
92
|
+
4. **Carry.** A ward pk and bytes in, bytes or nothing out. Nothing means no
|
|
93
|
+
door was reached, and a throw is read the same way.
|
|
94
|
+
5. **Random.** A count in, that many bytes of entropy out. Every key a ward
|
|
95
|
+
mints is drawn from it.
|
|
96
|
+
6. **Wrote.** The ward says it after every write to its partition, and after
|
|
97
|
+
nothing else. A harbor that keeps the partition saves after it, when it
|
|
98
|
+
likes and in the order it was told. A harbor that keeps nothing needs it
|
|
99
|
+
not at all.
|
|
100
|
+
7. **Lend.** What the device lends this ward's beings, by name. One call: a
|
|
101
|
+
name and a taker in, whether it was taken out. The harbor's root mints an
|
|
102
|
+
invitation on a being of its own ward, for this ward alone, and hands it
|
|
103
|
+
to the taker, which knocks and takes it and answers whether it did. A
|
|
104
|
+
taker that would not take is one the harbor unmints for, so nothing
|
|
105
|
+
half-lives. No is every kind of no. A harbor that lends nothing needs it
|
|
106
|
+
not at all.
|
|
107
|
+
|
|
108
|
+
Seven things, and nothing else is ever passed: a harbor that needs an eighth
|
|
109
|
+
has found a gap in Quo or a leak into the ward. `lend` is the whole of what
|
|
110
|
+
a device offers, and it offers it as a relation and never as an object: the
|
|
111
|
+
things a device can do are beings, booted by the harbor in a ward of its
|
|
112
|
+
own, and a being reaches one by holding a standing at her, exactly as she
|
|
113
|
+
reaches a being on another planet. The name is the harbor's namespace and no
|
|
114
|
+
word of the ward, which ward may ask for which name is decided where the
|
|
115
|
+
ground is built, and a stranger's ward is lent nothing. A harbor never mints:
|
|
116
|
+
it holds the ask pointer of the ward it booted, so it is that ward's root,
|
|
117
|
+
and the root may invite on any being of its ward. What comes back is a value
|
|
118
|
+
the ward carries to her, as an invitation is carried anywhere.
|
|
103
119
|
|
|
104
120
|
Returned:
|
|
105
121
|
|
|
@@ -133,9 +149,9 @@ out her answer(asker, method?, args?) -> object | silence the one method
|
|
|
133
149
|
```
|
|
134
150
|
|
|
135
151
|
The stance is her cells, her standings to ask, the calls to invite,
|
|
136
|
-
knock, take and remove, and
|
|
137
|
-
instantiate with a class name, and receives her. No method is
|
|
138
|
-
and what she answers to it is her blueprint.
|
|
152
|
+
knock, take and remove, boot, and lend. The ward builds it and hands it
|
|
153
|
+
to the harbor's instantiate with a class name, and receives her. No method is
|
|
154
|
+
the empty ask, and what she answers to it is her blueprint.
|
|
139
155
|
|
|
140
156
|
The stance, as every being in every language receives it. Nothing more is
|
|
141
157
|
ever offered, and nothing here may be missing.
|
|
@@ -156,6 +172,10 @@ stance
|
|
|
156
172
|
boot(class, key, id?) -> key | null a new being of her ward, by class name.
|
|
157
173
|
with an id, her standing to her under it
|
|
158
174
|
|
|
175
|
+
lend(name, id) -> id | null a standing at what this device lends,
|
|
176
|
+
by the harbor's name for it. awaitable:
|
|
177
|
+
the ward knocks and takes it for her
|
|
178
|
+
|
|
159
179
|
wanted = { time? } what this one ask may spend, in milliseconds. optional,
|
|
160
180
|
and so is saying anything at all
|
|
161
181
|
```
|
|
@@ -165,7 +185,7 @@ Return table.
|
|
|
165
185
|
| call | returns | when |
|
|
166
186
|
| ------------------- | ---------- | ------------------------------------------------------------------------------------------------------------ |
|
|
167
187
|
| invite(id, notes?) | invitation | she minted a fresh id; the occupant record exists from now, with those notes on it |
|
|
168
|
-
| | null | the id already names a record, occupant or standing, or is a reserved word
|
|
188
|
+
| | null | the id already names a record, occupant or standing, or is a reserved word, or the notes are not values |
|
|
169
189
|
| remove(id) | nothing | always. removing what is not there is nothing |
|
|
170
190
|
| knock(inv, m, a, w) | object | the far being answered |
|
|
171
191
|
| | silence | no ward claims the invitation, or another consumed it, or the far being chose silence |
|
|
@@ -181,6 +201,9 @@ Return table.
|
|
|
181
201
|
| boot(cls, key, id?) | key | she exists from now, with fresh cells, and a restart finds her; with an id, her maker holds her standing |
|
|
182
202
|
| | null | the key is already booted, the harbor holds no such class, the class threw at birth, the id is one the maker |
|
|
183
203
|
| | | already holds or a reserved word, or the relation was refused; nothing of the being made is left |
|
|
204
|
+
| lend(name, id) | id | this device lends that name to her ward, and she holds a standing at it under the id she gave |
|
|
205
|
+
| | null | it lends no such name here, the id already names a record or is a reserved word, or the relation was |
|
|
206
|
+
| | | refused; nothing is left behind |
|
|
184
207
|
|
|
185
208
|
A being may make, and only the owner reaches into another. Boot touches
|
|
186
209
|
nobody else: the being made has empty cells and no relation but the one her
|
|
@@ -196,8 +219,59 @@ no one yet. What the owner has that the maker does not is every ask that
|
|
|
196
219
|
reaches into a being from outside: public, invite and knock for her, remove,
|
|
197
220
|
unboot. Who may ask her to boot is her gate, as who may ask her anything is.
|
|
198
221
|
|
|
199
|
-
|
|
200
|
-
|
|
222
|
+
Lend is boot's shape for what the device already has. What a device can do
|
|
223
|
+
is beings, in a ward its harbor booted and roots, and `lend` is how a being
|
|
224
|
+
of another ward comes to hold a standing at one: her ward asks the ground
|
|
225
|
+
for the name, the harbor's root mints an invitation on that being, and her
|
|
226
|
+
ward knocks with it and takes it under the id she gave. She is handed the
|
|
227
|
+
id and nothing else, exactly as her maker is handed a key. From then on it
|
|
228
|
+
is an ordinary standing, counted and rotated, removable by her, and told
|
|
229
|
+
`removed` when the far being drops her.
|
|
230
|
+
|
|
231
|
+
Boot's shape includes what boot does when it fails. A being made whose
|
|
232
|
+
relation could not be made is unmade, because she is her maker's ward's own
|
|
233
|
+
and that ward may take her out again. The being lent is not: she stands in
|
|
234
|
+
the harbor's ward, which no other ward may reach into. So the two halves are
|
|
235
|
+
one call rather than two, and the ward's half runs inside the harbor's: the
|
|
236
|
+
harbor mints, hands the invitation to her ward to knock and take, and hears
|
|
237
|
+
whether it was taken. A knock refused, a take that lost the id to another
|
|
238
|
+
line of hers, a ward gone in between: each answers no, and the root that
|
|
239
|
+
minted removes the occupant it made. Nothing half-lives on either side of
|
|
240
|
+
the seam, and a refused lend costs the box nothing, which is what the table
|
|
241
|
+
above promises.
|
|
242
|
+
|
|
243
|
+
The invitation never reaches her, and that is the difference between this
|
|
244
|
+
relation and every other one she holds. Her own invitations are hers to
|
|
245
|
+
give away, because giving one away is giving her own relation away. This
|
|
246
|
+
one is not hers: it is the device's, minted for her ward alone, and a value
|
|
247
|
+
she could copy is a capability she could hand to anyone. So she never sees
|
|
248
|
+
it. A being who wants to lend her device access to another lends it in the
|
|
249
|
+
open, by offering an ask of her own that forwards to her standing, where her
|
|
250
|
+
gate reads who is asking and she can stop.
|
|
251
|
+
|
|
252
|
+
Null is every kind of no, and she cannot tell them apart because there is
|
|
253
|
+
nothing she would do differently: this harbor lends nothing, or nothing of
|
|
254
|
+
that name, or nothing of that name to her ward, or what was minted could not
|
|
255
|
+
be taken. What a device has is not hers to enumerate.
|
|
256
|
+
|
|
257
|
+
The ground is the harbor's, so `lend` reaches the box she is running on and
|
|
258
|
+
no other. A ward that moved box is handed the new harbor's ground, and a
|
|
259
|
+
standing she woke up holding names a being on the box she left, which is
|
|
260
|
+
what a standing means and is why it is not a bug. A being who wants the box
|
|
261
|
+
she is on asks for it again at every birth, which she cannot tell from a
|
|
262
|
+
restart and does not need to.
|
|
263
|
+
|
|
264
|
+
Lend is one direction, and the other one is not a second mechanism. A being
|
|
265
|
+
who wants to be woken invites, hands that invitation to whoever will wake
|
|
266
|
+
her inside an ask, and is woken as the occupant she named. A tick, a
|
|
267
|
+
delivery, a push and a stranger's ask are one act at her door, told apart by
|
|
268
|
+
the id her ward puts on them and by nothing else. Nothing reaches her that
|
|
269
|
+
she did not invite, and nothing wakes her that does not hold a standing at
|
|
270
|
+
her.
|
|
271
|
+
|
|
272
|
+
Ask, knock, invite, take, boot and lend are awaitable. Async where the
|
|
273
|
+
language has it, blocking where it does not. Every ask she makes is a new
|
|
274
|
+
call.
|
|
201
275
|
|
|
202
276
|
The asker has three shapes and no fourth, and nothing else ever reaches her.
|
|
203
277
|
|
|
@@ -208,7 +282,13 @@ The asker has three shapes and no fourth, and nothing else ever reaches her.
|
|
|
208
282
|
owner.
|
|
209
283
|
|
|
210
284
|
`OWNER` and `PUBLIC` are reserved words: invite and take refuse them, so no
|
|
211
|
-
occupant can ever wear either name.
|
|
285
|
+
occupant can ever wear either name. A kit reserves more, because a relation
|
|
286
|
+
is written in two places, the ward's keys and her record, and a name either
|
|
287
|
+
of them cannot hold is a relation half made and a throw where the table above
|
|
288
|
+
promises a null. Which names those are is that kit's, since an id never
|
|
289
|
+
crosses a door and no far ward can tell. Where the refusal happens is Quo's:
|
|
290
|
+
at the mint and at the take, where every other refusal is, and never at the
|
|
291
|
+
write.
|
|
212
292
|
|
|
213
293
|
## Silence, the words, error
|
|
214
294
|
|
|
@@ -226,10 +306,9 @@ a word the ward's word. one of nine, said only to someone the w
|
|
|
226
306
|
```
|
|
227
307
|
|
|
228
308
|
- An **error** is an ordinary answer. Quo never reads it, never makes it,
|
|
229
|
-
and never treats it apart from any other object. The
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
read like any object.
|
|
309
|
+
and never treats it apart from any other object. The owner's asks answer
|
|
310
|
+
error objects for what they refuse, and they are hers to read like any
|
|
311
|
+
object.
|
|
233
312
|
- **Silence** names no reason, by law. It is what the door says to bytes it
|
|
234
313
|
cannot admit, so that a stranger learns nothing, and what a being says
|
|
235
314
|
when she chooses to say nothing. It is not blindly retryable: the far
|
|
@@ -295,18 +374,33 @@ S2 the standing is gone she held a standing, dropped it, and asked
|
|
|
295
374
|
S3 the wait ran out the ask's time was spent and no reply was read.
|
|
296
375
|
what comes back late is not read. the number is spent.
|
|
297
376
|
an ask still waiting at its lane when the wait ran out is never sent. the word is `late`.
|
|
298
|
-
S4 the reply is not one bytes came back that do not open, or are not signed by the ward they
|
|
377
|
+
S4 the reply is not one bytes came back over the size, or that do not open, or are not signed by the ward they
|
|
299
378
|
were sent to, or are none of the three reply shapes. the number is spent.
|
|
300
379
|
not Quo's bytes: silence.
|
|
301
380
|
S5 the far door answered silence, or a word, exactly as the door said it.
|
|
302
381
|
```
|
|
303
382
|
|
|
304
383
|
And unreached in two: `U1` the args are not one object of values, or could
|
|
305
|
-
not be sealed, so nothing left
|
|
384
|
+
not be sealed, or the method is neither a word nor absent, so nothing left.
|
|
385
|
+
That last is the same rule and the same reason: a payload is written as JSON,
|
|
386
|
+
which drops a field it cannot write, so a method that is not a word would
|
|
387
|
+
arrive as no method at all, and no method at all is the empty ask. She would
|
|
388
|
+
have asked for work, been handed a blueprint, and spent a number on it. What
|
|
389
|
+
a ward cannot send it does not send;
|
|
306
390
|
`U2` the harbor returned nothing, or threw, so no door was reached. The number is
|
|
307
391
|
taken all the same, and the gap it leaves in the count is harmless: the door
|
|
308
392
|
honours any number above its mark.
|
|
309
393
|
|
|
394
|
+
S4 is strict, and strict is a price paid on purpose. A reply carries `seen`
|
|
395
|
+
always, and a reply whose `seen` is neither a digest nor null is none of the
|
|
396
|
+
three shapes, so an answer a far being really gave is read as silence and the
|
|
397
|
+
number is spent with it. The alternative is to read the object and drop the
|
|
398
|
+
field, and then two kits disagree about whether an answer arrived: one hands
|
|
399
|
+
her an object, the other hands her silence, and silence is not blindly
|
|
400
|
+
retryable. That is the one disagreement Quo cannot afford, and it is worth
|
|
401
|
+
losing an answer from a kit that writes one field wrong. A kit that writes it
|
|
402
|
+
wrong is a kit the vectors catch before it ever speaks to anyone.
|
|
403
|
+
|
|
310
404
|
### What the door says
|
|
311
405
|
|
|
312
406
|
The door judges thirteen cases, in this order, and the first case met is
|
|
@@ -319,7 +413,7 @@ wrote in her cells is hers.
|
|
|
319
413
|
|
|
320
414
|
```
|
|
321
415
|
strangers: silence, nothing written, heard false
|
|
322
|
-
D1 the box does not open wrong padlock, garbage, too short. the reply is sealed to the lid if
|
|
416
|
+
D1 the box does not open wrong padlock, garbage, too short, over the size. the reply is sealed to the lid if
|
|
323
417
|
the bytes carried one, and is noise otherwise. a lid that will not
|
|
324
418
|
take a seal, a small-order point, is no lid: noise.
|
|
325
419
|
D2 the payload is malformed by or next not 64 lowercase hex, method not a string, args present and
|
|
@@ -362,10 +456,17 @@ Nothing else survives a removal.
|
|
|
362
456
|
lid the ask came with, signed by the ward key. Same bytes, same length.
|
|
363
457
|
A stranger cannot tell one refusal from another, nor any of them from a
|
|
364
458
|
being who chose to say nothing.
|
|
365
|
-
The door equalizes the bytes and not the time it took to write them
|
|
366
|
-
seven cases are
|
|
367
|
-
|
|
368
|
-
|
|
459
|
+
The door equalizes the bytes and not the time it took to write them, and
|
|
460
|
+
the seven cases are not alike in time: two of them verify a signature and
|
|
461
|
+
five refuse before they would. A heir pk rides in the clear, so whoever
|
|
462
|
+
holds a copy of an invitation can time a knock signed with nothing and
|
|
463
|
+
learn whether that invitation is still unspent. What that buys them is
|
|
464
|
+
what knocking with the invitation would have told them anyway, and
|
|
465
|
+
knocking spends it, which is why the door does not pay for a signature it
|
|
466
|
+
has no reason to check. What is equal is what the door says and what it
|
|
467
|
+
writes, and those are the two a stranger could otherwise use. A word, to a
|
|
468
|
+
key the door has bound, is another length, and may be: whoever hears it
|
|
469
|
+
has already proven who they are.
|
|
369
470
|
2. A refusal writes nothing. No number, no key, no heir, no cell, no bind.
|
|
370
471
|
The same bytes presented again meet the same refusal, and a stranger who
|
|
371
472
|
knocks a thousand times leaves no mark. This holds for the three
|
|
@@ -383,10 +484,7 @@ Nothing else survives a removal.
|
|
|
383
484
|
own ward; unreached is the wire's nothing. A ward never answers nothing,
|
|
384
485
|
so that nothing always means unreached.
|
|
385
486
|
6. Nobody enforces what a being does with silence or a word. Each is one
|
|
386
|
-
value she compares against, and
|
|
387
|
-
unchanged.
|
|
388
|
-
|
|
389
|
-
`test/silence.test.ts` asserts every numbered line above, by its number.
|
|
487
|
+
value she compares against, and a ward hands them to her unchanged.
|
|
390
488
|
|
|
391
489
|
## Words and values
|
|
392
490
|
|
|
@@ -394,11 +492,21 @@ Nothing else survives a removal.
|
|
|
394
492
|
|
|
395
493
|
Everything that crosses an edge is I-JSON (RFC 7493): args, answer,
|
|
396
494
|
blueprint, invitation, and whatever she caches from them. Strings are valid
|
|
397
|
-
Unicode
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
495
|
+
Unicode, which is text and not code units: a surrogate stands in a pair or it
|
|
496
|
+
is no string, since a lone one is a character nobody has and no encoding on a
|
|
497
|
+
wire can carry. No duplicate keys. Numbers must be representable as IEEE
|
|
498
|
+
doubles, so integers are exact up to 2^53, and minus zero is not one of them:
|
|
499
|
+
JSON writes it as zero and reads it back as zero, so a harbor keeping objects
|
|
500
|
+
would hand her a sign a harbor writing bytes would not. Larger integers and
|
|
501
|
+
exact decimals travel as strings, with a schema format saying so. Bytes are
|
|
502
|
+
base64 strings. Nothing else is a value: no dates, no references, no
|
|
503
|
+
functions, no native types. An id or a standing is never a value.
|
|
504
|
+
|
|
505
|
+
The two above are the shape of every rule here: a value is a value when every
|
|
506
|
+
harbor and every kit gives back what was put in. Anything a harbor keeping
|
|
507
|
+
objects would preserve and a harbor writing JSON would lose is refused where
|
|
508
|
+
it is written, because the alternative is a harbor that lies to her about
|
|
509
|
+
which harbor she is standing in.
|
|
402
510
|
|
|
403
511
|
Args are held to the same rule before they are sealed: an ask whose args
|
|
404
512
|
are not one object of values is unreached, because nothing left. Her answer
|
|
@@ -410,7 +518,7 @@ The refusal is a throw where she wrote it, which her ward turns into the
|
|
|
410
518
|
silence it turns every throw into. She has not answered, and
|
|
411
519
|
nothing was written down that a harbor would later have to lie about. This
|
|
412
520
|
holds all the way down: a container read through her cells is part of her
|
|
413
|
-
cells.
|
|
521
|
+
cells.
|
|
414
522
|
|
|
415
523
|
### Silence and the words
|
|
416
524
|
|
|
@@ -418,14 +526,9 @@ Two of the three kinds of "no object came back". The chapter "Silence, the
|
|
|
418
526
|
words, error" is the whole of them; here only the values. Silence is one
|
|
419
527
|
distinguished value. Null is an answer. A word is a second kind of
|
|
420
528
|
distinguished value, her ward's own, nine of them, `unreached` among them.
|
|
421
|
-
None is an object, and none carries anything but its name.
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
`isWord` and `wordOf` read them, and `isUnreached` is the one word a being
|
|
425
|
-
asks about most. `told` names a word and leaves everything else exactly as it
|
|
426
|
-
came, so asking which word arrived is one comparison rather than two joined by
|
|
427
|
-
an and: `told(out) === 'late'`. A kit in another language spells it however
|
|
428
|
-
that language spells one value standing for either, and owes nothing here.
|
|
529
|
+
None is an object, and none carries anything but its name. A kit spells each
|
|
530
|
+
however its language spells one value standing for neither an object nor an
|
|
531
|
+
absence, and the spelling is owed to nobody outside that kit.
|
|
429
532
|
|
|
430
533
|
### Blueprint, schema, digest
|
|
431
534
|
|
|
@@ -448,8 +551,7 @@ serialization of the blueprint. Same bytes from every language. This is law:
|
|
|
448
551
|
two wards in two languages always hash one blueprint to one digest. A ward
|
|
449
552
|
that cannot do this is not a ward. Because only values reach a digest, a key
|
|
450
553
|
holding what is not a value is dropped before hashing and an array slot
|
|
451
|
-
holding one is null, which is what crossing an edge does to them anyway.
|
|
452
|
-
reference is `src/being/digest.ts`.
|
|
554
|
+
holding one is null, which is what crossing an edge does to them anyway.
|
|
453
555
|
|
|
454
556
|
Two places in RFC 8785 are where languages part, and a kit is held to both by
|
|
455
557
|
`vectors/framing.json`. Keys sort by **UTF-16 code unit**, not by code point
|
|
@@ -496,10 +598,12 @@ and an occupant wearing that name would be two parties with one face.
|
|
|
496
598
|
`PUBLIC` guards nothing today, because a public asker is `{}` and carries no
|
|
497
599
|
id, and it is claimed now while claiming it is free.
|
|
498
600
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
601
|
+
A kit refuses more names than those two, wherever its own spelling of the
|
|
602
|
+
stance would collide with an id: a standing under a name that spelling has
|
|
603
|
+
already taken would be unreachable, and invite and take refuse it like the
|
|
604
|
+
ward's words. Which names collide is that kit's, because an id never crosses
|
|
605
|
+
a door and a kit that spells the stance another way has no collision to
|
|
606
|
+
refuse.
|
|
503
607
|
|
|
504
608
|
### Cells
|
|
505
609
|
|
|
@@ -507,9 +611,11 @@ Cells are I-JSON values. The ward may persist them. A restart is silent: she
|
|
|
507
611
|
is constructed again with the same cells. Three keys at their root are the
|
|
508
612
|
ward's, `standings`, `occupants` and `class`, and a write of hers to them is
|
|
509
613
|
refused where she wrote it, like a non-value. A value nested past sixty-four
|
|
510
|
-
levels
|
|
511
|
-
|
|
512
|
-
|
|
614
|
+
levels is refused the same way, and that bound is Quo's because a far ward
|
|
615
|
+
reads what a near one wrote: a kit with a deeper stack still refuses at
|
|
616
|
+
sixty-four, or two kits disagree about which blueprint is a value. A kit
|
|
617
|
+
refuses beside it whatever its own runtime writes one way and reads another,
|
|
618
|
+
and those are its own.
|
|
513
619
|
|
|
514
620
|
```
|
|
515
621
|
cells
|
|
@@ -533,7 +639,12 @@ cells
|
|
|
533
639
|
occupant and a standing that are the same far being: all hers. `invite`
|
|
534
640
|
may seed it, which is how an inviter says the terms it mints under, and
|
|
535
641
|
after that it is written by nobody but her. The owner's `invite` passes
|
|
536
|
-
what it was given straight through; the ward reads none of it.
|
|
642
|
+
what it was given straight through; the ward reads none of it. What is
|
|
643
|
+
seeded is values and is kept as a copy, all the way down: notes that were
|
|
644
|
+
not values would be a record no harbor could write back, and notes shared
|
|
645
|
+
with whoever seeded them would be a hand inside her cells that writes
|
|
646
|
+
without the ward being told, so a restart would bring back something she
|
|
647
|
+
never read. Notes that are not values are no invitation.
|
|
537
648
|
|
|
538
649
|
## Relations
|
|
539
650
|
|
|
@@ -724,11 +835,22 @@ Three keys per relation over its life, one rule at the door: the key I hold
|
|
|
724
835
|
for you may speak, and so may the key it announced last time, and each
|
|
725
836
|
number once.
|
|
726
837
|
|
|
838
|
+
A send that announces nothing leaves the spare standing. Every ask announces
|
|
839
|
+
its next but a public one, which holds no heir and is one key for life, so
|
|
840
|
+
this is a foreign kit's send and not this one's; and a caller who skipped an
|
|
841
|
+
announcement still holds the key she announced before it. The door forgets no
|
|
842
|
+
key it vouched for until another replaces it, and forgetting one here would
|
|
843
|
+
meet that key with silence at the next ask and kill a healthy relation over a
|
|
844
|
+
field. On a fresh heir the rule is the other one: nothing announced is
|
|
845
|
+
`unannounced`, because there the announcement is what binds.
|
|
846
|
+
|
|
727
847
|
Every key in a relation was minted by one side and its secret never left
|
|
728
848
|
that side, except the heir, which the inviter gives away and which dies the
|
|
729
849
|
first time it speaks. No key serves two relations. No key outlives its
|
|
730
|
-
relation. A ward keeps
|
|
731
|
-
is
|
|
850
|
+
relation. A ward keeps a bounded list of the pks a being's side minted, and
|
|
851
|
+
how long it is, is that ward's own: nothing in Quo reads the list, so a
|
|
852
|
+
shorter one costs a shorter trail for whoever is looking at the ward, and a
|
|
853
|
+
kit that keeps none holds the same ward.
|
|
732
854
|
|
|
733
855
|
### The count
|
|
734
856
|
|
|
@@ -766,9 +888,8 @@ what she asked for held to what her ward allows: a number that is not a
|
|
|
766
888
|
positive whole number falls to the default rather than refusing her, and one
|
|
767
889
|
above the ceiling is the ceiling, silently, because the ceiling is not hers
|
|
768
890
|
to know. Budget is granted by a ward, never minted by a being. How wide the
|
|
769
|
-
default and the ceiling are is the ward's own
|
|
770
|
-
|
|
771
|
-
`src/ward/allowance.ts`.
|
|
891
|
+
default and the ceiling are is the ward's own, and no far door can tell one
|
|
892
|
+
ward's from another's.
|
|
772
893
|
|
|
773
894
|
They are two numbers and not one, because the third argument is for both
|
|
774
895
|
directions. A being who knows her own work asks for less on the ask she wants
|
|
@@ -848,7 +969,7 @@ is the one door a stranger may walk through, and only because she chose it.
|
|
|
848
969
|
|
|
849
970
|
Inner: being keys, ids, cells, stances, doors, the bind table, every secret,
|
|
850
971
|
every method, every arg, every answer. Nothing inner is ever readable in the
|
|
851
|
-
bytes, and
|
|
972
|
+
bytes, and a kit proves it by reading every byte string that crossed.
|
|
852
973
|
|
|
853
974
|
Outer: ward pks, heir pks, ephemeral pks, ciphertext. That is the whole of
|
|
854
975
|
what the wire sees. The one value a being holds that is outer is the
|
|
@@ -860,25 +981,20 @@ share no key learn nothing from each other.
|
|
|
860
981
|
|
|
861
982
|
### The wire
|
|
862
983
|
|
|
863
|
-
|
|
864
|
-
agrees, SHA-256 hashes, AES-256-GCM encrypts
|
|
865
|
-
together by HKDF-SHA-256 under an empty salt and
|
|
866
|
-
|
|
984
|
+
Five algorithms, named once and never negotiated: Ed25519 signs, X25519
|
|
985
|
+
agrees, SHA-256 hashes, AES-256-GCM encrypts, and the key and nonce it
|
|
986
|
+
encrypts under are derived together by HKDF-SHA-256 under an empty salt and
|
|
987
|
+
the label `quo-seal`. That
|
|
988
|
+
label is the message cipher's and no other: HKDF appears twice in Quo,
|
|
867
989
|
here from an agreement and again at the ward key from a seed, and the three
|
|
868
990
|
labels, `quo-seal`, `quo-ward-sign`, `quo-ward-seal`, are three so that two
|
|
869
991
|
derivations never answer to one name. The
|
|
870
992
|
ephemeral pk is the additional authenticated data of every box. A small-order
|
|
871
|
-
public key verifies nothing; an all-zero agreement is refused.
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
and never captured at load, so a page without one -- a plain http:// origin, a
|
|
877
|
-
sandboxed frame -- fails at the first ask with one sentence rather than deep
|
|
878
|
-
inside a key import. The arithmetic is `src/ward/arithmetic.ts`, the seal is
|
|
879
|
-
`src/ward/seal.ts`, and `vectors/arithmetic.json` and `vectors/framing.json`
|
|
880
|
-
hold fixed inputs and outputs so a kit in another language proves it agrees
|
|
881
|
-
on the bytes.
|
|
993
|
+
public key verifies nothing; an all-zero agreement is refused. SHA-256,
|
|
994
|
+
AES-GCM and HKDF are everywhere; the two curves are recent, and a terrain
|
|
995
|
+
without them is a terrain no ward runs on. `vectors/arithmetic.json` and
|
|
996
|
+
`vectors/framing.json` hold fixed inputs and outputs so a kit in another
|
|
997
|
+
language proves it agrees on the bytes.
|
|
882
998
|
|
|
883
999
|
```
|
|
884
1000
|
ask on the wire box = ephemeral X25519 pk (32) || AES-GCM( payload || signature (64) )
|
|
@@ -914,6 +1030,33 @@ opens the reply with it. A reply that does not open, or is not signed by the
|
|
|
914
1030
|
ward it was sent to, is silence. Unreached never crosses: the wire's nothing
|
|
915
1031
|
is it.
|
|
916
1032
|
|
|
1033
|
+
There is one size, and it is on the bytes: a door refuses the bytes of an ask
|
|
1034
|
+
above **one mebibyte**, and a sender refuses the bytes of a reply above the
|
|
1035
|
+
same, each before anything is opened. Refusing them is bytes that said
|
|
1036
|
+
nothing, which is already silence, so it is D1 at the door and S4 at the
|
|
1037
|
+
sender, and there is no tenth word and no case of its own. The number is one
|
|
1038
|
+
because breadth costs bytes: an ask with a thousand args, a blueprint with a
|
|
1039
|
+
thousand asks and a reply with a million-element list are all one box that is
|
|
1040
|
+
too big, and a second number for any of them would be a second thing two kits
|
|
1041
|
+
must agree on for nothing. What a being holds in her cells is not this
|
|
1042
|
+
number's business and not Quo's: only what crosses is bounded. One mebibyte
|
|
1043
|
+
because an ask is a message and not a file, and what is larger is asked for
|
|
1044
|
+
in pieces, by a being who knows how her own work divides.
|
|
1045
|
+
|
|
1046
|
+
The hand to a kit in another language is two things, and they are of two
|
|
1047
|
+
kinds. `vectors/` is the byte-level hand: fixed inputs and outputs for
|
|
1048
|
+
everything a stranger can observe, the arithmetic, the ward pk, the digest,
|
|
1049
|
+
the signed body, the sealed shapes, the invitation, the knock, and the
|
|
1050
|
+
frames on a socket and the one request a door takes. A kit reproduces them
|
|
1051
|
+
or it is not this protocol. The conformance suite is the behavioural hand,
|
|
1052
|
+
and it is a checklist and not a harness: one ward is one runtime and one
|
|
1053
|
+
language, so the beings a suite is shown with run only in the ward its kit
|
|
1054
|
+
wrote, and a kit ports the suite and its beings and reads them beside its
|
|
1055
|
+
own. No kit
|
|
1056
|
+
drives a foreign ward through its door, and nothing is owed
|
|
1057
|
+
here before 1.0.0 that does: the door's thirteen cases and the vectors are
|
|
1058
|
+
what two kits meet on, and the suite is what each proves alone.
|
|
1059
|
+
|
|
917
1060
|
## The ward
|
|
918
1061
|
|
|
919
1062
|
### What a ward is
|
|
@@ -946,40 +1089,31 @@ run and the next, a ward is
|
|
|
946
1089
|
nothing at all.
|
|
947
1090
|
|
|
948
1091
|
One ward is one runtime and one language, and every being in it shares both.
|
|
949
|
-
A harbor that wants two languages starts two wards at least.
|
|
950
|
-
|
|
951
|
-
named
|
|
952
|
-
platform surface is the language plus ten globals. Six are the ward's own:
|
|
953
|
-
`crypto`, `TextEncoder`, `TextDecoder`, `structuredClone`, `setTimeout` and
|
|
954
|
-
`atob`. Four more came with the harbor, and are the whole of what a reach
|
|
955
|
-
costs: `fetch` and `WebSocket`, the two kinds of reach; `DataView`, the frame
|
|
956
|
-
id on a socket; and `clearTimeout`, the dialer's reconnect called off. That
|
|
957
|
-
list is a promise, not an accident: `test/terrain.test.ts` fails the build
|
|
958
|
-
both when a file names a platform and when it reaches for a global outside
|
|
959
|
-
the list, and when the list names one the tree has stopped using.
|
|
960
|
-
|
|
961
|
-
The package exports the emitted `dist/`, JavaScript with a declaration
|
|
962
|
-
beside it, on every specifier, so plain Node imports it; the tree runs the
|
|
963
|
-
source directly, and every other terrain reaches a ward through a
|
|
964
|
-
bundler. `test/bundle.test.ts` bundles the three words and runs them, and
|
|
965
|
-
asserts the artefact carries nothing a terrain cannot provide.
|
|
1092
|
+
A harbor that wants two languages starts two wards at least. A ward names no
|
|
1093
|
+
runtime: what it stands on is the language and whatever the terrain hands it,
|
|
1094
|
+
and a kit that named one would be a ward that runs in one place.
|
|
966
1095
|
|
|
967
1096
|
The conformance suite is the ward's truth, so it has to be checkable wherever
|
|
968
|
-
a ward runs. It names no runtime either: its runner is handed in
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
1097
|
+
a ward runs. It names no runtime either: its runner is handed in. It is
|
|
1098
|
+
written against the stance, which is Quo's, and it reaches a kit through one
|
|
1099
|
+
probe, which every kit writes for itself. The probe is six obligations, and a
|
|
1100
|
+
kit that can meet them can be put under the suite:
|
|
1101
|
+
|
|
1102
|
+
1. Boot a being of a named class into a ward, and say which key she has.
|
|
1103
|
+
2. Hand over that ward's ask pointer, so the suite can pilot it as its owner.
|
|
1104
|
+
3. Show the ward's ledger as values: its heir table and its bind table, read
|
|
1105
|
+
and never written, so the suite can see that a refusal wrote nothing and
|
|
1106
|
+
that a knock bound what it should.
|
|
1107
|
+
4. Boot a ward from a partition it is handed, which is what proves a restart
|
|
1108
|
+
and what proves an adoption.
|
|
1109
|
+
5. Move a ward from one harbor to another keeping its pk, which is what
|
|
1110
|
+
proves that a relation survives the move.
|
|
1111
|
+
6. Produce a knock signed with a key nobody announced, which is the one thing
|
|
1112
|
+
the suite sends through a door as a stranger would.
|
|
1113
|
+
|
|
1114
|
+
A kit that cannot do one of these under the topology it is being run in says
|
|
1115
|
+
so at the call, and the chapters that need it are skipped by name rather than
|
|
1116
|
+
passed in silence.
|
|
983
1117
|
|
|
984
1118
|
### The partition
|
|
985
1119
|
|
|
@@ -987,8 +1121,9 @@ Everything durable a ward has is here, every secret included, and nothing
|
|
|
987
1121
|
here is ever in a being's cells. Values only, so the harbor may persist it as
|
|
988
1122
|
it likes: as this process's objects, as a row, as a line of JSON on a disk. A
|
|
989
1123
|
reboot from its JSON is the same ward. A harbor that keeps it copies it
|
|
990
|
-
through JSON and
|
|
991
|
-
behind the cells guard
|
|
1124
|
+
through JSON and by no deeper copy its language offers: what the ward hands
|
|
1125
|
+
out is already values, behind the cells guard, and a copy that carries more
|
|
1126
|
+
than JSON does would carry a shape a reboot cannot give back.
|
|
992
1127
|
|
|
993
1128
|
```
|
|
994
1129
|
partition
|
|
@@ -1001,11 +1136,11 @@ partition
|
|
|
1001
1136
|
spoke: bytes came back once. sent: bytes went out once, answered or not
|
|
1002
1137
|
bounded, oldest out, and one that answered outlives one that never did
|
|
1003
1138
|
answered <ward>:<heir> | public:<ward> -> true knocked and answered
|
|
1004
|
-
minted the
|
|
1139
|
+
minted the pks her side minted, bounded. nothing in the ward reads it: it is there to
|
|
1005
1140
|
be looked at, and a kit that keeps the list empty holds the same ward
|
|
1006
1141
|
heirs heir pk -> { being, id, current, announced, fresh, mark, spent } the door's view of every occupant
|
|
1007
|
-
gone heir pk -> { current, announced } the keys held when an id was removed, bounded,
|
|
1008
|
-
holder hears `removed` and nobody else
|
|
1142
|
+
gone heir pk -> { current, announced } the keys held when an id was removed, bounded, oldest out,
|
|
1143
|
+
so their holder hears `removed` and nobody else a thing
|
|
1009
1144
|
public the one public being's key, or null
|
|
1010
1145
|
```
|
|
1011
1146
|
|
|
@@ -1020,6 +1155,17 @@ since an answered knock is a relation she may still take. A being who knocks
|
|
|
1020
1155
|
without ever taking keeps a fixed number of keys behind her, not one per
|
|
1021
1156
|
invitation she ever met.
|
|
1022
1157
|
|
|
1158
|
+
How long each of the three bounded lists is, is the ward's own, and each says
|
|
1159
|
+
what a reader loses when it bites. A `gone` record past the count is a
|
|
1160
|
+
removed relation whose holder hears silence where she would have heard
|
|
1161
|
+
`removed`, which is what every stranger hears and tells her nothing she can
|
|
1162
|
+
act on. A knock record past the count is an invitation she cannot take, and
|
|
1163
|
+
she knocks again with it or asks for another. The `minted` list is looked at
|
|
1164
|
+
and never read, so its oldest entry going costs a name for a key already
|
|
1165
|
+
dead. None of the three is observable to a far ward as a number: a far side
|
|
1166
|
+
sees only that some old thing is unknown here, which is what it sees from a
|
|
1167
|
+
ward that booted onto a fresh partition.
|
|
1168
|
+
|
|
1023
1169
|
The version is one value and it does not move until 1.0.0. There is nobody
|
|
1024
1170
|
holding a partition of another shape to tell apart: if the shape changes, a
|
|
1025
1171
|
partition is thrown away, not migrated and not counted. A ward opening a
|
|
@@ -1092,15 +1238,15 @@ ward names every arrival on the ask `{ id: 'OWNER' }`, the third asker of the
|
|
|
1092
1238
|
ward-to-being edge, and answers it as such; an owner at the door arrives as
|
|
1093
1239
|
her id. What an owner can do is reach into a being from outside, which no
|
|
1094
1240
|
being can: mark the public being, place a relation into a being of the
|
|
1095
|
-
ward, take one out of her,
|
|
1096
|
-
with every being of the ward. The
|
|
1097
|
-
|
|
1241
|
+
ward, take one out of her, take her out of the ward, and ask her. Boot it
|
|
1242
|
+
shares with every being of the ward. The ward is a being to her owner: the
|
|
1243
|
+
empty ask is her describe,
|
|
1098
1244
|
and each ask in it carries a description and an input naming its fields, as
|
|
1099
1245
|
a being's asks do, so that a side renders the owner's asks the way it
|
|
1100
1246
|
renders anyone's and holds no list of its own.
|
|
1101
1247
|
|
|
1102
1248
|
```
|
|
1103
|
-
ask() -> { asks: [boot, public, invite, knock, remove, unboot],
|
|
1249
|
+
ask() -> { asks: [boot, public, invite, knock, remove, unboot, ask],
|
|
1104
1250
|
notes: { pk, beings: { key: { class, public, digest, absent? } } } }
|
|
1105
1251
|
ask('boot', { key, class }) -> { booted: key } | { error }
|
|
1106
1252
|
ask('public', { key }) -> { public: key } | { error }
|
|
@@ -1110,11 +1256,14 @@ ask('knock', { being | { boot: class, key },
|
|
|
1110
1256
|
-> { taken: id | null, answer } | { error: 'silence' | 'unreached' | ... }
|
|
1111
1257
|
ask('remove', { being, id }) -> { removed: id } | { error }
|
|
1112
1258
|
ask('unboot', { being }) -> { unbooted: key, removed: [id, ...] } | { error }
|
|
1259
|
+
ask('ask', { being?, method?, args?, wanted? })
|
|
1260
|
+
-> her object | { error: 'silence' | 'threw' | 'late' | ... }
|
|
1113
1261
|
anything else -> { error: 'unknown ask' }
|
|
1114
1262
|
```
|
|
1115
1263
|
|
|
1116
|
-
- The owner is a caller like any other: `wanted` says what its knock
|
|
1117
|
-
spend, and saying nothing is the ward's default, exactly as for a
|
|
1264
|
+
- The owner is a caller like any other: `wanted` says what its knock or its
|
|
1265
|
+
ask may spend, and saying nothing is the ward's default, exactly as for a
|
|
1266
|
+
being.
|
|
1118
1267
|
- The describe runs every being's own describe as `OWNER` and hashes it; a
|
|
1119
1268
|
being that throws or falls silent there shows a null digest. A being
|
|
1120
1269
|
absent this run is listed with a null digest and `absent: true`.
|
|
@@ -1165,6 +1314,16 @@ anything else -> { error: 'unknown ask' }
|
|
|
1165
1314
|
the root may ask it, for the reason only the root may invite one: from the
|
|
1166
1315
|
door it is answered as a remove on nobody. Ownership moves by the root
|
|
1167
1316
|
alone.
|
|
1317
|
+
- **The owner's ask is the third asker of the ward-to-being edge, filled in
|
|
1318
|
+
by the ward.** It reaches into a being and asks her, which is strictly less
|
|
1319
|
+
than unboot, and it is the only way to that asker: nothing outside the
|
|
1320
|
+
ward names `OWNER`. She is judged as any arrival is, the three choices and
|
|
1321
|
+
no others, and the wait is bounded like any other. She hears `threw` for a
|
|
1322
|
+
throw, a word out of her, or a shape that is not hers to make, and the
|
|
1323
|
+
owner hears each as an object. With no being named it is the public being,
|
|
1324
|
+
asked as nobody, and unbound: a stranger's view, so a throw of hers is
|
|
1325
|
+
silence, and a device serving her to strangers hears what a stranger hears
|
|
1326
|
+
and no more. The ward itself is refused, and so is a name no being holds.
|
|
1168
1327
|
|
|
1169
1328
|
The door is a ward function. It is not the ward's answer: it judges before
|
|
1170
1329
|
anything is named, and a being's answer only ever receives named askers. The
|
|
@@ -1249,6 +1408,20 @@ The harbor:
|
|
|
1249
1408
|
- Passes every ward the ground, once, at birth. Receives a door and an ask.
|
|
1250
1409
|
Hands the ask to exactly one holder, by the device's own rules. That
|
|
1251
1410
|
holder is the ward's owner.
|
|
1411
|
+
- Boots a ward of its own, when the device has anything to lend, and keeps
|
|
1412
|
+
its ask pointer rather than handing it out, so it is that ward's root.
|
|
1413
|
+
What the device can do lives there as beings, and `lend` mints an
|
|
1414
|
+
invitation on one for a ward that asks, hands it to that ward to knock and
|
|
1415
|
+
take, and removes what it minted where the ward did not take it. Which ward
|
|
1416
|
+
may ask for which name is the harbor's own, and a stranger's ward is lent
|
|
1417
|
+
nothing. Nothing else about that ward is special: it has a seed, a
|
|
1418
|
+
partition, a door and beings, and every ask that reaches one of them is
|
|
1419
|
+
sealed, counted and judged like any other. Those beings are where a world's
|
|
1420
|
+
time comes from. A being runs only while she is answering, so every ask in
|
|
1421
|
+
Quo is asked by a being or by an owner, and a world in which nobody holds a
|
|
1422
|
+
clock, a line or a socket is a world where nothing happens that nobody
|
|
1423
|
+
asked for. What a device has, one of its beings holds, and she begins
|
|
1424
|
+
holding it at birth like anything else she does with her constructor.
|
|
1252
1425
|
- Hands its own device's code the beings it made for a ward, by key, and the
|
|
1253
1426
|
keys it has. This is not a path around a door. The object is already in
|
|
1254
1427
|
that process, made there a moment ago by the harbor itself, and reaching
|
|
@@ -1286,37 +1459,28 @@ Not stressed with:
|
|
|
1286
1459
|
- Fanning out, broadcasting, or forwarding to a pk other than the one it was
|
|
1287
1460
|
given. One pk is one ward is one door.
|
|
1288
1461
|
- Choosing a class, deciding an id, reading the keys inside a relation,
|
|
1289
|
-
minting an invitation, or acting on anything a
|
|
1462
|
+
minting an invitation on a ward it does not root, or acting on anything a
|
|
1463
|
+
partition contains.
|
|
1290
1464
|
- Judging anything. A ward judges its door. The harbor delivers to it.
|
|
1291
1465
|
- Speaking Quo. It is nobody's occupant and holds no standing anywhere. The
|
|
1292
1466
|
harbor is not a ward and is nobody's.
|
|
1293
1467
|
|
|
1294
|
-
The memory harbor, `src/harbor/memory.ts`, is one process and no wire. It
|
|
1295
|
-
keeps partitions by seed, routes its own doors, and may be linked to peers,
|
|
1296
|
-
which stands in for a wire, and cut, which stands in for weather. It routes
|
|
1297
|
-
one hop: a pk that is not its own and not a direct peer's is nothing. It
|
|
1298
|
-
keeps no lease: two of them may hold one seed and one partition, which is
|
|
1299
|
-
the broken vouch every real harbor refuses, kept here so that the tests can
|
|
1300
|
-
show what divergence looks like. Every ward and being assertion in the tree
|
|
1301
|
-
is made on it first, so that the network never hides a fault in the words;
|
|
1302
|
-
the harbor core then passes the same suite over memory stores.
|
|
1303
|
-
|
|
1304
1468
|
What a harbor on a device keeps is a ward's three parts under one name: the
|
|
1305
1469
|
seed, the partition, and a **ward record**, which says where the class
|
|
1306
1470
|
bodies come from and which being is the user's. `user` is a key and nothing
|
|
1307
1471
|
else: a label the device's own code hands back to get the being it made,
|
|
1308
|
-
never read to route a byte or judge an ask.
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
them
|
|
1317
|
-
|
|
1318
|
-
Carrying bytes to a pk off the device is a **reach
|
|
1319
|
-
|
|
1472
|
+
never read to route a byte or judge an ask. Wherever those three parts are
|
|
1473
|
+
kept is a **store**, and what a store owes is the same everywhere: list what
|
|
1474
|
+
it holds, load and put a ward under a name, save the partition when the ward
|
|
1475
|
+
said it wrote, save the record after a boot learned the pk, take a ward out
|
|
1476
|
+
as the first move of a migration, and keep the directory's hints, a pk at a
|
|
1477
|
+
URL, across a restart. A name already kept is refused. A store reads nothing
|
|
1478
|
+
it keeps and hands the partition back as values, never as the object it was
|
|
1479
|
+
given. A disk, a tab, an edge object and a process's own memory are each a
|
|
1480
|
+
store, and every one of them answers the same way.
|
|
1481
|
+
|
|
1482
|
+
Carrying bytes to a pk off the device is a **reach**: carry bytes to a pk,
|
|
1483
|
+
get bytes back or nothing. Two kinds, and no third:
|
|
1320
1484
|
a **request**, one URL, the bytes posted to it with the pk as the last
|
|
1321
1485
|
segment and the reply as the answer, listener to listener; and a
|
|
1322
1486
|
**socket**, one held line used in
|
|
@@ -1324,10 +1488,9 @@ both directions, opened by whichever side can dial, with a frame id
|
|
|
1324
1488
|
matching each reply to its ask and one text frame in which a side announces
|
|
1325
1489
|
the ward pks it holds. The framing on a socket is binary: an ask is a kind
|
|
1326
1490
|
byte, a four-byte id, the 64-byte pk and the bytes; a reply is the kind, the
|
|
1327
|
-
id and the bytes; and nothing delivered is the kind and the id alone.
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
who accepts a socket is the terrain's business. A reach reads nothing; a
|
|
1491
|
+
id and the bytes; and nothing delivered is the kind and the id alone. A kit
|
|
1492
|
+
holds either end of a line and never a listener: who accepts a socket is the
|
|
1493
|
+
terrain's business. A reach reads nothing; a
|
|
1331
1494
|
harbor opens no box but its own probe's.
|
|
1332
1495
|
Nothing comes back only where the reach knows nothing was delivered: no such
|
|
1333
1496
|
pk at the far end, a connection that would not open or closed before it
|
|
@@ -1335,9 +1498,8 @@ opened, a line already gone, a status from a request that says the listener
|
|
|
1335
1498
|
did not take the bytes, refused on their face or with nobody behind the
|
|
1336
1499
|
gateway. A
|
|
1337
1500
|
reach that sent the bytes and lost the line after answers nothing at all,
|
|
1338
|
-
and the ward's bound ends the ask.
|
|
1339
|
-
`
|
|
1340
|
-
`vectors/wire.json`.
|
|
1501
|
+
and the ward's bound ends the ask. The frames are pinned in
|
|
1502
|
+
`vectors/wire.json`, and every reach of every kind answers alike.
|
|
1341
1503
|
|
|
1342
1504
|
A reach also carries the **wire suite**: which frames these are, and which
|
|
1343
1505
|
five algorithms seal what they travel with. It is one number, it is not
|
|
@@ -1350,10 +1512,10 @@ speaks. A side meeting a suite it does not know carries nothing for it and
|
|
|
1350
1512
|
closes, naming the refusal on the way out with close code 4001; a
|
|
1351
1513
|
request door meeting one answers nothing delivered. A dialer refused that
|
|
1352
1514
|
way waits out the ceiling before asking again, because a suite does not
|
|
1353
|
-
become speakable by asking sooner. Its wait
|
|
1515
|
+
become speakable by asking sooner. Its wait goes back to the shortest one
|
|
1354
1516
|
where the far side announced and was taken, and not where the line merely
|
|
1355
1517
|
opened: a listener that opens and then refuses would otherwise be dialed at
|
|
1356
|
-
|
|
1518
|
+
one fixed short wait for good. Absent is this suite,
|
|
1357
1519
|
because a caller older than the header is this one. Present and different is
|
|
1358
1520
|
refused as it is written: the number is compared as it was sent, so a suite
|
|
1359
1521
|
is one spelling and not a family of them.
|
|
@@ -1366,8 +1528,8 @@ has to be able to say so to a kit that cannot, or the day it arrives every
|
|
|
1366
1528
|
world stops answering at once and none of them can say why. A silence names
|
|
1367
1529
|
no reason, by law. This number is the reason, said before the silence.
|
|
1368
1530
|
|
|
1369
|
-
The **harbor core
|
|
1370
|
-
|
|
1531
|
+
The **harbor core** is what every harbor on a device is: the store and the
|
|
1532
|
+
reach put together under the ground. It boots every
|
|
1371
1533
|
ward the store keeps, keeps the map of ward pk to door for its own wards
|
|
1372
1534
|
and the **directory**, pk to reach, for foreign ones, carries bytes to a
|
|
1373
1535
|
pk and delivers bytes from the wire to one door. The directory is filled
|
|
@@ -1399,13 +1561,14 @@ silence a door owes such a box, signed by the claimed key. One rule makes a
|
|
|
1399
1561
|
any listener: bytes that arrive from the wire go to an own door or to a
|
|
1400
1562
|
socket this harbor holds for that pk, and never onward by request. So a
|
|
1401
1563
|
harbor that cannot be dialed is reached through the one it dialed, by
|
|
1402
|
-
anyone who holds a hint that its pk is there. The **dialer
|
|
1403
|
-
|
|
1564
|
+
anyone who holds a hint that its pk is there. The **dialer** is that harbor's
|
|
1565
|
+
half: one held socket to a URL, its
|
|
1404
1566
|
own pks announced when the line opens and again whenever what this harbor
|
|
1405
1567
|
holds changes, so a ward booted, adopted or dropped on a line already in hand
|
|
1406
1568
|
is reachable through it without waiting for that line to fall; the listener's
|
|
1407
1569
|
bound, dialed again
|
|
1408
|
-
with a wait that
|
|
1570
|
+
with a wait that backs off to a ceiling when the line drops, how far being
|
|
1571
|
+
that harbor's own, and
|
|
1409
1572
|
while it is dialed it is one of the harbor's fallbacks, where a pk nobody
|
|
1410
1573
|
here knows is sent. A device that slept, a phone in a pocket, comes back
|
|
1411
1574
|
with that wait frozen and, often, its socket closed under it by the system
|
|
@@ -1486,364 +1649,14 @@ whether an occupant is a person, a model or a program.
|
|
|
1486
1649
|
9. Whatever her ward cannot name is not hers to worry about: what the ward
|
|
1487
1650
|
does with an arrival it cannot name is the ward's.
|
|
1488
1651
|
|
|
1489
|
-
### The
|
|
1490
|
-
|
|
1491
|
-
A being is anything with a constructor taking the stance and an `answer`.
|
|
1492
|
-
The raw shape needs no import from the kit. The kit also offers a base class,
|
|
1493
|
-
`Being` in `src/being/being.ts`, which is a convenience and not Quo:
|
|
1494
|
-
|
|
1495
|
-
- `static cells` are her defaults, merged at birth only where a key is
|
|
1496
|
-
missing, so a restart keeps what she wrote.
|
|
1497
|
-
- `static asks` declares what she can be asked, name to
|
|
1498
|
-
`{ description?, input?, output?, for? }`, in blueprint order.
|
|
1499
|
-
`for(occupant, asker)` decides whether this asker sees the ask, and so
|
|
1500
|
-
whether this asker may call it: what she shows is what she can be asked,
|
|
1501
|
-
one gate for describe and for dispatch.
|
|
1502
|
-
- Both statics are read off the class the object was made from, and a
|
|
1503
|
-
subclass that declares either **replaces** its parent's rather than adding
|
|
1504
|
-
to it. That is the rule and not an oversight: a being's blueprint is
|
|
1505
|
-
exactly what the class in front of you declares, in the order she chose,
|
|
1506
|
-
and a merge would hand her asks she may mean to drop and an order she did
|
|
1507
|
-
not write. A subclass that means to extend says so, in one spelling,
|
|
1508
|
-
`static override asks = { ...Parent.asks, mine: {} }`, and the same for
|
|
1509
|
-
cells. A parent that means to be subclassed at all annotates rather than
|
|
1510
|
-
infers, `static override cells: JsonObject = { ... }`, since this language
|
|
1511
|
-
holds a subclass's static side to its parent's and would otherwise refuse a
|
|
1512
|
-
subclass declaring fewer keys than the parent happened to write.
|
|
1513
|
-
- `answer` is written for her. The empty ask is `describe(asker)`, which she
|
|
1514
|
-
may override by hand. A named ask calls the method of that name with
|
|
1515
|
-
`(args, asker)`. Anything not declared, hidden from this asker, or
|
|
1516
|
-
inherited from Object's prototype is `{ error: 'unknown ask' }` and the
|
|
1517
|
-
method is never entered.
|
|
1518
|
-
- A declared ask with no method, or one named after the base's own members,
|
|
1519
|
-
fails at birth, loudly, so a boot fails and nothing half-lives. The
|
|
1520
|
-
method is one on her prototype chain below Object's: a class field
|
|
1521
|
-
holding a function is not there yet when the base checks, and the
|
|
1522
|
-
refusal says so.
|
|
1523
|
-
- `occupant(asker)` is the occupant record for whoever is at the door, and
|
|
1524
|
-
undefined at a public being. `invite`, `knock`, `take`, `boot`, `cells`,
|
|
1525
|
-
`standings` and `occupants` reach the stance and nothing else.
|
|
1526
|
-
|
|
1527
|
-
### Examples
|
|
1528
|
-
|
|
1529
|
-
The smallest being. Answers whoever her ward names, describes one ask.
|
|
1530
|
-
|
|
1531
|
-
```js
|
|
1532
|
-
class Echo {
|
|
1533
|
-
constructor(stance) {
|
|
1534
|
-
this.s = stance;
|
|
1535
|
-
}
|
|
1536
|
-
answer(asker, method, args) {
|
|
1537
|
-
if (method === undefined) return { asks: [{ name: 'echo', input: {} }], notes: {} };
|
|
1538
|
-
return { from: asker.id ?? null, ...args };
|
|
1539
|
-
}
|
|
1540
|
-
}
|
|
1541
|
-
```
|
|
1652
|
+
### The raw shape
|
|
1542
1653
|
|
|
1543
|
-
A
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
class Shop {
|
|
1548
|
-
constructor(stance) {
|
|
1549
|
-
this.s = stance;
|
|
1550
|
-
}
|
|
1551
|
-
async invite(name) {
|
|
1552
|
-
const id = `g-${name}`;
|
|
1553
|
-
const inv = await this.s.occupants.invite(id);
|
|
1554
|
-
this.s.cells.occupants[id].notes.expireAt = 2028; // hers, not Quo's
|
|
1555
|
-
return inv; // goes by mail
|
|
1556
|
-
}
|
|
1557
|
-
async answer(asker, method, args) {
|
|
1558
|
-
if (method === undefined) return { asks: [{ name: 'hello', input: {} }], notes: {} };
|
|
1559
|
-
if (asker.id === undefined) return { welcome: false }; // a stranger at the public door has no record
|
|
1560
|
-
const rec = this.s.cells.occupants[asker.id];
|
|
1561
|
-
if (method === 'hello' && args.invitation) {
|
|
1562
|
-
const back = await this.s.standings.knock(args.invitation, 'hi');
|
|
1563
|
-
if (back !== silence && !isUnreached(back))
|
|
1564
|
-
await this.s.standings.take(`back-${asker.id}`, args.invitation);
|
|
1565
|
-
}
|
|
1566
|
-
return { welcome: rec.notes.expireAt > 2026 };
|
|
1567
|
-
}
|
|
1568
|
-
}
|
|
1569
|
-
```
|
|
1570
|
-
|
|
1571
|
-
A guest. Consumes an invitation, and only then decides to keep the shop.
|
|
1572
|
-
|
|
1573
|
-
```js
|
|
1574
|
-
class Guest {
|
|
1575
|
-
constructor(stance) {
|
|
1576
|
-
this.s = stance;
|
|
1577
|
-
}
|
|
1578
|
-
async join(invitation) {
|
|
1579
|
-
const mine = await this.s.occupants.invite('shop'); // so the shop can reach me
|
|
1580
|
-
const out = await this.s.standings.knock(invitation, 'hello', { invitation: mine });
|
|
1581
|
-
if (out === silence || isUnreached(out)) return out; // nothing was born
|
|
1582
|
-
await this.s.standings.take('shop', invitation); // now, and only now
|
|
1583
|
-
return out;
|
|
1584
|
-
}
|
|
1585
|
-
answer(asker, method) {
|
|
1586
|
-
if (method === undefined) return { asks: [{ name: 'hi', input: {} }], notes: {} };
|
|
1587
|
-
return { heard: method };
|
|
1588
|
-
}
|
|
1589
|
-
}
|
|
1590
|
-
```
|
|
1591
|
-
|
|
1592
|
-
A relay. Forwards every ask to one standing and never looks inside, and asks
|
|
1593
|
-
for a short wait because she is one door of several. Silence passes through
|
|
1594
|
-
her; a word does not, since a word out of a being is `threw` at the door,
|
|
1595
|
-
D13, so she says it as an error of her own.
|
|
1596
|
-
|
|
1597
|
-
```js
|
|
1598
|
-
class Relay {
|
|
1599
|
-
constructor(stance) {
|
|
1600
|
-
this.s = stance;
|
|
1601
|
-
}
|
|
1602
|
-
async answer(asker, method, args) {
|
|
1603
|
-
const out = await this.s.standings.next.ask(method, args, { time: 2000 });
|
|
1604
|
-
return isWord(out) ? { error: wordOf(out) } : out; // unreached and late reach her asker as an error, not as a throw
|
|
1605
|
-
}
|
|
1606
|
-
}
|
|
1607
|
-
```
|
|
1608
|
-
|
|
1609
|
-
A watcher. Notices a standing changed shape, then decides.
|
|
1610
|
-
|
|
1611
|
-
```js
|
|
1612
|
-
class Watcher {
|
|
1613
|
-
constructor(stance) {
|
|
1614
|
-
this.s = stance;
|
|
1615
|
-
}
|
|
1616
|
-
async answer(asker, method, args) {
|
|
1617
|
-
if (method === undefined) return { asks: [{ name: 'poke', input: {} }], notes: {} };
|
|
1618
|
-
const out = await this.s.standings.src.ask('read', args);
|
|
1619
|
-
const rec = this.s.cells.standings.src;
|
|
1620
|
-
if (rec.seen !== rec.digest) {
|
|
1621
|
-
const bp = await this.s.standings.src.ask(); // refresh, or
|
|
1622
|
-
if (!bp?.asks.some((a) => a.name === 'read')) this.s.standings.remove('src'); // walk away
|
|
1623
|
-
}
|
|
1624
|
-
return out;
|
|
1625
|
-
}
|
|
1626
|
-
}
|
|
1627
|
-
```
|
|
1628
|
-
|
|
1629
|
-
## The tree
|
|
1630
|
-
|
|
1631
|
-
The repository is one TypeScript implementation of this document, run
|
|
1632
|
-
directly on Node's type stripping, no dependencies. Node 22.18
|
|
1633
|
-
or later. The package is `@quo-systems/quo`, published from 0.1.0, the
|
|
1634
|
-
first version under this name, and it starts over: nothing before it under
|
|
1635
|
-
any other name is this protocol. Before 1.0.0 every version may change the
|
|
1636
|
-
words, and nothing is kept for a holder of an earlier one.
|
|
1637
|
-
|
|
1638
|
-
The tree runs as TypeScript and the package ships as JavaScript. Node
|
|
1639
|
-
strips types nowhere under `node_modules`, so a consumer cannot load the
|
|
1640
|
-
source. `npm run build` emits `dist/` from `src`
|
|
1641
|
-
alone, one JavaScript file and one declaration file per source file with
|
|
1642
|
-
every relative import rewritten, and the exports map points there, types
|
|
1643
|
-
beside default. The
|
|
1644
|
-
build runs before every gate and every publish and is never tracked;
|
|
1645
|
-
nothing in this repository imports it except through the package name,
|
|
1646
|
-
which is how a consumer does. `test/package.test.ts` is the one
|
|
1647
|
-
suite that meets the package as a stranger: it packs the tarball,
|
|
1648
|
-
installs it into an empty folder, and imports every entry point under
|
|
1649
|
-
plain Node. `npm pack --dry-run` shows what ships: `dist/`, the four
|
|
1650
|
-
source folders, the vectors, this document, the README, the licence and
|
|
1651
|
-
the notice, and nothing else. This document ships, decided here: it is the
|
|
1652
|
-
truth the source and the vectors are read against, and a kit in another
|
|
1653
|
-
language is written against it and nothing else. Publishing runs both
|
|
1654
|
-
gates first, `npm run check` and `npm run check:terrain`, and refuses on a
|
|
1655
|
-
failure.
|
|
1656
|
-
|
|
1657
|
-
```
|
|
1658
|
-
src/being/ the Being side. types, the base class, silence, the digest.
|
|
1659
|
-
src/ward/ the ward. the Ground contract, door, seal, arithmetic, heirs, stance, owner, partition, cells, allowance.
|
|
1660
|
-
src/harbor/ the memory harbor, the store, the reach, the dialer and the harbor core.
|
|
1661
|
-
src/conformance/ the behaviours any ward must show, and the fixed beings they are shown with.
|
|
1662
|
-
test/ the suites.
|
|
1663
|
-
vectors/ fixed inputs and outputs: the arithmetic, Quo's own framing, the frames on the wire.
|
|
1664
|
-
```
|
|
1665
|
-
|
|
1666
|
-
The hand to a kit in another language is two things, and they are of two
|
|
1667
|
-
kinds. `vectors/` is the byte-level hand: fixed inputs and outputs for
|
|
1668
|
-
everything a stranger can observe, the arithmetic, the ward pk, the digest,
|
|
1669
|
-
the signed body, the sealed shapes, the invitation, the knock, and the
|
|
1670
|
-
frames on a socket and the one request a door takes. A kit reproduces them
|
|
1671
|
-
or it is not this protocol. `src/conformance/` is the behavioural hand, and
|
|
1672
|
-
it is a checklist and not a harness: one ward is one runtime and one
|
|
1673
|
-
language, so the beings it is shown with run only in a TypeScript ward, and
|
|
1674
|
-
a kit ports the suite and its beings and reads them beside its own. Nothing
|
|
1675
|
-
in this tree drives a foreign ward through its door, and nothing is owed
|
|
1676
|
-
here before 1.0.0 that does: the door's thirteen cases and the vectors are
|
|
1677
|
-
what two kits meet on, and the suite is what each proves alone.
|
|
1654
|
+
A being is anything her language can construct with the stance and ask with
|
|
1655
|
+
`answer`. She needs no import from any kit, and a kit that could only make
|
|
1656
|
+
beings out of a base class of its own would be a kit standing between a
|
|
1657
|
+
being and her ward.
|
|
1678
1658
|
|
|
1679
|
-
|
|
1680
|
-
is `Ward`, `@quo-systems/quo/harbor` is `MemoryHarbor`, `Harbor`, the
|
|
1681
|
-
store, the reach and the dialer, and `@quo-systems/quo/conformance` is
|
|
1682
|
-
`conform` with the store and reach suites beside it.
|
|
1683
|
-
|
|
1684
|
-
The gate is `npm run check`: typecheck under TypeScript 7, oxlint with
|
|
1685
|
-
type-aware rules, markdownlint, then every suite under `node --test`. There
|
|
1686
|
-
is no CI; the gate runs in seconds and is run before every commit. Nothing
|
|
1687
|
-
red is committed except a test marked todo, which is a claim the tree does
|
|
1688
|
-
not yet meet and says so.
|
|
1689
|
-
|
|
1690
|
-
### The suites
|
|
1691
|
-
|
|
1692
|
-
The beings are fixed and the ward is what is tested. A ward kit in any
|
|
1693
|
-
language offers the ground, the door, and the owner's ask as written, and
|
|
1694
|
-
passes the same suite. Those tests are the checklist, not the mock.
|
|
1695
|
-
|
|
1696
|
-
- `test/being.test.ts`: the base class against a stance stub. No ward, no
|
|
1697
|
-
harbor. Defaults, describe, dispatch, the gate, the reserved names, the
|
|
1698
|
-
digest.
|
|
1699
|
-
- `src/conformance/index.ts`: one suite of behaviours, written against the
|
|
1700
|
-
stance and one probe: a kit hands the suite its ward's heir table and
|
|
1701
|
-
bind table as values, and a forged knock, so the suite can see that a
|
|
1702
|
-
refusal wrote nothing and a knock bound what it should. It reads the
|
|
1703
|
-
tables and never writes them; the forged knock is the one thing it sends
|
|
1704
|
-
through a door. With the beings in `src/conformance/beings.ts`: a
|
|
1705
|
-
printer, a shop, two customers, one raw being with no base class, and a
|
|
1706
|
-
member of an estate. Any ward must pass it, under any topology.
|
|
1707
|
-
- `src/conformance/estate.ts`: the estate, and the last chapter of that
|
|
1708
|
-
suite. Every other chapter is a scene: three beings, one move, one answer.
|
|
1709
|
-
This one is a graph under churn, which is the shape an organisation running
|
|
1710
|
-
on Quo actually has -- scattered wards on scattered harbors, partners and
|
|
1711
|
-
employees invited, knocking, taken, kicked, and moving to harbors of their
|
|
1712
|
-
own. It keeps a model of the graph, plays legal moves against it from three
|
|
1713
|
-
fixed seeds, and after every move holds two things: that the ledger every
|
|
1714
|
-
ward keeps closes on both ends, and that every arc in it answers when asked
|
|
1715
|
-
exactly what being that arc means. The second is held under all three
|
|
1716
|
-
topologies, and that is the promise of Quo at a scale a scene cannot
|
|
1717
|
-
reach: the model never learns the topology, so neither may any answer. The
|
|
1718
|
-
model is the script's own bookkeeping and is never compared with itself
|
|
1719
|
-
across topologies, which would hold by construction and prove nothing. A
|
|
1720
|
-
relation is two arcs and never one edge:
|
|
1721
|
-
the occupant is the host's, the standing is the guest's, and the model
|
|
1722
|
-
keeps them apart because the ward does. A red run prints its seed and the
|
|
1723
|
-
moves that got there. It is read beside one hand-written story that says in
|
|
1724
|
-
prose what the model is for.
|
|
1725
|
-
- `test/ward.test.ts`: the conformance suite against the real ward under
|
|
1726
|
-
three topologies over the memory harbor, one ward, one harbor with a ward
|
|
1727
|
-
per being, two harbors; and what only a real ward can be asked: the
|
|
1728
|
-
owner's asks, the door judged byte by byte, rotation and a lost reply,
|
|
1729
|
-
replay, a restart, and every byte on the wire inspected for anything inner.
|
|
1730
|
-
- `test/public.test.ts`: the public being, what the door does and does not
|
|
1731
|
-
do for her.
|
|
1732
|
-
- `test/silence.test.ts`: the chapter "Silence, the words, error" by its
|
|
1733
|
-
numbers: the five cases and two unreacheds of her ward, the thirteen
|
|
1734
|
-
cases of the door with a partition snapshot under each, seven strangers
|
|
1735
|
-
met with one silence and six bound keys hearing their word, hops refused
|
|
1736
|
-
at zero, and the six lines of the law of one silence.
|
|
1737
|
-
- `test/blueprint.test.ts`: blueprints and instantiation through a real
|
|
1738
|
-
ward. What a boot leaves behind, what a restart brings back when the code
|
|
1739
|
-
moved under the cells, the gate and the door, the reserved ids.
|
|
1740
|
-
- `test/allowance.test.ts`: the allowance. Default, ceiling, nonsense, the
|
|
1741
|
-
bound, the signed body, the door's refusal, and one ask through a ward.
|
|
1742
|
-
- `test/seal.test.ts`: the arithmetic against `vectors/arithmetic.json`,
|
|
1743
|
-
then the seal, round trip, and what it refuses; then the framing against
|
|
1744
|
-
`vectors/framing.json`. The arithmetic is standard and any language has
|
|
1745
|
-
it. The framing is Quo's own, and a kit that reproduces the hashes and
|
|
1746
|
-
not the ward pk, the digest, the signed ask body, the two sealed shapes,
|
|
1747
|
-
the invitation or the knock is not this protocol. Every seed in that file
|
|
1748
|
-
is fixed, so every output is fixed. The ask body is the payload as JSON
|
|
1749
|
-
and is not canonical: the vectors pin the order the type declares, and a
|
|
1750
|
-
kit that emits another order interoperates, because a door verifies the
|
|
1751
|
-
bytes it received, and will not reproduce the vectors. `hops` is in no
|
|
1752
|
-
vector, because nothing sets it. The invitation is JSON too, and the
|
|
1753
|
-
knock is pinned as the ask it is, by the heir, to the heir, announcing
|
|
1754
|
-
the knocker's own key, and then proven at a real door: a ward booted on
|
|
1755
|
-
the vector's seed, drawing the heir secret as its first entropy, mints
|
|
1756
|
-
the invitation vector, binds the knock vector at its door, answers it,
|
|
1757
|
-
spends the heir, and refuses the same bytes again.
|
|
1758
|
-
- `test/break.test.ts`: adversarial probes. Each states what this document
|
|
1759
|
-
promises, then tries to break it.
|
|
1760
|
-
- `test/gaps.test.ts` and `test/gaps2.test.ts`: cases the memory harbor
|
|
1761
|
-
cannot express because it is honest, in-order and lossless: a lost reply,
|
|
1762
|
-
a cycle, a partition written down and read back, a long relation, one
|
|
1763
|
-
seed booted twice. Each test is a claim that the ward is wrong; one that
|
|
1764
|
-
will not go red is not a bug.
|
|
1765
|
-
- `src/conformance/store.ts`: the store suite, written against the store
|
|
1766
|
-
interface alone and handed a maker of fresh stores. A fresh store keeps
|
|
1767
|
-
nothing; what was put comes back as it went in, as values and not as the
|
|
1768
|
-
object; a name already kept is refused; save and record touch only their
|
|
1769
|
-
part and are nothing on a name not kept; take hands a ward out and frees
|
|
1770
|
-
the name; hints are kept by pk and the last one wins.
|
|
1771
|
-
- `src/conformance/reach.ts`: the reach suite, written against the reach
|
|
1772
|
-
interface alone and handed a far side it controls: a door held behind a
|
|
1773
|
-
pk over there, and the far side dropped. The door's bytes come back;
|
|
1774
|
-
nothing for a pk nobody holds; asks in flight at once each get their own
|
|
1775
|
-
answer; what crosses is a copy both ways; and once the far side is gone,
|
|
1776
|
-
nothing. It cannot assert that a reach which sent and then lost the line
|
|
1777
|
-
answers nothing at all, since a suite cannot wait forever.
|
|
1778
|
-
- `test/harbor.test.ts`: the harbor pieces on the library's own ground,
|
|
1779
|
-
no device and no wire. The store suite against the memory store; the
|
|
1780
|
-
reach suite against the socket framing over two lines in one process, so
|
|
1781
|
-
the frames are asserted with no network under them; the conformance
|
|
1782
|
-
suite against two harbor cores over memory stores reaching each other
|
|
1783
|
-
in-process, drop and adopt as the migration; a ward that moves harbor
|
|
1784
|
-
keeping its pk and every relation, the rendezvous told on the line in
|
|
1785
|
-
hand; a ward booted or dropped after a line opened, announced on that
|
|
1786
|
-
line, and a claim on a pk nobody holds binding nothing; a restart from
|
|
1787
|
-
the store with the hints; the dialer over a stubbed line, announce, a claim proven
|
|
1788
|
-
at a real door before it binds and a claim nobody there holds left
|
|
1789
|
-
unbound, fallback, unbind and the wait before it dials again; and the frames against
|
|
1790
|
-
`vectors/wire.json`, the ask, the reply, nothing delivered and the
|
|
1791
|
-
announce, so a kit reproduces the bytes on a socket; and the request
|
|
1792
|
-
reach against the request record in the same file, over a fetch that
|
|
1793
|
-
sees what a listener would, one POST with the suite in its header, the
|
|
1794
|
-
reply as a 200 and nothing delivered as a 404. A socket to a real
|
|
1795
|
-
listener and every real store pass the same suites outside this tree.
|
|
1796
|
-
- `test/terrain.test.ts`: the terrain census. Nothing under `src/being/`,
|
|
1797
|
-
`src/ward/`, `src/harbor/` or `src/conformance/` names a runtime, and
|
|
1798
|
-
nothing reaches for a global outside the ones it names; nor does the
|
|
1799
|
-
census name one the tree has stopped using. It reads the source as text
|
|
1800
|
-
and not as a parse: it is there to catch drift, and does not pretend to
|
|
1801
|
-
stop someone determined to get around it.
|
|
1802
|
-
- `test/assert.test.ts`: `src/conformance/assert.ts` against
|
|
1803
|
-
`node:assert/strict`, pair by pair. The suite means the same thing on
|
|
1804
|
-
every terrain only if those two agree, so they are compared and not
|
|
1805
|
-
trusted.
|
|
1806
|
-
- `test/floor.test.ts`: the five algorithms this terrain must carry, probed
|
|
1807
|
-
one by one; that the arithmetic spends every one of them; and the two ways
|
|
1808
|
-
a terrain can be short -- no `crypto.subtle` at all, and a subtle without
|
|
1809
|
-
the curves -- each failing at the first call, in one sentence.
|
|
1810
|
-
- `test/package.test.ts`: the package as a stranger meets it. The tarball
|
|
1811
|
-
is packed, installed into an empty folder with nothing but Node, and
|
|
1812
|
-
every entry point the exports map names is imported. Every other suite
|
|
1813
|
-
reaches the source through a path or a workspace link, which resolves
|
|
1814
|
-
outside `node_modules`, where Node strips types; this is the one that
|
|
1815
|
-
cannot.
|
|
1816
|
-
- `test/bundle.test.ts`: the three words bundled as a consumer must bundle
|
|
1817
|
-
them, the artefact read for anything a terrain cannot provide, and then the
|
|
1818
|
-
whole conformance suite run out of the bundle.
|
|
1819
|
-
- `test/terrain/browser.test.ts`, `test/terrain/edge.test.ts`,
|
|
1820
|
-
`test/terrain/deno.test.ts` and `test/terrain/bun.test.ts`: that same
|
|
1821
|
-
bundle and that same suite in a real Chromium, in workerd, in Deno and in
|
|
1822
|
-
Bun, plus each terrain's floor, and, for the browser, a page whose
|
|
1823
|
-
`crypto` has no `subtle`. Deno runs it a second time with every permission
|
|
1824
|
-
denied but read -- no net, no environment, no write, no subprocess -- which
|
|
1825
|
-
is where a ward that had quietly come to need one of them would fail, and
|
|
1826
|
-
nowhere else in this repository. A terrain whose binary is absent skips and
|
|
1827
|
-
names the command that installs it; it never passes quietly.
|
|
1828
|
-
`test/terrain/engine.ts` runs the bundle in another engine on this machine.
|
|
1829
|
-
Behind `npm run check:terrain`. `test/terrain/bundle.ts` is the
|
|
1830
|
-
bundler and the reference run, `test/terrain/exercise.ts` is what every
|
|
1831
|
-
terrain runs, `test/terrain/floor.ts` is the floor -- each written once, so
|
|
1832
|
-
no terrain can be probed for less than another.
|
|
1833
|
-
- `test/world.ts`: the memory-harbor probe and the three topologies, held
|
|
1834
|
-
apart from any one chapter because every terrain drives the same one. It
|
|
1835
|
-
also answers the two asks the estate needs: the census, which is every
|
|
1836
|
-
partition in the world as values, and a migration, which lifts a partition
|
|
1837
|
-
out of one harbor and boots it from the same seed in the other -- same
|
|
1838
|
-
seed, same pk, so every standing anyone holds still points at her.
|
|
1839
|
-
- `test/repo.test.ts`: this document, the README and the project
|
|
1840
|
-
instructions against the repository: every path they name exists, every
|
|
1841
|
-
source file carries its licence, the package names no host and no user,
|
|
1842
|
-
the awaitable calls are marked and
|
|
1843
|
-
awaited in the examples above, the allowance is decided here and off the
|
|
1844
|
-
Open list, and the allowance is time alone on both sides of the door.
|
|
1845
|
-
|
|
1846
|
-
### Where the tree stands
|
|
1659
|
+
## Where the tree stands
|
|
1847
1660
|
|
|
1848
1661
|
The only place this document may name a gap between itself and the tree.
|
|
1849
1662
|
Each line is a debt to close, not a note to keep.
|
|
@@ -1863,14 +1676,14 @@ Decided here, so that the answer is not rediscovered:
|
|
|
1863
1676
|
|
|
1864
1677
|
- **Delivered, then died, is refused on repeat.** The far ward receives and
|
|
1865
1678
|
crashes, the wire says nothing, and the near ward calls it unreached.
|
|
1866
|
-
|
|
1679
|
+
No ward retries on its own, so a caller who asks again asks
|
|
1867
1680
|
under the next number and is heard. A repeated number is refused by every
|
|
1868
1681
|
door of this version, D10, and that is the whole answer: a repeated number
|
|
1869
1682
|
is only ever seen by the one door it was sent to, so a kit that one day
|
|
1870
1683
|
answers it from what the door already said interoperates with one that
|
|
1871
|
-
refuses, the way one ward's ceiling never meets another's.
|
|
1872
|
-
|
|
1873
|
-
|
|
1684
|
+
refuses, the way one ward's ceiling never meets another's. The slot for the
|
|
1685
|
+
reply that kit would keep is a field on the heir, and it costs two lines to
|
|
1686
|
+
cut now and a partition shape to cut after 1.0.0.
|
|
1874
1687
|
- **Hops is the door's half, and that half is whole.** An ask carries no
|
|
1875
1688
|
count of doors, so a chain of relays is bounded by time alone. `hops` is a
|
|
1876
1689
|
field of the ask, a whole number and never below zero, and a door refuses
|
|
@@ -1951,10 +1764,15 @@ Decided here, so that the answer is not rediscovered:
|
|
|
1951
1764
|
- **ward record**: what a harbor keeps beside a ward's seed and partition
|
|
1952
1765
|
to boot her again: her pk, where the class bodies come from, and which
|
|
1953
1766
|
being is the user's. The harbor's, never the ward's.
|
|
1767
|
+
- **size**: one mebibyte, on the bytes of an ask and on the bytes of a reply.
|
|
1768
|
+
Read before anything is opened. Over it is silence, and never a word.
|
|
1954
1769
|
- **lid**: the ephemeral X25519 pk an ask carries in front of its box. The
|
|
1955
1770
|
reply is sealed to it and to nothing else. One per ask, never reused.
|
|
1956
1771
|
- **edge**: one of the two seams of Quo, harbor to ward and ward to being.
|
|
1957
1772
|
An object crosses once at birth, calls cross for the rest of the ward's
|
|
1958
1773
|
life, and nothing else crosses.
|
|
1959
|
-
- **ground**: the one object a harbor passes a ward.
|
|
1774
|
+
- **ground**: the one object a harbor passes a ward. Seven things.
|
|
1775
|
+
- **lend**: a standing at one of the harbor's own beings, by the name that
|
|
1776
|
+
harbor knows it under. The ward knocks and takes it for her; she is handed
|
|
1777
|
+
the id and never the invitation.
|
|
1960
1778
|
- **door**: the ward's one voice outward. Sealed bytes in, sealed bytes out.
|